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.

780 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. print.c
  5. Abstract:
  6. This module contains the port
  7. specific WINFAX API functions.
  8. Author:
  9. Wesley Witt (wesw) 29-Nov-1996
  10. Revision History:
  11. --*/
  12. #include "faxapi.h"
  13. #pragma hdrstop
  14. int
  15. __cdecl
  16. PortPriorityCompare(
  17. const void *arg1,
  18. const void *arg2
  19. )
  20. {
  21. if (((PFAX_PORT_INFOW)arg1)->Priority < ((PFAX_PORT_INFOW)arg2)->Priority) {
  22. return -1;
  23. }
  24. if (((PFAX_PORT_INFOW)arg1)->Priority > ((PFAX_PORT_INFOW)arg2)->Priority) {
  25. return 1;
  26. }
  27. return 0;
  28. }
  29. BOOL
  30. WINAPI
  31. FaxEnumPortsW(
  32. IN HANDLE FaxHandle,
  33. OUT PFAX_PORT_INFOW *PortInfoBuffer,
  34. OUT LPDWORD PortsReturned
  35. )
  36. /*++
  37. Routine Description:
  38. Enumerates all of the FAX devices attached to the
  39. FAX server. The port state information is returned
  40. for each device.
  41. Arguments:
  42. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  43. PortInfoBuffer - Buffer to hold the port information
  44. PortInfoBufferSize - Total size of the port info buffer
  45. PortsReturned - The number of ports in the buffer
  46. Return Value:
  47. TRUE - Success
  48. FALSE - Failure, call GetLastError() for more error information.
  49. --*/
  50. {
  51. error_status_t ec;
  52. DWORD i;
  53. PFAX_PORT_INFOW PortInfo;
  54. DWORD PortInfoBufferSize = 0;
  55. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  56. SetLastError(ERROR_INVALID_HANDLE);
  57. return FALSE;
  58. }
  59. if (!PortInfoBuffer || !PortsReturned) {
  60. SetLastError(ERROR_INVALID_PARAMETER);
  61. return FALSE;
  62. }
  63. *PortInfoBuffer = NULL;
  64. ec = FAX_EnumPorts(
  65. FH_FAX_HANDLE(FaxHandle),
  66. (LPBYTE*)PortInfoBuffer,
  67. &PortInfoBufferSize,
  68. PortsReturned
  69. );
  70. if (ec) {
  71. SetLastError( ec );
  72. return FALSE;
  73. }
  74. PortInfo = (PFAX_PORT_INFOW) *PortInfoBuffer;
  75. for (i=0; i<*PortsReturned; i++) {
  76. FixupStringPtr( PortInfoBuffer, PortInfo[i].DeviceName );
  77. FixupStringPtr( PortInfoBuffer, PortInfo[i].Tsid );
  78. FixupStringPtr( PortInfoBuffer, PortInfo[i].Csid );
  79. }
  80. //
  81. // sort the ports by priority
  82. //
  83. qsort(
  84. (PVOID) *PortInfoBuffer,
  85. (int) (*PortsReturned),
  86. sizeof(FAX_PORT_INFOW),
  87. PortPriorityCompare
  88. );
  89. return TRUE;
  90. }
  91. BOOL
  92. WINAPI
  93. FaxEnumPortsA(
  94. IN HANDLE FaxHandle,
  95. OUT PFAX_PORT_INFOA *PortInfoBuffer,
  96. OUT LPDWORD PortsReturned
  97. )
  98. /*++
  99. Routine Description:
  100. Enumerates all of the FAX devices attached to the
  101. FAX server. The port state information is returned
  102. for each device.
  103. Arguments:
  104. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  105. PortInfoBuffer - Buffer to hold the port information
  106. PortInfoBufferSize - Total size of the port info buffer
  107. BytesNeeded - Total bytes needed for buffer
  108. PortsReturned - The number of ports in the buffer
  109. Return Value:
  110. TRUE - Success
  111. FALSE - Failure, call GetLastError() for more error information.
  112. --*/
  113. {
  114. DWORD i;
  115. PFAX_PORT_INFOW PortInfo;
  116. if (!FaxEnumPortsW(
  117. FaxHandle,
  118. (PFAX_PORT_INFOW *)PortInfoBuffer,
  119. PortsReturned
  120. )) {
  121. return FALSE;
  122. }
  123. //
  124. // convert the strings from unicode to ascii
  125. //
  126. PortInfo = (PFAX_PORT_INFOW) *PortInfoBuffer;
  127. for (i=0; i<*PortsReturned; i++) {
  128. ConvertUnicodeStringInPlace( (LPWSTR) PortInfo[i].DeviceName );
  129. ConvertUnicodeStringInPlace( (LPWSTR) PortInfo[i].Tsid );
  130. ConvertUnicodeStringInPlace( (LPWSTR) PortInfo[i].Csid );
  131. }
  132. return TRUE;
  133. }
  134. BOOL
  135. WINAPI
  136. FaxGetPortW(
  137. IN HANDLE FaxPortHandle,
  138. OUT PFAX_PORT_INFOW *PortInfoBuffer
  139. )
  140. /*++
  141. Routine Description:
  142. Returns port status information for a requested port.
  143. The device id passed in should be optained from FAXEnumPorts.
  144. Arguments:
  145. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  146. DeviceId - TAPI device id
  147. PortInfoBuffer - Buffer to hold the port information
  148. PortInfoBufferSize - Total size of the port info buffer
  149. Return Value:
  150. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  151. --*/
  152. {
  153. error_status_t ec;
  154. PFAX_PORT_INFOW PortInfo;
  155. DWORD PortInfoBufferSize = 0;
  156. if (!ValidateFaxHandle(FaxPortHandle, FHT_PORT)) {
  157. SetLastError(ERROR_INVALID_HANDLE);
  158. return FALSE;
  159. }
  160. if (!PortInfoBuffer) {
  161. SetLastError(ERROR_INVALID_PARAMETER);
  162. return FALSE;
  163. }
  164. *PortInfoBuffer = NULL;
  165. ec = FAX_GetPort(
  166. FH_PORT_HANDLE(FaxPortHandle),
  167. (LPBYTE*)PortInfoBuffer,
  168. &PortInfoBufferSize
  169. );
  170. if (ec) {
  171. SetLastError( ec );
  172. return FALSE;
  173. }
  174. PortInfo = (PFAX_PORT_INFOW) *PortInfoBuffer;
  175. FixupStringPtr( PortInfoBuffer, PortInfo->DeviceName );
  176. FixupStringPtr( PortInfoBuffer, PortInfo->Tsid );
  177. FixupStringPtr( PortInfoBuffer, PortInfo->Csid );
  178. return TRUE;
  179. }
  180. BOOL
  181. WINAPI
  182. FaxGetPortA(
  183. IN HANDLE FaxPortHandle,
  184. OUT PFAX_PORT_INFOA *PortInfoBuffer
  185. )
  186. /*++
  187. Routine Description:
  188. Returns port status information for a requested port.
  189. The device id passed in should be optained from FAXEnumPorts.
  190. Arguments:
  191. FaxHandle - FAX handle obtained from FaxConnectFaxServer
  192. DeviceId - TAPI device id
  193. PortInfoBuffer - Buffer to hold the port information
  194. PortInfoBufferSize - Total size of the port info buffer
  195. BytesNeeded - Total bytes needed for buffer
  196. Return Value:
  197. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  198. --*/
  199. {
  200. BOOL Rval = FALSE;
  201. PFAX_PORT_INFOW PortInfo;
  202. if (!FaxGetPortW( FaxPortHandle, (PFAX_PORT_INFOW *)PortInfoBuffer)) {
  203. goto exit;
  204. }
  205. PortInfo = (PFAX_PORT_INFOW) *PortInfoBuffer;
  206. ConvertUnicodeStringInPlace( (LPWSTR)PortInfo->DeviceName );
  207. ConvertUnicodeStringInPlace( (LPWSTR)PortInfo->Tsid );
  208. ConvertUnicodeStringInPlace( (LPWSTR) PortInfo->Csid );
  209. Rval = TRUE;
  210. exit:
  211. return Rval;
  212. }
  213. BOOL
  214. FaxSetPortW(
  215. IN HANDLE FaxPortHandle,
  216. IN const FAX_PORT_INFOW *PortInfoBuffer
  217. )
  218. /*++
  219. Routine Description:
  220. Changes the port capability mask. This allows the caller to
  221. enable or disable sending & receiving on a port basis.
  222. Arguments:
  223. FaxHandle - FAX handle obtained from FaxConnectFaxServer.
  224. PortInfo - PortInfo structure
  225. Return Value:
  226. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  227. --*/
  228. {
  229. error_status_t ec;
  230. PHANDLE_ENTRY HandleEntry = (PHANDLE_ENTRY) FaxPortHandle;
  231. if (!ValidateFaxHandle(FaxPortHandle, FHT_PORT)) {
  232. SetLastError(ERROR_INVALID_HANDLE);
  233. return FALSE;
  234. }
  235. if (!PortInfoBuffer) {
  236. SetLastError(ERROR_INVALID_PARAMETER);
  237. return FALSE;
  238. }
  239. __try {
  240. if (PortInfoBuffer->SizeOfStruct != sizeof(FAX_PORT_INFOW)) {
  241. SetLastError(ERROR_INVALID_PARAMETER);
  242. return FALSE;
  243. }
  244. } __except (EXCEPTION_EXECUTE_HANDLER) {
  245. SetLastError(GetExceptionCode());
  246. return FALSE;
  247. }
  248. if (!(HandleEntry->Flags & PORT_OPEN_MODIFY)) {
  249. SetLastError(ERROR_ACCESS_DENIED);
  250. return FALSE;
  251. }
  252. ec = FAX_SetPort(
  253. FH_PORT_HANDLE(FaxPortHandle),
  254. (PFAX_PORT_INFOW)PortInfoBuffer
  255. );
  256. if (ec) {
  257. SetLastError( ec );
  258. return FALSE;
  259. }
  260. return TRUE;
  261. }
  262. BOOL
  263. FaxSetPortA(
  264. IN HANDLE FaxPortHandle,
  265. IN const FAX_PORT_INFOA *PortInfoBuffer
  266. )
  267. /*++
  268. Routine Description:
  269. Changes the port capability mask. This allows the caller to
  270. enable or disable sending & receiving on a port basis.
  271. Arguments:
  272. FaxHandle - FAX handle obtained from FaxConnectFaxServer.
  273. PortInfo - PortInfo structure
  274. Return Value:
  275. ERROR_SUCCESS for success, otherwise a WIN32 error code.
  276. --*/
  277. {
  278. LPBYTE TempBuf = NULL;
  279. DWORD Size;
  280. DWORD SizeA;
  281. PFAX_PORT_INFOW PortInfo;
  282. if (!PortInfoBuffer || PortInfoBuffer->SizeOfStruct != sizeof(FAX_PORT_INFOA)) {
  283. SetLastError(ERROR_INVALID_PARAMETER);
  284. return FALSE;
  285. }
  286. PortInfo = (PFAX_PORT_INFOW) PortInfoBuffer;
  287. Size = sizeof(FAX_PORT_INFOA) +
  288. ((strlen((LPSTR)PortInfo->DeviceName ) + 1) * sizeof(WCHAR)) +
  289. ((strlen((LPSTR)PortInfo->Csid ) + 1) * sizeof(WCHAR)) +
  290. ((strlen((LPSTR)PortInfo->Tsid ) + 1) * sizeof(WCHAR));
  291. TempBuf = MemAlloc( Size );
  292. if (!TempBuf) {
  293. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  294. return FALSE;
  295. }
  296. SizeA = sizeof(FAX_PORT_INFOA) +
  297. (strlen((LPSTR)PortInfo->DeviceName ) + 1) +
  298. (strlen((LPSTR)PortInfo->Csid ) + 1) +
  299. (strlen((LPSTR)PortInfo->Tsid ) + 1);
  300. CopyMemory( TempBuf, PortInfoBuffer, SizeA );
  301. PortInfo = (PFAX_PORT_INFOW) TempBuf;
  302. PortInfo->SizeOfStruct = sizeof(FAX_PORT_INFOW);
  303. PortInfo->DeviceName = AnsiStringToUnicodeString( (LPSTR) PortInfo->DeviceName );
  304. PortInfo->Csid = AnsiStringToUnicodeString( (LPSTR) PortInfo->Csid );
  305. PortInfo->Tsid = AnsiStringToUnicodeString( (LPSTR) PortInfo->Tsid );
  306. if (!FaxSetPortW( FaxPortHandle, PortInfo )) {
  307. MemFree( TempBuf );
  308. return FALSE;
  309. }
  310. MemFree( (PBYTE) PortInfo->DeviceName );
  311. MemFree( (PBYTE) PortInfo->Csid );
  312. MemFree( (PBYTE) PortInfo->Tsid );
  313. MemFree( TempBuf );
  314. return TRUE;
  315. }
  316. BOOL
  317. WINAPI
  318. FaxOpenPort(
  319. IN HANDLE FaxHandle,
  320. IN DWORD DeviceId,
  321. IN DWORD Flags,
  322. OUT LPHANDLE FaxPortHandle
  323. )
  324. /*++
  325. Routine Description:
  326. Opens a fax port for subsequent use in other fax APIs.
  327. Arguments:
  328. FaxHandle - FAX handle obtained from FaxConnectFaxServer.
  329. DeviceId - Requested device id
  330. FaxPortHandle - The resulting FAX port handle.
  331. Return Value:
  332. TRUE - Success
  333. FALSE - Failure, call GetLastError() for more error information.
  334. --*/
  335. {
  336. error_status_t ec;
  337. PHANDLE_ENTRY HandleEntry;
  338. if (!ValidateFaxHandle(FaxHandle, FHT_SERVICE)) {
  339. SetLastError(ERROR_INVALID_HANDLE);
  340. return FALSE;
  341. }
  342. if ( !FaxPortHandle ||
  343. (!(Flags & (PORT_OPEN_QUERY | PORT_OPEN_MODIFY) ))) {
  344. SetLastError(ERROR_INVALID_PARAMETER);
  345. return FALSE;
  346. }
  347. ec = FAX_OpenPort( FH_FAX_HANDLE(FaxHandle), DeviceId, Flags, FaxPortHandle );
  348. if (ec) {
  349. SetLastError( ec );
  350. return FALSE;
  351. }
  352. HandleEntry = CreateNewPortHandle( FH_DATA(FaxHandle), Flags, *FaxPortHandle );
  353. if (HandleEntry) {
  354. HandleEntry->DeviceId = DeviceId;
  355. }
  356. *FaxPortHandle = HandleEntry;
  357. return *FaxPortHandle != NULL;
  358. }
  359. BOOL
  360. WINAPI
  361. FaxEnumRoutingMethodsW(
  362. IN HANDLE FaxPortHandle,
  363. OUT PFAX_ROUTING_METHODW *RoutingInfoBuffer,
  364. OUT LPDWORD MethodsReturned
  365. )
  366. {
  367. PFAX_ROUTING_METHODW FaxRoutingMethod = NULL;
  368. error_status_t ec;
  369. DWORD i;
  370. DWORD RoutingInfoBufferSize = 0;
  371. if (!ValidateFaxHandle(FaxPortHandle, FHT_PORT)) {
  372. SetLastError(ERROR_INVALID_HANDLE);
  373. return FALSE;
  374. }
  375. if (!RoutingInfoBuffer || !MethodsReturned) {
  376. SetLastError(ERROR_INVALID_PARAMETER);
  377. return FALSE;
  378. }
  379. *RoutingInfoBuffer = NULL;
  380. *MethodsReturned = 0;
  381. ec = FAX_EnumRoutingMethods(
  382. FH_PORT_HANDLE(FaxPortHandle),
  383. (LPBYTE*)RoutingInfoBuffer,
  384. &RoutingInfoBufferSize,
  385. MethodsReturned
  386. );
  387. if (ec) {
  388. SetLastError( ec );
  389. return FALSE;
  390. }
  391. FaxRoutingMethod = (PFAX_ROUTING_METHOD) *RoutingInfoBuffer;
  392. for (i=0; i<*MethodsReturned; i++) {
  393. FixupStringPtr( RoutingInfoBuffer, FaxRoutingMethod[i].DeviceName );
  394. FixupStringPtr( RoutingInfoBuffer, FaxRoutingMethod[i].Guid );
  395. FixupStringPtr( RoutingInfoBuffer, FaxRoutingMethod[i].FunctionName );
  396. FixupStringPtr( RoutingInfoBuffer, FaxRoutingMethod[i].FriendlyName );
  397. FixupStringPtr( RoutingInfoBuffer, FaxRoutingMethod[i].ExtensionImageName );
  398. FixupStringPtr( RoutingInfoBuffer, FaxRoutingMethod[i].ExtensionFriendlyName );
  399. }
  400. return TRUE;
  401. }
  402. BOOL
  403. WINAPI
  404. FaxEnumRoutingMethodsA(
  405. IN HANDLE FaxPortHandle,
  406. OUT PFAX_ROUTING_METHODA *RoutingInfoBuffer,
  407. OUT LPDWORD MethodsReturned
  408. )
  409. {
  410. PFAX_ROUTING_METHODW FaxRoutingMethod = NULL;
  411. DWORD i;
  412. if (!FaxEnumRoutingMethodsW(
  413. FaxPortHandle,
  414. (PFAX_ROUTING_METHODW *)RoutingInfoBuffer,
  415. MethodsReturned
  416. ))
  417. {
  418. return FALSE;
  419. }
  420. FaxRoutingMethod = (PFAX_ROUTING_METHOD) *RoutingInfoBuffer;
  421. for (i=0; i<*MethodsReturned; i++) {
  422. ConvertUnicodeStringInPlace( (LPWSTR)FaxRoutingMethod[i].DeviceName );
  423. ConvertUnicodeStringInPlace( (LPWSTR)FaxRoutingMethod[i].Guid );
  424. ConvertUnicodeStringInPlace( (LPWSTR)FaxRoutingMethod[i].FunctionName );
  425. ConvertUnicodeStringInPlace( (LPWSTR)FaxRoutingMethod[i].FriendlyName );
  426. ConvertUnicodeStringInPlace( (LPWSTR)FaxRoutingMethod[i].ExtensionImageName );
  427. ConvertUnicodeStringInPlace( (LPWSTR)FaxRoutingMethod[i].ExtensionFriendlyName );
  428. }
  429. return TRUE;
  430. }
  431. BOOL
  432. WINAPI
  433. FaxEnableRoutingMethodW(
  434. IN HANDLE FaxPortHandle,
  435. IN LPCWSTR RoutingGuid,
  436. IN BOOL Enabled
  437. )
  438. {
  439. error_status_t ec;
  440. if (!ValidateFaxHandle(FaxPortHandle, FHT_PORT)) {
  441. SetLastError(ERROR_INVALID_HANDLE);
  442. return FALSE;
  443. }
  444. if (!RoutingGuid) {
  445. SetLastError(ERROR_INVALID_PARAMETER);
  446. return FALSE;
  447. }
  448. ec = FAX_EnableRoutingMethod( FH_PORT_HANDLE(FaxPortHandle), (LPWSTR)RoutingGuid, Enabled);
  449. if (ec) {
  450. SetLastError( ec );
  451. return FALSE;
  452. }
  453. return TRUE;
  454. }
  455. BOOL
  456. WINAPI
  457. FaxEnableRoutingMethodA(
  458. IN HANDLE FaxPortHandle,
  459. IN LPCSTR RoutingGuid,
  460. IN BOOL Enabled
  461. )
  462. {
  463. BOOL Rval;
  464. LPWSTR RoutingGuidW = AnsiStringToUnicodeString( RoutingGuid );
  465. if (!RoutingGuidW) {
  466. SetLastError( ERROR_INVALID_PARAMETER );
  467. return FALSE;
  468. }
  469. Rval = FaxEnableRoutingMethodW( FaxPortHandle, RoutingGuidW, Enabled );
  470. MemFree( RoutingGuidW );
  471. return Rval;
  472. }
  473. BOOL
  474. WINAPI
  475. FaxGetRoutingInfoW(
  476. IN const HANDLE FaxPortHandle,
  477. IN LPCWSTR RoutingGuid,
  478. OUT LPBYTE *RoutingInfoBuffer,
  479. OUT LPDWORD RoutingInfoBufferSize
  480. )
  481. {
  482. error_status_t ec;
  483. if (!ValidateFaxHandle(FaxPortHandle, FHT_PORT)) {
  484. SetLastError(ERROR_INVALID_HANDLE);
  485. return FALSE;
  486. }
  487. if (!RoutingGuid || !RoutingInfoBuffer || !RoutingInfoBufferSize) {
  488. SetLastError(ERROR_INVALID_PARAMETER);
  489. return FALSE;
  490. }
  491. *RoutingInfoBuffer = NULL;
  492. *RoutingInfoBufferSize = 0;
  493. ec = FAX_GetRoutingInfo(
  494. FH_PORT_HANDLE(FaxPortHandle),
  495. (LPWSTR)RoutingGuid,
  496. RoutingInfoBuffer,
  497. RoutingInfoBufferSize
  498. );
  499. if (ec) {
  500. SetLastError( ec );
  501. return FALSE;
  502. }
  503. return TRUE;
  504. }
  505. BOOL
  506. WINAPI
  507. FaxGetRoutingInfoA(
  508. IN HANDLE FaxPortHandle,
  509. IN LPCSTR RoutingGuid,
  510. OUT LPBYTE *RoutingInfoBuffer,
  511. OUT LPDWORD RoutingInfoBufferSize
  512. )
  513. {
  514. BOOL Rval;
  515. LPWSTR RoutingGuidW = AnsiStringToUnicodeString( RoutingGuid );
  516. if (!RoutingGuidW) {
  517. SetLastError( ERROR_INVALID_PARAMETER );
  518. return FALSE;
  519. }
  520. Rval = FaxGetRoutingInfoW(
  521. FaxPortHandle,
  522. RoutingGuidW,
  523. RoutingInfoBuffer,
  524. RoutingInfoBufferSize
  525. );
  526. MemFree( RoutingGuidW );
  527. return Rval;
  528. }
  529. BOOL
  530. WINAPI
  531. FaxSetRoutingInfoW(
  532. IN HANDLE FaxPortHandle,
  533. IN LPCWSTR RoutingGuid,
  534. IN const BYTE *RoutingInfoBuffer,
  535. IN DWORD RoutingInfoBufferSize
  536. )
  537. {
  538. error_status_t ec;
  539. if (!ValidateFaxHandle(FaxPortHandle, FHT_PORT)) {
  540. SetLastError(ERROR_INVALID_HANDLE);
  541. return FALSE;
  542. }
  543. if (!RoutingGuid || !RoutingInfoBuffer || !RoutingInfoBufferSize) {
  544. SetLastError(ERROR_INVALID_PARAMETER);
  545. return FALSE;
  546. }
  547. ec = FAX_SetRoutingInfo(
  548. FH_PORT_HANDLE(FaxPortHandle),
  549. (LPWSTR)RoutingGuid,
  550. RoutingInfoBuffer,
  551. RoutingInfoBufferSize
  552. );
  553. if (ec) {
  554. SetLastError( ec );
  555. return FALSE;
  556. }
  557. return TRUE;
  558. }
  559. BOOL
  560. WINAPI
  561. FaxSetRoutingInfoA(
  562. IN HANDLE FaxPortHandle,
  563. IN LPCSTR RoutingGuid,
  564. IN const BYTE *RoutingInfoBuffer,
  565. IN DWORD RoutingInfoBufferSize
  566. )
  567. {
  568. BOOL Rval;
  569. LPWSTR RoutingGuidW = AnsiStringToUnicodeString( RoutingGuid );
  570. if (!RoutingGuidW) {
  571. SetLastError( ERROR_INVALID_PARAMETER );
  572. return FALSE;
  573. }
  574. Rval = FaxSetRoutingInfoW(
  575. FaxPortHandle,
  576. RoutingGuidW,
  577. RoutingInfoBuffer,
  578. RoutingInfoBufferSize
  579. );
  580. MemFree( RoutingGuidW );
  581. return Rval;
  582. }