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
53 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
55 name_buf
[ARRAYSIZE(name_buf
) - 1] = UNICODE_NULL
;
58 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
59 L
"\\??\\%wc:", DeviceExtension
->DriveLetter
);
61 RtlInitUnicodeString(&unicode_name
, name_buf
);
63 status
= IoDeleteSymbolicLink(&unicode_name
);
65 if (NT_SUCCESS(status
)) {
67 ("[VFD] Link %ws deleted\n", name_buf
));
69 DeviceExtension
->DriveLetter
= 0;
71 else if (status
!= STATUS_OBJECT_NAME_NOT_FOUND
) {
72 // the driver letter did not exist in the first place
75 ("[VFD] Link %ws not found\n", name_buf
));
77 DeviceExtension
->DriveLetter
= 0;
78 status
= STATUS_SUCCESS
;
82 ("[VFD] IoDeleteSymbolicLink %ws - %s\n",
83 name_buf
, GetStatusName(status
)));
87 if (NT_SUCCESS(status
) && DriveLetter
) {
89 // Create a new drive letter
93 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
95 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
96 (OsMajorVersion
>= 5) ?
97 L
"\\??\\Global\\%wc:" : L
"\\??\\%wc:",
100 name_buf
[ARRAYSIZE(name_buf
) - 1] = UNICODE_NULL
;
102 _snwprintf(name_buf
, ARRAYSIZE(name_buf
) - 1,
103 (OsMajorVersion
>= 5) ?
104 L
"\\??\\Global\\%wc:" : L
"\\??\\%wc:",
108 RtlInitUnicodeString(&unicode_name
, name_buf
);
110 status
= IoCreateSymbolicLink(
111 &unicode_name
, &(DeviceExtension
->DeviceName
));
113 if (NT_SUCCESS(status
)) {
114 VFDTRACE(VFDINFO
, ("[VFD] Link %ws created\n", name_buf
));
116 DeviceExtension
->DriveLetter
= DriveLetter
;
120 ("[VFD] IoCreateSymbolicLink %ws - %s\n",
121 name_buf
, GetStatusName(status
)));
126 ("[VFD] VfdSetLink - %s\n", GetStatusName(status
)));
132 // load the persistent drive letter from the registry
136 IN PDEVICE_EXTENSION DeviceExtension
,
137 IN PWSTR RegistryPath
)
139 RTL_QUERY_REGISTRY_TABLE params
[2];
145 VFDTRACE(VFDINFO
, ("[VFD] VfdLoadLink - IN\n"));
147 RtlZeroMemory(params
, sizeof(params
));
150 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
152 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
153 VFD_REG_DRIVE_LETTER L
"%lu",
154 DeviceExtension
->DeviceNumber
);
156 name_buf
[ARRAYSIZE(name_buf
) - 1] = UNICODE_NULL
;
158 _snwprintf(name_buf
, ARRAYSIZE(name_buf
) - 1,
159 VFD_REG_DRIVE_LETTER L
"%lu",
160 DeviceExtension
->DeviceNumber
);
163 params
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
164 params
[0].Name
= name_buf
;
165 params
[0].EntryContext
= &letter
;
166 params
[0].DefaultType
= REG_DWORD
;
167 params
[0].DefaultData
= &zero
;
168 params
[0].DefaultLength
= sizeof(ULONG
);
170 status
= RtlQueryRegistryValues(
171 RTL_REGISTRY_ABSOLUTE
| RTL_REGISTRY_OPTIONAL
,
172 RegistryPath
, ¶ms
[0], NULL
, NULL
);
175 ("[VFD] Drive letter '%wc' loaded from the registry\n",
176 letter
? letter
: ' '));
178 DeviceExtension
->DriveLetter
= (CHAR
)letter
;
181 ("[VFD] VfdLoadLink - %s\n", GetStatusName(status
)));
187 // store the persistent drive letter into the registry
191 IN PDEVICE_EXTENSION DeviceExtension
)
193 PVFD_DRIVER_EXTENSION driver_extension
;
198 VFDTRACE(VFDINFO
, ("[VFD] VfdStoreLink - IN\n"));
201 driver_extension
= IoGetDriverObjectExtension(
202 DeviceExtension
->device_object
->DriverObject
,
203 VFD_DRIVER_EXTENSION_ID
);
205 driver_extension
= DeviceExtension
->DriverExtension
;
208 if (!driver_extension
||
209 !driver_extension
->RegistryPath
.Buffer
) {
211 VFDTRACE(VFDWARN
, ("[VFD] Registry Path not present.\n"));
212 VFDTRACE(VFDINFO
, ("[VFD] VfdStoreLinks - OUT\n"));
213 return STATUS_DRIVER_INTERNAL_ERROR
;
217 name_buf
[sizeof(name_buf
) - 1] = UNICODE_NULL
;
219 _snwprintf(name_buf
, sizeof(name_buf
) - 1,
220 VFD_REG_DRIVE_LETTER L
"%lu",
221 DeviceExtension
->DeviceNumber
);
223 name_buf
[ARRAYSIZE(name_buf
) - 1] = UNICODE_NULL
;
225 _snwprintf(name_buf
, ARRAYSIZE(name_buf
) - 1,
226 VFD_REG_DRIVE_LETTER L
"%lu",
227 DeviceExtension
->DeviceNumber
);
230 letter
= DeviceExtension
->DriveLetter
;
232 status
= RtlWriteRegistryValue(
233 RTL_REGISTRY_ABSOLUTE
,
234 driver_extension
->RegistryPath
.Buffer
,
240 if (!NT_SUCCESS(status
)) {
242 ("[VFD] RtlWriteRegistryValue - %s\n",
243 GetStatusName(status
)));
247 ("[VFD] Drive letter '%wc' stored into the registry\n",
248 letter
? letter
: L
' '));
252 ("[VFD] VfdStoreLink - %s\n", GetStatusName(status
)));