1132 lines
25 KiB
C
1132 lines
25 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1996 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
mapi.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file implements wrappers for all mapi apis.
|
||
|
The wrappers are necessary because mapi does not
|
||
|
implement unicode and this code must be non-unicode.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
WIN32 User Mode
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Wesley Witt (wesw) 7-Aug-1996
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#undef UNICODE
|
||
|
#undef _UNICODE
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <mapiwin.h>
|
||
|
#include <mapix.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#define INTERNAL 1
|
||
|
#include "common.h"
|
||
|
#include "resource.h"
|
||
|
|
||
|
|
||
|
#define MAPISVC_INF "mapisvc.inf"
|
||
|
#define PAB_FILE_NAME "%windir%\\msfax.pab"
|
||
|
#define PST_FILE_NAME "%windir%\\msfax.pst"
|
||
|
|
||
|
#define FAXAB_SERVICE_NAME "MSFAX AB"
|
||
|
#define FAXXP_SERVICE_NAME "MSFAX XP"
|
||
|
#define MSAB_SERVICE_NAME "MSPST AB"
|
||
|
#define MSPST_SERVICE_NAME "MSPST MS"
|
||
|
#define CONTAB_SERVICE_NAME "CONTAB"
|
||
|
#define MSAB_SERVICE_NAME_W L"MSPST AB"
|
||
|
#define MSPST_SERVICE_NAME_W L"MSPST MS"
|
||
|
#define FAXAB_SERVICE_NAME_W L"MSFAX AB"
|
||
|
#define CONTAB_SERVICE_NAME_W L"CONTAB"
|
||
|
|
||
|
|
||
|
//
|
||
|
// pab property tags
|
||
|
//
|
||
|
|
||
|
#define PR_PAB_PATH PROP_TAG( PT_TSTRING, 0x6600 )
|
||
|
#define PR_PAB_PATH_W PROP_TAG( PT_UNICODE, 0x6600 )
|
||
|
#define PR_PAB_PATH_A PROP_TAG( PT_STRING8, 0x6600 )
|
||
|
#define PR_PAB_DET_DIR_VIEW_BY PROP_TAG( PT_LONG, 0x6601 )
|
||
|
|
||
|
#define PAB_DIR_VIEW_FIRST_THEN_LAST 0
|
||
|
#define PAB_DIR_VIEW_LAST_THEN_FIRST 1
|
||
|
|
||
|
//
|
||
|
// pst property tags
|
||
|
//
|
||
|
|
||
|
#define PR_PST_PATH PROP_TAG( PT_STRING8, 0x6700 )
|
||
|
#define PR_PST_REMEMBER_PW PROP_TAG( PT_BOOLEAN, 0x6701 )
|
||
|
#define PR_PST_ENCRYPTION PROP_TAG( PT_LONG, 0x6702 )
|
||
|
#define PR_PST_PW_SZ_OLD PROP_TAG( PT_STRING8, 0x6703 )
|
||
|
#define PR_PST_PW_SZ_NEW PROP_TAG( PT_STRING8, 0x6704 )
|
||
|
|
||
|
#define PSTF_NO_ENCRYPTION ((DWORD)0x80000000)
|
||
|
#define PSTF_COMPRESSABLE_ENCRYPTION ((DWORD)0x40000000)
|
||
|
#define PSTF_BEST_ENCRYPTION ((DWORD)0x20000000)
|
||
|
|
||
|
|
||
|
//
|
||
|
// externs & globals
|
||
|
//
|
||
|
|
||
|
extern BOOL MapiAvail;
|
||
|
|
||
|
static HMODULE MapiMod = NULL;
|
||
|
static LPMAPIADMINPROFILES MapiAdminProfiles = NULL;
|
||
|
static LPMAPIINITIALIZE MapiInitialize = NULL;
|
||
|
static LPMAPILOGONEX MapiLogonEx;
|
||
|
static LPMAPIUNINITIALIZE MapiUnInitialize = NULL;
|
||
|
static LPMAPIFREEBUFFER pMAPIFreeBuffer = NULL;
|
||
|
static LPPROFADMIN lpProfAdmin;
|
||
|
|
||
|
static CHAR MapiSvcInf[MAX_PATH*2];
|
||
|
static BOOL MapiStartedByLogon;
|
||
|
|
||
|
BOOL MapiAvail;
|
||
|
|
||
|
|
||
|
LPWSTR MyGetString(DWORD);
|
||
|
|
||
|
|
||
|
|
||
|
static
|
||
|
LPWSTR
|
||
|
AnsiStringToUnicodeString(
|
||
|
LPSTR AnsiString,
|
||
|
LPWSTR UnicodeString
|
||
|
)
|
||
|
{
|
||
|
DWORD Count;
|
||
|
|
||
|
|
||
|
//
|
||
|
// first see how big the buffer needs to be
|
||
|
//
|
||
|
Count = MultiByteToWideChar(
|
||
|
CP_ACP,
|
||
|
MB_PRECOMPOSED,
|
||
|
AnsiString,
|
||
|
-1,
|
||
|
NULL,
|
||
|
0
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// i guess the input string is empty
|
||
|
//
|
||
|
if (!Count) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// convert the string
|
||
|
//
|
||
|
Count = MultiByteToWideChar(
|
||
|
CP_ACP,
|
||
|
MB_PRECOMPOSED,
|
||
|
AnsiString,
|
||
|
-1,
|
||
|
UnicodeString,
|
||
|
Count
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// the conversion failed
|
||
|
//
|
||
|
if (!Count) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return UnicodeString;
|
||
|
}
|
||
|
|
||
|
|
||
|
static
|
||
|
LPSTR
|
||
|
UnicodeStringToAnsiString(
|
||
|
LPWSTR UnicodeString,
|
||
|
LPSTR AnsiString
|
||
|
)
|
||
|
{
|
||
|
DWORD Count;
|
||
|
|
||
|
|
||
|
//
|
||
|
// first see how big the buffer needs to be
|
||
|
//
|
||
|
Count = WideCharToMultiByte(
|
||
|
CP_ACP,
|
||
|
0,
|
||
|
UnicodeString,
|
||
|
-1,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// i guess the input string is empty
|
||
|
//
|
||
|
if (!Count) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// convert the string
|
||
|
//
|
||
|
Count = WideCharToMultiByte(
|
||
|
CP_ACP,
|
||
|
0,
|
||
|
UnicodeString,
|
||
|
-1,
|
||
|
AnsiString,
|
||
|
Count,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// the conversion failed
|
||
|
//
|
||
|
if (!Count) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return AnsiString;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
MyWriteProfileString(
|
||
|
LPTSTR SectionName,
|
||
|
LPTSTR KeyName,
|
||
|
LPTSTR Value,
|
||
|
LPWSTR SystemPath
|
||
|
)
|
||
|
{
|
||
|
char IniPath[MAX_PATH];
|
||
|
|
||
|
UnicodeStringToAnsiString(SystemPath, IniPath);
|
||
|
|
||
|
strcat(IniPath, "\\");
|
||
|
strcat(IniPath, MapiSvcInf);
|
||
|
|
||
|
WritePrivateProfileString(
|
||
|
SectionName,
|
||
|
KeyName,
|
||
|
Value,
|
||
|
IniPath
|
||
|
);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
MyWriteProfileStringW(
|
||
|
LPTSTR SectionName,
|
||
|
LPTSTR KeyName,
|
||
|
LPWSTR Value,
|
||
|
LPWSTR SystemPath
|
||
|
)
|
||
|
{
|
||
|
WCHAR WSectionName[100];
|
||
|
WCHAR WKeyName[100];
|
||
|
WCHAR WMapiSvcInf[MAX_PATH];
|
||
|
WCHAR IniPath[MAX_PATH];
|
||
|
|
||
|
AnsiStringToUnicodeString (MapiSvcInf, WMapiSvcInf);
|
||
|
AnsiStringToUnicodeString (KeyName, WKeyName) ;
|
||
|
AnsiStringToUnicodeString (SectionName, WSectionName);
|
||
|
|
||
|
swprintf(IniPath, L"%s\\%s", SystemPath, WMapiSvcInf);
|
||
|
|
||
|
WritePrivateProfileStringW(
|
||
|
WSectionName,
|
||
|
WKeyName,
|
||
|
Value,
|
||
|
IniPath
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AddFaxAbToMapiSvcInf(
|
||
|
LPWSTR SystemPath
|
||
|
)
|
||
|
{
|
||
|
|
||
|
MyWriteProfileStringW( "Default Services", "MSFAX AB", MyGetString(IDS_FAXAB_DISPLAY_NAME), SystemPath );
|
||
|
MyWriteProfileStringW( "Services", "MSFAX AB", MyGetString(IDS_FAXAB_DISPLAY_NAME), SystemPath );
|
||
|
|
||
|
MyWriteProfileStringW( "MSFAX AB", "PR_DISPLAY_NAME", MyGetString(IDS_FAXAB_DISPLAY_NAME), SystemPath );
|
||
|
MyWriteProfileString( "MSFAX AB", "Providers", "MSFAX ABP", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX AB", "PR_SERVICE_DLL_NAME", "FAXAB.DLL", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX AB", "PR_SERVICE_SUPPORT_FILES", "FAXAB.DLL", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX AB", "PR_SERVICE_ENTRY_NAME", "FABServiceEntry", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX AB", "PR_RESOURCE_FLAGS", "SERVICE_SINGLE_COPY|SERVICE_NO_PRIMARY_IDENTITY", SystemPath );
|
||
|
|
||
|
MyWriteProfileString( "MSFAX ABP", "PR_PROVIDER_DLL_NAME", "FAXAB.DLL", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX ABP", "PR_RESOURCE_TYPE", "MAPI_AB_PROVIDER", SystemPath );
|
||
|
MyWriteProfileStringW( "MSFAX ABP", "PR_DISPLAY_NAME", MyGetString(IDS_FAXAB_DISPLAY_NAME), SystemPath );
|
||
|
MyWriteProfileStringW( "MSFAX ABP", "PR_PROVIDER_DISPLAY", MyGetString(IDS_FAXAB_DISPLAY_NAME), SystemPath );
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AddFaxXpToMapiSvcInf(
|
||
|
LPWSTR SystemPath
|
||
|
)
|
||
|
{
|
||
|
MyWriteProfileStringW( "Default Services", "MSFAX XP", MyGetString(IDS_FAXXP_DISPLAY_NAME), SystemPath );
|
||
|
MyWriteProfileStringW( "Services", "MSFAX XP", MyGetString(IDS_FAXXP_DISPLAY_NAME), SystemPath );
|
||
|
|
||
|
MyWriteProfileStringW( "MSFAX XP", "PR_DISPLAY_NAME", MyGetString(IDS_FAXXP_DISPLAY_NAME), SystemPath );
|
||
|
MyWriteProfileString( "MSFAX XP", "Providers", "MSFAX XPP", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX XP", "PR_SERVICE_DLL_NAME", "FAXXP.DLL", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX XP", "PR_SERVICE_SUPPORT_FILES", "FAXXP.DLL", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX XP", "PR_SERVICE_ENTRY_NAME", "ServiceEntry", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX XP", "PR_RESOURCE_FLAGS", "SERVICE_SINGLE_COPY|SERVICE_NO_PRIMARY_IDENTITY", SystemPath );
|
||
|
|
||
|
MyWriteProfileString( "MSFAX XPP", "PR_PROVIDER_DLL_NAME", "FAXXP.DLL", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX XPP", "PR_RESOURCE_TYPE", "MAPI_TRANSPORT_PROVIDER", SystemPath );
|
||
|
MyWriteProfileString( "MSFAX XPP", "PR_RESOURCE_FLAGS", "STATUS_NO_DEFAULT_STORE", SystemPath );
|
||
|
MyWriteProfileStringW( "MSFAX XPP", "PR_DISPLAY_NAME", MyGetString(IDS_FAXXP_DISPLAY_NAME), SystemPath );
|
||
|
MyWriteProfileStringW( "MSFAX XPP", "PR_PROVIDER_DISPLAY", MyGetString(IDS_FAXXP_DISPLAY_NAME), SystemPath );
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
FreeSRowSet(
|
||
|
LPSRowSet prws
|
||
|
)
|
||
|
{
|
||
|
ULONG irw;
|
||
|
|
||
|
if (!prws) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for(irw = 0; irw < prws->cRows; irw++) {
|
||
|
pMAPIFreeBuffer( prws->aRow[irw].lpProps );
|
||
|
}
|
||
|
|
||
|
pMAPIFreeBuffer( prws );
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG
|
||
|
MLCRelease(
|
||
|
LPUNKNOWN punk
|
||
|
)
|
||
|
{
|
||
|
return (punk) ? punk->lpVtbl->Release(punk) : 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
ValidateProp(
|
||
|
LPSPropValue pval,
|
||
|
ULONG ulPropTag
|
||
|
)
|
||
|
{
|
||
|
if (pval->ulPropTag != ulPropTag) {
|
||
|
pval->ulPropTag = ulPropTag;
|
||
|
pval->Value.lpszA = "???";
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
IsMapiServiceInstalled(
|
||
|
LPWSTR ProfileNameW,
|
||
|
LPWSTR ServiceNameW
|
||
|
)
|
||
|
{
|
||
|
SPropTagArray taga = {2,{PR_DISPLAY_NAME,PR_SERVICE_NAME}};
|
||
|
BOOL rVal = FALSE;
|
||
|
LPSERVICEADMIN lpSvcAdmin;
|
||
|
LPMAPITABLE pmt = NULL;
|
||
|
LPSRowSet prws = NULL;
|
||
|
DWORD i;
|
||
|
LPSPropValue pval;
|
||
|
CHAR ProfileName[128];
|
||
|
CHAR ServiceName[64];
|
||
|
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
UnicodeStringToAnsiString( ProfileNameW, ProfileName );
|
||
|
UnicodeStringToAnsiString( ServiceNameW, ServiceName );
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (lpSvcAdmin->lpVtbl->GetMsgServiceTable( lpSvcAdmin, 0, &pmt )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (pmt->lpVtbl->SetColumns( pmt, &taga, 0 )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
for (i=0; i<prws->cRows; i++) {
|
||
|
pval = prws->aRow[i].lpProps;
|
||
|
ValidateProp( &pval[0], PR_DISPLAY_NAME );
|
||
|
ValidateProp( &pval[1], PR_SERVICE_NAME );
|
||
|
if (_stricmp( pval[1].Value.lpszA, ServiceName ) == 0) {
|
||
|
rVal = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
FreeSRowSet( prws );
|
||
|
MLCRelease( (LPUNKNOWN)pmt );
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
InstallFaxAddressBook(
|
||
|
HWND hwnd,
|
||
|
LPWSTR ProfileNameW
|
||
|
)
|
||
|
{
|
||
|
SPropTagArray taga = {2,{PR_SERVICE_NAME,PR_SERVICE_UID}};
|
||
|
SPropValue spvProps[2] = { 0 };
|
||
|
BOOL rVal = FALSE;
|
||
|
LPSERVICEADMIN lpSvcAdmin;
|
||
|
CHAR ProfileName[128];
|
||
|
CHAR Buffer[128];
|
||
|
HRESULT hResult;
|
||
|
LPMAPITABLE pmt = NULL;
|
||
|
LPSRowSet prws = NULL;
|
||
|
DWORD i;
|
||
|
LPSPropValue pval;
|
||
|
BOOL ConfigurePst = FALSE;
|
||
|
BOOL ConfigurePab = FALSE;
|
||
|
LPMAPISESSION Session = NULL;
|
||
|
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
UnicodeStringToAnsiString( ProfileNameW, ProfileName );
|
||
|
|
||
|
if (IsMapiServiceInstalled( ProfileNameW, CONTAB_SERVICE_NAME_W )) {
|
||
|
//
|
||
|
// we don't need a pab/fab if we have the outlook contact address book
|
||
|
//
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
hResult = lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin );
|
||
|
if (hResult) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (!IsMapiServiceInstalled( ProfileNameW, MSAB_SERVICE_NAME_W )) {
|
||
|
hResult = lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, MSAB_SERVICE_NAME, NULL, 0, 0 );
|
||
|
if (hResult && hResult != MAPI_E_NO_ACCESS) {
|
||
|
//
|
||
|
// mapi will return MAPI_E_NO_ACCESS when the service is already installed
|
||
|
//
|
||
|
goto exit;
|
||
|
}
|
||
|
ConfigurePab = TRUE;
|
||
|
}
|
||
|
|
||
|
if (!IsMapiServiceInstalled( ProfileNameW, MSPST_SERVICE_NAME_W )) {
|
||
|
hResult = lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, MSPST_SERVICE_NAME, NULL, 0, 0 );
|
||
|
if (hResult && hResult != MAPI_E_NO_ACCESS) {
|
||
|
//
|
||
|
// mapi will return MAPI_E_NO_ACCESS when the service is already installed
|
||
|
//
|
||
|
goto exit;
|
||
|
}
|
||
|
ConfigurePst = TRUE;
|
||
|
}
|
||
|
|
||
|
if (!IsMapiServiceInstalled( ProfileNameW, FAXAB_SERVICE_NAME_W )) {
|
||
|
hResult = lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, FAXAB_SERVICE_NAME, NULL, 0, 0 );
|
||
|
if (hResult && hResult != MAPI_E_NO_ACCESS) {
|
||
|
//
|
||
|
// mapi will return MAPI_E_NO_ACCESS when the service is already installed
|
||
|
//
|
||
|
goto exit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// now configure the address book and pst
|
||
|
//
|
||
|
|
||
|
if (lpSvcAdmin->lpVtbl->GetMsgServiceTable( lpSvcAdmin, 0, &pmt )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (pmt->lpVtbl->SetColumns( pmt, &taga, 0 )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
for (i=0; i<prws->cRows; i++) {
|
||
|
pval = prws->aRow[i].lpProps;
|
||
|
ValidateProp( &pval[0], PR_SERVICE_NAME );
|
||
|
if (ConfigurePab && (_stricmp( pval[0].Value.lpszA, MSAB_SERVICE_NAME) == 0)) {
|
||
|
//
|
||
|
// configure the pab service
|
||
|
//
|
||
|
|
||
|
ExpandEnvironmentStrings( PAB_FILE_NAME, Buffer, sizeof(Buffer) );
|
||
|
|
||
|
spvProps[0].ulPropTag = PR_PAB_PATH;
|
||
|
spvProps[0].Value.LPSZ = Buffer;
|
||
|
spvProps[1].ulPropTag = PR_PAB_DET_DIR_VIEW_BY;
|
||
|
spvProps[1].Value.ul = PAB_DIR_VIEW_FIRST_THEN_LAST;
|
||
|
|
||
|
if (lpSvcAdmin->lpVtbl->ConfigureMsgService( lpSvcAdmin, (LPMAPIUID)pval[1].Value.bin.lpb, (ULONG_PTR)hwnd, 0, 2, spvProps )) {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
if (ConfigurePst && (_stricmp( pval[0].Value.lpszA, MSPST_SERVICE_NAME) == 0)) {
|
||
|
//
|
||
|
// configure the pst service
|
||
|
//
|
||
|
|
||
|
ExpandEnvironmentStrings( PST_FILE_NAME, Buffer, sizeof(Buffer) );
|
||
|
|
||
|
spvProps[0].ulPropTag = PR_PST_PATH;
|
||
|
spvProps[0].Value.LPSZ = Buffer;
|
||
|
spvProps[1].ulPropTag = PR_PST_ENCRYPTION;
|
||
|
spvProps[1].Value.ul = PSTF_NO_ENCRYPTION;
|
||
|
|
||
|
if (lpSvcAdmin->lpVtbl->ConfigureMsgService( lpSvcAdmin, (LPMAPIUID)pval[1].Value.bin.lpb, (ULONG_PTR)hwnd, 0, 2, spvProps )) {
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ConfigurePab || ConfigurePst) {
|
||
|
__try {
|
||
|
if (MapiLogonEx(
|
||
|
0,
|
||
|
ProfileName,
|
||
|
NULL,
|
||
|
MAPI_NEW_SESSION | MAPI_EXTENDED,
|
||
|
&Session
|
||
|
) == 0)
|
||
|
{
|
||
|
MapiStartedByLogon = TRUE;
|
||
|
Session->lpVtbl->Logoff( Session, 0, 0, 0 );
|
||
|
}
|
||
|
|
||
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
rVal = TRUE;
|
||
|
|
||
|
exit:
|
||
|
FreeSRowSet( prws );
|
||
|
MLCRelease( (LPUNKNOWN)pmt );
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
InstallFaxTransport(
|
||
|
LPWSTR ProfileNameW
|
||
|
)
|
||
|
{
|
||
|
BOOL rVal = FALSE;
|
||
|
LPSERVICEADMIN lpSvcAdmin;
|
||
|
CHAR ProfileName[128];
|
||
|
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
UnicodeStringToAnsiString( ProfileNameW, ProfileName );
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, FAXXP_SERVICE_NAME, NULL, 0, 0 )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
rVal = TRUE;
|
||
|
|
||
|
exit:
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CreateDefaultMapiProfile(
|
||
|
LPWSTR ProfileNameW
|
||
|
)
|
||
|
{
|
||
|
BOOL rVal = FALSE;
|
||
|
CHAR ProfileName[128];
|
||
|
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
UnicodeStringToAnsiString( ProfileNameW, ProfileName );
|
||
|
|
||
|
//
|
||
|
// create the new profile
|
||
|
//
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->CreateProfile( lpProfAdmin, ProfileName, NULL, 0, 0 )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->SetDefaultProfile( lpProfAdmin, ProfileName, 0 )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
rVal = TRUE;
|
||
|
|
||
|
exit:
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
GetDefaultMapiProfile(
|
||
|
LPWSTR ProfileName
|
||
|
)
|
||
|
{
|
||
|
BOOL rVal = FALSE;
|
||
|
LPMAPITABLE pmt = NULL;
|
||
|
LPSRowSet prws = NULL;
|
||
|
LPSPropValue pval;
|
||
|
DWORD i;
|
||
|
DWORD j;
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the mapi profile table object
|
||
|
//
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->GetProfileTable( lpProfAdmin, 0, &pmt )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the actual profile data, FINALLY
|
||
|
//
|
||
|
|
||
|
if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// enumerate the profiles looking for the default profile
|
||
|
//
|
||
|
|
||
|
for (i=0; i<prws->cRows; i++) {
|
||
|
pval = prws->aRow[i].lpProps;
|
||
|
for (j = 0; j < 2; j++) {
|
||
|
if (pval[j].ulPropTag == PR_DEFAULT_PROFILE && pval[j].Value.b) {
|
||
|
//
|
||
|
// this is the default profile
|
||
|
//
|
||
|
AnsiStringToUnicodeString( pval[0].Value.lpszA, ProfileName );
|
||
|
rVal = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
FreeSRowSet( prws );
|
||
|
MLCRelease( (LPUNKNOWN)pmt );
|
||
|
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
DeleteMessageService(
|
||
|
LPSTR ProfileName
|
||
|
)
|
||
|
{
|
||
|
SPropTagArray taga = {2,{PR_SERVICE_NAME,PR_SERVICE_UID}};
|
||
|
BOOL rVal = FALSE;
|
||
|
LPSERVICEADMIN lpSvcAdmin;
|
||
|
LPMAPITABLE pmt = NULL;
|
||
|
LPSRowSet prws = NULL;
|
||
|
DWORD i;
|
||
|
LPSPropValue pval;
|
||
|
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (lpSvcAdmin->lpVtbl->GetMsgServiceTable( lpSvcAdmin, 0, &pmt )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (pmt->lpVtbl->SetColumns( pmt, &taga, 0 )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
for (i=0; i<prws->cRows; i++) {
|
||
|
|
||
|
pval = prws->aRow[i].lpProps;
|
||
|
|
||
|
ValidateProp( &pval[0], PR_SERVICE_NAME );
|
||
|
|
||
|
if (_stricmp( pval[0].Value.lpszA, "MSFAX AB" ) == 0) {
|
||
|
lpSvcAdmin->lpVtbl->DeleteMsgService( lpSvcAdmin, (LPMAPIUID) pval[1].Value.bin.lpb );
|
||
|
}
|
||
|
|
||
|
if (_stricmp( pval[0].Value.lpszA, "MSFAX XP" ) == 0) {
|
||
|
lpSvcAdmin->lpVtbl->DeleteMsgService( lpSvcAdmin, (LPMAPIUID) pval[1].Value.bin.lpb );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
FreeSRowSet( prws );
|
||
|
MLCRelease( (LPUNKNOWN)pmt );
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
DeleteFaxMsgServices(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
BOOL rVal = FALSE;
|
||
|
LPMAPITABLE pmt = NULL;
|
||
|
LPSRowSet prws = NULL;
|
||
|
LPSPropValue pval;
|
||
|
DWORD i;
|
||
|
DWORD j;
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the mapi profile table object
|
||
|
//
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->GetProfileTable( lpProfAdmin, 0, &pmt )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the actual profile data, FINALLY
|
||
|
//
|
||
|
|
||
|
if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// enumerate the profiles looking for the default profile
|
||
|
//
|
||
|
|
||
|
for (i=0; i<prws->cRows; i++) {
|
||
|
pval = prws->aRow[i].lpProps;
|
||
|
for (j = 0; j < 2; j++) {
|
||
|
if (pval[j].ulPropTag == PR_DISPLAY_NAME) {
|
||
|
DeleteMessageService( pval[j].Value.lpszA );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
FreeSRowSet( prws );
|
||
|
MLCRelease( (LPUNKNOWN)pmt );
|
||
|
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
IsExchangeInstalled(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
BOOL MapiAvail = FALSE;
|
||
|
CHAR MapiOption[4];
|
||
|
HKEY hKey;
|
||
|
LONG rVal;
|
||
|
DWORD Bytes;
|
||
|
DWORD Type;
|
||
|
|
||
|
rVal = RegOpenKey(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
"Software\\Microsoft\\Windows Messaging Subsystem",
|
||
|
&hKey
|
||
|
);
|
||
|
if (rVal == ERROR_SUCCESS) {
|
||
|
Bytes = sizeof(MapiOption);
|
||
|
rVal = RegQueryValueEx(
|
||
|
hKey,
|
||
|
"MAPIX",
|
||
|
NULL,
|
||
|
&Type,
|
||
|
(LPBYTE) MapiOption,
|
||
|
&Bytes
|
||
|
);
|
||
|
if (rVal == ERROR_SUCCESS) {
|
||
|
if (Bytes && MapiOption[0] == '1') {
|
||
|
MapiAvail = TRUE;
|
||
|
}
|
||
|
}
|
||
|
RegCloseKey( hKey );
|
||
|
}
|
||
|
|
||
|
return MapiAvail;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
InitializeMapi(
|
||
|
BOOL MinimalInit // just init some global variables, don't load MAPI (TRUE for GUI-mode setup)
|
||
|
)
|
||
|
{
|
||
|
MAPIINIT_0 MapiInit;
|
||
|
|
||
|
ExpandEnvironmentStrings( MAPISVC_INF, MapiSvcInf, sizeof(MapiSvcInf) );
|
||
|
if (MinimalInit) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
MapiAvail = IsExchangeInstalled();
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// load the mapi dll
|
||
|
//
|
||
|
|
||
|
MapiMod = LoadLibrary( "mapi32.dll" );
|
||
|
if (!MapiMod) {
|
||
|
MapiAvail = FALSE;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the addresses of the mapi functions that we need
|
||
|
//
|
||
|
|
||
|
MapiAdminProfiles = (LPMAPIADMINPROFILES) GetProcAddress( MapiMod, "MAPIAdminProfiles" );
|
||
|
MapiInitialize = (LPMAPIINITIALIZE) GetProcAddress( MapiMod, "MAPIInitialize" );
|
||
|
MapiUnInitialize = (LPMAPIUNINITIALIZE) GetProcAddress( MapiMod, "MAPIUninitialize" );
|
||
|
pMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress( MapiMod, "MAPIFreeBuffer" );
|
||
|
MapiLogonEx = (LPMAPILOGONEX) GetProcAddress( MapiMod, "MAPILogonEx" );
|
||
|
if ((!MapiAdminProfiles) || (!MapiInitialize) || (!MapiUnInitialize) || (!pMAPIFreeBuffer) || (!MapiLogonEx)) {
|
||
|
MapiAvail = FALSE;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// initialize mapi for our calls
|
||
|
//
|
||
|
|
||
|
MapiInit.ulVersion = 0;
|
||
|
MapiInit.ulFlags = 0;
|
||
|
|
||
|
if (MapiInitialize( &MapiInit )) {
|
||
|
MapiAvail = FALSE;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the admin profile object
|
||
|
//
|
||
|
|
||
|
if (MapiAdminProfiles( 0, &lpProfAdmin )) {
|
||
|
MapiAvail = FALSE;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
return MapiAvail;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
GetMapiProfiles(
|
||
|
HWND hwnd,
|
||
|
DWORD ResourceId
|
||
|
)
|
||
|
{
|
||
|
BOOL rVal = FALSE;
|
||
|
HMODULE MapiMod = NULL;
|
||
|
LPMAPITABLE pmt = NULL;
|
||
|
LPSRowSet prws = NULL;
|
||
|
LPSPropValue pval;
|
||
|
DWORD i;
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// add the default profile
|
||
|
//
|
||
|
|
||
|
SendDlgItemMessageA(
|
||
|
hwnd,
|
||
|
ResourceId,
|
||
|
CB_ADDSTRING,
|
||
|
0,
|
||
|
(LPARAM) "<Default Profile>"
|
||
|
);
|
||
|
|
||
|
SendDlgItemMessage(
|
||
|
hwnd,
|
||
|
ResourceId,
|
||
|
CB_SETCURSEL,
|
||
|
0,
|
||
|
0
|
||
|
);
|
||
|
|
||
|
if (!MapiAvail) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the mapi table object
|
||
|
//
|
||
|
|
||
|
if (lpProfAdmin->lpVtbl->GetProfileTable( lpProfAdmin, 0, &pmt )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the actual profile data, FINALLY
|
||
|
//
|
||
|
|
||
|
if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// enumerate the profiles and put the name
|
||
|
// of each profile in the combo box
|
||
|
//
|
||
|
|
||
|
for (i=0; i<prws->cRows; i++) {
|
||
|
pval = prws->aRow[i].lpProps;
|
||
|
|
||
|
SendDlgItemMessageA(
|
||
|
hwnd,
|
||
|
ResourceId,
|
||
|
CB_ADDSTRING,
|
||
|
0,
|
||
|
(LPARAM) pval[0].Value.lpszA
|
||
|
);
|
||
|
|
||
|
if (pval[2].Value.b) {
|
||
|
//
|
||
|
// this is the default profile
|
||
|
//
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// set the first one to be the current one
|
||
|
//
|
||
|
|
||
|
SendDlgItemMessage(
|
||
|
hwnd,
|
||
|
ResourceId,
|
||
|
CB_SETCURSEL,
|
||
|
0,
|
||
|
0
|
||
|
);
|
||
|
|
||
|
rVal = TRUE;
|
||
|
|
||
|
exit:
|
||
|
FreeSRowSet( prws );
|
||
|
MLCRelease( (LPUNKNOWN)pmt );
|
||
|
|
||
|
return rVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
GetExchangeInstallCommand(
|
||
|
LPWSTR InstallCommandW
|
||
|
)
|
||
|
{
|
||
|
HKEY hKey;
|
||
|
LONG rVal;
|
||
|
DWORD Bytes;
|
||
|
DWORD Type;
|
||
|
CHAR InstallCommand[512];
|
||
|
|
||
|
|
||
|
rVal = RegOpenKey(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
"Software\\Microsoft\\Windows Messaging Subsystem",
|
||
|
&hKey
|
||
|
);
|
||
|
if (rVal == ERROR_SUCCESS) {
|
||
|
Bytes = sizeof(InstallCommand);
|
||
|
rVal = RegQueryValueEx(
|
||
|
hKey,
|
||
|
"InstallCmd",
|
||
|
NULL,
|
||
|
&Type,
|
||
|
(LPBYTE) InstallCommand,
|
||
|
&Bytes
|
||
|
);
|
||
|
RegCloseKey( hKey );
|
||
|
if (rVal == ERROR_SUCCESS) {
|
||
|
AnsiStringToUnicodeString( InstallCommand, InstallCommandW );
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
InstallExchangeClientExtension(
|
||
|
LPSTR ExtensionName,
|
||
|
LPSTR ExtensionKey,
|
||
|
LPSTR FileName,
|
||
|
LPSTR ContextMask
|
||
|
)
|
||
|
{
|
||
|
HKEY hKey;
|
||
|
LONG rVal;
|
||
|
CHAR Buffer[512];
|
||
|
CHAR ExpandedFileName[MAX_PATH];
|
||
|
CHAR KeyName[MAX_PATH];
|
||
|
DWORD dontcare;
|
||
|
|
||
|
sprintf( KeyName, "Software\\Microsoft\\Exchange\\Client\\%s", ExtensionKey );
|
||
|
|
||
|
rVal = RegCreateKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
KeyName,
|
||
|
0,
|
||
|
NULL,
|
||
|
0,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hKey,
|
||
|
&dontcare );
|
||
|
|
||
|
if (rVal == ERROR_SUCCESS) {
|
||
|
|
||
|
ExpandEnvironmentStrings( FileName, ExpandedFileName, sizeof(ExpandedFileName) );
|
||
|
|
||
|
sprintf( Buffer, "4.0;%s;1;%s", ExpandedFileName, ContextMask );
|
||
|
|
||
|
rVal = RegSetValueEx(
|
||
|
hKey,
|
||
|
ExtensionName,
|
||
|
0,
|
||
|
REG_SZ,
|
||
|
(LPBYTE) Buffer,
|
||
|
strlen(Buffer) + 1
|
||
|
);
|
||
|
|
||
|
RegCloseKey( hKey );
|
||
|
|
||
|
return rVal == ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
IsExchangeRunning(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
#define MAX_TASKS 256
|
||
|
DWORD TaskCount;
|
||
|
PTASK_LIST TaskList = NULL;
|
||
|
DWORD ExchangePid = 0;
|
||
|
DWORD i;
|
||
|
|
||
|
|
||
|
if (MapiStartedByLogon) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
TaskList = (PTASK_LIST) malloc( MAX_TASKS * sizeof(TASK_LIST) );
|
||
|
if (!TaskList) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
TaskCount = GetTaskList( TaskList, MAX_TASKS );
|
||
|
if (!TaskCount) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
for (i=0; i<TaskCount; i++) {
|
||
|
if (_stricmp( TaskList[i].ProcessName, "exchng32.exe" ) == 0) {
|
||
|
ExchangePid = TaskList[i].dwProcessId;
|
||
|
break;
|
||
|
} else
|
||
|
if (_stricmp( TaskList[i].ProcessName, "mapisp32.exe" ) == 0) {
|
||
|
ExchangePid = TaskList[i].dwProcessId;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
free( TaskList );
|
||
|
return ExchangePid;
|
||
|
}
|