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.

377 lines
9.3 KiB

  1. /////////////////////////////////////////////////////
  2. //
  3. // Fax UI utlity implementation
  4. //
  5. #include <faxutil.h>
  6. #include <Shlwapi.h>
  7. #include <tchar.h>
  8. #include <htmlhelp.h>
  9. #include <Sddl.h>
  10. #include <Shlobj.h>
  11. #include <Aclapi.h>
  12. #include <faxres.h>
  13. #include <faxreg.h>
  14. #include "..\admin\faxres\resource.h"
  15. //
  16. // Topics of the fxsadmin.chm HTML help file
  17. //
  18. #define HELP_FOLDER_SECURITY FAX_ADMIN_HELP_FILE TEXT("::/FaxS_H_SecureFolder.htm")
  19. WNDPROC g_pfOrigWndProc = NULL; // original window procedure
  20. TCHAR* g_tszHelpTopic = NULL; // help topic
  21. LRESULT
  22. CALLBACK
  23. HlpSubclassProc(
  24. HWND hwnd, // handle to window
  25. UINT uMsg, // message identifier
  26. WPARAM wParam, // first message parameter
  27. LPARAM lParam // second message parameter
  28. )
  29. /*++
  30. Routine Description:
  31. Window procedure
  32. Displays HTML help topic when receives WM_HELP message
  33. --*/
  34. {
  35. if(WM_HELP == uMsg)
  36. {
  37. DEBUG_FUNCTION_NAME(TEXT("MgsHlpWindowProc(WM_HELP)"));
  38. DWORD dwRes;
  39. SetLastError(0);
  40. HtmlHelp(hwnd, g_tszHelpTopic, HH_DISPLAY_TOPIC, NULL);
  41. dwRes = GetLastError();
  42. if(dwRes != ERROR_SUCCESS)
  43. {
  44. DebugPrintEx(DEBUG_ERR, TEXT("HtmlHelp failed with %ld."), dwRes);
  45. }
  46. return 0;
  47. }
  48. if(g_pfOrigWndProc)
  49. {
  50. return CallWindowProc(g_pfOrigWndProc, hwnd, uMsg, wParam, lParam);
  51. }
  52. return 0;
  53. }
  54. int
  55. FaxMsgBox(
  56. HWND hWnd,
  57. DWORD dwMsgId,
  58. UINT uType
  59. )
  60. /*++
  61. Routine Description:
  62. MessageBox wrapper function
  63. Uses constant caption IDS_FAX_MESSAGE_BOX_TITLE "Microsoft Fax"
  64. Arguments:
  65. hWnd [in] - notification window
  66. dwMsgId [in] - message resource ID from FxsRes.dll
  67. uType [in] - MessageBox type
  68. Return Value:
  69. MessageBox return value
  70. --*/
  71. {
  72. DWORD dwRes;
  73. int nRes = IDABORT;
  74. TCHAR szTitle[MAX_PATH] = {0};
  75. TCHAR szMessage[MAX_PATH*2] = {0};
  76. DEBUG_FUNCTION_NAME(TEXT("FaxMsgBox"));
  77. //
  78. // Load strings
  79. //
  80. HINSTANCE hResource = GetResInstance(GetModuleHandle(NULL));
  81. if(!hResource)
  82. {
  83. dwRes = GetLastError();
  84. DebugPrintEx(DEBUG_ERR, TEXT("GetResInstance failed with %ld."), dwRes);
  85. return nRes;
  86. }
  87. if(!LoadString(hResource, IDS_FAX_MESSAGE_BOX_TITLE, szTitle, ARR_SIZE(szTitle)-1))
  88. {
  89. dwRes = GetLastError();
  90. DebugPrintEx(DEBUG_ERR, TEXT("LoadString failed with %ld."), dwRes);
  91. return nRes;
  92. }
  93. if(!LoadString(hResource, dwMsgId, szMessage, ARR_SIZE(szMessage)-1))
  94. {
  95. dwRes = GetLastError();
  96. DebugPrintEx(DEBUG_ERR, TEXT("LoadString failed with %ld."), dwRes);
  97. return nRes;
  98. }
  99. //
  100. // Open the message box
  101. //
  102. nRes = AlignedMessageBox(hWnd, szMessage, szTitle, uType);
  103. return nRes;
  104. } // FaxMsgBox
  105. int
  106. FaxMessageBoxWithHelp(
  107. HWND hWnd,
  108. DWORD dwMsgId,
  109. TCHAR* tszHelpTopic,
  110. UINT uType
  111. )
  112. /*++
  113. Routine Description:
  114. MessageBox wrapper function
  115. Creates helper window to handle WM_HELP message
  116. Arguments:
  117. hWnd [in] - parent window handle
  118. dwMsgId [in] - message resource ID from FxsRes.dll
  119. tszHelpTopic [in] - HTML help topic
  120. uType [in] - MessageBox type
  121. Return Value:
  122. MessageBox return value
  123. --*/
  124. {
  125. DEBUG_FUNCTION_NAME(TEXT("FaxMessageBoxWithHelp"));
  126. DWORD dwRes;
  127. int nRes = IDABORT;
  128. if(GetWindowLongPtr(hWnd, GWL_STYLE) & WS_CHILD)
  129. {
  130. //
  131. // A child window doesn't receive WM_HELP message
  132. // get handle to its parent.
  133. //
  134. hWnd = GetParent(hWnd);
  135. }
  136. //
  137. // Subclass parent window in order to catch WM_HELP message
  138. //
  139. g_pfOrigWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)HlpSubclassProc);
  140. if(!g_pfOrigWndProc)
  141. {
  142. dwRes = GetLastError();
  143. DebugPrintEx(DEBUG_ERR, TEXT("SetWindowLongPtr failed with %ld."), dwRes);
  144. return nRes;
  145. }
  146. g_tszHelpTopic = tszHelpTopic;
  147. //
  148. // Open the message box
  149. //
  150. nRes = FaxMsgBox(hWnd, dwMsgId, uType | MB_HELP);
  151. g_tszHelpTopic = NULL;
  152. //
  153. // Remove the subclass from the parent window
  154. //
  155. if(!SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)g_pfOrigWndProc))
  156. {
  157. dwRes = GetLastError();
  158. DebugPrintEx(DEBUG_ERR, TEXT("SetWindowLongPtr failed with %ld."), dwRes);
  159. }
  160. g_pfOrigWndProc = NULL;
  161. return nRes;
  162. } // FaxMessageBoxWithHelp
  163. DWORD
  164. AskUserAndAdjustFaxFolder(
  165. HWND hWnd,
  166. TCHAR* szServerName,
  167. TCHAR* szPath,
  168. DWORD dwError
  169. )
  170. /*++
  171. Routine Description:
  172. This function tries to create and adjust access rights for a use supplied path
  173. after the fax server failed to accept this path
  174. Arguments:
  175. hWnd [in] - Parent window
  176. szServerName [in] - Fax server name
  177. szPath [in] - Desired path
  178. dwError [in] - Error code returned by fax server
  179. Return Value:
  180. Win32 error code
  181. Special meaning:
  182. ERROR_SUCCESS - the folder has been created and adjusted
  183. ERROR_BAD_PATHNAME - an error message box has been shown to the user
  184. --*/
  185. {
  186. DWORD dwRes = ERROR_SUCCESS;
  187. DEBUG_FUNCTION_NAME(TEXT("AskUserAndAdjustFaxFolder"));
  188. if(dwError == ERROR_BAD_NETPATH ||
  189. dwError == ERROR_BAD_PATHNAME ||
  190. dwError == ERROR_DIRECTORY ||
  191. dwError == ERROR_NOT_READY ||
  192. szPath == NULL ||
  193. PathIsRelative(szPath))
  194. {
  195. //
  196. // The path is not valid
  197. //
  198. FaxMsgBox(hWnd, IDS_PATH_NOT_VALID, MB_OK | MB_ICONERROR);
  199. return ERROR_BAD_PATHNAME;
  200. }
  201. if(dwError == FAX_ERR_DIRECTORY_IN_USE)
  202. {
  203. //
  204. // The path is already used for fax archive or queue
  205. //
  206. FaxMsgBox(hWnd, IDS_FAX_ERR_DIRECTORY_IN_USE, MB_OK | MB_ICONERROR);
  207. return ERROR_BAD_PATHNAME;
  208. }
  209. if(dwError == FAX_ERR_FILE_ACCESS_DENIED)
  210. {
  211. //
  212. // The fax service has no access to the folder
  213. //
  214. FaxMessageBoxWithHelp(hWnd,
  215. IDS_FOLDER_ACCESS_DENIED,
  216. HELP_FOLDER_SECURITY,
  217. MB_OK | MB_ICONERROR);
  218. return ERROR_BAD_PATHNAME;
  219. }
  220. if(dwError != ERROR_PATH_NOT_FOUND &&
  221. dwError != ERROR_FILE_NOT_FOUND)
  222. {
  223. return dwError;
  224. }
  225. if(!IsLocalMachineName(szServerName))
  226. {
  227. //
  228. // Remote server
  229. //
  230. FaxMessageBoxWithHelp(hWnd,
  231. IDS_PATH_NOT_FOUND_REMOTE_FAX,
  232. HELP_FOLDER_SECURITY,
  233. MB_OK | MB_ICONERROR);
  234. return ERROR_BAD_PATHNAME;
  235. }
  236. //
  237. // Check for environment strings
  238. //
  239. if(StrChr(szPath, _T('%')))
  240. {
  241. //
  242. // Path contains environment variables
  243. //
  244. FaxMessageBoxWithHelp(hWnd,
  245. IDS_PATH_NOT_FOUND_ENV_VAR,
  246. HELP_FOLDER_SECURITY,
  247. MB_OK | MB_ICONERROR);
  248. return ERROR_BAD_PATHNAME;
  249. }
  250. if(PathIsNetworkPath(szPath))
  251. {
  252. FaxMessageBoxWithHelp(hWnd,
  253. IDS_PATH_NOT_FOUND_REMOTE_PATH,
  254. HELP_FOLDER_SECURITY,
  255. MB_OK | MB_ICONERROR);
  256. return ERROR_BAD_PATHNAME;
  257. }
  258. //
  259. // Suggest to create / adjust path
  260. //
  261. if(IDYES != FaxMessageBoxWithHelp(hWnd,
  262. IDS_PATH_NOT_FOUND_ASK_CREATE,
  263. HELP_FOLDER_SECURITY,
  264. MB_YESNO | MB_ICONQUESTION))
  265. {
  266. return ERROR_BAD_PATHNAME;
  267. }
  268. PSECURITY_DESCRIPTOR pSD = NULL;
  269. if(!ConvertStringSecurityDescriptorToSecurityDescriptor(SD_FAX_FOLDERS,
  270. SDDL_REVISION_1,
  271. &pSD,
  272. NULL))
  273. {
  274. dwRes = GetLastError();
  275. DebugPrintEx(DEBUG_ERR, TEXT("ConvertStringSecurityDescriptorToSecurityDescriptor failed with %ld."), dwRes);
  276. return dwRes;
  277. }
  278. //
  279. // Create the folder
  280. //
  281. SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), pSD, FALSE};
  282. dwRes = SHCreateDirectoryEx(hWnd, szPath, &sa);
  283. if(ERROR_SUCCESS != dwRes)
  284. {
  285. DebugPrintEx(DEBUG_ERR, TEXT("SHCreateDirectoryEx failed with %ld."), dwRes);
  286. if(dwRes == ERROR_BAD_PATHNAME)
  287. {
  288. FaxMsgBox(hWnd, IDS_PATH_NOT_VALID, MB_OK | MB_ICONERROR);
  289. }
  290. if(dwRes == ERROR_CANCELLED)
  291. {
  292. //
  293. // The user canceled the operation. No need to popup again.
  294. //
  295. dwRes = ERROR_BAD_PATHNAME;
  296. }
  297. goto exit;
  298. }
  299. exit:
  300. if(pSD)
  301. {
  302. LocalFree(pSD);
  303. }
  304. return dwRes;
  305. } // AskUserAndAdjustFaxFolder