summaryrefslogtreecommitdiff
path: root/plugins/ShellExt/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2013-08-24 07:01:05 +0000
committerGeorge Hazan <george.hazan@gmail.com>2013-08-24 07:01:05 +0000
commit77e9149fcd326fbb3aec4be4fdf5847a57ab4a28 (patch)
tree194fcb0fc1acd1ca64524db4b51837466e6b9b57 /plugins/ShellExt/src
parent22a7ffc73ec791f682edd2983a8f2279539f68b0 (diff)
first version that compiles ok
git-svn-id: http://svn.miranda-ng.org/main/trunk@5800 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/ShellExt/src')
-rw-r--r--plugins/ShellExt/src/Version.h4
-rw-r--r--plugins/ShellExt/src/main.cpp22
-rw-r--r--plugins/ShellExt/src/shlcom.cpp26
-rw-r--r--plugins/ShellExt/src/shlcom.h3
-rw-r--r--plugins/ShellExt/src/shlipc.cpp147
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;
+ }
+}