aboutsummaryrefslogtreecommitdiff
path: root/Src/auth/Loginbox/externalMngr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/auth/Loginbox/externalMngr.cpp')
-rw-r--r--Src/auth/Loginbox/externalMngr.cpp401
1 files changed, 401 insertions, 0 deletions
diff --git a/Src/auth/Loginbox/externalMngr.cpp b/Src/auth/Loginbox/externalMngr.cpp
new file mode 100644
index 00000000..10a67d30
--- /dev/null
+++ b/Src/auth/Loginbox/externalMngr.cpp
@@ -0,0 +1,401 @@
+#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;
+}