Moved and renamed some ReactOS specific macros
[reactos.git] / reactos / ntoskrnl / io / arcname.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: arcname.c,v 1.16 2003/11/17 02:12:51 hyperion Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: ntoskrnl/io/arcname.c
24 * PURPOSE: creates ARC names for boot devices
25 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
26 */
27
28
29 /* INCLUDES *****************************************************************/
30
31 #include <ddk/ntddk.h>
32 #include <rosrtl/string.h>
33
34 #include "internal/io.h"
35 #include "internal/xhal.h"
36
37 #define NDEBUG
38 #include <internal/debug.h>
39
40 /* MACROS *******************************************************************/
41
42 #define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
43
44 /* FUNCTIONS ****************************************************************/
45
46 NTSTATUS INIT_FUNCTION
47 IoCreateArcNames(VOID)
48 {
49 PCONFIGURATION_INFORMATION ConfigInfo;
50 PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
51 WCHAR DeviceNameBuffer[80];
52 WCHAR ArcNameBuffer[80];
53 UNICODE_STRING DeviceName;
54 UNICODE_STRING ArcName;
55 ULONG i, j;
56 NTSTATUS Status;
57
58 DPRINT("IoCreateArcNames() called\n");
59
60 ConfigInfo = IoGetConfigurationInformation();
61
62 /* create ARC names for floppy drives */
63 DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
64 for (i = 0; i < ConfigInfo->FloppyCount; i++)
65 {
66 swprintf(DeviceNameBuffer,
67 L"\\Device\\Floppy%lu",
68 i);
69 RtlInitUnicodeString(&DeviceName,
70 DeviceNameBuffer);
71
72 swprintf(ArcNameBuffer,
73 L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
74 i);
75 RtlInitUnicodeString(&ArcName,
76 ArcNameBuffer);
77 DPRINT("%wZ ==> %wZ\n",
78 &ArcName,
79 &DeviceName);
80
81 Status = IoAssignArcName(&ArcName,
82 &DeviceName);
83 if (!NT_SUCCESS(Status))
84 return(Status);
85 }
86
87 /* create ARC names for hard disk drives */
88 DPRINT("Disk drives: %lu\n", ConfigInfo->DiskCount);
89 for (i = 0; i < ConfigInfo->DiskCount; i++)
90 {
91 swprintf(DeviceNameBuffer,
92 L"\\Device\\Harddisk%lu\\Partition0",
93 i);
94 RtlInitUnicodeString(&DeviceName,
95 DeviceNameBuffer);
96
97 swprintf(ArcNameBuffer,
98 L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(0)",
99 i);
100 RtlInitUnicodeString(&ArcName,
101 ArcNameBuffer);
102 DPRINT("%wZ ==> %wZ\n",
103 &ArcName,
104 &DeviceName);
105
106 Status = IoAssignArcName(&ArcName,
107 &DeviceName);
108 if (!NT_SUCCESS(Status))
109 return(Status);
110
111 Status = xHalQueryDriveLayout(&DeviceName,
112 &LayoutInfo);
113 if (!NT_SUCCESS(Status))
114 return(Status);
115
116 DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);
117
118 for (j = 0;j < LayoutInfo->PartitionCount; j++)
119 {
120 swprintf(DeviceNameBuffer,
121 L"\\Device\\Harddisk%lu\\Partition%lu",
122 i,
123 j + 1);
124 RtlInitUnicodeString(&DeviceName,
125 DeviceNameBuffer);
126
127 swprintf(ArcNameBuffer,
128 L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
129 i,
130 j + 1);
131 RtlInitUnicodeString(&ArcName,
132 ArcNameBuffer);
133 DPRINT("%wZ ==> %wZ\n",
134 &ArcName,
135 &DeviceName);
136
137 Status = IoAssignArcName(&ArcName,
138 &DeviceName);
139 if (!NT_SUCCESS(Status))
140 return(Status);
141 }
142
143 ExFreePool(LayoutInfo);
144 LayoutInfo = NULL;
145 }
146
147 /* create ARC names for cdrom drives */
148 DPRINT("CD-ROM drives: %lu\n", ConfigInfo->CdRomCount);
149 for (i = 0; i < ConfigInfo->CdRomCount; i++)
150 {
151 swprintf(DeviceNameBuffer,
152 L"\\Device\\CdRom%lu",
153 i);
154 RtlInitUnicodeString(&DeviceName,
155 DeviceNameBuffer);
156
157 swprintf(ArcNameBuffer,
158 L"\\ArcName\\multi(0)disk(0)cdrom(%lu)",
159 i);
160 RtlInitUnicodeString(&ArcName,
161 ArcNameBuffer);
162 DPRINT("%wZ ==> %wZ\n",
163 &ArcName,
164 &DeviceName);
165
166 Status = IoAssignArcName(&ArcName,
167 &DeviceName);
168 if (!NT_SUCCESS(Status))
169 return(Status);
170 }
171
172 DPRINT("IoCreateArcNames() done\n");
173
174 return(STATUS_SUCCESS);
175 }
176
177
178 static NTSTATUS
179 IopCheckCdromDevices(PULONG DeviceNumber)
180 {
181 PCONFIGURATION_INFORMATION ConfigInfo;
182 OBJECT_ATTRIBUTES ObjectAttributes;
183 UNICODE_STRING DeviceName;
184 WCHAR DeviceNameBuffer[MAX_PATH];
185 HANDLE Handle;
186 ULONG i;
187 NTSTATUS Status;
188 IO_STATUS_BLOCK IoStatusBlock;
189 #if 0
190 PFILE_FS_VOLUME_INFORMATION FileFsVolume;
191 USHORT Buffer[FS_VOLUME_BUFFER_SIZE];
192
193 FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
194 #endif
195
196 ConfigInfo = IoGetConfigurationInformation();
197 for (i = 0; i < ConfigInfo->CdRomCount; i++)
198 {
199 #if 0
200 swprintf(DeviceNameBuffer,
201 L"\\Device\\CdRom%lu\\",
202 i);
203 RtlInitUnicodeString(&DeviceName,
204 DeviceNameBuffer);
205
206 InitializeObjectAttributes(&ObjectAttributes,
207 &DeviceName,
208 0,
209 NULL,
210 NULL);
211
212 Status = NtOpenFile(&Handle,
213 FILE_ALL_ACCESS,
214 &ObjectAttributes,
215 &IoStatusBlock,
216 0,
217 0);
218 DPRINT("NtOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
219 if (NT_SUCCESS(Status))
220 {
221 Status = NtQueryVolumeInformationFile(Handle,
222 &IoStatusBlock,
223 FileFsVolume,
224 FS_VOLUME_BUFFER_SIZE,
225 FileFsVolumeInformation);
226 DPRINT("NtQueryVolumeInformationFile() Status %lx\n", Status);
227 if (NT_SUCCESS(Status))
228 {
229 DPRINT("VolumeLabel: '%S'\n", FileFsVolume->VolumeLabel);
230 if (_wcsicmp(FileFsVolume->VolumeLabel, L"REACTOS") == 0)
231 {
232 NtClose(Handle);
233 *DeviceNumber = i;
234 return(STATUS_SUCCESS);
235 }
236 }
237 NtClose(Handle);
238 }
239 #endif
240
241 swprintf(DeviceNameBuffer,
242 L"\\Device\\CdRom%lu\\reactos\\ntoskrnl.exe",
243 i);
244 RtlInitUnicodeString(&DeviceName,
245 DeviceNameBuffer);
246
247 InitializeObjectAttributes(&ObjectAttributes,
248 &DeviceName,
249 0,
250 NULL,
251 NULL);
252
253 Status = NtOpenFile(&Handle,
254 FILE_ALL_ACCESS,
255 &ObjectAttributes,
256 &IoStatusBlock,
257 0,
258 0);
259 DPRINT("NtOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
260 if (NT_SUCCESS(Status))
261 {
262 DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i);
263 NtClose(Handle);
264 *DeviceNumber = i;
265 return(STATUS_SUCCESS);
266 }
267
268 }
269
270 DPRINT("Could not find ntoskrnl.exe\n");
271 *DeviceNumber = (ULONG)-1;
272
273 return(STATUS_UNSUCCESSFUL);
274 }
275
276
277 NTSTATUS INIT_FUNCTION
278 IoCreateSystemRootLink(PCHAR ParameterLine)
279 {
280 OBJECT_ATTRIBUTES ObjectAttributes;
281 IO_STATUS_BLOCK IoStatusBlock;
282 UNICODE_STRING LinkName;
283 UNICODE_STRING DeviceName;
284 UNICODE_STRING ArcName;
285 UNICODE_STRING BootPath;
286 PCHAR ParamBuffer;
287 PWCHAR ArcNameBuffer;
288 PCHAR p;
289 NTSTATUS Status;
290 ULONG Length;
291 HANDLE Handle;
292
293 /* Create local parameter line copy */
294 ParamBuffer = ExAllocatePool(PagedPool, 256);
295 strcpy(ParamBuffer, (char *)ParameterLine);
296
297 DPRINT("%s\n", ParamBuffer);
298 /* Format: <arc_name>\<path> [options...] */
299
300 /* cut options off */
301 p = strchr(ParamBuffer, ' ');
302 if (p)
303 *p = 0;
304 DPRINT("%s\n", ParamBuffer);
305
306 /* extract path */
307 p = strchr(ParamBuffer, '\\');
308 if (p)
309 {
310 DPRINT("Boot path: %s\n", p);
311 RtlCreateUnicodeStringFromAsciiz(&BootPath, p);
312 *p = 0;
313 }
314 else
315 {
316 DPRINT("Boot path: %s\n", "\\");
317 RtlCreateUnicodeStringFromAsciiz(&BootPath, "\\");
318 }
319 DPRINT("ARC name: %s\n", ParamBuffer);
320
321 p = strstr(ParamBuffer, "cdrom");
322 if (p != NULL)
323 {
324 ULONG DeviceNumber;
325
326 DPRINT("Booting from CD-ROM!\n");
327 Status = IopCheckCdromDevices(&DeviceNumber);
328 if (!NT_SUCCESS(Status))
329 {
330 CPRINT("Failed to find setup disk!\n");
331 return(Status);
332 }
333
334 sprintf(p, "cdrom(%lu)", DeviceNumber);
335
336 DPRINT("New ARC name: %s\n", ParamBuffer);
337
338 /* Adjust original command line */
339 p = strstr(ParameterLine, "cdrom");
340 if (p != NULL);
341 {
342 char temp[256];
343 char *q;
344
345 q = strchr(p, ')');
346 if (q != NULL)
347 {
348
349 q++;
350 strcpy(temp, q);
351 sprintf(p, "cdrom(%lu)", DeviceNumber);
352 strcat(p, temp);
353 }
354 }
355 }
356
357 /* Only arc name left - build full arc name */
358 ArcNameBuffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
359 swprintf(ArcNameBuffer,
360 L"\\ArcName\\%S", ParamBuffer);
361 RtlInitUnicodeString(&ArcName, ArcNameBuffer);
362 DPRINT("Arc name: %wZ\n", &ArcName);
363
364 /* free ParamBuffer */
365 ExFreePool(ParamBuffer);
366
367 /* allocate device name string */
368 DeviceName.Length = 0;
369 DeviceName.MaximumLength = 256 * sizeof(WCHAR);
370 DeviceName.Buffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
371
372 InitializeObjectAttributes(&ObjectAttributes,
373 &ArcName,
374 OBJ_OPENLINK,
375 NULL,
376 NULL);
377
378 Status = NtOpenSymbolicLinkObject(&Handle,
379 SYMBOLIC_LINK_ALL_ACCESS,
380 &ObjectAttributes);
381 if (!NT_SUCCESS(Status))
382 {
383 RtlFreeUnicodeString(&BootPath);
384 RtlFreeUnicodeString(&DeviceName);
385 CPRINT("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
386 &ArcName,
387 Status);
388 RtlFreeUnicodeString(&ArcName);
389
390 return(Status);
391 }
392 RtlFreeUnicodeString(&ArcName);
393
394 Status = NtQuerySymbolicLinkObject(Handle,
395 &DeviceName,
396 &Length);
397 NtClose (Handle);
398 if (!NT_SUCCESS(Status))
399 {
400 RtlFreeUnicodeString(&BootPath);
401 RtlFreeUnicodeString(&DeviceName);
402 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
403 Status);
404
405 return(Status);
406 }
407 DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);
408
409 RtlAppendUnicodeStringToString(&DeviceName,
410 &BootPath);
411
412 RtlFreeUnicodeString(&BootPath);
413 DPRINT("DeviceName: %wZ\n", &DeviceName);
414
415 /* create the '\SystemRoot' link */
416 RtlRosInitUnicodeStringFromLiteral(&LinkName,
417 L"\\SystemRoot");
418
419 Status = IoCreateSymbolicLink(&LinkName,
420 &DeviceName);
421 RtlFreeUnicodeString (&DeviceName);
422 if (!NT_SUCCESS(Status))
423 {
424 CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
425 Status);
426
427 return(Status);
428 }
429
430 /* Check whether '\SystemRoot'(LinkName) can be opened */
431 InitializeObjectAttributes(&ObjectAttributes,
432 &LinkName,
433 0,
434 NULL,
435 NULL);
436
437 Status = NtOpenFile(&Handle,
438 FILE_ALL_ACCESS,
439 &ObjectAttributes,
440 &IoStatusBlock,
441 0,
442 0);
443 if (!NT_SUCCESS(Status))
444 {
445 CPRINT("NtOpenFile() failed to open '\\SystemRoot' (Status %x)\n",
446 Status);
447 return(Status);
448 }
449
450 NtClose(Handle);
451
452 return(STATUS_SUCCESS);
453 }
454
455 /* EOF */