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
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;
|
|
}
|
|
|