2004-11-23 14:50:23 +01:00
/*
* Drive management UI code
*
* Copyright 2003 Mark Westcott
* Copyright 2004 Chris Morgan
* Copyright 2003 - 2004 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 <stdarg.h>
# include <stdio.h>
# include <windef.h>
# include <winbase.h>
# include <winreg.h>
# include <shellapi.h>
# include <objbase.h>
# include <shlguid.h>
# include <shlwapi.h>
# include <shlobj.h>
# include <winuser.h>
# include <wine/debug.h>
# include "winecfg.h"
# include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL ( winecfg ) ;
# define BOX_MODE_CD_ASSIGN 1
# define BOX_MODE_CD_AUTODETECT 2
# define BOX_MODE_NONE 3
# define BOX_MODE_NORMAL 4
static BOOL advanced = FALSE ;
static BOOL updating_ui = FALSE ;
static struct drive * current_drive ;
static void get_etched_rect ( HWND dialog , RECT * rect ) ;
2005-01-09 19:00:46 +01:00
static void update_controls ( HWND dialog ) ;
2004-11-23 14:50:23 +01:00
2005-05-09 16:34:56 +02:00
/**** listview helper functions ****/
/* clears the item at index in the listview */
static void lv_clear_curr_select ( HWND dialog , int index )
{
ListView_SetItemState ( GetDlgItem ( dialog , IDC_LIST_DRIVES ) , index , 0 , LVIS_SELECTED ) ;
}
/* selects the item at index in the listview */
static void lv_set_curr_select ( HWND dialog , int index )
{
/* no more than one item can be selected in our listview */
lv_clear_curr_select ( dialog , - 1 ) ;
ListView_SetItemState ( GetDlgItem ( dialog , IDC_LIST_DRIVES ) , index , LVIS_SELECTED , LVIS_SELECTED ) ;
}
/* returns the currently selected item in the listview */
static int lv_get_curr_select ( HWND dialog )
{
return SendDlgItemMessage ( dialog , IDC_LIST_DRIVES , LVM_GETNEXTITEM , - 1 , LVNI_SELECTED ) ;
}
/* sets the item in the listview at item->iIndex */
static void lv_set_item ( HWND dialog , LVITEM * item )
{
SendDlgItemMessage ( dialog , IDC_LIST_DRIVES , LVM_SETITEM , 0 , ( LPARAM ) item ) ;
}
/* inserts an item into the listview */
static void lv_insert_item ( HWND dialog , LVITEM * item )
{
SendDlgItemMessage ( dialog , IDC_LIST_DRIVES , LVM_INSERTITEM , 0 , ( LPARAM ) item ) ;
}
/* retrieve the item at index item->iIndex */
static void lv_get_item ( HWND dialog , LVITEM * item )
{
SendDlgItemMessage ( dialog , IDC_LIST_DRIVES , LVM_GETITEM , 0 , ( LPARAM ) item ) ;
}
2004-11-23 14:50:23 +01:00
static void set_advanced ( HWND dialog )
{
int state ;
2005-05-19 13:14:52 +02:00
char text [ 256 ] ;
2004-11-23 14:50:23 +01:00
RECT rect ;
if ( advanced )
{
state = SW_NORMAL ;
2005-06-16 22:39:19 +02:00
LoadString ( GetModuleHandle ( NULL ) , IDS_HIDE_ADVANCED , text , 256 ) ;
2004-11-23 14:50:23 +01:00
}
else
{
state = SW_HIDE ;
2005-06-16 22:39:19 +02:00
LoadString ( GetModuleHandle ( NULL ) , IDS_SHOW_ADVANCED , text , 256 ) ;
2004-11-23 14:50:23 +01:00
}
ShowWindow ( GetDlgItem ( dialog , IDC_RADIO_AUTODETECT ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_RADIO_ASSIGN ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_EDIT_LABEL ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_EDIT_DEVICE ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_STATIC_LABEL ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_BUTTON_BROWSE_DEVICE ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_EDIT_SERIAL ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_STATIC_SERIAL ) , state ) ;
ShowWindow ( GetDlgItem ( dialog , IDC_LABELSERIAL_STATIC ) , state ) ;
/* update the button text based on the state */
SetWindowText ( GetDlgItem ( dialog , IDC_BUTTON_SHOW_HIDE_ADVANCED ) , text ) ;
/* redraw for the etched line */
get_etched_rect ( dialog , & rect ) ;
InflateRect ( & rect , 5 , 5 ) ;
InvalidateRect ( dialog , & rect , TRUE ) ;
}
struct drive_typemap {
2005-03-14 11:05:12 +01:00
unsigned int sCode ;
2004-11-23 14:50:23 +01:00
const char * sDesc ;
} ;
2005-03-14 11:05:12 +01:00
static const struct drive_typemap type_pairs [ ] = {
2004-11-23 14:50:23 +01:00
{ DRIVE_FIXED , " Local hard disk " } ,
{ DRIVE_REMOTE , " Network share " } ,
{ DRIVE_REMOVABLE , " Floppy disk " } ,
{ DRIVE_CDROM , " CD-ROM " }
} ;
# define DRIVE_TYPE_DEFAULT 1
2005-06-02 17:11:32 +02:00
static void fill_drive_droplist ( long mask , char curletter , HWND dialog )
2004-11-23 14:50:23 +01:00
{
int i ;
int selection ;
int count ;
int next_letter ;
2005-06-02 17:11:32 +02:00
char sName [ 4 ] ;
2004-11-23 14:50:23 +01:00
2005-06-02 17:11:32 +02:00
strcpy ( sName , " A: " ) ;
2004-11-23 14:50:23 +01:00
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 ( dialog , IDC_COMBO_LETTER , CB_ADDSTRING , 0 , ( LPARAM ) sName ) ;
if ( toupper ( curletter ) = = ' 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 ( dialog , IDC_COMBO_LETTER , CB_SETCURSEL , selection , 0 ) ;
}
2005-06-02 17:11:32 +02:00
static void enable_labelserial_box ( HWND dialog , int mode )
2004-11-23 14:50:23 +01:00
{
WINE_TRACE ( " mode=%d \n " , mode ) ;
switch ( mode )
{
case BOX_MODE_CD_ASSIGN :
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_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_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 :
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 ;
}
}
2005-06-02 17:11:32 +02:00
static int fill_drives_list ( HWND dialog )
2004-11-23 14:50:23 +01:00
{
int count = 0 ;
BOOL drivec_present = FALSE ;
int i ;
int prevsel = - 1 ;
WINE_TRACE ( " \n " ) ;
updating_ui = TRUE ;
2005-05-09 16:34:56 +02:00
prevsel = lv_get_curr_select ( dialog ) ;
2004-11-23 14:50:23 +01:00
/* Clear the listbox */
2005-05-09 16:34:56 +02:00
SendDlgItemMessage ( dialog , IDC_LIST_DRIVES , LVM_DELETEALLITEMS , 0 , 0 ) ;
2004-11-23 14:50:23 +01:00
for ( i = 0 ; i < 26 ; i + + )
{
2005-05-09 16:34:56 +02:00
LVITEM item ;
char * letter = 0 ;
2004-11-23 14:50:23 +01:00
int len ;
/* skip over any unused drives */
if ( ! drives [ i ] . in_use )
continue ;
if ( drives [ i ] . letter = = ' C ' )
drivec_present = TRUE ;
2005-05-09 16:34:56 +02:00
len = snprintf ( letter , 0 , " %c: " , ' A ' + i ) ;
2004-11-23 14:50:23 +01:00
len + + ; /* add a byte for the trailing null */
2005-05-09 16:34:56 +02:00
letter = HeapAlloc ( GetProcessHeap ( ) , 0 , len ) ;
snprintf ( letter , len , " %c: " , ' A ' + i ) ;
memset ( & item , 0 , sizeof ( item ) ) ;
item . mask = LVIF_TEXT ;
item . iItem = count ;
item . iSubItem = 0 ;
item . pszText = letter ;
item . cchTextMax = lstrlen ( item . pszText ) ;
2004-11-23 14:50:23 +01:00
2005-05-09 16:34:56 +02:00
lv_insert_item ( dialog , & item ) ;
2004-11-23 14:50:23 +01:00
2005-05-09 16:34:56 +02:00
item . iSubItem = 1 ;
item . pszText = drives [ i ] . unixpath ;
item . cchTextMax = lstrlen ( item . pszText ) ;
2004-11-23 14:50:23 +01:00
2005-05-09 16:34:56 +02:00
lv_set_item ( dialog , & item ) ;
item . mask = LVIF_PARAM ;
item . iSubItem = 0 ;
item . lParam = ( LPARAM ) & drives [ i ] ;
lv_set_item ( dialog , & item ) ;
HeapFree ( GetProcessHeap ( ) , 0 , letter ) ;
2004-11-23 14:50:23 +01:00
count + + ;
}
WINE_TRACE ( " loaded %d drives \n " , count ) ;
/* show the warning if there is no Drive C */
if ( ! drivec_present )
ShowWindow ( GetDlgItem ( dialog , IDS_DRIVE_NO_C ) , SW_NORMAL ) ;
else
ShowWindow ( GetDlgItem ( dialog , IDS_DRIVE_NO_C ) , SW_HIDE ) ;
2005-05-09 16:34:56 +02:00
lv_set_curr_select ( dialog , prevsel = = - 1 ? 0 : prevsel ) ;
2004-11-23 14:50:23 +01:00
updating_ui = FALSE ;
return count ;
}
2005-06-02 17:11:32 +02:00
static void on_options_click ( HWND dialog )
2005-05-18 11:48:47 +02:00
{
if ( IsDlgButtonChecked ( dialog , IDC_SHOW_DIRSYM_LINK ) = = BST_CHECKED )
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , " " , " ShowDirSymLinks " , " Y " ) ;
2005-05-18 11:48:47 +02:00
else
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , " " , " ShowDirSymLinks " , " N " ) ;
2005-05-18 11:48:47 +02:00
if ( IsDlgButtonChecked ( dialog , IDC_SHOW_DOT_FILES ) = = BST_CHECKED )
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , " " , " ShowDotFiles " , " Y " ) ;
2005-05-18 11:48:47 +02:00
else
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , " " , " ShowDotFiles " , " N " ) ;
2005-05-18 11:48:47 +02:00
}
2004-11-23 14:50:23 +01:00
2005-06-02 17:11:32 +02:00
static void on_add_click ( HWND dialog )
2004-11-23 14:50:23 +01:00
{
/* 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 new = ' 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 */
int i , c ;
while ( mask & ( 1 < < ( new - ' A ' ) ) )
{
new + + ;
if ( new > ' Z ' )
{
MessageBox ( dialog , " You cannot add any more drives. \n \n Each 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 " , new ) ;
if ( new = = ' C ' ) add_drive ( new , " ../drive_c " , " System Drive " , " " , DRIVE_FIXED ) ;
else add_drive ( new , " / " , " " , " " , DRIVE_FIXED ) ;
fill_drives_list ( dialog ) ;
/* select the newly created drive */
mask = ~ drive_available_mask ( 0 ) ;
c = 0 ;
for ( i = 0 ; i < 26 ; i + + )
{
if ( ' A ' + i = = new ) break ;
if ( ( 1 < < i ) & mask ) c + + ;
}
2005-05-09 16:34:56 +02:00
lv_set_curr_select ( dialog , c ) ;
2004-11-23 14:50:23 +01:00
SetFocus ( GetDlgItem ( dialog , IDC_LIST_DRIVES ) ) ;
2005-01-09 19:00:46 +01:00
update_controls ( dialog ) ;
2004-11-23 14:50:23 +01:00
}
2005-06-02 17:11:32 +02:00
static void on_remove_click ( HWND dialog )
2004-11-23 14:50:23 +01:00
{
2005-05-09 16:34:56 +02:00
int itemIndex ;
2004-11-23 14:50:23 +01:00
struct drive * drive ;
2005-05-09 16:34:56 +02:00
LVITEM item ;
itemIndex = lv_get_curr_select ( dialog ) ;
if ( itemIndex = = - 1 ) return ; /* no selection */
memset ( & item , 0 , sizeof ( item ) ) ;
item . mask = LVIF_PARAM ;
item . iItem = itemIndex ;
item . iSubItem = 0 ;
lv_get_item ( dialog , & item ) ;
drive = ( struct drive * ) item . lParam ;
2004-11-23 14:50:23 +01:00
2005-05-09 16:34:56 +02:00
WINE_ERR ( " unixpath: %s \n " , drive - > unixpath ) ;
2004-11-23 14:50:23 +01:00
if ( drive - > letter = = ' C ' )
{
DWORD result = MessageBox ( dialog , " Are you sure you want to delete drive C? \n \n Most Windows applications expect drive C to exist, and will die messily if it doesn't. If you proceed remember to recreate it! " , " " , MB_YESNO | MB_ICONEXCLAMATION ) ;
if ( result = = IDNO ) return ;
}
delete_drive ( drive ) ;
fill_drives_list ( dialog ) ;
2005-05-09 16:34:56 +02:00
itemIndex = itemIndex - 1 ;
if ( itemIndex < 0 ) itemIndex = 0 ;
lv_set_curr_select ( dialog , itemIndex ) ; /* previous item */
2004-11-23 14:50:23 +01:00
SetFocus ( GetDlgItem ( dialog , IDC_LIST_DRIVES ) ) ;
2005-01-09 19:00:46 +01:00
update_controls ( dialog ) ;
2004-11-23 14:50:23 +01:00
}
2005-01-09 19:00:46 +01:00
static void update_controls ( HWND dialog )
{
2004-11-23 14:50:23 +01:00
char * path ;
2005-03-14 11:05:12 +01:00
unsigned int type ;
2004-11-23 14:50:23 +01:00
char * label ;
char * serial ;
2005-06-02 17:11:32 +02:00
const char * device ;
2004-11-23 14:50:23 +01:00
int i , selection = - 1 ;
2005-05-09 16:34:56 +02:00
LVITEM item ;
2004-11-23 14:50:23 +01:00
updating_ui = TRUE ;
2005-05-09 16:34:56 +02:00
i = lv_get_curr_select ( dialog ) ;
2004-11-23 14:50:23 +01:00
if ( i = = - 1 )
{
/* no selection? let's select something for the user. this will re-enter */
2005-05-09 16:34:56 +02:00
lv_set_curr_select ( dialog , i ) ;
2004-11-23 14:50:23 +01:00
return ;
}
2005-05-09 16:34:56 +02:00
memset ( & item , 0 , sizeof ( item ) ) ;
item . mask = LVIF_PARAM ;
item . iItem = i ;
item . iSubItem = 0 ;
lv_get_item ( dialog , & item ) ;
current_drive = ( struct drive * ) item . lParam ;
2004-11-23 14:50:23 +01:00
WINE_TRACE ( " Updating sheet for drive %c \n " , current_drive - > letter ) ;
/* Drive letters */
fill_drive_droplist ( drive_available_mask ( current_drive - > letter ) , current_drive - > letter , dialog ) ;
/* path */
path = current_drive - > unixpath ;
WINE_TRACE ( " set path control text to '%s' \n " , path ) ;
set_text ( dialog , IDC_EDIT_PATH , path ) ;
/* drive type */
type = current_drive - > type ;
if ( type )
{
2005-01-19 17:59:48 +01:00
SendDlgItemMessage ( dialog , IDC_COMBO_TYPE , CB_RESETCONTENT , 0 , 0 ) ;
2004-11-23 14:50:23 +01:00
for ( i = 0 ; i < sizeof ( type_pairs ) / sizeof ( struct drive_typemap ) ; i + + )
{
SendDlgItemMessage ( dialog , IDC_COMBO_TYPE , CB_ADDSTRING , 0 , ( LPARAM ) type_pairs [ i ] . sDesc ) ;
if ( type_pairs [ i ] . sCode = = type )
{
selection = i ;
}
}
if ( selection = = - 1 ) selection = DRIVE_TYPE_DEFAULT ;
SendDlgItemMessage ( dialog , IDC_COMBO_TYPE , CB_SETCURSEL , selection , 0 ) ;
} else WINE_WARN ( " no Type field? \n " ) ;
/* removeable media properties */
label = current_drive - > label ;
set_text ( dialog , IDC_EDIT_LABEL , label ) ;
/* set serial edit text */
serial = current_drive - > serial ;
set_text ( dialog , IDC_EDIT_SERIAL , serial ) ;
/* TODO: get the device here to put into the edit box */
device = " Not implemented yet " ;
set_text ( dialog , IDC_EDIT_DEVICE , device ) ;
device = NULL ;
selection = IDC_RADIO_ASSIGN ;
if ( ( type = = DRIVE_CDROM ) | | ( type = = DRIVE_REMOVABLE ) )
{
if ( device )
{
selection = IDC_RADIO_AUTODETECT ;
enable_labelserial_box ( dialog , BOX_MODE_CD_AUTODETECT ) ;
}
else
{
selection = IDC_RADIO_ASSIGN ;
enable_labelserial_box ( dialog , BOX_MODE_CD_ASSIGN ) ;
}
}
else
{
enable_labelserial_box ( dialog , BOX_MODE_NORMAL ) ;
selection = IDC_RADIO_ASSIGN ;
}
CheckRadioButton ( dialog , IDC_RADIO_AUTODETECT , IDC_RADIO_ASSIGN , selection ) ;
updating_ui = FALSE ;
return ;
}
2005-06-02 17:11:32 +02:00
static void on_edit_changed ( HWND dialog , WORD id )
2004-11-23 14:50:23 +01:00
{
if ( updating_ui ) return ;
WINE_TRACE ( " edit id %d changed \n " , id ) ;
/* using fill_drives_list here is pretty lazy, but i'm tired
fortunately there are only 26 letters in the alphabet , so
we don ' t have to worry about efficiency too much here : ) */
switch ( id )
{
case IDC_EDIT_LABEL :
{
char * label ;
label = get_text ( dialog , id ) ;
2004-12-23 18:06:43 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , current_drive - > label ) ;
2004-11-23 14:50:23 +01:00
current_drive - > label = label ? label : strdupA ( " " ) ;
WINE_TRACE ( " set label to %s \n " , current_drive - > label ) ;
fill_drives_list ( dialog ) ;
break ;
}
case IDC_EDIT_PATH :
{
char * path ;
path = get_text ( dialog , id ) ;
2004-12-23 18:06:43 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , current_drive - > unixpath ) ;
2004-11-23 14:50:23 +01:00
current_drive - > unixpath = path ? path : strdupA ( " drive_c " ) ;
WINE_TRACE ( " set path to %s \n " , current_drive - > unixpath ) ;
fill_drives_list ( dialog ) ;
break ;
}
case IDC_EDIT_SERIAL :
{
char * serial ;
serial = get_text ( dialog , id ) ;
2004-12-23 18:06:43 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , current_drive - > serial ) ;
2004-11-23 14:50:23 +01:00
current_drive - > serial = serial ? serial : strdupA ( " " ) ;
WINE_TRACE ( " set serial to %s " , current_drive - > serial ) ;
break ;
}
case IDC_EDIT_DEVICE :
{
char * device = get_text ( dialog , id ) ;
/* TODO: handle device if/when it makes sense to do so.... */
2004-12-23 18:06:43 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , device ) ;
2004-11-23 14:50:23 +01:00
fill_drives_list ( dialog ) ;
break ;
}
}
}
static void get_etched_rect ( HWND dialog , RECT * rect )
{
GetClientRect ( dialog , rect ) ;
/* these dimensions from the labelserial static in En.rc */
2005-02-08 13:08:20 +01:00
rect - > top = 265 ;
rect - > bottom = 265 ;
rect - > left + = 25 ;
2004-11-23 14:50:23 +01:00
rect - > right - = 25 ;
}
/* this just draws a nice line to separate the advanced gui from the n00b gui :) */
static void paint ( HWND dialog )
{
PAINTSTRUCT ps ;
BeginPaint ( dialog , & ps ) ;
if ( advanced )
{
RECT rect ;
get_etched_rect ( dialog , & rect ) ;
DrawEdge ( ps . hdc , & rect , EDGE_ETCHED , BF_TOP ) ;
}
EndPaint ( dialog , & ps ) ;
}
2005-03-09 17:41:30 +01:00
static void browse_for_folder ( HWND dialog )
{
static WCHAR wszUnixRootDisplayName [ ] =
{ ' : ' , ' : ' , ' { ' , ' C ' , ' C ' , ' 7 ' , ' 0 ' , ' 2 ' , ' E ' , ' B ' , ' 2 ' , ' - ' , ' 7 ' , ' D ' , ' C ' , ' 5 ' , ' - ' , ' 1 ' , ' 1 ' , ' D ' , ' 9 ' , ' - ' ,
2005-05-07 16:50:16 +02:00
' C ' , ' 6 ' , ' 8 ' , ' 7 ' , ' - ' , ' 0 ' , ' 0 ' , ' 0 ' , ' 4 ' , ' 2 ' , ' 3 ' , ' 8 ' , ' A ' , ' 0 ' , ' 1 ' , ' C ' , ' D ' , ' } ' , 0 } ;
char pszChoosePath [ 256 ] ;
2005-03-09 17:41:30 +01:00
BROWSEINFOA bi = {
dialog ,
NULL ,
NULL ,
2005-05-07 16:50:16 +02:00
pszChoosePath ,
2005-03-09 17:41:30 +01:00
0 ,
NULL ,
0 ,
0
} ;
IShellFolder * pDesktop ;
LPITEMIDLIST pidlUnixRoot , pidlSelectedPath ;
HRESULT hr ;
2005-05-07 16:50:16 +02:00
LoadString ( GetModuleHandle ( NULL ) , IDS_CHOOSE_PATH , pszChoosePath , 256 ) ;
2005-03-09 17:41:30 +01:00
hr = SHGetDesktopFolder ( & pDesktop ) ;
if ( ! SUCCEEDED ( hr ) ) return ;
hr = pDesktop - > lpVtbl - > ParseDisplayName ( pDesktop , NULL , NULL , wszUnixRootDisplayName , NULL ,
& pidlUnixRoot , NULL ) ;
if ( ! SUCCEEDED ( hr ) ) {
pDesktop - > lpVtbl - > Release ( pDesktop ) ;
return ;
}
bi . pidlRoot = pidlUnixRoot ;
pidlSelectedPath = SHBrowseForFolderA ( & bi ) ;
SHFree ( pidlUnixRoot ) ;
if ( pidlSelectedPath ) {
STRRET strSelectedPath ;
char * pszSelectedPath ;
HRESULT hr ;
hr = pDesktop - > lpVtbl - > GetDisplayNameOf ( pDesktop , pidlSelectedPath , SHGDN_FORPARSING ,
& strSelectedPath ) ;
pDesktop - > lpVtbl - > Release ( pDesktop ) ;
if ( ! SUCCEEDED ( hr ) ) {
SHFree ( pidlSelectedPath ) ;
return ;
}
hr = StrRetToStr ( & strSelectedPath , pidlSelectedPath , & pszSelectedPath ) ;
SHFree ( pidlSelectedPath ) ;
if ( ! SUCCEEDED ( hr ) ) return ;
HeapFree ( GetProcessHeap ( ) , 0 , current_drive - > unixpath ) ;
current_drive - > unixpath = strdupA ( pszSelectedPath ) ;
fill_drives_list ( dialog ) ;
update_controls ( dialog ) ;
CoTaskMemFree ( pszSelectedPath ) ;
}
}
2005-05-09 16:34:56 +02:00
static void init_listview_columns ( HWND dialog )
{
LVCOLUMN listColumn ;
RECT viewRect ;
int width ;
GetClientRect ( GetDlgItem ( dialog , IDC_LIST_DRIVES ) , & viewRect ) ;
width = ( viewRect . right - viewRect . left ) / 6 - 5 ;
listColumn . mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM ;
2005-06-02 17:11:32 +02:00
listColumn . pszText = ( char * ) " Letter " ;
2005-05-09 16:34:56 +02:00
listColumn . cchTextMax = lstrlen ( listColumn . pszText ) ;
listColumn . cx = width ;
SendDlgItemMessage ( dialog , IDC_LIST_DRIVES , LVM_INSERTCOLUMN , 0 , ( LPARAM ) & listColumn ) ;
listColumn . cx = viewRect . right - viewRect . left - width ;
2005-06-02 17:11:32 +02:00
listColumn . pszText = ( char * ) " Drive Mapping " ;
2005-05-09 16:34:56 +02:00
listColumn . cchTextMax = lstrlen ( listColumn . pszText ) ;
SendDlgItemMessage ( dialog , IDC_LIST_DRIVES , LVM_INSERTCOLUMN , 1 , ( LPARAM ) & listColumn ) ;
}
2005-05-18 11:48:47 +02:00
static void load_drive_options ( HWND dialog )
{
2005-06-23 13:42:54 +02:00
if ( ! strcmp ( get_reg_key ( config_key , " " , " ShowDirSymLinks " , " N " ) , " Y " ) )
2005-05-18 11:48:47 +02:00
CheckDlgButton ( dialog , IDC_SHOW_DIRSYM_LINK , BST_CHECKED ) ;
2005-06-23 13:42:54 +02:00
if ( ! strcmp ( get_reg_key ( config_key , " " , " ShowDotFiles " , " N " ) , " Y " ) )
2005-05-18 11:48:47 +02:00
CheckDlgButton ( dialog , IDC_SHOW_DOT_FILES , BST_CHECKED ) ;
}
2005-05-09 16:34:56 +02:00
2004-11-23 14:50:23 +01:00
INT_PTR CALLBACK
DriveDlgProc ( HWND dialog , UINT msg , WPARAM wParam , LPARAM lParam )
{
int item ;
struct drive * drive ;
switch ( msg )
{
case WM_INITDIALOG :
2005-05-09 16:34:56 +02:00
init_listview_columns ( dialog ) ;
2004-11-23 14:50:23 +01:00
load_drives ( ) ;
2005-05-18 11:48:47 +02:00
load_drive_options ( dialog ) ;
2004-11-23 14:50:23 +01:00
if ( ! drives [ 2 ] . in_use )
MessageBox ( dialog , " You don't have a drive C. This is not so great. \n \n Remember to click 'Add' in the Drives tab to create one! \n " , " " , MB_OK | MB_ICONEXCLAMATION ) ;
fill_drives_list ( dialog ) ;
update_controls ( dialog ) ;
/* put in non-advanced mode by default */
set_advanced ( dialog ) ;
break ;
case WM_SHOWWINDOW :
set_window_title ( dialog ) ;
break ;
case WM_PAINT :
paint ( dialog ) ;
break ;
case WM_COMMAND :
2005-05-18 11:48:47 +02:00
switch ( HIWORD ( wParam ) )
2004-11-23 14:50:23 +01:00
{
2005-05-18 11:48:47 +02:00
case EN_CHANGE :
on_edit_changed ( dialog , LOWORD ( wParam ) ) ;
break ;
case BN_CLICKED :
SendMessage ( GetParent ( dialog ) , PSM_CHANGED , 0 , 0 ) ;
switch ( LOWORD ( wParam ) )
{
case IDC_SHOW_DIRSYM_LINK :
case IDC_SHOW_DOT_FILES :
on_options_click ( dialog ) ;
break ;
}
break ;
2004-11-23 14:50:23 +01:00
}
switch ( LOWORD ( wParam ) )
{
case IDC_BUTTON_ADD :
if ( HIWORD ( wParam ) ! = BN_CLICKED ) break ;
on_add_click ( dialog ) ;
break ;
case IDC_BUTTON_REMOVE :
if ( HIWORD ( wParam ) ! = BN_CLICKED ) break ;
on_remove_click ( dialog ) ;
break ;
case IDC_BUTTON_EDIT :
if ( HIWORD ( wParam ) ! = BN_CLICKED ) break ;
item = SendMessage ( GetDlgItem ( dialog , IDC_LIST_DRIVES ) , LB_GETCURSEL , 0 , 0 ) ;
drive = ( struct drive * ) SendMessage ( GetDlgItem ( dialog , IDC_LIST_DRIVES ) , LB_GETITEMDATA , item , 0 ) ;
/*DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) drive); */
break ;
case IDC_BUTTON_AUTODETECT :
autodetect_drives ( ) ;
fill_drives_list ( dialog ) ;
break ;
case IDC_BUTTON_SHOW_HIDE_ADVANCED :
advanced = ! advanced ;
set_advanced ( dialog ) ;
break ;
case IDC_BUTTON_BROWSE_PATH :
2005-03-09 17:41:30 +01:00
browse_for_folder ( dialog ) ;
2004-11-23 14:50:23 +01:00
break ;
case IDC_RADIO_ASSIGN :
{
char * str ;
str = get_text ( dialog , IDC_EDIT_LABEL ) ;
2004-12-23 18:06:43 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , current_drive - > label ) ;
2004-11-23 14:50:23 +01:00
current_drive - > label = str ? str : strdupA ( " " ) ;
str = get_text ( dialog , IDC_EDIT_SERIAL ) ;
2004-12-23 18:06:43 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , current_drive - > serial ) ;
2004-11-23 14:50:23 +01:00
current_drive - > serial = str ? str : strdupA ( " " ) ;
/* TODO: we don't have a device at this point */
enable_labelserial_box ( dialog , BOX_MODE_CD_ASSIGN ) ;
break ;
}
case IDC_COMBO_TYPE :
{
int mode = BOX_MODE_NORMAL ;
int selection ;
if ( HIWORD ( wParam ) ! = CBN_SELCHANGE ) break ;
selection = SendDlgItemMessage ( dialog , IDC_COMBO_TYPE , CB_GETCURSEL , 0 , 0 ) ;
if ( selection = = 2 | | selection = = 3 ) /* cdrom or floppy */
{
if ( IsDlgButtonChecked ( dialog , IDC_RADIO_AUTODETECT ) )
mode = BOX_MODE_CD_AUTODETECT ;
else
mode = BOX_MODE_CD_ASSIGN ;
}
enable_labelserial_box ( dialog , mode ) ;
current_drive - > type = type_pairs [ selection ] . sCode ;
break ;
}
}
break ;
case WM_NOTIFY :
switch ( ( ( LPNMHDR ) lParam ) - > code )
{
case PSN_KILLACTIVE :
WINE_TRACE ( " PSN_KILLACTIVE \n " ) ;
2005-02-15 22:51:06 +01:00
SetWindowLongPtr ( dialog , DWLP_MSGRESULT , FALSE ) ;
2004-11-23 14:50:23 +01:00
break ;
case PSN_APPLY :
apply_drive_changes ( ) ;
2005-02-15 22:51:06 +01:00
SetWindowLongPtr ( dialog , DWLP_MSGRESULT , PSNRET_NOERROR ) ;
2004-11-23 14:50:23 +01:00
break ;
case PSN_SETACTIVE :
break ;
}
2005-05-10 15:14:49 +02:00
switch ( ( ( LPNMITEMACTIVATE ) lParam ) - > hdr . code )
{
case NM_CLICK :
update_controls ( dialog ) ;
break ;
}
2004-11-23 14:50:23 +01:00
break ;
}
return FALSE ;
}