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

  1. // **************************************************************************
  2. // Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. // File: utils.cpp
  5. //
  6. // Description:
  7. // Set of sample routines
  8. //
  9. // History:
  10. //
  11. // **************************************************************************
  12. //#pragma warning(disable:4201) // nonstandard extension nameless struct (used in windows.h)
  13. //#pragma warning(disable:4514) // unreferenced inline function has been removed (used in windows.h)
  14. #include "precomp.h"
  15. #include <stdio.h>
  16. #include <wbemidl.h>
  17. #include <sys\timeb.h>
  18. #include "utillib.h"
  19. //*****************************************************************************
  20. // Function: WbemErrorString
  21. // Purpose: Turns sc into a text string
  22. //*****************************************************************************
  23. BSTR WbemErrorString(SCODE sc)
  24. {
  25. IWbemStatusCodeTextPtr pStatus;
  26. BSTR bstr = NULL;
  27. SCODE mysc = CoCreateInstance(CLSID_WbemStatusCodeText, 0, CLSCTX_INPROC_SERVER,
  28. IID_IWbemStatusCodeText, (LPVOID *) &pStatus);
  29. if (mysc == S_OK)
  30. {
  31. mysc = pStatus->GetErrorCodeText(sc, 0, 0, &bstr);
  32. if (mysc == S_OK)
  33. {
  34. }
  35. else
  36. {
  37. WCHAR szBuffer2[MAXITOA];
  38. WCHAR szBuffer[sizeof(szBuffer2) + 4];
  39. _ltow(sc, szBuffer2, 16);
  40. wcscpy(szBuffer, L"0x");
  41. wcscat(szBuffer, szBuffer2);
  42. bstr = SysAllocString(szBuffer);
  43. }
  44. }
  45. return bstr;
  46. }
  47. //***************************************************************************
  48. // Function: PrintError
  49. // Purpose: Formats and prints the error message
  50. //***************************************************************************
  51. void PrintError(char *pszFailureReason, SCODE psc, DWORD dwMode)
  52. {
  53. VARIANT varString;
  54. SCODE sc;
  55. IWbemClassObject *pErrorObject = NULL;
  56. IErrorInfo* pEI = NULL;
  57. fprintf(stdout, "%s\n", pszFailureReason);
  58. fprintf(stdout, "FunctionReturn: %S(0x%08lx)\n", WbemErrorString(psc), psc);
  59. if (GetErrorInfo(0, &pEI) == S_OK)
  60. {
  61. pEI->QueryInterface(IID_IWbemClassObject, (void**)&pErrorObject);
  62. pEI->Release();
  63. }
  64. if (pErrorObject != NULL)
  65. {
  66. VariantInit(&varString);
  67. if (dwMode == ERROR_MODE_PRINTFIELDS)
  68. {
  69. if (pErrorObject->InheritsFrom(L"__NotifyStatus") != WBEM_NO_ERROR)
  70. {
  71. fprintf(stdout, "Unrecognized Error Object type\n");
  72. }
  73. else if (pErrorObject->InheritsFrom(L"__ExtendedStatus") == WBEM_NO_ERROR)
  74. {
  75. sc = pErrorObject->Get(L"Description", 0L, &varString, NULL, NULL);
  76. if (sc != S_OK)
  77. {
  78. fprintf(stdout, "Can't get Description: %d\n", sc);
  79. }
  80. else if (V_VT(&varString) == VT_BSTR)
  81. {
  82. FWPRINTF(stdout, L"Description: %wS\n", V_BSTR(&varString));
  83. }
  84. VariantClear(&varString);
  85. pErrorObject->Get(L"Operation", 0L, &varString, NULL, NULL);
  86. if (sc != S_OK)
  87. {
  88. fprintf(stdout, "Can't get Operation: %d\n", sc);
  89. }
  90. else if (V_VT(&varString) == VT_BSTR)
  91. {
  92. FWPRINTF(stdout, L"Operation: %wS\n", V_BSTR(&varString));
  93. }
  94. VariantClear(&varString);
  95. pErrorObject->Get(L"ParameterInfo", 0L, &varString, NULL, NULL);
  96. if (sc != S_OK)
  97. {
  98. fprintf(stdout, "Can't get ParameterInfo: %d\n", sc);
  99. }
  100. else if (V_VT(&varString) == VT_BSTR)
  101. {
  102. FWPRINTF(stdout, L"ParameterInfo: %wS\n", V_BSTR(&varString));
  103. }
  104. VariantClear(&varString);
  105. pErrorObject->Get(L"ProviderName", 0L, &varString, NULL, NULL);
  106. if (sc != S_OK)
  107. {
  108. fprintf(stdout, "Can't get ProviderName: %d\n", sc);
  109. }
  110. else if (V_VT(&varString) == VT_BSTR)
  111. {
  112. FWPRINTF(stdout, L"ProviderName: %wS\n", V_BSTR(&varString));
  113. }
  114. VariantClear(&varString);
  115. }
  116. }
  117. else
  118. {
  119. BSTR bstrObjectText = NULL;
  120. if (SUCCEEDED(pErrorObject->GetObjectText(0, &bstrObjectText)))
  121. {
  122. fprintf(stdout, "%wS", bstrObjectText);
  123. SysFreeString(bstrObjectText);
  124. }
  125. }
  126. RELEASE(pErrorObject);
  127. }
  128. }
  129. //***************************************************************************
  130. // Function: PrintErrorAndExit
  131. // Purpose: Formats an error message & exits program
  132. //***************************************************************************
  133. void PrintErrorAndExit(char *pszFailureReason, SCODE sc, DWORD dwMode)
  134. {
  135. PrintError(pszFailureReason, sc, dwMode);
  136. // Clean up and exit
  137. OleUninitialize();
  138. printf("Abnormal Termination\n");
  139. exit(1);
  140. };
  141. //***************************************************************************
  142. // Function: PrintErrorAndAsk
  143. // Purpose: Prints the error message and prompts to continue
  144. //***************************************************************************
  145. void PrintErrorAndAsk(char *pszFailureReason, SCODE sc, DWORD dwMode)
  146. {
  147. int c;
  148. PrintError(pszFailureReason, sc, dwMode);
  149. printf("Continue (Y/N)? ");
  150. c = getchar();
  151. while (getchar() != '\n')
  152. {
  153. }
  154. if ((c != 'Y') && (c != 'y'))
  155. {
  156. // Clean up and exit
  157. OleUninitialize();
  158. exit(1);
  159. }
  160. };
  161. //*****************************************************************************
  162. // Function: TypeToString
  163. // Purpose: Takes a variant, returns a pointer to a string that is the variant type
  164. //*****************************************************************************
  165. const WCHAR *TypeToString(VARIANT *p)
  166. {
  167. return TypeToString(p->vt);
  168. }
  169. //*****************************************************************************
  170. // Function: TypeToString
  171. // Purpose: Takes a VARTYPE, returns a pointer to a string that is the variant type
  172. //*****************************************************************************
  173. const WCHAR *TypeToString(VARTYPE v)
  174. {
  175. const static WCHAR *pVT_NULL = L"VT_NULL";
  176. const static WCHAR *pVT_EMTPY = L"VT_EMPTY";
  177. const static WCHAR *pVT_I1 = L"VT_I1";
  178. const static WCHAR *pVT_UI1 = L"VT_UI1";
  179. const static WCHAR *pVT_I2 = L"VT_I2";
  180. const static WCHAR *pVT_UI2 = L"VT_UI2";
  181. const static WCHAR *pVT_I4 = L"VT_I4";
  182. const static WCHAR *pVT_UI4 = L"VT_UI4";
  183. const static WCHAR *pVT_I8 = L"VT_I8";
  184. const static WCHAR *pVT_UI8 = L"VT_UI8";
  185. const static WCHAR *pVT_R4 = L"VT_R4";
  186. const static WCHAR *pVT_R8 = L"VT_R8";
  187. const static WCHAR *pVT_BOOL = L"VT_BOOL";
  188. const static WCHAR *pVT_BSTR = L"VT_BSTR";
  189. const static WCHAR *pVT_DISPATCH = L"VT_DISPATCH";
  190. const static WCHAR *pVT_UNKNOWN = L"VT_UNKNOWN";
  191. const static WCHAR *pVT_I1_ARRAY = L"VT_I1 | VT_ARRAY";
  192. const static WCHAR *pVT_UI1_ARRAY = L"VT_UI1 | VT_ARRAY";
  193. const static WCHAR *pVT_I2_ARRAY = L"VT_I2 | VT_ARRAY";
  194. const static WCHAR *pVT_UI2_ARRAY = L"VT_UI2 | VT_ARRAY";
  195. const static WCHAR *pVT_I4_ARRAY = L"VT_I4 | VT_ARRAY";
  196. const static WCHAR *pVT_UI4_ARRAY = L"VT_UI4 | VT_ARRAY";
  197. const static WCHAR *pVT_I8_ARRAY = L"VT_I8 | VT_ARRAY";
  198. const static WCHAR *pVT_UI8_ARRAY = L"VT_UI8 | VT_ARRAY";
  199. const static WCHAR *pVT_R4_ARRAY = L"VT_R4 | VT_ARRAY";
  200. const static WCHAR *pVT_R8_ARRAY = L"VT_R8 | VT_ARRAY";
  201. const static WCHAR *pVT_BOOL_ARRAY = L"VT_BOOL | VT_ARRAY";
  202. const static WCHAR *pVT_BSTR_ARRAY = L"VT_BSTR | VT_ARRAY";
  203. const static WCHAR *pVT_DISPATCH_ARRAY = L"VT_DISPATCH | VT_ARRAY";
  204. const static WCHAR *pVT_UNKNOWN_ARRAY = L"VT_UNKNOWN | VT_ARRAY";
  205. const WCHAR *pRetVal;
  206. switch (v)
  207. {
  208. case VT_NULL: pRetVal = pVT_NULL; break;
  209. case VT_I1: pRetVal = pVT_I1; break;
  210. case VT_UI1: pRetVal = pVT_UI1; break;
  211. case VT_I2: pRetVal = pVT_I2; break;
  212. case VT_UI2: pRetVal = pVT_UI2; break;
  213. case VT_I4: pRetVal = pVT_I4; break;
  214. case VT_UI4: pRetVal = pVT_UI4; break;
  215. case VT_I8: pRetVal = pVT_I8; break;
  216. case VT_UI8: pRetVal = pVT_UI8; break;
  217. case VT_R4: pRetVal = pVT_R4; break;
  218. case VT_R8: pRetVal = pVT_R8; break;
  219. case VT_BOOL: pRetVal = pVT_BOOL; break;
  220. case VT_BSTR: pRetVal = pVT_BSTR; break;
  221. case VT_DISPATCH: pRetVal = pVT_DISPATCH; break;
  222. case VT_UNKNOWN: pRetVal = pVT_UNKNOWN; break;
  223. case VT_I1|VT_ARRAY: pRetVal = pVT_I1_ARRAY; break;
  224. case VT_UI1|VT_ARRAY: pRetVal = pVT_UI1_ARRAY; break;
  225. case VT_I2|VT_ARRAY: pRetVal = pVT_I2_ARRAY; break;
  226. case VT_UI2|VT_ARRAY: pRetVal = pVT_UI2_ARRAY; break;
  227. case VT_I4|VT_ARRAY: pRetVal = pVT_I4_ARRAY; break;
  228. case VT_UI4|VT_ARRAY: pRetVal = pVT_UI4_ARRAY; break;
  229. case VT_I8|VT_ARRAY: pRetVal = pVT_I8_ARRAY; break;
  230. case VT_UI8|VT_ARRAY: pRetVal = pVT_UI8_ARRAY; break;
  231. case VT_R4|VT_ARRAY: pRetVal = pVT_R4_ARRAY; break;
  232. case VT_R8|VT_ARRAY: pRetVal = pVT_R8_ARRAY; break;
  233. case VT_BOOL|VT_ARRAY: pRetVal = pVT_BOOL_ARRAY; break;
  234. case VT_BSTR|VT_ARRAY: pRetVal = pVT_BSTR_ARRAY; break;
  235. case VT_DISPATCH|VT_ARRAY: pRetVal = pVT_DISPATCH_ARRAY; break;
  236. case VT_UNKNOWN|VT_ARRAY: pRetVal = pVT_UNKNOWN_ARRAY; break;
  237. default: pRetVal = L"<unknown>";
  238. }
  239. return pRetVal;
  240. }
  241. //*****************************************************************************
  242. // Function: TypeToString
  243. // Purpose: Takes a CIMTYPE, returns a pointer to a string that is the variant type
  244. //*****************************************************************************
  245. const WCHAR *TypeToString(CIMTYPE v)
  246. {
  247. const static WCHAR *pCIM_UNKNOWN = L"CIM_UNKNOWN";
  248. const static WCHAR *pCIM_ILLEGAL = L"CIM_ILLEGAL";
  249. const static WCHAR *pCIM_EMPTY = L"CIM_EMPTY";
  250. const static WCHAR *pCIM_SINT8 = L"CIM_SINT8";
  251. const static WCHAR *pCIM_UINT8 = L"CIM_UINT8";
  252. const static WCHAR *pCIM_SINT16 = L"CIM_SINT16";
  253. const static WCHAR *pCIM_UINT16 = L"CIM_UINT16";
  254. const static WCHAR *pCIM_SINT32 = L"CIM_SINT32";
  255. const static WCHAR *pCIM_UINT32 = L"CIM_UINT32";
  256. const static WCHAR *pCIM_SINT64 = L"CIM_SINT64";
  257. const static WCHAR *pCIM_UINT64 = L"CIM_UINT64";
  258. const static WCHAR *pCIM_REAL32 = L"CIM_REAL32";
  259. const static WCHAR *pCIM_REAL64 = L"CIM_REAL64";
  260. const static WCHAR *pCIM_BOOLEAN = L"CIM_BOOLEAN";
  261. const static WCHAR *pCIM_STRING = L"CIM_STRING";
  262. const static WCHAR *pCIM_DATETIME = L"CIM_DATETIME";
  263. const static WCHAR *pCIM_REFERENCE = L"CIM_REFERENCE";
  264. const static WCHAR *pCIM_OBJECT = L"CIM_OBJECT";
  265. const static WCHAR *pCIM_ILLEGAL_ARRAY = L"CIM_ILLEGAL | CIM_FLAG_ARRAY";
  266. const static WCHAR *pCIM_EMPTY_ARRAY = L"CIM_EMPTY | CIM_FLAG_ARRAY";
  267. const static WCHAR *pCIM_SINT8_ARRAY = L"CIM_SINT8 | CIM_FLAG_ARRAY";
  268. const static WCHAR *pCIM_UINT8_ARRAY = L"CIM_UINT8 | CIM_FLAG_ARRAY";
  269. const static WCHAR *pCIM_SINT16_ARRAY = L"CIM_SINT16 | CIM_FLAG_ARRAY";
  270. const static WCHAR *pCIM_UINT16_ARRAY = L"CIM_UINT16 | CIM_FLAG_ARRAY";
  271. const static WCHAR *pCIM_SINT32_ARRAY = L"CIM_SINT32 | CIM_FLAG_ARRAY";
  272. const static WCHAR *pCIM_UINT32_ARRAY = L"CIM_UINT32 | CIM_FLAG_ARRAY";
  273. const static WCHAR *pCIM_SINT64_ARRAY = L"CIM_SINT64 | CIM_FLAG_ARRAY";
  274. const static WCHAR *pCIM_UINT64_ARRAY = L"CIM_UINT64 | CIM_FLAG_ARRAY";
  275. const static WCHAR *pCIM_REAL32_ARRAY = L"CIM_REAL32 | CIM_FLAG_ARRAY";
  276. const static WCHAR *pCIM_REAL64_ARRAY = L"CIM_REAL64 | CIM_FLAG_ARRAY";
  277. const static WCHAR *pCIM_BOOLEAN_ARRAY = L"CIM_BOOLEAN | CIM_FLAG_ARRAY";
  278. const static WCHAR *pCIM_STRING_ARRAY = L"CIM_STRING | CIM_FLAG_ARRAY";
  279. const static WCHAR *pCIM_DATETIME_ARRAY = L"CIM_DATETIME | CIM_FLAG_ARRAY";
  280. const static WCHAR *pCIM_REFERENCE_ARRAY = L"CIM_REFERENCE | CIM_FLAG_ARRAY";
  281. const static WCHAR *pCIM_OBJECT_ARRAY = L"CIM_OBJECT | CIM_FLAG_ARRAY";
  282. const WCHAR *pRetVal;
  283. switch (v)
  284. {
  285. case CIM_ILLEGAL: pRetVal = pCIM_ILLEGAL; break;
  286. case CIM_EMPTY: pRetVal = pCIM_EMPTY; break;
  287. case CIM_SINT8: pRetVal = pCIM_SINT8; break;
  288. case CIM_UINT8: pRetVal = pCIM_UINT8; break;
  289. case CIM_SINT16: pRetVal = pCIM_SINT16; break;
  290. case CIM_UINT16: pRetVal = pCIM_UINT16; break;
  291. case CIM_SINT32: pRetVal = pCIM_SINT32; break;
  292. case CIM_UINT32: pRetVal = pCIM_UINT32; break;
  293. case CIM_SINT64: pRetVal = pCIM_SINT64; break;
  294. case CIM_UINT64: pRetVal = pCIM_UINT64; break;
  295. case CIM_REAL32: pRetVal = pCIM_REAL32; break;
  296. case CIM_REAL64: pRetVal = pCIM_REAL64; break;
  297. case CIM_BOOLEAN: pRetVal = pCIM_BOOLEAN; break;
  298. case CIM_STRING: pRetVal = pCIM_STRING; break;
  299. case CIM_DATETIME: pRetVal = pCIM_DATETIME; break;
  300. case CIM_REFERENCE: pRetVal = pCIM_REFERENCE; break;
  301. case CIM_OBJECT: pRetVal = pCIM_OBJECT; break;
  302. case CIM_SINT8 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT8_ARRAY; break;
  303. case CIM_UINT8 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT8_ARRAY; break;
  304. case CIM_SINT16 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT16_ARRAY; break;
  305. case CIM_UINT16 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT16_ARRAY; break;
  306. case CIM_SINT32 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT32_ARRAY; break;
  307. case CIM_UINT32 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT32_ARRAY; break;
  308. case CIM_SINT64 | CIM_FLAG_ARRAY: pRetVal = pCIM_SINT64_ARRAY; break;
  309. case CIM_UINT64 | CIM_FLAG_ARRAY: pRetVal = pCIM_UINT64_ARRAY; break;
  310. case CIM_REAL32 | CIM_FLAG_ARRAY: pRetVal = pCIM_REAL32_ARRAY; break;
  311. case CIM_REAL64 | CIM_FLAG_ARRAY: pRetVal = pCIM_REAL64_ARRAY; break;
  312. case CIM_BOOLEAN | CIM_FLAG_ARRAY: pRetVal = pCIM_BOOLEAN_ARRAY; break;
  313. case CIM_STRING | CIM_FLAG_ARRAY: pRetVal = pCIM_STRING_ARRAY; break;
  314. case CIM_DATETIME | CIM_FLAG_ARRAY: pRetVal = pCIM_DATETIME_ARRAY; break;
  315. case CIM_REFERENCE | CIM_FLAG_ARRAY: pRetVal = pCIM_REFERENCE_ARRAY; break;
  316. case CIM_OBJECT | CIM_FLAG_ARRAY: pRetVal = pCIM_OBJECT_ARRAY; break;
  317. default: pRetVal = pCIM_UNKNOWN; break;
  318. }
  319. return pRetVal;
  320. }
  321. //*****************************************************************************
  322. // Function: ValueToString
  323. // Purpose: Takes a variant, returns a string representation of that variant
  324. //*****************************************************************************
  325. WCHAR *ValueToString(CIMTYPE dwType, VARIANT *pValue, WCHAR **pbuf, WCHAR *fnHandler(VARIANT *pv))
  326. {
  327. DWORD iTotBufSize;
  328. WCHAR *vbuf = NULL;
  329. WCHAR *buf = NULL;
  330. WCHAR lbuf[BLOCKSIZE];
  331. switch (pValue->vt)
  332. {
  333. case VT_EMPTY:
  334. {
  335. buf = (WCHAR *)malloc(BLOCKSIZE);
  336. if (buf)
  337. {
  338. wcscpy(buf, L"<empty>");
  339. }
  340. break;
  341. }
  342. case VT_NULL:
  343. {
  344. buf = (WCHAR *)malloc(BLOCKSIZE);
  345. if (buf)
  346. {
  347. wcscpy(buf, L"<null>");
  348. }
  349. break;
  350. }
  351. case VT_BOOL:
  352. {
  353. VARIANT_BOOL b = pValue->boolVal;
  354. buf = (WCHAR *)malloc(BLOCKSIZE);
  355. if (buf)
  356. {
  357. if (!b)
  358. {
  359. wcscpy(buf, L"FALSE");
  360. }
  361. else
  362. {
  363. wcscpy(buf, L"TRUE");
  364. }
  365. }
  366. break;
  367. }
  368. case VT_I1:
  369. {
  370. char b = pValue->bVal;
  371. buf = (WCHAR *)malloc(BLOCKSIZE);
  372. if (buf)
  373. {
  374. if (b >= 32)
  375. {
  376. swprintf(buf, L"'%c' (%hd, 0x%hX)", b, (signed char)b, b);
  377. }
  378. else
  379. {
  380. swprintf(buf, L"%hd (0x%hX)", (signed char)b, b);
  381. }
  382. }
  383. break;
  384. }
  385. case VT_UI1:
  386. {
  387. unsigned char b = pValue->bVal;
  388. buf = (WCHAR *)malloc(BLOCKSIZE);
  389. if (buf)
  390. {
  391. if (b >= 32)
  392. {
  393. swprintf(buf, L"'%c' (%hu, 0x%hX)", b, (unsigned char)b, b);
  394. }
  395. else
  396. {
  397. swprintf(buf, L"%hu (0x%hX)", (unsigned char)b, b);
  398. }
  399. }
  400. break;
  401. }
  402. case VT_I2:
  403. {
  404. SHORT i = pValue->iVal;
  405. buf = (WCHAR *)malloc(BLOCKSIZE);
  406. if (buf)
  407. {
  408. swprintf(buf, L"%hd (0x%hX)", i, i);
  409. }
  410. break;
  411. }
  412. case VT_UI2:
  413. {
  414. USHORT i = pValue->uiVal;
  415. buf = (WCHAR *)malloc(BLOCKSIZE);
  416. if (buf)
  417. {
  418. swprintf(buf, L"%hu (0x%hX)", i, i);
  419. }
  420. break;
  421. }
  422. case VT_I4:
  423. {
  424. LONG l = pValue->lVal;
  425. buf = (WCHAR *)malloc(BLOCKSIZE);
  426. if (buf)
  427. {
  428. swprintf(buf, L"%d (0x%X)", l, l);
  429. }
  430. break;
  431. }
  432. case VT_UI4:
  433. {
  434. ULONG l = pValue->ulVal;
  435. buf = (WCHAR *)malloc(BLOCKSIZE);
  436. if (buf)
  437. {
  438. swprintf(buf, L"%u (0x%X)", l, l);
  439. }
  440. break;
  441. }
  442. case VT_R4:
  443. {
  444. float f = pValue->fltVal;
  445. buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
  446. if (buf)
  447. {
  448. swprintf(buf, L"%10.4f", f);
  449. }
  450. break;
  451. }
  452. case VT_R8:
  453. {
  454. double d = pValue->dblVal;
  455. buf = (WCHAR *)malloc(CVTBUFSIZE * sizeof(WCHAR));
  456. if (buf)
  457. {
  458. swprintf(buf, L"%10.4f", d);
  459. }
  460. break;
  461. }
  462. case VT_BSTR:
  463. {
  464. if (dwType == CIM_SINT64)
  465. {
  466. // a little redundant, but it makes me feel better
  467. LPWSTR pWStr = pValue->bstrVal;
  468. __int64 l = _wtoi64(pWStr);
  469. buf = (WCHAR *)malloc(BLOCKSIZE);
  470. if (buf)
  471. {
  472. swprintf(buf, L"%I64d", l, l);
  473. }
  474. }
  475. else if (dwType == CIM_UINT64)
  476. {
  477. // a little redundant, but it makes me feel better
  478. LPWSTR pWStr = pValue->bstrVal;
  479. __int64 l = _wtoi64(pWStr);
  480. buf = (WCHAR *)malloc(BLOCKSIZE);
  481. if (buf)
  482. {
  483. swprintf(buf, L"%I64u", l, l);
  484. }
  485. }
  486. else // string, datetime, reference
  487. {
  488. LPWSTR pWStr = pValue->bstrVal;
  489. buf = (WCHAR *)malloc((wcslen(pWStr) * sizeof(WCHAR)) + sizeof(WCHAR) + (2 * sizeof(WCHAR)));
  490. if (buf)
  491. {
  492. swprintf(buf, L"\"%wS\"", pWStr);
  493. }
  494. }
  495. break;
  496. }
  497. case VT_BOOL|VT_ARRAY:
  498. {
  499. SAFEARRAY *pVec = pValue->parray;
  500. long iLBound, iUBound;
  501. BOOL bFirst = TRUE;
  502. SafeArrayGetLBound(pVec, 1, &iLBound);
  503. SafeArrayGetUBound(pVec, 1, &iUBound);
  504. if ((iUBound - iLBound + 1) == 0)
  505. {
  506. buf = (WCHAR *)malloc(BLOCKSIZE);
  507. if (buf)
  508. {
  509. wcscpy(buf, L"<empty array>");
  510. }
  511. break;
  512. }
  513. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  514. if (buf)
  515. {
  516. wcscpy(buf, L"");
  517. for (long i = iLBound; i <= iUBound; i++)
  518. {
  519. if (!bFirst)
  520. {
  521. wcscat(buf, L",");
  522. }
  523. else
  524. {
  525. bFirst = FALSE;
  526. }
  527. VARIANT_BOOL v;
  528. SafeArrayGetElement(pVec, &i, &v);
  529. if (v)
  530. {
  531. wcscat(buf, L"TRUE");
  532. }
  533. else
  534. {
  535. wcscat(buf, L"FALSE");
  536. }
  537. }
  538. }
  539. break;
  540. }
  541. case VT_I1|VT_ARRAY:
  542. {
  543. SAFEARRAY *pVec = pValue->parray;
  544. long iLBound, iUBound;
  545. BOOL bFirst = TRUE;
  546. SafeArrayGetLBound(pVec, 1, &iLBound);
  547. SafeArrayGetUBound(pVec, 1, &iUBound);
  548. if ((iUBound - iLBound + 1) == 0)
  549. {
  550. buf = (WCHAR *)malloc(BLOCKSIZE);
  551. if (buf)
  552. {
  553. wcscpy(buf, L"<empty array>");
  554. }
  555. break;
  556. }
  557. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  558. if (buf)
  559. {
  560. wcscpy(buf, L"");
  561. WCHAR *pos = buf;
  562. DWORD len;
  563. BYTE *pbstr;
  564. SafeArrayAccessData(pVec, (void HUGEP* FAR*)&pbstr);
  565. for (long i = iLBound; i <= iUBound; i++)
  566. {
  567. if (!bFirst)
  568. {
  569. wcscpy(pos, L",");
  570. pos += 1;
  571. }
  572. else
  573. {
  574. bFirst = FALSE;
  575. }
  576. char v;
  577. // SafeArrayGetElement(pVec, &i, &v);
  578. v = pbstr[i];
  579. if (v < 32)
  580. {
  581. len = swprintf(lbuf, L"%hd (0x%X)", v, v);
  582. }
  583. else
  584. {
  585. len = swprintf(lbuf, L"'%c' %hd (0x%X)", v, v, v);
  586. }
  587. wcscpy(pos, lbuf);
  588. pos += len;
  589. }
  590. }
  591. SafeArrayUnaccessData(pVec);
  592. break;
  593. }
  594. case VT_UI1|VT_ARRAY:
  595. {
  596. SAFEARRAY *pVec = pValue->parray;
  597. long iLBound, iUBound;
  598. BOOL bFirst = TRUE;
  599. SafeArrayGetLBound(pVec, 1, &iLBound);
  600. SafeArrayGetUBound(pVec, 1, &iUBound);
  601. if ((iUBound - iLBound + 1) == 0)
  602. {
  603. buf = (WCHAR *)malloc(BLOCKSIZE);
  604. if (buf)
  605. {
  606. wcscpy(buf, L"<empty array>");
  607. }
  608. break;
  609. }
  610. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  611. if (buf)
  612. {
  613. wcscpy(buf, L"");
  614. WCHAR *pos = buf;
  615. DWORD len;
  616. BYTE *pbstr;
  617. SafeArrayAccessData(pVec, (void HUGEP* FAR*)&pbstr);
  618. for (long i = iLBound; i <= iUBound; i++)
  619. {
  620. if (!bFirst)
  621. {
  622. wcscpy(pos, L",");
  623. pos += 1;
  624. }
  625. else
  626. {
  627. bFirst = FALSE;
  628. }
  629. unsigned char v;
  630. // SafeArrayGetElement(pVec, &i, &v);
  631. v = pbstr[i];
  632. if (v < 32)
  633. {
  634. len = swprintf(lbuf, L"%hu (0x%X)", v, v);
  635. }
  636. else
  637. {
  638. len = swprintf(lbuf, L"'%c' %hu (0x%X)", v, v, v);
  639. }
  640. wcscpy(pos, lbuf);
  641. pos += len;
  642. }
  643. }
  644. SafeArrayUnaccessData(pVec);
  645. break;
  646. }
  647. case VT_I2|VT_ARRAY:
  648. {
  649. SAFEARRAY *pVec = pValue->parray;
  650. long iLBound, iUBound;
  651. BOOL bFirst = TRUE;
  652. SafeArrayGetLBound(pVec, 1, &iLBound);
  653. SafeArrayGetUBound(pVec, 1, &iUBound);
  654. if ((iUBound - iLBound + 1) == 0)
  655. {
  656. buf = (WCHAR *)malloc(BLOCKSIZE);
  657. if (buf)
  658. {
  659. wcscpy(buf, L"<empty array>");
  660. }
  661. break;
  662. }
  663. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  664. if (buf)
  665. {
  666. wcscpy(buf, L"");
  667. for (long i = iLBound; i <= iUBound; i++)
  668. {
  669. if (!bFirst)
  670. {
  671. wcscat(buf, L",");
  672. }
  673. else
  674. {
  675. bFirst = FALSE;
  676. }
  677. SHORT v;
  678. SafeArrayGetElement(pVec, &i, &v);
  679. swprintf(lbuf, L"%hd", v);
  680. wcscat(buf, lbuf);
  681. }
  682. }
  683. break;
  684. }
  685. case VT_UI2|VT_ARRAY:
  686. {
  687. SAFEARRAY *pVec = pValue->parray;
  688. long iLBound, iUBound;
  689. BOOL bFirst = TRUE;
  690. SafeArrayGetLBound(pVec, 1, &iLBound);
  691. SafeArrayGetUBound(pVec, 1, &iUBound);
  692. if ((iUBound - iLBound + 1) == 0)
  693. {
  694. buf = (WCHAR *)malloc(BLOCKSIZE);
  695. if (buf)
  696. {
  697. wcscpy(buf, L"<empty array>");
  698. }
  699. break;
  700. }
  701. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  702. if (buf)
  703. {
  704. wcscpy(buf, L"");
  705. for (long i = iLBound; i <= iUBound; i++)
  706. {
  707. if (!bFirst)
  708. {
  709. wcscat(buf, L",");
  710. }
  711. else
  712. {
  713. bFirst = FALSE;
  714. }
  715. USHORT v;
  716. SafeArrayGetElement(pVec, &i, &v);
  717. swprintf(lbuf, L"%hu", v);
  718. wcscat(buf, lbuf);
  719. }
  720. }
  721. break;
  722. }
  723. case VT_I4|VT_ARRAY:
  724. {
  725. SAFEARRAY *pVec = pValue->parray;
  726. long iLBound, iUBound;
  727. BOOL bFirst = TRUE;
  728. SafeArrayGetLBound(pVec, 1, &iLBound);
  729. SafeArrayGetUBound(pVec, 1, &iUBound);
  730. if ((iUBound - iLBound + 1) == 0)
  731. {
  732. buf = (WCHAR *)malloc(BLOCKSIZE);
  733. if (buf)
  734. {
  735. wcscpy(buf, L"<empty array>");
  736. }
  737. break;
  738. }
  739. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  740. if (buf)
  741. {
  742. wcscpy(buf, L"");
  743. for (long i = iLBound; i <= iUBound; i++)
  744. {
  745. if (!bFirst)
  746. {
  747. wcscat(buf, L",");
  748. }
  749. else
  750. {
  751. bFirst = FALSE;
  752. }
  753. LONG v;
  754. SafeArrayGetElement(pVec, &i, &v);
  755. _ltow(v, lbuf, 10);
  756. wcscat(buf, lbuf);
  757. }
  758. }
  759. break;
  760. }
  761. case VT_UI4|VT_ARRAY:
  762. {
  763. SAFEARRAY *pVec = pValue->parray;
  764. long iLBound, iUBound;
  765. BOOL bFirst = TRUE;
  766. SafeArrayGetLBound(pVec, 1, &iLBound);
  767. SafeArrayGetUBound(pVec, 1, &iUBound);
  768. if ((iUBound - iLBound + 1) == 0)
  769. {
  770. buf = (WCHAR *)malloc(BLOCKSIZE);
  771. if (buf)
  772. {
  773. wcscpy(buf, L"<empty array>");
  774. }
  775. break;
  776. }
  777. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  778. if (buf)
  779. {
  780. wcscpy(buf, L"");
  781. for (long i = iLBound; i <= iUBound; i++)
  782. {
  783. if (!bFirst)
  784. {
  785. wcscat(buf, L",");
  786. }
  787. else
  788. {
  789. bFirst = FALSE;
  790. }
  791. ULONG v;
  792. SafeArrayGetElement(pVec, &i, &v);
  793. _ultow(v, lbuf, 10);
  794. wcscat(buf, lbuf);
  795. }
  796. }
  797. break;
  798. }
  799. case CIM_REAL32|VT_ARRAY:
  800. {
  801. SAFEARRAY *pVec = pValue->parray;
  802. long iLBound, iUBound;
  803. BOOL bFirst = TRUE;
  804. SafeArrayGetLBound(pVec, 1, &iLBound);
  805. SafeArrayGetUBound(pVec, 1, &iUBound);
  806. if ((iUBound - iLBound + 1) == 0)
  807. {
  808. buf = (WCHAR *)malloc(BLOCKSIZE);
  809. if (buf)
  810. {
  811. wcscpy(buf, L"<empty array>");
  812. }
  813. break;
  814. }
  815. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * (CVTBUFSIZE * sizeof(WCHAR)));
  816. if (buf)
  817. {
  818. wcscpy(buf, L"");
  819. for (long i = iLBound; i <= iUBound; i++)
  820. {
  821. if (!bFirst)
  822. {
  823. wcscat(buf, L",");
  824. }
  825. else
  826. {
  827. bFirst = FALSE;
  828. }
  829. FLOAT v;
  830. SafeArrayGetElement(pVec, &i, &v);
  831. swprintf(lbuf, L"%10.4f", v);
  832. wcscat(buf, lbuf);
  833. }
  834. }
  835. break;
  836. }
  837. case CIM_REAL64|VT_ARRAY:
  838. {
  839. SAFEARRAY *pVec = pValue->parray;
  840. long iLBound, iUBound;
  841. BOOL bFirst = TRUE;
  842. SafeArrayGetLBound(pVec, 1, &iLBound);
  843. SafeArrayGetUBound(pVec, 1, &iUBound);
  844. if ((iUBound - iLBound + 1) == 0)
  845. {
  846. buf = (WCHAR *)malloc(BLOCKSIZE);
  847. if (buf)
  848. {
  849. wcscpy(buf, L"<empty array>");
  850. }
  851. break;
  852. }
  853. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * (CVTBUFSIZE * sizeof(WCHAR)));
  854. if (buf)
  855. {
  856. wcscpy(buf, L"");
  857. for (long i = iLBound; i <= iUBound; i++)
  858. {
  859. if (!bFirst)
  860. {
  861. wcscat(buf, L",");
  862. }
  863. else
  864. {
  865. bFirst = FALSE;
  866. }
  867. double v;
  868. SafeArrayGetElement(pVec, &i, &v);
  869. swprintf(lbuf, L"%10.4f", v);
  870. wcscat(buf, lbuf);
  871. }
  872. }
  873. break;
  874. }
  875. case VT_BSTR|VT_ARRAY:
  876. {
  877. if (dwType == (CIM_UINT64|VT_ARRAY))
  878. {
  879. SAFEARRAY *pVec = pValue->parray;
  880. long iLBound, iUBound;
  881. BOOL bFirst = TRUE;
  882. SafeArrayGetLBound(pVec, 1, &iLBound);
  883. SafeArrayGetUBound(pVec, 1, &iUBound);
  884. if ((iUBound - iLBound + 1) == 0)
  885. {
  886. buf = (WCHAR *)malloc(BLOCKSIZE);
  887. if (buf)
  888. {
  889. wcscpy(buf, L"<empty array>");
  890. }
  891. break;
  892. }
  893. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  894. if (buf)
  895. {
  896. wcscpy(buf, L"");
  897. for (long i = iLBound; i <= iUBound; i++)
  898. {
  899. if (!bFirst)
  900. {
  901. wcscat(buf, L",");
  902. }
  903. else
  904. {
  905. bFirst = FALSE;
  906. }
  907. BSTR v = NULL;
  908. SafeArrayGetElement(pVec, &i, &v);
  909. swprintf(lbuf, L"%I64u", _wtoi64(v));
  910. wcscat(buf, lbuf);
  911. }
  912. }
  913. }
  914. else if (dwType == (CIM_SINT64|VT_ARRAY))
  915. {
  916. SAFEARRAY *pVec = pValue->parray;
  917. long iLBound, iUBound;
  918. BOOL bFirst = TRUE;
  919. SafeArrayGetLBound(pVec, 1, &iLBound);
  920. SafeArrayGetUBound(pVec, 1, &iUBound);
  921. if ((iUBound - iLBound + 1) == 0)
  922. {
  923. buf = (WCHAR *)malloc(BLOCKSIZE);
  924. if (buf)
  925. {
  926. wcscpy(buf, L"<empty array>");
  927. }
  928. break;
  929. }
  930. buf = (WCHAR *)malloc((iUBound - iLBound + 1) * BLOCKSIZE);
  931. if (buf)
  932. {
  933. wcscpy(buf, L"");
  934. for (long i = iLBound; i <= iUBound; i++)
  935. {
  936. if (!bFirst)
  937. {
  938. wcscat(buf, L",");
  939. }
  940. else
  941. {
  942. bFirst = FALSE;
  943. }
  944. BSTR v = NULL;
  945. SafeArrayGetElement(pVec, &i, &v);
  946. swprintf(lbuf, L"%I64d", _wtoi64(v));
  947. wcscat(buf, lbuf);
  948. }
  949. }
  950. }
  951. else // string, datetime, reference
  952. {
  953. SAFEARRAY *pVec = pValue->parray;
  954. long iLBound, iUBound;
  955. DWORD iNeed;
  956. size_t iVSize;
  957. DWORD iCurBufSize;
  958. SafeArrayGetLBound(pVec, 1, &iLBound);
  959. SafeArrayGetUBound(pVec, 1, &iUBound);
  960. if ((iUBound - iLBound + 1) == 0)
  961. {
  962. buf = (WCHAR *)malloc(BLOCKSIZE);
  963. if (buf)
  964. {
  965. wcscpy(buf, L"<empty array>");
  966. }
  967. break;
  968. }
  969. iTotBufSize = (iUBound - iLBound + 1) * BLOCKSIZE;
  970. buf = (WCHAR *)malloc(iTotBufSize);
  971. if (buf)
  972. {
  973. buf[0] = L'\0';
  974. iCurBufSize = 0;
  975. iVSize = BLOCKSIZE;
  976. vbuf = (WCHAR *)malloc(BLOCKSIZE);
  977. if (vbuf)
  978. {
  979. size_t iLen;
  980. for (long i = iLBound; i <= iUBound; i++)
  981. {
  982. BSTR v = NULL;
  983. SafeArrayGetElement(pVec, &i, &v);
  984. iLen = (wcslen(v) + 1) * sizeof(WCHAR);
  985. if (iLen > iVSize)
  986. {
  987. WCHAR* pTmp = (WCHAR *)realloc(vbuf, iLen + sizeof(WCHAR));
  988. if (pTmp)
  989. {
  990. vbuf = pTmp;
  991. iVSize = iLen;
  992. }
  993. else
  994. {
  995. free(buf);
  996. buf = NULL;
  997. SysFreeString(v);
  998. break;
  999. }
  1000. }
  1001. // String size + (quotes + comma + null)
  1002. iNeed = (swprintf(vbuf, L"%wS", v) + 4) * sizeof(WCHAR);
  1003. if (iNeed + iCurBufSize > iTotBufSize)
  1004. {
  1005. iTotBufSize += (iNeed * 2); // Room enough for 2 more entries
  1006. WCHAR* pTmp = (WCHAR *)realloc(buf, iTotBufSize);
  1007. if (pTmp)
  1008. buf = pTmp;
  1009. else
  1010. {
  1011. free(buf);
  1012. buf = NULL;
  1013. SysFreeString(v);
  1014. break;
  1015. }
  1016. }
  1017. wcscat(buf, L"\"");
  1018. wcscat(buf, vbuf);
  1019. if (i + 1 <= iUBound)
  1020. {
  1021. wcscat(buf, L"\",");
  1022. }
  1023. else
  1024. {
  1025. wcscat(buf, L"\"");
  1026. }
  1027. iCurBufSize += iNeed;
  1028. SysFreeString(v);
  1029. }
  1030. free(vbuf);
  1031. }
  1032. }
  1033. }
  1034. break;
  1035. }
  1036. default:
  1037. {
  1038. if (fnHandler != NULL)
  1039. {
  1040. buf = fnHandler(pValue);
  1041. }
  1042. else
  1043. {
  1044. buf = (WCHAR *)malloc(BLOCKSIZE);
  1045. if (buf)
  1046. {
  1047. wcscpy(buf, L"<conversion error>");
  1048. }
  1049. }
  1050. break;
  1051. }
  1052. }
  1053. if (!buf)
  1054. {
  1055. PrintErrorAndExit("ValueToString() out of memory", S_OK, 0);
  1056. }
  1057. *pbuf = buf;
  1058. return buf;
  1059. }
  1060. //*****************************************************************************
  1061. // Function: cvt
  1062. // Purpose: Converts unicode to oem for console output
  1063. // Note: y must be freed by caller
  1064. //*****************************************************************************
  1065. char *cvt(WCHAR *x, char **y)
  1066. {
  1067. int dwRet, i;
  1068. i = WideCharToMultiByte( CP_OEMCP,
  1069. 0,
  1070. x,
  1071. -1,
  1072. NULL,
  1073. 0,
  1074. NULL,
  1075. NULL);
  1076. *y = (char *)calloc(i, 1);
  1077. if (*y)
  1078. {
  1079. dwRet = WideCharToMultiByte( CP_OEMCP,
  1080. 0,
  1081. x,
  1082. -1,
  1083. *y,
  1084. i,
  1085. NULL,
  1086. NULL);
  1087. if (dwRet == 0)
  1088. {
  1089. free(*y);
  1090. *y = (char *)malloc(sizeof(CVTFAILED));
  1091. if (*y)
  1092. {
  1093. memcpy(*y, CVTFAILED, sizeof(CVTFAILED));
  1094. }
  1095. }
  1096. }
  1097. else
  1098. {
  1099. PrintErrorAndExit("cvt() out of memory", S_OK, 0);
  1100. }
  1101. return *y;
  1102. }
  1103. //*****************************************************************************
  1104. // Function: myWFPrintf
  1105. // Purpose: Checks to see if outputing to console and converts strings
  1106. // to oem if necessary.
  1107. // Note: Returns number of characters written (ie if we write 3 oem
  1108. // chars, it returns 3. If it writes 4 wchars, it returns 4).
  1109. //*****************************************************************************
  1110. int myFWPrintf(FILE *f, WCHAR *fmt, ...)
  1111. {
  1112. va_list argptr;
  1113. size_t i;
  1114. int iSize = PAGESIZE;
  1115. WCHAR *wszBuff = (WCHAR *)malloc(iSize);
  1116. if (wszBuff)
  1117. {
  1118. wszBuff[(iSize/2)-2] = 0xffff;
  1119. va_start(argptr, fmt); // Init variable arguments
  1120. // Format the string into a buffer. Make sure the buffer is big enough
  1121. while (_vsnwprintf(wszBuff, (iSize-1)/sizeof(WCHAR), fmt, argptr) == -1)
  1122. {
  1123. if (wszBuff[(iSize/2)-2] != 0xffff)
  1124. {
  1125. WCHAR* pTmp = (WCHAR *)realloc(wszBuff, iSize + PAGESIZE);
  1126. if (pTmp)
  1127. {
  1128. wszBuff = pTmp;
  1129. wszBuff[(iSize/2)-2] = 0xffff;
  1130. iSize += PAGESIZE;
  1131. }
  1132. else
  1133. {
  1134. wszBuff[(iSize/2)-2] = L'\0';
  1135. break;
  1136. }
  1137. }
  1138. else
  1139. {
  1140. // unfortunately, _vsnwprintf won't handle the unicode character
  1141. // 0xffff. Since this isn't actually a valid unicode character,
  1142. // we'll just ignore it.
  1143. wcscpy(wszBuff, L"String contains 0xffff\n");
  1144. break;
  1145. }
  1146. }
  1147. if (f == stdout)
  1148. {
  1149. char *z = NULL;
  1150. fputs(cvt(wszBuff,&z), f);
  1151. i = strlen(z);
  1152. free(z);
  1153. }
  1154. else
  1155. {
  1156. i = wcslen(wszBuff);
  1157. fwrite(wszBuff, i * sizeof(WCHAR), 1, f);
  1158. }
  1159. free(wszBuff);
  1160. }
  1161. else
  1162. {
  1163. if (f == stdout)
  1164. {
  1165. char *szBuff = "myFWPrintf() out of memory";
  1166. i = strlen(szBuff);
  1167. fputs(szBuff, f);
  1168. }
  1169. else
  1170. {
  1171. wszBuff = L"myFWPrintf() out of memory";
  1172. i = wcslen(wszBuff);
  1173. fwrite(wszBuff, i * sizeof(WCHAR), 1, f);
  1174. }
  1175. }
  1176. va_end(argptr);
  1177. return (int)i;
  1178. }
  1179. //*****************************************************************************
  1180. // Function: difftime
  1181. // Purpose: Returns the elapsed time between two _timeb structures
  1182. // Note: This is different from the crt routine which works on time_t
  1183. // structures.
  1184. //*****************************************************************************
  1185. double difftime(struct _timeb finish, struct _timeb start)
  1186. {
  1187. double dRet;
  1188. if (start.millitm > finish.millitm)
  1189. {
  1190. dRet = ((finish.time - start.time) - 1) + (double)(((1000 + finish.millitm) - start.millitm) / 1000.0);
  1191. }
  1192. else
  1193. {
  1194. dRet = (finish.time - start.time) + (double)((finish.millitm - start.millitm) / 1000.0);
  1195. }
  1196. return dRet;
  1197. }