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.

377 lines
11 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. ndrcls.cxx
  5. Abstract:
  6. Routines for the ndrcls code generation class.
  7. Notes:
  8. History:
  9. Aug-31-1993 VibhasC Created.
  10. ----------------------------------------------------------------------------*/
  11. /****************************************************************************
  12. * include files
  13. ***************************************************************************/
  14. #include "becls.hxx"
  15. #pragma hdrstop
  16. /****************************************************************************
  17. * local definitions
  18. ***************************************************************************/
  19. /****************************************************************************
  20. * local data
  21. ***************************************************************************/
  22. /****************************************************************************
  23. * externs
  24. ***************************************************************************/
  25. /****************************************************************************/
  26. expr_node *
  27. CG_NDR::PresentedLengthExpression( CCB* )
  28. {
  29. expr_sizeof * pExpr = new expr_sizeof( GetType() );
  30. return pExpr;
  31. }
  32. expr_node *
  33. CG_NDR::PresentedSizeExpression( CCB* )
  34. {
  35. expr_sizeof * pExpr = new expr_sizeof( GetType() );
  36. return pExpr;
  37. }
  38. expr_node *
  39. CG_NDR::PresentedFirstExpression( CCB* )
  40. {
  41. return new expr_constant(0L);
  42. }
  43. /****************************************************************************
  44. utility functions
  45. ****************************************************************************/
  46. CG_STATUS
  47. CG_NDR::SizeAnalysis( ANALYSIS_INFO * pAna )
  48. {
  49. pAna;
  50. return CG_OK;
  51. }
  52. CG_STATUS
  53. CG_NDR::MarshallAnalysis( ANALYSIS_INFO * pAna )
  54. {
  55. pAna;
  56. return CG_OK;
  57. }
  58. node_skl *
  59. CG_NDR::GetBasicType()
  60. {
  61. node_skl * pT = GetType();
  62. switch (pT->NodeKind())
  63. {
  64. case NODE_ID:
  65. case NODE_FIELD:
  66. case NODE_PARAM:
  67. case NODE_DEF:
  68. return pT->GetBasicType();
  69. }
  70. return pT;
  71. }
  72. CG_STATUS
  73. CG_NDR::RefCheckAnalysis(
  74. ANALYSIS_INFO * pAna )
  75. {
  76. CG_NDR * pC = (CG_NDR *)GetChild();
  77. if( pC )
  78. pC->RefCheckAnalysis( pAna );
  79. return CG_OK;
  80. }
  81. CG_STATUS
  82. CG_NDR::InLocalAnalysis(
  83. ANALYSIS_INFO * pAna )
  84. {
  85. CG_NDR * pC = (CG_NDR *)GetChild();
  86. if( pC )
  87. pC->InLocalAnalysis( pAna );
  88. return CG_OK;
  89. }
  90. CG_STATUS
  91. CG_NDR::S_GenInitInLocals(
  92. CCB * pCCB )
  93. {
  94. CG_NDR * pC = (CG_NDR *)GetChild();
  95. if( pC )
  96. pC->S_GenInitInLocals( pCCB );
  97. return CG_OK;
  98. }
  99. CG_STATUS
  100. CG_NDR::GenRefChecks(
  101. CCB * pCCB )
  102. {
  103. CG_NDR * pC = (CG_NDR *)GetChild();
  104. if( pC )
  105. pC->GenRefChecks( pCCB );
  106. return CG_OK;
  107. }
  108. extern CMD_ARG * pCommand;
  109. void
  110. CG_NDR::GetNdrParamAttributes( CCB *pCCB, PARAM_ATTRIBUTES *attributes)
  111. {
  112. CG_PARAM * pParam;
  113. CG_NDR * pChild;
  114. CG_PROC * pProc;
  115. pChild = (CG_NDR *) GetChild();
  116. if ( pChild && (pChild->GetCGID() == ID_CG_GENERIC_HDL) )
  117. pChild = (CG_NDR *) pChild->GetChild();
  118. pParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
  119. pProc = (CG_PROC *) pCCB->GetCGNodeContext();
  120. if ( IsPipeOrPipeReference() )
  121. {
  122. // Pipe parameters are never sized.
  123. attributes->MustSize = 0;
  124. }
  125. else
  126. attributes->MustSize = (unsigned short) pParam->GetInterpreterMustSize();
  127. attributes->IsIn = (unsigned short) pParam->IsParamIn();
  128. attributes->IsOut = (unsigned short) pParam->IsParamOut();
  129. attributes->IsReturn = ( pParam->GetCGID() == ID_CG_RETURN )
  130. || ( pProc->HasComplexReturnType()
  131. && NULL == pParam->GetSibling() );
  132. attributes->IsPartialIgnore = pParam->IsParamPartialIgnore();
  133. attributes->IsForceAllocate = pParam->IsForceAllocate();
  134. attributes->IsBasetype = 0;
  135. // SAFEARRAY(FOO) is being generated as ID_CG_SAFEARRAY. It's in fact user
  136. // marshal on the wire.
  137. attributes->IsByValue =
  138. IsStruct() ||
  139. IsUnion() ||
  140. ( GetCGID() == ID_CG_TRANSMIT_AS ) ||
  141. ( GetCGID() == ID_CG_REPRESENT_AS ) ||
  142. ( GetCGID() == ID_CG_USER_MARSHAL ) ||
  143. ( GetCGID() == ID_CG_SAFEARRAY ) ||
  144. ( GetCGID() == ID_CG_CS_TAG ) ;
  145. attributes->IsSimpleRef =
  146. (pParam->GetCGID() != ID_CG_RETURN) &&
  147. IsPointer() &&
  148. ((CG_POINTER *)this)->IsBasicRefPointer();
  149. attributes->IsDontCallFreeInst = (unsigned short) pParam->GetDontCallFreeInst();
  150. attributes->IsPipe = (unsigned short) IsPipeOrPipeReference();
  151. attributes->SaveForAsyncFinish = (unsigned short) pParam->IsSaveForAsyncFinish();
  152. if ( (attributes->IsPipe) || (GetCGID() == ID_CG_CONTEXT_HDL) ||
  153. (IsPointer() && pChild && (pChild->GetCGID() == ID_CG_CONTEXT_HDL)))
  154. attributes->MustFree = 0;
  155. else
  156. attributes->MustFree = 1;
  157. attributes->ServerAllocSize = 0;
  158. if ( GetCGID() == ID_CG_PTR )
  159. {
  160. long Size = 0;
  161. (void)
  162. ((CG_POINTER *)this)->InterpreterAllocatesOnStack( pCCB,
  163. pParam,
  164. &Size );
  165. attributes->ServerAllocSize = unsigned short(Size / 8);
  166. }
  167. //
  168. // Now make a final check for a simple ref pointer to a basetype and for
  169. // a ref pointer to pointer.
  170. //
  171. // We mark pointers to basetypes as being both a basetype and a simple
  172. // ref pointer. Kind of an anomoly, but it works out well in the
  173. // interpreter.
  174. //
  175. // For both of these cases the pointer must have no allocate attributes
  176. // and can not be a return value.
  177. //
  178. if (
  179. IsPointer() &&
  180. (((CG_POINTER *)this)->GetPtrType() == PTR_REF) &&
  181. ! IS_ALLOCATE( ((CG_POINTER *)this)->GetAllocateDetails(),
  182. ALLOCATE_ALL_NODES ) &&
  183. ! IS_ALLOCATE( ((CG_POINTER *)this)->GetAllocateDetails(),
  184. ALLOCATE_DONT_FREE ) &&
  185. (pParam->GetCGID() != ID_CG_RETURN)
  186. )
  187. {
  188. //
  189. // Now make sure it's a pointer to basetype and that it is either
  190. // [in] or [in,out] (in which case we use the buffer to hold it) or
  191. // that it is [out] and there is room for it on the interpreter's
  192. // stack. We don't mark enum16s as SimpleRef-Basetype because of
  193. // their special handling (i.e. wire size != memory size).
  194. //
  195. if ( ((CG_POINTER *)this)->IsPointerToBaseType() &&
  196. ( pParam->IsParamIn() ||
  197. (((CG_POINTER *)this)->GetFormatAttr() & FC_ALLOCED_ON_STACK) ) )
  198. {
  199. if ( ((CG_BASETYPE *)pChild)->GetFormatChar() != FC_ENUM16 )
  200. {
  201. attributes->IsBasetype = 1;
  202. attributes->IsSimpleRef = 1;
  203. }
  204. attributes->MustFree = 0;
  205. }
  206. // we give a warning here because pointer to range doesn't work on
  207. // w2k sp2 and xp 2600 and before. There is a NDR bug that doesn't
  208. // allocate memory for poitner to range case.
  209. if (pChild &&
  210. pChild->IsSimpleType() &&
  211. ((CG_BASETYPE *)pChild)->GetRangeAttribute() != NULL &&
  212. !pCommand->IsNDR64Run() )
  213. {
  214. RpcError( NULL, 0, TOP_LEVEL_POINTER_RANGE, pParam->GetSymName() );
  215. }
  216. }
  217. }
  218. void
  219. CG_NDR::GenNdrParamDescription( CCB * pCCB )
  220. {
  221. FORMAT_STRING * pProcFormatString;
  222. PARAM_ATTRIBUTES Attributes;
  223. long FormatStringOffset;
  224. CG_PARAM * pParam;
  225. CG_NDR * pChild;
  226. pChild = (CG_NDR *) GetChild();
  227. if ( pChild && (pChild->GetCGID() == ID_CG_GENERIC_HDL) )
  228. pChild = (CG_NDR *) pChild->GetChild();
  229. pParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
  230. pProcFormatString = pCCB->GetProcFormatString();
  231. // Attributes.
  232. GetNdrParamAttributes( pCCB, &Attributes );
  233. pProcFormatString->PushParamFlagsShort( *((short *)&Attributes) );
  234. // Stack offset as number of ints.
  235. pProcFormatString->PushUShortStackOffsetOrSize(
  236. pParam->GetStackOffset( pCCB, I386_STACK_SIZING ) );
  237. //
  238. // If we found a pointer to a basetype, make sure and emit the basetype's
  239. // param format.
  240. //
  241. if ( Attributes.IsSimpleRef && Attributes.IsBasetype )
  242. {
  243. pProcFormatString->PushFormatChar(
  244. ((CG_BASETYPE *)pChild)->GetFormatChar() );
  245. pProcFormatString->PushByte( 0 );
  246. return;
  247. }
  248. if ( Attributes.IsSimpleRef )
  249. {
  250. CG_POINTER * pPointer;
  251. pPointer = (CG_POINTER *) this;
  252. switch ( pPointer->GetCGID() )
  253. {
  254. case ID_CG_STRING_PTR :
  255. if ( ((CG_STRING_POINTER *)pPointer)->IsStringableStruct() )
  256. FormatStringOffset = GetFormatStringOffset();
  257. else
  258. FormatStringOffset = pPointer->GetFormatStringOffset() + 2;
  259. break;
  260. case ID_CG_SIZE_STRING_PTR :
  261. if ( ((CG_STRING_POINTER *)pPointer)->IsStringableStruct() )
  262. FormatStringOffset = GetFormatStringOffset();
  263. else
  264. FormatStringOffset = pPointer->GetPointeeFormatStringOffset();
  265. break;
  266. case ID_CG_STRUCT_STRING_PTR :
  267. FormatStringOffset = GetFormatStringOffset();
  268. break;
  269. default :
  270. FormatStringOffset = pPointer->GetPointeeFormatStringOffset();
  271. break;
  272. }
  273. }
  274. else
  275. {
  276. FormatStringOffset = GetFormatStringOffset();
  277. }
  278. //
  279. // Push the offset in the type format string to the param's description.
  280. //
  281. pProcFormatString->PushShortTypeOffset( FormatStringOffset );
  282. }
  283. void
  284. CG_NDR::GenNdrParamDescriptionOld( CCB * pCCB )
  285. {
  286. FORMAT_STRING * pProcFormatString;
  287. CG_PARAM * pParam;
  288. long StackSize;
  289. long StackElem;
  290. pProcFormatString = pCCB->GetProcFormatString();
  291. pParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
  292. if ( pCommand->Is64BitEnv() )
  293. StackElem = 8;
  294. else
  295. StackElem = 4;
  296. StackSize = pParam->GetStackSize();
  297. StackSize = (StackSize + StackElem - 1) & ~ (StackElem - 1);
  298. pProcFormatString->PushSmallStackSize( (char) (StackSize / StackElem) );
  299. //
  300. // Push the offset in the type format string to the param's description.
  301. //
  302. pProcFormatString->PushShortTypeOffset( GetFormatStringOffset() );
  303. }