i have a need to find out if a process is running
i have a null-terminated string pointer (like 'SomeProc.exe',0)
i would like the function to return the PID if the process is running, or 0 if it isn't
it would be nice if it would work from Win 2000 through Win 7
currently, my game-plan is to use EnumProcesses, OpenProcess, then GetModuleFileName
i was wondering if anyone had experience with this kind of function
and, if so, if you used GetModuleFileName or one of the other functions to retrieve the process name
From my system.lib library, only works with NT based systems (ie NT4.0+). Note that it uses GetProcAddress for the API functions so it will not cause a program to fail if it is loaded (but not executed) on a Win9x system.
#Define SystemProcessInformation 5
#Define PAGE_READWRITE 4
#Define MEM_COMMIT 1000h
#Define MEM_RELEASE 8000h
VM_COUNTERS STRUCT
// NtQueryInformationProcess using ProcessVmCounters
PeakVirtualSize DD
VirtualSize DD
PageFaultCount DD
PeakWorkingSetSize DD
WorkingSetSize DD
QuotaPeakPagedPoolUsage DD
QuotaPagedPoolUsage DD
QuotaPeakNonPagedPoolUsage DD
QuotaNonPagedPoolUsage DD
PagefileUsage DD
PeakPagefileUsage DD
ENDS
CLIENT_ID STRUCT
UniqueProcess DD
UniqueThread DD
ENDS
SYSTEM_THREAD STRUCT
KernelTime DQ
UserTime DQ
CreateTime DQ
WaitTime DD
StartAddress DD
ClientId CLIENT_ID <>
Priority DD
BasePriority DD
ContextSwitches DD
ThreadState DD // 2=running; 5=waiting
WaitReason DD
ENDS
ANSI_STRING STRUCT
Length dw
MaximumLength dw
Buffer DD
ENDS
UNICODE_STRING STRUCT
Length DW
MaximumLength DW
Buffer DD
ENDS
SYSTEM_PROCESS_INFORMATION STRUCT
dNext DD
dThreadCount DD
dReserved01 DD
dReserved02 DD
dReserved03 DD
dReserved04 DD
dReserved05 DD
dReserved06 DD
qCreateTime DQ
qUserTime DQ
qKernelTime DQ
usName UNICODE_STRING <>
BasePriority DD
dUniqueProcessId DD
dInheritedFromUniqueProcessId DD
dHandleCount DD
dReserved07 DD
dReserved08 DD
VmCounters VM_COUNTERS <>
dCommitCharge DD
Threads SYSTEM_THREAD <>
ENDS
DATA SECTION
szFPBNDLL DB A"NTDLL.DLL",0
szFPBNFUNC DB A"NtQuerySystemInformation",0
CODE SECTION
FindProcessByNameNT FRAME pszProcess,StartID
uses edi,esi,ebx
LOCAL pProcessSnap :D
LOCAL buffer[256] :W
LOCAL hlib :D
LOCAL pNtQInf :D
invoke LoadLibraryA,offset szFPBNDLL
mov [hlib],eax
or eax,eax
jnz >
sub eax,eax
dec eax
ret
:
invoke GetProcAddress,[hlib],offset szFPBNFUNC
mov [pNtQInf],eax
or eax,eax
jnz >
sub eax,eax
dec eax
ret
:
mov edi,[pszProcess]
sub eax,eax
mov ecx,256
repne scasb
not cl
or ecx,ecx
jnz >
sub eax,eax
dec eax
ret
:
mov al, "\"
std
repne scasb
cld
add edi,2
or ecx,ecx
jnz >
mov edi,[pszProcess]
:
invoke MultiByteToWideChar,0,0,edi,-1,offset buffer,256
invoke VirtualAlloc,0,020000h,MEM_COMMIT,PAGE_READWRITE
mov [pProcessSnap],eax
mov esi,eax
or eax,eax
jnz >
sub eax,eax
dec eax
ret
:
invoke [pNtQInf],5,esi,20000h,0
; Find our processID
mov esi,[pProcessSnap]
L0:
mov ebx,[esi+SYSTEM_PROCESS_INFORMATION.dUniqueProcessId]
cmp ebx,[StartID]
jle >L1
; Do a quick compare to weed out the impossible ones by
; checking the first 2 characters to see if they match
lea eax, buffer
mov eax,[eax]
mov ecx,[esi+SYSTEM_PROCESS_INFORMATION.usName.Buffer]
or ecx,ecx
jz >L1
mov ecx,[ecx]
cmp eax,ecx
jne >L1
invoke lstrcmpiW,[esi+SYSTEM_PROCESS_INFORMATION.usName.Buffer],offset buffer
jz >.FOUND
L1:
mov eax,[esi+SYSTEM_PROCESS_INFORMATION.dNext]
add esi,eax
or eax,eax
jnz <L0
dec eax
push eax
jmp >.DONE
.FOUND
push ebx
.DONE
invoke VirtualFree,[pProcessSnap],0,MEM_RELEASE
invoke FreeLibrary,[hlib]
pop eax
or eax,eax
RET
ENDF
many thanks, Edgar :U
i'll just use your lib :P
Quote from: msdnNtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the alternate functions...
I would use the method dedndave describe here, but use GetModuleBaseName instead of GetModuleFileName.
just in case. here is something from one of my old projects.
ProcessWatch proc uses esi lpszProcessName:DWORD
LOCAL ProcessStructure:PROCESSENTRY32
LOCAL PID:DWORD
LOCAL hSnapshot:DWORD
NewSnapshot:
print "."
invoke Sleep, 100
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, ebx
mov hSnapshot, eax
mov eax, sizeof ProcessStructure
mov ProcessStructure.dwSize, eax
invoke Process32First, hSnapshot, addr ProcessStructure
@@:
invoke Sleep, 1
invoke Process32Next, hSnapshot, addr ProcessStructure
invoke GetLastError
.IF eax == ERROR_NO_MORE_FILES
invoke CloseHandle, hSnapshot
invoke SetLastError, ERROR_SUCCESS
jmp NewSnapshot
.ELSE
invoke lstrcmp, addr ProcessStructure.szExeFile, lpszProcessName
.IF eax == 0
mov eax, ProcessStructure.th32ProcessID
mov PID, eax
print " ", 13, 10, 13, 10
print "Process ID of target process :", 9
print str$(PID), 13, 10
invoke OpenProcess, PROCESS_ALL_ACCESS, TRUE, PID
mov esi, eax
print "Handle of target process :", 9
print str$(esi), 13, 10
invoke CloseHandle, hSnapshot
mov eax, esi
ret
.ELSE
jmp @b
.ENDIF
.ENDIF
ret
ProcessWatch endp
ew nasty code lol. old old code
Quote from: qWord on June 13, 2010, 07:21:34 PM
Quote from: msdnNtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the alternate functions...
I would use the method dedndave describe here, but use GetModuleBaseName instead of GetModuleFileName.
Still working up to and including Windows 7. Microsoft and many many third parties import this function in their tools, I can't see them deciding to trash it after 15 years and breaking hundreds of applications...
Quote from: donkey on June 13, 2010, 07:27:13 PMI can't see them deciding to trash it after 15 years and breaking hundreds of applications...
They have place this warning in their documentation, so it is possible that they break with this hundreds of applications.
Also there is no need to use this function - the normal API can do the same.
GetModuleFileName may not be as pretty as GetModuleBaseName
but, it would allow support back to Win 2000 (or even older - not sure)
Quote from: qWord on June 13, 2010, 07:44:41 PM
Quote from: donkey on June 13, 2010, 07:27:13 PMI can't see them deciding to trash it after 15 years and breaking hundreds of applications...
They have place this warning in their documentation, so it is possible that they break with this hundreds of applications.
Also there is no need to use this function - the normal API can do the same.
Actually they have placed that warning in many APIs over the years and they are almost all still around, in some the warning has been removed in some the function has been wrapped but the original still exists. Almost every one of the native API functions have that warning and AFAIK in the history of Windows only 17 of the Ntxxx functions have ever been removed. There are many many jobs in Windows that other functions can perform, that does not make them the best for the purpose, in this case the best function available is NtQuerySystemInformation. In the end Dave asked for it to work through to Windows 7 and it does, that is all that counts.
However you can use the kernel mode native api from user mode so ZwQuerySystemInformation is a direct replacement if you like, if MS breaks that it risks breaking drivers, another thing they learned from Vista would not be a good idea.
Also if you actually read the entry at MSDN I have followed their guidelines for usage:
QuoteIf you do use NtQuerySystemInformation, access the function through run-time dynamic linking. This gives your code an opportunity to respond gracefully if the function has been changed or removed from the operating system. Signature changes, however, may not be detectable.
Finally it is cited in several MSDN examples as well as by the moderators at MSDN social as the best way to obtain process specific information:
http://social.msdn.microsoft.com/Forums/en-GB/winforms/thread/002f27ac-e36d-429e-9377-661a212462ec
And comments like this by Microsoft MVP's make me think it will never be deprecated:
QuoteNtQuerySystemInformation is the only function currently available to get this list. It would be nice if there was a way to get all of the handles that your process has open, but unfortunately there is no way of doing this. Currently this is the only method known to work.
Edgar
I've never said, that it won't work.
However, it is strange that Microsoft's employs suggest to use it, while the documentation warn about it usage.
IMO compatibility of drivers can't be compare with compatibility of user land softwar. I'm not an expert on drivers, but for me they are OS-version specific (except for WDF stuff ?), so I would not see any problem when m$ decided to remove/change a Zw... functions.
My thought was: develop and forget - IMO Zw/NtQuerySystemInformation doesn't offers this :bg
qWord
Quote from: qWord on June 13, 2010, 11:21:02 PM
I've never said, that it won't work.
However, it is strange that Microsoft's employs suggest to use it, while the documentation warn about it usage.
IMO compatibility of drivers can't be compare with compatibility of user land softwar. I'm not an expert on drivers, but for me they are OS-version specific (except for WDF stuff ?), so I would not see any problem when m$ decided to remove/change a Zw... functions.
My though was: develop and forget - IMO Zw/NtQuerySystemInformation doesn't offers this :bg
qWord
Hi qWord,
Microsoft rarely deprecates any functions and I have not known them to do it to a function that is used as widely as that one. In the history of Windows I think MS has deprecated around 420 core functions (almost all in the change from 9x to NT) most of them kernel mode, around 100 of them were user mode functions and very few of those ever had that warning. So take the "develop and forget" attitude at your own risk...
But mostly that message is just MS covering their arses when dealing with the settlement API since it stung them badly in the court case.
Edgar
Quote from: donkey on June 13, 2010, 11:32:30 PM
But mostly that message is just MS covering their arses when dealing with the settlement API since it stung them badly in the court case.
They should add warnings for all functions ... just for being one the save side :toothy
I tend to come down on the side of using only published API calls even though the NTDLL ones are well known. There is enough stuff that does not work on Win7, Winfile just for example and i have run into other bits and pieces but to be fair, I have yet to find a normal API that does not work in the same way as XP and Win2000 did.
The one that surprised me in the latest round of cuts was the large number of ADVAPI calls dealing with security descriptors, no warnings like the one above just missing in the library for Windows 7. Also many applications that were written using the standard registry calls from Microsoft's examples failed under Vista, we saw enough posts about that here. If you decide you want to support an as of yet unwritten version of Windows you're just going to end up with a klunky ugly program that only does part of what it should and in no way can compare head to head against professionally written software. This was the main reasoning behind my header project supporting the undocumented ordinal calls, some of the functions exported as ordinals as far back as Win95 were "added" as named APIs after the settlement and finally documented, a good example are the DPA group of functions. Another ongoing part of the header project specifically deals with deprecated functions and will warn you if you attempt to use a core function that is not available to your targeted OS version.
My philosophy is that if it works up to the latest version of Windows and is later deprecated then I will rewrite it, after all I do not support Win9x and so it is not a good assumption to think that I will automatically support Windows 11.
Edgar