307 lines
11 KiB
C++
307 lines
11 KiB
C++
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 1993-1995
|
|
* TITLE: LEGACY.CPP
|
|
* VERSION: 1.0
|
|
* AUTHOR: randyau
|
|
* DATE: 9/19/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
|
|
Usb20ControllersOnly (
|
|
UsbItem *Item)
|
|
{
|
|
if (Item->IsController()) {
|
|
if (Item->child &&
|
|
Item->child->UsbVersion() >= 0x200) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
UsbLegacyPopup::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_LEGACY_SOLVED,
|
|
formatString,
|
|
MAX_PATH);
|
|
UsbSprintf(buf, formatString, deviceName);
|
|
LoadString(gHInst,
|
|
IDS_USB2_DEVICE_IN_USB1_HUB,
|
|
formatString,
|
|
MAX_PATH);
|
|
MessageBox(hWnd, buf, formatString, MB_OK);
|
|
EndDialog(hWnd, 0);
|
|
return TRUE;
|
|
}
|
|
//
|
|
// Set the notification using the name of the offending device
|
|
//
|
|
LoadString(gHInst,
|
|
IDS_LEGACY_NOTIFICATION,
|
|
formatString,
|
|
MAX_PATH);
|
|
UsbSprintf(buf, formatString, deviceName);
|
|
if (!SetTextItem(hWnd, IDC_LEGACY_NOTIFICATION, buf)) {
|
|
goto LegacyRefreshError;
|
|
}
|
|
|
|
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 LegacyRefreshError;
|
|
}
|
|
AddChunk(rootItem);
|
|
|
|
if (stage == 0) {
|
|
acquireInfo = GetControllerName(WmiHandle,
|
|
InstanceName.c_str());
|
|
if (!acquireInfo) {
|
|
goto LegacyRefreshError;
|
|
}
|
|
|
|
if (!rootItem->EnumerateController(0,
|
|
acquireInfo->Buffer,
|
|
&ImageList,
|
|
0)) {
|
|
goto LegacyRefreshError;
|
|
}
|
|
//
|
|
// 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 LegacyRefreshError;
|
|
}
|
|
if (rootItem->NumChildren() == 1) {
|
|
realItem = rootItem->child;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rootItem->child) {
|
|
|
|
//
|
|
// Find all usb 2.0 hubs with free ports.
|
|
//
|
|
USBTRACE((_T("Looking for free ports on usb 2.0 hubs\n")));
|
|
UsbItemActionFindUsb2xHubsWithFreePorts find1(rootItem);
|
|
rootItem->Walk(find1);
|
|
UsbItemList& devices1 = find1.GetHubs();
|
|
if (!devices1.empty()) {
|
|
USBTRACE((_T("Found free ports on usb 2.0 hubs\n")));
|
|
return AssembleDialog(rootItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_FREE_USB2_PORTS,
|
|
IDS_FREE_USB2_PORTS_RECOMMENDATION,
|
|
Usb20ControllersOnly,
|
|
UsbItemActionFindUsb2xHubsWithFreePorts::IsValid,
|
|
UsbItemActionFindUsb2xHubsWithFreePorts::IsExpanded);
|
|
}
|
|
|
|
|
|
USBTRACE((_T("Didn't find free ports on usb 2.0 hubs\n")));
|
|
|
|
//
|
|
// Find all usb 2.0 hubs that have usb 1.0 devices attached.
|
|
// These devices can be switched with the offending device.
|
|
//
|
|
USBTRACE((_T("Looking for usb 1.0 devices on usb 2.0 hubs\n")));
|
|
UsbItemActionFindUsb1xDevicesOnUsb2xHubs find2(rootItem);
|
|
rootItem->Walk(find2);
|
|
UsbItemList& devices2 = find2.GetDevices();
|
|
if (!devices2.empty()) {
|
|
USBTRACE((_T("Found usb 1.0 devices on usb 2.0 hubs\n")));
|
|
return AssembleDialog(rootItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_USB1_DEVICE_IN_USB2_HUB,
|
|
IDS_USB1_DEVICE_IN_USB2_HUB_RECOMMENDATION,
|
|
Usb20ControllersOnly,
|
|
UsbItemActionFindUsb1xDevicesOnUsb2xHubs::IsValid,
|
|
UsbItemActionFindUsb1xDevicesOnUsb2xHubs::IsExpanded);
|
|
}
|
|
USBTRACE((_T("Didn't find usb 1.0 devices on usb 2.0 hubs\n")));
|
|
|
|
}
|
|
}
|
|
{
|
|
//
|
|
// Check to see if there are ANY usb 2.0 hubs on the machine
|
|
//
|
|
USBTRACE((_T("Looking for ANY usb 2.0 ports\n")));
|
|
UsbItemActionFindUsb2xHubs find1(realItem);
|
|
realItem->Walk(find1);
|
|
UsbItemList& devices = find1.GetHubs();
|
|
if(devices.empty()) {
|
|
USBTRACE((_T("There aren't any usb 2.0 ports on this machine\n")));
|
|
return AssembleDialog(realItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_NO_USB2_HUBS,
|
|
IDS_NO_USB2_HUBS_RECOMMENDATION,
|
|
TrueAlways,
|
|
UsbItemActionFindUsb2xHubs::IsValid,
|
|
UsbItemActionFindUsb2xHubs::IsExpanded);
|
|
} else {
|
|
//
|
|
// Find all unknown devices attached to usb 2.0 hubs.
|
|
// These devices can be switched with the offending device.
|
|
//
|
|
USBTRACE((_T("Looking for unknown devices attached to usb 2.0 hubs\n")));
|
|
UsbItemActionFindUnknownDevicesOnUsb2xHubs find2(realItem);
|
|
realItem->Walk(find2);
|
|
UsbItemList& devices2 = find2.GetDevices();
|
|
if (!devices2.empty()) {
|
|
USBTRACE((_T("Found unknown devices attached to usb 2.0 hubs\n")));
|
|
return AssembleDialog(realItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_UNKNOWN_DEVICE_IN_USB2_HUB,
|
|
IDS_UNKNOWN_DEVICE_IN_USB2_HUB_RECOMMENDATION,
|
|
Usb20ControllersOnly,
|
|
UsbItemActionFindUnknownDevicesOnUsb2xHubs::IsValid,
|
|
UsbItemActionFindUnknownDevicesOnUsb2xHubs::IsExpanded);
|
|
} else {
|
|
USBTRACE((_T("Didn't find unknown devices on usb 2.0 hubs\n")));
|
|
//
|
|
// Last resort here. Highlight usb 2.0 hubs and tell the user
|
|
// to put it there if they want the device to work.
|
|
//
|
|
USBTRACE((_T("Last resort. Highlight usb 2.0 hubs\n")));
|
|
return AssembleDialog(realItem->child,
|
|
&item,
|
|
deviceName,
|
|
IDS_USB2_DEVICE_IN_USB2_HUB,
|
|
IDS_USB2_DEVICE_IN_USB2_HUB_RECOMMENDATION,
|
|
Usb20ControllersOnly,
|
|
UsbItemActionFindUsb2xHubs::IsValid,
|
|
UsbItemActionFindUsb2xHubs::IsValid);
|
|
}
|
|
}
|
|
}
|
|
USBTRACE((_T("Didn't find usb 2.0 devices on usb 2.0 hubs\n")));
|
|
return TRUE;
|
|
LegacyRefreshError:
|
|
USBTRACE((_T("LegacyRefreshError\n")));
|
|
|
|
if (acquireInfo) {
|
|
LocalFree(acquireInfo);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
UsbLegacyPopup::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_LEGACY_RECOMMENDATION, buf) ||
|
|
!SetTextItem(hWnd, IDC_LEGACY_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
|
|
UsbLegacyPopup::OnTimer()
|
|
{
|
|
|
|
if (deviceState == DeviceAttachedError) {
|
|
if (S_FALSE == QueryContinue()) {
|
|
// Update the device state
|
|
deviceState = DeviceDetachedError;
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|