00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "precomp.h"
00024
#pragma hdrstop
00025
00026 #define ARCDBG
00027
00028
00029
00030 ULONG
CountOfDisks;
00031 PCHAR *
DiskNames;
00032
00033
00034
00035 DISKGEOM *
DiskGeometryArray;
00036
00037 PPARTITION *
PrimaryPartitions,
00038 *
LogicalVolumes;
00039
00040
00041
00042
00043 PBOOLEAN
OffLine;
00044
00045
00046
00047
00048 BOOLEAN *
ChangesMade;
00049
00050
00051
00052
00053
00054
00055 #define CHANGED_DONT_ZAP ((BOOLEAN)(5))
00056
00057
00058
00059
00060
ARC_STATUS
00061
OpenDisks(
00062 VOID
00063 );
00064
00065
VOID
00066
CloseDisks(
00067 VOID
00068 );
00069
00070
ARC_STATUS
00071
GetGeometry(
00072 VOID
00073 );
00074
00075 BOOLEAN
00076
CheckIfDiskIsOffLine(
00077 IN ULONG Disk
00078 );
00079
00080
ARC_STATUS
00081
InitializePartitionLists(
00082 VOID
00083 );
00084
00085
ARC_STATUS
00086
GetRegions(
00087 IN ULONG Disk,
00088 IN
PPARTITION p,
00089 IN BOOLEAN WantUsedRegions,
00090 IN BOOLEAN WantFreeRegions,
00091 IN BOOLEAN WantLogicalRegions,
00092 OUT
PREGION_DESCRIPTOR *Region,
00093 OUT ULONG *RegionCount,
00094 IN REGION_TYPE RegionType
00095 );
00096
00097 BOOLEAN
00098
AddRegionEntry(
00099 IN OUT
PREGION_DESCRIPTOR *Regions,
00100 IN OUT ULONG *RegionCount,
00101 IN ULONG SizeMB,
00102 IN REGION_TYPE RegionType,
00103 IN
PPARTITION Partition,
00104 IN LARGE_INTEGER AlignedRegionOffset,
00105 IN LARGE_INTEGER AlignedRegionSize
00106 );
00107
00108
VOID
00109
AddPartitionToLinkedList(
00110 IN
PARTITION **Head,
00111 IN
PARTITION *p
00112 );
00113
00114 BOOLEAN
00115
IsInLinkedList(
00116 IN
PPARTITION p,
00117 IN
PPARTITION List
00118 );
00119
00120 BOOLEAN
00121
IsInLogicalList(
00122 IN ULONG Disk,
00123 IN
PPARTITION p
00124 );
00125
00126 BOOLEAN
00127
IsInPartitionList(
00128 IN ULONG Disk,
00129 IN
PPARTITION p
00130 );
00131
00132 LARGE_INTEGER
00133
AlignTowardsDiskStart(
00134 IN ULONG Disk,
00135 IN LARGE_INTEGER Offset
00136 );
00137
00138 LARGE_INTEGER
00139
AlignTowardsDiskEnd(
00140 IN ULONG Disk,
00141 IN LARGE_INTEGER Offset
00142 );
00143
00144
VOID
00145
FreeLinkedPartitionList(
00146 IN
PARTITION **q
00147 );
00148
00149
VOID
00150
MergeFreePartitions(
00151 IN
PPARTITION p
00152 );
00153
00154
VOID
00155
RenumberPartitions(
00156 ULONG Disk
00157 );
00158
00159
VOID
00160
FreePartitionInfoLinkedLists(
00161 IN
PARTITION **ListHeadArray
00162 );
00163
00164 LARGE_INTEGER
00165
DiskLengthBytes(
00166 IN ULONG Disk
00167 );
00168
00169
PPARTITION
00170
AllocatePartitionStructure(
00171 IN ULONG Disk,
00172 IN LARGE_INTEGER Offset,
00173 IN LARGE_INTEGER Length,
00174 IN UCHAR SysID,
00175 IN BOOLEAN Update,
00176 IN BOOLEAN Active,
00177 IN BOOLEAN Recognized
00178 );
00179
00180
00181
00182
ARC_STATUS
00183 FdiskInitialize(
00184 VOID
00185 )
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 {
00206
ARC_STATUS status;
00207 ULONG i;
00208
00209
00210
if((status =
LowQueryFdiskPathList(&
DiskNames,&
CountOfDisks)) !=
OK_STATUS) {
00211
return(status);
00212 }
00213
00214
#if 0
00215
#ifdef ARCDBG
00216
AlPrint(
"Disk count = %u\r\n",
CountOfDisks);
00217
for(i=0; i<
CountOfDisks; i++) {
00218
AlPrint(
"Disk %u: %s\r\n",i,
DiskNames[i]);
00219 }
00220 WaitKey();
00221
#endif
00222
#endif
00223
00224
DiskGeometryArray =
NULL;
00225
PrimaryPartitions =
NULL;
00226
LogicalVolumes =
NULL;
00227
00228
if(((
DiskGeometryArray =
AllocateMemory(
CountOfDisks *
sizeof(
DISKGEOM ))) ==
NULL)
00229 || ((
ChangesMade =
AllocateMemory(
CountOfDisks *
sizeof(BOOLEAN ))) ==
NULL)
00230 || ((
PrimaryPartitions =
AllocateMemory(
CountOfDisks *
sizeof(
PPARTITION))) ==
NULL)
00231 || ((
OffLine =
AllocateMemory(
CountOfDisks *
sizeof(BOOLEAN ))) ==
NULL)
00232 || ((
LogicalVolumes =
AllocateMemory(
CountOfDisks *
sizeof(
PPARTITION))) ==
NULL))
00233 {
00234
RETURN_OUT_OF_MEMORY;
00235 }
00236
00237
for(i=0; i<
CountOfDisks; i++) {
00238
PrimaryPartitions[i] =
NULL;
00239
LogicalVolumes[i] =
NULL;
00240
ChangesMade[i] =
FALSE;
00241
OffLine[i] =
CheckIfDiskIsOffLine(i);
00242
if(
OffLine[i]) {
00243
return(
ENODEV);
00244 }
00245 }
00246
00247
if(((status =
GetGeometry() ) !=
OK_STATUS)
00248 || ((status =
InitializePartitionLists()) !=
OK_STATUS))
00249 {
00250
return(status);
00251 }
00252
00253
return(
OK_STATUS);
00254 }
00255
00256
00257
VOID
00258 FdiskCleanUp(
00259 VOID
00260 )
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 {
00279
LowFreeFdiskPathList(
DiskNames,
CountOfDisks);
00280
00281
if(
DiskGeometryArray !=
NULL) {
00282
FreeMemory(
DiskGeometryArray);
00283 }
00284
if(
PrimaryPartitions !=
NULL) {
00285
FreePartitionInfoLinkedLists(
PrimaryPartitions);
00286
FreeMemory(
PrimaryPartitions);
00287 }
00288
if(
LogicalVolumes !=
NULL) {
00289
FreePartitionInfoLinkedLists(
LogicalVolumes);
00290
FreeMemory(
LogicalVolumes);
00291 }
00292
if(
ChangesMade !=
NULL) {
00293
FreeMemory(
ChangesMade);
00294 }
00295
if(
OffLine !=
NULL) {
00296
FreeMemory(
OffLine);
00297 }
00298 }
00299
00300
00301 BOOLEAN
00302 CheckIfDiskIsOffLine(
00303 IN ULONG Disk
00304 )
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 {
00324 ULONG
Handle;
00325 BOOLEAN IsOffLine;
00326
00327
if(
LowOpenDisk(
GetDiskName(Disk),&
Handle) ==
OK_STATUS) {
00328
00329 IsOffLine =
FALSE;
00330
LowCloseDisk(
Handle);
00331
00332 }
else {
00333
00334 IsOffLine =
TRUE;
00335 }
00336
00337
return(IsOffLine);
00338 }
00339
00340
00341
ARC_STATUS
00342 GetGeometry(
00343 VOID
00344 )
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 {
00371 ULONG i;
00372
ARC_STATUS status;
00373 ULONG TotalSectorCount,
00374
SectorSize,
00375 SectorsPerTrack,
00376 Heads;
00377
00378
for(i=0; i<
CountOfDisks; i++) {
00379
00380
if(
OffLine[i]) {
00381
continue;
00382 }
00383
00384
if((status =
LowGetDriveGeometry(
DiskNames[i],&TotalSectorCount,&
SectorSize,&SectorsPerTrack,&Heads)) !=
OK_STATUS) {
00385
return(status);
00386 }
00387
00388
DiskGeometryArray[i].
BytesPerSector =
SectorSize;
00389
DiskGeometryArray[i].
SectorsPerTrack = SectorsPerTrack;
00390
DiskGeometryArray[i].
Heads = Heads;
00391
DiskGeometryArray[i].
Cylinders.QuadPart = TotalSectorCount / (SectorsPerTrack * Heads);
00392
DiskGeometryArray[i].
BytesPerTrack = SectorsPerTrack *
SectorSize;
00393
DiskGeometryArray[i].
BytesPerCylinder = SectorsPerTrack *
SectorSize * Heads;
00394 }
00395
return(
OK_STATUS);
00396 }
00397
00398
00399
#if i386
00400
VOID
00401
SetPartitionActiveFlag(
00402 IN
PREGION_DESCRIPTOR Region,
00403 IN UCHAR value
00404 )
00405 {
00406
PPARTITION p = ((
PREGION_DATA)Region->Reserved)->Partition;
00407
00408
if((UCHAR)p->
Active != value) {
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 p->
Active = value;
00419
if(!p->
Update) {
00420 p->
Update =
CHANGED_DONT_ZAP;
00421 }
00422
ChangesMade[p->
Disk] =
TRUE;
00423 }
00424 }
00425
#endif
00426
00427
00428
VOID
00429 DetermineCreateSizeAndOffset(
00430 IN
PREGION_DESCRIPTOR Region,
00431 IN LARGE_INTEGER MinimumSize,
00432 IN ULONG CreationSizeMB,
00433 IN REGION_TYPE Type,
00434 OUT PLARGE_INTEGER CreationStart,
00435 OUT PLARGE_INTEGER CreationSize
00436 )
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 {
00470
PREGION_DATA CreateData = Region->Reserved;
00471 LARGE_INTEGER CSize,CStart;
00472 LARGE_INTEGER Mod;
00473 ULONG bpc =
DiskGeometryArray[Region->Disk].
BytesPerCylinder;
00474 ULONG bpt =
DiskGeometryArray[Region->Disk].
BytesPerTrack;
00475
00476
ASRT(Region->SysID ==
SYSID_UNUSED);
00477
00478
00479
00480
00481
00482
00483
00484
if(CreateData->
AlignedRegionOffset.QuadPart == 0) {
00485
00486 LARGE_INTEGER Delta;
00487
00488
if(Type ==
REGION_EXTENDED) {
00489
00490 Delta.QuadPart = bpc;
00491
00492 }
else {
00493
00494
ASRT(Type ==
REGION_PRIMARY);
00495 Delta.QuadPart = bpt;
00496 }
00497
00498 CreateData->
AlignedRegionOffset = Delta;
00499 CreateData->
AlignedRegionSize.QuadPart = (CreateData->
AlignedRegionSize.QuadPart - Delta.QuadPart);
00500 }
00501
00502 CStart = CreateData->
AlignedRegionOffset;
00503
if(MinimumSize.QuadPart == 0) {
00504 CSize.QuadPart = UInt32x32To64(CreationSizeMB,
ONE_MEG);
00505 }
else {
00506 CSize = MinimumSize;
00507
if(Type ==
REGION_LOGICAL) {
00508 CSize.QuadPart = CSize.QuadPart + bpt;
00509 }
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519 Mod.QuadPart = (CStart.QuadPart + CSize.QuadPart) % bpc;
00520
00521
if(Mod.QuadPart != 0) {
00522
00523
if((MinimumSize.QuadPart != 0) || (Mod.QuadPart > bpc/2)) {
00524 CSize.QuadPart = (CSize.QuadPart + (bpc - Mod.QuadPart));
00525 }
else {
00526 CSize.QuadPart = (CSize.QuadPart - Mod.QuadPart);
00527 }
00528 }
00529
00530
if(CSize.QuadPart > CreateData->
AlignedRegionSize.QuadPart) {
00531
00532
00533
00534
00535
00536
00537 CSize = CreateData->
AlignedRegionSize;
00538 }
00539
00540
ASRT(CStart.QuadPart != 0);
00541
ASRT(CSize.QuadPart != 0);
00542
00543 *CreationStart = CStart;
00544 *CreationSize = CSize;
00545 }
00546
00547
00548
ARC_STATUS
00549 CreatePartitionEx(
00550 IN
PREGION_DESCRIPTOR Region,
00551 IN LARGE_INTEGER MinimumSize,
00552 IN ULONG CreationSizeMB,
00553 IN REGION_TYPE Type,
00554 IN UCHAR SysId
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
PPARTITION p1,p2,p3;
00586
PREGION_DATA CreateData = Region->Reserved;
00587 LARGE_INTEGER CreationStart,CreationSize,LeftOver;
00588
PPARTITION *PartitionList;
00589
00590
ASRT(Region->SysID ==
SYSID_UNUSED);
00591
00592
DetermineCreateSizeAndOffset( Region,
00593 MinimumSize,
00594 CreationSizeMB,
00595 Type,
00596 &CreationStart,
00597 &CreationSize
00598 );
00599
00600
00601
00602
00603
00604
00605 p1 =
NULL;
00606 LeftOver.QuadPart = (CreationStart.QuadPart - CreateData->
Partition->
Offset.QuadPart);
00607
00608
if(LeftOver.QuadPart > 0) {
00609
00610 p1 =
AllocatePartitionStructure(Region->Disk,
00611 CreateData->
Partition->
Offset,
00612 LeftOver,
00613
SYSID_UNUSED,
00614
FALSE,
00615
FALSE,
00616
FALSE
00617 );
00618
if(p1 ==
NULL) {
00619
RETURN_OUT_OF_MEMORY;
00620 }
00621 }
00622
00623
00624
00625
00626 p2 =
NULL;
00627 LeftOver.QuadPart = (CreateData->
Partition->
Offset.QuadPart + CreateData->
Partition->
Length.QuadPart) -
00628 (CreationStart.QuadPart + CreationSize.QuadPart);
00629
00630
if(LeftOver.QuadPart != 0) {
00631
00632 LARGE_INTEGER TmpResult;
00633
00634 TmpResult.QuadPart = CreationStart.QuadPart + CreationSize.QuadPart;
00635 p2 =
AllocatePartitionStructure(Region->Disk,
00636 TmpResult,
00637 LeftOver,
00638
SYSID_UNUSED,
00639
FALSE,
00640
FALSE,
00641
FALSE
00642 );
00643
if(p2 ==
NULL) {
00644
RETURN_OUT_OF_MEMORY;
00645 }
00646 }
00647
00648
00649
00650 CreateData->
Partition->
Offset = CreationStart;
00651 CreateData->
Partition->
Length = CreationSize;
00652 CreateData->
Partition->
SysID = SysId;
00653 CreateData->
Partition->
Update =
TRUE;
00654 CreateData->
Partition->
Recognized =
TRUE;
00655
00656
00657
00658
00659
if(Type ==
REGION_EXTENDED) {
00660
00661
ASRT(
LogicalVolumes[Region->
Disk] ==
NULL);
00662
00663 p3 =
AllocatePartitionStructure(Region->Disk,
00664 CreationStart,
00665 CreationSize,
00666
SYSID_UNUSED,
00667
FALSE,
00668
FALSE,
00669
FALSE
00670 );
00671
if(p3 ==
NULL) {
00672
RETURN_OUT_OF_MEMORY;
00673 }
00674
AddPartitionToLinkedList(&
LogicalVolumes[Region->
Disk],p3);
00675 }
00676
00677 PartitionList = (Type ==
REGION_LOGICAL)
00678 ? &
LogicalVolumes[Region->Disk]
00679 : &
PrimaryPartitions[Region->Disk];
00680
00681
if(p1) {
00682
AddPartitionToLinkedList(PartitionList,p1);
00683 }
00684
if(p2) {
00685
AddPartitionToLinkedList(PartitionList,p2);
00686 }
00687
00688
MergeFreePartitions(*PartitionList);
00689
RenumberPartitions(Region->Disk);
00690
00691
ChangesMade[Region->Disk] =
TRUE;
00692
00693
return(
OK_STATUS);
00694 }
00695
00696
00697
ARC_STATUS
00698 CreatePartition(
00699 IN
PREGION_DESCRIPTOR Region,
00700 IN ULONG CreationSizeMB,
00701 IN REGION_TYPE Type
00702 )
00703 {
00704 LARGE_INTEGER LargeZero;
00705
00706 LargeZero.QuadPart = 0;
00707
return(
CreatePartitionEx(Region,
00708 LargeZero,
00709 CreationSizeMB,
00710 Type,
00711 (UCHAR)((Type ==
REGION_EXTENDED) ?
SYSID_EXTENDED
00712 :
SYSID_BIGFAT
00713 )
00714 )
00715 );
00716 }
00717
00718
00719
00720
ARC_STATUS
00721 DeletePartition(
00722 IN
PREGION_DESCRIPTOR Region
00723 )
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 {
00745
PREGION_DATA RegionData = Region->Reserved;
00746
PPARTITION *PartitionList;
00747
00748
ASRT(
IsInPartitionList(Region->Disk,RegionData->
Partition)
00749 ||
IsInLogicalList (Region->Disk,RegionData->
Partition)
00750 );
00751
00752
if(
IsExtended(Region->SysID)) {
00753
00754
ASRT(
IsInPartitionList(Region->Disk,RegionData->
Partition));
00755
00756
00757
00758
FreeLinkedPartitionList(&
LogicalVolumes[Region->
Disk]);
00759 }
00760
00761 RegionData->
Partition->
SysID =
SYSID_UNUSED;
00762 RegionData->
Partition->
Update =
TRUE;
00763 RegionData->
Partition->
Active =
FALSE;
00764 RegionData->
Partition->
OriginalPartitionNumber = 0;
00765
00766 PartitionList = (Region->RegionType ==
REGION_LOGICAL)
00767 ? &
LogicalVolumes[Region->Disk]
00768 : &
PrimaryPartitions[Region->Disk];
00769
00770
MergeFreePartitions(*PartitionList);
00771
RenumberPartitions(Region->Disk);
00772
00773
ChangesMade[Region->Disk] =
TRUE;
00774
00775
return(
OK_STATUS);
00776 }
00777
00778
00779
ARC_STATUS
00780 GetDiskRegions(
00781 IN ULONG Disk,
00782 IN BOOLEAN WantUsedRegions,
00783 IN BOOLEAN WantFreeRegions,
00784 IN BOOLEAN WantPrimaryRegions,
00785 IN BOOLEAN WantLogicalRegions,
00786 OUT
PREGION_DESCRIPTOR *Region,
00787 OUT ULONG *RegionCount
00788 )
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825 {
00826 *Region =
AllocateMemory(0);
00827 *RegionCount = 0;
00828
00829
if(WantPrimaryRegions) {
00830
return(
GetRegions(Disk,
00831
PrimaryPartitions[Disk],
00832 WantUsedRegions,
00833 WantFreeRegions,
00834 WantLogicalRegions,
00835 Region,
00836 RegionCount,
00837
REGION_PRIMARY
00838 )
00839 );
00840 }
else if(WantLogicalRegions) {
00841
return(
GetRegions(Disk,
00842
LogicalVolumes[Disk],
00843 WantUsedRegions,
00844 WantFreeRegions,
00845
FALSE,
00846 Region,
00847 RegionCount,
00848
REGION_LOGICAL
00849 )
00850 );
00851 }
00852
return(
OK_STATUS);
00853 }
00854
00855
00856
00857
00858
ARC_STATUS
00859 GetRegions(
00860 IN ULONG Disk,
00861 IN
PPARTITION p,
00862 IN BOOLEAN WantUsedRegions,
00863 IN BOOLEAN WantFreeRegions,
00864 IN BOOLEAN WantLogicalRegions,
00865 OUT
PREGION_DESCRIPTOR *Region,
00866 OUT ULONG *RegionCount,
00867 IN REGION_TYPE RegionType
00868 )
00869 {
00870
ARC_STATUS status;
00871 LARGE_INTEGER AlignedOffset,AlignedSize;
00872 ULONG SizeMB;
00873
00874
while(p) {
00875
00876
if(p->SysID ==
SYSID_UNUSED) {
00877
00878
if(WantFreeRegions) {
00879
00880 LARGE_INTEGER Result1, Result2;
00881
00882 AlignedOffset =
AlignTowardsDiskEnd(p->Disk,p->Offset);
00883
00884 Result2.QuadPart = p->Offset.QuadPart + p->Length.QuadPart;
00885 Result1 =
AlignTowardsDiskStart(p->Disk,Result2);
00886 AlignedSize.QuadPart = Result1.QuadPart - AlignedOffset.QuadPart;
00887
00888 SizeMB =
SIZEMB(AlignedSize);
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
if( (AlignedSize.QuadPart > 0)
00902 && SizeMB
00903 && ( (p->Offset.QuadPart != 0)
00904 || ( p->Length.QuadPart >
00905
DiskGeometryArray[p->Disk].
BytesPerCylinder )
00906 )
00907 )
00908 {
00909
if(!
AddRegionEntry(Region,
00910 RegionCount,
00911 SizeMB,
00912 RegionType,
00913 p,
00914 AlignedOffset,
00915 AlignedSize
00916 ))
00917 {
00918
RETURN_OUT_OF_MEMORY;
00919 }
00920 }
00921 }
00922 }
else {
00923
00924
if(WantUsedRegions) {
00925
00926 AlignedOffset = p->Offset;
00927 AlignedSize = p->Length;
00928 SizeMB =
SIZEMB(AlignedSize);
00929
00930
if(!
AddRegionEntry(Region,
00931 RegionCount,
00932 SizeMB,
00933 RegionType,
00934 p,
00935 AlignedOffset,
00936 AlignedSize
00937 ))
00938 {
00939
RETURN_OUT_OF_MEMORY;
00940 }
00941 }
00942
00943
if(
IsExtended(p->SysID) && WantLogicalRegions) {
00944 status =
GetRegions(Disk,
00945
LogicalVolumes[Disk],
00946 WantUsedRegions,
00947 WantFreeRegions,
00948
FALSE,
00949 Region,
00950 RegionCount,
00951
REGION_LOGICAL
00952 );
00953
if(status !=
OK_STATUS) {
00954
return(status);
00955 }
00956 }
00957 }
00958 p = p->Next;
00959 }
00960
return(
OK_STATUS);
00961 }
00962
00963
00964 BOOLEAN
00965 AddRegionEntry(
00966 OUT
PREGION_DESCRIPTOR *Regions,
00967 OUT ULONG *RegionCount,
00968 IN ULONG SizeMB,
00969 IN REGION_TYPE RegionType,
00970 IN
PPARTITION Partition,
00971 IN LARGE_INTEGER AlignedRegionOffset,
00972 IN LARGE_INTEGER AlignedRegionSize
00973 )
00974 {
00975
PREGION_DESCRIPTOR p;
00976
PREGION_DATA data;
00977
00978 p =
ReallocateMemory(*Regions,((*RegionCount) + 1) *
sizeof(
REGION_DESCRIPTOR));
00979
if(p ==
NULL) {
00980
return(
FALSE);
00981 }
else {
00982 *Regions = p;
00983 (*RegionCount)++;
00984 }
00985
00986 p = &(*Regions)[(*RegionCount)-1];
00987
00988
if(!(p->
Reserved =
AllocateMemory(
sizeof(
REGION_DATA)))) {
00989
return(
FALSE);
00990 }
00991
00992 p->
Disk = Partition->Disk;
00993 p->
SysID = Partition->SysID;
00994 p->
SizeMB = SizeMB;
00995 p->
Active = Partition->Active;
00996 p->
Recognized = Partition->Recognized;
00997 p->
PartitionNumber = Partition->PartitionNumber;
00998 p->
OriginalPartitionNumber = Partition->OriginalPartitionNumber;
00999 p->
RegionType = RegionType;
01000 p->
PersistentData = Partition->PersistentData;
01001
01002 data = p->
Reserved;
01003
01004 data->
Partition = Partition;
01005 data->
AlignedRegionOffset = AlignedRegionOffset;
01006 data->
AlignedRegionSize = AlignedRegionSize;
01007
01008
return(
TRUE);
01009 }
01010
01011
01012
VOID
01013 FreeRegionArray(
01014 IN
PREGION_DESCRIPTOR Region,
01015 IN ULONG RegionCount
01016 )
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 {
01037 ULONG i;
01038
01039
for(i=0; i<RegionCount; i++) {
01040
01041
if(Region[i].Reserved) {
01042
FreeMemory(Region[i].Reserved);
01043 }
01044 }
01045
FreeMemory(Region);
01046 }
01047
01048
01049
01050
VOID
01051 AddPartitionToLinkedList(
01052 IN OUT
PARTITION **Head,
01053 IN
PARTITION *p
01054 )
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 {
01076
PARTITION *cur,*prev;
01077
01078
if((cur = *Head) ==
NULL) {
01079 *Head = p;
01080
return;
01081 }
01082
01083
if(p->Offset.QuadPart < cur->
Offset.QuadPart) {
01084 p->Next = cur;
01085 cur->
Prev = p;
01086 *Head = p;
01087
return;
01088 }
01089
01090 prev = *Head;
01091 cur = cur->
Next;
01092
01093
while(cur) {
01094
if(p->Offset.QuadPart < cur->
Offset.QuadPart) {
01095
01096 p->
Next = cur;
01097 p->
Prev = prev;
01098 prev->
Next = p;
01099 cur->
Prev = p;
01100
return;
01101 }
01102 prev = cur;
01103 cur = cur->
Next;
01104 }
01105
01106 prev->
Next = p;
01107 p->
Prev = prev;
01108
return;
01109 }
01110
01111
01112 BOOLEAN
01113 IsInLinkedList(
01114 IN
PPARTITION p,
01115 IN
PPARTITION List
01116 )
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137 {
01138
while(
List) {
01139
if(p ==
List) {
01140
return(
TRUE);
01141 }
01142
List =
List->Next;
01143 }
01144
return(
FALSE);
01145 }
01146
01147
01148 BOOLEAN
01149 IsInLogicalList(
01150 IN ULONG Disk,
01151 IN
PPARTITION p
01152 )
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 {
01174
return(
IsInLinkedList(p,
LogicalVolumes[Disk]));
01175 }
01176
01177
01178 BOOLEAN
01179 IsInPartitionList(
01180 IN ULONG Disk,
01181 IN
PPARTITION p
01182 )
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203 {
01204
return(
IsInLinkedList(p,
PrimaryPartitions[Disk]));
01205 }
01206
01207
01208
VOID
01209 MergeFreePartitions(
01210 IN
PPARTITION p
01211 )
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232 {
01233
PPARTITION next;
01234
01235
while(p && p->Next) {
01236
01237
if((p->SysID ==
SYSID_UNUSED) && (p->Next->SysID ==
SYSID_UNUSED)) {
01238
01239 next = p->
Next;
01240
01241 p->
Length.QuadPart = (next->
Offset.QuadPart + next->
Length.QuadPart) - p->Offset.QuadPart;
01242
01243
if(p->Next = next->
Next) {
01244 next->
Next->
Prev = p;
01245 }
01246
01247
FreeMemory(next);
01248
01249 }
else {
01250 p = p->Next;
01251 }
01252 }
01253 }
01254
01255
01256
VOID
01257 RenumberPartitions(
01258 IN ULONG Disk
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
PPARTITION p =
PrimaryPartitions[Disk];
01289 ULONG
n = 1;
01290
01291
while(p) {
01292
if(!
IsExtended(p->
SysID)) {
01293 p->
PartitionNumber =
n;
01294
if(p->
SysID !=
SYSID_UNUSED) {
01295
n++;
01296 }
01297 }
01298 p = p->
Next;
01299 }
01300 p =
LogicalVolumes[Disk];
01301
while(p) {
01302 p->
PartitionNumber =
n;
01303
if(p->
SysID !=
SYSID_UNUSED) {
01304
n++;
01305 }
01306 p = p->
Next;
01307 }
01308 }
01309
01310
01311
PPARTITION
01312 FindPartitionElement(
01313 IN ULONG Disk,
01314 IN ULONG Partition
01315 )
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 {
01338
PPARTITION p;
01339
01340
ASRT(Partition);
01341
01342 p =
PrimaryPartitions[Disk];
01343
while(p) {
01344
if((p->
SysID !=
SYSID_UNUSED)
01345 && !
IsExtended(p->
SysID)
01346 && (p->
PartitionNumber == Partition))
01347 {
01348
return(p);
01349 }
01350 p = p->
Next;
01351 }
01352 p =
LogicalVolumes[Disk];
01353
while(p) {
01354
if((p->
SysID !=
SYSID_UNUSED)
01355 && (p->
PartitionNumber == Partition))
01356 {
01357
return(p);
01358 }
01359 p = p->
Next;
01360 }
01361
return(
NULL);
01362 }
01363
01364
01365
VOID
01366 SetSysID(
01367 IN ULONG Disk,
01368 IN ULONG Partition,
01369 IN UCHAR SysID
01370 )
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393 {
01394
PPARTITION p =
FindPartitionElement(Disk,Partition);
01395
01396
ASRT(p);
01397
01398
if(p) {
01399 p->
SysID = SysID;
01400
if(!p->
Update) {
01401 p->
Update =
CHANGED_DONT_ZAP;
01402 }
01403
ChangesMade[p->
Disk] =
TRUE;
01404 }
01405 }
01406
01407
01408
VOID
01409 SetSysID2(
01410 IN
PREGION_DESCRIPTOR Region,
01411 IN UCHAR SysID
01412 )
01413 {
01414
PPARTITION p = ((
PREGION_DATA)(Region->Reserved))->Partition;
01415
01416 p->
SysID = SysID;
01417
if(!p->
Update) {
01418 p->
Update =
CHANGED_DONT_ZAP;
01419 }
01420
ChangesMade[p->
Disk] =
TRUE;
01421 }
01422
01423
01424 ULONG
01425 GetHiddenSectorCount(
01426 IN ULONG Disk,
01427 IN ULONG Partition
01428 )
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451 {
01452
PPARTITION p =
FindPartitionElement(Disk,Partition);
01453 ULONG HiddenSectorCount = 0;
01454 LARGE_INTEGER Result;
01455
01456
ASRT(p);
01457
01458
if(p) {
01459
01460
if(
IsInLogicalList(Disk,p)) {
01461 HiddenSectorCount =
DiskGeometryArray[Disk].
SectorsPerTrack;
01462 }
else {
01463
ASRT(
IsInPartitionList(Disk,p));
01464 Result.QuadPart = p->
Offset.QuadPart /
DiskGeometryArray[Disk].
BytesPerSector;
01465 HiddenSectorCount =
LOWPART(Result);
01466 }
01467 }
01468
return(HiddenSectorCount);
01469 }
01470
01471
01472
VOID
01473 FreeLinkedPartitionList(
01474 IN OUT
PPARTITION *q
01475 )
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 {
01495
PARTITION *
n;
01496
PARTITION *p = *q;
01497
01498
while(p) {
01499
n = p->
Next;
01500
FreeMemory(p);
01501 p =
n;
01502 }
01503 *q =
NULL;
01504 }
01505
01506
01507
VOID
01508 FreePartitionInfoLinkedLists(
01509 IN
PPARTITION *ListHeadArray
01510 )
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530 {
01531 ULONG i;
01532
01533
for(i=0; i<
CountOfDisks; i++) {
01534
01535
FreeLinkedPartitionList(&ListHeadArray[i]);
01536 }
01537 }
01538
01539
01540
PPARTITION
01541 AllocatePartitionStructure(
01542 IN ULONG Disk,
01543 IN LARGE_INTEGER Offset,
01544 IN LARGE_INTEGER Length,
01545 IN UCHAR SysID,
01546 IN BOOLEAN Update,
01547 IN BOOLEAN Active,
01548 IN BOOLEAN Recognized
01549 )
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585 {
01586
PPARTITION p =
AllocateMemory(
sizeof(
PARTITION));
01587
01588
if(p) {
01589 p->
Next =
NULL;
01590 p->
Prev =
NULL;
01591 p->
Offset =
Offset;
01592 p->
Length = Length;
01593 p->
Disk = Disk;
01594 p->
Update = Update;
01595 p->
Active =
Active;
01596 p->
Recognized = Recognized;
01597 p->
SysID = SysID;
01598 p->
OriginalPartitionNumber = 0;
01599 p->
PartitionNumber = 0;
01600 p->
PersistentData = 0;
01601 }
01602
return(p);
01603 }
01604
01605
01606
ARC_STATUS
01607 InitializeFreeSpace(
01608 IN ULONG Disk,
01609 IN
PPARTITION *PartitionList,
01610 IN LARGE_INTEGER StartOffset,
01611 IN LARGE_INTEGER Length
01612 )
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647 {
01648
PPARTITION p = *PartitionList,q;
01649 LARGE_INTEGER
Start,
Size;
01650
01651
Start = StartOffset;
01652
01653
while(p) {
01654
01655
Size.QuadPart = p->
Offset.QuadPart -
Start.QuadPart;
01656
01657
if(
Size.QuadPart > 0) {
01658
01659
if(!(q =
AllocatePartitionStructure(Disk,
01660
Start,
01661
Size,
01662
SYSID_UNUSED,
01663
FALSE,
01664
FALSE,
01665
FALSE
01666 )
01667 )
01668 )
01669 {
01670
RETURN_OUT_OF_MEMORY;
01671 }
01672
01673
AddPartitionToLinkedList(PartitionList,q);
01674 }
01675
01676
Start.QuadPart = p->
Offset.QuadPart + p->
Length.QuadPart;
01677
01678 p = p->
Next;
01679
01680 }
01681
01682
Size.QuadPart = (StartOffset.QuadPart + Length.QuadPart) -
Start.QuadPart;
01683
01684
if(
Size.QuadPart > 0) {
01685
01686
if(!(q =
AllocatePartitionStructure(Disk,
01687
Start,
01688
Size,
01689
SYSID_UNUSED,
01690
FALSE,
01691
FALSE,
01692
FALSE
01693 )
01694 )
01695 )
01696 {
01697
RETURN_OUT_OF_MEMORY;
01698 }
01699
01700
AddPartitionToLinkedList(PartitionList,q);
01701 }
01702
01703
return(
OK_STATUS);
01704 }
01705
01706
01707
ARC_STATUS
01708 InitializeLogicalVolumeList(
01709 IN ULONG Disk,
01710 IN PDRIVE_LAYOUT_INFORMATION DriveLayout,
01711 IN ULONG PartitionNumber
01712 )
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737 {
01738
PPARTITION p,q;
01739 ULONG i,j;
01740 PPARTITION_INFORMATION d;
01741 LARGE_INTEGER HiddenBytes;
01742 ULONG BytesPerSector =
DiskGeometryArray[Disk].
BytesPerSector;
01743 LARGE_INTEGER Result1, Result2;
01744
01745
FreeLinkedPartitionList(&
LogicalVolumes[Disk]);
01746
01747 p =
PrimaryPartitions[Disk];
01748
while(p) {
01749
if(
IsExtended(p->
SysID)) {
01750
break;
01751 }
01752 p = p->
Next;
01753 }
01754
01755
if(p) {
01756
for(i=
ENTRIES_PER_BOOTSECTOR; i<DriveLayout->PartitionCount; i+=
ENTRIES_PER_BOOTSECTOR) {
01757
01758
for(j=i; j<i+
ENTRIES_PER_BOOTSECTOR; j++) {
01759
01760 d = &DriveLayout->PartitionEntry[j];
01761
01762
if((d->PartitionType !=
SYSID_UNUSED) && (d->PartitionType !=
SYSID_EXTENDED)) {
01763
01764 HiddenBytes.QuadPart = UInt32x32To64(d->HiddenSectors,BytesPerSector);
01765
01766 Result1.QuadPart = d->StartingOffset.QuadPart - HiddenBytes.QuadPart;
01767 Result2.QuadPart = d->PartitionLength.QuadPart + HiddenBytes.QuadPart;
01768
if(!(q =
AllocatePartitionStructure(Disk,
01769 Result1,
01770 Result2,
01771 d->PartitionType,
01772
FALSE,
01773 d->BootIndicator,
01774 d->RecognizedPartition
01775 )
01776 )
01777 )
01778 {
01779
RETURN_OUT_OF_MEMORY;
01780 }
01781
01782 q->
OriginalPartitionNumber = PartitionNumber++;
01783
AddPartitionToLinkedList(&
LogicalVolumes[Disk],q);
01784
01785
break;
01786 }
01787 }
01788 }
01789
return(
InitializeFreeSpace(Disk,
01790 &
LogicalVolumes[Disk],
01791 p->
Offset,
01792 p->
Length
01793 )
01794 );
01795 }
01796
return(
OK_STATUS);
01797 }
01798
01799
01800
ARC_STATUS
01801 InitializePrimaryPartitionList(
01802 IN ULONG Disk,
01803 IN PDRIVE_LAYOUT_INFORMATION DriveLayout,
01804 OUT PULONG NextPartitionNumber
01805 )
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 {
01832 ULONG i;
01833
PPARTITION p;
01834 PPARTITION_INFORMATION d;
01835 ULONG PartitionNumber = 1;
01836 LARGE_INTEGER LargeZero;
01837
01838
FreeLinkedPartitionList(&
PrimaryPartitions[Disk]);
01839
01840
if(DriveLayout->PartitionCount >=
ENTRIES_PER_BOOTSECTOR) {
01841
01842
for(i=0; i<
ENTRIES_PER_BOOTSECTOR; i++) {
01843
01844 d = &DriveLayout->PartitionEntry[i];
01845
01846
if(d->PartitionType !=
SYSID_UNUSED) {
01847
01848
if(!(p =
AllocatePartitionStructure(Disk,
01849 d->StartingOffset,
01850 d->PartitionLength,
01851 d->PartitionType,
01852
FALSE,
01853 d->BootIndicator,
01854 d->RecognizedPartition
01855 )
01856 )
01857 )
01858 {
01859
RETURN_OUT_OF_MEMORY;
01860 }
01861
01862 p->
OriginalPartitionNumber =
IsExtended(p->
SysID)
01863 ? 0
01864 : PartitionNumber++;
01865
01866
AddPartitionToLinkedList(&
PrimaryPartitions[Disk],p);
01867 }
01868 }
01869 }
01870 *NextPartitionNumber = PartitionNumber;
01871 LargeZero.QuadPart = 0;
01872
return(
InitializeFreeSpace(Disk,
01873 &
PrimaryPartitions[Disk],
01874 LargeZero,
01875
DiskLengthBytes(Disk)
01876 )
01877 );
01878 }
01879
01880
01881
ARC_STATUS
01882 InitializePartitionLists(
01883 VOID
01884 )
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905 {
01906
ARC_STATUS status;
01907 ULONG Disk;
01908 PDRIVE_LAYOUT_INFORMATION DriveLayout;
01909 ULONG PNum;
01910
01911
01912
for(Disk=0; Disk<
CountOfDisks; Disk++) {
01913
01914
if(
OffLine[Disk]) {
01915
continue;
01916 }
01917
01918
if((status =
LowGetDiskLayout(
DiskNames[Disk],&DriveLayout)) !=
OK_STATUS) {
01919
return(status);
01920 }
01921
01922
if((status =
InitializePrimaryPartitionList(Disk,DriveLayout,&PNum)) !=
OK_STATUS) {
01923
FreeMemory(DriveLayout);
01924
return(status);
01925 }
01926
if((status =
InitializeLogicalVolumeList(Disk,DriveLayout,PNum)) !=
OK_STATUS) {
01927
FreeMemory(DriveLayout);
01928
return(status);
01929 }
01930
01931
FreeMemory(DriveLayout);
01932
RenumberPartitions(Disk);
01933 }
01934
return(
OK_STATUS);
01935 }
01936
01937
01938
01939 LARGE_INTEGER
01940 DiskLengthBytes(
01941 IN ULONG Disk
01942 )
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 {
01962 LARGE_INTEGER l;
01963
01964 l.QuadPart = (ULONGLONG)
DiskGeometryArray[Disk].
Cylinders.QuadPart
01965 * (ULONGLONG)
DiskGeometryArray[Disk].
BytesPerCylinder;
01966
01967
return(l);
01968 }
01969
01970
01971 ULONG
01972 SIZEMB(
01973 IN LARGE_INTEGER ByteCount
01974 )
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996 {
01997 ULONG Remainder;
01998 ULONG SizeMB;
01999
02000 SizeMB = (ULONG)((ULONGLONG)ByteCount.QuadPart / (ULONGLONG)
ONE_MEG);
02001 Remainder = (ULONG)((ULONGLONG)ByteCount.QuadPart % (ULONGLONG)
ONE_MEG);
02002
02003
if(Remainder >=
ONE_MEG/2) {
02004 SizeMB++;
02005 }
02006
02007
return(SizeMB);
02008 }
02009
02010 ULONG
02011 DiskSizeMB(
02012 IN ULONG Disk
02013 )
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032 {
02033
return(
SIZEMB(
DiskLengthBytes(Disk)));
02034 }
02035
02036
02037 LARGE_INTEGER
02038 AlignTowardsDiskStart(
02039 IN ULONG Disk,
02040 IN LARGE_INTEGER Offset
02041 )
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062 {
02063 LARGE_INTEGER mod;
02064 LARGE_INTEGER Result;
02065
02066 mod.QuadPart =
Offset.QuadPart %
DiskGeometryArray[Disk].
BytesPerCylinder;
02067 Result.QuadPart =
Offset.QuadPart - mod.QuadPart;
02068
return(Result);
02069 }
02070
02071
02072 LARGE_INTEGER
02073 AlignTowardsDiskEnd(
02074 IN ULONG Disk,
02075 IN LARGE_INTEGER Offset
02076 )
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097 {
02098 LARGE_INTEGER mod;
02099 LARGE_INTEGER LargeInteger;
02100
02101 mod.QuadPart =
Offset.QuadPart %
DiskGeometryArray[Disk].
BytesPerCylinder;
02102
if(mod.QuadPart != 0) {
02103
02104 LargeInteger.QuadPart =
Offset.QuadPart +
DiskGeometryArray[Disk].
BytesPerCylinder;
02105
Offset =
AlignTowardsDiskStart(Disk,
02106 LargeInteger
02107 );
02108 }
02109
return(
Offset);
02110 }
02111
02112
02113 BOOLEAN
02114 IsExtended(
02115 IN UCHAR SysID
02116 )
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135 {
02136
return((BOOLEAN)(SysID ==
SYSID_EXTENDED));
02137 }
02138
02139
02140
ARC_STATUS
02141 IsAnyCreationAllowed(
02142 IN ULONG Disk,
02143 IN BOOLEAN AllowMultiplePrimaries,
02144 OUT PBOOLEAN AnyAllowed,
02145 OUT PBOOLEAN PrimaryAllowed,
02146 OUT PBOOLEAN ExtendedAllowed,
02147 OUT PBOOLEAN LogicalAllowed
02148 )
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180 {
02181
ARC_STATUS status;
02182
02183
if((status =
IsCreationOfPrimaryAllowed(Disk,AllowMultiplePrimaries,PrimaryAllowed)) !=
OK_STATUS) {
02184
return(status);
02185 }
02186
if((status =
IsCreationOfExtendedAllowed(Disk,ExtendedAllowed)) !=
OK_STATUS) {
02187
return(status);
02188 }
02189
if((status =
IsCreationOfLogicalAllowed(Disk,LogicalAllowed)) !=
OK_STATUS) {
02190
return(status);
02191 }
02192 *AnyAllowed = (BOOLEAN)(*PrimaryAllowed || *ExtendedAllowed || *LogicalAllowed);
02193
return(
OK_STATUS);
02194 }
02195
02196
02197
ARC_STATUS
02198 IsCreationOfPrimaryAllowed(
02199 IN ULONG Disk,
02200 IN BOOLEAN AllowMultiplePrimaries,
02201 OUT BOOLEAN *Allowed
02202 )
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230 {
02231
PREGION_DESCRIPTOR Regions;
02232 ULONG RegionCount;
02233 ULONG UsedCount,RecogCount,i;
02234
ARC_STATUS status;
02235 BOOLEAN FreeSpace =
FALSE;
02236
02237 status =
GetPrimaryDiskRegions(Disk,&Regions,&RegionCount);
02238
if(status !=
OK_STATUS) {
02239
return(status);
02240 }
02241
02242
for(UsedCount = RecogCount = i = 0; i<RegionCount; i++) {
02243
ASRT(Regions[i].RegionType !=
REGION_LOGICAL);
02244
if(Regions[i].
SysID ==
SYSID_UNUSED) {
02245 FreeSpace =
TRUE;
02246 }
else {
02247 UsedCount++;
02248
if(!
IsExtended(Regions[i].SysID) && Regions[i].
Recognized) {
02249 RecogCount++;
02250 }
02251 }
02252 }
02253
ASRT(UsedCount <=
ENTRIES_PER_BOOTSECTOR);
02254
ASRT(RecogCount <=
ENTRIES_PER_BOOTSECTOR);
02255
ASRT(RecogCount <= UsedCount);
02256
02257
if((UsedCount <
ENTRIES_PER_BOOTSECTOR)
02258 && FreeSpace
02259 && (!RecogCount || AllowMultiplePrimaries))
02260 {
02261 *Allowed =
TRUE;
02262 }
else {
02263 *Allowed =
FALSE;
02264 }
02265
02266
FreeRegionArray(Regions,RegionCount);
02267
return(
OK_STATUS);
02268 }
02269
02270
02271
ARC_STATUS
02272 IsCreationOfExtendedAllowed(
02273 IN ULONG Disk,
02274 OUT BOOLEAN *Allowed
02275 )
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299 {
02300
PREGION_DESCRIPTOR Regions;
02301 ULONG RegionCount;
02302 ULONG UsedCount,FreeCount,i;
02303
ARC_STATUS status;
02304
02305 status =
GetPrimaryDiskRegions(Disk,&Regions,&RegionCount);
02306
if(status !=
OK_STATUS) {
02307
return(status);
02308 }
02309
02310
for(UsedCount = FreeCount = i = 0; i<RegionCount; i++) {
02311
ASRT(Regions[i].RegionType !=
REGION_LOGICAL);
02312
if(Regions[i].
SysID ==
SYSID_UNUSED) {
02313
02314
02315
02316 FreeCount++;
02317 }
else {
02318 UsedCount++;
02319
if(
IsExtended(Regions[i].SysID)) {
02320
FreeRegionArray(Regions,RegionCount);
02321 *Allowed =
FALSE;
02322
return(
OK_STATUS);
02323 }
02324 }
02325 }
02326 *Allowed = (BOOLEAN)((UsedCount <
ENTRIES_PER_BOOTSECTOR) && FreeCount);
02327
FreeRegionArray(Regions,RegionCount);
02328
return(
OK_STATUS);
02329 }
02330
02331
02332
ARC_STATUS
02333 IsCreationOfLogicalAllowed(
02334 IN ULONG Disk,
02335 OUT BOOLEAN *Allowed
02336 )
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358 {
02359
PREGION_DESCRIPTOR Regions;
02360 ULONG RegionCount;
02361 ULONG i;
02362
ARC_STATUS status;
02363 BOOLEAN ExtendedExists;
02364
02365 *Allowed =
FALSE;
02366
02367 status =
DoesExtendedExist(Disk,&ExtendedExists);
02368
if(status !=
OK_STATUS) {
02369
return(status);
02370 }
02371
if(!ExtendedExists) {
02372
return(
OK_STATUS);
02373 }
02374
02375 status =
GetLogicalDiskRegions(Disk,&Regions,&RegionCount);
02376
if(status !=
OK_STATUS) {
02377
return(status);
02378 }
02379
02380
for(i = 0; i<RegionCount; i++) {
02381
ASRT(Regions[i].RegionType ==
REGION_LOGICAL);
02382
if(Regions[i].
SysID ==
SYSID_UNUSED) {
02383 *Allowed =
TRUE;
02384
break;
02385 }
02386 }
02387
FreeRegionArray(Regions,RegionCount);
02388
return(
OK_STATUS);
02389 }
02390
02391
02392
02393
ARC_STATUS
02394 DoesAnyPartitionExist(
02395 IN ULONG Disk,
02396 OUT PBOOLEAN AnyExists,
02397 OUT PBOOLEAN PrimaryExists,
02398 OUT PBOOLEAN ExtendedExists,
02399 OUT PBOOLEAN LogicalExists
02400 )
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428 {
02429
ARC_STATUS status;
02430
02431
if((status =
DoesAnyPrimaryExist(Disk,PrimaryExists )) !=
OK_STATUS) {
02432
return(status);
02433 }
02434
if((status =
DoesExtendedExist (Disk,ExtendedExists)) !=
OK_STATUS) {
02435
return(status);
02436 }
02437
if((status =
DoesAnyLogicalExist(Disk,LogicalExists )) !=
OK_STATUS) {
02438
return(status);
02439 }
02440 *AnyExists = (BOOLEAN)(*PrimaryExists || *ExtendedExists || *LogicalExists);
02441
return(
OK_STATUS);
02442 }
02443
02444
02445
ARC_STATUS
02446 DoesAnyPrimaryExist(
02447 IN ULONG Disk,
02448 OUT BOOLEAN *Exists
02449 )
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470 {
02471
PREGION_DESCRIPTOR Regions;
02472 ULONG RegionCount,i;
02473
ARC_STATUS status;
02474
02475 status =
GetUsedPrimaryDiskRegions(Disk,&Regions,&RegionCount);
02476
if(status !=
OK_STATUS) {
02477
return(status);
02478 }
02479
02480 *Exists =
FALSE;
02481
02482
for(i=0; i<RegionCount; i++) {
02483
ASRT(Regions[i].RegionType !=
REGION_LOGICAL);
02484
ASRT(Regions[i].SysID !=
SYSID_UNUSED);
02485
if(!
IsExtended(Regions[i].SysID)) {
02486 *Exists =
TRUE;
02487
break;
02488 }
02489 }
02490
FreeRegionArray(Regions,RegionCount);
02491
return(
OK_STATUS);
02492 }
02493
02494
02495
ARC_STATUS
02496 DoesExtendedExist(
02497 IN ULONG Disk,
02498 OUT BOOLEAN *Exists
02499 )
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520 {
02521
PREGION_DESCRIPTOR Regions;
02522 ULONG RegionCount,i;
02523
ARC_STATUS status;
02524
02525 status =
GetUsedPrimaryDiskRegions(Disk,&Regions,&RegionCount);
02526
if(status !=
OK_STATUS) {
02527
return(status);
02528 }
02529
02530 *Exists =
FALSE;
02531
02532
for(i=0; i<RegionCount; i++) {
02533
ASRT(Regions[i].RegionType !=
REGION_LOGICAL);
02534
ASRT(Regions[i].SysID !=
SYSID_UNUSED);
02535
if(
IsExtended(Regions[i].SysID)) {
02536 *Exists =
TRUE;
02537
break;
02538 }
02539 }
02540
FreeRegionArray(Regions,RegionCount);
02541
return(
OK_STATUS);
02542 }
02543
02544
02545
ARC_STATUS
02546 DoesAnyLogicalExist(
02547 IN ULONG Disk,
02548 OUT BOOLEAN *Exists
02549 )
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570 {
02571
PREGION_DESCRIPTOR Regions;
02572 ULONG RegionCount;
02573
ARC_STATUS status;
02574
02575 status =
GetUsedLogicalDiskRegions(Disk,&Regions,&RegionCount);
02576
if(status !=
OK_STATUS) {
02577
return(status);
02578 }
02579
02580 *Exists = (BOOLEAN)(RegionCount != 0);
02581
FreeRegionArray(Regions,RegionCount);
02582
return(
OK_STATUS);
02583 }
02584
02585
02586 ULONG
02587 GetDiskCount(
02588 VOID
02589 )
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609 {
02610
return(
CountOfDisks);
02611 }
02612
02613
02614 PCHAR
02615 GetDiskName(
02616 ULONG Disk
02617 )
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637 {
02638
return(
DiskNames[Disk]);
02639 }
02640
02641
02642
02643
02644 char UNKNOWN[] =
"Unknown type";
02645
02646 PCHAR
SysIDStrings[256] = {
"Free Space",
"FAT",
"XENIX1",
"XENIX2",
02647
"FAT",
"Extended",
"FAT",
"HPFS/NTFS",
02648
UNKNOWN,
UNKNOWN,
02649
"OS/2 Boot Manager",
UNKNOWN,
02650
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02651
UNKNOWN,
UNKNOWN,
02652
"EISA Utilities",
UNKNOWN,
02653
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02654
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02655
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02656
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02657
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02658
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02659
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02660
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02661
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02662
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02663
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02664
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02665
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02666
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02667
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02668
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02669
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02670
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02671
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02672
UNKNOWN,
UNKNOWN,
UNKNOWN,
"Unix",
02673
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02674
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02675
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02676
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02677
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02678
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02679
UNKNOWN,
UNKNOWN,
UNKNOWN,
"Unused",
02680
UNKNOWN,
"Windows NT Fault Tolerance",
02681
UNKNOWN,
UNKNOWN,
02682
"Windows NT Fault Tolerance",
UNKNOWN,
02683
"Windows NT Fault Tolerance",
02684
"Windows NT Fault Tolerance",
02685
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02686
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02687
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02688
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02689
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02690
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02691
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02692
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02693
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02694
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02695
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02696
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02697
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02698
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02699
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02700
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02701
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02702
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02703
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02704
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02705
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02706
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02707
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02708
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02709
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02710
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02711
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02712
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02713
UNKNOWN,
UNKNOWN,
UNKNOWN,
UNKNOWN,
02714
UNKNOWN,
UNKNOWN,
UNKNOWN,
"Table",
02715 };
02716
02717
02718 PCHAR
02719 GetSysIDName(
02720 UCHAR SysID
02721 )
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740 {
02741
return(
SysIDStrings[SysID]);
02742 }
02743
02744
02745
02746
02747
VOID
02748 UnusedEntryFill(
02749 IN PPARTITION_INFORMATION pinfo,
02750 IN ULONG EntryCount
02751 )
02752 {
02753 ULONG i;
02754 LARGE_INTEGER
Zero;
02755
02756
Zero.QuadPart = 0;
02757
02758
for(i=0; i<EntryCount; i++) {
02759
02760 pinfo[i].StartingOffset =
Zero;
02761 pinfo[i].PartitionLength =
Zero;
02762 pinfo[i].HiddenSectors = 0;
02763 pinfo[i].PartitionType =
SYSID_UNUSED;
02764 pinfo[i].BootIndicator =
FALSE;
02765 pinfo[i].RewritePartition =
TRUE;
02766 }
02767 }
02768
02769
02770 LARGE_INTEGER
02771 MakeBootRec(
02772 ULONG Disk,
02773 PPARTITION_INFORMATION pinfo,
02774
PPARTITION pLogical,
02775
PPARTITION pNextLogical
02776 )
02777 {
02778 ULONG Entry = 0;
02779 LARGE_INTEGER BytesPerTrack;
02780 LARGE_INTEGER SectorsPerTrack;
02781 LARGE_INTEGER StartingOffset;
02782
02783 BytesPerTrack.QuadPart = (
DiskGeometryArray[Disk].
BytesPerTrack);
02784 SectorsPerTrack.QuadPart = (
DiskGeometryArray[Disk].
SectorsPerTrack);
02785 StartingOffset.QuadPart = 0;
02786
02787
02788
02789
if(pLogical) {
02790
02791 pinfo[Entry].StartingOffset.QuadPart = pLogical->
Offset.QuadPart + BytesPerTrack.QuadPart;
02792 pinfo[Entry].PartitionLength.QuadPart = pLogical->
Length.QuadPart - BytesPerTrack.QuadPart;
02793 pinfo[Entry].HiddenSectors = SectorsPerTrack.LowPart;
02794 pinfo[Entry].RewritePartition = pLogical->
Update;
02795 pinfo[Entry].BootIndicator = pLogical->
Active;
02796 pinfo[Entry].PartitionType = pLogical->
SysID;
02797
02798
if(pinfo[Entry].RewritePartition) {
02799 StartingOffset = pinfo[Entry].StartingOffset;
02800 }
02801
02802 Entry++;
02803 }
02804
02805
if(pNextLogical) {
02806
02807 pinfo[Entry].StartingOffset = pNextLogical->
Offset;
02808 pinfo[Entry].PartitionLength = pNextLogical->
Length;
02809 pinfo[Entry].HiddenSectors = 0;
02810 pinfo[Entry].RewritePartition =
TRUE;
02811 pinfo[Entry].BootIndicator =
FALSE;
02812 pinfo[Entry].PartitionType =
SYSID_EXTENDED;
02813
02814 Entry++;
02815 }
02816
02817
UnusedEntryFill(pinfo+Entry,
ENTRIES_PER_BOOTSECTOR-Entry);
02818
return(StartingOffset);
02819 }
02820
02821
02822
ARC_STATUS
02823 ZapSector(
02824 ULONG Disk,
02825 LARGE_INTEGER Offset
02826 )
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849 {
02850 ULONG
SectorSize =
DiskGeometryArray[Disk].
BytesPerSector;
02851 ULONG i;
02852 PCHAR SectorBuffer,AlignedSectorBuffer;
02853
ARC_STATUS status;
02854 ULONG
Handle;
02855 LARGE_INTEGER LargeInteger;
02856
02857
if((SectorBuffer =
AllocateMemory(2*
SectorSize)) ==
NULL) {
02858
RETURN_OUT_OF_MEMORY;
02859 }
02860
02861 AlignedSectorBuffer = (PCHAR)(((ULONG)SectorBuffer+
SectorSize) & ~(
SectorSize-1));
02862
02863
for(i=0; i<
SectorSize; AlignedSectorBuffer[i++] = 0);
02864
02865
if((status =
LowOpenDisk(
GetDiskName(Disk),&
Handle)) !=
OK_STATUS) {
02866
FreeMemory(SectorBuffer);
02867
return(status);
02868 }
02869
02870 LargeInteger.QuadPart =
Offset.QuadPart /
SectorSize;
02871 status =
LowWriteSectors(
Handle,
02872
SectorSize,
02873
LOWPART(LargeInteger),
02874 1,
02875 AlignedSectorBuffer
02876 );
02877
02878
LowCloseDisk(
Handle);
02879
FreeMemory(SectorBuffer);
02880
02881
return(status);
02882 }
02883
02884
02885
ARC_STATUS
02886 WriteDriveLayout(
02887 IN ULONG Disk
02888 )
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909 {
02910 PDRIVE_LAYOUT_INFORMATION DriveLayout;
02911 PPARTITION_INFORMATION pinfo;
02912
PPARTITION n,p;
02913 ULONG EntryCount;
02914
ARC_STATUS status;
02915 LARGE_INTEGER StartingOffset;
02916 LARGE_INTEGER ExtendedStartingOffset;
02917
02918 ExtendedStartingOffset.QuadPart = 0;
02919
02920
02921
02922
02923
if(!(DriveLayout =
AllocateMemory(250 *
sizeof(PARTITION_INFORMATION)))) {
02924
RETURN_OUT_OF_MEMORY;
02925 }
02926
02927 pinfo = &DriveLayout->PartitionEntry[0];
02928
02929
02930
02931 EntryCount=0;
02932 p =
PrimaryPartitions[Disk];
02933
02934
while(p) {
02935
02936
if(p->
SysID !=
SYSID_UNUSED) {
02937
02938
ASRT(EntryCount <
ENTRIES_PER_BOOTSECTOR);
02939
02940
if(
IsExtended(p->
SysID)) {
02941 ExtendedStartingOffset = p->
Offset;
02942 }
02943
02944 pinfo[EntryCount].StartingOffset = p->
Offset;
02945 pinfo[EntryCount].PartitionLength = p->
Length;
02946 pinfo[EntryCount].PartitionType = p->
SysID;
02947 pinfo[EntryCount].BootIndicator = p->
Active;
02948 pinfo[EntryCount].RewritePartition = p->
Update;
02949
02950
02951
02952
02953 pinfo[EntryCount].HiddenSectors = 0;
02954
02955
02956
02957
02958
if(pinfo[EntryCount].RewritePartition
02959 && (p->
Update !=
CHANGED_DONT_ZAP)
02960 && !
IsExtended(pinfo[EntryCount].PartitionType))
02961 {
02962 status =
ZapSector(Disk,pinfo[EntryCount].StartingOffset);
02963
if(status !=
OK_STATUS) {
02964
FreeMemory(DriveLayout);
02965
return(status);
02966 }
02967 }
02968
02969 EntryCount++;
02970 }
02971 p = p->
Next;
02972 }
02973
02974
02975
02976
02977
02978
UnusedEntryFill(pinfo+EntryCount,
ENTRIES_PER_BOOTSECTOR - EntryCount);
02979 EntryCount =
ENTRIES_PER_BOOTSECTOR;
02980
02981
02982
02983
02984
02985
02986
#if 0
02987
02988
02989
02990
#else
02991
02992
02993
02994
02995
02996
02997
#endif
02998
02999
03000
if((p =
LogicalVolumes[Disk]) && (p->
SysID ==
SYSID_UNUSED)) {
03001
if(p->
Next) {
03002
ASRT(p->
Next->
SysID !=
SYSID_UNUSED);
03003
03004
MakeBootRec(Disk,pinfo+EntryCount,
NULL,p->
Next);
03005 EntryCount +=
ENTRIES_PER_BOOTSECTOR;
03006 p = p->
Next;
03007 }
else {
03008
ASRT(ExtendedStartingOffset.QuadPart != 0);
03009
#if 0
03010
status =
ZapSector(Disk,ExtendedStartingOffset);
03011
if(status !=
OK_STATUS) {
03012
FreeMemory(DriveLayout);
03013
return(status);
03014 }
03015
#else
03016
MakeBootRec(Disk,pinfo+EntryCount,
NULL,
NULL);
03017 EntryCount +=
ENTRIES_PER_BOOTSECTOR;
03018
#endif
03019
}
03020 }
03021
03022
while(p) {
03023
if(p->
SysID !=
SYSID_UNUSED) {
03024
03025
03026
03027
n = p->
Next;
03028
while(
n) {
03029
if(
n->SysID !=
SYSID_UNUSED) {
03030
break;
03031 }
03032
n =
n->Next;
03033 }
03034
03035 StartingOffset =
MakeBootRec(Disk,pinfo+EntryCount,p,
n);
03036
03037
03038
03039
03040
if((StartingOffset.QuadPart != 0) && (p->
Update !=
CHANGED_DONT_ZAP)) {
03041 status =
ZapSector(Disk,StartingOffset);
03042
if(status !=
OK_STATUS) {
03043
FreeMemory(DriveLayout);
03044
return(status);
03045 }
03046 }
03047
03048 EntryCount +=
ENTRIES_PER_BOOTSECTOR;
03049 }
03050 p = p->
Next;
03051 }
03052
03053 DriveLayout->PartitionCount = EntryCount;
03054 status =
LowSetDiskLayout(
DiskNames[Disk],DriveLayout);
03055
03056
FreeMemory(DriveLayout);
03057
03058
return(status);
03059 }
03060
03061
03062
ARC_STATUS
03063 CommitPartitionChanges(
03064 IN ULONG Disk
03065 )
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085 {
03086
PPARTITION p;
03087
ARC_STATUS status;
03088
03089
ASRT(!
OffLine[Disk]);
03090
03091
if(!
HavePartitionsBeenChanged(Disk)) {
03092
return(
OK_STATUS);
03093 }
03094
03095
if((status =
WriteDriveLayout(Disk)) !=
OK_STATUS) {
03096
return(status);
03097 }
03098
03099
03100
03101
03102 p =
PrimaryPartitions[Disk];
03103
while(p) {
03104 p->
Update =
FALSE;
03105 p->
OriginalPartitionNumber = p->
PartitionNumber;
03106 p = p->
Next;
03107 }
03108 p =
LogicalVolumes[Disk];
03109
while(p) {
03110 p->
Update =
FALSE;
03111 p->
OriginalPartitionNumber = p->
PartitionNumber;
03112 p = p->
Next;
03113 }
03114
03115
ChangesMade[Disk] =
FALSE;
03116
return(
OK_STATUS);
03117 }
03118
03119
03120 BOOLEAN
03121 HavePartitionsBeenChanged(
03122 IN ULONG Disk
03123 )
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144 {
03145
if(
OffLine[Disk]) {
03146
ASRT(!
ChangesMade[Disk]);
03147 }
03148
return(
ChangesMade[Disk]);
03149 }
03150
03151
VOID
03152 FdMarkDiskDirty(
03153 IN ULONG Disk
03154 )
03155 {
03156
ASRT(!
OffLine[Disk]);
03157
03158
ChangesMade[Disk] =
TRUE;
03159 }
03160
03161
VOID
03162 FdSetPersistentData(
03163 IN
PREGION_DESCRIPTOR Region,
03164 IN ULONG Data
03165 )
03166 {
03167 ((
PREGION_DATA)(Region->Reserved))->Partition->PersistentData = Data;
03168 }
03169
03170
03171 ULONG
03172 FdGetMinimumSizeMB(
03173 IN ULONG Disk
03174 )
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194 {
03195 LARGE_INTEGER LargeInteger;
03196
03197 LargeInteger.QuadPart =
DiskGeometryArray[Disk].
BytesPerCylinder;
03198
return(
max(
SIZEMB(LargeInteger),1));
03199 }
03200
03201
03202 ULONG
03203 FdGetMaximumSizeMB(
03204 IN
PREGION_DESCRIPTOR Region,
03205 IN REGION_TYPE CreationType
03206 )
03207 {
03208
PREGION_DATA CreateData = Region->Reserved;
03209 LARGE_INTEGER MaxSize = CreateData->
AlignedRegionSize;
03210
03211
ASRT(Region->SysID ==
SYSID_UNUSED);
03212
03213
if(CreateData->
AlignedRegionOffset.QuadPart == 0) {
03214
03215 ULONG Delta;
03216
03217
ASRT((CreationType ==
REGION_EXTENDED) || (CreationType ==
REGION_PRIMARY))
03218
03219 Delta = (CreationType ==
REGION_EXTENDED)
03220 ?
DiskGeometryArray[Region->Disk].
BytesPerCylinder
03221 :
DiskGeometryArray[Region->Disk].
BytesPerTrack;
03222
03223 MaxSize.QuadPart = MaxSize.QuadPart - Delta;
03224 }
03225
03226
return(
SIZEMB(MaxSize));
03227 }
03228
03229
03230 LARGE_INTEGER
03231 FdGetExactSize(
03232 IN
PREGION_DESCRIPTOR Region,
03233 IN BOOLEAN ForExtended
03234 )
03235 {
03236
PREGION_DATA RegionData = Region->Reserved;
03237 LARGE_INTEGER LargeSize = RegionData->
AlignedRegionSize;
03238 LARGE_INTEGER BytesPerTrack;
03239 LARGE_INTEGER BytesPerCylinder;
03240
03241 BytesPerTrack.QuadPart = (
DiskGeometryArray[Region->Disk].
BytesPerTrack);
03242 BytesPerCylinder.QuadPart = (
DiskGeometryArray[Region->Disk].
BytesPerCylinder);
03243
03244
if(Region->RegionType ==
REGION_LOGICAL) {
03245
03246
03247
03248
03249
03250
03251
03252 LargeSize.QuadPart = LargeSize.QuadPart - BytesPerTrack.QuadPart;
03253
03254 }
else if(Region->SysID ==
SYSID_UNUSED) {
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
if((RegionData->
AlignedRegionOffset.QuadPart == 0) || ForExtended) {
03268 LargeSize.QuadPart = LargeSize.QuadPart - BytesPerTrack.QuadPart;
03269 }
03270
03271
if((RegionData->
AlignedRegionOffset.QuadPart == 0) && ForExtended) {
03272 LargeSize.QuadPart = LargeSize.QuadPart - BytesPerCylinder.QuadPart;
03273 }
03274 }
03275
03276
return(LargeSize);
03277 }
03278
03279
03280 LARGE_INTEGER
03281 FdGetExactOffset(
03282 IN
PREGION_DESCRIPTOR Region
03283 )
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305 {
03306 LARGE_INTEGER
Offset = ((
PREGION_DATA)(Region->Reserved))->Partition->Offset;
03307
03308
if((Region->SysID !=
SYSID_UNUSED) && (Region->RegionType ==
REGION_LOGICAL)) {
03309
03310
03311
03312
03313
03314
03315
Offset.QuadPart =
Offset.QuadPart +
03316
DiskGeometryArray[Region->Disk].
BytesPerTrack;
03317 }
03318
03319
return(
Offset);
03320 }
03321
03322
03323 BOOLEAN
03324 FdCrosses1024Cylinder(
03325 IN
PREGION_DESCRIPTOR Region,
03326 IN ULONG CreationSizeMB,
03327 IN REGION_TYPE RegionType
03328 )
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352 {
03353 LARGE_INTEGER
Start,
Size,
End, LargeZero;
03354
03355
if(Region->SysID ==
SYSID_UNUSED) {
03356
03357
03358
03359
03360
03361
03362 LargeZero.QuadPart = 0;
03363
DetermineCreateSizeAndOffset( Region,
03364 LargeZero,
03365 CreationSizeMB,
03366 RegionType,
03367 &
Start,
03368 &
Size
03369 );
03370
03371 }
else {
03372
03373
Start = ((
PREGION_DATA)(Region->Reserved))->Partition->Offset;
03374
Size = ((
PREGION_DATA)(Region->Reserved))->Partition->Length;
03375 }
03376
03377
End.QuadPart = (
Start.QuadPart +
Size.QuadPart) - 1;
03378
03379
03380
03381
03382
03383
03384
return( (
End.QuadPart /
DiskGeometryArray[Region->Disk].
BytesPerCylinder) > 1023 );
03385 }
03386
03387
03388 BOOLEAN
03389 IsDiskOffLine(
03390 IN ULONG Disk
03391 )
03392 {
03393
return(
OffLine[Disk]);
03394 }