Source code of Windows XP (NT5)
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.

312 lines
6.0 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Active Directory 1.0 Sample Code
  4. //
  5. // Copyright (C) Microsoft Corporation, 1992 - 1995
  6. //
  7. // File: util.cxx
  8. //
  9. // Contents: Ansi to Unicode conversions and misc helper functions
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "main.hxx"
  13. //
  14. // Local functions
  15. //
  16. int
  17. AnsiToUnicodeString(
  18. LPSTR pAnsi,
  19. LPWSTR pUnicode,
  20. DWORD StringLength
  21. )
  22. {
  23. int iReturn;
  24. if( StringLength == 0 )
  25. StringLength = strlen( pAnsi );
  26. iReturn = MultiByteToWideChar(CP_ACP,
  27. MB_PRECOMPOSED,
  28. pAnsi,
  29. StringLength + 1,
  30. pUnicode,
  31. StringLength + 1 );
  32. //
  33. // Ensure NULL termination.
  34. //
  35. pUnicode[StringLength] = 0;
  36. return iReturn;
  37. }
  38. int
  39. UnicodeToAnsiString(
  40. LPWSTR pUnicode,
  41. LPSTR pAnsi,
  42. DWORD StringLength
  43. )
  44. {
  45. LPSTR pTempBuf = NULL;
  46. INT rc = 0;
  47. if( StringLength == 0 ) {
  48. //
  49. // StringLength is just the
  50. // number of characters in the string
  51. //
  52. StringLength = wcslen( pUnicode );
  53. }
  54. //
  55. // WideCharToMultiByte doesn't NULL terminate if we're copying
  56. // just part of the string, so terminate here.
  57. //
  58. pUnicode[StringLength] = 0;
  59. //
  60. // Include one for the NULL
  61. //
  62. StringLength++;
  63. //
  64. // Unfortunately, WideCharToMultiByte doesn't do conversion in place,
  65. // so allocate a temporary buffer, which we can then copy:
  66. //
  67. if( pAnsi == (LPSTR)pUnicode )
  68. {
  69. pTempBuf = (LPSTR)LocalAlloc( LPTR, StringLength );
  70. pAnsi = pTempBuf;
  71. }
  72. if( pAnsi )
  73. {
  74. rc = WideCharToMultiByte( CP_ACP,
  75. 0,
  76. pUnicode,
  77. StringLength,
  78. pAnsi,
  79. StringLength,
  80. NULL,
  81. NULL );
  82. }
  83. /* If pTempBuf is non-null, we must copy the resulting string
  84. * so that it looks as if we did it in place:
  85. */
  86. if( pTempBuf && ( rc > 0 ) )
  87. {
  88. pAnsi = (LPSTR)pUnicode;
  89. strcpy( pAnsi, pTempBuf );
  90. LocalFree( pTempBuf );
  91. }
  92. return rc;
  93. }
  94. LPWSTR
  95. AllocateUnicodeString(
  96. LPSTR pAnsiString
  97. )
  98. {
  99. LPWSTR pUnicodeString = NULL;
  100. if (!pAnsiString)
  101. return NULL;
  102. pUnicodeString = (LPWSTR)LocalAlloc(
  103. LPTR,
  104. strlen(pAnsiString)*sizeof(WCHAR) + sizeof(WCHAR)
  105. );
  106. if (pUnicodeString) {
  107. AnsiToUnicodeString(
  108. pAnsiString,
  109. pUnicodeString,
  110. 0
  111. );
  112. }
  113. return pUnicodeString;
  114. }
  115. void
  116. FreeUnicodeString(
  117. LPWSTR pUnicodeString
  118. )
  119. {
  120. LocalFree(pUnicodeString);
  121. return;
  122. }
  123. //
  124. // Misc helper functions for displaying data.
  125. //
  126. HRESULT
  127. PrintVariant(
  128. VARIANT varPropData
  129. )
  130. {
  131. HRESULT hr;
  132. BSTR bstrValue;
  133. switch (varPropData.vt) {
  134. case VT_I4:
  135. printf("%d", varPropData.lVal);
  136. break;
  137. case VT_BSTR:
  138. printf("%S", varPropData.bstrVal);
  139. break;
  140. case VT_BOOL:
  141. printf("%d", V_BOOL(&varPropData));
  142. break;
  143. case (VT_ARRAY | VT_VARIANT):
  144. PrintVariantArray(varPropData);
  145. break;
  146. case VT_DATE:
  147. hr = VarBstrFromDate(
  148. varPropData.date,
  149. LOCALE_SYSTEM_DEFAULT,
  150. LOCALE_NOUSEROVERRIDE,
  151. &bstrValue
  152. );
  153. printf("%S", bstrValue);
  154. break;
  155. default:
  156. printf("Data type is %d\n", varPropData.vt);
  157. break;
  158. }
  159. printf("\n");
  160. return(S_OK);
  161. }
  162. HRESULT
  163. PrintVariantArray(
  164. VARIANT var
  165. )
  166. {
  167. LONG dwSLBound = 0;
  168. LONG dwSUBound = 0;
  169. VARIANT v;
  170. LONG i;
  171. HRESULT hr = S_OK;
  172. if(!((V_VT(&var) & VT_VARIANT) && V_ISARRAY(&var))) {
  173. return(E_FAIL);
  174. }
  175. //
  176. // Check that there is only one dimension in this array
  177. //
  178. if ((V_ARRAY(&var))->cDims != 1) {
  179. hr = E_FAIL;
  180. BAIL_ON_FAILURE(hr);
  181. }
  182. //
  183. // Check that there is atleast one element in this array
  184. //
  185. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
  186. hr = E_FAIL;
  187. BAIL_ON_FAILURE(hr);
  188. }
  189. //
  190. // We know that this is a valid single dimension array
  191. //
  192. hr = SafeArrayGetLBound(V_ARRAY(&var),
  193. 1,
  194. (long FAR *)&dwSLBound
  195. );
  196. BAIL_ON_FAILURE(hr);
  197. hr = SafeArrayGetUBound(V_ARRAY(&var),
  198. 1,
  199. (long FAR *)&dwSUBound
  200. );
  201. BAIL_ON_FAILURE(hr);
  202. for (i = dwSLBound; i <= dwSUBound; i++) {
  203. VariantInit(&v);
  204. hr = SafeArrayGetElement(V_ARRAY(&var),
  205. (long FAR *)&i,
  206. &v
  207. );
  208. if (FAILED(hr)) {
  209. continue;
  210. }
  211. if (i < dwSUBound) {
  212. printf("%S, ", v.bstrVal);
  213. } else {
  214. printf("%S", v.bstrVal);
  215. }
  216. }
  217. return(S_OK);
  218. error:
  219. return(hr);
  220. }
  221. HRESULT
  222. PrintProperty(
  223. BSTR bstrPropName,
  224. HRESULT hRetVal,
  225. VARIANT varPropData
  226. )
  227. {
  228. HRESULT hr = S_OK;
  229. switch (hRetVal) {
  230. case 0:
  231. printf("%-32S: ", bstrPropName);
  232. PrintVariant(varPropData);
  233. break;
  234. case E_ADS_CANT_CONVERT_DATATYPE:
  235. printf("%-32S: ", bstrPropName);
  236. printf("<Data could not be converted for display>\n");
  237. break;
  238. default:
  239. printf("%-32S: ", bstrPropName);
  240. printf("<Data not available>\n");
  241. break;
  242. }
  243. return(hr);
  244. }
  245. void
  246. PrintUsage(
  247. void
  248. )
  249. {
  250. printf("usage: adscmd [list|dump] <ADsPath>\n") ;
  251. }
  252.