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

📄 fsdapis.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 *
 *  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=FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try { 
            f = ((PCREATEDIRECTORYW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_CREATEDIRECTORYW])(pVol->dwVolData, pwsPathName, pSecurityAttributes);
            if (f && pVol->hNotifyHandle) {
                NotifyPathChange(pVol->hNotifyHandle, pwsPathName, TRUE, FILE_ACTION_ADDED);
            }        
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
        }
        ExitVolume(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=FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try {
            f = ((PREMOVEDIRECTORYW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_REMOVEDIRECTORYW])(pVol->dwVolData, pwsPathName);
            if (f && pVol->hNotifyHandle) {
                NotifyPathChange(pVol->hNotifyHandle, pwsPathName, TRUE, FILE_ACTION_REMOVED);
            }        
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
        }
        ExitVolume(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=0xffffffff;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try {
            if (wcscmp( pwsFileName, L"\\") == 0) {
                dw = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_TEMPORARY;
            } else {    
                dw = ((PGETFILEATTRIBUTESW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_GETFILEATTRIBUTESW])(pVol->dwVolData, pwsFileName);
            }    
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
            dw = -1;
        }
        ExitVolume(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=FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try {
            f = ((PSETFILEATTRIBUTESW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_SETFILEATTRIBUTESW])(pVol->dwVolData, pwsFileName, dwAttributes);            
            if (f && pVol->hNotifyHandle) {
                NotifyPathChange(pVol->hNotifyHandle, pwsFileName, FALSE, FILE_ACTION_MODIFIED);
            }
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
        }
        ExitVolume(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 = FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try {
            f = ((PDELETEFILEW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_DELETEFILEW])(pVol->dwVolData, pwsFileName);
            if (f && pVol->hNotifyHandle) {
                NotifyPathChange(pVol->hNotifyHandle, pwsFileName, FALSE, FILE_ACTION_REMOVED);
            }
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
        }
        ExitVolume(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 = FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try {
            f = ((PMOVEFILEW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_MOVEFILEW])(pVol->dwVolData, pwsOldFileName, pwsNewFileName);
            if (f && pVol->hNotifyHandle) {
                NotifyMoveFile(pVol->hNotifyHandle, pwsOldFileName, pwsNewFileName);
            }        
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
        }
        ExitVolume(pVol);
    }    
    return f;
}


/*  FSDMGR_DeleteAndRenameFileW
 *
 *  ENTRY
 *      pVol -> VOL structure
 *      pwsDestFileName - pointer to name of existing file
 *      pwsSourceFileName - 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 pwsDestFileName, PCWSTR pwsSourceFileName)
{
    BOOL f=FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try {
            f = ((PDELETEANDRENAMEFILEW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_PRESTOCHANGOFILENAME])(pVol->dwVolData, pwsDestFileName, pwsSourceFileName);
            if (f && pVol->hNotifyHandle) {
                NotifyPathChange( pVol->hNotifyHandle, pwsDestFileName, FALSE, FILE_ACTION_REMOVED);
                NotifyMoveFile(pVol->hNotifyHandle, pwsSourceFileName, pwsDestFileName);
            }
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
        }
        ExitVolume(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 = FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
        __try {
            f = ((PGETDISKFREESPACEW)pVol->pDsk->pFSD->apfnAFS[AFSAPI_GETDISKFREESPACE])(pVol->dwVolData, pwsPathName, pSectorsPerCluster, pBytesPerSector, pFreeClusters, pClusters);
        } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
            SetLastError(ERROR_ACCESS_DENIED);
        }
        ExitVolume(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)
{
    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;

    __try {
        pHdl = pVol->dlHdlList.pHdlNext;
        while (pHdl != (PHDL)&pVol->dlHdlList) {
            ((PFLUSHFILEBUFFERS)pHdl->pVol->pDsk->pFSD->apfnFile[FILEAPI_FLUSHFILEBUFFERS])(pHdl->dwHdlData);
            pHdl = pHdl->dlHdl.pHdlNext;
        }
    } __except(ReportFault(GetExceptionInformation(), 0), EXCEPTION_EXECUTE_HANDLER) {
        SetLastError(ERROR_ACCESS_DENIED);
    }
    return TRUE;
}


/*  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 Disk_PowerOn(HANDLE hDsk);
void Disk_PowerOff(HANDLE hDsk);


void FSDMGR_Notify(PVOL pVol, DWORD dwFlags)
{
    extern DWORD g_dwWaitIODelay;
    PREFAST_ASSERT(VALIDSIG(pVol, VOL_SIG));

    // Do not use TryEnterVolume/ExitVolume for the notify API because we don't
    // want to modify the volume reference count. Instead, just catch invalid or 
    // removed volumes using exception handling.
    
    __try {
        
        if (dwFlags & FSNOTIFY_POWER_OFF) {
            DEBUGMSG( ZONE_APIS, (L"FSDMGR_Notfiy - PowerDown on volume %08X\r\n", pVol));
            ResetEvent( g_hResumeEvent);
            FSDMGR_CommitAllFiles(pVol);        // NOTE: This must come before setting the powerdown flag !!!
            MarkVolume(pVol, VOL_POWERDOWN);
            Disk_PowerOff(pVol->pDsk->hDsk);
        } else 
        if (dwFlags & FSNOTIFY_POWER_ON) {
            DEBUGMSG( ZONE_APIS, (L"FSDMGR_Notfiy - Powerup on volume %08X\r\n", pVol));
            Disk_PowerOn(pVol->pDsk->hDsk);
            UnmarkVolume(pVol, VOL_POWERDOWN);
            SetEvent( g_hResumeEvent);
        }

        // 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.

            
        ((PNOTIFY)pVol->pDsk->pFSD->apfnAFS[AFSAPI_NOTIFY])(pVol->dwVolData, dwFlags);        

        // We don't ReportFault for this specifically since we can hit a legit exception if the device goes away        
    } __except (EXCEPTION_EXECUTE_HANDLER) {
        SetLastError(ERROR_ACCESS_DENIED);
    }
}


/*  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=FALSE;

    WaitForVolume(pVol);
    if (TryEnterVolume(pVol)) {
         __try {

⌨️ 快捷键说明

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