ReactOS  0.4.15-dev-3165-gdf6fff7
fxusbpipekm.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) Microsoft. All rights reserved.
3 //
4 #include "fxusbpch.hpp"
5 
6 extern "C" {
7 #include "FxUsbPipeKm.tmh"
8 }
9 
10 #include "Fxglobals.h"
11 
12 VOID
15  )
16 /*++
17 
18 Routine Description:
19  virtual function which stores and references memory if it is an FxObject
20  and then fills in the appropriate fields in the URB.
21 
22 Arguments:
23  Buffer - union which can be many types of memory
24 
25 Return Value:
26  None
27 
28  --*/
29 {
30  RtlZeroMemory(m_Urb, sizeof(*m_Urb));
31 
33  m_Urb->Hdr.Length = sizeof(*m_Urb);
34 
36 
37  Buffer->AssignValues(&m_Urb->TransferBuffer,
40 
41  //
42  // If we have built a partial MDL, use that instead. TransferBufferLength
43  // is still valid because the Offsets or length in Buffer will have been
44  // used to create this PartialMdl by the caller.
45  //
46  if (m_PartialMdl != NULL) {
48  }
49 }
50 
51 __drv_functionClass(KDEFERRED_ROUTINE)
56 VOID
58  __in struct _KDPC *Dpc,
62  )
63 {
64  FxUsbPipeRepeatReader* pRepeater;
65  FxUsbPipe* pPipe;
66 
70 
71  #pragma prefast(push);
72 
73 
75  pPipe = pRepeater->Parent->m_Pipe;
76 
77  //
78  // Ignore the return value because once we have sent the request, we
79  // want all processing to be done in the completion routine.
80  //
82  pRepeater->Request->GetSubmitIrp());
83  #pragma prefast(pop);
84 }
85 
90  __in size_t TotalBufferLength
91  )
92 {
94  WDF_OBJECT_ATTRIBUTES attributes;
96  LONG i;
97 
99 
100  if (TotalBufferLength <= MAXUSHORT) {
103  }
104  else {
107  }
108 
109  if (m_Lookaside == NULL) {
111  }
112 
113  if (Config->BufferAttributes == NULL) {
114  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
115  }
116  else {
117  RtlCopyMemory(&attributes,
118  Config->BufferAttributes,
119  sizeof(WDF_OBJECT_ATTRIBUTES));
120  }
121 
122  //
123  // By specifying the loookaside as the parent for the memory objects that
124  // will be created, when we destroy the lookaside list, we will destroy any
125  // outstanding memory objects that have been allocated. This can happen if
126  // we initialize the repeater, but never send any i/o. (Normally the
127  // memory object would be freed when the read completes.)
128  //
129  attributes.ParentObject = m_Lookaside->GetObjectHandle();
130 
131  status = m_Lookaside->Initialize(TotalBufferLength, &attributes);
132  if (!NT_SUCCESS(status)) {
133  return status;
134  }
135 
138  &m_WorkItem
139  );
140  if (!NT_SUCCESS(status)) {
142  "Could not allocate workitem: %!STATUS!", status);
143  return status;
144  }
145 
146  m_Offsets.BufferLength = Config->TransferLength;
147  m_Offsets.BufferOffset = Config->HeaderLength;
148 
149  for (i = 0; i < m_NumReaders; i++) {
150  FxUsbPipeRepeatReader* pRepeater;
151 
152  pRepeater = &m_Readers[i];
153 
154  pRepeater->Parent = this;
155 
157 
158  //
159  // This will allocate the PIRP
160  //
163  NULL,
164  m_Pipe,
167  &pRepeater->Request);
168 
169  if (!NT_SUCCESS(status)) {
170  return status;
171  }
172 
173  pRepeater->RequestIrp = pRepeater->Request->GetSubmitIrp();
174 
175  //
176  // Initialize the event before FormatRepeater clears it
177  //
179 
180  if (!NT_SUCCESS(status)) {
183  "Could not initialize ReadCompletedEvent: %!STATUS!",
184  status);
185 
186  return status;
187  }
188 
189  //
190  // This will allocate the context
191  //
192  status = FormatRepeater(pRepeater);
193 
194  if (!NT_SUCCESS(status)) {
195  return status;
196  }
197  }
198 
199  return STATUS_SUCCESS;
200 }
201 
203 NTSTATUS
207  __in ULONG TransferFlags
208  )
209 {
210  FxUsbPipeTransferContext* pContext;
212  size_t bufferSize;
213  ULONG dummyLength;
214  FX_URB_TYPE urbType;
215 
216  //
217  // Make sure request is for the right type
218  //
221 
223  "WDFUSBPIPE %p not the right type, %!STATUS!",
224  GetHandle(), status);
225 
226  return status;
227  }
228 
229  bufferSize = Buffer->GetBufferLength();
230 
231  status = RtlSizeTToULong(bufferSize, &dummyLength);
232  if (!NT_SUCCESS(status)) {
234  "WDFUSBPIPE %p, buffer size truncated, %!STATUS!",
235  GetHandle(), status);
236  return status;
237  }
238 
239  //
240  // On reads, check to make sure the read in value is an integral number of
241  // packet sizes
242  //
243  if (TransferFlags & USBD_TRANSFER_DIRECTION_IN) {
244  if (IsInEndpoint() == FALSE) {
246  "Pipe %p, sending __in transaction on a __out endpoint",
247  this);
248 
250  }
251 
252  if (m_CheckPacketSize &&
255  }
256  }
257  else {
258  if (IsOutEndpoint() == FALSE) {
260  "Pipe %p, sending __out transaction on an __in endpoint",
261  this);
262 
264  }
265  }
266 
267  status = Request->ValidateTarget(this);
268  if (!NT_SUCCESS(status)) {
270  "Pipe %p, Request %p, setting target failed, "
271  "status %!STATUS!", this, Request, status);
272 
273  return status;
274  }
275 
276  if (Request->HasContextType(FX_RCT_USB_PIPE_XFER)) {
277  pContext = (FxUsbPipeTransferContext*) Request->GetContext();
278  }
279  else {
281 
282  pContext = new(GetDriverGlobals()) FxUsbPipeTransferContext(urbType);
283  if (pContext == NULL) {
285  }
286 
287  if (urbType == FxUrbTypeUsbdAllocated) {
288  status = pContext->AllocateUrb(m_USBDHandle);
289  if (!NT_SUCCESS(status)) {
290  delete pContext;
291  return status;
292  }
293  //
294  // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
295  // important to release those resorces before the devnode is removed. Those
296  // resoruces are removed at the time Request is disposed.
297  //
298  Request->EnableContextDisposeNotification();
299  }
300 
301  Request->SetContext(pContext);
302  }
303 
304  //
305  // Always set the memory after determining the context. This way we can
306  // free a previously referenced memory object if necessary.
307  //
308  if (Buffer->HasMdl()) {
309  PMDL pMdl;
310 
311  pMdl=NULL;
312  ASSERT(pContext->m_PartialMdl == NULL);
313 
314  //
315  // If it is an __in endpoint, the buffer will be written to by the
316  // controller, so request IoWriteAccess locking.
317  //
318  status = Buffer->GetOrAllocateMdl(
320  &pMdl,
321  &pContext->m_PartialMdl,
322  &pContext->m_UnlockPages,
324 
325  if (!NT_SUCCESS(status)) {
326  return status;
327  }
328 
329  ASSERT(pMdl != NULL);
330  }
331 
332  pContext->StoreAndReferenceMemory(Buffer);
333 
334  pContext->SetUrbInfo(m_PipeInformation.PipeHandle, TransferFlags);
335 
336  if (pContext->m_Urb == &pContext->m_UrbLegacy) {
337  urbType = FxUrbTypeLegacy;
338  }
339  else {
340  urbType = FxUrbTypeUsbdAllocated;
341  }
342 
343  FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
344 
345  return STATUS_SUCCESS;
346 }
347 
348 VOID
351  )
352 {
353  //
354  // Do a field by field copy for the WDF structure, since fields could change.
355  //
362 }
363 
366  VOID
367  )
368 {
370 }
371 
372 BOOLEAN
375  )
376 {
378 }
379 
CfxDevice * m_Device
Definition: fxobject.hpp:329
_Must_inspect_result_ NTSTATUS FormatTransferRequest(__in FxRequestBase *Request, __in FxRequestBuffer *Buffer, __in ULONG TransferFlags=0)
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
#define RtlSizeTToULong
FX_URB_TYPE GetFxUrbTypeForRequest(__in FxRequestBase *Request)
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PVOID WdmObject, __out FxSystemWorkItem **pObject)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:107
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define __drv_maxIRQL(irql)
Definition: driverspecs.h:290
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES RequestAttributes, __in_opt MdIrp Irp, __in_opt FxIoTarget *Target, __in FxRequestIrpOwnership Ownership, __in FxRequestConstructorCaller Caller, __deref_out FxRequest **Request)
Definition: fxrequest.cpp:161
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
__inline BOOLEAN IsOutEndpoint(VOID)
Definition: fxusbpipe.hpp:531
struct _URB_HEADER Hdr
Definition: usb.h:498
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
__drv_functionClass(KDEFERRED_ROUTINE) __drv_maxIRQL(DISPATCH_LEVEL) __drv_minIRQL(DISPATCH_LEVEL) __drv_requiresIRQL(DISPATCH_LEVEL) __drv_sameIRQL VOID FxUsbPipeContinuousReader
Definition: fxusbpipekm.cpp:51
enum _FX_URB_TYPE FX_URB_TYPE
FxUsbDevice * m_UsbDevice
Definition: fxusbpipe.hpp:698
FxSystemWorkItem * m_WorkItem
Definition: fxusbpipe.hpp:360
_In_ WDFUSBPIPE _Out_ PWDF_USB_PIPE_INFORMATION PipeInformation
Definition: wdfusb.h:1741
BOOLEAN IsType(__in WDF_USB_PIPE_TYPE Type)
__inline BOOLEAN IsInEndpoint(VOID)
Definition: fxusbpipe.hpp:513
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in EVENT_TYPE Type, __in BOOLEAN InitialState)
Definition: mxeventkm.h:55
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
_URB_BULK_OR_INTERRUPT_TRANSFER m_UrbLegacy
Definition: fxusbpipe.hpp:86
size_t BufferOffset
Definition: wdfmemory.h:65
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
#define __out
Definition: dbghelp.h:62
unsigned char BOOLEAN
Definition: bufpool.h:45
static MdDeferredRoutineType _FxUsbPipeContinuousReadDpc
Definition: fxusbpipe.hpp:306
_Must_inspect_result_ NTSTATUS Config(__in PWDF_USB_CONTINUOUS_READER_CONFIG Config, __in size_t TotalBufferLength)
Definition: fxusbpipekm.cpp:88
VOID GetInformation(__out PWDF_USB_PIPE_INFORMATION PipeInformation)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:264
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
#define __drv_sameIRQL
Definition: driverspecs.h:324
virtual _Must_inspect_result_ NTSTATUS Initialize(__in size_t BufferSize, __in PWDF_OBJECT_ATTRIBUTES MemoryAttributes)=0
PFX_DRIVER_GLOBALS pFxDriverGlobals
__inline MdIrp GetSubmitIrp(VOID)
UCHAR EndpointAddress
Definition: usb.h:261
#define ASSERT(a)
Definition: mode.c:44
#define __drv_requiresIRQL(irql)
Definition: driverspecs.h:320
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
WDFUSBPIPE GetHandle(VOID)
Definition: fxusbpipe.hpp:504
FxLookasideList * m_Lookaside
Definition: fxusbpipe.hpp:345
USHORT MaximumPacketSize
Definition: usb.h:260
Type
Definition: Type.h:6
FxUsbInterface * m_UsbInterface
Definition: fxusbpipe.hpp:700
ULONG MaximumTransferSize
Definition: usb.h:265
USBD_PIPE_INFORMATION m_PipeInformation
Definition: fxusbpipe.hpp:714
size_t BufferLength
Definition: wdfmemory.h:72
WDF_USB_PIPE_TYPE GetType(VOID)
size_t bufferSize
Definition: ketypes.h:687
UCHAR GetConfiguredSettingIndex(VOID)
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
#define _Must_inspect_result_
Definition: ms_sal.h:558
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_Must_inspect_result_ NTSTATUS FormatRepeater(__in FxUsbPipeRepeatReader *Repeater)
Definition: fxusbpipe.cpp:687
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
USBD_HANDLE m_USBDHandle
Definition: fxusbpipe.hpp:737
FxUsbPipeRepeatReader m_Readers[1]
Definition: fxusbpipe.hpp:406
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
USBD_PIPE_TYPE PipeType
Definition: usb.h:263
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: usb.h:529
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
WDFOBJECT ParentObject
Definition: wdfobject.h:130
WDFMEMORY_OFFSET m_Offsets
Definition: fxusbpipe.hpp:355
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
#define MAXUSHORT
Definition: typedefs.h:83
enum _WDF_USB_PIPE_TYPE WDF_USB_PIPE_TYPE
unsigned int ULONG
Definition: retypes.h:1
FxUsbPipeContinuousReader * Parent
Definition: fxusbpipe.hpp:194
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID SetUrbInfo(__in USBD_PIPE_HANDLE PipeHandle, __in ULONG TransferFlags)
Definition: fxusbpipe.cpp:903
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACINGIO
Definition: dbgtrace.h:66
BOOLEAN m_CheckPacketSize
Definition: fxusbpipe.hpp:732
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbpipe.cpp:825
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
#define __drv_minIRQL(irql)
Definition: driverspecs.h:292
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
Definition: usb.h:95
static WDF_USB_PIPE_TYPE _UsbdPipeTypeToWdf(__in USBD_PIPE_TYPE UsbdPipeType)
Definition: fxusbpipe.hpp:643
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
Definition: fxusbpipekm.cpp:13
VOID FxFormatUsbRequest(__in FxRequestBase *Request, __in PURB Urb, __in FX_URB_TYPE FxUrbType, __drv_when(FxUrbType==FxUrbTypeUsbdAllocated, __in) __drv_when(FxUrbType !=FxUrbTypeUsbdAllocated, __in_opt) USBD_HANDLE UsbdHandle)
Definition: usbutil.cpp:29
_URB_BULK_OR_INTERRUPT_TRANSFER * m_Urb
Definition: fxusbpipe.hpp:91
Definition: ps.c:97
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675