- Read more information from the registry about the disks detected by the bios.

- Fixed the detection of disks with a signature of zero (in AddDiskToList).  
- Update always the partition table if the modified flag is set.  
- Create an unique disk signature.  
- Declared some registry query structures in cmtype.h.


svn path=/trunk/; revision=17935
This commit is contained in:
Hartmut Birr 2005-09-19 20:01:29 +00:00
parent 1ddb0f87a0
commit 047952c5a1
3 changed files with 578 additions and 148 deletions

View file

@ -174,6 +174,116 @@ typedef struct _KEY_BASIC_INFORMATION
WCHAR Name[1]; WCHAR Name[1];
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION; } KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
#else
typedef struct _REG_DELETE_KEY_INFORMATION
{
PVOID Object;
} REG_DELETE_KEY_INFORMATION, *PREG_DELETE_KEY_INFORMATION;
typedef struct _REG_SET_VALUE_KEY_INFORMATION
{
PVOID Object;
PUNICODE_STRING ValueName;
ULONG TitleIndex;
ULONG Type;
PVOID Data;
ULONG DataSize;
} REG_SET_VALUE_KEY_INFORMATION, *PREG_SET_VALUE_KEY_INFORMATION;
typedef struct _REG_DELETE_VALUE_KEY_INFORMATION
{
PVOID Object;
PUNICODE_STRING ValueName;
} REG_DELETE_VALUE_KEY_INFORMATION, *PREG_DELETE_VALUE_KEY_INFORMATION;
typedef struct _REG_SET_INFORMATION_KEY_INFORMATION
{
PVOID Object;
KEY_SET_INFORMATION_CLASS KeySetInformationClass;
PVOID KeySetInformation;
ULONG KeySetInformationLength;
} REG_SET_INFORMATION_KEY_INFORMATION, *PREG_SET_INFORMATION_KEY_INFORMATION;
typedef struct _REG_ENUMERATE_KEY_INFORMATION
{
PVOID Object;
ULONG Index;
KEY_INFORMATION_CLASS KeyInformationClass;
PVOID KeyInformation;
ULONG Length;
PULONG ResultLength;
} REG_ENUMERATE_KEY_INFORMATION, *PREG_ENUMERATE_KEY_INFORMATION;
typedef struct _REG_ENUMERATE_VALUE_KEY_INFORMATION
{
PVOID Object;
ULONG Index;
KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass;
PVOID KeyValueInformation;
ULONG Length;
PULONG ResultLength;
} REG_ENUMERATE_VALUE_KEY_INFORMATION, *PREG_ENUMERATE_VALUE_KEY_INFORMATION;
typedef struct _REG_QUERY_KEY_INFORMATION
{
PVOID Object;
KEY_INFORMATION_CLASS KeyInformationClass;
PVOID KeyInformation;
ULONG Length;
PULONG ResultLength;
} REG_QUERY_KEY_INFORMATION, *PREG_QUERY_KEY_INFORMATION;
typedef struct _REG_QUERY_VALUE_KEY_INFORMATION
{
PVOID Object;
PUNICODE_STRING ValueName;
KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass;
PVOID KeyValueInformation;
ULONG Length;
PULONG ResultLength;
} REG_QUERY_VALUE_KEY_INFORMATION, *PREG_QUERY_VALUE_KEY_INFORMATION;
typedef struct _REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION
{
PVOID Object;
PKEY_VALUE_ENTRY ValueEntries;
ULONG EntryCount;
PVOID ValueBuffer;
PULONG BufferLength;
PULONG RequiredBufferLength;
} REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION, *PREG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION;
typedef struct _REG_PRE_CREATE_KEY_INFORMATION
{
PUNICODE_STRING CompleteName;
} REG_PRE_CREATE_KEY_INFORMATION, *PREG_PRE_CREATE_KEY_INFORMATION;
typedef struct _REG_POST_CREATE_KEY_INFORMATION
{
PUNICODE_STRING CompleteName;
PVOID Object;
NTSTATUS Status;
} REG_POST_CREATE_KEY_INFORMATION, *PREG_POST_CREATE_KEY_INFORMATION;
typedef struct _REG_PRE_OPEN_KEY_INFORMATION
{
PUNICODE_STRING CompleteName;
} REG_PRE_OPEN_KEY_INFORMATION, *PREG_PRE_OPEN_KEY_INFORMATION;
typedef struct _REG_POST_OPEN_KEY_INFORMATION
{
PUNICODE_STRING CompleteName;
PVOID Object;
NTSTATUS Status;
} REG_POST_OPEN_KEY_INFORMATION, *PREG_POST_OPEN_KEY_INFORMATION;
typedef struct _REG_POST_OPERATION_INFORMATION
{
PVOID Object;
NTSTATUS Status;
} REG_POST_OPERATION_INFORMATION,*PREG_POST_OPERATION_INFORMATION;
#endif #endif
typedef struct _PLUGPLAY_EVENT_BLOCK typedef struct _PLUGPLAY_EVENT_BLOCK
@ -275,5 +385,151 @@ typedef struct _PLUGPLAY_BUS_INSTANCE
WCHAR BusName[MAX_BUS_NAME]; WCHAR BusName[MAX_BUS_NAME];
} PLUGPLAY_BUS_INSTANCE, *PPLUGPLAY_BUS_INSTANCE; } PLUGPLAY_BUS_INSTANCE, *PPLUGPLAY_BUS_INSTANCE;
#ifdef NTOS_MODE_USER
#include <pshpack1.h>
typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
UCHAR Type;
UCHAR ShareDisposition;
USHORT Flags;
union {
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Generic;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Port;
struct {
ULONG Level;
ULONG Vector;
ULONG Affinity;
} Interrupt;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Memory;
struct {
ULONG Channel;
ULONG Port;
ULONG Reserved1;
} Dma;
struct {
ULONG Data[3];
} DevicePrivate;
struct {
ULONG Start;
ULONG Length;
ULONG Reserved;
} BusNumber;
struct {
ULONG DataSize;
ULONG Reserved1;
ULONG Reserved2;
} DeviceSpecificData;
} u;
} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Type */
#define CmResourceTypeNull 0
#define CmResourceTypePort 1
#define CmResourceTypeInterrupt 2
#define CmResourceTypeMemory 3
#define CmResourceTypeDma 4
#define CmResourceTypeDeviceSpecific 5
#define CmResourceTypeBusNumber 6
#define CmResourceTypeMaximum 7
#define CmResourceTypeNonArbitrated 128
#define CmResourceTypeConfigData 128
#define CmResourceTypeDevicePrivate 129
#define CmResourceTypePcCardConfig 130
#define CmResourceTypeMfCardConfig 131
/* CM_PARTIAL_RESOURCE_DESCRIPTOR.ShareDisposition */
typedef enum _CM_SHARE_DISPOSITION {
CmResourceShareUndetermined,
CmResourceShareDeviceExclusive,
CmResourceShareDriverExclusive,
CmResourceShareShared
} CM_SHARE_DISPOSITION;
/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypePort */
#define CM_RESOURCE_PORT_MEMORY 0x0000
#define CM_RESOURCE_PORT_IO 0x0001
#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004
#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008
#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010
#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020
#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040
#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080
/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeInterrupt */
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0x0000
#define CM_RESOURCE_INTERRUPT_LATCHED 0x0001
/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeMemory */
#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000
#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001
#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002
#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004
#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008
#define CM_RESOURCE_MEMORY_24 0x0010
#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020
/* CM_PARTIAL_RESOURCE_DESCRIPTOR.Flags if Type = CmResourceTypeDma */
#define CM_RESOURCE_DMA_8 0x0000
#define CM_RESOURCE_DMA_16 0x0001
#define CM_RESOURCE_DMA_32 0x0002
#define CM_RESOURCE_DMA_8_AND_16 0x0004
#define CM_RESOURCE_DMA_BUS_MASTER 0x0008
#define CM_RESOURCE_DMA_TYPE_A 0x0010
#define CM_RESOURCE_DMA_TYPE_B 0x0020
#define CM_RESOURCE_DMA_TYPE_F 0x0040
typedef struct _CM_PARTIAL_RESOURCE_LIST {
USHORT Version;
USHORT Revision;
ULONG Count;
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
INTERFACE_TYPE InterfaceType;
ULONG BusNumber;
CM_PARTIAL_RESOURCE_LIST PartialResourceList;
} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
typedef struct _CM_RESOURCE_LIST {
ULONG Count;
CM_FULL_RESOURCE_DESCRIPTOR List[1];
} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
typedef struct _CM_INT13_DRIVE_PARAMETER {
USHORT DriveSelect;
ULONG MaxCylinders;
USHORT SectorsPerTrack;
USHORT MaxHeads;
USHORT NumberDrives;
} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER;
typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA
{
ULONG BytesPerSector;
ULONG NumberOfCylinders;
ULONG SectorsPerTrack;
ULONG NumberOfHeads;
} CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA;
#include <poppack.h>
#endif
#endif #endif

View file

@ -424,28 +424,19 @@ ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry)
NTSTATUS NTSTATUS
STDCALL STDCALL
DiskQueryRoutine(PWSTR ValueName, DiskIdentifierQueryRoutine(PWSTR ValueName,
ULONG ValueType, ULONG ValueType,
PVOID ValueData, PVOID ValueData,
ULONG ValueLength, ULONG ValueLength,
PVOID Context, PVOID Context,
PVOID EntryContext) PVOID EntryContext)
{ {
PLIST_ENTRY ListHead = (PLIST_ENTRY)Context; PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
PULONG GlobalDiskCount = (PULONG)EntryContext;
PBIOSDISKENTRY BiosDiskEntry;
UNICODE_STRING NameU; UNICODE_STRING NameU;
if (ValueType == REG_SZ && if (ValueType == REG_SZ &&
ValueLength == 20 * sizeof(WCHAR)) ValueLength == 20 * sizeof(WCHAR))
{ {
BiosDiskEntry = RtlAllocateHeap(ProcessHeap, 0, sizeof(BIOSDISKENTRY));
if (BiosDiskEntry == NULL)
{
return STATUS_NO_MEMORY;
}
BiosDiskEntry->DiskNumber = (*GlobalDiskCount)++;
NameU.Buffer = (PWCHAR)ValueData; NameU.Buffer = (PWCHAR)ValueData;
NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR); NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum); RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
@ -453,30 +444,110 @@ DiskQueryRoutine(PWSTR ValueName,
NameU.Buffer = (PWCHAR)ValueData + 9; NameU.Buffer = (PWCHAR)ValueData + 9;
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature); RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
InsertTailList(ListHead, &BiosDiskEntry->ListEntry); return STATUS_SUCCESS;
} }
return STATUS_UNSUCCESSFUL;
return STATUS_SUCCESS;
} }
NTSTATUS
STDCALL
DiskConfigurationDataQueryRoutine(PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
ULONG ValueLength,
PVOID Context,
PVOID EntryContext)
{
PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
if (ValueType == REG_FULL_RESOURCE_DESCRIPTOR &&
ValueLength == sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
{
FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
/* FIXME:
* Is this 'paranoia' check correct ?
*/
if (FullResourceDescriptor->InterfaceType != InterfaceTypeUndefined ||
FullResourceDescriptor->BusNumber != 0 ||
FullResourceDescriptor->PartialResourceList.Count != 1 ||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type != CmResourceTypeDeviceSpecific ||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
{
return STATUS_UNSUCCESSFUL;
}
DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)(FullResourceDescriptor + 1);
BiosDiskEntry->DiskGeometry = *DiskGeometry;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
STDCALL
SystemConfigurationDataQueryRoutine(PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
ULONG ValueLength,
PVOID Context,
PVOID EntryContext)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
if (ValueType == REG_FULL_RESOURCE_DESCRIPTOR &&
ValueLength >= sizeof (CM_FULL_RESOURCE_DESCRIPTOR) &&
(ValueLength - sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) % sizeof(CM_INT13_DRIVE_PARAMETER) == 0)
{
FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
if (FullResourceDescriptor->InterfaceType != InterfaceTypeUndefined ||
FullResourceDescriptor->BusNumber != -1 ||
FullResourceDescriptor->PartialResourceList.Count != 1 ||
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type != CmResourceTypeDeviceSpecific)
{
return STATUS_UNSUCCESSFUL;
}
*Int13Drives = RtlAllocateHeap(ProcessHeap, 0, ValueLength - sizeof (CM_FULL_RESOURCE_DESCRIPTOR));
if (*Int13Drives == NULL)
{
return STATUS_NO_MEMORY;
}
memcpy(*Int13Drives, FullResourceDescriptor + 1, ValueLength - sizeof (CM_FULL_RESOURCE_DESCRIPTOR));
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter" #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
STATIC VOID STATIC VOID
EnumerateBiosDiskEntries(PPARTLIST PartList) EnumerateBiosDiskEntries(PPARTLIST PartList)
{ {
RTL_QUERY_REGISTRY_TABLE QueryTable[2]; RTL_QUERY_REGISTRY_TABLE QueryTable[3];
WCHAR Name[100]; WCHAR Name[100];
ULONG AdapterCount; ULONG AdapterCount;
ULONG ControllerCount;
ULONG DiskCount; ULONG DiskCount;
NTSTATUS Status; NTSTATUS Status;
ULONG GlobalDiskCount=0; PCM_INT13_DRIVE_PARAMETER Int13Drives;
PBIOSDISKENTRY BiosDiskEntry;
memset(QueryTable, 0, sizeof(QueryTable)); memset(QueryTable, 0, sizeof(QueryTable));
QueryTable[0].Name = L"Identifier";
QueryTable[0].QueryRoutine = DiskQueryRoutine; QueryTable[1].Name = L"Configuration Data";
QueryTable[0].EntryContext = (PVOID)&GlobalDiskCount; QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
Int13Drives = NULL;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
&QueryTable[1],
(PVOID)&Int13Drives,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
return;
}
AdapterCount = 0; AdapterCount = 0;
while (1) while (1)
@ -484,7 +555,7 @@ EnumerateBiosDiskEntries(PPARTLIST PartList)
swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount); swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name, Name,
&QueryTable[1], &QueryTable[2],
NULL, NULL,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -495,54 +566,93 @@ EnumerateBiosDiskEntries(PPARTLIST PartList)
swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount); swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name, Name,
&QueryTable[1], &QueryTable[2],
NULL, NULL,
NULL); NULL);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
ControllerCount = 0;
while (1) while (1)
{ {
swprintf(Name, L"%s\\%lu\\DiskController\\%lu", ROOT_NAME, AdapterCount, ControllerCount); swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name, Name,
&QueryTable[1], &QueryTable[2],
NULL, NULL,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
break; RtlFreeHeap(ProcessHeap, 0, Int13Drives);
return;
} }
swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral", ROOT_NAME, AdapterCount, ControllerCount); swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name, Name,
&QueryTable[1], &QueryTable[2],
NULL, NULL,
NULL); NULL);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
QueryTable[0].Name = L"Identifier";
QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
QueryTable[1].Name = L"Configuration Data";
QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
DiskCount = 0; DiskCount = 0;
while (1) while (1)
{ {
swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, ControllerCount, DiskCount); BiosDiskEntry = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, if (BiosDiskEntry == NULL)
Name,
QueryTable,
(PVOID)&PartList->BiosDiskListHead,
NULL);
if (!NT_SUCCESS(Status))
{ {
break; break;
} }
swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
QueryTable,
(PVOID)BiosDiskEntry,
NULL);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
break;
}
BiosDiskEntry->DiskNumber = DiskCount;
BiosDiskEntry->Recognized = FALSE;
if (DiskCount < Int13Drives[0].NumberDrives)
{
BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
}
else
{
DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
}
InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
DPRINT("DiskNumber: %d\n", BiosDiskEntry->DiskNumber);
DPRINT("Signature: %08x\n", BiosDiskEntry->Signature);
DPRINT("Checksum: %08x\n", BiosDiskEntry->Checksum);
DPRINT("BytesPerSector: %d\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
DPRINT("NumberOfCylinders: %d\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
DPRINT("NumberOfHeads: %d\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
DPRINT("MaxCylinders: %d\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
DiskCount++; DiskCount++;
} }
} }
ControllerCount++; RtlFreeHeap(ProcessHeap, 0, Int13Drives);
return;
} }
} }
AdapterCount++; AdapterCount++;
} }
RtlFreeHeap(ProcessHeap, 0, Int13Drives);
} }
static VOID static VOID
@ -656,19 +766,32 @@ AddDiskToList (HANDLE FileHandle,
DiskEntry->Checksum = Checksum; DiskEntry->Checksum = Checksum;
DiskEntry->Signature = Signature; DiskEntry->Signature = Signature;
if (Signature == 0)
{
/* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */
DiskEntry->Modified = TRUE;
}
DiskEntry->BiosFound = FALSE; DiskEntry->BiosFound = FALSE;
ListEntry = List->BiosDiskListHead.Flink; ListEntry = List->BiosDiskListHead.Flink;
while(ListEntry != &List->BiosDiskListHead) while(ListEntry != &List->BiosDiskListHead)
{ {
BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
/* FIXME:
* Compare the size from bios and the reported size from driver.
* If we have more than one disk with a zero or with the same signatur
* we must create new signatures and reboot. After the reboot,
* it is possible to identify the disks.
*/
if (BiosDiskEntry->Signature == Signature && if (BiosDiskEntry->Signature == Signature &&
BiosDiskEntry->Checksum == Checksum) BiosDiskEntry->Checksum == Checksum &&
!BiosDiskEntry->Recognized)
{ {
if (!DiskEntry->BiosFound) if (!DiskEntry->BiosFound)
{ {
DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
DiskEntry->BiosFound = TRUE; DiskEntry->BiosFound = TRUE;
BiosDiskEntry->Recognized = TRUE;
} }
else else
{ {
@ -2162,7 +2285,8 @@ WritePartitionsToDisk (PPARTLIST List)
WCHAR DstPath[MAX_PATH]; WCHAR DstPath[MAX_PATH];
UNICODE_STRING Name; UNICODE_STRING Name;
HANDLE FileHandle; HANDLE FileHandle;
PDISKENTRY DiskEntry; PDISKENTRY DiskEntry1;
PDISKENTRY DiskEntry2;
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
PLIST_ENTRY Entry1; PLIST_ENTRY Entry1;
PLIST_ENTRY Entry2; PLIST_ENTRY Entry2;
@ -2179,16 +2303,16 @@ WritePartitionsToDisk (PPARTLIST List)
Entry1 = List->DiskListHead.Flink; Entry1 = List->DiskListHead.Flink;
while (Entry1 != &List->DiskListHead) while (Entry1 != &List->DiskListHead)
{ {
DiskEntry = CONTAINING_RECORD (Entry1, DiskEntry1 = CONTAINING_RECORD (Entry1,
DISKENTRY, DISKENTRY,
ListEntry); ListEntry);
if (DiskEntry->Modified == TRUE) if (DiskEntry1->Modified == TRUE)
{ {
/* Count partitioned entries */ /* Count partitioned entries */
PartitionCount = 0; PartitionCount = 0;
Entry2 = DiskEntry->PartListHead.Flink; Entry2 = DiskEntry1->PartListHead.Flink;
while (Entry2 != &DiskEntry->PartListHead) while (Entry2 != &DiskEntry1->PartListHead)
{ {
PartEntry = CONTAINING_RECORD (Entry2, PartEntry = CONTAINING_RECORD (Entry2,
PARTENTRY, PARTENTRY,
@ -2200,50 +2324,44 @@ WritePartitionsToDisk (PPARTLIST List)
Entry2 = Entry2->Flink; Entry2 = Entry2->Flink;
} }
if (PartitionCount == 0)
if (PartitionCount > 0) {
{ DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) +
((4 - 1) * sizeof (PARTITION_INFORMATION));
}
else
{
DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) +
((PartitionCount - 1) * sizeof (PARTITION_INFORMATION)); ((PartitionCount - 1) * sizeof (PARTITION_INFORMATION));
DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap, }
0, DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap,
DriveLayoutSize); 0,
if (DriveLayout == NULL) DriveLayoutSize);
{ if (DriveLayout == NULL)
DPRINT1 ("RtlAllocateHeap() failed\n"); {
return FALSE; DPRINT1 ("RtlAllocateHeap() failed\n");
} return FALSE;
}
RtlZeroMemory (DriveLayout, RtlZeroMemory (DriveLayout,
DriveLayoutSize); DriveLayoutSize);
DriveLayout->PartitionCount = PartitionCount; if (PartitionCount == 0)
if (DiskEntry->Signature == 0) {
/* delete all partitions in the mbr */
DriveLayout->PartitionCount = 4;
for (Index = 0; Index < 4; Index++)
{ {
LARGE_INTEGER SystemTime; DriveLayout->PartitionEntry[Index].RewritePartition = TRUE;
TIME_FIELDS TimeFields;
PUCHAR Buffer;
NtQuerySystemTime (&SystemTime);
RtlTimeToTimeFields (&SystemTime, &TimeFields);
Buffer = (PUCHAR)&DiskEntry->Signature;
Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
/* FIXME:
* check for an existing signature
*/
} }
}
DriveLayout->Signature = DiskEntry->Signature; else
{
DriveLayout->PartitionCount = PartitionCount;
Index = 0; Index = 0;
Entry2 = DiskEntry->PartListHead.Flink; Entry2 = DiskEntry1->PartListHead.Flink;
while (Entry2 != &DiskEntry->PartListHead) while (Entry2 != &DiskEntry1->PartListHead)
{ {
PartEntry = CONTAINING_RECORD (Entry2, PartEntry = CONTAINING_RECORD (Entry2,
PARTENTRY, PARTENTRY,
@ -2258,74 +2376,127 @@ WritePartitionsToDisk (PPARTLIST List)
Entry2 = Entry2->Flink; Entry2 = Entry2->Flink;
} }
}
if (DiskEntry1->Signature == 0)
{
LARGE_INTEGER SystemTime;
TIME_FIELDS TimeFields;
PUCHAR Buffer;
Buffer = (PUCHAR)&DiskEntry1->Signature;
swprintf (DstPath, while (1)
L"\\Device\\Harddisk%d\\Partition0", {
DiskEntry->DiskNumber); NtQuerySystemTime (&SystemTime);
RtlInitUnicodeString (&Name, RtlTimeToTimeFields (&SystemTime, &TimeFields);
DstPath);
InitializeObjectAttributes (&ObjectAttributes, Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
&Name, Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
0, Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
if (DiskEntry1->Signature == 0)
{
continue;
}
/* check if the signature already exist */
/* FIXME:
* Check also signatures from disks, which are
* not visible (bootable) by the bios.
*/
Entry2 = List->DiskListHead.Flink;
while (Entry2 != &List->DiskListHead)
{
DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
if (DiskEntry1 != DiskEntry2 &&
DiskEntry1->Signature == DiskEntry2->Signature)
{
break;
}
Entry2 = Entry2->Flink;
}
if (Entry2 == &List->DiskListHead)
{
break;
}
}
/* set one partition entry to dirty, this will update the signature */
DriveLayout->PartitionEntry[0].RewritePartition = TRUE;
}
DriveLayout->Signature = DiskEntry1->Signature;
swprintf (DstPath,
L"\\Device\\Harddisk%d\\Partition0",
DiskEntry1->DiskNumber);
RtlInitUnicodeString (&Name,
DstPath);
InitializeObjectAttributes (&ObjectAttributes,
&Name,
0,
NULL,
NULL);
Status = NtOpenFile (&FileHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
0,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (Status))
{
DPRINT1 ("NtOpenFile() failed (Status %lx)\n", Status);
return FALSE;
}
Status = NtDeviceIoControlFile (FileHandle,
NULL, NULL,
NULL); NULL,
NULL,
Status = NtOpenFile (&FileHandle, &Iosb,
FILE_ALL_ACCESS, IOCTL_DISK_SET_DRIVE_LAYOUT,
&ObjectAttributes, DriveLayout,
&Iosb, DriveLayoutSize,
0, NULL,
FILE_SYNCHRONOUS_IO_NONALERT); 0);
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT1 ("NtOpenFile() failed (Status %lx)\n", Status); DPRINT1 ("NtDeviceIoControlFile() failed (Status %lx)\n", Status);
return FALSE;
}
Status = NtDeviceIoControlFile (FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_SET_DRIVE_LAYOUT,
DriveLayout,
DriveLayoutSize,
NULL,
0);
if (!NT_SUCCESS (Status))
{
DPRINT1 ("NtDeviceIoControlFile() failed (Status %lx)\n", Status);
NtClose (FileHandle);
return FALSE;
}
RtlFreeHeap (ProcessHeap,
0,
DriveLayout);
NtClose (FileHandle); NtClose (FileHandle);
return FALSE;
}
/* Install MBR code if the disk is new */ RtlFreeHeap (ProcessHeap,
if (DiskEntry->NewDisk == TRUE) 0,
{ DriveLayout);
wcscpy (SrcPath, SourceRootPath.Buffer);
wcscat (SrcPath, L"\\loader\\dosmbr.bin");
DPRINT1 ("Install MBR bootcode: %S ==> %S\n", NtClose (FileHandle);
SrcPath, DstPath);
/* Install MBR bootcode */ /* Install MBR code if the disk is new */
Status = InstallMbrBootCodeToDisk (SrcPath, if (DiskEntry1->NewDisk == TRUE &&
DstPath); DiskEntry1->BiosDiskNumber == 0)
if (!NT_SUCCESS (Status)) {
{ wcscpy (SrcPath, SourceRootPath.Buffer);
DPRINT1 ("InstallMbrBootCodeToDisk() failed (Status %lx)\n", wcscat (SrcPath, L"\\loader\\dosmbr.bin");
Status);
return FALSE;
}
DiskEntry->NewDisk = FALSE; DPRINT ("Install MBR bootcode: %S ==> %S\n",
} SrcPath, DstPath);
/* Install MBR bootcode */
Status = InstallMbrBootCodeToDisk (SrcPath,
DstPath);
if (!NT_SUCCESS (Status))
{
DPRINT1 ("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
Status);
return FALSE;
}
DiskEntry1->NewDisk = FALSE;
} }
} }

View file

@ -74,6 +74,9 @@ typedef struct _BIOSDISKENTRY
ULONG DiskNumber; ULONG DiskNumber;
ULONG Signature; ULONG Signature;
ULONG Checksum; ULONG Checksum;
BOOLEAN Recognized;
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
CM_INT13_DRIVE_PARAMETER Int13DiskData;
} BIOSDISKENTRY, *PBIOSDISKENTRY; } BIOSDISKENTRY, *PBIOSDISKENTRY;