Source code of Windows XP (NT5)
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.

637 lines
18 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1993 - 1999 Microsoft Corporation
  3. Module Name :
  4. hndl.c
  5. Abstract :
  6. To hold support routines for interpreting handles
  7. in support of Format Strings.
  8. Author :
  9. Bruce McQuistan (brucemc)
  10. Revision History :
  11. ryszardk 3/12/94 handle optimization and fixes
  12. ---------------------------------------------------------------------*/
  13. #include "precomp.hxx"
  14. #include "interp.h"
  15. extern const IID GUID_NULL;
  16. handle_t
  17. Ndr64GenericHandleMgr(
  18. PMIDL_STUB_DESC pStubDesc,
  19. uchar * ArgPtr,
  20. PFORMAT_STRING pFormat,
  21. uint Flags,
  22. handle_t * pGenericHandle
  23. )
  24. /*++
  25. Description :
  26. Provides a filter for generic binding handle management issues.
  27. Deals with implicit or explicit generic binding handles calling
  28. user functions as appropriate.
  29. Arguments :
  30. pStubDesc - pointer to current StubDescriptor.
  31. ArgPtr - pointer to handle.
  32. pFormat - pointer to Format string such that *pFormat is a
  33. handle descriptor.
  34. Flag - flag indicating either binding or unbinding.
  35. Returns :
  36. Valid binding handle.
  37. */
  38. {
  39. uchar GHandleSize;
  40. handle_t ReturnHandle = 0;
  41. BOOL fBinding;
  42. GENERIC_BINDING_ROUTINE pBindFunc = 0;
  43. GENERIC_UNBIND_ROUTINE pUnBindFunc = 0;
  44. const GENERIC_BINDING_ROUTINE_PAIR * Table;
  45. NDR64_BIND_GENERIC * pExplicitFormat;
  46. BOOL fIsPtr = FALSE;
  47. Table = pStubDesc->aGenericBindingRoutinePairs;
  48. fBinding = (Flags & BINDING_MASK);
  49. if ( Flags & IMPLICIT_MASK )
  50. {
  51. //
  52. // Implicit generic: All the info is taken from the implicit generic
  53. // handle info structure accessed via stub descriptor.
  54. //
  55. PGENERIC_BINDING_INFO pGenHandleInfo;
  56. pGenHandleInfo = pStubDesc->IMPLICIT_HANDLE_INFO.pGenericBindingInfo;
  57. GHandleSize = (uchar) pGenHandleInfo->Size;
  58. if ( fBinding )
  59. pBindFunc = pGenHandleInfo->pfnBind;
  60. else
  61. pUnBindFunc = pGenHandleInfo->pfnUnbind;
  62. }
  63. else
  64. {
  65. //
  66. // Explicit generic: Get index into array of function ptrs and
  67. // the gen handle size the format string.
  68. //
  69. NDR64_UINT8 TableIndex;
  70. pExplicitFormat = ( NDR64_BIND_GENERIC * )pFormat;
  71. NDR_ASSERT ( pExplicitFormat->HandleType == FC64_BIND_GENERIC, "invalid format char" );
  72. TableIndex = pExplicitFormat->RoutineIndex;
  73. GHandleSize = pExplicitFormat->Size;
  74. if ( fBinding )
  75. pBindFunc = Table[TableIndex].pfnBind;
  76. else
  77. pUnBindFunc = Table[TableIndex].pfnUnbind;
  78. if ( NDR64_IS_HANDLE_PTR(( ( NDR64_BIND_GENERIC * )pFormat )->Flags ) )
  79. fIsPtr = TRUE;
  80. }
  81. //
  82. // Call users routine on correctly dereferenced pointer.
  83. //
  84. switch (GHandleSize)
  85. {
  86. case 1:
  87. {
  88. uchar HandlePtr = (uchar)(ULONG_PTR)ArgPtr;
  89. if ( fIsPtr )
  90. HandlePtr = * (uchar *)ArgPtr;
  91. if ( fBinding )
  92. ReturnHandle =
  93. (handle_t)(ULONG_PTR)
  94. (*(GENERIC_BIND_FUNC_ARGCHAR)pBindFunc)(
  95. (uchar)(ULONG_PTR)HandlePtr );
  96. else
  97. (*(GENERIC_UNBIND_FUNC_ARGCHAR)pUnBindFunc)(
  98. (uchar)(ULONG_PTR)HandlePtr,
  99. *pGenericHandle );
  100. break;
  101. }
  102. case 2:
  103. {
  104. ushort HandlePtr = (ushort)(ULONG_PTR)ArgPtr;
  105. if ( fIsPtr )
  106. HandlePtr = * (ushort *)ArgPtr;
  107. if ( fBinding )
  108. ReturnHandle =
  109. (handle_t)(ULONG_PTR)
  110. (*(GENERIC_BIND_FUNC_ARGSHORT)pBindFunc)(
  111. (ushort)(ULONG_PTR)HandlePtr );
  112. else
  113. (*(GENERIC_UNBIND_FUNC_ARGSHORT)pUnBindFunc)(
  114. (ushort)(ULONG_PTR)HandlePtr,
  115. *pGenericHandle );
  116. break;
  117. }
  118. case 4:
  119. {
  120. ulong HandlePtr = (ulong)(ULONG_PTR)ArgPtr;
  121. if ( fIsPtr )
  122. HandlePtr = * (ulong *)ArgPtr;
  123. if ( fBinding )
  124. ReturnHandle =
  125. (handle_t)(ULONG_PTR)
  126. (*(GENERIC_BIND_FUNC_ARGLONG)pBindFunc)(
  127. (ulong)(ULONG_PTR)HandlePtr );
  128. else
  129. (*(GENERIC_UNBIND_FUNC_ARGLONG)pUnBindFunc)(
  130. (ulong)(ULONG_PTR)HandlePtr,
  131. *pGenericHandle );
  132. break;
  133. }
  134. #if defined(__RPC_WIN64__)
  135. case 8:
  136. {
  137. ULONG_PTR HandlePtr = (ULONG_PTR)ArgPtr;
  138. if ( fIsPtr )
  139. HandlePtr = * (ULONG_PTR *)ArgPtr;
  140. if ( fBinding )
  141. ReturnHandle =
  142. (handle_t)(ULONG_PTR)
  143. (*(GENERIC_BIND_FUNC_ARGINT64)pBindFunc)(
  144. (ULONG_PTR)HandlePtr );
  145. else
  146. (*(GENERIC_UNBIND_FUNC_ARGINT64)pUnBindFunc)(
  147. (ULONG_PTR)HandlePtr,
  148. *pGenericHandle );
  149. break;
  150. }
  151. #endif
  152. default:
  153. NDR_ASSERT(0,"GenericHandleMgr : Handle size too big");
  154. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  155. return 0;
  156. }
  157. if ( fBinding )
  158. {
  159. *pGenericHandle = ReturnHandle;
  160. if ( ReturnHandle == NULL )
  161. RpcRaiseException( RPC_S_INVALID_BINDING );
  162. }
  163. else
  164. *pGenericHandle = NULL;
  165. return ReturnHandle;
  166. }
  167. void
  168. Ndr64GenericHandleUnbind(
  169. PMIDL_STUB_DESC pStubDesc,
  170. uchar * ArgPtr,
  171. PFORMAT_STRING pFormat,
  172. uint Flags,
  173. handle_t * pGenericHandle
  174. )
  175. /*++
  176. Description :
  177. Unbinds a generic handle: checks if it is implicit or explicit,
  178. gets the handle and calls GenericHandleMgr.
  179. Arguments :
  180. pStubDesc - pointer to current StubDescriptor.
  181. ArgPtr - pointer to beginning of the stack.
  182. pFormat - pointer to Format string such that *pFormat is a
  183. handle descriptor.
  184. Flag - flag indicating implicit vs. explicit.
  185. --*/
  186. {
  187. if ( Flags & IMPLICIT_MASK )
  188. {
  189. PGENERIC_BINDING_INFO BindInfo;
  190. BindInfo = pStubDesc->IMPLICIT_HANDLE_INFO.pGenericBindingInfo;
  191. NDR_ASSERT( BindInfo != 0, "GenericHandleUnbind : null bind info" );
  192. ArgPtr = (uchar *) BindInfo->pObj;
  193. }
  194. else
  195. {
  196. ArgPtr += ( ( NDR64_BIND_GENERIC * )pFormat )->StackOffset;
  197. ArgPtr = *(uchar **)ArgPtr;
  198. // if ( NDR64_IS_HANDLE_PTR(( ( NDR64_BIND_GENERIC * )pFormat )->Flags ) )
  199. // ArgPtr = *(uchar * UNALIGNED *)ArgPtr;
  200. }
  201. (void) Ndr64GenericHandleMgr( pStubDesc,
  202. ArgPtr,
  203. pFormat,
  204. Flags,
  205. pGenericHandle );
  206. }
  207. handle_t
  208. Ndr64ImplicitBindHandleMgr(
  209. PMIDL_STUB_DESC pStubDesc,
  210. uchar HandleType,
  211. handle_t * pSavedGenericHandle
  212. )
  213. /*++
  214. Description :
  215. Provides a filter for implicit handle management issues. Deals
  216. with binding handles (generic, primitive or auto), extracting
  217. a valid handle from pStubDesc.
  218. Arguments :
  219. pStubDesc - pointer to current StubDescriptor.
  220. HandleType - handle format code.
  221. Return :
  222. Valid handle.
  223. --*/
  224. {
  225. handle_t ReturnHandle;
  226. PGENERIC_BINDING_INFO pBindInfo;
  227. switch ( HandleType )
  228. {
  229. case FC64_BIND_PRIMITIVE :
  230. ReturnHandle = *(pStubDesc->IMPLICIT_HANDLE_INFO.pPrimitiveHandle);
  231. break;
  232. case FC64_BIND_GENERIC :
  233. pBindInfo = pStubDesc->IMPLICIT_HANDLE_INFO.pGenericBindingInfo;
  234. NDR_ASSERT( pBindInfo != 0,
  235. "ImplicitBindHandleMgr : no generic bind info" );
  236. ReturnHandle = Ndr64GenericHandleMgr( pStubDesc,
  237. (uchar *)pBindInfo->pObj,
  238. &HandleType,
  239. BINDING_MASK | IMPLICIT_MASK,
  240. pSavedGenericHandle );
  241. break;
  242. case FC64_AUTO_HANDLE :
  243. ReturnHandle = *(pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
  244. break;
  245. case FC64_CALLBACK_HANDLE :
  246. ReturnHandle = GET_CURRENT_CALL_HANDLE();
  247. break;
  248. default :
  249. NDR_ASSERT(0, "ImplicitBindHandleMgr : bad handle type");
  250. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  251. return 0;
  252. }
  253. return ReturnHandle;
  254. }
  255. handle_t
  256. Ndr64ExplicitBindHandleMgr(
  257. PMIDL_STUB_DESC pStubDesc,
  258. uchar * ArgPtr,
  259. PFORMAT_STRING pFormat,
  260. handle_t * pSavedGenericHandle
  261. )
  262. /*
  263. Description :
  264. Provides a filter for explicit binding handle management issues.
  265. Deals with binding handles (primitive, generic or context), calling
  266. either no routine, NDR routines or user functions as appropriate.
  267. To be called in the following cases:
  268. 1) if handle is explicit.
  269. a) before calling I_RpcGetBuffer (to bind).
  270. b) after unmarshalling (to unbind).
  271. Arguments :
  272. pStubDesc - pointer to current StubDescriptor.
  273. ArgPtr - Pointer to start of stack
  274. pFormat - pointer to Format string such that *pFormat is a
  275. handle descriptor.
  276. Return :
  277. Valid binding handle.
  278. */
  279. {
  280. handle_t ReturnHandle;
  281. NDR64_BIND_CONTEXT * pExplicitFormat;
  282. //
  283. // We need to manage Explicit and Implicit handles.
  284. // Implicit handles are managed with info accessed via the StubMessage.
  285. // Explicit handles have their information stored in the format string.
  286. // We manage explicit handles for binding here.
  287. //
  288. pExplicitFormat = ( NDR64_BIND_CONTEXT * )pFormat;
  289. //
  290. // Get location in stack of handle referent.
  291. //
  292. ArgPtr += pExplicitFormat->StackOffset;
  293. ArgPtr = *(uchar **)ArgPtr;
  294. //
  295. // At this point ArgPtr is an address of the handle.
  296. //
  297. switch ( pExplicitFormat->HandleType )
  298. {
  299. case FC64_BIND_PRIMITIVE :
  300. if ( NDR64_IS_HANDLE_PTR( pExplicitFormat->Flags) )
  301. ArgPtr = *(uchar **)ArgPtr;
  302. ReturnHandle = (handle_t)(ULONG_PTR)ArgPtr;
  303. break;
  304. case FC64_BIND_GENERIC :
  305. ReturnHandle = Ndr64GenericHandleMgr( pStubDesc,
  306. ArgPtr,
  307. pFormat,
  308. BINDING_MASK,
  309. pSavedGenericHandle );
  310. break;
  311. case FC64_BIND_CONTEXT :
  312. if ( NDR64_IS_HANDLE_PTR( pExplicitFormat->Flags) )
  313. ArgPtr = *(uchar **)ArgPtr;
  314. if ( (!(ArgPtr)) && (!NDR64_IS_HANDLE_OUT(pExplicitFormat->Flags)) )
  315. RpcRaiseException( RPC_X_SS_IN_NULL_CONTEXT );
  316. ReturnHandle = 0; // covers NULL case below.
  317. if ( ArgPtr && !
  318. (ReturnHandle = NDRCContextBinding((NDR_CCONTEXT)ArgPtr)) )
  319. RpcRaiseException( RPC_X_SS_CONTEXT_MISMATCH );
  320. break;
  321. default :
  322. NDR_ASSERT( 0, "ExplictBindHandleMgr : bad handle type" );
  323. RpcRaiseException( RPC_S_INTERNAL_ERROR );
  324. return 0;
  325. }
  326. return ReturnHandle;
  327. }
  328. void
  329. Ndr64MarshallHandle(
  330. PMIDL_STUB_MESSAGE pStubMsg,
  331. uchar * pArg,
  332. PNDR64_FORMAT pFormat
  333. )
  334. /*++
  335. Routine description :
  336. Marshalls a context handle.
  337. Arguments :
  338. pStubMsg - Pointer to stub message.
  339. pArg - Context handle to marshall (NDR_CCONTEXT or NDR_SCONTEXT).
  340. pFormat - Context handle's format string description.
  341. Return :
  342. Buffer pointer after marshalling the context handle.
  343. --*/
  344. {
  345. long Index;
  346. NDR64_CONTEXT_HANDLE_FORMAT * pExplicitFormat;
  347. pExplicitFormat = ( NDR64_CONTEXT_HANDLE_FORMAT * ) pFormat;
  348. NDR_ASSERT( pExplicitFormat->FormatCode == FC64_BIND_CONTEXT,
  349. "Ndr64MarshallHandle : Expected a context handle" );
  350. if ( pStubMsg->IsClient )
  351. {
  352. NDR_CCONTEXT Context;
  353. ALIGN( pStubMsg->Buffer, 0x3 );
  354. //
  355. // Get the context handle.
  356. //
  357. Context = NDR64_IS_HANDLE_PTR( pExplicitFormat->ContextFlags ) ?
  358. *((NDR_CCONTEXT *)pArg) : (NDR_CCONTEXT)pArg;
  359. //
  360. // An [in] only context handle must be non-zero.
  361. //
  362. if ( ! Context && ! NDR64_IS_HANDLE_OUT( pExplicitFormat->ContextFlags ) )
  363. RpcRaiseException( RPC_X_SS_IN_NULL_CONTEXT );
  364. NDRCContextMarshall( Context, (void *) pStubMsg->Buffer );
  365. pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE;
  366. }
  367. else
  368. {
  369. Index = pExplicitFormat->Ordinal;
  370. if ( NDR64_IS_HANDLE_RETURN( pExplicitFormat->ContextFlags ) )
  371. {
  372. NDR_SCONTEXT SContext;
  373. //
  374. // Initialize the context handle.
  375. //
  376. SContext = Ndr64ContextHandleInitialize ( pStubMsg,
  377. (PFORMAT_STRING)pFormat );
  378. //
  379. // Put the user context that was returned into the context
  380. // handle.
  381. //
  382. *((uchar **)NDRSContextValue(SContext)) = pArg;
  383. pStubMsg->SavedContextHandles[Index] = SContext;
  384. }
  385. // add a marker to indicate runtime is marshalling the context handle,
  386. NDR_SCONTEXT pContext = pStubMsg->SavedContextHandles[Index];
  387. pStubMsg->SavedContextHandles[Index] = (NDR_SCONTEXT) CONTEXT_HANDLE_BEFORE_MARSHAL_MARKER;
  388. Ndr64ServerContextNewMarshall( pStubMsg,
  389. pContext,
  390. pStubMsg->StubDesc->apfnNdrRundownRoutines[pExplicitFormat->RundownRoutineIndex],
  391. (PFORMAT_STRING)pFormat );
  392. // after marshalling is finised, the hContext becomes invalid and
  393. // We need to zero out the saved context to avoid referencing garbage.
  394. pStubMsg->SavedContextHandles[Index] = (NDR_SCONTEXT)CONTEXT_HANDLE_AFTER_MARSHAL_MARKER;
  395. }
  396. }
  397. void
  398. Ndr64UnmarshallHandle(
  399. PMIDL_STUB_MESSAGE pStubMsg,
  400. uchar ** ppArg,
  401. PNDR64_FORMAT pFormat,
  402. bool /*fIgnored*/
  403. )
  404. /*++
  405. Routine description :
  406. Unmarshall a context handle.
  407. Arguments :
  408. pStubMsg - Pointer to stub message.
  409. ppArg - Pointer to the context handle on the client/server stack.
  410. On the client this is a NDR_CCONTEXT *. On the server
  411. side this is a NDR_SCONTEXT (regardless of direction).
  412. pFormat - Context handle's format string description.
  413. fIgnored - Ignored, but needed to match necessary routine prototype.
  414. Return :
  415. Buffer pointer after unmarshalling the context handle.
  416. --*/
  417. {
  418. NDR64_CONTEXT_HANDLE_FORMAT * pExplicitFormat;
  419. pExplicitFormat = (NDR64_CONTEXT_HANDLE_FORMAT * )pFormat;
  420. NDR_ASSERT( pExplicitFormat->FormatCode == FC64_BIND_CONTEXT,
  421. "Ndr64UnmarshallHHandle : Expected a context handle" );
  422. if ( pStubMsg->IsClient )
  423. {
  424. ALIGN( pStubMsg->Buffer, 0x3 );
  425. //
  426. // Check if we have a pointer to a context handle
  427. // (the pointer can't be null).
  428. //
  429. if ( NDR64_IS_HANDLE_PTR( pExplicitFormat->ContextFlags ) )
  430. {
  431. ppArg = (uchar **) *ppArg;
  432. }
  433. //
  434. // Zero an [out] only context handle before unmarshalling.
  435. //
  436. if ( ! NDR64_IS_HANDLE_IN( pExplicitFormat->ContextFlags ) )
  437. *ppArg = 0;
  438. //
  439. // We must use the original binding handle in this call.
  440. //
  441. NDRCContextUnmarshall( (NDR_CCONTEXT *)ppArg,
  442. pStubMsg->SavedHandle,
  443. (void *)pStubMsg->Buffer,
  444. pStubMsg->RpcMsg->DataRepresentation );
  445. pStubMsg->Buffer += CONTEXT_HANDLE_WIRE_SIZE;
  446. }
  447. else
  448. {
  449. NDR_SCONTEXT SContext =
  450. Ndr64ServerContextNewUnmarshall( pStubMsg,
  451. (PFORMAT_STRING)pFormat );
  452. Ndr64SaveContextHandle( pStubMsg,
  453. SContext,
  454. ppArg,
  455. (PFORMAT_STRING)pFormat );
  456. }
  457. }
  458. void
  459. Ndr64SaveContextHandle (
  460. PMIDL_STUB_MESSAGE pStubMsg,
  461. NDR_SCONTEXT CtxtHandle,
  462. uchar ** ppArg,
  463. PFORMAT_STRING pFormat )
  464. /*++
  465. Routine Description :
  466. Saves a context handle's current value and then extracts the user's
  467. context value.
  468. Arguments :
  469. pStubMsg - The stub message.
  470. CtxtHandle - The context handle.
  471. ppArg - Pointer to where user's context value should go.
  472. Return :
  473. None.
  474. */
  475. {
  476. long Index;
  477. // no NT3.5 stub in ndr64.
  478. Index = ( ( NDR64_CONTEXT_HANDLE_FORMAT * ) pFormat)->Ordinal;
  479. pStubMsg->SavedContextHandles[Index] = CtxtHandle;
  480. // On 32b alphas, a handle pointer needs to be properly sign extended
  481. // to a 64b virtual stack value, as this will become the register value.
  482. // So, we cast to the REGISTER_TYPE to get the sign extension
  483. if ( ! NDR64_IS_HANDLE_PTR(( ( NDR64_CONTEXT_HANDLE_FORMAT * ) pFormat)->ContextFlags) )
  484. *((REGISTER_TYPE*)ppArg) = (REGISTER_TYPE) *(NDRSContextValue(CtxtHandle));
  485. else
  486. *((REGISTER_TYPE*)ppArg) = (REGISTER_TYPE) NDRSContextValue(CtxtHandle);
  487. }