📄 driverdlg.c
字号:
/*
drivedlg.c
Virtual Floppy Disk drive control panel
Copyright (C) 2003 Kenji Kato
*/
#include "sysincl.h"
#include "vfdctl.h"
#include "vfdutil.h"
#include "vfdwin.h"
#include "resource.h"
//
// local definitions
//
// OPENFILENAME flag values in commdlg.h for WINVER >= 0x0500
// we don't want *.sys file to be added to recent docs folder
#define OFN_DONTADDTORECENT 0x02000000
// we want *.sys files to be shown in open dialog box
#define OFN_FORCESHOWHIDDEN 0x10000000
// fallback text strings for the open file dialog
#define FALLBACK_IMAGE_FILTER "Known image files (bin,dat,fdd,flp,ima,img,vfd)\0" \
"*.bin;*.dat;*.fdd;*.flp;*.ima;*.img;*.vfd\0" \
"All files (*.*)\0*.*\0"
#define FALLBACK_IMAGE_TITLE "Virtual FD Image"
#define FALLBACK_DRIVER_FILTER "Virtual FD Driver (vfd.sys)\0vfd.sys\0"
#define FALLBACK_DRIVER_TITLE "Virtual FD Driver"
#define FALLBACK_FORCE_STOP "Failed to unmount current image.\r\n" \
"The driver may not stop properly. Stop it anyway?"
#define FALLBACK_FORCE_REMOVE "Failed to stop the Virtual FD driver.\r\n" \
"The driver may not unload properly. Remove it anyway?"
//
// Windows message handlers
//
static void OnInitDialog (HWND hDlg);
static void OnImagePathEdit (HWND hDlg, HWND hEdit);
static void OnImageBrowse (HWND hDlg);
static void OnImageMount (HWND hDlg, HWND hButton);
static void OnImageUnmount (HWND hDlg, HWND hButton);
static void OnDriverPathEdit(HWND hDlg, HWND hEdit);
static void OnDriverBrowse (HWND hDlg);
static void OnDriverInstall (HWND hDlg, HWND hButton);
static void OnDriverRemove (HWND hDlg, HWND hButton);
static void OnDriverStart (HWND hDlg, HWND hButton);
static void OnDriverStop (HWND hDlg, HWND hButton);
//
// local functions
//
static BOOL ImageMount (HWND hDlg);
static BOOL DriverInstall (HWND hDlg);
static BOOL DriverRemove (HWND hDlg);
static BOOL DriverStart (HWND hDlg);
static BOOL DriverStop (HWND hDlg);
static BOOL AskForceStop (HWND hDlg);
static BOOL AskForceRemove (HWND hDlg);
static void AppendMessage (HWND hDlg, UINT msg, DWORD err);
//
// window message dispatcher
//
BOOL CALLBACK DriverProc(
HWND hDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
OnInitDialog(hDlg);
break;
case WM_COMMAND:
switch (wParam) {
case MAKELONG(IDC_IMAGE_PATH, EN_CHANGE):
OnImagePathEdit(hDlg, (HWND)lParam);
break;
case IDC_IMAGE_BROWSE:
OnImageBrowse(hDlg);
break;
case IDC_IMAGE_MOUNT:
OnImageMount(hDlg, (HWND)lParam);
break;
case IDC_IMAGE_UNMOUNT:
OnImageUnmount(hDlg, (HWND)lParam);
break;
case MAKELONG(IDC_DRIVER_PATH, EN_CHANGE):
OnDriverPathEdit(hDlg, (HWND)lParam);
break;
case IDC_DRIVER_BROWSE:
OnDriverBrowse(hDlg);
break;
case IDC_DRIVER_INSTALL:
OnDriverInstall(hDlg, (HWND)lParam);
break;
case IDC_DRIVER_REMOVE:
OnDriverRemove(hDlg, (HWND)lParam);
break;
case IDC_DRIVER_START:
OnDriverStart(hDlg, (HWND)lParam);
break;
case IDC_DRIVER_STOP:
OnDriverStop(hDlg, (HWND)lParam);
break;
}
break;
}
return 0;
}
//
// initialize drive dialog
//
void OnInitDialog(HWND hDlg)
{
HWND hCombo;
DWORD logical_drives;
char drive[] = " :";
DWORD len;
char driver_path[MAX_PATH];
// Init Drive Letter combo box
hCombo = GetDlgItem(hDlg, IDC_IMAGE_DRIVE);
if (hCombo == NULL) {
DEBUG_TRACE1(
"OnImageInitDialog: GetDlgItem - %s", ErrMsg(GetLastError()));
return;
}
SendMessage(hCombo, CB_RESETCONTENT, 0, 0);
// search all unused drive letters
logical_drives = GetLogicalDrives();
if (logical_drives == 0) {
DEBUG_TRACE1(
"OnImageInitDialog: GetLogicalDrives - %s", ErrMsg(GetLastError()));
return;
}
for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++) {
if (!(logical_drives & 0x01)) {
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)drive);
}
logical_drives >>= 1;
}
// add drive letter used by Virtual FD
if (VfdGetDriveLetter(&drive[0]) == ERROR_SUCCESS && isalpha(drive[0])) {
SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)drive);
}
else {
drive[0] = ChooseDriveLetter();
}
SendMessage(hCombo, CB_SELECTSTRING, 0, (LPARAM)drive);
// prepare default driver path
len = GetModuleFileName(
hAppInstance, driver_path, sizeof(driver_path));
if (len == 0) {
DEBUG_TRACE1(
"OnDriverInitDialog : GetModuleFileName - %s", ErrMsg(GetLastError()));
return;
}
// search the last '\' char
while (len > 0 && driver_path[len - 1] != '\\') {
len --;
}
strcpy(&driver_path[len], "vfd.sys");
SetDlgItemText(hDlg, IDC_DRIVER_PATH, driver_path);
//
// choose default radio buttons
//
CheckRadioButton(hDlg, IDC_IMAGE_720KB, IDC_IMAGE_2P88MB, IDC_IMAGE_1P44MB);
CheckRadioButton(hDlg, IDC_DRIVER_MANUAL, IDC_DRIVER_AUTO, IDC_DRIVER_MANUAL);
return;
}
//
// Image path is changed
//
void OnImagePathEdit(HWND hDlg, HWND hEdit)
{
EnableWindow(
GetDlgItem(hDlg, IDC_IMAGE_MOUNT),
(GetWindowTextLength(hEdit) != 0));
}
//
// Driver path is changed
//
void OnDriverPathEdit(HWND hDlg, HWND hEdit)
{
BOOL enable = (GetWindowTextLength(hEdit) != 0);
EnableWindow(GetDlgItem(hDlg, IDC_IMAGE_MOUNT), enable);
EnableWindow(GetDlgItem(hDlg, IDC_DRIVER_START), enable);
EnableWindow(GetDlgItem(hDlg, IDC_DRIVER_INSTALL), enable);
}
//
// image browse button is clicked
//
void OnImageBrowse(HWND hDlg)
{
OPENFILENAME ofn;
TCHAR path[MAX_PATH], dir[MAX_PATH];
TCHAR filter[150];
TCHAR title[50];
LPTSTR p;
DWORD attr;
int len;
//
// prepare filter for the open file dialog
//
if (LoadString(hAppInstance, IDS_IMAGE_OPEN_FILTER, filter, sizeof(filter))) {
LPTSTR p = filter;
while (*p) {
if (*p == '|') {
*p = '\0';
}
p++;
}
}
else {
DEBUG_TRACE1(
"OnImageBrowse : LoadString - %s", ErrMsg(GetLastError()));
memcpy(filter, FALLBACK_IMAGE_FILTER, sizeof(FALLBACK_IMAGE_FILTER));
}
//
// prepare title text for the open file dialog
//
if (!LoadString(hAppInstance, IDS_IMAGE_OPEN_TITLE, title, sizeof(title))) {
DEBUG_TRACE1(
"OnImageBrowse : LoadString - %s", ErrMsg(GetLastError()));
strcpy(title, FALLBACK_IMAGE_TITLE);
}
GetDlgItemText(hDlg, IDC_IMAGE_PATH, path, sizeof(path));
//
// Prepare OPENFILENAME structure
//
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFilter = filter;
ofn.lpstrFile = path;
ofn.nMaxFile = sizeof(path);
ofn.lpstrTitle = title;
ofn.Flags = OFN_CREATEPROMPT;
if (GetFullPathName(path, sizeof(dir), dir, &p) == 0) {
dir[0] = '\0';
}
attr = GetFileAttributes(dir);
if (attr == INVALID_FILE_ATTRIBUTES) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
strcpy(path, dir);
}
else {
path[0] = '\0';
}
}
else if (attr & FILE_ATTRIBUTE_DIRECTORY) {
path[0] = '\0';
ofn.lpstrInitialDir = dir;
}
else {
strcpy(path, dir);
}
len = strlen(path);
while (len && path[len - 1] == '\\') {
path[--len] = '\0';
}
if (GetOpenFileName(&ofn)) {
SetDlgItemText(hDlg, IDC_IMAGE_PATH, path);
CheckDlgButton(hDlg, IDC_IMAGE_READONLY,
(ofn.Flags & OFN_READONLY) ? BST_CHECKED : BST_UNCHECKED);
}
}
//
// Driver path browse button is clicked
//
void OnDriverBrowse(HWND hDlg)
{
OPENFILENAME ofn;
TCHAR filter[50];
TCHAR title[50];
TCHAR path[MAX_PATH];
// get current text in path edit
GetDlgItemText(hDlg, IDC_DRIVER_PATH, path, sizeof(path));
// prepare filter for the open file dialog
if (LoadString(hAppInstance, IDS_DRIVER_OPEN_FILTER, filter, sizeof(filter))) {
LPTSTR p = filter;
while (*p) {
if (*p == '|') {
*p = '\0';
}
p++;
}
}
else {
DEBUG_TRACE1(
"OnDriverBrowse : LoadString - %s", ErrMsg(GetLastError()));
memcpy(filter, FALLBACK_DRIVER_FILTER, sizeof(FALLBACK_DRIVER_FILTER));
}
// prepare title text for the open file dialog
if (!LoadString(hAppInstance, IDS_DRIVER_OPEN_TITLE, title, sizeof(title))) {
DEBUG_TRACE1(
"OnDriverBrowse : LoadString - %s", ErrMsg(GetLastError()));
strcpy(title, FALLBACK_DRIVER_TITLE);
}
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFilter = filter;
ofn.lpstrFile = path;
ofn.nMaxFile = sizeof(path);
ofn.lpstrTitle = title;
ofn.Flags = OFN_FILEMUSTEXIST
| OFN_NONETWORKBUTTON
| OFN_HIDEREADONLY
| OFN_DONTADDTORECENT
| OFN_FORCESHOWHIDDEN;
if (GetOpenFileName(&ofn)) {
SetDlgItemText(hDlg, IDC_DRIVER_PATH, path);
}
}
//
// Mount button is clicked
//
void OnImageMount(HWND hDlg, HWND hButton)
{
DWORD driver_state;
DWORD ret;
//
// ensure that the driver is running
//
if ((ret = VfdGetDriverState(&driver_state)) != ERROR_SUCCESS) {
AppendMessage(hDlg, IDS_ERR_IMAGE_MOUNT, ret);
return;
}
if (driver_state != SERVICE_RUNNING) {
if (driver_state == VFD_NOT_INSTALLED) {
if (!DriverInstall(hDlg)) {
return;
}
}
if (!DriverStart(hDlg)) {
return;
}
}
//
// mount the image
//
if (ImageMount(hDlg)) {
SendMessage(hButton, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
SetFocus(GetDlgItem(hDlg, IDC_IMAGE_UNMOUNT));
}
}
//
// Unmount button is clicked
//
void OnImageUnmount(HWND hDlg, HWND hButton)
{
DWORD ret;
ret = EnsureUnmount((ENSURE_CALLBACK)Retry_Callback, NULL, (DWORD)hDlg);
if (ret == ERROR_SUCCESS || ret == ERROR_NOT_READY) {
SendMessage(hButton, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
SetFocus(GetDlgItem(hDlg, IDC_IMAGE_MOUNT));
}
else {
AppendMessage(hDlg, IDS_ERR_IMAGE_UNMOUNT, ret);
}
}
//
// Install button is clicked
//
void OnDriverInstall(HWND hDlg, HWND hButton)
{
if (DriverInstall(hDlg)) {
SendMessage(hButton, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
SetFocus(GetDlgItem(hDlg, IDC_DRIVER_START));
}
}
//
// Uninstall button is clicked
//
void OnDriverRemove(HWND hDlg, HWND hButton)
{
DWORD driver_state;
DWORD ret;
//
// Ensure that the driver is stopped
//
if ((ret = VfdGetDriverState(&driver_state)) != ERROR_SUCCESS) {
AppendMessage(hDlg, IDS_ERR_DRIVER_REMOVE, ret);
return;
}
if (driver_state != SERVICE_STOPPED) {
ret = VfdGetMediaState();
if (ret == ERROR_SUCCESS || ret == ERROR_WRITE_PROTECT) {
ret = EnsureUnmount(
(ENSURE_CALLBACK)Retry_Callback,
(ENSURE_CALLBACK)AskForceStop,
(DWORD)hDlg);
if (ret != ERROR_SUCCESS && ret != ERROR_NOT_READY) {
AppendMessage(hDlg, IDS_ERR_IMAGE_UNMOUNT, ret);
return;
}
}
else if (ret != ERROR_NOT_READY) {
AppendMessage(hDlg, IDS_ERR_DRIVER_STOP, ret);
return;
}
if (!DriverStop(hDlg) && !AskForceRemove(GetParent(hDlg))) {
return;
}
}
//
// remove the driver
//
if (DriverRemove(hDlg)) {
SendMessage(hButton, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
SetFocus(GetDlgItem(hDlg, IDC_DRIVER_INSTALL));
}
}
//
// start button is clicked
//
void OnDriverStart(HWND hDlg, HWND hButton)
{
DWORD driver_state;
DWORD ret;
//
// ensure that the driver is installed
//
if ((ret = VfdGetDriverState(&driver_state)) != ERROR_SUCCESS) {
AppendMessage(hDlg, IDS_ERR_DRIVER_START, ret);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -