mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 19:21:38 +00:00
PSAPI: all the annoying stuff (enumeration and search, basically) has been taken care of. Only profiling remains to be implemented.
Check out the subsystem-independent routines in enum/ (FWIW: the whole DLL only imports two calls from kernel32.dll, SetLastError and AreFileApisANSI): they've been tested, and they could make for a great static library, to implement task manager, tlist, ToolHelp API, etc. Maybe a future addition to mingwnt? svn path=/trunk/; revision=3441
This commit is contained in:
parent
c0b94f90f9
commit
a0cbde7bb0
8 changed files with 746 additions and 233 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: module.c,v 1.2 2002/08/29 23:57:53 hyperion Exp $
|
||||
/* $Id: module.c,v 1.3 2002/08/31 15:36:55 hyperion Exp $
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
|
@ -23,8 +23,7 @@ STDCALL
|
|||
PsaEnumerateSystemModules
|
||||
(
|
||||
IN PSYSMOD_ENUM_ROUTINE Callback,
|
||||
IN OUT PVOID CallbackContext,
|
||||
IN OUT PVOID AllocatorContext
|
||||
IN OUT PVOID CallbackContext
|
||||
)
|
||||
{
|
||||
ULONG nSize;
|
||||
|
@ -63,8 +62,8 @@ PsaEnumerateSystemModules
|
|||
/* free the buffer, and reallocate it to the new size. RATIONALE: since we
|
||||
ignore the buffer's content at this point, there's no point in a realloc(),
|
||||
that could end up copying a large chunk of data we'd discard anyway */
|
||||
PsaFree(AllocatorContext, pnModuleCount);
|
||||
pTmp = PsaMalloc(AllocatorContext, nSize);
|
||||
free(pnModuleCount);
|
||||
pTmp = malloc(nSize);
|
||||
|
||||
if(pTmp == NULL)
|
||||
{
|
||||
|
@ -119,7 +118,7 @@ PsaEnumerateSystemModules
|
|||
|
||||
esm_Finalize:
|
||||
/* free the buffer */
|
||||
PsaFree(AllocatorContext, pnModuleCount);
|
||||
free(pnModuleCount);
|
||||
|
||||
return (nErrCode);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: process.c,v 1.2 2002/08/29 23:57:53 hyperion Exp $
|
||||
/* $Id: process.c,v 1.3 2002/08/31 15:36:55 hyperion Exp $
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
|
@ -23,8 +23,7 @@ STDCALL
|
|||
PsaEnumerateProcesses
|
||||
(
|
||||
IN PPROC_ENUM_ROUTINE Callback,
|
||||
IN OUT PVOID CallbackContext,
|
||||
IN OUT PVOID AllocatorContext
|
||||
IN OUT PVOID CallbackContext
|
||||
)
|
||||
{
|
||||
register NTSTATUS nErrCode = STATUS_SUCCESS;
|
||||
|
@ -44,8 +43,8 @@ PsaEnumerateProcesses
|
|||
/* free the buffer, and reallocate it to the new size. RATIONALE: since we
|
||||
ignore the buffer's contents at this point, there's no point in a realloc()
|
||||
that could end up copying a large chunk of data we'd discard anyway */
|
||||
PsaFree(AllocatorContext, pInfoBuffer);
|
||||
pTmp = PsaMalloc(AllocatorContext, nSize);
|
||||
free(pInfoBuffer);
|
||||
pTmp = malloc(nSize);
|
||||
|
||||
if(pTmp == NULL)
|
||||
{
|
||||
|
@ -101,7 +100,7 @@ PsaEnumerateProcesses
|
|||
|
||||
esp_Finalize:
|
||||
/* free the buffer */
|
||||
PsaFree(AllocatorContext, pInfoBuffer);
|
||||
free(pInfoBuffer);
|
||||
|
||||
/* return the last status */
|
||||
return (nErrCode);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: psapi.h,v 1.2 2002/08/29 23:57:54 hyperion Exp $
|
||||
/* $Id: psapi.h,v 1.3 2002/08/31 15:36:55 hyperion Exp $
|
||||
*/
|
||||
/*
|
||||
* internal/psapi.h
|
||||
|
@ -61,8 +61,7 @@ STDCALL
|
|||
PsaEnumerateProcesses
|
||||
(
|
||||
IN PPROC_ENUM_ROUTINE Callback,
|
||||
IN OUT PVOID CallbackContext,
|
||||
IN OUT PVOID AllocatorContext
|
||||
IN OUT PVOID CallbackContext
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
|
@ -70,8 +69,7 @@ STDCALL
|
|||
PsaEnumerateSystemModules
|
||||
(
|
||||
IN PSYSMOD_ENUM_ROUTINE Callback,
|
||||
IN OUT PVOID CallbackContext,
|
||||
IN OUT PVOID AllocatorContext
|
||||
IN OUT PVOID CallbackContext
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
|
@ -83,11 +81,6 @@ PsaEnumerateProcessModules
|
|||
IN OUT PVOID CallbackContext
|
||||
);
|
||||
|
||||
/* the user must provide these */
|
||||
PVOID STDCALL PsaMalloc(IN OUT PVOID Context, IN ULONG Size);
|
||||
PVOID STDCALL PsaRealloc(IN OUT PVOID Context, IN PVOID Addr, IN ULONG Size);
|
||||
VOID STDCALL PsaFree(IN OUT PVOID Context, IN PVOID Addr);
|
||||
|
||||
/* MACROS */
|
||||
#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.2 2002/06/18 22:15:57 hyperion Exp $
|
||||
# $Id: makefile,v 1.3 2002/08/31 15:36:56 hyperion Exp $
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
|
@ -10,8 +10,6 @@ TARGET_SDKLIBS = ntdll.a kernel32.a
|
|||
|
||||
TARGET_CFLAGS = -I./include -Wall
|
||||
|
||||
TARGET_LFLAGS = -nostdlib
|
||||
|
||||
TARGET_BASE = 0x68F70000
|
||||
|
||||
TARGET_OBJECTS = \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: stubs.c,v 1.3 2002/08/29 23:57:54 hyperion Exp $ */
|
||||
/* $Id: stubs.c,v 1.4 2002/08/31 15:36:56 hyperion Exp $ */
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
|
||||
|
@ -11,124 +11,7 @@ BOOL STDCALL EnumPageFiles(
|
|||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
DWORD STDCALL GetDeviceDriverBaseNameA(
|
||||
LPVOID ImageBase, // driver load address
|
||||
LPSTR lpBaseName, // driver base name buffer
|
||||
DWORD nSize // size of buffer
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetDeviceDriverBaseNameW(
|
||||
LPVOID ImageBase, // driver load address
|
||||
LPWSTR lpBaseName, // driver base name buffer
|
||||
DWORD nSize // size of buffer
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetDeviceDriverFileNameA(
|
||||
LPVOID ImageBase, // driver load address
|
||||
LPSTR lpFilename, // path buffer
|
||||
DWORD nSize // size of buffer
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetDeviceDriverFileNameW(
|
||||
LPVOID ImageBase, // driver load address
|
||||
LPWSTR lpFilename, // path buffer
|
||||
DWORD nSize // size of buffer
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetMappedFileNameA(
|
||||
HANDLE hProcess, // handle to process
|
||||
LPVOID lpv, // address to verify
|
||||
LPSTR lpFilename, // file name buffer
|
||||
DWORD nSize // size of buffer
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetMappedFileNameW(
|
||||
HANDLE hProcess, // handle to process
|
||||
LPVOID lpv, // address to verify
|
||||
LPWSTR lpFilename, // file name buffer
|
||||
DWORD nSize // size of buffer
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetModuleBaseNameA(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPSTR lpBaseName, // base name buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetModuleBaseNameW(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPWSTR lpBaseName, // base name buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetModuleFileNameExA(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPSTR lpFilename, // path buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetModuleFileNameExW(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPWSTR lpFilename, // path buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL STDCALL GetModuleInformation(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPMODULEINFO lpmodinfo, // information buffer
|
||||
DWORD cb // size of buffer
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FUNCTION);
|
||||
return FALSE;
|
||||
}
|
||||
#if 0
|
||||
BOOL STDCALL GetPerformanceInfo(
|
||||
PPERFORMANCE_INFORMATION pPerformanceInformation,
|
||||
DWORD cb
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: win32.c,v 1.2 2002/08/29 23:57:54 hyperion Exp $
|
||||
/* $Id: win32.c,v 1.3 2002/08/31 15:36:56 hyperion Exp $
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
|
@ -12,32 +12,18 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/psapi.h>
|
||||
|
||||
/* Memory allocators for PSAPI */
|
||||
PVOID STDCALL PsaMalloc(IN OUT PVOID Context, IN ULONG Size)
|
||||
{
|
||||
return malloc(Size);
|
||||
}
|
||||
|
||||
PVOID STDCALL PsaRealloc(IN OUT PVOID Context, IN PVOID Addr, IN ULONG Size)
|
||||
{
|
||||
return realloc(Addr, Size);
|
||||
}
|
||||
|
||||
VOID STDCALL PsaFree(IN OUT PVOID Context, IN PVOID Addr)
|
||||
{
|
||||
free(Addr);
|
||||
}
|
||||
|
||||
/* EmptyWorkingSet */
|
||||
BOOL STDCALL EmptyWorkingSet(HANDLE hProcess)
|
||||
{
|
||||
NTSTATUS nErrCode;
|
||||
QUOTA_LIMITS qlProcessQuota;
|
||||
|
||||
|
||||
/* query the working set */
|
||||
nErrCode = NtQueryInformationProcess
|
||||
(
|
||||
|
@ -51,11 +37,11 @@ BOOL STDCALL EmptyWorkingSet(HANDLE hProcess)
|
|||
/* failure */
|
||||
if(!NT_SUCCESS(nErrCode))
|
||||
goto fail;
|
||||
|
||||
|
||||
/* empty the working set */
|
||||
qlProcessQuota.MinimumWorkingSetSize = -1;
|
||||
qlProcessQuota.MaximumWorkingSetSize = -1;
|
||||
|
||||
|
||||
/* set the working set */
|
||||
nErrCode = NtSetInformationProcess
|
||||
(
|
||||
|
@ -68,7 +54,7 @@ BOOL STDCALL EmptyWorkingSet(HANDLE hProcess)
|
|||
/* success */
|
||||
if(NT_SUCCESS(nErrCode))
|
||||
return (TRUE);
|
||||
|
||||
|
||||
fail:
|
||||
/* failure */
|
||||
SetLastError(RtlNtStatusToDosError(nErrCode));
|
||||
|
@ -100,20 +86,20 @@ NTSTATUS STDCALL EnumDeviceDriversCallback
|
|||
|
||||
/* return current module */
|
||||
*(peddcContext->lpImageBase) = CurrentModule->BaseAddress;
|
||||
|
||||
|
||||
/* go to next array slot */
|
||||
(peddcContext->lpImageBase) ++;
|
||||
(peddcContext->nCount) --;
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* exported interface */
|
||||
BOOL STDCALL EnumDeviceDrivers
|
||||
(
|
||||
LPVOID *lpImageBase,
|
||||
DWORD cb,
|
||||
LPDWORD lpcbNeeded
|
||||
LPVOID *lpImageBase,
|
||||
DWORD cb,
|
||||
LPDWORD lpcbNeeded
|
||||
)
|
||||
{
|
||||
register NTSTATUS nErrCode;
|
||||
|
@ -127,15 +113,10 @@ BOOL STDCALL EnumDeviceDrivers
|
|||
*lpcbNeeded = 0;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* enumerate the system modules */
|
||||
nErrCode = PsaEnumerateSystemModules
|
||||
(
|
||||
&EnumDeviceDriversCallback,
|
||||
&eddcContext,
|
||||
NULL
|
||||
);
|
||||
|
||||
nErrCode = PsaEnumerateSystemModules(&EnumDeviceDriversCallback, &eddcContext);
|
||||
|
||||
/* return the count of bytes returned */
|
||||
*lpcbNeeded = (cb - eddcContext.nCount) * sizeof(PVOID);
|
||||
|
||||
|
@ -174,11 +155,11 @@ NTSTATUS STDCALL EnumProcessesCallback
|
|||
|
||||
/* return current process */
|
||||
*(pepcContext->lpidProcess) = CurrentProcess->ProcessId;
|
||||
|
||||
|
||||
/* go to next array slot */
|
||||
(pepcContext->lpidProcess) ++;
|
||||
(pepcContext->nCount) --;
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -192,7 +173,7 @@ BOOL STDCALL EnumProcesses
|
|||
{
|
||||
register NTSTATUS nErrCode;
|
||||
ENUM_PROCESSES_CONTEXT epcContext = {lpidProcess, cb / sizeof(DWORD)};
|
||||
|
||||
|
||||
cb /= sizeof(DWORD);
|
||||
|
||||
/* do nothing if the buffer is empty */
|
||||
|
@ -201,10 +182,10 @@ BOOL STDCALL EnumProcesses
|
|||
*lpcbNeeded = 0;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* enumerate the process ids */
|
||||
nErrCode = PsaEnumerateProcesses(&EnumProcessesCallback, &epcContext, NULL);
|
||||
|
||||
nErrCode = PsaEnumerateProcesses(&EnumProcessesCallback, &epcContext);
|
||||
|
||||
*lpcbNeeded = (cb - epcContext.nCount) * sizeof(DWORD);
|
||||
|
||||
/* success */
|
||||
|
@ -234,7 +215,7 @@ NTSTATUS STDCALL EnumProcessModulesCallback
|
|||
IN OUT PVOID CallbackContext
|
||||
)
|
||||
{
|
||||
register PENUM_PROCESS_MODULES_CONTEXT pepmcContext =
|
||||
register PENUM_PROCESS_MODULES_CONTEXT pepmcContext =
|
||||
(PENUM_PROCESS_MODULES_CONTEXT)CallbackContext;
|
||||
|
||||
/* no more buffer space */
|
||||
|
@ -243,25 +224,25 @@ NTSTATUS STDCALL EnumProcessModulesCallback
|
|||
|
||||
/* return current process */
|
||||
*(pepmcContext->lphModule) = CurrentModule->BaseAddress;
|
||||
|
||||
|
||||
/* go to next array slot */
|
||||
(pepmcContext->lphModule) ++;
|
||||
(pepmcContext->nCount) --;
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* exported interface */
|
||||
BOOL STDCALL EnumProcessModules(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE *lphModule, // array of module handles
|
||||
DWORD cb, // size of array
|
||||
LPDWORD lpcbNeeded // number of bytes required
|
||||
HANDLE hProcess,
|
||||
HMODULE *lphModule,
|
||||
DWORD cb,
|
||||
LPDWORD lpcbNeeded
|
||||
)
|
||||
{
|
||||
register NTSTATUS nErrCode;
|
||||
ENUM_PROCESS_MODULES_CONTEXT epmcContext = {lphModule, cb / sizeof(HMODULE)};
|
||||
|
||||
|
||||
cb /= sizeof(DWORD);
|
||||
|
||||
/* do nothing if the buffer is empty */
|
||||
|
@ -270,7 +251,7 @@ BOOL STDCALL EnumProcessModules(
|
|||
*lpcbNeeded = 0;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* enumerate the process modules */
|
||||
nErrCode = PsaEnumerateProcessModules
|
||||
(
|
||||
|
@ -278,7 +259,7 @@ BOOL STDCALL EnumProcessModules(
|
|||
&EnumProcessModulesCallback,
|
||||
&epmcContext
|
||||
);
|
||||
|
||||
|
||||
*lpcbNeeded = (cb - epmcContext.nCount) * sizeof(DWORD);
|
||||
|
||||
/* success */
|
||||
|
@ -292,5 +273,665 @@ BOOL STDCALL EnumProcessModules(
|
|||
}
|
||||
}
|
||||
|
||||
/* GetDeviceDriverBase/FileName */
|
||||
/* common callback context */
|
||||
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;
|
||||
|
||||
/* common callback routine */
|
||||
NTSTATUS STDCALL GetDeviceDriverNameCallback
|
||||
(
|
||||
IN ULONG ModuleCount,
|
||||
IN PSYSTEM_MODULE_ENTRY CurrentModule,
|
||||
IN OUT PVOID CallbackContext
|
||||
)
|
||||
{
|
||||
register PGET_DEVICE_DRIVER_NAME_CONTEXT pgddncContext =
|
||||
(PGET_DEVICE_DRIVER_NAME_CONTEXT) CallbackContext;
|
||||
|
||||
/* module found */
|
||||
if(pgddncContext->ImageBase == CurrentModule->BaseAddress)
|
||||
{
|
||||
register PCHAR pcModuleName;
|
||||
register ULONG l;
|
||||
|
||||
/* get the full name or just the filename part */
|
||||
if(pgddncContext->bFullName)
|
||||
pcModuleName = &CurrentModule->Name[0];
|
||||
else
|
||||
pcModuleName = &CurrentModule->Name[CurrentModule->PathLength];
|
||||
|
||||
/* get the length of the name */
|
||||
l = strlen(pcModuleName);
|
||||
|
||||
/* if user buffer smaller than the name */
|
||||
if(pgddncContext->nSize <= l)
|
||||
/* use the user buffer's length */
|
||||
l = pgddncContext->nSize;
|
||||
/* if user buffer larger than the name */
|
||||
else
|
||||
{
|
||||
/* enough space for the null terminator */
|
||||
l ++;
|
||||
pgddncContext->nSize = l;
|
||||
}
|
||||
|
||||
/* copy the string */
|
||||
if(pgddncContext->bUnicode)
|
||||
{
|
||||
/* Unicode: convert and copy */
|
||||
ANSI_STRING strAnsi = {l, l, pcModuleName};
|
||||
UNICODE_STRING wstrUnicode =
|
||||
{
|
||||
0,
|
||||
l * sizeof(WCHAR),
|
||||
pgddncContext->lpUnicodeName
|
||||
};
|
||||
/* driver names should always be in language-neutral ASCII, so we don't
|
||||
bother calling AreFileApisANSI() */
|
||||
RtlAnsiStringToUnicodeString(&wstrUnicode, &strAnsi, FALSE);
|
||||
}
|
||||
else
|
||||
/* ANSI/OEM: direct copy */
|
||||
memcpy(pgddncContext->lpAnsiName, pcModuleName, l);
|
||||
|
||||
/* terminate the enumeration */
|
||||
return STATUS_NO_MORE_FILES;
|
||||
}
|
||||
/* continue searching */
|
||||
else
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* common internal implementation */
|
||||
DWORD FASTCALL internalGetDeviceDriverName(
|
||||
BOOLEAN bUnicode,
|
||||
BOOLEAN bFullName,
|
||||
LPVOID ImageBase,
|
||||
LPVOID lpName,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
register NTSTATUS nErrCode;
|
||||
GET_DEVICE_DRIVER_NAME_CONTEXT gddncContext =
|
||||
{
|
||||
ImageBase,
|
||||
{ bFullName, bUnicode },
|
||||
nSize,
|
||||
{ lpName }
|
||||
};
|
||||
|
||||
/* empty buffer */
|
||||
if(lpName == NULL || nSize == 0)
|
||||
return 0;
|
||||
|
||||
/* invalid image base */
|
||||
if(ImageBase == NULL)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* start the enumeration */
|
||||
nErrCode = PsaEnumerateSystemModules
|
||||
(
|
||||
&GetDeviceDriverNameCallback,
|
||||
&gddncContext
|
||||
);
|
||||
|
||||
if(nErrCode == STATUS_NO_MORE_FILES)
|
||||
/* module was found, return string size */
|
||||
return gddncContext.nSize;
|
||||
else
|
||||
{
|
||||
if(NT_SUCCESS(nErrCode))
|
||||
/* module was not found */
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
else
|
||||
/* an error occurred */
|
||||
SetLastError(RtlNtStatusToDosError(nErrCode));
|
||||
|
||||
/* failure */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* exported interfaces */
|
||||
/*
|
||||
NOTES:
|
||||
- nSize is not, as stated by Microsoft's documentation, the byte size, but the
|
||||
count of characters in the buffer
|
||||
- the return value is the count of characters copied into the buffer
|
||||
- the functions don't attempt to null-terminate the string
|
||||
*/
|
||||
DWORD STDCALL GetDeviceDriverBaseNameA(
|
||||
LPVOID ImageBase,
|
||||
LPSTR lpBaseName,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
return internalGetDeviceDriverName(FALSE, FALSE, ImageBase, lpBaseName, nSize);
|
||||
}
|
||||
|
||||
DWORD STDCALL GetDeviceDriverFileNameA(
|
||||
LPVOID ImageBase,
|
||||
LPSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
return internalGetDeviceDriverName(FALSE, TRUE, ImageBase, lpFilename, nSize);
|
||||
}
|
||||
|
||||
DWORD STDCALL GetDeviceDriverBaseNameW(
|
||||
LPVOID ImageBase,
|
||||
LPWSTR lpBaseName,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
return internalGetDeviceDriverName(TRUE, FALSE, ImageBase, lpBaseName, nSize);
|
||||
}
|
||||
|
||||
DWORD STDCALL GetDeviceDriverFileNameW(
|
||||
LPVOID ImageBase,
|
||||
LPWSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
return internalGetDeviceDriverName(TRUE, TRUE, ImageBase, lpFilename, nSize);
|
||||
}
|
||||
|
||||
/* GetMappedFileName */
|
||||
/* common internal implementation */
|
||||
DWORD FASTCALL internalGetMappedFileName(
|
||||
BOOLEAN bUnicode,
|
||||
HANDLE hProcess,
|
||||
LPVOID lpv,
|
||||
LPVOID lpName,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
register NTSTATUS nErrCode;
|
||||
register ULONG nBufSize;
|
||||
PMEMORY_SECTION_NAME pmsnName;
|
||||
|
||||
/* empty buffer */
|
||||
if(nSize == 0 || (LPSTR)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 = malloc(nBufSize + offsetof(MEMORY_SECTION_NAME, NameBuffer));
|
||||
|
||||
if(pmsnName == NULL)
|
||||
{
|
||||
/* failure */
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize the destination buffer */
|
||||
pmsnName->SectionFileName.Length = 0;
|
||||
pmsnName->SectionFileName.Length = nBufSize;
|
||||
|
||||
#if 0
|
||||
__try
|
||||
{
|
||||
#endif
|
||||
/* query the name */
|
||||
nErrCode = NtQueryVirtualMemory
|
||||
(
|
||||
hProcess,
|
||||
lpv,
|
||||
MemorySectionName,
|
||||
pmsnName,
|
||||
nBufSize,
|
||||
NULL
|
||||
);
|
||||
|
||||
if(!NT_SUCCESS(nErrCode))
|
||||
{
|
||||
/* failure */
|
||||
SetLastError(RtlNtStatusToDosError(nErrCode));
|
||||
#if 0
|
||||
#else
|
||||
/* free the buffer */
|
||||
free(pmsnName);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy the name */
|
||||
if(bUnicode)
|
||||
{
|
||||
/* destination is an Unicode string: direct copy */
|
||||
memcpy
|
||||
(
|
||||
(LPWSTR)lpName,
|
||||
pmsnName->NameBuffer,
|
||||
pmsnName->SectionFileName.Length
|
||||
);
|
||||
|
||||
#if 0
|
||||
#else
|
||||
/* free the buffer */
|
||||
free(pmsnName);
|
||||
#endif
|
||||
|
||||
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 strAnsi = {0, nSize, (LPSTR)lpName};
|
||||
|
||||
if(AreFileApisANSI())
|
||||
/* destination is an ANSI string: convert and copy */
|
||||
RtlUnicodeStringToAnsiString(&strAnsi, &pmsnName->SectionFileName, FALSE);
|
||||
else
|
||||
/* destination is an OEM string: convert and copy */
|
||||
RtlUnicodeStringToOemString(&strAnsi, &pmsnName->SectionFileName, FALSE);
|
||||
|
||||
#if 0
|
||||
#else
|
||||
/* free the buffer */
|
||||
free(pmsnName);
|
||||
#endif
|
||||
|
||||
if(strAnsi.Length < nSize)
|
||||
{
|
||||
/* null-terminate the string */
|
||||
((LPSTR)lpName)[strAnsi.Length] = 0;
|
||||
return strAnsi.Length + 1;
|
||||
}
|
||||
|
||||
return strAnsi.Length;
|
||||
}
|
||||
|
||||
#if 0
|
||||
}
|
||||
__finally
|
||||
{
|
||||
free(pmsnName);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* exported interfaces */
|
||||
DWORD STDCALL GetMappedFileNameA(
|
||||
HANDLE hProcess,
|
||||
LPVOID lpv,
|
||||
LPSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
return internalGetMappedFileName(FALSE, hProcess, lpv, lpFilename, nSize);
|
||||
}
|
||||
|
||||
DWORD STDCALL GetMappedFileNameW(
|
||||
HANDLE hProcess,
|
||||
LPVOID lpv,
|
||||
LPWSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
return internalGetMappedFileName(TRUE, hProcess, lpv, lpFilename, nSize);
|
||||
}
|
||||
|
||||
/* GetModuleInformation */
|
||||
/* common callback context */
|
||||
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;
|
||||
|
||||
/* common callback */
|
||||
NTSTATUS STDCALL GetModuleInformationCallback
|
||||
(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PLDR_MODULE CurrentModule,
|
||||
IN OUT PVOID CallbackContext
|
||||
)
|
||||
{
|
||||
register PGET_MODULE_INFORMATION_CONTEXT pgmicContext =
|
||||
(PGET_MODULE_INFORMATION_CONTEXT)CallbackContext;
|
||||
|
||||
/* found the module we were looking for */
|
||||
if(CurrentModule->BaseAddress == pgmicContext->hModule)
|
||||
{
|
||||
/* we want the module name */
|
||||
if(pgmicContext->Flags.bWantName)
|
||||
{
|
||||
register NTSTATUS nErrCode;
|
||||
register PUNICODE_STRING pwstrSource;
|
||||
register ULONG l;
|
||||
|
||||
if(pgmicContext->Flags.bFullName)
|
||||
/* full name */
|
||||
pwstrSource = &(CurrentModule->FullDllName);
|
||||
else
|
||||
/* base name only */
|
||||
pwstrSource = &(CurrentModule->BaseDllName);
|
||||
|
||||
/* paranoia */
|
||||
pwstrSource->Length -= pwstrSource->Length % sizeof(WCHAR);
|
||||
|
||||
/* l is the byte size of the user buffer */
|
||||
l = pgmicContext->nBufSize * sizeof(WCHAR);
|
||||
|
||||
/* if the user buffer has room for the string and a null terminator */
|
||||
if(l >= (pwstrSource->Length + sizeof(WCHAR)))
|
||||
{
|
||||
/* limit the buffer size */
|
||||
l = pwstrSource->Length;
|
||||
|
||||
/* null-terminate the string */
|
||||
if(pgmicContext->Flags.bUnicode)
|
||||
pgmicContext->lpUnicodeName[l / sizeof(WCHAR)] = 0;
|
||||
else
|
||||
pgmicContext->lpAnsiName[l / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
if(pgmicContext->Flags.bUnicode)
|
||||
{
|
||||
/* Unicode: direct copy */
|
||||
/* NOTE: I've chosen not to check for ProcessHandle == NtCurrentProcess(),
|
||||
this function is complicated enough as it is */
|
||||
nErrCode = NtReadVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
pwstrSource->Buffer,
|
||||
pgmicContext->lpUnicodeName,
|
||||
l,
|
||||
NULL
|
||||
);
|
||||
|
||||
if(NT_SUCCESS(nErrCode))
|
||||
pgmicContext->nBufSize = l / sizeof(WCHAR);
|
||||
else
|
||||
{
|
||||
pgmicContext->nBufSize = 0;
|
||||
return nErrCode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ANSI/OEM: convert and copy */
|
||||
register LPWSTR pwcUnicodeBuf;
|
||||
ANSI_STRING strAnsi = {0, pgmicContext->nBufSize, pgmicContext->lpAnsiName};
|
||||
UNICODE_STRING wstrUnicodeBuf;
|
||||
|
||||
/* allocate the local buffer */
|
||||
pwcUnicodeBuf = malloc(pwstrSource->Length);
|
||||
|
||||
#if 0
|
||||
__try
|
||||
{
|
||||
#endif
|
||||
if(pwcUnicodeBuf == NULL)
|
||||
/* failure */
|
||||
#if 0
|
||||
return STATUS_NO_MEMORY;
|
||||
#else
|
||||
{
|
||||
nErrCode = STATUS_NO_MEMORY;
|
||||
goto exitWithStatus;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* copy the string in the local buffer */
|
||||
nErrCode = NtReadVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
pwstrSource->Buffer,
|
||||
pwcUnicodeBuf,
|
||||
l,
|
||||
NULL
|
||||
);
|
||||
|
||||
if(!NT_SUCCESS(nErrCode))
|
||||
/* failure */
|
||||
#if 0
|
||||
return nErrCode;
|
||||
#else
|
||||
goto exitWithStatus;
|
||||
#endif
|
||||
|
||||
/* initialize Unicode string buffer */
|
||||
wstrUnicodeBuf.Length = wstrUnicodeBuf.MaximumLength = l;
|
||||
wstrUnicodeBuf.Buffer = pwcUnicodeBuf;
|
||||
|
||||
/* convert and copy */
|
||||
if(AreFileApisANSI())
|
||||
RtlUnicodeStringToAnsiString(&strAnsi, &wstrUnicodeBuf, FALSE);
|
||||
else
|
||||
RtlUnicodeStringToOemString(&strAnsi, &wstrUnicodeBuf, FALSE);
|
||||
|
||||
/* return the string size */
|
||||
pgmicContext->nBufSize = strAnsi.Length;
|
||||
#if 0
|
||||
}
|
||||
__finally
|
||||
{
|
||||
/* free the buffer */
|
||||
free(pwcUnicodeBuf);
|
||||
}
|
||||
#else
|
||||
/* success */
|
||||
nErrCode = STATUS_NO_MORE_FILES;
|
||||
|
||||
exitWithStatus:
|
||||
/* free the buffer */
|
||||
free(pwcUnicodeBuf);
|
||||
return nErrCode;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
/* we want other module information */
|
||||
else
|
||||
{
|
||||
register ULONG nSize = pgmicContext->nBufSize;
|
||||
|
||||
/* base address */
|
||||
if(nSize >= sizeof(CurrentModule->BaseAddress))
|
||||
{
|
||||
pgmicContext->lpmodinfo->lpBaseOfDll = CurrentModule->BaseAddress;
|
||||
nSize -= sizeof(CurrentModule->BaseAddress);
|
||||
}
|
||||
|
||||
/* image size */
|
||||
if(nSize >= sizeof(CurrentModule->SizeOfImage))
|
||||
{
|
||||
pgmicContext->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? */
|
||||
pgmicContext->lpmodinfo->EntryPoint = (PVOID)CurrentModule->EntryPoint;
|
||||
|
||||
pgmicContext->nBufSize = TRUE;
|
||||
}
|
||||
|
||||
return STATUS_NO_MORE_FILES;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* common internal implementation */
|
||||
DWORD FASTCALL internalGetModuleInformation(
|
||||
HANDLE hProcess,
|
||||
HMODULE hModule,
|
||||
GET_MODULE_INFORMATION_FLAGS Flags,
|
||||
LPVOID lpBuffer,
|
||||
DWORD nBufSize
|
||||
)
|
||||
{
|
||||
register NTSTATUS nErrCode;
|
||||
GET_MODULE_INFORMATION_CONTEXT gmicContext =
|
||||
{
|
||||
hModule,
|
||||
Flags,
|
||||
nBufSize,
|
||||
{lpBuffer}
|
||||
};
|
||||
|
||||
|
||||
nErrCode = PsaEnumerateProcessModules
|
||||
(
|
||||
hProcess,
|
||||
&GetModuleInformationCallback,
|
||||
&gmicContext
|
||||
);
|
||||
|
||||
if(nErrCode == STATUS_NO_MORE_FILES)
|
||||
return gmicContext.nBufSize;
|
||||
else
|
||||
{
|
||||
if(NT_SUCCESS(nErrCode))
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
else
|
||||
SetLastError(RtlNtStatusToDosError(nErrCode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* exported interfaces */
|
||||
DWORD STDCALL GetModuleBaseNameA(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPSTR lpBaseName, // base name buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
register GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, FALSE, FALSE};
|
||||
return internalGetModuleInformation
|
||||
(
|
||||
hProcess,
|
||||
hModule,
|
||||
Flags,
|
||||
lpBaseName,
|
||||
nSize
|
||||
);
|
||||
}
|
||||
|
||||
DWORD STDCALL GetModuleBaseNameW(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPWSTR lpBaseName, // base name buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
register GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, TRUE, FALSE};
|
||||
return internalGetModuleInformation
|
||||
(
|
||||
hProcess,
|
||||
hModule,
|
||||
Flags,
|
||||
lpBaseName,
|
||||
nSize
|
||||
);
|
||||
}
|
||||
|
||||
DWORD STDCALL GetModuleFileNameExA(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPSTR lpFilename, // path buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
register GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, FALSE, TRUE};
|
||||
return internalGetModuleInformation
|
||||
(
|
||||
hProcess,
|
||||
hModule,
|
||||
Flags,
|
||||
lpFilename,
|
||||
nSize
|
||||
);
|
||||
}
|
||||
|
||||
DWORD STDCALL GetModuleFileNameExW(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPWSTR lpFilename, // path buffer
|
||||
DWORD nSize // maximum characters to retrieve
|
||||
)
|
||||
{
|
||||
register GET_MODULE_INFORMATION_FLAGS Flags = {TRUE, TRUE, TRUE};
|
||||
return internalGetModuleInformation
|
||||
(
|
||||
hProcess,
|
||||
hModule,
|
||||
Flags,
|
||||
lpFilename,
|
||||
nSize
|
||||
);
|
||||
}
|
||||
|
||||
BOOL STDCALL GetModuleInformation(
|
||||
HANDLE hProcess, // handle to process
|
||||
HMODULE hModule, // handle to module
|
||||
LPMODULEINFO lpmodinfo, // information buffer
|
||||
DWORD cb // size of buffer
|
||||
)
|
||||
{
|
||||
register GET_MODULE_INFORMATION_FLAGS Flags = {FALSE, FALSE, FALSE};
|
||||
return (BOOL)internalGetModuleInformation
|
||||
(
|
||||
hProcess,
|
||||
hModule,
|
||||
Flags,
|
||||
lpmodinfo,
|
||||
cb
|
||||
);
|
||||
}
|
||||
/* EOF */
|
||||
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
; $Id: psapi.def,v 1.1 2002/06/18 22:11:55 hyperion Exp $
|
||||
; $Id: psapi.def,v 1.2 2002/08/31 15:36:56 hyperion Exp $
|
||||
;
|
||||
|
||||
LIBRARY PSAPI.DLL
|
||||
EXPORTS
|
||||
EmptyWorkingSet@4
|
||||
EnumDeviceDrivers@12
|
||||
EnumProcessModules@16
|
||||
EnumProcesses@12
|
||||
GetDeviceDriverBaseNameA@12
|
||||
GetDeviceDriverBaseNameW@12
|
||||
GetDeviceDriverFileNameA@12
|
||||
GetDeviceDriverFileNameW@12
|
||||
GetMappedFileNameA@16
|
||||
GetMappedFileNameW@16
|
||||
GetModuleBaseNameA@16
|
||||
GetModuleBaseNameW@16
|
||||
GetModuleFileNameExA@16
|
||||
GetModuleFileNameExW@16
|
||||
GetModuleInformation@16
|
||||
GetProcessMemoryInfo@12
|
||||
GetWsChanges@12
|
||||
InitializeProcessForWsWatch@4
|
||||
QueryWorkingSet@12
|
||||
EmptyWorkingSet @10
|
||||
EnumDeviceDrivers @2
|
||||
EnumProcessModules @3
|
||||
EnumProcesses @4
|
||||
GetDeviceDriverBaseNameA @5
|
||||
GetDeviceDriverBaseNameW @6
|
||||
GetDeviceDriverFileNameA @7
|
||||
GetDeviceDriverFileNameW @8
|
||||
GetMappedFileNameA @9
|
||||
GetMappedFileNameW @1
|
||||
GetModuleBaseNameA @11
|
||||
GetModuleBaseNameW @12
|
||||
GetModuleFileNameExA @13
|
||||
GetModuleFileNameExW @14
|
||||
GetModuleInformation @15
|
||||
GetProcessMemoryInfo @16
|
||||
GetWsChanges @17
|
||||
InitializeProcessForWsWatch @18
|
||||
QueryWorkingSet @19
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
; $Id: psapi.edf,v 1.1 2002/06/18 22:16:53 hyperion Exp $
|
||||
; $Id: psapi.edf,v 1.2 2002/08/31 15:36:56 hyperion Exp $
|
||||
;
|
||||
|
||||
LIBRARY PSAPI.DLL
|
||||
EXPORTS
|
||||
EmptyWorkingSet=EmptyWorkingSet@4
|
||||
EnumDeviceDrivers=EnumDeviceDrivers@12
|
||||
EnumProcessModules=EnumProcessModules@16
|
||||
EnumProcesses=EnumProcesses@12
|
||||
GetDeviceDriverBaseNameA=GetDeviceDriverBaseNameA@12
|
||||
GetDeviceDriverBaseNameW=GetDeviceDriverBaseNameW@12
|
||||
GetDeviceDriverFileNameA=GetDeviceDriverFileNameA@12
|
||||
GetDeviceDriverFileNameW=GetDeviceDriverFileNameW@12
|
||||
GetMappedFileNameA=GetMappedFileNameA@16
|
||||
GetMappedFileNameW=GetMappedFileNameW@16
|
||||
GetModuleBaseNameA=GetModuleBaseNameA@16
|
||||
GetModuleBaseNameW=GetModuleBaseNameW@16
|
||||
GetModuleFileNameExA=GetModuleFileNameExA@16
|
||||
GetModuleFileNameExW=GetModuleFileNameExW@16
|
||||
GetModuleInformation=GetModuleInformation@16
|
||||
GetProcessMemoryInfo=GetProcessMemoryInfo@12
|
||||
GetWsChanges=GetWsChanges@12
|
||||
InitializeProcessForWsWatch=InitializeProcessForWsWatch@4
|
||||
QueryWorkingSet=QueryWorkingSet@12
|
||||
EmptyWorkingSet=EmptyWorkingSet@4 @10
|
||||
EnumDeviceDrivers=EnumDeviceDrivers@12 @2
|
||||
EnumProcessModules=EnumProcessModules@16 @3
|
||||
EnumProcesses=EnumProcesses@12 @4
|
||||
GetDeviceDriverBaseNameA=GetDeviceDriverBaseNameA@12 @5
|
||||
GetDeviceDriverBaseNameW=GetDeviceDriverBaseNameW@12 @6
|
||||
GetDeviceDriverFileNameA=GetDeviceDriverFileNameA@12 @7
|
||||
GetDeviceDriverFileNameW=GetDeviceDriverFileNameW@12 @8
|
||||
GetMappedFileNameA=GetMappedFileNameA@16 @9
|
||||
GetMappedFileNameW=GetMappedFileNameW@16 @1
|
||||
GetModuleBaseNameA=GetModuleBaseNameA@16 @11
|
||||
GetModuleBaseNameW=GetModuleBaseNameW@16 @12
|
||||
GetModuleFileNameExA=GetModuleFileNameExA@16 @13
|
||||
GetModuleFileNameExW=GetModuleFileNameExW@16 @14
|
||||
GetModuleInformation=GetModuleInformation@16 @15
|
||||
GetProcessMemoryInfo=GetProcessMemoryInfo@12 @16
|
||||
GetWsChanges=GetWsChanges@12 @17
|
||||
InitializeProcessForWsWatch=InitializeProcessForWsWatch@4 @18
|
||||
QueryWorkingSet=QueryWorkingSet@12 @19
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue