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

📄 api.c

📁 Windows操作系统中文件系统过滤驱动和设备驱动之间的相似
💻 C
📖 第 1 页 / 共 2 页
字号:
 *      Commit/close functions are exempted simply to allow us to block all
 *      threads and cleanly flush/unmount a volume without deadlocking.
 */

BOOL FATEnter(PVOLUME pvol, BYTE idLog)
{
    if (cLoads == 0) {
        SetLastError(ERROR_NOT_READY);
        return FALSE;
    }
    InterlockedIncrement(&cFATThreads);

    if (!BufEnter(pvol, FALSE)) {
        DEBUGMSGW(ZONE_ERRORS, (DBGTEXTW("FATFS!FATEnter: BufEnter failed, failing API request!\r\n")));
        InterlockedDecrement(&cFATThreads);
        return FALSE;
    }

    return TRUE;
}

void FATEnterQuick(void)
{
    InterlockedIncrement(&cFATThreads);
}


/*  FATExit  - Gates threads exiting FATFS
 *
 *  ENTRY
 *      idLog - one of the LOGID_* equates
 *
 *  EXIT
 *      None
 *
 *  NOTES
 *      Called at the end of most FATFS API entry points.  If we are
 *      the last thread, and the shutdown bit is set, then we will signal
 *      the shutdown event.  The shutdown event is initially reset AND
 *      auto-reset.
 *
 *      Also, if there is any risk of code inside here modifying the error code
 *      we set via SetLastError (if any), then that code must always save/restore
 *      the last error code.  I think even if all the APIs it calls succeeds, some 
 *      of those APIs may do something like "SetLastError(0)" when they initialize, 
 *      so we have to guard against that.
 *
 *  QUALIFICATIONS
 *      This is currently called only on every FATFS API entry point that
 *      could possibly generate I/O (with the exception of commit/close).  If
 *      a thread slips into GetFileTime, for example, who cares?  This could be
 *      restricted even further, and called only on entry points that could
 *      possibly generate WRITES, but since we ALSO want to ensure that shutdowns
 *      are timely (as well as safe), preventing as much I/O as possible seems
 *      worthwhile.
 *
 *      Commit/close functions are exempted simply to allow us to block all
 *      threads and cleanly flush/unmount a volume without deadlocking.
 */

void FATExit(PVOLUME pvol, BYTE idLog)
{
    BufExit(pvol);

    if (InterlockedDecrement(&cFATThreads) == 0) {
    }
}

void FATExitQuick(void)
{
    InterlockedDecrement(&cFATThreads);
}




/*  FATAttach - DLL_PROCESS_ATTACH handler
 *
 *  ENTRY
 *      None
 *
 *  EXIT
 *      TRUE if successful, FALSE if not.  Most failures can probably
 *      be attributed to insufficient memory.
 *
 *  NOTES
 *      This is assumed to be protected by a critical section.  Since it is
 *      currently called only by FATMain, we are protected by the loader's
 *      critical section.
 */

BOOL FATAttach()
{
    BOOL fInit = TRUE;

    if (cLoads++ == 0) {
        DEBUGREGISTER(hFATFS);
        
        InitList((PDLINK)&dlDisks);

#ifdef DEBUG
        InitializeCriticalSection(&csAlloc);
        DEBUGALLOC(DEBUGALLOC_CS);
#endif
        InitializeCriticalSection(&csFATFS);
        DEBUGALLOC(DEBUGALLOC_CS);

        hevStartup  = CreateEvent(NULL, TRUE, TRUE, NULL);
        DEBUGALLOC(DEBUGALLOC_EVENT);
        hevShutdown = CreateEvent(NULL, FALSE, FALSE, NULL);
        DEBUGALLOC(DEBUGALLOC_EVENT);

        hHeap = HeapCreate (0, 0x1000, 0);
    }
    return hevStartup && hevShutdown && hHeap && fInit;
}


/*  FATDetach - DLL_PROCESS_DETACH handler
 *
 *  ENTRY
 *      None
 *
 *  EXIT
 *      TRUE if successful, FALSE if not (currently, it always returns TRUE)
 *
 *  NOTES
 *      This is assumed to be protected by a critical section.  Since it is
 *      currently called only by FATMain, we are protected by the loader's
 *      critical section.
 */

BOOL FATDetach()
{
        // Now make sure every file is closed and every volume is freed,
        // so that we don't leak any memory.  We have deliberately omitted
        // FATEnter/FATExit from FAT_CloseAllFiles and FAT_CloseFile
        // to avoid deadlocking if any files *do* need to be closed.

        UnmountAllDisks(FALSE);

        DEBUGFREE(DEBUGALLOC_EVENT);
        CloseHandle(hevShutdown);
        DEBUGFREE(DEBUGALLOC_EVENT);
        CloseHandle(hevStartup);

        DEBUGFREE(DEBUGALLOC_CS);
        DeleteCriticalSection(&csFATFS);
#ifdef DEBUG
        DEBUGFREE(DEBUGALLOC_CS);
        DeleteCriticalSection(&csAlloc);
#endif

        HeapDestroy (hHeap);
    
        DEBUGMSG(ZONE_INIT,(DBGTEXT("FATFS!FATDetach complete (%d sectors written in %d requests)\r\n"), csecWrite, creqWrite)); 
        return TRUE;
}


BOOL FSD_MountDisk(HDSK hDsk)
{
    DWORD flVol;
    PDSK pdsk = NULL;
    TCHAR szName[MAX_PATH];
    STORAGEDEVICEINFO sdi;
    DWORD dwRet;

    wsprintf(szName, L"%08X", hDsk);
    RETAILMSG(1,(L"FSD_MountDisk hDsk=%08X\r\n",hDsk));
    DEBUGMSGW(ZONE_INIT || ZONE_APIS,(DBGTEXTW("FSD_MountDisk: mounting volumes for hDsk=%08X\r\n"), hDsk));

    flVol = VOLF_NONE;
    
    memset (&sdi, 0, sizeof(STORAGEDEVICEINFO));
    sdi.cbSize = sizeof(STORAGEDEVICEINFO);
    
    if (FSDMGR_DiskIoControl(hDsk, IOCTL_DISK_DEVICE_INFO, &sdi, sizeof(STORAGEDEVICEINFO), NULL, 0, &dwRet, NULL)) {
        if (sdi.dwDeviceFlags & STORAGE_DEVICE_FLAG_READONLY) {
            flVol = VOLF_READONLY;
        }
    }

    DEBUGALLOC(DEBUGALLOC_HANDLE);

    pdsk = MountDisk((HANDLE)hDsk, szName, flVol);

    if (pdsk) {
        pdsk->d_flags |= flVol;     // VOLF_READONLY maps to DSKF_READONLY

        if (pdsk->d_flags & (DSKF_REMOUNTED | DSKF_RECYCLED)) {
            // Make sure the REMOUNT bit in the VOLUME pointer is set
            (DWORD)pdsk |= 0x1;
        }
    }
    
    DEBUGMSG(ZONE_APIS,(DBGTEXT("FSD_Init returned 0x%x\r\n"), pdsk));
    return (pdsk != NULL);
}



BOOL FSD_UnmountDisk(HDSK hDsk)
{
    BOOL fSuccess = TRUE;
    PDSK pdsk = NULL;

    DEBUGMSG(ZONE_INIT || ZONE_APIS,(DBGTEXT("FSD_UnmountDisk(0x%x): unmounting...\r\n"), hDsk));
    RETAILMSG(1,(L"FSD_UnmountDisk 0x%x\r\n",hDsk));
    EnterCriticalSection(&csFATFS);
    if (!hDsk) {
        // Unmount all volumes still marked frozen on all disks
        fSuccess = UnmountAllDisks(TRUE);
    }
    else if (pdsk = FindDisk((HANDLE)hDsk, NULL, NULL)) {
        // Make sure the REMOUNT bit in the VOLUME pointer is clear
        (DWORD)pdsk &= ~1;
        fSuccess = UnmountDisk(pdsk, FALSE);
    }
    LeaveCriticalSection( &csFATFS);
    DEBUGMSG(ZONE_APIS,(DBGTEXT("FSD_Deinit(0x%x) returned %d\r\n"), pdsk, fSuccess));
    return fSuccess;
}


/*  FATMain - FATFS.DLL initialization entry point
 *
 *  ENTRY
 *      DllInstance - DLL module handle
 *      Reason - DLL_* initialization message
 *      Reserved - reserved
 *
 *  EXIT
 *      TRUE if successful, FALSE if not.  Most failures can probably
 *      be attributed to insufficient memory.
 */

BOOL WINAPI DllMain(HANDLE DllInstance, DWORD Reason, LPVOID Reserved)
{
    switch(Reason) {

    case DLL_PROCESS_ATTACH:

        // DEBUGMSG(ZONE_INIT,(DBGTEXT("FATFS!FATMain: DLL_PROCESS_ATTACH\r\n")));

		
        DisableThreadLibraryCalls( (HMODULE)DllInstance);
        hFATFS = (HINSTANCE)DllInstance;
        return FATAttach();

    case DLL_PROCESS_DETACH:
      //DEBUGMSG(ZONE_INIT,(DBGTEXT("FATFS!FATMain: DLL_PROCESS_DETACH\r\n")));
        return FATDetach();

    default:
      //DEBUGMSG(ZONE_INIT,(DBGTEXT("FATFS!FATMain: Reason #%d ignored\r\n"), Reason));
        break;
    }
    return TRUE;
}

⌨️ 快捷键说明

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