|
|
#include <pch.hxx>
#include "demand.h"
#include <bmapi.h>
#define FBadCh(c) ((c) - ' ' > 64)
#define DEC(c) ((BYTE) (((c) - ' ') & 0x3f))
/* uuencode/decode a binary string */ #define ENC(c) ((BYTE) ((c) ? ((c) & 0x3f) + ' ': '`'))
int rgLeft[3] = { 0, 2, 3 };
typedef USHORT CCH;
STDAPI_(BOOL) FDecodeID(LPTSTR sz, LPBYTE pb, ULONG *pcb); STDAPI_(int) CchEncodedLine(int cb); STDAPI_(ULONG) CbOfEncoded(LPTSTR sz); ERR ErrSzToBinaryEID( LPSTR lpstrEID, ULONG * lpcbEID, LPVOID * lppvEID ); LPSTR FAR PASCAL LpstrFromBstrA( BSTR bstrSrc, LPSTR lpstrDest ); LPSTR FAR PASCAL LpstrFromBstr( BSTR bstrSrc, LPSTR lpstrDest ); int FAR PASCAL FBMAPIFreeStruct (LPVOID lpMapiIn, ULONG uCount, USHORT usFlag); ULONG PASCAL VB2Mapi( LPVOID lpVBIn, LPVOID lpMapiIn, ULONG uCount, USHORT usFlag ); LPMAPI_MESSAGE FAR PASCAL vbmsg2mapimsg( LPVB_MESSAGE lpVBMessage, LPSAFEARRAY lpsaVBRecips, LPSAFEARRAY lpsaVBFiles, ULONG * pulErr ); ERR FAR PASCAL ErrLpstrToBstrA( LPSTR cstr, BSTR * lpBstr ); ERR FAR PASCAL ErrLpstrToBstr( LPSTR cstr, BSTR * lpBstr ); STDAPI_(void) EncodeID(LPBYTE pb, ULONG cb, LPTSTR sz); STDAPI_(ULONG) CchOfEncoding(ULONG cbBinary); ERR ErrBinaryToSzEID( LPVOID lpvEID, ULONG cbEID, LPSTR * lppstrEID ); ULONG PASCAL Mapi2VB (LPVOID lpMapiIn, LPVOID lpVBIn, ULONG uCount, USHORT usFlag);
/*---------------------------------------------------------------------
* * Copyright Microsoft Corporation, 1992 * _______________________________________________________________ * * PROGRAM: BMAPI.CPP * * PURPOSE: Contains library routines VB MAPI wrappers * * FUNCTIONS: * BMAPISendMail * BMAPIFindNext * BMAPIReadMail * BMAPIGetReadMail * BMAPISaveMail * BMAPIAddress * BMAPIGetAddress * BMAPIResolveName * BMAPIDetails * * MISCELLANEOUS: * * - All BMAPI procedures basically follow the same structure as * follows; * * BMAPI_ENTRY BMAPIRoutine (...) * { * Allocate C Structures * Translate VB structures to C structures * Call MAPI Procedure * Translate C structures to VB Structures * DeAllocate C Structures * Return * } * * * REVISION HISTORY: * * - Last modified by v-snatar * * * _____________________________________________________________ * * Copyright Microsoft Corporation, 1992-1997 * *----------------------------------------------------------------------*/
//---------------------------------------------------------------------------
// Name: BMAPISendMail()
//
// Description:
// 32 bit support for VB MAPISendMail().
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPISendMail (LHANDLE hSession, ULONG_PTR ulUIParam, LPVB_MESSAGE lpM, LPSAFEARRAY * lppsaRecips, LPSAFEARRAY * lppsaFiles, ULONG flFlags, ULONG ulReserved) { ULONG ulRet = SUCCESS_SUCCESS; LPMAPI_MESSAGE lpMail = NULL;
// Translate VB data into C data.
if ((lpMail = vbmsg2mapimsg( lpM, *lppsaRecips, *lppsaFiles, &ulRet )) == NULL) return ulRet;
// Call MAPI Procedure
ulRet = MAPISendMail( hSession, // session
ulUIParam, // UIParam
lpMail, // Mail
flFlags, // Flags
ulReserved ); // Reserved
// Free up data allocated by call to vbmsg2mapimsg
FBMAPIFreeStruct(lpMail, 1, MESSAGE); return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPIFindNext()
//
// Description:
// Implements FindNext MAPI API.
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPIFindNext( LHANDLE hSession, // Session
ULONG_PTR ulUIParam, // UIParam
BSTR * lpbstrType, // MessageType
BSTR * lpbstrSeed, // Seed message Id
ULONG flFlags, // Flags
ULONG ulReserved, // Reserved
BSTR * lpbstrId) // Message Id (in/out)
{ ULONG ulRet; LPSTR lpID = NULL; LPSTR lpSeed; LPSTR lpTypeArg;
// Translate VB strings into C strings. We'll deallocate
// the strings before we return.
// Always allocate the MessageID string. This way we can redimension
// it to fit the returned size. We'll never use the caller's buffer.
// It turns out the VBSetHlstr call (from ErrLpstrToHlstr) will reassign
// the string for us.
if (!MemAlloc((LPVOID*)&lpID, 513)) return MAPI_E_INSUFFICIENT_MEMORY;
lpSeed = LpstrFromBstrA( *lpbstrSeed, NULL); lpTypeArg = LpstrFromBstrA( *lpbstrType, NULL);
// Call MAPI Procedure
ulRet = MAPIFindNext( hSession, // Session
ulUIParam, // UIParam
lpTypeArg, // Message Type
lpSeed, // Seed Message Id
flFlags, // Flags,
ulReserved, // Reserved
lpID ); // Message ID
// Translate Message ID into VB string
if ( ulRet == SUCCESS_SUCCESS ) ErrLpstrToBstrA( lpID, lpbstrId);
// Free up C strings allocated by call to LpstrFromHlstr
SafeMemFree( lpID ); SafeMemFree( lpSeed ); SafeMemFree( lpTypeArg );
return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPIReadMail()
//
// Description:
//
// Implements MAPIReadMail VB API. The memory allocated by
// MAPIReadMail is NOT deallocated (with MAPIFreeBuffer) until
// the caller calls BMAPIGetReadMail. The recipient and file
// count is returned so that the caller can Re-dimension buffers
// before calling BMAPI GetReadMail. A long pointer to the
// ReadMail data is also returned since it is required in the
// BAMPIGetReadMail call.
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPIReadMail( PULONG_PTR lpulMessage, // pointer to output data (out)
LPULONG nRecips, // number of recipients (out)
LPULONG nFiles, // number of file attachments (out)
LHANDLE hSession, // Session
ULONG_PTR ulUIParam, // UIParam
BSTR * lpbstrID, // Message Id
ULONG flFlags, // Flags
ULONG ulReserved ) // Reserved
{ LPSTR lpID; ULONG ulRet; LPMAPI_MESSAGE lpMail = NULL;
// Translate VB String to C String
lpID = LpstrFromBstrA( *lpbstrID, NULL );
// Read the message, lpMail is set by MAPI to point
// to the memory allocated by MAPI.
ulRet = MAPIReadMail( hSession, // Session
ulUIParam, // UIParam
lpID, // Message Id
flFlags, // Flags
ulReserved, // Reserved
&lpMail ); // Pointer to MAPI Data (returned)
// Check for read error return code
if ( ulRet != SUCCESS_SUCCESS ) { // Clean up. Set return message to zero
*lpulMessage = 0L; SafeMemFree( lpID ); return ulRet; }
// Pull out the recipient and file array re-dim info
*nFiles = lpMail->nFileCount; *nRecips = lpMail->nRecipCount; *lpulMessage = (ULONG_PTR) (LPVOID) lpMail;
SafeMemFree( lpID ); return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPIGetReadMail()
//
// Description:
//
// Copies data stored by MAPI ReadMail (see BMAPIReadMail)
// into a VB Buffer passed by the caller. It is up to the
// caller to make sure the buffer passed is large enough to
// accomodate the data.
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPIGetReadMail( ULONG lpMessage, // Pointer to MAPI Mail
LPVB_MESSAGE lpvbMessage, // Pointer to VB Message Buffer (out)
LPSAFEARRAY * lppsaRecips, // Pointer to VB Recipient Buffer (out)
LPSAFEARRAY * lppsaFiles, // Pointer to VB File attachment Buffer (out)
LPVB_RECIPIENT lpvbOrig) // Pointer to VB Originator Buffer (out)
{ ULONG ulRet = SUCCESS_SUCCESS; ERR errVBrc; LPMAPI_MESSAGE lpMail;
lpMail = (LPMAPI_MESSAGE)((ULONG_PTR)lpMessage); if ( !lpMail ) return MAPI_E_INSUFFICIENT_MEMORY;
// copy Attachment info to callers VB Buffer
if (ulRet = Mapi2VB( lpMail->lpFiles, *lppsaFiles, lpMail->nFileCount, FILE )) { MAPIFreeBuffer(lpMail); return ulRet; }
// copy Recipient info to callers VB Buffer
if ( ulRet = Mapi2VB( lpMail->lpRecips, *lppsaRecips, lpMail->nRecipCount, RECIPIENT | USESAFEARRAY ) ) { MAPIFreeBuffer( lpMail ); return ulRet; }
// Copy MAPI Message to callers VB Buffer
errVBrc = 0;
if ( lpMail->lpOriginator ) { lpvbOrig->ulReserved = lpMail->lpOriginator->ulReserved; lpvbOrig->ulRecipClass = MAPI_ORIG;
if ( lpMail->lpOriginator->lpszName ) errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpOriginator->lpszName, &lpvbOrig->bstrName ));
if ( lpMail->lpOriginator->lpszAddress ) errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpOriginator->lpszAddress, &lpvbOrig->bstrAddress ));
if (lpMail->lpOriginator->ulEIDSize) { LPSTR lpStrEID;
// Hexize recipient EID and convert to OLE BSTR
if ( ErrBinaryToSzEID( lpMail->lpOriginator->lpEntryID, lpMail->lpOriginator->ulEIDSize, &lpStrEID ) ) { errVBrc = TRUE; goto exit; }
// To figure out size first convert to UNICODE
errVBrc = ErrLpstrToBstr( lpStrEID, &lpvbOrig->bstrEID ); if ( errVBrc ) { goto exit_orig; }
lpvbOrig->ulEIDSize = SysStringByteLen( lpvbOrig->bstrEID ) + sizeof(OLECHAR);
SysFreeString( lpvbOrig->bstrEID );
errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpStrEID, &lpvbOrig->bstrEID ));
exit_orig:
SafeMemFree( lpStrEID ); } }
lpvbMessage->flFlags = lpMail->flFlags; lpvbMessage->ulReserved = lpMail->ulReserved; lpvbMessage->nRecipCount = lpMail->nRecipCount; lpvbMessage->nFileCount = lpMail->nFileCount;
if (lpMail->lpszSubject) errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszSubject, &lpvbMessage->bstrSubject));
if (lpMail->lpszNoteText) errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszNoteText, &lpvbMessage->bstrNoteText));
if (lpMail->lpszMessageType) errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszMessageType, &lpvbMessage->bstrMessageType));
if (lpMail->lpszDateReceived) errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszDateReceived, &lpvbMessage->bstrDate));
exit:
MAPIFreeBuffer( lpMail );
if ( errVBrc ) ulRet = MAPI_E_FAILURE;
return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPISaveMail()
//
// Description:
// Implements MAPISaveMail API.
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPISaveMail( LHANDLE hSession, // Session
ULONG_PTR ulUIParam, // UIParam
LPVB_MESSAGE lpM, // Pointer to VB Message Buffer
LPSAFEARRAY * lppsaRecips, // Pointer to VB Recipient Buffer
LPSAFEARRAY * lppsaFiles, // Pointer to VB File Attacment Buffer
ULONG flFlags, // Flags
ULONG ulReserved, // Reserved
BSTR * lpbstrID) // Message ID
{ LPSTR lpID; ULONG ulRet= SUCCESS_SUCCESS; LPMAPI_MESSAGE lpMail;
// Translate VB data to MAPI data
lpID = LpstrFromBstrA( *lpbstrID, NULL );
// If we allocate Message ID then we can set the flag.
// otherwise for backward compatability assume the callers buffer size.
if ( lpID == NULL ) { if (!MemAlloc((LPVOID*)&lpID, 513)) return MAPI_E_INSUFFICIENT_MEMORY; }
if ( (lpMail = vbmsg2mapimsg( lpM, *lppsaRecips, *lppsaFiles, &ulRet )) == NULL ) { SafeMemFree( lpID ); return ulRet; }
ulRet = MAPISaveMail( hSession, ulUIParam, lpMail, flFlags, ulReserved, lpID );
if ( ulRet ) goto exit;
if ( ErrLpstrToBstrA( lpID, lpbstrID ) ) ulRet = MAPI_E_INSUFFICIENT_MEMORY;
exit: SafeMemFree( lpID ); FBMAPIFreeStruct( lpMail, 1, MESSAGE );
return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPIAddress()
//
// Description:
//
// Purpose: Allows Visual Basic to call MAPIAddress. The
// Recipient data is stored in a global memory block. To
// retrieve the data the caller must call BMAPIGetAddress.
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPIAddress( PULONG_PTR lpulRecip, // Pointer to New Recipient Buffer (out)
LHANDLE hSession, // Session
ULONG_PTR ulUIParam, // UIParam
BSTR * lpbstrCaption, // Caption string
ULONG ulEditFields, // Number of Edit Controls
BSTR * lpbstrLabel, // Label string
LPULONG lpulRecipients, // Pointer to number of Recipients (in/out)
LPSAFEARRAY * lppsaRecip, // Pointer to Initial Recipients VB_RECIPIENT
ULONG ulFlags, // Flags
ULONG ulReserved ) // Reserve
{ LPSTR lpLabel = NULL; LPSTR lpCaption = NULL; ULONG ulRet; ULONG nRecipients = 0; LPMAPI_RECIPIENT lpMapi = NULL; LPMAPI_RECIPIENT lpNewRecipients = NULL;
// Convert VB Strings to C strings
lpLabel = LpstrFromBstrA( *lpbstrLabel, NULL ); lpCaption = LpstrFromBstrA( *lpbstrCaption, NULL );
// Allocate memory and translate VB_RECIPIENTS to MAPI_RECIPIENTS.
if ( *lpulRecipients ) { if (!MemAlloc((LPVOID*)&lpMapi, (*lpulRecipients * sizeof (MAPI_RECIPIENT)))) return MAPI_E_INSUFFICIENT_MEMORY; }
if ( ulRet = VB2Mapi( (LPVOID)*lppsaRecip, (LPVOID)lpMapi, *lpulRecipients, RECIPIENT | USESAFEARRAY ) ) { SafeMemFree( lpLabel ); SafeMemFree( lpCaption ); FBMAPIFreeStruct( lpMapi, *lpulRecipients, RECIPIENT ); return ulRet; }
// Call the MAPIAddress function
ulRet = MAPIAddress( hSession, // Session
ulUIParam, // UIParam
lpCaption, // Caption
ulEditFields, // Number of edit fields
lpLabel, // Label
*lpulRecipients, // Number of Recipients
lpMapi, // Pointer to recipients
ulFlags, // Flags
ulReserved, // Reserved
(LPULONG) &nRecipients, // Address for new recipient count
(lpMapiRecipDesc far *)&lpNewRecipients); // Address of new recipient data
// Free up MAPI structures created in this procedure
SafeMemFree( lpLabel ); SafeMemFree( lpCaption ); FBMAPIFreeStruct( lpMapi, *lpulRecipients, RECIPIENT );
// Set the returned parameters and return
if ( ulRet == SUCCESS_SUCCESS ) { *lpulRecipients = nRecipients; *lpulRecip = (ULONG_PTR) (LPVOID) lpNewRecipients; }
return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPIGetAddress()
//
// Description:
// Converts a MapiRecipDesc array into an OLE 2.0 SAFEARRAY.
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPIGetAddress (ULONG ulRecipientData, // Pointer to recipient data
ULONG cRecipients, // Number of recipients
LPSAFEARRAY * lppsaRecips ) // VB recipient array
{ ULONG ulRet = SUCCESS_SUCCESS; LPMAPI_RECIPIENT lpData = NULL;
if (cRecipients == 0) { MAPIFreeBuffer( (LPVOID)((ULONG_PTR)ulRecipientData) ); return SUCCESS_SUCCESS; }
lpData = (LPMAPI_RECIPIENT)((ULONG_PTR)ulRecipientData);
// Translate MAPI Address data to VB buffer
ulRet = Mapi2VB( lpData, *lppsaRecips, cRecipients, RECIPIENT | USESAFEARRAY );
// Free up MAPI recipient data since it got copied over.
MAPIFreeBuffer( lpData ); return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPIDetails()
//
// Description:
// Allows VB to call MAPIDetails procedure.
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPIDetails (LHANDLE hSession, // Session
ULONG_PTR ulUIParam, // UIParam
LPVB_RECIPIENT lpVB, // Pointer to VB recipient stucture
ULONG ulFlags, // Flags
ULONG ulReserved) // Reserved
{ ULONG ulRet; LPMAPI_RECIPIENT lpMapi = NULL;
// Translate VB_RECIPIENTS to MAPI_RECIPIENTS.
if (!MemAlloc((LPVOID*)&lpMapi,sizeof (MAPI_RECIPIENT))) return MAPI_E_INSUFFICIENT_MEMORY;
if ( ulRet = VB2Mapi( lpVB, lpMapi, 1, RECIPIENT ) ) { FBMAPIFreeStruct( lpMapi, 1, RECIPIENT ); return ulRet; }
// Call the Simple MAPI function
ulRet = MAPIDetails( hSession, // Session
ulUIParam, // UIParam
lpMapi, // Pointer to MAPI Recipient structure
ulFlags, // Flags
ulReserved ); // Reserved
FBMAPIFreeStruct( lpMapi, 1L, RECIPIENT ); return ulRet; }
//---------------------------------------------------------------------------
// Name: BMAPIResolveName
//
// Description:
// Implements VB MAPIResolveName
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
BMAPI_ENTRY BMAPIResolveName (LHANDLE hSession, // Session
ULONG_PTR ulUIParam, // UIParam
BSTR bstrMapiName, // Name to be resolved
ULONG ulFlags, // Flags
ULONG ulReserved, // Reserved
LPVB_RECIPIENT lpVB) // Pointer to VB recipient structure (out)
{ LPMAPI_RECIPIENT lpMapi = NULL; ULONG ulRet; LPSTR lpszMapiName;
lpszMapiName = LpstrFromBstrA( bstrMapiName, NULL );
// Call the MAPIResolveName function
ulRet = MAPIResolveName( hSession, // Session
ulUIParam, // UIParam
lpszMapiName, // Pointer to resolve name
ulFlags, // Flags
ulReserved, // Reserved
(LPPMAPI_RECIPIENT) &lpMapi ); // Pointer to Recipient (returned)
if (ulRet != SUCCESS_SUCCESS) return ulRet;
// Translate MAPI data to VB data
ulRet = Mapi2VB( lpMapi, lpVB, 1, RECIPIENT );
MAPIFreeBuffer( lpMapi ); return ulRet; }
// Helper Functions
//---------------------------------------------------------------------------
// Name: vbmsg2mapimsg()
//
// Description:
// Translates VB Message structure to MAPI Message structure
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
LPMAPI_MESSAGE FAR PASCAL vbmsg2mapimsg( LPVB_MESSAGE lpVBMessage, LPSAFEARRAY lpsaVBRecips, LPSAFEARRAY lpsaVBFiles, ULONG * pulErr )
{ LPMAPI_FILE lpMapiFile=NULL; LPMAPI_MESSAGE lpMapiMessage=NULL; LPMAPI_RECIPIENT lpMapiRecipient=NULL;
if (lpVBMessage == (LPVB_MESSAGE) NULL) { *pulErr = MAPI_E_FAILURE; return NULL; }
// Allocate MAPI Message, Recipient and File structures
// NOTE: Don't move the following lines of code without
// making sure you de-allocate memory properly if the
// calls fail.
if (!MemAlloc((LPVOID*)&lpMapiMessage,sizeof(MapiMessage))) { *pulErr = MAPI_E_INSUFFICIENT_MEMORY; return NULL; }
if (lpVBMessage->nFileCount > 0) { if (!MemAlloc((LPVOID*)&lpMapiFile, sizeof(MAPI_FILE)*lpVBMessage->nFileCount)) { FBMAPIFreeStruct( (LPVOID*)&lpMapiMessage, 1, MESSAGE ); *pulErr = MAPI_E_INSUFFICIENT_MEMORY; return NULL; } }
if (lpVBMessage->nRecipCount > 0) { if (!MemAlloc((LPVOID*)&lpMapiRecipient, sizeof(MAPI_RECIPIENT)*lpVBMessage->nRecipCount)) { FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE ); FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE ); *pulErr = MAPI_E_INSUFFICIENT_MEMORY; return NULL; } }
// Translate structures from VB to MAPI
if ( *pulErr = VB2Mapi( lpsaVBFiles, lpMapiFile, lpVBMessage->nFileCount, FILE | USESAFEARRAY ) ) { FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE ); FBMAPIFreeStruct( lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT ); FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE ); return NULL; }
if ( *pulErr = VB2Mapi( lpsaVBRecips, lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT | USESAFEARRAY ) ) { FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE ); FBMAPIFreeStruct( lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT ); FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE ); return NULL; }
if ( *pulErr = VB2Mapi( lpVBMessage, lpMapiMessage, 1, MESSAGE ) ) { FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE ); FBMAPIFreeStruct( lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT ); FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE ); return NULL; }
// Chain File and Recipient structures to Message structure
lpMapiMessage->lpFiles = lpMapiFile; lpMapiMessage->lpRecips = lpMapiRecipient;
return lpMapiMessage; }
//---------------------------------------------------------------------------
// Name: VB2Mapi()
//
// Description:
// Converts VB structures to MAPI structures. Arrays from
// VB 4.0 arrive as OLE SAFEARRAYs.
//
// Parameters:
// Returns:
// Simple MAPI error code
//
// Effects:
// Notes:
// originally FALSE for failure, TRUE for success.
// Revision:
//---------------------------------------------------------------------------
ULONG PASCAL VB2Mapi( LPVOID lpVBIn, LPVOID lpMapiIn, ULONG uCount, USHORT usFlag ) { ULONG u; HRESULT hr = 0; ULONG ulErr = SUCCESS_SUCCESS; ERR Err = FALSE; LPVB_RECIPIENT lpVBR; LPMAPI_RECIPIENT lpMapiR; LPVB_MESSAGE lpVBM; LPMAPI_MESSAGE lpMapiM; LPVB_FILE lpVBF; LPMAPI_FILE lpMapiF; LPSAFEARRAY lpsa = NULL;
if (lpVBIn == (LPVOID)NULL) { lpMapiIn = NULL; return SUCCESS_SUCCESS; }
if (uCount <= 0) { lpMapiIn = NULL; return SUCCESS_SUCCESS; }
if ( lpMapiIn == (LPVOID)NULL ) return MAPI_E_FAILURE;
switch ( usFlag & ~(USESAFEARRAY) ) { case RECIPIENT: if ( usFlag & USESAFEARRAY ) { lpsa = (LPSAFEARRAY)lpVBIn; hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBR ); if (hr) { ulErr = MAPI_E_FAILURE; goto exit; }
if (!lpVBR || lpsa->rgsabound[0].cElements < uCount) { (void)SafeArrayUnaccessData( lpsa ); ulErr = MAPI_E_INVALID_RECIPS; goto exit; } } else { lpVBR = (LPVB_RECIPIENT)lpVBIn; }
lpMapiR = (LPMAPI_RECIPIENT)lpMapiIn;
for ( u = 0L; u < uCount; u++, lpMapiR++, lpVBR++ ) { lpMapiR->ulReserved = lpVBR->ulReserved; lpMapiR->ulRecipClass = lpVBR->ulRecipClass;
if ( usFlag & USESAFEARRAY ) { lpMapiR->lpszName = LpstrFromBstr( lpVBR->bstrName, NULL ); lpMapiR->lpszAddress = LpstrFromBstr( lpVBR->bstrAddress, NULL ); } else { lpMapiR->lpszName = LpstrFromBstrA( lpVBR->bstrName, NULL ); lpMapiR->lpszAddress = LpstrFromBstrA( lpVBR->bstrAddress, NULL ); }
if (lpVBR->ulEIDSize > 0L) { LPSTR lpStrT;
// Convert EID string from OLE Bstr...
if ( usFlag & USESAFEARRAY ) { if ( IsBadReadPtr( lpVBR->bstrEID, lpVBR->ulEIDSize ) ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
lpStrT = LpstrFromBstr( lpVBR->bstrEID, NULL ); } else { // VB 4.0 took care of translating Wide Char to Multibyte.
// ulEIDSize is still based on UNICODE byte size. Take
// smallest approximation.
if ( IsBadReadPtr( lpVBR->bstrEID, lpVBR->ulEIDSize / 2 ) ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
lpStrT = LpstrFromBstrA( lpVBR->bstrEID, NULL ); }
// and UnHexize.
if ( lpStrT ) { Err = ErrSzToBinaryEID( lpStrT, &lpMapiR->ulEIDSize, &lpMapiR->lpEntryID );
SafeMemFree(lpStrT );
if ( Err ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
} } else lpMapiR->lpEntryID = (LPVOID) NULL; }
if ( usFlag & USESAFEARRAY ) (void)SafeArrayUnaccessData( lpsa );
break;
case FILE: lpsa = (LPSAFEARRAY)lpVBIn; hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBF ); if ( hr ) { ulErr = MAPI_E_FAILURE; goto exit; }
if ( !lpVBF || lpsa->rgsabound[0].cElements < uCount ) { (void)SafeArrayUnaccessData( lpsa ); ulErr = MAPI_E_ATTACHMENT_NOT_FOUND; goto exit; }
lpMapiF = (LPMAPI_FILE)lpMapiIn;
for (u = 0L; u < uCount; u++, lpMapiF++, lpVBF++) { lpMapiF->ulReserved = lpVBF->ulReserved; lpMapiF->flFlags = lpVBF->flFlags; lpMapiF->nPosition = lpVBF->nPosition; lpMapiF->lpszPathName = LpstrFromBstr( lpVBF->bstrPathName, NULL ); lpMapiF->lpszFileName = LpstrFromBstr( lpVBF->bstrFileName, NULL ); lpMapiF->lpFileType = LpstrFromBstr( lpVBF->bstrFileType, NULL); }
(void)SafeArrayUnaccessData( lpsa );
break;
case MESSAGE: lpVBM = (LPVB_MESSAGE) lpVBIn; lpMapiM = (LPMAPI_MESSAGE) lpMapiIn;
lpMapiM->ulReserved = lpVBM->ulReserved; lpMapiM->flFlags = lpVBM->flFlags; lpMapiM->nRecipCount = lpVBM->nRecipCount; lpMapiM->lpOriginator = NULL; lpMapiM->nFileCount = lpVBM->nFileCount; lpMapiM->lpRecips = NULL; lpMapiM->lpFiles = NULL;
// errors are ignored
lpMapiM->lpszSubject = LpstrFromBstrA( lpVBM->bstrSubject, NULL ); lpMapiM->lpszNoteText = LpstrFromBstrA( lpVBM->bstrNoteText, NULL ); lpMapiM->lpszConversationID = LpstrFromBstrA( lpVBM->bstrConversationID, NULL ); lpMapiM->lpszDateReceived = LpstrFromBstrA( lpVBM->bstrDate, NULL ); lpMapiM->lpszMessageType = LpstrFromBstrA( lpVBM->bstrMessageType, NULL );
break;
default: ulErr = MAPI_E_FAILURE; goto exit; }
exit:
return ulErr; }
//---------------------------------------------------------------------------
// Name: Mapi2VB
//
// Description:
// Converts MAPI RECIPIENT, FILE, or MESSAGE structures to VB
// Recipients and Files are handled as OLE SAFEARRAYs.
//
// Parameters:
// Returns:
// Simple Mapi error code
//
// Effects:
// Notes:
// originally FALSE for failure, TRUE for success.
// Revision:
//---------------------------------------------------------------------------
ULONG PASCAL Mapi2VB (LPVOID lpMapiIn, LPVOID lpVBIn, ULONG uCount, USHORT usFlag) { HRESULT hr = 0; ERR Err = FALSE; ULONG ulErr = SUCCESS_SUCCESS; ULONG u; LPVB_MESSAGE lpVBM; LPMAPI_MESSAGE lpMapiM; LPVB_RECIPIENT lpVBR; LPMAPI_RECIPIENT lpMapiR; LPVB_FILE lpVBF; LPMAPI_FILE lpMapiF; LPSAFEARRAY lpsa = NULL;
// If lpVBIn is NULL, this is a bad thing
if (lpVBIn == (LPVOID) NULL) return MAPI_E_FAILURE;
// if lpMapiIn is NULL then set
// lpVBIn to NULL and return success
if (lpMapiIn == NULL) { lpVBIn = NULL; return SUCCESS_SUCCESS; }
switch ( usFlag & ~(USESAFEARRAY) ) { case RECIPIENT: if ( usFlag & USESAFEARRAY ) { lpsa = (LPSAFEARRAY)lpVBIn; hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBR ); if (hr) { ulErr = MAPI_E_FAILURE; goto exit; }
if ( !lpVBR || lpsa->rgsabound[0].cElements < uCount ) { (void)SafeArrayUnaccessData(lpsa); ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
} else { lpVBR = (LPVB_RECIPIENT)lpVBIn; }
lpMapiR = (LPMAPI_RECIPIENT)lpMapiIn;
for (u = 0L; u < uCount; u++, lpMapiR++, lpVBR++) { lpVBR->ulReserved = lpMapiR->ulReserved; lpVBR->ulRecipClass = lpMapiR->ulRecipClass;
if (usFlag & USESAFEARRAY) { if ( ErrLpstrToBstr( lpMapiR->lpszName, &lpVBR->bstrName ) ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
if (Err = ErrLpstrToBstr( lpMapiR->lpszAddress, &lpVBR->bstrAddress ) ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; } } else { if ( ErrLpstrToBstrA( lpMapiR->lpszName, &lpVBR->bstrName ) ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
if ( ErrLpstrToBstrA( lpMapiR->lpszAddress, &lpVBR->bstrAddress ) ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; } }
if ( lpMapiR->ulEIDSize > 0L) { LPSTR lpStrEID;
// Convert Recip EID to a hexized string
if ( ErrBinaryToSzEID( lpMapiR->lpEntryID, lpMapiR->ulEIDSize, &lpStrEID ) ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
// Convert to a BSTR
// and figure out the size
if ( usFlag & USESAFEARRAY ) { Err = ErrLpstrToBstr( lpStrEID, &lpVBR->bstrEID ); SafeMemFree( lpStrEID );
if (Err) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
lpVBR->ulEIDSize = SysStringByteLen( lpVBR->bstrEID ) + sizeof(OLECHAR); } else { // To figure out size first convert to UNICODE
if ( ErrLpstrToBstr( lpStrEID, &lpVBR->bstrEID ) ) { SafeMemFree( lpStrEID ); ulErr = MAPI_E_INVALID_RECIPS; goto exit; }
lpVBR->ulEIDSize = SysStringByteLen( lpVBR->bstrEID ) + sizeof(OLECHAR);
SysFreeString( lpVBR->bstrEID );
Err = ErrLpstrToBstrA( lpStrEID, &lpVBR->bstrEID ); SafeMemFree( lpStrEID ); if ( Err ) { ulErr = MAPI_E_INVALID_RECIPS; goto exit; } } } }
if ( usFlag & USESAFEARRAY ) (void)SafeArrayUnaccessData( lpsa );
break;
case FILE: lpsa = (LPSAFEARRAY)lpVBIn; hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBF ); if ( hr ) { ulErr = MAPI_E_FAILURE; goto exit; }
if ( !lpVBF || lpsa->rgsabound[0].cElements < uCount ) { (void)SafeArrayUnaccessData( lpsa ); ulErr = MAPI_E_FAILURE; goto exit; }
lpMapiF = (LPMAPI_FILE) lpMapiIn;
for (u = 0L; u < uCount; u++, lpMapiF++, lpVBF++) { lpVBF->ulReserved = lpMapiF->ulReserved; lpVBF->flFlags = lpMapiF->flFlags; lpVBF->nPosition = lpMapiF->nPosition;
if ( ErrLpstrToBstr( lpMapiF->lpszPathName, &lpVBF->bstrPathName ) ) { ulErr = MAPI_E_ATTACHMENT_NOT_FOUND; goto exit; }
if ( ErrLpstrToBstr( lpMapiF->lpszFileName, &lpVBF->bstrFileName ) ) { ulErr = MAPI_E_ATTACHMENT_NOT_FOUND; goto exit; }
// this is something to keep VBAPI from faulting
if ( ErrLpstrToBstr( (LPSTR) "", &lpVBF->bstrFileType ) ) { ulErr = MAPI_E_ATTACHMENT_NOT_FOUND; goto exit; } }
(void)SafeArrayUnaccessData( lpsa );
break;
case MESSAGE: lpVBM = (LPVB_MESSAGE)lpVBIn; lpMapiM = (LPMAPI_MESSAGE)lpMapiIn;
lpVBM->ulReserved = lpMapiM->ulReserved; lpVBM->flFlags = lpMapiM->flFlags; lpVBM->nRecipCount = lpMapiM->nRecipCount; lpVBM->nFileCount = lpMapiM->nFileCount;
if ( ErrLpstrToBstr( lpMapiM->lpszSubject, &lpVBM->bstrSubject ) ) { ulErr = MAPI_E_INVALID_MESSAGE; goto exit; }
if ( ErrLpstrToBstr( lpMapiM->lpszNoteText, &lpVBM->bstrNoteText ) ) { ulErr = MAPI_E_INVALID_MESSAGE; goto exit; }
if ( ErrLpstrToBstr( lpMapiM->lpszConversationID, &lpVBM->bstrConversationID ) ) { ulErr = MAPI_E_INVALID_MESSAGE; goto exit; }
if ( ErrLpstrToBstr( lpMapiM->lpszDateReceived, &lpVBM->bstrDate ) ) { ulErr = MAPI_E_INVALID_MESSAGE; goto exit; }
if ( ErrLpstrToBstr( lpMapiM->lpszMessageType, &lpVBM->bstrMessageType ) ) { ulErr = MAPI_E_INVALID_MESSAGE; goto exit; }
break;
default: ulErr = MAPI_E_FAILURE; goto exit; }
exit: return ulErr; }
//---------------------------------------------------------------------------
// Name: FBMAPIFreeStruct()
//
// Description:
// DeAllocates MAPI structure created in VB2MAPI
//
// Parameters:
// Returns:
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
int FAR PASCAL FBMAPIFreeStruct (LPVOID lpMapiIn, ULONG uCount, USHORT usFlag) { ULONG u; LPMAPI_RECIPIENT lpMapiR; LPMAPI_FILE lpMapiF; LPMAPI_MESSAGE lpMapiM;
if (lpMapiIn == (LPVOID) NULL) return TRUE;
switch ( usFlag ) { case RECIPIENT: lpMapiR = (LPMAPI_RECIPIENT)lpMapiIn;
for ( u = 0L; u < uCount; u++, lpMapiR++ ) { SafeMemFree(lpMapiR->lpszName); SafeMemFree(lpMapiR->lpszAddress); SafeMemFree(lpMapiR->lpEntryID); }
SafeMemFree(lpMapiIn); break;
case FILE: lpMapiF = (LPMAPI_FILE) lpMapiIn;
for ( u = 0L; u < uCount; u++, lpMapiF++ ) { SafeMemFree(lpMapiF->lpszPathName); SafeMemFree(lpMapiF->lpszFileName); SafeMemFree(lpMapiF->lpFileType); }
SafeMemFree(lpMapiIn); break;
case MESSAGE: lpMapiM = ( LPMAPI_MESSAGE ) lpMapiIn;
if (lpMapiM->lpRecips) FBMAPIFreeStruct((LPVOID)lpMapiM->lpRecips, lpMapiM->nRecipCount, RECIPIENT);
if (lpMapiM->lpFiles) FBMAPIFreeStruct((LPVOID) lpMapiM->lpFiles, lpMapiM->nFileCount, FILE);
SafeMemFree( lpMapiM->lpszSubject ); SafeMemFree( lpMapiM->lpszNoteText ); SafeMemFree( lpMapiM->lpszMessageType ); SafeMemFree( lpMapiM->lpszDateReceived ); SafeMemFree( lpMapiM->lpszConversationID ); SafeMemFree( lpMapiM ); break;
default: return FALSE; }
return TRUE; }
//---------------------------------------------------------------------------
// Name: LpstrFromBstr()
//
// Description:
// Copies and converts OLE Bstr from UNICODE to an ANSI
// C string.
//
// Parameters:
// Returns:
// String if successful
// NULL if failure
// Effects:
// Notes:
// Note that this function returns NULL for failure as well as
// a NULL bstr. This was how the original VB 3.0 implementation
// worked.
//
// Revision:
//---------------------------------------------------------------------------
LPSTR FAR PASCAL LpstrFromBstr( BSTR bstrSrc, LPSTR lpstrDest ) { USHORT cbSrc;
if ( !bstrSrc ) return NULL;
// Copy over the bstr string to a 'C' string
cbSrc = (USHORT)SysStringLen((OLECHAR *)bstrSrc);
if (cbSrc == 0) return NULL;
// make sure we handle truly multi byte character sets when
// we convert from UNICODE to MultiByte.
cbSrc = (USHORT)((cbSrc + 1) * sizeof(OLECHAR));
// If Destination is NULL then we'll allocate
// memory to hold the string. The caller must
// deallocate this at some time.
if ( lpstrDest == NULL ) { if(!MemAlloc((LPVOID*)&lpstrDest, cbSrc)) return NULL; }
if (!WideCharToMultiByte(CP_ACP, 0, bstrSrc, -1, lpstrDest, cbSrc, NULL, NULL)) { SafeMemFree(lpstrDest); lpstrDest = NULL; }
return lpstrDest; }
//---------------------------------------------------------------------------
// Name: LpstrFromBstrA
//
// Description:
// Copies OLE Bstre ANSI string to C string. Allocates string space
// from the global heap and returns a long
// pointer to memory. The memory must be freed by the caller
// with a call to BMAPIFree.
//
// Parameters:
// Returns:
// String if successful
// NULL if failure
//
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
LPSTR FAR PASCAL LpstrFromBstrA( BSTR bstrSrc, LPSTR lpstrDest ) { USHORT cbSrc;
// If Destination is NULL then we'll allocate memory to hold the
// string. The caller must deallocate this at some time.
cbSrc = (USHORT)SysStringByteLen((OLECHAR *)bstrSrc);
// Copy over the hlstr string to a 'C' string
if ( cbSrc == 0 ) return NULL;
if ( lpstrDest == NULL ) { if (!MemAlloc((LPVOID*)&lpstrDest, cbSrc + 1)) return NULL; }
memcpy( lpstrDest, bstrSrc, cbSrc ); lpstrDest[cbSrc] = '\0';
return lpstrDest; }
//---------------------------------------------------------------------------
// Name: ErrSzToBinaryEID()
//
// Description:
// Converts a hexized binary string to binary returning
// the binary data and the size of the data.
//
// Parameters:
// Returns:
// FALSE if success.
// TRUE if failure.
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
ERR ErrSzToBinaryEID( LPSTR lpstrEID, ULONG * lpcbEID, LPVOID * lppvEID ) { ERR Err = FALSE; ULONG cbEID;
cbEID = CbOfEncoded( lpstrEID ); if (!MemAlloc(lppvEID, cbEID)) { Err = TRUE; goto exit; }
if (!FDecodeID( lpstrEID, (LPBYTE)*lppvEID, lpcbEID ) ) { Err = TRUE; SafeMemFree( *lppvEID ); *lppvEID = NULL; goto exit; }
exit:
return Err; }
/*
* Given an string that encodes some binary data, returns the * maximal size of the binary data. */ STDAPI_(ULONG) CbOfEncoded(LPTSTR sz) { return (lstrlen(sz) / 4 + 1) * 3; // slightly fat
}
/*
* Given a byte count, returns the number of characters necessary * to encode that many bytes. */ STDAPI_(int) CchEncodedLine(int cb) { Assert(cb <= 45); return (cb / 3) * 4 + rgLeft[cb % 3]; }
/*
- FDecodeID - * Purpose: * Turns a character string produced by EncodeID back to a * byte string. Some validation of the input string is done. * * Arguments: * sz in The input character string. * pb out The decoded byte string. The output * string is not length-checked. * pcb out The size of the byte string * * Returns: * FALSE => the encoded string was garbled in some way * TRUE => all OK */ STDAPI_(BOOL) FDecodeID(LPTSTR sz, LPBYTE pb, ULONG *pcb) { int cchLine; int ich; CCH cch = (CCH)lstrlen(sz); LPTSTR szT = sz;
AssertSz(!IsBadStringPtr(sz, INFINITE), "FDecodeID: sz fails address check"); AssertSz(!IsBadWritePtr(pb, 1), "FDecodeID: pb fails address check"); AssertSz(!IsBadWritePtr(pcb, sizeof(ULONG)), "FDecodeID: pcb fails address check");
*pcb = 0;
while (*szT) { // Process line header
if (FBadCh(*szT)) return FALSE; ich = DEC(*szT); // Byte count for "line"
*pcb += ich; // running total of decoded info
cchLine = CchEncodedLine(ich); // Length-check this "line"
if (szT + cchLine + 1 > sz + cch) return FALSE; ++szT;
// Process line contents
for (ich = 0; ich < cchLine; ++ich) { if (FBadCh(*szT)) return FALSE; switch (ich % 4) { case 0: *pb = (BYTE) (DEC(*szT) << 2); break; case 1: *pb |= (DEC(*szT) >> 4) & 0x03; ++pb; *pb = (BYTE) (DEC(*szT) << 4); break; case 2: *pb |= (DEC(*szT) >> 2) & 0x0f; ++pb; *pb = (BYTE) (DEC(*szT) << 6); break; case 3: *pb |= DEC(*szT); ++pb; break; } ++szT; } }
return TRUE; }
//---------------------------------------------------------------------------
// Name: ErrLpstrToBstrA()
//
// Description:
// Copies C string to OLE BSTR. Note that the bstr
// contains an ANSI string. VB 4.0 will automatically
// convert this ANSI string to unicode when the string if
// this string is a member of a UDT and declared as a UDT.
// Arrays of UDTs are handled as SAFEARRAYS.
//
//
// Parameters:
// Returns:
// FALSE if successful
// TRUE if failure
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
ERR FAR PASCAL ErrLpstrToBstrA( LPSTR cstr, BSTR * lpBstr ) { UINT uiLen;
if ( *lpBstr ) SysFreeString( *lpBstr );
uiLen = lstrlen( cstr );
*lpBstr = SysAllocStringByteLen( cstr, (uiLen) ? uiLen : 0 );
return (ERR)((*lpBstr) ? FALSE : TRUE); }
//---------------------------------------------------------------------------
// Name: ErrBinaryToSzEID()
//
// Description:
// Converts binary data to a hexized string.
//
// Parameters:
// Returns:
// FALSE if success.
// TRUE if failure.
//
// Effects:
// Notes:
// Revision:
//---------------------------------------------------------------------------
ERR ErrBinaryToSzEID( LPVOID lpvEID, ULONG cbEID, LPSTR * lppstrEID ) { ERR Err = FALSE; ULONG cbStr;
cbStr = CchOfEncoding( cbEID );
if (!MemAlloc((LPVOID*)lppstrEID, cbStr)) { Err = TRUE; goto exit; }
EncodeID( (LPBYTE)lpvEID, cbEID, *lppstrEID );
exit:
return Err; }
/*
* Given the size of a binary string, returns the size of its * ASCII encoding. */ STDAPI_(ULONG) CchOfEncoding(ULONG cbBinary) { return (cbBinary / 3) * 4 // 3 bytes -> 4 characters
+ rgLeft[cbBinary % 3] // Leftover bytes -> N characters
+ ((cbBinary / 45) + 1) // overhead: 1 byte per line
+ 1; // null
}
/*
- EncodeID - * Purpose: * Turns a byte string into a character string, using the * uuencode algorithm. * * Three bytes are mapped into 6 bits each of 4 characters, in * the range 0x21 - 0x60. The encoding is broken up into lines * of 60 characters or less. Each line begins with a count * byte (which specifies the number of bytes encoded, not * characters) and ends with a CRLF pair. * * Note that this encoding is sub-optimal for UNICODE: the * characters used still fall into the 7-bit ASCII range. * * Arguments: * pb in the byte string to encode * cb in length of the input string * sz out the encoded character string. No * length checking is performed on the * output. * */ STDAPI_(void) EncodeID(LPBYTE pb, ULONG cb, LPTSTR sz) { int cbLine; int ib; BYTE b; #ifdef DEBUG
LPTSTR szBase = sz; ULONG cchTot = CchOfEncoding(cb); #endif
AssertSz(!IsBadReadPtr(pb, (UINT) cb), "EncodeID: pb fails address check"); AssertSz(!IsBadWritePtr(sz, (UINT) cchTot), "EncodeID: sz fails address check");
while (cb) { cbLine = min(45, (int)cb);
Assert(sz < szBase + cchTot); *sz++ = ENC(cbLine);
for (ib = 0; ib < cbLine; ++ib) { Assert(sz < szBase + cchTot); b = 0; switch (ib % 3) { case 0: *sz++ = ENC(*pb >> 2); if (ib+1 < cbLine) b = (BYTE) ((pb[1] >> 4) & 0x0f); *sz++ = ENC((*pb << 4) & 0x30 | b); break; case 1: if (ib+1 < cbLine) b = (BYTE) ((pb[1] >> 6) & 0x03); *sz++ = ENC((*pb << 2) & 0x3c | b); break; case 2: *sz++ = ENC(*pb & 0x3f); break; } pb++; }
cb -= cbLine; Assert(cb == 0 || sz + 1 < szBase + cchTot); }
Assert(sz + 1 == szBase + cchTot); *sz = 0; }
//---------------------------------------------------------------------------
// Name: ErrLpstrToBstr()
//
// Description:
// Copies and converts a C string to an OLE BSTR. This
// routine will convert MultiByte to WideChar.
// Parameters:
// Returns:
// FALSE if successful
// TRUE if failure
//
// Effects:
// Notes:
// SysReallocString returns FALSE if memory failure.
// Revision:
//---------------------------------------------------------------------------
ERR FAR PASCAL ErrLpstrToBstr( LPSTR cstr, BSTR * lpBstr ) { OLECHAR * lpszWC = NULL; INT cch = 0; ERR Err = FALSE;
if ( !cstr ) { *lpBstr = NULL; return FALSE; }
cch = lstrlen( cstr ); if (!MemAlloc((LPVOID*)&lpszWC, (cch + 1) * sizeof(OLECHAR))) return TRUE ;
// convert ANSI to WideChar
if ( !MultiByteToWideChar( GetACP(), 0, cstr, -1, lpszWC, cch + 1 ) ) { Err = TRUE; goto exit;
}
if ( *lpBstr ) { Err = (ERR)!SysReAllocString( lpBstr, lpszWC ); if ( Err ) goto exit; } else { *lpBstr = SysAllocString( lpszWC ); if ( !*lpBstr ) { Err = TRUE; goto exit; } }
exit:
SafeMemFree(lpszWC);
return Err; }
|