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.
 
 
 
 
 
 

1361 lines
42 KiB

// **************************************************************************
// Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
//
// File: utils.cpp
//
// Description:
// Set of sample routines
//
// History:
//
// **************************************************************************
//#pragma warning(disable:4201) // nonstandard extension nameless struct (used in windows.h)
//#pragma warning(disable:4514) // unreferenced inline function has been removed (used in windows.h)
#include "precomp.h"
#include <stdio.h>
#include <wbemidl.h>
#include <sys\timeb.h>
#include "utillib.h"
//*****************************************************************************
// Function: WbemErrorString
// Purpose: Turns sc into a text string
//*****************************************************************************
BSTR WbemErrorString(SCODE sc)
{
IWbemStatusCodeTextPtr pStatus;
BSTR bstr = NULL;
SCODE mysc = CoCreateInstance(CLSID_WbemStatusCodeText, 0, CLSCTX_INPROC_SERVER,
IID_IWbemStatusCodeText, (LPVOID *) &pStatus);
if (mysc == S_OK)
{
mysc = pStatus->GetErrorCodeText(sc, 0, 0, &bstr);
if (mysc == S_OK)
{
}
else
{
WCHAR szBuffer2[MAXITOA];
WCHAR szBuffer[sizeof(szBuffer2) + 4];
_ltow(sc, szBuffer2, 16);
wcscpy(szBuffer, L"0x");
wcscat(szBuffer, szBuffer2);
bstr = SysAllocString(szBuffer);
}
}
return bstr;
}
//***************************************************************************
// Function: PrintError
// Purpose: Formats and prints the error message
//***************************************************************************
void PrintError(char *pszFailureReason, SCODE psc, DWORD dwMode)
{
VARIANT varString;
SCODE sc;
IWbemClassObject *pErrorObject = NULL;
IErrorInfo* pEI = NULL;
fprintf(stdout, "%s\n", pszFailureReason);
fprintf(stdout, "FunctionReturn: %S(0x%08lx)\n", WbemErrorString(psc), psc);
if (GetErrorInfo(0, &pEI) == S_OK)
{
pEI->QueryInterface(IID_IWbemClassObject, (void**)&pErrorObject);
pEI->Release();
}
if (pErrorObject != NULL)
{
VariantInit(&varString);
if (dwMode == ERROR_MODE_PRINTFIELDS)
{
if (pErrorObject->InheritsFrom(L"__NotifyStatus") != WBEM_NO_ERROR)
{
fprintf(stdout, "Unrecognized Error Object type\n");
}
else if (pErrorObject->InheritsFrom(L"__ExtendedStatus") == WBEM_NO_ERROR)
{
sc = pErrorObject->Get(L"Description", 0L, &varString, NULL, NULL);
if (sc != S_OK)
{
fprintf(stdout, "Can't get Description: %d\n", sc);
}
else if (V_VT(&varString) == VT_BSTR)
{
FWPRINTF(stdout, L"Description: %wS\n", V_BSTR(&varString));
}
VariantClear(&varString);
pErrorObject->Get(L"Operation", 0L, &varString, NULL, NULL);
if (sc != S_OK)
{
fprintf(stdout, "Can't get Operation: %d\n", sc);
}
else if (V_VT(&varString) == VT_BSTR)
{
FWPRINTF(stdout, L"Operation: %wS\n", V_BSTR(&varString));
}
VariantClear(&varString);
pErrorObject->Get(L"ParameterInfo", 0L, &varString, NULL, NULL);
if (sc != S_OK)
{
fprintf(stdout, "Can't get ParameterInfo: %d\n", sc);
}
else if (V_VT(&varString) == VT_BSTR)
{
FWPRINTF(stdout, L"ParameterInfo: %wS\n", V_BSTR(&varString));
}
VariantClear(&varString);
pErrorObject->Get(L"ProviderName", 0L, &varString, NULL, NULL);
if (sc != S_OK)
{
fprintf(stdout, "Can't get ProviderName: %d\n", sc);
}
else if (V_VT(&varString) == VT_BSTR)
{
FWPRINTF(stdout, L"ProviderName: %wS\n", V_BSTR(&varString));
}
VariantClear(&varString);
}
}
else
{
BSTR bstrObjectText = NULL;
if (SUCCEEDED(pErrorObject->GetObjectText(0, &bstrObjectText)))
{
fprintf(stdout, "%wS", bstrObjectText);
SysFreeString(bstrObjectText);
}
}
RELEASE(pErrorObject);
}
}
//***************************************************************************
// Function: PrintErrorAndExit
// Purpose: Formats an error message & exits program
//***************************************************************************
void PrintErrorAndExit(char *pszFailureReason, SCODE sc, DWORD dwMode)
{
PrintError(pszFailureReason, sc, dwMode);
// Clean up and exit
OleUninitialize();
printf("Abnormal Termination\n");
exit(1);
};
//***************************************************************************
// Function: PrintErrorAndAsk
// Purpose: Prints the error message and prompts to continue
//***************************************************************************
void PrintErrorAndAsk(char *pszFailureReason, SCODE sc, DWORD dwMode)
{
int c;
PrintError(pszFailureReason, sc, dwMode);
printf("Continue (Y/N)? ");
c = getchar();
while (getchar() != '\n')
{
}
if ((c != 'Y') && (c != 'y'))
{
// Clean up and exit
OleUninitialize();
exit(1);
}
};
//*****************************************************************************
// Function: TypeToString
// Purpose: Takes a variant, returns a pointer to a string that is the variant type
//*****************************************************************************
const WCHAR *TypeToString(VARIANT *p)
{
return TypeToString(p->vt);
}
//*****************************************************************************
// Function: TypeToString
// Purpose: Takes a VARTYPE, returns a pointer to a string that is the variant type
//*****************************************************************************
const WCHAR *TypeToString(VARTYPE v)
{
const static WCHAR *pVT_NULL = L"VT_NULL";
const static WCHAR *pVT_EMTPY = L"VT_EMPTY";
const static WCHAR *pVT_I1 = L"VT_I1";
const static WCHAR *pVT_UI1 = L"VT_UI1";
const static WCHAR *pVT_I2 = L"VT_I2";
const static WCHAR *pVT_UI2 = L"VT_UI2";
const static WCHAR *pVT_I4 = L"VT_I4";
const static WCHAR *pVT_UI4 = L"VT_UI4";
const static WCHAR *pVT_I8 = L"VT_I8";
const static WCHAR *pVT_UI8 = L"VT_UI8";
const static WCHAR *pVT_R4 = L"VT_R4";
const static WCHAR *pVT_R8 = L"VT_R8";
const static WCHAR *pVT_BOOL = L"VT_BOOL";
const static WCHAR *pVT_BSTR = L"VT_BSTR";
const static WCHAR *pVT_DISPATCH = L"VT_DISPATCH";
const static WCHAR *pVT_UNKNOWN = L"VT_UNKNOWN";
const static WCHAR *pVT_I1_ARRAY = L"VT_I1 | VT_ARRAY";
const static WCHAR *pVT_UI1_ARRAY = L"VT_UI1 | VT_ARRAY";
const static WCHAR *pVT_I2_ARRAY = L"VT_I2 | VT_ARRAY";
const static WCHAR *pVT_UI2_ARRAY = L"VT_UI2 | VT_ARRAY";
const static WCHAR *pVT_I4_ARRAY = L"VT_I4 | VT_ARRAY";
const static WCHAR *pVT_UI4_ARRAY = L"VT_UI4 | VT_ARRAY";
const static WCHAR *pVT_I8_ARRAY = L"VT_I8 | VT_ARRAY";
const static WCHAR *pVT_UI8_ARRAY = L"VT_UI8 | VT_ARRAY";
const static WCHAR *pVT_R4_ARRAY = L"VT_R4 | VT_ARRAY";
const static WCHAR *pVT_R8_ARRAY = L"VT_R8 | VT_ARRAY";
const static WCHAR *pVT_BOOL_ARRAY = L"VT_BOOL | VT_ARRAY";
const static WCHAR *pVT_BSTR_ARRAY = L"VT_BSTR | VT_ARRAY";
const static WCHAR *pVT_DISPATCH_ARRAY = L"VT_DISPATCH | VT_ARRAY";
const static WCHAR *pVT_UNKNOWN_ARRAY = L"VT_UNKNOWN | VT_ARRAY";
const WCHAR *pRetVal;
switch (v)
{
case VT_NULL: pRetVal = pVT_NULL; break;
case VT_I1: pRetVal = pVT_I1; break;
case VT_UI1: pRetVal = pVT_UI1; break;
case VT_I2: pRetVal = pVT_I2; break;
case VT_UI2: pRetVal = pVT_UI2; break;
case VT_I4: pRetVal = pVT_I4; break;
case VT_UI4: pRetVal = pVT_UI4; break;
case VT_I8: pRetVal = pVT_I8; break;
case VT_UI8: pRetVal = pVT_UI8; break;
case VT_R4: pRetVal = pVT_R4; break;
case VT_R8: pRetVal = pVT_R8; break;
case VT_BOOL: pRetVal = pVT_BOOL; break;
case VT_BSTR: pRetVal = pVT_BSTR; break;
case VT_DISPATCH: pRetVal = pVT_DISPATCH; break;
case VT_UNKNOWN: pRetVal = pVT_UNKNOWN; break;
case VT_I1|VT_ARRAY: pRetVal = pVT_I1_ARRAY; break;
case VT_UI1|VT_ARRAY: pRetVal = pVT_UI1_ARRAY; break;
case VT_I2|VT_ARRAY: pRetVal = pVT_I2_ARRAY; break;
case VT_UI2|VT_ARRAY: pRetVal = pVT_UI2_ARRAY; break;
case VT_I4|VT_ARRAY: pRetVal = pVT_I4_ARRAY; break;
case VT_UI4|VT_ARRAY: pRetVal = pVT_UI4_ARRAY; break;
case VT_I8|VT_ARRAY: pRetVal = pVT_I8_ARRAY; break;
case VT_UI8|VT_ARRAY: pRetVal = pVT_UI8_ARRAY; break;
case VT_R4|VT_ARRAY: pRetVal = pVT_R4_ARRAY; break;
case VT_R8|VT_ARRAY: pRetVal = pVT_R8_ARRAY; break;
case VT_BOOL|VT_ARRAY: pRetVal = pVT_BOOL_ARRAY; break;
case VT_BSTR|VT_ARRAY: pRetVal = pVT_BSTR_ARRAY; break;
case VT_DISPATCH|VT_ARRAY: pRetVal = pVT_DISPATCH_ARRAY; break;
case VT_UNKNOWN|VT_ARRAY: pRetVal = pVT_UNKNOWN_ARRAY; break;
default: pRetVal = L"<unknown>";
}
return pRetVal;
}
//*****************************************************************************
// Function: TypeToString
// Purpose: Takes a CIMTYPE, returns a pointer to a string that is the variant type
//*****************************************************************************
const WCHAR *TypeToString(CIMTYPE v)
{
const static WCHAR *pCIM_UNKNOWN = L"CIM_UNKNOWN";
const static WCHAR *pCIM_ILLEGAL = L"CIM_ILLEGAL";
const static WCHAR *pCIM_EMPTY = L"CIM_EMPTY";
const static WCHAR *pCIM_SINT8 = L"CIM_SINT8";
const static WCHAR *pCIM_UINT8 = L"CIM_UINT8";
const static WCHAR *pCIM_SINT16 = L"CIM_SINT16";
const static WCHAR *pCIM_UINT16 = L"CIM_UINT16";
const static WCHAR *pCIM_SINT32 = L"CIM_SINT32";
const static WCHAR *pCIM_UINT32 = L"CIM_UINT32";
const static WCHAR *pCIM_SINT64 = L"CIM_SINT64";
const static WCHAR *pCIM_UINT64 = L"CIM_UINT64";
const static WCHAR *pCIM_REAL32 = L"CIM_REAL32";
const static WCHAR *pCIM_REAL64 = L"CIM_REAL64";
const static WCHAR *pCIM_BOOLEAN = L"CIM_BOOLEAN";
const static WCHAR *pCIM_STRING = L"CIM_STRING";
const static WCHAR *pCIM_DATETIME = L"CIM_DATETIME";
const static WCHAR *pCIM_REFERENCE = L"CIM_REFERENCE";
const static WCHAR *pCIM_OBJECT = L"CIM_OBJECT";
const static WCHAR *pCIM_ILLEGAL_ARRAY = L"CIM_ILLEGAL | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_EMPTY_ARRAY = L"CIM_EMPTY | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_SINT8_ARRAY = L"CIM_SINT8 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_UINT8_ARRAY = L"CIM_UINT8 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_SINT16_ARRAY = L"CIM_SINT16 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_UINT16_ARRAY = L"CIM_UINT16 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_SINT32_ARRAY = L"CIM_SINT32 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_UINT32_ARRAY = L"CIM_UINT32 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_SINT64_ARRAY = L"CIM_SINT64 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_UINT64_ARRAY = L"CIM_UINT64 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_REAL32_ARRAY = L"CIM_REAL32 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_REAL64_ARRAY = L"CIM_REAL64 | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_BOOLEAN_ARRAY = L"CIM_BOOLEAN | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_STRING_ARRAY = L"CIM_STRING | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_DATETIME_ARRAY = L"CIM_DATETIME | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_REFERENCE_ARRAY = L"CIM_REFERENCE | CIM_FLAG_ARRAY";
const static WCHAR *pCIM_OBJECT_ARRAY = L"CIM_OBJECT | CIM_FLAG_ARRAY";
const WCHAR *pRetVal;
switch (v)
{
case CIM_ILLEGAL: pRetVal = pCIM_ILLEGAL; break;
case CIM_EMPTY: pRetVal = pCIM_EMPTY; break;
case CIM_SINT8: pRetVal = pCIM_SINT8; break;
case CIM_UINT8: pRetVal = pCIM_UINT8; break;
case CIM_SINT16: pRetVal = pCIM_SINT16; break;
case CIM_UINT16: pRetVal = pCIM_UINT16; break;
case CIM_SINT32: pRetVal = pCIM_SINT32; break;
case CIM_UINT32: pRetVal = pCIM_UINT32; break;
case CIM_SINT64: pRetVal = pCIM_SINT64; break;
case CIM_UINT64: pRetVal = pCIM_UINT64; break;
case CIM_REAL32: pRetVal = pCIM_REAL32; break;
case CIM_REAL64: pRetVal = pCIM_REAL64; break;
case CIM_BOOLEAN: pRetVal = pCIM_BOOLEAN; break;
case CIM_STRING: pRetVal = pCIM_STRING; break;
case CIM_DATETIME: pRetVal = pCIM_DATETIME; break;
case CIM_REFERENCE: pRetVal = pCIM_REFERENCE; break;
case CIM_OBJECT: pRetVal = pCIM_OBJECT; break;
case CIM_SINT8 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT8_ARRAY; break;
case CIM_UINT8 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT8_ARRAY; break;
case CIM_SINT16 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT16_ARRAY; break;
case CIM_UINT16 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT16_ARRAY; break;
case CIM_SINT32 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT32_ARRAY; break;
case CIM_UINT32 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT32_ARRAY; break;
case CIM_SINT64 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT64_ARRAY; break;
case CIM_UINT64 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT64_ARRAY; break;
case CIM_REAL32 | CIM_FLAG_ARRAY: pRetVal = pCIM_REAL32_ARRAY; break;
case CIM_REAL64 | CIM_FLAG_ARRAY: pRetVal = pCIM_REAL64_ARRAY; break;
case CIM_BOOLEAN | CIM_FLAG_ARRAY: pRetVal = pCIM_BOOLEAN_ARRAY; break;
case CIM_STRING | CIM_FLAG_ARRAY: pRetVal = pCIM_STRING_ARRAY; break;
case CIM_DATETIME | CIM_FLAG_ARRAY: pRetVal = pCIM_DATETIME_ARRAY; break;
case CIM_REFERENCE | CIM_FLAG_ARRAY: pRetVal = pCIM_REFERENCE_ARRAY; break;
case CIM_OBJECT | CIM_FLAG_ARRAY: pRetVal = pCIM_OBJECT_ARRAY; break;
default: pRetVal = pCIM_UNKNOWN; break;
}
return pRetVal;
}
//*****************************************************************************
// Function: ValueToString
// Purpose: Takes a variant, returns a string representation of that variant
//*****************************************************************************
WCHAR *ValueToString(CIMTYPE dwType, VARIANT *pValue, WCHAR **pbuf, WCHAR *fnHandler(VARIANT *pv))
{
DWORD iTotBufSize;
WCHAR *vbuf = NULL;
WCHAR *buf = NULL;
WCHAR lbuf[BLOCKSIZE];
switch (pValue->vt)
{
case VT_EMPTY:
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty>");
}
break;
}
case VT_NULL:
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<null>");
}
break;
}
case VT_BOOL:
{
VARIANT_BOOL b = pValue->boolVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
if (!b)
{
wcscpy(buf, L"FALSE");
}
else
{
wcscpy(buf, L"TRUE");
}
}
break;
}
case VT_I1:
{
char b = pValue->bVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
if (b >= 32)
{
swprintf(buf, L"'%c' (%hd, 0x%hX)", b, (signed char)b, b);
}
else
{
swprintf(buf, L"%hd (0x%hX)", (signed char)b, b);
}
}
break;
}
case VT_UI1:
{
unsigned char b = pValue->bVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
if (b >= 32)
{
swprintf(buf, L"'%c' (%hu, 0x%hX)", b, (unsigned char)b, b);
}
else
{
swprintf(buf, L"%hu (0x%hX)", (unsigned char)b, b);
}
}
break;
}
case VT_I2:
{
SHORT i = pValue->iVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
swprintf(buf, L"%hd (0x%hX)", i, i);
}
break;
}
case VT_UI2:
{
USHORT i = pValue->uiVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
swprintf(buf, L"%hu (0x%hX)", i, i);
}
break;
}
case VT_I4:
{
LONG l = pValue->lVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
swprintf(buf, L"%d (0x%X)", l, l);
}
break;
}
case VT_UI4:
{
ULONG l = pValue->ulVal;
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
swprintf(buf, L"%u (0x%X)", l, l);
}
break;
}
case VT_R4:
{
float f = pValue->fltVal;
buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
if (buf)
{
swprintf(buf, L"%10.4f", f);
}
break;
}
case VT_R8:
{
double d = pValue->dblVal;
buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
if (buf)
{
swprintf(buf, L"%10.4f", d);
}
break;
}
case VT_BSTR:
{
if (dwType == CIM_SINT64)
{
// a little redundant, but it makes me feel better
LPWSTR pWStr = pValue->bstrVal;
__int64 l = _wtoi64(pWStr);
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
swprintf(buf, L"%I64d", l, l);
}
}
else if (dwType == CIM_UINT64)
{
// a little redundant, but it makes me feel better
LPWSTR pWStr = pValue->bstrVal;
__int64 l = _wtoi64(pWStr);
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
swprintf(buf, L"%I64u", l, l);
}
}
else // string, datetime, reference
{
LPWSTR pWStr = pValue->bstrVal;
buf = (WCHAR *)malloc((wcslen(pWStr) * sizeof(WCHAR)) + sizeof(WCHAR) + (2 * sizeof(WCHAR)));
if (buf)
{
swprintf(buf, L"\"%wS\"", pWStr);
}
}
break;
}
case VT_BOOL|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
VARIANT_BOOL v;
SafeArrayGetElement(pVec, &i, &v);
if (v)
{
wcscat(buf, L"TRUE");
}
else
{
wcscat(buf, L"FALSE");
}
}
}
break;
}
case VT_I1|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
WCHAR *pos = buf;
DWORD len;
BYTE *pbstr;
SafeArrayAccessData(pVec, (void HUGEP* FAR*)&pbstr);
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscpy(pos, L",");
pos += 1;
}
else
{
bFirst = FALSE;
}
char v;
// SafeArrayGetElement(pVec, &i, &v);
v = pbstr[i];
if (v < 32)
{
len = swprintf(lbuf, L"%hd (0x%X)", v, v);
}
else
{
len = swprintf(lbuf, L"'%c' %hd (0x%X)", v, v, v);
}
wcscpy(pos, lbuf);
pos += len;
}
}
SafeArrayUnaccessData(pVec);
break;
}
case VT_UI1|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
WCHAR *pos = buf;
DWORD len;
BYTE *pbstr;
SafeArrayAccessData(pVec, (void HUGEP* FAR*)&pbstr);
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscpy(pos, L",");
pos += 1;
}
else
{
bFirst = FALSE;
}
unsigned char v;
// SafeArrayGetElement(pVec, &i, &v);
v = pbstr[i];
if (v < 32)
{
len = swprintf(lbuf, L"%hu (0x%X)", v, v);
}
else
{
len = swprintf(lbuf, L"'%c' %hu (0x%X)", v, v, v);
}
wcscpy(pos, lbuf);
pos += len;
}
}
SafeArrayUnaccessData(pVec);
break;
}
case VT_I2|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
SHORT v;
SafeArrayGetElement(pVec, &i, &v);
swprintf(lbuf, L"%hd", v);
wcscat(buf, lbuf);
}
}
break;
}
case VT_UI2|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
USHORT v;
SafeArrayGetElement(pVec, &i, &v);
swprintf(lbuf, L"%hu", v);
wcscat(buf, lbuf);
}
}
break;
}
case VT_I4|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
LONG v;
SafeArrayGetElement(pVec, &i, &v);
_ltow(v, lbuf, 10);
wcscat(buf, lbuf);
}
}
break;
}
case VT_UI4|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
ULONG v;
SafeArrayGetElement(pVec, &i, &v);
_ultow(v, lbuf, 10);
wcscat(buf, lbuf);
}
}
break;
}
case CIM_REAL32|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * (CVTBUFSIZE * sizeof(WCHAR)));
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
FLOAT v;
SafeArrayGetElement(pVec, &i, &v);
swprintf(lbuf, L"%10.4f", v);
wcscat(buf, lbuf);
}
}
break;
}
case CIM_REAL64|VT_ARRAY:
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * (CVTBUFSIZE * sizeof(WCHAR)));
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
double v;
SafeArrayGetElement(pVec, &i, &v);
swprintf(lbuf, L"%10.4f", v);
wcscat(buf, lbuf);
}
}
break;
}
case VT_BSTR|VT_ARRAY:
{
if (dwType == (CIM_UINT64|VT_ARRAY))
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
BSTR v = NULL;
SafeArrayGetElement(pVec, &i, &v);
swprintf(lbuf, L"%I64u", _wtoi64(v));
wcscat(buf, lbuf);
}
}
}
else if (dwType == (CIM_SINT64|VT_ARRAY))
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
BOOL bFirst = TRUE;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"");
for (long i = iLBound; i <= iUBound; i++)
{
if (!bFirst)
{
wcscat(buf, L",");
}
else
{
bFirst = FALSE;
}
BSTR v = NULL;
SafeArrayGetElement(pVec, &i, &v);
swprintf(lbuf, L"%I64d", _wtoi64(v));
wcscat(buf, lbuf);
}
}
}
else // string, datetime, reference
{
SAFEARRAY *pVec = pValue->parray;
long iLBound, iUBound;
DWORD iNeed;
size_t iVSize;
DWORD iCurBufSize;
SafeArrayGetLBound(pVec, 1, &iLBound);
SafeArrayGetUBound(pVec, 1, &iUBound);
if ((iUBound - iLBound + 1) == 0)
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<empty array>");
}
break;
}
iTotBufSize = (iUBound - iLBound + 1) * BLOCKSIZE;
buf = (WCHAR *)malloc(iTotBufSize);
if (buf)
{
buf[0] = L'\0';
iCurBufSize = 0;
iVSize = BLOCKSIZE;
vbuf = (WCHAR *)malloc(BLOCKSIZE);
if (vbuf)
{
size_t iLen;
for (long i = iLBound; i <= iUBound; i++)
{
BSTR v = NULL;
SafeArrayGetElement(pVec, &i, &v);
iLen = (wcslen(v) + 1) * sizeof(WCHAR);
if (iLen > iVSize)
{
WCHAR* pTmp = (WCHAR *)realloc(vbuf, iLen + sizeof(WCHAR));
if (pTmp)
{
vbuf = pTmp;
iVSize = iLen;
}
else
{
free(buf);
buf = NULL;
SysFreeString(v);
break;
}
}
// String size + (quotes + comma + null)
iNeed = (swprintf(vbuf, L"%wS", v) + 4) * sizeof(WCHAR);
if (iNeed + iCurBufSize > iTotBufSize)
{
iTotBufSize += (iNeed * 2); // Room enough for 2 more entries
WCHAR* pTmp = (WCHAR *)realloc(buf, iTotBufSize);
if (pTmp)
buf = pTmp;
else
{
free(buf);
buf = NULL;
SysFreeString(v);
break;
}
}
wcscat(buf, L"\"");
wcscat(buf, vbuf);
if (i + 1 <= iUBound)
{
wcscat(buf, L"\",");
}
else
{
wcscat(buf, L"\"");
}
iCurBufSize += iNeed;
SysFreeString(v);
}
free(vbuf);
}
}
}
break;
}
default:
{
if (fnHandler != NULL)
{
buf = fnHandler(pValue);
}
else
{
buf = (WCHAR *)malloc(BLOCKSIZE);
if (buf)
{
wcscpy(buf, L"<conversion error>");
}
}
break;
}
}
if (!buf)
{
PrintErrorAndExit("ValueToString() out of memory", S_OK, 0);
}
*pbuf = buf;
return buf;
}
//*****************************************************************************
// Function: cvt
// Purpose: Converts unicode to oem for console output
// Note: y must be freed by caller
//*****************************************************************************
char *cvt(WCHAR *x, char **y)
{
int dwRet, i;
i = WideCharToMultiByte( CP_OEMCP,
0,
x,
-1,
NULL,
0,
NULL,
NULL);
*y = (char *)calloc(i, 1);
if (*y)
{
dwRet = WideCharToMultiByte( CP_OEMCP,
0,
x,
-1,
*y,
i,
NULL,
NULL);
if (dwRet == 0)
{
free(*y);
*y = (char *)malloc(sizeof(CVTFAILED));
if (*y)
{
memcpy(*y, CVTFAILED, sizeof(CVTFAILED));
}
}
}
else
{
PrintErrorAndExit("cvt() out of memory", S_OK, 0);
}
return *y;
}
//*****************************************************************************
// Function: myWFPrintf
// Purpose: Checks to see if outputing to console and converts strings
// to oem if necessary.
// Note: Returns number of characters written (ie if we write 3 oem
// chars, it returns 3. If it writes 4 wchars, it returns 4).
//*****************************************************************************
int myFWPrintf(FILE *f, WCHAR *fmt, ...)
{
va_list argptr;
size_t i;
int iSize = PAGESIZE;
WCHAR *wszBuff = (WCHAR *)malloc(iSize);
if (wszBuff)
{
wszBuff[(iSize/2)-2] = 0xffff;
va_start(argptr, fmt); // Init variable arguments
// Format the string into a buffer. Make sure the buffer is big enough
while (_vsnwprintf(wszBuff, (iSize-1)/sizeof(WCHAR), fmt, argptr) == -1)
{
if (wszBuff[(iSize/2)-2] != 0xffff)
{
WCHAR* pTmp = (WCHAR *)realloc(wszBuff, iSize + PAGESIZE);
if (pTmp)
{
wszBuff = pTmp;
wszBuff[(iSize/2)-2] = 0xffff;
iSize += PAGESIZE;
}
else
{
wszBuff[(iSize/2)-2] = L'\0';
break;
}
}
else
{
// unfortunately, _vsnwprintf won't handle the unicode character
// 0xffff. Since this isn't actually a valid unicode character,
// we'll just ignore it.
wcscpy(wszBuff, L"String contains 0xffff\n");
break;
}
}
if (f == stdout)
{
char *z = NULL;
fputs(cvt(wszBuff,&z), f);
i = strlen(z);
free(z);
}
else
{
i = wcslen(wszBuff);
fwrite(wszBuff, i * sizeof(WCHAR), 1, f);
}
free(wszBuff);
}
else
{
if (f == stdout)
{
char *szBuff = "myFWPrintf() out of memory";
i = strlen(szBuff);
fputs(szBuff, f);
}
else
{
wszBuff = L"myFWPrintf() out of memory";
i = wcslen(wszBuff);
fwrite(wszBuff, i * sizeof(WCHAR), 1, f);
}
}
va_end(argptr);
return (int)i;
}
//*****************************************************************************
// Function: difftime
// Purpose: Returns the elapsed time between two _timeb structures
// Note: This is different from the crt routine which works on time_t
// structures.
//*****************************************************************************
double difftime(struct _timeb finish, struct _timeb start)
{
double dRet;
if (start.millitm > finish.millitm)
{
dRet = ((finish.time - start.time) - 1) + (double)(((1000 + finish.millitm) - start.millitm) / 1000.0);
}
else
{
dRet = (finish.time - start.time) + (double)((finish.millitm - start.millitm) / 1000.0);
}
return dRet;
}