Creates a COM service to able Jitsi 32 bits to communicate with MAPI 64 bits (Outlook). And vice-versa.

cusax-fix
Vincent Lucas 13 years ago
parent 30d591762b
commit bd11acf2b2

@ -44,41 +44,6 @@ AddrBookContactQuery_getPtrCallbackMethodID(JNIEnv *jniEnv, jobject callback)
return callbackMethodID;
}
jmethodID
AddrBookContactQuery_getStringCallbackMethodID(
JNIEnv *jniEnv, jobject callback)
{
jclass callbackClass;
jmethodID callbackMethodID = 0;
/*
* Make sure that the specified arguments are valid. For example, check
* whether callback exists and has the necessary signature.
*/
if (callback)
{
callbackClass = (*jniEnv)->GetObjectClass(jniEnv, callback);
if (callbackClass)
{
callbackMethodID
= (*jniEnv)->GetMethodID(
jniEnv,
callbackClass, "callback", "(Ljava/lang/String;)Z");
if (!callbackMethodID)
{
Exception_throwNew(
jniEnv, "java/lang/IllegalArgumentException", "callback");
}
}
}
else
{
Exception_throwNew(
jniEnv, "java/lang/NullPointerException", "callback");
}
return callbackMethodID;
}
static void
Exception_throwNew(JNIEnv *jniEnv, const char *className, const char *message)
{

@ -17,9 +17,6 @@ extern "C" {
jmethodID AddrBookContactQuery_getPtrCallbackMethodID
(JNIEnv *jniEnv, jobject callback);
jmethodID AddrBookContactQuery_getStringCallbackMethodID
(JNIEnv *jniEnv, jobject callback);
#ifdef __cplusplus
}
#endif /* #ifdef __cplusplus */

@ -0,0 +1,98 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "MAPIBitness.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Msi.h>
#include <stdio.h>
/**
* Checks the bitness of the Outlook installation and of the Jitsi executable.
*
* @author Vincent Lucas
*/
/**
* Returns the bitness of the current executable.
*
* @return 64 if the current executable is 64 bits. 32 otherwise.
*/
int MAPIBitness_getExecutableBitnessVersion(void)
{
char executable[FILENAME_MAX];
GetModuleFileName(NULL, executable, FILENAME_MAX);
DWORD type;
GetBinaryType(executable, &type);
if(type == SCS_64BIT_BINARY)
{
return 64;
}
return 32;
}
/**
* Returns the bitness of the Outlook installation.
*
* @return 64 if Outlook 64 bits version is installed. 32 if Outlook 32 bits
* version is installed. -1 otherwise.
*/
int MAPIBitness_getOutlookBitnessVersion(void)
{
int nbOutlookRegister = 3;
TCHAR outlookRegister[][MAX_PATH] = {
TEXT("{1E77DE88-BCAB-4C37-B9E5-073AF52DFD7A}"), // Outlook 2010
TEXT("{24AAE126-0911-478F-A019-07B875EB9996}"), // Outlook 2007
TEXT("{BC174BAD-2F53-4855-A1D5-0D575C19B1EA}") // Outlook 2003
};
DWORD pathLength = 0;
for(int i = 0; i < nbOutlookRegister; ++i)
{
if(MsiProvideQualifiedComponent(
outlookRegister[i],
TEXT("outlook.x64.exe"),
(DWORD) INSTALLMODE_DEFAULT,
NULL,
&pathLength)
== ERROR_SUCCESS)
{
return 64;
}
else if(MsiProvideQualifiedComponent(
outlookRegister[i],
TEXT("outlook.exe"),
(DWORD) INSTALLMODE_DEFAULT,
NULL,
&pathLength)
== ERROR_SUCCESS)
{
return 32;
}
}
return -1;
}
/**
* Tests if the bitness of the Outlook installation is identical to the current
* executable.
*
* Returns 1 if the bitness of the Outlook installation is identical to the
* current executable. 0 otherwise.
*/
int MAPIBitness_isOutlookBitnessCompatible(void)
{
int outlookVersion = MAPIBitness_getOutlookBitnessVersion();
int executableVersion = MAPIBitness_getExecutableBitnessVersion();
return (outlookVersion == executableVersion);
}

@ -0,0 +1,21 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MAPIBITNESS_H_
#define _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MAPIBITNESS_H_
/**
* Checks the bitness of the Outlook installation and of the Jitsi executable.
*
* @author Vincent Lucas
*/
int MAPIBitness_getExecutableBitnessVersion(void);
int MAPIBitness_getOutlookBitnessVersion(void);
int MAPIBitness_isOutlookBitnessCompatible(void);
#endif

@ -9,6 +9,7 @@
#include "MAPISession.h"
#include "net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService.h"
#include "net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.h"
#include "MsOutlookAddrBookContactSourceService.h"
#include <mapidefs.h>
#include <stdio.h>
@ -21,10 +22,6 @@
* @author Vincent Lucas
*/
void MAPINotification_registerNotifyAllMsgStores(LPMAPISESSION mapiSession);
void MAPINotification_unregisterNotifyAllMsgStores(void);
/**
* The List of events we want to retrieve.
*/
@ -46,23 +43,78 @@ static jobject MAPINotification_notificationsDelegateObject = NULL;
static ULONG MAPINotification_openEntryUlFlags = MAPI_BEST_ACCESS;
static JavaVM * MAPINotification_VM = NULL;
void MAPINotification_callDeletedMethod(LPSTR iUnknown);
void MAPINotification_callInsertedMethod(LPSTR iUnknown);
void MAPINotification_callUpdatedMethod(LPSTR iUnknown);
void (*MAPINotification_callDeletedMethod)(LPSTR iUnknown) = NULL;
void (*MAPINotification_callInsertedMethod)(LPSTR iUnknown) = NULL;
void (*MAPINotification_callUpdatedMethod)(LPSTR iUnknown) = NULL;
LPUNKNOWN
MAPINotification_openEntry
(ULONG cbEntryID, LPENTRYID lpEntryID, LPVOID lpvContext);
ULONG MAPINotification_registerNotifyMessageDataBase(LPMDB iUnknown);
ULONG MAPINotification_registerNotifyTable(LPMAPITABLE iUnknown);
LONG STDAPICALLTYPE MAPINotification_tableChanged
(LPVOID lpvContext, ULONG cNotifications, LPNOTIFICATION lpNotifications);
/**
* Calls back the java side to list a contact.
*
* @param iUnknown The string representation of the entry id of the contact.
* @param object The Java object used to call the callback method. If NULL, then
* call the inserted notification method.
*
* @return True everything works fine and that we must continue to list the
* other contacts. False otherwise.
*/
boolean MAPINotification_callCallbackMethod(LPSTR iUnknown, void * object)
{
if(object == NULL)
{
MAPINotification_jniCallInsertedMethod(iUnknown);
return true;
}
boolean proceed = false;
JNIEnv *tmpJniEnv = NULL;
if(MAPINotification_VM
->AttachCurrentThreadAsDaemon((void**) &tmpJniEnv, NULL) == 0)
{
if(object != NULL)
{
jclass callbackClass = tmpJniEnv->GetObjectClass((jobject) object);
if(callbackClass)
{
jmethodID ptrOutlookContactCallbackMethodIdCallback
= tmpJniEnv->GetMethodID(
callbackClass,
"callback",
"(Ljava/lang/String;)Z");
if(ptrOutlookContactCallbackMethodIdCallback)
{
jstring value = tmpJniEnv->NewStringUTF(iUnknown);
// Report the MAPI_MAILUSER to the callback.
proceed = tmpJniEnv->CallBooleanMethod(
(jobject) object,
ptrOutlookContactCallbackMethodIdCallback,
value);
}
}
}
MAPINotification_VM->DetachCurrentThread();
}
return proceed;
}
/**
* Calls back the java side when a contact is deleted.
*
* @param iUnknown The string representation of the entry id of the deleted
* contact.
*/
void MAPINotification_callDeletedMethod(LPSTR iUnknown)
void MAPINotification_jniCallDeletedMethod(LPSTR iUnknown)
{
JNIEnv *tmpJniEnv = NULL;
@ -85,7 +137,7 @@ void MAPINotification_callDeletedMethod(LPSTR iUnknown)
*
* @param iUnknown A pointer to the newly created contact.
*/
void MAPINotification_callInsertedMethod(LPSTR iUnknown)
void MAPINotification_jniCallInsertedMethod(LPSTR iUnknown)
{
JNIEnv *tmpJniEnv = NULL;
@ -108,7 +160,7 @@ void MAPINotification_callInsertedMethod(LPSTR iUnknown)
*
* @param iUnknown A pointer to the updated contact.
*/
void MAPINotification_callUpdatedMethod(LPSTR iUnknown)
void MAPINotification_jniCallUpdatedMethod(LPSTR iUnknown)
{
JNIEnv *tmpJniEnv = NULL;
@ -153,14 +205,16 @@ STDAPICALLTYPE MAPINotification_onNotify
{
if(lpvContext != NULL)
{
LPSTR entryIdStr = (LPSTR)::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
LPSTR entryIdStr = (LPSTR)
::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
HexFromBin(
(LPBYTE) lpNotifications[i].info.obj.lpEntryID,
lpNotifications[i].info.obj.cbEntryID,
entryIdStr);
if(lpNotifications[i].info.obj.ulObjType == MAPI_MESSAGE)
if(lpNotifications[i].info.obj.ulObjType == MAPI_MESSAGE
&& MAPINotification_callInsertedMethod != NULL)
{
MAPINotification_callInsertedMethod(entryIdStr);
}
@ -174,14 +228,16 @@ STDAPICALLTYPE MAPINotification_onNotify
{
if(lpvContext != NULL)
{
LPSTR entryIdStr = (LPSTR)::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
LPSTR entryIdStr = (LPSTR)
::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
HexFromBin(
(LPBYTE) lpNotifications[i].info.obj.lpEntryID,
lpNotifications[i].info.obj.cbEntryID,
entryIdStr);
if(lpNotifications[i].info.obj.ulObjType == MAPI_MESSAGE)
if(lpNotifications[i].info.obj.ulObjType == MAPI_MESSAGE
&& MAPINotification_callUpdatedMethod != NULL)
{
MAPINotification_callUpdatedMethod(entryIdStr);
}
@ -195,14 +251,16 @@ STDAPICALLTYPE MAPINotification_onNotify
{
if(lpvContext != NULL)
{
LPSTR entryIdStr = (LPSTR)::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
LPSTR entryIdStr = (LPSTR)
::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
HexFromBin(
(LPBYTE) lpNotifications[i].info.obj.lpEntryID,
lpNotifications[i].info.obj.cbEntryID,
entryIdStr);
if(lpNotifications[i].info.obj.ulObjType == MAPI_MESSAGE)
if(lpNotifications[i].info.obj.ulObjType == MAPI_MESSAGE
&& MAPINotification_callDeletedMethod != NULL)
{
MAPINotification_callDeletedMethod(entryIdStr);
}
@ -216,14 +274,14 @@ STDAPICALLTYPE MAPINotification_onNotify
{
if(lpvContext != NULL)
{
LPSTR entryIdStr
= (LPSTR)::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
LPSTR entryIdStr = (LPSTR)
::malloc(lpNotifications[i].info.obj.cbEntryID * 2 + 1);
HexFromBin(
(LPBYTE) lpNotifications[i].info.obj.lpEntryID,
lpNotifications[i].info.obj.cbEntryID,
entryIdStr);
LPSTR parentEntryIdStr
= (LPSTR)::malloc(lpNotifications[i].info.obj.cbParentID * 2 + 1);
LPSTR parentEntryIdStr = (LPSTR)
::malloc(lpNotifications[i].info.obj.cbParentID * 2 + 1);
HexFromBin(
(LPBYTE) lpNotifications[i].info.obj.lpParentID,
lpNotifications[i].info.obj.cbParentID,
@ -250,7 +308,8 @@ STDAPICALLTYPE MAPINotification_onNotify
if(lpNotifications[i].info.obj.ulObjType == MAPI_MESSAGE
&& strcmp(parentEntryIdStr, wasteBasketEntryIdStr) == 0)
&& strcmp(parentEntryIdStr, wasteBasketEntryIdStr) == 0
&& MAPINotification_callDeletedMethod != NULL)
{
MAPINotification_callDeletedMethod(entryIdStr);
}
@ -307,13 +366,12 @@ MAPINotification_openEntry
* updated.
*
* @param jniEnv The Java native interface environment.
* @param mapiSession The current MAPI session.
* @param notificationsDelegate The object called when a notification is fired
* (contact updated, inserted or deleted).
*/
void
MAPINotification_registerNotificationsDelegate
(JNIEnv *jniEnv, LPMAPISESSION mapiSession, jobject notificationsDelegate)
MAPINotification_registerJniNotificationsDelegate
(JNIEnv *jniEnv, jobject notificationsDelegate)
{
if(jniEnv->GetJavaVM(&MAPINotification_VM) < 0)
{
@ -323,9 +381,9 @@ MAPINotification_registerNotificationsDelegate
// If this function is called once again, then check first to unregister
// previous notification advises.
MAPINotification_unregisterNotificationsDelegate(jniEnv);
MAPINotification_unregisterJniNotificationsDelegate(jniEnv);
if(notificationsDelegate != NULL && mapiSession != NULL)
if(notificationsDelegate != NULL)
{
MAPINotification_notificationsDelegateObject
= jniEnv->NewGlobalRef(notificationsDelegate);
@ -348,15 +406,42 @@ MAPINotification_registerNotificationsDelegate
callbackClass,
"deleted",
"(Ljava/lang/String;)V");
// Register the notification of contact changed, created and
// deleted.
MAPINotification_registerNotifyAllMsgStores(mapiSession);
MAPINotification_callDeletedMethod
= MAPINotification_jniCallDeletedMethod;
MAPINotification_callInsertedMethod
= MAPINotification_jniCallInsertedMethod;
MAPINotification_callUpdatedMethod
= MAPINotification_jniCallUpdatedMethod;
}
}
}
/**
* Registers C callback functions when a contact is deleted, inserted or
* updated.
*
* @param deletedMethod The method to call when a contact has been deleted.
* @param insertedMethod The method to call when a contact has been inserted.
* @param updatedMethod The method to call when a contact has been updated.
*/
void
MAPINotification_registerNativeNotificationsDelegate
(void * deletedMethod, void * insertedMethod, void *updatedMethod)
{
// If this function is called once again, then check first to unregister
// previous notification advises.
MAPINotification_unregisterNativeNotificationsDelegate();
MAPINotification_callDeletedMethod = (void (*)(char*)) deletedMethod;
MAPINotification_callInsertedMethod = (void (*)(char*)) insertedMethod;
MAPINotification_callUpdatedMethod = (void (*)(char*)) updatedMethod;
}
/**
* Opens all the message store and register to notifications.
*
* @param mapiSession The current MAPI session.
*/
void MAPINotification_registerNotifyAllMsgStores(LPMAPISESSION mapiSession)
{
@ -525,9 +610,8 @@ STDAPICALLTYPE MAPINotification_tableChanged
*
* @param jniEnv The Java native interface environment.
*/
void MAPINotification_unregisterNotificationsDelegate(JNIEnv *jniEnv)
void MAPINotification_unregisterJniNotificationsDelegate(JNIEnv *jniEnv)
{
MAPINotification_unregisterNotifyAllMsgStores();
if(MAPINotification_notificationsDelegateObject != NULL)
{
jniEnv->DeleteGlobalRef(MAPINotification_notificationsDelegateObject);
@ -538,6 +622,14 @@ void MAPINotification_unregisterNotificationsDelegate(JNIEnv *jniEnv)
}
}
/**
* Unregisters C callback functions when a contact is deleted, inserted or
* updated.
*/
void MAPINotification_unregisterNativeNotificationsDelegate()
{
}
/**
* Frees all memory used to keep in mind the list of the message store and
* unregister each of them from the notifications.

@ -12,22 +12,39 @@
extern "C" {
#endif
#include "MsOutlookMAPI.h"
#include <jni.h>
#include <mapidefs.h>
#include <mapix.h>
/**
* Manages notification for the message data base (used to get the list of
* contact).
*
* @author Vincent Lucas
*/
boolean MAPINotification_callCallbackMethod(LPSTR iUnknown, void * object);
void MAPINotification_jniCallDeletedMethod(LPSTR iUnknown);
void MAPINotification_jniCallInsertedMethod(LPSTR iUnknown);
void MAPINotification_jniCallUpdatedMethod(LPSTR iUnknown);
LONG
STDAPICALLTYPE MAPINotification_onNotify
(LPVOID lpvContext, ULONG cNotifications, LPNOTIFICATION lpNotifications);
void
MAPINotification_registerNotificationsDelegate
(JNIEnv *jniEnv, LPMAPISESSION, jobject);
MAPINotification_registerJniNotificationsDelegate
(JNIEnv *jniEnv, jobject notificationsDelegate);
void
MAPINotification_registerNativeNotificationsDelegate
(void * deletedMethod, void * insertedMethod, void *updatedMethod);
void MAPINotification_registerNotifyAllMsgStores(LPMAPISESSION mapiSession);
ULONG MAPINotification_registerNotifyMessageDataBase (LPMDB iUnknown);
void MAPINotification_unregisterJniNotificationsDelegate(JNIEnv *jniEnv);
void MAPINotification_unregisterNativeNotificationsDelegate();
void MAPINotification_unregisterNotifyAllMsgStores(void);
void MAPINotification_unregisterNotificationsDelegate (JNIEnv *jniEnv);
#ifdef __cplusplus
}

@ -0,0 +1,32 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKADDRBOOKCONTACTQUERY_H_
#define _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKADDRBOOKCONTACTQUERY_H_
int MsOutlookAddrBookContactQuery_IMAPIProp_1DeleteProp
(long propId, const char * nativeEntryId);
long MsOutlookAddrBookContactQuery_IMAPIProp_1GetProps(
const char* nativeEntryId,
int propIdCount,
long * propIds,
long flags,
void ** props,
unsigned long* propsLength,
char * propsType);
int MsOutlookAddrBookContactQuery_IMAPIProp_1SetPropString
(long propId, const char* nativeValue, const char* nativeEntryId);
char* MsOutlookAddrBookContactQuery_createContact(void);
int MsOutlookAddrBookContactQuery_deleteContact(const char * nativeEntryId);
void MsOutlookAddrBookContactQuery_foreachMailUser
(const char * query, void * callback, void * callbackObject);
#endif

@ -0,0 +1,696 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "MsOutlookAddrBookContactSourceService.h"
#include "com/ComClient.h"
#include "MAPINotification.h"
#include "MAPISession.h"
#include "MAPIBitness.h"
#include <Tchar.h>
typedef BOOL (STDAPICALLTYPE *LPFBINFROMHEX)(LPSTR, LPBYTE);
typedef void (STDAPICALLTYPE *LPFREEPROWS)(LPSRowSet);
typedef void (STDAPICALLTYPE *LPHEXFROMBIN)(LPBYTE, int, LPSTR);
typedef HRESULT (STDAPICALLTYPE *LPHRALLOCADVISESINK)(LPNOTIFCALLBACK, LPVOID, LPMAPIADVISESINK FAR *);
typedef HRESULT (STDAPICALLTYPE *LPHRQUERYALLROWS)(LPMAPITABLE, LPSPropTagArray,
LPSRestriction, LPSSortOrderSet, LONG, LPSRowSet FAR *);
static HANDLE MsOutlookAddrBookContactSourceService_comServerHandle = NULL;
static LPFBINFROMHEX MsOutlookAddrBookContactSourceService_fBinFromHex;
static LPFREEPROWS MsOutlookAddrBookContactSourceService_freeProws;
static LPHEXFROMBIN MsOutlookAddrBookContactSourceService_hexFromBin;
static LPHRALLOCADVISESINK MsOutlookAddrBookContactSourceService_hrAllocAdviseSink;
static LPHRQUERYALLROWS MsOutlookAddrBookContactSourceService_hrQueryAllRows;
static LPMAPIALLOCATEBUFFER
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer;
static LPMAPIFREEBUFFER MsOutlookAddrBookContactSourceService_mapiFreeBuffer;
static LPMAPIINITIALIZE MsOutlookAddrBookContactSourceService_mapiInitialize;
static LPMAPILOGONEX MsOutlookAddrBookContactSourceService_mapiLogonEx;
static LPMAPIUNINITIALIZE
MsOutlookAddrBookContactSourceService_mapiUninitialize;
static HMODULE MsOutlookAddrBookContactSourceService_hMapiLib = NULL;
static jboolean
MsOutlookAddrBookContactSourceService_isValidDefaultMailClient
(LPCTSTR name, DWORD nameLength);
HRESULT MsOutlookAddrBookContactSourceService_MAPIInitialize
(jlong version, jlong flags)
{
HKEY regKey;
HRESULT hResult = MAPI_E_NO_SUPPORT;
/*
* In the absence of a default e-mail program, MAPIInitialize may show a
* dialog to notify of the fact. The dialog is undesirable here. Because we
* implement ContactSourceService for Microsoft Outlook, we will try to
* mitigate the problem by implementing an ad-hoc check whether Microsoft
* Outlook is installed.
*/
if (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\Office"),
0,
KEY_ENUMERATE_SUB_KEYS,
&regKey))
{
DWORD i = 0;
TCHAR installRootKeyName[
255 // The size limit of key name as documented in MSDN
+ 20 // \Outlook\InstallRoot
+ 1]; // The terminating null character
while (1)
{
LONG regEnumKeyEx;
DWORD subkeyNameLength = 255 + 1;
LPTSTR str;
HKEY installRootKey;
DWORD pathValueType;
DWORD pathValueSize;
regEnumKeyEx
= RegEnumKeyEx(
regKey,
i,
installRootKeyName, &subkeyNameLength,
NULL,
NULL, NULL,
NULL);
if (ERROR_NO_MORE_ITEMS == regEnumKeyEx)
break;
i++;
if (ERROR_SUCCESS != regEnumKeyEx)
continue;
str = installRootKeyName + subkeyNameLength;
memcpy(str, _T("\\Outlook\\InstallRoot"), 20 * sizeof(TCHAR));
*(str + 20) = 0;
if (ERROR_SUCCESS
== RegOpenKeyEx(
regKey,
installRootKeyName,
0,
KEY_QUERY_VALUE,
&installRootKey))
{
if ((ERROR_SUCCESS
== RegQueryValueEx(
installRootKey,
_T("Path"),
NULL,
&pathValueType,
NULL, &pathValueSize))
&& (REG_SZ == pathValueType)
&& pathValueSize)
{
LPTSTR pathValue;
// MSDN says "the string may not have been stored with the
// proper terminating null characters."
pathValueSize
+= sizeof(TCHAR)
* (12 // \Outlook.exe
+ 1); // The terminating null character
if (pathValueSize <= sizeof(installRootKeyName))
pathValue = installRootKeyName;
else
{
pathValue = (LPTSTR)::malloc(pathValueSize);
if (!pathValue)
continue;
}
if (ERROR_SUCCESS
== RegQueryValueEx(
installRootKey,
_T("Path"),
NULL,
NULL,
(LPBYTE) pathValue, &pathValueSize))
{
DWORD pathValueLength = pathValueSize / sizeof(TCHAR);
if (pathValueLength)
{
DWORD fileAttributes;
str = pathValue + (pathValueLength - 1);
if (*str)
str++;
memcpy(str, _T("\\Outlook.exe"), 12 * sizeof(TCHAR));
*(str + 12) = 0;
fileAttributes = GetFileAttributes(pathValue);
if (INVALID_FILE_ATTRIBUTES != fileAttributes)
hResult = S_OK;
}
}
if (pathValue != installRootKeyName)
free(pathValue);
}
RegCloseKey(installRootKey);
}
}
RegCloseKey(regKey);
// Make sure that Microsoft Outlook is the default mail client in order
// to prevent its dialog in the case of it not being the default mail
// client.
if (HR_SUCCEEDED(hResult))
{
DWORD defaultValueType;
// The buffer installRootKeyName is long enough to receive
// "Microsoft Outlook" so use it in order to not have to allocate
// more memory.
LPTSTR defaultValue = (LPTSTR) installRootKeyName;
DWORD defaultValueCapacity = sizeof(installRootKeyName);
jboolean checkHKeyLocalMachine;
hResult = MAPI_E_NO_SUPPORT;
if (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_CURRENT_USER,
_T("Software\\Clients\\Mail"),
0,
KEY_QUERY_VALUE,
&regKey))
{
DWORD defaultValueSize = defaultValueCapacity;
LONG regQueryValueEx
= RegQueryValueEx(
regKey,
NULL,
NULL,
&defaultValueType,
(LPBYTE) defaultValue, &defaultValueSize);
switch (regQueryValueEx)
{
case ERROR_SUCCESS:
{
if (REG_SZ == defaultValueType)
{
DWORD defaultValueLength
= defaultValueSize / sizeof(TCHAR);
if (JNI_TRUE
== MsOutlookAddrBookContactSourceService_isValidDefaultMailClient(
defaultValue,
defaultValueLength))
{
checkHKeyLocalMachine = JNI_FALSE;
if (_tcsnicmp(
_T("Microsoft Outlook"), defaultValue,
defaultValueLength)
== 0)
hResult = S_OK;
}
else
checkHKeyLocalMachine = JNI_TRUE;
}
else
checkHKeyLocalMachine = JNI_FALSE;
break;
}
case ERROR_FILE_NOT_FOUND:
checkHKeyLocalMachine = JNI_TRUE;
break;
case ERROR_MORE_DATA:
checkHKeyLocalMachine = JNI_FALSE;
break;
default:
checkHKeyLocalMachine = JNI_FALSE;
break;
}
RegCloseKey(regKey);
}
else
checkHKeyLocalMachine = JNI_TRUE;
if ((JNI_TRUE == checkHKeyLocalMachine)
&& (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("Software\\Clients\\Mail"),
0,
KEY_QUERY_VALUE,
&regKey)))
{
DWORD defaultValueSize = defaultValueCapacity;
LONG regQueryValueEx
= RegQueryValueEx(
regKey,
NULL,
NULL,
&defaultValueType,
(LPBYTE) defaultValue, &defaultValueSize);
if ((ERROR_SUCCESS == regQueryValueEx)
&& (REG_SZ == defaultValueType))
{
DWORD defaultValueLength = defaultValueSize / sizeof(TCHAR);
if ((_tcsnicmp(
_T("Microsoft Outlook"), defaultValue,
defaultValueLength)
== 0)
&& (JNI_TRUE
== MsOutlookAddrBookContactSourceService_isValidDefaultMailClient(_T("Microsoft Outlook"), 17)))
hResult = S_OK;
}
RegCloseKey(regKey);
}
}
}
// If we've determined that we'd like to go on with MAPI, try to load it.
if (HR_SUCCEEDED(hResult))
{
MsOutlookAddrBookContactSourceService_hMapiLib
= ::LoadLibrary(_T("mapi32.dll"));
hResult = MAPI_E_NO_SUPPORT;
if(MsOutlookAddrBookContactSourceService_hMapiLib)
{
// get and check function pointers
MsOutlookAddrBookContactSourceService_mapiInitialize
= (LPMAPIINITIALIZE) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"MAPIInitialize");
MsOutlookAddrBookContactSourceService_mapiUninitialize
= (LPMAPIUNINITIALIZE) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"MAPIUninitialize");
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer
= (LPMAPIALLOCATEBUFFER) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"MAPIAllocateBuffer");
MsOutlookAddrBookContactSourceService_mapiFreeBuffer
= (LPMAPIFREEBUFFER) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"MAPIFreeBuffer");
MsOutlookAddrBookContactSourceService_mapiLogonEx
= (LPMAPILOGONEX) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"MAPILogonEx");
// Depending on mapi32.dll version the following functions must be
// loaded with or without "...@#".
MsOutlookAddrBookContactSourceService_fBinFromHex
= (LPFBINFROMHEX) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"FBinFromHex");
if(MsOutlookAddrBookContactSourceService_fBinFromHex == NULL)
{
MsOutlookAddrBookContactSourceService_fBinFromHex
= (LPFBINFROMHEX) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"FBinFromHex@8");
}
MsOutlookAddrBookContactSourceService_freeProws
= (LPFREEPROWS) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"FreeProws");
if(MsOutlookAddrBookContactSourceService_freeProws == NULL)
{
MsOutlookAddrBookContactSourceService_freeProws
= (LPFREEPROWS) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"FreeProws@4");
}
MsOutlookAddrBookContactSourceService_hexFromBin
= (LPHEXFROMBIN) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"HexFromBin");
if(MsOutlookAddrBookContactSourceService_hexFromBin == NULL)
{
MsOutlookAddrBookContactSourceService_hexFromBin
= (LPHEXFROMBIN) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"HexFromBin@12");
}
MsOutlookAddrBookContactSourceService_hrAllocAdviseSink
= (LPHRALLOCADVISESINK)
GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"HrAllocAdviseSink");
if(MsOutlookAddrBookContactSourceService_hrAllocAdviseSink == NULL)
{
MsOutlookAddrBookContactSourceService_hrAllocAdviseSink
= (LPHRALLOCADVISESINK)
GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"HrAllocAdviseSink@12");
}
MsOutlookAddrBookContactSourceService_hrQueryAllRows
= (LPHRQUERYALLROWS) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"HrQueryAllRows");
if(MsOutlookAddrBookContactSourceService_hrQueryAllRows == NULL)
{
MsOutlookAddrBookContactSourceService_hrQueryAllRows
= (LPHRQUERYALLROWS) GetProcAddress(
MsOutlookAddrBookContactSourceService_hMapiLib,
"HrQueryAllRows@24");
}
if (MsOutlookAddrBookContactSourceService_mapiInitialize
&& MsOutlookAddrBookContactSourceService_mapiUninitialize
&& MsOutlookAddrBookContactSourceService_mapiAllocateBuffer
&& MsOutlookAddrBookContactSourceService_mapiFreeBuffer
&& MsOutlookAddrBookContactSourceService_mapiLogonEx
&& MsOutlookAddrBookContactSourceService_fBinFromHex
&& MsOutlookAddrBookContactSourceService_freeProws
&& MsOutlookAddrBookContactSourceService_hexFromBin
&& MsOutlookAddrBookContactSourceService_hrAllocAdviseSink
&& MsOutlookAddrBookContactSourceService_hrQueryAllRows)
{
MAPIINIT_0 mapiInit = { (ULONG) version, (ULONG) flags };
// Opening MAPI changes the working directory. Make a backup of
// the current directory, login to MAPI and restore it
DWORD dwSize = ::GetCurrentDirectory(0, NULL);
if (dwSize > 0)
{
LPTSTR lpszWorkingDir
= (LPTSTR)::malloc(dwSize*sizeof(TCHAR));
DWORD dwResult
= ::GetCurrentDirectory(dwSize, lpszWorkingDir);
if (dwResult != 0)
{
MAPISession_lock();
hResult
= MsOutlookAddrBookContactSourceService_mapiInitialize(
&mapiInit);
if(HR_SUCCEEDED(hResult)
&& MAPISession_getMapiSession() == NULL)
{
LPMAPISESSION mapiSession = NULL;
hResult = MsOutlookAddrBook_mapiLogonEx(
0,
NULL, NULL,
MAPI_EXTENDED
| MAPI_NO_MAIL
| MAPI_USE_DEFAULT,
&mapiSession);
// Register the notification of contact changed,
// created and deleted.
MAPINotification_registerNotifyAllMsgStores(
mapiSession);
}
::SetCurrentDirectory(lpszWorkingDir);
MAPISession_unlock();
}
else
{
hResult = HRESULT_FROM_WIN32(::GetLastError());
}
::free(lpszWorkingDir);
}
else
{
hResult = HRESULT_FROM_WIN32(::GetLastError());
}
}
}
}
if (HR_FAILED(hResult))
{
if(MsOutlookAddrBookContactSourceService_hMapiLib)
{
FreeLibrary(MsOutlookAddrBookContactSourceService_hMapiLib);
MsOutlookAddrBookContactSourceService_hMapiLib = NULL;
}
}
return hResult;
}
/**
* Starts the COM server if the bitness of Jitsi is different from the Outlook
* one (mapi32.dll).
*
* @return S_OK if eveything was fine. E_FAIL otherwise.
*/
HRESULT MsOutlookAddrBookContactSourceService_MAPIInitializeCOMServer()
{
HRESULT hr = E_FAIL;
MAPISession_lock();
// Start COM service
char applicationName[] = "native/jmsoutlookaddrbookcomserver.exe";
int applicationNameLength = strlen(applicationName);
char currentDirectory[FILENAME_MAX - applicationNameLength];
GetCurrentDirectory(
FILENAME_MAX - applicationNameLength,
currentDirectory);
char comServer[FILENAME_MAX];
sprintf(comServer, "%s/%s", currentDirectory, applicationName);
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
memset(&startupInfo, 0, sizeof(startupInfo));
memset(&processInfo, 0, sizeof(processInfo));
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_HIDE;
// Create the COM server
if(CreateProcess(
NULL,
comServer,
NULL, NULL, false, 0, NULL, NULL,
&startupInfo,
&processInfo))
{
MsOutlookAddrBookContactSourceService_comServerHandle
= processInfo.hProcess;
hr = S_OK;
}
// Start COM client
ComClient_start();
MAPISession_unlock();
return hr;
}
void MsOutlookAddrBookContactSourceService_MAPIUninitialize(void)
{
MAPISession_lock();
if(MAPIBitness_isOutlookBitnessCompatible())
{
LPMAPISESSION mapiSession = MAPISession_getMapiSession();
if(mapiSession != NULL)
{
MAPINotification_unregisterNotifyAllMsgStores();
mapiSession->Logoff(0, 0, 0);
mapiSession->Release();
MAPISession_setMapiSession(NULL);
}
if(MsOutlookAddrBookContactSourceService_hMapiLib)
{
MsOutlookAddrBookContactSourceService_mapiUninitialize();
MsOutlookAddrBookContactSourceService_mapiInitialize = NULL;
MsOutlookAddrBookContactSourceService_mapiUninitialize = NULL;
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer = NULL;
MsOutlookAddrBookContactSourceService_mapiFreeBuffer = NULL;
MsOutlookAddrBookContactSourceService_mapiLogonEx = NULL;
MsOutlookAddrBookContactSourceService_fBinFromHex = NULL;
MsOutlookAddrBookContactSourceService_freeProws = NULL;
MsOutlookAddrBookContactSourceService_hexFromBin = NULL;
MsOutlookAddrBookContactSourceService_hrAllocAdviseSink = NULL;
MsOutlookAddrBookContactSourceService_hrQueryAllRows = NULL;
::FreeLibrary(MsOutlookAddrBookContactSourceService_hMapiLib);
MsOutlookAddrBookContactSourceService_hMapiLib = NULL;
}
}
else
{
if(MsOutlookAddrBookContactSourceService_comServerHandle != NULL)
{
TerminateProcess(
MsOutlookAddrBookContactSourceService_comServerHandle,
1);
CloseHandle(MsOutlookAddrBookContactSourceService_comServerHandle);
MsOutlookAddrBookContactSourceService_comServerHandle = NULL;
}
ComClient_stop();
}
MAPISession_unlock();
}
/**
* Initializes the plugin but from the COM server point of view: natif side, no
* java available here.
*
* @param version The version of MAPI to load.
* @param flags The option choosen to load the MAPI to lib.
* @param deletedMethod A function pointer used as a callback on notification
* from outlook when a contact has been removed.
* @param insertedMethod A function pointer used as a callback on notification
* from outlook when a contact has been added.
* @param updatedMethod A function pointer used as a callback on notification
* from outlook when a contact has been modified.
*
* @return S_OK if everything was alright.
*/
HRESULT MsOutlookAddrBookContactSourceService_NativeMAPIInitialize
(jlong version, jlong flags,
void * deletedMethod, void * insertedMethod, void * updatedMethod)
{
MAPINotification_registerNativeNotificationsDelegate(
deletedMethod, insertedMethod, updatedMethod);
return MsOutlookAddrBookContactSourceService_MAPIInitialize(version, flags);
}
void MsOutlookAddrBookContactSourceService_NativeMAPIUninitialize()
{
MAPINotification_unregisterNativeNotificationsDelegate();
MsOutlookAddrBookContactSourceService_MAPIUninitialize();
}
static jboolean
MsOutlookAddrBookContactSourceService_isValidDefaultMailClient
(LPCTSTR name, DWORD nameLength)
{
jboolean validDefaultMailClient = JNI_FALSE;
if ((0 != nameLength) && (0 != name[0]))
{
LPTSTR str;
TCHAR keyName[
22 /* Software\Clients\Mail\ */
+ 255
+ 1 /* The terminating null character */];
HKEY key;
str = keyName;
_tcsncpy(str, _T("Software\\Clients\\Mail\\"), 22);
str += 22;
if (nameLength > 255)
nameLength = 255;
_tcsncpy(str, name, nameLength);
*(str + nameLength) = 0;
if (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
keyName,
0,
KEY_QUERY_VALUE,
&key))
{
validDefaultMailClient = JNI_TRUE;
RegCloseKey(key);
}
}
return validDefaultMailClient;
}
BOOL MsOutlookAddrBook_fBinFromHex(LPSTR lpsz, LPBYTE lpb)
{
return MsOutlookAddrBookContactSourceService_fBinFromHex(lpsz, lpb);
}
void MsOutlookAddrBook_freeProws(LPSRowSet lpRows)
{
MsOutlookAddrBookContactSourceService_freeProws(lpRows);
}
void MsOutlookAddrBook_hexFromBin(LPBYTE pb, int cb, LPSTR sz)
{
MsOutlookAddrBookContactSourceService_hexFromBin(pb, cb, sz);
}
void
MsOutlookAddrBook_hrAllocAdviseSink
(LPNOTIFCALLBACK lpfnCallback, LPVOID lpvContext, LPMAPIADVISESINK*
lppAdviseSink)
{
MsOutlookAddrBookContactSourceService_hrAllocAdviseSink(
lpfnCallback,
lpvContext,
lppAdviseSink);
}
HRESULT
MsOutlookAddrBook_hrQueryAllRows
(LPMAPITABLE lpTable, LPSPropTagArray lpPropTags,
LPSRestriction lpRestriction, LPSSortOrderSet lpSortOrderSet,
LONG crowsMax, LPSRowSet* lppRows)
{
return MsOutlookAddrBookContactSourceService_hrQueryAllRows(
lpTable,
lpPropTags,
lpRestriction,
lpSortOrderSet,
crowsMax,
lppRows);
}
SCODE
MsOutlookAddrBook_mapiAllocateBuffer(ULONG size, LPVOID FAR *buffer)
{
return
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer(size, buffer);
}
ULONG
MsOutlookAddrBook_mapiFreeBuffer(LPVOID buffer)
{
return MsOutlookAddrBookContactSourceService_mapiFreeBuffer(buffer);
}
HRESULT
MsOutlookAddrBook_mapiLogonEx
(ULONG_PTR uiParam,
LPTSTR profileName, LPTSTR password,
FLAGS flags,
LPMAPISESSION FAR *mapiSession)
{
HRESULT hResult;
MAPISession_lock();
LPMAPISESSION currentMapiSession = MAPISession_getMapiSession();
if (currentMapiSession != NULL)
hResult = S_OK;
else
{
hResult
= MsOutlookAddrBookContactSourceService_mapiLogonEx(
uiParam,
profileName, password,
flags,
&currentMapiSession);
MAPISession_setMapiSession(currentMapiSession);
}
if (HR_SUCCEEDED(hResult))
{
*mapiSession = currentMapiSession;
}
MAPISession_unlock();
return hResult;
}

@ -4,28 +4,10 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKADDRBOOKCONTACTSOURCESERVICE_H_
#define _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKADDRBOOKCONTACTSOURCESERVICE_H_
#ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKMAPI_H_
#define _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKMAPI_H_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifndef __in
#define __in
#endif /* #ifndef __in */
#ifndef __in_opt
#define __in_opt
#endif /* #ifndef __in_opt */
#ifndef __out
#define __out
#endif /* #ifndef __out */
#if defined(_WINBASE_H) && !defined(_WINBASE_)
#define _tagCY_DEFINED
#define _WINBASE_
#endif
#include <mapitags.h>
#include <jni.h>
#include <mapix.h>
BOOL MsOutlookAddrBook_fBinFromHex(LPSTR lpsz, LPBYTE lpb);
@ -61,4 +43,18 @@ HRESULT MsOutlookAddrBook_mapiLogonEx
LPMAPISESSION FAR *mapiSession);
#define MAPILogonEx MsOutlookAddrBook_mapiLogonEx
#endif /* #ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKMAPI_H_ */
HRESULT MsOutlookAddrBookContactSourceService_MAPIInitialize
(jlong version, jlong flags);
HRESULT MsOutlookAddrBookContactSourceService_MAPIInitializeCOMServer();
void MsOutlookAddrBookContactSourceService_MAPIUninitialize(void);
HRESULT MsOutlookAddrBookContactSourceService_NativeMAPIInitialize
(jlong version, jlong flags,
void * deletedMethod, void * insertedMethod, void * updatedMethod);
void MsOutlookAddrBookContactSourceService_NativeMAPIUninitialize();
#endif

@ -8,8 +8,8 @@
#ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKMAPIHRESULTEXCEPTION_H_
#define _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_MSOUTLOOKMAPIHRESULTEXCEPTION_H_
#include "MsOutlookMAPI.h"
#include <jni.h>
#include <Mapix.h>
#include <tchar.h>
#ifdef __cplusplus

@ -0,0 +1,54 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "StringUtils.h"
LPWSTR StringUtils::MultiByteToWideChar(LPCSTR str)
{
int wsize = ::MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
LPWSTR wstr;
if (wsize)
{
wstr = (LPWSTR) ::malloc(wsize * sizeof(WCHAR));
if (str && !::MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, wsize))
{
::free(wstr);
wstr = NULL;
}
}
else
wstr = NULL;
return wstr;
}
LPSTR StringUtils::WideCharToMultiByte(LPCWSTR wstr)
{
int size = ::WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
LPSTR str;
if (size)
{
str = (LPSTR) ::malloc(size);
if (str
&& !::WideCharToMultiByte(
CP_ACP,
0,
wstr,
-1,
str,
size,
NULL,
NULL))
{
::free(str);
str = NULL;
}
}
else
str = NULL;
return str;
}

@ -0,0 +1,20 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_STRINGUTILS_H_
#define _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_MSOUTLOOK_STRINGUTILS_H_
#include <tchar.h>
#include <windows.h>
class StringUtils
{
public:
static LPWSTR MultiByteToWideChar(LPCSTR str);
static LPSTR WideCharToMultiByte(LPCWSTR wstr);
};
#endif

@ -0,0 +1,138 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "ClassFactory.h"
#include <stdio.h>
/**
* Represents a base implementation of the <tt>IClassFactory</tt> interface.
*
* @author Lyubomir Marinov
* @author Vincent Lucas
*/
/**
* Returns an instance of the interface requested, if available.
*
* @param iid The identifier of the interface requested.
* @param obj A pointer use to return an object instance implementing the
* interface requested.
*
* @return S_OK if the corresponding interface has been found. E_POINTER, or
* E_NOINTERFACE otherwise.
*/
STDMETHODIMP ClassFactory::QueryInterface(REFIID iid, PVOID *obj)
{
HRESULT hr;
if(!obj)
{
hr = E_POINTER;
}
else if(IID_IUnknown == iid)
{
AddRef();
*obj = static_cast<LPUNKNOWN>(this);
hr = S_OK;
}
else if(IID_IClassFactory == iid)
{
AddRef();
*obj = static_cast<IClassFactory *>(this);
hr = S_OK;
}
else
{
*obj = NULL;
hr = E_NOINTERFACE;
}
return hr;
}
/**
* Increment the number of reference.
*
* @return The number of reference.
*/
STDMETHODIMP_(ULONG) ClassFactory::AddRef()
{
return ++_refCount;
}
/**
* Decrement the number of reference.
*
* @return The number of reference.
*/
STDMETHODIMP_(ULONG) ClassFactory::Release()
{
ULONG refCount = --_refCount;
if(!refCount)
{
delete this;
}
return refCount;
}
/**
* Unused.
*/
HRESULT ClassFactory::LockServer(BOOL lock)
{
return S_OK;
};
/**
* Register the CLISD of the implementer of this ClassFactory.
*
* @return S_OK if the class object was registered successfully. Any other value
* if fail.
*/
HRESULT ClassFactory::registerClassObject()
{
return
::CoRegisterClassObject(
_clsid,
this,
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED,
&_registration);
};
/**
* Unregister the CLISD of the implementer of this ClassFactory.
*
* @return S_OK the class object was revoked successfully. Any other value if
* fail.
*/
HRESULT ClassFactory::revokeClassObject()
{
return ::CoRevokeClassObject(_registration);
};
/**
* Instanciates this class factory for a given CLSID.
*
* @param clsid The CLSID to manage.
*/
ClassFactory::ClassFactory(REFCLSID clsid):
_clsid(clsid),
_registration(0),
_refCount(1)
{
};
/**
* Deletes this class factory.
*/
ClassFactory::~ClassFactory()
{
Release();
};

@ -0,0 +1,42 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef __MSOUTLOOKADDRBOOKCOM_CLASSFACTORY_H
#define __MSOUTLOOKADDRBOOKCOM_CLASSFACTORY_H
#include <Unknwn.h>
/**
* Represents a base implementation of the <tt>IClassFactory</tt> interface.
*
* @author Lyubomir Marinov
* @author Vincent Lucas
*/
class ClassFactory:
public IClassFactory
{
public:
STDMETHODIMP QueryInterface(REFIID iid, PVOID *obj);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHOD(LockServer)(BOOL lock);
HRESULT registerClassObject();
HRESULT revokeClassObject();
ClassFactory(REFCLSID clsid);
protected:
virtual ~ClassFactory();
private:
const CLSID _clsid;
DWORD _registration;
ULONG _refCount;
};
#endif

@ -0,0 +1,112 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "ComClient.h"
#include "../MAPIBitness.h"
#include "MsOutlookAddrBookServerClassFactory.h"
#include "MsOutlookAddrBookClientClassFactory.h"
#include "TypeLib.h"
#include <process.h>
#include <stdio.h>
/**
* Starts and stops registration for the COM client.
*
* @author Vincent Lucas
*/
/**
* A pointer to the COM server interface to make remote MAPI requests.
*/
static IMsOutlookAddrBookServer * ComClient_iServer = NULL;
/**
* The class factory of the COM client activated when the client type library is
* registered.
*/
static ClassFactory * ComClient_classFactory = NULL;
/**
* The client type library.
*/
static LPTYPELIB ComClient_typeLib = NULL;
/**
* Initializes the COM client.
*/
void ComClient_start(void)
{
HRESULT hr = E_FAIL;
if(CoInitializeEx(NULL, COINIT_MULTITHREADED) == S_OK)
{
// The server may be long to start, then retry 10 times with 1s pause
// between each try.
int retry = 10;
while(retry > 0)
{
if((hr = CoCreateInstance(
CLSID_MsOutlookAddrBookServer,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IMsOutlookAddrBookServer,
(void**) &ComClient_iServer)) == S_OK)
{
WCHAR * path = (WCHAR*) L"IMsOutlookAddrBookClient.tlb";
ComClient_typeLib = TypeLib_loadRegTypeLib(path);
ClassFactory *ComClient_classFactory
= new MsOutlookAddrBookClientClassFactory();
if(ComClient_classFactory->registerClassObject() != S_OK)
{
ComClient_classFactory->Release();
ComClient_classFactory = NULL;
}
::CoResumeClassObjects();
retry = 0;
}
Sleep(1000);
--retry;
}
}
}
/**
* Uninitializes the COM client.
*/
void ComClient_stop(void)
{
if(ComClient_iServer)
{
ComClient_iServer->Release();
ComClient_iServer = NULL;
}
::CoSuspendClassObjects();
if(ComClient_classFactory)
{
ComClient_classFactory->Release();
ComClient_classFactory = NULL;
}
if(ComClient_typeLib)
{
TypeLib_releaseTypeLib(ComClient_typeLib);
ComClient_typeLib = NULL;
}
}
/**
* A pointer to the COM server interface to make remote MAPI requests.
*/
IMsOutlookAddrBookServer * ComClient_getIServer()
{
return ComClient_iServer;
}

@ -0,0 +1,22 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef __MSOUTLOOKADDRBOOKCOM_COMCLIENT_H
#define __MSOUTLOOKADDRBOOKCOM_COMCLIENT_H
#include "IMsOutlookAddrBookServer.h"
/**
* Starts and stops registration for the COM client.
*
* @author Vincent Lucas
*/
void ComClient_start(void);
void ComClient_stop(void);
IMsOutlookAddrBookServer * ComClient_getIServer();
#endif

@ -0,0 +1,208 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 8.00.0595 */
/* at Tue May 07 03:41:40 2013
*/
/* Compiler settings for IMsOutlookAddrBookClient.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
//#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
#ifndef __IMsOutlookAddrBookClient_h__
#define __IMsOutlookAddrBookClient_h__
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
/* Forward Declarations */
#ifndef __IMsOutlookAddrBookClient_FWD_DEFINED__
#define __IMsOutlookAddrBookClient_FWD_DEFINED__
typedef interface IMsOutlookAddrBookClient IMsOutlookAddrBookClient;
#endif /* __IMsOutlookAddrBookClient_FWD_DEFINED__ */
#ifndef __IMsOutlookAddrBookClient_FWD_DEFINED__
#define __IMsOutlookAddrBookClient_FWD_DEFINED__
typedef interface IMsOutlookAddrBookClient IMsOutlookAddrBookClient;
#endif /* __IMsOutlookAddrBookClient_FWD_DEFINED__ */
/* header files for imported files */
#include "Unknwn.h"
#include "oaidl.h"
#ifdef __cplusplus
extern "C"{
#endif
#ifndef __IMsOutlookAddrBookClient_INTERFACE_DEFINED__
#define __IMsOutlookAddrBookClient_INTERFACE_DEFINED__
/* interface IMsOutlookAddrBookClient */
/* [oleautomation][dual][uuid][object] */
EXTERN_C const IID IID_IMsOutlookAddrBookClient;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("D579E840-B1A6-11E2-9E96-0800200C9A66")
IMsOutlookAddrBookClient : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE foreachMailUserCallback(
/* [in] */ BSTR id) = 0;
virtual HRESULT STDMETHODCALLTYPE deleted(
/* [in] */ BSTR id) = 0;
virtual HRESULT STDMETHODCALLTYPE inserted(
/* [in] */ BSTR id) = 0;
virtual HRESULT STDMETHODCALLTYPE updated(
/* [in] */ BSTR id) = 0;
};
#else /* C style interface */
typedef struct IMsOutlookAddrBookClientVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMsOutlookAddrBookClient * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMsOutlookAddrBookClient * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMsOutlookAddrBookClient * This);
HRESULT ( STDMETHODCALLTYPE *foreachMailUserCallback )(
IMsOutlookAddrBookClient * This,
/* [in] */ BSTR id);
HRESULT ( STDMETHODCALLTYPE *deleted )(
IMsOutlookAddrBookClient * This,
/* [in] */ BSTR id);
HRESULT ( STDMETHODCALLTYPE *inserted )(
IMsOutlookAddrBookClient * This,
/* [in] */ BSTR id);
HRESULT ( STDMETHODCALLTYPE *updated )(
IMsOutlookAddrBookClient * This,
/* [in] */ BSTR id);
END_INTERFACE
} IMsOutlookAddrBookClientVtbl;
interface IMsOutlookAddrBookClient
{
CONST_VTBL struct IMsOutlookAddrBookClientVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMsOutlookAddrBookClient_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMsOutlookAddrBookClient_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMsOutlookAddrBookClient_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMsOutlookAddrBookClient_foreachMailUserCallback(This,id) \
( (This)->lpVtbl -> foreachMailUserCallback(This,id) )
#define IMsOutlookAddrBookClient_deleted(This,id) \
( (This)->lpVtbl -> deleted(This,id) )
#define IMsOutlookAddrBookClient_inserted(This,id) \
( (This)->lpVtbl -> inserted(This,id) )
#define IMsOutlookAddrBookClient_updated(This,id) \
( (This)->lpVtbl -> updated(This,id) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMsOutlookAddrBookClient_INTERFACE_DEFINED__ */
#ifndef __IMsOutlookAddrBookClientTypeLib_LIBRARY_DEFINED__
#define __IMsOutlookAddrBookClientTypeLib_LIBRARY_DEFINED__
/* library IMsOutlookAddrBookClientTypeLib */
/* [helpstring][version][uuid] */
EXTERN_C const IID LIBID_IMsOutlookAddrBookClientTypeLib;
#endif /* __IMsOutlookAddrBookClientTypeLib_LIBRARY_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
unsigned long __RPC_USER BSTR_UserSize( unsigned long *, unsigned long , BSTR * );
unsigned char * __RPC_USER BSTR_UserMarshal( unsigned long *, unsigned char *, BSTR * );
unsigned char * __RPC_USER BSTR_UserUnmarshal(unsigned long *, unsigned char *, BSTR * );
void __RPC_USER BSTR_UserFree( unsigned long *, BSTR * );
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,35 @@
import "Unknwn.idl", "oaidl.idl";
[
object,
uuid(D579E840-B1A6-11E2-9E96-0800200C9A66),
dual,
oleautomation
]
interface IMsOutlookAddrBookClient : IUnknown
{
HRESULT foreachMailUserCallback(
[in] BSTR id);
HRESULT deleted(
[in] BSTR id);
HRESULT inserted(
[in] BSTR id);
HRESULT updated(
[in] BSTR id);
};
[
uuid(e361a5b0-b1c4-11e2-9e96-0800200c9a66),
version(1.0),
helpstring("IMsOutlookAddrBookClient Type Library"),
]
library IMsOutlookAddrBookClientTypeLib
{
importlib("stdole32.tlb");
interface IMsOutlookAddrBookClient;
};

@ -0,0 +1,251 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 8.00.0595 */
/* at Tue May 07 03:41:42 2013
*/
/* Compiler settings for IMsOutlookAddrBookServer.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
//#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
#ifndef __IMsOutlookAddrBookServer_h__
#define __IMsOutlookAddrBookServer_h__
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
/* Forward Declarations */
#ifndef __IMsOutlookAddrBookServer_FWD_DEFINED__
#define __IMsOutlookAddrBookServer_FWD_DEFINED__
typedef interface IMsOutlookAddrBookServer IMsOutlookAddrBookServer;
#endif /* __IMsOutlookAddrBookServer_FWD_DEFINED__ */
#ifndef __IMsOutlookAddrBookServer_FWD_DEFINED__
#define __IMsOutlookAddrBookServer_FWD_DEFINED__
typedef interface IMsOutlookAddrBookServer IMsOutlookAddrBookServer;
#endif /* __IMsOutlookAddrBookServer_FWD_DEFINED__ */
/* header files for imported files */
#include "Unknwn.h"
#include "oaidl.h"
#ifdef __cplusplus
extern "C"{
#endif
#ifndef __IMsOutlookAddrBookServer_INTERFACE_DEFINED__
#define __IMsOutlookAddrBookServer_INTERFACE_DEFINED__
/* interface IMsOutlookAddrBookServer */
/* [oleautomation][dual][uuid][object] */
EXTERN_C const IID IID_IMsOutlookAddrBookServer;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("5DDE9FF0-AC48-11E2-9E96-0800200C9A66")
IMsOutlookAddrBookServer : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE foreachMailUser(
/* [in] */ BSTR query) = 0;
virtual HRESULT STDMETHODCALLTYPE IMAPIProp_GetProps(
/* [in] */ BSTR entryId,
/* [in] */ int nbPropIds,
/* [in] */ SAFEARRAY * propIds,
/* [in] */ long flags,
/* [out] */ SAFEARRAY * *props,
/* [out] */ SAFEARRAY * *propsLength,
/* [out] */ SAFEARRAY * *propsType) = 0;
virtual HRESULT STDMETHODCALLTYPE createContact(
/* [out] */ BSTR *id) = 0;
virtual HRESULT STDMETHODCALLTYPE deleteContact(
/* [in] */ BSTR id) = 0;
virtual HRESULT STDMETHODCALLTYPE IMAPIProp_DeleteProp(
/* [in] */ long propId,
/* [in] */ BSTR entryId) = 0;
virtual HRESULT STDMETHODCALLTYPE IMAPIProp_SetPropString(
/* [in] */ long propId,
/* [in] */ BSTR value,
/* [in] */ BSTR entryId) = 0;
};
#else /* C style interface */
typedef struct IMsOutlookAddrBookServerVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IMsOutlookAddrBookServer * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IMsOutlookAddrBookServer * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IMsOutlookAddrBookServer * This);
HRESULT ( STDMETHODCALLTYPE *foreachMailUser )(
IMsOutlookAddrBookServer * This,
/* [in] */ BSTR query);
HRESULT ( STDMETHODCALLTYPE *IMAPIProp_GetProps )(
IMsOutlookAddrBookServer * This,
/* [in] */ BSTR entryId,
/* [in] */ int nbPropIds,
/* [in] */ SAFEARRAY * propIds,
/* [in] */ long flags,
/* [out] */ SAFEARRAY * *props,
/* [out] */ SAFEARRAY * *propsLength,
/* [out] */ SAFEARRAY * *propsType);
HRESULT ( STDMETHODCALLTYPE *createContact )(
IMsOutlookAddrBookServer * This,
/* [out] */ BSTR *id);
HRESULT ( STDMETHODCALLTYPE *deleteContact )(
IMsOutlookAddrBookServer * This,
/* [in] */ BSTR id);
HRESULT ( STDMETHODCALLTYPE *IMAPIProp_DeleteProp )(
IMsOutlookAddrBookServer * This,
/* [in] */ long propId,
/* [in] */ BSTR entryId);
HRESULT ( STDMETHODCALLTYPE *IMAPIProp_SetPropString )(
IMsOutlookAddrBookServer * This,
/* [in] */ long propId,
/* [in] */ BSTR value,
/* [in] */ BSTR entryId);
END_INTERFACE
} IMsOutlookAddrBookServerVtbl;
interface IMsOutlookAddrBookServer
{
CONST_VTBL struct IMsOutlookAddrBookServerVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define IMsOutlookAddrBookServer_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define IMsOutlookAddrBookServer_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define IMsOutlookAddrBookServer_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define IMsOutlookAddrBookServer_foreachMailUser(This,query) \
( (This)->lpVtbl -> foreachMailUser(This,query) )
#define IMsOutlookAddrBookServer_IMAPIProp_GetProps(This,entryId,nbPropIds,propIds,flags,props,propsLength,propsType) \
( (This)->lpVtbl -> IMAPIProp_GetProps(This,entryId,nbPropIds,propIds,flags,props,propsLength,propsType) )
#define IMsOutlookAddrBookServer_createContact(This,id) \
( (This)->lpVtbl -> createContact(This,id) )
#define IMsOutlookAddrBookServer_deleteContact(This,id) \
( (This)->lpVtbl -> deleteContact(This,id) )
#define IMsOutlookAddrBookServer_IMAPIProp_DeleteProp(This,propId,entryId) \
( (This)->lpVtbl -> IMAPIProp_DeleteProp(This,propId,entryId) )
#define IMsOutlookAddrBookServer_IMAPIProp_SetPropString(This,propId,value,entryId) \
( (This)->lpVtbl -> IMAPIProp_SetPropString(This,propId,value,entryId) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __IMsOutlookAddrBookServer_INTERFACE_DEFINED__ */
#ifndef __IMsOutlookAddrBookServerTypeLib_LIBRARY_DEFINED__
#define __IMsOutlookAddrBookServerTypeLib_LIBRARY_DEFINED__
/* library IMsOutlookAddrBookServerTypeLib */
/* [helpstring][version][uuid] */
EXTERN_C const IID LIBID_IMsOutlookAddrBookServerTypeLib;
#endif /* __IMsOutlookAddrBookServerTypeLib_LIBRARY_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
unsigned long __RPC_USER BSTR_UserSize( unsigned long *, unsigned long , BSTR * );
unsigned char * __RPC_USER BSTR_UserMarshal( unsigned long *, unsigned char *, BSTR * );
unsigned char * __RPC_USER BSTR_UserUnmarshal(unsigned long *, unsigned char *, BSTR * );
void __RPC_USER BSTR_UserFree( unsigned long *, BSTR * );
unsigned long __RPC_USER LPSAFEARRAY_UserSize( unsigned long *, unsigned long , LPSAFEARRAY * );
unsigned char * __RPC_USER LPSAFEARRAY_UserMarshal( unsigned long *, unsigned char *, LPSAFEARRAY * );
unsigned char * __RPC_USER LPSAFEARRAY_UserUnmarshal(unsigned long *, unsigned char *, LPSAFEARRAY * );
void __RPC_USER LPSAFEARRAY_UserFree( unsigned long *, LPSAFEARRAY * );
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,53 @@
import "Unknwn.idl", "oaidl.idl";
[
object,
uuid(5DDE9FF0-AC48-11E2-9E96-0800200C9A66),
dual,
oleautomation
]
interface IMsOutlookAddrBookServer : IUnknown
{
HRESULT foreachMailUser(
[in] BSTR query);
HRESULT IMAPIProp_GetProps(
[in] BSTR entryId,
[in] int nbPropIds,
[in] SAFEARRAY(long) propIds,
[in] long flags,
[out] SAFEARRAY(byte) * props,
[out] SAFEARRAY(unsigned long) * propsLength,
[out] SAFEARRAY(byte) * propsType);
HRESULT createContact(
[out] BSTR * id);
HRESULT deleteContact(
[in] BSTR id);
HRESULT IMAPIProp_DeleteProp(
[in] long propId,
[in] BSTR entryId);
HRESULT IMAPIProp_SetPropString(
[in] long propId,
[in] BSTR value,
[in] BSTR entryId);
};
[
uuid(158586d0-acfa-11e2-9e96-0800200c9a66),
version(1.0),
helpstring("IMsOutlookAddrBookServer Type Library"),
]
library IMsOutlookAddrBookServerTypeLib
{
importlib("stdole32.tlb");
interface IMsOutlookAddrBookServer;
};

@ -0,0 +1,169 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "MsOutlookAddrBookClient.h"
#include <stdio.h>
#include <wchar.h>
#include "../MAPINotification.h"
#include "../net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.h"
#include "../StringUtils.h"
/**
* Instanciates a new MsOutlookAddrBookClient.
*/
MsOutlookAddrBookClient::MsOutlookAddrBookClient():
_refCount(1)
{
}
/**
* Deletes this MsOutlookAddrBookClient.
*/
MsOutlookAddrBookClient::~MsOutlookAddrBookClient()
{
Release();
}
/**
* Returns an instance of the interface requested, if available.
*
* @param iid The identifier of the interface requested.
* @param obj A pointer use to return an object instance implementing the
* interface requested.
*
* @return S_OK if the corresponding interface has been found. E_POINTER, or
* E_NOINTERFACE otherwise.
*/
STDMETHODIMP MsOutlookAddrBookClient::QueryInterface(REFIID iid, PVOID *obj)
{
OLECHAR* strGuid;
StringFromCLSID(iid, &strGuid);
::CoTaskMemFree(strGuid);
HRESULT hr;
if (!obj)
{
hr = E_POINTER;
}
else if (IID_IUnknown == iid)
{
AddRef();
*obj = static_cast<IUnknown *>(
static_cast<IMsOutlookAddrBookClient *>(this));
hr = S_OK;
}
else if (IID_IMsOutlookAddrBookClient == iid)
{
AddRef();
*obj = static_cast<IMsOutlookAddrBookClient *>(this);
hr = S_OK;
}
else
{
hr = E_NOINTERFACE;
}
return hr;
}
/**
* Increment the number of reference.
*
* @return The number of reference.
*/
STDMETHODIMP_(ULONG) MsOutlookAddrBookClient::AddRef()
{
return ++_refCount;
}
/**
* Decrement the number of reference.
*
* @return The number of reference.
*/
STDMETHODIMP_(ULONG) MsOutlookAddrBookClient::Release()
{
ULONG refCount = --_refCount;
if(!refCount)
{
delete this;
}
return refCount;
}
/**
* Callback which receives each time the COM server found a contact when making
* a search via the foreachMailUser function.
*
* @param id The contact identifier.
*
* @return S_OK.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookClient::foreachMailUserCallback(
BSTR id)
{
char * charId = StringUtils::WideCharToMultiByte(id);
MAPINotification_callCallbackMethod(charId, NULL);
free(charId);
return S_OK;
}
/**
* Callback called each time the COM server forward a contact deleted notify
* event from MAPI.
*
* @param id The contact identifier.
*
* @return S_OK.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookClient::deleted(BSTR id)
{
char * charId = StringUtils::WideCharToMultiByte(id);
MAPINotification_jniCallDeletedMethod(charId);
free(charId);
return S_OK;
}
/**
* Callback called each time the COM server forward a contact inserted notify
* event from MAPI.
*
* @param id The contact identifier.
*
* @return S_OK.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookClient::inserted(BSTR id)
{
char * charId = StringUtils::WideCharToMultiByte(id);
MAPINotification_jniCallInsertedMethod(charId);
free(charId);
return S_OK;
}
/**
* Callback called each time the COM server forward a contact updated notify
* event from MAPI.
*
* @param id The contact identifier.
*
* @return S_OK.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookClient::updated(BSTR id)
{
char * charId = StringUtils::WideCharToMultiByte(id);
MAPINotification_jniCallUpdatedMethod(charId);
free(charId);
return S_OK;
}

@ -0,0 +1,51 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKCLIENT_H
#define __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKCLIENT_H
#include <stdio.h>
#include <unknwn.h>
#include "IMsOutlookAddrBookClient.h"
EXTERN_C const GUID DECLSPEC_SELECTANY CLSID_MsOutlookAddrBookClient
= {0x867BD590, 0xB1AC, 0x11E2,
{0x9E, 0x96, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66}}; // generated
EXTERN_C const GUID DECLSPEC_SELECTANY IID_IMsOutlookAddrBookClient
= {0xD579E840, 0xB1A6, 0x11E2,
{0x9E, 0x96, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66}}; // generated
/**
* @author Vincent Lucas
*/
class MsOutlookAddrBookClient:
public IMsOutlookAddrBookClient
{
public:
MsOutlookAddrBookClient();
// IUnknown
STDMETHODIMP QueryInterface(REFIID iid, PVOID *obj);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IMsOutlookAddrBookClient
HRESULT STDMETHODCALLTYPE foreachMailUserCallback(BSTR id);
HRESULT STDMETHODCALLTYPE deleted(BSTR id);
HRESULT STDMETHODCALLTYPE inserted(BSTR id);
HRESULT STDMETHODCALLTYPE updated(BSTR id);
protected:
virtual ~MsOutlookAddrBookClient();
private:
ULONG _refCount;
};
#endif

@ -0,0 +1,63 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "MsOutlookAddrBookClientClassFactory.h"
#include "MsOutlookAddrBookClient.h"
/**
* Instanciates a new MsOutlookAddrBookClientClassFactory.
*/
MsOutlookAddrBookClientClassFactory::MsOutlookAddrBookClientClassFactory():
ClassFactory(CLSID_MsOutlookAddrBookClient),
_msOutlookAddrBookClient(NULL)
{
}
/**
* Deletest this instance of MsOutlookAddrBookClientClassFactory.
*/
MsOutlookAddrBookClientClassFactory::~MsOutlookAddrBookClientClassFactory()
{
if (_msOutlookAddrBookClient)
_msOutlookAddrBookClient->Release();
}
/**
* Creates a new instance of a MsOutlookAddrBookClient.
*
* @param outer A pointer used if the object is being created as part of an
* aggregate,
* @param iid The identifier of the interface requested.
* @param obj A pointer use to return an object implemented the interface
* requested.
*
* @return S_OK if the corresponding interface has been found. Any other error
* otherwise.
*/
STDMETHODIMP
MsOutlookAddrBookClientClassFactory::CreateInstance
(LPUNKNOWN outer, REFIID iid, PVOID *obj)
{
HRESULT hr;
if(outer)
{
*obj = NULL;
hr = CLASS_E_NOAGGREGATION;
}
else
{
if(_msOutlookAddrBookClient)
{
_msOutlookAddrBookClient->Release();
}
_msOutlookAddrBookClient = NULL;
_msOutlookAddrBookClient = new MsOutlookAddrBookClient();
hr = _msOutlookAddrBookClient->QueryInterface(iid, obj);
}
return hr;
}

@ -0,0 +1,37 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKCLIENTCLASSFACTORY_H
#define __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKCLIENTCLASSFACTORY_H
#include "ClassFactory.h"
#include "MsOutlookAddrBookClient.h"
/**
* Implements the <tt>IClassFactory</tt> interface for the
* <tt>IMsOutlookAddrBookClient</tt>
* interface implementation.
*
* @author Lyubomir Marinov
*/
class MsOutlookAddrBookClientClassFactory:
public ClassFactory
{
public:
MsOutlookAddrBookClientClassFactory();
STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, PVOID *);
protected:
virtual ~MsOutlookAddrBookClientClassFactory();
private:
IMsOutlookAddrBookClient *_msOutlookAddrBookClient;
};
#endif /* _JMSOFFICECOMM_MSOUTLOOKADDRBOOKCLASSFACTORY_H_ */

@ -0,0 +1,367 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "MsOutlookAddrBookServer.h"
#include "MsOutlookAddrBookClient.h"
#include <mapix.h>
#include <stdio.h>
#include <wchar.h>
#include "../StringUtils.h"
#include "../MsOutlookAddrBookContactQuery.h"
/**
* Instanciates a new MsOutlookAddrBookServer.
*/
MsOutlookAddrBookServer::MsOutlookAddrBookServer():
_refCount(1)
{
}
/**
* Deletes this MsOutlookAddrBookServer.
*/
MsOutlookAddrBookServer::~MsOutlookAddrBookServer()
{
Release();
}
/**
* Returns an instance of the interface requested, if available.
*
* @param iid The identifier of the interface requested.
* @param obj A pointer use to return an object instance implementing the
* interface requested.
*
* @return S_OK if the corresponding interface has been found. E_POINTER, or
* E_NOINTERFACE otherwise.
*/
STDMETHODIMP MsOutlookAddrBookServer::QueryInterface(REFIID iid, PVOID *obj)
{
OLECHAR* strGuid;
StringFromCLSID(iid, &strGuid);
::CoTaskMemFree(strGuid);
HRESULT hr;
if (!obj)
{
hr = E_POINTER;
}
else if (IID_IUnknown == iid)
{
AddRef();
*obj = static_cast<IUnknown *>(
static_cast<IMsOutlookAddrBookServer *>(this));
hr = S_OK;
}
else if (IID_IMsOutlookAddrBookServer == iid)
{
AddRef();
*obj = static_cast<IMsOutlookAddrBookServer *>(this);
hr = S_OK;
}
else
{
hr = E_NOINTERFACE;
}
return hr;
}
/**
* Increment the number of reference.
*
* @return The number of reference.
*/
STDMETHODIMP_(ULONG) MsOutlookAddrBookServer::AddRef()
{
return ++_refCount;
}
/**
* Decrement the number of reference.
*
* @return The number of reference.
*/
STDMETHODIMP_(ULONG) MsOutlookAddrBookServer::Release()
{
ULONG refCount = --_refCount;
if(!refCount)
{
delete this;
}
return refCount;
}
/**
* Starts a search for contact using MAPI.A
*
* @param query The search pattern (unused).
*
* @return S_OK.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookServer::foreachMailUser(BSTR query)
{
char * charQuery = StringUtils::WideCharToMultiByte(query);
MsOutlookAddrBookContactQuery_foreachMailUser(
charQuery,
(void *) MsOutlookAddrBookServer::foreachMailUserCallback,
NULL);
free(charQuery);
return S_OK;
}
/**
* Calls back the java side to list a contact.
*
* @param iUnknown The string representation of the entry id of the contact.
* @param object Not used. Must be set to NULL.
*
* @return True everything works fine and that we must continue to list the
* other contacts. False otherwise.
*/
boolean MsOutlookAddrBookServer::foreachMailUserCallback(
LPSTR iUnknown,
void * object)
{
HRESULT hr = E_FAIL;
IMsOutlookAddrBookClient * msOutlookAddrBookClient = NULL;
if((hr = CoCreateInstance(
CLSID_MsOutlookAddrBookClient,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IMsOutlookAddrBookClient,
(void**) &msOutlookAddrBookClient)) == S_OK)
{
LPWSTR iUnknownW = StringUtils::MultiByteToWideChar(iUnknown);
BSTR res = SysAllocString(iUnknownW);
hr = msOutlookAddrBookClient->foreachMailUserCallback(res);
SysFreeString(res);
free(iUnknownW);
msOutlookAddrBookClient->Release();
}
return (hr == S_OK);
}
/**
* Get the properties for a given contact.
*
* @param entryId The contact identifier.
* @param nbPropIds The number of properties requested.
* @param propIds The list of property identifiers requested (long).
* @param flags A bitmask of flags that indicates the format for properties.
* @param props Used to return the properties gathered.
* @param propsLength Used to return the list of porperty length.
* @param propsType Used to return the list of type of property. b = byteArray,
* l = long, s = 8 bits string, u = 16 bits string.
*
* @return S_OK if eveything works fine. Any error value otherwise.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookServer::IMAPIProp_GetProps(
BSTR entryId,
int nbPropIds,
SAFEARRAY * propIds,
long flags,
SAFEARRAY ** props,
SAFEARRAY ** propsLength,
SAFEARRAY ** propsType)
{
HRESULT hr = E_FAIL;
void ** localProps = NULL;
unsigned long* localPropsLength = NULL;
// b = byteArray, l = long, s = 8 bits string, u = 16 bits string.
char * localPropsType = NULL;
if((localProps = (void**) malloc(nbPropIds * sizeof(void*))) != NULL)
{
if((localPropsLength = (unsigned long*) malloc(
nbPropIds * sizeof(unsigned long))) != NULL)
{
if((localPropsType = (char*) malloc(nbPropIds * sizeof(char)))
!= NULL)
{
SafeArrayLock(propIds);
long * longPropIds = (long*) propIds->pvData;
SafeArrayUnlock(propIds);
LPSTR id = StringUtils::WideCharToMultiByte(entryId);
hr = MsOutlookAddrBookContactQuery_IMAPIProp_1GetProps(
id,
nbPropIds,
longPropIds,
flags,
localProps,
localPropsLength,
localPropsType);
free(id);
if(HR_SUCCEEDED(hr))
{
long totalLength = 0;
for(int j = 0; j < nbPropIds; ++j)
{
totalLength += localPropsLength[j];
}
(*props) = SafeArrayCreateVector(VT_UI1, 0, totalLength);
SafeArrayLock(*props);
byte * data = (byte*) (*props)->pvData;
for(int j = 0; j < nbPropIds; ++j)
{
memcpy(data, localProps[j], localPropsLength[j]);
data += localPropsLength[j];
}
SafeArrayUnlock(*props);
(*propsLength) = SafeArrayCreateVector(VT_I4, 0, nbPropIds);
SafeArrayLock(*propsLength);
memcpy(
(*propsLength)->pvData,
localPropsLength,
nbPropIds * sizeof(unsigned long));
SafeArrayUnlock(*propsLength);
(*propsType) = SafeArrayCreateVector(VT_UI1, 0, nbPropIds);
SafeArrayLock(*propsType);
memcpy(
(*propsType)->pvData,
localPropsType,
nbPropIds * sizeof(char));
SafeArrayUnlock(*propsType);
}
for(int j = 0; j < nbPropIds; ++j)
{
if(localProps[j] != NULL)
free(localProps[j]);
}
free(localPropsType);
}
free(localPropsLength);
}
free(localProps);
}
return hr;
}
/**
* Creates an empty contact.
*
* @param id The identifier of the created contact.
*
* @return S_OK if the contact was correctly created. E_FAIL otherwise.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookServer::createContact(
BSTR *id)
{
LPSTR nativeId = MsOutlookAddrBookContactQuery_createContact();
if(nativeId != NULL)
{
LPWSTR nativeWId = StringUtils::MultiByteToWideChar(nativeId);
*id = SysAllocString(nativeWId);
free(nativeWId);
free(nativeId);
return S_OK;
}
return E_FAIL;
}
/**
* Deletes a contact.
*
* @param id The identifier of the contact to delete.
*
* @return S_OK if the contact was correctly deleted. E_FAIL otherwise.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookServer::deleteContact(
BSTR id)
{
HRESULT hr = E_FAIL;
if(id != NULL)
{
LPSTR nativeId = StringUtils::WideCharToMultiByte(id);
if(MsOutlookAddrBookContactQuery_deleteContact(nativeId) == 1)
{
hr = S_OK;
}
free(nativeId);
}
return hr;
}
/**
* Deletes a given property for a contact.
*
* @param propId The identifier of the property to delete.
* @param entryId The identifier of the contact.
*
* @return S_OK if the contact was correctly deleted. E_FAIL otherwise.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookServer::IMAPIProp_DeleteProp(
long propId,
BSTR entryId)
{
HRESULT hr = E_FAIL;
if(entryId != NULL)
{
LPSTR nativeId = StringUtils::WideCharToMultiByte(entryId);
if(MsOutlookAddrBookContactQuery_IMAPIProp_1DeleteProp(
propId,
nativeId) == 1)
{
hr = S_OK;
}
free(nativeId);
}
return hr;
}
/**
* Sets a given property for a contact.
*
* @param propId The identifier of the property to set.
* @param value The value to set for the property.
* @param entryId The identifier of the contact.
*
* @return S_OK if the contact was correctly deleted. E_FAIL otherwise.
*/
HRESULT STDMETHODCALLTYPE MsOutlookAddrBookServer::IMAPIProp_SetPropString(
long propId,
BSTR value,
BSTR entryId)
{
HRESULT hr = E_FAIL;
if(value != NULL && entryId != NULL)
{
LPSTR nativeValue = StringUtils::WideCharToMultiByte(value);
LPSTR nativeId = StringUtils::WideCharToMultiByte(entryId);
if(MsOutlookAddrBookContactQuery_IMAPIProp_1SetPropString(
propId,
nativeValue,
nativeId) == 1)
{
hr = S_OK;
}
free(nativeId);
free(nativeValue);
}
return hr;
}

@ -0,0 +1,78 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKSERVER_H
#define __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKSERVER_H
#include <stdio.h>
#include <unknwn.h>
#include "IMsOutlookAddrBookServer.h"
EXTERN_C const GUID DECLSPEC_SELECTANY CLSID_MsOutlookAddrBookServer
= {0x22435A40, 0xAB57, 0x11E2,
{0x9E, 0x96, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66}}; // generated.
EXTERN_C const GUID DECLSPEC_SELECTANY IID_IMsOutlookAddrBookServer
= {0x5DDE9FF0, 0xAC48, 0x11E2,
{0x9E, 0x96, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66}}; // generated
/**
* @author Vincent Lucas
*/
class MsOutlookAddrBookServer:
public IMsOutlookAddrBookServer
{
public:
MsOutlookAddrBookServer();
// IUnknown
STDMETHODIMP QueryInterface(REFIID, PVOID *);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IMsOutlookAddrBookServer
HRESULT STDMETHODCALLTYPE foreachMailUser(BSTR query);
HRESULT STDMETHODCALLTYPE IMAPIProp_GetProps(
BSTR entryId,
int nbPropIds,
SAFEARRAY * propIds,
long flags,
SAFEARRAY ** props,
SAFEARRAY ** propsLength,
SAFEARRAY ** propsType);
HRESULT STDMETHODCALLTYPE createContact(
BSTR *id);
HRESULT STDMETHODCALLTYPE deleteContact(
BSTR id);
HRESULT STDMETHODCALLTYPE IMAPIProp_DeleteProp(
long propId,
BSTR entryId);
HRESULT STDMETHODCALLTYPE IMAPIProp_SetPropString(
long propId,
BSTR value,
BSTR entryId);
protected:
virtual ~MsOutlookAddrBookServer();
private:
ULONG _refCount;
static boolean foreachMailUserCallback(
LPSTR iUnknown,
void * object);
};
#endif

@ -0,0 +1,64 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "MsOutlookAddrBookServerClassFactory.h"
#include "MsOutlookAddrBookServer.h"
/**
* Instanciates a new MsOutlookAddrBookServerClassFactory.
*/
MsOutlookAddrBookServerClassFactory::MsOutlookAddrBookServerClassFactory():
ClassFactory(CLSID_MsOutlookAddrBookServer),
_msOutlookAddrBookServer(NULL)
{
}
/**
* Deletest this instance of MsOutlookAddrBookServerClassFactory.
*/
MsOutlookAddrBookServerClassFactory::~MsOutlookAddrBookServerClassFactory()
{
if (_msOutlookAddrBookServer)
_msOutlookAddrBookServer->Release();
}
/**
* Creates a new instance of a MsOutlookAddrBookServer.
*
* @param outer A pointer used if the object is being created as part of an
* aggregate,
* @param iid The identifier of the interface requested.
* @param obj A pointer use to return an object implemented the interface
* requested.
*
* @return S_OK if the corresponding interface has been found. Any other error
* otherwise.
*/
STDMETHODIMP
MsOutlookAddrBookServerClassFactory::CreateInstance
(LPUNKNOWN outer, REFIID iid, PVOID *obj)
{
HRESULT hr;
if(outer)
{
*obj = NULL;
hr = CLASS_E_NOAGGREGATION;
}
else
{
if(_msOutlookAddrBookServer)
{
_msOutlookAddrBookServer->Release();
}
_msOutlookAddrBookServer = NULL;
_msOutlookAddrBookServer = new MsOutlookAddrBookServer();
hr = _msOutlookAddrBookServer->QueryInterface(iid, obj);
}
return hr;
}

@ -0,0 +1,37 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKSERVERCLASSFACTORY_H
#define __MSOUTLOOKADDRBOOKCOM_MSOUTLOOKADDRBOOKSERVERCLASSFACTORY_H
#include "ClassFactory.h"
#include "MsOutlookAddrBookServer.h"
/**
* Implements the <tt>IClassFactory</tt> interface for the
* <tt>IMsOutlookAddrBookServer</tt>
* interface implementation.
*
* @author Lyubomir Marinov
*/
class MsOutlookAddrBookServerClassFactory:
public ClassFactory
{
public:
MsOutlookAddrBookServerClassFactory();
STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, PVOID *);
protected:
virtual ~MsOutlookAddrBookServerClassFactory();
private:
IMsOutlookAddrBookServer *_msOutlookAddrBookServer;
};
#endif

@ -0,0 +1,102 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "TypeLib.h"
#include "../StringUtils.h"
#include <stdio.h>
/**
* Un/Register the typeLib for the COM server and client.
*
* @author Vincent Lucas
*/
/**
* Register the typeLib for the COM server and client.
*
* @param path The tlb filename.
*
* @return A pointer to the loaded typeLib. NULL if failed.
*/
LPTYPELIB TypeLib_loadRegTypeLib(WCHAR* path)
{
LPTYPELIB iTypeLib = NULL;
// Gets the path for the loading the tlb.
char * applicationName = StringUtils::WideCharToMultiByte(path);
int applicationNameLength = strlen(applicationName);
char currentDirectory[FILENAME_MAX - applicationNameLength - 8];
GetCurrentDirectory(
FILENAME_MAX - applicationNameLength - 8,
currentDirectory);
char libPath[FILENAME_MAX];
sprintf(libPath, "%s/native/%s", currentDirectory, applicationName);
free(applicationName);
LPWSTR libPathW = StringUtils::MultiByteToWideChar(libPath);
if(SUCCEEDED(::LoadTypeLibEx(libPathW, REGKIND_NONE, &iTypeLib)))
{
HMODULE oleaut32 = ::GetModuleHandle(_T("oleaut32.dll"));
if (oleaut32)
{
typedef HRESULT (WINAPI *RTLFU)(LPTYPELIB,LPOLESTR,LPOLESTR);
RTLFU registerTypeLibForUser
= (RTLFU) ::GetProcAddress(oleaut32, "RegisterTypeLibForUser");
if (registerTypeLibForUser)
{
registerTypeLibForUser(iTypeLib, libPathW, NULL);
}
else
{
iTypeLib = NULL;
}
}
else
{
iTypeLib = NULL;
}
}
free(libPathW);
return iTypeLib;
}
/**
* Unegister the typeLib for the COM server and client.
*
* @param A pointer to the loaded typeLib.
*/
void TypeLib_releaseTypeLib(LPTYPELIB iTypeLib)
{
HMODULE oleaut32 = ::GetModuleHandle(_T("oleaut32.dll"));
if(oleaut32)
{
typedef HRESULT (WINAPI *URTLFU)(REFGUID,WORD,WORD,LCID,SYSKIND);
URTLFU unRegisterTypeLibForUser
= (URTLFU) ::GetProcAddress(oleaut32, "UnRegisterTypeLibForUser");
if(unRegisterTypeLibForUser)
{
LPTLIBATTR typeLibAttr;
if(iTypeLib->GetLibAttr(&typeLibAttr) == S_OK)
{
unRegisterTypeLibForUser(
typeLibAttr->guid,
typeLibAttr->wMajorVerNum,
typeLibAttr->wMinorVerNum,
typeLibAttr->lcid,
typeLibAttr->syskind);
}
iTypeLib->ReleaseTLibAttr(typeLibAttr);
}
}
iTypeLib->Release();
}

@ -0,0 +1,21 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#ifndef __MSOUTLOOKADDRBOOKCOM_TYPELIB_H
#define __MSOUTLOOKADDRBOOKCOM_TYPELIB_H
#include <objbase.h>
/**
* Un/Register the typeLib for the COM server and client.
*
* @author Vincent Lucas
*/
LPTYPELIB TypeLib_loadRegTypeLib(WCHAR* path);
void TypeLib_releaseTypeLib(LPTYPELIB iTypeLib);
#endif

@ -0,0 +1,197 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
#include "../../MAPIBitness.h"
#include "../../MAPISession.h"
#include "../../MsOutlookAddrBookContactSourceService.h"
#include "../../StringUtils.h"
#include "../MsOutlookAddrBookClient.h"
#include "../MsOutlookAddrBookServerClassFactory.h"
#include "../TypeLib.h"
#include <stdio.h>
#include <TlHelp32.h>
#define MAPI_NO_COINIT 8
void waitParentProcessStop();
static void Server_deleted(LPSTR id);
static void Server_inserted(LPSTR id);
static void Server_updated(LPSTR id);
/**
* Starts the COM server.
*/
int main(int argc, char** argv)
{
HRESULT hr = E_FAIL;
if(::CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK)
{
return hr;
}
MAPISession_initLock();
if(MsOutlookAddrBookContactSourceService_NativeMAPIInitialize(
MAPI_INIT_VERSION,
MAPI_MULTITHREAD_NOTIFICATIONS | MAPI_NO_COINIT,
(void*) Server_deleted,
(void*) Server_inserted,
(void*) Server_updated)
!= S_OK)
{
return hr;
}
WCHAR * path = (WCHAR*) L"IMsOutlookAddrBookServer.tlb";
LPTYPELIB typeLib = TypeLib_loadRegTypeLib(path);
if(typeLib != NULL)
{
ClassFactory *classObject = new MsOutlookAddrBookServerClassFactory();
if(classObject != NULL)
{
hr = classObject->registerClassObject();
hr = ::CoResumeClassObjects();
waitParentProcessStop();
hr = ::CoSuspendClassObjects();
classObject->Release();
}
TypeLib_releaseTypeLib(typeLib);
}
MsOutlookAddrBookContactSourceService_NativeMAPIUninitialize();
MAPISession_freeLock();
return hr;
}
/**
* Wait that the parent process stops.
*/
void waitParentProcessStop()
{
HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 processEntry;
memset(&processEntry, 0, sizeof(processEntry));
processEntry.dwSize = sizeof(PROCESSENTRY32);
DWORD id = GetCurrentProcessId();
if(Process32First(handle, &processEntry))
{
do
{
// We have found this process
if(processEntry.th32ProcessID == id)
{
// Get the parent process handle.
HANDLE parentHandle
= OpenProcess(
SYNCHRONIZE
| PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ,
FALSE,
processEntry.th32ParentProcessID);
// Wait for our parent to stop.
DWORD exitCode;
GetExitCodeProcess(parentHandle, &exitCode);
while(exitCode == STILL_ACTIVE)
{
WaitForSingleObject(parentHandle, INFINITE);
GetExitCodeProcess(parentHandle, &exitCode);
}
return;
}
}
while(Process32Next(handle, &processEntry));
}
}
CloseHandle(handle);
}
/**
* Invoke the callback function of the COM client when a contact has been
* deleted from MAPI.
*
* @param id The contact identifer.
*/
static void Server_deleted(LPSTR id)
{
HRESULT hr = E_FAIL;
IMsOutlookAddrBookClient * msOutlookAddrBookClient = NULL;
if((hr = CoCreateInstance(
CLSID_MsOutlookAddrBookClient,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IMsOutlookAddrBookClient,
(void**) &msOutlookAddrBookClient)) == S_OK)
{
LPWSTR idW = StringUtils::MultiByteToWideChar(id);
BSTR res = SysAllocString(idW);
msOutlookAddrBookClient->deleted(res);
SysFreeString(res);
free(idW);
msOutlookAddrBookClient->Release();
}
}
/**
* Invoke the callback function of the COM client when a contact has been
* created from MAPI.
*
* @param id The contact identifer.
*/
static void Server_inserted(LPSTR id)
{
HRESULT hr = E_FAIL;
IMsOutlookAddrBookClient * msOutlookAddrBookClient = NULL;
if((hr = CoCreateInstance(
CLSID_MsOutlookAddrBookClient,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IMsOutlookAddrBookClient,
(void**) &msOutlookAddrBookClient)) == S_OK)
{
LPWSTR idW = StringUtils::MultiByteToWideChar(id);
BSTR res = SysAllocString(idW);
msOutlookAddrBookClient->inserted(res);
SysFreeString(res);
free(idW);
msOutlookAddrBookClient->Release();
}
}
/**
* Invoke the callback function of the COM client when a contact has been
* modified from MAPI.
*
* @param id The contact identifer.
*/
static void Server_updated(LPSTR id)
{
HRESULT hr = E_FAIL;
IMsOutlookAddrBookClient * msOutlookAddrBookClient = NULL;
if((hr = CoCreateInstance(
CLSID_MsOutlookAddrBookClient,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IMsOutlookAddrBookClient,
(void**) &msOutlookAddrBookClient)) == S_OK)
{
LPWSTR idW = StringUtils::MultiByteToWideChar(id);
BSTR res = SysAllocString(idW);
msOutlookAddrBookClient->updated(res);
SysFreeString(res);
free(idW);
msOutlookAddrBookClient->Release();
}
}

@ -19,7 +19,8 @@ JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_plugin_addrbook_msoutl
* Method: foreachMailUser
* Signature: (Ljava/lang/String;Lnet/java/sip/communicator/plugin/addrbook/PtrCallback;)V
*/
JNIEXPORT void JNICALL Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery_foreachMailUser
JNIEXPORT void JNICALL
Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery_foreachMailUser
(JNIEnv *, jclass, jstring, jobject);
JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery_IMAPIProp_1DeleteProp

@ -7,542 +7,50 @@
#include "net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService.h"
#include "../AddrBookContactQuery.h"
#include "MsOutlookAddrBookContactSourceService.h"
#include "MsOutlookMAPIHResultException.h"
#include "MAPINotification.h"
#include "MAPISession.h"
#include "net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef BOOL (STDAPICALLTYPE *LPFBINFROMHEX)(LPSTR, LPBYTE);
typedef void (STDAPICALLTYPE *LPFREEPROWS)(LPSRowSet);
typedef void (STDAPICALLTYPE *LPHEXFROMBIN)(LPBYTE, int, LPSTR);
typedef HRESULT (STDAPICALLTYPE *LPHRALLOCADVISESINK)(LPNOTIFCALLBACK, LPVOID, LPMAPIADVISESINK FAR *);
typedef HRESULT (STDAPICALLTYPE *LPHRQUERYALLROWS)(LPMAPITABLE, LPSPropTagArray, LPSRestriction, LPSSortOrderSet, LONG, LPSRowSet FAR *);
static LPFBINFROMHEX MsOutlookAddrBookContactSourceService_fBinFromHex;
static LPFREEPROWS MsOutlookAddrBookContactSourceService_freeProws;
static LPHEXFROMBIN MsOutlookAddrBookContactSourceService_hexFromBin;
static LPHRALLOCADVISESINK MsOutlookAddrBookContactSourceService_hrAllocAdviseSink;
static LPHRQUERYALLROWS MsOutlookAddrBookContactSourceService_hrQueryAllRows;
static LPMAPIALLOCATEBUFFER
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer;
static LPMAPIFREEBUFFER MsOutlookAddrBookContactSourceService_mapiFreeBuffer;
static LPMAPIINITIALIZE MsOutlookAddrBookContactSourceService_mapiInitialize;
static LPMAPILOGONEX MsOutlookAddrBookContactSourceService_mapiLogonEx;
static LPMAPIUNINITIALIZE
MsOutlookAddrBookContactSourceService_mapiUninitialize;
static HMODULE hMapiLib = NULL;
static jboolean
MsOutlookAddrBookContactSourceService_isValidDefaultMailClient
(LPCTSTR name, DWORD nameLength);
#include "MAPIBitness.h"
JNIEXPORT void JNICALL
Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService_MAPIInitialize
(JNIEnv *jniEnv, jclass /*clazz*/, jlong version, jlong flags,
(JNIEnv *jniEnv, jclass clazz, jlong version, jlong flags,
jobject notificationsDelegate)
{
HKEY regKey;
HRESULT hResult = MAPI_E_NO_SUPPORT;
/*
* In the absence of a default e-mail program, MAPIInitialize may show a
* dialog to notify of the fact. The dialog is undesirable here. Because we
* implement ContactSourceService for Microsoft Outlook, we will try to
* mitigate the problem by implementing an ad-hoc check whether Microsoft
* Outlook is installed.
*/
if (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\Office"),
0,
KEY_ENUMERATE_SUB_KEYS,
&regKey))
{
DWORD i = 0;
TCHAR installRootKeyName[
255 // The size limit of key name as documented in MSDN
+ 20 // \Outlook\InstallRoot
+ 1]; // The terminating null character
while (1)
{
LONG regEnumKeyEx;
DWORD subkeyNameLength = 255 + 1;
LPTSTR str;
HKEY installRootKey;
DWORD pathValueType;
DWORD pathValueSize;
regEnumKeyEx
= RegEnumKeyEx(
regKey,
i,
installRootKeyName, &subkeyNameLength,
NULL,
NULL, NULL,
NULL);
if (ERROR_NO_MORE_ITEMS == regEnumKeyEx)
break;
i++;
if (ERROR_SUCCESS != regEnumKeyEx)
continue;
str = installRootKeyName + subkeyNameLength;
memcpy(str, _T("\\Outlook\\InstallRoot"), 20 * sizeof(TCHAR));
*(str + 20) = 0;
if (ERROR_SUCCESS
== RegOpenKeyEx(
regKey,
installRootKeyName,
0,
KEY_QUERY_VALUE,
&installRootKey))
{
if ((ERROR_SUCCESS
== RegQueryValueEx(
installRootKey,
_T("Path"),
NULL,
&pathValueType,
NULL, &pathValueSize))
&& (REG_SZ == pathValueType)
&& pathValueSize)
{
LPTSTR pathValue;
// MSDN says "the string may not have been stored with the
// proper terminating null characters."
pathValueSize
+= sizeof(TCHAR)
* (12 // \Outlook.exe
+ 1); // The terminating null character
if (pathValueSize <= sizeof(installRootKeyName))
pathValue = installRootKeyName;
else
{
pathValue = (LPTSTR)::malloc(pathValueSize);
if (!pathValue)
continue;
}
if (ERROR_SUCCESS
== RegQueryValueEx(
installRootKey,
_T("Path"),
NULL,
NULL,
(LPBYTE) pathValue, &pathValueSize))
{
DWORD pathValueLength = pathValueSize / sizeof(TCHAR);
if (pathValueLength)
{
DWORD fileAttributes;
str = pathValue + (pathValueLength - 1);
if (*str)
str++;
memcpy(str, _T("\\Outlook.exe"), 12 * sizeof(TCHAR));
*(str + 12) = 0;
fileAttributes = GetFileAttributes(pathValue);
if (INVALID_FILE_ATTRIBUTES != fileAttributes)
hResult = S_OK;
}
}
if (pathValue != installRootKeyName)
free(pathValue);
}
RegCloseKey(installRootKey);
}
}
RegCloseKey(regKey);
// Make sure that Microsoft Outlook is the default mail client in order
// to prevent its dialog in the case of it not being the default mail
// client.
if (HR_SUCCEEDED(hResult))
{
DWORD defaultValueType;
// The buffer installRootKeyName is long enough to receive
// "Microsoft Outlook" so use it in order to not have to allocate
// more memory.
LPTSTR defaultValue = (LPTSTR) installRootKeyName;
DWORD defaultValueCapacity = sizeof(installRootKeyName);
jboolean checkHKeyLocalMachine;
HRESULT hr;
hResult = MAPI_E_NO_SUPPORT;
if (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_CURRENT_USER,
_T("Software\\Clients\\Mail"),
0,
KEY_QUERY_VALUE,
&regKey))
{
DWORD defaultValueSize = defaultValueCapacity;
LONG regQueryValueEx
= RegQueryValueEx(
regKey,
NULL,
NULL,
&defaultValueType,
(LPBYTE) defaultValue, &defaultValueSize);
MAPINotification_registerJniNotificationsDelegate(
jniEnv,
notificationsDelegate);
switch (regQueryValueEx)
{
case ERROR_SUCCESS:
{
if (REG_SZ == defaultValueType)
{
DWORD defaultValueLength
= defaultValueSize / sizeof(TCHAR);
if (JNI_TRUE
== MsOutlookAddrBookContactSourceService_isValidDefaultMailClient(
defaultValue,
defaultValueLength))
{
checkHKeyLocalMachine = JNI_FALSE;
if (_tcsnicmp(
_T("Microsoft Outlook"), defaultValue,
defaultValueLength)
== 0)
hResult = S_OK;
}
else
checkHKeyLocalMachine = JNI_TRUE;
}
else
checkHKeyLocalMachine = JNI_FALSE;
break;
}
case ERROR_FILE_NOT_FOUND:
checkHKeyLocalMachine = JNI_TRUE;
break;
case ERROR_MORE_DATA:
checkHKeyLocalMachine = JNI_FALSE;
break;
default:
checkHKeyLocalMachine = JNI_FALSE;
break;
}
RegCloseKey(regKey);
}
else
checkHKeyLocalMachine = JNI_TRUE;
if ((JNI_TRUE == checkHKeyLocalMachine)
&& (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("Software\\Clients\\Mail"),
0,
KEY_QUERY_VALUE,
&regKey)))
{
DWORD defaultValueSize = defaultValueCapacity;
LONG regQueryValueEx
= RegQueryValueEx(
regKey,
NULL,
NULL,
&defaultValueType,
(LPBYTE) defaultValue, &defaultValueSize);
if ((ERROR_SUCCESS == regQueryValueEx)
&& (REG_SZ == defaultValueType))
{
DWORD defaultValueLength = defaultValueSize / sizeof(TCHAR);
if ((_tcsnicmp(
_T("Microsoft Outlook"), defaultValue,
defaultValueLength)
== 0)
&& (JNI_TRUE
== MsOutlookAddrBookContactSourceService_isValidDefaultMailClient(_T("Microsoft Outlook"), 17)))
hResult = S_OK;
}
RegCloseKey(regKey);
}
}
if(MAPIBitness_isOutlookBitnessCompatible())
{
hr = MsOutlookAddrBookContactSourceService_MAPIInitialize(
version,
flags);
}
// If we've determined that we'd like to go on with MAPI, try to load it.
if (HR_SUCCEEDED(hResult))
else
{
hMapiLib = ::LoadLibrary(_T("mapi32.dll"));
hResult = MAPI_E_NO_SUPPORT;
if(hMapiLib)
{
// get and check function pointers
MsOutlookAddrBookContactSourceService_mapiInitialize
= (LPMAPIINITIALIZE) GetProcAddress(hMapiLib, "MAPIInitialize");
MsOutlookAddrBookContactSourceService_mapiUninitialize
= (LPMAPIUNINITIALIZE)
GetProcAddress(hMapiLib, "MAPIUninitialize");
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer
= (LPMAPIALLOCATEBUFFER)
GetProcAddress(hMapiLib, "MAPIAllocateBuffer");
MsOutlookAddrBookContactSourceService_mapiFreeBuffer
= (LPMAPIFREEBUFFER) GetProcAddress(hMapiLib, "MAPIFreeBuffer");
MsOutlookAddrBookContactSourceService_mapiLogonEx
= (LPMAPILOGONEX) GetProcAddress(hMapiLib, "MAPILogonEx");
MsOutlookAddrBookContactSourceService_fBinFromHex
= (LPFBINFROMHEX) GetProcAddress(hMapiLib, "FBinFromHex@8");
MsOutlookAddrBookContactSourceService_freeProws
= (LPFREEPROWS) GetProcAddress(hMapiLib, "FreeProws@4");
MsOutlookAddrBookContactSourceService_hexFromBin
= (LPHEXFROMBIN) GetProcAddress(hMapiLib, "HexFromBin@12");
MsOutlookAddrBookContactSourceService_hrAllocAdviseSink
= (LPHRALLOCADVISESINK)
GetProcAddress(hMapiLib, "HrAllocAdviseSink@12");
MsOutlookAddrBookContactSourceService_hrQueryAllRows
= (LPHRQUERYALLROWS)
GetProcAddress(hMapiLib, "HrQueryAllRows@24");
if (MsOutlookAddrBookContactSourceService_mapiInitialize
&& MsOutlookAddrBookContactSourceService_mapiUninitialize
&& MsOutlookAddrBookContactSourceService_mapiAllocateBuffer
&& MsOutlookAddrBookContactSourceService_mapiFreeBuffer
&& MsOutlookAddrBookContactSourceService_mapiLogonEx
&& MsOutlookAddrBookContactSourceService_fBinFromHex
&& MsOutlookAddrBookContactSourceService_freeProws
&& MsOutlookAddrBookContactSourceService_hexFromBin
&& MsOutlookAddrBookContactSourceService_hrAllocAdviseSink
&& MsOutlookAddrBookContactSourceService_hrQueryAllRows)
{
MAPIINIT_0 mapiInit = { (ULONG) version, (ULONG) flags };
// Opening MAPI changes the working directory. Make a backup of
// the current directory, login to MAPI and restore it
DWORD dwSize = ::GetCurrentDirectory(0, NULL);
if (dwSize > 0)
{
LPTSTR lpszWorkingDir
= (LPTSTR)::malloc(dwSize*sizeof(TCHAR));
DWORD dwResult
= ::GetCurrentDirectory(dwSize, lpszWorkingDir);
if (dwResult != 0)
{
MAPISession_lock();
hResult
= MsOutlookAddrBookContactSourceService_mapiInitialize(
&mapiInit);
if(HR_SUCCEEDED(hResult)
&& MAPISession_getMapiSession() == NULL)
{
LPMAPISESSION mapiSession = NULL;
hResult = MsOutlookAddrBook_mapiLogonEx(
0,
NULL, NULL,
MAPI_EXTENDED
| MAPI_NO_MAIL
| MAPI_USE_DEFAULT,
&mapiSession);
MAPINotification_registerNotificationsDelegate(
jniEnv,
mapiSession,
notificationsDelegate);
}
::SetCurrentDirectory(lpszWorkingDir);
MAPISession_unlock();
}
else
{
hResult = HRESULT_FROM_WIN32(::GetLastError());
}
::free(lpszWorkingDir);
}
else
{
hResult = HRESULT_FROM_WIN32(::GetLastError());
}
}
}
hr = MsOutlookAddrBookContactSourceService_MAPIInitializeCOMServer();
}
if (HR_FAILED(hResult))
if (HR_FAILED(hr))
{
if (hMapiLib)
{
FreeLibrary(hMapiLib);
hMapiLib = NULL;
}
/* Report any possible error regardless of where it has come from. */
// Report any possible error regardless of where it has come from.
MsOutlookMAPIHResultException_throwNew(
jniEnv,
hResult,
hr,
__FILE__, __LINE__);
}
}
JNIEXPORT void JNICALL
Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService_MAPIUninitialize
(JNIEnv *jniEnv, jclass /*clazz*/)
(JNIEnv *jniEnv, jclass clazz)
{
MAPISession_lock();
LPMAPISESSION mapiSession = MAPISession_getMapiSession();
if(mapiSession != NULL)
{
MAPINotification_unregisterNotificationsDelegate(jniEnv);
mapiSession->Logoff(0, 0, 0);
mapiSession->Release();
MAPISession_setMapiSession(NULL);
}
MsOutlookAddrBookContactSourceService_mapiUninitialize();
MsOutlookAddrBookContactSourceService_mapiInitialize = NULL;
MsOutlookAddrBookContactSourceService_mapiUninitialize = NULL;
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer = NULL;
MsOutlookAddrBookContactSourceService_mapiFreeBuffer = NULL;
MsOutlookAddrBookContactSourceService_mapiLogonEx = NULL;
MsOutlookAddrBookContactSourceService_fBinFromHex = NULL;
MsOutlookAddrBookContactSourceService_freeProws = NULL;
MsOutlookAddrBookContactSourceService_hexFromBin = NULL;
MsOutlookAddrBookContactSourceService_hrAllocAdviseSink = NULL;
MsOutlookAddrBookContactSourceService_hrQueryAllRows = NULL;
::FreeLibrary(hMapiLib);
hMapiLib = NULL;
MAPINotification_unregisterJniNotificationsDelegate(jniEnv);
MAPISession_unlock();
MsOutlookAddrBookContactSourceService_MAPIUninitialize();
}
BOOL MsOutlookAddrBook_fBinFromHex(LPSTR lpsz, LPBYTE lpb)
{
return MsOutlookAddrBookContactSourceService_fBinFromHex(lpsz, lpb);
}
void MsOutlookAddrBook_freeProws(LPSRowSet lpRows)
{
MsOutlookAddrBookContactSourceService_freeProws(lpRows);
}
void MsOutlookAddrBook_hexFromBin(LPBYTE pb, int cb, LPSTR sz)
{
return MsOutlookAddrBookContactSourceService_hexFromBin(pb, cb, sz);
}
void
MsOutlookAddrBook_hrAllocAdviseSink
(LPNOTIFCALLBACK lpfnCallback, LPVOID lpvContext, LPMAPIADVISESINK*
lppAdviseSink)
{
MsOutlookAddrBookContactSourceService_hrAllocAdviseSink(
lpfnCallback,
lpvContext,
lppAdviseSink);
}
HRESULT
MsOutlookAddrBook_hrQueryAllRows
(LPMAPITABLE lpTable, LPSPropTagArray lpPropTags,
LPSRestriction lpRestriction, LPSSortOrderSet lpSortOrderSet,
LONG crowsMax, LPSRowSet* lppRows)
{
return MsOutlookAddrBookContactSourceService_hrQueryAllRows(
lpTable,
lpPropTags,
lpRestriction,
lpSortOrderSet,
crowsMax,
lppRows);
}
SCODE
MsOutlookAddrBook_mapiAllocateBuffer(ULONG size, LPVOID FAR *buffer)
{
return
MsOutlookAddrBookContactSourceService_mapiAllocateBuffer(size, buffer);
}
ULONG
MsOutlookAddrBook_mapiFreeBuffer(LPVOID buffer)
{
return MsOutlookAddrBookContactSourceService_mapiFreeBuffer(buffer);
}
HRESULT
MsOutlookAddrBook_mapiLogonEx
(ULONG_PTR uiParam,
LPTSTR profileName, LPTSTR password,
FLAGS flags,
LPMAPISESSION FAR *mapiSession)
{
HRESULT hResult;
MAPISession_lock();
LPMAPISESSION currentMapiSession = MAPISession_getMapiSession();
if (currentMapiSession != NULL)
hResult = S_OK;
else
{
hResult
= MsOutlookAddrBookContactSourceService_mapiLogonEx(
uiParam,
profileName, password,
flags,
&currentMapiSession);
MAPISession_setMapiSession(currentMapiSession);
}
if (HR_SUCCEEDED(hResult))
{
*mapiSession = currentMapiSession;
}
MAPISession_unlock();
return hResult;
}
static jboolean
MsOutlookAddrBookContactSourceService_isValidDefaultMailClient
(LPCTSTR name, DWORD nameLength)
{
jboolean validDefaultMailClient = JNI_FALSE;
if ((0 != nameLength) && (0 != name[0]))
{
LPTSTR str;
TCHAR keyName[
22 /* Software\Clients\Mail\ */
+ 255
+ 1 /* The terminating null character */];
HKEY key;
str = keyName;
_tcsncpy(str, _T("Software\\Clients\\Mail\\"), 22);
str += 22;
if (nameLength > 255)
nameLength = 255;
_tcsncpy(str, name, nameLength);
*(str + nameLength) = 0;
if (ERROR_SUCCESS
== RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
keyName,
0,
KEY_QUERY_VALUE,
&key))
{
validDefaultMailClient = JNI_TRUE;
RegCloseKey(key);
}
}
return validDefaultMailClient;
}

@ -8,14 +8,13 @@
extern "C" {
#endif
#include "MsOutlookMAPI.h"
/*
* Class: net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService
* Method: MAPIInitialize
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService_MAPIInitialize
JNIEXPORT void JNICALL
Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService_MAPIInitialize
(JNIEnv *, jclass, jlong, jlong, jobject);
/*

@ -850,7 +850,8 @@
description="Build jmsoutlookaddrbook shared library for Windows"
if="is.running.windows"
depends="init-native">
<fail message="Outlook2010MAPIHeaders not set!" unless="Outlook2010MAPIHeaders" />
<fail message="Outlook2010MAPIHeaders not set!"
unless="Outlook2010MAPIHeaders" />
<cc
name="gcc"
objdir="${obj}"
@ -872,10 +873,48 @@
<linkerarg value="-m64" if="cross_64" />
<linkerarg value="-Wl,--kill-at" />
<linkerarg value="-Wl,--subsystem,windows" />
<libset libs="advapi32,uuid" />
<libset libs="advapi32, uuid, ole32, oleaut32, msi, stdc++" />
<fileset dir="${src}/native/addrbook" includes="*.c" />
<fileset dir="${src}/native/addrbook/msoutlook" includes="*.cxx" />
<fileset dir="${src}/native/addrbook/msoutlook/com/" includes="*.cxx" />
</cc>
</target>
<!-- compile msoutlookaddrbookserver executable for Windows -->
<target
name="msoutlookaddrbookcomserver"
description="Build jmsoutlookaddrbookcomserver executable for Windows"
if="is.running.windows"
depends="init-native">
<exec executable="cp">
<arg value="${src}/native/addrbook/msoutlook/com/*.tlb"/>
<arg value="${native_install_dir}/"/>
</exec>
<fail message="Outlook2010MAPIHeaders not set!"
unless="Outlook2010MAPIHeaders" />
<cc
name="g++"
objdir="${obj}"
outfile="${native_install_dir}/jmsoutlookaddrbookcomserver">
<compilerarg value="-I${system.JAVA_HOME}/include" />
<compilerarg value="-I${system.JAVA_HOME}/include/win32" />
<compilerarg value="-I${Outlook2010MAPIHeaders}" />
<compilerarg value="-m32" if="cross_64" /> <!-- inverse cross compil /-->
<compilerarg value="-m64" if="cross_32" /> <!-- inverse cross compil /-->
<compilerarg value="-O2" />
<compilerarg value="-Wall" />
<linkerarg value="-ojmsoutlookaddrbookcomserver.exe" />
<linkerarg value="-m32" if="cross_64" /> <!-- inverse cross compil /-->
<linkerarg value="-m64" if="cross_32" /> <!-- inverse cross compil /-->
<libset libs="uuid, ole32, oleaut32, msi, stdc++" />
<fileset dir="${src}/native/addrbook/msoutlook" includes="*.cxx" />
<fileset dir="${src}/native/addrbook/msoutlook/com" includes="*.cxx" />
<fileset dir="${src}/native/addrbook/msoutlook/com/server"
includes="*.cxx" />
</cc>
</target>
</project>

@ -968,18 +968,27 @@ protected void run()
*/
public void inserted(String id)
{
try
SourceContact sourceContact = findSourceContactByID(id);
if(sourceContact != null
&& sourceContact instanceof MsOutlookAddrBookSourceContact)
{
onMailUser(id);
updated(id);
}
catch (MsOutlookMAPIHResultException e)
else
{
if (logger.isDebugEnabled())
try
{
logger.debug(
MsOutlookAddrBookContactQuery.class.getSimpleName()
+ "#onMailUser(String)",
e);
onMailUser(id);
}
catch (MsOutlookMAPIHResultException e)
{
if (logger.isDebugEnabled())
{
logger.debug(
MsOutlookAddrBookContactQuery.class.getSimpleName()
+ "#onMailUser(String)",
e);
}
}
}
}
@ -991,8 +1000,7 @@ public void inserted(String id)
*/
public void updated(String id)
{
SourceContact sourceContact
= findSourceContactByID(id);
SourceContact sourceContact = findSourceContactByID(id);
if(sourceContact != null
&& sourceContact instanceof MsOutlookAddrBookSourceContact)
{

Loading…
Cancel
Save