[winecfg 8] Complete drive edit dialog, warn on lack of C drive, implement drive delete, code cleanups

Mike Hearn mike at theoretic.com
Thu Sep 11 09:56:54 CDT 2003


ChangeLog:
- All settings in the drive edit dialog are now instant apply
- Replace OK/Cancel buttons on the right with a close button on the bottom
- Warn the user when a C drive is not present
- Add drive functionality will now always create a C drive if one isn't present
- Misc crasher fixes
- Drive list box now reflects drives that take their data from a device correctly
- Various code cleanups


===================================================================
RCS file: /home/wine/wine/programs/winecfg/En.rc,v
retrieving revision 1.6
diff -u -r1.6 En.rc
--- programs/winecfg/En.rc	8 Sep 2003 18:58:07 -0000	1.6
+++ programs/winecfg/En.rc	11 Sep 2003 14:47:16 -0000
@@ -108,27 +108,6 @@
     PUSHBUTTON      "&Edit",IDC_DRIVE_EDIT,197,80,50,22
 END
 
-IDD_DRIVE_EDIT DIALOG DISCARDABLE  0, 0, 207, 110
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Drive Configuration"
-FONT 8, "MS Sans Serif"
-BEGIN
-    DEFPUSHBUTTON   "OK",ID_DRIVE_OK,150,7,50,14
-    PUSHBUTTON      "Cancel",ID_DRIVE_CANCEL,150,24,50,14
-    EDITTEXT        IDC_DRIVE_EDIT_NAME,42,8,78,13,ES_AUTOHSCROLL
-    LTEXT           "Drive:",-1,11,10,29,12
-    EDITTEXT        IDC_DRIVE_EDIT_LABEL,42,23,78,13,ES_AUTOHSCROLL
-    LTEXT           "Label:",-1,11,25,29,12
-    EDITTEXT        IDC_DRIVE_EDIT_TYPE,42,38,78,13,ES_AUTOHSCROLL
-    LTEXT           "Type:",-1,11,40,29,12
-    EDITTEXT        IDC_DRIVE_EDIT_PATH,42,53,78,13,ES_AUTOHSCROLL
-    LTEXT           "Path:",-1,11,55,29,12
-    EDITTEXT        IDC_DRIVE_EDIT_FS,42,68,78,13,ES_AUTOHSCROLL
-    LTEXT           "FS:",-1,11,70,29,12
-    EDITTEXT        IDC_DRIVE_EDIT_DEVICE,42,83,78,13,ES_AUTOHSCROLL
-    LTEXT           "Device:",-1,11,85,29,12
-END
-
 IDD_DRIVECFG DIALOG DISCARDABLE  0, 0, 260, 250
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
@@ -144,21 +123,20 @@
     PUSHBUTTON      "Browse...",IDC_BUTTON_REAL,202,60,44,14
     PUSHBUTTON      "Important Folders...",IDC_BUTTON_FOLDERS,173,85,73,14
     GROUPBOX        "Other Drives",IDC_STATIC,7,107,246,112
-    LISTBOX         IDC_LIST_DRIVES,14,118,232,76,LBS_SORT | LBS_NOINTEGRALHEIGHT | 
-                    LBS_MULTICOLUMN | WS_VSCROLL | WS_TABSTOP
+    LISTBOX         IDC_LIST_DRIVES,14,118,232,76,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "Add...",IDC_BUTTON_ADD,14,199,37,14
     PUSHBUTTON      "Remove",IDC_BUTTON_REMOVE,55,199,37,14
     PUSHBUTTON      "Edit...",IDC_BUTTON_EDIT,97,199,37,14
     PUSHBUTTON      "Autodetect...",IDC_BUTTON_AUTODETECT,197,199,49,14
+    LTEXT	    "WARNING: You don't seem to have a C drive defined. Click 'Add Drive' to add one.", IDS_DRIVE_NO_C, 7,223,250,110
 END
 
-IDD_DRIVE_EDIT2 DIALOG DISCARDABLE  0, 0, 272, 153
+IDD_DRIVE_EDIT DIALOG DISCARDABLE  0, 0, 203, 169
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Drive Configuration"
 FONT 8, "MS Sans Serif"
 BEGIN
-    DEFPUSHBUTTON   "OK",ID_BUTTON_OK,217,5,50,14
-    PUSHBUTTON      "Cancel",ID_BUTTON_CANCEL,217,22,50,14
+    DEFPUSHBUTTON   "&Close",ID_BUTTON_OK,145,150,50,13
     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
@@ -167,7 +145,7 @@
     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,133,29,12
+    LTEXT           "Serial:",IDC_STATIC_SERIAL,33,130,29,12
     COMBOBOX        IDC_COMBO_LETTER,31,20,78,60,CBS_DROPDOWNLIST  | 
                     WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "Browse...",IDC_BUTTON_BROWSE_PATH,154,5,40,13
@@ -181,7 +159,8 @@
     PUSHBUTTON      "Browse...",IDC_BUTTON_BROWSE_DEVICE,148,89,40,13
     CONTROL         "Manually Assign:",IDC_RADIO_ASSIGN,"Button",
                     BS_AUTORADIOBUTTON,21,104,69,10
-    GROUPBOX        "Label and Serial Number",IDC_BOX_LABELSERIAL,15,68,180,79
+    GROUPBOX        "Label and Serial Number",IDC_BOX_LABELSERIAL,6,68,189,79
+
 END
 
 STRINGTABLE DISCARDABLE 
Index: programs/winecfg/drive.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/drive.c,v
retrieving revision 1.5
diff -u -r1.5 drive.c
--- programs/winecfg/drive.c	10 Sep 2003 03:41:44 -0000	1.5
+++ programs/winecfg/drive.c	11 Sep 2003 14:47:19 -0000
@@ -43,6 +43,7 @@
 
 static BOOL updatingUI = FALSE;
 static char editWindowLetter; /* drive letter of the drive we are currently editing */
+static int lastSel = 0; /* the last drive selected in the property sheet */
 
 
 /* returns NULL on failure. caller is responsible for freeing result */
@@ -74,19 +75,58 @@
   return result;
 }
 
+/* call with newValue == NULL to remove a value */
 void setDriveValue(char letter, char *valueName, char *newValue) {
   char *driveSection = malloc(strlen("Drive X")+1);
   sprintf(driveSection, "Drive %c", letter);
-  addTransaction(driveSection, valueName, ACTION_SET, newValue);
+  if (newValue)
+    addTransaction(driveSection, valueName, ACTION_SET, newValue);
+  else
+    addTransaction(driveSection, valueName, ACTION_REMOVE, NULL);
   free(driveSection);
 }
 
-void refreshDriveDlg (HWND hDlg)
+/* copies a drive configuration branch */
+void copyDrive(char srcLetter, char destLetter) {
+  char *driveSection = alloca(strlen("Drive X")+1);
+  char *path, *label, *type, *serial, *fs;
+  
+  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");
+  fs = getDriveValue(srcLetter, "FileSystem");
+  
+  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 (fs)     addTransaction(driveSection, "FileSystem", ACTION_SET, fs);
+
+  if (path)   free(path);
+  if (label)  free(label);
+  if (type)   free(type);
+  if (serial) free(serial);
+  if (fs)     free(fs);
+}
+
+void removeDrive(char letter) {
+  char *driveSection = alloca(strlen("Drive X")+1);
+  sprintf(driveSection, "Drive %c", letter);
+  addTransaction(driveSection, NULL, ACTION_REMOVE, NULL);
+}
+
+int refreshDriveDlg (HWND hDlg)
 {
   int i;
   char *subKeyName = malloc(MAX_NAME_LENGTH);
   int driveCount = 0;
-  DWORD sizeOfSubKeyName;
+  DWORD sizeOfSubKeyName = MAX_NAME_LENGTH;
+  int doesDriveCExist = FALSE;
 
   WINE_TRACE("\n");
 
@@ -96,17 +136,19 @@
   SendMessageA(GetDlgItem(hDlg, 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 = 50) {
+       ++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;
       int titleLen;
       const char *itemLabel = "Drive %s (%s)";
       int itemIndex;
@@ -114,12 +156,13 @@
       if (RegOpenKeyExA (configKey, subKeyName, 0, KEY_READ, &hkDrive) != ERROR_SUCCESS)        {
         WINE_ERR("unable to open drive registry key");
         RegCloseKey(configKey);
-        return;
+        return -1;
       }
       
       /* extract the drive letter, force to upper case */
       driveLetter = subKeyName[strlen(subKeyName)-1];
-      if(driveLetter) driveLetter = toupper(driveLetter);
+      if (driveLetter) driveLetter = toupper(driveLetter);
+      if (driveLetter == 'C') doesDriveCExist = TRUE;
       
       ZeroMemory(returnBuffer, sizeof(*returnBuffer));
       sizeOfReturnBuffer = sizeof(returnBuffer);
@@ -132,23 +175,31 @@
         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 (%s) to the listbox\n", driveLetter, label);
+      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)");
       
-      if (!label) label = "no label";
       titleLen = strlen(itemLabel) - 1 + strlen(label) - 2 + 1;
       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);
+      snprintf(title, titleLen, "Drive %c: %s", driveLetter, label);
       
       /* the first SendMessage call adds the string and returns the index, the second associates that index with it */
       itemIndex = SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_ADDSTRING ,(WPARAM) -1, (LPARAM) title);
       SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETITEMDATA, itemIndex, (LPARAM) driveLetter);
       
       free(title);
-      if (label && (strcmp(label, "no label") != 0)) free(label);
+      free(label);
 
       driveCount++;
 	
@@ -156,11 +207,17 @@
   }
   
   WINE_TRACE("loaded %d drives\n", driveCount);
-  SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETSEL, TRUE, 0);
+  SendDlgItemMessage(hDlg, IDC_LIST_DRIVES, LB_SETSEL, TRUE, lastSel);
+
+  /* show the warning if there is no Drive C */
+  if (!doesDriveCExist)
+    ShowWindow(GetDlgItem(hDlg, IDS_DRIVE_NO_C), SW_NORMAL);
+  else
+    ShowWindow(GetDlgItem(hDlg, IDS_DRIVE_NO_C), SW_HIDE);
   
   free(subKeyName);  
   updatingUI = FALSE;
-  return;
+  return driveCount;
 }
 
 /******************************************************************************/
@@ -168,7 +225,7 @@
 /******************************************************************************/
 #define DRIVE_MASK_BIT(B) 1<<(toupper(B)-'A')
 
-typedef struct{
+typedef struct {
   char *sCode;
   char *sDesc;
 } code_desc_pair;
@@ -200,9 +257,11 @@
 
   for( i=0, count=0, selection=-1, next_letter=-1; i <= 'Z'-'A'; ++i ) {
     if( mask & DRIVE_MASK_BIT('A'+i) ) {
-      sName[0] = 'A' + i;
-      SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_ADDSTRING, 0, (LPARAM) sName );
+      int index;
       
+      sName[0] = 'A' + i;
+      index = SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_ADDSTRING, 0, (LPARAM) sName );
+			  
       if( toupper(currentLetter) == 'A' + i ) {
 	selection = count;
       }
@@ -222,18 +281,58 @@
   SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_SETCURSEL, selection, 0 );
 }
 
-/* if bEnable is 1 then we are editing a CDROM, so can enable all controls, otherwise we want to disable
- * "detect from device" and "serial number", but still allow the user to manually set the path. The UI
- * for this could be somewhat better -mike
- */
-void enable_labelserial_box(HWND hDlg, int bEnable)
+#define BOX_MODE_CD_ASSIGN 1
+#define BOX_MODE_CD_AUTODETECT 2
+#define BOX_MODE_NONE 3
+#define BOX_MODE_NORMAL 4
+void enable_labelserial_box(HWND hDlg, int mode)
 {
-  EnableWindow( GetDlgItem( hDlg, IDC_RADIO_AUTODETECT ), bEnable );
-  EnableWindow( GetDlgItem( hDlg, IDC_EDIT_DEVICE ), bEnable );
-  EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_BROWSE_DEVICE ), bEnable );
-  EnableWindow( GetDlgItem( hDlg, IDC_EDIT_SERIAL ), bEnable );
-  EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SERIAL ), bEnable );
-  EnableWindow( GetDlgItem( hDlg, IDC_STATIC_LABEL ), bEnable );
+  WINE_TRACE("mode=%d\n", mode);
+  switch (mode) {
+      case BOX_MODE_CD_ASSIGN:
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_AUTODETECT ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_ASSIGN ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_DEVICE ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_BROWSE_DEVICE ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_SERIAL ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_LABEL ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SERIAL ), 1);
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_LABEL ), 1);
+	break;
+	
+      case BOX_MODE_CD_AUTODETECT:
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_AUTODETECT ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_ASSIGN ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_DEVICE ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_BROWSE_DEVICE ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_SERIAL ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_LABEL ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SERIAL ), 0);
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_LABEL ), 0);
+	break;
+
+      case BOX_MODE_NONE:
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_AUTODETECT ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_ASSIGN ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_DEVICE ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_BROWSE_DEVICE ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_SERIAL ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_LABEL ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SERIAL ), 0);
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_LABEL ), 0);	
+	break;
+
+      case BOX_MODE_NORMAL:
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_AUTODETECT ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_RADIO_ASSIGN ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_DEVICE ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_BROWSE_DEVICE ), 0 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_SERIAL ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_EDIT_LABEL ), 1 );
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SERIAL ), 1);
+	EnableWindow( GetDlgItem( hDlg, IDC_STATIC_LABEL ), 1);
+	break;	
+  }
 }
 
 /* This function produces a mask for each drive letter that isn't currently used. Each bit of the long result
@@ -338,21 +437,16 @@
   } else WINE_WARN("no Device field?\n");
 
   selection = IDC_RADIO_ASSIGN;
-  if ((type && strcmp("cdrom", type) == 0) ||
-      (type && strcmp("floppy", type) == 0)) {
-    
-    if( (type && (strlen( device ) == 0)) &&
-	((serial && strlen( serial ) > 0) || (label && strlen( label ) > 0)) ) {
-      selection = IDC_RADIO_ASSIGN;
-    }
-    else {
+  if ((type && strcmp("cdrom", type) == 0) || (type && strcmp("floppy", type) == 0)) {
+    if (device) {
       selection = IDC_RADIO_AUTODETECT;
+      enable_labelserial_box(hDlg, BOX_MODE_CD_AUTODETECT);
+    } else {
+      selection = IDC_RADIO_ASSIGN;
+      enable_labelserial_box(hDlg, BOX_MODE_CD_ASSIGN);
     }
-    
-    enable_labelserial_box( hDlg, 1 );
-  }
-  else {
-    enable_labelserial_box( hDlg, 0 );
+  } else {
+    enable_labelserial_box(hDlg, BOX_MODE_NORMAL);
     selection = IDC_RADIO_ASSIGN;
   }
 
@@ -377,20 +471,40 @@
 void onEditChanged(HWND hDlg, WORD controlID) {
   WINE_TRACE("controlID=%d\n", controlID);
   switch (controlID) {
-      case IDC_EDIT_LABEL: { /* drive label edit box */
+      case IDC_EDIT_LABEL: {
         char *label = getDialogItemText(hDlg, controlID);
         setDriveValue(editWindowLetter, "Label", label);
         refreshDriveDlg(driveDlgHandle);
-        free(label);
+        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;
+      }
+      case IDC_EDIT_SERIAL: {
+	char *serial = getDialogItemText(hDlg, controlID);
+	setDriveValue(editWindowLetter, "Serial", 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;
+      }
   }
 }
 
 INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
   int selection;
-
+  
   switch (uMsg)  {
       case WM_INITDIALOG: {
 	editWindowLetter = (char) lParam;
@@ -400,21 +514,58 @@
     case WM_COMMAND:
       switch (LOWORD(wParam)) {
 	  case IDC_COMBO_TYPE:
-	    switch( HIWORD(wParam)) {
-		case CBN_SELCHANGE:
-		  selection = SendDlgItemMessage( hDlg, IDC_COMBO_TYPE, CB_GETCURSEL, 0, 0);
-		  if( selection == 2 || selection == 3 ) { /* cdrom or floppy */
-		    enable_labelserial_box( hDlg, 1 );
-		  }
-		  else {
-		    enable_labelserial_box( hDlg, 0 );
-		  }
-		  break;
+	    if (HIWORD(wParam) != CBN_SELCHANGE) break;
+	    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);
+	      else
+		enable_labelserial_box(hDlg, BOX_MODE_CD_ASSIGN);
+	    }
+	    else {
+	      enable_labelserial_box( hDlg, BOX_MODE_NORMAL );
 	    }
+	    setDriveValue(editWindowLetter, "Type", type_pairs[selection].sCode);
+	    break;
+
+	  case IDC_COMBO_LETTER: {
+	    int item = SendDlgItemMessage(hDlg, IDC_COMBO_LETTER, CB_GETCURSEL, 0, 0);
+	    char newLetter;
+	    SendDlgItemMessage(hDlg, IDC_COMBO_LETTER, CB_GETLBTEXT, item, (LPARAM) &newLetter);
+	    
+	    if (HIWORD(wParam) != CBN_SELCHANGE) break;
+	    if (newLetter == editWindowLetter) break;
+	    	    
+	    WINE_TRACE("changing drive letter to %c\n", newLetter);
+	    copyDrive(editWindowLetter, newLetter);
+	    removeDrive(editWindowLetter);
+	    editWindowLetter = newLetter;
+	    refreshDriveDlg(driveDlgHandle);
+	    break;
+	  }
+
+	  case IDC_BUTTON_BROWSE_PATH:
+	    WRITEME(hDlg);
+	    break;
+
+	  case IDC_RADIO_AUTODETECT: {
+	    setDriveValue(editWindowLetter, "Label", NULL);
+	    setDriveValue(editWindowLetter, "Serial", NULL);
+	    setDriveValue(editWindowLetter, "Device", getDialogItemText(hDlg, IDC_EDIT_DEVICE));
+	    enable_labelserial_box(hDlg, BOX_MODE_CD_AUTODETECT);
+	    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));
+	    enable_labelserial_box(hDlg, BOX_MODE_CD_ASSIGN);
+	    refreshDriveDlg(driveDlgHandle);
 	    break;
 	    
 	  case ID_BUTTON_OK:	  
-	  case ID_BUTTON_CANCEL:
 	    EndDialog(hDlg, wParam);
 	    return TRUE;
       }
@@ -429,7 +580,7 @@
      for now we will just force them to enter a path automatically, with / being the default. In future we should
      be able to temporarily map / then invoke the directory chooser dialog. */
   
-  char newLetter = 'D'; /* we skip A, B and of course C is already mapped, right? */
+  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;
   
@@ -444,14 +595,18 @@
   
   sectionName = malloc(strlen("Drive X") + 1);
   sprintf(sectionName, "Drive %c", newLetter);
-  addTransaction(sectionName, "Path", ACTION_SET, "/"); /* default to root path */
+  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);
 
   refreshDriveDlg(driveDlgHandle);
 
-  DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT2), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) newLetter);
+  DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) newLetter);
 }
 
 
@@ -459,16 +614,15 @@
 DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
   int selection = -1;
-
+  int nItem;
+  char letter;
+  
   switch (uMsg) {
       case WM_COMMAND:
 	switch (LOWORD(wParam)) {
 	    case IDC_LIST_DRIVES:
-	      switch(HIWORD( wParam )) {
-		  case LBN_DBLCLK:
-		    selection = -1;
-		    break;
-	      }
+	      if (HIWORD(wParam) == LBN_DBLCLK) selection = -1;
+	      if (HIWORD(wParam) == LBN_SELCHANGE) lastSel = SendDlgItemMessage(hDlg, IDC_LIST_DRIVES, LB_GETCURSEL, 0, 0);
 	      break;
 
 	    case IDC_BUTTON_ADD:
@@ -476,18 +630,23 @@
 	      break;
 
 	    case IDC_BUTTON_REMOVE:
-	      /* temporarily disabled, awaiting rewrite */
+	      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);
+	      refreshDriveDlg(driveDlgHandle);
 	      break;
 	      
 	    case IDC_BUTTON_EDIT:
-	      if (HIWORD(wParam) == BN_CLICKED) {
-		int nItem = SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES),  LB_GETCURSEL, 0, 0);
-		char letter = SendMessage(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_GETITEMDATA, nItem, 0);
-		
-		DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT2), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) letter);
-	      }
+	      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);
+	      break;
+
+	    case IDC_BUTTON_AUTODETECT:
+	      WRITEME(hDlg);
 	      break;
-	      
 	}
 	break;
 	
Index: programs/winecfg/resource.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/resource.h,v
retrieving revision 1.4
diff -u -r1.4 resource.h
--- programs/winecfg/resource.h	8 Sep 2003 18:58:07 -0000	1.4
+++ programs/winecfg/resource.h	11 Sep 2003 14:47:19 -0000
@@ -34,8 +34,7 @@
 #define IDD_DLLCFG                      110
 #define IDD_DRIVECFG                    111
 #define IDD_SYSTEMCFG                   112
-#define IDD_DRIVE_EDIT                  113
-#define IDD_DRIVE_EDIT2                 114
+#define IDD_DRIVE_EDIT                  114
 #define IDB_WINE_LOGO                   200
 #define IDC_TABABOUT                    1001
 #define IDC_APPLYBTN                    1002
@@ -102,3 +101,4 @@
 #define IDC_STATIC_SERIAL               1072
 #define IDC_STATIC_LABEL                1073
 #define IDC_ENABLE_DESKTOP              1074
+#define IDS_DRIVE_NO_C                  1075
Index: programs/winecfg/winecfg.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/winecfg.c,v
retrieving revision 1.10
diff -u -r1.10 winecfg.c
--- programs/winecfg/winecfg.c	10 Sep 2003 03:41:44 -0000	1.10
+++ programs/winecfg/winecfg.c	11 Sep 2003 14:47:21 -0000
@@ -178,6 +178,15 @@
     return S_OK;
 }
 
+/* removes the requested configuration section (subkey) from the registry, assuming it exists */
+/* this function might be slightly pointless, but in future we may wish to treat recursion specially etc, so we'll keep it for now */
+HRESULT removeConfigSection(char *section) {
+    HRESULT hr;
+    WINE_TRACE("section=%s\n", section);
+
+    return hr = RegDeleteKey(configKey, section);
+}
+
 
 /* ========================================================================= */
 /* Transaction management code */
@@ -191,7 +200,7 @@
     WINE_TRACE("destroying %p\n", trans);
     
     free(trans->section);
-    free(trans->key);
+    if (trans->key) free(trans->key);
     if (trans->newValue) free(trans->newValue);
     
     if (trans->next) trans->next->prev = trans->prev;
@@ -203,18 +212,16 @@
 }
 
 void addTransaction(char *section, char *key, enum transaction_action action, char *newValue) {
-    struct transaction *trans = malloc(sizeof(struct transaction));
+    struct transaction *trans = calloc(sizeof(struct transaction),1);
     
     assert( section != NULL );
-    assert( key != NULL );
     if (action == ACTION_SET) assert( newValue != NULL );
-
+    if (action == ACTION_SET) assert( key != NULL );
+				     
     trans->section = strdup(section);
-    trans->key = strdup(key);
-    trans->newValue = strdup(newValue);
+    if (key) trans->key = strdup(key);
+    if (newValue) trans->newValue = strdup(newValue);
     trans->action = action;
-    trans->next = NULL;
-    trans->prev = NULL;
     
     if (tqtail == NULL) {
 	tqtail = trans;
@@ -236,8 +243,14 @@
 	WINE_TRACE("Setting %s\\%s to '%s'\n", trans->section, trans->key, trans->newValue);
 	setConfigValue(trans->section, trans->key, trans->newValue);
     } else if (trans->action == ACTION_REMOVE) {
-	WINE_TRACE("Removing %s\\%s", trans->section, trans->key);
-	removeConfigValue(trans->section, trans->key);
+	if (trans->key) {
+	    WINE_TRACE("Removing %s\\%s\n", trans->section, trans->key);
+	    removeConfigValue(trans->section, trans->key);
+	} else {
+	    /* NULL key means remove that section entirely */
+	    WINE_TRACE("Removing section %s\n", trans->section);
+	    removeConfigSection(trans->section);
+	}
     }
     /* TODO: implement notifications here */
 }
@@ -253,7 +266,6 @@
     }
 }
 
-
 /* ================================== utility functions ============================ */
 
 /* returns a string with the window text of the dialog item. user is responsible for freeing the result */
@@ -264,3 +276,4 @@
     if (GetWindowText(item, result, len) == 0) return NULL;
     return result;
 }
+
Index: programs/winecfg/winecfg.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/winecfg.h,v
retrieving revision 1.8
diff -u -r1.8 winecfg.h
--- programs/winecfg/winecfg.h	10 Sep 2003 03:41:44 -0000	1.8
+++ programs/winecfg/winecfg.h	11 Sep 2003 14:47:21 -0000
@@ -43,6 +43,9 @@
 	return ret; \
     }
 
+#define WRITEME(owner) MessageBox(owner, "Write me!", "", MB_OK | MB_ICONEXCLAMATION);
+  
+
 /* Transaction management */
 enum transaction_action {
     ACTION_SET,





More information about the wine-patches mailing list