Windows Socket and Authentication build failed when including Poco-Library - c++

I have written a C++ program to authenticate windows user which is working seamlessly when Poco Library (Event) has not been included. I have a infinite while loop (while(true)) that needs to be halted when no request are coming from the serer application. Socket read runs independently in a separate thread.
Compiler : MingW 7.2
C++ Standard : C++14
Package Manager : Msys2
Architecture : x64
I am getting an error :
g++ -c -g -D__DEBUG -I/C/msys64/mingw64/include/boost -I/C/msys64/mingw64/include `pkg-config --cflags libconfig++` `pkg-config --cflags gnutls` -std=c++14 -MMD -MP -MF "build/Debug/MinGW-Windows/Authenticate.o.d" -o build/Debug/MinGW-Windows/Authenticate.o Authenticate.cpp
In file included from C:/msys64/mingw64/include/Poco/Foundation.h:102:0,
from C:/msys64/mingw64/include/Poco/Event.h:23,
from Common.hpp:41,
from Authenticate.hpp:19,
from Authenticate.cpp:14:
C:/msys64/mingw64/include/Poco/Platform_WIN32.h:179:92: note: #pragma message: Compiling POCO on Windows without #define POCO_WIN32_UTF8 is deprecated.
#pragma message("Compiling POCO on Windows without #define POCO_WIN32_UTF8 is deprecated.")
^
Authenticate.cpp: In member function 'bool Authenticate::authenticateUserCommandLine(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string, std::__cxx11::string&)':
Authenticate.cpp:30:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:30:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
Authenticate.cpp:32:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:32:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
Authenticate.cpp: In member function 'bool Authenticate::authenticateUserCommandLine(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string&)':
Authenticate.cpp:54:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:54:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
Authenticate.cpp:56:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:56:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
If I remove #include <Poco/Event.h> the program works properly without error.
If I add #define POCO_WIN32_UTF8, I have to replace LogonUser with LogonUserW. The biggest issue I have with adding #define POCO_WIN32_UTF8 is that I am getting an error at ::GetLastError() saying function not found.
LoginUser Usage :
if(password.length() == 0)
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
else
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
::GetLastError() Usage :
string Error::GetLastErrorAsString(void)
{
//Get the error message, if any.
DWORD errorMessageID = ::GetLastError();
if(errorMessageID == 0)
return string(); //No error message has been recorded
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
string message(messageBuffer, size);
//Free the buffer.
LocalFree(messageBuffer);
return message;
}

The problem was that I had included Poco/Event.h before windows.h. Poco/Event.h needs #define POCO_WIN32_UTF8 to be defined before including the header which caused the problem.
The problem was solved by including windows.h before defining #define POCO_WIN32_UTF8 which in turn was defined before including Poco/Event.h.

Related

CreateProcessA not working or returning any errors

I've tried to used both CreateProcessA and CreateProcess to create a instance of notepad, but to no success. CreateProcess always returns an error code of 2 when I run it, but CreateProccessA doesn't return anything at all.
This is what I have so far:
STARTUPINFOA startInfo;
PROCESS_INFORMATION processInfo;
ZeroMemory(&startInfo, sizeof(startInfo));
startInfo.cb = sizeof(startInfo);
ZeroMemory(&processInfo, sizeof(processInfo));
if (CreateProcessA(NULL, NULL,NULL,NULL,FALSE,NULL, NULL, "C:\\Windows\\notepad.exe", &startInfo, &processInfo)) {
DWORD Error = GetLastError();
MessageBoxA(NULL, "FAILED", "FAILED", MB_OK);
printf("%d", Error);
return 1;
}
Error 2 is ERROR_FILE_NOT_FOUND. You are passing the path to notepad.exe in the lpCurrentDirectory parameter, but it needs to be passed in the lpApplicationName or lpCommandLine parameter instead:
CreateProcessA("C:\\Windows\\notepad.exe", NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &startInfo, &processInfo)
CreateProcessA(NULL, "C:\\Windows\\notepad.exe", NULL, NULL, FALSE, NULL, NULL, NULL, &startInfo, &processInfo)
Also, you are calling GetLastError() when CreateProcessA() is successful. You need to call it when CreateProcessA() fails instead:
if (!CreateProcessA(...)) { // <-- note the !
DWORD Error = GetLastError();
...
}
Lastly, the %d specifier of printf() expects an int, not a DWORD. Use %ul instead, which expects an unsigned long, which is what DWORD is defined as:
printf("%ul", Error);

Convert argument to LPWSTR CreateProcess

I am trying to perform some actions using cmd.exe but I want to hide cmd.exe. When I tried to use full path instead of cmd.exe I always get this error:
char Process[] = "C:\\WINDOWS\\System32\\cmd.exe";
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
memset(&sinfo, 0, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
sinfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
sinfo.hStdInput = sinfo.hStdOutput = sinfo.hStdError = (HANDLE)mySocket;
CreateProcess(NULL, Process, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo);
WaitForSingleObject(pinfo.hProcess, INFINITE);
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
I always get:
CreateProcessW(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,LPVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION)': cannot convert argument 2 from 'char [28]' to 'LPWSTR' ConsoleApplication1
You are passing a narrow character array instead of a wide character array.
Change your project's character encoding setting to MultiByte instead of Unicode so that CreateProcess uses CreateProcessA instead of CreateProcessW.
Or, use wchar_t (or WCHAR, which is a typedef available in Windows for wchar_t) instead of char:
wchar_t Process[] = L"C:\\WINDOWS\\System32\\cmd.exe";
Or, you can change the code to use CreateProcessA manually:
char Process[] = "C:\\WINDOWS\\System32\\cmd.exe";
...
CreateProcessA(NULL, Process, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo);
...

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.

'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?

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");