263 lines
9.5 KiB
C++
263 lines
9.5 KiB
C++
/*******************************************************************************
|
|
*
|
|
* (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;
|
|
}
|
|
|