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.

555 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: clipformat.cxx
  7. //
  8. // Contents: Support for Windows/OLE data types for oleprx32.dll.
  9. // Used to be transmit_as routines, now user_marshal routines.
  10. //
  11. // This file contains support for SNB.
  12. //
  13. // Functions:
  14. // SNB_UserSize
  15. // SNB_UserMarshal
  16. // SNB_UserUnmarshal
  17. // SNB_UserFree
  18. // SNB_UserSize64
  19. // SNB_UserMarshal64
  20. // SNB_UserUnmarshal64
  21. // SNB_UserFree64
  22. //
  23. // History: 13-Dec-00 JohnDoty Migrated from transmit.cxx
  24. //
  25. //--------------------------------------------------------------------------
  26. #include "stdrpc.hxx"
  27. #pragma hdrstop
  28. #include <oleauto.h>
  29. #include <objbase.h>
  30. #include "transmit.hxx"
  31. #include <rpcwdt.h>
  32. #include <storext.h>
  33. #include <valid.h>
  34. #include <obase.h>
  35. #include <stream.hxx>
  36. #include "carefulreader.hxx"
  37. //+-------------------------------------------------------------------------
  38. //
  39. // Function: SNB_UserSize
  40. //
  41. // Synopsis: Sizes an SNB.
  42. //
  43. // Derivation: An array of strings in one block of memory.
  44. //
  45. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  46. //
  47. //--------------------------------------------------------------------------
  48. unsigned long __RPC_USER
  49. SNB_UserSize (
  50. unsigned long * pFlags,
  51. unsigned long Offset,
  52. SNB * pSnb )
  53. {
  54. if ( ! pSnb )
  55. return Offset;
  56. // calculate the number of strings and characters (with their terminators)
  57. ULONG ulCntStr = 0;
  58. ULONG ulCntChar = 0;
  59. if (pSnb && *pSnb)
  60. {
  61. SNB snb = *pSnb;
  62. WCHAR *psz = *snb;
  63. while (psz)
  64. {
  65. ulCntChar += lstrlenW(psz) + 1;
  66. ulCntStr++;
  67. snb++;
  68. psz = *snb;
  69. }
  70. }
  71. // The wire size is: conf size, 2 fields and the wchars.
  72. LENGTH_ALIGN( Offset, 3 );
  73. return ( Offset + 3 * sizeof(long) + ulCntChar * sizeof( WCHAR ) );
  74. }
  75. //+-------------------------------------------------------------------------
  76. //
  77. // Function: SNB_UserMarshall
  78. //
  79. // Synopsis: Marshalls an SNB into the RPC buffer.
  80. //
  81. // Derivation: An array of strings in one block of memory.
  82. //
  83. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  84. //
  85. //--------------------------------------------------------------------------
  86. unsigned char __RPC_FAR * __RPC_USER
  87. SNB_UserMarshal (
  88. unsigned long * pFlags,
  89. unsigned char * pBuffer,
  90. SNB * pSnb )
  91. {
  92. UserNdrDebugOut((UNDR_FORCE, "SNB_UserMarshal\n"));
  93. if ( ! pSnb )
  94. return pBuffer;
  95. // calculate the number of strings and characters (with their terminators)
  96. ULONG ulCntStr = 0;
  97. ULONG ulCntChar = 0;
  98. if (pSnb && *pSnb)
  99. {
  100. SNB snb = *pSnb;
  101. WCHAR *psz = *snb;
  102. while (psz)
  103. {
  104. ulCntChar += lstrlenW(psz) + 1;
  105. ulCntStr++;
  106. snb++;
  107. psz = *snb;
  108. }
  109. }
  110. // conformant size
  111. ALIGN( pBuffer, 3 );
  112. *( PULONG_LV_CAST pBuffer)++ = ulCntChar;
  113. // fields
  114. *( PULONG_LV_CAST pBuffer)++ = ulCntStr;
  115. *( PULONG_LV_CAST pBuffer)++ = ulCntChar;
  116. // actual strings only
  117. if ( pSnb && *pSnb )
  118. {
  119. // There is a NULL string pointer to mark the end of the pointer array.
  120. // However, the strings don't have to follow tightly.
  121. // Hence, we have to copy one string at a time.
  122. SNB snb = *pSnb;
  123. WCHAR *pszSrc;
  124. while (pszSrc = *snb++)
  125. {
  126. ULONG ulCopyLen = (lstrlenW(pszSrc) + 1) * sizeof(WCHAR);
  127. WdtpMemoryCopy( pBuffer, pszSrc, ulCopyLen );
  128. pBuffer += ulCopyLen;
  129. }
  130. }
  131. return pBuffer;
  132. }
  133. //+-------------------------------------------------------------------------
  134. //
  135. // Function: SNB_UserUnmarshall
  136. //
  137. // Synopsis: Unmarshalls an SNB from the RPC buffer.
  138. //
  139. // Derivation: An array of strings in one block of memory.
  140. //
  141. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  142. // Aug-99 JohnStra Add consistency checks.
  143. //
  144. //--------------------------------------------------------------------------
  145. unsigned char __RPC_FAR * __RPC_USER
  146. SNB_UserUnmarshal (
  147. unsigned long * pFlags,
  148. unsigned char * pBuffer,
  149. SNB * pSnb )
  150. {
  151. UserNdrDebugOut((UNDR_FORCE, "SNB_UserUnmarshal\n"));
  152. // Initialize CUserMarshalInfo object and get the buffer
  153. // size and pointer to the start of the buffer.
  154. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  155. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  156. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  157. // Align the buffer and save the size of the fixup.
  158. ALIGN( pBuffer, 3 );
  159. ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart);
  160. // Check for EOB before trying to get header.
  161. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (3 * sizeof( ULONG )) );
  162. // Get the header from the buffer.
  163. ULONG ulCntChar = *( PULONG_LV_CAST pBuffer)++;
  164. ULONG ulCntStr = *( PULONG_LV_CAST pBuffer)++;
  165. ULONG ulCntCharDup = *(PULONG_LV_CAST pBuffer)++;
  166. // Verify that 2nd instance of count matches first.
  167. if ( ulCntCharDup != ulCntChar )
  168. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  169. // No reusage of pSNB.
  170. if ( *pSnb )
  171. WdtpFree( pFlags, *pSnb );
  172. if ( ulCntStr == 0 )
  173. {
  174. // There are no strings.
  175. // NULL pSnb and return.
  176. *pSnb = NULL;
  177. return pBuffer;
  178. }
  179. // Validate the header:
  180. // Repeated char count must match first instance and char count must
  181. // not be less than the number of strings since that would mean at
  182. // least one of them doesn't isn't terminated.
  183. if ( (ulCntChar != ulCntCharDup) || (ulCntChar < ulCntStr) )
  184. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  185. // Check for EOB before trying to get the strings.
  186. CHECK_BUFFER_SIZE(
  187. BufferSize,
  188. cbFixup + (3 * sizeof(ULONG)) + (ulCntChar * sizeof(WCHAR)) );
  189. // Last WCHAR in the buffer must be the UNICODE terminator.
  190. WCHAR* pszChars = (WCHAR*) pBuffer;
  191. if ( pszChars[ulCntChar - 1] != 0x0000 )
  192. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  193. // construct the SNB.
  194. SNB Snb = (SNB) WdtpAllocate( pFlags,
  195. ( (ulCntStr + 1) * sizeof(WCHAR *) +
  196. ulCntChar * sizeof(WCHAR)) );
  197. *pSnb = Snb;
  198. if (Snb)
  199. {
  200. // create the pointer array within the SNB. to do this, we go through
  201. // the buffer, and use strlen to find the end of the each string for
  202. // us.
  203. WCHAR *pszSrc = (WCHAR *) pBuffer;
  204. WCHAR *pszTgt = (WCHAR *) (Snb + ulCntStr + 1); // right behind array
  205. void* SnbStart = Snb;
  206. ULONG ulTotLen = 0;
  207. ULONG i;
  208. for (i = ulCntStr; (i > 0) && (ulTotLen < ulCntChar); i--)
  209. {
  210. *Snb++ = pszTgt;
  211. ULONG ulLen = lstrlenW(pszSrc) + 1;
  212. pszSrc += ulLen;
  213. pszTgt += ulLen;
  214. ulTotLen += ulLen;
  215. }
  216. *Snb++ = NULL;
  217. // Verify that the number of strings and the number of chars
  218. // in the buffer matches what is supposed to be there.
  219. if ( (i > 0) || (ulTotLen < ulCntChar) )
  220. {
  221. WdtpFree( pFlags, SnbStart );
  222. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  223. }
  224. // Copy the actual strings.
  225. // We can do a block copy here as we packed them tight in the buffer.
  226. // Snb points right behind the lastarray of pointers within the SNB.
  227. WdtpMemoryCopy( Snb, pBuffer, ulCntChar * sizeof(WCHAR) );
  228. pBuffer += ulCntChar * sizeof(WCHAR);
  229. }
  230. return pBuffer;
  231. }
  232. //+-------------------------------------------------------------------------
  233. //
  234. // Function: SNB_UserFree
  235. //
  236. // Synopsis: Frees an SNB.
  237. //
  238. // Derivation: An array of strings in one block of memory.
  239. //
  240. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  241. //
  242. //--------------------------------------------------------------------------
  243. void __RPC_USER
  244. SNB_UserFree(
  245. unsigned long * pFlags,
  246. SNB * pSnb )
  247. {
  248. if ( pSnb && *pSnb )
  249. WdtpFree( pFlags, *pSnb );
  250. }
  251. #if defined(_WIN64)
  252. //+-------------------------------------------------------------------------
  253. //
  254. // Function: SNB_UserSize64
  255. //
  256. // Synopsis: Sizes an SNB.
  257. //
  258. // Derivation: An array of strings in one block of memory.
  259. //
  260. // history: Dec-00 JohnDoty Created from 32bit function
  261. //
  262. //--------------------------------------------------------------------------
  263. unsigned long __RPC_USER
  264. SNB_UserSize64 (
  265. unsigned long * pFlags,
  266. unsigned long Offset,
  267. SNB * pSnb )
  268. {
  269. if ( ! pSnb )
  270. return Offset;
  271. // calculate the number of strings and characters (with their terminators)
  272. ULONG ulCntStr = 0;
  273. ULONG ulCntChar = 0;
  274. if (pSnb && *pSnb)
  275. {
  276. SNB snb = *pSnb;
  277. WCHAR *psz = *snb;
  278. while (psz)
  279. {
  280. ulCntChar += lstrlenW(psz) + 1;
  281. ulCntStr++;
  282. snb++;
  283. psz = *snb;
  284. }
  285. }
  286. // The wire size is: conf size, 2 fields and the wchars.
  287. LENGTH_ALIGN( Offset, 7 );
  288. return ( Offset + 8 + (2 * sizeof(long)) + (ulCntChar * sizeof(WCHAR)) );
  289. }
  290. //+-------------------------------------------------------------------------
  291. //
  292. // Function: SNB_UserMarshal64
  293. //
  294. // Synopsis: Marshalls an SNB into the RPC buffer.
  295. //
  296. // Derivation: An array of strings in one block of memory.
  297. //
  298. // history: Dec-00 JohnDoty Created from 32bit function
  299. //
  300. //--------------------------------------------------------------------------
  301. unsigned char __RPC_FAR * __RPC_USER
  302. SNB_UserMarshal64 (
  303. unsigned long * pFlags,
  304. unsigned char * pBuffer,
  305. SNB * pSnb )
  306. {
  307. UserNdrDebugOut((UNDR_FORCE, "SNB_UserMarshal\n"));
  308. if ( ! pSnb )
  309. return pBuffer;
  310. // calculate the number of strings and characters (with their terminators)
  311. ULONG ulCntStr = 0;
  312. ULONG ulCntChar = 0;
  313. if (pSnb && *pSnb)
  314. {
  315. SNB snb = *pSnb;
  316. WCHAR *psz = *snb;
  317. while (psz)
  318. {
  319. ulCntChar += lstrlenW(psz) + 1;
  320. ulCntStr++;
  321. snb++;
  322. psz = *snb;
  323. }
  324. }
  325. // conformant size
  326. ALIGN( pBuffer, 7 );
  327. *( PHYPER_LV_CAST pBuffer)++ = ulCntChar;
  328. // fields
  329. *( PULONG_LV_CAST pBuffer)++ = ulCntStr;
  330. *( PULONG_LV_CAST pBuffer)++ = ulCntChar;
  331. // actual strings only
  332. if ( pSnb && *pSnb )
  333. {
  334. // There is a NULL string pointer to mark the end of the pointer array.
  335. // However, the strings don't have to follow tightly.
  336. // Hence, we have to copy one string at a time.
  337. SNB snb = *pSnb;
  338. WCHAR *pszSrc;
  339. while (pszSrc = *snb++)
  340. {
  341. ULONG ulCopyLen = (lstrlenW(pszSrc) + 1) * sizeof(WCHAR);
  342. WdtpMemoryCopy( pBuffer, pszSrc, ulCopyLen );
  343. pBuffer += ulCopyLen;
  344. }
  345. }
  346. return pBuffer;
  347. }
  348. //+-------------------------------------------------------------------------
  349. //
  350. // Function: SNB_UserUnmarshal64
  351. //
  352. // Synopsis: Unmarshalls an SNB from the RPC buffer.
  353. //
  354. // Derivation: An array of strings in one block of memory.
  355. //
  356. // history: Dec-00 JohnDoty Created from 32bit function
  357. //
  358. //--------------------------------------------------------------------------
  359. unsigned char __RPC_FAR * __RPC_USER
  360. SNB_UserUnmarshal64 (
  361. unsigned long * pFlags,
  362. unsigned char * pBuffer,
  363. SNB * pSnb )
  364. {
  365. UserNdrDebugOut((UNDR_FORCE, "SNB_UserUnmarshal\n"));
  366. // Initialize CUserMarshalInfo object and get the buffer
  367. // size and pointer to the start of the buffer.
  368. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  369. CarefulBufferReader stream( pBuffer, MarshalInfo.GetBufferSize() );
  370. // Get the header from the buffer.... (ReadHYPER aligns on 8).
  371. ULONG ulCntChar = (ULONG)stream.ReadHYPER();
  372. ULONG ulCntStr = stream.ReadULONGNA();
  373. ULONG ulCntCharDup = stream.ReadULONGNA();
  374. // Verify that 2nd instance of count matches first.
  375. if ( ulCntCharDup != ulCntChar )
  376. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  377. // No reusage of pSNB.
  378. if ( *pSnb )
  379. {
  380. WdtpFree( pFlags, *pSnb );
  381. *pSnb = NULL;
  382. }
  383. if ( ulCntStr == 0 )
  384. {
  385. // There are no strings.
  386. return stream.GetBuffer();
  387. }
  388. // Validate the header:
  389. // Repeated char count must match first instance and char count must
  390. // not be less than the number of strings since that would mean at
  391. // least one of them doesn't isn't terminated.
  392. if ( ulCntChar < ulCntStr )
  393. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  394. // Check for EOB before trying to get the strings.
  395. stream.CheckSize(ulCntChar * sizeof(WCHAR));
  396. // Last WCHAR in the buffer must be the UNICODE terminator.
  397. WCHAR* pszChars = (WCHAR*)stream.GetBuffer();
  398. if ( pszChars[ulCntChar - 1] != L'\0' )
  399. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  400. // construct the SNB.
  401. SNB Snb = (SNB) WdtpAllocate( pFlags,
  402. ( (ulCntStr + 1) * sizeof(WCHAR *) +
  403. ulCntChar * sizeof(WCHAR)) );
  404. *pSnb = Snb;
  405. if (Snb)
  406. {
  407. // create the pointer array within the SNB. to do this, we go through
  408. // the buffer, and use strlen to find the end of the each string for
  409. // us.
  410. WCHAR *pszSrc = (WCHAR *) stream.GetBuffer();
  411. WCHAR *pszTgt = (WCHAR *) (Snb + ulCntStr + 1); // right behind array
  412. void* SnbStart = Snb;
  413. ULONG ulTotLen = 0;
  414. ULONG i;
  415. for (i = ulCntStr; (i > 0) && (ulTotLen < ulCntChar); i--)
  416. {
  417. *Snb++ = pszTgt;
  418. ULONG ulLen = lstrlenW(pszSrc) + 1;
  419. pszSrc += ulLen;
  420. pszTgt += ulLen;
  421. ulTotLen += ulLen;
  422. }
  423. *Snb++ = NULL;
  424. // Verify that the number of strings and the number of chars
  425. // in the buffer matches what is supposed to be there.
  426. if ( (i > 0) || (ulTotLen < ulCntChar) )
  427. {
  428. WdtpFree( pFlags, SnbStart );
  429. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  430. }
  431. // Copy the actual strings.
  432. // We can do a block copy here as we packed them tight in the buffer.
  433. // Snb points right behind the lastarray of pointers within the SNB.
  434. WdtpMemoryCopy( Snb, stream.GetBuffer(), ulCntChar * sizeof(WCHAR) );
  435. stream.Advance(ulCntChar * sizeof(WCHAR));
  436. }
  437. return stream.GetBuffer();
  438. }
  439. //+-------------------------------------------------------------------------
  440. //
  441. // Function: SNB_UserFree64
  442. //
  443. // Synopsis: Frees an SNB.
  444. //
  445. // Derivation: An array of strings in one block of memory.
  446. //
  447. // history: Dec-00 JohnDoty Created from 32bit function
  448. //
  449. //--------------------------------------------------------------------------
  450. void __RPC_USER
  451. SNB_UserFree64 (
  452. unsigned long * pFlags,
  453. SNB * pSnb )
  454. {
  455. if ( pSnb && *pSnb )
  456. WdtpFree( pFlags, *pSnb );
  457. }
  458. #endif