03495 :
03496
03497 This routine walks
the disk writing
the partition tables from
03498
the entries in
the partition list buffer
for each partition.
03499
03500 Applications that create and
delete partitions should issue a
03501
IoReadPartitionTable call with
the '
return recognized partitions'
03502
boolean set to
false to get a full description of
the system.
03503
03504 Then
the drive layout structure can be modified by
the application to
03505 reflect
the new configuration of
the disk and then
is written back
03506 to
the disk
using this routine.
03507
03508 Arguments:
03509
03510 DeviceObject - Pointer to device object
for this disk.
03511
03512
SectorSize - Sector size on
the device.
03513
03514 SectorsPerTrack - Track size on
the device.
03515
03516 NumberOfHeads - Same as tracks per cylinder.
03517
03518 Return Value:
03519
03520 The functional value
is STATUS_SUCCESS
if all writes are completed
03521 without error.
03522
03523 --*/
03524
03525 {
03526
typedef struct _PARTITION_TABLE {
03527 PARTITION_INFORMATION PartitionEntry[4];
03528 } PARTITION_TABLE, *PPARTITION_TABLE;
03529
03530
typedef struct _DISK_LAYOUT {
03531 ULONG TableCount;
03532 ULONG Signature;
03533 PARTITION_TABLE PartitionTable[1];
03534 } DISK_LAYOUT, *PDISK_LAYOUT;
03535
03536
typedef struct _PTE {
03537 UCHAR ActiveFlag;
03538 UCHAR StartingTrack;
03539
USHORT StartingCylinder;
03540 UCHAR PartitionType;
03541 UCHAR EndingTrack;
03542
USHORT EndingCylinder;
03543 ULONG StartingSector;
03544 ULONG PartitionLength;
03545 } PTE;
03546
typedef PTE UNALIGNED *PPTE;
03547
03548
03549
03550
03551
03552
#define WHICH_BIT(Data, Bit) { \
03553
for (Bit = 0; Bit < 32; Bit++) { \
03554
if ((Data >> Bit) == 1) { \
03555
break; \
03556
} \
03557
} \
03558
}
03559
03560 ULONG writeSize;
03561
PUSHORT writeBuffer =
NULL;
03562 PPARTITION_TABLE partitionTable;
03563 CCHAR shiftCount;
03564 LARGE_INTEGER partitionTableOffset;
03565 LARGE_INTEGER nextRecordOffset;
03566 ULONG partitionTableCount;
03567
KEVENT event;
03568 IO_STATUS_BLOCK ioStatus;
03569
PIRP irp;
03570 BOOLEAN rewritePartition =
FALSE;
03571
NTSTATUS status = STATUS_SUCCESS;
03572 LARGE_INTEGER tempInt;
03573 BOOLEAN foundEZHooker =
FALSE;
03574 ULONG conventionalCylinders;
03575 LONGLONG diskSize;
03576
03577 BOOLEAN isSuperFloppy =
FALSE;
03578
03579
03580
03581
03582
03583
PAGED_CODE();
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
if (
SectorSize >= 512) {
03594 writeSize =
SectorSize;
03595 }
else {
03596 writeSize = 512;
03597 }
03598
03599
xHalGetPartialGeometry( DeviceObject,
03600 &conventionalCylinders,
03601 &diskSize );
03602
03603
03604
03605
03606
03607
03608 {
03609
03610 PVOID buff;
03611
03612
HalExamineMBR(
03613 DeviceObject,
03614 writeSize,
03615 (ULONG)0x55,
03616 &buff
03617 );
03618
03619
if (buff) {
03620
03621 foundEZHooker =
TRUE;
03622
ExFreePool(buff);
03623 partitionTableOffset.QuadPart = 512;
03624
03625 }
else {
03626
03627 partitionTableOffset.QuadPart = 0;
03628
03629 }
03630
03631 }
03632
03633
03634
03635
03636
03637
WHICH_BIT( SectorSize, shiftCount );
03638
03639
03640
03641
03642
03643 writeBuffer =
ExAllocatePoolWithTag( NonPagedPoolCacheAligned, PAGE_SIZE, 'btsF');
03644
03645
if (writeBuffer ==
NULL) {
03646
return STATUS_INSUFFICIENT_RESOURCES;
03647 }
03648
03649
03650
03651
03652
03653
03654
03655
KeInitializeEvent( &event, SynchronizationEvent, FALSE );
03656
03657 irp =
IoBuildSynchronousFsdRequest( IRP_MJ_READ,
03658 DeviceObject,
03659 writeBuffer,
03660 writeSize,
03661 &partitionTableOffset,
03662 &event,
03663 &ioStatus );
03664
03665
if (!irp) {
03666
ExFreePool(writeBuffer);
03667
return STATUS_INSUFFICIENT_RESOURCES;
03668 }
03669
03670 status =
IoCallDriver( DeviceObject, irp );
03671
03672
if (status == STATUS_PENDING) {
03673 (
VOID)
KeWaitForSingleObject( &event,
03674 Executive,
03675 KernelMode,
03676 FALSE,
03677 (PLARGE_INTEGER) NULL);
03678 status = ioStatus.Status;
03679 }
03680
03681
if (!
NT_SUCCESS( status )) {
03682
ExFreePool(writeBuffer);
03683
return status;
03684 }
03685
03686
03687
03688
03689
03690
if(writeBuffer[
BOOT_SIGNATURE_OFFSET] ==
BOOT_RECORD_SIGNATURE) {
03691 writeBuffer[
BOOT_SIGNATURE_OFFSET] += 0x1111;
03692 }
03693
03694 irp =
IoBuildSynchronousFsdRequest( IRP_MJ_WRITE,
03695 DeviceObject,
03696 writeBuffer,
03697 writeSize,
03698 &partitionTableOffset,
03699 &event,
03700 &ioStatus );
03701
03702
if (!irp) {
03703
ExFreePool(writeBuffer);
03704
return STATUS_INSUFFICIENT_RESOURCES;
03705 }
else {
03706
PIO_STACK_LOCATION irpStack;
03707 irpStack =
IoGetNextIrpStackLocation(irp);
03708 irpStack->
Flags |=
SL_OVERRIDE_VERIFY_VOLUME;
03709 }
03710
03711 status =
IoCallDriver( DeviceObject, irp );
03712
03713
if (status == STATUS_PENDING) {
03714 (
VOID)
KeWaitForSingleObject( &event,
03715 Executive,
03716 KernelMode,
03717 FALSE,
03718 (PLARGE_INTEGER) NULL);
03719 status = ioStatus.Status;
03720 }
03721
03722
03723
03724
03725
03726
ExFreePool( writeBuffer );
03727
03728
return status;
03729 }