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.

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