XPSTATUS.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:59k
源码类别:
Windows编程
开发平台:
Visual C++
- /*
- - X P S T A T U S . C
- -
- * Purpose:
- * Sample transport provider status interface code. This module
- * contains the following Transport SPI entry points:
- *
- * OpenStatusEntry()
- *
- * The Status Object methods implemented in this module are:
- *
- * QueryInterface,
- * AddRef,
- * Release,
- * GetLastError,
- * GetProps,
- * GetPropList,
- * SettingsDialog,
- * FlushQueues,
- *
- * Additional support functions found here:
- *
- * HrBuildTransportStatus
- * HrUpdateTransportStatus
- * NewSOB
- * HrLoadStatusString
- * MapScodeSz
- *
- * Copyright 1992-1995 Microsoft Corporation. All Rights Reserved.
- */
- //$BUG Invalid flags should return MAPI_E_UNKNOWN_FLAGS!
- #include "xppch.h"
- #include "xpresrc.h"
- #define MAX_STRING 8192
- #define MAX_RESRC_STRING 256
- /* Declared in xpbase.c */
- extern sptLogonArray;
- /* SOB IMAPIProp jump table */
- SOB_Vtbl vtblSOB =
- {
- SOB_QueryInterface,
- SOB_AddRef,
- SOB_Release,
- SOB_GetLastError,
- SOB_SaveChanges,
- SOB_GetProps,
- SOB_GetPropList,
- SOB_OpenProperty,
- SOB_SetProps,
- SOB_DeleteProps,
- SOB_CopyTo,
- SOB_CopyProps,
- SOB_GetNamesFromIDs,
- SOB_GetIDsFromNames,
- SOB_ValidateState,
- SOB_SettingsDialog,
- SOB_ChangePassword,
- SOB_FlushQueues,
- };
- /* Static properties. In this case the array of Property Tags available
- from the Status object if opened. The PR_RESOURCE_PATH must be last
- because we will not tell the client about this property if it isn't
- set in the Logon dialog. Being last makes GetPropList() easier to do. */
- /* Number of columns in Status row. */
- #define NUM_STATUS_ROW_PROPS 10
- const static SizedSPropTagArray(NUM_STATUS_ROW_PROPS, sptaStatusRow) =
- {
- NUM_STATUS_ROW_PROPS,
- {
- PR_RESOURCE_METHODS,
- PR_PROVIDER_DISPLAY,
- PR_DISPLAY_NAME,
- PR_IDENTITY_DISPLAY,
- PR_IDENTITY_ENTRYID,
- PR_IDENTITY_SEARCH_KEY,
- PR_STATUS_CODE,
- PR_STATUS_STRING,
- PR_OBJECT_TYPE,
- PR_RESOURCE_PATH
- }
- };
- /* List of IID's we support on open/query */
- #define N_IID 3
- static const LPIID lpStatusFamilyIID[N_IID] =
- {
- (LPIID) &IID_IUnknown, /* IUnknown is everyone's parent */
- (LPIID) &IID_IMAPIProp, /* IMAPIProp follows from this */
- (LPIID) &IID_IMAPIStatus /* My actual interface ID */
- };
- /* Local code */
- static HRESULT NewSOB(LPCIID lpInterface,
- ULONG ulOpenFlags,
- LPXPL lpxpl,
- ULONG * lpulObjType,
- LPSOB * lppSOB);
- static HRESULT HrLoadStatusString(LPXPL lpxpl,
- LPVOID lpvParent,
- LPTSTR * lppsz);
- /*
- - HrBuildTransportStatus
- -
- * Purpose:
- * Called by TransportLogon to build the Status Table entry for the
- * Sample Transport Provider.
- *
- * Parameters:
- * lpxpl The current session structure.
- * ulFlags 0 or STATUSROW_UPDATE
- *
- * Returns:
- * (HRESULT) Errors encountered if any.
- * (Status Row) Contains properties from session
- *
- * Operation:
- * This one's relatively simple: build a property value array based on
- * data in the session structure, and call (*lpMAPISup)->ModifyStatusRow
- * to register the row in the table.
- */
- HRESULT
- HrBuildTransportStatus(LPXPL lpxpl, ULONG ulFlags)
- {
- SCODE sc = 0;
- LPSPropValue lpPropArray = NULL;
- LPMAPISUP lpMAPISup = lpxpl->lpMAPISup;
- LPSPropValue pPropValT;
- LPVOID lpvT;
- LPVOID lpvT1;
- LPVOID lpvT2;
- LPTSTR lpszStatus = NULL;
- ULONG ulT;
- /* Allocate initial property array now. */
- sc = lpxpl->AllocateBuffer(sizeof(SPropValue) * (NUM_STATUS_ROW_PROPS - 1), (LPVOID *) &lpPropArray);
- if (sc)
- {
- DebugTraceSc(Status Row Allocation, sc);
- goto ret;
- }
- /* Store the properties into the status row */
- pPropValT = lpPropArray;
- /* 1. Transport's Display Name. */
- pPropValT->ulPropTag = PR_PROVIDER_DISPLAY;
- pPropValT->Value.LPSZ = (LPTSTR) MYDISPLAYNAME;
- pPropValT++;
- /* 2. Extra methods on status object */
- pPropValT->ulPropTag = PR_RESOURCE_METHODS;
- pPropValT->Value.ul = lpxpl->ulResourceMethods;
- pPropValT++;
- /* 3. Display Name associated with session. Use email address. */
- lpvT1 = ArrayIndex (PR_SAMPLE_DISPLAY_NAME, lpxpl->lpPropArray).Value.LPSZ;
- lpvT2 = ArrayIndex (PR_SAMPLE_EMAIL_ADDRESS, lpxpl->lpPropArray).Value.LPSZ;
- ulT = (lstrlen((LPCTSTR) lpvT1)+lstrlen((LPCTSTR) lpvT2)+4)*sizeof (TCHAR);
- sc = lpxpl->AllocateMore(ulT, (LPVOID) lpPropArray, &lpvT);
- if (sc)
- {
- DebugTraceSc(Session Display Name allocation, sc);
- goto ret;
- }
- wsprintf((LPTSTR) lpvT, TEXT("%s [%s]"), (LPTSTR) lpvT1, (LPTSTR) lpvT2);
- pPropValT->ulPropTag = PR_DISPLAY_NAME;
- pPropValT->Value.LPSZ = (LPTSTR) lpvT;
- pPropValT++;
- /* 4. User's Display Name. */
- Assert(lpxpl->lpMyIDArray);
- *pPropValT = lpxpl->lpMyIDArray[1];
- Assert(pPropValT->ulPropTag == PR_SENDER_NAME);
- Assert(!IsBadStringPtr(pPropValT->Value.LPSZ, MAX_STRING));
- pPropValT->ulPropTag = PR_IDENTITY_DISPLAY;
- pPropValT++;
- /* 5. User Entry-ID. */
- Assert(lpxpl->lpMyIDArray);
- *pPropValT = lpxpl->lpMyIDArray[0];
- Assert(pPropValT->ulPropTag == PR_SENDER_ENTRYID);
- Assert(pPropValT->Value.bin.cb);
- Assert(!IsBadReadPtr(pPropValT->Value.bin.lpb, (UINT) pPropValT->Value.bin.cb));
- pPropValT->ulPropTag = PR_IDENTITY_ENTRYID;
- pPropValT++;
- /* 6. User Search Key. */
- Assert(lpxpl->lpMyIDArray);
- *pPropValT = lpxpl->lpMyIDArray[2];
- Assert(pPropValT->ulPropTag == PR_SENDER_SEARCH_KEY);
- Assert(pPropValT->Value.bin.cb);
- Assert(!IsBadReadPtr(pPropValT->Value.bin.lpb, (UINT) pPropValT->Value.bin.cb));
- pPropValT->ulPropTag = PR_IDENTITY_SEARCH_KEY;
- pPropValT++;
- /* 7. Code. Online/Offline, Send/Receive, Uploading/Downloading. */
- pPropValT->ulPropTag = PR_STATUS_CODE;
- pPropValT->Value.ul = lpxpl->ulTransportStatus;
- pPropValT++;
- /* 8. Status String based on Status Code. */
- if (HrLoadStatusString(lpxpl, lpPropArray, &lpszStatus))
- {
- pPropValT->ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(PR_STATUS_STRING));
- pPropValT->Value.err = MAPI_E_NOT_FOUND;
- }
- else
- {
- pPropValT->ulPropTag = PR_STATUS_STRING;
- pPropValT->Value.LPSZ = lpszStatus;
- }
- pPropValT++;
- /* 9. Resource Path == WGAP Directory. */
- lpvT = (LPVOID) ArrayIndex(PR_SAMPLE_DIRECTORY, lpxpl->lpPropArray).Value.LPSZ;
- if (lstrlen((LPCTSTR) lpvT))
- {
- pPropValT->ulPropTag = PR_RESOURCE_PATH;
- pPropValT->Value.LPSZ = (LPTSTR) lpvT;
- pPropValT++;
- }
- /* Status Row is built. Register it. */
- sc = GetScode(lpMAPISup->lpVtbl->ModifyStatusRow(lpMAPISup,
- (pPropValT - lpPropArray), lpPropArray, ulFlags));
- if (FAILED(sc))
- DebugTrace("ModifyStatusRow failed.n");
- ret:
- /* Free the allocated memory */
- lpxpl->FreeBuffer(lpPropArray);
- DebugTraceSc(HrBuildTransportStatus, sc);
- return ResultFromScode(sc);
- }
- /*
- - HrUpdateTransportStatus
- -
- * Purpose:
- * Called by Transport code to update the PR_STATUS_CODE property in the
- * Status Table row for the Sample Transport Provider.
- *
- * Parameters:
- * lpxpl The current session structure.
- * ulFlags Flags. Not currently used.
- *
- * Returns:
- * (HRESULT) Errors encountered if any.
- * (Status Row) PR_STATUS_CODE and PR_STATUS_STRING updated
- *
- * Operation:
- * Transport should already have updated lpxpl->ulTransportStatus
- * before calling here. So all this routine does is construct a
- * notification structure for a status object modification and call
- * (*lpMAPISup)->ModifyStatusRow() to update the table. If there is a
- * string available in the StringTable, then our cProps goes to 2 and
- * we assign the string to the 2nd element of rgProps.
- */
- HRESULT
- HrUpdateTransportStatus(LPXPL lpxpl, ULONG ulFlags)
- {
- HRESULT hResult;
- ULONG cProps = 2;
- SPropValue rgProps[2];
- LPMAPISUP lpMAPISup = lpxpl->lpMAPISup;
- LPTSTR lpszStatus = NULL;
- /* Store the new Transport Provider Status Code. */
- rgProps[0].ulPropTag = PR_STATUS_CODE;
- rgProps[0].Value.ul = lpxpl->ulTransportStatus;
- /* Set the Status String according to ulStatus */
- if (HrLoadStatusString(lpxpl, NULL, &lpszStatus))
- {
- rgProps[1].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(PR_STATUS_STRING));
- rgProps[1].Value.err = MAPI_E_NOT_FOUND;
- }
- else
- {
- rgProps[1].ulPropTag = PR_STATUS_STRING;
- rgProps[1].Value.LPSZ = lpszStatus;
- }
- /* OK. Notify the Spooler. It will tell MAPI. */
- hResult = lpMAPISup->lpVtbl->ModifyStatusRow(lpMAPISup,
- cProps, rgProps, STATUSROW_UPDATE);
- lpxpl->FreeBuffer(lpszStatus);
- DebugTraceResult(ModifyStatusRow, hResult);
- return hResult;
- }
- /*
- - OpenStatusEntry
- -
- * Purpose:
- * Called by Spooler to service client OpenEntry request.
- *
- * Parameters:
- * lpiid Interface identifier.
- * ulFlags Open flags. The only doc'ed flag
- * is MAPI_MODIFY, which we don't support.
- * lpulObjType Pointer to a unsigned long into which
- * we are to store the type of the
- * object we've just opened.
- * lppEntry Points to a variable into which we
- * may store the object pointer.
- *
- * Returns:
- * (HRESULT) E_INVALIDARG if the session
- * pointer isn't valid, or any other
- * parameter not to our liking,
- * or any other errors we encounter.
- * *lpulObjType MAPI_STATUS if we open the entry,
- * unchanged if not
- * *lppEntry Pointer to object if we open the
- * entry, unchanged if not
- *
- * Operation:
- * Validate parameters. Call NewSOB() to create the object, returning
- * object type and object pointer into user-supplied locations.
- */
- STDMETHODIMP
- XPL_OpenStatusEntry(LPXPL lpxpl,
- LPCIID lpiid,
- ULONG ulFlags,
- ULONG * lpulObjType,
- LPMAPISTATUS * lppEntry)
- {
- HRESULT hResult;
- #ifndef MAC
- LPXPP lpxpp;
- #endif
- /* Need to do weak session validation to do this */
- if (IsBadWritePtr(lpxpl, sizeof(XPL)) ||
- IsBadWritePtr((lpxpp = lpxpl->lpxppParent), sizeof(XPP)) ||
- (lpiid != NULL && IsBadReadPtr(lpiid, sizeof(IID))) ||
- (IsBadWritePtr(lpulObjType, sizeof(ULONG))) ||
- (IsBadWritePtr(lppEntry, sizeof(LPMAPISTATUS))))
- {
- DebugTraceSc(OpenStatusEntry, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- /* Get the Critical Section */
- EnterCriticalSection(&lpxpp->csTransport);
- /* Validate the user's parameters always */
- /* Invalid parameter checking: 1) make sure the passed session
- is still valid; 2) lpiid should either be null or point
- to a piece of memory at least the size of a iid; 3) lpulObjType
- must point to a writable piece of memory the size of a ulong;
- 4) lppEntry must point to enough writable memory to store a
- LPMAPISTATUS. */
- if (!FIsValidSession(lpxpl))
- {
- hResult = ResultFromScode(E_INVALIDARG);
- DebugTrace("Invalid Logon object.n");
- goto ret;
- }
- /* We don't support MAPI_MODIFY and no other flags are spec'ed. */
- if (ulFlags & ~MAPI_MODIFY)
- {
- hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
- DebugTrace("Unknown Flags.n");
- goto ret;
- }
- if (ulFlags & MAPI_MODIFY)
- {
- hResult = ResultFromScode(MAPI_E_NO_ACCESS);
- DebugTrace("XP Support Object doesn't support Modify access.n");
- goto ret;
- }
- /* The argument list looks good to us. Now, if we already have opened
- a status object on this logon context, we'll just use QueryInterface
- to get a new copy of the object... */
- if (lpxpl->lpXPStatus)
- {
- hResult = lpxpl->lpXPStatus->lpVtbl->QueryInterface(lpxpl->lpXPStatus,
- (lpiid ? lpiid : &IID_IMAPIStatus), lppEntry);
- if (HR_FAILED(hResult))
- DebugTrace("QueryInterface failed.n");
- else
- *lpulObjType = MAPI_STATUS;
- }
- else
- {
- /* Or if we don't already have an object, create it, saving a
- copy in the logon context. */
- hResult = NewSOB(lpiid, ulFlags, lpxpl,
- lpulObjType, (LPSOB *) lppEntry);
- if (HR_FAILED(hResult))
- DebugTrace("NewSOB failed.n");
- else
- lpxpl->lpXPStatus = *lppEntry;
- }
- ret:
- /* Release the critical section. */
- LeaveCriticalSection(&lpxpp->csTransport);
- /* Errors returned from this routine are always in sc. So if
- sc is zero we return 0. If it's nonzero we return a hResult
- built here from sc. */
- DebugTraceResult(OpenStatusEntry, hResult);
- return hResult;
- }
- /*
- - NewSOB
- -
- * Purpose:
- * Called from OpenStatusEntry to create a Status Object.
- *
- * Parameters:
- * lpInterface If non-null must be IID_IMAPIStatus
- * ulOpenFlags Open flags. The only doc'ed flag
- * is MAPI_MODIFY, which we don't support.
- * lpxpl The handle of the session for which
- * we want to open a Status object. In
- * Spooler context, a pointer to the
- * session data structure.
- * lpulObjType Pointer to a unsigned long into which
- * we are to store the type of the
- * object we've just opened.
- * lppSOB Points to a variable into which we
- * may store the object pointer.
- *
- * Returns:
- * (HRESULT) MAPI_E_NO_SUPPORT if an
- * interface is specified, or any
- * other errors we encounter.
- * *lpulObjType MAPI_STATUS if we open the entry,
- * unchanged if not
- * *lppEntry Pointer to object if we open the
- * entry, unchanged if not
- *
- * Operation:
- * Allocates the memory for the object, initializes its data
- * members, plugs in the jump table and returns the appropriate
- * stuff to the caller.
- */
- static HRESULT
- NewSOB(LPCIID lpInterface,
- ULONG ulOpenFlags,
- LPXPL lpxpl,
- ULONG * lpulObjType,
- LPSOB * lppSOB)
- {
- SCODE sc;
- LPMAPISUP lpMAPISup = lpxpl->lpMAPISup;
- LPSOB lpSOB = NULL;
- ULONG i;
- *lpulObjType = 0;
- *lppSOB = NULL;
- /* Make sure no interface (or ours) was specified. */
- if (lpInterface)
- {
- for (i = 0; i < N_IID; i++)
- {
- if (!memcmp(lpInterface, lpStatusFamilyIID[i], sizeof(IID)))
- break;
- }
- if (i == N_IID)
- {
- DebugTraceSc(NewSOB, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- }
- /* Allocate space for the SOB structure */
- sc = lpxpl->AllocateBuffer(sizeof(SOB), (LPVOID *) &lpSOB);
- if (sc)
- {
- DebugTrace("Allocation of Status Object failed.n");
- return ResultFromScode(sc);
- }
- /* Fill in the data members and the jump table. */
- lpSOB->lpVtbl = &vtblSOB;
- lpSOB->lcInit = 1;
- lpSOB->lpsobMyAddress = lpSOB;
- lpSOB->hrLastError = 0;
- lpSOB->ulOpenFlags = ulOpenFlags;
- lpSOB->AllocateBuffer = lpxpl->AllocateBuffer;
- lpSOB->AllocateMore = lpxpl->AllocateMore;
- lpSOB->FreeBuffer = lpxpl->FreeBuffer;
- lpSOB->lpMAPISup = lpMAPISup;
- lpSOB->lpxpl = lpxpl;
- /* Return the newly constructed object to the caller. */
- *lpulObjType = MAPI_STATUS;
- *lppSOB = lpSOB;
- return 0;
- }
- /*
- - HrLoadStatusString
- -
- * Purpose:
- * Retrieves a Status String from the resource StringTable
- * based on ulStatus code passed in.
- *
- * Parameters:
- * lpxpl The Transport Logon session
- * lpvParent If non-null we chain the memory to this block
- * lppsz Place to copy Status String to.
- *
- * Returns:
- * hr Indicating Success/Failure
- *
- */
- static HRESULT
- HrLoadStatusString(LPXPL lpxpl, LPVOID lpvParent, LPTSTR *lppsz)
- {
- SCODE sc = S_OK;
- UINT ids;
- ULONG cb;
- ULONG ulStatus = lpxpl->ulTransportStatus;
- TCHAR szStatus[MAX_RESRC_STRING];
- /* Determine the IDS of the status. Since the status' are bit fields
- of ulStatus, we apply this hierarcy to determine the correct string. */
- if (ulStatus & STATUS_INBOUND_ACTIVE)
- ids = IDS_STATUS_UPLOADING;
- else if (ulStatus & STATUS_OUTBOUND_ACTIVE)
- ids = IDS_STATUS_DOWNLOADING;
- else if (ulStatus & STATUS_INBOUND_FLUSH)
- ids = IDS_STATUS_INFLUSHING;
- else if (ulStatus & STATUS_OUTBOUND_FLUSH)
- ids = IDS_STATUS_OUTFLUSHING;
- else if ((ulStatus & STATUS_AVAILABLE) &&
- ((ulStatus & STATUS_INBOUND_ENABLED) ||
- (ulStatus & STATUS_OUTBOUND_ENABLED)))
- ids = IDS_STATUS_ONLINE;
- else if (ulStatus & STATUS_AVAILABLE)
- ids = IDS_STATUS_AVAILABLE;
- else
- ids = IDS_STATUS_OFFLINE;
- /* Attempt to load the resource into our automatic variable. */
- cb = LoadString(lpxpl->lpxppParent->hInst, ids, szStatus, MAX_RESRC_STRING);
- if (!cb)
- {
- sc = MAPI_E_CALL_FAILED;
- DebugTrace("LoadString failed in HrLoadStatusString.n");
- goto ret;
- }
- /* We'll get the exact size of the string and put it on the heap.
- The caller had the luxury of specifying a parent block to chain
- this allocation to. */
- cb = (cb + 1) * sizeof(TCHAR);
- if (lpvParent)
- sc = lpxpl->AllocateMore(cb, lpvParent, (LPVOID *)lppsz);
- else
- sc = lpxpl->AllocateBuffer(cb, (LPVOID *)lppsz);
- if (FAILED(sc))
- {
- DebugTrace("Allocation failed in HrLoadStatusString.n");
- goto ret;
- }
- lstrcpy(*lppsz, szStatus);
- ret:
- DebugTraceSc(HrLoadStatusString, sc);
- return ResultFromScode(sc);
- }
- /*
- - IMAPISTATUS::QueryInterface
- -
- * Purpose:
- * Standard IUnknown method.
- *
- * Parameters:
- * lpObject Pointer to object
- * lpiid New interface to Query to
- * lppNewObj Where to store pointer to new object
- *
- * Returns:
- * (SCODE) E_INVALIDARG if the input object
- * doesn't look like a SOB, if the
- * IID isn't readable or lppNewObj
- * isn't writable; E_NOINTERFACE
- * if we don't know the IID.
- *
- * Operation:
- * Validate parameters. See if the caller wants IUnknown, IMAPIProp or
- * IStatus. If so, increment the usage count and return a new object.
- */
- STDMETHODIMP
- SOB_QueryInterface(LPSOB lpSOB,
- REFIID lpiid,
- LPVOID * lppNewObj)
- {
- ULONG i;
- /* Validate the parameters: 1) Does it seem to be an object?
- 2) is the refcount nonzero? 3) Is there enough there for
- an interface ID? 4) Is there enough there for a new object? */
- if ((IsBadWritePtr(lpSOB, sizeof(SOB))) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (IsBadReadPtr(lpiid, sizeof(IID))) ||
- (IsBadWritePtr(lppNewObj, sizeof(LPSOB))))
- {
- DebugTraceSc(SOB_QueryInterface, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- /* See if the requested interface is one of ours */
- for (i = 0; i < N_IID; i++)
- {
- if (!memcmp(lpiid, lpStatusFamilyIID[i], sizeof(IID)))
- break;
- }
- /* If we didn't find the interface, get out now. */
- if (i == N_IID)
- {
- /* OLE requires zeroing [out] parameters */
- *lppNewObj = NULL;
- DebugTraceSc(SOB_QueryInterface, E_NOINTERFACE);
- return ResultFromScode(E_NOINTERFACE);
- }
- /* We'll do this one. Bump the usage count and return a new pointer. */
- ++lpSOB->lcInit;
- *lppNewObj = lpSOB;
- return hrSuccess;
- }
- /*
- - IMAPISTATUS::AddRef
- -
- * Purpose:
- * Increment reference count if nonzero.
- *
- * Parameters:
- * lpObject Pointer to object (should be SOB)
- *
- * Returns:
- * (ULONG) Current reference count or zero if
- * it doesn't seem to be SOB.
- *
- * Operation:
- * Make sure it looks like a SOB, and if so, bump the reference count
- * and return the result to the caller.
- */
- STDMETHODIMP_(ULONG)
- SOB_AddRef(LPSOB lpSOB)
- {
- /* If it doesn't seem to be an object or refcount is zero, return zero */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- lpSOB->lcInit == 0 ||
- lpSOB->lpsobMyAddress != lpSOB)
- return 0;
- return ++lpSOB->lcInit;
- }
- /*
- - IMAPISTATUS::Release
- -
- * Purpose:
- * Decrement lcInit. If it's zero, release the object.
- *
- * Parameters:
- * lpObject Pointer to object (should be SOB)
- *
- * Returns:
- * (ULONG) Current reference count or zero if
- * it doesn't seem to be SOB.
- *
- * Operation:
- * Make sure it looks like a SOB, and if so, decrement the reference
- * count. If the count is now zero, deallocate the object.
- * Return the reference count to the caller.
- */
- STDMETHODIMP_(ULONG)
- SOB_Release(LPSOB lpSOB)
- {
- /* If it doesn't seem to be an object or refcount is zero, return zero */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- lpSOB->lcInit == 0 ||
- lpSOB->lpsobMyAddress != lpSOB)
- return 0;
- --lpSOB->lcInit;
- if (lpSOB->lcInit == 0)
- {
- DebugTrace("SOB::Release() freeing SOB.n");
- /* Unlink the status object from the logon object */
- if (FIsValidSession(lpSOB->lpxpl))
- lpSOB->lpxpl->lpXPStatus = NULL;
- lpSOB->lpVtbl = NULL;
- (*lpSOB->FreeBuffer) (lpSOB);
- return 0;
- }
- return lpSOB->lcInit;
- }
- /*
- - IMAPISTATUS::GetLastError
- -
- * Purpose:
- * Returns a string associated with the last HRESULT returned
- * by the SOB object.
- *
- * Parameters:
- * lpObject Pointer to object (should be SOB)
- * hError HRESULT that caller is interested in
- * ulFlags Ignored.
- * lppszMessage Pointer to where message pointer should
- * be copied.
- *
- * Returns:
- * (HRESULT) E_INVALIDARG if object doesn't look
- * like a SOB or if any parameters look
- * bad; other errors if any; 0 if successful.
- * *lppszMessage Pointer to error message if any, else NULL
- *
- * Operation:
- * Confirm the parameters. Compare the HRESULT to our last saved one. If
- * they match, copy the string into a new buffer and store the pointer
- * into the location provided by the caller.
- */
- STDMETHODIMP
- SOB_GetLastError(LPSOB lpSOB,
- HRESULT hError,
- ULONG ulFlags,
- LPMAPIERROR * lppMapiError )
- {
- HRESULT hResult = hrSuccess;
- SCODE sc;
- LPTSTR pszMessage = NULL;
- /* Validate the object and return pointer */
- *lppMapiError = NULL;
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (IsBadWritePtr(lppMapiError, sizeof(LPMAPIERROR))))
- {
- DebugTraceSc(SOB_GetLastError, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- if ( ulFlags & ~MAPI_UNICODE )
- {
- return ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
- }
- if ( ulFlags & MAPI_UNICODE )
- {
- return ResultFromScode( MAPI_E_BAD_CHARWIDTH );
- }
- /* See if we have the message the caller wants. If so,
- make a copy and pass it back. */
- if ((hError != 0) && (hError == lpSOB->hrLastError))
- {
- sc = lpSOB->AllocateBuffer( sizeof( MAPIERROR ), lppMapiError );
- if ( FAILED( sc ) )
- {
- hResult = ResultFromScode( sc );
- goto ret;
- }
- memset( *lppMapiError, 0, sizeof( MAPIERROR ) );
- (*lppMapiError)->ulVersion = MAPI_ERROR_VERSION;
- hResult = MapScodeSz(GetScode(hError), lpSOB->lpxpl, &pszMessage);
- if ( HR_FAILED( hResult ) )
- goto ret;
- sc = lpSOB->AllocateMore( Cbtszsize( pszMessage ), *lppMapiError,
- &(*lppMapiError)->lpszError );
- if ( FAILED( sc ) )
- {
- hResult = ResultFromScode( sc );
- goto ret;
- }
- lstrcpy( (*lppMapiError)->lpszError, pszMessage );
- }
- ret:
- if ( hResult )
- {
- lpSOB->FreeBuffer( *lppMapiError );
- *lppMapiError = NULL;
- }
- lpSOB->FreeBuffer( pszMessage );
- return hResult;
- }
- /*
- - IMAPISTATUS::GetProps
- -
- * Purpose:
- * Returns the properties listed in the lpPropTagArray.
- *
- * Parameters:
- * lpObject Pointer to object (should be SOB)
- * lpPropTagArray List of tags for which values are desired
- * ulFlags UNICODE / String8
- * lpcValues Pointer: where to store count of values
- * lppPropArray Pointer: where to store pointer to values
- *
- * Returns:
- * (HRESULT) E_INVALIDARG if object doesn't look like
- * a SOB or if any of the parameters look
- * bad; other errors if any; 0 if successful.
- * *lpcValues Contains a property count if successful
- * *lppPropArray Undefined if not successful; NULL if
- * no properties; points to array of
- * properties if any.
- *
- * Operation:
- * Confirm the parameters. If lpPropTagArray is NULL, use our canned
- * property list.
- * Walk through the list, and give the caller any properties in the
- * list which we can provide. Return count in *lpcValues and pointer to
- * the array in *lppPropArray.
- */
- STDMETHODIMP
- SOB_GetProps(LPSOB lpSOB,
- LPSPropTagArray lpPropTagArray,
- ULONG ulFlags,
- ULONG * lpcValues,
- LPSPropValue * lppPropArray)
- {
- SCODE sc = 0;
- HRESULT hResult = 0;
- ULONG ulT = 0;
- LPXPL lpxpl = NULL;
- HINSTANCE hInst;
- LPSPropValue lpPropArray = NULL;
- LPSPropValue lpMyIDArray = NULL;
- LPSPropTagArray lpspta = NULL;
- ULONG cb;
- LPTSTR lpsz;
- LPSPropValue lpPropT;
- BOOL fGotMemErrors = FALSE;
- BOOL fMyPTA = TRUE;
- BOOL fNoResourcePath = FALSE;
- /* Validate the object and the return pointers */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- lpSOB->lcInit == 0 ||
- lpSOB->lpsobMyAddress != lpSOB)
- {
- hResult = ResultFromScode(E_INVALIDARG);
- goto ret;
- }
- /* Validate the Flags */
- if ( ulFlags & ~(MAPI_UNICODE) )
- {
- hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
- goto ret;
- }
- if ( ulFlags & MAPI_UNICODE )
- {
- hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
- goto ret;
- }
- /* Validate the return pointers */
- if ((IsBadWritePtr(lpcValues, sizeof(ULONG))) ||
- (IsBadWritePtr(lppPropArray, sizeof(LPSPropValue))))
- {
- hResult = ResultFromScode(E_INVALIDARG);
- goto ret;
- }
- /* Validate the passed property tag array if any */
- if (lpPropTagArray)
- {
- if ((IsBadReadPtr(lpPropTagArray, CbNewSPropTagArray(0))) ||
- (lpPropTagArray->cValues == 0) ||
- (IsBadReadPtr(&lpPropTagArray->aulPropTag[0],
- (UINT) (lpPropTagArray->cValues * sizeof(ULONG)))))
- {
- hResult = ResultFromScode(E_INVALIDARG);
- goto ret;
- }
- fMyPTA = FALSE;
- lpspta = lpPropTagArray;
- }
- else
- {
- /* An array wasn't passed. Use ours. */
- lpspta = (LPSPropTagArray) &sptaStatusRow;
- }
- /* Parameters have passed muster. Create the property array. */
- lpxpl = lpSOB->lpxpl;
- hInst = lpxpl->lpxppParent->hInst;
- sc = ScCopySessionProps(lpxpl, &lpPropArray, &lpMyIDArray);
- if (FAILED(sc))
- goto ret;
- sc = (*lpSOB->AllocateBuffer) (sizeof(SPropValue) * (lpspta->cValues), (LPVOID *) lppPropArray);
- if (sc)
- {
- hResult = ResultFromScode(sc);
- lpSOB->hrLastError = hResult;
- goto ret;
- }
- /* Count will always equal input number since we'll either get a
- property value or a PT_ERROR. */
- for (ulT = 0; ulT < lpspta->cValues; ulT++)
- {
- switch (lpspta->aulPropTag[ulT])
- {
- case PR_RESOURCE_METHODS:
- (*lppPropArray)[ulT].ulPropTag = PR_RESOURCE_METHODS;
- (*lppPropArray)[ulT].Value.ul = lpxpl->ulResourceMethods;
- break;
- case PR_PROVIDER_DISPLAY:
- (*lppPropArray)[ulT].ulPropTag = PR_PROVIDER_DISPLAY;
- (*lppPropArray)[ulT].Value.LPSZ = (LPTSTR)MYDISPLAYNAME;
- break;
- case PR_DISPLAY_NAME:
- lpsz = ArrayIndex(PR_SAMPLE_EMAIL_ADDRESS, lpPropArray).Value.LPSZ;
- cb = sizeof(TCHAR) * (lstrlen(lpsz) + 1);
- sc = lpSOB->AllocateMore(cb, (LPVOID) *lppPropArray,
- (LPVOID *) &((*lppPropArray)[ulT].Value.LPSZ));
- if (sc)
- {
- fGotMemErrors = TRUE;
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(lpspta->aulPropTag[ulT]));
- (*lppPropArray)[ulT].Value.err = sc;
- }
- else
- {
- (*lppPropArray)[ulT].ulPropTag = PR_DISPLAY_NAME;
- lstrcpy((*lppPropArray)[ulT].Value.LPSZ, lpsz);
- }
- break;
- case PR_IDENTITY_DISPLAY:
- lpPropT = &(lpMyIDArray[1]);
- Assert(lpPropT);
- Assert(lpPropT->ulPropTag == PR_SENDER_NAME);
- cb = sizeof(TCHAR) * (lstrlen(lpPropT->Value.LPSZ) + 1);
- sc = lpSOB->AllocateMore(cb, (LPVOID) * lppPropArray,
- (LPVOID *) &((*lppPropArray)[ulT].Value.LPSZ));
- if (sc)
- {
- fGotMemErrors = TRUE;
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(lpspta->aulPropTag[ulT]));
- (*lppPropArray)[ulT].Value.err = sc;
- }
- else
- {
- (*lppPropArray)[ulT].ulPropTag = PR_IDENTITY_DISPLAY;
- lstrcpy((*lppPropArray)[ulT].Value.LPSZ, lpPropT->Value.LPSZ);
- }
- break;
- case PR_IDENTITY_ENTRYID:
- lpPropT = &(lpMyIDArray[0]);
- Assert(lpPropT);
- Assert(lpPropT->ulPropTag == PR_SENDER_ENTRYID);
- cb = lpPropT->Value.bin.cb;
- Assert(cb);
- Assert(!IsBadReadPtr(lpPropT->Value.bin.lpb, (UINT)cb));
- sc = lpSOB->AllocateMore(cb, (LPVOID) *lppPropArray,
- (LPVOID *) &((*lppPropArray)[ulT].Value.bin.lpb));
- if (sc)
- {
- fGotMemErrors = TRUE;
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(lpspta->aulPropTag[ulT]));
- (*lppPropArray)[ulT].Value.err = sc;
- }
- else
- {
- (*lppPropArray)[ulT].ulPropTag = PR_IDENTITY_ENTRYID;
- (*lppPropArray)[ulT].Value.bin.cb = cb;
- if (cb)
- memcpy((*lppPropArray)[ulT].Value.bin.lpb,
- lpPropT->Value.bin.lpb, (UINT)cb);
- }
- break;
- case PR_IDENTITY_SEARCH_KEY:
- lpPropT = &(lpMyIDArray[2]);
- Assert(lpPropT);
- Assert(lpPropT->ulPropTag == PR_SENDER_SEARCH_KEY);
- cb = lpPropT->Value.bin.cb;
- Assert(cb);
- Assert(!IsBadReadPtr(lpPropT->Value.bin.lpb, (UINT)cb));
- sc = lpSOB->AllocateMore(cb, (LPVOID) *lppPropArray,
- (LPVOID *) &((*lppPropArray)[ulT].Value.bin.lpb));
- if (sc)
- {
- fGotMemErrors = TRUE;
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(lpspta->aulPropTag[ulT]));
- (*lppPropArray)[ulT].Value.err = sc;
- }
- else
- {
- (*lppPropArray)[ulT].ulPropTag = PR_IDENTITY_SEARCH_KEY;
- (*lppPropArray)[ulT].Value.bin.cb = cb;
- if (cb)
- memcpy((*lppPropArray)[ulT].Value.bin.lpb,
- lpPropT->Value.bin.lpb, (UINT)cb);
- }
- break;
- case PR_STATUS_CODE:
- (*lppPropArray)[ulT].ulPropTag = PR_STATUS_CODE;
- (*lppPropArray)[ulT].Value.ul = lpxpl->ulTransportStatus;
- break;
- case PR_STATUS_STRING:
- lpsz = NULL;
- if (sc = GetScode(HrLoadStatusString(lpxpl, *lppPropArray, &lpsz)))
- {
- fGotMemErrors = TRUE;
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(lpspta->aulPropTag[ulT]));
- (*lppPropArray)[ulT].Value.err = sc;
- }
- else
- {
- (*lppPropArray)[ulT].ulPropTag = PR_STATUS_STRING;
- (*lppPropArray)[ulT].Value.LPSZ = lpsz;
- }
- break;
- case PR_RESOURCE_PATH:
- lpsz = (LPVOID) ArrayIndex(PR_SAMPLE_DIRECTORY, lpPropArray).Value.LPSZ;
- Assert(lpsz);
- cb = (lstrlen(lpsz) + 1) * sizeof(TCHAR);
- if (cb == sizeof(TCHAR))
- {
- if (fMyPTA)
- {
- fNoResourcePath = TRUE;
- }
- else
- {
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(PR_RESOURCE_PATH));
- (*lppPropArray)[ulT].Value.err = MAPI_E_NOT_FOUND;
- }
- break;
- }
- sc = (*lpSOB->AllocateMore) (cb, (LPVOID) * lppPropArray, (LPVOID *) &((*lppPropArray)[ulT].Value.LPSZ));
- if (sc)
- {
- fGotMemErrors = TRUE;
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(PR_RESOURCE_PATH));
- (*lppPropArray)[ulT].Value.err = sc;
- }
- else
- {
- (*lppPropArray)[ulT].ulPropTag = PR_RESOURCE_PATH;
- lstrcpy((*lppPropArray)[ulT].Value.LPSZ, lpsz);
- }
- break;
- case PR_OBJECT_TYPE:
- (*lppPropArray)[ulT].ulPropTag = PR_OBJECT_TYPE;
- (*lppPropArray)[ulT].Value.ul = MAPI_STATUS;
- break;
- default:
- (*lppPropArray)[ulT].ulPropTag = PROP_TAG(PT_ERROR, PROP_ID(lpspta->aulPropTag[ulT]));
- (*lppPropArray)[ulT].Value.err = MAPI_E_NOT_FOUND;
- hResult = ResultFromScode(MAPI_W_ERRORS_RETURNED);
- lpSOB->hrLastError = hResult;
- break;
- }
- }
- /* Store number of properties we're returning, i.e., the number
- asked for (with possible errors). */
- if (fMyPTA && fNoResourcePath)
- *lpcValues = lpspta->cValues - 1;
- else
- *lpcValues = lpspta->cValues;
- if (fGotMemErrors)
- {
- hResult = ResultFromScode(MAPI_W_ERRORS_RETURNED);
- lpSOB->hrLastError = hResult;
- }
- ret:
- if(lpxpl)
- {
- lpxpl->FreeBuffer(lpPropArray);
- lpxpl->FreeBuffer(lpMyIDArray);
- }
- DebugTraceResult(SOB_GetProps, hResult);
- return hResult;
- }
- /*
- - IMAPISTATUS::GetPropList
- -
- * Purpose:
- *
- * Parameters:
- * lpObject Pointer to object (should be SOB)
- * ulFlags UNICODE / String8
- * lppPropTagArray Pointer: where to store pointer to tags
- *
- * Returns:
- * (HRESULT) E_INVALIDARG if object doesn't look like a
- * SOB or if any of the parameters look bad;
- * other errors if any; 0 if successful.
- * *lppPropArray Undefined if not successful; points to
- * array of property tags otherwise.
- *
- * Operation:
- * Validate parameters; Create enough memory for out property tag list,
- * copy the list into it and do so. Return the new list into the caller's
- * pointer.
- */
- STDMETHODIMP
- SOB_GetPropList(LPSOB lpSOB,
- ULONG ulFlags,
- LPSPropTagArray * lppPropTagArray)
- {
- SCODE sc;
- HRESULT hResult = 0;
- LPXPL lpxpl;
- ULONG ulArraySize;
- ULONG cActualProps;
- /* Validate the Flags */
- if ( ulFlags & ~(MAPI_UNICODE) )
- {
- hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
- goto ret;
- }
- if ( ulFlags & MAPI_UNICODE )
- {
- hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
- goto ret;
- }
- /* Validate the object and the return pointers */
- if ((IsBadWritePtr(lpSOB, sizeof(SOB))) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (IsBadWritePtr(lppPropTagArray, sizeof(LPSPropTagArray))))
- {
- hResult = ResultFromScode(E_INVALIDARG);
- goto ret;
- }
- lpxpl = lpSOB->lpxpl;
- /* If WGAP Directory is empty, don't tell them about this property. */
- cActualProps = sptaStatusRow.cValues;
- if (lstrlen((LPTSTR) ArrayIndex(PR_SAMPLE_DIRECTORY, lpxpl->lpPropArray).Value.LPSZ))
- ulArraySize = CbNewSPropTagArray(sptaStatusRow.cValues);
- else
- {
- /* Adjust for removing a prop tag */
- cActualProps--;
- ulArraySize = CbNewSPropTagArray(sptaStatusRow.cValues - 1);
- }
- /* Allocate the required amount of memory */
- sc = (*lpSOB->AllocateBuffer) (ulArraySize, (LPVOID *) lppPropTagArray);
- if (sc)
- {
- hResult = ResultFromScode(sc);
- lpSOB->hrLastError = hResult;
- goto ret;
- }
- /* Copy the contents of our canned property tag array into the buffer */
- if (ulArraySize)
- {
- memcpy(*lppPropTagArray, &sptaStatusRow, (size_t) ulArraySize);
- (*lppPropTagArray)->cValues = cActualProps;
- }
- ret:
- DebugTraceResult(SOB_GetPropList, hResult);
- return hResult;
- }
- /*
- - SOB_SettingsDialog
- -
- * Purpose:
- * This routine will invoke the Transports Logon dialog to allow
- * the user to change the Logon properties. The lpPropArray on the
- * current session will be updated.
- *
- * Parameters:
- * lpSOB The status object for this transport session
- * ulUIParam The HWnd of the caller (may be null)
- * ulFlags If UI_READONLY will not update the lpPropArray
- *
- * Returns:
- * hResult Indicating success/failure.
- *
- * Operation:
- *
- */
- STDMETHODIMP
- SOB_SettingsDialog(LPSOB lpSOB,
- ULONG ulUIParam,
- ULONG ulFlags)
- {
- HRESULT hResult = hrSuccess;
- SCODE sc = S_OK;
- LPSPropValue lpMyIDArray = NULL;
- LPVOID lpvT, lpvT2;
- ULONG ulCount = MAX_LOGON_PROPERTIES - TEMP_LOGON_PROPERTIES;
- ULONG ulT;
- LPXPL lpxpl = lpSOB->lpxpl;
- LPSPropValue lpPropArray = NULL;
- LPMAPISUP lpMAPISup = lpxpl->lpMAPISup;
- LPPROFSECT lpProfileObj = NULL;
- XPDLG XPDialog;
- BOOL fNeedUI = TRUE;
- BOOL fInCS = FALSE;
- if ((IsBadReadPtr(lpSOB, sizeof(SOB))) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB))
- {
- hResult = ResultFromScode(E_INVALIDARG);
- goto ret;
- }
- if (ulFlags & ~UI_READONLY)
- {
- hResult = ResultFromScode(E_INVALIDARG);
- goto ret;
- }
- /* Get the Critical Section */
- EnterCriticalSection(&(lpxpl->lpxppParent->csTransport));
- fInCS = TRUE;
- sc = ScCopySessionProps(lpxpl, &lpPropArray, NULL);
- if (FAILED(sc))
- goto ret;
- /* Fill in the logon UI structure */
- XPDialog.hInst = lpxpl->lpxppParent->hInst;
- XPDialog.hwnd = (HWND) ulUIParam;
- XPDialog.lppPropArray = &lpPropArray;
- XPDialog.lpPTArray = (LPSPropTagArray) &sptLogonArray;
- XPDialog.AllocateBuffer = lpxpl->AllocateBuffer;
- XPDialog.AllocateMore = lpxpl->AllocateMore;
- XPDialog.FreeBuffer = lpxpl->FreeBuffer;
- XPDialog.lpMalloc = lpxpl->lpxppParent->lpMalloc;
- XPDialog.lpMAPISup = lpxpl->lpMAPISup;
- XPDialog.fLogon = FALSE;
- XPDialog.ulFlags = ulFlags;
- while (fNeedUI)
- {
- sc = ScDoLogonDlg(&XPDialog);
- if (FAILED(sc))
- {
- DebugTraceSc(Logon UI activation, sc);
- goto ret;
- }
- if (lpPropArray)
- {
- /* Got a prop array, make sure everything in it is good */
- for (ulT = 0; ulT < ulCount; ulT++)
- {
- if (PROP_TYPE((lpPropArray)[ulT].ulPropTag) == PT_ERROR)
- {
- DebugTrace("Property %x not available.n", PROP_ID((lpPropArray)[ulT].ulPropTag));
- sc = MAPI_E_NO_ACCESS;
- }
- }
- }
- else
- sc = MAPI_E_NO_ACCESS;
- if (sc)
- {
- DebugTraceSc(Logon UI returning, sc);
- goto ret;
- }
- /* Do some simple validation of the Logon Props */
- sc = ScCheckLogonProps(&XPDialog, TRUE);
- if (sc == MAPI_E_USER_CANCEL)
- goto ret;
- else if (sc == MAPI_E_INVALID_PARAMETER)
- continue;
- else
- fNeedUI = FALSE;
- /* If we get here, everything is fine and we can proceed. But first
- we should write the properties out if the user is willing. */
- ulT = ArrayIndex(PR_SAMPLE_FLAGS, lpPropArray).Value.ul;
- if ((ulT & PR_SAMPLE_FLAG_SAVE_DATA))
- {
- /* Try to open our profile. */
- hResult = lpMAPISup->lpVtbl->OpenProfileSection(lpMAPISup,
- (LPMAPIUID) NULL, MAPI_MODIFY, &lpProfileObj);
- if (HR_FAILED(hResult))
- {
- DebugTraceResult(MAPISUP: :OpenProfileSection, hResult);
- goto ret;
- }
- hResult = lpProfileObj->lpVtbl->SetProps(lpProfileObj,
- ulCount, lpPropArray, NULL);
- if (HR_FAILED(hResult))
- {
- DebugTraceResult(PROFSECT: :SetProps, hResult);
- goto ret;
- }
- }
- }
- /* Allocate initial property array for transport ID. */
- sc = (*lpxpl->AllocateBuffer) (sizeof(SPropValue) * NUM_SENDER_PROPS,
- (LPVOID *) &lpMyIDArray);
- if (sc)
- {
- DebugTraceSc(Sender ID property array allocation, sc);
- goto ret;
- }
- memset(lpMyIDArray, 0, sizeof(SPropValue) * NUM_SENDER_PROPS);
- /* Create the One-Off directly into the property value structure. */
- lpMyIDArray[0].ulPropTag = PR_SENDER_ENTRYID;
- hResult = lpMAPISup->lpVtbl->CreateOneOff(lpMAPISup,
- ArrayIndex(PR_SAMPLE_DISPLAY_NAME, lpPropArray).Value.LPSZ,
- ArrayIndex(PR_SAMPLE_EMAIL_ADDR_TYPE, lpPropArray).Value.LPSZ,
- ArrayIndex(PR_SAMPLE_EMAIL_ADDRESS, lpPropArray).Value.LPSZ,
- fMapiUnicode,
- &lpMyIDArray[0].Value.bin.cb,
- (LPENTRYID *) &lpMyIDArray[0].Value.bin.lpb);
- if (hResult)
- {
- DebugTraceResult(MAPISUP: :CreateOneOff, hResult);
- lpMyIDArray[0].Value.bin.lpb = NULL;
- goto ret;
- }
- /* Create the PR_SENDER_NAME property value. */
- lpvT2 = ArrayIndex(PR_SAMPLE_DISPLAY_NAME, lpPropArray).Value.LPSZ;
- ulT = lstrlen((LPCTSTR) lpvT2) + 1;
- sc = (*lpxpl->AllocateMore) (ulT, (LPVOID) lpMyIDArray,
- (LPVOID *) &lpvT);
- if (sc)
- {
- DebugTraceSc(User Display Name allocation, sc);
- goto ret;
- }
- lstrcpy((LPTSTR) lpvT, (LPCTSTR) lpvT2);
- lpMyIDArray[1].ulPropTag = PR_SENDER_NAME;
- lpMyIDArray[1].Value.LPSZ = (LPTSTR) lpvT;
- /* Create the PR_SENDER_SEARCH_KEY value. */
- lpMyIDArray[2].ulPropTag = PR_SENDER_SEARCH_KEY;
- /* Size of property = type plus colon plus address plus null. */
- ulT = 2 + lstrlen(ArrayIndex(PR_SAMPLE_EMAIL_ADDR_TYPE, lpPropArray).Value.LPSZ) +
- lstrlen(ArrayIndex(PR_SAMPLE_EMAIL_ADDRESS, lpPropArray).Value.LPSZ);
- sc = (*lpxpl->AllocateMore) (ulT, (LPVOID) lpMyIDArray,
- (LPVOID *) &lpvT);
- if (sc)
- {
- DebugTraceSc(User Search Key allocation, sc);
- goto ret;
- }
- /* PR_SENDER_SEARCH_KEY is "TYPE:ADDRESS" folded to uppercase. */
- wsprintf((LPTSTR) lpvT, TEXT("%s:%s"),
- (ArrayIndex(PR_SAMPLE_EMAIL_ADDR_TYPE, lpPropArray).Value.LPSZ),
- (ArrayIndex(PR_SAMPLE_EMAIL_ADDRESS, lpPropArray).Value.LPSZ));
- CharUpperBuff((LPTSTR) lpvT, (UINT)-- ulT);
- lpMyIDArray[2].Value.bin.cb = sizeof(TCHAR) * (1 + lstrlen((LPTSTR) lpvT));
- lpMyIDArray[2].Value.bin.lpb = lpvT;
- /* Replace the original PropArray with the new one. */
- lpxpl->FreeBuffer(lpxpl->lpPropArray);
- lpxpl->lpPropArray = lpPropArray;
- /* Now, free the original User Display Name and Entry-ID */
- if (lpxpl->lpMyIDArray)
- {
- (*lpxpl->FreeBuffer) (lpxpl->lpMyIDArray[0].Value.bin.lpb);
- (*lpxpl->FreeBuffer) (lpxpl->lpMyIDArray);
- }
- lpxpl->lpMyIDArray = lpMyIDArray;
- hResult = HrBuildTransportStatus(lpxpl, STATUSROW_UPDATE);
- ret:
- /* Release the Critical Section. */
- if (fInCS)
- LeaveCriticalSection(&(lpxpl->lpxppParent->csTransport));
- UlRelease(lpProfileObj);
- if (lpPropArray && (lpxpl->lpPropArray != lpPropArray))
- lpxpl->FreeBuffer(lpPropArray);
- if (lpMyIDArray && (lpxpl->lpMyIDArray != lpMyIDArray))
- {
- (*lpxpl->FreeBuffer) (lpMyIDArray[0].Value.bin.lpb);
- (*lpxpl->FreeBuffer) (lpMyIDArray);
- }
- if (!hResult && sc)
- hResult = ResultFromScode(sc);
- DebugTraceResult(SOB_SettingsDialog, hResult);
- return hResult;
- }
- /*
- - SOB_FlushQueues
- -
- * Purpose:
- * Logon object method used by Spooler if FlushQueues is called on
- * the spooler status object.
- *
- * Parameters:
- * lpSOB This pointer for Status Object
- * ulUIParam Window handle
- * cbTargetTransport Count of bytes in Entryid. Zero.
- * lpTargetTransport Entryid of transport. NULL.
- * ulFlags
- *
- * Returns:
- * (HRESULT) E_INVALIDARG if object doesn't
- * look like a XPL; MAPI_E_NO_SUPPORT
- * otherwise.
- *
- * Operation:
- * Validate the object pointer.
- */
- STDMETHODIMP
- SOB_FlushQueues(LPSOB lpSOB,
- ULONG ulUIParam,
- ULONG cbTargetTransport,
- LPENTRYID lpTargetTransport,
- ULONG ulFlags)
- {
- HRESULT hResult;
- if ((IsBadReadPtr(lpSOB, sizeof(SOB))) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB))
- {
- return ResultFromScode(E_INVALIDARG);
- }
- if (ulFlags & FLUSH_UPLOAD)
- lpSOB->lpxpl->ulTransportStatus |= STATUS_OUTBOUND_FLUSH;
- if (ulFlags & FLUSH_DOWNLOAD)
- lpSOB->lpxpl->ulTransportStatus |= STATUS_INBOUND_FLUSH;
- hResult = HrUpdateTransportStatus(lpSOB->lpxpl, 0L);
- return hResult;
- }
- /*
- - Unimplemented functions. Stubbed to give access or NYI.
- -
- */
- STDMETHODIMP
- SOB_SaveChanges(LPSOB lpSOB,
- ULONG ulFlags)
- {
- /* Do parameter validation */
- if (IsBadReadPtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (ulFlags & ~(KEEP_OPEN_READWRITE | KEEP_OPEN_READONLY | FORCE_SAVE)))
- {
- DebugTraceSc(SOB_SaveChanges, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_SaveChanges, MAPI_E_NO_ACCESS);
- return (ResultFromScode(MAPI_E_NO_ACCESS));
- }
- STDMETHODIMP
- SOB_OpenProperty(LPSOB lpSOB,
- ULONG ulPropTag,
- LPCIID lpiid,
- ULONG ulInterfaceOptions,
- ULONG ulFlags,
- LPUNKNOWN * lppUnk)
- {
- /* Do parameter validation */
- if (IsBadReadPtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (!lpiid || IsBadReadPtr(lpiid, sizeof(IID))) ||
- (ulFlags & ~(MAPI_CREATE | MAPI_MODIFY | MAPI_DEFERRED_ERRORS)) ||
- (!lppUnk || IsBadWritePtr(lppUnk, sizeof(LPVOID))))
- {
- DebugTraceSc(SOB_OpenProperty, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- if ( ulInterfaceOptions & ~(MAPI_UNICODE) )
- {
- return ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
- }
- if ( ulInterfaceOptions & MAPI_UNICODE )
- {
- return ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
- }
- DebugTraceSc(SOB_OpenProperty, MAPI_E_NO_SUPPORT);
- return (ResultFromScode(MAPI_E_NO_SUPPORT));
- }
- STDMETHODIMP
- SOB_SetProps(LPSOB lpSOB,
- ULONG cValues,
- LPSPropValue lpPropArray,
- LPSPropProblemArray * lppProblems)
- {
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (cValues && IsBadReadPtr(lpPropArray, (UINT)cValues*sizeof(SPropValue))) ||
- (IsBadWritePtr(lppProblems, sizeof(LPSPropProblemArray))))
- {
- DebugTraceSc(SOB_SetProps, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_SetProps, MAPI_E_NO_ACCESS);
- return (ResultFromScode(MAPI_E_NO_ACCESS));
- }
- STDMETHODIMP
- SOB_DeleteProps(LPSOB lpSOB,
- LPSPropTagArray lpPropTagArray,
- LPSPropProblemArray * lppProblems)
- {
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (!lpPropTagArray) ||
- (IsBadReadPtr(lpPropTagArray, (UINT)lpPropTagArray->cValues*sizeof(ULONG))) ||
- (IsBadWritePtr(lppProblems, sizeof(LPSPropProblemArray))))
- {
- DebugTraceSc(SOB_DeleteProps, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_DeleteProps, MAPI_E_NO_ACCESS);
- return (ResultFromScode(MAPI_E_NO_ACCESS));
- }
- STDMETHODIMP
- SOB_CopyTo(LPSOB lpSOB,
- ULONG ciidExclude,
- LPCIID rgiidExclude,
- LPSPropTagArray lpExcludeProps,
- ULONG ulUIParam,
- LPMAPIPROGRESS lpProgress,
- LPCIID lpInterface,
- LPVOID lpDestObj,
- ULONG ulFlags,
- LPSPropProblemArray * lppProblems)
- {
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (ciidExclude && (!rgiidExclude || IsBadReadPtr(rgiidExclude, (UINT)ciidExclude*sizeof(IID)))) ||
- (lpExcludeProps && IsBadReadPtr(lpExcludeProps, (UINT)lpExcludeProps->cValues*sizeof(ULONG))) ||
- (lpProgress && IsBadReadPtr(lpProgress, sizeof(LPMAPIPROGRESS))) ||
- (!lpInterface || IsBadReadPtr(lpInterface, sizeof(IID))) ||
- (IsBadReadPtr(lpDestObj, sizeof(LPVOID))) ||
- (ulFlags & ~(MAPI_MOVE | MAPI_NOREPLACE | MAPI_DIALOG | MAPI_DECLINE_OK)) ||
- (IsBadWritePtr(lppProblems, sizeof(LPSPropProblemArray))))
- {
- DebugTraceSc(SOB_CopyTo, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_CopyTo, MAPI_E_NO_SUPPORT);
- return (ResultFromScode(MAPI_E_NO_SUPPORT));
- }
- STDMETHODIMP
- SOB_CopyProps(LPSOB lpSOB,
- LPSPropTagArray lpIncludeProps,
- ULONG ulUIParam,
- LPMAPIPROGRESS lpProgress,
- LPCIID lpInterface,
- LPVOID lpDestObj,
- ULONG ulFlags,
- LPSPropProblemArray * lppProblems)
- {
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (lpIncludeProps && IsBadReadPtr(lpIncludeProps, (UINT)lpIncludeProps->cValues*sizeof(ULONG))) ||
- (lpProgress && IsBadReadPtr(lpProgress, sizeof(LPMAPIPROGRESS))) ||
- (!lpInterface || IsBadReadPtr(lpInterface, sizeof(IID))) ||
- (IsBadReadPtr(lpDestObj, sizeof(LPVOID))) ||
- (ulFlags & ~(MAPI_MOVE | MAPI_NOREPLACE | MAPI_DIALOG | MAPI_DECLINE_OK)) ||
- (IsBadWritePtr(lppProblems, sizeof(LPSPropProblemArray))))
- {
- DebugTraceSc(SOB_CopyProps, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_CopyProps, MAPI_E_NO_SUPPORT);
- return (ResultFromScode(MAPI_E_NO_SUPPORT));
- }
- STDMETHODIMP
- SOB_GetNamesFromIDs(LPSOB lpSOB,
- LPSPropTagArray * lppPropTags,
- LPGUID lpPropSet,
- ULONG ulFlags,
- ULONG * lpcPropNames,
- LPMAPINAMEID * * lpppPropNames)
- {
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (IsBadReadPtr(lppPropTags, sizeof(LPSPropTagArray))) ||
- (IsBadReadPtr(lpPropSet, sizeof(GUID))) ||
- (IsBadWritePtr(lpcPropNames, sizeof(ULONG))) ||
- (IsBadWritePtr(lpppPropNames, sizeof(LPVOID))))
- {
- DebugTraceSc(SOB_GetNamesFromIDs, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_GetNamesFromIDs, MAPI_E_NO_SUPPORT);
- return (ResultFromScode(MAPI_E_NO_SUPPORT));
- }
- STDMETHODIMP
- SOB_GetIDsFromNames(LPSOB lpSOB,
- ULONG cPropNames,
- LPMAPINAMEID * lppPropNames,
- ULONG ulFlags,
- LPSPropTagArray * lppPropTags)
- {
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (!lppPropNames || IsBadReadPtr(lppPropNames, (UINT)cPropNames*sizeof(LPMAPINAMEID))) ||
- (IsBadReadPtr(lppPropTags, sizeof(LPSPropTagArray))))
- {
- DebugTraceSc(SOB_GetIDsFromNames, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_GetIDsFromNames, MAPI_E_NO_SUPPORT);
- return (ResultFromScode(MAPI_E_NO_SUPPORT));
- }
- STDMETHODIMP
- SOB_ChangePassword(LPSOB lpSOB,
- LPTSTR lpOldPass,
- LPTSTR lpNewPass,
- ULONG ulFlags)
- {
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (IsBadStringPtr(lpOldPass, MAX_STRING)) ||
- (IsBadStringPtr(lpNewPass, MAX_STRING)) ||
- (ulFlags & ~MAPI_UNICODE))
- {
- DebugTraceSc(SOB_ChangePassword, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- if ( ulFlags & MAPI_UNICODE )
- {
- DebugTraceSc(SOB_ChangePassword, MAPI_E_BAD_CHARWIDTH);
- return ResultFromScode( MAPI_E_BAD_CHARWIDTH );
- }
- DebugTraceSc(SOB_ChangePassword, MAPI_E_NO_SUPPORT);
- return (ResultFromScode(MAPI_E_NO_SUPPORT));
- }
- STDMETHODIMP
- SOB_ValidateState(LPSOB lpSOB,
- ULONG ulUIParam,
- ULONG ulFlags)
- {
- ULONG ulFlagMask = REFRESH_XP_HEADER_CACHE |
- PROCESS_XP_HEADER_CACHE |
- FORCE_XP_CONNECT |
- FORCE_XP_DISCONNECT |
- SUPPRESS_UI;
- /* Do parameter validation */
- if (IsBadWritePtr(lpSOB, sizeof(SOB)) ||
- (lpSOB->lcInit == 0) ||
- (lpSOB->lpsobMyAddress != lpSOB) ||
- (ulFlags & (~(ulFlagMask))))
- {
- DebugTraceSc(SOB_ValidateState, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- DebugTraceSc(SOB_ValidateState, MAPI_E_NO_SUPPORT);
- return (ResultFromScode(MAPI_E_NO_SUPPORT));
- }
- /* The following array maps a string identifier (IDS) to status code */
- /* (SCODE). The order of SCODEs in the array has an external */
- /* dependency: the order of elements in the array is dictated by */
- /* the IDS definitions in xpresrc.h. This implicit association must */
- /* be maintained for the strings associated with string identifiers */
- /* to make sense. Thus, if either this structure or the rc.h defines */
- /* changes, the other must change to match it. */
- SCODE mpIdsScode[] =
- {
- SUCCESS_SUCCESS,
- MAPI_E_BUSY,
- MAPI_E_CALL_FAILED,
- MAPI_E_INVALID_PARAMETER,
- MAPI_E_NO_ACCESS,
- MAPI_E_NO_SUPPORT,
- MAPI_E_NOT_FOUND,
- MAPI_E_UNKNOWN_FLAGS,
- MAPI_E_VERSION,
- MAPI_E_NOT_ENOUGH_MEMORY,
- MAPI_W_ERRORS_RETURNED
- };
- /*
- * MapScodeSz
- *
- * Purpose:
- * Look up an SCODE in a mapping of IDS <-> SCODE to find its
- * associated informational string and return it (with memory
- * allocated by this function) to the caller.
- *
- * Arguments:
- * sc The SCODE to look up.
- * lpxpl Pointer to the Transport Logon object
- * lppszError Location in which to place an address to a
- * newly allocated buffer containing the
- * informational string associated with scArg.
- *
- * Returns:
- * HRESULT
- *
- * Errors:
- * MAPI_E_NO_MEMORY Could not allocate space for
- * the return string.
- */
- HRESULT
- MapScodeSz(SCODE scArg, LPXPL lpxpl, LPTSTR * lppszError)
- {
- HRESULT hr = hrSuccess;
- SCODE sc = SUCCESS_SUCCESS;
- ULONG cb;
- UINT ui;
- UINT ids;
- UINT uiMax = sizeof mpIdsScode / sizeof mpIdsScode[0];
- TCHAR rgch[512];
- if (!lppszError || IsBadWritePtr(lppszError, sizeof(LPVOID)))
- {
- DebugTrace("Bad lppszError in MapScodeSzn");
- return ResultFromScode(E_INVALIDARG);
- }
- *lppszError = NULL;
- /* Linear search in mpIdsScode for sc. */
- for (ui = 0; ui < uiMax; ui++)
- if (mpIdsScode[ui] == scArg)
- break;
- if (ui == uiMax)
- ids = IDS_UNKNOWN_ERROR;
- else
- ids = ui + LIB_ERRORS;
- if (!LoadString(lpxpl->lpxppParent->hInst, ids, rgch, sizeof(rgch)))
- {
- hr = ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY);
- DebugTraceResult(LoadString failed in MapScodeSz, hr);
- goto ret;
- }
- /* Allocate memory for return variable and set it */
- cb = (lstrlen(rgch) + 1) * sizeof(TCHAR);
- sc = lpxpl->AllocateBuffer(cb, (LPVOID *) lppszError);
- if (sc != SUCCESS_SUCCESS)
- {
- hr = ResultFromScode(sc);
- DebugTraceResult(AllocateBuffer failed in MapScodeSz, hr);
- goto ret;
- }
- lstrcpy(*lppszError, rgch);
- ret:
- DebugTraceResult(MapScodeSz, hr);
- return hr;
- }