janitory work Modified: trunk/reactos/lib/psapi/makefile Deleted: trunk/reactos/lib/psapi/misc/ Added: trunk/reactos/lib/psapi/psapi.c Deleted: trunk/reactos/lib/psapi/win32.c _____
Modified: trunk/reactos/lib/psapi/makefile --- trunk/reactos/lib/psapi/makefile 2005-01-15 16:35:30 UTC (rev 13059) +++ trunk/reactos/lib/psapi/makefile 2005-01-15 16:42:28 UTC (rev 13060) @@ -19,7 +19,7 @@
TARGET_PCH = precomp.h
-TARGET_OBJECTS = misc/dllmain.o malloc.o win32.o +TARGET_OBJECTS = malloc.o psapi.o DEP_OBJECTS = $(TARGET_OBJECTS)
_____
Copied: trunk/reactos/lib/psapi/psapi.c (from rev 13059, trunk/reactos/lib/psapi/win32.c) --- trunk/reactos/lib/psapi/win32.c 2005-01-15 16:35:30 UTC (rev 13059) +++ trunk/reactos/lib/psapi/psapi.c 2005-01-15 16:42:28 UTC (rev 13060) @@ -0,0 +1,1411 @@
+/* $Id$ + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * LICENSE: See LGPL.txt in the top level directory + * PROJECT: ReactOS system libraries + * FILE: reactos/lib/psapi/misc/win32.c + * PURPOSE: Win32 interfaces for PSAPI + * PROGRAMMER: KJK::Hyperion noog@libero.it + * Thomas Weidenmueller w3seek@reactos.com + * UPDATE HISTORY: + * 10/06/2002: Created + */ + +#include "precomp.h" + +#define NDEBUG +#include <debug.h> + +BOOLEAN +WINAPI +DllMain(HINSTANCE hDllHandle, + DWORD nReason, + LPVOID Reserved) +{ + switch(nReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hDllHandle); + break; + } + + return TRUE; +} + +/* INTERNAL *******************************************************************/ + +typedef struct _ENUM_DEVICE_DRIVERS_CONTEXT +{ + LPVOID *lpImageBase; + DWORD nCount; +} ENUM_DEVICE_DRIVERS_CONTEXT, *PENUM_DEVICE_DRIVERS_CONTEXT; + +NTSTATUS STDCALL +EnumDeviceDriversCallback(IN PSYSTEM_MODULE_INFORMATION_ENTRY CurrentModule, + IN OUT PVOID CallbackContext) +{ + PENUM_DEVICE_DRIVERS_CONTEXT Context = (PENUM_DEVICE_DRIVERS_CONTEXT)CallbackContext; + + /* no more buffer space */ + if(Context->nCount == 0) + { + return STATUS_INFO_LENGTH_MISMATCH; + } + + /* return current module */ + *Context->lpImageBase = CurrentModule->Base; + + /* go to next array slot */ + Context->lpImageBase++; + Context->nCount--; + + return STATUS_SUCCESS; +} + + +typedef struct _ENUM_PROCESSES_CONTEXT +{ + DWORD *lpidProcess; + DWORD nCount; +} ENUM_PROCESSES_CONTEXT, *PENUM_PROCESSES_CONTEXT; + +NTSTATUS STDCALL +EnumProcessesCallback(IN PSYSTEM_PROCESSES CurrentProcess, + IN OUT PVOID CallbackContext) +{ + PENUM_PROCESSES_CONTEXT Context = (PENUM_PROCESSES_CONTEXT)CallbackContext; + + /* no more buffer space */ + if(Context->nCount == 0) + { + return STATUS_INFO_LENGTH_MISMATCH; + } + + /* return current process */ + *Context->lpidProcess = CurrentProcess->ProcessId; + + /* go to next array slot */ + Context->lpidProcess++; + Context->nCount--; + + return STATUS_SUCCESS; +} + + +typedef struct _ENUM_PROCESS_MODULES_CONTEXT +{ + HMODULE *lphModule; + DWORD nCount; +} ENUM_PROCESS_MODULES_CONTEXT, *PENUM_PROCESS_MODULES_CONTEXT; + +NTSTATUS STDCALL +EnumProcessModulesCallback(IN HANDLE ProcessHandle, + IN PLDR_MODULE CurrentModule, + IN OUT PVOID CallbackContext) +{ + PENUM_PROCESS_MODULES_CONTEXT Context = (PENUM_PROCESS_MODULES_CONTEXT)CallbackContext; + + /* no more buffer space */ + if(Context->nCount == 0) + { + return STATUS_INFO_LENGTH_MISMATCH; + } + + /* return current process */ + *Context->lphModule = CurrentModule->BaseAddress; + + /* go to next array slot */ + Context->lphModule++; + Context->nCount--; + + return STATUS_SUCCESS; +} + + +typedef struct _GET_DEVICE_DRIVER_NAME_CONTEXT +{ + LPVOID ImageBase; + struct + { + ULONG bFullName : sizeof(ULONG) * 8 / 2; + ULONG bUnicode : sizeof(ULONG) * 8 / 2; + }; + DWORD nSize; + union + { + LPVOID lpName; + LPSTR lpAnsiName; + LPWSTR lpUnicodeName; + }; +} GET_DEVICE_DRIVER_NAME_CONTEXT, *PGET_DEVICE_DRIVER_NAME_CONTEXT; + +NTSTATUS STDCALL +GetDeviceDriverNameCallback(IN PSYSTEM_MODULE_INFORMATION_ENTRY CurrentModule, + IN OUT PVOID CallbackContext) +{ + PGET_DEVICE_DRIVER_NAME_CONTEXT Context = (PGET_DEVICE_DRIVER_NAME_CONTEXT)CallbackContext; + + /* module found */ + if(Context->ImageBase == CurrentModule->Base) + { + PCHAR pcModuleName; + ULONG l; + + /* get the full name or just the filename part */ + if(Context->bFullName) + pcModuleName = &CurrentModule->ImageName[0]; + else + pcModuleName = &CurrentModule->ImageName[CurrentModule->PathLength]; + + /* get the length of the name */ + l = strlen(pcModuleName); + + if(Context->nSize <= l) + { + /* use the user buffer's length */ + l = Context->nSize; + } + else + { + /* enough space for the null terminator */ + Context->nSize = ++l; + } + + /* copy the string */ + if(Context->bUnicode) + { + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + + UnicodeString.Length = 0; + UnicodeString.MaximumLength = l * sizeof(WCHAR); + UnicodeString.Buffer = Context->lpUnicodeName; + + RtlInitAnsiString(&AnsiString, pcModuleName); + /* driver names should always be in language-neutral ASCII, so we don't + bother calling AreFileApisANSI() */ + RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); + } + else + { + memcpy(Context->lpAnsiName, pcModuleName, l); + } + + /* terminate the enumeration */ + return STATUS_NO_MORE_FILES; + } + else + { + /* continue searching */ + return STATUS_SUCCESS; + } +} + + +static DWORD +InternalGetDeviceDriverName(BOOLEAN bUnicode, + BOOLEAN bFullName, + LPVOID ImageBase, + LPVOID lpName, + DWORD nSize) +{ + GET_DEVICE_DRIVER_NAME_CONTEXT Context; + NTSTATUS Status; + + if(lpName == NULL || nSize == 0) + { + return 0; + } + + if(ImageBase == NULL) + { + SetLastError(ERROR_INVALID_HANDLE); + return 0; + } + + Context.ImageBase = ImageBase; + Context.bFullName = bFullName; + Context.bUnicode = bUnicode; + Context.nSize = nSize; + Context.lpName = lpName; + + /* start the enumeration */ + Status = PsaEnumerateSystemModules(GetDeviceDriverNameCallback, &Context); + + if(Status == STATUS_NO_MORE_FILES) + { + /* module was found, return string size */ + return Context.nSize; + } + else if(NT_SUCCESS(Status)) + { + /* module was not found */ + SetLastError(ERROR_INVALID_HANDLE); + } + else + { + /* an error occurred */ + SetLastErrorByStatus(Status); + } + return 0; +} + + +static DWORD +InternalGetMappedFileName(BOOLEAN bUnicode, + HANDLE hProcess, + LPVOID lpv, + LPVOID lpName, + DWORD nSize) +{ + PMEMORY_SECTION_NAME pmsnName; + ULONG nBufSize; + NTSTATUS Status; + + if(nSize == 0 || lpName == NULL) + { + return 0; + } + + if(nSize > (0xFFFF / sizeof(WCHAR))) + { + /* if the user buffer contains more characters than would fit in an + UNICODE_STRING, limit the buffer size. RATIONALE: we don't limit buffer + size elsewhere because here superfluous buffer size will mean a larger + temporary buffer */ + nBufSize = 0xFFFF / sizeof(WCHAR); + } + else + { + nBufSize = nSize * sizeof(WCHAR); + } + + /* allocate the memory */ + pmsnName = PsaiMalloc(nBufSize + offsetof(MEMORY_SECTION_NAME, NameBuffer)); + + if(pmsnName == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + + /* initialize the destination buffer */ + pmsnName->SectionFileName.Length = 0; + pmsnName->SectionFileName.Length = nBufSize; + +#if 0 + __try + { +#endif + /* query the name */ + Status = NtQueryVirtualMemory(hProcess, + lpv, + MemorySectionName, + pmsnName, + nBufSize, + NULL); + if(!NT_SUCCESS(Status)) + { + PsaiFree(pmsnName); + SetLastErrorByStatus(Status); + return 0; + } + + if(bUnicode) + { + /* destination is an Unicode string: direct copy */ + memcpy((LPWSTR)lpName, pmsnName->NameBuffer, pmsnName->SectionFileName.Length); + + PsaiFree(pmsnName); + + if(pmsnName->SectionFileName.Length < nSize) + { + /* null-terminate the string */ + ((LPWSTR)lpName)[pmsnName->SectionFileName.Length] = 0; + return pmsnName->SectionFileName.Length + 1; + } + + return pmsnName->SectionFileName.Length; + } + else + { + ANSI_STRING AnsiString; + + AnsiString.Length = 0; + AnsiString.MaximumLength = nSize; + AnsiString.Buffer = (LPSTR)lpName; + + if(AreFileApisANSI()) + RtlUnicodeStringToAnsiString(&AnsiString, &pmsnName->SectionFileName, FALSE); + else + RtlUnicodeStringToOemString(&AnsiString, &pmsnName->SectionFileName, FALSE); + + PsaiFree(pmsnName); + + if(AnsiString.Length < nSize) + { + /* null-terminate the string */ + ((LPSTR)lpName)[AnsiString.Length] = 0; + return AnsiString.Length + 1; + } + + return AnsiString.Length; + } + +#if 0 + } + __finally + { + PsaiFree(pmsnName); + } +#endif +} + + +typedef struct _GET_MODULE_INFORMATION_FLAGS +{ + ULONG bWantName : sizeof(ULONG) * 8 / 4; + ULONG bUnicode : sizeof(ULONG) * 8 / 4; + ULONG bFullName : sizeof(ULONG) * 8 / 4; +} GET_MODULE_INFORMATION_FLAGS, *PGET_MODULE_INFORMATION_FLAGS; + +typedef struct _GET_MODULE_INFORMATION_CONTEXT +{ + HMODULE hModule; + GET_MODULE_INFORMATION_FLAGS Flags; + DWORD nBufSize; + union + { + LPWSTR lpUnicodeName; + LPSTR lpAnsiName; + LPMODULEINFO lpmodinfo; + LPVOID lpBuffer; + }; +} GET_MODULE_INFORMATION_CONTEXT, *PGET_MODULE_INFORMATION_CONTEXT; + +NTSTATUS STDCALL +GetModuleInformationCallback(IN HANDLE ProcessHandle, + IN PLDR_MODULE CurrentModule, + IN OUT PVOID CallbackContext) +{ + PGET_MODULE_INFORMATION_CONTEXT Context = (PGET_MODULE_INFORMATION_CONTEXT)CallbackContext; + + /* found the module we were looking for */ + if(CurrentModule->BaseAddress == Context->hModule) + { + /* we want the module name */ + if(Context->Flags.bWantName) + { + PUNICODE_STRING SourceString; + ULONG l; + NTSTATUS Status; + + if(Context->Flags.bFullName) + SourceString = &(CurrentModule->FullDllName); + else + SourceString = &(CurrentModule->BaseDllName); + + SourceString->Length -= SourceString->Length % sizeof(WCHAR); + + /* l is the byte size of the user buffer */ + l = Context->nBufSize * sizeof(WCHAR); + + /* if the user buffer has room for the string and a null terminator */ + if(l >= (SourceString->Length + sizeof(WCHAR))) + { + /* limit the buffer size */ + l = SourceString->Length; + + /* null-terminate the string */ + if(Context->Flags.bUnicode) + Context->lpUnicodeName[l / sizeof(WCHAR)] = 0; + else + Context->lpAnsiName[l / sizeof(WCHAR)] = 0; + } + + if(Context->Flags.bUnicode) + { + /* Unicode: direct copy */ + /* NOTE: I've chosen not to check for ProcessHandle == NtCurrentProcess(), + this function is complicated enough as it is */ + Status = NtReadVirtualMemory(ProcessHandle, + SourceString->Buffer, + Context->lpUnicodeName, + l, + NULL); + + if(!NT_SUCCESS(Status)) + { + Context->nBufSize = 0; + return Status; + } + + Context->nBufSize = l / sizeof(WCHAR); + } + else + { + /* ANSI/OEM: convert and copy */ + LPWSTR pwcUnicodeBuf; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + + AnsiString.Length = 0; + AnsiString.MaximumLength = Context->nBufSize; + AnsiString.Buffer = Context->lpAnsiName; + + /* allocate the local buffer */ + pwcUnicodeBuf = PsaiMalloc(SourceString->Length); + +#if 0 + __try + { +#endif + if(pwcUnicodeBuf == NULL) + { + Status = STATUS_NO_MEMORY; + goto exitWithStatus; + } + + /* copy the string in the local buffer */ + Status = NtReadVirtualMemory(ProcessHandle, + SourceString->Buffer, + pwcUnicodeBuf, + l, + NULL); + + if(!NT_SUCCESS(Status)) + { + goto exitWithStatus; + } + + /* initialize Unicode string buffer */ + UnicodeString.Length = UnicodeString.MaximumLength = l; + UnicodeString.Buffer = pwcUnicodeBuf; + + /* convert and copy */ + if(AreFileApisANSI()) + RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); + else + RtlUnicodeStringToOemString(&AnsiString, &UnicodeString, FALSE); + + /* return the string size */ + Context->nBufSize = AnsiString.Length; +#if 0 + } + __finally + { + /* free the buffer */ + PsaiFree(pwcUnicodeBuf); + } +#else + Status = STATUS_NO_MORE_FILES; + +exitWithStatus: + /* free the buffer */ + PsaiFree(pwcUnicodeBuf); + return Status; +#endif + } + } + else + { + /* we want other module information */ + ULONG nSize = Context->nBufSize; + + /* base address */ + if(nSize >= sizeof(CurrentModule->BaseAddress)) + { + Context->lpmodinfo->lpBaseOfDll = CurrentModule->BaseAddress; + nSize -= sizeof(CurrentModule->BaseAddress); + } + + /* image size */ + if(nSize >= sizeof(CurrentModule->SizeOfImage)) + { + Context->lpmodinfo->SizeOfImage = CurrentModule->SizeOfImage; + nSize -= sizeof(CurrentModule->SizeOfImage); + } + + /* entry point */ + if(nSize >= sizeof(CurrentModule->EntryPoint)) + { + /* ??? FIXME? is "EntryPoint" just the offset, or the real address? */ + Context->lpmodinfo->EntryPoint = (PVOID)CurrentModule->EntryPoint; + } + + Context->nBufSize = TRUE; + } + + return STATUS_NO_MORE_FILES; + } + + return STATUS_SUCCESS; +} + + +static DWORD +InternalGetModuleInformation(HANDLE hProcess, + HMODULE hModule, + GET_MODULE_INFORMATION_FLAGS Flags, + LPVOID lpBuffer, + DWORD nBufSize) +{ + GET_MODULE_INFORMATION_CONTEXT Context; + NTSTATUS Status; + + Context.hModule = hModule; + Context.Flags = Flags; + Context.nBufSize = nBufSize; + Context.lpBuffer = lpBuffer; + + Status = PsaEnumerateProcessModules(hProcess, GetModuleInformationCallback, &Context); + + if(Status == STATUS_NO_MORE_FILES) + { + /* module was found, return string size */ + return Context.nBufSize; + } + else if(NT_SUCCESS(Status)) + { + /* module was not found */ + SetLastError(ERROR_INVALID_HANDLE); + } + else + { + /* an error occurred */ + SetLastErrorByStatus(Status); + } + return 0; +} + + +typedef struct _INTERNAL_ENUM_PAGE_FILES_CONTEXT +{ + PENUM_PAGE_FILE_CALLBACKA pCallbackRoutine; + LPVOID lpContext; +} INTERNAL_ENUM_PAGE_FILES_CONTEXT, *PINTERNAL_ENUM_PAGE_FILES_CONTEXT; + + +static BOOL +InternalAnsiPageFileCallback(LPVOID pContext, + PENUM_PAGE_FILE_INFORMATION pPageFileInfo, + LPCWSTR lpFilename) +{ + size_t slen; + LPSTR AnsiFileName; + PINTERNAL_ENUM_PAGE_FILES_CONTEXT Context = (PINTERNAL_ENUM_PAGE_FILES_CONTEXT)pContext; + + slen = wcslen(lpFilename); + + AnsiFileName = (LPSTR)LocalAlloc(LMEM_FIXED, (slen + 1) * sizeof(CHAR)); + if(AnsiFileName != NULL) + { + BOOL Ret; + + WideCharToMultiByte(CP_ACP, + 0, + lpFilename, + -1, /* only works if the string is NULL-terminated!!! */ + AnsiFileName, + (slen + 1) * sizeof(CHAR), + NULL, + NULL); + + Ret = Context->pCallbackRoutine(Context->lpContext, pPageFileInfo, AnsiFileName); + + LocalFree((HLOCAL)AnsiFileName); + + return Ret; + } + + return FALSE; +} + +/* PUBLIC *********************************************************************/ + +/* + * @implemented + */ +BOOL +STDCALL +EmptyWorkingSet(HANDLE hProcess) +{ + QUOTA_LIMITS QuotaLimits; + NTSTATUS Status; + + /* query the working set */ + Status = NtQueryInformationProcess(hProcess, + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QuotaLimits), + NULL); + + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + /* empty the working set */ + QuotaLimits.MinimumWorkingSetSize = -1; + QuotaLimits.MaximumWorkingSetSize = -1; + + /* set the working set */ + Status = NtSetInformationProcess(hProcess, + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QuotaLimits)); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; +} + + +/* + * @implemented + */ +BOOL +STDCALL +EnumDeviceDrivers(LPVOID *lpImageBase, + DWORD cb, + LPDWORD lpcbNeeded) +{ + ENUM_DEVICE_DRIVERS_CONTEXT Context; + NTSTATUS Status; + + if(cb == 0 || lpImageBase == NULL) + { + *lpcbNeeded = 0; + return TRUE; + } + + cb /= sizeof(PVOID); + + Context.lpImageBase = lpImageBase; + Context.nCount = cb; + + Status = PsaEnumerateSystemModules(EnumDeviceDriversCallback, &Context); + + /* return the count of bytes returned */ + *lpcbNeeded = (cb - Context.nCount) * sizeof(PVOID); + + if(!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; +} + + +/* + * @implemented + */ +BOOL +STDCALL +EnumProcesses(DWORD *lpidProcess, + DWORD cb, + LPDWORD lpcbNeeded) +{ + ENUM_PROCESSES_CONTEXT Context; + NTSTATUS Status; + + cb /= sizeof(DWORD); + + if(cb == 0 || lpidProcess == NULL) + { + *lpcbNeeded = 0; + return TRUE; + } + + Context.lpidProcess = lpidProcess; + Context.nCount = cb; + + /* enumerate the process ids */ + Status = PsaEnumerateProcesses(EnumProcessesCallback, &Context); + + *lpcbNeeded = (cb - Context.nCount) * sizeof(DWORD); + + if(!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; +} + + +/* + * @implemented + */ +BOOL +STDCALL +EnumProcessModules(HANDLE hProcess, + HMODULE *lphModule, + DWORD cb, + LPDWORD lpcbNeeded) +{ + ENUM_PROCESS_MODULES_CONTEXT Context; + NTSTATUS Status; + + cb /= sizeof(HMODULE); + + if(cb == 0 || lphModule == NULL) + { + *lpcbNeeded = 0; + return TRUE; + } + + Context.lphModule = lphModule; + Context.nCount = cb; + + /* enumerate the process modules */ + Status = PsaEnumerateProcessModules(hProcess, EnumProcessModulesCallback, &Context); + + *lpcbNeeded = (cb - Context.nCount) * sizeof(DWORD); + + if(!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetDeviceDriverBaseNameA(LPVOID ImageBase, + LPSTR lpBaseName, + DWORD nSize) +{ + return InternalGetDeviceDriverName(FALSE, FALSE, ImageBase, lpBaseName, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetDeviceDriverFileNameA(LPVOID ImageBase, + LPSTR lpFilename, + DWORD nSize) +{ + return InternalGetDeviceDriverName(FALSE, TRUE, ImageBase, lpFilename, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetDeviceDriverBaseNameW(LPVOID ImageBase, + LPWSTR lpBaseName, + DWORD nSize) +{ + return InternalGetDeviceDriverName(TRUE, FALSE, ImageBase, lpBaseName, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetDeviceDriverFileNameW(LPVOID ImageBase, + LPWSTR lpFilename, + DWORD nSize) +{ + return InternalGetDeviceDriverName(TRUE, TRUE, ImageBase, lpFilename, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetMappedFileNameA(HANDLE hProcess, + LPVOID lpv, + LPSTR lpFilename, + DWORD nSize) +{ + return InternalGetMappedFileName(FALSE, hProcess, lpv, lpFilename, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetMappedFileNameW(HANDLE hProcess, + LPVOID lpv, + LPWSTR lpFilename, + DWORD nSize) +{ + return InternalGetMappedFileName(TRUE, hProcess, lpv, lpFilename, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetModuleBaseNameA(HANDLE hProcess, + HMODULE hModule, + LPSTR lpBaseName, + DWORD nSize) +{ + GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, FALSE, FALSE}; + return InternalGetModuleInformation(hProcess, hModule, Flags, lpBaseName, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetModuleBaseNameW(HANDLE hProcess, + HMODULE hModule, + LPWSTR lpBaseName, + DWORD nSize) +{ + GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, TRUE, FALSE}; + return InternalGetModuleInformation(hProcess, hModule, Flags, lpBaseName, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetModuleFileNameExA(HANDLE hProcess, + HMODULE hModule, + LPSTR lpFilename, + DWORD nSize) +{ + GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, FALSE, TRUE}; + return InternalGetModuleInformation(hProcess, hModule, Flags, lpFilename, nSize); +} + + +/* + * @implemented + */ +DWORD +STDCALL +GetModuleFileNameExW(HANDLE hProcess, + HMODULE hModule, + LPWSTR lpFilename, + DWORD nSize) +{ + GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, TRUE, TRUE}; + return InternalGetModuleInformation(hProcess, hModule, Flags, lpFilename, nSize); +} + + +/* + * @implemented + */ +BOOL +STDCALL +GetModuleInformation(HANDLE hProcess, + HMODULE hModule, + LPMODULEINFO lpmodinfo, + DWORD cb) +{ + GET_MODULE_INFORMATION_FLAGS Flags = {FALSE, FALSE, FALSE}; + return (BOOL)InternalGetModuleInformation(hProcess, hModule, Flags, lpmodinfo, cb); +} + + +/* + * @implemented + */ +BOOL +STDCALL +InitializeProcessForWsWatch(HANDLE hProcess) +{ + NTSTATUS Status; + + Status = NtSetInformationProcess(hProcess, + ProcessWorkingSetWatch, + NULL, + 0); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; +} + + +/* + * @implemented + */ +BOOL +STDCALL +GetWsChanges(HANDLE hProcess, + PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, + DWORD cb) +{ + NTSTATUS Status; + + Status = NtQueryInformationProcess(hProcess, + ProcessWorkingSetWatch, + (PVOID)lpWatchInfo, + cb, + NULL); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } [truncated at 1000 lines; 1829 more skipped]