📄 file.c
字号:
DEBUGCHK(pvol->v_cclusFree != UNKNOWN_CLUSTER);
// being conservative, there must be more free clusters than required clusters
dwError = (pvol->v_cclusFree > (dwClustersRequiredPerPage * dwNumPages)) ? ERROR_SUCCESS : ERROR_DISK_FULL;
exit:
return dwError;
}
#endif // TFAT
BOOL FAT_WriteFileGather(
PFHANDLE pfh,
FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToWrite,
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_WriteFileGather(0x%x,0x%x bytes)\r\n"), pfh, nNumberOfBytesToWrite));
GetSystemInfo (&SystemInfo);
if (!nNumberOfBytesToWrite || nNumberOfBytesToWrite % SystemInfo.dwPageSize) {
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
dwNumPages = nNumberOfBytesToWrite / SystemInfo.dwPageSize;
if (!FATEnter(pfh->fh_pstm->s_pvol, LOGID_WRITEFILE))
return FALSE;
#ifdef TFAT
if(pstm->s_pvol->v_fTfat && pstm->s_pstmParent)
EnterCriticalSection(&pstm->s_pstmParent->s_cs);
#endif
EnterCriticalSection(&pstm->s_cs);
LockFAT(pstm->s_pvol);
__try {
if (!(pfh->fh_mode & FH_MODE_WRITE) || (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)))
dwError = ERROR_ACCESS_DENIED;
else {
#ifdef TFAT
if (pstm->s_pvol->v_fTfat && (STF_TRANSDATA & pstm->s_flags)) {
dwError = CheckWriteFileGatherSpace(pstm->s_pvol, aSegmentArray, aOffsetArray, dwNumPages, SystemInfo.dwPageSize);
}
#endif
if (!dwError) {
for (iPage = 0; iPage < dwNumPages; iPage++) {
DWORD pos = aOffsetArray ? (DWORD)aOffsetArray[iPage].Alignment : pfh->fh_pos;
dwError = WriteStreamData(pstm, pos, aSegmentArray[iPage].Buffer, SystemInfo.dwPageSize, NULL, TRUE);
if (dwError)
break;
if (!aOffsetArray)
pfh->fh_pos += SystemInfo.dwPageSize;
}
}
}
#ifdef TFAT
if (!dwError && pstm->s_pvol->v_fTfat && (STF_WRITETHRU & pstm->s_flags))
{
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_WriteFileGather: Committing transactions")));
// Write succeeded, commit transations if in write-through mode
dwError = CommitTransactions (pstm->s_pvol);
}
#endif
} __except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
UnlockFAT(pstm->s_pvol);
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_WRITEFILE);
if (dwError)
SetLastError (dwError);
return dwError == ERROR_SUCCESS;
}
#endif
DWORD FAT_SetFilePointer(
PFHANDLE pfh,
LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh,
DWORD dwMoveMethod)
{
__int64 newPos = 0;
PDSTREAM pstm;
DWORD dwError;
DWORD dwReturn = (DWORD)-1;
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_SetFilePointer(0x%x,offset 0x%x,method %d)\r\n"), pfh, lDistanceToMove, dwMoveMethod));
FATEnterQuick();
pstm = pfh->fh_pstm;
ASSERT(pstm);
if (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)) {
dwError = ERROR_ACCESS_DENIED;
goto exit;
}
dwError = ERROR_SUCCESS;
__try {
if (lpDistanceToMoveHigh) {
SetLastError(NO_ERROR);
newPos = (__int64)*lpDistanceToMoveHigh<<32 | (DWORD)lDistanceToMove;
*lpDistanceToMoveHigh = 0;
} else {
newPos = lDistanceToMove;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
goto exit;
}
switch (dwMoveMethod) {
case FILE_BEGIN:
break;
case FILE_CURRENT:
newPos += pfh->fh_pos;
break;
case FILE_END:
newPos += pstm->s_size;
break;
default:
dwError = ERROR_INVALID_PARAMETER;
goto exit;
}
if ((newPos >> 32) != 0)
dwError = ERROR_NEGATIVE_SEEK;
else
dwReturn = pfh->fh_pos = (DWORD)newPos;
exit:
if (dwError)
SetLastError(dwError);
FATExitQuick();
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_SetFilePointer returned 0x%x (%d)\r\n"), dwReturn, dwError));
return dwReturn;
}
DWORD FAT_GetFileSize(PFHANDLE pfh, LPDWORD lpFileSizeHigh)
{
PDSTREAM pstm;
DWORD dwError;
DWORD dwReturn = (DWORD)-1;
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_GetFileSize(0x%x)\r\n"), pfh));
FATEnterQuick();
if (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)) {
dwError = ERROR_ACCESS_DENIED;
goto exit;
}
pstm = pfh->fh_pstm;
ASSERT(pstm);
dwError = ERROR_SUCCESS;
__try {
if (lpFileSizeHigh) {
SetLastError(NO_ERROR);
*lpFileSizeHigh= 0;
}
dwReturn = pstm->s_size;
} __except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
exit:
if (dwError)
SetLastError(dwError);
FATExitQuick();
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_GetFileSize returned 0x%x (%d)\r\n"), dwReturn, dwError));
return dwReturn;
}
BOOL FAT_GetFileInformationByHandle(
PFHANDLE pfh,
LPBY_HANDLE_FILE_INFORMATION lpFileInfo)
{
PDSTREAM pstm;
DWORD dwError;
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_GetFileInformationByHandle(0x%x)\r\n"), pfh));
FATEnterQuick();
if (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)) {
dwError = ERROR_ACCESS_DENIED;
goto exit;
}
pstm = pfh->fh_pstm;
ASSERT(pstm);
dwError = ERROR_SUCCESS;
EnterCriticalSection(&pstm->s_cs);
__try {
lpFileInfo->dwFileAttributes = pstm->s_attr;
lpFileInfo->ftCreationTime = pstm->s_ftCreate;
lpFileInfo->ftLastAccessTime = pstm->s_ftAccess;
lpFileInfo->ftLastWriteTime = pstm->s_ftWrite;
lpFileInfo->dwVolumeSerialNumber = pstm->s_pvol->v_serialID;
lpFileInfo->nFileSizeHigh = 0;
lpFileInfo->nFileSizeLow = pstm->s_size;
lpFileInfo->nNumberOfLinks = 1;
lpFileInfo->nFileIndexHigh = pstm->s_sid.sid_clusDir;
lpFileInfo->nFileIndexLow = pstm->s_sid.sid_ordDir;
#ifdef UNDER_CE
// NT does not have OID defined
lpFileInfo->dwOID = OIDFROMSTREAM(pstm); // TODO: YG - Investigate
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&pstm->s_cs);
exit:
if (dwError)
SetLastError(dwError);
FATExitQuick();
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_GetFileInformationByHandle returned 0x%x (%d)\r\n"), dwError == ERROR_SUCCESS, dwError));
return dwError == ERROR_SUCCESS;
}
BOOL FAT_FlushFileBuffers(PFHANDLE pfh)
{
PDSTREAM pstm;
DWORD dwError;
pstm = pfh->fh_pstm;
ASSERT(pstm);
if (!BufEnter(pstm->s_pvol, TRUE))
return FALSE;
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_FlushFileBuffers(0x%x)\r\n"), pfh));
if (!(pfh->fh_mode & FH_MODE_WRITE) || (pfh->fh_flags & FHF_UNMOUNTED)) {
dwError = ERROR_ACCESS_DENIED;
goto exit;
}
EnterCriticalSection(&pstm->s_cs);
dwError = CommitStream(pstm, TRUE);
LeaveCriticalSection(&pstm->s_cs);
#ifdef TFAT
if (pstm->s_pvol->v_fTfat && (dwError == ERROR_SUCCESS))
dwError = CommitTransactions (pstm->s_pvol);
#endif
exit:
if (dwError) {
SetLastError(dwError);
}
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_FlushFileBuffers returned 0x%x (%d)\r\n"), dwError == ERROR_SUCCESS, dwError));
BufExit(pstm->s_pvol);
return dwError == ERROR_SUCCESS;
}
BOOL FAT_GetFileTime(
PFHANDLE pfh,
LPFILETIME lpCreation,
LPFILETIME lpLastAccess,
LPFILETIME lpLastWrite)
{
PDSTREAM pstm;
DWORD dwError;
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_GetFileTime(0x%x)\r\n"), pfh));
FATEnterQuick();
if (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)) {
dwError = ERROR_ACCESS_DENIED;
goto exit;
}
pstm = pfh->fh_pstm;
ASSERT(pstm);
dwError = ERROR_SUCCESS;
EnterCriticalSection(&pstm->s_cs);
__try {
if (lpCreation)
*lpCreation = pstm->s_ftCreate;
if (lpLastAccess)
*lpLastAccess = pstm->s_ftAccess;
if (lpLastWrite)
*lpLastWrite = pstm->s_ftWrite;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&pstm->s_cs);
exit:
if (dwError)
SetLastError(dwError);
FATExitQuick();
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_GetFileTime returned 0x%x (%d)\r\n"), dwError == ERROR_SUCCESS, dwError));
return dwError == ERROR_SUCCESS;
}
BOOL FAT_SetFileTime(
PFHANDLE pfh,
CONST FILETIME *lpCreation,
CONST FILETIME *lpLastAccess,
CONST FILETIME *lpLastWrite)
{
PDSTREAM pstm;
DWORD dwError;
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_SetFileTime(0x%x)\r\n"), pfh));
if (!FATEnter(NULL, LOGID_NONE))
return FALSE;
pstm = pfh->fh_pstm;
ASSERT(pstm);
if (!(pfh->fh_mode & FH_MODE_WRITE) || (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED))) {
dwError = ERROR_ACCESS_DENIED;
goto exit;
}
if (pstm->s_pvol->v_flags & VOLF_READONLY) {
dwError = ERROR_WRITE_PROTECT;
goto exit;
}
dwError = ERROR_SUCCESS;
EnterCriticalSection(&pstm->s_cs);
__try {
if (lpCreation) {
pstm->s_ftCreate = *lpCreation;
pstm->s_flags |= STF_CREATE_TIME | STF_DIRTY_INFO;
}
if (lpLastAccess) {
pstm->s_ftAccess = *lpLastAccess;
pstm->s_flags |= STF_ACCESS_TIME | STF_DIRTY_INFO;
}
if (lpLastWrite) {
pstm->s_ftWrite = *lpLastWrite;
pstm->s_flags |= STF_WRITE_TIME | STF_DIRTY_INFO;
}
#ifdef WASTE_OF_TIME
// This is a waste of time, because when the recipient of this message
// turns around and calls FAT_OidGetInfo, it's not going to see the new
// time anyway. New file times don't get written to disk until a commit
// or close, and FAT_OidGetInfo only reports file information currently
// stored on disk. Since we always post DB_CEOID_CHANGED when a file's
// directory entry is updated, this DB_CEOID_CHANGED is superfluous.
//
// You might think that FAT_OidGetInfo should look for and extract
// information from an open stream (if one exists), but that would be
// inconsistent with how all other APIs have historically worked. For
// example, FindFirstFile always returns what's recorded in a file's
// directory entry, regardless of what another thread or process may be
// doing to that file at the same time. -JTP
FILESYSTEMNOTIFICATION(pvol, DB_CEOID_CHANGED, 0, SHCNE_UPDATEITEM, &pstm->s_sid, &pstm->s_sidParent, NULL, NULL, NULL, DBGTEXTW("FAT_SetFileTime"));
#endif // WASTE_OF_TIME
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&pstm->s_cs);
exit:
if (dwError)
SetLastError(dwError);
FATExit(pstm->s_pvol, LOGID_NONE);
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_SetFileTime returned 0x%x (%d)\r\n"), dwError == ERROR_SUCCESS, dwError));
return dwError == ERROR_SUCCESS;
}
BOOL FAT_SetEndOfFile(PFHANDLE pfh)
{
PDSTREAM pstm = pfh->fh_pstm;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -