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.

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