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.

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