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.

259 lines
6.1 KiB

  1. /*++
  2. Copyright (C) 1997-1999 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. if (BN_CLICKED == HIWORD(wParam))
  58. {
  59. if (IDOK == LOWORD(wParam))
  60. {
  61. OnOk();
  62. }
  63. else if (IDCANCEL == LOWORD(wParam))
  64. {
  65. EndDialog(m_hDlg, IDCANCEL);
  66. }
  67. }
  68. }
  69. void CRemoveDevDlg::OnOk()
  70. {
  71. SP_REMOVEDEVICE_PARAMS rmdParams;
  72. int hwpfIndex;
  73. BOOL Continue = TRUE;
  74. CHwProfile* phwpf;
  75. rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  76. rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
  77. HCURSOR hCursorOld;
  78. hCursorOld = SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)));
  79. //
  80. // Uninstall does not apply to specific profiles -- it is global.
  81. //
  82. rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
  83. rmdParams.HwProfile = 0;
  84. //
  85. // walk down the tree and remove all of this device's children
  86. //
  87. if (m_pDevice->GetChild() &&
  88. !IsRemoveSubtreeOk(m_pDevice->GetChild(), &rmdParams))
  89. {
  90. //
  91. // Children refuse the removal. Cancel the removal.
  92. //
  93. MsgBoxParam(m_hDlg, IDS_DESCENDANTS_VETO, 0, MB_OK | MB_ICONINFORMATION);
  94. EndDialog(m_hDlg, IDCANCEL);
  95. return;
  96. }
  97. SP_DEVINSTALL_PARAMS dip;
  98. dip.cbSize = sizeof(dip);
  99. m_pDevice->m_pMachine->DiSetClassInstallParams(*m_pDevice,
  100. &rmdParams.ClassInstallHeader,
  101. sizeof(rmdParams));
  102. BOOL RemovalOK;
  103. //
  104. // Either this device has no children or the children has no
  105. // objection on removal. Remove it.
  106. //
  107. RemovalOK = m_pDevice->m_pMachine->DiCallClassInstaller(DIF_REMOVE, *m_pDevice);
  108. if (hCursorOld)
  109. {
  110. SetCursor(hCursorOld);
  111. }
  112. m_pDevice->m_pMachine->DiSetClassInstallParams(*m_pDevice, NULL, 0);
  113. if (RemovalOK)
  114. {
  115. EndDialog(m_hDlg, IDOK);
  116. }
  117. else
  118. {
  119. //
  120. // Can not removed the device, return Cancel so that
  121. // the caller know what is going on.
  122. //
  123. MsgBoxParam(m_hDlg, IDS_UNINSTALL_FAILED, 0, MB_OK | MB_ICONINFORMATION);
  124. EndDialog(m_hDlg, IDCANCEL);
  125. }
  126. }
  127. //
  128. // This function walks the substree started with the given CDevice to
  129. // see if it is ok to removed the CDevice.
  130. // INPUT:
  131. // pDevice -- the device
  132. // prmdParams -- parameter used to call the setupapi
  133. // OUTPUT:
  134. // TRUE -- it is ok to remove
  135. // FALSE -- it is NOT ok to remove
  136. BOOL
  137. CRemoveDevDlg::IsRemoveSubtreeOk(
  138. CDevice* pDevice,
  139. PSP_REMOVEDEVICE_PARAMS prmdParams
  140. )
  141. {
  142. BOOL Result = TRUE;
  143. HDEVINFO hDevInfo;
  144. while (Result && pDevice)
  145. {
  146. //
  147. // if the device has children, remove all of them.
  148. //
  149. if (Result && pDevice->GetChild())
  150. {
  151. Result = IsRemoveSubtreeOk(pDevice->GetChild(), prmdParams);
  152. }
  153. //
  154. // create a new HDEVINFO just for this device -- we do not want
  155. // to change anything in the main device tree maintained by CMachine
  156. //
  157. hDevInfo = pDevice->m_pMachine->DiCreateDeviceInfoList(NULL, m_hDlg);
  158. if (INVALID_HANDLE_VALUE == hDevInfo)
  159. {
  160. return FALSE;
  161. }
  162. SP_DEVINFO_DATA DevData;
  163. DevData.cbSize = sizeof(DevData);
  164. CDevInfoList DevInfoList(hDevInfo, m_hDlg);
  165. //
  166. // include the device in the newly created hdevinfo
  167. //
  168. DevInfoList.DiOpenDeviceInfo(pDevice->GetDeviceID(), m_hDlg, 0,
  169. &DevData);
  170. DevInfoList.DiSetClassInstallParams(&DevData,
  171. &prmdParams->ClassInstallHeader,
  172. sizeof(SP_REMOVEDEVICE_PARAMS)
  173. );
  174. //
  175. // remove this devnode.
  176. //
  177. Result = DevInfoList.DiCallClassInstaller(DIF_REMOVE, &DevData);
  178. DevInfoList.DiSetClassInstallParams(&DevData, NULL, 0);
  179. //
  180. // continue the query on all the siblings
  181. //
  182. pDevice = pDevice->GetSibling();
  183. }
  184. return Result;
  185. }
  186. BOOL
  187. CRemoveDevDlg::OnDestroy()
  188. {
  189. HICON hIcon;
  190. if(hIcon = (HICON)SendDlgItemMessage(m_hDlg, IDC_REMOVEDEV_ICON, STM_GETICON, 0, 0)) {
  191. DestroyIcon(hIcon);
  192. }
  193. return FALSE;
  194. }
  195. BOOL
  196. CRemoveDevDlg::OnHelp(
  197. LPHELPINFO pHelpInfo
  198. )
  199. {
  200. WinHelp((HWND)pHelpInfo->hItemHandle, DEVMGR_HELP_FILE_NAME, HELP_WM_HELP,
  201. (ULONG_PTR)g_a210HelpIDs);
  202. return FALSE;
  203. }
  204. BOOL
  205. CRemoveDevDlg::OnContextMenu(
  206. HWND hWnd,
  207. WORD xPos,
  208. WORD yPos
  209. )
  210. {
  211. WinHelp(hWnd, DEVMGR_HELP_FILE_NAME, HELP_CONTEXTMENU,
  212. (ULONG_PTR)g_a210HelpIDs);
  213. return FALSE;
  214. }