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

📄 apis.c

📁 wince3.0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1997-2000 Microsoft Corporation.  All rights reserved.

Module Name:

    apis.c

Abstract:

    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 + -