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.

478 lines
16 KiB

  1. //
  2. // Copyright (C) 2000, Microsoft Corporation
  3. //
  4. // File: PackMisc.c
  5. //
  6. // Contents: packing routines used by DFS
  7. //
  8. // History: Dec. 8 2000, Author: udayh
  9. //
  10. //-----------------------------------------------------------------------------
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stddef.h>
  18. #include "dfsheader.h"
  19. #include "dfsmisc.h"
  20. #define BYTE_0_MASK 0xFF
  21. #define BYTE_0(Value) (UCHAR)( (Value) & BYTE_0_MASK)
  22. #define BYTE_1(Value) (UCHAR)( ((Value) >> 8) & BYTE_0_MASK)
  23. #define BYTE_2(Value) (UCHAR)( ((Value) >> 16) & BYTE_0_MASK)
  24. #define BYTE_3(Value) (UCHAR)( ((Value) >> 24) & BYTE_0_MASK)
  25. //+-------------------------------------------------------------------------
  26. //
  27. // Function PackGetULong
  28. //
  29. // Arguments: pValue - pointer to return info
  30. // ppBuffer - pointer to buffer that holds the binary
  31. // stream.
  32. // pSizeRemaining - pointer to size of above buffer
  33. //
  34. // Returns: Status
  35. // ERROR_SUCCESS if we could unpack the name info
  36. // ERROR_INVALID_DATA otherwise
  37. //
  38. //
  39. // Description: This routine reads one ulong value from the binary
  40. // stream, and returns that value. It adjusts the buffer
  41. // pointer and remaining size appropriately to point
  42. // to the next value in the binary stream.
  43. //
  44. //--------------------------------------------------------------------------
  45. DFSSTATUS
  46. PackGetULong(
  47. PULONG pValue,
  48. PVOID *ppBuffer,
  49. PULONG pSizeRemaining )
  50. {
  51. DFSSTATUS Status = ERROR_INVALID_DATA;
  52. ULONG SizeNeeded = sizeof(ULONG);
  53. PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
  54. if ( *pSizeRemaining >= SizeNeeded )
  55. {
  56. *pValue = (ULONG) ( (ULONG) pBinaryStream[0] |
  57. (ULONG) pBinaryStream[1] << 8 |
  58. (ULONG) pBinaryStream[2] << 16 |
  59. (ULONG) pBinaryStream[3] << 24);
  60. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
  61. *pSizeRemaining -= SizeNeeded;
  62. Status = ERROR_SUCCESS;
  63. }
  64. return Status;
  65. }
  66. //+-------------------------------------------------------------------------
  67. //
  68. // Function: PackSetULong - store one Ulong in the binary stream
  69. //
  70. // Arguments: Value - Ulong to add
  71. // ppBuffer - pointer to buffer that holds the binary stream.
  72. // pSizeRemaining - pointer to size remaining in buffer
  73. //
  74. // Returns: Status
  75. // ERROR_SUCCESS if we could unpack the name info
  76. // ERROR_INVALID_DATA otherwise
  77. //
  78. //
  79. // Description: This routine stores one ulong value in the binary stream,
  80. // It adjusts the buffer pointer and remaining size
  81. // appropriately to point to the next value
  82. // in the binary stream.
  83. //
  84. //--------------------------------------------------------------------------
  85. DFSSTATUS
  86. PackSetULong(
  87. ULONG Value,
  88. PVOID *ppBuffer,
  89. PULONG pSizeRemaining )
  90. {
  91. DFSSTATUS Status = ERROR_INVALID_DATA;
  92. ULONG SizeNeeded = sizeof(ULONG);
  93. PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
  94. if ( *pSizeRemaining >= SizeNeeded )
  95. {
  96. pBinaryStream[0] = BYTE_0( Value );
  97. pBinaryStream[1] = BYTE_1( Value );
  98. pBinaryStream[2] = BYTE_2( Value );
  99. pBinaryStream[3] = BYTE_3( Value );
  100. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
  101. *pSizeRemaining -= SizeNeeded;
  102. Status = ERROR_SUCCESS;
  103. }
  104. return Status;
  105. }
  106. //
  107. // Function: PackSizeULong, return size of ulong
  108. //
  109. ULONG
  110. PackSizeULong()
  111. {
  112. return sizeof(ULONG);
  113. }
  114. //+-------------------------------------------------------------------------
  115. //
  116. // Function: PackGetUShort - get one UShort from the binary stream
  117. //
  118. // Arguments: pValue - pointer to return info
  119. // ppBuffer - pointer to buffer that holds the binary
  120. // stream.
  121. // pSizeRemaining - pointer to size of above buffer
  122. //
  123. // Returns: Status
  124. // ERROR_SUCCESS if we could unpack the name info
  125. // ERROR_INVALID_DATA otherwise
  126. //
  127. //
  128. // Description: This routine reads one uShort value from the binary
  129. // stream, and returns that value. It adjusts the
  130. // buffer pointer and remaining size appropriately to
  131. // point to the next value in the binary stream.
  132. //
  133. //--------------------------------------------------------------------------
  134. DFSSTATUS
  135. PackGetUShort(
  136. PUSHORT pValue,
  137. PVOID *ppBuffer,
  138. PULONG pSizeRemaining )
  139. {
  140. DFSSTATUS Status = ERROR_INVALID_DATA;
  141. ULONG SizeNeeded = sizeof(USHORT);
  142. PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
  143. if ( *pSizeRemaining >= SizeNeeded )
  144. {
  145. *pValue = (USHORT)( (USHORT) pBinaryStream[0] |
  146. (USHORT) pBinaryStream[1] << 8 );
  147. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
  148. *pSizeRemaining -= SizeNeeded;
  149. Status = ERROR_SUCCESS;
  150. }
  151. return Status;
  152. }
  153. //+-------------------------------------------------------------------------
  154. //
  155. // Function: PackSetUShort - puts one UShort in the binary stream
  156. //
  157. // Arguments: Value - Ushort value
  158. // ppBuffer - pointer to buffer that holds the binary stream.
  159. // pSizeRemaining - pointer to size of above buffer
  160. //
  161. // Returns: Status
  162. // ERROR_SUCCESS if we could pack
  163. // ERROR_INVALID_DATA otherwise
  164. //
  165. //
  166. // Description: This routine puts one uShort value in the binary stream,
  167. // It adjusts the buffer pointer and
  168. // remaining size appropriately to point to the next value
  169. // in the binary stream.
  170. //
  171. //--------------------------------------------------------------------------
  172. DFSSTATUS
  173. PackSetUShort(
  174. USHORT Value,
  175. PVOID *ppBuffer,
  176. PULONG pSizeRemaining )
  177. {
  178. DFSSTATUS Status = ERROR_INVALID_DATA;
  179. ULONG SizeNeeded = sizeof(USHORT);
  180. PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
  181. if ( *pSizeRemaining >= SizeNeeded )
  182. {
  183. pBinaryStream[0] = BYTE_0(Value);
  184. pBinaryStream[1] = BYTE_1(Value);
  185. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
  186. *pSizeRemaining -= SizeNeeded;
  187. Status = ERROR_SUCCESS;
  188. }
  189. return Status;
  190. }
  191. //
  192. // Function: PackSizeUShort, return size of ushort
  193. //
  194. ULONG
  195. PackSizeUShort()
  196. {
  197. return sizeof(USHORT);
  198. }
  199. //+-------------------------------------------------------------------------
  200. //
  201. // Function: PackGetString - gets a string from a binary stream.
  202. //
  203. // Arguments: pString - pointer to returned unicode string
  204. // ppBuffer - pointer to buffer that holds the binary stream.
  205. // pSizeRemaining - pointer to size of above buffer
  206. //
  207. // Returns: Status
  208. // ERROR_SUCCESS if we could unpack the name info
  209. // ERROR_INVALID_DATA otherwise
  210. //
  211. //
  212. // Description: This routine reads one ulong value from the binary stream,
  213. // and determines that to be the length of the string.
  214. // It then sets up a unicode string, whose buffer points
  215. // to the appropriate place within the binary stream, and
  216. // whose length is set to the ulong value that was read.
  217. // It returns the buffer and size remaining adjusted appropriately.
  218. //
  219. //--------------------------------------------------------------------------
  220. DFSSTATUS
  221. PackGetString(
  222. PUNICODE_STRING pString,
  223. PVOID *ppBuffer,
  224. PULONG pSizeRemaining )
  225. {
  226. DFSSTATUS ReturnStatus = ERROR_INVALID_DATA;
  227. DFSSTATUS Status;
  228. //
  229. // We first get the length of the string.
  230. //
  231. Status = PackGetUShort(&pString->Length,
  232. ppBuffer,
  233. pSizeRemaining );
  234. if ( Status == ERROR_SUCCESS )
  235. {
  236. //
  237. // If the length exceeds the remaining binary stream or the length
  238. // is odd, we dont have a valid string.
  239. // Otherwise, set the pointer in the unicode string to the binary
  240. // stream representing the string, and update the buffer to point
  241. // to beyond the string.
  242. //
  243. if ( *pSizeRemaining >= pString->Length &&
  244. (pString->Length & 0x1) == 0 )
  245. {
  246. pString->Buffer = (LPWSTR)(*ppBuffer);
  247. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + pString->Length);
  248. *pSizeRemaining -= pString->Length;
  249. pString->MaximumLength = pString->Length;
  250. ReturnStatus = ERROR_SUCCESS;
  251. }
  252. }
  253. return ReturnStatus;
  254. }
  255. //+-------------------------------------------------------------------------
  256. //
  257. // Function: PackSetString - puts a string in the binary stream.
  258. //
  259. // Arguments: pString - pointer to unicode string to pack
  260. // ppBuffer - pointer to buffer that holds the binary stream.
  261. // pSizeRemaining - pointer to size of above buffer
  262. //
  263. // Returns: Status
  264. // ERROR_SUCCESS if we could pack
  265. // ERROR_INVALID_DATA otherwise
  266. //
  267. //
  268. // Description: This routine puts one ulong value in the binary stream
  269. // to represent length of string. It then copies the string
  270. // itself into the buffer.
  271. //
  272. //--------------------------------------------------------------------------
  273. DFSSTATUS
  274. PackSetString(
  275. PUNICODE_STRING pString,
  276. PVOID *ppBuffer,
  277. PULONG pSizeRemaining )
  278. {
  279. DFSSTATUS ReturnStatus = ERROR_INVALID_DATA;
  280. DFSSTATUS Status;
  281. //
  282. // We first set the length of the string.
  283. //
  284. Status = PackSetUShort( pString->Length,
  285. ppBuffer,
  286. pSizeRemaining );
  287. if ( Status == ERROR_SUCCESS )
  288. {
  289. //
  290. // If the length exceeds the remaining binary stream
  291. // we dont have a valid string.
  292. // Otherwise, we copy the unicode string to the binary
  293. // stream representing the string, and update the buffer to point
  294. // to beyond the string.
  295. //
  296. if ( *pSizeRemaining >= pString->Length )
  297. {
  298. memcpy((LPWSTR)(*ppBuffer), pString->Buffer, pString->Length);
  299. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + pString->Length);
  300. *pSizeRemaining -= pString->Length;
  301. ReturnStatus = ERROR_SUCCESS;
  302. }
  303. }
  304. return ReturnStatus;
  305. }
  306. //
  307. // Function: PackSizeString - return size of string
  308. //
  309. ULONG
  310. PackSizeString(
  311. PUNICODE_STRING pString)
  312. {
  313. return (ULONG)(sizeof(USHORT) + pString->Length);
  314. }
  315. //+-------------------------------------------------------------------------
  316. //
  317. // Function: PackGetGuid - Unpacks the guid from a binary stream
  318. //
  319. // Arguments: pGuid - pointer to a guid structure
  320. // ppBuffer - pointer to buffer that holds the binary stream.
  321. // pSizeRemaining - pointer to size of above buffer
  322. //
  323. // Returns: Status
  324. // ERROR_SUCCESS if we could unpack the info
  325. // ERROR_INVALID_DATA otherwise
  326. //
  327. //
  328. // Description: This routine expects the binary stream to hold a guid.
  329. // It reads the guid information into the guid structure in
  330. // the format prescribed for guids.
  331. // The ppbuffer and size are adjusted to point to the next
  332. // information in the binary stream.
  333. //
  334. //--------------------------------------------------------------------------
  335. DFSSTATUS
  336. PackGetGuid(
  337. GUID *pGuid,
  338. PVOID *ppBuffer,
  339. PULONG pSizeRemaining )
  340. {
  341. DFSSTATUS Status = ERROR_INVALID_DATA;
  342. ULONG SizeNeeded = sizeof(GUID);
  343. PUCHAR pGuidInfo = (PUCHAR)(*ppBuffer);
  344. if ( *pSizeRemaining >= SizeNeeded )
  345. {
  346. pGuid->Data1 = (ULONG) ((ULONG) pGuidInfo[0] |
  347. (ULONG) pGuidInfo[1] << 8 |
  348. (ULONG) pGuidInfo[2] << 16 |
  349. (ULONG) pGuidInfo[3] << 24 );
  350. pGuid->Data2 = (USHORT) ((USHORT) pGuidInfo[4] |
  351. (USHORT) pGuidInfo[5] << 8 );
  352. pGuid->Data3 = (USHORT) ((USHORT) pGuidInfo[6] |
  353. (USHORT) pGuidInfo[7] << 8 );
  354. memcpy(pGuid->Data4, &pGuidInfo[8], 8);
  355. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
  356. *pSizeRemaining -= SizeNeeded;
  357. Status = ERROR_SUCCESS;
  358. }
  359. return Status;
  360. }
  361. //+-------------------------------------------------------------------------
  362. //
  363. // Function: PackSetGuid - Packs the guid from a binary stream
  364. //
  365. // Arguments: pGuid - pointer to a guid structure
  366. // ppBuffer - pointer to buffer that holds the binary stream.
  367. // pSizeRemaining - pointer to size of above buffer
  368. //
  369. // Returns: Status
  370. // ERROR_SUCCESS if we could pack the info
  371. // ERROR_INVALID_DATA otherwise
  372. //
  373. //
  374. // Description: This routine stores the guid into the binary stream.
  375. // The ppbuffer and size are adjusted to point to the next
  376. // information in the binary stream.
  377. //
  378. //--------------------------------------------------------------------------
  379. DFSSTATUS
  380. PackSetGuid(
  381. GUID *pGuid,
  382. PVOID *ppBuffer,
  383. PULONG pSizeRemaining )
  384. {
  385. DFSSTATUS Status = ERROR_INVALID_DATA;
  386. ULONG SizeNeeded = sizeof(GUID);
  387. PUCHAR pGuidInfo = (PUCHAR)(*ppBuffer);
  388. if ( *pSizeRemaining >= SizeNeeded )
  389. {
  390. pGuidInfo[0] = BYTE_0(pGuid->Data1);
  391. pGuidInfo[1] = BYTE_1(pGuid->Data1);
  392. pGuidInfo[2] = BYTE_2(pGuid->Data1);
  393. pGuidInfo[3] = BYTE_3(pGuid->Data1);
  394. pGuidInfo[4] = BYTE_0(pGuid->Data2);
  395. pGuidInfo[5] = BYTE_1(pGuid->Data2);
  396. pGuidInfo[6] = BYTE_0(pGuid->Data3);
  397. pGuidInfo[7] = BYTE_1(pGuid->Data3);
  398. memcpy(&pGuidInfo[8], pGuid->Data4, 8);
  399. *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
  400. *pSizeRemaining -= SizeNeeded;
  401. Status = ERROR_SUCCESS;
  402. }
  403. return Status;
  404. }
  405. //
  406. // Function: PackSizeGuid - return size of Guid
  407. //
  408. ULONG
  409. PackSizeGuid()
  410. {
  411. return sizeof(GUID);
  412. }