ReactOS 0.4.15-dev-7924-g5949c20
fxusbinterfaceum.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxUsbInterfaceUm.cpp
8
9Abstract:
10
11Author:
12
13Environment:
14
15 user mode only
16
17Revision History:
18
19--*/
20
21#include "fxusbpch.hpp"
22
23extern "C" {
24#include "FxUsbInterfaceUm.tmh"
25}
26
29 _In_ UCHAR FrameworkInterfaceIndex
30)
31{
33 UMURB urb;
34
35 if (m_InterfaceNumber != FrameworkInterfaceIndex) {
37 "Composite device detected: Converting absolute interface "
38 "index %d to relative interface index %d", m_InterfaceNumber,
39 FrameworkInterfaceIndex);
40 }
41
42 if (FrameworkInterfaceIndex == 0) {
44 }
45 else {
46 RtlZeroMemory(&urb, sizeof(UMURB));
47
51
52 //
53 // If this is using the WinUSB dispatcher, this will ultimately call
54 // WinUsb_GetAssociatedInterface which expects a 0-based index but starts
55 // counting from index 1. To get the handle for interface n, we pass n-1
56 // and WinUSB will return the handle for (n-1)+1.
57 //
58 // The NativeUSB dispatcher ultimately calls WdfUsbTargetDeviceGetInterface.
59 // Unlike WinUSB.sys, this starts counting from index zero. The NativeUSB
60 // dispatcher expects this framework quirk and adjusts accordingly. See
61 // WudfNativeUsbDispatcher.cpp for more information.
62 //
63 // The actual interface number may differ from the interface index in
64 // composite devices. In all cases, the interface index (starting from zero)
65 // must be used.
66 //
67 urb.UmUrbGetAssociatedInterface.InterfaceIndex = FrameworkInterfaceIndex - 1;
68
70
71 if (NT_SUCCESS(status)) {
72 m_WinUsbHandle = urb.UmUrbGetAssociatedInterface.InterfaceHandle;
73 }
74 else {
76 "Failed to retrieve WinUsb interface handle");
78 }
79 }
80
81 return status;
82}
83
87 __in UCHAR NumPipes
88 )
89{
91 UCHAR iPipe;
92 FxUsbPipe* pPipe;
93 FxUsbPipe** ppPipes;
94 //
95 // Zero pipes are a valid configuration, this simplifies the code below.
96 //
97 ULONG size = (NumPipes == 0 ? 1 : NumPipes) * sizeof(FxUsbPipe*);
98 UMURB urb;
99
100 ppPipes = (FxUsbPipe**)FxPoolAllocate(GetDriverGlobals(), NonPagedPool, size);
101 if (ppPipes == NULL) {
105 "Unable to allocate memory %!STATUS!", status);
106 goto Done;
107 }
108
109 RtlZeroMemory(ppPipes, size);
110
111 for (iPipe = 0; iPipe < NumPipes; iPipe++) {
112 ppPipes[iPipe] = new (GetDriverGlobals(), PipesAttributes)
114
115 if (ppPipes[iPipe] == NULL) {
119 "Unable to allocate memory for the pipes %!STATUS!", status);
120 goto Done;
121 }
122
123 pPipe = ppPipes[iPipe];
124
125 status = pPipe->Init(m_UsbDevice->m_Device);
126 if (!NT_SUCCESS(status)) {
129 "Init pipe failed %!STATUS!", status);
130 goto Done;
131 }
132
133 status = pPipe->Commit(PipesAttributes, NULL, this);
134 if (!NT_SUCCESS(status)) {
137 "Commit pipe failed %!STATUS!", status);
138 goto Done;
139 }
140 }
141
142 if (IsInterfaceConfigured()) {
143 //
144 // Delete the old pipes
145 //
147 }
148
149 SetNumConfiguredPipes(NumPipes);
150 SetConfiguredPipes(ppPipes);
151
152 for (iPipe = 0; iPipe < m_NumberOfConfiguredPipes ; iPipe++) {
153 RtlZeroMemory(&urb, sizeof(UMURB));
154
155 urb.UmUrbQueryPipe.Hdr.InterfaceHandle = m_WinUsbHandle;
156 urb.UmUrbQueryPipe.Hdr.Function = UMURB_FUNCTION_QUERY_PIPE;
157 urb.UmUrbQueryPipe.Hdr.Length = sizeof(_UMURB_QUERY_PIPE);
158
159 urb.UmUrbQueryPipe.AlternateSetting = m_CurAlternateSetting;
160 urb.UmUrbQueryPipe.PipeID = iPipe;
161
162 status = m_UsbDevice->SendSyncUmUrb(&urb, 2);
163
164 if (!NT_SUCCESS(status)) {
167 "Send UMURB_FUNCTION_QUERY_PIPE failed %!STATUS!", status);
168 goto Done;
169 }
170
171 m_ConfiguredPipes[iPipe]->InitPipe(&urb.UmUrbQueryPipe.PipeInformation,
173 this);
174 }
175
176Done:
177 if (!NT_SUCCESS(status)) {
178 if (ppPipes != NULL) {
179 ASSERT(ppPipes != m_ConfiguredPipes);
180
181 for (iPipe = 0; iPipe < NumPipes; iPipe++) {
182 if (ppPipes[iPipe] != NULL) {
183 ppPipes[iPipe]->DeleteFromFailedCreate();
184 }
185 }
186
187 FxPoolFree(ppPipes);
188 ppPipes = NULL;
189 }
190 }
191
192 return status;
193}
194
198 )
199{
201 UCHAR iPipe;
202 FxUsbPipe** ppPipes;
203 UCHAR numberOfPipes;
204
205 numberOfPipes = m_NumberOfConfiguredPipes;
206 ppPipes = m_ConfiguredPipes;
207
208 for (iPipe = 0; iPipe < numberOfPipes; iPipe++) {
209 status = FxObjectAllocateContext(ppPipes[iPipe],
211 TRUE,
212 NULL);
213 if (!NT_SUCCESS(status)) {
216 "UpdatePipeAttributes failed %!STATUS!", status);
217 break;
218 }
219 }
220
221 //
222 // Pipe attributes are updated as part of select
223 // config and it is ok for the client driver to configure
224 // twice with the same attributes. In a similar scenario,
225 // KMDF will return STATUS_SUCCESS, so we should do the
226 // same for UMDF for consistency
227 //
230 }
231
232 return status;
233}
234
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ NTSTATUS Init(__in CfxDeviceBase *Device)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
VOID CleanupInterfacePipesAndDelete(__in FxUsbInterface *UsbInterface)
_Must_inspect_result_ NTSTATUS SendSyncUmUrb(__inout PUMURB Urb, __in ULONGLONG Time, __in_opt WDFREQUEST Request=NULL, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL)
FxUsbPipe ** m_ConfiguredPipes
VOID SetConfiguredPipes(__in FxUsbPipe **ppPipes)
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
BOOLEAN IsInterfaceConfigured(VOID)
NTSTATUS SetWinUsbHandle(_In_ UCHAR FrameworkInterfaceIndex)
UCHAR m_NumberOfConfiguredPipes
FxUsbDevice * m_UsbDevice
VOID SetNumConfiguredPipes(__in UCHAR NumberOfPipes)
NTSTATUS UpdatePipeAttributes(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes)
NTSTATUS MakeAndConfigurePipes(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in UCHAR NumPipes)
VOID InitPipe(__in PUSBD_PIPE_INFORMATION PipeInfo, __in UCHAR InterfaceNumber, __in FxUsbInterface *UsbInterface)
Definition: fxusbpipe.cpp:1073
#define __in
Definition: dbghelp.h:35
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NonPagedPool
Definition: env_spec_w32.h:307
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
_Must_inspect_result_ NTSTATUS FxObjectAllocateContext(__in FxObject *Object, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in BOOLEAN AllowCallbacksOnly, __deref_opt_out PVOID *Context)
Definition: handleapi.cpp:397
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
GLsizeiptr size
Definition: glext.h:5919
#define ASSERT(a)
Definition: mode.c:44
#define _In_
Definition: ms_sal.h:308
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
Definition: umusb.h:173
struct _UMURB_GET_ASSOCIATED_INTERFACE UmUrbGetAssociatedInterface
Definition: umusb.h:239
struct _UMURB_QUERY_PIPE UmUrbQueryPipe
Definition: umusb.h:237
Definition: ps.c:97
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UMURB_FUNCTION_GET_ASSOCIATED_INTERFACE
Definition: umusb.h:54
#define UMURB_FUNCTION_QUERY_PIPE
Definition: umusb.h:46
_Must_inspect_result_ _In_ WDFUSBINTERFACE _In_opt_ PWDF_OBJECT_ATTRIBUTES PipesAttributes
Definition: wdfusb.h:2390
unsigned char UCHAR
Definition: xmlstorage.h:181