mirror of
https://github.com/reactos/reactos.git
synced 2025-05-14 23:03:53 +00:00
582 lines
9.5 KiB
C
582 lines
9.5 KiB
C
![]() |
/*
|
||
|
vfdguiut.c
|
||
|
|
||
|
Virtual Floppy Drive for Windows
|
||
|
Driver control library
|
||
|
open / close / format GUI utility functions
|
||
|
|
||
|
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>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#include "vfdtypes.h"
|
||
|
#include "vfdapi.h"
|
||
|
#include "vfdlib.h"
|
||
|
#ifndef __REACTOS__
|
||
|
#include "vfdmsg.h"
|
||
|
#else
|
||
|
#include "vfdmsg_lib.h"
|
||
|
#endif
|
||
|
#include "vfdguirc.h"
|
||
|
|
||
|
//
|
||
|
// message box constants added since Win2K
|
||
|
//
|
||
|
|
||
|
#ifndef MB_CANCELTRYCONTINUE
|
||
|
#define MB_CANCELTRYCONTINUE 0x00000006L
|
||
|
#endif
|
||
|
|
||
|
#ifndef IDTRYAGAIN
|
||
|
#define IDTRYAGAIN 10
|
||
|
#endif
|
||
|
|
||
|
#ifndef IDCONTINUE
|
||
|
#define IDCONTINUE 11
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// local funcitons
|
||
|
//
|
||
|
static PSTR FormatSizeBytes(ULONG size, PSTR buf)
|
||
|
{
|
||
|
ULONG comma = 1;
|
||
|
int len;
|
||
|
|
||
|
while ((comma * 1000) < size) {
|
||
|
comma *= 1000;
|
||
|
}
|
||
|
|
||
|
len = sprintf(buf, "%lu", size / comma);
|
||
|
|
||
|
while (comma > 1) {
|
||
|
size %= comma;
|
||
|
comma /= 1000;
|
||
|
len += sprintf(buf + len, ",%03lu", size / comma);
|
||
|
}
|
||
|
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
static PSTR FormatSizeUnits(ULONG size, PSTR buf)
|
||
|
{
|
||
|
static const char *name[3] = {
|
||
|
" KB", " MB", " GB"
|
||
|
};
|
||
|
int unit;
|
||
|
double dsize;
|
||
|
|
||
|
if (size < 1000) {
|
||
|
#ifndef __REACTOS__
|
||
|
sprintf(buf, "%u", size);
|
||
|
#else
|
||
|
sprintf(buf, "%lu", size);
|
||
|
#endif
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
dsize = size;
|
||
|
dsize /= 1024;
|
||
|
unit = 0;
|
||
|
|
||
|
while (unit < 2 && dsize >= 1000) {
|
||
|
dsize /= 1000;
|
||
|
unit++;
|
||
|
}
|
||
|
|
||
|
if (dsize < 10) {
|
||
|
sprintf(buf, "%3.2f%s", dsize, name[unit]);
|
||
|
}
|
||
|
else if (dsize < 100) {
|
||
|
sprintf(buf, "%3.1f%s", dsize, name[unit]);
|
||
|
}
|
||
|
else if (dsize < 1000) {
|
||
|
sprintf(buf, "%3.0f%s", dsize, name[unit]);
|
||
|
}
|
||
|
else {
|
||
|
FormatSizeBytes((ULONG)dsize, buf);
|
||
|
strcat(buf, name[unit]);
|
||
|
}
|
||
|
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Close the current image
|
||
|
//
|
||
|
DWORD WINAPI VfdGuiClose(
|
||
|
HWND hParent, // parent window
|
||
|
ULONG nDevice) // device number
|
||
|
{
|
||
|
HANDLE hDevice;
|
||
|
SAVE_PARAM param;
|
||
|
CHAR path[MAX_PATH];
|
||
|
HCURSOR hourglass;
|
||
|
DWORD ret;
|
||
|
int reply;
|
||
|
|
||
|
VFDTRACE(0, ("VfdGuiClose()\n"));
|
||
|
|
||
|
hDevice = VfdOpenDevice(nDevice);
|
||
|
|
||
|
if (hDevice == INVALID_HANDLE_VALUE) {
|
||
|
return GetLastError();
|
||
|
}
|
||
|
|
||
|
// get current image information
|
||
|
|
||
|
ret = VfdGetImageInfo(
|
||
|
hDevice,
|
||
|
path,
|
||
|
¶m.DiskType,
|
||
|
¶m.MediaType,
|
||
|
¶m.MediaFlags,
|
||
|
¶m.FileType,
|
||
|
¶m.ImageSize);
|
||
|
|
||
|
if (ret != ERROR_SUCCESS) {
|
||
|
CloseHandle(hDevice);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
param.hDevice = hDevice;
|
||
|
param.ImageName = path;
|
||
|
|
||
|
// check if RAM image is modified
|
||
|
|
||
|
if (param.MediaFlags & VFD_FLAG_DATA_MODIFIED) {
|
||
|
PSTR msg = ModuleMessage(MSG_MEDIA_MODIFIED);
|
||
|
|
||
|
for (;;) {
|
||
|
reply = MessageBox(hParent, msg ? msg : "save?",
|
||
|
VFD_MSGBOX_TITLE, MB_ICONQUESTION | MB_YESNOCANCEL);
|
||
|
|
||
|
if (reply != IDYES) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (GuiSaveParam(hParent, ¶m) == ERROR_SUCCESS) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (msg) {
|
||
|
LocalFree(msg);
|
||
|
}
|
||
|
|
||
|
if (reply == IDCANCEL) {
|
||
|
CloseHandle(hDevice);
|
||
|
return ERROR_CANCELLED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// close the image
|
||
|
|
||
|
hourglass = LoadCursor(NULL, IDC_WAIT);
|
||
|
|
||
|
for (;;) {
|
||
|
|
||
|
// show the hourglass cursor
|
||
|
|
||
|
HCURSOR original = SetCursor(hourglass);
|
||
|
|
||
|
// close the current image
|
||
|
|
||
|
ret = VfdCloseImage(hDevice, FALSE);
|
||
|
|
||
|
// restore the original cursor
|
||
|
|
||
|
SetCursor(original);
|
||
|
|
||
|
if (ret != ERROR_ACCESS_DENIED) {
|
||
|
// success or errors other than access denied
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (IS_WINDOWS_NT()) {
|
||
|
|
||
|
// Windows NT -- cannot force close
|
||
|
// show retry / cancel message box
|
||
|
|
||
|
PSTR msg = ModuleMessage(MSG_UNMOUNT_FAILED);
|
||
|
|
||
|
reply = MessageBox(
|
||
|
hParent, msg ? msg : "retry", VFD_MSGBOX_TITLE,
|
||
|
MB_ICONEXCLAMATION | MB_RETRYCANCEL);
|
||
|
|
||
|
if (msg) {
|
||
|
LocalFree(msg);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
// Windows 2000 and later -- possible to force
|
||
|
// show cancel / retry / continue message box
|
||
|
|
||
|
PSTR msg = ModuleMessage(MSG_UNMOUNT_CONFIRM);
|
||
|
|
||
|
reply = MessageBox(
|
||
|
hParent, msg ? msg : "retry", VFD_MSGBOX_TITLE,
|
||
|
MB_ICONEXCLAMATION | MB_CANCELTRYCONTINUE);
|
||
|
|
||
|
if (msg) {
|
||
|
LocalFree(msg);
|
||
|
}
|
||
|
|
||
|
if (reply == IDCONTINUE) {
|
||
|
|
||
|
// try forced close
|
||
|
|
||
|
ret = VfdCloseImage(hDevice, TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (reply == IDCANCEL) {
|
||
|
ret = ERROR_CANCELLED;
|
||
|
break;
|
||
|
}
|
||
|
else if (reply == IDCONTINUE) {
|
||
|
|
||
|
// try forced close
|
||
|
|
||
|
ret = VfdCloseImage(hDevice, TRUE);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CloseHandle(hDevice);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Format the current media
|
||
|
//
|
||
|
DWORD WINAPI VfdGuiFormat(
|
||
|
HWND hParent, // parent window
|
||
|
ULONG nDevice) // device number
|
||
|
{
|
||
|
HANDLE hDevice;
|
||
|
ULONG ret;
|
||
|
PSTR msg;
|
||
|
|
||
|
msg = ModuleMessage(MSG_FORMAT_WARNING);
|
||
|
|
||
|
ret = MessageBox(hParent,
|
||
|
msg ? msg : "Format?",
|
||
|
VFD_MSGBOX_TITLE,
|
||
|
MB_ICONEXCLAMATION | MB_OKCANCEL);
|
||
|
|
||
|
if (msg) {
|
||
|
LocalFree(msg);
|
||
|
}
|
||
|
|
||
|
if (ret == IDCANCEL) {
|
||
|
MessageBox(hParent,
|
||
|
SystemMessage(ERROR_CANCELLED),
|
||
|
VFD_MSGBOX_TITLE, MB_ICONSTOP);
|
||
|
|
||
|
return ERROR_CANCELLED;
|
||
|
}
|
||
|
|
||
|
hDevice = VfdOpenDevice(nDevice);
|
||
|
|
||
|
if (hDevice == INVALID_HANDLE_VALUE) {
|
||
|
ret = GetLastError();
|
||
|
}
|
||
|
else {
|
||
|
HCURSOR original;
|
||
|
|
||
|
retry:
|
||
|
original = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
||
|
|
||
|
ret = VfdDismountVolume(hDevice, FALSE);
|
||
|
|
||
|
if (ret == ERROR_ACCESS_DENIED) {
|
||
|
PSTR msg;
|
||
|
int reply;
|
||
|
|
||
|
SetCursor(original);
|
||
|
|
||
|
msg = ModuleMessage(MSG_UNMOUNT_CONFIRM);
|
||
|
|
||
|
reply = MessageBox(
|
||
|
hParent, msg ? msg : "retry", VFD_MSGBOX_TITLE,
|
||
|
MB_ICONEXCLAMATION | MB_CANCELTRYCONTINUE);
|
||
|
|
||
|
if (msg) {
|
||
|
LocalFree(msg);
|
||
|
}
|
||
|
|
||
|
if (reply == IDRETRY) {
|
||
|
goto retry;
|
||
|
}
|
||
|
else if (reply == IDCANCEL) {
|
||
|
ret = ERROR_CANCELLED;
|
||
|
}
|
||
|
else {
|
||
|
VfdDismountVolume(hDevice, TRUE);
|
||
|
ret = ERROR_SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ret == ERROR_SUCCESS) {
|
||
|
ret = VfdFormatMedia(hDevice);
|
||
|
}
|
||
|
|
||
|
SetCursor(original);
|
||
|
|
||
|
CloseHandle(hDevice);
|
||
|
}
|
||
|
|
||
|
MessageBox(hParent,
|
||
|
SystemMessage(ret),
|
||
|
VFD_MSGBOX_TITLE,
|
||
|
ret == ERROR_SUCCESS ? MB_ICONINFORMATION : MB_ICONSTOP);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set a text to a dialog control
|
||
|
//
|
||
|
void SetControlText(
|
||
|
HWND hWnd,
|
||
|
UINT nCtrl,
|
||
|
DWORD nMsg)
|
||
|
{
|
||
|
PSTR p = NULL;
|
||
|
|
||
|
if (nMsg) {
|
||
|
p = ModuleMessage(nMsg);
|
||
|
}
|
||
|
|
||
|
if (nCtrl) {
|
||
|
SetDlgItemText(hWnd, nCtrl, p);
|
||
|
}
|
||
|
else {
|
||
|
SetWindowText(hWnd, p);
|
||
|
}
|
||
|
|
||
|
if (p) {
|
||
|
LocalFree(p);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Make file description text
|
||
|
//
|
||
|
void WINAPI VfdMakeFileDesc(
|
||
|
PSTR pBuffer,
|
||
|
ULONG nBufSize,
|
||
|
VFD_FILETYPE nFileType,
|
||
|
ULONG nFileSize,
|
||
|
DWORD nFileAttr)
|
||
|
{
|
||
|
PSTR type_str;
|
||
|
PSTR size_str;
|
||
|
PSTR attr_ro;
|
||
|
PSTR attr_enc;
|
||
|
PSTR attr_cmp;
|
||
|
|
||
|
ZeroMemory(pBuffer, nBufSize);
|
||
|
|
||
|
switch (nFileType) {
|
||
|
case VFD_FILETYPE_RAW:
|
||
|
type_str = ModuleMessage(MSG_FILETYPE_RAW);
|
||
|
break;
|
||
|
|
||
|
case VFD_FILETYPE_ZIP:
|
||
|
type_str = ModuleMessage(MSG_FILETYPE_ZIP);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
type_str = NULL;
|
||
|
}
|
||
|
|
||
|
if (nFileSize == INVALID_FILE_SIZE) {
|
||
|
size_str = ModuleMessage(MSG_DESC_NEW_FILE);
|
||
|
}
|
||
|
else {
|
||
|
CHAR buf[20], buf2[20];
|
||
|
size_str = ModuleMessage(MSG_DESC_FILESIZE,
|
||
|
FormatSizeBytes(nFileSize, buf),
|
||
|
FormatSizeUnits(nFileSize, buf2));
|
||
|
}
|
||
|
|
||
|
attr_ro = NULL;
|
||
|
attr_cmp = NULL;
|
||
|
attr_enc = NULL;
|
||
|
|
||
|
if (nFileAttr != INVALID_FILE_ATTRIBUTES) {
|
||
|
if (nFileAttr & FILE_ATTRIBUTE_READONLY) {
|
||
|
attr_ro = ModuleMessage(MSG_ATTR_READONLY);
|
||
|
}
|
||
|
|
||
|
if (nFileAttr & FILE_ATTRIBUTE_COMPRESSED) {
|
||
|
attr_cmp = ModuleMessage(MSG_ATTR_COMPRESSED);
|
||
|
}
|
||
|
|
||
|
if (nFileAttr & FILE_ATTRIBUTE_ENCRYPTED) {
|
||
|
attr_enc = ModuleMessage(MSG_ATTR_ENCRYPTED);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_snprintf(pBuffer, nBufSize - 1, "%s %s %s %s %s",
|
||
|
type_str ? type_str : "",
|
||
|
size_str ? size_str : "",
|
||
|
attr_ro ? attr_ro : "",
|
||
|
attr_cmp ? attr_cmp : "",
|
||
|
attr_enc ? attr_enc : "");
|
||
|
|
||
|
if (type_str) {
|
||
|
LocalFree(type_str);
|
||
|
}
|
||
|
if (size_str) {
|
||
|
LocalFree(size_str);
|
||
|
}
|
||
|
if (attr_ro) {
|
||
|
LocalFree(attr_ro);
|
||
|
}
|
||
|
if (attr_cmp) {
|
||
|
LocalFree(attr_cmp);
|
||
|
}
|
||
|
if (attr_enc) {
|
||
|
LocalFree(attr_enc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ShowContextMenu(
|
||
|
HWND hDlg,
|
||
|
HWND hCtl,
|
||
|
LPARAM lParam)
|
||
|
{
|
||
|
POINT pt;
|
||
|
UINT id;
|
||
|
HMENU hMenu;
|
||
|
|
||
|
pt.x = ((int)(short)LOWORD(lParam));
|
||
|
pt.y = ((int)(short)HIWORD(lParam));
|
||
|
|
||
|
if (pt.x == -1 || pt.y == -1) {
|
||
|
RECT rc;
|
||
|
|
||
|
GetWindowRect(hCtl, &rc);
|
||
|
pt.x = (rc.left + rc.right) / 2;
|
||
|
pt.y = (rc.top + rc.bottom) / 2;
|
||
|
|
||
|
id = GetDlgCtrlID(hCtl);
|
||
|
}
|
||
|
else {
|
||
|
POINT pt2 = pt;
|
||
|
|
||
|
ScreenToClient(hDlg, &pt2);
|
||
|
|
||
|
id = GetDlgCtrlID(
|
||
|
ChildWindowFromPoint(hDlg, pt2));
|
||
|
}
|
||
|
|
||
|
if (id < IDC_IMAGEFILE_LABEL ||
|
||
|
id > IDC_TRUNCATE) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
hMenu = CreatePopupMenu();
|
||
|
|
||
|
AppendMenu(hMenu, MF_STRING, 1, "&What's This");
|
||
|
|
||
|
if (TrackPopupMenu(hMenu, TPM_RETURNCMD,
|
||
|
pt.x, pt.y, 0, hDlg, NULL))
|
||
|
{
|
||
|
ShowHelpWindow(hDlg, id);
|
||
|
}
|
||
|
|
||
|
DestroyMenu(hMenu);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Show tool tip help
|
||
|
//
|
||
|
void ShowHelpWindow(
|
||
|
HWND hDlg,
|
||
|
UINT nCtl)
|
||
|
{
|
||
|
UINT msg;
|
||
|
RECT rc;
|
||
|
PSTR help;
|
||
|
|
||
|
switch (nCtl) {
|
||
|
case IDC_IMAGEFILE_LABEL:
|
||
|
case IDC_IMAGEFILE:
|
||
|
msg = MSG_HELP_IMAGEFILE;
|
||
|
break;
|
||
|
case IDC_IMAGEDESC_LABEL:
|
||
|
case IDC_IMAGEFILE_DESC:
|
||
|
msg = MSG_HELP_IMAGEDESC;
|
||
|
break;
|
||
|
case IDC_TARGETFILE_LABEL:
|
||
|
case IDC_TARGETFILE:
|
||
|
msg = MSG_HELP_TARGETFILE;
|
||
|
break;
|
||
|
case IDC_DISKTYPE_LABEL:
|
||
|
case IDC_DISKTYPE:
|
||
|
case IDC_DISKTYPE_FILE:
|
||
|
case IDC_DISKTYPE_RAM:
|
||
|
msg = MSG_HELP_DISKTYPE;
|
||
|
break;
|
||
|
case IDC_MEDIATYPE_LABEL:
|
||
|
case IDC_MEDIATYPE:
|
||
|
msg = MSG_HELP_MEDIATYPE;
|
||
|
break;
|
||
|
case IDC_WRITE_PROTECTED:
|
||
|
msg = MSG_HELP_PROTECT_NOW;
|
||
|
break;
|
||
|
case IDC_OPEN_PROTECTED:
|
||
|
msg = MSG_HELP_PROTECT_OPEN;
|
||
|
break;
|
||
|
case IDC_BROWSE:
|
||
|
msg = MSG_HELP_BROWSE;
|
||
|
break;
|
||
|
case IDC_OPEN:
|
||
|
msg = MSG_HELP_OPEN;
|
||
|
break;
|
||
|
case IDC_SAVE:
|
||
|
msg = MSG_HELP_SAVE;
|
||
|
break;
|
||
|
case IDC_CLOSE:
|
||
|
msg = MSG_HELP_CLOSE;
|
||
|
break;
|
||
|
case IDC_FORMAT:
|
||
|
msg = MSG_HELP_FORMAT;
|
||
|
break;
|
||
|
case IDC_CONTROL:
|
||
|
msg = MSG_HELP_CONTROL;
|
||
|
break;
|
||
|
case IDC_OVERWRITE:
|
||
|
msg = MSG_HELP_OVERWRITE;
|
||
|
break;
|
||
|
case IDC_TRUNCATE:
|
||
|
msg = MSG_HELP_TRUNCATE;
|
||
|
break;
|
||
|
default:
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
GetWindowRect(GetDlgItem(hDlg, nCtl), &rc);
|
||
|
|
||
|
help = ModuleMessage(msg);
|
||
|
|
||
|
if (help) {
|
||
|
VfdToolTip(hDlg, help, rc.left, (rc.top + rc.bottom) / 2, TRUE);
|
||
|
LocalFree(help);
|
||
|
}
|
||
|
}
|
||
|
|