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.

213 lines
6.5 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. #include "uemapp.h"
  4. #define MAXRCSTRING 514
  5. // Major hack follows to get this to work with the DEBUG alloc/free -- on NT
  6. // Local and Global heap functions evaluate to the same heap. The problem
  7. // here is that LocalFree gets mapped to DebugLocalFree, but when we
  8. // call FormatMessage, the buffer is not allocated through DebugLocalAlloc,
  9. // so it dies.
  10. //
  11. #ifdef DEBUG
  12. #undef LocalFree
  13. #define LocalFree GlobalFree
  14. #endif
  15. // this will check to see if lpcstr is a resource id or not. if it
  16. // is, it will return a LPSTR containing the loaded resource.
  17. // the caller must LocalFree this lpstr. if pszText IS a string, it
  18. // will return pszText
  19. //
  20. // returns:
  21. // pszText if it is already a string
  22. // or
  23. // LocalAlloced() memory to be freed with LocalFree
  24. // if pszRet != pszText free pszRet
  25. LPTSTR WINAPI ResourceCStrToStr(HINSTANCE hInst, LPCTSTR pszText)
  26. {
  27. TCHAR szTemp[MAXRCSTRING];
  28. LPTSTR pszRet = NULL;
  29. if (!IS_INTRESOURCE(pszText))
  30. return (LPTSTR)pszText;
  31. if (LOWORD((DWORD_PTR)pszText) && LoadString(hInst, LOWORD((DWORD_PTR)pszText), szTemp, ARRAYSIZE(szTemp)))
  32. {
  33. size_t cch = lstrlen(szTemp) + 1;
  34. pszRet = LocalAlloc(LPTR, cch * SIZEOF(TCHAR));
  35. if (pszRet)
  36. StringCchCopy(pszRet, cch, szTemp);
  37. }
  38. return pszRet;
  39. }
  40. LPSTR ResourceCStrToStrA(HINSTANCE hInst, LPCSTR pszText)
  41. {
  42. CHAR szTemp[MAXRCSTRING];
  43. LPSTR pszRet = NULL;
  44. if (!IS_INTRESOURCE(pszText))
  45. return (LPSTR)pszText;
  46. if (LOWORD((DWORD_PTR)pszText) && LoadStringA(hInst, LOWORD((DWORD_PTR)pszText), szTemp, ARRAYSIZE(szTemp)))
  47. {
  48. size_t cch = (lstrlenA(szTemp) + 1);
  49. pszRet = LocalAlloc(LPTR, cch * SIZEOF(CHAR));
  50. if (pszRet)
  51. StringCchCopyA(pszRet, cch, szTemp);
  52. }
  53. return pszRet;
  54. }
  55. LPTSTR _ConstructMessageString(HINSTANCE hInst, LPCTSTR pszMsg, va_list *ArgList)
  56. {
  57. LPTSTR pszRet;
  58. LPTSTR pszRes = ResourceCStrToStr(hInst, pszMsg);
  59. if (!pszRes)
  60. {
  61. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: Failed to load string template"));
  62. return NULL;
  63. }
  64. if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  65. pszRes, 0, 0, (LPTSTR)&pszRet, 0, ArgList))
  66. {
  67. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: FormatMessage failed %d"),GetLastError());
  68. DebugMsg(DM_ERROR, TEXT(" pszRes = %s"), pszRes );
  69. DebugMsg(DM_ERROR, !IS_INTRESOURCE(pszMsg) ?
  70. TEXT(" pszMsg = %s") :
  71. TEXT(" pszMsg = 0x%x"), pszMsg );
  72. pszRet = NULL;
  73. }
  74. if (pszRes != pszMsg)
  75. LocalFree(pszRes);
  76. return pszRet; // free with LocalFree()
  77. }
  78. LPSTR _ConstructMessageStringA(HINSTANCE hInst, LPCSTR pszMsg, va_list *ArgList)
  79. {
  80. LPSTR pszRet;
  81. LPSTR pszRes = ResourceCStrToStrA(hInst, pszMsg);
  82. if (!pszRes)
  83. {
  84. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: Failed to load string template"));
  85. return NULL;
  86. }
  87. if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  88. pszRes, 0, 0, (LPSTR)&pszRet, 0, ArgList))
  89. {
  90. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: FormatMessage failed %d"),GetLastError());
  91. DebugMsg(DM_ERROR, TEXT(" pszRes = %S"), pszRes );
  92. DebugMsg(DM_ERROR, !IS_INTRESOURCE(pszMsg) ?
  93. TEXT(" pszMsg = %s") :
  94. TEXT(" pszMsg = 0x%x"), pszMsg );
  95. pszRet = NULL;
  96. }
  97. if (pszRes != pszMsg)
  98. LocalFree(pszRes);
  99. return pszRet; // free with LocalFree()
  100. }
  101. // NOTE: ShellMessageBoxW has been re-implemented in shlwapi, so shell32 redirects that api there
  102. // Shlwapi doesn't need an A version (because it's in shell32), so we're leaving this code here...
  103. //
  104. int WINCAPI ShellMessageBoxA(HINSTANCE hInst, HWND hWnd, LPCSTR pszMsg, LPCSTR pszTitle, UINT fuStyle, ...)
  105. {
  106. LPSTR pszText;
  107. int result;
  108. CHAR szBuffer[80];
  109. va_list ArgList;
  110. // BUG 95214
  111. #ifdef DEBUG
  112. IUnknown* punk = NULL;
  113. if (SUCCEEDED(SHGetThreadRef(&punk)) && punk)
  114. {
  115. ASSERTMSG(hWnd != NULL, "shell32\\msgbox.c : ShellMessageBoxA - Caller should either be not under a browser or should have a parent hwnd");
  116. punk->lpVtbl->Release(punk);
  117. }
  118. #endif
  119. if (!IS_INTRESOURCE(pszTitle))
  120. {
  121. // do nothing
  122. }
  123. else if (LoadStringA(hInst, LOWORD((DWORD_PTR)pszTitle), szBuffer, ARRAYSIZE(szBuffer)))
  124. {
  125. // Allow this to be a resource ID or NULL to specifiy the parent's title
  126. pszTitle = szBuffer;
  127. }
  128. else if (hWnd)
  129. {
  130. // Grab the title of the parent
  131. GetWindowTextA(hWnd, szBuffer, ARRAYSIZE(szBuffer));
  132. //
  133. // we would rather not use the "Desktop" as our title,
  134. // but sometimes that is the window that is used, and we dont
  135. // have a better title. callers should review to make sure that
  136. // they want "Desktop" as the title to the dialog in
  137. // the case that the hwnd passed in is the desktop window.
  138. //
  139. if (!lstrcmpA(szBuffer, "Program Manager"))
  140. {
  141. LoadStringA(HINST_THISDLL, IDS_DESKTOP, szBuffer, ARRAYSIZE(szBuffer));
  142. pszTitle = szBuffer;
  143. DebugMsg(TF_WARNING, TEXT("No caption for SHMsgBox() on desktop"));
  144. }
  145. else
  146. pszTitle = szBuffer;
  147. }
  148. else
  149. {
  150. pszTitle = "";
  151. }
  152. va_start(ArgList, fuStyle);
  153. pszText = _ConstructMessageStringA(hInst, pszMsg, &ArgList);
  154. va_end(ArgList);
  155. if (pszText)
  156. {
  157. result = MessageBoxA(hWnd, pszText, pszTitle, fuStyle | MB_SETFOREGROUND);
  158. LocalFree(pszText);
  159. }
  160. else
  161. {
  162. DebugMsg(DM_ERROR, TEXT("smb: Not enough memory to put up dialog."));
  163. result = -1; // memory failure
  164. }
  165. return result;
  166. }
  167. //
  168. // returns:
  169. // pointer to formatted string, free this with SHFree() (not Free())
  170. //
  171. LPTSTR WINCAPI ShellConstructMessageString(HINSTANCE hInst, LPCTSTR pszMsg, ...)
  172. {
  173. LPTSTR pszRet;
  174. va_list ArgList;
  175. va_start(ArgList, pszMsg);
  176. pszRet = _ConstructMessageString(hInst, pszMsg, &ArgList);
  177. va_end(ArgList);
  178. return pszRet; // free with SHFree()
  179. }