'XcvData' was not declared in this scope - c++

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?

Related

Deleting a Standard TCP IP port using xcvdata not working

Xcvdata() for deleting port.
BOOL DeletePortCus( TCHAR* PortName )
{
HANDLE hPrinter;
PRINTER_DEFAULTS PrinterDefaults;
memset(&PrinterDefaults, 0, sizeof(PrinterDefaults));
PrinterDefaults.pDatatype = NULL;
PrinterDefaults.pDevMode = NULL;
PrinterDefaults.DesiredAccess = SERVER_ACCESS_ADMINISTER;
DWORD needed = 0;
DWORD rslt = 0;
//Port data
PORT_DATA_1 pOutputData ;
DWORD error = 0;
if (!OpenPrinter(L",XcvMonitor Standard TCP/IP Port", &hPrinter, &PrinterDefaults))
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), NULL,(LPTSTR) &lpMsgBuf, 0, NULL );
_tprintf( TEXT("Error in OpenPrinter. Error msg : %s"),lpMsgBuf);
LocalFree( lpMsgBuf );
return FALSE;
}
DWORD xcvresult= 0;
if (
!XcvData(
hPrinter,
TEXT("DeletePort"),
(PBYTE)PortName,
(lstrlen(PortName) +1) * sizeof(TCHAR), //the 1 is for the trailing NULL
( byte * ) &pOutputData,
sizeof(PORT_DATA_1),
&needed,
&xcvresult)
)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), NULL,(LPTSTR) &lpMsgBuf, 0, NULL );
_tprintf( TEXT("Error in XcvData. Error msg : %s; XcvDataPort status val = %d"), lpMsgBuf, xcvresult);
LocalFree( lpMsgBuf );
return FALSE;
}
ClosePrinter(hPrinter);
return TRUE;
}
The highlight is both the functions (openprinter and xcvdata) succeed. But the port is not getting removed. I am completely at a loss here as I dont have any error to lookup.
Instead of ,XcvMonitor Standard TCP/IP Port I also tried with ,XcvPort <portname>. Still same.
As Samer suggested below, I tried with OpenPrinter2 with no cache option.
PS: I know there's this simple alternative DeletePort(), but it invokes a UI dialog box if it fails, so I don't want to use it.
It seems the issue might be related to specific version of OS which caches printer handles. To get around this you use an alternate call OpenPrinter2 with the PRINTER_OPTION_NO_CACHE. Below is the modified code with the flag set.
HANDLE hPrinter;
PRINTER_DEFAULTS PrinterDefaults;
memset(&PrinterDefaults, 0, sizeof(PrinterDefaults));
PrinterDefaults.pDatatype = NULL;
PrinterDefaults.pDevMode = NULL;
PrinterDefaults.DesiredAccess = SERVER_ACCESS_ADMINISTER;
PRINTER_OPTIONS PrinterOptions;
PrinterOptions.cbSize = sizeof(PrinterOptions);
PrinterOptions.dwFlags = PRINTER_OPTION_NO_CACHE;
DWORD needed = 0;
DWORD rslt = 0;
//Port data
PORT_DATA_1 pOutputData ;
DWORD error = 0;
if (!OpenPrinter2(L",XcvMonitor Standard TCP/IP Port", &hPrinter, &PrinterDefaults, &PrinterOptions))
{
LPVOID lpMsgBuf;

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

Code Injection doesn't work on Vista or Win7?

So I had to two friends test the executable on their Vista & Win7 operating systems. Neither had the injected code executed (even when Run as Administrator) but the console open/closed. Does code injection via WriteProcessMemory and CreateRemoteThread still work on Vista or Win7?
The Code
Compiled using /RTCu on Visual Studio 2008 to prevent process crashing while on Windows XP after the remote thread terminates.
CodeInjector.h
#ifndef CODEINJECTOR_H
#define CODEINJECTOR_H
typedef HANDLE(WINAPI *GETPROC)();
typedef HMODULE(WINAPI *PLOADLIBRARYA)(const char *dll);
typedef LPVOID(WINAPI *PGETPROCADDRESS)(HMODULE mod, const char *func);
typedef int (WINAPI *FNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT);
typedef struct _IAT {
PLOADLIBRARYA pLoadLibraryA;
PGETPROCADDRESS pGetProcAddress;
FNMESSAGEBOX fnMessageBox;
} IAT;
typedef struct _DATA {
void *szData[256];
} DATA;
typedef struct _FNARGS {
LPVOID pIat;
LPVOID pData;
} FNARGS;
#endif /* CODEINJECTOR_H */
CodeInjector.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include <windows.h>
#include "CodeInjector.h"
using namespace std;
HANDLE getHandleByName(const char* nameWnd)
{
HWND hWnd = FindWindowA(0, nameWnd);
if (hWnd == 0) {
std::cerr << "Cannot find window" << std::endl;
} else {
DWORD pId;
GetWindowThreadProcessId(hWnd, &pId);
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, 0, &tkp, sizeof (tkp), NULL, NULL);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
if (!hProc) {
std::cerr << "Cannot open process: " << GetLastError() << std::endl;
} else {
return hProc;
}cout << hProc;
getchar();
}
return false;
}
static DWORD WINAPI ThreadFunc(FNARGS *info)
{
if (info == NULL || info->pIat == NULL || info->pData == NULL) {
return 0;
}
IAT *iat = (IAT *)info->pIat;
DATA *data = (DATA *)info->pData;
iat->fnMessageBox(NULL, (char*)data->szData[1], (char*)data->szData[0], MB_OK);
return 0;
}
static void ThreadFuncEnd() {}
int main(int argc, char** argv)
{
HANDLE hProc = getHandleByName("Calculator");
DWORD CodeSize = (DWORD) & ThreadFuncEnd - (DWORD) & ThreadFunc;
IAT hIAT;
DWORD hLibModule;
HMODULE hKernel = LoadLibraryA("kernel32.dll");
HMODULE hUser32 = LoadLibraryA("user32.dll");
hIAT.pLoadLibraryA = (PLOADLIBRARYA)GetProcAddress(hKernel, "LoadLibraryA");
hIAT.pGetProcAddress = (PGETPROCADDRESS)GetProcAddress(hKernel, "GetProcAddress");
hIAT.fnMessageBox = (FNMESSAGEBOX)GetProcAddress(hUser32, "MessageBoxA");
LPVOID hIATMemAddr = VirtualAllocEx(hProc, NULL, sizeof (IAT), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, hIATMemAddr, (LPVOID) & hIAT, sizeof (IAT), NULL);
DATA hData;
LPVOID hDataMemAddr = VirtualAllocEx(hProc, NULL, sizeof (DATA), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[0] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[1] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[2] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
hData.szData[3] = VirtualAllocEx(hProc, NULL, 64, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
char tmp[64];
strcpy(tmp, "Caption");
WriteProcessMemory(hProc, hData.szData[0], (LPVOID) & tmp, sizeof (tmp), NULL);
strcpy(tmp, "Message");
WriteProcessMemory(hProc, hData.szData[1], (LPVOID) & tmp, sizeof (tmp), NULL);
WriteProcessMemory(hProc, hDataMemAddr, (LPVOID) &hData, sizeof (DATA), NULL);
FNARGS tInfo;
tInfo.pIat = hIATMemAddr;
tInfo.pData = hDataMemAddr;
LPVOID hInfoMemAddr = VirtualAllocEx(hProc, NULL, sizeof (FNARGS), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, hInfoMemAddr, (LPVOID) & tInfo, sizeof (FNARGS), NULL);
LPVOID CodeMemAddr = VirtualAllocEx(hProc, NULL, CodeSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProc, CodeMemAddr, (LPVOID) & ThreadFunc, CodeSize, NULL);
HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)CodeMemAddr, hInfoMemAddr, 0, NULL);
WaitForSingleObject(hRemoteThread, INFINITE);
GetExitCodeThread(hRemoteThread, &hLibModule);
CloseHandle(hProc);
return 0;
}
Not really a surprise. Vista and Windows 7 have increased security. Lots of malware used Code Injection as one of the steps to bypass security mechanisms on Windows XP, and I'm glad to see Microsoft fixed this.

install driver using 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");