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.

360 lines
11 KiB

  1. //
  2. // Uninstal.C
  3. //
  4. // Copyright (C) Microsoft, 1994,1995 All Rights Reserved.
  5. //
  6. // History:
  7. // 3/20/95 [stevecat] - NT port & real clean up, unicode, etc.
  8. //
  9. //
  10. #include "priv.h"
  11. #include "appwiz.h"
  12. #include "regstr.h"
  13. #include "dlinst.h"
  14. #ifdef WX86
  15. BOOL bWx86Enabled=FALSE;
  16. BOOL bForceX86Env=FALSE;
  17. const WCHAR ProcArchName[]=L"PROCESSOR_ARCHITECTURE";
  18. #endif
  19. #ifdef DOWNLEVEL
  20. //////////////////////////////////////////////////////////////////////////////
  21. //
  22. // Unistall Page - the basic idea:
  23. //
  24. // this page has a simple listbox displaying removable software components
  25. // the user can select one and hit the "remove" button
  26. //
  27. //////////////////////////////////////////////////////////////////////////////
  28. //////////////////////////////////////////////////////////////////////////////
  29. //
  30. // defines
  31. //
  32. //////////////////////////////////////////////////////////////////////////////
  33. #define UNM_WAKEUP ( WM_APP + 1 ) // from terminated worker thread
  34. //////////////////////////////////////////////////////////////////////////////
  35. //
  36. // constant strings
  37. //
  38. //////////////////////////////////////////////////////////////////////////////
  39. static const TCHAR *c_UninstallKey = REGSTR_PATH_UNINSTALL;
  40. static const TCHAR *c_UninstallItemName = REGSTR_VAL_UNINSTALLER_DISPLAYNAME;
  41. static const TCHAR *c_UninstallItemCommand = REGSTR_VAL_UNINSTALLER_COMMANDLINE;
  42. const static DWORD aUninstallHelpIDs[] = { // Context Help IDs
  43. IDC_BUTTONSETUP, IDH_APPWIZ_DISKINTALLL_BUTTON,
  44. IDC_MODIFYUNINSTALL, IDH_APPWIZ_UNINSTALL_BUTTON,
  45. IDC_REGISTERED_APPS, IDH_APPWIZ_UNINSTALL_LIST,
  46. 0, 0
  47. };
  48. #define DISPLAYNAME_SIZE 64
  49. //////////////////////////////////////////////////////////////////////////////
  50. //
  51. // Uninstall_FreeList -- empties list of removable applications
  52. //
  53. // NOTE: the third parameter is the listbox to empty, which may be NULL
  54. //
  55. //////////////////////////////////////////////////////////////////////////////
  56. void Uninstall_FreeList( HWND dlg, LPWIZDATA lpwd, HWND listbox )
  57. {
  58. if( listbox )
  59. ListBox_ResetContent( listbox );
  60. if( lpwd->lpUItem )
  61. {
  62. LocalFree( (HANDLE)lpwd->lpUItem );
  63. lpwd->lpUItem = 0;
  64. }
  65. }
  66. //////////////////////////////////////////////////////////////////////////////
  67. //
  68. // Uninstall_RefreshList -- fills/refills the list of removable applications
  69. //
  70. //////////////////////////////////////////////////////////////////////////////
  71. void Uninstall_RefreshList( HWND dlg, LPWIZDATA lpwd )
  72. {
  73. DWORD dwTotal;
  74. //
  75. // we wouldn't have gotten here if dlgmgr failed to create the listbox
  76. //
  77. HWND listbox = GetDlgItem( dlg, IDC_REGISTERED_APPS );
  78. //
  79. // avoid flicker when visible
  80. //
  81. SetWindowRedraw( listbox, FALSE );
  82. //
  83. // clean out any residual junk
  84. //
  85. Uninstall_FreeList( dlg, lpwd, listbox );
  86. //
  87. // Maximum size of lists of removable apps
  88. //
  89. dwTotal = 0;
  90. DL_FillAppListBox(listbox, &dwTotal);
  91. DL_ConfigureButtonsAndStatic(dlg, listbox, LB_ERR);
  92. //
  93. // redraw now that we've filled it
  94. //
  95. SetWindowRedraw( listbox, TRUE );
  96. }
  97. //////////////////////////////////////////////////////////////////////////////
  98. //
  99. // UNINSTALL_THREAD_INFO
  100. //
  101. //////////////////////////////////////////////////////////////////////////////
  102. typedef struct
  103. {
  104. PROCESS_INFORMATION uninstaller;
  105. HWND dlg;
  106. } UNINSTALL_THREAD_INFO;
  107. //////////////////////////////////////////////////////////////////////////////
  108. //
  109. // Uninstall_TrackingThread
  110. //
  111. // -- waits for an uninstall command to complete and refreshes the dialog
  112. //
  113. //////////////////////////////////////////////////////////////////////////////
  114. DWORD Uninstall_TrackingThread( UNINSTALL_THREAD_INFO *info )
  115. {
  116. ResumeThread( info->uninstaller.hThread );
  117. CloseHandle( info->uninstaller.hThread );
  118. WaitForSingleObject( info->uninstaller.hProcess, INFINITE );
  119. CloseHandle( info->uninstaller.hProcess );
  120. PostMessage( info->dlg, UNM_WAKEUP, 0, 0 );
  121. return 0;
  122. }
  123. //////////////////////////////////////////////////////////////////////////////
  124. //
  125. // InstallUninstallDlgProc -- dlgproc for the install/uninstall page (surprise)
  126. //
  127. //////////////////////////////////////////////////////////////////////////////
  128. BOOL_PTR CALLBACK
  129. InstallUninstallDlgProc( HWND dlg, UINT message, WPARAM wparam, LPARAM lparam )
  130. {
  131. LPPROPSHEETPAGE page = (LPPROPSHEETPAGE)GetWindowLongPtr( dlg, DWLP_USER );
  132. LPWIZDATA lpwd = page ? (LPWIZDATA)page->lParam : NULL;
  133. switch( message )
  134. {
  135. case WM_INITDIALOG:
  136. SetWindowLongPtr( dlg, DWLP_USER, lparam );
  137. page = (LPPROPSHEETPAGE)lparam;
  138. lpwd = (LPWIZDATA)page->lParam;
  139. lpwd->hwnd = dlg;
  140. Uninstall_RefreshList( dlg, lpwd );
  141. #ifdef WX86
  142. //
  143. // Set initial state of ForceX86Env to FALSE (unchecked)
  144. //
  145. bForceX86Env = FALSE;
  146. if (bWx86Enabled) {
  147. SendDlgItemMessage(dlg,
  148. IDC_FORCEX86ENV,
  149. BM_SETSTATE,
  150. BST_UNCHECKED,
  151. 0
  152. );
  153. } else {
  154. ShowWindow(GetDlgItem(dlg,IDC_FORCEX86ENV), SW_HIDE);
  155. }
  156. #endif
  157. break;
  158. case WM_DESTROY:
  159. Uninstall_FreeList( dlg, lpwd, NULL );
  160. break;
  161. case UNM_WAKEUP:
  162. //
  163. // an uninstall in another thread just finished
  164. //
  165. EnableWindow( GetParent( dlg ), TRUE );
  166. SetForegroundWindow( GetParent( dlg ) );
  167. Uninstall_RefreshList( dlg, lpwd );
  168. break;
  169. case WM_NOTIFY:
  170. {
  171. NMHDR *nmhdr = (NMHDR *)lparam;
  172. switch( nmhdr->code )
  173. {
  174. case PSN_SETACTIVE:
  175. lpwd->hwnd = dlg;
  176. break;
  177. case PSN_KILLACTIVE:
  178. case PSN_HASHELP:
  179. case PSN_HELP:
  180. break;
  181. default:
  182. return FALSE;
  183. }
  184. break;
  185. }
  186. case WM_HELP:
  187. WinHelp((HWND)((LPHELPINFO)lparam)->hItemHandle, NULL,
  188. HELP_WM_HELP, (DWORD_PTR)aUninstallHelpIDs);
  189. break;
  190. case WM_CONTEXTMENU:
  191. WinHelp((HWND)wparam, NULL, HELP_CONTEXTMENU,
  192. (DWORD_PTR)aUninstallHelpIDs);
  193. break;
  194. case WM_COMMAND:
  195. switch( GET_WM_COMMAND_ID( wparam, lparam ) )
  196. {
  197. case IDC_BUTTONSETUP:
  198. if( GET_WM_COMMAND_CMD( wparam, lparam ) == BN_CLICKED ) {
  199. if (SetupWizard(lpwd)) {
  200. DismissCPL(lpwd);
  201. }
  202. }
  203. break;
  204. case IDC_MODIFY:
  205. case IDC_REPAIR:
  206. case IDC_UNINSTALL:
  207. case IDC_MODIFYUNINSTALL:
  208. if( GET_WM_COMMAND_CMD( wparam, lparam ) == BN_CLICKED )
  209. {
  210. HWND hwndListBox = GetDlgItem(dlg, IDC_REGISTERED_APPS);
  211. if (hwndListBox)
  212. {
  213. int iSel = ListBox_GetCurSel(hwndListBox);
  214. if (LB_ERR != iSel)
  215. DL_InvokeAction(GET_WM_COMMAND_ID( wparam, lparam ), dlg, hwndListBox, iSel);
  216. }
  217. }
  218. break;
  219. case IDC_REGISTERED_APPS:
  220. switch( GET_WM_COMMAND_CMD( wparam, lparam ) )
  221. {
  222. case LBN_SELCHANGE:
  223. {
  224. HWND hwndListBox = GetDlgItem(dlg, IDC_REGISTERED_APPS);
  225. if (hwndListBox)
  226. {
  227. int iSel = ListBox_GetCurSel(hwndListBox);
  228. if (LB_ERR != iSel)
  229. DL_ConfigureButtonsAndStatic(dlg, hwndListBox, iSel);
  230. }
  231. break;
  232. }
  233. case LBN_DBLCLK:
  234. {
  235. int iButtonID = 0;
  236. HWND hwndListBox = GetDlgItem(dlg, IDC_REGISTERED_APPS);
  237. if (hwndListBox)
  238. {
  239. int iSel = ListBox_GetCurSel(hwndListBox);
  240. if (LB_ERR != iSel)
  241. {
  242. // Go through all the buttons in order of less damaging to more
  243. // damaging and invoke the first visible+enable one
  244. HWND hwndTmp = GetDlgItem(dlg, IDC_MODIFYUNINSTALL);
  245. if (IsWindowVisible(hwndTmp) && IsWindowEnabled(hwndTmp))
  246. iButtonID = IDC_MODIFYUNINSTALL;
  247. else
  248. {
  249. hwndTmp = GetDlgItem(dlg, IDC_MODIFY);
  250. if (IsWindowVisible(hwndTmp) && IsWindowEnabled(hwndTmp))
  251. iButtonID = IDC_MODIFY;
  252. else
  253. {
  254. hwndTmp = GetDlgItem(dlg, IDC_REPAIR);
  255. if (IsWindowVisible(hwndTmp) && IsWindowEnabled(hwndTmp))
  256. iButtonID = IDC_REPAIR;
  257. else
  258. {
  259. hwndTmp = GetDlgItem(dlg, IDC_UNINSTALL);
  260. if (IsWindowVisible(hwndTmp) && IsWindowEnabled(hwndTmp))
  261. iButtonID = IDC_UNINSTALL;
  262. }
  263. }
  264. }
  265. if (iButtonID)
  266. DL_InvokeAction(iButtonID, dlg, hwndListBox, iSel);
  267. }
  268. }
  269. break;
  270. }
  271. }
  272. break;
  273. #ifdef WX86
  274. case IDC_FORCEX86ENV:
  275. if (bWx86Enabled &&
  276. GET_WM_COMMAND_CMD( wparam, lparam ) == BN_CLICKED )
  277. {
  278. bForceX86Env = !bForceX86Env;
  279. }
  280. break;
  281. #endif
  282. default:
  283. return FALSE;
  284. }
  285. break;
  286. default:
  287. return FALSE;
  288. }
  289. return TRUE;
  290. }
  291. #endif // DOWNLEVEL