| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- #include "./externalMngr.h"
- #include "./common.h"
- #include "../../winamp/jsapi.h"
- ExternalManager::ExternalManager()
- : ref(1), lastDispId(0)
- {
- InitializeCriticalSection(&lock);
- }
- ExternalManager::~ExternalManager()
- {
- EnterCriticalSection(&lock);
-
- size_t index= list.size();
- while(index--)
- {
- if (NULL != list[index].object)
- list[index].object->Release();
- }
- LeaveCriticalSection(&lock);
- DeleteCriticalSection(&lock);
- }
- HRESULT ExternalManager::CreateInstance(ExternalManager **instance)
- {
- if (NULL == instance) return E_POINTER;
-
- *instance = new ExternalManager();
- if (NULL == instance) return E_OUTOFMEMORY;
-
- return S_OK;
- }
- STDMETHODIMP_(ULONG) ExternalManager::AddRef(void)
- {
- return InterlockedIncrement((LONG*)&ref);
- }
- STDMETHODIMP_(ULONG) ExternalManager::Release(void)
- {
- if (0 == ref)
- return ref;
-
- LONG r = InterlockedDecrement((LONG*)&ref);
- if (0 == r)
- delete(this);
-
- return r;
- }
- STDMETHODIMP ExternalManager::QueryInterface(REFIID riid, PVOID *ppvObject)
- {
- if (NULL == ppvObject)
- return E_POINTER;
-
- if (IsEqualIID(riid, IID_IDispatchEx))
- *ppvObject = static_cast<IDispatchEx*>(this);
- else if (IsEqualIID(riid, IID_IDispatch))
- *ppvObject = static_cast<IDispatch*>(this);
- else if (IsEqualIID(riid, IID_IUnknown))
- *ppvObject = static_cast<IUnknown*>(this);
- else
- {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- if (NULL == *ppvObject)
- return E_UNEXPECTED;
- AddRef();
- return S_OK;
- }
- STDMETHODIMP ExternalManager::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
- {
- EnterCriticalSection(&lock);
- UINT unknowns = 0;
- size_t count = list.size();
- for (UINT i = 0; i != cNames ; i++)
- {
- rgdispid[i] = DISPID_UNKNOWN;
- for (size_t j =0; j < count; j++)
- {
- if (CSTR_EQUAL == CompareString(lcid, 0, rgszNames[i], -1, list[j].name, -1))
- {
- if (NULL != list[j].object)
- rgdispid[i] = list[j].id;
- else
- unknowns++;
- break;
- }
- if (DISPID_UNKNOWN == rgdispid[i])
- unknowns++;
- }
- }
-
- LeaveCriticalSection(&lock);
- return (0 != unknowns) ? DISP_E_UNKNOWNNAME : S_OK;
- }
- STDMETHODIMP ExternalManager::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP ExternalManager::GetTypeInfoCount(unsigned int FAR * pctinfo)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP ExternalManager::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
- {
- return InvokeEx(dispid, lcid, wFlags, pdispparams, pvarResult, pexecinfo, 0);
- }
- STDMETHODIMP ExternalManager::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid)
- {
- if (NULL == pid) return E_POINTER;
- *pid = DISPID_UNKNOWN;
- HRESULT hr = DISP_E_UNKNOWNNAME;
- if (NULL != bstrName && L'\0' != *bstrName)
- {
- UINT compareFlags = 0;
- if (0 != (fdexNameCaseInsensitive & grfdex))
- compareFlags |= NORM_IGNORECASE;
- EnterCriticalSection(&lock);
-
- size_t index = list.size();
- while(index--)
- {
- if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, compareFlags, bstrName, -1, list[index].name, -1))
- {
- if (NULL != list[index].object)
- {
- *pid = list[index].id;
- hr = S_OK;
- }
- break;
- }
- }
-
- LeaveCriticalSection(&lock);
- }
- return hr;
- }
- STDMETHODIMP ExternalManager::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
- {
- if (DISPATCH_METHOD == wFlags || DISPATCH_PROPERTYGET == wFlags || DISPATCH_CONSTRUCT == wFlags)
- JSAPI_INIT_RESULT(pvarRes, VT_DISPATCH);
- HRESULT hr(DISP_E_MEMBERNOTFOUND);
- EnterCriticalSection(&lock);
-
- size_t index = list.size();
- while(index--)
- {
- if (id == list[index].id)
- {
- if (NULL != list[index].object)
- {
- if (NULL != pvarRes &&
- (DISPATCH_METHOD == wFlags || DISPATCH_PROPERTYGET == wFlags || DISPATCH_CONSTRUCT == wFlags))
- {
- list[index].object->AddRef();
- pvarRes->pdispVal = list[index].object;
- }
- hr = S_OK;
- }
- break;
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- STDMETHODIMP ExternalManager::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
- {
- HRESULT hr = S_FALSE;
- if (NULL != bstrName && L'\0' != *bstrName)
- {
- UINT compareFlags = 0;
- if (0 != (fdexNameCaseInsensitive & grfdex))
- compareFlags |= NORM_IGNORECASE;
- EnterCriticalSection(&lock);
-
- size_t index = list.size();
- while(index--)
- {
- if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, compareFlags, bstrName, -1, list[index].name, -1))
- {
- if (NULL != list[index].object)
- {
- list[index].object->Release();
- list[index].object = NULL;
- hr = S_OK;
- }
- break;
- }
- }
-
- LeaveCriticalSection(&lock);
- }
- return hr;
- }
- STDMETHODIMP ExternalManager::DeleteMemberByDispID(DISPID id)
- {
- HRESULT hr = S_FALSE;
-
- EnterCriticalSection(&lock);
-
- size_t index = list.size();
- while(index--)
- {
- if (id == list[index].id)
- {
- if (NULL != list[index].object)
- {
- list[index].object->Release();
- list[index].object = NULL;
- hr = S_OK;
- }
- break;
- }
- }
-
- LeaveCriticalSection(&lock);
- return hr;
- }
- STDMETHODIMP ExternalManager::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
- {
- HRESULT hr(DISP_E_UNKNOWNNAME);
- EnterCriticalSection(&lock);
-
- size_t index = list.size();
- while(index--)
- {
- if (id == list[index].id)
- {
- if (NULL != list[index].object)
- {
- if (NULL != pgrfdex)
- {
- *pgrfdex = 0;
- if (0 != (grfdexPropCanAll & grfdexFetch))
- *pgrfdex |= (fdexPropCanGet | fdexPropCanCall);
- if (0 != (grfdexPropCannotAll & grfdexFetch))
- *pgrfdex |= (fdexPropCannotPut | fdexPropCanPutRef | fdexPropCannotConstruct | fdexPropCannotSourceEvents);
- if (0 != (grfdexPropExtraAll & grfdexFetch))
- *pgrfdex |= (fdexPropNoSideEffects | fdexPropNoSideEffects);
- }
- hr = S_OK;
- }
- break;
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- STDMETHODIMP ExternalManager::GetMemberName(DISPID id, BSTR *pbstrName)
- {
- HRESULT hr(DISP_E_UNKNOWNNAME);
- EnterCriticalSection(&lock);
-
- size_t index = list.size();
- while(index--)
- {
- if (id == list[index].id)
- {
- if (NULL != list[index].object)
- {
- if (NULL != pbstrName)
- {
- *pbstrName = SysAllocString(list[index].name);
- hr = S_OK;
- }
- }
- break;
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- STDMETHODIMP ExternalManager::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid)
- {
- HRESULT hr(S_FALSE);
- if (NULL == pid) return S_FALSE;
- *pid = DISPID_UNKNOWN;
- EnterCriticalSection(&lock);
-
- size_t count = list.size();
- if (DISPID_STARTENUM == id)
- {
- if (count > 0)
- {
- *pid = list[0].id;
- hr = S_OK;
- }
- }
- else
- {
- for(size_t i = 0; i < count; i++)
- {
- if (id == list[i].id)
- {
- i++;
- if (i < count)
- {
- *pid = list[i].id;
- hr = S_OK;
- }
- break;
- }
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- STDMETHODIMP ExternalManager::GetNameSpaceParent(IUnknown **ppunk)
- {
- return E_NOTIMPL;
- }
- HRESULT ExternalManager::AddDispatch(LPCWSTR pszName, IDispatch *pDispatch, DISPID *pid)
- {
- if (NULL != pid)
- *pid = DISPID_UNKNOWN;
- if (NULL == pszName || L'\0' == pszName || NULL == pDispatch)
- return E_INVALIDARG;
- HRESULT hr;
-
- EnterCriticalSection(&lock);
-
- size_t index = list.size();
- while(index--)
- {
- if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, pszName, -1, list[index].name, -1))
- {
- if (NULL != list[index].object)
- {
- hr = E_FAIL;
- }
- else
- {
- list[index].object = pDispatch;
- pDispatch->AddRef();
- *pid = list[index].id;
- hr = S_OK;
- }
- break;
- }
- }
- if ((size_t)-1 == index)
- {
- DispatchRecord r;
- r.name = LoginBox_CopyString(pszName);
- if (NULL == r.name)
- hr = E_OUTOFMEMORY;
- else
- {
- r.id = ++lastDispId;
- r.object = pDispatch;
- pDispatch->AddRef();
- list.push_back(r);
- *pid = r.id;
- hr = S_OK;
- }
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
|