#pragma once /* For use within Outlook add-ins only -- v0.2 April 4, 2004 (c) MAPILab Ltd. -- http://www.mapilab.com/ Software for Microsoft Outlook & Exchange Server History: v0.2 - April 4, 2004 FIX: we should not release the pointer returned by __getSuperObjectFn, because this function don't increase object references counter NEW: the code was successfully tested with Outlook 2000 SR-1, Outlook XP and Outlook 2003 (with lpOutlApp=NULL) v0.1 - April 1, 2004 NEW: Initial release at http://blogs.OfficeZealot.com/gorlach/ To-do: 1. Test code with Outlook 2000 (not SR-1) 2. Test code with Outlook 2000 in IMO mode */ // {00067263-0000-C000-000000000046} DEFINE_GUID(IID_SuperOutlookObject, 0x67263, 0,0,0xC0,0,0,0,0,0,0,0x46); typedef LPUNKNOWN (WINAPI *__getSuperObjectFn)(void); class ISuperOutlookObject : public IUnknown { public: STDMETHOD(GetMapiSession)(IMAPISession **session) = 0; }; HRESULT GetSuperMapiSession(Outlook::_Application *lpOutlApp, LPMAPISESSION *lppSession) { HRESULT hr; IUnknown *unk = NULL; if (!lppSession) return MAPI_E_INVALID_PARAMETER; if (lpOutlApp) { // this method work for Outlook XP and Outlook 2003, and will work in future versions Outlook::_NameSpace *lpOutlNamespace = NULL; if (SUCCEEDED(hr=lpOutlApp->get_Session(&lpOutlNamespace))) { DISPID rgDispId; DISPPARAMS dispparams = {NULL, NULL, 0, 0}; VARIANT vaResult; LPOLESTR pName = L"MAPIOBJECT"; VariantInit(&vaResult); if (SUCCEEDED(hr=lpOutlNamespace->GetIDsOfNames(IID_NULL,&pName,1,LOCALE_SYSTEM_DEFAULT,&rgDispId))) if (SUCCEEDED(hr=lpOutlNamespace->Invoke(rgDispId, IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &vaResult, NULL, NULL))) if (vaResult.vt == VT_UNKNOWN) unk = vaResult.punkVal; lpOutlNamespace->Release(); if (unk) { hr=unk->QueryInterface(IID_IMAPISession,(void**)lppSession); unk->Release(); unk = NULL; if (SUCCEEDED(hr)) return hr; } } } // this method work with Outlook 2000, Outlook XP and Outlook 2003, but // may cause exception in future Outlook versions HMODULE hLib = LoadLibrary("OUTLLIB.DLL"); if (!hLib) return E_FAIL; BYTE* lpbFn = (BYTE*)GetProcAddress(hLib,"HrDisplayFolderPickerForOutlookToday@0"); if (!lpbFn) { FreeLibrary(hLib); return E_FAIL; } for (int a = 0; a < 100; a++) if (lpbFn[a] == 0xe8) // search for first CALL in HrDisplayFolderPickerForOutlookToday { DWORD addr = (DWORD)(lpbFn + 5 + a + *(DWORD*)(lpbFn+a+1)); if (addr > (DWORD)hLib && addr < (DWORD)lpbFn+0x0100000) { __getSuperObjectFn fn = (__getSuperObjectFn)addr; unk = fn(); break; } } if (unk) { ISuperOutlookObject *pSuperObject = NULL; if (SUCCEEDED(hr=unk->QueryInterface(IID_SuperOutlookObject,(void**)&pSuperObject))) { hr = pSuperObject->GetMapiSession(lppSession); pSuperObject->Release(); } unk = NULL; // Don't release this pointer! __getSuperObjectFn don't increase // object references counter. } else hr = E_FAIL; FreeLibrary(hLib); return hr; }