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.

262 lines
9.5 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1993-1995
  4. * TITLE: NESTED.CPP
  5. * VERSION: 1.0
  6. * AUTHOR: randyau
  7. * DATE: 10/11/2000
  8. *
  9. ********************************************************************************
  10. *
  11. * CHANGE LOG:
  12. *
  13. * DATE REV DESCRIPTION
  14. * ---------- ------- ----------------------------------------------------------
  15. * 9/19/2000 randyau Original implementation.
  16. *
  17. *******************************************************************************/
  18. #include "UsbPopup.h"
  19. #include "itemfind.h"
  20. #include "debug.h"
  21. #include "usbutil.h"
  22. BOOL
  23. UsbNestedHubPopup::Refresh()
  24. {
  25. TV_INSERTSTRUCT item;
  26. int i=0; //, size;
  27. String hubName;
  28. int stage;
  29. TCHAR buf[MAX_PATH];
  30. TCHAR formatString[MAX_PATH];
  31. PUSB_ACQUIRE_INFO acquireInfo = 0;
  32. LPCTSTR deviceName = deviceItem.configInfo->deviceDesc.c_str();
  33. UsbItem *realItem;
  34. if (deviceState == DeviceReattached) {
  35. //
  36. // Set the notification using the name of the offending device
  37. //
  38. LoadString(gHInst,
  39. IDS_NESTED_SOLVED,
  40. formatString,
  41. MAX_PATH);
  42. LoadString(gHInst,
  43. IDS_HUB_NESTED_TOO_DEEPLY,
  44. buf,
  45. MAX_PATH);
  46. MessageBox(hWnd, formatString, buf, MB_OK);
  47. EndDialog(hWnd, 0);
  48. return TRUE;
  49. }
  50. //
  51. // Clear all UI components, and then recreate the rootItem
  52. //
  53. UsbTreeView_DeleteAllItems(hTreeDevices);
  54. //
  55. // Set the notification using the name of the offending device
  56. //
  57. LoadString(gHInst,
  58. IDS_NESTED_NOTIFICATION,
  59. buf,
  60. MAX_PATH);
  61. if (!SetTextItem(hWnd, IDC_NESTED_NOTIFICATION, buf)) {
  62. goto NestedRefreshError;
  63. }
  64. for (stage=0; stage < 2; stage++) {
  65. //
  66. // Recreate the rootItem for each enumeration attempt
  67. //
  68. if (rootItem) {
  69. DeleteChunk(rootItem);
  70. delete rootItem;
  71. }
  72. realItem = rootItem = new UsbItem;
  73. if (!realItem) {
  74. USBERROR((_T("Out of memory!\n")));
  75. goto NestedRefreshError;
  76. }
  77. AddChunk(rootItem);
  78. if (stage == 0) {
  79. acquireInfo = GetControllerName(WmiHandle,
  80. InstanceName.c_str());
  81. if (!acquireInfo) {
  82. goto NestedRefreshError;
  83. }
  84. if (!rootItem->EnumerateController(0,
  85. acquireInfo->Buffer,
  86. &ImageList,
  87. 0)) {
  88. goto NestedRefreshError;
  89. }
  90. //
  91. // Usability: Rename the "Root Hub" to "My Computer" and change the
  92. // USB "shovel" icon to a computer icon.
  93. //
  94. LoadString(gHInst,
  95. IDS_MY_COMPUTER,
  96. buf,
  97. MAX_PATH);
  98. rootItem->child->configInfo->deviceDesc = buf;
  99. wsprintf(buf, _T(" (%d ports)"), rootItem->child->NumPorts());
  100. rootItem->child->configInfo->deviceDesc += buf;
  101. ImageList.GetClassImageIndex(MyComputerClass,
  102. &rootItem->child->imageIndex);
  103. acquireInfo = (PUSB_ACQUIRE_INFO) LocalFree(acquireInfo);
  104. } else {
  105. if (!rootItem->EnumerateAll(&ImageList)) {
  106. goto NestedRefreshError;
  107. }
  108. if (rootItem->NumChildren() == 1) {
  109. realItem = rootItem->child;
  110. break;
  111. }
  112. }
  113. if (rootItem->child) {
  114. if (deviceItem.PortPower() > 100) {
  115. // Self powered hubs can go anywhere.
  116. //
  117. // Find all hubs with unused ports.
  118. //
  119. USBTRACE((_T("Looking for free ports on self powered hubs\n")));
  120. UsbItemActionFindHubsWithFreePorts find1(rootItem);
  121. rootItem->Walk(find1);
  122. UsbItemList& devices1 = find1.GetHubs();
  123. if (!devices1.empty()) {
  124. USBTRACE((_T("Found free ports on self powered hubs\n")));
  125. return AssembleDialog(rootItem->child,
  126. &item,
  127. deviceName,
  128. IDS_FREE_PORTS,
  129. IDS_FREE_PORTS_RECOMMENDATION,
  130. TrueAlways,
  131. UsbItemActionFindHubsWithFreePorts::IsValid,
  132. UsbItemActionFindHubsWithFreePorts::IsExpanded);
  133. }
  134. USBTRACE((_T("Didn't find free ports on self powered hubs\n")));
  135. //
  136. // Find all devices on hubs.
  137. // These devices can be switched with the
  138. // offending device.
  139. //
  140. UsbItemActionFindDevicesOnHubs find2(rootItem);
  141. rootItem->Walk(find2);
  142. UsbItemList& devices2 = find2.GetDevices();
  143. if (!devices2.empty()) {
  144. return AssembleDialog(rootItem->child,
  145. &item,
  146. deviceName,
  147. IDS_DEVICE_IN_POWERED_HUB,
  148. IDS_DEVICE_IN_POWERED_HUB_RECOMMENDATION,
  149. TrueAlways,
  150. UsbItemActionFindDevicesOnHubs::IsValid,
  151. UsbItemActionFindDevicesOnHubs::IsExpanded);
  152. }
  153. } else { //
  154. // Bus powered hubs need a self-powered hub.
  155. // Find all unused ports on self powered hubs
  156. //
  157. USBTRACE((_T("Looking for free ports on self powered hubs\n")));
  158. UsbItemActionFindSelfPoweredHubsWithFreePortsForHub find1(rootItem);
  159. rootItem->Walk(find1);
  160. UsbItemList& devices1 = find1.GetHubs();
  161. if (!devices1.empty()) {
  162. USBTRACE((_T("Found free ports on self powered hubs\n")));
  163. return AssembleDialog(rootItem->child,
  164. &item,
  165. deviceName,
  166. IDS_FREE_POWERED_PORTS,
  167. IDS_FREE_PORTS_RECOMMENDATION,
  168. TrueAlways,
  169. UsbItemActionFindSelfPoweredHubsWithFreePorts::IsValid,
  170. UsbItemActionFindSelfPoweredHubsWithFreePorts::IsExpanded);
  171. }
  172. USBTRACE((_T("Didn't find free ports on self powered hubs\n")));
  173. //
  174. // Find all devices on self powered hubs.
  175. // These devices can be switched with the
  176. // offending device.
  177. //
  178. UsbItemActionFindDevicesOnSelfPoweredHubs find2(rootItem);
  179. rootItem->Walk(find2);
  180. UsbItemList& devices2 = find2.GetDevices();
  181. if (!devices2.empty()) {
  182. return AssembleDialog(rootItem->child,
  183. &item,
  184. deviceName,
  185. IDS_DEVICE_IN_POWERED_HUB,
  186. IDS_DEVICE_IN_POWERED_HUB_RECOMMENDATION,
  187. TrueAlways,
  188. UsbItemActionFindDevicesOnSelfPoweredHubs::IsValid,
  189. UsbItemActionFindDevicesOnSelfPoweredHubs::IsExpanded);
  190. }
  191. }
  192. }
  193. }
  194. // Shouldn't get here.
  195. assert(FALSE);
  196. return TRUE;
  197. NestedRefreshError:
  198. USBTRACE((_T("NestedRefreshError\n")));
  199. if (acquireInfo) {
  200. LocalFree(acquireInfo);
  201. }
  202. return FALSE;
  203. }
  204. BOOL
  205. UsbNestedHubPopup::AssembleDialog(UsbItem* RootItem,
  206. LPTV_INSERTSTRUCT LvItem,
  207. LPCTSTR DeviceName,
  208. UINT Explanation,
  209. UINT Recommendation,
  210. PUsbItemActionIsValid IsValid,
  211. PUsbItemActionIsValid IsBold,
  212. PUsbItemActionIsValid IsExpanded)
  213. {
  214. HTREEITEM hDevice;
  215. TCHAR buf[MAX_PATH], formatString[MAX_PATH];
  216. LoadString(gHInst,
  217. Recommendation,
  218. formatString,
  219. MAX_PATH);
  220. UsbSprintf(buf, formatString, DeviceName);
  221. if (!SetTextItem(hWnd, IDC_NESTED_RECOMMENDATION, buf) ||
  222. !SetTextItem(hWnd, IDC_NESTED_EXPLANATION, Explanation)) {
  223. return FALSE;
  224. }
  225. if (!InsertTreeItem(hTreeDevices,
  226. RootItem,
  227. NULL,
  228. LvItem,
  229. IsValid,
  230. IsBold,
  231. IsExpanded)) {
  232. return FALSE;
  233. }
  234. if (NULL != (hDevice = TreeView_FindItem(hTreeDevices,
  235. DeviceName))) {
  236. return TreeView_SelectItem (hTreeDevices, hDevice);
  237. }
  238. return TRUE;
  239. }