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

📄 common.cpp

📁 用测试OLE DB提供者的一个程序。能够测试出OEL DB提供者到底实现了哪些接口?很灵的。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// Microsoft OLE DB RowsetViewer
// Copyright (C) 1994 - 1998 By Microsoft Corporation.
//
// @doc
//
// @module COMMON.CPP
//
//-----------------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////
// Include
//
/////////////////////////////////////////////////////////////////////////////
#include "common.h"


/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToMBCS
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertToMBCS(WCHAR* pwsz, CHAR* psz, ULONG cStrLen)
{
	ASSERT(psz);

	//No-op
	if(pwsz==NULL)
	{
		psz[0] = EOL;
		return S_FALSE;
	}

	//Convert the string to MBCS
	INT iResult = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, cStrLen, NULL, NULL);
	
	//Add NULL Terminator
	psz[min((ULONG)iResult, cStrLen-1)] = EOL;
	return iResult ? S_OK : E_FAIL;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToMBCS
//		Dynamically allocated memory
/////////////////////////////////////////////////////////////////////////////
CHAR* ConvertToMBCS(WCHAR* pwsz)
{
	//no-op case
	if(!pwsz)
		return NULL;
	
	//Determine the space required for the conversion
	LONG iLen = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, NULL, 0, NULL, NULL);

	//Allocate space for the string
	CHAR* pszBuffer = NULL;
	SAFE_ALLOC(pszBuffer, CHAR, iLen+1);

	//Now convert the string
	WideCharToMultiByte(CP_ACP, 0, pwsz, -1, pszBuffer, iLen+1, NULL, NULL);

CLEANUP:
	return pszBuffer;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToWCHAR
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertToWCHAR(CHAR* psz, WCHAR* pwsz, ULONG cStrLen)
{
	ASSERT(pwsz);

	//No-op
	if(psz==NULL)
	{
		pwsz[0] = wEOL;
		return S_FALSE;
	}

	//Convert the string to MBCS
	INT iResult = MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cStrLen);

	//Add NULL Terminator
	pwsz[min((ULONG)iResult, cStrLen-1)] = wEOL;
	return iResult ? S_OK : E_FAIL;
}



/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToWCHAR
//		Dynamically allocated memory
/////////////////////////////////////////////////////////////////////////////
WCHAR* ConvertToWCHAR(CHAR* psz)
{
	//no-op case
	if(!psz)
		return NULL;
	
	//Determine the space required for the conversion
	LONG iLen = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);

	//Allocate space for the string
	WCHAR* pwszBuffer = NULL;
	SAFE_ALLOC(pwszBuffer, WCHAR, iLen+1);

	//Now convert the string
	MultiByteToWideChar(CP_ACP, 0, psz, -1, pwszBuffer, iLen+1);

CLEANUP:
	return pwszBuffer;
}



/////////////////////////////////////////////////////////////////////////////
// HRESULT GUIDFromString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT GUIDFromString(CHAR* psz, GUID* pGuid)
{
	if(psz == NULL || pGuid == NULL)
		return E_FAIL;

	WCHAR* pwsz = ConvertToWCHAR(psz);
	HRESULT hr = CLSIDFromString(pwsz, pGuid);

	SAFE_FREE(pwsz);
	return hr;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertString(CHAR* psz, ULONG ulMaxSize, DWORD dwFlags)
{
	ASSERT(psz);
	ASSERT(ulMaxSize);
	CHAR* pszStop = NULL;

	//Currently only deals with HEX or DECIMAL
	ASSERT(dwFlags & CONV_HEX || dwFlags & CONV_DECIMAL);

	//Convert String to integer
	LONG lValue = strtol(psz, &pszStop, 10);
	if(lValue == LONG_MAX || lValue == 0 || pszStop==NULL || pszStop[0]!=EOL)
		return E_FAIL;

	//Convert Integer back to requested Format
	if(dwFlags & CONV_HEX)
		sprintf(psz, "0x%x", lValue);
	else
		sprintf(psz, "%d", lValue);

	return S_OK;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT BYTESToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT BYTESToString(BYTE* pb, CHAR* pszBuffer, ULONG cBytes, ULONG* pulStrLen)
{
	ASSERT(pb && pszBuffer);

	// Process the byte stream, converting each byte into
	// its two character unicode hexaDECIMAL representation
	static CHAR s_chHex[] = 
	{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

	for(ULONG i=0; i<cBytes; i++)
	{
		*pszBuffer++ = s_chHex[*pb >> 4];
		*pszBuffer++ = s_chHex[*pb & 0x0F];
		pb++;
	}
	*pszBuffer = EOL;
	
	if(pulStrLen)
		*pulStrLen = cBytes << 1;
	return S_OK;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT StringToBYTES
//
/////////////////////////////////////////////////////////////////////////////
HRESULT StringToBYTES(CHAR* pszBuffer, BYTE* pb, ULONG cBytes, ULONG* pcbBytes)
{
	ASSERT(pszBuffer && pb);

	// Process the byte stream, converting each byte into
	// its two character unicode hexaDECIMAL representation
	static CHAR s_chByte[] = 
	{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '?', '?', '?', '?', '?', '?', '?', 'A', 'B', 'C', 'D', 'E', 'F'};

	for(ULONG i=0; i<cBytes; i++)
	{
		// Process first character of pair
		CHAR ch = *pszBuffer++;
		if( ch >= '0' && ch <= '9' )
			ch -= '0';
		else if( ch >= 'A' && ch <= 'F' )
			ch -= 'A' - 10;
		else if( ch >= 'a' && ch <= 'f' )
			ch -= 'a' - 10;
		else
			return DB_E_CANTCONVERTVALUE;
		*pb = (BYTE)ch << 4;

		// Advance to second character of pair
		ch = *pszBuffer++;
		if( ch >= '0' && ch <= '9' )
			ch -= '0';
		else if( ch >= 'A' && ch <= 'F' )
			ch -= 'A' - 10;
		else if( ch >= 'a' && ch <= 'f' )
			ch -= 'a' - 10;
		else
			return DB_E_CANTCONVERTVALUE;
		*pb |= (BYTE)ch;

		// Done two characters -- created one byte
		pb++;
	}
	
	if(pcbBytes)
		*pcbBytes = cBytes;
	return S_OK;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT VariantToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT VariantToString(VARIANT* pVariant, CHAR* psz, ULONG ulMaxSize, DWORD dwFlags)
{
	//Convert a VARIANT to a WCHAR
	ASSERT(pVariant);
	ASSERT(psz);
	ASSERT(ulMaxSize > 0);
	HRESULT hr = S_OK;
	
	//Find the VariantType
	DBTYPE wType = V_VT(pVariant);
	VARIANT VarTemp;
	VariantInit(&VarTemp);
	static LCID lcid = GetSystemDefaultLCID();

	//VT_ARRAY is not handled by VariantChangeTypeEx
	if(wType & VT_ARRAY)
	{
		TESTC(hr = SafeArrayToString(V_ARRAY(pVariant), wType, psz, ulMaxSize));
		goto CLEANUP;
	}

	switch(wType)
	{
		case VT_NULL:
		case VT_EMPTY:
			psz[0] = EOL;
			break;

		case VT_BOOL:
			if(V_BOOL(pVariant) == VARIANT_TRUE)
				sprintf(psz, "%s", dwFlags & CONV_VARBOOL ? "VARIANT_TRUE" : "True");
			else if(V_BOOL(pVariant) == VARIANT_FALSE)
				sprintf(psz, "%s", dwFlags & CONV_VARBOOL ? "VARIANT_FALSE" : "False");
			else
				sprintf(psz, "%d", V_BOOL(pVariant));
			break;

		case VT_ERROR:
			sprintf(psz, "%d", V_ERROR(pVariant));
			break;

		default:
		{
			//Delgate
			TESTC(hr = VariantChangeTypeEx(
				&VarTemp,	// Destination (convert not in place)
				pVariant,	// Source
				lcid,		// LCID
				0,			// dwFlags
				VT_BSTR ));
	
			//Convert to MBCS
			ConvertToMBCS(V_BSTR(&VarTemp), psz, ulMaxSize);
		}
	};

CLEANUP:
	psz[ulMaxSize-1] = EOL;
	XTEST(NULL, VariantClear(&VarTemp));
	return hr;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT VariantToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT VariantToString(VARIANT* pVariant, WCHAR* pwsz, ULONG ulMaxSize, DWORD dwFlags)
{
	//Convert a VARIANT to a WCHAR
	ASSERT(pVariant);
	ASSERT(pwsz);
	ASSERT(ulMaxSize > 0);
	HRESULT hr = S_OK;
	
	//Find the VariantType
	DBTYPE wType = V_VT(pVariant);
	VARIANT VarTemp;
	VariantInit(&VarTemp);
	static LCID lcid = GetSystemDefaultLCID();

	//VT_ARRAY is not handled by VariantChangeTypeEx
	if(wType & VT_ARRAY)
	{
		CHAR szBuffer[MAX_COL_SIZE];
		ASSERT(ulMaxSize >= MAX_COL_SIZE);
		TESTC(hr = SafeArrayToString(V_ARRAY(pVariant), wType, szBuffer, MAX_COL_SIZE));
		ConvertToWCHAR(szBuffer, pwsz, MAX_COL_SIZE);
		goto CLEANUP;
	}

	switch(wType)
	{
		case VT_NULL:
		case VT_EMPTY:
			pwsz[0] = EOL;
			break;

		case VT_BOOL:
			if(V_BOOL(pVariant) == VARIANT_TRUE)
				swprintf(pwsz, L"%s", dwFlags & CONV_VARBOOL ? L"VARIANT_TRUE" : L"True");
			else if(V_BOOL(pVariant) == VARIANT_FALSE)
				swprintf(pwsz, L"%s", dwFlags & CONV_VARBOOL ? L"VARIANT_FALSE" : L"False");
			else
				swprintf(pwsz, L"%d", V_BOOL(pVariant));
			break;

		case VT_ERROR:
			swprintf(pwsz, L"%d", V_ERROR(pVariant));
			break;

		default:
		{
			TESTC(hr = VariantChangeTypeEx(
				&VarTemp,	// Destination (convert not in place)
				pVariant,	// Source
				lcid,		// LCID
				0,			// dwFlags
				VT_BSTR ));

			//Convert to MBCS
			wcsncpy(pwsz, V_BSTR(&VarTemp), ulMaxSize);

			//May need Hex postprocessing
			if(dwFlags & CONV_HEX)
			{
				switch(V_VT(pVariant))
				{
					case DBTYPE_I4:
						swprintf(pwsz, L"0x%x", V_I4(pVariant));
						break;
				}
			}
		}
	};

CLEANUP:
	pwsz[ulMaxSize-1] = wEOL;
	XTEST(NULL, VariantClear(&VarTemp));
	return hr;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT StringToVariant
//
/////////////////////////////////////////////////////////////////////////////
HRESULT StringToVariant(WCHAR* pwsz, VARTYPE vt, VARIANT* pVariant, DWORD dwFlags)
{
	//Convert a VARIANT to a WCHAR
	ASSERT(pwsz);
	ASSERT(pVariant);
	HRESULT hr = S_OK;

	//Assign the type...
	V_VT(pVariant) = vt;
	static LCID lcid = GetSystemDefaultLCID();

	//VariantChangeTypeEx seems to handle most types,
	//except the following cases...
	switch(vt)
	{
		case VT_NULL:
		case VT_EMPTY:
			break;

		case VT_BOOL:
		{	
			if(dwFlags & CONV_VARBOOL && _wcsicmp(pwsz, L"VARIANT_TRUE")==0)
				V_BOOL(pVariant) = VARIANT_TRUE;
			else if(dwFlags & CONV_VARBOOL && _wcsicmp(pwsz, L"VARIANT_FALSE")==0)
				V_BOOL(pVariant) = VARIANT_FALSE;
			else if(dwFlags & CONV_ALPHABOOL && _wcsicmp(pwsz, L"True")==0)
				V_BOOL(pVariant) = VARIANT_TRUE;
			else if(dwFlags & CONV_ALPHABOOL && _wcsicmp(pwsz, L"False")==0)
				V_BOOL(pVariant) = VARIANT_FALSE;
			else
			{
				LONG lValue = wcstol(pwsz, NULL, 0);
				if(lValue == LONG_MAX || lValue>SHRT_MAX || lValue<SHRT_MIN)
				{
					hr = E_FAIL;
					goto CLEANUP;
				}
				V_BOOL(pVariant) = (VARIANT_BOOL)lValue;
			}
			break;
		}

		case VT_I4:
		case VT_UI4:
		case VT_ERROR:
		{	
			//We handle this case seperatly since we want to handle HEX values
			WCHAR* pwszStop = NULL;
			LONG ulValue = wcstol(pwsz, &pwszStop, 0);
			if(pwszStop==NULL || pwszStop[0]!=wEOL)
			{
				hr = E_FAIL;
				goto CLEANUP;
			}

			V_I4(pVariant) = ulValue;
			break;
		}

		default:
		{
			//Place the string into the BSTR of the VARIANT
			V_VT(pVariant) = VT_BSTR;
			V_BSTR(pVariant) = SysAllocString(pwsz);
			
			//Now delegate to VariantChangeType...
			TESTC(hr = VariantChangeTypeEx(
				pVariant,	// Destination (convert in place)
				pVariant,	// Source
				lcid,		// LCID
				0,			// dwFlags
				vt ));
		}
	};

CLEANUP:
	return hr;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT SafeArrayToString
//
/////////////////////////////////////////////////////////////////////////////
HRESULT SafeArrayToString(SAFEARRAY* pSafeArray, DBTYPE wType, CHAR* pszBuffer, ULONG ulMaxSize)
{
	ASSERT(pSafeArray);

	//This method is capable of handling N-Dimenstions of Data!!

⌨️ 快捷键说明

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