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

📄 propset.cpp

📁 连接oracle
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1997 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"

#if !defined(_MAC)

#include <malloc.h>
#include <ole2.h>
#include <oleauto.h>
#include "propset.h"

#ifdef AFXCTL_PROP_SEG
#pragma code_seg(AFXCTL_PROP_SEG)
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW


static LPVOID CountPrefixedStringA(LPCSTR lpsz)
{
	DWORD cb = (lstrlenA( lpsz ) + 1);
	LPDWORD lp = (LPDWORD)malloc( (int)cb + sizeof(DWORD) );
	if (lp)
	{
		*lp = cb;
		lstrcpyA( (LPSTR)(lp+1), lpsz );
	}

	return (LPVOID)lp;
}


static LPVOID CountPrefixedStringW(LPCWSTR lpsz)
{
	DWORD cb = (wcslen( lpsz ) + 1);
	LPDWORD lp = (LPDWORD)malloc( (int)cb * sizeof(WCHAR) + sizeof(DWORD) );
	if (lp)
	{
		*lp = cb;
		wcscpy( (LPWSTR)(lp+1), lpsz );
	}

	return (LPVOID)lp;
}


#ifdef _UNICODE
#define CountPrefixedStringT CountPrefixedStringW
#else
#define CountPrefixedStringT CountPrefixedStringA
#endif


#ifdef _UNICODE

#define MAX_STRLEN 1024

static LPBYTE ConvertStringProp(LPBYTE pbProp, DWORD dwType, ULONG nReps,
	size_t cbCharSize)
{
	LPBYTE pbResult = NULL; // Return value
	ULONG cbResult = 0;     // Number of bytes in pbResult
	LPBYTE pbBuffer;        // Temporary holding space
	ULONG cchOrig;          // Number of characters in original string
	ULONG cchCopy;          // Number of characters to copy
	ULONG cbCopy;           // Number of bytes to copy
	LPBYTE pbResultNew;     // Used for realloc of pbResult

	pbBuffer = (LPBYTE)malloc(MAX_STRLEN * cbCharSize);
	if (pbBuffer == NULL)
		return NULL;

	// If it's a vector, the count goes first.
	if (dwType & VT_VECTOR)
	{
		pbResult = (LPBYTE)malloc(sizeof(DWORD));
		if (pbResult == NULL)
		{
			free(pbBuffer);
			return NULL;
		}
		*(LPDWORD)pbResult = nReps;
		cbResult = sizeof(DWORD);
	}

	while (nReps--)
	{
		cchOrig = *(LPDWORD)pbProp;
		pbProp += sizeof(DWORD);

		// Convert multibyte string to Unicode.
		if (cbCharSize == sizeof(WCHAR))
		{
			cchCopy = _mbstowcsz((LPWSTR)pbBuffer, (LPSTR)pbProp,
				min(cchOrig, MAX_STRLEN));
		}
		else
		{
			cchCopy = _wcstombsz((LPSTR)pbBuffer, (LPWSTR)pbProp,
				min(cchOrig, MAX_STRLEN));
		}

		// Allocate space to append string.
		cbCopy = cchCopy * cbCharSize;
		pbResultNew = (LPBYTE)realloc(pbResult, cbResult + sizeof(DWORD) +
			cbCopy);

		// If allocation failed, cleanup and return NULL;
		if (pbResultNew == NULL)
		{
			free(pbResult);
			free(pbBuffer);
			return NULL;
		}

		pbResult = pbResultNew;

		// Copy character count and converted string into place,
		// then update the total size.
		memcpy(pbResult + cbResult, (LPBYTE)&cchCopy, sizeof(DWORD));
		memcpy(pbResult + cbResult + sizeof(DWORD), pbBuffer, cbCopy);
		cbResult += sizeof(DWORD) + cbCopy;

		// Advance to the next vector element
		pbProp += (cchOrig * cbCharSize);
	}

	free(pbBuffer);
	return pbResult;
}

#endif // _UNICODE


/////////////////////////////////////////////////////////////////////////////
//Implementation of the CProperty class

CProperty::CProperty( void )
{
	m_dwPropID = 0;

	m_dwType = VT_EMPTY;
	m_pValue = NULL;       // must init to NULL
}

CProperty::CProperty( DWORD dwID, const LPVOID pValue, DWORD dwType )
{
	m_dwPropID = dwID;
	m_dwType = dwType;
	m_pValue = NULL;       // must init to NULL
	Set( dwID, pValue, dwType );
}

CProperty::~CProperty()
{
	FreeValue();
}

BOOL CProperty::Set( DWORD dwID, const LPVOID pValue, DWORD dwType )
{
	m_dwType = dwType;
	m_dwPropID = dwID;

	return Set( pValue );
}

BOOL CProperty::Set( const LPVOID pValue, DWORD dwType )
{
	m_dwType = dwType;
	return Set( pValue );
}

BOOL CProperty::Set( const  LPVOID pVal )
{
	ULONG           cb;
	ULONG           cbItem;
	ULONG           cbValue;
	ULONG           nReps;
	LPBYTE          pCur;
	LPVOID          pValue = pVal;
	DWORD           dwType = m_dwType;
	LPVOID          pValueOrig = NULL;

	if (m_pValue != NULL)
	{
		FreeValue();
	}

	if (pValue == NULL || m_dwType == 0)
		return TRUE;

	// Given pValue, determine how big it is
	// Then allocate a new buffer for m_pValue and copy...
	nReps = 1;
	cbValue = 0;
	pCur = (LPBYTE)pValue;
	if (m_dwType & VT_VECTOR)
	{
		// The next DWORD is a count of the elements
		nReps = *(LPDWORD)pValue;
		cb = sizeof( nReps );
		pCur += cb;
		cbValue += cb;
		dwType &= ~VT_VECTOR;
	}
	else
	{
		// If we get any of the string-like types,
		// and we are not a vector create a count-prefixed
		// buffer.
		switch (dwType )
		{
			case VT_LPSTR:          // null terminated string      
				pValueOrig = pValue;
				pValue = CountPrefixedStringA( (LPSTR)pValueOrig );
				pCur = (LPBYTE)pValue;
			break;

			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  
				pValueOrig = pValue;
				pValue = CountPrefixedStringT( (LPTSTR)pValueOrig );
				pCur = (LPBYTE)pValue;
			break;

			case VT_LPWSTR:         // UNICODE string 
				pValueOrig = pValue;
				pValue = CountPrefixedStringW( (LPWSTR)pValueOrig );
				pCur = (LPBYTE)pValue;
			break;
		}
	}

	// 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.
	//
	cbItem = 0;        // Size of the current item
	while (nReps--)
	{
		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_CLSID:          // A Class ID                  
				cbItem = sizeof(CLSID);
			break;

#ifndef _UNICODE
			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  
#endif // _UNICODE
			case VT_LPSTR:          // null terminated string      
			case VT_BLOB_OBJECT:    // Blob contains an object     
			case VT_BLOB_PROPSET:   // Blob contains a propset     
			case VT_BLOB:           // Length prefixed bytes       
			case VT_CF:             // Clipboard format            
				// Get the DWORD that gives us the size, making
				// sure we increment cbValue.
				cbItem = *(LPDWORD)pCur;
				cb = sizeof(cbItem);
				pCur += cb;
				cbValue += cb;
			break;

#ifdef _UNICODE
			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  
#endif // _UNICODE
			case VT_LPWSTR:         // UNICODE string 
				cbItem = *(LPDWORD)pCur * sizeof(WCHAR);
				cb = sizeof( cbItem );
				pCur += cb;
				cbValue += cb;
			break;
	        case VT_VARIANT:        // VARIANT*                
	        break;

			default:
				if (pValueOrig)
					free( pValue );
				return FALSE;
		}

		// Add 'cb' to cbItem before seeking...
		//
		// Seek to the next item
		pCur += cbItem;
		cbValue += cbItem;
	}

	if (NULL == AllocValue(cbValue))
	{
		TRACE0("CProperty::AllocValue failed");
		return FALSE;
	}
	memcpy( m_pValue, pValue, (int)cbValue );

	if (pValueOrig)
		free( pValue );

	return TRUE;
}

LPVOID CProperty::Get( void )
{   return Get( (DWORD*)NULL );   }

LPVOID CProperty::Get( DWORD* pcb )
{
	DWORD   cb;
	LPBYTE  p = NULL;

	p = (LPBYTE)m_pValue;

	// m_pValue points to a Property "Value" which may
	// have size information included...
	switch( m_dwType )
	{
		case VT_EMPTY:          // nothing                     
			cb = 0;
		break;

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

		case VT_I4:             // 4 byte signed int           
		case VT_R4:             // 4 byte real                 
			cb = 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                    
			cb = 8;
		break;

#ifndef _UNICODE
		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  
#endif // UNICODE
		case VT_LPSTR:          // null terminated string      
		case VT_CF:             // Clipboard format            
			// Read the DWORD that gives us the size, making
			// sure we increment cbValue.
			cb = *(LPDWORD)p;
			p += sizeof( DWORD );
		break;

		case VT_BLOB:           // Length prefixed bytes       
		case VT_BLOB_OBJECT:    // Blob contains an object     
		case VT_BLOB_PROPSET:   // Blob contains a propset     
			// Read the DWORD that gives us the size.
			cb = *(LPDWORD)p;
		break;

#ifdef _UNICODE
		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  
#endif // _UNICODE
		case VT_LPWSTR:         // UNICODE string 
			cb = *(LPDWORD)p * sizeof(WCHAR);
			p += sizeof( DWORD );
		break;

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

        case VT_VARIANT:        // VARIANT*                
        break;

		default:
			return NULL;
	}
	if (pcb != NULL)
		*pcb = cb;

	return p;
}

DWORD  CProperty::GetType( void )
{   return m_dwType;  }

void   CProperty::SetType( DWORD dwType )
{   m_dwType = dwType; }

DWORD CProperty::GetID( void )
{   return m_dwPropID;   }

void CProperty::SetID( DWORD dwPropID )
{    m_dwPropID = dwPropID;   }

LPVOID CProperty::GetRawValue( void )
{   return m_pValue; }

BOOL CProperty::WriteToStream( IStream* pIStream )
{
	ULONG           cb;
	ULONG           cbTotal; // Total size of the whole value
	DWORD           dwType = m_dwType;
	DWORD           nReps;
	LPBYTE          pValue;
	LPBYTE          pCur;
	BOOL            bSuccess = FALSE;
	BYTE            b = 0;

	nReps = 1;
	pValue = (LPBYTE)m_pValue;
	pCur = pValue;
	cbTotal = 0;
	if (m_dwType & VT_VECTOR)
	{
		// Value is a DWORD count of elements followed by
		// that many repititions of the value.
		//
		nReps = *(LPDWORD)pCur;
		cbTotal = sizeof(DWORD);
		pCur += cbTotal;
		dwType &= ~VT_VECTOR;
	}

#ifdef _UNICODE
	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  
			pValue = ConvertStringProp(pCur, m_dwType, nReps, sizeof(char));
			if (m_dwType & VT_VECTOR)
				pCur = pValue + sizeof(DWORD);
		break;
	}
#endif // _UNICODE

	// Figure out how big the data is.
	while (nReps--)
	{
		switch (dwType)
		{
			case VT_EMPTY:          // nothing                     
				cb = 0;
			break;

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

			case VT_I4:             // 4 byte signed int           
			case VT_R4:             // 4 byte real                 
				cb = 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                    
				cb = 8;
			break;

			case VT_LPSTR:          // null terminated string      

⌨️ 快捷键说明

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