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.

757 lines
16 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. winfax.cpp
  5. Abstract:
  6. This file implements a pseudo winfax interface.
  7. The COM interfaces call winfax using the regular
  8. winfax.h header file and include the cpp file
  9. as part of the build. This module provides winfax
  10. interfaces that talk to the fax server through
  11. http/ftp via isapi instead of the coventional rpc
  12. methods. This allows the COM interfaces to work
  13. on the internet and across a proxy too.
  14. If you add any winfax interfaces to this file you
  15. must be sure to correctly update the faxisapi.h
  16. header file and add the corresponding function
  17. in the faxisapi dll.
  18. Author:
  19. Wesley Witt (wesw) 1-June-1997
  20. Environment:
  21. User Mode
  22. --*/
  23. #include <windows.h>
  24. #include <wininet.h>
  25. #include <stdio.h>
  26. #include <tchar.h>
  27. #include "faxutil.h"
  28. #include "winfax.h"
  29. #include "faxisapi.h"
  30. #define FixupStringIn(_s,_buf) if ((_s)) { (_s) = (LPWSTR) ((DWORD)(_s) + (DWORD)(_buf)); }
  31. HINTERNET hInternet;
  32. HINTERNET hConnection;
  33. HANDLE hHeap;
  34. VOID
  35. StoreString(
  36. LPWSTR String,
  37. LPDWORD DestString,
  38. LPBYTE Buffer,
  39. LPDWORD Offset
  40. )
  41. {
  42. if (String) {
  43. wcscpy( (LPWSTR) (Buffer+*Offset), String );
  44. *DestString = *Offset;
  45. *Offset += StringSize( String );
  46. } else {
  47. *DestString = 0;
  48. }
  49. }
  50. DWORD
  51. PortInfoSize(
  52. PFAX_PORT_INFOW PortInfo
  53. )
  54. {
  55. DWORD Size = sizeof(FAX_PORT_INFOW);
  56. Size += StringSize( PortInfo->DeviceName );
  57. Size += StringSize( PortInfo->Tsid );
  58. Size += StringSize( PortInfo->Csid );
  59. return Size;
  60. }
  61. VOID
  62. Flush(
  63. HINTERNET hSession
  64. )
  65. {
  66. BOOL Rslt;
  67. DWORD Size;
  68. LPBYTE Buffer[32];
  69. do {
  70. Size = sizeof(Buffer);
  71. Rslt = InternetReadFile( hSession, Buffer, Size, &Size );
  72. } while( Rslt && Size );
  73. }
  74. BOOL
  75. GetResponse(
  76. HINTERNET hSession,
  77. LPBYTE Buffer,
  78. DWORD BufferSize
  79. )
  80. {
  81. BOOL Rslt;
  82. DWORD Size;
  83. IFAX_RESPONSE_HEADER Response;
  84. Rslt = InternetReadFile(
  85. hSession,
  86. (LPVOID) &Response,
  87. sizeof(IFAX_RESPONSE_HEADER),
  88. &Size
  89. );
  90. if (!Rslt) {
  91. return FALSE;
  92. }
  93. if (Response.ErrorCode) {
  94. SetLastError( Response.ErrorCode );
  95. return FALSE;
  96. }
  97. if (Response.Size) {
  98. Rslt = InternetReadFile(
  99. hSession,
  100. Buffer,
  101. min( BufferSize, Response.Size - sizeof(IFAX_RESPONSE_HEADER)),
  102. &Size
  103. );
  104. if (!Rslt) {
  105. return FALSE;
  106. }
  107. }
  108. return TRUE;
  109. }
  110. BOOL
  111. GetResponseAlloc(
  112. HINTERNET hSession,
  113. LPBYTE *Buffer
  114. )
  115. {
  116. BOOL Rslt;
  117. DWORD Size;
  118. IFAX_RESPONSE_HEADER Response;
  119. Rslt = InternetReadFile(
  120. hSession,
  121. (LPVOID) &Response,
  122. sizeof(IFAX_RESPONSE_HEADER),
  123. &Size
  124. );
  125. if (!Rslt) {
  126. return FALSE;
  127. }
  128. if (Response.ErrorCode) {
  129. SetLastError( Response.ErrorCode );
  130. return FALSE;
  131. }
  132. *Buffer = (LPBYTE) MemAlloc( Response.Size );
  133. if (*Buffer == NULL) {
  134. return FALSE;
  135. }
  136. Rslt = InternetReadFile(
  137. hSession,
  138. *Buffer,
  139. Response.Size - sizeof(IFAX_RESPONSE_HEADER),
  140. &Size
  141. );
  142. if (!Rslt) {
  143. MemFree( *Buffer );
  144. return FALSE;
  145. }
  146. return TRUE;
  147. }
  148. HINTERNET
  149. OpenRequest(
  150. VOID
  151. )
  152. {
  153. HINTERNET hSession = HttpOpenRequestA(
  154. hConnection,
  155. "GET",
  156. "/scripts/faxisapi.dll",
  157. "HTTP/1.0",
  158. "",
  159. NULL,
  160. INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
  161. 0
  162. );
  163. if (!hSession) {
  164. return NULL;
  165. }
  166. return hSession;
  167. }
  168. BOOL
  169. SendRequest(
  170. HINTERNET hSession,
  171. LPVOID Buffer,
  172. DWORD BufferSize
  173. )
  174. {
  175. BOOL Rslt = HttpSendRequestA(
  176. hSession,
  177. NULL,
  178. 0,
  179. Buffer,
  180. BufferSize
  181. );
  182. if (!Rslt) {
  183. return FALSE;
  184. }
  185. DWORD Code, Size;
  186. Size = sizeof(DWORD);
  187. if (!HttpQueryInfoA( hSession, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &Code, &Size, NULL )) {
  188. return FALSE;
  189. }
  190. if (Code != HTTP_STATUS_OK) {
  191. return FALSE;
  192. }
  193. return TRUE;
  194. }
  195. extern "C"
  196. VOID
  197. WINAPI
  198. FaxFreeBuffer(
  199. LPVOID Buffer
  200. )
  201. {
  202. MemFree( Buffer );
  203. }
  204. extern "C"
  205. BOOL
  206. WINAPI
  207. FaxClose(
  208. IN HANDLE FaxHandle
  209. )
  210. {
  211. HINTERNET hSession = OpenRequest();
  212. if (!hSession) {
  213. return FALSE;
  214. }
  215. IFAX_GENERAL iFaxGeneral;
  216. iFaxGeneral.Command = ICMD_CLOSE;
  217. iFaxGeneral.FaxHandle = FaxHandle;
  218. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxGeneral, sizeof(IFAX_GENERAL) );
  219. if (!Rslt) {
  220. InternetCloseHandle( hSession );
  221. return FALSE;
  222. }
  223. Rslt = GetResponse( hSession, NULL, 0 );
  224. Flush( hSession );
  225. InternetCloseHandle( hSession );
  226. return Rslt;
  227. }
  228. extern "C"
  229. BOOL
  230. WINAPI
  231. FaxConnectFaxServerW(
  232. IN LPWSTR MachineName OPTIONAL,
  233. OUT LPHANDLE FaxHandle
  234. )
  235. {
  236. CHAR MachineNameA[64];
  237. if (hInternet) {
  238. InternetCloseHandle( hInternet );
  239. }
  240. if (hConnection) {
  241. InternetCloseHandle( hConnection );
  242. }
  243. if (!hHeap) {
  244. hHeap = HeapInitialize( NULL, NULL, NULL, 0 );
  245. }
  246. WideCharToMultiByte(
  247. CP_ACP,
  248. 0,
  249. MachineName,
  250. -1,
  251. MachineNameA,
  252. sizeof(MachineNameA),
  253. NULL,
  254. NULL
  255. );
  256. hInternet = InternetOpenA(
  257. "FaxCom",
  258. INTERNET_OPEN_TYPE_PRECONFIG,
  259. NULL,
  260. NULL,
  261. 0
  262. );
  263. if (!hInternet) {
  264. return FALSE;
  265. }
  266. hConnection = InternetConnectA(
  267. hInternet,
  268. MachineNameA,
  269. INTERNET_DEFAULT_HTTP_PORT,
  270. NULL,
  271. NULL,
  272. INTERNET_SERVICE_HTTP,
  273. 0,
  274. 0
  275. );
  276. if (!hConnection) {
  277. return FALSE;
  278. }
  279. HINTERNET hSession = OpenRequest();
  280. if (!hSession) {
  281. return FALSE;
  282. }
  283. IFAX_CONNECT iFaxConnect;
  284. iFaxConnect.Command = ICMD_CONNECT;
  285. wcscpy( iFaxConnect.ServerName, MachineName );
  286. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxConnect, sizeof(IFAX_CONNECT) );
  287. if (!Rslt) {
  288. InternetCloseHandle( hSession );
  289. return FALSE;
  290. }
  291. DWORD Code, Size;
  292. HttpQueryInfo( hSession, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &Code, &Size, NULL );
  293. Rslt = GetResponse( hSession, (LPBYTE)FaxHandle, sizeof(HANDLE) );
  294. Flush( hSession );
  295. InternetCloseHandle( hSession );
  296. return Rslt;
  297. }
  298. extern "C"
  299. BOOL
  300. WINAPI
  301. FaxEnumPortsW(
  302. IN HANDLE FaxHandle,
  303. OUT LPBYTE *PortInfoBuffer,
  304. OUT LPDWORD PortsReturned
  305. )
  306. {
  307. HINTERNET hSession = OpenRequest();
  308. if (!hSession) {
  309. return FALSE;
  310. }
  311. IFAX_GENERAL iFaxGeneral;
  312. iFaxGeneral.Command = ICMD_ENUM_PORTS;
  313. iFaxGeneral.FaxHandle = FaxHandle;
  314. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxGeneral, sizeof(IFAX_GENERAL) );
  315. if (!Rslt) {
  316. InternetCloseHandle( hSession );
  317. return FALSE;
  318. }
  319. Rslt = GetResponse( hSession, (LPBYTE)PortsReturned, sizeof(DWORD) );
  320. if (Rslt) {
  321. Rslt = GetResponseAlloc( hSession, PortInfoBuffer );
  322. }
  323. if (Rslt) {
  324. PFAX_PORT_INFOW PortInfo = (PFAX_PORT_INFOW) *PortInfoBuffer;
  325. for (DWORD i=0; i<*PortsReturned; i++) {
  326. FixupStringIn( PortInfo[i].DeviceName, PortInfo );
  327. FixupStringIn( PortInfo[i].Tsid, PortInfo );
  328. FixupStringIn( PortInfo[i].Csid, PortInfo );
  329. }
  330. }
  331. Flush( hSession );
  332. InternetCloseHandle( hSession );
  333. return Rslt;
  334. }
  335. extern "C"
  336. BOOL
  337. WINAPI
  338. FaxOpenPort(
  339. IN HANDLE FaxHandle,
  340. IN DWORD DeviceId,
  341. IN DWORD Flags,
  342. OUT LPHANDLE FaxPortHandle
  343. )
  344. {
  345. HINTERNET hSession = OpenRequest();
  346. if (!hSession) {
  347. return FALSE;
  348. }
  349. IFAX_OPEN_PORT iFaxOpenPort;
  350. iFaxOpenPort.Command = ICMD_OPEN_PORT;
  351. iFaxOpenPort.FaxHandle = FaxHandle;
  352. iFaxOpenPort.DeviceId = DeviceId;
  353. iFaxOpenPort.Flags = Flags;
  354. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxOpenPort, sizeof(IFAX_OPEN_PORT) );
  355. if (!Rslt) {
  356. InternetCloseHandle( hSession );
  357. return FALSE;
  358. }
  359. Rslt = GetResponse( hSession, (LPBYTE)FaxPortHandle, sizeof(HANDLE) );
  360. Flush( hSession );
  361. InternetCloseHandle( hSession );
  362. return Rslt;
  363. }
  364. extern "C"
  365. BOOL
  366. WINAPI
  367. FaxGetPortW(
  368. IN HANDLE FaxPortHandle,
  369. OUT LPBYTE *PortInfoBuffer
  370. )
  371. {
  372. HINTERNET hSession = OpenRequest();
  373. if (!hSession) {
  374. return FALSE;
  375. }
  376. IFAX_GENERAL iFaxGeneral;
  377. iFaxGeneral.Command = ICMD_GET_PORT;
  378. iFaxGeneral.FaxHandle = FaxPortHandle;
  379. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxGeneral, sizeof(IFAX_GENERAL) );
  380. if (!Rslt) {
  381. InternetCloseHandle( hSession );
  382. return FALSE;
  383. }
  384. Rslt = GetResponseAlloc( hSession, PortInfoBuffer );
  385. if (Rslt) {
  386. PFAX_PORT_INFOW PortInfo = (PFAX_PORT_INFOW) *PortInfoBuffer;
  387. FixupStringIn( PortInfo->DeviceName, PortInfo );
  388. FixupStringIn( PortInfo->Tsid, PortInfo );
  389. FixupStringIn( PortInfo->Csid, PortInfo );
  390. }
  391. Flush( hSession );
  392. InternetCloseHandle( hSession );
  393. return Rslt;
  394. }
  395. extern "C"
  396. BOOL
  397. WINAPI
  398. FaxSetPortW(
  399. IN HANDLE FaxPortHandle,
  400. IN LPBYTE PortInfoBuffer
  401. )
  402. {
  403. PFAX_PORT_INFOW PortInfo = (PFAX_PORT_INFOW) PortInfoBuffer;
  404. HINTERNET hSession = OpenRequest();
  405. if (!hSession) {
  406. return FALSE;
  407. }
  408. DWORD Size = sizeof(IFAX_SET_PORT) + PortInfoSize( PortInfo );
  409. DWORD Offset = sizeof(IFAX_SET_PORT);
  410. PIFAX_SET_PORT iFaxSetPort = (PIFAX_SET_PORT) MemAlloc( Size );
  411. if (!iFaxSetPort) {
  412. return FALSE;
  413. }
  414. iFaxSetPort->Command = ICMD_SET_PORT;
  415. iFaxSetPort->FaxPortHandle = FaxPortHandle;
  416. iFaxSetPort->PortInfo.SizeOfStruct = PortInfo->SizeOfStruct;
  417. iFaxSetPort->PortInfo.DeviceId = PortInfo->DeviceId;
  418. iFaxSetPort->PortInfo.State = PortInfo->State;
  419. iFaxSetPort->PortInfo.Flags = PortInfo->Flags;
  420. iFaxSetPort->PortInfo.Rings = PortInfo->Rings;
  421. iFaxSetPort->PortInfo.Priority = PortInfo->Priority;
  422. StoreString( PortInfo->DeviceName, (LPDWORD)iFaxSetPort->PortInfo.DeviceName, (LPBYTE)iFaxSetPort, &Offset );
  423. StoreString( PortInfo->Csid, (LPDWORD)iFaxSetPort->PortInfo.Csid, (LPBYTE)iFaxSetPort, &Offset );
  424. StoreString( PortInfo->Tsid, (LPDWORD)iFaxSetPort->PortInfo.Tsid, (LPBYTE)iFaxSetPort, &Offset );
  425. BOOL Rslt = SendRequest( hSession, (LPVOID) iFaxSetPort, Size );
  426. MemFree( iFaxSetPort );
  427. if (!Rslt) {
  428. InternetCloseHandle( hSession );
  429. return FALSE;
  430. }
  431. Rslt = GetResponse( hSession, NULL, 0 );
  432. Flush( hSession );
  433. InternetCloseHandle( hSession );
  434. return Rslt;
  435. }
  436. extern "C"
  437. BOOL
  438. WINAPI
  439. FaxGetRoutingInfoW(
  440. IN HANDLE FaxPortHandle,
  441. IN LPWSTR RoutingGuid,
  442. OUT LPBYTE *RoutingInfoBuffer,
  443. OUT LPDWORD RoutingInfoBufferSize
  444. )
  445. {
  446. HINTERNET hSession = OpenRequest();
  447. if (!hSession) {
  448. return FALSE;
  449. }
  450. IFAX_GET_ROUTINGINFO iFaxGetRoutingInfo;
  451. iFaxGetRoutingInfo.Command = ICMD_GET_ROUTINGINFO;
  452. iFaxGetRoutingInfo.FaxPortHandle = FaxPortHandle;
  453. wcsncpy( iFaxGetRoutingInfo.RoutingGuid, RoutingGuid, MAX_GUID_STRING_LEN );
  454. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxGetRoutingInfo, sizeof(IFAX_GET_ROUTINGINFO) );
  455. if (!Rslt) {
  456. InternetCloseHandle( hSession );
  457. return FALSE;
  458. }
  459. Rslt = GetResponse( hSession, (LPBYTE)RoutingInfoBufferSize, sizeof(DWORD) );
  460. if (Rslt) {
  461. Rslt = GetResponseAlloc( hSession, RoutingInfoBuffer );
  462. }
  463. Flush( hSession );
  464. InternetCloseHandle( hSession );
  465. return Rslt;
  466. return TRUE;
  467. }
  468. extern "C"
  469. BOOL
  470. WINAPI
  471. FaxGetDeviceStatusW(
  472. IN HANDLE FaxPortHandle,
  473. OUT LPBYTE *StatusBuffer
  474. )
  475. {
  476. HINTERNET hSession = OpenRequest();
  477. if (!hSession) {
  478. return FALSE;
  479. }
  480. IFAX_GENERAL iFaxGeneral;
  481. iFaxGeneral.Command = ICMD_GET_DEVICE_STATUS;
  482. iFaxGeneral.FaxHandle = FaxPortHandle;
  483. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxGeneral, sizeof(IFAX_GENERAL) );
  484. if (!Rslt) {
  485. InternetCloseHandle( hSession );
  486. return FALSE;
  487. }
  488. Rslt = GetResponseAlloc( hSession, StatusBuffer );
  489. PFAX_DEVICE_STATUSW DeviceStatus = (PFAX_DEVICE_STATUSW) *StatusBuffer;
  490. FixupStringIn( DeviceStatus->CallerId, DeviceStatus );
  491. FixupStringIn( DeviceStatus->Csid, DeviceStatus );
  492. FixupStringIn( DeviceStatus->DeviceName, DeviceStatus );
  493. FixupStringIn( DeviceStatus->DocumentName, DeviceStatus );
  494. FixupStringIn( DeviceStatus->PhoneNumber, DeviceStatus );
  495. FixupStringIn( DeviceStatus->RoutingString, DeviceStatus );
  496. FixupStringIn( DeviceStatus->SenderName, DeviceStatus );
  497. FixupStringIn( DeviceStatus->RecipientName, DeviceStatus );
  498. FixupStringIn( DeviceStatus->StatusString, DeviceStatus );
  499. FixupStringIn( DeviceStatus->Tsid, DeviceStatus );
  500. Flush( hSession );
  501. InternetCloseHandle( hSession );
  502. return Rslt;
  503. }
  504. extern "C"
  505. BOOL
  506. WINAPI
  507. FaxEnumRoutingMethodsW(
  508. IN HANDLE FaxPortHandle,
  509. OUT LPBYTE *RoutingInfoBuffer,
  510. OUT LPDWORD MethodsReturned
  511. )
  512. {
  513. HINTERNET hSession = OpenRequest();
  514. if (!hSession) {
  515. return FALSE;
  516. }
  517. IFAX_GENERAL iFaxGeneral;
  518. iFaxGeneral.Command = ICMD_ENUM_ROUTING_METHODS;
  519. iFaxGeneral.FaxHandle = FaxPortHandle;
  520. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxGeneral, sizeof(IFAX_GENERAL) );
  521. if (!Rslt) {
  522. InternetCloseHandle( hSession );
  523. return FALSE;
  524. }
  525. Rslt = GetResponse( hSession, (LPBYTE)MethodsReturned, sizeof(DWORD) );
  526. if (Rslt) {
  527. Rslt = GetResponseAlloc( hSession, RoutingInfoBuffer );
  528. }
  529. if (Rslt) {
  530. PFAX_ROUTING_METHODW RoutingMethod = (PFAX_ROUTING_METHODW) *RoutingInfoBuffer;
  531. for (DWORD i=0; i<*MethodsReturned; i++) {
  532. FixupStringIn( RoutingMethod[i].DeviceName, RoutingMethod );
  533. FixupStringIn( RoutingMethod[i].Guid, RoutingMethod );
  534. FixupStringIn( RoutingMethod[i].FriendlyName, RoutingMethod );
  535. FixupStringIn( RoutingMethod[i].FunctionName, RoutingMethod );
  536. FixupStringIn( RoutingMethod[i].ExtensionImageName, RoutingMethod );
  537. FixupStringIn( RoutingMethod[i].ExtensionFriendlyName, RoutingMethod );
  538. }
  539. }
  540. Flush( hSession );
  541. InternetCloseHandle( hSession );
  542. return Rslt;
  543. }
  544. extern "C"
  545. BOOL
  546. WINAPI
  547. FaxEnableRoutingMethodW(
  548. IN HANDLE FaxPortHandle,
  549. IN LPWSTR RoutingGuid,
  550. IN BOOL Enabled
  551. )
  552. {
  553. HINTERNET hSession = OpenRequest();
  554. if (!hSession) {
  555. return FALSE;
  556. }
  557. IFAX_ENABLE_ROUTING_METHOD iFaxEnableRouting;
  558. iFaxEnableRouting.Command = ICMD_ENABLE_ROUTING_METHOD;
  559. iFaxEnableRouting.FaxPortHandle = FaxPortHandle;
  560. iFaxEnableRouting.Enabled = Enabled;
  561. wcsncpy( iFaxEnableRouting.RoutingGuid, RoutingGuid, MAX_GUID_STRING_LEN );
  562. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxEnableRouting, sizeof(IFAX_ENABLE_ROUTING_METHOD) );
  563. if (!Rslt) {
  564. InternetCloseHandle( hSession );
  565. return FALSE;
  566. }
  567. Rslt = GetResponse( hSession, NULL, 0 );
  568. Flush( hSession );
  569. InternetCloseHandle( hSession );
  570. return Rslt;
  571. }
  572. extern "C"
  573. BOOL
  574. WINAPI
  575. FaxGetVersion(
  576. IN HANDLE FaxHandle,
  577. OUT LPDWORD Version
  578. )
  579. {
  580. HINTERNET hSession = OpenRequest();
  581. if (!hSession) {
  582. return FALSE;
  583. }
  584. IFAX_GENERAL iFaxGeneral;
  585. iFaxGeneral.Command = ICMD_GET_VERSION;
  586. iFaxGeneral.FaxHandle = FaxHandle;
  587. BOOL Rslt = SendRequest( hSession, (LPVOID) &iFaxGeneral, sizeof(IFAX_GENERAL) );
  588. if (!Rslt) {
  589. InternetCloseHandle( hSession );
  590. return FALSE;
  591. }
  592. Rslt = GetResponse( hSession, (LPBYTE)Version, sizeof(DWORD) );
  593. Flush( hSession );
  594. InternetCloseHandle( hSession );
  595. return Rslt;
  596. }