⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 Windows操作系统中文件系统过滤驱动和设备驱动之间的相似
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -