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.
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>
33 #include "internal/io.h"
34 #include "internal/xhal.h"
37 #include <internal/debug.h>
39 /* MACROS *******************************************************************/
41 #define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
43 /* FUNCTIONS ****************************************************************/
46 IoCreateArcNames(VOID)
48 PCONFIGURATION_INFORMATION ConfigInfo;
49 PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
50 WCHAR DeviceNameBuffer[80];
51 WCHAR ArcNameBuffer[80];
52 UNICODE_STRING DeviceName;
53 UNICODE_STRING ArcName;
57 DPRINT("IoCreateArcNames() called\n");
59 ConfigInfo = IoGetConfigurationInformation();
61 /* create ARC names for floppy drives */
62 DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
63 for (i = 0; i < ConfigInfo->FloppyCount; i++)
65 swprintf(DeviceNameBuffer,
66 L"\\Device\\Floppy%lu",
68 RtlInitUnicodeString(&DeviceName,
71 swprintf(ArcNameBuffer,
72 L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
74 RtlInitUnicodeString(&ArcName,
76 DPRINT("%wZ ==> %wZ\n",
80 Status = IoAssignArcName(&ArcName,
82 if (!NT_SUCCESS(Status))
86 /* create ARC names for hard disk drives */
87 DPRINT("Disk drives: %lu\n", ConfigInfo->DiskCount);
88 for (i = 0; i < ConfigInfo->DiskCount; i++)
90 swprintf(DeviceNameBuffer,
91 L"\\Device\\Harddisk%lu\\Partition0",
93 RtlInitUnicodeString(&DeviceName,
96 swprintf(ArcNameBuffer,
97 L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(0)",
99 RtlInitUnicodeString(&ArcName,
101 DPRINT("%wZ ==> %wZ\n",
105 Status = IoAssignArcName(&ArcName,
107 if (!NT_SUCCESS(Status))
110 Status = xHalQueryDriveLayout(&DeviceName,
112 if (!NT_SUCCESS(Status))
115 DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);
117 for (j = 0;j < LayoutInfo->PartitionCount; j++)
119 swprintf(DeviceNameBuffer,
120 L"\\Device\\Harddisk%lu\\Partition%lu",
123 RtlInitUnicodeString(&DeviceName,
126 swprintf(ArcNameBuffer,
127 L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
130 RtlInitUnicodeString(&ArcName,
132 DPRINT("%wZ ==> %wZ\n",
136 Status = IoAssignArcName(&ArcName,
138 if (!NT_SUCCESS(Status))
142 ExFreePool(LayoutInfo);
146 /* create ARC names for cdrom drives */
147 DPRINT("CD-ROM drives: %lu\n", ConfigInfo->CDRomCount);
148 for (i = 0; i < ConfigInfo->CDRomCount; i++)
150 swprintf(DeviceNameBuffer,
151 L"\\Device\\CdRom%lu",
153 RtlInitUnicodeString(&DeviceName,
156 swprintf(ArcNameBuffer,
157 L"\\ArcName\\multi(0)disk(0)cdrom(%lu)",
159 RtlInitUnicodeString(&ArcName,
161 DPRINT("%wZ ==> %wZ\n",
165 Status = IoAssignArcName(&ArcName,
167 if (!NT_SUCCESS(Status))
171 DPRINT("IoCreateArcNames() done\n");
173 return(STATUS_SUCCESS);
178 IopCheckCdromDevices(PULONG DeviceNumber)
180 PFILE_FS_VOLUME_INFORMATION FileFsVolume;
181 PCONFIGURATION_INFORMATION ConfigInfo;
182 OBJECT_ATTRIBUTES ObjectAttributes;
183 UNICODE_STRING DeviceName;
184 WCHAR DeviceNameBuffer[32];
188 IO_STATUS_BLOCK IoStatusBlock;
189 USHORT Buffer[FS_VOLUME_BUFFER_SIZE];
191 FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
193 ConfigInfo = IoGetConfigurationInformation();
194 for (i = 0; i < ConfigInfo->CDRomCount; i++)
196 swprintf(DeviceNameBuffer,
197 L"\\Device\\CdRom%lu\\",
199 RtlInitUnicodeString(&DeviceName,
202 InitializeObjectAttributes(&ObjectAttributes,
208 Status = NtOpenFile(&Handle,
214 DPRINT("NtOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
215 if (NT_SUCCESS(Status))
217 Status = NtQueryVolumeInformationFile(Handle,
220 FS_VOLUME_BUFFER_SIZE,
221 FileFsVolumeInformation);
222 DPRINT("NtQueryVolumeInformationFile() Status %lx\n", Status);
223 if (NT_SUCCESS(Status))
225 DPRINT("VolumeLabel: '%S'\n", FileFsVolume->VolumeLabel);
226 if (_wcsicmp(FileFsVolume->VolumeLabel, L"REACTOS") == 0)
230 return(STATUS_SUCCESS);
237 *DeviceNumber = (ULONG)-1;
239 return(STATUS_UNSUCCESSFUL);
244 IoCreateSystemRootLink(PCHAR ParameterLine)
246 OBJECT_ATTRIBUTES ObjectAttributes;
247 UNICODE_STRING LinkName;
248 UNICODE_STRING DeviceName;
249 UNICODE_STRING ArcName;
250 UNICODE_STRING BootPath;
252 PWCHAR ArcNameBuffer;
258 /* Create local parameter line copy */
259 ParamBuffer = ExAllocatePool(PagedPool, 256);
260 strcpy(ParamBuffer, (char *)ParameterLine);
262 DPRINT("%s\n", ParamBuffer);
263 /* Format: <arc_name>\<path> [options...] */
265 /* cut options off */
266 p = strchr(ParamBuffer, ' ');
269 DPRINT("%s\n", ParamBuffer);
272 p = strchr(ParamBuffer, '\\');
275 DPRINT("Boot path: %s\n", p);
276 RtlCreateUnicodeStringFromAsciiz(&BootPath, p);
281 DPRINT("Boot path: %s\n", "\\");
282 RtlCreateUnicodeStringFromAsciiz(&BootPath, "\\");
284 DPRINT("ARC name: %s\n", ParamBuffer);
286 p = strstr(ParamBuffer, "cdrom");
291 DPRINT("Booting from CD-ROM!\n");
292 Status = IopCheckCdromDevices(&DeviceNumber);
293 if (!NT_SUCCESS(Status))
295 CPRINT("Failed to find setup disk!\n");
299 sprintf(p, "cdrom(%lu)", DeviceNumber);
301 DPRINT("New ARC name: %s\n", ParamBuffer);
303 /* Adjust original command line */
304 p = strstr(ParameterLine, "cdrom");
316 sprintf(p, "cdrom(%lu)", DeviceNumber);
322 /* Only arc name left - build full arc name */
323 ArcNameBuffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
324 swprintf(ArcNameBuffer,
325 L"\\ArcName\\%S", ParamBuffer);
326 RtlInitUnicodeString(&ArcName, ArcNameBuffer);
327 DPRINT("Arc name: %wZ\n", &ArcName);
329 /* free ParamBuffer */
330 ExFreePool(ParamBuffer);
332 /* allocate device name string */
333 DeviceName.Length = 0;
334 DeviceName.MaximumLength = 256 * sizeof(WCHAR);
335 DeviceName.Buffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
337 InitializeObjectAttributes(&ObjectAttributes,
343 Status = NtOpenSymbolicLinkObject(&Handle,
344 SYMBOLIC_LINK_ALL_ACCESS,
346 if (!NT_SUCCESS(Status))
348 RtlFreeUnicodeString(&BootPath);
349 RtlFreeUnicodeString(&DeviceName);
350 CPRINT("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
353 RtlFreeUnicodeString(&ArcName);
357 RtlFreeUnicodeString(&ArcName);
359 Status = NtQuerySymbolicLinkObject(Handle,
363 if (!NT_SUCCESS(Status))
365 RtlFreeUnicodeString(&BootPath);
366 RtlFreeUnicodeString(&DeviceName);
367 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
372 DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);
374 RtlAppendUnicodeStringToString(&DeviceName,
377 RtlFreeUnicodeString(&BootPath);
378 DPRINT("DeviceName: %wZ\n", &DeviceName);
380 /* create the '\SystemRoot' link */
381 RtlInitUnicodeStringFromLiteral(&LinkName,
384 Status = IoCreateSymbolicLink(&LinkName,
386 RtlFreeUnicodeString (&DeviceName);
387 if (!NT_SUCCESS(Status))
389 CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
395 /* Check whether '\SystemRoot'(LinkName) can be opened */
396 InitializeObjectAttributes(&ObjectAttributes,
402 Status = NtOpenFile(&Handle,
408 if (!NT_SUCCESS(Status))
410 CPRINT("NtOpenFile() failed to open '\\SystemRoot' (Status %x)\n",
417 return(STATUS_SUCCESS);