📄 apis.c
字号:
/* FSDMGR_Notify - FSD notification handler
*
* ENTRY
* pVol -> VOL structure
* dwFlags == one or more FSNOTIFY_* flags
*
* EXIT
* None.
*
* NOTES
* This function is invoked once per registered volume every time the
* power goes off, comes back, or devices have finished initializing. I'm
* only interested in hooking the FSNOTIFY_POWER_ON notification, so that I
* can flag all relevant disks as UNCERTAIN, but unfortunately, I cannot
* avoid being called for all events, not to mention multiple times per disk
* if there are multiple volumes per disk.
*/
void FSDMGR_Notify(PVOL pVol, DWORD dwFlags)
{
ASSERT(VALIDSIG(pVol, VOL_SIG));
if (dwFlags & FSNOTIFY_POWER_OFF) {
DEBUGMSGW(ZONE_POWER,(DBGTEXTW("FSDMGR_Notify(FSNOTIFY_POWER_OFF)\n")));
// hevPowerDown is signalled (set) as soon as the last thread exits
// during VOL_POWERDOWN. Even though it is auto-reset, we manually
// reset it now, because the last thread on a previous power-down could
// have decremented pVol->cThreads to zero and set hevPowerDown before
// we made it to the test-and-wait code below, thus leaving hevPowerDown
// in a signaled state.
ResetEvent(pVol->hevPowerDown);
// hevPowerUp stops threads in FSDMGR_Enter during VOL_POWERDOWN, and is
// signalled (set) as soon as we receive FSNOTIFY_DEVICES_ON notification.
ResetEvent(pVol->hevPowerUp);
pVol->dwFlags |= VOL_POWERDOWN;
// We know at this point that no more threads can get in. There
// may still be threads inside. If not, pVol->cThreads is zero.
// Otherwise, we will block, and the last thread's FSDMGR_Exit call will
// wake us up. We have to do this repeatedly, because a thread may
// have erroneously thought it was the last one.
while (pVol->cThreads)
WaitForSingleObject(pVol->hevPowerDown, INFINITE);
// Now make sure all files are committed; this function calls the FSD's
// FlushFileBuffers entry point directly, instead of calling our external
// FSDMGR_FlushFileBuffers function, thereby insuring that we won't deadlock
// ourselves, now that VOL_POWERDOWN has been set....
FSDMGR_CommitAllFiles(pVol);
DEBUGMSGW(ZONE_POWER,(DBGTEXTW("FSDMGR_Notify(FSNOTIFY_POWER_OFF): all threads blocked for %s\n"), pVol->wsVol));
}
else if (dwFlags & FSNOTIFY_POWER_ON) {
DEBUGMSGW(ZONE_POWER && !(pVol->pDsk->dwFlags & DSK_UNCERTAIN),(DBGTEXTW("FSDMGR_Notify(FSNOTIFY_POWER_ON): marking %s uncertain\n"), pVol->pDsk->wsDsk));
MarkDisk(pVol->pDsk, DSK_UNCERTAIN);
}
else if (dwFlags & FSNOTIFY_DEVICES_ON) {
DEBUGMSG(ZONE_POWER,(DBGTEXT("FSDMGR_Notify(FSNOTIFY_DEVICES_ON): unblocking all threads for %s\n"), pVol->wsVol));
pVol->dwFlags &= ~VOL_POWERDOWN;
SetEvent(pVol->hevPowerUp);
}
// Now pass the notification on to the FSD as well; in general, they shouldn't
// need to do very much on these events, because we've tried to take care of the
// hard problems already, and these events need to be responsive.
// However, one common requirement is flushing all non-handle-based data (eg,
// dirty buffers) on the FSNOTIFY_POWER_OFF event. We could ask the FSDs to
// export a special "Flush" interface that we can call from here, but that seems
// like a pointless abstraction, especially given that other interesting FSNOTIFY
// events may be added in the future and I'd rather not have to rev FSDMGR just
// for that.
pVol->pDsk->pFSD->apfnAFS[AFSAPI_NOTIFY](pVol->dwVolData, dwFlags);
}
/* FSDMGR_RegisterFileSystemFunction
*
* ENTRY
* pVol -> VOL structure
* pfn -> function address to call
*
* EXIT
* TRUE if supported, FALSE if not
*/
BOOL FSDMGR_RegisterFileSystemFunction(PVOL pVol, SHELLFILECHANGEFUNC_t pfn)
{
BOOL f;
FSDMGR_Enter(pVol);
f = pVol->pDsk->pFSD->apfnAFS[AFSAPI_REGISTERFILESYSTEMFUNCTION](pVol->dwVolData, pfn);
FSDMGR_Exit(pVol);
return f;
}
/* FSDMGR_FindFirstFileW
*
* ENTRY
* pVol -> VOL structure
* hProc == handle of originating process
* pwsFileSpec -> name of file(s), wildcards allowed
* pfd -> WIN32_FIND_DATAW to be filled in on success
*
* EXIT
* HANDLE to be used with subsequent FindNextFileW() and FindClose() APIs,
* or INVALID_HANDLE_VALUE if error.
*/
HANDLE FSDMGR_FindFirstFileW(PVOL pVol, HANDLE hProc, PCWSTR pwsFileSpec, PWIN32_FIND_DATAW pfd)
{
HANDLE h;
FSDMGR_Enter(pVol);
h = (HANDLE)pVol->pDsk->pFSD->apfnAFS[AFSAPI_FINDFIRSTFILEW](pVol->dwVolData, hProc, pwsFileSpec, pfd);
FSDMGR_Exit(pVol);
return h;
}
/* FSDMGR_FindNextFileW
*
* ENTRY
* pHdl -> HDL structure
* pfd -> WIN32_FIND_DATAW to be filled in on success
*
* EXIT
* TRUE if successful, FALSE if not (call GetLastError for error code)
*/
BOOL FSDMGR_FindNextFileW(PHDL pHdl, PWIN32_FIND_DATAW pfd)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFind[FINDAPI_FINDNEXTFILEW](pHdl->dwHdlData, pfd);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_FindClose
*
* ENTRY
* pHdl -> HDL structure
*
* EXIT
* TRUE if successful, FALSE if not (call GetLastError for error code)
*/
BOOL FSDMGR_FindClose(PHDL pHdl)
{
BOOL f = FALSE;
PVOL pVol = pHdl->pVol;
FSDMGR_Enter(pVol);
if (pVol->pDsk->pFSD->apfnFind[FINDAPI_FINDCLOSE](pHdl->dwHdlData)) {
DeallocFSDHandle(pHdl);
f = TRUE;
}
FSDMGR_Exit(pVol);
return f;
}
/* FSDMGR_CreateFileW
*
* ENTRY
* pVol -> VOL structure
* hProc == handle of originating process
* pwsFileName
*
* EXIT
* TRUE if successful, FALSE if not (call GetLastError for error code)
*/
HANDLE FSDMGR_CreateFileW(PVOL pVol, HANDLE hProc, PCWSTR pwsFileName, DWORD dwAccess, DWORD dwShareMode, PSECURITY_ATTRIBUTES pSecurityAttributes, DWORD dwCreate, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
HANDLE h;
if (FSDMGR_SystemCanDeadlock(pVol))
return INVALID_HANDLE_VALUE;
FSDMGR_Enter(pVol);
h = (HANDLE)pVol->pDsk->pFSD->apfnAFS[AFSAPI_CREATEFILEW](pVol->dwVolData, hProc, pwsFileName, dwAccess, dwShareMode, pSecurityAttributes, dwCreate, dwFlagsAndAttributes, hTemplateFile);
FSDMGR_Exit(pVol);
return h;
}
/* FSDMGR_ReadFile
*/
BOOL FSDMGR_ReadFile(PHDL pHdl, PVOID pBuffer, DWORD cbRead, PDWORD pcbRead, OVERLAPPED *pOverlapped)
{
BOOL f;
if (FSDMGR_SystemCanDeadlock(pHdl->pVol))
return FALSE;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_READFILE](pHdl->dwHdlData, pBuffer, cbRead, pcbRead, pOverlapped);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_ReadFileWithSeek
*/
BOOL FSDMGR_ReadFileWithSeek(PHDL pHdl, PVOID pBuffer, DWORD cbRead, PDWORD pcbRead, OVERLAPPED *pOverlapped, DWORD dwLowOffset, DWORD dwHighOffset)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_READFILEWITHSEEK](pHdl->dwHdlData, pBuffer, cbRead, pcbRead, pOverlapped, dwLowOffset, dwHighOffset);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_WriteFile
*/
BOOL FSDMGR_WriteFile(PHDL pHdl, PVOID pBuffer, DWORD cbWrite, PDWORD pcbWritten, OVERLAPPED *pOverlapped)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_WRITEFILE](pHdl->dwHdlData, pBuffer, cbWrite, pcbWritten, pOverlapped);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_WriteFileWithSeek
*/
BOOL FSDMGR_WriteFileWithSeek(PHDL pHdl, PVOID pBuffer, DWORD cbWrite, PDWORD pcbWritten, OVERLAPPED *pOverlapped, DWORD dwLowOffset, DWORD dwHighOffset)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_WRITEFILEWITHSEEK](pHdl->dwHdlData, pBuffer, cbWrite, pcbWritten, pOverlapped, dwLowOffset, dwHighOffset);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_SetFilePointer
*/
DWORD FSDMGR_SetFilePointer(PHDL pHdl, LONG lDistanceToMove, PLONG pDistanceToMoveHigh, DWORD dwMoveMethod)
{
DWORD dw;
FSDMGR_Enter(pHdl->pVol);
dw = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_SETFILEPOINTER](pHdl->dwHdlData, lDistanceToMove, pDistanceToMoveHigh, dwMoveMethod);
FSDMGR_Exit(pHdl->pVol);
return dw;
}
/* FSDMGR_GetFileSize
*/
DWORD FSDMGR_GetFileSize(PHDL pHdl, PDWORD pFileSizeHigh)
{
DWORD dw;
FSDMGR_Enter(pHdl->pVol);
dw = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_GETFILESIZE](pHdl->dwHdlData, pFileSizeHigh);
FSDMGR_Exit(pHdl->pVol);
return dw;
}
/* FSDMGR_GetFileInformationByHandle
*/
BOOL FSDMGR_GetFileInformationByHandle(PHDL pHdl, PBY_HANDLE_FILE_INFORMATION pFileInfo)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_GETFILEINFORMATIONBYHANDLE](pHdl->dwHdlData, pFileInfo);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_FlushFileBuffers
*/
BOOL FSDMGR_FlushFileBuffers(PHDL pHdl)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_FLUSHFILEBUFFERS](pHdl->dwHdlData);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_GetFileTime
*/
BOOL FSDMGR_GetFileTime(PHDL pHdl, FILETIME *pCreation, FILETIME *pLastAccess, FILETIME *pLastWrite)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_GETFILETIME](pHdl->dwHdlData, pCreation, pLastAccess, pLastWrite);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_SetFileTime
*/
BOOL FSDMGR_SetFileTime(PHDL pHdl, CONST FILETIME *pCreation, CONST FILETIME *pLastAccess, CONST FILETIME *pLastWrite)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_SETFILETIME](pHdl->dwHdlData, pCreation, pLastAccess, pLastWrite);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_SetEndOfFile
*/
BOOL FSDMGR_SetEndOfFile(PHDL pHdl)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_SETENDOFFILE](pHdl->dwHdlData);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_DeviceIoControl
*/
BOOL FSDMGR_DeviceIoControl(PHDL pHdl, DWORD dwIoControlCode, PVOID pInBuf, DWORD nInBufSize, PVOID pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned, OVERLAPPED *pOverlapped)
{
BOOL f;
FSDMGR_Enter(pHdl->pVol);
f = pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_DEVICEIOCONTROL](pHdl->dwHdlData, dwIoControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned, pOverlapped);
FSDMGR_Exit(pHdl->pVol);
return f;
}
/* FSDMGR_CloseFile
*/
BOOL FSDMGR_CloseFile(PHDL pHdl)
{
BOOL f = FALSE;
PVOL pVol = pHdl->pVol;
FSDMGR_Enter(pVol);
if (pVol->pDsk->pFSD->apfnFile[FILEAPI_CLOSEFILE](pHdl->dwHdlData)) {
DeallocFSDHandle(pHdl);
f = TRUE;
}
FSDMGR_Exit(pVol);
return f;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -