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.

642 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. shortcut.c
  5. Abstract:
  6. This module contains code to manipulate shortcuts.
  7. Author:
  8. Wesley Witt (wesw) 24-Jul-1997
  9. Revision History:
  10. --*/
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <shlobj.h>
  15. #include <shellapi.h>
  16. #include <commdlg.h>
  17. #include <winspool.h>
  18. #include <tchar.h>
  19. #include "faxreg.h"
  20. #include "faxutil.h"
  21. #include "prtcovpg.h"
  22. #include <shfolder.h>
  23. #include <strsafe.h>
  24. BOOL
  25. IsValidCoverPage(
  26. LPCTSTR pFileName
  27. )
  28. /*++
  29. Routine Description:
  30. Check if pFileName is a valid cover page file
  31. Arguments:
  32. pFileName - [in] file name
  33. Return Value:
  34. TRUE if pFileName is a valid cover page file
  35. FALSE otherwise
  36. --*/
  37. {
  38. HANDLE hFile;
  39. DWORD dwBytesRead;
  40. BYTE CpHeaderSignature[20]= {0x46,0x41,0x58,0x43,0x4F,0x56,0x45,0x52,0x2D,0x56,0x45,0x52,0x30,0x30,0x35,0x77,0x87,0x00,0x00,0x00};
  41. COMPOSITEFILEHEADER fileHeader = {0};
  42. hFile = SafeCreateFile(pFileName,
  43. GENERIC_READ,
  44. FILE_SHARE_READ,
  45. NULL,
  46. OPEN_EXISTING,
  47. FILE_ATTRIBUTE_NORMAL,
  48. NULL);
  49. if (hFile == INVALID_HANDLE_VALUE)
  50. {
  51. DebugPrint(( TEXT("CreateFile failed: %d\n"), GetLastError()));
  52. return FALSE;
  53. }
  54. if(!ReadFile(hFile,
  55. &fileHeader,
  56. sizeof(fileHeader),
  57. &dwBytesRead,
  58. NULL))
  59. {
  60. DebugPrint(( TEXT("ReadFile failed: %d\n"), GetLastError()));
  61. CloseHandle(hFile);
  62. return FALSE;
  63. }
  64. //
  65. // Check the 20-byte signature in the header
  66. //
  67. if ((sizeof(fileHeader) != dwBytesRead) ||
  68. memcmp(CpHeaderSignature, fileHeader.Signature, 20 ))
  69. {
  70. CloseHandle(hFile);
  71. return FALSE;
  72. }
  73. CloseHandle(hFile);
  74. return TRUE;
  75. }
  76. BOOL
  77. GetSpecialPath(
  78. IN int nFolder,
  79. OUT LPTSTR lptstrPath,
  80. IN DWORD dwPathSize
  81. )
  82. /*++
  83. Routine Description:
  84. Get a path from a CSIDL constant
  85. Arguments:
  86. nFolder - CSIDL_ constant
  87. lptstrPath - Buffer to receive the path, assume this buffer is at least MAX_PATH chars large
  88. dwPathSize - lptstrPath buffer size in TCHARs
  89. Return Value:
  90. TRUE for success.
  91. FALSE for failure.
  92. --*/
  93. {
  94. HMODULE hMod = NULL;
  95. PFNSHGETFOLDERPATH pSHGetFolderPath = NULL;
  96. HRESULT hr;
  97. BOOL fSuccess = FALSE;
  98. TCHAR strPath[MAX_PATH]= {0};
  99. DEBUG_FUNCTION_NAME(TEXT("GetSpecialPath"))
  100. // Load SHFolder.dll
  101. hMod = LoadLibrary(_T("SHFolder.dll"));
  102. if (hMod==NULL)
  103. {
  104. DebugPrintEx(DEBUG_ERR, TEXT("LoadLibrary"),GetLastError());
  105. goto exit;
  106. }
  107. // Obtain a pointer to the SHGetFolderPath function
  108. #ifdef UNICODE
  109. pSHGetFolderPath = (PFNSHGETFOLDERPATH)GetProcAddress(hMod,"SHGetFolderPathW");
  110. #else
  111. pSHGetFolderPath = (PFNSHGETFOLDERPATH)GetProcAddress(hMod,"SHGetFolderPathA");
  112. #endif
  113. if (pSHGetFolderPath==NULL)
  114. {
  115. DebugPrintEx(DEBUG_ERR, TEXT("GetProcAddress"),GetLastError());
  116. goto exit;
  117. }
  118. hr = pSHGetFolderPath(NULL,nFolder,NULL,SHGFP_TYPE_CURRENT,strPath);
  119. if (FAILED(hr))
  120. {
  121. DebugPrintEx(DEBUG_ERR, TEXT("SHGetFolderPath"),hr);
  122. SetLastError(hr);
  123. goto exit;
  124. }
  125. hr = StringCchCopy(lptstrPath,dwPathSize,strPath);
  126. if (FAILED(hr))
  127. {
  128. DebugPrintEx(DEBUG_ERR,
  129. TEXT("StringCchCopy failed (ec=%lu)"),
  130. HRESULT_CODE(hr));
  131. SetLastError(HRESULT_CODE(hr));
  132. goto exit;
  133. }
  134. fSuccess = TRUE;
  135. exit:
  136. if (hMod)
  137. {
  138. if (!FreeLibrary(hMod))
  139. {
  140. DebugPrintEx(DEBUG_ERR, TEXT("FreeLibrary"),GetLastError());
  141. }
  142. }
  143. return fSuccess;
  144. }
  145. BOOL
  146. GetClientCpDir(
  147. LPTSTR CpDir,
  148. DWORD CpDirSize
  149. )
  150. /*++
  151. Routine Description:
  152. Gets the client coverpage directory. The cover page path will return with '\'
  153. at the end: CSIDL_PERSONAL\Fax\Personal CoverPages\
  154. Arguments:
  155. CpDir - buffer to hold the coverpage dir
  156. CpDirSize - size in TCHARs of CpDir
  157. Return Value:
  158. Pointer to the client coverpage direcory.
  159. --*/
  160. {
  161. TCHAR szPath[MAX_PATH+1] = {0};
  162. TCHAR szSuffix[MAX_PATH+1] = {0};
  163. DWORD dwSuffixSize = sizeof(szSuffix);
  164. DWORD dwType;
  165. DWORD dwSuffixLen;
  166. LONG lRes;
  167. HRESULT hRes;
  168. if(!CpDir)
  169. {
  170. Assert(CpDir);
  171. return FALSE;
  172. }
  173. CpDir[0] = 0;
  174. //
  175. // get the suffix from the registry
  176. //
  177. HKEY hKey = OpenRegistryKey(HKEY_CURRENT_USER,
  178. REGKEY_FAX_SETUP,
  179. TRUE,
  180. KEY_QUERY_VALUE);
  181. if(NULL == hKey)
  182. {
  183. return FALSE;
  184. }
  185. lRes = RegQueryValueEx(hKey,
  186. REGVAL_CP_LOCATION,
  187. NULL,
  188. &dwType,
  189. (LPBYTE)szSuffix,
  190. &dwSuffixSize);
  191. RegCloseKey(hKey);
  192. if(ERROR_SUCCESS != lRes || (REG_SZ != dwType && REG_EXPAND_SZ != dwType))
  193. {
  194. //
  195. // W2K fax has REG_EXPAND_SZ type of the entry
  196. //
  197. return FALSE;
  198. }
  199. //
  200. // get personal folder location
  201. //
  202. if (!GetSpecialPath(CSIDL_PERSONAL, szPath, ARR_SIZE(szPath)))
  203. {
  204. DebugPrint(( TEXT("GetSpecialPath failed err=%ld"), GetLastError()));
  205. return FALSE;
  206. }
  207. hRes = StringCchCopy(CpDir, CpDirSize, szPath);
  208. if (FAILED(hRes))
  209. {
  210. SetLastError( HRESULT_CODE(hRes) );
  211. return FALSE;
  212. }
  213. if(szSuffix[0] != TEXT('\\'))
  214. {
  215. //
  216. // The suffix doesn't start with '\' - add it
  217. //
  218. hRes = StringCchCat (CpDir, CpDirSize, TEXT("\\"));
  219. if (FAILED(hRes))
  220. {
  221. SetLastError( HRESULT_CODE(hRes) );
  222. return FALSE;
  223. }
  224. }
  225. dwSuffixLen = lstrlen(szSuffix);
  226. if(dwSuffixLen > 0 && dwSuffixLen < ARR_SIZE(szSuffix) && szSuffix[dwSuffixLen-1] != TEXT('\\'))
  227. {
  228. //
  229. // The suffix doesn't end with '\' - add it
  230. //
  231. hRes = StringCchCat (szSuffix, ARR_SIZE(szSuffix), TEXT("\\"));
  232. if (FAILED(hRes))
  233. {
  234. SetLastError( HRESULT_CODE(hRes) );
  235. return FALSE;
  236. }
  237. }
  238. hRes = StringCchCat (CpDir, CpDirSize, szSuffix);
  239. if (FAILED(hRes))
  240. {
  241. SetLastError( HRESULT_CODE(hRes) );
  242. return FALSE;
  243. }
  244. MakeDirectory(CpDir);
  245. return TRUE;
  246. }
  247. BOOL
  248. SetClientCpDir(
  249. LPTSTR CpDir
  250. )
  251. /*++
  252. Routine Description:
  253. Sets the client coverpage directory.
  254. Arguments:
  255. CpDir - pointer to the coverpage dir
  256. Return Value:
  257. TRUE if success
  258. --*/
  259. {
  260. HKEY hKey = OpenRegistryKey(HKEY_CURRENT_USER,
  261. REGKEY_FAX_SETUP,
  262. TRUE,
  263. KEY_ALL_ACCESS);
  264. if(NULL == hKey)
  265. {
  266. return FALSE;
  267. }
  268. if(!SetRegistryString(hKey,
  269. REGVAL_CP_LOCATION,
  270. CpDir))
  271. {
  272. RegCloseKey(hKey);
  273. return FALSE;
  274. }
  275. RegCloseKey(hKey);
  276. return TRUE;
  277. }
  278. BOOL
  279. GetServerCpDir(
  280. LPCTSTR lpctstrServerName,
  281. LPTSTR lptstrCpDir,
  282. DWORD dwCpDirSize
  283. )
  284. /*++
  285. Routine Description:
  286. Gets the server's coverpage directory.
  287. Arguments:
  288. lpctstrServerName - [in] server name or NULL
  289. lptstrCpDir - [out] buffer to hold the coverpage dir
  290. dwCpDirSize - [in] size in chars of lptstrCpDir
  291. Return Value:
  292. TRUE - If success
  293. FALSE - Otherwise (see thread's last error)
  294. --*/
  295. {
  296. TCHAR szComputerName[(MAX_COMPUTERNAME_LENGTH + 1)] = {0};
  297. DWORD dwSizeOfComputerName = sizeof(szComputerName)/sizeof(TCHAR);
  298. HRESULT hRes;
  299. DEBUG_FUNCTION_NAME(TEXT("GetServerCpDir"))
  300. if ((!lptstrCpDir) || (!dwCpDirSize))
  301. {
  302. ASSERT_FALSE;
  303. SetLastError (ERROR_INVALID_PARAMETER);
  304. return FALSE;
  305. }
  306. if(IsLocalMachineName(lpctstrServerName))
  307. {
  308. //
  309. // Local machine case
  310. //
  311. TCHAR szCommonAppData [MAX_PATH + 1];
  312. LPCTSTR lpctstrServerCPDirSuffix = NULL;
  313. HKEY hKey;
  314. if (!GetSpecialPath(CSIDL_COMMON_APPDATA, szCommonAppData, ARR_SIZE(szCommonAppData) ))
  315. {
  316. DebugPrintEx(
  317. DEBUG_ERR,
  318. TEXT("GetSpecialPath (CSIDL_COMMON_APPDATA) failed with %ld"),
  319. GetLastError());
  320. return FALSE;
  321. }
  322. hKey = OpenRegistryKey (HKEY_LOCAL_MACHINE,
  323. REGKEY_FAX_SETUP,
  324. FALSE,
  325. KEY_QUERY_VALUE);
  326. if (!hKey)
  327. {
  328. DebugPrintEx(
  329. DEBUG_ERR,
  330. TEXT("OpenRegistryKey (%s) failed with %ld"),
  331. REGKEY_FAX_CLIENT,
  332. GetLastError());
  333. return FALSE;
  334. }
  335. lpctstrServerCPDirSuffix = GetRegistryString (hKey,
  336. REGVAL_SERVER_CP_LOCATION,
  337. TEXT(""));
  338. if (!lpctstrServerCPDirSuffix)
  339. {
  340. DebugPrintEx(
  341. DEBUG_ERR,
  342. TEXT("GetRegistryString (%s) failed with %ld"),
  343. REGVAL_SERVER_CP_LOCATION,
  344. GetLastError());
  345. RegCloseKey (hKey);
  346. return FALSE;
  347. }
  348. RegCloseKey (hKey);
  349. if (!lstrlen (lpctstrServerCPDirSuffix))
  350. {
  351. SetLastError (ERROR_REGISTRY_CORRUPT);
  352. DebugPrintEx(
  353. DEBUG_ERR,
  354. TEXT("Value at %s is empty"),
  355. REGVAL_SERVER_CP_LOCATION);
  356. MemFree ((LPVOID)lpctstrServerCPDirSuffix);
  357. return FALSE;
  358. }
  359. hRes = StringCchPrintf( lptstrCpDir,
  360. dwCpDirSize,
  361. TEXT("%s\\%s"),
  362. szCommonAppData,
  363. lpctstrServerCPDirSuffix);
  364. if (FAILED(hRes))
  365. {
  366. DebugPrintEx(
  367. DEBUG_ERR,
  368. TEXT("StringCchPrintf failed (ec=%lu)"),
  369. HRESULT_CODE(hRes));
  370. SetLastError (HRESULT_CODE(hRes));
  371. MemFree ((LPVOID)lpctstrServerCPDirSuffix);
  372. return FALSE;
  373. }
  374. MemFree ((LPVOID)lpctstrServerCPDirSuffix);
  375. return TRUE;
  376. }
  377. else
  378. {
  379. //
  380. // Remote server case
  381. //
  382. hRes = StringCchPrintf( lptstrCpDir,
  383. dwCpDirSize,
  384. TEXT("\\\\%s\\") FAX_COVER_PAGES_SHARE_NAME,
  385. lpctstrServerName);
  386. if (FAILED(hRes))
  387. {
  388. DebugPrintEx(
  389. DEBUG_ERR,
  390. TEXT("StringCchPrintf failed (ec=%lu)"),
  391. HRESULT_CODE(hRes));
  392. SetLastError (HRESULT_CODE(hRes));
  393. return FALSE;
  394. }
  395. return TRUE;
  396. }
  397. } // GetServerCpDir
  398. DWORD
  399. WinHelpContextPopup(
  400. ULONG_PTR dwHelpId,
  401. HWND hWnd
  402. )
  403. /*++
  404. Routine name : WinHelpContextPopup
  405. Routine description:
  406. open context sensetive help popup with WinHelp
  407. Author:
  408. Alexander Malysh (AlexMay), Mar, 2000
  409. Arguments:
  410. dwHelpId [in] - help ID
  411. hWnd [in] - parent window handler
  412. Return Value:
  413. None.
  414. --*/
  415. {
  416. DWORD dwExpRes;
  417. DWORD dwRes = ERROR_SUCCESS;
  418. TCHAR tszHelpFile[MAX_PATH+1];
  419. if (0 == dwHelpId)
  420. {
  421. return dwRes;
  422. }
  423. if(!IsFaxComponentInstalled(FAX_COMPONENT_HELP_CLIENT_HLP))
  424. {
  425. //
  426. // The help file is not installed
  427. //
  428. return dwRes;
  429. }
  430. //
  431. // get help file name
  432. //
  433. dwExpRes = ExpandEnvironmentStrings(FAX_CONTEXT_HELP_FILE, tszHelpFile, MAX_PATH);
  434. if(0 == dwExpRes)
  435. {
  436. dwRes = GetLastError();
  437. DebugPrint(( TEXT("ExpandEnvironmentStrings failed: %d\n"), dwRes ));
  438. return dwRes;
  439. }
  440. WinHelp(hWnd,
  441. tszHelpFile,
  442. HELP_CONTEXTPOPUP,
  443. dwHelpId
  444. );
  445. return dwRes;
  446. }//WinHelpContextPopup
  447. BOOL
  448. InvokeServiceManager(
  449. HWND hDlg,
  450. HINSTANCE hResource,
  451. UINT uid
  452. )
  453. /*++
  454. Routine name : InvokeServiceManager
  455. Routine description:
  456. Invokes a new instance of the Fax Service Manager or pop up an old instance if such one exists.
  457. Arguments:
  458. hDlg [in] - Identifies the parent window
  459. hResource [in] - handle to resource module
  460. uid [in] - resource identifier
  461. Return Value:
  462. TRUE - If success
  463. FALSE - Otherwise
  464. --*/
  465. {
  466. DWORD dwRes = 0;
  467. HWND hwndAdminConsole = NULL;
  468. TCHAR szAdminWindowTitle[MAX_PATH] = {0};
  469. DEBUG_FUNCTION_NAME(TEXT("InvokeServiceManager()"));
  470. if(!LoadString(hResource, uid, szAdminWindowTitle, MAX_PATH))
  471. {
  472. DebugPrintEx(DEBUG_ERR,
  473. TEXT("LoadString failed: string ID=%d, error=%d"),
  474. uid,
  475. GetLastError());
  476. Assert(FALSE);
  477. }
  478. else
  479. {
  480. hwndAdminConsole = FindWindow(NULL, szAdminWindowTitle); // MMCMainFrame
  481. }
  482. if(hwndAdminConsole)
  483. {
  484. // Switch to that window if client console is already running
  485. ShowWindow(hwndAdminConsole, SW_RESTORE);
  486. SetForegroundWindow(hwndAdminConsole);
  487. }
  488. else
  489. {
  490. HINSTANCE hAdmin;
  491. hAdmin = ShellExecute(
  492. hDlg,
  493. TEXT("open"),
  494. FAX_ADMIN_CONSOLE_IMAGE_NAME,
  495. NULL,
  496. NULL,
  497. SW_SHOWNORMAL
  498. );
  499. if((DWORD_PTR)hAdmin <= 32)
  500. {
  501. // error
  502. dwRes = PtrToUlong(hAdmin);
  503. DebugPrintEx(DEBUG_ERR,
  504. TEXT("ShellExecute failed: error=%d"),dwRes );
  505. return FALSE;
  506. }
  507. }
  508. return TRUE;
  509. }//InvokeServiceManager