PSAPI: all the annoying stuff (enumeration and search, basically) has been taken...
authorKJK::Hyperion <hackbunny@reactos.org>
Sat, 31 Aug 2002 15:36:56 +0000 (15:36 +0000)
committerKJK::Hyperion <hackbunny@reactos.org>
Sat, 31 Aug 2002 15:36:56 +0000 (15:36 +0000)
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

reactos/lib/psapi/enum/module.c
reactos/lib/psapi/enum/process.c
reactos/lib/psapi/include/internal/psapi.h
reactos/lib/psapi/makefile
reactos/lib/psapi/misc/stubs.c
reactos/lib/psapi/misc/win32.c
reactos/lib/psapi/psapi.def
reactos/lib/psapi/psapi.edf

index 1c6428c..1428020 100644 (file)
@@ -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);
 }
index 9b3dbb8..6c18708 100644 (file)
@@ -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);
index f78e153..c8ba3a2 100644 (file)
@@ -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"
 
index f4253f4..7094e85 100644 (file)
@@ -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 = \
index 3b805e9..120bb74 100644 (file)
@@ -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 
index 9b6b61b..a78305b 100644 (file)
@@ -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
 
 #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 */
 
index 1da1926..37c7fa9 100644 (file)
@@ -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
index 78c6423..46c767c 100644 (file)
@@ -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