亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
91理论电影在线观看| 99久久国产综合精品色伊| 日韩精品资源二区在线| 久久精品免费观看| 国产精品视频观看| 欧美写真视频网站| 久久国产乱子精品免费女| 视频一区二区中文字幕| 国产欧美1区2区3区| 欧美日韩国产中文| 菠萝蜜视频在线观看一区| 色av成人天堂桃色av| 亚洲国产日韩一级| 国产日韩欧美精品在线| 国产校园另类小说区| 欧美精品丝袜久久久中文字幕| 国产a久久麻豆| 美女视频黄频大全不卡视频在线播放| 综合激情网...| 欧美精品一区二区精品网| 欧美亚洲综合一区| 欧美精品乱人伦久久久久久| 欧美一卡2卡3卡4卡| 在线亚洲人成电影网站色www| 免费av网站大全久久| 亚洲高清免费观看高清完整版在线观看| 亚洲精品视频在线观看网站| 久久久电影一区二区三区| 91精品国产福利在线观看| 欧美videos中文字幕| 91精品在线免费| 欧美主播一区二区三区| 5566中文字幕一区二区电影| 欧美一区二区在线免费观看| 久久久精品欧美丰满| 亚洲欧洲日韩综合一区二区| 欧美国产激情一区二区三区蜜月| 精品少妇一区二区三区| 免费久久99精品国产| 激情综合网av| 奇米影视在线99精品| 国产经典欧美精品| 国产在线精品一区二区三区不卡| 亚洲免费在线视频一区 二区| 国产精品国产三级国产a| 国产日韩欧美麻豆| 亚洲一区二区视频在线观看| 综合分类小说区另类春色亚洲小说欧美| 亚洲综合一区二区三区| 日本欧美一区二区三区乱码| 蜜臀国产一区二区三区在线播放| 国产成人精品免费在线| 欧美在线观看一二区| 26uuu成人网一区二区三区| 精品国产91乱码一区二区三区| 国产精品久久久久久久久久免费看| 亚洲一区中文在线| 国产麻豆91精品| 欧美日韩五月天| 在线不卡免费欧美| 国产精品久久一级| 全国精品久久少妇| 成人美女视频在线观看18| 成人午夜视频在线| 正在播放亚洲一区| 亚洲少妇30p| 国内精品免费在线观看| 欧美日韩一区二区三区免费看| 久久精品人人做人人爽97| 五月婷婷综合激情| 奇米四色…亚洲| 日本高清不卡aⅴ免费网站| 久久久亚洲午夜电影| 亚洲成a人片综合在线| 免费在线观看成人| 欧美午夜一区二区三区| 国产欧美日韩麻豆91| 蜜臀av在线播放一区二区三区| 91亚洲永久精品| 国产婷婷精品av在线| 麻豆91精品视频| 欧美午夜精品一区二区蜜桃 | 欧美日韩国产高清一区| 中文在线免费一区三区高中清不卡| 奇米精品一区二区三区在线观看一 | 久久精品视频免费观看| 免费观看久久久4p| 国产精品乱人伦中文| 黄页视频在线91| 日韩午夜三级在线| 国产欧美一区二区精品性色| 免费精品视频最新在线| 欧美日本乱大交xxxxx| 亚洲视频1区2区| av在线不卡网| 在线综合+亚洲+欧美中文字幕| 亚洲欧美国产77777| 不卡区在线中文字幕| 国产欧美综合在线观看第十页| 久色婷婷小香蕉久久| 日韩视频永久免费| 日韩av一区二区三区| 欧美久久久久中文字幕| 性欧美大战久久久久久久久| 欧美三区在线视频| 亚洲午夜电影在线| 欧美调教femdomvk| 午夜精品一区二区三区三上悠亚| 色国产综合视频| 一区二区在线观看免费视频播放| 91色.com| 一区二区三区丝袜| 国产精品自产自拍| 欧美老女人在线| 午夜成人免费电影| 91精品久久久久久久99蜜桃| 午夜久久久久久久久| 欧美一区二区精品在线| 另类调教123区| 久久蜜桃一区二区| 国产精品一区专区| 欧美激情艳妇裸体舞| av一区二区三区黑人| 亚洲一区中文日韩| 3atv一区二区三区| 激情文学综合网| 国产精品久久午夜夜伦鲁鲁| 色偷偷久久人人79超碰人人澡| 久久久亚洲高清| 成人午夜短视频| 伊人性伊人情综合网| 在线电影国产精品| 国产一区二区三区在线看麻豆| 国产欧美精品一区二区色综合朱莉 | 丁香一区二区三区| 中文字幕一区二区三区乱码在线| 91国产免费看| 捆绑紧缚一区二区三区视频| 国产视频不卡一区| 欧美伊人久久久久久久久影院| 在线免费观看视频一区| 午夜精品久久久久影视| 欧美精品一区二| 9i看片成人免费高清| 亚洲成人黄色影院| 精品国产乱码久久久久久久| 波多野结衣亚洲| 婷婷六月综合网| 久久久亚洲精品一区二区三区| 97精品久久久久中文字幕| 天堂资源在线中文精品| 久久久www免费人成精品| 色婷婷综合久久久中文一区二区 | 不卡的电影网站| 亚洲成人免费在线观看| 久久久www成人免费无遮挡大片| 一本一本大道香蕉久在线精品| 蜜桃久久精品一区二区| 中文字幕一区二区三区视频| 7799精品视频| 99国产欧美久久久精品| 秋霞电影一区二区| 亚洲日本在线视频观看| 日韩精品一区二区三区在线| 91在线码无精品| 激情综合亚洲精品| 亚洲高清免费在线| 国产精品女上位| 日韩三区在线观看| 91高清在线观看| 丁香婷婷综合色啪| 美女在线视频一区| 亚洲欧美日韩电影| 亚洲精品一区二区三区在线观看| 日本精品视频一区二区| 国产成人午夜99999| 天堂成人免费av电影一区| 国产精品国产三级国产a| 精品国产1区二区| 欧美一区二区三区在线电影| 91高清在线观看| 成人黄色电影在线| 国产中文一区二区三区| 日韩国产一区二| 夜夜操天天操亚洲| 国产精品女同互慰在线看 | 亚洲1区2区3区4区| 18欧美亚洲精品| 国产欧美日韩另类一区| www国产亚洲精品久久麻豆| 欧美精品久久天天躁| 日本道免费精品一区二区三区| 成人在线视频一区| 国产精品原创巨作av| 久久97超碰国产精品超碰| 午夜精品福利久久久| 亚洲国产裸拍裸体视频在线观看乱了| 亚洲色图视频网| 中文字幕亚洲一区二区va在线| 亚洲国产精品高清|