windows-nt/Source/XPSP1/NT/printscan/fax/activefax/faxtiff.cpp
2020-09-26 16:20:57 +08:00

794 lines
14 KiB
C++

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
faxtiff.cpp
Abstract:
This file implements the FaxTiff object.
Author:
Wesley Witt (wesw) 13-May-1997
Environment:
User Mode
--*/
#include "stdafx.h"
#include "FaxTiff.h"
CFaxTiff::CFaxTiff()
{
hFile = INVALID_HANDLE_VALUE;
hMap = NULL;
fPtr = NULL;
}
CFaxTiff::~CFaxTiff()
{
if (hFile != INVALID_HANDLE_VALUE) {
UnmapViewOfFile( fPtr );
CloseHandle( hMap );
CloseHandle( hFile );
}
}
BSTR CFaxTiff::GetString( DWORD ResId )
{
WCHAR TmpBuf[MAX_PATH];
::LoadString( _Module.GetModuleInstance(), ResId, TmpBuf, sizeof(TmpBuf)/sizeof(WCHAR) );
return SysAllocString( TmpBuf ) ;
}
LPWSTR
CFaxTiff::AnsiStringToUnicodeString(
LPSTR AnsiString
)
{
DWORD Count;
LPWSTR UnicodeString;
//
// first see how big the buffer needs to be
//
Count = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiString,
-1,
NULL,
0
);
//
// i guess the input string is empty
//
if (!Count) {
return NULL;
}
//
// allocate a buffer for the unicode string
//
Count += 1;
UnicodeString = (LPWSTR) LocalAlloc( LPTR, Count * sizeof(UNICODE_NULL) );
if (!UnicodeString) {
return NULL;
}
//
// convert the string
//
Count = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiString,
-1,
UnicodeString,
Count
);
//
// the conversion failed
//
if (!Count) {
LocalFree( UnicodeString );
return NULL;
}
return UnicodeString;
}
LPSTR
CFaxTiff::UnicodeStringToAnsiString(
LPWSTR UnicodeString
)
{
DWORD Count;
LPSTR AnsiString;
//
// first see how big the buffer needs to be
//
Count = WideCharToMultiByte(
CP_ACP,
0,
UnicodeString,
-1,
NULL,
0,
NULL,
NULL
);
//
// i guess the input string is empty
//
if (!Count) {
return NULL;
}
//
// allocate a buffer for the unicode string
//
Count += 1;
AnsiString = (LPSTR) LocalAlloc( LPTR, Count );
if (!AnsiString) {
return NULL;
}
//
// convert the string
//
Count = WideCharToMultiByte(
CP_ACP,
0,
UnicodeString,
-1,
AnsiString,
Count,
NULL,
NULL
);
//
// the conversion failed
//
if (!Count) {
LocalFree( AnsiString );
return NULL;
}
return AnsiString;
}
LPWSTR CFaxTiff::GetStringTag(WORD TagId)
{
for (DWORD i=0; i<NumDirEntries; i++) {
if (TiffTags[i].TagId == TagId) {
if (TiffTags[i].DataType != TIFF_ASCII) {
return NULL;
}
if (TiffTags[i].DataCount > 4) {
return AnsiStringToUnicodeString( (LPSTR) (fPtr + TiffTags[i].DataOffset) );
}
return AnsiStringToUnicodeString( (LPSTR) &TiffTags[i].DataOffset );
}
}
return NULL;
}
DWORD CFaxTiff::GetDWORDTag(WORD TagId)
{
for (DWORD i=0; i<NumDirEntries; i++) {
if (TiffTags[i].TagId == TagId) {
if (TiffTags[i].DataType != TIFF_LONG) {
return 0;
}
return TiffTags[i].DataOffset;
}
}
return 0;
}
DWORDLONG CFaxTiff::GetQWORDTag(WORD TagId)
{
for (DWORD i=0; i<NumDirEntries; i++) {
if (TiffTags[i].TagId == TagId) {
if (TiffTags[i].DataType != TIFF_SRATIONAL) {
return 0;
}
return *(UNALIGNED DWORDLONG*) (fPtr + TiffTags[i].DataOffset);
}
}
return 0;
}
STDMETHODIMP CFaxTiff::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IFaxTiff,
};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
STDMETHODIMP CFaxTiff::get_ReceiveTime(BSTR * pVal)
{
BSTR Copy = NULL;
DWORD StrSize = 0;
WCHAR DateStr[256];
WCHAR TimeStr[128];
FILETIME LocalTime;
SYSTEMTIME SystemTime;
DWORDLONG ReceiveTime;
BOOL bFail = FALSE;
if (!pVal) {
return E_POINTER;
}
ReceiveTime = GetQWORDTag( TIFFTAG_FAX_TIME );
if (ReceiveTime == 0) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
goto copy;
}
FileTimeToLocalFileTime( (FILETIME*) &ReceiveTime, &LocalTime );
FileTimeToSystemTime( &LocalTime, &SystemTime );
StrSize = GetDateFormat(
LOCALE_USER_DEFAULT,
0,
&SystemTime,
NULL,
DateStr,
sizeof(DateStr)
);
if (StrSize == 0) {
Copy = GetString( IDS_UNAVAILABLE );
goto copy;
}
StrSize = GetTimeFormat(
LOCALE_USER_DEFAULT,
0,
&SystemTime,
NULL,
TimeStr,
sizeof(TimeStr)
);
if (StrSize == 0) {
Copy = GetString( IDS_UNAVAILABLE );
goto copy;
}
wcscat( DateStr, L" @ " );
wcscat( DateStr, TimeStr );
Copy = SysAllocString( DateStr );
copy:
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_Image(BSTR *FileName)
{
if (!FileName) {
return E_POINTER;
}
BSTR Copy = SysAllocString( TiffFileName );
if (!Copy && TiffFileName) {
return E_OUTOFMEMORY;
}
__try {
*FileName = Copy;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::put_Image(BSTR FileName)
{
if (!FileName) {
return E_POINTER;
}
HRESULT Rslt = E_FAIL;
//
// if a file was previously open, then close it
//
if (hFile != INVALID_HANDLE_VALUE) {
UnmapViewOfFile( fPtr );
CloseHandle( hMap );
CloseHandle( hFile );
}
//
// open the tiff file
//
hFile = CreateFile(
FileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
goto exit;
}
hMap = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY | SEC_COMMIT,
0,
0,
NULL
);
if (!hMap) {
goto exit;
}
fPtr = (LPBYTE) MapViewOfFile(
hMap,
FILE_MAP_READ,
0,
0,
0
);
if (!fPtr) {
goto exit;
}
TiffHeader = (PTIFF_HEADER) fPtr;
//
// validate that the file is really a tiff file
//
if ((TiffHeader->Identifier != TIFF_LITTLEENDIAN) || (TiffHeader->Version != TIFF_VERSION)) {
goto exit;
}
//
// get the tag count
//
NumDirEntries = *(LPWORD)(fPtr + TiffHeader->IFDOffset);
//
// get a pointer to the tags
//
TiffTags = (UNALIGNED TIFF_TAG*) (fPtr + TiffHeader->IFDOffset + sizeof(WORD));
//
// save the file name
//
wcscpy( TiffFileName, FileName );
//
// set a good return value
//
Rslt = 0;
exit:
if (Rslt) {
if (hFile != INVALID_HANDLE_VALUE) {
if (fPtr) {
UnmapViewOfFile( fPtr );
}
if (hMap) {
CloseHandle( hMap );
}
CloseHandle( hFile );
hFile = INVALID_HANDLE_VALUE;
hMap = NULL;
fPtr = NULL;
}
}
return Rslt;
}
STDMETHODIMP CFaxTiff::get_RecipientName(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR RecipName = GetStringTag( TIFFTAG_RECIP_NAME );
if (!RecipName) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = FALSE;
} else {
Copy = SysAllocString( RecipName );
LocalFree( RecipName );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_RecipientNumber(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR RecipNumber = GetStringTag( TIFFTAG_RECIP_NUMBER );
if (!RecipNumber) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
} else {
Copy = SysAllocString( RecipNumber );
LocalFree( RecipNumber );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_SenderName(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR SenderName = GetStringTag( TIFFTAG_SENDER_NAME );
if (!SenderName) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
} else {
Copy = SysAllocString( SenderName );
LocalFree( SenderName );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_Routing(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR Routing = GetStringTag( TIFFTAG_ROUTING );
if (!Routing) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
} else {
Copy = SysAllocString( Routing );
LocalFree( Routing );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_CallerId(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR CallerId = GetStringTag( TIFFTAG_CALLERID );
if (!CallerId) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
} else {
Copy = SysAllocString( CallerId );
LocalFree( CallerId );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_Csid(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR Csid = GetStringTag( TIFFTAG_CSID );
if (!Csid) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
} else {
Copy = SysAllocString( Csid );
LocalFree( Csid );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_Tsid(BSTR * pVal)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR Tsid = GetStringTag( TIFFTAG_TSID );
if (!Tsid) {
Copy = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
} else {
Copy = SysAllocString( Tsid );
LocalFree( Tsid );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_RawReceiveTime(VARIANT *pVal)
{
if (!pVal) {
return E_POINTER;
}
VARIANT local;
DWORDLONG ReceiveTime = GetQWORDTag( TIFFTAG_FAX_TIME );
ZeroMemory(&local, sizeof(local));
local.vt = VT_CY;
local.cyVal.Lo = (DWORD)(ReceiveTime & 0xFFFFFFFF);
local.cyVal.Hi = (LONG) (ReceiveTime >> 32);
//
// can't use VariantCopy because this is a caller allocated variant
//
__try {
pVal->vt = local.vt;
pVal->cyVal.Lo = local.cyVal.Lo;
pVal->cyVal.Hi = local.cyVal.Hi;
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
return E_UNEXPECTED;
}
STDMETHODIMP CFaxTiff::get_TiffTagString(
WORD tagID,
BSTR* pVal
)
{
if (!pVal) {
return E_POINTER;
}
BSTR Copy;
BOOL bFail = FALSE;
LPWSTR Value = GetStringTag( tagID );
if (!Value) {
Value = GetString( IDS_UNAVAILABLE );
bFail = TRUE;
} else {
Copy = SysAllocString( Value );
LocalFree( Copy );
}
if (!Copy) {
return E_OUTOFMEMORY;
}
__try {
*pVal = Copy;
if (bFail) {
return S_FALSE;
}
return S_OK;
} __except (EXCEPTION_EXECUTE_HANDLER) {
SysFreeString( Copy );
}
return E_UNEXPECTED;
}