test: fmtexp.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# fmtexp.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Classes

struct | UNALIGNED_SECTOR_ZERO

## Defines

#define | READ_SIZE 65536
#define | CSEC_FAT32MEG 65536
#define | CSEC_FAT16BIT 32680
#define | SYSID_FAT12BIT 1
#define | SYSID_FAT16BIT 4
#define | SYSID_FAT32MEG 6
#define | MIN_CLUS_BIG 4085
#define | MAX_CLUS_BIG 65525

## Typedefs

typedef * | PUNALIGNED_SECTOR_ZERO

## Functions

ARC_STATUS | FmtIsFatPartition (IN ULONG PartitionId, IN ULONG SectorSize, OUT PBOOLEAN IsFatPartition)
ARC_STATUS | FmtIsFat (IN PCHAR PartitionPath, OUT PBOOLEAN IsFatPartition)
USHORT | ComputeSecPerCluster (IN ULONG NumSectors, IN BOOLEAN SmallFat)
ULONG | ComputeNewSerialNumber (IN ULONG Seed)
VOID | EditFat (IN USHORT ClusterNumber, IN USHORT ClusterEntry, IN OUT PUCHAR Fat, IN BOOLEAN SmallFat)
ARC_STATUS | FmtFillFormatBuffer (IN ULONG NumberOfSectors, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN ULONG NumberOfHiddenSectors, OUT PVOID FormatBuffer, IN ULONG FormatBufferSize, OUT PULONG SuperAreaSize, IN ULONG TimeSeed, IN PULONG BadSectorsList, IN ULONG NumberOfBadSectors)
ARC_STATUS | FmtVerifySectors (IN ULONG PartitionId, IN ULONG NumberOfSectors, IN ULONG SectorSize, OUT PULONG *BadSectorsList, OUT PULONG NumberOfBadSectors)
ARC_STATUS | FmtFatFormat (IN PCHAR PartitionPath, IN ULONG HiddenSectorCount)
ARC_STATUS | FmtQueryFatPartitionList (OUT PCHAR **FatPartitionList, OUT PULONG ListLength)
ARC_STATUS | FmtFreeFatPartitionList (IN OUT PCHAR *FatPartitionList, IN ULONG ListLength)

## Define Documentation

#define CSEC_FAT16BIT 32680

| Definition at line 32 of file fmtexp.c. Referenced by FmtFillFormatBuffer().

#define CSEC_FAT32MEG 65536

| Definition at line 31 of file fmtexp.c. Referenced by FmtFillFormatBuffer().

#define MAX_CLUS_BIG 65525

| Definition at line 37 of file fmtexp.c. Referenced by ComputeSecPerCluster().

#define MIN_CLUS_BIG 4085

| Definition at line 36 of file fmtexp.c. Referenced by ComputeSecPerCluster().

#define READ_SIZE 65536

| Definition at line 4 of file fmtexp.c. Referenced by FmtVerifySectors().

#define SYSID_FAT12BIT 1

| Definition at line 33 of file fmtexp.c. Referenced by FmtFillFormatBuffer().

#define SYSID_FAT16BIT 4

| Definition at line 34 of file fmtexp.c. Referenced by FmtFillFormatBuffer().

#define SYSID_FAT32MEG 6

| Definition at line 35 of file fmtexp.c. Referenced by FmtFillFormatBuffer().

## Typedef Documentation

typedef * PUNALIGNED_SECTOR_ZERO

| Referenced by FmtFillFormatBuffer().

## Function Documentation

ULONG ComputeNewSerialNumber | ( | IN ULONG | Seed | ) |

Definition at line 190 of file fmtexp.c.

References Seed.

Referenced by FmtFillFormatBuffer().

    00195                    :
    00196
    00197     This routine computes a new serial number for a volume.
    00198
    00199 Arguments:
    00200
    00201     Seed    - Supplies a seed for the serial number.
    00202
    00203 Return Value:
    00204
    00205     A new volume serial number.
    00206
    00207 --*/
    00208 {
    00209     PUCHAR  p;
    00210     ULONG   i;
    00211
    00212     p = (PUCHAR) &Seed;
    00213
    00214     for (i = 0; i < sizeof(ULONG); i++) {
    00215
    00216         Seed += p[i];
    00217         Seed = (Seed >> 2) + (Seed << 30);
    00218     }
    00219
    00220     return Seed;
    00221 }

USHORT ComputeSecPerCluster | ( | IN ULONG | NumSectors,
|  | IN BOOLEAN | SmallFat
| ) |

Definition at line 146 of file fmtexp.c.

References max, MAX_CLUS_BIG, MIN_CLUS_BIG, and USHORT.

Referenced by FmtFillFormatBuffer().

    00152                    :
    00153
    00154     This routine computes the number of sectors per cluster.
    00155
    00156 Arguments:
    00157
    00158     NumSectors  - Supplies the number of sectors on the disk.
    00159     SmallFat    - Supplies whether or not the FAT should be small.
    00160
    00161 Return Value:
    00162
    00163     The number of sectors per cluster necessary.
    00164
    00165 --*/
    00166 {
    00167     ULONG   threshold;
    00168     USHORT  sec_per_clus;
    00169     USHORT  min_sec_per_clus;
    00170
    00171     threshold = SmallFat ? MIN_CLUS_BIG : MAX_CLUS_BIG;
    00172     sec_per_clus = 1;
    00173
    00174     while (NumSectors >= threshold) {
    00175         sec_per_clus *= 2;
    00176         threshold *= 2;
    00177     }
    00178
    00179     if (SmallFat) {
    00180         min_sec_per_clus = 8;
    00181     } else {
    00182         min_sec_per_clus = 4;
    00183     }
    00184
    00185     return max(sec_per_clus, min_sec_per_clus);
    00186 }

VOID EditFat | ( | IN USHORT | ClusterNumber,
|  | IN USHORT | ClusterEntry,
|  | IN OUT PUCHAR | Fat,
|  | IN BOOLEAN | SmallFat
| ) |

Definition at line 225 of file fmtexp.c.

References n, and PUSHORT.

Referenced by FmtFillFormatBuffer().

    00233                    :
    00234
    00235     This routine edits the FAT entry 'ClusterNumber' with 'ClusterEntry'.
    00236
    00237 Arguments:
    00238
    00239     ClusterNumber   - Supplies the number of the cluster to edit.
    00240     ClusterEntry    - Supplies the new value for that cluster number.
    00241     Fat             - Supplies the FAT to edit.
    00242     SmallFat        - Supplies whether or not the FAT is small.
    00243
    00244 Return Value:
    00245
    00246     None.
    00247
    00248 --*/
    00249 {
    00250     ULONG   n;
    00251
    00252     if (SmallFat) {
    00253
    00254         n = ClusterNumber*3;
    00255         if (n%2) {
    00256                 Fat[n/2] = (UCHAR) ((Fat[n/2]&0x0F) | ((ClusterEntry&0x000F)<<4));
    00257             Fat[n/2 + 1] = (UCHAR) ((ClusterEntry&0x0FF0)>>4);
    00258         } else {
    00259             Fat[n/2] = (UCHAR) (ClusterEntry&0x00FF);
    00260                 Fat[n/2 + 1] = (UCHAR) ((Fat[n/2 + 1]&0xF0) |
    00261                                     ((ClusterEntry&0x0F00)>>8));
    00262         }
    00263
    00264     } else {
    00265
    00266         ((PUSHORT) Fat)[ClusterNumber] = ClusterEntry;
    00267
    00268     }
    00269 }

ARC_STATUS FmtFatFormat | ( | IN PCHAR | PartitionPath,
|  | IN ULONG | HiddenSectorCount
| ) |

Definition at line 601 of file fmtexp.c.

References AllocateMemory, ARC_STATUS, ArcClose, ArcGetTime, ArcOpen, ArcOpenReadWrite, ENOMEM, ESUCCESS, FmtFillFormatBuffer(), FmtVerifySectors(), FreeMemory, LowGetPartitionGeometry(), LowWriteSectors(), and NULL.

Referenced by DoMakePartitionSystemPartition(), and DoSystemPartitionCreate().

    00607                    :
    00608
    00609     This routine does a FAT format on the given partition.
    00610
    00611 Arguments:
    00612
    00613     PartitionPath   - Supplies a path to the partition to format.
    00614
    00615 Return Value:
    00616
    00617     LowGetPartitionGeometry, ArcOpen,
    00618     FmtVerifySectors, FmtFillFormatBuffer, LowWriteSectors,
    00619     ArcClose, ENOMEM
    00620
    00621 --*/
    00622 {
    00623     ULONG           num_sectors;
    00624     ULONG           sector_size;
    00625     ULONG           sec_per_track;
    00626     ULONG           heads;
    00627     ULONG           hidden_sectors;
    00628     PULONG          bad_sectors;
    00629     ULONG           num_bad_sectors;
    00630     PVOID           format_buffer;
    00631     ULONG           max_sec_per_sa;
    00632     ULONG           super_area_size;
    00633     ARC_STATUS      r;
    00634     ULONG           partition_id;
    00635     ULONG           time_seed;
    00636     PTIME_FIELDS    ptime_fields;
    00637
    00638
    00639     r = LowGetPartitionGeometry(PartitionPath, &num_sectors,
    00640                                 &sector_size, &sec_per_track, &heads);
    00641
    00642     if (r != ESUCCESS) {
    00643         return r;
    00644     }
    00645
    00646     hidden_sectors = HiddenSectorCount;
    00647
    00648     r = ArcOpen(PartitionPath, ArcOpenReadWrite, &partition_id);
    00649
    00650     if (r != ESUCCESS) {
    00651         return r;
    00652     }
    00653
    00654     bad_sectors = NULL;
    00655
    00656     r = FmtVerifySectors(partition_id, num_sectors, sector_size,
    00657                          &bad_sectors, &num_bad_sectors);
    00658
    00659     if (r != ESUCCESS) {
    00660         ArcClose(partition_id);
    00661         return r;
    00662     }
    00663
    00664     max_sec_per_sa = 1 +
    00665                      2*((2*65536 - 1)/sector_size + 1) +
    00666                      ((512*32 - 1)/sector_size + 1);
    00667
    00668     ptime_fields = ArcGetTime();
    00669
    00670     time_seed = (ptime_fields->Year - 1970)*366*24*60*60 +
    00671                 (ptime_fields->Month)*31*24*60*60 +
    00672                 (ptime_fields->Day)*24*60*60 +
    00673                 (ptime_fields->Hour)*60*60 +
    00674                 (ptime_fields->Minute)*60 +
    00675                 (ptime_fields->Second);
    00676
    00677     if (!(format_buffer = AllocateMemory(max_sec_per_sa*sector_size))) {
    00678
    00679         if (bad_sectors) {
    00680             FreeMemory(bad_sectors);
    00681         }
    00682         ArcClose(partition_id);
    00683         return ENOMEM;
    00684     }
    00685
    00686     r = FmtFillFormatBuffer(num_sectors,
    00687                             sector_size,
    00688                             sec_per_track,
    00689                             heads,
    00690                             hidden_sectors,
    00691                             format_buffer,
    00692                             max_sec_per_sa*sector_size,
    00693                             &super_area_size,
    00694                             time_seed,
    00695                             bad_sectors,
    00696                             num_bad_sectors);
    00697
    00698
    00699     if (bad_sectors) {
    00700         FreeMemory(bad_sectors);
    00701     }
    00702
    00703     if (r != ESUCCESS) {
    00704         ArcClose(partition_id);
    00705         FreeMemory(format_buffer);
    00706         return r;
    00707     }
    00708
    00709     r = LowWriteSectors(partition_id, sector_size, 0,
    00710                         super_area_size/sector_size, format_buffer);
    00711
    00712     FreeMemory(format_buffer);
    00713
    00714     if (r != ESUCCESS) {
    00715         ArcClose(partition_id);
    00716         return r;
    00717     }
    00718
    00719     return ArcClose(partition_id);
    00720 }

ARC_STATUS FmtFillFormatBuffer | ( | IN ULONG | NumberOfSectors,
|  | IN ULONG | SectorSize,
|  | IN ULONG | SectorsPerTrack,
|  | IN ULONG | NumberOfHeads,
|  | IN ULONG | NumberOfHiddenSectors,
|  | OUT PVOID | FormatBuffer,
|  | IN ULONG | FormatBufferSize,
|  | OUT PULONG | SuperAreaSize,
|  | IN ULONG | TimeSeed,
|  | IN PULONG | BadSectorsList,
|  | IN ULONG | NumberOfBadSectors
| ) |

Definition at line 273 of file fmtexp.c.

References ComputeNewSerialNumber(), ComputeSecPerCluster(), CSEC_FAT16BIT, CSEC_FAT32MEG, E2BIG, EditFat(), EINVAL, EIO, ENOMEM, ESUCCESS, PUNALIGNED_SECTOR_ZERO, SectorSize, SYSID_FAT12BIT, SYSID_FAT16BIT, SYSID_FAT32MEG, and USHORT.

Referenced by FmtFatFormat().

    00288                    :
    00289
    00290     This routine computes a FAT super area based on the disk size,
    00291     disk geometry, and bad sectors of the volume.
    00292
    00293 Arguments:
    00294
    00295     NumberOfSectors         - Supplies the number of sectors on the volume.
    00296     SectorSize              - Supplies the number of bytes per sector.
    00297     SectorsPerTrack         - Supplies the number of sectors per track.
    00298     NumberOfHeads           - Supplies the number of heads.
    00299     NumberOfHiddenSectors   - Supplies the number of hidden sectors.
    00300     FormatBuffer            - Returns the super area for the volume.
    00301     FormatBufferSize        - Supplies the number of bytes in the supplied
    00302                                 buffer.
    00303     SuperAreaSize           - Returns the number of bytes in the super area.
    00304     TimeSeed                - Supplies a time seed for serial number.
    00305     BadSectorsList          - Supplies the list of bad sectors on the volume.
    00306     NumberOfBadSectors      - Supplies the number of bad sectors in the list.
    00307
    00308 Return Value:
    00309
    00310     ENOMEM  - The buffer wasn't big enough.
    00311     E2BIG   - The disk is too large to be formatted.
    00312     EIO     - There is a bad sector in the super area.
    00313     EINVAL  - There is a bad sector off the end of the disk.
    00314     ESUCCESS
    00315
    00316 --*/
    00317 {
    00318     PUNALIGNED_SECTOR_ZERO  psecz;
    00319     PUCHAR                  puchar;
    00320     USHORT                  tmp_ushort;
    00321     ULONG                   tmp_ulong;
    00322     BOOLEAN                 small_fat;
    00323     ULONG                   num_sectors;
    00324     ULONG                   partition_id;
    00325     ULONG                   sec_per_fat;
    00326     ULONG                   sec_per_root;
    00327     ULONG                   sec_per_clus;
    00328     ULONG                   i;
    00329     ULONG                   sec_per_sa;
    00330
    00331
    00332     // First memset the buffer to all zeros;
    00333     memset(FormatBuffer, 0, (unsigned int) FormatBufferSize);
    00334
    00335
    00336     // Make sure that there's enough room for the BPB.
    00337
    00338     if (!FormatBuffer || FormatBufferSize < SectorSize) {
    00339         return ENOMEM;
    00340     }
    00341
    00342     // Compute the number of sectors on disk.
    00343     num_sectors = NumberOfSectors;
    00344
    00345     // Compute the partition identifier.
    00346     partition_id = num_sectors < CSEC_FAT16BIT ? SYSID_FAT12BIT :
    00347                    num_sectors < CSEC_FAT32MEG ? SYSID_FAT16BIT :
    00348                                                  SYSID_FAT32MEG;
    00349
    00350     // Compute whether or not to have a big or small FAT.
    00351     small_fat = (BOOLEAN) (partition_id == SYSID_FAT12BIT);
    00352
    00353
    00354     psecz = (PUNALIGNED_SECTOR_ZERO) FormatBuffer;
    00355     puchar = (PUCHAR) FormatBuffer;
    00356
    00357     // Set up the jump instruction.
    00358     psecz->IntelNearJumpCommand[0] = 0xEB;
    00359     tmp_ushort = 0x903C;
    00360     memcpy(psecz->BootStrapJumpOffset, &tmp_ushort, sizeof(USHORT));
    00361
    00362     // Set up the OEM data.
    00363     memcpy(psecz->OemData, "WINNT1.0", 8); // BUGBUG norbertk
    00364
    00365     // Set up the bytes per sector.
    00366     tmp_ushort = (USHORT) SectorSize;
    00367     memcpy(psecz->BytesPerSector, &tmp_ushort, sizeof(USHORT));
    00368
    00369     // Set up the number of sectors per cluster.
    00370     sec_per_clus = ComputeSecPerCluster(num_sectors, small_fat);
    00371     if (sec_per_clus > 128) {
    00372
    00373         // The disk is too large to be formatted.
    00374         return E2BIG;
    00375     }
    00376     psecz->SectorsPerCluster[0] = (UCHAR) sec_per_clus;
    00377
    00378     // Set up the number of reserved sectors.
    00379     tmp_ushort = 1;
    00380     memcpy(psecz->ReservedSectors, &tmp_ushort, sizeof(USHORT));
    00381
    00382     // Set up the number of FATs.
    00383     psecz->Fats[0] = 2;
    00384
    00385     // Set up the number of root entries and number of sectors for the root.
    00386     tmp_ushort = 512;
    00387     memcpy(psecz->RootEntries, &tmp_ushort, sizeof(USHORT));
    00388     sec_per_root = (512*32 - 1)/SectorSize + 1;
    00389
    00390     // Set up the number of sectors.
    00391     if (num_sectors >= 1<<16) {
    00392         tmp_ushort = 0;
    00393         tmp_ulong = num_sectors;
    00394     } else {
    00395         tmp_ushort = (USHORT) num_sectors;
    00396         tmp_ulong = 0;
    00397     }
    00398     memcpy(psecz->Sectors, &tmp_ushort, sizeof(USHORT));
    00399     memcpy(psecz->LargeSectors, &tmp_ulong, sizeof(ULONG));
    00400
    00401     // Set up the media byte.
    00402     psecz->Media[0] = 0xF8;
    00403
    00404     // Set up the number of sectors per FAT.
    00405     if (small_fat) {
    00406         sec_per_fat = num_sectors/(2 + SectorSize*sec_per_clus*2/3);
    00407     } else {
    00408         sec_per_fat = num_sectors/(2 + SectorSize*sec_per_clus/2);
    00409     }
    00410     sec_per_fat++;
    00411     tmp_ushort = (USHORT) sec_per_fat;
    00412     memcpy(psecz->SectorsPerFat, &tmp_ushort, sizeof(USHORT));
    00413
    00414     // Set up the number of sectors per track.
    00415     tmp_ushort = (USHORT) SectorsPerTrack;
    00416     memcpy(psecz->SectorsPerTrack, &tmp_ushort, sizeof(USHORT));
    00417
    00418     // Set up the number of heads.
    00419     tmp_ushort = (USHORT) NumberOfHeads;
    00420     memcpy(psecz->Heads, &tmp_ushort, sizeof(USHORT));
    00421
    00422     // Set up the number of hidden sectors.
    00423     memcpy(psecz->HiddenSectors, &NumberOfHiddenSectors, sizeof(ULONG));
    00424
    00425     // Set up the physical drive number.
    00426     psecz->PhysicalDrive[0] = 0x80;
    00427
    00428     // Set up the BPB signature.
    00429     psecz->Signature[0] = 0x29;
    00430
    00431     // Set up the serial number.
    00432     tmp_ulong = ComputeNewSerialNumber(TimeSeed);
    00433     memcpy(psecz->SerialNumber, &tmp_ulong, sizeof(ULONG));
    00434
    00435     // Set up the system id.
    00436     memcpy(psecz->SystemIdText, "FAT     ", 8);
    00437
    00438     // Set up the boot signature.
    00439     puchar[510] = 0x55;
    00440     puchar[511] = 0xAA;
    00441
    00442
    00443     // Now make sure that the buffer has enough room for both of the
    00444     // FATs and the root directory.
    00445
    00446     sec_per_sa = 1 + 2*sec_per_fat + sec_per_root;
    00447     *SuperAreaSize = SectorSize*sec_per_sa;
    00448     if (*SuperAreaSize > FormatBufferSize) {
    00449         return ENOMEM;
    00450     }
    00451
    00452
    00453     // Set up the first FAT.
    00454
    00455     puchar[SectorSize] = 0xF8;
    00456     puchar[SectorSize + 1] = 0xFF;
    00457     puchar[SectorSize + 2] = 0xFF;
    00458
    00459     if (!small_fat) {
    00460         puchar[SectorSize + 3] = 0xFF;
    00461     }
    00462
    00463
    00464     for (i = 0; i < NumberOfBadSectors; i++) {
    00465
    00466         if (BadSectorsList[i] < sec_per_sa) {
    00467             // There's a bad sector in the super area.
    00468             return EIO;
    00469         }
    00470
    00471         if (BadSectorsList[i] >= num_sectors) {
    00472             // Bad sector out of range.
    00473             return EINVAL;
    00474         }
    00475
    00476         // Compute the bad cluster number;
    00477         tmp_ushort = (USHORT)
    00478                      ((BadSectorsList[i] - sec_per_sa)/sec_per_clus + 2);
    00479
    00480         EditFat(tmp_ushort, (USHORT) 0xFFF7, &puchar[SectorSize], small_fat);
    00481     }
    00482
    00483
    00484     // Copy the first FAT onto the second.
    00485
    00486     memcpy(&puchar[SectorSize*(1 + sec_per_fat)],
    00487            &puchar[SectorSize],
    00488            (unsigned int) SectorSize*sec_per_fat);
    00489
    00490     return ESUCCESS;
    00491 }

ARC_STATUS FmtFreeFatPartitionList | ( | IN OUT PCHAR * | FatPartitionList,
|  | IN ULONG | ListLength
| ) |

Definition at line 919 of file fmtexp.c.

References LowFreePathList().

    00925                    :
    00926
    00927     This routine frees up the heap space taken by the FAT partition
    00928     list.
    00929
    00930 Arguments:
    00931
    00932     FatPartitionList    - Supplies the buffer to free.
    00933     ListLength          - Supplies the buffer length.
    00934
    00935 Return Value:
    00936
    00937     LowFreePathList
    00938
    00939 --*/
    00940 {
    00941     return LowFreePathList(FatPartitionList, ListLength);
    00942 }
    }

ARC_STATUS FmtIsFat | ( | IN PCHAR | PartitionPath,
|  | OUT PBOOLEAN | IsFatPartition
| ) |

Definition at line 93 of file fmtexp.c.

References ARC_STATUS, ArcClose, ArcOpen, ArcOpenReadOnly, ESUCCESS, FmtIsFatPartition(), and LowGetPartitionGeometry().

Referenced by DoMakePartitionSystemPartition(), and FmtQueryFatPartitionList().

    00099                    :
    00100
    00101     This routine computes whether or not the given partition is a FAT
    00102     partition.
    00103
    00104 Arguments:
    00105
    00106     PartitionPath   - Supplies a path to the partition.
    00107     IsFatPartition  - Returns whether or not the partition is FAT.
    00108
    00109 Return Value:
    00110
    00111     ArcOpen, ArcClose, LowGetPartitionGeometry, FmtIsFatPartition
    00112
    00113 --*/
    00114 {
    00115     ULONG       partition_id;
    00116     ARC_STATUS  r;
    00117     ULONG       total_sectors, sector_size, sec_per_track, heads;
    00118
    00119     r = LowGetPartitionGeometry(PartitionPath, &total_sectors, &sector_size,
    00120                                 &sec_per_track, &heads);
    00121
    00122     if (r != ESUCCESS) {
    00123         return r;
    00124     }
    00125
    00126     r = ArcOpen(PartitionPath, ArcOpenReadOnly, &partition_id);
    00127
    00128     if (r != ESUCCESS) {
    00129         return r;
    00130     }
    00131
    00132     r = FmtIsFatPartition(partition_id, sector_size, IsFatPartition);
    00133
    00134     if (r != ESUCCESS) {
    00135         ArcClose(partition_id);
    00136         return r;
    00137     }
    00138
    00139     return ArcClose(partition_id);
    00140 }

ARC_STATUS FmtIsFatPartition | ( | IN ULONG | PartitionId,
|  | IN ULONG | SectorSize,
|  | OUT PBOOLEAN | IsFatPartition
| ) |

Definition at line 42 of file fmtexp.c.

References AllocateMemory, ARC_STATUS, Buffer, ENOMEM, ESUCCESS, FreeMemory, LowReadSectors(), and SectorSize.

Referenced by FmtIsFat().

    00049                    :
    00050
    00051     This routine computes whether or not the given partition is a FAT
    00052     partition.
    00053
    00054 Arguments:
    00055
    00056     VolumeId        - Supplies the volume to check.
    00057     SectorSize      - Supplies the number of bytes per sector.
    00058     IsFatPartition  - Returns whether or not the partition is FAT.
    00059
    00060 Return Value:
    00061
    00062     LowReadSectors, ENOMEM, ESUCCESS
    00063
    00064 --*/
    00065 {
    00066     PUCHAR      Buffer;
    00067     ARC_STATUS  r;
    00068
    00069     if (!(Buffer = AllocateMemory(SectorSize*2))) {
    00070         return ENOMEM;
    00071     }
    00072
    00073     r = LowReadSectors(PartitionId, SectorSize, 0, 2, Buffer);
    00074
    00075     if (r != ESUCCESS) {
    00076         FreeMemory(Buffer);
    00077         return r;
    00078     }
    00079
    00080     *IsFatPartition = Buffer[510] == 0x55 &&
    00081                       Buffer[511] == 0xAA &&
    00082                       Buffer[0x10] != 0 &&
    00083                       Buffer[0x15] == Buffer[SectorSize] &&
    00084                       Buffer[SectorSize + 1] == 0xFF &&
    00085                       Buffer[SectorSize + 2] == 0xFF;
    00086
    00087     FreeMemory(Buffer);
    00088     return ESUCCESS;
    00089 }

ARC_STATUS FmtQueryFatPartitionList | ( | OUT PCHAR ** | FatPartitionList,
|  | OUT PULONG | ListLength
| ) |

Definition at line 724 of file fmtexp.c.

References AllocateMemory, ARC_STATUS, ArcClose, ArcOpen, ArcOpenReadOnly, CHAR, CONFIGURATION_TYPE, DiskPeripheral, EIO, ENOMEM, ESUCCESS, FmtIsFat(), FreeMemory, LowFreePathList(), LowQueryPathList(), NULL, sprintf(), and strlen().

    00730                    :
    00731
    00732     This routine browses the component tree for all disk peripherals
    00733     and the attempts to open partitions on all of them.  It add all
    00734     FAT partitions to the list and returns it.
    00735
    00736 Arguments:
    00737
    00738     FatPartitionList    - Returns a list of FAT partitions.
    00739     ListLength          - Returns the length of the list.
    00740
    00741 Return Value:
    00742
    00743     LowQueryPathList, ArcOpen, ArcClose, FmtIsFat, EIO, ENOMEM, ESUCCESS
    00744
    00745 --*/
    00746 {
    00747     CONFIGURATION_TYPE          config_type;
    00748     ARC_STATUS                  r;
    00749     PCHAR*                      peripheral_list;
    00750     ULONG                       peripheral_list_length;
    00751     ULONG                       i, j;
    00752     ULONG                       num_partitions;
    00753     CHAR                        partition_buf[21];
    00754     ULONG                       partition_id;
    00755     PCHAR*                      fat_partition_list;
    00756     ULONG                       fat_partition_list_length;
    00757     BOOLEAN                     is_fat;
    00758     PCHAR                       partition_name;
    00759
    00760
    00761     // First get a list of the all of the disk peripheral paths.
    00762
    00763     config_type = DiskPeripheral;
    00764     r = LowQueryPathList(NULL, &config_type, &peripheral_list,
    00765                          &peripheral_list_length);
    00766
    00767     if (r != ESUCCESS) {
    00768         return r;
    00769     }
    00770
    00771     // Now we have a list of disk peripheral paths.
    00772
    00773
    00774
    00775     // Next, count how many partitions there are.
    00776
    00777     num_partitions = 0;
    00778     for (i = 0; i < peripheral_list_length; i++) {
    00779
    00780         partition_name = AllocateMemory(strlen(peripheral_list[i]) + 21);
    00781
    00782         if (!partition_name) {
    00783             LowFreePathList(peripheral_list, peripheral_list_length);
    00784             return ENOMEM;
    00785         }
    00786
    00787         for (j = 1; ; j++) {
    00788
    00789             strcpy(partition_name, peripheral_list[i]);
    00790             sprintf(partition_buf, "partition(%d)", j);
    00791             strcat(partition_name, partition_buf);
    00792
    00793             r = ArcOpen(partition_name, ArcOpenReadOnly, &partition_id);
    00794
    00795             if (r != ESUCCESS) {
    00796                 break;
    00797             }
    00798
    00799             num_partitions++;
    00800
    00801             r = ArcClose(partition_id);
    00802
    00803             if (r != ESUCCESS) {
    00804                 LowFreePathList(peripheral_list, peripheral_list_length);
    00805                 FreeMemory(partition_name);
    00806                 return r;
    00807             }
    00808         }
    00809
    00810         FreeMemory(partition_name);
    00811     }
    00812
    00813     // 'num_partitions' indicates the number of partitions on the disk.
    00814
    00815
    00816     // Allocate a buffer for the FAT partitions list.  There can be
    00817     // no more FAT partitions then there are partitions.
    00818
    00819     fat_partition_list = (PCHAR*) AllocateMemory(num_partitions*sizeof(PCHAR));
    00820
    00821     if (!fat_partition_list) {
    00822         LowFreePathList(peripheral_list, peripheral_list_length);
    00823         return ENOMEM;
    00824     }
    00825
    00826     for (i = 0; i < num_partitions; i++) {
    00827         fat_partition_list[i] = NULL;
    00828     }
    00829
    00830     fat_partition_list_length = 0;
    00831
    00832     // 'fat_partition_list_length' indicates the number of FAT partitions.
    00833
    00834
    00835
    00836     // Now go through all of the peripherals trying all possible
    00837     // partitions on each.  Test these to see if they are FAT and
    00838     // put the FAT ones in 'fat_partitions_list'.
    00839
    00840     for (i = 0; i < peripheral_list_length; i++) {
    00841
    00842         partition_name = AllocateMemory(strlen(peripheral_list[i]) + 21);
    00843
    00844         if (!partition_name) {
    00845             LowFreePathList(peripheral_list, peripheral_list_length);
    00846             LowFreePathList(fat_partition_list, fat_partition_list_length);
    00847             return ENOMEM;
    00848         }
    00849
    00850         for (j = 1; ; j++) {
    00851
    00852             strcpy(partition_name, peripheral_list[i]);
    00853             sprintf(partition_buf, "partition(%d)", j);
    00854             strcat(partition_name, partition_buf);
    00855
    00856             r = ArcOpen(partition_name, ArcOpenReadOnly, &partition_id);
    00857
    00858             if (r != ESUCCESS) {
    00859                 break;
    00860             }
    00861
    00862             r = ArcClose(partition_id);
    00863
    00864             if (r != ESUCCESS) {
    00865                 LowFreePathList(peripheral_list, peripheral_list_length);
    00866                 LowFreePathList(fat_partition_list, fat_partition_list_length);
    00867                 FreeMemory(partition_name);
    00868                 return r;
    00869             }
    00870
    00871             r = FmtIsFat(partition_name, &is_fat);
    00872
    00873             if (r != ESUCCESS) {
    00874                 LowFreePathList(peripheral_list, peripheral_list_length);
    00875                 LowFreePathList(fat_partition_list, fat_partition_list_length);
    00876                 FreeMemory(partition_name);
    00877                 return r;
    00878             }
    00879
    00880             if (is_fat) {
    00881
    00882                 if (fat_partition_list_length == num_partitions) {
    00883                     // This can't happen.
    00884                     LowFreePathList(peripheral_list, peripheral_list_length);
    00885                     LowFreePathList(fat_partition_list, fat_partition_list_length);
    00886                     FreeMemory(partition_name);
    00887                     return EIO;
    00888                 }
    00889
    00890                 fat_partition_list[fat_partition_list_length] =
    00891                         AllocateMemory(strlen(partition_name) + 1);
    00892
    00893                 if (!fat_partition_list[fat_partition_list_length]) {
    00894                     LowFreePathList(peripheral_list, peripheral_list_length);
    00895                     LowFreePathList(fat_partition_list, fat_partition_list_length);
    00896                     FreeMemory(partition_name);
    00897                     return ENOMEM;
    00898                 }
    00899
    00900                 strcpy(fat_partition_list[fat_partition_list_length], partition_name);
    00901
    00902                 fat_partition_list_length++;
    00903             }
    00904         }
    00905
    00906         FreeMemory(partition_name);
    00907     }
    00908
    00909     LowFreePathList(peripheral_list, peripheral_list_length);
    00910
    00911     *FatPartitionList = fat_partition_list;
    00912     *ListLength = fat_partition_list_length;
    00913
    00914     return ESUCCESS;
    00915 }

ARC_STATUS FmtVerifySectors | ( | IN ULONG | PartitionId,
|  | IN ULONG | NumberOfSectors,
|  | IN ULONG | SectorSize,
|  | OUT PULONG * | BadSectorsList,
|  | OUT PULONG | NumberOfBadSectors
| ) |

Definition at line 495 of file fmtexp.c.

References AllocateMemory, AlPrint(), ARC_STATUS, ENOMEM, ESUCCESS, FreeMemory, LowReadSectors(), MSGMARGIN, READ_SIZE, ReallocateMemory, and SectorSize.

Referenced by FmtFatFormat().

    00504                    :
    00505
    00506     This routine verifies all of the sectors on the volume.
    00507     It returns a pointer to a list of bad sectors.  The pointer
    00508     will be NULL if there was an error detected.
    00509
    00510 Arguments:
    00511
    00512     PartitionId         - Supplies a handle to the partition for reading.
    00513     NumberOfSectors     - Supplies the number of partition sectors.
    00514     SectorSize          - Supplies the number of bytes per sector.
    00515     BadSectorsList      - Returns the list of bad sectors.
    00516     NumberOfBadSectors  - Returns the number of bad sectors in the list.
    00517
    00518 Return Value:
    00519
    00520     ENOMEM, ESUCCESS
    00521
    00522 --*/
    00523 {
    00524     ULONG           num_read_sec;
    00525     PVOID           read_buffer;
    00526     ULONG           i, j;
    00527     PULONG          bad_sec_buf;
    00528     ULONG           max_num_bad;
    00529     ARC_STATUS      r;
    00530     ULONG           percent;
    00531
    00532     if (!(read_buffer = AllocateMemory(READ_SIZE))) {
    00533         return ENOMEM;
    00534     }
    00535
    00536     max_num_bad = 100;
    00537     if (!(bad_sec_buf = (PULONG) AllocateMemory(max_num_bad*sizeof(ULONG)))) {
    00538         FreeMemory(read_buffer);
    00539         return ENOMEM;
    00540     }
    00541
    00542     *NumberOfBadSectors = 0;
    00543
    00544     num_read_sec = READ_SIZE/SectorSize;
    00545
    00546
    00547     percent = 1;
    00548     for (i = 0; i < NumberOfSectors; i += num_read_sec) {
    00549
    00550         if (percent != i*100/NumberOfSectors) {
    00551             percent = i*100/NumberOfSectors;
    00552             AlPrint("%s%d percent formatted.\r", MSGMARGIN, percent);
    00553         }
    00554
    00555         if (i + num_read_sec > NumberOfSectors) {
    00556             num_read_sec = NumberOfSectors - i;
    00557         }
    00558
    00559         r = LowReadSectors(PartitionId, SectorSize, i,
    00560                            num_read_sec, read_buffer);
    00561
    00562         if (r != ESUCCESS) {
    00563
    00564             for (j = 0; j < num_read_sec; j++) {
    00565
    00566                 r = LowReadSectors(PartitionId, SectorSize, i+j, 1,
    00567                                    read_buffer);
    00568
    00569                 if (r != ESUCCESS) {
    00570
    00571                     if (*NumberOfBadSectors == max_num_bad) {
    00572
    00573                         max_num_bad += 100;
    00574                         if (!(bad_sec_buf = (PULONG)
    00575                               ReallocateMemory(bad_sec_buf,
    00576                                                max_num_bad*sizeof(ULONG)))) {
    00577
    00578                             FreeMemory(read_buffer);
    00579                             FreeMemory(bad_sec_buf);
    00580                             return ENOMEM;
    00581                         }
    00582                     }
    00583
    00584                     bad_sec_buf[(*NumberOfBadSectors)++] = i + j;
    00585                 }
    00586             }
    00587         }
    00588     }
    00589
    00590     AlPrint("%s100 percent formatted.\r\n",MSGMARGIN);
    00591
    00592     *BadSectorsList = bad_sec_buf;
    00593
    00594     FreeMemory(read_buffer);
    00595
    00596     return ESUCCESS;
    00597 }