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.

1124 lines
30 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: scmif.cxx
  7. //
  8. // Contents: Entry points for scm interface.
  9. //
  10. // Functions: StartObjectService
  11. // SvcActivateObject
  12. // SvcCreateActivateObject
  13. // ObjectServerStarted
  14. // StopServer
  15. //
  16. // History: 01-May-93 Ricksa Created
  17. // 31-Dec-93 ErikGav Chicago port
  18. //
  19. //--------------------------------------------------------------------------
  20. #include "act.hxx"
  21. //+-------------------------------------------------------------------------
  22. //
  23. // Function: Dummy1
  24. //
  25. // Synopsis: Needed for IDL hack. Never called.
  26. //
  27. // Arguments: [hRpc] - RPC handle
  28. // [orpcthis] - ORPC handle
  29. // [localthis] - ORPC call data
  30. // [orpcthat] - ORPC reply data
  31. //
  32. // Returns: HRESULT
  33. //
  34. // History: 14 Apr 95 AlexMit Created
  35. //
  36. //--------------------------------------------------------------------------
  37. extern "C" HRESULT DummyQueryInterfaceIOSCM(
  38. handle_t hRpc,
  39. ORPCTHIS *orpcthis,
  40. LOCALTHIS *localthis,
  41. ORPCTHAT *orpcthat,
  42. DWORD dummy )
  43. {
  44. CairoleDebugOut((DEB_ERROR, "SCM Dummy function should never be called!\n" ));
  45. orpcthat->flags = 0;
  46. orpcthat->extensions = NULL;
  47. return E_FAIL;
  48. }
  49. //+-------------------------------------------------------------------------
  50. //
  51. // Function: Dummy2
  52. //
  53. // Synopsis: Needed for IDL hack. Never called.
  54. //
  55. // Arguments: [hRpc] - RPC handle
  56. // [orpcthis] - ORPC handle
  57. // [localthis] - ORPC call data
  58. // [orpcthat] - ORPC reply data
  59. //
  60. // Returns: HRESULT
  61. //
  62. // History: 14 Apr 95 AlexMit Created
  63. //
  64. //--------------------------------------------------------------------------
  65. extern "C" HRESULT DummyAddRefIOSCM(
  66. handle_t hRpc,
  67. ORPCTHIS *orpcthis,
  68. LOCALTHIS *localthis,
  69. ORPCTHAT *orpcthat,
  70. DWORD dummy )
  71. {
  72. CairoleDebugOut((DEB_ERROR, "SCM Dummy function should never be called!\n" ));
  73. orpcthat->flags = 0;
  74. orpcthat->extensions = NULL;
  75. return E_FAIL;
  76. }
  77. //+-------------------------------------------------------------------------
  78. //
  79. // Function: Dummy3
  80. //
  81. // Synopsis: Needed for IDL hack. Never called.
  82. //
  83. // Arguments: [hRpc] - RPC handle
  84. // [orpcthis] - ORPC handle
  85. // [localthis] - ORPC call data
  86. // [orpcthat] - ORPC reply data
  87. //
  88. // Returns: HRESULT
  89. //
  90. // History: 14 Apr 95 AlexMit Created
  91. //
  92. //--------------------------------------------------------------------------
  93. extern "C" HRESULT DummyReleaseIOSCM(
  94. handle_t hRpc,
  95. ORPCTHIS *orpcthis,
  96. LOCALTHIS *localthis,
  97. ORPCTHAT *orpcthat,
  98. DWORD dummy )
  99. {
  100. CairoleDebugOut((DEB_ERROR, "SCM Dummy function should never be called!\n" ));
  101. orpcthat->flags = 0;
  102. orpcthat->extensions = NULL;
  103. return E_FAIL;
  104. }
  105. //+-------------------------------------------------------------------------
  106. //
  107. // Function: ServerRegisterClsid
  108. //
  109. // Synopsis: Notifies SCM that server is started for a class
  110. //
  111. // Arguments: [hRpc] - RPC handle
  112. // [phProcess] - context handle
  113. // [lpDeskTop] - caller's desktop
  114. // [pregin] - array of registration entries
  115. // [ppregout] - array of registration cookies to return
  116. // [rpcstat] - status code
  117. //
  118. // Returns: HRESULT
  119. //
  120. // History: 01-May-93 Ricksa Created
  121. //
  122. //--------------------------------------------------------------------------
  123. extern "C" HRESULT ServerRegisterClsid(
  124. handle_t hRpc,
  125. PHPROCESS phProcess,
  126. RegInput *pregin,
  127. RegOutput **ppregout,
  128. error_status_t *rpcstat)
  129. {
  130. CProcess * pProcess;
  131. RegOutput * pregout;
  132. CServerTableEntry * pClassTableEntry;
  133. CClsidData * pClsidData = NULL;
  134. DWORD Size, Entries, i;
  135. UCHAR ServerState;
  136. LONG Status;
  137. HRESULT hr;
  138. HANDLE* phRegisterEvents = NULL;
  139. CheckLocalCall( hRpc );
  140. // Parameter validation
  141. if (!pregin || !ppregout || !rpcstat)
  142. return E_INVALIDARG;
  143. *rpcstat = 0;
  144. *ppregout = 0;
  145. pProcess = ReferenceProcess( phProcess, TRUE );
  146. if ( ! pProcess )
  147. return E_ACCESSDENIED;
  148. // Allocate an array of handles to hold the register events.
  149. phRegisterEvents = (HANDLE*)alloca(sizeof(HANDLE) * pregin->dwSize);
  150. memset(phRegisterEvents, 0, sizeof(HANDLE) * pregin->dwSize);
  151. Size = sizeof(RegOutput) + (pregin->dwSize - 1) * sizeof(DWORD);
  152. *ppregout = (RegOutput *) PrivMemAlloc(Size);
  153. if ( ! *ppregout )
  154. {
  155. ReleaseProcess( pProcess );
  156. return E_OUTOFMEMORY;
  157. }
  158. pregout = *ppregout;
  159. memset( pregout, 0, Size );
  160. pregout->dwSize = pregin->dwSize;
  161. Entries = pregin->dwSize;
  162. //
  163. // First loop, we add all of the registrations.
  164. //
  165. for ( i = 0; i < Entries; i++ )
  166. {
  167. pClsidData = 0;
  168. #ifndef _CHICAGO_
  169. // This path taken by non-COM+ servers, ergo
  170. // no IComClassinfo
  171. (void) LookupClsidData(
  172. pregin->rginent[i].clsid,
  173. NULL,
  174. pProcess->GetToken(),
  175. LOAD_APPID,
  176. &pClsidData );
  177. //
  178. // Check that the caller is allowed to register this CLSID.
  179. //
  180. if ( pClsidData && ! pClsidData->CertifyServer( pProcess ) )
  181. {
  182. delete pClsidData;
  183. hr = CO_E_WRONG_SERVER_IDENTITY;
  184. break;
  185. }
  186. #endif
  187. //
  188. // Get the register event for this clsid, to be signalled later on
  189. // in the second loop below. If we couldn't find a pClsidData for
  190. // this clsid, that's fine it just means it was a registration for
  191. // an unknown clsid (which is legal).
  192. //
  193. if (pClsidData)
  194. {
  195. phRegisterEvents[i] = pClsidData->ServerRegisterEvent();
  196. if (!phRegisterEvents[i])
  197. {
  198. delete pClsidData;
  199. hr = E_OUTOFMEMORY;
  200. break;
  201. }
  202. }
  203. ServerState = SERVERSTATE_SUSPENDED;
  204. // Note: REGCLS_SINGLEUSE is *not* a bitflag, it's zero!
  205. // Therefore, it is incompatible with all other flags
  206. if ( pregin->rginent[i].dwFlags == REGCLS_SINGLEUSE )
  207. ServerState |= SERVERSTATE_SINGLEUSE;
  208. if ( pregin->rginent[i].dwFlags & REGCLS_SURROGATE )
  209. ServerState |= SERVERSTATE_SURROGATE;
  210. #if 0 // #ifdef _CHICAGO_
  211. //
  212. // On Win9x, we use a notification window to do lazy registers from a
  213. // single threaded apartment. We don't use the notification window if
  214. // this register is coming in from a resumed suspended registration.
  215. // This is when the overloaded REGCLS_SUSPENDED flag is set.
  216. //
  217. if ( ! (pregin->rginent[i].dwFlags | REGCLS_SUSPENDED) && IsSTAThread() )
  218. ServerState |= SERVERSTATE_USENOTIFYWIN;
  219. #endif
  220. pClassTableEntry = gpClassTable->GetOrCreate( pregin->rginent[i].clsid );
  221. if ( ! pClassTableEntry )
  222. hr = E_OUTOFMEMORY;
  223. if ( pClassTableEntry )
  224. {
  225. hr = pClassTableEntry->RegisterServer(
  226. pProcess,
  227. pregin->rginent[i].ipid,
  228. pClsidData,
  229. NULL,
  230. ServerState,
  231. &pregout->RegKeys[i] );
  232. pClassTableEntry->Release();
  233. }
  234. if ( pClsidData )
  235. {
  236. delete pClsidData;
  237. pClsidData = NULL;
  238. }
  239. if ( hr != S_OK )
  240. break;
  241. }
  242. //
  243. // If we encountered any errors then we remove any entries which were
  244. // successfully added.
  245. //
  246. // On success, we now signal all of the class table events.
  247. //
  248. // This loop restarts itself in removal mode if it encounters an errors
  249. // while trying to signal the register events.
  250. //
  251. for ( i = 0; i < Entries; i++ )
  252. {
  253. HANDLE hRegisterEvent;
  254. pClassTableEntry = gpClassTable->Lookup( pregin->rginent[i].clsid );
  255. if ( S_OK == hr )
  256. {
  257. ASSERT( pClassTableEntry );
  258. pClassTableEntry->UnsuspendServer( pregout->RegKeys[i] );
  259. //
  260. // Signal to waiting client (if any) that this clsid is registered
  261. //
  262. if (phRegisterEvents[i])
  263. {
  264. SetEvent(phRegisterEvents[i]);
  265. CloseHandle(phRegisterEvents[i]);
  266. phRegisterEvents[i] = 0;
  267. }
  268. }
  269. if ( (hr != S_OK) && pregout->RegKeys[i] )
  270. {
  271. if ( pClassTableEntry )
  272. pClassTableEntry->RevokeServer( pProcess, pregout->RegKeys[i] );
  273. }
  274. if ( pClassTableEntry )
  275. pClassTableEntry->Release();
  276. }
  277. if ( hr != S_OK )
  278. memset( pregout->RegKeys, 0, pregout->dwSize * sizeof(DWORD) );
  279. //
  280. // Release all of the registration event handles
  281. //
  282. for (i = 0; i < Entries; i++)
  283. {
  284. if (phRegisterEvents[i])
  285. CloseHandle(phRegisterEvents[i]);
  286. }
  287. ReleaseProcess( pProcess );
  288. return hr;
  289. }
  290. //+-------------------------------------------------------------------------
  291. //
  292. // Function: StopServer
  293. //
  294. // Synopsis: Get notification that class server is stopping
  295. //
  296. // Arguments: [hRpc] - RPC handle
  297. // [prevcls] - list of classes/registrations to stop
  298. //
  299. // History: 01-May-93 Ricksa Created
  300. //
  301. //--------------------------------------------------------------------------
  302. extern "C" void ServerRevokeClsid(
  303. handle_t hRpc,
  304. PHPROCESS phProcess,
  305. RevokeClasses *prevcls,
  306. error_status_t *rpcstat)
  307. {
  308. CServerTableEntry* pClassTableEntry;
  309. RevokeEntry* prevent;
  310. DWORD Entries;
  311. CProcess* pProcess;
  312. CheckLocalCall( hRpc );
  313. // Parameter validation
  314. if (!prevcls || !rpcstat)
  315. return;
  316. pProcess = ReferenceProcess(phProcess);
  317. if (!pProcess)
  318. return;
  319. *rpcstat = 0;
  320. Entries = prevcls->dwSize;
  321. prevent = prevcls->revent;
  322. for ( ; Entries--; prevent++ )
  323. {
  324. pClassTableEntry = gpClassTable->Lookup( prevent->clsid );
  325. if ( pClassTableEntry )
  326. {
  327. pClassTableEntry->RevokeServer( pProcess, prevent->dwReg );
  328. pClassTableEntry->Release();
  329. }
  330. }
  331. }
  332. void GetThreadID(
  333. handle_t hRpc,
  334. DWORD * pThreadID,
  335. error_status_t *prpcstat)
  336. {
  337. CheckLocalCall( hRpc );
  338. // Parameter validation
  339. if (!pThreadID || !prpcstat)
  340. return;
  341. *prpcstat = 0;
  342. *pThreadID = InterlockedExchangeAdd((long *)&gNextThreadID,1);
  343. }
  344. //+-------------------------------------------------------------------------
  345. //
  346. // Function: UpdateActivationSettings
  347. //
  348. // Synopsis: Re-read default activation settings.
  349. //
  350. // Arguments: [hRpc] - RPC handle
  351. // [prpcstat] - communication status
  352. //
  353. //--------------------------------------------------------------------------
  354. #ifdef _CHICAGO_
  355. extern HRESULT ReadRegistry();
  356. #else
  357. extern void ComputeSecurity();
  358. #endif _CHICAGO_
  359. extern "C" void UpdateActivationSettings(
  360. handle_t hRpc,
  361. error_status_t *prpcstat)
  362. {
  363. CheckLocalCall( hRpc );
  364. // Parameter validation
  365. if (!prpcstat)
  366. return;
  367. *prpcstat = 0;
  368. ReadRemoteActivationKeys();
  369. ComputeSecurity();
  370. }
  371. //+-------------------------------------------------------------------------
  372. //
  373. // Function: VerifyCallerIsAdministrator
  374. //
  375. // Synopsis: Verifies that the specified user is an administrator
  376. //
  377. // Returns: S_OK -- success, *pbAdmin is valid
  378. // other -- error occurred
  379. //
  380. // Arguments: [pToken] - token of the user
  381. // [pbAdmin] - out param denoting admin status
  382. //
  383. //--------------------------------------------------------------------------
  384. HRESULT VerifyCallerIsAdministrator(CToken* pToken, BOOL* pbAdmin)
  385. {
  386. BOOL fSuccess;
  387. PSID psidAdmin;
  388. SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
  389. // Allocate sid for Administrators
  390. fSuccess = AllocateAndInitializeSid(&SystemSidAuthority, 2,
  391. SECURITY_BUILTIN_DOMAIN_RID,
  392. DOMAIN_ALIAS_RID_ADMINS,
  393. 0, 0, 0, 0, 0, 0, &psidAdmin);
  394. if (!fSuccess)
  395. return HRESULT_FROM_WIN32(GetLastError());
  396. // Check that caller is an admin
  397. fSuccess = CheckTokenMembership(pToken->GetToken(), psidAdmin, pbAdmin);
  398. FreeSid(psidAdmin);
  399. if (!fSuccess)
  400. return HRESULT_FROM_WIN32(GetLastError());
  401. return S_OK;
  402. }
  403. //+-------------------------------------------------------------------------
  404. //
  405. // Function: EnableDisableDynamicIPTracking
  406. //
  407. // Synopsis: Writes a "Y" or "N" to the HKLM\Software\MS\Ole\
  408. // EnableSystemDynamicIPTracking string value, and sets the
  409. // global variable gbDynamicIPChangesEnabled accordingly.
  410. //
  411. // Arguments: [hRpc] - RPC handle
  412. // [phProcess] - context handle
  413. // [fEnable] - whether to enable or disable
  414. // [prpcstat] - communication status
  415. //
  416. //--------------------------------------------------------------------------
  417. extern "C"
  418. HRESULT EnableDisableDynamicIPTracking(
  419. handle_t hRpc,
  420. PHPROCESS phProcess,
  421. BOOL fEnable,
  422. error_status_t* prpcstat)
  423. {
  424. HRESULT hr = S_OK;
  425. BOOL bAdmin;
  426. ORSTATUS status;
  427. CheckLocalCall( hRpc ); // raises exception if not
  428. // Parameter validation
  429. if (!prpcstat)
  430. return E_INVALIDARG;
  431. *prpcstat = 0; // we got here so we are OK
  432. // Make sure we know who's calling
  433. CProcess* pProcess = ReferenceProcess(phProcess);
  434. if (!pProcess)
  435. return E_ACCESSDENIED;
  436. // Get token for the caller
  437. CToken* pToken;
  438. status = LookupOrCreateToken(hRpc, TRUE, &pToken);
  439. if (status != ERROR_SUCCESS)
  440. return E_ACCESSDENIED;
  441. hr = VerifyCallerIsAdministrator(pToken, &bAdmin);
  442. pToken->Release();
  443. if (FAILED(hr))
  444. return hr;
  445. if (!bAdmin)
  446. return E_ACCESSDENIED;
  447. SCMVDATEHEAP();
  448. hr = gAddrExclusionMgr.EnableDisableDynamicTracking(fEnable);
  449. SCMVDATEHEAP();
  450. return hr;
  451. }
  452. //+-------------------------------------------------------------------------
  453. //
  454. // Function: GetCurrentIPExclusionList
  455. //
  456. // Synopsis: Passes the contents of the current address exclusion list
  457. // back to the caller
  458. //
  459. // Arguments: [hRpc] - RPC handle
  460. // [phProcess] - context handle
  461. // [pdwNumStrings] - size of the pppszStrings array
  462. // [pppszStrings] - array of pointers to NULL-term'd strings
  463. // [prpcstat] - communication status
  464. //
  465. //--------------------------------------------------------------------------
  466. extern "C"
  467. HRESULT GetCurrentAddrExclusionList(
  468. handle_t hRpc,
  469. PHPROCESS phProcess,
  470. DWORD* pdwNumStrings,
  471. LPWSTR** pppszStrings,
  472. error_status_t* prpcstat)
  473. {
  474. HRESULT hr = S_OK;
  475. BOOL bAdmin;
  476. ORSTATUS status;
  477. CheckLocalCall( hRpc ); // raises exception if not
  478. // Parameter validation
  479. if (!pdwNumStrings || !pppszStrings || !prpcstat)
  480. return E_INVALIDARG;
  481. *prpcstat = 0; // we got here so we are OK
  482. // Make sure we know who's calling
  483. CProcess* pProcess = ReferenceProcess(phProcess);
  484. if (!pProcess)
  485. return E_ACCESSDENIED;
  486. // Get token for the caller
  487. CToken* pToken;
  488. status = LookupOrCreateToken(hRpc, TRUE, &pToken);
  489. if (status != ERROR_SUCCESS)
  490. return E_ACCESSDENIED;
  491. hr = VerifyCallerIsAdministrator(pToken, &bAdmin);
  492. pToken->Release();
  493. if (FAILED(hr))
  494. return hr;
  495. if (!bAdmin)
  496. return E_ACCESSDENIED;
  497. SCMVDATEHEAP();
  498. hr = gAddrExclusionMgr.GetExclusionList(
  499. pdwNumStrings,
  500. pppszStrings);
  501. SCMVDATEHEAP();
  502. return hr;
  503. }
  504. //+-------------------------------------------------------------------------
  505. //
  506. // Function: SetAddrExclusionList
  507. //
  508. // Synopsis: Re-sets the contents of the address exclusion list, and updates
  509. // all currently running processes with the new bindings.
  510. //
  511. // Arguments: [hRpc] - RPC handle
  512. // [phProcess] - context handle
  513. // [dwNumStrings] - size of the ppszStrings array
  514. // [ppszStrings] - array of pointers to NULL-term'd strings
  515. // [prpcstat] - communication status
  516. //
  517. //--------------------------------------------------------------------------
  518. extern "C"
  519. HRESULT SetAddrExclusionList(
  520. handle_t hRpc,
  521. PHPROCESS phProcess,
  522. DWORD dwNumStrings,
  523. LPWSTR* ppszStrings,
  524. error_status_t* prpcstat)
  525. {
  526. HRESULT hr = S_OK;
  527. BOOL bAdmin;
  528. ORSTATUS status;
  529. CheckLocalCall( hRpc ); // raises exception if not
  530. // Parameter validation
  531. if (!ppszStrings || !prpcstat)
  532. return E_INVALIDARG;
  533. *prpcstat = 0; // we got here so we are OK
  534. // Make sure we know who's calling
  535. CProcess* pProcess = ReferenceProcess(phProcess);
  536. if (!pProcess)
  537. return E_ACCESSDENIED;
  538. // Get token for the caller
  539. CToken* pToken;
  540. status = LookupOrCreateToken(hRpc, TRUE, &pToken);
  541. if (status != ERROR_SUCCESS)
  542. return E_ACCESSDENIED;
  543. hr = VerifyCallerIsAdministrator(pToken, &bAdmin);
  544. pToken->Release();
  545. if (FAILED(hr))
  546. return hr;
  547. if (!bAdmin)
  548. return E_ACCESSDENIED;
  549. SCMVDATEHEAP();
  550. hr = gAddrExclusionMgr.SetExclusionList(
  551. dwNumStrings,
  552. ppszStrings);
  553. SCMVDATEHEAP();
  554. return hr;
  555. }
  556. //+-------------------------------------------------------------------------
  557. //
  558. // Function: FlushSCMBindings
  559. //
  560. // Synopsis: Remove the specified machine bindings from our remote binding
  561. // handle cache
  562. //
  563. // Arguments: [hRpc] - RPC handle
  564. // [prpcstat] - communication status
  565. //
  566. //--------------------------------------------------------------------------
  567. extern "C"
  568. HRESULT FlushSCMBindings(
  569. handle_t hRpc,
  570. PHPROCESS phProcess,
  571. WCHAR* pszMachineName,
  572. error_status_t* prpcstat)
  573. {
  574. HRESULT hr;
  575. BOOL bAdmin;
  576. ORSTATUS status;
  577. CheckLocalCall( hRpc ); // raises exception if not
  578. // Parameter validation
  579. if (!pszMachineName || !prpcstat)
  580. return E_INVALIDARG;
  581. *prpcstat = 0; // we got here so we are OK
  582. // Make sure we know who's calling
  583. CProcess* pProcess = ReferenceProcess(phProcess);
  584. if (!pProcess)
  585. return E_ACCESSDENIED;
  586. // Get token for the caller
  587. CToken* pToken;
  588. status = LookupOrCreateToken(hRpc, TRUE, &pToken);
  589. if (status != ERROR_SUCCESS)
  590. return E_ACCESSDENIED;
  591. hr = VerifyCallerIsAdministrator(pToken, &bAdmin);
  592. pToken->Release();
  593. if (FAILED(hr))
  594. return hr;
  595. if (!bAdmin)
  596. return E_ACCESSDENIED;
  597. SCMVDATEHEAP();
  598. hr = gpRemoteMachineList->FlushSpecificBindings(pszMachineName);
  599. SCMVDATEHEAP();
  600. return hr;
  601. }
  602. //+-------------------------------------------------------------------------
  603. //
  604. // Function: RetireServer
  605. //
  606. // Synopsis: Marks the specified server as being no longer eligible for
  607. // component activations of any type. Currently only used
  608. // to support COM+'s process recycling feature.
  609. //
  610. // Arguments: [hRpc] - RPC handle
  611. // [pguidProcessIdentifier] - guid which identifies the server
  612. // [prpcstat] - communication status
  613. //
  614. //--------------------------------------------------------------------------
  615. extern "C"
  616. HRESULT RetireServer(
  617. handle_t hRpc,
  618. PHPROCESS phProcess,
  619. GUID* pguidProcessIdentifier,
  620. error_status_t* prpcstat)
  621. {
  622. CheckLocalCall( hRpc ); // raises exception if not
  623. // Parameter validation
  624. if (!pguidProcessIdentifier || !prpcstat)
  625. return E_INVALIDARG;
  626. *prpcstat = 0; // we got here so we are OK
  627. if (!pguidProcessIdentifier)
  628. return E_INVALIDARG;
  629. // Make sure we know who's calling
  630. CProcess* pProcess = ReferenceProcess(phProcess);
  631. if (!pProcess)
  632. return E_ACCESSDENIED;
  633. // Get token for the caller
  634. CToken* pToken;
  635. ORSTATUS status;
  636. status = LookupOrCreateToken(hRpc, TRUE, &pToken);
  637. if (status != ERROR_SUCCESS)
  638. return E_ACCESSDENIED;
  639. // Make sure they're an administrator
  640. HRESULT hr;
  641. BOOL bAdmin;
  642. hr = VerifyCallerIsAdministrator(pToken, &bAdmin);
  643. pToken->Release();
  644. if (FAILED(hr))
  645. return hr;
  646. if (!bAdmin)
  647. return E_ACCESSDENIED;
  648. // Okay, see if we know which process they're talking about
  649. gpProcessListLock->LockShared();
  650. hr = E_INVALIDARG; // review for better code when we don't find the process
  651. CBListIterator all_procs(gpProcessList);
  652. CProcess* pprocess;
  653. while (pprocess = (CProcess*)all_procs.Next())
  654. {
  655. if (*pprocess->GetGuidProcessIdentifier() == *pguidProcessIdentifier)
  656. {
  657. // Found it. Mark it as retired
  658. pprocess->Retire();
  659. hr = S_OK;
  660. break;
  661. }
  662. }
  663. gpProcessListLock->UnlockShared();
  664. return hr;
  665. }
  666. CWIPTable gWIPTbl; // global instance of the class
  667. CWIPTable * gpWIPTbl = &gWIPTbl;
  668. //+-------------------------------------------------------------------------
  669. //
  670. // Function: CopyDualStringArray
  671. //
  672. // Synopsis: makes a copy of the given string array
  673. //
  674. // History: 22-Jan-96 Rickhi Created
  675. //
  676. //--------------------------------------------------------------------------
  677. HRESULT CopyDualStringArray(DUALSTRINGARRAY *psa, DUALSTRINGARRAY **ppsaNew)
  678. {
  679. ULONG ulSize = sizeof(DUALSTRINGARRAY) + (psa->wNumEntries * sizeof(WCHAR));
  680. *ppsaNew = (DUALSTRINGARRAY *) PrivMemAlloc(ulSize);
  681. if (*ppsaNew == NULL)
  682. {
  683. return E_OUTOFMEMORY;
  684. }
  685. memcpy(*ppsaNew, psa, ulSize);
  686. return S_OK;
  687. }
  688. //+-------------------------------------------------------------------------
  689. //
  690. // Member: CWIPTable::AddEntry, public
  691. //
  692. // Synopsis: Adds a WIPEntry to the table.
  693. //
  694. // Arguments: [hWnd] - window handle
  695. // [pStd] - standard marshaled interface STDOBJREF
  696. // [pOxidInfo] - info needed to resolve the OXID
  697. // [pdwCookie] - cookie to return (to be placed on the window)
  698. //
  699. // History: 22-Jan-96 Rickhi Created
  700. //
  701. //--------------------------------------------------------------------------
  702. HRESULT CWIPTable::AddEntry(
  703. DWORD_PTR hWnd,
  704. STDOBJREF *pStd,
  705. OXID_INFO *pOxidInfo,
  706. DWORD_PTR *pdwCookie
  707. )
  708. {
  709. // make a copy of the string array in the OxidInfo since MIDL will
  710. // delete it on the way back out of the call.
  711. DUALSTRINGARRAY *psaNew;
  712. HRESULT hr;
  713. if (m_fCsInitialized == FALSE)
  714. {
  715. ASSERT(FALSE);
  716. return E_OUTOFMEMORY;
  717. }
  718. psaNew = (DUALSTRINGARRAY *) PrivMemAlloc(sizeof(DUALSTRINGARRAY) + (pOxidInfo->psa->wNumEntries * sizeof(WCHAR)));
  719. if (psaNew == NULL)
  720. {
  721. return E_OUTOFMEMORY;
  722. }
  723. memcpy(psaNew, pOxidInfo->psa, sizeof(DUALSTRINGARRAY) + (pOxidInfo->psa->wNumEntries * sizeof(WCHAR)));
  724. #if 0 // #ifdef _CHICAGO_
  725. CLockSmMutex lck(gWIPmxs);
  726. #else
  727. CLock2 lck(s_mxs);
  728. #endif
  729. // find a free slot in the table
  730. DWORD_PTR dwpIndex = s_iNextFree;
  731. if (dwpIndex == (DWORD_PTR)-1)
  732. {
  733. // grow the table
  734. dwpIndex = Grow();
  735. }
  736. if (dwpIndex != (DWORD_PTR)-1)
  737. {
  738. // get the pointer to the entry,
  739. WIPEntry *pEntry = s_pTbl + dwpIndex;
  740. // update the next free index.
  741. s_iNextFree = pEntry->hWnd;
  742. // copy in the data
  743. memcpy(&pEntry->std, pStd, sizeof(STDOBJREF));
  744. memcpy(&pEntry->oxidInfo, pOxidInfo, sizeof(OXID_INFO));
  745. pEntry->oxidInfo.psa = psaNew;
  746. pEntry->hWnd = hWnd;
  747. pEntry->dwFlags = WIPF_OCCUPIED;
  748. // set the cookie to return
  749. *pdwCookie = dwpIndex+5000;
  750. // return success
  751. hr = S_OK;
  752. }
  753. else
  754. {
  755. // free the allocated string array
  756. PrivMemFree(psaNew);
  757. hr = E_OUTOFMEMORY;
  758. }
  759. return hr;
  760. }
  761. //+-------------------------------------------------------------------------
  762. //
  763. // Member: CWIPTable::GetEntry, public
  764. //
  765. // Synopsis: Retrieves and optionally delets a WIPEntry from the table.
  766. //
  767. // Arguments: [hWnd] - window handle
  768. // [dwCookie] - cookie from the window
  769. // [pStd] - place to return STDOBJREF data
  770. // [pOxidInfo] - place to return info needed to resolve the OXID
  771. //
  772. // History: 22-Jan-96 Rickhi Created
  773. //
  774. //--------------------------------------------------------------------------
  775. HRESULT CWIPTable::GetEntry(
  776. DWORD_PTR hWnd,
  777. DWORD_PTR dwCookie,
  778. BOOL fRevoke,
  779. STDOBJREF *pStd,
  780. OXID_INFO *pOxidInfo)
  781. {
  782. HRESULT hr = E_INVALIDARG;
  783. // validate the cookie
  784. DWORD_PTR dwpIndex = dwCookie - 5000;
  785. if (dwpIndex >= s_cEntries)
  786. {
  787. return hr;
  788. }
  789. if (m_fCsInitialized == FALSE)
  790. {
  791. ASSERT(FALSE);
  792. return E_OUTOFMEMORY;
  793. }
  794. #if 0 // #ifdef _CHICAGO_
  795. CLockSmMutex lck(gWIPmxs);
  796. #else
  797. CLock2 lck(s_mxs);
  798. #endif
  799. // get the pointer to the entry,
  800. WIPEntry *pEntry = s_pTbl + dwpIndex;
  801. // make sure the entry is occupied
  802. if (pEntry->dwFlags & WIPF_OCCUPIED)
  803. {
  804. DUALSTRINGARRAY *psaNew;
  805. psaNew = (DUALSTRINGARRAY *) PrivMemAlloc(sizeof(DUALSTRINGARRAY) + (pEntry->oxidInfo.psa->wNumEntries * sizeof(WCHAR)));
  806. if (psaNew == NULL)
  807. {
  808. return E_OUTOFMEMORY;
  809. }
  810. memcpy(psaNew, pEntry->oxidInfo.psa, sizeof(DUALSTRINGARRAY) + (pEntry->oxidInfo.psa->wNumEntries * sizeof(WCHAR)));
  811. // copy out the data to return
  812. memcpy(pStd, &pEntry->std, sizeof(STDOBJREF));
  813. memcpy(pOxidInfo, &pEntry->oxidInfo, sizeof(OXID_INFO));
  814. pOxidInfo->psa = psaNew;
  815. if (fRevoke)
  816. {
  817. // free the entry by updating the flags and the next free index
  818. PrivMemFree(pEntry->oxidInfo.psa);
  819. pEntry->dwFlags = WIPF_VACANT;
  820. pEntry->hWnd = s_iNextFree;
  821. s_iNextFree = dwpIndex;
  822. }
  823. // return success
  824. hr = S_OK;
  825. }
  826. return hr;
  827. }
  828. //+-------------------------------------------------------------------------
  829. //
  830. // Member: CWIPTable::Grow, private
  831. //
  832. // Synopsis: grows the WIPTable size.
  833. //
  834. // History: 22-Jan-96 Rickhi Created
  835. //
  836. //--------------------------------------------------------------------------
  837. DWORD_PTR CWIPTable::Grow()
  838. {
  839. // compute the size and allocate a new table
  840. DWORD_PTR dwSize = (s_cEntries + WIPTBL_GROW_SIZE) * sizeof(WIPEntry);
  841. WIPEntry *pNewTbl = (WIPEntry *) PrivMemAlloc((size_t)dwSize);
  842. if (pNewTbl != NULL)
  843. {
  844. // copy the old table in
  845. memcpy(pNewTbl, s_pTbl, (size_t)(s_cEntries * sizeof(WIPEntry)));
  846. // free the old table
  847. if (s_pTbl)
  848. {
  849. PrivMemFree(s_pTbl);
  850. }
  851. // replace the old table ptr
  852. s_pTbl = pNewTbl;
  853. // update the free list and mark the new entries as vacant
  854. s_iNextFree = s_cEntries;
  855. WIPEntry *pNext = s_pTbl + s_cEntries;
  856. for (ULONG i=0; i< WIPTBL_GROW_SIZE; i++)
  857. {
  858. pNext->hWnd = ++s_cEntries;
  859. pNext->dwFlags = WIPF_VACANT;
  860. pNext++;
  861. }
  862. (pNext-1)->hWnd = (DWORD_PTR)-1; // last entry has END_OF_LIST marker
  863. }
  864. return s_iNextFree;
  865. }
  866. //+-------------------------------------------------------------------------
  867. //
  868. // Function: RegisterWindowPropInterface
  869. //
  870. // Synopsis: Associate a window property with a (standard) marshaled
  871. // interface.
  872. //
  873. // Arguments: [hRpc] - RPC handle
  874. // [hWnd] - window handle
  875. // [pStd] - standard marshaled interface STDOBJREF
  876. // [pOxidInfo] - info needed to resolve the OXID
  877. // [pdwCookie] - cookie to return (to be placed on the window)
  878. // [prpcstat] - communication status
  879. //
  880. // History: 22-Jan-96 Rickhi Created
  881. //
  882. //--------------------------------------------------------------------------
  883. extern "C" HRESULT RegisterWindowPropInterface(
  884. handle_t hRpc,
  885. DWORD_PTR hWnd,
  886. STDOBJREF *pStd,
  887. OXID_INFO *pOxidInfo,
  888. DWORD_PTR *pdwCookie,
  889. error_status_t *prpcstat)
  890. {
  891. CheckLocalCall( hRpc );
  892. // Parameter validation
  893. if (!pStd || !pOxidInfo || !pOxidInfo->psa || !pdwCookie || !prpcstat)
  894. return E_INVALIDARG;
  895. *prpcstat = 0;
  896. CairoleDebugOut((DEB_SCM,
  897. "_IN RegisterWindowPropInterface hWnd:%x pStd:%x pOxidInfo:%x\n",
  898. hWnd, pStd, pOxidInfo));
  899. VDATEHEAP();
  900. HRESULT hr = gpWIPTbl->AddEntry(hWnd, pStd, pOxidInfo, pdwCookie);
  901. CairoleDebugOut((DEB_SCM, "_OUT RegisterWindowPropInterface dwCookie:%x\n",
  902. *pdwCookie));
  903. VDATEHEAP();
  904. return hr;
  905. }
  906. //+-------------------------------------------------------------------------
  907. //
  908. // Function: GetWindowPropInterface
  909. //
  910. // Synopsis: Get the marshaled interface associated with a window property.
  911. //
  912. // Arguments: [hRpc] - RPC handle
  913. // [hWnd] - window handle
  914. // [dwCookie] - cookie from the window
  915. // [fRevoke] - whether to revoke entry or not
  916. // [pStd] - standard marshaled interface STDOBJREF to return
  917. // [pOxidInfo] - info needed to resolve the OXID
  918. // [prpcstat] - communication status
  919. //
  920. // History: 22-Jan-96 Rickhi Created
  921. //
  922. //--------------------------------------------------------------------------
  923. extern "C" HRESULT GetWindowPropInterface(
  924. handle_t hRpc,
  925. DWORD_PTR hWnd,
  926. DWORD_PTR dwCookie,
  927. BOOL fRevoke,
  928. STDOBJREF *pStd,
  929. OXID_INFO *pOxidInfo,
  930. error_status_t *prpcstat)
  931. {
  932. CheckLocalCall( hRpc );
  933. // Parameter validation
  934. if (!pStd || !pOxidInfo || !prpcstat)
  935. return E_INVALIDARG;
  936. *prpcstat = 0;
  937. CairoleDebugOut((DEB_SCM,
  938. "_IN GetWindowPropInterface hWnd:%x dwCookie:%x fRevoke:%x\n",
  939. hWnd, dwCookie, fRevoke));
  940. VDATEHEAP();
  941. HRESULT hr = gpWIPTbl->GetEntry(hWnd, dwCookie, fRevoke, pStd, pOxidInfo);
  942. CairoleDebugOut((DEB_SCM,
  943. "_OUT GetWindowPropInterface pStd:%x pOxidInfo:%x\n", pStd, pOxidInfo));
  944. VDATEHEAP();
  945. return hr;
  946. }