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

305 lines
9 KiB
C++

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1993-1995
* TITLE: BNDWIDTH.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 "PropPage.h"
#include "itemfind.h"
#include "debug.h"
#include "usbutil.h"
void
UsbBandwidthPopup::AddIsoDevicesToListView(UsbItem *controller,
int iIndent) {
UINT interruptBW;
LVITEM item;
TCHAR buf[MAX_PATH];
UsbItem *usbItem;
ZeroMemory(&item, sizeof(LVITEM));
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE | LVIF_INDENT;
item.iIndent = iIndent;
UsbItemActionFindIsoDevices find;
controller->child->Walk(find);
//
// Put the devices in that use very little bandwidth first so that they
// will be shuffled to the bottom when the high consumption devices are
// added.
//
UsbItemList& isoDevices = find.GetIsoDevices();
for (usbItem = isoDevices.begin() ? *isoDevices.Current() : NULL;
usbItem;
usbItem = isoDevices.next() ? *isoDevices.Current() : NULL) {
item.iImage = usbItem->imageIndex;
item.lParam = (LPARAM) usbItem;
assert(usbItem->configInfo != NULL);
item.pszText = (LPTSTR) usbItem->configInfo->deviceDesc.c_str();
UsbSprintf(buf, TEXT("%d%%"), usbItem->bandwidth);
ListView_InsertItem(hListDevices, &item);
ListView_SetItemText(hListDevices, 0, 1, buf);
}
//
// Add an item indicating that the system always uses 10%
//
item.iItem = 0;
ImageList.GetClassImageIndex(MyComputerClass, &item.iImage);
item.lParam = (LPARAM) controller;
LoadString(gHInst,
IDS_BANDWIDTH_CONTROLLER_RSRVD,
buf,
MAX_PATH);
item.pszText = buf;
ListView_InsertItem(hListDevices, &item);
interruptBW = 10 + UsbItem::CalculateBWPercent(find.InterruptBW());
wsprintf(buf,_T("%d%%"),interruptBW);
ListView_SetItemText(hListDevices, 0, 1, buf);
}
BOOL
UsbBandwidthPopup::Refresh()
{
PUSB_ACQUIRE_INFO acquireInfo = 0;
UsbItem *controller;
LVITEM item;
TCHAR buf[MAX_PATH];
TCHAR formatString[MAX_PATH];
// CWaitCursor wait;
//
// Clear all UI components, and then recreate the rootItem
//
ListView_DeleteAllItems(hListDevices);
if (rootItem) {
DeleteChunk(rootItem);
delete rootItem;
}
rootItem = new UsbItem;
AddChunk(rootItem);
acquireInfo = GetControllerName(WmiHandle,
InstanceName.c_str());
if (!acquireInfo) {
goto BandwidthRefreshError;
}
if (!rootItem->EnumerateAll(&ImageList)) {
goto BandwidthRefreshError;
}
acquireInfo = (PUSB_ACQUIRE_INFO) LocalFree(acquireInfo);
//
// Set the notification using the name of the offending device
//
LoadString(gHInst,
IDS_BANDWIDTH_NOTIFICATION,
formatString,
MAX_PATH);
UsbSprintf(buf,
formatString,
deviceItem.configInfo->deviceDesc.c_str(),
UsbItem::CalculateBWPercent(ConnectionNotification->RequestedBandwidth));
if (!SetTextItem(hWnd, IDC_BANDWIDTH_NOTIFICATION, buf)) {
goto BandwidthRefreshError;
}
ZeroMemory(&item, sizeof(LVITEM));
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
if (rootItem->NumChildren() == 1) {
//
// Computer only has one controller installed
//
if (!SetTextItem(hWnd, IDC_BANDWIDTH_EXPLANATION, IDS_BW_EXPLANATION) ||
!SetTextItem(hWnd, IDC_BANDWIDTH_RECOMMENDATION, IDS_BW_RECOMMENDATION)) {
goto BandwidthRefreshError;
}
AddIsoDevicesToListView(rootItem->child, 0);
} else if (rootItem->NumChildren() > 1) {
//
// Computer has multiple controllers on board. Yeehaw!
//
LoadString(gHInst,
IDS_BANDWIDTH_RECOMMENDATION,
formatString,
MAX_PATH);
UsbSprintf(buf,
formatString,
deviceItem.configInfo->deviceDesc.c_str());
if (!SetTextItem(hWnd, IDC_BANDWIDTH_RECOMMENDATION, buf) ||
!SetTextItem(hWnd, IDC_BANDWIDTH_EXPLANATION, IDS_BW_EXPLANATION)) {
goto BandwidthRefreshError;
}
//
// Change the column text from "Device" to "Controller"
//
LV_COLUMN column;
ZeroMemory(&column, sizeof(LV_COLUMN));
column.mask = LVCF_TEXT;
LoadString(gHInst, IDS_CONTROLLER, buf, MAX_PATH);
column.pszText = buf;
ListView_SetColumn(hListDevices, 0, &column);
//
// Iterate through the controllers and find out how much bandwidth is
// being used on each. Display this in a list view control.
//
for (controller = rootItem->child;
controller != NULL;
controller = controller->sibling) {
AddIsoDevicesToListView(controller, 1);
item.iItem = 0;
item.iImage = controller->imageIndex;
item.lParam = (LPARAM) controller;
item.pszText = (LPTSTR) controller->configInfo->deviceDesc.c_str();
ListView_InsertItem(hListDevices, &item);
}
}
return TRUE;
BandwidthRefreshError:
if (acquireInfo) {
LocalFree(acquireInfo);
}
return FALSE;
}
BOOL
UsbBandwidthPopup::OnInitDialog(HWND HWnd)
{
hWnd = HWnd;
LV_COLUMN column;
RECT rect;
HANDLE hExclamation;
HICON hIcon;
TCHAR buf[MAX_PATH];
//
// Set the Icon to an exclamation mark
//
if (NULL == (hIcon = LoadIcon(NULL, (LPTSTR) IDI_EXCLAMATION)) ||
NULL == (hExclamation = GetDlgItem(hWnd, IDC_ICON_BANDWIDTH))) {
return FALSE;
}
SendMessage((HWND) hExclamation, STM_SETICON, (WPARAM) hIcon, NULL);
hListDevices = GetDlgItem(HWnd, IDC_LIST_CONTROLLERS);
ListView_SetImageList(hListDevices, ImageList.ImageList(), LVSIL_SMALL);
//
// Add columns to the list box
//
ZeroMemory(&column, sizeof(LV_COLUMN));
column.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
column.fmt = LVCFMT_LEFT;
LoadString(gHInst, IDS_DEVICE, buf, MAX_PATH);
column.pszText = buf;
GetClientRect(hListDevices, &rect);
column.cx = (int) (.65*(rect.right - rect.left));
ListView_InsertColumn(hListDevices, 0, &column);
ZeroMemory(&column, sizeof(LV_COLUMN));
column.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
column.fmt = LVCFMT_LEFT;
LoadString(gHInst, IDS_BANDWIDTH_CONSUMED, buf, MAX_PATH);
column.pszText = buf;
GetClientRect(hListDevices, &rect);
column.cx = (int) (.35*(rect.right - rect.left));
ListView_InsertColumn(hListDevices, 1, &column);
return Refresh();
}
BOOL
UsbBandwidthPopup::OnCommand(INT wNotifyCode,
INT wID,
HWND hCtl)
{
switch (wID) {
case IDOK:
EndDialog(hWnd, wID);
return TRUE;
case IDC_BW_REFRESH:
Refresh();
return TRUE;
}
return FALSE;
}
BOOL
UsbBandwidthPopup::IsPopupStillValid() {
USB_BUS_NOTIFICATION busNotification;
USBINFO((_T("Names %s, %s!\n"),
deviceItem.configInfo->deviceDesc.c_str(),
LastDeviceName.c_str()));
if (!GetBusNotification(WmiHandle, &busNotification)) {
USBERROR((_T("Failed to get bus notification!\n")));
return FALSE;
}
//
// Is this the same scenario?
//
if (deviceItem.configInfo->deviceDesc == LastDeviceName &&
busNotification.ConsumedBandwidth == LastBandwidthConsumed &&
ConnectionNotification->RequestedBandwidth == LastBandwidthRequested) {
USBWARN((_T("Same scenario!!!")));
return FALSE;
}
//
// Change the scenario.
//
LastDeviceName = deviceItem.configInfo->deviceDesc;
LastBandwidthConsumed = busNotification.ConsumedBandwidth;
LastBandwidthRequested = ConnectionNotification->RequestedBandwidth;
//
// Is this notification still relevant?
//
USBINFO((_T("Bandwidth consumed %x, requested %x, total %x!\n"),
busNotification.ConsumedBandwidth,
ConnectionNotification->RequestedBandwidth,
busNotification.TotalBandwidth));
if (busNotification.ConsumedBandwidth +
ConnectionNotification->RequestedBandwidth <
busNotification.TotalBandwidth) {
USBWARN((_T("Got BW notification when there was no need!\n")));
return FALSE;
}
return TRUE;
}
UsbString UsbBandwidthPopup::LastDeviceName = _T("");
ULONG UsbBandwidthPopup::LastBandwidthRequested = 0;
ULONG UsbBandwidthPopup::LastBandwidthConsumed = 0;