Stub implementations for EnumPageFiles{A,W}, GetProcessImageFileName{A,W}.
Implement GetPerformanceInfo, GetProcessMemoryInfo on top of
NtQueryInformationProcess and GetWsChanges, QueryWorkingSet{,Ex} on
top of NtQueryVirtualMemory.

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index c714564..e32a62a 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1449,7 +1449,12 @@
     UINT size = 0;
     MEMORY_BASIC_INFORMATION *info = buffer;
 
-    if (info_class != MemoryBasicInformation) return STATUS_INVALID_INFO_CLASS;
+    if (info_class != MemoryBasicInformation)
+    {
+        FIXME("(%p, %p, %ld, %p, %ld, %p) Unimplemented information class\n", process, addr,
+              info_class, buffer, len, res_len);
+        return STATUS_INVALID_INFO_CLASS;
+    }
     if (ADDRESS_SPACE_LIMIT && addr >= ADDRESS_SPACE_LIMIT)
         return STATUS_WORKING_SET_LIMIT_RANGE;
 
diff --git a/dlls/psapi/psapi.spec b/dlls/psapi/psapi.spec
index 2bedfef..a7066af 100644
--- a/dlls/psapi/psapi.spec
+++ b/dlls/psapi/psapi.spec
@@ -1,7 +1,7 @@
 @ stdcall EmptyWorkingSet(long)
 @ stdcall EnumDeviceDrivers(ptr long ptr)
-@ stub    EnumPageFilesA
-@ stub    EnumPageFilesW
+@ stdcall EnumPageFilesA(ptr ptr)
+@ stdcall EnumPageFilesW(ptr ptr)
 @ stdcall EnumProcessModules(long ptr long ptr)
 @ stdcall EnumProcesses(ptr long ptr)
 @ stdcall GetDeviceDriverBaseNameA(ptr str long)
@@ -15,10 +15,11 @@
 @ stdcall GetModuleFileNameExA(long long str long)
 @ stdcall GetModuleFileNameExW(long long wstr long)
 @ stdcall GetModuleInformation(long long ptr long)
-@ stub    GetPerformanceInfo
-@ stub    GetProcessImageFileNameA
-@ stub    GetProcessImageFileNameW
+@ stdcall GetPerformanceInfo(ptr long)
+@ stdcall GetProcessImageFileNameA(long ptr long)
+@ stdcall GetProcessImageFileNameW(long ptr long)
 @ stdcall GetProcessMemoryInfo(long ptr long)
 @ stdcall GetWsChanges(long ptr long)
 @ stdcall InitializeProcessForWsWatch(long)
 @ stdcall QueryWorkingSet(long ptr long)
+@ stdcall QueryWorkingSetEx(long ptr long)
diff --git a/dlls/psapi/psapi_main.c b/dlls/psapi/psapi_main.c
index c61770e..bd1c73b 100644
--- a/dlls/psapi/psapi_main.c
+++ b/dlls/psapi/psapi_main.c
@@ -28,6 +28,7 @@
 #include "wine/unicode.h"
 #include "wine/debug.h"
 #include "winnls.h"
+#include "ntstatus.h"
 #include "psapi.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(psapi);
@@ -53,6 +54,23 @@
     return TRUE;
 }
 
+/***********************************************************************
+ *           EnumPageFilesA (PSAPI.@)
+ */
+BOOL WINAPI EnumPageFilesA( PENUM_PAGE_FILE_CALLBACKA callback, LPVOID context )
+{
+    FIXME("(%p, %p) stub\n", callback, context );
+    return FALSE;
+}
+
+/***********************************************************************
+ *           EnumPageFilesW (PSAPI.@)
+ */
+BOOL WINAPI EnumPageFilesW( PENUM_PAGE_FILE_CALLBACKW callback, LPVOID context )
+{
+    FIXME("(%p, %p) stub\n", callback, context );
+    return FALSE;
+}
 
 /***********************************************************************
  *           EnumProcesses (PSAPI.@)
@@ -443,15 +461,75 @@
 }
 
 /***********************************************************************
- *           GetProcessMemoryInfo (PSAPI.@)
+ *           GetPerformanceInfo (PSAPI.@)
  */
-BOOL WINAPI GetProcessMemoryInfo(HANDLE Process, 
-                                 PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb)
+BOOL WINAPI GetPerformanceInfo( PPERFORMANCE_INFORMATION info, DWORD size )
 {
-    FIXME("(hProcess=%p, %p, %ld): stub\n",
-          Process, ppsmemCounters, cb);
-    
-    memset(ppsmemCounters, 0, cb);
+    NTSTATUS status;
+
+    TRACE( "(%p, %ld)\n", info, size );
+
+    status = NtQueryInformationProcess( GetCurrentProcess(), SystemPerformanceInformation, info, size, NULL );
+
+    if (status)
+    {
+        SetLastError( RtlNtStatusToDosError( status ) );
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *           GetProcessImageFileNameA (PSAPI.@)
+ */
+DWORD WINAPI GetProcessImageFileNameA( HANDLE process, LPSTR file, DWORD size )
+{
+    FIXME("(%p, %p, %ld) stub\n", process, file, size );
+    return 0;
+}
+
+/***********************************************************************
+ *           GetProcessImageFileNameW (PSAPI.@)
+ */
+DWORD WINAPI GetProcessImageFileNameW( HANDLE process, LPWSTR file, DWORD size )
+{
+    FIXME("(%p, %p, %ld) stub\n", process, file, size );
+    return 0;
+}
+
+/***********************************************************************
+ *           GetProcessMemoryInfo (PSAPI.@)
+ *
+ * Retrieve memory usage information for a given process
+ *
+ */
+BOOL WINAPI GetProcessMemoryInfo( HANDLE process, PPROCESS_MEMORY_COUNTERS counters, DWORD size )
+{
+    NTSTATUS status;
+    VM_COUNTERS vmc;
+
+    TRACE( "(%p, %p, %ld)\n", process, counters, size );
+
+    status = NtQueryInformationProcess( process, ProcessVmCounters, &vmc, sizeof(vmc), NULL );
+
+    if (status)
+    {
+        SetLastError( RtlNtStatusToDosError( status ) );
+        return FALSE;
+    }
+
+    /* FIXME: check size */
+
+    counters->cb = sizeof(PROCESS_MEMORY_COUNTERS);
+    counters->PageFaultCount = vmc.PageFaultCount;
+    counters->PeakWorkingSetSize = vmc.PeakWorkingSetSize;
+    counters->WorkingSetSize = vmc.WorkingSetSize;
+    counters->QuotaPeakPagedPoolUsage = vmc.QuotaPeakPagedPoolUsage;
+    counters->QuotaPagedPoolUsage = vmc.QuotaPagedPoolUsage;
+    counters->QuotaPeakNonPagedPoolUsage = vmc.QuotaPeakNonPagedPoolUsage;
+    counters->QuotaNonPagedPoolUsage = vmc.QuotaNonPagedPoolUsage;
+    counters->PagefileUsage = vmc.PagefileUsage;
+    counters->PeakPagefileUsage = vmc.PeakPagefileUsage;
 
     return TRUE;
 }
@@ -459,14 +537,19 @@
 /***********************************************************************
  *           GetWsChanges (PSAPI.@)
  */
-BOOL WINAPI GetWsChanges(HANDLE hProcess, 
-                         PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, DWORD cb)
+BOOL WINAPI GetWsChanges( HANDLE process, PPSAPI_WS_WATCH_INFORMATION watchinfo, DWORD size )
 {
-    FIXME("(hProcess=%p, %p, %ld): stub\n",
-          hProcess, lpWatchInfo, cb);
+    NTSTATUS status;
 
-    memset(lpWatchInfo, 0, cb);
+    TRACE( "(%p, %p, %ld)\n", process, watchinfo, size );
 
+    status = NtQueryVirtualMemory( process, NULL, ProcessWorkingSetWatch, watchinfo, size, NULL );
+
+    if (status)
+    {
+        SetLastError( RtlNtStatusToDosError( status ) );
+        return FALSE;
+    }
     return TRUE;
 }
 
@@ -483,12 +566,37 @@
 /***********************************************************************
  *           QueryWorkingSet (PSAPI.@)
  */
-BOOL WINAPI QueryWorkingSet(HANDLE hProcess, LPVOID pv, DWORD cb)
+BOOL WINAPI QueryWorkingSet( HANDLE process, LPVOID buffer, DWORD size )
 {
-    FIXME("(hProcess=%p, %p, %ld)\n", hProcess, pv, cb);
+    NTSTATUS status;
 
-    if (pv && cb)
-        ((DWORD *) pv)[0] = 0; /* Empty WorkingSet */
+    TRACE( "(%p, %p, %ld)\n", process, buffer, size );
 
+    status = NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer, size, NULL );
+
+    if (status)
+    {
+        SetLastError( RtlNtStatusToDosError( status ) );
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *           QueryWorkingSetEx (PSAPI.@)
+ */
+BOOL WINAPI QueryWorkingSetEx( HANDLE process, LPVOID buffer, DWORD size )
+{
+    NTSTATUS status;
+
+    TRACE( "(%p, %p, %ld)\n", process, buffer, size );
+
+    status = NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer,  size, NULL );
+
+    if (status)
+    {
+        SetLastError( RtlNtStatusToDosError( status ) );
+        return FALSE;
+    }
     return TRUE;
 }
diff --git a/include/psapi.h b/include/psapi.h
index 0a1ecc5..0c1dbd0 100644
--- a/include/psapi.h
+++ b/include/psapi.h
@@ -46,7 +46,7 @@
   LPVOID FaultingVa;
 } PSAPI_WS_WATCH_INFORMATION, *PPSAPI_WS_WATCH_INFORMATION;
 
-typedef struct _PERFORMACE_INFORMATION {
+typedef struct _PERFORMANCE_INFORMATION {
     DWORD cb;
     SIZE_T CommitTotal;
     SIZE_T CommitLimit;
@@ -61,7 +61,7 @@
     DWORD HandleCount;
     DWORD ProcessCount;
     DWORD ThreadCount;
-} PERFORMACE_INFORMATION, *PPERFORMACE_INFORMATION;
+} PERFORMANCE_INFORMATION, *PPERFORMANCE_INFORMATION;
 
 typedef struct _ENUM_PAGE_FILE_INFORMATION {
     DWORD cb;
@@ -90,6 +90,7 @@
 BOOL  WINAPI GetModuleInformation(HANDLE, HMODULE, LPMODULEINFO, DWORD);
 BOOL  WINAPI EmptyWorkingSet(HANDLE);
 BOOL  WINAPI QueryWorkingSet(HANDLE, PVOID, DWORD);
+BOOL  WINAPI QueryWorkingSetEx(HANDLE, PVOID, DWORD);
 BOOL  WINAPI InitializeProcessForWsWatch(HANDLE);
 BOOL  WINAPI GetWsChanges(HANDLE, PPSAPI_WS_WATCH_INFORMATION, DWORD);
 DWORD WINAPI GetMappedFileNameW(HANDLE, LPVOID, LPWSTR, DWORD);
@@ -103,7 +104,7 @@
 DWORD WINAPI GetDeviceDriverFileNameW(LPVOID, LPWSTR, DWORD);
 #define      GetDeviceDriverFileName WINELIB_NAME_AW(GetDeviceDriverFileName)
 BOOL  WINAPI GetProcessMemoryInfo(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
-BOOL  WINAPI GetPerformanceInfo(PPERFORMACE_INFORMATION, DWORD);
+BOOL  WINAPI GetPerformanceInfo(PPERFORMANCE_INFORMATION, DWORD);
 BOOL  WINAPI EnumPageFilesA(PENUM_PAGE_FILE_CALLBACKA, LPVOID);
 BOOL  WINAPI EnumPageFilesW(PENUM_PAGE_FILE_CALLBACKW, LPVOID);
 #define EnumPageFiles WINELIB_NAME_AW(EnumPageFiles)
diff --git a/include/winternl.h b/include/winternl.h
index 16e18a8..0ce1223 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -617,9 +617,11 @@
     WinStationInformation = 8
 } WINSTATIONINFOCLASS;
 
-typedef enum
-{
-    MemoryBasicInformation = 0
+typedef enum _MEMORY_INFORMATION_CLASS {
+    MemoryBasicInformation,
+    MemoryWorkingSetList,
+    MemorySectionName,
+    MemoryBasicVlmInformation
 } MEMORY_INFORMATION_CLASS;
 
 typedef enum _MUTANT_INFORMATION_CLASS