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.

844 lines
23 KiB

  1. #include "faxrtp.h"
  2. #pragma hdrstop
  3. HINSTANCE g_hModule;
  4. HINSTANCE g_hResource;
  5. WCHAR FaxReceiveDir[MAX_PATH];
  6. CFaxCriticalSection g_csRoutingStrings;
  7. PFAXROUTEADDFILE FaxRouteAddFile;
  8. PFAXROUTEDELETEFILE FaxRouteDeleteFile;
  9. PFAXROUTEGETFILE FaxRouteGetFile;
  10. PFAXROUTEENUMFILES FaxRouteEnumFiles;
  11. //
  12. // Private callback functions
  13. //
  14. PGETRECIEPTSCONFIGURATION g_pGetRecieptsConfiguration;
  15. PFREERECIEPTSCONFIGURATION g_pFreeRecieptsConfiguration;
  16. extern PFAX_EXT_GET_DATA g_pFaxExtGetData;
  17. extern PFAX_EXT_FREE_BUFFER g_pFaxExtFreeBuffer;
  18. extern "C"
  19. DWORD
  20. DllMain(
  21. HINSTANCE hInstance,
  22. DWORD Reason,
  23. LPVOID Context
  24. )
  25. {
  26. if (Reason == DLL_PROCESS_ATTACH)
  27. {
  28. g_hModule = hInstance;
  29. g_hResource = GetResInstance(hInstance);
  30. if(!g_hResource)
  31. {
  32. return FALSE;
  33. }
  34. FXSEVENTInitialize();
  35. DisableThreadLibraryCalls( hInstance );
  36. }
  37. if (Reason == DLL_PROCESS_DETACH)
  38. {
  39. FXSEVENTFree();
  40. HeapCleanup();
  41. FreeResInstance();
  42. }
  43. return TRUE;
  44. }
  45. BOOL WINAPI
  46. FaxRouteInitialize(
  47. IN HANDLE HeapHandle,
  48. IN PFAX_ROUTE_CALLBACKROUTINES FaxRouteCallbackRoutines
  49. )
  50. {
  51. PFAX_ROUTE_CALLBACKROUTINES_P pFaxRouteCallbackRoutinesP = (PFAX_ROUTE_CALLBACKROUTINES_P)FaxRouteCallbackRoutines;
  52. DEBUG_FUNCTION_NAME(TEXT("FaxRouteInitialize"));
  53. //
  54. // HeapHandle - is unused. We use the process default heap!
  55. //
  56. ZeroMemory (FaxReceiveDir, sizeof(FaxReceiveDir));
  57. FaxRouteAddFile = FaxRouteCallbackRoutines->FaxRouteAddFile;
  58. FaxRouteDeleteFile = FaxRouteCallbackRoutines->FaxRouteDeleteFile;
  59. FaxRouteGetFile = FaxRouteCallbackRoutines->FaxRouteGetFile;
  60. FaxRouteEnumFiles = FaxRouteCallbackRoutines->FaxRouteEnumFiles;
  61. if (!g_csRoutingStrings.InitializeAndSpinCount())
  62. {
  63. DebugPrintEx(DEBUG_ERR, L"InitializeAndSpinCount failed with: %ld", GetLastError());
  64. return FALSE;
  65. }
  66. if (sizeof (FAX_ROUTE_CALLBACKROUTINES_P) == FaxRouteCallbackRoutines->SizeOfStruct)
  67. {
  68. //
  69. // This is a special hack - the service is giving us its private callbacks
  70. //
  71. g_pGetRecieptsConfiguration = pFaxRouteCallbackRoutinesP->GetRecieptsConfiguration;
  72. g_pFreeRecieptsConfiguration = pFaxRouteCallbackRoutinesP->FreeRecieptsConfiguration;
  73. _tcsncpy ( FaxReceiveDir, pFaxRouteCallbackRoutinesP->lptstrFaxQueueDir, ARR_SIZE(FaxReceiveDir)-1 );
  74. }
  75. else
  76. {
  77. //
  78. // The service MUST provide us with the private structure containing CsConfig.
  79. // Otherwise, when we call LoadReceiptsSettings(), we might read half-baked data.
  80. //
  81. ASSERT_FALSE;
  82. }
  83. Assert (_tcslen (FaxReceiveDir));
  84. PREG_FAX_SERVICE pFaxReg = NULL;
  85. if (!InitializeEventLog(&pFaxReg))
  86. {
  87. DebugPrintEx(DEBUG_ERR, L"InitializeEventLog failed with: %ld", GetLastError());
  88. return FALSE;
  89. }
  90. FreeFaxRegistry(pFaxReg);
  91. InitializeStringTable();
  92. DWORD dwRes = g_DevicesMap.Init ();
  93. if (ERROR_SUCCESS != dwRes)
  94. {
  95. SetLastError (dwRes);
  96. return FALSE;
  97. }
  98. return TRUE;
  99. } // FaxRouteInitialize
  100. BOOL WINAPI
  101. FaxRoutePrint(
  102. const FAX_ROUTE *FaxRoute,
  103. PVOID *FailureData,
  104. LPDWORD FailureDataSize
  105. )
  106. {
  107. CDeviceRoutingInfo *pDevInfo;
  108. WCHAR NameBuffer[MAX_PATH];
  109. LPCWSTR FBaseName;
  110. WCHAR TiffFileName[MAX_PATH];
  111. DWORD Size;
  112. wstring strPrint;
  113. DEBUG_FUNCTION_NAME(TEXT("FaxRoutePrint"));
  114. pDevInfo = g_DevicesMap.GetDeviceRoutingInfo ( FaxRoute->DeviceId );
  115. if (!pDevInfo)
  116. {
  117. DebugPrintEx (DEBUG_ERR,
  118. L"GetDeviceRoutingInfo failed with %ld",
  119. GetLastError ());
  120. return FALSE;
  121. }
  122. if (!pDevInfo->IsPrintEnabled())
  123. {
  124. DebugPrintEx (DEBUG_MSG,
  125. L"Routing to printer is disabled for device %ld",
  126. FaxRoute->DeviceId);
  127. return TRUE;
  128. }
  129. Size = sizeof(TiffFileName);
  130. if (!FaxRouteGetFile(
  131. FaxRoute->JobId,
  132. 1,
  133. TiffFileName,
  134. &Size))
  135. {
  136. DebugPrintEx (DEBUG_MSG,
  137. L"FaxRouteGetFile failed with %ld",
  138. GetLastError ());
  139. return FALSE;
  140. }
  141. //
  142. // print the fax in requested to do so
  143. //
  144. //
  145. // NOTICE: If the supplied printer name is an empty string,
  146. // the code retrieves the name of the default printer installed.
  147. //
  148. if (!pDevInfo->GetPrinter(strPrint))
  149. {
  150. DebugPrintEx ( DEBUG_ERR,
  151. L"GetPrinter failed with %ld",
  152. GetLastError ());
  153. return FALSE;
  154. }
  155. if (strPrint.length() == 0)
  156. {
  157. GetProfileString( L"windows",
  158. L"device",
  159. L",,,",
  160. (LPWSTR) NameBuffer,
  161. MAX_PATH
  162. );
  163. FBaseName = NameBuffer;
  164. }
  165. else
  166. {
  167. FBaseName = strPrint.c_str();
  168. }
  169. return TiffRoutePrint( TiffFileName, (LPTSTR)FBaseName );
  170. } // FaxRoutePrint
  171. BOOL WINAPI
  172. FaxRouteStore(
  173. const FAX_ROUTE *FaxRoute,
  174. PVOID *FailureData,
  175. LPDWORD FailureDataSize
  176. )
  177. {
  178. CDeviceRoutingInfo *pDevInfo;
  179. WCHAR TiffFileName[MAX_PATH * 2]={0};
  180. DWORD Size;
  181. LPTSTR FullPath = NULL;
  182. DWORD StrCount;
  183. wstring strFolder;
  184. DEBUG_FUNCTION_NAME(TEXT("FaxRouteStore"));
  185. pDevInfo = g_DevicesMap.GetDeviceRoutingInfo( FaxRoute->DeviceId );
  186. if (!pDevInfo)
  187. {
  188. DebugPrintEx (DEBUG_ERR,
  189. L"GetDeviceRoutingInfo failed with %ld",
  190. GetLastError ());
  191. return FALSE;
  192. }
  193. if (!pDevInfo->IsStoreEnabled())
  194. {
  195. DebugPrintEx (DEBUG_MSG,
  196. L"Routing to folder is disabled for device %ld",
  197. FaxRoute->DeviceId);
  198. return TRUE;
  199. }
  200. //
  201. // Get the file name
  202. //
  203. Size = sizeof(TiffFileName);
  204. if (!FaxRouteGetFile(
  205. FaxRoute->JobId,
  206. 1,
  207. TiffFileName,
  208. &Size))
  209. {
  210. DebugPrintEx (DEBUG_MSG,
  211. L"FaxRouteGetFile failed with %ld",
  212. GetLastError ());
  213. return FALSE;
  214. }
  215. if (!pDevInfo->GetStoreFolder(strFolder))
  216. {
  217. DebugPrintEx ( DEBUG_ERR,
  218. L"GetStoreFolder failed with %ld",
  219. GetLastError ());
  220. return FALSE;
  221. }
  222. if (strFolder.length() == 0)
  223. {
  224. SetLastError (ERROR_BAD_CONFIGURATION);
  225. DebugPrintEx (DEBUG_MSG,
  226. L"Folder name is empty - no configuration",
  227. FaxRoute->DeviceId);
  228. FaxLog(
  229. FAXLOG_CATEGORY_INBOUND,
  230. FAXLOG_LEVEL_MIN,
  231. 3,
  232. MSG_FAX_SAVE_FAILED,
  233. TiffFileName,
  234. TEXT(""),
  235. DWORD2HEX(ERROR_BAD_CONFIGURATION)
  236. );
  237. return FALSE;
  238. }
  239. StrCount = ExpandEnvironmentStrings( strFolder.c_str(), FullPath, 0 );
  240. FullPath = (LPWSTR) MemAlloc( StrCount * sizeof(WCHAR) );
  241. if (!FullPath)
  242. {
  243. DebugPrintEx (DEBUG_ERR,
  244. L"Failed to allocate %ld bytes",
  245. StrCount * sizeof(WCHAR));
  246. return FALSE;
  247. }
  248. ExpandEnvironmentStrings( strFolder.c_str(), FullPath, StrCount );
  249. if (lstrlen (FullPath) > MAX_PATH)
  250. {
  251. DebugPrintEx (DEBUG_ERR,
  252. L"Store folder name exceeds MAX_PATH chars");
  253. SetLastError (ERROR_BUFFER_OVERFLOW);
  254. FaxLog(
  255. FAXLOG_CATEGORY_INBOUND,
  256. FAXLOG_LEVEL_MIN,
  257. 3,
  258. MSG_FAX_SAVE_FAILED,
  259. TiffFileName,
  260. FullPath,
  261. DWORD2HEX(ERROR_BUFFER_OVERFLOW)
  262. );
  263. MemFree( FullPath );
  264. return FALSE;
  265. }
  266. //
  267. // If we are moving the fax to the directory that is was received into, do nothing to the file
  268. //
  269. if (_wcsicmp( FullPath, FaxReceiveDir ) == 0)
  270. {
  271. FaxLog(
  272. FAXLOG_CATEGORY_INBOUND,
  273. FAXLOG_LEVEL_MAX,
  274. 2,
  275. MSG_FAX_SAVE_SUCCESS,
  276. TiffFileName,
  277. TiffFileName
  278. );
  279. }
  280. else if (!FaxMoveFile ( TiffFileName, FullPath ))
  281. {
  282. MemFree( FullPath );
  283. return FALSE;
  284. }
  285. MemFree( FullPath );
  286. return TRUE;
  287. } // FaxRouteStore
  288. BOOL
  289. CreateMailBodyAndSubject (
  290. const FAX_ROUTE *pFaxRoute,
  291. LPTSTR *plptstrSubject,
  292. LPTSTR *plptstrBody
  293. )
  294. /*++
  295. Routine name : CreateMailBodyAndSubject
  296. Routine description:
  297. Creates the SMTP mail subject and body.
  298. Used by route by SMTP routing method
  299. Author:
  300. Eran Yariv (EranY), Jul, 2000
  301. Arguments:
  302. pFaxRoute [in] - Routing information
  303. plptstrSubject [out] - Allocated subject. Free with LocalFree
  304. plptstrBody [out] - Allocated body. Free with LocalFree
  305. Return Value:
  306. TRUE if successful, FALSE otherwise.
  307. --*/
  308. {
  309. WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  310. WCHAR wszElapsedTimeStr[512];
  311. WCHAR wszStartTimeStr[512];
  312. LPCTSTR lpctstrRecipientStr;
  313. LPCTSTR lpctstrSenderStr;
  314. LPDWORD MsgPtr[7];
  315. DWORD MsgCount;
  316. LPWSTR lpwstrMsgBody = NULL;
  317. LPWSTR lpwstrMsgSubject = NULL;
  318. DEBUG_FUNCTION_NAME(TEXT("CreateMailBodyAndSubject"));
  319. Assert (pFaxRoute && plptstrSubject && plptstrBody);
  320. //
  321. // Get computer name
  322. //
  323. DWORD dwComputerNameSize = sizeof (wszComputerName) / sizeof (wszComputerName[0]);
  324. if (!GetComputerName (wszComputerName, &dwComputerNameSize))
  325. {
  326. DebugPrintEx (DEBUG_ERR,
  327. L"GetComputerName failed. ec = %ld",
  328. GetLastError ());
  329. goto error;
  330. }
  331. //
  332. // Create elapsed time string
  333. //
  334. if (!FormatElapsedTimeStr(
  335. (FILETIME*)&pFaxRoute->ElapsedTime,
  336. wszElapsedTimeStr,
  337. ARR_SIZE(wszElapsedTimeStr)))
  338. {
  339. DebugPrintEx (DEBUG_ERR,
  340. L"FormatElapsedTimeStr failed. ec = %ld",
  341. GetLastError ());
  342. goto error;
  343. }
  344. //
  345. // Create start time string
  346. //
  347. SYSTEMTIME stStartTime;
  348. FILETIME tmLocalTime;
  349. //
  350. // Convert time from UTC to local time zone
  351. //
  352. if (!FileTimeToLocalFileTime( (FILETIME*)&(pFaxRoute->ReceiveTime), &tmLocalTime ))
  353. {
  354. DebugPrintEx(
  355. DEBUG_ERR,
  356. TEXT("FileTimeToLocalFileTime failed. (ec: %ld)"),
  357. GetLastError());
  358. goto error;
  359. }
  360. if (!FileTimeToSystemTime( &tmLocalTime, &stStartTime ))
  361. {
  362. DebugPrintEx(
  363. DEBUG_ERR,
  364. TEXT("FileTimeToSystemTime failed. (ec: %ld)"),
  365. GetLastError());
  366. goto error;
  367. }
  368. if (!FaxTimeFormat (
  369. LOCALE_SYSTEM_DEFAULT,
  370. 0,
  371. &stStartTime,
  372. NULL,
  373. wszStartTimeStr,
  374. sizeof (wszStartTimeStr) / sizeof (wszStartTimeStr[0])))
  375. {
  376. DebugPrintEx (DEBUG_ERR,
  377. L"FaxTimeFormat failed. ec = %ld",
  378. GetLastError ());
  379. goto error;
  380. }
  381. //
  382. // Extract recipient name
  383. //
  384. if (!pFaxRoute->RoutingInfo || !pFaxRoute->RoutingInfo[0])
  385. {
  386. if (pFaxRoute->Csid && lstrlen (pFaxRoute->Csid))
  387. {
  388. //
  389. // Use CSID as recipient name
  390. //
  391. lpctstrRecipientStr = pFaxRoute->Csid;
  392. }
  393. else
  394. {
  395. //
  396. // No routing info and no CSID: use string from resource
  397. //
  398. lpctstrRecipientStr = GetString (IDS_UNKNOWN_RECIPIENT);
  399. }
  400. }
  401. else
  402. {
  403. //
  404. // Use routing info as recipient name
  405. //
  406. lpctstrRecipientStr = pFaxRoute->RoutingInfo;
  407. }
  408. //
  409. // Extract sender name
  410. //
  411. if (pFaxRoute->Tsid && lstrlen (pFaxRoute->Tsid))
  412. {
  413. //
  414. // Use TSID as sender
  415. //
  416. lpctstrSenderStr = pFaxRoute->Tsid;
  417. }
  418. else
  419. {
  420. //
  421. // No TSID: use string from resource
  422. //
  423. lpctstrSenderStr = GetString(IDS_UNKNOWN_SENDER);
  424. }
  425. //
  426. // Create mail body
  427. //
  428. MsgPtr[0] = (LPDWORD) (lpctstrSenderStr ? lpctstrSenderStr : TEXT("")); // Sender
  429. MsgPtr[1] = (LPDWORD) (pFaxRoute->CallerId ? pFaxRoute->CallerId : TEXT("")); // CallerID
  430. MsgPtr[2] = (LPDWORD) (lpctstrRecipientStr ? lpctstrRecipientStr : TEXT("")); // Recipient name
  431. MsgPtr[3] = (LPDWORD) ULongToPtr((pFaxRoute->PageCount)); // Pages
  432. MsgPtr[4] = (LPDWORD) wszStartTimeStr; // Transmission time
  433. MsgPtr[5] = (LPDWORD) wszElapsedTimeStr; // Transmission duration
  434. MsgPtr[6] = (LPDWORD) (pFaxRoute->DeviceName ? pFaxRoute->DeviceName : TEXT("")); // Device name
  435. MsgCount = FormatMessage(
  436. FORMAT_MESSAGE_FROM_HMODULE |
  437. FORMAT_MESSAGE_ARGUMENT_ARRAY |
  438. FORMAT_MESSAGE_ALLOCATE_BUFFER,
  439. g_hResource,
  440. MSG_MAIL_MSG_BODY,
  441. MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
  442. (LPWSTR)&lpwstrMsgBody,
  443. 0,
  444. (va_list *) MsgPtr
  445. );
  446. if (!MsgCount)
  447. {
  448. DebugPrintEx (DEBUG_ERR,
  449. L"FormatMessage failed. ec = %ld",
  450. GetLastError ());
  451. goto error;
  452. }
  453. //
  454. // Create subject line
  455. //
  456. MsgPtr[0] = (LPDWORD) wszComputerName; // Computer name
  457. MsgPtr[1] = (LPDWORD) (lpctstrSenderStr ? lpctstrSenderStr : TEXT("")); // Sender
  458. MsgCount = FormatMessage(
  459. FORMAT_MESSAGE_FROM_HMODULE |
  460. FORMAT_MESSAGE_ARGUMENT_ARRAY |
  461. FORMAT_MESSAGE_ALLOCATE_BUFFER,
  462. g_hResource,
  463. MSG_SUBJECT_LINE,
  464. MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
  465. (LPWSTR)&lpwstrMsgSubject,
  466. 0,
  467. (va_list *) MsgPtr
  468. );
  469. if (!MsgCount)
  470. {
  471. DebugPrintEx (DEBUG_ERR,
  472. L"FormatMessage failed. ec = %ld",
  473. GetLastError ());
  474. goto error;
  475. }
  476. //
  477. // Success
  478. //
  479. *plptstrSubject = lpwstrMsgSubject;
  480. *plptstrBody = lpwstrMsgBody;
  481. return TRUE;
  482. error:
  483. if (lpwstrMsgSubject)
  484. {
  485. LocalFree (lpwstrMsgSubject);
  486. }
  487. if (lpwstrMsgBody)
  488. {
  489. LocalFree (lpwstrMsgBody);
  490. }
  491. return FALSE;
  492. } // CreateMailBodyAndSubject
  493. BOOL
  494. MailIncomingJob(
  495. const FAX_ROUTE *pFaxRoute,
  496. LPCWSTR lpcwstrMailTo,
  497. LPCWSTR TiffFileName
  498. )
  499. /*++
  500. Routine Description:
  501. Mails a TIFF file using CDO2
  502. Arguments:
  503. pFaxRoute [in] - Routing information
  504. lpcwstrMailTo [in] - Email recipient address
  505. TiffFileName [in] - Name of TIFF file to mail
  506. Return Value:
  507. TRUE for success, FALSE on error
  508. --*/
  509. {
  510. LPWSTR lpwstrMsgBody = NULL;
  511. LPWSTR lpwstrMsgSubject = NULL;
  512. HRESULT hr;
  513. BOOL bRes = FALSE;
  514. DWORD dwRes;
  515. PFAX_SERVER_RECEIPTS_CONFIGW pReceiptsConfiguration = NULL;
  516. DEBUG_FUNCTION_NAME(TEXT("MailIncomingJob"));
  517. //
  518. // Read current mail configuration
  519. //
  520. dwRes = g_pGetRecieptsConfiguration (&pReceiptsConfiguration, TRUE);
  521. if (ERROR_SUCCESS != dwRes)
  522. {
  523. DebugPrintEx(
  524. DEBUG_ERR,
  525. TEXT("GetRecieptsConfiguration failed with %ld"),
  526. dwRes);
  527. goto exit;
  528. }
  529. //
  530. // Get body and subject
  531. //
  532. if (!CreateMailBodyAndSubject (pFaxRoute, &lpwstrMsgSubject, &lpwstrMsgBody))
  533. {
  534. dwRes = GetLastError ();
  535. DebugPrintEx(
  536. DEBUG_ERR,
  537. TEXT("CreateMailBodyAndSubject failed with %ld"),
  538. dwRes);
  539. goto exit;
  540. }
  541. //
  542. // Send the mail
  543. //
  544. hr = SendMail (
  545. pReceiptsConfiguration->lptstrSMTPFrom, // From
  546. lpcwstrMailTo, // To
  547. lpwstrMsgSubject, // Subject
  548. lpwstrMsgBody, // Body
  549. NULL, // HTML Body
  550. TiffFileName, // Attachment
  551. TEXT("FAX.TIF"), // Attachment description
  552. pReceiptsConfiguration->lptstrSMTPServer, // SMTP server
  553. pReceiptsConfiguration->dwSMTPPort, // SMTP port
  554. (pReceiptsConfiguration->SMTPAuthOption == FAX_SMTP_AUTH_ANONYMOUS) ?
  555. CDO_AUTH_ANONYMOUS :
  556. (pReceiptsConfiguration->SMTPAuthOption == FAX_SMTP_AUTH_BASIC) ?
  557. CDO_AUTH_BASIC : CDO_AUTH_NTLM, // Authentication type
  558. pReceiptsConfiguration->lptstrSMTPUserName, // User name
  559. pReceiptsConfiguration->lptstrSMTPPassword, // Password
  560. pReceiptsConfiguration->hLoggedOnUser); // Logged on user token
  561. if (FAILED(hr))
  562. {
  563. DebugPrintEx(
  564. DEBUG_ERR,
  565. TEXT("SendMail failed. (hr: 0x%08x)"),
  566. hr);
  567. dwRes = hr;
  568. goto exit;
  569. }
  570. bRes = TRUE;
  571. exit:
  572. if (lpwstrMsgSubject)
  573. {
  574. LocalFree (lpwstrMsgSubject);
  575. }
  576. if (lpwstrMsgBody)
  577. {
  578. LocalFree (lpwstrMsgBody);
  579. }
  580. if (NULL != pReceiptsConfiguration)
  581. {
  582. g_pFreeRecieptsConfiguration( pReceiptsConfiguration, TRUE);
  583. }
  584. if (bRes)
  585. {
  586. //
  587. // Mail is sent OK
  588. //
  589. FaxLog(FAXLOG_CATEGORY_INBOUND,
  590. FAXLOG_LEVEL_MAX,
  591. 1,
  592. MSG_FAX_ROUTE_EMAIL_SUCCESS,
  593. TiffFileName);
  594. }
  595. else
  596. {
  597. FaxLog(FAXLOG_CATEGORY_INBOUND,
  598. FAXLOG_LEVEL_MIN,
  599. 2,
  600. MSG_FAX_ROUTE_EMAIL_FAILED,
  601. TiffFileName,
  602. DWORD2HEX(dwRes));
  603. }
  604. return bRes;
  605. } // MailIncomingJob
  606. BOOL WINAPI
  607. FaxRouteEmail(
  608. const FAX_ROUTE *pFaxRoute,
  609. PVOID *FailureData,
  610. LPDWORD FailureDataSize
  611. )
  612. {
  613. CDeviceRoutingInfo *pDevInfo;
  614. WCHAR wszTiffFileName[MAX_PATH];
  615. DWORD dwSize;
  616. wstring strSMTP;
  617. DEBUG_FUNCTION_NAME(TEXT("FaxRouteEmail"));
  618. pDevInfo = g_DevicesMap.GetDeviceRoutingInfo( pFaxRoute->DeviceId );
  619. if (!pDevInfo)
  620. {
  621. DebugPrintEx (DEBUG_ERR,
  622. L"Could not retrieve routing info for device %ld. ec = %ld",
  623. pFaxRoute->DeviceId,
  624. GetLastError ());
  625. return FALSE;
  626. }
  627. if (!pDevInfo->GetSMTPTo(strSMTP))
  628. {
  629. DebugPrintEx ( DEBUG_ERR,
  630. L"GetSMTPTo failed with %ld",
  631. GetLastError ());
  632. return FALSE;
  633. }
  634. if (!pDevInfo->IsEmailEnabled())
  635. {
  636. DebugPrintEx (DEBUG_MSG,
  637. L"email is disabled for device %ld. Not sending",
  638. pFaxRoute->DeviceId);
  639. return TRUE;
  640. }
  641. //
  642. // Get full TIFF file
  643. //
  644. dwSize = sizeof(wszTiffFileName);
  645. if (!FaxRouteGetFile(
  646. pFaxRoute->JobId,
  647. 1,
  648. wszTiffFileName,
  649. &dwSize))
  650. {
  651. DebugPrintEx (DEBUG_ERR,
  652. L"FaxRouteGetFile for job %ld. ec = %ld",
  653. pFaxRoute->JobId,
  654. GetLastError ());
  655. return FALSE;
  656. }
  657. if (strSMTP.length() == 0)
  658. {
  659. SetLastError (ERROR_BAD_CONFIGURATION);
  660. DebugPrintEx (DEBUG_MSG,
  661. L"address is empty for device %ld. Not sending",
  662. pFaxRoute->DeviceId);
  663. FaxLog(
  664. FAXLOG_CATEGORY_INBOUND,
  665. FAXLOG_LEVEL_MAX,
  666. 2,
  667. MSG_FAX_ROUTE_EMAIL_FAILED,
  668. wszTiffFileName,
  669. DWORD2HEX(ERROR_BAD_CONFIGURATION)
  670. );
  671. return FALSE;
  672. }
  673. //
  674. // Mail the new fax TIFF
  675. //
  676. if (!MailIncomingJob( pFaxRoute, strSMTP.c_str(), wszTiffFileName ))
  677. {
  678. DebugPrintEx (DEBUG_ERR,
  679. L"MailIncomingJob for job %ld. ec = %ld",
  680. pFaxRoute->JobId,
  681. GetLastError ());
  682. return FALSE;
  683. }
  684. return TRUE;
  685. } // FaxRouteEmail
  686. BOOL WINAPI
  687. FaxRouteConfigure(
  688. OUT HPROPSHEETPAGE *PropSheetPage
  689. )
  690. {
  691. return TRUE;
  692. }
  693. BOOL WINAPI
  694. FaxRouteDeviceEnable(
  695. IN LPCWSTR lpcwstrRoutingGuid,
  696. IN DWORD dwDeviceId,
  697. IN LONG bEnabled
  698. )
  699. {
  700. DEBUG_FUNCTION_NAME(TEXT("FaxRouteDeviceEnable"));
  701. DWORD MaskBit = GetMaskBit( lpcwstrRoutingGuid );
  702. if (MaskBit == 0)
  703. {
  704. return FALSE;
  705. }
  706. CDeviceRoutingInfo *pDeviceProp = g_DevicesMap.GetDeviceRoutingInfo (dwDeviceId);
  707. if (!pDeviceProp)
  708. {
  709. return FALSE;
  710. }
  711. DWORD dwRes;
  712. switch (MaskBit)
  713. {
  714. case LR_EMAIL:
  715. if (QUERY_STATUS == bEnabled)
  716. {
  717. return pDeviceProp->IsEmailEnabled ();
  718. }
  719. dwRes = pDeviceProp->EnableEmail (bEnabled);
  720. break;
  721. case LR_STORE:
  722. if (QUERY_STATUS == bEnabled)
  723. {
  724. return pDeviceProp->IsStoreEnabled ();
  725. }
  726. dwRes = pDeviceProp->EnableStore (bEnabled);
  727. break;
  728. case LR_PRINT:
  729. if (QUERY_STATUS == bEnabled)
  730. {
  731. return pDeviceProp->IsPrintEnabled ();
  732. }
  733. dwRes = pDeviceProp->EnablePrint (bEnabled);
  734. break;
  735. default:
  736. ASSERT_FALSE;
  737. SetLastError (ERROR_GEN_FAILURE);
  738. return FALSE;
  739. }
  740. SetLastError (dwRes);
  741. return ERROR_SUCCESS == dwRes ? TRUE : FALSE;
  742. } // FaxRouteDeviceEnable
  743. BOOL WINAPI
  744. FaxRouteDeviceChangeNotification(
  745. IN DWORD dwDeviceId,
  746. IN BOOL bNewDevice
  747. )
  748. {
  749. DEBUG_FUNCTION_NAME(TEXT("FaxRouteDeviceChangeNotification"));
  750. //
  751. // We don't care about new devices now.
  752. // We're using a late-discovery cache so we'll discover the device once
  753. // we route something from it or once it is configured for routing.
  754. //
  755. return TRUE;
  756. UNREFERENCED_PARAMETER (dwDeviceId);
  757. UNREFERENCED_PARAMETER (bNewDevice);
  758. } // FaxRouteDeviceChangeNotification