- More heapification.
- Split drive code into core, UI and autodetect. - Implement drive autodetection. - Slight redesign of drive tab. - Code cleanup.
This commit is contained in:
parent
14de4815b3
commit
7d8711e15f
|
@ -26,7 +26,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
|
||||
IDD_ABOUTCFG DIALOGEX 0, 0, 260, 250
|
||||
STYLE WS_CHILD
|
||||
FONT 8, "MS Shell Dlg"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Wine Version:",IDC_STATIC,119,17,55,8
|
||||
LTEXT "CVS",IDC_WINEVER,179,17,56,8
|
||||
|
@ -40,7 +40,7 @@ END
|
|||
|
||||
IDD_APPCFG DIALOG DISCARDABLE 0, 0, 260, 250
|
||||
STYLE WS_CHILD | WS_DISABLED
|
||||
FONT 8, "MS Shell Dlg"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
GROUPBOX " Application Settings ",IDC_STATIC, 8,4,244,240
|
||||
LTEXT "Wine can mimic different Windows versions for each application.",
|
||||
|
@ -57,7 +57,7 @@ END
|
|||
|
||||
IDD_GRAPHCFG DIALOG DISCARDABLE 0, 0, 260, 250
|
||||
STYLE WS_CHILD | WS_DISABLED
|
||||
FONT 8, "MS Shell Dlg"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Screen color depth: ",IDC_STATIC,8,10,70,30
|
||||
COMBOBOX IDC_SCREEN_DEPTH,80,8,170,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
|
@ -81,7 +81,7 @@ END
|
|||
|
||||
IDD_DLLCFG DIALOG DISCARDABLE 0, 0, 260, 250
|
||||
STYLE WS_CHILD | WS_DISABLED
|
||||
FONT 8, "MS Shell Dlg"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
GROUPBOX " DLL Overrides ",IDC_STATIC,8,4,244,240
|
||||
LTEXT "Dynamic Link Libraries can be specified individually to be either builtin (provided by Wine) or native (taken from Windows or provided by the application)."
|
||||
|
@ -98,62 +98,44 @@ BEGIN
|
|||
PUSHBUTTON "&Remove DLL override",IDC_DLLS_REMOVEDLL,163,224,82,14
|
||||
END
|
||||
|
||||
IDD_SYSTEMCFG DIALOG DISCARDABLE 0, 0, 260, 250
|
||||
STYLE WS_CHILD
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
GROUPBOX "Drives",IDC_STATIC,8,4,244,120
|
||||
LISTBOX IDC_LIST_DRIVES,15,23,179,90,WS_VSCROLL
|
||||
PUSHBUTTON "&Add",IDC_DRIVE_ADD,197,22,50,22
|
||||
PUSHBUTTON "&Remove",IDC_DRIVE_REMOVE,197,51,50,22
|
||||
PUSHBUTTON "&Edit",IDC_DRIVE_EDIT,197,80,50,22
|
||||
END
|
||||
|
||||
IDD_DRIVECFG DIALOG DISCARDABLE 0, 0, 260, 250
|
||||
STYLE WS_CHILD | WS_DISABLED
|
||||
FONT 8, "MS Shell Dlg"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
GROUPBOX "Drive Mappings",IDC_STATIC,7,107,246,112
|
||||
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
|
||||
GROUPBOX " Drive mappings ",IDC_STATIC,8,4,244,240
|
||||
LISTBOX IDC_LIST_DRIVES,15,18,232,76,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "&Add...",IDC_BUTTON_ADD,15,98,37,14
|
||||
PUSHBUTTON "&Remove",IDC_BUTTON_REMOVE,56,98,37,14
|
||||
PUSHBUTTON "Auto&detect...",IDC_BUTTON_AUTODETECT,197,98,49,14
|
||||
|
||||
/* editing drive details */
|
||||
LTEXT "&Path:",IDC_STATIC,15,123,20,9
|
||||
EDITTEXT IDC_EDIT_PATH,41,120,160,13,ES_AUTOHSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "&Browse...",IDC_BUTTON_BROWSE_PATH,206,120,40,13
|
||||
|
||||
LTEXT "&Type:",IDC_STATIC_TYPE,15,138,21,10
|
||||
COMBOBOX IDC_COMBO_TYPE,41,135,77,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "Label and serial number",IDC_LABELSERIAL_STATIC,15,155,55,10
|
||||
|
||||
PUSHBUTTON "&Show Advanced",IDC_BUTTON_SHOW_HIDE_ADVANCED,186,136,60,13
|
||||
CONTROL "Autodetect &from Device:",IDC_RADIO_AUTODETECT,"Button",
|
||||
BS_AUTORADIOBUTTON,15,166,93,10
|
||||
EDITTEXT IDC_EDIT_DEVICE,27,176,174,13,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Bro&wse...",IDC_BUTTON_BROWSE_DEVICE,206,176,40,13
|
||||
CONTROL "&Manually Assign:",IDC_RADIO_ASSIGN,"Button",
|
||||
BS_AUTORADIOBUTTON,15,195,69,10
|
||||
|
||||
LTEXT "&Label:",IDC_STATIC_LABEL,33,208,29,12
|
||||
EDITTEXT IDC_EDIT_LABEL,63,205,78,13,ES_AUTOHSCROLL | WS_TABSTOP
|
||||
LTEXT "S&erial:",IDC_STATIC_SERIAL,33,225,29,12
|
||||
EDITTEXT IDC_EDIT_SERIAL,63,221,78,13,ES_AUTOHSCROLL | WS_TABSTOP
|
||||
|
||||
IDD_DRIVE_EDIT DIALOG DISCARDABLE 0, 0, 203, 169
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Drive Configuration"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "&Ok",ID_BUTTON_OK,145,150,50,16
|
||||
LTEXT "Letter:",IDC_STATIC,5,23,26,9
|
||||
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,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,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,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,98,69,10
|
||||
GROUPBOX "Label and serial number",IDC_BOX_LABELSERIAL,6,58,189,85
|
||||
END
|
||||
|
||||
IDD_AUDIOCFG DIALOG DISCARDABLE 0, 0, 260, 250
|
||||
STYLE WS_CHILD | WS_DISABLED
|
||||
FONT 8, "MS Shell Dlg"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Audio driver: ",IDC_STATIC,10,20,60,8
|
||||
COMBOBOX IDC_AUDIO_DRIVER,70,18,85,85,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
|
|
|
@ -10,6 +10,8 @@ C_SRCS = \
|
|||
appdefaults.c \
|
||||
audio.c \
|
||||
drive.c \
|
||||
drivedetect.c \
|
||||
driveui.c \
|
||||
libraries.c \
|
||||
main.c \
|
||||
properties.c \
|
||||
|
|
|
@ -105,7 +105,7 @@ init_comboboxes (HWND dialog)
|
|||
SendDlgItemMessage(dialog, IDC_DOSVER, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
/* add the default entries (automatic) which correspond to no setting */
|
||||
if (currentApp)
|
||||
if (current_app)
|
||||
{
|
||||
SendDlgItemMessage(dialog, IDC_WINVER, CB_ADDSTRING, 0, (LPARAM) "Use global settings");
|
||||
SendDlgItemMessage(dialog, IDC_DOSVER, CB_ADDSTRING, 0, (LPARAM) "Use global settings");
|
||||
|
@ -173,7 +173,7 @@ static void init_appsheet(HWND dialog)
|
|||
size = sizeof(appname);
|
||||
while (RegEnumKeyEx(key, i, appname, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||
{
|
||||
add_listview_item(listview, appname, strdup(appname));
|
||||
add_listview_item(listview, appname, strdupA(appname));
|
||||
|
||||
i++;
|
||||
size = sizeof(appname);
|
||||
|
@ -219,7 +219,7 @@ static int get_listview_selection(HWND listview)
|
|||
static void on_selection_change(HWND dialog, HWND listview)
|
||||
{
|
||||
LVITEM item;
|
||||
char *oldapp = currentApp;
|
||||
char *oldapp = current_app;
|
||||
|
||||
WINE_TRACE("()\n");
|
||||
|
||||
|
@ -230,23 +230,23 @@ static void on_selection_change(HWND dialog, HWND listview)
|
|||
|
||||
ListView_GetItem(listview, &item);
|
||||
|
||||
currentApp = (char *) item.lParam;
|
||||
current_app = (char *) item.lParam;
|
||||
|
||||
if (currentApp)
|
||||
if (current_app)
|
||||
{
|
||||
WINE_TRACE("currentApp is now %s\n", currentApp);
|
||||
WINE_TRACE("current_app is now %s\n", current_app);
|
||||
enable(IDC_APP_REMOVEAPP);
|
||||
}
|
||||
else
|
||||
{
|
||||
WINE_TRACE("currentApp=NULL, editing global settings\n");
|
||||
WINE_TRACE("current_app=NULL, editing global settings\n");
|
||||
/* focus will never be on the button in this callback so it's safe */
|
||||
disable(IDC_APP_REMOVEAPP);
|
||||
}
|
||||
|
||||
/* reset the combo boxes if we changed from/to global/app-specific */
|
||||
|
||||
if ((oldapp && !currentApp) || (!oldapp && currentApp))
|
||||
if ((oldapp && !current_app) || (!oldapp && current_app))
|
||||
init_comboboxes(dialog);
|
||||
|
||||
update_comboboxes(dialog);
|
||||
|
@ -276,12 +276,12 @@ static void on_add_app_click(HWND dialog)
|
|||
HWND listview = GetDlgItem(dialog, IDC_APP_LISTVIEW);
|
||||
int count = ListView_GetItemCount(listview);
|
||||
|
||||
if (currentApp) free(currentApp);
|
||||
currentApp = strdup(filetitle);
|
||||
if (current_app) HeapFree(GetProcessHeap(), 0, current_app);
|
||||
current_app = strdupA(filetitle);
|
||||
|
||||
WINE_TRACE("adding %s\n", currentApp);
|
||||
WINE_TRACE("adding %s\n", current_app);
|
||||
|
||||
add_listview_item(listview, currentApp, currentApp);
|
||||
add_listview_item(listview, current_app, current_app);
|
||||
|
||||
ListView_SetItemState(listview, count, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
||||
|
||||
|
@ -375,9 +375,11 @@ AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch(HIWORD(wParam)) {
|
||||
switch(HIWORD(wParam))
|
||||
{
|
||||
case CBN_SELCHANGE:
|
||||
switch(LOWORD(wParam)) {
|
||||
switch(LOWORD(wParam))
|
||||
{
|
||||
case IDC_WINVER:
|
||||
on_winver_change(hDlg);
|
||||
break;
|
||||
|
@ -386,7 +388,8 @@ AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
}
|
||||
case BN_CLICKED:
|
||||
switch(LOWORD(wParam)) {
|
||||
switch(LOWORD(wParam))
|
||||
{
|
||||
case IDC_APP_ADDAPP:
|
||||
on_add_app_click(hDlg);
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Drive autodetection code
|
||||
*
|
||||
* Copyright 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 <wine/debug.h>
|
||||
#include <wine/library.h>
|
||||
|
||||
#include "winecfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mntent.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <winbase.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
|
||||
|
||||
BOOL gui_mode = TRUE;
|
||||
static long working_mask = 0;
|
||||
|
||||
static char *ignored_fstypes[] = {
|
||||
"devpts",
|
||||
"tmpfs",
|
||||
"proc",
|
||||
"sysfs",
|
||||
"swap",
|
||||
"usbdevfs",
|
||||
"rpc_pipefs",
|
||||
NULL
|
||||
};
|
||||
|
||||
static BOOL should_ignore_fstype(char *type)
|
||||
{
|
||||
char **s;
|
||||
|
||||
for (s = ignored_fstypes; *s; s++)
|
||||
if (!strcmp(*s, type)) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL is_drive_defined(char *path)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 26; i++)
|
||||
if (drives[i].in_use && !strcmp(drives[i].unixpath, path)) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* returns Z + 1 if there are no more available letters */
|
||||
static char allocate_letter()
|
||||
{
|
||||
char letter;
|
||||
|
||||
for (letter = 'C'; letter <= 'Z'; letter++)
|
||||
if ((DRIVE_MASK_BIT(letter) & working_mask) != 0) break;
|
||||
|
||||
return letter;
|
||||
}
|
||||
|
||||
#define FSTAB_OPEN 1
|
||||
#define NO_MORE_LETTERS 2
|
||||
#define NO_ROOT 3
|
||||
#define NO_DRIVE_C 4
|
||||
|
||||
static void report_error(int code)
|
||||
{
|
||||
char *buffer;
|
||||
int len;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case FSTAB_OPEN:
|
||||
if (gui_mode)
|
||||
{
|
||||
static const char *s = "Could not open your mountpoint description table.\n\nOpening of /etc/fstab failed: %s";
|
||||
len = snprintf(NULL, 0, s, strerror(errno));
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, len + 1);
|
||||
snprintf(buffer, len, s, strerror(errno));
|
||||
MessageBox(NULL, s, "", MB_OK | MB_ICONEXCLAMATION);
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "winecfg: could not open fstab: %s", strerror(errno));
|
||||
}
|
||||
break;
|
||||
|
||||
case NO_MORE_LETTERS:
|
||||
if (gui_mode) MessageBox(NULL, "No more letters are available to auto-detect available drives with.", "", MB_OK | MB_ICONEXCLAMATION);
|
||||
fprintf(stderr, "winecfg: no more available letters while scanning /etc/fstab");
|
||||
break;
|
||||
|
||||
case NO_ROOT:
|
||||
if (gui_mode) MessageBox(NULL, "Could not ensure that the root directory was mapped.\n\n"
|
||||
"This can happen if you run out of drive letters. "
|
||||
"It's important to have the root directory mapped, otherwise Wine"
|
||||
"will not be able to always find the programs you want to run. "
|
||||
"Try unmapping a drive letter then trying again.", "",
|
||||
MB_OK | MB_ICONEXCLAMATION);
|
||||
else fprintf(stderr, "winecfg: unable to map root drive\n");
|
||||
break;
|
||||
|
||||
case NO_DRIVE_C:
|
||||
if (gui_mode)
|
||||
MessageBox(NULL, "No virtual drive C mapped\n\nTry running wineprefixcreate", "", MB_OK | MB_ICONEXCLAMATION);
|
||||
else
|
||||
fprintf(stderr, "winecfg: no drive_c directory\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ensure_root_is_mapped()
|
||||
{
|
||||
int i;
|
||||
BOOL mapped = FALSE;
|
||||
|
||||
for (i = 0; i < 26; i++)
|
||||
if (drives[i].in_use && !strcmp(drives[i].unixpath, "/")) mapped = TRUE;
|
||||
|
||||
if (!mapped)
|
||||
{
|
||||
/* work backwards from Z, trying to map it */
|
||||
char letter;
|
||||
|
||||
for (letter = 'Z'; letter >= 'A'; letter--)
|
||||
{
|
||||
if (drives[letter - 'A'].in_use) continue;
|
||||
add_drive(letter, "/", "System", 0, DRIVE_FIXED);
|
||||
WINE_TRACE("allocated drive %c as the root drive\n", letter);
|
||||
}
|
||||
|
||||
if (letter == ('A' - 1)) report_error(NO_ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
static void ensure_drive_c_is_mapped()
|
||||
{
|
||||
struct stat buf;
|
||||
const char *configdir = wine_get_config_dir();
|
||||
int len;
|
||||
char *drive_c_dir;
|
||||
|
||||
if (drives[2].in_use) return;
|
||||
|
||||
len = snprintf(NULL, 0, "%s/../drive_c", configdir);
|
||||
drive_c_dir = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
snprintf(drive_c_dir, len, "%s/../drive_c", configdir);
|
||||
HeapFree(GetProcessHeap(), 0, drive_c_dir);
|
||||
|
||||
if (stat(drive_c_dir, &buf) == 0)
|
||||
{
|
||||
add_drive('C', "../drive_c", "Virtual Windows Drive", "0", DRIVE_FIXED);
|
||||
}
|
||||
else
|
||||
{
|
||||
report_error(NO_DRIVE_C);
|
||||
}
|
||||
}
|
||||
|
||||
int autodetect_drives()
|
||||
{
|
||||
struct mntent *ent;
|
||||
FILE *fstab;
|
||||
|
||||
/* we want to build a list of autodetected drives, then ensure each entry
|
||||
exists in the users setup. so, we superimpose the autodetected drives
|
||||
onto whatever is pre-existing.
|
||||
|
||||
for now let's just rummage around inside the fstab.
|
||||
*/
|
||||
|
||||
load_drives();
|
||||
|
||||
working_mask = drive_available_mask('\0');
|
||||
|
||||
fstab = fopen("/etc/fstab", "r");
|
||||
if (!fstab)
|
||||
{
|
||||
report_error(FSTAB_OPEN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while ((ent = getmntent(fstab)))
|
||||
{
|
||||
char letter;
|
||||
char label[256];
|
||||
int type;
|
||||
|
||||
WINE_TRACE("ent->mnt_dir=%s\n", ent->mnt_dir);
|
||||
|
||||
if (should_ignore_fstype(ent->mnt_type)) continue;
|
||||
if (is_drive_defined(ent->mnt_dir)) continue;
|
||||
|
||||
/* allocate a drive for it */
|
||||
letter = allocate_letter();
|
||||
if (letter == ']')
|
||||
{
|
||||
report_error(NO_MORE_LETTERS);
|
||||
fclose(fstab);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WINE_TRACE("adding drive %c for %s, type %s\n", letter, ent->mnt_dir, ent->mnt_type);
|
||||
|
||||
strncpy(label, "Drive X", 8);
|
||||
label[6] = letter;
|
||||
|
||||
if (!strcmp(ent->mnt_type, "nfs")) type = DRIVE_REMOTE;
|
||||
else if (!strcmp(ent->mnt_type, "nfs4")) type = DRIVE_REMOTE;
|
||||
else if (!strcmp(ent->mnt_type, "smbfs")) type = DRIVE_REMOTE;
|
||||
else if (!strcmp(ent->mnt_type, "cifs")) type = DRIVE_REMOTE;
|
||||
else if (!strcmp(ent->mnt_type, "coda")) type = DRIVE_REMOTE;
|
||||
else if (!strcmp(ent->mnt_type, "iso9660")) type = DRIVE_CDROM;
|
||||
else if (!strcmp(ent->mnt_type, "ramfs")) type = DRIVE_RAMDISK;
|
||||
else type = DRIVE_FIXED;
|
||||
|
||||
add_drive(letter, ent->mnt_dir, label, "0", type);
|
||||
|
||||
working_mask |= DRIVE_MASK_BIT(letter);
|
||||
}
|
||||
|
||||
fclose(fstab);
|
||||
|
||||
ensure_root_is_mapped();
|
||||
|
||||
ensure_drive_c_is_mapped();
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,650 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
static void set_advanced(HWND dialog)
|
||||
{
|
||||
int state;
|
||||
char *text;
|
||||
RECT rect;
|
||||
|
||||
/* FIXME: internationalization */
|
||||
if (advanced)
|
||||
{
|
||||
state = SW_NORMAL;
|
||||
text = "&Hide Advanced";
|
||||
}
|
||||
else
|
||||
{
|
||||
state = SW_HIDE;
|
||||
text = "&Show Advanced";
|
||||
}
|
||||
|
||||
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 {
|
||||
const uint sCode;
|
||||
const char *sDesc;
|
||||
};
|
||||
|
||||
static struct drive_typemap type_pairs[] = {
|
||||
{ DRIVE_FIXED, "Local hard disk" },
|
||||
{ DRIVE_REMOTE, "Network share" },
|
||||
{ DRIVE_REMOVABLE, "Floppy disk" },
|
||||
{ DRIVE_CDROM, "CD-ROM" }
|
||||
};
|
||||
|
||||
#define DRIVE_TYPE_DEFAULT 1
|
||||
|
||||
void fill_drive_droplist(long mask, char curletter, HWND dialog)
|
||||
{
|
||||
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(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);
|
||||
}
|
||||
|
||||
|
||||
void enable_labelserial_box(HWND dialog, int mode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int fill_drives_list(HWND dialog)
|
||||
{
|
||||
int count = 0;
|
||||
BOOL drivec_present = FALSE;
|
||||
int i;
|
||||
int prevsel = -1;
|
||||
|
||||
WINE_TRACE("\n");
|
||||
|
||||
updating_ui = TRUE;
|
||||
|
||||
prevsel = SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_GETCURSEL, 0, 0);
|
||||
|
||||
/* Clear the listbox */
|
||||
SendMessage(GetDlgItem(dialog, IDC_LIST_DRIVES), LB_RESETCONTENT, 0, 0);
|
||||
|
||||
for(i = 0; i < 26; i++)
|
||||
{
|
||||
char *title = 0;
|
||||
int len;
|
||||
int index;
|
||||
|
||||
/* skip over any unused drives */
|
||||
if (!drives[i].in_use)
|
||||
continue;
|
||||
|
||||
if (drives[i].letter == 'C')
|
||||
drivec_present = TRUE;
|
||||
|
||||
len = snprintf(title, 0, "%c: %s", 'A' + i,
|
||||
drives[i].unixpath);
|
||||
len++; /* add a byte for the trailing null */
|
||||
|
||||
title = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
|
||||
/* 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, len, "%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 */
|
||||
index = SendMessage(GetDlgItem(dialog, IDC_LIST_DRIVES), LB_ADDSTRING ,(WPARAM) -1, (LPARAM) title);
|
||||
SendMessage(GetDlgItem(dialog, IDC_LIST_DRIVES), LB_SETITEMDATA, index, (LPARAM) &drives[i]);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, title);
|
||||
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);
|
||||
|
||||
SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_SETCURSEL, prevsel == -1 ? 0 : prevsel, 0);
|
||||
|
||||
updating_ui = FALSE;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void on_add_click(HWND dialog)
|
||||
{
|
||||
/* 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\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", 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++;
|
||||
}
|
||||
SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_SETCURSEL, c, 0);
|
||||
|
||||
SetFocus(GetDlgItem(dialog, IDC_LIST_DRIVES));
|
||||
}
|
||||
|
||||
void on_remove_click(HWND dialog)
|
||||
{
|
||||
int item;
|
||||
struct drive *drive;
|
||||
|
||||
item = SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_GETCURSEL, 0, 0);
|
||||
if (item == -1) return; /* no selection */
|
||||
|
||||
drive = (struct drive *) SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_GETITEMDATA, item, 0);
|
||||
|
||||
if (drive->letter == 'C')
|
||||
{
|
||||
DWORD result = MessageBox(dialog, "Are you sure you want to delete drive C?\n\nMost 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);
|
||||
|
||||
item = item - 1;
|
||||
if (item < 0) item = 0;
|
||||
SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_SETCURSEL, item, 0); /* previous item */
|
||||
|
||||
SetFocus(GetDlgItem(dialog, IDC_LIST_DRIVES));
|
||||
}
|
||||
|
||||
void update_controls(HWND dialog) {
|
||||
char *path;
|
||||
uint type;
|
||||
char *label;
|
||||
char *serial;
|
||||
char *device;
|
||||
int i, selection = -1;
|
||||
|
||||
updating_ui = TRUE;
|
||||
|
||||
i = SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_GETCURSEL, 0, 0);
|
||||
if (i == -1)
|
||||
{
|
||||
/* no selection? let's select something for the user. this will re-enter */
|
||||
SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_SETCURSEL, 0, 0);
|
||||
return;
|
||||
}
|
||||
current_drive = (struct drive *) SendDlgItemMessage(dialog, IDC_LIST_DRIVES, LB_GETITEMDATA, i, 0);
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void on_edit_changed(HWND dialog, WORD id)
|
||||
{
|
||||
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);
|
||||
if (current_drive->label) HeapFree(GetProcessHeap(), 0, current_drive->label);
|
||||
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);
|
||||
if (current_drive->unixpath) HeapFree(GetProcessHeap(), 0, current_drive->unixpath);
|
||||
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);
|
||||
if (current_drive->serial) HeapFree(GetProcessHeap(), 0, current_drive->serial);
|
||||
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.... */
|
||||
if (device) HeapFree(GetProcessHeap(), 0, device);
|
||||
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 */
|
||||
rect->top = 258;
|
||||
rect->bottom = 258;
|
||||
rect->left += 35;
|
||||
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);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK
|
||||
DriveDlgProc (HWND dialog, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int item;
|
||||
struct drive *drive;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
load_drives();
|
||||
|
||||
if (!drives[2].in_use)
|
||||
MessageBox(dialog, "You don't have a drive C. This is not so great.\n\nRemember 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:
|
||||
if (HIWORD(wParam) == EN_CHANGE)
|
||||
{
|
||||
on_edit_changed(dialog, LOWORD(wParam));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_LIST_DRIVES:
|
||||
if (HIWORD(wParam) == LBN_SELCHANGE)
|
||||
update_controls(dialog);
|
||||
|
||||
break;
|
||||
|
||||
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:
|
||||
MessageBox(dialog, "", "Write me!", MB_OK);
|
||||
break;
|
||||
|
||||
case IDC_RADIO_ASSIGN:
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = get_text(dialog, IDC_EDIT_LABEL);
|
||||
if (current_drive->label) HeapFree(GetProcessHeap(), 0, current_drive->label);
|
||||
current_drive->label = str ? str : strdupA("");
|
||||
|
||||
str = get_text(dialog, IDC_EDIT_SERIAL);
|
||||
if (current_drive->serial) HeapFree(GetProcessHeap(), 0, current_drive->serial);
|
||||
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");
|
||||
SetWindowLong(dialog, DWL_MSGRESULT, FALSE);
|
||||
break;
|
||||
case PSN_APPLY:
|
||||
apply_drive_changes();
|
||||
SetWindowLong(dialog, DWL_MSGRESULT, PSNRET_NOERROR);
|
||||
break;
|
||||
case PSN_SETACTIVE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -35,7 +35,6 @@
|
|||
#define IDD_GRAPHCFG 110
|
||||
#define IDD_DLLCFG 111
|
||||
#define IDD_DRIVECFG 112
|
||||
#define IDD_SYSTEMCFG 113
|
||||
#define IDD_DRIVE_EDIT 114
|
||||
#define IDB_WINE_LOGO 200
|
||||
#define IDC_TABABOUT 1001
|
||||
|
@ -95,13 +94,15 @@
|
|||
#define IDC_RADIO_AUTODETECT 1068
|
||||
#define IDC_RADIO_ASSIGN 1069
|
||||
#define IDC_BUTTON_BROWSE_DEVICE 1070
|
||||
#define IDC_BOX_LABELSERIAL 1071
|
||||
#define IDC_STATIC_SERIAL 1072
|
||||
#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
|
||||
#define IDC_LABELSERIAL_STATIC 1078
|
||||
|
||||
#define IDC_DRIVE_LABEL 1078
|
||||
|
||||
/* graphics */
|
||||
#define IDC_ENABLE_MANAGED 1100
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* - Use unicode
|
||||
* - Icons in listviews/icons
|
||||
* - Better add app dialog, scan c: for EXE files and add to list in background
|
||||
* - Use [GNOME] HIG style groupboxes rather than win32 style (looks nicer, imho)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -47,11 +53,11 @@ void set_window_title(HWND dialog)
|
|||
char *newtitle;
|
||||
|
||||
/* update the window title */
|
||||
if (currentApp)
|
||||
if (current_app)
|
||||
{
|
||||
char *template = "Wine Configuration for %s";
|
||||
newtitle = HeapAlloc(GetProcessHeap(), 0, strlen(template) + strlen(currentApp) + 1);
|
||||
sprintf(newtitle, template, currentApp);
|
||||
newtitle = HeapAlloc(GetProcessHeap(), 0, strlen(template) + strlen(current_app) + 1);
|
||||
sprintf(newtitle, template, current_app);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -65,7 +71,7 @@ void set_window_title(HWND dialog)
|
|||
|
||||
|
||||
/**
|
||||
* get_config_key: Retrieves a configuration value from the registry
|
||||
* getkey: Retrieves a configuration value from the registry
|
||||
*
|
||||
* char *subkey : the name of the config section
|
||||
* char *name : the name of the config value
|
||||
|
@ -75,7 +81,7 @@ void set_window_title(HWND dialog)
|
|||
* not. Caller is responsible for releasing the result.
|
||||
*
|
||||
*/
|
||||
static char *get_config_key (char *subkey, char *name, char *def)
|
||||
static char *getkey (char *subkey, char *name, char *def)
|
||||
{
|
||||
LPBYTE buffer = NULL;
|
||||
DWORD len;
|
||||
|
@ -123,7 +129,7 @@ end:
|
|||
}
|
||||
|
||||
/**
|
||||
* set_config_key: convenience wrapper to set a key/value pair
|
||||
* setkey: convenience wrapper to set a key/value pair
|
||||
*
|
||||
* const char *subKey : the name of the config section
|
||||
* const char *valueName : the name of the config value
|
||||
|
@ -133,7 +139,7 @@ end:
|
|||
*
|
||||
* If valueName or value is NULL, an empty section will be created
|
||||
*/
|
||||
int set_config_key(const char *subkey, const char *name, const char *value) {
|
||||
int setkey(const char *subkey, const char *name, const char *value) {
|
||||
DWORD res = 1;
|
||||
HKEY key = NULL;
|
||||
|
||||
|
@ -252,7 +258,7 @@ char *get(char *path, char *name, char *def)
|
|||
}
|
||||
|
||||
/* no, so get from the registry */
|
||||
val = get_config_key(path, name, def);
|
||||
val = getkey(path, name, def);
|
||||
|
||||
WINE_TRACE("returning %s\n", val);
|
||||
|
||||
|
@ -439,7 +445,7 @@ static void process_setting(struct setting *s)
|
|||
if (s->value)
|
||||
{
|
||||
WINE_TRACE("Setting %s:%s to '%s'\n", s->path, s->name, s->value);
|
||||
set_config_key(s->path, s->name, s->value);
|
||||
setkey(s->path, s->name, s->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -465,7 +471,7 @@ void apply(void)
|
|||
|
||||
/* ================================== utility functions ============================ */
|
||||
|
||||
char *currentApp = NULL; /* the app we are currently editing, or NULL if editing global */
|
||||
char *current_app = NULL; /* the app we are currently editing, or NULL if editing global */
|
||||
|
||||
/* returns a registry key path suitable for passing to addTransaction */
|
||||
char *keypath(char *section)
|
||||
|
@ -474,10 +480,10 @@ char *keypath(char *section)
|
|||
|
||||
if (result) HeapFree(GetProcessHeap(), 0, result);
|
||||
|
||||
if (currentApp)
|
||||
if (current_app)
|
||||
{
|
||||
result = HeapAlloc(GetProcessHeap(), 0, strlen("AppDefaults\\") + strlen(currentApp) + 2 /* \\ */ + strlen(section) + 1 /* terminator */);
|
||||
sprintf(result, "AppDefaults\\%s\\%s", currentApp, section);
|
||||
result = HeapAlloc(GetProcessHeap(), 0, strlen("AppDefaults\\") + strlen(current_app) + 2 /* \\ */ + strlen(section) + 1 /* terminator */);
|
||||
sprintf(result, "AppDefaults\\%s\\%s", current_app, section);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -494,6 +500,10 @@ void PRINTERROR(void)
|
|||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
0, GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
|
||||
(LPSTR)&msg, 0, NULL);
|
||||
|
||||
/* eliminate trailing newline, is this a Wine bug? */
|
||||
*(strrchr(msg, '\n')) = '\0';
|
||||
|
||||
WINE_TRACE("error: '%s'\n", msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,15 +38,7 @@
|
|||
#define IS_OPTION_FALSE(ch) \
|
||||
((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
|
||||
|
||||
#define return_if_fail(try) \
|
||||
if (!(try)) { \
|
||||
WINE_ERR("check (" #try ") at %s:%d failed, returning\n", __FILE__, __LINE__ - 1); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define WRITEME(owner) MessageBox(owner, "Write me!", "", MB_OK | MB_ICONEXCLAMATION);
|
||||
|
||||
extern char *currentApp; /* NULL means editing global settings */
|
||||
extern char *current_app; /* NULL means editing global settings */
|
||||
|
||||
/* Use get and set to alter registry settings. The changes made through set
|
||||
won't be committed to the registry until process_all_settings is called,
|
||||
|
@ -55,6 +47,7 @@ extern char *currentApp; /* NULL means editing global settings */
|
|||
You are expected to release the result of get. The parameters to set will
|
||||
be copied, so release them too when necessary.
|
||||
*/
|
||||
|
||||
void set(char *path, char *name, char *value);
|
||||
char *get(char *path, char *name, char *def);
|
||||
BOOL exists(char *path, char *name);
|
||||
|
@ -62,37 +55,52 @@ void apply(void);
|
|||
char **enumerate_values(char *path);
|
||||
|
||||
/* returns a string of the form "AppDefaults\\appname.exe\\section", or just "section" if
|
||||
* the user is editing the global settings.
|
||||
*
|
||||
* no explicit free is needed of the string returned by this function
|
||||
the user is editing the global settings.
|
||||
|
||||
no explicit free is needed of the string returned by this function
|
||||
*/
|
||||
char *keypath(char *section);
|
||||
|
||||
/* Initializes the transaction system */
|
||||
int initialize(void);
|
||||
extern HKEY config_key;
|
||||
|
||||
/* hack for the property sheet control */
|
||||
void set_window_title(HWND dialog);
|
||||
|
||||
/* Graphics */
|
||||
|
||||
void initGraphDlg (HWND hDlg);
|
||||
void saveGraphDlgSettings (HWND hDlg);
|
||||
/* Window procedures */
|
||||
INT_PTR CALLBACK GraphDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/* Drive management */
|
||||
void initDriveDlg (HWND hDlg);
|
||||
void saveDriveSettings (HWND hDlg);
|
||||
|
||||
INT_PTR CALLBACK DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
INT_PTR CALLBACK AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
INT_PTR CALLBACK LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/* Audio config dialog */
|
||||
INT_PTR CALLBACK AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/* some basic utilities to make win32 suck less */
|
||||
/* Drive management */
|
||||
void load_drives();
|
||||
int autodetect_drives();
|
||||
|
||||
struct drive
|
||||
{
|
||||
char letter;
|
||||
char *unixpath;
|
||||
char *label;
|
||||
char *serial;
|
||||
DWORD type; /* one of the DRIVE_ constants from winbase.h */
|
||||
|
||||
BOOL in_use;
|
||||
};
|
||||
|
||||
#define DRIVE_MASK_BIT(B) 1 << (toupper(B) - 'A')
|
||||
|
||||
long drive_available_mask(char letter);
|
||||
BOOL add_drive(char letter, char *targetpath, char *label, char *serial, unsigned int type);
|
||||
void delete_drive(struct drive *pDrive);
|
||||
void apply_drive_changes();
|
||||
extern struct drive drives[26]; /* one for each drive letter */
|
||||
|
||||
BOOL gui_mode;
|
||||
|
||||
/* Some basic utilities to make win32 suck less */
|
||||
#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() */
|
||||
|
@ -104,15 +112,20 @@ static inline char *strdupA(char *s)
|
|||
return strcpy(r, s);
|
||||
}
|
||||
|
||||
static inline char *get_control_text(HWND dialog, WORD id)
|
||||
static inline char *get_text(HWND dialog, WORD id)
|
||||
{
|
||||
HWND item = GetDlgItem(dialog, id);
|
||||
int len = GetWindowTextLength(item) + 1;
|
||||
char *result = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (GetWindowText(item, result, len) == 0) return NULL;
|
||||
char *result = len ? HeapAlloc(GetProcessHeap(), 0, len) : NULL;
|
||||
if (!result || GetWindowText(item, result, len) == 0) return NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
#define WINE_KEY_ROOT "Software\\Wine\\Wine\\Config"
|
||||
static inline void set_text(HWND dialog, WORD id, char *text)
|
||||
{
|
||||
SetWindowText(GetDlgItem(dialog, id), text);
|
||||
}
|
||||
|
||||
#define WINE_KEY_ROOT "Software\\Wine\\Testing\\Config"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -145,8 +145,8 @@ static void set_from_desktop_edits(HWND dialog) {
|
|||
|
||||
WINE_TRACE("\n");
|
||||
|
||||
width = get_control_text(dialog, IDC_DESKTOP_WIDTH);
|
||||
height = get_control_text(dialog, IDC_DESKTOP_HEIGHT);
|
||||
width = get_text(dialog, IDC_DESKTOP_WIDTH);
|
||||
height = get_text(dialog, IDC_DESKTOP_HEIGHT);
|
||||
|
||||
if (strcmp(width, "") == 0)
|
||||
{
|
||||
|
@ -184,7 +184,7 @@ void on_enable_desktop_clicked(HWND dialog) {
|
|||
}
|
||||
|
||||
static void on_screen_depth_changed(HWND dialog) {
|
||||
char *newvalue = get_control_text(dialog, IDC_SCREEN_DEPTH);
|
||||
char *newvalue = get_text(dialog, IDC_SCREEN_DEPTH);
|
||||
char *spaceIndex = strchr(newvalue, ' ');
|
||||
|
||||
WINE_TRACE("newvalue=%s\n", newvalue);
|
||||
|
|
Loading…
Reference in New Issue