ReactOS  0.4.15-dev-3440-g915569a
fxusbinterfaceum.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxUsbInterfaceUm.cpp
8 
9 Abstract:
10 
11 Author:
12 
13 Environment:
14 
15  user mode only
16 
17 Revision History:
18 
19 --*/
20 
21 #include "fxusbpch.hpp"
22 
23 extern "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 
48  urb.UmUrbGetAssociatedInterface.Hdr.InterfaceHandle = m_UsbDevice->m_WinUsbHandle;
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 
69  status = m_UsbDevice->SendSyncUmUrb(&urb, 5);
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 
176 Done:
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 
195 NTSTATUS
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 
CfxDevice * m_Device
Definition: fxobject.hpp:329
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
FxUsbDevice * m_UsbDevice
_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
#define TRUE
Definition: types.h:120
_Must_inspect_result_ NTSTATUS SendSyncUmUrb(__inout PUMURB Urb, __in ULONGLONG Time, __in_opt WDFREQUEST Request=NULL, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL)
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS SetWinUsbHandle(_In_ UCHAR FrameworkInterfaceIndex)
FxUsbPipe ** m_ConfiguredPipes
NTSTATUS UpdatePipeAttributes(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes)
VOID SetNumConfiguredPipes(__in UCHAR NumberOfPipes)
VOID SetConfiguredPipes(__in FxUsbPipe **ppPipes)
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
Definition: umusb.h:173
UCHAR m_NumberOfConfiguredPipes
#define _In_
Definition: ms_sal.h:308
#define UMURB_FUNCTION_QUERY_PIPE
Definition: umusb.h:46
GLsizeiptr size
Definition: glext.h:5919
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_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
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID CleanupInterfacePipesAndDelete(__in FxUsbInterface *UsbInterface)
_Must_inspect_result_ _In_ WDFUSBINTERFACE _In_opt_ PWDF_OBJECT_ATTRIBUTES PipesAttributes
Definition: wdfusb.h:2388
_Must_inspect_result_ NTSTATUS Init(__in CfxDeviceBase *Device)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define UMURB_FUNCTION_GET_ASSOCIATED_INTERFACE
Definition: umusb.h:54
struct _UMURB_GET_ASSOCIATED_INTERFACE UmUrbGetAssociatedInterface
Definition: umusb.h:239
NTSTATUS MakeAndConfigurePipes(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in UCHAR NumPipes)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
BOOLEAN IsInterfaceConfigured(VOID)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
struct _UMURB_QUERY_PIPE UmUrbQueryPipe
Definition: umusb.h:237
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
VOID InitPipe(__in PUSBD_PIPE_INFORMATION PipeInfo, __in UCHAR InterfaceNumber, __in FxUsbInterface *UsbInterface)
Definition: fxusbpipe.cpp:1073
Definition: ps.c:97