Windows NT 4.0 source code leak
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.

309 lines
7.1 KiB

4 years ago
  1. /* --------------------------------------------------------------------
  2. Microsoft OS/2 LAN Manager
  3. Copyright(c) Microsoft Corp., 1991
  4. -------------------------------------------------------------------- */
  5. /* --------------------------------------------------------------------
  6. Description :
  7. Provides RPC client side stub context management
  8. History :
  9. stevez 01-15-91 First bits into the bucket.
  10. -------------------------------------------------------------------- */
  11. #ifdef NTENV
  12. extern "C"
  13. {
  14. #include <sysinc.h>
  15. }
  16. #else // NTENV
  17. #include <sysinc.h>
  18. #endif // NTENV
  19. #include <rpc.h>
  20. #include <rpcdcep.h>
  21. #include <rpcndr.h>
  22. #include <util.hxx>
  23. #include <osfpcket.hxx>
  24. #ifdef NTENV
  25. #include <memory.h>
  26. #endif // NTENV
  27. #ifdef WIN
  28. #define memset _fmemset
  29. #define memcpy _fmemcpy
  30. #define memcmp _fmemcmp
  31. #endif // WIN
  32. // The NDR format of a context is a (GUID, long) instead of a pointer
  33. // in the server address space due history. Anyway, we just save this
  34. // cookie, which is sent on the and mapped to and from a pointer
  35. // on the server side.
  36. #define CONTEXT_MAGIC_VALUE 0xFEDCBA98
  37. typedef struct _WIRE_CONTEXT
  38. {
  39. unsigned long ContextType;
  40. UUID ContextUuid;
  41. } WIRE_CONTEXT;
  42. typedef struct _CCONTEXT {
  43. RPC_BINDING_HANDLE hRPC; // binding handle assoicated with context
  44. unsigned long MagicValue;
  45. WIRE_CONTEXT NDR;
  46. } CCONTEXT, *PCCONTEXT;
  47. static unsigned char NilContext[20];
  48. RPC_BINDING_HANDLE RPC_ENTRY
  49. NDRCContextBinding (
  50. IN NDR_CCONTEXT CContext
  51. )
  52. /*++
  53. Routine Description:
  54. Given a client context handle, we need to extract the binding from it.
  55. If an addressing exception occurs, we need to return invalid handle
  56. rather than GP-fault.
  57. Arguments:
  58. CContext - Supplies the client context handle.
  59. Return Value:
  60. The binding handle associated with the supplied client context handle
  61. will be returned. If the client context handle is invalid, then we
  62. raise the RPC_X_SS_CONTEXT_MISMATCH exception.
  63. --*/
  64. {
  65. #ifdef NTENV
  66. RpcTryExcept
  67. {
  68. if ( ((CCONTEXT PAPI *) CContext)->MagicValue != CONTEXT_MAGIC_VALUE )
  69. {
  70. RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
  71. }
  72. }
  73. RpcExcept( ( RpcExceptionCode() == STATUS_ACCESS_VIOLATION )
  74. || ( RpcExceptionCode() == STATUS_DATATYPE_MISALIGNMENT ) )
  75. {
  76. RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
  77. }
  78. RpcEndExcept
  79. #else // NTENV
  80. if ( ( CContext == 0 )
  81. || ( ((CCONTEXT PAPI *) CContext)->MagicValue != CONTEXT_MAGIC_VALUE ) )
  82. {
  83. RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
  84. }
  85. #endif // NTENV
  86. return(((CCONTEXT PAPI *) CContext)->hRPC);
  87. }
  88. void RPC_ENTRY
  89. NDRCContextMarshall ( // copy a context to a buffer
  90. IN NDR_CCONTEXT hCC, // context to marshell
  91. OUT void PAPI *pBuff // buffer to marshell to
  92. // Copy the interal representation of a context into a buffer
  93. ) //-----------------------------------------------------------------------//
  94. {
  95. #define hCContext ((CCONTEXT PAPI *) hCC) // cast opeqe pointer to internal
  96. if (!hCContext)
  97. memset(pBuff, 0, cbNDRContext);
  98. else
  99. {
  100. // Check the magic value to see if this is a legit context
  101. RpcTryExcept
  102. {
  103. if ( ((CCONTEXT PAPI *) hCContext)->MagicValue != CONTEXT_MAGIC_VALUE )
  104. {
  105. RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
  106. }
  107. }
  108. RpcExcept(1)
  109. {
  110. RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
  111. }
  112. RpcEndExcept
  113. memcpy(pBuff, &hCContext->NDR, sizeof(hCContext->NDR));
  114. }
  115. #undef hCContext
  116. }
  117. static void
  118. ByteSwapWireContext(
  119. IN WIRE_CONTEXT PAPI * WireContext,
  120. IN unsigned long PAPI * DataRepresentation
  121. )
  122. /*++
  123. Routine Description:
  124. If necessary, the wire context will be byte swapped in place.
  125. Arguments:
  126. WireContext - Supplies the wire context be byte swapped and returns the
  127. resulting byte swapped context.
  128. DataRepresentation - Supplies the data representation of the supplied wire
  129. context.
  130. --*/
  131. {
  132. if ( (*DataRepresentation & NDR_LITTLE_ENDIAN)
  133. != NDR_LOCAL_ENDIAN )
  134. {
  135. ByteSwapLong(WireContext->ContextType);
  136. ByteSwapLong(WireContext->ContextUuid.Data1);
  137. ByteSwapShort(WireContext->ContextUuid.Data2);
  138. ByteSwapShort(WireContext->ContextUuid.Data3);
  139. }
  140. }
  141. void RPC_ENTRY
  142. NDRCContextUnmarshall ( // process returned context
  143. OUT NDR_CCONTEXT PAPI *phCContext,// stub context to update
  144. IN RPC_BINDING_HANDLE hRPC, // binding handle to associate with
  145. IN void PAPI *pBuff, // pointer to NDR wire format
  146. IN unsigned long DataRepresentation // pointer to NDR data rep
  147. // Update the users context handle from the servers NDR wire format.
  148. ) //-----------------------------------------------------------------------//
  149. {
  150. PCCONTEXT hCC = (PCCONTEXT) ((long) *phCContext);
  151. // destory this context if the server returned none
  152. ByteSwapWireContext((WIRE_CONTEXT PAPI *) pBuff,
  153. (unsigned long PAPI *) &DataRepresentation);
  154. ASSERT( !RpcpCheckHeap() );
  155. if (memcmp(pBuff, NilContext, cbNDRContext) == 0)
  156. {
  157. if (hCC)
  158. {
  159. if (hCC->hRPC)
  160. RpcBindingFree(&(hCC->hRPC)); // discard duplicated binding
  161. hCC->MagicValue = 0;
  162. I_RpcFree(hCC);
  163. }
  164. *phCContext = Nil;
  165. return;
  166. }
  167. PCCONTEXT hCCtemp = 0;
  168. if (! hCC) // allocate new if none existed
  169. {
  170. hCCtemp = (PCCONTEXT) I_RpcAllocate(sizeof(CCONTEXT));
  171. if (hCCtemp == 0)
  172. {
  173. RpcRaiseException(RPC_S_OUT_OF_MEMORY);
  174. }
  175. hCCtemp->MagicValue = CONTEXT_MAGIC_VALUE;
  176. }
  177. else if (memcmp(&hCC->NDR, pBuff, sizeof(hCC->NDR)) == 0)
  178. {
  179. // the returned context is the same as the app's context.
  180. return;
  181. }
  182. RPC_BINDING_HANDLE hBindtemp ;
  183. if( I_RpcBindingCopy(hRPC, &hBindtemp) != RPC_S_OK )
  184. {
  185. ASSERT( !RpcpCheckHeap() );
  186. I_RpcFree( hCCtemp );
  187. RpcRaiseException(RPC_S_OUT_OF_MEMORY);
  188. }
  189. if ( hCCtemp )
  190. hCC = hCCtemp;
  191. else
  192. RpcBindingFree(&(hCC->hRPC));
  193. memcpy(&hCC->NDR, pBuff, sizeof(hCC->NDR));
  194. hCC->hRPC = hBindtemp;
  195. ASSERT( !RpcpCheckHeap() );
  196. *phCContext = (NDR_CCONTEXT)hCC;
  197. }
  198. void RPC_ENTRY
  199. RpcSsDestroyClientContext (
  200. IN OUT void PAPI * PAPI * ContextHandle
  201. )
  202. /*++
  203. Routine Description:
  204. A client application will use this routine to destroy a context handle
  205. which it no longer needs. This will work without having to contact the
  206. server.
  207. Arguments:
  208. ContextHandle - Supplies the context handle to be destroyed. It will
  209. be set to zero before this routine returns.
  210. Exceptions:
  211. If the context handle is invalid, then the RPC_X_SS_CONTEXT_MISMATCH
  212. exception will be raised.
  213. --*/
  214. {
  215. RPC_BINDING_HANDLE BindingHandle;
  216. RPC_STATUS RpcStatus;
  217. BindingHandle = NDRCContextBinding(*ContextHandle);
  218. RpcStatus = RpcBindingFree(&BindingHandle);
  219. // ASSERT( RpcStatus == RPC_S_OK );
  220. I_RpcFree(*ContextHandle);
  221. *ContextHandle = 0;
  222. }