ntdll: Fix the various structures returned by NtQuerySystemInformation for 64-bit.
authorAlexandre Julliard <julliard@winehq.org>
Sat, 3 Jan 2009 13:54:11 +0000 (14:54 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Sat, 3 Jan 2009 13:55:32 +0000 (14:55 +0100)
dlls/dbghelp/minidump.c
dlls/kernel32/toolhelp.c
dlls/ntdll/nt.c
dlls/ntdll/process.c
dlls/ntdll/tests/info.c
dlls/psapi/psapi_main.c
include/winternl.h

index cc12415754450b037a2d716688e41a65d300a278..0419bc87b960e0d6e54014d65fcf4d1a86f64e86 100644 (file)
@@ -98,10 +98,9 @@ static BOOL fetch_processes_info(struct dump_context* dc)
         dc->spi = dc->pcs_buffer;
         for (;;)
         {
-            if (dc->spi->dwProcessID == dc->pid) return TRUE;
-            if (!dc->spi->dwOffset) break;
-            dc->spi = (SYSTEM_PROCESS_INFORMATION*)     
-                ((char*)dc->spi + dc->spi->dwOffset);
+            if (HandleToUlong(dc->spi->UniqueProcessId) == dc->pid) return TRUE;
+            if (!dc->spi->NextEntryOffset) break;
+            dc->spi = (SYSTEM_PROCESS_INFORMATION*)((char*)dc->spi + dc->spi->NextEntryOffset);
         }
     }
     HeapFree(GetProcessHeap(), 0, dc->pcs_buffer);
@@ -179,13 +178,13 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
                               const MINIDUMP_EXCEPTION_INFORMATION* except,
                               MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
 {
-    DWORD                       tid = dc->spi->ti[thd_idx].dwThreadID;
+    DWORD                       tid = HandleToUlong(dc->spi->ti[thd_idx].ClientId.UniqueThread);
     HANDLE                      hThread;
     THREAD_BASIC_INFORMATION    tbi;
 
     memset(ctx, 0, sizeof(*ctx));
 
-    mdThd->ThreadId = dc->spi->ti[thd_idx].dwThreadID;
+    mdThd->ThreadId = tid;
     mdThd->SuspendCount = 0;
     mdThd->Teb = 0;
     mdThd->Stack.StartOfMemoryRange = 0;
@@ -198,8 +197,7 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
 
     if ((hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid)) == NULL)
     {
-        FIXME("Couldn't open thread %u (%u)\n",
-              dc->spi->ti[thd_idx].dwThreadID, GetLastError());
+        FIXME("Couldn't open thread %u (%u)\n", tid, GetLastError());
         return FALSE;
     }
     
@@ -713,7 +711,7 @@ static  unsigned        dump_threads(struct dump_context* dc,
             cbin.ProcessId = dc->pid;
             cbin.ProcessHandle = dc->hProcess;
             cbin.CallbackType = ThreadCallback;
-            cbin.u.Thread.ThreadId = dc->spi->ti[i].dwThreadID;
+            cbin.u.Thread.ThreadId = HandleToUlong(dc->spi->ti[i].ClientId.UniqueThread);
             cbin.u.Thread.ThreadHandle = 0; /* FIXME */
             cbin.u.Thread.Context = ctx;
             cbin.u.Thread.SizeOfContext = sizeof(CONTEXT);
index 5cd8d90ca453549ace2cccf39a0da1e9f161ae01..77a0cd7ba9c7ed274064cb98466a0e98f261b2d7 100644 (file)
@@ -202,7 +202,7 @@ static BOOL fetch_process_thread( DWORD flags, SYSTEM_PROCESS_INFORMATION** pspi
                 spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + offset);
                 if (flags & TH32CS_SNAPPROCESS) (*num_pcs)++;
                 if (flags & TH32CS_SNAPTHREAD) *num_thd += spi->dwThreadCount;
-            } while ((offset = spi->dwOffset));
+            } while ((offset = spi->NextEntryOffset));
             return TRUE;
         case STATUS_INFO_LENGTH_MISMATCH:
             *pspi = HeapReAlloc( GetProcessHeap(), 0, *pspi, size *= 2 );
@@ -234,18 +234,18 @@ static void fill_process( struct snapshot* snap, ULONG* offset,
 
         pcs_entry->dwSize = sizeof(PROCESSENTRY32W);
         pcs_entry->cntUsage = 0; /* MSDN says no longer used, always 0 */
-        pcs_entry->th32ProcessID = spi->dwProcessID;
+        pcs_entry->th32ProcessID = HandleToUlong(spi->UniqueProcessId);
         pcs_entry->th32DefaultHeapID = 0; /* MSDN says no longer used, always 0 */
         pcs_entry->th32ModuleID = 0; /* MSDN says no longer used, always 0 */
         pcs_entry->cntThreads = spi->dwThreadCount;
-        pcs_entry->th32ParentProcessID = spi->dwParentProcessID;
+        pcs_entry->th32ParentProcessID = HandleToUlong(spi->ParentProcessId);
         pcs_entry->pcPriClassBase = spi->dwBasePriority;
         pcs_entry->dwFlags = 0; /* MSDN says no longer used, always 0 */
         l = min(spi->ProcessName.Length, sizeof(pcs_entry->szExeFile) - sizeof(WCHAR));
         memcpy(pcs_entry->szExeFile, spi->ProcessName.Buffer, l);
         pcs_entry->szExeFile[l / sizeof(WCHAR)] = '\0';
         pcs_entry++;
-    } while ((poff = spi->dwOffset));
+    } while ((poff = spi->NextEntryOffset));
 
     *offset += num * sizeof(PROCESSENTRY32W);
 }
@@ -274,8 +274,8 @@ static void fill_thread( struct snapshot* snap, ULONG* offset, LPVOID info, ULON
         {
             thd_entry->dwSize = sizeof(THREADENTRY32);
             thd_entry->cntUsage = 0; /* MSDN says no longer used, always 0 */
-            thd_entry->th32ThreadID = sti->dwThreadID;
-            thd_entry->th32OwnerProcessID = sti->dwOwningPID;
+            thd_entry->th32ThreadID = HandleToUlong(sti->ClientId.UniqueThread);
+            thd_entry->th32OwnerProcessID = HandleToUlong(sti->ClientId.UniqueProcess);
             thd_entry->tpBasePri = sti->dwBasePriority;
             thd_entry->tpDeltaPri = 0; /* MSDN says no longer used, always 0 */
             thd_entry->dwFlags = 0; /* MSDN says no longer used, always 0" */
@@ -283,7 +283,7 @@ static void fill_thread( struct snapshot* snap, ULONG* offset, LPVOID info, ULON
             sti++;
             thd_entry++;
       }
-    } while ((poff = spi->dwOffset));
+    } while ((poff = spi->NextEntryOffset));
     *offset += num * sizeof(THREADENTRY32);
 }
 
index c593f45e1992fa90d3cfe7a297355add6ccf9f03..879a324288442b1f0ab4317260cc230c9affa317 100644 (file)
@@ -824,15 +824,15 @@ NTSTATUS WINAPI NtQuerySystemInformation(
  
                             memset(spi, 0, sizeof(*spi));
 
-                            spi->dwOffset = procstructlen - wlen;
+                            spi->NextEntryOffset = procstructlen - wlen;
                             spi->dwThreadCount = reply->threads;
 
                             /* spi->pszProcessName will be set later on */
 
                             spi->dwBasePriority = reply->priority;
-                            spi->dwProcessID = (DWORD)reply->pid;
-                            spi->dwParentProcessID = (DWORD)reply->ppid;
-                            spi->dwHandleCount = reply->handles;
+                            spi->UniqueProcessId = UlongToHandle(reply->pid);
+                            spi->ParentProcessId = UlongToHandle(reply->ppid);
+                            spi->HandleCount = reply->handles;
 
                             /* spi->ti will be set later on */
 
@@ -863,7 +863,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
                             if (!(ret = wine_server_call( req )))
                             {
                                 j++;
-                                if (reply->pid == spi->dwProcessID)
+                                if (UlongToHandle(reply->pid) == spi->UniqueProcessId)
                                 {
                                     /* ftKernelTime, ftUserTime, ftCreateTime;
                                      * dwTickCount, dwStartAddress
@@ -871,8 +871,9 @@ NTSTATUS WINAPI NtQuerySystemInformation(
 
                                     memset(&spi->ti[i], 0, sizeof(spi->ti));
 
-                                    spi->ti[i].dwOwningPID = reply->pid;
-                                    spi->ti[i].dwThreadID  = reply->tid;
+                                    spi->ti[i].CreateTime.QuadPart = 0xdeadbeef;
+                                    spi->ti[i].ClientId.UniqueProcess = UlongToHandle(reply->pid);
+                                    spi->ti[i].ClientId.UniqueThread  = UlongToHandle(reply->tid);
                                     spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
                                     spi->ti[i].dwBasePriority = reply->base_pri;
                                     i++;
@@ -884,17 +885,17 @@ NTSTATUS WINAPI NtQuerySystemInformation(
                     if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
 
                     /* now append process name */
-                    spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->dwOffset);
+                    spi->ProcessName.Buffer = (WCHAR*)((char*)spi + spi->NextEntryOffset);
                     spi->ProcessName.Length = wlen - sizeof(WCHAR);
                     spi->ProcessName.MaximumLength = wlen;
                     memcpy( spi->ProcessName.Buffer, exename, wlen );
-                    spi->dwOffset += wlen;
+                    spi->NextEntryOffset += wlen;
 
                     last = spi;
-                    spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->dwOffset);
+                    spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset);
                 }
             }
-            if (ret == STATUS_SUCCESS && last) last->dwOffset = 0;
+            if (ret == STATUS_SUCCESS && last) last->NextEntryOffset = 0;
             if (hSnap) NtClose(hSnap);
         }
         break;
index be17eef5e3caba0dcd7782c2bc36c441cb81ce88..153ac8ae022d6450d0b46eeb95b54a6974ec4f5f 100644 (file)
@@ -212,7 +212,8 @@ NTSTATUS WINAPI NtQueryInformationProcess(
         {
             VM_COUNTERS pvmi;
 
-            if (ProcessInformationLength >= sizeof(VM_COUNTERS))
+            /* older Windows versions don't have the PrivatePageCount field */
+            if (ProcessInformationLength >= FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
             {
                 if (!ProcessInformation)
                     ret = STATUS_ACCESS_VIOLATION;
@@ -223,12 +224,14 @@ NTSTATUS WINAPI NtQueryInformationProcess(
                     /* FIXME : real data */
                     memset(&pvmi, 0 , sizeof(VM_COUNTERS));
 
-                    memcpy(ProcessInformation, &pvmi, sizeof(VM_COUNTERS));
+                    len = ProcessInformationLength;
+                    if (len != FIELD_OFFSET(VM_COUNTERS,PrivatePageCount)) len = sizeof(VM_COUNTERS);
 
-                    len = sizeof(VM_COUNTERS);
+                    memcpy(ProcessInformation, &pvmi, min(ProcessInformationLength,sizeof(VM_COUNTERS)));
                 }
 
-                if (ProcessInformationLength > sizeof(VM_COUNTERS))
+                if (ProcessInformationLength != FIELD_OFFSET(VM_COUNTERS,PrivatePageCount) &&
+                    ProcessInformationLength != sizeof(VM_COUNTERS))
                     ret = STATUS_INFO_LENGTH_MISMATCH;
             }
             else ret = STATUS_INFO_LENGTH_MISMATCH;
index f61196eed746d2c8d193eb67ba7ab622a1e6999b..b118bd3c0883887d2a1e29e4619397eefae33877 100644 (file)
@@ -227,7 +227,7 @@ static void test_query_process(void)
 
     /* Copy of our winternl.h structure turned into a private one */
     typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE {
-        DWORD dwOffset;
+        ULONG NextEntryOffset;
         DWORD dwThreadCount;
         DWORD dwUnknown1[6];
         FILETIME ftCreationTime;
@@ -235,9 +235,9 @@ static void test_query_process(void)
         FILETIME ftKernelTime;
         UNICODE_STRING ProcessName;
         DWORD dwBasePriority;
-        DWORD dwProcessID;
-        DWORD dwParentProcessID;
-        DWORD dwHandleCount;
+        HANDLE UniqueProcessId;
+        HANDLE ParentProcessId;
+        ULONG HandleCount;
         DWORD dwUnknown3;
         DWORD dwUnknown4;
         VM_COUNTERS vmCounters;
@@ -261,15 +261,15 @@ static void test_query_process(void)
     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
     spi = spi_buf;
 
-    /* Get the first dwOffset, from this we can deduce the OS version we're running
+    /* Get the first NextEntryOffset, from this we can deduce the OS version we're running
      *
      * W2K/WinXP/W2K3:
-     *   dwOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
+     *   NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
      * NT:
-     *   dwOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
+     *   NextEntryOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION)
      * Wine (with every windows version):
-     *   dwOffset for a process is 0 if just this test is running
-     *   dwOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) +
+     *   NextEntryOffset for a process is 0 if just this test is running
+     *   NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) +
      *                             ProcessName.MaximumLength
      *     if more wine processes are running
      *
@@ -278,7 +278,7 @@ static void test_query_process(void)
 
     pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength);
 
-    is_nt = ( spi->dwOffset - (sbi.NumberOfProcessors * sizeof(SYSTEM_THREAD_INFORMATION)) == 136);
+    is_nt = ( spi->NextEntryOffset - (sbi.NumberOfProcessors * sizeof(SYSTEM_THREAD_INFORMATION)) == 136);
 
     if (is_nt) skip("Windows version is NT, we will skip thread tests\n");
 
@@ -294,7 +294,7 @@ static void test_query_process(void)
     {
         i++;
 
-        last_pid = spi->dwProcessID;
+        last_pid = (DWORD_PTR)spi->UniqueProcessId;
 
         ok( spi->dwThreadCount > 0, "Expected some threads for this process, got 0\n");
 
@@ -306,17 +306,17 @@ static void test_query_process(void)
             for ( j = 0; j < spi->dwThreadCount; j++) 
             {
                 k++;
-                ok ( spi->ti[j].dwOwningPID == spi->dwProcessID, 
-                     "The owning pid of the thread (%d) doesn't equal the pid (%d) of the process\n",
-                     spi->ti[j].dwOwningPID, spi->dwProcessID);
+                ok ( spi->ti[j].ClientId.UniqueProcess == spi->UniqueProcessId,
+                     "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n",
+                     spi->ti[j].ClientId.UniqueProcess, spi->UniqueProcessId);
             }
         }
 
-        if (!spi->dwOffset) break;
+        if (!spi->NextEntryOffset) break;
 
         one_before_last_pid = last_pid;
 
-        spi = (SYSTEM_PROCESS_INFORMATION_PRIVATE*)((char*)spi + spi->dwOffset);
+        spi = (SYSTEM_PROCESS_INFORMATION_PRIVATE*)((char*)spi + spi->NextEntryOffset);
     }
     trace("Total number of running processes : %d\n", i);
     if (!is_nt) trace("Total number of running threads   : %d\n", k);
@@ -545,12 +545,12 @@ static void test_query_process_basic(void)
     ULONG ReturnLength;
 
     typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE {
-        DWORD ExitStatus;
-        DWORD PebBaseAddress;
-        DWORD AffinityMask;
-        DWORD BasePriority;
-        ULONG UniqueProcessId;
-        ULONG InheritedFromUniqueProcessId;
+        DWORD_PTR ExitStatus;
+        PPEB      PebBaseAddress;
+        DWORD_PTR AffinityMask;
+        DWORD_PTR BasePriority;
+        ULONG_PTR UniqueProcessId;
+        ULONG_PTR InheritedFromUniqueProcessId;
     } PROCESS_BASIC_INFORMATION_PRIVATE, *PPROCESS_BASIC_INFORMATION_PRIVATE;
 
     PROCESS_BASIC_INFORMATION_PRIVATE pbi;
@@ -604,7 +604,7 @@ static void test_query_process_basic(void)
     ok( sizeof(pbi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
                                                                                                                                                
     /* Check if we have some return values */
-    trace("ProcessID : %d\n", pbi.UniqueProcessId);
+    trace("ProcessID : %lx\n", pbi.UniqueProcessId);
     ok( pbi.UniqueProcessId > 0, "Expected a ProcessID > 0, got 0\n");
 }
 
@@ -613,30 +613,30 @@ static void test_query_process_vm(void)
     NTSTATUS status;
     ULONG ReturnLength;
     VM_COUNTERS pvi;
+    ULONG old_size = FIELD_OFFSET(VM_COUNTERS,PrivatePageCount);
 
     status = pNtQueryInformationProcess(NULL, ProcessVmCounters, NULL, sizeof(pvi), NULL);
     ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
         "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08x\n", status);
 
-    status = pNtQueryInformationProcess(NULL, ProcessVmCounters, &pvi, sizeof(pvi), NULL);
+    status = pNtQueryInformationProcess(NULL, ProcessVmCounters, &pvi, old_size, NULL);
     ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
 
     /* Windows XP and W2K3 will report success for a size of 44 AND 48 !
        Windows W2K will only report success for 44.
-       For now we only care for 44, which is sizeof(VM_COUNTERS)
-       If an app depends on it, we have to implement this in ntdll/process.c
+       For now we only care for 44, which is FIELD_OFFSET(VM_COUNTERS,PrivatePageCount))
     */
 
     status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, 24, &ReturnLength);
     ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
 
-    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, sizeof(pvi), &ReturnLength);
+    status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, old_size, &ReturnLength);
     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
-    ok( sizeof(pvi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
+    ok( old_size == ReturnLength, "Inconsistent length %d\n", ReturnLength);
 
     status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, 46, &ReturnLength);
     ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
-    ok( sizeof(pvi) == ReturnLength, "Inconsistent length %d\n", ReturnLength);
+    ok( ReturnLength == old_size || ReturnLength == sizeof(pvi), "Inconsistent length %d\n", ReturnLength);
 
     /* Check if we have some return values */
     trace("WorkingSetSize : %ld\n", pvi.WorkingSetSize);
index 9fe8281f9d369e96697ce29b3b8cb803ab64242b..7f90a2193e0ffe5c4eebe9e8eb81f06e6016ce22 100644 (file)
@@ -222,13 +222,13 @@ BOOL WINAPI EnumProcesses(DWORD *lpdwProcessIDs, DWORD cb, DWORD *lpcbUsed)
 
     for (*lpcbUsed = 0; cb >= sizeof(DWORD); cb -= sizeof(DWORD))
     {
-        *lpdwProcessIDs++ = spi->dwProcessID;
+        *lpdwProcessIDs++ = HandleToUlong(spi->UniqueProcessId);
         *lpcbUsed += sizeof(DWORD);
 
-        if (spi->dwOffset == 0)
+        if (spi->NextEntryOffset == 0)
             break;
 
-        spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->dwOffset);
+        spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset);
     }
 
     HeapFree(GetProcessHeap(), 0, pBuf);
index 4704e1c1cdfd7ae12c3910b14b28afa936c68b34..60ca82126e6e660067df0cd861ad42c5a57b98d4 100644 (file)
@@ -1000,20 +1000,20 @@ PVOID WINAPI RtlVirtualUnwind(ULONG,ULONG64,ULONG64,RUNTIME_FUNCTION*,CONTEXT*,P
  */
 
 /* This is used by NtQuerySystemInformation */
-typedef struct _SYSTEM_THREAD_INFORMATION{
-    FILETIME    ftKernelTime;
-    FILETIME    ftUserTime;
-    FILETIME    ftCreateTime;
-    DWORD       dwTickCount;
-    DWORD       dwStartAddress;
-    DWORD       dwOwningPID;
-    DWORD       dwThreadID;
-    DWORD       dwCurrentPriority;
-    DWORD       dwBasePriority;
-    DWORD       dwContextSwitches;
-    DWORD       dwThreadState;
-    DWORD       dwWaitReason;
-    DWORD       dwUnknown;
+typedef struct _SYSTEM_THREAD_INFORMATION
+{                                    /* win32/win64 */
+    LARGE_INTEGER KernelTime;          /* 00/00 */
+    LARGE_INTEGER UserTime;            /* 08/08 */
+    LARGE_INTEGER CreateTime;          /* 10/10 */
+    DWORD         dwTickCount;         /* 18/18 */
+    LPVOID        StartAddress;        /* 1c/20 */
+    CLIENT_ID     ClientId;            /* 20/28 */
+    DWORD         dwCurrentPriority;   /* 28/38 */
+    DWORD         dwBasePriority;      /* 2c/3c */
+    DWORD         dwContextSwitches;   /* 30/40 */
+    DWORD         dwThreadState;       /* 34/44 */
+    DWORD         dwWaitReason;        /* 38/48 */
+    DWORD         dwUnknown;           /* 3c/4c */
 } SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
 
 typedef struct _IO_STATUS_BLOCK {
@@ -1353,38 +1353,39 @@ typedef struct _VM_COUNTERS_ {
     SIZE_T QuotaNonPagedPoolUsage;
     SIZE_T PagefileUsage;
     SIZE_T PeakPagefileUsage;
+    SIZE_T PrivatePageCount;
 } VM_COUNTERS, *PVM_COUNTERS;
 
 typedef struct _SYSTEM_PROCESS_INFORMATION {
-#ifdef __WINESRC__
-    DWORD dwOffset;
-    DWORD dwThreadCount;
-    DWORD dwUnknown1[6];
-    FILETIME ftCreationTime;
-    FILETIME ftUserTime;
-    FILETIME ftKernelTime;
-    UNICODE_STRING ProcessName;
-    DWORD dwBasePriority;
-    DWORD dwProcessID;
-    DWORD dwParentProcessID;
-    DWORD dwHandleCount;
-    DWORD dwUnknown3;
-    DWORD dwUnknown4;
-    VM_COUNTERS vmCounters;
-    IO_COUNTERS ioCounters;
-    SYSTEM_THREAD_INFORMATION ti[1];
+#ifdef __WINESRC__                  /* win32/win64 */
+    ULONG NextEntryOffset;             /* 00/00 */
+    DWORD dwThreadCount;               /* 04/04 */
+    DWORD dwUnknown1[6];               /* 08/08 */
+    LARGE_INTEGER CreationTime;        /* 20/20 */
+    LARGE_INTEGER UserTime;            /* 28/28 */
+    LARGE_INTEGER KernelTime;          /* 30/30 */
+    UNICODE_STRING ProcessName;        /* 38/38 */
+    DWORD dwBasePriority;              /* 40/48 */
+    HANDLE UniqueProcessId;            /* 44/50 */
+    HANDLE ParentProcessId;            /* 48/58 */
+    ULONG HandleCount;                 /* 4c/60 */
+    DWORD dwUnknown3;                  /* 50/64 */
+    DWORD dwUnknown4;                  /* 54/68 */
+    VM_COUNTERS vmCounters;            /* 58/70 */
+    IO_COUNTERS ioCounters;            /* 88/d0 */
+    SYSTEM_THREAD_INFORMATION ti[1];   /* b8/100 */
 #else
-    ULONG NextEntryOffset;
-    BYTE Reserved1[52];
-    PVOID Reserved2[3];
-    HANDLE UniqueProcessId;
-    PVOID Reserved3;
-    ULONG HandleCount;
-    BYTE Reserved4[4];
-    PVOID Reserved5[11];
-    SIZE_T PeakPagefileUsage;
-    SIZE_T PrivatePageCount;
-    LARGE_INTEGER Reserved6[6];
+    ULONG NextEntryOffset;             /* 00/00 */
+    BYTE Reserved1[52];                /* 04/04 */
+    PVOID Reserved2[3];                /* 38/38 */
+    HANDLE UniqueProcessId;            /* 44/50 */
+    PVOID Reserved3;                   /* 48/58 */
+    ULONG HandleCount;                 /* 4c/60 */
+    BYTE Reserved4[4];                 /* 50/64 */
+    PVOID Reserved5[11];               /* 54/68 */
+    SIZE_T PeakPagefileUsage;          /* 80/c0 */
+    SIZE_T PrivatePageCount;           /* 84/c8 */
+    LARGE_INTEGER Reserved6[6];        /* 88/d0 */
 #endif
 } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
 
@@ -1936,16 +1937,16 @@ typedef struct _LDR_MODULE
 
 typedef struct _SYSTEM_MODULE
 {
-    ULONG               Reserved1;
-    ULONG               Reserved2;
-    PVOID               ImageBaseAddress;
-    ULONG               ImageSize;
-    ULONG               Flags;
-    WORD                Id;
-    WORD                Rank;
-    WORD                Unknown;
-    WORD                NameOffset;
-    BYTE                Name[MAXIMUM_FILENAME_LENGTH];
+    PVOID               Reserved1;                      /* 00/00 */
+    PVOID               Reserved2;                      /* 04/08 */
+    PVOID               ImageBaseAddress;               /* 08/10 */
+    ULONG               ImageSize;                      /* 0c/18 */
+    ULONG               Flags;                          /* 10/1c */
+    WORD                Id;                             /* 14/20 */
+    WORD                Rank;                           /* 16/22 */
+    WORD                Unknown;                        /* 18/24 */
+    WORD                NameOffset;                     /* 1a/26 */
+    BYTE                Name[MAXIMUM_FILENAME_LENGTH];  /* 1c/28 */
 } SYSTEM_MODULE, *PSYSTEM_MODULE;
 
 typedef struct _SYSTEM_MODULE_INFORMATION