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

📄 file.c

📁 从大量的wince源代码中剥离出的fat文件系统源代码.移植性非常高. 里面带有source i.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
    DWORD dwReturn = (DWORD)-1;

    DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_GetFileSize(0x%x)\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)\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)\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;
        lpFileInfo->dwOID = OIDFROMSTREAM(pstm);    // TODO: YG - Investigate
    }
    __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)\n"), dwError == ERROR_SUCCESS, dwError));

    return dwError == ERROR_SUCCESS;
}


BOOL FAT_FlushFileBuffers(PFHANDLE pfh)
{
    PDSTREAM pstm;
    DWORD dwError;

    if (!BufEnter(TRUE))
        return FALSE;

    DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_FlushFileBuffers(0x%x)\n"), pfh));

    if (!(pfh->fh_mode & FH_MODE_WRITE) || (pfh->fh_flags & FHF_UNMOUNTED)) {
        dwError = ERROR_ACCESS_DENIED;
        goto exit;
    }

    pstm = pfh->fh_pstm;
    ASSERT(pstm);

    EnterCriticalSection(&pstm->s_cs);
    dwError = CommitStream(pstm, TRUE);
    LeaveCriticalSection(&pstm->s_cs);

  exit:
    if (dwError) {
        SetLastError(dwError);
    }

    DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_FlushFileBuffers returned 0x%x (%d)\n"), dwError == ERROR_SUCCESS, dwError));

    BufExit();
    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)\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)\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)\n"), pfh));

    if (!FATEnter(NULL, LOGID_NONE))
        return FALSE;

    if (!(pfh->fh_mode & FH_MODE_WRITE) || (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED))) {
        dwError = ERROR_ACCESS_DENIED;
        goto exit;
    }

    pstm = pfh->fh_pstm;
    ASSERT(pstm);

    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(LOGID_NONE);

    DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_SetFileTime returned 0x%x (%d)\n"), dwError == ERROR_SUCCESS, dwError));

    return dwError == ERROR_SUCCESS;
}


BOOL FAT_SetEndOfFile(PFHANDLE pfh)
{
    PDSTREAM pstm;
    DWORD dwError;

    DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_SetEndOfFile(0x%x)\n"), pfh));

    if (!FATEnter(pfh->fh_pstm->s_pvol, LOGID_SETENDOFFILE))
        return FALSE;

    if (!(pfh->fh_mode & FH_MODE_WRITE) || (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED))) {
        dwError = ERROR_ACCESS_DENIED;
        goto exit;
    }

    pstm = pfh->fh_pstm;
    ASSERT(pstm);

    EnterCriticalSection(&pstm->s_cs);
    dwError = ResizeStream(pstm, pfh->fh_pos, RESIZESTREAM_SHRINK|RESIZESTREAM_UPDATEFAT);
    LeaveCriticalSection(&pstm->s_cs);

  exit:
    if (dwError) {
        SetLastError(dwError);
    }

    FATExit(LOGID_SETENDOFFILE);

    DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_SetEndOfFile returned 0x%x (%d)\n"), dwError == ERROR_SUCCESS, dwError));

    return dwError == ERROR_SUCCESS;
}


BOOL FAT_DeviceIoControl(
PFHANDLE pfh,
DWORD dwIoControlCode,
LPVOID lpInBuf, DWORD nInBufSize,
LPVOID lpOutBuf, DWORD nOutBufSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped)
{
    DWORD dwError = ERROR_INVALID_PARAMETER;

    DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_DeviceIoControl(0x%x,0x%x)\n"), pfh, dwIoControlCode));

    
    // FATEnterQuick();

    if ((pfh->fh_flags & FHF_VOLUME) && !(pfh->fh_flags & FHF_UNMOUNTED)) {

        PVOLUME pvol = pfh->fh_pstm->s_pvol;

      __try {

        *lpBytesReturned = 0;

        if ((dwIoControlCode == IOCTL_DISK_GET_DEVICE_PARAMETERS ||
             dwIoControlCode == IOCTL_DISK_GET_VOLUME_PARAMETERS) &&
            nOutBufSize >= sizeof(DEVPB)) {

            QueryVolumeParameters(pvol, (PDEVPB)lpOutBuf, dwIoControlCode == IOCTL_DISK_GET_VOLUME_PARAMETERS);

            *lpBytesReturned = sizeof(DEVPB);
            dwError = ERROR_SUCCESS;
            goto exit;
        }

        if (dwIoControlCode == IOCTL_DISK_GET_FREE_SPACE && nOutBufSize >= sizeof(FREEREQ)) {

            PFREEREQ pfr = (PFREEREQ)lpOutBuf;

            if (FAT_GetDiskFreeSpaceW(pvol,
                                     NULL,
                                     &pfr->fr_SectorsPerCluster,
                                     &pfr->fr_BytesPerSector,
                                     &pfr->fr_FreeClusters,
                                     &pfr->fr_Clusters)) {
                *lpBytesReturned = sizeof(FREEREQ);
                dwError = ERROR_SUCCESS;
            }
            goto exit;
        }


        // NOTE: Callers of IOCTL_DISK_FORMAT_VOLUME and IOCTL_DISK_SCAN_VOLUME
        // need only pass the first (flags) DWORD of the corresponding FMTVOLREQ and
        // SCANVOLREQ packets;  the flags will indicate whether or not any of the
        // additional fields that we may or may not add over time are actually present.

        if (dwIoControlCode == IOCTL_DISK_FORMAT_VOLUME) {
            if (nInBufSize < sizeof(DWORD))
                lpInBuf = NULL;
            dwError = FormatVolume(pvol, (PFMTVOLREQ)lpInBuf);
            *lpBytesReturned = 0;
            goto exit;
        }

        if (dwIoControlCode == IOCTL_DISK_SCAN_VOLUME) {
            DWORD dwScanVol = SCANVOL_QUICK;
            PSCANRESULTS psr = NULL;
            if (nInBufSize >= sizeof(DWORD) && lpInBuf) {
                dwScanVol = ((PSCANVOLREQ)lpInBuf)->sv_dwScanVol;
            }
            if (nOutBufSize >= sizeof(SCANRESULTS) && lpOutBuf) {
                psr = lpOutBuf;
                psr->sr_dwScanErr = 0;
            }
            dwError = ScanVolume(pvol, dwScanVol, NULL, psr);
            if (psr)
                *lpBytesReturned = sizeof(SCANRESULTS);
            goto exit;
        }

#ifdef DEBUG
        if (dwIoControlCode == IOCTL_DISK_SET_DEBUG_ZONES && nInBufSize >= sizeof(DWORD)) {
            dpCurSettings.ulZoneMask = *(PDWORD)lpInBuf;
            dwError = ERROR_SUCCESS;
            *lpBytesReturned = 0;
            goto exit;
        }
#endif

// Last ditch attempt... if all else fails and the dwIoControlCode is
// in the valid range, pass it on to the device driver and hope for the best

        if (((dwIoControlCode >> 16) & 0xffff) != IOCTL_DISK_BASE ||
            ((dwIoControlCode >> 2) & 0xfff) < 0x080 ||
            ((dwIoControlCode >> 2) & 0xfff) >= 0x700) {
            if (!FSDMGR_DiskIoControl((HDSK)pvol->v_pdsk->d_hdsk, dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned, lpOverlapped)) {
                dwError = GetLastError();
            } else {
                dwError = ERROR_SUCCESS;
            }
            goto exit;
        }

      } __except (EXCEPTION_EXECUTE_HANDLER) {
        ;
      }
    }

  exit:
    if (dwError)
        SetLastError(dwError);

    
    DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_DeviceIoControl returned 0x%x (%d)\n"), dwError == ERROR_SUCCESS, dwError));

    return dwError == ERROR_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -