Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenusbd.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Universal Serial Bus Driver/Helper Library 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: drivers/usb/usbd/usbd.c 00005 * PURPOSE: Helper Library for USB 00006 * PROGRAMMERS: 00007 * Filip Navara <xnavara@volny.cz> 00008 * Michael Martin <michael.martin@reactos.org> 00009 * 00010 */ 00011 00012 /* 00013 * Universal Serial Bus Driver/Helper Library 00014 * 00015 * Written by Filip Navara <xnavara@volny.cz> 00016 * 00017 * Notes: 00018 * This driver was obsoleted in Windows XP and most functions 00019 * became pure stubs. But some of them were retained for backward 00020 * compatibilty with existing drivers. 00021 * 00022 * Preserved functions: 00023 * 00024 * USBD_Debug_GetHeap (implemented) 00025 * USBD_Debug_RetHeap (implemented) 00026 * USBD_CalculateUsbBandwidth (implemented, tested) 00027 * USBD_CreateConfigurationRequestEx (implemented) 00028 * USBD_CreateConfigurationRequest 00029 * USBD_GetInterfaceLength (implemented) 00030 * USBD_ParseConfigurationDescriptorEx (implemented) 00031 * USBD_ParseDescriptors (implemented) 00032 * USBD_GetPdoRegistryParameters (implemented) 00033 */ 00034 00035 #define _USBD_ 00036 #define NDEBUG 00037 #include <ntddk.h> 00038 #include <usbdi.h> 00039 #include <usbdlib.h> 00040 #include <debug.h> 00041 #ifndef PLUGPLAY_REGKEY_DRIVER 00042 #define PLUGPLAY_REGKEY_DRIVER 2 00043 #endif 00044 00045 NTSTATUS NTAPI 00046 DriverEntry(PDRIVER_OBJECT DriverObject, 00047 PUNICODE_STRING RegistryPath) 00048 { 00049 return STATUS_SUCCESS; 00050 } 00051 00052 /* 00053 * @implemented 00054 */ 00055 ULONG NTAPI 00056 DllInitialize(ULONG Unknown) 00057 { 00058 return 0; 00059 } 00060 00061 /* 00062 * @implemented 00063 */ 00064 ULONG NTAPI 00065 DllUnload(VOID) 00066 { 00067 return 0; 00068 } 00069 00070 /* 00071 * @implemented 00072 */ 00073 PVOID NTAPI 00074 USBD_Debug_GetHeap(ULONG Unknown1, POOL_TYPE PoolType, ULONG NumberOfBytes, 00075 ULONG Tag) 00076 { 00077 return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); 00078 } 00079 00080 /* 00081 * @implemented 00082 */ 00083 VOID NTAPI 00084 USBD_Debug_RetHeap(PVOID Heap, ULONG Unknown2, ULONG Unknown3) 00085 { 00086 ExFreePool(Heap); 00087 } 00088 00089 /* 00090 * @implemented 00091 */ 00092 VOID NTAPI 00093 USBD_Debug_LogEntry(PCHAR Name, ULONG_PTR Info1, ULONG_PTR Info2, 00094 ULONG_PTR Info3) 00095 { 00096 } 00097 00098 /* 00099 * @implemented 00100 */ 00101 PVOID NTAPI 00102 USBD_AllocateDeviceName(ULONG Unknown) 00103 { 00104 UNIMPLEMENTED 00105 return NULL; 00106 } 00107 00108 /* 00109 * @implemented 00110 */ 00111 ULONG NTAPI 00112 USBD_CalculateUsbBandwidth( 00113 ULONG MaxPacketSize, 00114 UCHAR EndpointType, 00115 BOOLEAN LowSpeed 00116 ) 00117 { 00118 ULONG OverheadTable[] = { 00119 0x00, /* UsbdPipeTypeControl */ 00120 0x09, /* UsbdPipeTypeIsochronous */ 00121 0x00, /* UsbdPipeTypeBulk */ 00122 0x0d /* UsbdPipeTypeInterrupt */ 00123 }; 00124 ULONG Result; 00125 00126 if (OverheadTable[EndpointType] != 0) 00127 { 00128 Result = ((MaxPacketSize + OverheadTable[EndpointType]) * 8 * 7) / 6; 00129 if (LowSpeed) 00130 return Result << 3; 00131 return Result; 00132 } 00133 return 0; 00134 } 00135 00136 /* 00137 * @implemented 00138 */ 00139 ULONG NTAPI 00140 USBD_Dispatch(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, ULONG Unknown4) 00141 { 00142 UNIMPLEMENTED 00143 return 1; 00144 } 00145 00146 /* 00147 * @implemented 00148 */ 00149 VOID NTAPI 00150 USBD_FreeDeviceMutex(PVOID Unknown) 00151 { 00152 UNIMPLEMENTED 00153 } 00154 00155 /* 00156 * @implemented 00157 */ 00158 VOID NTAPI 00159 USBD_FreeDeviceName(PVOID Unknown) 00160 { 00161 UNIMPLEMENTED 00162 } 00163 00164 /* 00165 * @implemented 00166 */ 00167 VOID NTAPI 00168 USBD_WaitDeviceMutex(PVOID Unknown) 00169 { 00170 UNIMPLEMENTED 00171 } 00172 00173 /* 00174 * @implemented 00175 */ 00176 ULONG NTAPI 00177 USBD_GetSuspendPowerState(ULONG Unknown1) 00178 { 00179 UNIMPLEMENTED 00180 return 0; 00181 } 00182 00183 /* 00184 * @implemented 00185 */ 00186 NTSTATUS NTAPI 00187 USBD_InitializeDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, 00188 ULONG Unknown4, ULONG Unknown5, ULONG Unknown6) 00189 { 00190 UNIMPLEMENTED 00191 return STATUS_NOT_SUPPORTED; 00192 } 00193 00194 /* 00195 * @implemented 00196 */ 00197 NTSTATUS NTAPI 00198 USBD_RegisterHostController(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, 00199 ULONG Unknown4, ULONG Unknown5, ULONG Unknown6, ULONG Unknown7, 00200 ULONG Unknown8, ULONG Unknown9, ULONG Unknown10) 00201 { 00202 UNIMPLEMENTED 00203 return STATUS_NOT_SUPPORTED; 00204 } 00205 00206 /* 00207 * @implemented 00208 */ 00209 NTSTATUS NTAPI 00210 USBD_GetDeviceInformation(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3) 00211 { 00212 UNIMPLEMENTED 00213 return STATUS_NOT_SUPPORTED; 00214 } 00215 00216 /* 00217 * @implemented 00218 */ 00219 NTSTATUS NTAPI 00220 USBD_CreateDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, 00221 ULONG Unknown4, ULONG Unknown5) 00222 { 00223 UNIMPLEMENTED 00224 return STATUS_NOT_SUPPORTED; 00225 } 00226 00227 /* 00228 * @implemented 00229 */ 00230 NTSTATUS NTAPI 00231 USBD_RemoveDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3) 00232 { 00233 UNIMPLEMENTED 00234 return STATUS_NOT_SUPPORTED; 00235 } 00236 00237 /* 00238 * @implemented 00239 */ 00240 VOID NTAPI 00241 USBD_CompleteRequest(ULONG Unknown1, ULONG Unknown2) 00242 { 00243 UNIMPLEMENTED 00244 } 00245 00246 /* 00247 * @implemented 00248 */ 00249 VOID NTAPI 00250 USBD_RegisterHcFilter( 00251 PDEVICE_OBJECT DeviceObject, 00252 PDEVICE_OBJECT FilterDeviceObject 00253 ) 00254 { 00255 UNIMPLEMENTED 00256 } 00257 00258 /* 00259 * @implemented 00260 */ 00261 VOID NTAPI 00262 USBD_SetSuspendPowerState(ULONG Unknown1, ULONG Unknown2) 00263 { 00264 UNIMPLEMENTED 00265 } 00266 00267 /* 00268 * @implemented 00269 */ 00270 NTSTATUS NTAPI 00271 USBD_MakePdoName(ULONG Unknown1, ULONG Unknown2) 00272 { 00273 UNIMPLEMENTED 00274 return STATUS_NOT_SUPPORTED; 00275 } 00276 00277 /* 00278 * @implemented 00279 */ 00280 NTSTATUS NTAPI 00281 USBD_QueryBusTime( 00282 PDEVICE_OBJECT RootHubPdo, 00283 PULONG CurrentFrame 00284 ) 00285 { 00286 UNIMPLEMENTED 00287 return STATUS_NOT_SUPPORTED; 00288 } 00289 00290 /* 00291 * @implemented 00292 */ 00293 VOID NTAPI 00294 USBD_GetUSBDIVersion( 00295 PUSBD_VERSION_INFORMATION Version 00296 ) 00297 { 00298 if (Version != NULL) 00299 { 00300 Version->USBDI_Version = USBDI_VERSION; 00301 Version->Supported_USB_Version = 0x200; 00302 } 00303 } 00304 00305 /* 00306 * @implemented 00307 */ 00308 NTSTATUS NTAPI 00309 USBD_RestoreDevice(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3) 00310 { 00311 UNIMPLEMENTED 00312 return STATUS_NOT_SUPPORTED; 00313 } 00314 00315 /* 00316 * @implemented 00317 */ 00318 VOID NTAPI 00319 USBD_RegisterHcDeviceCapabilities(ULONG Unknown1, ULONG Unknown2, 00320 ULONG Unknown3) 00321 { 00322 UNIMPLEMENTED 00323 } 00324 00325 /* 00326 * @implemented 00327 */ 00328 PURB NTAPI 00329 USBD_CreateConfigurationRequestEx( 00330 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 00331 PUSBD_INTERFACE_LIST_ENTRY InterfaceList 00332 ) 00333 { 00334 PURB Urb; 00335 ULONG UrbSize = 0; 00336 ULONG InterfaceCount = 0, PipeCount = 0; 00337 ULONG InterfaceNumber, EndPointNumber; 00338 PUSBD_INTERFACE_INFORMATION InterfaceInfo; 00339 00340 while(InterfaceList[InterfaceCount].InterfaceDescriptor) 00341 { 00342 // pipe count 00343 PipeCount += InterfaceList[InterfaceCount].InterfaceDescriptor->bNumEndpoints; 00344 00345 // interface count 00346 InterfaceCount++; 00347 } 00348 00349 // size of urb 00350 UrbSize = GET_SELECT_CONFIGURATION_REQUEST_SIZE(InterfaceCount, PipeCount); 00351 00352 // allocate urb 00353 Urb = ExAllocatePool(NonPagedPool, UrbSize); 00354 if (!Urb) 00355 { 00356 // no memory 00357 return NULL; 00358 } 00359 00360 // zero urb 00361 RtlZeroMemory(Urb, UrbSize); 00362 00363 // init urb header 00364 Urb->UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION; 00365 Urb->UrbSelectConfiguration.Hdr.Length = UrbSize; 00366 Urb->UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor; 00367 00368 // init interface information 00369 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; 00370 for (InterfaceNumber = 0; InterfaceNumber < InterfaceCount; InterfaceNumber++) 00371 { 00372 // init interface info 00373 InterfaceList[InterfaceNumber].Interface = InterfaceInfo; 00374 InterfaceInfo->InterfaceNumber = InterfaceList[InterfaceNumber].InterfaceDescriptor->bInterfaceNumber; 00375 InterfaceInfo->AlternateSetting = InterfaceList[InterfaceNumber].InterfaceDescriptor->bAlternateSetting; 00376 InterfaceInfo->NumberOfPipes = InterfaceList[InterfaceNumber].InterfaceDescriptor->bNumEndpoints; 00377 00378 // store length 00379 InterfaceInfo->Length = GET_USBD_INTERFACE_SIZE(InterfaceList[InterfaceNumber].InterfaceDescriptor->bNumEndpoints); 00380 00381 // sanity check 00382 //C_ASSERT(FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes) == 16); 00383 00384 for (EndPointNumber = 0; EndPointNumber < InterfaceInfo->NumberOfPipes; EndPointNumber++) 00385 { 00386 // init max transfer size 00387 InterfaceInfo->Pipes[EndPointNumber].MaximumTransferSize = PAGE_SIZE; 00388 } 00389 00390 // next interface info 00391 InterfaceInfo = (PUSBD_INTERFACE_INFORMATION) ((ULONG_PTR)InterfaceInfo + InterfaceInfo->Length); 00392 } 00393 00394 return Urb; 00395 } 00396 00397 /* 00398 * @implemented 00399 */ 00400 PURB NTAPI 00401 USBD_CreateConfigurationRequest( 00402 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 00403 PUSHORT Size 00404 ) 00405 { 00406 /* WindowsXP returns NULL */ 00407 return NULL; 00408 } 00409 00410 /* 00411 * @implemented 00412 */ 00413 ULONG NTAPI 00414 USBD_GetInterfaceLength( 00415 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, 00416 PUCHAR BufferEnd 00417 ) 00418 { 00419 ULONG_PTR Current; 00420 PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor = InterfaceDescriptor; 00421 ULONG Length = 0; 00422 BOOLEAN InterfaceFound = FALSE; 00423 00424 for (Current = (ULONG_PTR)CurrentDescriptor; 00425 Current < (ULONG_PTR)BufferEnd; 00426 Current += CurrentDescriptor->bLength) 00427 { 00428 CurrentDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current; 00429 00430 if ((CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) && (InterfaceFound)) 00431 break; 00432 else if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) 00433 InterfaceFound = TRUE; 00434 00435 Length += CurrentDescriptor->bLength; 00436 } 00437 00438 return Length; 00439 } 00440 00441 /* 00442 * @implemented 00443 */ 00444 PUSB_COMMON_DESCRIPTOR NTAPI 00445 USBD_ParseDescriptors( 00446 PVOID DescriptorBuffer, 00447 ULONG TotalLength, 00448 PVOID StartPosition, 00449 LONG DescriptorType 00450 ) 00451 { 00452 PUSB_COMMON_DESCRIPTOR CommonDescriptor; 00453 00454 /* use start position */ 00455 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)StartPosition; 00456 00457 00458 /* find next available descriptor */ 00459 while(CommonDescriptor) 00460 { 00461 if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)DescriptorBuffer + TotalLength)) 00462 { 00463 /* end reached */ 00464 DPRINT("End reached %p\n", CommonDescriptor); 00465 return NULL; 00466 } 00467 00468 DPRINT("CommonDescriptor Type %x Length %x\n", CommonDescriptor->bDescriptorType, CommonDescriptor->bLength); 00469 00470 /* is the requested one */ 00471 if (CommonDescriptor->bDescriptorType == DescriptorType) 00472 { 00473 /* it is */ 00474 return CommonDescriptor; 00475 } 00476 00477 /* sanity check */ 00478 ASSERT(CommonDescriptor->bLength); 00479 00480 /* move to next descriptor */ 00481 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); 00482 } 00483 00484 /* no descriptor found */ 00485 return NULL; 00486 } 00487 00488 00489 /* 00490 * @implemented 00491 */ 00492 PUSB_INTERFACE_DESCRIPTOR NTAPI 00493 USBD_ParseConfigurationDescriptorEx( 00494 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 00495 PVOID StartPosition, 00496 LONG InterfaceNumber, 00497 LONG AlternateSetting, 00498 LONG InterfaceClass, 00499 LONG InterfaceSubClass, 00500 LONG InterfaceProtocol 00501 ) 00502 { 00503 BOOLEAN Found; 00504 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; 00505 00506 /* set to start position */ 00507 InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)StartPosition; 00508 00509 DPRINT("USBD_ParseConfigurationDescriptorEx\n"); 00510 DPRINT("ConfigurationDescriptor %p Length %lu\n", ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength); 00511 DPRINT("CurrentOffset %p Offset %lu\n", StartPosition, ((ULONG_PTR)StartPosition - (ULONG_PTR)ConfigurationDescriptor)); 00512 00513 while(InterfaceDescriptor) 00514 { 00515 /* get interface descriptor */ 00516 InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, InterfaceDescriptor, USB_INTERFACE_DESCRIPTOR_TYPE); 00517 if (!InterfaceDescriptor) 00518 { 00519 /* no more descriptors available */ 00520 break; 00521 } 00522 00523 DPRINT("InterfaceDescriptor %p InterfaceNumber %x AlternateSetting %x Length %lu\n", InterfaceDescriptor, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, InterfaceDescriptor->bLength); 00524 00525 /* set found */ 00526 Found = TRUE; 00527 00528 /* is there an interface number provided */ 00529 if(InterfaceNumber != -1) 00530 { 00531 if(InterfaceNumber != InterfaceDescriptor->bInterfaceNumber) 00532 { 00533 /* interface number does not match */ 00534 Found = FALSE; 00535 } 00536 } 00537 00538 /* is there an alternate setting provided */ 00539 if(AlternateSetting != -1) 00540 { 00541 if(AlternateSetting != InterfaceDescriptor->bAlternateSetting) 00542 { 00543 /* alternate setting does not match */ 00544 Found = FALSE; 00545 } 00546 } 00547 00548 /* match on interface class */ 00549 if(InterfaceClass != -1) 00550 { 00551 if(InterfaceClass != InterfaceDescriptor->bInterfaceClass) 00552 { 00553 /* no match with interface class criteria */ 00554 Found = FALSE; 00555 } 00556 } 00557 00558 /* match on interface sub class */ 00559 if(InterfaceSubClass != -1) 00560 { 00561 if(InterfaceSubClass != InterfaceDescriptor->bInterfaceSubClass) 00562 { 00563 /* no interface sub class match */ 00564 Found = FALSE; 00565 } 00566 } 00567 00568 /* interface protocol criteria */ 00569 if(InterfaceProtocol != -1) 00570 { 00571 if(InterfaceProtocol != InterfaceDescriptor->bInterfaceProtocol) 00572 { 00573 /* no interface protocol match */ 00574 Found = FALSE; 00575 } 00576 } 00577 00578 if (Found) 00579 { 00580 /* the choosen one */ 00581 return InterfaceDescriptor; 00582 } 00583 00584 /* sanity check */ 00585 ASSERT(InterfaceDescriptor->bLength); 00586 00587 /* move to next descriptor */ 00588 InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); 00589 } 00590 00591 DPRINT("No Descriptor With InterfaceNumber %ld AlternateSetting %ld InterfaceClass %ld InterfaceSubClass %ld InterfaceProtocol %ld found\n", InterfaceNumber, 00592 AlternateSetting, InterfaceClass, InterfaceSubClass, InterfaceProtocol); 00593 00594 return NULL; 00595 } 00596 00597 /* 00598 * @implemented 00599 */ 00600 PUSB_INTERFACE_DESCRIPTOR NTAPI 00601 USBD_ParseConfigurationDescriptor( 00602 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, 00603 UCHAR InterfaceNumber, 00604 UCHAR AlternateSetting 00605 ) 00606 { 00607 return USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, 00608 (PVOID)ConfigurationDescriptor, InterfaceNumber, AlternateSetting, 00609 -1, -1, -1); 00610 } 00611 00612 00613 /* 00614 * @implemented 00615 */ 00616 ULONG NTAPI 00617 USBD_GetPdoRegistryParameter( 00618 PDEVICE_OBJECT PhysicalDeviceObject, 00619 PVOID Parameter, 00620 ULONG ParameterLength, 00621 PWCHAR KeyName, 00622 ULONG KeyNameLength 00623 ) 00624 { 00625 NTSTATUS Status; 00626 HANDLE DevInstRegKey; 00627 00628 /* Open the device key */ 00629 Status = IoOpenDeviceRegistryKey(PhysicalDeviceObject, 00630 PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_ALL, &DevInstRegKey); 00631 if (NT_SUCCESS(Status)) 00632 { 00633 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo; 00634 UNICODE_STRING ValueName; 00635 ULONG Length; 00636 00637 /* Initialize the unicode string based on caller data */ 00638 ValueName.Buffer = KeyName; 00639 ValueName.Length = ValueName.MaximumLength = KeyNameLength; 00640 00641 Length = ParameterLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION); 00642 PartialInfo = ExAllocatePool(PagedPool, Length); 00643 if (PartialInfo) 00644 { 00645 Status = ZwQueryValueKey(DevInstRegKey, &ValueName, 00646 KeyValuePartialInformation, PartialInfo, Length, &Length); 00647 if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) 00648 { 00649 /* The caller doesn't want all the data */ 00650 ExFreePool(PartialInfo); 00651 PartialInfo = ExAllocatePool(PagedPool, Length); 00652 if (PartialInfo) 00653 { 00654 Status = ZwQueryValueKey(DevInstRegKey, &ValueName, 00655 KeyValuePartialInformation, PartialInfo, Length, &Length); 00656 } 00657 else 00658 { 00659 Status = STATUS_NO_MEMORY; 00660 } 00661 } 00662 00663 if (NT_SUCCESS(Status)) 00664 { 00665 /* Compute the length to copy back */ 00666 if (ParameterLength < PartialInfo->DataLength) 00667 Length = ParameterLength; 00668 else 00669 Length = PartialInfo->DataLength; 00670 00671 RtlCopyMemory(Parameter, 00672 PartialInfo->Data, 00673 Length); 00674 } 00675 00676 if (PartialInfo) 00677 { 00678 ExFreePool(PartialInfo); 00679 } 00680 } else 00681 Status = STATUS_NO_MEMORY; 00682 ZwClose(DevInstRegKey); 00683 } 00684 return Status; 00685 } Generated on Sun May 27 2012 04:28:30 for ReactOS by
1.7.6.1
|