#DEFINE PROCESS_TERMINATE (0x0001) #DEFINE PROCESS_CREATE_THREAD (0x0002) #DEFINE PROCESS_VM_OPERATION (0x0008) #DEFINE PROCESS_VM_READ (0x0010) #DEFINE PROCESS_VM_WRITE (0x0020) #DEFINE PROCESS_DUP_HANDLE (0x0040) #DEFINE PROCESS_CREATE_PROCESS (0x0080) #DEFINE PROCESS_SET_QUOTA (0x0100) #DEFINE PROCESS_SET_INFORMATION (0x0200) #DEFINE PROCESS_QUERY_INFORMATION (0x0400) #DEFINE PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \0xFFF) #DEFINE LOC_STRLEN 300 LOCAL nGot && Number of processes returned LOCAL cProcesses && Array of DWORDS LOCAL hModule && DWORD module handle LOCAL cBuff && Maybe not needed LOCAL nPtr && Pointer used for converting DWORDS to integers LOCAL nNumOfProcesses && LOCAL nInc LOCAL nSizeOfFilename LOCAL nBoolval LOCAL lRetVal LOCAL cName LOCAL nHandleFlag LOCAL nSizeOfArray && One DWORD, four bytes lRetVal = .F. nBoolval = 0 nInc = 0 nBytesReturned = 0 nSizeOfArray = 4 hModule = CHR(0)+CHR(0)+CHR(0)+CHR(0) cName = REPLICATE(CHR(0),40) nHandleFlag = 0 hProcess = 0 nGot = 0 cProcesses = CHR(200)+CHR(0)+CHR(0)+CHR(0)+REPLICATE(CHR(0),196) nPtr = 1 DECLARE INTEGER EnumProcesses IN PSAPI STRING @cProcesses, INTEGER, INTEGER @nGot DECLARE INTEGER OpenProcess IN WIN32API INTEGER nAccess, INTEGER nHandleFlag, INTEGER hProcess DECLARE INTEGER EnumProcessModules IN PSAPI INTEGER hProcess, STRING @hModule, INTEGER nSizeOfArray, INTEGER @nBytesReturned DECLARE INTEGER GetModuleFileNameEx IN PSAPI INTEGER hProcess, INTEGER hModule, STRING @cName, INTEGER, nSize DECLARE INTEGER GetModuleBaseName IN PSAPI INTEGER hProcess, INTEGER hModule, STRING @cName, INTEGER nSize *-- EnumProcesses is passed a pointer to an array of DWORDs, i.e., four byte strings and a pointer to *-- an INTEGER that will hold the number of DWORDs filled with process ID's. It's impossible *-- to know in advance the number of processes so 24 is a guess. 24*4 = the 96 chr(0) length) nBoolval = EnumProcesses(@cProcesses,400,@nGot) *-- Dimension an array of the proper size based on the processes returned value, nGot nNumOfProcesses = nGot/4 DIMENSION aProcesses[nNumOfProcesses,2] *-- Load the array with integer values derived from the DWORDs FOR nInc = 1 TO nNumOfProcesses * cBuff = substr(cProcesses,nPtr,4) aProcesses[nInc,1] = CharToBin(SUBSTR(cProcesses,nPtr,4)) nPtr = nPtr + 4 ENDFOR *-- Run through the process IDs and determine the process file name. FOR nInc = 1 TO nNumOfProcesses *-- Set/re-set the variables used for each iteration. hModuleList = REPLICATE(CHR(0), LOC_STRLEN) cName = REPLICATE(CHR(0),80) nSizeOfFilename = 0 nBoolval = 0 *-- The SystemIdleProcess has a 0 for the PID, ignore it. IF aProcesses[nInc,1] > 0 *-- OpenProcess returns a process handle for a specified process ID. hProcess = OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ,0,aProcesses[nInc,1]) *-- Non-zero return value indicates success. IF hProcess > 0 *-- EnumProcessModules takes the process handle and loads the module array (an array of DWORDs) with module handles. *-- We are only interested in the main module here so we only pass a pointer to a single four byte string. nBoolval = EnumProcessModules(hProcess,@hModuleList,LOC_STRLEN,@nBytesReturned) *-- Non-zero return value indicates success. IF nBoolval > 0 nNumOfModules = nBytesReturned/4 *-- Load the array with integer values derived from the DWORDs nPtr = 1 cName = REPLICATE(CHR(0),80) nSizeOfFilename = 0 nBoolval = 0 hModule = CharToBin(SUBSTR(hModuleList,1,4)) nSizeOfFilename = GetModuleFileNameEx(hProcess, hModule, @cName, 80) ? cName *-- Check for VFP IF nSizeOfFilename > 0 AND "VFP"$UPPER(cName) FOR nInc2 = 1 TO nNumOfModules cName = REPLICATE(CHR(0),80) nSizeOfFilename = 0 nBoolval = 0 hModule = CharToBin(SUBSTR(hModuleList,nPtr,4)) *-- Gets the filename with complete path. nSizeOfFilename = GetModuleFileNameEx(hProcess, hModule, @cName, 80) *-- Gets the filename without path. * nSizeOfFilename = GetModuleBaseName(hProcess, hModule, @cName, 80) nPtr = nPtr + 4 IF nSizeOfFilename > 0 IF nInc2 = 1 ? LEFT(cName,nSizeOfFilename) ELSE ? " " + LEFT(cName,nSizeOfFilename) ENDIF ENDIF ENDFOR ENDIF ENDIF ENDIF ENDIF ENDFOR RETURN lRetVal FUNCTION CharToBin(tcBuff) *-- This assumes passed string is four bytes or less. nReturn = IIF(LEN(tcBuff)>0,ASC(SUBSTR(tcBuff, 1,1)), 0) + ; IIF(LEN(tcBuff)>1,ASC(SUBSTR(tcBuff, 2,1)) * 256, 0) + ; IIF(LEN(tcBuff)>2,ASC(SUBSTR(tcBuff, 3,1)) * 65536, 0) + ; IIF(LEN(tcBuff)>3,ASC(SUBSTR(tcBuff, 4,1)) * 16777216, 0) RETURN (nReturn) ENDFUNC FUNCTION BinToChar(tnValue) LOCAL cBuff, byte1, byte2, byte3, byte4 cBuff = "" IF tnValue > 16777215 cBuff = CHR(255)+CHR(255)+CHR(255)+CHR(255) ELSE byte4 = INT(tnValue/(256^3)) byte3 = INT(MOD(tnValue,(256^3))/ (256^2)) byte2 = INT(MOD(MOD(tnValue,(256^3)),(256^2))/256) byte1 = INT(MOD(MOD(MOD(tnValue,(256^3)),(256^2)),256)) *-- Now stuff the a temporary string with the new value cBuff = CHR(byte1) + CHR(byte2) + CHR(byte3) + CHR(byte4) ENDIF RETURN cBuff ENDFUNC