1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxUsbInterfaceAPI.cpp 8 9 Abstract: 10 11 12 Author: 13 14 Environment: 15 16 Both kernel and user mode 17 18 Revision History: 19 20 --*/ 21 #include "fxusbpch.hpp" 22 23 extern "C" { 24 #include "FxUsbInterfaceAPI.tmh" 25 } 26 27 // 28 // Extern "C" all APIs 29 // 30 extern "C" { 31 32 _Must_inspect_result_ 33 __drv_maxIRQL(PASSIVE_LEVEL) 34 NTSTATUS 35 WDFAPI 36 WDFEXPORT(WdfUsbInterfaceSelectSetting)( 37 __in 38 PWDF_DRIVER_GLOBALS DriverGlobals, 39 __in 40 WDFUSBINTERFACE UsbInterface, 41 __in_opt 42 PWDF_OBJECT_ATTRIBUTES PipesAttributes, 43 __in 44 PWDF_USB_INTERFACE_SELECT_SETTING_PARAMS Params 45 ) 46 /*++ 47 48 Routine Description: 49 Selects an alternate setting on a given interface number 50 51 Arguments: 52 UsbInterface - the interface whose setting will be selected 53 54 PipesAttributes - Attributes to apply to each of the new pipes on the setting 55 56 Params - Strucutre indicating how to select a new setting 57 58 Return Value: 59 NTSTATUS 60 61 --*/ 62 { 63 DDI_ENTRY(); 64 65 PFX_DRIVER_GLOBALS pFxDriverGlobals; 66 FxUsbInterface* pUsbInterface; 67 NTSTATUS status; 68 69 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 70 UsbInterface, 71 FX_TYPE_USB_INTERFACE, 72 (PVOID*) &pUsbInterface, 73 &pFxDriverGlobals); 74 75 FxPointerNotNull(pFxDriverGlobals, Params); 76 77 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 78 if (!NT_SUCCESS(status)) { 79 return status; 80 } 81 82 if (Params->Size != sizeof(WDF_USB_INTERFACE_SELECT_SETTING_PARAMS)) { 83 status = STATUS_INFO_LENGTH_MISMATCH; 84 DoTraceLevelMessage( 85 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 86 "Params size %d, expected %d %!STATUS!", Params->Size, 87 sizeof(WDF_USB_INTERFACE_SELECT_SETTING_PARAMS), status); 88 return status; 89 } 90 91 status = FxValidateObjectAttributes(pFxDriverGlobals, 92 PipesAttributes, 93 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED); 94 if (!NT_SUCCESS(status)) { 95 return status; 96 } 97 98 #if (FX_CORE_MODE == FX_CORE_USER_MODE) 99 if (Params->Type != WdfUsbInterfaceSelectSettingTypeSetting) { 100 FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("UMDF may only select settings by index."), 101 DriverGlobals->DriverName); 102 } 103 #endif 104 105 switch (Params->Type) { 106 case WdfUsbInterfaceSelectSettingTypeDescriptor: 107 if (Params->Types.Descriptor.InterfaceDescriptor == NULL) { 108 status = STATUS_INVALID_PARAMETER; 109 DoTraceLevelMessage( 110 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 111 "InterfaceDescriptor passed in is NULL %!STATUS!", status); 112 113 } 114 else { 115 status = pUsbInterface->SelectSettingByDescriptor( 116 PipesAttributes, 117 Params->Types.Descriptor.InterfaceDescriptor 118 ); 119 } 120 break; 121 122 case WdfUsbInterfaceSelectSettingTypeSetting: 123 status = pUsbInterface->SelectSettingByIndex( 124 PipesAttributes, 125 Params->Types.Interface.SettingIndex 126 ); 127 break; 128 129 case WdfUsbInterfaceSelectSettingTypeUrb: 130 if (Params->Types.Urb.Urb == NULL || 131 Params->Types.Urb.Urb->UrbHeader.Function != URB_FUNCTION_SELECT_INTERFACE || 132 (Params->Types.Urb.Urb->UrbHeader.Length < 133 sizeof(struct _URB_SELECT_INTERFACE) - sizeof(USBD_PIPE_INFORMATION)) ) { 134 status = STATUS_INVALID_PARAMETER; 135 DoTraceLevelMessage( 136 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 137 "URB or URB fields passed in are invalid Urb 0x%p %!STATUS!", 138 Params->Types.Urb.Urb, status); 139 140 } 141 else { 142 status = pUsbInterface->SelectSetting(PipesAttributes, 143 Params->Types.Urb.Urb); 144 } 145 break; 146 147 default: 148 status = STATUS_INVALID_PARAMETER; 149 break; 150 } 151 152 return status; 153 } 154 155 156 __drv_maxIRQL(DISPATCH_LEVEL) 157 BYTE 158 WDFAPI 159 WDFEXPORT(WdfUsbInterfaceGetInterfaceNumber)( 160 __in 161 PWDF_DRIVER_GLOBALS DriverGlobals, 162 __in 163 WDFUSBINTERFACE UsbInterface 164 ) 165 /*++ 166 167 Routine Description: 168 Returns the interface number of the given interface. The interface number 169 is not necessarily the same as the index of the interface. Once is specified 170 by the device, the other is where it is located within an internal array. 171 172 Arguments: 173 UsbInterface - Interace whose number will be returned 174 175 Return Value: 176 interface number 177 178 --*/ 179 { 180 DDI_ENTRY(); 181 182 FxUsbInterface * pUsbInterface; 183 184 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 185 UsbInterface, 186 FX_TYPE_USB_INTERFACE, 187 (PVOID*) &pUsbInterface); 188 189 return pUsbInterface->GetInterfaceNumber(); 190 } 191 192 __drv_maxIRQL(DISPATCH_LEVEL) 193 BYTE 194 WDFAPI 195 WDFEXPORT(WdfUsbInterfaceGetNumEndpoints)( 196 __in 197 PWDF_DRIVER_GLOBALS DriverGlobals, 198 __in 199 WDFUSBINTERFACE UsbInterface, 200 __in 201 UCHAR SettingIndex 202 ) 203 /*++ 204 205 Routine Description: 206 Returns the number of endpoints (not configured) for a given setting on the 207 given interface. 208 209 Arguments: 210 UsbInterface - interface whose number of endpoints will be returned 211 212 SettingsIndex - the index into the alternate setting array 213 214 Return Value: 215 Number of endpoints 216 217 --*/ 218 { 219 DDI_ENTRY(); 220 221 FxUsbInterface * pUsbInterface; 222 223 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 224 UsbInterface, 225 FX_TYPE_USB_INTERFACE , 226 (PVOID*) &pUsbInterface); 227 228 return pUsbInterface->GetNumEndpoints(SettingIndex); 229 } 230 231 __drv_maxIRQL(DISPATCH_LEVEL) 232 VOID 233 WDFAPI 234 WDFEXPORT(WdfUsbInterfaceGetEndpointInformation)( 235 __in 236 PWDF_DRIVER_GLOBALS DriverGlobals, 237 __in 238 WDFUSBINTERFACE UsbInterface, 239 __in 240 UCHAR SettingIndex, 241 __in 242 UCHAR EndpointIndex, 243 __out 244 PWDF_USB_PIPE_INFORMATION EndpointInfo 245 ) 246 /*++ 247 248 Routine Description: 249 Returns information on a given endpoint (unconfigured) for an interface + 250 alternate setting index. 251 252 Arguments: 253 UsbInterface - interface which contains the endpoint 254 255 SettingIndex - alternate setting index 256 257 EndpointIndex - index into the endpoint array contained by interface+setting 258 259 EndpointInfo - structure to be filled in with the info of the endpoint 260 261 Return Value: 262 None 263 264 --*/ 265 { 266 DDI_ENTRY(); 267 268 PFX_DRIVER_GLOBALS pFxDriverGlobals; 269 FxUsbInterface * pUsbInterface; 270 271 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 272 UsbInterface, 273 FX_TYPE_USB_INTERFACE, 274 (PVOID*) &pUsbInterface, 275 &pFxDriverGlobals); 276 277 FxPointerNotNull(pFxDriverGlobals, EndpointInfo); 278 279 if (EndpointInfo->Size != sizeof(WDF_USB_PIPE_INFORMATION)) { 280 DoTraceLevelMessage( 281 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 282 "EndpointInfo Size %d incorrect, expected %d, %!STATUS!", 283 EndpointInfo->Size, sizeof(WDF_USB_PIPE_INFORMATION), 284 STATUS_INFO_LENGTH_MISMATCH); 285 FxVerifierDbgBreakPoint(pFxDriverGlobals); 286 return; 287 } 288 289 pUsbInterface->GetEndpointInformation(SettingIndex, 290 EndpointIndex, 291 EndpointInfo); 292 } 293 294 __drv_maxIRQL(DISPATCH_LEVEL) 295 BYTE 296 WDFEXPORT(WdfUsbInterfaceGetNumSettings)( 297 __in 298 PWDF_DRIVER_GLOBALS DriverGlobals, 299 __in 300 WDFUSBINTERFACE UsbInterface 301 ) 302 /*++ 303 304 Routine Description: 305 Returns the number of settings available on an interface. 306 307 Arguments: 308 UsbInterface - the usb interface being queried 309 310 Return Value: 311 Number of settings as described by the config descriptor 312 313 --*/ 314 { 315 DDI_ENTRY(); 316 317 FxUsbInterface * pUsbInterface; 318 319 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 320 UsbInterface, 321 FX_TYPE_USB_INTERFACE, 322 (PVOID*) &pUsbInterface); 323 324 return pUsbInterface->GetNumSettings(); 325 } 326 327 __drv_maxIRQL(DISPATCH_LEVEL) 328 VOID 329 WDFAPI 330 WDFEXPORT(WdfUsbInterfaceGetDescriptor)( 331 __in 332 PWDF_DRIVER_GLOBALS DriverGlobals, 333 __in 334 WDFUSBINTERFACE UsbInterface, 335 __in 336 UCHAR SettingIndex, 337 __out 338 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor 339 ) 340 /*++ 341 342 Routine Description: 343 Returns the underlying USB interface descriptor for the given WDF handle 344 345 Arguments: 346 UsbInterface - interface whose descriptor will be returned 347 348 SettingIndex - alternatve setting whose interface should be returned 349 350 InterfaceDescriptor - Pointer which will receive the descriptor 351 352 --*/ 353 { 354 DDI_ENTRY(); 355 356 PFX_DRIVER_GLOBALS pFxDriverGlobals; 357 FxUsbInterface * pUsbInterface; 358 359 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 360 UsbInterface, 361 FX_TYPE_USB_INTERFACE, 362 (PVOID*) &pUsbInterface, 363 &pFxDriverGlobals); 364 365 FxPointerNotNull(pFxDriverGlobals, InterfaceDescriptor); 366 367 pUsbInterface->GetDescriptor(InterfaceDescriptor, SettingIndex); 368 } 369 370 __drv_maxIRQL(DISPATCH_LEVEL) 371 BYTE 372 WDFAPI 373 WDFEXPORT(WdfUsbInterfaceGetConfiguredSettingIndex)( 374 __in 375 PWDF_DRIVER_GLOBALS DriverGlobals, 376 __in 377 WDFUSBINTERFACE UsbInterface 378 ) 379 /*++ 380 381 Routine Description: 382 Returns the alternate setting index which is currently configured 383 384 Arguments: 385 UsbInterface - interfase whose configured setting is being queried 386 387 Return Value: 388 The current setting or 0 on failure 389 390 --*/ 391 { 392 DDI_ENTRY(); 393 394 FxUsbInterface * pUsbInterface; 395 396 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 397 UsbInterface, 398 FX_TYPE_USB_INTERFACE , 399 (PVOID*) &pUsbInterface); 400 401 return pUsbInterface->GetConfiguredSettingIndex(); 402 } 403 404 __drv_maxIRQL(DISPATCH_LEVEL) 405 BYTE 406 WDFAPI 407 WDFEXPORT(WdfUsbInterfaceGetNumConfiguredPipes)( 408 __in 409 PWDF_DRIVER_GLOBALS DriverGlobals, 410 __in 411 WDFUSBINTERFACE UsbInterface 412 ) 413 /*++ 414 415 Routine Description: 416 Returns the number of configured pipes on a given interface. 417 418 Arguments: 419 UsbInterface - the configured interface 420 421 Return Value: 422 Number of configured pipes or 0 on error 423 424 --*/ 425 { 426 DDI_ENTRY(); 427 428 FxUsbInterface * pUsbInterface; 429 430 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 431 UsbInterface, 432 FX_TYPE_USB_INTERFACE , 433 (PVOID*) &pUsbInterface); 434 435 return pUsbInterface->GetNumConfiguredPipes(); 436 } 437 438 __drv_maxIRQL(DISPATCH_LEVEL) 439 WDFUSBPIPE 440 WDFAPI 441 WDFEXPORT(WdfUsbInterfaceGetConfiguredPipe)( 442 __in 443 PWDF_DRIVER_GLOBALS DriverGlobals, 444 __in 445 WDFUSBINTERFACE UsbInterface, 446 __in 447 UCHAR PipeIndex, 448 __out_opt 449 PWDF_USB_PIPE_INFORMATION PipeInfo 450 ) 451 /*++ 452 453 Routine Description: 454 Returns the WDFUSBPIPE handle for the configured interface + pipe index. 455 Optionally, information about the pipe is also returned. 456 457 Arguments: 458 UsbInterface - configured interface 459 460 PipeIndex - index into the number of pipes on the interface 461 462 PipeInfo - information to be returned on the pipe 463 464 Return Value: 465 valid WDFUSBPIPE or NULL on error 466 467 --*/ 468 { 469 DDI_ENTRY(); 470 471 PFX_DRIVER_GLOBALS pFxDriverGlobals; 472 FxUsbInterface * pUsbInterface; 473 NTSTATUS status; 474 475 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 476 UsbInterface, 477 FX_TYPE_USB_INTERFACE, 478 (PVOID*) &pUsbInterface, 479 &pFxDriverGlobals); 480 481 if (PipeInfo != NULL && PipeInfo->Size != sizeof(WDF_USB_PIPE_INFORMATION)) { 482 status = STATUS_INFO_LENGTH_MISMATCH; 483 484 DoTraceLevelMessage( 485 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, 486 "PipeInfo Size %d incorrect, expected %d, %!STATUS!", 487 PipeInfo->Size, sizeof(WDF_USB_PIPE_INFORMATION), status); 488 489 FxVerifierDbgBreakPoint(pFxDriverGlobals); 490 491 return NULL; 492 } 493 494 return pUsbInterface->GetConfiguredPipe(PipeIndex, PipeInfo); 495 } 496 497 } // extern "C" 498