Source code of Windows XP (NT5)
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.

933 lines
25 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. faxsiren.cpp
  5. Abstract:
  6. sample routing extension. Sets an event when a fax is received, writes routing data into a log file.
  7. --*/
  8. #include <windows.h>
  9. #include <tchar.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <faxroute.h>
  13. #include <winfax.h>
  14. //
  15. // macros
  16. //
  17. #define ValidString( String ) ((String) ? (String) : L"" )
  18. #ifdef DBG
  19. #define MYDEBUG( parm ) DebugPrint parm
  20. #else
  21. #define MYDEBUG( parm )
  22. #endif
  23. //
  24. // constants
  25. //
  26. #define ROUTEITGUID L"{5797dee0-e738-11d0-83c0-00c04fb6e984}"
  27. #define FAXSIREN L"FaxSirenEvent"
  28. #define LOGNAME L"%temp%\\ReceiveLog.txt"
  29. #define ININAME L"%temp%\\FaxRoute.ini"
  30. #define SIRENDIR L"FaxSirenFolder"
  31. #define EXTENSIONNAME L"FaxSiren Routing Extension"
  32. #define EXTENSIONFRIENDLYNAME L"Fax Siren"
  33. #define EXTENSIONPATH L"%systemroot%\\system32\\faxsiren.dll"
  34. #define FAXSIRENMETHOD L"Siren"
  35. #define FAXSIRENFRIENDLYNAME L"Routing Siren"
  36. #define FAXSIRENFUNCTION L"RouteIt"
  37. //
  38. // forward declarations
  39. //
  40. BOOL
  41. WriteRoutingInfoIntoIniFile(
  42. LPWSTR TiffFileName,
  43. PFAX_ROUTE FaxRoute
  44. );
  45. BOOL
  46. AppendFileNametoLogFile(
  47. LPWSTR TiffFileName,
  48. PFAX_ROUTE FaxRoute
  49. );
  50. void
  51. DebugPrint(
  52. LPWSTR,
  53. ...
  54. );
  55. BOOL WINAPI
  56. ExtensionCallback(
  57. IN HANDLE FaxHandle,
  58. IN LPVOID Context,
  59. IN OUT LPWSTR MethodName,
  60. IN OUT LPWSTR FriendlyName,
  61. IN OUT LPWSTR FunctionName,
  62. IN OUT LPWSTR Guid
  63. );
  64. //
  65. // globals
  66. //
  67. PFAXROUTEADDFILE FaxRouteAddFile;
  68. PFAXROUTEDELETEFILE FaxRouteDeleteFile;
  69. PFAXROUTEGETFILE FaxRouteGetFile;
  70. PFAXROUTEENUMFILES FaxRouteEnumFiles;
  71. PFAXROUTEMODIFYROUTINGDATA FaxRouteModifyRoutingData;
  72. HANDLE hHeap;
  73. HANDLE hReceiveEvent;
  74. CRITICAL_SECTION csRoute;
  75. LPWSTR IniFile = NULL;
  76. LPWSTR LogFile = NULL;
  77. HINSTANCE MyhInstance;
  78. extern "C"
  79. DWORD
  80. DllEntry(
  81. HINSTANCE hInstance,
  82. DWORD Reason,
  83. LPVOID Context
  84. )
  85. /*++
  86. Routine Description:
  87. dll entrypoint
  88. Arguments:
  89. hInstance - Module handle
  90. Reason - Reason for being called
  91. Context - Register context
  92. Return Value:
  93. TRUE for success, otherwise FALSE.
  94. --*/
  95. {
  96. switch (Reason) {
  97. case DLL_PROCESS_ATTACH:
  98. MyhInstance = hInstance;
  99. DisableThreadLibraryCalls(hInstance);
  100. break;
  101. case DLL_PROCESS_DETACH:
  102. //
  103. // cleanup
  104. //
  105. if (hReceiveEvent) CloseHandle(hReceiveEvent);
  106. break;
  107. }
  108. return TRUE;
  109. }
  110. STDAPI
  111. DllRegisterServer(
  112. VOID
  113. )
  114. /*++
  115. Routine Description:
  116. Function for the in-process server to create its registry entries
  117. Return Value:
  118. S_OK on success
  119. Notes:
  120. We leverage the DllRegisterServer entrypoint as an easy way to configure
  121. our routing extension for use on the system. Note that the extension doesn't
  122. have any COM code in it per se, but this makes installation much simpler since
  123. the setup code doesn't have to use custom code to setup the routing extension.
  124. --*/
  125. {
  126. HRESULT RetCode;
  127. HMODULE hWinFax;
  128. PFAXREGISTERROUTINGEXTENSION pFaxRegisterRoutingExtension;
  129. PFAXCONNECTFAXSERVER pFaxConnectFaxServer;
  130. PFAXCLOSE pFaxClose;
  131. HANDLE hFax;
  132. DWORD ExtensionCount = 0;
  133. //
  134. // we assume that the routing extension has already been installed into the
  135. // proper location by the setup code.
  136. //
  137. hWinFax = LoadLibrary( L"winfax.dll" );
  138. if (!hWinFax) {
  139. MYDEBUG(( L"LoadLibrary failed, ec = %d\n", GetLastError() ));
  140. RetCode = E_UNEXPECTED;
  141. goto e0;
  142. }
  143. pFaxRegisterRoutingExtension = (PFAXREGISTERROUTINGEXTENSION) GetProcAddress(
  144. hWinFax,
  145. "FaxRegisterRoutingExtensionW" );
  146. pFaxConnectFaxServer = (PFAXCONNECTFAXSERVER) GetProcAddress(
  147. hWinFax,
  148. "FaxConnectFaxServerW" );
  149. pFaxClose = (PFAXCLOSE) GetProcAddress(
  150. hWinFax,
  151. "FaxClose" );
  152. if (!pFaxRegisterRoutingExtension || !pFaxConnectFaxServer || !pFaxClose) {
  153. MYDEBUG(( L"GetProcAddress failed, ec = %d\n", GetLastError() ));
  154. RetCode = E_UNEXPECTED;
  155. goto e1;
  156. }
  157. if (!pFaxConnectFaxServer( NULL, &hFax )) {
  158. MYDEBUG(( L"FaxConnectFaxServer failed, ec = %d\n", GetLastError() ));
  159. RetCode = HRESULT_FROM_WIN32( GetLastError() );
  160. goto e1;
  161. }
  162. if (!pFaxRegisterRoutingExtension(
  163. hFax,
  164. EXTENSIONNAME,
  165. EXTENSIONFRIENDLYNAME,
  166. EXTENSIONPATH,
  167. ExtensionCallback,
  168. (LPVOID) &ExtensionCount
  169. )) {
  170. MYDEBUG(( L"FaxRegisterRoutingExtension failed, ec = %d\n", GetLastError() ));
  171. RetCode = HRESULT_FROM_WIN32( GetLastError() );
  172. goto e2;
  173. }
  174. RetCode = S_OK;
  175. e2:
  176. pFaxClose( hFax );
  177. e1:
  178. FreeLibrary( hWinFax );
  179. e0:
  180. return RetCode;
  181. }
  182. BOOL WINAPI
  183. ExtensionCallback(
  184. IN HANDLE FaxHandle,
  185. IN LPVOID Context,
  186. IN OUT LPWSTR MethodName,
  187. IN OUT LPWSTR FriendlyName,
  188. IN OUT LPWSTR FunctionName,
  189. IN OUT LPWSTR Guid
  190. )
  191. /*++
  192. Routine Description:
  193. Callback function for adding our routing extensions
  194. Return Value:
  195. TRUE if we added another extension, FALSE if we're done adding extensions
  196. --*/
  197. {
  198. PDWORD ExtensionCount = (PDWORD) Context;
  199. //
  200. // since we only have one extension, this is a really simple function
  201. // --we don't really need the context data above, it's just here to
  202. // illustrate what you might use the context data for.
  203. //
  204. if (ExtensionCount) {
  205. MYDEBUG(( L"ExtensionCallback called for extension %d\n", *ExtensionCount ));
  206. } else {
  207. MYDEBUG(( L"context data is NULL, can't continue\n", *ExtensionCount ));
  208. return FALSE;
  209. }
  210. if (*ExtensionCount != 0) {
  211. //
  212. // we've added all of our methods, return FALSE to signify that we're done
  213. //
  214. return FALSE;
  215. }
  216. wcscpy(MethodName, FAXSIRENMETHOD );
  217. wcscpy(FriendlyName, FAXSIRENFRIENDLYNAME );
  218. wcscpy(FunctionName, FAXSIRENFUNCTION );
  219. wcscpy(Guid, ROUTEITGUID );
  220. *ExtensionCount += 1;
  221. return TRUE;
  222. }
  223. //
  224. // required exports
  225. //
  226. BOOL WINAPI
  227. FaxRouteInitialize(
  228. IN HANDLE HeapHandle,
  229. IN PFAX_ROUTE_CALLBACKROUTINES FaxRouteCallbackRoutines
  230. )
  231. /*++
  232. Routine Description:
  233. This functions is called by the fax service to initialize the routing extension. This function
  234. should only be called once per instantiation of the fax service
  235. Arguments:
  236. HeapHandle - Heap handle for memory all allocations
  237. FaxRouteCallbackRoutines - structure containing callback functions
  238. Return Value:
  239. TRUE for success, otherwise FALSE.
  240. --*/
  241. {
  242. DWORD dwNeeded;
  243. SECURITY_DESCRIPTOR sd;
  244. SECURITY_ATTRIBUTES sa;
  245. //
  246. // make sure we can understand the structure
  247. //
  248. if ( FaxRouteCallbackRoutines->SizeOfStruct < sizeof(FAX_ROUTE_CALLBACKROUTINES) ) {
  249. MYDEBUG ((L"The passed in SizeOfStruct (%d) is smaller than expected (%d) ",
  250. FaxRouteCallbackRoutines->SizeOfStruct,
  251. sizeof(FAX_ROUTE_CALLBACKROUTINES) ));
  252. return FALSE;
  253. }
  254. hHeap = HeapHandle;
  255. FaxRouteAddFile = FaxRouteCallbackRoutines->FaxRouteAddFile;
  256. FaxRouteDeleteFile = FaxRouteCallbackRoutines->FaxRouteDeleteFile;
  257. FaxRouteGetFile = FaxRouteCallbackRoutines->FaxRouteGetFile;
  258. FaxRouteEnumFiles = FaxRouteCallbackRoutines->FaxRouteEnumFiles;
  259. FaxRouteModifyRoutingData = FaxRouteCallbackRoutines->FaxRouteModifyRoutingData;
  260. InitializeCriticalSection( &csRoute );
  261. //
  262. // create a named event
  263. //
  264. // note that we need to create a security descriptor with a NULL DACL (all access) because we want the named
  265. // event to be opened by programs that might not be running in same context as the fax service
  266. //
  267. if ( !InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION) ) {
  268. MYDEBUG(( L"InitializeSecurityDecriptor failed, ec = %d\n", GetLastError() ));
  269. return FALSE;
  270. }
  271. if ( !SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE) ) {
  272. MYDEBUG(( L"SetSecurityDescriptorDacl failed, ec = %d\n", GetLastError() ));
  273. return FALSE;
  274. }
  275. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  276. sa.lpSecurityDescriptor = &sd;
  277. sa.bInheritHandle = FALSE;
  278. hReceiveEvent = CreateEvent(&sa,FALSE,FALSE,FAXSIREN);
  279. if (!hReceiveEvent) {
  280. if (GetLastError() != ERROR_ALREADY_EXISTS) {
  281. MYDEBUG (( L"CreateEvent failed, ec = %d\n", GetLastError() ));
  282. return FALSE;
  283. }
  284. }
  285. //
  286. // get path to files for logging, etc.
  287. //
  288. dwNeeded = ExpandEnvironmentStrings(ININAME,IniFile,0);
  289. IniFile = (LPWSTR) HeapAlloc(hHeap,HEAP_ZERO_MEMORY,(dwNeeded)*sizeof(WCHAR));
  290. if (!IniFile) {
  291. MYDEBUG((L"HeapAlloc failed, ec = %d\n", GetLastError() ));
  292. return FALSE;
  293. }
  294. DWORD dwSuccess = ExpandEnvironmentStrings(ININAME,IniFile,dwNeeded);
  295. if (dwSuccess == 0) {
  296. return FALSE;
  297. }
  298. dwNeeded = ExpandEnvironmentStrings(LOGNAME,LogFile,0);
  299. LogFile = (LPWSTR) HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(WCHAR)*(dwNeeded));
  300. if (!LogFile) {
  301. MYDEBUG(( L"HeapAlloc failed, ec = %d\n", GetLastError() ));
  302. return FALSE;
  303. }
  304. dwSuccess = ExpandEnvironmentStrings(LOGNAME,LogFile,dwNeeded);
  305. if (dwSuccess == 0) {
  306. return FALSE;
  307. }
  308. MYDEBUG (( L"Logfile : %s\n", LogFile ));
  309. MYDEBUG (( L"Inifile : %s\n", IniFile ));
  310. return TRUE;
  311. }
  312. BOOL WINAPI
  313. FaxRouteGetRoutingInfo(
  314. IN LPWSTR RoutingGuid,
  315. IN DWORD DeviceId,
  316. IN LPBYTE RoutingInfo,
  317. OUT LPDWORD RoutingInfoSize
  318. )
  319. /*++
  320. Routine Description:
  321. This functions is called by the fax service to
  322. get routing configuration data.
  323. Arguments:
  324. RoutingGuid - Unique identifier for the requested routing method
  325. DeviceId - Device that is being configured
  326. RoutingInfo - Routing info buffer
  327. RoutingInfoSize - Size of the buffer (in bytes)
  328. Return Value:
  329. TRUE for success, otherwise FALSE.
  330. --*/
  331. {
  332. //
  333. // the sample doesn't have any per device routing data, so this function is
  334. // just stubbed out -- if you have per device routing data, it would be
  335. // retrieved here.
  336. //
  337. if (RoutingInfoSize) {
  338. *RoutingInfoSize = 0;
  339. }
  340. return TRUE;
  341. }
  342. BOOL WINAPI
  343. FaxRouteSetRoutingInfo(
  344. IN LPWSTR RoutingGuid,
  345. IN DWORD DeviceId,
  346. IN LPBYTE RoutingInfo,
  347. IN DWORD RoutingInfoSize
  348. )
  349. /*++
  350. Routine Description:
  351. This functions is called by the fax service to
  352. set routing configuration data.
  353. Arguments:
  354. RoutingGuid - Unique identifier for the requested routing method
  355. DeviceId - Device that is being configured
  356. RoutingInfo - Routing info buffer
  357. RoutingInfoSize - Size of the buffer (in bytes)
  358. Return Value:
  359. TRUE for success, otherwise FALSE.
  360. --*/
  361. {
  362. //
  363. // the sample doesn't have any per device routing data, so this function is
  364. // just stubbed out -- if you have per device routing data, it would be
  365. // commited to storage here.
  366. //
  367. return TRUE;
  368. }
  369. BOOL WINAPI
  370. FaxRouteDeviceEnable(
  371. IN LPWSTR RoutingGuid,
  372. IN DWORD DeviceId,
  373. IN LONG Enabled
  374. )
  375. /*++
  376. Routine Description:
  377. This functions is called by the fax service to determine if a routing extension is enabled or
  378. to enable a routing extension
  379. Arguments:
  380. RoutingGuid - Unique identifier for the requested routing method
  381. DeviceId - Device that is being configured
  382. Enabled - meaning differs based on context (see FAXROUTE_ENABLE enumerated type)
  383. Return Value:
  384. depends on context.
  385. --*/
  386. {
  387. //
  388. // -note that we make the assumption that there are never more than 4 devices in this sample
  389. // -also note that this isn't thread safe
  390. // -a real routing extension wouldn't make these assumptions, and would probably have some
  391. // persistent store which kept track of the enabled state of an extension per-routing method
  392. //
  393. static long MyEnabled[4] = {STATUS_ENABLE,STATUS_ENABLE,STATUS_ENABLE,STATUS_ENABLE};
  394. static DWORD DeviceIdIndex[4] = {0,0,0,0};
  395. DWORD count;
  396. //
  397. // make sure that we're dealing with our routing method
  398. //
  399. if (wcscmp(RoutingGuid,ROUTEITGUID) != 0) {
  400. MYDEBUG (( L"Passed a GUID (%s) for a method not in this extension!\n", RoutingGuid ));
  401. return FALSE;
  402. }
  403. for (count = 0 ; count <4; count ++) {
  404. if (DeviceIdIndex[count] == DeviceId) {
  405. break;
  406. } else if (DeviceIdIndex[count] == 0) {
  407. DeviceIdIndex[count] = DeviceId;
  408. }
  409. }
  410. if (Enabled == QUERY_STATUS) {
  411. return MyEnabled[count];
  412. }
  413. MYDEBUG (( L"Setting enabled state to %s\n",
  414. (Enabled == STATUS_DISABLE) ? L"STATUS_DISABLE" : L"STATUS_ENABLE"
  415. ));
  416. MyEnabled[count] = Enabled;
  417. return TRUE;
  418. }
  419. BOOL WINAPI
  420. FaxRouteDeviceChangeNotification(
  421. IN DWORD DeviceId,
  422. IN BOOL NewDevice
  423. )
  424. /*++
  425. Routine Description:
  426. This functions is called by the fax service to alert the routing extension that a device
  427. has changed
  428. Arguments:
  429. DeviceId - Device that has changed
  430. NewDevice - TRUE means device was added, FALSE means a device was removed
  431. Return Value:
  432. TRUE for success
  433. --*/
  434. {
  435. //
  436. // We don't have any per device routing data, so this is just stubbed out
  437. //
  438. return TRUE;
  439. }
  440. //
  441. // routing method(s)
  442. //
  443. BOOL WINAPI
  444. RouteIt(
  445. PFAX_ROUTE FaxRoute,
  446. PVOID *FailureData,
  447. LPDWORD FailureDataSize
  448. )
  449. /*++
  450. Routine Description:
  451. This functions is called by the fax service to
  452. route a received fax.
  453. Arguments:
  454. FaxRoute - Routing information
  455. FailureData - Failure data buffer
  456. FailureDataSize - Size of failure data buffer
  457. Return Value:
  458. TRUE for success, otherwise FALSE.
  459. --*/
  460. {
  461. WCHAR TiffFileName[MAX_PATH];
  462. WCHAR Dir[MAX_PATH],Drive[10],File[MAX_PATH],Ext[10];
  463. WCHAR CopyOfTiff[MAX_PATH];
  464. DWORD Size = sizeof(TiffFileName);
  465. //
  466. // serialize access to this function so that data is written into the logfile accurately
  467. //
  468. EnterCriticalSection( &csRoute );
  469. if (!FaxRouteGetFile(
  470. FaxRoute->JobId,
  471. 0,
  472. TiffFileName,
  473. &Size))
  474. {
  475. MYDEBUG(( L"Couldn't FaxRouteGetFile, ec = %d", GetLastError() ));
  476. LeaveCriticalSection( &csRoute );
  477. return FALSE;
  478. }
  479. MYDEBUG ((L"Received fax %s\n\tCSID :%s\n\t Name : %s\n\t #: %s\n\tDevice: %s\n",
  480. TiffFileName,
  481. ValidString ( FaxRoute->Csid ),
  482. ValidString ( FaxRoute->ReceiverName),
  483. ValidString ( FaxRoute->ReceiverNumber),
  484. ValidString ( FaxRoute->DeviceName )
  485. ));
  486. _wsplitpath(TiffFileName, Drive, Dir, File, Ext );
  487. wsprintf(CopyOfTiff,L"%s\\%s\\%s%s",Drive,SIRENDIR,File,Ext);
  488. //
  489. // copy the tiff so it persists after this routine exits
  490. //
  491. CopyFile(TiffFileName,CopyOfTiff,FALSE);
  492. //
  493. // write some logging data
  494. //
  495. WriteRoutingInfoIntoIniFile(CopyOfTiff,FaxRoute);
  496. AppendFileNametoLogFile(TiffFileName, FaxRoute);
  497. //
  498. // signal event -- another application could use this named event to do something
  499. // with the file that was just copied into this directory
  500. // (note that the INI file isn't thread-safe accross applications, we could have the routing data overwritten by
  501. // another fax being received)
  502. //
  503. SetEvent(hReceiveEvent);
  504. //
  505. // service needs to be able to interact with the current desktop for this to work
  506. //
  507. MessageBeep(MB_ICONEXCLAMATION);
  508. LeaveCriticalSection( &csRoute );
  509. return TRUE;
  510. }
  511. //
  512. // utility fcn's
  513. //
  514. BOOL WriteRoutingInfoIntoIniFile(LPWSTR TiffFileName,PFAX_ROUTE FaxRoute)
  515. {
  516. WCHAR Buffer[MAX_PATH*2];
  517. //
  518. // write each routing info member into ini file
  519. //
  520. //filename
  521. ZeroMemory(Buffer,MAX_PATH*2);
  522. wsprintf(Buffer, L"%s",ValidString (TiffFileName) );
  523. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  524. L"FileName",// pointer to key name
  525. Buffer, // pointer to string to add
  526. IniFile // pointer to initialization filename
  527. );
  528. //jobid
  529. ZeroMemory(Buffer,MAX_PATH*2);
  530. wsprintf(Buffer, L"%u",FaxRoute->JobId);
  531. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  532. L"JobId",// pointer to key name
  533. Buffer, // pointer to string to add
  534. IniFile // pointer to initialization filename
  535. );
  536. //elapsedtime
  537. ZeroMemory(Buffer,MAX_PATH*2);
  538. wsprintf(Buffer, L"%u",FaxRoute->ElapsedTime);
  539. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  540. L"ElapsedTime",// pointer to key name
  541. Buffer, // pointer to string to add
  542. IniFile // pointer to initialization filename
  543. );
  544. //receivetime
  545. ZeroMemory(Buffer,MAX_PATH*2);
  546. wsprintf(Buffer, L"%u",FaxRoute->ReceiveTime);
  547. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  548. L"ReceiveTime",// pointer to key name
  549. Buffer, // pointer to string to add
  550. IniFile // pointer to initialization filename
  551. );
  552. //pagecount
  553. ZeroMemory(Buffer,MAX_PATH*2);
  554. wsprintf(Buffer, L"%u",FaxRoute->PageCount);
  555. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  556. L"PageCount",// pointer to key name
  557. Buffer, // pointer to string to add
  558. IniFile // pointer to initialization filename
  559. );
  560. //Csid
  561. ZeroMemory(Buffer,MAX_PATH*2);
  562. wsprintf(Buffer, L"%s",ValidString (FaxRoute->Csid ));
  563. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  564. L"Csid",// pointer to key name
  565. Buffer, // pointer to string to add
  566. IniFile // pointer to initialization filename
  567. );
  568. //CallerId
  569. ZeroMemory(Buffer,MAX_PATH*2);
  570. wsprintf(Buffer, L"%s",ValidString (FaxRoute->CallerId ));
  571. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  572. L"CallerId",// pointer to key name
  573. Buffer, // pointer to string to add
  574. IniFile // pointer to initialization filename
  575. );
  576. //RoutingInfo
  577. ZeroMemory(Buffer,MAX_PATH*2);
  578. wsprintf(Buffer, L"%s",ValidString (FaxRoute->RoutingInfo ));
  579. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  580. L"RoutingInfo",// pointer to key name
  581. Buffer, // pointer to string to add
  582. IniFile // pointer to initialization filename
  583. );
  584. //ReceiverName
  585. ZeroMemory(Buffer,MAX_PATH*2);
  586. wsprintf(Buffer, L"%s",ValidString (FaxRoute->ReceiverName ));
  587. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  588. L"ReceiverName",// pointer to key name
  589. Buffer, // pointer to string to add
  590. IniFile // pointer to initialization filename
  591. );
  592. //ReceiverNumber
  593. ZeroMemory(Buffer,MAX_PATH*2);
  594. wsprintf(Buffer, L"%s",ValidString (FaxRoute->ReceiverNumber ));
  595. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  596. L"ReceiverNumber",// pointer to key name
  597. Buffer, // pointer to string to add
  598. IniFile // pointer to initialization filename
  599. );
  600. //DeviceName
  601. ZeroMemory(Buffer,MAX_PATH*2);
  602. wsprintf(Buffer, L"%s",ValidString (FaxRoute->DeviceName ));
  603. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  604. L"DeviceName",// pointer to key name
  605. Buffer, // pointer to string to add
  606. IniFile // pointer to initialization filename
  607. );
  608. //DeviceId
  609. ZeroMemory(Buffer,MAX_PATH*2);
  610. wsprintf(Buffer, L"%u",FaxRoute->DeviceId );
  611. WritePrivateProfileString( L"RoutingInfo",// pointer to section name
  612. L"DeviceId",// pointer to key name
  613. Buffer, // pointer to string to add
  614. IniFile // pointer to initialization filename
  615. );
  616. return TRUE;
  617. }
  618. BOOL AppendFileNametoLogFile (LPWSTR TiffFileName,PFAX_ROUTE FaxRoute)
  619. {
  620. HANDLE hFile = INVALID_HANDLE_VALUE;
  621. WCHAR Buffer[MAX_PATH];
  622. WCHAR szDateTime[104];
  623. WCHAR lpDate[50];
  624. WCHAR lpTime[50];
  625. DWORD dwWrote = 0;
  626. hFile = CreateFile(LogFile,
  627. GENERIC_WRITE,
  628. FILE_SHARE_WRITE,
  629. NULL,
  630. OPEN_ALWAYS,
  631. FILE_ATTRIBUTE_NORMAL,
  632. NULL);
  633. if (hFile == INVALID_HANDLE_VALUE) {
  634. MYDEBUG (( L"CreateFile failed, ec = %d\n", GetLastError() ));
  635. return FALSE;
  636. }
  637. if ( !GetDateFormat( LOCALE_SYSTEM_DEFAULT,
  638. DATE_SHORTDATE,
  639. NULL, // use system date
  640. NULL, // use locale format
  641. lpDate,
  642. sizeof(lpDate) ) ) {
  643. MYDEBUG(( L"GetDateFormat failed, ec = %d\n", GetLastError() ));
  644. return FALSE;
  645. }
  646. if ( !GetTimeFormat( LOCALE_SYSTEM_DEFAULT,
  647. TIME_NOSECONDS,
  648. NULL, // use system time
  649. NULL, // use locale format
  650. lpTime,
  651. sizeof(lpTime) ) ) {
  652. MYDEBUG(( L"GetTimeFormat failed, ec = %d\n", GetLastError() ));
  653. return FALSE;
  654. }
  655. wsprintf( szDateTime, TEXT("%-8s %-8s"), lpDate, lpTime);
  656. wsprintf(Buffer, L"%s :Received %s\r\n",ValidString(szDateTime),ValidString(TiffFileName));
  657. SetFilePointer(hFile,0,0,FILE_END);
  658. if (!WriteFile(hFile,Buffer,lstrlen(Buffer)*sizeof(WCHAR),&dwWrote,NULL)) {
  659. MYDEBUG (( L"WriteFile() failed, ec = %d\n", GetLastError() ));
  660. CloseHandle(hFile);
  661. return FALSE;
  662. }
  663. CloseHandle(hFile);
  664. return TRUE;
  665. }
  666. void
  667. DebugPrint(
  668. LPTSTR Format,
  669. ...
  670. )
  671. /*++
  672. Routine Description:
  673. Prints a debug string
  674. Arguments:
  675. format - wsprintf() format string
  676. ... - Variable data
  677. Return Value:
  678. None.
  679. --*/
  680. {
  681. TCHAR Buffer[1024];
  682. TCHAR AppName[MAX_PATH];
  683. TCHAR ShortName[MAX_PATH];
  684. SYSTEMTIME CurrentTime;
  685. int len=0;
  686. va_list marker;
  687. ZeroMemory(AppName,MAX_PATH);
  688. ZeroMemory(ShortName,MAX_PATH);
  689. if ( GetModuleFileName(NULL, // handle to module to find filename for
  690. AppName,
  691. MAX_PATH) ) {
  692. _tsplitpath(AppName,NULL,NULL,ShortName,NULL);
  693. }
  694. ZeroMemory(&CurrentTime,sizeof(SYSTEMTIME));
  695. GetLocalTime(&CurrentTime);
  696. wsprintf(Buffer, TEXT ("%02d.%02d.%02d.%03d %s: "),CurrentTime.wHour,
  697. CurrentTime.wMinute,
  698. CurrentTime.wSecond,
  699. CurrentTime.wMilliseconds,
  700. ShortName );
  701. // init arg list
  702. va_start(marker,Format);
  703. // point to rest of blank buffer
  704. len = lstrlen(Buffer);
  705. _vsntprintf(&Buffer[len], // don't want to overwrite the start of the string!
  706. sizeof(Buffer)-len, //size of the rest of the buffer
  707. Format,
  708. marker);
  709. len = lstrlen(Buffer);
  710. if (Buffer[len-1] == L'\n' ) {
  711. Buffer[len-1] = L'\r';
  712. Buffer[len] = L'\n';
  713. Buffer[len+1] = 0;
  714. }
  715. else {
  716. Buffer[len] = L'\r';
  717. Buffer[len+1] = L'\n';
  718. Buffer[len+2] = 0;
  719. }
  720. OutputDebugString(Buffer);
  721. va_end(marker);
  722. }