ReactOS 0.4.16-dev-1946-g52006dd
fxusbpipekm.cpp
Go to the documentation of this file.
1//
2// Copyright (C) Microsoft. All rights reserved.
3//
4#include "../fxusbpch.hpp"
5
6extern "C" {
7#if defined(EVENT_TRACING)
8#include "FxUsbPipeKm.tmh"
9#endif
10
11#define RtlSizeTToULong RtlULongPtrToULong
12}
13
14#include "fxglobals.h"
15
16VOID
19 )
20/*++
21
22Routine Description:
23 virtual function which stores and references memory if it is an FxObject
24 and then fills in the appropriate fields in the URB.
25
26Arguments:
27 Buffer - union which can be many types of memory
28
29Return Value:
30 None
31
32 --*/
33{
34 RtlZeroMemory(m_Urb, sizeof(*m_Urb));
35
37 m_Urb->Hdr.Length = sizeof(*m_Urb);
38
40
41 Buffer->AssignValues(&m_Urb->TransferBuffer,
44
45 //
46 // If we have built a partial MDL, use that instead. TransferBufferLength
47 // is still valid because the Offsets or length in Buffer will have been
48 // used to create this PartialMdl by the caller.
49 //
50 if (m_PartialMdl != NULL) {
52 }
53}
54
55__drv_functionClass(KDEFERRED_ROUTINE)
60VOID
62 __in struct _KDPC *Dpc,
66 )
67{
68 FxUsbPipeRepeatReader* pRepeater;
69 FxUsbPipe* pPipe;
70
74
75 #pragma prefast(push);
76
77
79 pPipe = pRepeater->Parent->m_Pipe;
80
81 //
82 // Ignore the return value because once we have sent the request, we
83 // want all processing to be done in the completion routine.
84 //
86 pRepeater->Request->GetSubmitIrp());
87 #pragma prefast(pop);
88}
89
94 __in size_t TotalBufferLength
95 )
96{
98 WDF_OBJECT_ATTRIBUTES attributes;
100 LONG i;
101
103
104 if (TotalBufferLength <= MAXUSHORT) {
107 }
108 else {
111 }
112
113 if (m_Lookaside == NULL) {
115 }
116
117 if (Config->BufferAttributes == NULL) {
118 WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
119 }
120 else {
121 RtlCopyMemory(&attributes,
122 Config->BufferAttributes,
123 sizeof(WDF_OBJECT_ATTRIBUTES));
124 }
125
126 //
127 // By specifying the loookaside as the parent for the memory objects that
128 // will be created, when we destroy the lookaside list, we will destroy any
129 // outstanding memory objects that have been allocated. This can happen if
130 // we initialize the repeater, but never send any i/o. (Normally the
131 // memory object would be freed when the read completes.)
132 //
134
135 status = m_Lookaside->Initialize(TotalBufferLength, &attributes);
136 if (!NT_SUCCESS(status)) {
137 return status;
138 }
139
143 );
144 if (!NT_SUCCESS(status)) {
146 "Could not allocate workitem: %!STATUS!", status);
147 return status;
148 }
149
150 m_Offsets.BufferLength = Config->TransferLength;
151 m_Offsets.BufferOffset = Config->HeaderLength;
152
153 for (i = 0; i < m_NumReaders; i++) {
154 FxUsbPipeRepeatReader* pRepeater;
155
156 pRepeater = &m_Readers[i];
157
158 pRepeater->Parent = this;
159
161
162 //
163 // This will allocate the PIRP
164 //
167 NULL,
168 m_Pipe,
171 &pRepeater->Request);
172
173 if (!NT_SUCCESS(status)) {
174 return status;
175 }
176
177 pRepeater->RequestIrp = pRepeater->Request->GetSubmitIrp();
178
179 //
180 // Initialize the event before FormatRepeater clears it
181 //
183
184 if (!NT_SUCCESS(status)) {
187 "Could not initialize ReadCompletedEvent: %!STATUS!",
188 status);
189
190 return status;
191 }
192
193 //
194 // This will allocate the context
195 //
196 status = FormatRepeater(pRepeater);
197
198 if (!NT_SUCCESS(status)) {
199 return status;
200 }
201 }
202
203 return STATUS_SUCCESS;
204}
205
211 __in ULONG TransferFlags
212 )
213{
214 FxUsbPipeTransferContext* pContext;
216 size_t bufferSize;
217 ULONG dummyLength;
218 FX_URB_TYPE urbType;
219
220 //
221 // Make sure request is for the right type
222 //
225
227 "WDFUSBPIPE %p not the right type, %!STATUS!",
228 GetHandle(), status);
229
230 return status;
231 }
232
233 bufferSize = Buffer->GetBufferLength();
234
235 status = RtlSizeTToULong(bufferSize, &dummyLength);
236 if (!NT_SUCCESS(status)) {
238 "WDFUSBPIPE %p, buffer size truncated, %!STATUS!",
239 GetHandle(), status);
240 return status;
241 }
242
243 //
244 // On reads, check to make sure the read in value is an integral number of
245 // packet sizes
246 //
247 if (TransferFlags & USBD_TRANSFER_DIRECTION_IN) {
248 if (IsInEndpoint() == FALSE) {
250 "Pipe %p, sending __in transaction on a __out endpoint",
251 this);
252
254 }
255
256 if (m_CheckPacketSize &&
259 }
260 }
261 else {
262 if (IsOutEndpoint() == FALSE) {
264 "Pipe %p, sending __out transaction on an __in endpoint",
265 this);
266
268 }
269 }
270
271 status = Request->ValidateTarget(this);
272 if (!NT_SUCCESS(status)) {
274 "Pipe %p, Request %p, setting target failed, "
275 "status %!STATUS!", this, Request, status);
276
277 return status;
278 }
279
280 if (Request->HasContextType(FX_RCT_USB_PIPE_XFER)) {
281 pContext = (FxUsbPipeTransferContext*) Request->GetContext();
282 }
283 else {
285
286 pContext = new(GetDriverGlobals()) FxUsbPipeTransferContext(urbType);
287 if (pContext == NULL) {
289 }
290
291 if (urbType == FxUrbTypeUsbdAllocated) {
292 status = pContext->AllocateUrb(m_USBDHandle);
293 if (!NT_SUCCESS(status)) {
294 delete pContext;
295 return status;
296 }
297 //
298 // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
299 // important to release those resorces before the devnode is removed. Those
300 // resoruces are removed at the time Request is disposed.
301 //
302 Request->EnableContextDisposeNotification();
303 }
304
305 Request->SetContext(pContext);
306 }
307
308 //
309 // Always set the memory after determining the context. This way we can
310 // free a previously referenced memory object if necessary.
311 //
312 if (Buffer->HasMdl()) {
313 PMDL pMdl;
314
315 pMdl=NULL;
316 ASSERT(pContext->m_PartialMdl == NULL);
317
318 //
319 // If it is an __in endpoint, the buffer will be written to by the
320 // controller, so request IoWriteAccess locking.
321 //
322 status = Buffer->GetOrAllocateMdl(
324 &pMdl,
325 &pContext->m_PartialMdl,
326 &pContext->m_UnlockPages,
328
329 if (!NT_SUCCESS(status)) {
330 return status;
331 }
332
333 ASSERT(pMdl != NULL);
334 }
335
337
338 pContext->SetUrbInfo(m_PipeInformation.PipeHandle, TransferFlags);
339
340 if (pContext->m_Urb == &pContext->m_UrbLegacy) {
341 urbType = FxUrbTypeLegacy;
342 }
343 else {
344 urbType = FxUrbTypeUsbdAllocated;
345 }
346
347 FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
348
349 return STATUS_SUCCESS;
350}
351
352VOID
355 )
356{
357 //
358 // Do a field by field copy for the WDF structure, since fields could change.
359 //
366}
367
370 VOID
371 )
372{
374}
375
379 )
380{
382}
383
unsigned char BOOLEAN
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
virtual _Must_inspect_result_ NTSTATUS Initialize(__in size_t BufferSize, __in PWDF_OBJECT_ATTRIBUTES MemoryAttributes)=0
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
__inline MdIrp GetSubmitIrp(VOID)
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
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PVOID WdmObject, __out FxSystemWorkItem **pObject)
FX_URB_TYPE GetFxUrbTypeForRequest(__in FxRequestBase *Request)
UCHAR GetConfiguredSettingIndex(VOID)
FxUsbDevice * m_UsbDevice
Definition: fxusbpipe.hpp:698
BOOLEAN IsType(__in WDF_USB_PIPE_TYPE Type)
static WDF_USB_PIPE_TYPE _UsbdPipeTypeToWdf(__in USBD_PIPE_TYPE UsbdPipeType)
Definition: fxusbpipe.hpp:643
WDF_USB_PIPE_TYPE GetType(VOID)
BOOLEAN m_CheckPacketSize
Definition: fxusbpipe.hpp:732
_Must_inspect_result_ NTSTATUS FormatTransferRequest(__in FxRequestBase *Request, __in FxRequestBuffer *Buffer, __in ULONG TransferFlags=0)
USBD_PIPE_INFORMATION m_PipeInformation
Definition: fxusbpipe.hpp:714
VOID GetInformation(__out PWDF_USB_PIPE_INFORMATION PipeInformation)
FxUsbInterface * m_UsbInterface
Definition: fxusbpipe.hpp:700
USBD_HANDLE m_USBDHandle
Definition: fxusbpipe.hpp:737
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in EVENT_TYPE Type, __in BOOLEAN InitialState)
Definition: mxeventkm.h:55
#define __in
Definition: dbghelp.h:35
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
#define TRACINGIO
Definition: dbgtrace.h:66
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define __drv_requiresIRQL(irql)
Definition: driverspecs.h:321
#define __drv_maxIRQL(irql)
Definition: driverspecs.h:291
#define __drv_functionClass(x)
Definition: driverspecs.h:274
#define __drv_sameIRQL
Definition: driverspecs.h:325
#define __drv_minIRQL(irql)
Definition: driverspecs.h:293
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define RtlSizeTToULong
@ FxRequestConstructorCallerIsFx
@ FxRequestOwnsIrp
@ FX_RCT_USB_PIPE_XFER
@ FxUrbTypeLegacy
Definition: fxusbdevice.hpp:27
@ FxUrbTypeUsbdAllocated
Definition: fxusbdevice.hpp:28
enum _FX_URB_TYPE FX_URB_TYPE
size_t bufferSize
return pUsbPipe IsOutEndpoint()
return pUsbPipe IsInEndpoint()
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
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
@ NotificationEvent
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:772
long LONG
Definition: pedump.c:60
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
FxUsbPipeRepeatReader m_Readers[1]
Definition: fxusbpipe.hpp:406
FxLookasideList * m_Lookaside
Definition: fxusbpipe.hpp:345
_Must_inspect_result_ NTSTATUS FormatRepeater(__in FxUsbPipeRepeatReader *Repeater)
Definition: fxusbpipe.cpp:689
static MdDeferredRoutineType _FxUsbPipeContinuousReadDpc
Definition: fxusbpipe.hpp:306
FxSystemWorkItem * m_WorkItem
Definition: fxusbpipe.hpp:360
WDFMEMORY_OFFSET m_Offsets
Definition: fxusbpipe.hpp:355
_Must_inspect_result_ NTSTATUS Config(__in PWDF_USB_CONTINUOUS_READER_CONFIG Config, __in size_t TotalBufferLength)
Definition: fxusbpipekm.cpp:92
FxUsbPipeContinuousReader * Parent
Definition: fxusbpipe.hpp:194
_URB_BULK_OR_INTERRUPT_TRANSFER m_UrbLegacy
Definition: fxusbpipe.hpp:86
_URB_BULK_OR_INTERRUPT_TRANSFER * m_Urb
Definition: fxusbpipe.hpp:91
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
Definition: fxusbpipekm.cpp:17
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbpipe.cpp:827
VOID SetUrbInfo(__in USBD_PIPE_HANDLE PipeHandle, __in ULONG TransferFlags)
Definition: fxusbpipe.cpp:905
Definition: ketypes.h:751
struct _URB_HEADER Hdr
Definition: usb.h:498
Definition: usb.h:529
USHORT MaximumPacketSize
Definition: usb.h:260
ULONG MaximumTransferSize
Definition: usb.h:265
USBD_PIPE_TYPE PipeType
Definition: usb.h:263
UCHAR EndpointAddress
Definition: usb.h:261
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:264
size_t BufferOffset
Definition: wdfmemory.h:65
size_t BufferLength
Definition: wdfmemory.h:72
WDFOBJECT ParentObject
Definition: wdfobject.h:130
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
Definition: usb.h:95
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:31
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
@ WdfUsbPipeTypeInterrupt
Definition: wdfusb.h:122
@ WdfUsbPipeTypeBulk
Definition: wdfusb.h:121
_In_ WDFUSBPIPE _Out_ PWDF_USB_PIPE_INFORMATION PipeInformation
Definition: wdfusb.h:1744
enum _WDF_USB_PIPE_TYPE WDF_USB_PIPE_TYPE
@ IoReadAccess
Definition: ketypes.h:915
@ IoWriteAccess
Definition: ketypes.h:916
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:740
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:739
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:741