/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORP., 1993-1995 * TITLE: NESTED.CPP * VERSION: 1.0 * AUTHOR: randyau * DATE: 10/11/2000 * ******************************************************************************** * * CHANGE LOG: * * DATE REV DESCRIPTION * ---------- ------- ---------------------------------------------------------- * 9/19/2000 randyau Original implementation. * *******************************************************************************/ #include "UsbPopup.h" #include "itemfind.h" #include "debug.h" #include "usbutil.h" BOOL UsbNestedHubPopup::Refresh() { TV_INSERTSTRUCT item; int i=0; //, size; String hubName; int stage; TCHAR buf[MAX_PATH]; TCHAR formatString[MAX_PATH]; PUSB_ACQUIRE_INFO acquireInfo = 0; LPCTSTR deviceName = deviceItem.configInfo->deviceDesc.c_str(); UsbItem *realItem; if (deviceState == DeviceReattached) { // // Set the notification using the name of the offending device // LoadString(gHInst, IDS_NESTED_SOLVED, formatString, MAX_PATH); LoadString(gHInst, IDS_HUB_NESTED_TOO_DEEPLY, buf, MAX_PATH); MessageBox(hWnd, formatString, buf, MB_OK); EndDialog(hWnd, 0); return TRUE; } // // Clear all UI components, and then recreate the rootItem // UsbTreeView_DeleteAllItems(hTreeDevices); // // Set the notification using the name of the offending device // LoadString(gHInst, IDS_NESTED_NOTIFICATION, buf, MAX_PATH); if (!SetTextItem(hWnd, IDC_NESTED_NOTIFICATION, buf)) { goto NestedRefreshError; } for (stage=0; stage < 2; stage++) { // // Recreate the rootItem for each enumeration attempt // if (rootItem) { DeleteChunk(rootItem); delete rootItem; } realItem = rootItem = new UsbItem; if (!realItem) { USBERROR((_T("Out of memory!\n"))); goto NestedRefreshError; } AddChunk(rootItem); if (stage == 0) { acquireInfo = GetControllerName(WmiHandle, InstanceName.c_str()); if (!acquireInfo) { goto NestedRefreshError; } if (!rootItem->EnumerateController(0, acquireInfo->Buffer, &ImageList, 0)) { goto NestedRefreshError; } // // Usability: Rename the "Root Hub" to "My Computer" and change the // USB "shovel" icon to a computer icon. // LoadString(gHInst, IDS_MY_COMPUTER, buf, MAX_PATH); rootItem->child->configInfo->deviceDesc = buf; wsprintf(buf, _T(" (%d ports)"), rootItem->child->NumPorts()); rootItem->child->configInfo->deviceDesc += buf; ImageList.GetClassImageIndex(MyComputerClass, &rootItem->child->imageIndex); acquireInfo = (PUSB_ACQUIRE_INFO) LocalFree(acquireInfo); } else { if (!rootItem->EnumerateAll(&ImageList)) { goto NestedRefreshError; } if (rootItem->NumChildren() == 1) { realItem = rootItem->child; break; } } if (rootItem->child) { if (deviceItem.PortPower() > 100) { // Self powered hubs can go anywhere. // // Find all hubs with unused ports. // USBTRACE((_T("Looking for free ports on self powered hubs\n"))); UsbItemActionFindHubsWithFreePorts find1(rootItem); rootItem->Walk(find1); UsbItemList& devices1 = find1.GetHubs(); if (!devices1.empty()) { USBTRACE((_T("Found free ports on self powered hubs\n"))); return AssembleDialog(rootItem->child, &item, deviceName, IDS_FREE_PORTS, IDS_FREE_PORTS_RECOMMENDATION, TrueAlways, UsbItemActionFindHubsWithFreePorts::IsValid, UsbItemActionFindHubsWithFreePorts::IsExpanded); } USBTRACE((_T("Didn't find free ports on self powered hubs\n"))); // // Find all devices on hubs. // These devices can be switched with the // offending device. // UsbItemActionFindDevicesOnHubs find2(rootItem); rootItem->Walk(find2); UsbItemList& devices2 = find2.GetDevices(); if (!devices2.empty()) { return AssembleDialog(rootItem->child, &item, deviceName, IDS_DEVICE_IN_POWERED_HUB, IDS_DEVICE_IN_POWERED_HUB_RECOMMENDATION, TrueAlways, UsbItemActionFindDevicesOnHubs::IsValid, UsbItemActionFindDevicesOnHubs::IsExpanded); } } else { // // Bus powered hubs need a self-powered hub. // Find all unused ports on self powered hubs // USBTRACE((_T("Looking for free ports on self powered hubs\n"))); UsbItemActionFindSelfPoweredHubsWithFreePortsForHub find1(rootItem); rootItem->Walk(find1); UsbItemList& devices1 = find1.GetHubs(); if (!devices1.empty()) { USBTRACE((_T("Found free ports on self powered hubs\n"))); return AssembleDialog(rootItem->child, &item, deviceName, IDS_FREE_POWERED_PORTS, IDS_FREE_PORTS_RECOMMENDATION, TrueAlways, UsbItemActionFindSelfPoweredHubsWithFreePorts::IsValid, UsbItemActionFindSelfPoweredHubsWithFreePorts::IsExpanded); } USBTRACE((_T("Didn't find free ports on self powered hubs\n"))); // // Find all devices on self powered hubs. // These devices can be switched with the // offending device. // UsbItemActionFindDevicesOnSelfPoweredHubs find2(rootItem); rootItem->Walk(find2); UsbItemList& devices2 = find2.GetDevices(); if (!devices2.empty()) { return AssembleDialog(rootItem->child, &item, deviceName, IDS_DEVICE_IN_POWERED_HUB, IDS_DEVICE_IN_POWERED_HUB_RECOMMENDATION, TrueAlways, UsbItemActionFindDevicesOnSelfPoweredHubs::IsValid, UsbItemActionFindDevicesOnSelfPoweredHubs::IsExpanded); } } } } // Shouldn't get here. assert(FALSE); return TRUE; NestedRefreshError: USBTRACE((_T("NestedRefreshError\n"))); if (acquireInfo) { LocalFree(acquireInfo); } return FALSE; } BOOL UsbNestedHubPopup::AssembleDialog(UsbItem* RootItem, LPTV_INSERTSTRUCT LvItem, LPCTSTR DeviceName, UINT Explanation, UINT Recommendation, PUsbItemActionIsValid IsValid, PUsbItemActionIsValid IsBold, PUsbItemActionIsValid IsExpanded) { HTREEITEM hDevice; TCHAR buf[MAX_PATH], formatString[MAX_PATH]; LoadString(gHInst, Recommendation, formatString, MAX_PATH); UsbSprintf(buf, formatString, DeviceName); if (!SetTextItem(hWnd, IDC_NESTED_RECOMMENDATION, buf) || !SetTextItem(hWnd, IDC_NESTED_EXPLANATION, Explanation)) { return FALSE; } if (!InsertTreeItem(hTreeDevices, RootItem, NULL, LvItem, IsValid, IsBold, IsExpanded)) { return FALSE; } if (NULL != (hDevice = TreeView_FindItem(hTreeDevices, DeviceName))) { return TreeView_SelectItem (hTreeDevices, hDevice); } return TRUE; }