Windows NT 4.0 source code leak
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.

952 lines
22 KiB

4 years ago
  1. #if !defined(__RPC_DOS__) && !defined(__RPC_WIN16__)
  2. //+-------------------------------------------------------------------------
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  6. //
  7. // File: rpcproxy.c
  8. //
  9. // Contents: Contains runtime functions for interface proxies and stubs.
  10. //
  11. // Functions:
  12. // DllGetClassObject
  13. // DllCanUnloadNow
  14. // MIDL_user_allocate
  15. // MIDL_user_free
  16. // NdrGetProxyBuffer
  17. // NdrGetProxyIID
  18. // NdrProxyInitialize
  19. // NdrProxyGetBuffer
  20. // NdrProxySendReceive
  21. // NdrProxyFreeBuffer
  22. // NdrProxyErrorHandler
  23. // NdrStubInitialize
  24. // NdrStubGetBuffer
  25. //
  26. // Classes: CStdProxyBuffer
  27. // CStdPSFactoryBuffer
  28. // CStdStubBuffer
  29. //
  30. //
  31. //
  32. //--------------------------------------------------------------------------
  33. #include <rpcproxy.h>
  34. #include <assert.h>
  35. //+-------------------------------------------------------------------------
  36. //
  37. // Global data
  38. //
  39. //--------------------------------------------------------------------------
  40. long DllRefCount = 0;
  41. IPSFactoryBufferVtbl CStdPSFactoryBufferVtbl = {
  42. CStdPSFactoryBuffer_QueryInterface,
  43. CStdPSFactoryBuffer_AddRef,
  44. CStdPSFactoryBuffer_Release,
  45. CStdPSFactoryBuffer_CreateProxy,
  46. CStdPSFactoryBuffer_CreateStub };
  47. CStdPSFactoryBuffer gPSFactoryBuffer = {
  48. &CStdPSFactoryBufferVtbl,
  49. 0 };
  50. IRpcProxyBufferVtbl CStdProxyBufferVtbl = {
  51. CStdProxyBuffer_QueryInterface,
  52. CStdProxyBuffer_AddRef,
  53. CStdProxyBuffer_Release,
  54. CStdProxyBuffer_Connect,
  55. CStdProxyBuffer_Disconnect };
  56. //+-------------------------------------------------------------------------
  57. //
  58. // Function: DllGetClassObject
  59. //
  60. // Synopsis: Standard implementation of entrypoint required by binder.
  61. //
  62. // Arguments: [rclsid] -- class id to find
  63. // [riid] -- interface to return
  64. // [ppv] -- output pointer
  65. //
  66. // Returns: E_UNEXPECTED if class not found
  67. // Otherwise, whatever is returned by the class's QI
  68. //
  69. // Algorithm: Searches the linked list for the required class.
  70. //
  71. // Notes:
  72. //
  73. //--------------------------------------------------------------------------
  74. HRESULT STDAPICALLTYPE DllGetClassObject (
  75. REFCLSID rclsid,
  76. REFIID riid,
  77. LPVOID FAR* ppv )
  78. {
  79. HRESULT hr = E_UNEXPECTED;
  80. assert(rclsid);
  81. assert(riid);
  82. assert(ppv);
  83. *ppv = 0;
  84. if(memcmp(rclsid, &CLSID_PSFactoryBuffer, sizeof(IID)) == 0)
  85. hr = gPSFactoryBuffer.lpVtbl->QueryInterface((IPSFactoryBuffer *)&gPSFactoryBuffer, riid, ppv);
  86. return hr;
  87. }
  88. //+-------------------------------------------------------------------------
  89. //
  90. // Function: DllCanUnloadNow
  91. //
  92. // Synopsis: Standard entrypoint required by binder
  93. //
  94. // Returns: S_OK if DLL reference count is zero
  95. // S_FALSE otherwise
  96. //
  97. //--------------------------------------------------------------------------
  98. HRESULT STDAPICALLTYPE DllCanUnloadNow ()
  99. {
  100. HRESULT hr;
  101. if(DllRefCount == 0)
  102. hr = S_OK;
  103. else
  104. hr = S_FALSE;
  105. return hr;
  106. }
  107. //+-------------------------------------------------------------------------
  108. //
  109. // Method: CStdPSFactoryBuffer_QueryInterface, public
  110. //
  111. // Synopsis: Query for an interface on the class factory.
  112. //
  113. // Derivation: IUnknown
  114. //
  115. //--------------------------------------------------------------------------
  116. HRESULT STDMETHODCALLTYPE
  117. CStdPSFactoryBuffer_QueryInterface (
  118. IPSFactoryBuffer *pThis,
  119. REFIID iid,
  120. void **ppv )
  121. {
  122. HRESULT hr = E_NOINTERFACE;
  123. assert(pThis);
  124. assert(iid);
  125. assert(ppv);
  126. *ppv = 0;
  127. if ((memcmp(iid, &IID_IUnknown, sizeof(IID)) == 0) ||
  128. (memcmp(iid, &IID_IPSFactoryBuffer, sizeof(IID)) == 0))
  129. {
  130. *ppv = pThis;
  131. pThis->lpVtbl->AddRef(pThis);
  132. hr = S_OK;
  133. }
  134. return hr;
  135. }
  136. //+-------------------------------------------------------------------------
  137. //
  138. // Method: CStdPSFactoryBuffer_AddRef, public
  139. //
  140. // Synopsis: Increment DLL reference counts
  141. //
  142. // Derivation: IUnknown
  143. //
  144. // Notes: We have a single instance of the CStdPSFactoryBuffer.
  145. //
  146. //--------------------------------------------------------------------------
  147. ULONG STDMETHODCALLTYPE
  148. CStdPSFactoryBuffer_AddRef(
  149. IPSFactoryBuffer *this)
  150. {
  151. assert(this);
  152. InterlockedIncrement(&((CStdPSFactoryBuffer *)this)->RefCount);
  153. InterlockedIncrement(&DllRefCount);
  154. return (unsigned long) ((CStdPSFactoryBuffer *)this)->RefCount;
  155. }
  156. //+-------------------------------------------------------------------------
  157. //
  158. // Method: CStdPSFactoryBuffer_Release, public
  159. //
  160. // Synopsis: Decrement DLL reference count
  161. //
  162. // Derivation: IUnknown
  163. //
  164. //--------------------------------------------------------------------------
  165. ULONG STDMETHODCALLTYPE
  166. CStdPSFactoryBuffer_Release(
  167. IPSFactoryBuffer *this)
  168. {
  169. long t;
  170. unsigned long count;
  171. assert(this);
  172. t = InterlockedDecrement(&((CStdPSFactoryBuffer *)this)->RefCount);
  173. InterlockedDecrement(&DllRefCount);
  174. if(t == 0)
  175. count = 0;
  176. else
  177. count = (unsigned long) ((CStdPSFactoryBuffer *)this)->RefCount;
  178. return count;
  179. }
  180. //+-------------------------------------------------------------------------
  181. //
  182. // Method: CStdPSFactoryBuffer_CreateProxy, public
  183. //
  184. // Synopsis: Create a proxy for the specified interface.
  185. //
  186. //--------------------------------------------------------------------------
  187. HRESULT STDMETHODCALLTYPE
  188. CStdPSFactoryBuffer_CreateProxy
  189. (
  190. IPSFactoryBuffer *this,
  191. IUnknown *punkOuter,
  192. REFIID riid,
  193. IRpcProxyBuffer **ppProxy,
  194. void **ppv
  195. )
  196. {
  197. HRESULT hr = E_OUTOFMEMORY;
  198. const IID *pIID;
  199. CStdProxyBuffer *pProxyBuffer = 0;
  200. int i, j;
  201. assert(this);
  202. assert(riid);
  203. assert(ppProxy);
  204. assert(ppv);
  205. *ppProxy = 0;
  206. *ppv = 0;
  207. //Search the list of proxy files.
  208. for(i = 0;
  209. pProxyFileList[i] && !pProxyBuffer;
  210. i++)
  211. {
  212. //Search the interface proxies in the proxy buffer
  213. for(j = 0;
  214. ((CStdProxyBuffer *)pProxyFileList[i]->pProxyBuffer)->aProxyVtbl[j] && !pProxyBuffer;
  215. j++)
  216. {
  217. pIID = NdrGetProxyIID(&((CStdProxyBuffer *)pProxyFileList[i]->pProxyBuffer)->aProxyVtbl[j]);
  218. assert(pIID);
  219. if(memcmp(riid, pIID, sizeof(IID)) == 0)
  220. {
  221. //We found the interface!
  222. //Allocate memory for the new proxy buffer.
  223. pProxyBuffer = (CStdProxyBuffer *) CoTaskMemAlloc(pProxyFileList[i]->ProxyBufferSize);
  224. if(pProxyBuffer)
  225. {
  226. //Initialize the new proxy buffer.
  227. memcpy(pProxyBuffer, pProxyFileList[i]->pProxyBuffer, pProxyFileList[i]->ProxyBufferSize);
  228. pProxyBuffer->punkOuter = punkOuter;
  229. //Increment the DLL reference count.
  230. InterlockedIncrement(&DllRefCount);
  231. *ppProxy = (IRpcProxyBuffer *) pProxyBuffer;
  232. *ppv = &pProxyBuffer->aProxyVtbl[j];
  233. hr = S_OK;
  234. }
  235. }
  236. }
  237. }
  238. return hr;
  239. }
  240. //+-------------------------------------------------------------------------
  241. //
  242. // Method: CStdPSFactoryBuffer_CreateStub, public
  243. //
  244. // Synopsis: Create a stub for the specified interface.
  245. //
  246. //--------------------------------------------------------------------------
  247. HRESULT STDMETHODCALLTYPE
  248. CStdPSFactoryBuffer_CreateStub
  249. (
  250. IPSFactoryBuffer *this,
  251. REFIID riid,
  252. IUnknown *punkServer,
  253. IRpcStubBuffer **ppStub
  254. )
  255. {
  256. HRESULT hr = E_OUTOFMEMORY;
  257. const IID *pIID;
  258. CStdStubBuffer *pStubBuffer = 0;
  259. int i, j;
  260. assert(this);
  261. assert(riid);
  262. assert(ppStub);
  263. *ppStub = 0;
  264. //Search the list of proxy files.
  265. for(i = 0;
  266. pProxyFileList[i] && !pStubBuffer;
  267. i++)
  268. {
  269. //Search the interface stubs in the stub buffer
  270. for(j = 0;
  271. ((CStdStubBuffer *)pProxyFileList[i]->pStubBuffer)->aInterfaceStub[j].lpVtbl && !pStubBuffer;
  272. j++)
  273. {
  274. pIID = NdrGetStubIID(&((CStdStubBuffer *)pProxyFileList[i]->pStubBuffer)->aInterfaceStub[j].lpVtbl);
  275. assert(pIID);
  276. if(memcmp(riid, pIID, sizeof(IID)) == 0)
  277. {
  278. //We found the interface!
  279. //Allocate memory for the new proxy buffer.
  280. pStubBuffer = (CStdStubBuffer *) CoTaskMemAlloc(pProxyFileList[i]->StubBufferSize);
  281. if(pStubBuffer)
  282. {
  283. //Initialize the new stub buffer.
  284. memcpy(pStubBuffer, pProxyFileList[i]->pStubBuffer, pProxyFileList[i]->StubBufferSize);
  285. if(punkServer)
  286. {
  287. punkServer->lpVtbl->AddRef(punkServer);
  288. pStubBuffer->punkObject = punkServer;
  289. hr = punkServer->lpVtbl->QueryInterface(punkServer, riid, &pStubBuffer->aInterfaceStub[j].pvServerObject);
  290. }
  291. else
  292. hr = S_OK;
  293. if(FAILED(hr))
  294. CoTaskMemFree(pStubBuffer);
  295. else
  296. {
  297. *ppStub = (IRpcStubBuffer *) &pStubBuffer->aInterfaceStub[j].lpVtbl;
  298. //Increment the DLL reference count.
  299. InterlockedIncrement(&DllRefCount);
  300. }
  301. }
  302. }
  303. }
  304. }
  305. return hr;
  306. }
  307. //+-------------------------------------------------------------------------
  308. //
  309. // Method: CStdProxyBuffer_QueryInterface, public
  310. //
  311. // Synopsis: Query for an interface on the proxy. This provides access
  312. // to both internal and external interfaces.
  313. //
  314. //--------------------------------------------------------------------------
  315. HRESULT STDMETHODCALLTYPE
  316. CStdProxyBuffer_QueryInterface(IRpcProxyBuffer *pThis, REFIID riid, void **ppv)
  317. {
  318. HRESULT hr = E_NOINTERFACE;
  319. CStdProxyBuffer *pProxyBuffer = (CStdProxyBuffer *) pThis;
  320. void *pInterfaceProxy = 0;
  321. int j;
  322. const IID *pIID;
  323. assert(pThis);
  324. assert(riid);
  325. assert(ppv);
  326. *ppv = 0;
  327. if((memcmp(riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  328. (memcmp(riid, &IID_IRpcProxyBuffer, sizeof(IID)) == 0))
  329. {
  330. //This is an internal interface. Increment the internal reference count.
  331. InterlockedIncrement( &((CStdProxyBuffer *)pThis)->RefCount);
  332. *ppv = pThis;
  333. hr = S_OK;
  334. }
  335. //Search the interface proxies in the proxy buffer
  336. for(j = 0;
  337. pProxyBuffer->aProxyVtbl[j] && !pInterfaceProxy;
  338. j++)
  339. {
  340. pIID = NdrGetProxyIID(&pProxyBuffer->aProxyVtbl[j]);
  341. assert(pIID);
  342. if(memcmp(riid, pIID, sizeof(IID)) == 0)
  343. {
  344. //We found the interface!
  345. pInterfaceProxy = &pProxyBuffer->aProxyVtbl[j];
  346. //Increment the reference count.
  347. if(pProxyBuffer->punkOuter)
  348. {
  349. pProxyBuffer->punkOuter->lpVtbl->AddRef(pProxyBuffer->punkOuter);
  350. }
  351. else
  352. {
  353. InterlockedIncrement(&pProxyBuffer->RefCount);
  354. }
  355. *ppv = pInterfaceProxy;
  356. hr = S_OK;
  357. }
  358. }
  359. return hr;
  360. };
  361. //+-------------------------------------------------------------------------
  362. //
  363. // Method: CStdProxyBuffer_AddRef, public
  364. //
  365. // Synopsis: Increment reference count.
  366. //
  367. //--------------------------------------------------------------------------
  368. ULONG STDMETHODCALLTYPE
  369. CStdProxyBuffer_AddRef(IRpcProxyBuffer *pThis)
  370. {
  371. InterlockedIncrement(&((CStdProxyBuffer *)pThis)->RefCount);
  372. return (ULONG) ((CStdProxyBuffer *)pThis)->RefCount;
  373. };
  374. //+-------------------------------------------------------------------------
  375. //
  376. // Method: CStdProxyBuffer_Release, public
  377. //
  378. // Synopsis: Decrement reference count.
  379. //
  380. //--------------------------------------------------------------------------
  381. ULONG STDMETHODCALLTYPE
  382. CStdProxyBuffer_Release(IRpcProxyBuffer *pThis)
  383. {
  384. long RefCount;
  385. unsigned long count;
  386. assert(pThis);
  387. RefCount = InterlockedDecrement(&((CStdProxyBuffer *)pThis)->RefCount);
  388. assert(RefCount >= 0);
  389. if(RefCount == 0)
  390. {
  391. count = 0;
  392. //Decrement the DLL reference count.
  393. InterlockedDecrement(&DllRefCount);
  394. //Free the memory
  395. MIDL_user_free(pThis);
  396. }
  397. else
  398. count = (unsigned long) ((CStdProxyBuffer *)pThis)->RefCount;
  399. return count;
  400. };
  401. //+-------------------------------------------------------------------------
  402. //
  403. // Method: CStdProxyBuffer_Connect, public
  404. //
  405. // Synopsis: Connect the proxy to the channel.
  406. //
  407. //--------------------------------------------------------------------------
  408. HRESULT STDMETHODCALLTYPE
  409. CStdProxyBuffer_Connect(IRpcProxyBuffer *pThis, IRpcChannelBuffer *pChannel)
  410. {
  411. HRESULT hr = E_UNEXPECTED;
  412. assert(pThis);
  413. pThis->lpVtbl->Disconnect(pThis);
  414. if(pChannel)
  415. hr = pChannel->lpVtbl->QueryInterface(pChannel, &IID_IRpcChannelBuffer, &((CStdProxyBuffer *)pThis)->pChannel);
  416. return hr;
  417. };
  418. //+-------------------------------------------------------------------------
  419. //
  420. // Method: CStdProxyBuffer_Disconnect, public
  421. //
  422. // Synopsis: Disconnect the proxy from the channel.
  423. //
  424. // Derivation: IRpcProxyBuffer
  425. //
  426. //--------------------------------------------------------------------------
  427. void STDMETHODCALLTYPE
  428. CStdProxyBuffer_Disconnect(IRpcProxyBuffer *pThis)
  429. {
  430. assert(pThis);
  431. if(((CStdProxyBuffer *)pThis)->pChannel)
  432. {
  433. ((CStdProxyBuffer *)pThis)->pChannel->lpVtbl->Release(((CStdProxyBuffer *)pThis)->pChannel);
  434. ((CStdProxyBuffer *)pThis)->pChannel = 0;
  435. }
  436. };
  437. //+-------------------------------------------------------------------------
  438. //
  439. // Method: CStdStubBuffer_QueryInterface, public
  440. //
  441. // Synopsis: Query for an interface on the stub buffer.
  442. //
  443. //--------------------------------------------------------------------------
  444. HRESULT STDMETHODCALLTYPE
  445. CStdStubBuffer_QueryInterface(IRpcStubBuffer *pThis, REFIID riid, void **ppvObject)
  446. {
  447. HRESULT hr = E_NOINTERFACE;
  448. assert(pThis);
  449. assert(riid);
  450. assert(ppvObject);
  451. *ppvObject = 0;
  452. if ((memcmp(riid, &IID_IUnknown, sizeof(IID)) == 0) ||
  453. (memcmp(riid, &IID_IRpcStubBuffer, sizeof(IID)) == 0))
  454. {
  455. *ppvObject = (IRpcStubBuffer *) pThis;
  456. pThis->lpVtbl->AddRef(pThis);
  457. hr = S_OK;
  458. }
  459. return hr;
  460. }
  461. //+-------------------------------------------------------------------------
  462. //
  463. // Method: CStdStubBuffer_AddRef, public
  464. //
  465. // Synopsis: Increment reference count.
  466. //
  467. //--------------------------------------------------------------------------
  468. ULONG STDMETHODCALLTYPE
  469. CStdStubBuffer_AddRef(IRpcStubBuffer *pThis)
  470. {
  471. CStdStubBuffer *pStubBuffer;
  472. assert(pThis);
  473. pStubBuffer = NdrGetStubBuffer(pThis);
  474. assert(pStubBuffer);
  475. InterlockedIncrement(&pStubBuffer->RefCount);
  476. return (ULONG) pStubBuffer->RefCount;
  477. }
  478. //+-------------------------------------------------------------------------
  479. //
  480. // Method: CStdStubBuffer_Release, public
  481. //
  482. // Synopsis: Decrement reference count.
  483. //
  484. //--------------------------------------------------------------------------
  485. ULONG STDMETHODCALLTYPE
  486. CStdStubBuffer_Release(IRpcStubBuffer *pThis)
  487. {
  488. long RefCount;
  489. unsigned long count;
  490. CStdStubBuffer *pStubBuffer;
  491. assert(pThis);
  492. pStubBuffer = NdrGetStubBuffer(pThis);
  493. assert(pStubBuffer);
  494. RefCount = InterlockedDecrement(&pStubBuffer->RefCount);
  495. assert(RefCount >= 0);
  496. if(RefCount == 0)
  497. {
  498. count = 0;
  499. //Decrement the DLL reference count.
  500. InterlockedDecrement(&DllRefCount);
  501. //Free the stub buffer
  502. MIDL_user_free(pStubBuffer);
  503. }
  504. else
  505. count = (unsigned long) pStubBuffer->RefCount;
  506. return count;
  507. }
  508. HRESULT STDMETHODCALLTYPE
  509. CStdStubBuffer_Connect(IRpcStubBuffer *pThis, IUnknown *pUnkServer)
  510. {
  511. HRESULT hr = E_UNEXPECTED;
  512. CStdStubBuffer *pStubBuffer;
  513. assert(pThis);
  514. pStubBuffer = NdrGetStubBuffer(pThis);
  515. assert(pStubBuffer);
  516. pThis->lpVtbl->Disconnect(pThis);
  517. if(pUnkServer)
  518. {
  519. hr = pUnkServer->lpVtbl->QueryInterface(pUnkServer, &IID_IUnknown, &pStubBuffer->punkObject);
  520. }
  521. return hr;
  522. }
  523. void STDMETHODCALLTYPE
  524. CStdStubBuffer_Disconnect(IRpcStubBuffer *pThis)
  525. {
  526. CStdStubBuffer *pStubBuffer;
  527. long temp;
  528. int j;
  529. IUnknown *punkObject;
  530. assert(pThis);
  531. pStubBuffer = NdrGetStubBuffer(pThis);
  532. assert(pStubBuffer);
  533. punkObject = pStubBuffer->punkObject;
  534. //Free the interface pointers held by the stub buffer
  535. if(punkObject)
  536. {
  537. for(j = 0;
  538. pStubBuffer->aInterfaceStub[j].lpVtbl;
  539. j++)
  540. {
  541. temp = InterlockedExchange((long *) &pStubBuffer->aInterfaceStub[j].pvServerObject, 0);
  542. if(temp)
  543. punkObject->lpVtbl->Release(punkObject);
  544. }
  545. temp = InterlockedExchange((long *) &pStubBuffer->punkObject, 0);
  546. if(temp)
  547. punkObject->lpVtbl->Release(punkObject);
  548. }
  549. }
  550. HRESULT STDMETHODCALLTYPE
  551. CStdStubBuffer_Invoke(
  552. IRpcStubBuffer *pThis,
  553. RPCOLEMESSAGE *prpcmsg,
  554. IRpcChannelBuffer *pRpcChannelBuffer)
  555. {
  556. HRESULT hr = S_OK;
  557. unsigned char **ppTemp;
  558. unsigned char *pTemp;
  559. CInterfaceStubVtbl *pStubVtbl;
  560. CInterfaceStub *pInterfaceStub;
  561. DWORD dwExceptionCode;
  562. assert(pThis);
  563. assert(prpcmsg);
  564. assert(pRpcChannelBuffer);
  565. pInterfaceStub = (CInterfaceStub *) pThis;
  566. //Get a pointer to the stub vtbl.
  567. ppTemp = (unsigned char **) pThis;
  568. pTemp = *ppTemp;
  569. pTemp -= sizeof(CInterfaceStubHeader);
  570. pStubVtbl = (CInterfaceStubVtbl *) pTemp;
  571. __try
  572. {
  573. //Check the data rep
  574. //Check if we are connected to the server object.
  575. if(pInterfaceStub->pvServerObject == 0)
  576. {
  577. CStdStubBuffer *pStubBuffer = NdrGetStubBuffer(pThis);
  578. assert(pStubBuffer);
  579. if(pStubBuffer->punkObject)
  580. {
  581. const IID *piid = NdrGetStubIID(pThis);
  582. assert(piid);
  583. hr = pStubBuffer->punkObject->lpVtbl->QueryInterface(pStubBuffer->punkObject, piid, &pInterfaceStub->pvServerObject);
  584. if(FAILED(hr))
  585. {
  586. SetLastError(hr);
  587. RpcRaiseException(RPC_E_FAULT);
  588. }
  589. }
  590. else
  591. {
  592. //We are not connected to the server object.
  593. SetLastError((unsigned long) CO_E_OBJNOTCONNECTED);
  594. RpcRaiseException(RPC_E_FAULT);
  595. }
  596. }
  597. //Check if procnum is valid.
  598. if(prpcmsg->iMethod >= pStubVtbl->header.DispatchTableCount)
  599. RpcRaiseException(RPC_S_PROCNUM_OUT_OF_RANGE);
  600. (*pStubVtbl->header.pDispatchTable[prpcmsg->iMethod])(
  601. pRpcChannelBuffer,
  602. (PRPC_MESSAGE) prpcmsg,
  603. pInterfaceStub->pvServerObject);
  604. }
  605. except(EXCEPTION_EXECUTE_HANDLER)
  606. {
  607. dwExceptionCode = GetExceptionCode();
  608. switch(dwExceptionCode)
  609. {
  610. case RPC_E_FAULT:
  611. hr = GetLastError();
  612. break;
  613. case RPC_E_SERVERFAULT:
  614. //Pass the server's exception to the channel.
  615. dwExceptionCode = GetLastError();
  616. RpcRaiseException(dwExceptionCode);
  617. break;
  618. default:
  619. //Assume this is a win32 error code.
  620. hr = HRESULT_FROM_WIN32(dwExceptionCode);
  621. break;
  622. }
  623. }
  624. return hr;
  625. }
  626. IRpcStubBuffer * STDMETHODCALLTYPE
  627. CStdStubBuffer_IsIIDSupported(IRpcStubBuffer *pThis, REFIID riid)
  628. {
  629. int j;
  630. CStdStubBuffer *pStubBuffer;
  631. IRpcStubBuffer *pInterfaceStub = 0;
  632. const IID *pIID;
  633. assert(pThis);
  634. assert(riid);
  635. pStubBuffer = NdrGetStubBuffer(pThis);
  636. assert(pStubBuffer);
  637. //Search the interface stubs in the stub buffer
  638. for(j = 0;
  639. pStubBuffer->aInterfaceStub[j].lpVtbl && !pInterfaceStub;
  640. j++)
  641. {
  642. pIID = NdrGetStubIID(&pStubBuffer->aInterfaceStub[j].lpVtbl);
  643. assert(pIID);
  644. if(memcmp(riid, pIID, sizeof(IID)) == 0)
  645. {
  646. //We found the interface!
  647. if(pStubBuffer->aInterfaceStub[j].pvServerObject == 0)
  648. {
  649. //Check if the server object supports the interface.
  650. if(pStubBuffer->punkObject)
  651. {
  652. pStubBuffer->punkObject->lpVtbl->QueryInterface(
  653. pStubBuffer->punkObject,
  654. riid,
  655. &pStubBuffer->aInterfaceStub[j].pvServerObject);
  656. }
  657. }
  658. if(pStubBuffer->aInterfaceStub[j].pvServerObject)
  659. {
  660. pInterfaceStub = (IRpcStubBuffer *)&pStubBuffer->aInterfaceStub[j].lpVtbl;
  661. pInterfaceStub->lpVtbl->AddRef(pInterfaceStub);
  662. }
  663. }
  664. }
  665. return pInterfaceStub;
  666. }
  667. ULONG STDMETHODCALLTYPE
  668. CStdStubBuffer_CountRefs(IRpcStubBuffer *pThis)
  669. {
  670. ULONG count = 0;
  671. int j;
  672. CStdStubBuffer *pStubBuffer;
  673. assert(pThis);
  674. pStubBuffer = NdrGetStubBuffer(pThis);
  675. assert(pStubBuffer);
  676. if(pStubBuffer->punkObject != 0)
  677. count++;
  678. //Search the interface stubs in the stub buffer
  679. for(j = 0;
  680. pStubBuffer->aInterfaceStub[j].lpVtbl;
  681. j++)
  682. {
  683. //We found the interface!
  684. if(pStubBuffer->aInterfaceStub[j].pvServerObject != 0)
  685. count++;
  686. }
  687. return count;
  688. }
  689. HRESULT STDMETHODCALLTYPE
  690. CStdStubBuffer_DebugServerQueryInterface(IRpcStubBuffer *pThis, void **ppv)
  691. {
  692. HRESULT hr = E_UNEXPECTED;
  693. assert(pThis);
  694. assert(ppv);
  695. *ppv = ((CInterfaceStub *)pThis)->pvServerObject;
  696. if(*ppv)
  697. hr = S_OK;
  698. return hr;
  699. }
  700. void STDMETHODCALLTYPE
  701. CStdStubBuffer_DebugServerRelease(IRpcStubBuffer *pthis, void *pv)
  702. {
  703. }
  704. //+-------------------------------------------------------------------------
  705. //
  706. // Method: IUnknown_QueryInterface_Proxy
  707. //
  708. // Synopsis: Implementation of QueryInterface for interface proxy.
  709. //
  710. //--------------------------------------------------------------------------
  711. HRESULT __stdcall
  712. IUnknown_QueryInterface_Proxy(
  713. IUnknown *pThis,
  714. REFIID riid,
  715. void **ppv)
  716. {
  717. HRESULT hr = E_NOINTERFACE;
  718. CStdProxyBuffer *pProxyBuffer = NdrGetProxyBuffer(pThis);
  719. assert(pProxyBuffer);
  720. hr = pProxyBuffer->punkOuter->lpVtbl->QueryInterface(pProxyBuffer->punkOuter, riid, ppv);
  721. return hr;
  722. };
  723. //+-------------------------------------------------------------------------
  724. //
  725. // Method: IUnknown_AddRef_Proxy
  726. //
  727. // Synopsis: Implementation of AddRef for interface proxy.
  728. //
  729. //--------------------------------------------------------------------------
  730. ULONG __stdcall
  731. IUnknown_AddRef_Proxy(IUnknown *pThis)
  732. {
  733. CStdProxyBuffer *pProxyBuffer = NdrGetProxyBuffer(pThis);
  734. ULONG count;
  735. count = pProxyBuffer->punkOuter->lpVtbl->AddRef(pProxyBuffer->punkOuter);
  736. return count;
  737. };
  738. //+-------------------------------------------------------------------------
  739. //
  740. // Method: IUnknown_Release_Proxy
  741. //
  742. // Synopsis: Implementation of Release for interface proxy.
  743. //
  744. //--------------------------------------------------------------------------
  745. ULONG __stdcall
  746. IUnknown_Release_Proxy(IUnknown *pThis)
  747. {
  748. CStdProxyBuffer *pProxyBuffer = NdrGetProxyBuffer(pThis);
  749. ULONG count;
  750. count = pProxyBuffer->punkOuter->lpVtbl->Release(pProxyBuffer->punkOuter);
  751. return count;
  752. };
  753. void __RPC_STUB
  754. IUnknown_QueryInterface_Stub(
  755. IRpcChannelBuffer * _pRpcChannelBuffer,
  756. PRPC_MESSAGE _pRpcMessage,
  757. void * _pvServerObject )
  758. {
  759. }
  760. void __RPC_STUB
  761. IUnknown_AddRef_Stub(
  762. IRpcChannelBuffer * _pRpcChannelBuffer,
  763. PRPC_MESSAGE _pRpcMessage,
  764. void * _pvServerObject )
  765. {
  766. }
  767. void __RPC_STUB
  768. IUnknown_Release_Stub(
  769. IRpcChannelBuffer * _pRpcChannelBuffer,
  770. PRPC_MESSAGE _pRpcMessage,
  771. void * _pvServerObject )
  772. {
  773. }
  774. //+-------------------------------------------------------------------------
  775. //
  776. // Function: MIDL_user_allocate
  777. //
  778. // Synopsis: Allocate memory via OLE task allocator.
  779. //
  780. //--------------------------------------------------------------------------
  781. void * __stdcall MIDL_user_allocate(size_t size)
  782. {
  783. void *pMemory;
  784. pMemory = CoTaskMemAlloc(size);
  785. if(0 == pMemory)
  786. {
  787. SetLastError((unsigned long) E_OUTOFMEMORY);
  788. RpcRaiseException(RPC_E_FAULT);
  789. }
  790. return pMemory;
  791. }
  792. //+-------------------------------------------------------------------------
  793. //
  794. // Function: MIDL_user_free
  795. //
  796. // Synopsis: Free memory using OLE task allocator.
  797. //
  798. //--------------------------------------------------------------------------
  799. void __stdcall MIDL_user_free(void *pMemory)
  800. {
  801. CoTaskMemFree(pMemory);
  802. }
  803. #endif // !defined(__RPC_DOS__) && !defined(__RPC_WIN16__)