1. made the PEB structure match xp's layout
2. fixed GetVersionEx()
Modified: trunk/reactos/include/napi/teb.h
Modified: trunk/reactos/lib/kernel32/misc/env.c
Modified: trunk/reactos/lib/ntdll/ldr/startup.c
Modified: trunk/reactos/ntoskrnl/ps/process.c

Modified: trunk/reactos/include/napi/teb.h
--- trunk/reactos/include/napi/teb.h	2005-02-18 22:46:49 UTC (rev 13638)
+++ trunk/reactos/include/napi/teb.h	2005-02-19 03:38:43 UTC (rev 13639)
@@ -105,8 +105,8 @@
    UCHAR InheritedAddressSpace;                     /* 00h */
    UCHAR ReadImageFileExecOptions;                  /* 01h */
    UCHAR BeingDebugged;                             /* 02h */
-   UCHAR Spare;                                     /* 03h */
-   PVOID Mutant;                                    /* 04h */
+   BOOLEAN SpareBool;                               /* 03h */
+   HANDLE Mutant;                                   /* 04h */
    PVOID ImageBaseAddress;                          /* 08h */
    PPEB_LDR_DATA Ldr;                               /* 0Ch */
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;  /* 10h */
@@ -131,7 +131,6 @@
    PVOID UnicodeCaseTableData;                      /* 60h */
    ULONG NumberOfProcessors;                        /* 64h */
    ULONG NtGlobalFlag;                              /* 68h */
-   UCHAR Spare2[0x4];                               /* 6Ch */
    LARGE_INTEGER CriticalSectionTimeout;            /* 70h */
    ULONG HeapSegmentReserve;                        /* 78h */
    ULONG HeapSegmentCommit;                         /* 7Ch */
@@ -139,7 +138,7 @@
    ULONG HeapDeCommitFreeBlockThreshold;            /* 84h */
    ULONG NumberOfHeaps;                             /* 88h */
    ULONG MaximumNumberOfHeaps;                      /* 8Ch */
-   PVOID** ProcessHeaps;                            /* 90h */
+   PVOID* ProcessHeaps;                             /* 90h */
    PVOID GdiSharedHandleTable;                      /* 94h */
    PVOID ProcessStarterHelper;                      /* 98h */
    PVOID GdiDCAttributeList;                        /* 9Ch */
@@ -147,13 +146,19 @@
    ULONG OSMajorVersion;                            /* A4h */
    ULONG OSMinorVersion;                            /* A8h */
    USHORT OSBuildNumber;                            /* ACh */
-   UCHAR SPMajorVersion;                            /* AEh */
-   UCHAR SPMinorVersion;                            /* AFh */
+   USHORT OSCSDVersion;                             /* AEh */
    ULONG OSPlatformId;                              /* B0h */
    ULONG ImageSubSystem;                            /* B4h */
    ULONG ImageSubSystemMajorVersion;                /* B8h */
-   ULONG ImageSubSystemMinorVersion;                /* C0h */
+   ULONG ImageSubSystemMinorVersion;                /* BCh */
+   ULONG ImageProcessAffinityMask;                  /* C0h */
    ULONG GdiHandleBuffer[0x22];                     /* C4h */
+   PVOID PostProcessInitRoutine;                    /* 14Ch */
+   PVOID *TlsExpansionBitmap;                       /* 150h */
+   ULONG TlsExpansionBitmapBits[0x20];              /* 154h */
+   ULONG SessionId;                                 /* 1D4h */
+   PVOID AppCompatInfo;                             /* 1D8h */
+   UNICODE_STRING CSDVersion;                       /* 1DCh */
 } PEB;
 
 #ifndef __USE_W32API

Modified: trunk/reactos/lib/kernel32/misc/env.c
--- trunk/reactos/lib/kernel32/misc/env.c	2005-02-18 22:46:49 UTC (rev 13638)
+++ trunk/reactos/lib/kernel32/misc/env.c	2005-02-19 03:38:43 UTC (rev 13639)
@@ -226,21 +226,21 @@
 STDCALL
 GetVersion(VOID)
 {
- PPEB pPeb = NtCurrentPeb();
- DWORD nVersion;
+  PPEB pPeb = NtCurrentPeb();
+  DWORD nVersion;
 
- nVersion = MAKEWORD(pPeb->OSMajorVersion, pPeb->OSMinorVersion);
+  nVersion = MAKEWORD(pPeb->OSMajorVersion, pPeb->OSMinorVersion);
 
- /* behave consistently when posing as another operating system */
- /* build number */
- if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_WINDOWS)
-  nVersion |= ((DWORD)(pPeb->OSBuildNumber)) << 16;
+  /* behave consistently when posing as another operating system */
+  /* build number */
+  if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_WINDOWS)
+    nVersion |= ((DWORD)(pPeb->OSBuildNumber)) << 16;
  
- /* non-NT platform flag */
- if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_NT)
-  nVersion |= 0x80000000;
+  /* non-NT platform flag */
+  if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_NT)
+    nVersion |= 0x80000000;
 
- return nVersion;
+  return nVersion;
 }
 
 
@@ -253,67 +253,44 @@
     LPOSVERSIONINFOW lpVersionInformation
     )
 {
- PPEB pPeb = NtCurrentPeb();
- WCHAR *RosVersion;
-
- /* TODO: move this into RtlGetVersion */
- switch(lpVersionInformation->dwOSVersionInfoSize)
- {
-  case sizeof(OSVERSIONINFOEXW):
+  NTSTATUS Status;
+  
+  if(lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOW) &&
+     lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW))
   {
-   LPOSVERSIONINFOEXW lpVersionInformationEx =
-    (LPOSVERSIONINFOEXW)lpVersionInformation;
-
-   lpVersionInformationEx->wServicePackMajor = pPeb->SPMajorVersion;
-   lpVersionInformationEx->wServicePackMinor = pPeb->SPMinorVersion;
-   /* TODO: read from the KUSER_SHARED_DATA */
-   lpVersionInformationEx->wSuiteMask = 0;
-   /* TODO: call RtlGetNtProductType */
-   lpVersionInformationEx->wProductType = 0;
-   /* ??? */
-   lpVersionInformationEx->wReserved = 0;
-   /* fall through */
+    /* for some reason win sets ERROR_INSUFFICIENT_BUFFER even if it is large
+       enough but doesn't match the exact sizes supported, ERROR_INVALID_PARAMETER
+       would've been much more appropriate... */
+    SetLastError(ERROR_INSUFFICIENT_BUFFER);
+    return FALSE;
   }
 
-  case sizeof(OSVERSIONINFOW):
+  Status = RtlGetVersion((PRTL_OSVERSIONINFOW)lpVersionInformation);
+  if(NT_SUCCESS(Status))
   {
-   lpVersionInformation->dwMajorVersion = pPeb->OSMajorVersion;
-   lpVersionInformation->dwMinorVersion = pPeb->OSMinorVersion;
-   lpVersionInformation->dwBuildNumber = pPeb->OSBuildNumber;
-   lpVersionInformation->dwPlatformId = pPeb->OSPlatformId;
+    int ln, maxlen;
+    
+    /* append a reactos specific string to the szCSDVersion string */
 
-   /* First the Windows compatible string */
-   _snwprintf(lpVersionInformation->szCSDVersion,
-              sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR),
-              L"Service Pack %u", pPeb->SPMajorVersion);
-   /* Add the Reactos-specific string */
-   RosVersion = lpVersionInformation->szCSDVersion + wcslen(lpVersionInformation->szCSDVersion) + 1;
-   wcsncpy
-   (
-    RosVersion,
-    L"ReactOS " KERNEL_VERSION_STR L" (Build " KERNEL_VERSION_BUILD_STR L")",
-    sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR) -
-    ((RosVersion - lpVersionInformation->szCSDVersion) + 1)
-   );
+    /* FIXME - we shouldn't do this when there is a (ros-specific) compatibility
+               flag set so we don't screw applications that might depend on a
+               certain string */
 
-   /* null-terminate, just in case */
-   lpVersionInformation->szCSDVersion
-   [
-    sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR) - 1
-   ] = 0;
-
-   break;
+    ln = wcslen(lpVersionInformation->szCSDVersion);
+    maxlen = (sizeof(lpVersionInformation->szCSDVersion) / sizeof(lpVersionInformation->szCSDVersion[0]) - 1);
+    if(maxlen > ln)
+    {
+      PWCHAR szVer = lpVersionInformation->szCSDVersion + ln;
+      RtlZeroMemory(szVer, (maxlen - ln + 1) * sizeof(WCHAR));
+      wcsncpy(szVer,
+              L" ReactOS " KERNEL_VERSION_STR L" (Build " KERNEL_VERSION_BUILD_STR L")",
+              maxlen - ln);
+    }
+    
+    return TRUE;
   }
 
-  default:
-  {
-   /* unknown version information revision */
-   SetLastError(ERROR_INSUFFICIENT_BUFFER);
-   return FALSE;
-  }
- }
- 
- return TRUE;
+  return FALSE;
 }
 
 
@@ -326,111 +303,61 @@
     LPOSVERSIONINFOA lpVersionInformation
     )
 {
- NTSTATUS nErrCode;
- OSVERSIONINFOEXW oviVerInfo;
- LPOSVERSIONINFOEXA lpVersionInformationEx;
+  OSVERSIONINFOEXW viw;
+  
+  RtlZeroMemory(&viw, sizeof(viw));
+  
+  switch(lpVersionInformation->dwOSVersionInfoSize)
+  {
+    case sizeof(OSVERSIONINFOA):
+      viw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+      break;
 
- /* UNICODE_STRING descriptor of the Unicode version string */
- UNICODE_STRING wstrVerStr =
- {
-  /*
-   gives extra work to RtlUnicodeStringToAnsiString, but spares us an
-   RtlInitUnicodeString round
-  */
-  0,
-  sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion),
-  oviVerInfo.szCSDVersion
- };
+    case sizeof(OSVERSIONINFOEXA):
+      viw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
+      break;
 
- /* ANSI_STRING descriptor of the ANSI version string buffer */
- ANSI_STRING strVerStr =
- {
-  0,
-  sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion),
-  lpVersionInformation->szCSDVersion
- };
-
- switch(lpVersionInformation->dwOSVersionInfoSize)
- {
-  case sizeof(OSVERSIONINFOEXA):
-  {
-   oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
-   break;
+    default:
+      /* for some reason win sets ERROR_INSUFFICIENT_BUFFER even if it is large
+         enough but doesn't match the exact sizes supported, ERROR_INVALID_PARAMETER
+         would've been much more appropriate... */
+      SetLastError(ERROR_INSUFFICIENT_BUFFER);
+      return FALSE;
   }
-
-  case sizeof(OSVERSIONINFOA):
+  
+  if(GetVersionExW((LPOSVERSIONINFOW)&viw))
   {
-   oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
-   break;
+    ANSI_STRING CSDVersionA;
+    UNICODE_STRING CSDVersionW;
+    
+    /* copy back fields that match both supported structures */
+    lpVersionInformation->dwMajorVersion = viw.dwMajorVersion;
+    lpVersionInformation->dwMinorVersion = viw.dwMinorVersion;
+    lpVersionInformation->dwBuildNumber = viw.dwBuildNumber;
+    lpVersionInformation->dwPlatformId = viw.dwPlatformId;
+    
+    RtlInitUnicodeString(&CSDVersionW, viw.szCSDVersion);
+    
+    CSDVersionA.Length = 0;
+    CSDVersionA.MaximumLength = sizeof(lpVersionInformation->szCSDVersion);
+    CSDVersionA.Buffer = lpVersionInformation->szCSDVersion;
+    
+    RtlUnicodeStringToAnsiString(&CSDVersionA, &CSDVersionW, FALSE);
+    
+    /* copy back the extended fields */
+    if(viw.dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW))
+    {
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wServicePackMajor = viw.wServicePackMajor;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wServicePackMinor = viw.wServicePackMinor;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wSuiteMask = viw.wSuiteMask;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wProductType = viw.wProductType;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wReserved = viw.wReserved;
+    }
+    
+    return TRUE;
   }
-
-  default:
-  {
-   /* unknown version information revision */
-   SetLastError(ERROR_INSUFFICIENT_BUFFER);
-   return FALSE;
-  }
- }
-
- if(!GetVersionExW((LPOSVERSIONINFOW)&oviVerInfo))
+  
   return FALSE;
-
- /* null-terminate, just in case */
- oviVerInfo.szCSDVersion
- [
-  sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) /
-  sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) -
-  1
- ] = 0;
- wstrVerStr.Length = wcslen(wstrVerStr.Buffer) * sizeof(WCHAR);
-
- /* convert the win version string */
- nErrCode = RtlUnicodeStringToAnsiString(&strVerStr, &wstrVerStr, FALSE);
- 
- if(!NT_SUCCESS(nErrCode))
- {
-  /* failure */
-  SetLastErrorByStatus(nErrCode);
-  return FALSE;
- }
-
- wstrVerStr.Buffer = oviVerInfo.szCSDVersion + wstrVerStr.Length / sizeof(WCHAR) + 1;
- wstrVerStr.MaximumLength = sizeof(oviVerInfo.szCSDVersion) - (wstrVerStr.Length + sizeof(WCHAR));
- wstrVerStr.Length = wcslen(wstrVerStr.Buffer) * sizeof(WCHAR);
- strVerStr.Buffer = lpVersionInformation->szCSDVersion + strVerStr.Length + 1;
- strVerStr.MaximumLength = sizeof(lpVersionInformation->szCSDVersion) - (strVerStr.Length + 1);
- strVerStr.Length = 0;
-
- /* convert the ReactOS version string */
- nErrCode = RtlUnicodeStringToAnsiString(&strVerStr, &wstrVerStr, FALSE);
- 
- if(!NT_SUCCESS(nErrCode))
- {
-  /* failure */
-  SetLastErrorByStatus(nErrCode);
-  return FALSE;
- }
-
- /* copy the fields */
- lpVersionInformation->dwMajorVersion = oviVerInfo.dwMajorVersion;
- lpVersionInformation->dwMinorVersion = oviVerInfo.dwMinorVersion;
- lpVersionInformation->dwBuildNumber = oviVerInfo.dwBuildNumber;
- lpVersionInformation->dwPlatformId = oviVerInfo.dwPlatformId;
- 
- if(lpVersionInformation->dwOSVersionInfoSize < sizeof(OSVERSIONINFOEXA))
-  /* success */
-  return TRUE;
-
- /* copy the extended fields */
- lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
- lpVersionInformationEx->wServicePackMajor = oviVerInfo.wServicePackMajor;
- lpVersionInformationEx->wServicePackMinor = oviVerInfo.wServicePackMinor;
- lpVersionInformationEx->wSuiteMask = oviVerInfo.wSuiteMask;
- lpVersionInformationEx->wProductType = oviVerInfo.wProductType;
- lpVersionInformationEx->wReserved = oviVerInfo.wReserved;
-
- /* success */
- return TRUE;
 }
 
 

Modified: trunk/reactos/lib/ntdll/ldr/startup.c
--- trunk/reactos/lib/ntdll/ldr/startup.c	2005-02-18 22:46:49 UTC (rev 13638)
+++ trunk/reactos/lib/ntdll/ldr/startup.c	2005-02-19 03:38:43 UTC (rev 13639)
@@ -207,10 +207,9 @@
 		Peb->OSPlatformId = (ULONG)PlatformId;
 
 		/* optional service pack version numbers */
-		if(ReadCompatibilitySetting(SubKeyHandle, L"SPMajorVersion", ValueInfo, &SPMajorVersion))
-			Peb->SPMajorVersion = (UCHAR)SPMajorVersion;
-		if(ReadCompatibilitySetting(SubKeyHandle, L"SPMinorVersion", ValueInfo, &SPMinorVersion))
-			Peb->SPMinorVersion = (UCHAR)SPMinorVersion;
+		if(ReadCompatibilitySetting(SubKeyHandle, L"SPMajorVersion", ValueInfo, &SPMajorVersion) &&
+		   ReadCompatibilitySetting(SubKeyHandle, L"SPMinorVersion", ValueInfo, &SPMinorVersion))
+			Peb->OSCSDVersion = ((SPMajorVersion & 0xFF) << 8) | (SPMinorVersion & 0xFF);
 
 finish:
 		/* we're finished */

Modified: trunk/reactos/ntoskrnl/ps/process.c
--- trunk/reactos/ntoskrnl/ps/process.c	2005-02-18 22:46:49 UTC (rev 13638)
+++ trunk/reactos/ntoskrnl/ps/process.c	2005-02-19 03:38:43 UTC (rev 13639)
@@ -569,7 +569,7 @@
   Peb->OSMinorVersion = 0;
   Peb->OSBuildNumber = 1381;
   Peb->OSPlatformId = 2; //VER_PLATFORM_WIN32_NT;
-  Peb->SPMajorVersion = 6;
+  Peb->OSCSDVersion = 6 << 8;
 
   Peb->AnsiCodePageData     = (char*)TableBase + NlsAnsiTableOffset;
   Peb->OemCodePageData      = (char*)TableBase + NlsOemTableOffset;