ReactOS  0.4.14-dev-49-gfb4591c
disksup.c
Go to the documentation of this file.
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/fstub/disksup.c
5 * PURPOSE: I/O HAL Routines for Disk Access
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl
8 * Casper S. Hornstrup (chorns@users.sourceforge.net)
9 */
10 
11 /* INCLUDES ******************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 #include <internal/hal.h>
17 
18 /* DEPRECATED FUNCTIONS ******************************************************/
19 
20 #if 1
21 const WCHAR DiskMountString[] = L"\\DosDevices\\%C:";
22 
23 #define AUTO_DRIVE MAXULONG
24 
25 #define PARTITION_MAGIC 0xaa55
26 
27 #define EFI_PMBR_OSTYPE_EFI 0xEE
28 
29 #include <pshpack1.h>
30 
31 typedef struct _REG_DISK_MOUNT_INFO
32 {
36 
37 #include <poppack.h>
38 
39 typedef enum _DISK_MANAGER
40 {
44 } DISK_MANAGER;
45 
46 static BOOLEAN
48  IN ULONG DriveNumber,
52  IN HANDLE hKey,
54  OUT PUCHAR NtSystemPath)
55 {
56  WCHAR DriveNameBuffer[16];
57  UNICODE_STRING DriveName;
58  ULONG i;
61 
62  DPRINT("HalpAssignDrive()\n");
63 
64  if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 26))
65  {
66  /* Force assignment */
68  if ((ObSystemDeviceMap->DriveMap & (1 << DriveNumber)) != 0)
69  {
70  DbgPrint("Drive letter already used!\n");
72  return FALSE;
73  }
75  }
76  else
77  {
78  /* Automatic assignment */
79  DriveNumber = AUTO_DRIVE;
81  for (i = 2; i < 26; i++)
82  {
83  if ((ObSystemDeviceMap->DriveMap & (1 << i)) == 0)
84  {
85  DriveNumber = i;
86  break;
87  }
88  }
90 
91  if (DriveNumber == AUTO_DRIVE)
92  {
93  DbgPrint("No drive letter available!\n");
94  return FALSE;
95  }
96  }
97 
98  DPRINT("DriveNumber %lu\n", DriveNumber);
99 
100  /* Build drive name */
101  swprintf(DriveNameBuffer,
102  L"\\??\\%C:",
103  'A' + DriveNumber);
104  RtlInitUnicodeString(&DriveName,
105  DriveNameBuffer);
106 
107  DPRINT(" %wZ ==> %wZ\n",
108  &DriveName,
109  PartitionName);
110 
111  /* Create symbolic link */
112  Status = IoCreateSymbolicLink(&DriveName,
113  PartitionName);
114 
115  if (hKey &&
117  Signature)
118  {
119  DiskMountInfo.Signature = Signature;
120  DiskMountInfo.StartingOffset = StartingOffset;
121  swprintf(DriveNameBuffer, DiskMountString, L'A' + DriveNumber);
122  RtlInitUnicodeString(&DriveName, DriveNameBuffer);
123 
124  Status = ZwSetValueKey(hKey,
125  &DriveName,
126  0,
127  REG_BINARY,
128  &DiskMountInfo,
129  sizeof(DiskMountInfo));
130  if (!NT_SUCCESS(Status))
131  {
132  DPRINT1("ZwCreateValueKey failed for %wZ, status=%x\n", &DriveName, Status);
133  }
134  }
135 
136  /* Check if this is a boot partition */
137  if (RtlCompareUnicodeString(PartitionName, BootDevice, FALSE) == 0)
138  {
139  /* Set NtSystemPath to that partition's disk letter */
140  *NtSystemPath = (UCHAR)('A' + DriveNumber);
141  }
142 
143  return TRUE;
144 }
145 
146 ULONG
148 {
150  UNICODE_STRING ArcName;
151  PWCHAR ArcNameBuffer;
154  POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
155  ULONG Skip;
157  ULONG CurrentRDisk;
158  ULONG RDiskCount;
159  BOOLEAN First = TRUE;
160  ULONG Count;
161 
163  if (DirectoryInfo == NULL)
164  {
165  return 0;
166  }
167 
168  RtlInitUnicodeString(&ArcName, L"\\ArcName");
170  &ArcName,
171  0,
172  NULL,
173  NULL);
174 
178  if (!NT_SUCCESS(Status))
179  {
180  DPRINT1("ZwOpenDirectoryObject for %wZ failed, status=%lx\n", &ArcName, Status);
181  ExFreePoolWithTag(DirectoryInfo, TAG_FILE_SYSTEM);
182  return 0;
183  }
184 
185  RDiskCount = 0;
186  Skip = 0;
187  while (NT_SUCCESS(Status))
188  {
189  Status = ZwQueryDirectoryObject (DirectoryHandle,
190  DirectoryInfo,
191  2 * PAGE_SIZE,
192  FALSE,
193  First,
194  &Skip,
195  &ResultLength);
196  First = FALSE;
197  if (NT_SUCCESS(Status))
198  {
199  Count = 0;
200  while (DirectoryInfo[Count].Name.Buffer)
201  {
202  DPRINT("Count %x\n", Count);
203  DirectoryInfo[Count].Name.Buffer[DirectoryInfo[Count].Name.Length / sizeof(WCHAR)] = 0;
204  ArcNameBuffer = DirectoryInfo[Count].Name.Buffer;
205  if (DirectoryInfo[Count].Name.Length >= sizeof(L"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR) &&
206  !_wcsnicmp(ArcNameBuffer, L"multi(0)disk(0)rdisk(", (sizeof(L"multi(0)disk(0)rdisk(") - sizeof(WCHAR)) / sizeof(WCHAR)))
207  {
208  DPRINT("%S\n", ArcNameBuffer);
209  ArcNameBuffer += (sizeof(L"multi(0)disk(0)rdisk(") - sizeof(WCHAR)) / sizeof(WCHAR);
210  CurrentRDisk = 0;
211  while (iswdigit(*ArcNameBuffer))
212  {
213  CurrentRDisk = CurrentRDisk * 10 + *ArcNameBuffer - L'0';
214  ArcNameBuffer++;
215  }
216  if (!_wcsicmp(ArcNameBuffer, L")") &&
217  CurrentRDisk >= RDiskCount)
218  {
219  RDiskCount = CurrentRDisk + 1;
220  }
221  }
222  Count++;
223  }
224  }
225  }
226 
228 
229  ExFreePoolWithTag(DirectoryInfo, TAG_FILE_SYSTEM);
230  return RDiskCount;
231 }
232 
233 NTSTATUS
235 {
236  WCHAR NameBuffer[80];
237  UNICODE_STRING ArcName;
238  UNICODE_STRING LinkName;
240  HANDLE LinkHandle;
242 
243  swprintf(NameBuffer,
244  L"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
245  RDisk);
246 
247  RtlInitUnicodeString(&ArcName, NameBuffer);
249  &ArcName,
250  0,
251  NULL,
252  NULL);
253  Status = ZwOpenSymbolicLinkObject(&LinkHandle,
256  if (!NT_SUCCESS(Status))
257  {
258  DPRINT1("ZwOpenSymbolicLinkObject failed for %wZ, status=%lx\n", &ArcName, Status);
259  return Status;
260  }
261 
262  LinkName.Buffer = NameBuffer;
263  LinkName.Length = 0;
264  LinkName.MaximumLength = sizeof(NameBuffer);
265  Status = ZwQuerySymbolicLinkObject(LinkHandle,
266  &LinkName,
267  NULL);
268  ZwClose(LinkHandle);
269  if (!NT_SUCCESS(Status))
270  {
271  DPRINT1("ZwQuerySymbolicLinkObject failed, status=%lx\n", Status);
272  return Status;
273  }
274  if (LinkName.Length < sizeof(L"\\Device\\Harddisk0\\Partition0") - sizeof(WCHAR) ||
275  LinkName.Length >= sizeof(NameBuffer))
276  {
277  return STATUS_UNSUCCESSFUL;
278  }
279 
280  NameBuffer[LinkName.Length / sizeof(WCHAR)] = 0;
281  if (_wcsnicmp(NameBuffer, L"\\Device\\Harddisk", (sizeof(L"\\Device\\Harddisk") - sizeof(WCHAR)) / sizeof(WCHAR)))
282  {
283  return STATUS_UNSUCCESSFUL;
284  }
285  LinkName.Buffer += (sizeof(L"\\Device\\Harddisk") - sizeof(WCHAR)) / sizeof(WCHAR);
286 
287  if (!iswdigit(*LinkName.Buffer))
288  {
289  return STATUS_UNSUCCESSFUL;
290  }
291  *DiskNumber = 0;
292  while (iswdigit(*LinkName.Buffer))
293  {
294  *DiskNumber = *DiskNumber * 10 + *LinkName.Buffer - L'0';
295  LinkName.Buffer++;
296  }
297  if (_wcsicmp(LinkName.Buffer, L"\\Partition0"))
298  {
299  return STATUS_UNSUCCESSFUL;
300  }
301  return STATUS_SUCCESS;
302 }
303 
304 NTSTATUS
305 FASTCALL
307  OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo)
308 {
309  IO_STATUS_BLOCK StatusBlock;
310  DISK_GEOMETRY DiskGeometry;
313  KEVENT Event;
314  PIRP Irp;
316 
317  DPRINT("xHalpQueryDriveLayout %wZ %p\n",
318  DeviceName,
319  LayoutInfo);
320 
321  /* Get the drives sector size */
324  &FileObject,
325  &DeviceObject);
326  if (!NT_SUCCESS(Status))
327  {
328  DPRINT("Status %x\n", Status);
329  return(Status);
330  }
331 
334  FALSE);
335 
337  DeviceObject,
338  NULL,
339  0,
340  &DiskGeometry,
341  sizeof(DISK_GEOMETRY),
342  FALSE,
343  &Event,
344  &StatusBlock);
345  if (Irp == NULL)
346  {
349  }
350 
352  Irp);
353  if (Status == STATUS_PENDING)
354  {
356  Executive,
357  KernelMode,
358  FALSE,
359  NULL);
360  Status = StatusBlock.Status;
361  }
362  if (!NT_SUCCESS(Status))
363  {
364  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
365  {
366  DiskGeometry.BytesPerSector = 512;
367  }
368  else
369  {
371  return(Status);
372  }
373  }
374 
375  DPRINT("DiskGeometry.BytesPerSector: %lu\n",
376  DiskGeometry.BytesPerSector);
377 
378  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
379  {
381 
382  /* Allocate a partition list for a single entry. */
385  if (Buffer != NULL)
386  {
388  sizeof(DRIVE_LAYOUT_INFORMATION));
389  Buffer->PartitionCount = 1;
390  *LayoutInfo = Buffer;
391 
393  }
394  else
395  {
397  }
398  }
399  else
400  {
401  /* Read the partition table */
403  DiskGeometry.BytesPerSector,
404  TRUE,
405  LayoutInfo);
406  }
407 
409 
410  return(Status);
411 }
412 
413 VOID
414 FASTCALL
416  IN PSTRING NtDeviceName,
417  OUT PUCHAR NtSystemPath,
418  OUT PSTRING NtSystemPathString)
419 {
420  PDRIVE_LAYOUT_INFORMATION *LayoutArray;
421  PCONFIGURATION_INFORMATION ConfigInfo;
423  IO_STATUS_BLOCK StatusBlock;
424  UNICODE_STRING UnicodeString1;
425  UNICODE_STRING UnicodeString2;
427  PWSTR Buffer1;
428  PWSTR Buffer2;
429  ULONG i, j, k;
430  ULONG DiskNumber;
431  ULONG RDisk;
433  HANDLE hKey;
434  ULONG Length;
435  PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
437  ULONG RDiskCount;
439 
441  NtDeviceName,
442  TRUE);
443 
444  DPRINT("xHalIoAssignDriveLetters()\n");
445 
446  ConfigInfo = IoGetConfigurationInformation();
447 
448  RDiskCount = xHalpGetRDiskCount();
449 
450  DPRINT("RDiskCount %lu\n", RDiskCount);
451 
453  64 * sizeof(WCHAR),
455  if (!Buffer1) return;
456 
458  32 * sizeof(WCHAR),
460  if (!Buffer2)
461  {
463  return;
464  }
465 
466  PartialInformation = ExAllocatePoolWithTag(PagedPool,
469  if (!PartialInformation)
470  {
473  return;
474  }
475 
476  DiskMountInfo = (PREG_DISK_MOUNT_INFO) PartialInformation->Data;
477 
478  /* Create or open the 'MountedDevices' key */
479  RtlInitUnicodeString(&UnicodeString1, L"\\Registry\\Machine\\SYSTEM\\MountedDevices");
481  &UnicodeString1,
483  NULL,
484  NULL);
485  Status = ZwCreateKey(&hKey,
488  0,
489  NULL,
491  NULL);
492  if (!NT_SUCCESS(Status))
493  {
494  hKey = NULL;
495  DPRINT("ZwCreateKey failed for %wZ, status=%x\n", &UnicodeString1, Status);
496  }
497 
498  /* Create PhysicalDrive links */
499  DPRINT("Physical disk drives: %lu\n", ConfigInfo->DiskCount);
500  for (i = 0; i < ConfigInfo->DiskCount; i++)
501  {
502  swprintf(Buffer1, L"\\Device\\Harddisk%lu\\Partition0", i);
503  RtlInitUnicodeString(&UnicodeString1, Buffer1);
504 
506  &UnicodeString1,
507  0,
508  NULL,
509  NULL);
510 
514  &StatusBlock,
517  if (NT_SUCCESS(Status))
518  {
520 
521  swprintf(Buffer2, L"\\??\\PhysicalDrive%lu", i);
522  RtlInitUnicodeString(&UnicodeString2, Buffer2);
523 
524  DPRINT("Creating link: %S ==> %S\n",
525  Buffer2,
526  Buffer1);
527 
528  IoCreateSymbolicLink(&UnicodeString2,
529  &UnicodeString1);
530  }
531  }
532 
533  /* Initialize layout array */
534  if (ConfigInfo->DiskCount == 0)
535  goto end_assign_disks;
536  LayoutArray = ExAllocatePoolWithTag(NonPagedPool,
537  ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION), TAG_FILE_SYSTEM);
538  if (!LayoutArray)
539  {
540  ExFreePoolWithTag(PartialInformation, TAG_FILE_SYSTEM);
543  if (hKey) ObCloseHandle(hKey, KernelMode);
544  return;
545  }
546 
547  RtlZeroMemory(LayoutArray,
548  ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
549  for (i = 0; i < ConfigInfo->DiskCount; i++)
550  {
551  swprintf(Buffer1, L"\\Device\\Harddisk%lu\\Partition0", i);
552  RtlInitUnicodeString(&UnicodeString1, Buffer1);
553 
554  Status = xHalQueryDriveLayout(&UnicodeString1, &LayoutArray[i]);
555  if (!NT_SUCCESS(Status))
556  {
557  DbgPrint("xHalQueryDriveLayout() failed (Status = 0x%lx)\n",
558  Status);
559  LayoutArray[i] = NULL;
560  continue;
561  }
562  /* We don't use the RewritePartition value while mounting the disks.
563  * We use this value for marking pre-assigned (registry) partitions.
564  */
565  for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
566  {
567  LayoutArray[i]->PartitionEntry[j].RewritePartition = FALSE;
568  }
569  }
570 
571 #ifndef NDEBUG
572  /* Dump layout array */
573  for (i = 0; i < ConfigInfo->DiskCount; i++)
574  {
575  DPRINT("Harddisk %d:\n",
576  i);
577 
578  if (LayoutArray[i] == NULL)
579  continue;
580 
581  DPRINT("Logical partitions: %d\n",
582  LayoutArray[i]->PartitionCount);
583 
584  for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
585  {
586  DPRINT(" %d: nr:%x boot:%x type:%x startblock:%I64u count:%I64u\n",
587  j,
588  LayoutArray[i]->PartitionEntry[j].PartitionNumber,
589  LayoutArray[i]->PartitionEntry[j].BootIndicator,
590  LayoutArray[i]->PartitionEntry[j].PartitionType,
591  LayoutArray[i]->PartitionEntry[j].StartingOffset.QuadPart,
592  LayoutArray[i]->PartitionEntry[j].PartitionLength.QuadPart);
593  }
594  }
595 #endif
596 
597  /* Assign pre-assigned (registry) partitions */
598  if (hKey)
599  {
600  for (k = 2; k < 26; k++)
601  {
602  swprintf(Buffer1, DiskMountString, L'A' + k);
603  RtlInitUnicodeString(&UnicodeString1, Buffer1);
604  Status = ZwQueryValueKey(hKey,
605  &UnicodeString1,
607  PartialInformation,
609  &Length);
610  if (NT_SUCCESS(Status) &&
611  PartialInformation->Type == REG_BINARY &&
612  PartialInformation->DataLength == sizeof(REG_DISK_MOUNT_INFO))
613  {
614  DPRINT("%wZ => %08x:%08x%08x\n", &UnicodeString1, DiskMountInfo->Signature,
615  DiskMountInfo->StartingOffset.u.HighPart, DiskMountInfo->StartingOffset.u.LowPart);
616  {
617  BOOLEAN Found = FALSE;
618  for (i = 0; i < ConfigInfo->DiskCount; i++)
619  {
620  DPRINT("%x\n", LayoutArray[i]->Signature);
621  if (LayoutArray[i] &&
622  LayoutArray[i]->Signature &&
623  LayoutArray[i]->Signature == DiskMountInfo->Signature)
624  {
625  for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
626  {
627  if (LayoutArray[i]->PartitionEntry[j].StartingOffset.QuadPart == DiskMountInfo->StartingOffset.QuadPart)
628  {
629  if (IsRecognizedPartition(LayoutArray[i]->PartitionEntry[j].PartitionType) &&
630  LayoutArray[i]->PartitionEntry[j].RewritePartition == FALSE)
631  {
632  swprintf(Buffer2,
633  L"\\Device\\Harddisk%lu\\Partition%lu",
634  i,
635  LayoutArray[i]->PartitionEntry[j].PartitionNumber);
636  RtlInitUnicodeString(&UnicodeString2, Buffer2);
637 
638  /* Assign drive */
639  DPRINT(" %wZ\n", &UnicodeString2);
640  Found = HalpAssignDrive(&UnicodeString2,
641  k,
643  DiskMountInfo->Signature,
644  DiskMountInfo->StartingOffset,
645  NULL,
646  &BootDevice,
647  NtSystemPath);
648  /* Mark the partition as assigned */
649  LayoutArray[i]->PartitionEntry[j].RewritePartition = TRUE;
650  }
651  break;
652  }
653  }
654  }
655  }
656  if (Found == FALSE)
657  {
658  /* We didn't find a partition for this entry, remove them. */
659  Status = ZwDeleteValueKey(hKey, &UnicodeString1);
660  }
661  }
662  }
663  }
664  }
665 
666  /* Assign bootable partition on first harddisk */
667  DPRINT("Assigning bootable primary partition on first harddisk:\n");
668  if (RDiskCount > 0)
669  {
670  Status = xHalpGetDiskNumberFromRDisk(0, &DiskNumber);
671  if (NT_SUCCESS(Status) &&
672  DiskNumber < ConfigInfo->DiskCount &&
673  LayoutArray[DiskNumber])
674  {
675  /* Search for bootable partition */
676  for (j = 0; j < NUM_PARTITION_TABLE_ENTRIES && j < LayoutArray[DiskNumber]->PartitionCount; j++)
677  {
678  if ((LayoutArray[DiskNumber]->PartitionEntry[j].BootIndicator != FALSE) &&
679  IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType))
680  {
681  if (LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE)
682  {
683  swprintf(Buffer2,
684  L"\\Device\\Harddisk%lu\\Partition%lu",
685  DiskNumber,
686  LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
687  RtlInitUnicodeString(&UnicodeString2, Buffer2);
688 
689  /* Assign drive */
690  DPRINT(" %wZ\n", &UnicodeString2);
691  HalpAssignDrive(&UnicodeString2,
692  AUTO_DRIVE,
694  LayoutArray[DiskNumber]->Signature,
695  LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
696  hKey,
697  &BootDevice,
698  NtSystemPath);
699  /* Mark the partition as assigned */
700  LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
701  }
702  break;
703  }
704  }
705  }
706  }
707 
708  /* Assign remaining primary partitions */
709  DPRINT("Assigning remaining primary partitions:\n");
710  for (RDisk = 0; RDisk < RDiskCount; RDisk++)
711  {
712  Status = xHalpGetDiskNumberFromRDisk(RDisk, &DiskNumber);
713  if (NT_SUCCESS(Status) &&
714  DiskNumber < ConfigInfo->DiskCount &&
715  LayoutArray[DiskNumber])
716  {
717  /* Search for primary partitions */
718  for (j = 0; (j < NUM_PARTITION_TABLE_ENTRIES) && (j < LayoutArray[DiskNumber]->PartitionCount); j++)
719  {
720  if (LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
721  IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType))
722  {
723  swprintf(Buffer2,
724  L"\\Device\\Harddisk%lu\\Partition%lu",
725  DiskNumber,
726  LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
727  RtlInitUnicodeString(&UnicodeString2, Buffer2);
728 
729  /* Assign drive */
730  DPRINT(" %wZ\n",
731  &UnicodeString2);
732  HalpAssignDrive(&UnicodeString2,
733  AUTO_DRIVE,
735  LayoutArray[DiskNumber]->Signature,
736  LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
737  hKey,
738  &BootDevice,
739  NtSystemPath);
740  /* Mark the partition as assigned */
741  LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
742  }
743  }
744  }
745  }
746 
747  /* Assign extended (logical) partitions */
748  DPRINT("Assigning extended (logical) partitions:\n");
749  for (RDisk = 0; RDisk < RDiskCount; RDisk++)
750  {
751  Status = xHalpGetDiskNumberFromRDisk(RDisk, &DiskNumber);
752  if (NT_SUCCESS(Status) &&
753  DiskNumber < ConfigInfo->DiskCount &&
754  LayoutArray[DiskNumber])
755  {
756  /* Search for extended partitions */
757  for (j = NUM_PARTITION_TABLE_ENTRIES; j < LayoutArray[DiskNumber]->PartitionCount; j++)
758  {
759  if (IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType) &&
760  LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
761  LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber != 0)
762  {
763  swprintf(Buffer2,
764  L"\\Device\\Harddisk%lu\\Partition%lu",
765  DiskNumber,
766  LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
767  RtlInitUnicodeString(&UnicodeString2, Buffer2);
768 
769  /* Assign drive */
770  DPRINT(" %wZ\n",
771  &UnicodeString2);
772  HalpAssignDrive(&UnicodeString2,
773  AUTO_DRIVE,
775  LayoutArray[DiskNumber]->Signature,
776  LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
777  hKey,
778  &BootDevice,
779  NtSystemPath);
780  /* Mark the partition as assigned */
781  LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
782  }
783  }
784  }
785  }
786 
787  /* Assign remaining primary partitions without an arc-name */
788  DPRINT("Assigning remaining primary partitions:\n");
789  for (DiskNumber = 0; DiskNumber < ConfigInfo->DiskCount; DiskNumber++)
790  {
791  if (LayoutArray[DiskNumber])
792  {
793  /* Search for primary partitions */
794  for (j = 0; (j < NUM_PARTITION_TABLE_ENTRIES) && (j < LayoutArray[DiskNumber]->PartitionCount); j++)
795  {
796  if (LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
797  IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType))
798  {
799  swprintf(Buffer2,
800  L"\\Device\\Harddisk%lu\\Partition%lu",
801  DiskNumber,
802  LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
803  RtlInitUnicodeString(&UnicodeString2, Buffer2);
804 
805  /* Assign drive */
806  DPRINT(" %wZ\n",
807  &UnicodeString2);
808  HalpAssignDrive(&UnicodeString2,
809  AUTO_DRIVE,
811  LayoutArray[DiskNumber]->Signature,
812  LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
813  hKey,
814  &BootDevice,
815  NtSystemPath);
816  /* Mark the partition as assigned */
817  LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
818  }
819  }
820  }
821  }
822 
823  /* Assign extended (logical) partitions without an arc-name */
824  DPRINT("Assigning extended (logical) partitions:\n");
825  for (DiskNumber = 0; DiskNumber < ConfigInfo->DiskCount; DiskNumber++)
826  {
827  if (LayoutArray[DiskNumber])
828  {
829  /* Search for extended partitions */
830  for (j = NUM_PARTITION_TABLE_ENTRIES; j < LayoutArray[DiskNumber]->PartitionCount; j++)
831  {
832  if (IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType) &&
833  LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
834  LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber != 0)
835  {
836  swprintf(Buffer2,
837  L"\\Device\\Harddisk%lu\\Partition%lu",
838  DiskNumber,
839  LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
840  RtlInitUnicodeString(&UnicodeString2, Buffer2);
841 
842  /* Assign drive */
843  DPRINT(" %wZ\n",
844  &UnicodeString2);
845  HalpAssignDrive(&UnicodeString2,
846  AUTO_DRIVE,
848  LayoutArray[DiskNumber]->Signature,
849  LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
850  hKey,
851  &BootDevice,
852  NtSystemPath);
853  /* Mark the partition as assigned */
854  LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
855  }
856  }
857  }
858  }
859 
860  /* Assign removable disk drives */
861  DPRINT("Assigning removable disk drives:\n");
862  for (i = 0; i < ConfigInfo->DiskCount; i++)
863  {
864  if (LayoutArray[i])
865  {
866  /* Search for virtual partitions */
867  if (LayoutArray[i]->PartitionCount == 1 &&
868  LayoutArray[i]->PartitionEntry[0].PartitionType == 0)
869  {
870  swprintf(Buffer2, L"\\Device\\Harddisk%lu\\Partition1", i);
871  RtlInitUnicodeString(&UnicodeString2, Buffer2);
872 
873  /* Assign drive */
874  DPRINT(" %wZ\n",
875  &UnicodeString2);
876  HalpAssignDrive(&UnicodeString2,
877  AUTO_DRIVE,
879  0,
881  hKey,
882  &BootDevice,
883  NtSystemPath);
884  }
885  }
886  }
887 
888  /* Free layout array */
889  for (i = 0; i < ConfigInfo->DiskCount; i++)
890  {
891  if (LayoutArray[i] != NULL)
892  ExFreePoolWithTag(LayoutArray[i], TAG_FILE_SYSTEM);
893  }
894  ExFreePoolWithTag(LayoutArray, TAG_FILE_SYSTEM);
895 end_assign_disks:
896 
897  /* Assign floppy drives */
898  DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
899  for (i = 0; i < ConfigInfo->FloppyCount; i++)
900  {
901  swprintf(Buffer1, L"\\Device\\Floppy%lu", i);
902  RtlInitUnicodeString(&UnicodeString1, Buffer1);
903 
904  /* Assign drive letters A: or B: or first free drive letter */
905  DPRINT(" %wZ\n",
906  &UnicodeString1);
907  HalpAssignDrive(&UnicodeString1,
908  (i < 2) ? i : AUTO_DRIVE,
910  0,
912  hKey,
913  &BootDevice,
914  NtSystemPath);
915  }
916 
917  /* Assign cdrom drives */
918  DPRINT("CD-Rom drives: %lu\n", ConfigInfo->CdRomCount);
919  for (i = 0; i < ConfigInfo->CdRomCount; i++)
920  {
921  swprintf(Buffer1, L"\\Device\\CdRom%lu", i);
922  RtlInitUnicodeString(&UnicodeString1, Buffer1);
923 
924  /* Assign first free drive letter */
925  DPRINT(" %wZ\n", &UnicodeString1);
926  HalpAssignDrive(&UnicodeString1,
927  AUTO_DRIVE,
929  0,
931  hKey,
932  &BootDevice,
933  NtSystemPath);
934  }
935 
936  /* Anything else to do? */
937 
938  ExFreePoolWithTag(PartialInformation, TAG_FILE_SYSTEM);
941  if (hKey) ObCloseHandle(hKey, KernelMode);
942 }
943 
944 #endif
945 
946 /* PRIVATE FUNCTIONS *********************************************************/
947 
948 NTSTATUS
949 NTAPI
951  IN PDISK_GEOMETRY Geometry,
952  OUT PULONGLONG RealSectorCount)
953 {
954  PIRP Irp;
956  PKEVENT Event;
959  PAGED_CODE();
960 
961  /* Allocate a non-paged event */
963  sizeof(KEVENT),
966 
967  /* Initialize it */
969 
970  /* Build the IRP */
972  DeviceObject,
973  NULL,
974  0UL,
975  Geometry,
976  sizeof(DISK_GEOMETRY),
977  FALSE,
978  Event,
979  &IoStatusBlock);
980  if (!Irp)
981  {
982  /* Fail, free the event */
985  }
986 
987  /* Call the driver and check if it's pending */
989  if (Status == STATUS_PENDING)
990  {
991  /* Wait on the driver */
994  }
995 
996  /* Check if the driver returned success */
997  if(NT_SUCCESS(Status))
998  {
999  /* Build another IRP */
1001  DeviceObject,
1002  NULL,
1003  0UL,
1004  &PartitionInfo,
1005  sizeof(PARTITION_INFORMATION),
1006  FALSE,
1007  Event,
1008  &IoStatusBlock);
1009  if (!Irp)
1010  {
1011  /* Fail, free the event */
1014  }
1015 
1016  /* Reset event */
1018 
1019  /* Call the driver and check if it's pending */
1021  if (Status == STATUS_PENDING)
1022  {
1023  /* Wait on the driver */
1026  }
1027 
1028  /* Check if the driver returned success */
1029  if(NT_SUCCESS(Status))
1030  {
1031  /* Get the number of sectors */
1032  *RealSectorCount = (PartitionInfo.PartitionLength.QuadPart /
1033  Geometry->BytesPerSector);
1034  }
1035  }
1036 
1037  /* Free the event and return the Status */
1039  return Status;
1040 }
1041 
1042 BOOLEAN
1043 NTAPI
1045  IN ULONGLONG MaxOffset,
1046  IN ULONGLONG MaxSector)
1047 {
1048  ULONGLONG EndingSector;
1049  PAGED_CODE();
1050 
1051  /* Unused partitions are considered valid */
1052  if (Entry->PartitionType == PARTITION_ENTRY_UNUSED) return TRUE;
1053 
1054  /* Get the last sector of the partition */
1056 
1057  /* Check if it's more then the maximum sector */
1058  if (EndingSector > MaxSector)
1059  {
1060  /* Invalid partition */
1061  DPRINT1("FSTUB: entry is invalid\n");
1062  DPRINT1("FSTUB: offset %#08lx\n", GET_STARTING_SECTOR(Entry));
1063  DPRINT1("FSTUB: length %#08lx\n", GET_PARTITION_LENGTH(Entry));
1064  DPRINT1("FSTUB: end %#I64x\n", EndingSector);
1065  DPRINT1("FSTUB: max %#I64x\n", MaxSector);
1066  return FALSE;
1067  }
1068  else if(GET_STARTING_SECTOR(Entry) > MaxOffset)
1069  {
1070  /* Invalid partition */
1071  DPRINT1("FSTUB: entry is invalid\n");
1072  DPRINT1("FSTUB: offset %#08lx\n", GET_STARTING_SECTOR(Entry));
1073  DPRINT1("FSTUB: length %#08lx\n", GET_PARTITION_LENGTH(Entry));
1074  DPRINT1("FSTUB: end %#I64x\n", EndingSector);
1075  DPRINT1("FSTUB: maxOffset %#I64x\n", MaxOffset);
1076  return FALSE;
1077  }
1078 
1079  /* It's fine, return success */
1080  return TRUE;
1081 }
1082 
1083 VOID
1084 NTAPI
1086  IN PLARGE_INTEGER PartitionLength,
1087  IN CCHAR ShiftCount,
1089  IN ULONG NumberOfTracks,
1090  IN ULONG ConventionalCylinders,
1091  OUT PPARTITION_DESCRIPTOR PartitionDescriptor)
1092 {
1093  LARGE_INTEGER FirstSector, SectorCount;
1094  ULONG LastSector, Remainder, SectorsPerCylinder;
1095  ULONG StartingCylinder, EndingCylinder;
1096  ULONG StartingTrack, EndingTrack;
1097  ULONG StartingSector, EndingSector;
1098  PAGED_CODE();
1099 
1100  /* Calculate the number of sectors for each cylinder */
1101  SectorsPerCylinder = SectorsPerTrack * NumberOfTracks;
1102 
1103  /* Calculate the first sector, and the sector count */
1104  FirstSector.QuadPart = PartitionOffset->QuadPart >> ShiftCount;
1105  SectorCount.QuadPart = PartitionLength->QuadPart >> ShiftCount;
1106 
1107  /* Now calculate the last sector */
1108  LastSector = FirstSector.LowPart + SectorCount.LowPart - 1;
1109 
1110  /* Calculate the first and last cylinders */
1111  StartingCylinder = FirstSector.LowPart / SectorsPerCylinder;
1112  EndingCylinder = LastSector / SectorsPerCylinder;
1113 
1114  /* Set the default number of cylinders */
1115  if (!ConventionalCylinders) ConventionalCylinders = 1024;
1116 
1117  /* Normalize the values */
1118  if (StartingCylinder >= ConventionalCylinders)
1119  {
1120  /* Set the maximum to 1023 */
1121  StartingCylinder = ConventionalCylinders - 1;
1122  }
1123  if (EndingCylinder >= ConventionalCylinders)
1124  {
1125  /* Set the maximum to 1023 */
1126  EndingCylinder = ConventionalCylinders - 1;
1127  }
1128 
1129  /* Calculate the starting head and sector that still remain */
1130  Remainder = FirstSector.LowPart % SectorsPerCylinder;
1131  StartingTrack = Remainder / SectorsPerTrack;
1132  StartingSector = Remainder % SectorsPerTrack;
1133 
1134  /* Calculate the ending head and sector that still remain */
1135  Remainder = LastSector % SectorsPerCylinder;
1136  EndingTrack = Remainder / SectorsPerTrack;
1137  EndingSector = Remainder % SectorsPerTrack;
1138 
1139  /* Set cylinder data for the MSB */
1140  PartitionDescriptor->StartingCylinderMsb = (UCHAR)StartingCylinder;
1141  PartitionDescriptor->EndingCylinderMsb = (UCHAR)EndingCylinder;
1142 
1143  /* Set the track data */
1144  PartitionDescriptor->StartingTrack = (UCHAR)StartingTrack;
1145  PartitionDescriptor->EndingTrack = (UCHAR)EndingTrack;
1146 
1147  /* Update cylinder data for the LSB */
1148  StartingCylinder = ((StartingSector + 1) & 0x3F) |
1149  ((StartingCylinder >> 2) & 0xC0);
1150  EndingCylinder = ((EndingSector + 1) & 0x3F) |
1151  ((EndingCylinder >> 2) & 0xC0);
1152 
1153  /* Set the cylinder data for the LSB */
1154  PartitionDescriptor->StartingCylinderLsb = (UCHAR)StartingCylinder;
1155  PartitionDescriptor->EndingCylinderLsb = (UCHAR)EndingCylinder;
1156 }
1157 
1158 VOID
1159 FASTCALL
1161  IN PULONG ConventionalCylinders,
1162  IN PLONGLONG DiskSize)
1163 {
1164  PDISK_GEOMETRY DiskGeometry = NULL;
1166  PKEVENT Event = NULL;
1167  PIRP Irp;
1168  NTSTATUS Status;
1169 
1170  /* Set defaults */
1171  *ConventionalCylinders = 0;
1172  *DiskSize = 0;
1173 
1174  /* Allocate the structure in nonpaged pool */
1175  DiskGeometry = ExAllocatePoolWithTag(NonPagedPool,
1176  sizeof(DISK_GEOMETRY),
1177  TAG_FILE_SYSTEM);
1178  if (!DiskGeometry) goto Cleanup;
1179 
1180  /* Allocate the status block in nonpaged pool */
1182  sizeof(IO_STATUS_BLOCK),
1183  TAG_FILE_SYSTEM);
1184  if (!IoStatusBlock) goto Cleanup;
1185 
1186  /* Allocate the event in nonpaged pool too */
1188  sizeof(KEVENT),
1189  TAG_FILE_SYSTEM);
1190  if (!Event) goto Cleanup;
1191 
1192  /* Initialize the event */
1194 
1195  /* Build the IRP */
1197  DeviceObject,
1198  NULL,
1199  0,
1200  DiskGeometry,
1201  sizeof(DISK_GEOMETRY),
1202  FALSE,
1203  Event,
1204  IoStatusBlock);
1205  if (!Irp) goto Cleanup;
1206 
1207  /* Now call the driver */
1209  if (Status == STATUS_PENDING)
1210  {
1211  /* Wait for it to complete */
1214  }
1215 
1216  /* Check driver status */
1217  if (NT_SUCCESS(Status))
1218  {
1219  /* Return the cylinder count */
1220  *ConventionalCylinders = DiskGeometry->Cylinders.LowPart;
1221 
1222  /* Make sure it's not larger then 1024 */
1223  if (DiskGeometry->Cylinders.LowPart >= 1024)
1224  {
1225  /* Otherwise, normalize the value */
1226  *ConventionalCylinders = 1024;
1227  }
1228 
1229  /* Calculate the disk size */
1230  *DiskSize = DiskGeometry->Cylinders.QuadPart *
1231  DiskGeometry->TracksPerCylinder *
1232  DiskGeometry->SectorsPerTrack *
1233  DiskGeometry->BytesPerSector;
1234  }
1235 
1236 Cleanup:
1237  /* Free all the pointers */
1240  if (DiskGeometry) ExFreePoolWithTag(DiskGeometry, TAG_FILE_SYSTEM);
1241  return;
1242 }
1243 
1244 VOID
1245 FASTCALL
1248  IN ULONG MbrTypeIdentifier,
1249  OUT PVOID *MbrBuffer)
1250 {
1252  PUCHAR Buffer;
1253  ULONG BufferSize;
1254  KEVENT Event;
1256  PIRP Irp;
1257  PPARTITION_DESCRIPTOR PartitionDescriptor;
1258  NTSTATUS Status;
1259  PIO_STACK_LOCATION IoStackLocation;
1260  Offset.QuadPart = 0;
1261 
1262  /* Assume failure */
1263  *MbrBuffer = NULL;
1264 
1265  /* Normalize the buffer size */
1266  BufferSize = max(SectorSize, 512);
1267 
1268  /* Allocate the buffer */
1270  PAGE_SIZE > BufferSize ?
1272  TAG_FILE_SYSTEM);
1273  if (!Buffer) return;
1274 
1275  /* Initialize the Event */
1277 
1278  /* Build the IRP */
1280  DeviceObject,
1281  Buffer,
1282  BufferSize,
1283  &Offset,
1284  &Event,
1285  &IoStatusBlock);
1286  if (!Irp)
1287  {
1288  /* Failed */
1290  return;
1291  }
1292 
1293  /* Make sure to override volume verification */
1294  IoStackLocation = IoGetNextIrpStackLocation(Irp);
1295  IoStackLocation->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
1296 
1297  /* Call the driver */
1299  if (Status == STATUS_PENDING)
1300  {
1301  /* Wait for completion */
1304  }
1305 
1306  /* Check driver Status */
1307  if (NT_SUCCESS(Status))
1308  {
1309  /* Validate the MBR Signature */
1311  {
1312  /* Failed */
1314  return;
1315  }
1316 
1317  /* Get the partition entry */
1318  PartitionDescriptor = (PPARTITION_DESCRIPTOR)
1320 
1321  /* Make sure it's what the caller wanted */
1322  if (PartitionDescriptor->PartitionType != MbrTypeIdentifier)
1323  {
1324  /* It's not, free our buffer */
1326  }
1327  else
1328  {
1329  /* Check if this is a secondary entry */
1330  if (PartitionDescriptor->PartitionType == 0x54)
1331  {
1332  /* Return our buffer, but at sector 63 */
1333  *(PULONG)Buffer = 63;
1334  *MbrBuffer = Buffer;
1335  }
1336  else if (PartitionDescriptor->PartitionType == 0x55)
1337  {
1338  /* EZ Drive, return the buffer directly */
1339  *MbrBuffer = Buffer;
1340  }
1341  else
1342  {
1343  /* Otherwise crash on debug builds */
1344  ASSERT(PartitionDescriptor->PartitionType == 0x55);
1345  }
1346  }
1347  }
1348 }
1349 
1350 VOID
1351 NTAPI
1353  IN ULONGLONG MaxOffset)
1354 {
1355  ULONG PartitionMaxOffset, PartitionLength;
1356  PAGED_CODE();
1357 
1358  /* Compute partition length (according to MBR entry) */
1359  PartitionMaxOffset = GET_STARTING_SECTOR(PartitionDescriptor) + GET_PARTITION_LENGTH(PartitionDescriptor);
1360  /* In case the partition length goes beyond disk size... */
1361  if (PartitionMaxOffset > MaxOffset)
1362  {
1363  /* Resize partition to its maximum real length */
1364  PartitionLength = (ULONG)(PartitionMaxOffset - GET_STARTING_SECTOR(PartitionDescriptor));
1365  SET_PARTITION_LENGTH(PartitionDescriptor, PartitionLength);
1366  }
1367 }
1368 
1369 NTSTATUS
1370 FASTCALL
1375 {
1376  KEVENT Event;
1378  PIRP Irp;
1379  PPARTITION_DESCRIPTOR PartitionDescriptor;
1380  CCHAR Entry;
1381  NTSTATUS Status;
1383  PUCHAR Buffer = NULL;
1384  ULONG BufferSize = 2048, InputSize;
1385  PDRIVE_LAYOUT_INFORMATION DriveLayoutInfo = NULL;
1386  LONG j = -1, i = -1, k;
1387  DISK_GEOMETRY DiskGeometry;
1388  LONGLONG EndSector, MaxSector, StartOffset;
1389  ULONGLONG MaxOffset;
1390  LARGE_INTEGER Offset, VolumeOffset;
1391  BOOLEAN IsPrimary = TRUE, IsEzDrive = FALSE, MbrFound = FALSE;
1392  BOOLEAN IsValid, IsEmpty = TRUE;
1393  PVOID MbrBuffer;
1394  PIO_STACK_LOCATION IoStackLocation;
1396  LARGE_INTEGER HiddenSectors64;
1397  VolumeOffset.QuadPart = Offset.QuadPart = 0;
1398  PAGED_CODE();
1399 
1400  /* Allocate the buffer */
1402  BufferSize,
1403  TAG_FILE_SYSTEM);
1405 
1406  /* Normalize the buffer size */
1407  InputSize = max(512, SectorSize);
1408 
1409  /* Check for EZ Drive */
1410  HalExamineMBR(DeviceObject, InputSize, 0x55, &MbrBuffer);
1411  if (MbrBuffer)
1412  {
1413  /* EZ Drive found, bias the offset */
1414  IsEzDrive = TRUE;
1415  ExFreePoolWithTag(MbrBuffer, TAG_FILE_SYSTEM);
1416  Offset.QuadPart = 512;
1417  }
1418 
1419  /* Get drive geometry */
1420  Status = HalpGetFullGeometry(DeviceObject, &DiskGeometry, &MaxOffset);
1421  if (!NT_SUCCESS(Status))
1422  {
1424  *PartitionBuffer = NULL;
1425  return Status;
1426  }
1427 
1428  /* Get the end and maximum sector */
1429  EndSector = MaxOffset;
1430  MaxSector = MaxOffset << 1;
1431  DPRINT("FSTUB: MaxOffset = %#I64x, MaxSector = %#I64x\n",
1432  MaxOffset, MaxSector);
1433 
1434  /* Allocate our buffer */
1436  if (!Buffer)
1437  {
1438  /* Fail, free the input buffer */
1440  *PartitionBuffer = NULL;
1442  }
1443 
1444  /* Start partition loop */
1445  do
1446  {
1447  /* Assume the partition is valid */
1448  IsValid = TRUE;
1449 
1450  /* Initialize the event */
1452 
1453  /* Clear the buffer and build the IRP */
1454  RtlZeroMemory(Buffer, InputSize);
1456  DeviceObject,
1457  Buffer,
1458  InputSize,
1459  &Offset,
1460  &Event,
1461  &IoStatusBlock);
1462  if (!Irp)
1463  {
1464  /* Failed */
1466  break;
1467  }
1468 
1469  /* Make sure to disable volume verification */
1470  IoStackLocation = IoGetNextIrpStackLocation(Irp);
1471  IoStackLocation->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
1472 
1473  /* Call the driver */
1475  if (Status == STATUS_PENDING)
1476  {
1477  /* Wait for completion */
1480  }
1481 
1482  /* Normalize status code and check for failure */
1484  if (!NT_SUCCESS(Status)) break;
1485 
1486  /* If we biased for EZ-Drive, unbias now */
1487  if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
1488 
1489  /* Make sure this is a valid MBR */
1491  {
1492  /* It's not, fail */
1493  DPRINT1("FSTUB: (IoReadPartitionTable) No 0xaa55 found in "
1494  "partition table %d\n", j + 1);
1495  break;
1496  }
1497 
1498  /* At this point we have a valid MBR */
1499  MbrFound = TRUE;
1500 
1501  /* Check if we weren't given an offset */
1502  if (!Offset.QuadPart)
1503  {
1504  /* Then read the signature off the disk */
1505  (*PartitionBuffer)->Signature = ((PULONG)Buffer)[PARTITION_TABLE_OFFSET / 2 - 1];
1506  }
1507 
1508  /* Get the partition descriptor array */
1509  PartitionDescriptor = (PPARTITION_DESCRIPTOR)
1511 
1512  /* Start looping partitions */
1513  j++;
1514  DPRINT("FSTUB: Partition Table %d:\n", j);
1515  for (Entry = 1, k = 0; Entry <= 4; Entry++, PartitionDescriptor++)
1516  {
1517  /* Get the partition type */
1518  PartitionType = PartitionDescriptor->PartitionType;
1519 
1520  /* Print debug messages */
1521  DPRINT("Partition Entry %d,%d: type %#x %s\n",
1522  j,
1523  Entry,
1524  PartitionType,
1525  (PartitionDescriptor->ActiveFlag) ? "Active" : "");
1526  DPRINT("\tOffset %#08lx for %#08lx Sectors\n",
1527  GET_STARTING_SECTOR(PartitionDescriptor),
1528  GET_PARTITION_LENGTH(PartitionDescriptor));
1529 
1530  /* Check whether we're facing a protective MBR */
1532  {
1533  /* Partition length might be bigger than disk size */
1534  FstubFixupEfiPartition(PartitionDescriptor,
1535  MaxOffset);
1536  }
1537 
1538  /* Make sure that the partition is valid, unless it's the first */
1539  if (!(HalpIsValidPartitionEntry(PartitionDescriptor,
1540  MaxOffset,
1541  MaxSector)) && (j == 0))
1542  {
1543  /* It's invalid, so fail */
1544  IsValid = FALSE;
1545  break;
1546  }
1547 
1548  /* Check if it's a container */
1550  {
1551  /* Increase the count of containers */
1552  if (++k != 1)
1553  {
1554  /* More then one table is invalid */
1555  DPRINT1("FSTUB: Multiple container partitions found in "
1556  "partition table %d\n - table is invalid\n",
1557  j);
1558  IsValid = FALSE;
1559  break;
1560  }
1561  }
1562 
1563  /* Check if the partition is supposedly empty */
1564  if (IsEmpty)
1565  {
1566  /* But check if it actually has a start and/or length */
1567  if ((GET_STARTING_SECTOR(PartitionDescriptor)) ||
1568  (GET_PARTITION_LENGTH(PartitionDescriptor)))
1569  {
1570  /* So then it's not really empty */
1571  IsEmpty = FALSE;
1572  }
1573  }
1574 
1575  /* Check if the caller wanted only recognized partitions */
1577  {
1578  /* Then check if this one is unused, or a container */
1581  {
1582  /* Skip it, since the caller doesn't want it */
1583  continue;
1584  }
1585  }
1586 
1587  /* Increase the structure count and check if they can fit */
1588  if ((sizeof(DRIVE_LAYOUT_INFORMATION) +
1589  (++i * sizeof(PARTITION_INFORMATION))) >
1590  BufferSize)
1591  {
1592  /* Allocate a new buffer that's twice as big */
1593  DriveLayoutInfo = ExAllocatePoolWithTag(NonPagedPool,
1594  BufferSize << 1,
1595  TAG_FILE_SYSTEM);
1596  if (!DriveLayoutInfo)
1597  {
1598  /* Out of memory, unto this extra structure */
1599  --i;
1601  break;
1602  }
1603 
1604  /* Copy the contents of the old buffer */
1605  RtlMoveMemory(DriveLayoutInfo,
1606  *PartitionBuffer,
1607  BufferSize);
1608 
1609  /* Free the old buffer and set this one as the new one */
1611  *PartitionBuffer = DriveLayoutInfo;
1612 
1613  /* Double the size */
1614  BufferSize <<= 1;
1615  }
1616 
1617  /* Now get the current structure being filled and initialize it */
1618  PartitionInfo = &(*PartitionBuffer)->PartitionEntry[i];
1619  PartitionInfo->PartitionType = PartitionType;
1620  PartitionInfo->RewritePartition = FALSE;
1621 
1622  /* Check if we're dealing with a partition that's in use */
1624  {
1625  /* Check if it's bootable */
1626  PartitionInfo->BootIndicator = PartitionDescriptor->
1627  ActiveFlag & 0x80 ?
1628  TRUE : FALSE;
1629 
1630  /* Check if its' a container */
1632  {
1633  /* Then don't recognize it and use the volume offset */
1634  PartitionInfo->RecognizedPartition = FALSE;
1635  StartOffset = VolumeOffset.QuadPart;
1636  }
1637  else
1638  {
1639  /* Then recognize it and use the partition offset */
1640  PartitionInfo->RecognizedPartition = TRUE;
1641  StartOffset = Offset.QuadPart;
1642  }
1643 
1644  /* Get the starting offset */
1645  PartitionInfo->StartingOffset.QuadPart =
1646  StartOffset +
1647  UInt32x32To64(GET_STARTING_SECTOR(PartitionDescriptor),
1648  SectorSize);
1649 
1650  /* Calculate the number of hidden sectors */
1651  HiddenSectors64.QuadPart = (PartitionInfo->
1652  StartingOffset.QuadPart -
1653  StartOffset) /
1654  SectorSize;
1655  PartitionInfo->HiddenSectors = HiddenSectors64.LowPart;
1656 
1657  /* Get the partition length */
1658  PartitionInfo->PartitionLength.QuadPart =
1659  UInt32x32To64(GET_PARTITION_LENGTH(PartitionDescriptor),
1660  SectorSize);
1661 
1662  /* Get the partition number */
1663  PartitionInfo->PartitionNumber = (!IsContainerPartition(PartitionType)) ? i + 1 : 0;
1664  }
1665  else
1666  {
1667  /* Otherwise, clear all the relevant fields */
1668  PartitionInfo->BootIndicator = FALSE;
1669  PartitionInfo->RecognizedPartition = FALSE;
1670  PartitionInfo->StartingOffset.QuadPart = 0;
1671  PartitionInfo->PartitionLength.QuadPart = 0;
1672  PartitionInfo->HiddenSectors = 0;
1673 
1674  PartitionInfo->PartitionNumber = 0;
1675  }
1676  }
1677 
1678  /* Finish debug log, and check for failure */
1679  DPRINT("\n");
1680  if (!NT_SUCCESS(Status)) break;
1681 
1682  /* Also check if we hit an invalid entry here */
1683  if (!IsValid)
1684  {
1685  /* We did, so break out of the loop minus one entry */
1686  j--;
1687  break;
1688  }
1689 
1690  /* Reset the offset */
1691  Offset.QuadPart = 0;
1692 
1693  /* Go back to the descriptor array and loop it */
1694  PartitionDescriptor = (PPARTITION_DESCRIPTOR)
1696  for (Entry = 1; Entry <= 4; Entry++, PartitionDescriptor++)
1697  {
1698  /* Check if this is a container partition, since we skipped them */
1699  if (IsContainerPartition(PartitionDescriptor->PartitionType))
1700  {
1701  /* Get its offset */
1702  Offset.QuadPart = VolumeOffset.QuadPart +
1703  UInt32x32To64(
1704  GET_STARTING_SECTOR(PartitionDescriptor),
1705  SectorSize);
1706 
1707  /* If this is a primary partition, this is the volume offset */
1708  if (IsPrimary) VolumeOffset = Offset;
1709 
1710  /* Also update the maximum sector */
1711  MaxSector = GET_PARTITION_LENGTH(PartitionDescriptor);
1712  DPRINT1("FSTUB: MaxSector now = %I64d\n", MaxSector);
1713  break;
1714  }
1715  }
1716 
1717  /* Loop the next partitions, which are not primary anymore */
1718  IsPrimary = FALSE;
1719  } while (Offset.HighPart | Offset.LowPart);
1720 
1721  /* Check if this is a removable device that's probably a super-floppy */
1722  if ((DiskGeometry.MediaType == RemovableMedia) &&
1723  (j == 0) && (MbrFound) && (IsEmpty))
1724  {
1725  PBOOT_SECTOR_INFO BootSectorInfo = (PBOOT_SECTOR_INFO)Buffer;
1726 
1727  /* Read the jump bytes to detect super-floppy */
1728  if ((BootSectorInfo->JumpByte[0] == 0xeb) ||
1729  (BootSectorInfo->JumpByte[0] == 0xe9))
1730  {
1731  /* Super floppes don't have typical MBRs, so skip them */
1732  DPRINT1("FSTUB: Jump byte %#x found along with empty partition "
1733  "table - disk is a super floppy and has no valid MBR\n",
1734  BootSectorInfo->JumpByte);
1735  j = -1;
1736  }
1737  }
1738 
1739  /* Check if we're still at partition -1 */
1740  if (j == -1)
1741  {
1742  /* The likely cause is the super floppy detection above */
1743  if ((MbrFound) || (DiskGeometry.MediaType == RemovableMedia))
1744  {
1745  /* Print out debugging information */
1746  DPRINT1("FSTUB: Drive %#p has no valid MBR. Make it into a "
1747  "super-floppy\n",
1748  DeviceObject);
1749  DPRINT1("FSTUB: Drive has %I64d sectors and is %#016I64x "
1750  "bytes large\n",
1751  EndSector, EndSector * DiskGeometry.BytesPerSector);
1752 
1753  /* We should at least have some sectors */
1754  if (EndSector > 0)
1755  {
1756  /* Get the entry we'll use */
1757  PartitionInfo = &(*PartitionBuffer)->PartitionEntry[0];
1758 
1759  /* Fill it out with data for a super-floppy */
1760  PartitionInfo->RewritePartition = FALSE;
1761  PartitionInfo->RecognizedPartition = TRUE;
1762  PartitionInfo->PartitionType = PARTITION_FAT_16;
1763  PartitionInfo->BootIndicator = FALSE;
1764  PartitionInfo->HiddenSectors = 0;
1765  PartitionInfo->StartingOffset.QuadPart = 0;
1766  PartitionInfo->PartitionLength.QuadPart = (EndSector *
1767  DiskGeometry.
1768  BytesPerSector);
1769 
1770  /* FIXME: REACTOS HACK */
1771  PartitionInfo->PartitionNumber = 0;
1772 
1773  /* Set the signature and set the count back to 0 */
1774  (*PartitionBuffer)->Signature = 1;
1775  i = 0;
1776  }
1777  }
1778  else
1779  {
1780  /* Otherwise, this isn't a super floppy, so set an invalid count */
1781  i = -1;
1782  }
1783  }
1784 
1785  /* Set the partition count */
1786  (*PartitionBuffer)->PartitionCount = ++i;
1787 
1788  /* If we have no count, delete the signature */
1789  if (!i) (*PartitionBuffer)->Signature = 0;
1790 
1791  /* Free the buffer and check for success */
1793  if (!NT_SUCCESS(Status))
1794  {
1796  *PartitionBuffer = NULL;
1797  }
1798 
1799  /* Return status */
1800  return Status;
1801 }
1802 
1803 NTSTATUS
1804 FASTCALL
1809 {
1810  PIRP Irp;
1811  KEVENT Event;
1813  NTSTATUS Status;
1814  LARGE_INTEGER Offset, VolumeOffset;
1815  PUCHAR Buffer = NULL;
1816  ULONG BufferSize;
1817  ULONG i = 0;
1818  ULONG Entry;
1819  PPARTITION_DESCRIPTOR PartitionDescriptor;
1820  BOOLEAN IsPrimary = TRUE, IsEzDrive = FALSE;
1821  PVOID MbrBuffer;
1822  PIO_STACK_LOCATION IoStackLocation;
1823  VolumeOffset.QuadPart = Offset.QuadPart = 0;
1824  PAGED_CODE();
1825 
1826  /* Normalize the buffer size */
1827  BufferSize = max(512, SectorSize);
1828 
1829  /* Check for EZ Drive */
1830  HalExamineMBR(DeviceObject, BufferSize, 0x55, &MbrBuffer);
1831  if (MbrBuffer)
1832  {
1833  /* EZ Drive found, bias the offset */
1834  IsEzDrive = TRUE;
1835  ExFreePoolWithTag(MbrBuffer, TAG_FILE_SYSTEM);
1836  Offset.QuadPart = 512;
1837  }
1838 
1839  /* Allocate our partition buffer */
1842 
1843  /* Initialize the event we'll use and loop partitions */
1845  do
1846  {
1847  /* Reset the event since we reuse it */
1848  KeClearEvent(&Event);
1849 
1850  /* Build the read IRP */
1852  DeviceObject,
1853  Buffer,
1854  BufferSize,
1855  &Offset,
1856  &Event,
1857  &IoStatusBlock);
1858  if (!Irp)
1859  {
1860  /* Fail */
1862  break;
1863  }
1864 
1865  /* Make sure to disable volume verification */
1866  IoStackLocation = IoGetNextIrpStackLocation(Irp);
1867  IoStackLocation->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
1868 
1869  /* Call the driver */
1871  if (Status == STATUS_PENDING)
1872  {
1873  /* Wait for completion */
1876  }
1877 
1878  /* Check for failure */
1879  if (!NT_SUCCESS(Status)) break;
1880 
1881  /* If we biased for EZ-Drive, unbias now */
1882  if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
1883 
1884  /* Make sure this is a valid MBR */
1886  {
1887  /* It's not, fail */
1889  break;
1890  }
1891 
1892  /* Get the partition descriptors and loop them */
1893  PartitionDescriptor = (PPARTITION_DESCRIPTOR)
1895  for (Entry = 1; Entry <= 4; Entry++, PartitionDescriptor++)
1896  {
1897  /* Check if it's unused or a container partition */
1898  if ((PartitionDescriptor->PartitionType ==
1900  (IsContainerPartition(PartitionDescriptor->PartitionType)))
1901  {
1902  /* Go to the next one */
1903  continue;
1904  }
1905 
1906  /* It's a valid partition, so increase the partition count */
1907  if (++i == PartitionNumber)
1908  {
1909  /* We found a match, set the type */
1910  PartitionDescriptor->PartitionType = (UCHAR)PartitionType;
1911 
1912  /* Reset the reusable event */
1913  KeClearEvent(&Event);
1914 
1915  /* Build the write IRP */
1917  DeviceObject,
1918  Buffer,
1919  BufferSize,
1920  &Offset,
1921  &Event,
1922  &IoStatusBlock);
1923  if (!Irp)
1924  {
1925  /* Fail */
1927  break;
1928  }
1929 
1930  /* Disable volume verification */
1931  IoStackLocation = IoGetNextIrpStackLocation(Irp);
1932  IoStackLocation->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
1933 
1934  /* Call the driver */
1936  if (Status == STATUS_PENDING)
1937  {
1938  /* Wait for completion */
1940  Executive,
1941  KernelMode,
1942  FALSE,
1943  NULL);
1945  }
1946 
1947  /* We're done, break out of the loop */
1948  break;
1949  }
1950  }
1951 
1952  /* If we looped all the partitions, break out */
1953  if (Entry <= NUM_PARTITION_TABLE_ENTRIES) break;
1954 
1955  /* Nothing found yet, get the partition array again */
1956  PartitionDescriptor = (PPARTITION_DESCRIPTOR)
1958  for (Entry = 1; Entry <= 4; Entry++, PartitionDescriptor++)
1959  {
1960  /* Check if this was a container partition (we skipped these) */
1961  if (IsContainerPartition(PartitionDescriptor->PartitionType))
1962  {
1963  /* Update the partition offset */
1964  Offset.QuadPart = VolumeOffset.QuadPart +
1965  GET_STARTING_SECTOR(PartitionDescriptor) *
1966  SectorSize;
1967 
1968  /* If this was the primary partition, update the volume too */
1969  if (IsPrimary) VolumeOffset = Offset;
1970  break;
1971  }
1972  }
1973 
1974  /* Check if we already searched all the partitions */
1976  {
1977  /* Then we failed to find a good MBR */
1979  break;
1980  }
1981 
1982  /* Loop the next partitions, which are not primary anymore */
1983  IsPrimary = FALSE;
1984  } while (i < PartitionNumber);
1985 
1986  /* Everything done, cleanup */
1988  return Status;
1989 }
1990 
1991 NTSTATUS
1992 FASTCALL
1998 {
1999  KEVENT Event;
2001  PIRP Irp;
2003  ULONG BufferSize;
2004  PUSHORT Buffer;
2005  PPTE Entry;
2006  PPARTITION_TABLE PartitionTable;
2007  LARGE_INTEGER Offset, NextOffset, ExtendedOffset, SectorOffset;
2008  LARGE_INTEGER StartOffset, PartitionLength;
2009  ULONG i, j;
2010  CCHAR k;
2011  BOOLEAN IsEzDrive = FALSE, IsSuperFloppy = FALSE, DoRewrite = FALSE, IsMbr;
2012  ULONG ConventionalCylinders;
2013  LONGLONG DiskSize;
2015  PVOID MbrBuffer;
2017  PIO_STACK_LOCATION IoStackLocation;
2020  ExtendedOffset.QuadPart = NextOffset.QuadPart = Offset.QuadPart = 0;
2021  PAGED_CODE();
2022 
2023  /* Normalize the buffer size */
2024  BufferSize = max(512, SectorSize);
2025 
2026  /* Get the partial drive geometry */
2027  xHalGetPartialGeometry(DeviceObject, &ConventionalCylinders, &DiskSize);
2028 
2029  /* Check for EZ Drive */
2030  HalExamineMBR(DeviceObject, BufferSize, 0x55, &MbrBuffer);
2031  if (MbrBuffer)
2032  {
2033  /* EZ Drive found, bias the offset */
2034  IsEzDrive = TRUE;
2035  ExFreePoolWithTag(MbrBuffer, TAG_FILE_SYSTEM);
2036  Offset.QuadPart = 512;
2037  }
2038 
2039  /* Get the number of bits to shift to multiply by the sector size */
2040  for (k = 0; k < 32; k++) if ((SectorSize >> k) == 1) break;
2041 
2042  /* Check if there's only one partition */
2043  if (PartitionBuffer->PartitionCount == 1)
2044  {
2045  /* Check if it has no starting offset or hidden sectors */
2046  if (!(PartitionInfo->StartingOffset.QuadPart) &&
2047  !(PartitionInfo->HiddenSectors))
2048  {
2049  /* Then it's a super floppy */
2050  IsSuperFloppy = TRUE;
2051 
2052  /* Which also means it must be non-bootable FAT-16 */
2053  if ((PartitionInfo->PartitionNumber) ||
2054  (PartitionInfo->PartitionType != PARTITION_FAT_16) ||
2055  (PartitionInfo->BootIndicator))
2056  {
2057  /* It's not, so we fail */
2058  return STATUS_INVALID_PARAMETER;
2059  }
2060 
2061  /* Check if it needs a rewrite, and disable EZ drive for sure */
2062  if (PartitionInfo->RewritePartition) DoRewrite = TRUE;
2063  IsEzDrive = FALSE;
2064  }
2065  }
2066 
2067  /* Count the number of partition tables */
2068  DiskLayout->TableCount = (PartitionBuffer->PartitionCount + 4 - 1) / 4;
2069 
2070  /* Allocate our partition buffer */
2073 
2074  /* Loop the entries */
2076  for (i = 0; i < DiskLayout->TableCount; i++)
2077  {
2078  /* Set if this is the MBR partition */
2079  IsMbr= (BOOLEAN)!i;
2080 
2081  /* Initialize th event */
2083 
2084  /* Build the read IRP */
2086  DeviceObject,
2087  Buffer,
2088  BufferSize,
2089  &Offset,
2090  &Event,
2091  &IoStatusBlock);
2092  if (!Irp)
2093  {
2094  /* Fail */
2096  break;
2097  }
2098 
2099  /* Make sure to disable volume verification */
2100  IoStackLocation = IoGetNextIrpStackLocation(Irp);
2101  IoStackLocation->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
2102 
2103  /* Call the driver */
2105  if (Status == STATUS_PENDING)
2106  {
2107  /* Wait for completion */
2110  }
2111 
2112  /* Check for failure */
2113  if (!NT_SUCCESS(Status)) break;
2114 
2115  /* If we biased for EZ-Drive, unbias now */
2116  if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
2117 
2118  /* Check if this is a normal disk */
2119  if (!IsSuperFloppy)
2120  {
2121  /* Set the boot record signature */
2123 
2124  /* By default, don't require a rewrite */
2125  DoRewrite = FALSE;
2126 
2127  /* Check if we don't have an offset */
2128  if (!Offset.QuadPart)
2129  {
2130  /* Check if the signature doesn't match */
2131  if (((PULONG)Buffer)[PARTITION_TABLE_OFFSET / 2 - 1] !=
2132  PartitionBuffer->Signature)
2133  {
2134  /* Then write the signature and now we need a rewrite */
2135  ((PULONG)Buffer)[PARTITION_TABLE_OFFSET / 2 - 1] =
2136  PartitionBuffer->Signature;
2137  DoRewrite = TRUE;
2138  }
2139  }
2140 
2141  /* Loop the partition table entries */
2142  PartitionTable = &DiskLayout->PartitionTable[i];
2143  for (j = 0; j < 4; j++)
2144  {
2145  /* Get the current entry and type */
2146  TableEntry = &PartitionTable->PartitionEntry[j];
2147  PartitionType = TableEntry->PartitionType;
2148 
2149  /* Check if the entry needs a rewrite */
2150  if (TableEntry->RewritePartition)
2151  {
2152  /* Then we need one too */
2153  DoRewrite = TRUE;
2154 
2155  /* Save the type and if it's a bootable partition */
2156  Entry[j].PartitionType = TableEntry->PartitionType;
2157  Entry[j].ActiveFlag = TableEntry->BootIndicator ? 0x80 : 0;
2158 
2159  /* Make sure it's used */
2161  {
2162  /* Make sure it's not a container (unless primary) */
2163  if ((IsMbr) || !(IsContainerPartition(PartitionType)))
2164  {
2165  /* Use the partition offset */
2166  StartOffset.QuadPart = Offset.QuadPart;
2167  }
2168  else
2169  {
2170  /* Use the extended logical partition offset */
2171  StartOffset.QuadPart = ExtendedOffset.QuadPart;
2172  }
2173 
2174  /* Set the sector offset */
2175  SectorOffset.QuadPart = TableEntry->
2176  StartingOffset.QuadPart -
2177  StartOffset.QuadPart;
2178 
2179  /* Now calculate the starting sector */
2180  StartOffset.QuadPart = SectorOffset.QuadPart >> k;
2181  Entry[j].StartingSector = StartOffset.LowPart;
2182 
2183  /* As well as the length */
2184  PartitionLength.QuadPart = TableEntry->PartitionLength.
2185  QuadPart >> k;
2186  Entry[j].PartitionLength = PartitionLength.LowPart;
2187 
2188  /* Calculate the CHS values */
2189  HalpCalculateChsValues(&TableEntry->StartingOffset,
2190  &TableEntry->PartitionLength,
2191  k,
2193  NumberOfHeads,
2194  ConventionalCylinders,
2196  &Entry[j]);
2197  }
2198  else
2199  {
2200  /* Otherwise set up an empty entry */
2201  Entry[j].StartingSector = 0;
2202  Entry[j].PartitionLength = 0;
2203  Entry[j].StartingTrack = 0;
2204  Entry[j].EndingTrack = 0;
2205  Entry[j].StartingCylinder = 0;
2206  Entry[j].EndingCylinder = 0;
2207  }
2208  }
2209 
2210  /* Check if this is a container partition */
2212  {
2213  /* Then update the offset to use */
2214  NextOffset = TableEntry->StartingOffset;
2215  }
2216  }
2217  }
2218 
2219  /* Check if we need to write back the buffer */
2220  if (DoRewrite)
2221  {
2222  /* We don't need to do this again */
2223  DoRewrite = FALSE;
2224 
2225  /* Initialize the event */
2227 
2228  /* If we unbiased for EZ-Drive, rebias now */
2229  if ((IsEzDrive) && !(Offset.QuadPart)) Offset.QuadPart = 512;
2230 
2231  /* Build the write IRP */
2233  DeviceObject,
2234  Buffer,
2235  BufferSize,
2236  &Offset,
2237  &Event,
2238  &IoStatusBlock);
2239  if (!Irp)
2240  {
2241  /* Fail */
2243  break;
2244  }
2245 
2246  /* Make sure to disable volume verification */
2247  IoStackLocation = IoGetNextIrpStackLocation(Irp);
2248  IoStackLocation->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
2249 
2250  /* Call the driver */
2252  if (Status == STATUS_PENDING)
2253  {
2254  /* Wait for completion */
2256  Executive,
2257  KernelMode,
2258  FALSE,
2259  NULL);
2261  }
2262 
2263  /* Check for failure */
2264  if (!NT_SUCCESS(Status)) break;
2265 
2266  /* If we biased for EZ-Drive, unbias now */
2267  if (IsEzDrive && (Offset.QuadPart == 512)) Offset.QuadPart = 0;
2268  }
2269 
2270  /* Update the partition offset and set the extended offset if needed */
2271  Offset = NextOffset;
2272  if (IsMbr) ExtendedOffset = NextOffset;
2273  }
2274 
2275  /* If we had a buffer, free it, then return status */
2277  return Status;
2278 }
2279 
2280 /* PUBLIC FUNCTIONS **********************************************************/
2281 
2282 /*
2283  * @implemented
2284  */
2285 VOID
2286 FASTCALL
2289  IN ULONG MbrTypeIdentifier,
2290  OUT PVOID *MbrBuffer)
2291 {
2292  HALDISPATCH->HalExamineMBR(DeviceObject,
2293  SectorSize,
2294  MbrTypeIdentifier,
2295  MbrBuffer);
2296 }
2297 
2298 /*
2299  * @implemented
2300  */
2301 NTSTATUS
2302 FASTCALL
2307 {
2308  return HALDISPATCH->HalIoReadPartitionTable(DeviceObject,
2309  SectorSize,
2311  PartitionBuffer);
2312 }
2313 
2314 /*
2315  * @implemented
2316  */
2317 NTSTATUS
2318 FASTCALL
2323 {
2324  return HALDISPATCH->HalIoSetPartitionInformation(DeviceObject,
2325  SectorSize,
2327  PartitionType);
2328 }
2329 
2330 /*
2331  * @implemented
2332  */
2333 NTSTATUS
2334 FASTCALL
2340 {
2341  return HALDISPATCH->HalIoWritePartitionTable(DeviceObject,
2342  SectorSize,
2344  NumberOfHeads,
2345  PartitionBuffer);
2346 }
2347 
2348 /*
2349  * @implemented
2350  */
2351 VOID
2352 FASTCALL
2354  IN PSTRING NtDeviceName,
2355  OUT PUCHAR NtSystemPath,
2356  OUT PSTRING NtSystemPathString)
2357 {
2358  HALDISPATCH->HalIoAssignDriveLetters(LoaderBlock,
2359  NtDeviceName,
2360  NtSystemPath,
2361  NtSystemPathString);
2362 }
2363 
2364 /* EOF */
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
NTSTATUS FASTCALL IoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
Definition: disksup.c:2319
#define TAG_FILE_SYSTEM
Definition: tag.h:50
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
LARGE_INTEGER StartingOffset
Definition: partlist.c:25
#define GET_STARTING_SECTOR(p)
Definition: hal.h:252
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:394
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define EFI_PMBR_OSTYPE_EFI
Definition: disksup.c:27
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
struct _Entry Entry
Definition: kefuncs.h:640
Definition: hal.h:331
#define DbgPrint
Definition: loader.c:25
struct _PTE * PPTE
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
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
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
#define REG_BINARY
Definition: nt_native.h:1496
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
UCHAR JumpByte[1]
Definition: hal.h:301
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
VOID NTAPI HalpCalculateChsValues(IN PLARGE_INTEGER PartitionOffset, IN PLARGE_INTEGER PartitionLength, IN CCHAR ShiftCount, IN ULONG SectorsPerTrack, IN ULONG NumberOfTracks, IN ULONG ConventionalCylinders, OUT PPARTITION_DESCRIPTOR PartitionDescriptor)
Definition: disksup.c:1085
unsigned char * PUCHAR
Definition: retypes.h:3
#define iswdigit(_c)
Definition: ctype.h:667
Definition: bl.h:252
LONG NTSTATUS
Definition: precomp.h:26
#define DOSDEVICE_DRIVE_CDROM
Definition: obtypes.h:168
#define STATUS_BAD_MASTER_BOOT_RECORD
Definition: ntstatus.h:391
#define PARTITION_TABLE_OFFSET
Definition: hal.h:243
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
ULONG xHalpGetRDiskCount(VOID)
Definition: disksup.c:147
static HANDLE DirectoryHandle
Definition: ObType.c:48
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
UINT DriveType
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:245
ULONG BytesPerSector
Definition: ntdddisk.h:376
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
ULONG TracksPerCylinder
Definition: ntdddisk.h:374
uint16_t * PWCHAR
Definition: typedefs.h:54
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
Definition: iofuncs.h:2066
WCHAR DeviceName[]
Definition: adapter.cpp:21
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
#define SET_PARTITION_LENGTH(p, l)
Definition: hal.h:267
struct _DISK_LAYOUT * PDISK_LAYOUT
#define PAGED_CODE()
Definition: video.h:57
#define FILE_SHARE_READ
Definition: compat.h:125
PARTITION_INFORMATION PartitionEntry[4]
Definition: hal.h:318
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
struct _REG_DISK_MOUNT_INFO REG_DISK_MOUNT_INFO
VOID FASTCALL xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MbrTypeIdentifier, OUT PVOID *MbrBuffer)
Definition: disksup.c:1246
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
ULONG DriveMap
Definition: obtypes.h:528
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:389
WCHAR First[]
Definition: FormatMessage.c:11
#define DOSDEVICE_DRIVE_REMOVABLE
Definition: obtypes.h:165
HANDLE FileHandle
Definition: stats.c:38
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2066
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct _REG_DISK_MOUNT_INFO * PREG_DISK_MOUNT_INFO
long LONG
Definition: pedump.c:60
VOID FASTCALL xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PSTRING NtDeviceName, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString)
Definition: disksup.c:415
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
NTSTATUS FASTCALL xHalIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
Definition: disksup.c:1805
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
_In_ ULONG _In_ BOOLEAN _Out_ struct _DRIVE_LAYOUT_INFORMATION ** PartitionBuffer
Definition: iofuncs.h:2048
#define SectorOffset(L)
Definition: cdprocs.h:1632
unsigned char BOOLEAN
#define AUTO_DRIVE
Definition: disksup.c:23
smooth NULL
Definition: ftsmooth.c:416
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:471
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
return Found
Definition: dirsup.c:1270
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
NTSTATUS NTAPI HalpGetFullGeometry(IN PDEVICE_OBJECT DeviceObject, IN PDISK_GEOMETRY Geometry, OUT PULONGLONG RealSectorCount)
Definition: disksup.c:950
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 GLint GLint j
Definition: glfuncs.h:250
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
int64_t LONGLONG
Definition: typedefs.h:66
#define GET_PARTITION_LENGTH(p)
Definition: hal.h:261
NTSTATUS FASTCALL IoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, IN OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
Definition: disksup.c:2303
_DISK_MANAGER
Definition: disksup.c:39
NTSTATUS FASTCALL xHalIoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, IN OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
Definition: disksup.c:1371
#define DOSDEVICE_DRIVE_FIXED
Definition: obtypes.h:166
#define BOOT_RECORD_SIGNATURE
Definition: parttest.c:17
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
char CCHAR
Definition: typedefs.h:50
UCHAR PartitionType
Definition: hal.h:282
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONG TableCount
Definition: hal.h:323
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:372
ULONG SectorsPerTrack
Definition: ntdddisk.h:375
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:271
#define swprintf(buf, format,...)
Definition: sprintf.c:56
struct _PARTITION_DESCRIPTOR * PPARTITION_DESCRIPTOR
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
#define BufferSize
Definition: classpnp.h:419
MEDIA_TYPE MediaType
Definition: ntdddisk.h:373
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PARTITION_TABLE PartitionTable[1]
Definition: hal.h:325
#define PARTITION_FAT_16
Definition: disk.h:90
static BOOLEAN HalpAssignDrive(IN PUNICODE_STRING PartitionName, IN ULONG DriveNumber, IN UCHAR DriveType, IN ULONG Signature, IN LARGE_INTEGER StartingOffset, IN HANDLE hKey, IN PUNICODE_STRING BootDevice, OUT PUCHAR NtSystemPath)
Definition: disksup.c:47
VOID NTAPI FstubFixupEfiPartition(IN PPARTITION_DESCRIPTOR PartitionDescriptor, IN ULONGLONG MaxOffset)
Definition: disksup.c:1352
* PFILE_OBJECT
Definition: iotypes.h:1955
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BOOLEAN RewritePartition
Definition: ntdddisk.h:400
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:88
static const WCHAR L[]
Definition: oid.c:1250
BOOLEAN NTAPI HalpIsValidPartitionEntry(IN PPARTITION_DESCRIPTOR Entry, IN ULONGLONG MaxOffset, IN ULONGLONG MaxSector)
Definition: disksup.c:1044
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
NTSTATUS FASTCALL xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
Definition: disksup.c:1993
_In_ ULONG _In_ BOOLEAN ReturnRecognizedPartitions
Definition: iofuncs.h:2046
NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG)
Definition: largeint.c:31
#define BOOT_SIGNATURE_OFFSET
Definition: hal.h:244
ULONG LowPart
Definition: typedefs.h:104
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define STATUS_NO_DATA_DETECTED
Definition: udferr_usr.h:131
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
PDEVICE_MAP ObSystemDeviceMap
Definition: obinit.c:46
ULONG SectorCount
Definition: part_xbox.c:32
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
UCHAR ActiveFlag
Definition: hal.h:278
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID FASTCALL xHalGetPartialGeometry(IN PDEVICE_OBJECT DeviceObject, IN PULONG ConventionalCylinders, IN PLONGLONG DiskSize)
Definition: disksup.c:1160
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:679
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
const WCHAR DiskMountString[]
Definition: disksup.c:21
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
NTSTATUS xHalpGetDiskNumberFromRDisk(ULONG RDisk, PULONG DiskNumber)
Definition: disksup.c:234
VOID FASTCALL IoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PSTRING NtDeviceName, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString)
Definition: disksup.c:2353
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 DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ typedef _In_ ULONG TableEntry
Definition: iotypes.h:3947
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
CHAR PartitionType
Definition: part_xbox.c:33
ret QuadPart
Definition: rtlfuncs.h:3091
#define NUM_PARTITION_TABLE_ENTRIES
Definition: hal.h:247
unsigned int ULONG
Definition: retypes.h:1
enum _DISK_MANAGER DISK_MANAGER
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID FASTCALL HalExamineMBR(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MbrTypeIdentifier, OUT PVOID *MbrBuffer)
Definition: disksup.c:2287
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_In_ ULONG SectorSize
Definition: halfuncs.h:291
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
static const WCHAR Signature[]
Definition: parser.c:141
static DISK_MOUNT_INFO DiskMountInfo[MAX_DISK_TYPE]
Definition: disk.c:478
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define UInt32x32To64(a, b)
Definition: intsafe.h:258
#define UL
Definition: tui.h:83
int k
Definition: mpi.c:3369
unsigned short * PUSHORT
Definition: retypes.h:2
NTSTATUS FASTCALL IoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
Definition: disksup.c:2335
#define HALDISPATCH
Definition: haltypes.h:278
base of all file and directory entries
Definition: entries.h:82
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
struct _BOOT_SECTOR_INFO * PBOOT_SECTOR_INFO
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
LONGLONG QuadPart
Definition: typedefs.h:112
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3046
NTSTATUS FASTCALL xHalQueryDriveLayout(IN PUNICODE_STRING DeviceName, OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo)
Definition: disksup.c:306