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.

793 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. faxtiff.cpp
  5. Abstract:
  6. This file implements the FaxTiff object.
  7. Author:
  8. Wesley Witt (wesw) 13-May-1997
  9. Environment:
  10. User Mode
  11. --*/
  12. #include "stdafx.h"
  13. #include "FaxTiff.h"
  14. CFaxTiff::CFaxTiff()
  15. {
  16. hFile = INVALID_HANDLE_VALUE;
  17. hMap = NULL;
  18. fPtr = NULL;
  19. }
  20. CFaxTiff::~CFaxTiff()
  21. {
  22. if (hFile != INVALID_HANDLE_VALUE) {
  23. UnmapViewOfFile( fPtr );
  24. CloseHandle( hMap );
  25. CloseHandle( hFile );
  26. }
  27. }
  28. BSTR CFaxTiff::GetString( DWORD ResId )
  29. {
  30. WCHAR TmpBuf[MAX_PATH];
  31. ::LoadString( _Module.GetModuleInstance(), ResId, TmpBuf, sizeof(TmpBuf)/sizeof(WCHAR) );
  32. return SysAllocString( TmpBuf ) ;
  33. }
  34. LPWSTR
  35. CFaxTiff::AnsiStringToUnicodeString(
  36. LPSTR AnsiString
  37. )
  38. {
  39. DWORD Count;
  40. LPWSTR UnicodeString;
  41. //
  42. // first see how big the buffer needs to be
  43. //
  44. Count = MultiByteToWideChar(
  45. CP_ACP,
  46. MB_PRECOMPOSED,
  47. AnsiString,
  48. -1,
  49. NULL,
  50. 0
  51. );
  52. //
  53. // i guess the input string is empty
  54. //
  55. if (!Count) {
  56. return NULL;
  57. }
  58. //
  59. // allocate a buffer for the unicode string
  60. //
  61. Count += 1;
  62. UnicodeString = (LPWSTR) LocalAlloc( LPTR, Count * sizeof(UNICODE_NULL) );
  63. if (!UnicodeString) {
  64. return NULL;
  65. }
  66. //
  67. // convert the string
  68. //
  69. Count = MultiByteToWideChar(
  70. CP_ACP,
  71. MB_PRECOMPOSED,
  72. AnsiString,
  73. -1,
  74. UnicodeString,
  75. Count
  76. );
  77. //
  78. // the conversion failed
  79. //
  80. if (!Count) {
  81. LocalFree( UnicodeString );
  82. return NULL;
  83. }
  84. return UnicodeString;
  85. }
  86. LPSTR
  87. CFaxTiff::UnicodeStringToAnsiString(
  88. LPWSTR UnicodeString
  89. )
  90. {
  91. DWORD Count;
  92. LPSTR AnsiString;
  93. //
  94. // first see how big the buffer needs to be
  95. //
  96. Count = WideCharToMultiByte(
  97. CP_ACP,
  98. 0,
  99. UnicodeString,
  100. -1,
  101. NULL,
  102. 0,
  103. NULL,
  104. NULL
  105. );
  106. //
  107. // i guess the input string is empty
  108. //
  109. if (!Count) {
  110. return NULL;
  111. }
  112. //
  113. // allocate a buffer for the unicode string
  114. //
  115. Count += 1;
  116. AnsiString = (LPSTR) LocalAlloc( LPTR, Count );
  117. if (!AnsiString) {
  118. return NULL;
  119. }
  120. //
  121. // convert the string
  122. //
  123. Count = WideCharToMultiByte(
  124. CP_ACP,
  125. 0,
  126. UnicodeString,
  127. -1,
  128. AnsiString,
  129. Count,
  130. NULL,
  131. NULL
  132. );
  133. //
  134. // the conversion failed
  135. //
  136. if (!Count) {
  137. LocalFree( AnsiString );
  138. return NULL;
  139. }
  140. return AnsiString;
  141. }
  142. LPWSTR CFaxTiff::GetStringTag(WORD TagId)
  143. {
  144. for (DWORD i=0; i<NumDirEntries; i++) {
  145. if (TiffTags[i].TagId == TagId) {
  146. if (TiffTags[i].DataType != TIFF_ASCII) {
  147. return NULL;
  148. }
  149. if (TiffTags[i].DataCount > 4) {
  150. return AnsiStringToUnicodeString( (LPSTR) (fPtr + TiffTags[i].DataOffset) );
  151. }
  152. return AnsiStringToUnicodeString( (LPSTR) &TiffTags[i].DataOffset );
  153. }
  154. }
  155. return NULL;
  156. }
  157. DWORD CFaxTiff::GetDWORDTag(WORD TagId)
  158. {
  159. for (DWORD i=0; i<NumDirEntries; i++) {
  160. if (TiffTags[i].TagId == TagId) {
  161. if (TiffTags[i].DataType != TIFF_LONG) {
  162. return 0;
  163. }
  164. return TiffTags[i].DataOffset;
  165. }
  166. }
  167. return 0;
  168. }
  169. DWORDLONG CFaxTiff::GetQWORDTag(WORD TagId)
  170. {
  171. for (DWORD i=0; i<NumDirEntries; i++) {
  172. if (TiffTags[i].TagId == TagId) {
  173. if (TiffTags[i].DataType != TIFF_SRATIONAL) {
  174. return 0;
  175. }
  176. return *(UNALIGNED DWORDLONG*) (fPtr + TiffTags[i].DataOffset);
  177. }
  178. }
  179. return 0;
  180. }
  181. STDMETHODIMP CFaxTiff::InterfaceSupportsErrorInfo(REFIID riid)
  182. {
  183. static const IID* arr[] =
  184. {
  185. &IID_IFaxTiff,
  186. };
  187. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  188. {
  189. if (InlineIsEqualGUID(*arr[i],riid))
  190. return S_OK;
  191. }
  192. return S_FALSE;
  193. }
  194. STDMETHODIMP CFaxTiff::get_ReceiveTime(BSTR * pVal)
  195. {
  196. BSTR Copy = NULL;
  197. DWORD StrSize = 0;
  198. WCHAR DateStr[256];
  199. WCHAR TimeStr[128];
  200. FILETIME LocalTime;
  201. SYSTEMTIME SystemTime;
  202. DWORDLONG ReceiveTime;
  203. BOOL bFail = FALSE;
  204. if (!pVal) {
  205. return E_POINTER;
  206. }
  207. ReceiveTime = GetQWORDTag( TIFFTAG_FAX_TIME );
  208. if (ReceiveTime == 0) {
  209. Copy = GetString( IDS_UNAVAILABLE );
  210. bFail = TRUE;
  211. goto copy;
  212. }
  213. FileTimeToLocalFileTime( (FILETIME*) &ReceiveTime, &LocalTime );
  214. FileTimeToSystemTime( &LocalTime, &SystemTime );
  215. StrSize = GetDateFormat(
  216. LOCALE_USER_DEFAULT,
  217. 0,
  218. &SystemTime,
  219. NULL,
  220. DateStr,
  221. sizeof(DateStr)
  222. );
  223. if (StrSize == 0) {
  224. Copy = GetString( IDS_UNAVAILABLE );
  225. goto copy;
  226. }
  227. StrSize = GetTimeFormat(
  228. LOCALE_USER_DEFAULT,
  229. 0,
  230. &SystemTime,
  231. NULL,
  232. TimeStr,
  233. sizeof(TimeStr)
  234. );
  235. if (StrSize == 0) {
  236. Copy = GetString( IDS_UNAVAILABLE );
  237. goto copy;
  238. }
  239. wcscat( DateStr, L" @ " );
  240. wcscat( DateStr, TimeStr );
  241. Copy = SysAllocString( DateStr );
  242. copy:
  243. if (!Copy) {
  244. return E_OUTOFMEMORY;
  245. }
  246. __try {
  247. *pVal = Copy;
  248. if (bFail) {
  249. return S_FALSE;
  250. }
  251. return S_OK;
  252. } __except (EXCEPTION_EXECUTE_HANDLER) {
  253. SysFreeString( Copy );
  254. }
  255. return E_UNEXPECTED;
  256. }
  257. STDMETHODIMP CFaxTiff::get_Image(BSTR *FileName)
  258. {
  259. if (!FileName) {
  260. return E_POINTER;
  261. }
  262. BSTR Copy = SysAllocString( TiffFileName );
  263. if (!Copy && TiffFileName) {
  264. return E_OUTOFMEMORY;
  265. }
  266. __try {
  267. *FileName = Copy;
  268. return S_OK;
  269. } __except (EXCEPTION_EXECUTE_HANDLER) {
  270. SysFreeString( Copy );
  271. }
  272. return E_UNEXPECTED;
  273. }
  274. STDMETHODIMP CFaxTiff::put_Image(BSTR FileName)
  275. {
  276. if (!FileName) {
  277. return E_POINTER;
  278. }
  279. HRESULT Rslt = E_FAIL;
  280. //
  281. // if a file was previously open, then close it
  282. //
  283. if (hFile != INVALID_HANDLE_VALUE) {
  284. UnmapViewOfFile( fPtr );
  285. CloseHandle( hMap );
  286. CloseHandle( hFile );
  287. }
  288. //
  289. // open the tiff file
  290. //
  291. hFile = CreateFile(
  292. FileName,
  293. GENERIC_READ,
  294. FILE_SHARE_READ,
  295. NULL,
  296. OPEN_EXISTING,
  297. 0,
  298. NULL
  299. );
  300. if (hFile == INVALID_HANDLE_VALUE) {
  301. goto exit;
  302. }
  303. hMap = CreateFileMapping(
  304. hFile,
  305. NULL,
  306. PAGE_READONLY | SEC_COMMIT,
  307. 0,
  308. 0,
  309. NULL
  310. );
  311. if (!hMap) {
  312. goto exit;
  313. }
  314. fPtr = (LPBYTE) MapViewOfFile(
  315. hMap,
  316. FILE_MAP_READ,
  317. 0,
  318. 0,
  319. 0
  320. );
  321. if (!fPtr) {
  322. goto exit;
  323. }
  324. TiffHeader = (PTIFF_HEADER) fPtr;
  325. //
  326. // validate that the file is really a tiff file
  327. //
  328. if ((TiffHeader->Identifier != TIFF_LITTLEENDIAN) || (TiffHeader->Version != TIFF_VERSION)) {
  329. goto exit;
  330. }
  331. //
  332. // get the tag count
  333. //
  334. NumDirEntries = *(LPWORD)(fPtr + TiffHeader->IFDOffset);
  335. //
  336. // get a pointer to the tags
  337. //
  338. TiffTags = (UNALIGNED TIFF_TAG*) (fPtr + TiffHeader->IFDOffset + sizeof(WORD));
  339. //
  340. // save the file name
  341. //
  342. wcscpy( TiffFileName, FileName );
  343. //
  344. // set a good return value
  345. //
  346. Rslt = 0;
  347. exit:
  348. if (Rslt) {
  349. if (hFile != INVALID_HANDLE_VALUE) {
  350. if (fPtr) {
  351. UnmapViewOfFile( fPtr );
  352. }
  353. if (hMap) {
  354. CloseHandle( hMap );
  355. }
  356. CloseHandle( hFile );
  357. hFile = INVALID_HANDLE_VALUE;
  358. hMap = NULL;
  359. fPtr = NULL;
  360. }
  361. }
  362. return Rslt;
  363. }
  364. STDMETHODIMP CFaxTiff::get_RecipientName(BSTR * pVal)
  365. {
  366. if (!pVal) {
  367. return E_POINTER;
  368. }
  369. BSTR Copy;
  370. BOOL bFail = FALSE;
  371. LPWSTR RecipName = GetStringTag( TIFFTAG_RECIP_NAME );
  372. if (!RecipName) {
  373. Copy = GetString( IDS_UNAVAILABLE );
  374. bFail = FALSE;
  375. } else {
  376. Copy = SysAllocString( RecipName );
  377. LocalFree( RecipName );
  378. }
  379. if (!Copy) {
  380. return E_OUTOFMEMORY;
  381. }
  382. __try {
  383. *pVal = Copy;
  384. if (bFail) {
  385. return S_FALSE;
  386. }
  387. return S_OK;
  388. } __except (EXCEPTION_EXECUTE_HANDLER) {
  389. SysFreeString( Copy );
  390. }
  391. return E_UNEXPECTED;
  392. }
  393. STDMETHODIMP CFaxTiff::get_RecipientNumber(BSTR * pVal)
  394. {
  395. if (!pVal) {
  396. return E_POINTER;
  397. }
  398. BSTR Copy;
  399. BOOL bFail = FALSE;
  400. LPWSTR RecipNumber = GetStringTag( TIFFTAG_RECIP_NUMBER );
  401. if (!RecipNumber) {
  402. Copy = GetString( IDS_UNAVAILABLE );
  403. bFail = TRUE;
  404. } else {
  405. Copy = SysAllocString( RecipNumber );
  406. LocalFree( RecipNumber );
  407. }
  408. if (!Copy) {
  409. return E_OUTOFMEMORY;
  410. }
  411. __try {
  412. *pVal = Copy;
  413. if (bFail) {
  414. return S_FALSE;
  415. }
  416. return S_OK;
  417. } __except (EXCEPTION_EXECUTE_HANDLER) {
  418. SysFreeString( Copy );
  419. }
  420. return E_UNEXPECTED;
  421. }
  422. STDMETHODIMP CFaxTiff::get_SenderName(BSTR * pVal)
  423. {
  424. if (!pVal) {
  425. return E_POINTER;
  426. }
  427. BSTR Copy;
  428. BOOL bFail = FALSE;
  429. LPWSTR SenderName = GetStringTag( TIFFTAG_SENDER_NAME );
  430. if (!SenderName) {
  431. Copy = GetString( IDS_UNAVAILABLE );
  432. bFail = TRUE;
  433. } else {
  434. Copy = SysAllocString( SenderName );
  435. LocalFree( SenderName );
  436. }
  437. if (!Copy) {
  438. return E_OUTOFMEMORY;
  439. }
  440. __try {
  441. *pVal = Copy;
  442. if (bFail) {
  443. return S_FALSE;
  444. }
  445. return S_OK;
  446. } __except (EXCEPTION_EXECUTE_HANDLER) {
  447. SysFreeString( Copy );
  448. }
  449. return E_UNEXPECTED;
  450. }
  451. STDMETHODIMP CFaxTiff::get_Routing(BSTR * pVal)
  452. {
  453. if (!pVal) {
  454. return E_POINTER;
  455. }
  456. BSTR Copy;
  457. BOOL bFail = FALSE;
  458. LPWSTR Routing = GetStringTag( TIFFTAG_ROUTING );
  459. if (!Routing) {
  460. Copy = GetString( IDS_UNAVAILABLE );
  461. bFail = TRUE;
  462. } else {
  463. Copy = SysAllocString( Routing );
  464. LocalFree( Routing );
  465. }
  466. if (!Copy) {
  467. return E_OUTOFMEMORY;
  468. }
  469. __try {
  470. *pVal = Copy;
  471. if (bFail) {
  472. return S_FALSE;
  473. }
  474. return S_OK;
  475. } __except (EXCEPTION_EXECUTE_HANDLER) {
  476. SysFreeString( Copy );
  477. }
  478. return E_UNEXPECTED;
  479. }
  480. STDMETHODIMP CFaxTiff::get_CallerId(BSTR * pVal)
  481. {
  482. if (!pVal) {
  483. return E_POINTER;
  484. }
  485. BSTR Copy;
  486. BOOL bFail = FALSE;
  487. LPWSTR CallerId = GetStringTag( TIFFTAG_CALLERID );
  488. if (!CallerId) {
  489. Copy = GetString( IDS_UNAVAILABLE );
  490. bFail = TRUE;
  491. } else {
  492. Copy = SysAllocString( CallerId );
  493. LocalFree( CallerId );
  494. }
  495. if (!Copy) {
  496. return E_OUTOFMEMORY;
  497. }
  498. __try {
  499. *pVal = Copy;
  500. if (bFail) {
  501. return S_FALSE;
  502. }
  503. return S_OK;
  504. } __except (EXCEPTION_EXECUTE_HANDLER) {
  505. SysFreeString( Copy );
  506. }
  507. return E_UNEXPECTED;
  508. }
  509. STDMETHODIMP CFaxTiff::get_Csid(BSTR * pVal)
  510. {
  511. if (!pVal) {
  512. return E_POINTER;
  513. }
  514. BSTR Copy;
  515. BOOL bFail = FALSE;
  516. LPWSTR Csid = GetStringTag( TIFFTAG_CSID );
  517. if (!Csid) {
  518. Copy = GetString( IDS_UNAVAILABLE );
  519. bFail = TRUE;
  520. } else {
  521. Copy = SysAllocString( Csid );
  522. LocalFree( Csid );
  523. }
  524. if (!Copy) {
  525. return E_OUTOFMEMORY;
  526. }
  527. __try {
  528. *pVal = Copy;
  529. if (bFail) {
  530. return S_FALSE;
  531. }
  532. return S_OK;
  533. } __except (EXCEPTION_EXECUTE_HANDLER) {
  534. SysFreeString( Copy );
  535. }
  536. return E_UNEXPECTED;
  537. }
  538. STDMETHODIMP CFaxTiff::get_Tsid(BSTR * pVal)
  539. {
  540. if (!pVal) {
  541. return E_POINTER;
  542. }
  543. BSTR Copy;
  544. BOOL bFail = FALSE;
  545. LPWSTR Tsid = GetStringTag( TIFFTAG_TSID );
  546. if (!Tsid) {
  547. Copy = GetString( IDS_UNAVAILABLE );
  548. bFail = TRUE;
  549. } else {
  550. Copy = SysAllocString( Tsid );
  551. LocalFree( Tsid );
  552. }
  553. if (!Copy) {
  554. return E_OUTOFMEMORY;
  555. }
  556. __try {
  557. *pVal = Copy;
  558. if (bFail) {
  559. return S_FALSE;
  560. }
  561. return S_OK;
  562. } __except (EXCEPTION_EXECUTE_HANDLER) {
  563. SysFreeString( Copy );
  564. }
  565. return E_UNEXPECTED;
  566. }
  567. STDMETHODIMP CFaxTiff::get_RawReceiveTime(VARIANT *pVal)
  568. {
  569. if (!pVal) {
  570. return E_POINTER;
  571. }
  572. VARIANT local;
  573. DWORDLONG ReceiveTime = GetQWORDTag( TIFFTAG_FAX_TIME );
  574. ZeroMemory(&local, sizeof(local));
  575. local.vt = VT_CY;
  576. local.cyVal.Lo = (DWORD)(ReceiveTime & 0xFFFFFFFF);
  577. local.cyVal.Hi = (LONG) (ReceiveTime >> 32);
  578. //
  579. // can't use VariantCopy because this is a caller allocated variant
  580. //
  581. __try {
  582. pVal->vt = local.vt;
  583. pVal->cyVal.Lo = local.cyVal.Lo;
  584. pVal->cyVal.Hi = local.cyVal.Hi;
  585. return S_OK;
  586. } __except (EXCEPTION_EXECUTE_HANDLER) {
  587. }
  588. return E_UNEXPECTED;
  589. }
  590. STDMETHODIMP CFaxTiff::get_TiffTagString(
  591. WORD tagID,
  592. BSTR* pVal
  593. )
  594. {
  595. if (!pVal) {
  596. return E_POINTER;
  597. }
  598. BSTR Copy;
  599. BOOL bFail = FALSE;
  600. LPWSTR Value = GetStringTag( tagID );
  601. if (!Value) {
  602. Value = GetString( IDS_UNAVAILABLE );
  603. bFail = TRUE;
  604. } else {
  605. Copy = SysAllocString( Value );
  606. LocalFree( Copy );
  607. }
  608. if (!Copy) {
  609. return E_OUTOFMEMORY;
  610. }
  611. __try {
  612. *pVal = Copy;
  613. if (bFail) {
  614. return S_FALSE;
  615. }
  616. return S_OK;
  617. } __except (EXCEPTION_EXECUTE_HANDLER) {
  618. SysFreeString( Copy );
  619. }
  620. return E_UNEXPECTED;
  621. }