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.

6105 lines
201 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. print.c
  5. Abstract:
  6. This module contains the job
  7. specific WINFAX API functions.
  8. Author:
  9. Wesley Witt (wesw) 29-Nov-1996
  10. Revision History:
  11. 4-Oct-1999 Danl Fix GetFaxPrinterName to retrieve the proper printer.
  12. Fix CreateFinalTiffFile to work with GetFaxPrinterName
  13. 28-Oct-1999 Danl Fix GetFaxPrinterName to return proper name for a client
  14. installed on a serer machine.
  15. --*/
  16. #include "faxapi.h"
  17. #include "faxreg.h"
  18. #pragma hdrstop
  19. #include <mbstring.h>
  20. #define STRSAFE_NO_DEPRECATE
  21. #include <strsafe.h>
  22. #define InchesToCM(_x) (((_x) * 254L + 50) / 100)
  23. #define CMToInches(_x) (((_x) * 100L + 127) / 254)
  24. #define LEFT_MARGIN 1 // ---|
  25. #define RIGHT_MARGIN 1 // |
  26. #define TOP_MARGIN 1 // |---> in inches
  27. #define BOTTOM_MARGIN 1 // ---|
  28. static BOOL CopyJobParamEx(PFAX_JOB_PARAM_EX lpDst,LPCFAX_JOB_PARAM_EX lpcSrc);
  29. static void FreeJobParamEx(PFAX_JOB_PARAM_EX lpJobParamEx,BOOL bDestroy);
  30. static BOOL
  31. FaxGetPersonalProfileInfoW (
  32. IN HANDLE hFaxHandle,
  33. IN DWORDLONG dwlMessageId,
  34. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  35. IN FAX_ENUM_PERSONAL_PROF_TYPES ProfType,
  36. OUT PFAX_PERSONAL_PROFILEW *lppPersonalProfile
  37. );
  38. static BOOL
  39. FaxGetPersonalProfileInfoA (
  40. IN HANDLE hFaxHandle,
  41. IN DWORDLONG dwlMessageId,
  42. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  43. IN FAX_ENUM_PERSONAL_PROF_TYPES ProfType,
  44. OUT PFAX_PERSONAL_PROFILEA *lppPersonalProfile
  45. );
  46. static
  47. BOOL
  48. CopyFileToServerQueueA (
  49. const HANDLE IN hFaxHandle,
  50. const HANDLE IN hLocalFile,
  51. LPCSTR IN lpcstrLocalFileExt,
  52. LPSTR OUT lpstrServerFileName, // Name + extension of file created on the server
  53. DWORD IN cchServerFileName
  54. );
  55. static
  56. BOOL
  57. CopyFileToServerQueueW (
  58. const HANDLE IN hFaxHandle,
  59. const HANDLE IN hLocaFile,
  60. LPCWSTR IN lpcwstrLocalFileExt,
  61. LPWSTR OUT lpwstrServerFileName, // Name + extension of file created on the server
  62. DWORD IN cchServerFileName
  63. );
  64. #ifdef UNICODE
  65. #define CopyFileToServerQueue CopyFileToServerQueueW
  66. #else
  67. #define CopyFileToServerQueue CopyFileToServerQueueA
  68. #endif // #ifdef UNICODE
  69. DWORD WINAPI FAX_SendDocumentEx_A
  70. (
  71. IN handle_t hBinding,
  72. IN LPCSTR lpcstrFileName,
  73. IN LPCFAX_COVERPAGE_INFO_EXA lpcCoverPageInfo,
  74. IN LPCFAX_PERSONAL_PROFILEA lpcSenderProfile,
  75. IN DWORD dwNumRecipients,
  76. IN LPCFAX_PERSONAL_PROFILEA lpcRecipientList,
  77. IN LPCFAX_JOB_PARAM_EXA lpcJobParams,
  78. OUT LPDWORD lpdwJobId,
  79. OUT PDWORDLONG lpdwlMessageId,
  80. OUT PDWORDLONG lpdwlRecipientMessageIds
  81. );
  82. BOOL WINAPI FaxSendDocumentEx2A
  83. (
  84. IN HANDLE hFaxHandle,
  85. IN LPCSTR lpctstrFileName,
  86. IN LPCFAX_COVERPAGE_INFO_EXA lpcCoverPageInfo,
  87. IN LPCFAX_PERSONAL_PROFILEA lpcSenderProfile,
  88. IN DWORD dwNumRecipients,
  89. IN LPCFAX_PERSONAL_PROFILEA lpcRecipientList,
  90. IN LPCFAX_JOB_PARAM_EXA lpJobParams,
  91. OUT LPDWORD lpdwJobId,
  92. OUT PDWORDLONG lpdwlMessageId,
  93. OUT PDWORDLONG lpdwlRecipientMessageIds
  94. );
  95. BOOL WINAPI FaxSendDocumentEx2W
  96. (
  97. IN HANDLE hFaxHandle,
  98. IN LPCWSTR lpctstrFileName,
  99. IN LPCFAX_COVERPAGE_INFO_EXW lpcCoverPageInfo,
  100. IN LPCFAX_PERSONAL_PROFILEW lpcSenderProfile,
  101. IN DWORD dwNumRecipients,
  102. IN LPCFAX_PERSONAL_PROFILEW lpcRecipientList,
  103. IN LPCFAX_JOB_PARAM_EXW lpJobParams,
  104. OUT LPDWORD lpdwJobId,
  105. OUT PDWORDLONG lpdwlMessageId,
  106. OUT PDWORDLONG lpdwlRecipientMessageIds
  107. );
  108. #ifdef UNICODE
  109. #define FaxSendDocumentEx2 FaxSendDocumentEx2W
  110. #else
  111. #define FaxSendDocumentEx2 FaxSendDocumentEx2A
  112. #endif // !UNICODE
  113. BOOL WINAPI FaxSendDocumentExW
  114. (
  115. IN HANDLE hFaxHandle,
  116. IN LPCWSTR lpctstrFileName,
  117. IN LPCFAX_COVERPAGE_INFO_EXW lpcCoverPageInfo,
  118. IN LPCFAX_PERSONAL_PROFILEW lpcSenderProfile,
  119. IN DWORD dwNumRecipients,
  120. IN LPCFAX_PERSONAL_PROFILEW lpcRecipientList,
  121. IN LPCFAX_JOB_PARAM_EXW lpcJobParams,
  122. OUT PDWORDLONG lpdwlMessageId,
  123. OUT PDWORDLONG lpdwlRecipientMessageIds
  124. )
  125. {
  126. return FaxSendDocumentEx2W (hFaxHandle,
  127. lpctstrFileName,
  128. lpcCoverPageInfo,
  129. lpcSenderProfile,
  130. dwNumRecipients,
  131. lpcRecipientList,
  132. lpcJobParams,
  133. NULL,
  134. lpdwlMessageId,
  135. lpdwlRecipientMessageIds
  136. );
  137. }
  138. BOOL WINAPI FaxSendDocumentExA
  139. (
  140. IN HANDLE hFaxHandle,
  141. IN LPCSTR lpctstrFileName,
  142. IN LPCFAX_COVERPAGE_INFO_EXA lpcCoverPageInfo,
  143. IN LPCFAX_PERSONAL_PROFILEA lpcSenderProfile,
  144. IN DWORD dwNumRecipients,
  145. IN LPCFAX_PERSONAL_PROFILEA lpcRecipientList,
  146. IN LPCFAX_JOB_PARAM_EXA lpcJobParams,
  147. OUT PDWORDLONG lpdwlMessageId,
  148. OUT PDWORDLONG lpdwlRecipientMessageIds
  149. )
  150. {
  151. return FaxSendDocumentEx2A (hFaxHandle,
  152. lpctstrFileName,
  153. lpcCoverPageInfo,
  154. lpcSenderProfile,
  155. dwNumRecipients,
  156. lpcRecipientList,
  157. lpcJobParams,
  158. NULL,
  159. lpdwlMessageId,
  160. lpdwlRecipientMessageIds
  161. );
  162. }
  163. /*
  164. - GetServerNameFromPrinterInfo
  165. -
  166. * Purpose:
  167. * Get the Server name, given a PRINTER_INFO_2 structure
  168. *
  169. * Arguments:
  170. * [in] ppi2 - Address of PRINTER_INFO_2 structure
  171. * [out] lpptszServerName - Address of string pointer for returned name.
  172. *
  173. * Returns:
  174. * BOOL - TRUE: sucess , FALSE: failure.
  175. *
  176. * Remarks:
  177. * This inline function retrieves the server from a printer info structure
  178. * in the appropriate way for win9x and NT.
  179. */
  180. _inline BOOL
  181. GetServerNameFromPrinterInfo(PPRINTER_INFO_2 ppi2,LPTSTR *lpptszServerName)
  182. {
  183. if (!ppi2)
  184. {
  185. return FALSE;
  186. }
  187. #ifndef WIN95
  188. *lpptszServerName = NULL;
  189. if (ppi2->pServerName)
  190. {
  191. if (!(*lpptszServerName = StringDup(ppi2->pServerName + 2)))
  192. {
  193. return FALSE;
  194. }
  195. }
  196. return TRUE;
  197. #else //WIN95
  198. if (!(ppi2->pPortName))
  199. {
  200. return FALSE;
  201. }
  202. if (!(*lpptszServerName = StringDup(ppi2->pPortName + 2)))
  203. {
  204. return FALSE;
  205. }
  206. //
  207. // Formatted: \\Server\port
  208. //
  209. _tcstok(*lpptszServerName,TEXT("\\"));
  210. #endif //WIN95
  211. return TRUE;
  212. }
  213. BOOL
  214. LocalSystemTimeToSystemTime(
  215. const SYSTEMTIME * LocalSystemTime,
  216. LPSYSTEMTIME SystemTime
  217. )
  218. {
  219. FILETIME LocalFileTime;
  220. FILETIME UtcFileTime;
  221. DEBUG_FUNCTION_NAME(TEXT("LocalSystemTimeToSystemTime"));
  222. if (!SystemTimeToFileTime( LocalSystemTime, &LocalFileTime )) {
  223. DebugPrintEx(
  224. DEBUG_ERR,
  225. TEXT("SystemTimeToFileTime failed. (ec: %ld)"),
  226. GetLastError());
  227. return FALSE;
  228. }
  229. if (!LocalFileTimeToFileTime( &LocalFileTime, &UtcFileTime )) {
  230. DebugPrintEx(
  231. DEBUG_ERR,
  232. TEXT("LocalFileTimeToFileTime failed. (ec: %ld)"),
  233. GetLastError());
  234. return FALSE;
  235. }
  236. if (!FileTimeToSystemTime( &UtcFileTime, SystemTime )) {
  237. DebugPrintEx(
  238. DEBUG_ERR,
  239. TEXT("FileTimeToSystemTime failed. (ec: %ld)"),
  240. GetLastError());
  241. return FALSE;
  242. }
  243. return TRUE;
  244. }
  245. /*
  246. - GetFaxPrinterName
  247. -
  248. * Purpose:
  249. * Get The Name of a printer associated with the fax handle.
  250. *
  251. * Arguments:
  252. * [in] hFax - handle to a fax server (obtained via FaxConnectFaxServer).
  253. * If this parameter is NULL the name of the local fax printer
  254. * is retrieved
  255. *
  256. * Returns:
  257. * LPTSTR - name of fax server associated with the fax handle. NULL on
  258. * failure
  259. *
  260. * Remarks:
  261. * This function utilized GetFaxServerName macro which extracts the server
  262. * name out of its handle.
  263. */
  264. #define GetFaxServerName(hFax) FH_DATA(hFax)->MachineName
  265. LPTSTR
  266. GetFaxPrinterName(
  267. HANDLE hFax
  268. )
  269. {
  270. PPRINTER_INFO_2 ppi2;
  271. DWORD dwi,dwCount;
  272. LPTSTR lptszServerName = NULL,
  273. lptszFaxServerName = NULL,
  274. lptszFaxPrinterName = NULL;
  275. //
  276. // Get a list of all printers
  277. //
  278. ppi2 = (PPRINTER_INFO_2) MyEnumPrinters( NULL, 2, &dwCount, 0 );
  279. if (ppi2 != NULL)
  280. {
  281. //
  282. // If a non NULL handle is given get the server name associated with it.
  283. //
  284. if (hFax != NULL)
  285. {
  286. lptszFaxServerName = GetFaxServerName(hFax);
  287. if (lptszFaxServerName != NULL)
  288. {
  289. #ifndef WIN95
  290. TCHAR tszComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  291. DWORD cbCompName = ARR_SIZE(tszComputerName);
  292. if (GetComputerName(tszComputerName,&cbCompName))
  293. {
  294. //
  295. // Check to see if the Fax Server is local.
  296. //
  297. if(_tcsicmp(tszComputerName,lptszFaxServerName) == 0)
  298. {
  299. lptszFaxServerName = NULL;
  300. }
  301. }
  302. else
  303. {
  304. //
  305. // Last error has bee set by GetComputerName
  306. //
  307. return NULL;
  308. }
  309. #endif //WIN95
  310. }
  311. }
  312. for (dwi=0; dwi< dwCount; dwi++)
  313. {
  314. //
  315. // Check to see if this one is a fax printer.
  316. //
  317. if (_tcscmp(ppi2[dwi].pDriverName, FAX_DRIVER_NAME ) == 0)
  318. {
  319. if (!GetServerNameFromPrinterInfo(&ppi2[dwi],&lptszServerName))
  320. {
  321. //
  322. // Note: the above function allocates storage for lptszServerName
  323. //
  324. continue;
  325. }
  326. //
  327. // Check to see if the printer's server is the one associated with
  328. // the handle we have.
  329. //
  330. if ((lptszFaxServerName == lptszServerName) ||
  331. ((lptszFaxServerName && lptszServerName) &&
  332. _tcsicmp( lptszFaxServerName, lptszServerName) == 0))
  333. {
  334. //
  335. // We have found our printer.
  336. //
  337. lptszFaxPrinterName = (LPTSTR) StringDup( ppi2[dwi].pPrinterName );
  338. MemFree(lptszServerName);
  339. break;
  340. }
  341. MemFree(lptszServerName);
  342. }
  343. }
  344. MemFree( ppi2 );
  345. }
  346. //
  347. // Set Last Error if we failed to find a Printer
  348. //
  349. if (!lptszFaxPrinterName)
  350. {
  351. SetLastError(ERROR_OBJECT_NOT_FOUND);
  352. }
  353. return lptszFaxPrinterName;
  354. }
  355. BOOL
  356. CreateFinalTiffFile(
  357. IN LPTSTR FileName,
  358. OUT LPTSTR FinalTiffFile,
  359. IN DWORD cchFinalTiffFile,
  360. IN HANDLE hFax
  361. )
  362. /*++
  363. Routine name : CreateFinalTiffFile
  364. Routine description:
  365. Creates a valid TIFF file for transmission from an arbitrary attachmnet file.
  366. Author:
  367. Eran Yariv (EranY), Feb, 2002
  368. Arguments:
  369. FileName [in] The file name of the arbitrary attachmnet file.
  370. FinalTiffFile [out] A buffer which will hold, upon success, the name of the valid result TIFF file
  371. cchFinalTiffFile [in] The size, in TCHARs, of FinalTiffFile
  372. hFax [in] The connection handle to the fax server
  373. Return Value:
  374. TRUE on success.
  375. FALSE on failure (sets last error)
  376. --*/
  377. {
  378. TCHAR TempPath[MAX_PATH];
  379. TCHAR FullPath[MAX_PATH];
  380. TCHAR TempFile[MAX_PATH];
  381. TCHAR TiffFile[MAX_PATH];
  382. LPTSTR FaxPrinter = NULL;
  383. FAX_PRINT_INFO PrintInfo;
  384. DWORD TmpFaxJobId;
  385. FAX_CONTEXT_INFO ContextInfo;
  386. LPTSTR p;
  387. DWORD Flags = 0;
  388. BOOL Rslt;
  389. DWORD ec = ERROR_SUCCESS; // LastError for this function.
  390. DWORD dwFileSize = 0;
  391. HRESULT hr;
  392. DEBUG_FUNCTION_NAME(TEXT("CreateFinalTiffFile"));
  393. //
  394. // make sure that the tiff file passed in is a valid tiff file
  395. //
  396. if (!GetTempPath( sizeof(TempPath)/sizeof(TCHAR), TempPath ))
  397. {
  398. ec=GetLastError();
  399. goto Error;
  400. }
  401. if (GetTempFileName( TempPath, _T("fax"), 0, TempFile ) == 0 )
  402. {
  403. ec=GetLastError();
  404. goto Error;
  405. }
  406. DWORD nNeededSize = GetFullPathName( TempFile, sizeof(FullPath)/sizeof(TCHAR), FullPath, &p );
  407. if ( nNeededSize == 0 ||
  408. nNeededSize > sizeof(FullPath)/sizeof(TCHAR) )
  409. {
  410. //
  411. // GetTempFileName created 0 byte file, so we need to delete it before exit
  412. //
  413. DeleteFile( TempPath );
  414. if (nNeededSize == 0)
  415. {
  416. ec=GetLastError();
  417. }
  418. else
  419. {
  420. ec=ERROR_BUFFER_OVERFLOW;
  421. }
  422. goto Error;
  423. }
  424. if (!ConvertTiffFileToValidFaxFormat( FileName, FullPath, &Flags ))
  425. {
  426. if ((Flags & TIFFCF_NOT_TIFF_FILE) == 0)
  427. {
  428. Flags = TIFFCF_NOT_TIFF_FILE;
  429. }
  430. }
  431. if (Flags & TIFFCF_NOT_TIFF_FILE)
  432. {
  433. //
  434. // try to output the source file into a tiff file,
  435. // by printing to the fax printer in "file" mode
  436. //
  437. HANDLE hFile = INVALID_HANDLE_VALUE;
  438. FaxPrinter = GetFaxPrinterName(hFax);
  439. if (FaxPrinter == NULL)
  440. {
  441. ec=GetLastError();
  442. DeleteFile( FullPath );
  443. goto Error;
  444. }
  445. if (!PrintRandomDocument( FaxPrinter, FileName, FullPath ))
  446. {
  447. ec=GetLastError();
  448. DeleteFile( FullPath );
  449. goto Error;
  450. }
  451. //
  452. // Try to open file
  453. // to check its size
  454. //
  455. hFile = SafeCreateFile(
  456. FullPath,
  457. GENERIC_READ,
  458. FILE_SHARE_READ,
  459. NULL,
  460. OPEN_EXISTING,
  461. FILE_ATTRIBUTE_NORMAL,
  462. NULL);
  463. if (INVALID_HANDLE_VALUE == hFile)
  464. {
  465. ec = GetLastError();
  466. DeleteFile( FullPath );
  467. DebugPrintEx(DEBUG_ERR, _T("Opening %s for read failed (ec: %ld)"), FullPath, ec);
  468. goto Error;
  469. }
  470. //
  471. // Get the File Size
  472. //
  473. dwFileSize = GetFileSize(hFile, NULL);
  474. //
  475. // Close the File Handle
  476. //
  477. CloseHandle (hFile);
  478. //
  479. // Check the result of the GetFileSize()
  480. //
  481. if (INVALID_FILE_SIZE == dwFileSize)
  482. {
  483. ec = GetLastError();
  484. DeleteFile( FullPath );
  485. DebugPrintEx(DEBUG_ERR, _T("GetFileSize failed (ec: %ld)"), ec);
  486. goto Error;
  487. }
  488. if (!dwFileSize)
  489. {
  490. //
  491. // Zero-sized file passed to us
  492. //
  493. ec = ERROR_INVALID_DATA;
  494. DeleteFile( FullPath );
  495. goto Error;
  496. }
  497. _tcscpy( TiffFile, FullPath );
  498. }
  499. else if (Flags & TIFFCF_UNCOMPRESSED_BITS)
  500. {
  501. if (FaxPrinter == NULL)
  502. {
  503. FaxPrinter = GetFaxPrinterName(hFax);
  504. if (FaxPrinter == NULL)
  505. {
  506. ec=GetLastError();
  507. DeleteFile( FullPath );
  508. goto Error;
  509. }
  510. }
  511. if (Flags & TIFFCF_ORIGINAL_FILE_GOOD)
  512. {
  513. //
  514. // nothing at fullpath, just delete it and use the original source
  515. //
  516. DeleteFile( FullPath );
  517. _tcscpy( TiffFile, FileName );
  518. }
  519. else
  520. {
  521. _tcscpy( TiffFile, FullPath );
  522. }
  523. if (GetTempFileName( TempPath, _T("fax"), 0, TempFile ) == 0 ||
  524. GetFullPathName( TempFile, sizeof(FullPath)/sizeof(TCHAR), FullPath, &p ) == 0)
  525. {
  526. ec=GetLastError();
  527. DeleteFile( TiffFile );
  528. goto Error;
  529. }
  530. ZeroMemory( &PrintInfo, sizeof(FAX_PRINT_INFO) );
  531. PrintInfo.SizeOfStruct = sizeof(FAX_PRINT_INFO);
  532. PrintInfo.OutputFileName = FullPath;
  533. ZeroMemory( &ContextInfo, sizeof(FAX_CONTEXT_INFO) );
  534. ContextInfo.SizeOfStruct = sizeof(FAX_CONTEXT_INFO);
  535. if (!FaxStartPrintJob( FaxPrinter, &PrintInfo, &TmpFaxJobId, &ContextInfo ))
  536. {
  537. ec=GetLastError();
  538. if ((Flags & TIFFCF_ORIGINAL_FILE_GOOD) == 0) DeleteFile( TiffFile );
  539. DeleteFile( FullPath );
  540. goto Error;
  541. }
  542. Rslt = PrintTiffFile( ContextInfo.hDC, TiffFile ); // This will call EndDoc
  543. if (!Rslt)
  544. {
  545. ec = GetLastError();
  546. Assert (ec);
  547. }
  548. if ((Flags & TIFFCF_ORIGINAL_FILE_GOOD) == 0)
  549. {
  550. DeleteFile( TiffFile );
  551. }
  552. if (!DeleteDC (ContextInfo.hDC))
  553. {
  554. DebugPrintEx(
  555. DEBUG_ERR,
  556. TEXT("DeleteDC failed. (ec: %ld)"),
  557. GetLastError());
  558. }
  559. if (!Rslt)
  560. {
  561. DeleteFile( FullPath );
  562. goto Error;
  563. }
  564. _tcscpy( TiffFile, FullPath );
  565. }
  566. else if (Flags & TIFFCF_ORIGINAL_FILE_GOOD)
  567. {
  568. //
  569. // we didn't create anything at FullPath, just use FileName
  570. //
  571. DeleteFile( FullPath );
  572. _tcscpy( TiffFile, FileName );
  573. }
  574. else
  575. {
  576. //
  577. // should never hit this case
  578. //
  579. Assert(FALSE);
  580. ec=ERROR_INVALID_DATA;
  581. DeleteFile( FullPath );
  582. goto Error;
  583. }
  584. hr = StringCchCopy (FinalTiffFile, cchFinalTiffFile, TiffFile);
  585. if (FAILED(hr))
  586. {
  587. ASSERT_FALSE;
  588. ec = HRESULT_CODE(hr);
  589. goto Error;
  590. }
  591. Error:
  592. MemFree (FaxPrinter);
  593. if (ERROR_SUCCESS != ec)
  594. {
  595. SetLastError(ec);
  596. return FALSE;
  597. }
  598. return TRUE;
  599. } // CreateFinalTiffFile
  600. static
  601. BOOL
  602. CopyFileToServerQueueA (
  603. const HANDLE IN hFaxHandle,
  604. const HANDLE IN hLocalFile,
  605. LPCSTR IN lpcstrLocalFileExt,
  606. LPSTR OUT lpstrServerFileName, // Name + extension of file created on the server
  607. DWORD IN cchServerFileName
  608. )
  609. /*++
  610. Routine name : CopyFileToServerQueueA
  611. Routine description:
  612. Creates a new file in the server's queue and copies another file to it.
  613. ANSI version
  614. Author:
  615. Eran Yariv (EranY), Dec, 1999
  616. Arguments:
  617. hFaxHandle [in ] - Fax Server Handle
  618. hLocalFile [in ] - Open handle of local file (source)
  619. The file should be open for read and the file pointer should
  620. be located at the beginning of the file.
  621. lpcstrLocalFileExt [in ] - Extension of generated queue file
  622. lpstrServerFileName [out] - Name of queue file created.
  623. This is a preallocated buffer that should be big enough
  624. to contain MAX_PATH characters.
  625. cchServerFileName [in ] - The size, in chars, of lpstrServerFileName
  626. Return Value:
  627. TRUE - Success
  628. FALSE - Failure, call GetLastError() for more error information.
  629. --*/
  630. {
  631. DWORD ec = ERROR_SUCCESS;
  632. LPCWSTR lpcwstrLocalFileExt = NULL;
  633. WCHAR wszServerFileName[MAX_PATH];
  634. DEBUG_FUNCTION_NAME(TEXT("CopyFileToServerQueueA"));
  635. //
  636. // Convert input parameter from ANSI to UNICODE
  637. //
  638. lpcwstrLocalFileExt = AnsiStringToUnicodeString(lpcstrLocalFileExt); // Allocates Memory !!!
  639. if (!lpcwstrLocalFileExt)
  640. {
  641. ec = GetLastError();
  642. goto exit;
  643. }
  644. if (!CopyFileToServerQueueW (hFaxHandle,
  645. hLocalFile,
  646. lpcwstrLocalFileExt,
  647. wszServerFileName,
  648. ARR_SIZE(wszServerFileName)))
  649. {
  650. ec = GetLastError();
  651. goto exit;
  652. }
  653. //
  654. // Convert output parameter from UNICODE to ANSI
  655. //
  656. if (!WideCharToMultiByte (
  657. CP_ACP,
  658. 0,
  659. wszServerFileName,
  660. -1,
  661. lpstrServerFileName,
  662. cchServerFileName,
  663. NULL,
  664. NULL
  665. ))
  666. {
  667. ec = GetLastError();
  668. goto exit;
  669. }
  670. Assert (ERROR_SUCCESS == ec);
  671. exit:
  672. //
  673. // Free temp strings
  674. //
  675. MemFree ((LPVOID)lpcwstrLocalFileExt);
  676. if (ERROR_SUCCESS != ec)
  677. {
  678. SetLastError (ec);
  679. return FALSE;
  680. }
  681. return TRUE;
  682. } // CopyFileToServerQueueA
  683. static
  684. BOOL
  685. CopyFileToServerQueueW (
  686. const HANDLE IN hFaxHandle,
  687. const HANDLE IN hLocaFile,
  688. LPCWSTR IN lpcwstrLocalFileExt,
  689. LPWSTR OUT lpwstrServerFileName, // Name + extension of file created on the server
  690. DWORD IN cchServerFileName
  691. )
  692. /*++
  693. Routine name : CopyFileToServerQueueW
  694. Routine description:
  695. Creates a new file in the server's queue and copies another file to it.
  696. UNICODE version
  697. Author:
  698. Eran Yariv (EranY), Dec, 1999
  699. Arguments:
  700. hFaxHandle [in ] - Fax Server Handle
  701. hLocalFile [in ] - Open handle of local file (source).
  702. The file should be open for read and the file pointer should
  703. be located at the beginning of the file.
  704. lpcwstrLocalFileExt [in ] - Extension of generated queue file
  705. lpwstrServerFileName [out] - Name of queue file created
  706. This is a preallocated buffer that should be big enough
  707. to contain MAX_PATH characters.
  708. cchServerFileName [in ] - The size, in WCHARs, of lpwstrServerFileName
  709. Return Value:
  710. TRUE - Success
  711. FALSE - Failure, call GetLastError() for more error information.
  712. --*/
  713. {
  714. DWORD ec = ERROR_SUCCESS;
  715. HANDLE hCopyContext = NULL;
  716. PBYTE aBuffer = NULL ;
  717. DEBUG_FUNCTION_NAME(TEXT("CopyFileToServerQueueW"));
  718. Assert (INVALID_HANDLE_VALUE != hLocaFile && lpcwstrLocalFileExt && lpwstrServerFileName);
  719. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  720. {
  721. SetLastError (ERROR_INVALID_HANDLE);
  722. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() failed."));
  723. return FALSE;
  724. }
  725. aBuffer = (PBYTE)MemAlloc(RPC_COPY_BUFFER_SIZE);
  726. if (NULL == aBuffer)
  727. {
  728. ec = ERROR_NOT_ENOUGH_MEMORY;
  729. DebugPrintEx(
  730. DEBUG_ERR,
  731. TEXT("Failed to allocate memory for read/write buffer."));
  732. goto exit;
  733. }
  734. //
  735. // We must fill lpwstrServerFileName with MAX_PATH-1 long string
  736. // so that the server side FAX_StartCopyToServer will get MAX_PATH buffer as out parameter
  737. //
  738. for ( DWORD i=0 ; i<cchServerFileName ; ++i)
  739. {
  740. lpwstrServerFileName[i]=L'A';
  741. }
  742. lpwstrServerFileName[cchServerFileName-1] = L'\0';
  743. //
  744. // Acquire copy context handle
  745. //
  746. __try
  747. {
  748. ec = FAX_StartCopyToServer (
  749. FH_FAX_HANDLE(hFaxHandle),
  750. lpcwstrLocalFileExt,
  751. lpwstrServerFileName,
  752. &hCopyContext);
  753. }
  754. __except (EXCEPTION_EXECUTE_HANDLER)
  755. {
  756. //
  757. // For some reason we got an exception.
  758. //
  759. ec = GetExceptionCode();
  760. DebugPrintEx(
  761. DEBUG_ERR,
  762. TEXT("Exception on RPC call to FAX_StartCopyToServer. (ec: %ld)"),
  763. ec);
  764. }
  765. if (ERROR_SUCCESS != ec)
  766. {
  767. DumpRPCExtendedStatus ();
  768. DebugPrintEx(DEBUG_ERR, _T("FAX_StartCopyToServer failed (ec: %ld)"), ec);
  769. goto exit;
  770. }
  771. //
  772. // Start copy iteration(s)
  773. //
  774. for (;;)
  775. {
  776. DWORD dwBytesRead;
  777. if (!ReadFile (hLocaFile,
  778. aBuffer,
  779. sizeof (BYTE) * RPC_COPY_BUFFER_SIZE,
  780. &dwBytesRead,
  781. NULL))
  782. {
  783. ec = GetLastError ();
  784. DebugPrintEx(
  785. DEBUG_ERR,
  786. TEXT("ReadFile failed (ec: %ld)"),
  787. ec);
  788. goto exit;
  789. }
  790. if (0 == dwBytesRead)
  791. {
  792. //
  793. // EOF situation
  794. //
  795. break;
  796. }
  797. //
  798. // Move bytes to server via RPC
  799. //
  800. __try
  801. {
  802. ec = FAX_WriteFile (
  803. hCopyContext,
  804. aBuffer,
  805. dwBytesRead);
  806. }
  807. __except (EXCEPTION_EXECUTE_HANDLER)
  808. {
  809. //
  810. // For some reason we got an exception.
  811. //
  812. ec = GetExceptionCode();
  813. DebugPrintEx(
  814. DEBUG_ERR,
  815. TEXT("Exception on RPC call to FAX_WriteFile. (ec: %ld)"),
  816. ec);
  817. }
  818. if (ERROR_SUCCESS != ec)
  819. {
  820. DumpRPCExtendedStatus ();
  821. DebugPrintEx(
  822. DEBUG_ERR,
  823. TEXT("FAX_WriteFile failed (ec: %ld)"),
  824. ec);
  825. goto exit;
  826. }
  827. } // End of copy iteration
  828. Assert (ERROR_SUCCESS == ec);
  829. exit:
  830. if (NULL != hCopyContext)
  831. {
  832. DWORD ec2 = ERROR_SUCCESS;
  833. //
  834. // Close RPC copy context
  835. //
  836. __try
  837. {
  838. ec2 = FAX_EndCopy (&hCopyContext);
  839. }
  840. __except (EXCEPTION_EXECUTE_HANDLER)
  841. {
  842. //
  843. // For some reason we got an exception.
  844. //
  845. ec2 = GetExceptionCode();
  846. DebugPrintEx(
  847. DEBUG_ERR,
  848. TEXT("Exception on RPC call to FAX_EndCopy. (ec: %ld)"),
  849. ec2);
  850. }
  851. if (ERROR_SUCCESS != ec2)
  852. {
  853. DumpRPCExtendedStatus ();
  854. DebugPrintEx(
  855. DEBUG_ERR,
  856. TEXT("FAX_EndCopy failed (ec: %ld)"),
  857. ec2);
  858. }
  859. if (!ec)
  860. {
  861. ec = ec2;
  862. }
  863. }
  864. if (NULL != aBuffer)
  865. {
  866. MemFree(aBuffer);
  867. }
  868. if (ERROR_SUCCESS != ec)
  869. {
  870. SetLastError (ec);
  871. return FALSE;
  872. }
  873. return TRUE;
  874. } // CopyFileToServerQueueW
  875. void
  876. FreePersonalProfileStrings(
  877. PFAX_PERSONAL_PROFILE pProfile
  878. )
  879. {
  880. MemFree(pProfile->lptstrName);
  881. MemFree(pProfile->lptstrFaxNumber);
  882. MemFree(pProfile->lptstrCompany);
  883. MemFree(pProfile->lptstrStreetAddress);
  884. MemFree(pProfile->lptstrCity);
  885. MemFree(pProfile->lptstrState);
  886. MemFree(pProfile->lptstrZip);
  887. MemFree(pProfile->lptstrCountry);
  888. MemFree(pProfile->lptstrTitle);
  889. MemFree(pProfile->lptstrDepartment);
  890. MemFree(pProfile->lptstrOfficeLocation);
  891. MemFree(pProfile->lptstrHomePhone);
  892. MemFree(pProfile->lptstrOfficePhone);
  893. MemFree(pProfile->lptstrEmail);
  894. MemFree(pProfile->lptstrBillingCode);
  895. MemFree(pProfile->lptstrTSID);
  896. }
  897. BOOL
  898. WINAPI
  899. FaxSendDocument(
  900. IN HANDLE FaxHandle,
  901. IN LPCTSTR FileName,
  902. IN FAX_JOB_PARAM *lpcJobParams,
  903. IN const FAX_COVERPAGE_INFO *lpcCoverPageInfo,
  904. OUT LPDWORD FaxJobId
  905. )
  906. {
  907. FAX_JOB_PARAM_EX JobParamsEx;
  908. FAX_PERSONAL_PROFILE Sender;
  909. FAX_PERSONAL_PROFILE Recipient;
  910. FAX_COVERPAGE_INFO_EX CoverPageEx;
  911. LPCFAX_COVERPAGE_INFO_EX lpcNewCoverPageInfo;
  912. BOOL bRes;
  913. DWORDLONG dwParentId;
  914. DWORDLONG dwRecipientId;
  915. DWORD FaxJobIdLocal;
  916. DEBUG_FUNCTION_NAME(_T("FaxSendDocument"));
  917. if (!FaxJobId || !lpcJobParams || !FaxJobId)
  918. {
  919. DebugPrintEx(DEBUG_ERR,
  920. TEXT("FaxJobId or lpcJobParams or FaxJobId is NULL"));
  921. SetLastError (ERROR_INVALID_PARAMETER);
  922. return FALSE;
  923. }
  924. if (sizeof (FAX_JOB_PARAM) != lpcJobParams->SizeOfStruct)
  925. {
  926. DebugPrintEx(DEBUG_ERR,
  927. TEXT("lpcJobParams->SizeOfStruct is %d, expecting %d"),
  928. lpcJobParams->SizeOfStruct,
  929. sizeof (FAX_JOB_PARAM));
  930. SetLastError (ERROR_INVALID_PARAMETER);
  931. return FALSE;
  932. }
  933. if (lpcCoverPageInfo && (sizeof (FAX_COVERPAGE_INFO) != lpcCoverPageInfo->SizeOfStruct))
  934. {
  935. DebugPrintEx(DEBUG_ERR,
  936. TEXT("lpcCoverPageInfo->SizeOfStruct is %d, expecting %d"),
  937. lpcCoverPageInfo->SizeOfStruct,
  938. sizeof (FAX_COVERPAGE_INFO));
  939. SetLastError (ERROR_INVALID_DATA);
  940. return FALSE;
  941. }
  942. //
  943. // Copy the legacy job parameters to the new structures used to add
  944. // parent and recipient job.
  945. //
  946. memset(&JobParamsEx,0,sizeof(FAX_JOB_PARAM_EX));
  947. JobParamsEx.dwSizeOfStruct =sizeof(FAX_JOB_PARAM_EX);
  948. JobParamsEx.dwScheduleAction=lpcJobParams->ScheduleAction;
  949. JobParamsEx.tmSchedule=lpcJobParams->ScheduleTime;
  950. JobParamsEx.dwReceiptDeliveryType=lpcJobParams->DeliveryReportType;
  951. JobParamsEx.lptstrReceiptDeliveryAddress=StringDup( lpcJobParams->DeliveryReportAddress);
  952. JobParamsEx.hCall=lpcJobParams->CallHandle;
  953. JobParamsEx.Priority = FAX_PRIORITY_TYPE_NORMAL;
  954. memcpy(JobParamsEx.dwReserved, lpcJobParams->Reserved, sizeof(lpcJobParams->Reserved));
  955. JobParamsEx.lptstrDocumentName=StringDup( lpcJobParams->DocumentName);
  956. memset(&Sender,0,sizeof(FAX_PERSONAL_PROFILE));
  957. Sender.dwSizeOfStruct =sizeof(FAX_PERSONAL_PROFILE);
  958. Sender.lptstrBillingCode=StringDup(lpcJobParams->BillingCode);
  959. Sender.lptstrCompany=StringDup( lpcJobParams->SenderCompany);
  960. Sender.lptstrDepartment=StringDup( lpcJobParams->SenderDept);
  961. Sender.lptstrName=StringDup( lpcJobParams->SenderName);
  962. Sender.lptstrTSID=StringDup( lpcJobParams->Tsid );
  963. memset(&CoverPageEx,0,sizeof(FAX_COVERPAGE_INFO_EX));
  964. if (lpcCoverPageInfo)
  965. {
  966. Sender.lptstrCity=StringDup( lpcCoverPageInfo->SdrAddress); // due to structures incompatibility Sender.lptstrCity will
  967. // contain the whole address
  968. if (NULL == Sender.lptstrName)
  969. {
  970. Sender.lptstrName=StringDup( lpcCoverPageInfo->SdrName);
  971. }
  972. if (NULL == Sender.lptstrCompany)
  973. {
  974. Sender.lptstrCompany=StringDup( lpcCoverPageInfo->SdrCompany);
  975. }
  976. if (NULL == Sender.lptstrDepartment)
  977. {
  978. Sender.lptstrDepartment=StringDup( lpcCoverPageInfo->SdrDepartment);
  979. }
  980. Sender.lptstrFaxNumber=StringDup( lpcCoverPageInfo->SdrFaxNumber);
  981. Sender.lptstrHomePhone=StringDup( lpcCoverPageInfo->SdrHomePhone);
  982. Sender.lptstrOfficeLocation=StringDup( lpcCoverPageInfo->SdrOfficeLocation);
  983. Sender.lptstrOfficePhone=StringDup( lpcCoverPageInfo->SdrOfficePhone);
  984. Sender.lptstrTitle=StringDup( lpcCoverPageInfo->SdrTitle);
  985. CoverPageEx.dwSizeOfStruct=sizeof(FAX_COVERPAGE_INFO_EX);
  986. CoverPageEx.dwCoverPageFormat=FAX_COVERPAGE_FMT_COV;
  987. CoverPageEx.lptstrCoverPageFileName=StringDup(lpcCoverPageInfo->CoverPageName);
  988. CoverPageEx.lptstrNote=StringDup(lpcCoverPageInfo->Note);
  989. CoverPageEx.lptstrSubject=StringDup(lpcCoverPageInfo->Subject);
  990. CoverPageEx.bServerBased=lpcCoverPageInfo->UseServerCoverPage;
  991. lpcNewCoverPageInfo =&CoverPageEx;
  992. JobParamsEx.dwPageCount = lpcCoverPageInfo->PageCount;
  993. }
  994. else
  995. {
  996. lpcNewCoverPageInfo = NULL;
  997. }
  998. memset(&Recipient,0,sizeof(FAX_PERSONAL_PROFILE));
  999. Recipient.dwSizeOfStruct =sizeof(FAX_PERSONAL_PROFILE);
  1000. Recipient.lptstrName=StringDup( lpcJobParams->RecipientName);
  1001. Recipient.lptstrFaxNumber=StringDup( lpcJobParams->RecipientNumber);
  1002. if (lpcCoverPageInfo)
  1003. {
  1004. if (NULL == Recipient.lptstrName)
  1005. {
  1006. Recipient.lptstrName=StringDup( lpcCoverPageInfo->RecName);
  1007. }
  1008. if (NULL == Recipient.lptstrFaxNumber)
  1009. {
  1010. Recipient.lptstrFaxNumber=StringDup( lpcCoverPageInfo->RecFaxNumber);
  1011. }
  1012. Recipient.lptstrCountry=StringDup( lpcCoverPageInfo->RecCountry);
  1013. Recipient.lptstrStreetAddress=StringDup( lpcCoverPageInfo->RecStreetAddress);
  1014. Recipient.lptstrCompany=StringDup( lpcCoverPageInfo->RecCompany);
  1015. Recipient.lptstrDepartment=StringDup( lpcCoverPageInfo->RecDepartment);
  1016. Recipient.lptstrHomePhone=StringDup( lpcCoverPageInfo->RecHomePhone);
  1017. Recipient.lptstrOfficeLocation=StringDup( lpcCoverPageInfo->RecOfficeLocation);
  1018. Recipient.lptstrOfficePhone=StringDup( lpcCoverPageInfo->RecOfficePhone);
  1019. Recipient.lptstrTitle=StringDup( lpcCoverPageInfo->RecTitle);
  1020. Recipient.lptstrZip=StringDup( lpcCoverPageInfo->RecZip);
  1021. Recipient.lptstrCity=StringDup( lpcCoverPageInfo->RecCity);
  1022. }
  1023. bRes=FaxSendDocumentEx2(
  1024. FaxHandle,
  1025. FileName,
  1026. lpcNewCoverPageInfo,
  1027. &Sender,
  1028. 1,
  1029. &Recipient,
  1030. &JobParamsEx,
  1031. &FaxJobIdLocal,
  1032. &dwParentId,
  1033. &dwRecipientId);
  1034. if(bRes && FaxJobId)
  1035. {
  1036. *FaxJobId = FaxJobIdLocal;
  1037. }
  1038. //
  1039. // Free everything
  1040. //
  1041. MemFree(JobParamsEx.lptstrReceiptDeliveryAddress);
  1042. MemFree(JobParamsEx.lptstrDocumentName);
  1043. MemFree(CoverPageEx.lptstrCoverPageFileName);
  1044. MemFree(CoverPageEx.lptstrNote);
  1045. MemFree(CoverPageEx.lptstrSubject);
  1046. FreePersonalProfileStrings(&Recipient);
  1047. FreePersonalProfileStrings(&Sender);
  1048. if (ERROR_NO_ASSOCIATION == GetLastError ())
  1049. {
  1050. //
  1051. // We need to support W2K backwards compatability up to the exact error code in case of failure.
  1052. //
  1053. SetLastError (ERROR_INVALID_DATA);
  1054. }
  1055. return bRes;
  1056. }
  1057. #ifdef UNICODE
  1058. // We need to support an ANSI version that calls the Unicode version
  1059. BOOL
  1060. WINAPI
  1061. FaxSendDocumentA(
  1062. IN HANDLE FaxHandle,
  1063. IN LPCSTR FileName,
  1064. IN FAX_JOB_PARAMA *JobParamsA,
  1065. IN const FAX_COVERPAGE_INFOA *CoverpageInfoA,
  1066. OUT LPDWORD FaxJobId
  1067. )
  1068. /*++
  1069. Routine Description:
  1070. Sends a FAX document to the specified recipient.
  1071. This is an asychronous operation. Use FaxReportStatus
  1072. to determine when the send is completed.
  1073. Arguments:
  1074. FaxHandle - FAX handle obtained from FaxConnectFaxServer.
  1075. FileName - File containing the TIFF-F FAX document.
  1076. JobParams - pointer to FAX_JOB_PARAM structure with transmission params
  1077. CoverpageInfo - optional pointer to FAX_COVERPAGE_INFO structure
  1078. FaxJobId - receives the Fax JobId for the job.
  1079. Return Value:
  1080. TRUE - Success
  1081. FALSE - Failure, call GetLastError() for more error information.
  1082. --*/
  1083. {
  1084. error_status_t ec;
  1085. LPWSTR FileNameW = NULL;
  1086. FAX_JOB_PARAMW JobParamsW = {0};
  1087. FAX_COVERPAGE_INFOW CoverpageInfoW = {0};
  1088. DEBUG_FUNCTION_NAME(_T("FaxSendDocumentA"));
  1089. if (!JobParamsA ||
  1090. (sizeof (FAX_JOB_PARAMA) != JobParamsA->SizeOfStruct))
  1091. {
  1092. SetLastError(ERROR_INVALID_PARAMETER);
  1093. DebugPrintEx(DEBUG_ERR, _T("JobParamsA is NULL or has bad size."));
  1094. return FALSE;
  1095. }
  1096. if (CoverpageInfoA &&
  1097. (sizeof (FAX_COVERPAGE_INFOA) != CoverpageInfoA->SizeOfStruct))
  1098. {
  1099. SetLastError(ERROR_INVALID_DATA);
  1100. DebugPrintEx(DEBUG_ERR, _T("CoverpageInfoA has bad size."));
  1101. return FALSE;
  1102. }
  1103. if (FileName)
  1104. {
  1105. FileNameW = AnsiStringToUnicodeString( FileName );
  1106. if (FileNameW == NULL)
  1107. {
  1108. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1109. ec = ERROR_OUTOFMEMORY;
  1110. goto exit;
  1111. }
  1112. }
  1113. CopyMemory(&JobParamsW, JobParamsA, sizeof(FAX_JOB_PARAMA));
  1114. JobParamsW.SizeOfStruct = sizeof(FAX_JOB_PARAMW);
  1115. JobParamsW.RecipientNumber = AnsiStringToUnicodeString(JobParamsA->RecipientNumber);
  1116. if (!JobParamsW.RecipientNumber && JobParamsA->RecipientNumber)
  1117. {
  1118. ec = ERROR_OUTOFMEMORY;
  1119. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1120. goto exit;
  1121. }
  1122. JobParamsW.RecipientName = AnsiStringToUnicodeString(JobParamsA->RecipientName);
  1123. if (!JobParamsW.RecipientName && JobParamsA->RecipientName)
  1124. {
  1125. ec = ERROR_OUTOFMEMORY;
  1126. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1127. goto exit;
  1128. }
  1129. JobParamsW.Tsid = AnsiStringToUnicodeString(JobParamsA->Tsid);
  1130. if (!JobParamsW.Tsid && JobParamsA->Tsid)
  1131. {
  1132. ec = ERROR_OUTOFMEMORY;
  1133. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1134. goto exit;
  1135. }
  1136. JobParamsW.SenderName = AnsiStringToUnicodeString(JobParamsA->SenderName);
  1137. if (!JobParamsW.SenderName && JobParamsA->SenderName)
  1138. {
  1139. ec = ERROR_OUTOFMEMORY;
  1140. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1141. goto exit;
  1142. }
  1143. JobParamsW.SenderCompany = AnsiStringToUnicodeString(JobParamsA->SenderCompany);
  1144. if (!JobParamsW.SenderCompany && JobParamsA->SenderCompany)
  1145. {
  1146. ec = ERROR_OUTOFMEMORY;
  1147. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1148. goto exit;
  1149. }
  1150. JobParamsW.SenderDept = AnsiStringToUnicodeString(JobParamsA->SenderDept);
  1151. if (!JobParamsW.SenderDept && JobParamsA->SenderDept)
  1152. {
  1153. ec = ERROR_OUTOFMEMORY;
  1154. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1155. goto exit;
  1156. }
  1157. JobParamsW.BillingCode = AnsiStringToUnicodeString(JobParamsA->BillingCode);
  1158. if (!JobParamsW.BillingCode && JobParamsA->BillingCode)
  1159. {
  1160. ec = ERROR_OUTOFMEMORY;
  1161. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1162. goto exit;
  1163. }
  1164. JobParamsW.DeliveryReportAddress = AnsiStringToUnicodeString(JobParamsA->DeliveryReportAddress);
  1165. if (!JobParamsW.DeliveryReportAddress && JobParamsA->DeliveryReportAddress)
  1166. {
  1167. ec = ERROR_OUTOFMEMORY;
  1168. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1169. goto exit;
  1170. }
  1171. JobParamsW.DocumentName = AnsiStringToUnicodeString(JobParamsA->DocumentName);
  1172. if (!JobParamsW.DocumentName && JobParamsA->DocumentName)
  1173. {
  1174. ec = ERROR_OUTOFMEMORY;
  1175. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1176. goto exit;
  1177. }
  1178. if (CoverpageInfoA)
  1179. {
  1180. CoverpageInfoW.SizeOfStruct = sizeof(FAX_COVERPAGE_INFOW);
  1181. CoverpageInfoW.UseServerCoverPage = CoverpageInfoA->UseServerCoverPage;
  1182. CoverpageInfoW.PageCount = CoverpageInfoA->PageCount;
  1183. CoverpageInfoW.TimeSent = CoverpageInfoA->TimeSent;
  1184. CoverpageInfoW.CoverPageName = AnsiStringToUnicodeString( CoverpageInfoA->CoverPageName );
  1185. if (!CoverpageInfoW.CoverPageName && CoverpageInfoA->CoverPageName)
  1186. {
  1187. ec = ERROR_OUTOFMEMORY;
  1188. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1189. goto exit;
  1190. }
  1191. CoverpageInfoW.RecName = AnsiStringToUnicodeString( CoverpageInfoA->RecName );
  1192. if (!CoverpageInfoW.RecName && CoverpageInfoA->RecName)
  1193. {
  1194. ec = ERROR_OUTOFMEMORY;
  1195. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1196. goto exit;
  1197. }
  1198. CoverpageInfoW.RecFaxNumber = AnsiStringToUnicodeString( CoverpageInfoA->RecFaxNumber );
  1199. if (!CoverpageInfoW.RecFaxNumber && CoverpageInfoA->RecFaxNumber)
  1200. {
  1201. ec = ERROR_OUTOFMEMORY;
  1202. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1203. goto exit;
  1204. }
  1205. CoverpageInfoW.RecCompany = AnsiStringToUnicodeString( CoverpageInfoA->RecCompany );
  1206. if (!CoverpageInfoW.RecCompany && CoverpageInfoA->RecCompany)
  1207. {
  1208. ec = ERROR_OUTOFMEMORY;
  1209. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1210. goto exit;
  1211. }
  1212. CoverpageInfoW.RecStreetAddress = AnsiStringToUnicodeString( CoverpageInfoA->RecStreetAddress );
  1213. if (!CoverpageInfoW.RecStreetAddress && CoverpageInfoA->RecStreetAddress)
  1214. {
  1215. ec = ERROR_OUTOFMEMORY;
  1216. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1217. goto exit;
  1218. }
  1219. CoverpageInfoW.RecCity = AnsiStringToUnicodeString( CoverpageInfoA->RecCity );
  1220. if (!CoverpageInfoW.RecCity && CoverpageInfoA->RecCity)
  1221. {
  1222. ec = ERROR_OUTOFMEMORY;
  1223. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1224. goto exit;
  1225. }
  1226. CoverpageInfoW.RecState = AnsiStringToUnicodeString( CoverpageInfoA->RecState );
  1227. if (!CoverpageInfoW.RecState && CoverpageInfoA->RecState)
  1228. {
  1229. ec = ERROR_OUTOFMEMORY;
  1230. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1231. goto exit;
  1232. }
  1233. CoverpageInfoW.RecZip = AnsiStringToUnicodeString( CoverpageInfoA->RecZip );
  1234. if (!CoverpageInfoW.RecZip && CoverpageInfoA->RecZip)
  1235. {
  1236. ec = ERROR_OUTOFMEMORY;
  1237. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1238. goto exit;
  1239. }
  1240. CoverpageInfoW.RecCountry = AnsiStringToUnicodeString( CoverpageInfoA->RecCountry );
  1241. if (!CoverpageInfoW.RecCountry && CoverpageInfoA->RecCountry)
  1242. {
  1243. ec = ERROR_OUTOFMEMORY;
  1244. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1245. goto exit;
  1246. }
  1247. CoverpageInfoW.RecTitle = AnsiStringToUnicodeString( CoverpageInfoA->RecTitle );
  1248. if (!CoverpageInfoW.RecTitle && CoverpageInfoA->RecTitle)
  1249. {
  1250. ec = ERROR_OUTOFMEMORY;
  1251. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1252. goto exit;
  1253. }
  1254. CoverpageInfoW.RecDepartment = AnsiStringToUnicodeString( CoverpageInfoA->RecDepartment );
  1255. if (!CoverpageInfoW.RecDepartment && CoverpageInfoA->RecDepartment)
  1256. {
  1257. ec = ERROR_OUTOFMEMORY;
  1258. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1259. goto exit;
  1260. }
  1261. CoverpageInfoW.RecOfficeLocation = AnsiStringToUnicodeString( CoverpageInfoA->RecOfficeLocation );
  1262. if (!CoverpageInfoW.RecOfficeLocation && CoverpageInfoA->RecOfficeLocation)
  1263. {
  1264. ec = ERROR_OUTOFMEMORY;
  1265. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1266. goto exit;
  1267. }
  1268. CoverpageInfoW.RecHomePhone = AnsiStringToUnicodeString( CoverpageInfoA->RecHomePhone );
  1269. if (!CoverpageInfoW.RecHomePhone && CoverpageInfoA->RecHomePhone)
  1270. {
  1271. ec = ERROR_OUTOFMEMORY;
  1272. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1273. goto exit;
  1274. }
  1275. CoverpageInfoW.RecOfficePhone = AnsiStringToUnicodeString( CoverpageInfoA->RecOfficePhone );
  1276. if (!CoverpageInfoW.RecOfficePhone && CoverpageInfoA->RecOfficePhone)
  1277. {
  1278. ec = ERROR_OUTOFMEMORY;
  1279. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1280. goto exit;
  1281. }
  1282. CoverpageInfoW.SdrName = AnsiStringToUnicodeString( CoverpageInfoA->SdrName );
  1283. if (!CoverpageInfoW.SdrName && CoverpageInfoA->SdrName)
  1284. {
  1285. ec = ERROR_OUTOFMEMORY;
  1286. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1287. goto exit;
  1288. }
  1289. CoverpageInfoW.SdrFaxNumber = AnsiStringToUnicodeString( CoverpageInfoA->SdrFaxNumber );
  1290. if (!CoverpageInfoW.SdrFaxNumber && CoverpageInfoA->SdrFaxNumber)
  1291. {
  1292. ec = ERROR_OUTOFMEMORY;
  1293. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1294. goto exit;
  1295. }
  1296. CoverpageInfoW.SdrCompany = AnsiStringToUnicodeString( CoverpageInfoA->SdrCompany );
  1297. if (!CoverpageInfoW.SdrCompany && CoverpageInfoA->SdrCompany)
  1298. {
  1299. ec = ERROR_OUTOFMEMORY;
  1300. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1301. goto exit;
  1302. }
  1303. CoverpageInfoW.SdrAddress = AnsiStringToUnicodeString( CoverpageInfoA->SdrAddress );
  1304. if (!CoverpageInfoW.SdrAddress && CoverpageInfoA->SdrAddress)
  1305. {
  1306. ec = ERROR_OUTOFMEMORY;
  1307. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1308. goto exit;
  1309. }
  1310. CoverpageInfoW.SdrTitle = AnsiStringToUnicodeString( CoverpageInfoA->SdrTitle );
  1311. if (!CoverpageInfoW.SdrTitle && CoverpageInfoA->SdrTitle)
  1312. {
  1313. ec = ERROR_OUTOFMEMORY;
  1314. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1315. goto exit;
  1316. }
  1317. CoverpageInfoW.SdrDepartment = AnsiStringToUnicodeString( CoverpageInfoA->SdrDepartment );
  1318. if (!CoverpageInfoW.SdrDepartment && CoverpageInfoA->SdrDepartment)
  1319. {
  1320. ec = ERROR_OUTOFMEMORY;
  1321. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1322. goto exit;
  1323. }
  1324. CoverpageInfoW.SdrOfficeLocation = AnsiStringToUnicodeString( CoverpageInfoA->SdrOfficeLocation );
  1325. if (!CoverpageInfoW.SdrOfficeLocation && CoverpageInfoA->SdrOfficeLocation)
  1326. {
  1327. ec = ERROR_OUTOFMEMORY;
  1328. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1329. goto exit;
  1330. }
  1331. CoverpageInfoW.SdrHomePhone = AnsiStringToUnicodeString( CoverpageInfoA->SdrHomePhone );
  1332. if (!CoverpageInfoW.SdrHomePhone && CoverpageInfoA->SdrHomePhone)
  1333. {
  1334. ec = ERROR_OUTOFMEMORY;
  1335. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1336. goto exit;
  1337. }
  1338. CoverpageInfoW.SdrOfficePhone = AnsiStringToUnicodeString( CoverpageInfoA->SdrOfficePhone );
  1339. if (!CoverpageInfoW.SdrOfficePhone && CoverpageInfoA->SdrOfficePhone)
  1340. {
  1341. ec = ERROR_OUTOFMEMORY;
  1342. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1343. goto exit;
  1344. }
  1345. CoverpageInfoW.Note = AnsiStringToUnicodeString( CoverpageInfoA->Note );
  1346. if (!CoverpageInfoW.Note && CoverpageInfoA->Note)
  1347. {
  1348. ec = ERROR_OUTOFMEMORY;
  1349. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1350. goto exit;
  1351. }
  1352. CoverpageInfoW.Subject = AnsiStringToUnicodeString( CoverpageInfoA->Subject );
  1353. if (!CoverpageInfoW.Subject && CoverpageInfoA->Subject)
  1354. {
  1355. ec = ERROR_OUTOFMEMORY;
  1356. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1357. goto exit;
  1358. }
  1359. }
  1360. if (FaxSendDocumentW( FaxHandle,
  1361. FileNameW,
  1362. &JobParamsW,
  1363. CoverpageInfoA ? &CoverpageInfoW : NULL,
  1364. FaxJobId )) {
  1365. ec = 0;
  1366. }
  1367. else
  1368. {
  1369. ec = GetLastError();
  1370. DebugPrintEx(DEBUG_ERR, _T("FaxSendDocumentW() is failed. ec = %ld."), ec);
  1371. }
  1372. exit:
  1373. MemFree( (LPBYTE) FileNameW );
  1374. MemFree( (LPBYTE) JobParamsW.RecipientNumber );
  1375. MemFree( (LPBYTE) JobParamsW.RecipientName );
  1376. MemFree( (LPBYTE) JobParamsW.Tsid );
  1377. MemFree( (LPBYTE) JobParamsW.SenderName );
  1378. MemFree( (LPBYTE) JobParamsW.SenderDept );
  1379. MemFree( (LPBYTE) JobParamsW.SenderCompany );
  1380. MemFree( (LPBYTE) JobParamsW.BillingCode );
  1381. MemFree( (LPBYTE) JobParamsW.DeliveryReportAddress );
  1382. MemFree( (LPBYTE) JobParamsW.DocumentName );
  1383. if (CoverpageInfoA)
  1384. {
  1385. MemFree( (LPBYTE) CoverpageInfoW.CoverPageName );
  1386. MemFree( (LPBYTE) CoverpageInfoW.RecName );
  1387. MemFree( (LPBYTE) CoverpageInfoW.RecFaxNumber );
  1388. MemFree( (LPBYTE) CoverpageInfoW.RecCompany );
  1389. MemFree( (LPBYTE) CoverpageInfoW.RecStreetAddress );
  1390. MemFree( (LPBYTE) CoverpageInfoW.RecCity );
  1391. MemFree( (LPBYTE) CoverpageInfoW.RecState );
  1392. MemFree( (LPBYTE) CoverpageInfoW.RecZip );
  1393. MemFree( (LPBYTE) CoverpageInfoW.RecCountry );
  1394. MemFree( (LPBYTE) CoverpageInfoW.RecTitle );
  1395. MemFree( (LPBYTE) CoverpageInfoW.RecDepartment );
  1396. MemFree( (LPBYTE) CoverpageInfoW.RecOfficeLocation );
  1397. MemFree( (LPBYTE) CoverpageInfoW.RecHomePhone );
  1398. MemFree( (LPBYTE) CoverpageInfoW.RecOfficePhone );
  1399. MemFree( (LPBYTE) CoverpageInfoW.SdrName );
  1400. MemFree( (LPBYTE) CoverpageInfoW.SdrFaxNumber );
  1401. MemFree( (LPBYTE) CoverpageInfoW.SdrCompany );
  1402. MemFree( (LPBYTE) CoverpageInfoW.SdrAddress );
  1403. MemFree( (LPBYTE) CoverpageInfoW.SdrTitle );
  1404. MemFree( (LPBYTE) CoverpageInfoW.SdrDepartment );
  1405. MemFree( (LPBYTE) CoverpageInfoW.SdrOfficeLocation );
  1406. MemFree( (LPBYTE) CoverpageInfoW.SdrHomePhone );
  1407. MemFree( (LPBYTE) CoverpageInfoW.SdrOfficePhone );
  1408. MemFree( (LPBYTE) CoverpageInfoW.Note );
  1409. MemFree( (LPBYTE) CoverpageInfoW.Subject );
  1410. }
  1411. if (ec)
  1412. {
  1413. SetLastError( ec );
  1414. return FALSE;
  1415. }
  1416. return TRUE;
  1417. }
  1418. #else
  1419. // When compiling for ANSI (Win9X) we need only to suppot the ANSI version
  1420. BOOL
  1421. WINAPI
  1422. FaxSendDocumentW(
  1423. IN HANDLE FaxHandle,
  1424. IN LPCWSTR FileName,
  1425. IN FAX_JOB_PARAMW *JobParams,
  1426. IN const FAX_COVERPAGE_INFOW *CoverpageInfo,
  1427. OUT LPDWORD FaxJobId
  1428. )
  1429. {
  1430. UNREFERENCED_PARAMETER(FaxHandle);
  1431. UNREFERENCED_PARAMETER(FileName);
  1432. UNREFERENCED_PARAMETER(JobParams);
  1433. UNREFERENCED_PARAMETER(CoverpageInfo);
  1434. UNREFERENCED_PARAMETER(FaxJobId);
  1435. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1436. return FALSE;
  1437. }
  1438. #endif
  1439. BOOL
  1440. CopyCallbackDataAnsiToNeutral(
  1441. PFAX_JOB_PARAMA pJobParamsA,
  1442. PFAX_COVERPAGE_INFOA pCoverPageA,
  1443. PFAX_JOB_PARAM_EX pJobParamsEx,
  1444. PFAX_COVERPAGE_INFO_EX pCoverPageEx,
  1445. PFAX_PERSONAL_PROFILE pSender,
  1446. PFAX_PERSONAL_PROFILE pRecipient
  1447. )
  1448. {
  1449. ZeroMemory(pJobParamsEx, sizeof(*pJobParamsEx));
  1450. pJobParamsEx->dwSizeOfStruct = sizeof(*pJobParamsEx);
  1451. pJobParamsEx->dwScheduleAction = pJobParamsA->ScheduleAction;
  1452. pJobParamsEx->tmSchedule = pJobParamsA->ScheduleTime;
  1453. pJobParamsEx->dwReceiptDeliveryType = pJobParamsA->DeliveryReportType;
  1454. pJobParamsEx->Priority = FAX_PRIORITY_TYPE_NORMAL;
  1455. pJobParamsEx->hCall = pJobParamsA->CallHandle;
  1456. memcpy(pJobParamsEx->dwReserved, pJobParamsA->Reserved, sizeof(pJobParamsA->Reserved));
  1457. if(pCoverPageA)
  1458. {
  1459. pJobParamsEx->dwPageCount = pCoverPageA->PageCount;
  1460. }
  1461. ZeroMemory(pCoverPageEx, sizeof(*pCoverPageEx));
  1462. pCoverPageEx->dwSizeOfStruct = sizeof(*pCoverPageEx);
  1463. pCoverPageEx->dwCoverPageFormat = FAX_COVERPAGE_FMT_COV;
  1464. if(pCoverPageA)
  1465. {
  1466. pCoverPageEx->bServerBased = pCoverPageA->UseServerCoverPage;
  1467. }
  1468. ZeroMemory(pSender, sizeof(*pSender));
  1469. pSender->dwSizeOfStruct = sizeof(*pSender);
  1470. ZeroMemory(pRecipient, sizeof(*pRecipient));
  1471. pRecipient->dwSizeOfStruct = sizeof(*pRecipient);
  1472. #ifdef UNICODE
  1473. pJobParamsEx->lptstrReceiptDeliveryAddress = AnsiStringToUnicodeString(pJobParamsA->DeliveryReportAddress);
  1474. pJobParamsEx->lptstrDocumentName = AnsiStringToUnicodeString(pJobParamsA->DocumentName);
  1475. pSender->lptstrName = AnsiStringToUnicodeString(pJobParamsA->SenderName);
  1476. pSender->lptstrCompany = AnsiStringToUnicodeString(pJobParamsA->SenderCompany);
  1477. pSender->lptstrDepartment = AnsiStringToUnicodeString(pJobParamsA->SenderDept);
  1478. pSender->lptstrBillingCode = AnsiStringToUnicodeString(pJobParamsA->BillingCode);
  1479. pRecipient->lptstrName = AnsiStringToUnicodeString(pJobParamsA->RecipientName);
  1480. pRecipient->lptstrFaxNumber = AnsiStringToUnicodeString(pJobParamsA->RecipientNumber);
  1481. pRecipient->lptstrTSID = AnsiStringToUnicodeString(pJobParamsA->Tsid);
  1482. if(pCoverPageA)
  1483. {
  1484. pCoverPageEx->lptstrCoverPageFileName = AnsiStringToUnicodeString(pCoverPageA->CoverPageName);
  1485. pCoverPageEx->lptstrNote = AnsiStringToUnicodeString(pCoverPageA->Note);
  1486. pCoverPageEx->lptstrSubject = AnsiStringToUnicodeString(pCoverPageA->Subject);
  1487. pSender->lptstrCity=AnsiStringToUnicodeString(pCoverPageA->SdrAddress); // due to structures incopitabilty pSender.lptstrCity will
  1488. // contain the whole address
  1489. pSender->lptstrFaxNumber = AnsiStringToUnicodeString(pCoverPageA->SdrFaxNumber);
  1490. pSender->lptstrStreetAddress = AnsiStringToUnicodeString(pCoverPageA->SdrAddress);
  1491. pSender->lptstrTitle = AnsiStringToUnicodeString(pCoverPageA->SdrTitle);
  1492. pSender->lptstrOfficeLocation = AnsiStringToUnicodeString(pCoverPageA->SdrOfficeLocation);
  1493. pSender->lptstrHomePhone = AnsiStringToUnicodeString(pCoverPageA->SdrHomePhone);
  1494. pSender->lptstrOfficePhone = AnsiStringToUnicodeString(pCoverPageA->SdrOfficePhone);
  1495. pRecipient->lptstrCompany = AnsiStringToUnicodeString(pCoverPageA->RecCompany);
  1496. pRecipient->lptstrStreetAddress = AnsiStringToUnicodeString(pCoverPageA->RecStreetAddress);
  1497. pRecipient->lptstrCity = AnsiStringToUnicodeString(pCoverPageA->RecCity);
  1498. pRecipient->lptstrState = AnsiStringToUnicodeString(pCoverPageA->RecState);
  1499. pRecipient->lptstrZip = AnsiStringToUnicodeString(pCoverPageA->RecZip);
  1500. pRecipient->lptstrCountry = AnsiStringToUnicodeString(pCoverPageA->RecCountry);
  1501. pRecipient->lptstrTitle = AnsiStringToUnicodeString(pCoverPageA->RecTitle);
  1502. pRecipient->lptstrDepartment = AnsiStringToUnicodeString(pCoverPageA->RecDepartment);
  1503. pRecipient->lptstrOfficeLocation = AnsiStringToUnicodeString(pCoverPageA->RecOfficeLocation);
  1504. pRecipient->lptstrHomePhone = AnsiStringToUnicodeString(pCoverPageA->RecHomePhone);
  1505. pRecipient->lptstrOfficePhone = AnsiStringToUnicodeString(pCoverPageA->RecOfficePhone);
  1506. }
  1507. #else
  1508. pJobParamsEx->lptstrReceiptDeliveryAddress = StringDup(pJobParamsA->DeliveryReportAddress);
  1509. pJobParamsEx->lptstrDocumentName = StringDup(pJobParamsA->DocumentName);
  1510. pSender->lptstrName = StringDup(pJobParamsA->SenderName);
  1511. pSender->lptstrCompany = StringDup(pJobParamsA->SenderCompany);
  1512. pSender->lptstrDepartment = StringDup(pJobParamsA->SenderDept);
  1513. pSender->lptstrBillingCode = StringDup(pJobParamsA->BillingCode);
  1514. pRecipient->lptstrName = StringDup(pJobParamsA->RecipientName);
  1515. pRecipient->lptstrFaxNumber = StringDup(pJobParamsA->RecipientNumber);
  1516. pRecipient->lptstrTSID = StringDup(pJobParamsA->Tsid);
  1517. if(pCoverPageA)
  1518. {
  1519. pCoverPageEx->lptstrCoverPageFileName = StringDup(pCoverPageA->CoverPageName);
  1520. pCoverPageEx->lptstrNote = StringDup(pCoverPageA->Note);
  1521. pCoverPageEx->lptstrSubject = StringDup(pCoverPageA->Subject);
  1522. pSender->lptstrCity=StringDup(pCoverPageA->SdrAddress); // due to structures incopitabilty Sender.lptstrCity will
  1523. // contain the whole address
  1524. pSender->lptstrFaxNumber = StringDup(pCoverPageA->SdrFaxNumber);
  1525. pSender->lptstrStreetAddress = StringDup(pCoverPageA->SdrAddress);
  1526. pSender->lptstrTitle = StringDup(pCoverPageA->SdrTitle);
  1527. pSender->lptstrOfficeLocation = StringDup(pCoverPageA->SdrOfficeLocation);
  1528. pSender->lptstrHomePhone = StringDup(pCoverPageA->SdrHomePhone);
  1529. pSender->lptstrOfficePhone = StringDup(pCoverPageA->SdrOfficePhone);
  1530. pRecipient->lptstrCompany = StringDup(pCoverPageA->RecCompany);
  1531. pRecipient->lptstrStreetAddress = StringDup(pCoverPageA->RecStreetAddress);
  1532. pRecipient->lptstrCity = StringDup(pCoverPageA->RecCity);
  1533. pRecipient->lptstrState = StringDup(pCoverPageA->RecState);
  1534. pRecipient->lptstrZip = StringDup(pCoverPageA->RecZip);
  1535. pRecipient->lptstrCountry = StringDup(pCoverPageA->RecCountry);
  1536. pRecipient->lptstrTitle = StringDup(pCoverPageA->RecTitle);
  1537. pRecipient->lptstrDepartment = StringDup(pCoverPageA->RecDepartment);
  1538. pRecipient->lptstrOfficeLocation = StringDup(pCoverPageA->RecOfficeLocation);
  1539. pRecipient->lptstrHomePhone = StringDup(pCoverPageA->RecHomePhone);
  1540. pRecipient->lptstrOfficePhone = StringDup(pCoverPageA->RecOfficePhone);
  1541. }
  1542. #endif
  1543. return TRUE;
  1544. }
  1545. BOOL
  1546. CopyCallbackDataWideToNeutral(
  1547. PFAX_JOB_PARAMW pJobParamsW,
  1548. PFAX_COVERPAGE_INFOW pCoverPageW,
  1549. PFAX_JOB_PARAM_EX pJobParamsEx,
  1550. PFAX_COVERPAGE_INFO_EX pCoverPageEx,
  1551. PFAX_PERSONAL_PROFILE pSender,
  1552. PFAX_PERSONAL_PROFILE pRecipient
  1553. )
  1554. {
  1555. ZeroMemory(pJobParamsEx, sizeof(*pJobParamsEx));
  1556. pJobParamsEx->dwSizeOfStruct = sizeof(*pJobParamsEx);
  1557. pJobParamsEx->dwScheduleAction = pJobParamsW->ScheduleAction;
  1558. pJobParamsEx->tmSchedule = pJobParamsW->ScheduleTime;
  1559. pJobParamsEx->dwReceiptDeliveryType = pJobParamsW->DeliveryReportType;
  1560. pJobParamsEx->Priority = FAX_PRIORITY_TYPE_NORMAL;
  1561. pJobParamsEx->hCall = pJobParamsW->CallHandle;
  1562. memcpy(pJobParamsEx->dwReserved, pJobParamsW->Reserved, sizeof(pJobParamsW->Reserved));
  1563. if(pCoverPageW)
  1564. {
  1565. pJobParamsEx->dwPageCount = pCoverPageW->PageCount;
  1566. }
  1567. ZeroMemory(pCoverPageEx, sizeof(*pCoverPageEx));
  1568. pCoverPageEx->dwSizeOfStruct = sizeof(*pCoverPageEx);
  1569. pCoverPageEx->dwCoverPageFormat = FAX_COVERPAGE_FMT_COV;
  1570. if(pCoverPageW)
  1571. {
  1572. pCoverPageEx->bServerBased = pCoverPageW->UseServerCoverPage;
  1573. }
  1574. ZeroMemory(pSender, sizeof(*pSender));
  1575. pSender->dwSizeOfStruct = sizeof(*pSender);
  1576. ZeroMemory(pRecipient, sizeof(*pRecipient));
  1577. pRecipient->dwSizeOfStruct = sizeof(*pRecipient);
  1578. #ifdef UNICODE
  1579. pJobParamsEx->lptstrReceiptDeliveryAddress = StringDup(pJobParamsW->DeliveryReportAddress);
  1580. pJobParamsEx->lptstrDocumentName = StringDup(pJobParamsW->DocumentName);
  1581. pSender->lptstrName = StringDup(pJobParamsW->SenderName);
  1582. pSender->lptstrCompany = StringDup(pJobParamsW->SenderCompany);
  1583. pSender->lptstrDepartment = StringDup(pJobParamsW->SenderDept);
  1584. pSender->lptstrBillingCode = StringDup(pJobParamsW->BillingCode);
  1585. pRecipient->lptstrName = StringDup(pJobParamsW->RecipientName);
  1586. pRecipient->lptstrFaxNumber = StringDup(pJobParamsW->RecipientNumber);
  1587. pRecipient->lptstrTSID = StringDup(pJobParamsW->Tsid);
  1588. if(pCoverPageW)
  1589. {
  1590. pCoverPageEx->lptstrCoverPageFileName = StringDup(pCoverPageW->CoverPageName);
  1591. pCoverPageEx->lptstrNote = StringDup(pCoverPageW->Note);
  1592. pCoverPageEx->lptstrSubject = StringDup(pCoverPageW->Subject);
  1593. pSender->lptstrCity=StringDup(pCoverPageW->SdrAddress); // due to structures incompitabilty Sender.lptstrCity will
  1594. // contain the whole address
  1595. pSender->lptstrFaxNumber = StringDup(pCoverPageW->SdrFaxNumber);
  1596. pSender->lptstrStreetAddress = StringDup(pCoverPageW->SdrAddress);
  1597. pSender->lptstrTitle = StringDup(pCoverPageW->SdrTitle);
  1598. pSender->lptstrOfficeLocation = StringDup(pCoverPageW->SdrOfficeLocation);
  1599. pSender->lptstrHomePhone = StringDup(pCoverPageW->SdrHomePhone);
  1600. pSender->lptstrOfficePhone = StringDup(pCoverPageW->SdrOfficePhone);
  1601. pRecipient->lptstrCompany = StringDup(pCoverPageW->RecCompany);
  1602. pRecipient->lptstrStreetAddress = StringDup(pCoverPageW->RecStreetAddress);
  1603. pRecipient->lptstrCity = StringDup(pCoverPageW->RecCity);
  1604. pRecipient->lptstrState = StringDup(pCoverPageW->RecState);
  1605. pRecipient->lptstrZip = StringDup(pCoverPageW->RecZip);
  1606. pRecipient->lptstrCountry = StringDup(pCoverPageW->RecCountry);
  1607. pRecipient->lptstrTitle = StringDup(pCoverPageW->RecTitle);
  1608. pRecipient->lptstrDepartment = StringDup(pCoverPageW->RecDepartment);
  1609. pRecipient->lptstrOfficeLocation = StringDup(pCoverPageW->RecOfficeLocation);
  1610. pRecipient->lptstrHomePhone = StringDup(pCoverPageW->RecHomePhone);
  1611. pRecipient->lptstrOfficePhone = StringDup(pCoverPageW->RecOfficePhone);
  1612. }
  1613. #else
  1614. pJobParamsEx->lptstrReceiptDeliveryAddress = UnicodeStringToAnsiString(pJobParamsW->DeliveryReportAddress);
  1615. pJobParamsEx->lptstrDocumentName = UnicodeStringToAnsiString(pJobParamsW->DocumentName);
  1616. pSender->lptstrName = UnicodeStringToAnsiString(pJobParamsW->SenderName);
  1617. pSender->lptstrCompany = UnicodeStringToAnsiString(pJobParamsW->SenderCompany);
  1618. pSender->lptstrDepartment = UnicodeStringToAnsiString(pJobParamsW->SenderDept);
  1619. pSender->lptstrBillingCode = UnicodeStringToAnsiString(pJobParamsW->BillingCode);
  1620. pRecipient->lptstrName = UnicodeStringToAnsiString(pJobParamsW->RecipientName);
  1621. pRecipient->lptstrFaxNumber = UnicodeStringToAnsiString(pJobParamsW->RecipientNumber);
  1622. pRecipient->lptstrTSID = UnicodeStringToAnsiString(pJobParamsW->Tsid);
  1623. if(pCoverPageW)
  1624. {
  1625. pCoverPageEx->lptstrCoverPageFileName = UnicodeStringToAnsiString(pCoverPageW->CoverPageName);
  1626. pCoverPageEx->lptstrNote = UnicodeStringToAnsiString(pCoverPageW->Note);
  1627. pCoverPageEx->lptstrSubject = UnicodeStringToAnsiString(pCoverPageW->Subject);
  1628. pSender->lptstrCity=UnicodeStringToAnsiString(pCoverPageW->SdrAddress);
  1629. pSender->lptstrFaxNumber = UnicodeStringToAnsiString(pCoverPageW->SdrFaxNumber);
  1630. pSender->lptstrStreetAddress = UnicodeStringToAnsiString(pCoverPageW->SdrAddress);
  1631. pSender->lptstrTitle = UnicodeStringToAnsiString(pCoverPageW->SdrTitle);
  1632. pSender->lptstrOfficeLocation = UnicodeStringToAnsiString(pCoverPageW->SdrOfficeLocation);
  1633. pSender->lptstrHomePhone = UnicodeStringToAnsiString(pCoverPageW->SdrHomePhone);
  1634. pSender->lptstrOfficePhone = UnicodeStringToAnsiString(pCoverPageW->SdrOfficePhone);
  1635. pRecipient->lptstrCompany = UnicodeStringToAnsiString(pCoverPageW->RecCompany);
  1636. pRecipient->lptstrStreetAddress = UnicodeStringToAnsiString(pCoverPageW->RecStreetAddress);
  1637. pRecipient->lptstrCity = UnicodeStringToAnsiString(pCoverPageW->RecCity);
  1638. pRecipient->lptstrState = UnicodeStringToAnsiString(pCoverPageW->RecState);
  1639. pRecipient->lptstrZip = UnicodeStringToAnsiString(pCoverPageW->RecZip);
  1640. pRecipient->lptstrCountry = UnicodeStringToAnsiString(pCoverPageW->RecCountry);
  1641. pRecipient->lptstrTitle = UnicodeStringToAnsiString(pCoverPageW->RecTitle);
  1642. pRecipient->lptstrDepartment = UnicodeStringToAnsiString(pCoverPageW->RecDepartment);
  1643. pRecipient->lptstrOfficeLocation = UnicodeStringToAnsiString(pCoverPageW->RecOfficeLocation);
  1644. pRecipient->lptstrHomePhone = UnicodeStringToAnsiString(pCoverPageW->RecHomePhone);
  1645. pRecipient->lptstrOfficePhone = UnicodeStringToAnsiString(pCoverPageW->RecOfficePhone);
  1646. }
  1647. #endif
  1648. return TRUE;
  1649. }
  1650. BOOL
  1651. FaxSendDocumentForBroadcastInternal(
  1652. IN HANDLE FaxHandle,
  1653. IN LPCWSTR FileNameW,
  1654. OUT LPDWORD FaxJobId,
  1655. BOOL AnsiCallback,
  1656. IN PFAX_RECIPIENT_CALLBACKW FaxRecipientCallbackW,
  1657. IN LPVOID Context
  1658. )
  1659. {
  1660. BOOL success = FALSE;
  1661. LPSTR FileNameA = NULL;
  1662. TCHAR ExistingFile[MAX_PATH];
  1663. DWORD dwJobId;
  1664. DWORDLONG dwlJobId;
  1665. DWORDLONG dwlParentJobId = 0;
  1666. LPTSTR FileName;
  1667. FAX_JOB_PARAMA JobParamsA;
  1668. FAX_COVERPAGE_INFOA CoverPageA;
  1669. FAX_JOB_PARAMW JobParamsW;
  1670. FAX_COVERPAGE_INFOW CoverPageW;
  1671. FAX_JOB_PARAM_EX JobParamsEx;
  1672. FAX_COVERPAGE_INFO_EX CoverPageEx;
  1673. FAX_PERSONAL_PROFILE Sender;
  1674. FAX_PERSONAL_PROFILE Recipient;
  1675. DWORD rc;
  1676. LPTSTR p;
  1677. DWORD i;
  1678. DEBUG_FUNCTION_NAME(TEXT("FaxSendDocumentForBroadcastInternal"));
  1679. //
  1680. // argument validation
  1681. //
  1682. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE))
  1683. {
  1684. SetLastError(ERROR_INVALID_HANDLE);
  1685. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  1686. goto Cleanup;
  1687. }
  1688. if(FileNameW == NULL)
  1689. {
  1690. SetLastError(ERROR_INVALID_PARAMETER);
  1691. DebugPrintEx(DEBUG_ERR, _T("FileNameW is NULL."));
  1692. goto Cleanup;
  1693. }
  1694. if(FaxRecipientCallbackW == NULL)
  1695. {
  1696. SetLastError(ERROR_INVALID_PARAMETER);
  1697. DebugPrintEx(DEBUG_ERR, _T("FaxRecipientCallbackW is NULL."));
  1698. goto Cleanup;
  1699. }
  1700. FileNameA = UnicodeStringToAnsiString(FileNameW);
  1701. if(FileNameA == NULL)
  1702. {
  1703. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1704. DebugPrintEx(DEBUG_ERR, _T("UnicodeStringToAnsiString() is failed."));
  1705. goto Cleanup;
  1706. }
  1707. #ifdef UNICODE
  1708. FileName = (LPTSTR)FileNameW;
  1709. #else
  1710. FileName = FileNameA;
  1711. #endif
  1712. // make sure the file is there
  1713. rc = GetFullPathName(FileName, sizeof(ExistingFile) / sizeof(TCHAR), ExistingFile, &p);
  1714. if(rc > MAX_PATH || rc == 0)
  1715. {
  1716. DebugPrintEx(DEBUG_ERR, TEXT("GetFullPathName failed, ec= %d\n"),GetLastError());
  1717. SetLastError( (rc > MAX_PATH)
  1718. ? ERROR_BUFFER_OVERFLOW
  1719. : GetLastError() );
  1720. goto Cleanup;
  1721. }
  1722. if(GetFileAttributes(ExistingFile)==0xFFFFFFFF)
  1723. {
  1724. SetLastError(ERROR_FILE_NOT_FOUND);
  1725. goto Cleanup;
  1726. }
  1727. for(i = 1;;i++) {
  1728. //
  1729. // prepare and execute callback
  1730. //
  1731. if(AnsiCallback)
  1732. {
  1733. ZeroMemory(&JobParamsA, sizeof(JobParamsA));
  1734. JobParamsA.SizeOfStruct = sizeof(JobParamsA);
  1735. ZeroMemory(&CoverPageA, sizeof(CoverPageA));
  1736. CoverPageA.SizeOfStruct = sizeof(CoverPageA);
  1737. if(!(*(PFAX_RECIPIENT_CALLBACKA)FaxRecipientCallbackW)(FaxHandle, i, Context, &JobParamsA, &CoverPageA))
  1738. {
  1739. break;
  1740. }
  1741. if(JobParamsA.RecipientNumber == NULL)
  1742. {
  1743. continue;
  1744. }
  1745. if(!CopyCallbackDataAnsiToNeutral(&JobParamsA, &CoverPageA, &JobParamsEx, &CoverPageEx, &Sender, &Recipient))
  1746. {
  1747. DebugPrintEx(DEBUG_ERR,
  1748. _T("CopyCallbackDataAnsiToNeutral() is failed, ec= %ld."),
  1749. GetLastError());
  1750. goto Cleanup;
  1751. }
  1752. }
  1753. else
  1754. {
  1755. ZeroMemory(&JobParamsW, sizeof(JobParamsW));
  1756. JobParamsW.SizeOfStruct = sizeof(JobParamsW);
  1757. ZeroMemory(&CoverPageW, sizeof(CoverPageW));
  1758. CoverPageW.SizeOfStruct = sizeof(CoverPageW);
  1759. if(!FaxRecipientCallbackW(FaxHandle, i, Context, &JobParamsW, &CoverPageW))
  1760. {
  1761. break;
  1762. }
  1763. if(JobParamsW.RecipientNumber == NULL)
  1764. {
  1765. continue;
  1766. }
  1767. if(!CopyCallbackDataWideToNeutral(&JobParamsW, &CoverPageW, &JobParamsEx, &CoverPageEx, &Sender, &Recipient))
  1768. {
  1769. DebugPrintEx(DEBUG_ERR,
  1770. _T("CopyCallbackDataWideToNeutral() is failed, ec= %ld."),
  1771. GetLastError());
  1772. goto Cleanup;
  1773. }
  1774. }
  1775. if(!FaxSendDocumentEx2(FaxHandle,
  1776. ExistingFile,
  1777. CoverPageEx.lptstrCoverPageFileName ? &CoverPageEx : NULL,
  1778. &Sender,
  1779. 1,
  1780. &Recipient,
  1781. &JobParamsEx,
  1782. &dwJobId,
  1783. &dwlParentJobId,
  1784. &dwlJobId))
  1785. {
  1786. DebugPrintEx(
  1787. DEBUG_ERR,
  1788. TEXT("FAX_SendDocumentEx failed with error code 0x%0x"),
  1789. GetLastError());
  1790. goto Cleanup;
  1791. }
  1792. //
  1793. // give caller FIRST job parent's ID
  1794. //
  1795. if (i == 1 && FaxJobId)
  1796. {
  1797. *FaxJobId = (DWORD)dwlParentJobId;
  1798. }
  1799. MemFree(CoverPageEx.lptstrCoverPageFileName);
  1800. MemFree(CoverPageEx.lptstrNote);
  1801. MemFree(CoverPageEx.lptstrSubject);
  1802. MemFree(JobParamsEx.lptstrReceiptDeliveryAddress);
  1803. MemFree(JobParamsEx.lptstrDocumentName);
  1804. FreePersonalProfileStrings(&Sender);
  1805. FreePersonalProfileStrings(&Recipient);
  1806. }
  1807. success = TRUE;
  1808. Cleanup:
  1809. MemFree(FileNameA);
  1810. return success;
  1811. }
  1812. #ifdef UNICODE
  1813. BOOL
  1814. WINAPI
  1815. FaxSendDocumentForBroadcastW(
  1816. IN HANDLE FaxHandle,
  1817. IN LPCWSTR FileName,
  1818. OUT LPDWORD FaxJobId,
  1819. IN PFAX_RECIPIENT_CALLBACKW FaxRecipientCallback,
  1820. IN LPVOID Context
  1821. )
  1822. {
  1823. return FaxSendDocumentForBroadcastInternal(
  1824. FaxHandle,
  1825. FileName,
  1826. FaxJobId,
  1827. FALSE,
  1828. FaxRecipientCallback,
  1829. Context);
  1830. }
  1831. #else
  1832. // Not supported on Win9x
  1833. BOOL
  1834. WINAPI
  1835. FaxSendDocumentForBroadcastW(
  1836. IN HANDLE FaxHandle,
  1837. IN LPCWSTR FileName,
  1838. OUT LPDWORD FaxJobId,
  1839. IN PFAX_RECIPIENT_CALLBACKW FaxRecipientCallback,
  1840. IN LPVOID Context
  1841. )
  1842. {
  1843. UNREFERENCED_PARAMETER(FileName);
  1844. UNREFERENCED_PARAMETER(FaxJobId);
  1845. UNREFERENCED_PARAMETER(FaxRecipientCallback);
  1846. UNREFERENCED_PARAMETER(Context);
  1847. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1848. return FALSE;
  1849. }
  1850. #endif
  1851. BOOL
  1852. WINAPI
  1853. FaxSendDocumentForBroadcastA(
  1854. IN HANDLE FaxHandle,
  1855. IN LPCSTR FileName,
  1856. OUT LPDWORD FaxJobId,
  1857. IN PFAX_RECIPIENT_CALLBACKA FaxRecipientCallback,
  1858. IN LPVOID Context
  1859. )
  1860. {
  1861. LPWSTR FileNameW = NULL;
  1862. BOOL success = FALSE;
  1863. DEBUG_FUNCTION_NAME(_T("FaxSendDocumentForBroadcastA"));
  1864. if(FileName == NULL)
  1865. {
  1866. SetLastError(ERROR_INVALID_PARAMETER);
  1867. DebugPrintEx(DEBUG_ERR, _T("FileName is NULL."));
  1868. goto Cleanup;
  1869. }
  1870. FileNameW = AnsiStringToUnicodeString(FileName);
  1871. if(FileNameW == NULL)
  1872. {
  1873. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1874. DebugPrintEx(DEBUG_ERR, _T("AnsiStringToUnicodeString() is failed."));
  1875. goto Cleanup;
  1876. }
  1877. success = FaxSendDocumentForBroadcastInternal(
  1878. FaxHandle,
  1879. FileNameW,
  1880. FaxJobId,
  1881. TRUE,
  1882. (PFAX_RECIPIENT_CALLBACKW)FaxRecipientCallback,
  1883. Context);
  1884. Cleanup:
  1885. MemFree(FileNameW);
  1886. return success;
  1887. }
  1888. BOOL
  1889. WINAPI
  1890. FaxAbort(
  1891. IN HANDLE FaxHandle,
  1892. IN DWORD JobId
  1893. )
  1894. /*++
  1895. Routine Description:
  1896. Abort the specified FAX job. All outstanding FAX
  1897. operations are terminated.
  1898. Arguments:
  1899. FaxHandle - FAX Server handle obtained from FaxConnectFaxServer.
  1900. JobId - job id.
  1901. Return Value:
  1902. TRUE - Success
  1903. FALSE - Failure, call GetLastError() for more error information.
  1904. --*/
  1905. {
  1906. error_status_t ec;
  1907. //
  1908. // argument validation
  1909. //
  1910. DEBUG_FUNCTION_NAME(TEXT("FaxAbort"));
  1911. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  1912. SetLastError(ERROR_INVALID_HANDLE);
  1913. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  1914. return FALSE;
  1915. }
  1916. __try
  1917. {
  1918. ec = FAX_Abort( (handle_t) FH_FAX_HANDLE(FaxHandle),(DWORD) JobId );
  1919. }
  1920. __except (EXCEPTION_EXECUTE_HANDLER)
  1921. {
  1922. //
  1923. // For some reason we crashed.
  1924. //
  1925. ec = GetExceptionCode();
  1926. DebugPrintEx(
  1927. DEBUG_ERR,
  1928. TEXT("Exception on RPC call to FAX_Abort. (ec: %ld)"),
  1929. ec);
  1930. }
  1931. if (ec)
  1932. {
  1933. DumpRPCExtendedStatus ();
  1934. SetLastError( ec );
  1935. DebugPrintEx(DEBUG_ERR, _T("FAX_Abort() is failed. (ec: %ld)"), ec);
  1936. return FALSE;
  1937. }
  1938. return TRUE;
  1939. }
  1940. extern "C"
  1941. BOOL
  1942. WINAPI
  1943. FaxEnumJobsW(
  1944. IN HANDLE FaxHandle,
  1945. OUT PFAX_JOB_ENTRYW *JobEntryBuffer,
  1946. OUT LPDWORD JobsReturned
  1947. )
  1948. {
  1949. PFAX_JOB_ENTRYW JobEntry;
  1950. error_status_t ec;
  1951. DWORD BufferSize = 0;
  1952. DWORD i;
  1953. DWORD Size;
  1954. DEBUG_FUNCTION_NAME(TEXT("FaxEnumJobsW"));
  1955. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  1956. SetLastError(ERROR_INVALID_HANDLE);
  1957. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  1958. return FALSE;
  1959. }
  1960. if (!JobEntryBuffer) {
  1961. SetLastError(ERROR_INVALID_PARAMETER);
  1962. DebugPrintEx(DEBUG_ERR, _T("JobEntryBuffer is NULL."));
  1963. return FALSE;
  1964. }
  1965. if (!JobsReturned) {
  1966. SetLastError(ERROR_INVALID_PARAMETER);
  1967. DebugPrintEx(DEBUG_ERR, _T("JobsReturned is NULL."));
  1968. return FALSE;
  1969. }
  1970. *JobEntryBuffer = NULL;
  1971. *JobsReturned = 0;
  1972. Size = 0;
  1973. __try
  1974. {
  1975. ec = FAX_EnumJobs( FH_FAX_HANDLE(FaxHandle), (LPBYTE*)JobEntryBuffer, &Size, JobsReturned );
  1976. }
  1977. __except (EXCEPTION_EXECUTE_HANDLER)
  1978. {
  1979. //
  1980. // For some reason we crashed.
  1981. //
  1982. ec = GetExceptionCode();
  1983. DebugPrintEx(
  1984. DEBUG_ERR,
  1985. TEXT("Exception on RPC call to FAX_EnumJobs. (ec: %ld)"),
  1986. ec);
  1987. }
  1988. if (ec)
  1989. {
  1990. DumpRPCExtendedStatus ();
  1991. SetLastError( ec );
  1992. DebugPrintEx(DEBUG_ERR, _T("FAX_EnumJobs() is failed. ec = %ld."), ec);
  1993. return FALSE;
  1994. }
  1995. JobEntry = (PFAX_JOB_ENTRYW) *JobEntryBuffer;
  1996. for (i=0; i<*JobsReturned; i++) {
  1997. FixupStringPtrW( JobEntryBuffer, JobEntry[i].UserName );
  1998. FixupStringPtrW( JobEntryBuffer, JobEntry[i].RecipientNumber );
  1999. FixupStringPtrW( JobEntryBuffer, JobEntry[i].RecipientName );
  2000. FixupStringPtrW( JobEntryBuffer, JobEntry[i].DocumentName );
  2001. FixupStringPtrW( JobEntryBuffer, JobEntry[i].Tsid );
  2002. FixupStringPtrW( JobEntryBuffer, JobEntry[i].SenderName );
  2003. FixupStringPtrW( JobEntryBuffer, JobEntry[i].SenderCompany );
  2004. FixupStringPtrW( JobEntryBuffer, JobEntry[i].SenderDept );
  2005. FixupStringPtrW( JobEntryBuffer, JobEntry[i].BillingCode );
  2006. FixupStringPtrW( JobEntryBuffer, JobEntry[i].DeliveryReportAddress );
  2007. }
  2008. return TRUE;
  2009. }
  2010. extern "C"
  2011. BOOL
  2012. WINAPI
  2013. FaxEnumJobsA(
  2014. IN HANDLE FaxHandle,
  2015. OUT PFAX_JOB_ENTRYA *JobEntryBuffer,
  2016. OUT LPDWORD JobsReturned
  2017. )
  2018. {
  2019. PFAX_JOB_ENTRYW JobEntry;
  2020. DWORD i;
  2021. DEBUG_FUNCTION_NAME(TEXT("FaxEnumJobsA"));
  2022. //
  2023. // no need to validate parameters, FaxEnumJobsW() will do that
  2024. //
  2025. if (!FaxEnumJobsW( FaxHandle, (PFAX_JOB_ENTRYW *)JobEntryBuffer, JobsReturned)) {
  2026. DebugPrintEx(DEBUG_ERR, _T("FaxEnumJobsW() is failed."));
  2027. return FALSE;
  2028. }
  2029. JobEntry = (PFAX_JOB_ENTRYW) *JobEntryBuffer;
  2030. for (i=0; i<*JobsReturned; i++)
  2031. {
  2032. if (!ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].UserName ) ||
  2033. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].RecipientNumber ) ||
  2034. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].RecipientName ) ||
  2035. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].DocumentName ) ||
  2036. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].Tsid ) ||
  2037. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].SenderName ) ||
  2038. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].SenderCompany ) ||
  2039. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].SenderDept ) ||
  2040. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].BillingCode ) ||
  2041. !ConvertUnicodeStringInPlace( (LPCWSTR) JobEntry[i].DeliveryReportAddress ))
  2042. {
  2043. DebugPrintEx(DEBUG_ERR, _T("ConvertUnicodeStringInPlace failed, ec = %ld."), GetLastError());
  2044. MemFree (*JobEntryBuffer);
  2045. return FALSE;
  2046. }
  2047. }
  2048. return TRUE;
  2049. } // FaxEnumJobsA
  2050. BOOL
  2051. WINAPI
  2052. FaxSetJobW(
  2053. IN HANDLE FaxHandle,
  2054. IN DWORD JobId,
  2055. IN DWORD Command,
  2056. IN const FAX_JOB_ENTRYW *JobEntry
  2057. )
  2058. /*++
  2059. Routine Description:
  2060. set job status information for a requested JobId
  2061. Note that this is the fax server JobId, not a spooler job ID.
  2062. Arguments:
  2063. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  2064. JobId - Fax service Job ID
  2065. Command - JC_* constant for controlling the job
  2066. JobEntry - pointer to Buffer holding the job information. This parameter is Unused
  2067. Return Value:
  2068. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  2069. --*/
  2070. {
  2071. error_status_t ec;
  2072. DEBUG_FUNCTION_NAME(TEXT("FaxSetJobW"));
  2073. //
  2074. // Validate Parameters
  2075. //
  2076. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  2077. SetLastError(ERROR_INVALID_HANDLE);
  2078. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  2079. return FALSE;
  2080. }
  2081. if (Command > JC_RESTART || Command == JC_UNKNOWN) {
  2082. SetLastError (ERROR_INVALID_PARAMETER);
  2083. DebugPrintEx(DEBUG_ERR, _T("Wrong Command."));
  2084. return FALSE;
  2085. }
  2086. __try
  2087. {
  2088. ec = FAX_SetJob( FH_FAX_HANDLE(FaxHandle), JobId, Command );
  2089. }
  2090. __except (EXCEPTION_EXECUTE_HANDLER)
  2091. {
  2092. //
  2093. // For some reason we crashed.
  2094. //
  2095. ec = GetExceptionCode();
  2096. DebugPrintEx(
  2097. DEBUG_ERR,
  2098. TEXT("Exception on RPC call to FAX_SetJob. (ec: %ld)"),
  2099. ec);
  2100. }
  2101. if (ec)
  2102. {
  2103. DumpRPCExtendedStatus ();
  2104. SetLastError( ec );
  2105. DebugPrintEx(DEBUG_ERR, _T("FAX_SetJob() is failed. (ec: %ld)"), ec);
  2106. return FALSE;
  2107. }
  2108. UNREFERENCED_PARAMETER(JobEntry);
  2109. return TRUE;
  2110. }
  2111. BOOL
  2112. WINAPI
  2113. FaxSetJobA(
  2114. IN HANDLE FaxHandle,
  2115. IN DWORD JobId,
  2116. IN DWORD Command,
  2117. IN const FAX_JOB_ENTRYA *JobEntryA
  2118. )
  2119. /*++
  2120. Routine Description:
  2121. set job status information for a requested JobId
  2122. Note that this is the fax server JobId, not a spooler job ID.
  2123. Arguments:
  2124. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  2125. JobId - Fax service Job ID
  2126. Command - JC_* constant for controlling the job
  2127. JobEntryA - pointer to Buffer holding the job information. This parameter is Unused
  2128. Return Value:
  2129. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  2130. --*/
  2131. {
  2132. error_status_t ec = 0;
  2133. DEBUG_FUNCTION_NAME(TEXT("FaxSetJobA"));
  2134. //
  2135. // No Need to Validate Parameters, because
  2136. // FaxSetJobW() will do that.
  2137. //
  2138. // The JobEntry parameter is not used by FaxSetJobW, that's why we place a hard-coded NULL.
  2139. //
  2140. if (!FaxSetJobW( FaxHandle, JobId, Command, NULL))
  2141. {
  2142. DebugPrintEx(DEBUG_ERR, _T("FAxSetJobW() is failed. (ec: %ld)"), GetLastError());
  2143. return FALSE;
  2144. }
  2145. UNREFERENCED_PARAMETER(JobEntryA);
  2146. return TRUE;
  2147. }
  2148. extern "C"
  2149. BOOL
  2150. WINAPI
  2151. FaxGetJobW(
  2152. IN HANDLE FaxHandle,
  2153. IN DWORD JobId,
  2154. IN PFAX_JOB_ENTRYW *JobEntryBuffer
  2155. )
  2156. /*++
  2157. Routine Description:
  2158. Returns job status information for a requested JobId
  2159. Note that this is the fax server JobId, not a spooler job ID.
  2160. Arguments:
  2161. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  2162. JobId - Fax service Job ID
  2163. JobEntryBuffer - Buffer to hold the job information
  2164. Return Value:
  2165. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  2166. --*/
  2167. {
  2168. error_status_t ec = 0;
  2169. PFAX_JOB_ENTRY JobEntry;
  2170. DWORD JobEntrySize = 0;
  2171. //
  2172. // parameter validation
  2173. //
  2174. DEBUG_FUNCTION_NAME(TEXT("FaxGetJobW"));
  2175. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  2176. SetLastError(ERROR_INVALID_HANDLE);
  2177. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  2178. return FALSE;
  2179. }
  2180. if (!JobEntryBuffer) {
  2181. SetLastError(ERROR_INVALID_PARAMETER);
  2182. DebugPrintEx(DEBUG_ERR, _T("JobEntryBuffer is NULL."));
  2183. return FALSE;
  2184. }
  2185. *JobEntryBuffer = NULL;
  2186. __try
  2187. {
  2188. ec = FAX_GetJob( FH_FAX_HANDLE(FaxHandle), JobId, (unsigned char **) JobEntryBuffer , &JobEntrySize );
  2189. }
  2190. __except (EXCEPTION_EXECUTE_HANDLER)
  2191. {
  2192. //
  2193. // For some reason we crashed.
  2194. //
  2195. ec = GetExceptionCode();
  2196. DebugPrintEx(
  2197. DEBUG_ERR,
  2198. TEXT("Exception on RPC call to FAX_GetJob. (ec: %ld)"),
  2199. ec);
  2200. }
  2201. if (ec)
  2202. {
  2203. DumpRPCExtendedStatus ();
  2204. SetLastError( ec );
  2205. DebugPrintEx(DEBUG_ERR, _T("FAX_GetJob() failed. (ec: %ld)"), ec);
  2206. return FALSE;
  2207. }
  2208. JobEntry = (PFAX_JOB_ENTRY) *JobEntryBuffer;
  2209. FixupStringPtr (JobEntryBuffer, JobEntry->UserName);
  2210. FixupStringPtr (JobEntryBuffer, JobEntry->RecipientNumber );
  2211. FixupStringPtr (JobEntryBuffer, JobEntry->RecipientName );
  2212. FixupStringPtr (JobEntryBuffer, JobEntry->Tsid );
  2213. FixupStringPtr (JobEntryBuffer, JobEntry->SenderName );
  2214. FixupStringPtr (JobEntryBuffer, JobEntry->SenderDept );
  2215. FixupStringPtr (JobEntryBuffer, JobEntry->SenderCompany );
  2216. FixupStringPtr (JobEntryBuffer, JobEntry->BillingCode );
  2217. FixupStringPtr (JobEntryBuffer, JobEntry->DeliveryReportAddress );
  2218. FixupStringPtr (JobEntryBuffer, JobEntry->DocumentName );
  2219. return TRUE;
  2220. }
  2221. extern "C"
  2222. BOOL
  2223. WINAPI
  2224. FaxGetJobA(
  2225. IN HANDLE FaxHandle,
  2226. IN DWORD JobId,
  2227. IN PFAX_JOB_ENTRYA *JobEntryBuffer
  2228. )
  2229. /*++
  2230. Routine Description:
  2231. Returns job status information for a requested JobId
  2232. Note that this is the fax server JobId, not a spooler job ID.
  2233. Arguments:
  2234. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  2235. JobId - Fax service Job ID
  2236. JobEntryBuffer - Buffer to hold the job information
  2237. Return Value:
  2238. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  2239. --*/
  2240. {
  2241. PFAX_JOB_ENTRYW JobEntryW;
  2242. DWORD JobEntrySize = 0;
  2243. error_status_t ec = 0;
  2244. DEBUG_FUNCTION_NAME(TEXT("FaxGetJobA"));
  2245. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  2246. SetLastError(ERROR_INVALID_HANDLE);
  2247. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  2248. return FALSE;
  2249. }
  2250. if (!JobEntryBuffer) {
  2251. SetLastError(ERROR_INVALID_PARAMETER);
  2252. DebugPrintEx(DEBUG_ERR, _T("JobEntryBuffer is NULL."));
  2253. return FALSE;
  2254. }
  2255. *JobEntryBuffer = NULL;
  2256. __try
  2257. {
  2258. ec = FAX_GetJob( FH_FAX_HANDLE(FaxHandle), JobId, (unsigned char **) JobEntryBuffer,&JobEntrySize );
  2259. }
  2260. __except (EXCEPTION_EXECUTE_HANDLER)
  2261. {
  2262. //
  2263. // For some reason we crashed.
  2264. //
  2265. ec = GetExceptionCode();
  2266. DebugPrintEx(
  2267. DEBUG_ERR,
  2268. TEXT("Exception on RPC call to FAX_GetJob. (ec: %ld)"),
  2269. ec);
  2270. }
  2271. if (ec)
  2272. {
  2273. DumpRPCExtendedStatus ();
  2274. JobEntryBuffer = NULL;
  2275. SetLastError(ec);
  2276. return FALSE;
  2277. }
  2278. //
  2279. // convert to Ansi
  2280. //
  2281. JobEntryW = (PFAX_JOB_ENTRYW) *JobEntryBuffer;
  2282. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->UserName);
  2283. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->RecipientNumber );
  2284. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->RecipientName );
  2285. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->Tsid );
  2286. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->SenderName );
  2287. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->SenderDept );
  2288. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->SenderCompany );
  2289. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->BillingCode );
  2290. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->DeliveryReportAddress );
  2291. FixupStringPtrW (JobEntryBuffer, (LPCWSTR) JobEntryW->DocumentName );
  2292. if (!ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->UserName) ||
  2293. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->RecipientNumber ) ||
  2294. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->RecipientName ) ||
  2295. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->Tsid ) ||
  2296. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->SenderName ) ||
  2297. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->SenderDept ) ||
  2298. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->SenderCompany ) ||
  2299. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->BillingCode ) ||
  2300. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->DeliveryReportAddress ) ||
  2301. !ConvertUnicodeStringInPlace( (LPCWSTR)JobEntryW->DocumentName ))
  2302. {
  2303. DebugPrintEx(DEBUG_ERR, _T("ConvertUnicodeStringInPlace failed, ec = %ld."), GetLastError());
  2304. MemFree (JobEntryW);
  2305. return FALSE;
  2306. }
  2307. (*JobEntryBuffer)->SizeOfStruct = sizeof(FAX_JOB_ENTRYA);
  2308. return TRUE;
  2309. } // FaxGetJobA
  2310. BOOL
  2311. WINAPI
  2312. FaxGetPageData(
  2313. IN HANDLE FaxHandle,
  2314. IN DWORD JobId,
  2315. OUT LPBYTE *Buffer,
  2316. OUT LPDWORD BufferSize,
  2317. OUT LPDWORD ImageWidth,
  2318. OUT LPDWORD ImageHeight
  2319. )
  2320. {
  2321. error_status_t ec;
  2322. DEBUG_FUNCTION_NAME(TEXT("FaxGetPageData"));
  2323. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  2324. SetLastError(ERROR_INVALID_HANDLE);
  2325. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  2326. return FALSE;
  2327. }
  2328. if (!Buffer || !BufferSize || !ImageWidth || !ImageHeight) {
  2329. SetLastError(ERROR_INVALID_PARAMETER);
  2330. DebugPrintEx(DEBUG_ERR, _T("Some of the parameters is NULL."));
  2331. return FALSE;
  2332. }
  2333. *Buffer = NULL;
  2334. *BufferSize = 0;
  2335. *ImageWidth = 0;
  2336. *ImageHeight = 0;
  2337. __try
  2338. {
  2339. ec = FAX_GetPageData( FH_FAX_HANDLE(FaxHandle), JobId, Buffer, BufferSize, ImageWidth, ImageHeight );
  2340. }
  2341. __except (EXCEPTION_EXECUTE_HANDLER)
  2342. {
  2343. //
  2344. // For some reason we crashed.
  2345. //
  2346. ec = GetExceptionCode();
  2347. DebugPrintEx(
  2348. DEBUG_ERR,
  2349. TEXT("Exception on RPC call to FAX_GetPageData. (ec: %ld)"),
  2350. ec);
  2351. }
  2352. if (ec)
  2353. {
  2354. DumpRPCExtendedStatus ();
  2355. SetLastError( ec );
  2356. return FALSE;
  2357. }
  2358. return TRUE;
  2359. }
  2360. #ifdef UNICODE
  2361. BOOL WINAPI FaxSendDocumentEx2A
  2362. (
  2363. IN HANDLE hFaxHandle,
  2364. IN LPCSTR lpcstrFileName,
  2365. IN LPCFAX_COVERPAGE_INFO_EXA lpcCoverPageInfo,
  2366. IN LPCFAX_PERSONAL_PROFILEA lpcSenderProfile,
  2367. IN DWORD dwNumRecipients,
  2368. IN LPCFAX_PERSONAL_PROFILEA lpcRecipientList,
  2369. IN LPCFAX_JOB_PARAM_EXA lpcJobParams,
  2370. OUT LPDWORD lpdwJobId,
  2371. OUT PDWORDLONG lpdwlMessageId,
  2372. OUT PDWORDLONG lpdwlRecipientMessageIds
  2373. )
  2374. {
  2375. DWORD ec = ERROR_SUCCESS;
  2376. LPWSTR lpwstrFileNameW = NULL;
  2377. FAX_COVERPAGE_INFO_EXW CoverpageInfoW ;
  2378. FAX_PERSONAL_PROFILEW SenderProfileW ;
  2379. PFAX_PERSONAL_PROFILEW lpRecipientListW = NULL;
  2380. FAX_JOB_PARAM_EXW JobParamsW ;
  2381. DWORD dwIndex;
  2382. DEBUG_FUNCTION_NAME(TEXT("FaxSendDocumentExA"));
  2383. ZeroMemory( &CoverpageInfoW, sizeof(FAX_COVERPAGE_INFO_EXW) );
  2384. ZeroMemory( &SenderProfileW, sizeof(FAX_PERSONAL_PROFILEW) );
  2385. ZeroMemory( &JobParamsW, sizeof(FAX_JOB_PARAM_EXW));
  2386. //
  2387. // argument validation
  2388. //
  2389. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE)) {
  2390. DebugPrintEx(
  2391. DEBUG_ERR,
  2392. TEXT("Invalid parameters: Fax handle 0x%08X is not valid."),
  2393. hFaxHandle);
  2394. ec=ERROR_INVALID_HANDLE;
  2395. goto Error;
  2396. }
  2397. if (!lpdwlMessageId || !lpdwlRecipientMessageIds)
  2398. {
  2399. DebugPrintEx(
  2400. DEBUG_ERR,
  2401. TEXT("Invalid output parameters: lpdwlMessageId = 0x%I64X, lpdwlRecipientMessageIds = 0x%I64x"),
  2402. lpdwlMessageId,
  2403. lpdwlRecipientMessageIds);
  2404. ec = ERROR_INVALID_PARAMETER;
  2405. goto Error;
  2406. }
  2407. if (lpcCoverPageInfo)
  2408. {
  2409. if (lpcCoverPageInfo->dwSizeOfStruct != sizeof(FAX_COVERPAGE_INFO_EXA)) {
  2410. DebugPrintEx(
  2411. DEBUG_ERR,
  2412. TEXT("Invalid parameters: Size of CoverpageInfo (%d) != %ld."),
  2413. lpcCoverPageInfo->dwSizeOfStruct,
  2414. sizeof(FAX_COVERPAGE_INFO_EXA));
  2415. ec=ERROR_INVALID_PARAMETER;
  2416. goto Error;
  2417. }
  2418. }
  2419. if (lpcSenderProfile)
  2420. {
  2421. if (lpcSenderProfile->dwSizeOfStruct != sizeof(FAX_PERSONAL_PROFILEA)) {
  2422. DebugPrintEx(
  2423. DEBUG_ERR,
  2424. TEXT("Invalid parameters: Size of SenderProfile (%d) != %ld."),
  2425. lpcSenderProfile->dwSizeOfStruct,
  2426. sizeof(FAX_PERSONAL_PROFILEA));
  2427. ec = ERROR_INVALID_PARAMETER;
  2428. goto Error;
  2429. }
  2430. }
  2431. if (!dwNumRecipients)
  2432. {
  2433. DebugPrintEx(
  2434. DEBUG_ERR,
  2435. TEXT("Invalid parameters: dwNumRecipients is ZERO."));
  2436. ec=ERROR_INVALID_PARAMETER;
  2437. goto Error;
  2438. }
  2439. if (!lpcRecipientList)
  2440. {
  2441. DebugPrintEx(
  2442. DEBUG_ERR,
  2443. TEXT("Invalid parameters: lpcRecipientList is NULL."));
  2444. ec=ERROR_INVALID_PARAMETER;
  2445. goto Error;
  2446. }
  2447. if (lpcJobParams)
  2448. {
  2449. if (lpcJobParams->dwSizeOfStruct != sizeof(FAX_JOB_PARAM_EXA)) {
  2450. DebugPrintEx(
  2451. DEBUG_ERR,
  2452. TEXT("Invalid parameters: Size of JobParams (%d) != %ld."),
  2453. lpcJobParams->dwSizeOfStruct,
  2454. sizeof(FAX_JOB_PARAM_EXA));
  2455. ec = ERROR_INVALID_PARAMETER;
  2456. goto Error;
  2457. }
  2458. }
  2459. for(dwIndex = 0; dwIndex < dwNumRecipients; dwIndex++)
  2460. {
  2461. if (lpcRecipientList[dwIndex].dwSizeOfStruct != sizeof(FAX_PERSONAL_PROFILEA))
  2462. {
  2463. DebugPrintEx(
  2464. DEBUG_ERR,
  2465. TEXT("Invalid parameters: Size of lpcRecipientList[%d] (%d) != %ld."),
  2466. dwIndex,
  2467. lpcRecipientList[dwIndex].dwSizeOfStruct,
  2468. sizeof(FAX_PERSONAL_PROFILEA));
  2469. ec = ERROR_INVALID_PARAMETER;
  2470. goto Error;
  2471. }
  2472. }
  2473. //
  2474. // convert input parameters
  2475. //
  2476. if (lpcstrFileName)
  2477. {
  2478. if (!(lpwstrFileNameW = AnsiStringToUnicodeString(lpcstrFileName)))
  2479. {
  2480. DebugPrintEx(
  2481. DEBUG_ERR,
  2482. TEXT("Failed to allocate memory for file name"));
  2483. ec = ERROR_NOT_ENOUGH_MEMORY;
  2484. goto Error;
  2485. }
  2486. }
  2487. if (lpcCoverPageInfo)
  2488. {
  2489. CoverpageInfoW.dwSizeOfStruct = sizeof(FAX_COVERPAGE_INFO_EXW);
  2490. CoverpageInfoW.dwCoverPageFormat = lpcCoverPageInfo->dwCoverPageFormat;
  2491. CoverpageInfoW.bServerBased = lpcCoverPageInfo->bServerBased;
  2492. if (!(CoverpageInfoW.lptstrCoverPageFileName = AnsiStringToUnicodeString ( lpcCoverPageInfo->lptstrCoverPageFileName)) && lpcCoverPageInfo->lptstrCoverPageFileName ||
  2493. !(CoverpageInfoW.lptstrNote = AnsiStringToUnicodeString ( lpcCoverPageInfo->lptstrNote )) && lpcCoverPageInfo->lptstrNote ||
  2494. !(CoverpageInfoW.lptstrSubject = AnsiStringToUnicodeString ( lpcCoverPageInfo->lptstrSubject )) && lpcCoverPageInfo->lptstrSubject)
  2495. {
  2496. DebugPrintEx(
  2497. DEBUG_ERR,
  2498. TEXT("Failed to allocate memory for Cover Page Info"));
  2499. ec = ERROR_NOT_ENOUGH_MEMORY;
  2500. goto Error;
  2501. }
  2502. }
  2503. if (lpcSenderProfile)
  2504. {
  2505. SenderProfileW.dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILEW);
  2506. if (!(SenderProfileW.lptstrName = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrName )) && lpcSenderProfile->lptstrName ||
  2507. !(SenderProfileW.lptstrFaxNumber = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrFaxNumber )) && lpcSenderProfile->lptstrFaxNumber ||
  2508. !(SenderProfileW.lptstrCompany = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrCompany )) && lpcSenderProfile->lptstrCompany ||
  2509. !(SenderProfileW.lptstrStreetAddress = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrStreetAddress )) && lpcSenderProfile->lptstrStreetAddress ||
  2510. !(SenderProfileW.lptstrCity = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrCity )) && lpcSenderProfile->lptstrCity||
  2511. !(SenderProfileW.lptstrState = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrState )) && lpcSenderProfile->lptstrState||
  2512. !(SenderProfileW.lptstrZip = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrZip )) && lpcSenderProfile->lptstrZip||
  2513. !(SenderProfileW.lptstrCountry = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrCountry )) && lpcSenderProfile->lptstrCountry ||
  2514. !(SenderProfileW.lptstrTitle = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrTitle )) && lpcSenderProfile->lptstrTitle ||
  2515. !(SenderProfileW.lptstrDepartment = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrDepartment )) && lpcSenderProfile->lptstrDepartment ||
  2516. !(SenderProfileW.lptstrOfficeLocation = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrOfficeLocation )) && lpcSenderProfile->lptstrOfficeLocation ||
  2517. !(SenderProfileW.lptstrHomePhone = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrHomePhone )) && lpcSenderProfile->lptstrHomePhone ||
  2518. !(SenderProfileW.lptstrOfficePhone = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrOfficePhone )) && lpcSenderProfile->lptstrOfficePhone ||
  2519. !(SenderProfileW.lptstrEmail = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrEmail )) && lpcSenderProfile->lptstrEmail ||
  2520. !(SenderProfileW.lptstrBillingCode = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrBillingCode )) && lpcSenderProfile->lptstrBillingCode ||
  2521. !(SenderProfileW.lptstrTSID = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrTSID )) && lpcSenderProfile->lptstrTSID)
  2522. {
  2523. DebugPrintEx(
  2524. DEBUG_ERR,
  2525. TEXT("Failed to allocate memory for Sender Profile"));
  2526. ec = ERROR_NOT_ENOUGH_MEMORY;
  2527. goto Error;
  2528. }
  2529. }
  2530. if (!(lpRecipientListW = (PFAX_PERSONAL_PROFILEW) MemAlloc(sizeof(FAX_PERSONAL_PROFILEW)*dwNumRecipients)))
  2531. {
  2532. DebugPrintEx(
  2533. DEBUG_ERR,
  2534. TEXT("Failed to allocate memory for recipient list"));
  2535. ec=ERROR_NOT_ENOUGH_MEMORY;
  2536. goto Error;
  2537. }
  2538. for(dwIndex = 0; dwIndex < dwNumRecipients; dwIndex++)
  2539. {
  2540. ZeroMemory( &lpRecipientListW[dwIndex], sizeof(FAX_PERSONAL_PROFILEW) );
  2541. lpRecipientListW[dwIndex].dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILEW);
  2542. if (!(lpRecipientListW[dwIndex].lptstrName = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrName )) && lpcRecipientList[dwIndex].lptstrName ||
  2543. !(lpRecipientListW[dwIndex].lptstrFaxNumber = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrFaxNumber )) && lpcRecipientList[dwIndex].lptstrFaxNumber ||
  2544. !(lpRecipientListW[dwIndex].lptstrCompany = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrCompany )) && lpcRecipientList[dwIndex].lptstrCompany ||
  2545. !(lpRecipientListW[dwIndex].lptstrStreetAddress = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrStreetAddress )) && lpcRecipientList[dwIndex].lptstrStreetAddress ||
  2546. !(lpRecipientListW[dwIndex].lptstrCity = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrCity )) && lpcRecipientList[dwIndex].lptstrCity ||
  2547. !(lpRecipientListW[dwIndex].lptstrState = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrState )) && lpcRecipientList[dwIndex].lptstrState ||
  2548. !(lpRecipientListW[dwIndex].lptstrZip = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrZip )) && lpcRecipientList[dwIndex].lptstrZip ||
  2549. !(lpRecipientListW[dwIndex].lptstrCountry = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrCountry )) && lpcRecipientList[dwIndex].lptstrCountry ||
  2550. !(lpRecipientListW[dwIndex].lptstrTitle = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrTitle )) && lpcRecipientList[dwIndex].lptstrTitle ||
  2551. !(lpRecipientListW[dwIndex].lptstrDepartment = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrDepartment )) && lpcRecipientList[dwIndex].lptstrDepartment ||
  2552. !(lpRecipientListW[dwIndex].lptstrOfficeLocation = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrOfficeLocation )) && lpcRecipientList[dwIndex].lptstrOfficeLocation ||
  2553. !(lpRecipientListW[dwIndex].lptstrHomePhone = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrHomePhone )) && lpcRecipientList[dwIndex].lptstrHomePhone ||
  2554. !(lpRecipientListW[dwIndex].lptstrOfficePhone = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrOfficePhone )) && lpcRecipientList[dwIndex].lptstrOfficePhone ||
  2555. !(lpRecipientListW[dwIndex].lptstrEmail = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrEmail )) && lpcRecipientList[dwIndex].lptstrEmail ||
  2556. !(lpRecipientListW[dwIndex].lptstrBillingCode = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrBillingCode )) && lpcRecipientList[dwIndex].lptstrBillingCode ||
  2557. !(lpRecipientListW[dwIndex].lptstrTSID = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrTSID )) && lpcRecipientList[dwIndex].lptstrTSID )
  2558. {
  2559. DebugPrintEx(
  2560. DEBUG_ERR,
  2561. TEXT("Failed to allocate memory for recipient list"));
  2562. ec=ERROR_NOT_ENOUGH_MEMORY;
  2563. goto Error;
  2564. }
  2565. }
  2566. if (lpcJobParams)
  2567. {
  2568. JobParamsW.dwSizeOfStruct = sizeof(FAX_JOB_PARAM_EXW);
  2569. JobParamsW.Priority = lpcJobParams->Priority;
  2570. JobParamsW.dwScheduleAction = lpcJobParams->dwScheduleAction;
  2571. JobParamsW.tmSchedule = lpcJobParams->tmSchedule;
  2572. JobParamsW.dwReceiptDeliveryType = lpcJobParams->dwReceiptDeliveryType;
  2573. JobParamsW.hCall = lpcJobParams->hCall;
  2574. JobParamsW.dwPageCount = lpcJobParams->dwPageCount;
  2575. memcpy(JobParamsW.dwReserved,lpcJobParams->dwReserved, sizeof(lpcJobParams->dwReserved));
  2576. if (!(JobParamsW.lptstrDocumentName = AnsiStringToUnicodeString ( lpcJobParams->lptstrDocumentName)) && lpcJobParams->lptstrDocumentName||
  2577. !(JobParamsW.lptstrReceiptDeliveryAddress =
  2578. AnsiStringToUnicodeString ( lpcJobParams->lptstrReceiptDeliveryAddress)) &&
  2579. lpcJobParams->lptstrReceiptDeliveryAddress)
  2580. {
  2581. DebugPrintEx(
  2582. DEBUG_ERR,
  2583. TEXT("Failed to allocate memory for job params"));
  2584. ec=ERROR_NOT_ENOUGH_MEMORY;
  2585. goto Error;
  2586. }
  2587. }
  2588. if (!FaxSendDocumentEx2W(hFaxHandle,
  2589. lpwstrFileNameW,
  2590. (lpcCoverPageInfo) ? &CoverpageInfoW : NULL,
  2591. &SenderProfileW,
  2592. dwNumRecipients,
  2593. lpRecipientListW,
  2594. &JobParamsW,
  2595. lpdwJobId,
  2596. lpdwlMessageId,
  2597. lpdwlRecipientMessageIds))
  2598. {
  2599. ec = GetLastError();
  2600. DebugPrintEx(
  2601. DEBUG_ERR,
  2602. TEXT("FaxSendDocumentExW failed. ec=0x%X"),ec);
  2603. goto Error;
  2604. }
  2605. goto Exit;
  2606. Exit:
  2607. Assert (ERROR_SUCCESS == ec);
  2608. Error:
  2609. //
  2610. // free JobParamsW
  2611. //
  2612. MemFree ( JobParamsW.lptstrDocumentName );
  2613. MemFree ( JobParamsW.lptstrReceiptDeliveryAddress );
  2614. //
  2615. // free lpRecipientListW
  2616. //
  2617. if (lpRecipientListW)
  2618. {
  2619. for(dwIndex = 0; dwIndex < dwNumRecipients; dwIndex++)
  2620. {
  2621. MemFree ( lpRecipientListW[dwIndex].lptstrName );
  2622. MemFree ( lpRecipientListW[dwIndex].lptstrFaxNumber );
  2623. MemFree ( lpRecipientListW[dwIndex].lptstrCompany );
  2624. MemFree ( lpRecipientListW[dwIndex].lptstrStreetAddress );
  2625. MemFree ( lpRecipientListW[dwIndex].lptstrCity );
  2626. MemFree ( lpRecipientListW[dwIndex].lptstrState );
  2627. MemFree ( lpRecipientListW[dwIndex].lptstrZip );
  2628. MemFree ( lpRecipientListW[dwIndex].lptstrCountry );
  2629. MemFree ( lpRecipientListW[dwIndex].lptstrTitle );
  2630. MemFree ( lpRecipientListW[dwIndex].lptstrDepartment );
  2631. MemFree ( lpRecipientListW[dwIndex].lptstrOfficeLocation );
  2632. MemFree ( lpRecipientListW[dwIndex].lptstrHomePhone );
  2633. MemFree ( lpRecipientListW[dwIndex].lptstrOfficePhone );
  2634. MemFree ( lpRecipientListW[dwIndex].lptstrEmail );
  2635. MemFree ( lpRecipientListW[dwIndex].lptstrBillingCode );
  2636. MemFree ( lpRecipientListW[dwIndex].lptstrTSID );
  2637. }
  2638. MemFree (lpRecipientListW);
  2639. }
  2640. //
  2641. // free SenderProfileW
  2642. //
  2643. MemFree ( SenderProfileW.lptstrName );
  2644. MemFree ( SenderProfileW.lptstrFaxNumber );
  2645. MemFree ( SenderProfileW.lptstrCompany );
  2646. MemFree ( SenderProfileW.lptstrStreetAddress );
  2647. MemFree ( SenderProfileW.lptstrCity );
  2648. MemFree ( SenderProfileW.lptstrState );
  2649. MemFree ( SenderProfileW.lptstrZip );
  2650. MemFree ( SenderProfileW.lptstrCountry );
  2651. MemFree ( SenderProfileW.lptstrTitle );
  2652. MemFree ( SenderProfileW.lptstrDepartment );
  2653. MemFree ( SenderProfileW.lptstrOfficeLocation );
  2654. MemFree ( SenderProfileW.lptstrHomePhone );
  2655. MemFree ( SenderProfileW.lptstrOfficePhone );
  2656. MemFree ( SenderProfileW.lptstrEmail );
  2657. MemFree ( SenderProfileW.lptstrBillingCode );
  2658. MemFree ( SenderProfileW.lptstrTSID );
  2659. //
  2660. // free CoverpageInfoW
  2661. //
  2662. MemFree( CoverpageInfoW.lptstrCoverPageFileName );
  2663. MemFree( CoverpageInfoW.lptstrNote );
  2664. MemFree( CoverpageInfoW.lptstrSubject );
  2665. //
  2666. // free file name
  2667. //
  2668. MemFree( lpwstrFileNameW );
  2669. SetLastError(ec);
  2670. return (ERROR_SUCCESS == ec);
  2671. }
  2672. #else
  2673. BOOL WINAPI FaxSendDocumentEx2W
  2674. (
  2675. IN HANDLE hFaxHandle,
  2676. IN LPCWSTR lpctstrFileName,
  2677. IN LPCFAX_COVERPAGE_INFO_EXW lpcCoverPageInfo,
  2678. IN LPCFAX_PERSONAL_PROFILEW lpcSenderProfile,
  2679. IN DWORD dwNumRecipients,
  2680. IN LPCFAX_PERSONAL_PROFILEW lpcRecipientList,
  2681. IN LPCFAX_JOB_PARAM_EXW lpcJobParams,
  2682. OUT LPDWORD lpdwJobId,
  2683. OUT PDWORDLONG lpdwlMessageId,
  2684. OUT PDWORDLONG lpdwlRecipientMessageIds
  2685. )
  2686. {
  2687. UNREFERENCED_PARAMETER(hFaxHandle);
  2688. UNREFERENCED_PARAMETER(lpctstrFileName);
  2689. UNREFERENCED_PARAMETER(lpcCoverPageInfo);
  2690. UNREFERENCED_PARAMETER(lpcSenderProfile);
  2691. UNREFERENCED_PARAMETER(dwNumRecipients);
  2692. UNREFERENCED_PARAMETER(lpcRecipientList);
  2693. UNREFERENCED_PARAMETER(lpcJobParams);
  2694. UNREFERENCED_PARAMETER(lpdwJobId);
  2695. UNREFERENCED_PARAMETER(lpdwlMessageId);
  2696. UNREFERENCED_PARAMETER(lpdwlRecipientMessageIds);
  2697. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  2698. return FALSE;
  2699. }
  2700. #endif
  2701. BOOL WINAPI FaxSendDocumentEx2
  2702. (
  2703. IN HANDLE hFaxHandle,
  2704. IN LPCTSTR lpctstrFileName,
  2705. IN LPCFAX_COVERPAGE_INFO_EX lpcCoverPageInfo,
  2706. IN LPCFAX_PERSONAL_PROFILE lpcSenderProfile,
  2707. IN DWORD dwNumRecipients,
  2708. IN LPCFAX_PERSONAL_PROFILE lpcRecipientList,
  2709. IN LPCFAX_JOB_PARAM_EX lpcJobParams,
  2710. OUT LPDWORD lpdwJobId,
  2711. OUT PDWORDLONG lpdwlMessageId,
  2712. OUT PDWORDLONG lpdwlRecipientMessageIds
  2713. )
  2714. {
  2715. LPTSTR lptstrMachineName = NULL;
  2716. LPTSTR lptstrBodyFileName=NULL; // Points to the name of the body file at the server queue directory.
  2717. // It is NULL if there is no body file.
  2718. TCHAR szQueueFileName[MAX_PATH];
  2719. DWORD ec;
  2720. FAX_JOB_PARAM_EX JobParamCopy;
  2721. FAX_COVERPAGE_INFO_EX newCoverInfo;
  2722. TCHAR szTiffFile[MAX_PATH];
  2723. LPTSTR lptstrFinalTiffFile = NULL; // Points to the fixed temporary TIFF file which is generated from the
  2724. // original body file if it is not valid.
  2725. // Points to the original body if there was no need to create a fixed TIFF.
  2726. // Will remain NULL if no body was specified.
  2727. TCHAR szQueueCoverpageFile[MAX_PATH]; // The name of the generated cover page template file in the queue dir (short name)
  2728. LPCFAX_COVERPAGE_INFO_EX lpcFinalCoverInfo=NULL; // Points to the cover page information structure to be used.
  2729. // This will be the same as lpcCoverPageInfo if the cover page is not personal.
  2730. // It will point to &newCoverInfo if the cover page is personal.
  2731. TCHAR szLocalCpFile[MAX_PATH] = {0};
  2732. DEBUG_FUNCTION_NAME(TEXT("FaxSendDocumentEx"));
  2733. memset(&JobParamCopy,0,sizeof(JobParamCopy));
  2734. //
  2735. // argument validation
  2736. //
  2737. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  2738. {
  2739. DebugPrintEx(
  2740. DEBUG_ERR,
  2741. TEXT("Invalid parameters: Fax handle 0x%08X is not valid."),
  2742. hFaxHandle);
  2743. ec=ERROR_INVALID_HANDLE;
  2744. goto Error;
  2745. }
  2746. if (!lpctstrFileName && !lpcCoverPageInfo)
  2747. {
  2748. DebugPrintEx(
  2749. DEBUG_ERR,
  2750. TEXT("Invalid parameters: Both body and coverpage info are not specified."));
  2751. ec=ERROR_INVALID_PARAMETER;
  2752. goto Error;
  2753. }
  2754. if (lpcCoverPageInfo)
  2755. {
  2756. if (lpcCoverPageInfo->dwSizeOfStruct!= sizeof(FAX_COVERPAGE_INFO_EXW))
  2757. {
  2758. DebugPrintEx(
  2759. DEBUG_ERR,
  2760. TEXT("Invalid parameters: Size of CoverpageInfo (%d) != %ld."),
  2761. lpcCoverPageInfo->dwSizeOfStruct,
  2762. sizeof(FAX_COVERPAGE_INFO_EXW));
  2763. ec=ERROR_INVALID_PARAMETER;
  2764. goto Error;
  2765. }
  2766. if (FAX_COVERPAGE_FMT_COV != lpcCoverPageInfo->dwCoverPageFormat &&
  2767. FAX_COVERPAGE_FMT_COV_SUBJECT_ONLY != lpcCoverPageInfo->dwCoverPageFormat)
  2768. {
  2769. DebugPrintEx(
  2770. DEBUG_ERR,
  2771. TEXT("Unsupported Cover Page format (%d)."),
  2772. lpcCoverPageInfo->dwCoverPageFormat);
  2773. ec=ERROR_INVALID_PARAMETER;
  2774. goto Error;
  2775. }
  2776. if (FAX_COVERPAGE_FMT_COV == lpcCoverPageInfo->dwCoverPageFormat &&
  2777. !lpcCoverPageInfo->lptstrCoverPageFileName)
  2778. {
  2779. DebugPrintEx(
  2780. DEBUG_ERR,
  2781. TEXT("Invalid parameters: CoverpageInfo->CoverPageName is NULL."));
  2782. //
  2783. // Notice: We must return ERROR_FILE_NOT_FOUND and not ERROR_INVALID_PARAMETER.
  2784. // This is because the MSDN on the legacy FaxSendDocument function explicitly
  2785. // specifies so, and this function (untimately) gets called from FaxSendDocument ().
  2786. //
  2787. ec=ERROR_FILE_NOT_FOUND;
  2788. goto Error;
  2789. }
  2790. }
  2791. if (lpcSenderProfile)
  2792. {
  2793. if (lpcSenderProfile->dwSizeOfStruct!= sizeof(FAX_PERSONAL_PROFILEW))
  2794. {
  2795. DebugPrintEx(
  2796. DEBUG_ERR,
  2797. TEXT("Invalid parameters: Size of lpcSenderProfile (%d) != %ld."),
  2798. lpcSenderProfile->dwSizeOfStruct,
  2799. sizeof(FAX_PERSONAL_PROFILEW));
  2800. ec=ERROR_INVALID_PARAMETER;
  2801. goto Error;
  2802. }
  2803. }
  2804. else
  2805. {
  2806. DebugPrintEx(DEBUG_ERR,TEXT("Invalid parameters: lpcSenderProfile is NULL."));
  2807. ec=ERROR_INVALID_PARAMETER;
  2808. goto Error;
  2809. }
  2810. if (lpcJobParams)
  2811. {
  2812. if (lpcJobParams->dwSizeOfStruct!= sizeof(FAX_JOB_PARAM_EXW))
  2813. {
  2814. DebugPrintEx(
  2815. DEBUG_ERR,
  2816. TEXT("Invalid parameters: Size of lpcJobParams (%d) != %ld."),
  2817. lpcSenderProfile->dwSizeOfStruct,
  2818. sizeof(FAX_JOB_PARAM_EXW));
  2819. ec=ERROR_INVALID_PARAMETER;
  2820. goto Error;
  2821. }
  2822. if (lpcJobParams->dwScheduleAction != JSA_NOW &&
  2823. lpcJobParams->dwScheduleAction != JSA_SPECIFIC_TIME &&
  2824. lpcJobParams->dwScheduleAction != JSA_DISCOUNT_PERIOD)
  2825. {
  2826. DebugPrintEx(
  2827. DEBUG_ERR,
  2828. TEXT("Invalid parameters: lpcJobParams->dwScheduleAction (%ld) is invalid."),
  2829. lpcJobParams->dwScheduleAction);
  2830. ec=ERROR_INVALID_PARAMETER;
  2831. goto Error;
  2832. }
  2833. if (lpcJobParams->dwReceiptDeliveryType & ~(DRT_ALL | DRT_MODIFIERS))
  2834. {
  2835. DebugPrintEx(
  2836. DEBUG_ERR,
  2837. TEXT("Invalid parameters: lpcJobParams->DeliveryReportType (%ld) is invalid."),
  2838. lpcJobParams->dwReceiptDeliveryType);
  2839. ec=ERROR_INVALID_PARAMETER;
  2840. goto Error;
  2841. }
  2842. if (((lpcJobParams->dwReceiptDeliveryType & ~DRT_MODIFIERS) != DRT_NONE) &&
  2843. ((lpcJobParams->dwReceiptDeliveryType & ~DRT_MODIFIERS) != DRT_EMAIL) &&
  2844. ((lpcJobParams->dwReceiptDeliveryType & ~DRT_MODIFIERS) != DRT_MSGBOX)
  2845. )
  2846. {
  2847. DebugPrintEx(
  2848. DEBUG_ERR,
  2849. TEXT("Invalid parameters: lpcJobParams->DeliveryReportType (%ld) has invalid values combination."),
  2850. lpcJobParams->dwReceiptDeliveryType);
  2851. ec=ERROR_INVALID_PARAMETER;
  2852. goto Error;
  2853. }
  2854. }
  2855. else
  2856. {
  2857. DebugPrintEx(
  2858. DEBUG_ERR,
  2859. TEXT("Invalid parameters: lpcJobParams is NULL"));
  2860. ec=ERROR_INVALID_PARAMETER;
  2861. goto Error;
  2862. }
  2863. if (lpctstrFileName)
  2864. {
  2865. TCHAR szExistingFile[MAX_PATH];
  2866. DWORD rc;
  2867. LPTSTR p;
  2868. DWORD dwFileSize;
  2869. HANDLE hLocalFile = INVALID_HANDLE_VALUE;
  2870. //
  2871. // make sure the file is there
  2872. //
  2873. rc = GetFullPathName(lpctstrFileName,sizeof(szExistingFile)/sizeof(TCHAR),szExistingFile,&p);
  2874. if (rc > MAX_PATH || rc == 0)
  2875. {
  2876. DebugPrintEx(
  2877. DEBUG_ERR,
  2878. TEXT("GetFullPathName failed, ec= %d\n"),
  2879. GetLastError() );
  2880. ec=(rc > MAX_PATH) ? ERROR_INVALID_PARAMETER : GetLastError() ;
  2881. goto Error;
  2882. }
  2883. if (GetFileAttributes(szExistingFile) == 0xFFFFFFFF)
  2884. {
  2885. DebugPrintEx(
  2886. DEBUG_ERR,
  2887. TEXT("GetFileAttributes for %ws failed (ec= %d)."),
  2888. szExistingFile,
  2889. GetLastError() );
  2890. ec=ERROR_FILE_NOT_FOUND;
  2891. goto Error;
  2892. }
  2893. //
  2894. // Check file size is non-zero and make sure it is not a device
  2895. // Try to open file
  2896. //
  2897. hLocalFile = SafeCreateFile (
  2898. szExistingFile,
  2899. GENERIC_READ,
  2900. FILE_SHARE_READ,
  2901. NULL,
  2902. OPEN_EXISTING,
  2903. FILE_ATTRIBUTE_NORMAL,
  2904. NULL);
  2905. if ( INVALID_HANDLE_VALUE == hLocalFile )
  2906. {
  2907. ec = GetLastError ();
  2908. DebugPrintEx(
  2909. DEBUG_ERR,
  2910. TEXT("Opening %s for read failed (ec: %ld)"),
  2911. szExistingFile,
  2912. ec);
  2913. goto Error;
  2914. }
  2915. dwFileSize = GetFileSize (hLocalFile, NULL);
  2916. if (INVALID_FILE_SIZE == dwFileSize)
  2917. {
  2918. ec = GetLastError ();
  2919. DebugPrintEx(
  2920. DEBUG_ERR,
  2921. TEXT("GetFileSize failed (ec: %ld)"),
  2922. ec);
  2923. CloseHandle (hLocalFile);
  2924. goto Error;
  2925. }
  2926. CloseHandle (hLocalFile);
  2927. if (!dwFileSize)
  2928. {
  2929. //
  2930. // Zero-sized file passed to us
  2931. //
  2932. ec = ERROR_INVALID_DATA;
  2933. goto Error;
  2934. }
  2935. }
  2936. if (!dwNumRecipients)
  2937. {
  2938. DebugPrintEx(
  2939. DEBUG_ERR,
  2940. TEXT("Invalid parameters: dwNumRecipients is ZERO."));
  2941. ec=ERROR_INVALID_PARAMETER;
  2942. goto Error;
  2943. }
  2944. lptstrMachineName = IsLocalFaxConnection(hFaxHandle) ? NULL : FH_DATA(hFaxHandle)->MachineName;
  2945. // let's check if its allowed to use personal coverpages
  2946. if (lpcCoverPageInfo &&
  2947. FAX_COVERPAGE_FMT_COV == lpcCoverPageInfo->dwCoverPageFormat)
  2948. {
  2949. if (!lpcCoverPageInfo->bServerBased)
  2950. {
  2951. // the requested coverpage is personal
  2952. BOOL bPersonalCPAllowed = TRUE;
  2953. if (!FaxGetPersonalCoverPagesOption(hFaxHandle, &bPersonalCPAllowed))
  2954. {
  2955. DebugPrintEx( DEBUG_ERR,
  2956. _T("FaxGetPersonalCoverPagesOption failed with ec = %d"),
  2957. ec=GetLastError());
  2958. goto Error;
  2959. }
  2960. if (!bPersonalCPAllowed)
  2961. {
  2962. // clients must use cover pages on the server
  2963. DebugPrintEx(
  2964. DEBUG_WRN,
  2965. TEXT("The use of personal cover pages is prohibited"));
  2966. // this is returned in order to be caught by the caller
  2967. // it's unique enough to be understood
  2968. ec = ERROR_CANT_ACCESS_FILE;
  2969. goto Error;
  2970. }
  2971. }
  2972. }
  2973. if (lpcCoverPageInfo &&
  2974. FAX_COVERPAGE_FMT_COV == lpcCoverPageInfo->dwCoverPageFormat &&
  2975. !ValidateCoverpage(lpcCoverPageInfo->lptstrCoverPageFileName,
  2976. lptstrMachineName,
  2977. lpcCoverPageInfo->bServerBased,
  2978. szLocalCpFile,
  2979. ARR_SIZE(szLocalCpFile)))
  2980. {
  2981. DebugPrintEx(
  2982. DEBUG_ERR,
  2983. TEXT("ValidateCoverPage failed for %ws."),
  2984. lpcCoverPageInfo->lptstrCoverPageFileName);
  2985. ec=ERROR_FILE_NOT_FOUND;
  2986. goto Error;
  2987. }
  2988. if (lpcJobParams->hCall != 0 || lpcJobParams->dwReserved[0]==0xFFFF1234)
  2989. {
  2990. //
  2991. // Handoff is not supported
  2992. //
  2993. DebugPrintEx(DEBUG_ERR,TEXT("Invalid parameter: We do not support handoff."));
  2994. ec = ERROR_NOT_SUPPORTED;
  2995. goto Error;
  2996. }
  2997. //
  2998. // this is a normal fax...validate the fax numbers of all recipients.
  2999. //
  3000. UINT i;
  3001. for (i = 0; i < dwNumRecipients; i++)
  3002. {
  3003. if (!lpcRecipientList[i].lptstrFaxNumber)
  3004. {
  3005. DebugPrintEx(DEBUG_ERR,TEXT("Invalid parameters: recipient %ld does not have a fax number."),i);
  3006. ec=ERROR_INVALID_PARAMETER;
  3007. goto Error;
  3008. }
  3009. }
  3010. if (lpctstrFileName)
  3011. {
  3012. //
  3013. // Genereate a valid TIFF file from the body file we got if it is not valid.
  3014. // Note that CreateFinalTiffFile will return the ORIGINAL file name
  3015. // and will NOT create a new file if the original TIFF is good.
  3016. //
  3017. ZeroMemory(szTiffFile,sizeof(szTiffFile));
  3018. if (!CreateFinalTiffFile((LPTSTR)lpctstrFileName, szTiffFile, ARR_SIZE(szTiffFile), hFaxHandle)) // No cover page rendering
  3019. {
  3020. ec=GetLastError();
  3021. DebugPrintEx(
  3022. DEBUG_ERR,
  3023. TEXT("CreateFinalTiffFile for file %s has failed."),
  3024. lpctstrFileName);
  3025. goto Error;
  3026. }
  3027. lptstrFinalTiffFile = szTiffFile;
  3028. }
  3029. else
  3030. {
  3031. lptstrFinalTiffFile = NULL;
  3032. }
  3033. DebugPrintEx(
  3034. DEBUG_MSG,
  3035. TEXT("FinallTiff (body) file is %s"),
  3036. lptstrFinalTiffFile);
  3037. if (lptstrFinalTiffFile)
  3038. {
  3039. //
  3040. // copy the final body TIFF to the server's queue dir
  3041. //
  3042. HANDLE hLocalFile = INVALID_HANDLE_VALUE;
  3043. //
  3044. // Try to open local file first
  3045. //
  3046. hLocalFile = SafeCreateFile (
  3047. lptstrFinalTiffFile,
  3048. GENERIC_READ,
  3049. FILE_SHARE_READ,
  3050. NULL,
  3051. OPEN_EXISTING,
  3052. FILE_ATTRIBUTE_NORMAL,
  3053. NULL);
  3054. if ( INVALID_HANDLE_VALUE == hLocalFile )
  3055. {
  3056. ec = GetLastError ();
  3057. DebugPrintEx(
  3058. DEBUG_ERR,
  3059. TEXT("Opening %s for read failed (ec: %ld)"),
  3060. lptstrFinalTiffFile,
  3061. ec);
  3062. goto Error;
  3063. }
  3064. if (!CopyFileToServerQueue( hFaxHandle, hLocalFile, FAX_TIF_FILE_EXT, szQueueFileName, ARR_SIZE(szQueueFileName) ))
  3065. {
  3066. ec = GetLastError();
  3067. DebugPrintEx(
  3068. DEBUG_ERR,
  3069. TEXT("Failed to copy body file (%s) to queue dir."),
  3070. lptstrFinalTiffFile);
  3071. CloseHandle (hLocalFile);
  3072. goto Error;
  3073. }
  3074. CloseHandle (hLocalFile);
  3075. lptstrBodyFileName=szQueueFileName;
  3076. }
  3077. else
  3078. {
  3079. lptstrBodyFileName = NULL;
  3080. }
  3081. DebugPrintEx(
  3082. DEBUG_MSG,
  3083. TEXT("BodyFileName (after copying to server queue) is %s"),
  3084. lptstrBodyFileName);
  3085. //
  3086. // queue the fax to be sent
  3087. //
  3088. if (!CopyJobParamEx(&JobParamCopy,lpcJobParams))
  3089. {
  3090. DebugPrintEx(DEBUG_ERR,TEXT("CopyJobParamEx failed."));
  3091. ec=GetLastError();
  3092. goto Error;
  3093. }
  3094. JobParamCopy.dwReserved[0] = 0;
  3095. JobParamCopy.dwReserved[1] = 0;
  3096. JobParamCopy.dwReserved[2] = 0;
  3097. if (lpcJobParams->dwScheduleAction == JSA_SPECIFIC_TIME)
  3098. {
  3099. //
  3100. // convert the system time from local to utc
  3101. //
  3102. if (!LocalSystemTimeToSystemTime( &lpcJobParams->tmSchedule, &JobParamCopy.tmSchedule ))
  3103. {
  3104. ec=GetLastError();
  3105. DebugPrintEx(
  3106. DEBUG_ERR,
  3107. TEXT("LocalSystemTimeToSystemTime() failed. (ec: %ld)"),
  3108. ec);
  3109. goto Error;
  3110. }
  3111. }
  3112. if (lpcCoverPageInfo)
  3113. {
  3114. //
  3115. // If the cover page is a personal cover page then copy it
  3116. // to the server queue directory. This will allow the server to access it.
  3117. // Note the following rules regarding the cover page file path passed to FAX_SendDocumentEx:
  3118. // Server cover pages are specified by thier FULL path to thier location in the server. This is the
  3119. // way we get them from the client.
  3120. // Personal cover pages are copied to the QUEUE directory at the server. We then pass to the FAX_SendDocumentEx
  3121. // just thier SHORT name. The server will append the QUEUE path.
  3122. //
  3123. if (FAX_COVERPAGE_FMT_COV == lpcCoverPageInfo->dwCoverPageFormat &&
  3124. !lpcCoverPageInfo->bServerBased)
  3125. {
  3126. HANDLE hLocalFile = INVALID_HANDLE_VALUE;
  3127. BOOL bRes;
  3128. Assert(lpcCoverPageInfo->lptstrCoverPageFileName);
  3129. //
  3130. // Try to open local file first
  3131. //
  3132. hLocalFile = SafeCreateFile (
  3133. szLocalCpFile,
  3134. GENERIC_READ,
  3135. FILE_SHARE_READ,
  3136. NULL,
  3137. OPEN_EXISTING,
  3138. FILE_ATTRIBUTE_NORMAL,
  3139. NULL);
  3140. if ( INVALID_HANDLE_VALUE == hLocalFile )
  3141. {
  3142. ec = GetLastError ();
  3143. DebugPrintEx(
  3144. DEBUG_ERR,
  3145. TEXT("Opening %s for read failed (ec: %ld)"),
  3146. szLocalCpFile,
  3147. ec);
  3148. goto Error;
  3149. }
  3150. bRes = CopyFileToServerQueue( hFaxHandle,
  3151. hLocalFile,
  3152. FAX_COVER_PAGE_EXT_LETTERS,
  3153. szQueueCoverpageFile,
  3154. ARR_SIZE(szQueueCoverpageFile) );
  3155. if (!bRes)
  3156. {
  3157. ec=GetLastError();
  3158. DebugPrintEx(
  3159. DEBUG_ERR,
  3160. TEXT("Failed to copy personal cover page file (%s) to queue dir. (ec: %d)\n"),
  3161. szLocalCpFile,
  3162. ec);
  3163. CloseHandle (hLocalFile);
  3164. goto Error;
  3165. }
  3166. else
  3167. {
  3168. //
  3169. // We use newCoverInfo since we do not wish to change the input parameter
  3170. // structure (the client owns it) but we must change the cover page file path.
  3171. //
  3172. memcpy((LPVOID)&newCoverInfo,(LPVOID)lpcCoverPageInfo,sizeof(FAX_COVERPAGE_INFO_EXW));
  3173. newCoverInfo.lptstrCoverPageFileName=szQueueCoverpageFile;
  3174. DebugPrintEx(
  3175. DEBUG_MSG,
  3176. TEXT("Personal cover page file (%s) copied to (%s)."),
  3177. lpcCoverPageInfo->lptstrCoverPageFileName,
  3178. szQueueCoverpageFile);
  3179. }
  3180. CloseHandle (hLocalFile);
  3181. lpcFinalCoverInfo=&newCoverInfo;
  3182. }
  3183. else
  3184. {
  3185. lpcFinalCoverInfo=lpcCoverPageInfo;
  3186. DebugPrintEx(
  3187. DEBUG_MSG,
  3188. TEXT("A server cover page (%s) is specified. Do not copy to queue dir."),
  3189. lpcCoverPageInfo->lptstrCoverPageFileName);
  3190. }
  3191. }
  3192. else
  3193. {
  3194. //
  3195. // In case of no cover page we send a cover page information structure with
  3196. // everything set to null including the path to the file name.
  3197. // The fax service code checks that the file name is not NULL
  3198. // to determine if a cover page is specified or not.
  3199. //
  3200. memset((LPVOID)&newCoverInfo,0,sizeof(FAX_COVERPAGE_INFO_EXW));
  3201. lpcFinalCoverInfo=&newCoverInfo;
  3202. }
  3203. __try
  3204. {
  3205. #ifndef UNICODE
  3206. //
  3207. // Need to convert ANSI parameters to Unicode and Back
  3208. //
  3209. ec=FAX_SendDocumentEx_A(FH_FAX_HANDLE(hFaxHandle),
  3210. lptstrBodyFileName,
  3211. lpcFinalCoverInfo,
  3212. lpcSenderProfile,
  3213. dwNumRecipients,
  3214. lpcRecipientList,
  3215. &JobParamCopy,
  3216. lpdwJobId,
  3217. lpdwlMessageId,
  3218. lpdwlRecipientMessageIds);
  3219. #else
  3220. ec=FAX_SendDocumentEx(FH_FAX_HANDLE(hFaxHandle),
  3221. lptstrBodyFileName,
  3222. lpcFinalCoverInfo,
  3223. lpcSenderProfile,
  3224. dwNumRecipients,
  3225. lpcRecipientList,
  3226. &JobParamCopy,
  3227. lpdwJobId,
  3228. lpdwlMessageId,
  3229. lpdwlRecipientMessageIds);
  3230. #endif
  3231. }
  3232. __except (EXCEPTION_EXECUTE_HANDLER)
  3233. {
  3234. //
  3235. // For some reason we got an exception.
  3236. //
  3237. ec = GetExceptionCode();
  3238. DebugPrintEx(
  3239. DEBUG_ERR,
  3240. TEXT("Exception on RPC call to FAX_SendDocumentEx. (ec: %ld)"),
  3241. ec);
  3242. }
  3243. if (ERROR_SUCCESS!=ec)
  3244. {
  3245. DumpRPCExtendedStatus ();
  3246. DebugPrintEx(
  3247. DEBUG_ERR,
  3248. TEXT("FAX_SendDocumentEx failed with error code 0x%0x"),
  3249. ec);
  3250. goto Error;
  3251. }
  3252. DebugPrintEx(
  3253. DEBUG_MSG,
  3254. TEXT("FAX_SendDocumentEx succeeded. Parent Job Id = 0x%I64x."),
  3255. *lpdwlMessageId);
  3256. //
  3257. // we're done if it's a normal call
  3258. //
  3259. ec=ERROR_SUCCESS;
  3260. goto Exit;
  3261. Error:
  3262. Exit:
  3263. FreeJobParamEx(&JobParamCopy,FALSE);
  3264. //
  3265. // Delete the Temp Final Tiff file.
  3266. //
  3267. if (lptstrFinalTiffFile)
  3268. {
  3269. if (_tcscmp(lptstrFinalTiffFile,lpctstrFileName))
  3270. {
  3271. //
  3272. // We delete the final tiff file only if it is not the original TIFF file (i.e.
  3273. // a temp file was really created). We DO NOT want to delete the user provided
  3274. // body file !!!
  3275. //
  3276. DebugPrintEx(
  3277. DEBUG_MSG,
  3278. TEXT("Deleting temporary Final Tiff file %s"),
  3279. lptstrFinalTiffFile);
  3280. if (!DeleteFile(lptstrFinalTiffFile))
  3281. {
  3282. DebugPrintEx(
  3283. DEBUG_ERR,
  3284. TEXT("Failed to delete Final Tiff file %s (ec: %ld)"),
  3285. lptstrFinalTiffFile,
  3286. GetLastError());
  3287. }
  3288. }
  3289. }
  3290. //
  3291. // Note that FAX_SendDocumentEx will take care of deleting the cover page template
  3292. // in case there was an error. We make sure we copy the cover page just before calling
  3293. // FAX_SendDocumentEx, thus we do not need to delete the cover page template in this
  3294. // function.
  3295. //
  3296. SetLastError(ec);
  3297. return (ERROR_SUCCESS == ec);
  3298. } // FaxSendDocumentEx2
  3299. BOOL CopyJobParamEx(PFAX_JOB_PARAM_EX lpDst,LPCFAX_JOB_PARAM_EX lpcSrc)
  3300. {
  3301. DEBUG_FUNCTION_NAME(TEXT("CopyJobParamEx"));
  3302. Assert(lpDst);
  3303. Assert(lpcSrc);
  3304. memcpy(lpDst,lpcSrc,sizeof(FAX_JOB_PARAM_EXW));
  3305. if (lpcSrc->lptstrReceiptDeliveryAddress)
  3306. {
  3307. lpDst->lptstrReceiptDeliveryAddress =
  3308. StringDup(lpcSrc->lptstrReceiptDeliveryAddress);
  3309. if (!lpDst->lptstrReceiptDeliveryAddress)
  3310. {
  3311. return FALSE;
  3312. }
  3313. }
  3314. if (lpcSrc->lptstrDocumentName)
  3315. {
  3316. lpDst->lptstrDocumentName=StringDup(lpcSrc->lptstrDocumentName);
  3317. if (!lpDst->lptstrDocumentName)
  3318. {
  3319. MemFree(lpDst->lptstrReceiptDeliveryAddress);
  3320. return FALSE;
  3321. }
  3322. }
  3323. return TRUE;
  3324. }
  3325. void FreeJobParamEx(PFAX_JOB_PARAM_EX lpJobParamEx,BOOL bDestroy)
  3326. {
  3327. Assert(lpJobParamEx);
  3328. MemFree(lpJobParamEx->lptstrReceiptDeliveryAddress);
  3329. MemFree(lpJobParamEx->lptstrDocumentName);
  3330. if (bDestroy) {
  3331. MemFree(lpJobParamEx);
  3332. }
  3333. }
  3334. #ifndef UNICODE
  3335. FaxGetRecipientInfoX (
  3336. IN HANDLE hFaxHandle,
  3337. IN DWORDLONG dwlMessageId,
  3338. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3339. OUT PFAX_PERSONAL_PROFILEW *lppPersonalProfile
  3340. )
  3341. {
  3342. UNREFERENCED_PARAMETER (hFaxHandle);
  3343. UNREFERENCED_PARAMETER (dwlMessageId);
  3344. UNREFERENCED_PARAMETER (Folder);
  3345. UNREFERENCED_PARAMETER (lppPersonalProfile);
  3346. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  3347. return FALSE;
  3348. }
  3349. #endif
  3350. BOOL
  3351. FaxGetRecipientInfoW (
  3352. IN HANDLE hFaxHandle,
  3353. IN DWORDLONG dwlMessageId,
  3354. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3355. OUT PFAX_PERSONAL_PROFILEW *lppPersonalProfile
  3356. )
  3357. /*++
  3358. Routine Description:
  3359. Returns the recipient FAX_PERSONAL_PROFILE structure of the specified recipient job.
  3360. Arguments:
  3361. hFaxHandle - FAX handle obtained from FaxConnectFaxServer
  3362. dwRecipientId - Unique number that identifies a queueud
  3363. or active fax recipient job.
  3364. lppPersonalProfile - Pointer to the adress of a FAX_PERSONAL_PROFILE structure
  3365. to recieve the specified recipient info.
  3366. Return Value:
  3367. Non Zero for success, otherwise a WIN32 error code.
  3368. --*/
  3369. {
  3370. return FaxGetPersonalProfileInfoW (hFaxHandle,
  3371. dwlMessageId,
  3372. Folder,
  3373. RECIPIENT_PERSONAL_PROF,
  3374. lppPersonalProfile);
  3375. }
  3376. BOOL
  3377. FaxGetRecipientInfoA (
  3378. IN HANDLE hFaxHandle,
  3379. IN DWORDLONG dwlMessageId,
  3380. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3381. OUT PFAX_PERSONAL_PROFILEA *lppPersonalProfile
  3382. )
  3383. {
  3384. return FaxGetPersonalProfileInfoA (hFaxHandle,
  3385. dwlMessageId,
  3386. Folder,
  3387. RECIPIENT_PERSONAL_PROF,
  3388. lppPersonalProfile);
  3389. }
  3390. #ifndef UNICODE
  3391. FaxGetSenderInfoX (
  3392. IN HANDLE hFaxHandle,
  3393. IN DWORDLONG dwlMessageId,
  3394. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3395. OUT PFAX_PERSONAL_PROFILEW *lppPersonalProfile
  3396. )
  3397. {
  3398. UNREFERENCED_PARAMETER (hFaxHandle);
  3399. UNREFERENCED_PARAMETER (dwlMessageId);
  3400. UNREFERENCED_PARAMETER (Folder);
  3401. UNREFERENCED_PARAMETER (lppPersonalProfile);
  3402. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  3403. return FALSE;
  3404. }
  3405. #endif
  3406. BOOL
  3407. FaxGetSenderInfoW (
  3408. IN HANDLE hFaxHandle,
  3409. IN DWORDLONG dwlMessageId,
  3410. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3411. OUT PFAX_PERSONAL_PROFILEW *lppPersonalProfile
  3412. )
  3413. /*++
  3414. Routine Description:
  3415. Returns the sender FAX_PERSONAL_PROFILE structure of the specified recipient job.
  3416. Arguments:
  3417. hFaxHandle - FAX handle obtained from FaxConnectFaxServer
  3418. dwSenderId - Unique number that identifies a queueud
  3419. or active fax recipient job.
  3420. lppPersonalProfile - Pointer to the adress of a FAX_PERSONAL_PROFILE structure
  3421. to recieve the specified sender info.
  3422. Return Value:
  3423. Non Zero for success, otherwise a WIN32 error code.
  3424. --*/
  3425. {
  3426. return FaxGetPersonalProfileInfoW (hFaxHandle,
  3427. dwlMessageId,
  3428. Folder,
  3429. SENDER_PERSONAL_PROF,
  3430. lppPersonalProfile);
  3431. }
  3432. BOOL
  3433. FaxGetSenderInfoA (
  3434. IN HANDLE hFaxHandle,
  3435. IN DWORDLONG dwlMessageId,
  3436. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3437. OUT PFAX_PERSONAL_PROFILEA *lppPersonalProfile
  3438. )
  3439. {
  3440. return FaxGetPersonalProfileInfoA (hFaxHandle,
  3441. dwlMessageId,
  3442. Folder,
  3443. SENDER_PERSONAL_PROF,
  3444. lppPersonalProfile);
  3445. }
  3446. static BOOL
  3447. FaxGetPersonalProfileInfoW (
  3448. IN HANDLE hFaxHandle,
  3449. IN DWORDLONG dwlMessageId,
  3450. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3451. IN FAX_ENUM_PERSONAL_PROF_TYPES ProfType,
  3452. OUT PFAX_PERSONAL_PROFILEW *lppPersonalProfile
  3453. )
  3454. {
  3455. error_status_t ec;
  3456. DWORD dwBufferSize = 0;
  3457. LPBYTE Buffer = NULL;
  3458. PFAX_PERSONAL_PROFILEW lpPersoProf;
  3459. DEBUG_FUNCTION_NAME(TEXT("FaxGetPersonalProfileInfoW"));
  3460. Assert (lppPersonalProfile);
  3461. Assert (RECIPIENT_PERSONAL_PROF == ProfType ||
  3462. SENDER_PERSONAL_PROF == ProfType);
  3463. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  3464. {
  3465. SetLastError(ERROR_INVALID_HANDLE);
  3466. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  3467. return FALSE;
  3468. }
  3469. if (FAX_MESSAGE_FOLDER_SENTITEMS != Folder &&
  3470. FAX_MESSAGE_FOLDER_QUEUE != Folder)
  3471. {
  3472. SetLastError(ERROR_INVALID_PARAMETER);
  3473. DebugPrintEx(DEBUG_ERR, _T("Wrong Folder."));
  3474. return FALSE;
  3475. }
  3476. //
  3477. // Call RPC function.
  3478. //
  3479. __try
  3480. {
  3481. ec = FAX_GetPersonalProfileInfo (FH_FAX_HANDLE(hFaxHandle),
  3482. dwlMessageId,
  3483. Folder,
  3484. ProfType,
  3485. &Buffer,
  3486. &dwBufferSize
  3487. );
  3488. }
  3489. __except (EXCEPTION_EXECUTE_HANDLER)
  3490. {
  3491. //
  3492. // For some reason we got an exception.
  3493. //
  3494. ec = GetExceptionCode();
  3495. DebugPrintEx(
  3496. DEBUG_ERR,
  3497. TEXT("Exception on RPC call to FAX_GetRecipientInfo. (ec: %ld)"),
  3498. ec);
  3499. }
  3500. if (ERROR_SUCCESS != ec)
  3501. {
  3502. DumpRPCExtendedStatus ();
  3503. SetLastError( ec );
  3504. return FALSE;
  3505. }
  3506. *lppPersonalProfile = (PFAX_PERSONAL_PROFILEW)Buffer;
  3507. //
  3508. // Unpack Buffer
  3509. //
  3510. lpPersoProf = (PFAX_PERSONAL_PROFILEW) *lppPersonalProfile;
  3511. Assert(lpPersoProf);
  3512. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrName );
  3513. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrFaxNumber );
  3514. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrCompany );
  3515. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrStreetAddress );
  3516. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrCity );
  3517. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrState );
  3518. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrZip );
  3519. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrCountry );
  3520. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrTitle );
  3521. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrDepartment );
  3522. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrOfficeLocation );
  3523. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrHomePhone );
  3524. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrOfficePhone );
  3525. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrEmail );
  3526. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrBillingCode );
  3527. FixupStringPtrW( &lpPersoProf, lpPersoProf->lptstrTSID );
  3528. return TRUE;
  3529. }
  3530. static BOOL
  3531. FaxGetPersonalProfileInfoA (
  3532. IN HANDLE hFaxHandle,
  3533. IN DWORDLONG dwlMessageId,
  3534. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  3535. IN FAX_ENUM_PERSONAL_PROF_TYPES ProfType,
  3536. OUT PFAX_PERSONAL_PROFILEA *lppPersonalProfile
  3537. )
  3538. {
  3539. DEBUG_FUNCTION_NAME(TEXT("FaxGetPersonalProfileInfoA"));
  3540. if (!FaxGetPersonalProfileInfoW(
  3541. hFaxHandle,
  3542. dwlMessageId,
  3543. Folder,
  3544. ProfType,
  3545. (PFAX_PERSONAL_PROFILEW*) lppPersonalProfile
  3546. ))
  3547. {
  3548. return FALSE;
  3549. }
  3550. if (!ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrName ) ||
  3551. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrFaxNumber ) ||
  3552. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrStreetAddress ) ||
  3553. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrCity ) ||
  3554. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrState ) ||
  3555. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrZip ) ||
  3556. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrCountry ) ||
  3557. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrCompany ) ||
  3558. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrTitle ) ||
  3559. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrDepartment ) ||
  3560. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrOfficeLocation )||
  3561. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrHomePhone ) ||
  3562. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrOfficePhone ) ||
  3563. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrEmail ) ||
  3564. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrBillingCode ) ||
  3565. !ConvertUnicodeStringInPlace( (LPWSTR) (*lppPersonalProfile)->lptstrTSID ))
  3566. {
  3567. DebugPrintEx(DEBUG_ERR, _T("ConvertUnicodeStringInPlace failed, ec = %ld."), GetLastError());
  3568. MemFree (*lppPersonalProfile);
  3569. return FALSE;
  3570. }
  3571. (*lppPersonalProfile)->dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILEA);
  3572. return TRUE;
  3573. } // FaxGetPersonalProfileInfoA
  3574. DWORD WINAPI FAX_SendDocumentEx_A
  3575. (
  3576. IN handle_t hBinding,
  3577. IN LPCSTR lpcstrFileName,
  3578. IN LPCFAX_COVERPAGE_INFO_EXA lpcCoverPageInfo,
  3579. IN LPCFAX_PERSONAL_PROFILEA lpcSenderProfile,
  3580. IN DWORD dwNumRecipients,
  3581. IN LPCFAX_PERSONAL_PROFILEA lpcRecipientList,
  3582. IN LPCFAX_JOB_PARAM_EXA lpcJobParams,
  3583. OUT LPDWORD lpdwJobId,
  3584. OUT PDWORDLONG lpdwlMessageId,
  3585. OUT PDWORDLONG lpdwlRecipientMessageIds
  3586. )
  3587. {
  3588. DWORD ec = ERROR_SUCCESS;
  3589. LPWSTR lpwstrFileNameW = NULL;
  3590. FAX_COVERPAGE_INFO_EXW CoverpageInfoW ;
  3591. FAX_PERSONAL_PROFILEW SenderProfileW ;
  3592. PFAX_PERSONAL_PROFILEW lpRecipientListW = NULL;
  3593. FAX_JOB_PARAM_EXW JobParamsW ;
  3594. DWORD dwIndex;
  3595. DEBUG_FUNCTION_NAME(TEXT("FAX_SendDocumentEx2_A"));
  3596. ZeroMemory( &CoverpageInfoW, sizeof(FAX_COVERPAGE_INFO_EXW) );
  3597. ZeroMemory( &SenderProfileW, sizeof(FAX_PERSONAL_PROFILEW) );
  3598. ZeroMemory( &JobParamsW, sizeof(FAX_JOB_PARAM_EXW));
  3599. //
  3600. // convert input parameters
  3601. //
  3602. if (lpcstrFileName)
  3603. {
  3604. if (!(lpwstrFileNameW = AnsiStringToUnicodeString(lpcstrFileName)))
  3605. {
  3606. DebugPrintEx(
  3607. DEBUG_ERR,
  3608. TEXT("Failed to allocate memory for file name"));
  3609. ec = ERROR_NOT_ENOUGH_MEMORY;
  3610. goto Error;
  3611. }
  3612. }
  3613. if (lpcCoverPageInfo)
  3614. {
  3615. CoverpageInfoW.dwSizeOfStruct = sizeof(FAX_COVERPAGE_INFO_EXW);
  3616. CoverpageInfoW.dwCoverPageFormat = lpcCoverPageInfo->dwCoverPageFormat;
  3617. CoverpageInfoW.bServerBased = lpcCoverPageInfo->bServerBased;
  3618. if (!(CoverpageInfoW.lptstrCoverPageFileName = AnsiStringToUnicodeString ( lpcCoverPageInfo->lptstrCoverPageFileName)) && lpcCoverPageInfo->lptstrCoverPageFileName ||
  3619. !(CoverpageInfoW.lptstrNote = AnsiStringToUnicodeString ( lpcCoverPageInfo->lptstrNote )) && lpcCoverPageInfo->lptstrNote ||
  3620. !(CoverpageInfoW.lptstrSubject = AnsiStringToUnicodeString ( lpcCoverPageInfo->lptstrSubject )) && lpcCoverPageInfo->lptstrSubject)
  3621. {
  3622. DebugPrintEx(
  3623. DEBUG_ERR,
  3624. TEXT("Failed to allocate memory for Cover Page Info"));
  3625. ec = ERROR_NOT_ENOUGH_MEMORY;
  3626. goto Error;
  3627. }
  3628. }
  3629. if (lpcSenderProfile)
  3630. {
  3631. SenderProfileW.dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILEW);
  3632. if (!(SenderProfileW.lptstrName = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrName )) && lpcSenderProfile->lptstrName ||
  3633. !(SenderProfileW.lptstrFaxNumber = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrFaxNumber )) && lpcSenderProfile->lptstrFaxNumber ||
  3634. !(SenderProfileW.lptstrCompany = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrCompany )) && lpcSenderProfile->lptstrCompany ||
  3635. !(SenderProfileW.lptstrStreetAddress = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrStreetAddress )) && lpcSenderProfile->lptstrStreetAddress ||
  3636. !(SenderProfileW.lptstrCity = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrCity )) && lpcSenderProfile->lptstrCity||
  3637. !(SenderProfileW.lptstrState = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrState )) && lpcSenderProfile->lptstrState||
  3638. !(SenderProfileW.lptstrZip = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrZip )) && lpcSenderProfile->lptstrZip||
  3639. !(SenderProfileW.lptstrCountry = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrCountry )) && lpcSenderProfile->lptstrCountry ||
  3640. !(SenderProfileW.lptstrTitle = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrTitle )) && lpcSenderProfile->lptstrTitle ||
  3641. !(SenderProfileW.lptstrDepartment = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrDepartment )) && lpcSenderProfile->lptstrDepartment ||
  3642. !(SenderProfileW.lptstrOfficeLocation = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrOfficeLocation )) && lpcSenderProfile->lptstrOfficeLocation ||
  3643. !(SenderProfileW.lptstrHomePhone = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrHomePhone )) && lpcSenderProfile->lptstrHomePhone ||
  3644. !(SenderProfileW.lptstrOfficePhone = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrOfficePhone )) && lpcSenderProfile->lptstrOfficePhone ||
  3645. !(SenderProfileW.lptstrEmail = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrEmail )) && lpcSenderProfile->lptstrEmail ||
  3646. !(SenderProfileW.lptstrBillingCode = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrBillingCode )) && lpcSenderProfile->lptstrBillingCode ||
  3647. !(SenderProfileW.lptstrTSID = AnsiStringToUnicodeString ( lpcSenderProfile->lptstrTSID )) && lpcSenderProfile->lptstrTSID)
  3648. {
  3649. DebugPrintEx(
  3650. DEBUG_ERR,
  3651. TEXT("Failed to allocate memory for Sender Profile"));
  3652. ec = ERROR_NOT_ENOUGH_MEMORY;
  3653. goto Error;
  3654. }
  3655. }
  3656. if (!(lpRecipientListW = (PFAX_PERSONAL_PROFILEW)MemAlloc(sizeof(FAX_PERSONAL_PROFILEW)*dwNumRecipients)))
  3657. {
  3658. DebugPrintEx(
  3659. DEBUG_ERR,
  3660. TEXT("Failed to allocate memory for recipient list"));
  3661. ec=ERROR_NOT_ENOUGH_MEMORY;
  3662. goto Error;
  3663. }
  3664. for(dwIndex = 0; dwIndex < dwNumRecipients; dwIndex++)
  3665. {
  3666. ZeroMemory( &lpRecipientListW[dwIndex], sizeof(FAX_PERSONAL_PROFILEW) );
  3667. lpRecipientListW[dwIndex].dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILEW);
  3668. if (!(lpRecipientListW[dwIndex].lptstrName = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrName )) && lpcRecipientList[dwIndex].lptstrName ||
  3669. !(lpRecipientListW[dwIndex].lptstrFaxNumber = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrFaxNumber )) && lpcRecipientList[dwIndex].lptstrFaxNumber ||
  3670. !(lpRecipientListW[dwIndex].lptstrCompany = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrCompany )) && lpcRecipientList[dwIndex].lptstrCompany ||
  3671. !(lpRecipientListW[dwIndex].lptstrStreetAddress = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrStreetAddress )) && lpcRecipientList[dwIndex].lptstrStreetAddress ||
  3672. !(lpRecipientListW[dwIndex].lptstrCity = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrCity )) && lpcRecipientList[dwIndex].lptstrCity ||
  3673. !(lpRecipientListW[dwIndex].lptstrState = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrState )) && lpcRecipientList[dwIndex].lptstrState ||
  3674. !(lpRecipientListW[dwIndex].lptstrZip = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrZip )) && lpcRecipientList[dwIndex].lptstrZip ||
  3675. !(lpRecipientListW[dwIndex].lptstrCountry = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrCountry )) && lpcRecipientList[dwIndex].lptstrCountry ||
  3676. !(lpRecipientListW[dwIndex].lptstrTitle = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrTitle )) && lpcRecipientList[dwIndex].lptstrTitle ||
  3677. !(lpRecipientListW[dwIndex].lptstrDepartment = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrDepartment )) && lpcRecipientList[dwIndex].lptstrDepartment ||
  3678. !(lpRecipientListW[dwIndex].lptstrOfficeLocation = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrOfficeLocation )) && lpcRecipientList[dwIndex].lptstrOfficeLocation ||
  3679. !(lpRecipientListW[dwIndex].lptstrHomePhone = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrHomePhone )) && lpcRecipientList[dwIndex].lptstrHomePhone ||
  3680. !(lpRecipientListW[dwIndex].lptstrOfficePhone = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrOfficePhone )) && lpcRecipientList[dwIndex].lptstrOfficePhone ||
  3681. !(lpRecipientListW[dwIndex].lptstrEmail = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrEmail )) && lpcRecipientList[dwIndex].lptstrEmail ||
  3682. !(lpRecipientListW[dwIndex].lptstrBillingCode = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrBillingCode )) && lpcRecipientList[dwIndex].lptstrBillingCode ||
  3683. !(lpRecipientListW[dwIndex].lptstrTSID = AnsiStringToUnicodeString ( lpcRecipientList[dwIndex].lptstrTSID )) && lpcRecipientList[dwIndex].lptstrTSID )
  3684. {
  3685. DebugPrintEx(
  3686. DEBUG_ERR,
  3687. TEXT("Failed to allocate memory for recipient list"));
  3688. ec=ERROR_NOT_ENOUGH_MEMORY;
  3689. goto Error;
  3690. }
  3691. }
  3692. if (lpcJobParams)
  3693. {
  3694. JobParamsW.dwSizeOfStruct = sizeof(FAX_JOB_PARAM_EXW);
  3695. JobParamsW.Priority = lpcJobParams->Priority;
  3696. JobParamsW.dwScheduleAction = lpcJobParams->dwScheduleAction;
  3697. JobParamsW.tmSchedule = lpcJobParams->tmSchedule;
  3698. JobParamsW.dwReceiptDeliveryType = lpcJobParams->dwReceiptDeliveryType;
  3699. JobParamsW.hCall = lpcJobParams->hCall;
  3700. JobParamsW.dwPageCount = lpcJobParams->dwPageCount;
  3701. memcpy(JobParamsW.dwReserved,lpcJobParams->dwReserved, sizeof(lpcJobParams->dwReserved));
  3702. if (!(JobParamsW.lptstrDocumentName = AnsiStringToUnicodeString ( lpcJobParams->lptstrDocumentName)) && lpcJobParams->lptstrDocumentName||
  3703. !(JobParamsW.lptstrReceiptDeliveryAddress =
  3704. AnsiStringToUnicodeString ( lpcJobParams->lptstrReceiptDeliveryAddress)) &&
  3705. lpcJobParams->lptstrReceiptDeliveryAddress)
  3706. {
  3707. DebugPrintEx(
  3708. DEBUG_ERR,
  3709. TEXT("Failed to allocate memory for job params"));
  3710. ec=ERROR_NOT_ENOUGH_MEMORY;
  3711. goto Error;
  3712. }
  3713. }
  3714. __try
  3715. {
  3716. ec = FAX_SendDocumentEx(hBinding,
  3717. lpwstrFileNameW,
  3718. (lpcCoverPageInfo) ? &CoverpageInfoW : NULL,
  3719. &SenderProfileW,
  3720. dwNumRecipients,
  3721. lpRecipientListW,
  3722. &JobParamsW,
  3723. lpdwJobId,
  3724. lpdwlMessageId,
  3725. lpdwlRecipientMessageIds);
  3726. }
  3727. __except (EXCEPTION_EXECUTE_HANDLER)
  3728. {
  3729. //
  3730. // For some reason we got an exception.
  3731. //
  3732. ec = GetExceptionCode();
  3733. DebugPrintEx(
  3734. DEBUG_ERR,
  3735. TEXT("Exception on RPC call to FAX_SendDocumentEx. (ec: %ld)"),
  3736. ec);
  3737. }
  3738. if (ERROR_SUCCESS != ec)
  3739. {
  3740. DumpRPCExtendedStatus ();
  3741. DebugPrintEx(
  3742. DEBUG_ERR,
  3743. TEXT("FAX_SendDocumentEx failed. ec=0x%X"),ec);
  3744. goto Error;
  3745. }
  3746. //
  3747. // No need to convert output parameters back
  3748. //
  3749. goto Exit;
  3750. Exit:
  3751. Assert( ERROR_SUCCESS == ec);
  3752. Error:
  3753. // free JobParamsW
  3754. MemFree ( JobParamsW.lptstrDocumentName );
  3755. MemFree ( JobParamsW.lptstrReceiptDeliveryAddress );
  3756. if (NULL != lpRecipientListW)
  3757. {
  3758. // free lpRecipientListW
  3759. for(dwIndex = 0; dwIndex < dwNumRecipients; dwIndex++)
  3760. {
  3761. MemFree ( lpRecipientListW[dwIndex].lptstrName );
  3762. MemFree ( lpRecipientListW[dwIndex].lptstrFaxNumber );
  3763. MemFree ( lpRecipientListW[dwIndex].lptstrCompany );
  3764. MemFree ( lpRecipientListW[dwIndex].lptstrStreetAddress );
  3765. MemFree ( lpRecipientListW[dwIndex].lptstrCity );
  3766. MemFree ( lpRecipientListW[dwIndex].lptstrState );
  3767. MemFree ( lpRecipientListW[dwIndex].lptstrZip );
  3768. MemFree ( lpRecipientListW[dwIndex].lptstrCountry );
  3769. MemFree ( lpRecipientListW[dwIndex].lptstrTitle );
  3770. MemFree ( lpRecipientListW[dwIndex].lptstrDepartment );
  3771. MemFree ( lpRecipientListW[dwIndex].lptstrOfficeLocation );
  3772. MemFree ( lpRecipientListW[dwIndex].lptstrHomePhone );
  3773. MemFree ( lpRecipientListW[dwIndex].lptstrOfficePhone );
  3774. MemFree ( lpRecipientListW[dwIndex].lptstrEmail );
  3775. MemFree ( lpRecipientListW[dwIndex].lptstrBillingCode );
  3776. MemFree ( lpRecipientListW[dwIndex].lptstrTSID );
  3777. }
  3778. MemFree (lpRecipientListW);
  3779. }
  3780. // free SenderProfileW
  3781. MemFree ( SenderProfileW.lptstrName );
  3782. MemFree ( SenderProfileW.lptstrFaxNumber );
  3783. MemFree ( SenderProfileW.lptstrCompany );
  3784. MemFree ( SenderProfileW.lptstrStreetAddress );
  3785. MemFree ( SenderProfileW.lptstrCity );
  3786. MemFree ( SenderProfileW.lptstrState );
  3787. MemFree ( SenderProfileW.lptstrZip );
  3788. MemFree ( SenderProfileW.lptstrCountry );
  3789. MemFree ( SenderProfileW.lptstrTitle );
  3790. MemFree ( SenderProfileW.lptstrDepartment );
  3791. MemFree ( SenderProfileW.lptstrOfficeLocation );
  3792. MemFree ( SenderProfileW.lptstrHomePhone );
  3793. MemFree ( SenderProfileW.lptstrOfficePhone );
  3794. MemFree ( SenderProfileW.lptstrEmail );
  3795. MemFree ( SenderProfileW.lptstrBillingCode );
  3796. MemFree ( SenderProfileW.lptstrTSID );
  3797. // free CoverpageInfoW
  3798. MemFree( CoverpageInfoW.lptstrCoverPageFileName );
  3799. MemFree( CoverpageInfoW.lptstrNote );
  3800. MemFree( CoverpageInfoW.lptstrSubject );
  3801. // free file name
  3802. MemFree( lpwstrFileNameW );
  3803. return ec;
  3804. }
  3805. #ifndef UNICODE
  3806. BOOL FaxGetJobExX (
  3807. IN HANDLE hFaxHandle,
  3808. IN DWORDLONG dwlMessageID,
  3809. OUT PFAX_JOB_ENTRY_EXA *ppJobEntry
  3810. )
  3811. {
  3812. UNREFERENCED_PARAMETER (hFaxHandle);
  3813. UNREFERENCED_PARAMETER (dwlMessageID);
  3814. UNREFERENCED_PARAMETER (ppJobEntry);
  3815. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  3816. return FALSE;
  3817. }
  3818. #endif
  3819. BOOL FaxGetJobExA (
  3820. IN HANDLE hFaxHandle,
  3821. IN DWORDLONG dwlMessageID,
  3822. OUT PFAX_JOB_ENTRY_EXA *ppJobEntry
  3823. )
  3824. {
  3825. DEBUG_FUNCTION_NAME(TEXT("FaxGetJobExA"));
  3826. if (!FaxGetJobExW( hFaxHandle,
  3827. dwlMessageID,
  3828. (PFAX_JOB_ENTRY_EXW*) ppJobEntry))
  3829. {
  3830. return FALSE;
  3831. }
  3832. if (!ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->lpctstrRecipientNumber ) ||
  3833. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->lpctstrRecipientName ) ||
  3834. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->lpctstrSenderUserName ) ||
  3835. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->lpctstrBillingCode ) ||
  3836. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->lpctstrDocumentName ) ||
  3837. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->lpctstrSubject ) ||
  3838. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->pStatus->lpctstrExtendedStatus ) ||
  3839. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->pStatus->lpctstrTsid ) ||
  3840. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->pStatus->lpctstrCsid ) ||
  3841. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->pStatus->lpctstrDeviceName ) ||
  3842. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->pStatus->lpctstrCallerID ) ||
  3843. !ConvertUnicodeStringInPlace( (LPWSTR) (*ppJobEntry)->pStatus->lpctstrRoutingInfo ))
  3844. {
  3845. DebugPrintEx(DEBUG_ERR, _T("ConvertUnicodeStringInPlace failed, ec = %ld."), GetLastError());
  3846. MemFree (*ppJobEntry);
  3847. return FALSE;
  3848. }
  3849. (*ppJobEntry)->dwSizeOfStruct = sizeof(FAX_JOB_ENTRY_EXA);
  3850. return TRUE;
  3851. } // FaxGetJobExA
  3852. BOOL FaxGetJobExW (
  3853. IN HANDLE hFaxHandle,
  3854. IN DWORDLONG dwlMessageID,
  3855. OUT PFAX_JOB_ENTRY_EXW *ppJobEntry
  3856. )
  3857. /*++
  3858. Routine name : FaxGetJobExW
  3859. Routine description:
  3860. Returns FAX_JOB_ENTRY_EX structure of the specified message.
  3861. The caller must call FaxFreeBuffer to deallocate the memory.
  3862. Author:
  3863. Oded Sacher (OdedS), Nov, 1999
  3864. Arguments:
  3865. hFaxHandle [ ] - Fax handle obtained from FaxConnectFaxServer()
  3866. dwlMessageID [ ] - Unique message ID
  3867. ppJobEntry [ ] - Buffer to receive the FAX_JOB_ENTRY_EX structure
  3868. Return Value:
  3869. BOOL
  3870. --*/
  3871. {
  3872. error_status_t ec;
  3873. DWORD dwBufferSize = 0;
  3874. LPBYTE Buffer = NULL;
  3875. PFAX_JOB_ENTRY_EXW lpJobEntry;
  3876. PFAX_JOB_STATUSW lpFaxStatus;
  3877. DEBUG_FUNCTION_NAME(TEXT("FaxGetJobExW"));
  3878. Assert (ppJobEntry);
  3879. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  3880. {
  3881. SetLastError(ERROR_INVALID_HANDLE);
  3882. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  3883. return FALSE;
  3884. }
  3885. //
  3886. // Call RPC function.
  3887. //
  3888. __try
  3889. {
  3890. ec = FAX_GetJobEx (FH_FAX_HANDLE(hFaxHandle),
  3891. dwlMessageID,
  3892. &Buffer,
  3893. &dwBufferSize
  3894. );
  3895. }
  3896. __except (EXCEPTION_EXECUTE_HANDLER)
  3897. {
  3898. //
  3899. // For some reason we got an exception.
  3900. //
  3901. ec = GetExceptionCode();
  3902. DebugPrintEx(
  3903. DEBUG_ERR,
  3904. TEXT("Exception on RPC call to FAX_GetJobEx. (ec: %ld)"),
  3905. ec);
  3906. }
  3907. if (ERROR_SUCCESS != ec)
  3908. {
  3909. DumpRPCExtendedStatus ();
  3910. SetLastError( ec );
  3911. return FALSE;
  3912. }
  3913. *ppJobEntry = (PFAX_JOB_ENTRY_EXW)Buffer;
  3914. //
  3915. // Unpack Buffer
  3916. //
  3917. lpJobEntry = (PFAX_JOB_ENTRY_EXW) *ppJobEntry;
  3918. lpFaxStatus = (PFAX_JOB_STATUSW) ((LPBYTE)*ppJobEntry + sizeof (FAX_JOB_ENTRY_EXW));
  3919. lpJobEntry->pStatus = lpFaxStatus;
  3920. FixupStringPtrW( &lpJobEntry, lpJobEntry->lpctstrRecipientNumber );
  3921. FixupStringPtrW( &lpJobEntry, lpJobEntry->lpctstrRecipientName );
  3922. FixupStringPtrW( &lpJobEntry, lpJobEntry->lpctstrSenderUserName );
  3923. FixupStringPtrW( &lpJobEntry, lpJobEntry->lpctstrBillingCode );
  3924. FixupStringPtrW( &lpJobEntry, lpJobEntry->lpctstrDocumentName );
  3925. FixupStringPtrW( &lpJobEntry, lpJobEntry->lpctstrSubject );
  3926. FixupStringPtrW( &lpJobEntry, lpFaxStatus->lpctstrExtendedStatus );
  3927. FixupStringPtrW( &lpJobEntry, lpFaxStatus->lpctstrTsid );
  3928. FixupStringPtrW( &lpJobEntry, lpFaxStatus->lpctstrCsid );
  3929. FixupStringPtrW( &lpJobEntry, lpFaxStatus->lpctstrDeviceName );
  3930. FixupStringPtrW( &lpJobEntry, lpFaxStatus->lpctstrCallerID );
  3931. FixupStringPtrW( &lpJobEntry, lpFaxStatus->lpctstrRoutingInfo );
  3932. return TRUE;
  3933. }
  3934. #ifndef UNICODE
  3935. BOOL FaxEnumJobsExX (
  3936. IN HANDLE hFaxHandle,
  3937. IN DWORD dwJobTypes,
  3938. OUT PFAX_JOB_ENTRY_EXA *ppJobEntries,
  3939. OUT LPDWORD lpdwJobs
  3940. )
  3941. {
  3942. UNREFERENCED_PARAMETER (hFaxHandle);
  3943. UNREFERENCED_PARAMETER (dwJobTypes);
  3944. UNREFERENCED_PARAMETER (ppJobEntries);
  3945. UNREFERENCED_PARAMETER (lpdwJobs);
  3946. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  3947. return FALSE;
  3948. }
  3949. #endif
  3950. BOOL FaxEnumJobsExA (
  3951. IN HANDLE hFaxHandle,
  3952. IN DWORD dwJobTypes,
  3953. OUT PFAX_JOB_ENTRY_EXA *ppJobEntries,
  3954. OUT LPDWORD lpdwJobs
  3955. )
  3956. {
  3957. PFAX_JOB_ENTRY_EXW pJobEntry;
  3958. DWORD i;
  3959. DEBUG_FUNCTION_NAME(TEXT("FaxEnumJobsExA"));
  3960. if (!FaxEnumJobsExW (hFaxHandle,
  3961. dwJobTypes,
  3962. (PFAX_JOB_ENTRY_EXW*)ppJobEntries,
  3963. lpdwJobs))
  3964. {
  3965. return FALSE;
  3966. }
  3967. pJobEntry = (PFAX_JOB_ENTRY_EXW) *ppJobEntries;
  3968. for (i = 0; i < *lpdwJobs; i++)
  3969. {
  3970. if (!ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].lpctstrRecipientNumber ) ||
  3971. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].lpctstrRecipientName ) ||
  3972. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].lpctstrSenderUserName ) ||
  3973. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].lpctstrBillingCode ) ||
  3974. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].lpctstrDocumentName ) ||
  3975. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].lpctstrSubject ) ||
  3976. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].pStatus->lpctstrExtendedStatus ) ||
  3977. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].pStatus->lpctstrTsid ) ||
  3978. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].pStatus->lpctstrCsid ) ||
  3979. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].pStatus->lpctstrDeviceName ) ||
  3980. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].pStatus->lpctstrCallerID ) ||
  3981. !ConvertUnicodeStringInPlace( (LPWSTR) pJobEntry[i].pStatus->lpctstrRoutingInfo ))
  3982. {
  3983. DebugPrintEx(DEBUG_ERR, _T("ConvertUnicodeStringInPlace failed, ec = %ld."), GetLastError());
  3984. MemFree (*ppJobEntries);
  3985. return FALSE;
  3986. }
  3987. }
  3988. return TRUE;
  3989. } // FaxEnumJobsExA
  3990. BOOL FaxEnumJobsExW (
  3991. IN HANDLE hFaxHandle,
  3992. IN DWORD dwJobTypes,
  3993. OUT PFAX_JOB_ENTRY_EXW *ppJobEntries,
  3994. OUT LPDWORD lpdwJobs
  3995. )
  3996. {
  3997. error_status_t ec;
  3998. DWORD dwBufferSize = 0;
  3999. PFAX_JOB_ENTRY_EXW lpJobEntry;
  4000. PFAX_JOB_STATUSW lpFaxStatus;
  4001. DWORD i;
  4002. DEBUG_FUNCTION_NAME(TEXT("FaxEnumJobsExW"));
  4003. Assert (ppJobEntries && lpdwJobs);
  4004. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  4005. {
  4006. SetLastError(ERROR_INVALID_HANDLE);
  4007. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  4008. return FALSE;
  4009. }
  4010. if (dwJobTypes & JT_BROADCAST)
  4011. {
  4012. SetLastError(ERROR_INVALID_PARAMETER);
  4013. DebugPrintEx(DEBUG_ERR, _T("dwJobTypes & JT_BROADCAST."));
  4014. return FALSE;
  4015. }
  4016. if (!(dwJobTypes & JT_SEND ||
  4017. dwJobTypes & JT_RECEIVE ||
  4018. dwJobTypes & JT_ROUTING))
  4019. {
  4020. SetLastError(ERROR_INVALID_PARAMETER);
  4021. return FALSE;
  4022. }
  4023. *lpdwJobs = 0;
  4024. *ppJobEntries = NULL;
  4025. //
  4026. // Call RPC function.
  4027. //
  4028. __try
  4029. {
  4030. ec = FAX_EnumJobsEx (FH_FAX_HANDLE(hFaxHandle),
  4031. dwJobTypes,
  4032. (LPBYTE*)ppJobEntries,
  4033. &dwBufferSize,
  4034. lpdwJobs
  4035. );
  4036. }
  4037. __except (EXCEPTION_EXECUTE_HANDLER)
  4038. {
  4039. //
  4040. // For some reason we got an exception.
  4041. //
  4042. ec = GetExceptionCode();
  4043. DebugPrintEx(
  4044. DEBUG_ERR,
  4045. TEXT("Exception on RPC call to FaxEnumJobsExW. (ec: %ld)"),
  4046. ec);
  4047. }
  4048. if (ERROR_SUCCESS != ec)
  4049. {
  4050. DumpRPCExtendedStatus ();
  4051. SetLastError( ec );
  4052. return FALSE;
  4053. }
  4054. //
  4055. // Unpack Buffer
  4056. //
  4057. lpJobEntry = (PFAX_JOB_ENTRY_EXW) *ppJobEntries;
  4058. lpFaxStatus = (PFAX_JOB_STATUSW) ((LPBYTE)*ppJobEntries + (sizeof(FAX_JOB_ENTRY_EXW) * (*lpdwJobs)));
  4059. for (i = 0; i < *lpdwJobs; i++)
  4060. {
  4061. lpJobEntry[i].pStatus = &lpFaxStatus[i];
  4062. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].lpctstrRecipientNumber );
  4063. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].lpctstrRecipientName );
  4064. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].lpctstrSenderUserName );
  4065. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].lpctstrBillingCode );
  4066. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].lpctstrDocumentName );
  4067. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].lpctstrSubject );
  4068. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].pStatus->lpctstrExtendedStatus );
  4069. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].pStatus->lpctstrTsid );
  4070. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].pStatus->lpctstrCsid );
  4071. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].pStatus->lpctstrDeviceName );
  4072. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].pStatus->lpctstrCallerID );
  4073. FixupStringPtrW( &lpJobEntry, lpJobEntry[i].pStatus->lpctstrRoutingInfo );
  4074. }
  4075. return TRUE;
  4076. }
  4077. //********************************************
  4078. //* Archive jobs
  4079. //********************************************
  4080. WINFAXAPI
  4081. BOOL
  4082. WINAPI
  4083. FaxStartMessagesEnum (
  4084. IN HANDLE hFaxHandle,
  4085. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  4086. OUT PHANDLE phEnum
  4087. )
  4088. /*++
  4089. Routine name : FaxStartMessagesEnum
  4090. Routine description:
  4091. A fax client application calls the FaxStartMessagesEnum
  4092. function to start enumerating messages in one of the archives
  4093. Author:
  4094. Eran Yariv (EranY), Dec, 1999
  4095. Arguments:
  4096. hFaxHandle [in ] - Specifies a fax server handle returned by a call
  4097. to the FaxConnectFaxServer function.
  4098. Folder [in ] - The type of the archive where the message resides.
  4099. FAX_MESSAGE_FOLDER_QUEUE is an invalid
  4100. value for this parameter.
  4101. phEnum [out] - Points to an enumeration handle return value.
  4102. Return Value:
  4103. TRUE - Success
  4104. FALSE - Failure, call GetLastError() for more error information.
  4105. --*/
  4106. {
  4107. error_status_t ec;
  4108. PHANDLE_ENTRY pHandleEntry;
  4109. HANDLE hServerContext;
  4110. DEBUG_FUNCTION_NAME(TEXT("FaxStartMessagesEnum"));
  4111. if (!ValidateFaxHandle(hFaxHandle,FHT_SERVICE))
  4112. {
  4113. SetLastError(ERROR_INVALID_HANDLE);
  4114. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  4115. return FALSE;
  4116. }
  4117. if ((FAX_MESSAGE_FOLDER_INBOX != Folder) &&
  4118. (FAX_MESSAGE_FOLDER_SENTITEMS != Folder))
  4119. {
  4120. DebugPrintEx(DEBUG_ERR, _T("Bad folder specified (%ld)"), Folder);
  4121. SetLastError(ERROR_INVALID_PARAMETER);
  4122. return FALSE;
  4123. }
  4124. //
  4125. // Create a local handle that will hold the one returned from the service
  4126. //
  4127. pHandleEntry = CreateNewMsgEnumHandle( FH_DATA(hFaxHandle));
  4128. if (!pHandleEntry)
  4129. {
  4130. ec = GetLastError ();
  4131. DebugPrintEx(
  4132. DEBUG_ERR,
  4133. TEXT("Can't create local handle entry (ec = %ld)"),
  4134. ec);
  4135. SetLastError(ec);
  4136. return FALSE;
  4137. }
  4138. __try
  4139. {
  4140. ec = FAX_StartMessagesEnum(
  4141. FH_FAX_HANDLE(hFaxHandle),
  4142. Folder,
  4143. &hServerContext
  4144. );
  4145. }
  4146. __except (EXCEPTION_EXECUTE_HANDLER)
  4147. {
  4148. //
  4149. // For some reason we got an exception.
  4150. //
  4151. ec = GetExceptionCode();
  4152. DebugPrintEx(
  4153. DEBUG_ERR,
  4154. TEXT("Exception on RPC call to FAX_StartMessagesEnum. (ec: %ld)"),
  4155. ec);
  4156. }
  4157. if (ERROR_SUCCESS != ec)
  4158. {
  4159. //
  4160. // Free local handle
  4161. //
  4162. DumpRPCExtendedStatus ();
  4163. CloseFaxHandle( pHandleEntry );
  4164. SetLastError(ec);
  4165. return FALSE;
  4166. }
  4167. //
  4168. // Store retuned handle (Fax Server context handle) in our local handle
  4169. //
  4170. FH_MSG_ENUM_HANDLE(pHandleEntry) = hServerContext;
  4171. //
  4172. // Return our local handle instead of server's handle
  4173. //
  4174. *phEnum = pHandleEntry;
  4175. return TRUE;
  4176. } // FaxStartMessagesEnum
  4177. WINFAXAPI
  4178. BOOL
  4179. WINAPI
  4180. FaxEndMessagesEnum (
  4181. IN HANDLE hEnum
  4182. )
  4183. /*++
  4184. Routine name : FaxEndMessagesEnum
  4185. Routine description:
  4186. A fax client application calls the FaxEndMessagesEnum function to stop
  4187. enumerating messages in one of the archives.
  4188. Author:
  4189. Eran Yariv (EranY), Dec, 1999
  4190. Arguments:
  4191. hEnum [in] - The enumeration handle value.
  4192. This value is obtained by calling FaxStartMessagesEnum.
  4193. Return Value:
  4194. TRUE - Success
  4195. FALSE - Failure, call GetLastError() for more error information.
  4196. --*/
  4197. {
  4198. error_status_t ec;
  4199. HANDLE hMsgEnumContext;
  4200. PHANDLE_ENTRY pHandleEntry = (PHANDLE_ENTRY) hEnum;
  4201. DEBUG_FUNCTION_NAME(TEXT("FaxEndMessagesEnum"));
  4202. if (!ValidateFaxHandle(hEnum, FHT_MSGENUM))
  4203. {
  4204. SetLastError(ERROR_INVALID_HANDLE);
  4205. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  4206. return FALSE;
  4207. }
  4208. //
  4209. // Retrieved the RPC context handle of the message enumeration from the handle object we got.
  4210. //
  4211. hMsgEnumContext = FH_MSG_ENUM_HANDLE(hEnum);
  4212. __try
  4213. {
  4214. //
  4215. // Attempt to tell the server we are shutting down this enumeration context
  4216. //
  4217. ec = FAX_EndMessagesEnum(&hMsgEnumContext);
  4218. }
  4219. __except (EXCEPTION_EXECUTE_HANDLER)
  4220. {
  4221. //
  4222. // For some reason we got an exception.
  4223. //
  4224. ec = GetExceptionCode();
  4225. DebugPrintEx(
  4226. DEBUG_ERR,
  4227. TEXT("Exception on RPC call to FAX_EndMessagesEnum. (ec: %ld)"),
  4228. ec);
  4229. }
  4230. if (ERROR_SUCCESS == ec)
  4231. {
  4232. //
  4233. // Free local handle object
  4234. //
  4235. DumpRPCExtendedStatus ();
  4236. CloseFaxHandle( pHandleEntry );
  4237. return TRUE;
  4238. }
  4239. //
  4240. // Failure
  4241. //
  4242. SetLastError (ec);
  4243. return FALSE;
  4244. } // FaxEndMessagesEnum
  4245. WINFAXAPI
  4246. BOOL
  4247. WINAPI
  4248. FaxEnumMessagesA (
  4249. IN HANDLE hEnum,
  4250. IN DWORD dwNumMessages,
  4251. OUT PFAX_MESSAGEA *ppMsgs,
  4252. OUT LPDWORD lpdwReturnedMsgs
  4253. )
  4254. /*++
  4255. Routine name : FaxEnumMessagesA
  4256. Routine description:
  4257. A fax client application calls the FaxEnumMessages function to enumerate
  4258. messages in one of the archives.
  4259. This function is incremental. That is, it uses an internal context cursor to
  4260. point to the next set of messages to retrieve for each call.
  4261. The cursor is set to point to the begging of the messages in the archive after a
  4262. successful call to FaxStartMessagesEnum.
  4263. Each successful call to FaxEnumMessages advances the cursor by the number of
  4264. messages retrieved.
  4265. Once the cursor reaches the end of the enumeration,
  4266. the function fails with ERROR_NO_DATA error code.
  4267. The FaxEndMessagesEnum function should be called then.
  4268. This is the ANSI version.
  4269. Author:
  4270. Eran Yariv (EranY), Dec, 1999
  4271. Arguments:
  4272. hEnum [in ] - The enumeration handle value.
  4273. This value is obtained by calling
  4274. FAX_StartMessagesEnum.
  4275. dwNumMessages [in ] - A DWORD value indicating the maximal number
  4276. of messages the caller requires to enumerate.
  4277. This value cannot be zero.
  4278. ppMsgs [out] - A pointer to a buffer of FAX_MESSAGE structures.
  4279. This buffer will contain lpdwReturnedMsgs entries.
  4280. The buffer will be allocated by the function
  4281. and the caller must free it.
  4282. lpdwReturnedMsgs [out] - Pointer to a DWORD value indicating the actual
  4283. number of messages retrieved.
  4284. This value cannot exceed dwNumMessages.
  4285. Return Value:
  4286. TRUE - Success
  4287. FALSE - Failure, call GetLastError() for more error information.
  4288. --*/
  4289. {
  4290. DWORD i;
  4291. PFAX_MESSAGEW *ppWMsgs = (PFAX_MESSAGEW*)ppMsgs;
  4292. DEBUG_FUNCTION_NAME(TEXT("FaxEnumMessagesA"));
  4293. //
  4294. // Call UNICODE function.
  4295. //
  4296. if (!FaxEnumMessagesW (hEnum, dwNumMessages, ppWMsgs, lpdwReturnedMsgs))
  4297. {
  4298. return FALSE;
  4299. }
  4300. //
  4301. // Convert all strings to ANSI
  4302. //
  4303. for (i = 0; i < *lpdwReturnedMsgs; i++)
  4304. {
  4305. if (!ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrRecipientNumber) ||
  4306. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrRecipientName) ||
  4307. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrSenderNumber) ||
  4308. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrSenderName) ||
  4309. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrTsid) ||
  4310. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrCsid) ||
  4311. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrSenderUserName) ||
  4312. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrBillingCode) ||
  4313. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrDeviceName) ||
  4314. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrDocumentName) ||
  4315. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrSubject) ||
  4316. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrCallerID) ||
  4317. !ConvertUnicodeStringInPlace ((*ppWMsgs)[i].lpctstrRoutingInfo))
  4318. {
  4319. DebugPrintEx(DEBUG_ERR, _T("ConvertUnicodeStringInPlace failed, ec = %ld."), GetLastError());
  4320. MemFree (*ppMsgs);
  4321. return FALSE;
  4322. }
  4323. }
  4324. return TRUE;
  4325. } // FaxEnumMessagesA
  4326. WINFAXAPI
  4327. BOOL
  4328. WINAPI
  4329. FaxEnumMessagesW (
  4330. IN HANDLE hEnum,
  4331. IN DWORD dwNumMessages,
  4332. OUT PFAX_MESSAGEW *ppMsgs,
  4333. OUT LPDWORD lpdwReturnedMsgs
  4334. )
  4335. /*++
  4336. Routine name : FaxEnumMessagesW
  4337. Routine description:
  4338. A fax client application calls the FaxEnumMessages function to enumerate
  4339. messages in one of the archives.
  4340. This function is incremental. That is, it uses an internal context cursor to
  4341. point to the next set of messages to retrieve for each call.
  4342. The cursor is set to point to the begging of the messages in the archive after a
  4343. successful call to FaxStartMessagesEnum.
  4344. Each successful call to FaxEnumMessages advances the cursor by the number of
  4345. messages retrieved.
  4346. Once the cursor reaches the end of the enumeration,
  4347. the function fails with ERROR_NO_DATA error code.
  4348. The FaxEndMessagesEnum function should be called then.
  4349. This is the UNICODE version.
  4350. Author:
  4351. Eran Yariv (EranY), Dec, 1999
  4352. Arguments:
  4353. hEnum [in ] - The enumeration handle value.
  4354. This value is obtained by calling
  4355. FAX_StartMessagesEnum.
  4356. dwNumMessages [in ] - A DWORD value indicating the maximal number
  4357. of messages the caller requires to enumerate.
  4358. This value cannot be zero.
  4359. ppMsgs [out] - A pointer to a buffer of FAX_MESSAGE structures.
  4360. This buffer will contain lpdwReturnedMsgs entries.
  4361. The buffer will be allocated by the function
  4362. and the caller must free it.
  4363. lpdwReturnedMsgs [out] - Pointer to a DWORD value indicating the actual
  4364. number of messages retrieved.
  4365. This value cannot exceed dwNumMessages.
  4366. Return Value:
  4367. TRUE - Success
  4368. FALSE - Failure, call GetLastError() for more error information.
  4369. --*/
  4370. {
  4371. DWORD dwBufferSize = 0;
  4372. error_status_t ec;
  4373. DWORD dwIndex;
  4374. DEBUG_FUNCTION_NAME(TEXT("FaxEnumMessagesW"));
  4375. if (!ValidateFaxHandle(hEnum, FHT_MSGENUM))
  4376. {
  4377. SetLastError(ERROR_INVALID_HANDLE);
  4378. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  4379. return FALSE;
  4380. }
  4381. if (!dwNumMessages || !ppMsgs || !lpdwReturnedMsgs)
  4382. {
  4383. SetLastError(ERROR_INVALID_PARAMETER);
  4384. DebugPrintEx(DEBUG_ERR, _T("At least one of the parameters is NULL."));
  4385. return FALSE;
  4386. }
  4387. *ppMsgs = NULL;
  4388. __try
  4389. {
  4390. ec = FAX_EnumMessages(
  4391. FH_MSG_ENUM_HANDLE(hEnum), // Enumeration handle
  4392. dwNumMessages, // Maximal number of messages to get
  4393. (LPBYTE*)ppMsgs, // Pointer to messages buffer
  4394. &dwBufferSize, // Size of allocated buffer
  4395. lpdwReturnedMsgs // Number of messages actually returned
  4396. );
  4397. }
  4398. __except (EXCEPTION_EXECUTE_HANDLER)
  4399. {
  4400. //
  4401. // For some reason we got an exception.
  4402. //
  4403. ec = GetExceptionCode();
  4404. DebugPrintEx(
  4405. DEBUG_ERR,
  4406. TEXT("Exception on RPC call to FAX_EnumMessages. (ec: %ld)"),
  4407. ec);
  4408. }
  4409. if (ERROR_SUCCESS != ec)
  4410. {
  4411. DumpRPCExtendedStatus ();
  4412. SetLastError( ec );
  4413. return FALSE;
  4414. }
  4415. for (dwIndex = 0; dwIndex < *lpdwReturnedMsgs; dwIndex++)
  4416. {
  4417. PFAX_MESSAGEW pCurMsg = &(((PFAX_MESSAGEW)(*ppMsgs))[dwIndex]);
  4418. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrRecipientNumber);
  4419. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrRecipientName);
  4420. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrSenderNumber);
  4421. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrSenderName);
  4422. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrTsid);
  4423. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrCsid);
  4424. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrSenderUserName);
  4425. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrBillingCode);
  4426. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrDeviceName);
  4427. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrDocumentName);
  4428. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrSubject);
  4429. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrCallerID);
  4430. FixupStringPtrW (ppMsgs, pCurMsg->lpctstrRoutingInfo);
  4431. }
  4432. return TRUE;
  4433. } // FaxEnumMessagesW
  4434. #ifndef UNICODE
  4435. WINFAXAPI
  4436. BOOL
  4437. WINAPI
  4438. FaxEnumMessagesX (
  4439. IN HANDLE hEnum,
  4440. IN DWORD dwNumMessages,
  4441. OUT PFAX_MESSAGEW *ppMsgs,
  4442. OUT LPDWORD lpdwReturnedMsgs
  4443. )
  4444. {
  4445. UNREFERENCED_PARAMETER (hEnum);
  4446. UNREFERENCED_PARAMETER (dwNumMessages);
  4447. UNREFERENCED_PARAMETER (ppMsgs);
  4448. UNREFERENCED_PARAMETER (lpdwReturnedMsgs);
  4449. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  4450. return FALSE;
  4451. } // FaxEnumMessagesX
  4452. #endif // #ifndef UNICODE
  4453. WINFAXAPI
  4454. BOOL
  4455. WINAPI
  4456. FaxGetMessageA (
  4457. IN HANDLE hFaxHandle,
  4458. IN DWORDLONG dwlMessageId,
  4459. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  4460. OUT PFAX_MESSAGEA *ppMsg
  4461. )
  4462. /*++
  4463. Routine name : FaxGetMessageA
  4464. Routine description:
  4465. Removes a message from an archive.
  4466. ANSI version.
  4467. Author:
  4468. Eran Yariv (EranY), Dec, 1999
  4469. Arguments:
  4470. hFaxHandle [in ] - Handle to the fax server
  4471. dwlMessageId [in ] - Unique message id
  4472. Folder [in ] - Archive folder
  4473. ppMsg [out] - Pointer to buffer to hold message information
  4474. Return Value:
  4475. TRUE - Success
  4476. FALSE - Failure, call GetLastError() for more error information.
  4477. --*/
  4478. {
  4479. PFAX_MESSAGEW *ppWMsg = (PFAX_MESSAGEW*)ppMsg;
  4480. DEBUG_FUNCTION_NAME(TEXT("FaxGetMessageA"));
  4481. //
  4482. // Call UNICODE function.
  4483. //
  4484. if (!FaxGetMessageW (hFaxHandle, dwlMessageId, Folder, ppWMsg))
  4485. {
  4486. return FALSE;
  4487. }
  4488. //
  4489. // Convert all strings to ANSI
  4490. //
  4491. if (!ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrRecipientNumber) ||
  4492. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrRecipientName) ||
  4493. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrSenderNumber) ||
  4494. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrSenderName) ||
  4495. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrTsid) ||
  4496. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrCsid) ||
  4497. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrSenderUserName) ||
  4498. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrBillingCode) ||
  4499. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrDeviceName) ||
  4500. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrDocumentName) ||
  4501. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrSubject) ||
  4502. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrCallerID) ||
  4503. !ConvertUnicodeStringInPlace ((*ppWMsg)->lpctstrRoutingInfo))
  4504. {
  4505. DebugPrintEx(DEBUG_ERR, _T("ConvertUnicodeStringInPlace failed, ec = %ld."), GetLastError());
  4506. MemFree (*ppMsg);
  4507. return FALSE;
  4508. }
  4509. (*ppMsg)->dwSizeOfStruct = sizeof(FAX_MESSAGEA);
  4510. return TRUE;
  4511. } // FaxGetMessageA
  4512. WINFAXAPI
  4513. BOOL
  4514. WINAPI
  4515. FaxGetMessageW (
  4516. IN HANDLE hFaxHandle,
  4517. IN DWORDLONG dwlMessageId,
  4518. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  4519. OUT PFAX_MESSAGEW *ppMsg
  4520. )
  4521. /*++
  4522. Routine name : FaxGetMessageW
  4523. Routine description:
  4524. Removes a message from an archive.
  4525. UNICODE version.
  4526. Author:
  4527. Eran Yariv (EranY), Dec, 1999
  4528. Arguments:
  4529. hFaxHandle [in ] - Handle to the fax server
  4530. dwlMessageId [in ] - Unique message id
  4531. Folder [in ] - Archive folder
  4532. ppMsg [out] - Pointer to buffer to hold message information
  4533. Return Value:
  4534. TRUE - Success
  4535. FALSE - Failure, call GetLastError() for more error information.
  4536. --*/
  4537. {
  4538. DWORD dwBufferSize = 0;
  4539. error_status_t ec;
  4540. DEBUG_FUNCTION_NAME(TEXT("FaxGetMessageW"));
  4541. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  4542. {
  4543. SetLastError(ERROR_INVALID_HANDLE);
  4544. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  4545. return FALSE;
  4546. }
  4547. if (!ppMsg || !dwlMessageId)
  4548. {
  4549. SetLastError(ERROR_INVALID_PARAMETER);
  4550. DebugPrintEx(DEBUG_ERR, _T("ppMsg OR dwlMessageId is NULL."));
  4551. return FALSE;
  4552. }
  4553. if ((FAX_MESSAGE_FOLDER_INBOX != Folder) &&
  4554. (FAX_MESSAGE_FOLDER_SENTITEMS != Folder))
  4555. {
  4556. DebugPrintEx(
  4557. DEBUG_ERR,
  4558. TEXT("Bad folder specified (%ld)"),
  4559. Folder);
  4560. SetLastError(ERROR_INVALID_PARAMETER);
  4561. return FALSE;
  4562. }
  4563. *ppMsg = NULL;
  4564. __try
  4565. {
  4566. ec = FAX_GetMessage(
  4567. FH_FAX_HANDLE(hFaxHandle),
  4568. dwlMessageId,
  4569. Folder,
  4570. (LPBYTE*)ppMsg,
  4571. &dwBufferSize);
  4572. }
  4573. __except (EXCEPTION_EXECUTE_HANDLER)
  4574. {
  4575. //
  4576. // For some reason we got an exception.
  4577. //
  4578. ec = GetExceptionCode();
  4579. DebugPrintEx(
  4580. DEBUG_ERR,
  4581. TEXT("Exception on RPC call to FAX_GetMessage. (ec: %ld)"),
  4582. ec);
  4583. }
  4584. if (ERROR_SUCCESS != ec)
  4585. {
  4586. DumpRPCExtendedStatus ();
  4587. SetLastError( ec );
  4588. return FALSE;
  4589. }
  4590. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrRecipientNumber);
  4591. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrRecipientName);
  4592. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrSenderNumber);
  4593. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrSenderName);
  4594. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrTsid);
  4595. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrCsid);
  4596. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrSenderUserName);
  4597. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrBillingCode);
  4598. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrDeviceName);
  4599. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrDocumentName);
  4600. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrSubject);
  4601. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrCallerID);
  4602. FixupStringPtrW (ppMsg, (*ppMsg)->lpctstrRoutingInfo);
  4603. return TRUE;
  4604. } // FaxGetMessageW
  4605. #ifndef UNICODE
  4606. WINFAXAPI
  4607. BOOL
  4608. WINAPI
  4609. FaxGetMessageX (
  4610. IN HANDLE hFaxHandle,
  4611. IN DWORDLONG dwlMessageId,
  4612. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  4613. OUT PFAX_MESSAGEW *ppMsg
  4614. )
  4615. {
  4616. UNREFERENCED_PARAMETER (hFaxHandle);
  4617. UNREFERENCED_PARAMETER (dwlMessageId);
  4618. UNREFERENCED_PARAMETER (Folder);
  4619. UNREFERENCED_PARAMETER (ppMsg);
  4620. SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
  4621. return FALSE;
  4622. } // FaxGetMessageX
  4623. #endif // #ifndef UNICODE
  4624. WINFAXAPI
  4625. BOOL
  4626. WINAPI
  4627. FaxRemoveMessage (
  4628. IN HANDLE hFaxHandle,
  4629. IN DWORDLONG dwlMessageId,
  4630. IN FAX_ENUM_MESSAGE_FOLDER Folder
  4631. )
  4632. /*++
  4633. Routine name : FaxRemoveMessage
  4634. Routine description:
  4635. Removes a message from an archive
  4636. Author:
  4637. Eran Yariv (EranY), Dec, 1999
  4638. Arguments:
  4639. hFaxHandle [in] - Handle to the fax server
  4640. dwlMessageId [in] - Unique message id
  4641. Folder [in] - Archive folder
  4642. Return Value:
  4643. TRUE - Success
  4644. FALSE - Failure, call GetLastError() for more error information.
  4645. --*/
  4646. {
  4647. error_status_t ec;
  4648. DEBUG_FUNCTION_NAME(TEXT("FaxRemoveMessage"));
  4649. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  4650. {
  4651. SetLastError(ERROR_INVALID_HANDLE);
  4652. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  4653. return FALSE;
  4654. }
  4655. if (!dwlMessageId)
  4656. {
  4657. SetLastError(ERROR_INVALID_PARAMETER);
  4658. DebugPrintEx(DEBUG_ERR, _T("dwlMessageId is ZERO."));
  4659. return FALSE;
  4660. }
  4661. if ((FAX_MESSAGE_FOLDER_INBOX != Folder) &&
  4662. (FAX_MESSAGE_FOLDER_SENTITEMS != Folder))
  4663. {
  4664. DebugPrintEx(
  4665. DEBUG_ERR,
  4666. TEXT("Bad folder specified (%ld)"),
  4667. Folder);
  4668. SetLastError(ERROR_INVALID_PARAMETER);
  4669. return FALSE;
  4670. }
  4671. __try
  4672. {
  4673. ec = FAX_RemoveMessage(
  4674. FH_FAX_HANDLE(hFaxHandle),
  4675. dwlMessageId,
  4676. Folder);
  4677. }
  4678. __except (EXCEPTION_EXECUTE_HANDLER)
  4679. {
  4680. //
  4681. // For some reason we got an exception.
  4682. //
  4683. ec = GetExceptionCode();
  4684. DebugPrintEx(
  4685. DEBUG_ERR,
  4686. TEXT("Exception on RPC call to FAX_RemoveMessage. (ec: %ld)"),
  4687. ec);
  4688. }
  4689. if (ERROR_SUCCESS != ec)
  4690. {
  4691. DumpRPCExtendedStatus ();
  4692. SetLastError( ec );
  4693. return FALSE;
  4694. }
  4695. return TRUE;
  4696. } // FaxRemoveMessage
  4697. WINFAXAPI
  4698. BOOL
  4699. WINAPI
  4700. FaxGetMessageTiff (
  4701. IN HANDLE hFaxHandle,
  4702. IN DWORDLONG dwlMessageId,
  4703. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  4704. IN LPCTSTR lpctstrFilePath
  4705. )
  4706. /*++
  4707. Routine name : FaxGetMessageTiff
  4708. Routine description:
  4709. Retrieves a message TIFF from the archive / queue
  4710. Author:
  4711. Eran Yariv (EranY), Dec, 1999
  4712. Arguments:
  4713. hFaxHandle [in] - handle to fax server
  4714. dwlMessageId [in] - Unique message id
  4715. Folder [in] - Archive / queue folder
  4716. lpctstrFilePath [in] - Path to local file to receive TIFF image
  4717. Return Value:
  4718. TRUE - Success
  4719. FALSE - Failure, call GetLastError() for more error information.
  4720. --*/
  4721. {
  4722. DWORD ec = ERROR_SUCCESS;
  4723. DWORD ec2 = ERROR_SUCCESS;
  4724. HANDLE hFile = INVALID_HANDLE_VALUE;
  4725. HANDLE hCopyContext = NULL;
  4726. PBYTE aBuffer=NULL;
  4727. DEBUG_FUNCTION_NAME(TEXT("FaxGetMessageTiff"));
  4728. //
  4729. // parameters validation
  4730. //
  4731. if ((FAX_MESSAGE_FOLDER_QUEUE != Folder) &&
  4732. (FAX_MESSAGE_FOLDER_INBOX != Folder) &&
  4733. (FAX_MESSAGE_FOLDER_SENTITEMS != Folder))
  4734. {
  4735. DebugPrintEx(
  4736. DEBUG_ERR,
  4737. TEXT("Bad folder specified (%ld)"),
  4738. Folder);
  4739. SetLastError(ERROR_INVALID_PARAMETER);
  4740. return FALSE;
  4741. }
  4742. if (!dwlMessageId)
  4743. {
  4744. DebugPrintEx(
  4745. DEBUG_ERR,
  4746. TEXT("zero msg id specified"));
  4747. SetLastError(ERROR_INVALID_PARAMETER);
  4748. return FALSE;
  4749. }
  4750. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  4751. {
  4752. SetLastError (ERROR_INVALID_HANDLE);
  4753. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  4754. return FALSE;
  4755. }
  4756. //
  4757. // start FaxGetMessageTiff implementation
  4758. //
  4759. //
  4760. // Try to open local file first
  4761. //
  4762. hFile = SafeCreateFile (
  4763. lpctstrFilePath,
  4764. GENERIC_WRITE,
  4765. FILE_SHARE_READ,
  4766. NULL,
  4767. CREATE_ALWAYS,
  4768. FILE_ATTRIBUTE_NORMAL,
  4769. NULL);
  4770. if ( INVALID_HANDLE_VALUE == hFile )
  4771. {
  4772. ec = GetLastError ();
  4773. DebugPrintEx(
  4774. DEBUG_ERR,
  4775. TEXT("Opening %s for write failed (ec: %ld)"),
  4776. lpctstrFilePath,
  4777. ec);
  4778. if (ERROR_ACCESS_DENIED == ec ||
  4779. ERROR_SHARING_VIOLATION == ec)
  4780. {
  4781. ec = FAX_ERR_FILE_ACCESS_DENIED;
  4782. }
  4783. SetLastError (ec);
  4784. return FALSE;
  4785. }
  4786. aBuffer = (PBYTE)MemAlloc(RPC_COPY_BUFFER_SIZE);
  4787. if (NULL == aBuffer)
  4788. {
  4789. ec = ERROR_NOT_ENOUGH_MEMORY;
  4790. DebugPrintEx(
  4791. DEBUG_ERR,
  4792. TEXT("Failed to allocate memory for read/write buffer."));
  4793. goto exit;
  4794. }
  4795. //
  4796. // Acquire copy context handle
  4797. //
  4798. __try
  4799. {
  4800. ec = FAX_StartCopyMessageFromServer (
  4801. FH_FAX_HANDLE(hFaxHandle),
  4802. dwlMessageId,
  4803. Folder,
  4804. &hCopyContext);
  4805. }
  4806. __except (EXCEPTION_EXECUTE_HANDLER)
  4807. {
  4808. //
  4809. // For some reason we got an exception.
  4810. //
  4811. ec = GetExceptionCode();
  4812. DebugPrintEx(
  4813. DEBUG_ERR,
  4814. TEXT("Exception on RPC call to FAX_StartCopyMessageFromServer. (ec: %ld)"),
  4815. ec);
  4816. }
  4817. if (ERROR_SUCCESS != ec)
  4818. {
  4819. DumpRPCExtendedStatus ();
  4820. DebugPrintEx(
  4821. DEBUG_ERR,
  4822. TEXT("FAX_StartCopyMessageFromServer failed (ec: %ld)"),
  4823. ec);
  4824. goto exit;
  4825. }
  4826. //
  4827. // Start copy iteration(s)
  4828. //
  4829. for (;;)
  4830. {
  4831. //
  4832. // Set dwBytesToWrite to buffer size so that the RPC layer allocates
  4833. // dwBytesToWrite bytes localy on the server and copies them back to us.
  4834. //
  4835. DWORD dwBytesToWrite = sizeof (BYTE) * RPC_COPY_BUFFER_SIZE; // size of aBuffer in bytes
  4836. DWORD dwBytesWritten;
  4837. //
  4838. // Move bytes from server via RPC
  4839. //
  4840. __try
  4841. {
  4842. ec = FAX_ReadFile (
  4843. hCopyContext,
  4844. sizeof (BYTE) * RPC_COPY_BUFFER_SIZE, // size of aBuffer in bytes
  4845. aBuffer,
  4846. &dwBytesToWrite);
  4847. }
  4848. __except (EXCEPTION_EXECUTE_HANDLER)
  4849. {
  4850. //
  4851. // For some reason we got an exception.
  4852. //
  4853. ec = GetExceptionCode();
  4854. DebugPrintEx(
  4855. DEBUG_ERR,
  4856. TEXT("Exception on RPC call to FAX_ReadFile. (ec: %ld)"),
  4857. ec);
  4858. }
  4859. if (ERROR_SUCCESS != ec)
  4860. {
  4861. DumpRPCExtendedStatus ();
  4862. DebugPrintEx(
  4863. DEBUG_ERR,
  4864. TEXT("FAX_ReadFile failed (ec: %ld)"),
  4865. ec);
  4866. goto exit;
  4867. }
  4868. if (0 == dwBytesToWrite)
  4869. {
  4870. //
  4871. // No more bytes to copy from the server - stop the loop
  4872. //
  4873. break;
  4874. }
  4875. //
  4876. // Put data in our local file
  4877. //
  4878. if (!WriteFile (hFile,
  4879. aBuffer,
  4880. dwBytesToWrite,
  4881. &dwBytesWritten,
  4882. NULL))
  4883. {
  4884. ec = GetLastError ();
  4885. DebugPrintEx(
  4886. DEBUG_ERR,
  4887. TEXT("WriteFile failed (ec: %ld)"),
  4888. ec);
  4889. goto exit;
  4890. }
  4891. if (dwBytesWritten != dwBytesToWrite)
  4892. {
  4893. //
  4894. // Strange situation
  4895. //
  4896. DebugPrintEx(
  4897. DEBUG_ERR,
  4898. TEXT("WriteFile was asked to write %ld bytes but wrote only %ld bytes"),
  4899. dwBytesToWrite,
  4900. dwBytesWritten);
  4901. ec = ERROR_GEN_FAILURE;
  4902. goto exit;
  4903. }
  4904. } // End of copy iteration
  4905. Assert (ERROR_SUCCESS == ec);
  4906. exit:
  4907. if (INVALID_HANDLE_VALUE != hFile)
  4908. {
  4909. //
  4910. // Close the open file
  4911. //
  4912. if (!CloseHandle (hFile))
  4913. {
  4914. ec2 = GetLastError ();
  4915. DebugPrintEx(
  4916. DEBUG_ERR,
  4917. TEXT("CloseHandle failed (ec: %ld)"),
  4918. ec2);
  4919. }
  4920. if (ERROR_SUCCESS == ec)
  4921. {
  4922. //
  4923. // If we had an error during wrapup, propogate it out
  4924. //
  4925. ec = ec2;
  4926. }
  4927. }
  4928. if (NULL != hCopyContext)
  4929. {
  4930. //
  4931. // Close RPC copy context
  4932. //
  4933. __try
  4934. {
  4935. ec2 = FAX_EndCopy (&hCopyContext);
  4936. }
  4937. __except (EXCEPTION_EXECUTE_HANDLER)
  4938. {
  4939. //
  4940. // For some reason we got an exception.
  4941. //
  4942. ec2 = GetExceptionCode();
  4943. DebugPrintEx(
  4944. DEBUG_ERR,
  4945. TEXT("Exception on RPC call to FAX_EndCopy. (ec: %ld)"),
  4946. ec2);
  4947. }
  4948. if (ERROR_SUCCESS != ec2)
  4949. {
  4950. DumpRPCExtendedStatus ();
  4951. DebugPrintEx(
  4952. DEBUG_ERR,
  4953. TEXT("FAX_EndCopy failed (ec: %ld)"),
  4954. ec2);
  4955. }
  4956. if (ERROR_SUCCESS == ec)
  4957. {
  4958. //
  4959. // If we had an error during wrapup, propogate it out
  4960. //
  4961. ec = ec2;
  4962. }
  4963. }
  4964. if (NULL != aBuffer)
  4965. {
  4966. MemFree(aBuffer);
  4967. }
  4968. //
  4969. // On down-level clients (<XP), the default viewer (Kodak imaging) can't
  4970. // display files with more than 54 tags. So call TiffLimitTagNumber, which
  4971. // will cut down any tags beyond 54.
  4972. //
  4973. if (ec == ERROR_SUCCESS)
  4974. {
  4975. if (!IsWinXPOS())
  4976. {
  4977. if (!TiffLimitTagNumber(lpctstrFilePath, 54))
  4978. {
  4979. ec = GetLastError();
  4980. DebugPrintEx(DEBUG_ERR, TEXT("TiffLimitTagNumber failed, ec=%d"), ec);
  4981. }
  4982. }
  4983. }
  4984. if (ERROR_SUCCESS != ec)
  4985. {
  4986. //
  4987. // Some error occured - delete the local file (if exists at all)
  4988. //
  4989. if (!DeleteFile (lpctstrFilePath))
  4990. {
  4991. DWORD dwRes = GetLastError ();
  4992. if (ERROR_FILE_NOT_FOUND != dwRes)
  4993. {
  4994. DebugPrintEx(
  4995. DEBUG_ERR,
  4996. TEXT("DeleteFile (%s) return error %ld"),
  4997. lpctstrFilePath,
  4998. dwRes);
  4999. }
  5000. }
  5001. SetLastError (ec);
  5002. return FALSE;
  5003. }
  5004. return TRUE;
  5005. } // FaxGetMessageTiff
  5006. #ifdef UNICODE
  5007. WINFAXAPI
  5008. BOOL
  5009. WINAPI
  5010. FaxGetMessageTiffA (
  5011. IN HANDLE hFaxHandle,
  5012. IN DWORDLONG dwlMessageId,
  5013. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  5014. IN LPCSTR lpctstrFilePath
  5015. )
  5016. /*++
  5017. Routine name : FaxGetMessageTiffA
  5018. Routine description:
  5019. Retrieves a message TIFF from the archive / queue.
  5020. ANSI version for NT clients
  5021. Author:
  5022. Eran Yariv (EranY), Dec, 1999
  5023. Arguments:
  5024. hFaxHandle [in] - handle to fax server
  5025. dwlMessageId [in] - Unique message id
  5026. Folder [in] - Archive / queue folder
  5027. lpctstrFilePath [in] - Path to local file to receive TIFF image
  5028. Return Value:
  5029. TRUE - Success
  5030. FALSE - Failure, call GetLastError() for more error information.
  5031. --*/
  5032. {
  5033. LPWSTR lpwstrFilePath;
  5034. BOOL bRes;
  5035. lpwstrFilePath = AnsiStringToUnicodeString (lpctstrFilePath);
  5036. if (!lpwstrFilePath)
  5037. {
  5038. return FALSE;
  5039. }
  5040. bRes = FaxGetMessageTiffW (hFaxHandle, dwlMessageId, Folder, lpwstrFilePath);
  5041. MemFree ((LPVOID)lpwstrFilePath);
  5042. return bRes;
  5043. } // FaxGetMessageTiffA
  5044. #else
  5045. WINFAXAPI
  5046. BOOL
  5047. WINAPI
  5048. FaxGetMessageTiffW (
  5049. IN HANDLE hFaxHandle,
  5050. IN DWORDLONG dwlMessageId,
  5051. IN FAX_ENUM_MESSAGE_FOLDER Folder,
  5052. IN LPCWSTR lpctstrFilePath
  5053. )
  5054. {
  5055. UNREFERENCED_PARAMETER(hFaxHandle);
  5056. UNREFERENCED_PARAMETER(dwlMessageId);
  5057. UNREFERENCED_PARAMETER(Folder);
  5058. UNREFERENCED_PARAMETER(lpctstrFilePath);
  5059. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  5060. return FALSE;
  5061. } // FaxGetMessageTiffW
  5062. #endif
  5063. //********************************************
  5064. //* Recipients limit in a single broadcast
  5065. //********************************************
  5066. WINFAXAPI
  5067. BOOL
  5068. FaxSetRecipientsLimit(
  5069. IN HANDLE hFaxHandle,
  5070. IN DWORD dwRecipientsLimit
  5071. )
  5072. /*++
  5073. Routine name : FaxSetRecipientsLimit
  5074. Routine description:
  5075. A fax client application calls the FaxSetRecipientsLimit to set the
  5076. recipients limit of a single broadcast job.
  5077. Arguments:
  5078. hFaxHandle - unused
  5079. dwRecipientsLimit - the recipients limit to set
  5080. Return Value:
  5081. Standard Win32 error code
  5082. --*/
  5083. {
  5084. UNREFERENCED_PARAMETER (hFaxHandle);
  5085. UNREFERENCED_PARAMETER (dwRecipientsLimit);
  5086. SetLastError(ERROR_NOT_SUPPORTED);
  5087. return FALSE;
  5088. } // FaxSetRecipientsLimit
  5089. WINFAXAPI
  5090. BOOL
  5091. FaxGetRecipientsLimit(
  5092. IN HANDLE hFaxHandle,
  5093. OUT LPDWORD lpdwRecipientsLimit
  5094. )
  5095. /*++
  5096. Routine name : FaxGetRecipientsLimit
  5097. Routine description:
  5098. A fax client application calls the FaxGetRecipientsLimit to get the
  5099. recipients limit of a single broadcast job.
  5100. Arguments:
  5101. hFaxHandle - handle to fax server
  5102. lpdwRecipientsLimit - pointer to a DWORD to receive the recipients limit
  5103. Return Value:
  5104. Standard Win32 error code
  5105. --*/
  5106. {
  5107. DWORD ec;
  5108. DWORD dwRecipientsLimit;
  5109. DEBUG_FUNCTION_NAME(TEXT("FaxGetRecipientsLimit"));
  5110. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  5111. {
  5112. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  5113. SetLastError (ERROR_INVALID_HANDLE);
  5114. return FALSE;
  5115. }
  5116. if (NULL == lpdwRecipientsLimit)
  5117. {
  5118. DebugPrintEx(DEBUG_ERR, _T("lpdwRecipientsLimit is NULL."));
  5119. SetLastError(ERROR_INVALID_PARAMETER);
  5120. return FALSE;
  5121. }
  5122. if (FAX_API_VERSION_2 > FH_SERVER_VER(hFaxHandle))
  5123. {
  5124. //
  5125. // Servers of API version 0,1 don't support FAX_GetRecipientsLimit
  5126. // These servers have no recipients limit.
  5127. //
  5128. DebugPrintEx(DEBUG_MSG,
  5129. _T("Server version is %ld - No recipients limit"),
  5130. FH_SERVER_VER(hFaxHandle));
  5131. *lpdwRecipientsLimit = 0; // No recipients limit
  5132. return TRUE;
  5133. }
  5134. //
  5135. // Call RPC function.
  5136. //
  5137. __try
  5138. {
  5139. ec = FAX_GetRecipientsLimit(
  5140. FH_FAX_HANDLE(hFaxHandle),
  5141. &dwRecipientsLimit);
  5142. }
  5143. __except (EXCEPTION_EXECUTE_HANDLER)
  5144. {
  5145. //
  5146. // For some reason we got an exception.
  5147. //
  5148. ec = GetExceptionCode();
  5149. DebugPrintEx(
  5150. DEBUG_ERR,
  5151. TEXT("Exception on RPC call to FAX_GetRecipientsLimit. (ec: %ld)"),
  5152. ec);
  5153. }
  5154. if (ERROR_SUCCESS != ec)
  5155. {
  5156. DumpRPCExtendedStatus ();
  5157. SetLastError( ec );
  5158. return FALSE;
  5159. }
  5160. *lpdwRecipientsLimit = dwRecipientsLimit;
  5161. return TRUE;
  5162. } // FaxGetRecipientsLimit
  5163. WINFAXAPI
  5164. BOOL
  5165. FaxGetServerSKU(
  5166. IN HANDLE hFaxHandle,
  5167. OUT PRODUCT_SKU_TYPE* pServerSKU
  5168. )
  5169. /*++
  5170. Routine name : FaxGetServerSKU
  5171. Routine description:
  5172. A fax client application calls the FaxGetRecipientsLimit to get the
  5173. recipients limit of a single broadcast job.
  5174. Arguments:
  5175. hFaxHandle - handle to fax server
  5176. pServerSKU - pointer to a PRODUCT_SKU_TYPE to receive the fax server SKU
  5177. Return Value:
  5178. Standard Win32 error code
  5179. --*/
  5180. {
  5181. DWORD ec;
  5182. PRODUCT_SKU_TYPE ServerSKU;
  5183. DEBUG_FUNCTION_NAME(TEXT("FaxGetServerSKU"));
  5184. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  5185. {
  5186. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  5187. SetLastError (ERROR_INVALID_HANDLE);
  5188. return FALSE;
  5189. }
  5190. if (NULL == pServerSKU)
  5191. {
  5192. DebugPrintEx(DEBUG_ERR, _T("pServerSKU is NULL."));
  5193. SetLastError(ERROR_INVALID_PARAMETER);
  5194. return FALSE;
  5195. }
  5196. if (FAX_API_VERSION_2 > FH_SERVER_VER(hFaxHandle))
  5197. {
  5198. //
  5199. // Servers of API version 0,1 don't support FaxGetServerSKU
  5200. // Call FaxEnumOutboundRules() and check the error code
  5201. //
  5202. DWORD dwNumRules;
  5203. PFAX_OUTBOUND_ROUTING_RULE pRule = NULL;
  5204. if(!FaxEnumOutboundRules(hFaxHandle, &pRule, &dwNumRules))
  5205. {
  5206. ec = GetLastError();
  5207. DebugPrintEx(DEBUG_WRN, _T("FaxEnumOutboundRules() failed with %ld)"), ec);
  5208. if(FAX_ERR_NOT_SUPPORTED_ON_THIS_SKU == ec)
  5209. {
  5210. //
  5211. // Desktop SKU, return PRO
  5212. //
  5213. *pServerSKU = PRODUCT_SKU_PROFESSIONAL;
  5214. }
  5215. else
  5216. {
  5217. *pServerSKU = PRODUCT_SKU_UNKNOWN;
  5218. }
  5219. }
  5220. else
  5221. {
  5222. //
  5223. // Server SKU, return PRODUCT_SKU_DATA_CENTER
  5224. //
  5225. *pServerSKU = PRODUCT_SKU_DATA_CENTER;
  5226. FaxFreeBuffer(pRule);
  5227. }
  5228. return TRUE;
  5229. }
  5230. //
  5231. // The server supports FaxGetServerSKU, Call RPC function.
  5232. //
  5233. __try
  5234. {
  5235. ec = FAX_GetServerSKU(
  5236. FH_FAX_HANDLE(hFaxHandle),
  5237. &ServerSKU);
  5238. }
  5239. __except (EXCEPTION_EXECUTE_HANDLER)
  5240. {
  5241. //
  5242. // For some reason we got an exception.
  5243. //
  5244. ec = GetExceptionCode();
  5245. DebugPrintEx(
  5246. DEBUG_ERR,
  5247. TEXT("Exception on RPC call to FAX_GetServerSKU. (ec: %ld)"),
  5248. ec);
  5249. }
  5250. if (ERROR_SUCCESS != ec)
  5251. {
  5252. DumpRPCExtendedStatus ();
  5253. SetLastError( ec );
  5254. return FALSE;
  5255. }
  5256. *pServerSKU = ServerSKU;
  5257. return TRUE;
  5258. } // FaxGetServerSKU
  5259. WINFAXAPI
  5260. BOOL
  5261. FaxCheckValidFaxFolder(
  5262. IN HANDLE hFaxHandle,
  5263. IN LPCWSTR lpcwstrPath
  5264. )
  5265. /*++
  5266. Routine name : FaxCheckValidFaxFolder
  5267. Routine description:
  5268. Used by fax client application to check if a given path is accessible (valid for use)
  5269. by the fax service.
  5270. Arguments:
  5271. hFaxHandle - handle to fax server
  5272. lpcwstrPath - Path to check
  5273. Return Value:
  5274. TRUE if folder if path can be used by the fax service.
  5275. FALSE otherwise, refer to thread's last error for error code.
  5276. --*/
  5277. {
  5278. DWORD ec;
  5279. DEBUG_FUNCTION_NAME(TEXT("FaxCheckValidFaxFolder"));
  5280. if (!ValidateFaxHandle(hFaxHandle, FHT_SERVICE))
  5281. {
  5282. DebugPrintEx(DEBUG_ERR, _T("ValidateFaxHandle() is failed."));
  5283. SetLastError (ERROR_INVALID_HANDLE);
  5284. return FALSE;
  5285. }
  5286. if (FAX_API_VERSION_2 > FH_SERVER_VER(hFaxHandle))
  5287. {
  5288. //
  5289. // Servers of API version 0,1 don't support FaxCheckValidFaxFolder
  5290. //
  5291. return ERROR_NOT_SUPPORTED;
  5292. }
  5293. //
  5294. // The server supports FaxCheckValidFaxFolder, Call RPC function.
  5295. //
  5296. __try
  5297. {
  5298. ec = FAX_CheckValidFaxFolder(
  5299. FH_FAX_HANDLE(hFaxHandle),
  5300. lpcwstrPath);
  5301. }
  5302. __except (EXCEPTION_EXECUTE_HANDLER)
  5303. {
  5304. //
  5305. // For some reason we got an exception.
  5306. //
  5307. ec = GetExceptionCode();
  5308. DebugPrintEx(
  5309. DEBUG_ERR,
  5310. TEXT("Exception on RPC call to FAX_CheckValidFaxFolder. (ec: %ld)"),
  5311. ec);
  5312. }
  5313. if (ERROR_SUCCESS != ec)
  5314. {
  5315. DumpRPCExtendedStatus ();
  5316. SetLastError (ec);
  5317. return FALSE;
  5318. }
  5319. return TRUE;
  5320. } // FaxCheckValidFaxFolder