Sie sind hier: Home / Kundensupport / FAQ und Artikel / Wie sind Sicherheitseingabeaufforde...

Wie sind Sicherheitseingabeaufforderung in Microsoft® Visual Basic® Programmen für Microsoft® Outlook zu vermeiden

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 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:

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 requested value is saved in ulPropTag 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 be also noted that if string properties requested are returned as ANSI-strings, before being used in Visual Basic they need to be converted from 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 got 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 MAPI initialization (if you are using OOM, not CDO, you may have to perform through 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 that 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?

Wünsche und Anregungen
FAQ und Artikel

Schnelle Links zu MAPILab Software:
Outlook Add-Ins
Exchange Add-Ons

Software für SharePoint
Add-ons für Microsoft Excel