| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 | //#define PLUGIN_NAME "Nullsoft ActiveSync Plug-in"#define PLUGIN_VERSION L"0.25"#include "ASDevice.h"int init();void quit();intptr_t MessageProc(int msg, intptr_t param1, intptr_t param2, intptr_t param3);extern PMPDevicePlugin plugin = {PMPHDR_VER,0,init,quit,MessageProc};static HANDLE killEvent=0, hThread=0;static DWORD WINAPI ThreadFunc(LPVOID lpParam);IRAPIDesktop *pIRapiDesktop = NULL;// wasabi based services for localisation supportapi_language *WASABI_API_LNG = 0;HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;std::vector<ASDevice*> devices;std::vector<ejectedDevice*> ejected;static RAPIDEVICEID lastDevId;class MyRAPISink : public IRAPISink {public:	virtual HRESULT STDMETHODCALLTYPE OnDeviceConnected(IRAPIDevice *pIDevice) {		RAPI_DEVICEINFO devInfo;		if(!SUCCEEDED(pIDevice->GetDeviceInfo(&devInfo))) return S_OK;		SysFreeString(devInfo.bstrName);		SysFreeString(devInfo.bstrPlatform);				EnterCriticalSection(&cs);		lastDevId = devInfo.DeviceId;		for(unsigned int i=0; i<ejected.size(); i++) {			if(devInfo.DeviceId == ejected[i]->id) {				ejected[i]->marked=true;				LeaveCriticalSection(&cs);				return S_OK;			}		}		for(unsigned int i=0; i<devices.size(); i++) {			if(devInfo.DeviceId == devices[i]->devInfo.DeviceId || devices[i]->pIDevice == pIDevice) {				LeaveCriticalSection(&cs);				return S_OK;			}		}		IRAPISession *pISession = NULL;		if (SUCCEEDED(pIDevice->CreateSession(&pISession))) {			if (SUCCEEDED(pISession->CeRapiInit())) devices.push_back(new ASDevice(pIDevice,pISession));			else pISession->Release();		}		LeaveCriticalSection(&cs);		return S_OK;	}		virtual HRESULT STDMETHODCALLTYPE OnDeviceDisconnected(IRAPIDevice *pIDevice) {		EnterCriticalSection(&cs);		RAPI_DEVICEINFO devInfo;		if(!SUCCEEDED(pIDevice->GetDeviceInfo(&devInfo))) return S_OK;		for(unsigned int i=0; i<devices.size(); i++) {			if(devInfo.DeviceId == devices[i]->devInfo.DeviceId || devices[i]->pIDevice == pIDevice) {				SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)devices[i],PMP_IPC_DEVICEDISCONNECTED);				delete devices[i];			}		}		SysFreeString(devInfo.bstrName);		SysFreeString(devInfo.bstrPlatform);		LeaveCriticalSection(&cs);		return S_OK;	}		DWORD RAPISinkContext;	CRITICAL_SECTION cs;	ULONG refs;  MyRAPISink() {refs=1; InitializeCriticalSection(&cs);}	~MyRAPISink() { DeleteCriticalSection(&cs); }  #define IMPLEMENTS(ifc) if (riid == IID_ ## ifc) { ++refs; *ppvObject = static_cast<ifc *>(this); return S_OK; }  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void __RPC_FAR *__RPC_FAR *ppvObject) {    IMPLEMENTS(IRAPISink);    IMPLEMENTS(IUnknown);    *ppvObject = NULL; 	  return E_NOINTERFACE;  }  virtual ULONG STDMETHODCALLTYPE AddRef() { return ++refs; }  virtual ULONG STDMETHODCALLTYPE Release() { int x = --refs; if(!x) delete this; return x; }  #undef IMPLEMENTS};MyRAPISink *pMyRapiSink=NULL;int init() {	CoInitializeEx(NULL, COINIT_MULTITHREADED);	HRESULT hr = CoCreateInstance(CLSID_RAPI,NULL,CLSCTX_INPROC_SERVER,IID_IRAPIDesktop,(void**)&pIRapiDesktop);	if(!SUCCEEDED(hr) || !pIRapiDesktop) return -1; // no activesync on this computer!	// loader so that we can get the localisation service api for use	waServiceFactory *sf = plugin.service->service_getServiceByGuid(languageApiGUID);	if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());	// need to have this initialised before we try to do anything with localisation features	WASABI_API_START_LANG(plugin.hDllInstance,PmpACTIVESYNCLangGUID);	static wchar_t szDescription[256];	swprintf(szDescription, ARRAYSIZE(szDescription),			 WASABI_API_LNGSTRINGW(IDS_NULLSOFT_ACTIVESYNC_PLUGIN), PLUGIN_VERSION);	plugin.description = szDescription;	killEvent = CreateEvent(NULL,TRUE,FALSE,NULL);	DWORD dwThreadId; 	hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, &dwThreadId);	return 0;}static void enumDevices() {	// find all the currently connected devices	IRAPIEnumDevices* pIRapiEnumDevices = NULL;	HRESULT hr = pIRapiDesktop->EnumDevices(&pIRapiEnumDevices);	for (unsigned int i = 0; i < ejected.size(); i++) ejected[i]->marked = false;	while (SUCCEEDED(hr) && pIRapiEnumDevices) {		IRAPIDevice* pIRapiDevice = NULL;		hr = pIRapiEnumDevices->Next(&pIRapiDevice);		if (SUCCEEDED(hr) && pIRapiDevice) {			pMyRapiSink->OnDeviceConnected(pIRapiDevice);			pIRapiDevice->Release();		}		else {			pIRapiEnumDevices->Release();			pIRapiEnumDevices = NULL;		}	}	//for (unsigned int i = 0; i < ejected.size(); i++)	//{	//	if (!ejected[i]->marked)	//	{	//		free(ejected[i]);	//		ejected.eraseindex(i);	//	}	//}	auto it = ejected.begin();	while (it != ejected.end())	{		ejectedDevice* dev = *it;		if (!dev->marked)		{			free(dev);			it = ejected.erase(it);		}		else		{			it++;		}	}}static void init2() {	// set up device connection/disconnection notifications	pMyRapiSink = new MyRAPISink();	pIRapiDesktop->Advise(pMyRapiSink,(DWORD_PTR*)&pMyRapiSink->RAPISinkContext);	// find currently attached devices	enumDevices();}void quit() {	SetEvent(killEvent);	if (hThread) {		for(;;) {			int val = WaitForSingleObjectEx(hThread,15000,TRUE);			if(val == WAIT_OBJECT_0) { CloseHandle(hThread); break; }			else if(val == WAIT_TIMEOUT) { TerminateThread(hThread, 0); break; }			else continue;		}	}	CloseHandle(killEvent);	pIRapiDesktop->UnAdvise(pMyRapiSink->RAPISinkContext);	pIRapiDesktop->Release();	pMyRapiSink->Release();  CoUninitialize();	for(unsigned int i=0; i<ejected.size(); i++) free(ejected[i]);}static DWORD WINAPI ThreadFunc(LPVOID lpParam) {	CoInitializeEx(0,COINIT_MULTITHREADED);	init2();	while (WaitForSingleObjectEx(killEvent,5000,TRUE) != WAIT_OBJECT_0) {		// FUCKO: For some reason I'm not getting the device connected notifications, so lets just enum for devices on a regular basis.		enumDevices();	}	CoUninitialize();  return 0;}intptr_t MessageProc(int msg, intptr_t param1, intptr_t param2, intptr_t param3) {	if (msg == PMP_NO_CONFIG)		return TRUE;	return FALSE;}extern "C" {	__declspec( dllexport ) PMPDevicePlugin * winampGetPMPDevicePlugin(){return &plugin;}	__declspec( dllexport ) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param) {		int i = (int)devices.size();		while(i-- > 0) devices[i]->Close();		return PMP_PLUGIN_UNINSTALL_NOW;	}};
 |