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/res/shldlgs.rc | 45 ++++++++ plugins/ShellExt/shellext_10.vcxproj | 11 +- plugins/ShellExt/shellext_10.vcxproj.filters | 19 +++- plugins/ShellExt/shellext_11.vcxproj | 8 +- plugins/ShellExt/shellext_11.vcxproj.filters | 6 ++ 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 +++++++++++++++++++++++++++ 10 files changed, 265 insertions(+), 26 deletions(-) create mode 100644 plugins/ShellExt/res/shldlgs.rc create mode 100644 plugins/ShellExt/src/shlipc.cpp (limited to 'plugins') diff --git a/plugins/ShellExt/res/shldlgs.rc b/plugins/ShellExt/res/shldlgs.rc new file mode 100644 index 0000000000..83c3145139 --- /dev/null +++ b/plugins/ShellExt/res/shldlgs.rc @@ -0,0 +1,45 @@ +#include "..\src\resource.h" +#include "afxres.h" + +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_SHLOPTS DIALOG DISCARDABLE 0, 0, 312, 238 +STYLE WS_POPUP +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Display contacts in their assigned groups (if any)", + IDC_USEGROUPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15, + 35,281,8 + CONTROL "Only if/when the contact list is using them", + IDC_CLISTGROUPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,29, + 50,267,8 + CONTROL "Display hidden, ignored or temporary contacts", + IDC_SHOWFULL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,65, + 281,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,26,21,192,1 + LTEXT "Menus",IDC_CAPMENUS,10,17,24,8 + LTEXT "",IDC_STATIC,214,16,10,11,NOT WS_GROUP + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,34,145,183,1 + LTEXT "Shell Status",IDC_CAPSHLSTATUS,10,141,43,8 + LTEXT "",IDC_STATIC,214,111,10,11,NOT WS_GROUP + LTEXT "...",IDC_STATUS,15,154,253,12 + GROUPBOX "Shell context menus",IDC_STATIC,0,0,311,238 + CONTROL "Do not display the profile name in use",IDC_NOPROF, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,80,285,8 + CONTROL "Show contacts that you have set privacy rules for", + IDC_SHOWINVISIBLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 15,110,290,8 + PUSHBUTTON "Remove",IDC_REMOVE,14,173,42,14 + CONTROL "Do not show status icons in menus",IDC_USEOWNERDRAW, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,95,290,8 + LTEXT "",IDC_STATIC,214,136,10,11,NOT WS_GROUP + CONTROL "Do not show contacts that are offline, even if my contact list does",IDC_HIDEOFFLINE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,125,290,8 +END diff --git a/plugins/ShellExt/shellext_10.vcxproj b/plugins/ShellExt/shellext_10.vcxproj index c7bcaf7f97..830c94747e 100644 --- a/plugins/ShellExt/shellext_10.vcxproj +++ b/plugins/ShellExt/shellext_10.vcxproj @@ -98,6 +98,7 @@ false $(ProfileDir)..\..\bin10\lib /PDBALTPATH:%_PDB% + mir_core.dll @@ -126,6 +127,7 @@ $(IntDir)$(TargetName).lib false $(ProfileDir)..\..\bin10\lib + mir_core.dll @@ -154,6 +156,7 @@ false $(ProfileDir)..\..\bin10\lib /PDBALTPATH:%_PDB% + mir_core.dll @@ -180,19 +183,25 @@ $(IntDir)$(TargetName).lib false $(ProfileDir)..\..\bin10\lib + mir_core.dll + + - + + + + Create diff --git a/plugins/ShellExt/shellext_10.vcxproj.filters b/plugins/ShellExt/shellext_10.vcxproj.filters index 6bad33a8fc..94085f5086 100644 --- a/plugins/ShellExt/shellext_10.vcxproj.filters +++ b/plugins/ShellExt/shellext_10.vcxproj.filters @@ -24,12 +24,18 @@ Header Files + + Header Files + + + Header Files + - + Resource Files - + Resource Files @@ -40,5 +46,14 @@ Source Files + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file diff --git a/plugins/ShellExt/shellext_11.vcxproj b/plugins/ShellExt/shellext_11.vcxproj index 12aae8a42d..f34657320e 100644 --- a/plugins/ShellExt/shellext_11.vcxproj +++ b/plugins/ShellExt/shellext_11.vcxproj @@ -19,7 +19,7 @@ - ShellExt + ShlExt {B27B85B5-0EF1-496D-99D7-0702A98A342A} @@ -101,6 +101,7 @@ true false $(ProfileDir)..\..\bin11\lib + mir_core.dll @@ -130,6 +131,7 @@ false $(ProfileDir)..\..\bin11\lib false + mir_core.dll @@ -157,6 +159,7 @@ $(IntDir)$(TargetName).lib false $(ProfileDir)..\..\bin11\lib + mir_core.dll @@ -183,6 +186,7 @@ $(IntDir)$(TargetName).lib false $(ProfileDir)..\..\bin11\lib + mir_core.dll @@ -193,12 +197,14 @@ + + Create diff --git a/plugins/ShellExt/shellext_11.vcxproj.filters b/plugins/ShellExt/shellext_11.vcxproj.filters index 85793afe77..94085f5086 100644 --- a/plugins/ShellExt/shellext_11.vcxproj.filters +++ b/plugins/ShellExt/shellext_11.vcxproj.filters @@ -35,6 +35,9 @@ Resource Files + + Resource Files + @@ -49,5 +52,8 @@ Source Files + + Source Files + \ No newline at end of file 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