*!* Source: www.news2news.com/vfp *!* http://www.news2news.com/vfp/?example=176&function=270 DO DECL *| typedef struct _PROCESS_HEAP_ENTRY { *| PVOID lpData; 1:4 *| DWORD cbData; 5:4 *| BYTE cbOverhead; 9:1 *| BYTE iRegionIndex; 10:1 *| WORD wFlags; 11:2 *| union { *| struct { *| HANDLE hMem; 13:4 *| DWORD dwReserved[ 3 ]; 17:4 *| } Block; *| struct { *| DWORD dwCommittedSize; 13:4 *| DWORD dwUnCommittedSize; 17:4 *| LPVOID lpFirstBlock; 21:4 *| LPVOID lpLastBlock; 25:4 *| } Region; *| }; total: 28 bytes *| } PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY #DEFINE STRU_LENGTH 28 *| Flags -- properties of the heap element #DEFINE PROCESS_HEAP_REGION 1 #DEFINE PROCESS_HEAP_UNCOMMITTED_RANGE 2 #DEFINE PROCESS_HEAP_ENTRY_BUSY 4 #DEFINE PROCESS_HEAP_ENTRY_MOVEABLE 16 #DEFINE PROCESS_HEAP_ENTRY_DDESHARE 32 LOCAL ii, lnHeapCount, lcBuffer, hHeap, lcHeapEntry, lnResult,; lpData, cbData, cbOverhead, lnRegIndex, lnFlags,; lnSzCmt, lnSzUncmt, lnFBlock, lnLBlock lnHeapCount = 256 lcBuffer = REPLI (CHR(0), lnHeapCount*4) lnHeapCount = GetProcessHeaps (lnHeapCount, @lcBuffer) * resulting cursor CREATE CURSOR csResult (heapno N(5), heapptr N(12), dataptr N(12),; datasize N(12), oversize N(4), regindex N(4), flags N(12),; szcomm N(12), szuncomm N(12), fblock N(12), lblock N(12)) FOR ii = 1 TO lnHeapCount hHeap = buf2dword(SUBSTR (lcBuffer, (ii-1)*4+1, 4)) * The HeapLock function is primarily useful for preventing * the allocation and release of heap memory by other threads * while the calling thread uses the HeapWalk function. IF HeapLock (hHeap) = 0 ? "Failure to lock handle:", hHeap LOOP ENDIF * stuff the buffer with zeroes lcHeapEntry = REPLI (CHR(0), STRU_LENGTH) DO WHILE HeapWalk(hHeap, @lcHeapEntry) <> 0 lpData = buf2dword (SUBSTR(lcHeapEntry, 1,4)) cbData = buf2dword (SUBSTR(lcHeapEntry, 5,4)) cbOverhead = ASC(SUBSTR(lcHeapEntry, 9,1)) lnRegIndex = ASC(SUBSTR(lcHeapEntry, 10,1)) lnFlags = buf2word (SUBSTR(lcHeapEntry, 11,2)) IF lnFlags = PROCESS_HEAP_REGION lnSzCmt = buf2dword (SUBSTR(lcHeapEntry, 13,4)) lnSzUncmt = buf2dword (SUBSTR(lcHeapEntry, 17,4)) lnFBlock = buf2dword (SUBSTR(lcHeapEntry, 21,4)) lnLBlock = buf2dword (SUBSTR(lcHeapEntry, 25,4)) ELSE STORE 0 TO lnSzCmt, lnSzUncmt, lnFBlock, lnLBlock ENDIF INSERT INTO csResult VALUES (ii, hHeap, lpData, cbData, cbOverhead,; lnRegIndex, lnFlags, lnSzCmt, lnSzUncmt, lnFBlock, lnLBlock) ENDDO * Each call to HeapLock must be matched by * a corresponding call to the HeapUnlock function = HeapUnlock (hHeap) ENDFOR *!* Leo Kool: create a summary SELECT heapno, heapptr, COUNT(heapptr) AS BLOCKS, ; SUM(IIF(flags=0,1,0)) AS f0blcks, ; SUM(IIF(flags=0,datasize,0)) AS f0szd, ; SUM(IIF(flags=0,oversize,0)) AS f0szoh, ; SUM(IIF(flags=1,1,0)) AS f1blcks, ; SUM(IIF(flags=1,datasize,0)) AS f1szd, ; SUM(IIF(flags=1,oversize,0)) AS f1szoh, ; SUM(IIF(flags=2,1,0)) AS f2blcks, ; SUM(IIF(flags=2,datasize,0)) AS f2szd, ; SUM(IIF(flags=2,oversize,0)) AS f2szoh, ; SUM(IIF(flags=4,1,0)) AS f4blcks, ; SUM(IIF(flags=4,datasize,0)) AS f4szd, ; SUM(IIF(flags=4,oversize,0)) AS f4szoh, ; regindex, MAX(szcomm) AS szcomm, MAX(szuncomm) AS szuncomm, ; MAX(szcomm + szuncomm) AS sztotal, MAX(fblock) AS fblock, MAX(lblock) AS lblock ; FROM csResult GROUP BY heapno, regindex INTO CURSOR csSummary FUNCTION buf2dword (lcBuffer) RETURN ASC(SUBSTR(lcBuffer, 1,1)) + ; ASC(SUBSTR(lcBuffer, 2,1)) * 256 +; ASC(SUBSTR(lcBuffer, 3,1)) * 65536 +; ASC(SUBSTR(lcBuffer, 4,1)) * 16777216 FUNCTION buf2word (lcBuffer) RETURN ASC(SUBSTR(lcBuffer, 1,1)) + ASC(SUBSTR(lcBuffer, 2,1)) * 256 PROCEDURE DECL DECLARE INTEGER GetProcessHeaps IN kernel32 INTEGER NumberOfHeaps, STRING @ProcessHeaps DECLARE INTEGER HeapWalk IN kernel32 INTEGER hHeap, STRING @lpEntry DECLARE INTEGER HeapLock IN kernel32 INTEGER hHeap DECLARE INTEGER HeapUnlock IN kernel32 INTEGER hHeap