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

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

?? handleirp.c

?? Introduction to the Transport Device Interface-f
?? C
字號:
/**********************************************************************
 * 
 *  Toby Opferman
 *
 *  Handling IRP Library
 *
 *  This example is for educational purposes only.  I license this source
 *  out for use in learning how to write a device driver.
 *
 *  Copyright (c) 2005, All Rights Reserved  
 **********************************************************************/


#define _X86_ 

#include <wdm.h>
#include "kmem.h"
#include "handleirp.h"


typedef struct _IRPLIST *PIRPLIST;
 
typedef struct _IRPLIST
{
    PIRP pIrp;
    PFNCLEANUPIRP pfnCleanUpIrp;
    PDRIVER_CANCEL pfnCancelRoutine;
    PVOID pContext;
    PIRPLIST pNextIrp;

} IRPLIST, *PIRPLIST;

typedef struct _IRPLISTHEAD
{
    KSPIN_LOCK kspIrpListLock;
    ULONG ulPoolTag;
    PIRPLIST pListFront;
    PIRPLIST pListBack;
    
} IRPLISTHEAD, *PIRPLISTHEAD;



/* #pragma alloc_text(PAGE, HandleIrp_FreeIrpListWithCleanUp) */
/* #pragma alloc_text(PAGE, HandleIrp_AddIrp)  */
/* #pragma alloc_text(PAGE, HandleIrp_RemoveNextIrp) */
#pragma alloc_text(PAGE, HandleIrp_CreateIrpList)
#pragma alloc_text(PAGE, HandleIrp_FreeIrpList) 
/* #pragma alloc_text(PAGE, HandleIrp_PerformCancel) */



/**********************************************************************
 * 
 *  HandleIrp_CreateIrpList
 *
 *    This function creates an IRP List Head context.
 *
 **********************************************************************/
PIRPLISTHEAD HandleIrp_CreateIrpList(ULONG ulPoolTag)
{
   PIRPLISTHEAD pIrpListHead = NULL;

   pIrpListHead = (PIRPLISTHEAD)KMem_AllocateNonPagedMemory(sizeof(IRPLISTHEAD), ulPoolTag);

   if(pIrpListHead)
   {
       DbgPrint("HandleIrp_CreateIrpList Allocate = 0x%0x \r\n", pIrpListHead);

       pIrpListHead->ulPoolTag = ulPoolTag;

       KeInitializeSpinLock(&pIrpListHead->kspIrpListLock);
       pIrpListHead->pListBack = pIrpListHead->pListFront = NULL;
   }

   return pIrpListHead;
}

/**********************************************************************
 * 
 *  HandleIrp_FreeIrpList
 *
 *    This function frees an IRP List Head.
 *
 *    This function will fail if there are currently IRPs in the list.
 *
 **********************************************************************/
NTSTATUS HandleIrp_FreeIrpList(PIRPLISTHEAD pIrpListHead)
{
    NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
    
    if(pIrpListHead->pListBack == NULL && pIrpListHead->pListFront == NULL)
    {
        NtStatus = STATUS_SUCCESS;
        DbgPrint("HandleIrp_FreeIrpList Complete Free Memory = 0x%0x \r\n", pIrpListHead);

        KMem_FreeNonPagedMemory(pIrpListHead);
    }

    return NtStatus;
}

/**********************************************************************
 * 
 *  HandleIrp_FreeIrpListWithCleanUp
 *
 *    This function cancels the IRP List Head.
 *
 *    This function will fail if there are currently IRPs in the list.
 *
 **********************************************************************/
void HandleIrp_FreeIrpListWithCleanUp(PIRPLISTHEAD pIrpListHead)
{
    PIRPLIST pIrpListCurrent;
    KIRQL kOldIrql;
    PDRIVER_CANCEL pCancelRoutine;

    KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);
    
    pIrpListCurrent  = pIrpListHead->pListFront;

    while(pIrpListCurrent)
    {
        /*
         * To remove an IRP from the Queue we first want to
         * reset the cancel routine.
         */
        pCancelRoutine = IoSetCancelRoutine(pIrpListCurrent->pIrp, NULL);

        pIrpListHead->pListFront = pIrpListCurrent->pNextIrp;

        if(pIrpListHead->pListFront == NULL)
        {
            pIrpListHead->pListBack = NULL;
        }

        KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);
            
        pIrpListCurrent->pfnCleanUpIrp(pIrpListCurrent->pIrp, pIrpListCurrent->pContext);   

        DbgPrint("HandleIrp_FreeIrpListWithCleanUp Complete Free Memory = 0x%0x \r\n", pIrpListCurrent);

        KMem_FreeNonPagedMemory(pIrpListCurrent);
        pIrpListCurrent = NULL;

        KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);
        
        pIrpListCurrent  = pIrpListHead->pListFront;
    }


    KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);

    HandleIrp_FreeIrpList(pIrpListHead);
}

/**********************************************************************
 * 
 *  HandleIrp_AddIrp
 *
 *    This function adds an IRP to the IRP List.
 *
 **********************************************************************/
NTSTATUS HandleIrp_AddIrp(PIRPLISTHEAD pIrpListHead, PIRP pIrp, PDRIVER_CANCEL pDriverCancelRoutine, PFNCLEANUPIRP pfnCleanUpIrp, PVOID pContext)
{
    NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
    KIRQL kOldIrql;
    PDRIVER_CANCEL pCancelRoutine;
    PIRPLIST pIrpList;

    pIrpList = (PIRPLIST)KMem_AllocateNonPagedMemory(sizeof(IRPLIST), pIrpListHead->ulPoolTag);

    if(pIrpList)
    {
        DbgPrint("HandleIrp_AddIrp Allocate Memory = 0x%0x \r\n", pIrpList);

        pIrpList->pContext      = pContext;
        pIrpList->pfnCleanUpIrp = pfnCleanUpIrp;
        pIrpList->pIrp          = pIrp;
        pIrpList->pfnCancelRoutine = pDriverCancelRoutine;

        /*
         *  The first thing we need to to is acquire our spin lock.
         *
         *  The reason for this is a few things.
         *
         *     1. All access to this list is synchronized, the obvious reason
         *     2. This will synchronize adding this IRP to the list with the cancel routine.
         *
         */
    
        KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);
    
        /*
         * We will now attempt to set the cancel routine which will be called
         * when (if) the IRP is ever canceled.  This allows us to remove an IRP
         * from the queue that is no longer valid.
         *
         * A potential misconception is that if the IRP is canceled it is no longer
         * valid.  This is not true the IRP does not self-destruct.  The IRP is valid
         * as long as it has not been completed.  Once it has been completed this is
         * when it is no longer valid (while we own it).  So, while we own the IRP we need
         * to complete it at some point.  The reason for setting a cancel routine is to realize
         * that the IRP has been canceled and complete it immediately and get rid of it.  
         * We don't want to do processing for an IRP that has been canceled as the result
         * will just be thrown away.
         *
         * So, if we remove an IRP from this list for processing and it's canceled the only
         * problem is that we did processing on it.  We complete it at the end and there's no problem.
         *
         * There is a problem however if your code is written in a way that allows your cancel routine
         * to complete the IRP unconditionally.  This is fine as long as you have some type of synchronization
         * since you DO NOT WANT TO COMPLETE AN IRP TWICE!!!!!!
         */
    
        IoSetCancelRoutine(pIrp, pIrpList->pfnCancelRoutine);
    
        /*
         * We have set our cancel routine.  Now, check if the IRP has already been canceled.
         *
         * We must set the cancel routine before checking this to ensure that once we queue
         * the IRP it will definately be called if the IRP is ever canceled.
         */
    
        if(pIrp->Cancel)
        {
            /*
             * If the IRP has been canceled we can then check if our cancel routine has been
             * called.
             */
            pCancelRoutine = IoSetCancelRoutine(pIrp, NULL);
    
            /*
             * if pCancelRoutine == NULL then our cancel routine has been called.
             * if pCancelRoutine != NULL then our cancel routine has not been called.
             *
             * The I/O Manager will set the cancel routine to NULL before calling the cancel routine.
             *
             * We have a decision to make here, we need to write the code in a way that we only
             * complete and clean up the IRP once.  We either allow the cancel routine to do it
             * or we do it here.  Now, we will already have to clean up the IRP here if the
             * pCancelRoutine != NULL.
             *
             * The solution we are going with here is that we will only clean up IRP's in the cancel
             * routine if the are in the list.  So, we will not add any IRP to the list if it has
             * already been canceled once we get to this location.
             *
             */
            KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);
    
            /*
             * We are going to allow the clean up function to complete the IRP.
             */
            pfnCleanUpIrp(pIrp, pContext);
            DbgPrint("HandleIrp_AddIrp Complete Free Memory = 0x%0x \r\n", pIrpList);
            KMem_FreeNonPagedMemory(pIrpList);
        }
        else
        {
            /*
             * The IRP has not been canceled, so we can simply queue it!
             */


            pIrpList->pNextIrp      = NULL;
            
            IoMarkIrpPending(pIrp);

            if(pIrpListHead->pListBack)
            {
               pIrpListHead->pListBack->pNextIrp = pIrpList;
               pIrpListHead->pListBack           = pIrpList;
            }
            else
            {
               pIrpListHead->pListFront = pIrpListHead->pListBack = pIrpList;
            }

            KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);

            NtStatus = STATUS_SUCCESS;
        }
    }
    else
    {
        /*
         * We are going to allow the clean up function to complete the IRP.
         */
        pfnCleanUpIrp(pIrp, pContext);
    }
    

    return NtStatus;      
}

/**********************************************************************
 * 
 *  HandleIrp_RemoveNextIrp
 *
 *    This function removes the next valid IRP.
 *
 **********************************************************************/
PIRP HandleIrp_RemoveNextIrp(PIRPLISTHEAD pIrpListHead)
{
    PIRP pIrp = NULL;
    KIRQL kOldIrql;
    PDRIVER_CANCEL pCancelRoutine;
    PIRPLIST pIrpListCurrent;

    KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);
    
    pIrpListCurrent  = pIrpListHead->pListFront;

    while(pIrpListCurrent && pIrp == NULL)
    {
        /*
         * To remove an IRP from the Queue we first want to
         * reset the cancel routine.
         */
        pCancelRoutine = IoSetCancelRoutine(pIrpListCurrent->pIrp, NULL);

        /*
         * The next phase is to determine if this IRP has been canceled
         */

        if(pIrpListCurrent->pIrp->Cancel)
        {
            /*
             * We have been canceled so we need to determine if our cancel routine
             * has already been called.  pCancelRoutine will be NULL if our cancel
             * routine has been called.  If will not be NULL if our cancel routine
             * has not been called.  However, we don't care in either case and we
             * will simply complete the IRP here since we have to implement at
             * least that case anyway.
             *
             * Remove the IRP from the list.
             */

            pIrpListHead->pListFront = pIrpListCurrent->pNextIrp;

            if(pIrpListHead->pListFront == NULL)
            {
                pIrpListHead->pListBack = NULL;
            }

            KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);
            
            pIrpListCurrent->pfnCleanUpIrp(pIrpListCurrent->pIrp, pIrpListCurrent->pContext);

            DbgPrint("HandleIrp_RemoveNextIrp Complete Free Memory = 0x%0x \r\n", pIrpListCurrent);
            KMem_FreeNonPagedMemory(pIrpListCurrent);
            pIrpListCurrent = NULL;

            KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);
            
            pIrpListCurrent  = pIrpListHead->pListFront;

        }
        else
        {
            pIrpListHead->pListFront = pIrpListCurrent->pNextIrp;

            if(pIrpListHead->pListFront == NULL)
            {
                pIrpListHead->pListBack = NULL;
            }

            pIrp = pIrpListCurrent->pIrp;

            KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);

            DbgPrint("HandleIrp_RemoveNextIrp Complete Free Memory = 0x%0x \r\n", pIrpListCurrent);
            KMem_FreeNonPagedMemory(pIrpListCurrent);
            pIrpListCurrent = NULL;

            KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);
            
        }
    }


    KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);

    return pIrp;
}

/**********************************************************************
 * 
 *  HandleIrp_PerformCancel
 *
 *    This function removes the specified IRP from the list.
 *
 **********************************************************************/
NTSTATUS HandleIrp_PerformCancel(PIRPLISTHEAD pIrpListHead, PIRP pIrp)
{
    NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
    KIRQL kOldIrql;
    PIRPLIST pIrpListCurrent, pIrpListPrevious;

    KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);
    
    pIrpListPrevious = NULL;
    pIrpListCurrent  = pIrpListHead->pListFront;

    while(pIrpListCurrent && NtStatus == STATUS_UNSUCCESSFUL)
    {
        if(pIrpListCurrent->pIrp == pIrp)
        {
            if(pIrpListPrevious)
            {
               pIrpListPrevious->pNextIrp = pIrpListCurrent->pNextIrp;
            }

            if(pIrpListHead->pListFront == pIrpListCurrent)
            {
               pIrpListHead->pListFront = pIrpListCurrent->pNextIrp;
            }

            if(pIrpListHead->pListBack == pIrpListCurrent)
            {
                pIrpListHead->pListBack = pIrpListPrevious;
            }

            KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);
            
            NtStatus = STATUS_SUCCESS;

            /*
             * We are going to allow the clean up function to complete the IRP.
             */
            pIrpListCurrent->pfnCleanUpIrp(pIrpListCurrent->pIrp, pIrpListCurrent->pContext);

            DbgPrint("HandleIrp_PerformCancel Complete Free Memory = 0x%0x \r\n", pIrpListCurrent);

            KMem_FreeNonPagedMemory(pIrpListCurrent);

            pIrpListCurrent = NULL;

            KeAcquireSpinLock(&pIrpListHead->kspIrpListLock, &kOldIrql);

        }
        else
        {
            pIrpListPrevious = pIrpListCurrent;
            pIrpListCurrent = pIrpListCurrent->pNextIrp;
        }
    }


    KeReleaseSpinLock(&pIrpListHead->kspIrpListLock, kOldIrql);

    return NtStatus;
}




?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人av资源站| 亚洲天堂av一区| 国产精品系列在线播放| 国产日韩欧美a| 色噜噜狠狠成人中文综合| 免费欧美日韩国产三级电影| 欧美综合天天夜夜久久| 久久电影网站中文字幕| 国产精品大尺度| 精品裸体舞一区二区三区| 91在线免费看| 激情综合色综合久久综合| 一区二区三区不卡在线观看| www精品美女久久久tv| 欧美日韩精品系列| 不卡在线观看av| 国产成人亚洲综合色影视| 日韩黄色片在线观看| 亚洲伦理在线免费看| 久久综合国产精品| 精品国产一区二区精华| 欧美日韩欧美一区二区| 全国精品久久少妇| 亚洲美女在线国产| 国产精品二区一区二区aⅴ污介绍| 精品国产第一区二区三区观看体验 | 亚洲激情校园春色| 亚洲欧洲在线观看av| 国产精品福利在线播放| 久久久国产精华| 国产人久久人人人人爽| 中文字幕第一区二区| 中日韩免费视频中文字幕| 精品国产区一区| 国产精品久久影院| 亚洲日本韩国一区| 午夜在线电影亚洲一区| 日韩精品91亚洲二区在线观看| 美女网站色91| 成人精品视频一区二区三区| 色素色在线综合| 日韩欧美国产综合一区| 国产日韩欧美综合一区| 亚洲激情男女视频| 精品亚洲国产成人av制服丝袜| 国产91综合一区在线观看| 色综合色综合色综合色综合色综合 | 久久人人97超碰com| 亚洲欧美日韩一区| 国产真实精品久久二三区| 91视频免费观看| 精品国产电影一区二区| 亚洲综合一区二区三区| 国产成人午夜片在线观看高清观看| 91在线国内视频| 精品国产乱子伦一区| 三级精品在线观看| 91性感美女视频| 欧美国产精品中文字幕| 一区二区在线观看视频在线观看| 国产在线不卡视频| 日韩一级片网站| 日本免费新一区视频| 欧美色倩网站大全免费| 一区二区三区在线看| 成人av片在线观看| 国产精品久久久久久久裸模| 国产美女视频91| 久久精品一区二区| 国产精品亚洲а∨天堂免在线| 日韩欧美一级精品久久| 亚洲国产美国国产综合一区二区| 成人午夜电影小说| 国产清纯白嫩初高生在线观看91| 国产米奇在线777精品观看| 久久久久久综合| proumb性欧美在线观看| 亚洲少妇最新在线视频| 在线精品国精品国产尤物884a| 一区二区三区 在线观看视频| 精品婷婷伊人一区三区三| 婷婷一区二区三区| 久久综合五月天婷婷伊人| 国产成a人亚洲| 亚洲二区视频在线| 26uuu亚洲| 欧洲国产伦久久久久久久| 久久99久久久久| 亚洲欧美另类综合偷拍| 精品久久人人做人人爱| 91在线国产福利| 国产精品伊人色| 一区二区三区四区不卡在线| 久久久久久久网| 亚洲三级在线免费| 裸体歌舞表演一区二区| 国产精品国产自产拍高清av | 国产精品久久久久婷婷| 欧美视频中文字幕| eeuss鲁一区二区三区| 一级精品视频在线观看宜春院 | 亚洲福利视频一区二区| 国产精品―色哟哟| 久久色.com| 欧美成人女星排名| 日韩一区二区三区电影| 欧美性做爰猛烈叫床潮| 在线亚洲人成电影网站色www| 国内欧美视频一区二区| 久久成人精品无人区| 青青草91视频| 精品在线你懂的| 国产在线播放一区| 国产一区二区视频在线播放| 精品一区二区三区av| 黄页网站大全一区二区| 国产一本一道久久香蕉| 福利一区二区在线| 91在线视频播放| 欧美精品三级在线观看| 日韩欧美黄色影院| 国产精品无码永久免费888| 国产精品进线69影院| 亚洲一区二区三区小说| 偷拍亚洲欧洲综合| 成人性生交大片免费看在线播放 | 欧美tickling挠脚心丨vk| 精品国产123| 亚洲国产精品久久久久婷婷884 | 激情综合网激情| www.日韩精品| 日韩一区二区电影在线| 欧美国产精品中文字幕| 日韩电影免费在线看| 国产suv精品一区二区6| 欧美群妇大交群中文字幕| 久久综合九色综合97婷婷女人| 一区二区三区四区在线| 国产成人自拍高清视频在线免费播放| 色综合亚洲欧洲| 2023国产精品自拍| 日韩av中文字幕一区二区| 色综合久久久网| 国产精品伦理一区二区| 蜜臀91精品一区二区三区| 在线观看日韩高清av| 中文字幕一区二区三区精华液| 久久成人精品无人区| 欧美一区日本一区韩国一区| 亚洲精品videosex极品| 99精品欧美一区| 综合电影一区二区三区 | 国产精品久久777777| 国产高清精品在线| 国产亚洲一区二区三区| 国产剧情一区二区三区| 中文一区二区在线观看| 从欧美一区二区三区| 国产精品电影院| 色综合一区二区三区| 亚洲一区国产视频| 91精选在线观看| 国产综合久久久久久久久久久久| 精品欧美一区二区久久| 国产成人高清视频| 国产精品久99| 欧美裸体bbwbbwbbw| 国产精品综合一区二区| 1024国产精品| 日韩视频免费观看高清完整版 | 日韩电影一区二区三区四区| 精品少妇一区二区三区日产乱码 | 欧美日韩高清影院| 午夜精品久久久久久久99水蜜桃| 91精品国产欧美一区二区18| 国产精品一区二区在线观看不卡| 亚洲精品视频在线看| 日韩女优视频免费观看| 在线观看日韩高清av| 成人美女在线视频| 蜜臀精品久久久久久蜜臀| 亚洲猫色日本管| 中文字幕巨乱亚洲| 26uuu国产在线精品一区二区| 91福利区一区二区三区| 成人精品视频一区| 国内成人精品2018免费看| 污片在线观看一区二区| 亚洲狠狠丁香婷婷综合久久久| 国产女同互慰高潮91漫画| 精品国产乱码久久久久久免费| 欧美午夜免费电影| 色婷婷综合五月| 91麻豆国产福利精品| 99re这里只有精品首页| 成人激情黄色小说| 成人动漫一区二区三区| 成人aaaa免费全部观看| 成人污污视频在线观看| 久久精品噜噜噜成人88aⅴ|