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.
 
 
 
 
 
 

1060 lines
29 KiB

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1998
*
* TITLE: IPropItm.Cpp
*
* VERSION: 2.0
*
* AUTHOR: ReedB
*
* DATE: 19 Feb, 1998
*
* DESCRIPTION:
* Implementation of WIA item class server properties.
*
*******************************************************************************/
#include "precomp.h"
#include "stiexe.h"
#include <regstr.h>
#include <wiamindr.h>
// #include <wiadbg.h>
#include "wiapsc.h"
#include "helpers.h"
//
// Strings used to access the registry. REGSTR_* string constants can be
// found in sdk\inc\regstr.h
//
TCHAR g_szREGSTR_PATH_WIA[] = REGSTR_PATH_SETUP TEXT("\\WIA");
/*******************************************************************************
*
* ReadMultiple
* WriteMultiple
* ReadPropertyNames
* Enum
* GetPropertyAttributes
* GetCount
*
* DESCRIPTION:
* IWiaPropertyStorage methods.
*
* PARAMETERS:
*
*******************************************************************************/
/**************************************************************************\
* CWiaItem::ReadMultiple
*
* This method reads the specified number of properties from the item's
* current value property storage. This method conforms to that standard
* OLE IPropertyStorage::ReadMultiple method.
*
* Arguments:
*
* cpspec - Number of properties to read.
* rgpspec - Array of PropSpec's specifying which properties
* are to be read.
* rgpropvar - Array where the property values will be copied
* to.
*
* Arguments:
*
* cpspec
* rgpspec
* rgpropvar
*
* Return Value:
*
* status
*
* History:
*
* 9/3/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::ReadMultiple(
ULONG cpspec,
const PROPSPEC __RPC_FAR rgpspec[],
PROPVARIANT __RPC_FAR rgpropvar[])
{
DBG_FN(CWiaItem::ReadMultiple);
HRESULT hr;
LONG lFlags = 0;
//
// Corresponding driver item must be valid to talk with hardware.
//
hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem);
if (FAILED(hr)) {
return hr;
}
//
// rgpropvar must be valid
//
if (IsBadWritePtr(rgpropvar, sizeof(PROPVARIANT) * cpspec)) {
DBG_ERR(("CWiaItem::ReadMultiple, last parameter (rgpropvar) is invalid"));
return E_INVALIDARG;
}
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
//
// Check whether the properties being read are the WIA Managed properties.
// If they are, there is still no need to initialize the item.
//
if (AreWiaInitializedProps(cpspec, (PROPSPEC*) rgpspec)) {
return (m_pPropStg->CurStg())->ReadMultiple(cpspec, rgpspec, rgpropvar);
}
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::ReadMultiple, InitLazyProps failed"));
return hr;
}
}
//
// Check whether the properties requested are all cacheable
//
hr = (m_pPropStg->AccessStg())->ReadMultiple(cpspec, rgpspec, rgpropvar);
if (FAILED(hr)) {
ReportReadWriteMultipleError(hr, "CWiaItem::ReadMultiple", NULL, TRUE, cpspec, rgpspec);
//
// Property attributes are not required absolutely, continue without it.
//
} else {
for (ULONG i = 0; i < cpspec; i++) {
//
// The client requests a property not read yet or non-cacheable
//
if ((rgpropvar[i].vt == VT_UI4) &&
(! (rgpropvar[i].lVal & WIA_PROP_CACHEABLE))) {
break;
}
}
//
// Clear the access flags from the rgpropvar
//
FreePropVariantArray(cpspec, rgpropvar);
//
// If all the properties are cacheable, then take the quick path
//
if (i == cpspec) {
hr = (m_pPropStg->CurStg())->ReadMultiple(cpspec, rgpspec, rgpropvar);
if (hr == S_OK) {
//
// Check whether all the properties are retrieved correctly
// some properties might not have been read from the storage
//
for (ULONG i = 0; i < cpspec; i++) {
if (rgpropvar[i].vt == VT_EMPTY) {
break;
}
}
if (i == cpspec) {
//
// All the properties requested are found in cache
//
return (hr);
} else {
FreePropVariantArray(cpspec, rgpropvar);
}
}
}
}
if (SUCCEEDED(hr)) {
//
// Make sure all PropSpecs are using PropID's. This is so that
// drivers only have to deal with PropID's. If some of the
// PropSpecs are using string names, then convert them.
//
PROPSPEC *pPropSpec = NULL;
hr = m_pPropStg->NamesToPropIDs(cpspec, (PROPSPEC*) rgpspec, &pPropSpec);
if (SUCCEEDED(hr)) {
//
// Give device mini driver a chance to update the device properties.
//
{
LOCK_WIA_DEVICE _LWD(this, &hr);
if(SUCCEEDED(hr)) {
hr = m_pActiveDevice->m_DrvWrapper.WIA_drvReadItemProperties((BYTE*)this,
lFlags,
cpspec,
(pPropSpec ? pPropSpec : rgpspec),
&m_lLastDevErrVal);
}
}
if (pPropSpec) {
LocalFree(pPropSpec);
pPropSpec = NULL;
}
}
if (SUCCEEDED(hr)) {
hr = (m_pPropStg->CurStg())->ReadMultiple(cpspec, rgpspec, rgpropvar);
if (FAILED(hr)) {
ReportReadWriteMultipleError(hr,
"CWiaItem::ReadMultiple",
NULL,
TRUE,
cpspec,
rgpspec);
}
}
}
return hr;
}
/**************************************************************************\
* CWiaItem::ReadPropertyNames
*
* Returns the string name of the specified properties if they exist.
* This conforms to the standard OLE IPropertyStorage::ReadPropertyNames
* method.
*
* Arguments:
*
* pstmProp - Pointer to property stream.
*
* Return Value:
*
* Status
*
* History:
*
* 9/3/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::ReadPropertyNames(
ULONG cpropid,
const PROPID __RPC_FAR rgpropid[],
LPOLESTR __RPC_FAR rglpwstrName[])
{
DBG_FN(CWiaItem::ReadPropertyNames);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::ReadPropertyNames, InitLazyProps failed"));
return hr;
}
}
return (m_pPropStg->CurStg())->ReadPropertyNames(cpropid,rgpropid,rglpwstrName);
}
/**************************************************************************\
* CWiaItem::WritePropertyNames
*
* Returns the string name of the specified properties if they exist.
* This conforms to the standard OLE IPropertyStorage::ReadPropertyNames
* method.
*
* Arguments:
*
* pstmProp - Pointer to property stream.
*
* Return Value:
*
* Status
*
* History:
*
* 9/3/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::WritePropertyNames(
ULONG cpropid,
const PROPID rgpropid[],
const LPOLESTR rglpwstrName[])
{
DBG_FN(CWiaItem::WritePropertyNames);
PROPVARIANT *pv;
PROPSPEC *pspec;
ULONG index;
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::WritePropertyNames, InitLazyProps failed"));
return hr;
}
}
pv = (PROPVARIANT*) LocalAlloc(LPTR, sizeof(PROPVARIANT) * cpropid);
if (!pv) {
DBG_ERR(("CWiaItem::WritePropertyNames, Out of memory"));
return E_OUTOFMEMORY;
}
pspec = (PROPSPEC*) LocalAlloc(LPTR, sizeof(PROPSPEC) * cpropid);
if (!pspec) {
DBG_ERR(("CWiaItem::WritePropertyNames, Out of memory"));
LocalFree(pv);
return E_OUTOFMEMORY;
}
//
// Put PROPIDs into the PROPSPEC array.
//
for (index = 0; index < cpropid; index++) {
pspec[index].ulKind = PRSPEC_PROPID;
pspec[index].propid = rgpropid[index];
}
hr = (m_pPropStg->AccessStg())->ReadMultiple(cpropid,
pspec,
pv);
if (SUCCEEDED(hr)) {
//
// Make sure the properties are App. written properties. If a valid
// access flag for a property exists, then it was written by the
// driver and not the App, so exit.
//
for (index = 0; index < cpropid; index++) {
if (pv[index].vt != VT_EMPTY) {
DBG_ERR(("CWiaItem::WritePropertyNames, not allowed to write prop: %d.",rgpropid[index]));
hr = E_ACCESSDENIED;
break;
}
}
if (SUCCEEDED(hr)) {
hr = (m_pPropStg->CurStg())->WritePropertyNames(cpropid,
rgpropid,
rglpwstrName);
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::WritePropertyNames, WritePropertyNames failed"));
}
}
} else {
DBG_ERR(("CWiaItem::WritePropertyNames, Reading Access values failed"));
}
LocalFree(pspec);
LocalFree(pv);
return hr;
}
/**************************************************************************\
* CWiaItem::Enum
*
* Returns a IEnumSTATPROPSTG enumerator over the current value property
* storage. Conforms to the standard OLE IPRopertyStorage::Enum method.
*
* Arguments:
*
* pstmProp - Pointer to property stream.
*
* Return Value:
*
* Status
*
* History:
*
* 9/3/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::Enum(
IEnumSTATPROPSTG __RPC_FAR *__RPC_FAR *ppenum)
{
DBG_FN(CWiaItem::Enum);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::Enum, InitLazyProps failed"));
return hr;
}
}
return (m_pPropStg->CurStg())->Enum(ppenum);
}
/**************************************************************************\
* CWiaItem::WriteMultiple
*
* This method writes the specified number of properties into the item's
* property storage. Validation will be performed on those property
* values. The properties will be restored to their old (valid) values
* if validation fails.
*
* Arguments:
*
* cpspec - Number of properties to write.
* rgpspec - Array of PropSpec's specifying which properties
* are to be written.
* rgpropvar - Array containing values that the properties
* will be set to.
* propidNameFirst - Minimum value for property identifiers when
* they don't exist and must be allocated.
*
* Return Value:
*
* Status - S_OK if writes and validation succeeded.
* E_INVALIDARG if validation failed due to an
* incorrect property value.
* Other error returns are from
* ValidateWiaDrvItemAccess, CheckPropertyAccess,
* CreatePropertyStorage and CopyProperties.
*
* History:
*
* 9/3/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::WriteMultiple(
ULONG cpspec,
const PROPSPEC __RPC_FAR rgpspec[],
const PROPVARIANT __RPC_FAR rgpropvar[],
PROPID propidNameFirst)
{
DBG_FN(CWiaItem::WriteMultiple);
HRESULT hr;
//
// Corresponding driver item must be valid.
//
hr = ValidateWiaDrvItemAccess(m_pWiaDrvItem);
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::WriteMultiple, ValidateDrvItemAccess failed"));
return hr;
}
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::WriteMultiple, InitLazyProps failed"));
return hr;
}
}
//
// there is no point in going further if there are no properties to
// write
//
if(cpspec == 0) {
return S_OK;
}
//
// We do not want to fail users who erroneousely attempt to write
// to write to read-only properties IF that the values they
// are trying to write are the same as current values. To achive
// this, we first current values of the properties they want to
// write:
//
PROPVARIANT *curVals = (PROPVARIANT *) LocalAlloc(LPTR, sizeof(PROPVARIANT) * cpspec);
PROPSPEC *newSpecs = (PROPSPEC *) LocalAlloc(LPTR, sizeof(PROPSPEC) * cpspec);
PROPVARIANT *newVals = (PROPVARIANT *) LocalAlloc(LPTR, sizeof(PROPVARIANT) * cpspec);
ULONG newcpspec = cpspec;
if(curVals == NULL || newSpecs == NULL || newVals == NULL) {
DBG_ERR(("CWiaItem::WriteMultiple, failed to allocate memory"));
goto Cleanup;
}
CopyMemory(newSpecs, rgpspec, sizeof(PROPSPEC) * cpspec);
CopyMemory(newVals, rgpropvar, sizeof(PROPVARIANT) * cpspec);
memset(curVals, 0, sizeof(PROPVARIANT) * cpspec);
hr = m_pPropStg->CurStg()->ReadMultiple(cpspec, rgpspec, curVals);
if(SUCCEEDED(hr)) {
//
// Now for every property value they want to write we check if
// it is the same as the current value
//
ULONG ulNewEltIndex = 0;
for(ULONG i = 0; i < cpspec; i++) {
if(curVals[i].vt != rgpropvar[i].vt)
continue;
if(memcmp(curVals + i, rgpropvar + i, sizeof(PROPVARIANT)) == 0 ||
(curVals[i].vt == VT_BSTR && !lstrcmp(curVals[i].bstrVal, rgpropvar[i].bstrVal)) ||
(curVals[i].vt == VT_CLSID && IsEqualGUID(*curVals[i].puuid, *rgpropvar[i].puuid)))
{
// the value "matches", wipe it from both arrays.
if(i != (cpspec - 1)) {
//
// Move a block of values/propspecs.
// The number of elements to move is 1 less than the
// remaining number of elements we still have to check.
// Move these elements up in the new value array - put
// them after the elements we've decided to keep so far
//
MoveMemory(newVals + ulNewEltIndex,
newVals + ulNewEltIndex + 1,
(cpspec - i - 1) * sizeof(PROPVARIANT));
MoveMemory(newSpecs + ulNewEltIndex,
newSpecs + ulNewEltIndex + 1,
(cpspec - i - 1) * sizeof(PROPSPEC));
}
newcpspec--;
} else {
//
// We want to keep this element, so increase the element index.
//
ulNewEltIndex++;
}
}
// It could happen that all values are the same, in which case we
// don't want to write anything at all
if(newcpspec == 0) {
hr = S_OK;
goto Cleanup;
}
}
//
// Verify write access to all requested properties. If any of the
// properties are read ony, the call fails with access denied.
//
hr = m_pPropStg->CheckPropertyAccess(TRUE,
newcpspec,
(PROPSPEC*)newSpecs);
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::WriteMultiple, CheckPropertyAccess failed"));
goto Cleanup;
}
//
// First create the backup.
//
hr = m_pPropStg->Backup();
if (SUCCEEDED(hr)) {
//
// Write property values.
//
hr = (m_pPropStg->CurStg())->WriteMultiple(newcpspec,
newSpecs,
newVals,
propidNameFirst);
if (SUCCEEDED(hr)) {
//
// Write was successful, so do validation
//
LONG lFlags = 0;
//
// Make sure all PropSpecs are using PropID's. If some of the
// PropSpecs are using string names, then convert them.
// This is so that drivers only have to deal with PropID's.
//
PROPSPEC *pPropSpec = NULL;
hr = m_pPropStg->NamesToPropIDs(newcpspec, (PROPSPEC*) newSpecs, &pPropSpec);
if (SUCCEEDED(hr)) {
//
// Let the device mini driver know the properties have changed.
// Device only gets propspec, must read prop values from item's
// property stream.
//
{
LOCK_WIA_DEVICE _LWD(this, &hr);
if(SUCCEEDED(hr)) {
hr = m_pActiveDevice->m_DrvWrapper.WIA_drvValidateItemProperties((BYTE*)this,
lFlags,
newcpspec,
(pPropSpec ? pPropSpec : newSpecs),
&m_lLastDevErrVal);
}
}
if (pPropSpec) {
LocalFree(pPropSpec);
pPropSpec = NULL;
}
} else {
DBG_ERR(("CWiaItem::WriteMultiple, conversion to PropIDs failed"));
}
} else {
DBG_ERR(("CWiaItem::WriteMultiple, test write failed"));
}
HRESULT hresult;
if (SUCCEEDED(hr)) {
//
// Validation passed, so free the backups. Use a new
// HRESULT, since we don't want to overwrite hr returned by
// drvValidateItemProperties.
//
hresult = m_pPropStg->ReleaseBackups();
if (FAILED(hresult)) {
DBG_ERR(("CWiaItem::WriteMultiple, ReleaseBackups failed, continuing anyway..."));
}
} else {
//
// Didn't pass validation failed, so restore old values. Use
// a new HRESULT, since we don't want to overwrite hr returned
// by drvValidateItemProperties.
//
hresult = m_pPropStg->Undo();
if (FAILED(hresult)) {
DBG_ERR(("CWiaItem::WriteMultiple, Undo() failed, could not restore invalid properties to their original values"));
}
}
} else {
DBG_ERR(("CWiaItem::WriteMultiple, couldn't make backup copy of properties"));
}
Cleanup:
if(curVals) {
FreePropVariantArray(cpspec, curVals);
LocalFree(curVals);
}
if(newVals) LocalFree(newVals);
if(newSpecs) LocalFree(newSpecs);
return hr;
}
/**************************************************************************\
* GetPropertyAttributes
*
* Get the access flags and valid values for a property.
*
* Arguments:
*
* pWiasContext - Pointer to WIA item
* cPropSpec - The number of properties
* pPropSpec - array of property specification.
* pulAccessFlags - array of LONGs access flags.
* pPropVar - Pointer to returned valid values.
*
* Return Value:
*
* Status
*
* History:
*
* 1/15/1999 Original Version
* 07/19/1999 Moved from iitem to ipropitm to implement IWiaPropertyStorage
* interface.
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::GetPropertyAttributes(
ULONG cPropSpec,
PROPSPEC pPropSpec[],
ULONG pulAccessFlags[],
PROPVARIANT ppvValidValues[])
{
DBG_FN(CWiaItem::GetPropertyAttributes);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::GetPropertyAttributes, InitLazyProps failed"));
return hr;
}
}
//
// RPC has already done parameter validation for us, so call
// GetPropertyAttributesHelper to do the work.
//
return GetPropertyAttributesHelper(this,
cPropSpec,
pPropSpec,
pulAccessFlags,
ppvValidValues);
}
/**************************************************************************\
* CWiaItem::GetCount
*
* Returns the number of properties stored in an item's current value
* property storage.
*
* Arguments:
*
* pulPropCount - Address to store the property count.
*
* Return Value:
*
* Status
*
* History:
*
* 9/3/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::GetCount(
ULONG* pulPropCount)
{
DBG_FN(CWiaItem::GetCount);
IEnumSTATPROPSTG *pIEnum;
STATPROPSTG stg;
ULONG ulCount;
HRESULT hr = S_OK;
if (pulPropCount == NULL) {
DBG_ERR(("CWiaItem::GetCount, NULL parameter!"));
return E_INVALIDARG;
} else {
*pulPropCount = 0;
}
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::GetCount, InitLazyProps failed"));
return hr;
}
}
hr = (m_pPropStg->CurStg())->Enum(&pIEnum);
if (SUCCEEDED(hr)) {
ulCount = 0;
while (pIEnum->Next(1, &stg, NULL) == S_OK) {
ulCount++;
if(stg.lpwstrName) {
CoTaskMemFree(stg.lpwstrName);
}
}
if (SUCCEEDED(hr)) {
hr = S_OK;
*pulPropCount = ulCount;
} else {
DBG_ERR(("CWiaItem::GetCount, pIEnum->Next failed (0x%X)", hr));
}
pIEnum->Release();
} else {
DBG_ERR(("CWiaItem::GetCount, Enum off CurStg failed (0x%X)", hr));
}
return hr;
}
/**************************************************************************\
* CWiaItem::GetPropertyStream
*
* Get a copy of an items property stream. Caller must free returned
* property stream.
*
* Arguments:
*
* pCompatibilityId - Address of GUID to receive the device's property
* stream CompatibilityId.
* ppstmProp - Pointer to returned property stream.
*
* Return Value:
*
* Status
*
* History:
*
* 09/03/1998 Original Version
* 12/12/1999 Modified to use CompatibilityId
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::GetPropertyStream(
GUID *pCompatibilityId,
LPSTREAM *ppstmProp)
{
DBG_FN(CWiaItem::GetPropertyStream);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::GetPropertyStream, InitLazyProps failed"));
return hr;
}
}
return m_pPropStg->GetPropertyStream(pCompatibilityId, ppstmProp);
}
/**************************************************************************\
* CWiaItem::SetPropertyStream
*
* Set an items property stream.
*
* Arguments:
*
* pCompatibilityId - Pointer to a GUID representing the property
* stream CompatibilityId.
* pstmProp - Pointer to property stream.
*
* Return Value:
*
* Status
*
* History:
*
* 09/03/1998 Original Version
* 12/12/1999 Modified to use CompatibilityId
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::SetPropertyStream(
GUID *pCompatibilityId,
LPSTREAM pstmProp)
{
DBG_FN(CWiaItem::SetPropertyStream);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::SetPropertyStream, InitLazyProps failed"));
return hr;
}
}
return m_pPropStg->SetPropertyStream(pCompatibilityId, this, pstmProp);
}
/**************************************************************************\
*
* Methods of IPropertyStorage not directly off IWiaPropertySTorage
*
* DeleteMultiple
* DeletePropertyNames
* Commit
* Revert
* SetTimes
* SetClass
* Stat
*
* 9/3/1998 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaItem::DeleteMultiple(
ULONG cpspec,
const PROPSPEC __RPC_FAR rgpspec[])
{
DBG_FN(CWiaItem::DeleteMultiple);
return E_ACCESSDENIED;
}
HRESULT _stdcall CWiaItem::DeletePropertyNames(
ULONG cpropid,
const PROPID __RPC_FAR rgpropid[])
{
DBG_FN(CWiaItem::DeletePropertyNames);
return E_ACCESSDENIED;
}
HRESULT _stdcall CWiaItem::Commit(DWORD grfCommitFlags)
{
DBG_FN(CWiaItem::Commit);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::Commit, InitLazyProps failed"));
return hr;
}
}
hr = (m_pPropStg->CurStg())->Commit(grfCommitFlags);
return hr;
}
HRESULT _stdcall CWiaItem::Revert(void)
{
DBG_FN(CWiaItem::Revert);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::Revert, InitLazyProps failed"));
return hr;
}
}
hr = (m_pPropStg->CurStg())->Revert();
return hr;
}
HRESULT _stdcall CWiaItem::SetTimes(
const FILETIME __RPC_FAR *pctime,
const FILETIME __RPC_FAR *patime,
const FILETIME __RPC_FAR *pmtime)
{
DBG_FN(CWiaItem::SetTimes);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::SetTimes, InitLazyProps failed"));
return hr;
}
}
hr = (m_pPropStg->CurStg())->SetTimes(pctime,patime,pmtime);
return hr;
}
HRESULT _stdcall CWiaItem::SetClass(REFCLSID clsid)
{
DBG_FN(CWiaItem::SetClass);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::SetClass, InitLazyProps failed"));
return hr;
}
}
return (m_pPropStg->CurStg())->SetClass(clsid);
}
HRESULT _stdcall CWiaItem::Stat(STATPROPSETSTG *pstatpsstg)
{
DBG_FN(CWiaItem::Stat);
HRESULT hr;
//
// Check whether item properties have been initialized
//
if (!m_bInitialized) {
hr = InitLazyProps();
if (FAILED(hr)) {
DBG_ERR(("CWiaItem::Stat, InitLazyProps failed"));
return hr;
}
}
hr = (m_pPropStg->CurStg())->Stat(pstatpsstg);
return hr;
}