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 }


Generated on Sat May 15 19:43:44 2004 for test by doxygen 1.3.7