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.

296 lines
9.1 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: certmsg.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. //+---------------------------------------------------------------------------
  11. //
  12. // File: certmsg.cpp
  13. //
  14. // Contents: message display APIs
  15. //
  16. // History: 11/97 xtan
  17. //
  18. //----------------------------------------------------------------------------
  19. #include "pch.cpp"
  20. #pragma hdrstop
  21. // Application Includes
  22. #include "setupids.h"
  23. #include "certmsg.h"
  24. #define __dwFILE__ __dwFILE_CERTLIB_CERTMSG_CPP__
  25. extern FNLOGMESSAGEBOX *g_pfnLogMessagBox;
  26. //--------------------------------------------------------------------
  27. // Throw up a dialog with the format "<Prefix><UserMsg><SysErrorMsg>".
  28. // <Prefix> is basically "An error was detected...run the
  29. // wizard again..." and is prepended if CMB_REPEATWIZPREFIX
  30. // is specified.
  31. // <UserMsg> is specified by dwMsgId and can contain "%1" which
  32. // will be replaced with pwszCustomMsg. if dwMsgId is 0,
  33. // pwszCustomMsg is used instead.
  34. // <SysErrorMsg> is the system message for hrCode. It can be
  35. // suppressed if CMB_NOERRFROMSYS is specified.
  36. int
  37. CertMessageBox(
  38. IN HINSTANCE hInstance,
  39. IN BOOL fUnattended,
  40. IN HWND hWnd,
  41. IN DWORD dwMsgId,
  42. IN HRESULT hrCode,
  43. IN UINT uType,
  44. IN OPTIONAL const WCHAR * pwszCustomMsg)
  45. {
  46. HRESULT hr;
  47. int nMsgBoxRetVal = -1;
  48. DWORD nMsgChars = 0;
  49. WCHAR szEmergency[36];
  50. // variables that must be cleaned up
  51. WCHAR * pwszTitle = NULL;
  52. WCHAR * pwszPrefix = NULL;
  53. WCHAR * pwszUserMsg = NULL;
  54. WCHAR * pwszExpandedUserMsg = NULL;
  55. WCHAR const *pwszSysMsg = NULL;
  56. WCHAR * pwszFinalMsg = NULL;
  57. // mask off CMB defines
  58. BOOL fRepeatWizPrefix = uType & CMB_REPEATWIZPREFIX;
  59. BOOL fNoErrFromSys = uType & CMB_NOERRFROMSYS;
  60. uType &= ~(CMB_NOERRFROMSYS | CMB_REPEATWIZPREFIX);
  61. // load title
  62. hr=myLoadRCString(hInstance, IDS_MSG_TITLE, &pwszTitle);
  63. _JumpIfError(hr, error, "myLoadRCString");
  64. // load the "this wizard will need to be run again" prefix, if necessary
  65. if (fRepeatWizPrefix) {
  66. hr=myLoadRCString(hInstance, IDS_ERR_REPEATWIZPREFIX, &pwszPrefix);
  67. _JumpIfError(hr, error, "myLoadRCString");
  68. nMsgChars+=wcslen(pwszPrefix);
  69. }
  70. // get the system message for this error, if necessary
  71. if (!fNoErrFromSys) {
  72. pwszSysMsg = myGetErrorMessageText1(hrCode, TRUE, pwszCustomMsg);
  73. nMsgChars += wcslen(pwszSysMsg) + 1;
  74. }
  75. if (0!=dwMsgId) {
  76. // load requested message from resource
  77. hr=myLoadRCString(hInstance, dwMsgId, &pwszUserMsg);
  78. _JumpIfError(hr, error, "myLoadRCString");
  79. // perform substitution if necessary
  80. if (NULL==pwszCustomMsg) {
  81. // no substitution necessary
  82. CSASSERT(NULL==wcsstr(pwszUserMsg, L"%1")); // were we expecting a substitution?
  83. } else {
  84. // perform a substitution
  85. CSASSERT(NULL!=wcsstr(pwszUserMsg, L"%1")); // were we not expecting a substitution?
  86. if (!FormatMessage(
  87. FORMAT_MESSAGE_ALLOCATE_BUFFER | // flags
  88. FORMAT_MESSAGE_FROM_STRING |
  89. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  90. pwszUserMsg, // source
  91. 0, // message id
  92. 0, // language id
  93. reinterpret_cast<WCHAR *>(&pwszExpandedUserMsg), // output buffer
  94. 0, // min size
  95. reinterpret_cast<va_list *>(
  96. const_cast<WCHAR **>(&pwszCustomMsg)))) // pointer to array of pointers
  97. {
  98. hr=myHLastError();
  99. _JumpError(hr, error, "FormatMessage");
  100. }
  101. // use the expanded message instead of the unexpanded message
  102. LocalFree(pwszUserMsg);
  103. pwszUserMsg=pwszExpandedUserMsg;
  104. pwszExpandedUserMsg = NULL;
  105. }
  106. }
  107. else if (NULL != pwszCustomMsg)
  108. {
  109. // use pwszCustomMsg instead
  110. CSASSERT(NULL!=pwszCustomMsg);
  111. pwszUserMsg=const_cast<WCHAR *>(pwszCustomMsg);
  112. }
  113. else
  114. {
  115. hr = E_POINTER;
  116. _JumpError(hr, error, "Invalid NULL param");
  117. }
  118. nMsgChars+=wcslen(pwszUserMsg);
  119. // allocate buffer to hold everything
  120. pwszFinalMsg=(WCHAR *)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (nMsgChars+1)*sizeof(WCHAR));
  121. if (NULL == pwszFinalMsg)
  122. {
  123. hr = E_OUTOFMEMORY;
  124. _JumpError(hr, error, "LocalAlloc");
  125. }
  126. // build the message
  127. if (NULL!=pwszPrefix) {
  128. wcscat(pwszFinalMsg, pwszPrefix);
  129. }
  130. wcscat(pwszFinalMsg, pwszUserMsg);
  131. if (NULL!=pwszSysMsg) {
  132. wcscat(pwszFinalMsg, L" ");
  133. wcscat(pwszFinalMsg, pwszSysMsg);
  134. }
  135. CSASSERT(wcslen(pwszFinalMsg) <= nMsgChars);
  136. // finally show message
  137. DBGPRINT((DBG_SS_CERTLIB, "MessageBox: %ws: %ws\n", pwszTitle, pwszFinalMsg));
  138. if (NULL != g_pfnLogMessagBox)
  139. {
  140. (*g_pfnLogMessagBox)(hrCode, dwMsgId, pwszTitle, pwszFinalMsg);
  141. }
  142. if (fUnattended)
  143. {
  144. nMsgBoxRetVal = IDYES;
  145. }
  146. else
  147. {
  148. nMsgBoxRetVal=MessageBox(hWnd, pwszFinalMsg, pwszTitle, uType | MB_SETFOREGROUND);
  149. }
  150. if (NULL != g_pfnLogMessagBox)
  151. {
  152. _snwprintf(szEmergency, ARRAYSIZE(szEmergency), L"%d", nMsgBoxRetVal);
  153. (*g_pfnLogMessagBox)(S_OK, dwMsgId, pwszTitle, szEmergency);
  154. }
  155. // skip error handling
  156. goto done;
  157. error:
  158. // we had an error, but we really need to show something
  159. // build a non-localized desperation dialog: "Fatal: 0xNNNNNNNN MsgId:0xNNNNNNNN"
  160. _snwprintf(szEmergency, ARRAYSIZE(szEmergency), L"Fatal: 0x%8X MsgId: 0x%8X", hr, dwMsgId);
  161. DBGPRINT((DBG_SS_CERTLIB, "EmergencyMessageBox: %ws\n", szEmergency));
  162. if (NULL != g_pfnLogMessagBox)
  163. {
  164. (*g_pfnLogMessagBox)(hrCode, dwMsgId, L"EmergencyMessageBox", szEmergency);
  165. }
  166. if (!fUnattended) {
  167. // The message box with these flags is guaranteed to display
  168. MessageBox(hWnd, szEmergency, NULL, MB_ICONHAND | MB_SYSTEMMODAL);
  169. }
  170. done:
  171. if (NULL!=pwszTitle) {
  172. LocalFree(pwszTitle);
  173. }
  174. if (NULL!=pwszPrefix) {
  175. LocalFree(pwszPrefix);
  176. }
  177. if (NULL!=pwszUserMsg && pwszUserMsg!=pwszCustomMsg) {
  178. LocalFree(pwszUserMsg);
  179. }
  180. if (NULL!=pwszExpandedUserMsg) {
  181. LocalFree(pwszExpandedUserMsg);
  182. }
  183. if (NULL!=pwszSysMsg) {
  184. LocalFree(const_cast<WCHAR *>(pwszSysMsg));
  185. }
  186. if (NULL!=pwszFinalMsg) {
  187. LocalFree(pwszFinalMsg);
  188. }
  189. return nMsgBoxRetVal;
  190. }
  191. //--------------------------------------------------------------------
  192. // Throw up a dialog with the format "<UserMsg>".
  193. // <UserMsg> is specified by dwMsgId and can contain "%1" which
  194. // will be replaced with pwszCustomMsg.
  195. int
  196. CertInfoMessageBox(
  197. IN HINSTANCE hInstance,
  198. IN BOOL fUnattended,
  199. IN HWND hWnd,
  200. IN DWORD dwMsgId,
  201. IN OPTIONAL const WCHAR * pwszCustomMsg)
  202. {
  203. return CertMessageBox(
  204. hInstance,
  205. fUnattended,
  206. hWnd,
  207. dwMsgId,
  208. 0,
  209. MB_OK | MB_ICONINFORMATION | CMB_NOERRFROMSYS,
  210. pwszCustomMsg);
  211. }
  212. //--------------------------------------------------------------------
  213. // Throw up a dialog with the format "<Prefix><UserMsg><SysErrorMsg>".
  214. // <Prefix> is basically "An error was detected...run the
  215. // wizard again..." .
  216. // <UserMsg> is specified by dwMsgId and can contain "%1" which
  217. // will be replaced with pwszCustomMsg.
  218. // <SysErrorMsg> is the system message for hrCode.
  219. int
  220. CertErrorMessageBox(
  221. IN HINSTANCE hInstance,
  222. IN BOOL fUnattended,
  223. IN HWND hWnd,
  224. IN DWORD dwMsgId,
  225. IN HRESULT hrCode,
  226. IN OPTIONAL const WCHAR * pwszCustomMsg)
  227. {
  228. return CertMessageBox(
  229. hInstance,
  230. fUnattended,
  231. hWnd,
  232. dwMsgId,
  233. hrCode,
  234. MB_OK | MB_ICONERROR | CMB_REPEATWIZPREFIX,
  235. pwszCustomMsg);
  236. }
  237. //--------------------------------------------------------------------
  238. // Throw up a dialog with the format "<UserMsg><SysErrorMsg>".
  239. // <UserMsg> is specified by dwMsgId and can contain "%1" which
  240. // will be replaced with pwszCustomMsg.
  241. // <SysErrorMsg> is the system message for hrCode. It is
  242. // suppressed if a successful hrCode is specified.
  243. int
  244. CertWarningMessageBox(
  245. IN HINSTANCE hInstance,
  246. IN BOOL fUnattended,
  247. IN HWND hWnd,
  248. IN DWORD dwMsgId,
  249. IN HRESULT hrCode,
  250. IN OPTIONAL const WCHAR * pwszCustomMsg)
  251. {
  252. UINT uType=MB_OK | MB_ICONWARNING;
  253. if (SUCCEEDED(hrCode)) {
  254. uType |= CMB_NOERRFROMSYS;
  255. }
  256. return CertMessageBox(
  257. hInstance,
  258. fUnattended,
  259. hWnd,
  260. dwMsgId,
  261. hrCode,
  262. uType,
  263. pwszCustomMsg);
  264. }