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.

643 lines
15 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. resource.c
  5. Abstract:
  6. Routines that manipulate resources (strings, messages, etc).
  7. Author:
  8. Ted Miller (tedm) 6-Feb-1995
  9. Revision History:
  10. Jamie Hunter (JamieHun) Apr-28-2002
  11. Security code review
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. VOID
  16. SetDlgText(
  17. IN HWND hwndDlg,
  18. IN INT iControl,
  19. IN UINT nStartString,
  20. IN UINT nEndString
  21. )
  22. /*++
  23. Routine Description:
  24. This routine concatenates a number of string resources and does a
  25. SetWindowText() for a dialog text control.
  26. Arguments:
  27. hwndDlg - Handle to dialog window
  28. iControl - Dialog control ID to receive text
  29. nStartString - ID of first string resource to concatenate
  30. nEndString - ID of last string resource to concatenate
  31. Return Value:
  32. None.
  33. Remarks:
  34. String IDs must be consecutive.
  35. --*/
  36. {
  37. TCHAR StringBuffer[SDT_MAX_TEXT];
  38. UINT i;
  39. INT Len = 0;
  40. for(i = nStartString;
  41. ((i <= nEndString) && (Len < (SDT_MAX_TEXT - 1)));
  42. i++)
  43. {
  44. Len += LoadString(MyDllModuleHandle,
  45. i,
  46. StringBuffer + Len,
  47. SDT_MAX_TEXT - Len
  48. );
  49. }
  50. if(!Len) {
  51. StringBuffer[0] = TEXT('\0');
  52. }
  53. SetDlgItemText(hwndDlg, iControl, StringBuffer);
  54. }
  55. PTSTR
  56. MyLoadString(
  57. IN UINT StringId
  58. )
  59. /*++
  60. Routine Description:
  61. Retreive a string from the string resources of this module.
  62. Arguments:
  63. StringId - supplies string table identifier for the string.
  64. Return Value:
  65. Pointer to buffer containing string. If the string was not found
  66. or some error occurred retreiving it, this buffer will be empty.
  67. Caller can free the buffer with MyFree().
  68. If NULL is returned, out of memory.
  69. --*/
  70. {
  71. PTSTR Buffer, p;
  72. int Length, RequiredLength;
  73. //
  74. // Start out with a reasonably-sized buffer so that we'll rarely need to
  75. // grow the buffer and retry (Length is in terms of characters, not bytes).
  76. //
  77. Length = LINE_LEN;
  78. while(TRUE) {
  79. Buffer = MyMalloc(Length * sizeof(TCHAR));
  80. if(!Buffer) {
  81. return NULL;
  82. }
  83. RequiredLength = LoadString(MyDllModuleHandle,
  84. StringId,
  85. Buffer,
  86. Length
  87. );
  88. if(!RequiredLength) {
  89. *Buffer = TEXT('\0');
  90. Length = 1;
  91. break;
  92. }
  93. //
  94. // Because of the way LoadString works, there's no way to
  95. // tell for sure whether your buffer was big enough in the case where
  96. // the length returned just fits in the buffer you supplied (the API
  97. // silently truncates in this case). Thus, if RequiredLength is exactly
  98. // the size of our supplied buffer (minus terminating null, which
  99. // LoadString doesn't count), we increase the buffer size by LINE_LEN
  100. // characters and try again, to make sure we get the whole string.
  101. //
  102. if(RequiredLength < (Length - 1)) {
  103. //
  104. // Looks like we got the whole string. Set the length to be the
  105. // required length + 1 character, to accommodate the terminating
  106. // null character.
  107. //
  108. Length = RequiredLength + 1;
  109. break;
  110. } else {
  111. MyFree(Buffer);
  112. Length += LINE_LEN;
  113. }
  114. }
  115. //
  116. // Resize the buffer to its correct size. If this fails (which it shouldn't)
  117. // it's no big deal, it just means we're using a larger buffer for this string
  118. // than we need to.
  119. //
  120. if(p = MyRealloc(Buffer, Length * sizeof(TCHAR))) {
  121. Buffer = p;
  122. }
  123. return Buffer;
  124. }
  125. PTSTR
  126. FormatStringMessageV(
  127. IN UINT FormatStringId,
  128. IN va_list *ArgumentList
  129. )
  130. /*++
  131. Routine Description:
  132. Retreive a string from the string resources of this module and
  133. format it using FormatMessage.
  134. Arguments:
  135. StringId - supplies string table identifier for the string.
  136. ArgumentList - supplies list of strings to be substituted in the
  137. format string.
  138. Return Value:
  139. Pointer to buffer containing formatted message. If the string was not found
  140. or some error occurred retreiving it, this buffer will be NULL
  141. Caller can free the buffer with MyFree().
  142. If NULL is returned, out of memory.
  143. --*/
  144. {
  145. PTSTR FormatString;
  146. va_list arglist;
  147. PTSTR Message;
  148. PTSTR Return;
  149. DWORD d;
  150. //
  151. // First, load the format string.
  152. //
  153. FormatString = MyLoadString(FormatStringId);
  154. if(!FormatString) {
  155. return(NULL);
  156. }
  157. //
  158. // Now format the message using the arguements the caller passed.
  159. //
  160. d = FormatMessage(
  161. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  162. FormatString,
  163. 0,
  164. 0,
  165. (PTSTR)&Message,
  166. 0,
  167. ArgumentList
  168. );
  169. MyFree(FormatString);
  170. if(!d) {
  171. return(NULL);
  172. }
  173. //
  174. // Make duplicate using our memory system so user can free with MyFree().
  175. //
  176. Return = DuplicateString(Message);
  177. LocalFree((HLOCAL)Message);
  178. return(Return);
  179. }
  180. PTSTR
  181. FormatStringMessage(
  182. IN UINT FormatStringId,
  183. ...
  184. )
  185. /*++
  186. Routine Description:
  187. Retreive a string from the string resources of this module and
  188. format it using FormatMessage.
  189. Arguments:
  190. StringId - supplies string table identifier for the string.
  191. Return Value:
  192. Pointer to buffer containing formatted message. If the string was not found
  193. or some error occurred retreiving it, this buffer will be empty.
  194. Caller can free the buffer with MyFree().
  195. If NULL is returned, out of memory.
  196. --*/
  197. {
  198. va_list arglist;
  199. PTSTR p;
  200. va_start(arglist,FormatStringId);
  201. p = FormatStringMessageV(FormatStringId,&arglist);
  202. va_end(arglist);
  203. return(p);
  204. }
  205. PTSTR
  206. FormatStringMessageFromStringV(
  207. IN PTSTR FormatString,
  208. IN va_list *ArgumentList
  209. )
  210. /*++
  211. Routine Description:
  212. Format the input string using FormatMessage.
  213. Arguments:
  214. FormatString - supplies the format string.
  215. ArgumentList - supplies list of strings to be substituted in the
  216. format string.
  217. Return Value:
  218. Pointer to buffer containing formatted message. If some error occurred
  219. formatting the string, this buffer will be NULL.
  220. Caller can free the buffer with MyFree().
  221. If NULL is returned, out of memory/other error
  222. --*/
  223. {
  224. va_list arglist;
  225. PTSTR Message;
  226. PTSTR Return;
  227. DWORD d;
  228. //
  229. // Format the message using the arguements the caller passed.
  230. //
  231. d = FormatMessage(
  232. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  233. FormatString,
  234. 0,
  235. 0,
  236. (PTSTR)&Message,
  237. 0,
  238. ArgumentList
  239. );
  240. if(!d) {
  241. return(NULL);
  242. }
  243. //
  244. // Make duplicate using our memory system so user can free with MyFree().
  245. //
  246. Return = DuplicateString(Message);
  247. LocalFree((HLOCAL)Message);
  248. return(Return);
  249. }
  250. PTSTR
  251. FormatStringMessageFromString(
  252. IN PTSTR FormatString,
  253. ...
  254. )
  255. /*++
  256. Routine Description:
  257. Format the input string using FormatMessage.
  258. Arguments:
  259. FormatString - supplies the format string.
  260. Return Value:
  261. Pointer to buffer containing formatted message. If some error occurred
  262. formatting the string, this buffer will be empty.
  263. Caller can free the buffer with MyFree().
  264. If NULL is returned, out of memory.
  265. --*/
  266. {
  267. va_list arglist;
  268. PTSTR p;
  269. va_start(arglist,FormatString);
  270. p = FormatStringMessageFromStringV(FormatString,&arglist);
  271. va_end(arglist);
  272. return(p);
  273. }
  274. INT
  275. FormatMessageBox(
  276. IN HANDLE hinst,
  277. IN HWND hwndParent,
  278. IN UINT TextMessageId,
  279. IN PCTSTR Title,
  280. IN UINT Style,
  281. ...
  282. )
  283. /*++
  284. Routine Description:
  285. This routine formats two message strings--one containing messagebox text,
  286. and the other containing a messagebox caption. The message box is then
  287. displayed.
  288. The message ids can be either a message in this dll's message table
  289. resources or a win32 error code, in which case a description of
  290. that error is retreived from the system.
  291. Arguments:
  292. hinst - Supplies the handle of the module containing string resources to
  293. be used.
  294. hwndParent - Supplies the handle of window to be the parent of the message box.
  295. TextMessageId - Supplies message-table identifier or win32 error code
  296. for the messagebox text.
  297. TitleMessageId - Supplies message-table identifier or win32 error code
  298. for the messagebox caption.
  299. Style - Supplies style flags for the message box.
  300. ... - Supplies arguments to be inserted in the message text.
  301. Return Value:
  302. The return value is zero if there is not enough memory to create the message box, or
  303. if a failure occurred while creating the message box.
  304. If the function succeeds, the return value is one of the following menu-item values
  305. returned by the dialog box:
  306. IDABORT Abort button was selected.
  307. IDCANCEL Cancel button was selected.
  308. IDIGNORE Ignore button was selected.
  309. IDNO No button was selected.
  310. IDOK OK button was selected.
  311. IDRETRY Retry button was selected.
  312. IDYES Yes button was selected.
  313. If a message box has a Cancel button, the function returns the IDCANCEL value if
  314. either the ESC key is pressed or the Cancel button is selected. If the message box
  315. has no Cancel button, pressing ESC has no effect.
  316. --*/
  317. {
  318. va_list arglist;
  319. PTSTR Text = NULL;
  320. INT ret;
  321. //
  322. // We should never be called if we're not interactive.
  323. //
  324. MYASSERT(!(GlobalSetupFlags & (PSPGF_NONINTERACTIVE|PSPGF_UNATTENDED_SETUP)));
  325. if(GlobalSetupFlags & (PSPGF_NONINTERACTIVE|PSPGF_UNATTENDED_SETUP)) {
  326. return 0;
  327. }
  328. try {
  329. va_start(arglist, Style);
  330. Text = RetreiveAndFormatMessageV(TextMessageId, &arglist);
  331. va_end(arglist);
  332. if(Text) {
  333. //
  334. // We always beep when we display the message
  335. //
  336. MessageBeep(Style & (MB_ICONHAND|MB_ICONEXCLAMATION|MB_ICONQUESTION|MB_ICONASTERISK));
  337. ret = MessageBox(hwndParent, Text, Title, Style);
  338. } else {
  339. ret = 0;
  340. }
  341. } except(EXCEPTION_EXECUTE_HANDLER) {
  342. ret = 0;
  343. }
  344. if(Text) {
  345. MyFree(Text);
  346. }
  347. return ret;
  348. }
  349. PTSTR
  350. RetreiveAndFormatMessageV(
  351. IN UINT MessageId,
  352. IN va_list *ArgumentList
  353. )
  354. /*++
  355. Routine Description:
  356. Format a message string using a message string and caller-supplied
  357. arguments.
  358. The message id can be either a message in this dll's message table
  359. resources or a win32 error code, in which case a description of
  360. that error is retreived from the system.
  361. Arguments:
  362. MessageId - supplies message-table identifier or win32 error code
  363. for the message.
  364. ArgumentList - supplies arguments to be inserted in the message text.
  365. Return Value:
  366. Pointer to buffer containing formatted message. If the message was not found
  367. or some error occurred retreiving it, this buffer will be empty.
  368. Caller can free the buffer with MyFree().
  369. If NULL is returned, out of memory.
  370. --*/
  371. {
  372. DWORD d;
  373. PTSTR Buffer;
  374. PTSTR Message;
  375. TCHAR ModuleName[MAX_PATH];
  376. TCHAR ErrorNumber[24];
  377. PTCHAR p;
  378. PTSTR Args[2];
  379. d = FormatMessage(
  380. FORMAT_MESSAGE_ALLOCATE_BUFFER
  381. | ((MessageId < MSG_FIRST) ?
  382. (FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS)
  383. : FORMAT_MESSAGE_FROM_HMODULE),
  384. (PVOID)MyDllModuleHandle,
  385. MessageId,
  386. MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),
  387. (PTSTR)&Buffer,
  388. 0,
  389. ArgumentList
  390. );
  391. if(!d) {
  392. if(GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
  393. return(NULL);
  394. }
  395. MYVERIFY(SUCCEEDED(StringCchPrintf(ErrorNumber,
  396. SIZECHARS(ErrorNumber),
  397. TEXT("%x"),
  398. MessageId)));
  399. Args[0] = ErrorNumber;
  400. Args[1] = ModuleName;
  401. if(GetModuleFileName(MyDllModuleHandle,ModuleName,SIZECHARS(ModuleName))) {
  402. if(p = _tcsrchr(ModuleName,TEXT('\\'))) {
  403. Args[1] = p+1;
  404. }
  405. } else {
  406. ModuleName[0] = 0;
  407. }
  408. d = FormatMessage(
  409. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  410. NULL,
  411. ERROR_MR_MID_NOT_FOUND,
  412. MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),
  413. (PTSTR)&Buffer,
  414. 0,
  415. (va_list *)Args
  416. );
  417. if(!d) {
  418. //
  419. // Give up.
  420. //
  421. return(NULL);
  422. }
  423. }
  424. //
  425. // Make duplicate using our memory system so user can free with MyFree().
  426. //
  427. Message = DuplicateString(Buffer);
  428. LocalFree((HLOCAL)Buffer);
  429. return(Message);
  430. }
  431. PTSTR
  432. RetreiveAndFormatMessage(
  433. IN UINT MessageId,
  434. ...
  435. )
  436. /*++
  437. Routine Description:
  438. Format a message string using a message string and caller-supplied
  439. arguments.
  440. The message id can be either a message in this dll's message table
  441. resources or a win32 error code, in which case a description of
  442. that error is retreived from the system.
  443. Arguments:
  444. MessageId - supplies message-table identifier or win32 error code
  445. for the message.
  446. ... - supplies arguments to be inserted in the message text.
  447. Return Value:
  448. Pointer to buffer containing formatted message. If the message was not found
  449. or some error occurred retreiving it, this buffer will be empty.
  450. Caller can free the buffer with MyFree().
  451. If NULL is returned, out of memory.
  452. --*/
  453. {
  454. va_list arglist;
  455. PTSTR p;
  456. va_start(arglist,MessageId);
  457. p = RetreiveAndFormatMessageV(MessageId,&arglist);
  458. va_end(arglist);
  459. return(p);
  460. }