?? apis.c
字號:
/*++Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved.Module Name: apis.cAbstract: This file contains the FSDMGR entry points for all supported file system APIs.--*/#define KEEP_SYSCALLS // for kernel.h only#define NO_DEFINE_KCALL // for kernel.h only#include "kernel.h"#include "fsdmgrp.h"#define KERNELCALLSTACK(pcstk) (((DWORD)(pcstk)->retAddr & 0xf0000000) == 0x80000000)/* FSDMGR_SystemCanDeadlock - Determine if caller is kernel * * ENTRY * pvol -> VOL structure * * EXIT * TRUE if caller is kernel, FALSE if not * * NOTES * We need this special power-down test before calling FSDMGR_Enter so * that if/when the loader tries to open PCMCIA drivers before we have * received the FSNOTIFY_DEVICES_ON notification, we will fail the * call instead of blocking it. */BOOL FSDMGR_SystemCanDeadlock(PVOL pVol){ // If we're in a "shutdown" state, meaning all calls to FATEnter will // block until FSNOTIFY_DEVICES_ON is issued, then we need to make this // check in a few key places (ie, where the kernel may call us) in order // to prevent a deadlock.//#if 0 PTHREAD pth; PCALLSTACK pcstk; if (!(pVol->dwFlags & VOL_POWERDOWN)) return FALSE; pth = ((PHDATA)((GetCurrentThreadId() & HANDLE_ADDRESS_MASK) + 0x80000000))->pvObj; if (pcstk = pth->pcstkTop) { if (KERNELCALLSTACK(pcstk) || (pcstk = pcstk->pcstkNext) && KERNELCALLSTACK(pcstk)) { SetLastError(ERROR_ACCESS_DENIED); return TRUE; } }//#endif return FALSE;}/* FSDMGR_Enter - Tracks (and potentially blocks) threads entering an FSD * * ENTRY * pVol -> VOL structure * * EXIT * None * * NOTES * It's not strictly necessary to keep track of threads entering * an FSD on a per-volume basis, or to block them on such a basis -- * these functions could just as easily perform their task using globals. */ void FSDMGR_Enter(PVOL pVol){ ASSERT(VALIDSIG(pVol, VOL_SIG)); if (pVol->dwFlags & VOL_POWERDOWN) WaitForSingleObject(pVol->hevPowerUp, INFINITE); InterlockedIncrement(&pVol->cThreads);}/* FSDMGR_Exit - Tracks threads leaving an FSD (and can signal when the last one leaves) * * ENTRY * pVol -> VOL structure * * EXIT * None * * NOTES * See FSDMGR_Enter for notes. */void FSDMGR_Exit(PVOL pVol){ ASSERT(VALIDSIG(pVol, VOL_SIG)); if (InterlockedDecrement(&pVol->cThreads) == 0) { if (pVol->dwFlags & VOL_POWERDOWN) SetEvent(pVol->hevPowerDown); }}/* FSDMGR_CloseVolume - Called when a volume is being deregistered * * ENTRY * pVol -> VOL structure * * EXIT * Always returns TRUE (that's what OUR stub always does, and it's * expected that that's what FSDs will do too, if they even care to hook * this entry point). */BOOL FSDMGR_CloseVolume(PVOL pVol){ return pVol->pDsk->pFSD->apfnAFS[AFSAPI_CLOSEVOLUME](pVol->dwVolData);}/* FSDMGR_CreateDirectoryW - Create a new subdirectory * * ENTRY * pVol -> VOL structure * pwsPathName - pointer to name of new subdirectory * pSecurityAttributes - pointer to security attributes (ignored) * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) */BOOL FSDMGR_CreateDirectoryW(PVOL pVol, PCWSTR pwsPathName, PSECURITY_ATTRIBUTES pSecurityAttributes){ BOOL f; FSDMGR_Enter(pVol); f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_CREATEDIRECTORYW](pVol->dwVolData, pwsPathName, pSecurityAttributes); FSDMGR_Exit(pVol); return f;}/* FSDMGR_RemoveDirectoryW - Destroy an existing subdirectory * * ENTRY * pVol -> VOL structure * pwsPathName - pointer to name of existing subdirectory * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) */BOOL FSDMGR_RemoveDirectoryW(PVOL pVol, PCWSTR pwsPathName){ BOOL f; FSDMGR_Enter(pVol); f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_REMOVEDIRECTORYW](pVol->dwVolData, pwsPathName); FSDMGR_Exit(pVol); return f;}/* FSDMGR_GetFileAttributesW - Get file/subdirectory attributes * * ENTRY * pVol -> VOL structure * pwsFileName - pointer to name of existing file/subdirectory * * EXIT * Attributes of file/subdirectory if it exists, 0xFFFFFFFF if it * does not (call GetLastError for error code). */DWORD FSDMGR_GetFileAttributesW(PVOL pVol, PCWSTR pwsFileName){ DWORD dw; FSDMGR_Enter(pVol); dw = pVol->pDsk->pFSD->apfnAFS[AFSAPI_GETFILEATTRIBUTESW](pVol->dwVolData, pwsFileName); FSDMGR_Exit(pVol); return dw;}/* FSDMGR_SetFileAttributesW - Set file/subdirectory attributes * * ENTRY * pVol -> VOL structure * pwsFileName - pointer to name of existing file/subdirectory * dwAttributes - new attributes for file/subdirectory * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) */BOOL FSDMGR_SetFileAttributesW(PVOL pVol, PCWSTR pwsFileName, DWORD dwAttributes){ BOOL f; FSDMGR_Enter(pVol); f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_SETFILEATTRIBUTESW](pVol->dwVolData, pwsFileName, dwAttributes); FSDMGR_Exit(pVol); return f;}/* FSDMGR_DeleteFileW - Delete file * * ENTRY * pVol -> VOL structure * pwsFileName - pointer to name of existing file * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) * * NOTES * A file marked FILE_ATTRIBUTE_READONLY cannot be deleted. You have to * remove that attribute first, with SetFileAttributes. * * An open file cannot be deleted. All open handles must be closed first. * * A subdirectory cannot be deleted with this call either. You have to * use RemoveDirectory instead. */BOOL FSDMGR_DeleteFileW(PVOL pVol, PCWSTR pwsFileName){ BOOL f; FSDMGR_Enter(pVol); f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_DELETEFILEW](pVol->dwVolData, pwsFileName); FSDMGR_Exit(pVol); return f;}/* FSDMGR_MoveFileW * * ENTRY * pVol -> VOL structure * pwsOldFileName - pointer to name of existing file * pwsNewFileName - pointer to new name for file * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) * * NOTES * We call FindFirst once to obtain the source directory stream for the * for the existing file, and if it really exists, we call FindFirst * again to obtain the destination directory stream for the new file, * verifying that the new name does NOT exist. Then we create the new * name and destroy the old. * * When moving a directory, we must make sure that our traversal * of the destination path does not cross the source directory, otherwise * we will end up creating a circular directory chain. */BOOL FSDMGR_MoveFileW(PVOL pVol, PCWSTR pwsOldFileName, PCWSTR pwsNewFileName){ BOOL f; FSDMGR_Enter(pVol); f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_MOVEFILEW](pVol->dwVolData, pwsOldFileName, pwsNewFileName); FSDMGR_Exit(pVol); return f;}/* FSDMGR_DeleteAndRenameFileW * * ENTRY * pVol -> VOL structure * pwsOldFileName - pointer to name of existing file * pwsNewFileName - pointer to name of file to be renamed to existing file * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) */BOOL FSDMGR_DeleteAndRenameFileW(PVOL pVol, PCWSTR pwsOldFileName, PCWSTR pwsNewFileName){ BOOL f; FSDMGR_Enter(pVol); f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_PRESTOCHANGOFILENAME](pVol->dwVolData, pwsOldFileName, pwsNewFileName); FSDMGR_Exit(pVol); return f;}/* FSDMGR_GetFreeDiskSpaceW * * ENTRY * pVol -> VOL structure * pwsPathName -> volume name (eg, "\Storage Card") * pSectorsPerCluster -> DWORD to receive sectors/cluster * pBytesPerSector -> DWORD to receive bytes/sector * pFreeClusters -> DWORD to receive available clusters on volume * pClusters -> DWORD to receive total clusters on volume * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) */BOOL FSDMGR_GetDiskFreeSpaceW(PVOL pVol, PCWSTR pwsPathName, PDWORD pSectorsPerCluster, PDWORD pBytesPerSector, PDWORD pFreeClusters, PDWORD pClusters){ BOOL f; FSDMGR_Enter(pVol); f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_GETDISKFREESPACE](pVol->dwVolData, pwsPathName, pSectorsPerCluster, pBytesPerSector, pFreeClusters, pClusters); FSDMGR_Exit(pVol); return f;}/* FSDMGR_CloseAllFiles (no FSD equivalent) * * ENTRY * pVol -> VOL structure * hProc == handle of terminating process * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) */BOOL FSDMGR_CloseAllFiles(PVOL pVol, HANDLE hProc){ PHDL pHdl; FSDMGR_Enter(pVol);loop1: pHdl = pVol->dlHdlList.pHdlNext; while (pHdl != (PHDL)&pVol->dlHdlList) { if (pHdl->hProc == hProc) { SetHandleOwner(pHdl->h, GetCurrentProcess()); if (CloseHandle(pHdl->h)) goto loop1; // handle was freed, state of our list has changed } pHdl = pHdl->dlHdl.pHdlNext; } FSDMGR_Exit(pVol); return TRUE;}/* FSDMGR_CommitAllFiles (no FSD equivalent) * * ENTRY * pVol -> VOL structure * * EXIT * TRUE if successful, FALSE if not (call GetLastError for error code) */BOOL FSDMGR_CommitAllFiles(PVOL pVol){ PHDL pHdl; // There ain't no steenkin' FSDMGR_Enter/FSDMGR_Exit calls in this function // because it's called during FSNOTIFY_POWER_OFF and we don't want to hang ourselves. pHdl = pVol->dlHdlList.pHdlNext; while (pHdl != (PHDL)&pVol->dlHdlList) { pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_FLUSHFILEBUFFERS](pHdl->dwHdlData); pHdl = pHdl->dlHdl.pHdlNext; } return TRUE;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -