reactos/lib/kernel32/misc
diff -u -r1.4 -r1.5
--- toolhelp.c 28 Aug 2004 22:06:02 -0000 1.4
+++ toolhelp.c 31 Oct 2004 00:04:19 -0000 1.5
@@ -1,4 +1,22 @@
-/* $Id: toolhelp.c,v 1.4 2004/08/28 22:06:02 navaraf Exp $
+/*
+ * ReactOS kernel
+ * Copyright (C) 2004 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: toolhelp.c,v 1.5 2004/10/31 00:04:19 weiden Exp $
*
* KERNEL32.DLL toolhelp functions
*
@@ -6,339 +24,1124 @@
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/misc/toolhelp.c
* PURPOSE: Toolhelp functions
- * PROGRAMMER: Robert Dickenson (robd@mok.lvcm.com)
+ * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
+ * Robert Dickenson (robd@mok.lvcm.com)
+ *
+ * NOTES: Do NOT use the heap functions in here because they
+ * adulterate the heap statistics!
+ *
* UPDATE HISTORY:
- * Created 05 January 2003
+ * 10/30/2004 Implemented some parts (w3)
+ * Inspired by the book "Windows NT Native API"
+ * Created 05 January 2003 (robd)
+ */
+
+#include <k32.h>
+
+#define NDEBUG
+#include "../include/debug.h"
+
+/* INTERNAL DEFINITIONS *******************************************************/
+
+#define CHECK_PARAM_SIZE(ptr, siz) \
+ if((ptr) == NULL || (ptr)->dwSize != (siz)) \
+ { \
+ SetLastError(ERROR_INVALID_PARAMETER); \
+ return FALSE; \
+ }
+
+/*
+ * Tests in win showed that the dwSize field can be greater than the actual size
+ * of the structure for the ansi functions. I found this out by accidently
+ * forgetting to set the dwSize field in a test application and it just didn't
+ * work in ros but in win.
*/
-#include <windows.h>
-#include <tlhelp32.h>
+#define CHECK_PARAM_SIZEA(ptr, siz) \
+ if((ptr) == NULL || (ptr)->dwSize < (siz)) \
+ { \
+ SetLastError(ERROR_INVALID_PARAMETER); \
+ return FALSE; \
+ }
+
+#define OffsetToPtr(Snapshot, Offset) \
+ ((ULONG_PTR)((Snapshot) + 1) + (ULONG_PTR)(Offset))
+
+typedef struct _TH32SNAPSHOT
+{
+ /* Heap list */
+ ULONG HeapListCount;
+ ULONG HeapListIndex;
+ ULONG_PTR HeapListOffset;
+ /* Module list */
+ ULONG ModuleListCount;
+ ULONG ModuleListIndex;
+ ULONG_PTR ModuleListOffset;
+ /* Process list */
+ ULONG ProcessListCount;
+ ULONG ProcessListIndex;
+ ULONG_PTR ProcessListOffset;
+ /* Thread list */
+ ULONG ThreadListCount;
+ ULONG ThreadListIndex;
+ ULONG_PTR ThreadListOffset;
+} TH32SNAPSHOT, *PTH32SNAPSHOT;
+
+/* INTERNAL FUNCTIONS *********************************************************/
+
+static VOID
+TH32FreeAllocatedResources(PDEBUG_BUFFER HeapDebug,
+ PDEBUG_BUFFER ModuleDebug,
+ PVOID ProcThrdInfo,
+ ULONG ProcThrdInfoSize)
+{
+ if(HeapDebug != NULL)
+ {
+ RtlDestroyQueryDebugBuffer(HeapDebug);
+ }
+ if(ModuleDebug != NULL)
+ {
+ RtlDestroyQueryDebugBuffer(ModuleDebug);
+ }
+
+ if(ProcThrdInfo != NULL)
+ {
+ NtFreeVirtualMemory(NtCurrentProcess(),
+ ProcThrdInfo,
+ &ProcThrdInfoSize,
+ MEM_RELEASE);
+ }
+}
+
+static NTSTATUS
+TH32CreateSnapshot(DWORD dwFlags,
+ DWORD th32ProcessID,
+ PDEBUG_BUFFER *HeapDebug,
+ PDEBUG_BUFFER *ModuleDebug,
+ PVOID *ProcThrdInfo,
+ ULONG *ProcThrdInfoSize)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ *HeapDebug = NULL;
+ *ModuleDebug = NULL;
+ *ProcThrdInfo = NULL;
+ *ProcThrdInfoSize = 0;
+
+ /*
+ * Allocate the debug information for a heap snapshot
+ */
+ if(dwFlags & TH32CS_SNAPHEAPLIST)
+ {
+ *HeapDebug = RtlCreateQueryDebugBuffer(0, FALSE);
+ if(*HeapDebug != NULL)
+ {
+ Status = RtlQueryProcessDebugInformation(th32ProcessID,
+ PDI_HEAPS,
+ *HeapDebug);
+ }
+ else
+ Status = STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ * Allocate the debug information for a module snapshot
+ */
+ if(dwFlags & TH32CS_SNAPMODULE &&
+ NT_SUCCESS(Status))
+ {
+ *ModuleDebug = RtlCreateQueryDebugBuffer(0, FALSE);
+ if(*ModuleDebug != NULL)
+ {
+ Status = RtlQueryProcessDebugInformation(th32ProcessID,
+ PDI_MODULES,
+ *HeapDebug);
+ }
+ else
+ Status = STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ * Allocate enough memory for the system's process list
+ */
+
+ if(dwFlags & (TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD) &&
+ NT_SUCCESS(Status))
+ {
+ for(;;)
+ {
+ (*ProcThrdInfoSize) += 0x10000;
+ Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ ProcThrdInfo,
+ 0,
+ ProcThrdInfoSize,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if(!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ Status = NtQuerySystemInformation(SystemProcessInformation,
+ *ProcThrdInfo,
+ *ProcThrdInfoSize,
+ NULL);
+ if(Status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ NtFreeVirtualMemory(NtCurrentProcess(),
+ ProcThrdInfo,
+ ProcThrdInfoSize,
+ MEM_RELEASE);
+ *ProcThrdInfo = NULL;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ /*
+ * Free resources in case of failure!
+ */
+
+ if(!NT_SUCCESS(Status))
+ {
+ TH32FreeAllocatedResources(*HeapDebug,
+ *ModuleDebug,
+ *ProcThrdInfo,
+ *ProcThrdInfoSize);
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+TH32CreateSnapshotSectionInitialize(DWORD dwFlags,
+ DWORD th32ProcessID,
+ PDEBUG_BUFFER HeapDebug,
+ PDEBUG_BUFFER ModuleDebug,
+ PVOID ProcThrdInfo,
+ HANDLE *SectionHandle)
+{
+ PSYSTEM_PROCESS_INFORMATION ProcessInfo;
+ LPHEAPLIST32 HeapListEntry;
+ LPMODULEENTRY32W ModuleListEntry;
+ LPPROCESSENTRY32W ProcessListEntry;
+ LPTHREADENTRY32 ThreadListEntry;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ LARGE_INTEGER SSize, SOffset;
+ HANDLE hSection;
+ PTH32SNAPSHOT Snapshot;
+ ULONG_PTR DataOffset;
+ ULONG ViewSize, i;
+ ULONG nProcesses = 0, nThreads = 0, nHeaps = 0, nModules = 0;
+ ULONG RequiredSnapshotSize = sizeof(TH32SNAPSHOT);
+ PHEAP_INFORMATION hi = NULL;
+ PMODULE_INFORMATION mi = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /*
+ * Determine the required size for the heap snapshot
+ */
+ if(dwFlags & TH32CS_SNAPHEAPLIST)
+ {
+ hi = (PHEAP_INFORMATION)HeapDebug->HeapInformation;
+ nHeaps = hi->HeapCount;
+ RequiredSnapshotSize += nHeaps * sizeof(HEAPLIST32);
+ }
+
+ /*
+ * Determine the required size for the module snapshot
+ */
+ if(dwFlags & TH32CS_SNAPMODULE)
+ {
+ mi = (PMODULE_INFORMATION)ModuleDebug->ModuleInformation;
+ nModules = mi->ModuleCount;
+ RequiredSnapshotSize += nModules * sizeof(MODULEENTRY32W);
+ }
+
+ /*
+ * Determine the required size for the processes and threads snapshot
+ */
+ if(dwFlags & (TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD))
+ {
+ ULONG ProcOffset = 0;
+
+ ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo;
+ do
+ {
+ ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
+ nProcesses++;
+ nThreads += ProcessInfo->NumberOfThreads;
+ ProcOffset = ProcessInfo->NextEntryOffset;
+ } while(ProcOffset != 0);
+
+ if(dwFlags & TH32CS_SNAPPROCESS)
+ {
+ RequiredSnapshotSize += nProcesses * sizeof(PROCESSENTRY32W);
+ }
+ if(dwFlags & TH32CS_SNAPTHREAD)
+ {
+ RequiredSnapshotSize += nThreads * sizeof(THREADENTRY32);
+ }
+ }
+
+ /*
+ * Create and map the section
+ */
+
+ SSize.QuadPart = RequiredSnapshotSize;
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ ((dwFlags & TH32CS_INHERIT) ? OBJ_INHERIT : 0),
+ NULL,
+ NULL);
+
+ Status = NtCreateSection(&hSection,
+ SECTION_ALL_ACCESS,
+ &ObjectAttributes,
+ &SSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL);
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ SOffset.QuadPart = 0;
+ ViewSize = 0;
+ Snapshot = NULL;
+
+ Status = NtMapViewOfSection(hSection,
+ NtCurrentProcess(),
+ (PVOID*)&Snapshot,
+ 0,
+ 0,
+ &SOffset,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READWRITE);
+ if(!NT_SUCCESS(Status))
+ {
+ NtClose(hSection);
+ return Status;
+ }
+
+ RtlZeroMemory(Snapshot, sizeof(TH32SNAPSHOT));
+ DataOffset = 0;
+
+ /*
+ * Initialize the section data and fill it with all the data we collected
+ */
+
+ /* initialize the heap list */
+ if(dwFlags & TH32CS_SNAPHEAPLIST)
+ {
+ Snapshot->HeapListCount = nHeaps;
+ Snapshot->HeapListOffset = DataOffset;
+ HeapListEntry = (LPHEAPLIST32)OffsetToPtr(Snapshot, DataOffset);
+ for(i = 0; i < nHeaps; i++)
+ {
+ HeapListEntry->dwSize = sizeof(HEAPLIST32);
+ HeapListEntry->th32ProcessID = th32ProcessID;
+ HeapListEntry->th32HeapID = 0; /* FIXME - use the base address of the heap we're iterating */
+ HeapListEntry->dwFlags = 0; /* FIXME - use the flags of the heap we're iterating */
+
+ HeapListEntry++;
+ }
+
+ DataOffset += hi->HeapCount * sizeof(HEAPLIST32);
+ }
+
+ /* initialize the module list */
+ if(dwFlags & TH32CS_SNAPMODULE)
+ {
+ Snapshot->ModuleListCount = nModules;
+ Snapshot->ModuleListOffset = DataOffset;
+ ModuleListEntry = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, DataOffset);
+ for(i = 0; i < nModules; i++)
+ {
+ ModuleListEntry->dwSize = sizeof(MODULEENTRY32W);
+ ModuleListEntry->th32ProcessID = th32ProcessID;
+ /* FIXME - fill the MODULEENTRY32W structure */
-#define CHECK_PARAM_SIZE(ptr, siz) \
- if (!ptr || ptr->dwSize != siz) { \
- SetLastError(ERROR_INVALID_PARAMETER); \
- return FALSE; \
+ ModuleListEntry++;
}
+ DataOffset += mi->ModuleCount * sizeof(MODULEENTRY32W);
+ }
+
+ /* initialize the process list */
+ if(dwFlags & TH32CS_SNAPPROCESS)
+ {
+ ULONG ProcOffset = 0;
+
+ Snapshot->ProcessListCount = nProcesses;
+ Snapshot->ProcessListOffset = DataOffset;
+ ProcessListEntry = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, DataOffset);
+ ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo;
+ do
+ {
+ ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
+
+ ProcessListEntry->dwSize = sizeof(PROCESSENTRY32W);
+ ProcessListEntry->cntUsage = 0; /* no longer used */
+ ProcessListEntry->th32ProcessID = (ULONG)ProcessInfo->UniqueProcessId;
+ ProcessListEntry->th32DefaultHeapID = 0; /* no longer used */
+ ProcessListEntry->th32ModuleID = 0; /* no longer used */
+ ProcessListEntry->cntThreads = ProcessInfo->NumberOfThreads;
+ ProcessListEntry->th32ParentProcessID = (ULONG)ProcessInfo->InheritedFromUniqueProcessId;
+ ProcessListEntry->pcPriClassBase = ProcessInfo->BasePriority;
+ ProcessListEntry->dwFlags = 0; /* no longer used */
+ if(ProcessInfo->ImageName.Buffer != NULL)
+ {
+ DbgPrint("proc: %ws\n", ProcessInfo->ImageName.Buffer);
+ lstrcpynW(ProcessListEntry->szExeFile,
+ ProcessInfo->ImageName.Buffer,
+ min(ProcessInfo->ImageName.Length, sizeof(ProcessListEntry->szExeFile) / sizeof(ProcessListEntry->szExeFile[0])));
+ }
+ else
+ {
+ lstrcpyW(ProcessListEntry->szExeFile, L"[System Process]");
+ }
+
+ ProcessListEntry++;
+
+ ProcOffset = ProcessInfo->NextEntryOffset;
+ } while(ProcOffset != 0);
+
+ DataOffset += nProcesses * sizeof(PROCESSENTRY32W);
+ }
+
+ /* initialize the thread list */
+ if(dwFlags & TH32CS_SNAPTHREAD)
+ {
+ ULONG ProcOffset = 0;
+
+ Snapshot->ThreadListCount = nThreads;
+ Snapshot->ThreadListOffset = DataOffset;
+ ThreadListEntry = (LPTHREADENTRY32)OffsetToPtr(Snapshot, DataOffset);
+ ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo;
+ do
+ {
+ PSYSTEM_THREAD_INFORMATION ThreadInfo;
+ ULONG n;
+
+ ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
+ ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
+
+ for(n = 0; n < ProcessInfo->NumberOfThreads; n++)
+ {
+ ThreadListEntry->dwSize = sizeof(THREADENTRY32);
+ ThreadListEntry->cntUsage = 0; /* no longer used */
+ ThreadListEntry->th32ThreadID = (ULONG)ThreadInfo->ClientId.UniqueThread;
+ ThreadListEntry->th32OwnerProcessID = (ULONG)ThreadInfo->ClientId.UniqueProcess;
+ ThreadListEntry->tpBasePri = ThreadInfo->BasePriority;
+ ThreadListEntry->tpDeltaPri = 0; /* no longer used */
+ ThreadListEntry->dwFlags = 0; /* no longer used */
+
+ ThreadInfo++;
+ ThreadListEntry++;
+ }
+
+ ProcOffset = ProcessInfo->NextEntryOffset;
+ } while(ProcOffset != 0);
+ }
+
+ /*
+ * We're done, unmap the view and return the section handle
+ */
+
+ Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
+
+ if(NT_SUCCESS(Status))
+ {
+ *SectionHandle = hSection;
+ }
+ else
+ {
+ NtClose(hSection);
+ }
+
+ return Status;
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @unimplemented
*/
-BOOL WINAPI
+BOOL
+STDCALL
Heap32First(LPHEAPENTRY32 lphe, DWORD th32ProcessID, DWORD th32HeapID)
{
- CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32));
+ CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32));
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ SetLastError(ERROR_NO_MORE_FILES);
+ return FALSE;
}
/*
* @unimplemented
*/
-BOOL WINAPI
+BOOL
+STDCALL
Heap32Next(LPHEAPENTRY32 lphe)
{
-/*
-typedef struct tagHEAPENTRY32 {
- DWORD dwSize;
- HANDLE hHandle;
- DWORD dwAddress;
- DWORD dwBlockSize;
- DWORD dwFlags;
- DWORD dwLockCount;
- DWORD dwResvd;
- DWORD th32ProcessID;
- DWORD th32HeapID;
-} HEAPENTRY32,*PHEAPENTRY32,*LPHEAPENTRY32;
- */
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ CHECK_PARAM_SIZE(lphe, sizeof(HEAPENTRY32));
+
+ SetLastError(ERROR_NO_MORE_FILES);
+ return FALSE;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL WINAPI
+BOOL
+STDCALL
Heap32ListFirst(HANDLE hSnapshot, LPHEAPLIST32 lphl)
{
- CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));
+ PTH32SNAPSHOT Snapshot;
+ LARGE_INTEGER SOffset;
+ ULONG ViewSize;
+ NTSTATUS Status;
+
+ CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));
+
+ SOffset.QuadPart = 0;
+ ViewSize = 0;
+ Snapshot = NULL;
+
+ Status = NtMapViewOfSection(hSnapshot,
+ NtCurrentProcess(),
+ (PVOID*)&Snapshot,
+ 0,
+ 0,
+ &SOffset,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READWRITE);
+ if(NT_SUCCESS(Status))
+ {
+ BOOL Ret;
+
+ if(Snapshot->ModuleListCount > 0)
+ {
+ LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset);
+ Snapshot->HeapListIndex = 1;
+ RtlCopyMemory(lphl, &Entries[0], sizeof(HEAPLIST32));
+ Ret = TRUE;
+ }
+ else
+ {
+ SetLastError(ERROR_NO_MORE_FILES);
+ Ret = FALSE;
+ }
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
+ return Ret;
+ }
+
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL WINAPI
-Heap32ListNext(HANDLE hSnapshot, LPHEAPLIST32 lph1)
+BOOL
+STDCALL
+Heap32ListNext(HANDLE hSnapshot, LPHEAPLIST32 lphl)
{
-/*
-typedef struct tagHEAPLIST32 {
- DWORD dwSize;
- DWORD th32ProcessID;
- DWORD th32HeapID;
- DWORD dwFlags;
-} HEAPLIST32,*PHEAPLIST32,*LPHEAPLIST32;
- */
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ PTH32SNAPSHOT Snapshot;
+ LARGE_INTEGER SOffset;
+ ULONG ViewSize;
+ NTSTATUS Status;
+
+ CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));
+
+ SOffset.QuadPart = 0;
+ ViewSize = 0;
+ Snapshot = NULL;
+
+ Status = NtMapViewOfSection(hSnapshot,
+ NtCurrentProcess(),
+ (PVOID*)&Snapshot,
+ 0,
+ 0,
+ &SOffset,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READWRITE);
+ if(NT_SUCCESS(Status))
+ {
+ BOOL Ret;
+
+ if(Snapshot->HeapListCount > 0 &&
+ Snapshot->HeapListIndex < Snapshot->HeapListCount)
+ {
+ LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset);
+ RtlCopyMemory(lphl, &Entries[Snapshot->HeapListIndex++], sizeof(HEAPLIST32));
+ Ret = TRUE;
+ }
+ else
+ {
+ SetLastError(ERROR_NO_MORE_FILES);
+ Ret = FALSE;
+ }
+
+ NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
+ return Ret;
+ }
+
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL WINAPI
+BOOL
+STDCALL
Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
{
- CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32));
+ MODULEENTRY32W me;
+ BOOL Ret;
+
+ CHECK_PARAM_SIZEA(lpme, sizeof(MODULEENTRY32));
+
+ me.dwSize = sizeof(MODULEENTRY32W);
+
+ Ret = Module32FirstW(hSnapshot, &me);
+ if(Ret)
+ {
+ lpme->th32ModuleID = me.th32ModuleID;
+ lpme->th32ProcessID = me.th32ProcessID;
+ lpme->GlblcntUsage = me.GlblcntUsage;
+ lpme->ProccntUsage = me.ProccntUsage;
+ lpme->modBaseAddr = me.modBaseAddr;
+ lpme->modBaseSize = me.modBaseSize;
+ lpme->hModule = me.hModule;
+
+ WideCharToMultiByte(CP_ACP, 0, me.szModule, -1, lpme->szModule, sizeof(lpme->szModule), 0, 0);
+ WideCharToMultiByte(CP_ACP, 0, me.szExePath, -1, lpme->szExePath, sizeof(lpme->szExePath), 0, 0);
+ }
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ return Ret;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL WINAPI
+BOOL
+STDCALL
Module32FirstW(HANDLE hSnapshot, LPMODULEENTRY32W lpme)
{
- CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32W));
+ PTH32SNAPSHOT Snapshot;
+ LARGE_INTEGER SOffset;
+ ULONG ViewSize;
+ NTSTATUS Status;
+
+ CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32W));
+
+ SOffset.QuadPart = 0;
+ ViewSize = 0;
+ Snapshot = NULL;
+
+ Status = NtMapViewOfSection(hSnapshot,
+ NtCurrentProcess(),
+ (PVOID*)&Snapshot,
+ 0,
+ 0,
+ &SOffset,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READWRITE);
+ if(NT_SUCCESS(Status))
+ {
+ BOOL Ret;
+
+ if(Snapshot->ModuleListCount > 0)
+ {
+ LPMODULEENTRY32W Entries = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, Snapshot->ModuleListOffset);
+ Snapshot->ModuleListIndex = 1;
+ RtlCopyMemory(lpme, &Entries[0], sizeof(MODULEENTRY32W));
+ Ret = TRUE;
+ }
+ else
+ {
+ SetLastError(ERROR_NO_MORE_FILES);
+ Ret = FALSE;
+ }
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
+ return Ret;
+ }
+
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL WINAPI
+BOOL
+STDCALL
Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme)
{
-/*
-typedef struct tagMODULEENTRY32 {
- DWORD dwSize;
- DWORD th32ModuleID;
- DWORD th32ProcessID;
- DWORD GlblcntUsage;
- DWORD ProccntUsage;
- BYTE *modBaseAddr;
- DWORD modBaseSize;
- HMODULE hModule;
- char szModule[MAX_MODULE_NAME32 + 1];
- char szExePath[MAX_PATH];
-} MODULEENTRY32,*PMODULEENTRY32,*LPMODULEENTRY32;
- */
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ MODULEENTRY32W me;
+ BOOL Ret;
+
+ CHECK_PARAM_SIZEA(lpme, sizeof(MODULEENTRY32));
+
+ me.dwSize = sizeof(MODULEENTRY32W);
+
+ Ret = Module32NextW(hSnapshot, &me);
+ if(Ret)
+ {
+ lpme->th32ModuleID = me.th32ModuleID;
+ lpme->th32ProcessID = me.th32ProcessID;
+ lpme->GlblcntUsage = me.GlblcntUsage;
+ lpme->ProccntUsage = me.ProccntUsage;
+ lpme->modBaseAddr = me.modBaseAddr;
+ lpme->modBaseSize = me.modBaseSize;
+ lpme->hModule = me.hModule;
+
+ WideCharToMultiByte(CP_ACP, 0, me.szModule, -1, lpme->szModule, sizeof(lpme->szModule), 0, 0);
+ WideCharToMultiByte(CP_ACP, 0, me.szExePath, -1, lpme->szExePath, sizeof(lpme->szExePath), 0, 0);
+ }
+
+ return Ret;
}
-BOOL WINAPI
+
+BOOL
+STDCALL
Module32NextW(HANDLE hSnapshot, LPMODULEENTRY32W lpme)
{
-/*
-typedef struct tagMODULEENTRY32W {
- DWORD dwSize;
- DWORD th32ModuleID;
- DWORD th32ProcessID;
- DWORD GlblcntUsage;
- DWORD ProccntUsage;
- BYTE *modBaseAddr;
- DWORD modBaseSize;
- HMODULE hModule;
- WCHAR szModule[MAX_MODULE_NAME32 + 1];
- WCHAR szExePath[MAX_PATH];
-} MODULEENTRY32W,*PMODULEENTRY32W,*LPMODULEENTRY32W;
+ PTH32SNAPSHOT Snapshot;
+ LARGE_INTEGER SOffset;
+ ULONG ViewSize;
+ NTSTATUS Status;
+
+ CHECK_PARAM_SIZE(lpme, sizeof(MODULEENTRY32W));
+
+ SOffset.QuadPart = 0;
+ ViewSize = 0;
+ Snapshot = NULL;
+
+ Status = NtMapViewOfSection(hSnapshot,
+ NtCurrentProcess(),
+ (PVOID*)&Snapshot,
+ 0,
+ 0,
+ &SOffset,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READWRITE);
+ if(NT_SUCCESS(Status))
+ {
+ BOOL Ret;
+
+ if(Snapshot->ModuleListCount > 0 &&
+ Snapshot->ModuleListIndex < Snapshot->ModuleListCount)
+ {
+ LPMODULEENTRY32W Entries = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, Snapshot->ModuleListOffset);
+ RtlCopyMemory(lpme, &Entries[Snapshot->ProcessListIndex++], sizeof(MODULEENTRY32W));
+ Ret = TRUE;
+ }
+ else
+ {
+ SetLastError(ERROR_NO_MORE_FILES);
+ Ret = FALSE;
+ }
- */
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
+ return Ret;
+ }
+
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL STDCALL
+BOOL
+STDCALL
Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
{
- CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32));
+ PROCESSENTRY32W pe;
+ BOOL Ret;
+
+ CHECK_PARAM_SIZEA(lppe, sizeof(PROCESSENTRY32));
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ pe.dwSize = sizeof(PROCESSENTRY32W);
+
+ Ret = Process32FirstW(hSnapshot, &pe);
+ if(Ret)
+ {
+ lppe->cntUsage = pe.cntUsage;
+ lppe->th32ProcessID = pe.th32ProcessID;
+ lppe->th32DefaultHeapID = pe.th32DefaultHeapID;
+ lppe->th32ModuleID = pe.th32ModuleID;
+ lppe->cntThreads = pe.cntThreads;
+ lppe->th32ParentProcessID = pe.th32ParentProcessID;
+ lppe->pcPriClassBase = pe.pcPriClassBase;
+ lppe->dwFlags = pe.dwFlags;
+
+ WideCharToMultiByte(CP_ACP, 0, pe.szExeFile, -1, lppe->szExeFile, sizeof(lppe->szExeFile), 0, 0);
+ }
+
+ return Ret;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL STDCALL
-Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
+BOOL
+STDCALL
+Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
{
-/*
-typedef struct tagPROCESSENTRY32 {
- DWORD dwSize;
- DWORD cntUsage;
- DWORD th32ProcessID;
- DWORD th32DefaultHeapID;
- DWORD th32ModuleID;
- DWORD cntThreads;
- DWORD th32ParentProcessID;
- LONG pcPriClassBase;
- DWORD dwFlags;
- CHAR szExeFile[MAX_PATH];
-} PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32;
- */
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
+ PTH32SNAPSHOT Snapshot;
+ LARGE_INTEGER SOffset;
+ ULONG ViewSize;
+ NTSTATUS Status;
+
+ CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32W));
+
+ SOffset.QuadPart = 0;
+ ViewSize = 0;
+ Snapshot = NULL;
+
+ Status = NtMapViewOfSection(hSnapshot,
+ NtCurrentProcess(),
+ (PVOID*)&Snapshot,
+ 0,
+ 0,
+ &SOffset,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READWRITE);
+ if(NT_SUCCESS(Status))
+ {
+ BOOL Ret;
+
+ if(Snapshot->ProcessListCount > 0)
+ {
+ LPPROCESSENTRY32W Entries = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, Snapshot->ProcessListOffset);
+
+ Snapshot->ProcessListIndex = 1;
+ RtlCopyMemory(lppe, &Entries[0], sizeof(PROCESSENTRY32W));
+ Ret = TRUE;
+ }
+ else
+ {
+
+ SetLastError(ERROR_NO_MORE_FILES);
+ Ret = FALSE;
+ }
+
+ NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
+ return Ret;
+ }
+
+ SetLastErrorByStatus(Status);
+ return FALSE;
}
/*
- * @unimplemented
+ * @implemented
*/
-BOOL STDCALL
-Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
+BOOL
+STDCALL
+Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
[truncated at 1000 lines; 369 more skipped]