--- trunk/reactos/ntoskrnl/io/arcname.c 2005-09-15 17:19:31 UTC (rev 17864)
+++ trunk/reactos/ntoskrnl/io/arcname.c 2005-09-15 17:23:41 UTC (rev 17865)
@@ -19,56 +19,197 @@
#define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
-/* FUNCTIONS ****************************************************************/
+/* STRUCTURES ***************************************************************/
-NTSTATUS INIT_FUNCTION
-IoCreateArcNames(VOID)
+typedef struct _DISKENTRY
{
- PCONFIGURATION_INFORMATION ConfigInfo;
- PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
- WCHAR DeviceNameBuffer[80];
- WCHAR ArcNameBuffer[80];
- UNICODE_STRING DeviceName;
- UNICODE_STRING ArcName;
- ULONG i, j, k;
- NTSTATUS Status;
- PFILE_OBJECT FileObject;
+ LIST_ENTRY ListEntry;
+ ULONG DiskNumber;
+ ULONG Signature;
+ ULONG Checksum;
PDEVICE_OBJECT DeviceObject;
- BOOL IsRemovableMedia;
+} DISKENTRY, *PDISKENTRY;
- DPRINT("IoCreateArcNames() called\n");
+#define PARTITION_TBL_SIZE 4
- ConfigInfo = IoGetConfigurationInformation();
+#include <pshpack1.h>
- /* create ARC names for floppy drives */
- DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
- for (i = 0; i < ConfigInfo->FloppyCount; i++)
+typedef struct _PARTITION
+{
+ unsigned char BootFlags; /* bootable? 0=no, 128=yes */
+ unsigned char StartingHead; /* beginning head number */
+ unsigned char StartingSector; /* beginning sector number */
+ unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
+ unsigned char PartitionType; /* Operating System type indicator code */
+ unsigned char EndingHead; /* ending head number */
+ unsigned char EndingSector; /* ending sector number */
+ unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
+ unsigned int StartingBlock; /* first sector relative to start of disk */
+ unsigned int SectorCount; /* number of sectors in partition */
+} PARTITION, *PPARTITION;
+
+typedef struct _PARTITION_SECTOR
+{
+ UCHAR BootCode[440]; /* 0x000 */
+ ULONG Signature; /* 0x1B8 */
+ UCHAR Reserved[2]; /* 0x1BC */
+ PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
+ USHORT Magic; /* 0x1FE */
+} PARTITION_SECTOR, *PPARTITION_SECTOR;
+
+#include <poppack.h>
+
+/* FUNCTIONS ****************************************************************/
+
+STATIC
+NTSTATUS
+STDCALL
+INIT_FUNCTION
+DiskQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ PLIST_ENTRY ListHead = (PLIST_ENTRY)Context;
+ PULONG GlobalDiskCount = (PULONG)EntryContext;
+ PDISKENTRY DiskEntry;
+ UNICODE_STRING NameU;
+
+ if (ValueType == REG_SZ &&
+ ValueLength == 20 * sizeof(WCHAR))
{
- swprintf(DeviceNameBuffer,
- L"\\Device\\Floppy%lu",
- i);
- RtlInitUnicodeString(&DeviceName,
- DeviceNameBuffer);
+ DiskEntry = ExAllocatePool(PagedPool, sizeof(DISKENTRY));
+ if (DiskEntry == NULL)
+ {
+ return STATUS_NO_MEMORY;
+ }
+ DiskEntry->DiskNumber = (*GlobalDiskCount)++;
- swprintf(ArcNameBuffer,
- L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
- i);
- RtlInitUnicodeString(&ArcName,
- ArcNameBuffer);
- DPRINT("%wZ ==> %wZ\n",
- &ArcName,
- &DeviceName);
+ NameU.Buffer = (PWCHAR)ValueData;
+ NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
+ RtlUnicodeStringToInteger(&NameU, 16, &DiskEntry->Checksum);
- Status = IoAssignArcName(&ArcName,
- &DeviceName);
+ NameU.Buffer = (PWCHAR)ValueData + 9;
+ RtlUnicodeStringToInteger(&NameU, 16, &DiskEntry->Signature);
+
+ InsertTailList(ListHead, &DiskEntry->ListEntry);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
+
+STATIC VOID INIT_FUNCTION
+IopEnumerateBiosDisks(PLIST_ENTRY ListHead)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ WCHAR Name[100];
+ ULONG AdapterCount;
+ ULONG ControllerCount;
+ ULONG DiskCount;
+ NTSTATUS Status;
+ ULONG GlobalDiskCount=0;
+
+
+ memset(QueryTable, 0, sizeof(QueryTable));
+ QueryTable[0].Name = L"Identifier";
+ QueryTable[0].QueryRoutine = DiskQueryRoutine;
+ QueryTable[0].EntryContext = (PVOID)&GlobalDiskCount;
+
+ AdapterCount = 0;
+ while (1)
+ {
+ swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[1],
+ NULL,
+ NULL);
if (!NT_SUCCESS(Status))
- return(Status);
+ {
+ break;
+ }
+
+ swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[1],
+ NULL,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ ControllerCount = 0;
+ while (1)
+ {
+ swprintf(Name, L"%s\\%lu\\DiskController\\%lu", ROOT_NAME, AdapterCount, ControllerCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[1],
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral", ROOT_NAME, AdapterCount, ControllerCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[1],
+ NULL,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ DiskCount = 0;
+ while (1)
+ {
+ swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ QueryTable,
+ (PVOID)ListHead,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+ DiskCount++;
+ }
+ }
+ ControllerCount++;
+ }
+ }
+ AdapterCount++;
}
+}
- /* create ARC names for hard disk drives */
- DPRINT("Disk drives: %lu\n", ConfigInfo->DiskCount);
- for (i = 0, k = 0; i < ConfigInfo->DiskCount; i++)
+STATIC VOID INIT_FUNCTION
+IopEnumerateDisks(PLIST_ENTRY ListHead)
+{
+ ULONG i, k;
+ PDISKENTRY DiskEntry;
+ DISK_GEOMETRY DiskGeometry;
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK StatusBlock;
+ LARGE_INTEGER PartitionOffset;
+ PULONG Buffer;
+ WCHAR DeviceNameBuffer[80];
+ UNICODE_STRING DeviceName;
+ NTSTATUS Status;
+ PDEVICE_OBJECT DeviceObject;
+ PFILE_OBJECT FileObject;
+ BOOLEAN IsRemovableMedia;
+ PPARTITION_SECTOR PartitionBuffer = NULL;
+ ULONG PartitionBufferSize = 0;
+
+
+ for (i = 0; i < IoGetConfigurationInformation()->DiskCount; i++)
{
+
swprintf(DeviceNameBuffer,
L"\\Device\\Harddisk%lu\\Partition0",
i);
@@ -88,12 +229,249 @@
ObDereferenceObject(FileObject);
if (IsRemovableMedia)
{
+ ObDereferenceObject(DeviceObject);
continue;
}
+ DiskEntry = ExAllocatePool(PagedPool, sizeof(DISKENTRY));
+ if (DiskEntry == NULL)
+ {
+ KEBUGCHECK(0);
+ }
+ DiskEntry->DiskNumber = i;
+ DiskEntry->DeviceObject = DeviceObject;
+ /* determine the sector size */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ DeviceObject,
+ NULL,
+ 0,
+ &DiskGeometry,
+ sizeof(DISK_GEOMETRY),
+ FALSE,
+ &Event,
+ &StatusBlock);
+ if (Irp == NULL)
+ {
+ KEBUGCHECK(0);
+ }
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = StatusBlock.Status;
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECK(0);
+ }
+ if (PartitionBuffer != NULL && PartitionBufferSize < DiskGeometry.BytesPerSector)
+ {
+ ExFreePool(PartitionBuffer);
+ PartitionBuffer = NULL;
+ }
+ if (PartitionBuffer == NULL)
+ {
+ PartitionBufferSize = max(DiskGeometry.BytesPerSector, PAGE_SIZE);
+ PartitionBuffer = ExAllocatePool(PagedPool, PartitionBufferSize);
+ if (PartitionBuffer == NULL)
+ {
+ KEBUGCHECK(0);
+ }
+ }
+
+ /* read the partition sector */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ PartitionOffset.QuadPart = 0;
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+ DeviceObject,
+ PartitionBuffer,
+ DiskGeometry.BytesPerSector,
+ &PartitionOffset,
+ &Event,
+ &StatusBlock);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECK(0);
+ }
+
+ /* Calculate the MBR checksum */
+ DiskEntry->Checksum = 0;
+ Buffer = (PULONG)PartitionBuffer;
+ for (k = 0; k < 128; k++)
+ {
+ DiskEntry->Checksum += Buffer[k];
+ }
+ DiskEntry->Checksum = ~DiskEntry->Checksum + 1;
+ DiskEntry->Signature = PartitionBuffer->Signature;
+
+ InsertTailList(ListHead, &DiskEntry->ListEntry);
+ }
+ if (PartitionBuffer)
+ {
+ ExFreePool(PartitionBuffer);
+ }
+}
+
+STATIC NTSTATUS INIT_FUNCTION
+IopAssignArcNamesToDisk(PDEVICE_OBJECT DeviceObject, ULONG RDisk, ULONG DiskNumber)
+{
+ WCHAR DeviceNameBuffer[80];
+ WCHAR ArcNameBuffer[80];
+ UNICODE_STRING DeviceName;
+ UNICODE_STRING ArcName;
+ PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
+ NTSTATUS Status;
+ ULONG i;
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK StatusBlock;
+ ULONG PartitionNumber;
+
+ swprintf(DeviceNameBuffer,
+ L"\\Device\\Harddisk%lu\\Partition0",
+ DiskNumber);
+ RtlInitUnicodeString(&DeviceName,
+ DeviceNameBuffer);
+
+ swprintf(ArcNameBuffer,
+ L"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
+ RDisk);
+ RtlInitUnicodeString(&ArcName,
+ ArcNameBuffer);
+
+ DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
+
+ Status = IoAssignArcName(&ArcName, &DeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoAssignArcName failed, status=%lx\n", Status);
+ return(Status);
+ }
+
+ LayoutInfo = ExAllocatePool(PagedPool, 2 * PAGE_SIZE);
+ if (LayoutInfo == NULL)
+ {
+ return STATUS_NO_MEMORY;
+ }
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_LAYOUT,
+ DeviceObject,
+ NULL,
+ 0,
+ LayoutInfo,
+ 2 * PAGE_SIZE,
+ FALSE,
+ &Event,
+ &StatusBlock);
+ if (Irp == NULL)
+ {
+ ExFreePool(LayoutInfo);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = StatusBlock.Status;
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(LayoutInfo);
+ return Status;
+ }
+
+ DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);
+
+ PartitionNumber = 1;
+ for (i = 0; i < LayoutInfo->PartitionCount; i++)
+ {
+ if (!IsContainerPartition(LayoutInfo->PartitionEntry[i].PartitionType) &&
+ LayoutInfo->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED)
+ {
+
+ swprintf(DeviceNameBuffer,
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ DiskNumber,
+ PartitionNumber);
+ RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
+
+ swprintf(ArcNameBuffer,
+ L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
+ RDisk,
+ PartitionNumber);
+ RtlInitUnicodeString(&ArcName, ArcNameBuffer);
+
+ DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
+
+ Status = IoAssignArcName(&ArcName, &DeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoAssignArcName failed, status=%lx\n", Status);
+ ExFreePool(LayoutInfo);
+ return(Status);
+ }
+ PartitionNumber++;
+ }
+ }
+ ExFreePool(LayoutInfo);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS INIT_FUNCTION
+IoCreateArcNames(VOID)
+{
+ PCONFIGURATION_INFORMATION ConfigInfo;
+ WCHAR DeviceNameBuffer[80];
+ WCHAR ArcNameBuffer[80];
+ UNICODE_STRING DeviceName;
+ UNICODE_STRING ArcName;
+ ULONG i, RDiskNumber;
+ NTSTATUS Status;
+ LIST_ENTRY BiosDiskListHead;
+ LIST_ENTRY DiskListHead;
+ PLIST_ENTRY Entry;
+ PDISKENTRY BiosDiskEntry;
+ PDISKENTRY DiskEntry;
+
+ DPRINT("IoCreateArcNames() called\n");
+
+ ConfigInfo = IoGetConfigurationInformation();
+
+ /* create ARC names for floppy drives */
+ DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
+ for (i = 0; i < ConfigInfo->FloppyCount; i++)
+ {
+ swprintf(DeviceNameBuffer,
+ L"\\Device\\Floppy%lu",
+ i);
+ RtlInitUnicodeString(&DeviceName,
+ DeviceNameBuffer);
+
swprintf(ArcNameBuffer,
- L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(0)",
- k);
+ L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
+ i);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
@@ -104,42 +482,44 @@
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);
+ }
- Status = xHalQueryDriveLayout(&DeviceName,
- &LayoutInfo);
- if (!NT_SUCCESS(Status))
- return(Status);
+ /* create ARC names for hard disk drives */
+ InitializeListHead(&BiosDiskListHead);
+ InitializeListHead(&DiskListHead);
+ IopEnumerateBiosDisks(&BiosDiskListHead);
+ IopEnumerateDisks(&DiskListHead);
- DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);
+ RDiskNumber = 0;
+ while (!IsListEmpty(&BiosDiskListHead))
+ {
+ Entry = RemoveHeadList(&BiosDiskListHead);
+ BiosDiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+ Entry = DiskListHead.Flink;
+ while (Entry != &DiskListHead)
+ {
+ DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+ if (DiskEntry->Checksum == BiosDiskEntry->Checksum &&
+ DiskEntry->Signature == BiosDiskEntry->Signature)
+ {
- for (j = 0;j < LayoutInfo->PartitionCount; j++)
- {
- swprintf(DeviceNameBuffer,
- L"\\Device\\Harddisk%lu\\Partition%lu",
- i,
- j + 1);
- RtlInitUnicodeString(&DeviceName,
- DeviceNameBuffer);
+ Status = IopAssignArcNamesToDisk(DiskEntry->DeviceObject, RDiskNumber, DiskEntry->DiskNumber);
- swprintf(ArcNameBuffer,
- L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
- k,
- j + 1);
- RtlInitUnicodeString(&ArcName,
- ArcNameBuffer);
- DPRINT("%wZ ==> %wZ\n",
- &ArcName,
- &DeviceName);
+ RemoveEntryList(&DiskEntry->ListEntry);
+ ExFreePool(DiskEntry);
+ break;
+ }
+ Entry = Entry->Flink;
+ }
+ RDiskNumber++;
+ ExFreePool(BiosDiskEntry);
+ }
- Status = IoAssignArcName(&ArcName,
- &DeviceName);
- if (!NT_SUCCESS(Status))
- return(Status);
- }
-
- ExFreePool(LayoutInfo);
- LayoutInfo = NULL;
- k++;
+ while (!IsListEmpty(&DiskListHead))
+ {
+ Entry = RemoveHeadList(&DiskListHead);
+ DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+ ExFreePool(DiskEntry);
}
/* create ARC names for cdrom drives */
@@ -173,7 +553,7 @@
}
-static NTSTATUS
+static NTSTATUS INIT_FUNCTION
IopCheckCdromDevices(PULONG DeviceNumber)
{
PCONFIGURATION_INFORMATION ConfigInfo;