C++ Correct Usage of LPDWORD - c++

I have an array of hWnds of buttons that I want to monitor for clicks. I also have an array of HWINEVENTHOOKs that I will use to monitor them. GetWindowThreadProcessID gives me an LPDWORD process ID, which is not accepted by SetWinEventHook. I am unclear on whether I am correctly using LPDWORDs in this example. Please could somebody point me in the right direction?
EDIT: Thank you to everyone who contributed, I have posted the corrected code below.
New Code:
int i = 0;
for (HWND hWnd : hWnds) {
DWORD processID = 0;
DWORD threadID = GetWindowThreadProcessId(hWnd, &processID);
hooks[i] = SetWinEventHook(EVENT_OBJECT_INVOKED, EVENT_OBJECT_INVOKED,
NULL,
WinEventProcCallback, processID, threadID, WINEVENT_OUTOFCONTEXT);
i++;
}

LPDWORD is just a typedef for DWORD* and when a Windows SDK function parameter is a "LPsomething" you generally need to pass a pointer to a "something" (except for the LP[C][W]STR string types).
DWORD processID;
DWORD threadID = GetWindowThreadProcessId(hWnd, &processID);
if (threadID)
{
// Do something with threadID and/or processID
}
The Windows SDK uses Systems Hungarian notation for the Desktop/Classic API.

Related

How to assign value to LPVOID buffer of ReadFile

I am developing a win32 API hook program.
Accordingly to my understanding, when a program calls ReadFile for a particular file, the content of that file is copied to lpBuffer(see the definition below),
ReadFile definition:
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
Now, my target is to alter this lpBuffer and fill it with provided content by me!
I am using EasyHook to hook ReadFile. I am not familiar with LPVOID type. I was able to alter the content for GetCurrentDirectory using the following code.
string b = "C:\\my\\altered\\directory";
DWORD returnLength = b.length();
int i;
for (i = 0; i<b.length(); i++)
{
lpBuffer[i] = b[i];
}
lpBuffer[i++] = '\0';
GetCurrentDirectory definition:
DWORD GetCurrentDirectory(
DWORD nBufferLength,
LPTSTR lpBuffer
);
How to do similar value assignment for ReadFile (LPVOID lpBuffer)?
Here's the LPVOID typedef:
#define far
typedef void far *LPVOID;
The far macro is defined as nothing, I guess it's because of some historical reasons (baggage).
So you can almost directly treat the LPVOID as void*.
And now, suppose you have a std::vector<uint8_t> named FakeData, just:
if (nNumberOfBytesToRead < FakeData.size()) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
memcpy(lpBuffer, FakeData.data(), FakeData.size());
*lpNumberOfBytesRead = FakeData.size();
SetLastError(ERROR_SUCCESS);
return TRUE;

C++ Process Monitoring (GetExitCodeProcess)

I want to monitor a process in c++, so I'm using:
std::wstring windowName = TEXT("needle");
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
The FindWindow function, as I understand it, checks the title for all windows (Why did Microsoft name their OS after a core part of it, checking windows in Windows, madness). If a title matches "needle" then it gives me the...
HWND windowHandle
Next I am using:
DWORD* PID;
GetWindowThreadProcessId(windowHandle, PID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, *PID);
This gives me the processID or PID as I've named it. I can then use that to...
HWND p;
DWORD state;
GetExitCodeProcess(p, &state);
... get the state of the process, I'm going to check for it being "STILL_ACTIVE", like so:
if (state != STILL_ACTIVE) {
std::cout << "excessive profanity\n";
}
else {
std::cout << "sigh of relief\n";
}
Except this doesn't work, "cout-ing" (new verb) the value of state gives me some kind of hexadecimal code. It's never "STILL_ACTIVE" despite having multiple windows with "needle" as the title. The code compiles fine, it's just something to do with conversion, pointers, LPCWSTR's or something I've never come across. Help would be appreciated. Thanks
You have two problems:
1) As PaulMcKenzie points out in his answer, PID points to nothing, and will cause problems. Instead you should declare a DWORD and pass a pointer to it to GetWindowThreadProcessId:
DWORD PID;
// note: &PID instead of just PID
GetWindowThreadProcessId(windowHandle, &PID);
// note: Just PID instead of *PID
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
2) GetExitCodeProcess needs a handle to a process, not an uninitialized HWND. Instead you should give it the handle returned from OpenProcess:
DWORD state;
// note: this is the hProcess returned from OpenProcess
GetExitCodeProcess(hProcess, &state);
Note that this will still only work for one process. If multiple processes have windows with the title "needle" then the result of your FindWindow call will be unpredictable.
One error (and probably not the only error) is that there is no way this can work correctly:
DWORD* PID;
GetWindowThreadProcessId(windowHandle, PID);
You are giving GetWindowThreadProcessId an uninitialized pointer, PID. There is nothing that the function can do with it except dereference it (causing undefined behavior), or at best, check if the value is NULL.
When a function asks for a pointer, it doesn't mean you literally declare a pointer and pass it to the function. The function wants the address of an existing entity:
DWORD PID;
GetWindowThreadProcessId(windowHandle, &PID);

Invalid Monitor Handle Error When Executing SetMonitorBrightness Function In Windows - C++

I am writing a program in Windows and I want to get the brightness of a computer monitor. I am using the Windows GetMonitorBrightness function, however I am having some trouble.
this is my code so far:
DWORD dw;
HMONITOR hMonitor = NULL;
DWORD cPhysicalMonitors;
LPPHYSICAL_MONITOR pPhysicalMonitors = NULL;
LPDWORD pdwMinimumBrightness=NULL;
LPDWORD pdwCurrentBrightness=NULL;
LPDWORD pdwMaximumBrightness=NULL;
HWND hwnd = FindWindow(NULL, NULL);
hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &cPhysicalMonitors);
pPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc(cPhysicalMonitors* sizeof(PHYSICAL_MONITOR));
bSuccess = GetPhysicalMonitorsFromHMONITOR(hMonitor, cPhysicalMonitors, pPhysicalMonitors);
bSuccess = GetMonitorBrightness(hMonitor, pdwMinimumBrightness, pdwCurrentBrightness, pdwMaximumBrightness);
I wrote this following the documentation at http://msdn.microsoft.com/en-us/library/windows/desktop/dd692972%28v=vs.85%29.aspx
but when I run this code I get an error saying "This function failed because an invalid monitor handle was passed to it".
I can't see anything wrong with the code I wrote, but I cannot seem to figure out the reason for this error.
EDIT: I should mention I am trying this out on a CRT monitor
EDIT 2: Fixed this problem, turns out I wasn't passing a proper handle to GetMonitorBrightness.
bSuccess = GetPhysicalMonitorsFromHMONITOR(hMonitor, cPhysicalMonitors, pPhysicalMonitors);
HANDLE pmh = pPhysicalMonitors[0].hPhysicalMonitor; //<---------------
bSuccess = GetMonitorBrightness(pmh, pdwMinimumBrightness, pdwCurrentBrightness, pdwMaximumBrightness);
Adding the marked line above, solved this problem
Add #pragma comment(lib,"Dxva2.lib") next to the #include file.
You aren't checking the return value of MonitorFromWindow. If the monitor is not found, it will return NULL because you have passed MONITOR_DEFAULTTONULL. Null is not a monitor handle.
Try MONITOR_DEFAULTTONEAREST or MONITOR_DEFAULTTOPRIMARY.

Is it possible to hook the creation of windows globally so I can control where the windows are placed on the screen?

I can inject a hook into running processes to catch when they create, destroy, max/min. But I haven't come up with a way to catch the creation of a new process so that I can inject my hook into that one.
Does anyone know the best way to accomplish this?
SetWindowsHookEx is your easiest solution.
If you don't mind upsetting the anti-virus software, you can also inject a DLL into each process that will then hook CreateProcess (to inject the DLL into further processes) and CreateWindowEx (for your purposes).
EDIT: I just read your question completely. Yes, you'll want to just hook CreateProcessW and inject your hook into future processes.
EDIT #2: I was actually working on something like this yesterday, so some code which does what you want.
#include <windows.h>
// call GetModuleFileNameto get the full path of the module before installing the hook
static LPWSTR lpszDllName;
HMODULE LoadModuleEx(__in HANDLE hProcess, __in_z LPCTSTR lpcszDll)
{
DWORD cdwSize;
LPVOID lpvAllocation;
HANDLE hThread;
HMODULE hRet;
cdwSize = lstrlen(lpcszDll) + 1;
cdwSize *= sizeof(TCHAR);
lpvAllocation = VirtualAllocEx(hProcess, NULL, cdwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpvAllocation != NULL)
{
if (WriteProcessMemory(hProcess, lpvAllocation, lpcszDll, cdwSize, NULL))
{
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, lpvAllocation, 0, NULL);
if (hThread != NULL)
{
GetExitCodeThread(hThread, (LPDWORD)&hRet);
CloseHandle(hThread);
}
}
VirtualFreeEx(hProcess, lpvAllocation, cdwSize, MEM_DECOMMIT);
}
return hRet;
}
// hook future process creation - install this hook on top of CreateProcessW
// I'd suggest using Microsoft Detours [http://research.microsoft.com/en-us/projects/detours/]
BOOL WINAPI CreateProcessWHook(__in_opt LPCWSTR lpApplicationName, __inout_opt LPWSTR lpCommandLine, __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCWSTR lpCurrentDirectory, __in LPSTARTUPINFO lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation)
{
// create the process suspended
if (dwCreationFlags & CREATE_SUSPENDED != CREATE_SUSPENDED)
dwCreationFlags |= CREATE_SUSPENDED;
// call original CreateProcessW
BOOL bRet = _CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
if (bRet)
{
// inject DLL
LoadModuleEx(lpProcessInformation->hProcess, lpszDllName);
// resume thread
ResumeThread(lpProcessInformation->hThread);
}
return bRet;
}
You'll want to use a system hook using SetWindowsHookEx. That will then allow you to provide a callback when applications (for example) create a window.
As other people have mentioned, using SetWindowsHookEx to create a shell hook is probably the optimal solution.
If you're really serious about catching the creation of new processes and injecting your own code, you'll have to load a kernel driver and use PsSetLoadImageNotifyRoutine, but this is almost certainly the wrong approach.

How to ensure only one process is created by CreateProcess when calling concurrently in c++?

Quoted from here:
BOOL WINAPI CreateProcess(
__in_opt LPCTSTR lpApplicationName,
__inout_opt LPTSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCTSTR lpCurrentDirectory,
__in LPSTARTUPINFO lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
I have two independant programe that creates exactly the same process, how can I ensure that if one of them has already created the process, the other won't create it twice?
The most simple way is if you create a named object after the start of the program. For example CreateEvent, CreateMutex and so on. To verify existance of the application you can just use OpenEvent, OpenMutex and so on before creating of the object. You can choose (if desired) the name of the object with the the "Global\" prefix (see http://msdn.microsoft.com/en-us/library/aa382954.aspx) to allow only one process for all terminal server session.
UPDATED: Because how I can see there are different opinions about my suggestion I try to explain it more exactly and add the corresponding test example.
The main idea is that the application which are started create any named object is the object with the same name not yet exist. This only reserve the name in the Kernel Object Namespaces. No real usage of the object are needed. The advantaged of this way compared with creating of a file on the disk is that named objects are temporary and are owned by a application. So if the application are ended, be killed or be terminated in any other way (because of unhanded exception for example) the named object will be automatically deleted by the operation system. In the following example I don't use CloseHandle at all. How you can test the application can successfully determine whether it runs as the first instance or not.
#include <windows.h>
//#include <Sddl.h>
LPCTSTR g_pszEventName = TEXT("MyTestEvent"); // TEXT("Global\\MyTestEvent")
void DisplayFirstInstanceStartedMessage()
{
TCHAR szText[1024];
wsprintf (szText,
TEXT("The first instance are started.\nThe event with the name \"%s\" is created."),
g_pszEventName);
MessageBox (NULL,
szText,
TEXT("CreateEventTest"), MB_OK);
}
void DisplayAlreadyRunningMessage ()
{
TCHAR szText[1024];
wsprintf (szText,
TEXT("The first instance of the aplication is already running.\nThe event with the name \"%s\" already exist."),
g_pszEventName);
MessageBox (NULL,
szText,
TEXT("CreateEventTest"), MB_ICONWARNING | MB_OK);
}
void DisplayErrorMessage (DWORD dwErrorCode)
{
if (dwErrorCode == ERROR_ALREADY_EXISTS)
DisplayAlreadyRunningMessage();
else {
LPTSTR pErrorString;
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | // Always search in system message table !!!
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
0, NULL, // source of message definition
dwErrorCode, // message ID
// 0, // language ID
// GetUserDefaultLangID(), // language ID
// GetSystemDefaultLangID(),
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&pErrorString, // pointer for buffer to allocate
0, // min number of chars to allocate
NULL)) {
MessageBox (NULL, pErrorString, TEXT("CreateEventTest"), MB_OK);
LocalFree (pErrorString);
}
else {
TCHAR szText[1024];
wsprintf (szText, TEXT("Error %d in the CreateEvent(..., \"%s\")"), dwErrorCode, g_pszEventName);
MessageBox (NULL, szText, TEXT("CreateEventTest"), MB_OK);
}
}
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//SECURITY_ATTRIBUTES sa;
//BOOL bSuccess;
HANDLE hEvent = OpenEvent (EVENT_MODIFY_STATE, FALSE, g_pszEventName);// EVENT_ALL_ACCESS
if (hEvent == NULL) {
DWORD dwErrorCode = GetLastError();
if (dwErrorCode != ERROR_FILE_NOT_FOUND) {
DisplayErrorMessage(dwErrorCode);
return 1;
}
}
else {
DisplayAlreadyRunningMessage();
return 0;
}
//sa.bInheritHandle = FALSE;
//sa.nLength = sizeof(SECURITY_ATTRIBUTES);
//bSuccess = ConvertStringSecurityDescriptorToSecurityDescriptor (
// TEXT("D:(A;OICI;GA;;;WD)"), // Allow full control
// SDDL_REVISION_1,
// &sa.lpSecurityDescriptor,
// NULL);
hEvent = CreateEvent (NULL, // &sa
TRUE, FALSE, g_pszEventName);
//sa.lpSecurityDescriptor = LocalFree (sa.lpSecurityDescriptor);
if (hEvent == NULL) {
DWORD dwErrorCode = GetLastError();
DisplayErrorMessage(dwErrorCode);
return 1;
}
else
DisplayFirstInstanceStartedMessage();
return 0;
UNREFERENCED_PARAMETER (hInstance);
UNREFERENCED_PARAMETER (hPrevInstance);
UNREFERENCED_PARAMETER (lpCmdLine);
UNREFERENCED_PARAMETER (nShowCmd);
}
If one want support that different users from the same desktop or from the different desktops could start only one instance of the program, one can uncomment some parts of the commented code or replace the name MyTestEvent of the event to Global\MyTestEvent.
I hope after the example my position will be clear. In such kind of the event usage no call of WaitForSingleObject() are needed.
You cannot do this by letting the process you start creating a named object. That's an inherent race condition, it takes time for the process to get started. Both programs need to call CreateMutex at some point before trying to create the 3rd process with an agreed-upon name. Then they need to call WaitForSingleObject() with a zero wait time to try to acquire the mutex. Whomever gets it is the one that should call CreateProcess().
More work is needed after this to deal with this 3rd process terminating.
You can use this function
BOOL WINAPI EnumProcesses(
__out DWORD *pProcessIds,
__in DWORD cb,
__out DWORD *pBytesReturned
);
to get a list of all the pids of all currently running processes and check if the process is running?