409 lines
11 KiB
C++
409 lines
11 KiB
C++
#include "Winamp.h"
|
|
#include "../Winamp/JSAPI.h"
|
|
#include <mshtmdid.h>
|
|
#include <mshtmhst.h>
|
|
#include <stdio.h>
|
|
#include <shlwapi.h>
|
|
#include <malloc.h>
|
|
|
|
#define BUFFER_LEN 1024
|
|
|
|
// {294DFA02-5A90-4dc7-872D-1EF54817078D}
|
|
static const GUID CLSID_WINAMP_CRAP =
|
|
{ 0x294dfa02, 0x5a90, 0x4dc7, { 0x87, 0x2d, 0x1e, 0xf5, 0x48, 0x17, 0x7, 0x8d } };
|
|
|
|
Winamp::Winamp()
|
|
{
|
|
refCount=1;
|
|
|
|
webBrowser_=0;
|
|
connectionPointContainer=0;
|
|
cookie_=0;
|
|
document_=0;
|
|
client_site = 0;
|
|
}
|
|
/* other things being asked for:
|
|
{00000008-0000-0000-C000-000000000046} (dunno what interface)
|
|
HTMLDocument
|
|
IOleControl B196B288-BAB4-101A-B69C-00AA00341D07
|
|
IClientSecurity
|
|
IQuickActivate
|
|
IPersistPropertyBag2
|
|
IPersistPropertyBag
|
|
IPersistStreamInit
|
|
IPersistStorage
|
|
IViewObjectEx
|
|
IViewObject
|
|
IActiveScript BB1A2AE1-A4F9-11CF-8F20-00805F2CD064
|
|
IOleCommandTarget B722BCCB-4E68-101B-A2BC-00AA00404770
|
|
IDispatchEx A6EF9860-C720-11D0-9337-00A0C90DCAA9
|
|
CB5BDC81-93C1-11cf-8F20-00805F2CD064
|
|
6D5140D3-7436-11CE-8034-00AA006009FA (dunno what interface)
|
|
*/
|
|
|
|
HRESULT Winamp::QueryInterface(REFIID riid, LPVOID FAR *ppvObj)
|
|
{
|
|
//DebugBreak();
|
|
if (!ppvObj)
|
|
return E_POINTER;
|
|
else if (IsEqualIID(riid, IID_IUnknown))
|
|
*ppvObj = /*static_cast<IUnknown *>*/(this);
|
|
else if (IsEqualIID(riid, IID_IObjectWithSite))
|
|
*ppvObj = static_cast<IObjectWithSite *>(this);
|
|
//else if (IsEqualIID(riid, __uuidof(IWinamp)))
|
|
//*ppvObj = static_cast<IWinamp *>(this);
|
|
else if (IsEqualIID(riid, IID_IDispatch))
|
|
*ppvObj = (IDispatch *)this;
|
|
else if (IsEqualIID(riid, IID_IOleObject))
|
|
*ppvObj = (IOleObject *)this;
|
|
else if (IsEqualIID(riid, IID_IPersistStorage))
|
|
*ppvObj = (IPersistStorage *)this;
|
|
else if (IsEqualIID(riid, IID_IDataObject))
|
|
*ppvObj = (IDataObject *)this;
|
|
else if (IsEqualIID(riid, IID_IObjectSafety))
|
|
*ppvObj = (IObjectSafety *)this;
|
|
else
|
|
{
|
|
LPOLESTR guidstr;
|
|
StringFromIID(riid, &guidstr);
|
|
//MessageBox(NULL, guidstr, L"queryinterface", MB_OK);
|
|
*ppvObj = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG Winamp::AddRef(void)
|
|
{
|
|
return ++refCount;
|
|
}
|
|
|
|
ULONG Winamp::Release(void)
|
|
{
|
|
if (refCount == 0)
|
|
return 0;
|
|
|
|
ULONG retCount=--refCount;
|
|
if (refCount == 0)
|
|
delete this;
|
|
return retCount;
|
|
}
|
|
|
|
|
|
#define DISP_TABLE \
|
|
CHECK_ID(Test)\
|
|
CHECK_ID(getVersion)\
|
|
|
|
#define CHECK_ID(str) JSAPI_DISP_ENUMIFY(str),
|
|
enum {
|
|
DISP_TABLE
|
|
};
|
|
#undef CHECK_ID
|
|
#define CHECK_ID(str) if (wcscmp(rgszNames[i], L## #str) == 0) { rgdispid[i] = JSAPI_DISP_ENUMIFY(str); continue; }
|
|
|
|
HRESULT Winamp::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
|
|
{
|
|
bool unknowns = false;
|
|
for (unsigned int i = 0;i != cNames;i++)
|
|
{
|
|
DISP_TABLE
|
|
|
|
rgdispid[i] = DISPID_UNKNOWN;
|
|
unknowns = true;
|
|
|
|
}
|
|
if (unknowns)
|
|
return DISP_E_UNKNOWNNAME;
|
|
else
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT Winamp::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT Winamp::GetTypeInfoCount(unsigned int FAR * pctinfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
#undef CHECK_ID
|
|
#define CHECK_ID(str) case JSAPI_DISP_ENUMIFY(str): return str(wFlags, pdispparams, pvarResult, puArgErr);
|
|
HRESULT Winamp::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
|
|
{
|
|
switch (dispid)
|
|
{
|
|
DISP_TABLE
|
|
}
|
|
return DISP_E_MEMBERNOTFOUND;
|
|
}
|
|
|
|
HRESULT Winamp::GetSite(REFIID riid, void** ppvSite)
|
|
{
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
HRESULT Winamp::SetSite(IUnknown* iu)
|
|
{/*
|
|
if (! (iu->QueryInterface(IID_IWebBrowser2, (void**) &webBrowser_) == S_OK ))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
if (! (iu->QueryInterface(IID_IConnectionPointContainer, (void**) &connectionPointContainer) == S_OK ))
|
|
{
|
|
return E_FAIL;
|
|
// ::MessageBox(0, "xxx", 0, 0);
|
|
}
|
|
|
|
// make sure we\'re getting browser events
|
|
IConnectionPoint* spCP;
|
|
HRESULT hr = connectionPointContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &spCP);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
hr = spCP->Advise(static_cast<IDispatch*>(this), &cookie_);
|
|
*/
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT Winamp::Test(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
|
{
|
|
JSAPI_VERIFY_METHOD(wFlags);
|
|
JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
|
|
|
|
MessageBoxA(NULL,"test", "IWinamp", MB_OK);
|
|
|
|
JSAPI_INIT_RESULT(pvarResult, VT_BOOL);
|
|
JSAPI_SET_VARIANT(pvarResult, V_BOOL, VARIANT_TRUE);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
HRESULT Winamp::getVersion(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
|
{
|
|
JSAPI_VERIFY_METHOD(wFlags);
|
|
JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
|
|
|
|
JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
|
|
JSAPI_SET_RESULT(pvarResult, bstrVal, SysAllocString(L"7766"));
|
|
|
|
return S_OK;
|
|
}
|
|
#endif
|
|
|
|
HRESULT Winamp::getVersion(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
|
{
|
|
JSAPI_VERIFY_METHOD(wFlags);
|
|
JSAPI_VERIFY_PARAMCOUNT(pdispparams, 0);
|
|
|
|
wchar_t csVersion[BUFFER_LEN];
|
|
////////////////////////////////
|
|
DWORD BufferSize = BUFFER_LEN;
|
|
DWORD cbData;
|
|
bool keyFound = false;
|
|
|
|
wchar_t exeName[] = L"\\winamp.exe";
|
|
wchar_t fileName[BUFFER_LEN];
|
|
csVersion[0]=0;
|
|
memset(&fileName[0],'\0',BUFFER_LEN);
|
|
wchar_t fileNameTemp[BUFFER_LEN];
|
|
|
|
HKEY hKey;
|
|
cbData = BUFFER_LEN;
|
|
|
|
// first check the protocol handler registry key, we're looking for
|
|
// the winamp:// protocol handler. If we find this, then this is the
|
|
// "right" exe for winamp we need to get the version number on
|
|
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("winamp\\shell\\open\\command"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
|
if ( RegQueryValueEx( hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE) fileNameTemp,
|
|
&cbData ) != ERROR_SUCCESS) {
|
|
return ERROR_PATH_NOT_FOUND;
|
|
}
|
|
|
|
RegCloseKey (hKey);
|
|
if (StrStrW(fileNameTemp,L"winamp.exe")) {
|
|
int indexOfFirstQuote = StrCSpnW(fileNameTemp, L"\"");
|
|
int indexOfSecondQuote = StrCSpnW(&fileNameTemp[indexOfFirstQuote+1], L"\"");
|
|
|
|
if (indexOfFirstQuote >= 0) {
|
|
keyFound = true;
|
|
lstrcpynW(fileName,&fileNameTemp[indexOfFirstQuote+1], indexOfSecondQuote+1);
|
|
}
|
|
} else {
|
|
// some other app (itunes ??) controlling the winamp:// protocol
|
|
// return error
|
|
return ERROR_PATH_NOT_FOUND;
|
|
}
|
|
}
|
|
|
|
if (!keyFound) {
|
|
// See if the reg key exists
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Winamp"), 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
|
|
return ERROR_PATH_NOT_FOUND;
|
|
}
|
|
|
|
cbData = BUFFER_LEN;
|
|
if ( RegQueryValueEx( hKey,
|
|
TEXT(""),
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE) fileName,
|
|
&cbData ) != ERROR_SUCCESS) {
|
|
return ERROR_PATH_NOT_FOUND;
|
|
}
|
|
RegCloseKey (hKey);
|
|
keyFound = true;
|
|
wcscat(fileName,exeName);
|
|
}
|
|
|
|
if (!keyFound) {
|
|
return ERROR_PATH_NOT_FOUND;
|
|
}
|
|
|
|
|
|
////////////////////////////////
|
|
static TCHAR sBackSlash[] = {'\\','\0'};
|
|
DWORD dwVersionDataLen = GetFileVersionInfoSize(fileName, NULL);
|
|
|
|
if (dwVersionDataLen)
|
|
{
|
|
char* fvBuf = (char *)alloca(dwVersionDataLen);//new char[dwVersionDataLen];
|
|
if (GetFileVersionInfo(fileName, 0, dwVersionDataLen, fvBuf)) {
|
|
|
|
LPVOID pVal;
|
|
UINT nValLen;
|
|
if (VerQueryValue(fvBuf, sBackSlash, &pVal, &nValLen)) {
|
|
if (nValLen == sizeof(VS_FIXEDFILEINFO)) {
|
|
VS_FIXEDFILEINFO* pFixedFileInfo = (VS_FIXEDFILEINFO*)pVal;
|
|
//wsprintf(csVersion, L"%d.%d.%d.%d",
|
|
// HIWORD(pFixedFileInfo->dwFileVersionMS), LOWORD(pFixedFileInfo->dwFileVersionMS),
|
|
// HIWORD(pFixedFileInfo->dwFileVersionLS), LOWORD(pFixedFileInfo->dwFileVersionLS));
|
|
wsprintf(csVersion, L"%d.%d%d",
|
|
HIWORD(pFixedFileInfo->dwFileVersionMS), LOWORD(pFixedFileInfo->dwFileVersionMS),
|
|
HIWORD(pFixedFileInfo->dwFileVersionLS));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
|
|
JSAPI_SET_RESULT(pvarResult, bstrVal, SysAllocString(csVersion));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT Winamp::SetClientSite(IOleClientSite *pClientSite)
|
|
{
|
|
// TODO
|
|
client_site = pClientSite;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT Winamp::GetClientSite(IOleClientSite **ppClientSite)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::SetHostNames(LPCOLESTR szContainerApp,LPCOLESTR szContainerObj)
|
|
{ return S_OK; }
|
|
HRESULT Winamp::Close(DWORD dwSaveOption)
|
|
{ return S_OK; }
|
|
HRESULT Winamp::SetMoniker(DWORD dwWhichMoniker,IMoniker *pmk)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,IMoniker **ppmk)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::InitFromData(IDataObject *pDataObject,BOOL fCreation,DWORD dwReserved)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::GetClipboardData(DWORD dwReserved,IDataObject **ppDataObject)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::DoVerb(LONG iVerb,LPMSG lpmsg,IOleClientSite *pActiveSite,LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
|
|
{ return S_OK; }
|
|
HRESULT Winamp::EnumVerbs(IEnumOLEVERB **ppEnumOleVerb)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::Update(void)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::IsUpToDate(void)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::GetUserClassID(CLSID *pClsid)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::GetUserType(DWORD dwFormOfType,LPOLESTR *pszUserType)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::SetExtent(DWORD dwDrawAspect,SIZEL *psizel)
|
|
{ return E_NOTIMPL; }
|
|
|
|
HRESULT Winamp::GetExtent(DWORD dwDrawAspect,SIZEL *psizel)
|
|
{
|
|
// TODO
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT Winamp::Advise(IAdviseSink *pAdvSink,DWORD *pdwConnection)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::Unadvise(DWORD dwConnection)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::EnumAdvise(IEnumSTATDATA **ppenumAdvise)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::GetMiscStatus(DWORD dwAspect,DWORD *pdwStatus)
|
|
{
|
|
*pdwStatus = OLEMISC_INVISIBLEATRUNTIME;
|
|
return S_OK;
|
|
}
|
|
HRESULT Winamp::SetColorScheme(LOGPALETTE *pLogpal)
|
|
{ return E_NOTIMPL; }
|
|
|
|
HRESULT Winamp::GetClassID(CLSID *pClassID)
|
|
{ *pClassID = CLSID_WINAMP_CRAP; return S_OK; }
|
|
HRESULT Winamp::IsDirty(void)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::InitNew(IStorage *pStg)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::Load(IStorage *pStg)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::Save(IStorage *pStgSave, BOOL fSameAsLoad)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::SaveCompleted(IStorage *pStgNew)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::HandsOffStorage(void)
|
|
{ return E_NOTIMPL; }
|
|
|
|
HRESULT Winamp::GetData(FORMATETC *pformatetcIn,STGMEDIUM *pmedium)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::GetDataHere(FORMATETC *pformatetc,STGMEDIUM *pmedium)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::QueryGetData(FORMATETC *pformatetc)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::GetCanonicalFormatEtc(FORMATETC *pformatectIn,FORMATETC *pformatetcOut)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::SetData(FORMATETC *pformatetc,STGMEDIUM *pmedium,BOOL fRelease)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC **ppenumFormatEtc)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::DAdvise(FORMATETC *pformatetc,DWORD advf,IAdviseSink *pAdvSink,DWORD *pdwConnection)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::DUnadvise(DWORD dwConnection)
|
|
{ return E_NOTIMPL; }
|
|
HRESULT Winamp::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
|
|
{ return E_NOTIMPL; }
|
|
|
|
HRESULT Winamp::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
|
|
{
|
|
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
|
|
*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
|
|
|
|
return S_OK;
|
|
}
|
|
HRESULT Winamp::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
|
|
{
|
|
|
|
return S_OK;
|
|
} |