📄 vfdwin.c
字号:
/*
vfdwin.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
//
#define FALLBACK_UNMOUNT_RETRY "Failed to unmount the current image.\r\n" \
"Some programs may be using the drive."
//
// local funtions
//
static BOOL MountImage();
//
// global variable instances
//
extern HINSTANCE hAppInstance = NULL;
//
// Application entry point
//
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg = { 0 };
HWND hMainDlg;
HANDLE hMutex;
DWORD err;
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(nCmdShow);
//
// Save application instance handle
//
hAppInstance = hInstance;
//
// Check first command line parameter
//
if (lpCmdLine && *lpCmdLine && MountImage()) {
return 0;
}
//
// Avoid running multiple instances of Vfd Control Panel
//
hMutex = CreateMutex(NULL, TRUE, VFD_APP_NAME);
if (hMutex == NULL) {
err = GetLastError();
DEBUG_TRACE1("WinMain : CreateMutex - %s", ErrMsg(err));
ShowErrorMessage(err, IDS_ERR_APP_INIT);
return 0;
}
//
// If another instance is running, bring it to foreground and quit
//
if (GetLastError() == ERROR_ALREADY_EXISTS) {
PostMessage(HWND_BROADCAST, RegisterWindowMessage(VFD_WAKEUP_MSG_STR), 0, 0);
goto cleanup;
}
//
// initialize ole and common controls
//
err = CoInitialize(NULL);
if (!SUCCEEDED(err)) {
DEBUG_TRACE1("WinMain : CoInitialize - %s", ErrMsg(err));
ShowErrorMessage(err, IDS_ERR_APP_INIT);
goto cleanup;
}
InitCommonControls();
//
// Create the main dialog window
//
hMainDlg = CreateDialog(
hInstance,
MAKEINTRESOURCE(IDD_MAIN),
NULL,
MainProc);
if (hMainDlg == NULL) {
err = GetLastError();
DEBUG_TRACE1("WinMain : CreateDialogParam - %s", ErrMsg(err));
ShowErrorMessage(err, IDS_ERR_APP_INIT);
goto cleanup;
}
//
// Message loop
//
for (;;) {
BOOL ret = GetMessage(&msg, NULL, 0, 0);
if (ret == 0) {
break;
}
else if (ret == -1) {
err = GetLastError();
DEBUG_TRACE1("WinMain: GetMessage - %s", ErrMsg(err));
ShowErrorMessage(err, IDS_ERR_APP_INTERNAL);
break;
}
else {
if (!IsDialogMessage(hMainDlg, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
cleanup:
if (hMutex) {
CloseHandle(hMutex);
}
CoUninitialize();
_CrtDumpMemoryLeaks();
return msg.wParam;
}
//
// Unmount the current image and mount the new image
//
BOOL MountImage()
{
LPTSTR image_path = NULL;
BOOL read_only = FALSE;
ULONG file_size = 0;
TCHAR new_drive[] = "\0:";
TCHAR old_drive = '\0';
BOOL open_folder = TRUE;
DWORD state;
DWORD ret;
//
// process command line parameters
//
while (*(++__argv)) {
if (stricmp(*__argv, VFD_MOUNT_SWITCH) == 0) {
continue;
}
else if (stricmp(*__argv, "/umount") == 0) {
image_path = NULL;
break;
}
else if (stricmp(*__argv, "/ro") == 0) {
read_only = TRUE;
}
else if (stricmp(*__argv, "/720") == 0) {
file_size = VFD_FILESIZE_720KB;
}
else if (stricmp(*__argv, "/144") == 0) {
file_size = VFD_FILESIZE_1P44MB;
}
else if (stricmp(*__argv, "/288") == 0) {
file_size = VFD_FILESIZE_2P88MB;
}
else if (stricmp(*__argv, "/q") == 0) {
open_folder = FALSE;
}
else if (strnicmp(*__argv, "/l:", 3) == 0 && isalpha(*(*__argv + 3))) {
new_drive[0] = *(*__argv + 3);
}
else if (**__argv == '/' || image_path) {
ShowErrorMessage(0, IDS_ERR_INVALID_PARAM, *__argv);
return FALSE;
}
else {
image_path = *__argv;
if (*image_path == '\"' && *(image_path + strlen(image_path) - 1) == '\"') {
// remove quote characters if the path is quoted
*(image_path + strlen(image_path) - 1) = '\0';
image_path++;
}
}
}
//
// check image file
//
if (image_path) {
ret = VfdCheckImageFile(image_path, NULL, &read_only);
if (ret == ERROR_FILE_NOT_FOUND) {
// an image file cannot be created read-only
if (read_only) {
ret = VFD_ERROR_CREATE_READONLY;
goto error_message;
}
// size must be specified to create a new image
if (file_size == 0) {
ret = VFD_ERROR_IMAGE_SIZE;
goto error_message;
}
}
else if (ret != ERROR_SUCCESS) {
DEBUG_TRACE1("MountImage : VfdCheckImageFile - %s", ErrMsg(ret));
goto error_message;
}
}
//
// get current driver status
//
if ((ret = VfdGetDriverState(&state)) != ERROR_SUCCESS) {
goto error_message;
}
if (state != SERVICE_RUNNING) {
// ensure that the driver is installed
if (state == VFD_NOT_INSTALLED) {
if ((ret = VfdInstall(NULL, FALSE)) != ERROR_SUCCESS) {
DEBUG_TRACE1("MountImage: VfdInstall - %s", ErrMsg(ret));
ShowErrorMessage(ret, IDS_ERR_DRIVER_INSTALL);
return TRUE;
}
}
// ensure that the driver is running
if (state != SERVICE_RUNNING) {
if ((ret = VfdStart(NULL)) != ERROR_SUCCESS) {
DEBUG_TRACE1("MountImage: VfdStart - %s", ErrMsg(ret));
ShowErrorMessage(ret, IDS_ERR_DRIVER_START);
return TRUE;
}
}
}
else {
VfdGetDriveLetter(&old_drive);
if ((ret = VfdGetMediaState()) == ERROR_SUCCESS ||
ret == ERROR_WRITE_PROTECT) {
// unmount current image
ret = EnsureUnmount((ENSURE_CALLBACK)Retry_Callback, NULL, 0);
if (ret != ERROR_SUCCESS && ret != ERROR_NOT_READY) {
ShowErrorMessage(ret, IDS_ERR_IMAGE_UNMOUNT);
return TRUE;
}
}
else if (ret != ERROR_NOT_READY) {
DEBUG_TRACE1("MountImage : VfdGetMediaState - %s", ErrMsg(ret));
goto error_message;
}
}
//
// if image path is not specified, nothing more to do
//
if (image_path == NULL) {
return TRUE;
}
//
// (re-)assign the drive letter
//
if (!isalpha(new_drive[0])) {
if (isalpha(old_drive)) {
new_drive[0] = old_drive;
}
else {
new_drive[0] = ChooseDriveLetter();
}
}
if ((ret = VfdSetDriveLetter(new_drive[0])) != ERROR_SUCCESS) {
DEBUG_TRACE1("MountImage : VfdSetDriveLetter - %s", ErrMsg(ret));
goto error_message;
}
//
// mount the image file
//
if ((ret = VfdMount(image_path, read_only, file_size)) != ERROR_SUCCESS) {
VfdDelDriveLetter(new_drive[0]);
DEBUG_TRACE1("MountImage : VfdMount - %s", ErrMsg(ret));
goto error_message;
}
//
// Unless otherwise specified, open the mounted drive
//
if (open_folder) {
if ((DWORD)ShellExecute(NULL, NULL, new_drive, NULL, NULL, SW_SHOWNORMAL) <= 32) {
DEBUG_TRACE1("MountImage : ShellExecute - %s", ErrMsg(GetLastError()));
}
}
return TRUE;
error_message:
ShowErrorMessage(ret, IDS_ERR_IMAGE_MOUNT, image_path ? image_path : "???");
return TRUE;
}
//
// Unmount retry confirmation
//
BOOL Retry_Callback(HWND hWnd)
{
TCHAR msg[100];
if (!LoadString(hAppInstance,
IDS_MSG_UNMOUNT_RETRY, msg, sizeof(msg))) {
// use fallback message string
strcpy(msg, FALLBACK_UNMOUNT_RETRY);
}
if (MessageBox(IsWindow(hWnd) ? hWnd : NULL, msg, VFD_APP_NAME,
MB_ICONEXCLAMATION | MB_RETRYCANCEL) == IDRETRY)
{
return TRUE;
}
else {
return FALSE;
}
}
//
// Displays error message
//
void ShowErrorMessage(DWORD err, DWORD msg, ...)
{
TCHAR buf[500];
DWORD len = 0;
if (msg) {
TCHAR tmp[500];
if (LoadString(hAppInstance, msg, tmp, sizeof(tmp))) {
va_list list;
va_start(list, msg);
len = vsprintf(buf, tmp, list);
}
else {
len = sprintf(buf, "VfdWin Message: %lu", msg);
}
strcpy(buf + len, "\r\n");
len += 2;
}
if (err) {
VfdErrorMessage(err, buf + len, sizeof(buf) - len);
}
MessageBox(NULL, buf, VFD_APP_NAME, MB_ICONSTOP);
}
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -