/*
 * Drive management UI code
 *
 * Copyright 2003 Mark Westcott
 * Copyright 2003 Mike Hearn
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#include <wine/debug.h>
#include <shellapi.h>
#include <objbase.h>
#include <shlguid.h>
#include <shlwapi.h>
#include <shlobj.h>

#include "winecfg.h"
#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(winecfg);

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 */
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;
}

/* 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);
}

/* 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 = MAX_NAME_LENGTH;
  int doesDriveCExist = FALSE;

  WINE_TRACE("\n");

  updatingUI = TRUE;

  /* Clear the listbox */
  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 = 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;
      
      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;
      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);
      
      /* 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);
      free(label);

      driveCount++;
	
    }
  }
  
  WINE_TRACE("loaded %d drives\n", driveCount);
  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 driveCount;
}

/******************************************************************************/
/*  The Drive Editing Dialog                                                  */
/******************************************************************************/
#define DRIVE_MASK_BIT(B) 1<<(toupper(B)-'A')

typedef struct {
  const char *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"}
};
#define DRIVE_TYPE_DEFAULT 1

static code_desc_pair fs_pairs[] = {
  {"win95", "Long file names"},
  {"msdos", "MS-DOS 8 character file names"},
  {"unix", "UNIX file names"}
};
 
#define DRIVE_FS_DEFAULT 0


void fill_drive_droplist(long mask, char currentLetter, HWND hDlg)
{
  int i;
  int selection;
  int count;
  int next_letter;
  char sName[4] = "A:";

  for( i=0, count=0, selection=-1, next_letter=-1; i <= 'Z'-'A'; ++i ) {
    if( mask & DRIVE_MASK_BIT('A'+i) ) {
      int index;
      
      sName[0] = 'A' + i;
      index = SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_ADDSTRING, 0, (LPARAM) sName );
			  
      if( toupper(currentLetter) == 'A' + i ) {
	selection = count;
      }
      
      if( i >= 2 && next_letter == -1){ /*default drive is first one of C-Z */
	next_letter = count;
      }
      
      count++;
    }
  }
  
  if( selection == -1 ) {
    selection = next_letter;
  }
  
  SendDlgItemMessage( hDlg, IDC_COMBO_LETTER, CB_SETCURSEL, selection, 0 );
}

#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 dialog, int mode)
{
  WINE_TRACE("mode=%d\n", mode);
  switch (mode) {
      case BOX_MODE_CD_ASSIGN:
	enable(IDC_RADIO_AUTODETECT);
	enable(IDC_RADIO_ASSIGN);
	disable(IDC_EDIT_DEVICE);
	disable(IDC_BUTTON_BROWSE_DEVICE);
	enable(IDC_EDIT_SERIAL);
	enable(IDC_EDIT_LABEL);
	enable(IDC_STATIC_SERIAL);
	enable(IDC_STATIC_LABEL);
	break;
	
      case BOX_MODE_CD_AUTODETECT:
	enable(IDC_RADIO_AUTODETECT);
	enable(IDC_RADIO_ASSIGN);
	enable(IDC_EDIT_DEVICE);
	enable(IDC_BUTTON_BROWSE_DEVICE);
	disable(IDC_EDIT_SERIAL);
	disable(IDC_EDIT_LABEL);
	disable(IDC_STATIC_SERIAL);
	disable(IDC_STATIC_LABEL);
	break;

      case BOX_MODE_NONE:
	disable(IDC_RADIO_AUTODETECT);
	disable(IDC_RADIO_ASSIGN);
	disable(IDC_EDIT_DEVICE);
	disable(IDC_BUTTON_BROWSE_DEVICE);
	disable(IDC_EDIT_SERIAL);
	disable(IDC_EDIT_LABEL);
	disable(IDC_STATIC_SERIAL);
	disable(IDC_STATIC_LABEL);
	break;

      case BOX_MODE_NORMAL:
	disable(IDC_RADIO_AUTODETECT);
	enable(IDC_RADIO_ASSIGN);
	disable(IDC_EDIT_DEVICE);
	disable(IDC_BUTTON_BROWSE_DEVICE);
	enable(IDC_EDIT_SERIAL);
	enable(IDC_EDIT_LABEL);
	enable(IDC_STATIC_SERIAL);
	enable(IDC_STATIC_LABEL);
	break;	
  }
}

/* This function produces a mask for each drive letter that isn't currently used. Each bit of the long result
 * represents a letter, with A being the least significant bit, and Z being the most significant.
 *
 * To calculate this, we loop over each letter, and see if we can get a drive entry for it. If so, we
 * set the appropriate bit. At the end, we flip each bit, to give the desired result.
 *
 * The letter parameter is always marked as being available. This is so the edit dialog can display the
 * currently used drive letter alongside the available ones.
 */
long drive_available_mask(char letter)
{
  long result = 0;
  char curLetter;
  char *slop;
  
  WINE_TRACE("\n");
 
  for (curLetter = 'A'; curLetter < 'Z'; curLetter++) {
    slop = getDriveValue(curLetter, "Path");
    if (slop != NULL) {
      result |= DRIVE_MASK_BIT(curLetter);
      free(slop);
    }
  }
  
  result = ~result;
  if (letter) result |= DRIVE_MASK_BIT(letter);
  
  WINE_TRACE( "finished drive letter loop with %lx\n", result );
  return result;
}


void refreshDriveEditDialog(HWND hDlg) {
  char *path;
  char *type;
  char *fs;
  char *serial;
  char *label;
  char *device;
  int i, selection;

  updatingUI = TRUE;
  
  /* Drive letters */
  fill_drive_droplist( drive_available_mask( editWindowLetter ), editWindowLetter, hDlg );

  /* path */
  path = getDriveValue(editWindowLetter, "Path");
  if (path) {
    SetWindowText(GetDlgItem(hDlg, IDC_EDIT_PATH), path);
  } else WINE_WARN("no Path field?\n");
  
  /* drive type */
  type = getDriveValue(editWindowLetter, "Type");
  if (type) {
    for(i = 0, selection = -1; i < sizeof(type_pairs)/sizeof(code_desc_pair); i++) {
      SendDlgItemMessage(hDlg, IDC_COMBO_TYPE, CB_ADDSTRING, 0,
			 (LPARAM) type_pairs[i].sDesc);
      if(strcasecmp(type_pairs[i].sCode, type) == 0){
	selection = i;
      }
    }
  
    if( selection == -1 ) selection = DRIVE_TYPE_DEFAULT;
    SendDlgItemMessage(hDlg, IDC_COMBO_TYPE, CB_SETCURSEL, selection, 0);
  } else WINE_WARN("no Type field?\n");

  
  /* FileSystem name handling */
  fs = getDriveValue(editWindowLetter, "FileSystem");
  if (fs) {
    for( i=0, selection=-1; i < sizeof(fs_pairs)/sizeof(code_desc_pair); i++) {
      SendDlgItemMessage(hDlg, IDC_COMBO_NAMES, CB_ADDSTRING, 0,
			 (LPARAM) fs_pairs[i].sDesc);
      if(strcasecmp(fs_pairs[i].sCode, fs) == 0){
	selection = i;
      }
    }
  
    if( selection == -1 ) selection = DRIVE_FS_DEFAULT;
    SendDlgItemMessage(hDlg, IDC_COMBO_NAMES, CB_SETCURSEL, selection, 0);
  } else WINE_WARN("no FileSystem field?\n");


  /* removeable media properties */
  serial = getDriveValue(editWindowLetter, "Serial");
  if (serial) {
    SendDlgItemMessage(hDlg, IDC_EDIT_SERIAL, WM_SETTEXT, 0,(LPARAM)serial);
  } else WINE_WARN("no Serial field?\n");

  label = getDriveValue(editWindowLetter, "Label");
  if (label) {
    SendDlgItemMessage(hDlg, IDC_EDIT_LABEL, WM_SETTEXT, 0,(LPARAM)label);
  } else WINE_WARN("no Label field?\n");

  device = getDriveValue(editWindowLetter, "Device");
  if (device) {
    SendDlgItemMessage(hDlg, 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 (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);
    }
  } else {
    enable_labelserial_box(hDlg, BOX_MODE_NORMAL);
    selection = IDC_RADIO_ASSIGN;
  }

  CheckRadioButton( hDlg, IDC_RADIO_AUTODETECT, IDC_RADIO_ASSIGN, selection );
  if (path) SendDlgItemMessage(hDlg, IDC_EDIT_PATH, WM_SETTEXT, 0,(LPARAM)path);
  
  if (path) free(path);
  if (type) free(type);
  if (fs) free(fs);
  if (serial) free(serial);
  if (label) free(label);
  if (device) free(device);

  updatingUI = FALSE;
  
  return;
}

/* storing the drive propsheet HWND here is a bit ugly, but the simplest solution for now */
static HWND driveDlgHandle;

void onEditChanged(HWND hDlg, WORD controlID) {
  WINE_TRACE("controlID=%d\n", controlID);
  switch (controlID) {
      case IDC_EDIT_LABEL: {
        char *label = getDialogItemText(hDlg, controlID);
        setDriveValue(editWindowLetter, "Label", 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;
      }
      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;
	refreshDriveEditDialog(hDlg);
      }

    case WM_COMMAND:
      switch (LOWORD(wParam)) {
	  case IDC_COMBO_TYPE:
	    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:	  
	    EndDialog(hDlg, wParam);
	    return TRUE;
      }
      if (HIWORD(wParam) == EN_CHANGE) onEditChanged(hDlg, LOWORD(wParam));
      break;
  }
  return FALSE;
}

void onAddDriveClicked(HWND hDlg) {
  /* we should allocate a drive letter automatically. We also need some way to let the user choose the mapping point,
     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 = '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++;
    if (newLetter > 'Z') {
      MessageBox(NULL, "You cannot add any more drives.\n\nEach drive must have a letter, from A to Z, so you cannot have more than 26", "", MB_OK | MB_ICONEXCLAMATION);
      return;
    }
  }
  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);

  refreshDriveDlg(driveDlgHandle);

  DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) newLetter);
}


INT_PTR CALLBACK
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:
	      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:
	      onAddDriveClicked(hDlg);
	      break;

	    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);
	      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);
	      break;

	    case IDC_BUTTON_AUTODETECT:
	      WRITEME(hDlg);
	      break;
	}
	break;
	
      case WM_NOTIFY: switch(((LPNMHDR)lParam)->code) {
	    case PSN_KILLACTIVE:
	      SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
	      break;
	    case PSN_APPLY:
	      SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
	      break;
	    case PSN_SETACTIVE:
	      driveDlgHandle = hDlg;
	      refreshDriveDlg (driveDlgHandle);
	      break;
	}
	break;

  }

  return FALSE;
}
