4 Virtual Floppy Drive for Windows NT platform
5 Kernel mode driver: persistent drive letter functions
7 Copyright (C) 2003-2005 Ken Kato
15 #pragma alloc_text(PAGE, VfdSetLink)
16 #pragma alloc_text(PAGE, VfdLoadLink)
17 #pragma alloc_text(PAGE, VfdStoreLink)
18 #endif // ALLOC_PRAGMA
21 // create or remove the persistent drive letter (Windows NT)
25 IN PDEVICE_EXTENSION DeviceExtension
,
28 UNICODE_STRING unicode_name
;
30 NTSTATUS status
= STATUS_SUCCESS
;
32 VFDTRACE(VFDINFO
, ("[VFD] VfdSetLink - IN\n"));
34 // convert lower case into upper case
36 if (DriveLetter
>= 'a' && DriveLetter
<= 'z') {
37 DriveLetter
-= ('a' - 'A');
40 // check the drive letter range
42 if (DriveLetter
!= 0 &&
43 (DriveLetter
< 'A' || DriveLetter
> 'Z')) {
44 return STATUS_INVALID_PARAMETER
;
47 if (DeviceExtension
->DriveLetter
&&
48 DeviceExtension
->DriveLetter
!= DriveLetter
) {
50 // Delete the old drive letter
52 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
54 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
55 L
"\\??\\%wc:", DeviceExtension
->DriveLetter
);
57 RtlInitUnicodeString(&unicode_name
, name_buf
);
59 status
= IoDeleteSymbolicLink(&unicode_name
);
61 if (NT_SUCCESS(status
)) {
63 ("[VFD] Link %ws deleted\n", name_buf
));
65 DeviceExtension
->DriveLetter
= 0;
67 else if (status
!= STATUS_OBJECT_NAME_NOT_FOUND
) {
68 // the driver letter did not exist in the first place
71 ("[VFD] Link %ws not found\n", name_buf
));
73 DeviceExtension
->DriveLetter
= 0;
74 status
= STATUS_SUCCESS
;
78 ("[VFD] IoDeleteSymbolicLink %ws - %s\n",
79 name_buf
, GetStatusName(status
)));
83 if (NT_SUCCESS(status
) && DriveLetter
) {
85 // Create a new drive letter
88 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
90 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
91 (OsMajorVersion
>= 5) ?
92 L
"\\??\\Global\\%wc:" : L
"\\??\\%wc:",
95 RtlInitUnicodeString(&unicode_name
, name_buf
);
97 status
= IoCreateSymbolicLink(
98 &unicode_name
, &(DeviceExtension
->DeviceName
));
100 if (NT_SUCCESS(status
)) {
101 VFDTRACE(VFDINFO
, ("[VFD] Link %ws created\n", name_buf
));
103 DeviceExtension
->DriveLetter
= DriveLetter
;
107 ("[VFD] IoCreateSymbolicLink %ws - %s\n",
108 name_buf
, GetStatusName(status
)));
113 ("[VFD] VfdSetLink - %s\n", GetStatusName(status
)));
119 // load the persistent drive letter from the registry
123 IN PDEVICE_EXTENSION DeviceExtension
,
124 IN PWSTR RegistryPath
)
126 RTL_QUERY_REGISTRY_TABLE params
[2];
132 VFDTRACE(VFDINFO
, ("[VFD] VfdLoadLink - IN\n"));
134 RtlZeroMemory(params
, sizeof(params
));
136 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
138 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
139 VFD_REG_DRIVE_LETTER L
"%lu",
140 DeviceExtension
->DeviceNumber
);
142 params
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
143 params
[0].Name
= name_buf
;
144 params
[0].EntryContext
= &letter
;
145 params
[0].DefaultType
= REG_DWORD
;
146 params
[0].DefaultData
= &zero
;
147 params
[0].DefaultLength
= sizeof(ULONG
);
149 status
= RtlQueryRegistryValues(
150 RTL_REGISTRY_ABSOLUTE
| RTL_REGISTRY_OPTIONAL
,
151 RegistryPath
, ¶ms
[0], NULL
, NULL
);
154 ("[VFD] Drive letter '%wc' loaded from the registry\n",
155 letter
? letter
: ' '));
157 DeviceExtension
->DriveLetter
= (CHAR
)letter
;
160 ("[VFD] VfdLoadLink - %s\n", GetStatusName(status
)));
166 // store the persistent drive letter into the registry
170 IN PDEVICE_EXTENSION DeviceExtension
)
172 PVFD_DRIVER_EXTENSION driver_extension
;
177 VFDTRACE(VFDINFO
, ("[VFD] VfdStoreLink - IN\n"));
180 driver_extension
= IoGetDriverObjectExtension(
181 DeviceExtension
->device_object
->DriverObject
,
182 VFD_DRIVER_EXTENSION_ID
);
184 driver_extension
= DeviceExtension
->DriverExtension
;
187 if (!driver_extension
||
188 !driver_extension
->RegistryPath
.Buffer
) {
190 VFDTRACE(VFDWARN
, ("[VFD] Registry Path not present.\n"));
191 VFDTRACE(VFDINFO
, ("[VFD] VfdStoreLinks - OUT\n"));
192 return STATUS_DRIVER_INTERNAL_ERROR
;
195 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
197 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
198 VFD_REG_DRIVE_LETTER L
"%lu",
199 DeviceExtension
->DeviceNumber
);
201 letter
= DeviceExtension
->DriveLetter
;
203 status
= RtlWriteRegistryValue(
204 RTL_REGISTRY_ABSOLUTE
,
205 driver_extension
->RegistryPath
.Buffer
,
211 if (!NT_SUCCESS(status
)) {
213 ("[VFD] RtlWriteRegistryValue - %s\n",
214 GetStatusName(status
)));
218 ("[VFD] Drive letter '%wc' stored into the registry\n",
219 letter
? letter
: L
' '));
223 ("[VFD] VfdStoreLink - %s\n", GetStatusName(status
)));