- 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];
} 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
typedef struct _PLUGPLAY_EVENT_BLOCK
@ -275,5 +385,151 @@ typedef struct _PLUGPLAY_BUS_INSTANCE
WCHAR BusName[MAX_BUS_NAME];
} 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

View file

@ -424,28 +424,19 @@ ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry)
NTSTATUS
STDCALL
DiskQueryRoutine(PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
ULONG ValueLength,
PVOID Context,
PVOID EntryContext)
DiskIdentifierQueryRoutine(PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
ULONG ValueLength,
PVOID Context,
PVOID EntryContext)
{
PLIST_ENTRY ListHead = (PLIST_ENTRY)Context;
PULONG GlobalDiskCount = (PULONG)EntryContext;
PBIOSDISKENTRY BiosDiskEntry;
PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
UNICODE_STRING NameU;
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.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
@ -453,30 +444,110 @@ DiskQueryRoutine(PWSTR ValueName,
NameU.Buffer = (PWCHAR)ValueData + 9;
RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
InsertTailList(ListHead, &BiosDiskEntry->ListEntry);
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
return STATUS_UNSUCCESSFUL;
}
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"
STATIC VOID
EnumerateBiosDiskEntries(PPARTLIST PartList)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
WCHAR Name[100];
ULONG AdapterCount;
ULONG ControllerCount;
ULONG DiskCount;
NTSTATUS Status;
ULONG GlobalDiskCount=0;
PCM_INT13_DRIVE_PARAMETER Int13Drives;
PBIOSDISKENTRY BiosDiskEntry;
memset(QueryTable, 0, sizeof(QueryTable));
QueryTable[0].Name = L"Identifier";
QueryTable[0].QueryRoutine = DiskQueryRoutine;
QueryTable[0].EntryContext = (PVOID)&GlobalDiskCount;
QueryTable[1].Name = L"Configuration Data";
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;
while (1)
@ -484,7 +555,7 @@ EnumerateBiosDiskEntries(PPARTLIST PartList)
swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
&QueryTable[1],
&QueryTable[2],
NULL,
NULL);
if (!NT_SUCCESS(Status))
@ -495,54 +566,93 @@ EnumerateBiosDiskEntries(PPARTLIST PartList)
swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
&QueryTable[1],
&QueryTable[2],
NULL,
NULL);
if (NT_SUCCESS(Status))
{
ControllerCount = 0;
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,
Name,
&QueryTable[1],
&QueryTable[2],
NULL,
NULL);
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,
Name,
&QueryTable[1],
&QueryTable[2],
NULL,
NULL);
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;
while (1)
{
swprintf(Name, L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
Name,
QueryTable,
(PVOID)&PartList->BiosDiskListHead,
NULL);
if (!NT_SUCCESS(Status))
BiosDiskEntry = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
if (BiosDiskEntry == NULL)
{
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++;
}
}
ControllerCount++;
RtlFreeHeap(ProcessHeap, 0, Int13Drives);
return;
}
}
AdapterCount++;
}
RtlFreeHeap(ProcessHeap, 0, Int13Drives);
}
static VOID
@ -656,19 +766,32 @@ AddDiskToList (HANDLE FileHandle,
DiskEntry->Checksum = Checksum;
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;
ListEntry = List->BiosDiskListHead.Flink;
while(ListEntry != &List->BiosDiskListHead)
{
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 &&
BiosDiskEntry->Checksum == Checksum)
BiosDiskEntry->Checksum == Checksum &&
!BiosDiskEntry->Recognized)
{
if (!DiskEntry->BiosFound)
{
DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
DiskEntry->BiosFound = TRUE;
BiosDiskEntry->Recognized = TRUE;
}
else
{
@ -2162,7 +2285,8 @@ WritePartitionsToDisk (PPARTLIST List)
WCHAR DstPath[MAX_PATH];
UNICODE_STRING Name;
HANDLE FileHandle;
PDISKENTRY DiskEntry;
PDISKENTRY DiskEntry1;
PDISKENTRY DiskEntry2;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry1;
PLIST_ENTRY Entry2;
@ -2179,16 +2303,16 @@ WritePartitionsToDisk (PPARTLIST List)
Entry1 = List->DiskListHead.Flink;
while (Entry1 != &List->DiskListHead)
{
DiskEntry = CONTAINING_RECORD (Entry1,
DISKENTRY,
ListEntry);
DiskEntry1 = CONTAINING_RECORD (Entry1,
DISKENTRY,
ListEntry);
if (DiskEntry->Modified == TRUE)
if (DiskEntry1->Modified == TRUE)
{
/* Count partitioned entries */
PartitionCount = 0;
Entry2 = DiskEntry->PartListHead.Flink;
while (Entry2 != &DiskEntry->PartListHead)
Entry2 = DiskEntry1->PartListHead.Flink;
while (Entry2 != &DiskEntry1->PartListHead)
{
PartEntry = CONTAINING_RECORD (Entry2,
PARTENTRY,
@ -2200,50 +2324,44 @@ WritePartitionsToDisk (PPARTLIST List)
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) +
((PartitionCount - 1) * sizeof (PARTITION_INFORMATION));
DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap,
0,
DriveLayoutSize);
if (DriveLayout == NULL)
{
DPRINT1 ("RtlAllocateHeap() failed\n");
return FALSE;
}
}
DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap,
0,
DriveLayoutSize);
if (DriveLayout == NULL)
{
DPRINT1 ("RtlAllocateHeap() failed\n");
return FALSE;
}
RtlZeroMemory (DriveLayout,
DriveLayoutSize);
RtlZeroMemory (DriveLayout,
DriveLayoutSize);
DriveLayout->PartitionCount = PartitionCount;
if (DiskEntry->Signature == 0)
if (PartitionCount == 0)
{
/* delete all partitions in the mbr */
DriveLayout->PartitionCount = 4;
for (Index = 0; Index < 4; Index++)
{
LARGE_INTEGER SystemTime;
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->PartitionEntry[Index].RewritePartition = TRUE;
}
DriveLayout->Signature = DiskEntry->Signature;
}
else
{
DriveLayout->PartitionCount = PartitionCount;
Index = 0;
Entry2 = DiskEntry->PartListHead.Flink;
while (Entry2 != &DiskEntry->PartListHead)
Entry2 = DiskEntry1->PartListHead.Flink;
while (Entry2 != &DiskEntry1->PartListHead)
{
PartEntry = CONTAINING_RECORD (Entry2,
PARTENTRY,
@ -2258,74 +2376,127 @@ WritePartitionsToDisk (PPARTLIST List)
Entry2 = Entry2->Flink;
}
}
if (DiskEntry1->Signature == 0)
{
LARGE_INTEGER SystemTime;
TIME_FIELDS TimeFields;
PUCHAR Buffer;
Buffer = (PUCHAR)&DiskEntry1->Signature;
swprintf (DstPath,
L"\\Device\\Harddisk%d\\Partition0",
DiskEntry->DiskNumber);
RtlInitUnicodeString (&Name,
DstPath);
InitializeObjectAttributes (&ObjectAttributes,
&Name,
0,
while (1)
{
NtQuerySystemTime (&SystemTime);
RtlTimeToTimeFields (&SystemTime, &TimeFields);
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);
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);
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,
&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);
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;
}
/* Install MBR code if the disk is new */
if (DiskEntry->NewDisk == TRUE)
{
wcscpy (SrcPath, SourceRootPath.Buffer);
wcscat (SrcPath, L"\\loader\\dosmbr.bin");
RtlFreeHeap (ProcessHeap,
0,
DriveLayout);
DPRINT1 ("Install MBR bootcode: %S ==> %S\n",
SrcPath, DstPath);
NtClose (FileHandle);
/* Install MBR bootcode */
Status = InstallMbrBootCodeToDisk (SrcPath,
DstPath);
if (!NT_SUCCESS (Status))
{
DPRINT1 ("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
Status);
return FALSE;
}
/* Install MBR code if the disk is new */
if (DiskEntry1->NewDisk == TRUE &&
DiskEntry1->BiosDiskNumber == 0)
{
wcscpy (SrcPath, SourceRootPath.Buffer);
wcscat (SrcPath, L"\\loader\\dosmbr.bin");
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 Signature;
ULONG Checksum;
BOOLEAN Recognized;
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
CM_INT13_DRIVE_PARAMETER Int13DiskData;
} BIOSDISKENTRY, *PBIOSDISKENTRY;