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

📄 path.c

📁 从大量的wince源代码中剥离出的fat文件系统源代码.移植性非常高. 里面带有source i.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
        return INVALID_ATTR;

    if (pvol->v_flags & (VOLF_INVALID | VOLF_UNMOUNTED | VOLF_FROZEN | VOLF_WRITELOCKED)) {
        SetLastError(ERROR_ACCESS_DENIED);
        FATExit(LOGID_NONE);
        DEBUGMSGW(ZONE_APIS || ZONE_ERRORS,(DBGTEXTW("FATFS!FAT_GetFileAttributesW(%-.64s) returned 0x%x (%d)\n"), pwsFileName, INVALID_ATTR, ERROR_ACCESS_DENIED));
        return INVALID_ATTR;
    }

    // FindFirst will call SetLastError appropriately, so
    // all we have to do is bail if it doesn't return a stream.

    wcsncpy (wsFName, pwsFileName, MAX_PATH);
    wsFName[MAX_PATH] = TEXT('\0'); // Ensure null
    // Desktop will remove trailing '\' && '/'
    while (wcslen(wsFName) && ((wsFName[wcslen(wsFName)-1] == TEXT('\\')) ||
                               (wsFName[wcslen(wsFName)-1] == TEXT('/')))) {
        // Trim trailing slash
        wsFName[wcslen(wsFName)-1] = TEXT('\0');
    }

    sh.sh_flags = SHF_BYNAME;
    FindFirst(pvol, wsFName, &sh, NULL, &fd, NAME_FILE | NAME_DIR, UNKNOWN_CLUSTER);

    FATExit(LOGID_NONE);

    DEBUGMSGW(ZONE_APIS || ZONE_ERRORS && fd.dwFileAttributes == INVALID_ATTR,(DBGTEXTW("FATFS!FAT_GetFileAttributesW(%-.64s) returned 0x%x (%d)\n"), pwsFileName, fd.dwFileAttributes, fd.dwFileAttributes != INVALID_ATTR? 0 : GetLastError()));

    return fd.dwFileAttributes;
}


/*  FAT_SetFileAttributesW - Set file/subdirectory attributes
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      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 FAT_SetFileAttributesW(PVOLUME pvol, PCWSTR pwsFileName, DWORD dwAttributes)
{
    PDSTREAM pstmDir;
    SHANDLE sh;
    DIRINFO di;
    DWORD dw, dwError;
    WIN32_FIND_DATAW fd;

    DEBUGMSGW(ZONE_APIS,(DBGTEXTW("FATFS!FAT_SetFileAttributesW(0x%x,%d chars: %s)\n"), dwAttributes, wcslen(pwsFileName), pwsFileName));

    // NOTE: Even though this call modifies the volume, it never has any impact
    // on file system integrity, so we don't waste time logging it (ie, LOGID_NONE).

    if (!FATEnter(NULL, LOGID_NONE))
        return FALSE;

    if (pvol->v_flags & (VOLF_INVALID | VOLF_UNMOUNTED | VOLF_FROZEN | VOLF_LOCKED)) {
        dwError = ERROR_ACCESS_DENIED;
        goto error;
    }

    if (pvol->v_flags & VOLF_READONLY) {
        dwError = ERROR_WRITE_PROTECT;
        goto error;
    }

    // FindFirst will call SetLastError appropriately, so
    // all we have to do is bail if it doesn't return a stream.

    sh.sh_flags = SHF_BYNAME;

    pstmDir = FindFirst(pvol, pwsFileName, &sh, &di, &fd, NAME_FILE | NAME_DIR, UNKNOWN_CLUSTER);
    if (!pstmDir) {
        FATExit(LOGID_NONE);
        DEBUGMSGW(ZONE_APIS || ZONE_ERRORS,(DBGTEXTW("FATFS!FAT_SetFileAttributesW(%-.64s) returned FALSE (%d)\n"), pwsFileName, GetLastError()));
        return FALSE;
    }

    // FindFirst calls SetLastError on error, so retrieve what it set, if anything

    dwError = GetLastError();

    // If FindFirst was successful...

    if (fd.dwFileAttributes != INVALID_ATTR) {

        
        if (dwAttributes == FILE_ATTRIBUTE_NORMAL)
            dwAttributes = 0;
        else
            dwAttributes &= ~(FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_INROM);

        // NOTE: We don't actually support the TEMPORARY or COMPRESSED
        // attributes, but it doesn't hurt anything if they're passed in.

        if (dwAttributes & ~(ATTR_CHANGEABLE | FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_COMPRESSED)) {
            dwError = ERROR_ACCESS_DENIED;
        }
        else {
            // NOTE: We pass 0 for the size instead of sizeof(DIRENTRY) to disable logging
            // of this modification, since we are not logging these particular calls (by virtue
            // of LOGID_NONE above).

            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                dwAttributes |= FILE_ATTRIBUTE_DIRECTORY;
            }

            dwError = ModifyStreamBuffer(pstmDir, di.di_pde, 0);
            if (!dwError)
                di.di_pde->de_attr = (BYTE)dwAttributes;

            FILESYSTEMNOTIFICATION(pvol, DB_CEOID_CHANGED, 0, SHCNE_UPDATEITEM, &di.di_sid, &pstmDir->s_sid, NULL, NULL, NULL, DBGTEXTW("FAT_SetFileAttributesW"));
        }
    }

    dw = CloseStream(pstmDir);
    if (!dwError)
        dwError = dw;

    if (dwError) {
      error:
        SetLastError(dwError);
    }

    FATExit(LOGID_NONE);

    DEBUGMSGW(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXTW("FATFS!FAT_SetFileAttributesW(0x%x,%-.64s) returned 0x%x (%d)\n"), dwAttributes, pwsFileName, dwError == ERROR_SUCCESS, dwError));

    return dwError == ERROR_SUCCESS;
}


/*  FAT_DeleteFileW - Delete file
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      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 FAT_DeleteFileW(PVOLUME pvol, PCWSTR pwsFileName)
{
    PDSTREAM pstmDir;
    SHANDLE sh;
    DIRINFO di;
    WIN32_FIND_DATAW fd;
    DWORD dwError = ERROR_SUCCESS;
#ifdef SHELL_CALLBACK_NOTIFICATION
    CEOIDINFO oiOld;
#endif

    DEBUGMSGW(ZONE_APIS,(DBGTEXTW("FATFS!FAT_DeleteFileW(%d chars: %s)\n"), wcslen(pwsFileName), pwsFileName));

    if (!FATEnter(pvol, LOGID_DELETEFILE))
        return FALSE;

    if (pvol->v_flags & (VOLF_INVALID | VOLF_UNMOUNTED | VOLF_FROZEN | VOLF_LOCKED)) {
        dwError = ERROR_ACCESS_DENIED;
        goto error;
    }

    if (pvol->v_flags & VOLF_READONLY) {
        dwError = ERROR_WRITE_PROTECT;
        goto error;
    }

    // FindFirst will call SetLastError appropriately, so
    // all we have to do is bail if it doesn't return a stream.

    sh.sh_flags = SHF_BYNAME;
    pstmDir = FindFirst(pvol, pwsFileName, &sh, &di, &fd, NAME_FILE, UNKNOWN_CLUSTER);
    if (!pstmDir) {
        FATExit(LOGID_DELETEFILE);
        DEBUGMSGW(ZONE_APIS || ZONE_ERRORS,(DBGTEXTW("FATFS!FAT_DeleteFileW(%-.64s) returned FALSE (%d)\n"), pwsFileName, GetLastError()));
        return FALSE;
    }

    // If the source file doesn't exist, fail

    if (fd.dwFileAttributes == INVALID_ATTR) {
        CloseStream(pstmDir);
        FATExit(LOGID_DELETEFILE);
        DEBUGMSGW(ZONE_APIS || ZONE_ERRORS,(DBGTEXTW("FATFS!FAT_DeleteFileW(%-.64s) returned FALSE (%d)\n"), pwsFileName, GetLastError()));
        return FALSE;
    }

    // If the source file is R/O or a directory, fail
    //
    // NOTE: Win95 reports ERROR_FILE_NOT_FOUND if the name is an existing
    // directory, whereas NT reports ERROR_ACCESS_DENIED.  I find the latter
    // to be more sensible. -JTP

    if (fd.dwFileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY)) {
        dwError = ERROR_ACCESS_DENIED;
        goto exit;
    }

    // If the source file has any open handles, fail

    if (CheckStreamHandles(pstmDir->s_pvol, &di.di_sid)) {
        dwError = ERROR_ACCESS_DENIED;
        goto exit;
    }

    // Retrieve the fully-qualified pathname of the source, in case we need
    // it for the FILESYSTEMNOTIFICATION at the end of the function.  We have to
    // do the wacky buffer holding/unholding because pstmDir's current buffer is
    // in a known state, and we can't tolerate GetSIDInfo mucking that state up.

#ifdef SHELL_CALLBACK_NOTIFICATION
    if (pfnShell && ZONE_SHELLMSGS) {
        PBUF pbuf = pstmDir->s_pbufCur;
        HoldBuffer(pbuf);
        GetSIDInfo(pvol, &di.di_sid, &oiOld);
        ReleaseStreamBuffer(pstmDir, FALSE);
        AssignStreamBuffer(pstmDir, pbuf, FALSE);
        UnholdBuffer(pbuf);
    }
#endif

    dwError = DestroyName(pstmDir, &di);

    if (!dwError)
        FILESYSTEMNOTIFICATION(pvol, 0, DB_CEOID_FILE_DELETED, SHCNE_DELETE, NULL, NULL, &di.di_sid, &pstmDir->s_sid, &oiOld, DBGTEXTW("FAT_DeleteFileW"));

  exit:
    CloseStream(pstmDir);

    if (dwError) {
      error:
        SetLastError(dwError);
    }

    FATExit(LOGID_DELETEFILE);

    DEBUGMSGW(ZONE_APIS || ZONE_ERRORS && dwError,(DBGTEXTW("FATFS!FAT_DeleteFileW(%-.64s) returned 0x%x (%d)\n"), pwsFileName, dwError == ERROR_SUCCESS, dwError));

    return dwError == ERROR_SUCCESS;
}


/*  FAT_MoveFileW
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      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 FAT_MoveFileW(PVOLUME pvol, PCWSTR pwsOldFileName, PCWSTR pwsNewFileName)
{
    PBUF pbufSrc;
    BYTE bAttrSrc;
    WIN32_FIND_DATAW fd;
    SHANDLE shSrc, shDst;
    DIRINFO diSrc, diDst;
    PDSTREAM pstmSrc, pstmDst;
    DIRENTRY deClone, *pdeClone;
    DWORD dwError = ERROR_SUCCESS;
    DWORD clusFail = UNKNOWN_CLUSTER;
#ifdef SHELL_CALLBACK_NOTIFICATION
    CEOIDINFO oiOld;
#endif

    DEBUGONLY(pdeClone = INVALID_PTR);

    DEBUGMSGW(ZONE_APIS,(DBGTEXTW("FATFS!FAT_MoveFileW(%d->%d chars: %s->%s)\n"), wcslen(pwsOldFileName), wcslen(pwsNewFileName), pwsOldFileName, pwsNewFileName));

    if (!FATEnter(pvol, LOGID_MOVEFILE))
        return FALSE;

    if (pvol->v_flags & (VOLF_INVALID | VOLF_UNMOUNTED | VOLF_FROZEN | VOLF_LOCKED)) {
        dwError = ERROR_ACCESS_DENIED;
        goto error;
    }

    if (pvol->v_flags & VOLF_READONLY) {
        dwError = ERROR_WRITE_PROTECT;
        goto error;
    }

    // We add an explicit call to OpenRoot because this function performs
    // two path traversals starting at the root, with a lock on the source
    // directory while it traverses the destination.  So if another thread
    // tried to open a file in that source directory at the same time, it would
    // block waiting for MoveFile to finish, but MoveFile couldn't finish if
    // the other thread currently had a stream open in MoveFile's destination
    // path.  The explicit OpenRoot prevents all other path-based calls from
    // even starting down that path.

    OpenRoot(pvol);

    shSrc.sh_flags = SHF_BYNAME;
    pstmSrc = FindFirst(pvol, pwsOldFileName, &shSrc, &diSrc, &fd, NAME_FILE | NAME_DIR, UNKNOWN_CLUSTER);
    if (!pstmSrc) {
        CloseRoot(pvol);
        FATExit(LOGID_MOVEFILE);
        DEBUGMSGW(ZONE_APIS || ZONE_ERRORS,(DBGTEXTW("FATFS!FAT_MoveFileW(%s->%s) returned FALSE (%d)\n"), pwsOldFileName, pwsNewFileName, GetLastError()));
        return FALSE;
    }

    // If the source file doesn't exist, fail

    if (fd.dwFileAttributes == INVALID_ATTR) {
        CloseStream(pstmSrc);
        CloseRoot(pvol);
        FATExit(LOGID_MOVEFILE);
        DEBUGMSGW(ZONE_APIS || ZONE_ERRORS,(DBGTEXTW("FATFS!FAT_MoveFileW(%s->%s) returned FALSE (%d)\n"), pwsOldFileName, pwsNewFileName, GetLastError()));
        return FALSE;
    }

    // If the source file has any open handles, fail
#if 0
    if (CheckStreamHandles(pstmSrc->s_pvol, &diSrc.di_sid)) {
        dwError = ERROR_ACCESS_DENIED;
        goto exit3;
    }
#endif

    bAttrSrc = (BYTE)fd.dwFileAttributes;

    // Retrieve the fully-qualified pathname of the source, in case we need
    // it for the FILESYSTEMNOTIFICATION at the end of the function.  We have to
    // do the wacky buffer holding/unholding because pstmSrc's current buffer is
    // in a known state, and we can't tolerate GetSIDInfo mucking that state up.

⌨️ 快捷键说明

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