正如arx所提到的,ProcessIdToSessionId
应该做这项工作。
但不幸的是,就我而言,它告诉我ACCESS_DENIED
我感兴趣的流程。
它为当前流程工作。
所以这是我的解决方案,使用NtQuerySystemInformation
.
.NETsProcess
类在内部使用相同的功能。
typedef struct _SYSTEM_PROCESS_INFORMATION_BUG {
//...
}
typedef NTSTATUS (WINAPI *PNtQuerySystemInformation) (
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
#ifndef NT_ERROR
#define NT_ERROR(Status) ((ULONG)(Status) >> 30 == 3)
#endif
#define PROCESSINFO_BUFFERSIZE (256*1024)
DLL_EXPORT int GetProcessIdFromPath2(char *exePath, int flags) {
char exe[MAX_PATH], *exeName, file[MAX_PATH], *fileName;
DWORD pidCurrent, sessionIdCurrent;
int ret=-1;
strcpy(exe, exePath);
strupr(exe);
exeName=getFileName(exe);
pidCurrent = GetCurrentProcessId();
if (!ProcessIdToSessionId(pidCurrent, &sessionIdCurrent)) sessionIdCurrent=0;
HMODULE hNT = LoadLibrary("Ntdll.dll");
if (hNT) {
PNtQuerySystemInformation pNtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress(hNT, "NtQuerySystemInformation");
if (pNtQuerySystemInformation) {
SYSTEM_PROCESS_INFORMATION_BUG* processInfo;
char *buffer = (char*)malloc(PROCESSINFO_BUFFERSIZE);
if (!buffer) {
ret=-3;
}
else {
char *current=buffer;
DWORD len;
int count=0;
NTSTATUS s = pNtQuerySystemInformation(SystemProcessInformation, buffer, PROCESSINFO_BUFFERSIZE, &len);
if (NT_ERROR(s)) {
ret=-2;
}
else {
ret=0;
while(1) {
processInfo = (SYSTEM_PROCESS_INFORMATION_BUG*)current;
if (processInfo->ImageName.Buffer!=NULL){
wcstombs(file, processInfo->ImageName.Buffer, MAX_PATH-1);
strupr(file);
fileName=getFileName(file);
if (strcmp(fileName, exeName)==0) {
if (processInfo->UniqueProcessId!=pidCurrent) {
if (processInfo->SessionId==sessionIdCurrent) {
ret = processInfo->UniqueProcessId;
}
}
}
}
if (processInfo->NextEntryOffset==0) break;
current+=processInfo->NextEntryOffset;
count++;
}
}
free(buffer);
buffer=NULL;
}
}
FreeLibrary(hNT);
}
return ret;
}