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.
 
 
 
 
 
 

1424 lines
33 KiB

/*++
Copyright (C) 2000 Microsoft Corporation
Module Name:
iso15740.cpp
Abstract:
This module implements methods used for manipulating PTP structures
Author:
Dave Parsons
Revision History:
--*/
#include "ptppch.h"
#include <platform.h> // for MAKELONGLONG
//
// This function returns a 2 byte integer from raw data and advances the pointer
//
// Input:
// ppRaw -- pointer to a pointer to the raw data
//
WORD
ParseWord(BYTE **ppRaw)
{
WORD w;
// we know that **ppRaw points to a little-endian word
w = MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
*ppRaw += sizeof(WORD);
return w;
}
//
// This function returns a 4 byte integer from raw data and advances the pointer
//
// Input:
// ppRaw -- pointer to a pointer to the raw data
//
DWORD
ParseDword(BYTE **ppRaw)
{
DWORD dw;
// we know that **ppRaw points to a little-endian dword
dw = MAKELONG(MAKEWORD((*ppRaw)[0],(*ppRaw)[1]),
MAKEWORD((*ppRaw)[2],(*ppRaw)[3]));
*ppRaw += sizeof(DWORD);
return dw;
}
//
// This function returns an 8 byte integer from raw data and advances the pointer
//
// Input:
// ppRaw -- pointer to a pointer to the raw data
//
QWORD
ParseQword(BYTE **ppRaw)
{
QWORD qw;
// we know that **ppRaw points to a little-endian qword
qw = MAKELONGLONG(MAKELONG(MAKEWORD((*ppRaw)[0],(*ppRaw)[1]),
MAKEWORD((*ppRaw)[2],(*ppRaw)[3])),
MAKELONG(MAKEWORD((*ppRaw)[4],(*ppRaw)[5]),
MAKEWORD((*ppRaw)[6],(*ppRaw)[7])));
*ppRaw += sizeof(QWORD);
return qw;
}
//
// This function writes a 2 byte integer to a raw data buffer and advances the pointer
//
// Input:
// ppRaw -- pointer to pointer to the raw data
// value -- value to write
//
VOID
WriteWord(BYTE **ppRaw, WORD value)
{
(*ppRaw)[0] = LOBYTE(LOWORD(value));
(*ppRaw)[1] = HIBYTE(LOWORD(value));
*ppRaw += sizeof(WORD);
return;
}
//
// This function writes a 4 byte integer to a raw data buffer and advances the pointer
//
// Input:
// ppRaw -- pointer to pointer to the raw data
// value -- value to write
//
VOID
WriteDword(BYTE **ppRaw, DWORD value)
{
(*ppRaw)[0] = LOBYTE(LOWORD(value));
(*ppRaw)[1] = HIBYTE(LOWORD(value));
(*ppRaw)[2] = LOBYTE(HIWORD(value));
(*ppRaw)[3] = HIBYTE(HIWORD(value));
*ppRaw += sizeof(DWORD);
return;
}
//
// CBstr constructor
//
CBstr::CBstr() :
m_bstrString(NULL)
{
}
//
// CBstr copy constructor
//
CBstr::CBstr(const CBstr &src)
{
m_bstrString = SysAllocString(src.m_bstrString);
}
//
// CBstr destructor
//
CBstr::~CBstr()
{
if (m_bstrString)
SysFreeString(m_bstrString);
}
//
// Make a copy of a string
//
HRESULT
CBstr::Copy(WCHAR *wcsString)
{
HRESULT hr = S_OK;
if (m_bstrString)
{
if (!SysReAllocString(&m_bstrString, wcsString))
{
wiauDbgError("Copy", "memory allocation failed");
return E_OUTOFMEMORY;
}
}
else
{
m_bstrString = SysAllocString(wcsString);
if (!m_bstrString)
{
wiauDbgError("Copy", "memory allocation failed");
return E_OUTOFMEMORY;
}
}
return hr;
}
//
// This function initializes a BSTR from a raw PTP string, clearing
// the BSTR first, if needed
//
// Input:
// ppRaw -- pointer to pointer to raw data to initialize the string from
// bParse -- indicates whether to advance the raw pointer or not
//
HRESULT
CBstr::Init(
BYTE **ppRaw,
BOOL bParse
)
{
HRESULT hr = S_OK;
//
// Check arguments
//
if (!ppRaw || !*ppRaw)
{
wiauDbgError("Init", "invalid arg");
return E_INVALIDARG;
}
//
// Extract the length from the raw data, and set up a more convenient pointer
// to the string data (skipping over the length byte)
//
int length = (UCHAR) **ppRaw;
OLECHAR *pRaw = (OLECHAR *) (*ppRaw + sizeof(UCHAR));
if (m_bstrString)
{
if (!SysReAllocStringLen(&m_bstrString, pRaw, length))
{
wiauDbgError("Init", "memory allocation failed");
return E_OUTOFMEMORY;
}
}
else
{
m_bstrString = SysAllocStringLen(pRaw, length);
if (!m_bstrString)
{
wiauDbgError("Init", "memory allocation failed");
return E_OUTOFMEMORY;
}
}
//
// If requested, advance the raw pointer past the string. One byte for the length and
// 2 times the number of chars in the wide string.
//
if (bParse)
{
*ppRaw += sizeof(UCHAR) + length * sizeof(USHORT);
}
return hr;
}
//
// This function writes the string to a buffer in PTP format
//
// Input:
// ppRaw -- pointer to pointer to buffer
// Length -- amount of space left in the buffer in bytes
//
VOID
CBstr::WriteToBuffer(
BYTE **ppRaw
)
{
UCHAR NumChars = (UCHAR) Length();
//
// Add one for null terminating char, but only if string is non-empty
//
if (NumChars > 0)
NumChars++;
int NumBytes = NumChars * sizeof(WCHAR);
**ppRaw = NumChars;
(*ppRaw)++;
if (NumChars > 0)
{
memcpy(*ppRaw, String(), NumBytes);
*ppRaw += NumBytes;
}
return;
}
//
// This function dumps a PTP string to the log
//
// Input:
// szDesc -- Description for the string
//
VOID
CBstr::Dump(char *szDesc)
{
if (m_bstrString && SysStringLen(m_bstrString) > 0)
{
wiauDbgDump("", "%s %S", szDesc, m_bstrString);
}
else
{
wiauDbgDump("", "%s <blank>", szDesc);
}
return;
}
//
// Dumps the contents of a CArray8 to the log
//
// Input:
// szDesc -- description for the string
// szFiller -- filler to use for subsequent lines
//
VOID
CArray8::Dump(
char *szDesc,
char *szFiller
)
{
HRESULT hr = S_OK;
char szPart[MAX_PATH] = "\0";
char szMsg[MAX_PATH] = "\0";
//
// Make sure array is not empty
//
if (GetSize() > 0)
{
//
// Prime output string
//
hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szDesc);
if (FAILED(hr))
{
goto Cleanup;
}
//
// Loop through the elements
//
for (int count = 0; count < GetSize(); count++)
{
//
// Start a new line every 8 values
//
if ((count != 0) && (count % 8 == 0))
{
wiauDbgDump("", "%s", szMsg);
hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szFiller);
if (FAILED(hr))
{
goto Cleanup;
}
}
hr = StringCchPrintfA(szPart, ARRAYSIZE(szPart), " 0x%02x", m_aT[count]);
if (FAILED(hr))
{
goto Cleanup;
}
hr = StringCchCatA(szMsg, ARRAYSIZE(szMsg), szPart);
if (FAILED(hr))
{
goto Cleanup;
}
}
wiauDbgDump("", "%s", szMsg);
}
else
{
wiauDbgDump("", "%s <blank>", szDesc);
}
Cleanup:
if (FAILED(hr))
{
wiauDbgErrorHr(hr, "CArray8::Dump", "Failed to dump array");
}
return;
}
//
// Dumps the contents of a CArray16 to the log
//
// Input:
// szDesc -- description for the string
// szFiller -- filler to use for subsequent lines
//
VOID
CArray16::Dump(
char *szDesc,
char *szFiller
)
{
HRESULT hr = S_OK;
char szMsg[MAX_PATH] = "\0";
char szPart[MAX_PATH] = "\0";
//
// Make sure it's not empty
//
if (GetSize() > 0)
{
//
// Prime output string
//
hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szDesc);
if (FAILED(hr))
{
goto Cleanup;
}
//
// Loop through the elements
//
for (int count = 0; count < GetSize(); count++)
{
//
// Start a new line every 4 values
//
if ((count != 0) && (count % 4 == 0))
{
wiauDbgDump("", "%s", szMsg);
hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szFiller);
if (FAILED(hr))
{
goto Cleanup;
}
}
hr = StringCchPrintfA(szPart, ARRAYSIZE(szPart), " 0x%04x", m_aT[count]);
if (FAILED(hr))
{
goto Cleanup;
}
hr = StringCchCatA(szMsg, ARRAYSIZE(szMsg), szPart);
if (FAILED(hr))
{
goto Cleanup;
}
}
wiauDbgDump("", "%s", szMsg);
}
else
{
wiauDbgDump("", "%s <blank>", szDesc);
}
Cleanup:
if (FAILED(hr))
{
wiauDbgErrorHr(hr, "CArray16::Dump", "Failed to dump array");
}
return;
}
//
// This function parses a CArray32 from an array of UCHARs
//
BOOL
CArray32::ParseFrom8(
BYTE **ppRaw,
int NumSize
)
{
if (!ppRaw || !*ppRaw)
return FALSE;
RemoveAll();
// Get the number of elements from the raw data
ULONG NumElems;
switch (NumSize)
{
case 4:
NumElems = MAKELONG(MAKEWORD((*ppRaw)[0], (*ppRaw)[1]), MAKEWORD((*ppRaw)[2], (*ppRaw)[3]));
break;
case 2:
NumElems = MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
break;
case 1:
NumElems = **ppRaw;
break;
default:
return FALSE;
}
*ppRaw += NumSize;
// Allocate space for the array
if (!GrowTo(NumElems))
return FALSE;
// Copy in the elements, one at a time
BYTE *pValues = *ppRaw;
ULONG value = 0;
for (ULONG count = 0; count < NumElems; count++)
{
value = (ULONG) pValues[count];
if (!Add(value))
return FALSE;
}
// Advance the raw pointer past the array and number of elements field
*ppRaw += NumElems * sizeof(BYTE);
return TRUE;
}
//
// This function parses a CArray32 from an array of WORDs
//
BOOL
CArray32::ParseFrom16(
BYTE **ppRaw,
int NumSize
)
{
if (!ppRaw || !*ppRaw)
return FALSE;
RemoveAll();
// Get the number of elements from the raw data
ULONG NumElems;
switch (NumSize)
{
case 4:
NumElems = MAKELONG(MAKEWORD((*ppRaw)[0], (*ppRaw)[1]), MAKEWORD((*ppRaw)[2], (*ppRaw)[3]));
break;
case 2:
NumElems = MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
break;
case 1:
NumElems = **ppRaw;
break;
default:
return FALSE;
}
*ppRaw += NumSize;
// Allocate space for the array
if (!GrowTo(NumElems))
return FALSE;
// Copy in the elements, one at a time
ULONG value = 0;
for (ULONG count = 0; count < NumElems; count++)
{
value = (ULONG) MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
*ppRaw += sizeof(WORD);
if (!Add(value))
return FALSE;
}
return TRUE;
}
//
// Copies values from an array of bytes
//
BOOL
CArray32::Copy(CArray8 values8)
{
RemoveAll();
GrowTo(values8.GetSize());
for (int count = 0; count < values8.GetSize(); count++)
{
ULONG value = values8[count];
if (!Add(value))
return FALSE;
}
return TRUE;
}
//
// Copies values from an array of bytes
//
BOOL
CArray32::Copy(CArray16 values16)
{
RemoveAll();
GrowTo(values16.GetSize());
for (int count = 0; count < values16.GetSize(); count++)
{
ULONG value = values16[count];
if (!Add(value))
return FALSE;
}
return TRUE;
}
//
// Dumps the contents of a CArray32 to the log
//
// Input:
// szDesc -- description for the string
// szFiller -- filler to use for subsequent lines
//
VOID
CArray32::Dump(
char *szDesc,
char *szFiller
)
{
HRESULT hr = S_OK;
char szMsg[MAX_PATH] = "\0";
char szPart[MAX_PATH] = "\0";
//
// Make sure it's not empty
//
if (GetSize() > 0)
{
//
// Prime output string
//
hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szDesc);
if (FAILED(hr))
{
goto Cleanup;
}
//
// Loop through the elements
//
for (int count = 0; count < GetSize(); count++)
{
//
// Start a new line every 4 values
//
if ((count != 0) && (count % 4 == 0))
{
wiauDbgDump("", "%s", szMsg);
hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szFiller);
if (FAILED(hr))
{
goto Cleanup;
}
}
hr = StringCchPrintfA(szPart, ARRAYSIZE(szPart), " 0x%08x", m_aT[count]);
if (FAILED(hr))
{
goto Cleanup;
}
hr = StringCchCatA(szMsg, ARRAYSIZE(szMsg), szPart);
if (FAILED(hr))
{
goto Cleanup;
}
}
wiauDbgDump("", "%s", szMsg);
}
else
{
wiauDbgDump("", "%s <blank>", szDesc);
}
Cleanup:
if (FAILED(hr))
{
wiauDbgErrorHr(hr, "CArray32::Dump", "Failed to dump array");
}
return;
}
//
// This function initializes a string array from raw data, clearing
// the array first, if needed
//
// Input:
// ppRaw -- pointer to pointer to raw data to initialize the string from
// bParse -- indicates whether to advance the raw pointer or not
//
HRESULT
CArrayString::Init(
BYTE **ppRaw,
int NumSize
)
{
HRESULT hr = S_OK;
if (!ppRaw || !*ppRaw)
return E_INVALIDARG;
RemoveAll();
// Get the number of elements from the raw data
int NumElems;
switch (NumSize)
{
case 4:
NumElems = MAKELONG(MAKEWORD((*ppRaw)[0],(*ppRaw)[1]),
MAKEWORD((*ppRaw)[2],(*ppRaw)[3]));
break;
case 2:
NumElems = MAKEWORD((*ppRaw)[0],(*ppRaw)[1]);
break;
case 1:
NumElems = (BYTE) **ppRaw;
break;
default:
return E_FAIL;
}
// Allocate space for the array
if (!GrowTo(NumElems))
return E_OUTOFMEMORY;
// Advance past the number of elements field
*ppRaw += NumSize;
// Read in each string
CBstr tempStr;
for (int count = 0; count < NumElems; count++)
{
tempStr.Init(ppRaw, TRUE);
if (!Add(tempStr))
return E_FAIL;
}
return hr;
}
//
// Dumps the contents of a CArrayString to the log
//
// Input:
// szDesc -- description for the string
// szFiller -- filler to use for subsequent lines
//
VOID
CArrayString::Dump(
char *szDesc,
char *szFiller
)
{
int count;
//
// Make sure it's not empty
//
if (GetSize() > 0)
{
//
// Dump first string with description
//
m_aT[0].Dump(szDesc);
//
// Loop through the elements, dumping with the filler
//
for (count = 1; count < GetSize(); count++)
m_aT[count].Dump(szFiller);
}
else
{
wiauDbgDump("", "%s <blank>", szDesc);
}
return;
}
//
// CPtpDeviceInfo constructor
//
CPtpDeviceInfo::CPtpDeviceInfo() :
m_Version(0),
m_VendorExtId(0),
m_VendorExtVersion(0),
m_FuncMode(0)
{
}
//
// CPtpDeviceInfo copying constructor
//
CPtpDeviceInfo::CPtpDeviceInfo(const CPtpDeviceInfo &src) :
m_Version(src.m_Version),
m_VendorExtId(src.m_VendorExtId),
m_VendorExtVersion(src.m_VendorExtVersion),
m_cbstrVendorExtDesc(src.m_cbstrVendorExtDesc),
m_FuncMode(src.m_FuncMode),
m_cbstrManufacturer(src.m_cbstrManufacturer),
m_cbstrModel(src.m_cbstrModel),
m_cbstrDeviceVersion(src.m_cbstrDeviceVersion),
m_cbstrSerialNumber(src.m_cbstrSerialNumber)
{
for (INT i = 0; i < src.m_SupportedOps.GetSize(); i++)
{
m_SupportedOps.Add(src.m_SupportedOps[i]);
}
for (i = 0; i < src.m_SupportedEvents.GetSize(); i++)
{
m_SupportedEvents.Add(src.m_SupportedEvents[i]);
}
for (i = 0; i < src.m_SupportedProps.GetSize(); i++)
{
m_SupportedProps.Add(src.m_SupportedProps[i]);
}
for (i = 0; i < src.m_SupportedCaptureFmts.GetSize(); i++)
{
m_SupportedCaptureFmts.Add(src.m_SupportedCaptureFmts[i]);
}
for (i = 0; i < src.m_SupportedImageFmts.GetSize(); i++)
{
m_SupportedImageFmts.Add(src.m_SupportedImageFmts[i]);
}
}
//
// CPtpDeviceInfo destructor
//
CPtpDeviceInfo::~CPtpDeviceInfo()
{
}
//
// This function initializes the device info from raw data
//
// Input:
// pRawData -- the raw data
//
HRESULT
CPtpDeviceInfo::Init(BYTE *pRawData)
{
HRESULT hr = S_OK;
BYTE *pCurrent = pRawData;
m_Version = ParseWord(&pCurrent);
m_VendorExtId = ParseDword(&pCurrent);
m_VendorExtVersion = ParseWord(&pCurrent);
hr = m_cbstrVendorExtDesc.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
m_FuncMode = ParseWord(&pCurrent);
if (!m_SupportedOps.Parse(&pCurrent))
return E_FAIL;
if (!m_SupportedEvents.Parse(&pCurrent))
return E_FAIL;
if (!m_SupportedProps.Parse(&pCurrent))
return E_FAIL;
if (!m_SupportedCaptureFmts.Parse(&pCurrent))
return E_FAIL;
if (!m_SupportedImageFmts.Parse(&pCurrent))
return E_FAIL;
hr = m_cbstrManufacturer.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
hr = m_cbstrModel.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
hr = m_cbstrDeviceVersion.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
hr = m_cbstrSerialNumber.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
return hr;
}
//
// This function dumps the device information to the log
//
VOID
CPtpDeviceInfo::Dump()
{
wiauDbgDump("", "DumpDeviceInfo, dumping DeviceInfo:");
wiauDbgDump("", " Standard version = 0x%04x", m_Version);
wiauDbgDump("", " Vendor ext id = 0x%08x", m_VendorExtId);
wiauDbgDump("", " Vendor ext ver = 0x%04x", m_VendorExtVersion);
m_cbstrVendorExtDesc.Dump( " Vendor ext desc =");
m_SupportedOps.Dump( " Ops supported =", " ");
m_SupportedEvents.Dump( " Events supported =", " ");
m_SupportedProps.Dump( " Props supported =", " ");
m_SupportedCaptureFmts.Dump( " Capture fmts supp =", " ");
m_SupportedImageFmts.Dump( " Img formats supp =", " ");
m_cbstrManufacturer.Dump( " Manufacturer =");
m_cbstrModel.Dump( " Model =");
m_cbstrDeviceVersion.Dump( " Device Version =");
m_cbstrSerialNumber.Dump( " Serial Number =");
return;
}
//
// CPtpStorageInfo constructor
//
CPtpStorageInfo::CPtpStorageInfo() :
m_StorageId(0),
m_StorageType(0),
m_FileSystemType(0),
m_AccessCapability(0),
m_MaxCapacity(0),
m_FreeSpaceInBytes(0),
m_FreeSpaceInImages(0)
{
}
//
// CPtpStorageInfo destructor
//
CPtpStorageInfo::~CPtpStorageInfo()
{
}
//
// This function initializes the device info from raw data
//
// Input:
// pRawData -- the raw data
//
HRESULT
CPtpStorageInfo::Init(
BYTE *pRawData,
DWORD StorageId
)
{
HRESULT hr = S_OK;
BYTE *pCurrent = pRawData;
m_StorageId = StorageId;
m_StorageType = ParseWord(&pCurrent);
m_FileSystemType = ParseWord(&pCurrent);
m_AccessCapability = ParseWord(&pCurrent);
m_MaxCapacity = ParseQword(&pCurrent);
m_FreeSpaceInBytes = ParseQword(&pCurrent);
m_FreeSpaceInImages = ParseDword(&pCurrent);
hr = m_cbstrStorageDesc.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
hr = m_cbstrStorageLabel.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
return hr;
}
//
// This function dumps the storage information to the log
//
VOID
CPtpStorageInfo::Dump()
{
wiauDbgDump("", "DumpStorageInfo, dumping StorageInfo for store 0x%08x:", m_StorageId);
wiauDbgDump("", " Storage type = 0x%04x", m_StorageType);
wiauDbgDump("", " File system type = 0x%04x", m_FileSystemType);
wiauDbgDump("", " Access capability = 0x%04x", m_AccessCapability);
wiauDbgDump("", " Max capacity = %I64u", m_MaxCapacity);
wiauDbgDump("", " Free space (byte) = %I64u", m_FreeSpaceInBytes);
wiauDbgDump("", " Free space (imgs) = %u", m_FreeSpaceInImages);
m_cbstrStorageDesc.Dump( " Storage desc =");
m_cbstrStorageLabel.Dump( " Storage label =");
return;
}
//
// CPtpObjectInfo constructor
//
CPtpObjectInfo::CPtpObjectInfo() :
m_ObjectHandle(0),
m_StorageId(0),
m_FormatCode(0),
m_ProtectionStatus(0),
m_CompressedSize(0),
m_ThumbFormat(0),
m_ThumbCompressedSize(0),
m_ThumbPixWidth(0),
m_ThumbPixHeight(0),
m_ImagePixWidth(0),
m_ImagePixHeight(0),
m_ImageBitDepth(0),
m_ParentHandle(0),
m_AssociationType(0),
m_AssociationDesc(0),
m_SequenceNumber(0)
{
}
//
// CPtpObjectInfo destructor
//
CPtpObjectInfo::~CPtpObjectInfo()
{
}
//
// This function initializes the object info from raw data
//
// Input:
// pRawData -- the raw data
// ObjectHandle -- the object's handle
//
HRESULT
CPtpObjectInfo::Init(
BYTE *pRawData,
DWORD ObjectHandle
)
{
HRESULT hr = S_OK;
BYTE *pCurrent = pRawData;
m_ObjectHandle = ObjectHandle;
m_StorageId = ParseDword(&pCurrent);
m_FormatCode = ParseWord(&pCurrent);
m_ProtectionStatus = ParseWord(&pCurrent);
m_CompressedSize = ParseDword(&pCurrent);
m_ThumbFormat = ParseWord(&pCurrent);
m_ThumbCompressedSize = ParseDword(&pCurrent);
m_ThumbPixWidth = ParseDword(&pCurrent);
m_ThumbPixHeight = ParseDword(&pCurrent);
m_ImagePixWidth = ParseDword(&pCurrent);
m_ImagePixHeight = ParseDword(&pCurrent);
m_ImageBitDepth = ParseDword(&pCurrent);
m_ParentHandle = ParseDword(&pCurrent);
m_AssociationType = ParseWord(&pCurrent);
m_AssociationDesc = ParseDword(&pCurrent);
m_SequenceNumber = ParseDword(&pCurrent);
hr = m_cbstrFileName.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
hr = m_cbstrCaptureDate.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
hr = m_cbstrModificationDate.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
hr = m_cbstrKeywords.Init(&pCurrent, TRUE);
if (FAILED(hr))
return hr;
return hr;
}
//
// This function writes the ObjectInfo structure to a buffer in PTP format
//
// Input:
// ppRaw -- pointer to pointer to buffer
// Length -- amount of space left in the buffer in bytes
//
VOID
CPtpObjectInfo::WriteToBuffer(
BYTE **ppRaw
)
{
WriteDword(ppRaw, m_StorageId);
WriteWord(ppRaw, m_FormatCode);
WriteWord(ppRaw, m_ProtectionStatus);
WriteDword(ppRaw, m_CompressedSize);
WriteWord(ppRaw, m_ThumbFormat);
WriteDword(ppRaw, m_ThumbCompressedSize);
WriteDword(ppRaw, m_ThumbPixWidth);
WriteDword(ppRaw, m_ThumbPixHeight);
WriteDword(ppRaw, m_ImagePixWidth);
WriteDword(ppRaw, m_ImagePixHeight);
WriteDword(ppRaw, m_ImageBitDepth);
WriteDword(ppRaw, m_ParentHandle);
WriteWord(ppRaw, m_AssociationType);
WriteDword(ppRaw, m_AssociationDesc);
WriteDword(ppRaw, m_SequenceNumber);
m_cbstrFileName.WriteToBuffer(ppRaw);
m_cbstrCaptureDate.WriteToBuffer(ppRaw);
m_cbstrModificationDate.WriteToBuffer(ppRaw);
m_cbstrKeywords.WriteToBuffer(ppRaw);
return;
}
//
// This function dumps the object information to the log
//
VOID
CPtpObjectInfo::Dump()
{
wiauDbgDump("", "DumpObjectInfo, dumping ObjectInfo for object 0x%08x:", m_ObjectHandle);
wiauDbgDump("", " Storage id = 0x%08x", m_StorageId);
wiauDbgDump("", " Format code = 0x%04x", m_FormatCode);
wiauDbgDump("", " Protection status = 0x%04x", m_ProtectionStatus);
wiauDbgDump("", " Compressed size = %u", m_CompressedSize);
wiauDbgDump("", " Thumbnail format = 0x%04x", m_ThumbFormat);
wiauDbgDump("", " Thumbnail size = %u", m_ThumbCompressedSize);
wiauDbgDump("", " Thumbnail width = %u", m_ThumbPixWidth);
wiauDbgDump("", " Thumbnail height = %u", m_ThumbPixHeight);
wiauDbgDump("", " Image width = %u", m_ImagePixWidth);
wiauDbgDump("", " Image height = %u", m_ImagePixHeight);
wiauDbgDump("", " Image bit depth = %u", m_ImageBitDepth);
wiauDbgDump("", " Parent obj handle = 0x%08x", m_ParentHandle);
wiauDbgDump("", " Association type = 0x%04x", m_AssociationType);
wiauDbgDump("", " Association desc = 0x%08x", m_AssociationDesc);
wiauDbgDump("", " Sequence number = %u", m_SequenceNumber);
m_cbstrFileName.Dump( " File name =");
m_cbstrCaptureDate.Dump( " Capture date =");
m_cbstrModificationDate.Dump( " Modification date =");
m_cbstrKeywords.Dump( " Keywords =");
return;
}
//
// CPtpPropDesc constructor
//
CPtpPropDesc::CPtpPropDesc() :
m_PropCode(0),
m_DataType(0),
m_GetSet(0),
m_FormFlag(0),
m_NumValues(0),
m_lDefault(0),
m_lCurrent(0),
m_lRangeMin(0),
m_lRangeMax(0),
m_lRangeStep(0)
{
}
//
// CPtpPropDesc destructor
//
CPtpPropDesc::~CPtpPropDesc()
{
}
//
// This function initializes a CPtpPropDesc from raw data
//
// Input:
// pRawData -- pointer to the raw data
//
HRESULT
CPtpPropDesc::Init(BYTE *pRawData)
{
HRESULT hr = S_OK;
BYTE *pCurrent = pRawData;
m_PropCode = ParseWord(&pCurrent);
m_DataType = ParseWord(&pCurrent);
m_GetSet = *pCurrent++;
switch (m_DataType)
{
case PTP_DATATYPE_INT8:
case PTP_DATATYPE_UINT8:
m_lDefault = *pCurrent++;
m_lCurrent = *pCurrent++;
break;
case PTP_DATATYPE_INT16:
case PTP_DATATYPE_UINT16:
m_lDefault = ParseWord(&pCurrent);
m_lCurrent = ParseWord(&pCurrent);
break;
case PTP_DATATYPE_INT32:
case PTP_DATATYPE_UINT32:
m_lDefault = ParseDword(&pCurrent);
m_lCurrent = ParseDword(&pCurrent);
break;
case PTP_DATATYPE_STRING:
hr = m_cbstrDefault.Init(&pCurrent, TRUE);
if (FAILED(hr)) return hr;
hr = m_cbstrCurrent.Init(&pCurrent, TRUE);
if (FAILED(hr)) return hr;
break;
default:
return E_FAIL;
}
m_FormFlag = *pCurrent++;
if (m_FormFlag == PTP_FORMFLAGS_RANGE)
{
switch (m_DataType)
{
case PTP_DATATYPE_INT8:
case PTP_DATATYPE_UINT8:
m_lRangeMin = *pCurrent++;
m_lRangeMax = *pCurrent++;
m_lRangeStep = *pCurrent++;
m_lRangeStep = max(1, m_lRangeStep);
break;
case PTP_DATATYPE_INT16:
case PTP_DATATYPE_UINT16:
m_lRangeMin = ParseWord(&pCurrent);
m_lRangeMax = ParseWord(&pCurrent);
m_lRangeStep = ParseWord(&pCurrent);
m_lRangeStep = max(1, m_lRangeStep);
break;
case PTP_DATATYPE_INT32:
case PTP_DATATYPE_UINT32:
m_lRangeMin = ParseDword(&pCurrent);
m_lRangeMax = ParseDword(&pCurrent);
m_lRangeStep = ParseDword(&pCurrent);
m_lRangeStep = max(1, m_lRangeStep);
break;
case PTP_DATATYPE_STRING:
hr = m_cbstrRangeMin.Init(&pCurrent, TRUE);
if (FAILED(hr)) return hr;
hr = m_cbstrRangeMax.Init(&pCurrent, TRUE);
if (FAILED(hr)) return hr;
hr = m_cbstrRangeStep.Init(&pCurrent, TRUE);
if (FAILED(hr)) return hr;
break;
default:
return E_FAIL;
}
}
else if (m_FormFlag == PTP_FORMFLAGS_ENUM)
{
switch (m_DataType)
{
case PTP_DATATYPE_INT8:
case PTP_DATATYPE_UINT8:
if (!m_lValues.ParseFrom8(&pCurrent, 2))
return E_FAIL;
break;
case PTP_DATATYPE_INT16:
case PTP_DATATYPE_UINT16:
if (!m_lValues.ParseFrom16(&pCurrent, 2))
return E_FAIL;
break;
case PTP_DATATYPE_INT32:
case PTP_DATATYPE_UINT32:
if (!m_lValues.Parse(&pCurrent, 2))
return E_FAIL;
break;
case PTP_DATATYPE_STRING:
hr = m_cbstrValues.Init(&pCurrent, 2);
if (FAILED(hr)) return hr;
break;
default:
return E_FAIL;
}
m_NumValues = max(m_lValues.GetSize(), m_cbstrValues.GetSize());
}
return hr;
}
//
// This function sets the current value of a CPtpPropDesc from raw data
//
// Input:
// pRaw -- pointer to the raw data
//
HRESULT
CPtpPropDesc::ParseValue(BYTE *pRaw)
{
HRESULT hr = S_OK;
BYTE *pCurrent = pRaw;
switch (m_DataType)
{
case PTP_DATATYPE_INT8:
case PTP_DATATYPE_UINT8:
m_lCurrent = *pCurrent++;
break;
case PTP_DATATYPE_INT16:
case PTP_DATATYPE_UINT16:
m_lCurrent = ParseWord(&pCurrent);
break;
case PTP_DATATYPE_INT32:
case PTP_DATATYPE_UINT32:
m_lCurrent = ParseDword(&pCurrent);
break;
case PTP_DATATYPE_STRING:
hr = m_cbstrCurrent.Init(&pCurrent, TRUE);
break;
default:
return E_FAIL;
}
return hr;
}
//
// This function writes the current value of a CPtpPropDesc to a raw buffer
//
// Input:
// ppRaw -- pointer to pointer to a raw buffer
//
VOID
CPtpPropDesc::WriteValue(BYTE **ppRaw)
{
switch (m_DataType)
{
case PTP_DATATYPE_INT8:
case PTP_DATATYPE_UINT8:
**ppRaw = (BYTE) m_lCurrent;
(*ppRaw)++;
break;
case PTP_DATATYPE_INT16:
case PTP_DATATYPE_UINT16:
WriteWord(ppRaw, (WORD) m_lCurrent);
break;
case PTP_DATATYPE_INT32:
case PTP_DATATYPE_UINT32:
WriteDword(ppRaw, m_lCurrent);
break;
case PTP_DATATYPE_STRING:
m_cbstrCurrent.WriteToBuffer(ppRaw);
break;
}
return;
}
//
// This function dumps the property description information to the log
//
VOID
CPtpPropDesc::Dump()
{
wiauDbgDump("", "CPtpPropDesc::Dump, dumping PropDesc for property 0x%04x:", m_PropCode);
wiauDbgDump("", " Data type = 0x%04x", m_DataType);
wiauDbgDump("", " GetSet = 0x%02x", m_GetSet);
if (m_DataType == PTP_DATATYPE_STRING)
{
m_cbstrDefault.Dump(" Default =");
m_cbstrCurrent.Dump(" Current =");
wiauDbgDump("", " Form flag = 0x%02x", m_FormFlag);
switch (m_FormFlag)
{
case PTP_FORMFLAGS_RANGE:
m_cbstrRangeMin.Dump(" Range min =");
m_cbstrRangeMax.Dump(" Range max =");
m_cbstrRangeStep.Dump(" Range step =");
break;
case PTP_FORMFLAGS_ENUM:
m_cbstrValues.Dump(" Valid values =", " ");
break;
default:
wiauDbgDump("", " <unknown valid value type>");
}
}
else
{
wiauDbgDump("", " Default = 0x%08x", m_lDefault);
wiauDbgDump("", " Current = 0x%08x", m_lCurrent);
wiauDbgDump("", " Form flag = 0x%02x", m_FormFlag);
switch (m_FormFlag)
{
case PTP_FORMFLAGS_RANGE:
wiauDbgDump("", " Range min = 0x%08x", m_lRangeMin);
wiauDbgDump("", " Range max = 0x%08x", m_lRangeMax);
wiauDbgDump("", " Range step = 0x%08x", m_lRangeStep);
break;
case PTP_FORMFLAGS_ENUM:
m_lValues.Dump(" Valid values =", " ");
break;
default:
wiauDbgDump("", " <unknown valid value type>");
}
}
return;
}
//
// This function dumps the property value to the log
//
VOID
CPtpPropDesc::DumpValue()
{
wiauDbgDump("", "CPtpPropDescDumpValue, current value for property 0x%04x:", m_PropCode);
if (m_DataType == PTP_DATATYPE_STRING)
m_cbstrCurrent.Dump(" Current =");
else
wiauDbgDump("", " Current = 0x%08x", m_lCurrent);
return;
}