Reputation: 68053
I've accidentally removed Win2K compatibility from an application by using GetProcessID.
I use it like this, to get the main HWND for the launched application.
ShellExecuteEx(&info); // Launch application
HANDLE han = info.hProcess; // Get process
cbinfo.han = han;
//Call EnumWindows to enumerate windows....
//with this as the callback
static BOOL CALLBACK enumproc(HWND hwnd, LPARAM lParam)
{
DWORD id;
GetWIndowThreadProcessID(hwnd, &id);
if (id == GetProcessID(cbinfo.han))
setResult(hwnd)
...
}
Any ideas how the same function could be acheived on Win2K?
Upvotes: 4
Views: 4009
Reputation: 68053
Thanks to DavidK and Larry - Here's my final solution. Full error handling is left as an exercise for the reader.
Note that rather than specifically checking the OS version, I attempt to dynamically link to the functions. Static linking would mean that the application would simply fail to load if the procedure wasn't available.
This has been tried successfully on Win2K and Vista:
#include "Winternl.h"
typedef DWORD (WINAPI* pfnGetProcID)(HANDLE h);
typedef NTSTATUS (WINAPI* pfnQueryInformationProcess)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength);
DWORD MyGetProcessId(HANDLE h)
{
static pfnQueryInformationProcess ntQIP = (pfnQueryInformationProcess) GetProcAddress(GetModuleHandle("NTDLL.DLL"),"NtQueryInformationProcess");
static pfnGetProcID getPId = (pfnGetProcID) GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcessId");
if ((ntQIP == NULL) && (getPId == NULL))
throw Exception("Can't retrieve process ID : GetProcessID not supported");
if (getPId != NULL)
return getPId(h);
else
{
PROCESS_BASIC_INFORMATION info;
ULONG returnSize;
ntQIP(h, ProcessBasicInformation, &info, sizeof(info), &returnSize); // Get basic information.
return info.UniqueProcessId;
}
}
Upvotes: 3
Reputation: 16142
DavidK's right. Please see the comment in the ZwQueryInformationProcess documentation:
[ZwQueryInformationProcess may be altered or unavailable in future versions of Windows. Applications should use the alternate functions listed in this topic.]
That means that Microsoft can choose to remove this at any time in the future, thus breaking your application. I strongly consider you follow DavidK's advice and use ZwQueryInformationProcess on OS's that don't support GetProcessID and use GetProcessID on OS's that support it (XP SP1 and above).
Upvotes: 4
Reputation:
No, it's not ZwQueryInformationProcess() It's NtQIP and of course it works for all versions since NT 3.5 and you don't need to test OS at all
Upvotes: -1
Reputation:
There is an 'sort-of-unsupported' function: ZwQueryInformationProcess(): see
http://msdn.microsoft.com/en-us/library/ms687420.aspx
This will give you the process id (amongst other things), given the handle. This isn't guaranteed to work with future Windows versions, so I'd suggest having a helper function that tests the OS version and then uses GetProcAddress() to call either GetProcessId() for XP and above, and ZwQueryInformationProcess() for Win2K only.
Upvotes: 6