일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- port
- VMware
- DevOps
- 루비
- QT
- 드라이버
- docker-compose
- VPN
- 도커
- 우분투
- window size
- 방화벽체크
- opsworks
- docker
- driver
- golang
- RUBY
- docker container
- docker registry
- 리눅스
- Openswan
- ubuntu
- AWS
- ssh command
- VIM
- 패키지
- ssh
- Linux
- sudo
- Chef
- Today
- Total
구리의 창고
USB 드라이버 인터럽트 통신에서 데이터 받아오기 본문
일단.. 인터럽트 전송 전용 URB를 만든다.
지금부터 할 방법으로는 데이터를 받아오기 위해선 두 개의 함수가 필요하다
한 개는 urb를 생성하는과정이고, 한 개는 데이터를 처리하면서 다시 urb를 생성하게해준다.
UsbBuildInterruptOrBulkTransferRequest() 함수를 이용해 URB를 생성해준다.
그리고 IoSetCompletionRoutine() 함수를 이용해서, Irp와 인터럽트가 들어왔을 때 호출 할 함수를 등록해준다.
NTSTATUS StartInterruptUrb(
PDEVICE_EXTENSION pdx
)
{
// If the interrupt polling IRP is currently running, don't try to start
// it again.
BOOLEAN startirp;
KIRQL oldirql ;
PIRP Irp ;
PURB urb ;
PIO_STACK_LOCATION stack ;
DbgPrint("[!] StartInterruptUrb\n");
KeAcquireSpinLock(&pdx->polllock, &oldirql) ;
if (pdx->pollpending)
{
startirp = FALSE ;
}
else
{
startirp = TRUE, pdx->pollpending = TRUE ;
}
KeReleaseSpinLock(&pdx->polllock, oldirql) ;
if (!startirp)
{
return STATUS_DEVICE_BUSY ; // already pending
}
Irp = pdx->PollingIrp ;
urb = pdx->PollingUrb ;
ASSERT(Irp && urb);
// Initialize the URB we use for reading the interrupt pipe
UsbBuildInterruptOrBulkTransferRequest(
urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
pdx->hpipe,
&pdx->intdata,
NULL,
sizeof(pdx->intdata),
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL
);
// Install "OnInterrupt" as the completion routine for the polling IRP.
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnInterrupt, pdx, TRUE, TRUE, TRUE);
// Initialize the IRP for an internal control request
stack = IoGetNextIrpStackLocation(Irp) ;
stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL ;
stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB ;
stack->Parameters.Others.Argument1 = urb ;
Irp->Cancel = FALSE;
return IoCallDriver(pdx->TopOfStackDeviceObject, Irp);
}
NTSTATUS OnInterrupt(
PDEVICE_OBJECT junk,
PIRP Irp,
PDEVICE_EXTENSION pdx
)
{
KIRQL oldirql ;
int i ;
KeAcquireSpinLock(&pdx->polllock, &oldirql) ;
pdx->pollpending = FALSE ;
KeReleaseSpinLock(&pdx->polllock, oldirql) ;
DbgPrint("[!] OnInterrupt Enter, Status : %x\n", Irp->IoStatus.Status);
if (NT_SUCCESS(Irp->IoStatus.Status)) {
DbgPrint("[!] Interrupt : %x %x %x %x\n", pdx->intdata[0], pdx->intdata[1], pdx->intdata[2], pdx->intdata[3]) ;
StartInterruptUrb(pdx); // issue next polling request
pdx->InitPolling = TRUE ;
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
헌데 문제가 발생한다.
실제로 전송되는 데이터가 버퍼크기보다 작으면 블루스크린이 뜨고만다...
USB 초기화 하는 부분에서 PIPE의 MaxPacketSize를 적절히 조절해준다.
'Window Driver' 카테고리의 다른 글
Application과 Driver 이벤트 공유하기 (0) | 2010.03.05 |
---|---|
RtlQueryRegistryValues, RtlWriteRegistryValue, RtlDeleteRegistryValue (0) | 2010.03.03 |
USB드라이버가 URB를 IRP에 담아서 사용하는 방법 (0) | 2010.02.25 |
CLASS GUID (0) | 2010.02.24 |
Writing Windows WDM Device Drivers (CHRIS CANT) CD (0) | 2010.02.23 |
Comments