tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
20楼#
发布于:2005-07-26 16:54
IoCancelIrp
//
// An IRPLOCK allows for safe cancellation. The idea is to protect the IRP
// while the canceller is calling IoCancelIrp. This is done by wrapping the
// call in InterlockedExchange(s). The roles are as follows:
//
// Initiator/completion: Cancelable --> IoCallDriver() --> Completed
// Canceller: CancelStarted --> IoCancelIrp() --> CancelCompleted
//
// No cancellation:
//   Cancelable-->Completed
//
// Cancellation, IoCancelIrp returns before completion:
//   Cancelable --> CancelStarted --> CancelCompleted --> Completed
//
// Canceled after completion:
//   Cancelable --> Completed -> CancelStarted
//
// Cancellation, IRP completed during call to IoCancelIrp():
//   Cancelable --> CancelStarted -> Completed --> CancelCompleted
//
//  The transition from CancelStarted to Completed tells the completer to block
//  postprocessing (IRP ownership is transferred to the canceller). Similarly,
//  the canceller learns it owns IRP postprocessing (free, completion, etc)
//  during a Completed->CancelCompleted transition.
//




status = IoCallDriver(TopOfDeviceStack, irp);

    if (status == STATUS_PENDING) {

        dueTime.QuadPart = -10000 * Milliseconds;

        status = KeWaitForSingleObject(
                            &event,
                            Executive,
                            KernelMode,
                            FALSE,
                            &dueTime
                            );

        if (status == STATUS_TIMEOUT) {

            if (InterlockedExchange((PVOID)&lock, IRPLOCK_CANCEL_STARTED) == IRPLOCK_CANCELABLE) {

                //
                // You got it to the IRP before it was completed. You can cancel
                // the IRP without fear of losing it, because the completion routine
                // does not let go of the IRP until you allow it.
                //
                IoCancelIrp(irp);

                //
                // Release the completion routine. If it already got there,
                // then you need to complete it yourself. Otherwise, you got
                // through IoCancelIrp before the IRP completed entirely.
                //
                if (InterlockedExchange(&lock, IRPLOCK_CANCEL_COMPLETE) == IRPLOCK_COMPLETED) {
                    IoCompleteRequest(irp, IO_NO_INCREMENT);
                }
            }

            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

            ioStatus.Status = status; // Return STATUS_TIMEOUT

        } else {

            status = ioStatus.Status;
        }
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
21楼#
发布于:2005-07-26 17:02
IoCancelIrp
VOID
CancelPendingIrp(
    PDEVICE_EXTENSION DeviceExtension
    )
/*++
    This function tries to cancel the PendingIrp if it is not already completed.
    Note that the IRP may not be completed and freed when the
    function returns. Therefore, if you are calling this from your PNP Remove device handle,
    you must wait on the IrpEvent to make sure the IRP is indeed completed
    before successfully completing the remove request and allowing the driver to unload.
--*/
{
     if (InterlockedExchange((PVOID)&DeviceExtension->IrpLock, IRPLOCK_CANCEL_STARTED) == IRPLOCK_CANCELABLE) {

        //
        // You got it to the IRP before it was completed. You can cancel
        // the IRP without fear of losing it, as the completion routine
        // will not let go of the IRP until you say so.
        //
        IoCancelIrp(DeviceExtension->PendingIrp);
        //
        // Release the completion routine. If it already got there,
        // then you need to free it yourself. Otherwise, you got
        // through IoCancelIrp before the IRP completed entirely.
        //
        if (InterlockedExchange((PVOID)&DeviceExtension->IrpLock, IRPLOCK_CANCEL_COMPLETE) == IRPLOCK_COMPLETED) {
            IoFreeIrp(DeviceExtension->PendingIrp);
            DeviceExtension->PendingIrp = NULL;
            KeSetEvent(&DeviceExtension->IrpEvent, IO_NO_INCREMENT, FALSE);
        }

     }

    return ;
}
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
22楼#
发布于:2005-07-26 17:12
/**********************************************************************
 *
 *  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;
}

/**********************************************************************
 *
 *  TdiExample_CancelRoutine
 *
 *    This function is called if the IRP is ever canceled
 *
 *    CancelIo() from user mode, IoCancelIrp() from the Kernel
 *
 **********************************************************************/
VOID TdiExample_CancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
    PIRPLISTHEAD pIrpListHead = NULL;

    /*
     * We must release the cancel spin lock
     */

    IoReleaseCancelSpinLock(pIrp->CancelIrql);
    
    DbgPrint("TdiExample_CancelRoutine Called IRP = 0x%0x \r\n", pIrp);

    /*
     * We stored the IRPLISTHEAD context in our DriverContext on the IRP
     * before adding it to the queue so it should not be NULL here.
     */

    pIrpListHead = (PIRPLISTHEAD)pIrp->Tail.Overlay.DriverContext[0];
    pIrp->Tail.Overlay.DriverContext[0] = NULL;
    
    /*
     * We can then just throw the IRP to the PerformCancel
     * routine since it will find it in the queue, remove it and
     * then call our clean up routine.  Our clean up routine
     * will then complete the IRP.  If this does not occur then
     * our completion of the IRP will occur in another context
     * since it is not in the list.
     */
    HandleIrp_PerformCancel(pIrpListHead, pIrp);

}
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
23楼#
发布于:2005-08-03 16:46
什么都不东,还居然完成PDIUSBD12的驱动,应用及嵌入式3个程序
1. 驱动程序由XP DDK的样板程序修改而成(E:\WINDDK\2600.1106\src\wdm\usb\bulkusb).
     1] 更改GUID为如下:
      #ifndef _BULKUSB_USER_H
      #define _BULKUSB_USER_H

       #include <initguid.h>

     // {00873FDF-61A8-11d1-AA5E-00C04FB1728B}  for BULKUSB.SYS
     DEFINE_GUID(GUID_CLASS_I82930_BULK,
     0x77f49320, 0x16ef, 0x11d2, 0xad, 0x51, 0x0, 0x60, 0x97, 0xb5, 0x14, 0xdd);
     2] INF文件为

[Version]
Signature="$CHICAGO$"
Class=USB
;// USB class intsall GUID
;ClassGUID={36FC9E60-C465-11CF-8056-444553540000}
provider=%PHILIPS%
;DriverVer=15/07/2005
LayoutFile=layout.inf

;[SourceDisksNames]
;1="BulkUsb Installation Disk",,,

;[SourceDisksFiles]
;BULKUSB.sys = 1
;BULKUSB.inf = 1

[Manufacturer]
%MfgName%=Philips

[Philips]
%USB\VID_0471&PID_0222.DeviceDesc%=D12TEST.Dev, USB\VID_0471&PID_0222
%USB\VID_0471&PID_0666.DeviceDesc%=D12TEST.Dev, USB\VID_0471&PID_0666
%USB\VID_0471&PID_0888.DeviceDesc%=D12TEST.Dev, USB\VID_0471&PID_0888

[PreCopySection]
HKR,,NoSetupUI,,1

[DestinationDirs]
D12TEST.Files.Ext = 10,System32\Drivers
D12TEST.Files.Inf = 10,INF

[D12TEST.Dev]
CopyFiles=D12TEST.Files.Ext
AddReg=D12TEST.AddReg

[D12TEST.Dev.NT]
CopyFiles=D12TEST.Files.Ext
AddReg=D12TEST.AddReg

[D12TEST.Dev.NT.Services]
Addservice = D12TEST, 0x00000002, D12TEST.AddService

[D12TEST.AddService]
DisplayName    = %D12TEST.SvcDesc%
ServiceType    = 1                  ; SERVICE_KERNEL_DRIVER
StartType      = 2                  ; SERVICE_AUTO_START
ErrorControl   = 1                  ; SERVICE_ERROR_NORMAL
ServiceBinary  = %10%\System32\Drivers\D12TEST.sys
LoadOrderGroup = Base

[D12TEST.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,D12TEST.sys
HKLM,"System\Currentcontrolset\Services\D12TEST\Parameters","MaximumTransferSize",0x10001,65536
HKLM,"System\Currentcontrolset\Services\D12TEST\Parameters","DebugLevel",0x10001,2


[D12TEST.Files.Ext]
D12TEST.sys


;---------------------------------------------------------------;

[Strings]
PHILIPS="Philips Semiconductors"
MfgName="Philips"
USB\VID_0471&PID_0222.DeviceDesc="Philips PDIUSBD12 Evaluation Board"
USB\VID_0471&PID_0666.DeviceDesc="Philips PDIUSBD12 SMART Evaluation Board"
USB\VID_0471&PID_0888.DeviceDesc="Philips PDIUSBD12 USB-EPP Evaluation Board"
D12TEST.SvcDesc="D12TEST.Sys PDIUSBD12 Bulk IO test driver"

2.  应用程序解决ReadFile()阻塞方法如下:

                DWORD mByte = *len;
       DWORD lent;
       if(m_hEP2Read != INVALID_HANDLE_VALUE)
       {
              ReadFile(m_hEP2Read,buf,mByte,&mByte,&m_OvRead /*NULL*/);
              return *len = mByte;
       }
      
       if(GetLastError()==ERROR_IO_PENDING)
       {
              if(WaitForSingleObject(m_OvRead.hEvent, 100)==WAIT_TIMEOUT)
              {
                     CancelIo(m_hEP2Read);
              }
              GetOverlappedResult(m_hEP2Read, &m_OvRead, &lent, FALSE);
       }
       return 0;
3. 嵌入式按照以上个帖即可实现连接USB,安装USB驱动程序.
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
24楼#
发布于:2007-01-04 16:10
免驱动的D12 HID协议联机通信
D12SuspendProc() 80

D12BusRstProc() 40

D12SuspendProc() 80

D12SuspendProc() 80

D12BusRstProc() 40
0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 18
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10 0x51 0xC2 0x01 0x13 0x00 0x01 0x01 0x04
 USB_DataInStage() cnt = 2 EP0Data.Count = 2
0x00 0x01

D12BusRstProc() 40
0x00 0x05 0x01 0x00 0x00 0x00 0x00 0x00
USB_REQUEST_SET_ADDRESS = 5
D12_SetAddressEnable() REQUEST_TO_DEVICE = 0
0x80 0x06 0x00 0x01 0x00 0x00 0x12 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 18
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10 0x51 0xC2 0x01 0x13 0x00 0x01 0x01 0x04
 USB_DataInStage() cnt = 2 EP0Data.Count = 2
0x00 0x01
0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00
 USB_DataInStage() cnt = 9 EP0Data.Count = 9
0x09 0x02 0x22 0x00 0x01 0x01 0x00 0x80 0x32
0x80 0x06 0x00 0x02 0x00 0x00 0xFF 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 34
0x09 0x02 0x22 0x00 0x01 0x01 0x00 0x80 0x32 0x09 0x04 0x00 0x00 0x01 0x03 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 18
0x00 0x5C 0x09 0x21 0x00 0x01 0x00 0x01 0x22 0x1D 0x00 0x07 0x05 0x81 0x03 0x10
 USB_DataInStage() cnt = 2 EP0Data.Count = 2
0x00 0x10
0x80 0x06 0x00 0x03 0x00 0x00 0xFF 0x00
 USB_DataInStage() cnt = 4 EP0Data.Count = 4
0x04 0x03 0x09 0x04
0x80 0x06 0x04 0x03 0x09 0x04 0xFF 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 45
0x2D 0x03 0x4E 0x00 0x45 0x00 0x57 0x00 0x41 0x00 0x52 0x00 0x45 0x00 0x20 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 29
0x50 0x00 0x54 0x00 0x53 0x00 0x31 0x00 0x2E 0x00 0x30 0x00 0x31 0x00 0x54 0x00
 USB_DataInStage() cnt = 13 EP0Data.Count = 13
0x52 0x00 0x43 0x00 0xEF 0xCC 0x00 0xD9 0xC8 0x00 0xC5 0xB2 0x00
0x80 0x06 0x00 0x03 0x00 0x00 0xFF 0x00
 USB_DataInStage() cnt = 4 EP0Data.Count = 4
0x04 0x03 0x09 0x04
0x80 0x06 0x04 0x03 0x09 0x04 0xFF 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 45
0x2D 0x03 0x4E 0x00 0x45 0x00 0x57 0x00 0x41 0x00 0x52 0x00 0x45 0x00 0x20 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 29
0x50 0x00 0x54 0x00 0x53 0x00 0x31 0x00 0x2E 0x00 0x30 0x00 0x31 0x00 0x54 0x00
 USB_DataInStage() cnt = 13 EP0Data.Count = 13
0x52 0x00 0x43 0x00 0xEF 0xCC 0x00 0xD9 0xC8 0x00 0xC5 0xB2 0x00
0x80 0x06 0x00 0x01 0x00 0x00 0x12 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 18
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10 0x51 0xC2 0x01 0x13 0x00 0x01 0x01 0x04
 USB_DataInStage() cnt = 2 EP0Data.Count = 2
0x00 0x01
0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00
 USB_DataInStage() cnt = 9 EP0Data.Count = 9
0x09 0x02 0x22 0x00 0x01 0x01 0x00 0x80 0x32
0x80 0x06 0x00 0x02 0x00 0x00 0x22 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 34
0x09 0x02 0x22 0x00 0x01 0x01 0x00 0x80 0x32 0x09 0x04 0x00 0x00 0x01 0x03 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 18
0x00 0x5C 0x09 0x21 0x00 0x01 0x00 0x01 0x22 0x1D 0x00 0x07 0x05 0x81 0x03 0x10
 USB_DataInStage() cnt = 2 EP0Data.Count = 2
0x00 0x10
0x00 0x09 0x01 0x00 0x00 0x00 0x00 0x00
0x21 0x0A 0x00 0x00 0x00 0x00 0x00 0x00
0x81 0x06 0x00 0x22 0x00 0x00 0x5D 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 29
0x06 0x00 0xFF 0x09 0x01 0xA1 0x01 0xB2 0x01 0x82 0x19 0x01 0x29 0x3F 0x15 0x00
 USB_DataInStage() cnt = 13 EP0Data.Count = 13
0x25 0xFF 0x95 0x3F 0x75 0x08 0x82 0x01 0x02 0x92 0x01 0x02 0xC0

D12Ep1InProc() 8

D12Ep1InProc() 8

D12BusRstProc() 40
0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 18
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10 0x51 0xC2 0x01 0x13 0x00 0x01 0x01 0x04
 USB_DataInStage() cnt = 2 EP0Data.Count = 2
0x00 0x01

D12BusRstProc() 40
0x00 0x05 0x02 0x00 0x00 0x00 0x00 0x00
USB_REQUEST_SET_ADDRESS = 5
D12_SetAddressEnable() REQUEST_TO_DEVICE = 0
0x80 0x06 0x00 0x01 0x00 0x00 0x12 0x00
 USB_DataInStage() cnt = 16 EP0Data.Count = 18
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10 0x51 0xC2 0x01 0x13 0x00 0x01 0x01 0x04
 USB_DataInStage() cnt = 2 EP0Data.Count = 2
0x00 0x01
0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00
 USB_DataInStage() cnt = 9 EP0Data.Count = 9
0x09 0x02 0x22 0x00 0x01 0x01 0x00 0x80 0x32
0x00 0x09 0x01 0x00 0x00 0x00 0x00 0x00
0x02 0x01 0x00 0x00 0x81 0x00 0x00 0x00

D12Ep1InProc() 8

D12Ep1InProc() 8
tyt5555
驱动小牛
驱动小牛
  • 注册日期2006-03-15
  • 最后登录2009-03-02
  • 粉丝0
  • 关注0
  • 积分1004分
  • 威望172点
  • 贡献值0点
  • 好评度131点
  • 原创分0分
  • 专家分0分
25楼#
发布于:2007-01-11 15:13
有点雾里看花
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
26楼#
发布于:2008-06-18 10:54
今天无奈又来这里看旧帐。幸好往日依旧。两种连接过程依然还在
tianrongcai
驱动牛犊
驱动牛犊
  • 注册日期2005-06-24
  • 最后登录2011-03-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望39点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
27楼#
发布于:2008-06-18 10:59
第一次插入USB HOST的USB设备收到的第一个数据包
80 6 0 1 0 0 40 0  ,如不是第一次40的数据有可能就改为你的控制端点的缓冲长度。
movetoporket
驱动牛犊
驱动牛犊
  • 注册日期2008-06-21
  • 最后登录2012-02-11
  • 粉丝0
  • 关注0
  • 积分38分
  • 威望382点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
28楼#
发布于:2008-06-25 22:55
不懂,回复你.
depan
驱动牛犊
驱动牛犊
  • 注册日期2007-10-21
  • 最后登录2008-07-07
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望8点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
29楼#
发布于:2008-07-01 13:14
能打个包.这样小弟也看不懂
上一页 下一页
游客

返回顶部