install driver using c++ - c++

I'm trying to install driver behind the user:
I've create DLL which call SetupCopyOEMInf using c++ then i call it from VB application:
C++ code:
PBOOL bRebootRequired = false;
PCTSTR szInfFileName = (PCTSTR) "c:\\temp\\ttt\\Driver\\slabvcp.inf";
if(!SetupCopyOEMInf(szInfFileName,NULL, SPOST_PATH, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL)){;
DWORD dw = GetLastError();
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,0, NULL );
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
}
And when i call this function i receiving error "The system cannot find the file specified."
But the path to my file is correct.

PCTSTR szInfFileName = (PCTSTR) "c:\\temp\\ttt\\Driver\\slabvcp.inf";
A cast is not going to work, it will turn your 8-bit character string into Chinese. Fix:
PCTSTR szInfFileName = _T("c:\\temp\\ttt\\Driver\\slabvcp.inf");

Related

Failed with error 87: The parameter is incorrect. How to determine which parameter is incorrect?

I'm trying to create a win32 window as simple as possible, in a unit test, but I get an error 87: how do I get which parameter is incorrect ?
#include <windows.h>
#include <strsafe.h>
LPTSTR GetErrorMessage(wstring fnName)
{
LPTSTR messageBuffer{};
LPTSTR displayBuffer{};
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
0, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&messageBuffer, 0, 0);
displayBuffer = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, lstrlen(messageBuffer) + (fnName.size() + 40) * sizeof(TCHAR));
StringCchPrintf(displayBuffer, LocalSize(displayBuffer) / sizeof(TCHAR), L"%s failed with error %d: %s", fnName.c_str(), dw, messageBuffer);
return displayBuffer;
}
TEST_METHOD(WinTest)
{
auto hwnd = CreateWindowExW(WS_EX_APPWINDOW, 0, L"test w", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 800, 600, 0, 0, 0, 0);
Assert::IsNotNull(hwnd, GetErrorMessage(L"CreateWindowExW"));
ShowWindow(hwnd, SW_SHOWDEFAULT);
Sleep(1000);
}
Assert failed. CreateWindowExW failed with error 87: The parameter is incorrect.
Reference: createwindowexw on learn.microsoft.com
To answer the specific question you asked - the Win32 API does not tell you WHICH parameter is invalid. You have to read the documentation for the function that failed, and then debug your code to compare the values you are actually passing to the function to see how they differ from the acceptable values the function is expecting.
In this particular example, you are passing a NULL pointer to the lpClassName parameter of CreateWindowEx(), which is not allowed. You must specify the name of the window class you want to create.
On a side note, your GetErrorMessage() function is leaking memory, as it does not free the memory allocated by either FormatMessage() or LocalAlloc(). Both messageBuffer and displayBuffer need to be freed with LocalFree().
I strongly advise you to make GetErrorMessage() return a wstring instead of a raw TCHAR* pointer, eg:
wstring GetErrorMessage(const wstring &fnName)
{
DWORD dw = GetLastError();
wostringstream displayBuffer;
displayBuffer << fnName << L" failed with error " << dw;
LPWSTR messageBuffer{};
if (FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
0,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&messageBuffer,
0,
0))
{
displayBuffer << L": " << messageBuffer;
LocalFree(messageBuffer);
}
return displayBuffer.str();
}

Wide Char Version of Get last Error?

This is Microsoft's code:
void ErrorExit(LPCWSTR lpszFunction, DWORD NTStatusMessage)
{
// Retrieve the system error message for the last-error code
DWORD dww = 0;
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
if (NTStatusMessage)
{
dww = NTStatusMessage;
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_FROM_HMODULE,
hdlNtCreateFile,
dww,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR) &lpMsgBuf,
0,
NULL );
}
else
{
dww = GetLastError();
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dww,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&lpMsgBuf,0, NULL);
}
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %lu: %s"), lpszFunction, dww, lpMsgBuf);
printf("\a"); //audible bell not working yet
MessageBoxW(NULL, (LPCTSTR)lpDisplayBuf, L"Error", MB_OK);
LocalFree(lpDisplayBuf);
LocalFree(lpMsgBuf);
//ExitProcess(dw);
}
I added a section for NTstatus and changed the arg to LPCWSTR. It's basically nonfunctional as simply changing to StringCchPrintfW segfaults on the LPVOID types. Any way of making it wide char friendly?
This problem was solved by adding _UNICODE and UNICODE to the Preprocessor definitions in C/C++ > Preprocessor.
The MessageBox call in the OP code adjusted a little: thanks to someone knowledgeable on the Microsoft forums.

CreateProcess application not found in cache c++ MFC

i am writing a simple program which calls CreateProcess thousands of times, so its taking a while to run. in my output windows i'm seeing this message each time
application "whatever.exe" not found in cache
i call CreateProcess like this
BOOL result = CreateProcess(NULL, g_minicapcmd,
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInformation);
if (!result) {
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
CString strError = (LPTSTR) lpMsgBuf;
TRACE(_T("::executeCommandLine() failed at CreateProcess()\nCommand=%s\nMessage=%s\n\n"), g_minicapcmd, strError);
LocalFree(lpMsgBuf);
return false;
} else {
// Successfully created the process. Wait for it to finish.
WaitForSingleObject( processInformation.hProcess, INFINITE );
// Close the handles.
CloseHandle( processInformation.hProcess );
CloseHandle( processInformation.hThread );
}
is there a way to get it to cache or some way to make it faster? i already tried putting the .exe its loading on ramdisk and that helped a bit

Locking a drive with FSCTL_LOCK_VOLUME

I'm having trouble locking my C drive so I can extract some file information later.
#define wszDrive L"\\\\.\\PhysicalDrive0"
HANDLE targetVol = INVALID_HANDLE_VALUE;
DWORD stats;
targetVol = CreateFile(wszDrive,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
/*FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS*/0,
NULL);
if (targetVol == INVALID_HANDLE_VALUE) // cannot open the drive
{
cout << "error in ioControl with volume handler" << endl;
system("pause");
}
if (DeviceIoControl(targetVol,
FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0,
&stats,
NULL) ==0)
{
cout << "Error with targetVol DeviceIo" << endl;
ErrorExit(TEXT("GetProcessId"));
system("pause");
}
The Error exit below returns "GetProcessID faile with error 1: Incorrect function."
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
Do you guys have any idea what's going on wrong?
The MSDN docs for FSCTL_LOCK_VOLUME say right off the bat that
Locks a volume if it is not in use
The C: drive is almost always in use. The only time it's not in use is if you've booted from different media.

'XcvData' was not declared in this scope

I'm trying to install a virtual printer with Ghostscript and RedMon which prints to a PDF file using c++, but when i try to compile my code, i got 'XcvData' was not declared in this scope on the function below:
#include <windows.h>
#include <winspool.h>
BOOL AddPort()
{
DWORD cbneed,cbstate;
PBYTE pOutputData;
HANDLE hXcv = INVALID_HANDLE_VALUE;
PRINTER_DEFAULTS Defaults = { NULL,NULL,SERVER_ACCESS_ADMINISTER };
WCHAR pszPortName[]=L"UTReportPDFPort:";
pOutputData=(PBYTE)malloc(MAX_PATH);
if(!OpenPrinter((WCHAR*)",XcvMonitor Redirected Port",&hXcv,&Defaults ))
{
LPVOID lpMsgBuf;
GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), NULL,(LPTSTR) &lpMsgBuf, 0, NULL );
::MessageBox(0,(LPCTSTR)lpMsgBuf,(WCHAR*)"ERROR",MB_OK|MB_ICONINFORMATION);
free(pOutputData);
LocalFree( lpMsgBuf );
return FALSE;
}
if(!XcvData(hXcv,L"AddPort",(PBYTE)pszPortName,sizeof(pszPortName),(PBYTE)pOutputData,MAX_PATH,&cbneed,&cbstate))
{
LPVOID lpMsgBuf;
SetLastError(cbstate);
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), NULL,(LPTSTR) &lpMsgBuf, 0, NULL );
::MessageBox(0,(LPCTSTR)lpMsgBuf,(WCHAR*)"ERROR",MB_OK|MB_ICONINFORMATION);
LocalFree( lpMsgBuf );
free(pOutputData);
}
free(pOutputData);
ClosePrinter(hXcv);
return TRUE;
}
What i can do to use the XcvData function on my Qt application?