diff options
Diffstat (limited to 'plugins/ShellExt/src')
| -rw-r--r-- | plugins/ShellExt/src/Version.h | 4 | ||||
| -rw-r--r-- | plugins/ShellExt/src/main.cpp | 22 | ||||
| -rw-r--r-- | plugins/ShellExt/src/shlcom.cpp | 26 | ||||
| -rw-r--r-- | plugins/ShellExt/src/shlcom.h | 3 | ||||
| -rw-r--r-- | plugins/ShellExt/src/shlipc.cpp | 147 | 
5 files changed, 180 insertions, 22 deletions
diff --git a/plugins/ShellExt/src/Version.h b/plugins/ShellExt/src/Version.h index 656c2324b5..89aa117923 100644 --- a/plugins/ShellExt/src/Version.h +++ b/plugins/ShellExt/src/Version.h @@ -9,8 +9,8 @@  #define __STRINGIFY(x)				#x
  #define __VERSION_STRING			__STRINGIFY(__FILEVERSION_STRING_DOTS)
 -#define __PLUGIN_NAME        "ShellExt"
 -#define __FILENAME           "ShellExt.dll"
 +#define __PLUGIN_NAME        "ShlExt"
 +#define __FILENAME           "ShlExt.dll"
  #define __DESCRIPTION        "Windows Explorer extension for Miranda NG."
  #define __AUTHOR             "Sam Kothari, Miranda NG Team"
  #define __AUTHOREMAIL        "egodust@users.sourceforge.net"
 diff --git a/plugins/ShellExt/src/main.cpp b/plugins/ShellExt/src/main.cpp index b2c3473172..1791fc99f8 100644 --- a/plugins/ShellExt/src/main.cpp +++ b/plugins/ShellExt/src/main.cpp @@ -19,7 +19,11 @@ PLUGININFOEX pluginInfoEx = {  BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  {
 -	hInst = hinstDLL;
 +	if (fdwReason == DLL_PROCESS_ATTACH) {
 +		hInst = hinstDLL;
 +		DisableThreadLibraryCalls(hinstDLL);
 +	}
 +
  	return TRUE;
  }
 @@ -53,13 +57,13 @@ TCHAR key1[] = _T("miranda.shlext\\{72013A26-A94C-11d6-8540-A5E62932711D}\\Inpro  HRESULT __stdcall DllRegisterServer()
  {
 -	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext", REG_SZ, str1, sizeof(str1)-1))
 +	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext", REG_SZ, str1, sizeof(str1)))
  		return E_FAIL;
 -	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext\\CLSID", REG_SZ, str2, sizeof(str2)-1))
 +	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext\\CLSID", REG_SZ, str2, sizeof(str2)))
  		return E_FAIL;
 -	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext\\{72013A26-A94C-11d6-8540-A5E62932711D}", REG_SZ, str3, sizeof(str3)-1))
 +	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext\\{72013A26-A94C-11d6-8540-A5E62932711D}", REG_SZ, str3, sizeof(str3)))
  		return E_FAIL;
 -	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext\\{72013A26-A94C-11d6-8540-A5E62932711D}\\ProgID", REG_SZ, str3, sizeof(str3)-1))
 +	if ( RegSetValueA(HKEY_CLASSES_ROOT, "miranda.shlext\\{72013A26-A94C-11d6-8540-A5E62932711D}\\ProgID", REG_SZ, str3, sizeof(str3)))
  		return E_FAIL;
  	TCHAR tszFileName[MAX_PATH];
 @@ -73,15 +77,15 @@ HRESULT __stdcall DllRegisterServer()  	if ( RegSetValueA(k1, "ThreadingModel", REG_SZ, str4, sizeof(str4)))
  		return E_FAIL;
 -	if ( RegSetValueA(HKEY_CLASSES_ROOT, "*\\shellex\\ContextMenuHandlers\\miranda.shlext", REG_SZ, str2, sizeof(str2)-1))
 +	if ( RegSetValueA(HKEY_CLASSES_ROOT, "*\\shellex\\ContextMenuHandlers\\miranda.shlext", REG_SZ, str2, sizeof(str2)))
  		return E_FAIL;
 -	if ( RegSetValueA(HKEY_CLASSES_ROOT, "Directory\\shellex\\ContextMenuHandlers\\miranda.shlext", REG_SZ, str2, sizeof(str2)-1))
 +	if ( RegSetValueA(HKEY_CLASSES_ROOT, "Directory\\shellex\\ContextMenuHandlers\\miranda.shlext", REG_SZ, str2, sizeof(str2)))
  		return E_FAIL;
  	HRegKey k2(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"));
  	if (k2 == NULL)
  		return E_FAIL;
 -	if ( RegSetValueA(k2, str2, REG_SZ, str1, sizeof(str1)-1))
 +	if ( RegSetValueA(k2, str2, REG_SZ, str1, sizeof(str1)))
  		return E_FAIL;
  	return S_OK;
 @@ -89,7 +93,7 @@ HRESULT __stdcall DllRegisterServer()  HRESULT __stdcall DllUnregisterServer()
  {
 -  return RemoveCOMRegistryEntries();
 +	return RemoveCOMRegistryEntries();
  }
  /////////////////////////////////////////////////////////////////////////////////////////
 diff --git a/plugins/ShellExt/src/shlcom.cpp b/plugins/ShellExt/src/shlcom.cpp index 8d7103a5a0..fbbf299894 100644 --- a/plugins/ShellExt/src/shlcom.cpp +++ b/plugins/ShellExt/src/shlcom.cpp @@ -1,13 +1,19 @@  #include "stdafx.h"
  #include "shlcom.h"
 -struct
 +static bool VistaOrLater;
 +
 +struct SHLCOM
  {
  	int FactoryCount, ObjectCount;
 -}
 -static dllpublic;
 -bool VistaOrLater;
 +	SHLCOM() {
 +		FactoryCount = ObjectCount = 0;
 +		VistaOrLater = GetProcAddress( GetModuleHandleA("kernel32.dll"), "GetProductInfo") != NULL;
 +	}		
 +};
 +
 +static SHLCOM dllobject;
  #define IPC_PACKET_SIZE (0x1000 * 32)
  #define IPC_PACKET_NAME "m.mi.miranda.ipc.server"
 @@ -569,7 +575,7 @@ TShlComRec::TShlComRec()    hMemDC = CreateCompatibleDC(DC);
    ReleaseDC(0, DC);
    // keep count on the number of objects
 -  dllpublic.ObjectCount++;
 +  dllobject.ObjectCount++;
  }
  HRESULT TShlComRec::QueryInterface(REFIID riid, void **ppvObject)
 @@ -634,7 +640,7 @@ ULONG TShlComRec::Release()  		// free the instance (class record) created
  		delete this;
 -		dllpublic.ObjectCount--;
 +		dllobject.ObjectCount--;
  	} 
  	return ret;
  }
 @@ -973,7 +979,8 @@ struct TClassFactoryRec : public IClassFactory  {
  	TClassFactoryRec() :
  		RefCount(1)
 -		{	dllpublic.FactoryCount++;
 +		{
 +			dllobject.FactoryCount++;
  		}
  	LONG RefCount;
 @@ -1002,7 +1009,7 @@ ULONG TClassFactoryRec::Release()  	ULONG result = --RefCount;
  	if (result == 0) {
  		delete this;
 -		dllpublic.FactoryCount--;
 +		dllobject.FactoryCount--;
  	}
  	return result;
  }
 @@ -1505,6 +1512,7 @@ HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)  {
  	if (rclsid == CLSID_ISHLCOM && riid == IID_IClassFactory && FindWindowA(MIRANDANAME, NULL) != 0) {
  		*ppv = new TClassFactoryRec();
 +		MessageBoxA(0, "Ding!", "Dong", MB_OK);
  		return S_OK;
  	}
 @@ -1514,7 +1522,7 @@ HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)  HRESULT DllCanUnloadNow()
  {
 -	if (dllpublic.FactoryCount == 0 && dllpublic.ObjectCount == 0)
 +	if (dllobject.FactoryCount == 0 && dllobject.ObjectCount == 0)
  		return S_OK;
  	return S_FALSE;
  }
 diff --git a/plugins/ShellExt/src/shlcom.h b/plugins/ShellExt/src/shlcom.h index 01461acd8d..ab0f337fe7 100644 --- a/plugins/ShellExt/src/shlcom.h +++ b/plugins/ShellExt/src/shlcom.h @@ -114,7 +114,6 @@ struct THeaderIPC  /////////////////////////////////////////////////////////////////////////////////////////
 -
  struct TShlComRec : public IShellExtInit, public IContextMenu3
  {
  	TShlComRec();
 @@ -205,4 +204,4 @@ TSlotIPC* ipcAlloc(THeaderIPC *pipch, int nSize);  void ipcFixupAddresses(BOOL FromServer, THeaderIPC *pipch);
  TGroupNode* AllocGroupNode(TGroupNodeList *list, TGroupNode *Root, int Depth);
 -TGroupNode* FindGroupNode(TGroupNode* P, const DWORD Hash, DWORD Depth);
 +TGroupNode* FindGroupNode(TGroupNode* p, const DWORD Hash, int Depth);
 diff --git a/plugins/ShellExt/src/shlipc.cpp b/plugins/ShellExt/src/shlipc.cpp new file mode 100644 index 0000000000..6cba631398 --- /dev/null +++ b/plugins/ShellExt/src/shlipc.cpp @@ -0,0 +1,147 @@ +#include "stdafx.h"
 +#include "shlcom.h"
 +
 +TGroupNode* FindGroupNode(TGroupNode *p, const DWORD Hash, int Depth)
 +{
 +	while (p != NULL) {
 +		if (p->Hash == Hash && p->Depth == Depth)
 +			return p;
 +
 +		if (p->Left != NULL) {
 +			TGroupNode *q = FindGroupNode(p->Left, Hash, Depth);
 +			if (q != NULL)
 +				return q;
 +		}
 +		p = p->Right;
 +	}
 +	return p;
 +}
 +
 +TGroupNode* AllocGroupNode(TGroupNodeList *list, TGroupNode *Root, int Depth)
 +{
 +	TGroupNode *p = (TGroupNode*)mir_alloc( sizeof(TGroupNode));
 +	p->Left = NULL;
 +	p->Right = NULL;
 +	p->Depth = Depth;
 +	if (Depth > 0) {
 +		if (Root->Left == NULL)
 +			Root->Left = p;
 +		else {
 +			Root = Root->Left;
 +			while (Root->Right != NULL)
 +				Root = Root->Right;
 +			Root->Right = p;
 +		}
 +	}
 +	else {
 +		if (list->First == NULL)
 +			list->First = p;
 +		if (list->Last != NULL)
 +			list->Last->Right = p;
 +		list->Last = p;
 +	}
 +	return p;
 +}
 +
 +void ipcPrepareRequests(int ipcPacketSize, THeaderIPC *pipch, DWORD fRequests)
 +{
 +	// some fields may already have values like the event object name to open
 +	pipch->cbSize = sizeof(THeaderIPC);
 +	pipch->dwVersion = PLUGIN_MAKE_VERSION(2, 0, 1, 2);
 +	pipch->dwFlags = 0;
 +	pipch->pServerBaseAddress = NULL;
 +	pipch->pClientBaseAddress = pipch;
 +	pipch->fRequests = fRequests;
 +	pipch->Slots = 0;
 +	pipch->IconsBegin = NULL;
 +	pipch->ContactsBegin = NULL;
 +	pipch->GroupsBegin = NULL;
 +	pipch->NewIconsBegin = NULL;
 +	pipch->DataSize = ipcPacketSize - pipch->cbSize;
 +	// the server side will adjust these pointers as soon as it opens
 +	// the mapped file to it's base address, these are set 'ere because ipcAlloc()
 +	// maybe used on the client side && are translated by the server side.
 +	// ipcAlloc() is used on the client side when transferring filenames
 +	// to the ST thread.
 +	pipch->DataPtr = (TSlotIPC*)(LPSTR(pipch) + sizeof(THeaderIPC));
 +	pipch->DataPtrEnd = (TSlotIPC*)(LPSTR(pipch->DataPtr) + pipch->DataSize);
 +	pipch->DataFramePtr = pipch->DataPtr;
 +	// fill the data area
 +	memset(pipch->DataPtr, pipch->DataSize, 0);
 +}
 +
 +DWORD ipcSendRequest(HANDLE hSignal, HANDLE hWaitFor, THeaderIPC *pipch, DWORD dwTimeoutMsecs)
 +{
 +	// signal ST to work
 +	SetEvent(hSignal);
 +	// wait for reply, it should open a h&&le to hWaitFor... 
 +	while (true) {
 +		switch ( WaitForSingleObjectEx(hWaitFor, dwTimeoutMsecs, true)) {
 +		case WAIT_OBJECT_0:
 +			return pipch->fRequests;
 +
 +		case WAIT_IO_COMPLETION:
 +			// APC call...
 +			break;
 +
 +		default:
 +			return REPLY_FAIL;
 +		}
 +	}
 +}
 +
 +TSlotIPC* ipcAlloc(THeaderIPC *pipch, int nSize)
 +{
 +	// nSize maybe zero, in that case there is no string section ---
 +	UINT_PTR PSP = UINT_PTR(pipch->DataFramePtr) + sizeof(TSlotIPC) + nSize;
 +	// is it past the end?
 +	if (PSP >= UINT_PTR(pipch->DataPtrEnd))
 +		return NULL;
 +	// return the pointer
 +	TSlotIPC *p = (TSlotIPC*)pipch->DataFramePtr;
 +	// set up the item
 +	p->cbSize = sizeof(TSlotIPC);
 +	p->cbStrSection = nSize;
 +	// update the frame ptr
 +	pipch->DataFramePtr = (void*)PSP;
 +	// let this item jump to the next yet-to-be-allocated-item which should be null anyway
 +	p->Next = (TSlotIPC*)PSP;
 +	return p;
 +}
 +
 +void ipcFixupAddresses(BOOL FromServer, THeaderIPC *pipch)
 +{
 +	if (pipch->pServerBaseAddress == pipch->pClientBaseAddress)
 +		return;
 +
 +	INT_PTR diff = INT_PTR(pipch->pClientBaseAddress) - INT_PTR(pipch->pServerBaseAddress);
 +
 +	// fix up all the pointers in the header
 +	if (pipch->IconsBegin != NULL)
 +		pipch->IconsBegin = (TSlotIPC*)(UINT_PTR(pipch->IconsBegin) + diff);
 +
 +	if (pipch->ContactsBegin != NULL)
 +		pipch->ContactsBegin = (TSlotIPC*)(UINT_PTR(pipch->ContactsBegin) + diff);
 +
 +	if (pipch->GroupsBegin != NULL)
 +		pipch->GroupsBegin = (TSlotIPC*)(UINT_PTR(pipch->GroupsBegin) + diff);
 +
 +	if (pipch->NewIconsBegin != NULL)
 +		pipch->NewIconsBegin = (TSlotIPC*)(UINT_PTR(pipch->NewIconsBegin) + diff);
 +
 +	pipch->DataPtr = (TSlotIPC*)(UINT_PTR(pipch->DataPtr) + diff);
 +	pipch->DataPtrEnd = (TSlotIPC*)(UINT_PTR(pipch->DataPtrEnd) + diff);
 +	pipch->DataFramePtr = (void*)(UINT_PTR(pipch->DataFramePtr) + diff);
 +
 +	// and the link list
 +	TSlotIPC *pct = pipch->DataPtr;
 +	while (pct != NULL) {
 +		// the first pointer is already fixed up, have to get a pointer
 +		// to the next pointer && modify where it jumps to
 +		TSlotIPC **q = &pct->Next;
 +		if (*q != NULL)
 +			*q = (TSlotIPC*)(UINT_PTR(*q) + diff);
 +
 +		pct = *q;
 +	}
 +}
  | 
