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.

224 lines
5.7 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. bstr.cxx
  5. Abstract:
  6. Windows Data Type Support by means of [user_marshal] attribute.
  7. Covers:
  8. BSTR
  9. Author:
  10. Bill Morel (billmo) Oct 14, 1995
  11. These routines provide [wire_marshal] support for BSTRs.
  12. Revision History:
  13. 14-Jun-96 MikeHill Converted to use the new PrivSysAllocString,
  14. PrivSysReAllocString, & PrivSysFreeString routines
  15. (defined elsewhere in OLE32).
  16. -------------------------------------------------------------------*/
  17. //#include "stdrpc.hxx"
  18. #pragma hdrstop
  19. #include <wtypes.h>
  20. #include "transmit.h"
  21. #include <privoa.h> // PrivSys* routines
  22. // round up string alloc requests to nearest N-byte boundary, since allocator
  23. // will round up anyway. Improves cache hits.
  24. //
  25. // UNDONE: optimal for Chicago is 4
  26. // UNDONE: optimal for Daytona is 32
  27. // UNDONE: 4 didn't help the a$ = a$ + "x" case at all.
  28. // UNDONE: 8 did (gave 50% cache hit)
  29. //
  30. #define WIN32_ALLOC_ALIGN (4 - 1)
  31. #define DEFAULT_ALLOC_ALIGN (2 - 1)
  32. /***
  33. *unsigned int PrivSysStringByteLen(BSTR)
  34. *Purpose:
  35. * return the length in bytes of the given BSTR.
  36. *
  37. *Entry:
  38. * bstr = the BSTR to return the length of
  39. *
  40. *Exit:
  41. * return value = unsigned int, length in bytes.
  42. *
  43. ***********************************************************************/
  44. // #########################################################################
  45. //
  46. // BSTR
  47. //
  48. // #########################################################################
  49. //+-------------------------------------------------------------------------
  50. //
  51. // Function: BSTR_UserSize
  52. //
  53. // Synopsis: Get the wire size for the BSTR handle and data.
  54. //
  55. // Derivation: Conformant struct with a flag field:
  56. // align + 12 + data size.
  57. //
  58. //--------------------------------------------------------------------------
  59. unsigned long __RPC_USER
  60. BSTR_UserSize (
  61. unsigned long * pFlags,
  62. unsigned long Offset,
  63. BSTR * pBstr)
  64. {
  65. // Null bstr doesn't get marshalled.
  66. if ( pBstr == NULL || *pBstr == NULL )
  67. return Offset;
  68. unsigned long ulDataSize;
  69. LENGTH_ALIGN( Offset, 3 );
  70. // Takes the byte length of a unicode string
  71. ulDataSize = PrivSysStringByteLen( *pBstr );
  72. return( Offset + 12 + ulDataSize) ;
  73. }
  74. //+-------------------------------------------------------------------------
  75. //
  76. // Function: BSTR_UserMarshall
  77. //
  78. // Synopsis: Marshalls an BSTR object into the RPC buffer.
  79. //
  80. // Derivation: Conformant struct with a flag field:
  81. // align, size, null flag, size, data (bytes, if any)
  82. //
  83. //--------------------------------------------------------------------------
  84. unsigned char __RPC_FAR * __RPC_USER
  85. BSTR_UserMarshal (
  86. unsigned long * pFlags,
  87. unsigned char * pBuffer,
  88. BSTR * pBstr)
  89. {
  90. // A null Bstr is not marshalled, the engine will take care of it.
  91. if ( pBstr == NULL || *pBstr == NULL )
  92. return pBuffer;
  93. unsigned long ulDataSize;
  94. // Data size (in bytes): a null bstr gets a data size of zero.
  95. ulDataSize = PrivSysStringByteLen( *pBstr );
  96. // Conformant size.
  97. ALIGN( pBuffer, 3 );
  98. *( PULONG_LV_CAST pBuffer)++ = (ulDataSize >> 1);
  99. // FLAGGED_WORD_BLOB: Handle is the null/non-null flag
  100. *( PULONG_LV_CAST pBuffer)++ = (unsigned long)*pBstr;
  101. // Length on wire is in words.
  102. *( PULONG_LV_CAST pBuffer)++ = (ulDataSize >> 1);
  103. if( ulDataSize )
  104. {
  105. // we don't put the terminating string on wire
  106. WdtpMemoryCopy( pBuffer, *pBstr, ulDataSize );
  107. }
  108. return( pBuffer + ulDataSize );
  109. }
  110. //+-------------------------------------------------------------------------
  111. //
  112. // Function: BSTR_UserUnmarshall
  113. //
  114. // Synopsis: Unmarshalls an BSTR object from the RPC buffer.
  115. //
  116. // Derivation: Conformant struct with a flag field:
  117. // align, size, null flag, size, data (bytes, if any)
  118. //
  119. //--------------------------------------------------------------------------
  120. unsigned char __RPC_FAR * __RPC_USER
  121. BSTR_UserUnmarshal (
  122. unsigned long * pFlags,
  123. unsigned char * pBuffer,
  124. BSTR * pBstr)
  125. {
  126. unsigned long ulDataSize, fHandle;
  127. BSTR Bstr = NULL; // Default to NULL BSTR
  128. ALIGN( pBuffer, 3 );
  129. ulDataSize = *( PULONG_LV_CAST pBuffer)++;
  130. fHandle = *(ulong *)pBuffer;
  131. pBuffer += 8;
  132. if ( fHandle )
  133. {
  134. // Length on wire is in words, and the string is unicode.
  135. if ( *pBstr &&
  136. *(((ulong *)*pBstr) -1) == (ulDataSize << 1) )
  137. WdtpMemoryCopy( *pBstr, pBuffer, (ulDataSize << 1) );
  138. else
  139. {
  140. if (!PrivSysReAllocStringLen( pBstr,
  141. (OLECHAR *)pBuffer,
  142. ulDataSize ))
  143. RpcRaiseException( E_OUTOFMEMORY );
  144. }
  145. }
  146. else
  147. {
  148. // free the old one, make it NULL.
  149. PrivSysFreeString( *pBstr );
  150. *pBstr = NULL;
  151. }
  152. return( pBuffer + (ulDataSize << 1) );
  153. }
  154. //+-------------------------------------------------------------------------
  155. //
  156. // Function: BSTR_UserFree
  157. //
  158. // Synopsis: Free an BSTR.
  159. //
  160. //--------------------------------------------------------------------------
  161. void __RPC_USER
  162. BSTR_UserFree(
  163. unsigned long * pFlags,
  164. BSTR * pBstr)
  165. {
  166. if( pBstr && *pBstr )
  167. {
  168. PrivSysFreeString(* pBstr);
  169. *pBstr = NULL;
  170. }
  171. }