256 lines
8.8 KiB
C++
256 lines
8.8 KiB
C++
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 1993-1995
|
|
* TITLE: POWER.CPP
|
|
* VERSION: 1.0
|
|
* AUTHOR: jsenior
|
|
* DATE: 10/28/1998
|
|
*
|
|
********************************************************************************
|
|
*
|
|
* CHANGE LOG:
|
|
*
|
|
* DATE REV DESCRIPTION
|
|
* ---------- ------- ----------------------------------------------------------
|
|
* 10/28/1998 jsenior Original implementation.
|
|
*
|
|
*******************************************************************************/
|
|
#include "UsbPopup.h"
|
|
#include "itemfind.h"
|
|
#include "debug.h"
|
|
#include "usbutil.h"
|
|
|
|
BOOL
|
|
UsbPowerPopup::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;
|
|
|
|
//
|
|
// Clear all UI components, and then recreate the rootItem
|
|
//
|
|
UsbTreeView_DeleteAllItems(hTreeDevices);
|
|
|
|
if (deviceState == DeviceReattached) {
|
|
//
|
|
// Set the notification using the name of the offending device
|
|
//
|
|
LoadString(gHInst,
|
|
IDS_POWER_SOLVED,
|
|
formatString,
|
|
MAX_PATH);
|
|
LoadString(gHInst,
|
|
IDS_POWER_EXCEEDED,
|
|
buf,
|
|
MAX_PATH);
|
|
MessageBox(hWnd, formatString, buf, MB_OK);
|
|
EndDialog(hWnd, 0);
|
|
return TRUE;
|
|
}
|
|
//
|
|
// Set the notification using the name of the offending device
|
|
//
|
|
LoadString(gHInst,
|
|
IDS_POWER_NOTIFICATION,
|
|
formatString,
|
|
MAX_PATH);
|
|
UsbSprintf(buf, formatString, deviceName);
|
|
if (!SetTextItem(hWnd, IDC_POWER_NOTIFICATION, buf)) {
|
|
goto PowerRefreshError;
|
|
}
|
|
|
|
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 PowerRefreshError;
|
|
}
|
|
AddChunk(rootItem);
|
|
|
|
if (stage == 0) {
|
|
acquireInfo = GetControllerName(WmiHandle,
|
|
InstanceName.c_str());
|
|
if (!acquireInfo) {
|
|
goto PowerRefreshError;
|
|
}
|
|
|
|
if (!rootItem->EnumerateController(0,
|
|
acquireInfo->Buffer,
|
|
&ImageList,
|
|
0)) {
|
|
goto PowerRefreshError;
|
|
}
|
|
//
|
|
// 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 PowerRefreshError;
|
|
}
|
|
if (rootItem->NumChildren() == 1) {
|
|
realItem = rootItem->child;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rootItem->child) {
|
|
//
|
|
// Find all unused ports on self powered hubs
|
|
//
|
|
UsbItemActionFindSelfPoweredHubsWithFreePorts find1(rootItem);
|
|
rootItem->Walk(find1);
|
|
UsbItemList& devices1 = find1.GetHubs();
|
|
if (!devices1.empty()) {
|
|
return AssembleDialog(rootItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_POWER_PORTS,
|
|
IDS_POWER_RECOMMENDATION_PORTS,
|
|
TrueAlways,
|
|
UsbItemActionFindFreePortsOnSelfPoweredHubs::IsValid,
|
|
UsbItemActionFindFreePortsOnSelfPoweredHubs::IsExpanded);
|
|
}
|
|
//
|
|
// Find all self powered hubs that have devices attached requiring less
|
|
// than or equal to 100 mA. These devices can be switched with the
|
|
// offending device.
|
|
//
|
|
UsbItemActionFindLowPoweredDevicesOnSelfPoweredHubs find2(rootItem);
|
|
rootItem->Walk(find2);
|
|
UsbItemList& devices2 = find2.GetDevices();
|
|
if (!devices2.empty()) {
|
|
return AssembleDialog(rootItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_POWER_DEVICE,
|
|
IDS_POWER_RECOMMENDATION_DEVICE,
|
|
TrueAlways,
|
|
UsbItemActionFindLowPoweredDevicesOnSelfPoweredHubs::IsValid,
|
|
UsbItemActionFindLowPoweredDevicesOnSelfPoweredHubs::IsExpanded);
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
//
|
|
// Find all self powered hubs that have devices attached requiring less
|
|
// than or equal to 100 mA. These devices can be switched with the
|
|
// offending device.
|
|
//
|
|
UsbItemActionFindUnknownPoweredDevicesOnSelfPoweredHubs find2(realItem);
|
|
realItem->Walk(find2);
|
|
UsbItemList& devices = find2.GetDevices();
|
|
if (!devices.empty()) {
|
|
return AssembleDialog(realItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_POWER_HIGHDEVICE,
|
|
IDS_POWER_RECHIGHDEVICE,
|
|
TrueAlways,
|
|
UsbItemActionFindUnknownPoweredDevicesOnSelfPoweredHubs::IsValid,
|
|
UsbItemActionFindUnknownPoweredDevicesOnSelfPoweredHubs::IsExpanded);
|
|
}
|
|
}
|
|
//
|
|
// Last resort here. Highlight high-powered devices on self-powered hubs
|
|
// and tell the user to put it there if they want the device to work.
|
|
//
|
|
if (realItem->child) {
|
|
return AssembleDialog(realItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_POWER_HIGHDEVICE,
|
|
IDS_POWER_RECHIGHDEVICE,
|
|
TrueAlways,
|
|
UsbItemActionFindHighPoweredDevicesOnSelfPoweredHubs::IsValid,
|
|
UsbItemActionFindHighPoweredDevicesOnSelfPoweredHubs::IsExpanded);
|
|
}
|
|
return TRUE;
|
|
PowerRefreshError:
|
|
if (acquireInfo) {
|
|
LocalFree(acquireInfo);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
UsbPowerPopup::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_POWER_RECOMMENDATION, buf) ||
|
|
!SetTextItem(hWnd, IDC_POWER_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;
|
|
}
|
|
|
|
USBINT_PTR
|
|
UsbPowerPopup::OnTimer()
|
|
{
|
|
if (deviceState == DeviceAttachedError) {
|
|
if (S_FALSE == QueryContinue()) {
|
|
// Update the device state
|
|
deviceState = DeviceDetachedError;
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|