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.

471 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995.
  5. //
  6. // File:
  7. // objexif.cxx
  8. //
  9. // Contents:
  10. // Entry point for remote activation call to SCM/OR.
  11. //
  12. // Functions:
  13. // RemoteActivation
  14. //
  15. // History:
  16. //
  17. //--------------------------------------------------------------------------
  18. #include "act.hxx"
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: _RemoteActivation
  22. //
  23. // Synopsis: Entry point for old style activations from off machine.
  24. // Creates new stype activation properties and forwards to
  25. // ActivateFromPropertiesPreamble.
  26. //
  27. //----------------------------------------------------------------------------
  28. error_status_t _RemoteActivation(
  29. handle_t hRpc,
  30. ORPCTHIS *ORPCthis,
  31. ORPCTHAT *ORPCthat,
  32. GUID *Clsid,
  33. WCHAR *pwszObjectName,
  34. MInterfacePointer *pObjectStorage,
  35. DWORD ClientImpLevel,
  36. DWORD Mode,
  37. DWORD Interfaces,
  38. IID *pIIDs,
  39. unsigned short cRequestedProtseqs,
  40. unsigned short aRequestedProtseqs[],
  41. OXID *pOxid,
  42. DUALSTRINGARRAY **ppdsaOxidBindings,
  43. IPID *pipidRemUnknown,
  44. DWORD *pAuthnHint,
  45. COMVERSION *pServerVersion,
  46. HRESULT *phr,
  47. MInterfacePointer **ppInterfaceData,
  48. HRESULT *pResults )
  49. {
  50. RPC_STATUS sc;
  51. ACTIVATION_PARAMS ActParams;
  52. LOCALTHIS Localthis;
  53. WCHAR * pwszDummy;
  54. error_status_t rpcerror= RPC_S_OK;
  55. IID *newIIDs = 0;
  56. DWORD count;
  57. DWORD i;
  58. IComClassInfo* pClassInfo = NULL;
  59. IInitActivationPropertiesIn* pInitActPropsIn = NULL;
  60. // check for valid parameters
  61. if (ORPCthis == NULL ||
  62. ORPCthat == NULL ||
  63. Clsid == NULL ||
  64. pOxid == NULL ||
  65. Interfaces == 0 ||
  66. pIIDs == NULL ||
  67. ppdsaOxidBindings == NULL ||
  68. pipidRemUnknown == NULL ||
  69. pAuthnHint == NULL ||
  70. pServerVersion == NULL ||
  71. phr == NULL ||
  72. ppInterfaceData == NULL ||
  73. pResults == NULL)
  74. {
  75. return E_INVALIDARG;
  76. }
  77. *ppInterfaceData = NULL;
  78. *pOxid = 0;
  79. *ppdsaOxidBindings = NULL;
  80. memset(&ActParams, 0, sizeof(ActParams));
  81. /** Old Functionality **/
  82. Localthis.dwClientThread = 0;
  83. Localthis.dwFlags = LOCALF_NONE;
  84. ORPCthis->flags |= ORPCF_DYNAMIC_CLOAKING;
  85. ORPCthat->flags = 0;
  86. ORPCthat->extensions = NULL;
  87. // Determine what version to use for the returned interface. Fail
  88. // if the client wants a version we don't support.
  89. *pServerVersion = ORPCthis->version;
  90. *phr = NegotiateDCOMVersion( pServerVersion );
  91. if (*phr != OR_OK)
  92. {
  93. pServerVersion->MajorVersion = COM_MAJOR_VERSION;
  94. pServerVersion->MinorVersion = COM_MINOR_VERSION;
  95. return RPC_S_OK;
  96. }
  97. if ( ! s_fEnableDCOM )
  98. {
  99. *phr = E_ACCESSDENIED;
  100. return RPC_S_OK;
  101. }
  102. RegisterAuthInfoIfNecessary();
  103. /** Set up Actparams **/
  104. ActParams.hRpc = hRpc;
  105. ActParams.ORPCthis = ORPCthis;
  106. ActParams.Localthis = &Localthis;
  107. ActParams.ORPCthat = ORPCthat;
  108. ActParams.oldActivationCall = TRUE;
  109. ActParams.RemoteActivation = TRUE;
  110. if ( pwszObjectName || pObjectStorage )
  111. ActParams.MsgType = GETPERSISTENTINSTANCE;
  112. else
  113. ActParams.MsgType = (Mode == MODE_GET_CLASS_OBJECT) ?
  114. GETCLASSOBJECT : CREATEINSTANCE;
  115. /** Set up Activation Properties **/
  116. ActivationPropertiesIn * pInActivationProperties=NULL;
  117. ActivationPropertiesOut * pOutActivationProperties=NULL;
  118. InstantiationInfo * pInstantiationInfo=NULL;
  119. IScmRequestInfo * pInScmRequestInfo=NULL;
  120. IInstanceInfo *pInstanceInfo=NULL;
  121. ISpecialSystemProperties* pISpecialSystemProps = NULL;
  122. REMOTE_REQUEST_SCM_INFO *pReqInfo;
  123. IScmReplyInfo * pScmReplyInfo = NULL;
  124. REMOTE_REPLY_SCM_INFO *pReply;
  125. pInActivationProperties = new ActivationPropertiesIn;
  126. if (NULL == pInActivationProperties)
  127. {
  128. *phr = E_OUTOFMEMORY;
  129. return RPC_S_OK;
  130. }
  131. HRESULT hr;
  132. // Incoming session id from down-level clients is implicitly INVALID_SESSION_ID; make it so
  133. *phr = pInActivationProperties->QueryInterface(IID_ISpecialSystemProperties, (void**)&pISpecialSystemProps);
  134. if (FAILED(*phr))
  135. goto exit_oldremote;
  136. hr = pISpecialSystemProps->SetSessionId(INVALID_SESSION_ID, FALSE, FALSE);
  137. ASSERT(hr == S_OK);
  138. // pISpecialSystemProps will be released just before returning
  139. pInstantiationInfo = pInActivationProperties->GetInstantiationInfo();
  140. if (pInstantiationInfo == NULL)
  141. {
  142. *phr = E_OUTOFMEMORY;
  143. goto exit_oldremote;
  144. }
  145. *phr = pInActivationProperties->QueryInterface(IID_IScmRequestInfo,
  146. (LPVOID*)&pInScmRequestInfo);
  147. if (FAILED(*phr))
  148. goto exit_oldremote;
  149. hr = pInstantiationInfo->SetClsid(*Clsid);
  150. ASSERT(hr == S_OK);
  151. hr = pInstantiationInfo->SetClsctx(CLSCTX_LOCAL_SERVER);
  152. ASSERT(hr == S_OK);
  153. hr = pInstantiationInfo->SetClientCOMVersion(ORPCthis->version);
  154. ASSERT(hr == S_OK);
  155. *phr = pInActivationProperties->AddRequestedIIDs(Interfaces,pIIDs);
  156. if ( FAILED(*phr) )
  157. goto exit_oldremote;
  158. if (ActParams.MsgType == GETPERSISTENTINSTANCE)
  159. {
  160. *phr = pInActivationProperties->QueryInterface(IID_IInstanceInfo,
  161. (LPVOID*)&pInstanceInfo);
  162. if (FAILED(*phr))
  163. goto exit_oldremote;
  164. if ( pwszObjectName )
  165. {
  166. WCHAR *oldName = pwszObjectName;
  167. *phr = GetServerPath( pwszObjectName, &pwszObjectName);
  168. if ( FAILED(*phr) )
  169. goto exit_oldremote;
  170. *phr = pInstanceInfo->SetFile(pwszObjectName, Mode);
  171. if ( FAILED(*phr) )
  172. goto exit_oldremote;
  173. pInstanceInfo->GetFile(&ActParams.pwszPath, &ActParams.Mode);
  174. if (pwszObjectName != oldName)
  175. PrivMemFree(pwszObjectName);
  176. }
  177. else
  178. {
  179. ActParams.pwszPath = 0;
  180. }
  181. if (pObjectStorage)
  182. {
  183. MInterfacePointer* newStorage;
  184. newStorage = (MInterfacePointer*)
  185. AllocateAndCopy((InterfaceData*)pObjectStorage);
  186. if (newStorage)
  187. {
  188. *phr = pInstanceInfo->SetStorageIFD(newStorage);
  189. ActParams.pIFDStorage = pObjectStorage;
  190. }
  191. else
  192. *phr = E_OUTOFMEMORY;
  193. }
  194. if ( FAILED(*phr) )
  195. goto exit_oldremote;
  196. }
  197. pReqInfo = (REMOTE_REQUEST_SCM_INFO *)MIDL_user_allocate(sizeof(REMOTE_REQUEST_SCM_INFO));
  198. if (pReqInfo)
  199. {
  200. memset(pReqInfo, 0, sizeof(REMOTE_REQUEST_SCM_INFO));
  201. pReqInfo->ClientImpLevel = ClientImpLevel;
  202. if (pReqInfo->cRequestedProtseqs = cRequestedProtseqs)
  203. {
  204. pReqInfo->pRequestedProtseqs = (unsigned short*)
  205. MIDL_user_allocate(sizeof(unsigned short) *
  206. cRequestedProtseqs);
  207. if (pReqInfo->pRequestedProtseqs == NULL)
  208. {
  209. *phr = E_OUTOFMEMORY;
  210. MIDL_user_free(pReqInfo);
  211. }
  212. }
  213. }
  214. else
  215. *phr = E_OUTOFMEMORY;
  216. if ( FAILED(*phr) )
  217. goto exit_oldremote;
  218. for (i=0; i<cRequestedProtseqs; i++)
  219. pReqInfo->pRequestedProtseqs[i] = aRequestedProtseqs[i];
  220. pInScmRequestInfo->SetRemoteRequestInfo(pReqInfo);
  221. //Set up for marshalling
  222. pInActivationProperties->SetDestCtx(MSHCTX_DIFFERENTMACHINE);
  223. //
  224. // Get/set class info for the requested class; ActivateFromPropertiesPreamble
  225. // expects that actpropsin will already have had this done.
  226. //
  227. *phr = GetClassInfoFromClsid(*Clsid, &pClassInfo);
  228. if (FAILED(*phr))
  229. goto exit_oldremote;
  230. *phr = pInActivationProperties->QueryInterface(IID_IInitActivationPropertiesIn, (void**)&pInitActPropsIn);
  231. if (FAILED(*phr))
  232. goto exit_oldremote;
  233. *phr = pInitActPropsIn->SetClassInfo(pClassInfo);
  234. if (FAILED(*phr))
  235. goto exit_oldremote;
  236. //Mark properties object as having been delegated from by
  237. //client which is implicitly true even though it's created here
  238. //for first time
  239. pInActivationProperties->SetDelegated();
  240. //Delegate through activation properties
  241. IActivationPropertiesOut *pActPropsOut;
  242. *phr = ActivateFromPropertiesPreamble(pInActivationProperties,
  243. &pActPropsOut,
  244. &ActParams);
  245. pOutActivationProperties = ActParams.pActPropsOut;
  246. if ((*phr != S_OK) || (pOutActivationProperties == NULL))
  247. goto exit_oldremote;
  248. *phr = pOutActivationProperties->QueryInterface(IID_IScmReplyInfo,
  249. (LPVOID*)&pScmReplyInfo);
  250. if ( FAILED(*phr) )
  251. goto exit_oldremote;
  252. pScmReplyInfo->GetRemoteReplyInfo(&pReply);
  253. *pOxid = pReply->Oxid;
  254. *ppdsaOxidBindings = pReply->pdsaOxidBindings;
  255. pReply->pdsaOxidBindings = NULL; // so it won't be freed twice
  256. *pipidRemUnknown = pReply->ipidRemUnknown;
  257. *pAuthnHint = pReply->authnHint;
  258. // For custom marshalled interfaces the reply is not set. Don't
  259. // clear the version number in that case.
  260. if (pReply->serverVersion.MajorVersion != 0)
  261. *pServerVersion = pReply->serverVersion;
  262. *phr = pOutActivationProperties->GetMarshalledResults(&count,
  263. &newIIDs,
  264. &pResults,
  265. &ppInterfaceData);
  266. // ********************
  267. // ** Begin fix for NT Bug 312637
  268. // ** April 1, 1999 -- stevesw
  269. // **
  270. // ** GetMarshalledResults puts a pointer to an empty MInterfacePointer
  271. // ** in the ppInterfaceData array. NT4 expects the values to be NULL.
  272. // ** Here we translate from NT5 to NT4 by freeing and nulling out these
  273. // ** array values.
  274. // **
  275. for (i = 0; i < count; i++ )
  276. {
  277. if ( !SUCCEEDED(pResults[i]) ||
  278. ppInterfaceData[i]->ulCntData < 2*sizeof(ULONG) )
  279. {
  280. ActMemFree (ppInterfaceData[i]);
  281. ppInterfaceData[i] = NULL;
  282. }
  283. }
  284. // **
  285. // ** End fix for NT Bug 312637
  286. // ********************
  287. pScmReplyInfo->Release();
  288. count = pOutActivationProperties->Release();
  289. ASSERT(count == 0);
  290. exit_oldremote:
  291. if (pInstanceInfo)
  292. pInstanceInfo->Release();
  293. if (pClassInfo)
  294. pClassInfo->Release();
  295. if (pInitActPropsIn)
  296. pInitActPropsIn->Release();
  297. if (pISpecialSystemProps)
  298. {
  299. pISpecialSystemProps->Release();
  300. }
  301. if (pInScmRequestInfo)
  302. {
  303. count = pInScmRequestInfo->Release();
  304. ASSERT(count == 1);
  305. }
  306. if (pInActivationProperties)
  307. {
  308. count = pInActivationProperties->Release();
  309. ASSERT(count == 0);
  310. }
  311. return rpcerror;
  312. }
  313. //+---------------------------------------------------------------------------
  314. //
  315. // Function: GetServerPath
  316. //
  317. // Synopsis: Computes file name of executable with drive name instead of
  318. // UNC name.
  319. //
  320. // Description: This is to work around limitations in NT's current
  321. // security/rdr. If we get a UNC path to this machine,
  322. // convert it into a drive based path. A server activated as
  323. // the client can not open any UNC path file, even if local,
  324. // so we make it drive based.
  325. //
  326. // On Chicago, we neither have this problem nor do we have
  327. // the NetGetShareInfo entrypoint in the relevant DLL
  328. //
  329. //----------------------------------------------------------------------------
  330. HRESULT GetServerPath(
  331. WCHAR * pwszPath,
  332. WCHAR ** pwszServerPath )
  333. {
  334. WCHAR * pwszFinalPath;
  335. ASSERT(pwszPath != NULL);
  336. ASSERT(pwszServerPath != NULL);
  337. pwszFinalPath = pwszPath;
  338. *pwszServerPath = pwszPath;
  339. if ( (pwszPath[0] == L'\\') && (pwszPath[1] == L'\\') )
  340. {
  341. WCHAR wszMachineName[MAX_COMPUTERNAME_LENGTH+1];
  342. WCHAR * pwszShareName;
  343. WCHAR * pwszShareEnd;
  344. PSHARE_INFO_2 pShareInfo;
  345. NET_API_STATUS Status;
  346. HRESULT hr;
  347. // It's already UNC so this had better succeed.
  348. hr = GetMachineName(
  349. pwszPath,
  350. wszMachineName
  351. #ifdef DFSACTIVATION
  352. ,FALSE
  353. #endif
  354. );
  355. if ( FAILED(hr) )
  356. return hr;
  357. if ( gpMachineName->Compare( wszMachineName ) )
  358. {
  359. pwszShareName = pwszPath + 2;
  360. while ( *pwszShareName++ != L'\\' )
  361. ;
  362. pwszShareEnd = pwszShareName;
  363. while ( *pwszShareEnd != L'\\' )
  364. pwszShareEnd++;
  365. // This is OK, we're just munching on the string the RPC stub passed us.
  366. *pwszShareEnd = 0;
  367. pShareInfo = 0;
  368. Status = NetShareGetInfo(
  369. NULL,
  370. pwszShareName,
  371. 2,
  372. (LPBYTE *)&pShareInfo );
  373. if ( Status != STATUS_SUCCESS )
  374. return (ULONG) CO_E_BAD_PATH;
  375. pwszFinalPath = (WCHAR *) PrivMemAlloc( sizeof(WCHAR) * (MAX_PATH+1) );
  376. if ( ! pwszFinalPath )
  377. {
  378. LocalFree( pShareInfo );
  379. return (ULONG) E_OUTOFMEMORY;
  380. }
  381. lstrcpyW( pwszFinalPath, pShareInfo->shi2_path );
  382. *pwszShareEnd = L'\\';
  383. lstrcatW( pwszFinalPath, pwszShareEnd );
  384. //
  385. // Netapi32.dll midl_user_allocate calls LocalAlloc, so use
  386. // LocalFree to free up the stuff the stub allocated.
  387. //
  388. LocalFree( pShareInfo );
  389. }
  390. }
  391. *pwszServerPath = pwszFinalPath;
  392. return S_OK;
  393. }