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.

371 lines
15 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /***************************************************************************/
  4. /***** Common Library Component - File Management - 1 **********************/
  5. /***************************************************************************/
  6. INT_PTR APIENTRY ErrDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  7. /*
  8. ** Purpose:
  9. ** Sets Silent Mode.
  10. ** Arguments:
  11. ** fMode: new setting for Silent Mode.
  12. ** Returns:
  13. ** The old mode setting.
  14. */
  15. BOOL APIENTRY FSetSilent(fMode)
  16. BOOL fMode;
  17. {
  18. BOOL fOld = fSilentSystem;
  19. fSilentSystem = fMode;
  20. return(fOld);
  21. }
  22. /*
  23. ** Purpose:
  24. ** Gets current Silent Mode.
  25. ** Arguments:
  26. ** none.
  27. ** Returns:
  28. ** The current mode setting.
  29. */
  30. BOOL APIENTRY FGetSilent(VOID)
  31. {
  32. return(fSilentSystem);
  33. }
  34. typedef struct tagETABELEM {
  35. #if DBG
  36. unsigned ArgumentCount;
  37. GRC GRC;
  38. #endif
  39. WORD ResourceID;
  40. BOOL ForceNonCritical;
  41. } ETABELEM;
  42. #if DBG
  43. #define ETABLE_ELEM(grc,ResID,cArgs,f) { cArgs,grc,ResID,f }
  44. #else
  45. #define ETABLE_ELEM(grc,ResID,cArgs,f) { ResID,f }
  46. #endif
  47. // keep the following table in sync with shellrc.rc (esp. arg counts)
  48. ETABELEM ErrorTable[] = {
  49. // |error code being |resource ID for text |required # of |whether to force
  50. // |reported to the |that comprises the |supplemental |non-critical err
  51. // |error handler |sprintf format string |text strings |
  52. // | |for this error |for insertion |
  53. // | | |into message |
  54. ETABLE_ELEM(grcOkay ,0 ,0 ,FALSE),
  55. ETABLE_ELEM(grcNotOkay ,0 ,0 ,FALSE),
  56. ETABLE_ELEM(grcOutOfMemory ,IDS_ERROR_OOM ,0 ,FALSE),
  57. ETABLE_ELEM(grcInvalidStruct ,0 ,0 ,FALSE),
  58. ETABLE_ELEM(grcOpenFileErr ,IDS_ERROR_OPENFILE ,1 ,TRUE ),
  59. ETABLE_ELEM(grcCreateFileErr ,IDS_ERROR_CREATEFILE ,1 ,TRUE ),
  60. ETABLE_ELEM(grcReadFileErr ,IDS_ERROR_READFILE ,1 ,TRUE ),
  61. ETABLE_ELEM(grcWriteFileErr ,IDS_ERROR_WRITEFILE ,1 ,TRUE ),
  62. ETABLE_ELEM(grcRemoveFileErr ,IDS_ERROR_REMOVEFILE ,1 ,TRUE ),
  63. ETABLE_ELEM(grcRenameFileErr ,IDS_ERROR_RENAMEFILE ,2 ,TRUE ),
  64. ETABLE_ELEM(grcReadDiskErr ,IDS_ERROR_READDISK ,1 ,TRUE ),
  65. ETABLE_ELEM(grcCreateDirErr ,IDS_ERROR_CREATEDIR ,1 ,TRUE ),
  66. ETABLE_ELEM(grcRemoveDirErr ,IDS_ERROR_REMOVEDIR ,1 ,TRUE ),
  67. ETABLE_ELEM(grcBadINF ,IDS_ERROR_GENERALINF ,1 ,FALSE),
  68. ETABLE_ELEM(grcINFBadSectionLabel ,IDS_ERROR_INFBADSECTION ,1 ,FALSE),
  69. ETABLE_ELEM(grcINFBadLine ,IDS_ERROR_INFBADLINE ,1 ,FALSE),
  70. ETABLE_ELEM(grcINFBadKey ,IDS_ERROR_GENERALINF ,1 ,FALSE),
  71. ETABLE_ELEM(grcCloseFileErr ,IDS_ERROR_CLOSEFILE ,1 ,TRUE ),
  72. ETABLE_ELEM(grcChangeDirErr ,IDS_ERROR_CHANGEDIR ,1 ,TRUE ),
  73. ETABLE_ELEM(grcINFSrcDescrSect ,IDS_ERROR_INFSMDSECT ,1 ,FALSE),
  74. ETABLE_ELEM(grcTooManyINFKeys ,IDS_ERROR_INFXKEYS ,1 ,FALSE),
  75. ETABLE_ELEM(grcWriteInf ,IDS_ERROR_WRITEINF ,1 ,FALSE),
  76. ETABLE_ELEM(grcInvalidPoer ,IDS_ERROR_INVALIDPOER ,0 ,FALSE),
  77. ETABLE_ELEM(grcINFMissingLine ,IDS_ERROR_INFMISSINGLINE ,2 ,FALSE),
  78. ETABLE_ELEM(grcINFBadFDLine ,IDS_ERROR_INFBADFDLINE ,2 ,FALSE),
  79. ETABLE_ELEM(grcINFBadRSLine ,IDS_ERROR_INFBADRSLINE ,0 ,FALSE),
  80. ETABLE_ELEM(grcInvalidPathErr ,IDS_ERROR_INVALIDPATH ,2 ,TRUE ),
  81. ETABLE_ELEM(grcWriteIniValueErr ,IDS_ERROR_WRITEINIVALUE ,3 ,TRUE ),
  82. ETABLE_ELEM(grcReplaceIniValueErr ,IDS_ERROR_REPLACEINIVALUE ,3 ,TRUE ),
  83. ETABLE_ELEM(grcIniValueTooLongErr ,IDS_ERROR_INIVALUETOOLONG ,0 ,TRUE ),
  84. ETABLE_ELEM(grcDDEInitErr ,IDS_ERROR_DDEINIT ,0 ,TRUE ),
  85. ETABLE_ELEM(grcDDEExecErr ,IDS_ERROR_DDEEXEC ,1 ,TRUE ),
  86. ETABLE_ELEM(grcBadWinExeFileFormatErr,IDS_ERROR_BADWINEXEFILEFORMAT,1 ,TRUE ),
  87. ETABLE_ELEM(grcResourceTooLongErr ,IDS_ERROR_RESOURCETOOLONG ,1 ,TRUE ),
  88. ETABLE_ELEM(grcMissingSysIniSectionErr,IDS_ERROR_MISSINGSYSINISECTION,2 ,TRUE ),
  89. ETABLE_ELEM(grcDecompGenericErr ,IDS_ERROR_DECOMPGENERIC ,1 ,TRUE ),
  90. ETABLE_ELEM(grcDecompUnknownAlgErr ,IDS_ERROR_DECOMPUNKNOWNALG ,2 ,TRUE ),
  91. ETABLE_ELEM(grcMissingResourceErr ,IDS_ERROR_MISSINGRESOURCE ,1 ,TRUE ),
  92. ETABLE_ELEM(grcLibraryLoadErr ,IDS_ERROR_LOADLIBRARY ,1 ,TRUE ),
  93. ETABLE_ELEM(grcBadLibEntry ,IDS_ERROR_BADLIBENTRY ,1 ,TRUE ),
  94. ETABLE_ELEM(grcApplet ,IDS_ERROR_INVOKEAPPLET ,1 ,TRUE ),
  95. ETABLE_ELEM(grcExternal ,IDS_ERROR_EXTERNALERROR ,2 ,TRUE ),
  96. ETABLE_ELEM(grcSpawn ,IDS_ERROR_SPAWN ,1 ,TRUE ),
  97. ETABLE_ELEM(grcDiskFull ,IDS_ERROR_DISKFULL ,0 ,TRUE ),
  98. ETABLE_ELEM(grcDDEAddItem ,IDS_ERROR_DDEADDITEM ,2 ,TRUE ),
  99. ETABLE_ELEM(grcDDERemoveItem ,IDS_ERROR_DDEREMOVEITEM ,2 ,TRUE ),
  100. ETABLE_ELEM(grcINFMissingSection ,IDS_ERROR_INFMISSINGSECT ,2 ,FALSE),
  101. ETABLE_ELEM(grcRunTimeParseErr ,IDS_ERROR_RUNTIMEPARSE ,2 ,FALSE),
  102. ETABLE_ELEM(grcOpenSameFileErr ,IDS_ERROR_OPENSAMEFILE ,1 ,TRUE ),
  103. ETABLE_ELEM(grcGetVolInfo ,IDS_ERROR_GETVOLINFO ,2 ,TRUE ),
  104. ETABLE_ELEM(grcGetFileSecurity ,IDS_ERROR_GETFILESECURITY ,1 ,TRUE ),
  105. ETABLE_ELEM(grcSetFileSecurity ,IDS_ERROR_SETFILESECURITY ,1 ,TRUE ),
  106. ETABLE_ELEM(grcVerifyFileErr ,IDS_ERROR_VERIFYFILE ,1 ,TRUE )
  107. };
  108. /*
  109. ** Purpose:
  110. ** Handles an Out Of Memory Error.
  111. ** Arguments:
  112. ** hwndParent: handle to window to pass to message boxes.
  113. ** Returns:
  114. ** fTrue if the user pressed RETRY (eg thinks it was handled).
  115. ** fFalse if it could not be handled or the user pressed ABORT.
  116. */
  117. BOOL APIENTRY FHandleOOM(hwndParent)
  118. HWND hwndParent;
  119. {
  120. return(EercErrorHandler(hwndParent, grcOutOfMemory, fTrue, 0, 0, 0) ==
  121. eercRetry);
  122. }
  123. /*
  124. ** Purpose:
  125. ** Handles an error by using a message box. grcNotOkay is too
  126. ** general and never produces a MessageBox, but returns either
  127. ** eercAbort or eercIgnore depending on fCritical.
  128. ** Arguments:
  129. ** hwndParent: handle to window to pass to message boxes.
  130. ** grc: type of error to handle (cannot be grcOkay).
  131. ** fCritical: whether the failed operation can be ignored.
  132. ** sz1, sz2, sz3: supplemental information to display in MessageBox.
  133. ** case grcOutOfMemory: none
  134. ** case grcOpenFileErr: sz1 = filename
  135. ** case grcCreateFileErr: sz1 = filename
  136. ** case grcReadFileErr: sz1 = filename
  137. ** case grcWriteFileErr: sz1 = filename
  138. ** case grcRemoveFileErr: sz1 = filename
  139. ** case grcRenameFileErr: sz1 = old filename, sz2 = new filename
  140. ** case grcReadDiskErr: sz1 = disk
  141. ** case grcCreateDirErr: sz1 = dirname
  142. ** case grcRemoveDirErr: sz1 = dirname
  143. ** case grcBadINF: sz1 = INF filename
  144. ** case grcINFBadKey: sz1 = INF filename
  145. ** case grcINFBadSectionLabel: sz1 = INF filename
  146. ** case grcINFBadLine: sz1 = INF filename
  147. ** case grcTooManyINFKeys: sz1 = INF filename
  148. ** case grcINFSrcDescrSect: sz1 = INF filename
  149. ** case grcWriteInf: sz1 = INF filename
  150. ** case grcInvalidPoer: none
  151. ** case grcINFMissingLine: sz1 = INF filename , sz2 = INF Section
  152. ** case grcINFMissingSection: sz1 = INF filename , sz2 = INF Section
  153. ** case grcINFBadFDLine: sz1 = INF filename , sz2 = INF Section
  154. ** case grcLibraryLoadErr: sz1 = library pathname
  155. ** case grcBadLibEntry: sz1 = entry point name
  156. ** case grcApplet: sz1 = library pathname
  157. ** case grcExternal: sz1 = entry point, sz2 = text returned from dll
  158. ** case grcRunTimeParseErr: sz1 = INF filename , sz2 = INF Line
  159. ** case grcOpenSameFileErr: sz1 = INF filename
  160. ** Notes:
  161. ** Action depends on the the global variable fSilentSystem.
  162. ** Returns:
  163. ** eercAbort if the caller should abort its execution.
  164. ** eercRetry if the caller should retry the operation.
  165. ** eercIgnore if the caller should fail this non-critical operation
  166. ** but continue with the next.
  167. **
  168. ***************************************************************************/
  169. EERC __cdecl EercErrorHandler(HWND hwndParent,GRC grc,BOOL fCritical,...)
  170. {
  171. EERC eerc;
  172. SZ szMessage = NULL;
  173. INT_PTR intRet;
  174. SZ szTemplate,
  175. szCritErrTemplate,
  176. szNonCritErrTemplate ;
  177. va_list arglist;
  178. #if DBG
  179. unsigned arg;
  180. #endif
  181. CHP rgchBufTmpLong[256];
  182. HWND aw;
  183. //
  184. // Get rid of annoying critical errors
  185. //
  186. if(ErrorTable[grc].ForceNonCritical) {
  187. fCritical = FALSE;
  188. }
  189. szTemplate = fCritical ? "CritErr" : "NonCritErr";
  190. eerc = fCritical ? eercAbort : eercIgnore;
  191. //
  192. // See if there are non-empty global overrides to the standard
  193. // error dialog templates.
  194. //
  195. szCritErrTemplate = SzFindSymbolValueInSymTab("!STF_TEMPLATE_CRITERR");
  196. szNonCritErrTemplate = SzFindSymbolValueInSymTab("!STF_TEMPLATE_NONCRITERR");
  197. if ( fCritical && szCritErrTemplate && strlen( szCritErrTemplate ) )
  198. {
  199. szTemplate = szCritErrTemplate ;
  200. }
  201. else
  202. if ( ! fCritical && szNonCritErrTemplate && strlen( szNonCritErrTemplate ) )
  203. {
  204. szTemplate = szNonCritErrTemplate ;
  205. }
  206. Assert(grc <= grcLast);
  207. Assert((grc != grcOkay) && (grc != grcInvalidStruct));
  208. if (fSilentSystem || grc == grcNotOkay || grc == grcCloseFileErr) {
  209. return(eerc);
  210. }
  211. if (grc != grcOutOfMemory) {
  212. while ((szMessage = (SZ)SAlloc((CB)1024)) == (SZ)NULL) {
  213. if (EercErrorHandler(hwndParent, grcOutOfMemory, fTrue, 0, 0, 0)
  214. == eercAbort) {
  215. return(eerc); /* REVIEW eercAbort? */
  216. }
  217. *szMessage = '\0';
  218. }
  219. }
  220. // debug sanity checks.
  221. Assert(ErrorTable[grc].GRC == grc);
  222. Assert(ErrorTable[grc].ResourceID); // otherwise the error should have
  223. // been handled by code above
  224. EvalAssert(LoadString(hInst,ErrorTable[grc].ResourceID,rgchBufTmpLong,255));
  225. if(grc == grcOutOfMemory) {
  226. szMessage = rgchBufTmpLong;
  227. } else {
  228. va_start(arglist,fCritical);
  229. #if DBG
  230. for(arg=0; arg<ErrorTable[grc].ArgumentCount; arg++) {
  231. ChkArg(va_arg(arglist,SZ) != NULL, (USHORT)(3+arg), eerc);
  232. }
  233. va_start(arglist,fCritical);
  234. #endif
  235. wvsprintf(szMessage,rgchBufTmpLong,arglist);
  236. va_end(arglist);
  237. }
  238. AssertRet(szMessage != (SZ)NULL, eerc);
  239. MessageBeep(0);
  240. //
  241. // Make sure setup / active dialog in setup is in the foreground
  242. //
  243. aw = GetLastActivePopup( hWndShell );
  244. if ( aw == NULL ) {
  245. aw = hWndShell;
  246. }
  247. SetForegroundWindow( aw );
  248. //
  249. // Put up the error dialog box
  250. //
  251. if(aw == hWndShell) {
  252. ShowOwnedPopups(aw,FALSE);
  253. }
  254. if((intRet = DialogBoxParam(hInst,(LPCSTR)szTemplate, aw,(DLGPROC)ErrDlgProc,(LPARAM)szMessage)) == -1) {
  255. LoadString(hInst,IDS_ERROR_OOM,rgchBufTmpLong,255);
  256. LoadString(hInst,IDS_ERROR_DIALOGCAPTION,rgchBufTmpShort,63);
  257. MessageBox(aw, rgchBufTmpLong, rgchBufTmpShort,
  258. MB_ICONHAND | MB_SYSTEMMODAL);
  259. if (grc != grcOutOfMemory) {
  260. SFree(szMessage);
  261. }
  262. if(aw == hWndShell) {
  263. ShowOwnedPopups(aw,TRUE);
  264. }
  265. return(eerc);
  266. } else {
  267. if(aw == hWndShell) {
  268. ShowOwnedPopups(aw,TRUE);
  269. }
  270. }
  271. if (intRet == IDIGNORE) {
  272. AssertRet(!fCritical, eercAbort);
  273. eerc = eercIgnore;
  274. } else if (intRet == IDRETRY) {
  275. eerc = eercRetry;
  276. } else {
  277. SendMessage(hWndShell,(WORD)STF_ERROR_ABORT,0,0);
  278. eerc = eercAbort;
  279. }
  280. if (grc != grcOutOfMemory) {
  281. SFree(szMessage);
  282. }
  283. return(eerc);
  284. }
  285. INT_PTR APIENTRY ErrDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  286. {
  287. int i;
  288. switch(message) {
  289. case WM_INITDIALOG:
  290. FCenterDialogOnDesktop(hDlg);
  291. SetDlgItemText(hDlg,IDC_TEXT1,(SZ)lParam);
  292. return(TRUE);
  293. case WM_CLOSE:
  294. PostMessage(
  295. hDlg,
  296. WM_COMMAND,
  297. MAKELONG(IDC_X, BN_CLICKED),
  298. 0L
  299. );
  300. return(TRUE);
  301. case WM_COMMAND:
  302. switch(LOWORD(wParam)) {
  303. case IDC_R: // retry
  304. EndDialog(hDlg,IDRETRY);
  305. return(TRUE);
  306. case IDC_X: // exit setup
  307. EvalAssert(LoadString(hInst, IDS_ERROR_DIALOGCAPTION, rgchBufTmpShort,
  308. cchpBufTmpShortMax));
  309. EvalAssert(LoadString(hInst, IDS_NOTDONE, rgchBufTmpLong,
  310. cchpBufTmpLongMax));
  311. i = MessageBox(hDlg, rgchBufTmpLong, rgchBufTmpShort,
  312. MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION | MB_APPLMODAL);
  313. if ( i == IDYES ) {
  314. EndDialog(hDlg,IDABORT);
  315. }
  316. return(TRUE);
  317. case IDC_C: // ignore
  318. EndDialog(hDlg,IDIGNORE);
  319. return(TRUE);
  320. }
  321. break;
  322. }
  323. return(FALSE);
  324. }