PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/libusbK/src/lusbk_stack_collection.c

http://usb-travis.googlecode.com/
C | 576 lines | 438 code | 115 blank | 23 comment | 37 complexity | c0771c9f05ecc40d3c50f711bbfb4d46 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, LGPL-2.0
  1. /*!********************************************************************
  2. libusbK - Multi-driver USB library.
  3. Copyright (C) 2012 Travis Lee Robinson. All Rights Reserved.
  4. libusb-win32.sourceforge.net
  5. Development : Travis Lee Robinson (libusbdotnet@gmail.com)
  6. Testing : Xiaofan Chen (xiaofanc@gmail.com)
  7. At the discretion of the user of this library, this software may be
  8. licensed under the terms of the GNU Public License v3 or a BSD-Style
  9. license as outlined in the following files:
  10. * LICENSE-gpl3.txt
  11. * LICENSE-bsd.txt
  12. License files are located in a license folder at the root of source and
  13. binary distributions.
  14. ********************************************************************!*/
  15. #include "lusbk_private.h"
  16. #include "lusbk_handles.h"
  17. #include "lusbk_stack_collection.h"
  18. // warning C4127: conditional expression is constant.
  19. #pragma warning(disable: 4127)
  20. #ifndef DESCRIPTOR_PARSE_BUILD_STACK___________________________________
  21. typedef struct _DESCRIPTOR_ITERATOR
  22. {
  23. LONG Remaining;
  24. union
  25. {
  26. PUCHAR Offset;
  27. PUSB_COMMON_DESCRIPTOR Comn;
  28. PUSB_INTERFACE_DESCRIPTOR Intf;
  29. PUSB_ENDPOINT_DESCRIPTOR Pipe;
  30. } Ptr;
  31. } DESCRIPTOR_ITERATOR, *PDESCRIPTOR_ITERATOR;
  32. static BOOL u_Desc_Next(PDESCRIPTOR_ITERATOR desc)
  33. {
  34. if (desc->Remaining < sizeof(USB_COMMON_DESCRIPTOR)) return FALSE;
  35. desc->Remaining -= desc->Ptr.Comn->bLength;
  36. if (desc->Remaining >= sizeof(USB_COMMON_DESCRIPTOR))
  37. {
  38. desc->Ptr.Offset += desc->Ptr.Comn->bLength;
  39. return TRUE;
  40. }
  41. return FALSE;
  42. }
  43. static void u_Add_Pipe(PKUSB_ALT_INTERFACE_EL altInterfaceEL, PDESCRIPTOR_ITERATOR desc)
  44. {
  45. PKUSB_PIPE_EL pipeEL;
  46. DESCRIPTOR_ITERATOR descPrev;
  47. memcpy(&descPrev, desc, sizeof(descPrev));
  48. while (u_Desc_Next(desc))
  49. {
  50. if (desc->Ptr.Comn->bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
  51. {
  52. memcpy(desc, &descPrev, sizeof(*desc));
  53. break;
  54. }
  55. else if (desc->Ptr.Comn->bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT)
  56. {
  57. FindPipeEL(altInterfaceEL, pipeEL, FALSE, desc->Ptr.Pipe->bEndpointAddress);
  58. if (!pipeEL)
  59. {
  60. pipeEL = Mem_Alloc(sizeof(*pipeEL));
  61. if (!pipeEL) return;
  62. pipeEL->Descriptor = desc->Ptr.Pipe;
  63. pipeEL->ID = pipeEL->Descriptor->bEndpointAddress;
  64. pipeEL->Index = altInterfaceEL->PipeCount++;
  65. DL_APPEND(altInterfaceEL->PipeList, pipeEL);
  66. }
  67. }
  68. memcpy(&descPrev, desc, sizeof(descPrev));
  69. }
  70. }
  71. static void u_Add_Interface(PKUSB_HANDLE_INTERNAL Handle, PDESCRIPTOR_ITERATOR desc)
  72. {
  73. PKUSB_INTERFACE_EL interfaceEL;
  74. PKUSB_ALT_INTERFACE_EL altInterfaceEL;
  75. FindInterfaceEL(Handle->Device->UsbStack, interfaceEL, FALSE, desc->Ptr.Intf->bInterfaceNumber);
  76. if (!interfaceEL)
  77. {
  78. interfaceEL = Mem_Alloc(sizeof(*interfaceEL));
  79. if (!interfaceEL) return;
  80. interfaceEL->ID = desc->Ptr.Intf->bInterfaceNumber;
  81. interfaceEL->Index = Handle->Device->UsbStack->InterfaceCount++;
  82. interfaceEL->SharedInterface = &Get_SharedInterface(Handle, interfaceEL->Index);
  83. interfaceEL->SharedInterface->ID = interfaceEL->ID;
  84. interfaceEL->SharedInterface->Index = interfaceEL->Index;
  85. DL_APPEND(Handle->Device->UsbStack->InterfaceList, interfaceEL);
  86. }
  87. FindAltInterfaceEL(interfaceEL, altInterfaceEL, FALSE, desc->Ptr.Intf->bAlternateSetting);
  88. if (!altInterfaceEL)
  89. {
  90. altInterfaceEL = Mem_Alloc(sizeof(*altInterfaceEL));
  91. if (!altInterfaceEL) return;
  92. altInterfaceEL->Descriptor = desc->Ptr.Intf;
  93. altInterfaceEL->ID = desc->Ptr.Intf->bAlternateSetting;
  94. altInterfaceEL->Index = interfaceEL->AltInterfaceCount++;
  95. DL_APPEND(interfaceEL->AltInterfaceList, altInterfaceEL);
  96. }
  97. u_Add_Pipe(altInterfaceEL, desc);
  98. }
  99. static BOOL u_Init_Config(__in PKUSB_HANDLE_INTERNAL Handle)
  100. {
  101. DWORD errorCode = ERROR_SUCCESS;
  102. DESCRIPTOR_ITERATOR desc;
  103. PUSB_CONFIGURATION_DESCRIPTOR cfg = Handle->Device->ConfigDescriptor;
  104. Mem_Zero(&desc, sizeof(desc));
  105. desc.Ptr.Offset = (PUCHAR)cfg;
  106. desc.Remaining = (LONG)cfg->wTotalLength;
  107. while(u_Desc_Next(&desc))
  108. {
  109. if (desc.Ptr.Comn->bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
  110. u_Add_Interface(Handle, &desc);
  111. }
  112. return LusbwError(errorCode);
  113. }
  114. #endif
  115. static BOOL u_Init_Handle(__out PKUSB_HANDLE_INTERNAL* Handle,
  116. __in KUSB_DRVID DriverID,
  117. __in_opt PKDEV_HANDLE_INTERNAL SharedDevice,
  118. __in_opt PKUSB_STACK_CB Init_BackendCB,
  119. __in PKOBJ_CB Cleanup_UsbK,
  120. __in PKOBJ_CB Cleanup_DevK)
  121. {
  122. PKUSB_HANDLE_INTERNAL handle = NULL;
  123. UNREFERENCED_PARAMETER(DriverID);
  124. ErrorHandle(!IsHandleValid(Handle), Error, "Handle");
  125. handle = PoolHandle_Acquire_UsbK(Cleanup_UsbK);
  126. ErrorNoSet(!IsHandleValid(handle), Error, "->PoolHandle_Acquire_UsbK");
  127. if (SharedDevice)
  128. {
  129. // this is a cloned/associated handle.
  130. ErrorSet(!PoolHandle_Inc_DevK(SharedDevice), Error, ERROR_RESOURCE_NOT_AVAILABLE, "->PoolHandle_Inc_DevK");
  131. handle->Device = SharedDevice;
  132. handle->IsClone = TRUE;
  133. }
  134. else
  135. {
  136. handle->Device = PoolHandle_Acquire_DevK(Cleanup_DevK);
  137. ErrorNoSet(!IsHandleValid(handle->Device), Error, "->PoolHandle_Acquire_DevK");
  138. if (Init_BackendCB)
  139. {
  140. ErrorNoSet(!Init_BackendCB(handle), Error, "->Init_BackendCB");
  141. }
  142. }
  143. *Handle = handle;
  144. return TRUE;
  145. Error:
  146. if (handle) PoolHandle_Dec_UsbK(handle);
  147. *Handle = NULL;
  148. return FALSE;
  149. }
  150. BOOL UsbStack_Init(
  151. __out KUSB_HANDLE* Handle,
  152. __in_opt KUSB_DRVID DriverID,
  153. __in BOOL UsePipeCache,
  154. __in_opt HANDLE DeviceHandle,
  155. __in_opt KLST_DEVINFO_HANDLE DevInfo,
  156. __in_opt PKDEV_HANDLE_INTERNAL SharedDevice,
  157. __in PKUSB_STACK_CB Init_ConfigCB,
  158. __in_opt PKUSB_STACK_CB Init_BackendCB,
  159. __in PKOBJ_CB Cleanup_UsbK,
  160. __in PKOBJ_CB Cleanup_DevK)
  161. {
  162. BOOL success;
  163. PKUSB_HANDLE_INTERNAL handle = NULL;
  164. const size_t extraMemAlloc = sizeof(KUSB_INTERFACE_STACK) + sizeof(KUSB_DRIVER_API) + ((sizeof(KDEV_SHARED_INTERFACE) * KDEV_SHARED_INTERFACE_COUNT));
  165. PUCHAR extraMem;
  166. success = u_Init_Handle(&handle, DriverID, SharedDevice, Init_BackendCB, Cleanup_UsbK, Cleanup_DevK);
  167. ErrorNoSetAction(!success, return FALSE, "->u_Init_Handle");
  168. // if SharedDevice is non-null this handle is an associated handle
  169. if (!SharedDevice)
  170. {
  171. if (!IsHandleValid(DeviceHandle))
  172. {
  173. DeviceHandle = CreateDeviceFile(DevInfo->DevicePath);
  174. ErrorNoSet(!IsHandleValid(DeviceHandle), Error, "CreateDeviceFile failed.");
  175. DriverID = (KUSB_DRVID)DevInfo->DriverID;
  176. handle->Device->DevicePath = Str_Dupe(DevInfo->DevicePath);
  177. }
  178. handle->Device->MasterDeviceHandle = DeviceHandle;
  179. extraMem = Mem_Alloc(extraMemAlloc);
  180. ErrorMemoryAction(!IsHandleValid(extraMem), return FALSE);
  181. handle->Device->UsbStack = (KUSB_INTERFACE_STACK*)extraMem;
  182. extraMem += sizeof(KUSB_INTERFACE_STACK);
  183. handle->Device->DriverAPI = (KUSB_DRIVER_API*)extraMem;
  184. extraMem += sizeof(KUSB_DRIVER_API);
  185. handle->Device->SharedInterfaces = (KDEV_SHARED_INTERFACE*)extraMem;
  186. extraMem += ((sizeof(KDEV_SHARED_INTERFACE) * KDEV_SHARED_INTERFACE_COUNT));
  187. handle->Device->UsbStack->UsePipeCache = UsePipeCache;
  188. success = Init_ConfigCB(handle);
  189. ErrorNoSet(!success, Error, "->Init_ConfigCB");
  190. handle->Selected_SharedInterface_Index = 0;
  191. success = u_Init_Config(handle);
  192. ErrorNoSet(!success, Error, "->u_Init_Config");
  193. // load a driver API
  194. LibK_LoadDriverAPI(handle->Device->DriverAPI, DriverID);
  195. if (handle->Device->UsbStack->UsePipeCache)
  196. UsbStack_RefreshPipeCache(handle);
  197. }
  198. *Handle = (KUSB_HANDLE)handle;
  199. if (!SharedDevice)
  200. {
  201. PoolHandle_Live_DevK(handle->Device);
  202. PoolHandle_Live_UsbK(handle);
  203. }
  204. return TRUE;
  205. Error:
  206. if (IsHandleValid(handle)) PoolHandle_Dec_UsbK(handle);
  207. *Handle = NULL;
  208. return FALSE;
  209. }
  210. BOOL UsbStack_CloneHandle (
  211. __in KUSB_HANDLE Handle,
  212. __out KUSB_HANDLE* ClonedHandle)
  213. {
  214. PKUSB_HANDLE_INTERNAL handle;
  215. PKUSB_HANDLE_INTERNAL clonedHandle = NULL;
  216. BOOL success;
  217. Pub_To_Priv_UsbK(Handle, handle, return FALSE);
  218. ErrorSetAction(!PoolHandle_Inc_UsbK(handle), ERROR_RESOURCE_NOT_AVAILABLE, return FALSE, "->PoolHandle_Inc_UsbK");
  219. success = UsbStack_Init(
  220. (KUSB_HANDLE*)&clonedHandle,
  221. handle->Device->DriverAPI->Info.DriverID,
  222. handle->Device->UsbStack->UsePipeCache,
  223. NULL,
  224. NULL,
  225. handle->Device,
  226. NULL,
  227. NULL,
  228. handle->Base.Evt.Cleanup,
  229. handle->Device->Base.Evt.Cleanup);
  230. ErrorNoSet(!success, Error, "->UsbStack_Init");
  231. clonedHandle->Selected_SharedInterface_Index = handle->Selected_SharedInterface_Index;
  232. *ClonedHandle = (KUSB_HANDLE)clonedHandle;
  233. PoolHandle_Dec_UsbK(handle);
  234. PoolHandle_Live_UsbK(clonedHandle);
  235. return TRUE;
  236. Error:
  237. if (IsHandleValid(clonedHandle)) PoolHandle_Dec_UsbK(clonedHandle);
  238. PoolHandle_Dec_UsbK(handle);
  239. *ClonedHandle = NULL;
  240. return FALSE;
  241. }
  242. BOOL UsbStack_GetAssociatedInterface (
  243. __in KUSB_HANDLE Handle,
  244. __in UCHAR AssociatedInterfaceIndex,
  245. __out KUSB_HANDLE* AssociatedHandle)
  246. {
  247. PKUSB_HANDLE_INTERNAL handle;
  248. PKUSB_HANDLE_INTERNAL associatedHandle = NULL;
  249. UCHAR nextIndex;
  250. PKUSB_INTERFACE_EL interfaceEL;
  251. BOOL success;
  252. Pub_To_Priv_UsbK(Handle, handle, return FALSE);
  253. ErrorSetAction(!PoolHandle_Inc_UsbK(handle), ERROR_RESOURCE_NOT_AVAILABLE, return FALSE, "->PoolHandle_Inc_UsbK");
  254. nextIndex = ((UCHAR)handle->Selected_SharedInterface_Index) + 1 + AssociatedInterfaceIndex;
  255. FindInterfaceEL(handle->Device->UsbStack, interfaceEL, TRUE, nextIndex);
  256. ErrorSet(!interfaceEL, Error, ERROR_NO_MORE_ITEMS, "Interface index %u not found.", nextIndex);
  257. success = UsbStack_CloneHandle((KUSB_HANDLE)handle, (KUSB_HANDLE*)&associatedHandle);
  258. ErrorNoSet(!success, Error, "->UsbStack_CloneHandle");
  259. associatedHandle->Selected_SharedInterface_Index = nextIndex;
  260. *AssociatedHandle = (KUSB_HANDLE)associatedHandle;
  261. PoolHandle_Dec_UsbK(handle);
  262. PoolHandle_Live_UsbK(associatedHandle);
  263. return TRUE;
  264. Error:
  265. if (IsHandleValid(associatedHandle)) PoolHandle_Dec_UsbK(associatedHandle);
  266. PoolHandle_Dec_UsbK(handle);
  267. *AssociatedHandle = NULL;
  268. return FALSE;
  269. }
  270. VOID UsbStack_Clear(PKUSB_INTERFACE_STACK UsbStack)
  271. {
  272. PKUSB_INTERFACE_EL nextInterfaceEL, t0;
  273. PKUSB_ALT_INTERFACE_EL nextAltInterfaceEL, t1;
  274. PKUSB_PIPE_EL nextPipeEL, t2;
  275. if (!IsHandleValid(UsbStack)) return;
  276. // free the interface list
  277. DL_FOREACH_SAFE(UsbStack->InterfaceList, nextInterfaceEL, t0)
  278. {
  279. // free the stack collection lists
  280. DL_FOREACH_SAFE(nextInterfaceEL->AltInterfaceList, nextAltInterfaceEL, t1)
  281. {
  282. DL_FOREACH_SAFE(nextAltInterfaceEL->PipeList, nextPipeEL, t2)
  283. {
  284. DL_DELETE(nextAltInterfaceEL->PipeList, nextPipeEL);
  285. Mem_Free(&nextPipeEL);
  286. }
  287. DL_DELETE(nextInterfaceEL->AltInterfaceList, nextAltInterfaceEL);
  288. Mem_Free(&nextAltInterfaceEL);
  289. }
  290. DL_DELETE(UsbStack->InterfaceList, nextInterfaceEL);
  291. Mem_Free(&nextInterfaceEL);
  292. }
  293. }
  294. BOOL UsbStack_Rebuild(
  295. __in PKUSB_HANDLE_INTERNAL Handle,
  296. __in PKUSB_STACK_CB Init_ConfigCB)
  297. {
  298. BOOL success;
  299. if (DecLock(ALLK_GETREF_HANDLE(Handle->Device)) != 1)
  300. {
  301. IncLock(ALLK_GETREF_HANDLE(Handle->Device));
  302. return LusbwError(ERROR_RESOURCE_NOT_AVAILABLE);
  303. }
  304. if (DecLock(ALLK_GETREF_HANDLE(Handle->Device)) != 0)
  305. {
  306. IncLock(ALLK_GETREF_HANDLE(Handle->Device));
  307. IncLock(ALLK_GETREF_HANDLE(Handle->Device));
  308. return LusbwError(ERROR_RESOURCE_NOT_AVAILABLE);
  309. }
  310. UsbStack_Clear(Handle->Device->UsbStack);
  311. Mem_Free(&Handle->Device->ConfigDescriptor);
  312. Handle->Selected_SharedInterface_Index = 0;
  313. memset(Handle->Device->SharedInterfaces, 0, sizeof(Handle->Device->SharedInterfaces));
  314. memset(&Handle->Move, 0, sizeof(Handle->Move));
  315. success = Init_ConfigCB(Handle);
  316. ErrorNoSet(!success, Error, "->Init_ConfigCB");
  317. success = u_Init_Config(Handle);
  318. ErrorNoSet(!success, Error, "->u_Init_Config");
  319. IncLock(ALLK_GETREF_HANDLE(Handle->Device));
  320. IncLock(ALLK_GETREF_HANDLE(Handle->Device));
  321. return TRUE;
  322. Error:
  323. IncLock(ALLK_GETREF_HANDLE(Handle->Device));
  324. IncLock(ALLK_GETREF_HANDLE(Handle->Device));
  325. return FALSE;
  326. }
  327. BOOL UsbStack_QueryInterfaceSettings (
  328. __in KUSB_HANDLE Handle,
  329. __in UCHAR AltSettingIndex,
  330. __out PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor)
  331. {
  332. PKUSB_HANDLE_INTERNAL handle;
  333. PKUSB_INTERFACE_EL intfEL;
  334. PKUSB_ALT_INTERFACE_EL altfEL;
  335. ErrorParamAction(!IsHandleValid(UsbAltInterfaceDescriptor), "UsbAltInterfaceDescriptor", return FALSE);
  336. ErrorParamAction(AltSettingIndex > 0x7F, "AltSettingIndex", return FALSE);
  337. Pub_To_Priv_UsbK(Handle, handle, return FALSE);
  338. ErrorSetAction(!PoolHandle_Inc_UsbK(handle), ERROR_RESOURCE_NOT_AVAILABLE, return FALSE, "->PoolHandle_Inc_UsbK");
  339. FindInterfaceEL(handle->Device->UsbStack, intfEL, TRUE, handle->Selected_SharedInterface_Index);
  340. ErrorSet(!intfEL, Error, ERROR_NO_MORE_ITEMS, "Failed locating interface number %u.", handle->Selected_SharedInterface_Index);
  341. FindAltInterfaceEL(intfEL, altfEL, TRUE, AltSettingIndex);
  342. ErrorSet(!altfEL, Error, ERROR_NO_MORE_ITEMS, "AltSettingIndex %u does not exists.", AltSettingIndex);
  343. memcpy(UsbAltInterfaceDescriptor, altfEL->Descriptor, sizeof(*UsbAltInterfaceDescriptor));
  344. PoolHandle_Dec_UsbK(handle);
  345. return TRUE;
  346. Error:
  347. PoolHandle_Dec_UsbK(handle);
  348. return FALSE;
  349. }
  350. BOOL UsbStack_SelectInterface (
  351. __in KUSB_HANDLE Handle,
  352. __in UCHAR IndexOrNumber,
  353. __in BOOL IsIndex)
  354. {
  355. PKUSB_HANDLE_INTERNAL handle;
  356. PKUSB_INTERFACE_EL intfEL;
  357. ErrorParamAction(IndexOrNumber > 0x7F, "IndexOrNumber", return FALSE);
  358. Pub_To_Priv_UsbK(Handle, handle, return FALSE);
  359. ErrorSetAction(!PoolHandle_Inc_UsbK(handle), ERROR_RESOURCE_NOT_AVAILABLE, return FALSE, "->PoolHandle_Inc_UsbK");
  360. FindInterfaceEL(handle->Device->UsbStack, intfEL, IsIndex, IndexOrNumber);
  361. ErrorSet(!intfEL, Error, ERROR_NO_MORE_ITEMS, "Failed locating interface %s %u.", IsIndex ? "index" : "number", IndexOrNumber);
  362. InterlockedExchange(&handle->Selected_SharedInterface_Index, intfEL->Index);
  363. PoolHandle_Dec_UsbK(handle);
  364. return TRUE;
  365. Error:
  366. PoolHandle_Dec_UsbK(handle);
  367. return FALSE;
  368. }
  369. BOOL UsbStack_QuerySelectedEndpoint(
  370. __in KUSB_HANDLE Handle,
  371. __in UCHAR EndpointAddressOrIndex,
  372. __in BOOL IsIndex,
  373. __out PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor)
  374. {
  375. PKUSB_HANDLE_INTERNAL handle;
  376. PKUSB_INTERFACE_EL intfEL;
  377. PKUSB_ALT_INTERFACE_EL altfEL;
  378. PKUSB_PIPE_EL pipeEL;
  379. UCHAR altSetting;
  380. ErrorParamAction(!IsHandleValid(EndpointDescriptor), "EndpointDescriptor", return FALSE);
  381. Pub_To_Priv_UsbK(Handle, handle, return FALSE);
  382. ErrorSetAction(!PoolHandle_Inc_UsbK(handle), ERROR_RESOURCE_NOT_AVAILABLE, return FALSE, "->PoolHandle_Inc_UsbK");
  383. FindInterfaceEL(handle->Device->UsbStack, intfEL, TRUE, handle->Selected_SharedInterface_Index);
  384. ErrorSet(!intfEL, Error, ERROR_NO_MORE_ITEMS, "Failed locating interface number %u.", handle->Selected_SharedInterface_Index);
  385. altSetting = (UCHAR)handle->Device->SharedInterfaces[handle->Selected_SharedInterface_Index].CurrentAltSetting;
  386. FindAltInterfaceEL(intfEL, altfEL, FALSE, altSetting);
  387. ErrorSet(!altfEL, Error, ERROR_NO_MORE_ITEMS, "AltSettingNumber %u does not exists.", altSetting);
  388. FindPipeEL(altfEL, pipeEL, IsIndex, EndpointAddressOrIndex);
  389. ErrorSet(!pipeEL, Error, ERROR_NO_MORE_ITEMS, "Endpoint %s %u does not exists.", IsIndex ? "index" : "address", EndpointAddressOrIndex);
  390. memcpy(EndpointDescriptor, pipeEL->Descriptor, sizeof(*EndpointDescriptor));
  391. PoolHandle_Dec_UsbK(handle);
  392. return TRUE;
  393. Error:
  394. PoolHandle_Dec_UsbK(handle);
  395. return FALSE;
  396. }
  397. BOOL UsbStack_QueryPipe(
  398. __in KUSB_HANDLE Handle,
  399. __in UCHAR AltSettingNumber,
  400. __in UCHAR PipeIndex,
  401. __out PWINUSB_PIPE_INFORMATION PipeInformation)
  402. {
  403. PKUSB_HANDLE_INTERNAL handle;
  404. PKUSB_INTERFACE_EL intfEL;
  405. PKUSB_ALT_INTERFACE_EL altfEL;
  406. PKUSB_PIPE_EL pipeEL;
  407. ErrorParamAction(AltSettingNumber > 0x7F, "AltSettingNumber", return FALSE);
  408. ErrorParamAction(PipeIndex > 0x1F, "PipeIndex", return FALSE);
  409. ErrorParamAction(!IsHandleValid(PipeInformation), "PipeInformation", return FALSE);
  410. Pub_To_Priv_UsbK(Handle, handle, return FALSE);
  411. ErrorSetAction(!PoolHandle_Inc_UsbK(handle), ERROR_RESOURCE_NOT_AVAILABLE, return FALSE, "->PoolHandle_Inc_UsbK");
  412. FindInterfaceEL(handle->Device->UsbStack, intfEL, TRUE, handle->Selected_SharedInterface_Index);
  413. ErrorSet(!intfEL, Error, ERROR_NO_MORE_ITEMS, "Failed locating interface number %u.", handle->Selected_SharedInterface_Index);
  414. FindAltInterfaceEL(intfEL, altfEL, FALSE, AltSettingNumber);
  415. ErrorSet(!altfEL, Error, ERROR_NO_MORE_ITEMS, "AltSettingNumber %u does not exists.", AltSettingNumber);
  416. FindPipeEL(altfEL, pipeEL, TRUE, PipeIndex);
  417. ErrorSet(!pipeEL, Error, ERROR_NO_MORE_ITEMS, "PipeIndex %u does not exists.", PipeIndex);
  418. PipeInformation->PipeType = pipeEL->Descriptor->bmAttributes & 0x03;
  419. PipeInformation->MaximumPacketSize = (pipeEL->Descriptor->wMaxPacketSize & 0x7FF) * (((pipeEL->Descriptor->wMaxPacketSize >> 11) & 0x3) + 1);
  420. PipeInformation->PipeId = pipeEL->Descriptor->bEndpointAddress;
  421. PipeInformation->Interval = pipeEL->Descriptor->bInterval;
  422. PoolHandle_Dec_UsbK(handle);
  423. return TRUE;
  424. Error:
  425. PoolHandle_Dec_UsbK(handle);
  426. return FALSE;
  427. }
  428. BOOL UsbStack_RefreshPipeCache(PKUSB_HANDLE_INTERNAL Handle)
  429. {
  430. PKUSB_INTERFACE_EL intfEL;
  431. PKUSB_ALT_INTERFACE_EL altfEL;
  432. PKUSB_PIPE_EL pipeEL;
  433. PKDEV_SHARED_INTERFACE sharedInterface;
  434. KUSB_PIPE_CACHE* pipeCacheItem;
  435. DL_FOREACH(Handle->Device->UsbStack->InterfaceList, intfEL)
  436. {
  437. sharedInterface = &Get_SharedInterface(Handle, intfEL->Index);
  438. DL_FOREACH(intfEL->AltInterfaceList, altfEL)
  439. {
  440. DL_FOREACH(altfEL->PipeList, pipeEL)
  441. {
  442. pipeCacheItem = &Handle->Device->UsbStack->PipeCache[PIPEID_TO_IDX(pipeEL->ID)];
  443. if (altfEL->ID == sharedInterface->CurrentAltSetting)
  444. {
  445. InterlockedExchangePointer(&pipeCacheItem->InterfaceHandle, sharedInterface->InterfaceHandle);
  446. }
  447. else if (pipeCacheItem->InterfaceHandle == NULL)
  448. {
  449. if (sharedInterface->InterfaceHandle)
  450. InterlockedExchangePointer(&pipeCacheItem->InterfaceHandle, sharedInterface->InterfaceHandle);
  451. else
  452. InterlockedExchangePointer(&pipeCacheItem->InterfaceHandle, Handle->Device->MasterInterfaceHandle);
  453. }
  454. }
  455. }
  456. }
  457. return TRUE;
  458. }