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.

846 lines
27 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: nt2umi.cxx
  7. //
  8. // Contents: Contains the routines to convert from NT objects to
  9. // UMI_PROPERTY structures.
  10. //
  11. // History: 02-29-00 SivaramR Created.
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "winnt.hxx"
  15. //----------------------------------------------------------------------------
  16. // Function: WinNTTypeToUmiIntegers
  17. //
  18. // Synopsis: Converts from NT object to UMI_PROPERTY structure containing
  19. // one of the signed/unsigned integers (1, 2, 4 or 8 bytes each).
  20. //
  21. // Arguments:
  22. //
  23. // pNtObject Pointer to NT object
  24. // dwNumValues Number of values in pNtObject
  25. // pPropArray Pointer to UMI_PROPERTY that returns the converted values
  26. // pExistingMem If non-NULL, the provider does not allocate memory. Instead,
  27. // the memory pointed to by this argument is used.
  28. // dwMemSize Number of bytes of memory pointed to by pExistingMem
  29. // UmiType UMI type to convert the NT object to
  30. //
  31. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  32. //
  33. // Modifies: *pExistingMem if pExistingMem is non-NULL
  34. // *pPropArray otherwise
  35. //
  36. //----------------------------------------------------------------------------
  37. HRESULT WinNTTypeToUmiIntegers(
  38. LPNTOBJECT pNtObject,
  39. DWORD dwNumValues,
  40. UMI_PROPERTY *pPropArray,
  41. LPVOID pExistingMem,
  42. DWORD dwMemSize,
  43. UMI_TYPE UmiType
  44. )
  45. {
  46. DWORD dwSize = 0, dwMemRequired = 0, dwNtValue = 0, i = 0;
  47. void *pIntArray = NULL;
  48. HRESULT hr = UMI_S_NO_ERROR;
  49. // Check if the NT type can be converted to the requested UMI type
  50. if(pNtObject->NTType != NT_SYNTAX_ID_DWORD)
  51. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  52. switch(UmiType) {
  53. case UMI_TYPE_I1:
  54. case UMI_TYPE_UI1:
  55. dwSize = 1;
  56. break;
  57. case UMI_TYPE_I2:
  58. case UMI_TYPE_UI2:
  59. dwSize = 2;
  60. break;
  61. case UMI_TYPE_I4:
  62. case UMI_TYPE_UI4:
  63. dwSize = 4;
  64. break;
  65. case UMI_TYPE_I8:
  66. case UMI_TYPE_UI8:
  67. dwSize = 8;
  68. break;
  69. default:
  70. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  71. }
  72. dwMemRequired = dwNumValues * dwSize;
  73. if(NULL == pExistingMem) {
  74. // provider has to allocate memory
  75. pIntArray = (void *) AllocADsMem(dwMemRequired);
  76. if(NULL == pIntArray)
  77. BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
  78. }
  79. else {
  80. // user provided memory to return data
  81. if(dwMemSize < dwMemRequired)
  82. BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
  83. pIntArray = pExistingMem;
  84. }
  85. for(i = 0; i < dwNumValues; i++) {
  86. dwNtValue = pNtObject[i].NTValue.dwValue;
  87. switch(UmiType) {
  88. case UMI_TYPE_I1:
  89. case UMI_TYPE_UI1:
  90. *((CHAR *)(pIntArray) + i) = (CHAR) dwNtValue;
  91. break;
  92. case UMI_TYPE_I2:
  93. case UMI_TYPE_UI2:
  94. *((WCHAR *)(pIntArray) + i) = (WCHAR) dwNtValue;
  95. break;
  96. case UMI_TYPE_I4:
  97. case UMI_TYPE_UI4:
  98. *((DWORD *)(pIntArray) + i) = dwNtValue;
  99. break;
  100. case UMI_TYPE_I8:
  101. case UMI_TYPE_UI8:
  102. *((__int64 *)(pIntArray) + i) = (__int64) dwNtValue;
  103. break;
  104. default:
  105. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  106. } // switch
  107. } // for
  108. if(pPropArray != NULL)
  109. pPropArray->pUmiValue = (UMI_VALUE *) pIntArray;
  110. RRETURN(hr);
  111. error:
  112. if( (pIntArray != NULL) && (NULL == pExistingMem) )
  113. FreeADsMem(pIntArray);
  114. RRETURN(hr);
  115. }
  116. //----------------------------------------------------------------------------
  117. // Function: WinNTTypeToUmiFileTimes
  118. //
  119. // Synopsis: Converts from NT object to UMI_PROPERTY structure containing
  120. // a filetime.
  121. //
  122. // Arguments:
  123. //
  124. // pNtObject Pointer to NT object
  125. // dwNumValues Number of values in pNtObject
  126. // pPropArray Pointer to UMI_PROPERTY that returns the converted values
  127. // pExistingMem If non-NULL, the provider does not allocate memory. Instead,
  128. // the memory pointed to by this argument is used.
  129. // dwMemSize Number of bytes of memory pointed to by pExistingMem
  130. //
  131. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  132. //
  133. // Modifies: *pExistingMem if pExistingMem is non-NULL
  134. // *pPropArray otherwise
  135. //
  136. //----------------------------------------------------------------------------
  137. HRESULT WinNTTypeToUmiFileTimes(
  138. LPNTOBJECT pNtObject,
  139. DWORD dwNumValues,
  140. UMI_PROPERTY *pPropArray,
  141. LPVOID pExistingMem,
  142. DWORD dwMemSize
  143. )
  144. {
  145. DWORD dwMemRequired = 0, i = 0;
  146. void *pFileTimeArray = NULL;
  147. HRESULT hr = UMI_S_NO_ERROR;
  148. BOOL fRetVal = FALSE;
  149. SYSTEMTIME LocalTime, SystemTime;
  150. FILETIME LocalFileTime, FileTime;
  151. LARGE_INTEGER tmpTime;
  152. // Check if the NT type can be converted to the requested UMI type
  153. if(pNtObject->NTType != NT_SYNTAX_ID_SYSTEMTIME)
  154. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  155. dwMemRequired = dwNumValues * sizeof(FILETIME);
  156. if(NULL == pExistingMem) {
  157. // provider has to allocate memory
  158. pFileTimeArray = (void *) AllocADsMem(dwMemRequired);
  159. if(NULL == pFileTimeArray)
  160. BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
  161. }
  162. else {
  163. // user provided memory to return data
  164. if(dwMemSize < dwMemRequired)
  165. BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
  166. pFileTimeArray = pExistingMem;
  167. }
  168. for(i = 0; i < dwNumValues; i++) {
  169. if(NT_SYNTAX_ID_SYSTEMTIME == pNtObject->NTType) {
  170. // convert from UTC to local time
  171. fRetVal = SystemTimeToTzSpecificLocalTime(
  172. NULL,
  173. &(pNtObject[i].NTValue.stSystemTimeValue),
  174. &LocalTime
  175. );
  176. if(FALSE == fRetVal)
  177. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  178. fRetVal = SystemTimeToFileTime(
  179. &LocalTime,
  180. &LocalFileTime
  181. );
  182. if(FALSE == fRetVal)
  183. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  184. }
  185. else if(NT_SYNTAX_ID_DATE == pNtObject->NTType) {
  186. GetSystemTime(&SystemTime);
  187. // only the hours and minutes are valid. Rest is no-op.
  188. SystemTime.wHour = (WORD) ((pNtObject[i].NTValue.dwValue)/60);
  189. SystemTime.wMinute = (WORD) ((pNtObject[i].NTValue.dwValue)%60);
  190. SystemTime.wSecond =0;
  191. SystemTime.wMilliseconds = 0;
  192. // now convert UTC To local time
  193. fRetVal = SystemTimeToTzSpecificLocalTime(
  194. NULL,
  195. &SystemTime,
  196. &LocalTime
  197. );
  198. if(FALSE == fRetVal)
  199. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  200. fRetVal = SystemTimeToFileTime(
  201. &LocalTime,
  202. &LocalFileTime
  203. );
  204. if(FALSE == fRetVal)
  205. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  206. }
  207. else if(NT_SYNTAX_ID_DATE_1970 == pNtObject->NTType) {
  208. memset(&FileTime, 0, sizeof(FILETIME));
  209. RtlSecondsSince1970ToTime(
  210. pNtObject[i].NTValue.dwSeconds1970,
  211. &tmpTime
  212. );
  213. FileTime.dwLowDateTime = tmpTime.LowPart;
  214. FileTime.dwHighDateTime = tmpTime.HighPart;
  215. fRetVal = FileTimeToLocalFileTime(
  216. &FileTime,
  217. &LocalFileTime
  218. );
  219. if(FALSE == fRetVal)
  220. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  221. }
  222. *((FILETIME *)pFileTimeArray + i) = LocalFileTime;
  223. }
  224. if(pPropArray != NULL)
  225. pPropArray->pUmiValue = (UMI_VALUE *) pFileTimeArray;
  226. RRETURN(hr);
  227. error:
  228. if( (pFileTimeArray != NULL) && (NULL == pExistingMem) )
  229. FreeADsMem(pFileTimeArray);
  230. RRETURN(hr);
  231. }
  232. //----------------------------------------------------------------------------
  233. // Function: WinNTTypeToUmiSystemTimes
  234. //
  235. // Synopsis: Converts from NT object to UMI_PROPERTY structure containing
  236. // a systemtime.
  237. //
  238. // Arguments:
  239. //
  240. // pNtObject Pointer to NT object
  241. // dwNumValues Number of values in pNtObject
  242. // pPropArray Pointer to UMI_PROPERTY that returns the converted values
  243. // pExistingMem If non-NULL, the provider does not allocate memory. Instead,
  244. // the memory pointed to by this argument is used.
  245. // dwMemSize Number of bytes of memory pointed to by pExistingMem
  246. //
  247. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  248. //
  249. // Modifies: *pExistingMem if pExistingMem is non-NULL
  250. // *pPropArray otherwise
  251. //
  252. //----------------------------------------------------------------------------
  253. HRESULT WinNTTypeToUmiSystemTimes(
  254. LPNTOBJECT pNtObject,
  255. DWORD dwNumValues,
  256. UMI_PROPERTY *pPropArray,
  257. LPVOID pExistingMem,
  258. DWORD dwMemSize
  259. )
  260. {
  261. DWORD dwMemRequired = 0, i = 0;
  262. void *pSysTimeArray = NULL;
  263. HRESULT hr = UMI_S_NO_ERROR;
  264. SYSTEMTIME LocalTime, SystemTime;
  265. BOOL fRetVal = FALSE;
  266. FILETIME FileTime, LocalFileTime;
  267. LARGE_INTEGER tmpTime;
  268. // Check if the NT type can be converted to the requested UMI type
  269. if( (pNtObject->NTType != NT_SYNTAX_ID_SYSTEMTIME) &&
  270. (pNtObject->NTType != NT_SYNTAX_ID_DATE) &&
  271. (pNtObject->NTType != NT_SYNTAX_ID_DATE_1970) )
  272. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  273. dwMemRequired = dwNumValues * sizeof(SYSTEMTIME);
  274. if(NULL == pExistingMem) {
  275. // provider has to allocate memory
  276. pSysTimeArray = (void *) AllocADsMem(dwMemRequired);
  277. if(NULL == pSysTimeArray)
  278. BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
  279. }
  280. else {
  281. // user provided memory to return data
  282. if(dwMemSize < dwMemRequired)
  283. BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
  284. pSysTimeArray = pExistingMem;
  285. }
  286. for(i = 0; i < dwNumValues; i++) {
  287. if(NT_SYNTAX_ID_SYSTEMTIME == pNtObject->NTType) {
  288. // convert from UTC to local time
  289. fRetVal = SystemTimeToTzSpecificLocalTime(
  290. NULL,
  291. &pNtObject[i].NTValue.stSystemTimeValue,
  292. &LocalTime
  293. );
  294. if(FALSE == fRetVal)
  295. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  296. }
  297. else if(NT_SYNTAX_ID_DATE == pNtObject->NTType) {
  298. GetSystemTime(&SystemTime);
  299. // only the hours and minutes are valid. Rest is no-op.
  300. SystemTime.wHour = (WORD) ((pNtObject[i].NTValue.dwValue)/60);
  301. SystemTime.wMinute = (WORD) ((pNtObject[i].NTValue.dwValue)%60);
  302. SystemTime.wSecond =0;
  303. SystemTime.wMilliseconds = 0;
  304. // now convert UTC To local time
  305. fRetVal = SystemTimeToTzSpecificLocalTime(
  306. NULL,
  307. &SystemTime,
  308. &LocalTime
  309. );
  310. if(FALSE == fRetVal)
  311. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  312. }
  313. else if(NT_SYNTAX_ID_DATE_1970 == pNtObject->NTType) {
  314. memset(&FileTime, 0, sizeof(FILETIME));
  315. RtlSecondsSince1970ToTime(
  316. pNtObject[i].NTValue.dwSeconds1970,
  317. &tmpTime
  318. );
  319. FileTime.dwLowDateTime = tmpTime.LowPart;
  320. FileTime.dwHighDateTime = tmpTime.HighPart;
  321. fRetVal = FileTimeToLocalFileTime(
  322. &FileTime,
  323. &LocalFileTime
  324. );
  325. if(FALSE == fRetVal)
  326. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  327. fRetVal = FileTimeToSystemTime(
  328. &LocalFileTime,
  329. &LocalTime
  330. );
  331. if(FALSE == fRetVal)
  332. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  333. }
  334. *((SYSTEMTIME *)pSysTimeArray + i) = LocalTime;
  335. }
  336. if(pPropArray != NULL)
  337. pPropArray->pUmiValue = (UMI_VALUE *) pSysTimeArray;
  338. RRETURN(hr);
  339. error:
  340. if( (pSysTimeArray != NULL) && (NULL == pExistingMem) )
  341. FreeADsMem(pSysTimeArray);
  342. RRETURN(hr);
  343. }
  344. //----------------------------------------------------------------------------
  345. // Function: WinNTTypeToUmiBools
  346. //
  347. // Synopsis: Converts from NT object to UMI_PROPERTY structure containing
  348. // a boolean
  349. //
  350. // Arguments:
  351. //
  352. // pNtObject Pointer to NT object
  353. // dwNumValues Number of values in pNtObject
  354. // pPropArray Pointer to UMI_PROPERTY that returns the converted values
  355. // pExistingMem If non-NULL, the provider does not allocate memory. Instead,
  356. // the memory pointed to by this argument is used.
  357. // dwMemSize Number of bytes of memory pointed to by pExistingMem
  358. //
  359. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  360. //
  361. // Modifies: *pExistingMem if pExistingMem is non-NULL
  362. // *pPropArray otherwise
  363. //
  364. //----------------------------------------------------------------------------
  365. HRESULT WinNTTypeToUmiBools(
  366. LPNTOBJECT pNtObject,
  367. DWORD dwNumValues,
  368. UMI_PROPERTY *pPropArray,
  369. LPVOID pExistingMem,
  370. DWORD dwMemSize
  371. )
  372. {
  373. DWORD dwMemRequired = 0, i = 0;
  374. void *pBoolArray = NULL;
  375. HRESULT hr = UMI_S_NO_ERROR;
  376. // Check if the NT type can be converted to the requested UMI type
  377. if(pNtObject->NTType != NT_SYNTAX_ID_BOOL)
  378. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  379. dwMemRequired = dwNumValues * sizeof(BOOL);
  380. if(NULL == pExistingMem) {
  381. // provider has to allocate memory
  382. pBoolArray = (void *) AllocADsMem(dwMemRequired);
  383. if(NULL == pBoolArray)
  384. BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
  385. }
  386. else {
  387. // user provided memory to return data
  388. if(dwMemSize < dwMemRequired)
  389. BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
  390. pBoolArray = pExistingMem;
  391. }
  392. for(i = 0; i < dwNumValues; i++) {
  393. if(pNtObject[i].NTValue.fValue)
  394. *((BOOL *)pBoolArray + i) = TRUE;
  395. else
  396. *((BOOL *)pBoolArray + i) = FALSE;
  397. }
  398. if(pPropArray != NULL)
  399. pPropArray->pUmiValue = (UMI_VALUE *) pBoolArray;
  400. RRETURN(hr);
  401. error:
  402. if( (pBoolArray != NULL) && (NULL == pExistingMem) )
  403. FreeADsMem(pBoolArray);
  404. RRETURN(hr);
  405. }
  406. //----------------------------------------------------------------------------
  407. // Function: WinNTTypeToUmiLPWSTRs
  408. //
  409. // Synopsis: Converts from NT object to UMI_PROPERTY structure containing
  410. // a string
  411. //
  412. // Arguments:
  413. //
  414. // pNtObject Pointer to NT object
  415. // dwNumValues Number of values in pNtObject
  416. // pPropArray Pointer to UMI_PROPERTY that returns the converted values
  417. // pExistingMem If non-NULL, the provider does not allocate memory. Instead,
  418. // the memory pointed to by this argument is used.
  419. // dwMemSize Number of bytes of memory pointed to by pExistingMem
  420. //
  421. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  422. //
  423. // Modifies: *pExistingMem if pExistingMem is non-NULL
  424. // *pPropArray otherwise
  425. //
  426. //----------------------------------------------------------------------------
  427. HRESULT WinNTTypeToUmiLPWSTRs(
  428. LPNTOBJECT pNtObject,
  429. DWORD dwNumValues,
  430. UMI_PROPERTY *pPropArray,
  431. LPVOID pExistingMem,
  432. DWORD dwMemSize
  433. )
  434. {
  435. DWORD dwMemRequired = 0, i = 0;
  436. void *pStrArray = NULL;
  437. HRESULT hr = UMI_S_NO_ERROR;
  438. LPWSTR pszTmpStr = NULL;
  439. UCHAR Seed = UMI_ENCODE_SEED3;
  440. UNICODE_STRING Password;
  441. // Check if the NT type can be converted to the requested UMI type
  442. if( (pNtObject->NTType != NT_SYNTAX_ID_LPTSTR) &&
  443. (pNtObject->NTType != NT_SYNTAX_ID_DelimitedString) &&
  444. (pNtObject->NTType != NT_SYNTAX_ID_NulledString) &&
  445. (pNtObject->NTType != NT_SYNTAX_ID_EncryptedString) )
  446. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  447. dwMemRequired = dwNumValues * sizeof(LPWSTR);
  448. if(NULL == pExistingMem) {
  449. // provider has to allocate memory
  450. pStrArray = (void *) AllocADsMem(dwMemRequired);
  451. if(NULL == pStrArray)
  452. BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
  453. }
  454. else {
  455. // user provided memory to return data. GetAs() will call this function
  456. // only if the property is single-valued. Copy the string into the
  457. // memory supplied y the caller.
  458. //
  459. ADsAssert(1 == dwNumValues);
  460. dwMemRequired = (wcslen(pNtObject->NTValue.pszValue) + 1) *
  461. sizeof(WCHAR);
  462. if(dwMemSize < dwMemRequired)
  463. BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
  464. wcscpy((WCHAR *) pExistingMem, pNtObject->NTValue.pszValue);
  465. if(NT_SYNTAX_ID_EncryptedString == pNtObject->NTType) {
  466. // decrypt the string (typically password)
  467. RtlInitUnicodeString(&Password, (WCHAR *) pExistingMem);
  468. RtlRunDecodeUnicodeString(Seed, &Password);
  469. }
  470. RRETURN(UMI_S_NO_ERROR);
  471. }
  472. memset(pStrArray, 0, dwMemRequired);
  473. for(i = 0; i < dwNumValues; i++) {
  474. if(pNtObject[i].NTValue.pszValue != NULL) {
  475. pszTmpStr = AllocADsStr(pNtObject[i].NTValue.pszValue);
  476. if(NULL == pszTmpStr)
  477. BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
  478. if(NT_SYNTAX_ID_EncryptedString == pNtObject->NTType) {
  479. // decrypt the string (typically password)
  480. RtlInitUnicodeString(&Password, pszTmpStr);
  481. RtlRunDecodeUnicodeString(Seed, &Password);
  482. }
  483. }
  484. *((LPWSTR *)pStrArray + i) = pszTmpStr;
  485. }
  486. if(pPropArray != NULL)
  487. pPropArray->pUmiValue = (UMI_VALUE *) pStrArray;
  488. RRETURN(hr);
  489. error:
  490. if(pStrArray != NULL) {
  491. // free any strings allocated
  492. for(i = 0; i < dwNumValues; i++)
  493. if(((LPWSTR *) pStrArray)[i] != NULL)
  494. FreeADsStr(((LPWSTR *) pStrArray)[i]);
  495. if(NULL == pExistingMem)
  496. // provider allocated memory
  497. FreeADsMem(pStrArray);
  498. }
  499. RRETURN(hr);
  500. }
  501. //----------------------------------------------------------------------------
  502. // Function: WinNTTypeToUmiOctetStrings
  503. //
  504. // Synopsis: Converts from NT object to UMI_PROPERTY structure containing
  505. // an octet string
  506. //
  507. // Arguments:
  508. //
  509. // pNtObject Pointer to NT object
  510. // dwNumValues Number of values in pNtObject
  511. // pPropArray Pointer to UMI_PROPERTY that returns the converted values
  512. // pExistingMem If non-NULL, the provider does not allocate memory. Instead,
  513. // the memory pointed to by this argument is used.
  514. // dwMemSize Number of bytes of memory pointed to by pExistingMem
  515. //
  516. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  517. //
  518. // Modifies: *pExistingMem if pExistingMem is non-NULL
  519. // *pPropArray otherwise
  520. //
  521. //----------------------------------------------------------------------------
  522. HRESULT WinNTTypeToUmiOctetStrings(
  523. LPNTOBJECT pNtObject,
  524. DWORD dwNumValues,
  525. UMI_PROPERTY *pPropArray,
  526. LPVOID pExistingMem,
  527. DWORD dwMemSize
  528. )
  529. {
  530. DWORD dwMemRequired = 0, i = 0;
  531. void *pOctetStrArray = NULL;
  532. HRESULT hr = UMI_S_NO_ERROR;
  533. LPWSTR pTmpOctetStr = NULL;
  534. // Check if the NT type can be converted to the requested UMI type
  535. if(pNtObject->NTType != NT_SYNTAX_ID_OCTETSTRING)
  536. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  537. dwMemRequired = dwNumValues * sizeof(UMI_OCTET_STRING);
  538. if(NULL == pExistingMem) {
  539. // provider has to allocate memory
  540. pOctetStrArray = (void *) AllocADsMem(dwMemRequired);
  541. if(NULL == pOctetStrArray)
  542. BAIL_ON_FAILURE(UMI_E_OUT_OF_MEMORY);
  543. }
  544. else {
  545. // user provided memory to return data
  546. if(dwMemSize < dwMemRequired)
  547. BAIL_ON_FAILURE(hr = UMI_E_INSUFFICIENT_MEMORY);
  548. pOctetStrArray = pExistingMem;
  549. }
  550. memset(pOctetStrArray, 0, dwMemRequired);
  551. for(i = 0; i < dwNumValues; i++) {
  552. pTmpOctetStr = (LPWSTR)
  553. AllocADsMem(pNtObject[i].NTValue.octetstring.dwSize);
  554. if(NULL == pTmpOctetStr)
  555. BAIL_ON_FAILURE(hr = UMI_E_OUT_OF_MEMORY);
  556. memcpy(
  557. pTmpOctetStr,
  558. pNtObject[i].NTValue.octetstring.pByte,
  559. pNtObject[i].NTValue.octetstring.dwSize
  560. );
  561. ((UMI_OCTET_STRING *)pOctetStrArray + i)->uLength =
  562. pNtObject[i].NTValue.octetstring.dwSize;
  563. ((UMI_OCTET_STRING *)pOctetStrArray + i)->lpValue =
  564. (BYTE *) pTmpOctetStr;
  565. }
  566. if(pPropArray != NULL)
  567. pPropArray->pUmiValue = (UMI_VALUE *) pOctetStrArray;
  568. RRETURN(hr);
  569. error:
  570. if(pOctetStrArray != NULL) {
  571. // free any strings allocated
  572. for(i = 0; i < dwNumValues; i++)
  573. if(((UMI_OCTET_STRING *) pOctetStrArray)[i].lpValue != NULL)
  574. FreeADsMem(((UMI_OCTET_STRING *) pOctetStrArray)[i].lpValue);
  575. if(NULL == pExistingMem)
  576. // provider allocated memory
  577. FreeADsMem(pOctetStrArray);
  578. }
  579. RRETURN(hr);
  580. }
  581. //----------------------------------------------------------------------------
  582. // Function: WinNTTypeToUmi
  583. //
  584. // Synopsis: Converts from NT object to UMI_PROPERTY structure.
  585. //
  586. // Arguments:
  587. //
  588. // pNtObject Pointer to NT object
  589. // dwNumValues Number of values in pNtObject
  590. // pPropArray Pointer to UMI_PROPERTY that returns the converted values
  591. // pExistingMem If non-NULL, the provider does not allocate memory. Instead,
  592. // the memory pointed to by this argument is used.
  593. // dwMemSize Number of bytes of memory pointed to by pExistingMem
  594. // UmiType UMI type to convert the NT object to
  595. //
  596. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  597. //
  598. // Modifies: *pExistingMem if pExistingMem is non-NULL
  599. // *pPropArray otherwise
  600. //
  601. //----------------------------------------------------------------------------
  602. HRESULT WinNTTypeToUmi(
  603. LPNTOBJECT pNtObject,
  604. DWORD dwNumValues,
  605. UMI_PROPERTY *pPropArray,
  606. LPVOID pExistingMem,
  607. DWORD dwMemSize,
  608. UMI_TYPE UmiType
  609. )
  610. {
  611. HRESULT hr = UMI_S_NO_ERROR;
  612. ADsAssert( (pNtObject != NULL) &&
  613. ((pPropArray != NULL) || (pExistingMem != NULL)) );
  614. // only one of pPropArray and pExistingMem can be non-NULL
  615. ADsAssert( (NULL == pPropArray) || (NULL == pExistingMem) );
  616. // Enclose code in try/except to catch AVs caused by the user passing in
  617. // a bad pointer in pExistingMem
  618. __try {
  619. switch(UmiType) {
  620. case UMI_TYPE_NULL:
  621. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  622. case UMI_TYPE_I1:
  623. case UMI_TYPE_I2:
  624. case UMI_TYPE_I4:
  625. case UMI_TYPE_I8:
  626. case UMI_TYPE_UI1:
  627. case UMI_TYPE_UI2:
  628. case UMI_TYPE_UI4:
  629. case UMI_TYPE_UI8:
  630. hr = WinNTTypeToUmiIntegers(
  631. pNtObject,
  632. dwNumValues,
  633. pPropArray,
  634. pExistingMem,
  635. dwMemSize,
  636. UmiType
  637. );
  638. break;
  639. case UMI_TYPE_R4:
  640. case UMI_TYPE_R8:
  641. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  642. case UMI_TYPE_FILETIME:
  643. hr = WinNTTypeToUmiFileTimes(
  644. pNtObject,
  645. dwNumValues,
  646. pPropArray,
  647. pExistingMem,
  648. dwMemSize
  649. );
  650. break;
  651. case UMI_TYPE_SYSTEMTIME:
  652. hr = WinNTTypeToUmiSystemTimes(
  653. pNtObject,
  654. dwNumValues,
  655. pPropArray,
  656. pExistingMem,
  657. dwMemSize
  658. );
  659. break;
  660. case UMI_TYPE_BOOL:
  661. hr = WinNTTypeToUmiBools(
  662. pNtObject,
  663. dwNumValues,
  664. pPropArray,
  665. pExistingMem,
  666. dwMemSize
  667. );
  668. break;
  669. case UMI_TYPE_IDISPATCH:
  670. case UMI_TYPE_IUNKNOWN:
  671. case UMI_TYPE_VARIANT: // TODO later
  672. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  673. case UMI_TYPE_LPWSTR:
  674. hr = WinNTTypeToUmiLPWSTRs(
  675. pNtObject,
  676. dwNumValues,
  677. pPropArray,
  678. pExistingMem,
  679. dwMemSize
  680. );
  681. break;
  682. case UMI_TYPE_OCTETSTRING:
  683. hr = WinNTTypeToUmiOctetStrings(
  684. pNtObject,
  685. dwNumValues,
  686. pPropArray,
  687. pExistingMem,
  688. dwMemSize
  689. );
  690. break;
  691. case UMI_TYPE_UMIARRAY:
  692. case UMI_TYPE_DISCOVERY:
  693. case UMI_TYPE_UNDEFINED:
  694. case UMI_TYPE_DEFAULT:
  695. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  696. default:
  697. BAIL_ON_FAILURE(hr = UMI_E_CANT_CONVERT_DATA);
  698. } // switch
  699. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  700. if(pExistingMem != NULL) {
  701. // assume this is the cause of the exception
  702. BAIL_ON_FAILURE(hr = UMI_E_INTERNAL_EXCEPTION);
  703. }
  704. else
  705. // don't mask bugs in provider
  706. throw;
  707. }
  708. if(pPropArray != NULL) {
  709. pPropArray->uType = UmiType;
  710. pPropArray->uCount = dwNumValues;
  711. }
  712. error:
  713. RRETURN(hr);
  714. }