Leaked source code of windows server 2003
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.

263 lines
6.4 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation
  3. Module Name:
  4. devrmdlg.cpp
  5. Abstract:
  6. This module implements CRemoveDevDlg -- device removing dialog box
  7. Author:
  8. William Hsieh (williamh) created
  9. Revision History:
  10. --*/
  11. #include "devmgr.h"
  12. #include "hwprof.h"
  13. #include "devrmdlg.h"
  14. //
  15. // help topic ids
  16. //
  17. const DWORD g_a210HelpIDs[]=
  18. {
  19. IDC_REMOVEDEV_ICON, IDH_DISABLEHELP, // Confirm Device Removal: "" (Static)
  20. IDC_REMOVEDEV_DEVDESC, IDH_DISABLEHELP, // Confirm Device Removal: "" (Static)
  21. IDC_REMOVEDEV_WARNING, IDH_DISABLEHELP, // Confirm Device Removal: "" (Static)
  22. 0, 0
  23. };
  24. //
  25. // CRemoveDevDlg implementation
  26. //
  27. BOOL CRemoveDevDlg::OnInitDialog()
  28. {
  29. SetDlgItemText(m_hDlg, IDC_REMOVEDEV_DEVDESC, m_pDevice->GetDisplayName());
  30. HICON hIconOld;
  31. hIconOld = (HICON)SendDlgItemMessage(m_hDlg, IDC_REMOVEDEV_ICON,
  32. STM_SETICON,
  33. (WPARAM)(m_pDevice->LoadClassIcon()),
  34. 0
  35. );
  36. if (hIconOld)
  37. DestroyIcon(hIconOld);
  38. try
  39. {
  40. String str;
  41. str.LoadString(g_hInstance, IDS_REMOVEDEV_WARN);
  42. SetDlgItemText(m_hDlg, IDC_REMOVEDEV_WARNING, str);
  43. }
  44. catch (CMemoryException* e)
  45. {
  46. e->Delete();
  47. return FALSE;
  48. }
  49. return TRUE;
  50. }
  51. void
  52. CRemoveDevDlg::OnCommand(
  53. WPARAM wParam,
  54. LPARAM lParam
  55. )
  56. {
  57. UNREFERENCED_PARAMETER(lParam);
  58. if (BN_CLICKED == HIWORD(wParam))
  59. {
  60. if (IDOK == LOWORD(wParam))
  61. {
  62. OnOk();
  63. }
  64. else if (IDCANCEL == LOWORD(wParam))
  65. {
  66. EndDialog(m_hDlg, IDCANCEL);
  67. }
  68. }
  69. }
  70. void CRemoveDevDlg::OnOk()
  71. {
  72. SP_REMOVEDEVICE_PARAMS rmdParams;
  73. rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  74. rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
  75. HCURSOR hCursorOld;
  76. hCursorOld = SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)));
  77. //
  78. // Uninstall does not apply to specific profiles -- it is global.
  79. //
  80. rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
  81. rmdParams.HwProfile = 0;
  82. //
  83. // walk down the tree and remove all of this device's children
  84. //
  85. if (m_pDevice->GetChild() &&
  86. !IsRemoveSubtreeOk(m_pDevice->GetChild(), &rmdParams))
  87. {
  88. //
  89. // Children refuse the removal. Cancel the removal.
  90. //
  91. MsgBoxParam(m_hDlg, IDS_DESCENDANTS_VETO, 0, MB_OK | MB_ICONINFORMATION);
  92. EndDialog(m_hDlg, IDCANCEL);
  93. return;
  94. }
  95. SP_DEVINSTALL_PARAMS dip;
  96. dip.cbSize = sizeof(dip);
  97. m_pDevice->m_pMachine->DiSetClassInstallParams(*m_pDevice,
  98. &rmdParams.ClassInstallHeader,
  99. sizeof(rmdParams));
  100. BOOL RemovalOK;
  101. //
  102. // Either this device has no children or the children has no
  103. // objection on removal. Remove it.
  104. //
  105. RemovalOK = m_pDevice->m_pMachine->DiCallClassInstaller(DIF_REMOVE, *m_pDevice);
  106. if (hCursorOld)
  107. {
  108. SetCursor(hCursorOld);
  109. }
  110. m_pDevice->m_pMachine->DiSetClassInstallParams(*m_pDevice, NULL, 0);
  111. if (RemovalOK)
  112. {
  113. EndDialog(m_hDlg, IDOK);
  114. }
  115. else
  116. {
  117. //
  118. // Can not removed the device, return Cancel so that
  119. // the caller know what is going on.
  120. //
  121. MsgBoxParam(m_hDlg, IDS_UNINSTALL_FAILED, 0, MB_OK | MB_ICONINFORMATION);
  122. EndDialog(m_hDlg, IDCANCEL);
  123. }
  124. }
  125. //
  126. // This function walks the substree started with the given CDevice to
  127. // see if it is ok to removed the CDevice.
  128. // INPUT:
  129. // pDevice -- the device
  130. // prmdParams -- parameter used to call the setupapi
  131. // OUTPUT:
  132. // TRUE -- it is ok to remove
  133. // FALSE -- it is NOT ok to remove
  134. BOOL
  135. CRemoveDevDlg::IsRemoveSubtreeOk(
  136. CDevice* pDevice,
  137. PSP_REMOVEDEVICE_PARAMS prmdParams
  138. )
  139. {
  140. BOOL Result = TRUE;
  141. HDEVINFO hDevInfo;
  142. while (Result && pDevice)
  143. {
  144. //
  145. // if the device has children, remove all of them.
  146. //
  147. if (Result && pDevice->GetChild())
  148. {
  149. Result = IsRemoveSubtreeOk(pDevice->GetChild(), prmdParams);
  150. }
  151. //
  152. // create a new HDEVINFO just for this device -- we do not want
  153. // to change anything in the main device tree maintained by CMachine
  154. //
  155. hDevInfo = pDevice->m_pMachine->DiCreateDeviceInfoList(NULL, m_hDlg);
  156. if (INVALID_HANDLE_VALUE == hDevInfo)
  157. {
  158. return FALSE;
  159. }
  160. SP_DEVINFO_DATA DevData;
  161. DevData.cbSize = sizeof(DevData);
  162. CDevInfoList DevInfoList(hDevInfo, m_hDlg);
  163. //
  164. // include the device in the newly created hdevinfo
  165. //
  166. DevInfoList.DiOpenDeviceInfo(pDevice->GetDeviceID(), m_hDlg, 0,
  167. &DevData);
  168. DevInfoList.DiSetClassInstallParams(&DevData,
  169. &prmdParams->ClassInstallHeader,
  170. sizeof(SP_REMOVEDEVICE_PARAMS)
  171. );
  172. //
  173. // remove this devnode.
  174. //
  175. Result = DevInfoList.DiCallClassInstaller(DIF_REMOVE, &DevData);
  176. DevInfoList.DiSetClassInstallParams(&DevData, NULL, 0);
  177. //
  178. // continue the query on all the siblings
  179. //
  180. pDevice = pDevice->GetSibling();
  181. }
  182. return Result;
  183. }
  184. BOOL
  185. CRemoveDevDlg::OnDestroy()
  186. {
  187. HICON hIcon;
  188. hIcon = (HICON)SendDlgItemMessage(m_hDlg, IDC_REMOVEDEV_ICON, STM_GETICON, 0, 0);
  189. if (hIcon) {
  190. DestroyIcon(hIcon);
  191. }
  192. return FALSE;
  193. }
  194. BOOL
  195. CRemoveDevDlg::OnHelp(
  196. LPHELPINFO pHelpInfo
  197. )
  198. {
  199. WinHelp((HWND)pHelpInfo->hItemHandle, DEVMGR_HELP_FILE_NAME, HELP_WM_HELP,
  200. (ULONG_PTR)g_a210HelpIDs);
  201. return FALSE;
  202. }
  203. BOOL
  204. CRemoveDevDlg::OnContextMenu(
  205. HWND hWnd,
  206. WORD xPos,
  207. WORD yPos
  208. )
  209. {
  210. UNREFERENCED_PARAMETER(xPos);
  211. UNREFERENCED_PARAMETER(yPos);
  212. WinHelp(hWnd, DEVMGR_HELP_FILE_NAME, HELP_CONTEXTMENU,
  213. (ULONG_PTR)g_a210HelpIDs);
  214. return FALSE;
  215. }