📄 pc_dev.c
字号:
/*
$Log: PC_dev.c,v $
Revision 1.3 2008/07/01 11:57:40 HSL
修改 BUF不对齐的情况下读取 SECTOR错误的 BUG.
Revision 1.2 2008/06/23 13:36:07 HSL
增加写 SECTOR 代码的支持.
Revision 1.1 2008/06/23 12:58:41 HSL
增加 文件系统的 PC仿真支持.
*/
#include "../inc/fs_comm.h"
#if !defined(BOARD)
#define _IN_EMLUATOR_
#include "PC_dev.h"
char PC_SYSTEM_DEV_PATH[] = "\\\\.\\C:";
char PC_USER_DEV_PATH[] = "\\\\.\\D:";
HANDLE gPCDevSysDiskHandle = INVALID_HANDLE_VALUE;
HANDLE gPCDevUserDiskHandle = INVALID_HANDLE_VALUE;
BOOLEAN gPCDevSysDiskWritable; //系统盘是否可写.
BOOLEAN gPCDevUsrDiskWritable; //系统盘是否可写.
DWORD dwSysSectPerClust;
DWORD dwSysBytesPerSect;
DWORD dwSysFreeClusters;
DWORD dwSysTotalClusters;
DWORD dwUserSectPerClust;
DWORD dwUserBytesPerSect;
DWORD dwUserFreeClusters;
DWORD dwUserTotalClusters;
#define PCFS_TMPBUF_SIZE 2048
#pragma pack( 16 )
BYTE gPCSysDiskTmpBuf[PCFS_TMPBUF_SIZE];
BYTE gPCUsrDiskTmpBuf[PCFS_TMPBUF_SIZE];
#pragma pack( )
int FS_PCGetStatus(void);
int FS_PCSysReadSec(uint32 LBA, uint32 SecCount, void *buf);
int FS_PCUserReadSec(uint32 LBA, uint32 SecCount, void *buf);
int FS_PCSysWriteSec(uint32 LBA, uint32 SecCount, void *buf);
int FS_PCUserWriteSec(uint32 LBA, uint32 SecCount, void *buf);
int FS_PCSysIoCtl(uint32 cmd, uint32 arg, void *buf);
int FS_PCUserIoCtl(uint32 cmd, uint32 arg, void *buf);
void PCSysCacheInit(void);
int FS_PCSysMediumInit(void);
void PCUserCacheInit(void);
int FS_PCUserMediumInit(void);
#define PC_SYSTEM_FAT_CACHE_COUNT 32
#define PC_SYSTEM_FDT_CACHE_COUNT 8
#define PC_SYSTEM_DATA_CACHE_COUNT 4
#define PC_USER_FAT_CACHE_COUNT 32
#define PC_USER_FDT_CACHE_COUNT 8
#define PC_USER_DATA_CACHE_COUNT 4
uint8 PCFatCacheBuf[PC_SYSTEM_FAT_CACHE_COUNT][512];
uint8 PCFdtCacheBuf[PC_SYSTEM_FDT_CACHE_COUNT][512];
uint8 PCDataCacheBuf[PC_SYSTEM_DATA_CACHE_COUNT][512];
FS_CACHE_DATA PC_FatCacheData[PC_SYSTEM_FAT_CACHE_COUNT];
FS_CACHE_DATA PC_FdtCacheData[PC_SYSTEM_FDT_CACHE_COUNT];
FS_CACHE_DATA PC_DataCacheData[PC_SYSTEM_DATA_CACHE_COUNT];
FS_CACHE PCFatCache ={PC_FatCacheData, 0, PC_SYSTEM_FAT_CACHE_COUNT};
FS_CACHE PCFdtCache ={PC_FdtCacheData, 0, PC_SYSTEM_FDT_CACHE_COUNT};
FS_CACHE PCDataCache={PC_DataCacheData, 0, PC_SYSTEM_DATA_CACHE_COUNT};
uint8 PCUFatCacheBuf[PC_USER_FAT_CACHE_COUNT][512];
uint8 PCUFdtCacheBuf[PC_USER_FDT_CACHE_COUNT][512];
uint8 PCUDataCacheBuf[PC_USER_DATA_CACHE_COUNT][512];
FS_CACHE_DATA PC_UFatCacheData[PC_USER_FAT_CACHE_COUNT];
FS_CACHE_DATA PC_UFdtCacheData[PC_USER_FDT_CACHE_COUNT];
FS_CACHE_DATA PC_UDataCacheData[PC_USER_DATA_CACHE_COUNT];
FS_CACHE PCUFatCache ={PC_UFatCacheData, 0, PC_USER_FAT_CACHE_COUNT};
FS_CACHE PCUFdtCache ={PC_UFdtCacheData, 0, PC_USER_FDT_CACHE_COUNT};
FS_CACHE PCUDataCache={PC_UDataCacheData, 0, PC_USER_DATA_CACHE_COUNT};
const FS_DEVICE_TYPE FS_PCSysDevice={
"C:\\",
"SysDisk",
FS_PCGetStatus,
FS_PCSysReadSec,
FS_PCSysWriteSec,
FS_PCSysIoCtl,
FS_PCSysMediumInit,
&PCFatCache,
&PCFdtCache,
&PCDataCache
};
const FS_DEVICE_TYPE FS_PCUserDevice={
"D:\\",
"Flash",
FS_PCGetStatus,
FS_PCUserReadSec,
FS_PCUserWriteSec,
FS_PCUserIoCtl,
FS_PCUserMediumInit,
&PCUFatCache,
&PCUFdtCache,
&PCUDataCache
};
int FS_PCGetStatus(void)
{
return(0);
}
// diskCapacity 的单位为 M.查找是否存在 小于指定容量大小的 可移动磁盘.TRUE:存在,FALSE:不存在.
/*
1.存在一个BUG.当系统发送 DEVICE CHANGE 消息的时候, 通常 3个移动磁盘里面只有一个能够访问,其他的
两个还处于未 READY 状态.
*/
BOOLEAN FS_PCDevGetRemovedDisk(char *diskPath , DWORD diskCapacityMin ,
DWORD diskCapacityMax )
{
DWORD disks = GetLogicalDrives( );
int i ;
UINT drType;
char rootPath[ ] = "D:\\";
for( i = 3; i < 26 ; i++ )
{
if( disks&(0x01<<i) )
{
drType = GetDriveType(rootPath);
if( DRIVE_REMOVABLE == drType )
{
char DevPathBuf[24];
DWORD dwSectPerClust;
DWORD dwBytesPerSect;
DWORD dwFreeClusters;
DWORD dwTotalClusters;
diskPath[4] = rootPath[0];
strcpy(DevPathBuf, diskPath);
strcat(DevPathBuf, "\\");
if(GetDiskFreeSpace(DevPathBuf, &dwSectPerClust,
&dwBytesPerSect,
&dwFreeClusters,
&dwTotalClusters))
{
// M BTYE TO SECTOR( 512BYTES )
if( dwSectPerClust*dwTotalClusters <= diskCapacityMax*1024*2
&& dwSectPerClust*dwTotalClusters >= diskCapacityMin*1024*2 )
return TRUE;
}
}
}
rootPath[0]++;
}
return FALSE;
}
/*********************************************************************************/
#if 0
//系统配接口函数
#endif
/*********************************************************************************/
int FS_PCSysReadSec(uint32 LBA, uint32 SecCount, void *buf)
{
DWORD dwCB;
DWORD dwCB2;
DWORD dwPtrLow;
DWORD dwError;
BOOL rd;
dwCB2 = 512 * LBA;
dwCB = (DWORD)(((INT64U)512*LBA)>>32);
dwPtrLow = SetFilePointer(gPCDevSysDiskHandle, dwCB2, (long *)&dwCB, FILE_BEGIN);
if (dwPtrLow == 0xFFFFFFFF && (dwError = GetLastError()) != NO_ERROR )
{
// Deal with failure
TR("Read:Seek SysDisk Failed,Lba=0x%x,Err=%d" , LBA , dwError );
return -1;
} // End of error handler
dwPtrLow = PCFS_TMPBUF_SIZE;
while( SecCount > 0 )
{
if( SecCount <= (PCFS_TMPBUF_SIZE/512) )
{
dwPtrLow = 512 * SecCount;
}
rd = ReadFile(gPCDevSysDiskHandle, gPCSysDiskTmpBuf ,
dwPtrLow , &dwCB, NULL);
if( !rd || dwCB != dwPtrLow )
{
dwError = GetLastError();
TR("Read:Read SysDisk Failed,Lba=0x%x,SecCnt=%d,Err=%d,rd=%d,dwCB=%d" ,
LBA ,SecCount, dwError , rd , dwCB);
return -1;
}
memcpy( buf , gPCSysDiskTmpBuf , dwPtrLow );
buf =(char*)buf+ dwPtrLow;
SecCount -= (dwPtrLow/512);
}
return 0;
}
int FS_PCSysWriteSec(uint32 LBA, uint32 SecCount, void *buf)
{
DWORD dwCB;
DWORD dwCB2;
//系统盘不可写.
if( !gPCDevSysDiskWritable )
return -1;
dwCB2 = 512 * LBA;
dwCB = (DWORD)(((INT64U)512*LBA)>>32);
SetFilePointer(gPCDevSysDiskHandle, dwCB2, (long *)&dwCB, FILE_BEGIN);
if( WriteFile(gPCDevSysDiskHandle, buf, 512 * SecCount, &dwCB, NULL) == 0 )
{
TR("Write SysDisk Failed,SECTOR=%d,Err=%d" , SecCount , GetLastError() );
return -1;
}
if(dwCB != 512*SecCount)
{
return -1;
}
return 0;
}
int FS_PCSysIoCtl(uint32 cmd, uint32 arg, void *buf)
{
uint32 *rbuf;
rbuf = (uint32 *)buf;
switch(cmd)
{
case IO_CTL_GET_CAPACITY:
//*rbuf = GetCapacity(DISK_SYS);
*rbuf = dwSysTotalClusters*dwSysSectPerClust;
break;
case IO_CTL_GET_MEDIUM_START_SEC:
*rbuf = 0;
break;
case IO_CTL_CACHE_WRITE_BACK:
//PCCacheCloseAll();
break;
case IO_CTL_FLUSH_CACHE:
PCSysCacheInit();
break;
default:
break;
}
return(0);
}
void PCSysCacheInit(void)
{
uint32 i;
FS_CACHE_DATA *pCache;
pCache = PCFatCache.pCacheData;
for(i=0; i<PC_SYSTEM_FAT_CACHE_COUNT; i++){
pCache->flag = 0;
pCache->pBuffer = &PCFatCacheBuf[i][0];
pCache->SectorNo = 0xFFFFFFFF;
pCache++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -