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

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專(zhuān)輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? xferpkt.c

?? This is the library for all storage drivers. It simplifies writing a storage driver by implementing
?? C
?? 第 1 頁(yè) / 共 3 頁(yè)
字號(hào):
/*++

Copyright (C) Microsoft Corporation, 1991 - 1999

Module Name:

    xferpkt.c

Abstract:

    Packet routines for CLASSPNP

Environment:

    kernel mode only

Notes:


Revision History:

--*/

#include "classp.h"
#include "debug.h"

#ifdef ALLOC_PRAGMA
    #pragma alloc_text(PAGE, InitializeTransferPackets)
    #pragma alloc_text(PAGE, DestroyAllTransferPackets)
    #pragma alloc_text(PAGE, SetupEjectionTransferPacket)
    #pragma alloc_text(PAGE, SetupModeSenseTransferPacket)
#endif


ULONG MinWorkingSetTransferPackets = MIN_WORKINGSET_TRANSFER_PACKETS_Consumer;
ULONG MaxWorkingSetTransferPackets = MAX_WORKINGSET_TRANSFER_PACKETS_Consumer;


/*
 *  InitializeTransferPackets
 *
 *      Allocate/initialize TRANSFER_PACKETs and related resources.
 */
NTSTATUS InitializeTransferPackets(PDEVICE_OBJECT Fdo)
{
    PCOMMON_DEVICE_EXTENSION commonExt = Fdo->DeviceExtension;
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    PSTORAGE_ADAPTER_DESCRIPTOR adapterDesc = commonExt->PartitionZeroExtension->AdapterDescriptor;
    ULONG hwMaxPages;
    NTSTATUS status = STATUS_SUCCESS;

    PAGED_CODE();

    /*
     *  Precompute the maximum transfer length
     */
    ASSERT(adapterDesc->MaximumTransferLength);

    hwMaxPages = adapterDesc->MaximumPhysicalPages ? adapterDesc->MaximumPhysicalPages-1 : 0;

    fdoData->HwMaxXferLen = MIN(adapterDesc->MaximumTransferLength, hwMaxPages << PAGE_SHIFT);
    fdoData->HwMaxXferLen = MAX(fdoData->HwMaxXferLen, PAGE_SIZE);

    fdoData->NumTotalTransferPackets = 0;
    fdoData->NumFreeTransferPackets = 0;
    InitializeSListHead(&fdoData->FreeTransferPacketsList);
    InitializeListHead(&fdoData->AllTransferPacketsList);
    InitializeListHead(&fdoData->DeferredClientIrpList);

    /*
     *  Set the packet threshold numbers based on the Windows SKU.
     */
    if (ExVerifySuite(Personal)){
        // this is Windows Personal
        MinWorkingSetTransferPackets = MIN_WORKINGSET_TRANSFER_PACKETS_Consumer;
        MaxWorkingSetTransferPackets = MAX_WORKINGSET_TRANSFER_PACKETS_Consumer;
    }
    else if (ExVerifySuite(Enterprise) || ExVerifySuite(DataCenter)){
        // this is Advanced Server or Datacenter
        MinWorkingSetTransferPackets = MIN_WORKINGSET_TRANSFER_PACKETS_Enterprise;
        MaxWorkingSetTransferPackets = MAX_WORKINGSET_TRANSFER_PACKETS_Enterprise;
    }
    else if (ExVerifySuite(TerminalServer)){
        // this is standard Server or Pro with terminal server
        MinWorkingSetTransferPackets = MIN_WORKINGSET_TRANSFER_PACKETS_Server;
        MaxWorkingSetTransferPackets = MAX_WORKINGSET_TRANSFER_PACKETS_Server;
    }
    else {
        // this is Professional without terminal server
        MinWorkingSetTransferPackets = MIN_WORKINGSET_TRANSFER_PACKETS_Consumer;
        MaxWorkingSetTransferPackets = MAX_WORKINGSET_TRANSFER_PACKETS_Consumer;
    }

    while (fdoData->NumFreeTransferPackets < MIN_INITIAL_TRANSFER_PACKETS){
        PTRANSFER_PACKET pkt = NewTransferPacket(Fdo);
        if (pkt){
            InterlockedIncrement(&fdoData->NumTotalTransferPackets);
            EnqueueFreeTransferPacket(Fdo, pkt);
        }
        else {
            status = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }
    }
    fdoData->DbgPeakNumTransferPackets = fdoData->NumTotalTransferPackets;

    /*
     *  Pre-initialize our SCSI_REQUEST_BLOCK template with all
     *  the constant fields.  This will save a little time for each xfer.
     *  NOTE: a CdbLength field of 10 may not always be appropriate
     */
    RtlZeroMemory(&fdoData->SrbTemplate, sizeof(SCSI_REQUEST_BLOCK));
    fdoData->SrbTemplate.Length = sizeof(SCSI_REQUEST_BLOCK);
    fdoData->SrbTemplate.Function = SRB_FUNCTION_EXECUTE_SCSI;
    fdoData->SrbTemplate.QueueAction = SRB_SIMPLE_TAG_REQUEST;
    fdoData->SrbTemplate.SenseInfoBufferLength = sizeof(SENSE_DATA);
    fdoData->SrbTemplate.CdbLength = 10;

    return status;
}


VOID DestroyAllTransferPackets(PDEVICE_OBJECT Fdo)
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    TRANSFER_PACKET *pkt;

    PAGED_CODE();

    ASSERT(IsListEmpty(&fdoData->DeferredClientIrpList));

    while (pkt = DequeueFreeTransferPacket(Fdo, FALSE)){
        DestroyTransferPacket(pkt);
        InterlockedDecrement(&fdoData->NumTotalTransferPackets);
    }

    ASSERT(fdoData->NumTotalTransferPackets == 0);
}


PTRANSFER_PACKET NewTransferPacket(PDEVICE_OBJECT Fdo)
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    PTRANSFER_PACKET newPkt;

    newPkt = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSFER_PACKET), 'pnPC');

    if (newPkt){
        RtlZeroMemory(newPkt, sizeof(TRANSFER_PACKET)); // just to be sure

        /*
         *  Allocate resources for the packet.
         */
        newPkt->Irp = IoAllocateIrp(Fdo->StackSize, FALSE);
        if (newPkt->Irp){
            KIRQL oldIrql;

            //
            // Allocate a MDL.  Add one page to the length to insure an extra page
            // entry is allocated if the buffer does not start on page boundaries.
            //
            newPkt->PartialMdl = IoAllocateMdl(NULL,
                                               fdoData->HwMaxXferLen + PAGE_SIZE,
                                               FALSE,
                                               FALSE,
                                               NULL);

            if (newPkt->PartialMdl) {

                ASSERT(newPkt->PartialMdl->Size >= (CSHORT)(sizeof(MDL) + BYTES_TO_PAGES(fdoData->HwMaxXferLen) * sizeof(PFN_NUMBER)));

                newPkt->Fdo = Fdo;

#if DBG
                newPkt->DbgPktId = InterlockedIncrement(&fdoData->DbgMaxPktId);
#endif

                /*
                 *  Enqueue the packet in our static AllTransferPacketsList
                 *  (just so we can find it during debugging if its stuck somewhere).
                 */
                KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
                InsertTailList(&fdoData->AllTransferPacketsList, &newPkt->AllPktsListEntry);
                KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);

            } else {
                IoFreeIrp(newPkt->Irp);
                ExFreePool(newPkt);
                newPkt = NULL;
            }
        }
        else {
            ExFreePool(newPkt);
            newPkt = NULL;
        }
    }

    return newPkt;
}


/*
 *  DestroyTransferPacket
 *
 */
VOID DestroyTransferPacket(PTRANSFER_PACKET Pkt)
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Pkt->Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    KIRQL oldIrql;

    ASSERT(!Pkt->SlistEntry.Next);
    ASSERT(!Pkt->OriginalIrp);

    KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);

    /*
     *  Delete the packet from our all-packets queue.
     */
    ASSERT(!IsListEmpty(&Pkt->AllPktsListEntry));
    ASSERT(!IsListEmpty(&fdoData->AllTransferPacketsList));
    RemoveEntryList(&Pkt->AllPktsListEntry);
    InitializeListHead(&Pkt->AllPktsListEntry);

    KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);

    IoFreeMdl(Pkt->PartialMdl);
    IoFreeIrp(Pkt->Irp);
    ExFreePool(Pkt);
}


VOID EnqueueFreeTransferPacket(PDEVICE_OBJECT Fdo, PTRANSFER_PACKET Pkt)
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    KIRQL oldIrql;
    ULONG newNumPkts;

    ASSERT(!Pkt->SlistEntry.Next);

    InterlockedPushEntrySList(&fdoData->FreeTransferPacketsList, &Pkt->SlistEntry);
    newNumPkts = InterlockedIncrement(&fdoData->NumFreeTransferPackets);
    ASSERT(newNumPkts <= fdoData->NumTotalTransferPackets);

    /*
     *  If the total number of packets is larger than MinWorkingSetTransferPackets,
     *  that means that we've been in stress.  If all those packets are now
     *  free, then we are now out of stress and can free the extra packets.
     *  Free down to MaxWorkingSetTransferPackets immediately, and
     *  down to MinWorkingSetTransferPackets lazily (one at a time).
     */
    if (fdoData->NumFreeTransferPackets >= fdoData->NumTotalTransferPackets){

        /*
         *  1.  Immediately snap down to our UPPER threshold.
         */
        if (fdoData->NumTotalTransferPackets > MaxWorkingSetTransferPackets){
            SINGLE_LIST_ENTRY pktList;
            PSINGLE_LIST_ENTRY slistEntry;
            PTRANSFER_PACKET pktToDelete;

            DBGTRACE(ClassDebugTrace, ("Exiting stress, block freeing (%d-%d) packets.", fdoData->NumTotalTransferPackets, MaxWorkingSetTransferPackets));

            /*
             *  Check the counter again with lock held.  This eliminates a race condition
             *  while still allowing us to not grab the spinlock in the common codepath.
             *
             *  Note that the spinlock does not synchronize with threads dequeuing free
             *  packets to send (DequeueFreeTransferPacket does that with a lightweight
             *  interlocked exchange); the spinlock prevents multiple threads in this function
             *  from deciding to free too many extra packets at once.
             */
            SimpleInitSlistHdr(&pktList);
            KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
            while ((fdoData->NumFreeTransferPackets >= fdoData->NumTotalTransferPackets) &&
                   (fdoData->NumTotalTransferPackets > MaxWorkingSetTransferPackets)){

                pktToDelete = DequeueFreeTransferPacket(Fdo, FALSE);
                if (pktToDelete){
                    SimplePushSlist(&pktList,
                                    (PSINGLE_LIST_ENTRY)&pktToDelete->SlistEntry);
                    InterlockedDecrement(&fdoData->NumTotalTransferPackets);
                }
                else {
                    DBGTRACE(ClassDebugTrace, ("Extremely unlikely condition (non-fatal): %d packets dequeued at once for Fdo %p. NumTotalTransferPackets=%d (1).", MaxWorkingSetTransferPackets, Fdo, fdoData->NumTotalTransferPackets));
                    break;
                }
            }
            KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);

            while (slistEntry = SimplePopSlist(&pktList)){
                pktToDelete = CONTAINING_RECORD(slistEntry, TRANSFER_PACKET, SlistEntry);
                DestroyTransferPacket(pktToDelete);
            }

        }

        /*
         *  2.  Lazily work down to our LOWER threshold (by only freeing one packet at a time).
         */
        if (fdoData->NumTotalTransferPackets > MinWorkingSetTransferPackets){
            /*
             *  Check the counter again with lock held.  This eliminates a race condition
             *  while still allowing us to not grab the spinlock in the common codepath.
             *
             *  Note that the spinlock does not synchronize with threads dequeuing free
             *  packets to send (DequeueFreeTransferPacket does that with a lightweight
             *  interlocked exchange); the spinlock prevents multiple threads in this function
             *  from deciding to free too many extra packets at once.
             */
            PTRANSFER_PACKET pktToDelete = NULL;

            DBGTRACE(ClassDebugTrace, ("Exiting stress, lazily freeing one of %d/%d packets.", fdoData->NumTotalTransferPackets, MinWorkingSetTransferPackets));

            KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
            if ((fdoData->NumFreeTransferPackets >= fdoData->NumTotalTransferPackets) &&
                (fdoData->NumTotalTransferPackets > MinWorkingSetTransferPackets)){

                pktToDelete = DequeueFreeTransferPacket(Fdo, FALSE);
                if (pktToDelete){
                    InterlockedDecrement(&fdoData->NumTotalTransferPackets);
                }
                else {
                    DBGTRACE(ClassDebugTrace, ("Extremely unlikely condition (non-fatal): %d packets dequeued at once for Fdo %p. NumTotalTransferPackets=%d (2).", MinWorkingSetTransferPackets, Fdo, fdoData->NumTotalTransferPackets));
                }
            }
            KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);

            if (pktToDelete){
                DestroyTransferPacket(pktToDelete);
            }
        }

    }

}


PTRANSFER_PACKET DequeueFreeTransferPacket(PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded)
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    PTRANSFER_PACKET pkt;
    PSLIST_ENTRY slistEntry;

    slistEntry = InterlockedPopEntrySList(&fdoData->FreeTransferPacketsList);
    if (slistEntry){
        slistEntry->Next = NULL;
        pkt = CONTAINING_RECORD(slistEntry, TRANSFER_PACKET, SlistEntry);
        InterlockedDecrement(&fdoData->NumFreeTransferPackets);
    }
    else {
        if (AllocIfNeeded){

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩欧美第一区| 国产一区免费电影| 欧美日韩一区二区三区四区| 国产精品白丝在线| 欧美亚洲国产一区二区三区va| 亚洲一区二区三区视频在线播放| 7777精品伊人久久久大香线蕉完整版 | 欧美片网站yy| 国产精一区二区三区| 一区二区三区在线免费观看| 欧美日韩www| 欧美二区乱c少妇| voyeur盗摄精品| 日韩中文字幕一区二区三区| 久久综合五月天婷婷伊人| av在线一区二区三区| 色综合天天视频在线观看 | 日韩激情中文字幕| 麻豆成人免费电影| 亚洲激情综合网| 欧美国产精品专区| 日韩一级片在线播放| 91最新地址在线播放| 国产精品一区二区三区乱码| 成人国产一区二区三区精品| 精品一区二区三区香蕉蜜桃 | 日韩欧美成人一区| 欧美激情艳妇裸体舞| 亚洲一区二区高清| 极品销魂美女一区二区三区| 成人免费视频播放| 国产精品18久久久久久久久久久久 | 亚洲制服丝袜av| 久久成人综合网| 日本va欧美va欧美va精品| 亚洲美女精品一区| 自拍偷拍欧美精品| 国产精品美女一区二区三区| 久久精品夜色噜噜亚洲aⅴ| 91精品国产综合久久久久久漫画| 久久综合久色欧美综合狠狠| 亚洲精品国产无套在线观| 青青草成人在线观看| 成人高清av在线| 精品欧美乱码久久久久久| 欧美一区二区女人| 日韩视频免费观看高清完整版 | 99精品黄色片免费大全| 日韩欧美一区中文| 亚洲综合色噜噜狠狠| 韩国视频一区二区| 国产精品夜夜嗨| 欧美日本乱大交xxxxx| 国产精品短视频| 国产成人啪免费观看软件| 福利一区二区在线观看| a级高清视频欧美日韩| 欧美大片在线观看一区二区| 亚洲一区二区三区小说| 成人一区在线看| 久久伊99综合婷婷久久伊| 丝袜a∨在线一区二区三区不卡 | 亚洲国产成人va在线观看天堂| 亚洲国产欧美另类丝袜| 91日韩一区二区三区| 欧美日韩免费电影| 亚洲精品视频在线观看网站| 国产激情视频一区二区在线观看 | 日韩精品乱码免费| 在线一区二区三区| 日韩欧美国产电影| 偷拍与自拍一区| 国产精品一区二区三区99| 日韩三级视频中文字幕| 免费成人结看片| 欧美一级xxx| 蜜桃视频在线观看一区| 日韩欧美的一区| 国产在线播放一区三区四| 26uuu精品一区二区三区四区在线| 日本免费新一区视频| 国产91在线|亚洲| 国产三级欧美三级| 亚洲色图丝袜美腿| 色欧美片视频在线观看| 亚洲国产精品久久艾草纯爱| 精品视频资源站| 奇米一区二区三区av| 日韩三级在线免费观看| 国产精品一区三区| 亚洲色图在线播放| 欧美高清视频不卡网| 久久精品久久久精品美女| xfplay精品久久| eeuss国产一区二区三区| 一区二区三区在线观看欧美| 欧美日韩情趣电影| 老司机免费视频一区二区三区| 久久嫩草精品久久久精品一| 五月激情六月综合| 久久只精品国产| 91麻豆视频网站| 蜜桃视频一区二区三区在线观看| 国产三级一区二区| 欧美亚洲日本一区| 美女看a上一区| 日韩毛片视频在线看| 91精品久久久久久久91蜜桃| 国产一区二区三区免费在线观看| 国产精品国产三级国产有无不卡 | 日韩欧美国产一区二区在线播放| 国产一区二区三区观看| 亚洲伦理在线精品| 欧美变态口味重另类| 91色九色蝌蚪| 国产一区在线视频| 亚洲国产精品嫩草影院| 久久午夜色播影院免费高清| 色国产综合视频| 国产最新精品免费| 午夜精品福利一区二区三区蜜桃| 国产女主播在线一区二区| 欧美日韩精品欧美日韩精品| 国产传媒日韩欧美成人| 日韩成人一区二区| 亚洲欧美视频一区| 久久久电影一区二区三区| 欧美日韩精品一区二区三区四区| 国产精品456| 久99久精品视频免费观看| 亚洲第一福利视频在线| 欧美狂野另类xxxxoooo| 99精品视频在线免费观看| 久久国产剧场电影| 日韩av中文字幕一区二区三区| 国产精品萝li| 国产日韩欧美精品在线| 欧美mv日韩mv国产网站app| 欧美中文字幕不卡| 伦理电影国产精品| 五月综合激情婷婷六月色窝| 亚洲精品国产a| ...xxx性欧美| 在线综合+亚洲+欧美中文字幕| 99精品欧美一区二区三区小说| 国产成人午夜99999| 国产精品一区二区久激情瑜伽| 蜜桃视频在线观看一区二区| 日本欧美大码aⅴ在线播放| 亚洲国产美女搞黄色| 亚洲高清久久久| 亚洲电影第三页| 视频一区欧美日韩| 午夜精品久久久久影视| 天天影视色香欲综合网老头| 午夜精品福利在线| 奇米影视一区二区三区| 久久97超碰国产精品超碰| 国产一区二区三区观看| 国产成人精品一区二区三区四区| 国产精品69久久久久水密桃| 国产成人一区二区精品非洲| 成人一区在线观看| 色综合天天综合色综合av| 久久国产精品99久久久久久老狼 | 亚洲精品少妇30p| 亚洲免费观看在线观看| 亚洲国产精品久久久久婷婷884| 五月婷婷激情综合| 美女网站视频久久| 成人在线视频首页| 在线精品观看国产| 欧美一级片在线| 精品国产91乱码一区二区三区 | 欧美猛男超大videosgay| 日韩一级片网站| 欧美国产成人在线| 亚洲综合在线五月| 日本成人中文字幕在线视频| 极品少妇一区二区| gogo大胆日本视频一区| 欧美日韩电影一区| 久久精品人人爽人人爽| 一区二区三区欧美视频| 男女性色大片免费观看一区二区| 国产激情视频一区二区在线观看 | 日韩精品一区二区三区三区免费| 久久久久久**毛片大全| 一区二区三区在线影院| 久久99在线观看| 91麻豆.com| 精品少妇一区二区三区| 怡红院av一区二区三区| 精品一区二区成人精品| 色婷婷久久一区二区三区麻豆| 欧洲av一区二区嗯嗯嗯啊| 久久久不卡影院| 亚洲一区二区美女| 不卡的av中国片| 欧美精品一区二区三区很污很色的 |