home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / adsi / sampprov / cdispmgr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-29  |  6.9 KB  |  304 lines

  1. /*++
  2.  
  3. Copyright (c) 1996 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     CDispMgr.c
  8.  
  9. Abstract:
  10.  
  11.     Dispatch Manager implementation
  12.  
  13. Author:
  14.  
  15. Environment:
  16.  
  17.     User mode
  18.  
  19. Revision History :
  20.  
  21. --*/
  22. #include "adssmp.h"
  23. #pragma hdrstop
  24.  
  25. DISPID
  26. CDispatchMgr::getDISPID(DISPID InputDispId)
  27. {
  28.     return(InputDispId & 0x0000FFFF);
  29. }
  30.  
  31. DISPID
  32. CDispatchMgr::getTypeinfoID(DISPID InputDispId)
  33. {
  34.     return((InputDispId & 0x7fff0000) >> 16);
  35. }
  36.  
  37. void *
  38. CDispatchMgr::getInterfacePtr(DISPID TypeinfoID
  39.                                   )
  40. {
  41.     PTYPEINFOENTRY pTypeInfoEntry = NULL;
  42.     pTypeInfoEntry = _pTypeInfoEntry;
  43.     while (pTypeInfoEntry) {
  44.         if (pTypeInfoEntry->TypeInfoId == TypeinfoID) {
  45.             return(pTypeInfoEntry->pInterfacePointer);
  46.         }
  47.         pTypeInfoEntry = pTypeInfoEntry->pNext;
  48.     }
  49.     return(NULL);
  50. }
  51.  
  52. PTYPEINFOENTRY
  53. CDispatchMgr::FindTypeInfoEntry(LONG TypeInfoId)
  54. {
  55.     PTYPEINFOENTRY pTypeInfoEntry;
  56.  
  57.     pTypeInfoEntry = _pTypeInfoEntry;
  58.     while (pTypeInfoEntry) {
  59.         if (pTypeInfoEntry->TypeInfoId == TypeInfoId) {
  60.             return(pTypeInfoEntry);
  61.         }
  62.         pTypeInfoEntry = pTypeInfoEntry->pNext;
  63.     }
  64.     return(NULL);
  65. }
  66.  
  67.  
  68.  
  69. HRESULT
  70. CDispatchMgr::AddTypeInfo(void FAR *ptypeinfo,
  71.                                void * pIntfptr)
  72. {
  73.     PTYPEINFOENTRY pTypeInfoEntry = NULL;
  74.     HRESULT hr;
  75.  
  76.     if (pTypeInfoEntry =FindTypeInfo(ptypeinfo)) {
  77.         return(E_FAIL);
  78.     }
  79.     pTypeInfoEntry = (PTYPEINFOENTRY)LocalAlloc(LPTR,sizeof(TYPEINFOENTRY));
  80.     if (!pTypeInfoEntry) {
  81.         hr = E_OUTOFMEMORY;
  82.         BAIL_IF_ERROR(hr);
  83.     }
  84.  
  85.     pTypeInfoEntry->ptypeinfo = ptypeinfo;
  86.     pTypeInfoEntry->TypeInfoId = gentypeinfoid();
  87.     pTypeInfoEntry->pInterfacePointer = pIntfptr;
  88.  
  89.     pTypeInfoEntry->pNext = _pTypeInfoEntry;
  90.     _pTypeInfoEntry = pTypeInfoEntry;
  91.  
  92.     RRETURN(S_OK);
  93.  
  94. cleanup:
  95.     RRETURN(hr);
  96. }
  97.  
  98. STDMETHODIMP
  99. CDispatchMgr::GetTypeInfoCount(unsigned int FAR* pctinfo)
  100. {
  101.     RRETURN(E_NOTIMPL);
  102. }
  103.  
  104. STDMETHODIMP
  105. CDispatchMgr::GetTypeInfo(unsigned int itinfo, LCID lcid,
  106.         ITypeInfo FAR* FAR* pptinfo)
  107. {
  108.     RRETURN(E_NOTIMPL);
  109. }
  110.  
  111. STDMETHODIMP
  112. CDispatchMgr::GetIDsOfNames(REFIID iid, LPWSTR FAR* rgszNames,
  113.         unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
  114. {
  115.     PTYPEINFOENTRY pTypeInfo = NULL;
  116.     HRESULT hr;
  117.  
  118.     pTypeInfo = _pTypeInfoEntry;
  119.     while (pTypeInfo) {
  120.         hr = DispGetIDsOfNames(((ITypeInfo *)pTypeInfo->ptypeinfo),
  121.                                 rgszNames,
  122.                                 cNames,
  123.                                 rgdispid
  124.                                 );
  125.         if (SUCCEEDED(hr)) {
  126.             generate_newids(pTypeInfo->TypeInfoId,
  127.                             rgdispid,
  128.                             cNames
  129.                             );
  130.             RRETURN(hr);
  131.         }
  132.         pTypeInfo = pTypeInfo->pNext;
  133.     }
  134.     RRETURN(E_FAIL);
  135. }
  136.  
  137. STDMETHODIMP
  138. CDispatchMgr::Invoke(DISPID dispidMember, REFIID iid, LCID lcid,
  139.         unsigned short wFlags, DISPPARAMS FAR* pdispparams,
  140.         VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo,
  141.         unsigned int FAR* puArgErr)
  142. {
  143.         RRETURN(TypeInfoInvoke(dispidMember,
  144.                                iid,
  145.                                lcid,
  146.                                wFlags,
  147.                                pdispparams,
  148.                                pvarResult,
  149.                                pexcepinfo,
  150.                                puArgErr
  151.                                ));
  152. }
  153.  
  154. void
  155. CDispatchMgr::generate_newids(LONG TypeInfoId,
  156.         DISPID FAR* rgdispid, unsigned int cNames)
  157. {
  158.     unsigned int i = 0;
  159.     for (i = 0; i < cNames; i++ ) {
  160.         rgdispid[i] = (DISPID)(((unsigned int)TypeInfoId << 16) | rgdispid[i]);
  161.     }
  162. }
  163.  
  164. STDMETHODIMP
  165. CDispatchMgr::TypeInfoInvoke(DISPID dispidMember, REFIID iid, LCID lcid,
  166.         unsigned short wFlags, DISPPARAMS FAR* pdispparams,
  167.         VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo,
  168.         unsigned int FAR* puArgErr)
  169. {
  170.  
  171.     void * pInterfacePtr = NULL;
  172.     DISPID dispid;
  173.     DISPID typeinfoid;
  174.     ITypeInfo *pTypeInfo;
  175.     HRESULT hr = S_OK;
  176.  
  177.     if (dispidMember <= 0) {
  178.         dispid = dispidMember;
  179.         switch (dispid) {
  180.         case -4:
  181.             if (_pDispidNewEnum) {
  182.                 pTypeInfo = (ITypeInfo *)_pDispidNewEnum->ptypeinfo;
  183.                 pInterfacePtr = _pDispidNewEnum->pInterfacePointer;
  184.                 break;
  185.  
  186.             }else {
  187.                 hr = DISP_E_BADINDEX;
  188.                 BAIL_IF_ERROR(hr);
  189.  
  190.             }
  191.             break;
  192.  
  193.         default:
  194.              hr = DISP_E_BADINDEX;
  195.              BAIL_IF_ERROR(hr);
  196.  
  197.         }
  198.  
  199.     }else {
  200.         typeinfoid = getTypeinfoID(dispidMember);
  201.         dispid = getDISPID(dispidMember);
  202.         pInterfacePtr = getInterfacePtr(typeinfoid);
  203.         hr = getTypeInfo(typeinfoid, &pTypeInfo);
  204.         BAIL_IF_ERROR(hr);
  205.     }
  206.  
  207.     hr = DispInvoke(pInterfacePtr,
  208.                 pTypeInfo,
  209.                 dispid,
  210.                 wFlags,
  211.                 pdispparams,
  212.                 pvarResult,
  213.                 pexcepinfo,
  214.                 puArgErr
  215.                 );
  216.     return hr;
  217.  
  218. cleanup:
  219.  
  220.     RRETURN(hr);
  221. }
  222.  
  223.  
  224. HRESULT
  225. CDispatchMgr::getTypeInfo(DISPID typeinfoid, ITypeInfo FAR * FAR * ppTypeInfo)
  226. {
  227.     PTYPEINFOENTRY pTypeInfoEntry;
  228.     pTypeInfoEntry = _pTypeInfoEntry;
  229.     while (pTypeInfoEntry) {
  230.         if (pTypeInfoEntry->TypeInfoId == typeinfoid) {
  231.             *ppTypeInfo = (ITypeInfo FAR *)pTypeInfoEntry->ptypeinfo;
  232.             RRETURN(S_OK);
  233.         }
  234.         pTypeInfoEntry = pTypeInfoEntry->pNext;
  235.     }
  236.     RRETURN(E_FAIL);
  237. }
  238.  
  239. CDispatchMgr::CDispatchMgr()
  240. {
  241.     _pTypeInfoEntry = NULL;
  242.     _pDispidNewEnum = NULL;
  243.     _dwTypeInfoId = 0;
  244. }
  245.  
  246. CDispatchMgr::~CDispatchMgr()
  247. {
  248.     PTYPEINFOENTRY pTypeInfoEntry = NULL;
  249.     PTYPEINFOENTRY pTemp = NULL;
  250.     ITypeInfo *pTypeInfo = NULL;
  251.  
  252.     pTypeInfoEntry = _pTypeInfoEntry;
  253.  
  254.     while (pTypeInfoEntry) {
  255.  
  256.         pTemp = pTypeInfoEntry;
  257.  
  258.         pTypeInfo = (ITypeInfo *)pTypeInfoEntry->ptypeinfo;
  259.         pTypeInfo->Release();
  260.  
  261.         pTypeInfoEntry = pTemp->pNext;
  262.  
  263.         LocalFree(pTemp);
  264.     }
  265. }
  266.  
  267. HRESULT
  268. CDispatchMgr::MarkAsNewEnum(void *pTypeInfo)
  269. {
  270.     PTYPEINFOENTRY pTypeInfoEntry;
  271.  
  272.     if (!pTypeInfo) {
  273.         RRETURN(E_FAIL);
  274.     }
  275.     if (!(pTypeInfoEntry = FindTypeInfo(pTypeInfo))) {
  276.         RRETURN(E_FAIL);
  277.     }
  278.     _pDispidNewEnum = pTypeInfoEntry;
  279.     RRETURN(S_OK);
  280. }
  281.  
  282.  
  283.  
  284. PTYPEINFOENTRY
  285. CDispatchMgr::FindTypeInfo(void *pTypeInfo)
  286. {
  287.     PTYPEINFOENTRY pTypeInfoEntry;
  288.  
  289.     pTypeInfoEntry = _pTypeInfoEntry;
  290.     while (pTypeInfoEntry) {
  291.         if (pTypeInfoEntry->ptypeinfo == pTypeInfo) {
  292.             return(pTypeInfoEntry);
  293.         }
  294.         pTypeInfoEntry = pTypeInfoEntry->pNext;
  295.     }
  296.     return(NULL);
  297. }
  298.  
  299. LONG
  300. CDispatchMgr::gentypeinfoid()
  301. {
  302.     return (_dwTypeInfoId++);
  303. }
  304.