⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 propset.cpp

📁 连接oracle
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			case VT_BSTR:           // binary string               
			case VT_STREAM:         // Name of the stream follows  
			case VT_STORAGE:        // Name of the storage follows 
			case VT_STREAMED_OBJECT:// Stream contains an object   
			case VT_STORED_OBJECT:  // Storage contains an object  
			case VT_STREAMED_PROPSET:// Stream contains a propset  
			case VT_STORED_PROPSET: // Storage contains a propset  
			case VT_BLOB:           // Length prefixed bytes       
			case VT_BLOB_OBJECT:    // Blob contains an object     
			case VT_BLOB_PROPSET:   // Blob contains a propset     
			case VT_CF:             // Clipboard format            
				cb = sizeof(DWORD) + *(LPDWORD)pCur;
			break;

			case VT_LPWSTR:         // UNICODE string 
				cb = sizeof(DWORD) + (*(LPDWORD)pCur * sizeof(WCHAR));
			break;

			case VT_CLSID:          // A Class ID                  
				cb = sizeof(CLSID);
			break;

	        case VT_VARIANT:        // VARIANT*                
	        break;

			default:
				return FALSE;
		}

		pCur += cb;
		cbTotal+= cb;
	}

	// Write the type
	pIStream->Write((LPVOID)&m_dwType, sizeof(m_dwType), &cb);
	if (cb != sizeof(m_dwType))
		goto Cleanup;

	// Write the value
	pIStream->Write((LPVOID)pValue, cbTotal, &cb);
	if (cb != cbTotal)
		goto Cleanup;

	// Make sure we are 32 bit aligned
	cbTotal = (((cbTotal + 3) >> 2) << 2) - cbTotal;
	while (cbTotal--)
	{
		pIStream->Write((LPVOID)&b, 1, &cb);
		if (cb != sizeof(BYTE))
			goto Cleanup;
	}

	bSuccess = TRUE;

Cleanup:
	if (pValue != m_pValue)
		free(pValue);

	return bSuccess;
}

BOOL CProperty::ReadFromStream( IStream* pIStream )
{
	ULONG           cb;
	ULONG           cbItem;
	ULONG           cbValue;
	DWORD           dwType;
	ULONG           nReps;
	ULONG           iReps;
	LPSTREAM        pIStrItem;
	LARGE_INTEGER   li;

	// All properties are made up of a type/value pair.
	// The obvious first thing to do is to get the type...
	pIStream->Read( (LPVOID)&m_dwType, sizeof(m_dwType), &cb );
	if (cb != sizeof(m_dwType))
		return FALSE;

	dwType = m_dwType;
	nReps = 1;
	cbValue = 0;
	if (m_dwType & VT_VECTOR)
	{
		// The next DWORD in the stream is a count of the
		// elements
		pIStream->Read( (LPVOID)&nReps, sizeof(nReps), &cb );
		if (cb != sizeof(nReps))
			return FALSE;
		cbValue += cb;
		dwType &= ~VT_VECTOR;
	}

	// Since a value can be made up of a vector (VT_VECTOR) of
	// items, we first seek through the value, picking out
	// each item, getting it's size.  We use a cloned
	// stream for this (pIStrItem).
	// We then use our pIStream to read the entire 'blob' into
	// the allocated buffer.
	//
	cbItem = 0;        // Size of the current item
	pIStream->Clone( &pIStrItem );
	ASSERT(pIStrItem != NULL);
	iReps = nReps;
	while (iReps--)
	{
		switch (dwType)
		{
			case VT_EMPTY:          // nothing                     
				cbItem = 0;
			break;

			case VT_I2:             // 2 byte signed int           
			case VT_BOOL:           // True=-1, False=0            
				cbItem = 2;
			break;

			case VT_I4:             // 4 byte signed int           
			case VT_R4:             // 4 byte real                 
				cbItem = 4;
			break;

			case VT_R8:             // 8 byte real                 
			case VT_CY:             // currency                    
			case VT_DATE:           // date                        
			case VT_I8:             // signed 64-bit int           
			case VT_FILETIME:       // FILETIME                    
				cbItem = 8;
			break;

			case VT_LPSTR:          // null terminated string      
			case VT_BSTR:           // binary string               
			case VT_STREAM:         // Name of the stream follows  
			case VT_STORAGE:        // Name of the storage follows 
			case VT_STREAMED_OBJECT:// Stream contains an object   
			case VT_STORED_OBJECT:  // Storage contains an object  
			case VT_STREAMED_PROPSET:// Stream contains a propset  
			case VT_STORED_PROPSET: // Storage contains a propset  
			case VT_BLOB:           // Length prefixed bytes       
			case VT_BLOB_OBJECT:    // Blob contains an object     
			case VT_BLOB_PROPSET:   // Blob contains a propset     
			case VT_CF:             // Clipboard format            
				// Read the DWORD that gives us the size, making
				// sure we increment cbValue.
				pIStream->Read( (LPVOID)&cbItem, sizeof(cbItem), &cb );
				if (cb != sizeof(cbItem))
					return FALSE;
				LISet32( li, -(LONG)cb );
				pIStream->Seek( li, STREAM_SEEK_CUR, NULL );
				cbValue += cb;
			break;

			case VT_LPWSTR:         // UNICODE string 
				pIStream->Read( (LPVOID)&cbItem, sizeof(cbItem), &cb );
				if (cb != sizeof(cbItem))
					return FALSE;
				LISet32( li, -(LONG)cb );
				pIStream->Seek( li, STREAM_SEEK_CUR, NULL );
				cbValue += cb;
				cbItem *= sizeof(WCHAR);
			break;

			case VT_CLSID:          // A Class ID                  
				cbItem = sizeof(CLSID);
			break;

	        case VT_VARIANT:        // VARIANT*                
	        break;

			default:
				pIStrItem->Release();
				return FALSE;
		}

		// Add 'cb' to cbItem before seeking...
		//
		// Seek to the next item
		LISet32( li, cbItem );
		pIStrItem->Seek( li, STREAM_SEEK_CUR, NULL);
		cbValue += cbItem;
	}

	pIStrItem->Release();

#ifdef _UNICODE
	LPBYTE pTmp;

	switch (dwType)
	{
		case VT_BSTR:           // binary string               
		case VT_STREAM:         // Name of the stream follows  
		case VT_STORAGE:        // Name of the storage follows 
		case VT_STREAMED_OBJECT:// Stream contains an object   
		case VT_STORED_OBJECT:  // Storage contains an object  
		case VT_STREAMED_PROPSET:// Stream contains a propset  
		case VT_STORED_PROPSET: // Storage contains a propset  
			pTmp = (LPBYTE)malloc((int)cbValue);
			pIStream->Read( pTmp, cbValue, &cb );
			m_pValue = ConvertStringProp(pTmp, m_dwType, nReps, sizeof(WCHAR));
			free(pTmp);
		break;

		default:
#endif // _UNICODE
			// Allocate cbValue bytes
			if (NULL == AllocValue(cbValue))
				return FALSE;

			// Read the buffer from pIStream
			pIStream->Read( m_pValue, cbValue, &cb );
			if (cb != cbValue)
				return FALSE;
#ifdef _UNICODE
		break;
	}
#endif // _UNICODE

	// Done!
	return TRUE;
}


LPVOID CProperty::AllocValue(ULONG cb)
{
	return m_pValue = malloc((int)cb);
}


void CProperty::FreeValue()
{
	if (m_pValue != NULL)
	{
		free(m_pValue);
		m_pValue = NULL;
	}
}

/////////////////////////////////////////////////////////////////////////////
// Implementation of the CPropertySection Class

CPropertySection::CPropertySection( void )
{
	m_FormatID = GUID_NULL;
	m_SH.cbSection = 0;
	m_SH.cProperties = 0;
}

CPropertySection::CPropertySection( CLSID FormatID )
{
	m_FormatID = FormatID;
	m_SH.cbSection = 0;
	m_SH.cProperties = 0;
}

CPropertySection::~CPropertySection( void )
{
	RemoveAll();
	return;
}

CLSID CPropertySection::GetFormatID( void )
{   return m_FormatID; }

void CPropertySection::SetFormatID( CLSID FormatID )
{   m_FormatID = FormatID; }

BOOL CPropertySection::Set( DWORD dwPropID, LPVOID pValue, DWORD dwType )
{
	CProperty* pProp = GetProperty( dwPropID );
	if (pProp == NULL)
	{
		if ((pProp = new CProperty( dwPropID, pValue, dwType )) != NULL)
			AddProperty( pProp );
		return (pProp != NULL);
	}

	pProp->Set( dwPropID, pValue, dwType );
	return TRUE;
}

BOOL CPropertySection::Set( DWORD dwPropID, LPVOID pValue )
{
	// Since no dwType was specified, the property is assumed
	// to exist.   Fail if it does not.
	CProperty* pProp = GetProperty( dwPropID );
	if (pProp != NULL && pProp->m_dwType)
	{
		pProp->Set( dwPropID, pValue, pProp->m_dwType );
		return TRUE;
	}
	else
		return FALSE;
}

LPVOID CPropertySection::Get( DWORD dwPropID )
{   return Get( dwPropID, (DWORD*)NULL );  }

LPVOID CPropertySection::Get( DWORD dwPropID, DWORD* pcb )
{
	CProperty* pProp = GetProperty( dwPropID );
	if (pProp)
        {
                pProp->AssertValid();
                return pProp->Get( pcb );
        }
	else
		return NULL;
}

void CPropertySection::Remove( DWORD dwID )
{
	POSITION pos = m_PropList.GetHeadPosition();
	CProperty*  pProp;
	while( pos != NULL )
	{
		POSITION posRemove = pos;
		pProp = (CProperty*)m_PropList.GetNext( pos );
		if (pProp->m_dwPropID == dwID)
		{
			m_PropList.RemoveAt( posRemove );
			delete pProp;
			m_SH.cProperties--;
			return;
		}
	}
}

void CPropertySection::RemoveAll( )
{
	POSITION pos = m_PropList.GetHeadPosition();
	while( pos != NULL )
		delete (CProperty*)m_PropList.GetNext( pos );
	m_PropList.RemoveAll();
	m_SH.cProperties = 0;
}


CProperty* CPropertySection::GetProperty( DWORD dwPropID )
{
	POSITION pos = m_PropList.GetHeadPosition();
	m_PropList.AssertValid();
	CProperty* pProp;
	while (pos != NULL)
	{
		pProp= (CProperty*)m_PropList.GetNext( pos );
		pProp->AssertValid();
		if (pProp->m_dwPropID == dwPropID)
			return pProp;
	}
	return NULL;
}

void CPropertySection::AddProperty( CProperty* pProp )
{
	m_PropList.AddTail( pProp );
	m_SH.cProperties++;
}

DWORD CPropertySection::GetSize( void )
{   return m_SH.cbSection; }

DWORD CPropertySection::GetCount( void )
{   return m_PropList.GetCount();  }

CObList* CPropertySection::GetList( void )
{   return &m_PropList;  }

BOOL CPropertySection::WriteToStream( IStream* pIStream )
{
	// Create a dummy property entry for the name dictionary (ID == 0).
	Set(0, NULL, VT_EMPTY);

	ULONG           cb;
	ULARGE_INTEGER  ulSeekOld;
	ULARGE_INTEGER  ulSeek;
	LPSTREAM        pIStrPIDO;
	PROPERTYIDOFFSET  pido;
	LARGE_INTEGER   li;

	// The Section header contains the number of bytes in the
	// section.  Thus we need  to go back to where we should
	// write the count of bytes
	// after we write all the property sets..
	// We accomplish this by saving the seek pointer to where
	// the size should be written in ulSeekOld
	m_SH.cbSection = 0;
	m_SH.cProperties = m_PropList.GetCount();
	LISet32( li, 0 );
	pIStream->Seek( li, STREAM_SEEK_CUR, &ulSeekOld);

	pIStream->Write((LPVOID)&m_SH, sizeof(m_SH), &cb);
	if (sizeof(m_SH) != cb)
	{
		TRACE0("Write of section header failed (1).\n");
		return FALSE;
	}

	if (m_PropList.IsEmpty())
	{
		TRACE0("Warning: Wrote empty property section.\n");
		return TRUE;
	}

	// After the section header is the list of property ID/Offset pairs
	// Since there is an ID/Offset pair for each property and we
	// need to write the ID/Offset pair as we write each property
	// we clone the stream and use the clone to access the
	// table of ID/offset pairs (PIDO)...
	//
	pIStream->Clone( &pIStrPIDO );

	// Now seek pIStream past the PIDO list
	//
	LISet32( li,  m_SH.cProperties * sizeof( PROPERTYIDOFFSET ) );
	pIStream->Seek( li, STREAM_SEEK_CUR, &ulSeek);

	// Now write each section to pIStream.
	CProperty* pProp = NULL;
	POSITION pos = m_PropList.GetHeadPosition();
	while( pos != NULL )
	{
		// Get next element (note cast)
		pProp = (CProperty*)m_PropList.GetNext( pos );

		if (pProp->m_dwPropID != 0)
		{
			// Write it
			if (!pProp->WriteToStream( pIStream ))
			{
				pIStrPIDO->Release();
				return FALSE;
			}
		}
		else
		{
			if (!WriteNameDictToStream( pIStream ))
			{
				pIStrPIDO->Release();
				return FALSE;
			}
		}

		// Using our cloned stream write the Format ID / Offset pair
		// The offset to this property is the current seek pointer
		// minus the pointer to the beginning of the section
		pido.dwOffset = ulSeek.LowPart - ulSeekOld.LowPart;
		pido.propertyID = pProp->m_dwPropID;
		pIStrPIDO->Write((LPVOID)&pido, sizeof(pido), &cb);
		if (sizeof(pido) != cb)
		{
			TRACE0("Write of 'pido' failed\n");
			pIStrPIDO->Release();
			return FALSE;
		}

		// Get the seek offset after the write
		LISet32( li, 0 );
		pIStream->Seek( li, STREAM_SEEK_CUR, &ulSeek );
	}

	pIStrPIDO->Release();

	// Now go back to ulSeekOld and write the section header.
	// Size of section is current seek point minus old seek point
	//
	m_SH.cbSection = ulSeek.LowPart - ulSeekOld.LowPart;

	// Seek to beginning of this section and write the section header.
	LISet32( li, ulSeekOld.LowPart );
	pIStream->Seek( li, STREAM_SEEK_SET, NULL );
	pIStream->Write((LPVOID)&m_SH, sizeof(m_SH), &cb);
	if (sizeof(m_SH) != cb)
	{
		TRACE0("Write of section header failed (2).\n");
		return FALSE;
	}

	// Now seek to end of of the now written section
	LISet32(li, ulSeek.LowPart);
	pIStream->Seek(li, STREAM_SEEK_SET, NULL);

	return TRUE;
}

BOOL CPropertySection::ReadFromStream( IStream* pIStream,
	LARGE_INTEGER liPropSet )
{
	ULONG               cb;
	PROPERTYIDOFFSET    pido;
	ULONG               cProperties;
	LPSTREAM            pIStrPIDO;
	ULARGE_INTEGER      ulSectionStart;
	LARGE_INTEGER       li;
	CProperty*          pProp;

	if (m_SH.cProperties || !m_PropList.IsEmpty())
		RemoveAll();

	// pIStream is pointing to the beginning of the section we
	// are to read.  First there is a DWORD that is the count
	// of bytes in this section, then there is a count
	// of properties, followed by a list of propertyID/offset pairs,
	// followed by type/value pairs.
	//
	LISet32( li, 0 );
	pIStream->Seek( li, STREAM_SEEK_CUR, &ulSectionStart );
	pIStream->Read( (LPVOID)&m_SH, sizeof(m_SH), &cb );
	if (cb != sizeof(m_SH))
		return FALSE;

	// Now we're pointing at the first of the PropID/Offset pairs
	// (PIDOs).   To get to each property we use a cloned stream
	// to stay back and point at the PIDOs (pIStrPIDO).  We seek
	// pIStream to each of the Type/Value pairs, creating CProperites
	// and so forth as we go...
	//
	pIStream->Clone( &pIStrPIDO );

	cProperties = m_SH.cProperties;
	while (cProperties--)
	{
		pIStrPIDO->Read( (LPVOID)&pido, sizeof( pido ), &cb );
		if (cb != sizeof(pido))
		{
			pIStrPIDO->Release();
			return FALSE;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -