From 77e9149fcd326fbb3aec4be4fdf5847a57ab4a28 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 24 Aug 2013 07:01:05 +0000 Subject: first version that compiles ok git-svn-id: http://svn.miranda-ng.org/main/trunk@5800 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ShellExt/src/Version.h | 4 +- plugins/ShellExt/src/main.cpp | 22 +++--- plugins/ShellExt/src/shlcom.cpp | 26 ++++--- plugins/ShellExt/src/shlcom.h | 3 +- plugins/ShellExt/src/shlipc.cpp | 147 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 22 deletions(-) create mode 100644 plugins/ShellExt/src/shlipc.cpp (limited to 'plugins/ShellExt/src') 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; + } +} -- cgit v1.2.3