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.

270 lines
9.1 KiB

  1. #include "priv.h"
  2. #include "resource.h"
  3. #include <mluisupp.h>
  4. struct SUParams {
  5. LPSOFTDISTINFO psdi;
  6. BITBOOL bRemind : 1;
  7. BITBOOL bDetails : 1;
  8. LONG cyNoDetails;
  9. LONG cxDlg;
  10. LONG cyDlg;
  11. };
  12. INT_PTR CALLBACK SoftwareUpdateDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  13. SHDOCAPI_(DWORD) SoftwareUpdateMessageBox( HWND hWnd,
  14. LPCWSTR szDistUnit,
  15. DWORD dwFlags,
  16. LPSOFTDISTINFO psdi )
  17. {
  18. HRESULT hr;
  19. int iRet = IDIGNORE;
  20. SOFTDISTINFO sdi;
  21. SUParams suparams;
  22. DWORD dwAdStateNew = SOFTDIST_ADSTATE_NONE;
  23. if ( psdi == NULL )
  24. {
  25. // use a local
  26. sdi.cbSize = sizeof(SOFTDISTINFO);
  27. sdi.dwReserved = 0;
  28. psdi = &sdi;
  29. }
  30. suparams.psdi = psdi;
  31. suparams.bRemind = TRUE;
  32. suparams.bDetails = FALSE;
  33. hr = GetSoftwareUpdateInfo( szDistUnit, psdi );
  34. // we need an HREF to work properly. The title and abstract are negotiable.
  35. if ( SUCCEEDED(hr) && psdi->szHREF != NULL )
  36. {
  37. // see if this is an update the user already knows about.
  38. // If it is, then skip the dialog.
  39. if ( (psdi->dwUpdateVersionMS >= psdi->dwInstalledVersionMS ||
  40. (psdi->dwUpdateVersionMS == psdi->dwInstalledVersionMS &&
  41. psdi->dwUpdateVersionLS >= psdi->dwInstalledVersionLS)) &&
  42. (psdi->dwUpdateVersionMS >= psdi->dwAdvertisedVersionMS ||
  43. (psdi->dwUpdateVersionMS == psdi->dwAdvertisedVersionMS &&
  44. psdi->dwUpdateVersionLS >= psdi->dwAdvertisedVersionLS)) )
  45. {
  46. DWORD idDlg;
  47. if ( hr == S_OK ) // new version
  48. {
  49. // we have a pending update, either on the net, or downloaded
  50. if ( psdi->dwFlags & SOFTDIST_FLAG_USAGE_PRECACHE )
  51. {
  52. dwAdStateNew = SOFTDIST_ADSTATE_DOWNLOADED;
  53. // Show same dialog for downloaded/available states
  54. // because users get confused. See IE5 RAID entry 14488
  55. idDlg = IDD_SUAVAILABLE;
  56. }
  57. else
  58. {
  59. dwAdStateNew = SOFTDIST_ADSTATE_AVAILABLE;
  60. idDlg = IDD_SUAVAILABLE;
  61. }
  62. }
  63. else if ( psdi->dwUpdateVersionMS == psdi->dwInstalledVersionMS &&
  64. psdi->dwUpdateVersionLS == psdi->dwInstalledVersionLS )
  65. {
  66. // if installed version matches advertised, then we autoinstalled already
  67. dwAdStateNew = SOFTDIST_ADSTATE_INSTALLED;
  68. idDlg = IDD_SUINSTALLED;
  69. }
  70. else
  71. {
  72. idDlg = 0;
  73. }
  74. // only show the dialog if we've haven't been in this ad state before for
  75. // this update version
  76. if ( dwAdStateNew > psdi->dwAdState && idDlg != 0)
  77. {
  78. // Sundown: coercion is OK since SoftwareUpdateDlgProc returns true/false
  79. iRet = (int) DialogBoxParam(MLGetHinst(),
  80. MAKEINTRESOURCE(idDlg),
  81. hWnd,
  82. SoftwareUpdateDlgProc,
  83. (LPARAM)&suparams);
  84. }
  85. } // if update is a newer version than advertised
  86. // If the user doesn't want a reminder and didn't cancel, mark the DU.
  87. if ( !suparams.bRemind && (iRet == IDNO || iRet == IDYES) )
  88. {
  89. SetSoftwareUpdateAdvertisementState( szDistUnit,
  90. dwAdStateNew,
  91. psdi->dwUpdateVersionMS,
  92. psdi->dwUpdateVersionLS );
  93. } // if we're finished with this ad state for this version
  94. } // if we got the update info
  95. else
  96. iRet = IDABORT;
  97. if ( FAILED(hr) || psdi == &sdi )
  98. {
  99. if ( psdi->szTitle != NULL )
  100. {
  101. CoTaskMemFree( psdi->szTitle );
  102. psdi->szTitle = NULL;
  103. }
  104. if ( psdi->szAbstract != NULL )
  105. {
  106. CoTaskMemFree( psdi->szAbstract );
  107. psdi->szAbstract = NULL;
  108. };
  109. if ( psdi->szHREF != NULL )
  110. {
  111. CoTaskMemFree( psdi->szHREF );
  112. psdi->szHREF = NULL;
  113. }
  114. }
  115. return iRet;
  116. }
  117. INT_PTR CALLBACK SoftwareUpdateDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  118. {
  119. BOOL fRet = 0;
  120. SUParams *psuparam = (SUParams*)GetWindowLongPtr(hDlg, DWLP_USER);;
  121. HRESULT hr = S_OK;
  122. HWND hwndDetails;
  123. switch (msg)
  124. {
  125. case WM_INITDIALOG:
  126. int cchDetails;
  127. TCHAR *pszTitle;
  128. TCHAR *pszAbstract;
  129. TCHAR *pszDetails;
  130. TCHAR szFmt[MAX_PATH];
  131. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  132. psuparam = (SUParams*)lParam;
  133. if (SHRestricted( REST_NOFORGETSOFTWAREUPDATE))
  134. EnableWindow(GetDlgItem(hDlg, IDC_REMIND), FALSE);
  135. // Prepare the details from the SOFTDISTINFO
  136. MLLoadString(IDS_SUDETAILSFMT, szFmt, ARRAYSIZE(szFmt) );
  137. cchDetails = lstrlen( szFmt );
  138. if ( psuparam->psdi->szTitle != NULL )
  139. {
  140. pszTitle = psuparam->psdi->szTitle;
  141. }
  142. else
  143. {
  144. pszTitle = NULL;
  145. }
  146. if ( psuparam->psdi->szAbstract != NULL )
  147. {
  148. pszAbstract = psuparam->psdi->szAbstract;
  149. }
  150. else
  151. {
  152. pszAbstract = NULL;
  153. }
  154. pszDetails = new TCHAR[cchDetails];
  155. if ( pszDetails != NULL )
  156. {
  157. wnsprintf( pszDetails, cchDetails, szFmt, ((pszTitle!=NULL)?pszTitle:TEXT("")),
  158. ((pszAbstract!=NULL)?pszAbstract:TEXT("")) );
  159. // set the details text
  160. SetDlgItemText( hDlg, IDC_DETAILSTEXT, pszDetails );
  161. // initialize the reminder check box
  162. CheckDlgButton( hDlg, IDC_REMIND, ((psuparam->bRemind)?BST_CHECKED:BST_UNCHECKED) );
  163. // Hide or show the details
  164. RECT rectDlg;
  165. RECT rectDetails;
  166. GetWindowRect( hDlg, &rectDlg );
  167. psuparam->cyDlg = rectDlg.bottom - rectDlg.top;
  168. psuparam->cxDlg = rectDlg.right - rectDlg.left;
  169. hwndDetails = GetDlgItem( hDlg, IDC_DETAILSTEXT );
  170. GetWindowRect( hwndDetails, &rectDetails );
  171. psuparam->cyNoDetails = rectDetails.top - rectDlg.top;
  172. SetWindowPos( hwndDetails, NULL, 0,0,0,0, SWP_NOMOVE | SWP_HIDEWINDOW | SWP_NOZORDER | SWP_NOSIZE );
  173. SetWindowPos( hDlg, NULL,
  174. 0,0,psuparam->cxDlg,psuparam->cyNoDetails,
  175. SWP_NOMOVE | SWP_NOZORDER );
  176. }
  177. else
  178. EndDialog( hDlg, IDABORT );
  179. if ( pszDetails != NULL )
  180. delete pszDetails;
  181. fRet = TRUE;
  182. break;
  183. case WM_COMMAND:
  184. switch (LOWORD(wParam))
  185. {
  186. case IDYES:
  187. EndDialog(hDlg, IDYES );
  188. fRet = TRUE;
  189. break;
  190. case IDNO:
  191. EndDialog(hDlg, IDNO );
  192. fRet = TRUE;
  193. break;
  194. case IDC_REMIND:
  195. psuparam->bRemind = IsDlgButtonChecked( hDlg, IDC_REMIND ) == BST_CHECKED;
  196. fRet = TRUE;
  197. break;
  198. case IDC_DETAILS:
  199. {
  200. TCHAR szDetails[40];
  201. // toggle the details
  202. hwndDetails = GetDlgItem( hDlg, IDC_DETAILSTEXT );
  203. psuparam->bDetails = !psuparam->bDetails;
  204. if ( psuparam->bDetails )
  205. {
  206. // show the details
  207. // switch button to close text
  208. MLLoadString(IDS_SUDETAILSCLOSE, szDetails, ARRAYSIZE(szDetails) );
  209. SetDlgItemText( hDlg, IDC_DETAILS, szDetails );
  210. SetWindowPos( hDlg, NULL,
  211. 0,0,psuparam->cxDlg, psuparam->cyDlg,
  212. SWP_NOMOVE | SWP_NOZORDER );
  213. SetWindowPos( hwndDetails, NULL, 0,0,0,0, SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOSIZE );
  214. }
  215. else
  216. {
  217. MLLoadString(IDS_SUDETAILSOPEN, szDetails, ARRAYSIZE(szDetails) );
  218. SetDlgItemText( hDlg, IDC_DETAILS, szDetails );
  219. SetWindowPos( hwndDetails, NULL, 0,0,0,0, SWP_NOMOVE | SWP_HIDEWINDOW | SWP_NOZORDER | SWP_NOSIZE );
  220. SetWindowPos( hDlg, NULL,
  221. 0,0,psuparam->cxDlg,psuparam->cyNoDetails,
  222. SWP_NOMOVE | SWP_NOZORDER );
  223. }
  224. }
  225. fRet = TRUE;
  226. break;
  227. }
  228. break;
  229. case WM_CLOSE:
  230. EndDialog(hDlg, IDNO);
  231. fRet = TRUE;
  232. break;
  233. case WM_DESTROY:
  234. fRet = TRUE;
  235. break;
  236. default:
  237. fRet = FALSE;
  238. }
  239. return fRet;
  240. }