Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

852 lines
23 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1993-1995
  4. * TITLE: USBITEM.CPP
  5. * VERSION: 1.0
  6. * AUTHOR: jsenior
  7. * DATE: 10/28/1998
  8. *
  9. ********************************************************************************
  10. *
  11. * CHANGE LOG:
  12. *
  13. * DATE REV DESCRIPTION
  14. * ---------- ------- ----------------------------------------------------------
  15. * 10/28/1998 jsenior Original implementation.
  16. *
  17. *******************************************************************************/
  18. #include "UsbItem.h"
  19. #include "resource.h"
  20. // From root\wdm10\usb\hcd\uhcd\bandwdth.c
  21. #define HCD_BW_PER_FRAME ((ULONG)12000) // bits/ms
  22. #define HCD_TOTAL_USB_BW ((ULONG)12000*32)
  23. // From root\wdm10\usb\inc\hcdi.h
  24. #define USB_ISO_OVERHEAD_BYTES 9
  25. #define USB_INTERRUPT_OVERHEAD_BYTES 13
  26. #include "debug.h"
  27. extern HINSTANCE gHInst;
  28. UsbItem::~UsbItem()
  29. {
  30. if (configInfo) {
  31. DeleteChunk(configInfo);
  32. delete configInfo;
  33. }
  34. if (deviceInfo) {
  35. DeleteChunk(deviceInfo);
  36. delete deviceInfo;
  37. }
  38. DeleteChunk(sibling);
  39. delete sibling;
  40. DeleteChunk(child);
  41. delete child;
  42. }
  43. UsbItem *
  44. UsbItem::AddLeaf(UsbItem* Parent,
  45. UsbDeviceInfo* DeviceInfo,
  46. UsbItemType Type,
  47. UsbConfigInfo* ConfigInfo,
  48. UsbImageList *ClassImageList)
  49. {
  50. //
  51. // Fill in the parent's Child field
  52. //
  53. // If it's not null, walk the chain of children of this parent and add
  54. // this node to the end of the chain.
  55. //
  56. if (Parent != 0) {
  57. //
  58. // Create a new USBMGR_TVITEM
  59. //
  60. UsbItem *lastSibling = 0, *item = 0;
  61. item = new UsbItem();
  62. AddChunk(item);
  63. if (0 == item)
  64. {
  65. USBERROR((_T("Out of Memory\n")));
  66. return FALSE;
  67. }
  68. if (Parent->child != 0) {
  69. //
  70. // This parent already has a child. Look for the end of the chain of
  71. // children.
  72. //
  73. lastSibling = Parent->child;
  74. while (0 != lastSibling->sibling) {
  75. lastSibling = lastSibling->sibling;
  76. }
  77. //
  78. // Found the last sibling for this parent
  79. //
  80. lastSibling->sibling = item;
  81. }
  82. else {
  83. //
  84. // No children for this parent yet
  85. //
  86. Parent->child = item;
  87. }
  88. item->parent = Parent;
  89. item->deviceInfo = DeviceInfo;
  90. item->configInfo = ConfigInfo;
  91. item->itemType = Type;
  92. item->GetClassImageIndex(ClassImageList);
  93. return item;
  94. }
  95. else { // This item is the root (no parent)
  96. deviceInfo = DeviceInfo;
  97. configInfo = ConfigInfo;
  98. itemType = Type;
  99. GetClassImageIndex(ClassImageList);
  100. return this;
  101. }
  102. }
  103. void
  104. UsbItem::GetClassImageIndex(UsbImageList *ClassImageList)
  105. {
  106. if (!configInfo ||
  107. !configInfo->deviceClass.size()) {
  108. //
  109. // No device class, so assign the default USB class
  110. //
  111. ClassImageList->GetClassImageIndex(TEXT("USB"), &imageIndex);
  112. } else {
  113. if (_tcsicmp(configInfo->deviceClass.c_str(), USBHID) == 0) {
  114. //
  115. // This device is HID, so find out what its child is for the
  116. // appropriate icon
  117. //
  118. CONFIGRET cr;
  119. DEVINST childDI;
  120. TCHAR buf[MAX_PATH];
  121. ULONG len;
  122. cr = CM_Get_Child(&childDI,
  123. configInfo->devInst,
  124. 0);
  125. USBINFO( (_T("Found HID device: %s, devInst: %x\n"),
  126. configInfo->deviceDesc.c_str(),
  127. configInfo->devInst));
  128. if (cr == CR_SUCCESS) {
  129. len = sizeof(buf);
  130. cr = CM_Get_DevNode_Registry_Property(childDI,
  131. CM_DRP_CLASS,
  132. NULL,
  133. buf,
  134. &len,
  135. 0);
  136. if (cr == CR_SUCCESS) {
  137. configInfo->deviceClass = buf;
  138. USBINFO( (_T("New class: %s\n"), buf));
  139. }
  140. len = sizeof(buf);
  141. cr = CM_Get_DevNode_Registry_Property(childDI,
  142. CM_DRP_DEVICEDESC,
  143. NULL,
  144. buf,
  145. &len,
  146. 0);
  147. if (cr == CR_SUCCESS) {
  148. configInfo->deviceDesc = buf;
  149. USBINFO( (_T("New name: %s\n"), configInfo->deviceDesc.c_str()));
  150. }
  151. }
  152. }
  153. ClassImageList->GetClassImageIndex(configInfo->deviceClass.c_str(),
  154. &imageIndex);
  155. }
  156. }
  157. UINT
  158. UsbItem::EndpointBandwidth(
  159. ULONG MaxPacketSize,
  160. UCHAR EndpointType,
  161. BOOLEAN LowSpeed
  162. )
  163. /*++
  164. Return Value:
  165. banwidth consumed in bits/ms, returns 0 for bulk
  166. and control endpoints
  167. --*/
  168. {
  169. ULONG bw = 0;
  170. //
  171. // control, iso, bulk, interrupt
  172. //
  173. ULONG overhead[4] = {
  174. 0,
  175. USB_ISO_OVERHEAD_BYTES,
  176. 0,
  177. USB_INTERRUPT_OVERHEAD_BYTES
  178. };
  179. // return zero for control or bulk
  180. if (!overhead[EndpointType]) {
  181. return 0;
  182. }
  183. //
  184. // Calculate bandwidth for endpoint. We will use the
  185. // approximation: (overhead bytes plus MaxPacket bytes)
  186. // times 8 bits/byte times worst case bitstuffing overhead.
  187. // This gives bit times, for low speed endpoints we multiply
  188. // by 8 again to convert to full speed bits.
  189. //
  190. //
  191. // Figure out how many bits are required for the transfer.
  192. // (multiply by 7/6 because, in the worst case you might
  193. // have a bit-stuff every six bits requiring 7 bit times to
  194. // transmit 6 bits of data.)
  195. //
  196. // overhead(bytes) * maxpacket(bytes/ms) * 8
  197. // (bits/byte) * bitstuff(7/6) = bits/ms
  198. bw = ((overhead[EndpointType]+MaxPacketSize) * 8 * 7) / 6;
  199. if (LowSpeed) {
  200. bw *= 8;
  201. }
  202. return bw;
  203. }
  204. inline ULONG
  205. UsbItem::CalculateBWPercent(ULONG bw) { return (bw*100) / HCD_BW_PER_FRAME; }
  206. int
  207. UsbItem::CalculateTotalBandwidth(
  208. ULONG NumPipes,
  209. BOOLEAN LowSpeed,
  210. USB_PIPE_INFO *PipeInfo
  211. )
  212. {
  213. ULONG i = 0, bwConsumed, bwTotal = 0;
  214. PUSB_ENDPOINT_DESCRIPTOR epd = 0;
  215. for (i = 0; i < NumPipes; i++) {
  216. epd = &PipeInfo[i].EndpointDescriptor;
  217. //
  218. // We only take into account iso BW. Interrupt bw is accounted for
  219. // in another way.
  220. //
  221. if (USB_ENDPOINT_TYPE_ISOCHRONOUS ==
  222. (epd->bmAttributes & USB_ENDPOINT_TYPE_MASK)) {
  223. bwConsumed = EndpointBandwidth(epd->wMaxPacketSize,
  224. (UCHAR)(epd->bmAttributes & USB_ENDPOINT_TYPE_MASK),
  225. LowSpeed);
  226. bwTotal += bwConsumed;
  227. }
  228. }
  229. bwTotal = CalculateBWPercent(bwTotal);
  230. return bwTotal;
  231. }
  232. BOOL
  233. UsbItem::ComputeBandwidth()
  234. {
  235. bandwidth = 0;
  236. if (deviceInfo && deviceInfo->connectionInfo &&
  237. !deviceInfo->connectionInfo->DeviceIsHub) {
  238. if (deviceInfo->connectionInfo->NumberOfOpenPipes > 0) {
  239. if (0 != (bandwidth = CalculateTotalBandwidth(
  240. deviceInfo->connectionInfo->NumberOfOpenPipes,
  241. deviceInfo->connectionInfo->LowSpeed,
  242. deviceInfo->connectionInfo->PipeList))) {
  243. return TRUE;
  244. }
  245. } else { // Device is not consuming any bandwidth
  246. USBTRACE((_T("%s has no open pipes\n"),
  247. configInfo->deviceDesc.c_str()));
  248. }
  249. }
  250. return FALSE;
  251. }
  252. BOOL
  253. UsbItem::ComputePower()
  254. {
  255. power = 0;
  256. if (IsHub()) {
  257. if (PortPower() == 100) {
  258. //
  259. // Hub that is bus powered requires one unit of power for itself
  260. // plus one unit for each of its ports
  261. //
  262. power = (1 + NumPorts()) > 4 ? 500 : 100 * (1 + NumPorts());
  263. } else {
  264. //
  265. // Self-powered hubs don't require any power from upstream
  266. //
  267. power = 0;
  268. }
  269. return TRUE;
  270. }
  271. if (deviceInfo && deviceInfo->configDesc) {
  272. power = deviceInfo->configDesc->MaxPower*2;
  273. return TRUE;
  274. }
  275. return FALSE;
  276. }
  277. BOOL
  278. UsbItem::IsController()
  279. {
  280. if (itemType == HCD) {
  281. return TRUE;
  282. }
  283. return FALSE;
  284. }
  285. BOOL
  286. UsbItem::IsHub()
  287. {
  288. if (itemType == RootHub || itemType == Hub)
  289. return TRUE;
  290. if (deviceInfo) {
  291. if (deviceInfo->isHub)
  292. return TRUE;
  293. if (deviceInfo->connectionInfo && deviceInfo->connectionInfo->DeviceIsHub)
  294. return TRUE;
  295. }
  296. return FALSE;
  297. }
  298. ULONG UsbItem::UsbVersion()
  299. {
  300. if (deviceInfo) {
  301. if (deviceInfo->connectionInfo) {
  302. return deviceInfo->connectionInfo->DeviceDescriptor.bcdUSB;
  303. #ifdef HUB_CAPS
  304. } else if(hubCaps.HubIs2xCapable) { // Probably the root hub, check hub capabilities
  305. return 0x200;
  306. #endif
  307. }
  308. #if 0
  309. else {
  310. return 0x200;
  311. }
  312. #endif
  313. }
  314. return 0x100;
  315. }
  316. BOOL UsbItem::IsDescriptionValidDevice()
  317. {
  318. if (!IsUnusedPort() &&
  319. configInfo &&
  320. configInfo->deviceDesc.c_str()) {
  321. return TRUE;
  322. }
  323. return FALSE;
  324. }
  325. ULONG UsbItem::NumChildren()
  326. {
  327. UsbItem *item;
  328. ULONG i = 0;
  329. for (item = child; item != NULL; item = item->sibling) {
  330. if (item->IsDescriptionValidDevice()) {
  331. i++;
  332. }
  333. }
  334. return i;
  335. }
  336. ULONG UsbItem::NumPorts()
  337. {
  338. UsbItem *item;
  339. ULONG i = 0;
  340. if (IsHub()) {
  341. for (item = child; item != NULL; item = item->sibling) {
  342. i++;
  343. }
  344. }
  345. return i;
  346. }
  347. ULONG UsbItem::PortPower()
  348. {
  349. if (IsHub()) {
  350. if (deviceInfo->hubInfo.u.HubInformation.HubIsBusPowered)
  351. return 100;
  352. else
  353. return 500;
  354. } else {
  355. return 0;
  356. }
  357. }
  358. BOOL
  359. UsbItem::Walk(UsbItemAction& Action)
  360. {
  361. if (sibling) {
  362. if (!sibling->Walk(Action))
  363. return FALSE;
  364. }
  365. if (child) {
  366. if (!child->Walk(Action))
  367. return FALSE;
  368. }
  369. return Action(this);
  370. }
  371. BOOL
  372. UsbItem::ShallowWalk(UsbItemAction& Action)
  373. {
  374. if (sibling) {
  375. if (!sibling->ShallowWalk(Action))
  376. return FALSE;
  377. }
  378. return Action(this);
  379. }
  380. BOOL
  381. UsbItem::GetDeviceInfo( String &HubName,
  382. ULONG index)
  383. {
  384. HANDLE hHubDevice;
  385. PUSB_NODE_CONNECTION_INFORMATION connectionInfo = 0;
  386. String driverKeyName;
  387. TCHAR buf[MAX_PATH];
  388. //
  389. // Try to open the hub device
  390. //
  391. hHubDevice = GetHandleForDevice(HubName);
  392. if (hHubDevice == INVALID_HANDLE_VALUE) {
  393. goto GetDeviceInfoError;
  394. }
  395. if (!GetPortAttributes(hHubDevice, &cxnAttributes, index)) {
  396. USBERROR( (_T("Couldn't get node connection attributes\n")));
  397. goto GetDeviceInfoError;
  398. }
  399. if (NULL == (connectionInfo = GetConnectionInformation(hHubDevice, index))) {
  400. USBERROR( (_T("Couldn't get node connection information\n")));
  401. goto GetDeviceInfoError;
  402. }
  403. //
  404. // Allocate configuration information structure
  405. //
  406. configInfo = new UsbConfigInfo();
  407. AddChunk(configInfo);
  408. if (configInfo == 0) {
  409. goto GetDeviceInfoError;
  410. }
  411. //
  412. // If there is a device connected, get the Device Description
  413. //
  414. if (connectionInfo->ConnectionStatus != NoDeviceConnected) {
  415. driverKeyName = GetDriverKeyName(hHubDevice,index);
  416. if (!driverKeyName.empty()) {
  417. GetConfigMgrInfo(driverKeyName, configInfo);
  418. }
  419. if (configInfo->deviceDesc.empty()) {
  420. if (connectionInfo->DeviceIsHub) {
  421. if (connectionInfo->DeviceDescriptor.bcdUSB >= 0x200) {
  422. LoadString(gHInst, IDS_UNKNOWN20HUB, buf, MAX_PATH);
  423. } else {
  424. LoadString(gHInst, IDS_UNKNOWNHUB, buf, MAX_PATH);
  425. }
  426. } else {
  427. LoadString(gHInst, IDS_UNKNOWNDEVICE, buf, MAX_PATH);
  428. }
  429. configInfo->deviceDesc = buf;
  430. }
  431. if (configInfo->deviceClass.empty()) {
  432. configInfo->deviceClass = connectionInfo->DeviceIsHub ?
  433. TEXT("USB") : TEXT("Unknown");
  434. }
  435. itemType = connectionInfo->DeviceIsHub ? UsbItem::UsbItemType::Hub :
  436. UsbItem::UsbItemType::Device;
  437. //
  438. // Allocate some space for a USBDEVICEINFO structure to hold the
  439. // info for this device.
  440. //
  441. deviceInfo = new UsbDeviceInfo();
  442. AddChunk(deviceInfo);
  443. if (deviceInfo == 0) {
  444. goto GetDeviceInfoError;
  445. }
  446. if (NULL != (deviceInfo->configDescReq =
  447. GetConfigDescriptor(hHubDevice, index))) {
  448. deviceInfo->configDesc =
  449. (PUSB_CONFIGURATION_DESCRIPTOR)(deviceInfo->configDescReq+1);
  450. }
  451. deviceInfo->connectionInfo = connectionInfo;
  452. }
  453. else {
  454. //
  455. // Empty port. Add "Port n"
  456. //
  457. LocalFree(connectionInfo);
  458. itemType = UsbItem::UsbItemType::Empty;
  459. LoadString(gHInst, IDS_UNUSEDPORT, buf, MAX_PATH);
  460. configInfo->deviceDesc = buf;
  461. UnusedPort = TRUE;
  462. configInfo->deviceClass = TEXT("USB");
  463. }
  464. CloseHandle(hHubDevice);
  465. return TRUE;
  466. GetDeviceInfoError:
  467. //
  468. // Clean up any stuff that got allocated
  469. //
  470. if (hHubDevice != INVALID_HANDLE_VALUE)
  471. {
  472. CloseHandle(hHubDevice);
  473. hHubDevice = INVALID_HANDLE_VALUE;
  474. }
  475. if (deviceInfo) {
  476. DeleteChunk(deviceInfo);
  477. delete deviceInfo;
  478. }
  479. if (connectionInfo)
  480. {
  481. LocalFree(connectionInfo);
  482. }
  483. if (configInfo) {
  484. DeleteChunk(configInfo);
  485. delete configInfo;
  486. }
  487. return FALSE;
  488. }
  489. //
  490. // Recursively inserts items appropriately into a treeview
  491. //
  492. BOOL
  493. UsbItem::InsertTreeItem (HWND hWndTree,
  494. UsbItem *usbItem,
  495. HTREEITEM hParent,
  496. LPTV_INSERTSTRUCT item,
  497. PUsbItemActionIsValid IsValid,
  498. PUsbItemActionIsValid IsBold,
  499. PUsbItemActionIsValid IsExpanded)
  500. {
  501. if (!usbItem || !item) {
  502. return FALSE;
  503. }
  504. if (IsValid(usbItem)) {
  505. HTREEITEM hItem;
  506. ZeroMemory(item, sizeof(TV_INSERTSTRUCT));
  507. // Get the image index
  508. item->hParent = hParent;
  509. item->hInsertAfter = TVI_LAST;
  510. item->item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; // TVIF_CHILDREN
  511. if (IsBold(usbItem)) {
  512. item->itemex.state = TVIS_BOLD;
  513. }
  514. if (IsExpanded(usbItem)) {
  515. item->itemex.state |= TVIS_EXPANDED;
  516. }
  517. item->itemex.stateMask = (UINT)~(TVIS_STATEIMAGEMASK | TVIS_OVERLAYMASK);
  518. item->itemex.pszText = (LPTSTR) usbItem->configInfo->deviceDesc.c_str();
  519. item->itemex.cchTextMax = _tcsclen(usbItem->configInfo->deviceDesc.c_str());
  520. item->itemex.iImage = usbItem->imageIndex;
  521. item->itemex.iSelectedImage = usbItem->imageIndex;
  522. if (usbItem->child) {
  523. item->itemex.cChildren = 1;
  524. }
  525. item->itemex.lParam = (USBLONG_PTR) usbItem;
  526. if (NULL == (hItem = TreeView_InsertItem(hWndTree,
  527. item))) {
  528. int i = GetLastError();
  529. return FALSE;
  530. }
  531. if (usbItem->child) {
  532. if (!InsertTreeItem(hWndTree,
  533. usbItem->child,
  534. hItem,
  535. item,
  536. IsValid,
  537. IsBold,
  538. IsExpanded)) {
  539. return FALSE;
  540. }
  541. }
  542. }
  543. if (usbItem->sibling) {
  544. if (!InsertTreeItem(hWndTree,
  545. usbItem->sibling,
  546. hParent,
  547. item,
  548. IsValid,
  549. IsBold,
  550. IsExpanded)) {
  551. return FALSE;
  552. }
  553. }
  554. return TRUE;
  555. }
  556. BOOL
  557. UsbTreeView_DeleteAllItems(HWND hTreeDevices)
  558. {
  559. HTREEITEM hTreeRoot;
  560. //
  561. // Select the root and delete so as to delete whole tree.
  562. // There is a paint bug in tree view that if you delete all when the
  563. // root isn't selected, then it will paint badly.
  564. //
  565. if (NULL == (hTreeRoot = (HTREEITEM) SendMessage(hTreeDevices,
  566. TVM_GETNEXTITEM,
  567. (WPARAM)TVGN_ROOT,
  568. (LPARAM)NULL))) {
  569. // Nothing to delete; successful
  570. return TRUE;
  571. }
  572. if (!SendMessage(hTreeDevices,
  573. TVM_SELECTITEM,
  574. (WPARAM)TVGN_CARET,
  575. (LPARAM)hTreeRoot)) {
  576. // Can't select the root; YIKES!
  577. return FALSE;
  578. }
  579. //
  580. // deleteAllOk = TreeView_DeleteAllItems(hTreeDevices);
  581. //
  582. return (BOOL) SendMessage(hTreeDevices,
  583. TVM_DELETEITEM,
  584. 0,
  585. (LPARAM)TVI_ROOT);
  586. }
  587. HTREEITEM
  588. TreeView_FindItem(HWND hWndTree,
  589. LPCTSTR text)
  590. {
  591. HTREEITEM hItemPrev, hItemNext;
  592. TCHAR buf[MAX_PATH];
  593. TVITEM tvItem;
  594. tvItem.mask = TVIF_TEXT | TVIF_HANDLE;
  595. tvItem.pszText = buf;
  596. tvItem.cchTextMax = MAX_PATH;
  597. if (NULL == (hItemNext = TreeView_GetRoot(hWndTree))) {
  598. return NULL;
  599. }
  600. hItemPrev = hItemNext;
  601. while (hItemPrev) {
  602. //
  603. // Drill all the way down, checking the nodes along the way.
  604. //
  605. while (hItemNext) {
  606. //
  607. // Check this leaf
  608. //
  609. tvItem.hItem = hItemNext;
  610. if (TreeView_GetItem(hWndTree, &tvItem)) {
  611. if (!_tcscmp(tvItem.pszText, text)) {
  612. return hItemNext;
  613. }
  614. }
  615. //
  616. // Get the next child
  617. //
  618. hItemPrev = hItemNext;
  619. hItemNext = TreeView_GetNextItem(hWndTree,
  620. hItemPrev,
  621. TVGN_CHILD);
  622. }
  623. //
  624. // Find the first sibling on the way back up the tree
  625. //
  626. while (!hItemNext && hItemPrev) {
  627. //
  628. // Get the sibling
  629. //
  630. hItemNext = TreeView_GetNextItem(hWndTree,
  631. hItemPrev,
  632. TVGN_NEXT);
  633. if (!hItemNext) {
  634. //
  635. // Get the parent
  636. //
  637. hItemPrev = TreeView_GetNextItem(hWndTree,
  638. hItemPrev,
  639. TVGN_PARENT);
  640. }
  641. }
  642. }
  643. return NULL;
  644. }
  645. HANDLE
  646. UsbCreateFileA(
  647. IN LPCWSTR lpFileName,
  648. IN DWORD dwDesiredAccess,
  649. IN DWORD dwShareMode,
  650. IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  651. IN DWORD dwCreationDisposition,
  652. IN DWORD dwFlagsAndAttributes,
  653. IN HANDLE hTemplateFile)
  654. {
  655. CHAR usbDeviceName[MAX_PATH];
  656. if (!WideCharToMultiByte(CP_ACP,
  657. WC_NO_BEST_FIT_CHARS,
  658. lpFileName,
  659. -1,
  660. usbDeviceName,
  661. MAX_PATH,
  662. NULL,
  663. NULL)) {
  664. return INVALID_HANDLE_VALUE;
  665. }
  666. return CreateFileA (usbDeviceName,
  667. dwDesiredAccess,
  668. dwShareMode,
  669. lpSecurityAttributes,
  670. dwCreationDisposition,
  671. dwFlagsAndAttributes,
  672. hTemplateFile);
  673. }
  674. //
  675. // Get the index into the ImageList for this device's icon
  676. //
  677. BOOL
  678. UsbImageList::GetClassImageIndex(LPCTSTR DeviceClass,
  679. PINT ImageIndex)
  680. {
  681. #ifndef WINNT
  682. IconItem *iconItem;
  683. BOOL found = FALSE;
  684. int i = 0;
  685. for (iconItem = iconTable.begin();
  686. iconItem;
  687. iconItem = iconTable.next(), i++) {
  688. if (_tcsicmp(DeviceClass, iconItem->szClassName) == 0) {
  689. *ImageIndex = iconItem->imageIndex;
  690. return TRUE;
  691. }
  692. }
  693. #endif // ~WINNT
  694. GUID classGuid;
  695. DWORD listSize;
  696. if(SetupDiClassGuidsFromName(DeviceClass,
  697. &classGuid,
  698. 1,
  699. &listSize)) {
  700. return SetupDiGetClassImageIndex(&ClassImageList, &classGuid, ImageIndex);
  701. }
  702. return FALSE;
  703. }
  704. BOOL
  705. UsbImageList::GetClassImageList()
  706. {
  707. ZeroMemory(&ClassImageList, sizeof(SP_CLASSIMAGELIST_DATA));
  708. ClassImageList.cbSize = sizeof(SP_CLASSIMAGELIST_DATA);
  709. if (!SetupDiGetClassImageList(&ClassImageList)) {
  710. USBERROR((TEXT("Failed to get imagelist, error %x"), GetLastError()));
  711. return FALSE;
  712. }
  713. #ifndef WINNT
  714. HICON hIcon;
  715. IconItem iconItem;
  716. HIMAGELIST imageList = ClassImageList.ImageList;
  717. iconTable.clear();
  718. hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_IMAGE));
  719. iconItem.imageIndex = ImageList_AddIcon(imageList, hIcon);
  720. iconItem.szClassName = TEXT("Image");
  721. iconTable.push_back(iconItem);
  722. hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_MODEM));
  723. iconItem.imageIndex = ImageList_AddIcon(imageList, hIcon);
  724. iconItem.szClassName = TEXT("Modem");
  725. iconTable.push_back(iconItem);
  726. hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_INFRARED));
  727. iconItem.imageIndex = ImageList_AddIcon(imageList, hIcon);
  728. iconItem.szClassName = TEXT("Infrared");
  729. iconTable.push_back(iconItem);
  730. hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_CDROM));
  731. iconItem.imageIndex = ImageList_AddIcon(imageList, hIcon);
  732. iconItem.szClassName = TEXT("CDROM");
  733. iconTable.push_back(iconItem);
  734. hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_FLOPPY));
  735. iconItem.imageIndex = ImageList_AddIcon(imageList, hIcon);
  736. iconItem.szClassName = TEXT("DiskDrive");
  737. iconTable.push_back(iconItem);
  738. hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_MEDIA));
  739. iconItem.imageIndex = ImageList_AddIcon(imageList, hIcon);
  740. iconItem.szClassName = TEXT("MEDIA");
  741. iconTable.push_back(iconItem);
  742. #endif // ~WINNT
  743. return TRUE;
  744. }