00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "ntos.h"
00027
#include "zwapi.h"
00028
#include "hal.h"
00029
#include "ntdddisk.h"
00030
#include "haldisp.h"
00031
#include "ntddft.h"
00032
#include "mountmgr.h"
00033
#include "stdio.h"
00034
#include <setupblk.h>
00035
00036
#include "drivesup.h"
00037
00038
00039
00040
00041
00042 ULONG
DrivesupDebug = 0;
00043 ULONG
DrivesupBreakIn =
FALSE;
00044
00045
VOID
00046
DrivesupDebugPrint(
00047 ULONG DebugPrintLevel,
00048 PCCHAR DebugMessage,
00049 ...
00050 );
00051
00052 #define DebugPrint(x) DrivesupDebugPrint x
00053
00054
00055
00056
00057
00058 #define GET_STARTING_SECTOR( p ) ( \
00059
(ULONG) (p->StartingSectorLsb0) + \
00060
(ULONG) (p->StartingSectorLsb1 << 8) + \
00061
(ULONG) (p->StartingSectorMsb0 << 16) + \
00062
(ULONG) (p->StartingSectorMsb1 << 24) )
00063
00064 #define GET_PARTITION_LENGTH( p ) ( \
00065
(ULONG) (p->PartitionLengthLsb0) + \
00066
(ULONG) (p->PartitionLengthLsb1 << 8) + \
00067
(ULONG) (p->PartitionLengthMsb0 << 16) + \
00068
(ULONG) (p->PartitionLengthMsb1 << 24) )
00069
00070
00071
00072
00073
00074 typedef struct _BOOT_SECTOR_INFO {
00075 UCHAR
JumpByte[1];
00076 UCHAR
Ignore1[2];
00077 UCHAR
OemData[8];
00078 UCHAR
BytesPerSector[2];
00079 UCHAR
Ignore2[6];
00080 UCHAR
NumberOfSectors[2];
00081 UCHAR
MediaByte[1];
00082 UCHAR
Ignore3[2];
00083 UCHAR
SectorsPerTrack[2];
00084 UCHAR
NumberOfHeads[2];
00085 }
BOOT_SECTOR_INFO, *
PBOOT_SECTOR_INFO;
00086
00087
00088
00089
00090
00091 static PUCHAR
DiskPartitionName =
"\\Device\\Harddisk%d\\Partition%d";
00092 static PUCHAR
RegistryKeyName = DISK_REGISTRY_KEY;
00093
00094
VOID
00095
HalpCalculateChsValues(
00096 IN PLARGE_INTEGER PartitionOffset,
00097 IN PLARGE_INTEGER PartitionLength,
00098 IN CCHAR ShiftCount,
00099 IN ULONG SectorsPerTrack,
00100 IN ULONG NumberOfTracks,
00101 IN ULONG ConventionalCylinders,
00102 OUT
PPARTITION_DESCRIPTOR PartitionDescriptor
00103 );
00104
00105
NTSTATUS
00106
HalpQueryPartitionType(
00107 IN PUNICODE_STRING DeviceName,
00108 IN PDRIVE_LAYOUT_INFORMATION DriveLayout,
00109 OUT PULONG PartitionType
00110 );
00111
00112
NTSTATUS
00113
HalpQueryDriveLayout(
00114 IN PUNICODE_STRING DeviceName,
00115 OUT PDRIVE_LAYOUT_INFORMATION* DriveLayout
00116 );
00117
00118
VOID
00119
FASTCALL
00120
xHalGetPartialGeometry(
00121 IN
PDEVICE_OBJECT DeviceObject,
00122 IN PULONG ConventionalCylinders,
00123 IN PLONGLONG DiskSize
00124 );
00125
00126
NTSTATUS
00127
HalpGetFullGeometry(
00128 IN
PDEVICE_OBJECT DeviceObject,
00129 IN PDISK_GEOMETRY Geometry,
00130 OUT PULONGLONG RealSectorCount
00131 );
00132
00133 BOOLEAN
00134
HalpIsValidPartitionEntry(
00135
PPARTITION_DESCRIPTOR Entry,
00136 ULONGLONG MaxOffset,
00137 ULONGLONG MaxSector
00138 );
00139
00140
NTSTATUS
00141
HalpNextMountLetter(
00142 IN PUNICODE_STRING DeviceName,
00143 OUT PUCHAR DriveLetter
00144 );
00145
00146 UCHAR
00147
HalpNextDriveLetter(
00148 IN PUNICODE_STRING DeviceName,
00149 IN PSTRING NtDeviceName,
00150 OUT PUCHAR NtSystemPath,
00151 IN BOOLEAN UseHardLinksIfNecessary
00152 );
00153
00154
VOID
00155
HalpEnableAutomaticDriveLetterAssignment(
00156 );
00157
00158
NTSTATUS
00159
HalpSetMountLetter(
00160 IN PUNICODE_STRING DeviceName,
00161 IN UCHAR DriveLetter
00162 );
00163
00164 BOOLEAN
00165
HalpIsOldStyleFloppy(
00166 IN PUNICODE_STRING DeviceName
00167 );
00168
00169
#ifdef ALLOC_PRAGMA
00170
#pragma alloc_text(PAGE, HalpCalculateChsValues)
00171
#pragma alloc_text(PAGE, HalpQueryPartitionType)
00172
#pragma alloc_text(PAGE, HalpQueryDriveLayout)
00173
#pragma alloc_text(PAGE, HalpNextMountLetter)
00174
#pragma alloc_text(PAGE, HalpNextDriveLetter)
00175
#pragma alloc_text(PAGE, HalpEnableAutomaticDriveLetterAssignment)
00176
#pragma alloc_text(PAGE, HalpSetMountLetter)
00177
#pragma alloc_text(PAGE, xHalIoAssignDriveLetters)
00178
#pragma alloc_text(PAGE, xHalIoReadPartitionTable)
00179
#pragma alloc_text(PAGE, xHalIoSetPartitionInformation)
00180
#pragma alloc_text(PAGE, xHalIoWritePartitionTable)
00181
#pragma alloc_text(PAGE, HalpIsValidPartitionEntry)
00182
#pragma alloc_text(PAGE, HalpGetFullGeometry)
00183
#pragma alloc_text(PAGE, HalpIsOldStyleFloppy)
00184
#endif
00185
00186
00187
00188
VOID
00189
FASTCALL
00190 xHalExamineMBR(
00191 IN
PDEVICE_OBJECT DeviceObject,
00192 IN ULONG SectorSize,
00193 IN ULONG MBRTypeIdentifier,
00194 OUT PVOID *Buffer
00195 )
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 {
00238
00239
00240 LARGE_INTEGER partitionTableOffset;
00241 PUCHAR readBuffer = (PUCHAR)
NULL;
00242
KEVENT event;
00243 IO_STATUS_BLOCK ioStatus;
00244
PIRP irp;
00245
PPARTITION_DESCRIPTOR partitionTableEntry;
00246
NTSTATUS status = STATUS_SUCCESS;
00247 ULONG readSize;
00248
00249 *
Buffer =
NULL;
00250
00251
00252
00253
00254
00255
00256
00257
00258
if (
SectorSize >= 512) {
00259 readSize =
SectorSize;
00260 }
else {
00261 readSize = 512;
00262 }
00263
00264
00265
00266
00267
00268 partitionTableOffset = RtlConvertUlongToLargeInteger( 0 );
00269
00270
00271
00272
00273
00274 readBuffer =
ExAllocatePoolWithTag(
00275
NonPagedPoolCacheAligned,
00276
PAGE_SIZE>readSize?PAGE_SIZE:readSize,
00277 'btsF'
00278 );
00279
00280
if (readBuffer ==
NULL) {
00281
return;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
KeInitializeEvent( &event, NotificationEvent,
FALSE );
00292
00293 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_READ,
00294 DeviceObject,
00295 readBuffer,
00296 readSize,
00297 &partitionTableOffset,
00298 &event,
00299 &ioStatus );
00300
00301
if (!irp) {
00302
ExFreePool(readBuffer);
00303
return;
00304 }
else {
00305
PIO_STACK_LOCATION irpStack;
00306 irpStack =
IoGetNextIrpStackLocation(irp);
00307 irpStack->
Flags |=
SL_OVERRIDE_VERIFY_VOLUME;
00308 }
00309
00310 status =
IoCallDriver( DeviceObject, irp );
00311
00312
if (status == STATUS_PENDING) {
00313 (
VOID)
KeWaitForSingleObject( &event,
00314
Executive,
00315
KernelMode,
00316
FALSE,
00317 (PLARGE_INTEGER)
NULL);
00318 status = ioStatus.Status;
00319 }
00320
00321
if (!
NT_SUCCESS( status )) {
00322
ExFreePool(readBuffer);
00323
return;
00324 }
00325
00326
00327
00328
00329
00330
if (((
PUSHORT) readBuffer)[
BOOT_SIGNATURE_OFFSET] !=
BOOT_RECORD_SIGNATURE) {
00331
ExFreePool(readBuffer);
00332
return;
00333 }
00334
00335
00336
00337
00338
00339 partitionTableEntry = (
PPARTITION_DESCRIPTOR) &(((
PUSHORT) readBuffer)[
PARTITION_TABLE_OFFSET]);
00340
00341
if (partitionTableEntry->
PartitionType != MBRTypeIdentifier) {
00342
00343
00344
00345
00346
ExFreePool(readBuffer);
00347
00348 }
else {
00349
00350
if (partitionTableEntry->
PartitionType == 0x54) {
00351
00352
00353
00354
00355
00356
00357
00358 ((PULONG)readBuffer)[0] = 63;
00359 *
Buffer = readBuffer;
00360
00361 }
else if (partitionTableEntry->
PartitionType == 0x55) {
00362
00363
00364
00365
00366
00367
00368 *
Buffer = readBuffer;
00369
00370 }
else {
00371
00372
ASSERT(partitionTableEntry->
PartitionType == 0x55);
00373
00374 }
00375
00376 }
00377
00378 }
00379
00380
VOID
00381
FASTCALL
00382 xHalGetPartialGeometry(
00383 IN
PDEVICE_OBJECT DeviceObject,
00384 IN PULONG ConventionalCylinders,
00385 IN PLONGLONG DiskSize
00386 )
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 {
00409
PIRP localIrp;
00410 PDISK_GEOMETRY diskGeometry;
00411 PIO_STATUS_BLOCK iosb;
00412
PKEVENT eventPtr;
00413
NTSTATUS status;
00414
00415 *ConventionalCylinders = 0UL;
00416 *DiskSize = 0UL;
00417
00418 diskGeometry =
ExAllocatePoolWithTag(
00419
NonPagedPool,
00420
sizeof(DISK_GEOMETRY),
00421 'btsF'
00422 );
00423
00424
if (!diskGeometry) {
00425
00426
return;
00427
00428 }
00429
00430 iosb =
ExAllocatePoolWithTag(
00431
NonPagedPool,
00432
sizeof(IO_STATUS_BLOCK),
00433 'btsF'
00434 );
00435
00436
if (!iosb) {
00437
00438
ExFreePool(diskGeometry);
00439
return;
00440
00441 }
00442
00443 eventPtr =
ExAllocatePoolWithTag(
00444
NonPagedPool,
00445
sizeof(
KEVENT),
00446 'btsF'
00447 );
00448
00449
if (!eventPtr) {
00450
00451
ExFreePool(iosb);
00452
ExFreePool(diskGeometry);
00453
return;
00454
00455 }
00456
00457
KeInitializeEvent(
00458 eventPtr,
00459 NotificationEvent,
00460
FALSE
00461 );
00462
00463 localIrp =
IoBuildDeviceIoControlRequest(
00464 IOCTL_DISK_GET_DRIVE_GEOMETRY,
00465 DeviceObject,
00466
NULL,
00467 0UL,
00468 diskGeometry,
00469
sizeof(DISK_GEOMETRY),
00470
FALSE,
00471 eventPtr,
00472 iosb
00473 );
00474
00475
if (!localIrp) {
00476
00477
ExFreePool(eventPtr);
00478
ExFreePool(iosb);
00479
ExFreePool(diskGeometry);
00480
return;
00481
00482 }
00483
00484
00485
00486
00487
00488
00489
00490 status =
IoCallDriver(
00491 DeviceObject,
00492 localIrp
00493 );
00494
00495
if (status == STATUS_PENDING) {
00496 (
VOID)
KeWaitForSingleObject(
00497 eventPtr,
00498
Executive,
00499
KernelMode,
00500
FALSE,
00501 (PLARGE_INTEGER)
NULL
00502 );
00503 status = iosb->Status;
00504 }
00505
00506
if (
NT_SUCCESS(status)) {
00507
00508
00509
00510
00511
00512
00513 *ConventionalCylinders = diskGeometry->Cylinders.LowPart;
00514
00515
00516
00517
00518
00519
00520
if (diskGeometry->Cylinders.QuadPart >= (LONGLONG)1024) {
00521
00522 *ConventionalCylinders = 1024;
00523
00524 }
00525
00526
00527
00528
00529
00530 *DiskSize = diskGeometry->Cylinders.QuadPart *
00531 diskGeometry->TracksPerCylinder *
00532 diskGeometry->SectorsPerTrack *
00533 diskGeometry->BytesPerSector;
00534
00535 }
00536
00537
ExFreePool(eventPtr);
00538
ExFreePool(iosb);
00539
ExFreePool(diskGeometry);
00540
return;
00541
00542 }
00543
00544
00545
VOID
00546 HalpCalculateChsValues(
00547 IN PLARGE_INTEGER PartitionOffset,
00548 IN PLARGE_INTEGER PartitionLength,
00549 IN CCHAR ShiftCount,
00550 IN ULONG SectorsPerTrack,
00551 IN ULONG NumberOfTracks,
00552 IN ULONG ConventionalCylinders,
00553 OUT
PPARTITION_DESCRIPTOR PartitionDescriptor
00554 )
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 {
00607 ULONG startSector, sectorCount, endSector;
00608 ULONG sectorsPerCylinder;
00609 ULONG remainder;
00610 ULONG startC, startH, startS, endC, endH, endS;
00611 LARGE_INTEGER tempInt;
00612
00613
PAGED_CODE();
00614
00615
00616
00617
00618
00619
00620 sectorsPerCylinder = SectorsPerTrack * NumberOfTracks;
00621
00622
00623
00624
00625
00626 tempInt.QuadPart = PartitionOffset->QuadPart >> ShiftCount;
00627 startSector = tempInt.LowPart;
00628
00629 tempInt.QuadPart = PartitionLength->QuadPart >> ShiftCount;
00630 sectorCount = tempInt.LowPart;
00631
00632 endSector = startSector + sectorCount - 1;
00633
00634 startC = startSector / sectorsPerCylinder;
00635 endC = endSector / sectorsPerCylinder;
00636
00637
if (!ConventionalCylinders) {
00638
00639 ConventionalCylinders = 1024;
00640
00641 }
00642
00643
00644
00645
00646
00647
if (startC >= ConventionalCylinders) {
00648
00649 startC = ConventionalCylinders - 1;
00650
00651 }
00652
00653
if (endC >= ConventionalCylinders) {
00654
00655 endC = ConventionalCylinders - 1;
00656
00657 }
00658
00659
00660
00661
00662
00663 remainder = startSector % sectorsPerCylinder;
00664 startH = remainder / SectorsPerTrack;
00665 startS = remainder % SectorsPerTrack;
00666
00667
00668
00669
00670
00671 remainder = endSector % sectorsPerCylinder;
00672 endH = remainder / SectorsPerTrack;
00673 endS = remainder % SectorsPerTrack;
00674
00675
00676
00677
00678
00679
00680
00681 PartitionDescriptor->StartingCylinderMsb = (UCHAR) startC;
00682 PartitionDescriptor->EndingCylinderMsb = (UCHAR) endC;
00683
00684
00685
00686 PartitionDescriptor->StartingTrack = (UCHAR) startH;
00687 PartitionDescriptor->EndingTrack = (UCHAR) endH;
00688
00689
00690
00691 PartitionDescriptor->StartingCylinderLsb = (UCHAR) (((startS + 1) & 0x3f)
00692 | ((startC >> 2) & 0xc0));
00693
00694 PartitionDescriptor->EndingCylinderLsb = (UCHAR) (((endS + 1) & 0x3f)
00695 | ((endC >> 2) & 0xc0));
00696 }
00697
00698
00699 #define BOOTABLE_PARTITION 0
00700 #define PRIMARY_PARTITION 1
00701 #define LOGICAL_PARTITION 2
00702 #define FT_PARTITION 3
00703 #define OTHER_PARTITION 4
00704
00705
NTSTATUS
00706 HalpQueryPartitionType(
00707 IN PUNICODE_STRING DeviceName,
00708 IN PDRIVE_LAYOUT_INFORMATION DriveLayout,
00709 OUT PULONG PartitionType
00710 )
00711
00712 {
00713
NTSTATUS status;
00714
PFILE_OBJECT fileObject;
00715
PDEVICE_OBJECT deviceObject;
00716
KEVENT event;
00717
PIRP irp;
00718 PARTITION_INFORMATION partInfo;
00719 IO_STATUS_BLOCK ioStatus;
00720 ULONG i;
00721
00722 status =
IoGetDeviceObjectPointer(DeviceName,
00723 FILE_READ_ATTRIBUTES,
00724 &fileObject, &deviceObject);
00725
if (!
NT_SUCCESS(status)) {
00726
return status;
00727 }
00728 deviceObject =
IoGetAttachedDeviceReference(fileObject->
DeviceObject);
00729
ObDereferenceObject(fileObject);
00730
00731
if ((deviceObject->
Characteristics&FILE_REMOVABLE_MEDIA) ||
00732 !DriveLayout) {
00733
00734
ObDereferenceObject(deviceObject);
00735 *PartitionType =
LOGICAL_PARTITION;
00736
return STATUS_SUCCESS;
00737 }
00738
00739
KeInitializeEvent(&event, NotificationEvent,
FALSE);
00740
00741 irp =
IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
00742 deviceObject,
NULL, 0, &partInfo,
00743
sizeof(partInfo),
FALSE, &event,
00744 &ioStatus);
00745
if (!irp) {
00746
ObDereferenceObject(deviceObject);
00747
return STATUS_INSUFFICIENT_RESOURCES;
00748 }
00749
00750 status =
IoCallDriver(deviceObject, irp);
00751
if (status == STATUS_PENDING) {
00752
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
00753 status = ioStatus.Status;
00754 }
00755
00756
ObDereferenceObject(deviceObject);
00757
00758
if (!
NT_SUCCESS(status)) {
00759
return status;
00760 }
00761
00762
if (!IsRecognizedPartition(partInfo.PartitionType)) {
00763 *PartitionType =
OTHER_PARTITION;
00764
return STATUS_SUCCESS;
00765 }
00766
00767
if (partInfo.PartitionType&0x80) {
00768 *PartitionType =
FT_PARTITION;
00769
return STATUS_SUCCESS;
00770 }
00771
00772
for (i = 0; i < 4; i++) {
00773
if (partInfo.StartingOffset.QuadPart ==
00774 DriveLayout->PartitionEntry[i].StartingOffset.QuadPart) {
00775
00776
if (partInfo.BootIndicator) {
00777 *PartitionType =
BOOTABLE_PARTITION;
00778 }
else {
00779 *PartitionType =
PRIMARY_PARTITION;
00780 }
00781
00782
return STATUS_SUCCESS;
00783 }
00784 }
00785
00786 *PartitionType =
LOGICAL_PARTITION;
00787
return STATUS_SUCCESS;
00788 }
00789
00790
00791
NTSTATUS
00792 HalpQueryDriveLayout(
00793 IN PUNICODE_STRING DeviceName,
00794 OUT PDRIVE_LAYOUT_INFORMATION* DriveLayout
00795 )
00796
00797 {
00798
NTSTATUS status;
00799
PFILE_OBJECT fileObject;
00800
PDEVICE_OBJECT deviceObject;
00801
KEVENT event;
00802
PIRP irp;
00803 DISK_GEOMETRY geometry;
00804 IO_STATUS_BLOCK ioStatus;
00805
00806 status =
IoGetDeviceObjectPointer(DeviceName, FILE_READ_ATTRIBUTES,
00807 &fileObject, &deviceObject);
00808
if (!
NT_SUCCESS(status)) {
00809
return status;
00810 }
00811 deviceObject =
IoGetAttachedDeviceReference(fileObject->
DeviceObject);
00812
ObDereferenceObject(fileObject);
00813
00814
if (deviceObject->
Characteristics&FILE_REMOVABLE_MEDIA) {
00815
ObDereferenceObject(deviceObject);
00816
return STATUS_NO_MEDIA;
00817 }
00818
00819
KeInitializeEvent(&event, NotificationEvent,
FALSE);
00820
00821 irp =
IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
00822 deviceObject,
NULL, 0, &geometry,
00823
sizeof(geometry),
FALSE, &event,
00824 &ioStatus);
00825
if (!irp) {
00826
ObDereferenceObject(deviceObject);
00827
return STATUS_INSUFFICIENT_RESOURCES;
00828 }
00829
00830 status =
IoCallDriver(deviceObject, irp);
00831
if (status == STATUS_PENDING) {
00832
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
00833 status = ioStatus.Status;
00834 }
00835
00836
if (!
NT_SUCCESS(status)) {
00837
ObDereferenceObject(deviceObject);
00838
return status;
00839 }
00840
00841 status =
IoReadPartitionTable(deviceObject, geometry.BytesPerSector,
00842
FALSE, DriveLayout);
00843
00844
ObDereferenceObject(deviceObject);
00845
00846
return status;
00847 }
00848
00849
00850
NTSTATUS
00851 HalpNextMountLetter(
00852 IN PUNICODE_STRING DeviceName,
00853 OUT PUCHAR DriveLetter
00854 )
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 {
00875 UNICODE_STRING name;
00876
PFILE_OBJECT fileObject;
00877
PDEVICE_OBJECT deviceObject;
00878 PMOUNTMGR_DRIVE_LETTER_TARGET input;
00879
KEVENT event;
00880
PIRP irp;
00881 MOUNTMGR_DRIVE_LETTER_INFORMATION output;
00882 IO_STATUS_BLOCK ioStatus;
00883
NTSTATUS status;
00884
00885
RtlInitUnicodeString(&name, MOUNTMGR_DEVICE_NAME);
00886 status =
IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &fileObject,
00887 &deviceObject);
00888
if (!
NT_SUCCESS(status)) {
00889
return status;
00890 }
00891
00892 input =
ExAllocatePoolWithTag(
PagedPool,
00893 (
sizeof(MOUNTMGR_DRIVE_LETTER_TARGET) +
00894 DeviceName->Length),
00895 'btsF'
00896 );
00897
00898
if (!input) {
00899
ObDereferenceObject(fileObject);
00900
return STATUS_INSUFFICIENT_RESOURCES;
00901 }
00902
00903 input->DeviceNameLength = DeviceName->Length;
00904 RtlCopyMemory(input->DeviceName, DeviceName->Buffer, DeviceName->Length);
00905
00906
KeInitializeEvent(&event, NotificationEvent,
FALSE);
00907 irp =
IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER,
00908 deviceObject, input,
00909
sizeof(MOUNTMGR_DRIVE_LETTER_TARGET) +
00910 DeviceName->Length, &output,
00911
sizeof(output),
FALSE, &event,
00912 &ioStatus);
00913
if (!irp) {
00914
ExFreePool(input);
00915
ObDereferenceObject(fileObject);
00916
return STATUS_INSUFFICIENT_RESOURCES;
00917 }
00918
00919 status =
IoCallDriver(deviceObject, irp);
00920
if (status == STATUS_PENDING) {
00921
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
00922 status = ioStatus.Status;
00923 }
00924
00925
ExFreePool(input);
00926
ObDereferenceObject(fileObject);
00927
00928 *DriveLetter = output.CurrentDriveLetter;
00929
00930
return status;
00931 }
00932
00933 UCHAR
00934 HalpNextDriveLetter(
00935 IN PUNICODE_STRING DeviceName,
00936 IN PSTRING NtDeviceName,
00937 OUT PUCHAR NtSystemPath,
00938 IN BOOLEAN UseHardLinksIfNecessary
00939 )
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 {
00962
NTSTATUS status;
00963 UCHAR firstDriveLetter, driveLetter;
00964 WCHAR name[40];
00965 UNICODE_STRING symName;
00966 UNICODE_STRING unicodeString, floppyPrefix, cdromPrefix;
00967
00968 status =
HalpNextMountLetter(DeviceName, &driveLetter);
00969
if (
NT_SUCCESS(status)) {
00970
return driveLetter;
00971 }
00972
00973
if (!NtDeviceName || !NtSystemPath) {
00974
return 0xFF;
00975 }
00976
00977
RtlInitUnicodeString(&floppyPrefix,
L"\\Device\\Floppy");
00978
RtlInitUnicodeString(&cdromPrefix,
L"\\Device\\CdRom");
00979
if (
RtlPrefixUnicodeString(&floppyPrefix, DeviceName,
TRUE)) {
00980 firstDriveLetter =
'A';
00981 }
else if (
RtlPrefixUnicodeString(&cdromPrefix, DeviceName,
TRUE)) {
00982 firstDriveLetter =
'D';
00983 }
else {
00984 firstDriveLetter =
'C';
00985 }
00986
00987
for (driveLetter = firstDriveLetter; driveLetter <=
'Z'; driveLetter++) {
00988 status =
HalpSetMountLetter(DeviceName, driveLetter);
00989
if (
NT_SUCCESS(status)) {
00990
RtlAnsiStringToUnicodeString(&unicodeString, NtDeviceName,
TRUE);
00991
if (
RtlEqualUnicodeString(&unicodeString, DeviceName,
TRUE)) {
00992 NtSystemPath[0] = driveLetter;
00993 }
00994
RtlFreeUnicodeString(&unicodeString);
00995
return driveLetter;
00996 }
00997 }
00998
00999
if (!UseHardLinksIfNecessary) {
01000
return 0;
01001 }
01002
01003
for (driveLetter = firstDriveLetter; driveLetter <=
'Z'; driveLetter++) {
01004 swprintf(name,
L"\\DosDevices\\%c:", driveLetter);
01005
RtlInitUnicodeString(&symName, name);
01006 status =
IoCreateSymbolicLink(&symName, DeviceName);
01007
if (
NT_SUCCESS(status)) {
01008
RtlAnsiStringToUnicodeString(&unicodeString, NtDeviceName,
TRUE);
01009
if (
RtlEqualUnicodeString(&unicodeString, DeviceName,
TRUE)) {
01010 NtSystemPath[0] = driveLetter;
01011 }
01012
RtlFreeUnicodeString(&unicodeString);
01013
return driveLetter;
01014 }
01015 }
01016
01017
return 0;
01018 }
01019
01020
01021
VOID
01022 HalpEnableAutomaticDriveLetterAssignment(
01023 )
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 {
01043 UNICODE_STRING name;
01044
PFILE_OBJECT fileObject;
01045
PDEVICE_OBJECT deviceObject;
01046
KEVENT event;
01047
PIRP irp;
01048 IO_STATUS_BLOCK ioStatus;
01049
NTSTATUS status;
01050
01051
RtlInitUnicodeString(&name, MOUNTMGR_DEVICE_NAME);
01052 status =
IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &fileObject,
01053 &deviceObject);
01054
if (!
NT_SUCCESS(status)) {
01055
return;
01056 }
01057
01058
KeInitializeEvent(&event, NotificationEvent,
FALSE);
01059 irp =
IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS,
01060 deviceObject,
NULL, 0,
NULL, 0,
FALSE,
01061 &event, &ioStatus);
01062
if (!irp) {
01063
ObDereferenceObject(fileObject);
01064
return;
01065 }
01066
01067 status =
IoCallDriver(deviceObject, irp);
01068
if (status == STATUS_PENDING) {
01069
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
01070 status = ioStatus.Status;
01071 }
01072
01073
ObDereferenceObject(fileObject);
01074 }
01075
01076
01077
NTSTATUS
01078 HalpSetMountLetter(
01079 IN PUNICODE_STRING DeviceName,
01080 IN UCHAR DriveLetter
01081 )
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 {
01102 WCHAR dosBuffer[30];
01103 UNICODE_STRING dosName;
01104 ULONG createPointSize;
01105 PMOUNTMGR_CREATE_POINT_INPUT createPoint;
01106 UNICODE_STRING name;
01107
NTSTATUS status;
01108
PFILE_OBJECT fileObject;
01109
PDEVICE_OBJECT deviceObject;
01110
KEVENT event;
01111
PIRP irp;
01112 IO_STATUS_BLOCK ioStatus;
01113
01114 swprintf(dosBuffer,
L"\\DosDevices\\%c:", DriveLetter);
01115
RtlInitUnicodeString(&dosName, dosBuffer);
01116
01117 createPointSize =
sizeof(MOUNTMGR_CREATE_POINT_INPUT) +
01118 dosName.Length + DeviceName->Length;
01119
01120 createPoint = (PMOUNTMGR_CREATE_POINT_INPUT)
01121
ExAllocatePoolWithTag(
PagedPool, createPointSize, 'btsF');
01122
if (!createPoint) {
01123
return STATUS_INSUFFICIENT_RESOURCES;
01124 }
01125
01126 createPoint->SymbolicLinkNameOffset =
sizeof(MOUNTMGR_CREATE_POINT_INPUT);
01127 createPoint->SymbolicLinkNameLength = dosName.Length;
01128 createPoint->DeviceNameOffset = createPoint->SymbolicLinkNameOffset +
01129 createPoint->SymbolicLinkNameLength;
01130 createPoint->DeviceNameLength = DeviceName->Length;
01131
01132 RtlCopyMemory((PCHAR) createPoint + createPoint->SymbolicLinkNameOffset,
01133 dosName.Buffer, dosName.Length);
01134 RtlCopyMemory((PCHAR) createPoint + createPoint->DeviceNameOffset,
01135 DeviceName->Buffer, DeviceName->Length);
01136
01137
RtlInitUnicodeString(&name, MOUNTMGR_DEVICE_NAME);
01138 status =
IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &fileObject,
01139 &deviceObject);
01140
if (!
NT_SUCCESS(status)) {
01141
ExFreePool(createPoint);
01142
return status;
01143 }
01144
01145
KeInitializeEvent(&event, NotificationEvent,
FALSE);
01146 irp =
IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_CREATE_POINT,
01147 deviceObject, createPoint,
01148 createPointSize,
NULL, 0,
FALSE,
01149 &event, &ioStatus);
01150
if (!irp) {
01151
ObDereferenceObject(fileObject);
01152
ExFreePool(createPoint);
01153
return STATUS_INSUFFICIENT_RESOURCES;
01154 }
01155
01156 status =
IoCallDriver(deviceObject, irp);
01157
if (status == STATUS_PENDING) {
01158
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
01159 status = ioStatus.Status;
01160 }
01161
01162
ObDereferenceObject(fileObject);
01163
ExFreePool(createPoint);
01164
01165
return status;
01166 }
01167
01168
01169
01170 BOOLEAN
01171 HalpIsOldStyleFloppy(
01172 IN PUNICODE_STRING DeviceName
01173 )
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195 {
01196
PFILE_OBJECT fileObject;
01197
PDEVICE_OBJECT deviceObject;
01198
KEVENT event;
01199
PIRP irp;
01200 MOUNTDEV_NAME name;
01201 IO_STATUS_BLOCK ioStatus;
01202
NTSTATUS status;
01203
01204
PAGED_CODE();
01205
01206 status =
IoGetDeviceObjectPointer(DeviceName, FILE_READ_ATTRIBUTES,
01207 &fileObject, &deviceObject);
01208
if (!
NT_SUCCESS(status)) {
01209
return FALSE;
01210 }
01211 deviceObject =
IoGetAttachedDeviceReference(fileObject->
DeviceObject);
01212
ObDereferenceObject(fileObject);
01213
01214
01215
KeInitializeEvent(&event, NotificationEvent,
FALSE);
01216 irp =
IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
01217 deviceObject,
NULL, 0, &name,
01218
sizeof(name),
FALSE, &event,
01219 &ioStatus);
01220
if (!irp) {
01221
ObDereferenceObject(deviceObject);
01222
return FALSE;
01223 }
01224
01225 status =
IoCallDriver(deviceObject, irp);
01226
if (status == STATUS_PENDING) {
01227
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
01228 status = ioStatus.Status;
01229 }
01230
01231
ObDereferenceObject(deviceObject);
01232
01233
if (status == STATUS_BUFFER_OVERFLOW) {
01234
return FALSE;
01235 }
01236
01237
return TRUE;
01238 }
01239
01240
01241
VOID
01242
FASTCALL
01243 xHalIoAssignDriveLetters(
01244 IN
struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
01245 IN PSTRING NtDeviceName,
01246 OUT PUCHAR NtSystemPath,
01247 OUT PSTRING NtSystemPathString
01248 )
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302 {
01303 PUCHAR ntName;
01304 STRING ansiString;
01305 UNICODE_STRING unicodeString;
01306 PUCHAR ntPhysicalName;
01307 STRING ansiPhysicalString;
01308 UNICODE_STRING unicodePhysicalString;
01309
NTSTATUS status;
01310 OBJECT_ATTRIBUTES objectAttributes;
01311
PCONFIGURATION_INFORMATION configurationInformation;
01312 ULONG diskCount;
01313 ULONG floppyCount;
01314 HANDLE deviceHandle;
01315 IO_STATUS_BLOCK ioStatusBlock;
01316 ULONG diskNumber;
01317 ULONG i, j;
01318 UCHAR driveLetter;
01319 WCHAR deviceNameBuffer[50];
01320 UNICODE_STRING deviceName, floppyPrefix, cdromPrefix;
01321 PDRIVE_LAYOUT_INFORMATION layout;
01322 BOOLEAN bootable;
01323 ULONG partitionType;
01324 ULONG skip;
01325 ULONG diskCountIncrement;
01326 ULONG actualDiskCount = 0;
01327
01328
PAGED_CODE();
01329
01330
01331
01332
01333
01334 configurationInformation =
IoGetConfigurationInformation();
01335
01336 diskCount = configurationInformation->
DiskCount;
01337 floppyCount = configurationInformation->
FloppyCount;
01338
01339
01340
01341
01342
01343 ntName =
ExAllocatePoolWithTag(
NonPagedPool, 128, 'btsF');
01344
01345 ntPhysicalName =
ExAllocatePoolWithTag(
NonPagedPool, 64, 'btsF');
01346
01347
if (ntName ==
NULL || ntPhysicalName ==
NULL) {
01348
01349
KeBugCheck( ASSIGN_DRIVE_LETTERS_FAILED );
01350
01351 }
01352
01353
01354
01355
01356
01357
if (
IoRemoteBootClient) {
01358
01359 PUCHAR p;
01360 PUCHAR q;
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379 p = strrchr( LoaderBlock->NtBootPathName,
'\\' );
01380 q =
NULL;
01381
if ( (p !=
NULL) && (*(p+1) == 0) ) {
01382
01383
01384
01385
01386
01387
01388 q = p;
01389 *q = 0;
01390 p = strrchr( LoaderBlock->NtBootPathName,
'\\' );
01391 *q =
'\\';
01392 }
01393
if ( p ==
NULL ) {
01394
KeBugCheck( ASSIGN_DRIVE_LETTERS_FAILED );
01395 }
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
#if defined(REMOTE_BOOT)
01406
if ((LoaderBlock->SetupLoaderBlock->Flags & (
SETUPBLK_FLAGS_REMOTE_INSTALL |
01407
SETUPBLK_FLAGS_SYSPREP_INSTALL)) == 0) {
01408 NtSystemPath[0] =
'C';
01409 }
else
01410
#endif
01411
{
01412 NtSystemPath[0] =
'X';
01413 }
01414 NtSystemPath[1] =
':';
01415 strcpy(&NtSystemPath[2], p );
01416
if ( q !=
NULL ) {
01417 NtSystemPath[
strlen(NtSystemPath)-1] =
'\0';
01418 }
01419
RtlInitString(NtSystemPathString, NtSystemPath);
01420
01421 }
01422
01423
01424
01425
01426
01427 diskCountIncrement = 0;
01428
for (diskNumber = 0; diskNumber < diskCount; diskNumber++) {
01429
01430
01431
01432
01433
01434
sprintf( ntName,
DiskPartitionName, diskNumber, 0 );
01435
01436
01437
01438
01439
01440
RtlInitAnsiString( &ansiString, ntName );
01441
01442
RtlAnsiStringToUnicodeString( &unicodeString, &ansiString,
TRUE );
01443
01444 InitializeObjectAttributes( &objectAttributes,
01445 &unicodeString,
01446 OBJ_CASE_INSENSITIVE,
01447
NULL,
01448
NULL );
01449
01450
01451
01452
01453
01454 status =
ZwOpenFile( &deviceHandle,
01455 FILE_READ_DATA | SYNCHRONIZE,
01456 &objectAttributes,
01457 &ioStatusBlock,
01458 FILE_SHARE_READ,
01459 FILE_SYNCHRONOUS_IO_NONALERT );
01460
01461
if (
NT_SUCCESS( status )) {
01462
01463
01464
01465
01466
01467
01468
sprintf( ntPhysicalName,
"\\DosDevices\\PhysicalDrive%d", diskNumber );
01469
01470
RtlInitAnsiString( &ansiPhysicalString, ntPhysicalName );
01471
01472
RtlAnsiStringToUnicodeString( &unicodePhysicalString, &ansiPhysicalString,
TRUE );
01473
01474
IoCreateSymbolicLink( &unicodePhysicalString, &unicodeString );
01475
01476
RtlFreeUnicodeString( &unicodePhysicalString );
01477
01478 ZwClose(deviceHandle);
01479
01480 actualDiskCount = diskNumber + 1;
01481 }
01482
01483
RtlFreeUnicodeString( &unicodeString );
01484
01485
if (!
NT_SUCCESS( status )) {
01486
01487
#if DBG
01488
DbgPrint(
"IoAssignDriveLetters: Failed to open %s\n", ntName );
01489
#endif // DBG
01490
01491
01492
01493
01494
01495
01496
if (diskCountIncrement < 50) {
01497 diskCountIncrement++;
01498 diskCount++;
01499 }
01500 }
01501
01502 }
01503
01504
ExFreePool( ntName );
01505
ExFreePool( ntPhysicalName );
01506
01507 diskCount -= diskCountIncrement;
01508
if (actualDiskCount > diskCount) {
01509 diskCount = actualDiskCount;
01510 }
01511
01512
for (i = 0; i < diskCount; i++) {
01513
01514 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition0", i);
01515
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01516
01517 status =
HalpQueryDriveLayout(&deviceName, &layout);
01518
if (!
NT_SUCCESS(status)) {
01519 layout =
NULL;
01520 }
01521
01522 bootable =
FALSE;
01523
for (j = 1; ; j++) {
01524
01525 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition%d",
01526 i, j);
01527
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01528
01529 status =
HalpQueryPartitionType(&deviceName, layout,
01530 &partitionType);
01531
if (!
NT_SUCCESS(status)) {
01532
break;
01533 }
01534
01535
if (partitionType !=
BOOTABLE_PARTITION) {
01536
continue;
01537 }
01538
01539 bootable =
TRUE;
01540
01541
HalpNextDriveLetter(&deviceName, NtDeviceName, NtSystemPath,
FALSE);
01542
break;
01543 }
01544
01545
if (bootable) {
01546
if (layout) {
01547
ExFreePool(layout);
01548 }
01549
continue;
01550 }
01551
01552
for (j = 1; ; j++) {
01553
01554 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition%d",
01555 i, j);
01556
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01557
01558 status =
HalpQueryPartitionType(&deviceName, layout,
01559 &partitionType);
01560
if (!
NT_SUCCESS(status)) {
01561
break;
01562 }
01563
01564
if (partitionType !=
PRIMARY_PARTITION) {
01565
continue;
01566 }
01567
01568
HalpNextDriveLetter(&deviceName, NtDeviceName, NtSystemPath,
FALSE);
01569
break;
01570 }
01571
01572
if (layout) {
01573
ExFreePool(layout);
01574 }
01575 }
01576
01577
for (i = 0; i < diskCount; i++) {
01578
01579 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition0", i);
01580
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01581
01582 status =
HalpQueryDriveLayout(&deviceName, &layout);
01583
if (!
NT_SUCCESS(status)) {
01584 layout =
NULL;
01585 }
01586
01587
for (j = 1; ; j++) {
01588
01589 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition%d",
01590 i, j);
01591
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01592
01593 status =
HalpQueryPartitionType(&deviceName, layout,
01594 &partitionType);
01595
if (!
NT_SUCCESS(status)) {
01596
break;
01597 }
01598
01599
if (partitionType !=
LOGICAL_PARTITION) {
01600
continue;
01601 }
01602
01603
HalpNextDriveLetter(&deviceName, NtDeviceName, NtSystemPath,
FALSE);
01604 }
01605
01606
if (layout) {
01607
ExFreePool(layout);
01608 }
01609 }
01610
01611
for (i = 0; i < diskCount; i++) {
01612
01613 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition0", i);
01614
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01615
01616 status =
HalpQueryDriveLayout(&deviceName, &layout);
01617
if (!
NT_SUCCESS(status)) {
01618 layout =
NULL;
01619 }
01620
01621 skip = 0;
01622
for (j = 1; ; j++) {
01623
01624 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition%d",
01625 i, j);
01626
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01627
01628 status =
HalpQueryPartitionType(&deviceName, layout,
01629 &partitionType);
01630
if (!
NT_SUCCESS(status)) {
01631
break;
01632 }
01633
01634
if (partitionType ==
BOOTABLE_PARTITION) {
01635 skip = j;
01636 }
else if (partitionType ==
PRIMARY_PARTITION) {
01637
if (!skip) {
01638 skip = j;
01639 }
01640 }
01641 }
01642
01643
for (j = 1; ; j++) {
01644
01645
if (j == skip) {
01646
continue;
01647 }
01648
01649 swprintf(deviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition%d",
01650 i, j);
01651
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01652
01653 status =
HalpQueryPartitionType(&deviceName, layout,
01654 &partitionType);
01655
if (!
NT_SUCCESS(status)) {
01656
break;
01657 }
01658
01659
if (partitionType !=
PRIMARY_PARTITION &&
01660 partitionType !=
FT_PARTITION) {
01661
01662
continue;
01663 }
01664
01665
HalpNextDriveLetter(&deviceName, NtDeviceName, NtSystemPath,
FALSE);
01666 }
01667
01668
if (layout) {
01669
ExFreePool(layout);
01670 }
01671 }
01672
01673
for (i = 0; i < floppyCount; i++) {
01674
01675 swprintf(deviceNameBuffer,
L"\\Device\\Floppy%d", i);
01676
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01677
01678
if (!
HalpIsOldStyleFloppy(&deviceName)) {
01679
continue;
01680 }
01681
01682
HalpNextDriveLetter(&deviceName, NtDeviceName, NtSystemPath,
TRUE);
01683 }
01684
01685
for (i = 0; i < floppyCount; i++) {
01686
01687 swprintf(deviceNameBuffer,
L"\\Device\\Floppy%d", i);
01688
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01689
01690
if (
HalpIsOldStyleFloppy(&deviceName)) {
01691
continue;
01692 }
01693
01694
HalpNextDriveLetter(&deviceName, NtDeviceName, NtSystemPath,
TRUE);
01695 }
01696
01697
for (i = 0; i < configurationInformation->
CdRomCount; i++) {
01698
01699 swprintf(deviceNameBuffer,
L"\\Device\\CdRom%d", i);
01700
RtlInitUnicodeString(&deviceName, deviceNameBuffer);
01701
01702
HalpNextDriveLetter(&deviceName, NtDeviceName, NtSystemPath,
TRUE);
01703 }
01704
01705
if (!
IoRemoteBootClient) {
01706
RtlAnsiStringToUnicodeString(&unicodeString, NtDeviceName,
TRUE);
01707 driveLetter =
HalpNextDriveLetter(&unicodeString,
NULL,
NULL,
TRUE);
01708
if (driveLetter) {
01709
if (driveLetter != 0xFF) {
01710 NtSystemPath[0] = driveLetter;
01711 }
01712 }
else {
01713
RtlInitUnicodeString(&floppyPrefix,
L"\\Device\\Floppy");
01714
RtlInitUnicodeString(&cdromPrefix,
L"\\Device\\CdRom");
01715
if (
RtlPrefixUnicodeString(&floppyPrefix, &unicodeString,
TRUE)) {
01716 driveLetter =
'A';
01717 }
else if (
RtlPrefixUnicodeString(&cdromPrefix, &unicodeString,
TRUE)) {
01718 driveLetter =
'D';
01719 }
else {
01720 driveLetter =
'C';
01721 }
01722
for (; driveLetter <=
'Z'; driveLetter++) {
01723 status =
HalpSetMountLetter(&unicodeString, driveLetter);
01724
if (
NT_SUCCESS(status)) {
01725 NtSystemPath[0] = driveLetter;
01726 }
01727 }
01728 }
01729
RtlFreeUnicodeString(&unicodeString);
01730 }
01731
01732
HalpEnableAutomaticDriveLetterAssignment();
01733
01734 }
01735
01736
01737
NTSTATUS
01738
FASTCALL
01739 xHalIoReadPartitionTable(
01740 IN
PDEVICE_OBJECT DeviceObject,
01741 IN ULONG SectorSize,
01742 IN BOOLEAN ReturnRecognizedPartitions,
01743 OUT
struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer
01744 )
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806 {
01807 ULONG partitionBufferSize =
PARTITION_BUFFER_SIZE;
01808 PDRIVE_LAYOUT_INFORMATION newPartitionBuffer =
NULL;
01809
01810 LONG partitionTableCounter = -1;
01811
01812 DISK_GEOMETRY diskGeometry;
01813 ULONGLONG endSector;
01814 ULONGLONG maxSector;
01815 ULONGLONG maxOffset;
01816
01817 LARGE_INTEGER partitionTableOffset;
01818 LARGE_INTEGER volumeStartOffset;
01819 LARGE_INTEGER tempInt;
01820 BOOLEAN primaryPartitionTable;
01821 LONG partitionNumber;
01822 PUCHAR readBuffer = (PUCHAR)
NULL;
01823
KEVENT event;
01824
01825 IO_STATUS_BLOCK ioStatus;
01826
PIRP irp;
01827
PPARTITION_DESCRIPTOR partitionTableEntry;
01828 CCHAR partitionEntry;
01829
NTSTATUS status = STATUS_SUCCESS;
01830 ULONG readSize;
01831 PPARTITION_INFORMATION partitionInfo;
01832 BOOLEAN foundEZHooker =
FALSE;
01833
01834 BOOLEAN mbrSignatureFound =
FALSE;
01835 BOOLEAN emptyPartitionTable =
TRUE;
01836
01837
PAGED_CODE();
01838
01839
01840
01841
01842
01843
01844 *PartitionBuffer =
ExAllocatePoolWithTag(
NonPagedPool,
01845 partitionBufferSize,
01846 'btsF' );
01847
01848
if (*PartitionBuffer ==
NULL) {
01849
return STATUS_INSUFFICIENT_RESOURCES;
01850 }
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
if (
SectorSize >= 512) {
01861 readSize =
SectorSize;
01862 }
else {
01863 readSize = 512;
01864 }
01865
01866
01867
01868
01869
01870
01871 {
01872
01873 PVOID buff;
01874
01875
HalExamineMBR(
01876 DeviceObject,
01877 readSize,
01878 (ULONG)0x55,
01879 &buff
01880 );
01881
01882
if (buff) {
01883
01884 foundEZHooker =
TRUE;
01885
ExFreePool(buff);
01886 partitionTableOffset.QuadPart = 512;
01887
01888 }
else {
01889
01890 partitionTableOffset.QuadPart = 0;
01891
01892 }
01893
01894 }
01895
01896
01897
01898
01899
01900
01901 status =
HalpGetFullGeometry(DeviceObject,
01902 &diskGeometry,
01903 &maxOffset);
01904
01905
if(!
NT_SUCCESS(status)) {
01906
ExFreePool(*PartitionBuffer);
01907 *PartitionBuffer =
NULL;
01908
return status;
01909 }
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919 endSector = maxOffset;
01920
01921 maxSector = maxOffset * 2;
01922
01923
DebugPrint((2,
"MaxOffset = %#I64x, maxSector = %#I64x\n",
01924 maxOffset, maxSector));
01925
01926
01927
01928
01929
01930
01931 primaryPartitionTable =
TRUE;
01932
01933
01934
01935
01936
01937 volumeStartOffset.QuadPart = 0;
01938
01939
01940
01941
01942
01943 partitionNumber = -1;
01944
01945
01946
01947
01948
01949 readBuffer =
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned,
01950
PAGE_SIZE,
01951 'btsF' );
01952
01953
if (readBuffer ==
NULL) {
01954
ExFreePool( *PartitionBuffer );
01955
return STATUS_INSUFFICIENT_RESOURCES;
01956 }
01957
01958
01959
01960
01961
01962
01963
01964
do {
01965
01966 BOOLEAN tableIsValid;
01967 ULONG containerPartitionCount;
01968
01969 tableIsValid =
TRUE;
01970
01971
01972
01973
01974
01975
01976
01977
01978
KeInitializeEvent( &event, NotificationEvent,
FALSE );
01979
01980
01981
01982
01983
01984
01985 RtlZeroMemory(readBuffer, readSize);
01986
01987 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_READ,
01988 DeviceObject,
01989 readBuffer,
01990 readSize,
01991 &partitionTableOffset,
01992 &event,
01993 &ioStatus );
01994
01995
if (!irp) {
01996 status = STATUS_INSUFFICIENT_RESOURCES;
01997
break;
01998 }
else {
01999
PIO_STACK_LOCATION irpStack;
02000 irpStack =
IoGetNextIrpStackLocation(irp);
02001 irpStack->
Flags |=
SL_OVERRIDE_VERIFY_VOLUME;
02002 }
02003
02004 status =
IoCallDriver( DeviceObject, irp );
02005
02006
if (status == STATUS_PENDING) {
02007 (
VOID)
KeWaitForSingleObject( &event,
02008
Executive,
02009
KernelMode,
02010
FALSE,
02011 (PLARGE_INTEGER)
NULL);
02012 status = ioStatus.Status;
02013 }
02014
02015
02016
02017
02018
02019
02020
02021
if(status == STATUS_NO_DATA_DETECTED) {
02022 status = STATUS_SUCCESS;
02023 }
02024
02025
if (!
NT_SUCCESS( status )) {
02026
break;
02027 }
02028
02029
02030
02031
02032
02033
02034
02035
02036
if (foundEZHooker && (partitionTableOffset.QuadPart == 512)) {
02037
02038 partitionTableOffset.QuadPart = 0;
02039
02040 }
02041
02042
02043
02044
02045
02046
if (((
PUSHORT) readBuffer)[
BOOT_SIGNATURE_OFFSET] !=
BOOT_RECORD_SIGNATURE) {
02047
02048
DebugPrint((1,
"xHalIoReadPT: No 0xaa55 found in partition table %d\n",
02049 partitionTableCounter + 1));
02050
02051
break;
02052
02053 }
else {
02054 mbrSignatureFound =
TRUE;
02055 }
02056
02057
02058
02059
02060
02061
if (partitionTableOffset.QuadPart == 0) {
02062 (*PartitionBuffer)->Signature = ((PULONG) readBuffer)[
PARTITION_TABLE_OFFSET/2-1];
02063 }
02064
02065 partitionTableEntry = (
PPARTITION_DESCRIPTOR) &(((
PUSHORT) readBuffer)[
PARTITION_TABLE_OFFSET]);
02066
02067
02068
02069
02070
02071 partitionTableCounter++;
02072
02073
02074
02075
02076
02077
02078
DebugPrint((2,
"Partition Table %d:\n", partitionTableCounter));
02079
02080
for (partitionEntry = 1, containerPartitionCount = 0;
02081 partitionEntry <=
NUM_PARTITION_TABLE_ENTRIES;
02082 partitionEntry++, partitionTableEntry++) {
02083
02084
DebugPrint((2,
"Partition Entry %d,%d: type %#x %s\n",
02085 partitionTableCounter,
02086 partitionEntry,
02087 partitionTableEntry->
PartitionType,
02088 (partitionTableEntry->
ActiveFlag) ?
"Active" :
""));
02089
02090
DebugPrint((2,
"\tOffset %#08lx for %#08lx Sectors\n",
02091
GET_STARTING_SECTOR(partitionTableEntry),
02092
GET_PARTITION_LENGTH(partitionTableEntry)));
02093
02094
02095
02096
02097
02098
if((
HalpIsValidPartitionEntry(partitionTableEntry,
02099 maxOffset,
02100 maxSector) ==
FALSE) &&
02101 (partitionTableCounter == 0)) {
02102
02103
ASSERT(
DrivesupBreakIn ==
FALSE);
02104
DrivesupBreakIn =
FALSE;
02105 tableIsValid =
FALSE;
02106
break;
02107
02108 }
02109
02110
02111
02112
02113
02114
if(IsContainerPartition(partitionTableEntry->
PartitionType)) {
02115
02116 containerPartitionCount++;
02117
02118
if(containerPartitionCount != 1) {
02119
02120
DebugPrint((1,
"Multiple container partitions found in "
02121
"partition table %d\n - table is invalid\n",
02122 partitionTableCounter));
02123 tableIsValid =
FALSE;
02124
break;
02125 }
02126
02127 }
02128
02129
if(emptyPartitionTable) {
02130
02131
if((
GET_STARTING_SECTOR(partitionTableEntry) != 0) ||
02132 (
GET_PARTITION_LENGTH(partitionTableEntry) != 0)) {
02133
02134
02135
02136
02137
02138
02139 emptyPartitionTable =
FALSE;
02140 }
02141 }
02142
02143
02144
02145
02146
02147
02148
02149
if (ReturnRecognizedPartitions) {
02150
02151
02152
02153
02154
02155
02156
02157
if ((partitionTableEntry->
PartitionType == PARTITION_ENTRY_UNUSED) ||
02158 IsContainerPartition(partitionTableEntry->
PartitionType)) {
02159
02160
continue;
02161 }
02162 }
02163
02164
02165
02166
02167
02168 partitionNumber++;
02169
02170
if (((partitionNumber *
sizeof( PARTITION_INFORMATION )) +
02171
sizeof( DRIVE_LAYOUT_INFORMATION )) >
02172 (ULONG) partitionBufferSize) {
02173
02174
02175
02176
02177
02178
02179
02180
02181 newPartitionBuffer =
ExAllocatePoolWithTag(
NonPagedPool,
02182 partitionBufferSize << 1,
02183 'btsF' );
02184
02185
if (newPartitionBuffer ==
NULL) {
02186 --partitionNumber;
02187 status = STATUS_INSUFFICIENT_RESOURCES;
02188
break;
02189 }
02190
02191 RtlMoveMemory( newPartitionBuffer,
02192 *PartitionBuffer,
02193 partitionBufferSize );
02194
02195
ExFreePool( *PartitionBuffer );
02196
02197
02198
02199
02200
02201
02202 *PartitionBuffer = newPartitionBuffer;
02203 partitionBufferSize <<= 1;
02204 }
02205
02206
02207
02208
02209
02210
02211
02212
02213 partitionInfo = &(*PartitionBuffer)->PartitionEntry[partitionNumber];
02214
02215 partitionInfo->PartitionType = partitionTableEntry->
PartitionType;
02216
02217 partitionInfo->RewritePartition =
FALSE;
02218
02219
if (partitionTableEntry->
PartitionType != PARTITION_ENTRY_UNUSED) {
02220 LONGLONG startOffset;
02221
02222 partitionInfo->BootIndicator =
02223 partitionTableEntry->
ActiveFlag &
PARTITION_ACTIVE_FLAG ?
02224 (BOOLEAN)
TRUE : (BOOLEAN)
FALSE;
02225
02226
if (IsContainerPartition(partitionTableEntry->
PartitionType)) {
02227 partitionInfo->RecognizedPartition =
FALSE;
02228 startOffset = volumeStartOffset.QuadPart;
02229 }
else {
02230 partitionInfo->RecognizedPartition =
TRUE;
02231 startOffset = partitionTableOffset.QuadPart;
02232 }
02233
02234 partitionInfo->StartingOffset.QuadPart = startOffset +
02235 UInt32x32To64(
GET_STARTING_SECTOR(partitionTableEntry),
02236
SectorSize);
02237 tempInt.QuadPart = (partitionInfo->StartingOffset.QuadPart -
02238 startOffset) /
SectorSize;
02239 partitionInfo->HiddenSectors = tempInt.LowPart;
02240
02241 partitionInfo->PartitionLength.QuadPart =
02242 UInt32x32To64(
GET_PARTITION_LENGTH(partitionTableEntry),
02243
SectorSize);
02244
02245 }
else {
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255 partitionInfo->BootIndicator =
FALSE;
02256 partitionInfo->RecognizedPartition =
FALSE;
02257 partitionInfo->StartingOffset.QuadPart = 0;
02258 partitionInfo->PartitionLength.QuadPart = 0;
02259 partitionInfo->HiddenSectors = 0;
02260 }
02261
02262 }
02263
02264
DebugPrint((2,
"\n"));
02265
02266
02267
02268
02269
02270
if (!
NT_SUCCESS( status )) {
02271
break;
02272 }
02273
02274
if(tableIsValid ==
FALSE) {
02275
02276
02277
02278
02279
02280
02281
02282 partitionTableCounter--;
02283
break;
02284 }
02285
02286
02287
02288
02289
02290
02291
02292
02293 partitionTableEntry = (
PPARTITION_DESCRIPTOR) &(((
PUSHORT) readBuffer)[
PARTITION_TABLE_OFFSET]);
02294
02295
02296
02297
02298
02299 partitionTableOffset.QuadPart = 0;
02300
02301
for (partitionEntry = 1;
02302 partitionEntry <=
NUM_PARTITION_TABLE_ENTRIES;
02303 partitionEntry++, partitionTableEntry++) {
02304
02305
if (IsContainerPartition(partitionTableEntry->
PartitionType)) {
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316 partitionTableOffset.QuadPart = volumeStartOffset.QuadPart +
02317 UInt32x32To64(
GET_STARTING_SECTOR(partitionTableEntry),
02318
SectorSize);
02319
02320
02321
02322
02323
02324
02325
02326
02327
if (primaryPartitionTable) {
02328 volumeStartOffset = partitionTableOffset;
02329 }
02330
02331
02332
02333
02334
02335
02336 maxSector =
GET_PARTITION_LENGTH(partitionTableEntry);
02337
02338
DebugPrint((2,
"MaxSector now = %#08lx\n", maxSector));
02339
02340
02341
02342
02343
02344
02345
break;
02346 }
02347 }
02348
02349
02350
02351
02352
02353
02354 primaryPartitionTable =
FALSE;
02355
02356
02357 }
while (partitionTableOffset.HighPart | partitionTableOffset.LowPart);
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
DebugPrint((4,
"xHalIoReadPartitionTable: RM %d PTC %d MBR %d EPT %d\n",
02368 diskGeometry.MediaType,
02369 partitionTableCounter,
02370 mbrSignatureFound,
02371 emptyPartitionTable));
02372
02373
if((diskGeometry.MediaType == RemovableMedia) &&
02374 (partitionTableCounter == 0) &&
02375 (mbrSignatureFound ==
TRUE) &&
02376 (emptyPartitionTable ==
TRUE)) {
02377
02378
PBOOT_SECTOR_INFO bootSector = (
PBOOT_SECTOR_INFO) readBuffer;
02379
02380
if((bootSector->
JumpByte[0] == 0xeb) ||
02381 (bootSector->
JumpByte[0] == 0xe9)) {
02382
02383
02384
02385
02386
02387
DebugPrint((1,
"xHalIoReadPartitionTable: Jump byte %#x found "
02388
"along with empty partition table - disk is a "
02389
"super floppy and has no valid MBR\n",
02390 bootSector->
JumpByte));
02391
02392 partitionTableCounter = -1;
02393 }
02394 }
02395
02396
02397
02398
02399
02400
02401
02402
if(partitionTableCounter == -1) {
02403
02404
if((mbrSignatureFound ==
TRUE) ||
02405 (diskGeometry.MediaType == RemovableMedia)) {
02406
02407
02408
02409
02410
02411
02412
02413
02414
DebugPrint((1,
"xHalIoReadPartitionTable: Drive %#p has no valid MBR. "
02415
"Make it into a super-floppy\n", DeviceObject));
02416
02417
DebugPrint((1,
"xHalIoReadPartitionTable: Drive has %#08lx sectors "
02418
"and is %#016I64x bytes large\n",
02419 endSector, endSector * diskGeometry.BytesPerSector));
02420
02421
if (endSector > 0) {
02422
02423 partitionInfo = &(*PartitionBuffer)->PartitionEntry[0];
02424
02425 partitionInfo->RewritePartition =
FALSE;
02426 partitionInfo->RecognizedPartition =
TRUE;
02427 partitionInfo->PartitionType = PARTITION_FAT_16;
02428 partitionInfo->BootIndicator =
FALSE;
02429
02430 partitionInfo->HiddenSectors = 0;
02431
02432 partitionInfo->StartingOffset.QuadPart = 0;
02433
02434 partitionInfo->PartitionLength.QuadPart =
02435 (endSector * diskGeometry.BytesPerSector);
02436
02437 (*PartitionBuffer)->Signature = 1;
02438
02439 partitionNumber = 0;
02440 }
02441 }
else {
02442
02443
02444
02445
02446
02447
02448 partitionNumber = -1;
02449 }
02450 }
02451
02452
02453
02454
02455
02456
02457 (*PartitionBuffer)->PartitionCount = ++partitionNumber;
02458
02459
if (!partitionNumber) {
02460
02461
02462
02463
02464
02465 (*PartitionBuffer)->Signature = 0;
02466 }
02467
02468
02469
02470
02471
02472
if (readBuffer !=
NULL) {
02473
ExFreePool( readBuffer );
02474 }
02475
02476
if (!
NT_SUCCESS(status)) {
02477
ExFreePool(*PartitionBuffer);
02478 *PartitionBuffer =
NULL;
02479 }
02480
return status;
02481 }
02482
02483
NTSTATUS
02484
FASTCALL
02485 xHalIoSetPartitionInformation(
02486 IN
PDEVICE_OBJECT DeviceObject,
02487 IN ULONG SectorSize,
02488 IN ULONG PartitionNumber,
02489 IN ULONG PartitionType
02490 )
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544 {
02545
02546
#define GET_STARTING_SECTOR( p ) ( \
02547
(ULONG) (p->StartingSectorLsb0) + \
02548
(ULONG) (p->StartingSectorLsb1 << 8) + \
02549
(ULONG) (p->StartingSectorMsb0 << 16) + \
02550
(ULONG) (p->StartingSectorMsb1 << 24) )
02551
02552
PIRP irp;
02553
KEVENT event;
02554 IO_STATUS_BLOCK ioStatus;
02555
NTSTATUS status;
02556 LARGE_INTEGER partitionTableOffset;
02557 LARGE_INTEGER volumeStartOffset;
02558 PUCHAR buffer = (PUCHAR)
NULL;
02559 ULONG transferSize;
02560 ULONG partitionNumber;
02561 ULONG partitionEntry;
02562
PPARTITION_DESCRIPTOR partitionTableEntry;
02563 BOOLEAN primaryPartitionTable;
02564 BOOLEAN foundEZHooker =
FALSE;
02565
02566
PAGED_CODE();
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
if (
SectorSize >= 512) {
02579 transferSize =
SectorSize;
02580 }
else {
02581 transferSize = 512;
02582 }
02583
02584
02585
02586
02587
02588
02589
02590 {
02591
02592 PVOID buff;
02593
02594
HalExamineMBR(
02595 DeviceObject,
02596 transferSize,
02597 (ULONG)0x55,
02598 &buff
02599 );
02600
02601
if (buff) {
02602
02603 foundEZHooker =
TRUE;
02604
ExFreePool(buff);
02605 partitionTableOffset.QuadPart = 512;
02606
02607 }
else {
02608
02609 partitionTableOffset.QuadPart = 0;
02610
02611 }
02612
02613 }
02614
02615
02616
02617
02618
02619
02620 volumeStartOffset.QuadPart = 0;
02621
02622
02623
02624
02625
02626
02627 primaryPartitionTable =
TRUE;
02628
02629
02630
02631
02632
02633 partitionNumber = 0;
02634
02635
02636
02637
02638
02639 buffer =
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned,
PAGE_SIZE, 'btsF');
02640
if (buffer ==
NULL) {
02641
return STATUS_INSUFFICIENT_RESOURCES;
02642 }
02643
02644
02645
02646
02647
02648
02649
KeInitializeEvent( &event, NotificationEvent,
FALSE );
02650
02651
02652
02653
02654
02655
02656
do {
02657
02658
02659
02660
02661
02662 (
VOID)
KeResetEvent( &event );
02663
02664 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_READ,
02665 DeviceObject,
02666 buffer,
02667 transferSize,
02668 &partitionTableOffset,
02669 &event,
02670 &ioStatus );
02671
02672
if (!irp) {
02673 status = STATUS_INSUFFICIENT_RESOURCES;
02674
break;
02675 }
else {
02676
PIO_STACK_LOCATION irpStack;
02677 irpStack =
IoGetNextIrpStackLocation(irp);
02678 irpStack->
Flags |=
SL_OVERRIDE_VERIFY_VOLUME;
02679 }
02680
02681 status =
IoCallDriver( DeviceObject, irp );
02682
02683
if (status == STATUS_PENDING) {
02684 (
VOID)
KeWaitForSingleObject( &event,
02685
Executive,
02686
KernelMode,
02687
FALSE,
02688 (PLARGE_INTEGER)
NULL );
02689 status = ioStatus.Status;
02690 }
02691
02692
if (!
NT_SUCCESS( status )) {
02693
break;
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703
if (foundEZHooker && (partitionTableOffset.QuadPart == 512)) {
02704
02705 partitionTableOffset.QuadPart = 0;
02706
02707 }
02708
02709
02710
02711
02712
02713
02714
if (((
PUSHORT) buffer)[
BOOT_SIGNATURE_OFFSET] !=
BOOT_RECORD_SIGNATURE) {
02715 status = STATUS_BAD_MASTER_BOOT_RECORD;
02716
break;
02717 }
02718
02719 partitionTableEntry = (
PPARTITION_DESCRIPTOR) &(((
PUSHORT) buffer)[
PARTITION_TABLE_OFFSET]);
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
for (partitionEntry = 1;
02730 partitionEntry <=
NUM_PARTITION_TABLE_ENTRIES;
02731 partitionEntry++, partitionTableEntry++) {
02732
02733
02734
02735
02736
02737
02738
if ((partitionTableEntry->
PartitionType == PARTITION_ENTRY_UNUSED) ||
02739 IsContainerPartition(partitionTableEntry->
PartitionType)) {
02740
continue;
02741 }
02742
02743
02744
02745
02746
02747
02748
02749 partitionNumber++;
02750
02751
if (partitionNumber == PartitionNumber) {
02752
02753
02754
02755
02756
02757
02758
02759 partitionTableEntry->
PartitionType = (UCHAR) PartitionType;
02760
02761 (
VOID)
KeResetEvent( &event );
02762
02763 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_WRITE,
02764 DeviceObject,
02765 buffer,
02766 transferSize,
02767 &partitionTableOffset,
02768 &event,
02769 &ioStatus );
02770
02771
if (!irp) {
02772 status = STATUS_INSUFFICIENT_RESOURCES;
02773
break;
02774 }
else {
02775
PIO_STACK_LOCATION irpStack;
02776 irpStack =
IoGetNextIrpStackLocation(irp);
02777 irpStack->
Flags |=
SL_OVERRIDE_VERIFY_VOLUME;
02778 }
02779
02780 status =
IoCallDriver( DeviceObject, irp );
02781
02782
if (status == STATUS_PENDING) {
02783 (
VOID)
KeWaitForSingleObject( &event,
02784
Executive,
02785
KernelMode,
02786
FALSE,
02787 (PLARGE_INTEGER)
NULL );
02788 status = ioStatus.Status;
02789 }
02790
02791
break;
02792 }
02793 }
02794
02795
02796
02797
02798
02799
02800
02801
if (partitionEntry <=
NUM_PARTITION_TABLE_ENTRIES) {
02802
break;
02803 }
02804
02805
02806
02807
02808
02809
02810
02811
02812 partitionTableEntry = (
PPARTITION_DESCRIPTOR) &(((
PUSHORT) buffer)[
PARTITION_TABLE_OFFSET]);
02813
02814
for (partitionEntry = 1;
02815 partitionEntry <=
NUM_PARTITION_TABLE_ENTRIES;
02816 partitionEntry++, partitionTableEntry++) {
02817
02818
if (IsContainerPartition(partitionTableEntry->
PartitionType)) {
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829 partitionTableOffset.QuadPart = volumeStartOffset.QuadPart +
02830 UInt32x32To64(
GET_STARTING_SECTOR(partitionTableEntry),
02831
SectorSize);
02832
02833
02834
02835
02836
02837
02838
02839
02840
if (primaryPartitionTable) {
02841 volumeStartOffset = partitionTableOffset;
02842 }
02843
02844
break;
02845 }
02846 }
02847
02848
02849
02850
02851
02852
02853
if (partitionEntry >
NUM_PARTITION_TABLE_ENTRIES) {
02854 status = STATUS_BAD_MASTER_BOOT_RECORD;
02855
break;
02856 }
02857
02858
02859
02860
02861
02862 primaryPartitionTable =
FALSE;
02863
02864 }
while (partitionNumber < PartitionNumber);
02865
02866
02867
02868
02869
02870
if (buffer !=
NULL) {
02871
ExFreePool( buffer );
02872 }
02873
02874
return status;
02875 }
02876
02877
NTSTATUS
02878
FASTCALL
02879 xHalIoWritePartitionTable(
02880 IN
PDEVICE_OBJECT DeviceObject,
02881 IN ULONG SectorSize,
02882 IN ULONG SectorsPerTrack,
02883 IN ULONG NumberOfHeads,
02884 IN
struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer
02885 )
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921 {
02922
typedef struct _PARTITION_TABLE {
02923 PARTITION_INFORMATION PartitionEntry[4];
02924 } PARTITION_TABLE, *PPARTITION_TABLE;
02925
02926
typedef struct _DISK_LAYOUT {
02927 ULONG TableCount;
02928 ULONG Signature;
02929 PARTITION_TABLE PartitionTable[1];
02930 } DISK_LAYOUT, *PDISK_LAYOUT;
02931
02932
typedef struct _PTE {
02933 UCHAR ActiveFlag;
02934 UCHAR StartingTrack;
02935
USHORT StartingCylinder;
02936 UCHAR PartitionType;
02937 UCHAR EndingTrack;
02938
USHORT EndingCylinder;
02939 ULONG StartingSector;
02940 ULONG PartitionLength;
02941 } PTE;
02942
typedef PTE UNALIGNED *PPTE;
02943
02944
02945
02946
02947
02948
#define WHICH_BIT(Data, Bit) { \
02949
for (Bit = 0; Bit < 32; Bit++) { \
02950
if ((Data >> Bit) == 1) { \
02951
break; \
02952
} \
02953
} \
02954
}
02955
02956 ULONG writeSize;
02957
PUSHORT writeBuffer =
NULL;
02958 PPTE partitionEntry;
02959 PPARTITION_TABLE partitionTable;
02960 CCHAR shiftCount;
02961 LARGE_INTEGER partitionTableOffset;
02962 LARGE_INTEGER nextRecordOffset;
02963 ULONG partitionTableCount;
02964 ULONG partitionEntryCount;
02965
KEVENT event;
02966 IO_STATUS_BLOCK ioStatus;
02967
PIRP irp;
02968 BOOLEAN rewritePartition =
FALSE;
02969
NTSTATUS status = STATUS_SUCCESS;
02970 LARGE_INTEGER tempInt;
02971 BOOLEAN foundEZHooker =
FALSE;
02972 ULONG conventionalCylinders;
02973 LONGLONG diskSize;
02974
02975 BOOLEAN isSuperFloppy =
FALSE;
02976
02977
02978
02979
02980
02981 PDISK_LAYOUT diskLayout = (PDISK_LAYOUT) PartitionBuffer;
02982
02983
02984
02985
02986
02987
PAGED_CODE();
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
if (
SectorSize >= 512) {
02998 writeSize =
SectorSize;
02999 }
else {
03000 writeSize = 512;
03001 }
03002
03003
xHalGetPartialGeometry( DeviceObject,
03004 &conventionalCylinders,
03005 &diskSize );
03006
03007
03008
03009
03010
03011
03012 {
03013
03014 PVOID buff;
03015
03016
HalExamineMBR(
03017 DeviceObject,
03018 writeSize,
03019 (ULONG)0x55,
03020 &buff
03021 );
03022
03023
if (buff) {
03024
03025 foundEZHooker =
TRUE;
03026
ExFreePool(buff);
03027 partitionTableOffset.QuadPart = 512;
03028
03029 }
else {
03030
03031 partitionTableOffset.QuadPart = 0;
03032
03033 }
03034
03035 }
03036
03037
03038
03039
03040
03041 nextRecordOffset.QuadPart = 0;
03042
03043
03044
03045
03046
03047
WHICH_BIT(
SectorSize, shiftCount );
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
if(PartitionBuffer->PartitionCount == 1) {
03062
03063 PPARTITION_INFORMATION partitionEntry = PartitionBuffer->PartitionEntry;
03064
03065
if((partitionEntry->StartingOffset.QuadPart == 0) &&
03066 (partitionEntry->HiddenSectors == 0)) {
03067
03068 isSuperFloppy =
TRUE;
03069
03070
03071
03072
03073
03074
03075
03076
03077
if((partitionEntry->PartitionNumber != 0) ||
03078 (partitionEntry->PartitionType != PARTITION_FAT_16) ||
03079 (partitionEntry->BootIndicator ==
TRUE)) {
03080
03081
return STATUS_INVALID_PARAMETER;
03082 }
03083
03084
if(partitionEntry->RewritePartition ==
TRUE) {
03085 rewritePartition =
TRUE;
03086 }
03087
03088 foundEZHooker =
FALSE;
03089 }
03090 }
03091
03092
03093
03094
03095
03096 diskLayout->TableCount =
03097 (PartitionBuffer->PartitionCount +
03098
NUM_PARTITION_TABLE_ENTRIES - 1) /
03099
NUM_PARTITION_TABLE_ENTRIES;
03100
03101
03102
03103
03104
03105 writeBuffer =
ExAllocatePoolWithTag(
NonPagedPoolCacheAligned,
PAGE_SIZE, 'btsF');
03106
03107
if (writeBuffer ==
NULL) {
03108
return STATUS_INSUFFICIENT_RESOURCES;
03109 }
03110
03111
03112
03113
03114
03115 partitionEntry = (PPTE) &writeBuffer[
PARTITION_TABLE_OFFSET];
03116
03117
for (partitionTableCount = 0;
03118 partitionTableCount < diskLayout->TableCount;
03119 partitionTableCount++) {
03120
03121 UCHAR partitionType;
03122
03123
03124
03125
03126
03127
03128 BOOLEAN mbr = (BOOLEAN) (!partitionTableCount);
03129 LARGE_INTEGER extendedPartitionOffset;
03130
03131
03132
03133
03134
03135
03136
03137
KeInitializeEvent( &event, NotificationEvent,
FALSE );
03138
03139 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_READ,
03140 DeviceObject,
03141 writeBuffer,
03142 writeSize,
03143 &partitionTableOffset,
03144 &event,
03145 &ioStatus );
03146
03147
if (!irp) {
03148 status = STATUS_INSUFFICIENT_RESOURCES;
03149
break;
03150 }
else {
03151
PIO_STACK_LOCATION irpStack;
03152 irpStack =
IoGetNextIrpStackLocation(irp);
03153 irpStack->
Flags |=
SL_OVERRIDE_VERIFY_VOLUME;
03154 }
03155
03156 status =
IoCallDriver( DeviceObject, irp );
03157
03158
if (status == STATUS_PENDING) {
03159 (
VOID)
KeWaitForSingleObject( &event,
03160
Executive,
03161
KernelMode,
03162
FALSE,
03163 (PLARGE_INTEGER)
NULL);
03164 status = ioStatus.Status;
03165 }
03166
03167
if (!
NT_SUCCESS( status )) {
03168
break;
03169 }
03170
03171
03172
03173
03174
03175
03176
03177
03178
if (foundEZHooker && (partitionTableOffset.QuadPart == 512)) {
03179
03180 partitionTableOffset.QuadPart = 0;
03181
03182 }
03183
03184
if(isSuperFloppy ==
FALSE) {
03185
03186
03187
03188
03189
03190 writeBuffer[
BOOT_SIGNATURE_OFFSET] =
BOOT_RECORD_SIGNATURE;
03191
03192
03193
03194
03195
03196 rewritePartition =
FALSE;
03197
if (partitionTableOffset.QuadPart == 0) {
03198
03199
if (((PULONG)writeBuffer)[
PARTITION_TABLE_OFFSET/2-1] !=
03200 PartitionBuffer->Signature) {
03201
03202 ((PULONG) writeBuffer)[
PARTITION_TABLE_OFFSET/2-1] =
03203 PartitionBuffer->Signature;
03204 rewritePartition =
TRUE;
03205 }
03206 }
03207
03208
03209
03210
03211
03212 partitionTable = &diskLayout->PartitionTable[partitionTableCount];
03213
03214
03215
03216
03217
03218
03219
03220
for (partitionEntryCount = 0;
03221 partitionEntryCount <
NUM_PARTITION_TABLE_ENTRIES;
03222 partitionEntryCount++) {
03223
03224 partitionType =
03225 partitionTable->PartitionEntry[partitionEntryCount].PartitionType;
03226
03227
03228
03229
03230
03231
03232
if (partitionTable->PartitionEntry[partitionEntryCount].RewritePartition) {
03233
03234
03235
03236
03237
03238 rewritePartition =
TRUE;
03239
03240
03241
03242
03243
03244 partitionEntry[partitionEntryCount].PartitionType =
03245 partitionTable->PartitionEntry[partitionEntryCount].PartitionType;
03246
03247
03248
03249
03250
03251 partitionEntry[partitionEntryCount].ActiveFlag =
03252 partitionTable->PartitionEntry[partitionEntryCount].BootIndicator ?
03253 (UCHAR)
PARTITION_ACTIVE_FLAG : (UCHAR) 0;
03254
03255
if (partitionType != PARTITION_ENTRY_UNUSED) {
03256
03257 LARGE_INTEGER sectorOffset;
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
if (mbr || !IsContainerPartition(partitionType)) {
03268 tempInt.QuadPart = partitionTableOffset.QuadPart;
03269 }
else {
03270 tempInt.QuadPart = extendedPartitionOffset.QuadPart;
03271 }
03272
03273 sectorOffset.QuadPart =
03274 partitionTable->PartitionEntry[partitionEntryCount].StartingOffset.QuadPart -
03275 tempInt.QuadPart;
03276
03277 tempInt.QuadPart = sectorOffset.QuadPart >> shiftCount;
03278 partitionEntry[partitionEntryCount].StartingSector = tempInt.LowPart;
03279
03280
03281
03282
03283
03284 tempInt.QuadPart = partitionTable->PartitionEntry[partitionEntryCount].PartitionLength.QuadPart >> shiftCount;
03285 partitionEntry[partitionEntryCount].PartitionLength = tempInt.LowPart;
03286
03287
03288
03289
03290
03291
HalpCalculateChsValues(
03292 &partitionTable->PartitionEntry[partitionEntryCount].StartingOffset,
03293 &partitionTable->PartitionEntry[partitionEntryCount].PartitionLength,
03294 shiftCount,
03295 SectorsPerTrack,
03296 NumberOfHeads,
03297 conventionalCylinders,
03298 (
PPARTITION_DESCRIPTOR) &partitionEntry[partitionEntryCount]);
03299
03300 }
else {
03301
03302
03303
03304
03305
03306
03307 partitionEntry[partitionEntryCount].StartingSector = 0;
03308 partitionEntry[partitionEntryCount].PartitionLength = 0;
03309 partitionEntry[partitionEntryCount].StartingTrack = 0;
03310 partitionEntry[partitionEntryCount].EndingTrack = 0;
03311 partitionEntry[partitionEntryCount].StartingCylinder = 0;
03312 partitionEntry[partitionEntryCount].EndingCylinder = 0;
03313 }
03314
03315 }
03316
03317
if (IsContainerPartition(partitionType)) {
03318
03319
03320
03321
03322
03323 nextRecordOffset =
03324 partitionTable->PartitionEntry[partitionEntryCount].StartingOffset;
03325 }
03326
03327 }
03328
03329 }
else {
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
if(writeBuffer[
BOOT_SIGNATURE_OFFSET] ==
BOOT_RECORD_SIGNATURE) {
03340
03341 }
03342 }
03343
03344
if (rewritePartition ==
TRUE) {
03345
03346 rewritePartition =
FALSE;
03347
03348
03349
03350
03351
03352
03353
KeInitializeEvent( &event, NotificationEvent,
FALSE );
03354
03355
if (foundEZHooker && (partitionTableOffset.QuadPart == 0)) {
03356
03357 partitionTableOffset.QuadPart = 512;
03358
03359 }
03360 irp =
IoBuildSynchronousFsdRequest(
IRP_MJ_WRITE,
03361 DeviceObject,
03362 writeBuffer,
03363 writeSize,
03364 &partitionTableOffset,
03365 &event,
03366 &ioStatus );
03367
03368
if (!irp) {
03369 status = STATUS_INSUFFICIENT_RESOURCES;
03370
break;
03371 }
else {
03372
PIO_STACK_LOCATION irpStack;
03373 irpStack =
IoGetNextIrpStackLocation(irp);
03374 irpStack->
Flags |=
SL_OVERRIDE_VERIFY_VOLUME;
03375 }
03376
03377 status =
IoCallDriver( DeviceObject, irp );
03378
03379
if (status == STATUS_PENDING) {
03380 (
VOID)
KeWaitForSingleObject( &event,
03381
Executive,
03382
KernelMode,
03383
FALSE,
03384 (PLARGE_INTEGER)
NULL);
03385 status = ioStatus.Status;
03386 }
03387
03388
if (!
NT_SUCCESS( status )) {
03389
break;
03390 }
03391
03392
03393
if (foundEZHooker && (partitionTableOffset.QuadPart == 512)) {
03394
03395 partitionTableOffset.QuadPart = 0;
03396
03397 }
03398
03399 }
03400
03401
03402
03403
03404
03405 partitionTableOffset = nextRecordOffset;
03406
if(mbr) {
03407 extendedPartitionOffset = nextRecordOffset;
03408 }
03409
03410 }
03411
03412
03413
03414
03415
03416
if (writeBuffer !=
NULL) {
03417
ExFreePool( writeBuffer );
03418 }
03419
03420
return status;
03421 }
03422
03423
03424 BOOLEAN
03425 HalpIsValidPartitionEntry(
03426
PPARTITION_DESCRIPTOR Entry,
03427 ULONGLONG MaxOffset,
03428 ULONGLONG MaxSector
03429 )
03430 {
03431 ULONGLONG endingSector;
03432
03433
PAGED_CODE();
03434
03435
if(Entry->
PartitionType == PARTITION_ENTRY_UNUSED) {
03436
03437
03438
03439
03440
03441
return TRUE;
03442
03443 }
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453 endingSector =
GET_STARTING_SECTOR(Entry) +
03454
GET_PARTITION_LENGTH(Entry);
03455
03456
if(endingSector > MaxSector) {
03457
03458
DebugPrint((1,
"HalpIsValidPartitionEntry: entry is invalid\n"));
03459
DebugPrint((1,
"\tHalpIsValidPartitionEntry: offset %#08lx\n",
03460
GET_STARTING_SECTOR(Entry)));
03461
DebugPrint((1,
"\tHalpIsValidPartitionEntry: length %#08lx\n",
03462
GET_PARTITION_LENGTH(Entry)));
03463
DebugPrint((1,
"\tHalpIsValidPartitionEntry: end %#I64x\n", endingSector));
03464
DebugPrint((1,
"\tHalpIsValidPartitionEntry: max %#I64x\n", MaxSector));
03465
03466
return FALSE;
03467 }
else if(
GET_STARTING_SECTOR(Entry) > MaxOffset) {
03468
03469
DebugPrint((1,
"HalpIsValidPartitionEntry: entry is invalid\n"));
03470
DebugPrint((1,
"\tHalpIsValidPartitionEntry: offset %#08lx\n",
03471
GET_STARTING_SECTOR(Entry)));
03472
DebugPrint((1,
"\tHalpIsValidPartitionEntry: length %#08lx\n",
03473
GET_PARTITION_LENGTH(Entry)));
03474
DebugPrint((1,
"\tHalpIsValidPartitionEntry: end %#I64x\n", endingSector));
03475
DebugPrint((1,
"\tHalpIsValidPartitionEntry: maxOffset %#I64x\n", MaxOffset));
03476
03477
return FALSE;
03478 }
03479
03480
return TRUE;
03481 }
03482
03483
03484
NTSTATUS
03485
FASTCALL
03486 xHalIoClearPartitionTable(
03487 IN
PDEVICE_OBJECT DeviceObject,
03488 IN ULONG SectorSize,
03489 IN ULONG SectorsPerTrack,
03490 IN ULONG NumberOfHeads
03491 )
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
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 }
03730
03731
03732
03733
03734
NTSTATUS
03735 HalpGetFullGeometry(
03736 IN
PDEVICE_OBJECT DeviceObject,
03737 IN PDISK_GEOMETRY Geometry,
03738 OUT PULONGLONG RealSectorCount
03739 )
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764 {
03765
PIRP localIrp;
03766 IO_STATUS_BLOCK iosb;
03767
PKEVENT eventPtr;
03768
NTSTATUS status;
03769
03770
PAGED_CODE();
03771
03772 eventPtr =
ExAllocatePoolWithTag(
03773
NonPagedPool,
03774
sizeof(
KEVENT),
03775 'btsF'
03776 );
03777
03778
if (!eventPtr) {
03779
return STATUS_INSUFFICIENT_RESOURCES;
03780 }
03781
03782
KeInitializeEvent(
03783 eventPtr,
03784 NotificationEvent,
03785
FALSE
03786 );
03787
03788 localIrp =
IoBuildDeviceIoControlRequest(
03789 IOCTL_DISK_GET_DRIVE_GEOMETRY,
03790 DeviceObject,
03791
NULL,
03792 0UL,
03793 Geometry,
03794
sizeof(DISK_GEOMETRY),
03795
FALSE,
03796 eventPtr,
03797 &iosb
03798 );
03799
03800
if (!localIrp) {
03801
ExFreePool(eventPtr);
03802
return STATUS_INSUFFICIENT_RESOURCES;
03803 }
03804
03805
03806
03807
03808
03809
03810
03811 status =
IoCallDriver(
03812 DeviceObject,
03813 localIrp
03814 );
03815
03816
if (status == STATUS_PENDING) {
03817 (
VOID)
KeWaitForSingleObject(
03818 eventPtr,
03819
Executive,
03820
KernelMode,
03821
FALSE,
03822 (PLARGE_INTEGER)
NULL
03823 );
03824 status = iosb.Status;
03825 }
03826
03827
if(
NT_SUCCESS(status)) {
03828
03829 PARTITION_INFORMATION partitionInfo;
03830
03831 localIrp =
IoBuildDeviceIoControlRequest(
03832 IOCTL_DISK_GET_PARTITION_INFO,
03833 DeviceObject,
03834
NULL,
03835 0UL,
03836 &partitionInfo,
03837
sizeof(PARTITION_INFORMATION),
03838
FALSE,
03839 eventPtr,
03840 &iosb
03841 );
03842
03843
if (!localIrp) {
03844
ExFreePool(eventPtr);
03845
return STATUS_INSUFFICIENT_RESOURCES;
03846 }
03847
03848
03849
03850
03851
03852
03853
03854 status =
IoCallDriver(
03855 DeviceObject,
03856 localIrp
03857 );
03858
03859
if (status == STATUS_PENDING) {
03860 (
VOID)
KeWaitForSingleObject(
03861 eventPtr,
03862
Executive,
03863
KernelMode,
03864
FALSE,
03865 (PLARGE_INTEGER)
NULL
03866 );
03867 status = iosb.Status;
03868 }
03869
03870
if(
NT_SUCCESS(status)) {
03871 *RealSectorCount = (partitionInfo.PartitionLength.QuadPart /
03872 Geometry->BytesPerSector);
03873 }
03874 }
03875
03876
ExFreePool(eventPtr);
03877
return status;
03878 }
03879
03880
03881
VOID
03882 DrivesupDebugPrint(
03883 ULONG DebugPrintLevel,
03884 PCCHAR DebugMessage,
03885 ...
03886 )
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903 {
03904 UCHAR DrivesupBuffer[256];
03905
03906 va_list ap;
03907
03908 va_start(ap,
DebugMessage);
03909
03910
03911
if (DebugPrintLevel <=
DrivesupDebug) {
03912
03913 _vsnprintf(DrivesupBuffer, 256,
DebugMessage, ap);
03914
03915
DbgPrint(DrivesupBuffer);
03916 }
03917
03918 va_end(ap);
03919
03920 }