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.

316 lines
8.6 KiB

  1. //
  2. // Downlevel (NT4, win9X) Install/Unistall page
  3. //
  4. #include "priv.h"
  5. #include "appwizid.h"
  6. #include "dlinst.h"
  7. #include "sccls.h"
  8. //
  9. // DonwLevelManager: Ugly singleton class
  10. //
  11. // Mainly there to keep state info and for its destructor
  12. //
  13. class CDLManager* g_pDLManager = NULL;
  14. class CDLManager
  15. {
  16. public:
  17. // Rely on the fact that shell "new" zero out memory
  18. CDLManager() : _hrInit(E_FAIL)
  19. {
  20. _hrInit = CoInitialize(0);
  21. _szStatic[0] = 0;
  22. _szStatic2[0] = 0;
  23. _uiStatic = 0;
  24. }
  25. ~CDLManager()
  26. {
  27. if (_peia)
  28. _peia->Release();
  29. if (SUCCEEDED(_hrInit))
  30. CoUninitialize();
  31. }
  32. public:
  33. void InitButtonsHandle(HWND hwndPage)
  34. {
  35. // No check for success: check before using
  36. if (!_hwndModifyUninstall)
  37. {
  38. _hwndModifyUninstall = GetDlgItem(hwndPage, IDC_MODIFYUNINSTALL);
  39. _rghwndButtons[IDC_MODIFY-IDC_BASEBUTTONS] = GetDlgItem(hwndPage, IDC_MODIFY);
  40. _rghwndButtons[IDC_REPAIR-IDC_BASEBUTTONS] = GetDlgItem(hwndPage, IDC_REPAIR);
  41. _rghwndButtons[IDC_UNINSTALL-IDC_BASEBUTTONS] = GetDlgItem(hwndPage, IDC_UNINSTALL);
  42. }
  43. }
  44. void SetVisibleButtons(BOOL bShow3Buttons)
  45. {
  46. // bShow3Buttons == TRUE will show the three buttons
  47. if (_hwndModifyUninstall)
  48. ShowWindow(_hwndModifyUninstall, bShow3Buttons?SW_HIDE:SW_SHOW);
  49. for (int i=0;i<3;++i)
  50. {
  51. if (_rghwndButtons[i])
  52. ShowWindow(_rghwndButtons[i], bShow3Buttons?SW_SHOW:SW_HIDE);
  53. }
  54. }
  55. public:
  56. IEnumInstalledApps* _peia;
  57. HWND _hwndModifyUninstall;
  58. HWND _rghwndButtons[3];
  59. HRESULT _hrInit;
  60. TCHAR _szStatic[250];
  61. TCHAR _szStatic2[50];
  62. UINT _uiStatic;
  63. };
  64. //
  65. // pcApps has to be already initialized, we only increment it
  66. //
  67. STDAPI DL_FillAppListBox(HWND hwndListBox, DWORD* pdwApps)
  68. {
  69. ASSERT(IsWindow(hwndListBox));
  70. static CDLManager DLManager;
  71. g_pDLManager = &DLManager;
  72. ASSERT(g_pDLManager);
  73. HRESULT hres = E_FAIL;
  74. IShellAppManager * pam;
  75. if (SUCCEEDED(g_pDLManager->_hrInit))
  76. {
  77. hres = CoCreateInstance(CLSID_ShellAppManager, NULL, CLSCTX_INPROC_SERVER,
  78. IID_IShellAppManager, (LPVOID *)&pam);
  79. if (SUCCEEDED(hres))
  80. {
  81. // Initialize InstalledApp Enum if required
  82. if (!g_pDLManager->_peia)
  83. hres = pam->EnumInstalledApps(&g_pDLManager->_peia);
  84. if (SUCCEEDED(hres))
  85. {
  86. IInstalledApp* pia;
  87. while ((hres = g_pDLManager->_peia->Next(&pia)) == S_OK)
  88. {
  89. APPINFODATA ais = {0};
  90. ais.cbSize = sizeof(ais);
  91. ais.dwMask = AIM_DISPLAYNAME;
  92. pia->GetAppInfo(&ais);
  93. if (ais.dwMask & AIM_DISPLAYNAME)
  94. {
  95. int iIndex = LB_ERR;
  96. #ifdef UNICODE
  97. iIndex = ListBox_AddString(hwndListBox, ais.pszDisplayName);
  98. #else
  99. PCHAR pszTmp = NULL;
  100. // Get the size
  101. int cbSize = WideCharToMultiByte(CP_ACP, 0, ais.pszDisplayName, -1, pszTmp, 0,
  102. NULL, NULL);
  103. if (cbSize)
  104. {
  105. pszTmp = (LPTSTR)LocalAlloc(LPTR, cbSize);
  106. if (pszTmp)
  107. {
  108. cbSize = WideCharToMultiByte(CP_ACP, 0, ais.pszDisplayName, -1, pszTmp, cbSize,
  109. NULL, NULL);
  110. if (cbSize)
  111. iIndex = ListBox_AddString(hwndListBox, pszTmp);
  112. LocalFree(pszTmp);
  113. }
  114. }
  115. #endif
  116. // Did the operation succeed?
  117. if (LB_ERR != iIndex)
  118. {
  119. // Is memory OK?
  120. if (LB_ERRSPACE != iIndex)
  121. {
  122. // Yes
  123. ListBox_SetItemData(hwndListBox, iIndex, pia);
  124. ++(*pdwApps);
  125. }
  126. else
  127. {
  128. // No, better get out
  129. pia->Release();
  130. break;
  131. }
  132. }
  133. }
  134. else
  135. pia->Release();
  136. }
  137. }
  138. pam->Release();
  139. }
  140. }
  141. return hres;
  142. }
  143. STDAPI_(BOOL) DL_ConfigureButtonsAndStatic(HWND hwndPage, HWND hwndListBox, int iSel)
  144. {
  145. ASSERT(IsWindow(hwndPage));
  146. ASSERT(IsWindow(hwndListBox));
  147. ASSERT(0 <= iSel);
  148. UINT uiStatic = IDS_UNINSTINSTR_LEGACY;
  149. BOOL fret = FALSE;
  150. if (LB_ERR != iSel)
  151. {
  152. LRESULT lres = ListBox_GetItemData(hwndListBox, iSel);
  153. if (LB_ERR != lres)
  154. {
  155. fret = TRUE;
  156. IInstalledApp* pia = (IInstalledApp*)lres;
  157. DWORD dwActions = 0;
  158. pia->GetPossibleActions(&dwActions);
  159. dwActions &= (APPACTION_MODIFY|APPACTION_REPAIR|APPACTION_UNINSTALL|APPACTION_MODIFYREMOVE);
  160. g_pDLManager->InitButtonsHandle(hwndPage);
  161. if (dwActions & APPACTION_MODIFYREMOVE)
  162. {
  163. // Manage to show the right buttons
  164. g_pDLManager->SetVisibleButtons(FALSE);
  165. EnableWindow(g_pDLManager->_hwndModifyUninstall, TRUE);
  166. }
  167. else
  168. {
  169. if (dwActions & (APPACTION_MODIFY|APPACTION_REPAIR|APPACTION_UNINSTALL))
  170. {
  171. // Manage to show the right buttons
  172. g_pDLManager->SetVisibleButtons(TRUE);
  173. // Enable the applicable buttons
  174. EnableWindow(g_pDLManager->_rghwndButtons[IDC_MODIFY-IDC_BASEBUTTONS],
  175. (dwActions&APPACTION_MODIFY)?TRUE:FALSE);
  176. EnableWindow(g_pDLManager->_rghwndButtons[IDC_REPAIR-IDC_BASEBUTTONS],
  177. (dwActions&APPACTION_REPAIR)?TRUE:FALSE);
  178. EnableWindow(g_pDLManager->_rghwndButtons[IDC_UNINSTALL-IDC_BASEBUTTONS],
  179. (dwActions&APPACTION_UNINSTALL)?TRUE:FALSE);
  180. uiStatic = IDS_UNINSTINSTR_NEW;
  181. }
  182. else
  183. {
  184. // Manage to show the right buttons
  185. g_pDLManager->SetVisibleButtons(FALSE);
  186. EnableWindow(g_pDLManager->_hwndModifyUninstall, FALSE);
  187. }
  188. }
  189. }
  190. }
  191. if (!(*g_pDLManager->_szStatic))
  192. {
  193. if(!LoadString(g_hinst, IDS_UNINSTINSTR, g_pDLManager->_szStatic, ARRAYSIZE(g_pDLManager->_szStatic)))
  194. *(g_pDLManager->_szStatic) = 0;
  195. }
  196. if (*g_pDLManager->_szStatic && (g_pDLManager->_uiStatic != uiStatic))
  197. {
  198. TCHAR szMergedStatic[250];
  199. LoadString(g_hinst, uiStatic, g_pDLManager->_szStatic2, ARRAYSIZE(g_pDLManager->_szStatic2));
  200. wsprintf(szMergedStatic, g_pDLManager->_szStatic, g_pDLManager->_szStatic2);
  201. SetDlgItemText(hwndPage, IDC_UNINSTINSTR, szMergedStatic);
  202. g_pDLManager->_uiStatic = uiStatic;
  203. }
  204. return fret;
  205. }
  206. STDAPI_(BOOL) DL_InvokeAction(int iButtonID, HWND hwndPage, HWND hwndListBox, int iSel)
  207. {
  208. BOOL fret = FALSE;
  209. // Get app from listbox selection
  210. LRESULT lres = ListBox_GetItemData(hwndListBox, iSel);
  211. if (LB_ERR != lres)
  212. {
  213. fret = TRUE;
  214. IInstalledApp* pia = (IInstalledApp*)lres;
  215. // Invoke action from button ID
  216. if (pia)
  217. {
  218. HWND hwndPropSheet = GetParent(hwndPage);
  219. ::EnableWindow(hwndPropSheet, FALSE);
  220. switch(iButtonID)
  221. {
  222. case IDC_MODIFY:
  223. pia->Modify(hwndPropSheet);
  224. break;
  225. case IDC_REPAIR:
  226. // Pass FALSe, we don't want to reinstall, only repair
  227. pia->Repair(FALSE);
  228. break;
  229. case IDC_MODIFYUNINSTALL:
  230. case IDC_UNINSTALL:
  231. pia->Uninstall(hwndPropSheet);
  232. break;
  233. default:
  234. //???
  235. break;
  236. }
  237. ::EnableWindow(hwndPropSheet , TRUE);
  238. }
  239. }
  240. return fret;
  241. }