?? msdos.c
字號(hào):
/*
Module Name:
msdos.c
Abstract:
Implements routines to process an MS-DOS partition.
*/
#include <windows.h>
#include <halether.h>
#include <nkintr.h>
#include "msdos.h"
#include "CFLoad.h"
#include "CFDisk.h"
#define DBG_VERBOSE_MSG 0
#define DBG_READFILE_MSG 0
#define DBG_FILEDIR_MSG 0
#define DBG_LOADFILE_MSG 0
#define DBG_ERROR_MSG 0
BYTE sectorBuffer[mBytesPerSector];
//BYTE fatBuffer[mMaxFATSize * mBytesPerSector];
PBYTE fatBuffer = (PBYTE) mFATLoadAddr;
PBYTE bootFileContent = (PBYTE) mMSDFileLoadAddr;
BYTE mBootFileName[mBootfileNameLength];
BYTE mBootFileExtension[mBootfileExtLength];
int sectorsPerCluster;
int reservedSectors;
int copiesOfFAT;
int rootDirEntries;
int totalSectors;
int sectorsPerFAT;
int hiddenSectors;
int partitionMap;
int partitionStart;
int partitionLength;
int partitionType;
int directoryStart;
int fatStart;
int clusterStart;
int bootFileStart;
int bootFileLength;
int currentCluster;
ULONG clusterIndex;
#if (DBG_VERBOSE_MSG | DBG_READFILE_MSG)
BOOL BootGetMemory(ULONG startAddr, ULONG length, BYTE dataSize);
#endif
// Function to read unaligned WORDs and DWORDs from a buffer.
DWORD
bytesToNum(BYTE *b, int bytes)
{
DWORD result = 0;
int i;
for(i=0; i < bytes; i++)
result |= b[i] << (i << 3);
return result;
}
// Function to compute the next cluster of a file based on table lookup.
int
getNextCluster(int cluster)
{
int temp;
int next;
if (partitionType == mFAT16Type || partitionType == mDOS32MegType)
{
next = bytesToNum(fatBuffer + (cluster << 1), 2);
}
else if (partitionType == mFAT12Type)
{
temp = cluster * 3;
next = bytesToNum(fatBuffer + (temp >> 1), 2);
if (temp & 0x0001)
next >>= 4;
next &= 0xFFF;
}
else
{
return 0;
}
return next;
}
// Read a cluster into the specified buffer.
void
readCluster(int cluster, BYTE *p)
{
int i;
int sector;
sector = clusterStart + (cluster - 2) * sectorsPerCluster;
for(i=0; i < sectorsPerCluster; i++)
{
CFReadSector(sector + i, p);
// EdbgOutputDebugString("CF Read Sector = 0x%x\n\r", sector+i);
p += mBytesPerSector;
}
}
// Scans the partition map looking for the first bootable partition.
BOOL
findBootPartition(void)
{
partitionType = mEmptyType;
#if 0
{
DWORD i = 0;
DWORD selection;
for (;;i++)
{
while(1)
{
selection = OEMReadDebugByte();
if (selection == 0x20)
break;
if (selection == 0x0d)
goto testend;
}
CFReadSector(i, sectorBuffer);
BootGetMemory((ULONG) sectorBuffer, mBytesPerSector, sizeof(BYTE));
}
}
testend:
#endif
CFReadSector(0, sectorBuffer);
// EdbgOutputDebugString("CF Read Sector(Find Boot Partition)\n\r");
#if DBG_VERBOSE_MSG
EdbgOutputDebugString("findBootPartition: Boot Partition at Sector 0\n\r");
BootGetMemory((ULONG) sectorBuffer, mBytesPerSector, sizeof(BYTE));
#endif
for(partitionMap = mPartitionMapOffset; partitionMap < mPartitionSigOffset; partitionMap += mPartitionMapSize)
{
if (bytesToNum(sectorBuffer + partitionMap, 1) != mPartitionBootableFlag)
continue;
partitionStart = bytesToNum(sectorBuffer + partitionMap + mPartitionStartOffset, mPartitionStartLength);
partitionLength = bytesToNum(sectorBuffer + partitionMap + mPartitionLengthOffset, mPartitionLengthLength);
partitionType = bytesToNum(sectorBuffer + partitionMap + mPartitionTypeOffset, mPartitionTypeLength);
EdbgOutputDebugString("findBootPartition: partitionStart = %d = 0x%x\n\r", partitionStart, partitionStart);
EdbgOutputDebugString("findBootPartition: partitionLength = %d = 0x%x\n\r", partitionLength, partitionLength);
EdbgOutputDebugString("findBootPartition: partitionType = %d = 0x%x\n\r", partitionType, partitionType);
switch(partitionType)
{
case mFAT16Type: // 16-bit FAT < 32MB
case mDOS32MegType: // 16-bit FAT >= 32MB - 2GB
case mFAT12Type: // 12-bit FAT < 16MB
return TRUE;
break;
default:
EdbgOutputDebugString("findBootPartition: partition type %d not supported!\r\n", partitionType);
return FALSE;
}
}
EdbgOutputDebugString("findBootPartition: partitionStart and partitionLength NOT FOUND\n\r");
return FALSE;
}
// Reads partition information from the master boot record. This also reads the FAT
// into memory for later access.
BOOL
processBootRecord(void)
{
int i;
PBYTE dog = sectorBuffer;
EdbgOutputDebugString("processBootRecord: partitionStart = %d = 0x%x\n\r", partitionStart, partitionStart);
CFReadSector(partitionStart, sectorBuffer);
EdbgOutputDebugString("CF Read Sector (ProcessBootRecord)\n\r");
sectorsPerCluster = bytesToNum(sectorBuffer+mSectorsPerClusterOffset, mSectorsPerClusterSize);
reservedSectors = bytesToNum(sectorBuffer+mReservedSectorsOffset, mReservedSectorsSize);
copiesOfFAT = bytesToNum(sectorBuffer+mCopiesOfFATOffset, mCopiesOfFATSize);
rootDirEntries = bytesToNum(sectorBuffer+mRootDirEntriesOffset, mRootDirEntriesSize);
sectorsPerFAT = bytesToNum(sectorBuffer+mSectorsPerFATOffset, mSectorsPerFATSize);
hiddenSectors = bytesToNum(sectorBuffer+mHiddenSectorsOffset, mHiddenSectorsSize);
#if DBG_VERBOSE_MSG
EdbgOutputDebugString("processBootRecord: Boot Record at partitionStart Sector: %d\n\r", partitionStart);
BootGetMemory((ULONG) sectorBuffer, mBytesPerSector, sizeof(BYTE));
EdbgOutputDebugString("processBootRecord: sectorsPerCluster = %d = 0x%x\n\r", sectorsPerCluster, sectorsPerCluster);
EdbgOutputDebugString("processBootRecord: reservedSectors = %d = 0x%x\n\r", reservedSectors, reservedSectors);
EdbgOutputDebugString("processBootRecord: copiesOfFAT = %d = 0x%x\n\r", copiesOfFAT, copiesOfFAT);
EdbgOutputDebugString("processBootRecord: rootDirEntries = %d = 0x%x\n\r", rootDirEntries, rootDirEntries);
EdbgOutputDebugString("processBootRecord: sectorsPerFAT = %d = 0x%x\n\r", sectorsPerFAT, sectorsPerFAT);
EdbgOutputDebugString("processBootRecord: hiddenSectors = %d = 0x%x\n\r", hiddenSectors, hiddenSectors);
EdbgOutputDebugString("processBootRecord: fatStart = %d = 0x%x\n\r", fatStart, fatStart);
EdbgOutputDebugString("processBootRecord: directoryStart = %d = 0x%x\n\r", directoryStart, directoryStart);
EdbgOutputDebugString("processBootRecord: clusterStart = %d = 0x%x\n\r", clusterStart, clusterStart);
#endif
if (sectorsPerFAT > mMaxFATSize)
{
EdbgOutputDebugString("processBootRecord: %d sectors too large for internal buffer of %d sectors!\r\n", sectorsPerFAT, mMaxFATSize);
return FALSE;
}
EdbgOutputDebugString("processBootRecord: partitionStart = %d = 0x%x\n\r", partitionStart, partitionStart);
fatStart = partitionStart + reservedSectors;
directoryStart = fatStart + copiesOfFAT * sectorsPerFAT;
clusterStart = directoryStart + rootDirEntries * mDirectoryEntrySize / mBytesPerSector;
// read FAT
for(i=0; i < sectorsPerFAT; i++)
{
CFReadSector(fatStart + i, fatBuffer + (i * mBytesPerSector));
// EdbgOutputDebugString("CF Read Sector (Read FAT)\n\r");
#if DBG_VERBOSE_MSG
EdbgOutputDebugString("processBootRecord: fatBuffer = %d = 0x%x\n\r", (fatBuffer + (i * mBytesPerSector)), (fatBuffer + (i * mBytesPerSector)));
BootGetMemory(((ULONG) (fatBuffer + (i * mBytesPerSector))), (mBytesPerSector), sizeof(BYTE));
#endif
}
#if DBG_VERBOSE_MSG
EdbgOutputDebugString("processBootRecord: fatBuffer\n\r");
BootGetMemory((ULONG) fatBuffer, (mBytesPerSector * sectorsPerFAT), sizeof(BYTE));
#endif
return TRUE;
}
// Searches the root directory for a specific file (NKImage.BIN). When found, sets up the
// file start cluster and file length.
BOOL
findBootFile(PBYTE fileName, PBYTE fileExt)
{
PBYTE dirEntry = 0;
int i;
PBYTE p = bootFileContent;
for (i=0; i < rootDirEntries; i++)
{
dirEntry += mDirectoryEntrySize;
if ((i & 0xF) == 0)
{
//EdbgOutputDebugString("findBootFile: Directory Sector = %d = 0x%x\n\r", directoryStart, directoryStart);
//EdbgOutputDebugString("findBootFile: dirEntry = %d = 0x%x\n\r", dirEntry, dirEntry);
CFReadSector(directoryStart++, sectorBuffer);
//EdbgOutputDebugString("CF Read Sector (FindBootFile)\n\r");
dirEntry = sectorBuffer;
#if DBG_FILEDIR_MSG
EdbgOutputDebugString("findBootFile: Directory Sector\n\r");
BootGetMemory(((ULONG) sectorBuffer), mBytesPerSector, sizeof(BYTE));
#endif
}
if (!(compare(dirEntry+mDirNameOffset, fileName, mBootfileNameLength) &&
compare(dirEntry+mDirExtOffset, fileExt, mBootfileExtLength)))
continue;
bootFileStart = bytesToNum(dirEntry+mDirStartOffset, mDirStartSize);
bootFileLength = bytesToNum(dirEntry+mDirLengthOffset, mDirLengthSize);
//EdbgOutputDebugString("findBootFile: bootFileStart = %d = 0x%x\n\r", (USHORT) bootFileStart, (USHORT) bootFileStart);
//EdbgOutputDebugString("findBootFile: bootFileLength = %d = 0x%x\n\r", (USHORT) bootFileLength, (USHORT) bootFileLength);
currentCluster = bootFileStart;
clusterIndex = 0;
return TRUE;
}
return FALSE;
}
// Simple compare routine (small).
BOOL
compare(PBYTE a, PBYTE b, int length)
{
while (length--)
if (*a++ != *b++)
return FALSE;
return TRUE;
}
// Simple copy routine (small).
void
copy(PBYTE a, PBYTE b, int length)
{
while(length--)
*b++ = *a++;
}
// Processes .BIN file.
BOOL
readBootFile(PBYTE Addr, ULONG bytesToRead, PULONG bytesRead)
{
PBYTE addrPtr = Addr;
ULONG bytesPerCluster;
//EdbgOutputDebugString("readBootFile: Addr = 0x%x, bytesToRead = %d = 0x%x\n\r", Addr, bytesToRead, bytesToRead);
bytesPerCluster = mBytesPerSector * sectorsPerCluster;
*bytesRead = 0;
while (bytesToRead > 0)
{
//EdbgOutputDebugString("readBootFile: addrPtr = 0x%x\n\r", addrPtr);
//EdbgOutputDebugString("readBootFile: bytesToRead = %d = 0x%x\n\r", bytesToRead, bytesToRead);
//EdbgOutputDebugString("readBootFile: bytesRead = %d = 0x%x\n\r", *bytesRead, *bytesRead);
//EdbgOutputDebugString("readBootFile: currentCluster = 0x%x\n\r", currentCluster);
readCluster(currentCluster, bootFileContent);
#if DBG_READFILE_MSG
EdbgOutputDebugString("loadBootFile: Read Cluster: %d = 0x%x\n\r", currentCluster, currentCluster);
BootGetMemory(((ULONG) bootFileContent), bytesPerCluster, sizeof(BYTE));
#endif
if((currentCluster & mClusterEndOfFileMask) == mClusterEndOfFile)
{
EdbgOutputDebugString("loadBootFile: Cluster EOF Found\n\r");
break;
}
if ((clusterIndex + bytesToRead) > bytesPerCluster)
{
memcpy(addrPtr, (bootFileContent + clusterIndex), (bytesPerCluster - clusterIndex));
bytesToRead -= (bytesPerCluster - clusterIndex);
*bytesRead += (bytesPerCluster - clusterIndex);
addrPtr += (bytesPerCluster - clusterIndex);
currentCluster = getNextCluster(currentCluster);
clusterIndex = 0;
}
else
{
memcpy(addrPtr, (bootFileContent + clusterIndex), bytesToRead);
clusterIndex += bytesToRead;
*bytesRead += bytesToRead;
addrPtr += bytesToRead;
bytesToRead -= bytesToRead;
}
}
#if DBG_READFILE_MSG
EdbgOutputDebugString("readBootFile: Addr = 0x%x, bytesRead = %d = 0x%x\n\r", Addr, *bytesRead, *bytesRead);
BootGetMemory(((ULONG) Addr), *bytesRead, sizeof(BYTE));
#endif
return TRUE;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -