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
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;
|
|
}
|