ReactOS 0.4.16-dev-329-g9223134
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#include "FxUsbPipeKm.tmh"
8}
9
10#include "Fxglobals.h"
11
12VOID
15 )
16/*++
17
18Routine 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
22Arguments:
23 Buffer - union which can be many types of memory
24
25Return 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)
56VOID
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 //
130
131 status = m_Lookaside->Initialize(TotalBufferLength, &attributes);
132 if (!NT_SUCCESS(status)) {
133 return status;
134 }
135
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
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
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
348VOID
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
375 )
376{
378}
379
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:325
@ NotificationEvent
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
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:687
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:88
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:13
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbpipe.cpp:825
VOID SetUrbInfo(__in USBD_PIPE_HANDLE PipeHandle, __in ULONG TransferFlags)
Definition: fxusbpipe.cpp:903
Definition: ketypes.h:699
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:29
_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:863
@ IoWriteAccess
Definition: ketypes.h:864
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689