⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfdwin.c

📁 Virtual Floppy Driver
💻 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 + -