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

📄 file.c

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