254 lines
8.8 KiB
C
254 lines
8.8 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
cvf.hxx
|
||
|
||
Abstract:
|
||
|
||
This module contains basic declarations and definitions for
|
||
the double-space file system format. Note that more extensive
|
||
description of the file system structures may be found in
|
||
ntos\fastfat\cvf.h
|
||
|
||
Author:
|
||
|
||
Bill McJohn [BillMc] 24-September-1993
|
||
|
||
Revision History:
|
||
|
||
Adapted from utils\ufat\inc\cvf.hxx
|
||
|
||
--*/
|
||
|
||
#if !defined( _CVF_DEFN_ )
|
||
#define _CVF_DEFN_
|
||
|
||
#include "bpb.h"
|
||
|
||
// Manifest constants for fixed values on a Double Space drive:
|
||
//
|
||
CONST DoubleSpaceBytesPerSector = 512;
|
||
CONST DoubleSpaceLog2BytesPerSector = 9;
|
||
CONST DoubleSpaceSectorsPerCluster = 16;
|
||
CONST DoubleSpaceLog2SectorsPerCluster = 4;
|
||
CONST DoubleSpaceReservedSectors = 16;
|
||
CONST DoubleSpaceFats = 1;
|
||
CONST DoubleSpaceSectorsInRootDir = 32;
|
||
CONST DoubleSpaceRootEntries = 512;
|
||
CONST DoubleSpaceMediaByte = 0xf8;
|
||
CONST DoubleSpaceSectorsPerTrack = 0x11;
|
||
CONST DoubleSpaceHeads = 6;
|
||
CONST DoubleSpaceHiddenSectors = 0;
|
||
CONST DoubleSpaceReservedSectors2 = 31;
|
||
CONST DSBytesPerBitmapPage = 2048;
|
||
CONST DSSectorsPerBitmapPage = 4;
|
||
|
||
CONST ULONG EIGHT_MEG = 8 * 1024L * 1024L;
|
||
|
||
CONST DbSignatureLength = 4;
|
||
CONST UCHAR FirstDbSignature[4 /* DbSignatureLength */] = { (UCHAR)0xf8, 'D', 'R', 0 };
|
||
CONST UCHAR SecondDbSignature[4 /* DbSignatureLength */] = "MDR";
|
||
|
||
#if 0
|
||
// INLINE
|
||
ULONG
|
||
ComputeMaximumCapacity(
|
||
IN ULONG HostDriveSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function computes the maximum capacity for a compressed
|
||
volume file on a host volume of a given size.
|
||
|
||
Arguments:
|
||
|
||
HostDriveSize -- Supplies the size in bytes of the host drive.
|
||
|
||
Return Value:
|
||
|
||
The appropriate Maximum Capacity.
|
||
|
||
--*/
|
||
{
|
||
ULONG MaxCap;
|
||
|
||
if( HostDriveSize < 20 * 1024L * 1024L ) {
|
||
|
||
MaxCap = 16 * HostDriveSize;
|
||
|
||
} else if ( HostDriveSize < 64 * 1024L * 1024L ) {
|
||
|
||
MaxCap = 8 * HostDriveSize;
|
||
|
||
} else {
|
||
|
||
MaxCap = 4 * HostDriveSize;
|
||
}
|
||
|
||
if( MaxCap < 4 * 1024L * 1024L ) {
|
||
|
||
MaxCap = 4 * 1024L * 1024L;
|
||
|
||
} else if( MaxCap > 512 * 1024L * 1024L ) {
|
||
|
||
MaxCap = 512 * 1024L * 1024L;
|
||
}
|
||
|
||
return MaxCap;
|
||
}
|
||
#endif
|
||
|
||
typedef struct _PACKED_CVF_HEADER {
|
||
|
||
//
|
||
// First a typical start of a boot sector
|
||
//
|
||
|
||
UCHAR Jump[1]; // offset = 0x000 0
|
||
UCHAR JmpOffset[2];
|
||
UCHAR Oem[8]; // offset = 0x003 3
|
||
PACKED_BIOS_PARAMETER_BLOCK PackedBpb; // offset = 0x00B 11
|
||
|
||
//
|
||
// Now the DblSpace extensions
|
||
//
|
||
|
||
UCHAR CvfFatExtensionsLbnMinus1[2]; // offset = 0x024 36
|
||
UCHAR LogOfBytesPerSector[1]; // offset = 0x026 38
|
||
UCHAR DosBootSectorLbn[2]; // offset = 0x027 39
|
||
UCHAR DosRootDirectoryOffset[2]; // offset = 0x029 41
|
||
UCHAR CvfHeapOffset[2]; // offset = 0x02B 43
|
||
UCHAR CvfFatFirstDataEntry[2]; // offset = 0x02D 45
|
||
UCHAR CvfBitmap2KSize[1]; // offset = 0x02F 47
|
||
UCHAR Reserved1[2]; // offset = 0x030 48
|
||
UCHAR LogOfSectorsPerCluster[1]; // offset = 0x032 50
|
||
UCHAR Reserved2[2]; // offset = 0x033
|
||
UCHAR MinFile[4]; // offset = 0x035
|
||
UCHAR Reserved3[4]; // offset = 0x039
|
||
UCHAR Is12BitFat[1]; // offset = 0x03D 61
|
||
UCHAR CvfMaximumCapacity[2]; // offset = 0x03E 62
|
||
UCHAR StartBootCode;
|
||
|
||
} PACKED_CVF_HEADER; // sizeof = 0x040 64
|
||
typedef PACKED_CVF_HEADER *PPACKED_CVF_HEADER;
|
||
|
||
//
|
||
// For the unpacked version we'll only define the necessary field and skip
|
||
// the jump and oem fields.
|
||
//
|
||
|
||
typedef struct _CVF_HEADER {
|
||
|
||
UCHAR Jump;
|
||
USHORT JmpOffset;
|
||
|
||
UCHAR Oem[8];
|
||
BIOS_PARAMETER_BLOCK Bpb;
|
||
|
||
USHORT CvfFatExtensionsLbnMinus1;
|
||
UCHAR LogOfBytesPerSector;
|
||
USHORT DosBootSectorLbn;
|
||
USHORT DosRootDirectoryOffset;
|
||
USHORT CvfHeapOffset;
|
||
USHORT CvfFatFirstDataEntry;
|
||
UCHAR CvfBitmap2KSize;
|
||
UCHAR LogOfSectorsPerCluster;
|
||
UCHAR Is12BitFat;
|
||
ULONG MinFile;
|
||
USHORT CvfMaximumCapacity;
|
||
|
||
} CVF_HEADER;
|
||
typedef CVF_HEADER *PCVF_HEADER;
|
||
|
||
//
|
||
// Here is NT's typical routine/macro to unpack the cvf header because DOS
|
||
// doesn't bother to naturally align anything.
|
||
//
|
||
// VOID
|
||
// CvfUnpackCvfHeader (
|
||
// IN OUT PCVF_HEADER UnpackedHeader,
|
||
// IN PPACKED_CVF_HEADER PackedHeader
|
||
// );
|
||
//
|
||
|
||
#define CvfUnpackCvfHeader(UH,PH) { \
|
||
\
|
||
memcpy( &(UH)->Jump, &(PH)->Jump, 1 ); \
|
||
memcpy( &(UH)->JmpOffset, &(PH)->JmpOffset, 2 ); \
|
||
memcpy( &(UH)->Oem, &(PH)->Oem, 8 ); \
|
||
UnpackBios( &(UH)->Bpb, &(PH)->PackedBpb ); \
|
||
CopyUchar2( &(UH)->CvfFatExtensionsLbnMinus1, &(PH)->CvfFatExtensionsLbnMinus1[0] ); \
|
||
CopyUchar1( &(UH)->LogOfBytesPerSector, &(PH)->LogOfBytesPerSector[0] ); \
|
||
CopyUchar2( &(UH)->DosBootSectorLbn, &(PH)->DosBootSectorLbn[0] ); \
|
||
CopyUchar2( &(UH)->DosRootDirectoryOffset, &(PH)->DosRootDirectoryOffset[0] ); \
|
||
CopyUchar2( &(UH)->CvfHeapOffset, &(PH)->CvfHeapOffset[0] ); \
|
||
CopyUchar2( &(UH)->CvfFatFirstDataEntry, &(PH)->CvfFatFirstDataEntry[0] ); \
|
||
CopyUchar1( &(UH)->CvfBitmap2KSize, &(PH)->CvfBitmap2KSize[0] ); \
|
||
CopyUchar1( &(UH)->LogOfSectorsPerCluster, &(PH)->LogOfSectorsPerCluster[0] ); \
|
||
CopyUchar1( &(UH)->Is12BitFat, &(PH)->Is12BitFat[0] ); \
|
||
CopyUchar4( &(UH)->MinFile, &(PH)->MinFile[0] ); \
|
||
CopyUchar2( &(UH)->CvfMaximumCapacity, &(PH)->CvfMaximumCapacity[0] ); \
|
||
}
|
||
|
||
|
||
#define CvfPackCvfHeader(PH,UH) { \
|
||
\
|
||
memcpy( &(PH)->Jump, &(UH)->Jump, 1 ); \
|
||
memcpy( &(PH)->JmpOffset, &(UH)->JmpOffset, 2 ); \
|
||
memcpy( &(PH)->Oem, &(UH)->Oem, 8 ); \
|
||
PackBios( &(UH)->Bpb, &(PH)->PackedBpb, ); \
|
||
CopyUchar2( (PH)->CvfFatExtensionsLbnMinus1, &(UH)->CvfFatExtensionsLbnMinus1 ); \
|
||
CopyUchar1( (PH)->LogOfBytesPerSector, &(UH)->LogOfBytesPerSector ); \
|
||
CopyUchar2( (PH)->DosBootSectorLbn, &(UH)->DosBootSectorLbn ); \
|
||
CopyUchar2( (PH)->DosRootDirectoryOffset, &(UH)->DosRootDirectoryOffset ); \
|
||
CopyUchar2( (PH)->CvfHeapOffset, &(UH)->CvfHeapOffset ); \
|
||
CopyUchar2( (PH)->CvfFatFirstDataEntry, &(UH)->CvfFatFirstDataEntry ); \
|
||
CopyUchar1( (PH)->CvfBitmap2KSize, &(UH)->CvfBitmap2KSize ); \
|
||
CopyUchar1( (PH)->LogOfSectorsPerCluster, &(UH)->LogOfSectorsPerCluster ); \
|
||
CopyUchar1( (PH)->Is12BitFat, &(UH)->Is12BitFat ); \
|
||
CopyUchar4( (PH)->MinFile, &(UH)->MinFile ); \
|
||
CopyUchar2( (PH)->CvfMaximumCapacity, &(UH)->CvfMaximumCapacity ); \
|
||
memset( (PH)->Reserved1, 0, 2 ); \
|
||
memset( (PH)->Reserved2, 0, 2 ); \
|
||
memset( (PH)->Reserved3, 0, 4 ); \
|
||
}
|
||
|
||
|
||
//
|
||
// The CVF FAT EXTENSIONS is a table is ULONG entries. Each entry corresponds
|
||
// to a FAT cluster. The entries describe where in the CVF_HEAP to locate
|
||
// the data for the cluster. It indicates if the data is compressed and the
|
||
// length of the compressed and uncompressed form.
|
||
//
|
||
|
||
typedef struct _CVF_FAT_EXTENSIONS {
|
||
|
||
ULONG CvfHeapLbnMinus1 : 21;
|
||
ULONG Reserved : 1;
|
||
ULONG CompressedSectorLengthMinus1 : 4;
|
||
ULONG UncompressedSectorLengthMinus1 : 4;
|
||
ULONG IsDataUncompressed : 1;
|
||
ULONG IsEntryInUse : 1;
|
||
|
||
} CVF_FAT_EXTENSIONS;
|
||
typedef CVF_FAT_EXTENSIONS *PCVF_FAT_EXTENSIONS;
|
||
|
||
|
||
//
|
||
// Some sizes are fixed so we'll declare them as manifest constants
|
||
//
|
||
#define CVF_MINIMUM_DISK_SIZE (512 * 1024L)
|
||
#define CVF_FATFAILSAFE (1024L)
|
||
#define CVF_MIN_HEAP_SECTORS (60)
|
||
#define CVF_RESERVED_AREA_1_SECTOR_SIZE (1)
|
||
#define CVF_RESERVED_AREA_2_SECTOR_SIZE (31)
|
||
#define CVF_RESERVED_AREA_4_SECTOR_SIZE (2)
|
||
|
||
|
||
#endif // _CVF_DEFN_
|