📄 file.c
字号:
#ifdef TFAT
if(pstm->s_pvol->v_fTfat && pstm->s_pstmParent)
EnterCriticalSection(&pstm->s_pstmParent->s_cs);
#endif
EnterCriticalSection(&pstm->s_cs);
__try {
if (!(pfh->fh_mode & FH_MODE_READ) || (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)))
dwError = ERROR_ACCESS_DENIED;
else {
if (!lpdwLowOffset) {
// authorize access
if (FSDMGR_TestFileLockEx(AcquireFileLockState, ReleaseFileLockState, (DWORD)pfh, TRUE, nBytesToRead, pfh->fh_pos, 0)) {
dwError = ReadStreamData(pstm, pfh->fh_pos, buffer, nBytesToRead, &cbRead);
pfh->fh_pos += cbRead;
}
else {
dwError = ERROR_ACCESS_DENIED;
}
}
else {
// authorize access
if (FSDMGR_TestFileLockEx(AcquireFileLockState, ReleaseFileLockState, (DWORD)pfh, TRUE, nBytesToRead, *lpdwLowOffset, 0)) {
dwError = ReadStreamData(pstm, *lpdwLowOffset, buffer, nBytesToRead, &cbRead);
}
else {
dwError = ERROR_ACCESS_DENIED;
}
}
}
if (lpNumBytesRead && (ERROR_SUCCESS == dwError)) {
*lpNumBytesRead = cbRead;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&pstm->s_cs);
#ifdef TFAT
if(pstm->s_pvol->v_fTfat && pstm->s_pstmParent)
LeaveCriticalSection(&pstm->s_pstmParent->s_cs);
#endif
return dwError;
}
DWORD FATFSWriteFile(
PFHANDLE pfh,
LPCVOID buffer,
DWORD nBytesToWrite,
LPDWORD lpNumBytesWritten,
LPOVERLAPPED lpOverlapped,
LPDWORD lpdwLowOffset,
LPDWORD lpdwHighOffset)
{
PDSTREAM pstm;
DWORD dwError = ERROR_GEN_FAILURE;
DWORD cbWritten = 0;
RETAILMSG(1,(L"[FSD] FATFSWriteFile\r\n"));
pstm = pfh->fh_pstm;
ASSERT(pstm);
#ifdef TFAT
if(pstm->s_pstmParent)
EnterCriticalSection(&pstm->s_pstmParent->s_cs);
#endif
EnterCriticalSection(&pstm->s_cs);
__try {
if (!(pfh->fh_mode & FH_MODE_WRITE) || (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)))
dwError = ERROR_ACCESS_DENIED;
else {
if (!lpdwLowOffset) {
if (FSDMGR_TestFileLockEx(AcquireFileLockState, ReleaseFileLockState, (DWORD)pfh, FALSE, nBytesToWrite, pfh->fh_pos, 0)) {
dwError = WriteStreamData(pstm, pfh->fh_pos, buffer, nBytesToWrite, &cbWritten, TRUE);
pfh->fh_pos += cbWritten;
}
else {
dwError = ERROR_ACCESS_DENIED;
}
}
else {
if (FSDMGR_TestFileLockEx(AcquireFileLockState, ReleaseFileLockState, (DWORD)pfh, TRUE, nBytesToWrite, *lpdwLowOffset, 0)) {
dwError = WriteStreamData(pstm, *lpdwLowOffset, buffer, nBytesToWrite, &cbWritten, TRUE);
}
else {
dwError = ERROR_ACCESS_DENIED;
}
}
if (lpNumBytesWritten && (ERROR_SUCCESS == dwError)) {
*lpNumBytesWritten = cbWritten;
}
// TEST_BREAK
PWR_BREAK_NOTIFY(11);
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&pstm->s_cs);
#ifdef TFAT
if(pstm->s_pstmParent)
LeaveCriticalSection(&pstm->s_pstmParent->s_cs);
#endif
return dwError;
}
#if NUM_FILE_APIS == 13
BOOL FAT_ReadFilePagein(
PFHANDLE pfh,
LPVOID buffer,
DWORD nBytesToRead,
LPDWORD lpNumBytesRead,
LPOVERLAPPED lpOverlapped)
{
#ifdef DEMAND_PAGING
PDSTREAM pstm;
DWORD dwError;
pstm = pfh->fh_pstm;
ASSERT(pstm);
if (buffer == NULL && nBytesToRead == 0) {
if (pstm->s_pvol->v_pdsk->d_diActive.di_flags & DISK_INFO_FLAG_PAGEABLE) {
pstm->s_flags |= STF_DEMANDPAGED;
return TRUE; // yes, Pagein requests are supported
}
DEBUGMSG(TRUE,(DBGTEXT("FATFS!FAT_ReadFilePagein: driver declines to demand-page '%.11hs'\r\n"), pstm->s_achOEM));
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE; // but this little piggy cried all the way home
}
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_ReadFilePagein(0x%x,0x%x bytes,position 0x%x)\r\n"), pfh, nBytesToRead, pfh->fh_pos));
ASSERT(pstm->s_flags & STF_DEMANDPAGED);
if (dwError = FATFSReadFile(pfh, buffer, nBytesToRead, lpNumBytesRead, lpOverlapped, NULL, NULL))
SetLastError(dwError);
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,
(DBGTEXT("FATFS!FAT_ReadFilePagein(0x%x) returned 0x%x (%d, 0x%x bytes, pos 0x%x, size 0x%x)\r\n"), pfh, dwError == ERROR_SUCCESS, dwError, *lpNumBytesRead, pfh->fh_pos, pstm->s_size));
return dwError == ERROR_SUCCESS;
#else
DEBUGMSG(TRUE,(DBGTEXT("FATFS!FAT_ReadFilePagein(0x%x,0x%x bytes,position 0x%x) is hard-coded to FAIL!\r\n"), pfh, nBytesToRead, pfh->fh_pos));
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE;
#endif
}
#endif
BOOL FAT_ReadFile(
PFHANDLE pfh,
LPVOID buffer,
DWORD nBytesToRead,
LPDWORD lpNumBytesRead,
LPOVERLAPPED lpOverlapped)
{
PDSTREAM pstm;
DWORD dwError;
pstm = pfh->fh_pstm;
ASSERT(pstm);
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_ReadFile(0x%x,0x%x bytes,position 0x%x)\r\n"), pfh, nBytesToRead, pfh->fh_pos));
if (!FATEnter(NULL, LOGID_NONE)) {
DEBUGMSG(ZONE_APIS || ZONE_ERRORS,(DBGTEXT("FATFS!FAT_ReadFile bailing...\r\n")));
return FALSE;
}
if (buffer)
LockPages(buffer,nBytesToRead,0,LOCKFLAG_WRITE);
if (dwError = FATFSReadFile(pfh, buffer, nBytesToRead, lpNumBytesRead, lpOverlapped, NULL, NULL))
SetLastError(dwError);
if (buffer)
UnlockPages(buffer,nBytesToRead);
FATExit(pstm->s_pvol, LOGID_NONE);
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,
(DBGTEXT("FATFS!FAT_ReadFile(0x%x) returned 0x%x (%d, 0x%x bytes, pos 0x%x, size 0x%x)\r\n"), pfh, dwError == ERROR_SUCCESS, dwError, *lpNumBytesRead, pfh->fh_pos, pstm->s_size));
return dwError == ERROR_SUCCESS;
}
#if NUM_FILE_APIS > 13
BOOL FAT_ReadFileWithSeek(
PFHANDLE pfh,
LPVOID buffer,
DWORD nBytesToRead,
LPDWORD lpNumBytesRead,
LPOVERLAPPED lpOverlapped,
DWORD dwLowOffset,
DWORD dwHighOffset)
{
#ifdef DEMAND_PAGING
PDSTREAM pstm;
DWORD dwError=ERROR_SUCCESS;
pstm = pfh->fh_pstm;
ASSERT(pstm);
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_ReadFileWithSeek(0x%x,0x%x bytes,position 0x%x)\r\n"), pfh, nBytesToRead, dwLowOffset));
if (buffer == NULL && nBytesToRead == 0) {
if (pstm->s_pvol->v_pdsk->d_diActive.di_flags & DISK_INFO_FLAG_PAGEABLE) {
pstm->s_flags |= STF_DEMANDPAGED;
return TRUE; // yes, Pagein requests are supported
}
DEBUGMSG(TRUE,(DBGTEXT("FATFS!FAT_ReadFileWithSeek: driver declines to demand-page '%.11hs'\r\n"), pstm->s_achOEM));
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE; // but this little piggy cried all the way home
}
if (buffer)
LockPages(buffer,nBytesToRead,0,LOCKFLAG_WRITE);
if (!FATEnter(NULL, LOGID_NONE))
return FALSE;
dwError = FATFSReadFile(pfh, buffer, nBytesToRead, lpNumBytesRead, lpOverlapped, &dwLowOffset, &dwHighOffset);
FATExit(pstm->s_pvol, LOGID_NONE);
if (dwError) {
SetLastError(dwError);
}
if (buffer)
UnlockPages(buffer,nBytesToRead);
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,
(DBGTEXT("FATFS!FAT_ReadFileWithSeek(0x%x) returned 0x%x (%d, 0x%x bytes, size 0x%x)\r\n"), pfh, dwError == ERROR_SUCCESS, dwError, *lpNumBytesRead, pstm->s_size));
return dwError == ERROR_SUCCESS;
#else
DEBUGMSG(TRUE,(DBGTEXT("FATFS!FAT_ReadFileWithSeek(0x%x,0x%x bytes,position 0x%x) is hard-coded to FAIL!\r\n"), pfh, nBytesToRead, pfh->fh_pos));
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE;
#endif
}
BOOL FAT_ReadFileScatter(
PFHANDLE pfh,
FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToRead,
LPDWORD lpReserved,
LPOVERLAPPED lpOverlapped)
{
PDSTREAM pstm;
DWORD dwError = ERROR_SUCCESS;
SYSTEM_INFO SystemInfo;
DWORD dwNumPages;
DWORD iPage;
// Interpret lpReserved as an array of 64-bit offsets if provided.
FILE_SEGMENT_ELEMENT* aOffsetArray = (FILE_SEGMENT_ELEMENT*)lpReserved;
pstm = pfh->fh_pstm;
ASSERT(pstm);
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_ReadFileScatter(0x%x,0x%x bytes)\r\n"), pfh, nNumberOfBytesToRead));
GetSystemInfo (&SystemInfo);
if (!nNumberOfBytesToRead || nNumberOfBytesToRead % SystemInfo.dwPageSize) {
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
dwNumPages = nNumberOfBytesToRead / SystemInfo.dwPageSize;
if (!FATEnter(NULL, LOGID_NONE)) {
DEBUGMSG(ZONE_APIS || ZONE_ERRORS,(DBGTEXT("FATFS!FAT_ReadFile bailing...\r\n")));
return FALSE;
}
#ifdef TFAT
if(pstm->s_pvol->v_fTfat && pstm->s_pstmParent)
EnterCriticalSection(&pstm->s_pstmParent->s_cs);
#endif
EnterCriticalSection(&pstm->s_cs);
__try {
if (!(pfh->fh_mode & FH_MODE_READ) || (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)))
dwError = ERROR_ACCESS_DENIED;
else {
for (iPage = 0; iPage < dwNumPages; iPage++) {
DWORD pos = aOffsetArray ? (DWORD)aOffsetArray[iPage].Alignment : pfh->fh_pos;
dwError = ReadStreamData(pstm, pos, aSegmentArray[iPage].Buffer, SystemInfo.dwPageSize, NULL);
if (dwError)
break;
if (!aOffsetArray)
pfh->fh_pos += SystemInfo.dwPageSize;
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&pstm->s_cs);
#ifdef TFAT
if(pstm->s_pvol->v_fTfat && pstm->s_pstmParent)
LeaveCriticalSection(&pstm->s_pstmParent->s_cs);
#endif
FATExit(pstm->s_pvol, LOGID_NONE);
if (dwError)
SetLastError (dwError);
return dwError == ERROR_SUCCESS;
}
#endif
BOOL FAT_WriteFile(
PFHANDLE pfh,
LPCVOID buffer,
DWORD nBytesToWrite,
LPDWORD lpNumBytesWritten,
LPOVERLAPPED lpOverlapped)
{
PDSTREAM pstm;
DWORD dwError;
pstm = pfh->fh_pstm;
ASSERT(pstm);
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_WriteFile(0x%x,0x%x bytes,position 0x%x)\r\n"), pfh, nBytesToWrite, pfh->fh_pos));
if (!FATEnter(pfh->fh_pstm->s_pvol, LOGID_WRITEFILE))
return FALSE;
if (buffer)
LockPages((LPVOID)buffer,nBytesToWrite,0,LOCKFLAG_READ);
if (dwError = FATFSWriteFile(pfh, buffer, nBytesToWrite, lpNumBytesWritten, lpOverlapped, NULL, NULL)) {
SetLastError(dwError);
}
#ifdef TFAT
else if (pstm->s_pvol->v_fTfat && (STF_WRITETHRU & pstm->s_flags))
{
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_WriteFile: Committing transactions")));
// Write succeeded, commit transations if in write-through mode
dwError = CommitTransactions (pstm->s_pvol);
}
#endif
UnlockPages((LPVOID)buffer,nBytesToWrite);
FATExit(pstm->s_pvol, LOGID_WRITEFILE);
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,
(DBGTEXT("FATFS!FAT_WriteFile(0x%x) returned 0x%x (%d, 0x%x bytes, pos 0x%x, size 0x%x)\r\n"), pfh, dwError == ERROR_SUCCESS, dwError, *lpNumBytesWritten, pfh->fh_pos, pstm->s_size));
return dwError == ERROR_SUCCESS;
}
#if NUM_FILE_APIS > 13
BOOL FAT_WriteFileWithSeek(
PFHANDLE pfh,
LPCVOID buffer,
DWORD nBytesToWrite,
LPDWORD lpNumBytesWritten,
LPOVERLAPPED lpOverlapped,
DWORD dwLowOffset,
DWORD dwHighOffset)
{
#ifdef DEMAND_PAGING
PDSTREAM pstm;
DWORD dwError;
pstm = pfh->fh_pstm;
ASSERT(pstm);
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_WriteFileWithSeek(0x%x,0x%x bytes,position 0x%x)\r\n"), pfh, nBytesToWrite, dwLowOffset));
if (buffer)
LockPages((LPVOID)buffer,nBytesToWrite,0,LOCKFLAG_READ);
if (!FATEnter(pfh->fh_pstm->s_pvol, LOGID_WRITEFILE)) {
if (buffer)
UnlockPages((LPVOID)buffer,nBytesToWrite);
return FALSE;
}
dwError = FATFSWriteFile(pfh, buffer, nBytesToWrite, lpNumBytesWritten, lpOverlapped, &dwLowOffset, &dwHighOffset);
if (dwError != ERROR_SUCCESS) {
SetLastError(dwError);
}
#ifdef TFAT
else if (pstm->s_pvol->v_fTfat && (STF_WRITETHRU & pstm->s_flags) && !(pstm->s_pvol->v_flFATFS & FATFS_WFWS_NOWRITETHRU))
{
// Write succeeded, commit transations if in write-through mode
dwError = CommitTransactions (pstm->s_pvol);
}
#endif
FATExit(pstm->s_pvol, LOGID_WRITEFILE);
if (buffer)
UnlockPages((LPVOID)buffer,nBytesToWrite);
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,
(DBGTEXT("FATFS!FAT_WriteFileWithSeek(0x%x) returned 0x%x (%d, 0x%x bytes, size 0x%x)\r\n"), pfh, dwError == ERROR_SUCCESS, dwError, *lpNumBytesWritten, pstm->s_size));
return dwError == ERROR_SUCCESS;
#else
DEBUGMSG(TRUE,(DBGTEXT("FATFS!FAT_WriteFileWithSeek(0x%x,0x%x bytes,position 0x%x) is hard-coded to FAIL!\r\n"), pfh, nBytesToWrite, pfh->fh_pos));
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE;
#endif
}
#ifdef TFAT
// determine if there is sufficient space left on the device to safely complete a transacted WFG operation
static DWORD CheckWriteFileGatherSpace(PVOLUME pvol, FILE_SEGMENT_ELEMENT *aSegmentArray, FILE_SEGMENT_ELEMENT *aOffsetArray, DWORD dwNumPages, DWORD dwPageSize)
{
DWORD dwError = ERROR_SUCCESS;
// If cluster size is greater than page size, assume one page required per cluster.
// For larger disks, this is a conservative estimate of the requirements since several contiguous
// pages may map to the same cluster.
DWORD dwClustersRequiredPerPage = (dwPageSize > pvol->v_cbClus) ? (dwPageSize / pvol->v_cbClus) : 1;
// determine the number of free clusters in the file system if it has not already been determined
if (UNKNOWN_CLUSTER == pvol->v_cclusFree) {
if (!CalculateFreeClustersInRAM(pvol)) {
// If we couldn't do it in RAM, try it through the FAT buffers.
dwError = CalculateFreeClustersFromBuffers(pvol);
if (dwError) {
goto exit;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -