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

📄 api.c

📁 从大量的wince源代码中剥离出的fat文件系统源代码.移植性非常高. 里面带有source i.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
    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(BYTE idLog)
{
    BufExit();

    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) {

        HKEY hKeyFATFS;
        BYTE b;
        DWORD dwFlags;
        DWORD cb, dw, dwError;

        dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, awcFATFS, 0, KEY_ALL_ACCESS, &hKeyFATFS);
        if (!dwError) {
            cb = sizeof(dwFlags);
            if (RegQueryValueEx(hKeyFATFS, awcFlags, NULL, &dw, (PBYTE)&dwFlags, &cb) == ERROR_SUCCESS && cb == sizeof(dwFlags)) {
                flFATFS |= (dwFlags & FATFS_REGISTRY_FLAGS);
                DEBUGMSG(ZONE_INIT && (dwFlags & ~FATFS_REGISTRY_FLAGS),(DBGTEXT("FATFS!FATAttach: unsupported bits set in registry flags: 0x%08x\n"), dwFlags & ~FATFS_REGISTRY_FLAGS));
            }
            cb = sizeof(b);
            if (RegQueryValueEx(hKeyFATFS, awcUpdateAccess, NULL, &dw, &b, &cb) == ERROR_SUCCESS && cb == sizeof(b)) {
                if (b)
                    flFATFS |= FATFS_UPDATE_ACCESS;
            }
            RegCloseKey(hKeyFATFS);
        }
        DEBUGREGISTER(hFATFS);

        DEBUGMSGW(ZONE_INIT,(DBGTEXTW("FATFS!FATAttach: access time updates %s\n"), flFATFS & FATFS_UPDATE_ACCESS? TEXTW("enabled") : TEXTW("disabled")));
        DEBUGMSGW(ZONE_INIT,(DBGTEXTW("FATFS!FATAttach: event logging %s\n"), flFATFS & FATFS_DISABLE_LOG? TEXTW("disabled") : TEXTW("enabled")));
        DEBUGMSGW(ZONE_INIT,(DBGTEXTW("FATFS!FATAttach: automatic scanning %s\n"), flFATFS & FATFS_DISABLE_AUTOSCAN? TEXTW("disabled") : TEXTW("enabled")));
        DEBUGMSGW(ZONE_INIT,(DBGTEXTW("FATFS!FATAttach: write verify %s\n"), flFATFS & FATFS_VERIFY_WRITES? TEXTW("enabled") : (flFATFS & FATFS_DISABLE_AUTOSCAN? TEXTW("disabled") : TEXTW("enabled on first 3 writes"))));
        DEBUGMSGW(ZONE_INIT,(DBGTEXTW("FATFS!FATAttach: extra FAT on format %s\n"), flFATFS & FATFS_ENABLE_BACKUP_FAT? TEXTW("enabled") : TEXTW("disabled")));

        InitList((PDLINK)&dlDisks);

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

        fInit = BufInit();

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

    }
    return hevStartup && hevShutdown && 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()
{
#if 0
    ASSERT(cLoads > 0);

    if (--cLoads == 0) {

                
        int n = 300;

        // Since we're being unloaded, make absolutely sure every thread
        // is out, so that we leave the volume in a consistent state.  The
        // first step in preventing anyone NEW from getting in is closing
        // all our API handles.


        do {
            // Give hevBufThreads a kick in case we've got any threads
            // stacked up inside BufEnter;  no *new* threads should be stacking
            // up, since cLoads == 0 now.  Do the same to get rid of the lazy-writer.

            SetEvent(hevBufThreads);

            
#ifndef UNDER_CE
            Sleep(0);
#else
            Sleep(50);
#endif
            if (cFATThreads == 0 && cBufThreads == cBufThreadsOrig || --n == 0)
                break;

            DEBUGMSGBREAK(TRUE, (DBGTEXT("FATFS!FATDetach: %d threads still active (%d using buffers) even after sleeping!\n"), cFATThreads, cBufThreadsOrig-cBufThreads));
        }
        while (TRUE);

        // Simulating a power-off notification now will make sure that any other
        // threads that were ALREADY inside are gone by the time this returns.
        // As always, the most important reason for doing this is trying to insure
        // that all volumes are left in a consistent state.  WARNING: you don't
        // want to do this *before* the sleep loop above, because otherwise one of 
        // those hypothetical "just *about* to enter us" threads will see that 
        // FATFS_SHUTDOWN is set and block forever. -JTP

        FAT_Notify(NULL, FSNOTIFY_POWER_OFF);
#endif
        // 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);

        BufDeinit();

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

        DEBUGFREE(DEBUGALLOC_CS);
        DeleteCriticalSection(&csFATFS);
#ifdef DEBUG
        DEBUGFREE(DEBUGALLOC_CS);
        DeleteCriticalSection(&csAlloc);
#endif
        // Assert that all allocations, buffers, etc, were freed

//YG        DEBUGMSGBREAK(cbAlloc != 0, (DBGTEXT("FATFS!FATDetach: cbAlloc(0x%x) != 0\n"), cbAlloc));
        ASSERT(cbufTotal == 0 && cbufError == 0);

        DEBUGMSG(ZONE_INIT,(DBGTEXT("FATFS!FATDetach complete (%d sectors written in %d requests)\n"), csecWrite, creqWrite));
#if 0
    }
#endif    
    return TRUE;
}


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

    wsprintf(szName, L"%08X", hDsk);

    DEBUGMSGW(ZONE_INIT || ZONE_APIS,(DBGTEXTW("FSD_MountDisk: mounting volumes for hDsk=%08X\n"), hDsk));

    flVol = VOLF_NONE;

    // TODO: Add a function to FSDMGR to figure out READONLY Volumes
    // TODO:         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\n"), pdsk));
    return (pdsk != NULL);
}



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

    DEBUGMSG(ZONE_INIT || ZONE_APIS,(DBGTEXT("FSD_UnmountDisk(0x%x): unmounting...\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\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\n")));
        hFATFS = (HINSTANCE)DllInstance;
        return FATAttach();

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

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

⌨️ 快捷键说明

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