Author: dchapyshev
Date: Mon Apr 13 15:58:39 2009
New Revision: 40478

URL: http://svn.reactos.org/svn/reactos?rev=40478&view=rev
Log:
- Fully implement GetProcessVersion. +1 passed winetest

Modified:
    trunk/reactos/dll/win32/kernel32/process/proc.c

Modified: trunk/reactos/dll/win32/kernel32/process/proc.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/process/proc.c?rev=40478&r1=40477&r2=40478&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/process/proc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/process/proc.c [iso-8859-1] Mon Apr 13 
15:58:39 2009
@@ -781,30 +781,89 @@
  * @implemented
  */
 DWORD WINAPI
-GetProcessVersion (DWORD ProcessId)
-{
-  DWORD                        Version = 0;
-  PIMAGE_NT_HEADERS    NtHeader = NULL;
-  PVOID                        BaseAddress = NULL;
-
-  /* Caller's */
-  if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
-    {
-      BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
-      NtHeader = RtlImageNtHeader (BaseAddress);
-      if (NULL != NtHeader)
-       {
-         Version =
-           (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
-           (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
-       }
-    }
-  else /* other process */
-    {
-      /* FIXME: open the other process */
-      SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    }
-  return (Version);
+GetProcessVersion(DWORD ProcessId)
+{
+    DWORD Version = 0;
+    PIMAGE_NT_HEADERS NtHeader = NULL;
+    IMAGE_NT_HEADERS NtHeaders;
+    IMAGE_DOS_HEADER DosHeader;
+    PROCESS_BASIC_INFORMATION ProcessBasicInfo;
+    PVOID BaseAddress = NULL;
+    HANDLE ProcessHandle;
+    NTSTATUS Status;
+    SIZE_T Count;
+    PEB Peb;
+
+    _SEH2_TRY
+    {
+        /* Caller's */
+        if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
+        {
+            BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
+            NtHeader = RtlImageNtHeader(BaseAddress);
+
+            Version = (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 
16) |
+                      (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
+        }
+        else /* other process */
+        {
+            ProcessHandle = OpenProcess(PROCESS_VM_READ | 
PROCESS_QUERY_INFORMATION,
+                                        FALSE,
+                                        ProcessId);
+
+            if (!ProcessHandle) return 0;
+
+            Status = NtQueryInformationProcess(ProcessHandle,
+                                               ProcessBasicInformation,
+                                               &ProcessBasicInfo,
+                                               sizeof(ProcessBasicInfo),
+                                               NULL);
+            if (!NT_SUCCESS(Status)) goto Error;
+
+            Status = NtReadVirtualMemory(ProcessHandle,
+                                         ProcessBasicInfo.PebBaseAddress,
+                                         &Peb,
+                                         sizeof(Peb),
+                                         &Count);
+            if (!NT_SUCCESS(Status) || Count != sizeof(Peb)) goto Error;
+
+            memset(&DosHeader, 0, sizeof(DosHeader));
+            Status = NtReadVirtualMemory(ProcessHandle,
+                                         Peb.ImageBaseAddress,
+                                         &DosHeader,
+                                         sizeof(DosHeader),
+                                         &Count);
+
+            if (!NT_SUCCESS(Status) || Count != sizeof(DosHeader)) goto Error;
+            if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) goto Error;
+
+            memset(&NtHeaders, 0, sizeof(NtHeaders));
+            Status = NtReadVirtualMemory(ProcessHandle,
+                                         (char *)Peb.ImageBaseAddress + 
DosHeader.e_lfanew,
+                                         &NtHeaders,
+                                         sizeof(NtHeaders),
+                                         &Count);
+
+            if (!NT_SUCCESS(Status) || Count != sizeof(NtHeaders)) goto Error;
+            if (NtHeaders.Signature != IMAGE_NT_SIGNATURE) goto Error;
+
+            Version = MAKELONG(NtHeaders.OptionalHeader.MinorSubsystemVersion,
+                               NtHeaders.OptionalHeader.MajorSubsystemVersion);
+
+Error:
+            if (!NT_SUCCESS(Status))
+            {
+                SetLastErrorByStatus(Status);
+            }
+        }
+    }
+    _SEH2_FINALLY
+    {
+        if (ProcessHandle) CloseHandle(ProcessHandle);
+    }
+    _SEH2_END;
+
+    return Version;
 }
 
 

Reply via email to