//$--HrGWResolveAddress@------------------------------------------------------- // Returns the entry ID for the recipient identified by a given address. // ----------------------------------------------------------------------------- HRESULT HrGWResolveAddressW( IN LPABCONT lpGalABCont, // pointer to GAL container IN LPCWSTR lpszAddress, // pointer to proxy address OUT BOOL *lpfMapiRecip, // MAPI recipient OUT ULONG *lpcbEntryID, // count of bytes in entry ID OUT LPENTRYID *lppEntryID) // pointer to entry ID { HRESULT hr = NOERROR; LPSTR lpszAddressA = NULL; DEBUGPUBLIC( "HrGWResolveAddressW()"); hr = CHK_HrGWResolveAddressW( lpGalABCont, lpszAddress, lpfMapiRecip, lpcbEntryID, lppEntryID); if( FAILED( hr)) RETURN( hr); // MAPI doesn't officially support resolution of UNICODE // addresses. Therefore, the address is converted to ANSI... hr = HrStrWToStrA( lpszAddress, &lpszAddressA); if( FAILED( hr)) goto cleanup; hr = HrGWResolveAddressA( lpGalABCont, lpszAddressA, lpfMapiRecip, lpcbEntryID, lppEntryID); cleanup: MAPIFREEBUFFER( lpszAddressA); RETURN(hr); }
//$--HrMAPISetAddressList-------------------------------------------------------- // Set an address list. // ----------------------------------------------------------------------------- HRESULT HrMAPISetAddressList( // RETURNS: return code IN ULONG iEntry, // index of address list entry IN ULONG cProps, // count of values in address list // entry IN LPSPropValue lpPropValues, // pointer to address list entry IN OUT LPADRLIST lpAdrList) // pointer to address list pointer { HRESULT hr = NOERROR; SCODE sc = 0; LPSPropValue lpNewPropValues = NULL; ULONG cBytes = 0; DEBUGPUBLIC("HrMAPISetAddressList()\n"); hr = CHK_HrMAPISetAddressList( iEntry, cProps, lpPropValues, lpAdrList); if(FAILED(hr)) RETURN(hr); if(iEntry >= lpAdrList->cEntries) { hr = HR_LOG(E_FAIL); goto cleanup; } sc = ScDupPropset( cProps, lpPropValues, MAPIAllocateBuffer, &lpNewPropValues); if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } if(lpAdrList->aEntries[iEntry].rgPropVals != NULL) { MAPIFREEBUFFER(lpAdrList->aEntries[iEntry].rgPropVals); } lpAdrList->aEntries[iEntry].cValues = cProps; lpAdrList->aEntries[iEntry].rgPropVals = lpNewPropValues; cleanup: RETURN(hr); }
//$--HrMAPIGetPropToFile--------------------------------------------------------- // Get a property and put in a given file. // ----------------------------------------------------------------------------- HRESULT HrMAPIGetPropToFile( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag IN LPSTR lpszFilename, // pointer to destination file name OUT ULONG *lpcbProp) // pointer to count of bytes address // variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; SCODE sc = 0; LPSTREAM lpStream = NULL; HANDLE hFile = NULL; ULONG ulBytesRead = 0; LPBYTE lpbBlock = NULL; DWORD dwBytesWritten = 0; DEBUGPUBLIC("HrMAPIGetPropToFile()\n"); hr = CHK_HrMAPIGetPropToFile( lpObj, ulPropTag, lpszFilename, lpcbProp); if(FAILED(hr)) RETURN(hr); // Open a stream on the property hrT = MAPICALL(lpObj)->OpenProperty( /*lpObj,*/ ulPropTag, (LPIID)&IID_IStream, STGM_READ, MAPI_DEFERRED_ERRORS, (LPUNKNOWN *)&lpStream); if(FAILED(hrT)) { // Streams are not supported by provider if((hrT == MAPI_E_NO_SUPPORT) || (hrT == MAPI_E_INTERFACE_NOT_SUPPORTED)) { ULONG PropType = 0; lpStream = NULL; MODULE_WARNING1("Streams are not supported by provider [%08lx]",hrT); PropType = PROP_TYPE(ulPropTag); // Read property into memory switch(PropType) { case PT_BINARY: hr = HrMAPIGetPropBinary( lpObj, ulPropTag, &ulBytesRead, (void **)&lpbBlock); break; default: hr = HrMAPIGetPropString( lpObj, ulPropTag, &ulBytesRead, (void **)&lpbBlock); } } else { hr = HR_LOG(E_FAIL); goto cleanup; } if(FAILED(hr)) { goto cleanup; } } hFile = CreateFile( lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFile == INVALID_HANDLE_VALUE) { hr = HR_LOG(E_FAIL); goto cleanup; } // Copy propery value to the file if(lpStream != NULL) { sc = MAPIAllocateBuffer(EDK_CBTRANSFER, (void **)&lpbBlock); // An error occured allocating the block buffer if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } for (;;) { // Read a block from the stream hrT = /*OLECALL*/(lpStream)->Read( /*lpStream,*/ lpbBlock, EDK_CBTRANSFER, &ulBytesRead); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } if(ulBytesRead == 0L) break; // Write the block to the file hr = _HrWriteFile(hFile, ulBytesRead, lpbBlock); if(FAILED(hr)) { goto cleanup; } } } else { // Write the block to the file hr = _HrWriteFile(hFile, ulBytesRead, lpbBlock); if(FAILED(hr)) { goto cleanup; } } cleanup: // Close the file if(hFile != NULL) { if(CloseHandle(hFile) == FALSE) { hr = HR_LOG(E_FAIL); } } // Release the stream //ULOLERELEASE(lpStream); if (lpStream != NULL) { lpStream->Release(); } lpStream = NULL; MAPIFREEBUFFER(lpbBlock); RETURN(hr); }
//$--HrMAPIGetPropSystime-------------------------------------------------------- // Get a systime property. // ----------------------------------------------------------------------------- HRESULT HrMAPIGetPropSystime( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag OUT LPFILETIME lpSystime) // pointer to property variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; ULONG cValues = 0; LPSPropValue lpPropValue = NULL; SCODE sc = 0; SizedSPropTagArray(1, rgPropTag) = { 1, { 0 } }; DEBUGPUBLIC("HrMAPIGetPropSystime()\n"); hr = CHK_HrMAPIGetPropSystime( lpObj, ulPropTag, lpSystime); if(FAILED(hr)) RETURN(hr); // Initialize FILETIME structure ZeroMemory(lpSystime, sizeof(FILETIME)); rgPropTag.cValues = 1; rgPropTag.aulPropTag[0] = ulPropTag; hrT = MAPICALL(lpObj)->GetProps( /*lpObj,*/ (LPSPropTagArray)&rgPropTag, fMapiUnicode, &cValues, &lpPropValue); if(hrT == MAPI_W_ERRORS_RETURNED) { if((lpPropValue != NULL) && (lpPropValue->Value.ul == MAPI_E_NOT_FOUND)) { hr = HR_LOG(MAPI_E_NOT_FOUND); } else { hr = HR_LOG(E_FAIL); } goto cleanup; } if(FAILED(hrT)) { lpPropValue = NULL; hr = HR_LOG(E_FAIL); goto cleanup; } ASSERTERROR(cValues != 0, "ZERO cValues variable"); ASSERTERROR(lpPropValue != NULL, "NULL lpPropValue variable"); lpSystime->dwLowDateTime = lpPropValue->Value.ft.dwLowDateTime; lpSystime->dwHighDateTime = lpPropValue->Value.ft.dwHighDateTime; cleanup: MAPIFREEBUFFER(lpPropValue); RETURN(hr); }
//$--HrMAPIGetPropLong----------------------------------------------------------- // Get a long property. // ----------------------------------------------------------------------------- HRESULT HrMAPIGetPropLong( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag OUT ULONG *lpulProp) // pointer to property variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; ULONG cValues = 0; LPSPropValue lpPropValue = NULL; SCODE sc = 0; SizedSPropTagArray(1, rgPropTag) = { 1, { 0 } }; DEBUGPUBLIC("HrMAPIGetPropLong()\n"); hr = CHK_HrMAPIGetPropLong( lpObj, ulPropTag, lpulProp); if(FAILED(hr)) RETURN(hr); *lpulProp = 0; rgPropTag.cValues = 1; rgPropTag.aulPropTag[0] = ulPropTag; hrT = MAPICALL(lpObj)->GetProps( /*lpObj,*/ (LPSPropTagArray)&rgPropTag, fMapiUnicode, &cValues, &lpPropValue); if(hrT == MAPI_W_ERRORS_RETURNED) { if((lpPropValue != NULL) && (lpPropValue->Value.ul == MAPI_E_NOT_FOUND)) { hr = HR_LOG(MAPI_E_NOT_FOUND); } else { hr = HR_LOG(E_FAIL); } goto cleanup; } if(FAILED(hrT)) { lpPropValue = NULL; hr = HR_LOG(E_FAIL); goto cleanup; } ASSERTERROR(cValues != 0, "ZERO cValues variable"); ASSERTERROR(lpPropValue != NULL, "NULL lpPropValue variable"); *lpulProp = lpPropValue->Value.ul; cleanup: MAPIFREEBUFFER(lpPropValue); RETURN(hr); }
//$--HrMAPIGetPropBinary--------------------------------------------------------- // Get a binary property. // ----------------------------------------------------------------------------- HRESULT HrMAPIGetPropBinary( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag OUT ULONG *lpcbProp, // count of bytes in property OUT LPVOID *lppvProp) // pointer to property address variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; ULONG cValues = 0; LPSPropValue lpPropValue = NULL; ULONG cbProp = 0; SCODE sc = 0; SizedSPropTagArray(1, rgPropTag) = { 1, { 0 } }; DEBUGPUBLIC("HrMAPIGetPropBinary()\n"); hr = CHK_HrMAPIGetPropBinary( lpObj, ulPropTag, lpcbProp, lppvProp); if(FAILED(hr)) RETURN(hr); *lpcbProp = 0L; *lppvProp = NULL; rgPropTag.cValues = 1; rgPropTag.aulPropTag[0] = ulPropTag; hrT = MAPICALL(lpObj)->GetProps( /*lpObj,*/ (LPSPropTagArray)&rgPropTag, fMapiUnicode, &cValues, &lpPropValue); if(hrT == MAPI_W_ERRORS_RETURNED) { if((lpPropValue != NULL) && (lpPropValue->Value.ul == MAPI_E_NOT_FOUND)) { hr = HR_LOG(MAPI_E_NOT_FOUND); } else { hr = HR_LOG(E_FAIL); } goto cleanup; } if(FAILED(hrT)) { lpPropValue = NULL; hr = HR_LOG(E_FAIL); goto cleanup; } ASSERTERROR(cValues != 0, "ZERO cValues variable"); ASSERTERROR(lpPropValue != NULL, "NULL lpPropValue variable"); cbProp = lpPropValue->Value.bin.cb; sc = MAPIAllocateBuffer(cbProp, lppvProp); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } ASSERTERROR(*lppvProp != NULL, "NULL *lppvProp pointer"); // Copy property value memcpy(*lppvProp, lpPropValue->Value.bin.lpb, cbProp); *lpcbProp = cbProp; cleanup: MAPIFREEBUFFER(lpPropValue); RETURN(hr); }
//$--HrMAPIOpenCachedProp-------------------------------------------------------- // // DESCRIPTION: Create a new (local) IPropData object in which the original object // properties are cached. The local cached can be created for // reading (for use with GetProp calls) for for writing (for use with // SetProp calls). The purpose of this function and HrMAPICloseCachedProp // is to reduce the number of remote procedure calls made by code // which performs many GetProp or SetProp calls on an object. // // INPUT: lpObj -- property object to cache // lpPropList -- list of properties to cache (for reading) // defaults to all properties if NULL. // ulFlags -- read OR write access flag (EDK_CACHE_READ // or EDK_CACHE_WRITE) // // OUTPUT: lppCachedObj -- cached property object // // RETURNS: HRESULT -- NOERROR if successful, // E_INVALIDARG if bad input // E_FAIL otherwise. // // NOTE: This function creates a cached object for reading only // or for writing only. It does not support and object // for both reading and writing. // // ----------------------------------------------------------------------------- HRESULT HrMAPIOpenCachedProp( // RETURNS: return code IN LPMAPIPROP lpObj, // source object IN LPSPropTagArray lpPropList, // list of properties to cache IN ULONG ulFlags, // open for reading only or for writing only OUT LPPROPDATA FAR * lppCachedObj) // cached version of source object { HRESULT hr = NOERROR; LPSPropProblemArray lpProblems = NULL; LPSPropValue lpPropVals = NULL; ULONG ulPropCount= 0; // number of properties DEBUGPUBLIC("HrMAPIOpenCachedProp()\n"); hr = CHK_HrMAPIOpenCachedProp( lpObj, lpPropList, ulFlags, lppCachedObj); if(FAILED(hr)) RETURN(hr); *lppCachedObj = NULL; // // Call CreateIProp() to create a new IPropData object. // Since IPropData inherits from IMAPIProp, we can use it as our // IMAPIProp cache pointer. // hr = CreateIProp( &IID_IMAPIPropData, // interface type MAPIAllocateBuffer, // allocation routine MAPIAllocateMore, // allocate more routine MAPIFreeBuffer, // deallocation routine 0, // reserved lppCachedObj); // address of pointer to new IPropData object if(FAILED(hr)) { hr = HR_LOG(E_FAIL); goto cleanup; } // If we are creating the cache for reading, then // we must populate the new object with properties. // Otherwise, we pass an "empty" object back to the user // for property writing. if ( ulFlags == EDK_CACHE_READ ) { // Get properties from remote object and set these same properties // on the local object. hr = MAPICALL(lpObj)->GetProps( /*lpObj,*/ // for C to C++ vtbl resolution lpPropList, // Get all properties fMapiUnicode, // flags &ulPropCount, // number of properties retrieved &lpPropVals); // property values structure pointer // handle errors // If there is an error, release the cached object if ( FAILED(hr) || (hr == MAPI_W_ERRORS_RETURNED) ) { hr = HR_LOG(E_FAIL); goto cleanup; } hr = MAPICALL(*lppCachedObj)->SetProps(/**lppCachedObj,*/ ulPropCount, lpPropVals, &lpProblems); // handle errors if ( FAILED(hr) ) { hr = HR_LOG(E_FAIL); goto cleanup; } // Check to see if there were any problems setting the // properties if ( lpProblems != NULL ) { // We have an error hr = HR_LOG(E_FAIL); goto cleanup; } } // end if creating cache for reading // We have been successful. cleanup: // Handle error case if ( FAILED(hr) ) { ULRELEASE(*lppCachedObj); } // Free MAPI buffers MAPIFREEBUFFER(lpProblems); MAPIFREEBUFFER(lpPropVals); RETURN(hr); }
//$--HrMAPICloseCachedProp------------------------------------------------------- // // DESCRIPTION: If object was created as a write cache, // copy properties in local cached object // back to original remote object. // // INPUT: lpCachedObj -- cached property object // lpOriginalObj -- original property object // ulFlags -- read cache or write cache flag (EDK_CACHE_READ // or EDK_CACHE_WRITE) // // OUTPUT: lppProblems -- set to the property problem array returned // by if there were problems setting properties on the original // object // // NOTES: lppProblems: It may be set, even though overall call // is successful. This is because all of the SetProps have been "deferred" on the // original object until this call, the user will need to evaluate // the contents of the lppProblems buffer pointer based on which // properties he/or she actually tried to set. // // RETURNS: HRESULT -- NOERROR if successful, // E_INVALIDARG if bad input // E_FAIL otherwise // // lppProblems will only be valid if return code // is NOERROR. // // ----------------------------------------------------------------------------- HRESULT HrMAPICloseCachedProp( // RETURNS: return code IN LPPROPDATA lpCachedObj, // cached property object IN LPMAPIPROP lpOriginalObj, // original object IN ULONG ulFlags, // cache type (EDK_CACHE_READ or EDK_CACHE_WRITE) OUT LPSPropProblemArray FAR * lppProblems) // pointer to property problems array if problems setting properties { HRESULT hr = NOERROR; ULONG ulPropCount = 0; // number of properties LPSPropValue lpPropVals = NULL; // property values DEBUGPUBLIC("HrMAPICloseCachedProp()\n"); hr = CHK_HrMAPICloseCachedProp( lpCachedObj, lpOriginalObj, ulFlags, lppProblems); if(FAILED(hr)) RETURN(hr); *lppProblems = NULL; // initialize output // If the cache was opened for writing, copy all of the // properties from the cached object back to the original // object. if ( ulFlags == EDK_CACHE_WRITE ) { // Get properties from local object and set these same properties // on the remote object. CopyTo() is not sufficient, because it // won't copy read-only properties. hr = MAPICALL(lpCachedObj)->GetProps( /*lpCachedObj,*/ // for C to C++ vtbl resolution NULL, // get all properties fMapiUnicode, // flags &ulPropCount, // number of properties retrieved &lpPropVals); // property values structure pointer // handle errors if ( FAILED(hr) || (hr == MAPI_W_ERRORS_RETURNED) ) { hr = HR_LOG(E_FAIL); goto cleanup; } // Set all properties retrieved in the remote object hr = MAPICALL(lpOriginalObj)->SetProps(/*lpOriginalObj,*/ ulPropCount, lpPropVals, lppProblems); // handle errors if ( FAILED(hr) ) { hr = HR_LOG(E_FAIL); goto cleanup; } } // end if cache created for writing // The user will need to evaluate why the set property // call has failed (if *lppProblems has been set // by the SetProps call) based on what properties (if any) // they have set in the cached object. // Overall, we have been successful. cleanup: // Free MAPI buffers MAPIFREEBUFFER(lpPropVals); RETURN(hr); }
//$--HrMAPIMoveOneProp----------------------------------------------------------- // Move one property from a source object to a destination object. // ----------------------------------------------------------------------------- HRESULT HrMAPIMoveOneProp( // RETURNS: return code IN LPMAPIPROP lpSrcObj, // pointer to source object IN ULONG ulSrcPropTag, // source property tag IN ULONG ulDstPropTag, // destination property tag IN BOOL IsMust, // TRUE if a required property IN BOOL IsReplace, // TRUE if existing destination // property can be replaced IN OUT LPMAPIPROP lpDstObj) // pointer to destination object { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; SCODE sc = 0; ULONG cProps = 0; LPSPropValue lpProps = NULL; SizedSPropTagArray(1, rgPropTag) = { 1, 0 }; DEBUGPUBLIC("HrMAPIMoveOneProp()\n"); hr = CHK_HrMAPIMoveOneProp( lpSrcObj, ulSrcPropTag, ulDstPropTag, IsMust, IsReplace, lpDstObj); if(FAILED(hr)) RETURN(hr); if(PROP_TYPE(ulSrcPropTag) != PROP_TYPE(ulDstPropTag)) { hr = HR_LOG(E_FAIL); goto cleanup; } if((IsReplace == FALSE) && FPropExists(lpDstObj, ulDstPropTag)) { MODULE_WARNING("Destination property exists and not overwritten."); goto cleanup; } rgPropTag.cValues = 1; rgPropTag.aulPropTag[0] = ulSrcPropTag; hrT = MAPICALL(lpSrcObj)->GetProps( /*lpSrcObj,*/ (LPSPropTagArray)&rgPropTag, fMapiUnicode, &cProps, &lpProps); if(hrT == MAPI_W_ERRORS_RETURNED) { hrT = lpProps->Value.ul; if(hrT != MAPI_E_NOT_FOUND) { hr = HR_LOG(E_FAIL); } else if(IsMust == TRUE) { hr = HR_LOG(MAPI_E_NOT_FOUND); } goto cleanup; } if(FAILED(hrT)) { lpProps = NULL; hr = HR_LOG(E_FAIL); goto cleanup; } ASSERTERROR(cProps != 0, "ZERO cProps variable"); ASSERTERROR(lpProps != NULL, "NULL lpProps variable"); lpProps->ulPropTag = ulDstPropTag; hrT = MAPICALL(lpDstObj)->SetProps( /*lpDstObj,*/ cProps, lpProps, NULL); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } cleanup: MAPIFREEBUFFER(lpProps); RETURN(hr); }
//$--HrMAPIAppendSPropValues----------------------------------------------------- // Append one set of SPropValue's to another. // ----------------------------------------------------------------------------- HRESULT HrMAPIAppendSPropValues( // RETURNS: return code IN ULONG cHeadProps, // count of property values in head IN LPSPropValue lpHeadProps, // pointer to property values in // head IN ULONG cTailProps, // count of property values in tail IN LPSPropValue lpTailProps, // pointer to property values in // tail OUT ULONG *lpcNewProps, // pointer to count of property // values OUT LPSPropValue *lppNewProps) // pointer to property values { HRESULT hr = NOERROR; SCODE sc = 0; ULONG cNewProps = 0; LPSPropValue lpTmpProps = NULL; LPSPropValue lpNewProps = NULL; ULONG cBytes = 0; ULONG i = 0; ULONG j = 0; DEBUGPUBLIC("HrMAPIAppendSPropValues()\n"); hr = CHK_HrMAPIAppendSPropValues( cHeadProps, lpHeadProps, cTailProps, lpTailProps, lpcNewProps, lppNewProps); if(FAILED(hr)) RETURN(hr); *lpcNewProps = 0; *lppNewProps = NULL; cNewProps = cHeadProps + cTailProps; cBytes = CbSPropValue(cNewProps); sc = MAPIAllocateBuffer(cBytes, (void **)&lpTmpProps); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Copy existing property values for(i = 0; i < cHeadProps; i++) { lpTmpProps[i] = lpHeadProps[i]; } for(i = cHeadProps, j = 0; i < cNewProps; i++, j++) { lpTmpProps[i] = lpTailProps[j]; } sc = ScDupPropset( cNewProps, lpTmpProps, MAPIAllocateBuffer, &lpNewProps); if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } *lpcNewProps = cNewProps; *lppNewProps = lpNewProps; cleanup: MAPIFREEBUFFER(lpTmpProps); RETURN(hr); }
//$--HrMAPISetPropFromFile------------------------------------------------------- // Set a property from a given file. // ----------------------------------------------------------------------------- HRESULT HrMAPISetPropFromFile( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag IN LPSTR lpszFilename, // pointer to source file name OUT ULONG *lpcbProp) // pointer to count of bytes address // variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; SCODE sc = 0; LPSTREAM lpStream = NULL; HFILE hFile = HFILE_ERROR; OFSTRUCT ofStruct = {0}; DWORD dwBytesRead = 0; LPBYTE lpbBlock = NULL; ULONG ulBytesWritten = 0; ULARGE_INTEGER ll = {0,0}; ULONG ulFileSize = 0; BYTE bLastByte = 0xFF; ULONG cbProp = 0; DEBUGPUBLIC("HrMAPISetPropFromFile()\n"); hr = CHK_HrMAPISetPropFromFile( lpObj, ulPropTag, lpszFilename, lpcbProp); if(FAILED(hr)) RETURN(hr); *lpcbProp = 0; // Open a stream on the property hrT = MAPICALL(lpObj)->OpenProperty( /*lpObj,*/ ulPropTag, (LPIID)&IID_IStream, STGM_DIRECT | STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, MAPI_CREATE | MAPI_MODIFY | MAPI_DEFERRED_ERRORS, (LPUNKNOWN *)&lpStream); if(FAILED(hrT)) { // Streams are not supported by provider if((hrT == MAPI_E_NO_SUPPORT) || (hrT == MAPI_E_INTERFACE_NOT_SUPPORTED)) { lpStream = NULL; } else { hr = HR_LOG(E_FAIL); goto cleanup; } } hFile = OpenFile( lpszFilename, &ofStruct, OF_READ); if(hFile == HFILE_ERROR) { hr = HR_LOG(E_FAIL); goto cleanup; } // Get file size if((ulFileSize = GetFileSize((HANDLE)hFile, NULL)) == (DWORD)HFILE_ERROR) { hr = HR_LOG(E_FAIL); goto cleanup; } if(PROP_TYPE(ulPropTag) == PT_UNICODE) { if((ulFileSize % sizeof(wchar_t)) != 0) { hr = HR_LOG(E_FAIL); goto cleanup; } } cbProp = ulFileSize; // Copy propery value to the file if(lpStream != NULL) { // Allocate memory for the block buffer sc = MAPIAllocateBuffer(EDK_CBTRANSFER, (void **)&lpbBlock); // An error occured allocating the block buffer if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } ll.LowPart = ulFileSize; ll.HighPart = 0L; hrT = /*OLECALL*/(lpStream)->SetSize(/*lpStream,*/ ll); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } for (;;) { BOOL fStatus; // Read a block from the file fStatus = ReadFile( (HANDLE)hFile, lpbBlock, EDK_CBTRANSFER, &dwBytesRead, NULL); if(fStatus == FALSE) { hr = HR_LOG(E_FAIL); goto cleanup; } if(dwBytesRead == 0L) break; bLastByte = lpbBlock[dwBytesRead - 1L]; // Write a block to the stream hrT = /*OLECALL*/(lpStream)->Write( /*lpStream,*/ lpbBlock, dwBytesRead, &ulBytesWritten); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } if(ulBytesWritten < dwBytesRead) { hr = HR_LOG(MAPI_E_NOT_ENOUGH_DISK); goto cleanup; } } if((PROP_TYPE(ulPropTag) == PT_STRING8) || (PROP_TYPE(ulPropTag) == PT_UNICODE)) { // NULL terminate if not already if(bLastByte != 0) { // Initialize with enough zeroes for a NULL character ZeroMemory(lpbBlock, sizeof(wchar_t)); if(PROP_TYPE(ulPropTag) == PT_UNICODE) { dwBytesRead = sizeof(wchar_t); } else { dwBytesRead = 1L; } ulBytesWritten = 0L; // Write a block to the stream hrT = /*OLECALL*/(lpStream)->Write( /*lpStream,*/ lpbBlock, dwBytesRead, &ulBytesWritten); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } if(ulBytesWritten < dwBytesRead) { hr = HR_LOG(MAPI_E_NOT_ENOUGH_DISK); goto cleanup; } cbProp += ulBytesWritten; } } } else { BOOL fStatus = FALSE; ULONG PropType = 0; // Allocate the memory for the property value sc = MAPIAllocateBuffer( ulFileSize + 2 * sizeof(wchar_t), (void **)&lpbBlock); // An error occured allocating the block buffer if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } // Read the property value into memory fStatus = ReadFile( (HANDLE)hFile, lpbBlock, ulFileSize, &dwBytesRead, NULL); if(fStatus == FALSE) { hr = HR_LOG(E_FAIL); goto cleanup; } // Check if the entire file was read if(dwBytesRead != ulFileSize) { hr = HR_LOG(E_FAIL); goto cleanup; } if((PROP_TYPE(ulPropTag) == PT_STRING8) || (PROP_TYPE(ulPropTag) == PT_UNICODE)) { // NULL terminate if not already bLastByte = lpbBlock[dwBytesRead - 1L]; if(bLastByte != 0) { if(PROP_TYPE(ulPropTag) == PT_UNICODE) { ((wchar_t *)lpbBlock)[dwBytesRead/sizeof(wchar_t)] = '\0'; ulFileSize += sizeof(wchar_t); } else { lpbBlock[dwBytesRead] = 0; ulFileSize++; } cbProp = ulFileSize; } } PropType = PROP_TYPE(ulPropTag); // Set property switch(PropType) { case PT_BINARY: hr = HrMAPISetPropBinary( lpObj, ulPropTag, ulFileSize, &lpbBlock); break; default: hr = HrMAPISetPropString( lpObj, ulPropTag, &lpbBlock); } } cleanup: // Close the file if(hFile != HFILE_ERROR) { if(CloseHandle((HANDLE)hFile) == FALSE) { hr = HR_LOG(E_FAIL); } } // Release the stream //ULOLERELEASE(lpStream); if(lpStream != NULL) { lpStream->Release(); } lpStream = NULL; MAPIFREEBUFFER(lpbBlock); if(SUCCEEDED(hr)) { *lpcbProp = cbProp; } RETURN(hr); }
//$--HrFindExchangeGlobalAddressList------------------------------------------------- // Returns the entry ID of the global address list container in the address // book. // ----------------------------------------------------------------------------- HRESULT HrFindExchangeGlobalAddressList( // RETURNS: return code IN LPADRBOOK lpAdrBook, // address book pointer OUT ULONG *lpcbeid, // pointer to count of bytes in entry ID OUT LPENTRYID *lppeid) // pointer to entry ID pointer { HRESULT hr = NOERROR; ULONG ulObjType = 0; ULONG i = 0; LPMAPIPROP lpRootContainer = NULL; LPMAPIPROP lpContainer = NULL; LPMAPITABLE lpContainerTable = NULL; LPSRowSet lpRows = NULL; ULONG cbContainerEntryId = 0; LPENTRYID lpContainerEntryId = NULL; LPSPropValue lpCurrProp = NULL; SRestriction SRestrictAnd[2] = {0}; SRestriction SRestrictGAL = {0}; SPropValue SPropID = {0}; SPropValue SPropProvider = {0}; BYTE muid[] = MUIDEMSAB; SizedSPropTagArray(1, rgPropTags) = { 1, { PR_ENTRYID, } }; DEBUGPUBLIC("HrFindExchangeGlobalAddressList()"); hr = CHK_HrFindExchangeGlobalAddressList( lpAdrBook, lpcbeid, lppeid); if(FAILED(hr)) RETURN(hr); *lpcbeid = 0; *lppeid = NULL; // Open the root container of the address book hr = MAPICALL(lpAdrBook)->OpenEntry( /*lpAdrBook,*/ 0, NULL, NULL, MAPI_DEFERRED_ERRORS, &ulObjType, (LPUNKNOWN FAR *)&lpRootContainer); if(FAILED(hr)) { goto cleanup; } if(ulObjType != MAPI_ABCONT) { hr = HR_LOG(E_FAIL); goto cleanup; } // Get the hierarchy table of the root container hr = MAPICALL(((LPABCONT)lpRootContainer))->GetHierarchyTable( /*(LPABCONT)lpRootContainer,*/ MAPI_DEFERRED_ERRORS|CONVENIENT_DEPTH, &lpContainerTable); if(FAILED(hr)) { goto cleanup; } // Restrict the table to the global address list (GAL) // --------------------------------------------------- // Initialize provider restriction to only Exchange providers SRestrictAnd[0].rt = RES_PROPERTY; SRestrictAnd[0].res.resProperty.relop = RELOP_EQ; SRestrictAnd[0].res.resProperty.ulPropTag = PR_AB_PROVIDER_ID; SPropProvider.ulPropTag = PR_AB_PROVIDER_ID; SPropProvider.Value.bin.cb = 16; SPropProvider.Value.bin.lpb = (LPBYTE)muid; SRestrictAnd[0].res.resProperty.lpProp = &SPropProvider; // Initialize container ID restriction to only GAL container SRestrictAnd[1].rt = RES_PROPERTY; SRestrictAnd[1].res.resProperty.relop = RELOP_EQ; SRestrictAnd[1].res.resProperty.ulPropTag = PR_EMS_AB_CONTAINERID; SPropID.ulPropTag = PR_EMS_AB_CONTAINERID; SPropID.Value.l = 0; SRestrictAnd[1].res.resProperty.lpProp = &SPropID; // Initialize AND restriction SRestrictGAL.rt = RES_AND; SRestrictGAL.res.resAnd.cRes = 2; SRestrictGAL.res.resAnd.lpRes = &SRestrictAnd[0]; // Restrict the table to the GAL - only a single row should remain // Get the row corresponding to the GAL // // Query all the rows // hr = HrQueryAllRows( lpContainerTable, (LPSPropTagArray)&rgPropTags, &SRestrictGAL, NULL, 0, &lpRows); if(FAILED(hr) || (lpRows == NULL) || (lpRows->cRows != 1)) { hr = HR_LOG(E_FAIL); goto cleanup; } // Get the entry ID for the GAL lpCurrProp = &(lpRows->aRow[0].lpProps[0]); if(lpCurrProp->ulPropTag == PR_ENTRYID) { cbContainerEntryId = lpCurrProp->Value.bin.cb; lpContainerEntryId = (LPENTRYID)lpCurrProp->Value.bin.lpb; } else { hr = HR_LOG(EDK_E_NOT_FOUND); goto cleanup; } hr = MAPIAllocateBuffer(cbContainerEntryId, (LPVOID *)lppeid); if(FAILED(hr)) { *lpcbeid = 0; *lppeid = NULL; } else { CopyMemory( *lppeid, lpContainerEntryId, cbContainerEntryId); *lpcbeid = cbContainerEntryId; } cleanup: ULRELEASE(lpRootContainer); ULRELEASE(lpContainerTable); ULRELEASE(lpContainer); FREEPROWS(lpRows); if(FAILED(hr)) { MAPIFREEBUFFER(*lppeid); *lpcbeid = 0; *lppeid = NULL; } RETURN(hr); }
//$--HrMAPIAppendAddressList----------------------------------------------------- // Append to an address list. // ----------------------------------------------------------------------------- HRESULT HrMAPIAppendAddressList( // RETURNS: return code IN ULONG cProps, // count of values in address list // entry IN LPSPropValue lpPropValues, // pointer to address list entry IN OUT LPADRLIST *lppAdrList) // pointer to address list pointer { HRESULT hr = NOERROR; SCODE sc = 0; LPADRLIST lpAdrList = NULL; LPADRENTRY lpAdrEntry = NULL; LPSPropValue lpNewPropValues = NULL; ULONG i = 0; ULONG cBytes = 0; ULONG cEntries = 0; DEBUGPUBLIC("HrMAPIAppendAddressList()\n"); hr = CHK_HrMAPIAppendAddressList( cProps, lpPropValues, lppAdrList); if(FAILED(hr)) RETURN(hr); sc = ScDupPropset( cProps, lpPropValues, MAPIAllocateBuffer, &lpNewPropValues); if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } cEntries = ((*lppAdrList)->cEntries + 1); cBytes = CbNewADRLIST(cEntries); sc = MAPIAllocateBuffer(cBytes, (void **)&lpAdrList); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Initialize ADRLIST ZeroMemory(lpAdrList, cBytes); lpAdrEntry = lpAdrList->aEntries; // Copy old ADRENTRY values to array for(i = 0; i < (*lppAdrList)->cEntries; i++) { lpAdrEntry[i].cValues = (*lppAdrList)->aEntries[i].cValues; lpAdrEntry[i].rgPropVals = (*lppAdrList)->aEntries[i].rgPropVals; } // Copy new ADRENTRY values to array lpAdrEntry[i].cValues = cProps; lpAdrEntry[i].rgPropVals = lpNewPropValues; lpAdrList->cEntries = (*lppAdrList)->cEntries + 1; MAPIFREEBUFFER(*lppAdrList); *lppAdrList = lpAdrList; cleanup: if(FAILED(hr)) { MAPIFREEBUFFER(lpNewPropValues); } RETURN(hr); }
//$--HrMAPICreateAddressList----------------------------------------------------- // Create an address list. // ----------------------------------------------------------------------------- HRESULT HrMAPICreateAddressList( // RETURNS: return code IN ULONG cProps, // count of values in address list // entry IN LPSPropValue lpPropValues, // pointer to address list entry OUT LPADRLIST *lppAdrList) // pointer to address list pointer { HRESULT hr = NOERROR; SCODE sc = 0; LPSPropValue lpNewPropValues = NULL; ULONG cBytes = 0; DEBUGPUBLIC("HrMAPICreateAddressList()\n"); hr = CHK_HrMAPICreateAddressList( cProps, lpPropValues, lppAdrList); if(FAILED(hr)) RETURN(hr); *lppAdrList = NULL; sc = ScDupPropset( cProps, lpPropValues, MAPIAllocateBuffer, &lpNewPropValues); if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } cBytes = CbNewADRLIST(1); sc = MAPIAllocateBuffer(cBytes, (LPVOID*)lppAdrList); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Initialize ADRLIST structure ZeroMemory(*lppAdrList, cBytes); (*lppAdrList)->cEntries = 1; (*lppAdrList)->aEntries[0].cValues = cProps; (*lppAdrList)->aEntries[0].rgPropVals = lpNewPropValues; cleanup: if(FAILED(hr)) { if(lppAdrList != NULL) { MAPIFREEBUFFER(*lppAdrList); *lppAdrList = NULL; } MAPIFREEBUFFER(lpNewPropValues); } RETURN(hr); }
//$--HrMAPIFindOutbox--------------------------------------------------------- // Find IPM outbox folder. // ----------------------------------------------------------------------------- HRESULT HrMAPIFindOutbox( // RETURNS: return code IN LPMDB lpMdb, // pointer to message store OUT ULONG *lpcbeid, // count of bytes in entry ID OUT LPENTRYID *lppeid) // Entry ID of IPM outbox { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; SCODE sc = 0; ULONG cValues = 0; LPSPropValue lpPropValue = NULL; ULONG cbeid = 0; SPropTagArray rgPropTag = { 1, { PR_IPM_OUTBOX_ENTRYID } }; DEBUGPUBLIC("HrMAPIFindOutbox()"); hr = CHK_HrMAPIFindOutbox( lpMdb, lpcbeid, lppeid); if(FAILED(hr)) RETURN(hr); *lpcbeid = 0; *lppeid = NULL; // Get the outbox entry ID property. hrT = MAPICALL(lpMdb)->GetProps( /*lpMdb,*/ &rgPropTag, fMapiUnicode, &cValues, &lpPropValue); if(hrT == MAPI_W_ERRORS_RETURNED) { if((lpPropValue != NULL) && (lpPropValue->Value.ul == MAPI_E_NOT_FOUND)) { hr = HR_LOG(MAPI_E_NOT_FOUND); } else { hr = HR_LOG(E_FAIL); } goto cleanup; } if(FAILED(hrT)) { lpPropValue = NULL; hr = HR_LOG(E_FAIL); goto cleanup; } ASSERTERROR(cValues != 0, "ZERO cValues variable"); ASSERTERROR(lpPropValue != NULL, "NULL lpPropValue variable"); // Check to make sure we got the right property. if (lpPropValue->ulPropTag != PR_IPM_OUTBOX_ENTRYID) { hr = HR_LOG(E_FAIL); goto cleanup; } cbeid = lpPropValue->Value.bin.cb; sc = MAPIAllocateBuffer(cbeid, (void **)lppeid); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Copy outbox Entry ID CopyMemory( *lppeid, lpPropValue->Value.bin.lpb, cbeid); *lpcbeid = cbeid; cleanup: MAPIFREEBUFFER(lpPropValue); RETURN(hr); }
void Test(){ HRESULT hr = 0; LPMAPISESSION lpMapiSession = NULL; LPMDB lpMdb = NULL; IMAPITable* pIStoreTable = NULL; LPSRowSet pRows = NULL; IUnknown* lpExchManageStroe = NULL; SPropValue* pAllFoldersPropValue = NULL; do{ MAPIINIT_0 mapiInit = { 0, MAPI_MULTITHREAD_NOTIFICATIONS }; hr = MAPIInitialize(&mapiInit); DEFINE_IF_HR_NT_OK_BREAK(hr); //L"Outlook" hr = MAPILogonEx(0, NULL , NULL, MAPI_NEW_SESSION | MAPI_USE_DEFAULT | MAPI_EXTENDED, &lpMapiSession); DEFINE_IF_HR_NT_OK_BREAK(hr); enum{ PR_DEFAULT_STORE_, PR_ENTRYID_, PR_RESOURCE_FLAGS_, PR_MDB_PROVIDER_, PR_DISPLAY_NAME_, COUNT }; SizedSPropTagArray(COUNT, storeEntryID) = { COUNT, { PR_DEFAULT_STORE, PR_ENTRYID, PR_RESOURCE_FLAGS, PR_MDB_PROVIDER, PR_DISPLAY_NAME} }; ULONG ulRowCount = 0; ULONG ulRowIndex = 0; BOOL bFind = FALSE; hr = lpMapiSession->GetMsgStoresTable(0, &pIStoreTable); DEFINE_IF_HR_NT_OK_BREAK(hr); hr = pIStoreTable->SetColumns((LPSPropTagArray)&storeEntryID, 0); DEFINE_IF_HR_NT_OK_BREAK(hr); hr = pIStoreTable->GetRowCount(0, &ulRowCount); DEFINE_IF_HR_NT_OK_BREAK(hr); hr = pIStoreTable->QueryRows(ulRowCount, 0, &pRows); DEFINE_IF_HR_NT_OK_BREAK(hr); ulRowIndex = 0; while (ulRowIndex<pRows->cRows) { _SRow row = pRows->aRow[ulRowIndex]; if (row.lpProps[PR_DEFAULT_STORE_].Value.b == TRUE && (row.lpProps[PR_RESOURCE_FLAGS_].Value.ul & STATUS_DEFAULT_STORE) ) { bFind = TRUE; break; } ulRowIndex++; } if (bFind) { hr = lpMapiSession->OpenMsgStore(0, pRows->aRow[ulRowIndex].lpProps[PR_ENTRYID_].Value.bin.cb, (ENTRYID*)pRows->aRow[ulRowIndex].lpProps[PR_ENTRYID_].Value.bin.lpb, NULL, MDB_WRITE | MAPI_BEST_ACCESS | MDB_NO_DIALOG, (IMsgStore**)&lpMdb); DEFINE_IF_HR_NT_OK_BREAK(hr); } else { break; } enum { PR_IPM_OUTBOX_ENTRYID_, PR_VALID_FOLDER_MASK_, COUNT_ }; SizedSPropTagArray(COUNT_, rgPropTag) = { COUNT_, { PR_IPM_OUTBOX_ENTRYID, PR_VALID_FOLDER_MASK } }; ULONG ulValues = 0; hr = lpMdb->GetProps((LPSPropTagArray)&rgPropTag, 0, &ulValues, &pAllFoldersPropValue); DEFINE_IF_HR_NT_OK_BREAK(hr); ULONG lpObjType = 0; IMAPIFolder* lpMapiFolder = NULL; if (pAllFoldersPropValue[PR_VALID_FOLDER_MASK_].Value.ul & FOLDER_IPM_OUTBOX_VALID){ hr = lpMdb->OpenEntry(pAllFoldersPropValue[PR_IPM_OUTBOX_ENTRYID_].Value.bin.cb, (ENTRYID*)pAllFoldersPropValue[PR_IPM_OUTBOX_ENTRYID_].Value.bin.lpb, NULL, MAPI_BEST_ACCESS | MAPI_MODIFY, &lpObjType, (IUnknown**)&lpMapiFolder); DEFINE_IF_HR_NT_OK_BREAK(hr); } hr = AddMailW(lpMapiSession, lpMapiFolder, L"ceshi测试12", L"lhy测试12", L"*****@*****.**", false, false, true, false); DEFINE_IF_HR_NT_OK_BREAK(hr); } while (0); DWORD dError = GetLastError(); if (pAllFoldersPropValue){ MAPIFREEBUFFER(pAllFoldersPropValue); } if (lpExchManageStroe) { lpExchManageStroe->Release(); lpExchManageStroe = NULL; } if (lpMdb) { ULONG ulLogOffTag = LOGOFF_NO_WAIT; lpMdb->StoreLogoff(&ulLogOffTag); lpMdb->Release(); lpMdb = NULL; } if (pRows) { FreeProws(pRows); pRows = NULL; } if (pIStoreTable) { pIStoreTable->Release(); pIStoreTable = NULL; } if (lpMapiSession){ lpMapiSession->Logoff(0, 0, 0); lpMapiSession->Release(); lpMapiSession = NULL; } MAPIUninitialize(); }