reactos/modules/rosapps/lib/vfdlib/vfdguisave.c
Pierre Schweitzer 25c7e1a8d0
[VFD] Import the VFD project (Virtual Floppy Drive) which allows creating virtual
floppy drives in ReactOS and mount images on them.
Only the cmd got imported. The GUI interface may come later on.
Note that, as for vcdrom, the driver is left disabled and you need to explicitely
start it through vfd command line interface.

CORE-14090
2017-12-16 21:48:34 +01:00

530 lines
11 KiB
C

/*
vfdguisave.c
Virtual Floppy Drive for Windows
Driver control library
Save image GUI utility function
Copyright (c) 2003-2005 Ken Kato
*/
#ifdef __cplusplus
#pragma message(__FILE__": Compiled as C++ for testing purpose.")
#endif // __cplusplus
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef _MSC_VER
#pragma warning(push,3)
#endif
#include <commdlg.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include "vfdtypes.h"
#include "vfdapi.h"
#include "vfdlib.h"
#ifndef __REACTOS__
#include "vfdmsg.h"
#else
#include "vfdmsg_lib.h"
#endif
#include "vfdguirc.h"
//
// local functions
//
static INT CALLBACK SaveDialogProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
static void OnInit(HWND hDlg, PCSAVE_PARAM pParam);
static void OnTarget(HWND hDlg, HWND hEdit);
static void OnBrowse(HWND hDlg);
static void OnOverwrite(HWND hDlg, HWND hCheck);
static void OnTruncate(HWND hDlg, HWND hCheck);
static DWORD OnOK(HWND hDlg);
//
// Show Save Image dialog box
//
DWORD WINAPI VfdGuiSave(
HWND hParent,
ULONG nDevice)
{
SAVE_PARAM param;
CHAR path[MAX_PATH];
DWORD ret;
// open the source device
param.hDevice = VfdOpenDevice(nDevice);
if (param.hDevice == INVALID_HANDLE_VALUE) {
return GetLastError();
}
// get current image information
param.ImageName = path;
ret = VfdGetImageInfo(
param.hDevice,
param.ImageName,
&param.DiskType,
&param.MediaType,
&param.MediaFlags,
&param.FileType,
&param.ImageSize);
if (ret == ERROR_SUCCESS) {
// show dialog box
ret = GuiSaveParam(hParent, &param);
}
// close the source device
CloseHandle(param.hDevice);
return ret;
}
DWORD GuiSaveParam(
HWND hParent,
PCSAVE_PARAM pParam)
{
switch (DialogBoxParam(
g_hDllModule,
MAKEINTRESOURCE(IDD_SAVEDIALOG),
hParent,
SaveDialogProc,
(LPARAM)pParam))
{
case IDOK:
return ERROR_SUCCESS;
case IDCANCEL:
return ERROR_CANCELLED;
default:
return GetLastError();
}
}
//
// The dialog procedure
//
INT CALLBACK SaveDialogProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_INITDIALOG:
OnInit(hDlg, (PCSAVE_PARAM)lParam);
return TRUE;
case WM_COMMAND:
switch (wParam) {
case MAKELONG(IDC_TARGETFILE, EN_CHANGE):
OnTarget(hDlg, (HWND)lParam);
return TRUE;
case IDC_BROWSE:
OnBrowse(hDlg);
return TRUE;
case IDC_OVERWRITE:
OnOverwrite(hDlg, (HWND)lParam);
return TRUE;
case IDC_TRUNCATE:
OnTruncate(hDlg, (HWND)lParam);
return TRUE;
case IDOK:
if (OnOK(hDlg) == ERROR_SUCCESS) {
EndDialog(hDlg, IDOK);
}
return TRUE;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
break;
case WM_CONTEXTMENU:
ShowContextMenu(hDlg, (HWND)wParam, lParam);
break;
case WM_HELP:
{
LPHELPINFO info = (LPHELPINFO)lParam;
if (info->iContextType == HELPINFO_WINDOW) {
ShowHelpWindow(hDlg, info->iCtrlId);
}
}
return TRUE;
}
return FALSE;
}
//
// Initialize the dialog
//
void OnInit(
HWND hDlg,
PCSAVE_PARAM pParam)
{
// Store parameters
SetWindowLong(hDlg, GWL_USERDATA, (ULONG)pParam);
// clear the target existence flag
SetWindowLong(hDlg, DWL_USER, 0);
// Set dialog window title
SetControlText(hDlg, 0, MSG_SAVE_TITLE);
// Set control captions
SetControlText(hDlg, IDC_IMAGEFILE_LABEL, MSG_IMAGEFILE_LABEL);
SetControlText(hDlg, IDC_DISKTYPE_LABEL, MSG_DISKTYPE_LABEL);
SetControlText(hDlg, IDC_MEDIATYPE_LABEL, MSG_MEDIATYPE_LABEL);
SetControlText(hDlg, IDC_TARGETFILE_LABEL, MSG_TARGETFILE_LABEL);
SetControlText(hDlg, IDC_IMAGEDESC_LABEL, MSG_DESCRIPTION_LABEL);
SetControlText(hDlg, IDC_BROWSE, MSG_BROWSE_BUTTON);
SetControlText(hDlg, IDC_OVERWRITE, MSG_OVERWRITE_CHECK);
SetControlText(hDlg, IDC_TRUNCATE, MSG_TRUNCATE_CHECK);
SetControlText(hDlg, IDOK, MSG_SAVE_BUTTON);
SetControlText(hDlg, IDCANCEL, MSG_CANCEL_BUTTON);
// set disk type
if (pParam->DiskType == VFD_DISKTYPE_FILE) {
SetDlgItemText(hDlg, IDC_DISKTYPE, "FILE");
}
else {
SetDlgItemText(hDlg, IDC_DISKTYPE, "RAM");
}
// display media type
SetDlgItemText(hDlg, IDC_MEDIATYPE,
VfdMediaTypeName(pParam->MediaType));
// set current image and initial target
if (pParam->ImageName[0]) {
SetDlgItemText(hDlg, IDC_IMAGEFILE, pParam->ImageName);
SetDlgItemText(hDlg, IDC_TARGETFILE, pParam->ImageName);
}
else if (pParam->DiskType != VFD_DISKTYPE_FILE) {
SetDlgItemText(hDlg, IDC_IMAGEFILE, "<RAM>");
OnTarget(hDlg, GetDlgItem(hDlg, IDC_TARGETFILE));
}
}
//
// Path is changed -- check specified target file
//
void OnTarget(
HWND hDlg,
HWND hEdit)
{
PCSAVE_PARAM param;
CHAR buf[MAX_PATH];
ULONG file_size;
VFD_FILETYPE file_type;
DWORD file_attr;
DWORD ret;
// clear the target existence flag
SetWindowLong(hDlg, DWL_USER, 0);
// clear the description and hint text
SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, NULL);
SetDlgItemText(hDlg, IDC_IMAGEFILE_HINT, NULL);
// get the target file name
if (GetWindowText(hEdit, buf, sizeof(buf)) == 0) {
// target file is blank
EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
return;
}
else {
CHAR full[MAX_PATH];
PSTR file;
// convert into a full path
if (GetFullPathName(buf, sizeof(full), full, &file)) {
strcpy(buf, full);
}
}
//
// get the current image info
//
param = (PCSAVE_PARAM)GetWindowLong(hDlg, GWL_USERDATA);
if (_stricmp(param->ImageName, buf) == 0) {
// target is the current file
char desc[MAX_PATH];
VfdMakeFileDesc(desc, sizeof(desc),
param->FileType, param->ImageSize,
GetFileAttributes(param->ImageName));
SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, desc);
SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_CURRENT_FILE);
if (param->DiskType == VFD_DISKTYPE_FILE) {
// cannot overwrite the current FILE disk image
EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
return;
}
}
//
// check target image file
//
ret = VfdCheckImageFile(
buf, &file_attr, &file_type, &file_size);
if (ret == ERROR_FILE_NOT_FOUND) {
// file does not exist
SetControlText(hDlg, IDC_IMAGEFILE_DESC, MSG_DESC_NEW_FILE);
EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
return;
}
else if (ret != ERROR_SUCCESS) {
SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, SystemMessage(ret));
EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
return;
}
// set target file description
VfdMakeFileDesc(buf, sizeof(buf),
file_type, file_size, file_attr);
SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, buf);
// check target file type
if (file_type == VFD_FILETYPE_ZIP) {
SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_TARGET_IS_ZIP);
EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
return;
}
// the target is an existing raw file
EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), TRUE);
// set truncate box
if (file_size > VfdGetMediaSize(param->MediaType)) {
EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), TRUE);
SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_SIZE_MISMATCH);
}
else {
EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE);
}
// check overwrite setting
if (IsDlgButtonChecked(hDlg, IDC_OVERWRITE) != BST_CHECKED) {
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
else {
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
// target file exists and overwritable
SetWindowLong(hDlg, DWL_USER, 1);
}
//
// Show save file dialog box
//
void OnBrowse(
HWND hDlg)
{
OPENFILENAME ofn;
PSTR title;
CHAR file[MAX_PATH];
CHAR dir[MAX_PATH];
DWORD len;
title = ModuleMessage(MSG_SAVE_TITLE);
ZeroMemory(&ofn, sizeof(ofn));
ZeroMemory(file, sizeof(file));
ZeroMemory(dir, sizeof(dir));
len = GetDlgItemText(hDlg, IDC_TARGETFILE, file, sizeof(file));
if (len && file[len - 1] == '\\') {
strcpy(dir, file);
ZeroMemory(file, sizeof(file));
}
// Different structure sizes must be used for NT and 2K/XP
ofn.lStructSize = IS_WINDOWS_NT() ?
OPENFILENAME_SIZE_VERSION_400 : sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFile = file;
ofn.nMaxFile = sizeof(file);
ofn.lpstrInitialDir = dir;
ofn.lpstrTitle = title ? title : "Save Image";
ofn.lpstrFilter = "*.*\0*.*\0";
ofn.Flags = OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
if (GetSaveFileName(&ofn)) {
SetDlgItemText(hDlg, IDC_TARGETFILE, file);
SetFocus(GetDlgItem(hDlg, IDC_TARGETFILE));
}
if (title) {
LocalFree(title);
}
}
void OnOverwrite(
HWND hDlg,
HWND hCheck)
{
if (GetWindowLong(hDlg, DWL_USER)) {
// the target file exists and overwritable
if (SendMessage(hCheck, BM_GETCHECK, 0, 0) != BST_CHECKED) {
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}
else {
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
}
}
}
void OnTruncate(
HWND hDlg,
HWND hCheck)
{
UNREFERENCED_PARAMETER(hDlg);
UNREFERENCED_PARAMETER(hCheck);
}
//
// Save image
//
DWORD OnOK(
HWND hDlg)
{
PCSAVE_PARAM param;
CHAR path[MAX_PATH];
BOOL overwrite;
BOOL truncate;
DWORD ret;
param = (PCSAVE_PARAM)GetWindowLong(hDlg, GWL_USERDATA);
if (!param) {
return ERROR_INVALID_FUNCTION;
}
// get the target image name
if (GetDlgItemText(hDlg, IDC_TARGETFILE, path, sizeof(path)) == 0) {
return ERROR_INVALID_FUNCTION;
}
if (GetWindowLong(hDlg, DWL_USER)) {
// the target file exists and overwritable
overwrite = (IsDlgButtonChecked(hDlg, IDC_OVERWRITE) == BST_CHECKED);
truncate = (IsDlgButtonChecked(hDlg, IDC_TRUNCATE) == BST_CHECKED);
}
else {
overwrite = FALSE;
truncate = TRUE;
}
retry:
ret = VfdDismountVolume(param->hDevice, FALSE);
if (ret == ERROR_ACCESS_DENIED) {
PSTR msg = ModuleMessage(MSG_UNMOUNT_CONFIRM);
int reply = MessageBox(
hDlg, msg ? msg : "retry", VFD_MSGBOX_TITLE,
MB_ICONEXCLAMATION | MB_CANCELTRYCONTINUE);
if (msg) {
LocalFree(msg);
}
if (reply == IDRETRY) {
goto retry;
}
else if (reply == IDCANCEL) {
return ERROR_CANCELLED;
}
else {
VfdDismountVolume(param->hDevice, TRUE);
}
}
else if (ret != ERROR_SUCCESS) {
MessageBox(hDlg, SystemMessage(ret),
VFD_MSGBOX_TITLE, MB_ICONSTOP);
return ret;
}
ret = VfdSaveImage(param->hDevice, path, overwrite, truncate);
if (ret != ERROR_SUCCESS) {
// show error message
MessageBox(hDlg, SystemMessage(ret),
VFD_MSGBOX_TITLE, MB_ICONSTOP);
}
return ret;
}