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.

1020 lines
27 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////
  2. // W2K TIF files import support
  3. //
  4. #include "stdafx.h"
  5. #include <tiff.h>
  6. #include <Sddl.h>
  7. #include <shlobjp.h> // LinkWindow control
  8. #define __FILE_ID__ 75
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. #ifdef UNICODE
  15. #define WM_IMPORT_PROGRESS_INC WM_APP + 3 // Increment Import progress bar
  16. #define WM_IMPORT_SET_FILE_COUNT WM_APP + 4 // Set the file number to import
  17. extern CClientConsoleApp theApp;
  18. //
  19. // Structure passed to the ImportArchiveFolder thread
  20. //
  21. struct ImportFolderParam
  22. {
  23. LPCWSTR cszImportFolder; // Import folder name
  24. BOOL bSentItems; // TRUE if the folder contains outbound faxes
  25. HWND hImportDlg; // Handle to the Import progress dialog
  26. BOOL bCancel; // TRUE if the Cancel button has been pressed
  27. };
  28. DWORD
  29. ImportArchiveFile(
  30. LPCWSTR pszFile,
  31. LPWSTR pszArchiveFolder,
  32. BOOL bSentItems,
  33. WCHAR* pszUserSid,
  34. DWORDLONG* pdwlUniqueId
  35. )
  36. /*++
  37. Routine name : ImportArchiveFile
  38. Routine description:
  39. Imports pszFile file to the pszArchiveFolder folder.
  40. The pszFile should be generated by W2K MS Fax
  41. Arguments:
  42. pszFile - [in] Imported file name
  43. pszArchiveFolder - [in] MS Fax archive folder name
  44. bSentItems - [in] TRUE if the file from the sent archive, FALSE if it from receive one
  45. pszUserSid - [in] The user string SID, can be NULL if(bSentItems == FALSE)
  46. pdwlUniqueId - [out] Unique id for the file
  47. Return Value:
  48. Standard Win32 error code
  49. --*/
  50. {
  51. DWORD dwRes = ERROR_SUCCESS;
  52. DBG_ENTER(TEXT("ImportArchive"), dwRes);
  53. WCHAR* pszFileExt = FAX_TIF_FILE_EXT;
  54. WCHAR szArchFile[MAX_PATH] = {0};
  55. MS_TAG_INFO msTags = {0};
  56. //
  57. // Generate unique file name in the archive folder
  58. //
  59. *pdwlUniqueId = GenerateUniqueFileName(pszArchiveFolder,
  60. pszFileExt,
  61. szArchFile,
  62. ARR_SIZE(szArchFile));
  63. if(*pdwlUniqueId == 0)
  64. {
  65. dwRes = GetLastError();
  66. CALL_FAIL (GENERAL_ERR, TEXT ("GenerateUniqueFileName"), dwRes);
  67. goto exit;
  68. }
  69. if(bSentItems)
  70. {
  71. //
  72. // Add user user SID to the file name for the outbound archive
  73. //
  74. // Delete generated file without the user SID in the name
  75. //
  76. if(!DeleteFile(szArchFile))
  77. {
  78. CALL_FAIL (GENERAL_ERR, TEXT ("DeleteFile"), GetLastError());
  79. }
  80. //
  81. // Add the user SID to the file name
  82. //
  83. if (_sntprintf(szArchFile,
  84. ARR_SIZE(szArchFile) -1,
  85. TEXT("%s\\%s$%I64X%s"),
  86. pszArchiveFolder,
  87. pszUserSid,
  88. *pdwlUniqueId,
  89. FAX_TIF_FILE_DOT_EXT) < 0)
  90. {
  91. dwRes = ERROR_BUFFER_OVERFLOW;
  92. CALL_FAIL (GENERAL_ERR, TEXT ("Insufficient szArchFile buffer"), dwRes);
  93. goto exit;
  94. }
  95. }
  96. if(!CopyFile(pszFile, szArchFile, FALSE))
  97. {
  98. dwRes = GetLastError();
  99. CALL_FAIL (GENERAL_ERR, TEXT ("CopyFile"), dwRes);
  100. goto exit;
  101. }
  102. //
  103. // Read W2K MS TIF tags from the file
  104. //
  105. dwRes = GetW2kMsTiffTags(szArchFile, &msTags, bSentItems);
  106. if(ERROR_SUCCESS == dwRes)
  107. {
  108. //
  109. // Add new (XP) MS TIF tags to the file
  110. //
  111. if(!TiffAddMsTags(szArchFile, &msTags, bSentItems))
  112. {
  113. dwRes = GetLastError();
  114. CALL_FAIL (GENERAL_ERR, TEXT ("TiffAddMsTags"), dwRes);
  115. if(!DeleteFile(szArchFile))
  116. {
  117. CALL_FAIL (GENERAL_ERR, TEXT ("DeleteFile"), GetLastError());
  118. }
  119. goto exit;
  120. }
  121. }
  122. else if(ERROR_XP_TIF_FILE_FORMAT == dwRes)
  123. {
  124. //
  125. // The TIF file already has new (XP) TIF tags
  126. //
  127. dwRes = ERROR_SUCCESS;
  128. }
  129. else
  130. {
  131. //
  132. // The tiff file was not created by MS fax
  133. //
  134. if(!DeleteFile(szArchFile))
  135. {
  136. CALL_FAIL (GENERAL_ERR, TEXT ("DeleteFile"), GetLastError());
  137. }
  138. }
  139. exit:
  140. FreeMsTagInfo(&msTags);
  141. return dwRes;
  142. } // ImportArchiveFile
  143. DWORD
  144. WINAPI
  145. ImportArchiveFolder(
  146. LPVOID lpParameter // thread data
  147. )
  148. /*++
  149. Routine name : ImportArchiveFolder
  150. Routine description:
  151. Imports fax (tif) files from the cstrImportFolder folder to the MS Fax archive.
  152. Returns ERROR_FILE_NOT_FOUND if the folder does not contain TIF files
  153. Arguments:
  154. lpParameter - [in] pointer to ImportFolderParam structure
  155. Return Value:
  156. Standard Win32 error code
  157. --*/
  158. {
  159. ImportFolderParam* pParam = (ImportFolderParam*)lpParameter;
  160. DWORD dwRes = ERROR_SUCCESS;
  161. DWORD dwError;
  162. int nRes;
  163. WCHAR szFindMask[MAX_PATH] = {0};
  164. WCHAR szImportFile[MAX_PATH] = {0};
  165. WIN32_FIND_DATA findData = {0};
  166. HANDLE hFile = INVALID_HANDLE_VALUE;
  167. HANDLE hFax = NULL;
  168. PFAX_ARCHIVE_CONFIG pArchiveCfg = NULL;
  169. PSID pUserSid = NULL;
  170. WCHAR* pszUserSid = NULL;
  171. DWORDLONG dwlUniqueId;
  172. DWORD dwFileCount = 0;
  173. DWORD dwNotifyMsgID = 0; // Windows message id used for notification
  174. HMODULE hAdvapi32 = NULL;
  175. BOOL (*pfConvertSidToStringSid)(PSID, LPTSTR*) = NULL; // pointer to ConvertSidToStringSid()
  176. DBG_ENTER(TEXT("ImportFolderThread"), dwRes);
  177. if(!IsWinXPOS())
  178. {
  179. //
  180. // The Import functionality supported on XP OS only
  181. //
  182. ASSERTION_FAILURE;
  183. return ERROR_CALL_NOT_IMPLEMENTED;
  184. }
  185. //
  186. // ConvertSidToStringSid() Requires Windows 2000 or later, so we connect to it dynamically
  187. //
  188. hAdvapi32 = LoadLibrary(TEXT("advapi32.dll"));
  189. if(!hAdvapi32)
  190. {
  191. dwRes = GetLastError();
  192. CALL_FAIL (GENERAL_ERR, TEXT ("LoadLibrary(advapi32.dll)"), dwRes);
  193. goto exit;
  194. }
  195. (FARPROC&)pfConvertSidToStringSid = GetProcAddress(hAdvapi32, "ConvertSidToStringSidW");
  196. if(!pfConvertSidToStringSid)
  197. {
  198. dwRes = GetLastError();
  199. CALL_FAIL (GENERAL_ERR, TEXT ("GetProcAddress(ConvertSidToStringSid)"), dwRes);
  200. goto exit;
  201. }
  202. //
  203. // Compose find mask: path\*.tif
  204. //
  205. _snwprintf(szFindMask, MAX_PATH-1, TEXT("%s\\%s"), pParam->cszImportFolder, FAX_TIF_FILE_MASK);
  206. //
  207. // Count TIF files in the pParam->cszImportFolder folder
  208. //
  209. // Find the first tif file in the cstrImportFolder
  210. //
  211. hFile = FindFirstFile(szFindMask, &findData);
  212. if(INVALID_HANDLE_VALUE == hFile)
  213. {
  214. dwRes = GetLastError();
  215. CALL_FAIL (GENERAL_ERR, TEXT ("FindFirstFile"), dwRes);
  216. goto exit;
  217. }
  218. dwFileCount = 1;
  219. for(;;)
  220. {
  221. //
  222. // Find Next File
  223. //
  224. if(!FindNextFile(hFile, &findData))
  225. {
  226. dwError = GetLastError();
  227. if(ERROR_NO_MORE_FILES != dwError)
  228. {
  229. dwRes = dwError;
  230. CALL_FAIL (GENERAL_ERR, TEXT ("FindNextFile"), dwRes);
  231. }
  232. break;
  233. }
  234. dwFileCount += 1;
  235. }
  236. if(INVALID_HANDLE_VALUE != hFile)
  237. {
  238. FindClose(hFile);
  239. }
  240. if(pParam->hImportDlg)
  241. {
  242. //
  243. // Set progress bar range
  244. //
  245. SendMessage(pParam->hImportDlg, WM_IMPORT_SET_FILE_COUNT, dwFileCount, 0);
  246. }
  247. //
  248. // Find the first tif file in the cstrImportFolder
  249. //
  250. hFile = FindFirstFile(szFindMask, &findData);
  251. if(INVALID_HANDLE_VALUE == hFile)
  252. {
  253. dwRes = GetLastError();
  254. CALL_FAIL (GENERAL_ERR, TEXT ("FindFirstFile"), dwRes);
  255. goto exit;
  256. }
  257. //
  258. // Get fax server archive configuration
  259. //
  260. if(!FaxConnectFaxServer(NULL, &hFax))
  261. {
  262. dwRes = GetLastError();
  263. CALL_FAIL (RPC_ERR, TEXT ("FaxConnectFaxServer"), dwRes);
  264. goto exit;
  265. }
  266. //
  267. // Get pointer to the Client Console archive folder
  268. //
  269. if(theApp.m_pMainWnd)
  270. {
  271. CClientConsoleDoc* pDoc = NULL;
  272. pDoc = (CClientConsoleDoc*)((CFrameWnd*)theApp.m_pMainWnd)->GetActiveDocument();
  273. if(pDoc)
  274. {
  275. //
  276. // find local fax server
  277. //
  278. CServerNode* pServer = NULL;
  279. pServer = pDoc->FindServerByName(NULL);
  280. if(pServer)
  281. {
  282. //
  283. // Get archive folder
  284. //
  285. CFolder* pFolder = NULL;
  286. pFolder = pServer->GetFolder(pParam->bSentItems ? FOLDER_TYPE_SENT_ITEMS : FOLDER_TYPE_INBOX);
  287. if(pFolder && pFolder->IsValid())
  288. {
  289. dwNotifyMsgID = pServer->GetNotifyMsgID();
  290. }
  291. }
  292. }
  293. }
  294. //
  295. // Access check
  296. //
  297. DWORD dwAccessRights;
  298. if (!FaxAccessCheckEx(hFax,
  299. pParam->bSentItems ? FAX_ACCESS_MANAGE_OUT_ARCHIVE : FAX_ACCESS_MANAGE_IN_ARCHIVE,
  300. &dwAccessRights))
  301. {
  302. dwRes = GetLastError();
  303. CALL_FAIL (RPC_ERR, TEXT ("FaxAccessCheckEx"), dwRes);
  304. AlignedAfxMessageBox(IDS_IMPORT_NO_ACCESS, MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  305. goto exit;
  306. }
  307. if(!FaxGetArchiveConfiguration(hFax,
  308. pParam->bSentItems ? FAX_MESSAGE_FOLDER_SENTITEMS : FAX_MESSAGE_FOLDER_INBOX,
  309. &pArchiveCfg))
  310. {
  311. dwRes = GetLastError();
  312. CALL_FAIL (RPC_ERR, TEXT ("FaxGetArchiveConfiguration"), dwRes);
  313. goto exit;
  314. }
  315. BOOL bSameDir = FALSE;
  316. if ((dwRes = CheckToSeeIfSameDir((LPTSTR)pArchiveCfg->lpcstrFolder,(LPTSTR)pParam->cszImportFolder,&bSameDir)) != ERROR_SUCCESS)
  317. {
  318. CALL_FAIL (RPC_ERR, TEXT ("CheckToSeeIfSameDir"), dwRes);
  319. goto exit;
  320. }
  321. if (bSameDir)
  322. {
  323. AlignedAfxMessageBox(pParam->bSentItems ? IDS_IMPORT_SAME_DIR_SENT : IDS_IMPORT_SAME_DIR_INBOX
  324. , MB_OK | MB_ICONSTOP | MB_APPLMODAL);
  325. goto exit;
  326. }
  327. if(pParam->bSentItems)
  328. {
  329. //
  330. // Get the user string SID for the outbound archive
  331. //
  332. pUserSid = GetCurrentThreadSID();
  333. if (!pUserSid)
  334. {
  335. dwRes = GetLastError ();
  336. CALL_FAIL (GENERAL_ERR, TEXT ("GetCurrentThreadSID"), dwRes);
  337. goto exit;
  338. }
  339. if (!pfConvertSidToStringSid(pUserSid, &pszUserSid))
  340. {
  341. dwRes = GetLastError ();
  342. CALL_FAIL (GENERAL_ERR, TEXT ("ConvertSidToStringSid"), dwRes);
  343. goto exit;
  344. }
  345. }
  346. while(!pParam->bCancel)
  347. {
  348. //
  349. // Compose full path
  350. //
  351. _snwprintf(szImportFile, MAX_PATH-1, TEXT("%s\\%s\0"), pParam->cszImportFolder, findData.cFileName);
  352. nRes = IDOK;
  353. do
  354. {
  355. //
  356. // Import the file
  357. //
  358. dwError = ImportArchiveFile(szImportFile,
  359. pArchiveCfg->lpcstrFolder,
  360. pParam->bSentItems,
  361. pszUserSid,
  362. &dwlUniqueId);
  363. if(ERROR_SUCCESS != dwError)
  364. {
  365. CALL_FAIL (GENERAL_ERR, TEXT ("ImportArchiveFile"), dwRes);
  366. //
  367. // Popup "Cancel, Try Again, Continue" dialog
  368. //
  369. DWORD dwResId = IDS_IMPORT_ERROR;
  370. WCHAR szFormat[MAX_PATH] = {0};
  371. WCHAR szMsg[MAX_PATH] = {0};
  372. if(ERROR_BAD_FORMAT == dwError)
  373. {
  374. dwResId = IDS_IMPORT_BAD_FORMAT;
  375. }
  376. else if(ERROR_XP_TIF_WITH_WRONG_ARCHIVE_TYPE == dwError)
  377. {
  378. dwResId = pParam->bSentItems ? IDS_IMPORT_FILE_NOT_SEND_TYPE : IDS_IMPORT_FILE_NOT_RECEIVE_TYPE;
  379. }
  380. if(LoadString(GetResourceHandle(),
  381. dwResId,
  382. szFormat,
  383. ARR_SIZE(szFormat)))
  384. {
  385. _snwprintf(szMsg, MAX_PATH-1, szFormat, findData.cFileName);
  386. nRes = AlignedAfxMessageBox(szMsg, MB_CANCELTRYCONTINUE | MB_ICONSTOP | MB_APPLMODAL);
  387. if(IDCANCEL == nRes)
  388. {
  389. pParam->bCancel = TRUE;
  390. }
  391. }
  392. else
  393. {
  394. CALL_FAIL (GENERAL_ERR, TEXT ("LoadString(IDS_IMPORT_ERROR)"), GetLastError());
  395. }
  396. }
  397. }
  398. while(nRes == IDTRYAGAIN);
  399. if(dwNotifyMsgID)
  400. {
  401. //
  402. // Add the message to the archive folder
  403. // We simulate the server notification handled by the application main thread
  404. // The notification handler should free the event data
  405. //
  406. FAX_EVENT_EX* pEvent = (FAX_EVENT_EX*)MemAlloc(sizeof(FAX_EVENT_EX));
  407. if(!pEvent)
  408. {
  409. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  410. CALL_FAIL (GENERAL_ERR, TEXT ("MemAlloc"), dwRes);
  411. goto exit;
  412. }
  413. ZeroMemory(pEvent, sizeof(FAX_EVENT_EX));
  414. pEvent->dwSizeOfStruct = sizeof(FAX_EVENT_EX);
  415. pEvent->EventType = pParam->bSentItems ? FAX_EVENT_TYPE_OUT_ARCHIVE : FAX_EVENT_TYPE_IN_ARCHIVE;
  416. pEvent->EventInfo.JobInfo.Type = FAX_JOB_EVENT_TYPE_ADDED;
  417. pEvent->EventInfo.JobInfo.dwlMessageId = dwlUniqueId;
  418. theApp.m_pMainWnd->SendMessage(dwNotifyMsgID, 0, (LPARAM)pEvent);
  419. }
  420. if(pParam->hImportDlg)
  421. {
  422. //
  423. // Increment progress bar
  424. //
  425. SendMessage(pParam->hImportDlg, WM_IMPORT_PROGRESS_INC, 0, 0);
  426. }
  427. //
  428. // Find Next File
  429. //
  430. if(!FindNextFile(hFile, &findData))
  431. {
  432. dwError = GetLastError();
  433. if(ERROR_NO_MORE_FILES != dwError)
  434. {
  435. dwRes = dwError;
  436. CALL_FAIL (GENERAL_ERR, TEXT ("FindNextFile"), dwRes);
  437. }
  438. break;
  439. }
  440. } // while
  441. //
  442. // Notify the fax service
  443. //
  444. if(!FaxRefreshArchive(hFax,
  445. pParam->bSentItems ? FAX_MESSAGE_FOLDER_SENTITEMS : FAX_MESSAGE_FOLDER_INBOX))
  446. {
  447. dwRes = GetLastError();
  448. CALL_FAIL (GENERAL_ERR, TEXT ("FaxArchiveMessageAdded"), dwRes);
  449. }
  450. exit:
  451. if(pParam->hImportDlg)
  452. {
  453. //
  454. // Close the Progress dialog
  455. //
  456. SendMessage(pParam->hImportDlg, WM_CLOSE, 0, 0);
  457. }
  458. if(0 == dwFileCount)
  459. {
  460. //
  461. // The folder does not contain faxes
  462. //
  463. AlignedAfxMessageBox(IDS_IMPORT_EMPTY_FOLDER, MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
  464. }
  465. if(INVALID_HANDLE_VALUE != hFile)
  466. {
  467. FindClose(hFile);
  468. }
  469. if(pArchiveCfg)
  470. {
  471. FaxFreeBuffer(pArchiveCfg);
  472. }
  473. if(hFax)
  474. {
  475. FaxClose(hFax);
  476. }
  477. if(pUserSid)
  478. {
  479. MemFree(pUserSid);
  480. }
  481. if(pszUserSid)
  482. {
  483. LocalFree(pszUserSid);
  484. }
  485. if(hAdvapi32)
  486. {
  487. FreeLibrary(hAdvapi32);
  488. }
  489. return dwRes;
  490. } // ImportArchiveFolder
  491. INT_PTR
  492. CALLBACK
  493. ImportDlgProc(
  494. HWND hwndDlg, // handle to dialog box
  495. UINT uMsg, // message
  496. WPARAM wParam, // first message parameter
  497. LPARAM lParam // second message parameter
  498. )
  499. /*++
  500. Routine description:
  501. Import fax dialog procedure
  502. Arguments:
  503. HWND hwndDlg, // handle to dialog box
  504. UINT uMsg, // message
  505. WPARAM wParam, // first message parameter
  506. LPARAM lParam // second message parameter
  507. Return Value:
  508. return TRUE if it processed the message
  509. --*/
  510. {
  511. static ImportFolderParam* pIpmParam = NULL;
  512. static DWORD dwFileCount; // The number of the files to import
  513. static DWORD dwCurrentFile; // The number of the currently imported file
  514. switch ( uMsg )
  515. {
  516. case WM_INITDIALOG:
  517. {
  518. HANDLE hImportThread = NULL;
  519. pIpmParam = (ImportFolderParam*)lParam;
  520. TCHAR szFolder[MAX_PATH] = {0};
  521. DBG_ENTER(TEXT("ImportDlgProc(WM_INITDIALOG)"));
  522. dwFileCount = 0;
  523. dwCurrentFile = 0;
  524. //
  525. // Set import folder name
  526. //
  527. if(LoadString(GetResourceHandle(),
  528. pIpmParam->bSentItems ? IDS_IMPORT_TO_SENT_ITEMS : IDS_IMPORT_TO_INBOX,
  529. szFolder,
  530. ARR_SIZE(szFolder)))
  531. {
  532. SetDlgItemText(hwndDlg, IDC_PROGRESS_TITLE, szFolder);
  533. }
  534. else
  535. {
  536. CALL_FAIL (GENERAL_ERR, TEXT ("LoadString() for IDC_PROGRESS_TITLE"), GetLastError());
  537. }
  538. pIpmParam->hImportDlg = hwndDlg;
  539. hImportThread = CreateThread(NULL, // SD
  540. 0, // initial stack size
  541. ImportArchiveFolder, // thread function
  542. (LPVOID)pIpmParam, // thread argument
  543. 0, // creation option
  544. NULL); // thread identifier
  545. if(!hImportThread)
  546. {
  547. CALL_FAIL (GENERAL_ERR, TEXT ("CreateThread"), GetLastError());
  548. }
  549. else
  550. {
  551. CloseHandle(hImportThread);
  552. }
  553. return TRUE;
  554. }
  555. case WM_IMPORT_PROGRESS_INC:
  556. {
  557. //
  558. // Increment progress bar
  559. //
  560. SendDlgItemMessage(hwndDlg, IDC_PROGRESS_BAR, PBM_STEPIT, 0, 0);
  561. //
  562. // Compose and set currently imported fax number
  563. //
  564. ++dwCurrentFile;
  565. TCHAR szFormat[MAX_PATH] = {0};
  566. TCHAR szText[MAX_PATH] = {0};
  567. DWORD dwParam[2];
  568. DBG_ENTER(TEXT("ImportDlgProc(WM_IMPORT_PROGRESS_INC)"));
  569. dwParam[0] = dwCurrentFile;
  570. dwParam[1] = dwFileCount;
  571. if(!LoadString(GetResourceHandle(),
  572. IDS_PROGRESS_NUMBER,
  573. szFormat,
  574. ARR_SIZE(szFormat)))
  575. {
  576. CALL_FAIL (GENERAL_ERR, TEXT ("LoadString(IDS_PROGRESS_NUMBER)"), GetLastError());
  577. return TRUE;
  578. }
  579. if(FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  580. (LPCVOID)szFormat,
  581. 0,
  582. 0,
  583. szText,
  584. ARR_SIZE(szText),
  585. (va_list*)dwParam))
  586. {
  587. SetDlgItemText(hwndDlg, IDC_PROGRESS_NUMBER, szText);
  588. }
  589. return TRUE;
  590. }
  591. case WM_IMPORT_SET_FILE_COUNT:
  592. //
  593. // Set the pange and step of the proggress bar
  594. //
  595. dwFileCount = wParam;
  596. dwCurrentFile = 1;
  597. SendDlgItemMessage(hwndDlg, IDC_PROGRESS_BAR, PBM_SETRANGE32, 0, dwFileCount);
  598. SendDlgItemMessage(hwndDlg, IDC_PROGRESS_BAR, PBM_SETSTEP, 1, 0);
  599. return TRUE;
  600. case WM_CLOSE:
  601. EndDialog(hwndDlg, IDCANCEL);
  602. return TRUE;
  603. case WM_COMMAND:
  604. switch(LOWORD(wParam))
  605. {
  606. case IDCANCEL:
  607. //
  608. // Mark cancel, don't close the dialog
  609. //
  610. pIpmParam->bCancel = TRUE;
  611. EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
  612. return TRUE;
  613. }
  614. break;
  615. } // switch ( uMsg )
  616. return FALSE;
  617. } // ImportDlgProc
  618. DWORD
  619. ImportArchiveFolderUI(
  620. LPCWSTR cstrImportFolder,
  621. BOOL bSentItems,
  622. HWND hWnd
  623. )
  624. /*++
  625. Routine name : ImportArchiveFolderUI
  626. Routine description:
  627. Opens the Import Progress dialog
  628. Arguments:
  629. cstrImportFolder - [in] Import folder name
  630. bSentItems - [in] TRUE if the folder is the sent archive, FALSE if it is receive one
  631. hWnd - [in] Parent window
  632. Return Value:
  633. Standard Win32 error code
  634. --*/
  635. {
  636. DWORD dwRes = ERROR_SUCCESS;
  637. ImportFolderParam impParam = {0};
  638. impParam.cszImportFolder = cstrImportFolder;
  639. impParam.bSentItems = bSentItems;
  640. DBG_ENTER(TEXT("ImportArchiveFolderUI"), dwRes);
  641. DialogBoxParam(GetResourceHandle(), // handle to module
  642. MAKEINTRESOURCE(IDD_FAX_PROGRESS), // dialog box template
  643. hWnd, // handle to owner window
  644. ImportDlgProc, // dialog box procedure
  645. (LPARAM)&impParam); // initialization value
  646. return dwRes;
  647. } // ImportArchiveFolderUI
  648. BOOL
  649. IsFaxArchive(
  650. WCHAR* szFolder
  651. )
  652. /*++
  653. Routine name : IsFaxArchive
  654. Routine description:
  655. Determine if the folder contains at least one TIF file
  656. Arguments:
  657. szFolder - [in] folder name
  658. Return Value:
  659. TRUE if if the folder contains at least one TIF file
  660. FALSE otherwise
  661. --*/
  662. {
  663. WCHAR szFindMask[MAX_PATH] = {0};
  664. WIN32_FIND_DATA findData = {0};
  665. HANDLE hFile = INVALID_HANDLE_VALUE;
  666. DBG_ENTER(TEXT("IsFaxArchive"));
  667. //
  668. // Compose find mask: path\*.tif
  669. //
  670. _snwprintf(szFindMask, MAX_PATH-1, TEXT("%s\\%s"), szFolder, FAX_TIF_FILE_MASK);
  671. //
  672. // Find the first tif file in the cstrImportFolder
  673. //
  674. hFile = FindFirstFile(szFindMask, &findData);
  675. if(INVALID_HANDLE_VALUE == hFile)
  676. {
  677. CALL_FAIL (GENERAL_ERR, TEXT ("FindFirstFile"), GetLastError());
  678. return FALSE;
  679. }
  680. FindClose(hFile);
  681. return TRUE;
  682. }
  683. INT_PTR
  684. CALLBACK
  685. ImportInfoDlgProc(
  686. HWND hwndDlg, // handle to dialog box
  687. UINT uMsg, // message
  688. WPARAM wParam, // first message parameter
  689. LPARAM lParam // second message parameter
  690. )
  691. /*++
  692. Routine description:
  693. Import information fax dialog procedure
  694. Arguments:
  695. HWND hwndDlg, // handle to dialog box
  696. UINT uMsg, // message
  697. WPARAM wParam, // first message parameter
  698. LPARAM lParam // second message parameter
  699. Return Value:
  700. return TRUE if it processed the message
  701. --*/
  702. {
  703. switch (uMsg)
  704. {
  705. case WM_INITDIALOG:
  706. //
  707. // Set focus on the OK button
  708. //
  709. SetFocus(GetDlgItem(hwndDlg, IDOK));
  710. return FALSE;
  711. case WM_NOTIFY :
  712. {
  713. LPNMHDR lpnm = (LPNMHDR) lParam;
  714. if(((NM_CLICK == lpnm->code) || (NM_RETURN == lpnm->code)) &&
  715. lpnm->idFrom == IDC_IMPORT_HELP_LINK)
  716. {
  717. //
  718. // Display import help
  719. //
  720. HtmlHelpTopic(hwndDlg, FAX_HELP_IMPORT);
  721. return TRUE;
  722. }
  723. }
  724. break;
  725. case WM_COMMAND:
  726. switch (LOWORD(wParam))
  727. {
  728. case IDOK:
  729. case IDCANCEL:
  730. EndDialog(hwndDlg, IDOK);
  731. return TRUE;
  732. }
  733. break;
  734. }
  735. return FALSE;
  736. } // ImportInfoDlgProc
  737. DWORD
  738. DetectImportFiles()
  739. /*++
  740. Routine name : DetectImportFiles
  741. Routine description:
  742. Determine if the system has W2K fax archives.
  743. If yes warning dialog will be displayed for the first time.
  744. Return Value:
  745. Standard Win32 error code
  746. --*/
  747. {
  748. DWORD dwRes = ERROR_SUCCESS;
  749. HKEY hRegKey;
  750. DWORD dwImportWrn = 0; // 1 if the import warning has been displayed
  751. WCHAR* pszInbox = NULL;
  752. WCHAR* pszSentItems = NULL;
  753. DWORD dwSize = 0;
  754. BOOL bHaveFax = FALSE; // TRUE if the archives contain at least one TIF file
  755. DBG_ENTER(TEXT("DetectImportFiles"), dwRes);
  756. if(!IsWinXPOS())
  757. {
  758. return dwRes;
  759. }
  760. //
  761. // Check if the Import warning has been displayed
  762. //
  763. if ((hRegKey = OpenRegistryKey(HKEY_CURRENT_USER, REGKEY_FAX_SETUP, TRUE, KEY_ALL_ACCESS)))
  764. {
  765. dwImportWrn = GetRegistryDword(hRegKey, REGVAL_IMPORT_INFO);
  766. if(!dwImportWrn)
  767. {
  768. SetRegistryDword(hRegKey, REGVAL_IMPORT_INFO, TRUE);
  769. }
  770. RegCloseKey(hRegKey);
  771. }
  772. else
  773. {
  774. CALL_FAIL (GENERAL_ERR, TEXT ("OpenRegistryKey"), GetLastError());
  775. }
  776. if(dwImportWrn)
  777. {
  778. //
  779. // Import warning has been displayed
  780. //
  781. return dwRes;
  782. }
  783. //
  784. // Read W2K archives location
  785. //
  786. if (!(hRegKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, REGKEY_FAX_SETUP, TRUE, KEY_QUERY_VALUE)))
  787. {
  788. CALL_FAIL (GENERAL_ERR, TEXT ("OpenRegistryKey"), GetLastError());
  789. return dwRes;
  790. }
  791. pszInbox = GetRegistryStringMultiSz(hRegKey, REGVAL_W2K_INBOX, NULL, &dwSize);
  792. pszSentItems = GetRegistryString(hRegKey, REGVAL_W2K_SENT_ITEMS, NULL);
  793. RegCloseKey(hRegKey);
  794. //
  795. // Determine if the archives have at least one TIF file
  796. //
  797. bHaveFax = IsFaxArchive(pszSentItems);
  798. WCHAR* pszFolder = pszInbox;
  799. while(!bHaveFax && pszFolder && *pszFolder)
  800. {
  801. //
  802. // Walk though the multiline pszInbox string
  803. //
  804. bHaveFax = IsFaxArchive(pszFolder);
  805. pszFolder = _wcsninc(pszFolder, wcslen(pszFolder)+1);
  806. }
  807. MemFree(pszInbox);
  808. MemFree(pszSentItems);
  809. if(bHaveFax)
  810. {
  811. if(!LinkWindow_RegisterClass())
  812. {
  813. dwRes = ERROR_CAN_NOT_COMPLETE;
  814. CALL_FAIL (GENERAL_ERR, TEXT ("LinkWindow_RegisterClass"), dwRes);
  815. return dwRes;
  816. }
  817. DialogBoxParam(GetResourceHandle(), // handle to module
  818. MAKEINTRESOURCE(IDD_IMPORT_INFO), // dialog box template
  819. theApp.m_pMainWnd->m_hWnd, // handle to owner window
  820. ImportInfoDlgProc, // dialog box procedure
  821. NULL); // initialization value
  822. LinkWindow_UnregisterClass(theApp.m_hInstance);
  823. }
  824. return dwRes;
  825. }
  826. #endif //UNICODE