Add windows version registry entries.

diff --git a/programs/winecfg/appdefaults.c b/programs/winecfg/appdefaults.c
index 3231977..1bd68d0 100644
--- a/programs/winecfg/appdefaults.c
+++ b/programs/winecfg/appdefaults.c
@@ -32,10 +32,38 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
 
+static const struct
+{
+    const char *szVersion;
+    const char *szDescription;
+    DWORD       dwMajorVersion;
+    DWORD       dwMinorVersion;
+    DWORD       dwBuildNumber;
+    DWORD       dwPlatformId;
+    const char *szCSDVersion;
+    WORD        wServicePackMajor;
+    WORD        wServicePackMinor;
+    const char *szProductType;
+} win_versions[] =
+{
+    { "win2003", "Windows 2003",   5,  2, 0xECE, VER_PLATFORM_WIN32_NT, "Service Pack 1", 1, 0, "ServerNT"},
+    { "winxp",   "Windows XP",     5,  1, 0xA28, VER_PLATFORM_WIN32_NT, "Service Pack 2", 2, 0, "WinNT"},
+    { "win2k",   "Windows 2000",   5,  0, 0x893, VER_PLATFORM_WIN32_NT, "Service Pack 4", 4, 0, "WinNT"},
+    { "winme",   "Windows ME",     4, 90, 0xBB8, VER_PLATFORM_WIN32_WINDOWS, " ", 0, 0, ""},
+    { "win98",   "Windows 98",     4, 10, 0x8AE, VER_PLATFORM_WIN32_WINDOWS, " A ", 0, 0, ""},
+    { "win95",   "Windows 95",     4,  0, 0x3B6, VER_PLATFORM_WIN32_WINDOWS, "", 0, 0, ""},
+    { "nt40",    "Windows NT 4.0", 4,  0, 0x565, VER_PLATFORM_WIN32_NT, "Service Pack 6a", 6, 0, "WinNT"},
+    { "nt351",   "Windows NT 3.5", 3, 51, 0x421, VER_PLATFORM_WIN32_NT, "Service Pack 2", 0, 0, "WinNT"},
+    { "win31",   "Windows 3.1",    2, 10,     0, VER_PLATFORM_WIN32s, "Win32s 1.3", 0, 0, ""},
+    { "win30",   "Windows 3.0",    3,  0,     0, VER_PLATFORM_WIN32s, "Win32s 1.3", 0, 0, ""},
+    { "win20",   "Windows 2.0",    2,  0,     0, VER_PLATFORM_WIN32s, "Win32s 1.3", 0, 0, ""}
+};
+
+#define NB_VERSIONS (sizeof(win_versions)/sizeof(win_versions[0]))
+
 static void update_comboboxes(HWND dialog)
 {
   int i;
-  const VERSION_DESC *pVer = NULL;
 
   char *winver;
   
@@ -48,17 +76,14 @@
   /* normalize the version strings */
   if (*winver != '\0')
   {
-    if ((pVer = getWinVersions ()))
-    {
-      for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
+      for (i = 0; i < NB_VERSIONS; i++)
       {
-	if (!strcasecmp (pVer->szVersion, winver))
+	if (!strcasecmp (win_versions[i].szVersion, winver))
 	{
 	  SendDlgItemMessage (dialog, IDC_WINVER, CB_SETCURSEL, (WPARAM) (i + 1), 0);
-	  WINE_TRACE("match with %s\n", pVer->szVersion);
+	  WINE_TRACE("match with %s\n", win_versions[i].szVersion);
 	}
       }
-    }
   }
   else /* no explicit setting */
   {
@@ -73,7 +98,6 @@
 init_comboboxes (HWND dialog)
 {
   int i;
-  const VERSION_DESC *ver = NULL;
 
   SendDlgItemMessage(dialog, IDC_WINVER, CB_RESETCONTENT, 0, 0);
 
@@ -87,14 +111,11 @@
       SendDlgItemMessage(dialog, IDC_WINVER, CB_ADDSTRING, 0, (LPARAM) "Automatically detect required version");
   }
 
-  if ((ver = getWinVersions ()))
-  {
-    for (i = 0; *ver->szVersion || *ver->szDescription; i++, ver++)
+    for (i = 0; i < NB_VERSIONS; i++)
     {
       SendDlgItemMessage (dialog, IDC_WINVER, CB_ADDSTRING,
-			  0, (LPARAM) ver->szDescription);
+                          0, (LPARAM) win_versions[i].szDescription);
     }
-  }
 }
 
 static void add_listview_item(HWND listview, const char *text, void *association)
@@ -291,7 +312,6 @@
 static void on_winver_change(HWND dialog)
 {
     int selection = SendDlgItemMessage(dialog, IDC_WINVER, CB_GETCURSEL, 0, 0);
-    const VERSION_DESC *ver = getWinVersions();
 
     if (selection == 0)
     {
@@ -300,8 +320,59 @@
     }
     else
     {
-        WINE_TRACE("setting Version key to value '%s'\n", ver[selection - 1].szVersion);
-        set_reg_key(config_key, keypath(""), "Version", ver[selection - 1].szVersion);
+        WINE_TRACE("setting Version key to value '%s'\n", win_versions[selection - 1].szVersion);
+        set_reg_key(config_key, keypath(""), "Version", win_versions[selection - 1].szVersion);
+    }
+    /* global version only */
+    if (!current_app && selection != 0)
+    {
+        static const char szKey9x[] = "Software\\Microsoft\\Windows\\CurrentVersion";
+        static const char szKeyNT[] = "Software\\Microsoft\\Windows NT\\CurrentVersion";
+        static const char szKeyProdNT[] = "System\\CurrentControlSet\\Control\\ProductOptions";
+        static const char szKeyWindNT[] = "System\\CurrentControlSet\\Control\\Windows";
+        char Buffer[40];
+
+        switch (win_versions[selection-1].dwPlatformId)
+        {
+        case VER_PLATFORM_WIN32_WINDOWS:
+            snprintf(Buffer, sizeof(Buffer), "%ld.%ld.%ld", win_versions[selection-1].dwMajorVersion,
+                     win_versions[selection-1].dwMinorVersion, win_versions[selection-1].dwBuildNumber);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "VersionNumber", Buffer);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "SubVersionNumber", win_versions[selection-1].szCSDVersion);
+
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CSDVersion", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentVersion", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentBuildNumber", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyProdNT, "ProductType", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyWindNT, "CSDVersion", NULL);
+            break;
+
+        case VER_PLATFORM_WIN32_NT:
+            snprintf(Buffer, sizeof(Buffer), "%ld.%ld", win_versions[selection-1].dwMajorVersion,
+                     win_versions[selection-1].dwMinorVersion);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentVersion", Buffer);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CSDVersion", win_versions[selection-1].szCSDVersion);
+            snprintf(Buffer, sizeof(Buffer), "%ld", win_versions[selection-1].dwBuildNumber);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentBuildNumber", Buffer);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyProdNT, "ProductType", win_versions[selection-1].szProductType);
+            set_reg_key_dword(HKEY_LOCAL_MACHINE, szKeyWindNT, "CSDVersion",
+                              MAKEWORD( win_versions[selection-1].wServicePackMinor,
+                                        win_versions[selection-1].wServicePackMajor ));
+
+            set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "VersionNumber", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "SubVersionNumber", NULL);
+            break;
+
+        case VER_PLATFORM_WIN32s:
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CSDVersion", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentVersion", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentBuildNumber", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyProdNT, "ProductType", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKeyWindNT, "CSDVersion", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "VersionNumber", NULL);
+            set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "SubVersionNumber", NULL);
+            break;
+        }
     }
 
     /* enable the apply button  */
diff --git a/programs/winecfg/properties.c b/programs/winecfg/properties.c
index 03cda91..f57a990 100644
--- a/programs/winecfg/properties.c
+++ b/programs/winecfg/properties.c
@@ -24,21 +24,6 @@
 
 #include "properties.h"
 
-static const VERSION_DESC sWinVersions[] = {
-    {"win2003", "Windows 2003"},
-    {"winxp", "Windows XP"},
-    {"win2k", "Windows 2000"},
-    {"winme", "Windows ME"},
-    {"win98", "Windows 98"},
-    {"win95", "Windows 95"},
-    {"nt40", "Windows NT 4.0"},
-    {"nt351", "Windows NT 3.5"},
-    {"win31", "Windows 3.1"},
-    {"win30", "Windows 3.0"},
-    {"win20", "Windows 2.0"},
-    {"", ""}
-};
-
 static const DLL_DESC sDLLType[] = {
     {"oleaut32", DLL_BUILTIN},
     {"ole32", DLL_BUILTIN},
@@ -68,15 +53,6 @@
   {"Disable sound", ""},
   {"", ""}
 };
- 
-
-
-/*****************************************************************************
- */
-const VERSION_DESC* getWinVersions(void)
-{
-    return sWinVersions;
-}
 
 
 /*****************************************************************************
@@ -92,27 +68,3 @@
 {
     return sAudioDrivers;
 }
-
-
-/* Functions to convert from version to description and back */
-char* getVersionFromDescription(VERSION_DESC* pVer, char *desc)
-{
-  for (; *pVer->szVersion; pVer++)
-  {
-    if(!strcasecmp(pVer->szDescription, desc))
-      return pVer->szVersion;
-  }
-
-  return NULL;
-}
-
-char* getDescriptionFromVersion(VERSION_DESC* pVer, char *ver)
-{
-  for (; *pVer->szDescription; pVer++)
-  {
-    if(!strcasecmp(pVer->szVersion, ver))
-      return pVer->szDescription;
-  }
-
-  return NULL;
-}
diff --git a/programs/winecfg/properties.h b/programs/winecfg/properties.h
index 3d52f32..57a1019 100644
--- a/programs/winecfg/properties.h
+++ b/programs/winecfg/properties.h
@@ -37,12 +37,6 @@
 #define MAX_VERSION_LENGTH      48
 #define MAX_DESCRIPTION_LENGTH 128
 
-typedef struct
-{
-    char  szVersion[MAX_VERSION_LENGTH];
-    char  szDescription[MAX_DESCRIPTION_LENGTH];
-} VERSION_DESC;
-
 #define DLL_NATIVE  0x0000
 #define DLL_BUILTIN 0x0001
 
@@ -93,11 +87,7 @@
   int nType;
 } DEV_NODES;
 
-const VERSION_DESC *getWinVersions(void);
-const VERSION_DESC *getDOSVersions(void);
 const DLL_DESC *getDLLDefaults(void);
 const AUDIO_DRIVER *getAudioDrivers(void);
-char* getVersionFromDescription(VERSION_DESC *pVer, char *desc);
-char* getDescriptionFromVersion(VERSION_DESC *pVer, char *ver);
 
 #endif
diff --git a/programs/winecfg/winecfg.c b/programs/winecfg/winecfg.c
index a3051e6..8612619 100644
--- a/programs/winecfg/winecfg.c
+++ b/programs/winecfg/winecfg.c
@@ -139,11 +139,11 @@
  *
  * If valueName or value is NULL, an empty section will be created
  */
-static int set_config_key(HKEY root, const char *subkey, const char *name, const char *value) {
+static int set_config_key(HKEY root, const char *subkey, const char *name, const BYTE *value, DWORD type) {
     DWORD res = 1;
     HKEY key = NULL;
 
-    WINE_TRACE("subkey=%s: name=%s, value=%s\n", subkey, name, value);
+    WINE_TRACE("subkey=%s: name=%s, value=%s, type=%ld\n", subkey, name, value, type);
 
     assert( subkey != NULL );
 
@@ -155,7 +155,11 @@
     else key = root;
     if (name == NULL || value == NULL) goto end;
 
-    res = RegSetValueEx(key, name, 0, REG_SZ, value, strlen(value) + 1);
+    switch (type)
+    {
+        case REG_SZ: res = RegSetValueEx(key, name, 0, REG_SZ, value, strlen(value) + 1); break;
+        case REG_DWORD: res = RegSetValueEx(key, name, 0, REG_DWORD, value, sizeof(DWORD)); break;
+    }
     if (res != ERROR_SUCCESS) goto end;
 
     res = 0;
@@ -213,6 +217,7 @@
     char *path;   /* path in the registry rooted at root  */
     char *name;   /* name of the registry value. if null, this means delete the key  */
     char *value;  /* contents of the registry value. if null, this means delete the value  */
+    DWORD type;   /* type of registry value. REG_SZ or REG_DWORD for now */
 };
 
 struct list *settings;
@@ -281,16 +286,18 @@
  *
  * value is what to set the value to, or NULL to delete it.
  *
+ * type is REG_SZ or REG_DWORD.
+ *
  * These values will be copied when necessary.
  */
-void set_reg_key(HKEY root, const char *path, const char *name, const char *value)
+static void set_reg_key_ex(HKEY root, const char *path, const char *name, const void *value, DWORD type)
 {
     struct list *cursor;
     struct setting *s;
 
     assert( path != NULL );
 
-    WINE_TRACE("path=%s, name=%s, value=%s\n", path, name, value);
+    WINE_TRACE("path=%s, name=%s, value=%p\n", path, name, value);
 
     /* firstly, see if we already set this setting  */
     LIST_FOR_EACH( cursor, settings )
@@ -309,7 +316,17 @@
 
         /* yes, we have already set it, so just replace the content and return  */
         HeapFree(GetProcessHeap(), 0, s->value);
-        s->value = value ? strdupA(value) : NULL;
+        s->type = type;
+        switch (type)
+        {
+            case REG_SZ:
+                s->value = value ? strdupA(value) : NULL;
+                break;
+            case REG_DWORD:
+                s->value = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD));
+                memcpy( s->value, value, sizeof(DWORD) );
+                break;
+        }
 
         /* are we deleting this key? this won't remove any of the
          * children from the overlay so if the user adds it again in
@@ -329,11 +346,31 @@
     s->root  = root;
     s->path  = strdupA(path);
     s->name  = name  ? strdupA(name)  : NULL;
-    s->value = value ? strdupA(value) : NULL;
+    s->type  = type;
+    switch (type)
+    {
+        case REG_SZ:
+            s->value = value ? strdupA(value) : NULL;
+            break;
+        case REG_DWORD:
+            s->value = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD));
+            memcpy( s->value, value, sizeof(DWORD) );
+            break;
+    }
 
     list_add_tail(settings, &s->entry);
 }
 
+void set_reg_key(HKEY root, const char *path, const char *name, const char *value)
+{
+    set_reg_key_ex(root, path, name, value, REG_SZ);
+}
+
+void set_reg_key_dword(HKEY root, const char *path, const char *name, DWORD value)
+{
+    set_reg_key_ex(root, path, name, &value, REG_DWORD);
+}
+
 /**
  * enumerates the value names at the given path, taking into account
  * the changes in the settings list.
@@ -466,7 +503,7 @@
     if (s->value)
     {
 	WINE_TRACE("Setting %s:%s to '%s'\n", s->path, s->name, s->value);
-        set_config_key(s->root, s->path, s->name, s->value);
+        set_config_key(s->root, s->path, s->name, s->value, s->type);
     }
     else
     {
diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h
index f6bf3c7..a8c1957 100644
--- a/programs/winecfg/winecfg.h
+++ b/programs/winecfg/winecfg.h
@@ -52,6 +52,7 @@
  */
 
 void set_reg_key(HKEY root, const char *path, const char *name, const char *value);
+void set_reg_key_dword(HKEY root, const char *path, const char *name, DWORD value);
 char *get_reg_key(HKEY root, const char *path, const char *name, const char *def);
 BOOL reg_key_exists(HKEY root, const char *path, const char *name);
 void apply(void);