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.

7830 lines
232 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. wizard.c
  5. Abstract:
  6. Send fax wizard dialogs
  7. Environment:
  8. Fax driver user interface
  9. Revision History:
  10. 01/19/96 -davidx-
  11. Created it.
  12. 08/99 - 11/99 -v-sashab-
  13. Ported to ANSI.
  14. Changed UI.
  15. Added external interface for drivers.
  16. mm/dd/yy -author-
  17. description
  18. --*/
  19. #include "faxui.h"
  20. #include "tapiutil.h"
  21. #include "Registry.h"
  22. #include <fxsapip.h>
  23. #include "prtcovpg.h"
  24. #include "tiff.h"
  25. #include "cwabutil.h"
  26. #include "mapiabutil.h"
  27. #include <shellapi.h>
  28. #include <imm.h>
  29. #include "faxutil.h"
  30. #include "faxsendw.h"
  31. #include "shlwapi.h"
  32. #include <MAPI.H>
  33. #include <tifflib.h>
  34. #include <faxuiconstants.h>
  35. #define STRSAFE_NO_DEPRECATE
  36. #include <strsafe.h>
  37. #include "..\..\..\admin\cfgwzrd\FaxCfgWzExp.h"
  38. #define USE_LOCAL_SERVER_OUTBOUND_ROUTING 0xfffffffe
  39. #define PACKVERSION(major,minor) MAKELONG(minor,major)
  40. #define IE50_COMCTRL_VER PACKVERSION(5,80)
  41. DWORD GetDllVersion(LPCTSTR lpszDllName);
  42. enum { DEFAULT_INITIAL_DATA = 1,
  43. DEFAULT_RECEIPT_INFO = 2,
  44. DEFAULT_RECIPIENT_INFO = 4,
  45. DEFAULT_CV_INFO = 8,
  46. DEFAULT_SENDER_INFO = 16
  47. };
  48. #define REGVAL_FAKE_COVERPAGE TEXT("FakeCoverPage")
  49. #define REGVAL_FAKE_SERVER_BASED_CP TEXT("FakeServerBasedCP")
  50. #define REGVAL_FAKE_TESTS_COUNT TEXT("FakeTestsCount")
  51. #define REGVAL_KEY_FAKE_TESTS REGKEY_FAX_USERINFO TEXT("\\WzrdHack")
  52. //
  53. // Globals
  54. //
  55. PWIZARDUSERMEM g_pWizardUserMem;
  56. HWND g_hwndPreview = NULL;
  57. static DWORD g_dwCurrentDialingLocation = USE_LOCAL_SERVER_OUTBOUND_ROUTING;
  58. static DWORD g_dwMiniPreviewLandscapeWidth;
  59. static DWORD g_dwMiniPreviewLandscapeHeight;
  60. static DWORD g_dwMiniPreviewPortraitWidth;
  61. static DWORD g_dwMiniPreviewPortraitHeight;
  62. static WORD g_wCurrMiniPreviewOrientation;
  63. static BOOL g_bPreviewRTL = FALSE;
  64. BOOL FillCoverPageFields(PWIZARDUSERMEM pWizardUserMem, PCOVERPAGEFIELDS pCPFields);
  65. BOOL
  66. ErrorMessageBox(
  67. HWND hwndParent,
  68. UINT nErrorMessage,
  69. UINT uIcon
  70. );
  71. BOOL
  72. DisplayFaxPreview(
  73. HWND hWnd,
  74. PWIZARDUSERMEM pWizardUserMem,
  75. LPTSTR lptstrPreviewFile);
  76. LRESULT APIENTRY PreviewSubclassProc(
  77. HWND hwnd,
  78. UINT uMsg,
  79. WPARAM wParam,
  80. LPARAM lParam);
  81. BOOL DrawCoverPagePreview(
  82. HDC hdc,
  83. HWND hwndPrev,
  84. LPCTSTR lpctstrCoverPagePath,
  85. WORD wCPOrientation);
  86. BOOL EnableCoverDlgItems(PWIZARDUSERMEM pWizardUserMem, HWND hDlg);
  87. BOOL IsCanonicalNumber(LPCTSTR lptstrNumber);
  88. static BOOL IsNTSystemVersion();
  89. static BOOL GetTextualSid( const PSID pSid, LPTSTR tstrTextualSid, LPDWORD cchSidSize);
  90. static DWORD FormatCurrentUserKeyPath( const PTCHAR tstrRegRoot,
  91. PTCHAR* ptstrCurrentUserKeyPath);
  92. DWORD GetControlRect(HWND hCtrl, PRECT pRc);
  93. INT_PTR
  94. CALLBACK
  95. FaxUserInfoProc(
  96. HWND hDlg,
  97. UINT message,
  98. WPARAM wParam,
  99. LPARAM lParam
  100. );
  101. static HRESULT
  102. FreeRecipientInfo(
  103. DWORD * pdwNumberOfRecipients,
  104. PFAX_PERSONAL_PROFILE lpRecipientsInfo
  105. )
  106. /*++
  107. Routine Description:
  108. Frees array of recipients.
  109. Arguments:
  110. pdwNumberOfRecipients - number of recipients in array [IN/OUT]
  111. lpRecipientsInfo - pointer to array of recipients
  112. Return Value:
  113. S_OK - if success
  114. HRESULT error otherwise
  115. --*/
  116. {
  117. HRESULT hResult;
  118. DWORD i;
  119. Assert(pdwNumberOfRecipients);
  120. if (*pdwNumberOfRecipients==0)
  121. {
  122. return S_OK;
  123. }
  124. Assert(lpRecipientsInfo);
  125. for(i=0;i<*pdwNumberOfRecipients;i++)
  126. {
  127. hResult = FaxFreePersonalProfileInformation(&lpRecipientsInfo[i]);
  128. if (FAILED(hResult))
  129. {
  130. return hResult;
  131. }
  132. }
  133. MemFree(lpRecipientsInfo);
  134. *pdwNumberOfRecipients = 0;
  135. return S_OK;
  136. }
  137. VOID
  138. FillInPropertyPage(
  139. PROPSHEETPAGE *psp,
  140. BOOL bWizard97,
  141. INT dlgId,
  142. DLGPROC dlgProc,
  143. PWIZARDUSERMEM pWizardUserMem,
  144. INT TitleId,
  145. INT SubTitleId
  146. )
  147. /*++
  148. Routine Description:
  149. Fill out a PROPSHEETPAGE structure with the supplied parameters
  150. Arguments:
  151. psp - Points to the PROPSHEETPAGE structure to be filled out
  152. dlgId - Dialog template resource ID
  153. dlgProc - Dialog procedure
  154. pWizardUserMem - Pointer to the user mode memory structure
  155. TitleId - resource id for wizard subtitle
  156. SubTitleId - resource id for wizard subtitle
  157. Return Value:
  158. NONE
  159. --*/
  160. {
  161. LPTSTR WizardTitle = NULL;
  162. LPTSTR WizardSubTitle = NULL;
  163. Assert(psp);
  164. Assert(pWizardUserMem);
  165. Verbose(("FillInPropertyPage %d 0x%x\n",dlgId , pWizardUserMem));
  166. psp->dwSize = sizeof(PROPSHEETPAGE);
  167. //
  168. // Don't show titles if it's the first or last page
  169. //
  170. if (bWizard97)
  171. {
  172. if (TitleId==0 && SubTitleId ==0) {
  173. psp->dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
  174. } else {
  175. psp->dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  176. }
  177. }
  178. else
  179. {
  180. psp->dwFlags = PSP_DEFAULT ;
  181. }
  182. psp->hInstance = g_hResource;
  183. psp->pszTemplate = MAKEINTRESOURCE(dlgId);
  184. psp->pfnDlgProc = dlgProc;
  185. psp->lParam = (LPARAM) pWizardUserMem;
  186. if (bWizard97)
  187. {
  188. if (TitleId)
  189. {
  190. WizardTitle = MemAlloc(MAX_PATH * sizeof(TCHAR) );
  191. if(WizardTitle)
  192. {
  193. if (!LoadString(g_hResource, TitleId, WizardTitle, MAX_PATH))
  194. {
  195. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  196. Assert(FALSE);
  197. WizardTitle[0] = 0;
  198. }
  199. }
  200. else
  201. {
  202. Error(("MemAlloc failed."));
  203. }
  204. }
  205. if (SubTitleId)
  206. {
  207. WizardSubTitle = MemAlloc(MAX_PATH * sizeof(TCHAR));
  208. if(WizardSubTitle)
  209. {
  210. if (!LoadString(g_hResource, SubTitleId, WizardSubTitle, MAX_PATH))
  211. {
  212. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  213. Assert(FALSE);
  214. WizardSubTitle[0] = 0;
  215. }
  216. }
  217. else
  218. {
  219. Error(("MemAlloc failed."));
  220. }
  221. }
  222. psp->pszHeaderTitle = WizardTitle;
  223. psp->pszHeaderSubTitle = WizardSubTitle;
  224. }
  225. }
  226. LPTSTR
  227. GetTextStringValue(
  228. HWND hwnd
  229. )
  230. /*++
  231. Routine Description:
  232. Retrieve the string value in a text field
  233. Arguments:
  234. hwnd - Handle to a text window
  235. Return Value:
  236. Pointer to a string representing the current content of the text field
  237. NULL if the text field is empty or if there is an error
  238. --*/
  239. {
  240. INT length;
  241. LPTSTR pString;
  242. //
  243. // Find out how many characters are in the text field
  244. // and allocate enough memory to hold the string value
  245. //
  246. if ((length = GetWindowTextLength(hwnd)) == 0 ||
  247. (pString = MemAlloc(sizeof(TCHAR) * (length + 1))) == NULL)
  248. {
  249. return NULL;
  250. }
  251. //
  252. // Actually retrieve the string value
  253. //
  254. if (GetWindowText(hwnd, pString, length + 1) == 0) {
  255. MemFree(pString);
  256. return NULL;
  257. }
  258. return pString;
  259. }
  260. VOID
  261. LimitTextFields(
  262. HWND hDlg,
  263. INT *pLimitInfo
  264. )
  265. /*++
  266. Routine Description:
  267. Limit the maximum length for a number of text fields
  268. Arguments:
  269. hDlg - Specifies the handle to the dialog window
  270. pLimitInfo - Array of text field control IDs and their maximum length
  271. ID for the 1st text field, maximum length for the 1st text field
  272. ID for the 2nd text field, maximum length for the 2nd text field
  273. ...
  274. 0
  275. Note: The maximum length counts the NUL-terminator.
  276. Return Value:
  277. NONE
  278. --*/
  279. {
  280. while (*pLimitInfo != 0) {
  281. SendDlgItemMessage(hDlg, pLimitInfo[0], EM_SETLIMITTEXT, pLimitInfo[1]-1, 0);
  282. pLimitInfo += 2;
  283. }
  284. }
  285. PWIZARDUSERMEM
  286. CommonWizardProc(
  287. HWND hDlg,
  288. UINT message,
  289. WPARAM wParam,
  290. LPARAM lParam,
  291. DWORD buttonFlags
  292. )
  293. /*++
  294. Routine Description:
  295. Common procedure for handling wizard pages:
  296. Arguments:
  297. hDlg - Identifies the wizard page
  298. message - Specifies the message
  299. wParam - Specifies additional message-specific information
  300. lParam - Specifies additional message-specific information
  301. buttonFlags - Indicate which buttons should be enabled
  302. Return Value:
  303. NULL - Message is processed and the dialog procedure should return FALSE
  304. Otherwise - Message is not completely processed and
  305. The return value is a pointer to the user mode memory structure
  306. --*/
  307. {
  308. PWIZARDUSERMEM pWizardUserMem;
  309. pWizardUserMem = NULL;
  310. switch (message)
  311. {
  312. case WM_INITDIALOG:
  313. //
  314. // Store the pointer to user mode memory structure
  315. //
  316. lParam = ((PROPSHEETPAGE *) lParam)->lParam;
  317. pWizardUserMem = (PWIZARDUSERMEM) lParam;
  318. Assert(ValidPDEVWizardUserMem(pWizardUserMem));
  319. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  320. //
  321. // Make the title text bold
  322. //
  323. if (pWizardUserMem->dwComCtrlVer < IE50_COMCTRL_VER)
  324. {
  325. HWND hwndTitle;
  326. hwndTitle = GetDlgItem(hDlg,IDC_STATIC_HEADER_TITLE);
  327. if (hwndTitle)
  328. {
  329. SendMessage(hwndTitle,WM_SETFONT,(WPARAM)pWizardUserMem->hTitleFont ,MAKELPARAM((DWORD)FALSE,0));
  330. }
  331. }
  332. break;
  333. case WM_NOTIFY:
  334. pWizardUserMem = (PWIZARDUSERMEM) GetWindowLongPtr(hDlg, DWLP_USER);
  335. Assert(ValidPDEVWizardUserMem(pWizardUserMem));
  336. switch (((NMHDR *) lParam)->code)
  337. {
  338. case PSN_WIZFINISH:
  339. pWizardUserMem->finishPressed = TRUE;
  340. break;
  341. case PSN_SETACTIVE:
  342. PropSheet_SetWizButtons(GetParent(hDlg), buttonFlags);
  343. break;
  344. case PSN_RESET:
  345. case PSN_WIZBACK:
  346. case PSN_WIZNEXT:
  347. case PSN_KILLACTIVE:
  348. case LVN_KEYDOWN:
  349. case LVN_ITEMCHANGED:
  350. case NM_RCLICK:
  351. break;
  352. default:
  353. return NULL;
  354. }
  355. break;
  356. //
  357. // We wish all dialogs to recieve and handle the following commands:
  358. //
  359. case WM_DESTROY:
  360. case WM_COMMAND:
  361. case WM_CONTEXTMENU:
  362. pWizardUserMem = (PWIZARDUSERMEM) GetWindowLongPtr(hDlg, DWLP_USER);
  363. Assert(ValidPDEVWizardUserMem(pWizardUserMem));
  364. break;
  365. default:
  366. return NULL;
  367. }
  368. return pWizardUserMem;
  369. } // CommonWizardProc
  370. INT
  371. GetCurrentRecipient(
  372. HWND hDlg,
  373. PWIZARDUSERMEM pWizardUserMem,
  374. PRECIPIENT *ppRecipient
  375. )
  376. /*++
  377. Routine Description:
  378. Extract the current recipient information in the dialog
  379. Arguments:
  380. hDlg - Handle to the fax recipient wizard page
  381. pWizardUserMem - Points to user mode memory structure
  382. ppRecipient - Buffer to receive a pointer to a newly created RECIPIENT structure
  383. NULL if caller is only interested in the validity of recipient info
  384. Return Value:
  385. = 0 if successful
  386. > 0 error message string resource ID otherwise
  387. < 0 other error conditions
  388. --*/
  389. {
  390. PFAX_TAPI_LINECOUNTRY_LIST pCountryList = NULL;
  391. PFAX_TAPI_LINECOUNTRY_ENTRY pLineCountryEntry = NULL;
  392. DWORD countryId=0, countryCode=0;
  393. PRECIPIENT pRecipient = NULL;
  394. TCHAR areaCode[MAX_RECIPIENT_NUMBER];
  395. TCHAR phoneNumber[MAX_RECIPIENT_NUMBER];
  396. INT nameLen=0, areaCodeLen=0, numberLen=0;
  397. LPTSTR pName = NULL, pAddress = NULL;
  398. BOOL bUseDialingRules = FALSE;
  399. UINT cchAddress = 0;
  400. Assert(pWizardUserMem);
  401. pCountryList = pWizardUserMem->pCountryList;
  402. bUseDialingRules = pWizardUserMem->lpFaxSendWizardData->bUseDialingRules;
  403. //
  404. // Default value in case of error
  405. //
  406. if (ppRecipient)
  407. {
  408. *ppRecipient = NULL;
  409. }
  410. //
  411. // Find the current country code
  412. //
  413. if(bUseDialingRules)
  414. {
  415. countryId = GetCountryListBoxSel(GetDlgItem(hDlg, IDC_CHOOSE_COUNTRY_COMBO));
  416. if (countryId && (pLineCountryEntry = FindCountry(pCountryList,countryId)))
  417. {
  418. countryCode = pLineCountryEntry->dwCountryCode;
  419. }
  420. areaCodeLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_CHOOSE_AREA_CODE_EDIT));
  421. if ((areaCodeLen <= 0 && AreaCodeRules(pLineCountryEntry) == AREACODE_REQUIRED) ||
  422. (areaCodeLen >= MAX_RECIPIENT_NUMBER))
  423. {
  424. return IDS_BAD_RECIPIENT_AREACODE;
  425. }
  426. if (0 == countryId)
  427. {
  428. return IDS_BAD_RECIPIENT_COUNTRY_CODE;
  429. }
  430. }
  431. nameLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_CHOOSE_NAME_EDIT));
  432. numberLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_CHOOSE_NUMBER_EDIT));
  433. //
  434. // Validate the edit text fields
  435. //
  436. if (nameLen <= 0)
  437. {
  438. return IDS_BAD_RECIPIENT_NAME;
  439. }
  440. if (numberLen <= 0 || numberLen >= MAX_RECIPIENT_NUMBER)
  441. {
  442. return IDS_BAD_RECIPIENT_NUMBER;
  443. }
  444. if (NULL == ppRecipient)
  445. {
  446. return 0;
  447. }
  448. //
  449. // Calculate the amount of memory space we need and allocate it
  450. //
  451. pRecipient = MemAllocZ(sizeof(RECIPIENT));
  452. if(pRecipient)
  453. {
  454. ZeroMemory(pRecipient,sizeof(RECIPIENT));
  455. }
  456. pName = MemAllocZ((nameLen + 1) * sizeof(TCHAR));
  457. cchAddress = areaCodeLen + numberLen + 20;
  458. pAddress = MemAllocZ(cchAddress * sizeof(TCHAR));
  459. if (!pRecipient || !pName || !pAddress)
  460. {
  461. MemFree(pRecipient);
  462. MemFree(pName);
  463. MemFree(pAddress);
  464. return -1;
  465. }
  466. *ppRecipient = pRecipient;
  467. pRecipient->pName = pName;
  468. pRecipient->pAddress = pAddress;
  469. pRecipient->dwCountryId = countryId;
  470. pRecipient->bUseDialingRules = bUseDialingRules;
  471. pRecipient->dwDialingRuleId = g_dwCurrentDialingLocation;
  472. //
  473. // Get the recipient's name
  474. //
  475. GetWindowText(GetDlgItem(hDlg, IDC_CHOOSE_NAME_EDIT), pName, nameLen+1);
  476. //
  477. // Get the recipient's number
  478. // AddressType
  479. // [+ CountryCode Space]
  480. // [( AreaCode ) Space]
  481. // SubscriberNumber
  482. //
  483. GetWindowText(GetDlgItem(hDlg, IDC_CHOOSE_NUMBER_EDIT), phoneNumber, MAX_RECIPIENT_NUMBER);
  484. if (!IsValidFaxAddress (phoneNumber, !bUseDialingRules))
  485. {
  486. //
  487. // Fax address is invalid
  488. //
  489. MemFree(pRecipient);
  490. MemFree(pName);
  491. MemFree(pAddress);
  492. return IDS_INVALID_RECIPIENT_NUMBER;
  493. }
  494. if(!bUseDialingRules)
  495. {
  496. _tcscpy(pAddress, phoneNumber);
  497. }
  498. else
  499. {
  500. GetWindowText(GetDlgItem(hDlg, IDC_CHOOSE_AREA_CODE_EDIT),
  501. areaCode, MAX_RECIPIENT_NUMBER);
  502. AssemblePhoneNumber(pAddress,
  503. cchAddress,
  504. countryCode,
  505. areaCode,
  506. phoneNumber);
  507. }
  508. return 0;
  509. }
  510. BOOL
  511. InitRecipientListView(
  512. HWND hwndLV
  513. )
  514. /*++
  515. Routine Description:
  516. Initialize the recipient list view on the first page of Send Fax wizard
  517. Arguments:
  518. hwndLV - Window handle to the list view control
  519. Return Value:
  520. TRUE is success
  521. FALSE otherwise
  522. --*/
  523. {
  524. LV_COLUMN lvc;
  525. RECT rect;
  526. TCHAR buffer[MAX_TITLE_LEN];
  527. if (hwndLV == NULL) {
  528. return FALSE;
  529. }
  530. if (!GetClientRect(hwndLV, &rect))
  531. {
  532. Error(("GetClientRect failed. ec = 0x%X\n",GetLastError()));
  533. return FALSE;
  534. }
  535. ZeroMemory(&lvc, sizeof(lvc));
  536. ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
  537. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  538. lvc.fmt = LVCFMT_LEFT;
  539. lvc.pszText = buffer;
  540. lvc.cx = (rect.right - rect.left) / 2;
  541. lvc.iSubItem = 0;
  542. if (!LoadString(g_hResource, IDS_COLUMN_RECIPIENT_NAME, buffer, MAX_TITLE_LEN))
  543. {
  544. Error(("LoadString failed. ec = 0x%X\n",GetLastError()));
  545. return FALSE;
  546. }
  547. if (ListView_InsertColumn(hwndLV, 0, &lvc) == -1)
  548. {
  549. Error(("ListView_InsertColumn failed\n"));
  550. return FALSE;
  551. }
  552. lvc.cx -= GetSystemMetrics(SM_CXVSCROLL);
  553. lvc.iSubItem = 1;
  554. if (!LoadString(g_hResource, IDS_COLUMN_RECIPIENT_NUMBER, buffer, MAX_TITLE_LEN))
  555. {
  556. Error(("LoadString failed. ec = 0x%X\n",GetLastError()));
  557. return FALSE;
  558. }
  559. if (ListView_InsertColumn(hwndLV, 1, &lvc) == -1)
  560. {
  561. Error(("ListView_InsertColumn failed\n"));
  562. return FALSE;
  563. }
  564. //
  565. // Autosize the last column to get rid of unnecessary horizontal scroll bar
  566. //
  567. ListView_SetColumnWidth(hwndLV, 1, LVSCW_AUTOSIZE_USEHEADER);
  568. return TRUE;
  569. }
  570. typedef struct {
  571. DWORD dwSizeOfStruct;
  572. LPTSTR lptstrName;
  573. LPTSTR lptstrAddress;
  574. LPTSTR lptstrCountry;
  575. DWORD dwCountryId;
  576. DWORD dwDialingRuleId;
  577. BOOL bUseDialingRules;
  578. PFAX_TAPI_LINECOUNTRY_LIST pCountryList;
  579. } CHECKNUMBER, * PCHECKNUMBER;
  580. VOID
  581. FreeCheckNumberFields(OUT PCHECKNUMBER pCheckNumber)
  582. /*++
  583. Routine Description:
  584. Frees CHECKNUMBER structure
  585. Arguments:
  586. pCheckNumber - out pointer to CHECKNUMBER structure
  587. Return Value:
  588. NONE
  589. --*/
  590. {
  591. MemFree(pCheckNumber->lptstrName);
  592. MemFree(pCheckNumber->lptstrAddress);
  593. MemFree(pCheckNumber->lptstrCountry);
  594. ZeroMemory(pCheckNumber,sizeof(CHECKNUMBER));
  595. }
  596. BOOL
  597. InitCheckNumber(IN LPTSTR lptstrName,
  598. IN LPTSTR lptstrAddress,
  599. IN LPTSTR lptstrCountry,
  600. IN DWORD dwCountryId,
  601. IN DWORD dwDialingRuleId,
  602. IN BOOL bUseDialingRules,
  603. IN PFAX_TAPI_LINECOUNTRY_LIST pCountryList,
  604. OUT PCHECKNUMBER pCheckNumber)
  605. /*++
  606. Routine Description:
  607. Initializes CHECKNUMBER structure
  608. Arguments:
  609. lptstrName - recipient name
  610. lptstrAddress - recipient address
  611. lptstrCountry - recipient country
  612. dwCountryID - recipient country ID
  613. bUseDialingRules- Use Dialing Rules
  614. pCountryList - TAPI country list
  615. pCheckNumber - out pointer to CHECKNUMBER structure
  616. Return Value:
  617. TRUE if success
  618. FALSE otherwise
  619. --*/
  620. {
  621. ZeroMemory(pCheckNumber,sizeof(CHECKNUMBER));
  622. pCheckNumber->dwSizeOfStruct = sizeof(CHECKNUMBER);
  623. if (lptstrName && !(pCheckNumber->lptstrName = StringDup(lptstrName)))
  624. {
  625. Error(("Memory allocation failed\n"));
  626. goto error;
  627. }
  628. if (lptstrAddress && !(pCheckNumber->lptstrAddress = StringDup(lptstrAddress)))
  629. {
  630. Error(("Memory allocation failed\n"));
  631. goto error;
  632. }
  633. if (lptstrCountry && !(pCheckNumber->lptstrCountry = StringDup(lptstrCountry)))
  634. {
  635. Error(("Memory allocation failed\n"));
  636. goto error;
  637. }
  638. pCheckNumber->dwCountryId = dwCountryId;
  639. pCheckNumber->bUseDialingRules = bUseDialingRules;
  640. pCheckNumber->pCountryList = pCountryList;
  641. pCheckNumber->dwDialingRuleId = dwDialingRuleId;
  642. return TRUE;
  643. error:
  644. FreeCheckNumberFields(pCheckNumber);
  645. return FALSE;
  646. }
  647. INT
  648. ValidateCheckFaxRecipient(
  649. HWND hDlg,
  650. PCHECKNUMBER pCheckNumber
  651. )
  652. /*++
  653. Routine Description:
  654. Validates the current recipient information in the dialog
  655. Arguments:
  656. hDlg - Handle to the fax recipient wizard page
  657. pCheckNumber - Pointer to the CHECKNUMBER struct
  658. Return Value:
  659. = 0 if successful
  660. > 0 error message string resource ID otherwise
  661. --*/
  662. {
  663. DWORD countryId, countryCode;
  664. INT areaCodeLen, numberLen, nameLen;
  665. PFAX_TAPI_LINECOUNTRY_LIST pCountryList = pCheckNumber->pCountryList;
  666. PFAX_TAPI_LINECOUNTRY_ENTRY pLineCountryEntry;
  667. numberLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_CHECK_FAX_LOCAL));
  668. if (numberLen <= 0 || numberLen >= MAX_RECIPIENT_NUMBER)
  669. {
  670. return IDS_BAD_RECIPIENT_NUMBER;
  671. }
  672. if(!pCheckNumber->bUseDialingRules)
  673. {
  674. return 0;
  675. }
  676. //
  677. // Find the current country code
  678. //
  679. countryCode = 0;
  680. pLineCountryEntry = NULL;
  681. countryId = GetCountryListBoxSel(GetDlgItem(hDlg, IDC_CHECK_FAX_COUNTRY));
  682. if ((countryId != 0) &&
  683. (pLineCountryEntry = FindCountry(pCountryList,countryId)))
  684. {
  685. countryCode = pLineCountryEntry->dwCountryCode;
  686. }
  687. nameLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_CHECK_FAX_RECIPIENT_NAME));
  688. areaCodeLen = GetWindowTextLength(GetDlgItem(hDlg, IDC_CHECK_FAX_CITY));
  689. //
  690. // Validate the edit text fields
  691. //
  692. if (nameLen <= 0)
  693. {
  694. return IDS_BAD_RECIPIENT_NAME;
  695. }
  696. if ((areaCodeLen <= 0 && AreaCodeRules(pLineCountryEntry) == AREACODE_REQUIRED) ||
  697. (areaCodeLen >= MAX_RECIPIENT_NUMBER))
  698. {
  699. return IDS_BAD_RECIPIENT_AREACODE;
  700. }
  701. if (countryId==0)
  702. {
  703. return IDS_BAD_RECIPIENT_COUNTRY_CODE;
  704. }
  705. return 0;
  706. }
  707. VOID
  708. CheckFaxSetFocus(HWND hDlg,
  709. INT errId
  710. )
  711. {
  712. HWND hDglItem;
  713. switch (errId) {
  714. case IDS_ERROR_AREA_CODE:
  715. if (!SetDlgItemText(hDlg, IDC_CHECK_FAX_CITY, _T("")))
  716. {
  717. Warning(("SetDlgItemText failed. ec = 0x%X\n",GetLastError()));
  718. }
  719. case IDS_BAD_RECIPIENT_AREACODE:
  720. errId = IDC_CHECK_FAX_CITY;
  721. break;
  722. case IDS_BAD_RECIPIENT_COUNTRY_CODE:
  723. errId = IDC_CHECK_FAX_COUNTRY;
  724. break;
  725. case IDS_INVALID_RECIPIENT_NUMBER:
  726. if (!SetDlgItemText(hDlg, IDC_CHECK_FAX_LOCAL, _T("")))
  727. {
  728. Warning(("SetDlgItemText failed. ec = 0x%X\n",GetLastError()));
  729. }
  730. case IDS_BAD_RECIPIENT_NUMBER:
  731. errId = IDC_CHECK_FAX_LOCAL;
  732. break;
  733. case IDS_BAD_RECIPIENT_NAME:
  734. default:
  735. errId = IDC_CHECK_FAX_RECIPIENT_NAME;
  736. break;
  737. }
  738. if (!(hDglItem = GetDlgItem(hDlg, errId)))
  739. {
  740. Error(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  741. }
  742. else if (!SetFocus(hDglItem))
  743. {
  744. Error(("SetFocus failed. ec = 0x%X\n",GetLastError()));
  745. }
  746. }
  747. DWORD
  748. GetCountryCode(
  749. HWND hDlg,
  750. PFAX_TAPI_LINECOUNTRY_LIST pCountryList,
  751. INT nIDCountryItem
  752. )
  753. {
  754. /*++
  755. Routine Description:
  756. Retrieves country code.
  757. Arguments:
  758. hDlg - - Specifies the handle to the dialog window
  759. nIDCountryItem - Specifies the identifier of the control of country code
  760. Return Value:
  761. Coutry code if the country exists
  762. 0 otherwise
  763. --*/
  764. PFAX_TAPI_LINECOUNTRY_ENTRY pLineCountryEntry;
  765. DWORD dwCountryId, dwCountryCode;
  766. //
  767. // Find the current country code
  768. //
  769. dwCountryCode = 0;
  770. pLineCountryEntry = NULL;
  771. dwCountryId = GetCountryListBoxSel(GetDlgItem(hDlg, nIDCountryItem));
  772. if ((dwCountryId != 0) &&
  773. (pLineCountryEntry = FindCountry(pCountryList,dwCountryId)))
  774. {
  775. dwCountryCode = pLineCountryEntry->dwCountryCode;
  776. }
  777. return dwCountryCode;
  778. }
  779. LPTSTR
  780. GetAreaCodeOrFaxNumberFromControl(
  781. IN HWND hDlg,
  782. IN INT nIDItem,
  783. OUT LPTSTR szNumber,
  784. IN UINT cchNumber
  785. )
  786. {
  787. /*++
  788. Routine Description:
  789. Gets area code or phone number from an appropriate control
  790. Arguments:
  791. hDlg - - Specifies the handle to the dialog window
  792. nIDItem - Specifies the identifier of the control to be retrieved. (area code/fax number)
  793. szNumber - Output buffer
  794. cchNumber - The size of the szNumber OUT buffer in TCHARs
  795. Return Value:
  796. Area code/local fax number if the string is the number
  797. Or empty string otherwise
  798. --*/
  799. HWND hControl;
  800. Assert(szNumber);
  801. if (!(hControl = GetDlgItem(hDlg, nIDItem)))
  802. {
  803. Error(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  804. return _T( "" );
  805. }
  806. if (!GetWindowText(hControl, szNumber, cchNumber)&&GetLastError())
  807. {
  808. Error(("GetWindowText failed. ec = 0x%X\n",GetLastError()));
  809. return _T( "" );
  810. }
  811. return szNumber;
  812. }
  813. LPTSTR
  814. StripSpaces(
  815. IN LPTSTR lptstrPhoneNumber)
  816. {
  817. /*++
  818. Routine Description:
  819. Strips spaces from the beginning of lptstrPhoneNumber
  820. Arguments:
  821. lptstrPhoneNumber - phone number with spaces in the beginning
  822. Return Value:
  823. lptstrPhoneNumber without spaces in the beginning
  824. --*/
  825. TCHAR szSpaces[MAX_STRING_LEN];
  826. szSpaces[0] = (TCHAR) '\0';
  827. if (!lptstrPhoneNumber)
  828. return NULL;
  829. if (_stscanf(lptstrPhoneNumber,_T("%[ ]"),szSpaces))
  830. return lptstrPhoneNumber + _tcslen(szSpaces);
  831. return lptstrPhoneNumber;
  832. }
  833. LPTSTR
  834. StripCodesFromNumber(
  835. IN LPTSTR lptstrPhoneNumber,
  836. OUT DWORD *pdwCountryCode,
  837. OUT LPTSTR lptstrAreaCode,
  838. IN UINT cchAreaCode)
  839. /*++
  840. Routine Description:
  841. Extracts, if possible, area code. country code and local phone number from the phone number.
  842. This function considers three possibilities:
  843. 1. The number is canonical and has area code
  844. 2. The number is canonical and has no area code
  845. 3. The number is not canonical
  846. Arguments:
  847. lptstrPhoneNumber - assembled phone number
  848. pdwCountryCode - adress of country code
  849. lptstrAreaCode - address of area code
  850. cchAreaCode - size of the lptstrAreaCode OUT buffer in TCHARs
  851. Return Value:
  852. local phone number if the number was assembled or complete lptstrPhoneNumber otherwise
  853. The return value is HEAP allocated , call MemFree when the result is no longer needed.
  854. --*/
  855. {
  856. BOOL bIsCanonical;
  857. DWORD dwAreaCode;
  858. HRESULT hRc;
  859. LPTSTR pszSubNumber;
  860. LPTSTR szReturnValue;
  861. DWORD dwErrorCode;
  862. //
  863. // Input parameters validation.
  864. //
  865. if(!lptstrPhoneNumber ||
  866. !pdwCountryCode ||
  867. !lptstrAreaCode ||
  868. cchAreaCode < 1)
  869. {
  870. Assert(0);
  871. return NULL;
  872. }
  873. // initialization
  874. *pdwCountryCode = 0 ;
  875. pszSubNumber = NULL;
  876. szReturnValue = NULL;
  877. //
  878. // Input params are being checked so there is at least one TCHAR in the OUT buffer.
  879. //
  880. lptstrAreaCode[0] = TEXT('\0');
  881. dwErrorCode = IsCanonicalAddress(lptstrPhoneNumber,
  882. &bIsCanonical,
  883. pdwCountryCode,
  884. &dwAreaCode,
  885. &pszSubNumber);
  886. if(dwErrorCode != ERROR_SUCCESS)
  887. {
  888. Assert(0);
  889. goto Cleanup;
  890. }
  891. //
  892. // If the number is not canonical just return the original number.
  893. //
  894. if(!bIsCanonical)
  895. {
  896. szReturnValue = StringDup(lptstrPhoneNumber);
  897. if(szReturnValue == NULL)
  898. {
  899. Assert(0);
  900. goto Cleanup;
  901. }
  902. goto Cleanup;
  903. }
  904. else
  905. {
  906. //
  907. // The number is canonical and we have got 2 options
  908. //
  909. if(dwAreaCode == ROUTING_RULE_AREA_CODE_ANY)
  910. {
  911. //
  912. // Meaning that there is no area code
  913. //
  914. lptstrAreaCode[0] = TEXT('\0');
  915. //
  916. // Point to the heap allocated memory and make sure the cleanup will not touch it.
  917. //
  918. szReturnValue = pszSubNumber;
  919. pszSubNumber = NULL;
  920. goto Cleanup;
  921. }
  922. else
  923. {
  924. //
  925. // There is a country code + area code
  926. //
  927. hRc = StringCchPrintf(lptstrAreaCode,
  928. cchAreaCode,
  929. TEXT("%u"),
  930. dwAreaCode);
  931. if(FAILED(hRc))
  932. {
  933. Assert(0);
  934. goto Cleanup;
  935. }
  936. //
  937. // Point to the heap allocated memory and make sure the cleanup will not touch it.
  938. //
  939. szReturnValue = pszSubNumber;
  940. pszSubNumber = NULL;
  941. goto Cleanup;
  942. }
  943. }
  944. Cleanup:
  945. MemFree(pszSubNumber);
  946. return szReturnValue;
  947. }
  948. INT_PTR
  949. CALLBACK
  950. CheckFaxNumberDlgProc(
  951. HWND hDlg,
  952. UINT uMsg,
  953. WPARAM wParam,
  954. LPARAM lParam
  955. )
  956. /*++
  957. Routine Description:
  958. Dialog proc for check of fax number.
  959. Arguments:
  960. lParam - pointer to CHECKNUMBER structure.
  961. Return Value:
  962. 0 - if cancel
  963. 1 - if ok
  964. --*/
  965. {
  966. INT errId;
  967. INT cmd;
  968. PCHECKNUMBER pCheckNumber = (PCHECKNUMBER) lParam;
  969. TCHAR tszBuffer[MAX_STRING_LEN];
  970. TCHAR szAddress[MAX_STRING_LEN];
  971. TCHAR szAreaCode[MAX_RECIPIENT_NUMBER];
  972. TCHAR szPoneNumber[MAX_RECIPIENT_NUMBER];
  973. TCHAR szName[MAX_STRING_LEN];
  974. DWORD dwErrorCode;
  975. DWORD dwCountryId=0;
  976. DWORD dwCountryCode=0 ;
  977. LPTSTR lptstrLocalPhoneNumber=NULL;
  978. PFAX_TAPI_LINECOUNTRY_ENTRY pLineCountryEntry;
  979. HWND hControl;
  980. //
  981. // Maximum length for various text fields
  982. //
  983. static INT textLimits[] = {
  984. IDC_CHECK_FAX_RECIPIENT_NAME, 64,
  985. IDC_CHECK_FAX_CITY, 11,
  986. IDC_CHECK_FAX_LOCAL, 51,
  987. 0
  988. };
  989. ZeroMemory(szAreaCode, sizeof(szAreaCode));
  990. switch (uMsg)
  991. {
  992. case WM_INITDIALOG:
  993. LimitTextFields(hDlg, textLimits);
  994. if (pCheckNumber->lptstrName)
  995. {
  996. if (!SetDlgItemText(hDlg, IDC_CHECK_FAX_RECIPIENT_NAME, pCheckNumber->lptstrName))
  997. Warning(("SetDlgItemText failed. ec = 0x%X\n",GetLastError()));
  998. }
  999. // store pointer for futher proceeding
  1000. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  1001. //
  1002. // A numeric edit control should be LTR
  1003. //
  1004. SetLTREditDirection(hDlg, IDC_CHECK_FAX_NUMBER);
  1005. SetLTREditDirection(hDlg, IDC_CHECK_FAX_CITY);
  1006. SetLTREditDirection(hDlg, IDC_CHECK_FAX_LOCAL);
  1007. if(!pCheckNumber->bUseDialingRules)
  1008. {
  1009. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_FAX_COUNTRY), FALSE);
  1010. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_FAX_CITY), FALSE);
  1011. }
  1012. else
  1013. {
  1014. lptstrLocalPhoneNumber = StripCodesFromNumber( pCheckNumber->lptstrAddress,
  1015. &dwCountryCode,
  1016. szAreaCode,
  1017. ARR_SIZE(szAreaCode));
  1018. dwCountryId = pCheckNumber->dwCountryId;
  1019. if(!dwCountryId)
  1020. {
  1021. dwCountryId = GetCountryIdFromCountryCode(pCheckNumber->pCountryList,
  1022. dwCountryCode);
  1023. }
  1024. // init country combo box and try to identify the country
  1025. if (!(hControl=GetDlgItem(hDlg, IDC_CHECK_FAX_COUNTRY)))
  1026. {
  1027. Warning(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  1028. }
  1029. else
  1030. {
  1031. InitCountryListBox(pCheckNumber->pCountryList,
  1032. hControl,
  1033. NULL,
  1034. pCheckNumber->lptstrCountry,
  1035. dwCountryId,
  1036. TRUE);
  1037. }
  1038. if (dwCountryCode==0)
  1039. { // country code wasn't indentified
  1040. if (!(hControl=GetDlgItem(hDlg, IDC_CHECK_FAX_COUNTRY)))
  1041. {
  1042. Warning(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  1043. }
  1044. else
  1045. {
  1046. dwCountryId = GetCountryListBoxSel(hControl);
  1047. }
  1048. if ((dwCountryId != 0) &&
  1049. (pLineCountryEntry = FindCountry(pCheckNumber->pCountryList,dwCountryId)))
  1050. {
  1051. dwCountryCode = pLineCountryEntry->dwCountryCode;
  1052. }
  1053. }
  1054. Assert (lptstrLocalPhoneNumber);
  1055. SetDlgItemText(hDlg, IDC_CHECK_FAX_CITY , szAreaCode);
  1056. AssemblePhoneNumber(szAddress,
  1057. ARR_SIZE(szAddress),
  1058. dwCountryCode,
  1059. szAreaCode,
  1060. lptstrLocalPhoneNumber ? lptstrLocalPhoneNumber : _T(""));
  1061. }
  1062. SetDlgItemText(hDlg,
  1063. IDC_CHECK_FAX_NUMBER,
  1064. !(pCheckNumber->bUseDialingRules) ?
  1065. pCheckNumber->lptstrAddress : szAddress);
  1066. SetDlgItemText(hDlg,
  1067. IDC_CHECK_FAX_LOCAL,
  1068. !(pCheckNumber->bUseDialingRules) ?
  1069. pCheckNumber->lptstrAddress : lptstrLocalPhoneNumber);
  1070. MemFree(lptstrLocalPhoneNumber);
  1071. return TRUE;
  1072. case WM_COMMAND:
  1073. cmd = GET_WM_COMMAND_CMD(wParam, lParam);
  1074. switch (GET_WM_COMMAND_ID(wParam, lParam))
  1075. {
  1076. case IDC_CHECK_FAX_COUNTRY:
  1077. pCheckNumber = (PCHECKNUMBER) GetWindowLongPtr(hDlg, DWLP_USER);
  1078. Assert(pCheckNumber);
  1079. if (cmd == CBN_SELCHANGE)
  1080. {
  1081. if (!(GetDlgItem(hDlg, IDC_CHECK_FAX_COUNTRY)) ||
  1082. !(GetDlgItem(hDlg, IDC_CHECK_FAX_CITY)))
  1083. {
  1084. Warning(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  1085. }
  1086. else
  1087. {
  1088. SelChangeCountryListBox(GetDlgItem(hDlg, IDC_CHECK_FAX_COUNTRY),
  1089. GetDlgItem(hDlg, IDC_CHECK_FAX_CITY),
  1090. pCheckNumber->pCountryList);
  1091. }
  1092. AssemblePhoneNumber(szAddress,
  1093. ARR_SIZE(szAddress),
  1094. GetCountryCode(hDlg,pCheckNumber->pCountryList,IDC_CHECK_FAX_COUNTRY),
  1095. GetAreaCodeOrFaxNumberFromControl(hDlg,IDC_CHECK_FAX_CITY,szAreaCode,ARR_SIZE(szAreaCode)),
  1096. GetAreaCodeOrFaxNumberFromControl(hDlg,IDC_CHECK_FAX_LOCAL,szPoneNumber,ARR_SIZE(szPoneNumber)));
  1097. SetDlgItemText(hDlg, IDC_CHECK_FAX_NUMBER, szAddress);
  1098. }
  1099. break;
  1100. case IDC_CHECK_FAX_CITY:
  1101. if (cmd == EN_CHANGE)
  1102. {
  1103. pCheckNumber = (PCHECKNUMBER) GetWindowLongPtr(hDlg, DWLP_USER);
  1104. Assert(pCheckNumber);
  1105. // Read the text from the edit control.
  1106. if (!GetDlgItemText( hDlg, IDC_CHECK_FAX_CITY, tszBuffer, MAX_STRING_LEN))
  1107. {
  1108. dwErrorCode = GetLastError();
  1109. if ( dwErrorCode != (DWORD) ERROR_SUCCESS )
  1110. {
  1111. // Error reading the edit control.
  1112. }
  1113. }
  1114. AssemblePhoneNumber(szAddress,
  1115. ARR_SIZE(szAddress),
  1116. GetCountryCode(hDlg,pCheckNumber->pCountryList,IDC_CHECK_FAX_COUNTRY),
  1117. GetAreaCodeOrFaxNumberFromControl(hDlg,IDC_CHECK_FAX_CITY,szAreaCode,ARR_SIZE(szAreaCode)),
  1118. GetAreaCodeOrFaxNumberFromControl(hDlg,IDC_CHECK_FAX_LOCAL,szPoneNumber,ARR_SIZE(szPoneNumber)));
  1119. SetDlgItemText(hDlg, IDC_CHECK_FAX_NUMBER, szAddress);
  1120. }
  1121. break;
  1122. case IDC_CHECK_FAX_LOCAL:
  1123. if (cmd == EN_CHANGE)
  1124. {
  1125. pCheckNumber = (PCHECKNUMBER) GetWindowLongPtr(hDlg, DWLP_USER);
  1126. Assert(pCheckNumber);
  1127. //
  1128. // Read the text from the edit control.
  1129. //
  1130. if(!GetDlgItemText(hDlg,
  1131. IDC_CHECK_FAX_LOCAL,
  1132. tszBuffer,
  1133. MAX_STRING_LEN))
  1134. {
  1135. tszBuffer[0] = 0;
  1136. Warning(("GetDlgItemText(IDC_CHECK_FAX_LOCAL) failed. ec = 0x%X\n",GetLastError()));
  1137. }
  1138. if(pCheckNumber->bUseDialingRules)
  1139. {
  1140. AssemblePhoneNumber(szAddress,
  1141. ARR_SIZE(szAddress),
  1142. GetCountryCode(hDlg,pCheckNumber->pCountryList,IDC_CHECK_FAX_COUNTRY),
  1143. GetAreaCodeOrFaxNumberFromControl(hDlg,IDC_CHECK_FAX_CITY,szAreaCode,ARR_SIZE(szAreaCode)),
  1144. GetAreaCodeOrFaxNumberFromControl(hDlg,IDC_CHECK_FAX_LOCAL,szPoneNumber,ARR_SIZE(szPoneNumber)));
  1145. }
  1146. SetDlgItemText(hDlg,
  1147. IDC_CHECK_FAX_NUMBER,
  1148. !pCheckNumber->bUseDialingRules ?
  1149. tszBuffer : szAddress);
  1150. }
  1151. break;
  1152. }
  1153. switch(LOWORD( wParam ))
  1154. {
  1155. case IDOK:
  1156. pCheckNumber = (PCHECKNUMBER) GetWindowLongPtr(hDlg, DWLP_USER);
  1157. Assert(pCheckNumber);
  1158. errId = ValidateCheckFaxRecipient(hDlg, pCheckNumber);
  1159. if (errId > 0)
  1160. {
  1161. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, errId);
  1162. CheckFaxSetFocus(hDlg,errId);
  1163. return FALSE;
  1164. }
  1165. if(!GetDlgItemText(hDlg,
  1166. IDC_CHECK_FAX_LOCAL,
  1167. tszBuffer,
  1168. MAX_STRING_LEN))
  1169. {
  1170. tszBuffer[0] = 0;
  1171. Warning(("GetDlgItemText(IDC_CHECK_FAX_LOCAL) failed. ec = 0x%X\n",GetLastError()));
  1172. }
  1173. if (!IsValidFaxAddress (tszBuffer, !pCheckNumber->bUseDialingRules))
  1174. {
  1175. //
  1176. // Fax address is invalid
  1177. //
  1178. DisplayMessageDialog(hDlg, 0, 0, IDS_INVALID_RECIPIENT_NUMBER);
  1179. return FALSE;
  1180. }
  1181. ZeroMemory(szName,sizeof(TCHAR)*MAX_STRING_LEN);
  1182. if (!GetDlgItemText(hDlg,
  1183. IDC_CHECK_FAX_RECIPIENT_NAME,
  1184. szName,
  1185. MAX_STRING_LEN)
  1186. && GetLastError())
  1187. {
  1188. Error(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  1189. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, IDS_BAD_RECIPIENT_NAME);
  1190. CheckFaxSetFocus(hDlg,IDS_BAD_RECIPIENT_NAME);
  1191. return FALSE;
  1192. }
  1193. MemFree(pCheckNumber->lptstrName);
  1194. pCheckNumber->lptstrName = NULL;
  1195. if ((szName[0] != '\0') &&
  1196. !(pCheckNumber->lptstrName = StringDup(szName)))
  1197. {
  1198. Error(("Memory allocation failed\n"));
  1199. return FALSE;
  1200. }
  1201. ZeroMemory(szAddress,sizeof(TCHAR)*MAX_STRING_LEN);
  1202. if (!GetDlgItemText(hDlg,
  1203. IDC_CHECK_FAX_NUMBER,
  1204. szAddress,
  1205. MAX_STRING_LEN)
  1206. && GetLastError())
  1207. {
  1208. Error(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  1209. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, IDS_BAD_RECIPIENT_NUMBER);
  1210. CheckFaxSetFocus(hDlg,IDS_BAD_RECIPIENT_NUMBER);
  1211. return FALSE;
  1212. }
  1213. MemFree(pCheckNumber->lptstrAddress);
  1214. pCheckNumber->lptstrAddress = NULL;
  1215. if ((szAddress[0] != '\0') &&
  1216. !(pCheckNumber->lptstrAddress = StringDup(szAddress)))
  1217. {
  1218. Error(("Memory allocation failed\n"));
  1219. MemFree(pCheckNumber->lptstrName);
  1220. return FALSE;
  1221. }
  1222. pCheckNumber->dwCountryId = GetCountryListBoxSel(GetDlgItem(hDlg,
  1223. IDC_CHECK_FAX_COUNTRY));
  1224. EndDialog(hDlg,1);
  1225. return TRUE;
  1226. case IDCANCEL:
  1227. EndDialog( hDlg,0 );
  1228. return TRUE;
  1229. }
  1230. break;
  1231. default:
  1232. return FALSE;
  1233. }
  1234. return FALSE;
  1235. }
  1236. BOOL
  1237. IsCanonicalNumber(LPCTSTR lptstrNumber)
  1238. {
  1239. if (!lptstrNumber)
  1240. {
  1241. return FALSE;
  1242. }
  1243. if ( _tcsncmp(lptstrNumber,TEXT("+"),1) != 0 )
  1244. return FALSE;
  1245. return TRUE;
  1246. }
  1247. BOOL
  1248. InsertRecipientListItem(
  1249. HWND hwndLV,
  1250. PRECIPIENT pRecipient
  1251. )
  1252. /*++
  1253. Routine Description:
  1254. Insert an item into the recipient list view
  1255. Arguments:
  1256. hwndLV - Window handle to the recipient list view
  1257. pRecipient - Specifies the recipient to be inserted
  1258. Return Value:
  1259. TRUE if successful, FALSE if there is an error
  1260. --*/
  1261. {
  1262. LV_ITEM lvi = {0};
  1263. INT index;
  1264. TCHAR* pAddress = NULL;
  1265. lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
  1266. lvi.lParam = (LPARAM) pRecipient;
  1267. lvi.pszText = pRecipient->pName;
  1268. lvi.state = lvi.stateMask = LVIS_SELECTED;
  1269. if ((index = ListView_InsertItem(hwndLV, &lvi)) == -1)
  1270. {
  1271. Error(("ListView_InsertItem failed\n"));
  1272. return FALSE;
  1273. }
  1274. pAddress = pRecipient->pAddress;
  1275. #ifdef UNICODE
  1276. if(IsWindowRTL(hwndLV))
  1277. {
  1278. pAddress = (TCHAR*)MemAlloc(sizeof(TCHAR)*(_tcslen(pRecipient->pAddress)+2));
  1279. if(!pAddress)
  1280. {
  1281. Error(("MemAlloc failed\n"));
  1282. return FALSE;
  1283. }
  1284. _stprintf(pAddress, TEXT("%c%s"), UNICODE_LRO, pRecipient->pAddress);
  1285. }
  1286. #endif
  1287. ListView_SetItemText(hwndLV, index, 1, pAddress);
  1288. if(pAddress != pRecipient->pAddress)
  1289. {
  1290. MemFree(pAddress);
  1291. }
  1292. return TRUE;
  1293. }
  1294. PRECIPIENT
  1295. GetRecipientListItem(
  1296. HWND hwndLV,
  1297. INT index
  1298. )
  1299. /*++
  1300. Routine Description:
  1301. Retrieve the recipient associated with an item in the list view
  1302. Arguments:
  1303. hwndLV - Window handle to the recipient list view
  1304. index - Specifies the index of the interested item
  1305. Return Value:
  1306. Pointer to the requested recipient information
  1307. NULL if there is an error
  1308. --*/
  1309. {
  1310. LV_ITEM lvi;
  1311. ZeroMemory(&lvi, sizeof(lvi));
  1312. lvi.mask = LVIF_PARAM;
  1313. lvi.iItem = index;
  1314. if (ListView_GetItem(hwndLV, &lvi))
  1315. return (PRECIPIENT) lvi.lParam;
  1316. Error(("ListView_GetItem failed\n"));
  1317. return NULL;
  1318. }
  1319. VOID
  1320. FreeEntryID(
  1321. PWIZARDUSERMEM pWizardUserMem,
  1322. LPVOID lpEntryId
  1323. )
  1324. {
  1325. if (pWizardUserMem->lpMAPIabInit)
  1326. {
  1327. FreeMapiEntryID(pWizardUserMem,lpEntryId);
  1328. }
  1329. else
  1330. {
  1331. FreeWabEntryID(pWizardUserMem,lpEntryId);
  1332. }
  1333. }
  1334. INT
  1335. AddRecipient(
  1336. HWND hDlg,
  1337. PWIZARDUSERMEM pWizardUserMem
  1338. )
  1339. /*++
  1340. Routine Description:
  1341. Add the current recipient information entered by the user
  1342. into the recipient list
  1343. Arguments:
  1344. hDlg - Handle to the fax recipient wizard page
  1345. pWizardUserMem - Points to user mode memory structure
  1346. Return Value:
  1347. Same meaning as return value from GetCurrentRecipient, i.e.
  1348. = 0 if successful
  1349. > 0 error message string resource ID otherwise
  1350. < 0 other error conditions
  1351. --*/
  1352. {
  1353. PRECIPIENT pRecipient = NULL;
  1354. PRECIPIENT pRecipientList = NULL;
  1355. INT errId = 0;
  1356. HWND hwndLV;
  1357. BOOL bNewRecipient = TRUE;
  1358. //
  1359. // Collect information about the current recipient
  1360. //
  1361. if ((errId = GetCurrentRecipient(hDlg, pWizardUserMem, &pRecipient)) != 0)
  1362. {
  1363. return errId;
  1364. }
  1365. for(pRecipientList = pWizardUserMem->pRecipients; pRecipientList; pRecipientList = pRecipientList->pNext)
  1366. {
  1367. if(pRecipient->pAddress &&
  1368. pRecipient->pName &&
  1369. pRecipientList->pAddress &&
  1370. pRecipientList->pName &&
  1371. !_tcscmp(pRecipient->pAddress, pRecipientList->pAddress) &&
  1372. !_tcsicmp(pRecipient->pName, pRecipientList->pName))
  1373. {
  1374. //
  1375. // The recipient is already in list
  1376. //
  1377. bNewRecipient = FALSE;
  1378. FreeRecipient(pRecipient);
  1379. pRecipient = NULL;
  1380. break;
  1381. }
  1382. }
  1383. if(bNewRecipient && pRecipient)
  1384. {
  1385. //
  1386. // save last recipient country ID
  1387. //
  1388. pWizardUserMem->lpFaxSendWizardData->dwLastRecipientCountryId =
  1389. GetCountryListBoxSel(GetDlgItem(hDlg, IDC_CHOOSE_COUNTRY_COMBO));
  1390. //
  1391. // Insert the current recipient to the recipient list
  1392. //
  1393. hwndLV = GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST);
  1394. if(!hwndLV)
  1395. {
  1396. Assert(hwndLV);
  1397. errId = -1;
  1398. goto error;
  1399. }
  1400. if(!InsertRecipientListItem(hwndLV, pRecipient))
  1401. {
  1402. errId = -1;
  1403. goto error;
  1404. }
  1405. //
  1406. // Autosize the last column to get rid of unnecessary horizontal scroll bar
  1407. //
  1408. ListView_SetColumnWidth(hwndLV, 1, LVSCW_AUTOSIZE_USEHEADER);
  1409. //
  1410. // Add the recipient into the list
  1411. //
  1412. pRecipient->pNext = pWizardUserMem->pRecipients;
  1413. pWizardUserMem->pRecipients = pRecipient;
  1414. }
  1415. //
  1416. // Clear the name and number fields
  1417. //
  1418. if (!SetDlgItemText(hDlg, IDC_CHOOSE_NAME_EDIT, TEXT("")) ||
  1419. !SetDlgItemText(hDlg, IDC_CHOOSE_NUMBER_EDIT, TEXT("")))
  1420. {
  1421. Warning(("SetWindowText failed. ec = 0x%X\n",GetLastError()));
  1422. }
  1423. return errId;
  1424. error:
  1425. FreeRecipient(pRecipient);
  1426. return errId;
  1427. }
  1428. static
  1429. HRESULT
  1430. CopyRecipientInfo(
  1431. PFAX_PERSONAL_PROFILE pfppDestination,
  1432. PRECIPIENT prSource,
  1433. BOOL bLocalServer)
  1434. {
  1435. if ((pfppDestination->lptstrName = DuplicateString(prSource->pName)) == NULL)
  1436. {
  1437. Error(("Memory allocation failed\n"));
  1438. return ERROR_NOT_ENOUGH_MEMORY;
  1439. }
  1440. if ((prSource->bUseDialingRules) && // We have a canonical address and
  1441. bLocalServer && // and it's a local server
  1442. (USE_LOCAL_SERVER_OUTBOUND_ROUTING != prSource->dwDialingRuleId)) // we don't use server's outbound routing
  1443. {
  1444. //
  1445. // We need to translate the address ourseleves, using the specified dialing location
  1446. //
  1447. if (!TranslateAddress (prSource->pAddress,
  1448. prSource->dwDialingRuleId,
  1449. &pfppDestination->lptstrFaxNumber))
  1450. {
  1451. MemFree(pfppDestination->lptstrName);
  1452. pfppDestination->lptstrName = NULL;
  1453. return GetLastError ();
  1454. }
  1455. }
  1456. else
  1457. {
  1458. //
  1459. // Either 'Dial as entered' mode or using the server's outbound routing.
  1460. // Just copy the address as is.
  1461. //
  1462. if ((pfppDestination->lptstrFaxNumber = DuplicateString(prSource->pAddress)) == NULL)
  1463. {
  1464. MemFree(pfppDestination->lptstrName);
  1465. Error(("Memory allocation failed\n"));
  1466. return ERROR_NOT_ENOUGH_MEMORY;
  1467. }
  1468. }
  1469. Verbose(("Copied %ws from %ws\n", pfppDestination->lptstrName,pfppDestination->lptstrFaxNumber));
  1470. return S_OK;
  1471. }
  1472. static HRESULT
  1473. StoreRecipientInfoInternal(
  1474. PWIZARDUSERMEM pWizardUserMem
  1475. )
  1476. {
  1477. DWORD dwIndex;
  1478. HRESULT hResult = S_OK;
  1479. PRECIPIENT pCurrentRecip = NULL,pNewRecip = NULL;
  1480. PFAX_PERSONAL_PROFILE pCurrentPersonalProfile = NULL;
  1481. Assert(pWizardUserMem);
  1482. Assert(pWizardUserMem->lpInitialData);
  1483. Assert(pWizardUserMem->pRecipients == NULL);
  1484. if (!pWizardUserMem->lpInitialData->dwNumberOfRecipients) // zero recipients
  1485. return S_OK;
  1486. for (dwIndex = 0; dwIndex < pWizardUserMem->lpInitialData->dwNumberOfRecipients; dwIndex++)
  1487. {
  1488. if (!(pNewRecip = MemAlloc(sizeof(RECIPIENT))))
  1489. {
  1490. hResult = ERROR_NOT_ENOUGH_MEMORY;
  1491. Error(("Memory allocation failed\n"));
  1492. goto error;
  1493. }
  1494. ZeroMemory(pNewRecip,sizeof(RECIPIENT));
  1495. if (dwIndex == 0)
  1496. pWizardUserMem->pRecipients = pNewRecip;
  1497. pCurrentPersonalProfile = &pWizardUserMem->lpInitialData->lpRecipientsInfo[dwIndex];
  1498. if (pCurrentPersonalProfile->lptstrName && !(pNewRecip->pName = DuplicateString(pCurrentPersonalProfile->lptstrName)))
  1499. {
  1500. hResult = ERROR_NOT_ENOUGH_MEMORY;
  1501. Error(("Memory allocation failed\n"));
  1502. goto error;
  1503. }
  1504. if (pCurrentPersonalProfile->lptstrFaxNumber && !(pNewRecip->pAddress = DuplicateString(pCurrentPersonalProfile->lptstrFaxNumber)))
  1505. {
  1506. hResult = ERROR_NOT_ENOUGH_MEMORY;
  1507. Error(("Memory allocation failed\n"));
  1508. goto error;
  1509. }
  1510. pNewRecip->pCountry = NULL;
  1511. pNewRecip->pNext = NULL;
  1512. pNewRecip->lpEntryId = NULL;
  1513. pNewRecip->lpEntryId = 0;
  1514. pNewRecip->bFromAddressBook = FALSE;
  1515. if (!pCurrentRecip)
  1516. pCurrentRecip = pNewRecip;
  1517. else {
  1518. pCurrentRecip->pNext = pNewRecip;
  1519. pCurrentRecip = pCurrentRecip->pNext;
  1520. }
  1521. }
  1522. goto exit;
  1523. error:
  1524. FreeRecipientList(pWizardUserMem);
  1525. exit:
  1526. return hResult;
  1527. }
  1528. VOID
  1529. FreeRecipientList(
  1530. PWIZARDUSERMEM pWizardUserMem
  1531. )
  1532. /*++
  1533. Routine Description:
  1534. Free up the list of recipients associated with each fax job
  1535. Arguments:
  1536. pWizardUserMem - Points to the user mode memory structure
  1537. Return Value:
  1538. NONE
  1539. --*/
  1540. {
  1541. PRECIPIENT pNextRecipient, pFreeRecipient;
  1542. Assert(pWizardUserMem);
  1543. //
  1544. // Free the list of recipients
  1545. //
  1546. pNextRecipient = pWizardUserMem->pRecipients;
  1547. while (pNextRecipient) {
  1548. pFreeRecipient = pNextRecipient;
  1549. pNextRecipient = pNextRecipient->pNext;
  1550. FreeRecipient(pFreeRecipient);
  1551. }
  1552. pWizardUserMem->pRecipients = NULL;
  1553. }
  1554. INT
  1555. SizeOfRecipientList(
  1556. PWIZARDUSERMEM pWizardUserMem
  1557. )
  1558. /*++
  1559. Routine Description:
  1560. Calculates size of the list of recipients associated with each fax job
  1561. Arguments:
  1562. pWizardUserMem - Points to the user mode memory structure
  1563. Return Value:
  1564. size of the list
  1565. --*/
  1566. {
  1567. PRECIPIENT pNextRecipient;
  1568. INT iCount = 0;
  1569. Assert(pWizardUserMem);
  1570. pNextRecipient = pWizardUserMem->pRecipients;
  1571. while (pNextRecipient) {
  1572. iCount++;
  1573. pNextRecipient = pNextRecipient->pNext;
  1574. }
  1575. return iCount;
  1576. }
  1577. INT
  1578. FillRecipientListView(
  1579. PWIZARDUSERMEM pWizardUserMem,
  1580. HWND hWndList
  1581. )
  1582. /*++
  1583. Routine Description:
  1584. Fills recipient list view
  1585. Arguments:
  1586. pWizardUserMem - Points to the user mode memory structure
  1587. Return Value:
  1588. NONE
  1589. --*/
  1590. {
  1591. PRECIPIENT pNextRecipient;
  1592. Assert(pWizardUserMem);
  1593. pNextRecipient = pWizardUserMem->pRecipients;
  1594. while (pNextRecipient) {
  1595. if (!InsertRecipientListItem(hWndList,pNextRecipient))
  1596. {
  1597. Warning(("InsertRecipientListItem failed"));
  1598. }
  1599. pNextRecipient = pNextRecipient->pNext;
  1600. }
  1601. //
  1602. // Autosize the last column to get rid of unnecessary horizontal scroll bar
  1603. //
  1604. ListView_SetColumnWidth(hWndList, 1, LVSCW_AUTOSIZE_USEHEADER);
  1605. return TRUE;
  1606. }
  1607. BOOL
  1608. IsAreaCodeMandatory(
  1609. DWORD dwCountryCode,
  1610. PFAX_TAPI_LINECOUNTRY_LIST pFaxCountryList
  1611. )
  1612. /*++
  1613. Routine name : IsAreaCodeMandatory
  1614. Routine description:
  1615. Checks if an area code is mandatory for a specific long distance rule
  1616. Author:
  1617. Oded Sacher (OdedS), May, 2000
  1618. Arguments:
  1619. dwCountryCode [in] - The country country code.
  1620. pFaxCountryList [in] - The country list obtained by a call to FaxGetCountryList()
  1621. Return Value:
  1622. TRUE - The area code is needed.
  1623. FALSE - The area code is not mandatory.
  1624. --*/
  1625. {
  1626. DWORD dwIndex;
  1627. Assert (pFaxCountryList);
  1628. for (dwIndex=0; dwIndex < pFaxCountryList->dwNumCountries; dwIndex++)
  1629. {
  1630. if (pFaxCountryList->LineCountryEntries[dwIndex].dwCountryCode == dwCountryCode)
  1631. {
  1632. //
  1633. // Matching country code - Check long distance rule.
  1634. //
  1635. if (pFaxCountryList->LineCountryEntries[dwIndex].lpctstrLongDistanceRule)
  1636. {
  1637. if (_tcschr(pFaxCountryList->LineCountryEntries[dwIndex].lpctstrLongDistanceRule, TEXT('F')) != NULL)
  1638. {
  1639. return TRUE;
  1640. }
  1641. return FALSE;
  1642. }
  1643. }
  1644. }
  1645. return FALSE;
  1646. }
  1647. BOOL
  1648. AddRecipientsToList(
  1649. IN HWND hDlg,
  1650. IN OUT PWIZARDUSERMEM pWizardUserMem
  1651. )
  1652. {
  1653. /*++
  1654. Routine Description:
  1655. Adds recipients to list control. Checks addresses of each
  1656. recipient form the list. Inserts to the GUI list and new recipient list
  1657. canonical adresses or confirmed addresses by user only.
  1658. Returns a new list of recipients in PWIZARDUSERMEM struct.
  1659. Arguments:
  1660. hDlg - Handle to the fax recipient wizard page
  1661. pWizardUserMem - Points to user mode memory structure
  1662. Return Value:
  1663. TRUE if successful, FALSE otherwise
  1664. --*/
  1665. HWND hwndLV = NULL;
  1666. PRECIPIENT tmpRecip = NULL, pPrevRecip=NULL;
  1667. if (! (hwndLV = GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST)))
  1668. return FALSE;
  1669. if (!ListView_DeleteAllItems(hwndLV))
  1670. {
  1671. Warning(("ListView_DeleteAllItems failed\n"));
  1672. }
  1673. for (tmpRecip = pWizardUserMem->pRecipients; tmpRecip; tmpRecip = tmpRecip->pNext)
  1674. {
  1675. DWORD dwRes;
  1676. BOOL bCanonicalAdress;
  1677. DWORD dwCountryCode, dwAreaCode;
  1678. dwRes = IsCanonicalAddress( tmpRecip->pAddress,
  1679. &bCanonicalAdress,
  1680. &dwCountryCode,
  1681. &dwAreaCode,
  1682. NULL);
  1683. if (ERROR_SUCCESS != dwRes)
  1684. {
  1685. Error(("IsCanonicalAddress failed\n"));
  1686. }
  1687. else
  1688. {
  1689. tmpRecip->bUseDialingRules = TRUE;
  1690. tmpRecip->dwDialingRuleId = g_dwCurrentDialingLocation;
  1691. if (bCanonicalAdress)
  1692. {
  1693. if (IsAreaCodeMandatory(dwCountryCode, pWizardUserMem->pCountryList) &&
  1694. ROUTING_RULE_AREA_CODE_ANY == dwAreaCode)
  1695. {
  1696. tmpRecip->bUseDialingRules = FALSE;
  1697. }
  1698. }
  1699. else
  1700. {
  1701. tmpRecip->bUseDialingRules = FALSE;
  1702. }
  1703. }
  1704. if (!InsertRecipientListItem(hwndLV, tmpRecip))
  1705. {
  1706. Warning(("InsertRecipientListItem failed"));
  1707. }
  1708. }
  1709. // remove empty recipients
  1710. for (tmpRecip = pWizardUserMem->pRecipients,pPrevRecip=NULL; tmpRecip; )
  1711. {
  1712. if ((tmpRecip->pAddress == NULL) && (tmpRecip->pName == NULL))
  1713. {
  1714. // Should be removed
  1715. if (pPrevRecip==NULL)
  1716. {
  1717. pWizardUserMem->pRecipients = tmpRecip->pNext;
  1718. MemFree(tmpRecip);
  1719. tmpRecip = pWizardUserMem->pRecipients;
  1720. }
  1721. else
  1722. {
  1723. pPrevRecip->pNext= tmpRecip->pNext;
  1724. MemFree(tmpRecip);
  1725. tmpRecip = pPrevRecip->pNext;
  1726. }
  1727. }
  1728. else
  1729. {
  1730. pPrevRecip = tmpRecip;
  1731. tmpRecip = tmpRecip->pNext;
  1732. }
  1733. }
  1734. return TRUE;
  1735. }
  1736. BOOL
  1737. DoAddressBook(
  1738. HWND hDlg,
  1739. PWIZARDUSERMEM pWizardUserMem
  1740. )
  1741. /*++
  1742. Routine Description:
  1743. Display the MAPI address book dialog
  1744. Arguments:
  1745. hDlg - Handle to the fax recipient wizard page
  1746. pWizardUserMem - Points to user mode memory structure
  1747. Return Value:
  1748. TRUE if successful, FALSE otherwise
  1749. --*/
  1750. {
  1751. HWND hwndLV = NULL;
  1752. BOOL result = TRUE;
  1753. PRECIPIENT pNewRecip = NULL;
  1754. //
  1755. // Init MAPI address book
  1756. //
  1757. if (!pWizardUserMem->lpMAPIabInit)
  1758. {
  1759. pWizardUserMem->lpMAPIabInit = InitializeMAPIAB(g_hResource,hDlg);
  1760. }
  1761. //
  1762. // Init WAB
  1763. //
  1764. if (!pWizardUserMem->lpWabInit && !pWizardUserMem->lpMAPIabInit)
  1765. {
  1766. pWizardUserMem->lpWabInit = InitializeWAB(g_hResource);
  1767. }
  1768. if(!pWizardUserMem->lpMAPIabInit &&
  1769. !pWizardUserMem->lpWabInit)
  1770. {
  1771. ErrorMessageBox(hDlg, IDS_ERR_NO_ADDRESS_BOOK, MB_ICONERROR);
  1772. return FALSE;
  1773. }
  1774. //
  1775. // Add current recipient to the list if necessary
  1776. //
  1777. AddRecipient(hDlg, pWizardUserMem);
  1778. if (pWizardUserMem->lpMAPIabInit)
  1779. {
  1780. result = CallMAPIabAddress(
  1781. hDlg,
  1782. pWizardUserMem,
  1783. &pNewRecip
  1784. );
  1785. }
  1786. else if(pWizardUserMem->lpWabInit)
  1787. {
  1788. result = CallWabAddress(
  1789. hDlg,
  1790. pWizardUserMem,
  1791. &pNewRecip
  1792. );
  1793. }
  1794. FreeRecipientList(pWizardUserMem);
  1795. // copy new list of recipients from Address book to the pWizardUserMem
  1796. pWizardUserMem->pRecipients = pNewRecip;
  1797. if (!AddRecipientsToList(
  1798. hDlg,
  1799. pWizardUserMem))
  1800. {
  1801. Error(("Failed to add recipients to the list\n"));
  1802. }
  1803. if (!result)
  1804. {
  1805. DisplayMessageDialog( hDlg, MB_OK, IDS_WIZARD_TITLE, IDS_BAD_ADDRESS_TYPE );
  1806. }
  1807. return result;
  1808. }
  1809. LPTSTR
  1810. GetEMailAddress(
  1811. HWND hDlg,
  1812. PWIZARDUSERMEM pWizardUserMem
  1813. )
  1814. /*++
  1815. Routine Description:
  1816. Display the MAPI address book dialog
  1817. Arguments:
  1818. hDlg - Handle to the fax recipient wizard page
  1819. pWizardUserMem - Points to user mode memory structure
  1820. Return Value:
  1821. TRUE if successful, FALSE otherwise
  1822. --*/
  1823. {
  1824. LPTSTR result;
  1825. if(!pWizardUserMem->lpMAPIabInit)
  1826. {
  1827. pWizardUserMem->lpMAPIabInit = InitializeMAPIAB(g_hResource,hDlg);
  1828. }
  1829. if(!pWizardUserMem->lpMAPIabInit && !pWizardUserMem->lpWabInit)
  1830. {
  1831. pWizardUserMem->lpWabInit = InitializeWAB(g_hResource);
  1832. }
  1833. if(!pWizardUserMem->lpMAPIabInit && !pWizardUserMem->lpWabInit)
  1834. {
  1835. ErrorMessageBox(hDlg, IDS_ERR_NO_ADDRESS_BOOK, MB_ICONERROR);
  1836. return FALSE;
  1837. }
  1838. //
  1839. // Get a handle to the recipient list window
  1840. //
  1841. if (pWizardUserMem->lpMAPIabInit)
  1842. {
  1843. result = CallMAPIabAddressEmail(hDlg,
  1844. pWizardUserMem);
  1845. }
  1846. else
  1847. {
  1848. result = CallWabAddressEmail(hDlg,
  1849. pWizardUserMem);
  1850. }
  1851. return result;
  1852. }
  1853. BOOL
  1854. ValidateRecipients(
  1855. HWND hDlg,
  1856. PWIZARDUSERMEM pWizardUserMem
  1857. )
  1858. /*++
  1859. Routine Description:
  1860. Validate the list of fax recipients entered by the user
  1861. Arguments:
  1862. hDlg - Handle to the fax recipient wizard page
  1863. pWizardUserMem - Points to user mode memory structure
  1864. Return Value:
  1865. TRUE if successful, FALSE otherwise
  1866. --*/
  1867. {
  1868. INT iErrorStringId = 0;
  1869. INT iCtrlId = 0;
  1870. BOOL bDisplayPopup = FALSE;
  1871. if ((0 == GetWindowTextLength(GetDlgItem(hDlg, IDC_CHOOSE_NUMBER_EDIT))) &&
  1872. (0 == GetWindowTextLength(GetDlgItem(hDlg, IDC_CHOOSE_NAME_EDIT))))
  1873. {
  1874. //
  1875. // The name + phone number are empty.
  1876. // This means that the current recipient will not be added to the list.
  1877. // It's valid to press 'Next' on the recipients page if the list of recipients is not empty
  1878. //
  1879. if (!pWizardUserMem->pRecipients)
  1880. {
  1881. //
  1882. // At least one recipient must be there
  1883. //
  1884. iErrorStringId = IDS_BAD_RECIPIENT_NAME;
  1885. }
  1886. }
  1887. else
  1888. {
  1889. //
  1890. // There's a phone number
  1891. // Add current recipient to the list
  1892. //
  1893. iErrorStringId = AddRecipient(hDlg, pWizardUserMem);
  1894. }
  1895. if (0 == iErrorStringId)
  1896. {
  1897. //
  1898. // no errors so far, check recipients limit
  1899. //
  1900. DWORD dwRecipientsCount = SizeOfRecipientList(pWizardUserMem);
  1901. if (dwRecipientsCount > 0)
  1902. {
  1903. //
  1904. // There are some recipients, check the recipient limit.
  1905. //
  1906. if (0 != pWizardUserMem->dwRecipientsLimit && // The recipients limit exists
  1907. dwRecipientsCount > pWizardUserMem->dwRecipientsLimit)
  1908. {
  1909. //
  1910. // recipients limit exceeded, tell the user to remove some
  1911. //
  1912. iErrorStringId = IDS_WZRD_RECIPIENTS_LIMIT;
  1913. }
  1914. else
  1915. {
  1916. //
  1917. // All is OK
  1918. //
  1919. return TRUE;
  1920. }
  1921. }
  1922. }
  1923. //
  1924. // Failed to add recipient
  1925. // Set current focus to the appropriate text field as a convenience
  1926. //
  1927. switch (iErrorStringId)
  1928. {
  1929. case IDS_INVALID_RECIPIENT_NUMBER:
  1930. SetDlgItemText(hDlg, IDC_CHOOSE_NUMBER_EDIT, _T(""));
  1931. //
  1932. // Fall through...
  1933. //
  1934. case IDS_BAD_RECIPIENT_NUMBER:
  1935. iCtrlId = IDC_CHOOSE_NUMBER_EDIT;
  1936. bDisplayPopup = TRUE;
  1937. break;
  1938. case IDS_ERROR_AREA_CODE:
  1939. SetDlgItemText(hDlg, IDC_CHOOSE_AREA_CODE_EDIT, _T(""));
  1940. //
  1941. // Fall through...
  1942. //
  1943. case IDS_BAD_RECIPIENT_AREACODE:
  1944. iCtrlId = IDC_CHOOSE_AREA_CODE_EDIT;
  1945. bDisplayPopup = TRUE;
  1946. break;
  1947. case IDS_BAD_RECIPIENT_COUNTRY_CODE:
  1948. iCtrlId = IDC_CHOOSE_COUNTRY_COMBO;
  1949. bDisplayPopup = TRUE;
  1950. break;
  1951. case IDS_BAD_RECIPIENT_NAME:
  1952. case IDS_WZRD_RECIPIENTS_LIMIT:
  1953. bDisplayPopup = TRUE;
  1954. //
  1955. // Fall through...
  1956. //
  1957. default:
  1958. iCtrlId = IDC_CHOOSE_NAME_EDIT;
  1959. break;
  1960. }
  1961. if (bDisplayPopup)
  1962. {
  1963. //
  1964. // Display an error message
  1965. //
  1966. if (IDS_WZRD_RECIPIENTS_LIMIT == iErrorStringId)
  1967. {
  1968. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, iErrorStringId, pWizardUserMem->dwRecipientsLimit);
  1969. }
  1970. else
  1971. {
  1972. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, iErrorStringId);
  1973. }
  1974. }
  1975. SetFocus(GetDlgItem(hDlg, iCtrlId));
  1976. return FALSE;
  1977. } // ValidateRecipients
  1978. PRECIPIENT *
  1979. FindRecipient(
  1980. PWIZARDUSERMEM pWizardUserMem,
  1981. PRECIPIENT pRecipient
  1982. )
  1983. /*++
  1984. Routine Description:
  1985. Check if the specified recipient is in the list of recipients
  1986. Arguments:
  1987. pWizardUserMem - Points to user mode memory structure
  1988. pRecipient - Specifies the recipient to be found
  1989. Return Value:
  1990. Address of the link pointer to the specified recipient
  1991. NULL if the specified recipient is not found
  1992. --*/
  1993. {
  1994. PRECIPIENT pCurrent, *ppPrevNext;
  1995. //
  1996. // Search for the specified recipient in the list
  1997. //
  1998. ppPrevNext = (PRECIPIENT *) &pWizardUserMem->pRecipients;
  1999. pCurrent = pWizardUserMem->pRecipients;
  2000. while (pCurrent && pCurrent != pRecipient) {
  2001. ppPrevNext = (PRECIPIENT *) &pCurrent->pNext;
  2002. pCurrent = pCurrent->pNext;
  2003. }
  2004. //
  2005. // Return the address of the link pointer to the specified recipient
  2006. // or NULL if the specified recipient is not found
  2007. //
  2008. return pCurrent ? ppPrevNext : NULL;
  2009. }
  2010. BOOL
  2011. RemoveRecipient(
  2012. HWND hDlg,
  2013. PWIZARDUSERMEM pWizardUserMem
  2014. )
  2015. /*++
  2016. Routine Description:
  2017. Remove the currently selected recipient from the recipient list
  2018. Arguments:
  2019. hDlg - Handle to the fax recipient wizard page
  2020. pWizardUserMem - Points to user mode memory structure
  2021. Return Value:
  2022. TRUE if successful, FALSE otherwise
  2023. --*/
  2024. {
  2025. PRECIPIENT pRecipient, *ppPrevNext;
  2026. INT selIndex;
  2027. HWND hwndLV;
  2028. //
  2029. // Get the currently selected recipient, and
  2030. // Find the current recipient in the list, then
  2031. // Delete the current recipient and select the next one below it
  2032. //
  2033. if ((hwndLV = GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST)) &&
  2034. (selIndex = ListView_GetNextItem(hwndLV, -1, LVNI_ALL|LVNI_SELECTED)) != -1 &&
  2035. (pRecipient = GetRecipientListItem(hwndLV, selIndex)) &&
  2036. (ppPrevNext = FindRecipient(pWizardUserMem, pRecipient)) &&
  2037. ListView_DeleteItem(hwndLV, selIndex))
  2038. {
  2039. ListView_SetItemState(hwndLV,
  2040. selIndex,
  2041. LVIS_SELECTED|LVIS_FOCUSED,
  2042. LVIS_SELECTED|LVIS_FOCUSED);
  2043. //
  2044. // Delete the recipient from the internal list
  2045. //
  2046. *ppPrevNext = pRecipient->pNext;
  2047. FreeRecipient(pRecipient);
  2048. //
  2049. // Autosize the last column to get rid of unnecessary horizontal scroll bar
  2050. //
  2051. ListView_SetColumnWidth(hwndLV, 1, LVSCW_AUTOSIZE_USEHEADER);
  2052. return TRUE;
  2053. }
  2054. MessageBeep(MB_ICONHAND);
  2055. return FALSE;
  2056. }
  2057. VOID
  2058. EditRecipient(
  2059. HWND hDlg,
  2060. PWIZARDUSERMEM pWizardUserMem
  2061. )
  2062. /*++
  2063. Routine Description:
  2064. Edit the currently selected recipient in the recipient list
  2065. Arguments:
  2066. hDlg - Handle to the fax recipient wizard page
  2067. pWizardUserMem - Points to user mode memory structure
  2068. Return Value:
  2069. NONE
  2070. --*/
  2071. {
  2072. INT_PTR dlgResult;
  2073. CHECKNUMBER checkNumber = {0};
  2074. DWORD dwListIndex;
  2075. LV_ITEM lvi;
  2076. HWND hListWnd;
  2077. PRECIPIENT pRecip,pNewRecip;
  2078. TCHAR szCountry[MAX_STRING_LEN],szName[MAX_STRING_LEN],szAddress[MAX_STRING_LEN];
  2079. ZeroMemory(szName,sizeof(TCHAR)*MAX_STRING_LEN);
  2080. ZeroMemory(szAddress,sizeof(TCHAR)*MAX_STRING_LEN);
  2081. ZeroMemory(szCountry,sizeof(TCHAR)*MAX_STRING_LEN);
  2082. hListWnd = GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST);
  2083. dwListIndex = ListView_GetNextItem(hListWnd , -1, LVNI_ALL | LVNI_SELECTED);
  2084. while (dwListIndex != -1)
  2085. {
  2086. // Initialize lvi
  2087. lvi.mask = LVIF_PARAM;
  2088. // Set the item number
  2089. lvi.iItem = dwListIndex;
  2090. // Get the selected item from the list view
  2091. if (ListView_GetItem(hListWnd, &lvi))
  2092. {
  2093. pRecip = (PRECIPIENT) lvi.lParam;
  2094. Assert(pRecip);
  2095. if (!pRecip)
  2096. {
  2097. Error(("Failed to get recipient from recipient list"));
  2098. return;
  2099. }
  2100. if (InitCheckNumber(_tcscpy(szName,pRecip->pName ? pRecip->pName : _T("")),
  2101. _tcscpy(szAddress,pRecip->pAddress ? pRecip->pAddress : _T("")),
  2102. _tcscpy(szCountry,pRecip->pCountry ? pRecip->pCountry : _T("")),
  2103. pRecip->dwCountryId,
  2104. pRecip->dwDialingRuleId,
  2105. pRecip->bUseDialingRules,
  2106. pWizardUserMem->pCountryList,
  2107. &checkNumber))
  2108. {
  2109. dlgResult = DialogBoxParam(
  2110. (HINSTANCE) g_hResource,
  2111. MAKEINTRESOURCE( IDD_CHECK_FAX_NUMBER ),
  2112. hDlg,
  2113. CheckFaxNumberDlgProc,
  2114. (LPARAM) &checkNumber
  2115. );
  2116. if (dlgResult)
  2117. {
  2118. RemoveRecipient(hDlg, pWizardUserMem);
  2119. if (!(pNewRecip = MemAllocZ(sizeof(RECIPIENT))))
  2120. {
  2121. Error(("Memory allocation failed"));
  2122. FreeCheckNumberFields(&checkNumber);
  2123. return;
  2124. }
  2125. ZeroMemory(pNewRecip,sizeof(RECIPIENT));
  2126. if (checkNumber.lptstrName && !(pNewRecip->pName = StringDup(checkNumber.lptstrName)))
  2127. {
  2128. Error(("Memory allocation failed"));
  2129. MemFree(pNewRecip);
  2130. FreeCheckNumberFields(&checkNumber);
  2131. return;
  2132. }
  2133. if (checkNumber.lptstrAddress && !(pNewRecip->pAddress = StringDup(checkNumber.lptstrAddress)))
  2134. {
  2135. Error(("Memory allocation failed"));
  2136. MemFree(pNewRecip->pName);
  2137. MemFree(pNewRecip);
  2138. FreeCheckNumberFields(&checkNumber);
  2139. return;
  2140. }
  2141. if (szCountry && !(pNewRecip->pCountry = StringDup(szCountry)))
  2142. {
  2143. Error(("Memory allocation failed"));
  2144. MemFree(pNewRecip->pName);
  2145. MemFree(pNewRecip->pAddress);
  2146. MemFree(pNewRecip);
  2147. FreeCheckNumberFields(&checkNumber);
  2148. return;
  2149. }
  2150. pNewRecip->dwCountryId = checkNumber.dwCountryId;
  2151. pNewRecip->bUseDialingRules = checkNumber.bUseDialingRules;
  2152. pNewRecip->dwDialingRuleId = checkNumber.dwDialingRuleId;
  2153. if (InsertRecipientListItem(hListWnd, pNewRecip))
  2154. {
  2155. pNewRecip->pNext = pWizardUserMem->pRecipients;
  2156. pWizardUserMem->pRecipients = pNewRecip;
  2157. }
  2158. else
  2159. {
  2160. FreeRecipient(pNewRecip);
  2161. }
  2162. }
  2163. FreeCheckNumberFields(&checkNumber);
  2164. }
  2165. else
  2166. {
  2167. Error(("Failed to initialize CHECKNUMBER structure"));
  2168. }
  2169. }
  2170. dwListIndex = ListView_GetNextItem(hListWnd, dwListIndex, LVNI_ALL | LVNI_SELECTED);
  2171. }
  2172. }
  2173. VOID
  2174. LocationListSelChange(
  2175. HWND hDlg,
  2176. PWIZARDUSERMEM pUserMem
  2177. )
  2178. /*++
  2179. Routine Description:
  2180. Change the default TAPI location
  2181. Arguments:
  2182. hDlg - Handle to "Compose New Fax" wizard window
  2183. pUserMem - Pointer to user mode memory structure
  2184. Return Value:
  2185. NONE
  2186. --*/
  2187. {
  2188. HWND hwndList;
  2189. LRESULT selIndex;
  2190. DWORD dwLocationID;
  2191. if ((hwndList = GetDlgItem(hDlg, IDC_COMBO_DIALING_RULES)) &&
  2192. (selIndex = SendMessage(hwndList, CB_GETCURSEL, 0, 0)) != CB_ERR &&
  2193. (dwLocationID = (DWORD)SendMessage(hwndList, CB_GETITEMDATA, selIndex, 0)) != CB_ERR)
  2194. {
  2195. if (USE_LOCAL_SERVER_OUTBOUND_ROUTING != dwLocationID)
  2196. {
  2197. //
  2198. // User selected a real location - set it (in TAPI)
  2199. //
  2200. SetCurrentLocation(dwLocationID);
  2201. pUserMem->lpFaxSendWizardData->bUseOutboundRouting = FALSE;
  2202. }
  2203. else
  2204. {
  2205. //
  2206. // User selected to use the server's outbound routing rules - mark that.
  2207. // We use that information next time we run the wizard, to select the location in the combo-box.
  2208. //
  2209. pUserMem->lpFaxSendWizardData->bUseOutboundRouting = TRUE;
  2210. }
  2211. //
  2212. // Save it globally, will be used by AddRecipient
  2213. //
  2214. g_dwCurrentDialingLocation = dwLocationID;
  2215. }
  2216. } // LocationListSelChange
  2217. VOID
  2218. LocationListInit(
  2219. HWND hDlg,
  2220. PWIZARDUSERMEM pUserMem
  2221. )
  2222. /*++
  2223. Routine Description:
  2224. Initialize the list of TAPI locations
  2225. Arguments:
  2226. hDlg - Handle to "Compose New Fax" wizard window
  2227. pUserMem - Pointer to user mode memory structure
  2228. Return Value:
  2229. NONE
  2230. --*/
  2231. {
  2232. HWND hwndList;
  2233. DWORD dwIndex;
  2234. LRESULT listIdx;
  2235. LPTSTR lptstrLocationName;
  2236. LPTSTR lptstrSelectedName = NULL;
  2237. DWORD dwSelectedLocationId;
  2238. LPLINETRANSLATECAPS pTranslateCaps = NULL;
  2239. LPLINELOCATIONENTRY pLocationEntry;
  2240. Assert (pUserMem);
  2241. Assert (pUserMem->isLocalPrinter)
  2242. //
  2243. // Get the list of locations from TAPI and use it
  2244. // to initialize the location combo-box.
  2245. //
  2246. hwndList = GetDlgItem(hDlg, IDC_COMBO_DIALING_RULES);
  2247. Assert (hwndList);
  2248. if (WaitForSingleObject( pUserMem->hTAPIEvent, INFINITE ) != WAIT_OBJECT_0)
  2249. {
  2250. Error(("WaitForSingleObject failed. ec = 0x%X\n", GetLastError()));
  2251. Assert(FALSE);
  2252. return;
  2253. }
  2254. if (pTranslateCaps = GetTapiLocationInfo(hDlg))
  2255. {
  2256. SendMessage(hwndList, CB_RESETCONTENT, 0, 0);
  2257. pLocationEntry = (LPLINELOCATIONENTRY)
  2258. ((PBYTE) pTranslateCaps + pTranslateCaps->dwLocationListOffset);
  2259. for (dwIndex=0; dwIndex < pTranslateCaps->dwNumLocations; dwIndex++)
  2260. {
  2261. lptstrLocationName = (LPTSTR)
  2262. ((PBYTE) pTranslateCaps + pLocationEntry->dwLocationNameOffset);
  2263. if (pLocationEntry->dwPermanentLocationID == pTranslateCaps->dwCurrentLocationID)
  2264. {
  2265. lptstrSelectedName = lptstrLocationName;
  2266. dwSelectedLocationId = pLocationEntry->dwPermanentLocationID;
  2267. }
  2268. listIdx = SendMessage(hwndList, CB_INSERTSTRING, 0, (LPARAM) lptstrLocationName);
  2269. if (listIdx != CB_ERR)
  2270. {
  2271. SendMessage(hwndList,
  2272. CB_SETITEMDATA,
  2273. listIdx,
  2274. pLocationEntry->dwPermanentLocationID);
  2275. }
  2276. pLocationEntry++;
  2277. }
  2278. }
  2279. //
  2280. // Let's see if we should add the "Use Outbound Routing Rules" option to the list
  2281. //
  2282. if (!IsDesktopSKU())
  2283. {
  2284. //
  2285. // Not consumer SKU.
  2286. // There's a chance we have outbound routing rules.
  2287. // Add this option to the combo-box
  2288. //
  2289. TCHAR tszUseOutboundRouting[MAX_PATH];
  2290. if (LoadString (g_hResource, IDS_USE_OUTBOUND_ROUTING, tszUseOutboundRouting, ARR_SIZE(tszUseOutboundRouting)))
  2291. {
  2292. SendMessage(hwndList,
  2293. CB_INSERTSTRING,
  2294. 0,
  2295. (LPARAM)tszUseOutboundRouting);
  2296. SendMessage(hwndList,
  2297. CB_SETITEMDATA,
  2298. 0,
  2299. USE_LOCAL_SERVER_OUTBOUND_ROUTING);
  2300. //
  2301. // Restore last 'use outbound routing' option
  2302. //
  2303. if (pUserMem->lpFaxSendWizardData->bUseOutboundRouting)
  2304. {
  2305. lptstrSelectedName = NULL;
  2306. g_dwCurrentDialingLocation = USE_LOCAL_SERVER_OUTBOUND_ROUTING;
  2307. SendMessage(hwndList,
  2308. CB_SETCURSEL,
  2309. 0,
  2310. 0);
  2311. }
  2312. }
  2313. else
  2314. {
  2315. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  2316. }
  2317. }
  2318. if (lptstrSelectedName != NULL)
  2319. {
  2320. //
  2321. // Select the current dialing location in the combo-box
  2322. //
  2323. SendMessage(hwndList,
  2324. CB_SELECTSTRING,
  2325. (WPARAM) -1,
  2326. (LPARAM) lptstrSelectedName);
  2327. g_dwCurrentDialingLocation = dwSelectedLocationId;
  2328. }
  2329. MemFree(pTranslateCaps);
  2330. } // LocationListInit
  2331. void
  2332. CalcRecipientButtonsState(
  2333. HWND hDlg,
  2334. PWIZARDUSERMEM pWizardUserMem
  2335. )
  2336. /*++
  2337. Routine Description:
  2338. calculate Add, Remove and Edit buttons state
  2339. Arguments:
  2340. hDlg - Identifies the wizard page
  2341. pWizardUserMem - pointer to WIZARDUSERMEM struct
  2342. Return Value:
  2343. none
  2344. --*/
  2345. {
  2346. BOOL bEnable;
  2347. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_ADD),
  2348. GetCurrentRecipient(hDlg,pWizardUserMem, NULL) == 0);
  2349. bEnable = (ListView_GetNextItem(GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST),
  2350. -1, LVNI_ALL | LVNI_SELECTED) != -1);
  2351. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_REMOVE), bEnable);
  2352. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_EDIT), bEnable);
  2353. }
  2354. DWORD
  2355. GetControlRect(
  2356. HWND hCtrl,
  2357. PRECT pRc
  2358. )
  2359. /*++
  2360. Routine Description:
  2361. Retrieves the dimensions of the dialog control in dialog coordinates
  2362. Arguments:
  2363. hCtrl [in] - Identifies the dialog control
  2364. pRc [out] - control dimensions rect
  2365. Return Value:
  2366. Win32 error code
  2367. --*/
  2368. {
  2369. DWORD dwRes = ERROR_SUCCESS;
  2370. POINT pt;
  2371. if(!pRc || !hCtrl)
  2372. {
  2373. return ERROR_INVALID_PARAMETER;
  2374. }
  2375. //
  2376. // Get the control rect
  2377. //
  2378. if(!GetWindowRect(hCtrl, pRc))
  2379. {
  2380. dwRes = GetLastError();
  2381. Error(("GetWindowRect failed. ec = 0x%X\n", dwRes));
  2382. return dwRes;
  2383. }
  2384. //
  2385. // Convert the control dimensions to the dialog coordinates
  2386. //
  2387. pt.x = pRc->left;
  2388. pt.y = pRc->top;
  2389. if(!ScreenToClient (GetParent(hCtrl), &pt))
  2390. {
  2391. dwRes = GetLastError();
  2392. Error(("ScreenToClient failed. ec = 0x%X\n", dwRes));
  2393. return dwRes;
  2394. }
  2395. pRc->left = pt.x;
  2396. pRc->top = pt.y;
  2397. pt.x = pRc->right;
  2398. pt.y = pRc->bottom;
  2399. if(!ScreenToClient (GetParent(hCtrl), &pt))
  2400. {
  2401. dwRes = GetLastError();
  2402. Error(("ScreenToClient failed. ec = 0x%X\n", dwRes));
  2403. return dwRes;
  2404. }
  2405. pRc->right = pt.x;
  2406. pRc->bottom = pt.y;
  2407. return dwRes;
  2408. } // GetControlRect
  2409. INT_PTR
  2410. RecipientWizProc(
  2411. HWND hDlg,
  2412. UINT message,
  2413. WPARAM wParam,
  2414. LPARAM lParam
  2415. )
  2416. /*++
  2417. Routine Description:
  2418. Dialog procedure for the first wizard page: selecting the fax recipient
  2419. Arguments:
  2420. hDlg - Identifies the wizard page
  2421. message - Specifies the message
  2422. wParam - Specifies additional message-specific information
  2423. lParam - Specifies additional message-specific information
  2424. Return Value:
  2425. Depends on the message parameter
  2426. --*/
  2427. {
  2428. PWIZARDUSERMEM pWizardUserMem;
  2429. DWORD countryId = 0;
  2430. INT cmd;
  2431. NMHDR *pNMHdr;
  2432. HANDLE hEditControl;
  2433. DWORD dwMessagePos;
  2434. static HMENU hMenu = NULL;
  2435. // hReciptMenu is the handle to the receipt menu
  2436. static HMENU hReciptMenu;
  2437. BOOL bEnable;
  2438. //
  2439. // Maximum length for various text fields
  2440. //
  2441. static INT textLimits[] =
  2442. {
  2443. IDC_CHOOSE_NAME_EDIT, 64,
  2444. IDC_CHOOSE_AREA_CODE_EDIT, 11,
  2445. IDC_CHOOSE_NUMBER_EDIT, 51,
  2446. 0
  2447. };
  2448. //
  2449. // Handle common messages shared by all wizard pages
  2450. //
  2451. if (! (pWizardUserMem = CommonWizardProc(hDlg,
  2452. message,
  2453. wParam,
  2454. lParam,
  2455. PSWIZB_BACK | PSWIZB_NEXT)))
  2456. {
  2457. return FALSE;
  2458. }
  2459. switch (message)
  2460. {
  2461. case WM_DESTROY:
  2462. if (hMenu)
  2463. {
  2464. DestroyMenu (hMenu);
  2465. hMenu = NULL;
  2466. }
  2467. break;
  2468. case WM_INITDIALOG:
  2469. //
  2470. // check if the user has run the wizard before so they can fill in the coverpage info.
  2471. //
  2472. if (!(hMenu = LoadMenu(g_hResource, MAKEINTRESOURCE(IDR_MENU) )))
  2473. {
  2474. Error(("LoadMenu failed. ec = 0x%X\n",GetLastError()));
  2475. Assert(FALSE);
  2476. }
  2477. else if (!(hReciptMenu = GetSubMenu(hMenu,0)))
  2478. {
  2479. Error(("GetSubMenu failed. ec = 0x%X\n",GetLastError()));
  2480. Assert(FALSE);
  2481. }
  2482. LimitTextFields(hDlg, textLimits);
  2483. //
  2484. // Initialize the recipient list view
  2485. //
  2486. if (!GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST))
  2487. {
  2488. Warning(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  2489. }
  2490. else
  2491. {
  2492. if (!InitRecipientListView(GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST)))
  2493. {
  2494. Warning(("InitRecipientListView failed\n"));
  2495. }
  2496. }
  2497. // Disable the IME for the area code edit control.
  2498. hEditControl = GetDlgItem( hDlg, IDC_CHOOSE_AREA_CODE_EDIT );
  2499. if ( hEditControl != NULL )
  2500. {
  2501. ImmAssociateContext( hEditControl, (HIMC)0 );
  2502. }
  2503. // Disable the IME for the fax phone number edit control.
  2504. hEditControl = GetDlgItem( hDlg, IDC_CHOOSE_NUMBER_EDIT );
  2505. if ( hEditControl != NULL )
  2506. {
  2507. ImmAssociateContext( hEditControl, (HIMC)0 );
  2508. }
  2509. if(IsWindowRTL(hDlg))
  2510. {
  2511. //
  2512. // Area code field always should be on the left side of the fax number field
  2513. // So, we switch them when the layout is RTL
  2514. //
  2515. int nShift;
  2516. RECT rcNum, rcCode;
  2517. HWND hNum, hCode;
  2518. DWORD dwRes;
  2519. //
  2520. // A numeric edit control should be LTR
  2521. //
  2522. SetLTREditDirection(hDlg, IDC_CHOOSE_NUMBER_EDIT);
  2523. SetLTREditDirection(hDlg, IDC_CHOOSE_AREA_CODE_EDIT);
  2524. //
  2525. // Calculate the area code shift value
  2526. //
  2527. hNum = GetDlgItem( hDlg, IDC_CHOOSE_NUMBER_EDIT );
  2528. dwRes = GetControlRect(hNum, &rcNum);
  2529. if(ERROR_SUCCESS != dwRes)
  2530. {
  2531. goto rtl_exit;
  2532. }
  2533. hCode = GetDlgItem( hDlg, IDC_CHOOSE_AREA_CODE_EDIT );
  2534. dwRes = GetControlRect(hCode, &rcCode);
  2535. if(ERROR_SUCCESS != dwRes)
  2536. {
  2537. goto rtl_exit;
  2538. }
  2539. nShift = rcNum.left - rcCode.left;
  2540. //
  2541. // Move the fax number on the place of the crea code
  2542. //
  2543. SetWindowPos(hNum, 0,
  2544. rcCode.right,
  2545. rcNum.top,
  2546. 0, 0,
  2547. SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
  2548. //
  2549. // Shift the area code
  2550. //
  2551. SetWindowPos(hCode, 0,
  2552. rcCode.right + nShift,
  2553. rcCode.top,
  2554. 0, 0,
  2555. SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
  2556. //
  2557. // Shift the area code left bracket
  2558. //
  2559. hCode = GetDlgItem( hDlg, IDC_BRACKET_LEFT );
  2560. dwRes = GetControlRect(hCode, &rcCode);
  2561. if(ERROR_SUCCESS != dwRes)
  2562. {
  2563. goto rtl_exit;
  2564. }
  2565. SetWindowPos(hCode, 0,
  2566. rcCode.right + nShift,
  2567. rcCode.top,
  2568. 0, 0,
  2569. SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
  2570. //
  2571. // Shift the area code right bracket
  2572. //
  2573. hCode = GetDlgItem( hDlg, IDC_BRACKET_RIGHT );
  2574. dwRes = GetControlRect(hCode, &rcCode);
  2575. if(ERROR_SUCCESS != dwRes)
  2576. {
  2577. goto rtl_exit;
  2578. }
  2579. SetWindowPos(hCode, 0,
  2580. rcCode.right + nShift,
  2581. rcCode.top,
  2582. 0, 0,
  2583. SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
  2584. } rtl_exit:
  2585. //
  2586. // Initialize the list of countries
  2587. // Init country combo box and try to identify the country
  2588. //
  2589. Assert(pWizardUserMem->pCountryList != NULL);
  2590. InitCountryListBox(pWizardUserMem->pCountryList,
  2591. GetDlgItem(hDlg, IDC_CHOOSE_COUNTRY_COMBO),
  2592. GetDlgItem(hDlg, IDC_CHOOSE_AREA_CODE_EDIT),
  2593. NULL,
  2594. countryId,
  2595. TRUE);
  2596. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2597. if (pWizardUserMem->isLocalPrinter)
  2598. {
  2599. //
  2600. // On local printers, we have dialing rules capabilities
  2601. // Init the combo-box of dialing rules
  2602. //
  2603. LocationListInit (hDlg, pWizardUserMem);
  2604. }
  2605. else
  2606. {
  2607. //
  2608. // When faxing remotely, we never use dialing rules (security issue with credit card info).
  2609. // Hide the dialing rules combo-box and button
  2610. //
  2611. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_DIALING_RULES), FALSE);
  2612. ShowWindow (GetDlgItem(hDlg, IDC_COMBO_DIALING_RULES), SW_HIDE);
  2613. EnableWindow(GetDlgItem(hDlg, IDC_DIALING_RULES), FALSE);
  2614. ShowWindow (GetDlgItem(hDlg, IDC_DIALING_RULES), SW_HIDE);
  2615. }
  2616. //
  2617. // Restore the 'Use dialing rules' checkbox state
  2618. //
  2619. if (pWizardUserMem->lpFaxSendWizardData->bUseDialingRules)
  2620. {
  2621. if (!CheckDlgButton(hDlg, IDC_USE_DIALING_RULE, BST_CHECKED))
  2622. {
  2623. Warning(("CheckDlgButton(IDC_USE_DIALING_RULE) failed. ec = 0x%X\n",GetLastError()));
  2624. }
  2625. }
  2626. else
  2627. {
  2628. //
  2629. // 'Use dialing rule' is off - this implies 'Dial as entered'
  2630. //
  2631. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_AREA_CODE_EDIT), FALSE);
  2632. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_COUNTRY_COMBO), FALSE);
  2633. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_DIALING_RULES), FALSE);
  2634. EnableWindow(GetDlgItem(hDlg, IDC_DIALING_RULES), FALSE);
  2635. }
  2636. break;
  2637. case WM_CONTEXTMENU:
  2638. {
  2639. //
  2640. // Also handle keyboard-originated context menu (<Shift>+F10 or VK_APP)
  2641. //
  2642. HWND hListWnd;
  2643. if (!(hListWnd = GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST)))
  2644. {
  2645. Error(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  2646. break;
  2647. }
  2648. if (hListWnd != GetFocus())
  2649. {
  2650. //
  2651. // Only show context sensitive menu if the focus is on the list control
  2652. //
  2653. break;
  2654. }
  2655. if (ListView_GetSelectedCount(hListWnd) != 1)
  2656. {
  2657. //
  2658. // No item is selected in the list control ==> no menu
  2659. //
  2660. break;
  2661. }
  2662. //
  2663. // Get the cursor position
  2664. //
  2665. dwMessagePos = GetMessagePos();
  2666. //
  2667. // Display the document context menu
  2668. //
  2669. if (!TrackPopupMenu(hReciptMenu,
  2670. TPM_LEFTALIGN | TPM_LEFTBUTTON,
  2671. GET_X_LPARAM (dwMessagePos),
  2672. GET_Y_LPARAM (dwMessagePos),
  2673. 0,
  2674. hDlg,
  2675. NULL))
  2676. {
  2677. Warning(("TrackPopupMenu failed. ec = 0x%X\n",GetLastError()));
  2678. }
  2679. break;
  2680. }
  2681. case WM_NOTIFY:
  2682. pNMHdr = (LPNMHDR ) lParam;
  2683. Assert(pNMHdr);
  2684. switch (pNMHdr->code)
  2685. {
  2686. case LVN_KEYDOWN:
  2687. if (pNMHdr->hwndFrom == GetDlgItem(hDlg, IDC_CHOOSE_RECIPIENT_LIST) &&
  2688. ((LV_KEYDOWN *) pNMHdr)->wVKey == VK_DELETE)
  2689. {
  2690. if (!RemoveRecipient(hDlg, pWizardUserMem))
  2691. {
  2692. Warning(("RemoveRecipient failed\n"));
  2693. }
  2694. }
  2695. break;
  2696. case LVN_ITEMCHANGED:
  2697. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2698. break;
  2699. case PSN_WIZNEXT:
  2700. pWizardUserMem->lpFaxSendWizardData->bUseDialingRules =
  2701. (IsDlgButtonChecked(hDlg, IDC_USE_DIALING_RULE) == BST_CHECKED);
  2702. if (! ValidateRecipients(hDlg, pWizardUserMem))
  2703. {
  2704. //
  2705. // Validate the list of recipients and prevent the user
  2706. // from advancing to the next page if there is a problem
  2707. //
  2708. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  2709. return TRUE;
  2710. }
  2711. break;
  2712. case PSN_SETACTIVE:
  2713. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2714. break;
  2715. }
  2716. return FALSE;
  2717. case WM_COMMAND:
  2718. cmd = GET_WM_COMMAND_CMD(wParam, lParam);
  2719. switch (GET_WM_COMMAND_ID(wParam, lParam))
  2720. {
  2721. case IDC_DIALING_RULES:
  2722. //
  2723. // Use pressed the 'Dialing rules...' button
  2724. //
  2725. DoTapiProps(hDlg);
  2726. LocationListInit(hDlg, pWizardUserMem);
  2727. break;
  2728. case IDC_COMBO_DIALING_RULES:
  2729. if (CBN_SELCHANGE == cmd)
  2730. {
  2731. LocationListSelChange(hDlg, pWizardUserMem);
  2732. }
  2733. break;
  2734. case IDC_USE_DIALING_RULE:
  2735. pWizardUserMem->lpFaxSendWizardData->bUseDialingRules =
  2736. (IsDlgButtonChecked(hDlg, IDC_USE_DIALING_RULE) == BST_CHECKED);
  2737. bEnable = pWizardUserMem->lpFaxSendWizardData->bUseDialingRules;
  2738. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_AREA_CODE_EDIT), bEnable);
  2739. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_COUNTRY_COMBO), bEnable);
  2740. EnableWindow(GetDlgItem(hDlg, IDC_COMBO_DIALING_RULES), bEnable);
  2741. EnableWindow(GetDlgItem(hDlg, IDC_DIALING_RULES), bEnable);
  2742. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2743. break;
  2744. case IDC_CHOOSE_COUNTRY_COMBO:
  2745. if (cmd == CBN_SELCHANGE)
  2746. {
  2747. //
  2748. // Update the area code edit box if necessary
  2749. //
  2750. if (!(GetDlgItem(hDlg, IDC_CHOOSE_COUNTRY_COMBO)) ||
  2751. !(GetDlgItem(hDlg, IDC_CHOOSE_AREA_CODE_EDIT)))
  2752. {
  2753. Warning(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  2754. }
  2755. else
  2756. {
  2757. SelChangeCountryListBox(GetDlgItem(hDlg, IDC_CHOOSE_COUNTRY_COMBO),
  2758. GetDlgItem(hDlg, IDC_CHOOSE_AREA_CODE_EDIT),
  2759. pWizardUserMem->pCountryList);
  2760. }
  2761. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2762. }
  2763. break;
  2764. case IDC_CHOOSE_NAME_EDIT:
  2765. if (cmd == EN_CHANGE)
  2766. {
  2767. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2768. }
  2769. break;
  2770. case IDC_CHOOSE_AREA_CODE_EDIT:
  2771. if (cmd == EN_CHANGE)
  2772. {
  2773. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2774. }
  2775. break;
  2776. case IDC_CHOOSE_NUMBER_EDIT:
  2777. if (cmd == EN_CHANGE)
  2778. {
  2779. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2780. }
  2781. break;
  2782. case IDC_CHOOSE_ADDRBOOK:
  2783. if (!DoAddressBook(hDlg, pWizardUserMem))
  2784. {
  2785. Error(("DoAddressBook failed\n"));
  2786. }
  2787. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2788. break;
  2789. case IDC_CHOOSE_ADD:
  2790. if ((cmd = AddRecipient(hDlg, pWizardUserMem)) != 0)
  2791. {
  2792. if (cmd > 0)
  2793. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, cmd);
  2794. else
  2795. MessageBeep(MB_OK);
  2796. }
  2797. else
  2798. {
  2799. SetFocus(GetDlgItem(hDlg, IDC_CHOOSE_NAME_EDIT));
  2800. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2801. }
  2802. break;
  2803. case IDC_CHOOSE_REMOVE:
  2804. RemoveRecipient(hDlg, pWizardUserMem);
  2805. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2806. if (IsWindowEnabled(GetDlgItem(hDlg, IDC_CHOOSE_REMOVE)))
  2807. {
  2808. SetFocus(GetDlgItem(hDlg, IDC_CHOOSE_REMOVE));
  2809. }
  2810. else
  2811. {
  2812. SetFocus(GetDlgItem(hDlg, IDC_CHOOSE_NAME_EDIT));
  2813. }
  2814. break;
  2815. case IDC_CHOOSE_EDIT:
  2816. EditRecipient(hDlg, pWizardUserMem);
  2817. SetFocus(GetDlgItem(hDlg, IDC_CHOOSE_EDIT));
  2818. break;
  2819. }
  2820. switch (LOWORD(wParam))
  2821. {
  2822. case IDM_RECIPT_DELETE:
  2823. RemoveRecipient(hDlg, pWizardUserMem);
  2824. CalcRecipientButtonsState(hDlg, pWizardUserMem);
  2825. break;
  2826. case IDM_RECIPT_EDIT:
  2827. EditRecipient(hDlg, pWizardUserMem);
  2828. break;
  2829. }
  2830. break;
  2831. }
  2832. return TRUE;
  2833. }
  2834. VOID
  2835. ValidateSelectedCoverPage(
  2836. PWIZARDUSERMEM pWizardUserMem
  2837. )
  2838. /*++
  2839. Routine Description:
  2840. If a cover page is selected, then do the following:
  2841. if the cover page file is a link resolve it
  2842. check if the cover page file contains note/subject fields
  2843. Arguments:
  2844. pWizardUserMem - Points to user mode memory structure
  2845. Return Value:
  2846. NONE
  2847. --*/
  2848. {
  2849. COVDOCINFO covDocInfo;
  2850. DWORD ec;
  2851. Verbose(("Cover page selected: %ws\n", pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName));
  2852. ec = RenderCoverPage(NULL,
  2853. NULL,
  2854. NULL,
  2855. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,
  2856. &covDocInfo,
  2857. FALSE);
  2858. if (ERROR_SUCCESS == ec)
  2859. {
  2860. pWizardUserMem->noteSubjectFlag = covDocInfo.Flags;
  2861. pWizardUserMem->cpPaperSize = covDocInfo.PaperSize;
  2862. pWizardUserMem->cpOrientation = covDocInfo.Orientation;
  2863. }
  2864. else
  2865. {
  2866. Error(("Cannot examine cover page file '%ws': %d\n",
  2867. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,
  2868. ec));
  2869. }
  2870. }
  2871. INT_PTR
  2872. CoverPageWizProc(
  2873. HWND hDlg,
  2874. UINT message,
  2875. WPARAM wParam,
  2876. LPARAM lParam
  2877. )
  2878. /*++
  2879. Routine Description:
  2880. Dialog procedure for the second wizard page:
  2881. selecting cover page and setting other fax options
  2882. Arguments:
  2883. hDlg - Identifies the wizard page
  2884. message - Specifies the message
  2885. wParam - Specifies additional message-specific information
  2886. lParam - Specifies additional message-specific information
  2887. Return Value:
  2888. Depends on the message parameter
  2889. --*/
  2890. {
  2891. #define PREVIEW_BITMAP_WIDTH (850)
  2892. #define PREVIEW_BITMAP_HEIGHT (1098)
  2893. static INT textLimits[] = {
  2894. IDC_CHOOSE_CP_SUBJECT, 256,
  2895. IDC_CHOOSE_CP_NOTE, 8192,
  2896. 0
  2897. };
  2898. PWIZARDUSERMEM pWizardUserMem;
  2899. WORD cmdId;
  2900. HWND hwnd;
  2901. RECT rc;
  2902. double dRatio;
  2903. LONG_PTR numOfCoverPages = 0;
  2904. HDC hDC = NULL;
  2905. TCHAR szCoverFileName[MAX_PATH];
  2906. //
  2907. // Handle common messages shared by all wizard pages
  2908. //
  2909. if (! (pWizardUserMem = CommonWizardProc(hDlg, message, wParam, lParam, PSWIZB_BACK|PSWIZB_NEXT)))
  2910. {
  2911. return FALSE;
  2912. }
  2913. //
  2914. // Handle anything specific to the current wizard page
  2915. //
  2916. switch (message)
  2917. {
  2918. case WM_INITDIALOG:
  2919. //
  2920. // Measure the mini-preview current (portrait) dimensions
  2921. //
  2922. g_bPreviewRTL = IsWindowRTL(hDlg);
  2923. SetLTRControlLayout(hDlg, IDC_STATIC_CP_PREVIEW);
  2924. if (ERROR_SUCCESS != GetControlRect(GetDlgItem(hDlg, IDC_STATIC_CP_PREVIEW), &rc))
  2925. {
  2926. g_dwMiniPreviewPortraitWidth = 1;
  2927. g_dwMiniPreviewPortraitHeight = 1;
  2928. }
  2929. else
  2930. {
  2931. g_dwMiniPreviewPortraitWidth = abs(rc.right - rc.left) + 1;
  2932. g_dwMiniPreviewPortraitHeight = rc.bottom - rc.top + 1;
  2933. }
  2934. //
  2935. // By default, the mini-preview is set to portrait
  2936. //
  2937. g_wCurrMiniPreviewOrientation = DMORIENT_PORTRAIT;
  2938. //
  2939. // Now, derive the landscape dimensions from the portrait ones
  2940. //
  2941. g_dwMiniPreviewLandscapeWidth = (DWORD)((double)1.2 * (double)g_dwMiniPreviewPortraitWidth);
  2942. dRatio = (double)(g_dwMiniPreviewPortraitWidth) / (double)(g_dwMiniPreviewPortraitHeight);
  2943. Assert (dRatio < 1.0);
  2944. g_dwMiniPreviewLandscapeHeight = (DWORD)((double)(g_dwMiniPreviewLandscapeWidth) * dRatio);
  2945. //
  2946. // Initialize the list of cover pages
  2947. //
  2948. if (WaitForSingleObject( pWizardUserMem->hCPEvent, INFINITE ) != WAIT_OBJECT_0)
  2949. {
  2950. Error(("WaitForSingleObject failed. ec = 0x%X\n",GetLastError()));
  2951. Assert(FALSE);
  2952. //
  2953. // We cannot wait for this flag to be set, so make it default TRUE
  2954. //
  2955. pWizardUserMem->ServerCPOnly = TRUE;
  2956. }
  2957. pWizardUserMem->pCPInfo = AllocCoverPageInfo(pWizardUserMem->lptstrServerName,
  2958. pWizardUserMem->lptstrPrinterName,
  2959. pWizardUserMem->ServerCPOnly);
  2960. if (pWizardUserMem->pCPInfo)
  2961. {
  2962. InitCoverPageList(pWizardUserMem->pCPInfo,
  2963. GetDlgItem(hDlg, IDC_CHOOSE_CP_LIST),
  2964. pWizardUserMem->lpInitialData->lpCoverPageInfo->lptstrCoverPageFileName);
  2965. }
  2966. //
  2967. // Indicate whether cover page should be sent
  2968. //
  2969. numOfCoverPages = SendDlgItemMessage(hDlg, IDC_CHOOSE_CP_LIST, CB_GETCOUNT, 0, 0);
  2970. if ( numOfCoverPages <= 0)
  2971. {
  2972. pWizardUserMem->bSendCoverPage = FALSE;
  2973. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_CHECK), FALSE);
  2974. }
  2975. //
  2976. // make sure the user selects a coverpage if this is the fax send utility
  2977. //
  2978. if (pWizardUserMem->dwFlags & FSW_FORCE_COVERPAGE)
  2979. {
  2980. pWizardUserMem->bSendCoverPage = TRUE;
  2981. // hide the checkbox
  2982. CheckDlgButton(hDlg, IDC_CHOOSE_CP_CHECK, BST_INDETERMINATE );
  2983. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_CHECK), FALSE);
  2984. // If there are no cover pages, we should not allow to proceed. So we flag it here
  2985. if ( numOfCoverPages <= 0)
  2986. {
  2987. pWizardUserMem->bSendCoverPage = FALSE;
  2988. }
  2989. else
  2990. {
  2991. // In case there are cover pages, then
  2992. pWizardUserMem->bSendCoverPage = TRUE;
  2993. }
  2994. }
  2995. CheckDlgButton(hDlg, IDC_CHOOSE_CP_CHECK, pWizardUserMem->bSendCoverPage );
  2996. if (!EnableCoverDlgItems(pWizardUserMem,hDlg))
  2997. {
  2998. Error(("Failed to enable/disable note and subject field by selected cover page on Init."));
  2999. }
  3000. LimitTextFields(hDlg, textLimits);
  3001. g_hwndPreview = GetDlgItem(hDlg,IDC_STATIC_CP_PREVIEW);
  3002. //
  3003. // Subclass the static control we use for preview. This allows us to handle its WM_PAINT messages
  3004. //
  3005. pWizardUserMem->wpOrigStaticControlProc = (WNDPROC) SetWindowLongPtr(g_hwndPreview,GWLP_WNDPROC, (LONG_PTR) PreviewSubclassProc);
  3006. //
  3007. // Allow the preview control to have access to the WizardUserMem structure
  3008. //
  3009. g_pWizardUserMem = pWizardUserMem;
  3010. //
  3011. // Simulate cover page selection
  3012. //
  3013. SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_CHOOSE_CP_LIST,LBN_SELCHANGE),0);
  3014. break;
  3015. case WM_COMMAND:
  3016. switch (cmdId = GET_WM_COMMAND_ID(wParam, lParam))
  3017. {
  3018. case IDC_CHOOSE_CP_CHECK:
  3019. if (!EnableCoverDlgItems(pWizardUserMem,hDlg))
  3020. {
  3021. Error(("Failed to enable/disable note and subject field on CP_CHECK."));
  3022. }
  3023. break;
  3024. case IDC_CHOOSE_CP_LIST:
  3025. if (HIWORD(wParam)==LBN_SELCHANGE)
  3026. {
  3027. //
  3028. // Disable the subject and note edit boxes if the cover page does not contain the fields
  3029. //
  3030. if (!EnableCoverDlgItems(pWizardUserMem,hDlg))
  3031. {
  3032. Error(("Failed to enable/disable note and subject field by selected cover page."));
  3033. }
  3034. //
  3035. // Get the full path to the cover page so we can get its information.
  3036. //
  3037. if (GetSelectedCoverPage(pWizardUserMem->pCPInfo,
  3038. GetDlgItem(hDlg, IDC_CHOOSE_CP_LIST),
  3039. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName, //full path
  3040. (pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName) ? MAX_PATH : 0,
  3041. szCoverFileName, //file name
  3042. ARR_SIZE(szCoverFileName),
  3043. &pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->bServerBased) == CB_ERR)
  3044. {
  3045. Warning(("GetSelectedCoverPage failed or no *.COV files"));
  3046. }
  3047. InvalidateRect(g_hwndPreview, NULL, TRUE);
  3048. }
  3049. break;
  3050. case IDC_CHOOSE_CP_USER_INFO:
  3051. if (! (hwnd = GetDlgItem(hDlg, IDC_CHOOSE_CP_USER_INFO)))
  3052. {
  3053. Error(("GetDlgItem failed. ec = 0x%X\n",GetLastError()));
  3054. break;
  3055. }
  3056. DialogBoxParam(
  3057. (HINSTANCE) g_hResource,
  3058. MAKEINTRESOURCE( IDD_WIZARD_USERINFO ),
  3059. hwnd,
  3060. FaxUserInfoProc,
  3061. (LPARAM) pWizardUserMem
  3062. );
  3063. break;
  3064. };
  3065. break;
  3066. case WM_NOTIFY:
  3067. if ((pWizardUserMem->dwFlags & FSW_FORCE_COVERPAGE) && (!pWizardUserMem->bSendCoverPage))
  3068. {
  3069. // Here is a good place to add pop-up or something for the user.
  3070. PropSheet_SetWizButtons(GetParent(hDlg),PSWIZB_BACK);
  3071. }
  3072. switch (((NMHDR *) lParam)->code)
  3073. {
  3074. case PSN_WIZNEXT:
  3075. //
  3076. // Remember the cover page settings selected
  3077. //
  3078. pWizardUserMem->noteSubjectFlag = 0;
  3079. pWizardUserMem->cpPaperSize = 0;
  3080. pWizardUserMem->cpOrientation = 0;
  3081. pWizardUserMem->bSendCoverPage = IsDlgButtonChecked(hDlg, IDC_CHOOSE_CP_CHECK);
  3082. //
  3083. // Get the full path to the cover page so we can get its information.
  3084. //
  3085. if (GetSelectedCoverPage(pWizardUserMem->pCPInfo,
  3086. GetDlgItem(hDlg, IDC_CHOOSE_CP_LIST),
  3087. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName, //full path
  3088. (pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName) ? MAX_PATH : 0,
  3089. szCoverFileName, //file name
  3090. ARR_SIZE(szCoverFileName),
  3091. &pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->bServerBased) == CB_ERR)
  3092. {
  3093. Warning(("GetSelectedCoverPage failed or no *.COV files"));
  3094. }
  3095. if (pWizardUserMem->bSendCoverPage )
  3096. {
  3097. // if the cover page file is a link resolve it
  3098. // check if the cover page file contains note/subject fields
  3099. //
  3100. ValidateSelectedCoverPage(pWizardUserMem);
  3101. }
  3102. else
  3103. {
  3104. //
  3105. // pWizardUserMem->coverPage must be set to "" when no cover page is to be sent
  3106. //
  3107. _tcscpy(pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,TEXT(""));
  3108. }
  3109. //
  3110. // Collect the current values of other dialog controls
  3111. //
  3112. if (pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrSubject)
  3113. MemFree(pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrSubject);
  3114. if (pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrNote)
  3115. MemFree(pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrNote);
  3116. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrSubject = GetTextStringValue(GetDlgItem(hDlg, IDC_CHOOSE_CP_SUBJECT));
  3117. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrNote = GetTextStringValue(GetDlgItem(hDlg, IDC_CHOOSE_CP_NOTE));
  3118. //
  3119. // If the current application is "Send Note" utility,
  3120. // then the subject or note field must not be empty.
  3121. //
  3122. if((pWizardUserMem->dwFlags & FSW_FORCE_COVERPAGE) &&
  3123. ((pWizardUserMem->noteSubjectFlag & COVFP_NOTE) ||
  3124. (pWizardUserMem->noteSubjectFlag & COVFP_SUBJECT)))
  3125. {
  3126. if(!pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrNote &&
  3127. !pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrSubject)
  3128. {
  3129. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, IDS_NOTE_SUBJECT_EMPTY);
  3130. if(pWizardUserMem->noteSubjectFlag & COVFP_SUBJECT)
  3131. {
  3132. SetFocus(GetDlgItem(hDlg, IDC_CHOOSE_CP_SUBJECT));
  3133. }
  3134. else
  3135. {
  3136. SetFocus(GetDlgItem(hDlg, IDC_CHOOSE_CP_NOTE));
  3137. }
  3138. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  3139. return TRUE;
  3140. }
  3141. }
  3142. break;
  3143. }
  3144. break;
  3145. }
  3146. return TRUE;
  3147. }
  3148. BOOL
  3149. ValidateReceiptInfo(
  3150. HWND hDlg
  3151. )
  3152. {
  3153. TCHAR tcBuffer[MAX_STRING_LEN];
  3154. if (IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_NONE_RECEIPT))
  3155. goto ok;
  3156. if (!IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_MSGBOX) &&
  3157. !IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_EMAIL))
  3158. {
  3159. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, IDS_BAD_RECEIPT_FORM );
  3160. return FALSE;
  3161. }
  3162. if (IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_EMAIL) &&
  3163. (GetDlgItemText(hDlg, IDC_WIZ_FAXOPTS_EMAIL_EDIT, tcBuffer, MAX_STRING_LEN) == 0))
  3164. {
  3165. if(GetLastError() != ERROR_SUCCESS)
  3166. {
  3167. Error(("GetDlgItemText failed. ec = 0x%X\n",GetLastError()));
  3168. }
  3169. DisplayMessageDialog(hDlg, 0, IDS_WIZARD_TITLE, IDS_BAD_RECEIPT_EMAIL_ADD );
  3170. SetFocus(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_EMAIL_EDIT));
  3171. return FALSE;
  3172. }
  3173. ok:
  3174. return TRUE;
  3175. }
  3176. INT_PTR
  3177. FaxOptsWizProc(
  3178. HWND hDlg,
  3179. UINT message,
  3180. WPARAM wParam,
  3181. LPARAM lParam
  3182. )
  3183. /*++
  3184. Routine Description:
  3185. Dialog procedure for the wizard page: entering subject and note information
  3186. Arguments:
  3187. hDlg - Identifies the wizard page
  3188. message - Specifies the message
  3189. wParam - Specifies additional message-specific information
  3190. lParam - Specifies additional message-specific information
  3191. Return Value:
  3192. Depends on the message parameter
  3193. --*/
  3194. {
  3195. PWIZARDUSERMEM pWizardUserMem;
  3196. WORD cmdId;
  3197. BOOL bEnabled;
  3198. SYSTEMTIME st;
  3199. HANDLE hFax = NULL;
  3200. static HWND hTimeControl;
  3201. if (! (pWizardUserMem = CommonWizardProc(hDlg, message, wParam, lParam, PSWIZB_BACK|PSWIZB_NEXT)))
  3202. return FALSE;
  3203. switch (message)
  3204. {
  3205. case WM_INITDIALOG:
  3206. hTimeControl = GetDlgItem(hDlg,IDC_WIZ_FAXOPTS_SENDTIME);
  3207. Assert(hTimeControl);
  3208. //
  3209. // restore time to send controls
  3210. //
  3211. cmdId = (pWizardUserMem->lpInitialData->dwScheduleAction == JSA_DISCOUNT_PERIOD) ? IDC_WIZ_FAXOPTS_DISCOUNT :
  3212. (pWizardUserMem->lpInitialData->dwScheduleAction == JSA_SPECIFIC_TIME ) ? IDC_WIZ_FAXOPTS_SPECIFIC :
  3213. IDC_WIZ_FAXOPTS_ASAP;
  3214. if (!CheckDlgButton(hDlg, cmdId, TRUE))
  3215. {
  3216. Warning(("CheckDlgButton failed. ec = 0x%X\n",GetLastError()));
  3217. }
  3218. GetLocalTime(&st);
  3219. EnableWindow(hTimeControl, (cmdId == IDC_WIZ_FAXOPTS_SPECIFIC) );
  3220. if (pWizardUserMem->dwFlags & FSW_USE_SCHEDULE_ACTION) {
  3221. st.wHour = pWizardUserMem->lpInitialData->tmSchedule.wHour;
  3222. st.wMinute = pWizardUserMem->lpInitialData->tmSchedule.wMinute;
  3223. }
  3224. else
  3225. {
  3226. // use local time
  3227. }
  3228. if (!DateTime_SetSystemtime( hTimeControl, GDT_VALID, &st ))
  3229. {
  3230. Warning(("DateTime_SetFormat failed\n"));
  3231. }
  3232. //
  3233. // Init priority
  3234. //
  3235. //
  3236. // Low
  3237. //
  3238. bEnabled = ((pWizardUserMem->dwRights & FAX_ACCESS_SUBMIT) == FAX_ACCESS_SUBMIT);
  3239. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_FAXOPTS_PRIORITY_LOW), bEnabled);
  3240. //
  3241. // Normal
  3242. //
  3243. bEnabled = ((pWizardUserMem->dwRights & FAX_ACCESS_SUBMIT_NORMAL) == FAX_ACCESS_SUBMIT_NORMAL);
  3244. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_FAXOPTS_PRIORITY_NORMAL), bEnabled);
  3245. if (bEnabled)
  3246. {
  3247. //
  3248. // Normal is our default priority
  3249. //
  3250. CheckDlgButton (hDlg, IDC_WIZ_FAXOPTS_PRIORITY_NORMAL, BST_CHECKED);
  3251. }
  3252. else
  3253. {
  3254. Assert ((pWizardUserMem->dwRights & FAX_ACCESS_SUBMIT) == FAX_ACCESS_SUBMIT);
  3255. //
  3256. // Low is enabled - use it as default
  3257. //
  3258. CheckDlgButton (hDlg, IDC_WIZ_FAXOPTS_PRIORITY_LOW, BST_CHECKED);
  3259. }
  3260. //
  3261. // High
  3262. //
  3263. bEnabled = ((pWizardUserMem->dwRights & FAX_ACCESS_SUBMIT_HIGH) == FAX_ACCESS_SUBMIT_HIGH);
  3264. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_FAXOPTS_PRIORITY_HIGH), bEnabled);
  3265. return TRUE;
  3266. case WM_NOTIFY:
  3267. if (((NMHDR *) lParam)->code == PSN_WIZNEXT)
  3268. {
  3269. //
  3270. //
  3271. // retrieve the sending time
  3272. //
  3273. pWizardUserMem->lpFaxSendWizardData->dwScheduleAction =
  3274. IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_DISCOUNT) ? JSA_DISCOUNT_PERIOD :
  3275. IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_SPECIFIC) ? JSA_SPECIFIC_TIME :
  3276. JSA_NOW;
  3277. if (pWizardUserMem->lpFaxSendWizardData->dwScheduleAction == JSA_SPECIFIC_TIME) {
  3278. #ifdef DEBUG
  3279. DWORD rVal;
  3280. TCHAR TimeBuffer[128];
  3281. #endif
  3282. //
  3283. // get specific time
  3284. //
  3285. if (DateTime_GetSystemtime(hTimeControl,
  3286. &pWizardUserMem->lpFaxSendWizardData->tmSchedule) == GDT_ERROR )
  3287. {
  3288. Error(("DateTime_GetSystemtime failed\n"));
  3289. return FALSE;
  3290. }
  3291. #ifdef DEBUG
  3292. if (!(rVal = GetY2KCompliantDate(
  3293. LOCALE_USER_DEFAULT,
  3294. 0,
  3295. &pWizardUserMem->lpFaxSendWizardData->tmSchedule,
  3296. TimeBuffer,
  3297. ARR_SIZE(TimeBuffer)
  3298. )))
  3299. {
  3300. Error(("GetY2KCompliantDate: failed. ec = 0X%x\n",GetLastError()));
  3301. return FALSE;
  3302. }
  3303. TimeBuffer[rVal - 1] = TEXT(' ');
  3304. if(!FaxTimeFormat(
  3305. LOCALE_USER_DEFAULT,
  3306. 0,
  3307. &pWizardUserMem->lpFaxSendWizardData->tmSchedule,
  3308. NULL,
  3309. &TimeBuffer[rVal],
  3310. ARR_SIZE(TimeBuffer) - rVal
  3311. ))
  3312. {
  3313. Error(("FaxTimeFormat: failed. ec = 0X%x\n",GetLastError()));
  3314. return FALSE;
  3315. }
  3316. Verbose(("faxui - Fax Send time %ws", TimeBuffer));
  3317. #endif
  3318. }
  3319. //
  3320. // save priority
  3321. //
  3322. pWizardUserMem->lpFaxSendWizardData->Priority =
  3323. IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_PRIORITY_HIGH) ? FAX_PRIORITY_TYPE_HIGH :
  3324. IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_PRIORITY_NORMAL) ? FAX_PRIORITY_TYPE_NORMAL :
  3325. FAX_PRIORITY_TYPE_LOW;
  3326. if(0 == pWizardUserMem->dwSupportedReceipts)
  3327. {
  3328. //
  3329. // skip notifications page
  3330. //
  3331. SetWindowLongPtr(hDlg,
  3332. DWLP_MSGRESULT,
  3333. (pWizardUserMem->dwComCtrlVer >= IE50_COMCTRL_VER) ? IDD_WIZARD_CONGRATS :
  3334. IDD_WIZARD_CONGRATS_NOWIZARD97);
  3335. return TRUE;
  3336. }
  3337. }
  3338. break;
  3339. case WM_COMMAND:
  3340. switch (cmdId = GET_WM_COMMAND_ID(wParam, lParam)) {
  3341. case IDC_WIZ_FAXOPTS_SPECIFIC:
  3342. case IDC_WIZ_FAXOPTS_DISCOUNT:
  3343. case IDC_WIZ_FAXOPTS_ASAP:
  3344. EnableWindow(hTimeControl, (cmdId == IDC_WIZ_FAXOPTS_SPECIFIC) );
  3345. break;
  3346. };
  3347. break;
  3348. default:
  3349. return FALSE;
  3350. } ;
  3351. return TRUE;
  3352. }
  3353. void
  3354. CalcReceiptButtonsState(
  3355. HWND hDlg,
  3356. PWIZARDUSERMEM pWizardUserMem
  3357. )
  3358. /*++
  3359. Routine Description:
  3360. Calculates receipt page button state
  3361. Arguments:
  3362. hDlg - Identifies the wizard page
  3363. pWizardUserMem - pointer to WIZARDUSERMEM structure
  3364. Return Value:
  3365. none
  3366. --*/
  3367. {
  3368. BOOL bMailReceipt;
  3369. Assert(hDlg);
  3370. Assert(pWizardUserMem);
  3371. if((IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_NONE_RECEIPT) != BST_CHECKED) &&
  3372. (SizeOfRecipientList(pWizardUserMem) > 1))
  3373. {
  3374. //
  3375. // wish receipt, multiple recipients
  3376. //
  3377. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_GRP_PARENT), TRUE);
  3378. }
  3379. else
  3380. {
  3381. CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_GRP_PARENT, BST_UNCHECKED);
  3382. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_GRP_PARENT), FALSE);
  3383. }
  3384. bMailReceipt = IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_EMAIL) == BST_CHECKED;
  3385. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_ADDRBOOK), bMailReceipt);
  3386. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_EMAIL_EDIT), bMailReceipt);
  3387. if (bMailReceipt)
  3388. {
  3389. //
  3390. // Receipt by e-mail
  3391. //
  3392. if (! ((SizeOfRecipientList(pWizardUserMem) > 1) &&
  3393. (pWizardUserMem->dwFlags & FSW_FORCE_COVERPAGE) &&
  3394. IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_GRP_PARENT)
  3395. )
  3396. )
  3397. {
  3398. //
  3399. // NOT the case of (multiple recipients AND no attachment AND single receipt)
  3400. //
  3401. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_ATTACH_FAX), TRUE);
  3402. ShowWindow (GetDlgItem (hDlg, IDC_STATIC_ATTACH_NOTE), SW_HIDE);
  3403. ShowWindow (GetDlgItem (hDlg, IDC_WZRD_NOTE_ICON), SW_HIDE);
  3404. }
  3405. else
  3406. {
  3407. //
  3408. // The case of (multiple recipients AND no attachment AND single receipt)
  3409. //
  3410. CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_ATTACH_FAX, BST_UNCHECKED);
  3411. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_ATTACH_FAX), FALSE);
  3412. ShowWindow (GetDlgItem (hDlg, IDC_STATIC_ATTACH_NOTE), SW_SHOW);
  3413. ShowWindow (GetDlgItem (hDlg, IDC_WZRD_NOTE_ICON), SW_SHOW);
  3414. }
  3415. }
  3416. else
  3417. {
  3418. //
  3419. // No receipt by e-mail
  3420. //
  3421. ShowWindow (GetDlgItem (hDlg, IDC_STATIC_ATTACH_NOTE), SW_HIDE);
  3422. ShowWindow (GetDlgItem (hDlg, IDC_WZRD_NOTE_ICON), SW_HIDE);
  3423. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_ATTACH_FAX), FALSE);
  3424. }
  3425. }
  3426. INT_PTR
  3427. FaxReceiptWizProc(
  3428. HWND hDlg,
  3429. UINT message,
  3430. WPARAM wParam,
  3431. LPARAM lParam
  3432. )
  3433. /*++
  3434. Routine Description:
  3435. Dialog procedure for the wizard page: receipt information
  3436. Arguments:
  3437. hDlg - Identifies the wizard page
  3438. message - Specifies the message
  3439. wParam - Specifies additional message-specific information
  3440. lParam - Specifies additional message-specific information
  3441. Return Value:
  3442. Depends on the message parameter
  3443. --*/
  3444. {
  3445. PWIZARDUSERMEM pWizardUserMem;
  3446. WORD cmdId;
  3447. LPTSTR lptstrEmailAddress;
  3448. DWORD dwReceiptDeliveryType;
  3449. if (! (pWizardUserMem = CommonWizardProc(hDlg, message, wParam, lParam, PSWIZB_BACK|PSWIZB_NEXT)))
  3450. {
  3451. return FALSE;
  3452. }
  3453. switch (message)
  3454. {
  3455. case WM_INITDIALOG:
  3456. dwReceiptDeliveryType = pWizardUserMem->lpInitialData->dwReceiptDeliveryType;
  3457. //
  3458. // data is initializated without validation of correctness
  3459. // it is up to caller to check that the receipt data is correct and consistent
  3460. //
  3461. //
  3462. // no receipt
  3463. //
  3464. if (!CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_NONE_RECEIPT,
  3465. (dwReceiptDeliveryType == DRT_NONE) ? BST_CHECKED : BST_UNCHECKED))
  3466. {
  3467. Warning(("CheckDlgButton failed. ec = 0x%X\n",GetLastError()));
  3468. }
  3469. //
  3470. // single receipt
  3471. //
  3472. if((dwReceiptDeliveryType != DRT_NONE) && (SizeOfRecipientList(pWizardUserMem) > 1))
  3473. {
  3474. if (!CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_GRP_PARENT,
  3475. (dwReceiptDeliveryType & DRT_GRP_PARENT) ? BST_CHECKED : BST_UNCHECKED))
  3476. {
  3477. Warning(("CheckDlgButton failed. ec = 0x%X\n",GetLastError()));
  3478. }
  3479. }
  3480. else
  3481. {
  3482. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_GRP_PARENT), FALSE);
  3483. }
  3484. //
  3485. // message box receipt
  3486. //
  3487. if(pWizardUserMem->dwSupportedReceipts & DRT_MSGBOX)
  3488. {
  3489. if (!CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_MSGBOX,
  3490. (dwReceiptDeliveryType & DRT_MSGBOX) ? BST_CHECKED : BST_UNCHECKED))
  3491. {
  3492. Warning(("CheckDlgButton failed. ec = 0x%X\n",GetLastError()));
  3493. }
  3494. }
  3495. else
  3496. {
  3497. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_MSGBOX), FALSE);
  3498. if(dwReceiptDeliveryType & DRT_MSGBOX)
  3499. {
  3500. //
  3501. // If the previous choice was inbox
  3502. // but by now this option is disabled
  3503. // check no receipt option
  3504. //
  3505. CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_NONE_RECEIPT, BST_CHECKED);
  3506. }
  3507. }
  3508. //
  3509. // email receipt
  3510. //
  3511. if(pWizardUserMem->dwSupportedReceipts & DRT_EMAIL)
  3512. {
  3513. if (!CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_EMAIL,
  3514. (dwReceiptDeliveryType & DRT_EMAIL) ? BST_CHECKED : BST_UNCHECKED))
  3515. {
  3516. Warning(("CheckDlgButton failed. ec = 0x%X\n",GetLastError()));
  3517. }
  3518. }
  3519. else
  3520. {
  3521. EnableWindow(GetDlgItem(hDlg, IDC_WIZ_FAXOPTS_EMAIL), FALSE);
  3522. if(dwReceiptDeliveryType & DRT_EMAIL)
  3523. {
  3524. //
  3525. // If the previous choice was email
  3526. // but by now this option is disabled
  3527. // check no receipt option
  3528. //
  3529. CheckDlgButton(hDlg,IDC_WIZ_FAXOPTS_NONE_RECEIPT, BST_CHECKED);
  3530. }
  3531. }
  3532. if (pWizardUserMem->lpInitialData->szReceiptDeliveryAddress && (dwReceiptDeliveryType & DRT_EMAIL))
  3533. {
  3534. if (!SetDlgItemText(hDlg, IDC_WIZ_FAXOPTS_EMAIL_EDIT,
  3535. pWizardUserMem->lpInitialData->szReceiptDeliveryAddress))
  3536. {
  3537. Warning(("SetDlgItemText failed. ec = 0x%X\n",GetLastError()));
  3538. }
  3539. }
  3540. if (dwReceiptDeliveryType & DRT_ATTACH_FAX)
  3541. {
  3542. //
  3543. // Initial data has 'Attach fax' option set - check the checkbox
  3544. //
  3545. if (!CheckDlgButton(hDlg, IDC_WIZ_FAXOPTS_ATTACH_FAX, BST_CHECKED))
  3546. {
  3547. Warning(("CheckDlgButton failed. ec = 0x%X\n",GetLastError()));
  3548. }
  3549. }
  3550. CalcReceiptButtonsState(hDlg, pWizardUserMem);
  3551. return TRUE;
  3552. case WM_NOTIFY:
  3553. if (((NMHDR *) lParam)->code == PSN_WIZNEXT)
  3554. {
  3555. if (! ValidateReceiptInfo(hDlg))
  3556. {
  3557. //
  3558. // Validate the list of recipients and prevent the user
  3559. // from advancing to the next page if there is a problem
  3560. //
  3561. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  3562. return TRUE;
  3563. }
  3564. pWizardUserMem->lpFaxSendWizardData->dwReceiptDeliveryType = DRT_NONE;
  3565. if (!IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_NONE_RECEIPT))
  3566. {
  3567. TCHAR tcBuffer[MAX_STRING_LEN];
  3568. if (IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_GRP_PARENT))
  3569. {
  3570. pWizardUserMem->lpFaxSendWizardData->dwReceiptDeliveryType |= DRT_GRP_PARENT;
  3571. }
  3572. if (IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_MSGBOX))
  3573. {
  3574. DWORD dwBufSize = ARR_SIZE (tcBuffer);
  3575. pWizardUserMem->lpFaxSendWizardData->dwReceiptDeliveryType |= DRT_MSGBOX;
  3576. if (!GetComputerName (tcBuffer, &dwBufSize))
  3577. {
  3578. Error(("GetComputerName failed (ec=%ld)\n", GetLastError()));
  3579. return FALSE;
  3580. }
  3581. if (!(pWizardUserMem->lpFaxSendWizardData->szReceiptDeliveryAddress = StringDup(tcBuffer)))
  3582. {
  3583. Error(("Allocation of szReceiptDeliveryProfile failed!!!!\n"));
  3584. return FALSE;
  3585. }
  3586. }
  3587. else if (IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_EMAIL))
  3588. {
  3589. pWizardUserMem->lpFaxSendWizardData->dwReceiptDeliveryType |= DRT_EMAIL;
  3590. GetDlgItemText(hDlg, IDC_WIZ_FAXOPTS_EMAIL_EDIT, tcBuffer, MAX_STRING_LEN);
  3591. if (!(pWizardUserMem->lpFaxSendWizardData->szReceiptDeliveryAddress = StringDup(tcBuffer)))
  3592. {
  3593. Error(("Allocation of szReceiptDeliveryProfile failed!!!!\n"));
  3594. return FALSE;
  3595. }
  3596. if (IsDlgButtonChecked(hDlg,IDC_WIZ_FAXOPTS_ATTACH_FAX))
  3597. {
  3598. pWizardUserMem->lpFaxSendWizardData->dwReceiptDeliveryType |= DRT_ATTACH_FAX;
  3599. }
  3600. }
  3601. }
  3602. }
  3603. if (((NMHDR *) lParam)->code == PSN_SETACTIVE)
  3604. {
  3605. CalcReceiptButtonsState(hDlg, pWizardUserMem);
  3606. }
  3607. break;
  3608. case WM_COMMAND:
  3609. switch (cmdId = GET_WM_COMMAND_ID(wParam, lParam))
  3610. {
  3611. case IDC_WIZ_FAXOPTS_NONE_RECEIPT:
  3612. case IDC_WIZ_FAXOPTS_EMAIL:
  3613. case IDC_WIZ_FAXOPTS_MSGBOX:
  3614. case IDC_WIZ_FAXOPTS_GRP_PARENT:
  3615. CalcReceiptButtonsState(hDlg, pWizardUserMem);
  3616. break;
  3617. case IDC_WIZ_FAXOPTS_ADDRBOOK:
  3618. if (lptstrEmailAddress = GetEMailAddress(hDlg,pWizardUserMem))
  3619. {
  3620. SetDlgItemText(hDlg, IDC_WIZ_FAXOPTS_EMAIL_EDIT, lptstrEmailAddress);
  3621. MemFree(lptstrEmailAddress);
  3622. }
  3623. break;
  3624. };
  3625. break;
  3626. default:
  3627. return FALSE;
  3628. } ;
  3629. return TRUE;
  3630. }
  3631. #define FillEditCtrlWithInitialUserInfo(nIDDlgItem,field) \
  3632. if (pWizardUserMem->lpInitialData->lpSenderInfo->field && \
  3633. !IsEmptyString(pWizardUserMem->lpInitialData->lpSenderInfo->field)) { \
  3634. SetDlgItemText(hDlg, nIDDlgItem, pWizardUserMem->lpInitialData->lpSenderInfo->field); \
  3635. }
  3636. #define FillEditCtrlWithSenderWizardUserInfo(nIDDlgItem,field) \
  3637. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->field && \
  3638. !IsEmptyString(pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->field)) { \
  3639. SetDlgItemText(hDlg, nIDDlgItem, pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->field); \
  3640. }
  3641. #define FillUserInfoFromEditCrtl(nIDDlgItem,field) \
  3642. tcBuffer[0] = 0; \
  3643. GetDlgItemText(hDlg, nIDDlgItem, tcBuffer, MAX_STRING_LEN); \
  3644. pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->field = StringDup(tcBuffer); \
  3645. if (!pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->field) \
  3646. { \
  3647. Error(("Memory allocation failed")); \
  3648. }
  3649. INT_PTR
  3650. CALLBACK
  3651. FaxUserInfoProc(
  3652. HWND hDlg,
  3653. UINT message,
  3654. WPARAM wParam,
  3655. LPARAM lParam
  3656. )
  3657. /*++
  3658. Routine Description:
  3659. Dialog procedure for the info page: sender information
  3660. Arguments:
  3661. hDlg - Identifies the wizard page
  3662. message - Specifies the message
  3663. wParam - Specifies additional message-specific information
  3664. lParam - Specifies additional message-specific information
  3665. Return Value:
  3666. Depends on the message parameter
  3667. --*/
  3668. {
  3669. //
  3670. // Maximum length for various text fields
  3671. //
  3672. PWIZARDUSERMEM pWizardUserMem;
  3673. FAX_PERSONAL_PROFILE* pSenderInfo;
  3674. TCHAR tcBuffer[MAX_STRING_LEN];
  3675. static INT textLimits[] = {
  3676. IDC_WIZ_USERINFO_FULLNAME, MAX_USERINFO_FULLNAME,
  3677. IDC_WIZ_USERINFO_FAX_NUMBER, MAX_USERINFO_FAX_NUMBER,
  3678. IDC_WIZ_USERINFO_COMPANY, MAX_USERINFO_COMPANY,
  3679. IDC_WIZ_USERINFO_ADDRESS, MAX_USERINFO_ADDRESS,
  3680. IDC_WIZ_USERINFO_TITLE, MAX_USERINFO_TITLE,
  3681. IDC_WIZ_USERINFO_DEPT, MAX_USERINFO_DEPT,
  3682. IDC_WIZ_USERINFO_OFFICE, MAX_USERINFO_OFFICE,
  3683. IDC_WIZ_USERINFO_HOME_PHONE, MAX_USERINFO_HOME_PHONE,
  3684. IDC_WIZ_USERINFO_WORK_PHONE, MAX_USERINFO_WORK_PHONE,
  3685. IDC_WIZ_USERINFO_BILLING_CODE, MAX_USERINFO_BILLING_CODE,
  3686. IDC_WIZ_USERINFO_MAILBOX, MAX_USERINFO_MAILBOX,
  3687. 0
  3688. };
  3689. switch (message) {
  3690. case WM_INITDIALOG:
  3691. pWizardUserMem = (PWIZARDUSERMEM) lParam;
  3692. Assert(pWizardUserMem);
  3693. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  3694. LimitTextFields(hDlg, textLimits);
  3695. Assert(pWizardUserMem->lpInitialData);
  3696. Assert(pWizardUserMem->lpInitialData->lpSenderInfo);
  3697. Assert(pWizardUserMem->lpFaxSendWizardData->lpSenderInfo);
  3698. // init Sender Name
  3699. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrName)
  3700. {
  3701. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_FULLNAME, lptstrName);
  3702. }
  3703. else
  3704. {
  3705. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_FULLNAME, lptstrName);
  3706. }
  3707. //
  3708. // init Sender Fax Number
  3709. //
  3710. SetLTREditDirection(hDlg, IDC_WIZ_USERINFO_FAX_NUMBER);
  3711. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrFaxNumber)
  3712. {
  3713. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_FAX_NUMBER, lptstrFaxNumber);
  3714. }
  3715. else
  3716. {
  3717. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_FAX_NUMBER,lptstrFaxNumber);
  3718. }
  3719. // init Sender Company
  3720. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrCompany)
  3721. {
  3722. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_COMPANY, lptstrCompany);
  3723. }
  3724. else
  3725. {
  3726. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_COMPANY,lptstrCompany);
  3727. }
  3728. // init Sender Address
  3729. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrStreetAddress)
  3730. {
  3731. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_ADDRESS, lptstrStreetAddress);
  3732. }
  3733. else
  3734. {
  3735. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_ADDRESS,lptstrStreetAddress);
  3736. }
  3737. // init Sender Title
  3738. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrTitle)
  3739. {
  3740. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_TITLE,lptstrTitle);
  3741. }
  3742. else
  3743. {
  3744. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_TITLE, lptstrTitle);
  3745. }
  3746. // init Sender Department
  3747. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrDepartment)
  3748. {
  3749. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_DEPT,lptstrDepartment);
  3750. }
  3751. else
  3752. {
  3753. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_DEPT,lptstrDepartment);
  3754. }
  3755. // init Sender Office Location
  3756. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrOfficeLocation)
  3757. {
  3758. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_OFFICE,lptstrOfficeLocation);
  3759. }
  3760. else
  3761. {
  3762. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_OFFICE,lptstrOfficeLocation);
  3763. }
  3764. // init Sender Home Phone
  3765. SetLTREditDirection(hDlg, IDC_WIZ_USERINFO_HOME_PHONE);
  3766. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrHomePhone)
  3767. {
  3768. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_HOME_PHONE,lptstrHomePhone);
  3769. }
  3770. else
  3771. {
  3772. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_HOME_PHONE,lptstrHomePhone);
  3773. }
  3774. // init Sender Office Phone
  3775. SetLTREditDirection(hDlg, IDC_WIZ_USERINFO_WORK_PHONE);
  3776. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrOfficePhone)
  3777. {
  3778. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_WORK_PHONE,lptstrOfficePhone);
  3779. }
  3780. else
  3781. {
  3782. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_WORK_PHONE,lptstrOfficePhone);
  3783. }
  3784. // init Sender Billing Code
  3785. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrBillingCode)
  3786. {
  3787. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_BILLING_CODE,lptstrBillingCode);
  3788. }
  3789. else
  3790. {
  3791. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_BILLING_CODE,lptstrBillingCode);
  3792. }
  3793. // init Sender Internet Mail
  3794. SetLTREditDirection(hDlg, IDC_WIZ_USERINFO_MAILBOX);
  3795. if (pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrEmail)
  3796. {
  3797. FillEditCtrlWithSenderWizardUserInfo(IDC_WIZ_USERINFO_MAILBOX,lptstrEmail);
  3798. }
  3799. else
  3800. {
  3801. FillEditCtrlWithInitialUserInfo(IDC_WIZ_USERINFO_MAILBOX,lptstrEmail);
  3802. }
  3803. if (!CheckDlgButton(hDlg, IDC_USER_INFO_JUST_THIS_TIME, !pWizardUserMem->lpFaxSendWizardData->bSaveSenderInfo))
  3804. {
  3805. Warning(("CheckDlgButton failed. ec = 0x%X\n",GetLastError()));
  3806. }
  3807. return TRUE;
  3808. case WM_COMMAND:
  3809. switch(LOWORD( wParam ))
  3810. {
  3811. case IDOK:
  3812. pWizardUserMem = (PWIZARDUSERMEM) GetWindowLongPtr(hDlg, DWLP_USER);
  3813. Assert(pWizardUserMem);
  3814. pSenderInfo = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo;
  3815. //
  3816. // free sender fields except address
  3817. //
  3818. MemFree(pSenderInfo->lptstrName);
  3819. pSenderInfo->lptstrName = NULL;
  3820. MemFree(pSenderInfo->lptstrFaxNumber);
  3821. pSenderInfo->lptstrFaxNumber = NULL;
  3822. MemFree(pSenderInfo->lptstrCompany);
  3823. pSenderInfo->lptstrCompany = NULL;
  3824. MemFree(pSenderInfo->lptstrTitle);
  3825. pSenderInfo->lptstrTitle = NULL;
  3826. MemFree(pSenderInfo->lptstrDepartment);
  3827. pSenderInfo->lptstrDepartment = NULL;
  3828. MemFree(pSenderInfo->lptstrOfficeLocation);
  3829. pSenderInfo->lptstrOfficeLocation = NULL;
  3830. MemFree(pSenderInfo->lptstrHomePhone);
  3831. pSenderInfo->lptstrHomePhone = NULL;
  3832. MemFree(pSenderInfo->lptstrOfficePhone);
  3833. pSenderInfo->lptstrOfficePhone = NULL;
  3834. MemFree(pSenderInfo->lptstrEmail);
  3835. pSenderInfo->lptstrEmail = NULL;
  3836. MemFree(pSenderInfo->lptstrBillingCode);
  3837. pSenderInfo->lptstrBillingCode = NULL;
  3838. MemFree(pSenderInfo->lptstrStreetAddress);
  3839. pSenderInfo->lptstrStreetAddress = NULL;
  3840. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_FULLNAME, lptstrName);
  3841. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_FAX_NUMBER, lptstrFaxNumber);
  3842. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_COMPANY, lptstrCompany);
  3843. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_TITLE, lptstrTitle);
  3844. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_DEPT, lptstrDepartment);
  3845. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_OFFICE, lptstrOfficeLocation);
  3846. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_HOME_PHONE, lptstrHomePhone);
  3847. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_WORK_PHONE, lptstrOfficePhone);
  3848. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_BILLING_CODE, lptstrBillingCode);
  3849. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_MAILBOX, lptstrEmail);
  3850. FillUserInfoFromEditCrtl(IDC_WIZ_USERINFO_ADDRESS, lptstrStreetAddress);
  3851. pWizardUserMem->lpFaxSendWizardData->bSaveSenderInfo =
  3852. IsDlgButtonChecked(hDlg, IDC_USER_INFO_JUST_THIS_TIME) != BST_CHECKED;
  3853. EndDialog(hDlg,1);
  3854. return TRUE;
  3855. case IDCANCEL:
  3856. EndDialog( hDlg,0 );
  3857. return TRUE;
  3858. }
  3859. break;
  3860. case WM_HELP:
  3861. WinHelpContextPopup(((LPHELPINFO)lParam)->dwContextId, hDlg);
  3862. return TRUE;
  3863. case WM_CONTEXTMENU:
  3864. WinHelpContextPopup(GetWindowContextHelpId((HWND)wParam), hDlg);
  3865. return TRUE;
  3866. default:
  3867. return FALSE;
  3868. } ;
  3869. return TRUE;
  3870. }
  3871. LPTSTR
  3872. FormatTime(
  3873. WORD Hour,
  3874. WORD Minute,
  3875. LPTSTR Buffer,
  3876. LPDWORD lpdwBufferSize)
  3877. {
  3878. SYSTEMTIME SystemTime;
  3879. ZeroMemory(&SystemTime,sizeof(SystemTime));
  3880. SystemTime.wHour = Hour;
  3881. SystemTime.wMinute = Minute;
  3882. if (!FaxTimeFormat(LOCALE_USER_DEFAULT,
  3883. TIME_NOSECONDS,
  3884. &SystemTime,
  3885. NULL,
  3886. Buffer,
  3887. *lpdwBufferSize
  3888. ))
  3889. {
  3890. Error(("FaxTimeFormat failed. ec = 0x%X\n",GetLastError()));
  3891. //
  3892. // Indicate about the error
  3893. //
  3894. *lpdwBufferSize = 0;
  3895. Buffer[0] = '\0';
  3896. }
  3897. return Buffer;
  3898. }
  3899. INT_PTR
  3900. FinishWizProc(
  3901. HWND hDlg,
  3902. UINT message,
  3903. WPARAM wParam,
  3904. LPARAM lParam
  3905. )
  3906. /*++
  3907. Routine Description:
  3908. Dialog procedure for the last wizard page:
  3909. give user a chance to confirm or cancel the dialog.
  3910. Arguments:
  3911. hDlg - Identifies the wizard page
  3912. message - Specifies the message
  3913. wParam - Specifies additional message-specific information
  3914. lParam - Specifies additional message-specific information
  3915. Return Value:
  3916. Depends on the message parameter
  3917. --*/
  3918. {
  3919. PWIZARDUSERMEM pWizardUserMem;
  3920. HWND hPreview;
  3921. TCHAR TmpTimeBuffer[64];
  3922. TCHAR TimeBuffer[64] = {0};
  3923. TCHAR SendTimeBuffer[64];
  3924. TCHAR NoneBuffer[64];
  3925. TCHAR CoverpageBuffer[MAX_PATH+1] = {0};
  3926. LPTSTR Coverpage=NULL;
  3927. DWORD dwBufferSize = 0;
  3928. if (! (pWizardUserMem = CommonWizardProc(hDlg, message, wParam, lParam, PSWIZB_BACK|PSWIZB_FINISH)) )
  3929. return FALSE;
  3930. switch (message)
  3931. {
  3932. case WM_INITDIALOG:
  3933. //
  3934. // Init recipient list
  3935. //
  3936. if (!InitRecipientListView(GetDlgItem(hDlg, IDC_WIZ_CONGRATS_RECIPIENT_LIST)))
  3937. {
  3938. Warning(("InitRecipientListView failed\n"));
  3939. }
  3940. //
  3941. // Apply the print preview option if we where requested and default to show preview
  3942. //
  3943. hPreview = GetDlgItem(hDlg, IDC_WIZ_CONGRATS_PREVIEW_FAX);
  3944. if (pWizardUserMem->dwFlags & FSW_PRINT_PREVIEW_OPTION)
  3945. {
  3946. Button_Enable(hPreview, TRUE);
  3947. ShowWindow(hPreview, SW_SHOW);
  3948. }
  3949. else
  3950. {
  3951. Button_Enable(hPreview, FALSE);
  3952. ShowWindow(hPreview, SW_HIDE);
  3953. }
  3954. return TRUE;
  3955. case WM_COMMAND:
  3956. switch(LOWORD( wParam ))
  3957. {
  3958. case IDC_WIZ_CONGRATS_PREVIEW_FAX:
  3959. {
  3960. if (pWizardUserMem->hFaxPreviewProcess)
  3961. {
  3962. //
  3963. // Preview is in progress we can not continue.
  3964. //
  3965. ErrorMessageBox(hDlg, IDS_PLEASE_CLOSE_FAX_PREVIEW, MB_ICONINFORMATION);
  3966. }
  3967. else
  3968. {
  3969. DisplayFaxPreview(
  3970. hDlg,
  3971. pWizardUserMem,
  3972. pWizardUserMem->lpInitialData->lptstrPreviewFile
  3973. );
  3974. }
  3975. return TRUE;
  3976. }
  3977. break;
  3978. default:
  3979. break;
  3980. }
  3981. break;
  3982. case WM_NOTIFY:
  3983. switch (((NMHDR *) lParam)->code)
  3984. {
  3985. case PSN_WIZBACK :
  3986. if(0 == pWizardUserMem->dwSupportedReceipts)
  3987. {
  3988. //
  3989. // skip notifications page
  3990. //
  3991. SetWindowLongPtr(hDlg,
  3992. DWLP_MSGRESULT,
  3993. (pWizardUserMem->dwComCtrlVer >= IE50_COMCTRL_VER) ? IDD_WIZARD_FAXOPTS :
  3994. IDD_WIZARD_FAXOPTS_NOWIZARD97);
  3995. return TRUE;
  3996. }
  3997. break;
  3998. case PSN_WIZFINISH:
  3999. if (pWizardUserMem->hFaxPreviewProcess)
  4000. {
  4001. //
  4002. // Preview is in progress we can not continue.
  4003. //
  4004. ErrorMessageBox(hDlg, IDS_PLEASE_CLOSE_FAX_PREVIEW, MB_ICONINFORMATION);
  4005. //
  4006. // prevent the propsheet from closing
  4007. //
  4008. SetWindowLong(hDlg, DWLP_MSGRESULT, -1);
  4009. return TRUE;
  4010. }
  4011. else
  4012. {
  4013. return FALSE; // allow the propsheet to close
  4014. }
  4015. case PSN_SETACTIVE:
  4016. ZeroMemory(NoneBuffer,sizeof(NoneBuffer));
  4017. if (!LoadString(g_hResource,
  4018. IDS_NONE,
  4019. NoneBuffer,
  4020. ARR_SIZE(NoneBuffer)))
  4021. {
  4022. Error(("LoadString failed. ec = 0x%X\n",GetLastError()));
  4023. Assert(FALSE);
  4024. }
  4025. //
  4026. // large title font on last page
  4027. //
  4028. SetWindowFont(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_READY), pWizardUserMem->hLargeFont, TRUE);
  4029. //
  4030. // set the sender name if it exists
  4031. //
  4032. if ( pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrName )
  4033. {
  4034. SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_FROM, pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrName );
  4035. EnableWindow(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_FROM),TRUE);
  4036. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_CONGRATS_FROM),TRUE);
  4037. } else {
  4038. if (NoneBuffer[0] != NUL)
  4039. {
  4040. SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_FROM, NoneBuffer );
  4041. EnableWindow(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_FROM),FALSE);
  4042. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_CONGRATS_FROM),FALSE);
  4043. }
  4044. }
  4045. //
  4046. // set the recipient name
  4047. //
  4048. if (!ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_WIZ_CONGRATS_RECIPIENT_LIST)))
  4049. {
  4050. Warning(("ListView_DeleteAllItems failed\n"));
  4051. }
  4052. if (!FillRecipientListView(pWizardUserMem,GetDlgItem(hDlg, IDC_WIZ_CONGRATS_RECIPIENT_LIST)))
  4053. {
  4054. Warning(("FillRecipientListView failed\n"));
  4055. }
  4056. //
  4057. // when to send
  4058. //
  4059. switch (pWizardUserMem->lpFaxSendWizardData->dwScheduleAction)
  4060. {
  4061. case JSA_SPECIFIC_TIME:
  4062. if (!LoadString(g_hResource,
  4063. IDS_SEND_SPECIFIC,
  4064. TmpTimeBuffer,
  4065. ARR_SIZE(TmpTimeBuffer)))
  4066. {
  4067. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  4068. Assert(FALSE);
  4069. }
  4070. dwBufferSize = ARR_SIZE(TimeBuffer);
  4071. wsprintf(SendTimeBuffer,
  4072. TmpTimeBuffer,
  4073. FormatTime(pWizardUserMem->lpFaxSendWizardData->tmSchedule.wHour,
  4074. pWizardUserMem->lpFaxSendWizardData->tmSchedule.wMinute,
  4075. TimeBuffer,
  4076. &dwBufferSize));
  4077. break;
  4078. case JSA_DISCOUNT_PERIOD:
  4079. if (!LoadString(g_hResource,
  4080. IDS_SEND_DISCOUNT,
  4081. SendTimeBuffer,
  4082. ARR_SIZE(SendTimeBuffer)))
  4083. {
  4084. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  4085. Assert(FALSE);
  4086. }
  4087. break;
  4088. case JSA_NOW:
  4089. if (!LoadString(g_hResource,
  4090. IDS_SEND_ASAP,
  4091. SendTimeBuffer,
  4092. ARR_SIZE(SendTimeBuffer)))
  4093. {
  4094. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  4095. Assert(FALSE);
  4096. }
  4097. };
  4098. SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_TIME, SendTimeBuffer );
  4099. //
  4100. // Coverpage
  4101. //
  4102. if (pWizardUserMem->bSendCoverPage ) {
  4103. EnableWindow(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_COVERPG),TRUE);
  4104. EnableWindow(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_SUBJECT),TRUE);
  4105. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_CONGRATS_COVERPG),TRUE);
  4106. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_CONGRATS_SUBJECT),TRUE);
  4107. //
  4108. // format the coverpage for display to the user
  4109. //
  4110. // drop path
  4111. Coverpage = _tcsrchr(pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName, FAX_PATH_SEPARATOR_CHR);
  4112. if (!Coverpage) {
  4113. Coverpage = pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName;
  4114. } else {
  4115. Coverpage++;
  4116. }
  4117. _tcsncpy(CoverpageBuffer,Coverpage, MAX_PATH);
  4118. // crop file extension
  4119. Coverpage = _tcschr(CoverpageBuffer,TEXT(FILENAME_EXT));
  4120. if (Coverpage && *Coverpage) {
  4121. *Coverpage = (TCHAR) NUL;
  4122. }
  4123. SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_COVERPG, CoverpageBuffer );
  4124. if (pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrSubject) {
  4125. if (!SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_SUBJECT, pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrSubject ))
  4126. {
  4127. Warning(("SetDlgItemText failed. ec = 0x%X\n",GetLastError()));
  4128. }
  4129. } else {
  4130. if (NoneBuffer[0] != NUL)
  4131. {
  4132. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_CONGRATS_SUBJECT),FALSE);
  4133. EnableWindow(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_SUBJECT),FALSE);
  4134. SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_SUBJECT, NoneBuffer );
  4135. }
  4136. }
  4137. } else {
  4138. if (NoneBuffer[0] != NUL)
  4139. {
  4140. SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_COVERPG, NoneBuffer );
  4141. SetDlgItemText(hDlg, IDC_WIZ_CONGRATS_SUBJECT, NoneBuffer );
  4142. }
  4143. EnableWindow(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_COVERPG),FALSE);
  4144. EnableWindow(GetDlgItem(hDlg,IDC_STATIC_WIZ_CONGRATS_SUBJECT),FALSE);
  4145. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_CONGRATS_COVERPG),FALSE);
  4146. EnableWindow(GetDlgItem(hDlg,IDC_WIZ_CONGRATS_SUBJECT),FALSE);
  4147. }
  4148. break;
  4149. default:
  4150. ;
  4151. }
  4152. default:
  4153. return FALSE;
  4154. } ;
  4155. return TRUE;
  4156. }
  4157. INT_PTR
  4158. WelcomeWizProc(
  4159. HWND hDlg,
  4160. UINT message,
  4161. WPARAM wParam,
  4162. LPARAM lParam
  4163. )
  4164. /*++
  4165. Routine Description:
  4166. Dialog procedure for the first wizard page:
  4167. give user a chance to confirm or cancel the dialog.
  4168. Arguments:
  4169. hDlg - Identifies the wizard page
  4170. message - Specifies the message
  4171. wParam - Specifies additional message-specific information
  4172. lParam - Specifies additional message-specific information
  4173. Return Value:
  4174. Depends on the message parameter
  4175. --*/
  4176. {
  4177. PWIZARDUSERMEM pWizardUserMem;
  4178. UINT ResourceString = IDS_ERROR_SERVER_RETRIEVE;
  4179. if (! (pWizardUserMem = CommonWizardProc(hDlg, message, wParam, lParam, PSWIZB_NEXT)))
  4180. return FALSE;
  4181. switch (message) {
  4182. case WM_INITDIALOG:
  4183. //
  4184. // set the large fonts
  4185. //
  4186. SetWindowFont(GetDlgItem(hDlg,IDC_WIZ_WELCOME_TITLE), pWizardUserMem->hLargeFont, TRUE);
  4187. //
  4188. // show this text only if we're running the send wizard
  4189. //
  4190. if ((pWizardUserMem->dwFlags & FSW_USE_SEND_WIZARD) != FSW_USE_SEND_WIZARD)
  4191. {
  4192. MyHideWindow(GetDlgItem(hDlg,IDC_WIZ_WELCOME_FAXSEND) );
  4193. }
  4194. else
  4195. {
  4196. MyHideWindow(GetDlgItem(hDlg,IDC_WIZ_WELCOME_NOFAXSEND) );
  4197. }
  4198. return TRUE;
  4199. case WM_NOTIFY:
  4200. if (((NMHDR *) lParam)->code == PSN_WIZNEXT)
  4201. {
  4202. //
  4203. // tapi is asynchronously initialized, wait for it to finish spinning up.
  4204. //
  4205. if (WaitForSingleObject( pWizardUserMem->hCountryListEvent, INFINITE ) != WAIT_OBJECT_0)
  4206. {
  4207. Error(("WaitForSingleObject failed. ec = 0x%X\n",GetLastError()));
  4208. Assert(FALSE);
  4209. goto close_wizard;
  4210. }
  4211. //
  4212. // Check that pCountryList is filled. Otherwise some error occured, e.g. can not
  4213. // connect to Fax Server or TAPI initialization failed. In this case we show an
  4214. // error pop up and close an application.
  4215. //
  4216. if (pWizardUserMem->dwQueueStates & FAX_OUTBOX_BLOCKED )
  4217. {
  4218. ResourceString = IDS_ERROR_SERVER_BLOCKED;
  4219. goto close_wizard;
  4220. }
  4221. if (!pWizardUserMem->pCountryList)
  4222. {
  4223. ResourceString = IDS_ERROR_SERVER_RETRIEVE;
  4224. goto close_wizard;
  4225. }
  4226. if((pWizardUserMem->dwRights & FAX_ACCESS_SUBMIT) != FAX_ACCESS_SUBMIT &&
  4227. (pWizardUserMem->dwRights & FAX_ACCESS_SUBMIT_NORMAL) != FAX_ACCESS_SUBMIT_NORMAL &&
  4228. (pWizardUserMem->dwRights & FAX_ACCESS_SUBMIT_HIGH) != FAX_ACCESS_SUBMIT_HIGH)
  4229. {
  4230. ResourceString = IDS_ERROR_NO_SUBMIT_ACCESS;
  4231. goto close_wizard;
  4232. }
  4233. }
  4234. } ;
  4235. return FALSE;
  4236. close_wizard:
  4237. ErrorMessageBox(hDlg, ResourceString, MB_ICONSTOP);
  4238. PropSheet_PressButton(((NMHDR *) lParam)->hwndFrom,PSBTN_CANCEL);
  4239. SetWindowLongPtr( hDlg, DWLP_MSGRESULT, -1 );
  4240. return TRUE;
  4241. }
  4242. BOOL
  4243. GetFakeRecipientInfo( PWIZARDUSERMEM pWizardUserMem)
  4244. /*++
  4245. Routine Description:
  4246. Skip send fax wizard and get faked recipient information from the registry
  4247. Arguments:
  4248. pWizardUserMem - Points to the user mode memory structure
  4249. Return Value:
  4250. TRUE if successful.
  4251. FALSE and last error is qual ERROR_SUCCESS, some of the registry values are missing.
  4252. FALSE and last error is not ERROR_SUCCESS, if error occured.
  4253. --*/
  4254. {
  4255. LPTSTR pRecipientEntry;
  4256. DWORD index;
  4257. TCHAR buffer[MAX_STRING_LEN];
  4258. BOOL fSuccess = FALSE;
  4259. HKEY hRegKey;
  4260. DWORD dwRes = ERROR_SUCCESS;
  4261. DWORD dwStringSize;
  4262. LPTSTR pCoverPage = NULL;
  4263. TCHAR* tstrCurrentUserKeyPath = NULL;
  4264. DWORD dwTestsNum;
  4265. BOOL fServerBasedCP = FALSE;
  4266. const char* strDebugPrefix = "[******REGISTRY HACK******]:";
  4267. Verbose(("%s Send Fax Wizard skipped...\n", strDebugPrefix));
  4268. Assert(pWizardUserMem);
  4269. SetLastError(0);
  4270. if(IsNTSystemVersion())
  4271. {
  4272. Verbose(("%s NT Platform\n", strDebugPrefix));
  4273. dwRes = FormatCurrentUserKeyPath( REGVAL_KEY_FAKE_TESTS,
  4274. &tstrCurrentUserKeyPath);
  4275. if(dwRes != ERROR_SUCCESS)
  4276. {
  4277. Error(("%s FormatCurrentUserKeyPath failed with ec = 0x%X\n",strDebugPrefix,dwRes));
  4278. SetLastError(dwRes);
  4279. return FALSE;
  4280. }
  4281. }
  4282. else
  4283. {
  4284. Verbose(("%s Win9x Platform\n", strDebugPrefix));
  4285. tstrCurrentUserKeyPath = DuplicateString(REGVAL_KEY_FAKE_TESTS);
  4286. if(!tstrCurrentUserKeyPath)
  4287. {
  4288. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  4289. return FALSE;
  4290. }
  4291. }
  4292. #ifdef UNICODE
  4293. Verbose(("%s Registry entry - %S\n", strDebugPrefix,tstrCurrentUserKeyPath));
  4294. #else
  4295. Verbose(("%s Registry entry - %s\n", strDebugPrefix,tstrCurrentUserKeyPath));
  4296. #endif
  4297. // Open user registry key
  4298. dwRes = RegOpenKey ( HKEY_LOCAL_MACHINE ,
  4299. tstrCurrentUserKeyPath,
  4300. &hRegKey );
  4301. if (ERROR_SUCCESS != dwRes)
  4302. {
  4303. //
  4304. // Failed to open key
  4305. //
  4306. Error(("%s RegOpenKey failed with. ec = 0x%X\n",strDebugPrefix,dwRes));
  4307. MemFree(tstrCurrentUserKeyPath);
  4308. SetLastError(0);
  4309. return FALSE;
  4310. }
  4311. MemFree(tstrCurrentUserKeyPath);
  4312. //
  4313. // UserInfo key was successfully openened
  4314. //
  4315. dwTestsNum = GetRegistryDword (hRegKey, REGVAL_FAKE_TESTS_COUNT);
  4316. if (!dwTestsNum)
  4317. {
  4318. Verbose(("%s No tests to execute\n", strDebugPrefix));
  4319. RegCloseKey (hRegKey);
  4320. SetLastError(0);
  4321. return FALSE;
  4322. }
  4323. Verbose(("%s %d tests to execute\n",strDebugPrefix, dwTestsNum));
  4324. index = GetRegistryDword (hRegKey, REGVAL_STRESS_INDEX);
  4325. if (index >= dwTestsNum)
  4326. {
  4327. index = 0;
  4328. }
  4329. wsprintf(buffer, TEXT("FakeRecipient%d"), index);
  4330. pRecipientEntry = GetRegistryStringMultiSz (hRegKey,
  4331. buffer,
  4332. TEXT("NOT FOUND\0"),
  4333. &dwStringSize );
  4334. if(!pRecipientEntry || !_tcscmp(pRecipientEntry , TEXT("NOT FOUND")))
  4335. {
  4336. RegCloseKey (hRegKey);
  4337. SetLastError(0);
  4338. return FALSE;
  4339. }
  4340. FreeRecipientList(pWizardUserMem);
  4341. pCoverPage = GetRegistryString (hRegKey,
  4342. REGVAL_FAKE_COVERPAGE,
  4343. TEXT(""));
  4344. fServerBasedCP = GetRegistryDword (hRegKey, REGVAL_FAKE_SERVER_BASED_CP) ? TRUE : FALSE;
  4345. if(fServerBasedCP)
  4346. {
  4347. LPTSTR pServerBasedCP = MemAlloc( sizeof(TCHAR) * (_tcslen(pCoverPage) + 2));
  4348. if(pServerBasedCP)
  4349. {
  4350. _tcscpy(pServerBasedCP, TEXT("\\"));
  4351. _tcscat(pServerBasedCP, pCoverPage);
  4352. }
  4353. MemFree(pCoverPage);
  4354. pCoverPage = pServerBasedCP;
  4355. }
  4356. //
  4357. // Update an index so that next time around we'll pick a different fake recipient
  4358. //
  4359. if (++index >= dwTestsNum)
  4360. {
  4361. index = 0;
  4362. }
  4363. SetRegistryDword(hRegKey, REGVAL_STRESS_INDEX, index);
  4364. RegCloseKey(hRegKey);
  4365. //
  4366. // Each fake recipient entry is a REG_MULTI_SZ of the following format:
  4367. // recipient name #1
  4368. // recipient fax number #1
  4369. // recipient name #2
  4370. // recipient fax number #2
  4371. // ...
  4372. //
  4373. if(pRecipientEntry)
  4374. {
  4375. __try {
  4376. PRECIPIENT pRecipient = NULL;
  4377. LPTSTR pName, pAddress, p = pRecipientEntry;
  4378. pName = pAddress = NULL;
  4379. while (*p) {
  4380. pName = p;
  4381. pAddress = pName + _tcslen(pName);
  4382. pAddress = _tcsinc(pAddress);
  4383. p = pAddress + _tcslen(pAddress);
  4384. p = _tcsinc(p);
  4385. pRecipient = MemAllocZ(sizeof(RECIPIENT));
  4386. if(pRecipient)
  4387. {
  4388. ZeroMemory(pRecipient,sizeof(RECIPIENT));
  4389. }
  4390. pName = DuplicateString(pName);
  4391. pAddress = DuplicateString(pAddress);
  4392. if (!pRecipient || !pName || !pAddress)
  4393. {
  4394. Error(("%s Invalid fake recipient information\n", strDebugPrefix));
  4395. SetLastError(ERROR_INVALID_DATA);
  4396. MemFree(pRecipient);
  4397. MemFree(pName);
  4398. MemFree(pAddress);
  4399. break;
  4400. }
  4401. pRecipient->pNext = pWizardUserMem->pRecipients;
  4402. pWizardUserMem->pRecipients = pRecipient;
  4403. pRecipient->pName = pName;
  4404. pRecipient->pAddress = pAddress;
  4405. }
  4406. } __finally
  4407. {
  4408. if (fSuccess = (pWizardUserMem->pRecipients != NULL))
  4409. {
  4410. //
  4411. // Determine whether a cover page should be used
  4412. //
  4413. pWizardUserMem->bSendCoverPage = FALSE;
  4414. if ((pCoverPage != NULL) && lstrlen (pCoverPage) && pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo)
  4415. {
  4416. //
  4417. // Use the cover page
  4418. //
  4419. pWizardUserMem->bSendCoverPage = TRUE;
  4420. CopyString(pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,
  4421. pCoverPage,
  4422. MAX_PATH);
  4423. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->bServerBased = fServerBasedCP;
  4424. }
  4425. }
  4426. else
  4427. {
  4428. SetLastError(ERROR_INVALID_DATA);
  4429. }
  4430. }
  4431. }
  4432. MemFree(pRecipientEntry);
  4433. MemFree(pCoverPage);
  4434. return fSuccess;
  4435. }
  4436. static HRESULT
  4437. FaxFreePersonalProfileInformation(
  4438. PFAX_PERSONAL_PROFILE lpPersonalProfileInfo
  4439. )
  4440. {
  4441. if (lpPersonalProfileInfo) {
  4442. MemFree(lpPersonalProfileInfo->lptstrName);
  4443. lpPersonalProfileInfo->lptstrName = NULL;
  4444. MemFree(lpPersonalProfileInfo->lptstrFaxNumber);
  4445. lpPersonalProfileInfo->lptstrFaxNumber = NULL;
  4446. MemFree(lpPersonalProfileInfo->lptstrCompany);
  4447. lpPersonalProfileInfo->lptstrCompany = NULL;
  4448. MemFree(lpPersonalProfileInfo->lptstrStreetAddress);
  4449. lpPersonalProfileInfo->lptstrStreetAddress = NULL;
  4450. MemFree(lpPersonalProfileInfo->lptstrCity);
  4451. lpPersonalProfileInfo->lptstrCity = NULL;
  4452. MemFree(lpPersonalProfileInfo->lptstrState);
  4453. lpPersonalProfileInfo->lptstrState = NULL;
  4454. MemFree(lpPersonalProfileInfo->lptstrZip);
  4455. lpPersonalProfileInfo->lptstrZip = NULL;
  4456. MemFree(lpPersonalProfileInfo->lptstrCountry);
  4457. lpPersonalProfileInfo->lptstrCountry = NULL;
  4458. MemFree(lpPersonalProfileInfo->lptstrTitle);
  4459. lpPersonalProfileInfo->lptstrTitle = NULL;
  4460. MemFree(lpPersonalProfileInfo->lptstrDepartment);
  4461. lpPersonalProfileInfo->lptstrDepartment = NULL;
  4462. MemFree(lpPersonalProfileInfo->lptstrOfficeLocation);
  4463. lpPersonalProfileInfo->lptstrOfficeLocation = NULL;
  4464. MemFree(lpPersonalProfileInfo->lptstrHomePhone);
  4465. lpPersonalProfileInfo->lptstrHomePhone = NULL;
  4466. MemFree(lpPersonalProfileInfo->lptstrOfficePhone);
  4467. lpPersonalProfileInfo->lptstrOfficePhone = NULL;
  4468. MemFree(lpPersonalProfileInfo->lptstrEmail);
  4469. lpPersonalProfileInfo->lptstrEmail = NULL;
  4470. MemFree(lpPersonalProfileInfo->lptstrBillingCode);
  4471. lpPersonalProfileInfo->lptstrBillingCode = NULL;
  4472. MemFree(lpPersonalProfileInfo->lptstrTSID);
  4473. lpPersonalProfileInfo->lptstrTSID = NULL;
  4474. }
  4475. return S_OK;
  4476. }
  4477. static HRESULT
  4478. FaxFreeCoverPageInformation(
  4479. PFAX_COVERPAGE_INFO_EX lpCoverPageInfo
  4480. )
  4481. {
  4482. if (lpCoverPageInfo) {
  4483. MemFree(lpCoverPageInfo->lptstrCoverPageFileName);
  4484. MemFree(lpCoverPageInfo->lptstrNote);
  4485. MemFree(lpCoverPageInfo->lptstrSubject);
  4486. MemFree(lpCoverPageInfo);
  4487. }
  4488. return S_OK;
  4489. }
  4490. HRESULT WINAPI
  4491. FaxFreeSendWizardData(
  4492. LPFAX_SEND_WIZARD_DATA lpFaxSendWizardData
  4493. )
  4494. {
  4495. if (lpFaxSendWizardData) {
  4496. FaxFreeCoverPageInformation(lpFaxSendWizardData->lpCoverPageInfo) ;
  4497. FaxFreePersonalProfileInformation(lpFaxSendWizardData->lpSenderInfo);
  4498. MemFree(lpFaxSendWizardData->lpSenderInfo);
  4499. FreeRecipientInfo(&lpFaxSendWizardData->dwNumberOfRecipients,lpFaxSendWizardData->lpRecipientsInfo);
  4500. MemFree(lpFaxSendWizardData->szReceiptDeliveryAddress);
  4501. MemFree(lpFaxSendWizardData->lptstrPreviewFile);
  4502. }
  4503. return S_OK;
  4504. }
  4505. BOOL
  4506. SendFaxWizardInternal(
  4507. PWIZARDUSERMEM pWizardUserMem
  4508. );
  4509. HRESULT
  4510. FaxSendWizardUI(
  4511. IN DWORD hWndOwner,
  4512. IN DWORD dwFlags,
  4513. IN LPTSTR lptstrServerName,
  4514. IN LPTSTR lptstrPrinterName,
  4515. IN LPFAX_SEND_WIZARD_DATA lpInitialData,
  4516. OUT LPTSTR lptstrTifName,
  4517. IN UINT cchstrTifName,
  4518. OUT LPFAX_SEND_WIZARD_DATA lpFaxSendWizardData
  4519. )
  4520. /*++
  4521. Routine Description:
  4522. This function shows the fax send wizard
  4523. Arguments:
  4524. hWndOwner - pointer to owner's window
  4525. dwFlags - flags modified behavior of the fax send wizard. The flag can be combined from
  4526. the following values:
  4527. FSW_FORCE_COVERPAGE,
  4528. FSW_USE_SCANNER,
  4529. FSW_USE_SCHEDULE_ACTION,
  4530. FSW_USE_RECEIPT,
  4531. FSW_SEND_WIZARD_FROM_SN,
  4532. FSW_RESEND_WIZARD,
  4533. FSW_PRINT_PREVIEW_OPTION
  4534. for more information about this flags see win9xfaxprinterdriver.doc
  4535. lptstrServerName - pointer to the server name
  4536. lptstrPrinterName - pointer to the printer name
  4537. lpInitialData - pointer to the initial data (not NULL!!!)
  4538. lptstrTifName - pointer to the output scanned tiff file (must be allocated)
  4539. cchstrTifName - size of lptstrTifName buffer in TCHARs
  4540. lpFaxSendWizardData - pointer to received data
  4541. Return Value:
  4542. S_OK if success,
  4543. S_FALSE if CANCEL was pressed
  4544. error otherwise (may return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  4545. HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER))
  4546. --*/
  4547. {
  4548. PWIZARDUSERMEM pWizardUserMem = NULL;
  4549. BOOL bResult = FALSE;
  4550. HRESULT hResult = S_FALSE;
  4551. INT i,iCount;
  4552. PRECIPIENT pRecipient;
  4553. //
  4554. // Validate parameters
  4555. //
  4556. Assert(lpInitialData);
  4557. Assert(lpFaxSendWizardData);
  4558. Assert(lptstrTifName);
  4559. if (!lpInitialData || !lpFaxSendWizardData || !lptstrTifName ||
  4560. lpFaxSendWizardData->dwSizeOfStruct != sizeof(FAX_SEND_WIZARD_DATA))
  4561. {
  4562. Error(("Invalid parameter passed to function FaxSendWizardUI\n"));
  4563. hResult = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  4564. goto exit;
  4565. }
  4566. if ((pWizardUserMem = MemAllocZ(sizeof(WIZARDUSERMEM))) == NULL)
  4567. {
  4568. Error(("Memory allocation failed\n"));
  4569. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4570. goto exit;
  4571. }
  4572. ZeroMemory(pWizardUserMem, sizeof(WIZARDUSERMEM));
  4573. pWizardUserMem->lptstrServerName = lptstrServerName;
  4574. pWizardUserMem->lptstrPrinterName = lptstrPrinterName;
  4575. pWizardUserMem->dwFlags = dwFlags;
  4576. pWizardUserMem->lpInitialData = lpInitialData;
  4577. pWizardUserMem->lpFaxSendWizardData = lpFaxSendWizardData;
  4578. pWizardUserMem->isLocalPrinter = (lptstrServerName == NULL);
  4579. pWizardUserMem->szTempPreviewTiff[0] = TEXT('\0');
  4580. if ( (lpFaxSendWizardData->lpCoverPageInfo =
  4581. MemAllocZ(sizeof(FAX_COVERPAGE_INFO_EX))) == NULL)
  4582. {
  4583. Error(("Memory allocation failed\n"));
  4584. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4585. goto error;
  4586. }
  4587. ZeroMemory(lpFaxSendWizardData->lpCoverPageInfo, sizeof(FAX_COVERPAGE_INFO_EX));
  4588. lpFaxSendWizardData->lpCoverPageInfo->dwSizeOfStruct = sizeof(FAX_COVERPAGE_INFO_EX);
  4589. lpFaxSendWizardData->lpCoverPageInfo->dwCoverPageFormat = FAX_COVERPAGE_FMT_COV;
  4590. if ( (lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName =
  4591. MemAllocZ(sizeof(TCHAR)*MAX_PATH)) == NULL)
  4592. {
  4593. Error(("Memory allocation failed\n"));
  4594. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4595. goto error;
  4596. }
  4597. ZeroMemory(lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName, sizeof(TCHAR) * MAX_PATH);
  4598. if ( (lpFaxSendWizardData->lpSenderInfo = MemAllocZ(sizeof(FAX_PERSONAL_PROFILE))) == NULL)
  4599. {
  4600. Error(("Memory allocation failed\n"));
  4601. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4602. goto error;
  4603. }
  4604. ZeroMemory(lpFaxSendWizardData->lpSenderInfo, sizeof(FAX_PERSONAL_PROFILE));
  4605. lpFaxSendWizardData->lpSenderInfo->dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILE);
  4606. if (!CopyPersonalProfile(lpFaxSendWizardData->lpSenderInfo, lpInitialData->lpSenderInfo))
  4607. {
  4608. hResult = HRESULT_FROM_WIN32(GetLastError());
  4609. Error((
  4610. "CopyPersonalProflie() for SenderInfo failed (hr: 0x%08X)\n",
  4611. hResult
  4612. ));
  4613. goto error;
  4614. }
  4615. FreeRecipientList(pWizardUserMem);
  4616. //
  4617. // copies recipient information to internal structure
  4618. //
  4619. if (!SUCCEEDED(StoreRecipientInfoInternal(pWizardUserMem)))
  4620. {
  4621. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4622. goto error;
  4623. }
  4624. pWizardUserMem->bSendCoverPage = (pWizardUserMem->lpInitialData->lpCoverPageInfo->lptstrCoverPageFileName &&
  4625. pWizardUserMem->lpInitialData->lpCoverPageInfo->lptstrCoverPageFileName[0] != NUL);
  4626. bResult = SendFaxWizardInternal(pWizardUserMem);
  4627. if (bResult)
  4628. {
  4629. for (iCount=0,pRecipient=pWizardUserMem->pRecipients;
  4630. pRecipient;
  4631. pRecipient=pRecipient->pNext )
  4632. {
  4633. iCount++;
  4634. }
  4635. if ((lpFaxSendWizardData->dwNumberOfRecipients = iCount) > 0)
  4636. {
  4637. if ( (lpFaxSendWizardData->lpRecipientsInfo
  4638. = MemAllocZ(sizeof(FAX_PERSONAL_PROFILE)*iCount)) == NULL)
  4639. {
  4640. Error(("Memory allocation failed\n"));
  4641. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4642. goto error;
  4643. }
  4644. ZeroMemory(lpFaxSendWizardData->lpRecipientsInfo,sizeof(FAX_PERSONAL_PROFILE)*iCount);
  4645. for (i=0,pRecipient=pWizardUserMem->pRecipients;
  4646. pRecipient && i<iCount ;
  4647. pRecipient=pRecipient->pNext , i++)
  4648. {
  4649. lpFaxSendWizardData->lpRecipientsInfo[i].dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILE);
  4650. hResult = CopyRecipientInfo(&lpFaxSendWizardData->lpRecipientsInfo[i],
  4651. pRecipient,
  4652. pWizardUserMem->isLocalPrinter);
  4653. if (hResult != S_OK)
  4654. {
  4655. goto error;
  4656. }
  4657. }
  4658. }
  4659. if (pWizardUserMem->bSendCoverPage == FALSE)
  4660. {
  4661. Assert(lpFaxSendWizardData->lpCoverPageInfo);
  4662. MemFree(lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName);
  4663. lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName = NULL;
  4664. }
  4665. hResult = StringCchCopy(lptstrTifName, cchstrTifName, pWizardUserMem->FileName);
  4666. if(FAILED(hResult))
  4667. {
  4668. Error(("Not enough memory in lptstrTifName buffer\n"));
  4669. Assert(0);
  4670. goto error;
  4671. }
  4672. }
  4673. hResult = bResult ? S_OK : S_FALSE;
  4674. goto exit;
  4675. error:
  4676. if (lpFaxSendWizardData)
  4677. {
  4678. FaxFreeSendWizardData(lpFaxSendWizardData);
  4679. }
  4680. exit:
  4681. if (pWizardUserMem)
  4682. {
  4683. FreeRecipientList(pWizardUserMem);
  4684. if (pWizardUserMem->lpWabInit)
  4685. {
  4686. UnInitializeWAB( pWizardUserMem->lpWabInit);
  4687. }
  4688. if (pWizardUserMem->lpMAPIabInit)
  4689. {
  4690. UnInitializeMAPIAB(pWizardUserMem->lpMAPIabInit);
  4691. }
  4692. MemFree(pWizardUserMem);
  4693. }
  4694. return hResult;
  4695. }
  4696. HRESULT WINAPI
  4697. FaxSendWizard(
  4698. IN DWORD hWndOwner,
  4699. IN DWORD dwFlags,
  4700. IN LPTSTR lptstrServerName,
  4701. IN LPTSTR lptstrPrinterName,
  4702. IN LPFAX_SEND_WIZARD_DATA lpInitialData,
  4703. OUT LPTSTR lptstrTifName,
  4704. IN UINT cchstrTifName,
  4705. OUT LPFAX_SEND_WIZARD_DATA lpFaxSendWizardData
  4706. )
  4707. /*++
  4708. Routine Description:
  4709. This function prepares initial data and shows the fax send wizard.
  4710. This is invoked during CREATEDCPRE document event.
  4711. Arguments:
  4712. hWndOwner - pointer to owner's window
  4713. dwFlags - flags modified behavior of the fax send wizard. The flag can be combined from
  4714. the following values:
  4715. FSW_FORCE_COVERPAGE,
  4716. FSW_USE_SCANNER,
  4717. FSW_USE_SCHEDULE_ACTION,
  4718. FSW_USE_RECEIPT,
  4719. FSW_SEND_WIZARD_FROM_SN,
  4720. FSW_RESEND_WIZARD,
  4721. FSW_PRINT_PREVIEW_OPTION
  4722. for more information about this flags see win9xfaxprinterdriver.doc
  4723. lptstrServerName - pointer to the server name
  4724. lptstrPrinterName - pointer to the printer name
  4725. lpInitialData - pointer to the initial data (if NULL default values are created)
  4726. this is IN parameter, but it used as a local variable and may be changed
  4727. during the execution of the function. Though this parameter remains unchanged
  4728. at the end of function.
  4729. lptstrTifName - pointer to the output scanned tiff file (must be allocated)
  4730. cchstrTifName - size of lptstrTifName buffer in TCHARs
  4731. lpFaxSendWizardData - pointer to received data
  4732. Return Value:
  4733. S_OK if success,
  4734. S_FALSE if CANCEL was pressed
  4735. error otherwise (may return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY),
  4736. HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER))
  4737. --*/
  4738. {
  4739. HRESULT hResult;
  4740. DWORD dwIndex;
  4741. DWORD dwDeafultValues = 0;
  4742. HMODULE hConfigWizModule=NULL;
  4743. FAX_CONFIG_WIZARD fpFaxConfigWiz=NULL;
  4744. DWORD dwVersion, dwMajorWinVer, dwMinorWinVer;
  4745. BOOL bAbort = FALSE; // Do we abort because the user refused to enter a dialing location?
  4746. // Validate parameters
  4747. Assert(lpFaxSendWizardData);
  4748. Assert(lptstrTifName);
  4749. //
  4750. // Do not execute any code before this initialization
  4751. //
  4752. if(!InitializeDll())
  4753. {
  4754. hResult = E_FAIL;
  4755. goto exit;
  4756. }
  4757. if (!lpFaxSendWizardData || !lptstrTifName ||
  4758. lpFaxSendWizardData->dwSizeOfStruct != sizeof(FAX_SEND_WIZARD_DATA))
  4759. {
  4760. Error(("Invalid parameter passed to function FaxSendWizard\n"));
  4761. hResult = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  4762. goto exit;
  4763. }
  4764. //
  4765. // launch Fax Configuration Wizard
  4766. //
  4767. dwVersion = GetVersion();
  4768. dwMajorWinVer = (DWORD)(LOBYTE(LOWORD(dwVersion)));
  4769. dwMinorWinVer = (DWORD)(HIBYTE(LOWORD(dwVersion)));
  4770. if(dwMajorWinVer != 5 || dwMinorWinVer < 1)
  4771. {
  4772. //
  4773. // Configuration Wizard enable for Windows XP only
  4774. //
  4775. goto no_config_wizard;
  4776. }
  4777. if (GetEnvironmentVariable(TEXT("NTFaxSendNote"), NULL, 0))
  4778. {
  4779. //
  4780. // Running from within the Fax Send Note (fxssend.exe) - config wizard alerady launched implicitly.
  4781. //
  4782. goto no_config_wizard;
  4783. }
  4784. hConfigWizModule = LoadLibrary(FAX_CONFIG_WIZARD_DLL);
  4785. if(hConfigWizModule)
  4786. {
  4787. fpFaxConfigWiz = (FAX_CONFIG_WIZARD)GetProcAddress(hConfigWizModule, FAX_CONFIG_WIZARD_PROC);
  4788. if(fpFaxConfigWiz)
  4789. {
  4790. if(!fpFaxConfigWiz(FALSE, &bAbort))
  4791. {
  4792. Error(("FaxConfigWizard failed (ec: %ld)",GetLastError()));
  4793. }
  4794. }
  4795. else
  4796. {
  4797. Error(("GetProcAddress(FaxConfigWizard) failed (ec: %ld)",GetLastError()));
  4798. }
  4799. if(!FreeLibrary(hConfigWizModule))
  4800. {
  4801. Error(("FreeLibrary(FxsCgfWz.dll) failed (ec: %ld)",GetLastError()));
  4802. }
  4803. }
  4804. else
  4805. {
  4806. Error(("LoadLibrary(FxsCgfWz.dll) failed (ec: %ld)",GetLastError()));
  4807. }
  4808. if (bAbort)
  4809. {
  4810. //
  4811. // User refused to enter a dialing location - stop the wizard now
  4812. //
  4813. return E_ABORT;
  4814. }
  4815. no_config_wizard:
  4816. //
  4817. // save the user info when finish
  4818. //
  4819. lpFaxSendWizardData->bSaveSenderInfo = TRUE;
  4820. //
  4821. // restore UseDialingRules flag for local fax
  4822. //
  4823. lpFaxSendWizardData->bUseDialingRules = FALSE;
  4824. lpFaxSendWizardData->bUseOutboundRouting = FALSE;
  4825. if(S_OK != RestoreUseDialingRules(&lpFaxSendWizardData->bUseDialingRules,
  4826. &lpFaxSendWizardData->bUseOutboundRouting))
  4827. {
  4828. Error(("RestoreUseDialingRules failed\n"));
  4829. }
  4830. //
  4831. // Allocates memory for initial data if lpInitialData is NULL
  4832. //
  4833. if (!lpInitialData)
  4834. {
  4835. if (!(lpInitialData = MemAllocZ(sizeof(FAX_SEND_WIZARD_DATA))) )
  4836. {
  4837. Error(("Memory allocation failed\n"));
  4838. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4839. goto exit;
  4840. }
  4841. ZeroMemory(lpInitialData, sizeof(FAX_SEND_WIZARD_DATA));
  4842. lpInitialData->dwSizeOfStruct = sizeof(FAX_SEND_WIZARD_DATA);
  4843. dwDeafultValues |= DEFAULT_INITIAL_DATA;
  4844. }
  4845. //
  4846. // Restores receipt info
  4847. //
  4848. if (!(dwFlags & FSW_USE_RECEIPT))
  4849. {
  4850. RestoreLastReciptInfo(&lpInitialData->dwReceiptDeliveryType,
  4851. &lpInitialData->szReceiptDeliveryAddress);
  4852. dwDeafultValues |= DEFAULT_RECEIPT_INFO;
  4853. }
  4854. //
  4855. // Restores cover page inforamtion
  4856. //
  4857. if (!lpInitialData->lpCoverPageInfo)
  4858. {
  4859. if (!(lpInitialData->lpCoverPageInfo = MemAllocZ(sizeof(FAX_COVERPAGE_INFO_EX))))
  4860. {
  4861. Error(("Memory allocation failed\n"));
  4862. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4863. goto exit;
  4864. }
  4865. ZeroMemory(lpInitialData->lpCoverPageInfo, sizeof(FAX_COVERPAGE_INFO_EX));
  4866. lpInitialData->lpCoverPageInfo->dwSizeOfStruct = sizeof(FAX_COVERPAGE_INFO_EX);
  4867. lpInitialData->lpCoverPageInfo->dwCoverPageFormat = FAX_COVERPAGE_FMT_COV;
  4868. hResult = RestoreCoverPageInfo(&lpInitialData->lpCoverPageInfo->lptstrCoverPageFileName);
  4869. if (FAILED(hResult))
  4870. {
  4871. // Then continue to run and don't initialize cover page's fields
  4872. }
  4873. dwDeafultValues |= DEFAULT_CV_INFO;
  4874. }
  4875. //
  4876. // Restores sender information
  4877. //
  4878. if (!lpInitialData->lpSenderInfo)
  4879. {
  4880. if (!(lpInitialData->lpSenderInfo = MemAllocZ(sizeof(FAX_PERSONAL_PROFILE))))
  4881. {
  4882. Error(("Memory allocation failed\n"));
  4883. hResult = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  4884. goto exit;
  4885. }
  4886. ZeroMemory(lpInitialData->lpSenderInfo, sizeof(FAX_PERSONAL_PROFILE));
  4887. lpInitialData->lpSenderInfo->dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILE);
  4888. hResult = FaxGetSenderInformation(lpInitialData->lpSenderInfo);
  4889. if (FAILED(hResult))
  4890. {
  4891. // Then continue to run and don't initialize sender info's fields
  4892. }
  4893. dwDeafultValues |= DEFAULT_SENDER_INFO;
  4894. }
  4895. hResult = FaxSendWizardUI( hWndOwner,
  4896. dwFlags,
  4897. lptstrServerName,
  4898. lptstrPrinterName,
  4899. lpInitialData,
  4900. lptstrTifName,
  4901. cchstrTifName,
  4902. lpFaxSendWizardData
  4903. );
  4904. if (hResult == S_OK)
  4905. {
  4906. SaveLastReciptInfo(lpFaxSendWizardData->dwReceiptDeliveryType,
  4907. lpFaxSendWizardData->szReceiptDeliveryAddress);
  4908. //
  4909. // Save the information about the last recipient as a convenience
  4910. //
  4911. if (lpFaxSendWizardData->dwNumberOfRecipients)
  4912. {
  4913. SaveLastRecipientInfo(&lpFaxSendWizardData->lpRecipientsInfo[0],
  4914. lpFaxSendWizardData->dwLastRecipientCountryId);
  4915. }
  4916. if(lpFaxSendWizardData->bSaveSenderInfo)
  4917. {
  4918. FaxSetSenderInformation(lpFaxSendWizardData->lpSenderInfo);
  4919. }
  4920. //
  4921. // save UseDialingRules flag for local fax
  4922. //
  4923. if(S_OK != SaveUseDialingRules(lpFaxSendWizardData->bUseDialingRules,
  4924. lpFaxSendWizardData->bUseOutboundRouting))
  4925. {
  4926. Error(("SaveUseDialingRules failed\n"));
  4927. }
  4928. if (lpFaxSendWizardData->lpCoverPageInfo &&
  4929. lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName)
  4930. {
  4931. SaveCoverPageInfo(lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName);
  4932. //
  4933. // If Server Based Cover Page File Name has full path, cut it off
  4934. //
  4935. if ( lpFaxSendWizardData->lpCoverPageInfo->bServerBased )
  4936. {
  4937. LPTSTR lptstrDelimiter = NULL;
  4938. if ( lptstrDelimiter =
  4939. _tcsrchr(lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,
  4940. FAX_PATH_SEPARATOR_CHR))
  4941. {
  4942. lptstrDelimiter = _tcsinc(lptstrDelimiter);
  4943. _tcscpy(lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,
  4944. lptstrDelimiter);
  4945. }
  4946. else
  4947. {
  4948. //
  4949. // Cover Page should always contain full path
  4950. //
  4951. Assert(FALSE);
  4952. }
  4953. }
  4954. }
  4955. else
  4956. {
  4957. //
  4958. // Cover page is not used
  4959. //
  4960. SaveCoverPageInfo(TEXT(""));
  4961. }
  4962. }
  4963. exit:
  4964. ShutdownTapi();
  4965. if ( dwDeafultValues & DEFAULT_RECEIPT_INFO )
  4966. {
  4967. MemFree(lpInitialData->szReceiptDeliveryAddress);
  4968. lpInitialData->szReceiptDeliveryAddress = NULL;
  4969. }
  4970. if ( dwDeafultValues & DEFAULT_RECIPIENT_INFO )
  4971. {
  4972. for(dwIndex = 0; dwIndex < lpInitialData->dwNumberOfRecipients; dwIndex++)
  4973. {
  4974. FaxFreePersonalProfileInformation(&lpInitialData->lpRecipientsInfo [dwIndex]);
  4975. }
  4976. MemFree(lpInitialData->lpRecipientsInfo);
  4977. lpInitialData->lpRecipientsInfo = NULL;
  4978. lpInitialData->dwNumberOfRecipients = 0;
  4979. }
  4980. if ( dwDeafultValues & DEFAULT_CV_INFO )
  4981. {
  4982. if (lpFaxSendWizardData->lpCoverPageInfo)
  4983. {
  4984. MemFree(lpInitialData->lpCoverPageInfo->lptstrCoverPageFileName);
  4985. lpInitialData->lpCoverPageInfo->lptstrCoverPageFileName = NULL;
  4986. }
  4987. MemFree(lpInitialData->lpCoverPageInfo);
  4988. lpInitialData->lpCoverPageInfo = NULL;
  4989. }
  4990. if ( dwDeafultValues & DEFAULT_SENDER_INFO )
  4991. {
  4992. if (lpInitialData->lpSenderInfo)
  4993. {
  4994. FaxFreeSenderInformation(lpInitialData->lpSenderInfo);
  4995. MemFree(lpInitialData->lpSenderInfo);
  4996. lpInitialData->lpSenderInfo = NULL;
  4997. }
  4998. }
  4999. if (dwDeafultValues & DEFAULT_INITIAL_DATA)
  5000. {
  5001. MemFree(lpInitialData);
  5002. lpInitialData = NULL;
  5003. }
  5004. //
  5005. // Remove left of temp preview files
  5006. //
  5007. DeleteTempPreviewFiles (NULL, FALSE);
  5008. UnInitializeDll();
  5009. return hResult;
  5010. }
  5011. BOOL
  5012. SendFaxWizardInternal(
  5013. PWIZARDUSERMEM pWizardUserMem
  5014. )
  5015. /*++
  5016. Routine Description:
  5017. Present the Send Fax Wizard to the user.
  5018. Arguments:
  5019. pWizardUserMem - Points to the user mode memory structure
  5020. Return Value:
  5021. TRUE if successful, FALSE if there is an error or the user pressed Cancel.
  5022. --*/
  5023. #define NUM_PAGES 6 // Number of wizard pages
  5024. {
  5025. PROPSHEETPAGE *ppsp = NULL;
  5026. PROPSHEETHEADER psh;
  5027. INT result = FALSE;
  5028. HDC hdc = NULL;
  5029. INT i;
  5030. LOGFONT LargeFont;
  5031. LOGFONT lfTitleFont;
  5032. LOGFONT lfSubTitleFont;
  5033. NONCLIENTMETRICS ncm = {0};
  5034. TCHAR FontName[100];
  5035. TCHAR FontSize[30];
  5036. INT iFontSize;
  5037. DWORD ThreadId;
  5038. HANDLE hThread = NULL;
  5039. BOOL bSkipReceiptsPage = FALSE;
  5040. LPTSTR lptstrResource = NULL;
  5041. //
  5042. // A shortcut to skip fax wizard for debugging/testing purposes
  5043. //
  5044. if(!GetFakeRecipientInfo(pWizardUserMem))
  5045. {
  5046. if(GetLastError())
  5047. {
  5048. return FALSE;
  5049. }
  5050. // else continue
  5051. }
  5052. else
  5053. {
  5054. return TRUE;
  5055. }
  5056. Verbose(("Presenting Send Fax Wizard\n"));
  5057. if (IsDesktopSKU() && pWizardUserMem->isLocalPrinter)
  5058. {
  5059. //
  5060. // For desktop SKUs, we don't show the receipts page if faxing locally
  5061. //
  5062. bSkipReceiptsPage = TRUE;
  5063. Assert (pWizardUserMem->lpInitialData);
  5064. pWizardUserMem->lpInitialData->dwReceiptDeliveryType = DRT_NONE;
  5065. pWizardUserMem->lpFaxSendWizardData->dwReceiptDeliveryType = DRT_NONE;
  5066. }
  5067. if (! (ppsp = MemAllocZ(sizeof(PROPSHEETPAGE) * NUM_PAGES))) {
  5068. Error(("Memory allocation failed\n"));
  5069. return FALSE;
  5070. }
  5071. //
  5072. // fire off a thread to do some slow stuff later on in the wizard.
  5073. //
  5074. pWizardUserMem->hCPEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  5075. if (!pWizardUserMem->hCPEvent)
  5076. {
  5077. Error((
  5078. "Failed to create pWizardUserMem->hCPEvent (ec: %ld)",
  5079. GetLastError()
  5080. ));
  5081. goto Error;
  5082. }
  5083. pWizardUserMem->hCountryListEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  5084. if (!pWizardUserMem->hCountryListEvent)
  5085. {
  5086. Error((
  5087. "Failed to create pWizardUserMem->hCountryListEvent (ec: %ld)",
  5088. GetLastError()
  5089. ));
  5090. goto Error;
  5091. }
  5092. pWizardUserMem->hTAPIEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  5093. if (!pWizardUserMem->hTAPIEvent)
  5094. {
  5095. Error((
  5096. "Failed to create pWizardUserMem->hTAPIEvent (ec: %ld)",
  5097. GetLastError()
  5098. ));
  5099. goto Error;
  5100. }
  5101. pWizardUserMem->pCountryList = NULL;
  5102. MarkPDEVWizardUserMem(pWizardUserMem);
  5103. hThread = CreateThread(NULL, 0, AsyncWizardThread, pWizardUserMem, 0, &ThreadId);
  5104. if (!hThread)
  5105. {
  5106. Error(("CreateThread failed. ec = 0x%X\n",GetLastError()));
  5107. goto Error;
  5108. }
  5109. //
  5110. // Fill out one PROPSHEETPAGE structure for every page:
  5111. // The first page is a welcome page
  5112. // The first page is for choose the fax recipient
  5113. // The second page is for choosing cover page, subject and note
  5114. // The third page is for entering time to send
  5115. // The fourth page is for choosing of receipt form
  5116. // The fifth page is for scanning pages (optional)
  5117. // The last page gives the user a chance to confirm or cancel the dialog
  5118. //
  5119. pWizardUserMem->dwComCtrlVer = GetDllVersion(TEXT("comctl32.dll"));
  5120. Verbose(("COMCTL32.DLL Version is : 0x%08X", pWizardUserMem->dwComCtrlVer));
  5121. if ( pWizardUserMem->dwComCtrlVer >= IE50_COMCTRL_VER)
  5122. {
  5123. FillInPropertyPage( ppsp, TRUE, IDD_WIZARD_WELCOME, WelcomeWizProc, pWizardUserMem ,0,0);
  5124. FillInPropertyPage( ppsp+1,TRUE, IDD_WIZARD_CHOOSE_WHO, RecipientWizProc, pWizardUserMem ,IDS_WIZ_RECIPIENT_TITLE,IDS_WIZ_RECIPIENT_SUB);
  5125. FillInPropertyPage( ppsp+2, TRUE, IDD_WIZARD_CHOOSE_CP, CoverPageWizProc, pWizardUserMem ,IDS_WIZ_COVERPAGE_TITLE,IDS_WIZ_COVERPAGE_SUB );
  5126. FillInPropertyPage( ppsp+3, TRUE, IDD_WIZARD_FAXOPTS, FaxOptsWizProc, pWizardUserMem ,IDS_WIZ_FAXOPTS_TITLE,IDS_WIZ_FAXOPTS_SUB);
  5127. if (!bSkipReceiptsPage)
  5128. {
  5129. FillInPropertyPage( ppsp+4, TRUE, IDD_WIZARD_FAXRECEIPT, FaxReceiptWizProc, pWizardUserMem ,IDS_WIZ_FAXRECEIPT_TITLE,IDS_WIZ_FAXRECEIPT_SUB);
  5130. }
  5131. FillInPropertyPage( ppsp + 4 + (bSkipReceiptsPage ? 0 : 1),
  5132. TRUE, IDD_WIZARD_CONGRATS, FinishWizProc, pWizardUserMem ,0,0);
  5133. }
  5134. else
  5135. {
  5136. FillInPropertyPage( ppsp, FALSE, IDD_WIZARD_WELCOME_NOWIZARD97, WelcomeWizProc, pWizardUserMem ,0,0);
  5137. FillInPropertyPage( ppsp+1, FALSE, IDD_WIZARD_CHOOSE_WHO_NOWIZARD97, RecipientWizProc, pWizardUserMem ,IDS_WIZ_RECIPIENT_TITLE,IDS_WIZ_RECIPIENT_SUB);
  5138. FillInPropertyPage( ppsp+2, FALSE, IDD_WIZARD_CHOOSE_CP_NOWIZARD97, CoverPageWizProc, pWizardUserMem ,IDS_WIZ_COVERPAGE_TITLE,IDS_WIZ_COVERPAGE_SUB );
  5139. FillInPropertyPage( ppsp+3, FALSE, IDD_WIZARD_FAXOPTS_NOWIZARD97, FaxOptsWizProc, pWizardUserMem ,IDS_WIZ_FAXOPTS_TITLE,IDS_WIZ_FAXOPTS_SUB);
  5140. if (!bSkipReceiptsPage)
  5141. {
  5142. FillInPropertyPage( ppsp+4, FALSE, IDD_WIZARD_FAXRECEIPT_NOWIZARD97, FaxReceiptWizProc, pWizardUserMem ,IDS_WIZ_FAXRECEIPT_TITLE,IDS_WIZ_FAXRECEIPT_SUB);
  5143. }
  5144. FillInPropertyPage( ppsp + 4 + (bSkipReceiptsPage ? 0 : 1),
  5145. FALSE, IDD_WIZARD_CONGRATS_NOWIZARD97, FinishWizProc, pWizardUserMem ,0,0);
  5146. }
  5147. //
  5148. // Fill out the PROPSHEETHEADER structure
  5149. //
  5150. ZeroMemory(&psh, sizeof(psh));
  5151. if(pWizardUserMem->dwComCtrlVer >= PACKVERSION(4,71))
  5152. {
  5153. psh.dwSize = sizeof(PROPSHEETHEADER);
  5154. }
  5155. else
  5156. {
  5157. psh.dwSize = PROPSHEETHEADER_V1_SIZE;
  5158. }
  5159. if ( pWizardUserMem->dwComCtrlVer >= IE50_COMCTRL_VER)
  5160. {
  5161. psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
  5162. }
  5163. else
  5164. {
  5165. psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD ;
  5166. }
  5167. psh.hwndParent = GetActiveWindow();
  5168. psh.hInstance = g_hResource;
  5169. psh.hIcon = NULL;
  5170. psh.pszCaption = TEXT("");
  5171. psh.nPages = NUM_PAGES;
  5172. psh.nStartPage = 0;
  5173. psh.ppsp = ppsp;
  5174. if(hdc = GetDC(NULL)) {
  5175. if(GetDeviceCaps(hdc,BITSPIXEL) >= 8) {
  5176. lptstrResource = MAKEINTRESOURCE(IDB_WATERMARK_256);
  5177. }
  5178. else lptstrResource = MAKEINTRESOURCE(IDB_WATERMARK_16);
  5179. ReleaseDC(NULL,hdc);
  5180. }
  5181. if ( pWizardUserMem->dwComCtrlVer >= IE50_COMCTRL_VER)
  5182. {
  5183. psh.pszbmHeader = MAKEINTRESOURCE(IDB_FAXWIZ_WATERMARK);
  5184. psh.pszbmWatermark = lptstrResource;
  5185. }
  5186. //
  5187. // get the large fonts for wizard97
  5188. //
  5189. ncm.cbSize = sizeof(ncm);
  5190. if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0))
  5191. {
  5192. Error(("SystemParametersInfo failed. ec = 0x%X\n",GetLastError()));
  5193. goto Error;
  5194. }
  5195. else
  5196. {
  5197. CopyMemory((LPVOID* )&LargeFont, (LPVOID *) &ncm.lfMessageFont,sizeof(LargeFont) );
  5198. CopyMemory((LPVOID* )&lfTitleFont, (LPVOID *) &ncm.lfMessageFont,sizeof(lfTitleFont) );
  5199. CopyMemory((LPVOID* )&lfSubTitleFont,(LPVOID *) &ncm.lfMessageFont,sizeof(lfSubTitleFont) );
  5200. if (!LoadString(g_hResource,IDS_LARGEFONT_NAME,FontName,ARR_SIZE(FontName)))
  5201. {
  5202. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  5203. Assert(FALSE);
  5204. }
  5205. if (!LoadString(g_hResource,IDS_LARGEFONT_SIZE,FontSize,ARR_SIZE(FontSize)))
  5206. {
  5207. Warning(("LoadString failed. ec = 0x%X\n",GetLastError()));
  5208. Assert(FALSE);
  5209. }
  5210. iFontSize = _tcstoul( FontSize, NULL, 10 );
  5211. // make sure we at least have some basic font
  5212. if (*FontName == 0 || iFontSize == 0) {
  5213. lstrcpy(FontName,TEXT("MS Shell Dlg") );
  5214. iFontSize = 18;
  5215. }
  5216. lstrcpyn(LargeFont.lfFaceName, FontName, LF_FACESIZE);
  5217. LargeFont.lfWeight = FW_BOLD;
  5218. lstrcpyn(lfTitleFont.lfFaceName, _T("MS Shell Dlg"), LF_FACESIZE);
  5219. lfTitleFont.lfWeight = FW_BOLD;
  5220. lstrcpyn(lfSubTitleFont.lfFaceName, _T("MS Shell Dlg"), LF_FACESIZE);
  5221. lfSubTitleFont.lfWeight = FW_NORMAL;
  5222. hdc = GetDC(NULL);
  5223. if (!hdc)
  5224. {
  5225. Error((
  5226. "GetDC() failed (ec: ld)",
  5227. GetLastError()
  5228. ));
  5229. goto Error;
  5230. }
  5231. LargeFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * iFontSize / 72);
  5232. lfTitleFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * 9 / 72);
  5233. lfSubTitleFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * 9 / 72);
  5234. pWizardUserMem->hLargeFont = CreateFontIndirect(&LargeFont);
  5235. if (!pWizardUserMem->hLargeFont)
  5236. {
  5237. Error((
  5238. "CreateFontIndirect(&LargeFont) failed (ec: %ld)",
  5239. GetLastError()
  5240. ));
  5241. goto Error;
  5242. }
  5243. pWizardUserMem->hTitleFont = CreateFontIndirect(&lfTitleFont);
  5244. if (!pWizardUserMem->hTitleFont )
  5245. {
  5246. Error((
  5247. "CreateFontIndirect(&lfTitleFont) failed (ec: %ld)",
  5248. GetLastError()
  5249. ));
  5250. goto Error;
  5251. }
  5252. ReleaseDC( NULL, hdc);
  5253. hdc = NULL;
  5254. }
  5255. //
  5256. // Display the wizard pages
  5257. //
  5258. if (PropertySheet(&psh) > 0)
  5259. result = pWizardUserMem->finishPressed;
  5260. else
  5261. {
  5262. Error(("PropertySheet() failed (ec: %ld)",GetLastError()));
  5263. result = FALSE;
  5264. }
  5265. //
  5266. // Cleanup properly before exiting
  5267. //
  5268. goto Exit;
  5269. //
  5270. // free headings
  5271. //
  5272. Error:
  5273. result = FALSE;
  5274. Exit:
  5275. if (hThread)
  5276. {
  5277. DWORD dwRes = WaitForSingleObject(hThread, INFINITE);
  5278. if(WAIT_OBJECT_0 != dwRes)
  5279. {
  5280. Error(("WaitForSingleObject for AsyncWizardThread failed. ec = 0x%X\n",GetLastError()));
  5281. }
  5282. if(!CloseHandle(hThread))
  5283. {
  5284. Error(("CloseHandle failed. ec = 0x%X\n",GetLastError()));
  5285. }
  5286. }
  5287. if (pWizardUserMem->hCPEvent)
  5288. {
  5289. if (!CloseHandle(pWizardUserMem->hCPEvent))
  5290. {
  5291. Error(("CloseHandle(pWizardUserMem->hCPEvent) failed (ec: %ld)", GetLastError()));
  5292. }
  5293. }
  5294. if (pWizardUserMem->hCountryListEvent)
  5295. {
  5296. if(!CloseHandle(pWizardUserMem->hCountryListEvent))
  5297. {
  5298. Error(("CloseHandle(pWizardUserMem->hCountryListEvent) failed (ec: %ld)",
  5299. GetLastError()));
  5300. }
  5301. }
  5302. if (pWizardUserMem->hTAPIEvent)
  5303. {
  5304. if(!CloseHandle(pWizardUserMem->hTAPIEvent))
  5305. {
  5306. Error(("CloseHandle(pWizardUserMem->hTAPIEvent) failed (ec: %ld)",
  5307. GetLastError()));
  5308. }
  5309. }
  5310. if (hdc)
  5311. {
  5312. ReleaseDC( NULL, hdc);
  5313. hdc = NULL;
  5314. }
  5315. if ( pWizardUserMem->dwComCtrlVer >= IE50_COMCTRL_VER)
  5316. {
  5317. for (i = 0; i< NUM_PAGES; i++) {
  5318. MemFree( (PVOID)(ppsp+i)->pszHeaderTitle );
  5319. MemFree( (PVOID)(ppsp+i)->pszHeaderSubTitle );
  5320. }
  5321. }
  5322. if (pWizardUserMem->pCountryList)
  5323. {
  5324. FaxFreeBuffer(pWizardUserMem->pCountryList);
  5325. }
  5326. MemFree(ppsp);
  5327. if (pWizardUserMem->hLargeFont)
  5328. {
  5329. DeleteObject(pWizardUserMem->hLargeFont);
  5330. pWizardUserMem->hLargeFont = NULL;
  5331. }
  5332. if (pWizardUserMem->hTitleFont)
  5333. {
  5334. DeleteObject(pWizardUserMem->hTitleFont);
  5335. pWizardUserMem->hTitleFont = NULL;
  5336. }
  5337. if (pWizardUserMem->pCPInfo)
  5338. {
  5339. FreeCoverPageInfo(pWizardUserMem->pCPInfo);
  5340. pWizardUserMem->pCPInfo = NULL;
  5341. }
  5342. Verbose(("Wizard finished...\n"));
  5343. return result;
  5344. }
  5345. //*****************************************************************************
  5346. //* Name: EnableCoverDlgItems
  5347. //* Author: Ronen Barenboim / 4-Feb-1999
  5348. //*****************************************************************************
  5349. //* DESCRIPTION:
  5350. //* Enables or disables the cover page related dialog item in the cover
  5351. //* page selection dialog.
  5352. //* The selection is based on the following rules:
  5353. //* If the "select cover page" checkbox is off all the other dialog items
  5354. //* are off.
  5355. //* Otherwise,
  5356. //* The subject edit box is enabled only if the cover page has an embedded
  5357. //* subject field.
  5358. //* The note edit box is enabled only if the cover page has an embedded
  5359. //* subject field.
  5360. //* PARAMETERS:
  5361. //* [IN] PWIZARDUSERMEM pWizardUserMem:
  5362. //* A pointer USERMEM struct that contains information used by the wizard.
  5363. // Specifically USERMEM.pCPDATA is used to get the selected page path.
  5364. //* [IN] HWND hDlg:
  5365. //* A handle to the cover page dialog window.
  5366. //* RETURN VALUE:
  5367. //* FALSE: If the function failed.
  5368. //* TRUE: Otherwise.
  5369. //*****************************************************************************
  5370. BOOL EnableCoverDlgItems(PWIZARDUSERMEM pWizardUserMem, HWND hDlg)
  5371. {
  5372. //
  5373. // Disable the subject and note edit boxes if the cover page does not contain the fields
  5374. //
  5375. TCHAR szCoverPage[MAX_PATH];
  5376. DWORD bServerCoverPage;
  5377. BOOL bCPSelected;
  5378. Assert(pWizardUserMem);
  5379. Assert(hDlg);
  5380. if (IsDlgButtonChecked(hDlg,IDC_CHOOSE_CP_CHECK)==BST_INDETERMINATE)
  5381. CheckDlgButton(hDlg, IDC_CHOOSE_CP_CHECK, BST_UNCHECKED );
  5382. bCPSelected = (BST_CHECKED == IsDlgButtonChecked(hDlg,IDC_CHOOSE_CP_CHECK));
  5383. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_LIST), bCPSelected);
  5384. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_CHOOSE_CP_SUBJECT), bCPSelected);
  5385. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_USER_INFO), bCPSelected);
  5386. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_CP_PREVIEW), bCPSelected);
  5387. ShowWindow (GetDlgItem(hDlg, IDC_STATIC_CP_PREVIEW), bCPSelected ? SW_SHOW : SW_HIDE);
  5388. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_SUBJECT), bCPSelected);
  5389. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_CHOOSE_CP_NOTE), bCPSelected);
  5390. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_NOTE), bCPSelected);
  5391. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_CHOOSE_TEMPLATE), bCPSelected);
  5392. if (!bCPSelected)
  5393. {
  5394. return TRUE;
  5395. }
  5396. //
  5397. // We have a CP
  5398. //
  5399. if (CB_ERR!=GetSelectedCoverPage(pWizardUserMem->pCPInfo,
  5400. GetDlgItem(hDlg, IDC_CHOOSE_CP_LIST),
  5401. szCoverPage,
  5402. ARR_SIZE(szCoverPage),
  5403. NULL,
  5404. 0,
  5405. &bServerCoverPage))
  5406. {
  5407. DWORD ec;
  5408. COVDOCINFO covDocInfo;
  5409. //
  5410. // Get cover page information. The NULL parameter for hDC causes RenderCoverPage
  5411. // to just return the cover page information in covDocInfo. It does not actually
  5412. // create the cover page TIFF.
  5413. //
  5414. ec = RenderCoverPage(NULL,
  5415. NULL,
  5416. NULL,
  5417. szCoverPage,
  5418. &covDocInfo,
  5419. FALSE);
  5420. if (ERROR_SUCCESS == ec)
  5421. {
  5422. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_CHOOSE_TEMPLATE), TRUE);
  5423. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_NOTE), (covDocInfo.Flags & COVFP_NOTE) ? TRUE : FALSE);
  5424. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_CHOOSE_CP_NOTE), (covDocInfo.Flags & COVFP_NOTE) ? TRUE : FALSE);
  5425. EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_CP_SUBJECT), (covDocInfo.Flags & COVFP_SUBJECT) ? TRUE : FALSE);
  5426. EnableWindow(GetDlgItem(hDlg, IDC_STATIC_CHOOSE_CP_SUBJECT), (covDocInfo.Flags & COVFP_SUBJECT) ? TRUE : FALSE);
  5427. pWizardUserMem->noteSubjectFlag = covDocInfo.Flags;
  5428. pWizardUserMem->cpPaperSize = covDocInfo.PaperSize;
  5429. pWizardUserMem->cpOrientation = covDocInfo.Orientation;
  5430. }
  5431. else
  5432. {
  5433. Error(("Cannot examine cover page file '%ws': %d\n", szCoverPage, ec));
  5434. return FALSE;
  5435. }
  5436. }
  5437. else
  5438. {
  5439. Error(("Failed to get cover page name"));
  5440. Assert(FALSE); // This should neverhappen
  5441. return FALSE;
  5442. }
  5443. return TRUE;
  5444. } // EnableCoverDlgItems
  5445. #ifdef DBG
  5446. #ifdef WIN__95
  5447. ULONG __cdecl
  5448. DbgPrint(
  5449. CHAR * format,
  5450. ...
  5451. )
  5452. {
  5453. va_list va;
  5454. char sz[MAX_PATH]={0};
  5455. va_start(va, format);
  5456. _vsnprintf(sz, ARR_SIZE(sz)-1, format, va);
  5457. va_end(va);
  5458. OutputDebugString(sz);
  5459. return 0;
  5460. }
  5461. VOID DbgBreakPoint(VOID)
  5462. {
  5463. DebugBreak();
  5464. }
  5465. #endif
  5466. #endif // DBG
  5467. //*****************************************************************************
  5468. //* Name: DrawCoverPagePreview
  5469. //* Author: Ronen Barenboim / 31-Dec-99
  5470. //*****************************************************************************
  5471. //* DESCRIPTION:
  5472. //* Draws the specified coverpage template into the specified window using
  5473. //* the specified device context.
  5474. //* The coverpage template is drawn within the client area of the window
  5475. //* and is surrounded by a 1 pixel wide black frame.
  5476. //* The device context is required to support partial redraw due to
  5477. //* WM_PAINT messages.
  5478. //*
  5479. //* PARAMETERS:
  5480. //* [IN] hDc
  5481. //* The device context on which to draw the preview.
  5482. //*
  5483. //* [IN] hwndPrev
  5484. //* The window into which the preview will be drawn.
  5485. //*
  5486. //* [IN] lpctstrCoverPagePath
  5487. //* The full path to the cover page template to be drawn
  5488. //*
  5489. //* [IN] wCPOrientation
  5490. //* The orientation of the cover page template to be drawn
  5491. //*
  5492. //* RETURN VALUE:
  5493. //* TRUE if the operation succeeded.
  5494. //* FALSE otherwise. Call GetLastError() to get the last error.
  5495. //*****************************************************************************
  5496. BOOL DrawCoverPagePreview(
  5497. HDC hdc,
  5498. HWND hwndPrev,
  5499. LPCTSTR lpctstrCoverPagePath,
  5500. WORD wCPOrientation)
  5501. {
  5502. RECT rectPreview;
  5503. BOOL rVal = TRUE;
  5504. HGDIOBJ hOldPen = 0;
  5505. COVDOCINFO covDocInfo;
  5506. DWORD ec;
  5507. //
  5508. // Dummy data for preview.
  5509. //
  5510. COVERPAGEFIELDS UserData;
  5511. Assert ((DMORIENT_PORTRAIT == wCPOrientation) || (DMORIENT_LANDSCAPE == wCPOrientation));
  5512. ZeroMemory(&UserData,sizeof(COVERPAGEFIELDS));
  5513. UserData.ThisStructSize = sizeof(COVERPAGEFIELDS);
  5514. UserData.RecName = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_NAME);
  5515. UserData.RecFaxNumber = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_FAXNUMBER);
  5516. UserData.RecCompany = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_COMPANY);
  5517. UserData.RecStreetAddress = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_ADDRESS);
  5518. UserData.RecCity = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_CITY);
  5519. UserData.RecState = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_STATE);
  5520. UserData.RecZip = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_ZIP);
  5521. UserData.RecCountry = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_COUNTRY);
  5522. UserData.RecTitle = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_TITLE);
  5523. UserData.RecDepartment = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_DEPARTMENT);
  5524. UserData.RecOfficeLocation = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_OFFICE);
  5525. UserData.RecHomePhone = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_FAXNUMBER);
  5526. UserData.RecOfficePhone = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_FAXNUMBER);
  5527. //
  5528. // Senders stuff...
  5529. //
  5530. UserData.SdrName = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_NAME);
  5531. UserData.SdrFaxNumber = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_FAXNUMBER);
  5532. UserData.SdrCompany = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_COMPANY);
  5533. UserData.SdrAddress = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_ADDRESS);
  5534. UserData.SdrTitle = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_TITLE);
  5535. UserData.SdrDepartment = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_DEPARTMENT);
  5536. UserData.SdrOfficeLocation = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_OFFICE);
  5537. UserData.SdrHomePhone = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_FAXNUMBER);
  5538. UserData.SdrOfficePhone = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_FAXNUMBER);
  5539. UserData.SdrEmail = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_EMAIL);
  5540. //
  5541. // Misc Stuff...
  5542. //
  5543. UserData.Note = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_NOTE);
  5544. UserData.Subject = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_SUBJECT);
  5545. UserData.TimeSent = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_TIMESENT);
  5546. UserData.NumberOfPages = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_NUMPAGES);
  5547. UserData.ToList = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_TOLIST);
  5548. UserData.CCList = AllocateAndLoadString(g_hResource, IDS_CPPREVIEW_TOLIST);
  5549. if (!UserData.RecName || !UserData.RecFaxNumber ||
  5550. !UserData.RecCompany || !UserData.RecStreetAddress ||
  5551. !UserData.RecCity || !UserData.RecState ||
  5552. !UserData.RecZip || !UserData.RecCountry ||
  5553. !UserData.RecTitle || !UserData.RecDepartment ||
  5554. !UserData.RecOfficeLocation || !UserData.RecHomePhone ||
  5555. !UserData.RecOfficePhone || !UserData.SdrName ||
  5556. !UserData.SdrFaxNumber || !UserData.SdrCompany ||
  5557. !UserData.SdrAddress || !UserData.SdrTitle ||
  5558. !UserData.SdrDepartment || !UserData.SdrOfficeLocation ||
  5559. !UserData.SdrHomePhone || !UserData.SdrOfficePhone ||
  5560. !UserData.Note || !UserData.Subject ||
  5561. !UserData.TimeSent || !UserData.NumberOfPages ||
  5562. !UserData.ToList || !UserData.CCList ||
  5563. !UserData.SdrEmail)
  5564. {
  5565. rVal = FALSE;
  5566. Error(("AllocateAndLoadString() is failed. ec = %ld\n", GetLastError()));
  5567. goto exit;
  5568. }
  5569. if (wCPOrientation != g_wCurrMiniPreviewOrientation)
  5570. {
  5571. DWORD dwWidth;
  5572. DWORD dwHeight;
  5573. //
  5574. // Time to change the dimensions of the mini-preview control
  5575. //
  5576. if (DMORIENT_LANDSCAPE == wCPOrientation)
  5577. {
  5578. //
  5579. // Landscape
  5580. //
  5581. dwWidth = g_dwMiniPreviewLandscapeWidth;
  5582. dwHeight = g_dwMiniPreviewLandscapeHeight;
  5583. }
  5584. else
  5585. {
  5586. //
  5587. // Portrait
  5588. //
  5589. dwWidth = g_dwMiniPreviewPortraitWidth;
  5590. dwHeight = g_dwMiniPreviewPortraitHeight;
  5591. }
  5592. //
  5593. // Resize the mini-preview control according to the new width and height
  5594. //
  5595. ec = GetControlRect(hwndPrev,&rectPreview);
  5596. if(ERROR_SUCCESS != ec)
  5597. {
  5598. rVal = FALSE;
  5599. Error(("GetControlRect failed. ec = 0x%X\n", ec));
  5600. goto exit;
  5601. }
  5602. //
  5603. // Resize and hide window to avoid fliking during rendering
  5604. //
  5605. SetWindowPos(hwndPrev,
  5606. 0,
  5607. g_bPreviewRTL ? rectPreview.right : rectPreview.left,
  5608. rectPreview.top,
  5609. dwWidth,
  5610. dwHeight,
  5611. SWP_NOZORDER | SWP_HIDEWINDOW);
  5612. g_wCurrMiniPreviewOrientation = wCPOrientation;
  5613. }
  5614. //
  5615. //
  5616. // Get the preview window rectangle (again) that will serve as the limit for the preview.
  5617. //
  5618. GetClientRect(hwndPrev,&rectPreview);
  5619. //
  5620. // Draw frame
  5621. //
  5622. if ((hOldPen = SelectPen (hdc,GetStockPen(BLACK_PEN))) == HGDI_ERROR)
  5623. {
  5624. rVal = FALSE;
  5625. Error(("SelectPen failed.\n"));
  5626. goto exit;
  5627. }
  5628. if (!Rectangle(
  5629. hdc,
  5630. 0,
  5631. 0,
  5632. rectPreview.right-rectPreview.left,
  5633. rectPreview.bottom-rectPreview.top)
  5634. )
  5635. {
  5636. rVal = FALSE;
  5637. Error(("Rectangle failed. ec = 0x%X\n",GetLastError()));
  5638. goto exit;
  5639. }
  5640. //
  5641. // Shrink the rectangle so we draw inside the frame
  5642. //
  5643. rectPreview.left += 1;
  5644. rectPreview.top += 1;
  5645. rectPreview.right -= 1;
  5646. rectPreview.bottom -= 1;
  5647. ec = RenderCoverPage(
  5648. hdc,
  5649. &rectPreview,
  5650. &UserData,
  5651. lpctstrCoverPagePath,
  5652. &covDocInfo,
  5653. TRUE);
  5654. if (ERROR_SUCCESS != ec)
  5655. {
  5656. Error(("Failed to print cover page file '%s' (ec: %ld)\n",
  5657. lpctstrCoverPagePath,
  5658. ec)
  5659. );
  5660. rVal = FALSE;
  5661. goto exit;
  5662. }
  5663. ShowWindow(hwndPrev, SW_SHOW);
  5664. exit:
  5665. //
  5666. // restore pen
  5667. //
  5668. if (hOldPen) {
  5669. SelectPen (hdc,(HPEN)hOldPen);
  5670. }
  5671. MemFree(UserData.RecName);
  5672. MemFree(UserData.RecFaxNumber);
  5673. MemFree(UserData.RecCompany);
  5674. MemFree(UserData.RecStreetAddress);
  5675. MemFree(UserData.RecCity);
  5676. MemFree(UserData.RecState);
  5677. MemFree(UserData.RecZip);
  5678. MemFree(UserData.RecCountry);
  5679. MemFree(UserData.RecTitle);
  5680. MemFree(UserData.RecDepartment);
  5681. MemFree(UserData.RecOfficeLocation);
  5682. MemFree(UserData.RecHomePhone);
  5683. MemFree(UserData.RecOfficePhone);
  5684. MemFree(UserData.SdrName);
  5685. MemFree(UserData.SdrFaxNumber);
  5686. MemFree(UserData.SdrCompany);
  5687. MemFree(UserData.SdrAddress);
  5688. MemFree(UserData.SdrTitle);
  5689. MemFree(UserData.SdrDepartment);
  5690. MemFree(UserData.SdrOfficeLocation);
  5691. MemFree(UserData.SdrHomePhone);
  5692. MemFree(UserData.SdrOfficePhone);
  5693. MemFree(UserData.Note);
  5694. MemFree(UserData.Subject);
  5695. MemFree(UserData.TimeSent);
  5696. MemFree(UserData.NumberOfPages);
  5697. MemFree(UserData.ToList);
  5698. MemFree(UserData.CCList);
  5699. return rVal;
  5700. }
  5701. //
  5702. // Subclass procedure for the static control in which we draw the coverpage preview
  5703. // see win32 SDK for prototype description.
  5704. //
  5705. LRESULT APIENTRY PreviewSubclassProc(
  5706. HWND hwnd,
  5707. UINT uMsg,
  5708. WPARAM wParam,
  5709. LPARAM lParam)
  5710. {
  5711. PWIZARDUSERMEM pWizardUserMem = NULL;
  5712. //
  5713. // We store a pointer to the WIZARDUSERMEM in the window of the sublclassed
  5714. // static cotntrol window. (see WM_INITDIALOG).
  5715. //
  5716. pWizardUserMem = g_pWizardUserMem;
  5717. Assert(ValidPDEVWizardUserMem(pWizardUserMem));
  5718. //
  5719. // We only care about WM_PAINT messages.
  5720. // Everything else is delegated to the window procedure of the class we subclassed.
  5721. //
  5722. if (WM_PAINT == uMsg)
  5723. {
  5724. PAINTSTRUCT ps;
  5725. HDC hdc;
  5726. hdc = BeginPaint(hwnd,&ps);
  5727. if (!hdc)
  5728. {
  5729. Error(("BeginPaint failed (hWnd = 0x%X) (ec: %ld)\n",hwnd,GetLastError()));
  5730. return FALSE;
  5731. }
  5732. if (!DrawCoverPagePreview(
  5733. hdc,
  5734. hwnd,
  5735. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,
  5736. pWizardUserMem->cpOrientation));
  5737. {
  5738. Error(("Failed to draw preview window (hWnd = 0x%X)\n",hwnd));
  5739. }
  5740. EndPaint(hwnd,&ps);
  5741. return FALSE; // Notify windows that we handled the paint message. We don't delegate
  5742. // this to the static control
  5743. }
  5744. else
  5745. {
  5746. Assert(pWizardUserMem->wpOrigStaticControlProc);
  5747. return CallWindowProc(
  5748. pWizardUserMem->wpOrigStaticControlProc,
  5749. hwnd,
  5750. uMsg,
  5751. wParam,
  5752. lParam);
  5753. }
  5754. }
  5755. /*
  5756. Concatenates tstrRegRoot path and a the string representation of the current user's SID.
  5757. [in] tstrRegRoot - Registry root prefix.
  5758. [out] ptstrCurrentUserKeyPath - Returns a string that represents the current
  5759. user's root key in the Registry. Caller must call MemFree
  5760. to free the buffer when done with it.
  5761. Returns win32 error.
  5762. */
  5763. static DWORD
  5764. FormatCurrentUserKeyPath( const PTCHAR tstrRegRoot,
  5765. PTCHAR* ptstrCurrentUserKeyPath)
  5766. {
  5767. HANDLE hToken = NULL;
  5768. BYTE* bTokenInfo = NULL;
  5769. TCHAR* tstrTextualSid = NULL;
  5770. DWORD cchSidSize = 0;
  5771. DWORD dwFuncRetStatus = ERROR_SUCCESS;
  5772. DWORD cbBuffer = 0;
  5773. SID_AND_ATTRIBUTES SidUser;
  5774. TCHAR* pLast = NULL;
  5775. // Open impersonated token
  5776. if(!OpenThreadToken( GetCurrentThread(),
  5777. TOKEN_READ,
  5778. TRUE,
  5779. &hToken))
  5780. {
  5781. dwFuncRetStatus = GetLastError();
  5782. }
  5783. if(dwFuncRetStatus != ERROR_SUCCESS)
  5784. {
  5785. if(dwFuncRetStatus != ERROR_NO_TOKEN)
  5786. {
  5787. return dwFuncRetStatus;
  5788. }
  5789. // Thread is not impersonating a user, get the process token
  5790. if(!OpenProcessToken( GetCurrentProcess(),
  5791. TOKEN_READ,
  5792. &hToken))
  5793. {
  5794. return GetLastError();
  5795. }
  5796. }
  5797. // Get user's token information
  5798. if(!GetTokenInformation( hToken,
  5799. TokenUser,
  5800. NULL,
  5801. 0,
  5802. &cbBuffer))
  5803. {
  5804. dwFuncRetStatus = GetLastError();
  5805. if(dwFuncRetStatus != ERROR_INSUFFICIENT_BUFFER)
  5806. {
  5807. goto Exit;
  5808. }
  5809. dwFuncRetStatus = ERROR_SUCCESS;
  5810. }
  5811. bTokenInfo = MemAlloc(cbBuffer);
  5812. if(!bTokenInfo)
  5813. {
  5814. dwFuncRetStatus = ERROR_OUTOFMEMORY;
  5815. goto Exit;
  5816. }
  5817. if(!GetTokenInformation( hToken,
  5818. TokenUser,
  5819. bTokenInfo,
  5820. cbBuffer,
  5821. &cbBuffer))
  5822. {
  5823. dwFuncRetStatus = GetLastError();
  5824. goto Exit;
  5825. }
  5826. SidUser = (*(TOKEN_USER*)bTokenInfo).User;
  5827. if(!GetTextualSid( SidUser.Sid, NULL, &cchSidSize))
  5828. {
  5829. dwFuncRetStatus = GetLastError();
  5830. if(dwFuncRetStatus != ERROR_INSUFFICIENT_BUFFER)
  5831. {
  5832. goto Exit;
  5833. }
  5834. dwFuncRetStatus = ERROR_SUCCESS;
  5835. }
  5836. tstrTextualSid = MemAlloc(sizeof(TCHAR) * cchSidSize);
  5837. if(!tstrTextualSid)
  5838. {
  5839. dwFuncRetStatus = ERROR_OUTOFMEMORY;
  5840. goto Exit;
  5841. }
  5842. if(!GetTextualSid( SidUser.Sid, tstrTextualSid, &cchSidSize))
  5843. {
  5844. dwFuncRetStatus = GetLastError();
  5845. goto Exit;
  5846. }
  5847. // allocate an extra char for '\'
  5848. *ptstrCurrentUserKeyPath = MemAlloc( sizeof(TCHAR) * (_tcslen(tstrRegRoot) + cchSidSize + 2));
  5849. if(!*ptstrCurrentUserKeyPath)
  5850. {
  5851. dwFuncRetStatus = ERROR_OUTOFMEMORY;
  5852. goto Exit;
  5853. }
  5854. *ptstrCurrentUserKeyPath[0] = TEXT('\0');
  5855. if(tstrRegRoot[0] != TEXT('\0'))
  5856. {
  5857. _tcscat(*ptstrCurrentUserKeyPath,tstrRegRoot);
  5858. pLast = _tcsrchr(tstrRegRoot,TEXT('\\'));
  5859. if( !( pLast && (*_tcsinc(pLast)) == '\0' ) )
  5860. {
  5861. // the last character is not a backslash, add one...
  5862. _tcscat(*ptstrCurrentUserKeyPath, TEXT("\\"));
  5863. }
  5864. }
  5865. _tcscat(*ptstrCurrentUserKeyPath,tstrTextualSid);
  5866. Exit:
  5867. if(hToken)
  5868. {
  5869. if(!CloseHandle(hToken))
  5870. {
  5871. Error(("CloseHandle failed. ec = 0x%X\n",GetLastError()));
  5872. }
  5873. }
  5874. MemFree(bTokenInfo);
  5875. MemFree(tstrTextualSid);
  5876. return dwFuncRetStatus;
  5877. }
  5878. // ------------------------------------------
  5879. // This function was copied from SDK samples
  5880. // ------------------------------------------
  5881. /*
  5882. This function obtain the textual representation
  5883. of a binary Sid.
  5884. A standardized shorthand notation for SIDs makes it simpler to
  5885. visualize their components:
  5886. S-R-I-S-S...
  5887. In the notation shown above,
  5888. S identifies the series of digits as an SID,
  5889. R is the revision level,
  5890. I is the identifier-authority value,
  5891. S is subauthority value(s).
  5892. An SID could be written in this notation as follows:
  5893. S-1-5-32-544
  5894. In this example,
  5895. the SID has a revision level of 1,
  5896. an identifier-authority value of 5,
  5897. first subauthority value of 32,
  5898. second subauthority value of 544.
  5899. (Note that the above Sid represents the local Administrators group)
  5900. The GetTextualSid() function will convert a binary Sid to a textual
  5901. string.
  5902. The resulting string will take one of two forms. If the
  5903. IdentifierAuthority value is not greater than 2^32, then the SID
  5904. will be in the form:
  5905. S-1-5-21-2127521184-1604012920-1887927527-19009
  5906. ^ ^ ^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^
  5907. | | | | | | |
  5908. +-+-+------+----------+----------+--------+--- Decimal
  5909. Otherwise it will take the form:
  5910. S-1-0x206C277C6666-21-2127521184-1604012920-1887927527-19009
  5911. ^ ^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^
  5912. | | | | | | |
  5913. | Hexidecimal | | | | |
  5914. +----------------+------+----------+----------+--------+--- Decimal
  5915. If the function succeeds, the return value is TRUE.
  5916. If the function fails, the return value is FALSE. To get extended
  5917. error information, call the Win32 API GetLastError().
  5918. */
  5919. static BOOL
  5920. GetTextualSid( const PSID pSid, // binary Sid
  5921. LPTSTR tstrTextualSid, // buffer for Textual representaion of Sid
  5922. LPDWORD cchSidSize // required/provided TextualSid buffersize
  5923. )
  5924. {
  5925. PSID_IDENTIFIER_AUTHORITY pSia;
  5926. DWORD dwSubAuthorities;
  5927. DWORD cchSidCopy;
  5928. DWORD dwCounter;
  5929. //
  5930. // test if Sid passed in is valid
  5931. //
  5932. if(!IsValidSid(pSid))
  5933. {
  5934. return FALSE;
  5935. }
  5936. SetLastError(0);
  5937. // obtain SidIdentifierAuthority
  5938. //
  5939. pSia = GetSidIdentifierAuthority(pSid);
  5940. if(GetLastError())
  5941. {
  5942. return FALSE;
  5943. }
  5944. // obtain sidsubauthority count
  5945. //
  5946. dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
  5947. if(GetLastError())
  5948. {
  5949. return FALSE;
  5950. }
  5951. //
  5952. // compute approximate buffer length
  5953. // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
  5954. //
  5955. cchSidCopy = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
  5956. //
  5957. // check provided buffer length.
  5958. // If not large enough, indicate proper size and setlasterror
  5959. //
  5960. if(*cchSidSize < cchSidCopy)
  5961. {
  5962. *cchSidSize = cchSidCopy;
  5963. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  5964. return FALSE;
  5965. }
  5966. //
  5967. // prepare S-SID_REVISION-
  5968. //
  5969. cchSidCopy = wsprintf(tstrTextualSid, TEXT("S-%lu-"), SID_REVISION);
  5970. //
  5971. // prepare SidIdentifierAuthority
  5972. //
  5973. if ( (pSia->Value[0] != 0) || (pSia->Value[1] != 0) )
  5974. {
  5975. cchSidCopy += wsprintf(tstrTextualSid + cchSidCopy,
  5976. TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
  5977. (USHORT)pSia->Value[0],
  5978. (USHORT)pSia->Value[1],
  5979. (USHORT)pSia->Value[2],
  5980. (USHORT)pSia->Value[3],
  5981. (USHORT)pSia->Value[4],
  5982. (USHORT)pSia->Value[5]);
  5983. }
  5984. else
  5985. {
  5986. cchSidCopy += wsprintf(tstrTextualSid + cchSidCopy,
  5987. TEXT("%lu"),
  5988. (ULONG)(pSia->Value[5]) +
  5989. (ULONG)(pSia->Value[4] << 8) +
  5990. (ULONG)(pSia->Value[3] << 16) +
  5991. (ULONG)(pSia->Value[2] << 24));
  5992. }
  5993. //
  5994. // loop through SidSubAuthorities
  5995. //
  5996. for(dwCounter = 0 ; dwCounter < dwSubAuthorities ; dwCounter++)
  5997. {
  5998. cchSidCopy += wsprintf(tstrTextualSid + cchSidCopy, TEXT("-%lu"),
  5999. *GetSidSubAuthority(pSid, dwCounter) );
  6000. }
  6001. //
  6002. // tell the caller how many chars we provided, not including NULL
  6003. //
  6004. *cchSidSize = cchSidCopy;
  6005. return TRUE;
  6006. }
  6007. /*
  6008. Function returns TRUE if the current runing OS is NT platform.
  6009. If function returned false and GetLastError() returned an error value
  6010. the call GetVersionEx() failed.
  6011. */
  6012. static BOOL
  6013. IsNTSystemVersion()
  6014. {
  6015. OSVERSIONINFO osvi;
  6016. ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
  6017. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  6018. if (! GetVersionEx( &osvi))
  6019. {
  6020. return FALSE;
  6021. }
  6022. if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
  6023. {
  6024. return TRUE;
  6025. }
  6026. SetLastError(0);
  6027. return FALSE;
  6028. }
  6029. /*++
  6030. Routine Description:
  6031. Returns the version information for a DLL exporting "DllGetVersion".
  6032. DllGetVersion is exported by the shell DLLs (specifically COMCTRL32.DLL).
  6033. Arguments:
  6034. lpszDllName - The name of the DLL to get version information from.
  6035. Return Value:
  6036. The version is retuned as DWORD where:
  6037. HIWORD ( version DWORD ) = Major Version
  6038. LOWORD ( version DWORD ) = Minor Version
  6039. Use the macro PACKVERSION to comapre versions.
  6040. If the DLL does not export "DllGetVersion" the function returns 0.
  6041. --*/
  6042. DWORD GetDllVersion(LPCTSTR lpszDllName)
  6043. {
  6044. HINSTANCE hinstDll;
  6045. DWORD dwVersion = 0;
  6046. hinstDll = LoadLibrary(lpszDllName);
  6047. if(hinstDll)
  6048. {
  6049. DLLGETVERSIONPROC pDllGetVersion;
  6050. pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
  6051. // Because some DLLs may not implement this function, you
  6052. // must test for it explicitly. Depending on the particular
  6053. // DLL, the lack of a DllGetVersion function may
  6054. // be a useful indicator of the version.
  6055. if(pDllGetVersion)
  6056. {
  6057. DLLVERSIONINFO dvi;
  6058. HRESULT hr;
  6059. ZeroMemory(&dvi, sizeof(dvi));
  6060. dvi.cbSize = sizeof(dvi);
  6061. hr = (*pDllGetVersion)(&dvi);
  6062. if(SUCCEEDED(hr))
  6063. {
  6064. dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
  6065. }
  6066. }
  6067. FreeLibrary(hinstDll);
  6068. }
  6069. return dwVersion;
  6070. }
  6071. BOOL
  6072. DisplayFaxPreview(
  6073. HWND hWnd,
  6074. PWIZARDUSERMEM pWizardUserMem,
  6075. LPTSTR lptstrPreviewFile
  6076. )
  6077. /*++
  6078. Routine Description:
  6079. Create a temporary TIFF file of the whole job (cover page + body), pop the registered
  6080. TIFF viewer and ask the user whether to continue sending the fax.
  6081. TODO: Once we have our own TIFF viewer, we can use only the temporary file created by
  6082. the driver so far. The security issue of executing an unknown TIFF viewer on a
  6083. different copy of the preview TIFF won't exist anymore...
  6084. Arguments:
  6085. hWnd - Parent window handle.
  6086. pWizardUserMem - Points to the user mode memory structure.
  6087. lptstrPreviewFile - Full path to the file to be previewed.
  6088. Return Value:
  6089. TRUE to continue printing
  6090. FALSE to cancel the job
  6091. --*/
  6092. {
  6093. HDC hdc = NULL;
  6094. BOOL bRet = TRUE;
  6095. BOOL bPrintedCoverPage = FALSE;
  6096. short Orientation = DMORIENT_PORTRAIT;
  6097. DWORD dwSize;
  6098. HANDLE hFile = INVALID_HANDLE_VALUE;
  6099. DWORD ec = ERROR_SUCCESS;
  6100. COVERPAGEFIELDS cpFields = {0};
  6101. Assert(pWizardUserMem);
  6102. Assert(lptstrPreviewFile);
  6103. Assert(lptstrPreviewFile[0]);
  6104. //
  6105. // Get the body TIFF file size
  6106. //
  6107. if (INVALID_HANDLE_VALUE == (hFile = CreateFile(
  6108. lptstrPreviewFile,
  6109. GENERIC_READ,
  6110. 0,
  6111. NULL,
  6112. OPEN_EXISTING,
  6113. FILE_ATTRIBUTE_NORMAL,
  6114. NULL)))
  6115. {
  6116. ec = GetLastError();
  6117. Error(("Couldn't open preview file to get the file size. Error: %d\n", ec));
  6118. ErrorMessageBox(hWnd,IDS_PREVIEW_FAILURE, MB_ICONERROR);
  6119. goto Err_Exit;
  6120. }
  6121. dwSize = GetFileSize(hFile, NULL);
  6122. if (0xFFFFFFFF == dwSize)
  6123. {
  6124. ec = GetLastError();
  6125. Error(("Failed getting file size (ec: %ld).\n",ec));
  6126. ErrorMessageBox(hWnd,IDS_PREVIEW_FAILURE, MB_ICONERROR);
  6127. goto Err_Exit;
  6128. }
  6129. if (!CloseHandle(hFile))
  6130. {
  6131. Error(("CloseHandle() failed: (ec: %ld).\n", GetLastError()));
  6132. Assert(INVALID_HANDLE_VALUE == hFile); // assert false
  6133. }
  6134. hFile = INVALID_HANDLE_VALUE;
  6135. //
  6136. // Create a temporary file for the complete preview TIFF - This file will contain the
  6137. // rendered cover page (if used) and the document body
  6138. //
  6139. if (!GenerateUniqueFileNameWithPrefix(
  6140. TRUE, // Use process id
  6141. NULL, // Create in the system temporary directory
  6142. WIZARD_PREVIEW_TIFF_PREFIX, // Prefix
  6143. NULL, // Use FAX_TIF_FILE_EXT as extension
  6144. pWizardUserMem->szTempPreviewTiff,
  6145. MAX_PATH))
  6146. {
  6147. ec = GetLastError();
  6148. Error(("Failed creating temporary cover page TIFF file (ec: %ld)", ec));
  6149. ErrorMessageBox(hWnd,IDS_PREVIEW_FAILURE, MB_ICONERROR);
  6150. pWizardUserMem->szTempPreviewTiff[0] = TEXT('\0');
  6151. goto Err_Exit;
  6152. }
  6153. //
  6154. // Change the default orientation if needed
  6155. //
  6156. if (pWizardUserMem->cpOrientation == DMORIENT_LANDSCAPE)
  6157. {
  6158. Orientation = DMORIENT_LANDSCAPE;
  6159. }
  6160. //
  6161. // If we have a cover page merge it with the body
  6162. //
  6163. if (pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName &&
  6164. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName[0])
  6165. {
  6166. FillCoverPageFields(pWizardUserMem, &cpFields); // does not allocate any memory and can not fail
  6167. ec = PrintCoverPageToFile(
  6168. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName,
  6169. pWizardUserMem->szTempPreviewTiff,
  6170. pWizardUserMem->lptstrPrinterName,
  6171. Orientation,
  6172. 0, // Default resolution
  6173. &cpFields);
  6174. if (ERROR_SUCCESS != ec)
  6175. {
  6176. Error(("PrintCoverPageToFile() failed (ec: %ld)", ec));
  6177. ErrorMessageBox(hWnd,IDS_PREVIEW_FAILURE, MB_ICONERROR);
  6178. goto Err_Exit;
  6179. }
  6180. //
  6181. // Check if we have a non-empty body TIFF file (this happens when an empty document
  6182. // is printed - such as our "Send cover page" utility).
  6183. //
  6184. if (dwSize)
  6185. {
  6186. //
  6187. // Merge the document body TIFF to our cover page TIFF
  6188. //
  6189. if (!MergeTiffFiles(pWizardUserMem->szTempPreviewTiff, lptstrPreviewFile))
  6190. {
  6191. ec = GetLastError();
  6192. Error(("Failed merging cover page and preview TIFF files (ec: %ld).\n", ec));
  6193. ErrorMessageBox(hWnd,IDS_PREVIEW_FAILURE, MB_ICONERROR);
  6194. goto Err_Exit;
  6195. }
  6196. }
  6197. }
  6198. else
  6199. {
  6200. //
  6201. // No cover page was supplied
  6202. //
  6203. if (!dwSize)
  6204. {
  6205. //
  6206. // No cover page was included and we recieved an empty preview file !? In this
  6207. // case there is actually no preview to display so just exit.
  6208. // Note: This can happen when an empty notepad document is printed with no
  6209. // cover page.
  6210. //
  6211. Warning(("Empty preview file recieved with no cover page.\n"));
  6212. ErrorMessageBox(hWnd,IDS_PREVIEW_NOTHING_TO_PREVIEW, MB_ICONERROR);
  6213. goto Err_Exit;
  6214. }
  6215. //
  6216. // Just copy the driver body file to our temporary preview file
  6217. //
  6218. if (!CopyFile(lptstrPreviewFile, pWizardUserMem->szTempPreviewTiff, FALSE))
  6219. {
  6220. ec = GetLastError();
  6221. Error(("Failed copying TIFF file. Error: %d.\n", ec));
  6222. ErrorMessageBox(hWnd,IDS_PREVIEW_FAILURE, MB_ICONERROR);
  6223. goto Err_Exit;
  6224. }
  6225. }
  6226. //
  6227. // Pop the registered TIFF viewer
  6228. //
  6229. ec = ViewFile (pWizardUserMem->szTempPreviewTiff);
  6230. if (ERROR_SUCCESS != ec)
  6231. {
  6232. Error(("ShellExecuteEx failed\n"));
  6233. if(ERROR_NO_ASSOCIATION == ec)
  6234. {
  6235. ErrorMessageBox(hWnd, IDS_NO_TIF_ASSOCIATION, MB_ICONERROR);
  6236. }
  6237. else
  6238. {
  6239. ErrorMessageBox(hWnd, IDS_PREVIEW_FAILURE, MB_ICONERROR);
  6240. }
  6241. goto Err_Exit;
  6242. }
  6243. goto Exit;
  6244. Err_Exit:
  6245. if (pWizardUserMem->szTempPreviewTiff[0] != TEXT('\0'))
  6246. {
  6247. //
  6248. // Delete the file (it is possible that the function failed with the file already created)
  6249. //
  6250. if(!DeleteFile(pWizardUserMem->szTempPreviewTiff))
  6251. {
  6252. Error(("DeleteFile failed. ec = 0x%X\n",GetLastError()));
  6253. }
  6254. //
  6255. // Ignore errors since the file might not be there
  6256. //
  6257. pWizardUserMem->szTempPreviewTiff[0]=TEXT('\0');
  6258. }
  6259. bRet = FALSE;
  6260. Exit:
  6261. if (INVALID_HANDLE_VALUE != hFile)
  6262. {
  6263. if (!CloseHandle(hFile))
  6264. {
  6265. Error(("CloseHandle() failed: (ec: %ld).\n", GetLastError()));
  6266. Assert(INVALID_HANDLE_VALUE == hFile); // assert false
  6267. }
  6268. }
  6269. return bRet;
  6270. } // DisplayFaxPreview
  6271. BOOL
  6272. FillCoverPageFields(
  6273. IN PWIZARDUSERMEM pWizardUserMem,
  6274. OUT PCOVERPAGEFIELDS pCPFields)
  6275. /*++
  6276. Author:
  6277. Ronen Barenboim 25-March-2000
  6278. Routine Description:
  6279. Fills a COVERPAGEFIELDS structure from the content of a WIZARDUSERMEM structure.
  6280. Used to prepare a COVERPAGEFIELDS structure for cover page rendering before cover page
  6281. preview.
  6282. Arguments:
  6283. [IN] pWizardUserMem - Pointer to a WIZARDUSERMEM that holds the information to be extracted.
  6284. [OUT] pCPFields - Pointer to a COVERPAGEFIELDS structure that gets filled with
  6285. the information from WIZARDUSERMEM.
  6286. Return Value:
  6287. BOOL
  6288. Comments:
  6289. The function DOES NOT ALLOCATE any memory. It places in COVERPAGEFIELDS pointers to already
  6290. allocated memory in WIZARDUSERMEM.
  6291. --*/
  6292. {
  6293. static TCHAR szTime[256];
  6294. static TCHAR szNumberOfPages[10] = {0};
  6295. DWORD dwPageCount;
  6296. int iRet;
  6297. Assert(pWizardUserMem);
  6298. Assert(pCPFields);
  6299. memset(pCPFields,0,sizeof(COVERPAGEFIELDS));
  6300. pCPFields->ThisStructSize = sizeof(COVERPAGEFIELDS);
  6301. //
  6302. // Recipient stuff... (we use the first recipient)
  6303. //
  6304. pCPFields->RecName = pWizardUserMem->pRecipients->pName;
  6305. pCPFields->RecFaxNumber = pWizardUserMem->pRecipients->pAddress;
  6306. //
  6307. // Senders stuff...
  6308. //
  6309. pCPFields->SdrName = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrName;
  6310. pCPFields->SdrFaxNumber = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrFaxNumber;
  6311. pCPFields->SdrCompany = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrCompany;
  6312. pCPFields->SdrAddress = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrStreetAddress;
  6313. pCPFields->SdrTitle = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrTitle;
  6314. pCPFields->SdrDepartment = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrDepartment;
  6315. pCPFields->SdrOfficeLocation = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrOfficeLocation;
  6316. pCPFields->SdrHomePhone = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrHomePhone;
  6317. pCPFields->SdrOfficePhone = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrOfficePhone;
  6318. pCPFields->SdrEmail = pWizardUserMem->lpFaxSendWizardData->lpSenderInfo->lptstrEmail;
  6319. //
  6320. // Misc Stuff...
  6321. //
  6322. pCPFields->Note = pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrNote;
  6323. pCPFields->Subject = pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrSubject;
  6324. if(!GetY2KCompliantDate(LOCALE_USER_DEFAULT,
  6325. 0,
  6326. NULL,
  6327. szTime,
  6328. ARR_SIZE(szTime)))
  6329. {
  6330. Error(("GetY2KCompliantDate: failed. ec = 0X%x\n",GetLastError()));
  6331. return FALSE;
  6332. }
  6333. _tcscat(szTime, TEXT(" "));
  6334. if(!FaxTimeFormat(LOCALE_USER_DEFAULT,
  6335. 0,
  6336. NULL,
  6337. NULL,
  6338. _tcsninc(szTime, _tcslen(szTime)),
  6339. ARR_SIZE(szTime) - _tcslen(szTime)))
  6340. {
  6341. Error(("FaxTimeFormat: failed. ec = 0X%x\n",GetLastError()));
  6342. return FALSE;
  6343. }
  6344. pCPFields->TimeSent = szTime;
  6345. dwPageCount = pWizardUserMem->lpInitialData->dwPageCount;
  6346. if (pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName &&
  6347. pWizardUserMem->lpFaxSendWizardData->lpCoverPageInfo->lptstrCoverPageFileName[0])
  6348. {
  6349. dwPageCount++;
  6350. }
  6351. iRet= _sntprintf( szNumberOfPages,
  6352. ARR_SIZE(szNumberOfPages) -1,
  6353. TEXT("%d"),
  6354. dwPageCount);
  6355. Assert(iRet>0);
  6356. //
  6357. // make sure it is allways null terminated
  6358. //
  6359. szNumberOfPages[ARR_SIZE(szNumberOfPages) - 1] = TEXT('\0');
  6360. pCPFields->NumberOfPages = szNumberOfPages;
  6361. return TRUE;
  6362. }
  6363. BOOL
  6364. ErrorMessageBox(
  6365. HWND hwndParent,
  6366. UINT nErrorMessage,
  6367. UINT uIcon
  6368. )
  6369. {
  6370. static TCHAR szMessage[MAX_MESSAGE_LEN];
  6371. static TCHAR szTitle[MAX_MESSAGE_LEN];
  6372. Assert(nErrorMessage);
  6373. if (!LoadString(g_hResource, nErrorMessage, szMessage, MAX_MESSAGE_LEN))
  6374. {
  6375. Error(("Failed to load message string id %ld. (ec: %ld)", nErrorMessage, GetLastError()));
  6376. return FALSE;
  6377. }
  6378. if (!LoadString(g_hResource, IDS_WIZARD_TITLE, szTitle, MAX_MESSAGE_LEN))
  6379. {
  6380. Error(("Failed to load IDS_WIZARD_TITLE. (ec: %ld)", GetLastError()));
  6381. return FALSE;
  6382. }
  6383. AlignedMessageBox(hwndParent, szMessage, szTitle, MB_OK | uIcon);
  6384. return TRUE;
  6385. }