?? api.c
字號(hào):
* 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;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -