|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 1993-1995 * TITLE: USBPOPUP.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 "debug.h"
#include "usbutil.h"
UINT CALLBACK UsbPopup::StaticDialogCallback(HWND Hwnd, UINT Msg, LPPROPSHEETPAGE Page) { UsbPopup *that;
switch (Msg) { case PSPCB_CREATE: return TRUE; // return TRUE to continue with creation of page
case PSPCB_RELEASE: that = (UsbPopup*) Page->lParam; DeleteChunk(that); delete that;
return 0; // return value ignored
default: break; }
return TRUE; }
USBINT_PTR APIENTRY UsbPopup::StaticDialogProc(IN HWND hDlg, IN UINT uMessage, IN WPARAM wParam, IN LPARAM lParam) { UsbPopup *that;
that = (UsbPopup *) UsbGetWindowLongPtr(hDlg, USBDWLP_USER);
if (!that && uMessage != WM_INITDIALOG) return FALSE; //DefDlgProc(hDlg, uMessage, wParam, lParam);
switch (uMessage) {
case WM_COMMAND: return that->OnCommand(HIWORD(wParam), LOWORD(wParam), (HWND) lParam);
case WM_TIMER: return that->OnTimer(); case WM_INITDIALOG: that = (UsbPopup *) lParam; UsbSetWindowLongPtr(hDlg, USBDWLP_USER, (USBLONG_PTR) that); that->hWnd = hDlg;
return that->OnInitDialog(hDlg);
case WM_NOTIFY: return that->OnNotify(hDlg, (int) wParam, (LPNMHDR) lParam); case WM_DEVICECHANGE: return that->OnDeviceChange(hDlg, wParam, (PDEV_BROADCAST_HDR)lParam);
default: break; }
return that->ActualDialogProc(hDlg, uMessage, wParam, lParam); }
BOOL UsbPopup::OnCommand(INT wNotifyCode, INT wID, HWND hCtl) { switch (wID) { case IDOK: EndDialog(hWnd, wID); return TRUE; } return FALSE; }
BOOL UsbPopup::OnNotify(HWND hDlg, int nID, LPNMHDR pnmh) {
switch (nID) { case IDC_LIST_CONTROLLERS: if (pnmh->code == NM_DBLCLK) { //
// Display properties on this specific device on double click
//
UsbPropertyPage::DisplayPPSelectedListItem(hDlg, hListDevices); } return TRUE; case IDC_TREE_HUBS: if (pnmh->code == NM_DBLCLK) { //
// Display properties on this specific device on double click
//
UsbPropertyPage::DisplayPPSelectedTreeItem(hDlg, hTreeDevices); } return TRUE; }
return 0; }
BOOL UsbPopup::CustomDialog( DWORD DialogBoxId, DWORD IconId, DWORD FormatStringId, DWORD TitleStringId) { HRESULT hr;
//
// Make sure the device hasn't gone away.
//
if (UsbItem::UsbItemType::Empty == deviceItem.itemType) { return FALSE; }
TCHAR buf[MAX_PATH]; TCHAR formatString[MAX_PATH]; LoadString(gHInst, FormatStringId, formatString, MAX_PATH); UsbSprintf(buf, formatString, deviceItem.configInfo->deviceDesc.c_str()); LoadString(gHInst, TitleStringId, formatString, MAX_PATH);
pun->SetBalloonRetry(-1, -1, 0); pun->SetIconInfo(LoadIcon(gHInst, MAKEINTRESOURCE(IDI_USB)), formatString); pun->SetBalloonInfo(formatString, buf, IconId);
//
// Query me every 2 seconds.
//
hr = pun->Show(this, 2000);
pun->Release();
if (S_OK == hr) { if (-1 == DialogBoxParam(gHInst, MAKEINTRESOURCE(DialogBoxId), NULL, StaticDialogProc, (LPARAM) this)) { return FALSE; } } return TRUE; }
STDMETHODIMP_(ULONG) UsbPopup::AddRef() { return InterlockedIncrement(&RefCount); }
STDMETHODIMP_(ULONG) UsbPopup::Release() { assert( 0 != RefCount ); ULONG cRef = InterlockedDecrement(&RefCount); if ( 0 == cRef ) { //
// TODO: gpease 27-FEB-2002
// Figure out why someone commented out this delete. What's the use of having
// the RefCount if it is meaningless?
//
// delete this;
} return cRef; }
HRESULT UsbPopup::QueryInterface(REFIID iid, void **ppv) { if ((iid == IID_IUnknown) || (iid == IID_IQueryContinue)) { *ppv = (void *)(IQueryContinue *)this; } else { *ppv = NULL; // null the out param
return E_NOINTERFACE; }
AddRef(); return S_OK; }
HRESULT UsbPopup::QueryContinue() { USB_NODE_CONNECTION_INFORMATION connectionInfo; ULONG nBytes; HANDLE hHubDevice; String hubName = HubAcquireInfo->Buffer;
//
// Try to open the hub device
//
hHubDevice = GetHandleForDevice(hubName);
if (hHubDevice == INVALID_HANDLE_VALUE) { return S_FALSE; }
//
// Find out if we still have an underpowered device attached .
//
nBytes = sizeof(USB_NODE_CONNECTION_INFORMATION); ZeroMemory(&connectionInfo, nBytes); connectionInfo.ConnectionIndex = ConnectionNotification->ConnectionNumber;
if ( !DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, &connectionInfo, nBytes, &connectionInfo, nBytes, &nBytes, NULL)) { return S_FALSE; }
CloseHandle(hHubDevice);
switch (ConnectionNotification->NotificationType) { case InsufficentBandwidth: return connectionInfo.ConnectionStatus == DeviceNotEnoughBandwidth ? S_OK : S_FALSE; case EnumerationFailure: return connectionInfo.ConnectionStatus == DeviceFailedEnumeration ? S_OK : S_FALSE; case InsufficentPower: return connectionInfo.ConnectionStatus == DeviceNotEnoughPower ? S_OK : S_FALSE; case OverCurrent: return connectionInfo.ConnectionStatus == DeviceCausedOvercurrent ? S_OK : S_FALSE; case ModernDeviceInLegacyHub: return connectionInfo.ConnectionStatus == DeviceConnected ? S_OK : S_FALSE; case HubNestedTooDeeply: return connectionInfo.ConnectionStatus == DeviceHubNestedTooDeeply ? S_OK : S_FALSE; } return S_FALSE; }
void UsbPopup::Make(PUSB_CONNECTION_NOTIFICATION vUsbConnectionNotification, LPTSTR strInstanceName) { ULONG result; HRESULT hr; String hubName;
InstanceName = strInstanceName;
ConnectionNotification = vUsbConnectionNotification;
result = WmiOpenBlock((LPGUID) &GUID_USB_WMI_STD_DATA, 0, &WmiHandle);
if (result != ERROR_SUCCESS) { goto UsbPopupMakeError; }
hWnd = GetDesktopWindow();
InitCommonControls();
//
// Get the hub name and from that, get the name of the device to display in
// the dialog and display it.
// We'll use the port number which the device is attached to. This is:
// ConnectionNotification->ConnectionNumber;
HubAcquireInfo = GetHubName(WmiHandle, strInstanceName, ConnectionNotification); if (!HubAcquireInfo) { goto UsbPopupMakeError; }
hubName = HubAcquireInfo->Buffer;
//
// Make sure that the condition still exists.
//
if (S_FALSE == QueryContinue()) { USBTRACE((_T("Erorr does not exist anymore. Exitting.\n"))); goto UsbPopupMakeError; }
if (!deviceItem.GetDeviceInfo(hubName, ConnectionNotification->ConnectionNumber)) { goto UsbPopupMakeError; }
if (!IsPopupStillValid()) { //
// We already saw the error for this device. Usbhub is being
// repetitive.
//
goto UsbPopupMakeError; }
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (FAILED(hr)) { hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); } if (FAILED(hr)) { goto UsbPopupMakeError; } hr = CoCreateInstance(CLSID_UserNotification, NULL, CLSCTX_ALL, IID_PPV_ARG(IUserNotification, &pun));
if (!FAILED(hr)) { CustomDialogWrap(); }
CoUninitialize();
UsbPopupMakeError: USBTRACE((_T("UsbPopupMakeError\n"))); if (WmiHandle != INVALID_HANDLE_VALUE) { WmiCloseBlock(WmiHandle); } }
BOOL UsbPopup::OnInitDialog(HWND HWnd) { hWnd = HWnd; HANDLE hExclamation; HICON hIcon;
if (RegisterForDeviceReattach) { //
// Try to open the hub device
//
String hubName = HubAcquireInfo->Buffer; HANDLE hHubDevice = GetHandleForDevice(hubName);
if (hHubDevice != INVALID_HANDLE_VALUE) { //
// Register for notification for when the device is re-attached. We want
// to do this before we see the device get detached because we are polling
// and may miss the re-attach if we register when the device is removed.
//
// Allocate configuration information structure and get config mgr info
//
ConfigInfo = new UsbConfigInfo(); AddChunk(ConfigInfo); if (ConfigInfo) { String driverKeyName = GetDriverKeyName(hHubDevice, ConnectionNotification->ConnectionNumber);
if (!driverKeyName.empty()) { GetConfigMgrInfo(driverKeyName, ConfigInfo); // ISSUE: leak, jsenior, 4/19/00
} else { USBWARN((_T("Couldn't get driver key name. Error: (%x)."), GetLastError())); }
CHAR guidBuf[MAX_PATH]; DEV_BROADCAST_DEVICEINTERFACE devInterface; DWORD len = MAX_PATH; if (CM_Get_DevNode_Registry_PropertyA(ConfigInfo->devInst, CM_DRP_CLASSGUID, NULL, guidBuf, &len, 0) == CR_SUCCESS) {
ZeroMemory(&devInterface, sizeof(DEV_BROADCAST_DEVICEINTERFACE)); if (StrToGUID(guidBuf, &devInterface.dbcc_classguid)) { devInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); devInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
hNotifyArrival = RegisterDeviceNotification( HWnd, &devInterface, DEVICE_NOTIFY_WINDOW_HANDLE);
if (!hNotifyArrival){ USBWARN((_T("RegisterDeviceNotification failure (%x)."), GetLastError())); } } else { USBWARN((_T("GUID conversion didn't work."))); } USBWARN((_T("GUID data: %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x"), devInterface.dbcc_classguid.Data1, devInterface.dbcc_classguid.Data2, devInterface.dbcc_classguid.Data3, devInterface.dbcc_classguid.Data4[0], devInterface.dbcc_classguid.Data4[1], devInterface.dbcc_classguid.Data4[2], devInterface.dbcc_classguid.Data4[3], devInterface.dbcc_classguid.Data4[4], devInterface.dbcc_classguid.Data4[5], devInterface.dbcc_classguid.Data4[6], devInterface.dbcc_classguid.Data4[7])); } else { //
// If this fails, we need to default to the old functionality!
// ISSUE: jsenior
//
} } CloseHandle(hHubDevice); } }
//
// Set the Icon to an exclamation mark
//
if (NULL == (hIcon = LoadIcon(NULL, (LPTSTR) IDI_EXCLAMATION)) || NULL == (hExclamation = GetDlgItem(hWnd, IDC_ICON_POWER))) { return FALSE; } SendMessage((HWND) hExclamation, STM_SETICON, (WPARAM) hIcon, NULL);
//
// Get a persistent handle to the tree view control
//
if (NULL == (hTreeDevices = GetDlgItem(HWnd, IDC_TREE_HUBS))) { return FALSE; }
TreeView_SetImageList(hTreeDevices, ImageList.ImageList(), TVSIL_NORMAL);
return Refresh(); }
PUSB_ACQUIRE_INFO UsbPopup::GetHubName(WMIHANDLE WmiHandle, UsbString InstanceName, PUSB_CONNECTION_NOTIFICATION ConnectionNotification) { ULONG res, size; PUSB_ACQUIRE_INFO usbAcquireInfo;
//
// zero all the vars, get the controllers name
//
size = ConnectionNotification->HubNameLength * sizeof(WCHAR) + sizeof(USB_ACQUIRE_INFO); usbAcquireInfo = (PUSB_ACQUIRE_INFO) LocalAlloc(LMEM_ZEROINIT, size); if (!usbAcquireInfo) { USBERROR((_T("Acquire info allocation failed."))); return NULL; } usbAcquireInfo->NotificationType = AcquireHubName; usbAcquireInfo->TotalSize = size;
res = WmiExecuteMethod(WmiHandle, InstanceName.c_str(), AcquireHubName, size, usbAcquireInfo, &size, usbAcquireInfo );
if (res != ERROR_SUCCESS) { usbAcquireInfo = (PUSB_ACQUIRE_INFO) LocalFree(usbAcquireInfo); } return usbAcquireInfo; }
BOOLEAN UsbPopup::GetBusNotification(WMIHANDLE WmiHandle, PUSB_BUS_NOTIFICATION UsbBusNotification) { ULONG res, size;
memset(UsbBusNotification, 0, sizeof(USB_BUS_NOTIFICATION)); UsbBusNotification->NotificationType = AcquireBusInfo; size = sizeof(USB_BUS_NOTIFICATION);
res = WmiExecuteMethod(WmiHandle, InstanceName.c_str(), AcquireBusInfo, size, UsbBusNotification, &size, UsbBusNotification );
if (res != ERROR_SUCCESS) { return FALSE; } return TRUE; }
PUSB_ACQUIRE_INFO UsbPopup::GetControllerName(WMIHANDLE WmiHandle, UsbString InstanceName) { ULONG res, size; USB_BUS_NOTIFICATION usbBusNotification; PUSB_ACQUIRE_INFO usbAcquireInfo;
memset(&usbBusNotification, 0, sizeof(USB_BUS_NOTIFICATION)); usbBusNotification.NotificationType = AcquireBusInfo; size = sizeof(USB_BUS_NOTIFICATION);
res = WmiExecuteMethod(WmiHandle, InstanceName.c_str(), AcquireBusInfo, size, &usbBusNotification, &size, &usbBusNotification );
if (res != ERROR_SUCCESS) { return NULL; }
//
// zero all the vars, get the controllers name
//
size = usbBusNotification.ControllerNameLength * sizeof(WCHAR) + sizeof(USB_ACQUIRE_INFO); usbAcquireInfo = (PUSB_ACQUIRE_INFO) LocalAlloc(LMEM_ZEROINIT, size); usbAcquireInfo->NotificationType = AcquireControllerName; usbAcquireInfo->TotalSize = size;
res = WmiExecuteMethod(WmiHandle, InstanceName.c_str(), AcquireControllerName, size, usbAcquireInfo, &size, usbAcquireInfo );
if (res != ERROR_SUCCESS) { usbAcquireInfo = (PUSB_ACQUIRE_INFO) LocalFree(usbAcquireInfo); } return usbAcquireInfo; }
BOOL UsbPopup::OnDeviceChange(HWND hDlg, WPARAM wParam, PDEV_BROADCAST_HDR devHdr) { PDEV_BROADCAST_DEVICEINTERFACE devInterface = (PDEV_BROADCAST_DEVICEINTERFACE) devHdr; USBTRACE((_T("Device change notification, type %x."), wParam)); switch (wParam) { case DBT_DEVICEARRIVAL: USBTRACE((_T("Device arrival."))); if (devHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { USBTRACE((_T("Device: %s"),devInterface->dbcc_name)); // New device arrival.
// Compare the device description of this puppy to that of the one
// that we have.
//
if (devInterface->dbcc_name == ConfigInfo->deviceDesc && deviceState == DeviceDetachedError) { USBTRACE((_T("Device name match on arrival!"))); //
// The device has been reattached!
//
deviceState = DeviceReattached; Refresh(); } } break; case DBT_DEVICEREMOVECOMPLETE: USBTRACE((_T("Device removal."))); if (devHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { USBTRACE((_T("Device: %s"),devInterface->dbcc_name)); // New device arrival.
// Compare the device description of this puppy to that of the one
// that we have.
//
if (devInterface->dbcc_name == ConfigInfo->deviceDesc && deviceState == DeviceAttachedError) { USBTRACE((_T("Device name match on remove!"))); //
// The device has been reattached!
//
deviceState = DeviceDetachedError; Refresh(); } } break; } return TRUE; }
|