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_
|