windows-nt/Source/XPSP1/NT/shell/osshell/cpls/usb/nested.cpp
2020-09-26 16:20:57 +08:00

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;
}