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.

272 lines
9.4 KiB

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