ReactOS 0.4.15-dev-7918-g2a2556c
arcname.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for arcname.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI IopCreateArcNamesCd (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI IopCreateArcNamesDisk (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN BOOLEAN SingleDisk, OUT PBOOLEAN FoundBoot)
 
NTSTATUS NTAPI IopCreateArcNames (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI IopReassignSystemRoot (IN PLOADER_PARAMETER_BLOCK LoaderBlock, OUT PANSI_STRING NtBootPath)
 
BOOLEAN NTAPI IopVerifyDiskSignature (IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout, IN PARC_DISK_SIGNATURE ArcDiskSignature, OUT PULONG Signature)
 

Variables

UNICODE_STRING IoArcHalDeviceName
 
UNICODE_STRING IoArcBootDeviceName
 
PCHAR IoLoaderArcBootDeviceName
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file arcname.c.

Function Documentation

◆ IopCreateArcNames()

NTSTATUS NTAPI IopCreateArcNames ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 39 of file arcname.c.

40{
43 CHAR Buffer[128];
44 BOOLEAN SingleDisk;
45 BOOLEAN FoundBoot = FALSE;
46 UNICODE_STRING SystemDevice, LoaderPathNameW, BootDeviceName;
47 PARC_DISK_INFORMATION ArcDiskInfo = LoaderBlock->ArcDiskInformation;
48 ANSI_STRING ArcSystemString, ArcString, LanmanRedirector, LoaderPathNameA;
49
50 /* Check if we only have one disk on the machine */
51 SingleDisk = (ArcDiskInfo->DiskSignatureListHead.Flink->Flink ==
52 &ArcDiskInfo->DiskSignatureListHead);
53
54 /* Create the global HAL partition name */
55 sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcHalDeviceName);
56 RtlInitAnsiString(&ArcString, Buffer);
58 if (!NT_SUCCESS(Status))
59 return Status;
60
61 /* Create the global system partition name */
62 sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
63 RtlInitAnsiString(&ArcString, Buffer);
65 if (!NT_SUCCESS(Status))
66 return Status;
67
68 /* Allocate memory for the string */
69 Length = strlen(LoaderBlock->ArcBootDeviceName) + sizeof(ANSI_NULL);
71 Length,
72 TAG_IO);
74 {
75 /* Copy the name */
77 LoaderBlock->ArcBootDeviceName,
78 Length);
79 }
80
81 /* Check if we only found a disk, but we're booting from CD-ROM */
82 if ((SingleDisk) && strstr(LoaderBlock->ArcBootDeviceName, "cdrom"))
83 {
84 /* Then disable single-disk mode, since there's a CD drive out there */
85 SingleDisk = FALSE;
86 }
87
88 /* Build the boot strings */
89 RtlInitAnsiString(&ArcSystemString, LoaderBlock->ArcHalDeviceName);
90
91 /* If we are doing remote booting */
93 {
94 /* Yes, we have found boot device */
95 FoundBoot = TRUE;
96
97 /* Get NT device name */
98 RtlInitAnsiString(&LanmanRedirector, "\\Device\\LanmanRedirector");
99 Status = RtlAnsiStringToUnicodeString(&SystemDevice, &LanmanRedirector, TRUE);
100 if (!NT_SUCCESS(Status))
101 {
102 return Status;
103 }
104
105 /* Get ARC booting device name (in net(0) something) */
106 sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
107 RtlInitAnsiString(&ArcString, Buffer);
108 Status = RtlAnsiStringToUnicodeString(&BootDeviceName, &ArcString, TRUE);
109 if (NT_SUCCESS(Status))
110 {
111 /* Map ARC to NT name */
112 IoAssignArcName(&BootDeviceName, &SystemDevice);
113 RtlFreeUnicodeString(&BootDeviceName);
114
115 /* Now, get loader path name */
116 RtlInitAnsiString(&LoaderPathNameA, LoaderBlock->NtHalPathName);
117 Status = RtlAnsiStringToUnicodeString(&LoaderPathNameW, &LoaderPathNameA, TRUE);
118 if (!NT_SUCCESS(Status))
119 {
120 RtlFreeUnicodeString(&SystemDevice);
121 return Status;
122 }
123
124 /* And set it has system partition */
125 IopStoreSystemPartitionInformation(&SystemDevice, &LoaderPathNameW);
126 }
127
128 RtlFreeUnicodeString(&SystemDevice);
129
130 /* Don't quit here, even if everything went fine!
131 * We need IopCreateArcNamesDisk to properly map
132 * devices with symlinks.
133 * It will return success if the mapping process went fine
134 * even if it didn't find boot device.
135 * It won't reset boot device finding status as well.
136 */
137 }
138
139 /* Loop every disk and try to find boot disk */
140 Status = IopCreateArcNamesDisk(LoaderBlock, SingleDisk, &FoundBoot);
141 /* If it succeeded but we didn't find boot device, try to browse Cds */
142 if (NT_SUCCESS(Status) && !FoundBoot)
143 {
144 Status = IopCreateArcNamesCd(LoaderBlock);
145 }
146
147 /* Return success */
148 return Status;
149}
unsigned char BOOLEAN
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
#define sprintf(buf, format,...)
Definition: sprintf.c:55
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
BOOLEAN IoRemoteBootClient
Definition: init.c:70
VOID IopStoreSystemPartitionInformation(_In_ PUNICODE_STRING NtSystemPartitionDeviceName, _In_ PUNICODE_STRING OsLoaderPathName)
Definition: iorsrce.c:860
NTSTATUS NTAPI IopCreateArcNamesDisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN BOOLEAN SingleDisk, OUT PBOOLEAN FoundBoot)
Definition: arcname.c:416
NTSTATUS NTAPI IopCreateArcNamesCd(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: arcname.c:154
UNICODE_STRING IoArcHalDeviceName
Definition: arcname.c:19
UNICODE_STRING IoArcBootDeviceName
Definition: arcname.c:19
PCHAR IoLoaderArcBootDeviceName
Definition: arcname.c:20
LIST_ENTRY DiskSignatureListHead
Definition: arc.h:268
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TAG_IO
Definition: tag.h:80
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IoAssignArcName(_ArcName, _DeviceName)
char CHAR
Definition: xmlstorage.h:175

Referenced by IoInitSystem().

◆ IopCreateArcNamesCd()

NTSTATUS NTAPI IopCreateArcNamesCd ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 154 of file arcname.c.

155{
156 PIRP Irp;
159 PLIST_ENTRY NextEntry;
165 CHAR Buffer[128], ArcBuffer[128];
166 BOOLEAN NotEnabledPresent = FALSE;
168 ANSI_STRING DeviceStringA, ArcNameStringA;
169 PWSTR SymbolicLinkList, lSymbolicLinkList;
170 PARC_DISK_SIGNATURE ArcDiskSignature = NULL;
171 UNICODE_STRING DeviceStringW, ArcNameStringW;
172 ULONG DiskNumber, CdRomCount, CheckSum, i, EnabledDisks = 0;
173 PARC_DISK_INFORMATION ArcDiskInformation = LoaderBlock->ArcDiskInformation;
174
175 /* Get all the Cds present in the system */
177
178 /* Get enabled Cds and check if result matches
179 * For the record, enabled Cds (or even disk) are Cds/disks
180 * that have been successfully handled by MountMgr driver
181 * and that already own their device name. This is the "new" way
182 * to handle them, that came with NT5.
183 * Currently, Windows 2003 provides an ARC names creation based
184 * on both enabled drives and not enabled drives (lack from
185 * the driver).
186 * Given the current ReactOS state, that's good for us.
187 * To sum up, this is NOT a hack or whatsoever.
188 */
190 GUID_DEVINTERFACE_CDROM,
191 CdRomCount,
192 &EnabledDisks);
193 if (!NT_SUCCESS(Status))
194 {
195 NotEnabledPresent = TRUE;
196 }
197 /* Save symbolic link list address in order to free it after */
198 lSymbolicLinkList = SymbolicLinkList;
199 /* For the moment, we won't fail */
201
202 /* Browse all the ARC devices trying to find the one matching boot device */
203 for (NextEntry = ArcDiskInformation->DiskSignatureListHead.Flink;
204 NextEntry != &ArcDiskInformation->DiskSignatureListHead;
205 NextEntry = NextEntry->Flink)
206 {
207 ArcDiskSignature = CONTAINING_RECORD(NextEntry,
209 ListEntry);
210
211 if (strcmp(LoaderBlock->ArcBootDeviceName, ArcDiskSignature->ArcName) == 0)
212 {
213 break;
214 }
215
216 ArcDiskSignature = NULL;
217 }
218
219 /* Not found... Not booting from a Cd */
220 if (!ArcDiskSignature)
221 {
222 DPRINT("Failed finding a cd that could match current boot device\n");
223 goto Cleanup;
224 }
225
226 /* Allocate needed space for reading Cd */
228 if (!PartitionBuffer)
229 {
230 DPRINT("Failed allocating resources!\n");
231 /* Here, we fail, BUT we return success, some Microsoft joke */
232 goto Cleanup;
233 }
234
235 /* If we have more enabled Cds, take that into account */
236 if (EnabledDisks > CdRomCount)
237 {
238 CdRomCount = EnabledDisks;
239 }
240
241 /* If we'll have to browse for none enabled Cds, fix higher count */
242 if (NotEnabledPresent && !EnabledDisks)
243 {
244 CdRomCount += 5;
245 }
246
247 /* Finally, if in spite of all that work, we still don't have Cds, leave */
248 if (!CdRomCount)
249 {
250 goto Cleanup;
251 }
252
253 /* Start browsing Cds */
254 for (DiskNumber = 0, EnabledDisks = 0; DiskNumber < CdRomCount; DiskNumber++)
255 {
256 /* Check if we have an enabled disk */
257 if (lSymbolicLinkList && *lSymbolicLinkList != UNICODE_NULL)
258 {
259 /* Create its device name using first symbolic link */
260 RtlInitUnicodeString(&DeviceStringW, lSymbolicLinkList);
261 /* Then, update symbolic links list */
262 lSymbolicLinkList += wcslen(lSymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR));
263
264 /* Get its associated device object and file object */
265 Status = IoGetDeviceObjectPointer(&DeviceStringW,
267 &FileObject,
268 &DeviceObject);
269 /* Failure? Good bye! */
270 if (!NT_SUCCESS(Status))
271 {
272 goto Cleanup;
273 }
274
275 /* Now, we'll ask the device its device number */
278 NULL,
279 0,
281 sizeof(DeviceNumber),
282 FALSE,
283 &Event,
285 /* Failure? Good bye! */
286 if (!Irp)
287 {
288 /* Dereference file object before leaving */
291 goto Cleanup;
292 }
293
294 /* Call the driver, and wait for it if needed */
297 if (Status == STATUS_PENDING)
298 {
301 }
302 if (!NT_SUCCESS(Status))
303 {
305 goto Cleanup;
306 }
307
308 /* Finally, build proper device name */
309 sprintf(Buffer, "\\Device\\CdRom%lu", DeviceNumber.DeviceNumber);
310 RtlInitAnsiString(&DeviceStringA, Buffer);
311 Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
312 if (!NT_SUCCESS(Status))
313 {
315 goto Cleanup;
316 }
317 }
318 else
319 {
320 /* Create device name for the cd */
321 sprintf(Buffer, "\\Device\\CdRom%lu", EnabledDisks++);
322 RtlInitAnsiString(&DeviceStringA, Buffer);
323 Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
324 if (!NT_SUCCESS(Status))
325 {
326 goto Cleanup;
327 }
328
329 /* Get its device object */
330 Status = IoGetDeviceObjectPointer(&DeviceStringW,
332 &FileObject,
333 &DeviceObject);
334 if (!NT_SUCCESS(Status))
335 {
336 RtlFreeUnicodeString(&DeviceStringW);
337 goto Cleanup;
338 }
339 }
340
341 /* Initiate data for reading cd and compute checksum */
342 StartingOffset.QuadPart = 0x8000;
343 CheckSum = 0;
347 2048,
349 &Event,
351 if (Irp)
352 {
353 /* Call the driver, and wait for it if needed */
356 if (Status == STATUS_PENDING)
357 {
360 }
361
362 /* If reading succeeded, compute checksum by adding data, 2048 bytes checksum */
363 if (NT_SUCCESS(Status))
364 {
365 for (i = 0; i < 2048 / sizeof(ULONG); i++)
366 {
367 CheckSum += PartitionBuffer[i];
368 }
369 }
370 }
371
372 /* Dereference file object */
374
375 /* If checksums are matching, we have the proper cd */
376 if (CheckSum + ArcDiskSignature->CheckSum == 0)
377 {
378 /* Create ARC name */
379 sprintf(ArcBuffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
380 RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
381 Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE);
382 if (NT_SUCCESS(Status))
383 {
384 /* Create symbolic link */
385 IoAssignArcName(&ArcNameStringW, &DeviceStringW);
386 RtlFreeUnicodeString(&ArcNameStringW);
387 DPRINT("Boot device found\n");
388 }
389
390 /* And quit, whatever happens */
391 RtlFreeUnicodeString(&DeviceStringW);
392 goto Cleanup;
393 }
394
395 /* Free string before trying another disk */
396 RtlFreeUnicodeString(&DeviceStringW);
397 }
398
399Cleanup:
400 if (PartitionBuffer)
401 {
403 }
404
406 {
408 }
409
410 return Status;
411}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
static const WCHAR Cleanup[]
Definition: register.c:80
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPoolCacheAligned
Definition: env_spec_w32.h:310
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define KernelMode
Definition: asm.h:34
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNICODE_NULL
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
@ NotificationEvent
NTSTATUS IopFetchConfigurationInformation(_Out_ PWSTR *SymbolicLinkList, _In_ GUID Guid, _In_ ULONG ExpectedInterfaces, _Out_ PULONG Interfaces)
Definition: iorsrce.c:821
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
ULONG CheckSum
Definition: arc.h:258
PCHAR ArcName
Definition: arc.h:257
Definition: typedefs.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_opt_ PDEVICE_OBJECT _In_ ULONG _Outptr_result_nullonfailure_ _At_ * SymbolicLinkList(return==0, __drv_allocatesMem(Mem))) PZZWSTR *SymbolicLinkList
_In_ ULONG _In_ BOOLEAN _Out_ struct _DRIVE_LAYOUT_INFORMATION ** PartitionBuffer
Definition: iofuncs.h:2052
* PFILE_OBJECT
Definition: iotypes.h:1998
@ Executive
Definition: ketypes.h:415
#define ObDereferenceObject
Definition: obfuncs.h:203
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by IopCreateArcNames().

◆ IopCreateArcNamesDisk()

NTSTATUS NTAPI IopCreateArcNamesDisk ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN BOOLEAN  SingleDisk,
OUT PBOOLEAN  FoundBoot 
)

Definition at line 416 of file arcname.c.

419{
420 PIRP Irp;
421 PVOID Data;
424 PLIST_ENTRY NextEntry;
426 DISK_GEOMETRY DiskGeometry;
431 CHAR Buffer[128], ArcBuffer[128];
432 BOOLEAN NotEnabledPresent = FALSE;
434 PARC_DISK_SIGNATURE ArcDiskSignature;
435 PWSTR SymbolicLinkList, lSymbolicLinkList;
436 PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = NULL;
437 UNICODE_STRING DeviceStringW, ArcNameStringW, HalPathStringW;
438 ULONG DiskNumber, DiskCount, CheckSum, i, Signature, EnabledDisks = 0;
439 PARC_DISK_INFORMATION ArcDiskInformation = LoaderBlock->ArcDiskInformation;
440 ANSI_STRING ArcBootString, ArcSystemString, DeviceStringA, ArcNameStringA, HalPathStringA;
441
442 /* Initialise device number */
443 DeviceNumber.DeviceNumber = ULONG_MAX;
444 /* Get all the disks present in the system */
446
447 /* Get enabled disks and check if result matches */
449 GUID_DEVINTERFACE_DISK,
450 DiskCount,
451 &EnabledDisks);
452 if (!NT_SUCCESS(Status))
453 {
454 NotEnabledPresent = TRUE;
455 }
456
457 /* Save symbolic link list address in order to free it after */
458 lSymbolicLinkList = SymbolicLinkList;
459
460 /* Build the boot strings */
461 RtlInitAnsiString(&ArcBootString, LoaderBlock->ArcBootDeviceName);
462 RtlInitAnsiString(&ArcSystemString, LoaderBlock->ArcHalDeviceName);
463
464 /* If we have more enabled disks, take that into account */
465 if (EnabledDisks > DiskCount)
466 {
467 DiskCount = EnabledDisks;
468 }
469
470 /* If we'll have to browse for none enabled disks, fix higher count */
471 if (NotEnabledPresent && !EnabledDisks)
472 {
473 DiskCount += 20;
474 }
475
476 /* Finally, if in spite of all that work, we still don't have disks, leave */
477 if (!DiskCount)
478 {
479 goto Cleanup;
480 }
481
482 /* Start browsing disks */
483 for (DiskNumber = 0; DiskNumber < DiskCount; DiskNumber++)
484 {
485 ASSERT(DriveLayout == NULL);
486
487 /* Check if we have an enabled disk */
488 if (lSymbolicLinkList && *lSymbolicLinkList != UNICODE_NULL)
489 {
490 /* Create its device name using first symbolic link */
491 RtlInitUnicodeString(&DeviceStringW, lSymbolicLinkList);
492 /* Then, update symbolic links list */
493 lSymbolicLinkList += wcslen(lSymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR));
494
495 /* Get its associated device object and file object */
496 Status = IoGetDeviceObjectPointer(&DeviceStringW,
498 &FileObject,
499 &DeviceObject);
500 if (NT_SUCCESS(Status))
501 {
502 /* Now, we'll ask the device its device number */
505 NULL,
506 0,
508 sizeof(DeviceNumber),
509 FALSE,
510 &Event,
512 /* Missing resources is a shame... No need to go farther */
513 if (!Irp)
514 {
517 goto Cleanup;
518 }
519
520 /* Call the driver, and wait for it if needed */
523 if (Status == STATUS_PENDING)
524 {
527 }
528
529 /* If we didn't get the appriopriate data, just skip that disk */
530 if (!NT_SUCCESS(Status))
531 {
533 continue;
534 }
535 }
536
537 /* End of enabled disks enumeration */
538 if (NotEnabledPresent && *lSymbolicLinkList == UNICODE_NULL)
539 {
540 /* No enabled disk worked, reset field */
541 if (DeviceNumber.DeviceNumber == ULONG_MAX)
542 {
543 DeviceNumber.DeviceNumber = 0;
544 }
545
546 /* Update disk number to enable the following not enabled disks */
547 if (DeviceNumber.DeviceNumber > DiskNumber)
548 {
549 DiskNumber = DeviceNumber.DeviceNumber;
550 }
551
552 /* Increase a bit more */
553 DiskCount = DiskNumber + 20;
554 }
555 }
556 else
557 {
558 /* Create device name for the disk */
559 sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", DiskNumber);
560 RtlInitAnsiString(&DeviceStringA, Buffer);
561 Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
562 if (!NT_SUCCESS(Status))
563 {
564 goto Cleanup;
565 }
566
567 /* Get its device object */
568 Status = IoGetDeviceObjectPointer(&DeviceStringW,
570 &FileObject,
571 &DeviceObject);
572
573 RtlFreeUnicodeString(&DeviceStringW);
574 /* This is a security measure, to ensure DiskNumber will be used */
575 DeviceNumber.DeviceNumber = ULONG_MAX;
576 }
577
578 /* Something failed somewhere earlier, just skip the disk */
579 if (!NT_SUCCESS(Status))
580 {
581 continue;
582 }
583
584 /* Let's ask the disk for its geometry */
587 NULL,
588 0,
589 &DiskGeometry,
590 sizeof(DiskGeometry),
591 FALSE,
592 &Event,
594 /* Missing resources is a shame... No need to go farther */
595 if (!Irp)
596 {
599 goto Cleanup;
600 }
601
602 /* Call the driver, and wait for it if needed */
605 if (Status == STATUS_PENDING)
606 {
609 }
610 /* Failure, skip disk */
611 if (!NT_SUCCESS(Status))
612 {
614 continue;
615 }
616
617 /* Read the partition table */
619 &DriveLayout);
620 if (!NT_SUCCESS(Status))
621 {
623 continue;
624 }
625
626 /* Ensure we have at least 512 bytes per sector */
627 if (DiskGeometry.BytesPerSector < 512)
628 {
629 DiskGeometry.BytesPerSector = 512;
630 }
631
632 /* Check MBR type against EZ Drive type */
633 StartingOffset.QuadPart = 0;
634 HalExamineMBR(DeviceObject, DiskGeometry.BytesPerSector, 0x55, &Data);
635 if (Data)
636 {
637 /* If MBR is of the EZ Drive type, we'll read after it */
638 StartingOffset.QuadPart = DiskGeometry.BytesPerSector;
640 }
641
642 /* Allocate for reading enough data for checksum */
644 if (!PartitionBuffer)
645 {
648 goto Cleanup;
649 }
650
651 /* Read the first sector for computing checksum */
655 DiskGeometry.BytesPerSector,
657 &Event,
659 if (!Irp)
660 {
664 goto Cleanup;
665 }
666
667 /* Call the driver to perform reading */
670 if (Status == STATUS_PENDING)
671 {
674 }
675
676 /* If reading succeeded, calculate checksum by adding data */
677 if (NT_SUCCESS(Status))
678 {
679 for (i = 0, CheckSum = 0; i < 512 / sizeof(ULONG); i++)
680 {
681 CheckSum += PartitionBuffer[i];
682 }
683 }
684
685 /* Release now unnecessary resources */
688
689 /* If we failed, release drive layout before going to next disk */
690 if (!NT_SUCCESS(Status))
691 {
692 ExFreePool(DriveLayout);
693 DriveLayout = NULL;
694 continue;
695 }
696
697 /* Browse each ARC disk */
698 for (NextEntry = ArcDiskInformation->DiskSignatureListHead.Flink;
699 NextEntry != &ArcDiskInformation->DiskSignatureListHead;
700 NextEntry = NextEntry->Flink)
701 {
702 ArcDiskSignature = CONTAINING_RECORD(NextEntry,
704 ListEntry);
705
706 /* If they match, i.e.
707 * - There's only one disk for both BIOS and detected/enabled
708 * - Signatures are matching
709 * - Checksums are matching
710 * - This is MBR
711 */
712 if (((SingleDisk && DiskCount == 1) ||
713 (IopVerifyDiskSignature(DriveLayout, ArcDiskSignature, &Signature) &&
714 (ArcDiskSignature->CheckSum + CheckSum == 0))) &&
715 (DriveLayout->PartitionStyle == PARTITION_STYLE_MBR))
716 {
717 /* Create device name */
718 sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", (DeviceNumber.DeviceNumber != ULONG_MAX) ? DeviceNumber.DeviceNumber : DiskNumber);
719 RtlInitAnsiString(&DeviceStringA, Buffer);
720 Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
721 if (!NT_SUCCESS(Status))
722 {
723 goto Cleanup;
724 }
725
726 /* Create ARC name */
727 sprintf(ArcBuffer, "\\ArcName\\%s", ArcDiskSignature->ArcName);
728 RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
729 Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE);
730 if (!NT_SUCCESS(Status))
731 {
732 RtlFreeUnicodeString(&DeviceStringW);
733 goto Cleanup;
734 }
735
736 /* Link both */
737 IoAssignArcName(&ArcNameStringW, &DeviceStringW);
738
739 /* And release resources */
740 RtlFreeUnicodeString(&ArcNameStringW);
741 RtlFreeUnicodeString(&DeviceStringW);
742
743 /* Now, browse for every partition */
744 for (i = 1; i <= DriveLayout->PartitionCount; i++)
745 {
746 /* Create device name */
747 sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition%lu", (DeviceNumber.DeviceNumber != ULONG_MAX) ? DeviceNumber.DeviceNumber : DiskNumber, i);
748 RtlInitAnsiString(&DeviceStringA, Buffer);
749 Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE);
750 if (!NT_SUCCESS(Status))
751 {
752 goto Cleanup;
753 }
754
755 /* Create partial ARC name */
756 sprintf(ArcBuffer, "%spartition(%lu)", ArcDiskSignature->ArcName, i);
757 RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
758
759 /* Is that boot device? */
760 if (RtlEqualString(&ArcNameStringA, &ArcBootString, TRUE))
761 {
762 DPRINT("Found boot device\n");
763 *FoundBoot = TRUE;
764 }
765
766 /* Is that system partition? */
767 if (RtlEqualString(&ArcNameStringA, &ArcSystemString, TRUE))
768 {
769 /* Create HAL path name */
770 RtlInitAnsiString(&HalPathStringA, LoaderBlock->NtHalPathName);
771 Status = RtlAnsiStringToUnicodeString(&HalPathStringW, &HalPathStringA, TRUE);
772 if (!NT_SUCCESS(Status))
773 {
774 RtlFreeUnicodeString(&DeviceStringW);
775 goto Cleanup;
776 }
777
778 /* Then store those information to registry */
779 IopStoreSystemPartitionInformation(&DeviceStringW, &HalPathStringW);
780 RtlFreeUnicodeString(&HalPathStringW);
781 }
782
783 /* Create complete ARC name */
784 sprintf(ArcBuffer, "\\ArcName\\%spartition(%lu)", ArcDiskSignature->ArcName, i);
785 RtlInitAnsiString(&ArcNameStringA, ArcBuffer);
786 Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE);
787 if (!NT_SUCCESS(Status))
788 {
789 RtlFreeUnicodeString(&DeviceStringW);
790 goto Cleanup;
791 }
792
793 /* Link device name & ARC name */
794 IoAssignArcName(&ArcNameStringW, &DeviceStringW);
795
796 /* Release strings */
797 RtlFreeUnicodeString(&ArcNameStringW);
798 RtlFreeUnicodeString(&DeviceStringW);
799 }
800 }
801 else
802 {
803 /* Debugging feedback: Warn in case there's a valid partition,
804 * a matching signature, BUT a non-matching checksum: this can
805 * be the sign of a duplicate signature, or even worse a virus
806 * played with the partition table. */
807 if (ArcDiskSignature->ValidPartitionTable &&
808 (ArcDiskSignature->Signature == Signature) &&
809 (ArcDiskSignature->CheckSum + CheckSum != 0))
810 {
811 DPRINT("Be careful, you have a duplicate disk signature, or a virus altered your MBR!\n");
812 }
813 }
814 }
815
816 /* Finally, release drive layout */
817 ExFreePool(DriveLayout);
818 DriveLayout = NULL;
819 }
820
822
823Cleanup:
824 if (DriveLayout)
825 {
826 ExFreePool(DriveLayout);
827 }
828
830 {
832 }
833
834 return Status;
835}
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
static const WCHAR Signature[]
Definition: parser.c:141
NTSTATUS NTAPI IoReadPartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: fstubex.c:2279
#define ULONG_MAX
Definition: limits.h:44
#define ASSERT(a)
Definition: mode.c:44
@ PARTITION_STYLE_MBR
Definition: imports.h:201
NTSYSAPI BOOLEAN NTAPI RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
BOOLEAN NTAPI IopVerifyDiskSignature(IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout, IN PARC_DISK_SIGNATURE ArcDiskSignature, OUT PULONG Signature)
Definition: arcname.c:948
#define HalExamineMBR
Definition: part_xbox.c:325
BOOLEAN ValidPartitionTable
Definition: arc.h:259
ULONG Signature
Definition: arc.h:256
ULONG BytesPerSector
Definition: ntdddisk.h:409

Referenced by IopCreateArcNames().

◆ IopReassignSystemRoot()

NTSTATUS NTAPI IopReassignSystemRoot ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
OUT PANSI_STRING  NtBootPath 
)

Definition at line 840 of file arcname.c.

842{
845 CHAR Buffer[256], AnsiBuffer[256];
846 WCHAR ArcNameBuffer[64];
847 ANSI_STRING TargetString, ArcString, TempString;
848 UNICODE_STRING LinkName, TargetName, ArcName;
849 HANDLE LinkHandle;
850
851 /* Create the Unicode name for the current ARC boot device */
852 sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
855 if (!NT_SUCCESS(Status)) return FALSE;
856
857 /* Initialize the attributes and open the link */
859 &TargetName,
861 NULL,
862 NULL);
863 Status = NtOpenSymbolicLinkObject(&LinkHandle,
866 if (!NT_SUCCESS(Status))
867 {
868 /* We failed, free the string */
870 return FALSE;
871 }
872
873 /* Query the current \\SystemRoot */
874 ArcName.Buffer = ArcNameBuffer;
875 ArcName.Length = 0;
876 ArcName.MaximumLength = sizeof(ArcNameBuffer);
877 Status = NtQuerySymbolicLinkObject(LinkHandle, &ArcName, NULL);
878 if (!NT_SUCCESS(Status))
879 {
880 /* We failed, free the string */
882 return FALSE;
883 }
884
885 /* Convert it to Ansi */
886 ArcString.Buffer = AnsiBuffer;
887 ArcString.Length = 0;
888 ArcString.MaximumLength = sizeof(AnsiBuffer);
889 Status = RtlUnicodeStringToAnsiString(&ArcString, &ArcName, FALSE);
890 AnsiBuffer[ArcString.Length] = ANSI_NULL;
891
892 /* Close the link handle and free the name */
893 ObCloseHandle(LinkHandle, KernelMode);
895
896 /* Setup the system root name again */
897 RtlInitAnsiString(&TempString, "\\SystemRoot");
898 Status = RtlAnsiStringToUnicodeString(&LinkName, &TempString, TRUE);
899 if (!NT_SUCCESS(Status)) return FALSE;
900
901 /* Open the symbolic link for it */
903 &LinkName,
905 NULL,
906 NULL);
907 Status = NtOpenSymbolicLinkObject(&LinkHandle,
910 if (!NT_SUCCESS(Status)) return FALSE;
911
912 /* Destroy it */
913 NtMakeTemporaryObject(LinkHandle);
914 ObCloseHandle(LinkHandle, KernelMode);
915
916 /* Now create the new name for it */
917 sprintf(Buffer, "%s%s", ArcString.Buffer, LoaderBlock->NtBootPathName);
918
919 /* Copy it into the passed parameter and null-terminate it */
920 RtlCopyString(NtBootPath, &ArcString);
922
923 /* Setup the Unicode-name for the new symbolic link value */
926 &LinkName,
928 NULL,
929 NULL);
931 if (!NT_SUCCESS(Status)) return FALSE;
932
933 /* Create it */
937 &ArcName);
938
939 /* Free all the strings and close the handle and return success */
940 RtlFreeUnicodeString(&ArcName);
941 RtlFreeUnicodeString(&LinkName);
942 ObCloseHandle(LinkHandle, KernelMode);
943 return TRUE;
944}
CHAR AnsiBuffer[1024]
Definition: debug.c:15
_In_z_ PCHAR TargetString
Definition: cdrom.h:954
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlCopyString(PSTRING DestinationString, PSTRING SourceString)
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1473
static PCWSTR TargetName
Definition: ping.c:67
USHORT MaximumLength
Definition: env_spec_w32.h:377
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by IoInitSystem().

◆ IopVerifyDiskSignature()

BOOLEAN NTAPI IopVerifyDiskSignature ( IN PDRIVE_LAYOUT_INFORMATION_EX  DriveLayout,
IN PARC_DISK_SIGNATURE  ArcDiskSignature,
OUT PULONG  Signature 
)

Definition at line 948 of file arcname.c.

951{
952 /* First condition: having a valid partition table */
953 if (!ArcDiskSignature->ValidPartitionTable)
954 {
955 return FALSE;
956 }
957
958 /* If that partition table is the MBR */
959 if (DriveLayout->PartitionStyle == PARTITION_STYLE_MBR)
960 {
961 /* Then check MBR signature */
962 if (DriveLayout->Mbr.Signature == ArcDiskSignature->Signature)
963 {
964 /* And return it */
965 if (Signature)
966 {
967 *Signature = DriveLayout->Mbr.Signature;
968 }
969
970 return TRUE;
971 }
972 }
973 /* If that partition table is the GPT */
974 else if (DriveLayout->PartitionStyle == PARTITION_STYLE_GPT)
975 {
976 /* Check we are using GPT and compare GUID */
977 if (ArcDiskSignature->IsGpt &&
978 (((PULONG)ArcDiskSignature->GptSignature)[0] == DriveLayout->Gpt.DiskId.Data1 &&
979 ((PUSHORT)ArcDiskSignature->GptSignature)[2] == DriveLayout->Gpt.DiskId.Data2 &&
980 ((PUSHORT)ArcDiskSignature->GptSignature)[3] == DriveLayout->Gpt.DiskId.Data3 &&
981 ((PULONGLONG)ArcDiskSignature->GptSignature)[1] == ((PULONGLONG)DriveLayout->Gpt.DiskId.Data4)[0]))
982 {
983 /* There's no signature to give, so we just zero output */
984 if (Signature)
985 {
986 *Signature = 0;
987 }
988 return TRUE;
989 }
990 }
991
992 /* If we fall here, it means that something went wrong, so return that */
993 return FALSE;
994}
@ PARTITION_STYLE_GPT
Definition: imports.h:202
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
uint16_t * PUSHORT
Definition: typedefs.h:56

Referenced by IoGetBootDiskInformation(), and IopCreateArcNamesDisk().

Variable Documentation

◆ IoArcBootDeviceName

UNICODE_STRING IoArcBootDeviceName

Definition at line 19 of file arcname.c.

Referenced by IopCreateArcNames().

◆ IoArcHalDeviceName

UNICODE_STRING IoArcHalDeviceName

Definition at line 19 of file arcname.c.

Referenced by IopCreateArcNames().

◆ IoLoaderArcBootDeviceName

PCHAR IoLoaderArcBootDeviceName

Definition at line 20 of file arcname.c.

Referenced by IopCreateArcNames().