dcomLib.cpp
上传用户:baixin
上传日期:2008-03-13
资源大小:4795k
文件大小:24k
开发平台:

MultiPlatform

  1. /* dcomLib.cpp - DCOM library (VxDCOM) */
  2. /* Copyright (c) 1999 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 03z,03jan02,nel  Remove OLE2T.
  7. 03y,17dec01,nel  Add include sybmol for diab build.
  8. 03x,02nov01,nel  Correct docs errors.
  9. 03w,10oct01,nel  SPR#70838. Ensure that all threads are started with
  10.                  VX_FP_TASK to get round any FP/longlong issues with certain
  11.                  BSPs and also usage of FP in DCOM servers.
  12. 03v,06aug01,dbs  remove instance-creation from SCM
  13. 03u,02aug01,dbs  use simplified Thread API
  14. 03t,31jul01,dbs  change vxdcomPSRegister to autoreg ctor
  15. 03s,19jul01,dbs  fix include path of vxdcomGlobals.h
  16. 03r,16jul01,dbs  add library termination function
  17. 03q,13jul01,dbs  fix up includes
  18. 03p,02may01,nel  SPR#66227. Correct format of comments for refgen.
  19. 03o,02mar01,nel  SPR#62130. Add CoDisconectObject API.
  20. 03n,28feb00,dgp  update docs formatiing
  21. 03m,11feb00,dbs  IIDs moved to idl directory, no longer need to force
  22.                  linkage of system stubs
  23. 03l,13oct99,dbs  add reference material/man pages
  24. 03k,26aug99,aim  protect pMshl->UnmarshalInterface Release
  25. 03j,24aug99,dbs  fix extraction of results from MQI in CoGetClassObject
  26. 03i,19aug99,aim  removed TASK_SPAWN
  27. 03h,17aug99,dbs  add skeleton CoInitSecurity()
  28. 03g,17aug99,aim  added g_vxdcomExportAddress globals
  29. 03f,13aug99,aim  reworked dcomLibInit
  30. 03e,13aug99,aim  added g_vxdcomMinThreads & g_vxdcomMaxThreads
  31. 03d,02aug99,dbs  replace p/s init funcs with extern symbols
  32. 03c,29jul99,drm  Adding bool to dcomLibInit for client priority.
  33. 03b,28jul99,drm  Moving g_defaultServerPriority to comLib.cpp.
  34. 03a,27jul99,drm  Adding global for default server priority.
  35. 02z,26jul99,dbs  move marshaling into exporter
  36. 02y,23jul99,drm  Adding stack size param to dcomLibInit().
  37. 02x,21jul99,drm  Changing dcomLibInit() to accept additional arguments.
  38. 02w,12jul99,aim  change SCM task entry point
  39. 02v,09jul99,dbs  change to new ObjectExporter naming
  40. 02u,06jul99,dbs  make CoCIEx() call SCM method
  41. 02t,30jun99,dbs  add a ref to StdProxy when created in CoUnmarshalInterface()
  42. 02s,28jun99,dbs  tighten up default authn setting
  43. 02r,28jun99,dbs  add vxdcomUserAdd() function
  44. 02q,28jun99,dbs  add default authn level as arg to dcomLibInit()
  45. 02p,25jun99,aim  remove SCM::startService on non target build
  46. 02o,24jun99,aim  fix solaris build warnings
  47. 02n,24jun99,dbs  add authn APIs
  48. 02m,10jun99,aim  uses new SCM
  49. 02l,08jun99,dbs  simplify creation of StdProxy
  50. 02k,04jun99,dbs  fix registry-access functions
  51. 02j,03jun99,dbs  remove reliance on TLS from CoMarshalInterface
  52. 02i,02jun99,aim  changes for solaris build
  53. 02h,02jun99,dbs  use new OS-specific macros
  54. 02g,01jun99,dbs  add NOPING flag
  55. 02f,28may99,dbs  make stub disp-tbl a structure
  56. 02e,27may99,dbs  change to vxdcomTarget.h
  57. 02d,25may99,dbs  correctly free allocated DSA
  58. 02c,24may99,dbs  ask SCM for local object exporter
  59. 02b,21may99,dbs  remove unnecessary registry entry
  60. 02a,20may99,dbs  fix handling of returned array-types
  61. 01z,11may99,dbs  remove unnecessary registry-entries for p/s
  62. 01y,11may99,dbs  rename VXCOM to VXDCOM
  63. 01x,10may99,dbs  don't delete binding after call to IRemoteActivation
  64. 01w,10may99,dbs  simplify binding-handle usage
  65. 01v,03may99,drm  preliminary priority scheme support
  66. 01u,29apr99,dbs  fix -Wall warnings
  67. 01t,28apr99,dbs  remove extraneous AddRef() in CoMarshalInterface
  68. 01s,28apr99,dbs  don't release RPC binding-handle after remote activation
  69. 01r,27apr99,dbs  add mem-alloc functions
  70. 01q,27apr99,dbs  use right new for std-mashaler class
  71. 01p,26apr99,aim  added TRACE_CALL
  72. 01o,23apr99,dbs  use streams properly
  73. 01n,23apr99,dbs  remove warnings for unused locals
  74. 01m,22apr99,dbs  tidy up potential leaks
  75. 01l,15apr99,dbs  increase _ACTIVATION_MAX limit
  76. 01k,13apr99,dbs  remove unused includes
  77. 01j,09apr99,drm  adding diagnostic output
  78. 01i,11mar99,dbs  add IOXIDResolver support
  79. 01h,01mar99,dbs  help tidy up RPC startup
  80. 01g,11feb99,dbs  check for correct COM initialization
  81. 01f,10feb99,dbs  improve handling of endpoints
  82. 01e,08feb99,dbs  formalize naming convention and ORPC/RPC interface
  83. 01d,03feb99,dbs  simplify p/s architecture
  84. 01c,11jan99,dbs  reduce STL usage
  85. 01b,22dec98,dbs  improve ORPC interface
  86. 01a,18dec98,dbs  move plain COM functions into vxcomLib.cpp
  87. 01c,11dec98,dbs  simplify registry
  88. 01b,26nov98,dbs  add IRemUnknown functionality
  89. 01a,17nov98,dbs  created
  90. */
  91. #include "private/comMisc.h"            // for misc support funcs
  92. #include "dcomProxy.h" // for ndr_xxx() funcs
  93. #include "StdProxy.h" // for StdProxy class 
  94. #include "MemoryStream.h" // for VxRWMemStream class
  95. #include "ObjectExporter.h" // for ObjectExporter class
  96. #include "SCM.h" // for SCM class
  97. #include "orpcLib.h" // for ORPC constants
  98. #include "RemoteOxid.h" // for RemoteOxid class
  99. #include "StdMarshaler.h" // for StdMarshaler class
  100. #include "PSFactory.h" // for PSFactory class
  101. #include "private/vxdcomGlobals.h"      // global variables
  102. #include "taskLib.h"                    // VxWorks tasks
  103. #include "RemoteRegistry.h"             // DCOM registry
  104. /*
  105. DESCRIPTION
  106. This library provides a subset of the Win32 COM/DCOM API calls, in
  107. order to support the implementation of COM and DCOM in the VxWorks
  108. environment. 
  109.     
  110. */
  111. /* Include symbol for diab */
  112. extern "C" int include_vxdcom_dcomLib (void)
  113.     {
  114.     return 0;
  115.     }
  116.     
  117. /* Well-known GUIDs that are required by DCOM... */
  118. const IID CLSID_StdMarshal =
  119.     {0x00000017,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  120. const IID IID_IRpcChannelBuffer =
  121.     {0xD5F56B60,0x593B,0x101A,{0xB5,0x69,0x08,0x00,0x2B,0x2D,0xBF,0x7A}};
  122. const IID IID_IRpcProxyBuffer =
  123.     {0xD5F56A34,0x593B,0x101A,{0xB5,0x69,0x08,0x00,0x2B,0x2D,0xBF,0x7A}};
  124. extern "C"int scmTask ()
  125.     {
  126.     return SCM::startService ();
  127.     }
  128. /**************************************************************************
  129. *
  130. * dcomLibInit - dcomLib initialization function
  131. *
  132. * This function is called from the initialization stage of the
  133. * VxWorks boot procedure, and establishes the VxDCOM environment
  134. * according to the given arguments. These arguments are normally set
  135. * via the Tornado Project Facility, and are detailed in the VxDCOM
  136. * Component Supplement.
  137. *
  138. * RETURNS: the task-id of the SCM task.
  139. */
  140. extern "C" int dcomLibInit
  141.     (
  142.     int bstrPolicy, /* BSTR policy */
  143.     int authnLevel, /* DCOM Authentication level */
  144.     unsigned int priority, /* thread priority */
  145.     unsigned int numStatic, /* Static threads */
  146.     unsigned int numDynamic, /* Dynamic threads */
  147.     unsigned int stackSize, /* Stack Size of server thread */
  148.     unsigned int scmStackSize, /* Stack Size of SCM thread */
  149.     int clientPrioPropagation, /* Client Priority propagation */
  150.     int objectExporterPortNumber /* Object Exporter Port Number */
  151.     )
  152.     {
  153.     vxdcomBSTRPolicy = bstrPolicy;
  154.     // Initialize the Remote Registry...
  155.     dcomRemoteRegistryInit ();
  156.     
  157.     // Set the default authn level for NTLMSSP...
  158.     if ((authnLevel < RPC_C_AUTHN_LEVEL_NONE) ||
  159. (authnLevel > RPC_C_AUTHN_LEVEL_CONNECT))
  160. authnLevel = RPC_C_AUTHN_LEVEL_NONE;
  161.     g_defaultAuthnLevel = authnLevel;
  162.     // Set priority scheme global variables 
  163.     g_defaultServerPriority = (int) priority;
  164.     g_clientPriorityPropagation = clientPrioPropagation;
  165.     
  166.     g_vxdcomThreadPoolPriority = priority;
  167.     g_vxdcomMinThreads = numStatic;
  168.     g_vxdcomMaxThreads = numStatic + numDynamic;
  169.     g_vxdcomDefaultStackSize = stackSize;
  170.     g_scmTaskStackSize = scmStackSize;
  171.     g_vxdcomObjectExporterPortNumber = objectExporterPortNumber;
  172.     return ::taskSpawn ("tScmTask",
  173.                         g_scmTaskPriority,
  174.                         VX_FP_TASK,
  175.                         g_scmTaskStackSize,
  176.                         reinterpret_cast<FUNCPTR> (scmTask),
  177.                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  178.     }
  179. /**************************************************************************
  180. *
  181. * dcomLibTerm - dcomLib termination function
  182. *
  183. * This function can be called to shut down the SCM and so terminate
  184. * the DCOM functionality.
  185. */
  186. void dcomLibTerm ()
  187.     {
  188.     SCM::stopService ();
  189.     }
  190. /**************************************************************************
  191. *
  192. * CoGetClassObject - return an instance of the class-object for a coclass
  193. *
  194. * This function differs from the Win32 equivalent in that it is only
  195. * available when DCOM support is enabled, and not when only COM is
  196. * enabled. It accepts only the CLSCTX_INPROC_SERVER or
  197. * CLSCTX_REMOTE_SERVER values for 'dwClsContext' as the {local server}
  198. * model is not implemented in VxDCOM.
  199. *
  200. * RETURNS: an HRESULT value
  201. */
  202. HRESULT CoGetClassObject
  203.     (
  204.     REFCLSID rclsid, /* CLSID of class object */
  205.     DWORD dwClsContext, /* context */
  206.     COSERVERINFO* pServerInfo,    /* machine info */
  207.     REFIID riid, /* IID of desired interface */
  208.     void** ppv /* var to receive i/f ptr */
  209.     )
  210.     {
  211.     char * hint = 0;
  212.     if (pServerInfo->pwszName)
  213. {
  214. hint = new char [comWideStrLen (pServerInfo->pwszName) + 1];
  215. comWideToAscii (hint,
  216. pServerInfo->pwszName, 
  217. comWideStrLen (pServerInfo->pwszName) + 1);
  218. }
  219.     HRESULT hr =  comClassObjectGet (rclsid,
  220.      dwClsContext,
  221.                                      hint,
  222.                                      riid,
  223.                                      ppv);
  224.     if (hint)
  225. delete []hint;
  226.     return hr;
  227.     }
  228. /**************************************************************************
  229. *
  230. * CoRegisterClassObject - Register a class-object with the global class factory.
  231. *
  232. * Register a class-object with the global class-factory table. This is 
  233. * called from the server object when it is registered.
  234. *
  235. * RETURNS: S_OK on success, or CO_E_OBJISREG if the class is already in 
  236. * the class object table.
  237. */
  238. HRESULT CoRegisterClassObject
  239.     (
  240.     REFCLSID rclsid, /* CLSID to be registered */
  241.     IUnknown* pUnkCF, /* pointer to the class object */
  242.     DWORD dwClsContext, /* context (inproc/local/remote) */
  243.     DWORD flags, /* how to connect to the class object */
  244.     DWORD* lpdwRegister /* returned token */
  245.     )
  246.     {
  247.     TRACE_CALL;
  248.     // Validate args
  249.     if (! pUnkCF)
  250. return E_INVALIDARG;
  251.     //
  252.     // 1. Marshal IUnknown of Class-factory, creating a new GOT entry.
  253.     //
  254.     IStream* pStream;
  255.     HRESULT hr = VxRWMemStream::CreateInstance (0, IID_IStream, (void**) &pStream);
  256.     if (FAILED (hr))
  257. return hr;
  258.     
  259.     hr = CoMarshalInterface (pStream,
  260.      IID_IUnknown,
  261.      pUnkCF,
  262.      MSHCTX_LOCAL,
  263.      0,
  264.      MSHLFLAGS_NORMAL);
  265.     if (FAILED (hr))
  266. {
  267. pStream->Release ();
  268. return hr;
  269. }
  270.     //
  271.     // 2. Save CF in object-table. This is where it will be accessed
  272.     // later by the client. The OID is the one we just got from
  273.     // marshaling the interface-ptr...
  274.     //
  275.     ObjectExporter* px = SCM::objectExporter ();
  276.     ObjectTableEntry* pOTE = px->objectFindByStream (pStream);
  277.     DWORD dwRegister = (DWORD) pOTE;
  278.     if (pOTE)
  279. {
  280. pOTE->punkCF = pUnkCF;
  281. pOTE->clsid = rclsid;
  282. pOTE->dwRegToken = dwRegister;
  283. }
  284.     *lpdwRegister = dwRegister;
  285.     
  286.     px->Release ();
  287.     return S_OK;    
  288.     }
  289. /**************************************************************************
  290. *
  291. * CoRevokeClassObject - Unregister the class object.
  292. *
  293. * Un-register the class-factory from the class-factory table.
  294. *
  295. * RETURNS: S_OK on success, or S_FALSE on error.
  296. */
  297. HRESULT CoRevokeClassObject
  298.     (
  299.     DWORD dwRegister /* token for class object */
  300.     )
  301.     {
  302.     TRACE_CALL;
  303.     
  304.     ObjectExporter* px = SCM::objectExporter ();
  305.     ObjectTableEntry* pOTE = px->objectFindByToken (dwRegister);
  306.     HRESULT hr = S_OK;
  307.     
  308.     if (pOTE)
  309. px->objectUnregister (pOTE->oid);
  310.     else
  311. hr = S_FALSE;
  312.     
  313.     px->Release ();
  314.     return hr;
  315.     }
  316. /**************************************************************************
  317. *
  318. * CoCreateInstanceEx - create a single instance of an object
  319. *
  320. * This function differs from the Win32 equivalent in that it is only
  321. * available when DCOM support is enabled, and not when only COM is
  322. * enabled.
  323. *
  324. * RETURNS: an HRESULT value
  325. */
  326. HRESULT CoCreateInstanceEx
  327.     (
  328.     REFCLSID            rclsid,         /* CLSID of the object           */
  329.     IUnknown*           pUnkOuter,      /* ptr to aggregating object     */
  330.     DWORD               dwClsCtx,       /* one of CLSCTX values          */
  331.     COSERVERINFO*       pServerInfo,    /* machine to create object on   */
  332.     ULONG               nInterfaces, /* number of MULTI_QI structures */ 
  333.     MULTI_QI*           pResults        /* array of MULTI_QI structures  */
  334.     )
  335.     {
  336.     char * hint = 0;
  337.     if (pServerInfo->pwszName)
  338. {
  339. hint = new char [comWideStrLen (pServerInfo->pwszName) + 1];
  340. comWideToAscii (hint,
  341.         pServerInfo->pwszName,
  342. comWideStrLen (pServerInfo->pwszName) + 1);
  343. }
  344.     HRESULT hr =  comInstanceCreate (rclsid,
  345.                                      pUnkOuter,
  346.                                      dwClsCtx,
  347.                                      hint,
  348.                                      nInterfaces,
  349.                                      pResults);
  350.     if (hint)
  351. delete []hint;
  352.     return hr;
  353.     }
  354. /**************************************************************************
  355. *
  356. * CoGetStandardMarshal - Returns an instance of the standard marshaler.
  357. *
  358. * Returns an instance of the system standard marshaler. This object 
  359. * encapsulates the mechanism for marshaling any interface pointer into a 
  360. * stream, and is used (in this context) simply to marshal the given 
  361. * interface, after that it will be destroyed.
  362. *
  363. * RETURNS: S_OK.
  364. */
  365. HRESULT CoGetStandardMarshal
  366.     (
  367.     REFIID riid, /* interface IID */
  368.     IUnknown* pUnk, /* interface-ptr to be marshaled */
  369.     DWORD dwDestContext,  /* destination context */
  370.     void* pvDestContext,  /* reserved for future use */
  371.     DWORD mshlflags,      /* reason for marshaling */
  372.     IMarshal** ppMshl /* output ptr */
  373.     )
  374.     {
  375.     TRACE_CALL;
  376.     
  377.     *ppMshl = new VxStdMarshaler ();
  378.     (*ppMshl)->AddRef ();
  379.     return S_OK;
  380.     }
  381. /**************************************************************************
  382. *
  383. * CoMarshalInterface - marshal an interface pointer into a stream
  384. *
  385. * This function differs from its Win32 counterpart in that only
  386. * standard marshaling is supported. The interface to be marshaled is
  387. * 'not' queried for 'IMarshal' and no attempt will be made to use
  388. * custom marshaling even if the object supports it.
  389. *
  390. * RETURNS: an HRESULT value
  391. */
  392. HRESULT CoMarshalInterface
  393.     (
  394.     IStream* pStm, /* stream to marshal into */
  395.     REFIID riid, /* interface IID */
  396.     IUnknown* pUnk, /* interface-ptr to be marshaled */
  397.     DWORD dwDestContext,  /* destination context */
  398.     void* pvDestContext,  /* reserved for future use */
  399.     DWORD mshlflags       /* reason for marshaling */
  400.     )
  401.     {
  402.     TRACE_CALL;
  403.     // We are now going to make an entry in the object exporter's
  404.     // object table for the new object's marshaling packet. If at some
  405.     // point this function fails, we need to remove this entry...
  406.     ObjectExporter* pExp = SCM::objectExporter ();
  407.     return pExp->objectMarshal (CLSID_NULL,
  408. pStm,
  409. riid,
  410. pUnk,
  411. dwDestContext,
  412. pvDestContext,
  413. mshlflags,
  414. 0);
  415.     }
  416. /**************************************************************************
  417. *
  418. * CoUnmarshalInterface - Un-marshal an interface pointer from a stream
  419. *
  420. * This function differs from its Win32 counterpart in that only
  421. * standard marshaling is supported. If the OBJREF being Un-marshaled
  422. * indicates <custom marshaling> or <handler marshaling> then this call
  423. * will fail.
  424. *
  425. * RETURNS: an HRESULT value
  426. */
  427. HRESULT CoUnmarshalInterface
  428.     (
  429.     IStream* pStm, /* pointer to stream */
  430.     REFIID riid, /* IID of the interface */
  431.     void** ppv /* output variable to receive ptr */
  432.     )
  433.     {
  434.     TRACE_CALL;
  435.     
  436.     // Record current location in stream before use...
  437.     ULARGE_INTEGER currPos;
  438.     HRESULT hr = pStm->Seek (0, STREAM_SEEK_CUR, &currPos);
  439.     if (FAILED (hr))
  440. return hr;
  441.     // Read signature and flags from stream, to see if its a STDOBJREF.
  442.     // The STDOBJREF is known to be encoded in little-endian format as
  443.     // the rules of DCOM say so!
  444.     ULONG signature;
  445.     ULONG flags;
  446.     hr = pStm->Read (&signature, sizeof (signature), 0);
  447.     ndr_make_right (signature, VXDCOM_DREP_LITTLE_ENDIAN);
  448.     if (FAILED (hr))
  449. return hr;
  450.     hr = pStm->Read (&flags, sizeof (flags), 0);
  451.     ndr_make_right (flags, VXDCOM_DREP_LITTLE_ENDIAN);
  452.     if (FAILED (hr))
  453. return hr;
  454.     // Validate OBJREF format...
  455.     if (signature != OBJREF_SIGNATURE)
  456.         return RPC_E_INVALID_OBJREF;
  457.     if (flags != OBJREF_STANDARD)
  458.         return E_NOTIMPL;
  459.     // Now rewind the stream, ready for proper Un-marshaling...
  460.     pStm->Seek (currPos, STREAM_SEEK_SET, 0);
  461.     // Create std-proxy-object to perform Un-marshaling...
  462.     IMarshal* pMshl = new VxStdProxy ();
  463.     if (! pMshl)
  464. return E_OUTOFMEMORY;
  465.     pMshl->AddRef ();
  466.     // Call UnmarshalInterface() to create connection
  467.     hr = pMshl->UnmarshalInterface (pStm, riid, ppv);
  468.     if (FAILED (hr))
  469. return hr;
  470.     pMshl->Release ();
  471.     return hr;
  472.     }
  473. /**************************************************************************
  474. *
  475. * CoGetPSClsid - returns the proxy/stub CLSID for a given interface ID
  476. *
  477. * This function is meaningless in VxDCOM as CLSIDs are not used to
  478. * identify proxy/stub code as they are on Win32. Thus, this function
  479. * always return S_OK and outputs CLSID_NULL.
  480. *
  481. * RETURNS: S_OK
  482. */
  483. HRESULT CoGetPSClsid
  484.     (
  485.     REFIID              riid,           /* interface ID */
  486.     LPCLSID             pClsid          /* resulting P/S CLSID */
  487.     )
  488.     {
  489.     TRACE_CALL;
  490.     *pClsid = CLSID_NULL;
  491.     return S_OK;
  492.     }
  493. /**************************************************************************
  494. *
  495. * CoGetMarshalSizeMax - Returns the upper bound on the number of bytes needed to marshal the interface.
  496. *
  497. * Discover max size of marshaling packet required for given interface. As 
  498. * we don't support custom or handler marshaling, its simply the size of the 
  499. * std-mshl packet.
  500. *
  501. * RETURNS: S_OK on success or CO_E_NOTINITIALIZED.
  502. */
  503. HRESULT CoGetMarshalSizeMax
  504.     (
  505.     ULONG*              pulSize,        /* ptr to the upper-bound value */
  506.     REFIID              riid,           /* IID of interface */
  507.     IUnknown*           pUnk,           /* interface-ptr to be marshaled */
  508.     DWORD               dwDestContext,  /* destination process */
  509.     LPVOID              pvDestContext,  /* reserved for future use */
  510.     DWORD               mshlflags       /* reason for marshaling */
  511.     )
  512.     {
  513.     TRACE_CALL;
  514.     // Get std-marshaler, use its value...
  515.     IMarshal* pMshl;
  516.     HRESULT hr = CoGetStandardMarshal (riid,
  517.        pUnk,
  518.        dwDestContext,
  519.        pvDestContext,
  520.        mshlflags,
  521.        &pMshl);
  522.     if (SUCCEEDED (hr))
  523. {
  524. // Now find out marshal-size requirements of interface...
  525. hr = pMshl->GetMarshalSizeMax (riid,
  526.        pUnk,
  527.        dwDestContext,
  528.        pvDestContext, 
  529.        mshlflags,
  530.        pulSize);
  531. }
  532.     return hr;
  533.     }
  534. /*
  535. * vxdcom_ps_autoreg -- used by proxy/stub modules to register their
  536. * p/s classes with the system. Every server module that wants to be
  537. * remoted must register a p/s entry via this function. It provides 2
  538. * VTABLEs, one for proxies and one for stubs, and they are then
  539. * managed by the system's own p/s factory object.
  540. */
  541. vxdcom_ps_autoreg::vxdcom_ps_autoreg
  542.     (
  543.     REFIID iid, // IID of interface
  544.     const void* pvProxyVtbl, // proxy's VTBL ptr
  545.     const VXDCOM_STUB_DISPTBL* pStubDispTbl // stub dispatch table
  546.     )
  547.     {
  548.     // Register vtbl pointers with system P/S class factory...
  549.     VxPSFactory* pPSFactory = VxPSFactory::theInstance ();
  550.     pPSFactory->Register (iid, pvProxyVtbl, pStubDispTbl);
  551.     }
  552. /**************************************************************************
  553. *
  554. * vxdcomUserAdd - adds a user to the NTLMSSP user table
  555. *
  556. * This function adds a user/password combination to the VxDCOM NTLM
  557. * security tables. The password must be given in clear text, but only
  558. * the <password hash> is stored. This means that VxDCOM can use the
  559. * authentication setting RPC_CN_AUTHN_LEVEL_CONNECT to allow or
  560. * disallow incoming requests from specific users. If the
  561. * authentication level is set to this value, then only requests from
  562. * users with valid entries in the VxDCOM security tables will be
  563. * honored. Other users will be rejected with an 'access denied' error
  564. * when trying to activate servers on a VxDCOM target.
  565. *
  566. * RETURNS: void
  567. */
  568. void vxdcomUserAdd
  569.     (
  570.     const char* userName, /* user name */
  571.     const char* passwd /* user's password in plain text */
  572.     )
  573.     {
  574.     NTLMSSP::userAdd (userName, passwd);
  575.     }
  576. /**************************************************************************
  577. *
  578. * CoInitializeSecurity - establish security for the whole application 
  579. *
  580. * This function differs from its Win32 counterpart in that it only
  581. * supports the de-activation of security settings. This is because
  582. * VxDCOM does not support the full NTLM security subsystem, and so
  583. * this API is provided for source-compatibility only. However, to
  584. * prevent applications which rely on specific Win32 security behavior
  585. * from misbehaving under VxDCOM, this API will fail any attempts to
  586. * establish non-NULL security settings.
  587. *
  588. * RETURNS: S_OK if requested to disable security settings,
  589. * E_INVALIDARG otherwise.
  590. */
  591. HRESULT CoInitializeSecurity
  592.     (
  593.     void* psd, /* security descriptor - MBZ */
  594.     long cAuths, /* must be -1 */
  595.     void* asAuths, /* array of services - MBZ */
  596.     void* pReserved1, /* reserved - MBZ */
  597.     DWORD dwAuthnLevel, /* default authentication level */
  598.     DWORD dwImpLevel, /* default impersonation level */
  599.     void* pAuthList, /* per-service info - MBZ */
  600.     DWORD dwCapabilities, /* capabilities - must be EOAC_NONE */
  601.     void* pReserved3 /* reserved - MBZ */
  602.     )
  603.     {
  604.     if (psd || asAuths || pReserved1 || pAuthList || pReserved3 ||
  605. (cAuths != -1) ||
  606. (dwCapabilities != EOAC_NONE))
  607. return E_INVALIDARG;
  608.     g_defaultAuthnLevel = dwAuthnLevel;
  609.     return S_OK;
  610.     }
  611. /**************************************************************************
  612. *
  613. * CoDisconnectObject - disconnects all remote connections to an object
  614. *
  615. * This function forcibly disconnects all remote connections to the
  616. * given object. It should only ever be called in the same address
  617. * space (i.e. the same VxWorks instance) as the object being
  618. * disconnected. It is not for use by a remote client, for example.
  619. *
  620. * When this function is called, all references on the object instance
  621. * identified by 'pUnk' that are held by the VxDCOM object exporter,
  622. * are released. The result is that the exporter's tables no longer
  623. * hold references to that object, and so any subsequent attempts to
  624. * call methods on any of its interfaces will result in
  625. * RPC_E_INVALID_IPID errors. This approach means that there is no
  626. * chance of object references (to disconnected objects) remaining in
  627. * the server's export tables, and hence less likelyhood of leaks
  628. * occurring at the VxDCOM server.
  629. *
  630. * RETURNS: S_OK if all connections successfully severed.
  631. */
  632. HRESULT CoDisconnectObject
  633.     (
  634.     IUnknown*           pUnk,           /* object to be disconnected */
  635.     DWORD               dwReserved      /* reserved for future use */
  636.     )
  637.     {
  638.     // Does the object support IMarshal? If so, let it handle the
  639.     // disconnection itself...
  640.     IMarshal* pMshl=0;
  641.     HRESULT hr = pUnk->QueryInterface (IID_IMarshal,
  642.                                        (void**) &pMshl);
  643.     if (FAILED (hr))
  644.         {
  645.         // It doesn't have IMarshal, so use the standard marshaler. We
  646.         // must find the OID of the object in the exporter's tables...
  647.         ObjectExporter* pExp = SCM::objectExporter ();
  648.         ObjectTableEntry* pOTE = pExp->objectFindByIUnknown (pUnk);
  649.         if (pOTE)
  650.             {
  651.             pMshl = new VxStdMarshaler (pOTE->oid);
  652.             pMshl->AddRef ();
  653.             hr = S_OK;
  654.             }
  655.         else
  656.             hr = RPC_E_INVALID_OBJECT;
  657.         }
  658.     // Perform the disconnect, if everything went well...
  659.     if (SUCCEEDED (hr) && pMshl)
  660.         {
  661.         // Use marshaler to disconnect...
  662.         hr = pMshl->DisconnectObject (dwReserved);
  663.         // Release the marshaler...
  664.         pMshl->Release ();
  665.         }
  666.     // Return the result of the DisconnectObject() method...
  667.     return hr;
  668.     }