{ *********************************************************************** }
{                                                                         }
{ Translated Header File                                                  }
{ Part of the Delphi Visual Component Library                             }
{                                                                         }
{ Original Header File Copyright (c) 1985-2004 Microsoft Corporation      }
{  All Rights Reserved.                                                   }
{                                                                         }
{ Translation Copyright (c) 1995-2004 Borland Software Corporation        }
{                                                                         }
{ *********************************************************************** }

{*******************************************************}
{       Simple MAPI Interface Unit                      }
{*******************************************************}

unit Borland.Vcl.Mapi platform;

{NOTE: Do not place the $NOPACKAGEUNIT directive in this file}

interface

uses
  System.Text, System.Runtime.InteropServices, Windows;

{
  Messaging Applications Programming Interface.

  Purpose:

    This file defines the structures and constants used by that
    subset of the Messaging Applications Programming Interface
    which is supported under Windows by Microsoft Mail for PC
    Networks version 3.x.
}

type
  FLAGS = Cardinal;
  LHANDLE = Cardinal;

const
  lhSessionNull = (0);

type
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  MapiFileDesc = packed record
    ulReserved: Cardinal;        { Reserved for future use (must be 0)     }
    flFlags: Cardinal;           { Flags                                   }
    nPosition: Cardinal;         { character in text to be replaced by attachment }
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszPathName: string;        { Full path name of attachment file       }
    lpszFileName: IntPtr;        { Original file name (optional)           }
    lpFileType: IntPtr;          { Pointer - Attachment file type (can be lpMapiFileTagExt) }
  end;
  TMapiFileDesc = MapiFileDesc;

const
  MAPI_OLE = $00000001;
  MAPI_OLE_STATIC = $00000002;


type
  MapiFileTagExt = packed record
    ulReserved: Cardinal;   { Reserved, must be zero.                          }
    cbTag: Cardinal;        { Size (in bytes) of                               }
    lpTag: IntPtr;          { PByte - X.400 OID for this attachment type       }
    cbEncoding: Cardinal;   { Size (in bytes) of                               }
    lpEncoding: IntPtr;     { PByte - X.400 OID for this attachment's encoding }
  end;
  TMapiFileTagExt = MapiFileTagExt;


  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  MapiRecipDesc = packed record
    ulReserved: Cardinal;   { Reserved for future use                       }
    ulRecipClass: Cardinal; { Recipient class                               }
                            { MAPI_TO, MAPI_CC, MAPI_BCC, MAPI_ORIG         }
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszName: string;       { Recipient name                                }
    lpszAddress: IntPtr;    { Recipient address (optional)                  }
    ulEIDSize: Cardinal;    { Count in bytes of size of pEntryID            }
    lpEntryID: IntPtr;      { Pointer - System-specific recipient reference }
  end;
  TMapiRecipDesc = MapiRecipDesc;

const
  MAPI_ORIG = 0;                { Recipient is message originator          }
  MAPI_TO = 1;                  { Recipient is a primary recipient         }
  MAPI_CC = 2;                  { Recipient is a copy recipient            }
  MAPI_BCC = 3;                 { Recipient is blind copy recipient        }

type
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  MapiMessage = packed record
    ulReserved: Cardinal;         { Reserved for future use (M.B. 0)       }
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszSubject: string;          { Message Subject                        }
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszNoteText: string;         { Message Text                           }
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszMessageType: string;      { Message Class                          }
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszDateReceived: string;     { in YYYY/MM/DD HH:MM format             }
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszConversationID: string;   { conversation thread ID                 }
    flFlags: FLAGS;               { unread,return receipt                  }
    lpOriginator: IntPtr;         { PMapiRecipDesc - Originator descriptor }
    nRecipCount: Cardinal;        { Number of recipients                   }
    lpRecips: IntPtr;             { PMapiRecipDesc - Recipient descriptors }
    nFileCount: Cardinal;         { # of file attachments                  }
    lpFiles: IntPtr;              { PMapiFileDesc - Attachment descriptors }
  end;
  TMapiMessage = MapiMessage;

const
  MAPI_UNREAD = $00000001;
  MAPI_RECEIPT_REQUESTED = $00000002;
  MAPI_SENT = $00000004;


{ Entry points. }

{ flFlags values for Simple MAPI entry points. All documented flags are
  shown for each call. Duplicates are commented out but remain present
  for every call. }

{ MAPILogon() flags. }

  MAPI_LOGON_UI = $00000001;                { Display logon UI             }
  MAPI_PASSWORD_UI = $00020000;             { prompt for password only     }
  MAPI_NEW_SESSION = $00000002;             { Don't use shared session     }
  MAPI_FORCE_DOWNLOAD = $00001000;          { Get new mail before return   }
  MAPI_ALLOW_OTHERS = $00000008;            { Make this a shared session   (removed from 4.0 SDK) }
  MAPI_EXPLICIT_PROFILE = $00000010;        { Don't use default profile    (removed from 4.0 SDK) }
  MAPI_EXTENDED = $00000020;                { Extended MAPI Logon          }
  MAPI_USE_DEFAULT = $00000040;             { Use default profile in logon (removed from 4.0 SDK) }

  MAPI_SIMPLE_DEFAULT = MAPI_LOGON_UI or MAPI_FORCE_DOWNLOAD or MAPI_ALLOW_OTHERS; { removed from 4.0 SDK }
  MAPI_SIMPLE_EXPLICIT = MAPI_NEW_SESSION or MAPI_FORCE_DOWNLOAD or MAPI_EXPLICIT_PROFILE; { removed from 4.0 SDK }

{ MAPILogoff() flags.      }

  MAPI_LOGOFF_SHARED = $00000001;           { Close all shared sessions  (removed from 4.0 SDK)  }
  MAPI_LOGOFF_UI = $00000002;               { It's OK to present UI      (removed from 4.0 SDK)  }

{ MAPISendMail() flags.    }

{ #define MAPI_LOGON_UI        0x00000001     Display logon UI             }
{ #define MAPI_NEW_SESSION     0x00000002     Don't use shared session     }
  MAPI_DIALOG = $00000008;                  { Display a send note UI       }
{ # define MAPI_USE_DEFAULT     0x00000040     Use default profile in logon }

{ MAPIFindNext() flags.    }

  MAPI_UNREAD_ONLY = $00000020;             { Only unread messages         }
  MAPI_GUARANTEE_FIFO = $00000100;          { use date order               }
  MAPI_LONG_MSGID = $00004000;              { allow 512 char returned ID   }

{ MAPIReadMail() flags.    }

  MAPI_PEEK = $00000080;                    { Do not mark as read.         }
  MAPI_SUPPRESS_ATTACH = $00000800;         { header + body, no files      }
  MAPI_ENVELOPE_ONLY = $00000040;           { Only header information      }
  MAPI_BODY_AS_FILE = $00000200;

{ MAPISaveMail() flags.    }

{ #define MAPI_LOGON_UI        0x00000001     Display logon UI             }
{ #define MAPI_NEW_SESSION     0x00000002     Don't use shared session     }
{ #define MAPI_LONG_MSGID      0x00004000  /* allow 512 char returned ID   }

{ MAPIAddress() flags.     }

{ #define MAPI_LOGON_UI        0x00000001     Display logon UI             }
{ #define MAPI_NEW_SESSION     0x00000002     Don't use shared session     }

{ MAPIDetails() flags.     }

{ #define MAPI_LOGON_UI        0x00000001     Display logon UI             }
{ #define MAPI_NEW_SESSION     0x00000002     Don't use shared session     }
  MAPI_AB_NOMODIFY = $00000400;             { Don't allow mods of AB entries }

{ MAPIResolveName() flags. }

{ #define MAPI_LOGON_UI        0x00000001     Display logon UI             }
{ #define MAPI_NEW_SESSION     0x00000002     Don't use shared session     }
{ #define MAPI_DIALOG          0x00000008     Prompt for choices if ambiguous }
{ #define MAPI_AB_NOMODIFY     0x00000400     Don't allow mods of AB entries }

const
  SUCCESS_SUCCESS = 0;
  MAPI_USER_ABORT = 1;
  MAPI_E_USER_ABORT                  = MAPI_USER_ABORT;
  MAPI_E_FAILURE = 2;
  MAPI_E_LOGON_FAILURE = 3;
  MAPI_E_LOGIN_FAILURE               = MAPI_E_LOGON_FAILURE;
  MAPI_E_DISK_FULL = 4;
  MAPI_E_INSUFFICIENT_MEMORY = 5;
  MAPI_E_ACCESS_DENIED = 6;
  MAPI_E_TOO_MANY_SESSIONS = 8;
  MAPI_E_TOO_MANY_FILES = 9;
  MAPI_E_TOO_MANY_RECIPIENTS = 10;
  MAPI_E_ATTACHMENT_NOT_FOUND = 11;
  MAPI_E_ATTACHMENT_OPEN_FAILURE = 12;
  MAPI_E_ATTACHMENT_WRITE_FAILURE = 13;
  MAPI_E_UNKNOWN_RECIPIENT = 14;
  MAPI_E_BAD_RECIPTYPE = 15;
  MAPI_E_NO_MESSAGES = 16;
  MAPI_E_INVALID_MESSAGE = 17;
  MAPI_E_TEXT_TOO_LARGE = 18;
  MAPI_E_INVALID_SESSION = 19;
  MAPI_E_TYPE_NOT_SUPPORTED = 20;
  MAPI_E_AMBIGUOUS_RECIPIENT = 21;
  MAPI_E_AMBIG_RECIP                 = MAPI_E_AMBIGUOUS_RECIPIENT;
  MAPI_E_MESSAGE_IN_USE = 22;
  MAPI_E_NETWORK_FAILURE = 23;
  MAPI_E_INVALID_EDITFIELDS = 24;
  MAPI_E_INVALID_RECIPS = 25;
  MAPI_E_NOT_SUPPORTED = 26;


{ Delphi wrapper calls around Simple MAPI }

function MapiLogOn(ulUIParam: Cardinal; lpszProfileName: string;
  lpszPassword: string; flFlags: FLAGS; ulReserved: Cardinal;
  out lplhSession: LHANDLE): Cardinal;

function MapiLogOff(lhSession: LHANDLE; ulUIParam: Cardinal; flFlags: FLAGS;
  ulReserved: Cardinal): Cardinal;

function MapiSendMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpMessage: TMapiMessage; flFlags: FLAGS; ulReserved: Cardinal): Cardinal;

function MapiSendDocuments(ulUIParam: Cardinal; lpszDelimChar: string;
  lpszFilePaths: string; lpszFileNames: string; ulReserved: Cardinal): Cardinal;

function MapiFindNext(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageType: string; lpszSeedMessageID: string; flFlags: FLAGS;
  ulReserved: Cardinal; lpszMessageID: StringBuilder): Cardinal;

function MapiReadMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageID: string; flFlags: FLAGS; ulReserved: Cardinal;
  out lppMessage: IntPtr {PMapiMessage}): Cardinal;

function MapiSaveMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpMessage: TMapiMessage; flFlags: FLAGS; ulReserved: Cardinal;
  lpszMessageID: StringBuilder): Cardinal;

function MapiDeleteMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageID: string; flFlags: FLAGS; ulReserved: Cardinal): Cardinal;

function MapiFreeBuffer(pv: IntPtr): Cardinal;

function MapiAddress(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszCaption: string; nEditFields: Cardinal; lpszLabels: string;
  nRecips: Cardinal; lpRecips: IntPtr; flFlags: FLAGS;
  ulReserved: Cardinal; var lpnNewRecips: ULONG;
  var lppNewRecips: IntPtr {PMapiRecipDesc}): Cardinal;

function MapiDetails(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpRecip: TMapiRecipDesc; flFlags: FLAGS; ulReserved: Cardinal): Cardinal;

function MapiResolveName(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszName: string; flFlags: FLAGS; ulReserved: Cardinal;
  var lppRecip: IntPtr {PMapiRecipDesc}): Cardinal;

const
  MAPIDLL = 'MAPI32.DLL';

implementation

var
  MAPIAvailable: Boolean;
  MAPIChecked: Boolean = False;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiLogOn')]
function _MapiLogOn(ulUIParam: Cardinal; lpszProfileName: string;
  lpszPassword: string; flFlags: FLAGS; ulReserved: Cardinal;
  out lplhSession: LHANDLE): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiLogOff')]
function _MapiLogOff(lhSession: LHANDLE; ulUIParam: Cardinal; flFlags: FLAGS;
  ulReserved: Cardinal): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiSendMail')]
function _MapiSendMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpMessage: TMapiMessage; flFlags: FLAGS; ulReserved: Cardinal): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiSendDocuments')]
function _MapiSendDocuments(ulUIParam: Cardinal; lpszDelimChar: string;
  lpszFilePaths: string; lpszFileNames: string; ulReserved: Cardinal): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiFindNext')]
function _MapiFindNext(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageType: string; lpszSeedMessageID: string; flFlags: FLAGS;
  ulReserved: Cardinal; lpszMessageID: StringBuilder): Cardinal; external; 

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiReadMail')]
function _MapiReadMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageID: string; flFlags: FLAGS; ulReserved: Cardinal;
  out lppMessage: IntPtr {PMapiMessage}): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiSaveMail')]
function _MapiSaveMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpMessage: TMapiMessage; flFlags: FLAGS; ulReserved: Cardinal;
  lpszMessageID: StringBuilder): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiDeleteMail')]
function _MapiDeleteMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageID: string; flFlags: FLAGS; ulReserved: Cardinal): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiFreeBuffer')]
function _MapiFreeBuffer(pv: IntPtr): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiAddress')]
function _MapiAddress(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszCaption: string; nEditFields: Cardinal; lpszLabels: string;
  nRecips: Cardinal; lpRecips: IntPtr; flFlags: FLAGS;
  ulReserved: Cardinal; var lpnNewRecips: ULONG;
  var lppNewRecips: IntPtr {PMapiRecipDesc}): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiDetails')]
function _MapiDetails(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpRecip: TMapiRecipDesc; flFlags: FLAGS; ulReserved: Cardinal): Cardinal; external;

[DllImport(MAPIDLL, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'MapiResolveName')]
function _MapiResolveName(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszName: string; flFlags: FLAGS; ulReserved: Cardinal;
  var lppRecip: IntPtr {PMapiRecipDesc}): Cardinal; external;

procedure InitMapi;
var
  OSVersionInfo: TOSVersionInfo;
  hkWMS: HKEY;
  MAPIValueSize: DWORD;
  MAPIValueBuf: TBytes;
  rType: DWORD;
  MAPIModule: THandle;
begin
  if not MAPIChecked then
  begin
    MAPIChecked := True;
    MAPIModule := 0;

    OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);
    GetVersionEx(OSVersionInfo);
    if (OSVersionInfo.dwMajorVersion > 3) or
      ((OSVersionInfo.dwMajorVersion = 3) and
       (OSVersionInfo.dwMinorVersion > 51)) then
    begin
      MAPIValueSize := sizeof(MAPIValueBuf);
      if RegOpenKeyEx(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows Messaging Subsystem',
        0, KEY_READ, hkWMS) <> ERROR_SUCCESS then Exit;
      SetLength(MAPIValueBuf, 8);
      if RegQueryValueEx(hkWMS, 'MAPI', nil, rType, MAPIValueBuf,
        MAPIValueSize) <> ERROR_SUCCESS then Exit;
      RegCloseKey(hkWMS);
      if not ((MAPIValueBuf[0] = Byte('1')) and (MAPIValueBuf[1] = 0)) then Exit;
    end
    else
      if GetProfileInt('Mail', 'MAPI', 0) = 0 then Exit;

    try
      MAPIModule := LoadLibrary(MAPIDLL);
      MAPIAvailable := MAPIModule <> 0;
    finally
      FreeLibrary(MAPIModule);
    end;
  end;
end;

function MapiLogOn(ulUIParam: Cardinal; lpszProfileName: string;
  lpszPassword: string; flFlags: FLAGS; ulReserved: Cardinal;
  out lplhSession: LHANDLE): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiLogOn(ulUIParam, lpszProfileName, lpszPassword, flFlags,
      ulReserved, lplhSession)
  else Result := 1;
end;

function MapiLogOff(lhSession: LHANDLE; ulUIParam: Cardinal; flFlags: FLAGS;
  ulReserved: Cardinal): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiLogOff(lhSession, ulUIParam, flFlags, ulReserved)
  else Result := 1;
end;

function MapiSendMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpMessage: TMapiMessage; flFlags: FLAGS; ulReserved: Cardinal): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiSendMail(lhSession, ulUIParam, lpMessage, flFlags, ulReserved)
  else Result := 1;
end;

function MapiSendDocuments(ulUIParam: Cardinal; lpszDelimChar: string;
  lpszFilePaths: string; lpszFileNames: string; ulReserved: Cardinal): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiSendDocuments(ulUIParam, lpszDelimChar, lpszFilePaths,
      lpszFileNames, ulReserved)
  else Result := 1;
end;

function MapiFindNext(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageType: string; lpszSeedMessageID: string; flFlags: FLAGS;
  ulReserved: Cardinal; lpszMessageID: StringBuilder): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiFindNext(lhSession, ulUIParam, lpszMessageType,
      lpszSeedMessageID, flFlags, ulReserved, lpszMessageID)
  else Result := 1;
end;

function MapiReadMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageID: string; flFlags: FLAGS; ulReserved: Cardinal;
  out lppMessage: IntPtr {PMapiMessage}): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiReadMail(lhSession, ulUIParam, lpszMessageID, flFlags,
      ulReserved, lppMessage)
  else Result := 1;
end;

function MapiSaveMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpMessage: TMapiMessage; flFlags: FLAGS; ulReserved: Cardinal;
  lpszMessageID: StringBuilder): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiSaveMail(lhSession, ulUIParam, lpMessage, flFlags, ulReserved,
      lpszMessageID)
  else Result := 1;
end;

function MapiDeleteMail(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszMessageID: string; flFlags: FLAGS; ulReserved: Cardinal): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiDeleteMail(lhSession, ulUIParam, lpszMessageID, flFlags,
      ulReserved)
  else Result := 1;
end;

function MapiFreeBuffer(pv: IntPtr): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiFreeBuffer(pv)
  else Result := 1;
end;

function MapiAddress(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszCaption: string; nEditFields: Cardinal; lpszLabels: string;
  nRecips: Cardinal; lpRecips: IntPtr; flFlags: FLAGS;
  ulReserved: Cardinal; var lpnNewRecips: ULONG;
  var lppNewRecips: IntPtr {PMapiRecipDesc}): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiAddress(lhSession, ulUIParam, lpszCaption, nEditFields,
      lpszLabels, nRecips, lpRecips, flFlags, ulReserved, lpnNewRecips, lppNewRecips)
  else Result := 1;
end;

function MapiDetails(lhSession: LHANDLE; ulUIParam: Cardinal;
  const lpRecip: TMapiRecipDesc; flFlags: FLAGS; ulReserved: Cardinal): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiDetails(lhSession, ulUIParam, lpRecip, flFlags, ulReserved)
  else Result := 1;
end;

function MapiResolveName(lhSession: LHANDLE; ulUIParam: Cardinal;
  lpszName: string; flFlags: FLAGS; ulReserved: Cardinal;
  var lppRecip: IntPtr {PMapiRecipDesc}): Cardinal;
begin
  InitMapi;
  if MAPIAvailable then
    Result := _MapiResolveName(lhSession, ulUIParam, lpszName, flFlags,
      ulReserved, lppRecip)
  else Result := 1;
end;

end.
