?? file.c
字號:
DWORD dwError;
ASSERT(pstm);
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_SetEndOfFile(0x%x)\r\n"), pfh));
if (!FATEnter(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;
}
EnterCriticalSection(&pstm->s_cs);
dwError = ResizeStream(pstm, pfh->fh_pos, RESIZESTREAM_SHRINK|RESIZESTREAM_UPDATEFAT);
LeaveCriticalSection(&pstm->s_cs);
exit:
if (dwError) {
SetLastError(dwError);
}
FATExit(pstm->s_pvol, LOGID_SETENDOFFILE);
DEBUGMSG(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXT("FATFS!FAT_SetEndOfFile returned 0x%x (%d)\r\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;
PVOLUME pvol = pfh->fh_pstm->s_pvol;
DEBUGMSG(ZONE_APIS,(DBGTEXT("FATFS!FAT_DeviceIoControl(0x%x,0x%x)\r\n"), pfh, dwIoControlCode));
// Deny all IOCTL access to untrusted applications
if (OEM_CERTIFY_TRUST != PSLGetCallerTrust()) {
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
}
// FATEnterQuick();
#ifdef UNDER_CE
if (dwIoControlCode == FSCTL_COPY_EXTERNAL_START) {
if (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)) {
dwError = ERROR_ACCESS_DENIED;
goto exit;
}
if (!lpInBuf || nInBufSize < sizeof(FILE_COPY_EXTERNAL)) {
dwError = ERROR_INVALID_PARAMETER;
goto exit;
}
dwError = CopyFileExternal (pfh->fh_pstm, (PFILE_COPY_EXTERNAL)lpInBuf, lpOutBuf,nOutBufSize);
goto exit;
}
if (dwIoControlCode == FSCTL_COPY_EXTERNAL_COMPLETE) {
return FSDMGR_DiskIoControl((HDSK)pvol->v_pdsk->d_hdsk, IOCTL_DISK_COPY_EXTERNAL_COMPLETE, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned, lpOverlapped);
}
#endif
if ((pfh->fh_flags & FHF_VOLUME) && !(pfh->fh_flags & FHF_UNMOUNTED)) {
__try {
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);
if (lpBytesReturned) {
*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)) {
if (lpBytesReturned) {
*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);
if (lpBytesReturned) {
*lpBytesReturned = 0;
}
goto exit;
}
if (dwIoControlCode == IOCTL_DISK_SCAN_VOLUME) {
DWORD dwScanVol = SCANVOL_QUICK;
if (nInBufSize >= sizeof(DWORD) && lpInBuf) {
dwScanVol = ((PSCANVOLREQ)lpInBuf)->sv_dwScanVol;
}
dwError = ScanVolume(pvol, dwScanVol);
if (lpBytesReturned) {
*lpBytesReturned = 0;
}
goto exit;
}
#if defined(DEBUG) && defined(UNDER_CE)
if (dwIoControlCode == IOCTL_DISK_SET_DEBUG_ZONES && nInBufSize >= sizeof(DWORD)) {
dpCurSettings.ulZoneMask = *(PDWORD)lpInBuf;
dwError = ERROR_SUCCESS;
if (lpBytesReturned) {
*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)\r\n"), dwError == ERROR_SUCCESS, dwError));
return dwError == ERROR_SUCCESS;
}
#ifdef UNDER_CE
BOOL FAT_LockFileEx(PFHANDLE pfh, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
{
PREFAST_DEBUGCHK(pfh);
return FSDMGR_InstallFileLock(AcquireFileLockState, ReleaseFileLockState, (DWORD)pfh, dwFlags, dwReserved, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, lpOverlapped);
}
BOOL FAT_UnlockFileEx(PFHANDLE pfh, DWORD dwReserved, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
{
PREFAST_DEBUGCHK(pfh);
return FSDMGR_RemoveFileLock(AcquireFileLockState, ReleaseFileLockState, (DWORD)pfh, dwReserved, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, lpOverlapped);
}
BOOL AcquireFileLockState(DWORD dwPfh, PFILELOCKSTATE *ppFileLockState)
{
PFHANDLE pfh;
PDSTREAM pstm;
BOOL fRet;
pfh = (PFHANDLE)dwPfh;
PREFAST_DEBUGCHK(pfh);
PREFAST_DEBUGCHK(ppFileLockState);
FATEnterQuick();
pstm = pfh->fh_pstm;
PREFAST_DEBUGCHK(pstm);
if (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)) {
fRet = FALSE;
goto exit;
}
if (NULL == pstm->s_filelockstate.lpcs) {
fRet = FALSE;
goto exit;
}
// TODO: what protects pfh?
// acquire file lock state; exit in ReleaseFileLockState
EnterCriticalSection(pstm->s_filelockstate.lpcs);
// fetch file position
pstm->s_filelockstate.dwPosLow = pfh->fh_pos;
pstm->s_filelockstate.dwPosHigh = 0;
// fetch create access
pstm->s_filelockstate.dwAccess = 0;
if (pfh->fh_mode & AccessToMode(GENERIC_WRITE)) {
pstm->s_filelockstate.dwAccess |= GENERIC_WRITE;
}
if (pfh->fh_mode & AccessToMode(GENERIC_READ)){
pstm->s_filelockstate.dwAccess |= GENERIC_READ;
}
// fetch file lock container
*ppFileLockState = &pstm->s_filelockstate;
fRet = TRUE;
exit:
FATExitQuick();
return fRet;
}
BOOL ReleaseFileLockState(DWORD dwPfh, PFILELOCKSTATE *ppFileLockState)
{
PFHANDLE pfh;
PDSTREAM pstm;
BOOL fRet;
pfh = (PFHANDLE)dwPfh;
PREFAST_DEBUGCHK(pfh);
PREFAST_DEBUGCHK(ppFileLockState);
FATEnterQuick();
pstm = pfh->fh_pstm;
PREFAST_DEBUGCHK(pstm);
// if volume is unmounted, then fail
if (pfh->fh_flags & (FHF_VOLUME | FHF_UNMOUNTED)) {
fRet = FALSE;
goto exit;
}
if (NULL == pstm->s_filelockstate.lpcs) {
fRet = FALSE;
goto exit;
}
// release file lock state; enter s_filelockstate.cs in AcquireFileLockState
LeaveCriticalSection(pstm->s_filelockstate.lpcs);
fRet = TRUE;
exit:
FATExitQuick();
return fRet;
}
DWORD CopyFileExternal(PDSTREAM pstm, PFILE_COPY_EXTERNAL pInCopyReq, LPVOID lpOutBuf, DWORD nOutBufSize)
{
DWORD dwRuns = 0;
PDISK_COPY_EXTERNAL pOutCopyReq = NULL;
PSECTOR_LIST_ENTRY pEntry, pSectorList;
PVOLUME pvol = pstm->s_pvol;
DWORD dwSize;
DWORD dwError = ERROR_SUCCESS;
DWORD dwPosition = 0;
// Validate input parameters
if (!pInCopyReq->pUserData && pInCopyReq->cbUserDataSize) {
return ERROR_INVALID_PARAMETER;
}
FATEnterQuick();
EnterCriticalSection(&pstm->s_cs);
// Determine the number of sector runs
RewindStream (pstm, INVALID_POS);
while (UnpackRun (pstm) != ERROR_HANDLE_EOF) {
dwRuns++;
}
dwSize = sizeof(DISK_COPY_EXTERNAL) + dwRuns * sizeof(SECTOR_LIST_ENTRY);
if ((dwSize - sizeof(DISK_COPY_EXTERNAL)) / dwRuns != sizeof(SECTOR_LIST_ENTRY)) {
// Integer overflow
dwError = ERROR_INVALID_PARAMETER;
goto exit;
}
pOutCopyReq = HeapAlloc (hHeap, 0, dwSize);
if (!pOutCopyReq) {
DEBUGMSG(ZONE_ERRORS,(DBGTEXT("FATFS!CopyFileExternal: Out of memory\r\n")));
dwError = ERROR_OUTOFMEMORY;
goto exit;
}
// Initialize the output copy request structure by copying the input
pOutCopyReq->cbSize = sizeof(DISK_COPY_EXTERNAL);
pOutCopyReq->dwDirection = pInCopyReq->dwDirection;
pOutCopyReq->pUserData = pInCopyReq->pUserData;
pOutCopyReq->cbUserDataSize = pInCopyReq->cbUserDataSize;
_tcsncpy (pOutCopyReq->szCancelEventName, pInCopyReq->szCancelEventName, MAX_PATH-1);
pOutCopyReq->szCancelEventName[MAX_PATH-1] = 0;
pOutCopyReq->hCallerProc = GetCallerProcess();
pOutCopyReq->cbSectorListSize = dwRuns * sizeof(SECTOR_LIST_ENTRY);
// Set the file size.
pOutCopyReq->ulFileSize.LowPart = pstm->s_size;
pOutCopyReq->ulFileSize.HighPart = 0;
// The sector list starts at the end of the structure.
pSectorList = (PSECTOR_LIST_ENTRY)(pOutCopyReq + 1);
pEntry = pSectorList;
// Loop through each of the cluster runs and add each one to the sector list.
RewindStream (pstm, INVALID_POS);
dwPosition = 0;
while (UnpackRun (pstm) != ERROR_HANDLE_EOF) {
RunInfo RunInfo;
dwError = GetRunInfo (&pstm->s_runList, dwPosition, &RunInfo);
if (dwError != ERROR_SUCCESS) {
goto exit;
}
pEntry->dwStartSector = (RunInfo.StartBlock >> pvol->v_log2cblkSec) + pvol->v_secBlkBias;
ASSERT (RunInfo.StartPosition <= RunInfo.EndPosition);
pEntry->dwNumSectors = (RunInfo.EndPosition - RunInfo.StartPosition + pvol->v_pdsk->d_diActive.di_bytes_per_sect - 1) /
pvol->v_pdsk->d_diActive.di_bytes_per_sect;
pEntry++;
dwPosition += RunInfo.StartPosition;
}
// For a write, invalidate the cache for these sectors, since copy external will not go
// through the cache. For a read, flush any dirty sectors first, so that the correct
// data is read from disk.
if (pvol->v_DataCacheId != INVALID_CACHE_ID) {
if (pInCopyReq->dwDirection == COPY_EXTERNAL_READ) {
FSDMGR_FlushCache (pvol->v_DataCacheId, pSectorList, dwRuns, 0);
} else {
FSDMGR_InvalidateCache (pvol->v_DataCacheId, pSectorList, dwRuns, 0);
}
}
if (!FSDMGR_DiskIoControl((HDSK)pvol->v_pdsk->d_hdsk, IOCTL_DISK_COPY_EXTERNAL_START, (LPBYTE)pOutCopyReq, dwSize, lpOutBuf, nOutBufSize, NULL, NULL)) {
dwError = GetLastError();
}
exit:
if (pOutCopyReq)
HeapFree (hHeap, 0, (HLOCAL)pOutCopyReq);
LeaveCriticalSection(&pstm->s_cs);
FATExitQuick();
return dwError;
}
#else
BOOL FAT_LockFileEx(PFHANDLE pfh, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
{
return TRUE;
}
BOOL FAT_UnlockFileEx(PFHANDLE pfh, DWORD dwReserved, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
{
return TRUE;
}
BOOL AcquireFileLockState(DWORD dwPfh, PFILELOCKSTATE *ppFileLockState)
{
return TRUE;
}
BOOL ReleaseFileLockState(DWORD dwPfh, PFILELOCKSTATE *ppFileLockState)
{
return TRUE;
}
BOOL LockPages(LPVOID lpvAddress, DWORD cbSize, PDWORD pPFNs, int fOptions)
{
return TRUE;
}
BOOL UnlockPages(LPVOID lpvAddress, DWORD cbSize)
{
return TRUE;
}
BOOL SetHandleOwner(HANDLE h, HANDLE hProc)
{
return TRUE;
}
#endif
BOOL FAT_GetVolumeInfo(PVOLUME pvol, FSD_VOLUME_INFO *pInfo)
{
pInfo->dwBlockSize = pvol->v_cbClus;
if (pvol->v_flags & VOLF_READONLY)
pInfo->dwAttributes = FSD_ATTRIBUTE_READONLY;
pInfo->dwFlags = FSD_FLAG_LOCKFILE_SUPPORTED | FSD_FLAG_WFSC_SUPPORTED;
#ifdef TFAT
if (pvol->v_fTfat)
pInfo->dwFlags |= FSD_FLAG_TRANSACTION_SAFE;
if (pvol->v_flFATFS & FATFS_TRANS_DATA)
pInfo->dwFlags |= FSD_FLAG_TRANSACT_WRITES;
#endif
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -