[REACTOS] Fix 64 bit build (#465)
[reactos.git] / modules / rosapps / drivers / vfd / vfdlink.c
1 /*
2 vfdlink.c
3
4 Virtual Floppy Drive for Windows NT platform
5 Kernel mode driver: persistent drive letter functions
6
7 Copyright (C) 2003-2005 Ken Kato
8 */
9
10 #include "imports.h"
11 #include "vfddrv.h"
12 #include "vfddbg.h"
13
14 #ifdef ALLOC_PRAGMA
15 #pragma alloc_text(PAGE, VfdSetLink)
16 #pragma alloc_text(PAGE, VfdLoadLink)
17 #pragma alloc_text(PAGE, VfdStoreLink)
18 #endif // ALLOC_PRAGMA
19
20 //
21 // create or remove the persistent drive letter (Windows NT)
22 //
23 NTSTATUS
24 VfdSetLink(
25 IN PDEVICE_EXTENSION DeviceExtension,
26 IN CHAR DriveLetter)
27 {
28 UNICODE_STRING unicode_name;
29 WCHAR name_buf[15];
30 NTSTATUS status = STATUS_SUCCESS;
31
32 VFDTRACE(VFDINFO, ("[VFD] VfdSetLink - IN\n"));
33
34 // convert lower case into upper case
35
36 if (DriveLetter >= 'a' && DriveLetter <= 'z') {
37 DriveLetter -= ('a' - 'A');
38 }
39
40 // check the drive letter range
41
42 if (DriveLetter != 0 &&
43 (DriveLetter < 'A' || DriveLetter > 'Z')) {
44 return STATUS_INVALID_PARAMETER;
45 }
46
47 if (DeviceExtension->DriveLetter &&
48 DeviceExtension->DriveLetter != DriveLetter) {
49 //
50 // Delete the old drive letter
51 //
52 #ifndef __REACTOS__
53 name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
54 #else
55 name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
56 #endif
57
58 _snwprintf(name_buf, sizeof(name_buf) - 1,
59 L"\\??\\%wc:", DeviceExtension->DriveLetter);
60
61 RtlInitUnicodeString(&unicode_name, name_buf);
62
63 status = IoDeleteSymbolicLink(&unicode_name);
64
65 if (NT_SUCCESS(status)) {
66 VFDTRACE(VFDINFO,
67 ("[VFD] Link %ws deleted\n", name_buf));
68
69 DeviceExtension->DriveLetter = 0;
70 }
71 else if (status != STATUS_OBJECT_NAME_NOT_FOUND) {
72 // the driver letter did not exist in the first place
73
74 VFDTRACE(VFDINFO,
75 ("[VFD] Link %ws not found\n", name_buf));
76
77 DeviceExtension->DriveLetter = 0;
78 status = STATUS_SUCCESS;
79 }
80 else {
81 VFDTRACE(VFDWARN,
82 ("[VFD] IoDeleteSymbolicLink %ws - %s\n",
83 name_buf, GetStatusName(status)));
84 }
85 }
86
87 if (NT_SUCCESS(status) && DriveLetter) {
88 //
89 // Create a new drive letter
90 //
91
92 #ifndef __REACTOS__
93 name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
94
95 _snwprintf(name_buf, sizeof(name_buf) - 1,
96 (OsMajorVersion >= 5) ?
97 L"\\??\\Global\\%wc:" : L"\\??\\%wc:",
98 DriveLetter);
99 #else
100 name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
101
102 _snwprintf(name_buf, ARRAYSIZE(name_buf) - 1,
103 (OsMajorVersion >= 5) ?
104 L"\\??\\Global\\%wc:" : L"\\??\\%wc:",
105 DriveLetter);
106 #endif
107
108 RtlInitUnicodeString(&unicode_name, name_buf);
109
110 status = IoCreateSymbolicLink(
111 &unicode_name, &(DeviceExtension->DeviceName));
112
113 if (NT_SUCCESS(status)) {
114 VFDTRACE(VFDINFO, ("[VFD] Link %ws created\n", name_buf));
115
116 DeviceExtension->DriveLetter = DriveLetter;
117 }
118 else {
119 VFDTRACE(VFDWARN,
120 ("[VFD] IoCreateSymbolicLink %ws - %s\n",
121 name_buf, GetStatusName(status)));
122 }
123 }
124
125 VFDTRACE(VFDINFO,
126 ("[VFD] VfdSetLink - %s\n", GetStatusName(status)));
127
128 return status;
129 }
130
131 //
132 // load the persistent drive letter from the registry
133 //
134 NTSTATUS
135 VfdLoadLink(
136 IN PDEVICE_EXTENSION DeviceExtension,
137 IN PWSTR RegistryPath)
138 {
139 RTL_QUERY_REGISTRY_TABLE params[2];
140 WCHAR name_buf[20];
141 ULONG letter;
142 ULONG zero = 0;
143 NTSTATUS status;
144
145 VFDTRACE(VFDINFO, ("[VFD] VfdLoadLink - IN\n"));
146
147 RtlZeroMemory(params, sizeof(params));
148
149 #ifndef __REACTOS__
150 name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
151
152 _snwprintf(name_buf, sizeof(name_buf) - 1,
153 VFD_REG_DRIVE_LETTER L"%lu",
154 DeviceExtension->DeviceNumber);
155 #else
156 name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
157
158 _snwprintf(name_buf, ARRAYSIZE(name_buf) - 1,
159 VFD_REG_DRIVE_LETTER L"%lu",
160 DeviceExtension->DeviceNumber);
161 #endif
162
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);
169
170 status = RtlQueryRegistryValues(
171 RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
172 RegistryPath, &params[0], NULL, NULL);
173
174 VFDTRACE(VFDINFO,
175 ("[VFD] Drive letter '%wc' loaded from the registry\n",
176 letter ? letter : ' '));
177
178 DeviceExtension->DriveLetter = (CHAR)letter;
179
180 VFDTRACE(VFDINFO,
181 ("[VFD] VfdLoadLink - %s\n", GetStatusName(status)));
182
183 return status;
184 }
185
186 //
187 // store the persistent drive letter into the registry
188 //
189 NTSTATUS
190 VfdStoreLink(
191 IN PDEVICE_EXTENSION DeviceExtension)
192 {
193 PVFD_DRIVER_EXTENSION driver_extension;
194 WCHAR name_buf[20];
195 ULONG letter;
196 NTSTATUS status;
197
198 VFDTRACE(VFDINFO, ("[VFD] VfdStoreLink - IN\n"));
199
200 #ifdef VFD_PNP
201 driver_extension = IoGetDriverObjectExtension(
202 DeviceExtension->device_object->DriverObject,
203 VFD_DRIVER_EXTENSION_ID);
204 #else // VFD_PNP
205 driver_extension = DeviceExtension->DriverExtension;
206 #endif // VFD_PNP
207
208 if (!driver_extension ||
209 !driver_extension->RegistryPath.Buffer) {
210
211 VFDTRACE(VFDWARN, ("[VFD] Registry Path not present.\n"));
212 VFDTRACE(VFDINFO, ("[VFD] VfdStoreLinks - OUT\n"));
213 return STATUS_DRIVER_INTERNAL_ERROR;
214 }
215
216 #ifndef __REACTOS__
217 name_buf[sizeof(name_buf) - 1] = UNICODE_NULL;
218
219 _snwprintf(name_buf, sizeof(name_buf) - 1,
220 VFD_REG_DRIVE_LETTER L"%lu",
221 DeviceExtension->DeviceNumber);
222 #else
223 name_buf[ARRAYSIZE(name_buf) - 1] = UNICODE_NULL;
224
225 _snwprintf(name_buf, ARRAYSIZE(name_buf) - 1,
226 VFD_REG_DRIVE_LETTER L"%lu",
227 DeviceExtension->DeviceNumber);
228 #endif
229
230 letter = DeviceExtension->DriveLetter;
231
232 status = RtlWriteRegistryValue(
233 RTL_REGISTRY_ABSOLUTE,
234 driver_extension->RegistryPath.Buffer,
235 name_buf,
236 REG_DWORD,
237 &letter,
238 sizeof(ULONG));
239
240 if (!NT_SUCCESS(status)) {
241 VFDTRACE(VFDWARN,
242 ("[VFD] RtlWriteRegistryValue - %s\n",
243 GetStatusName(status)));
244 }
245 else {
246 VFDTRACE(VFDINFO,
247 ("[VFD] Drive letter '%wc' stored into the registry\n",
248 letter ? letter : L' '));
249 }
250
251 VFDTRACE(VFDINFO,
252 ("[VFD] VfdStoreLink - %s\n", GetStatusName(status)));
253
254 return status;
255 }