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]