ReactOS 0.4.16-dev-122-g325d74c
vfdcmd.c
Go to the documentation of this file.
1/*
2 vfdcmd.c
3
4 Virtual Floppy Drive for Windows
5 Driver control program (console version)
6
7 Copyright (C) 2003-2008 Ken Kato
8*/
9
10#ifdef __cplusplus
11#pragma message(__FILE__": Compiled as C++ for testing purpose.")
12#endif // __cplusplus
13
14#define WIN32_LEAN_AND_MEAN
15#define _CRTDBG_MAP_ALLOC
16#include <windows.h>
17#include <stdio.h>
18#include <stdarg.h>
19#include <stdlib.h>
20#include <crtdbg.h>
21
22#ifndef INVALID_FILE_ATTRIBUTES
23#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
24#endif // INVALID_FILE_ATTRIBUTES
25
26#include "vfdtypes.h"
27#include "vfdapi.h"
28#include "vfdver.h"
29#include "vfdmsg.h"
30
31//
32// current driver state
33//
35
36//
37// interactive flag
38//
39static const char *help_progname = "VFD.EXE ";
40
41//
42// command functions return value
43//
44#define VFD_OK 0
45#define VFD_NG 1
46
47//
48// operation mode
49//
50#define OPERATION_ASK 0 // ask user on error
51#define OPERATION_QUIT 1 // quits on error
52#define OPERATION_FORCE 2 // force on error
53
54//
55// invalid target number
56//
57#define TARGET_NONE (ULONG)-1
58
59//
60// command processing functions
61//
62typedef int (*cmdfnc)(const char **args);
63
64static int Install(const char **args);
65static int Remove(const char **args);
66static int Config(const char **args);
67static int Start(const char **args);
68static int Stop(const char **args);
69static int Shell(const char **args);
70static int Open(const char **args);
71static int Close(const char **args);
72static int Save(const char **args);
73static int Protect(const char **args);
74static int Format(const char **args);
75static int Link(const char **args);
76static int Unlink(const char **args);
77static int Status(const char **args);
78static int Help(const char **args);
79static int Version(const char **args);
80
81//
82// Command table
83//
84static const struct {
85 char *cmd; // command string
86 int max_args; // maximum allowed number of argc
87 cmdfnc func; // command processing function
88 DWORD hint; // command hint message id
89}
90Commands[] = {
91 {"INSTALL", 2, Install, MSG_HINT_INSTALL},
92 {"REMOVE", 1, Remove, MSG_HINT_REMOVE },
93 {"CONFIG", 1, Config, MSG_HINT_CONFIG },
94 {"START", 0, Start, MSG_HINT_START },
95 {"STOP", 1, Stop, MSG_HINT_STOP },
96 {"SHELL", 1, Shell, MSG_HINT_SHELL },
97 {"OPEN", 6, Open, MSG_HINT_OPEN },
98 {"CLOSE", 2, Close, MSG_HINT_CLOSE },
99 {"SAVE", 3, Save, MSG_HINT_SAVE, },
100 {"PROTECT", 2, Protect, MSG_HINT_PROTECT},
101 {"FORMAT", 2, Format, MSG_HINT_FORMAT },
102 {"LINK", 3, Link, MSG_HINT_LINK },
103 {"ULINK", 1, Unlink, MSG_HINT_ULINK },
104 {"STATUS", 0, Status, MSG_HINT_STATUS },
105 {"HELP", 1, Help, MSG_HELP_HELP },
106 {"?", 1, Help, MSG_HELP_HELP },
107 {"VERSION", 0, Version, MSG_HINT_VERSION},
108 {0, 0, 0, 0}
110
111//
112// Help message table
113//
114static const struct {
115 char *keyword; // help keyword
116 DWORD help; // help message id
117}
118HelpMsg[] = {
119 {"GENERAL", MSG_HELP_GENERAL},
120 {"CONSOLE", MSG_HELP_CONSOLE},
121 {"INSTALL", MSG_HELP_INSTALL},
122 {"REMOVE", MSG_HELP_REMOVE },
123 {"CONFIG", MSG_HELP_CONFIG },
124 {"START", MSG_HELP_START },
125 {"STOP", MSG_HELP_STOP },
126 {"SHELL", MSG_HELP_SHELL },
127 {"OPEN", MSG_HELP_OPEN },
128 {"CLOSE", MSG_HELP_CLOSE },
129 {"SAVE", MSG_HELP_SAVE },
130 {"PROTECT", MSG_HELP_PROTECT},
131 {"FORMAT", MSG_HELP_FORMAT },
132 {"LINK", MSG_HELP_LINK },
133 {"ULINK", MSG_HELP_ULINK },
134 {"STATUS", MSG_HELP_STATUS },
135 {"HELP", MSG_HELP_HELP },
136 {"VERSION", MSG_HINT_VERSION},
137 {0, 0}
139
140//
141// local functions
142//
143static int InteractiveConsole();
144static int ProcessCommandLine(int argc, const char **args);
145static int ParseCommand(const char *cmd);
146static int ParseHelpTopic(const char *topic);
147static int CheckDriver();
148static int InputChar(ULONG msg, PCSTR ans);
149static void PrintImageInfo(HANDLE hDevice);
150static void PrintDriveLetter(HANDLE hDevice, ULONG nDrive);
151static void PrintMessage(UINT msg, ...);
152static BOOL ConsolePager(char *pBuffer, BOOL bReset);
153static const char *SystemError(DWORD err);
154static void ConvertPathCase(char *src, char *dst);
155
156//
157// utility macro
158//
159#define IS_WINDOWS_NT() ((GetVersion() & 0xff) < 5)
160
161//
162// main
163//
164int main(int argc, const char **argv)
165{
166#ifdef _DEBUG
167
168 // output vfd.exe command reference text
169
170 if (*(argv + 1) && !_stricmp(*(argv + 1), "doc")) {
171 int idx = 0;
172 char *buf = "";
173
174 printf("\r\n VFD.EXE Command Reference\r\n");
175
176 while (HelpMsg[idx].keyword) {
177 int len = strlen(HelpMsg[idx].keyword);
178
179 printf(
180 "\r\n\r\n"
181 "====================\r\n"
182 "%*s\r\n"
183 "====================\r\n"
184 "\r\n",
185 (20 + len) / 2, HelpMsg[idx].keyword);
186
191 NULL, HelpMsg[idx].help, 0,
192 (LPTSTR)&buf, 0, (va_list *)&help_progname);
193
194 printf("%s", buf);
195
196 LocalFree(buf);
197
198 idx++;
199 }
200
201 return 0;
202 }
203#endif
204
205 // Reports memory leaks at process termination
206
208
209 // Check the operating system version
210
211 if (!VfdIsValidPlatform()) {
212 PrintMessage(MSG_WRONG_PLATFORM);
213 return VFD_NG;
214 }
215
216 if (argc < 2) {
217 // If no parameter is given, enter the interactive mode
218
219 return InteractiveConsole();
220 }
221 else {
222 // Perform a single operation
223
224 return ProcessCommandLine(argc - 1, argv + 1);
225 }
226}
227
228//
229// VFD interactive console
230//
232{
233 char input[1024]; // user input buffer
234
235 int argc; // number of args in the user input
236 char *args[10]; // args to pass to command functions
237
238 char sepa; // argument separator
239 char *p; // work pointer
240
241 // Disable the system default Ctrl+C handler
242
244
245 // Set the console title
246
248
249 // print version information and the console hint text
250
251 Version(NULL);
252
253 PrintMessage(MSG_CONSOLE_HINT);
254
255 // set interactive flag to exclude "VFD.EXE" from help text
256
257 help_progname = "";
258
259 // process user input
260
261 for (;;) {
262
263 // print the prompt
264
265 printf("[VFD] ");
266 fflush(stdout);
267
268 // read user input
269
270 fflush(stdin);
271 p = fgets(input, sizeof(input), stdin);
272
273 if (p == NULL) {
274
275 // most likely <ctrl+c>
276
277 printf("exit\n");
278 break;
279 }
280
281 // skip leading blank characters
282
283 while (*p == ' ' || *p == '\t' || *p == '\n') {
284 p++;
285 }
286
287 if (*p == '\0') {
288
289 // empty input
290
291 continue;
292 }
293
294 // handle external commands
295
296 if (!_strnicmp(p, "dir", 3) ||
297 !_strnicmp(p, "attrib", 6)) {
298
299 // special cases - frequently used commands
300 // pass these to system() even without '.'
301
302 system(p);
303 printf("\n");
304 continue;
305 }
306 else if (*p == '.') {
307
308 // external command
309
310 system(p + 1);
311 printf("\n");
312 continue;
313 }
314
315 // split the input line into parameters (10 parameters max)
316
317 argc = 0;
318 ZeroMemory(args, sizeof(args));
319
320 do {
321 // top of a parameter
322
323 args[argc++] = p;
324
325 // is the parameter quoted?
326
327 if (*p == '\"' || *p == '\'') {
328 sepa = *(p++);
329 }
330 else {
331 sepa = ' ';
332 }
333
334 // search the end of the parameter
335
336 while (*p && *p != '\n') {
337 if (sepa == ' ') {
338 if (*p == '\t' || *p == ' ') {
339 break; // tail of a non-quoted parameter
340 }
341 }
342 else {
343 if (*p == sepa) {
344 sepa = ' '; // close quote
345 }
346 }
347 p++;
348 }
349
350 // terminate the parameter
351
352 if (*p) {
353 *(p++) = '\0';
354 }
355
356 // skip trailing blank characters
357
358 while (*p == ' ' || *p == '\t' || *p == '\n') {
359 p++;
360 }
361
362 if (*p == '\0') {
363
364 // end of the input line - no more args
365
366 break;
367 }
368 }
369 while (argc < sizeof(args) / sizeof(args[0]));
370
371 // check the first parameter for special commands
372
373 if (!_stricmp(args[0], "exit") ||
374 !_stricmp(args[0], "quit") ||
375 !_stricmp(args[0], "bye")) {
376
377 // exit command
378
379 break;
380 }
381 else if (!_stricmp(args[0], "cd") ||
382 !_stricmp(args[0], "chdir")) {
383
384 // internal change directory command
385
386 if (args[1]) {
387 char path[MAX_PATH];
388 int i;
389
390 // ignore the /d option (of the standard cd command)
391
392 if (_stricmp(args[1], "/d")) {
393 i = 1;
394 }
395 else {
396 i = 2;
397 }
398
399 p = args[i];
400
401 if (*p == '\"' || *p == '\'') {
402
403 // the parameter is quoted -- remove quotations
404
405 p++;
406
407 while (*p && *p != *args[i]) {
408 p++;
409 }
410
411 args[i]++; // skip a leading quote
412 *p = '\0'; // remove a trailing quote
413 }
414 else {
415
416 // the parameter is not quoted
417 // -- concatenate params to allow spaces in unquoted path
418
419 while (i < argc - 1) {
420 *(args[i] + strlen(args[i])) = ' ';
421 i++;
422 }
423 }
424
425 // Match the case of the path to the name on the disk
426
428
431
432 if (ret == ERROR_FILE_NOT_FOUND) {
434 }
435
436 printf("%s", SystemError(ret));
437 }
438 }
439 else {
440 if (!GetCurrentDirectory(sizeof(input), input)) {
442 }
443 else {
444 printf("%s\n", input);
445 }
446 }
447 }
448 else if (isalpha(*args[0]) &&
449 *(args[0] + 1) == ':' &&
450 *(args[0] + 2) == '\0') {
451
452 // internal change drive command
453
454 *args[0] = (char)toupper(*args[0]);
455 *(args[0] + 2) = '\\';
456 *(args[0] + 3) = '\0';
457
458 if (!SetCurrentDirectory(args[0])) {
460 }
461 }
462 else {
463
464 // perform the requested VFD command
465
466 ProcessCommandLine(argc, (const char **)args);
467 }
468
469 printf("\n");
470 }
471
472 return VFD_OK;
473}
474
475//
476// process a single command
477//
478int ProcessCommandLine(int argc, const char **args)
479{
480 int cmd;
481 DWORD ret;
482
483 //
484 // Decide a command to perform
485 //
487
488 if (cmd < 0) {
489
490 // no matching command
491
492 return VFD_NG;
493 }
494
495 if (*(++args) &&
496 (!strcmp(*args, "/?") ||
497 !_stricmp(*args, "/h"))) {
498
499 // print a short hint for the command
500
502 return VFD_NG;
503 }
504
505 if (--argc > Commands[cmd].max_args) {
506
507 // too many parameters for the command
508
509 PrintMessage(MSG_TOO_MANY_ARGS);
511 return VFD_NG;
512 }
513
514 // Get the current driver state
515
517
518 if (ret != ERROR_SUCCESS) {
519 PrintMessage(MSG_GET_STAT_NG);
520 printf("%s", SystemError(ret));
521 return VFD_NG;
522 }
523
524 // Perform the requested operation
525
526 return (*Commands[cmd].func)(args);
527}
528
529//
530// Install the Virtual Floppy Driver
531// Command Line Parameters:
532// (optional) driver file path - default to executive's dir
533// (optional) auto start switch - default to demand start
534//
535int Install(const char **args)
536{
537 const char *install_path = NULL;
538 DWORD start_type = SERVICE_DEMAND_START;
539
540 DWORD ret;
541
542 // process parameters
543
544 while (args && *args) {
545
546 if (!_stricmp(*args, "/a") ||
547 !_stricmp(*args, "/auto")) {
548
549 if (start_type != SERVICE_DEMAND_START) {
550 PrintMessage(MSG_DUPLICATE_ARGS, *args);
551 return VFD_NG;
552 }
553/*
554 if (IS_WINDOWS_NT()) {
555
556 // On Windows NT, SYSTEM start drivers must be placed
557 // under the winnt\system32 directory. Since I don't
558 // care to handle driver file copying, I use the AUTO
559 // start method for Windows NT.
560
561 start_type = SERVICE_AUTO_START;
562 }
563 else {
564
565 // On Windows XP, the VFD driver must be running when
566 // the shell starts -- otherwise the shell doesn't
567 // recognize the VFD drives. Since Windows XP allows
568 // SYSTEM start drivers to be placed in any local
569 // directories, I use the SYSTEM start method here.
570 //
571 // This is not an issue when the driver is started
572 // manually because in that case VFD.EXE and VFDWIN.EXE
573 // notify the shell of the VFD drives.
574 //
575 // On Windows 2000 both SYSTEM and AUTO work fine.
576
577 start_type = SERVICE_SYSTEM_START;
578 }
579*/
580 // On second thought -- Win2K / XP mount manager assigns
581 // arbitrary drive letters to all drives it finds during
582 // the system start up. There is no way to prevent it
583 // until the driver is fully PnP compatible, so I'd settle
584 // for AUTO start for the time being.
585
586 start_type = SERVICE_AUTO_START;
587 }
588 else if (**args == '/') {
589 PrintMessage(MSG_UNKNOWN_OPTION, *args);
590 PrintMessage(MSG_HINT_INSTALL, help_progname);
591 return VFD_NG;
592 }
593 else {
594 if (install_path) {
595 PrintMessage(MSG_DUPLICATE_ARGS, "path");
596 return VFD_NG;
597 }
598
599 install_path = *args;
600 }
601
602 args++;
603 }
604
605 // already installed?
606
608 PrintMessage(MSG_DRIVER_EXISTS);
609 return VFD_NG;
610 }
611
612 // install the driver
613
615 install_path,
616 start_type);
617
618 if (ret != ERROR_SUCCESS) {
619 PrintMessage(MSG_INSTALL_NG);
620 printf("%s", SystemError(ret));
621 return VFD_NG;
622 }
623
624 // Get the latest driver state
625
627
628 if (ret != ERROR_SUCCESS) {
629 PrintMessage(MSG_GET_STAT_NG);
630 printf("%s", SystemError(ret));
631 return VFD_NG;
632 }
633
634 // operation successfull
635
636 PrintMessage(MSG_INSTALL_OK);
637
638 return VFD_OK;
639}
640
641//
642// Remove Virtual Floppy Driver from system
643// Command Line Parameters:
644// [/F | /FORCE | /Q | /QUIT]
645// /F forces remove operation if the driver cannot be stopped
646// /Q quits remove operation if the driver cannot be stopped
647//
648int Remove(const char **args)
649{
650 int mode = OPERATION_ASK;
651 const char *stop_params[] = { NULL, NULL };
652 DWORD ret;
653 int idx;
654
655 // parse parameters
656
657 while (args && *args) {
658
659 if (!_stricmp(*args, "/f") ||
660 !_stricmp(*args, "/force")) {
661
662 if (mode != OPERATION_ASK) {
663 PrintMessage(MSG_DUPLICATE_ARGS, *args);
664 return VFD_NG;
665 }
666
668 stop_params[0] = *args;
669 }
670 else if (!_stricmp(*args, "/q") ||
671 !_stricmp(*args, "/quit")) {
672
673 if (mode != OPERATION_ASK) {
674 PrintMessage(MSG_DUPLICATE_ARGS, *args);
675 return VFD_NG;
676 }
677
679 stop_params[0] = *args;
680 }
681 else {
682 PrintMessage(MSG_UNKNOWN_OPTION, *args);
683 PrintMessage(MSG_HINT_REMOVE, help_progname);
684 return VFD_NG;
685 }
686
687 args++;
688 }
689
690 // ensure the driver is installed
691
693 PrintMessage(MSG_NOT_INSTALLED);
694 return VFD_NG;
695 }
696
697 // ensure the driver is stopped
698
700
701 // Try to stop with the same command line option (/F or /Q)
702
703 while (Stop(stop_params) != VFD_OK) {
704
705 // stop failed
706
707 if (mode == OPERATION_FORCE) {
708 PrintMessage(MSG_REMOVE_FORCE);
709 break;
710 }
711 else if (mode == OPERATION_QUIT) {
712 PrintMessage(MSG_REMOVE_QUIT);
713 return VFD_NG;
714 }
715 else {
716 int c;
717
718 PrintMessage(MSG_REMOVE_WARN);
719
720 c = InputChar(MSG_RETRY_FORCE_CANCEL, "rfc");
721
722 if (c == 'f') { // force
723 break;
724 }
725 else if (c == 'c') { // cancel
726 return VFD_NG;
727 }
728 }
729 }
730 }
731
732 // remove the driver
733
735
736 if (ret != ERROR_SUCCESS) {
737 PrintMessage(MSG_REMOVE_NG);
738 printf("%s", SystemError(ret));
739 return VFD_NG;
740 }
741
742 // Wait for the driver to be actually removed for 3 secs Max.
743
744 for (idx = 0; idx < 10; idx++) {
745
747
748 if (ret != ERROR_SUCCESS) {
749 PrintMessage(MSG_GET_STAT_NG);
750 printf("%s", SystemError(ret));
751 return VFD_NG;
752 }
753
755 break;
756 }
757
758 Sleep(300);
759 }
760
762 PrintMessage(MSG_REMOVE_PENDING);
763 return VFD_NG;
764 }
765
766 // operation successful
767
768 PrintMessage(MSG_REMOVE_OK);
769
770 return VFD_OK;
771}
772
773//
774// Configure the Virtual Floppy Driver
775// Command Line Parameters:
776// /auto, /manual
777//
778int Config(const char **args)
779{
780 DWORD start_type = SERVICE_DISABLED;
781 DWORD ret;
782
783 while (args && *args) {
784 if (!_stricmp(*args, "/a") ||
785 !_stricmp(*args, "/auto")) {
786
787 if (start_type != SERVICE_DISABLED) {
788 PrintMessage(MSG_DUPLICATE_ARGS, *args);
789 return VFD_NG;
790 }
791
792 start_type = SERVICE_AUTO_START;
793 }
794 else if (!_stricmp(*args, "/m") ||
795 !_stricmp(*args, "/manual")) {
796
797 if (start_type != SERVICE_DISABLED) {
798 PrintMessage(MSG_DUPLICATE_ARGS, *args);
799 return VFD_NG;
800 }
801
802 start_type = SERVICE_DEMAND_START;
803 }
804 else {
805 PrintMessage(MSG_UNKNOWN_OPTION, *args);
806 PrintMessage(MSG_HINT_CONFIG, help_progname);
807 return VFD_NG;
808 }
809
810 args++;
811 }
812
813 if (start_type == SERVICE_DISABLED) {
814 // no parameter is specified
815 PrintMessage(MSG_HINT_CONFIG, help_progname);
816 return VFD_NG;
817 }
818
819 // ensure that the driver is installed
820
822 PrintMessage(MSG_NOT_INSTALLED);
823 return VFD_NG;
824 }
825
826 // ensure that the driver is up to date
827
828 if (CheckDriver() != VFD_OK) {
829 return VFD_NG;
830 }
831
832 // configure the driver
833
834 ret = VfdConfigDriver(start_type);
835
836 if (ret != ERROR_SUCCESS) {
837 PrintMessage(MSG_CONFIG_NG);
838 printf("%s", SystemError(ret));
839 return VFD_NG;
840 }
841
842 // operation successfull
843
844 PrintMessage(MSG_CONFIG_OK);
845
846 return VFD_OK;
847}
848
849//
850// Start the Virtual Floppy Driver
851// Command Line Parameters: None
852//
853int Start(const char **args)
854{
855 DWORD ret;
856
858
859 // ensure that the driver is installed
860
862 Install(NULL) != VFD_OK) {
863 return VFD_NG;
864 }
865
866 // ensure that the driver is up to date
867
868 if (CheckDriver() != VFD_OK) {
869 return VFD_NG;
870 }
871
872 // ensure that the driver is not running
873
875 PrintMessage(MSG_ALREADY_RUNNING);
876 return VFD_NG;
877 }
878
879 // start the driver
880
882
883 if (ret != ERROR_SUCCESS) {
884 PrintMessage(MSG_START_NG);
885 printf("%s", SystemError(ret));
886 return VFD_NG;
887 }
888
889 // operation successfull
890
891 PrintMessage(MSG_START_OK);
892
893 return VFD_OK;
894}
895
896//
897// Stop the Virtual Floppy Driver
898// Command Line Parameters:
899// /FORCE | /F Forces the operation on error
900// /QUIT | /Q Quits the operation on error
901//
902int Stop(const char **args)
903{
904 int mode = OPERATION_ASK;
905 const char *close_params[] = { "*", NULL, NULL };
906 DWORD ret;
907
908 while (args && *args) {
909 if (!_stricmp(*args, "/f") ||
910 !_stricmp(*args, "/force")) {
911
912 if (mode != OPERATION_ASK) {
913 PrintMessage(MSG_DUPLICATE_ARGS, *args);
914 return VFD_NG;
915 }
916
918
919 // parameter to pass to the Close() function
920 close_params[1] = *args;
921 }
922 else if (!_stricmp(*args, "/q") ||
923 !_stricmp(*args, "/quit")) {
924
925 if (mode != OPERATION_ASK) {
926 PrintMessage(MSG_DUPLICATE_ARGS, *args);
927 return VFD_NG;
928 }
929
931
932 // parameter to pass to the Close() function
933 close_params[1] = *args;
934 }
935 else {
936 PrintMessage(MSG_UNKNOWN_OPTION, *args);
937 PrintMessage(MSG_HINT_STOP, help_progname);
938 return VFD_NG;
939 }
940
941 args++;
942 }
943
944 // ensure that the driver is installed
945
947 PrintMessage(MSG_NOT_INSTALLED);
948 return VFD_NG;
949 }
950
951 // ensure that the driver is running
952
954 PrintMessage(MSG_NOT_STARTED);
955 return VFD_NG;
956 }
957
958 // ensure that all drives are empty
959
961
962 // Try to close drives with the same operation mode (/F or /Q)
963
964 while (Close(close_params) != VFD_OK) {
965
966 // close failed
967
968 if (mode == OPERATION_FORCE) {
969 PrintMessage(MSG_STOP_FORCE);
970 break;
971 }
972 else if (mode == OPERATION_QUIT) {
973 PrintMessage(MSG_STOP_QUIT);
974 return VFD_NG;
975 }
976 else {
977 int c;
978
979 PrintMessage(MSG_STOP_WARN);
980
981 c = InputChar(MSG_RETRY_FORCE_CANCEL, "rfc");
982
983 if (c == 'f') { // force
984 break;
985 }
986 else if (c == 'c') { // cancel
987 return VFD_NG;
988 }
989 }
990 }
991 }
992
993 // stop the driver
994
996
997 if (ret != ERROR_SUCCESS) {
998 PrintMessage(MSG_STOP_NG);
999 printf("%s", SystemError(ret));
1000 return VFD_NG;
1001 }
1002
1004 PrintMessage(MSG_STOP_PENDING);
1005 return VFD_NG;
1006 }
1007
1008 // operation successful
1009
1010 PrintMessage(MSG_STOP_OK);
1011
1012 return VFD_OK;
1013}
1014
1015//
1016// Enable / Disable the shell extension
1017// Command Line Parameters:
1018// (optional) /ON or /OFF
1019//
1020int Shell(const char **args)
1021{
1022 DWORD ret;
1023
1025
1026 if (ret != ERROR_SUCCESS &&
1029 PrintMessage(MSG_GET_SHELLEXT_NG);
1030 printf("%s", SystemError(ret));
1031 return VFD_NG;
1032 }
1033
1034 if (args && *args) {
1035 if (_stricmp(*args, "/on") == 0) {
1036 if (ret != ERROR_SUCCESS) {
1038
1039 if (ret != ERROR_SUCCESS) {
1040 PrintMessage(MSG_SET_SHELLEXT_NG);
1041 printf("%s", SystemError(ret));
1042 return VFD_NG;
1043 }
1044 }
1045 }
1046 else if (_stricmp(*args, "/off") == 0) {
1047 if (ret == ERROR_SUCCESS) {
1049
1050 if (ret != ERROR_SUCCESS) {
1051 PrintMessage(MSG_SET_SHELLEXT_NG);
1052 printf("%s", SystemError(ret));
1053 return VFD_NG;
1054 }
1055 }
1056 }
1057 else {
1058 PrintMessage(MSG_UNKNOWN_OPTION, *args);
1059 PrintMessage(MSG_HINT_SHELL, help_progname);
1060 return VFD_NG;
1061 }
1062
1064 }
1065
1066 if (ret == ERROR_PATH_NOT_FOUND ||
1068 PrintMessage(MSG_SHELLEXT_DISABLED);
1069 }
1070 else if (ret == ERROR_SUCCESS) {
1071 PrintMessage(MSG_SHELLEXT_ENABLED);
1072 }
1073 else {
1074 PrintMessage(MSG_GET_SHELLEXT_NG);
1075 printf("%s", SystemError(ret));
1076 return VFD_NG;
1077 }
1078
1079 return VFD_OK;
1080}
1081
1082//
1083// Open an image file to a Virtual Floppy Drive
1084// Command Line Parameters:
1085// [drive:] [file] [/NEW] [/RAM] [/P | /W]
1086// [/size] [/media] [/F | /FORCE | /Q | /QUIT]
1087
1088int Open(const char **args)
1089{
1090 int mode = OPERATION_ASK;
1091 BOOL create = FALSE;
1094 VFD_DISKTYPE disk_type = VFD_DISKTYPE_FILE;
1095 CHAR protect = '\0';
1096 VFD_MEDIA media_type = VFD_MEDIA_NONE;
1097 BOOL five_inch = FALSE;
1098 VFD_FLAGS media_flags = 0;
1099 HANDLE hDevice;
1100 CHAR letter;
1101 DWORD ret;
1102
1103 // process parameters
1104
1105 while (args && *args) {
1106
1107 if (!_stricmp(*args, "/f") ||
1108 !_stricmp(*args, "/force")) {
1109
1110 if (mode != OPERATION_ASK) {
1111 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1112 return VFD_NG;
1113 }
1114
1116 }
1117 else if (!_stricmp(*args, "/q") ||
1118 !_stricmp(*args, "/quit")) {
1119
1120 if (mode != OPERATION_ASK) {
1121 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1122 return VFD_NG;
1123 }
1124
1126 }
1127
1128 else if (!_stricmp(*args, "/new")) {
1129
1130 if (create) {
1131 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1132 return VFD_NG;
1133 }
1134
1135 create = TRUE;
1136 }
1137
1138 // Disk type options
1139
1140 else if (_stricmp(*args, "/ram") == 0) {
1141
1142 if (disk_type != VFD_DISKTYPE_FILE) {
1143 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1144 return VFD_NG;
1145 }
1146
1147 disk_type = VFD_DISKTYPE_RAM;
1148 }
1149
1150 // Protect options
1151 else if (_stricmp(*args, "/p") == 0 ||
1152 _stricmp(*args, "/w") == 0) {
1153
1154 if (protect) {
1155 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1156 return VFD_NG;
1157 }
1158
1159 protect = (CHAR)toupper(*(*args + 1));
1160 }
1161
1162 // media size options
1163
1164 else if (strcmp(*args, "/160") == 0) {
1165 if (media_type) {
1166 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1167 return VFD_NG;
1168 }
1169
1170 media_type = VFD_MEDIA_F5_160;
1171 }
1172 else if (strcmp(*args, "/180") == 0) {
1173 if (media_type) {
1174 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1175 return VFD_NG;
1176 }
1177
1178 media_type = VFD_MEDIA_F5_180;
1179 }
1180 else if (strcmp(*args, "/320") == 0) {
1181 if (media_type) {
1182 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1183 return VFD_NG;
1184 }
1185
1186 media_type = VFD_MEDIA_F5_320;
1187 }
1188 else if (strcmp(*args, "/360") == 0) {
1189 if (media_type) {
1190 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1191 return VFD_NG;
1192 }
1193
1194 media_type = VFD_MEDIA_F5_360;
1195 }
1196 else if (strcmp(*args, "/640") == 0) {
1197 if (media_type) {
1198 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1199 return VFD_NG;
1200 }
1201
1202 media_type = VFD_MEDIA_F3_640;
1203 }
1204 else if (strcmp(*args, "/720") == 0) {
1205 if (media_type) {
1206 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1207 return VFD_NG;
1208 }
1209
1210 media_type = VFD_MEDIA_F3_720;
1211 }
1212 else if (strcmp(*args, "/820") == 0) {
1213 if (media_type) {
1214 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1215 return VFD_NG;
1216 }
1217
1218 media_type = VFD_MEDIA_F3_820;
1219 }
1220 else if (strcmp(*args, "/120") == 0 ||
1221 strcmp(*args, "/1.20") == 0) {
1222 if (media_type) {
1223 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1224 return VFD_NG;
1225 }
1226
1227 media_type = VFD_MEDIA_F3_1P2;
1228 }
1229 else if (strcmp(*args, "/144") == 0 ||
1230 strcmp(*args, "/1.44") == 0) {
1231 if (media_type) {
1232 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1233 return VFD_NG;
1234 }
1235
1236 media_type = VFD_MEDIA_F3_1P4;
1237 }
1238 else if (strcmp(*args, "/168") == 0 ||
1239 strcmp(*args, "/1.68") == 0) {
1240 if (media_type) {
1241 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1242 return VFD_NG;
1243 }
1244
1245 media_type = VFD_MEDIA_F3_1P6;
1246 }
1247 else if (strcmp(*args, "/172") == 0 ||
1248 strcmp(*args, "/1.72") == 0) {
1249 if (media_type) {
1250 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1251 return VFD_NG;
1252 }
1253
1254 media_type = VFD_MEDIA_F3_1P7;
1255 }
1256 else if (strcmp(*args, "/288") == 0 ||
1257 strcmp(*args, "/2.88") == 0) {
1258 if (media_type) {
1259 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1260 return VFD_NG;
1261 }
1262
1263 media_type = VFD_MEDIA_F3_2P8;
1264 }
1265
1266 // 5.25 inch media
1267
1268 else if (strcmp(*args, "/5") == 0 ||
1269 strcmp(*args, "/525") == 0 ||
1270 strcmp(*args, "/5.25") == 0) {
1271
1272 if (five_inch) {
1273 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1274 return VFD_NG;
1275 }
1276
1277 five_inch = TRUE;
1278 }
1279
1280 // target option
1281
1282 else if (isalnum(**args) &&
1283 *(*args + 1) == ':' &&
1284 *(*args + 2) == '\0') {
1285
1286 if (target != TARGET_NONE) {
1287 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1288 return VFD_NG;
1289 }
1290
1291 target = toupper(**args);
1292 }
1293
1294 // filename
1295
1296 else if (**args != '/') {
1297 if (file_name) {
1298 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1299 return VFD_NG;
1300 }
1301
1302 file_name = *args;
1303 }
1304 else {
1305 PrintMessage(MSG_UNKNOWN_OPTION, *args);
1306 PrintMessage(MSG_HINT_OPEN, help_progname);
1307 return VFD_NG;
1308 }
1309
1310 args++;
1311 }
1312
1313 if (target == TARGET_NONE) {
1314 // default target
1315 target = '0';
1316 PrintMessage(MSG_TARGET_NOTICE, target);
1317 }
1318
1319 // check target file
1320
1321 if (file_name) {
1322 DWORD file_attr;
1325 BOOL overwrite = FALSE;
1326
1328 file_name, &file_attr, &file_type, &image_size);
1329
1330 if (ret == ERROR_FILE_NOT_FOUND) {
1331
1332 // the target file does not exist
1333
1334 if (!create) { // create option not specified
1335
1336 if (mode == OPERATION_FORCE) {
1337 PrintMessage(MSG_CREATE_NOTICE);
1338 }
1339 else {
1340 printf("%s", SystemError(ret));
1341
1342 if (mode == OPERATION_QUIT ||
1343 InputChar(MSG_CREATE_CONFIRM, "yn") == 'n') {
1344 return VFD_NG;
1345 }
1346 }
1347
1348 create = TRUE;
1349 }
1350 }
1351 else if (ret == ERROR_SUCCESS) {
1352
1353 // the target file exists
1354
1355 if (create) { // create option is specified
1356
1357 if (mode == OPERATION_FORCE) {
1358 PrintMessage(MSG_OVERWRITE_NOTICE);
1359 }
1360 else {
1362
1363 if (mode == OPERATION_QUIT ||
1364 InputChar(MSG_OVERWRITE_CONFIRM, "yn") == 'n') {
1365 return VFD_NG;
1366 }
1367 }
1368
1369 overwrite = TRUE;
1370 }
1371 }
1372 else {
1373 PrintMessage(MSG_OPEN_NG, file_name);
1374 printf("%s", SystemError(ret));
1375 return VFD_NG;
1376 }
1377
1378 //
1379 // create or overwrite the target file
1380 //
1381
1382 if (create) {
1383
1384 if (media_type == VFD_MEDIA_NONE) {
1385
1386 if (mode == OPERATION_FORCE) {
1387 PrintMessage(MSG_CREATE144_NOTICE);
1388 }
1389 else {
1390 PrintMessage(MSG_FILE_MEDIA_UNKNOWN);
1391
1392 if (mode == OPERATION_QUIT ||
1393 InputChar(MSG_CREATE144_CONFIRM, "yn") == 'n') {
1394 return VFD_NG;
1395 }
1396 }
1397
1398 media_type = VFD_MEDIA_F3_1P4;
1399 }
1400
1402 file_name, media_type, VFD_FILETYPE_RAW, overwrite);
1403
1404 if (ret != ERROR_SUCCESS) {
1405 PrintMessage(MSG_CREATE_NG, file_name);
1406 printf("%s", SystemError(ret));
1407 return VFD_NG;
1408 }
1409
1410 PrintMessage(MSG_FILE_CREATED);
1411
1413 file_name, &file_attr, &file_type, &image_size);
1414
1415 if (ret != ERROR_SUCCESS) {
1416 PrintMessage(MSG_OPEN_NG, file_name);
1417 printf("%s", SystemError(ret));
1418 return VFD_NG;
1419 }
1420 }
1421 else {
1422 //
1423 // use the existing target file
1424 // check image size and the media type
1425 //
1426
1427 VFD_MEDIA def_media; // default media for image size
1428 ULONG media_size; // specified media size
1429
1430 media_size = VfdGetMediaSize(media_type);
1431
1432 if (media_size > image_size) {
1433
1434 // specified media is too large for the image
1435
1436 PrintMessage(MSG_IMAGE_TOO_SMALL);
1437 return VFD_NG;
1438 }
1439
1440 def_media = VfdLookupMedia(image_size);
1441
1442 if (def_media == VFD_MEDIA_NONE) {
1443
1444 // image is too small for the smallest media
1445
1446 PrintMessage(MSG_IMAGE_TOO_SMALL);
1447 return VFD_NG;
1448 }
1449
1450 if (media_type == VFD_MEDIA_NONE) {
1451
1452 // media type is not specified
1453
1454 ULONG def_size = VfdGetMediaSize(def_media);
1455
1456 if (def_size != image_size) {
1457
1458 // image size does not match the largest media size
1459
1460 PrintMessage(MSG_NO_MATCHING_MEDIA, image_size);
1461
1462 if (mode == OPERATION_FORCE) {
1463 PrintMessage(MSG_MEDIATYPE_NOTICE,
1464 VfdMediaTypeName(def_media), def_size);
1465 }
1466 else if (mode == OPERATION_QUIT) {
1467 return VFD_NG;
1468 }
1469 else {
1470 PrintMessage(MSG_MEDIATYPE_SUGGEST,
1471 VfdMediaTypeName(def_media), def_size);
1472
1473 if (InputChar(MSG_MEDIATYPE_CONFIRM, "yn") == 'n') {
1474 return VFD_NG;
1475 }
1476 }
1477 }
1478
1479 media_type = def_media;
1480 }
1481 }
1482
1483 // check file attributes against the disk type
1484
1485 if (file_type == VFD_FILETYPE_ZIP ||
1487
1488 if (disk_type != VFD_DISKTYPE_RAM) {
1489
1490 if (mode == OPERATION_FORCE) {
1491 PrintMessage(MSG_RAM_MODE_NOTICE);
1492 }
1493 else {
1494 PrintMessage(MSG_RAM_MODE_ONLY);
1495
1496 if (mode == OPERATION_QUIT ||
1497 InputChar(MSG_RAM_MODE_CONFIRM, "yn") == 'n') {
1498 return VFD_NG;
1499 }
1500 }
1501
1502 disk_type = VFD_DISKTYPE_RAM;
1503 }
1504 }
1505
1506 if (disk_type != VFD_DISKTYPE_FILE) {
1507 if (!protect) {
1508 PrintMessage(MSG_DEFAULT_PROTECT);
1509 protect = 'P';
1510 }
1511 }
1512 }
1513 else {
1514 //
1515 // pure RAM disk
1516 //
1517 disk_type = VFD_DISKTYPE_RAM;
1518
1519 if (media_type == VFD_MEDIA_NONE) {
1520
1521 if (mode == OPERATION_FORCE) {
1522 PrintMessage(MSG_CREATE144_NOTICE);
1523 }
1524 else {
1525 PrintMessage(MSG_RAM_MEDIA_UNKNOWN);
1526
1527 if (mode == OPERATION_QUIT ||
1528 InputChar(MSG_CREATE144_CONFIRM, "yn") == 'n') {
1529 return VFD_NG;
1530 }
1531 }
1532
1533 media_type = VFD_MEDIA_F3_1P4;
1534 }
1535 }
1536
1537 if (protect == 'P') {
1538 media_flags |= VFD_FLAG_WRITE_PROTECTED;
1539 }
1540
1541 if (five_inch &&
1542 VfdGetMediaSize(media_type) ==
1543 VfdGetMediaSize((VFD_MEDIA)(media_type + 1))) {
1544 media_type = (VFD_MEDIA)(media_type + 1);
1545 }
1546
1547 // ensure that the driver is installed
1548
1550 Install(NULL) != VFD_OK) {
1551 return VFD_NG;
1552 }
1553
1554 // ensure that the driver is up to date
1555
1556 if (CheckDriver() != VFD_OK) {
1557 return VFD_NG;
1558 }
1559
1560 // ensure that the driver is running
1561
1563 Start(NULL) != VFD_OK) {
1564 return VFD_NG;
1565 }
1566
1567 // Open the target device
1568
1569 hDevice = VfdOpenDevice(target);
1570
1571 if (hDevice == INVALID_HANDLE_VALUE) {
1572 ret = GetLastError();
1573 PrintMessage(MSG_ACCESS_NG, target);
1574 printf("%s", SystemError(ret));
1575 return VFD_NG;
1576 }
1577
1578 // Ensure that the drive is empty
1579
1580 ret = VfdGetMediaState(hDevice);
1581
1582 if (ret != ERROR_NOT_READY) {
1583 if (ret == ERROR_SUCCESS ||
1585 PrintMessage(MSG_DRIVE_BUSY);
1586 }
1587 else {
1588 PrintMessage(MSG_GET_MEDIA_NG);
1589 printf("%s", SystemError(ret));
1590 }
1591
1592 CloseHandle(hDevice);
1593 return VFD_NG;
1594 }
1595
1596 // Open the image file
1597
1598 ret = VfdOpenImage(hDevice, file_name,
1599 disk_type, media_type, media_flags);
1600
1601 if (ret != ERROR_SUCCESS) {
1602 PrintMessage(MSG_OPEN_NG, file_name ? file_name : "<RAM>");
1603 printf("%s", SystemError(ret));
1604
1605 CloseHandle(hDevice);
1606 return VFD_NG;
1607 }
1608
1609 // assign a drive letter if the drive has none
1610
1611 VfdGetGlobalLink(hDevice, &letter);
1612
1613 if (!isalpha(letter)) {
1614 VfdGetLocalLink(hDevice, &letter);
1615 }
1616
1617 if (!isalpha(letter)) {
1618 VfdSetLocalLink(hDevice, VfdChooseLetter());
1619 }
1620
1621 // Get the actually opened image information.
1622
1623 PrintImageInfo(hDevice);
1624
1625 CloseHandle(hDevice);
1626
1627 return VFD_OK;
1628}
1629
1630//
1631// Close the current virtual floppy image
1632// Command Line Parameters:
1633// drive number or drive letter
1634// /F | /FORCE | /Q | /QUIT
1635//
1636int Close(const char **args)
1637{
1639
1640 ULONG target_min = TARGET_NONE;
1641 ULONG target_max = TARGET_NONE;
1642 HANDLE hDevice;
1643
1644 VFD_MEDIA media_type;
1645 VFD_FLAGS media_flags;
1646
1647 DWORD ret;
1648
1649 // check parameterS
1650
1651 while (args && *args) {
1652
1653 if (!_stricmp(*args, "/f") ||
1654 !_stricmp(*args, "/force")) {
1655
1656 if (mode != OPERATION_ASK) {
1657 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1658 return VFD_NG;
1659 }
1660
1662 }
1663 else if (!_stricmp(*args, "/q") ||
1664 !_stricmp(*args, "/quit")) {
1665
1666 if (mode != OPERATION_ASK) {
1667 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1668 return VFD_NG;
1669 }
1670
1672 }
1673 else if ((isalnum(**args) || **args == '*') &&
1674 (*(*args + 1) == ':' || *(*args + 1) == '\0')) {
1675
1676 if (target_min != TARGET_NONE) {
1677 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1678 return VFD_NG;
1679 }
1680
1681 if (**args == '*') {
1682 target_min = '0';
1683 target_max = '0' + VFD_MAXIMUM_DEVICES;
1684 }
1685 else {
1686 target_min = toupper(**args);
1687 target_max = target_min + 1;
1688 }
1689 }
1690 else {
1691 PrintMessage(MSG_UNKNOWN_OPTION, *args);
1692 PrintMessage(MSG_HINT_CLOSE, help_progname);
1693 return VFD_NG;
1694 }
1695
1696 args++;
1697 }
1698
1699 if (target_min == TARGET_NONE) {
1700 // default target = drive 0
1701 target_min = '0';
1702 target_max = '1';
1703 PrintMessage(MSG_TARGET_NOTICE, target_min);
1704 }
1705
1706 // ensure that the driver is installed
1707
1709 PrintMessage(MSG_NOT_INSTALLED);
1710 return VFD_NG;
1711 }
1712
1713 // ensure that the driver is running
1714
1716 PrintMessage(MSG_NOT_STARTED);
1717 return VFD_NG;
1718 }
1719
1720 // Close the drive(s)
1721
1722 while (target_min < target_max) {
1723
1724 // open the target device
1725
1726 hDevice = VfdOpenDevice(target_min);
1727
1728 if (hDevice == INVALID_HANDLE_VALUE) {
1729 ret = GetLastError();
1730
1731 PrintMessage(MSG_ACCESS_NG, target_min);
1732 printf("%s", SystemError(ret));
1733
1734 if (mode != OPERATION_FORCE) {
1735 return VFD_NG;
1736 }
1737
1738 target_min++;
1739 continue;
1740 }
1741
1742 // get the current image information
1743
1744 ret = VfdGetImageInfo(hDevice, NULL, NULL,
1745 &media_type, &media_flags, NULL, NULL);
1746
1747 if (ret != ERROR_SUCCESS) {
1748 PrintMessage(MSG_ACCESS_NG, target_min);
1749 printf("%s", SystemError(ret));
1750
1751 CloseHandle(hDevice);
1752
1753 if (mode != OPERATION_FORCE) {
1754 return VFD_NG;
1755 }
1756
1757 target_min++;
1758 continue;
1759 }
1760
1761 if (media_type == VFD_MEDIA_NONE) {
1762
1763 // drive is empty
1764
1765 CloseHandle(hDevice);
1766 target_min++;
1767 continue;
1768 }
1769
1770 if (media_flags & VFD_FLAG_DATA_MODIFIED) {
1771
1772 // RAM disk data is modified
1773
1774 PrintMessage(MSG_MEDIA_MODIFIED, target_min);
1775
1776 if (mode == OPERATION_FORCE) {
1777 PrintMessage(MSG_CLOSE_FORCE);
1778 }
1779 else if (mode == OPERATION_QUIT) {
1780 PrintMessage(MSG_CLOSE_QUIT);
1781 CloseHandle(hDevice);
1782 return VFD_NG;
1783 }
1784 else {
1785 if (InputChar(MSG_CLOSE_CONFIRM, "yn") == 'n') {
1786 CloseHandle(hDevice);
1787 return VFD_NG;
1788 }
1789 }
1790 }
1791
1792retry:
1794 hDevice, (mode == OPERATION_FORCE));
1795
1796 if (ret == ERROR_ACCESS_DENIED) {
1797
1798 PrintMessage(MSG_LOCK_NG, target_min);
1799
1800 if (mode == OPERATION_QUIT) {
1801 CloseHandle(hDevice);
1802 return VFD_NG;
1803 }
1804 else if (mode == OPERATION_ASK) {
1805
1806 int c;
1807
1808 if (IS_WINDOWS_NT()) {
1809 c = InputChar(MSG_RETRY_CANCEL, "rc");
1810 }
1811 else {
1812 c = InputChar(MSG_RETRY_FORCE_CANCEL, "rfc");
1813 }
1814
1815 if (c == 'f') { // force
1816 ret = VfdCloseImage(hDevice, TRUE);
1817 }
1818 else if (c == 'c') { // cancel
1819 CloseHandle(hDevice);
1820 return VFD_NG;
1821 }
1822 else {
1823 goto retry;
1824 }
1825 }
1826 }
1827
1828 CloseHandle(hDevice);
1829
1830 if (ret == ERROR_SUCCESS) {
1831 PrintMessage(MSG_CLOSE_OK, target_min);
1832 }
1833 else if (ret != ERROR_NOT_READY) {
1834 PrintMessage(MSG_CLOSE_NG, target_min);
1835 printf("%s", SystemError(ret));
1836
1837 if (mode != OPERATION_FORCE) {
1838 return VFD_NG;
1839 }
1840 }
1841
1842 target_min++;
1843 }
1844
1845 return VFD_OK;
1846}
1847
1848//
1849// Save the current image into a file
1850//
1851int Save(const char **args)
1852{
1853 int mode = OPERATION_ASK;
1855 CHAR file_name[MAX_PATH] = {0};
1856 BOOL overwrite = FALSE;
1857 BOOL truncate = FALSE;
1858
1859 HANDLE hDevice;
1860 CHAR current[MAX_PATH] = {0};
1861 VFD_MEDIA media_type;
1862 VFD_FLAGS media_flags;
1864 DWORD file_attr;
1866 DWORD ret;
1867
1868 // check parameters
1869
1870 while (args && *args) {
1871
1872 if (!_stricmp(*args, "/f") ||
1873 !_stricmp(*args, "/force")) {
1874
1875 if (mode != OPERATION_ASK) {
1876 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1877 return VFD_NG;
1878 }
1879
1881 }
1882 else if (!_stricmp(*args, "/q") ||
1883 !_stricmp(*args, "/quit")) {
1884
1885 if (mode != OPERATION_ASK) {
1886 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1887 return VFD_NG;
1888 }
1889
1891 }
1892 else if (!_stricmp(*args, "/o") ||
1893 !_stricmp(*args, "/over")) {
1894
1895 if (truncate || overwrite) {
1896 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1897 return VFD_NG;
1898 }
1899
1900 overwrite = TRUE;
1901 }
1902 else if (!_stricmp(*args, "/t") ||
1903 !_stricmp(*args, "/trunc")) {
1904
1905 if (truncate || overwrite) {
1906 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1907 return VFD_NG;
1908 }
1909
1910 truncate = TRUE;
1911 }
1912 else if (isalnum(**args) &&
1913 *(*args + 1) == ':' &&
1914 *(*args + 2) == '\0') {
1915
1916 if (target != TARGET_NONE) {
1917 PrintMessage(MSG_DUPLICATE_ARGS, *args);
1918 return VFD_NG;
1919 }
1920
1921 target = toupper(**args);
1922 }
1923 else if (**args == '/') {
1924 PrintMessage(MSG_UNKNOWN_OPTION, *args);
1925 PrintMessage(MSG_HINT_SAVE, help_progname);
1926 return VFD_NG;
1927 }
1928 else {
1930 }
1931
1932 args++;
1933 }
1934
1935 if (target == TARGET_NONE) {
1936 target = '0';
1937 PrintMessage(MSG_TARGET_NOTICE, target);
1938 }
1939
1940 // ensure that the driver is installed
1941
1943 PrintMessage(MSG_NOT_INSTALLED);
1944 return VFD_NG;
1945 }
1946
1947 // ensure that the driver is up to date
1948
1949 if (CheckDriver() != VFD_OK) {
1950 return VFD_NG;
1951 }
1952
1953 // ensure that the driver is running
1954
1956 PrintMessage(MSG_NOT_STARTED);
1957 return VFD_NG;
1958 }
1959
1960 // Open the target device
1961
1962 hDevice = VfdOpenDevice(target);
1963
1964 if (hDevice == INVALID_HANDLE_VALUE) {
1965 ret = GetLastError();
1966 PrintMessage(MSG_ACCESS_NG, target);
1967 printf("%s", SystemError(ret));
1968 return VFD_NG;
1969 }
1970
1971 // Get the current image info
1972
1973 ret = VfdGetImageInfo(hDevice, current, NULL,
1974 &media_type, &media_flags, NULL, NULL);
1975
1976 if (ret != ERROR_SUCCESS) {
1977 printf("%s", SystemError(ret));
1978 CloseHandle(hDevice);
1979 return VFD_NG;
1980 }
1981
1982 if (media_type == VFD_MEDIA_NONE) {
1984 CloseHandle(hDevice);
1985 return VFD_NG;
1986 }
1987
1988 if (file_name[0] == '\0') {
1989
1990 if (current[0] == '\0') {
1991
1992 PrintMessage(MSG_TARGET_REQUIRED);
1993 CloseHandle(hDevice);
1994
1995 return VFD_NG;
1996 }
1997
1999 }
2000
2001 if (!_stricmp(file_name, current)) {
2002
2003 // target is the current image file
2004
2005 if (!(media_flags & VFD_FLAG_DATA_MODIFIED)) {
2006
2007 // FILE disk (always up to date) or RAM disk is not modified
2008
2009 PrintMessage(MSG_TARGET_UP_TO_DATE);
2010 CloseHandle(hDevice);
2011
2012 return VFD_OK;
2013 }
2014
2015 overwrite = TRUE;
2016 }
2017
2018 // check target file
2019
2021 &file_attr, &file_type, &image_size);
2022
2023 if (ret == ERROR_SUCCESS) {
2024
2025 if (!overwrite && !truncate) {
2026
2027 if (mode == OPERATION_FORCE) {
2028 PrintMessage(MSG_OVERWRITE_NOTICE);
2029 overwrite = TRUE;
2030 }
2031 else if (mode == OPERATION_QUIT) {
2033 CloseHandle(hDevice);
2034
2035 return VFD_NG;
2036 }
2037 else {
2038 int c;
2039
2041
2042 c = InputChar(MSG_OVERWRITE_PROMPT, "otc");
2043
2044 if (c == 'o') {
2045 overwrite = TRUE;
2046 }
2047 else if (c == 't') {
2048 truncate = TRUE;
2049 }
2050 else {
2051 CloseHandle(hDevice);
2052 return VFD_NG;
2053 }
2054 }
2055 }
2056 }
2057 else if (ret != ERROR_FILE_NOT_FOUND) {
2058
2059 printf("%s", SystemError(ret));
2060 CloseHandle(hDevice);
2061
2062 return VFD_NG;
2063 }
2064
2065 if (file_type == VFD_FILETYPE_ZIP) {
2066
2067 // Cannot update a zip file
2068
2069 PrintMessage(MSG_TARGET_IS_ZIP);
2070 CloseHandle(hDevice);
2071
2072 return VFD_NG;
2073 }
2074
2075retry:
2077 hDevice, (mode == OPERATION_FORCE));
2078
2079 if (ret == ERROR_ACCESS_DENIED) {
2080
2081 PrintMessage(MSG_LOCK_NG, target);
2082
2083 if (mode == OPERATION_FORCE) {
2084 PrintMessage(MSG_SAVE_FORCE);
2085 }
2086 else if (mode == OPERATION_QUIT) {
2087 PrintMessage(MSG_SAVE_QUIT);
2088 CloseHandle(hDevice);
2089 return VFD_NG;
2090 }
2091 else {
2092 int c = InputChar(MSG_RETRY_FORCE_CANCEL, "rfc");
2093
2094 if (c == 'r') { // retry
2095 goto retry;
2096 }
2097 else if (c == 'f') { // force
2098 VfdDismountVolume(hDevice, TRUE);
2099 }
2100 else { // cancel
2101 CloseHandle(hDevice);
2102 return VFD_NG;
2103 }
2104 }
2105 }
2106 else if (ret != ERROR_SUCCESS) {
2107 printf("%s", SystemError(ret));
2108 CloseHandle(hDevice);
2109 return VFD_NG;
2110 }
2111
2112 ret = VfdSaveImage(hDevice, file_name,
2113 (overwrite || truncate), truncate);
2114
2115 CloseHandle(hDevice);
2116
2117 if (ret != ERROR_SUCCESS) {
2118 PrintMessage(MSG_SAVE_NG, target, file_name);
2119 printf("%s", SystemError(ret));
2120
2121 return VFD_NG;
2122 }
2123
2124 PrintMessage(MSG_SAVE_OK, target, file_name);
2125
2126 return VFD_OK;
2127}
2128
2129//
2130// Enable/disable virtual media write protection
2131//
2132int Protect(const char **args)
2133{
2134#define PROTECT_NONE 0
2135#define PROTECT_ON 1
2136#define PROTECT_OFF 2
2137 ULONG protect = PROTECT_NONE;
2139 HANDLE hDevice;
2140 DWORD ret;
2141
2142 // check parameters
2143
2144 while (args && *args) {
2145
2146 // Disk type options
2147
2148 if (_stricmp(*args, "/on") == 0) {
2149
2150 if (protect) {
2151 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2152 return VFD_NG;
2153 }
2154
2155 protect = PROTECT_ON;
2156 }
2157 else if (_stricmp(*args, "/off") == 0) {
2158
2159 if (protect) {
2160 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2161 return VFD_NG;
2162 }
2163
2164 protect = PROTECT_OFF;
2165 }
2166 else if (isalnum(**args)) {
2167
2168 if (target != TARGET_NONE) {
2169 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2170 return VFD_NG;
2171 }
2172
2173 target = toupper(**args);
2174 }
2175 else {
2176 PrintMessage(MSG_UNKNOWN_OPTION, *args);
2177 PrintMessage(MSG_HINT_PROTECT, help_progname);
2178 return VFD_NG;
2179 }
2180
2181 args++;
2182 }
2183
2184 if (target == TARGET_NONE) {
2185 target = '0';
2186 PrintMessage(MSG_TARGET_NOTICE, target);
2187 }
2188
2189 // ensure that the driver is installed
2190
2192 PrintMessage(MSG_NOT_INSTALLED);
2193 return VFD_NG;
2194 }
2195
2196 // ensure that the driver is up to date
2197
2198 if (CheckDriver() != VFD_OK) {
2199 return VFD_NG;
2200 }
2201
2202 // ensure that the driver is running
2203
2205 PrintMessage(MSG_NOT_STARTED);
2206 return VFD_NG;
2207 }
2208
2209 // open the target drive
2210
2211 hDevice = VfdOpenDevice(target);
2212
2213 if (hDevice == INVALID_HANDLE_VALUE) {
2214 ret = GetLastError();
2215 PrintMessage(MSG_ACCESS_NG, target);
2216 printf("%s", SystemError(ret));
2217 return VFD_NG;
2218 }
2219
2220 if (protect) {
2221 // change protect state
2222
2224 hDevice, (protect == PROTECT_ON));
2225
2226 if (ret != ERROR_SUCCESS) {
2227 PrintMessage(MSG_PROTECT_NG, target);
2228 printf("%s", SystemError(ret));
2229
2230 CloseHandle(hDevice);
2231 return VFD_NG;
2232 }
2233 }
2234
2235 // get the current protect state
2236
2237 ret = VfdGetMediaState(hDevice);
2238
2239 CloseHandle(hDevice);
2240
2241 if (ret == ERROR_SUCCESS) {
2242 PrintMessage(MSG_MEDIA_WRITABLE);
2243 }
2244 else if (ret == ERROR_WRITE_PROTECT) {
2245 PrintMessage(MSG_MEDIA_PROTECTED);
2246 }
2247 else {
2248 PrintMessage(MSG_GET_MEDIA_NG);
2249 printf("%s", SystemError(ret));
2250 return VFD_NG;
2251 }
2252
2253 return VFD_OK;
2254}
2255
2256//
2257// Format the virtual media with FAT12
2258//
2259int Format(const char **args)
2260{
2261 int mode = OPERATION_ASK;
2263 HANDLE hDevice;
2264 DWORD ret;
2265
2266 // check parameters
2267
2268 while (args && *args) {
2269
2270 if (!_stricmp(*args, "/f") ||
2271 !_stricmp(*args, "/force")) {
2272
2273 if (mode != OPERATION_ASK) {
2274 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2275 return VFD_NG;
2276 }
2277
2279 }
2280 else if (!_stricmp(*args, "/q") ||
2281 !_stricmp(*args, "/quit")) {
2282
2283 if (mode != OPERATION_ASK) {
2284 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2285 return VFD_NG;
2286 }
2287
2289 }
2290 else if (isalnum(**args)) {
2291 if (target != TARGET_NONE) {
2292 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2293 return VFD_NG;
2294 }
2295
2296 target = toupper(**args);
2297 }
2298 else {
2299 PrintMessage(MSG_UNKNOWN_OPTION, *args);
2300 PrintMessage(MSG_HINT_FORMAT, help_progname);
2301 return VFD_NG;
2302 }
2303
2304 args++;
2305 }
2306
2307 if (target == TARGET_NONE) {
2308 target = '0';
2309 PrintMessage(MSG_TARGET_NOTICE, target);
2310 }
2311
2312 // ensure that the driver is installed
2313
2315 PrintMessage(MSG_NOT_INSTALLED);
2316 return VFD_NG;
2317 }
2318
2319 // ensure that the driver is up to date
2320
2321 if (CheckDriver() != VFD_OK) {
2322 return VFD_NG;
2323 }
2324
2325 // ensure that the driver is running
2326
2328 PrintMessage(MSG_NOT_STARTED);
2329 return VFD_NG;
2330 }
2331
2332 // Open the device
2333
2334 hDevice = VfdOpenDevice(target);
2335
2336 if (hDevice == INVALID_HANDLE_VALUE) {
2337 ret = GetLastError();
2338 PrintMessage(MSG_ACCESS_NG, target);
2339 printf("%s", SystemError(ret));
2340 return VFD_NG;
2341 }
2342
2343 // check if the media is writable
2344
2345 ret = VfdGetMediaState(hDevice);
2346
2347 if (ret != ERROR_SUCCESS) {
2348 PrintMessage(MSG_FORMAT_NG, target);
2349 printf("%s", SystemError(ret));
2350
2351 CloseHandle(hDevice);
2352 return VFD_NG;
2353 }
2354
2355 // format the media
2356
2357retry:
2359 hDevice, (mode == OPERATION_FORCE));
2360
2361 if (ret == ERROR_ACCESS_DENIED) {
2362
2363 PrintMessage(MSG_LOCK_NG, target);
2364
2365 if (mode == OPERATION_FORCE) {
2366 PrintMessage(MSG_FORMAT_FORCE);
2367 }
2368 else if (mode == OPERATION_QUIT) {
2369 PrintMessage(MSG_FORMAT_QUIT);
2370 CloseHandle(hDevice);
2371 return VFD_NG;
2372 }
2373 else {
2374 int c = InputChar(MSG_RETRY_FORCE_CANCEL, "rfc");
2375
2376 if (c == 'r') { // retry
2377 goto retry;
2378 }
2379 else if (c == 'f') { // force
2380 VfdDismountVolume(hDevice, TRUE);
2381 }
2382 else { // cancel
2383 CloseHandle(hDevice);
2384 return VFD_NG;
2385 }
2386 }
2387 }
2388 else if (ret != ERROR_SUCCESS) {
2389 PrintMessage(MSG_LOCK_NG, target);
2390 CloseHandle(hDevice);
2391 return VFD_NG;
2392 }
2393
2394 ret = VfdFormatMedia(hDevice);
2395
2396 CloseHandle(hDevice);
2397
2398 if (ret != ERROR_SUCCESS) {
2399 PrintMessage(MSG_FORMAT_NG, target);
2400 printf("%s", SystemError(ret));
2401 return VFD_NG;
2402 }
2403
2404 // successful operation
2405
2406 PrintMessage(MSG_FORMAT_OK);
2407
2408 return VFD_OK;
2409}
2410
2411//
2412// Assign a drive letter to a Virtual Floppy Drive
2413//
2414int Link(const char **args)
2415{
2416 ULONG target_min = TARGET_NONE;
2417 ULONG target_max = TARGET_NONE;
2418 PCSTR letters = NULL;
2419 BOOL global = TRUE;
2420 HANDLE hDevice;
2421 DWORD ret;
2422
2423 while (args && *args) {
2424 if (!_stricmp(*args, "/g")) {
2425 global = TRUE;
2426 }
2427 else if (!_stricmp(*args, "/l")) {
2428 global = FALSE;
2429 }
2430 else if (isdigit(**args) || **args == '*') {
2431 if (target_min != TARGET_NONE) {
2432 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2433 return VFD_NG;
2434 }
2435
2436 if (**args == '*') {
2437 target_min = '0';
2438 target_max = '0' + VFD_MAXIMUM_DEVICES;
2439 }
2440 else {
2441 target_min = **args;
2442 target_max = target_min + 1;
2443 }
2444 }
2445 else if (isalpha(**args)) {
2446 if (letters) {
2447 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2448 return VFD_NG;
2449 }
2450 letters = *args;
2451 }
2452 else {
2453 PrintMessage(MSG_UNKNOWN_OPTION, *args);
2454 PrintMessage(MSG_HINT_LINK, help_progname);
2455 return VFD_NG;
2456 }
2457
2458 args++;
2459 }
2460
2461 if (target_min == TARGET_NONE) {
2462 // default: drive 0
2463 target_min = '0';
2464 target_max = '1';
2465 PrintMessage(MSG_TARGET_NOTICE, target_min);
2466 }
2467
2468 // ensure that the driver is installed
2469
2471 PrintMessage(MSG_NOT_INSTALLED);
2472 return VFD_NG;
2473 }
2474
2475 // ensure that the driver is up to date
2476
2477 if (CheckDriver() != VFD_OK) {
2478 return VFD_NG;
2479 }
2480
2481 // ensure that the driver is running
2482
2484 PrintMessage(MSG_NOT_STARTED);
2485 return VFD_NG;
2486 }
2487
2488 while (target_min < target_max) {
2489 ULONG number;
2490 CHAR letter;
2491
2492 hDevice = VfdOpenDevice(target_min);
2493
2494 if (hDevice == INVALID_HANDLE_VALUE) {
2495 ret = GetLastError();
2496 PrintMessage(MSG_ACCESS_NG, target_min);
2497 printf("%s", SystemError(ret));
2498 target_min++;
2499 continue;
2500 }
2501
2502 ret = VfdGetDeviceNumber(hDevice, &number);
2503
2504 if (ret != ERROR_SUCCESS) {
2505 PrintMessage(MSG_ACCESS_NG, target_min);
2506 printf("%s", SystemError(ret));
2507 CloseHandle(hDevice);
2508 target_min++;
2509 continue;
2510 }
2511
2512 if (letters && isalpha(*letters)) {
2513 letter = (CHAR)toupper(*(letters++));
2514 }
2515 else {
2516 letter = VfdChooseLetter();
2517 }
2518
2519 if (letter) {
2520 if (global) {
2521 ret = VfdSetGlobalLink(hDevice, letter);
2522 }
2523 else {
2524 ret = VfdSetLocalLink(hDevice, letter);
2525 }
2526
2527 if (ret != ERROR_SUCCESS) {
2528 PrintMessage(MSG_LINK_NG, number, letter);
2529 printf("%s", SystemError(ret));
2530 }
2531 }
2532 else {
2533 PrintMessage(MSG_LINK_FULL);
2534 }
2535
2536 PrintDriveLetter(hDevice, number);
2537
2538 CloseHandle(hDevice);
2539
2540 target_min++;
2541 }
2542
2543 return VFD_OK;
2544}
2545
2546//
2547// Remove a drive letter from a Virtual Floppy Drive
2548//
2549int Unlink(const char **args)
2550{
2551 ULONG target_min = TARGET_NONE;
2552 ULONG target_max = TARGET_NONE;
2553 HANDLE hDevice;
2554 DWORD ret;
2555
2556 while (args && *args) {
2557 if ((isalnum(**args) || **args == '*') &&
2558 (*(*args + 1) == ':' || *(*args + 1) == '\0')) {
2559
2560 if (target_min != TARGET_NONE) {
2561 PrintMessage(MSG_DUPLICATE_ARGS, *args);
2562 return VFD_NG;
2563 }
2564
2565 if (**args == '*') {
2566 target_min = '0';
2567 target_max = '0' + VFD_MAXIMUM_DEVICES;
2568 }
2569 else {
2570 target_min = **args;
2571 target_max = target_min + 1;
2572 }
2573 }
2574 else {
2575 PrintMessage(MSG_UNKNOWN_OPTION, *args);
2576 PrintMessage(MSG_HINT_ULINK, help_progname);
2577 return VFD_NG;
2578 }
2579
2580 args++;
2581 }
2582
2583 if (target_min == TARGET_NONE) {
2584 // default: drive 0
2585 target_min = '0';
2586 target_max = '1';
2587 PrintMessage(MSG_TARGET_NOTICE, target_min);
2588 }
2589
2590 // ensure that the driver is installed
2591
2593 PrintMessage(MSG_NOT_INSTALLED);
2594 return VFD_NG;
2595 }
2596
2597 // ensure that the driver is up to date
2598
2599 if (CheckDriver() != VFD_OK) {
2600 return VFD_NG;
2601 }
2602
2603 // ensure that the driver is running
2604
2606 PrintMessage(MSG_NOT_STARTED);
2607 return VFD_NG;
2608 }
2609
2610 while (target_min < target_max) {
2611 ULONG number;
2612
2613 hDevice = VfdOpenDevice(target_min);
2614
2615 if (hDevice == INVALID_HANDLE_VALUE) {
2616 ret = GetLastError();
2617 PrintMessage(MSG_ACCESS_NG, target_min);
2618 printf("%s", SystemError(ret));
2619 target_min++;
2620 continue;
2621 }
2622
2623 ret = VfdGetDeviceNumber(hDevice, &number);
2624
2625 if (ret != ERROR_SUCCESS) {
2626 PrintMessage(MSG_ACCESS_NG, target_min);
2627 printf("%s", SystemError(ret));
2628 CloseHandle(hDevice);
2629 target_min++;
2630 continue;
2631 }
2632
2633 VfdSetGlobalLink(hDevice, 0);
2634 VfdSetLocalLink(hDevice, 0);
2635
2636 PrintDriveLetter(hDevice, number);
2637
2638 CloseHandle(hDevice);
2639
2640 target_min++;
2641 }
2642
2643 return VFD_OK;
2644}
2645
2646//
2647// Print current driver state
2648// Command Line Parameters: None
2649//
2650int Status(const char **args)
2651{
2652 HANDLE hDevice;
2654 DWORD start_type;
2655 DWORD version;
2656 ULONG target;
2657 DWORD ret;
2658
2660
2662 PrintMessage(MSG_NOT_INSTALLED);
2663 }
2664 else {
2665
2666 // get current driver config
2667
2668 ret = VfdGetDriverConfig(path, &start_type);
2669
2670 if (ret != ERROR_SUCCESS) {
2671 PrintMessage(MSG_GET_CONFIG_NG);
2672 printf("%s", SystemError(ret));
2673 return VFD_NG;
2674 }
2675
2676 // print driver file path
2677
2678 PrintMessage(MSG_DRIVER_FILE, path);
2679
2680 // print driver version
2681 version = 0;
2682
2684
2685 hDevice = VfdOpenDevice(0);
2686
2687 if (hDevice != INVALID_HANDLE_VALUE) {
2688 ret = VfdGetDriverVersion(hDevice, &version);
2689
2690 CloseHandle(hDevice);
2691 }
2692
2693 }
2694
2695 if (version == 0) {
2697 }
2698
2699 if (ret == ERROR_SUCCESS) {
2700 PrintMessage(MSG_DRIVER_VERSION,
2701 HIWORD(version) & 0x7fff,
2702 LOWORD(version),
2703 (version & 0x80000000) ? "(debug)" : "");
2704 }
2705 else {
2706 PrintMessage(MSG_GET_VERSION_NG);
2707 printf("%s", SystemError(ret));
2708 }
2709
2710
2711 // print driver start type
2712
2713 PrintMessage(MSG_START_TYPE);
2714
2715 switch (start_type) {
2716 case SERVICE_AUTO_START:
2717 PrintMessage(MSG_START_AUTO);
2718 break;
2719
2720 case SERVICE_BOOT_START:
2721 PrintMessage(MSG_START_BOOT);
2722 break;
2723
2725 PrintMessage(MSG_START_DEMAND);
2726 break;
2727
2728 case SERVICE_DISABLED:
2729 PrintMessage(MSG_START_DISABLED);
2730 break;
2731
2733 PrintMessage(MSG_START_SYSTEM);
2734 break;
2735
2736 default:
2737 PrintMessage(MSG_UNKNOWN_LONG, start_type);
2738 break;
2739 }
2740
2741 // print current driver state
2742
2743 PrintMessage(MSG_DRIVER_STATUS);
2744
2745 switch (driver_state) {
2746 case SERVICE_STOPPED:
2747 PrintMessage(MSG_STATUS_STOPPED);
2748 break;
2749
2751 PrintMessage(MSG_STATUS_START_P);
2752 break;
2753
2755 PrintMessage(MSG_STATUS_STOP_P);
2756 break;
2757
2758 case SERVICE_RUNNING:
2759 PrintMessage(MSG_STATUS_RUNNING);
2760 break;
2761
2763 PrintMessage(MSG_STATUS_CONT_P);
2764 break;
2765
2767 PrintMessage(MSG_STATUS_PAUSE_P);
2768 break;
2769
2770 case SERVICE_PAUSED:
2771 PrintMessage(MSG_STATUS_PAUSED);
2772 break;
2773
2774 default:
2775 PrintMessage(MSG_UNKNOWN_LONG, driver_state);
2776 break;
2777 }
2778 }
2779
2780 // print shell extension status
2781
2782 printf("\n");
2783
2785 PrintMessage(MSG_SHELLEXT_ENABLED);
2786 }
2787 else {
2788 PrintMessage(MSG_SHELLEXT_DISABLED);
2789 }
2790
2791 // if driver is not running, no more info
2792
2794 return VFD_OK;
2795 }
2796
2797 // print image information
2798
2799 for (target = 0; target < VFD_MAXIMUM_DEVICES; target++) {
2800 HANDLE hDevice = VfdOpenDevice(target);
2801
2802 if (hDevice == INVALID_HANDLE_VALUE) {
2803 ret = GetLastError();
2804 PrintMessage(MSG_ACCESS_NG, target + '0');
2805 printf("%s", SystemError(ret));
2806 return VFD_NG;
2807 }
2808
2809 PrintImageInfo(hDevice);
2810
2811 CloseHandle(hDevice);
2812 }
2813
2814 return VFD_OK;
2815}
2816
2817//
2818// Print usage help
2819//
2820int Help(const char **args)
2821{
2822 DWORD msg = MSG_HELP_GENERAL;
2823 char *buf = NULL;
2824
2825 if (args && *args) {
2826 int cmd = ParseHelpTopic(*args);
2827
2828 if (cmd < 0) {
2829 msg = MSG_HELP_HELP;
2830 }
2831 else {
2832 msg = HelpMsg[cmd].help;
2833 }
2834 }
2835
2840 NULL, msg, 0, (LPTSTR)&buf, 0,
2842
2843 if (buf == NULL) {
2845 return VFD_NG;
2846 }
2847
2849 LocalFree(buf);
2850
2851 return VFD_OK;
2852}
2853
2854//
2855// Print version information
2856//
2857int Version(const char **args)
2858{
2860
2862 "http://chitchat.at.infoseek.co.jp/vmware/vfd.html\n");
2863
2864 return VFD_OK;
2865}
2866
2867//
2868// Parse command parameter
2869//
2870int ParseCommand(const char *cmd)
2871{
2872#define CMD_MATCH_NONE -1
2873#define CMD_MATCH_MULTI -2
2874
2875 size_t len;
2876 int idx;
2877 int match;
2878
2879 // skip a leading '/'
2880
2881 if (*cmd == '/') {
2882 cmd++;
2883 }
2884
2885 if (*cmd == '\0') {
2886
2887 // empty command
2888
2889 return CMD_MATCH_NONE;
2890 }
2891
2892 // find a match
2893 len = strlen(cmd);
2894 idx = 0;
2896
2897 while (Commands[idx].cmd) {
2898
2899 if (strlen(Commands[idx].cmd) >= len &&
2901
2902 if (match == CMD_MATCH_NONE) { // first match
2903 match = idx;
2904 }
2905 else { // multiple matches
2906 if (match != CMD_MATCH_MULTI) { // first time
2907 PrintMessage(MSG_AMBIGUOUS_COMMAND, cmd);
2908 printf("> %s ", Commands[match].cmd);
2910 }
2911
2912 printf("%s ", Commands[idx].cmd);
2913 }
2914 }
2915
2916 idx++;
2917 }
2918
2919 if (match == CMD_MATCH_NONE) { // match not found
2920 PrintMessage(MSG_UNKNOWN_COMMAND, cmd);
2921 }
2922 else if (match == CMD_MATCH_MULTI) { // multiple matches
2923 printf("\n");
2924 }
2925
2926 return match;
2927}
2928
2929int ParseHelpTopic(const char *topic)
2930{
2931 size_t len;
2932 int idx;
2933 int match;
2934
2935 if (*topic == '\0') {
2936
2937 // empty command
2938
2939 return CMD_MATCH_NONE;
2940 }
2941
2942 // find a match
2943 len = strlen(topic);
2944 idx = 0;
2946
2947 while (HelpMsg[idx].keyword) {
2948
2949 if (strlen(HelpMsg[idx].keyword) >= len &&
2951
2952 if (match == CMD_MATCH_NONE) { // first match
2953 match = idx;
2954 }
2955 else { // multiple matches
2956 if (match != CMD_MATCH_MULTI) { // first time
2957 PrintMessage(MSG_AMBIGUOUS_COMMAND, topic);
2958 printf("> %s ", HelpMsg[match].keyword);
2960 }
2961
2962 printf("%s ", HelpMsg[idx].keyword);
2963 }
2964 }
2965
2966 idx++;
2967 }
2968
2969 if (match == CMD_MATCH_NONE) { // match not found
2970 PrintMessage(MSG_UNKNOWN_COMMAND, topic);
2971 }
2972 else if (match == CMD_MATCH_MULTI) { // multiple matches
2973 printf("\n");
2974 }
2975
2976 return match;
2977}
2978
2979//
2980// Check driver version and update if necessary
2981//
2983{
2984 char path[MAX_PATH];
2985 DWORD start;
2986
2987 // check installed driver file version
2988
2991
2992 HANDLE hDevice;
2993
2995 return VFD_OK;
2996 }
2997
2998 // check running driver version
2999
3000 hDevice = VfdOpenDevice(0);
3001
3002 if (hDevice != INVALID_HANDLE_VALUE) {
3003 CloseHandle(hDevice);
3004 return VFD_OK;
3005 }
3006 }
3007
3008 PrintMessage(MSG_WRONG_DRIVER);
3009 return VFD_NG;
3010}
3011
3012//
3013// Print a prompt message and accept the reply input
3014//
3016{
3017 HANDLE hStdIn;
3019 DWORD result;
3020 int reply;
3021
3023 fflush(NULL);
3024
3026
3028
3029 for (;;) {
3031
3032 if (input.EventType == KEY_EVENT &&
3033 input.Event.KeyEvent.bKeyDown) {
3034
3035 reply = tolower(input.Event.KeyEvent.uChar.AsciiChar);
3036
3037 if (strchr(ans, reply)) {
3038 break;
3039 }
3040 }
3041 }
3042
3043 printf("%c\n", reply);
3044
3045 return reply;
3046}
3047
3048//
3049// Print image information on a Virtual Floppy Drive
3050//
3052 HANDLE hDevice)
3053{
3054 ULONG device_number;
3056 CHAR file_desc[MAX_PATH];
3057 VFD_DISKTYPE disk_type;
3058 VFD_MEDIA media_type;
3059 VFD_FLAGS media_flags;
3062 DWORD ret;
3063
3064 printf("\n");
3065
3066 // get current device number
3067
3068 ret = VfdGetDeviceNumber(hDevice, &device_number);
3069
3070 if (ret != ERROR_SUCCESS) {
3071 PrintMessage(MSG_GET_LINK_NG);
3072 printf("%s", SystemError(ret));
3073 device_number = (ULONG)-1;
3074 }
3075
3076 // get current drive letters
3077
3078 PrintDriveLetter(hDevice, device_number);
3079
3080 // image file information
3081
3082 ret = VfdGetImageInfo(hDevice, file_name, &disk_type,
3083 &media_type, &media_flags, &file_type, &image_size);
3084
3085 if (ret != ERROR_SUCCESS) {
3086 PrintMessage(MSG_GET_FILE_NG);
3087 printf("%s", SystemError(ret));
3088 return;
3089 }
3090
3091 // print image file information
3092 if (media_type == VFD_MEDIA_NONE) {
3093 PrintMessage(MSG_IMAGE_NONE);
3094 return;
3095 }
3096
3097 if (file_name[0]) {
3098 PrintMessage(MSG_IMAGE_NAME, file_name);
3099
3100 VfdMakeFileDesc(file_desc, sizeof(file_desc),
3102 }
3103 else {
3104 PrintMessage(MSG_IMAGE_NAME, "<RAM>");
3105
3106 VfdMakeFileDesc(file_desc, sizeof(file_desc),
3108 }
3109
3110 PrintMessage(MSG_FILE_DESC, file_desc);
3111
3112 if (disk_type == VFD_DISKTYPE_FILE) {
3113 PrintMessage(MSG_DISKTYPE_FILE);
3114 }
3115 else {
3116 if (media_flags & VFD_FLAG_DATA_MODIFIED) {
3117 PrintMessage(MSG_DISKTYPE_RAM_DIRTY);
3118 }
3119 else {
3120 PrintMessage(MSG_DISKTYPE_RAM_CLEAN);
3121 }
3122 }
3123
3124 // print other file info
3125
3126 PrintMessage(MSG_MEDIA_TYPE, VfdMediaTypeName(media_type));
3127
3128 if (media_flags & VFD_FLAG_WRITE_PROTECTED) {
3129 PrintMessage(MSG_MEDIA_PROTECTED);
3130 }
3131 else {
3132 PrintMessage(MSG_MEDIA_WRITABLE);
3133 }
3134}
3135
3136//
3137// Print drive letters on a virtual floppy drive
3138//
3140 HANDLE hDevice,
3141 ULONG nDrive)
3142{
3143 CHAR letter;
3144
3145 PrintMessage(MSG_DRIVE_LETTER, nDrive);
3146
3147 VfdGetGlobalLink(hDevice, &letter);
3148
3149 if (isalpha(letter)) {
3150 PrintMessage(MSG_PERSISTENT, toupper(letter));
3151 }
3152
3153 while (VfdGetLocalLink(hDevice, &letter) == ERROR_SUCCESS &&
3154 isalpha(letter)) {
3155 PrintMessage(MSG_EPHEMERAL, toupper(letter));
3156 }
3157
3158 printf("\n");
3159}
3160
3161//
3162// Prints a text on screen a page a time
3163//
3165{
3166 static int rows = 0;
3167 char prompt[80];
3168 int prompt_len = 0;
3170 HANDLE hStdIn;
3171
3172 //
3173 // prepare the console input and output handles
3174 //
3177
3178 for (;;) {
3181 DWORD result;
3182 DWORD mode;
3183 int cols;
3184 char *cur;
3185 char save;
3186
3187 //
3188 // Get the current console screen information
3189 //
3191
3192 if (bReset || rows <= 0) {
3193 rows = info.srWindow.Bottom - info.srWindow.Top - 1;
3194 }
3195
3196 cols = info.dwSize.X;
3197
3198 // console window is too small for paging
3199
3200 if (rows <= 0) {
3201 // print all text and exit
3202 printf("%s", pBuffer);
3203 break;
3204 }
3205
3206 //
3207 // find the tail of the text to be printed this time
3208 //
3209 cur = pBuffer;
3210 save = '\0';
3211
3212 while (*cur) {
3213 if (*(cur++) == '\n' || (cols--) == 0) {
3214 // reached the end of a line
3215 if (--rows == 0) {
3216 // reached the end of a page
3217 // insert a terminating NULL char
3218 save = *cur;
3219 *cur = '\0';
3220 break;
3221 }
3222
3223 cols = info.dwSize.X;
3224 }
3225 }
3226
3227 // print the current page
3228 printf("%s", pBuffer);
3229
3230 // end of the whole text?
3231 if (save == '\0') {
3232 break;
3233 }
3234
3235 //
3236 // prompt for the next page
3237 //
3238
3239 // prepare the prompt text
3240
3241 if (prompt_len == 0) {
3242
3243 prompt_len = FormatMessage(
3246 NULL, MSG_PAGER_PROMPT, 0,
3247 prompt, sizeof(prompt), NULL);
3248
3249 if (prompt_len == 0) {
3250 strcpy(prompt, "Press any key to continue...");
3251 prompt_len = strlen(prompt);
3252 }
3253 }
3254
3255 // get the current console input mode
3256
3258
3259 // change the mode to receive Ctrl+C as a regular input
3260
3262
3263 // get the current cursor position
3264
3266
3267 // print the prompt text
3268
3270 prompt_len, info.dwCursorPosition, &result);
3271
3272 // reverse the text color
3273
3275 (WORD)(info.wAttributes | COMMON_LVB_REVERSE_VIDEO),
3276 prompt_len, info.dwCursorPosition, &result);
3277
3278 // move cursor to the end of the prompt text
3279
3280 info.dwCursorPosition.X =
3281 (short)(info.dwCursorPosition.X + prompt_len);
3282
3283 SetConsoleCursorPosition(hStdOut, info.dwCursorPosition);
3284
3285 // wait for a key press event
3286
3288
3289 do {
3291 }
3292 while (input.EventType != KEY_EVENT ||
3293 !input.Event.KeyEvent.bKeyDown ||
3294 !input.Event.KeyEvent.uChar.AsciiChar);
3295
3296 // restore the original cursor position
3297
3298 info.dwCursorPosition.X =
3299 (short)(info.dwCursorPosition.X - prompt_len);
3300
3301 SetConsoleCursorPosition(hStdOut, info.dwCursorPosition);
3302
3303 // delete the prompt text
3304
3306 prompt_len, info.dwCursorPosition, &result);
3307
3308 // restore the text attribute to norml
3309
3311 prompt_len, info.dwCursorPosition, &result);
3312
3313 // restore the original console mode
3314
3316
3317 // check if the input was 'q', <esc> or <Ctrl+C> ?
3318
3319 if (input.Event.KeyEvent.uChar.AsciiChar == VK_CANCEL ||
3320 input.Event.KeyEvent.uChar.AsciiChar == VK_ESCAPE ||
3321 tolower(input.Event.KeyEvent.uChar.AsciiChar) == 'q') {
3322
3323 // cancelled by the user
3324 return FALSE;
3325 }
3326
3327 //
3328 // process the next page
3329 //
3330 *cur = save;
3331 pBuffer = cur;
3332 }
3333
3334 return TRUE;
3335}
3336
3337//
3338// Format and print a message text
3339//
3341{
3342 char *buf = NULL;
3343 va_list list;
3344
3345 va_start(list, msg);
3346
3347 if (FormatMessage(
3350 NULL, msg, 0, (LPTSTR)&buf, 0, &list)) {
3351
3352 printf("%s", buf);
3353 }
3354 else {
3355 printf("Unknown Message ID %u\n", msg);
3356 }
3357
3358 va_end(list);
3359
3360 if (buf) {
3361 LocalFree(buf);
3362 }
3363}
3364
3365//
3366// Return a system error message text
3367//
3369{
3370 static char msg[256];
3371
3372 if (!FormatMessage(
3375 NULL, err, 0, msg, sizeof(msg), NULL)) {
3376#ifndef __REACTOS__
3377 sprintf(msg, "Unknown system error %lu (0x%08x)\n", err, err);
3378#else
3379 sprintf(msg, "Unknown system error %lu (0x%08lx)\n", err, err);
3380#endif
3381 }
3382
3383 return msg;
3384}
3385
3386//
3387// Convert a path to match the case of names on the disk
3388//
3389void ConvertPathCase(char *src, char *dst)
3390{
3391 HANDLE hFind;
3393 char *p;
3394
3395 p = dst;
3396
3397 if (*src == '\"') {
3398 src++;
3399 }
3400
3401 if (*(src + strlen(src) - 1) == '\"') {
3402 *(src + strlen(src) - 1) = '\0';
3403 }
3404
3405 //
3406 // handle drive / remote server name
3407 //
3408 if (isalpha(*src) && *(src + 1) == ':') {
3409
3410 // drive name
3411
3412 *(p++) = (char)toupper(*src);
3413 strcpy(p++, ":\\");
3414
3415 src += 2;
3416 }
3417 else if (*src == '\\' || *src == '/') {
3418
3419 // absolute path or remote name
3420
3421 if ((*(src + 1) == '\\' || *(src + 1) == '/') &&
3422 *(src + 2) && *(src + 2) != '\\' && *(src + 2) != '/') {
3423
3424 // remote path
3425
3426 *(p++) = '\\';
3427 *(p++) = '\\';
3428 src += 2;
3429
3430 while (*src && *src != '\\' && *src != '/') {
3431 *(p++) = *(src++);
3432 }
3433 }
3434
3435 strcpy(p, "\\");
3436 }
3437 else {
3438 *p = '\0';
3439 }
3440
3441 // skip redundant '\'
3442
3443 while (*src == '\\' || *src == '/') {
3444 src++;
3445 }
3446
3447 // process the path
3448
3449 while (*src) {
3450
3451 char *q = src;
3452
3453 // separate the next part
3454
3455 while (*q && *q != '\\' && *q != '/') {
3456 q++;
3457 }
3458
3459 if ((q - src) == 2 && !strncmp(src, "..", 2)) {
3460 // parent dir - copy as it is
3461 if (p != dst) {
3462 *p++ = '\\';
3463 }
3464
3465 strcpy(p, "..");
3466 p += 2;
3467 }
3468 else if ((q - src) > 1 || *src != '.') {
3469 // path name other than "."
3470 if (p != dst) {
3471 *(p++) = '\\';
3472 }
3473
3474 strncpy(p, src, (q - src));
3475 *(p + (q - src)) = '\0';
3476
3477 hFind = FindFirstFile(dst, &find);
3478
3479 if (hFind == INVALID_HANDLE_VALUE) {
3480 strcpy(p, src);
3481 break;
3482 }
3483
3484 FindClose(hFind);
3485
3486 strcpy(p, find.cFileName);
3487 p += strlen(p);
3488 }
3489
3490 // skip trailing '\'s
3491
3492 while (*q == '\\' || *q == '/') {
3493 q++;
3494 }
3495
3496 src = q;
3497 }
3498}
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isalpha(c)
Definition: acclib.h:74
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int toupper(int c)
Definition: utclib.c:881
int tolower(int c)
Definition: utclib.c:902
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define msg(x)
Definition: auth_time.c:54
BOOL WINAPI FlushConsoleInputBuffer(IN HANDLE hConsoleInput)
Definition: console.c:220
BOOL WINAPI SetConsoleCursorPosition(IN HANDLE hConsoleOutput, IN COORD dwCursorPosition)
Definition: console.c:641
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
BOOL WINAPI FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: console.c:525
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:595
#define CHAR(Char)
#define _stricmp
Definition: cat.c:22
Definition: list.h:37
#define _CRTDBG_LEAK_CHECK_DF
Definition: crtdbg.h:52
#define _CRTDBG_REPORT_FLAG
Definition: crtdbg.h:60
#define _CrtSetDbgFlag(f)
Definition: crtdbg.h:245
static TAGID TAGID find
Definition: db.cpp:155
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define MAX_PATH
Definition: compat.h:34
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static const WCHAR version[]
Definition: asmname.c:66
BOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode)
Definition: console.c:1569
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode)
Definition: console.c:1606
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
int main()
Definition: test.c:6
int global
Definition: ehframes.cpp:22
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define printf
Definition: freeldr.h:97
return pTarget Start()
FxCollectionEntry * cur
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint64EXT * result
Definition: glext.h:11304
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define stdout
Definition: stdio.h:99
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
#define stdin
Definition: stdio.h:98
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
PCHAR Help
Definition: kdb_cli.c:345
#define c
Definition: ke_i.h:80
_In_opt_ PVOID _Out_ BOOLEAN * Stop
Definition: ldrtypes.h:241
#define Open
Definition: syshdrs.h:62
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
struct task_struct * current
Definition: linux.c:32
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static unsigned int number
Definition: dsound.c:1479
static const struct access_res create[16]
Definition: package.c:7505
static LPCWSTR file_name
Definition: protocol.c:147
HANDLE hStdOut
Definition: more.c:49
HANDLE hStdIn
Definition: more.c:49
#define argv
Definition: mplay32.c:18
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_COMPRESSED
Definition: nt_native.h:711
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define FILE_ATTRIBUTE_ENCRYPTED
Definition: ntifs_ex.h:385
#define LOWORD(l)
Definition: pedump.c:82
static const char topic[]
Definition: propsys.c:44
PVOID pBuffer
#define err(...)
#define list
Definition: rosglue.h:35
@ Close
Definition: sacdrv.h:268
int __cdecl system(_In_opt_z_ const char *_Command)
FD_TYPE file_type(FDSC **curr, char *fixed)
Definition: file.c:221
#define args
Definition: format.c:66
Definition: match.c:390
Definition: ftp_var.h:139
Definition: match.c:28
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
VFD_MEDIA WINAPI VfdLookupMedia(ULONG nSize)
Definition: vfdctl.c:3256
DWORD WINAPI VfdCheckHandlers()
Definition: vfdshutil.cpp:393
ULONG WINAPI VfdGetMediaSize(VFD_MEDIA nMediaType)
Definition: vfdctl.c:3272
DWORD WINAPI VfdSetLocalLink(HANDLE hDevice, CHAR cLetter)
Definition: vfdctl.c:2154
DWORD WINAPI VfdFormatMedia(HANDLE hDevice)
Definition: vfdctl.c:2523
DWORD WINAPI VfdUnregisterHandlers()
Definition: vfdshutil.cpp:297
DWORD WINAPI VfdWriteProtect(HANDLE hDevice, BOOL bProtect)
Definition: vfdctl.c:2484
DWORD WINAPI VfdStopDriver(PDWORD pState)
Definition: vfdctl.c:801
DWORD WINAPI VfdSaveImage(HANDLE hDevice, PCSTR sFileName, BOOL bOverWrite, BOOL bTruncate)
Definition: vfdctl.c:2685
DWORD WINAPI VfdGetDriverState(PDWORD pState)
Definition: vfdctl.c:1121
DWORD WINAPI VfdRemoveDriver()
Definition: vfdctl.c:557
CHAR WINAPI VfdChooseLetter()
Definition: vfdctl.c:3205
#define VFD_NOT_INSTALLED
Definition: vfdapi.h:20
DWORD WINAPI VfdGetGlobalLink(HANDLE hDevice, PCHAR pLetter)
Definition: vfdctl.c:2114
void WINAPI VfdMakeFileDesc(PSTR pBuffer, ULONG nBufSize, VFD_FILETYPE nFileType, ULONG nFileSize, DWORD nFileAttr)
Definition: vfdguiut.c:376
DWORD WINAPI VfdGetImageInfo(HANDLE hDevice, PSTR sFileName, PVFD_DISKTYPE pDiskType, PVFD_MEDIA pMediaType, PVFD_FLAGS pMediaFlags, PVFD_FILETYPE pFileType, PULONG pImageSize)
Definition: vfdctl.c:1839
DWORD WINAPI VfdInstallDriver(PCSTR sFileName, DWORD nStart)
Definition: vfdctl.c:241
HANDLE WINAPI VfdOpenDevice(ULONG nTarget)
Definition: vfdctl.c:1215
DWORD WINAPI VfdDismountVolume(HANDLE hDevice, BOOL bForce)
Definition: vfdctl.c:2629
DWORD WINAPI VfdGetLocalLink(HANDLE hDevice, PCHAR pLetter)
Definition: vfdctl.c:2281
DWORD WINAPI VfdGetMediaState(HANDLE hDevice)
Definition: vfdctl.c:1949
DWORD WINAPI VfdCheckDriverFile(PCSTR sFileName, PULONG pFileVersion)
Definition: vfdctl.c:2867
DWORD WINAPI VfdGetDriverVersion(HANDLE hDevice, PULONG pVersion)
Definition: vfdctl.c:2446
PCSTR WINAPI VfdMediaTypeName(VFD_MEDIA nMediaType)
Definition: vfdctl.c:3280
DWORD WINAPI VfdGetDriverConfig(PSTR sFileName, PDWORD pStart)
Definition: vfdctl.c:959
DWORD WINAPI VfdCheckImageFile(PCSTR sFileName, PDWORD pAttributes, PVFD_FILETYPE pFileType, PULONG pImageSize)
Definition: vfdctl.c:3035
DWORD WINAPI VfdGetDeviceNumber(HANDLE hDevice, PULONG pNumber)
Definition: vfdctl.c:2359
DWORD WINAPI VfdCreateImageFile(PCSTR sFileName, VFD_MEDIA nMediaType, VFD_FILETYPE nFileType, BOOL bOverWrite)
Definition: vfdctl.c:3126
BOOL WINAPI VfdIsValidPlatform()
Definition: vfdlib.c:87
DWORD WINAPI VfdRegisterHandlers()
Definition: vfdshutil.cpp:100
DWORD WINAPI VfdStartDriver(PDWORD pState)
Definition: vfdctl.c:647
DWORD WINAPI VfdConfigDriver(DWORD nStart)
Definition: vfdctl.c:468
DWORD WINAPI VfdSetGlobalLink(HANDLE hDevice, CHAR cLetter)
Definition: vfdctl.c:1984
DWORD hint
Definition: vfdcmd.c:88
static const char * SystemError(DWORD err)
Definition: vfdcmd.c:3368
static int CheckDriver()
Definition: vfdcmd.c:2982
#define OPERATION_QUIT
Definition: vfdcmd.c:51
cmdfnc func
Definition: vfdcmd.c:87
#define CMD_MATCH_MULTI
char * keyword
Definition: vfdcmd.c:115
static const struct @1539 Commands[]
#define PROTECT_OFF
#define PROTECT_NONE
static int Link(const char **args)
Definition: vfdcmd.c:2414
#define OPERATION_FORCE
Definition: vfdcmd.c:52
static int InputChar(ULONG msg, PCSTR ans)
Definition: vfdcmd.c:3015
#define VFD_OK
Definition: vfdcmd.c:44
char * cmd
Definition: vfdcmd.c:85
#define OPERATION_ASK
Definition: vfdcmd.c:50
#define IS_WINDOWS_NT()
Definition: vfdcmd.c:159
static void PrintMessage(UINT msg,...)
Definition: vfdcmd.c:3340
int max_args
Definition: vfdcmd.c:86
static int Save(const char **args)
Definition: vfdcmd.c:1851
static int Unlink(const char **args)
Definition: vfdcmd.c:2549
static DWORD driver_state
Definition: vfdcmd.c:34
#define PROTECT_ON
static void ConvertPathCase(char *src, char *dst)
Definition: vfdcmd.c:3389
#define TARGET_NONE
Definition: vfdcmd.c:57
static int InteractiveConsole()
Definition: vfdcmd.c:231
int(* cmdfnc)(const char **args)
Definition: vfdcmd.c:62
static int ProcessCommandLine(int argc, const char **args)
Definition: vfdcmd.c:478
static int ParseCommand(const char *cmd)
Definition: vfdcmd.c:2870
#define VFD_NG
Definition: vfdcmd.c:45
static int Shell(const char **args)
Definition: vfdcmd.c:1020
static void PrintImageInfo(HANDLE hDevice)
Definition: vfdcmd.c:3051
static const struct @1540 HelpMsg[]
#define CMD_MATCH_NONE
static void PrintDriveLetter(HANDLE hDevice, ULONG nDrive)
Definition: vfdcmd.c:3139
static int ParseHelpTopic(const char *topic)
Definition: vfdcmd.c:2929
static const char * help_progname
Definition: vfdcmd.c:39
static BOOL ConsolePager(char *pBuffer, BOOL bReset)
Definition: vfdcmd.c:3164
static int Install(const char **args)
Definition: vfdcmd.c:535
DWORD help
Definition: vfdcmd.c:116
VOID VfdCloseImage(IN PDEVICE_EXTENSION DeviceExtension)
Definition: vfdimg.c:435
NTSTATUS VfdOpenImage(IN PDEVICE_EXTENSION DeviceExtension, IN PVFD_IMAGE_INFO ImageInfo)
Definition: vfdimg.c:104
UCHAR VFD_FILETYPE
Definition: vfdtypes.h:62
#define VFD_MAXIMUM_DEVICES
Definition: vfdtypes.h:75
UCHAR VFD_MEDIA
Definition: vfdtypes.h:61
UCHAR VFD_DISKTYPE
Definition: vfdtypes.h:60
@ VFD_MEDIA_F3_820
Definition: vfdtypes.h:36
@ VFD_MEDIA_NONE
Definition: vfdtypes.h:27
@ VFD_MEDIA_F3_640
Definition: vfdtypes.h:32
@ VFD_MEDIA_F3_1P6
Definition: vfdtypes.h:40
@ VFD_MEDIA_F5_180
Definition: vfdtypes.h:29
@ VFD_MEDIA_F3_1P4
Definition: vfdtypes.h:39
@ VFD_MEDIA_F5_320
Definition: vfdtypes.h:30
@ VFD_MEDIA_F3_720
Definition: vfdtypes.h:34
@ VFD_MEDIA_F3_2P8
Definition: vfdtypes.h:42
@ VFD_MEDIA_F3_1P2
Definition: vfdtypes.h:37
@ VFD_MEDIA_F5_160
Definition: vfdtypes.h:28
@ VFD_MEDIA_F3_1P7
Definition: vfdtypes.h:41
@ VFD_MEDIA_F5_360
Definition: vfdtypes.h:31
@ VFD_DISKTYPE_FILE
Definition: vfdtypes.h:18
@ VFD_DISKTYPE_RAM
Definition: vfdtypes.h:19
@ VFD_FILETYPE_NONE
Definition: vfdtypes.h:51
@ VFD_FILETYPE_RAW
Definition: vfdtypes.h:52
@ VFD_FILETYPE_ZIP
Definition: vfdtypes.h:53
#define VFD_FLAG_DATA_MODIFIED
Definition: vfdtypes.h:69
#define VFD_FLAG_WRITE_PROTECTED
Definition: vfdtypes.h:68
UCHAR VFD_FLAGS
Definition: vfdtypes.h:63
#define VFD_PRODUCT_DESC
Definition: vfdver.h:66
#define VFD_COPYRIGHT_STR
Definition: vfdver.h:69
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
#define FormatMessage
Definition: winbase.h:3795
#define ZeroMemory
Definition: winbase.h:1712
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define STD_INPUT_HANDLE
Definition: winbase.h:267
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GetFileAttributes
Definition: winbase.h:3815
#define SetCurrentDirectory
Definition: winbase.h:3903
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:424
#define FORMAT_MESSAGE_FROM_HMODULE
Definition: winbase.h:422
#define FindFirstFile
Definition: winbase.h:3782
#define GetCurrentDirectory
Definition: winbase.h:3805
#define WriteConsoleOutputCharacter
Definition: wincon.h:789
#define ReadConsoleInput
Definition: wincon.h:778
#define KEY_EVENT
Definition: wincon.h:128
#define SetConsoleTitle
Definition: wincon.h:783
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78
#define COMMON_LVB_REVERSE_VIDEO
Definition: wincon.h:53
#define FillConsoleOutputCharacter
Definition: wincon.h:788
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_WRITE_PROTECT
Definition: winerror.h:122
#define ERROR_NOT_READY
Definition: winerror.h:124
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_PAUSED
Definition: winsvc.h:27
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define SERVICE_PAUSE_PENDING
Definition: winsvc.h:26
#define SERVICE_CONTINUE_PENDING
Definition: winsvc.h:25
#define VK_CANCEL
Definition: winuser.h:2195
#define VK_ESCAPE
Definition: winuser.h:2217
#define SERVICE_DEMAND_START
Definition: cmtypes.h:978
#define SERVICE_DISABLED
Definition: cmtypes.h:979
#define SERVICE_AUTO_START
Definition: cmtypes.h:977
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
char TCHAR
Definition: xmlstorage.h:189
CHAR * LPTSTR
Definition: xmlstorage.h:192
char CHAR
Definition: xmlstorage.h:175
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:221