The drive definitions have been moved out of the ~/.wine/config file and into 
the filesystem and registry.  The volume management functions modify drives 
are now supported(thanks Eric and Alexandre).  Having winecfg use these 
functions makes the drive dialog useable for editing drive mappings, 
something we need before we can turn winecfg loose on end users.  Feel free 
to try this patch out and report how it works.

* programs/winecfg/winecfg.c, winecfg.h, resource.h, En.rc, Makefile.in, 
drive.c
Chris Morgan <[EMAIL PROTECTED]>
Implemented an array of 26 drives and interface functions for adding, copying, 
moving and deleting drives. Added a "Show/Hide Advanced" button in the drive 
edit dialog that toggles the display of advanced options and resizes/moves 
controls.  Disable the 'autodetect' radio button in the drive edit dialog 
until we have autodetection support. Map window 'x' button to dialog close.

Added PRINTERROR() to call GetLastError(), translate into a plaintext message 
and print via WINE_TRACE().

Comments, questions?

Thanks,
Chris





Index: programs/winecfg/winecfg.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/winecfg.c,v
retrieving revision 1.19
diff -u -r1.19 winecfg.c
--- programs/winecfg/winecfg.c	1 Apr 2004 21:06:14 -0000	1.19
+++ programs/winecfg/winecfg.c	1 May 2004 03:54:21 -0000
@@ -293,3 +293,13 @@
     if (GetWindowText(item, result, len) == 0) return NULL;
     return result;
 }
+
+void PRINTERROR(void)
+{
+        LPSTR msg;
+
+        FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+                       0, GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
+                       (LPSTR)&msg, 0, NULL);
+        WINE_TRACE("error: '%s'\n", msg);
+}
Index: programs/winecfg/winecfg.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/winecfg.h,v
retrieving revision 1.14
diff -u -r1.14 winecfg.h
--- programs/winecfg/winecfg.h	7 Feb 2004 01:01:34 -0000	1.14
+++ programs/winecfg/winecfg.h	1 May 2004 03:54:21 -0000
@@ -118,6 +118,7 @@
 char *getDialogItemText(HWND hDlg, WORD controlID);
 #define disable(id) EnableWindow(GetDlgItem(dialog, id), 0);
 #define enable(id) EnableWindow(GetDlgItem(dialog, id), 1);
+void PRINTERROR(void); /* WINE_TRACE() the plaintext error message from GetLastError() */
 
 #define WINE_KEY_ROOT "Software\\Wine\\Wine\\Config"
 
Index: programs/winecfg/drive.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/drive.c,v
retrieving revision 1.12
diff -u -r1.12 drive.c
--- programs/winecfg/drive.c	12 Mar 2004 19:44:04 -0000	1.12
+++ programs/winecfg/drive.c	1 May 2004 03:54:24 -0000
@@ -3,6 +3,7 @@
  *
  * Copyright 2003 Mark Westcott
  * Copyright 2003 Mike Hearn
+ * Copyright 2004 Chris Morgan
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,6 +21,9 @@
  *
  */
 
+/* TODO: */
+/* - Support for devices(not sure what this means) */
+
 #include <assert.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -39,91 +43,120 @@
 #include "winecfg.h"
 #include "resource.h"
 
+
 WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
 
+typedef struct drive_entry_s
+{
+    char letter;
+    char *unixpath;
+    char *label;
+    char *serial;
+    uint type;
+
+    BOOL in_use;
+} drive_entry_t;
+
 static BOOL updatingUI = FALSE;
-static char editWindowLetter; /* drive letter of the drive we are currently editing */
+static drive_entry_t* editDriveEntry;
 static int lastSel = 0; /* the last drive selected in the property sheet */
+drive_entry_t drives[26]; /* one for each drive letter */
 
+int getDrive(char letter)
+{
+    return (toupper(letter) - 'A');
+}
 
-/* returns NULL on failure. caller is responsible for freeing result */
-char *getDriveValue(char letter, const char *valueName) {
-  HKEY hkDrive = 0;
-  char *subKeyName;
-  char *result = NULL;
-  HRESULT hr;
-  DWORD bufferSize;
-  
-  WINE_TRACE("letter=%c, valueName=%s\n", letter, valueName);
-
-  subKeyName = malloc(strlen("Drive X")+1);
-  sprintf(subKeyName, "Drive %c", letter);
-
-  hr = RegOpenKeyEx(configKey, subKeyName, 0, KEY_READ, &hkDrive);
-  if (hr != ERROR_SUCCESS) goto end;
-
-  hr = RegQueryValueEx(hkDrive, valueName, NULL, NULL, NULL, &bufferSize);
-  if (hr != ERROR_SUCCESS) goto end;
-
-  result = malloc(bufferSize);
-  hr = RegQueryValueEx(hkDrive, valueName, NULL, NULL, result, &bufferSize);
-  if (hr != ERROR_SUCCESS) goto end;
-  
-end:
-  if (hkDrive) RegCloseKey(hkDrive);
-  free(subKeyName);
-  return result;
+BOOL addDrive(char letter, char *targetpath, char *label, char *serial, uint type)
+{
+    if(drives[getDrive(letter)].in_use)
+        return FALSE;
+
+    WINE_TRACE("letter == '%c', unixpath == '%s', label == '%s', serial == '%s', type == %d\n",
+               letter, targetpath, label, serial, type);
+
+    drives[getDrive(letter)].letter = toupper(letter);
+    drives[getDrive(letter)].unixpath = strdup(targetpath);
+    drives[getDrive(letter)].label = strdup(label);
+    drives[getDrive(letter)].serial = strdup(serial);
+    drives[getDrive(letter)].type = type;
+    drives[getDrive(letter)].in_use = TRUE;
+
+    return TRUE;
 }
 
-/* call with newValue == NULL to remove a value */
-void setDriveValue(char letter, const char *valueName, const char *newValue) {
-  char *driveSection = malloc(strlen("Drive X")+1);
-  sprintf(driveSection, "Drive %c", letter);
-  if (newValue)
-    addTransaction(driveSection, valueName, ACTION_SET, newValue);
-  else
-    addTransaction(driveSection, valueName, ACTION_REMOVE, NULL);
-  free(driveSection);
+/* frees up the memory associated with a drive and returns the */
+/* pNext of the given drive entry */
+void freeDrive(drive_entry_t *pDrive)
+{
+    free(pDrive->unixpath);
+    free(pDrive->label);
+    free(pDrive->serial);
+
+    pDrive->in_use = FALSE;
 }
 
-/* copies a drive configuration branch */
-void copyDrive(char srcLetter, char destLetter) {
-  char driveSection[sizeof("Drive X") + 1];
-  char *path, *label, *type, *serial;
-  
-  WINE_TRACE("srcLetter=%c, destLetter=%c\n", srcLetter, destLetter);
-
-  sprintf(driveSection, "Drive %c", srcLetter);
-  path = getDriveValue(srcLetter, "Path");
-  label = getDriveValue(srcLetter, "Label");
-  type = getDriveValue(srcLetter, "Type");
-  serial = getDriveValue(srcLetter, "Serial");
-  
-  sprintf(driveSection, "Drive %c", destLetter);
-  if (path)   addTransaction(driveSection, "Path", ACTION_SET, path);
-  if (label)  addTransaction(driveSection, "Label", ACTION_SET, label);
-  if (type)   addTransaction(driveSection, "Type", ACTION_SET, type);
-  if (serial) addTransaction(driveSection, "Serial", ACTION_SET, serial);
-
-  if (path)   free(path);
-  if (label)  free(label);
-  if (type)   free(type);
-  if (serial) free(serial);
-}
-
-void removeDrive(char letter) {
-  char driveSection[sizeof("Drive X") + 1];
-  sprintf(driveSection, "Drive %c", letter);
-  addTransaction(driveSection, NULL, ACTION_REMOVE, NULL);
+void setDriveLabel(drive_entry_t *pDrive, char *label)
+{
+    WINE_TRACE("pDrive->letter '%c', label = '%s'\n", pDrive->letter, label);
+    free(pDrive->label);
+    pDrive->label = strdup(label);
+}
+
+void setDriveSerial(drive_entry_t *pDrive, char *serial)
+{
+    WINE_TRACE("pDrive->letter '%c', serial = '%s'\n", pDrive->letter, serial);
+    free(pDrive->serial);
+    pDrive->serial = strdup(serial);
+}
+
+void setDrivePath(drive_entry_t *pDrive, char *path)
+{
+    WINE_TRACE("pDrive->letter '%c', path = '%s'\n", pDrive->letter, path);
+    free(pDrive->unixpath);
+    pDrive->unixpath = strdup(path);
+}
+
+BOOL copyDrive(drive_entry_t *pSrc, drive_entry_t *pDst)
+{
+    if(pDst->in_use)
+    {
+        WINE_TRACE("pDst already in use\n");
+        return FALSE;
+    }
+
+    if(!pSrc->unixpath) WINE_TRACE("!pSrc->unixpath\n");
+    if(!pSrc->label) WINE_TRACE("!pSrc->label\n");
+    if(!pSrc->serial) WINE_TRACE("!pSrc->serial\n");
+
+    pDst->unixpath = strdup(pSrc->unixpath);
+    pDst->label = strdup(pSrc->label);
+    pDst->serial = strdup(pSrc->serial);
+    pDst->type = pSrc->type;
+    pDst->in_use = TRUE;
+
+    return TRUE;
+}
+
+BOOL moveDrive(drive_entry_t *pSrc, drive_entry_t *pDst)
+{
+    WINE_TRACE("pSrc->letter == %c, pDst->letter == %c\n", pSrc->letter, pDst->letter);
+
+    if(!copyDrive(pSrc, pDst))
+    {
+        WINE_TRACE("copyDrive failed\n");
+        return FALSE;
+    }
+
+    freeDrive(pSrc);
+    return TRUE;
 }
 
 int refreshDriveDlg (HWND dialog)
 {
-  int i;
-  char *subKeyName = malloc(MAX_NAME_LENGTH);
   int driveCount = 0;
-  DWORD sizeOfSubKeyName = MAX_NAME_LENGTH;
   int doesDriveCExist = FALSE;
+  int i;
 
   WINE_TRACE("\n");
 
@@ -131,78 +164,41 @@
 
   /* Clear the listbox */
   SendMessageA(GetDlgItem(dialog, IDC_LIST_DRIVES), LB_RESETCONTENT, 0, 0);
-  for (i = 0;
-       RegEnumKeyExA(configKey, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS;
-       ++i, sizeOfSubKeyName = MAX_NAME_LENGTH) {
-    
-    HKEY hkDrive;
-    char returnBuffer[MAX_NAME_LENGTH];
-    DWORD sizeOfReturnBuffer = sizeof(returnBuffer);
-    LONG r;
-    WINE_TRACE("%s\n", subKeyName);
-    
-    if (!strncmp("Drive ", subKeyName, 5)) {
-      char driveLetter = '\0';
-      char *label;
-      char *title;
-      char *device;
+
+  for(i = 0; i < 26; i++)
+  {
+      char *title = 0;
       int titleLen;
-      const char *itemLabel = "Drive %s (%s)";
       int itemIndex;
-      
-      if (RegOpenKeyExA (configKey, subKeyName, 0, KEY_READ, &hkDrive) != ERROR_SUCCESS)        {
-        WINE_ERR("unable to open drive registry key");
-        RegCloseKey(configKey);
-        return -1;
-      }
-      
-      /* extract the drive letter, force to upper case */
-      driveLetter = subKeyName[strlen(subKeyName)-1];
-      if (driveLetter) driveLetter = toupper(driveLetter);
-      if (driveLetter == 'C') doesDriveCExist = TRUE;
-      
-      ZeroMemory(returnBuffer, sizeof(*returnBuffer));
-      sizeOfReturnBuffer = sizeof(returnBuffer);
-      r = RegQueryValueExA(hkDrive, "Label", NULL, NULL, returnBuffer, &sizeOfReturnBuffer);
-      if (r == ERROR_SUCCESS) {
-        label = malloc(sizeOfReturnBuffer);
-        strncpy(label, returnBuffer, sizeOfReturnBuffer);
-      } else {
-        WINE_WARN("label not loaded: %ld\n", r);
-        label = NULL;
-      }
 
-      device = getDriveValue(driveLetter, "Device");
-      
-      /* We now know the label and drive letter, so we can add to the list. The list items will have the letter associated
-       * with them, which acts as the key. We can then use that letter to get/set the properties of the drive. */
-      WINE_TRACE("Adding %c: label=%s to the listbox, device=%s\n", driveLetter, label, device);
-
-      /* fixup label */
-      if (!label && device) {
-	label = malloc(strlen("[label read from device ]")+1+strlen(device));
-	sprintf(label, "[label read from device %s]", device);
-      }
-      if (!label) label = strdup("(no label)");
-      
-      titleLen = strlen(itemLabel) - 1 + strlen(label) - 2 + 1;
+      /* skip over any unused drives */
+      if(!drives[i].in_use)
+          continue;
+
+      if(drives[i].letter == 'C')
+          doesDriveCExist = TRUE;
+
+      titleLen = snprintf(title, 0, "Drive %c:\\ %s", 'A' + i,
+                          drives[i].unixpath);
+      titleLen++; /* add a byte for the trailing null */
+
       title = malloc(titleLen);
+
       /* the %s in the item label will be replaced by the drive letter, so -1, then
-	 -2 for the second %s which will be expanded to the label, finally + 1 for terminating #0 */
-      snprintf(title, titleLen, "Drive %c: %s", driveLetter, label);
-      
+         -2 for the second %s which will be expanded to the label, finally + 1 for terminating #0 */
+      snprintf(title, titleLen, "Drive %c:\\ %s", 'A' + i,
+               drives[i].unixpath);
+
+      WINE_TRACE("title is '%s'\n", title);
+
       /* the first SendMessage call adds the string and returns the index, the second associates that index with it */
       itemIndex = SendMessageA(GetDlgItem(dialog, IDC_LIST_DRIVES), LB_ADDSTRING ,(WPARAM) -1, (LPARAM) title);
-      SendMessageA(GetDlgItem(dialog, IDC_LIST_DRIVES), LB_SETITEMDATA, itemIndex, (LPARAM) driveLetter);
-      
-      free(title);
-      free(label);
+      SendMessageA(GetDlgItem(dialog, IDC_LIST_DRIVES), LB_SETITEMDATA, itemIndex, (LPARAM) &drives[i]);
 
+      free(title);
       driveCount++;
-	
-    }
   }
-  
+
   WINE_TRACE("loaded %d drives\n", driveCount);
   SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_SETSEL, TRUE, lastSel);
 
@@ -212,8 +208,6 @@
   else
     ShowWindow(GetDlgItem(dialog, IDS_DRIVE_NO_C), SW_HIDE);
   
-  free(subKeyName);
-
   /* disable or enable controls depending on whether we are editing global vs app specific config */
   if (appSettings == EDITING_GLOBAL) {
     WINE_TRACE("enabling controls\n");
@@ -243,15 +237,15 @@
 #define DRIVE_MASK_BIT(B) 1<<(toupper(B)-'A')
 
 typedef struct {
-  const char *sCode;
+  const uint sCode;
   const char *sDesc;
 } code_desc_pair;
 
 static code_desc_pair type_pairs[] = {
-  {"hd", "Local hard disk"},
-  {"network", "Network share" },
-  {"floppy", "Floppy disk"},
-  {"cdrom", "CD-ROM"}
+  {DRIVE_FIXED,      "Local hard disk"},
+  {DRIVE_REMOTE,     "Network share" },
+  {DRIVE_REMOVABLE,  "Floppy disk"},
+  {DRIVE_CDROM,      "CD-ROM"}
 };
 #define DRIVE_TYPE_DEFAULT 1
 
@@ -272,11 +266,11 @@
       index = SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_ADDSTRING, 0, (LPARAM) sName );
 			  
       if( toupper(currentLetter) == 'A' + i ) {
-	selection = count;
+          selection = count;
       }
       
       if( i >= 2 && next_letter == -1){ /*default drive is first one of C-Z */
-	next_letter = count;
+          next_letter = count;
       }
       
       count++;
@@ -299,7 +293,7 @@
   WINE_TRACE("mode=%d\n", mode);
   switch (mode) {
       case BOX_MODE_CD_ASSIGN:
-	enable(IDC_RADIO_AUTODETECT);
+//	enable(IDC_RADIO_AUTODETECT);
 	enable(IDC_RADIO_ASSIGN);
 	disable(IDC_EDIT_DEVICE);
 	disable(IDC_BUTTON_BROWSE_DEVICE);
@@ -310,7 +304,7 @@
 	break;
 	
       case BOX_MODE_CD_AUTODETECT:
-	enable(IDC_RADIO_AUTODETECT);
+//	enable(IDC_RADIO_AUTODETECT);
 	enable(IDC_RADIO_ASSIGN);
 	enable(IDC_EDIT_DEVICE);
 	enable(IDC_BUTTON_BROWSE_DEVICE);
@@ -356,19 +350,17 @@
 long drive_available_mask(char letter)
 {
   long result = 0;
-  char curLetter;
-  char *slop;
-  
+  int i;
+
   WINE_TRACE("\n");
- 
-  for (curLetter = 'A'; curLetter < 'Z'; curLetter++) {
-    slop = getDriveValue(curLetter, "Path");
-    if (slop != NULL) {
-      result |= DRIVE_MASK_BIT(curLetter);
-      free(slop);
-    }
-  }
+
   
+  for(i = 0; i < 26; i++)
+  {
+      if(!drives[i].in_use) continue;
+      result |= (1 << (toupper(drives[i].letter) - 'A'));
+  }
+
   result = ~result;
   if (letter) result |= DRIVE_MASK_BIT(letter);
   
@@ -376,34 +368,115 @@
   return result;
 }
 
+void advancedDriveEditDialog(HWND hDlg, BOOL showAdvanced)
+{
+#define ADVANCED_DELTA      120
+
+    static RECT okpos;
+    static BOOL got_initial_ok_position = FALSE;
+
+    static RECT windowpos; /* we only use the height of this rectangle */
+    static BOOL got_initial_window_position = FALSE;
+
+    static RECT current_window;
+
+    INT state;
+    INT offset;
+    char *text;
+
+    if(!got_initial_ok_position)
+    {
+        POINT pt;
+        GetWindowRect(GetDlgItem(hDlg, ID_BUTTON_OK), &okpos);
+        pt.x = okpos.left;
+        pt.y = okpos.top;
+        ScreenToClient(hDlg, &pt);
+        okpos.right+= (pt.x - okpos.left);
+        okpos.bottom+= (pt.y - okpos.top);
+        okpos.left = pt.x;
+        okpos.top = pt.y;
+        got_initial_ok_position = TRUE;
+    }
+
+    if(!got_initial_window_position)
+    {
+        GetWindowRect(hDlg, &windowpos);
+        got_initial_window_position = TRUE;
+    }
+          
+    if(showAdvanced)
+    {
+        state = SW_NORMAL;
+        offset = 0;
+        text = "Hide Advanced";
+    } else
+    {
+        state = SW_HIDE;
+        offset = ADVANCED_DELTA;
+        text = "Show Advanced";
+    }
+
+    ShowWindow(GetDlgItem(hDlg, IDC_STATIC_TYPE), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_COMBO_TYPE), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_BOX_LABELSERIAL), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_RADIO_AUTODETECT), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_RADIO_ASSIGN), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_EDIT_LABEL), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_EDIT_DEVICE), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_STATIC_LABEL), state);
+    ShowWindow(GetDlgItem(hDlg, IDC_BUTTON_BROWSE_DEVICE), state);
+    SetWindowPos(GetDlgItem(hDlg, ID_BUTTON_OK),
+                 HWND_TOP,
+                 okpos.left, okpos.top - offset, okpos.right - okpos.left,
+                 okpos.bottom - okpos.top,
+                 0);
+
+    /* resize the parent window */
+    GetWindowRect(hDlg, &current_window);
+    SetWindowPos(hDlg, 
+                 HWND_TOP,
+                 current_window.left,
+                 current_window.top,
+                 windowpos.right - windowpos.left,
+                 windowpos.bottom - windowpos.top - offset,
+                 0);
+
+    /* update the button text based on the state */
+    SetWindowText(GetDlgItem(hDlg, IDC_BUTTON_SHOW_HIDE_ADVANCED),
+                  text);
+}
+
 
 void refreshDriveEditDialog(HWND dialog) {
   char *path;
-  char *type;
-  char *serial;
+  uint type;
   char *label;
+  char *serial;
   char *device;
-  int i, selection;
+  int i, selection = -1;
 
   updatingUI = TRUE;
+
+  WINE_TRACE("\n");
   
   /* Drive letters */
-  fill_drive_droplist( drive_available_mask( editWindowLetter ), editWindowLetter, dialog );
+  fill_drive_droplist( drive_available_mask( editDriveEntry->letter ), editDriveEntry->letter, dialog );
 
   /* path */
-  path = getDriveValue(editWindowLetter, "Path");
+  path = editDriveEntry->unixpath;
   if (path) {
+    WINE_TRACE("set path control text to '%s'\n", path);
     SetWindowText(GetDlgItem(dialog, IDC_EDIT_PATH), path);
   } else WINE_WARN("no Path field?\n");
   
   /* drive type */
-  type = getDriveValue(editWindowLetter, "Type");
+  type = editDriveEntry->type;
   if (type) {
-    for(i = 0, selection = -1; i < sizeof(type_pairs)/sizeof(code_desc_pair); i++) {
+    for(i = 0; i < sizeof(type_pairs)/sizeof(code_desc_pair); i++) {
       SendDlgItemMessage(dialog, IDC_COMBO_TYPE, CB_ADDSTRING, 0,
 			 (LPARAM) type_pairs[i].sDesc);
-      if(strcasecmp(type_pairs[i].sCode, type) == 0){
-	selection = i;
+      if(type_pairs[i].sCode ==  type){
+          selection = i;
       }
     }
   
@@ -413,44 +486,42 @@
 
   
   /* removeable media properties */
-  serial = getDriveValue(editWindowLetter, "Serial");
-  if (serial) {
-    SendDlgItemMessage(dialog, IDC_EDIT_SERIAL, WM_SETTEXT, 0,(LPARAM)serial);
-  } else WINE_WARN("no Serial field?\n");
-
-  label = getDriveValue(editWindowLetter, "Label");
+  label = editDriveEntry->label;
   if (label) {
     SendDlgItemMessage(dialog, IDC_EDIT_LABEL, WM_SETTEXT, 0,(LPARAM)label);
   } else WINE_WARN("no Label field?\n");
 
-  device = getDriveValue(editWindowLetter, "Device");
+  /* set serial edit text */
+  serial = editDriveEntry->serial;
+  if (serial) {
+    SendDlgItemMessage(dialog, IDC_EDIT_SERIAL, WM_SETTEXT, 0,(LPARAM)serial);
+  } else WINE_WARN("no Serial field?\n");
+
+  //TODO: get the device here to put into the edit box
+  device = "Not implemented yet";
   if (device) {
     SendDlgItemMessage(dialog, IDC_EDIT_DEVICE, WM_SETTEXT, 0,(LPARAM)device);
   } else WINE_WARN("no Device field?\n");
 
   selection = IDC_RADIO_ASSIGN;
-  if ((type && strcmp("cdrom", type) == 0) || (type && strcmp("floppy", type) == 0)) {
+  if ((type == DRIVE_CDROM) || (type == DRIVE_REMOVABLE)) {
+#if 0
     if (device) {
       selection = IDC_RADIO_AUTODETECT;
       enable_labelserial_box(dialog, BOX_MODE_CD_AUTODETECT);
     } else {
+#endif
       selection = IDC_RADIO_ASSIGN;
       enable_labelserial_box(dialog, BOX_MODE_CD_ASSIGN);
+#if 0
     }
+#endif
   } else {
     enable_labelserial_box(dialog, BOX_MODE_NORMAL);
     selection = IDC_RADIO_ASSIGN;
   }
 
   CheckRadioButton( dialog, IDC_RADIO_AUTODETECT, IDC_RADIO_ASSIGN, selection );
-  if (path) SendDlgItemMessage(dialog, IDC_EDIT_PATH, WM_SETTEXT, 0,(LPARAM)path);
-  
-  if (path) free(path);
-  if (type) free(type);
-  if (serial) free(serial);
-  if (label) free(label);
-  if (device) free(device);
-
   
   updatingUI = FALSE;
   
@@ -465,42 +536,53 @@
   switch (controlID) {
       case IDC_EDIT_LABEL: {
         char *label = getDialogItemText(hDlg, controlID);
-        setDriveValue(editWindowLetter, "Label", label);
+        if(!label) label = strdup("");
+        setDriveLabel(editDriveEntry, label);
         refreshDriveDlg(driveDlgHandle);
         if (label) free(label);
         break;
       }
       case IDC_EDIT_PATH: {
-	char *path = getDialogItemText(hDlg, controlID);
-	if (!path) path = strdup("fake_windows"); /* default to assuming fake_windows in the .wine directory */
-	setDriveValue(editWindowLetter, "Path", path);
-	free(path);
-	break;
+          char *path = getDialogItemText(hDlg, controlID);
+          if (!path) path = strdup("fake_windows"); /* default to assuming fake_windows in the .wine directory */
+          WINE_TRACE("got path from control of '%s'\n", path);
+          setDrivePath(editDriveEntry, path);
+          if(path) free(path);
+          break;
       }
       case IDC_EDIT_SERIAL: {
-	char *serial = getDialogItemText(hDlg, controlID);
-	setDriveValue(editWindowLetter, "Serial", serial);
-	if (serial) free (serial);
-	break;
+          char *serial = getDialogItemText(hDlg, controlID);
+          if(!serial) serial = strdup("");
+          setDriveSerial(editDriveEntry, serial);
+          if (serial) free (serial);
+          break;
       }
       case IDC_EDIT_DEVICE: {
-	char *device = getDialogItemText(hDlg,controlID);
-	setDriveValue(editWindowLetter, "Device", device);
-	if (device) free(device);
-	refreshDriveDlg(driveDlgHandle);
-	break;
+          char *device = getDialogItemText(hDlg,controlID);
+          //TODO: handle device if/when it makes sense to do so....
+          if (device) free(device);
+          refreshDriveDlg(driveDlgHandle);
+          break;
       }
   }
 }
 
+/* edit a drive entry */
 INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
   int selection;
+  static BOOL advanced = FALSE;
 
   switch (uMsg)  {
+      case WM_CLOSE:
+	    EndDialog(hDlg, wParam);
+	    return TRUE;
+
       case WM_INITDIALOG: {
-	editWindowLetter = (char) lParam;
-	refreshDriveEditDialog(hDlg);
+          enable_labelserial_box(hDlg, BOX_MODE_NORMAL);
+          advancedDriveEditDialog(hDlg, advanced);
+          editDriveEntry = (drive_entry_t*)lParam;
+          refreshDriveEditDialog(hDlg);
       }
 
     case WM_COMMAND:
@@ -510,14 +592,14 @@
 	    selection = SendDlgItemMessage( hDlg, IDC_COMBO_TYPE, CB_GETCURSEL, 0, 0);
 	    if( selection == 2 || selection == 3 ) { /* cdrom or floppy */
 	      if (IsDlgButtonChecked(hDlg, IDC_RADIO_AUTODETECT))
-		enable_labelserial_box(hDlg, BOX_MODE_CD_AUTODETECT);
+              enable_labelserial_box(hDlg, BOX_MODE_CD_AUTODETECT);
 	      else
-		enable_labelserial_box(hDlg, BOX_MODE_CD_ASSIGN);
+              enable_labelserial_box(hDlg, BOX_MODE_CD_ASSIGN);
 	    }
 	    else {
 	      enable_labelserial_box( hDlg, BOX_MODE_NORMAL );
 	    }
-	    setDriveValue(editWindowLetter, "Type", type_pairs[selection].sCode);
+        editDriveEntry->type = type_pairs[selection].sCode;
 	    break;
 
 	  case IDC_COMBO_LETTER: {
@@ -526,12 +608,11 @@
 	    SendDlgItemMessage(hDlg, IDC_COMBO_LETTER, CB_GETLBTEXT, item, (LPARAM) &newLetter);
 	    
 	    if (HIWORD(wParam) != CBN_SELCHANGE) break;
-	    if (newLetter == editWindowLetter) break;
+	    if (newLetter == editDriveEntry->letter) break;
 	    	    
 	    WINE_TRACE("changing drive letter to %c\n", newLetter);
-	    copyDrive(editWindowLetter, newLetter);
-	    removeDrive(editWindowLetter);
-	    editWindowLetter = newLetter;
+        moveDrive(editDriveEntry, &drives[getDrive(newLetter)]);
+        editDriveEntry = &drives[getDrive(newLetter)];
 	    refreshDriveDlg(driveDlgHandle);
 	    break;
 	  }
@@ -541,25 +622,42 @@
 	    break;
 
 	  case IDC_RADIO_AUTODETECT: {
-	    setDriveValue(editWindowLetter, "Label", NULL);
-	    setDriveValue(editWindowLetter, "Serial", NULL);
-	    setDriveValue(editWindowLetter, "Device", getDialogItemText(hDlg, IDC_EDIT_DEVICE));
+        //TODO:
+        WINE_FIXME("Implement autodetection\n");
 	    enable_labelserial_box(hDlg, BOX_MODE_CD_AUTODETECT);
-	    refreshDriveDlg(driveDlgHandle);
+        refreshDriveDlg(driveDlgHandle);
 	    break;
 	  }
 	    
 	  case IDC_RADIO_ASSIGN:
-	    setDriveValue(editWindowLetter, "Device", NULL);
-	    setDriveValue(editWindowLetter, "Label", getDialogItemText(hDlg, IDC_EDIT_LABEL));
-	    setDriveValue(editWindowLetter, "Serial", getDialogItemText(hDlg, IDC_EDIT_SERIAL));
+      {
+        char *edit, *serial;
+        edit = getDialogItemText(hDlg, IDC_EDIT_LABEL);
+        if(!edit) edit = strdup("");
+        setDriveLabel(editDriveEntry, edit);
+        free(edit);
+
+        serial = getDialogItemText(hDlg, IDC_EDIT_SERIAL);
+        if(!serial) serial = strdup("");
+        setDriveSerial(editDriveEntry, serial);
+        free(serial);
+
+        //TODO: we don't have a device at this point
+//	    setDriveValue(editWindowLetter, "Device", NULL);
 	    enable_labelserial_box(hDlg, BOX_MODE_CD_ASSIGN);
 	    refreshDriveDlg(driveDlgHandle);
 	    break;
+      }
 	    
+      case IDC_BUTTON_SHOW_HIDE_ADVANCED:
+          advanced = (advanced == TRUE) ? FALSE : TRUE; /* toggle state */
+          advancedDriveEditDialog(hDlg, advanced);
+          break;
+
 	  case ID_BUTTON_OK:	  
 	    EndDialog(hDlg, wParam);
 	    return TRUE;
+
       }
       if (HIWORD(wParam) == EN_CHANGE) onEditChanged(hDlg, LOWORD(wParam));
       break;
@@ -574,7 +672,6 @@
   
   char newLetter = 'C'; /* we skip A and B, they are historically floppy drives */
   long mask = ~drive_available_mask(0); /* the mask is now which drives aren't available */
-  char *sectionName;
   
   while (mask & (1 << (newLetter - 'A'))) {
     newLetter++;
@@ -584,21 +681,324 @@
     }
   }
   WINE_TRACE("allocating drive letter %c\n", newLetter);
-  
-  sectionName = malloc(strlen("Drive X") + 1);
-  sprintf(sectionName, "Drive %c", newLetter);
-  if (newLetter == 'C') {
-    addTransaction(sectionName, "Path", ACTION_SET, "fake_windows");
-    addTransaction(sectionName, "Label", ACTION_SET, "System Drive");
-  } else
-    addTransaction(sectionName, "Path", ACTION_SET, "/"); /* default to root path */
-  addTransaction(sectionName, "Type", ACTION_SET, "hd");
-  processTransQueue(); /* make sure the drive has been added, even if we are not in instant apply mode */
-  free(sectionName);
+
+  if(newLetter == 'C') {
+      addDrive(newLetter, "fake_windows", "System Drive", "", DRIVE_FIXED);
+  } else {
+      addDrive(newLetter, "/", "", "", DRIVE_FIXED);
+  }
 
   refreshDriveDlg(driveDlgHandle);
 
-  DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) newLetter);
+  DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) &(drives[getDrive(newLetter)]));
+}
+
+void onDriveInitDialog(void)
+{
+  char *pDevices;
+  int ret;
+  int i;
+  int retval;
+
+  WINE_TRACE("\n");
+
+  /* setup the drives array */
+  pDevices = (char*)malloc(512);
+  ret = GetLogicalDriveStrings(512, pDevices);
+
+  /* make all devices unused */
+  for(i = 0; i < 26; i++)
+  {
+      drives[i].letter = 'A' + i;
+      drives[i].in_use = FALSE;
+  }
+
+  i = 0;
+
+  while(ret)
+  {
+    CHAR volumeNameBuffer[512];
+    DWORD serialNumber;
+    CHAR serialNumberString[256];
+    DWORD maxComponentLength;
+    DWORD fileSystemFlags;
+    CHAR fileSystemName[128];
+    char rootpath[256];
+    char simplepath[3];
+    int pathlen;
+    char targetpath[256];
+
+    *pDevices = toupper(*pDevices);
+
+    WINE_TRACE("pDevices == '%s'\n", pDevices);
+
+    volumeNameBuffer[0] = 0;
+    
+    retval = GetVolumeInformation(pDevices,
+                         volumeNameBuffer,
+                         sizeof(volumeNameBuffer),
+                         &serialNumber,
+                         &maxComponentLength,
+                         &fileSystemFlags,
+                         fileSystemName,
+                         sizeof(fileSystemName));
+    if(!retval)
+    {
+        WINE_TRACE("GetVolumeInformation() for '%s' failed, setting serialNumber to 0\n", pDevices);
+        PRINTERROR();
+        serialNumber = 0;
+    }
+
+    WINE_TRACE("serialNumber: '0x%lX'\n", serialNumber);
+
+    /* build rootpath for GetDriveType() */
+    strncpy(rootpath, pDevices, sizeof(rootpath));
+    pathlen = strlen(rootpath);
+    /* ensure that we have a backslash on the root path */
+    if((rootpath[pathlen - 1] != '\\') &&
+       (pathlen < sizeof(rootpath)))
+     {
+         rootpath[pathlen] = '\\';
+         rootpath[pathlen + 1] = 0;
+     }
+
+    strncpy(simplepath, pDevices, 2); /* QueryDosDevice() requires no trailing backslash */
+    simplepath[2] = 0;
+    QueryDosDevice(simplepath, targetpath, sizeof(targetpath)); 
+    
+    snprintf(serialNumberString, sizeof(serialNumberString), "%lX", serialNumber);
+    WINE_TRACE("serialNumberString: '%s'\n", serialNumberString);
+    addDrive(*pDevices, targetpath, volumeNameBuffer, serialNumberString, GetDriveType(rootpath));
+
+    ret-=strlen(pDevices);
+    pDevices+=strlen(pDevices);
+
+    /* skip over any nulls */
+    while((*pDevices == 0) && (ret))
+    {
+        ret--;
+        pDevices++;
+    }
+
+    i++;
+  }
+
+  WINE_TRACE("found %d drives\n", i);
+
+  free(pDevices);
+}
+
+
+void applyDriveChanges(void)
+{
+    int i;
+    CHAR devicename[4];
+    CHAR targetpath[256];
+    BOOL foundDrive;
+    CHAR volumeNameBuffer[512];
+    DWORD serialNumber;
+    DWORD maxComponentLength;
+    DWORD fileSystemFlags;
+    CHAR fileSystemName[128];
+    int retval;
+    BOOL defineDevice;
+
+    WINE_TRACE("\n");
+
+    /* add each drive and remove as we go */
+    for(i = 0; i < 26; i++)
+    {
+        defineDevice = FALSE;
+        foundDrive = FALSE;
+        snprintf(devicename, sizeof(devicename), "%c:", 'A' + i); 
+
+        /* get a drive */
+        if(QueryDosDevice(devicename, targetpath, sizeof(targetpath)))
+        {
+            foundDrive = TRUE;
+        }
+
+        /* if we found a drive and have a drive then compare things */
+        if(foundDrive && drives[i].in_use)
+        {
+            char newSerialNumberText[256];
+
+            volumeNameBuffer[0] = 0;
+
+            WINE_TRACE("drives[i].letter: '%c'\n", drives[i].letter);
+
+            snprintf(devicename, sizeof(devicename), "%c:\\", 'A' + i);
+            retval = GetVolumeInformation(devicename,
+                         volumeNameBuffer,
+                         sizeof(volumeNameBuffer),
+                         &serialNumber,
+                         &maxComponentLength,
+                         &fileSystemFlags,
+                         fileSystemName,
+                         sizeof(fileSystemName));
+            if(!retval)
+            {
+                WINE_TRACE("  GetVolumeInformation() for '%s' failed\n", devicename);
+                WINE_TRACE("  Skipping this drive\n");
+                PRINTERROR();
+                continue; /* skip this drive */
+            }
+
+            snprintf(newSerialNumberText, sizeof(newSerialNumberText), "%lX", serialNumber);
+
+            WINE_TRACE("  current path:   '%s', new path:   '%s'\n",
+                       targetpath, drives[i].unixpath);
+            WINE_TRACE("  current label:  '%s', new label:  '%s'\n",
+                       volumeNameBuffer, drives[i].label);
+            WINE_TRACE("  current serial: '%s', new serial: '%s'\n",
+                       newSerialNumberText, drives[i].serial);
+
+            /* compare to what we have */
+            /* do we have the same targetpath? */
+            if(strcmp(drives[i].unixpath, targetpath) ||
+               strcmp(drives[i].label, volumeNameBuffer) ||
+               strcmp(drives[i].serial, newSerialNumberText))
+            {
+                defineDevice = TRUE;
+                WINE_TRACE("  making changes to drive '%s'\n", devicename);
+            } else
+            {
+                WINE_TRACE("  no changes to drive '%s'\n", devicename);
+            }
+        } else if(foundDrive && !drives[i].in_use)
+        {
+            /* remove this drive */
+            if(!DefineDosDevice(DDD_REMOVE_DEFINITION, devicename, drives[i].unixpath))
+            {
+                WINE_ERR("unable to remove devicename of '%s', targetpath of '%s'\n",
+                    devicename, drives[i].unixpath);
+                PRINTERROR();
+            } else
+            {
+                WINE_TRACE("removed devicename of '%s', targetpath of '%s'\n",
+                           devicename, drives[i].unixpath);
+            }
+        } else if(drives[i].in_use) /* foundDrive must be false from the above check */
+        {
+            defineDevice = TRUE;
+        }
+
+        /* adding and modifying are the same steps */
+        if(defineDevice)
+        {
+            char filename[256];
+            HANDLE hFile;
+
+            HKEY hKey;
+            char *typeText;
+            char driveValue[256];
+
+            /* define this drive */
+            /* DefineDosDevice() requires that NO trailing slash be present */
+            snprintf(devicename, sizeof(devicename), "%c:", 'A' + i); 
+            if(!DefineDosDevice(DDD_RAW_TARGET_PATH, devicename, drives[i].unixpath))
+            {
+                WINE_ERR("  unable to define devicename of '%s', targetpath of '%s'\n",
+                    devicename, drives[i].unixpath);
+                PRINTERROR();
+            } else
+            {
+                WINE_TRACE("  added devicename of '%s', targetpath of '%s'\n",
+                           devicename, drives[i].unixpath);
+                
+                /* SetVolumeLabel() requires a trailing slash */
+                snprintf(devicename, sizeof(devicename), "%c:\\", 'A' + i);
+                if(!SetVolumeLabel(devicename, drives[i].label))
+                {
+                    WINE_ERR("unable to set volume label for devicename of '%s', label of '%s'\n",
+                        devicename, drives[i].label);
+                    PRINTERROR();
+                } else
+                {
+                    WINE_TRACE("  set volume label for devicename of '%s', label of '%s'\n",
+                        devicename, drives[i].label);
+                }
+            }
+
+            /* Set the drive type in the registry */
+            if(drives[i].type == DRIVE_FIXED)
+                typeText = "hd";
+            else if(drives[i].type == DRIVE_REMOTE)
+                typeText = "network";
+            else if(drives[i].type == DRIVE_REMOVABLE)
+                typeText = "floppy";
+            else /* must be DRIVE_CDROM */
+                typeText = "cdrom";
+            
+
+            snprintf(driveValue, sizeof(driveValue), "%c:", toupper(drives[i].letter));
+
+            retval = RegOpenKey(HKEY_LOCAL_MACHINE,
+                       "Software\\Wine\\Drives",
+                       &hKey);
+
+            if(retval != ERROR_SUCCESS)
+            {
+                WINE_TRACE("  Unable to open '%s'\n", "Software\\Wine\\Drives");
+            } else
+            {
+                retval = RegSetValueEx(
+                              hKey,
+                              driveValue,
+                              0,
+                              REG_SZ,
+                              typeText,
+                              strlen(typeText) + 1);
+                if(retval != ERROR_SUCCESS)
+                {
+                    WINE_TRACE("  Unable to set value of '%s' to '%s'\n",
+                               driveValue, typeText);
+                } else
+                {
+                    WINE_TRACE("  Finished setting value of '%s' to '%s'\n",
+                               driveValue, typeText);
+                    RegCloseKey(hKey);
+                }
+            }
+
+            /* Set the drive serial number via a .windows-serial file in */
+            /* the targetpath directory */
+            snprintf(filename, sizeof(filename), "%c:\\.windows-serial", drives[i].letter);
+            WINE_TRACE("  Putting serial number of '%ld' into file '%s'\n",
+                       serialNumber, filename);
+            hFile = CreateFile(filename,
+                       GENERIC_WRITE,
+                       FILE_SHARE_READ,
+                       NULL,
+                       CREATE_ALWAYS,
+                       FILE_ATTRIBUTE_NORMAL,
+                       NULL);
+            if(hFile)
+            {
+                WINE_TRACE("  writing serial number of '%s'\n", drives[i].serial);
+                WriteFile(hFile,
+                          drives[i].serial,
+                          strlen(drives[i].serial),
+                          NULL,
+                          NULL); 
+                WriteFile(hFile,
+                          "\n",
+                          strlen("\n"),
+                          NULL,
+                          NULL); 
+                CloseHandle(hFile);
+            } else
+            {
+                WINE_TRACE("  CreateFile() error with file '%s'\n", filename);
+            }
+        }
+
+        /* if this drive is in use we should free it up */
+        if(drives[i].in_use)
+        {
+            freeDrive(&drives[i]); /* free up the string memory */
+        }
+    }
 }
 
 
@@ -606,9 +1006,12 @@
 DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
   int nItem;
-  char letter;
-  
+  drive_entry_t *pDrive;
+
   switch (uMsg) {
+      case WM_INITDIALOG:
+          onDriveInitDialog();
+          break;
       case WM_COMMAND:
 	switch (LOWORD(wParam)) {
 	    case IDC_LIST_DRIVES:
@@ -626,16 +1029,16 @@
 	    case IDC_BUTTON_REMOVE:
 	      if (HIWORD(wParam) != BN_CLICKED) break;
 	      nItem = SendDlgItemMessage(hDlg, IDC_LIST_DRIVES,  LB_GETCURSEL, 0, 0);
-	      letter = SendDlgItemMessage(hDlg, IDC_LIST_DRIVES, LB_GETITEMDATA, nItem, 0);
-	      removeDrive(letter);
+	      pDrive = (drive_entry_t*)SendDlgItemMessage(hDlg, IDC_LIST_DRIVES, LB_GETITEMDATA, nItem, 0);
+          freeDrive(pDrive);
 	      refreshDriveDlg(driveDlgHandle);
 	      break;
 	      
 	    case IDC_BUTTON_EDIT:
 	      if (HIWORD(wParam) != BN_CLICKED) break;
 	      nItem = SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES),  LB_GETCURSEL, 0, 0);
-	      letter = SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_GETITEMDATA, nItem, 0);
-	      DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) letter);
+	      pDrive = (drive_entry_t*)SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_GETITEMDATA, nItem, 0);
+	      DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) pDrive);
 	      break;
 
 	    case IDC_BUTTON_AUTODETECT:
@@ -646,9 +1049,11 @@
 	
       case WM_NOTIFY: switch(((LPNMHDR)lParam)->code) {
 	    case PSN_KILLACTIVE:
+          WINE_TRACE("PSN_KILLACTIVE\n");
 	      SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
 	      break;
 	    case PSN_APPLY:
+          applyDriveChanges();
 	      SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
 	      break;
 	    case PSN_SETACTIVE:
Index: programs/winecfg/En.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/En.rc,v
retrieving revision 1.20
diff -u -r1.20 En.rc
--- programs/winecfg/En.rc	1 Apr 2004 21:06:14 -0000	1.20
+++ programs/winecfg/En.rc	1 May 2004 03:54:25 -0000
@@ -139,28 +139,28 @@
 CAPTION "Drive Configuration"
 FONT 8, "MS Sans Serif"
 BEGIN
-    DEFPUSHBUTTON   "&Close",ID_BUTTON_OK,145,150,50,13
+    DEFPUSHBUTTON   "&Ok",ID_BUTTON_OK,145,150,50,16
     LTEXT           "Letter:",IDC_STATIC,5,23,26,9
-    EDITTEXT        IDC_EDIT_LABEL,63,114,78,13,ES_AUTOHSCROLL
-    LTEXT           "Label:",IDC_STATIC_LABEL,33,117,29,12
-    LTEXT           "Type:",IDC_STATIC,5,54,21,10
+    EDITTEXT        IDC_EDIT_LABEL,63,108,78,13,ES_AUTOHSCROLL
+    LTEXT           "Label:",IDC_STATIC_LABEL,33,111,29,12
+    LTEXT           "Serial:",IDC_STATIC_SERIAL,33,127,29,12
+    EDITTEXT        IDC_EDIT_SERIAL,63,124,78,13,ES_AUTOHSCROLL
+    LTEXT           "Type:",IDC_STATIC_TYPE,5,39,21,10
     EDITTEXT        IDC_EDIT_PATH,31,5,117,13,ES_AUTOHSCROLL
-    LTEXT           "Path:",IDC_STATIC,5,9,20,9
-    LTEXT           "Names:",IDC_STATIC,5,39,25,9
-    EDITTEXT        IDC_EDIT_SERIAL,63,129,78,13,ES_AUTOHSCROLL
-    LTEXT           "Serial:",IDC_STATIC_SERIAL,33,130,29,12
-    COMBOBOX        IDC_COMBO_LETTER,31,20,78,60,CBS_DROPDOWNLIST  | 
+    LTEXT           "Path:",IDC_STATIC,5,8,20,9
+    COMBOBOX        IDC_COMBO_LETTER,31,20,77,60,CBS_DROPDOWNLIST  | 
                     WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "Browse...",IDC_BUTTON_BROWSE_PATH,154,5,40,13
-    COMBOBOX        IDC_COMBO_TYPE,31,52,78,60,CBS_DROPDOWNLIST | 
+    COMBOBOX        IDC_COMBO_TYPE,31,36,77,60,CBS_DROPDOWNLIST | 
                     WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "Show Advanced",IDC_BUTTON_SHOW_HIDE_ADVANCED,134,34,60,16
     CONTROL         "Autodetect from Device:",IDC_RADIO_AUTODETECT,"Button",
-                    BS_AUTORADIOBUTTON,21,79,93,10
-    EDITTEXT        IDC_EDIT_DEVICE,33,89,108,13,ES_AUTOHSCROLL
-    PUSHBUTTON      "Browse...",IDC_BUTTON_BROWSE_DEVICE,148,89,40,13
+                    BS_AUTORADIOBUTTON,21,69,93,10
+    EDITTEXT        IDC_EDIT_DEVICE,33,79,108,13,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse...",IDC_BUTTON_BROWSE_DEVICE,148,79,40,13
     CONTROL         "Manually Assign:",IDC_RADIO_ASSIGN,"Button",
-                    BS_AUTORADIOBUTTON,21,104,69,10
-    GROUPBOX        "Label and Serial Number",IDC_BOX_LABELSERIAL,6,68,189,79
+                    BS_AUTORADIOBUTTON,21,98,69,10
+    GROUPBOX        "Label and serial number",IDC_BOX_LABELSERIAL,6,58,189,85
 END
 
 IDD_AUDIOCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: programs/winecfg/resource.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/resource.h,v
retrieving revision 1.15
diff -u -r1.15 resource.h
--- programs/winecfg/resource.h	1 Apr 2004 21:06:14 -0000	1.15
+++ programs/winecfg/resource.h	1 May 2004 03:54:26 -0000
@@ -108,19 +108,21 @@
 #define IDC_STATIC_LABEL                1073
 #define IDC_ENABLE_DESKTOP              1074
 #define IDS_DRIVE_NO_C                  1075
+#define IDC_BUTTON_SHOW_HIDE_ADVANCED   1076
+#define IDC_STATIC_TYPE                 1077
 
 /* x11drv */
-#define IDC_ENABLE_MANAGED              1076
-#define IDC_SCREEN_DEPTH                1077
-#define IDC_DX_MOUSE_GRAB               1078
-#define IDC_USE_TAKE_FOCUS              1079
-#define IDC_DOUBLE_BUFFER               1080
+#define IDC_ENABLE_MANAGED              1100
+#define IDC_SCREEN_DEPTH                1101
+#define IDC_DX_MOUSE_GRAB               1102
+#define IDC_USE_TAKE_FOCUS              1103
+#define IDC_DOUBLE_BUFFER               1104
 
 /* applications tab */
-#define IDC_APP_TREEVIEW                1021
-#define IDC_APP_ADDAPP                  1081
-#define IDC_APP_REMOVEAPP               1082
+#define IDC_APP_TREEVIEW                1200
+#define IDC_APP_ADDAPP                  1201
+#define IDC_APP_REMOVEAPP               1202
 
 /* audio tab */
-#define IDC_AUDIO_AUTODETECT            1085
-#define IDC_AUDIO_DRIVER                1086
+#define IDC_AUDIO_AUTODETECT            1300
+#define IDC_AUDIO_DRIVER                1301
Index: programs/winecfg/Makefile.in
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Makefile.in,v
retrieving revision 1.10
diff -u -r1.10 Makefile.in
--- programs/winecfg/Makefile.in	9 Mar 2004 04:54:07 -0000	1.10
+++ programs/winecfg/Makefile.in	1 May 2004 03:54:26 -0000
@@ -4,7 +4,7 @@
 VPATH     = @srcdir@
 MODULE    = winecfg.exe
 APPMODE   = -mwindows
-IMPORTS   = comdlg32 comctl32 user32 advapi32
+IMPORTS   = comdlg32 comctl32 user32 advapi32 kernel32
 
 C_SRCS = \
 	appdefaults.c \

Reply via email to