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.

1355 lines
43 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation
  4. //
  5. // File: DfsMrshl.c
  6. //
  7. // Contents: Routines to handle marshalling of data structures. This file
  8. // has been specifically created so that user level code can
  9. // avail of the marshalling code simply by including this file.
  10. //
  11. // Classes:
  12. //
  13. // Functions:
  14. //
  15. // History: March 29, 1994 Milans created from PeterCo's routines
  16. //
  17. //-----------------------------------------------------------------------------
  18. #ifdef KERNEL_MODE
  19. #include "dfsprocs.h"
  20. #include "dfsmrshl.h"
  21. #include "dfsrtl.h"
  22. #define Dbg (DEBUG_TRACE_RTL)
  23. #else // !KERNEL_MODE
  24. #include "dfsmrshl.h"
  25. #ifndef ExRaiseStatus
  26. #define ExRaiseStatus(x) RtlRaiseStatus(x)
  27. #endif // ExRaiseStatus
  28. #ifndef try_return
  29. #define try_return(s) {s; goto try_exit;}
  30. #endif // try_return
  31. #ifndef DebugTrace
  32. #define DebugTrace(i,l,f,s)
  33. #endif // DebugTrace
  34. #endif // KERNEL_MODE
  35. NTSTATUS
  36. DfsRtlGetpwString(
  37. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  38. OUT PWSTR *ppwszString
  39. );
  40. NTSTATUS
  41. DfsRtlPutpwString(
  42. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  43. OUT PWSTR *ppwszString
  44. );
  45. NTSTATUS
  46. DfsRtlGetString(
  47. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  48. OUT PSTRING String
  49. );
  50. NTSTATUS
  51. DfsRtlPutString(
  52. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  53. OUT PSTRING String
  54. );
  55. #ifdef ALLOC_PRAGMA
  56. #pragma alloc_text( PAGE, DfsRtlGetpwString )
  57. #pragma alloc_text( PAGE, DfsRtlPutpwString )
  58. #pragma alloc_text( PAGE, DfsRtlGetString )
  59. #pragma alloc_text( PAGE, DfsRtlPutString )
  60. #pragma alloc_text( PAGE, DfsRtlGet )
  61. #pragma alloc_text( PAGE, DfsRtlPut )
  62. #pragma alloc_text( PAGE, DfsRtlSize )
  63. #pragma alloc_text( PAGE, DfsRtlUnwindGet )
  64. #endif //ALLOC_PRAGMA
  65. #define UNREFERENCED_LABEL(label)\
  66. if(0) goto label;
  67. #define DfsRtlGetUchar(MarshalBuffer, pValue) ( \
  68. ((MarshalBuffer)->Current + 1 <= (MarshalBuffer)->Last) ? \
  69. *(pValue) = (UCHAR)((MarshalBuffer)->Current[0] ), \
  70. (MarshalBuffer)->Current += 1, \
  71. STATUS_SUCCESS \
  72. : STATUS_DATA_ERROR \
  73. )
  74. #define DfsRtlPutUchar(MarshalBuffer, pValue) ( \
  75. ((MarshalBuffer)->Current + 1 <= (MarshalBuffer)->Last) ? \
  76. (MarshalBuffer)->Current[0] = BYTE_0(*pValue), \
  77. (MarshalBuffer)->Current += 1, \
  78. STATUS_SUCCESS \
  79. : STATUS_BUFFER_TOO_SMALL \
  80. )
  81. #define DfsRtlUnwindStringGet(s) { \
  82. if((s)->Length != 0 && (s)->Buffer != NULL) { \
  83. MarshalBufferFree((s)->Buffer); \
  84. (s)->Buffer = NULL; \
  85. (s)->Length = 0; \
  86. } \
  87. }
  88. #define DfsRtlUnwindUnicodeStringGet(s) \
  89. DfsRtlUnwindStringGet(s)
  90. NTSTATUS
  91. DfsRtlGetArrayUchar(
  92. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  93. IN ULONG cbArray,
  94. OUT PUCHAR pArray)
  95. {
  96. NTSTATUS status = STATUS_SUCCESS;
  97. DebugTrace(+1, Dbg, "DfsRtlGetArrayUchar: Entered\n", 0);
  98. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  99. // ASSERT(ARGUMENT_PRESENT(pArray));
  100. try {
  101. UNREFERENCED_LABEL(try_exit);
  102. if (MarshalBuffer->Current + cbArray <= MarshalBuffer->Last) {
  103. memcpy(pArray, MarshalBuffer->Current, cbArray);
  104. MarshalBuffer->Current += cbArray;
  105. } else {
  106. status = STATUS_DATA_ERROR;
  107. }
  108. try_exit: NOTHING;
  109. } finally {
  110. if (AbnormalTermination()) {
  111. DebugTrace(0, Dbg,
  112. "DfsRtlGetArrayUchar - Abnormal termination!\n", 0);
  113. status = STATUS_DATA_ERROR;
  114. }
  115. }
  116. DebugTrace(-1, Dbg, "DfsRtlGetArrayUchar: Exited %08lx\n", ULongToPtr( status ));
  117. return(status);
  118. }
  119. NTSTATUS
  120. DfsRtlPutArrayUchar(
  121. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  122. IN ULONG cbArray,
  123. OUT PUCHAR pArray)
  124. {
  125. NTSTATUS status = STATUS_SUCCESS;
  126. DebugTrace(+1, Dbg, "DfsRtlGetArrayUchar: Entered\n", 0);
  127. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  128. // ASSERT(ARGUMENT_PRESENT(pArray));
  129. try {
  130. UNREFERENCED_LABEL(try_exit);
  131. if (MarshalBuffer->Current + cbArray <= MarshalBuffer->Last) {
  132. if (cbArray) {
  133. memcpy(MarshalBuffer->Current, pArray, cbArray);
  134. MarshalBuffer->Current += cbArray;
  135. }
  136. } else {
  137. status = STATUS_BUFFER_TOO_SMALL;
  138. }
  139. try_exit: NOTHING;
  140. } finally {
  141. if (AbnormalTermination()) {
  142. DebugTrace(0, Dbg,
  143. "DfsRtlPutArrayUchar - Abnormal termination!\n", 0);
  144. status = STATUS_DATA_ERROR;
  145. }
  146. }
  147. DebugTrace(-1, Dbg, "DfsRtlPutArrayUchar: Exited %08lx\n", ULongToPtr( status ));
  148. return(status);
  149. }
  150. NTSTATUS
  151. DfsRtlGetpwString(
  152. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  153. OUT PWSTR *ppwszString
  154. )
  155. {
  156. USHORT size;
  157. PCHAR cp = NULL;
  158. NTSTATUS status = STATUS_SUCCESS;
  159. DebugTrace(+1, Dbg, "DfsRtlGetpwString: Entered\n", 0);
  160. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  161. ASSERT(ARGUMENT_PRESENT(ppwszString));
  162. try {
  163. UNREFERENCED_LABEL(try_exit);
  164. *ppwszString = NULL;
  165. if(NT_SUCCESS(status = DfsRtlGetUshort(MarshalBuffer, &size))) {
  166. if(size > 0) {
  167. if(
  168. MarshalBuffer->Current + size <= MarshalBuffer->Last &&
  169. ((ULONG)size + sizeof(WCHAR)) <= MAXUSHORT &&
  170. (size & 0x1) == 0
  171. ) {
  172. if((cp = ExAllocatePoolWithTag(
  173. PagedPool,
  174. size+sizeof(WCHAR),
  175. ' sfD')) != NULL) {
  176. memcpy(cp, MarshalBuffer->Current, size);
  177. *((WCHAR *) (cp + size)) = UNICODE_NULL;
  178. *ppwszString = (PWCHAR) cp;
  179. MarshalBuffer->Current += size;
  180. } else
  181. status = STATUS_INSUFFICIENT_RESOURCES;
  182. } else
  183. status = STATUS_DATA_ERROR;
  184. }
  185. }
  186. try_exit: NOTHING;
  187. } finally {
  188. if(AbnormalTermination()) {
  189. DebugTrace(0, Dbg,
  190. "DfsRtlGetpwString: Abnormal Termination!\n", 0);
  191. status = STATUS_DATA_ERROR;
  192. }
  193. if(!NT_SUCCESS(status) && cp)
  194. MarshalBufferFree(cp);
  195. }
  196. DebugTrace(-1, Dbg, "DfsRtlGetpwString: Exit -> %08lx\n", ULongToPtr( status ));
  197. return status;
  198. }
  199. NTSTATUS
  200. DfsRtlPutpwString(
  201. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  202. OUT PWSTR *ppwszString
  203. )
  204. {
  205. USHORT size;
  206. NTSTATUS status = STATUS_SUCCESS;
  207. DebugTrace(+1, Dbg, "DfsRtlPutpwString: Entered\n", 0);
  208. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  209. ASSERT(ARGUMENT_PRESENT(ppwszString));
  210. try {
  211. UNREFERENCED_LABEL(try_exit);
  212. if (*ppwszString != NULL)
  213. size = wcslen(*ppwszString)*sizeof(WCHAR);
  214. else
  215. size = 0;
  216. if(NT_SUCCESS(status = DfsRtlPutUshort(MarshalBuffer, &size))) {
  217. if(size > 0) {
  218. if(MarshalBuffer->Current + size <= MarshalBuffer->Last) {
  219. memcpy(MarshalBuffer->Current, *ppwszString, size);
  220. MarshalBuffer->Current += size;
  221. } else
  222. status = STATUS_BUFFER_TOO_SMALL;
  223. }
  224. }
  225. try_exit: NOTHING;
  226. } finally {
  227. if(AbnormalTermination()) {
  228. DebugTrace(0, Dbg,
  229. "DfsRtlPutString: Abnormal Termination!\n", 0);
  230. status = STATUS_DATA_ERROR;
  231. }
  232. }
  233. DebugTrace(-1, Dbg, "DfsRtlPutString: Exit -> %08lx\n", ULongToPtr( status ));
  234. return status;
  235. }
  236. NTSTATUS
  237. DfsRtlGetString(
  238. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  239. OUT PSTRING String
  240. )
  241. {
  242. USHORT size;
  243. PCHAR cp = NULL;
  244. NTSTATUS status = STATUS_SUCCESS;
  245. DebugTrace(+1, Dbg, "DfsRtlGetString: Entered\n", 0);
  246. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  247. ASSERT(ARGUMENT_PRESENT(String));
  248. try {
  249. UNREFERENCED_LABEL(try_exit);
  250. String->Length = String->MaximumLength = 0;
  251. String->Buffer = NULL;
  252. if(NT_SUCCESS(status = DfsRtlGetUshort(MarshalBuffer, &size))) {
  253. if(size > 0) {
  254. if(
  255. MarshalBuffer->Current + size <= MarshalBuffer->Last &&
  256. ((ULONG)size + sizeof(WCHAR)) <= MAXUSHORT &&
  257. (size & 0x1) == 0
  258. ) {
  259. if((cp = ExAllocatePoolWithTag(
  260. PagedPool,
  261. size+sizeof(WCHAR),
  262. ' sfD')) != NULL) {
  263. RtlZeroMemory(cp, size+sizeof(WCHAR));
  264. memcpy(cp, MarshalBuffer->Current, size);
  265. String->Length = (USHORT)size;
  266. String->MaximumLength = size + sizeof(WCHAR);
  267. String->Buffer = cp;
  268. MarshalBuffer->Current += size;
  269. } else
  270. status = STATUS_INSUFFICIENT_RESOURCES;
  271. } else
  272. status = STATUS_DATA_ERROR;
  273. }
  274. }
  275. try_exit: NOTHING;
  276. } finally {
  277. if(AbnormalTermination()) {
  278. DebugTrace(0, Dbg,
  279. "DfsRtlGetString: Abnormal Termination!\n", 0);
  280. status = STATUS_DATA_ERROR;
  281. }
  282. if(!NT_SUCCESS(status) && cp)
  283. MarshalBufferFree(cp);
  284. }
  285. DebugTrace(-1, Dbg, "DfsRtlGetString: Exit -> %08lx\n", ULongToPtr( status ));
  286. return status;
  287. }
  288. NTSTATUS
  289. DfsRtlPutString(
  290. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  291. OUT PSTRING String
  292. )
  293. {
  294. USHORT size;
  295. NTSTATUS status = STATUS_SUCCESS;
  296. DebugTrace(+1, Dbg, "DfsRtlPutString: Entered\n", 0);
  297. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  298. ASSERT(ARGUMENT_PRESENT(String));
  299. try {
  300. UNREFERENCED_LABEL(try_exit);
  301. size = String->Length;
  302. if(NT_SUCCESS(status = DfsRtlPutUshort(MarshalBuffer, &size))) {
  303. if(size > 0) {
  304. if(MarshalBuffer->Current + size <= MarshalBuffer->Last) {
  305. if(String->Buffer != NULL) {
  306. memcpy(MarshalBuffer->Current, String->Buffer, size);
  307. MarshalBuffer->Current += size;
  308. } else
  309. status = STATUS_DATA_ERROR;
  310. } else
  311. status = STATUS_BUFFER_TOO_SMALL;
  312. }
  313. }
  314. try_exit: NOTHING;
  315. } finally {
  316. if(AbnormalTermination()) {
  317. DebugTrace(0, Dbg,
  318. "DfsRtlPutString: Abnormal Termination!\n", 0);
  319. status = STATUS_DATA_ERROR;
  320. }
  321. }
  322. DebugTrace(-1, Dbg, "DfsRtlPutString: Exit -> %08lx\n", ULongToPtr( status ));
  323. return status;
  324. }
  325. #ifdef NOT_NEEDED
  326. NTSTATUS
  327. DfsRtlGetUnicodeString(
  328. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  329. OUT PUNICODE_STRING UnicodeString
  330. )
  331. {
  332. USHORT size;
  333. PWCHAR wcp = NULL;
  334. NTSTATUS status = STATUS_SUCCESS;
  335. DebugTrace(+1, Dbg, "DfsRtlGetUnicodeString: Entered\n", 0);
  336. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  337. ASSERT(ARGUMENT_PRESENT(UnicodeString));
  338. try {
  339. UnicodeString->Length = UnicodeString->MaximumLength = 0;
  340. UnicodeString->Buffer = NULL;
  341. if(NT_SUCCESS(status = DfsRtlGetUshort(MarshalBuffer, &size))) {
  342. if(size > 0) {
  343. if(
  344. MarshalBuffer->Current + size <= MarshalBuffer->Last &&
  345. ((ULONG)size + sizeof(WCHAR)) <= MAXUSHORT &&
  346. (size & 0x1) == 0
  347. ) {
  348. if((wcp = (ExAllocatePoolWithTag)(
  349. PagedPool,
  350. size+sizeof(WCHAR)
  351. ' sfD')) != NULL) {
  352. memcpy(wcp, MarshalBuffer->Current, size);
  353. wcp[size/sizeof(WCHAR)] = UNICODE_NULL;
  354. UnicodeString->Length = size;
  355. UnicodeString->MaximumLength = size + sizeof(WCHAR);
  356. UnicodeString->Buffer = wcp;
  357. MarshalBuffer->Current += size;
  358. } else
  359. status = STATUS_INSUFFICIENT_RESOURCES;
  360. } else
  361. status = STATUS_DATA_ERROR;
  362. }
  363. }
  364. try_exit: NOTHING;
  365. } finally {
  366. if(AbnormalTermination()) {
  367. DebugTrace(0, Dbg,
  368. "DfsRtlGetUnicodeString: Abnormal Termination!\n", 0);
  369. status = STATUS_DATA_ERROR;
  370. }
  371. if(!NT_SUCCESS(status) && wcp)
  372. MarshalBufferFree(wcp);
  373. }
  374. DebugTrace(-1, Dbg, "DfsRtlGetUnicodeString: Exit -> %08lx\n",
  375. status);
  376. return status;
  377. }
  378. NTSTATUS
  379. DfsRtlPutUnicodeString(
  380. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  381. OUT PUNICODE_STRING UnicodeString
  382. )
  383. {
  384. USHORT size;
  385. NTSTATUS status = STATUS_SUCCESS;
  386. DebugTrace(+1, Dbg, "DfsRtlPutUnicodeString: Entered\n", 0);
  387. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  388. ASSERT(ARGUMENT_PRESENT(UnicodeString));
  389. try {
  390. size = UnicodeString->Length;
  391. if(NT_SUCCESS(status = DfsRtlPutUshort(MarshalBuffer, &size))) {
  392. if(size > 0) {
  393. if(MarshalBuffer->Current + size <= MarshalBuffer->Last) {
  394. if(UnicodeString->Buffer != NULL) {
  395. memcpy(
  396. MarshalBuffer->Current,
  397. UnicodeString->Buffer,
  398. size
  399. );
  400. MarshalBuffer->Current += size;
  401. } else
  402. status = STATUS_DATA_ERROR;
  403. } else
  404. status = STATUS_BUFFER_TOO_SMALL;
  405. }
  406. }
  407. try_exit: NOTHING;
  408. } finally {
  409. if(AbnormalTermination()) {
  410. DebugTrace(0, Dbg,
  411. "DfsRtlPutUnicodeString: Abnormal Termination!\n", 0);
  412. status = STATUS_DATA_ERROR;
  413. }
  414. }
  415. DebugTrace(-1, Dbg, "DfsRtlPutUnicodeString: Exit -> %08lx\n",
  416. status);
  417. return status;
  418. }
  419. #else // NOT_NEEDED
  420. #define DfsRtlGetUnicodeString(b, s)\
  421. DfsRtlGetString(b, (PSTRING)(s))
  422. #define DfsRtlPutUnicodeString(b, s)\
  423. DfsRtlPutString(b, (PSTRING)(s))
  424. #endif // NOT_NEEDED
  425. NTSTATUS
  426. DfsRtlGet(
  427. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  428. IN PMARSHAL_INFO MarshalInfo,
  429. OUT PVOID Item
  430. )
  431. {
  432. PMARSHAL_TYPE_INFO typeInfo;
  433. PVOID subItem;
  434. PVOID subItemElem;
  435. ULONG cnt;
  436. ULONG unwindcnt;
  437. PUCHAR cntptr;
  438. ULONG itemSize;
  439. PMARSHAL_INFO subInfo;
  440. NTSTATUS status = STATUS_SUCCESS;
  441. DebugTrace(+1, Dbg, "DfsRtlGet: Entered\n", 0);
  442. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  443. ASSERT(ARGUMENT_PRESENT(MarshalInfo));
  444. ASSERT(ARGUMENT_PRESENT(Item));
  445. try {
  446. RtlZeroMemory(Item, MarshalInfo->_size);
  447. for(typeInfo = &MarshalInfo->_typeInfo[0];
  448. typeInfo < &MarshalInfo->_typeInfo[MarshalInfo->_typecnt];
  449. typeInfo++) {
  450. switch(typeInfo->_type & MTYPE_BASE_TYPE) {
  451. case MTYPE_COMPOUND:
  452. subInfo = typeInfo->_subinfo;
  453. itemSize = subInfo->_size;
  454. //
  455. // If this compound type is a conformant structure, then
  456. // we need to adjust the size field here.
  457. //
  458. if (subInfo->_typecnt > 0 &&
  459. subInfo->_typeInfo[0]._type == MTYPE_CONFORMANT_CNT) {
  460. MARSHAL_BUFFER tempMarshalBuffer = *MarshalBuffer;
  461. ULONG extraSize = 0;
  462. status = DfsRtlGetUlong(&tempMarshalBuffer, &extraSize);
  463. if (!NT_SUCCESS(status) || (itemSize + extraSize) < itemSize) {
  464. try_return(status = STATUS_DATA_ERROR);
  465. }
  466. itemSize += extraSize;
  467. }
  468. break;
  469. case MTYPE_CONFORMANT_CNT:
  470. itemSize = 0;
  471. break;
  472. case MTYPE_GUID:
  473. itemSize = sizeof(GUID);
  474. break;
  475. case MTYPE_STRING:
  476. itemSize = sizeof(STRING);
  477. break;
  478. case MTYPE_UNICODE_STRING:
  479. itemSize = sizeof(UNICODE_STRING);
  480. break;
  481. case MTYPE_PWSTR:
  482. itemSize = sizeof(PWSTR);
  483. break;
  484. case MTYPE_ULONG:
  485. itemSize = sizeof(ULONG);
  486. break;
  487. case MTYPE_USHORT:
  488. itemSize = sizeof(USHORT);
  489. break;
  490. case MTYPE_UCHAR:
  491. itemSize = sizeof(UCHAR);
  492. break;
  493. default:
  494. try_return(status = STATUS_DATA_ERROR);
  495. }
  496. if(typeInfo->_type & MTYPE_COUNTED_ARRAY) {
  497. cntptr = ((PUCHAR)Item + typeInfo->_cntoff);
  498. switch(typeInfo->_cntsize) {
  499. case sizeof(UCHAR):
  500. cnt = *(PUCHAR)cntptr;
  501. break;
  502. case sizeof(USHORT):
  503. cnt = *(PUSHORT)cntptr;
  504. break;
  505. case sizeof(ULONG):
  506. cnt = *(PULONG)cntptr;
  507. break;
  508. default:
  509. try_return(status = STATUS_DATA_ERROR);
  510. }
  511. } else if (typeInfo->_type & MTYPE_STATIC_ARRAY) {
  512. cnt = typeInfo->_cntoff;
  513. } else {
  514. cnt = 1;
  515. }
  516. if(typeInfo->_type & MTYPE_INDIRECT) {
  517. if((typeInfo->_type & MTYPE_COUNTED_ARRAY) && cnt == 0)
  518. subItem = NULL;
  519. else {
  520. subItem = NULL;
  521. if ((cnt != 0) && ((itemSize * cnt) / cnt) == itemSize)
  522. subItem = ExAllocatePoolWithTag(
  523. PagedPool,
  524. itemSize * cnt,
  525. ' sfD');
  526. if(subItem == NULL)
  527. try_return(status = STATUS_INSUFFICIENT_RESOURCES);
  528. }
  529. *(PVOID *)((PUCHAR)Item + typeInfo->_off) = subItem;
  530. }
  531. else
  532. subItem = ((PUCHAR)Item + typeInfo->_off);
  533. switch(typeInfo->_type & ~MTYPE_INDIRECT) {
  534. case MTYPE_COMPOUND:
  535. status = DfsRtlGet(
  536. MarshalBuffer,
  537. subInfo,
  538. subItem
  539. );
  540. break;
  541. case MTYPE_CONFORMANT_CNT:
  542. //
  543. // this field is used only when sizing a conformant
  544. // structure. As such, there is no place to unmarshal
  545. // it into. So, simply eat the ulong.
  546. //
  547. status = DfsRtlGetUlong(MarshalBuffer, &itemSize);
  548. break;
  549. case (MTYPE_COMPOUND|MTYPE_COUNTED_ARRAY):
  550. case (MTYPE_COMPOUND|MTYPE_STATIC_ARRAY):
  551. subItemElem = (PUCHAR)subItem;
  552. unwindcnt = cnt;
  553. while(cnt--) {
  554. status = DfsRtlGet(
  555. MarshalBuffer,
  556. subInfo,
  557. subItemElem
  558. );
  559. if(!NT_SUCCESS(status)) {
  560. while((++cnt) < unwindcnt) {
  561. ((PUCHAR)subItemElem) -= itemSize;
  562. DfsRtlUnwindGet(
  563. subInfo,
  564. &subInfo->_typeInfo[subInfo->_typecnt],
  565. subItemElem
  566. );
  567. }
  568. if(typeInfo->_type & MTYPE_INDIRECT)
  569. MarshalBufferFree(subItem);
  570. break;
  571. }
  572. ((PUCHAR)subItemElem) += itemSize;
  573. }
  574. break;
  575. case MTYPE_GUID:
  576. status = DfsRtlGetGuid(
  577. MarshalBuffer,
  578. (GUID *)subItem
  579. );
  580. break;
  581. case MTYPE_STRING:
  582. status = DfsRtlGetString(
  583. MarshalBuffer,
  584. (PSTRING)subItem
  585. );
  586. break;
  587. case MTYPE_UNICODE_STRING:
  588. status = DfsRtlGetUnicodeString(
  589. MarshalBuffer,
  590. (PUNICODE_STRING)subItem
  591. );
  592. break;
  593. case MTYPE_PWSTR:
  594. status = DfsRtlGetpwString(
  595. MarshalBuffer,
  596. (PWSTR *)subItem
  597. );
  598. break;
  599. case (MTYPE_PWSTR|MTYPE_COUNTED_ARRAY):
  600. case (MTYPE_PWSTR|MTYPE_STATIC_ARRAY):
  601. subItemElem = (PUCHAR)subItem;
  602. unwindcnt = cnt;
  603. while (cnt--) {
  604. status = DfsRtlGetpwString(
  605. MarshalBuffer,
  606. (PWSTR *)subItemElem);
  607. if (!NT_SUCCESS(status)) {
  608. while ((++cnt) < unwindcnt) {
  609. ((PUCHAR)subItemElem) -= itemSize;
  610. MarshalBufferFree((PVOID)*(PWSTR *)subItemElem);
  611. }
  612. if (typeInfo->_type & MTYPE_INDIRECT) {
  613. MarshalBufferFree(subItem);
  614. }
  615. break;
  616. }
  617. ((PUCHAR)subItemElem) += itemSize;
  618. }
  619. break;
  620. case (MTYPE_UNICODE_STRING|MTYPE_COUNTED_ARRAY):
  621. case (MTYPE_UNICODE_STRING|MTYPE_STATIC_ARRAY):
  622. subItemElem = (PUCHAR)subItem;
  623. unwindcnt = cnt;
  624. while(cnt--) {
  625. status = DfsRtlGetUnicodeString(
  626. MarshalBuffer,
  627. (PUNICODE_STRING)subItemElem
  628. );
  629. if(!NT_SUCCESS(status)) {
  630. while((++cnt) < unwindcnt) {
  631. ((PUCHAR)subItemElem) -= itemSize;
  632. DfsRtlUnwindUnicodeStringGet(
  633. (PUNICODE_STRING)subItemElem
  634. );
  635. }
  636. if(typeInfo->_type & MTYPE_INDIRECT)
  637. MarshalBufferFree(subItem);
  638. break;
  639. }
  640. ((PUCHAR)subItemElem) += itemSize;
  641. }
  642. break;
  643. case MTYPE_ULONG:
  644. status = DfsRtlGetUlong(
  645. MarshalBuffer,
  646. (PULONG)subItem
  647. );
  648. break;
  649. case MTYPE_USHORT:
  650. status = DfsRtlGetUshort(
  651. MarshalBuffer,
  652. (PUSHORT)subItem);
  653. break;
  654. case MTYPE_UCHAR:
  655. status = DfsRtlGetUchar(
  656. MarshalBuffer,
  657. (PUCHAR)subItem);
  658. break;
  659. case MTYPE_UCHAR|MTYPE_COUNTED_ARRAY:
  660. case MTYPE_UCHAR|MTYPE_STATIC_ARRAY:
  661. status = DfsRtlGetArrayUchar(
  662. MarshalBuffer,
  663. cnt,
  664. (PUCHAR)subItem);
  665. break;
  666. default:
  667. status = STATUS_DATA_ERROR;
  668. break;
  669. };
  670. if(!NT_SUCCESS(status))
  671. break;
  672. }
  673. try_exit: NOTHING;
  674. } finally {
  675. if(AbnormalTermination()) {
  676. DebugTrace(0, Dbg, "DfsRtlGet: Abnormal Termination!\n", 0);
  677. status = STATUS_DATA_ERROR;
  678. }
  679. if(!NT_SUCCESS(status))
  680. DfsRtlUnwindGet(MarshalInfo, typeInfo, Item);
  681. }
  682. DebugTrace(-1, Dbg, "DfsRtlGet: Exit -> %08lx\n", ULongToPtr( status ));
  683. return status;
  684. }
  685. NTSTATUS
  686. DfsRtlPut(
  687. IN OUT PMARSHAL_BUFFER MarshalBuffer,
  688. IN PMARSHAL_INFO MarshalInfo,
  689. OUT PVOID Item
  690. )
  691. {
  692. PMARSHAL_TYPE_INFO typeInfo;
  693. PVOID subItem;
  694. PVOID subItemElem;
  695. ULONG cnt;
  696. PUCHAR cntptr;
  697. ULONG itemSize;
  698. PMARSHAL_INFO subInfo;
  699. NTSTATUS status = STATUS_SUCCESS;
  700. DebugTrace(+1, Dbg, "DfsRtlPut: Entered\n", 0);
  701. ASSERT(ARGUMENT_PRESENT(MarshalBuffer));
  702. ASSERT(ARGUMENT_PRESENT(MarshalInfo));
  703. ASSERT(ARGUMENT_PRESENT(Item));
  704. try {
  705. for(typeInfo = &MarshalInfo->_typeInfo[0];
  706. typeInfo < &MarshalInfo->_typeInfo[MarshalInfo->_typecnt];
  707. typeInfo++) {
  708. switch(typeInfo->_type & MTYPE_BASE_TYPE) {
  709. case MTYPE_COMPOUND:
  710. subInfo = typeInfo->_subinfo;
  711. itemSize = subInfo->_size;
  712. break;
  713. case MTYPE_CONFORMANT_CNT:
  714. itemSize = typeInfo->_off;
  715. break;
  716. case MTYPE_GUID:
  717. itemSize = sizeof(GUID);
  718. break;
  719. case MTYPE_STRING:
  720. itemSize = sizeof(STRING);
  721. break;
  722. case MTYPE_UNICODE_STRING:
  723. itemSize = sizeof(UNICODE_STRING);
  724. break;
  725. case MTYPE_PWSTR:
  726. itemSize = sizeof(PWSTR);
  727. break;
  728. case MTYPE_ULONG:
  729. itemSize = sizeof(ULONG);
  730. break;
  731. case MTYPE_USHORT:
  732. itemSize = sizeof(USHORT);
  733. break;
  734. case MTYPE_UCHAR:
  735. itemSize = sizeof(UCHAR);
  736. break;
  737. default:
  738. try_return(status = STATUS_DATA_ERROR);
  739. }
  740. if(typeInfo->_type & MTYPE_COUNTED_ARRAY ||
  741. typeInfo->_type == MTYPE_CONFORMANT_CNT) {
  742. cntptr = ((PUCHAR)Item + typeInfo->_cntoff);
  743. switch(typeInfo->_cntsize) {
  744. case sizeof(UCHAR):
  745. cnt = *(PUCHAR)cntptr;
  746. break;
  747. case sizeof(USHORT):
  748. cnt = *(PUSHORT)cntptr;
  749. break;
  750. case sizeof(ULONG):
  751. cnt = *(PULONG)cntptr;
  752. break;
  753. default:
  754. try_return(status = STATUS_DATA_ERROR);
  755. }
  756. } else
  757. cnt = typeInfo->_cntoff;
  758. if(typeInfo->_type & MTYPE_INDIRECT) {
  759. subItem = *(PUCHAR *)((PUCHAR)Item + typeInfo->_off);
  760. if(subItem == NULL &&
  761. !((typeInfo->_type & MTYPE_COUNTED_ARRAY) && cnt == 0))
  762. try_return(status = STATUS_DATA_ERROR);
  763. } else
  764. subItem = ((PUCHAR)Item + typeInfo->_off);
  765. switch(typeInfo->_type & ~MTYPE_INDIRECT) {
  766. case MTYPE_COMPOUND:
  767. status = DfsRtlPut(
  768. MarshalBuffer,
  769. subInfo,
  770. subItem
  771. );
  772. break;
  773. case MTYPE_CONFORMANT_CNT:
  774. cnt *= itemSize;
  775. status = DfsRtlPutUlong(
  776. MarshalBuffer,
  777. &cnt);
  778. break;
  779. case (MTYPE_COMPOUND|MTYPE_COUNTED_ARRAY):
  780. case (MTYPE_COMPOUND|MTYPE_STATIC_ARRAY):
  781. //
  782. // No sense in having an array of conformant structures
  783. // ASSERT this fact
  784. //
  785. ASSERT(subInfo->_typecnt == 0
  786. ||
  787. subInfo->_typeInfo[0]._type != MTYPE_CONFORMANT_CNT
  788. );
  789. subItemElem = (PUCHAR)subItem;
  790. while(cnt--) {
  791. status = DfsRtlPut(
  792. MarshalBuffer,
  793. subInfo,
  794. subItemElem
  795. );
  796. if(!NT_SUCCESS(status))
  797. break;
  798. ((PUCHAR)subItemElem) += itemSize;
  799. }
  800. break;
  801. case MTYPE_GUID:
  802. status = DfsRtlPutGuid(
  803. MarshalBuffer,
  804. (GUID *)subItem
  805. );
  806. break;
  807. case MTYPE_STRING:
  808. status = DfsRtlPutString(
  809. MarshalBuffer,
  810. (PSTRING)subItem
  811. );
  812. break;
  813. case MTYPE_UNICODE_STRING:
  814. status = DfsRtlPutUnicodeString(
  815. MarshalBuffer,
  816. (PUNICODE_STRING)subItem
  817. );
  818. break;
  819. case MTYPE_PWSTR:
  820. status = DfsRtlPutpwString(
  821. MarshalBuffer,
  822. (PWSTR *)subItem
  823. );
  824. break;
  825. case (MTYPE_PWSTR|MTYPE_COUNTED_ARRAY):
  826. case (MTYPE_PWSTR|MTYPE_STATIC_ARRAY):
  827. subItemElem = (PWSTR *)subItem;
  828. while(cnt--) {
  829. status = DfsRtlPutpwString(
  830. MarshalBuffer,
  831. (PWSTR *)subItemElem);
  832. if (!NT_SUCCESS(status))
  833. break;
  834. ((PUCHAR)subItemElem) += itemSize;
  835. }
  836. break;
  837. case (MTYPE_UNICODE_STRING|MTYPE_COUNTED_ARRAY):
  838. case (MTYPE_UNICODE_STRING|MTYPE_STATIC_ARRAY):
  839. subItemElem = (PUCHAR)subItem;
  840. while(cnt--) {
  841. status = DfsRtlPutUnicodeString(
  842. MarshalBuffer,
  843. (PUNICODE_STRING)subItemElem
  844. );
  845. if(!NT_SUCCESS(status))
  846. break;
  847. ((PUCHAR)subItemElem) += itemSize;
  848. }
  849. break;
  850. case MTYPE_ULONG:
  851. status = DfsRtlPutUlong(
  852. MarshalBuffer,
  853. (PULONG)subItem
  854. );
  855. break;
  856. case MTYPE_USHORT:
  857. status = DfsRtlPutUshort(
  858. MarshalBuffer,
  859. (PUSHORT)subItem);
  860. break;
  861. case MTYPE_UCHAR:
  862. status = DfsRtlPutUchar(
  863. MarshalBuffer,
  864. (PUCHAR)subItem);
  865. break;
  866. case (MTYPE_UCHAR|MTYPE_COUNTED_ARRAY):
  867. case (MTYPE_UCHAR|MTYPE_STATIC_ARRAY):
  868. status = DfsRtlPutArrayUchar(
  869. MarshalBuffer,
  870. cnt,
  871. (PUCHAR)subItem);
  872. break;
  873. default:
  874. status = STATUS_DATA_ERROR;
  875. break;
  876. }
  877. if(!NT_SUCCESS(status))
  878. break;
  879. }
  880. try_exit: NOTHING;
  881. } finally {
  882. if(AbnormalTermination()) {
  883. DebugTrace(0, Dbg, "DfsRtlPut: Abnormal Termination!\n", 0);
  884. status = STATUS_DATA_ERROR;
  885. }
  886. }
  887. DebugTrace(-1, Dbg, "DfsRtlPut: Exit -> %08lx\n", ULongToPtr( status ));
  888. return status;
  889. }
  890. NTSTATUS
  891. DfsRtlSize(
  892. IN PMARSHAL_INFO MarshalInfo,
  893. IN PVOID Item,
  894. OUT PULONG Size
  895. )
  896. {
  897. PMARSHAL_TYPE_INFO typeInfo;
  898. PVOID subItem;
  899. PVOID subItemElem;
  900. ULONG cnt;
  901. PUCHAR cntptr;
  902. ULONG itemSize;
  903. PMARSHAL_INFO subInfo;
  904. NTSTATUS status = STATUS_SUCCESS;
  905. DebugTrace(+1, Dbg, "DfsRtlSize: Entered\n", 0);
  906. ASSERT(ARGUMENT_PRESENT(MarshalInfo));
  907. ASSERT(ARGUMENT_PRESENT(Item));
  908. ASSERT(ARGUMENT_PRESENT(Size));
  909. try {
  910. for(typeInfo = &MarshalInfo->_typeInfo[0];
  911. typeInfo < &MarshalInfo->_typeInfo[MarshalInfo->_typecnt];
  912. typeInfo++) {
  913. switch(typeInfo->_type & MTYPE_BASE_TYPE) {
  914. case MTYPE_COMPOUND:
  915. subInfo = typeInfo->_subinfo;
  916. itemSize = subInfo->_size;
  917. break;
  918. case MTYPE_CONFORMANT_CNT:
  919. //
  920. // For conformant structures, _offset is sizeof each
  921. // element, _cntsize is sizeof cnt field, and _cntoff is
  922. // offset of cnt field.
  923. //
  924. itemSize = typeInfo->_off;
  925. break;
  926. case MTYPE_GUID:
  927. itemSize = sizeof(GUID);
  928. break;
  929. case MTYPE_STRING:
  930. itemSize = sizeof(STRING);
  931. break;
  932. case MTYPE_UNICODE_STRING:
  933. itemSize = sizeof(UNICODE_STRING);
  934. break;
  935. case MTYPE_PWSTR:
  936. itemSize = sizeof(PWCHAR);
  937. break;
  938. case MTYPE_ULONG:
  939. itemSize = sizeof(ULONG);
  940. break;
  941. case MTYPE_USHORT:
  942. itemSize = sizeof(USHORT);
  943. break;
  944. case MTYPE_UCHAR:
  945. itemSize = sizeof(UCHAR);
  946. break;
  947. default:
  948. try_return(status = STATUS_DATA_ERROR);
  949. }
  950. if(typeInfo->_type & MTYPE_COUNTED_ARRAY ||
  951. typeInfo->_type == MTYPE_CONFORMANT_CNT) {
  952. cntptr = ((PUCHAR)Item + typeInfo->_cntoff);
  953. switch(typeInfo->_cntsize) {
  954. case sizeof(UCHAR):
  955. cnt = *(PUCHAR)cntptr;
  956. break;
  957. case sizeof(USHORT):
  958. cnt = *(PUSHORT)cntptr;
  959. break;
  960. case sizeof(ULONG):
  961. cnt = *(PULONG)cntptr;
  962. break;
  963. default:
  964. try_return(status = STATUS_DATA_ERROR);
  965. }
  966. } else
  967. cnt = typeInfo->_cntoff;
  968. if(typeInfo->_type & MTYPE_INDIRECT) {
  969. subItem = *(PUCHAR *)((PUCHAR)Item + typeInfo->_off);
  970. if(subItem == NULL &&
  971. !((typeInfo->_type & MTYPE_COUNTED_ARRAY) && cnt == 0))
  972. try_return(status = STATUS_DATA_ERROR);
  973. } else
  974. subItem = ((PUCHAR)Item + typeInfo->_off);
  975. switch(typeInfo->_type & ~MTYPE_INDIRECT) {
  976. case MTYPE_COMPOUND:
  977. status = DfsRtlSize(
  978. subInfo,
  979. subItem,
  980. Size
  981. );
  982. break;
  983. case MTYPE_CONFORMANT_CNT:
  984. (*Size) += sizeof(ULONG);
  985. break;
  986. case (MTYPE_COMPOUND|MTYPE_COUNTED_ARRAY):
  987. case (MTYPE_COMPOUND|MTYPE_STATIC_ARRAY):
  988. //
  989. // No sense in having an array of conformant structures
  990. // ASSERT this fact
  991. //
  992. ASSERT(subInfo->_typecnt == 0
  993. ||
  994. subInfo->_typeInfo[0]._type != MTYPE_CONFORMANT_CNT
  995. );
  996. subItemElem = (PUCHAR)subItem;
  997. while(cnt--) {
  998. status = DfsRtlSize(
  999. subInfo,
  1000. subItemElem,
  1001. Size
  1002. );
  1003. if(!NT_SUCCESS(status))
  1004. break;
  1005. ((PUCHAR)subItemElem) += itemSize;
  1006. }
  1007. break;
  1008. case MTYPE_GUID:
  1009. (*Size) += 16;
  1010. break;
  1011. case MTYPE_STRING:
  1012. status = DfsRtlSizeString(
  1013. (PSTRING)subItem,
  1014. Size
  1015. );
  1016. break;
  1017. case MTYPE_UNICODE_STRING:
  1018. status = DfsRtlSizeUnicodeString(
  1019. (PUNICODE_STRING)subItem,
  1020. Size
  1021. );
  1022. break;
  1023. case MTYPE_PWSTR:
  1024. status = DfsRtlSizepwString(
  1025. (PWSTR *)subItem,
  1026. Size
  1027. );
  1028. break;
  1029. case (MTYPE_PWSTR|MTYPE_COUNTED_ARRAY):
  1030. case (MTYPE_PWSTR|MTYPE_STATIC_ARRAY):
  1031. subItemElem = (PUCHAR)subItem;
  1032. while (cnt--) {
  1033. status = DfsRtlSizepwString(
  1034. (PWSTR *)subItemElem,
  1035. Size);
  1036. if (!NT_SUCCESS(status)) {
  1037. break;
  1038. }
  1039. ((PUCHAR)subItemElem) += itemSize;
  1040. }
  1041. break;
  1042. case (MTYPE_UNICODE_STRING|MTYPE_COUNTED_ARRAY):
  1043. case (MTYPE_UNICODE_STRING|MTYPE_STATIC_ARRAY):
  1044. subItemElem = (PUCHAR)subItem;
  1045. while(cnt--) {
  1046. status = DfsRtlSizeUnicodeString(
  1047. (PUNICODE_STRING)subItemElem,
  1048. Size
  1049. );
  1050. if(!NT_SUCCESS(status))
  1051. break;
  1052. ((PUCHAR)subItemElem) += itemSize;
  1053. }
  1054. break;
  1055. case MTYPE_ULONG:
  1056. (*Size) += 4;
  1057. break;
  1058. case MTYPE_USHORT:
  1059. (*Size) += 2;
  1060. break;
  1061. case MTYPE_UCHAR:
  1062. (*Size) += 1;
  1063. break;
  1064. case MTYPE_UCHAR|MTYPE_COUNTED_ARRAY:
  1065. case MTYPE_UCHAR|MTYPE_STATIC_ARRAY:
  1066. (*Size) += (cnt * sizeof(UCHAR));
  1067. break;
  1068. default:
  1069. status = STATUS_DATA_ERROR;
  1070. break;
  1071. };
  1072. if(!NT_SUCCESS(status))
  1073. break;
  1074. }
  1075. try_exit: NOTHING;
  1076. } finally {
  1077. if(AbnormalTermination()) {
  1078. DebugTrace(0, Dbg, "DfsRtlSize: Abnormal Termination!\n", 0);
  1079. status = STATUS_DATA_ERROR;
  1080. }
  1081. }
  1082. DebugTrace(0, Dbg, "DfsRtlSize: (*Size) = %ld\n", ULongToPtr( (*Size) ));
  1083. DebugTrace(-1, Dbg, "DfsRtlSize: Exit -> %08lx\n", ULongToPtr( status ));
  1084. return status;
  1085. }
  1086. VOID
  1087. DfsRtlUnwindGet(
  1088. IN PMARSHAL_INFO MarshalInfo,
  1089. IN PMARSHAL_TYPE_INFO LastTypeInfo,
  1090. IN PVOID Item
  1091. )
  1092. {
  1093. PMARSHAL_TYPE_INFO typeInfo;
  1094. PVOID subItem;
  1095. PVOID subItemElem;
  1096. ULONG cnt;
  1097. PUCHAR cntptr;
  1098. ULONG itemSize;
  1099. PMARSHAL_INFO subInfo;
  1100. NTSTATUS status = STATUS_SUCCESS;
  1101. DebugTrace(+1, Dbg, "DfsRtlUnwindGet: Entered\n", 0);
  1102. for(typeInfo = &MarshalInfo->_typeInfo[0];
  1103. typeInfo < LastTypeInfo;
  1104. typeInfo++) {
  1105. switch(typeInfo->_type & MTYPE_BASE_TYPE) {
  1106. case MTYPE_COMPOUND:
  1107. subInfo = typeInfo->_subinfo;
  1108. itemSize = subInfo->_size;
  1109. break;
  1110. case MTYPE_GUID:
  1111. itemSize = sizeof(GUID);
  1112. break;
  1113. case MTYPE_STRING:
  1114. itemSize = sizeof(STRING);
  1115. break;
  1116. case MTYPE_UNICODE_STRING:
  1117. itemSize = sizeof(UNICODE_STRING);
  1118. break;
  1119. case MTYPE_ULONG:
  1120. itemSize = sizeof(ULONG);
  1121. break;
  1122. case MTYPE_USHORT:
  1123. itemSize = sizeof(USHORT);
  1124. break;
  1125. case MTYPE_UCHAR:
  1126. itemSize = sizeof(UCHAR);
  1127. break;
  1128. default:
  1129. ExRaiseStatus(STATUS_DATA_ERROR);
  1130. }
  1131. if(typeInfo->_type & MTYPE_COUNTED_ARRAY) {
  1132. cntptr = ((PUCHAR)Item + typeInfo->_cntoff);
  1133. switch(typeInfo->_cntsize) {
  1134. case sizeof(UCHAR):
  1135. cnt = *(PUCHAR)cntptr;
  1136. break;
  1137. case sizeof(USHORT):
  1138. cnt = *(PUSHORT)cntptr;
  1139. break;
  1140. case sizeof(ULONG):
  1141. cnt = *(PULONG)cntptr;
  1142. break;
  1143. default:
  1144. ExRaiseStatus(STATUS_DATA_ERROR);
  1145. }
  1146. } else
  1147. cnt = typeInfo->_cntoff;
  1148. if(typeInfo->_type & MTYPE_INDIRECT) {
  1149. subItem = *(PUCHAR *)((PUCHAR)Item + typeInfo->_off);
  1150. if(subItem == NULL &&
  1151. !((typeInfo->_type & MTYPE_COUNTED_ARRAY) && cnt == 0))
  1152. ExRaiseStatus(STATUS_DATA_ERROR);
  1153. } else
  1154. subItem = ((PUCHAR)Item + typeInfo->_off);
  1155. switch(typeInfo->_type & ~MTYPE_INDIRECT) {
  1156. case MTYPE_COMPOUND:
  1157. DfsRtlUnwindGet(
  1158. subInfo,
  1159. &subInfo->_typeInfo[subInfo->_typecnt],
  1160. subItem
  1161. );
  1162. break;
  1163. case (MTYPE_COMPOUND|MTYPE_COUNTED_ARRAY):
  1164. case (MTYPE_COMPOUND|MTYPE_STATIC_ARRAY):
  1165. subItemElem = (PUCHAR)subItem;
  1166. while(cnt--) {
  1167. DfsRtlUnwindGet(
  1168. subInfo,
  1169. &subInfo->_typeInfo[subInfo->_typecnt],
  1170. subItemElem
  1171. );
  1172. ((PUCHAR)subItemElem) += itemSize;
  1173. }
  1174. break;
  1175. case MTYPE_STRING:
  1176. DfsRtlUnwindStringGet((PSTRING)subItem);
  1177. break;
  1178. case MTYPE_UNICODE_STRING:
  1179. DfsRtlUnwindUnicodeStringGet((PUNICODE_STRING)subItem);
  1180. break;
  1181. case (MTYPE_UNICODE_STRING|MTYPE_COUNTED_ARRAY):
  1182. case (MTYPE_UNICODE_STRING|MTYPE_STATIC_ARRAY):
  1183. subItemElem = (PUCHAR)subItem;
  1184. while(cnt--) {
  1185. DfsRtlUnwindUnicodeStringGet((PUNICODE_STRING)subItemElem);
  1186. ((PUCHAR)subItemElem) += itemSize;
  1187. }
  1188. break;
  1189. case MTYPE_GUID:
  1190. case MTYPE_ULONG:
  1191. case MTYPE_USHORT:
  1192. case MTYPE_UCHAR:
  1193. break;
  1194. default:
  1195. ExRaiseStatus(STATUS_DATA_ERROR);
  1196. };
  1197. if(typeInfo->_type & MTYPE_INDIRECT) {
  1198. MarshalBufferFree(subItem);
  1199. *(PUCHAR *)((PUCHAR)Item + typeInfo->_off) = NULL;
  1200. }
  1201. }
  1202. DebugTrace(-1, Dbg, "DfsRtlUnwindGet: Exit -> VOID\n", 0);
  1203. }