00001
#include "precomp.h"
00002
#pragma hdrstop
00003
#include <bootmbr.h>
00004
00005
ARC_STATUS
00006 LowOpenDisk(
00007 IN PCHAR DevicePath,
00008 OUT PULONG DiskId
00009 )
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 {
00027
char buffer[256];
00028
00029
sprintf(buffer,
"%spartition(0)",DevicePath);
00030
00031
return ArcOpen(buffer,
ArcOpenReadWrite, DiskId);
00032 }
00033
00034
00035
ARC_STATUS
00036 LowCloseDisk(
00037 IN ULONG DiskId
00038 )
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 {
00055
return ArcClose(DiskId);
00056 }
00057
00058
ARC_STATUS
00059 LowGetDriveGeometry(
00060 IN PCHAR DevicePath,
00061 OUT PULONG TotalSectorCount,
00062 OUT PULONG SectorSize,
00063 OUT PULONG SectorsPerTrack,
00064 OUT PULONG Heads
00065 )
00066 {
00067
char Buffer[256];
00068
00069
sprintf(
Buffer,
"%spartition(0)",DevicePath);
00070
return(
LowGetPartitionGeometry(
Buffer,TotalSectorCount,
SectorSize,SectorsPerTrack,Heads));
00071 }
00072
00073
00074
00075
ARC_STATUS
00076 LowGetPartitionGeometry(
00077 IN PCHAR PartitionPath,
00078 OUT PULONG TotalSectorCount,
00079 OUT PULONG SectorSize,
00080 OUT PULONG SectorsPerTrack,
00081 OUT PULONG Heads
00082 )
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 {
00104
FILE_INFORMATION file_info;
00105
ARC_STATUS r;
00106 ULONG fileid;
00107 LARGE_INTEGER l;
00108 CM_DISK_GEOMETRY_DEVICE_DATA *DiskGeometry;
00109
CONFIGURATION_COMPONENT *DiskComponent;
00110 CM_PARTIAL_RESOURCE_LIST *DiskConfiguration;
00111
CHAR DataBuffer[
sizeof(CM_PARTIAL_RESOURCE_LIST) +
00112
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)];
00113 CM_PARTIAL_RESOURCE_DESCRIPTOR *DiskData;
00114
00115
00116
00117 *
SectorSize = 512;
00118
00119
00120
00121 *SectorsPerTrack = 32;
00122 *Heads = 64;
00123
00124
00125
00126
00127
00128 DiskComponent =
ArcGetComponent(PartitionPath);
00129
00130
if (DiskComponent ==
NULL) {
00131
return EINVAL;
00132 }
00133
00134
00135
00136
00137
00138
00139
if (DiskComponent->
ConfigurationDataLength ==
sizeof(CM_PARTIAL_RESOURCE_LIST) +
00140
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA) ) {
00141
00142 DiskConfiguration = (CM_PARTIAL_RESOURCE_LIST *)DataBuffer;
00143
00144 r =
ArcGetConfigurationData(DiskConfiguration,DiskComponent);
00145
00146
if (r ==
ESUCCESS) {
00147
00148
00149
00150
00151
00152
if ( (DiskConfiguration->Version == 1 && DiskConfiguration->Revision >=3 ) ||
00153 (DiskConfiguration->Version > 1) ) {
00154
00155 DiskData = &(DiskConfiguration->PartialDescriptors[DiskConfiguration->Count-1]);
00156
00157
if (DiskData->Type == CmResourceTypeDeviceSpecific) {
00158
00159
if (DiskData->u.DeviceSpecificData.DataSize ==
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) {
00160 DiskGeometry = (CM_DISK_GEOMETRY_DEVICE_DATA *)
00161 &(DiskConfiguration->PartialDescriptors[DiskConfiguration->Count]);
00162 *SectorsPerTrack = DiskGeometry->SectorsPerTrack;
00163 *Heads = DiskGeometry->NumberOfHeads;
00164 *
SectorSize = DiskGeometry->BytesPerSector;
00165 }
00166 }
00167 }
00168 }
00169 }
00170
00171
00172
00173
00174
00175 r =
ArcOpen(PartitionPath,
ArcOpenReadOnly, &fileid);
00176
00177
if (r !=
ESUCCESS) {
00178
return r;
00179 }
00180
00181 r =
ArcGetFileInformation(fileid, &file_info);
00182
00183
if (r !=
ESUCCESS) {
00184
return r;
00185 }
00186
00187 r =
ArcClose(fileid);
00188
00189
if (r !=
ESUCCESS) {
00190
return r;
00191 }
00192
00193 l.QuadPart = file_info.
EndingAddress.QuadPart -
00194 file_info.
StartingAddress.QuadPart;
00195
00196 l.QuadPart = ((ULONGLONG)l.QuadPart) / ((ULONGLONG)(*SectorSize));
00197
00198
if (l.HighPart) {
00199
return E2BIG;
00200 }
00201
00202 *TotalSectorCount = l.LowPart;
00203
00204
return ESUCCESS;
00205 }
00206
00207
00208 #define MAX_TRANSFER 65536
00209
00210
00211
ARC_STATUS
00212 LowReadSectors(
00213 IN ULONG VolumeId,
00214 IN ULONG SectorSize,
00215 IN ULONG StartingSector,
00216 IN ULONG NumberOfSectors,
00217 OUT PVOID Buffer
00218 )
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 {
00240
ARC_STATUS r;
00241 ULONG
c;
00242 LARGE_INTEGER l;
00243 ULONG i;
00244 ULONG transfer;
00245 PCHAR buf;
00246 ULONG total;
00247
00248
00249 l.QuadPart = UInt32x32To64(StartingSector,
SectorSize);
00250
00251 buf = (PCHAR)
Buffer;
00252
00253 r =
ArcSeek(VolumeId, &l,
SeekAbsolute);
00254
00255
if (r !=
ESUCCESS) {
00256
return r;
00257 }
00258
00259 total =
SectorSize*NumberOfSectors;
00260
00261
for (i = 0; i < total; i +=
MAX_TRANSFER) {
00262
00263 transfer =
min(
MAX_TRANSFER, total - i);
00264
00265 r =
ArcRead(VolumeId, &buf[i], transfer, &
c);
00266
00267
if (r !=
ESUCCESS) {
00268
return r;
00269 }
00270
00271
if (
c != transfer) {
00272
return EIO;
00273 }
00274 }
00275
00276
return ESUCCESS;
00277 }
00278
00279
00280
ARC_STATUS
00281 LowWriteSectors(
00282 IN ULONG VolumeId,
00283 IN ULONG SectorSize,
00284 IN ULONG StartingSector,
00285 IN ULONG NumberOfSectors,
00286 IN PVOID Buffer
00287 )
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 {
00309
ARC_STATUS r;
00310 ULONG
c;
00311 LARGE_INTEGER l;
00312 ULONG i;
00313 ULONG transfer;
00314 PCHAR buf;
00315 ULONG total;
00316
00317 l.QuadPart = UInt32x32To64(StartingSector,
SectorSize);
00318
00319 buf = (PCHAR)
Buffer;
00320
00321 r =
ArcSeek(VolumeId, &l,
SeekAbsolute);
00322
00323
if (r !=
ESUCCESS) {
00324
return r;
00325 }
00326
00327 total =
SectorSize*NumberOfSectors;
00328
00329
for (i = 0; i < total; i +=
MAX_TRANSFER) {
00330
00331 transfer =
min(
MAX_TRANSFER, total - i);
00332
00333 r =
ArcWrite(VolumeId, &buf[i], transfer, &
c);
00334
00335
if (r !=
ESUCCESS) {
00336
return r;
00337 }
00338
00339
if (
c != transfer) {
00340
return EIO;
00341 }
00342 }
00343
00344
return ESUCCESS;
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
00372
00373 PCHAR
MnemonicTable[] = {
00374
"arc",
00375
"cpu",
00376
"fpu",
00377
"pic",
00378
"pdc",
00379
"sic",
00380
"sdc",
00381
"sc",
00382
"eisa",
00383
"tc",
00384
"scsi",
00385
"dti",
00386
"multi",
00387
"disk",
00388
"tape",
00389
"cdrom",
00390
"worm",
00391
"serial",
00392
"net",
00393
"video",
00394
"par",
00395
"point",
00396
"key",
00397
"audio",
00398
"other",
00399
"rdisk",
00400
"fdisk",
00401
"tape",
00402
"modem",
00403
"monitor",
00404
"print",
00405
"pointer",
00406
"keyboard",
00407
"term",
00408
"other",
00409
"line",
00410
"netper",
00411
"memory"
00412 };
00413
00414
00415
00416
00417
00418 CHAR Pathname[256];
00419
00420
00421 PCHAR
00422 AlGetPathnameFromComponent (
00423 IN
PCONFIGURATION_COMPONENT Component
00424 )
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 {
00444
PCONFIGURATION_COMPONENT ParentComponent;
00445
CHAR NewSegment[16];
00446
CHAR Tempname[256];
00447
00448
Pathname[0] = 0;
00449
00450
00451
00452
00453
00454
while ((ParentComponent =
ArcGetParent(Component)) !=
NULL) {
00455
00456
00457
00458
00459
00460
sprintf(NewSegment,
00461
"%s(%d)",
00462
MnemonicTable[Component->Type],
00463 Component->Key);
00464
00465
00466
00467
00468
00469 strcpy(Tempname,
Pathname);
00470 strcpy(
Pathname, NewSegment);
00471 strcat(
Pathname, Tempname);
00472
00473
00474
00475
00476
00477 Component = ParentComponent;
00478 }
00479
00480
return Pathname;
00481 }
00482
00483
00484
00485
ARC_STATUS
00486 LowQueryPathFromComponent(
00487 IN
PCONFIGURATION_COMPONENT Component,
00488 OUT PCHAR* Path
00489 )
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 {
00508 PCHAR p;
00509 PCHAR
path;
00510
00511 p =
AlGetPathnameFromComponent(Component);
00512
00513
path =
AllocateMemory(
strlen(p) + 1);
00514
00515
if (!
path) {
00516
return ENOMEM;
00517 }
00518
00519 strcpy(
path, p);
00520
00521 *Path =
path;
00522
00523
return ESUCCESS;
00524 }
00525
00526
00527
ARC_STATUS
00528 LowTraverseChildren(
00529 IN
PCONFIGURATION_COMPONENT Parent,
00530 IN CONFIGURATION_CLASS* ConfigClass OPTIONAL,
00531 IN CONFIGURATION_TYPE* ConfigType OPTIONAL,
00532 IN OUT
PCONFIGURATION_COMPONENT* MatchingArray OPTIONAL,
00533 IN OUT PULONG CurrentLength
00534 )
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 {
00558
PCONFIGURATION_COMPONENT pc;
00559
ARC_STATUS r;
00560
00561
if (!(pc =
ArcGetChild(Parent))) {
00562
return ESUCCESS;
00563 }
00564
00565
for (;;) {
00566
00567
if ((!ConfigClass || pc->
Class == *ConfigClass) &&
00568 (!ConfigType || pc->
Type == *ConfigType)) {
00569
00570
if (MatchingArray) {
00571
00572 MatchingArray[*
CurrentLength] = pc;
00573 }
00574
00575 (*CurrentLength)++;
00576 }
00577
00578 r =
LowTraverseChildren(pc, ConfigClass, ConfigType,
00579 MatchingArray,
CurrentLength);
00580
00581
if (r !=
ESUCCESS) {
00582
return r;
00583 }
00584
00585
if (!(pc =
ArcGetPeer(pc))) {
00586
break;
00587 }
00588 }
00589
00590
return ESUCCESS;
00591 }
00592
00593
00594
ARC_STATUS
00595 LowQueryComponentList(
00596 IN CONFIGURATION_CLASS* ConfigClass OPTIONAL,
00597 IN CONFIGURATION_TYPE* ConfigType OPTIONAL,
00598 OUT
PCONFIGURATION_COMPONENT** ComponentList,
00599 OUT PULONG ListLength
00600 )
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 {
00627
ARC_STATUS r;
00628
00629 *ListLength = 0;
00630
00631 r =
LowTraverseChildren(
NULL, ConfigClass, ConfigType,
NULL, ListLength);
00632
00633
if (r !=
ESUCCESS) {
00634
return r;
00635 }
00636
00637
if (!(*ComponentList = (
PCONFIGURATION_COMPONENT*)
AllocateMemory(
00638 (*ListLength)*
sizeof(
PCONFIGURATION_COMPONENT)))) {
00639
00640
return ENOMEM;
00641 }
00642
00643 *ListLength = 0;
00644
00645
return LowTraverseChildren(
NULL, ConfigClass, ConfigType,
00646 *ComponentList, ListLength);
00647 }
00648
00649
00650
ARC_STATUS
00651 LowQueryPathList(
00652 IN CONFIGURATION_CLASS* ConfigClass OPTIONAL,
00653 IN CONFIGURATION_TYPE* ConfigType OPTIONAL,
00654 OUT PCHAR** PathList,
00655 OUT PULONG ListLength
00656 )
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 {
00677
PCONFIGURATION_COMPONENT* component_list;
00678 ULONG list_length;
00679
ARC_STATUS r;
00680 ULONG i;
00681 PCHAR* path_list;
00682
00683 r =
LowQueryComponentList(ConfigClass, ConfigType,
00684 &component_list, &list_length);
00685
00686
if (r !=
ESUCCESS) {
00687
return r;
00688 }
00689
00690
if (!(path_list = (PCHAR*)
AllocateMemory(list_length*
sizeof(PCHAR)))) {
00691
FreeMemory(component_list);
00692
return ENOMEM;
00693 }
00694
00695
00696
for (i = 0; i < list_length; i++) {
00697 path_list[i] =
NULL;
00698 }
00699
00700
for (i = 0; i < list_length; i++) {
00701
00702 r =
LowQueryPathFromComponent(component_list[i], &path_list[i]);
00703
00704
if (r !=
ESUCCESS) {
00705
FreeMemory(component_list);
00706
LowFreePathList(path_list, list_length);
00707
return r;
00708 }
00709 }
00710
00711
FreeMemory(component_list);
00712
00713 *PathList = path_list;
00714 *ListLength = list_length;
00715
00716
return ESUCCESS;
00717 }
00718
00719
00720
ARC_STATUS
00721 LowFreePathList(
00722 IN PCHAR* PathList,
00723 IN ULONG ListLength
00724 )
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741 {
00742 ULONG i;
00743
00744
for (i = 0; i < ListLength; i++) {
00745
if (PathList[i]) {
00746
FreeMemory(PathList[i]);
00747 }
00748 }
00749
FreeMemory(PathList);
00750
00751
return ESUCCESS;
00752 }
00753
00754
00755
ARC_STATUS
00756 LowQueryFdiskPathList(
00757 OUT PCHAR** PathList,
00758 OUT PULONG ListLength
00759 )
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 {
00778
CONFIGURATION_TYPE config_type;
00779
00780 config_type =
DiskPeripheral;
00781
return LowQueryPathList(
NULL, &config_type, PathList, ListLength);
00782 }
00783
00784
00785
ARC_STATUS
00786 LowFreeFdiskPathList(
00787 IN OUT PCHAR* PathList,
00788 IN ULONG ListLength
00789 )
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 {
00807
return LowFreePathList(PathList, ListLength);
00808 }
00809
00810
00811
ARC_STATUS
00812 LowGetDiskLayout(
00813 IN PCHAR Path,
00814 OUT PDRIVE_LAYOUT_INFORMATION* DriveLayout
00815 )
00816 {
00817
ARC_STATUS status;
00818 ULONG
Handle;
00819 ULONG i,ExtendedStart,BootSector,Entry;
00820 ULONG
dummy,bps;
00821 BOOLEAN Link,mbr;
00822 PDRIVE_LAYOUT_INFORMATION DriveInfo;
00823 PPARTITION_INFORMATION p;
00824 PCHAR SectorBuffer;
00825
PPARTITION_DESCRIPTOR ptable;
00826
00827
00828
#define PSTART(p) ( \
00829
(ULONG) ((p)->StartingSectorLsb0) + \
00830
(ULONG) ((p)->StartingSectorLsb1 << 8) + \
00831
(ULONG) ((p)->StartingSectorMsb0 << 16) + \
00832
(ULONG) ((p)->StartingSectorMsb1 << 24) )
00833
00834
#define PLENGTH(p) ( \
00835
(ULONG) ((p)->PartitionLengthLsb0) + \
00836
(ULONG) ((p)->PartitionLengthLsb1 << 8) + \
00837
(ULONG) ((p)->PartitionLengthMsb0 << 16) + \
00838
(ULONG) ((p)->PartitionLengthMsb1 << 24) )
00839
00840
00841
00842
if((DriveInfo =
AlAllocateHeap(
sizeof(DRIVE_LAYOUT_INFORMATION) + (500*
sizeof(PARTITION_INFORMATION)))) ==
NULL) {
00843
return(
ENOMEM);
00844 }
00845 p = &DriveInfo->PartitionEntry[0];
00846
00847
if((status =
LowGetDriveGeometry(Path,&
dummy,&bps,&
dummy,&
dummy)) !=
ESUCCESS) {
00848
AlDeallocateHeap(DriveInfo);
00849
return(status);
00850 }
00851
00852
if((SectorBuffer =
AlAllocateHeap(bps)) ==
NULL) {
00853
AlDeallocateHeap(DriveInfo);
00854
return(
ENOMEM);
00855 }
00856
00857 ptable = (
PPARTITION_DESCRIPTOR)(SectorBuffer + (2*
PARTITION_TABLE_OFFSET));
00858
00859
if((status =
LowOpenDisk(Path,&
Handle)) !=
ESUCCESS) {
00860
AlDeallocateHeap(SectorBuffer);
00861
AlDeallocateHeap(DriveInfo);
00862
return(status);
00863 }
00864
00865 mbr =
TRUE;
00866 Entry = 0;
00867 BootSector = 0;
00868 ExtendedStart = 0;
00869 status =
ESUCCESS;
00870
00871
do {
00872
00873
if((status =
LowReadSectors(
Handle,bps,BootSector,1,SectorBuffer)) !=
ESUCCESS) {
00874
break;
00875 }
00876
00877
00878
00879
if(((
PUSHORT)SectorBuffer)[
BOOT_SIGNATURE_OFFSET] !=
BOOT_RECORD_SIGNATURE) {
00880
break;
00881 }
00882
00883 Link =
FALSE;
00884
00885
for(i=0; i<
NUM_PARTITION_TABLE_ENTRIES; i++) {
00886
00887
if(ptable[i].
PartitionType ==
SYSID_UNUSED) {
00888
00889
00890
00891 p[Entry].PartitionType =
SYSID_UNUSED;
00892 p[Entry].BootIndicator =
FALSE;
00893 p[Entry].RewritePartition =
FALSE;
00894 p[Entry].PartitionLength.QuadPart = 0;
00895 p[Entry].HiddenSectors = 0;
00896 p[Entry].StartingOffset.QuadPart = 0;
00897 p[Entry].RecognizedPartition =
FALSE;
00898
00899 }
else {
00900
00901 LARGE_INTEGER Result1, Result2;
00902
00903 p[Entry].PartitionType = ptable[i].
PartitionType;
00904 p[Entry].BootIndicator = ptable[i].
ActiveFlag;
00905 p[Entry].RewritePartition =
FALSE;
00906 p[Entry].PartitionLength.QuadPart = UInt32x32To64(
PLENGTH(ptable + i),bps);
00907
00908
00909
00910
00911
00912
00913
00914
00915 p[Entry].HiddenSectors =
PSTART(ptable + i);
00916 Result1.QuadPart = UInt32x32To64(
PSTART(ptable + i),bps);
00917 Result2.QuadPart = UInt32x32To64(BootSector,bps);
00918 p[Entry].StartingOffset.QuadPart = Result1.QuadPart + Result2.QuadPart;
00919
00920 p[Entry].RecognizedPartition =
TRUE;
00921
00922
if(p[Entry].PartitionType ==
SYSID_EXTENDED) {
00923
00924 Link =
TRUE;
00925
00926
if(mbr) {
00927 mbr =
FALSE;
00928 BootSector =
PSTART(ptable + i);
00929 ExtendedStart = BootSector;
00930 }
else {
00931 BootSector = ExtendedStart +
PSTART(ptable + i);
00932 }
00933 }
00934 }
00935 Entry++;
00936 }
00937 }
while(Link);
00938
00939
LowCloseDisk(
Handle);
00940
00941
AlDeallocateHeap(SectorBuffer);
00942
00943
if(status !=
ESUCCESS) {
00944
00945
AlDeallocateHeap(DriveInfo);
00946
return(status);
00947 }
00948
00949
00950
00951
00952 DriveInfo =
AlReallocateHeap(DriveInfo,
00953
sizeof(DRIVE_LAYOUT_INFORMATION)
00954 + ((Entry - 1) *
sizeof(PARTITION_INFORMATION))
00955 );
00956
00957 DriveInfo->PartitionCount = Entry;
00958
00959 *DriveLayout = DriveInfo;
00960
00961
return(
ESUCCESS);
00962 }
00963
00964
00965
00966
00967
00968
00969 typedef struct _tagCHS {
00970 USHORT StartCylinder;
00971 UCHAR
StartHead;
00972 UCHAR
StartSector;
00973 USHORT EndCylinder;
00974 UCHAR
EndHead;
00975 UCHAR
EndSector;
00976 }
CHS, *
PCHS;
00977
00978
00979
VOID
00980 CalculateCHSVals(
00981 IN ULONG Start,
00982 IN ULONG Size,
00983 IN ULONG spt,
00984 IN ULONG h,
00985 OUT PCHS chs
00986 )
00987 {
00988 ULONG spc = spt * h;
00989 ULONG r;
00990 ULONG
End =
Start+
Size-1;
00991
00992 chs->StartCylinder = (
USHORT)(
Start/spc);
00993 r =
Start % spc;
00994 chs->StartHead = (UCHAR)(r / spt);
00995 chs->StartSector = (UCHAR)((r % spt) + 1);
00996
00997 chs->EndCylinder = (
USHORT)(
End/spc);
00998 r =
End % spc;
00999 chs->EndHead = (UCHAR)(r / spt);
01000 chs->EndSector = (UCHAR)((r % spt) + 1);
01001 }
01002
01003
01004
VOID
01005 SetPartitionTableEntry(
01006 IN OUT
PPARTITION_DESCRIPTOR p,
01007 IN UCHAR Active,
01008 IN UCHAR SysID,
01009 IN ULONG RelativeSector,
01010 IN ULONG SectorCount,
01011 IN PCHS chs
01012 )
01013 {
01014
01015
01016 p->ActiveFlag =
Active;
01017 p->PartitionType = SysID;
01018
01019
if(chs) {
01020 p->StartingTrack = chs->StartHead;
01021 p->EndingTrack = chs->EndHead;
01022 }
else {
01023 p->StartingTrack = 0;
01024 p->EndingTrack = 0;
01025 }
01026
01027
if(chs) {
01028
01029
01030
01031 p->StartingCylinderLsb = (chs->StartSector & 0x3f) | ((chs->StartCylinder >> 2) & 0xc0);
01032 p->StartingCylinderMsb = (UCHAR)chs->StartCylinder;
01033
01034 p->EndingCylinderLsb = (chs->EndSector & 0x3f) | ((chs->EndCylinder >> 2) & 0xc0);
01035 p->EndingCylinderMsb = (UCHAR)chs->EndCylinder;
01036
01037 }
else {
01038
01039 p->StartingCylinderLsb = 0;
01040 p->StartingCylinderMsb = 0;
01041
01042 p->EndingCylinderLsb = 0;
01043 p->EndingCylinderMsb = 0;
01044 }
01045
01046
01047
01048 p->StartingSectorLsb0 = (UCHAR)(RelativeSector >> 0 );
01049 p->StartingSectorLsb1 = (UCHAR)(RelativeSector >> 8 );
01050 p->StartingSectorMsb0 = (UCHAR)(RelativeSector >> 16);
01051 p->StartingSectorMsb1 = (UCHAR)(RelativeSector >> 24);
01052
01053 p->PartitionLengthLsb0 = (UCHAR)(SectorCount >> 0 );
01054 p->PartitionLengthLsb1 = (UCHAR)(SectorCount >> 8 );
01055 p->PartitionLengthMsb0 = (UCHAR)(SectorCount >> 16);
01056 p->PartitionLengthMsb1 = (UCHAR)(SectorCount >> 24);
01057 }
01058
01059
01060 #define ZeroPartitionTableEntry(p) SetPartitionTableEntry(p,0,SYSID_UNUSED,0,0,NULL);
01061
01062
VOID
01063 ZeroPartitionTable(
01064
PPARTITION_DESCRIPTOR PartitionTable
01065 )
01066 {
01067 ULONG i;
01068
01069
for(i=0; i<
ENTRIES_PER_BOOTSECTOR; i++) {
01070
ZeroPartitionTableEntry(PartitionTable+i);
01071 }
01072 }
01073
01074
01075
ARC_STATUS
01076 LowSetDiskLayout(
01077 IN PCHAR Path,
01078 IN PDRIVE_LAYOUT_INFORMATION DriveLayout
01079 )
01080 {
01081
ARC_STATUS status;
01082 ULONG
dummy,bps,spt,h;
01083 PCHAR SectorBuffer;
01084 ULONG
Handle;
01085
PPARTITION_DESCRIPTOR PartitionTable;
01086 PPARTITION_INFORMATION p;
01087 BOOLEAN mbr =
TRUE,Update;
01088 ULONG BootSector = 0,ExtendedPartitionStart = 0,
01089 NextBootSector;
01090 ULONG i,j,UsedCount;
01091
CHS chs;
01092
01093
01094
#define SECCNT(l) ((ULONG)(((ULONGLONG)l.QuadPart)/((ULONGLONG)bps)))
01095
01096
01097
ASRT(DriveLayout->PartitionCount);
01098
01099
if((status =
LowGetDriveGeometry(Path,&
dummy,&bps,&spt,&h)) !=
ESUCCESS) {
01100
return(status);
01101 }
01102
01103
01104
01105
if((SectorBuffer =
AlAllocateHeap(bps)) ==
NULL) {
01106
return(
ENOMEM);
01107 }
01108
01109
01110
01111
01112
01113 RtlMoveMemory(SectorBuffer,x86BootCode,
min(X86BOOTCODE_SIZE,bps));
01114
01115 ((
PUSHORT)SectorBuffer)[
BOOT_SIGNATURE_OFFSET] =
BOOT_RECORD_SIGNATURE;
01116 PartitionTable = (
PPARTITION_DESCRIPTOR)(&(((
PUSHORT)SectorBuffer)[
PARTITION_TABLE_OFFSET]));
01117
01118
if((status =
LowOpenDisk(Path,&
Handle)) !=
ESUCCESS) {
01119
AlDeallocateHeap(SectorBuffer);
01120
return(status);
01121 }
01122
01123
ASRT(!(DriveLayout->PartitionCount %
ENTRIES_PER_BOOTSECTOR));
01124
for(i=0; i<DriveLayout->PartitionCount; i+=
ENTRIES_PER_BOOTSECTOR) {
01125
01126 Update =
FALSE;
01127 UsedCount = 0;
01128
01129
ZeroPartitionTable(PartitionTable);
01130
01131
for(j=0; j<
ENTRIES_PER_BOOTSECTOR; j++) {
01132
01133 p = &DriveLayout->PartitionEntry[i+j];
01134
01135
switch(p->PartitionType) {
01136
case SYSID_UNUSED:
01137
ZeroPartitionTableEntry(PartitionTable+j);
01138
break;
01139
01140
case SYSID_EXTENDED:
01141 NextBootSector =
SECCNT(p->StartingOffset);
01142
CalculateCHSVals(NextBootSector,
SECCNT(p->PartitionLength),spt,h,&chs);
01143
SetPartitionTableEntry(PartitionTable+j,
01144 p->BootIndicator,
01145
SYSID_EXTENDED,
01146
SECCNT(p->StartingOffset) - ExtendedPartitionStart,
01147
SECCNT(p->PartitionLength),
01148 &chs
01149 );
01150
if(mbr) {
01151 mbr =
FALSE;
01152 ExtendedPartitionStart = NextBootSector;
01153 }
01154
break;
01155
01156
default:
01157
CalculateCHSVals(
SECCNT(p->StartingOffset),
SECCNT(p->PartitionLength),spt,h,&chs);
01158
SetPartitionTableEntry(PartitionTable+j,
01159 p->BootIndicator,
01160 p->
PartitionType,
01161
SECCNT(p->StartingOffset) - BootSector,
01162
SECCNT(p->PartitionLength),
01163 &chs
01164 );
01165
break;
01166 }
01167 Update = Update || p->RewritePartition;
01168
01169
if(p->PartitionType !=
SYSID_UNUSED) {
01170 UsedCount++;
01171 }
01172 }
01173
if(Update || !UsedCount) {
01174
if((status =
LowWriteSectors(
Handle,bps,BootSector,1,SectorBuffer)) !=
ESUCCESS) {
01175
LowCloseDisk(
Handle);
01176
AlDeallocateHeap(SectorBuffer);
01177
return(status);
01178 }
01179 }
01180 BootSector = NextBootSector;
01181 }
01182
01183
LowCloseDisk(
Handle);
01184
AlDeallocateHeap(SectorBuffer);
01185
return(
ESUCCESS);
01186 }