ReactOS 0.4.15-dev-7906-g1b85a5f
vfdctl.c
Go to the documentation of this file.
1/*
2 vfdctl.c
3
4 Virtual Floppy Drive for Windows
5 Driver control library
6 Driver and image control functions
7
8 Copyright (C) 2003-2005 Ken Kato
9*/
10
11#ifdef __cplusplus
12#pragma message(__FILE__": Compiled as C++ for testing purpose.")
13#endif // __cplusplus
14
15#define WIN32_LEAN_AND_MEAN
16#include <windows.h>
17#include <dbt.h>
18#ifdef _MSC_VER
19#pragma warning (push, 3)
20#endif
21#include <shlobj.h>
22#include <winioctl.h>
23#ifdef _MSC_VER
24#pragma warning (pop)
25#endif
26#include <stdio.h>
27
28#include "vfdtypes.h"
29#include "vfdio.h"
30#include "vfdapi.h"
31#include "vfdlib.h"
32#include "vfdver.h"
33
34#ifndef IOCTL_DISK_GET_LENGTH_INFO
35// Old winioctl.h header doesn't define the following
36
37#define IOCTL_DISK_GET_LENGTH_INFO CTL_CODE(\
38IOCTL_DISK_BASE, 0x0017, METHOD_BUFFERED, FILE_READ_ACCESS)
39
40typedef struct _GET_LENGTH_INFORMATION {
43
44#endif // IOCTL_DISK_GET_LENGTH_INFO
45
46//
47// DOS device name (\\.\VirtualFD)
48//
49#ifndef __REACTOS__
50#define VFD_DEVICE_TEMPLATE "\\\\.\\" VFD_DEVICE_BASENAME "%u"
51#else
52#define VFD_DEVICE_TEMPLATE "\\\\.\\" VFD_DEVICE_BASENAME "%lu"
53#endif
54#define VFD_VOLUME_TEMPLATE "\\\\.\\%c:"
55
56#define VFD_INSTALL_DIRECTORY "\\system32\\drivers\\"
57
58#ifdef _DEBUG
59#ifndef __REACTOS__
60extern ULONG TraceFlags = (ULONG)-1;//0;
61extern CHAR *TraceFile = NULL;
62extern ULONG TraceLine = 0;
63#else
64ULONG TraceFlags = (ULONG)-1;//0;
65CHAR const * TraceFile = NULL;
66ULONG TraceLine = 0;
67#endif
68#endif
69
70//
71// broadcast a WM_DEVICECHANGE system message to inform
72// a drive letter creation / removal
73//
74#define VFD_LINK_CREATED 0
75#define VFD_LINK_REMOVED 1
76
77static void VfdBroadcastLink(
78 CHAR cLetter,
79 BOOL bRemoved)
80{
81 DWORD receipients;
82 DWORD device_event;
84
85 if (!isalpha(cLetter)) {
86 VFDTRACE(0,
87 ("VfdBroadcastLink: invalid parameter"))
88 return;
89 }
90
91 receipients = BSM_APPLICATIONS;
92
93 device_event = bRemoved ?
95
96 ZeroMemory(&params, sizeof(params));
97
98 params.dbcv_size = sizeof(params);
99 params.dbcv_devicetype = DBT_DEVTYP_VOLUME;
100 params.dbcv_reserved = 0;
101 params.dbcv_unitmask = (1 << (toupper(cLetter) - 'A'));
102 params.dbcv_flags = 0;
103
106 &receipients,
108 device_event,
109 (LPARAM)&params) <= 0) {
110
111 VFDTRACE(0,
112 ("VfdBroadcastLink: BroadcastSystemMessage - %s",
114 }
115}
116
117//
118// Broadcast a VFD notify message
119//
120static __inline void VfdNotify(
123{
124 // SendNotifyMessage causes volume locking conflict (I think)
125 // on Windows XP while closing an image with VfdWin
126// SendNotifyMessage(HWND_BROADCAST, uVfdMsg, wParam, lParam);
128}
129
130#ifdef VFD_EMBED_DRIVER
131//
132// Restore the VFD driver file in the system directory
133//
134
135static DWORD VfdRestoreDriver(
136 PCSTR sPath)
137{
138#define FUNC "VfdRestoreDriver"
139 HRSRC hRes;
140 DWORD size;
141 HGLOBAL hDrv;
142 PVOID pData;
145 DWORD ret;
146
147 //
148 // Prepare driver binary
149 //
150
151 // use embedded driver binary
152
153#define S(s) #s
155 S(VFD_DRIVER_NAME_ID), S(VFD_DRIVER_TYPE_ID));
156#undef S
157
158 if (hRes == NULL) {
159 ret = GetLastError();
160
161 VFDTRACE(0,
162 (FUNC ": FindResource - %s",
164
165 return ret;
166 }
167
169
170 if (size == 0) {
171 ret = GetLastError();
172
173 VFDTRACE(0,
174 (FUNC ": SizeofResource - %s",
176
177 return ret;
178 }
179
180 hDrv = LoadResource(g_hDllModule, hRes);
181
182 if (hDrv == NULL) {
183 ret = GetLastError();
184
185 VFDTRACE(0,
186 (FUNC ": LoadResource - %s",
188
189 return ret;
190 }
191
192 pData = LockResource(hDrv);
193
194 if (pData == NULL) {
195 ret = GetLastError();
196
197 VFDTRACE(0,
198 (FUNC ": LockResource - %s",
200
201 return ret;
202 }
203
204 // create the driver file
205
207 0, NULL, OPEN_ALWAYS, 0, NULL);
208
210 ret = GetLastError();
211
212 VFDTRACE(0,
213 (FUNC ": CreateFile(%s) - %s",
214 sPath, SystemMessage(ret)));
215
216 return ret;
217 }
218
219 if (!WriteFile(hFile, pData, size, &result, NULL) ||
220 size != result) {
221 ret = GetLastError();
222
223 VFDTRACE(0,
224 (FUNC ": CreateFile - %s",
226
228 return ret;
229 }
230
233
234 return ERROR_SUCCESS;
235}
236#endif // VFD_EMBED_DRIVER
237
238//
239// Install the Virtual Floppy Driver
240//
242 PCSTR sFileName,
243 DWORD nStart)
244{
245#undef FUNC
246#define FUNC "VfdInstallDriver"
247 SC_HANDLE hScManager; // Service Control Manager
248 SC_HANDLE hService = NULL; // Service (= Driver)
249#ifndef VFD_EMBED_DRIVER
252#endif // VFD_EMBED_DRIVER
253 CHAR system_dir[MAX_PATH];
254 PSTR inst_path;
255 DWORD len;
257
258#ifdef __REACTOS__
259 CHAR full_file_path[MAX_PATH];
260#endif
261
262 // get SystemRoot directory path
263
264// len = GetEnvironmentVariable(
265// "SystemRoot", system_dir, sizeof(system_dir));
266 len = GetWindowsDirectory(system_dir, sizeof(system_dir));
267
268 if (len == 0 || len > sizeof(system_dir)) {
269 VFDTRACE(0,
270 (FUNC ": %%SystemRoot%% is empty or too long.\n"));
271
273 }
274
275 inst_path = &system_dir[len];
276
277#ifdef __REACTOS__
278 strcpy(full_file_path, system_dir);
279 strcat(full_file_path, VFD_INSTALL_DIRECTORY);
280 strcat(full_file_path, VFD_DRIVER_FILENAME);
281#endif
282
283#ifdef VFD_EMBED_DRIVER
284 //
285 // use embedded driver file
286 //
288
289 ret = VfdRestoreDriver(system_dir);
290
291 if (ret != ERROR_SUCCESS) {
292 return ret;
293 }
294
295#else // VFD_EMBED_DRIVER
296 // Prepare driver binary's full path
297
298 if (sFileName == NULL || *sFileName == '\0') {
299
300 // default driver file is vfd.sys in the same directory as executable
301
303 NULL, file_path, sizeof(file_path));
304
305 if (len == 0) {
306 ret = GetLastError();
307
308 VFDTRACE(0,
309 (FUNC ": GetModuleFileName - %s",
311
312 return ret;
313 }
314
315 // search the last '\' character
316
317 while (len > 0 && file_path[len - 1] != '\\') {
318 len --;
319 }
320
321 // supply the file name (vfd.sys)
322
325 }
326 else {
327
328 // ensure that tha path is an absolute full path
329
331 sFileName,
332 sizeof(file_path),
333 file_path,
334 &file_name);
335
336 if (len == 0) {
337 ret = GetLastError();
338
339 VFDTRACE(0,
340 (FUNC ": GetFullPathName(%s) - %s\n",
341 sFileName, SystemMessage(ret)));
342
343 return ret;
344 }
345
347 // if the specified path is a directory,
348 // supply the file name (vfd.sys)
349
352 }
353 }
354
355#ifdef __REACTOS__
356 // Check install directory & file exist or use full_file_path
357
359 strcpy(file_path, full_file_path);
360 }
361#endif
362
363 // Check if the file is a valid Virtual Floppy driver
364
366
367 if (ret != ERROR_SUCCESS) {
368 VFDTRACE(0,
369 (FUNC ": VfdCheckDriverFile(%s)\n", file_path));
370
371 return ret;
372 }
373
374 // if the path is under the system directory, make it relative
375 // to the system directory
376
377 len = strlen(system_dir);
378
379 if (!_strnicmp(file_path, system_dir, len)) {
380 inst_path = &file_path[len];
381
382 while (*inst_path == '\\') {
383 inst_path++;
384 }
385 }
386 else {
387 inst_path = &file_path[0];
388 }
389#endif // VFD_EMBED_DRIVER
390
391 // Connect to the Service Control Manager
392
393 hScManager = OpenSCManager(
394 NULL, // local machine
395 NULL, // local database
396 SC_MANAGER_CREATE_SERVICE); // access required
397
398 if (hScManager == NULL) {
399 ret = GetLastError();
400
401 VFDTRACE(0,
402 (FUNC ": OpenSCManager() - %s",
404
405 goto cleanup;
406 }
407
408 // Create a new service object
409
410 hService = CreateService(
411 hScManager, // service control manager
412 VFD_DEVICE_BASENAME, // internal service name
413 VFD_DEVICE_BASENAME, // display name
414 SERVICE_ALL_ACCESS, // access mode
415 SERVICE_KERNEL_DRIVER, // service type
416 nStart, // service start type
417 SERVICE_ERROR_NORMAL, // start error sevirity
418 inst_path, // service image file path
419 NULL, // service group
420 NULL, // service tag
421 NULL, // service dependency
422 NULL, // use LocalSystem account
423 NULL // password for the account
424 );
425
426 if (!hService) {
427 // Failed to create a service object
428 ret = GetLastError();
429
430 VFDTRACE(0,
431 (FUNC ": CreateService() - %s",
433
434 goto cleanup;
435 }
436
437cleanup:
438 // Close the service object handle
439
440 if (hService) {
441 CloseServiceHandle(hService);
442 }
443
444 // Close handle to the service control manager.
445
446 if (hScManager) {
447 CloseServiceHandle(hScManager);
448 }
449
450 if (ret == ERROR_SUCCESS) {
451 // Broadcast the successful operation
453 }
454#ifdef VFD_EMBED_DRIVER
455 else {
456 // Delete the restored driver file
457 DeleteFile(system_dir);
458 }
459#endif // VFD_EMBED_DRIVER
460
461 return ret;
462}
463
464//
465// Configure the Virtual Floppy Driver (change the start method)
466//
467
469 DWORD nStart)
470{
471#undef FUNC
472#define FUNC "VfdConfigDriver"
473 SC_HANDLE hScManager; // Service Control Manager
474 SC_HANDLE hService; // Service (= Driver)
476
477 // Connect to the Service Control Manager
478
479 hScManager = OpenSCManager(NULL, NULL, 0);
480
481 if (hScManager == NULL) {
482 ret = GetLastError();
483
484 VFDTRACE(0,
485 (FUNC ": OpenSCManager() - %s",
487
488 return ret;
489 }
490
491 // Open the VFD driver entry in the service database
492
493 hService = OpenService(
494 hScManager, // Service control manager
495 VFD_DEVICE_BASENAME, // service name
496 SERVICE_CHANGE_CONFIG); // service access mode
497
498 if (hService == NULL) {
499 ret = GetLastError();
500
501 VFDTRACE(0,
502 (FUNC ": OpenService(SERVICE_CHANGE_CONFIG) - %s",
504
505 goto cleanup;
506 }
507
508 // Change the start method of the VFD driver
509
511 hService,
513 nStart,
515 NULL,
516 NULL,
517 NULL,
518 NULL,
519 NULL,
520 NULL,
521 NULL)) {
522
523 ret = GetLastError();
524
525 VFDTRACE(0,
526 (FUNC ": ChangeServiceConfig() - %s",
528
529 goto cleanup;
530 }
531
532cleanup:
533 // Close the service object handle
534
535 if (hService) {
536 CloseServiceHandle(hService);
537 }
538
539 // Close handle to the service control manager.
540
541 if (hScManager) {
542 CloseServiceHandle(hScManager);
543 }
544
545 // Broadcast the successful operation
546
547 if (ret == ERROR_SUCCESS) {
549 }
550
551 return ret;
552}
553
554//
555// Remove the Virtual Floppy Driver entry from the service database
556//
558{
559#undef FUNC
560#define FUNC "VfdRemoveDriver"
561 SC_HANDLE hScManager; // Service Control Manager
562 SC_HANDLE hService; // Service (= Driver)
565
566 // Get the current driver path
567
569
570 if (ret != ERROR_SUCCESS) {
571 return ret;
572 }
573
574 // Connect to the Service Control Manager
575
576 hScManager = OpenSCManager(NULL, NULL, 0);
577
578 if (hScManager == NULL) {
579 ret = GetLastError();
580
581 VFDTRACE(0,
582 (FUNC ": OpenSCManager() - %s",
584
585 return ret;
586 }
587
588 // Open the VFD driver entry in the service database
589
590 hService = OpenService(
591 hScManager, // Service control manager
592 VFD_DEVICE_BASENAME, // service name
593 DELETE); // service access mode
594
595 if (hService == NULL) {
596 ret = GetLastError();
597
598 VFDTRACE(0,
599 (FUNC ": OpenService(DELETE) - %s",
601
602 goto cleanup;
603 }
604
605 // Remove driver entry from registry
606
607 if (!DeleteService(hService)) {
608 ret = GetLastError();
609
610 VFDTRACE(0,
611 (FUNC ": DeleteService() - %s",
613
614 goto cleanup;
615 }
616
617cleanup:
618 // Close the service object handle
619
620 if (hService) {
621 CloseServiceHandle(hService);
622 }
623
624 // Close handle to the service control manager.
625
626 if (hScManager) {
627 CloseServiceHandle(hScManager);
628 }
629
630 // Broadcast the successful operation
631
632 if (ret == ERROR_SUCCESS) {
634
635#ifdef VFD_EMBED_DRIVER
636 // Remove the driver file
638#endif // VFD_EMBED_DRIVER
639 }
640
641 return ret;
642}
643
644//
645// Start the Virtual Floppy Driver
646//
648 PDWORD pState)
649{
650#undef FUNC
651#define FUNC "VfdStartDriver"
652 SC_HANDLE hScManager; // Service Control Manager
653 SC_HANDLE hService; // Service (= Driver)
656 HCURSOR original;
657 int i;
658
659 if (pState) {
660 *pState = 0;
661 }
662
663 // Connect to the Service Control Manager
664
665 hScManager = OpenSCManager(NULL, NULL, 0);
666
667 if (hScManager == NULL) {
668 ret = GetLastError();
669
670 VFDTRACE(0,
671 (FUNC ": OpenSCManager() - %s",
673
674 return ret;
675 }
676
677 // show an hourglass cursor
678
679 original = SetCursor(LoadCursor(NULL, IDC_WAIT));
680
681 // Open the VFD driver entry in the service database
682
683 hService = OpenService(
684 hScManager, // Service control manager
685 VFD_DEVICE_BASENAME, // service name
687 | SERVICE_QUERY_STATUS); // service access mode
688
689 if (hService == NULL) {
690 ret = GetLastError();
691
692 VFDTRACE(0,
693 (FUNC ": OpenService(SERVICE_START) - %s",
695
696 goto cleanup;
697 }
698
699 // Start the driver
700
701 if (!StartService(hService, 0, NULL)) {
702 ret = GetLastError();
703
704 VFDTRACE(0,
705 (FUNC ": StartService() - %s",
707
708 goto cleanup;
709 }
710
711 // Wait until the driver is properly running
712
713 i = 0;
714
715 for (;;) {
716 if (!QueryServiceStatus(hService, &stat)) {
717 ret = GetLastError();
718
719 VFDTRACE(0,
720 (FUNC ": QueryServiceStatus() - %s",
722
723 break;
724 }
725
726 if (stat.dwCurrentState == SERVICE_RUNNING || ++i == 5) {
727 break;
728 }
729
730 Sleep(1000);
731 }
732
733 if (stat.dwCurrentState == SERVICE_RUNNING) {
734
735 // Broadcast the successful operation
736
737 if (ret == ERROR_SUCCESS) {
739 }
740
741 // broadcast the arrival of VFD drives
742 // otherwise WinXP explorer doesn't recognize the VFD drives
743
744 for (i = 0; i < VFD_MAXIMUM_DEVICES; i++) {
745 HANDLE hDevice;
746 CHAR letter = 0;
747
748 hDevice = VfdOpenDevice(i);
749
750 if (hDevice != INVALID_HANDLE_VALUE) {
751
752 VfdGetGlobalLink(hDevice, &letter);
753
754 CloseHandle(hDevice);
755
756 if (isalpha(letter)) {
759 }
760 }
761 else {
762 VFDTRACE(0,
763 (FUNC ": VfdOpenDevice(%d) - %s",
765 }
766 }
767 }
768 else {
769 // somehow failed to start the driver
770
772 }
773
774 if (pState) {
775 *pState = stat.dwCurrentState;
776 }
777
778cleanup:
779 // Close the service object handle
780
781 if (hService) {
782 CloseServiceHandle(hService);
783 }
784
785 // Close handle to the service control manager.
786
787 if (hScManager) {
788 CloseServiceHandle(hScManager);
789 }
790
791 // revert to the original cursor
792
793 SetCursor(original);
794
795 return ret;
796}
797
798//
799// Stop the Virtual Floppy Driver
800//
802 PDWORD pState)
803{
804#undef FUNC
805#define FUNC "VfdStopDriver"
806 SC_HANDLE hScManager; // Service Control Manager
807 SC_HANDLE hService; // Service (= Driver)
809 CHAR drive_letters[VFD_MAXIMUM_DEVICES];
811 int i;
812 HCURSOR original;
813
814 if (pState) {
815 *pState = 0;
816 }
817
818 // Connect to the Service Control Manager
819
820 hScManager = OpenSCManager(NULL, NULL, 0);
821
822 if (hScManager == NULL) {
823 ret = GetLastError();
824
825 VFDTRACE(0,
826 (FUNC ": OpenSCManager() - %s",
828
829 return ret;
830 }
831
832 // Show the hourglass cursor
833
834 original = SetCursor(LoadCursor(NULL, IDC_WAIT));
835
836 // Open the VFD driver entry in the service database
837
838 hService = OpenService(
839 hScManager, // Service control manager
840 VFD_DEVICE_BASENAME, // service name
842 | SERVICE_QUERY_STATUS); // service access mode
843
844 if (hService == NULL) {
845 ret = GetLastError();
846
847 VFDTRACE(0,
848 (FUNC ": OpenService(SERVICE_STOP) - %s",
850
851 goto cleanup;
852 }
853
854 // Get assigned drive letters
855
856 for (i = 0; i < VFD_MAXIMUM_DEVICES; i++) {
857 HANDLE hDevice;
858 CHAR letter;
859
860 hDevice = VfdOpenDevice(i);
861
862 if (hDevice != INVALID_HANDLE_VALUE) {
863
864 // remove all session local drive letters
865
866 while (VfdGetLocalLink(hDevice, &letter) == ERROR_SUCCESS &&
867 isalpha(letter)) {
868 VfdSetLocalLink(hDevice, 0);
869 }
870
871 // store existing persistent drive letters
872
873 VfdGetGlobalLink(hDevice, &drive_letters[i]);
874
875 CloseHandle(hDevice);
876 }
877 else {
878 VFDTRACE(0,
879 (FUNC ": VfdOpenDevice(%d) - %s",
881 }
882 }
883
884 // Stop the driver
885
886 if (!ControlService(hService, SERVICE_CONTROL_STOP, &stat)) {
887 ret = GetLastError();
888
889 VFDTRACE(0,
890 (FUNC ": ControlService(SERVICE_CONTROL_STOP) - %s",
892
893 goto cleanup;
894 }
895
896 // Wait until the driver is stopped
897
898 i = 0;
899
900 while (stat.dwCurrentState != SERVICE_STOPPED && ++i < 5) {
901 Sleep(1000);
902
903 if (!QueryServiceStatus(hService, &stat)) {
904 ret = GetLastError();
905
906 VFDTRACE(0,
907 (FUNC ": QueryServiceStatus() - %s",
909
910 break;
911 }
912 }
913
914 if (stat.dwCurrentState != SERVICE_RUNNING) {
915
916 // broadcast the removal of persistent drive letters
917
918 for (i = 0; i < VFD_MAXIMUM_DEVICES; i++) {
919 if (isalpha(drive_letters[i])) {
920 VfdBroadcastLink(drive_letters[i], VFD_LINK_REMOVED);
922 }
923 }
924 }
925
926 if (pState) {
927 *pState = stat.dwCurrentState;
928 }
929
930cleanup:
931 // Close the service object handle
932
933 if (hService) {
934 CloseServiceHandle(hService);
935 }
936
937 // Close handle to the service control manager.
938
939 if (hScManager) {
940 CloseServiceHandle(hScManager);
941 }
942
943 // Broadcast the successful operation
944
945 if (ret == ERROR_SUCCESS) {
947 }
948
949 // revert to the original cursor
950
951 SetCursor(original);
952
953 return ret;
954}
955
956//
957// Get the Virtual Floppy Driver configuration
958//
960 PSTR sFileName,
961 PDWORD pStart)
962{
963#undef FUNC
964#define FUNC "VfdGetDriverConfig"
965 SC_HANDLE hScManager; // Service Control Manager
966 SC_HANDLE hService; // Service (= Driver)
970
971 if (sFileName) {
972 ZeroMemory(sFileName, MAX_PATH);
973 }
974
975 if (pStart) {
976 *pStart = 0;
977 }
978
979 // Connect to the Service Control Manager
980
981 hScManager = OpenSCManager(NULL, NULL, 0);
982
983 if (hScManager == NULL) {
984 ret = GetLastError();
985
986 VFDTRACE(0,
987 (FUNC ": OpenSCManager() - %s", SystemMessage(ret)));
988
989 return ret;
990 }
991
992 // Open the VFD driver entry in the service database
993
994 hService = OpenService(
995 hScManager, // Service control manager
996 VFD_DEVICE_BASENAME, // service name
997 SERVICE_QUERY_CONFIG); // service access mode
998
999 if (hService == NULL) {
1000 ret = GetLastError();
1001
1002 VFDTRACE(0,
1003 (FUNC ": OpenService(SERVICE_QUERY_CONFIG) - %s",
1004 SystemMessage(ret)));
1005
1006 goto cleanup;
1007 }
1008
1009 // Get the length of config information
1010
1011 if (!QueryServiceConfig(hService, NULL, 0, &result)) {
1012 ret = GetLastError();
1013
1016 }
1017 else {
1018 VFDTRACE(0,
1019 (FUNC ": QueryServiceConfig() - %s",
1020 SystemMessage(ret)));
1021
1022 goto cleanup;
1023 }
1024 }
1025
1026 // allocate a required buffer
1027
1029
1030 if (config == NULL) {
1031 ret = GetLastError();
1032
1033 VFDTRACE(0,
1034 (FUNC ": LocalAlloc(%lu) - %s\n",
1036
1037 goto cleanup;
1038 }
1039
1040 // get the config information
1041
1042 if (!QueryServiceConfig(hService, config, result, &result)) {
1043 ret = GetLastError();
1044
1045 VFDTRACE(0,
1046 (FUNC ": QueryServiceConfig() - %s",
1047 SystemMessage(ret)));
1048
1049 goto cleanup;
1050 }
1051
1052 // copy information to output buffer
1053
1054 if (sFileName) {
1055 if (strncmp(config->lpBinaryPathName, "\\??\\", 4) == 0) {
1056
1057 // driver path is an absolute UNC path
1058 strncpy(
1059 sFileName,
1060 config->lpBinaryPathName + 4,
1061 MAX_PATH);
1062 }
1063 else if (config->lpBinaryPathName[0] == '\\' ||
1064 (isalpha(config->lpBinaryPathName[0]) &&
1065 config->lpBinaryPathName[1] == ':')) {
1066
1067 // driver path is an absolute path
1068 strncpy(sFileName,
1069 config->lpBinaryPathName,
1070 MAX_PATH);
1071 }
1072 else {
1073 // driver path is relative to the SystemRoot
1074// DWORD len = GetEnvironmentVariable(
1075// "SystemRoot", sFileName, MAX_PATH);
1076
1077 DWORD len = GetWindowsDirectory(sFileName, MAX_PATH);
1078
1079 if (len == 0 || len > MAX_PATH) {
1080 VFDTRACE(0,
1081 (FUNC ": %%SystemRoot%% is empty or too long.\n"));
1082
1084 goto cleanup;
1085 }
1086
1087 sprintf((sFileName + len), "\\%s",
1088 config->lpBinaryPathName);
1089 }
1090 }
1091
1092 if (pStart) {
1093 *pStart = config->dwStartType;
1094 }
1095
1096cleanup:
1097 // Free service config buffer
1098
1099 if (config) {
1101 }
1102
1103 // Close the service object handle
1104
1105 if (hService) {
1106 CloseServiceHandle(hService);
1107 }
1108
1109 // Close handle to the service control manager.
1110
1111 if (hScManager) {
1112 CloseServiceHandle(hScManager);
1113 }
1114
1115 return ret;
1116}
1117
1118//
1119// Get the Virtual Floppy Driver running state
1120//
1122 PDWORD pState)
1123{
1124#undef FUNC
1125#define FUNC "VfdGetDriverState"
1126 SC_HANDLE hScManager = NULL; // Service Control Manager
1127 SC_HANDLE hService = NULL; // Service (= Driver)
1130
1131 if (pState) {
1132 *pState = 0;
1133 }
1134
1135 // Connect to the Service Control Manager
1136
1137 hScManager = OpenSCManager(NULL, NULL, 0);
1138
1139 if (hScManager == NULL) {
1140 ret = GetLastError();
1141
1142 VFDTRACE(0,
1143 (FUNC ": OpenSCManager() - %s",
1144 SystemMessage(ret)));
1145
1146 return ret;
1147 }
1148
1149 // Open the VFD driver entry in the service database
1150
1151 hService = OpenService(
1152 hScManager, // Service control manager
1153 VFD_DEVICE_BASENAME, // service name
1154 SERVICE_QUERY_STATUS); // service access mode
1155
1156 if (hService == NULL) {
1157
1158 ret = GetLastError();
1159
1161
1162 if (pState) {
1163 *pState = VFD_NOT_INSTALLED;
1164 }
1165
1167 }
1168 else {
1169 VFDTRACE(0,
1170 (FUNC ": OpenService(SERVICE_QUERY_STATUS) - %s",
1171 SystemMessage(ret)));
1172 }
1173
1174 goto cleanup;
1175 }
1176
1177 // Get current driver status
1178
1179 ZeroMemory(&status, sizeof(status));
1180
1181 if (!QueryServiceStatus(hService, &status)) {
1182 ret = GetLastError();
1183
1184 VFDTRACE(0,
1185 (FUNC ": QueryServiceStatus() - %s",
1186 SystemMessage(ret)));
1187
1188 goto cleanup;
1189 }
1190
1191 if (pState) {
1192 *pState = status.dwCurrentState;
1193 }
1194
1195cleanup:
1196 // Close the service object handle
1197
1198 if (hService) {
1199 CloseServiceHandle(hService);
1200 }
1201
1202 // Close handle to the service control manager.
1203
1204 if (hScManager) {
1205 CloseServiceHandle(hScManager);
1206 }
1207
1208 return ret;
1209}
1210
1211//
1212// open a Virtual Floppy drive without showing the "Insert Floppy"
1213// dialog when the drive is empty.
1214//
1216 ULONG nTarget) // either a drive letter or a device number
1217{
1218#undef FUNC
1219#define FUNC "VfdOpenDevice"
1220 CHAR dev_name[20];
1221 UINT err_mode;
1222 HANDLE hDevice;
1223
1224 // format a device name string
1225
1226 if (isalpha(nTarget)) {
1227 // nTarget is a drive letter
1228 // \\.<x>:
1229#ifndef __REACTOS__
1231#else
1233#endif
1234 }
1235 else if (isdigit(nTarget)) {
1236 // nTarget is a device number in character
1237 // \\.\VirtualFD<n>
1238 sprintf(dev_name, VFD_DEVICE_TEMPLATE, nTarget - '0');
1239 }
1240 else {
1241 // nTarget is a device number value
1242 // \\.\VirtualFD<n>
1244 }
1245
1246 // change error mode in order to avoid "Insert Floppy" dialog
1247
1249
1250 // open the target drive
1251
1252 hDevice = CreateFile(
1253 dev_name,
1256 NULL,
1259 NULL);
1260
1261 // revert to the original error mode
1262
1263 SetErrorMode(err_mode);
1264
1265 if (hDevice != INVALID_HANDLE_VALUE) {
1266
1267 // check if the target is a valid VFD drive
1268
1269 ULONG version;
1270
1271 if (VfdGetDriverVersion(hDevice, &version) != ERROR_SUCCESS) {
1272
1273 // Failed to get the driver version
1274
1275 CloseHandle(hDevice);
1276 hDevice = INVALID_HANDLE_VALUE;
1277 }
1278 else if ((version & ~0x80000000) !=
1280
1281 // the driver version mismatch
1282
1283// CloseHandle(hDevice);
1284// hDevice = INVALID_HANDLE_VALUE;
1285
1287 }
1288 }
1289 else {
1290 VFDTRACE(0,(
1291 "CreateFile(%s) - %s", dev_name,
1293 }
1294
1295 return hDevice;
1296}
1297
1298//
1299// Open a Virtual Floppy Image
1300//
1302 HANDLE hDevice,
1303 PCSTR sFileName,
1304 VFD_DISKTYPE nDiskType,
1305 VFD_MEDIA nMediaType,
1306 VFD_FLAGS nMediaFlags)
1307{
1308#undef FUNC
1309#define FUNC "VfdOpenImage"
1310 PCSTR prefix;
1311 CHAR abspath[MAX_PATH];
1312 DWORD name_len;
1313 DWORD result;
1315
1316 PVFD_IMAGE_INFO image_info = NULL;
1317 PUCHAR image_buf = NULL;
1320
1321 //
1322 // Check parameters
1323 //
1324
1325 if (hDevice == NULL ||
1326 hDevice == INVALID_HANDLE_VALUE) {
1327 return ERROR_INVALID_HANDLE;
1328 }
1329
1330 if (nMediaType == VFD_MEDIA_NONE ||
1331 nMediaType >= VFD_MEDIA_MAX) {
1332
1333 VFDTRACE(0,
1334 (FUNC ": Invalid MediaType - %u\n", nMediaType));
1335
1337 }
1338
1339
1340 if (sFileName && *sFileName) {
1341
1342 // check file contents and attributes
1343
1344 HANDLE hFile = CreateFile(sFileName, GENERIC_READ,
1346
1347 if (hFile == INVALID_HANDLE_VALUE) {
1348 ret = GetLastError();
1349
1350 VFDTRACE(0,
1351 (FUNC ": CreateFile(%s) - %s",
1352 sFileName, SystemMessage(ret)));
1353
1354 return ret;
1355 }
1356
1357 // try extracting image data from zip compressed file
1358
1359 ExtractZipImage(hFile, &image_buf, &image_size);
1360
1361 if (image_buf) {
1362
1364
1365 // imz file must be opened in RAM mode
1366
1367 if (nDiskType == VFD_DISKTYPE_FILE) {
1368
1369 VFDTRACE(0,
1370 (FUNC ": %s is a zip compressed file",
1371 sFileName));
1372
1375
1376 goto exit_func;
1377 }
1378 }
1379 else {
1380
1382
1383 if (nDiskType == VFD_DISKTYPE_FILE) {
1384
1385 // direct image file must not be compressed or encrypted
1386
1388
1390 ret = GetLastError();
1391
1392 VFDTRACE(0,
1393 (FUNC ": GetFileInformationByHandle - %s",
1394 SystemMessage(ret)));
1395
1397
1398 return ret;
1399 }
1400
1401 if (info.dwFileAttributes &
1403
1404 VFDTRACE(0,
1405 (FUNC ": file is compressed/encrypted"));
1406
1408
1409 return ERROR_FILE_ENCRYPTED;
1410 }
1411
1412 image_size = info.nFileSizeLow;
1413 }
1414 else {
1415
1416 // prepare image data for a file based RAM disk
1417
1419
1420 if (image_size == 0 || image_size == INVALID_FILE_SIZE) {
1421 ret = GetLastError();
1422
1423 VFDTRACE(0,
1424 (FUNC ": GetFileSize - %s",
1425 SystemMessage(ret)));
1426
1428
1429 return ret;
1430 }
1431
1432 image_buf = (PUCHAR)LocalAlloc(LPTR, image_size);
1433
1434 if (image_buf == NULL) {
1435 ret = GetLastError();
1436
1437 VFDTRACE(0,
1438 (FUNC ": LocalAlloc - %s",
1439 SystemMessage(ret)));
1440
1442
1443 return ret;
1444 }
1445
1446 if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) != 0) {
1447 ret = GetLastError();
1448
1449 VFDTRACE(0,
1450 (FUNC ": SetFilePointer - %s",
1451 SystemMessage(ret)));
1452
1454
1455 goto exit_func;
1456 }
1457
1458 if (!ReadFile(hFile, image_buf, image_size, &result, NULL) ||
1459 image_size != result) {
1460
1461 ret = GetLastError();
1462
1463 VFDTRACE(0,
1464 (FUNC ": ReadFile - %s",
1465 SystemMessage(ret)));
1466
1468
1469 goto exit_func;
1470 }
1471 }
1472 }
1473
1475
1476 // Prepare absolute path in the kernel namespace
1477
1478 if (*sFileName == '\\' && *(sFileName + 1) == '\\') {
1479
1480 // \\server\share\path\floppy.img
1481
1482 prefix = "\\??\\UNC";
1483 sFileName++; // drip the first '\'
1484 }
1485 else {
1486
1487 // local path
1488
1489 PSTR file_part;
1490
1491 if (GetFullPathName(sFileName,
1492 sizeof(abspath), abspath, &file_part) == 0) {
1493
1494 ret = GetLastError();
1495
1496 VFDTRACE(0,
1497 (FUNC ": GetFullPathName(%s) - %s\n",
1498 sFileName, SystemMessage(ret)));
1499
1500 goto exit_func;
1501 }
1502
1503 prefix = "\\??\\";
1504 sFileName = abspath;
1505 }
1506
1507 name_len = strlen(prefix) + strlen(sFileName);
1508 }
1509 else {
1510
1511 // filename is not specified -- pure RAM disk
1512
1513 nDiskType = VFD_DISKTYPE_RAM;
1515
1516 prefix = NULL;
1517 name_len = 0;
1518
1519 // prepare a FAT formatted RAM image
1520
1521 image_size = VfdGetMediaSize(nMediaType);
1522
1523 image_buf = (PUCHAR)LocalAlloc(LPTR, image_size);
1524
1525 if (image_buf == NULL) {
1526 ret = GetLastError();
1527
1528 VFDTRACE(0,
1529 (FUNC ": LocalAlloc - %s",
1530 SystemMessage(ret)));
1531
1532 return ret;
1533 }
1534
1536 }
1537
1538 if (image_size < VfdGetMediaSize(nMediaType)) {
1539
1540 // image is too small for the specified media type
1541
1542 VFDTRACE(0,
1543 (FUNC ": Image is too small for the specified media type\n"));
1544
1546 goto exit_func;
1547 }
1548
1549 // prepare VFD_IMAGE_INFO structure
1550
1551 image_info = (PVFD_IMAGE_INFO)LocalAlloc(LPTR,
1552 sizeof(VFD_IMAGE_INFO) + name_len + 1);
1553
1554 if (image_info == NULL) {
1555 ret = GetLastError();
1556
1557 VFDTRACE(0,
1558 (FUNC ": LocalAlloc(%lu) - %s\n",
1559 sizeof(VFD_IMAGE_INFO) + name_len + 1,
1560 SystemMessage(ret)));
1561
1562 goto exit_func;
1563 }
1564
1565 ZeroMemory(image_info,
1566 sizeof(VFD_IMAGE_INFO) + name_len + 1);
1567
1568 if (name_len) {
1569 sprintf(image_info->FileName,
1570 "%s%s", prefix, sFileName);
1571 }
1572
1573 image_info->NameLength = (USHORT)name_len;
1574
1575 image_info->DiskType = nDiskType;
1576 image_info->MediaType = nMediaType;
1577 image_info->MediaFlags = nMediaFlags;
1578 image_info->FileType = file_type;
1579 image_info->ImageSize = image_size;
1580
1581 if (nDiskType != VFD_DISKTYPE_FILE) {
1582 // protect flag for a RAM disk is set after
1583 // initializing the image buffer
1584 image_info->MediaFlags &= ~VFD_FLAG_WRITE_PROTECTED;
1585 }
1586
1587 VFDTRACE(0,
1588 (FUNC ": Opening file \"%s\" (%lu bytes) %s %s %s %s\n",
1589 name_len ? image_info->FileName : "<RAM>",
1590 image_info->ImageSize,
1591 (file_type == VFD_FILETYPE_ZIP) ? "ZIP image" : "RAW image",
1592 VfdMediaTypeName(nMediaType),
1593 (nDiskType == VFD_DISKTYPE_FILE) ? "FILE disk" : "RAM disk",
1594 (nMediaFlags & VFD_FLAG_WRITE_PROTECTED) ? "Protected" : "Writable"));
1595
1596 // Open the image file / create a ram disk
1597
1598 if (!DeviceIoControl(
1599 hDevice,
1601 image_info,
1602 sizeof(VFD_IMAGE_INFO) + name_len,
1603 NULL,
1604 0,
1605 &result,
1606 NULL))
1607 {
1608 ret = GetLastError();
1609
1610 VFDTRACE(0,
1611 (FUNC ": DeviceIoControl(IOCTL_VFD_OPEN_FILE) - %s",
1612 SystemMessage(ret)));
1613
1614 goto exit_func;
1615 }
1616
1617 // initialize the RAM disk image
1618
1619 if (nDiskType != VFD_DISKTYPE_FILE) {
1620
1621 image_size &= ~VFD_SECTOR_ALIGN_MASK;
1622
1623 if (SetFilePointer(hDevice, 0, NULL, FILE_BEGIN) != 0) {
1624 ret = GetLastError();
1625
1626 VFDTRACE(0,
1627 (FUNC ": SetFilePointer - %s",
1628 SystemMessage(ret)));
1629
1630 goto exit_func;
1631 }
1632
1633 if (!WriteFile(hDevice, image_buf, image_size, &result, NULL) ||
1634 image_size != result) {
1635
1636 ret = GetLastError();
1637
1638 VFDTRACE(0,
1639 (FUNC ": WriteFile - %s",
1640 SystemMessage(ret)));
1641
1642 goto exit_func;
1643 }
1644
1645 if (nMediaFlags & VFD_FLAG_WRITE_PROTECTED) {
1646 VfdWriteProtect(hDevice, TRUE);
1647 }
1648
1649 if (!DeviceIoControl(
1650 hDevice,
1652 NULL,
1653 0,
1654 NULL,
1655 0,
1656 &result,
1657 NULL))
1658 {
1659 VFDTRACE(0,
1660 (FUNC ": DeviceIoControl(IOCTL_VFD_RESET_MODIFY) - %s",
1662 }
1663 }
1664
1665 // Broadcast the successful operation
1666
1667 if (ret == ERROR_SUCCESS) {
1668 ULONG number;
1669 CHAR root[] = "A:\\";
1670
1671 if (VfdGetDeviceNumber(hDevice, &number) == ERROR_SUCCESS) {
1673 }
1674
1675 VfdGetGlobalLink(hDevice, &root[0]);
1676
1677 if (isalpha(root[0])) {
1679 }
1680
1681 while (VfdGetLocalLink(hDevice, &root[0]) == ERROR_SUCCESS &&
1682 isalpha(root[0])) {
1684 }
1685 }
1686
1687exit_func:
1688 if (image_info) {
1689 LocalFree(image_info);
1690 }
1691
1692 if (image_buf) {
1693 LocalFree(image_buf);
1694 }
1695
1696 return ret;
1697}
1698
1699//
1700// Close the virtual floppy Image
1701//
1703 HANDLE hDevice,
1704 BOOL bForce)
1705{
1706#undef FUNC
1707#define FUNC "VfdCloseImage"
1708 DWORD result;
1710 int retry = 0;
1711
1712lock_retry:
1713 if (!DeviceIoControl(
1714 hDevice,
1716 NULL,
1717 0,
1718 NULL,
1719 0,
1720 &result,
1721 NULL))
1722 {
1723 ret = GetLastError();
1724
1725 VFDTRACE(0,
1726 (FUNC ": DeviceIoControl(FSCTL_LOCK_VOLUME) - %s",
1727 SystemMessage(ret)));
1728
1729 if (ret != ERROR_ACCESS_DENIED || retry == 5) {
1730 // error other than access denied or
1731 // operation kept failing for 5 seconds
1732 return ret;
1733 }
1734
1735 if (!bForce) {
1736 // error is access denied and
1737 // the force flag is not set
1738
1739 if (retry == 0) {
1740
1741 // send the MEDIAREMOVED notification to the shell and
1742 // see if the shell releases the target drive
1743
1744 CHAR root[] = "A:\\";
1745
1746 VfdGetGlobalLink(hDevice, &root[0]);
1747
1748 if (isalpha(root[0])) {
1750 }
1751
1752 while (VfdGetLocalLink(hDevice, &root[0]) == ERROR_SUCCESS &&
1753 isalpha(root[0])) {
1755 }
1756 }
1757
1758 Sleep(1000);
1759 retry++;
1760
1761 goto lock_retry;
1762 }
1763 }
1764
1766
1767 if (!DeviceIoControl(
1768 hDevice,
1770 NULL,
1771 0,
1772 NULL,
1773 0,
1774 &result,
1775 NULL))
1776 {
1777 ret = GetLastError();
1778
1779 VFDTRACE(0,
1780 (FUNC ": DeviceIoControl(FSCTL_DISMOUNT_VOLUME) - %s",
1781 SystemMessage(ret)));
1782
1783 return ret;
1784 }
1785
1786 if (!DeviceIoControl(
1787 hDevice,
1789 NULL,
1790 0,
1791 NULL,
1792 0,
1793 &result,
1794 NULL))
1795 {
1796 ret = GetLastError();
1797
1798 if (ret != ERROR_NOT_READY) {
1799 VFDTRACE(0,
1800 (FUNC ": DeviceIoControl(IOCTL_VFD_CLOSE_FILE) - %s",
1801 SystemMessage(ret)));
1802 }
1803
1804 return ret;
1805 }
1806
1807 if (!DeviceIoControl(
1808 hDevice,
1810 NULL,
1811 0,
1812 NULL,
1813 0,
1814 &result,
1815 NULL))
1816 {
1817 // This should not be fatal because the volume is unlocked
1818 // when the handle is closed anyway
1819 VFDTRACE(0,
1820 (FUNC ": DeviceIoControl(FSCTL_UNLOCK_VOLUME) - %s",
1822 }
1823
1824 // Broadcast the successful operation
1825 if (ret == ERROR_SUCCESS) {
1826 ULONG number;
1827
1828 if (VfdGetDeviceNumber(hDevice, &number) == ERROR_SUCCESS) {
1830 }
1831 }
1832
1833 return ret;
1834}
1835
1836//
1837// Get Virtual Floppy image info
1838//
1840 HANDLE hDevice,
1841 PSTR sFileName,
1842 PVFD_DISKTYPE pDiskType,
1843 PVFD_MEDIA pMediaType,
1844 PVFD_FLAGS pMediaFlags,
1845 PVFD_FILETYPE pFileType,
1846 PULONG pImageSize)
1847{
1848#undef FUNC
1849#define FUNC "VfdGetImageInfo"
1850 PVFD_IMAGE_INFO image_info;
1851 DWORD result;
1853
1854 image_info = (PVFD_IMAGE_INFO)LocalAlloc(
1855 LPTR, sizeof(VFD_IMAGE_INFO) + MAX_PATH);
1856
1857 if (image_info == NULL) {
1858 ret = GetLastError();
1859
1860 VFDTRACE(0,
1861 (FUNC ": LocalAlloc(%lu) - %s\n",
1863
1864 return ret;
1865 }
1866
1867 ZeroMemory(image_info, sizeof(VFD_IMAGE_INFO) + MAX_PATH);
1868
1869 // Query file information
1870
1871 if (!DeviceIoControl(
1872 hDevice,
1874 NULL,
1875 0,
1876 image_info,
1877 sizeof(VFD_IMAGE_INFO) + MAX_PATH,
1878 &result,
1879 NULL))
1880 {
1881 ret = GetLastError();
1882
1883 if (ret != ERROR_MORE_DATA) {
1884 VFDTRACE(0,
1885 (FUNC ": DeviceIoControl(IOCTL_VFD_QUERY_FILE) - %s",
1886 SystemMessage(ret)));
1887
1888 goto cleanup;
1889 }
1890 }
1891
1892 // copy obtained information to output buffer
1893
1894 if (sFileName) {
1895
1896 // if filename is too long, clip it
1897
1898 if (image_info->NameLength >= MAX_PATH) {
1899 image_info->NameLength = MAX_PATH - 1;
1900 }
1901
1902 // ensure the name is properly terminated
1903
1904 image_info->FileName[image_info->NameLength] = '\0';
1905
1906 if (strncmp(image_info->FileName, "\\??\\UNC", 7) == 0) {
1907 *sFileName = '\\';
1908 strcpy(sFileName + 1, image_info->FileName + 7);
1909 }
1910 else if (strncmp(image_info->FileName, "\\??\\", 4) == 0) {
1911 strcpy(sFileName, image_info->FileName + 4);
1912 }
1913 else {
1914 strcpy(sFileName, image_info->FileName);
1915 }
1916 }
1917
1918 if (pDiskType) {
1919 *pDiskType = image_info->DiskType;
1920 }
1921
1922 if (pMediaType) {
1923 *pMediaType = image_info->MediaType;
1924 }
1925
1926 if (pMediaFlags) {
1927 *pMediaFlags = image_info->MediaFlags;
1928 }
1929
1930 if (pFileType) {
1931 *pFileType = image_info->FileType;
1932 }
1933
1934 if (pImageSize) {
1935 *pImageSize = image_info->ImageSize;
1936 }
1937
1938cleanup:
1939 if (image_info) {
1940 LocalFree(image_info);
1941 }
1942
1943 return ret;
1944}
1945
1946//
1947// Get current media state (opened / write protected)
1948//
1950 HANDLE hDevice)
1951{
1952#undef FUNC
1953#define FUNC "VfdGetMediaState"
1954 DWORD result;
1956
1957 // Query file information
1958
1959 if (!DeviceIoControl(
1960 hDevice,
1962 NULL,
1963 0,
1964 NULL,
1965 0,
1966 &result,
1967 NULL))
1968 {
1969 ret = GetLastError();
1970
1971 if (ret != ERROR_NOT_READY) {
1972 VFDTRACE(0,
1973 (FUNC ": DeviceIoControl(IOCTL_DISK_IS_WRITABLE) - %s",
1974 SystemMessage(ret)));
1975 }
1976 }
1977
1978 return ret;
1979}
1980
1981//
1982// Set or Delete a global drive letter
1983//
1985 HANDLE hDevice,
1986 CHAR cLetter)
1987{
1988#undef FUNC
1989#define FUNC "VfdSetGlobalLink"
1990 CHAR letter;
1991 ULONG number;
1992 DWORD result;
1993 DWORD ret;
1994
1995 if (isalpha(cLetter)) {
1996
1997 // make sure the drive does not have a drive letter
1998
1999 letter = 0;
2000
2001 VfdGetGlobalLink(hDevice, &letter);
2002
2003 if (isalpha(letter)) {
2004 VFDTRACE(0,
2005 (FUNC ": Drive already has a drive letter %c\n", letter));
2007 }
2008
2009 VfdGetLocalLink(hDevice, &letter);
2010
2011 if (isalpha(letter)) {
2012 VFDTRACE(0,
2013 (FUNC ": Drive already has a drive letter %c\n", letter));
2015 }
2016
2017 // make sure drive letter is not in use
2018
2019 cLetter = (CHAR)toupper(cLetter);
2020
2021 if (GetLogicalDrives() & (1 << (cLetter - 'A'))) {
2022 VFDTRACE(0,
2023 (FUNC ": Drive letter %c already used\n", cLetter));
2025 }
2026
2027 // Assign a new drive letter
2028
2029 if (!DeviceIoControl(
2030 hDevice,
2032 &cLetter,
2033 sizeof(cLetter),
2034 NULL,
2035 0,
2036 &result,
2037 NULL))
2038 {
2039 ret = GetLastError();
2040
2041 VFDTRACE(0,
2042 (FUNC ": DeviceIoControl(IOCTL_VFD_SET_LINK) - %s",
2043 SystemMessage(ret)));
2044
2045 return ret;
2046 }
2047
2048 // broadcast system message
2049
2051
2052 // broadcast VFD message
2053
2054 if (VfdGetDeviceNumber(hDevice, &number) == ERROR_SUCCESS) {
2056 }
2057
2058 return ERROR_SUCCESS;
2059 }
2060 else if (!cLetter) {
2061
2062 // make sure the drive has a global drive letter
2063
2064 letter = 0;
2065
2066 VfdGetGlobalLink(hDevice, &letter);
2067
2068 if (!isalpha(letter)) {
2069 VFDTRACE(0,
2070 (FUNC ": Drive does not have a drive letter\n"));
2072 }
2073
2074 // Remove drive letters
2075
2076 if (!DeviceIoControl(
2077 hDevice,
2079 &cLetter,
2080 sizeof(cLetter),
2081 NULL,
2082 0,
2083 &result,
2084 NULL))
2085 {
2086 ret = GetLastError();
2087
2088 VFDTRACE(0,
2089 (FUNC ": DeviceIoControl(IOCTL_VFD_SET_LINK) - %s",
2090 SystemMessage(ret)));
2091
2092 return ret;
2093 }
2094
2095 // broadcast system message
2096
2098
2099 // broadcast VFD message
2100 if (VfdGetDeviceNumber(hDevice, &number) == ERROR_SUCCESS) {
2102 }
2103
2104 return ERROR_SUCCESS;
2105 }
2106 else {
2108 }
2109}
2110
2111//
2112// Get a global drive letter
2113//
2115 HANDLE hDevice,
2116 PCHAR pLetter)
2117{
2118#undef FUNC
2119#define FUNC "VfdGetGlobalLinks"
2120 DWORD result;
2121 DWORD ret;
2122
2123 if (!pLetter) {
2125 }
2126
2127 *pLetter = 0;
2128
2129 if (!DeviceIoControl(
2130 hDevice,
2132 NULL,
2133 0,
2134 pLetter,
2135 sizeof(*pLetter),
2136 &result,
2137 NULL))
2138 {
2139 ret = GetLastError();
2140
2141 VFDTRACE(0,
2142 (FUNC ": DeviceIoControl(IOCTL_VFD_QUERY_LINK) - %s",
2143 SystemMessage(ret)));
2144
2145 return ret;
2146 }
2147
2148 return ERROR_SUCCESS;
2149}
2150
2151//
2152// Set or remove a local drive letter
2153//
2155 HANDLE hDevice,
2156 CHAR cLetter)
2157{
2158#undef FUNC
2159#define FUNC "VfdSetLocalLink"
2160 CHAR letter;
2161 CHAR dos_name[] = "A:";
2163 ULONG number;
2164 DWORD ret;
2165
2166 if (isalpha(cLetter)) {
2167
2168 // make sure the drive does not have a drive letter
2169
2170 letter = 0;
2171
2172 VfdGetGlobalLink(hDevice, &letter);
2173
2174 if (isalpha(letter)) {
2175 VFDTRACE(0,
2176 (FUNC ": Drive already has a drive letter %c\n", letter));
2178 }
2179
2180 VfdGetLocalLink(hDevice, &letter);
2181
2182 if (isalpha(letter)) {
2183 VFDTRACE(0,
2184 (FUNC ": Drive already has a drive letter %c\n", letter));
2186 }
2187
2188 // make sure drive letters are not in use
2189
2190 cLetter = (CHAR)toupper(cLetter);
2191
2192 if (GetLogicalDrives() & (1 << (cLetter - 'A'))) {
2193 VFDTRACE(0,
2194 (FUNC ": Drive letter already used\n"));
2195
2197 }
2198
2199 // get VFD device name
2200
2201 ret = VfdGetDeviceName(hDevice, dev_name, sizeof(dev_name));
2202
2203 if (ret != ERROR_SUCCESS) {
2204 return ret;
2205 }
2206
2207 // assign a drive letter
2208
2209 dos_name[0] = cLetter;
2210
2211 if (!DefineDosDevice(DDD_RAW_TARGET_PATH, dos_name, dev_name)) {
2212 ret = GetLastError();
2213
2214 VFDTRACE(0,
2215 (FUNC ": DefineDosDevice(%s,%s) - %s",
2216 dos_name, dev_name, SystemMessage(ret)));
2217 }
2218
2219 if (ret == ERROR_SUCCESS) {
2220 // broadcast VFD message
2221
2222 if (VfdGetDeviceNumber(hDevice, &number) == ERROR_SUCCESS) {
2224 }
2225 }
2226
2227 return ret;
2228 }
2229 else if (!cLetter) {
2230
2231 // make sure the drive has a local drive letter
2232
2233 letter = 0;
2234
2235 VfdGetLocalLink(hDevice, &letter);
2236
2237 if (!isalpha(letter)) {
2238 VFDTRACE(0,
2239 (FUNC ": Drive letter is not assigned to this drive\n"));
2241 }
2242
2243 // get VFD device name
2244
2245 ret = VfdGetDeviceName(hDevice, dev_name, sizeof(dev_name));
2246
2247 if (ret != ERROR_SUCCESS) {
2248 return ret;
2249 }
2250
2251 // remove drive letters
2252#define DDD_FLAGS (DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE)
2253
2254 dos_name[0] = (CHAR)toupper(letter);
2255
2256 if (!DefineDosDevice(DDD_FLAGS, dos_name, dev_name)) {
2257 ret = GetLastError();
2258
2259 VFDTRACE(0,
2260 (FUNC ": DefineDosDevice(%s,%s) - %s",
2261 dos_name, dev_name, SystemMessage(ret)));
2262 }
2263
2264 if (ret == ERROR_SUCCESS) {
2265 // broadcast VFD message
2266 if (VfdGetDeviceNumber(hDevice, &number) == ERROR_SUCCESS) {
2268 }
2269 }
2270
2271 return ret;
2272 }
2273 else {
2275 }
2276}
2277
2278//
2279// Get local drive letters
2280//
2282 HANDLE hDevice,
2283 PCHAR pLetter)
2284{
2285#undef FUNC
2286#define FUNC "VfdGetLocalLinks"
2287 CHAR global;
2288 ULONG logical;
2289 CHAR dos_name[] = "A:";
2291 CHAR dos_target[MAX_PATH * 2];
2292 DWORD ret;
2293
2294 if (!pLetter) {
2296 }
2297
2298 // Get the VFD device name
2299
2300 ret = VfdGetDeviceName(hDevice, dev_name, sizeof(dev_name));
2301
2302 if (ret != ERROR_SUCCESS) {
2303 return ret;
2304 }
2305
2306 // Get global drive letter
2307
2308 ret = VfdGetGlobalLink(hDevice, &global);
2309
2310 if (ret != ERROR_SUCCESS) {
2311 return ret;
2312 }
2313
2314 // Get logical drives
2315
2316 logical = GetLogicalDrives();
2317
2318 // exclude the global drive letter
2319
2320 if (isalpha(global)) {
2321 logical &= ~(1 << (toupper(global) - 'A'));
2322 }
2323
2324 // start searching from the next drive letter
2325
2326 if (isalpha(*pLetter)) {
2327 dos_name[0] = (CHAR)(toupper(*pLetter) + 1);
2328 logical >>= (dos_name[0] - 'A');
2329 }
2330
2331 // Check dos device targets
2332
2333 *pLetter = '\0';
2334
2335 while (logical) {
2336 if (logical & 0x01) {
2337 if (QueryDosDevice(dos_name, dos_target, sizeof(dos_target))) {
2338 if (_stricmp(dos_target, dev_name) == 0) {
2339 *pLetter = dos_name[0];
2340 break;
2341 }
2342 }
2343 else {
2344 VFDTRACE(0,
2345 (FUNC ": QueryDosDevice(%s) - %s",
2346 dos_name, SystemMessage(GetLastError())));
2347 }
2348 }
2349 logical >>= 1;
2350 dos_name[0]++;
2351 }
2352
2353 return ERROR_SUCCESS;
2354}
2355
2356//
2357// Get the Virtual Floppy device number
2358//
2360 HANDLE hDevice,
2361 PULONG pNumber)
2362{
2363#undef FUNC
2364#define FUNC "VfdGetDeviceNumber"
2365 DWORD result;
2367
2368 if (!pNumber) {
2370 }
2371
2372 *pNumber = 0;
2373
2374 if (!DeviceIoControl(
2375 hDevice,
2377 NULL,
2378 0,
2379 pNumber,
2380 sizeof(ULONG),
2381 &result,
2382 NULL))
2383 {
2384 ret = GetLastError();
2385
2386 VFDTRACE(0,
2387 (FUNC ": DeviceIoControl(IOCTL_VFD_QUERY_NUMBER) - %s",
2388 SystemMessage(ret)));
2389 }
2390
2391 return ret;
2392}
2393
2394// Get the Virtual Floppy device name
2395
2397 HANDLE hDevice,
2398 PCHAR pName,
2399 ULONG nLength)
2400{
2401#undef FUNC
2402#define FUNC "VfdGetDeviceName"
2403 DWORD result;
2404 WCHAR wname[MAX_PATH];
2406
2407 if (!pName || !nLength) {
2409 }
2410
2412
2413 if (!DeviceIoControl(
2414 hDevice,
2416 NULL,
2417 0,
2418 wname,
2419 sizeof(wname),
2420 &result,
2421 NULL))
2422 {
2423 ret = GetLastError();
2424
2425 VFDTRACE(0,
2426 (FUNC ": DeviceIoControl(IOCTL_VFD_QUERY_NUMBER) - %s",
2427 SystemMessage(ret)));
2428 }
2429
2430 if (!WideCharToMultiByte(CP_OEMCP, 0, &wname[1],
2431 wname[0] / sizeof(WCHAR), pName, nLength, NULL, NULL)) {
2432
2433 ret = GetLastError();
2434
2435 VFDTRACE(0,
2436 (FUNC ": WideCharToMultiByte - %s",
2437 SystemMessage(ret)));
2438 }
2439
2440 return ret;
2441}
2442
2443//
2444// Get Virtual Floppy driver version
2445//
2447 HANDLE hDevice,
2448 PULONG pVersion)
2449{
2450#undef FUNC
2451#define FUNC "VfdGetDriverVersion"
2452 DWORD result;
2454
2455 if (!pVersion) {
2457 }
2458
2459 *pVersion = '\0';
2460
2461 if (!DeviceIoControl(
2462 hDevice,
2464 NULL,
2465 0,
2466 pVersion,
2467 sizeof(ULONG),
2468 &result,
2469 NULL))
2470 {
2471 ret = GetLastError();
2472
2473 VFDTRACE(0,
2474 (FUNC ": DeviceIoControl(IOCTL_VFD_QUERY_VERSION) - %s",
2475 SystemMessage(ret)));
2476 }
2477
2478 return ret;
2479}
2480
2481//
2482// Change the write protect state of the media
2483//
2485 HANDLE hDevice,
2486 BOOL bProtect)
2487{
2488#undef FUNC
2489#define FUNC "VfdWriteProtect"
2490 DWORD result;
2492
2493 if (!DeviceIoControl(
2494 hDevice,
2496 NULL,
2497 0,
2498 NULL,
2499 0,
2500 &result,
2501 NULL))
2502 {
2503 ret = GetLastError();
2504
2505 VFDTRACE(0,
2506 (FUNC ": DeviceIoControl(IOCTL_VFD_SET_PROTECT) - %s",
2507 SystemMessage(ret)));
2508 }
2509
2510 if (ret == ERROR_SUCCESS) {
2511 ULONG number;
2512
2513 if (VfdGetDeviceNumber(hDevice, &number) == ERROR_SUCCESS) {
2515 }
2516 }
2517
2518 return ret;
2519}
2520
2521// Format the current media with FAT12
2522
2524 HANDLE hDevice)
2525{
2526#undef FUNC
2527#define FUNC "VfdFormatMedia"
2528 DWORD result;
2530 PUCHAR buf = NULL;
2532
2533 // Get the media size
2534
2535 if (!DeviceIoControl(
2536 hDevice,
2538 NULL,
2539 0,
2540 &length,
2541 sizeof(length),
2542 &result,
2543 NULL))
2544 {
2545 ret = GetLastError();
2546
2547 VFDTRACE(0,
2548 (FUNC ": DeviceIoControl(IOCTL_DISK_GET_LENGTH_INFO) - %s",
2549 SystemMessage(ret)));
2550
2551 goto exit_func;
2552 }
2553
2554 // Prepare a formatted image buffer
2555
2556 buf = (PUCHAR)LocalAlloc(LPTR, length.Length.LowPart);
2557
2558 if (buf == NULL) {
2559 ret = GetLastError();
2560
2561 VFDTRACE(0,
2562 (FUNC ": LocalAlloc - %s",
2563 SystemMessage(ret)));
2564
2565 goto exit_func;
2566 }
2567
2568 // format the buffer
2569
2571 VFD_BYTE_TO_SECTOR(length.Length.LowPart));
2572
2573 if (ret != ERROR_SUCCESS) {
2574 goto exit_func;
2575 }
2576
2577 // seek the top of the media
2578
2579 if (SetFilePointer(hDevice, 0, NULL, FILE_BEGIN) != 0) {
2580 ret = GetLastError();
2581
2582 VFDTRACE(0,
2583 (FUNC ": SetFilePointer - %s",
2584 SystemMessage(ret)));
2585
2586 goto exit_func;
2587 }
2588
2589 // write the image into the media
2590
2591 if (!WriteFile(hDevice, buf, length.Length.LowPart, &result, NULL) ||
2592 result != length.Length.LowPart) {
2593 ret = GetLastError();
2594
2595 VFDTRACE(0,
2596 (FUNC ": WriteFile - %s",
2597 SystemMessage(ret)));
2598
2599 goto exit_func;
2600 }
2601
2602exit_func:
2603 // unlock the target volume
2604 if (!DeviceIoControl(
2605 hDevice,
2607 NULL,
2608 0,
2609 NULL,
2610 0,
2611 &result,
2612 NULL))
2613 {
2614 VFDTRACE(0,
2615 (FUNC ": DeviceIoControl(FSCTL_UNLOCK_VOLUME) - %s",
2617 }
2618
2619 // release the format image buffer
2620 if (buf) {
2621 LocalFree(buf);
2622 }
2623
2624 return ret;
2625}
2626
2627// Dismount the volume (should be called before Save, Format)
2628
2630 HANDLE hDevice,
2631 BOOL bForce)
2632{
2633#undef FUNC
2634#define FUNC "VfdDismountVolume"
2635 DWORD result;
2637
2638 // Lock the target volume
2639
2640 if (!DeviceIoControl(
2641 hDevice,
2643 NULL,
2644 0,
2645 NULL,
2646 0,
2647 &result,
2648 NULL))
2649 {
2650 ret = GetLastError();
2651
2652 VFDTRACE(0,
2653 (FUNC ": DeviceIoControl(FSCTL_LOCK_VOLUME) - %s",
2654 SystemMessage(ret)));
2655
2656 if (ret != ERROR_ACCESS_DENIED || !bForce) {
2657 return ret;
2658 }
2659 }
2660
2661 // Dismount the target volume
2662
2663 if (!DeviceIoControl(
2664 hDevice,
2666 NULL,
2667 0,
2668 NULL,
2669 0,
2670 &result,
2671 NULL))
2672 {
2673 ret = GetLastError();
2674
2675 VFDTRACE(0,
2676 (FUNC ": DeviceIoControl(FSCTL_DISMOUNT_VOLUME) - %s",
2677 SystemMessage(ret)));
2678 }
2679
2680 return ret;
2681}
2682
2683// Save the current image into a file
2684
2686 HANDLE hDevice,
2687 PCSTR sFileName,
2688 BOOL bOverWrite,
2689 BOOL bTruncate)
2690{
2691#undef FUNC
2692#define FUNC "VfdSaveImage"
2694 DWORD result;
2696 PUCHAR buf = NULL;
2698
2699
2701
2702 // Get the media size
2703
2704 if (!DeviceIoControl(
2705 hDevice,
2707 NULL,
2708 0,
2709 &length,
2710 sizeof(length),
2711 &result,
2712 NULL))
2713 {
2714 ret = GetLastError();
2715
2716 VFDTRACE(0,
2717 (FUNC ": DeviceIoControl(IOCTL_DISK_GET_LENGTH_INFO) - %s",
2718 SystemMessage(ret)));
2719
2720 goto exit_func;
2721 }
2722
2723 // Prepare an intermediate image buffer
2724
2725 buf = (PUCHAR)LocalAlloc(LPTR, length.Length.LowPart);
2726
2727 if (buf == NULL) {
2728 ret = GetLastError();
2729
2730 VFDTRACE(0,
2731 (FUNC ": LocalAlloc - %s",
2732 SystemMessage(ret)));
2733
2734 goto exit_func;
2735 }
2736
2737 // seek the top of the media
2738
2739 if (SetFilePointer(hDevice, 0, NULL, FILE_BEGIN) != 0) {
2740 ret = GetLastError();
2741
2742 VFDTRACE(0,
2743 (FUNC ": SetFilePointer - %s",
2744 SystemMessage(ret)));
2745
2746 goto exit_func;
2747 }
2748
2749 // read the image data
2750
2751 if (!ReadFile(hDevice, buf, length.Length.LowPart, &result, NULL) ||
2752 result != length.Length.LowPart) {
2753 ret = GetLastError();
2754
2755 VFDTRACE(0,
2756 (FUNC ": ReadFile - %s",
2757 SystemMessage(ret)));
2758
2759 goto exit_func;
2760 }
2761
2762 // open the destination file
2763
2764 hFile = CreateFile(sFileName, GENERIC_WRITE, 0, NULL,
2765 bOverWrite ? OPEN_ALWAYS : CREATE_NEW, 0, NULL);
2766
2767 if (hFile == INVALID_HANDLE_VALUE) {
2768 ret = GetLastError();
2769
2770 VFDTRACE(0,
2771 (FUNC ": CreateFile - %s",
2772 SystemMessage(ret)));
2773
2774 goto exit_func;
2775 }
2776
2777 // seek the top of the file
2778
2779 if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) != 0) {
2780 ret = GetLastError();
2781
2782 VFDTRACE(0,
2783 (FUNC ": SetFilePointer - %s",
2784 SystemMessage(ret)));
2785
2786 goto exit_func;
2787 }
2788
2789 // write the image data
2790
2791 if (!WriteFile(hFile, buf, length.Length.LowPart, &result, NULL) ||
2792 result != length.Length.LowPart) {
2793 ret = GetLastError();
2794
2795 VFDTRACE(0,
2796 (FUNC ": WriteFile - %s",
2797 SystemMessage(ret)));
2798
2799 goto exit_func;
2800 }
2801
2802 // truncate the target file
2803
2804 if (bTruncate && !SetEndOfFile(hFile)) {
2805 ret = GetLastError();
2806
2807 VFDTRACE(0,
2808 (FUNC ": SetEndOfFile - %s",
2809 SystemMessage(ret)));
2810
2811 goto exit_func;
2812 }
2813
2814 // reset the media modified flag
2815
2816 if (!DeviceIoControl(
2817 hDevice,
2819 NULL,
2820 0,
2821 NULL,
2822 0,
2823 &result,
2824 NULL))
2825 {
2826 VFDTRACE(0,
2827 (FUNC ": DeviceIoControl(IOCTL_VFD_RESET_MODIFY) - %s",
2829 }
2830
2831exit_func:
2832 // unlock the target volume
2833
2834 if (!DeviceIoControl(
2835 hDevice,
2837 NULL,
2838 0,
2839 NULL,
2840 0,
2841 &result,
2842 NULL))
2843 {
2844 VFDTRACE(0,
2845 (FUNC ": DeviceIoControl(FSCTL_UNLOCK_VOLUME) - %s",
2847 }
2848
2849 // release the format image buffer
2850
2851 if (buf) {
2852 LocalFree(buf);
2853 }
2854
2855 // close the image file
2856
2857 if (hFile != INVALID_HANDLE_VALUE) {
2859 }
2860
2861 return ret;
2862}
2863
2864//
2865// Check if specified file is valid VFD driver
2866//
2868 PCSTR sFileName,
2869 PULONG pFileVersion)
2870{
2871#undef FUNC
2872#define FUNC "VfdCheckDriverFile"
2873 DWORD result;
2874 DWORD dummy;
2875 PVOID info;
2876 VS_FIXEDFILEINFO *fixedinfo;
2878 PSTR str;
2879
2880 // Check parameter
2881
2882 if (!sFileName || !*sFileName) {
2884 }
2885
2886 if (pFileVersion) {
2887 *pFileVersion = 0;
2888 }
2889
2890 // check file existence
2891
2892 if (GetFileAttributes(sFileName) == INVALID_FILE_ATTRIBUTES) {
2893 ret = GetLastError();
2894
2895 VFDTRACE(0,
2896 (FUNC ": GetFileAttributes - %s\n",
2897 SystemMessage(ret)));
2898
2899 return ret;
2900 }
2901
2902 // check file version
2903
2904 result = GetFileVersionInfoSize((PSTR)sFileName, &dummy);
2905
2906 if (result == 0) {
2907 VFDTRACE(0,
2908 (FUNC ": GetFileVersionInfoSize == 0\n"));
2909
2910 return ERROR_BAD_DRIVER;
2911 }
2912
2914
2915 if (info == NULL) {
2916 ret = GetLastError();
2917
2918 VFDTRACE(0,
2919 (FUNC ": LocalAlloc(%lu) - %s\n",
2921
2922 return ret;
2923 }
2924
2925 if (!GetFileVersionInfo((PSTR)sFileName, 0, result, info)) {
2926 ret = GetLastError();
2927
2928 VFDTRACE(0,
2929 (FUNC ": GetFileVersionInfo - %s", SystemMessage(ret)));
2930
2931 goto cleanup;
2932 }
2933
2934 result = sizeof(fixedinfo);
2935
2936 if (!VerQueryValue(info, "\\", (PVOID *)&fixedinfo, (PUINT)&result)) {
2937 ret = GetLastError();
2938
2939 VFDTRACE(0,
2940 (FUNC ": VerQueryValue(\"\\\") - %s", SystemMessage(ret)));
2941
2942 goto cleanup;
2943 }
2944
2945 if (fixedinfo->dwFileOS != VOS_NT_WINDOWS32 ||
2946 fixedinfo->dwFileType != VFT_DRV ||
2947 fixedinfo->dwFileSubtype != VFT2_DRV_SYSTEM) {
2948
2949 VFDTRACE(0,
2950 (FUNC ": Invalid file type flags\n"));
2951
2953
2954 goto cleanup;
2955 }
2956
2957 if (pFileVersion) {
2958 *pFileVersion = fixedinfo->dwFileVersionMS;
2959
2960 if (fixedinfo->dwFileFlags & VS_FF_DEBUG) {
2961 *pFileVersion |= 0x80000000;
2962 }
2963 }
2964
2965 if (!VerQueryValue(info,
2966 "\\StringFileInfo\\" VFD_VERSIONINFO_LANG "\\OriginalFileName",
2967 (PVOID *)&str, (PUINT)&result)) {
2968 ret = GetLastError();
2969
2970 VFDTRACE(0,
2971 (FUNC ": VerQueryValue(\"OriginalFileName\") - %s",
2972 SystemMessage(ret)));
2973
2974 goto cleanup;
2975 }
2976
2978 VFDTRACE(0,
2979 (FUNC ": Invalid original file name\n"));
2980
2982
2983 goto cleanup;
2984 }
2985
2988
2989 VFDTRACE(0,
2990 (FUNC ": Invalid version values - file:%08x, prod: %08x\n",
2991 fixedinfo->dwFileVersionMS, fixedinfo->dwProductVersionMS));
2992
2994
2995 goto cleanup;
2996 }
2997
2998 // Ensure that the driver binary is located on a local drive
2999 // because device driver cannot be started on network drives.
3000
3001 if (*sFileName == '\\' && *(sFileName + 1) == '\\') {
3002 // full path is a UNC path -- \\server\dir\...
3003
3004 VFDTRACE(0,
3005 (FUNC ": Driver is located on a network drive\n"));
3006
3008 }
3009 else {
3010 // ensure that the drive letter is not a network drive
3011
3012 CHAR root[] = " :\\";
3013
3014 root[0] = *sFileName;
3015
3016 if (GetDriveType(root) == DRIVE_REMOTE) {
3017 // the drive is a network drive
3018
3019 VFDTRACE(0,
3020 (FUNC ": Driver is located on a network drive\n"));
3021
3023 }
3024 }
3025
3026cleanup:
3027 LocalFree(info);
3028
3029 return ret;
3030}
3031
3032//
3033// check an image file
3034//
3036 PCSTR sFileName,
3037 PDWORD pAttributes,
3038 PVFD_FILETYPE pFileType,
3039 PULONG pImageSize)
3040{
3041#undef FUNC
3042#define FUNC "VfdCheckImageFile"
3043 HANDLE hFile;
3045
3046 if (!sFileName || !*sFileName || !pAttributes || !pImageSize || !pFileType) {
3048 }
3049
3050 // get file attributes
3051
3052 *pAttributes = GetFileAttributes(sFileName);
3053
3054 if (*pAttributes == INVALID_FILE_ATTRIBUTES) {
3055 ret = GetLastError();
3056
3057 if (ret != ERROR_FILE_NOT_FOUND) {
3058 VFDTRACE(0,
3059 (FUNC ": GetFileAttributes(%s) - %s\n",
3060 sFileName, SystemMessage(ret)));
3061 }
3062
3063 return ret;
3064 }
3065
3066 // Open the target file
3067
3069 0, NULL, OPEN_EXISTING, 0, NULL);
3070
3071 if (hFile == INVALID_HANDLE_VALUE) {
3072
3073 // failed to open
3074
3075 ret = GetLastError();
3076
3077 if (ret != ERROR_ACCESS_DENIED) {
3078 VFDTRACE(0,
3079 (FUNC ": CreateFile(%s) - %s\n",
3080 sFileName, SystemMessage(ret)));
3081
3082 return ret;
3083 }
3084
3085 // try opening it read-only
3086
3087 hFile = CreateFile(sFileName, GENERIC_READ,
3089
3090 if (hFile == INVALID_HANDLE_VALUE) {
3091
3092 // cannot open even read-only
3093
3094 ret = GetLastError();
3095
3096 VFDTRACE(0,
3097 (FUNC ": CreateFile(%s) - %s\n",
3098 sFileName, SystemMessage(ret)));
3099
3100 return ret;
3101 }
3102
3103 // file can be opened read-only
3104 *pAttributes |= FILE_ATTRIBUTE_READONLY;
3106 }
3107
3108 // check if the image is an IMZ file
3109
3110 if (ExtractZipInfo(hFile, pImageSize) == ERROR_SUCCESS) {
3111 *pFileType = VFD_FILETYPE_ZIP;
3112 }
3113 else {
3114 *pImageSize = GetFileSize(hFile, NULL);
3115 *pFileType = VFD_FILETYPE_RAW;
3116 }
3117
3119
3120 return ret;
3121}
3122
3123//
3124// Create a formatted new image file
3125//
3127 PCSTR sFileName,
3128 VFD_MEDIA nMediaType,
3129 VFD_FILETYPE nFileType,
3130 BOOL bOverWrite)
3131{
3132#undef FUNC
3133#define FUNC "VfdCreateImageFile"
3134 HANDLE hFile;
3136 PUCHAR image_buf = NULL;
3137 DWORD result;
3139
3140 if (nFileType != VFD_FILETYPE_RAW) {
3142 }
3143
3144 file_size = VfdGetMediaSize(nMediaType);
3145
3146 if (file_size == 0) {
3148 }
3149
3150 hFile = CreateFile(sFileName, GENERIC_WRITE, 0, NULL,
3151 bOverWrite ? CREATE_ALWAYS : CREATE_NEW, 0, NULL);
3152
3153 if (hFile == INVALID_HANDLE_VALUE) {
3154 ret = GetLastError();
3155
3156 VFDTRACE(0,
3157 (FUNC ": CreateFile - %s",
3158 SystemMessage(ret)));
3159
3160 return ret;
3161 }
3162
3163 image_buf = (PUCHAR)LocalAlloc(LPTR, file_size);
3164
3165 if (image_buf == NULL) {
3166 ret = GetLastError();
3167
3168 VFDTRACE(0,
3169 (FUNC ": LocalAlloc - %s",
3170 SystemMessage(ret)));
3171
3172 goto exit_func;
3173 }
3174
3176
3177 if (!WriteFile(hFile, image_buf, file_size, &result, NULL) ||
3178 file_size != result) {
3179
3180 ret = GetLastError();
3181
3182 VFDTRACE(0,
3183 (FUNC ": WriteFile - %s",
3184 SystemMessage(ret)));
3185
3186 goto exit_func;
3187 }
3188
3190
3191exit_func:
3193
3194 if (image_buf) {
3195 LocalFree(image_buf);
3196 }
3197
3198 return ret;
3199}
3200
3201
3202//
3203// choose first available drive letter
3204//
3206{
3207 DWORD logical_drives = GetLogicalDrives();
3208 CHAR drive_letter = 'A';
3209
3210 if (logical_drives == 0) {
3211 return '\0';
3212 }
3213
3214 while (logical_drives & 0x1) {
3215 logical_drives >>= 1;
3216 drive_letter++;
3217 }
3218
3219 if (drive_letter > 'Z') {
3220 return '\0';
3221 }
3222
3223 return drive_letter;
3224}
3225
3226//
3227// media type functions
3228//
3229static const struct
3230{
3233}
3235{
3236 { 0, "" }, // VFD_MEDIA_NONE,
3237 { VFD_SECTOR_TO_BYTE(320), "5.25\" 160KB" }, // VFD_MEDIA_F5_160
3238 { VFD_SECTOR_TO_BYTE(360), "5.25\" 180KB" }, // VFD_MEDIA_F5_180
3239 { VFD_SECTOR_TO_BYTE(640), "5.25\" 320KB" }, // VFD_MEDIA_F5_320
3240 { VFD_SECTOR_TO_BYTE(720), "5.25\" 360KB" }, // VFD_MEDIA_F5_360
3241 { VFD_SECTOR_TO_BYTE(1280), "3.5\" 640KB" }, // VFD_MEDIA_F3_640
3242 { VFD_SECTOR_TO_BYTE(1280), "5.25\" 640KB" }, // VFD_MEDIA_F5_640
3243 { VFD_SECTOR_TO_BYTE(1440), "3.5\" 720KB" }, // VFD_MEDIA_F3_720
3244 { VFD_SECTOR_TO_BYTE(1440), "5.25\" 720KB" }, // VFD_MEDIA_F5_720
3245 { VFD_SECTOR_TO_BYTE(1640), "3.5\" 820KB" }, // VFD_MEDIA_F3_820
3246 { VFD_SECTOR_TO_BYTE(2400), "3.5\" 1.2MB" }, // VFD_MEDIA_F3_1P2
3247 { VFD_SECTOR_TO_BYTE(2400), "5.25\" 1.2MB" }, // VFD_MEDIA_F5_1P2
3248 { VFD_SECTOR_TO_BYTE(2880), "3.5\" 1.44MB" }, // VFD_MEDIA_F3_1P4
3249 { VFD_SECTOR_TO_BYTE(3360), "3.5\" 1.68MB DMF" }, // VFD_MEDIA_F3_1P6
3250 { VFD_SECTOR_TO_BYTE(3444), "3.5\" 1.72MB DMF" }, // VFD_MEDIA_F3_1P7
3251 { VFD_SECTOR_TO_BYTE(5760), "3.5\" 2.88MB"} // VFD_MEDIA_F3_2P8
3253
3254// Lookup the largest media to fit in a size
3255
3257 ULONG nSize)
3258{
3259 VFD_MEDIA i;
3260
3261 for (i = 1; i < VFD_MEDIA_MAX; i++) {
3262 if (nSize < media_tbl[i].Size) {
3263 break;
3264 }
3265 }
3266
3267 return (--i);
3268}
3269
3270// Get media size (in bytes) of a media type
3271
3273 VFD_MEDIA nMediaType)
3274{
3275 return nMediaType < VFD_MEDIA_MAX ? media_tbl[nMediaType].Size : 0;
3276}
3277
3278// Get media type name
3279
3281 VFD_MEDIA nMediaType)
3282{
3283 return nMediaType < VFD_MEDIA_MAX ? media_tbl[nMediaType].Name : NULL;
3284}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
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
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
#define stat
Definition: acwin.h:99
#define CHAR(Char)
#define _stricmp
Definition: cat.c:22
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define DBT_DEVTYP_VOLUME
Definition: dbt.h:21
#define BSF_NOTIMEOUTIFNOTHUNG
Definition: dbt.h:57
#define BSF_NOHANG
Definition: dbt.h:56
#define BSM_APPLICATIONS
Definition: dbt.h:48
#define BSF_FORCEIFHUNG
Definition: dbt.h:54
#define DBT_DEVICEARRIVAL
Definition: dbt.h:12
#define DBT_DEVICEREMOVECOMPLETE
Definition: dbt.h:16
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define FILE_BEGIN
Definition: compat.h:761
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define WideCharToMultiByte
Definition: compat.h:111
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
static const WCHAR version[]
Definition: asmname.c:66
static void cleanup(void)
Definition: main.c:1335
UINT WINAPI SetErrorMode(IN UINT uMode)
Definition: except.c:751
BOOL WINAPI GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
Definition: fileinfo.c:458
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
int global
Definition: ehframes.cpp:22
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
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 LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
#define CREATE_ALWAYS
Definition: disk.h:72
#define FILE_FLAG_NO_BUFFERING
Definition: disk.h:45
#define CREATE_NEW
Definition: disk.h:69
#define OPEN_ALWAYS
Definition: disk.h:70
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static LPSTR pName
Definition: security.c:75
static unsigned int number
Definition: dsound.c:1479
static LPCWSTR file_name
Definition: protocol.c:147
const char * dev_name(int device)
Definition: wave.c:211
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FILE_ATTRIBUTE_COMPRESSED
Definition: nt_native.h:711
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DELETE
Definition: nt_native.h:57
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_ATTRIBUTE_ENCRYPTED
Definition: ntifs_ex.h:385
DWORD * PDWORD
Definition: pedump.c:68
unsigned short USHORT
Definition: pedump.c:61
static unsigned int file_size
Definition: regtests2xml.c:47
const WCHAR * str
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2845
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:622
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
#define S(x)
Definition: test.h:217
FD_TYPE file_type(FDSC **curr, char *fixed)
Definition: file.c:221
#define SHCNE_MEDIAINSERTED
Definition: shlobj.h:1880
#define SHCNE_MEDIAREMOVED
Definition: shlobj.h:1881
#define SHCNF_PATH
Definition: shlobj.h:1917
TCHAR file_path[MAX_PATH]
Definition: sndrec32.cpp:57
LARGE_INTEGER Length
Definition: imports.h:232
VFD_FLAGS MediaFlags
Definition: vfdio.h:66
VFD_FILETYPE FileType
Definition: vfdio.h:67
CHAR FileName[0]
Definition: vfdio.h:70
VFD_DISKTYPE DiskType
Definition: vfdio.h:64
ULONG ImageSize
Definition: vfdio.h:68
USHORT NameLength
Definition: vfdio.h:69
VFD_MEDIA MediaType
Definition: vfdio.h:65
Definition: stat.h:55
Definition: ps.c:97
DWORD dwFileVersionMS
Definition: compat.h:902
DWORD dwProductVersionMS
Definition: compat.h:904
DWORD dwFileSubtype
Definition: compat.h:910
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
const char * PCSTR
Definition: typedefs.h:52
#define MAKELONG(a, b)
Definition: typedefs.h:249
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define VOS_NT_WINDOWS32
Definition: verrsrc.h:71
#define VFT2_DRV_SYSTEM
Definition: verrsrc.h:91
#define VFT_DRV
Definition: verrsrc.h:77
#define VS_FF_DEBUG
Definition: verrsrc.h:42
#define VFD_NOT_INSTALLED
Definition: vfdapi.h:20
@ VFD_OPERATION_PROTECT
Definition: vfdapi.h:37
@ VFD_OPERATION_CONFIG
Definition: vfdapi.h:28
@ VFD_OPERATION_OPEN
Definition: vfdapi.h:32
@ VFD_OPERATION_DELLINK
Definition: vfdapi.h:36
@ VFD_OPERATION_SETLINK
Definition: vfdapi.h:35
@ VFD_OPERATION_INSTALL
Definition: vfdapi.h:27
@ VFD_OPERATION_REMOVE
Definition: vfdapi.h:29
@ VFD_OPERATION_START
Definition: vfdapi.h:30
@ VFD_OPERATION_CLOSE
Definition: vfdapi.h:34
@ VFD_OPERATION_STOP
Definition: vfdapi.h:31
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
struct _GET_LENGTH_INFORMATION * PGET_LENGTH_INFORMATION
VFD_MEDIA WINAPI VfdLookupMedia(ULONG nSize)
Definition: vfdctl.c:3256
ULONG WINAPI VfdGetMediaSize(VFD_MEDIA nMediaType)
Definition: vfdctl.c:3272
DWORD WINAPI VfdSetLocalLink(HANDLE hDevice, CHAR cLetter)
Definition: vfdctl.c:2154
DWORD WINAPI VfdGetDeviceName(HANDLE hDevice, PCHAR pName, ULONG nLength)
Definition: vfdctl.c:2396
ULONG Size
Definition: vfdctl.c:3231
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
DWORD WINAPI VfdFormatMedia(HANDLE hDevice)
Definition: vfdctl.c:2523
#define VFD_INSTALL_DIRECTORY
Definition: vfdctl.c:56
DWORD WINAPI VfdWriteProtect(HANDLE hDevice, BOOL bProtect)
Definition: vfdctl.c:2484
#define VFD_VOLUME_TEMPLATE
Definition: vfdctl.c:54
DWORD WINAPI VfdStopDriver(PDWORD pState)
Definition: vfdctl.c:801
#define VFD_LINK_CREATED
Definition: vfdctl.c:74
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: vfdctl.c:37
DWORD WINAPI VfdSaveImage(HANDLE hDevice, PCSTR sFileName, BOOL bOverWrite, BOOL bTruncate)
Definition: vfdctl.c:2685
static void VfdBroadcastLink(CHAR cLetter, BOOL bRemoved)
Definition: vfdctl.c:77
static __inline void VfdNotify(WPARAM wParam, LPARAM lParam)
Definition: vfdctl.c:120
DWORD WINAPI VfdGetDriverState(PDWORD pState)
Definition: vfdctl.c:1121
#define VFD_LINK_REMOVED
Definition: vfdctl.c:75
#define FUNC
DWORD WINAPI VfdRemoveDriver()
Definition: vfdctl.c:557
CHAR WINAPI VfdChooseLetter()
Definition: vfdctl.c:3205
DWORD WINAPI VfdGetGlobalLink(HANDLE hDevice, PCHAR pLetter)
Definition: vfdctl.c:2114
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 VfdCloseImage(HANDLE hDevice, BOOL bForce)
Definition: vfdctl.c:1702
DWORD WINAPI VfdInstallDriver(PCSTR sFileName, DWORD nStart)
Definition: vfdctl.c:241
HANDLE WINAPI VfdOpenDevice(ULONG nTarget)
Definition: vfdctl.c:1215
#define VFD_DEVICE_TEMPLATE
Definition: vfdctl.c:50
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
static const struct @1560 media_tbl[VFD_MEDIA_MAX]
DWORD WINAPI VfdOpenImage(HANDLE hDevice, PCSTR sFileName, VFD_DISKTYPE nDiskType, VFD_MEDIA nMediaType, VFD_FLAGS nMediaFlags)
Definition: vfdctl.c:1301
PCSTR Name
Definition: vfdctl.c:3232
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
#define DDD_FLAGS
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
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
DWORD FormatBufferFat(PUCHAR pBuffer, ULONG nSectors)
Definition: vfdfat.c:116
#define IOCTL_VFD_RESET_MODIFY
Definition: vfdio.h:299
#define VFD_BYTE_TO_SECTOR(b)
Definition: vfdio.h:44
#define IOCTL_VFD_QUERY_IMAGE
Definition: vfdio.h:163
#define IOCTL_VFD_SET_LINK
Definition: vfdio.h:194
#define IOCTL_VFD_CLOSE_IMAGE
Definition: vfdio.h:133
#define IOCTL_VFD_SET_PROTECT
Definition: vfdio.h:247
#define IOCTL_VFD_QUERY_LINK
Definition: vfdio.h:221
#define IOCTL_VFD_QUERY_VERSION
Definition: vfdio.h:387
struct _VFD_IMAGE_INFO * PVFD_IMAGE_INFO
#define VFD_DEVICE_BASENAME
Definition: vfdio.h:35
#define IOCTL_VFD_CLEAR_PROTECT
Definition: vfdio.h:273
#define IOCTL_VFD_QUERY_NAME
Definition: vfdio.h:358
#define IOCTL_VFD_QUERY_NUMBER
Definition: vfdio.h:325
#define VFD_SECTOR_TO_BYTE(s)
Definition: vfdio.h:45
#define IOCTL_VFD_OPEN_IMAGE
Definition: vfdio.h:107
HINSTANCE g_hDllModule
PCSTR SystemMessage(DWORD nError)
Definition: vfdlib.c:147
UINT g_nNotifyMsg
DWORD ExtractZipImage(HANDLE hFile, PUCHAR *pBuffer, PULONG pLength)
Definition: vfdzip.c:182
DWORD ExtractZipInfo(HANDLE hFile, ULONG *pSize)
Definition: vfdzip.c:133
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_NONE
Definition: vfdtypes.h:27
@ VFD_MEDIA_MAX
Definition: vfdtypes.h:43
@ VFD_DISKTYPE_FILE
Definition: vfdtypes.h:18
@ VFD_DISKTYPE_RAM
Definition: vfdtypes.h:19
UCHAR * PVFD_FILETYPE
Definition: vfdtypes.h:62
UCHAR * PVFD_FLAGS
Definition: vfdtypes.h:63
@ VFD_FILETYPE_NONE
Definition: vfdtypes.h:51
@ VFD_FILETYPE_RAW
Definition: vfdtypes.h:52
@ VFD_FILETYPE_ZIP
Definition: vfdtypes.h:53
UCHAR * PVFD_DISKTYPE
Definition: vfdtypes.h:60
#define VFD_FLAG_WRITE_PROTECTED
Definition: vfdtypes.h:68
UCHAR VFD_FLAGS
Definition: vfdtypes.h:63
UCHAR * PVFD_MEDIA
Definition: vfdtypes.h:61
#define VFD_DRIVER_MINOR
Definition: vfdver.h:21
#define VFD_VERSIONINFO_LANG
Definition: vfdver.h:33
#define VFD_DRIVER_MAJOR
Definition: vfdver.h:20
#define VFD_DRIVER_FILENAME
Definition: vfdver.h:19
#define VFD_PRODUCT_MAJOR
Definition: vfdver.h:15
#define VFD_PRODUCT_MINOR
Definition: vfdver.h:16
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define GetWindowsDirectory
Definition: winbase.h:3857
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GetDriveType
Definition: winbase.h:3812
#define DDD_RAW_TARGET_PATH
Definition: winbase.h:523
#define GetFileAttributes
Definition: winbase.h:3815
#define DRIVE_REMOTE
Definition: winbase.h:253
#define LPTR
Definition: winbase.h:381
DWORD WINAPI GetLogicalDrives(void)
Definition: disk.c:110
#define INVALID_FILE_SIZE
Definition: winbase.h:548
#define DeleteFile
Definition: winbase.h:3764
#define DefineDosDevice
Definition: winbase.h:3763
#define FindResource
Definition: winbase.h:3793
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2084
#define CreateFile
Definition: winbase.h:3749
#define QueryDosDevice
Definition: winbase.h:3892
#define GetModuleFileName
Definition: winbase.h:3831
#define GetFullPathName
Definition: winbase.h:3821
_In_ DWORD nLength
Definition: wincon.h:473
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
HICON HCURSOR
Definition: windef.h:299
#define WINAPI
Definition: msvc.h:6
#define ERROR_ALREADY_ASSIGNED
Definition: winerror.h:169
#define ERROR_BAD_ENVIRONMENT
Definition: winerror.h:113
#define ERROR_BAD_DRIVER
Definition: winerror.h:1180
#define ERROR_SERVICE_NOT_ACTIVE
Definition: winerror.h:613
#define ERROR_NOT_READY
Definition: winerror.h:124
#define ERROR_FILE_ENCRYPTED
Definition: winerror.h:1400
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
#define ERROR_NETWORK_ACCESS_DENIED
Definition: winerror.h:157
#define ERROR_REVISION_MISMATCH
Definition: winerror.h:788
#define CP_OEMCP
Definition: winnls.h:231
#define SERVICE_START
Definition: winsvc.h:57
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define QueryServiceConfig
Definition: winsvc.h:580
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
#define OpenSCManager
Definition: winsvc.h:575
#define SERVICE_ALL_ACCESS
Definition: winsvc.h:62
#define CreateService
Definition: winsvc.h:569
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SERVICE_NO_CHANGE
Definition: winsvc.h:20
#define SERVICE_CHANGE_CONFIG
Definition: winsvc.h:54
QUERY_SERVICE_CONFIGA * LPQUERY_SERVICE_CONFIG
Definition: winsvc.h:550
#define ChangeServiceConfig
Definition: winsvc.h:567
#define StartService
Definition: winsvc.h:585
#define SERVICE_STOP
Definition: winsvc.h:58
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_QUERY_CONFIG
Definition: winsvc.h:53
#define OpenService
Definition: winsvc.h:576
#define HWND_BROADCAST
Definition: winuser.h:1204
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define WM_DEVICECHANGE
Definition: winuser.h:1811
#define LoadCursor
Definition: winuser.h:5812
#define BroadcastSystemMessage
Definition: winuser.h:5732
#define PostMessage
Definition: winuser.h:5832
#define IDC_WAIT
Definition: winuser.h:689
#define VerQueryValue
Definition: winver.h:56
#define GetFileVersionInfo
Definition: winver.h:54
#define GetFileVersionInfoSize
Definition: winver.h:53
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:953
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:982
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175