3 * Copyright (C) 2002 ReactOS Team
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.
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.
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.
19 /* $Id: arcname.c,v 1.16 2003/11/17 02:12:51 hyperion Exp $
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)
29 /* INCLUDES *****************************************************************/
31 #include <ddk/ntddk.h>
32 #include <rosrtl/string.h>
34 #include "internal/io.h"
35 #include "internal/xhal.h"
38 #include <internal/debug.h>
40 /* MACROS *******************************************************************/
42 #define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
44 /* FUNCTIONS ****************************************************************/
46 NTSTATUS INIT_FUNCTION
47 IoCreateArcNames(VOID
)
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
;
58 DPRINT("IoCreateArcNames() called\n");
60 ConfigInfo
= IoGetConfigurationInformation();
62 /* create ARC names for floppy drives */
63 DPRINT("Floppy drives: %lu\n", ConfigInfo
->FloppyCount
);
64 for (i
= 0; i
< ConfigInfo
->FloppyCount
; i
++)
66 swprintf(DeviceNameBuffer
,
67 L
"\\Device\\Floppy%lu",
69 RtlInitUnicodeString(&DeviceName
,
72 swprintf(ArcNameBuffer
,
73 L
"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
75 RtlInitUnicodeString(&ArcName
,
77 DPRINT("%wZ ==> %wZ\n",
81 Status
= IoAssignArcName(&ArcName
,
83 if (!NT_SUCCESS(Status
))
87 /* create ARC names for hard disk drives */
88 DPRINT("Disk drives: %lu\n", ConfigInfo
->DiskCount
);
89 for (i
= 0; i
< ConfigInfo
->DiskCount
; i
++)
91 swprintf(DeviceNameBuffer
,
92 L
"\\Device\\Harddisk%lu\\Partition0",
94 RtlInitUnicodeString(&DeviceName
,
97 swprintf(ArcNameBuffer
,
98 L
"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(0)",
100 RtlInitUnicodeString(&ArcName
,
102 DPRINT("%wZ ==> %wZ\n",
106 Status
= IoAssignArcName(&ArcName
,
108 if (!NT_SUCCESS(Status
))
111 Status
= xHalQueryDriveLayout(&DeviceName
,
113 if (!NT_SUCCESS(Status
))
116 DPRINT("Number of partitions: %u\n", LayoutInfo
->PartitionCount
);
118 for (j
= 0;j
< LayoutInfo
->PartitionCount
; j
++)
120 swprintf(DeviceNameBuffer
,
121 L
"\\Device\\Harddisk%lu\\Partition%lu",
124 RtlInitUnicodeString(&DeviceName
,
127 swprintf(ArcNameBuffer
,
128 L
"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
131 RtlInitUnicodeString(&ArcName
,
133 DPRINT("%wZ ==> %wZ\n",
137 Status
= IoAssignArcName(&ArcName
,
139 if (!NT_SUCCESS(Status
))
143 ExFreePool(LayoutInfo
);
147 /* create ARC names for cdrom drives */
148 DPRINT("CD-ROM drives: %lu\n", ConfigInfo
->CdRomCount
);
149 for (i
= 0; i
< ConfigInfo
->CdRomCount
; i
++)
151 swprintf(DeviceNameBuffer
,
152 L
"\\Device\\CdRom%lu",
154 RtlInitUnicodeString(&DeviceName
,
157 swprintf(ArcNameBuffer
,
158 L
"\\ArcName\\multi(0)disk(0)cdrom(%lu)",
160 RtlInitUnicodeString(&ArcName
,
162 DPRINT("%wZ ==> %wZ\n",
166 Status
= IoAssignArcName(&ArcName
,
168 if (!NT_SUCCESS(Status
))
172 DPRINT("IoCreateArcNames() done\n");
174 return(STATUS_SUCCESS
);
179 IopCheckCdromDevices(PULONG DeviceNumber
)
181 PCONFIGURATION_INFORMATION ConfigInfo
;
182 OBJECT_ATTRIBUTES ObjectAttributes
;
183 UNICODE_STRING DeviceName
;
184 WCHAR DeviceNameBuffer
[MAX_PATH
];
188 IO_STATUS_BLOCK IoStatusBlock
;
190 PFILE_FS_VOLUME_INFORMATION FileFsVolume
;
191 USHORT Buffer
[FS_VOLUME_BUFFER_SIZE
];
193 FileFsVolume
= (PFILE_FS_VOLUME_INFORMATION
)Buffer
;
196 ConfigInfo
= IoGetConfigurationInformation();
197 for (i
= 0; i
< ConfigInfo
->CdRomCount
; i
++)
200 swprintf(DeviceNameBuffer
,
201 L
"\\Device\\CdRom%lu\\",
203 RtlInitUnicodeString(&DeviceName
,
206 InitializeObjectAttributes(&ObjectAttributes
,
212 Status
= NtOpenFile(&Handle
,
218 DPRINT("NtOpenFile() DeviceNumber %lu Status %lx\n", i
, Status
);
219 if (NT_SUCCESS(Status
))
221 Status
= NtQueryVolumeInformationFile(Handle
,
224 FS_VOLUME_BUFFER_SIZE
,
225 FileFsVolumeInformation
);
226 DPRINT("NtQueryVolumeInformationFile() Status %lx\n", Status
);
227 if (NT_SUCCESS(Status
))
229 DPRINT("VolumeLabel: '%S'\n", FileFsVolume
->VolumeLabel
);
230 if (_wcsicmp(FileFsVolume
->VolumeLabel
, L
"REACTOS") == 0)
234 return(STATUS_SUCCESS
);
241 swprintf(DeviceNameBuffer
,
242 L
"\\Device\\CdRom%lu\\reactos\\ntoskrnl.exe",
244 RtlInitUnicodeString(&DeviceName
,
247 InitializeObjectAttributes(&ObjectAttributes
,
253 Status
= NtOpenFile(&Handle
,
259 DPRINT("NtOpenFile() DeviceNumber %lu Status %lx\n", i
, Status
);
260 if (NT_SUCCESS(Status
))
262 DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i
);
265 return(STATUS_SUCCESS
);
270 DPRINT("Could not find ntoskrnl.exe\n");
271 *DeviceNumber
= (ULONG
)-1;
273 return(STATUS_UNSUCCESSFUL
);
277 NTSTATUS INIT_FUNCTION
278 IoCreateSystemRootLink(PCHAR ParameterLine
)
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
;
287 PWCHAR ArcNameBuffer
;
293 /* Create local parameter line copy */
294 ParamBuffer
= ExAllocatePool(PagedPool
, 256);
295 strcpy(ParamBuffer
, (char *)ParameterLine
);
297 DPRINT("%s\n", ParamBuffer
);
298 /* Format: <arc_name>\<path> [options...] */
300 /* cut options off */
301 p
= strchr(ParamBuffer
, ' ');
304 DPRINT("%s\n", ParamBuffer
);
307 p
= strchr(ParamBuffer
, '\\');
310 DPRINT("Boot path: %s\n", p
);
311 RtlCreateUnicodeStringFromAsciiz(&BootPath
, p
);
316 DPRINT("Boot path: %s\n", "\\");
317 RtlCreateUnicodeStringFromAsciiz(&BootPath
, "\\");
319 DPRINT("ARC name: %s\n", ParamBuffer
);
321 p
= strstr(ParamBuffer
, "cdrom");
326 DPRINT("Booting from CD-ROM!\n");
327 Status
= IopCheckCdromDevices(&DeviceNumber
);
328 if (!NT_SUCCESS(Status
))
330 CPRINT("Failed to find setup disk!\n");
334 sprintf(p
, "cdrom(%lu)", DeviceNumber
);
336 DPRINT("New ARC name: %s\n", ParamBuffer
);
338 /* Adjust original command line */
339 p
= strstr(ParameterLine
, "cdrom");
351 sprintf(p
, "cdrom(%lu)", DeviceNumber
);
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
);
364 /* free ParamBuffer */
365 ExFreePool(ParamBuffer
);
367 /* allocate device name string */
368 DeviceName
.Length
= 0;
369 DeviceName
.MaximumLength
= 256 * sizeof(WCHAR
);
370 DeviceName
.Buffer
= ExAllocatePool(PagedPool
, 256 * sizeof(WCHAR
));
372 InitializeObjectAttributes(&ObjectAttributes
,
378 Status
= NtOpenSymbolicLinkObject(&Handle
,
379 SYMBOLIC_LINK_ALL_ACCESS
,
381 if (!NT_SUCCESS(Status
))
383 RtlFreeUnicodeString(&BootPath
);
384 RtlFreeUnicodeString(&DeviceName
);
385 CPRINT("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
388 RtlFreeUnicodeString(&ArcName
);
392 RtlFreeUnicodeString(&ArcName
);
394 Status
= NtQuerySymbolicLinkObject(Handle
,
398 if (!NT_SUCCESS(Status
))
400 RtlFreeUnicodeString(&BootPath
);
401 RtlFreeUnicodeString(&DeviceName
);
402 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
407 DPRINT("Length: %lu DeviceName: %wZ\n", Length
, &DeviceName
);
409 RtlAppendUnicodeStringToString(&DeviceName
,
412 RtlFreeUnicodeString(&BootPath
);
413 DPRINT("DeviceName: %wZ\n", &DeviceName
);
415 /* create the '\SystemRoot' link */
416 RtlRosInitUnicodeStringFromLiteral(&LinkName
,
419 Status
= IoCreateSymbolicLink(&LinkName
,
421 RtlFreeUnicodeString (&DeviceName
);
422 if (!NT_SUCCESS(Status
))
424 CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
430 /* Check whether '\SystemRoot'(LinkName) can be opened */
431 InitializeObjectAttributes(&ObjectAttributes
,
437 Status
= NtOpenFile(&Handle
,
443 if (!NT_SUCCESS(Status
))
445 CPRINT("NtOpenFile() failed to open '\\SystemRoot' (Status %x)\n",
452 return(STATUS_SUCCESS
);