- Fix compile issues caused by previous patch.
[reactos.git] / reactos / ntoskrnl / io / arcname.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/arcname.c
6 * PURPOSE: Creates ARC names for boot devices
7 *
8 * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
9 */
10
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <internal/debug.h>
17
18 /* MACROS *******************************************************************/
19
20 #define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
21
22 /* FUNCTIONS ****************************************************************/
23
24 STATIC
25 NTSTATUS
26 STDCALL
27 INIT_FUNCTION
28 DiskQueryRoutine(PWSTR ValueName,
29 ULONG ValueType,
30 PVOID ValueData,
31 ULONG ValueLength,
32 PVOID Context,
33 PVOID EntryContext)
34 {
35 PLIST_ENTRY ListHead = (PLIST_ENTRY)Context;
36 PULONG GlobalDiskCount = (PULONG)EntryContext;
37 PDISKENTRY DiskEntry;
38 UNICODE_STRING NameU;
39
40 if (ValueType == REG_SZ &&
41 ValueLength == 20 * sizeof(WCHAR))
42 {
43 DiskEntry = ExAllocatePool(PagedPool, sizeof(DISKENTRY));
44 if (DiskEntry == NULL)
45 {
46 return STATUS_NO_MEMORY;
47 }
48 DiskEntry->DiskNumber = (*GlobalDiskCount)++;
49
50 NameU.Buffer = (PWCHAR)ValueData;
51 NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
52 RtlUnicodeStringToInteger(&NameU, 16, &DiskEntry->Checksum);
53
54 NameU.Buffer = (PWCHAR)ValueData + 9;
55 RtlUnicodeStringToInteger(&NameU, 16, &DiskEntry->Signature);
56
57 InsertTailList(ListHead, &DiskEntry->ListEntry);
58 }
59
60 return STATUS_SUCCESS;
61 }
62
63 #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
64
65 STATIC VOID INIT_FUNCTION
66 IopEnumerateBiosDisks(PLIST_ENTRY ListHead)
67 {
68 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
69 WCHAR Name[255];
70 ULONG AdapterCount;
71 ULONG ControllerCount;
72 ULONG DiskCount;
73 NTSTATUS Status;
74 ULONG GlobalDiskCount=0;
75
76
77 memset(QueryTable, 0, sizeof(QueryTable));
78 QueryTable[0].Name = L"Identifier";
79 QueryTable[0].QueryRoutine = DiskQueryRoutine;
80 QueryTable[0].EntryContext = (PVOID)&GlobalDiskCount;
81
82 AdapterCount = 0;
83 while (1)
84 {
85 swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
86 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
87 Name,
88 &QueryTable[1],
89 NULL,
90 NULL);
91 if (!NT_SUCCESS(Status))
92 {
93 break;
94 }
95
96 swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
97 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
98 Name,
99 &QueryTable[1],
100 NULL,
101 NULL);
102 if (NT_SUCCESS(Status))
103 {
104 ControllerCount = 0;
105 while (1)
106 {
107 swprintf(Name, L"%s\\%lu\\DiskController\\%lu", ROOT_NAME, AdapterCount, ControllerCount);
108 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
109 Name,
110 &QueryTable[1],
111 NULL,
112 NULL);
113 if (!NT_SUCCESS(Status))
114 {
115 break;
116 }
117
118 swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral", ROOT_NAME, AdapterCount, ControllerCount);
119 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
120 Name,
121 &QueryTable[1],
122 NULL,
123 NULL);
124 if (NT_SUCCESS(Status))
125 {
126 DiskCount = 0;
127 while (1)
128 {
129 swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
130 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
131 Name,
132 QueryTable,
133 (PVOID)ListHead,
134 NULL);
135 if (!NT_SUCCESS(Status))
136 {
137 break;
138 }
139 DiskCount++;
140 }
141 }
142 ControllerCount++;
143 }
144 }
145 AdapterCount++;
146 }
147 }
148
149 STATIC VOID INIT_FUNCTION
150 IopEnumerateDisks(PLIST_ENTRY ListHead)
151 {
152 ULONG i, k;
153 PDISKENTRY DiskEntry;
154 DISK_GEOMETRY DiskGeometry;
155 KEVENT Event;
156 PIRP Irp;
157 IO_STATUS_BLOCK StatusBlock;
158 LARGE_INTEGER PartitionOffset;
159 PULONG Buffer;
160 WCHAR DeviceNameBuffer[80];
161 UNICODE_STRING DeviceName;
162 NTSTATUS Status;
163 PDEVICE_OBJECT DeviceObject;
164 PFILE_OBJECT FileObject;
165 BOOLEAN IsRemovableMedia;
166 PPARTITION_SECTOR PartitionBuffer = NULL;
167 ULONG PartitionBufferSize = 0;
168
169
170 for (i = 0; i < IoGetConfigurationInformation()->DiskCount; i++)
171 {
172
173 swprintf(DeviceNameBuffer,
174 L"\\Device\\Harddisk%lu\\Partition0",
175 i);
176 RtlInitUnicodeString(&DeviceName,
177 DeviceNameBuffer);
178
179
180 Status = IoGetDeviceObjectPointer(&DeviceName,
181 FILE_READ_DATA,
182 &FileObject,
183 &DeviceObject);
184 if (!NT_SUCCESS(Status))
185 {
186 continue;
187 }
188 IsRemovableMedia = DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA ? TRUE : FALSE;
189 ObDereferenceObject(FileObject);
190 if (IsRemovableMedia)
191 {
192 ObDereferenceObject(DeviceObject);
193 continue;
194 }
195 DiskEntry = ExAllocatePool(PagedPool, sizeof(DISKENTRY));
196 if (DiskEntry == NULL)
197 {
198 KEBUGCHECK(0);
199 }
200 DiskEntry->DiskNumber = i;
201 DiskEntry->DeviceObject = DeviceObject;
202
203 /* determine the sector size */
204 KeInitializeEvent(&Event, NotificationEvent, FALSE);
205 Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
206 DeviceObject,
207 NULL,
208 0,
209 &DiskGeometry,
210 sizeof(DISK_GEOMETRY),
211 FALSE,
212 &Event,
213 &StatusBlock);
214 if (Irp == NULL)
215 {
216 KEBUGCHECK(0);
217 }
218
219 Status = IoCallDriver(DeviceObject, Irp);
220 if (Status == STATUS_PENDING)
221 {
222 KeWaitForSingleObject(&Event,
223 Executive,
224 KernelMode,
225 FALSE,
226 NULL);
227 Status = StatusBlock.Status;
228 }
229 if (!NT_SUCCESS(Status))
230 {
231 KEBUGCHECK(0);
232 }
233 if (PartitionBuffer != NULL && PartitionBufferSize < DiskGeometry.BytesPerSector)
234 {
235 ExFreePool(PartitionBuffer);
236 PartitionBuffer = NULL;
237 }
238 if (PartitionBuffer == NULL)
239 {
240 PartitionBufferSize = max(DiskGeometry.BytesPerSector, PAGE_SIZE);
241 PartitionBuffer = ExAllocatePool(PagedPool, PartitionBufferSize);
242 if (PartitionBuffer == NULL)
243 {
244 KEBUGCHECK(0);
245 }
246 }
247
248 /* read the partition sector */
249 KeInitializeEvent(&Event, NotificationEvent, FALSE);
250 PartitionOffset.QuadPart = 0;
251 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
252 DeviceObject,
253 PartitionBuffer,
254 DiskGeometry.BytesPerSector,
255 &PartitionOffset,
256 &Event,
257 &StatusBlock);
258 Status = IoCallDriver(DeviceObject, Irp);
259 if (Status == STATUS_PENDING)
260 {
261 KeWaitForSingleObject(&Event,
262 Executive,
263 KernelMode,
264 FALSE,
265 NULL);
266 Status = StatusBlock.Status;
267 }
268
269 if (!NT_SUCCESS(Status))
270 {
271 KEBUGCHECK(0);
272 }
273
274 /* Calculate the MBR checksum */
275 DiskEntry->Checksum = 0;
276 Buffer = (PULONG)PartitionBuffer;
277 for (k = 0; k < 128; k++)
278 {
279 DiskEntry->Checksum += Buffer[k];
280 }
281 DiskEntry->Checksum = ~DiskEntry->Checksum + 1;
282 DiskEntry->Signature = PartitionBuffer->Signature;
283
284 InsertTailList(ListHead, &DiskEntry->ListEntry);
285 }
286 if (PartitionBuffer)
287 {
288 ExFreePool(PartitionBuffer);
289 }
290 }
291
292 STATIC NTSTATUS INIT_FUNCTION
293 IopAssignArcNamesToDisk(PDEVICE_OBJECT DeviceObject, ULONG RDisk, ULONG DiskNumber)
294 {
295 WCHAR DeviceNameBuffer[80];
296 WCHAR ArcNameBuffer[80];
297 UNICODE_STRING DeviceName;
298 UNICODE_STRING ArcName;
299 PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
300 NTSTATUS Status;
301 ULONG i;
302 KEVENT Event;
303 PIRP Irp;
304 IO_STATUS_BLOCK StatusBlock;
305 ULONG PartitionNumber;
306
307 swprintf(DeviceNameBuffer,
308 L"\\Device\\Harddisk%lu\\Partition0",
309 DiskNumber);
310 RtlInitUnicodeString(&DeviceName,
311 DeviceNameBuffer);
312
313 swprintf(ArcNameBuffer,
314 L"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
315 RDisk);
316 RtlInitUnicodeString(&ArcName,
317 ArcNameBuffer);
318
319 DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
320
321 Status = IoAssignArcName(&ArcName, &DeviceName);
322 if (!NT_SUCCESS(Status))
323 {
324 DPRINT1("IoAssignArcName failed, status=%lx\n", Status);
325 return(Status);
326 }
327
328 LayoutInfo = ExAllocatePool(PagedPool, 2 * PAGE_SIZE);
329 if (LayoutInfo == NULL)
330 {
331 return STATUS_NO_MEMORY;
332 }
333 KeInitializeEvent(&Event, NotificationEvent, FALSE);
334 Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_LAYOUT,
335 DeviceObject,
336 NULL,
337 0,
338 LayoutInfo,
339 2 * PAGE_SIZE,
340 FALSE,
341 &Event,
342 &StatusBlock);
343 if (Irp == NULL)
344 {
345 ExFreePool(LayoutInfo);
346 return STATUS_INSUFFICIENT_RESOURCES;
347 }
348
349 Status = IoCallDriver(DeviceObject, Irp);
350 if (Status == STATUS_PENDING)
351 {
352 KeWaitForSingleObject(&Event,
353 Executive,
354 KernelMode,
355 FALSE,
356 NULL);
357 Status = StatusBlock.Status;
358 }
359 if (!NT_SUCCESS(Status))
360 {
361 ExFreePool(LayoutInfo);
362 return Status;
363 }
364
365 DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);
366
367 PartitionNumber = 1;
368 for (i = 0; i < LayoutInfo->PartitionCount; i++)
369 {
370 if (!IsContainerPartition(LayoutInfo->PartitionEntry[i].PartitionType) &&
371 LayoutInfo->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED)
372 {
373
374 swprintf(DeviceNameBuffer,
375 L"\\Device\\Harddisk%lu\\Partition%lu",
376 DiskNumber,
377 PartitionNumber);
378 RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
379
380 swprintf(ArcNameBuffer,
381 L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
382 RDisk,
383 PartitionNumber);
384 RtlInitUnicodeString(&ArcName, ArcNameBuffer);
385
386 DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
387
388 Status = IoAssignArcName(&ArcName, &DeviceName);
389 if (!NT_SUCCESS(Status))
390 {
391 DPRINT1("IoAssignArcName failed, status=%lx\n", Status);
392 ExFreePool(LayoutInfo);
393 return(Status);
394 }
395 PartitionNumber++;
396 }
397 }
398 ExFreePool(LayoutInfo);
399 return STATUS_SUCCESS;
400 }
401
402 NTSTATUS INIT_FUNCTION
403 IoCreateArcNames(VOID)
404 {
405 PCONFIGURATION_INFORMATION ConfigInfo;
406 WCHAR DeviceNameBuffer[80];
407 WCHAR ArcNameBuffer[80];
408 UNICODE_STRING DeviceName;
409 UNICODE_STRING ArcName;
410 ULONG i, RDiskNumber;
411 NTSTATUS Status;
412 LIST_ENTRY BiosDiskListHead;
413 LIST_ENTRY DiskListHead;
414 PLIST_ENTRY Entry;
415 PDISKENTRY BiosDiskEntry;
416 PDISKENTRY DiskEntry;
417
418 DPRINT("IoCreateArcNames() called\n");
419
420 ConfigInfo = IoGetConfigurationInformation();
421
422 /* create ARC names for floppy drives */
423 DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
424 for (i = 0; i < ConfigInfo->FloppyCount; i++)
425 {
426 swprintf(DeviceNameBuffer,
427 L"\\Device\\Floppy%lu",
428 i);
429 RtlInitUnicodeString(&DeviceName,
430 DeviceNameBuffer);
431
432 swprintf(ArcNameBuffer,
433 L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
434 i);
435 RtlInitUnicodeString(&ArcName,
436 ArcNameBuffer);
437 DPRINT("%wZ ==> %wZ\n",
438 &ArcName,
439 &DeviceName);
440
441 Status = IoAssignArcName(&ArcName,
442 &DeviceName);
443 if (!NT_SUCCESS(Status))
444 return(Status);
445 }
446
447 /* create ARC names for hard disk drives */
448 InitializeListHead(&BiosDiskListHead);
449 InitializeListHead(&DiskListHead);
450 IopEnumerateBiosDisks(&BiosDiskListHead);
451 IopEnumerateDisks(&DiskListHead);
452
453 RDiskNumber = 0;
454 while (!IsListEmpty(&BiosDiskListHead))
455 {
456 Entry = RemoveHeadList(&BiosDiskListHead);
457 BiosDiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
458 Entry = DiskListHead.Flink;
459 while (Entry != &DiskListHead)
460 {
461 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
462 if (DiskEntry->Checksum == BiosDiskEntry->Checksum &&
463 DiskEntry->Signature == BiosDiskEntry->Signature)
464 {
465
466 Status = IopAssignArcNamesToDisk(DiskEntry->DeviceObject, RDiskNumber, DiskEntry->DiskNumber);
467
468 RemoveEntryList(&DiskEntry->ListEntry);
469 ExFreePool(DiskEntry);
470 break;
471 }
472 Entry = Entry->Flink;
473 }
474 RDiskNumber++;
475 ExFreePool(BiosDiskEntry);
476 }
477
478 while (!IsListEmpty(&DiskListHead))
479 {
480 Entry = RemoveHeadList(&DiskListHead);
481 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
482 ExFreePool(DiskEntry);
483 }
484
485 /* create ARC names for cdrom drives */
486 DPRINT("CD-ROM drives: %lu\n", ConfigInfo->CdRomCount);
487 for (i = 0; i < ConfigInfo->CdRomCount; i++)
488 {
489 swprintf(DeviceNameBuffer,
490 L"\\Device\\CdRom%lu",
491 i);
492 RtlInitUnicodeString(&DeviceName,
493 DeviceNameBuffer);
494
495 swprintf(ArcNameBuffer,
496 L"\\ArcName\\multi(0)disk(0)cdrom(%lu)",
497 i);
498 RtlInitUnicodeString(&ArcName,
499 ArcNameBuffer);
500 DPRINT("%wZ ==> %wZ\n",
501 &ArcName,
502 &DeviceName);
503
504 Status = IoAssignArcName(&ArcName,
505 &DeviceName);
506 if (!NT_SUCCESS(Status))
507 return(Status);
508 }
509
510 DPRINT("IoCreateArcNames() done\n");
511
512 return(STATUS_SUCCESS);
513 }
514
515
516 static NTSTATUS INIT_FUNCTION
517 IopCheckCdromDevices(PULONG DeviceNumber)
518 {
519 PCONFIGURATION_INFORMATION ConfigInfo;
520 OBJECT_ATTRIBUTES ObjectAttributes;
521 UNICODE_STRING DeviceName;
522 WCHAR DeviceNameBuffer[MAX_PATH];
523 HANDLE Handle;
524 ULONG i;
525 NTSTATUS Status;
526 IO_STATUS_BLOCK IoStatusBlock;
527 #if 0
528 PFILE_FS_VOLUME_INFORMATION FileFsVolume;
529 USHORT Buffer[FS_VOLUME_BUFFER_SIZE];
530
531 FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
532 #endif
533
534 ConfigInfo = IoGetConfigurationInformation();
535 for (i = 0; i < ConfigInfo->CdRomCount; i++)
536 {
537 #if 0
538 swprintf(DeviceNameBuffer,
539 L"\\Device\\CdRom%lu\\",
540 i);
541 RtlInitUnicodeString(&DeviceName,
542 DeviceNameBuffer);
543
544 InitializeObjectAttributes(&ObjectAttributes,
545 &DeviceName,
546 0,
547 NULL,
548 NULL);
549
550 Status = ZwOpenFile(&Handle,
551 FILE_ALL_ACCESS,
552 &ObjectAttributes,
553 &IoStatusBlock,
554 0,
555 0);
556 DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
557 if (NT_SUCCESS(Status))
558 {
559 Status = ZwQueryVolumeInformationFile(Handle,
560 &IoStatusBlock,
561 FileFsVolume,
562 FS_VOLUME_BUFFER_SIZE,
563 FileFsVolumeInformation);
564 DPRINT("ZwQueryVolumeInformationFile() Status %lx\n", Status);
565 if (NT_SUCCESS(Status))
566 {
567 DPRINT("VolumeLabel: '%S'\n", FileFsVolume->VolumeLabel);
568 if (_wcsicmp(FileFsVolume->VolumeLabel, L"REACTOS") == 0)
569 {
570 ZwClose(Handle);
571 *DeviceNumber = i;
572 return(STATUS_SUCCESS);
573 }
574 }
575 ZwClose(Handle);
576 }
577 #endif
578
579 /*
580 * Check for 'reactos/ntoskrnl.exe' first...
581 */
582
583 swprintf(DeviceNameBuffer,
584 L"\\Device\\CdRom%lu\\reactos\\ntoskrnl.exe",
585 i);
586 RtlInitUnicodeString(&DeviceName,
587 DeviceNameBuffer);
588
589 InitializeObjectAttributes(&ObjectAttributes,
590 &DeviceName,
591 0,
592 NULL,
593 NULL);
594
595 Status = ZwOpenFile(&Handle,
596 FILE_ALL_ACCESS,
597 &ObjectAttributes,
598 &IoStatusBlock,
599 0,
600 0);
601 DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
602 if (NT_SUCCESS(Status))
603 {
604 DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i);
605 ZwClose(Handle);
606 *DeviceNumber = i;
607 return(STATUS_SUCCESS);
608 }
609
610 /*
611 * ...and for 'reactos/system32/ntoskrnl.exe' also.
612 */
613
614 swprintf(DeviceNameBuffer,
615 L"\\Device\\CdRom%lu\\reactos\\system32\\ntoskrnl.exe",
616 i);
617 RtlInitUnicodeString(&DeviceName,
618 DeviceNameBuffer);
619
620 InitializeObjectAttributes(&ObjectAttributes,
621 &DeviceName,
622 0,
623 NULL,
624 NULL);
625
626 Status = ZwOpenFile(&Handle,
627 FILE_ALL_ACCESS,
628 &ObjectAttributes,
629 &IoStatusBlock,
630 0,
631 0);
632 DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
633 if (NT_SUCCESS(Status))
634 {
635 DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i);
636 ZwClose(Handle);
637 *DeviceNumber = i;
638 return(STATUS_SUCCESS);
639 }
640 }
641
642 DPRINT("Could not find ntoskrnl.exe\n");
643 *DeviceNumber = (ULONG)-1;
644
645 return(STATUS_UNSUCCESSFUL);
646 }
647
648
649 NTSTATUS INIT_FUNCTION
650 IoCreateSystemRootLink(PCHAR ParameterLine)
651 {
652 OBJECT_ATTRIBUTES ObjectAttributes;
653 IO_STATUS_BLOCK IoStatusBlock;
654 UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
655 UNICODE_STRING DeviceName;
656 UNICODE_STRING ArcName;
657 UNICODE_STRING BootPath;
658 PCHAR ParamBuffer;
659 PWCHAR ArcNameBuffer;
660 PCHAR p;
661 NTSTATUS Status;
662 ULONG Length;
663 HANDLE Handle;
664
665 /* Create local parameter line copy */
666 ParamBuffer = ExAllocatePool(PagedPool, 256);
667 strcpy(ParamBuffer, (char *)ParameterLine);
668
669 DPRINT("%s\n", ParamBuffer);
670 /* Format: <arc_name>\<path> [options...] */
671
672 /* cut options off */
673 p = strchr(ParamBuffer, ' ');
674 if (p)
675 *p = 0;
676 DPRINT("%s\n", ParamBuffer);
677
678 /* extract path */
679 p = strchr(ParamBuffer, '\\');
680 if (p)
681 {
682 DPRINT("Boot path: %s\n", p);
683 RtlCreateUnicodeStringFromAsciiz(&BootPath, p);
684 *p = 0;
685 }
686 else
687 {
688 DPRINT("Boot path: %s\n", "\\");
689 RtlCreateUnicodeStringFromAsciiz(&BootPath, "\\");
690 }
691 DPRINT("ARC name: %s\n", ParamBuffer);
692
693 p = strstr(ParamBuffer, "cdrom");
694 if (p != NULL)
695 {
696 ULONG DeviceNumber;
697
698 DPRINT("Booting from CD-ROM!\n");
699 Status = IopCheckCdromDevices(&DeviceNumber);
700 if (!NT_SUCCESS(Status))
701 {
702 CPRINT("Failed to find setup disk!\n");
703 return(Status);
704 }
705
706 sprintf(p, "cdrom(%lu)", DeviceNumber);
707
708 DPRINT("New ARC name: %s\n", ParamBuffer);
709
710 /* Adjust original command line */
711 p = strstr(ParameterLine, "cdrom");
712 if (p != NULL);
713 {
714 char temp[256];
715 char *q;
716
717 q = strchr(p, ')');
718 if (q != NULL)
719 {
720
721 q++;
722 strcpy(temp, q);
723 sprintf(p, "cdrom(%lu)", DeviceNumber);
724 strcat(p, temp);
725 }
726 }
727 }
728
729 /* Only arc name left - build full arc name */
730 ArcNameBuffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
731 swprintf(ArcNameBuffer,
732 L"\\ArcName\\%S", ParamBuffer);
733 RtlInitUnicodeString(&ArcName, ArcNameBuffer);
734 DPRINT("Arc name: %wZ\n", &ArcName);
735
736 /* free ParamBuffer */
737 ExFreePool(ParamBuffer);
738
739 /* allocate device name string */
740 DeviceName.Length = 0;
741 DeviceName.MaximumLength = 256 * sizeof(WCHAR);
742 DeviceName.Buffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
743
744 InitializeObjectAttributes(&ObjectAttributes,
745 &ArcName,
746 OBJ_OPENLINK,
747 NULL,
748 NULL);
749
750 Status = ZwOpenSymbolicLinkObject(&Handle,
751 SYMBOLIC_LINK_ALL_ACCESS,
752 &ObjectAttributes);
753 if (!NT_SUCCESS(Status))
754 {
755 RtlFreeUnicodeString(&BootPath);
756 ExFreePool(DeviceName.Buffer);
757 CPRINT("ZwOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
758 &ArcName,
759 Status);
760 ExFreePool(ArcName.Buffer);
761
762 return(Status);
763 }
764 ExFreePool(ArcName.Buffer);
765
766 Status = ZwQuerySymbolicLinkObject(Handle,
767 &DeviceName,
768 &Length);
769 ZwClose (Handle);
770 if (!NT_SUCCESS(Status))
771 {
772 RtlFreeUnicodeString(&BootPath);
773 ExFreePool(DeviceName.Buffer);
774 CPRINT("ZwQuerySymbolicObject() failed (Status %x)\n",
775 Status);
776
777 return(Status);
778 }
779 DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);
780
781 RtlAppendUnicodeStringToString(&DeviceName,
782 &BootPath);
783
784 RtlFreeUnicodeString(&BootPath);
785 DPRINT("DeviceName: %wZ\n", &DeviceName);
786
787 /* create the '\SystemRoot' link */
788 Status = IoCreateSymbolicLink(&LinkName,
789 &DeviceName);
790 ExFreePool(DeviceName.Buffer);
791 if (!NT_SUCCESS(Status))
792 {
793 CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
794 Status);
795
796 return(Status);
797 }
798
799 /* Check whether '\SystemRoot'(LinkName) can be opened */
800 InitializeObjectAttributes(&ObjectAttributes,
801 &LinkName,
802 0,
803 NULL,
804 NULL);
805
806 Status = ZwOpenFile(&Handle,
807 FILE_ALL_ACCESS,
808 &ObjectAttributes,
809 &IoStatusBlock,
810 0,
811 0);
812 if (!NT_SUCCESS(Status))
813 {
814 CPRINT("ZwOpenFile() failed to open '\\SystemRoot' (Status %x)\n",
815 Status);
816 return(Status);
817 }
818
819 ZwClose(Handle);
820
821 return(STATUS_SUCCESS);
822 }
823
824 /* EOF */