You are here: Home / Support / Articles / How to avoid security prompts in Vi...

How to avoid security prompts in Visual Basic programs for Outlook

Table of contents:

  • Introduction
  • A few words about developing applications for Microsoft Outlook
  • Introduction to MAPI
  • Working with MAPI from Visual Basic without any third-party libraries
  • The components for work with MAPI
  • Working with MAPI from Visual Basic without any third-party libraries

    Notwithstanding the common opinion that there is no way to work with MAPI from Visual Basic, we dare to say to the contrary. Certainly, it is virtually impossible to access all the MAPI riches from Visual Basic, but the task of getting object properties shouldn't come difficult to an experienced developer.

    There is the following function in MAPI:

    HrGetOneProp(
    LPMAPIPROP pmp,
    ULONG ulPropTag,
    LPSPropValue FAR * ppprop
    );

    This function receives the pointer to the object interface (stored in MAPIOBJECT), tag, and returns the pointer to value. The most difficult problem here is how to deal with the returned value. In MAPI SDK it is described as follows:

    typedef struct _SPropValue
    {
    ULONG ulPropTag;
    ULONG dwAlignPad;
    union _PV Value;
    } SPropValue, FAR *LPSPropValue;

    The tag of the requested value is saved in ulPropTag as if the request was processed with no errors, and the Value union is described in MAPIDEFS.H as follows:

    typedef union _PV { short int i; /* case PT_I2 */ LONG l; /* case PT_LONG */ ULONG ul; /* alias for PT_LONG */ float flt; /* case PT_R4 */ double dbl; /* case PT_DOUBLE */ unsigned short int b; /* case PT_BOOLEAN */ CURRENCY cur; /* case PT_CURRENCY */ double at; /* case PT_APPTIME */ FILETIME ft; /* case PT_SYSTIME */ LPSTR lpszA; /* case PT_STRING8 */ SBinary bin; /* case PT_BINARY */ LPWSTR lpszW; /* case PT_UNICODE */ LPGUID lpguid; /* case PT_CLSID */ LARGE_INTEGER li; /* case PT_I8 */ SShortArray MVi; /* case PT_MV_I2 */ SLongArray MVl; /* case PT_MV_LONG */ SRealArray MVflt; /* case PT_MV_R4 */ SDoubleArray MVdbl; /* case PT_MV_DOUBLE */ SCurrencyArray MVcur; /* case PT_MV_CURRENCY */ SAppTimeArray MVat; /* case PT_MV_APPTIME */ SDateTimeArray MVft; /* case PT_MV_SYSTIME */ SBinaryArray MVbin; /* case PT_MV_BINARY */ SLPSTRArray MVszA; /* case PT_MV_STRING8 */ SWStringArray MVszW; /* case PT_MV_UNICODE */ SGuidArray MVguid; /* case PT_MV_CLSID */ SLargeIntegerArray MVli; /* case PT_MV_I8 */ SCODE err; /* case PT_ERROR */ LONG x; /* case PT_NULL, PT_OBJECT (no usable value) */ } __UPV;

    The example below was written and debugged in Visual Basic 6, and, to make it shorter, we've used a simpler description of the structure:

    Private Type SPropValue ulPropTag As Long dwAlignPad As Long val1 As Long val2 As Long val3 As Long End Type

    So, the call of HrGetOneProp creates the structure and returns the pointer to it. Once the work with the structure is completed, we must delete it, passing the pointer returned to the MAPIFreeBuffer function:

    Private Declare Function HrGetOneProp Lib "mapi32" _ Alias "HrGetOneProp@12" ( _ ByVal lpMapiProp As IUnknown, _ ByVal ulPropTag As Long, _ ByRef lppProp As Long) As Long Private Declare Function MAPIFreeBuffer Lib "mapi32" ( _ ByVal lppProp As Long) As Long

    It should also be noted that if the string properties requested are returned as ANSI-strings, before being used in Visual Basic they need to be converted into Unicode. The following code was borrowed from Chapter 6 of the book "Win32 API Programming with Visual Basic" by Steven Roman:

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ Destination As Any, Source As Any, ByVal Length As Long) Private Declare Function lstrlenA Lib "kernel32.dll" ( _ ByVal lpString As Long) As Long Private Function LPSTRtoBSTR(ByVal lpsz As Long) As String Dim cChars As Long cChars = lstrlenA(lpsz) LPSTRtoBSTR = String$(cChars, 0) CopyMemory ByVal StrPtr(LPSTRtoBSTR), ByVal lpsz, cChars LPSTRtoBSTR = Trim(StrConv(LPSTRtoBSTR, vbUnicode)) End Function

    Well, now we have everything we need to get the value of the tag PR_SENDER_EMAIL_ADDRESS we've been so keenly interested in:

    Private Sub PrintEmail() Dim objSesson As Object Dim objItem As Object Set objSession = CreateObject("MAPI.Session") objSession.Logon Set objItem = objSession.Inbox.Messages.GetFirst Dim ptrSProp As Long ptrSProp = 0 If HrGetOneProp(objItem.MAPIOBJECT, &H0C1F001E, ptrSProp) = 0 Then Dim sprop As SPropValue CopyMemory sprop, ByVal ptrSProp, 20 MsgBox LPSTRtoBSTR(sprop.val1) MAPIFreeBuffer ptrSProp End If Set objItem = Nothing Set objSession = Nothing End Sub

    The PrintEmail does the following:

    1. Creates a CDO session
    2. By the Logon request, performs a MAPI initialization (if you are using OOM, not CDO, you may have to perform this through the invocation of the function MAPIInitialize)
    3. Receives the first message in the Inbox folder of Outlook into objItem
    4. Receives the pointer to the SPropValue structure into the ptrSProp variable by the HrGetOneProp call
    5. Copies the data from the structure in the spprop variable, after which the pointer to the outcome string (in the ANSI format) appears in spprop.val1
    6. By the LPSTRtoBSTR request, converts the string into the Visual Basic format, and displays it on the screen by the MsgBox request
    7. By the MAPIFreeBuffer call, frees the memory allocated for the structure by the HrGetOneProp request
    8. Release the object and closes the CDO session

    Now, congratulations! We've managed to bypass the security system without using any third-party libraries and components. But, well, what can components offer us?


    Leave your Suggestion:
    Name:
    E-mail:
    Related links
    Support area
    Post suggestion
    Articles
    Frequently Asked Questions
    The Website uses cookies that allow us to recognize you and collect information about your user experience.

    Permission to use cookies necessary for the use of the Site and its services, including ordering services. By visiting the site, we are sure that you consent to the use and storage of cookies on your device. If you agree, continue to use the site. If not – set special settings in your browser or contact technical support.