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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? buffer.c

?? 從大量的wince源代碼中剝離出的fat文件系統源代碼。移植性非常高。 微軟的代碼
?? C
?? 第 1 頁 / 共 4 頁
字號:
 *      pos - file position of data being requested
 *      lenMod - length of data to be modified (0 if not modifying)
 *      *ppvStart - address of pvStart variable to set to start of data
 *      *ppvEnd - address of pvEnd variable to set to end of buffer (optional)
 *
 *  EXIT
 *      ERROR_SUCCESS (0) if successful, non-zero if not.
 *
 *      The buffer containing the data is left held.  It can be explicitly
 *      unheld (eg, via ReleaseStreamBuffer or CommitAndReleaseStreamBuffers),
 *      or implicitly by another ReadStreamBuffer;  if a second ReadStreamBuffer
 *      returns a pointer to the same buffer, the buffer remains held, but the
 *      hold count is not advanced.  The idea is to relieve callers from having
 *      to pair all (or any of) their reads with unholds.
 *
 *  NOTES
 *      Callers promise that the requested POSITION (pos) lies within
 *      the current RUN (pstm->s_run).  The current RUN starts at some
 *      BLOCK (s_run.r_blk).  If the data is buffered, it will be in
 *      a buffer containing block ((pos - s_run.r_start)/BLOCK_SIZE + r_blk).
 */

DWORD ReadStreamBuffer(PDSTREAM pstm, DWORD pos, int lenMod, PVOID *ppvStart, PVOID *ppvEnd)
{
    PBUF pbuf;
    DWORD dwError;
    DWORD blk, blkBuf, offset;
    PBYTE pdata, pdataEnd;
    PVOLUME pvol = pstm->s_pvol;

    if (pos < pstm->s_run.r_start || pos >= pstm->s_run.r_end) {
        DEBUGMSGBREAK(ZONE_INIT || ZONE_ERRORS,
                 (DBGTEXT("FATFS!ReadStreamBuffer: bad position (%d) for stream %.11hs\n"), pos, pstm->s_achOEM));
        return ERROR_INVALID_DATA;
    }

    // Compute the stream-relative offset
    // and the corresponding volume-relative block

    offset = pos - pstm->s_run.r_start;
    blk = pstm->s_run.r_blk + (offset >> BLOCK_LOG2);

    // Compute the offset into the volume-relative block

    offset &= BLOCK_OFFSET_MASK;


    // Convert the volume-relative block # into a buffer-granular block #

    blkBuf = blk & maskBufBlock;

    // Find (or create) a buffer that starts with that buffer-granular
    // block number.  If lenMod >= cbBuf and blkBuf == blk and offset == 0,
    // then FindBuffer does not need to actuall fill the buffer with data from
    // the volume, because the entire buffer is to be modified anyway.

    DEBUGMSG(ZONE_LOGIO && (pstm->s_flags & STF_DEMANDPAGED),(DBGTEXT("FATFS!ReadStreamBuffer(DP): begin findbuffer\n")));
    dwError = FindBuffer(pvol, blkBuf, pstm,
                         (lenMod >= (int)cbBuf && blkBuf == blk && offset == 0),
                         &pbuf);
    DEBUGMSG(ZONE_LOGIO && (pstm->s_flags & STF_DEMANDPAGED),(DBGTEXT("FATFS!ReadStreamBuffer(DP): end findbuffer\n")));

    if (!dwError) {

        pdata = pbuf->b_pdata + ((blk - blkBuf) << BLOCK_LOG2) + offset;
        *ppvStart = pdata;

        // There's data all the way up to (buf_pdata + cbBuf-1), but it's
        // not necessarily VALID data.  We need to limit it to the amount of data
        // specified in the RUN.

        if (ppvEnd) {
            pdataEnd = pdata + (pstm->s_run.r_end - pos);
            if (pdataEnd > pbuf->b_pdata + cbBuf)
                pdataEnd = pbuf->b_pdata + cbBuf;
            *ppvEnd = pdataEnd;
        }
    }
    return dwError;
}


/*  ModifyStreamBuffer
 *
 *  ENTRY
 *      pstm - pointer to stream
 *      pMod - pointer to modification
 *      cbMod - length of modification (ZERO to prevent logging)
 *
 *  EXIT
 *      ERROR_SUCCESS if the stream's buffer is allowed to be modified, otherwise
 *      some error code (eg, ERROR_WRITE_PROTECT).
 */

DWORD ModifyStreamBuffer(PDSTREAM pstm, PVOID pMod, int cbMod)
{
    PBYTE pbMod = pMod;
    PBUF pbuf = pstm->s_pbufCur;
    
    // A just-dirtied buffer should also be a held buffer

    DEBUGMSG(ZONE_BUFFERS,(DBGTEXT("FATFS!ModifyStreamBuffer(block %d, stream %.11hs)\n"), pbuf->b_blk, pstm->s_achOEM));

    ASSERT(pbuf);
    ASSERT(pstm->s_flags & STF_BUFCURHELD);

    // Make sure the specified address lies within the buffer's range,
    // and then adjust the length if it extends past the end of the buffer

    ASSERT(pbMod >= pbuf->b_pdata && pbMod <= pbuf->b_pdata+cbBuf);

    if (cbMod > 0 && pbMod+cbMod > pbuf->b_pdata+cbBuf)
        cbMod = (pbuf->b_pdata+cbBuf) - pbMod;

    // If this stream contains file system data structures (FAT or directory info),
    // then pass the region being modified to ModifyBuffer so that it can do appropriate
    // buffer logging;  otherwise, pass a zero length to indicate that no logging
    // is required.

    return ModifyBuffer(pbuf, pbMod, (pstm->s_flags & STF_VOLUME)? cbMod : 0);
}




/*  CommitBufferSet
 *
 *  ENTRY
 *      pstm - pointer to stream if iCommit >= 0;
 *             pointer to volume (or NULL) if iCommit < 0
 *
 *      if iCommit >= 0 (ie, pstm points to stream):
 *          1 means release stream buffer; 0 means retain
 *
 *      if iCommit < 0 (ie, pstm points to volume, or NULL):
 *          -1 means commit everything not held;
 *          -2 means commit everything not held older than msWriteDelayMin
 *
 *  EXIT
 *      ERROR_SUCCESS (0) if successful, non-zero if not.
 *
 *  NOTES
 *      The assumption we make here is that a dirty buffer that is
 *      currently held will be explicitly committed once it is unheld,
 *      so we leave it alone.  Besides, the buffer could be in a
 *      transitional/incomplete state.
 *
 *      This doesn't mean that UnholdBuffer will do the commit for you
 *      either (because it won't).  Callers are allowed to hold/unhold
 *      dirtied buffers repeatedly without incuring the overhead of a
 *      write until they choose to do so, but they must choose to do so
 *      EVENTUALLY, in order to minimize the periods of time where the
 *      file system is in an inconsistent state.
 */

DWORD CommitBufferSet(PDSTREAM pstm, int iCommit)
{
    DWORD dw, dwError;
    PBUF pbuf, pbufEnd;

    // If the buffer pool hasn't been initialized yet, feign success

    if (cBufVolumes == 0)
        return ERROR_SUCCESS;


    dwError = ERROR_SUCCESS;
    EnterCriticalSection(&csBuffers);

    // If the caller is done with the stream's current buffer, then release
    // it first, so that the logic below (to commit only those buffers that are
    // no longer held) does the right thing.
    
    if (iCommit > 0 && pstm)
        dwError = ReleaseStreamBuffer(pstm, TRUE);

    pbuf = dlBufMRU.pbufNext;
    pbufEnd = (PBUF)&dlBufMRU;

    while (pbuf != pbufEnd) {

        // If you didn't want to release the current buffer (ie, you want to
        // commit it even though you -- or someone else -- is still holding it)
        // then we'll commit ALL the stream's buffers (held or not), on the premise
        // that what you're *really* trying to do is get the entire stream into a
        // consistent state (eg, a directory stream that was both modified and
        // grown).

        if (!pstm ||
            iCommit >= 0 && pbuf->b_pstm == pstm ||
            iCommit <  0 && pbuf->b_pvol == (PVOLUME)pstm) {

            BOOL fCommit = (iCommit == 0 || !HeldBuffer(pbuf));

            if (fCommit) {
                dw = CommitBuffer(pbuf, TRUE);
                if (!dwError)
                    dwError = dw;
            }
        }
        pbuf = pbuf->b_dlink.pbufNext;
    }

    LeaveCriticalSection(&csBuffers);

    return dwError;
}


/*  InvalidateBufferSet - Invalidate all buffers for specified volume
 *
 *  ENTRY
 *      pvol -> VOLUME structure
 *      fAll == FALSE to invalidate only clean buffers, TRUE to also invalidate dirty ones
 *
 *  EXIT
 *      None
 */

void InvalidateBufferSet(PVOLUME pvol, BOOL fAll)
{
    BOOL fDirty;
    PBUF pbuf, pbufEnd;

    EnterCriticalSection(&csBuffers);

    fDirty = FALSE;
    pbuf = dlBufMRU.pbufNext;
    pbufEnd = (PBUF)&dlBufMRU;

    while (pbuf != pbufEnd) {

        // If this buffer contains data that belonged to the specified
        // volume, and no thread is using that data, invalidate the buffer.

        if (pbuf->b_pvol == pvol) {
            
            BOOL fInvalidate = !HeldBuffer(pbuf) && (fAll || !(pbuf->b_flags & BUF_DIRTY));

            DEBUGMSG(fInvalidate && (pbuf->b_flags & BUF_DIRTY), (DBGTEXT("FATFS!InvalidateBufferSet: dirty buffer for block %d being invalidated!\n"), pbuf->b_blk));

            // The only reason we hold the buffer is so that CleanBuffer
            // won't generate a bogus assertion.  We don't care about the
            // data anymore, so it is otherwise pointless.

            if (fInvalidate) {
                HoldBuffer(pbuf);
                CleanBuffer(pbuf);
                UnholdBuffer(pbuf);
                pbuf->b_pvol = NULL;    // invalidated!
            }
            else if (pbuf->b_flags & BUF_DIRTY)
                fDirty = TRUE;
        }
        pbuf = pbuf->b_dlink.pbufNext;
    }

    // If all dirty buffers were invalidated, the volume should no longer be considered dirty.

    if (!fDirty)
        pvol->v_flags &= ~VOLF_DIRTY;

    LeaveCriticalSection(&csBuffers);
}


/*  LockBlocks - Lock a range of blocks for direct (non-buffered) I/O
 *
 *  ENTRY
 *      pstm - pointer to DSTREAM
 *      pos - file position of data being requested
 *      len - length of data being requested
 *      pblk - pointer to first unbuffered block (if successful)
 *      pcblk - pointer to count of unbuffered blocks (if successful)
 *      fWrite - FALSE if locking for read, TRUE if write
 *
 *  EXIT
 *      TRUE if successful (ie, the request starts at a buffer-granular
 *      block number and spans some multiple of blocks-per-buffer, none
 *      of which are currently buffered), FALSE if not.
 *
 *  NOTES
 *      If the call returns TRUE, then the caller can issue ReadVolume or
 *      WriteVolume directly.  The buffer critical section is left held on
 *      return for writes only -- to avoid races that might result in
 *      buffer pool inconsistency -- so it is critical that UnlockBlocks(TRUE)
 *      be called when done writing a range of blocks.
 *
 *      As with ReadStreamBuffer, callers promise that the requested POSITION
 *      (pos) lies within the current RUN (pstm->s_run).  The current RUN
 *      starts at some BLOCK (s_run.r_blk).  If the data is buffered, it will
 *      be in a buffer containing block ((pos - s_run.r_start)/BLOCK_SIZE + r_blk).
 */

BOOL LockBlocks(PDSTREAM pstm, DWORD pos, DWORD len, DWORD *pblk, DWORD *pcblk, BOOL fWrite)
{
    PBUF pbuf, pbufEnd;
    DWORD blk, blkBuf, blkBufEnd;
    DWORD offset, cblks;
    PVOLUME pvol = pstm->s_pvol;

    if (pos < pstm->s_run.r_start || pos >= pstm->s_run.r_end) {
        DEBUGMSGBREAK(ZONE_INIT || ZONE_ERRORS,
                 (DBGTEXT("FATFS!LockBlocks: bad position (%d) for stream %.11hs\n"), pos, pstm->s_achOEM));
        return FALSE;
    }

    // Compute the stream-relative offset
    // and the corresponding volume-relative block

    offset = pos - pstm->s_run.r_start;
    blk = pstm->s_run.r_blk + (offset >> BLOCK_LOG2);

    // Limit the size of the request to what exists in the current run

    if (len > pstm->s_run.r_end - pos)
        len = pstm->s_run.r_end - pos;

    // Convert the volume-relative block # into a buffer-granular block #

    blkBuf = blk & maskBufBlock;
    if (blkBuf != blk || (offset & BLOCK_OFFSET_MASK) || (cblks = len >> BLOCK_LOG2) < cblkBuf) {

        // The request does not start at the beginning of a buffer-granular
        // block, or does not start at the beginning of that block, or is
        // smaller the number of blocks in a buffer.

        
        return FALSE;
    }

    // Compute an ending buffer-granular block #, by adding cblks after
    // it has been truncated to the number of blocks in a buffer.

    blkBufEnd = blkBuf + (cblks & ~(cblkBuf-1));

    // Now we just need to find the largest cblkBuf chunk of blocks that
    // is not currently buffered.

    EnterCriticalSection(&csBuffers);

    pbuf = dlBufMRU.pbufNext;
    pbufEnd = (PBUF)&dlBufMRU;

    while (pbuf != pbufEnd) {

        if (pbuf->b_pvol && pbuf->b_pvol == pvol) {

            // If the first block is buffered, then fail the request.

            if (pbuf->b_blk == blkBuf) {
                blkBuf = blkBufEnd;
                break;
            }

            // If this buffer contains some information inside the range
            // being requested, then shrink the range down.

            if (pbuf->b_blk > blkBuf && pbuf->b_blk < blkBufEnd) {
                blkBufEnd = pbuf->b_blk;
            }
        }
        pbuf = pbuf->b_dlink.pbufNext;
    }

    if (blkBuf != blkBufEnd) {
        *pblk = blkBuf;
        *pcblk = blkBufEnd - blkBuf;
        if (!fWrite)
            LeaveCriticalSection(&csBuffers);
        return TRUE;
    }

    LeaveCriticalSection(&csBuffers);
    return FALSE;
}


void UnlockBlocks(DWORD blk, DWORD cblk, BOOL fWrite)
{
    if (fWrite)
        LeaveCriticalSection(&csBuffers);
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩欧美123| 久久久久88色偷偷免费| 国内精品视频一区二区三区八戒| 国产欧美视频一区二区| 欧美日韩亚洲另类| 成人黄色网址在线观看| 日韩精品每日更新| 亚洲蜜臀av乱码久久精品| 久久影院午夜片一区| 欧美日韩在线观看一区二区 | 亚洲成av人影院在线观看网| 久久精品一级爱片| 欧美一区二区三区在| 91小视频在线观看| 国产精品1区二区.| 日本亚洲一区二区| 亚洲一线二线三线视频| 国产欧美精品区一区二区三区 | 国产一区二区三区高清播放| 亚洲午夜免费电影| 中文字幕在线免费不卡| 久久久久高清精品| 精品国产区一区| 91精品国产综合久久精品| 欧美主播一区二区三区| 成人精品视频一区二区三区尤物| 久久99热99| 美国毛片一区二区三区| 日韩中文字幕区一区有砖一区| 亚洲欧美二区三区| 亚洲视频免费看| 国产精品高潮呻吟| 国产精品免费久久久久| 国产日韩高清在线| 久久久久久久av麻豆果冻| 精品国产a毛片| 欧美zozo另类异族| 精品国产3级a| 精品国产乱码久久久久久牛牛| 欧美一区二区在线观看| 欧美一区二区三区精品| 欧美日韩国产小视频| 欧美日韩一级片网站| 欧美性极品少妇| 欧美日韩在线观看一区二区| 欧美三级中文字| 欧美日本韩国一区二区三区视频| 欧美日韩高清一区二区不卡| 在线播放一区二区三区| 日韩一区二区在线看| 欧美一区二区福利在线| 日韩精品中文字幕在线一区| 26uuu亚洲综合色| 国产欧美精品一区二区色综合朱莉| 久久青草国产手机看片福利盒子 | 国产精品99久久不卡二区| 激情六月婷婷综合| 国产成人精品免费视频网站| 成人影视亚洲图片在线| 91丨porny丨蝌蚪视频| 欧洲精品视频在线观看| 欧美伦理影视网| 精品噜噜噜噜久久久久久久久试看| 久久综合国产精品| 国产精品久久久久婷婷二区次| 亚洲欧美激情在线| 奇米在线7777在线精品 | 国产一区二区免费在线| 国产.欧美.日韩| 色综合久久久久久久| 7777精品伊人久久久大香线蕉超级流畅 | 美女爽到高潮91| 国产麻豆精品一区二区| 91在线无精精品入口| 欧美美女直播网站| 久久综合网色—综合色88| 国产精品妹子av| 午夜电影网一区| 国产精品一二三| 91福利在线导航| 欧美变态tickle挠乳网站| 国产精品视频免费| 午夜不卡在线视频| 国产一区二区三区综合| 色综合一个色综合亚洲| 日韩亚洲电影在线| 国产精品乱码人人做人人爱 | 久久精品夜色噜噜亚洲a∨| 日韩一区中文字幕| 日本女优在线视频一区二区| 国产成人免费视频精品含羞草妖精| 色婷婷亚洲综合| 久久午夜电影网| 亚洲国产日韩在线一区模特| 国产在线看一区| 欧美色图12p| 欧美国产日本韩| 免费在线成人网| 色久优优欧美色久优优| 久久麻豆一区二区| 视频一区二区三区在线| 99视频一区二区| 精品国产乱码久久久久久老虎| 亚洲免费av高清| 丁香六月综合激情| 日韩精品中午字幕| 五月激情六月综合| 一本色道a无线码一区v| 久久精品视频一区二区三区| 三级久久三级久久| 色婷婷综合久久久中文字幕| 国产亚洲女人久久久久毛片| 日本美女一区二区| 欧美中文字幕一区二区三区亚洲| 久久久www成人免费无遮挡大片 | 另类人妖一区二区av| 91国产精品成人| 国产精品对白交换视频| 国内久久精品视频| 欧美xxxxxxxx| 美女视频黄久久| 欧美一区二区视频在线观看2020 | 久久精品国产99国产| 欧美三级日韩三级国产三级| 亚洲天堂精品在线观看| 国产成人精品影视| 国产午夜精品久久久久久免费视 | 91丨九色丨蝌蚪丨老版| 欧美国产日韩一二三区| 国产一区二区中文字幕| 精品少妇一区二区三区| 蜜臀精品一区二区三区在线观看| 欧美精品日韩精品| 午夜亚洲国产au精品一区二区| 91久久一区二区| 一片黄亚洲嫩模| 欧洲av在线精品| 午夜国产不卡在线观看视频| 欧美日韩免费高清一区色橹橹| 亚洲精品国产视频| 在线精品视频一区二区三四| 伊人性伊人情综合网| 色婷婷久久综合| 亚洲国产一区二区a毛片| 欧美性大战久久久| 婷婷开心久久网| 日韩午夜在线播放| 激情欧美一区二区三区在线观看| 久久综合久久综合亚洲| 国产不卡视频一区二区三区| 国产精品女同一区二区三区| 色悠久久久久综合欧美99| 亚洲一区二区欧美日韩 | 欧美一级片在线| 久久99精品久久久久婷婷| 久久综合久久综合亚洲| 粉嫩绯色av一区二区在线观看| 国产精品久线在线观看| 在线亚洲一区二区| 亚洲高清免费视频| 欧美tickle裸体挠脚心vk| 国产激情一区二区三区四区| 国产精品久久网站| 91久久精品一区二区三区| 日韩精品电影在线观看| www久久精品| a美女胸又www黄视频久久| 亚洲成人tv网| 久久亚洲春色中文字幕久久久| caoporen国产精品视频| 夜夜揉揉日日人人青青一国产精品| 欧美一级黄色大片| 成人永久aaa| 日韩综合在线视频| 国产三区在线成人av| 在线视频国产一区| 寂寞少妇一区二区三区| 亚洲日本护士毛茸茸| 91精品国产一区二区三区| 国产精品一二三四五| 亚洲一级不卡视频| 久久精品一区八戒影视| 欧美偷拍一区二区| 国产中文字幕一区| 亚洲国产成人高清精品| 久久欧美一区二区| 在线区一区二视频| 国产精品1024| 午夜精品福利久久久| 国产精品视频看| 日韩视频一区在线观看| 成人国产精品免费观看动漫| 日本成人在线一区| 亚洲色图在线看| 久久久国产精华| 7777精品伊人久久久大香线蕉完整版 | 91在线观看成人| 麻豆freexxxx性91精品| 亚洲精品老司机| 欧美激情中文不卡|