亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? stream.c

?? FAT文件系統(tǒng)源代碼
?? C
?? 第 1 頁 / 共 4 頁
字號(hào):
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++


Module Name:

    stream.c

Abstract:

    This file contains routines for manipulating streams.

Revision History:

--*/

#include "fatfs.h"

/*  OpenStream - Open/create stream
 *
 *  ENTRY
 *      pvol - pointer to VOLUME
 *      clusFirst - first cluster of stream (the search criteria)
 *      psid - pointer to SID, NULL if none
 *      pstmParent - pointer to parent DSTREAM (NULL if none/unknown)
 *      pdi - pointer to DIRINFO (NULL if none/unknown)
 *      dwFlags - one or more OPENSTREAM_* flags (eg, OPENSTREAM_CREATE, OPENSTREAM_REFRESH)
 *
 *  EXIT
 *      pointer to DSTREAM if successful (and critical section left held),
 *      NULL if not (ie, out of memory)
 *
 *  NOTES
 *      If clusFirst is UNKNOWN_CLUSTER, then psid becomes the search criteria.
 *
 *      Streams for data that is not cluster-mapped (eg, FAT, root directory)
 *      must be completely contiguous;  their RUN info must be set to match
 *      the size of the stream, so that ReadStream will always call directly
 *      to ReadStreamBuffer without attempting to call UnpackRun (which knows
 *      only how to deal with cluster-mapped data).
 */

PDSTREAM OpenStream(PVOLUME pvol, DWORD clusFirst, PDSID psid, PDSTREAM pstmParent, PDIRINFO pdi, DWORD dwFlags)
{
    PDSTREAM pstm;
    PFILELOCKSTATE pFileLockState;

    // Assert that at least one search criteria appears valid

    ASSERT(clusFirst != UNKNOWN_CLUSTER? TRUE : (int)psid);

    EnterCriticalSection(&pvol->v_csStms);

    // If the caller wants to create a private stream, then skip the search
    //創(chuàng)建private的stream
    if ((dwFlags & (OPENSTREAM_CREATE|OPENSTREAM_PRIVATE)) != (OPENSTREAM_CREATE|OPENSTREAM_PRIVATE)) {

        for (pstm = pvol->v_dlOpenStreams.pstmNext; pstm != (PDSTREAM)&pvol->v_dlOpenStreams; pstm = pstm->s_dlOpenStreams.pstmNext) {

            if (!(pstm->s_flags & STF_PRIVATE) != !(dwFlags & OPENSTREAM_PRIVATE))
                continue;

            if (clusFirst != UNKNOWN_CLUSTER &&
                    pstm->s_clusFirst == clusFirst ||
                clusFirst == UNKNOWN_CLUSTER &&
                    pstm->s_sid.sid_clusDir == psid->sid_clusDir && pstm->s_sid.sid_ordDir == psid->sid_ordDir) {

                ASSERT(pstm->s_refs != 0);
                goto init;
            }
        }
    }

    // The requested stream is not open.  Bail if the volume is unmounted and
    // has not yet been remounted or recycled, or if the volume is fine and we
    // simply cannot allocate memory for a new stream.

    if (!(dwFlags & OPENSTREAM_CREATE) ||
        (pvol->v_flags & (VOLF_UNMOUNTED | VOLF_REMOUNTED | VOLF_RECYCLED)) == VOLF_UNMOUNTED ||
        !(pstm = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(DSTREAM)))) {

        LeaveCriticalSection(&pvol->v_csStms);
        return NULL;
    }
    DEBUGALLOC(sizeof(DSTREAM));

    // Initialize file lock state
    pFileLockState = &pstm->s_filelockstate;
    FSDMGR_OpenFileLockState(pFileLockState);
    // 對(duì)該stream的臨界區(qū)變量進(jìn)行初始化
    InitializeCriticalSection(&pstm->s_cs);
    DEBUGALLOC(DEBUGALLOC_CS);
    // 設(shè)置該stream的其它屬性
    pstm->s_pvol = pvol;
    pstm->s_flags = STF_VOLUME;

    pstm->s_clusFirst = clusFirst;
    if (psid)
        pstm->s_sid = *psid;

    pstm->s_blkDir = INVALID_BLOCK;
    // 初始化pstm->s_runList的所有單元,并對(duì)run的第一個(gè)slot開始簇設(shè)置為clusFirst
    InitStreamRunList (&pstm->s_runList, pvol, clusFirst);

    // If the caller wanted a PRIVATE root stream, then we have to clone
    // the appropriate fields from the volume's root stream.

    if (dwFlags & OPENSTREAM_PRIVATE) {
        ASSERT(clusFirst);
        pstm->s_flags |= STF_PRIVATE;
        if (clusFirst == ROOT_PSEUDO_CLUSTER) {
            pstm->s_runList = pvol->v_pstmRoot->s_runList;
            pstm->s_size = pvol->v_pstmRoot->s_size;
        }
    }
    //使pstm->s_dlOpenHandles得前向和后向都指向其本身
    InitList((PDLINK)&pstm->s_dlOpenHandles);
	
    AddItem((PDLINK)&pvol->v_dlOpenStreams, (PDLINK)&pstm->s_dlOpenStreams);

    // Common code for both cases (old stream, new stream).  An old
    // stream might have been created with minimal information by a thread
    // for its own minimal purposes, but if another thread requests the same
    // stream and provides more detailed information, we need to record/update
    // that information, so that the stream will satisfy both threads'
    // purposes.

  init:
    pstm->s_refs++;

#ifdef TFAT
    // TFAT, add a ref to the parent stream only if it was not added before
    if(pvol->v_fTfat && pstmParent)
    {
        if(pstm->s_pstmParent){
            ASSERT(pstm->s_pstmParent == pstmParent);
        }else{
            pstm->s_pstmParent = pstmParent;
            pstmParent->s_refs++;
        }
    }
#endif

    LeaveCriticalSection(&pvol->v_csStms);
    EnterCriticalSection(&pstm->s_cs);

    if (!pstm->s_clusFirst || pstm->s_clusFirst == UNKNOWN_CLUSTER)
        pstm->s_clusFirst = clusFirst;

    if (psid) {
        if (!pstm->s_sid.sid_clusDir || pstm->s_sid.sid_clusDir == UNKNOWN_CLUSTER) {
            pstm->s_sid = *psid;
        }
    }

    if (pdi && (!(pstm->s_flags & STF_INIT) || (dwFlags & OPENSTREAM_REFRESH))) {

        // Whenever pdi is provided, pstmParent must be provided too.

        ASSERT(pstmParent);

        // We save the OEM name in the DIRENTRY for validation during handle
        // regeneration.

        memcpy(pstm->s_achOEM, pdi->di_pde->de_name, sizeof(pdi->di_pde->de_name));

        // Mask off any invalid attributes
        pstm->s_attr = pdi->di_pde->de_attr & ~ATTR_INVALID;

        pstm->s_size = (pdi->di_pde->de_attr & ATTR_DIR_MASK) == ATTR_DIRECTORY? MAX_DIRSIZE : pdi->di_pde->de_size;

        pstm->s_sidParent = pstmParent->s_sid;
        pstm->s_cwPath = pdi->di_cwName + pstmParent->s_cwPath + 1;

#ifdef TFAT
        // Compensate for the TFAT hidden directory so it doesn't count against MAX_PATH
        if (pvol->v_fTfat && !(pvol->v_flags & VOLF_32BIT_FAT) && !(pvol->v_flFATFS & FATFS_DISABLE_TFAT_REDIR) &&
            !pstm->s_sidParent.sid_ordDir && !pstm->s_sidParent.sid_clusDir)
        {
            pstm->s_cwPath = 0;
        }
#endif

        // We should never need to query or update a DIRECTORY stream's
        // DIRENTRY however (or the date/time values inside it).

        if (!(pstm->s_attr & ATTR_DIRECTORY)) {

            pstm->s_flags &= ~STF_VOLUME;

            // As an optimization, remember the physical block and offset
            // within that block of the stream's DIRENTRY.  This will save
            // us from having to perform a OpenStream/FindNext combination
            // in CommitStream whenever we need to update a stream's DIRENTRY.

            // For that information to be available and valid, however, all
            // callers must have a "lock" on the parent stream, and the stream
            // in turn must have a "current buffer".

            ASSERT(OWNCRITICALSECTION(&pstmParent->s_cs));
            ASSERT(pstmParent->s_pbufCur);

            if (pstmParent->s_pbufCur) {
                pstm->s_blkDir = pstmParent->s_pbufCur->b_blk;
                pstm->s_offDir = (PBYTE)pdi->di_pde - pstmParent->s_pbufCur->b_pdata;
            }

            // DOSTimeToFileTime can fail because it doesn't range-check any of
            // the date/time values in the directory entry;  it just pulls them apart
            // and calls SystemTimeToFileTime, which won't initialize the FILETIME
            // structure if there's an error.  Fortunately, all the FILETIMEs have been
            // zero-initialized, because that's what the Win32 API dictates when a time
            // is unknown/not supported.

            DOSTimeToFileTime(pdi->di_pde->de_createdDate,
                              pdi->di_pde->de_createdTime,
                              pdi->di_pde->de_createdTimeMsec, &pstm->s_ftCreate);

            DOSTimeToFileTime(pdi->di_pde->de_date, pdi->di_pde->de_time, 0, &pstm->s_ftWrite);

            DOSTimeToFileTime(pdi->di_pde->de_lastAccessDate, 0, 0, &pstm->s_ftAccess);
        }

        pstm->s_flags |= STF_INIT;

    }

#ifdef DEBUG
    else {
        if (clusFirst == FAT_PSEUDO_CLUSTER)
            memcpy(pstm->s_achOEM, "<FAT>", 5);
        else if (clusFirst == ROOT_PSEUDO_CLUSTER)
            memcpy(pstm->s_achOEM, "<ROOT>", 6);
    }
#endif

    if (pvol->v_flFATFS & FATFS_FORCE_WRITETHROUGH) 
        pstm->s_flags |= STF_WRITETHRU;

    if (pvol->v_flFATFS & FATFS_TRANS_DATA) 
        pstm->s_flags |= STF_TRANSDATA;

    DEBUGMSGW(ZONE_STREAMS,(DBGTEXTW("FATFS!OpenStream %s stream 0x%08x for '%.11hs' (%d)\r\n"), pstm->s_refs > 1? TEXTW("opened") : TEXTW("created"), pstm, pstm->s_achOEM, pstm->s_refs));
    return pstm;
}

DWORD CloseStream(PDSTREAM pstm)
{
    DWORD dwError = ERROR_SUCCESS;
    PFILELOCKSTATE pFileLockState;
    PEMPTYLOCKCONTAINER pfnEmptyLockContainer;

    if (pstm) {

        PVOLUME pvol = pstm->s_pvol;

        ASSERT(OWNCRITICALSECTION(&pstm->s_cs));

        // When there is no lazy-writer, CloseStream may be the last opportunity we
        // have to visit buffers for this stream, so we need to call CommitStream(TRUE),
        // lest any buffers languish dirty indefinitely -- which would in turn increase
        // the chances of the media appearing inconsistent if it was removed unexpectedly.
        // Of course, we warn the user to put the media back in when that happens, but
        // it's best to prevent such warnings in the first place.
        //
        // When there IS a lazy-writer, we can let it take care of buffers for path-based
        // and volume-based streams, and invoke CommitStream(TRUE) only for handle-based streams.
        //
        // This logic is somewhat arbitrary -- we could always call CommitStream(FALSE) -- but
        // since files are often closed as a result of some explicit user action, and since such
        // actions often precede unexpected media removal, I'm not exactly being paranoid for
        // no reason here.... -JTP

        dwError = CommitStream(pstm, TRUE);

        ASSERT(!(pstm->s_flags & STF_BUFCURHELD) && pstm->s_pbufCur == NULL);

        LeaveCriticalSection(&pstm->s_cs);
        EnterCriticalSection(&pvol->v_csStms);
        // 該stream被引用的次數(shù)為1
        if (--pstm->s_refs == 0) {

#ifdef TFAT
            // TFAT, lower the refcount on the parent stream
            if(pvol->v_fTfat && pstm->s_pstmParent)
            {
                ASSERT(pstm->s_pstmParent->s_refs);
                if(1 == pstm->s_pstmParent->s_refs){
                    EnterCriticalSection(&pstm->s_pstmParent->s_cs);
                    CloseStream(pstm->s_pstmParent);
                } else{
                    --pstm->s_pstmParent->s_refs;
                }
            }
#endif

            // Deinitialize file lock state
            pFileLockState = &pstm->s_filelockstate;
            pfnEmptyLockContainer = FSDMGR_EmptyLockContainer;
            FSDMGR_CloseFileLockState(pFileLockState, pfnEmptyLockContainer);

            DEBUGMSG(ZONE_STREAMS,(DBGTEXT("FATFS!CloseStream destroying stream 0x%08x for '%.11hs'\r\n"), pstm, pstm->s_achOEM));
            // 從鏈表	pstm->s_dlOpenStreams上刪除一個(gè)stream節(jié)點(diǎn)
            RemoveItem((PDLINK)&pstm->s_dlOpenStreams);

            PathCacheStreamInvalidate (pvol, pstm);
            InvalidateSteamBuffer (pstm);

            DEBUGFREE(DEBUGALLOC_CS);
            DeleteCriticalSection(&pstm->s_cs);
            DEBUGFREE(sizeof(DSTREAM));
            VERIFYTRUE(HeapFree(hHeap, 0, pstm));

            
        } else {
            DEBUGMSG(ZONE_STREAMS,(DBGTEXT("FATFS!CloseStream stream 0x%08x for '%.11hs' has %d refs\r\n"), pstm, pstm->s_achOEM, pstm->s_refs));
        }

        LeaveCriticalSection(&pvol->v_csStms);
    }
    return dwError;
}


/*  CommitStream - flush buffers (and DIRENTRY) associated with this stream
 *
 *  ENTRY
 *      pstm - pointer to DSTREAM
 *      fAll - TRUE to commit all stream buffers, FALSE to just update DIRENTRY
 *
 *  EXIT
 *      ERROR_SUCCESS (0) if successful, non-zero if not
 *
 *  NOTES
 *      As an optimization, OpenStream remembers the physical block and
 *      within that block of the stream's DIRENTRY.  This will save
 *      us from having to perform a OpenStream/FindNext combination
 *      in CommitStream every time we need to update a stream's DIRENTRY.
 *
 *      As an added optimization, OpenStream also records the parent's OID
 *      if a parent stream was specified when the stream was created.  Thus,
 *      CommitStream has all the information it needs to post a CEOID_CHANGED
 *      message if the stream changed, again without having to open the
 *      parent stream.
 */

DWORD CommitStream(PDSTREAM pstm, BOOL fAll)
{
    DWORD dwError = ERROR_SUCCESS;

    ASSERT(OWNCRITICALSECTION(&pstm->s_cs));

    // NOTE: CommitStream refuses to update an unmounted stream because
    // the volume the stream was associated with may have been unmounted and
    // RECYCLED, in which case this stream is dead and its directory entry
    // can never be safely updated.  The stream will eventually go away when
    // all the apps with handles to the stream close their handles.

    if (!(pstm->s_flags & STF_UNMOUNTED)) {

        // Commit all dirty buffers associated with this stream.  There
        // is no return value from this function.  Any held stream buffer will
        // be released as well.

        if (!fAll)
            dwError = ReleaseStreamBuffer(pstm, FALSE);
        else
            dwError = CommitAndReleaseStreamBuffers(pstm);

        // The rest of this is for non-FAT, non-root, non-directory
        // streams only (ie, streams with DIRENTRY's that should be updated).

        if (!(pstm->s_flags & STF_VOLUME)) {

            SYSTEMTIME stLocal;

            GetLocalTime(&stLocal);

            // A stream gets a new access time if it's a new day, unless
            // STF_ACCESS_TIME is set, in which case someone has already set a
            // specific access time.

            
            if ((pstm->s_pvol->v_flags & VOLF_UPDATE_ACCESS) && !(pstm->s_flags & STF_ACCESS_TIME)) {

                SYSTEMTIME stTmp;
                FILETIME ftTmp1, ftTmp2;

                stTmp = stLocal;
                stTmp.wDayOfWeek = stTmp.wHour = stTmp.wMinute = stTmp.wSecond = stTmp.wMilliseconds = 0;

                // Now that I've truncated the local system time to midnight,

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
色综合久久久久综合| 欧亚洲嫩模精品一区三区| 自拍偷拍国产亚洲| 日韩欧美国产成人一区二区| 97久久精品人人澡人人爽| 久久99热狠狠色一区二区| 亚洲最新在线观看| 日本一二三不卡| 精品国产99国产精品| 欧美日韩在线亚洲一区蜜芽| 99久久婷婷国产综合精品电影| 美女精品一区二区| 亚洲高清不卡在线观看| 综合久久久久久| 国产视频一区在线播放| 日韩欧美一区二区不卡| 欧美丝袜自拍制服另类| 99久久免费视频.com| 国产精品白丝av| 久久国内精品视频| 日韩黄色免费电影| 亚洲一区二区黄色| 亚洲乱码国产乱码精品精小说| 欧美极品少妇xxxxⅹ高跟鞋| 精品99一区二区三区| 欧美成人a∨高清免费观看| 欧美精品黑人性xxxx| 欧美性极品少妇| 欧洲av在线精品| 欧美性色综合网| 欧美性大战久久| 在线观看欧美日本| 91国模大尺度私拍在线视频| 99精品久久99久久久久| 99精品国产91久久久久久| 成人妖精视频yjsp地址| 粉嫩一区二区三区在线看| 国产不卡视频在线观看| 成人免费观看视频| 成人手机在线视频| 成人97人人超碰人人99| 91在线视频免费91| 91麻豆精品秘密| 欧美综合亚洲图片综合区| 欧美色网一区二区| 这里是久久伊人| 欧美成人一区二区三区片免费| 日韩精品影音先锋| 久久久另类综合| 国产日韩一级二级三级| 国产精品毛片a∨一区二区三区| 国产精品日日摸夜夜摸av| 亚洲成av人影院| 亚洲欧美日韩成人高清在线一区| 亚洲美女淫视频| 亚洲国产成人av网| 日韩av中文字幕一区二区| 麻豆成人91精品二区三区| 国产专区欧美精品| 波多野结衣中文一区| 欧美亚洲一区三区| 91精品国产综合久久蜜臀| 精品三级在线观看| 国产精品久99| 亚洲一区二区3| 免费一级片91| 成人黄色在线网站| 欧美日韩高清在线播放| 精品日韩99亚洲| 亚洲欧洲日产国产综合网| 亚洲成人免费视| 国产精品一区二区三区网站| 91精彩视频在线观看| 日韩午夜小视频| 激情六月婷婷久久| 成人a区在线观看| 欧美色老头old∨ideo| 亚洲精品一区二区精华| 亚洲伦在线观看| 久久66热re国产| 色婷婷精品久久二区二区蜜臂av| 日韩一区二区在线观看| 中文字幕欧美一区| 蜜臀av一区二区在线免费观看| 国产1区2区3区精品美女| 精品婷婷伊人一区三区三| 久久久.com| 日韩在线一区二区三区| 成人激情校园春色| 91麻豆精品国产91久久久久| 中文字幕免费一区| 免费成人在线播放| 91免费国产在线| 久久男人中文字幕资源站| 亚洲高清久久久| k8久久久一区二区三区 | av网站一区二区三区| 欧美肥胖老妇做爰| 亚洲欧美日韩国产手机在线| 国产一区在线不卡| 欧美日本在线观看| 中文字幕日韩一区| 国产精品一二三四| 欧美猛男男办公室激情| 中文字幕字幕中文在线中不卡视频| 美女视频一区二区三区| 在线日韩国产精品| 国产精品视频一二三区| 美女网站一区二区| 欧美日韩国产精品自在自线| 国产精品久久久一本精品| 久久99国产精品免费网站| 欧美三级三级三级爽爽爽| 亚洲欧洲日产国码二区| 国产成人午夜视频| 欧美www视频| 日韩电影在线观看电影| 欧美四级电影在线观看| 亚洲男同1069视频| aaa欧美日韩| 国产精品毛片高清在线完整版| 国产精品综合视频| 精品国产制服丝袜高跟| 久久激五月天综合精品| 日韩欧美一二区| 日日骚欧美日韩| 91麻豆精品国产自产在线| 午夜精品久久久久久久99樱桃| 在线观看国产日韩| 亚洲自拍偷拍网站| 欧美性感一类影片在线播放| 亚洲午夜精品网| 精品视频在线看| 亚洲国产婷婷综合在线精品| 欧美性受极品xxxx喷水| 亚洲综合在线电影| 欧美性猛交xxxx乱大交退制版| 亚洲永久精品国产| 欧美性生活一区| 石原莉奈在线亚洲二区| 7777精品久久久大香线蕉 | 精品在线亚洲视频| 精品国产乱码久久久久久蜜臀| 久久99精品久久久久| 久久综合久久综合亚洲| 国产精品一二三区| 国产精品乱码妇女bbbb| 91麻豆国产自产在线观看| 一区二区三区欧美日韩| 欧美日韩久久不卡| 蜜桃视频在线观看一区| 久久免费的精品国产v∧| 国产精品一二三区| 亚洲丝袜自拍清纯另类| 欧美亚洲国产一区二区三区| 午夜日韩在线电影| 日韩精品一区二区三区视频| 国产乱人伦偷精品视频免下载 | 色婷婷亚洲一区二区三区| 亚洲成人综合在线| 91精品免费在线观看| 韩国av一区二区三区在线观看| 中文字幕精品综合| 欧美中文字幕一二三区视频| 日本最新不卡在线| 久久久精品中文字幕麻豆发布| 国产网红主播福利一区二区| 成人精品小蝌蚪| 亚洲第一成人在线| 国产视频一区在线观看| 在线免费观看日韩欧美| 麻豆91免费看| 亚洲视频一区二区在线| 日韩一级片网址| av毛片久久久久**hd| 丝袜美腿成人在线| 欧美国产日韩在线观看| 欧美男女性生活在线直播观看| 国产精品综合在线视频| 亚洲一区二区三区四区五区中文| 日韩欧美国产高清| 色偷偷久久一区二区三区| 久久99精品国产.久久久久| 亚洲免费在线播放| 精品国产乱码久久| 欧美性色黄大片| 成人丝袜18视频在线观看| 婷婷激情综合网| 中文字幕一区不卡| 日韩精品一区二| 欧美综合视频在线观看| 国产乱理伦片在线观看夜一区| 亚洲一区免费视频| 国产精品色噜噜| 日韩欧美国产高清| 欧美日韩激情一区二区| fc2成人免费人成在线观看播放| 久久精品免费观看| 五月激情综合网| 亚洲免费在线播放|