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/... ============================================================================== --- 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; }