Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

304 lines
9.0 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1993-1995
  4. * TITLE: BNDWIDTH.CPP
  5. * VERSION: 1.0
  6. * AUTHOR: jsenior
  7. * DATE: 10/28/1998
  8. *
  9. ********************************************************************************
  10. *
  11. * CHANGE LOG:
  12. *
  13. * DATE REV DESCRIPTION
  14. * ---------- ------- ----------------------------------------------------------
  15. * 10/28/1998 jsenior Original implementation.
  16. *
  17. *******************************************************************************/
  18. #include "UsbPopup.h"
  19. #include "PropPage.h"
  20. #include "itemfind.h"
  21. #include "debug.h"
  22. #include "usbutil.h"
  23. void
  24. UsbBandwidthPopup::AddIsoDevicesToListView(UsbItem *controller,
  25. int iIndent) {
  26. UINT interruptBW;
  27. LVITEM item;
  28. TCHAR buf[MAX_PATH];
  29. UsbItem *usbItem;
  30. ZeroMemory(&item, sizeof(LVITEM));
  31. item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE | LVIF_INDENT;
  32. item.iIndent = iIndent;
  33. UsbItemActionFindIsoDevices find;
  34. controller->child->Walk(find);
  35. //
  36. // Put the devices in that use very little bandwidth first so that they
  37. // will be shuffled to the bottom when the high consumption devices are
  38. // added.
  39. //
  40. UsbItemList& isoDevices = find.GetIsoDevices();
  41. for (usbItem = isoDevices.begin() ? *isoDevices.Current() : NULL;
  42. usbItem;
  43. usbItem = isoDevices.next() ? *isoDevices.Current() : NULL) {
  44. item.iImage = usbItem->imageIndex;
  45. item.lParam = (LPARAM) usbItem;
  46. assert(usbItem->configInfo != NULL);
  47. item.pszText = (LPTSTR) usbItem->configInfo->deviceDesc.c_str();
  48. UsbSprintf(buf, TEXT("%d%%"), usbItem->bandwidth);
  49. ListView_InsertItem(hListDevices, &item);
  50. ListView_SetItemText(hListDevices, 0, 1, buf);
  51. }
  52. //
  53. // Add an item indicating that the system always uses 10%
  54. //
  55. item.iItem = 0;
  56. ImageList.GetClassImageIndex(MyComputerClass, &item.iImage);
  57. item.lParam = (LPARAM) controller;
  58. LoadString(gHInst,
  59. IDS_BANDWIDTH_CONTROLLER_RSRVD,
  60. buf,
  61. MAX_PATH);
  62. item.pszText = buf;
  63. ListView_InsertItem(hListDevices, &item);
  64. interruptBW = 10 + UsbItem::CalculateBWPercent(find.InterruptBW());
  65. wsprintf(buf,_T("%d%%"),interruptBW);
  66. ListView_SetItemText(hListDevices, 0, 1, buf);
  67. }
  68. BOOL
  69. UsbBandwidthPopup::Refresh()
  70. {
  71. PUSB_ACQUIRE_INFO acquireInfo = 0;
  72. UsbItem *controller;
  73. LVITEM item;
  74. TCHAR buf[MAX_PATH];
  75. TCHAR formatString[MAX_PATH];
  76. // CWaitCursor wait;
  77. //
  78. // Clear all UI components, and then recreate the rootItem
  79. //
  80. ListView_DeleteAllItems(hListDevices);
  81. if (rootItem) {
  82. DeleteChunk(rootItem);
  83. delete rootItem;
  84. }
  85. rootItem = new UsbItem;
  86. AddChunk(rootItem);
  87. acquireInfo = GetControllerName(WmiHandle,
  88. InstanceName.c_str());
  89. if (!acquireInfo) {
  90. goto BandwidthRefreshError;
  91. }
  92. if (!rootItem->EnumerateAll(&ImageList)) {
  93. goto BandwidthRefreshError;
  94. }
  95. acquireInfo = (PUSB_ACQUIRE_INFO) LocalFree(acquireInfo);
  96. //
  97. // Set the notification using the name of the offending device
  98. //
  99. LoadString(gHInst,
  100. IDS_BANDWIDTH_NOTIFICATION,
  101. formatString,
  102. MAX_PATH);
  103. UsbSprintf(buf,
  104. formatString,
  105. deviceItem.configInfo->deviceDesc.c_str(),
  106. UsbItem::CalculateBWPercent(ConnectionNotification->RequestedBandwidth));
  107. if (!SetTextItem(hWnd, IDC_BANDWIDTH_NOTIFICATION, buf)) {
  108. goto BandwidthRefreshError;
  109. }
  110. ZeroMemory(&item, sizeof(LVITEM));
  111. item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  112. if (rootItem->NumChildren() == 1) {
  113. //
  114. // Computer only has one controller installed
  115. //
  116. if (!SetTextItem(hWnd, IDC_BANDWIDTH_EXPLANATION, IDS_BW_EXPLANATION) ||
  117. !SetTextItem(hWnd, IDC_BANDWIDTH_RECOMMENDATION, IDS_BW_RECOMMENDATION)) {
  118. goto BandwidthRefreshError;
  119. }
  120. AddIsoDevicesToListView(rootItem->child, 0);
  121. } else if (rootItem->NumChildren() > 1) {
  122. //
  123. // Computer has multiple controllers on board. Yeehaw!
  124. //
  125. LoadString(gHInst,
  126. IDS_BANDWIDTH_RECOMMENDATION,
  127. formatString,
  128. MAX_PATH);
  129. UsbSprintf(buf,
  130. formatString,
  131. deviceItem.configInfo->deviceDesc.c_str());
  132. if (!SetTextItem(hWnd, IDC_BANDWIDTH_RECOMMENDATION, buf) ||
  133. !SetTextItem(hWnd, IDC_BANDWIDTH_EXPLANATION, IDS_BW_EXPLANATION)) {
  134. goto BandwidthRefreshError;
  135. }
  136. //
  137. // Change the column text from "Device" to "Controller"
  138. //
  139. LV_COLUMN column;
  140. ZeroMemory(&column, sizeof(LV_COLUMN));
  141. column.mask = LVCF_TEXT;
  142. LoadString(gHInst, IDS_CONTROLLER, buf, MAX_PATH);
  143. column.pszText = buf;
  144. ListView_SetColumn(hListDevices, 0, &column);
  145. //
  146. // Iterate through the controllers and find out how much bandwidth is
  147. // being used on each. Display this in a list view control.
  148. //
  149. for (controller = rootItem->child;
  150. controller != NULL;
  151. controller = controller->sibling) {
  152. AddIsoDevicesToListView(controller, 1);
  153. item.iItem = 0;
  154. item.iImage = controller->imageIndex;
  155. item.lParam = (LPARAM) controller;
  156. item.pszText = (LPTSTR) controller->configInfo->deviceDesc.c_str();
  157. ListView_InsertItem(hListDevices, &item);
  158. }
  159. }
  160. return TRUE;
  161. BandwidthRefreshError:
  162. if (acquireInfo) {
  163. LocalFree(acquireInfo);
  164. }
  165. return FALSE;
  166. }
  167. BOOL
  168. UsbBandwidthPopup::OnInitDialog(HWND HWnd)
  169. {
  170. hWnd = HWnd;
  171. LV_COLUMN column;
  172. RECT rect;
  173. HANDLE hExclamation;
  174. HICON hIcon;
  175. TCHAR buf[MAX_PATH];
  176. //
  177. // Set the Icon to an exclamation mark
  178. //
  179. if (NULL == (hIcon = LoadIcon(NULL, (LPTSTR) IDI_EXCLAMATION)) ||
  180. NULL == (hExclamation = GetDlgItem(hWnd, IDC_ICON_BANDWIDTH))) {
  181. return FALSE;
  182. }
  183. SendMessage((HWND) hExclamation, STM_SETICON, (WPARAM) hIcon, NULL);
  184. hListDevices = GetDlgItem(HWnd, IDC_LIST_CONTROLLERS);
  185. ListView_SetImageList(hListDevices, ImageList.ImageList(), LVSIL_SMALL);
  186. //
  187. // Add columns to the list box
  188. //
  189. ZeroMemory(&column, sizeof(LV_COLUMN));
  190. column.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  191. column.fmt = LVCFMT_LEFT;
  192. LoadString(gHInst, IDS_DEVICE, buf, MAX_PATH);
  193. column.pszText = buf;
  194. GetClientRect(hListDevices, &rect);
  195. column.cx = (int) (.65*(rect.right - rect.left));
  196. ListView_InsertColumn(hListDevices, 0, &column);
  197. ZeroMemory(&column, sizeof(LV_COLUMN));
  198. column.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  199. column.fmt = LVCFMT_LEFT;
  200. LoadString(gHInst, IDS_BANDWIDTH_CONSUMED, buf, MAX_PATH);
  201. column.pszText = buf;
  202. GetClientRect(hListDevices, &rect);
  203. column.cx = (int) (.35*(rect.right - rect.left));
  204. ListView_InsertColumn(hListDevices, 1, &column);
  205. return Refresh();
  206. }
  207. BOOL
  208. UsbBandwidthPopup::OnCommand(INT wNotifyCode,
  209. INT wID,
  210. HWND hCtl)
  211. {
  212. switch (wID) {
  213. case IDOK:
  214. EndDialog(hWnd, wID);
  215. return TRUE;
  216. case IDC_BW_REFRESH:
  217. Refresh();
  218. return TRUE;
  219. }
  220. return FALSE;
  221. }
  222. BOOL
  223. UsbBandwidthPopup::IsPopupStillValid() {
  224. USB_BUS_NOTIFICATION busNotification;
  225. USBINFO((_T("Names %s, %s!\n"),
  226. deviceItem.configInfo->deviceDesc.c_str(),
  227. LastDeviceName.c_str()));
  228. if (!GetBusNotification(WmiHandle, &busNotification)) {
  229. USBERROR((_T("Failed to get bus notification!\n")));
  230. return FALSE;
  231. }
  232. //
  233. // Is this the same scenario?
  234. //
  235. if (deviceItem.configInfo->deviceDesc == LastDeviceName &&
  236. busNotification.ConsumedBandwidth == LastBandwidthConsumed &&
  237. ConnectionNotification->RequestedBandwidth == LastBandwidthRequested) {
  238. USBWARN((_T("Same scenario!!!")));
  239. return FALSE;
  240. }
  241. //
  242. // Change the scenario.
  243. //
  244. LastDeviceName = deviceItem.configInfo->deviceDesc;
  245. LastBandwidthConsumed = busNotification.ConsumedBandwidth;
  246. LastBandwidthRequested = ConnectionNotification->RequestedBandwidth;
  247. //
  248. // Is this notification still relevant?
  249. //
  250. USBINFO((_T("Bandwidth consumed %x, requested %x, total %x!\n"),
  251. busNotification.ConsumedBandwidth,
  252. ConnectionNotification->RequestedBandwidth,
  253. busNotification.TotalBandwidth));
  254. if (busNotification.ConsumedBandwidth +
  255. ConnectionNotification->RequestedBandwidth <
  256. busNotification.TotalBandwidth) {
  257. USBWARN((_T("Got BW notification when there was no need!\n")));
  258. return FALSE;
  259. }
  260. return TRUE;
  261. }
  262. UsbString UsbBandwidthPopup::LastDeviceName = _T("");
  263. ULONG UsbBandwidthPopup::LastBandwidthRequested = 0;
  264. ULONG UsbBandwidthPopup::LastBandwidthConsumed = 0;