Skip to content

Commit

Permalink
Merge pull request #202 from stephenegriffin/binary
Browse files Browse the repository at this point in the history
Binary
  • Loading branch information
stephenegriffin committed Aug 2, 2018
2 parents 4e67885 + 6733e5f commit 0800355
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 82 deletions.
46 changes: 20 additions & 26 deletions MAPI/Cache/NamedPropCache.cpp
Expand Up @@ -430,22 +430,20 @@ namespace cache
return hRes;
}

_Check_return_ HRESULT CacheGetIDsFromNames(
_Check_return_ LPSPropTagArray CacheGetIDsFromNames(
_In_ LPMAPIPROP lpMAPIProp,
ULONG cbSig,
_In_count_(cbSig) LPBYTE lpSig,
ULONG cPropNames,
_In_count_(cPropNames) LPMAPINAMEID* lppPropNames,
ULONG ulFlags,
_Out_opt_cap_(cPropNames) LPSPropTagArray* lppPropTags)
ULONG ulFlags)
{
if (!lpMAPIProp || !cPropNames || !*lppPropNames || !lppPropTags) return MAPI_E_INVALID_PARAMETER;
if (!lpMAPIProp || !cPropNames || !*lppPropNames) return nullptr;

// We're going to walk the cache, looking for the values we need. As soon as we have all the values we need, we're done
// If we reach the end of the cache and don't have everything, we set up to make a GetIDsFromNames call.

// First, allocate our results using MAPI
auto hRes = S_OK;
auto lpPropTags = mapi::allocate<LPSPropTagArray>(CbNewSPropTagArray(cPropNames));
if (lpPropTags)
{
Expand Down Expand Up @@ -497,9 +495,9 @@ namespace cache
const ULONG ulUncachedTags = 0;
LPSPropTagArray lpUncachedTags = nullptr;

hRes = EC_H_GETPROPS(
EC_H_GETPROPS_S(
lpMAPIProp->GetIDsFromNames(ulMisses, lppUncachedPropNames, ulFlags, &lpUncachedTags));
if (SUCCEEDED(hRes) && lpUncachedTags && lpUncachedTags->cValues == ulMisses)
if (lpUncachedTags && lpUncachedTags->cValues == ulMisses)
{
// Cache the results
AddMapping(cbSig, lpSig, ulUncachedTags, lppUncachedPropNames, lpUncachedTags);
Expand Down Expand Up @@ -532,62 +530,58 @@ namespace cache
}

MAPIFreeBuffer(lppUncachedPropNames);

if (ulMisses != 0) hRes = MAPI_W_ERRORS_RETURNED;
}

*lppPropTags = lpPropTags;
}

return hRes;
return lpPropTags;
}

_Check_return_ HRESULT GetIDsFromNames(
_Check_return_ LPSPropTagArray GetIDsFromNames(
_In_ LPMAPIPROP lpMAPIProp,
ULONG cPropNames,
_In_opt_count_(cPropNames) LPMAPINAMEID* lppPropNames,
ULONG ulFlags,
_Out_ _Deref_post_cap_(cPropNames) LPSPropTagArray* lppPropTags)
ULONG ulFlags)
{
if (!lpMAPIProp) return MAPI_E_INVALID_PARAMETER;
if (!lpMAPIProp) return nullptr;

auto propTags = LPSPropTagArray{};
// Check if we're bypassing the cache:
if (!fCacheNamedProps() ||
// If no names were passed, we have to bypass the cache
// Should we cache results?
!cPropNames || !lppPropNames || !*lppPropNames)
{
return lpMAPIProp->GetIDsFromNames(cPropNames, lppPropNames, ulFlags, lppPropTags);
WC_H_GETPROPS(lpMAPIProp->GetIDsFromNames(cPropNames, lppPropNames, ulFlags, &propTags));
return propTags;
}

LPSPropValue lpProp = nullptr;

auto hRes = WC_MAPI(HrGetOneProp(lpMAPIProp, PR_MAPPING_SIGNATURE, &lpProp));
WC_MAPI_S(HrGetOneProp(lpMAPIProp, PR_MAPPING_SIGNATURE, &lpProp));

if (SUCCEEDED(hRes) && lpProp && PT_BINARY == PROP_TYPE(lpProp->ulPropTag))
if (lpProp && PT_BINARY == PROP_TYPE(lpProp->ulPropTag))
{
hRes = WC_H_GETPROPS(CacheGetIDsFromNames(
propTags = CacheGetIDsFromNames(
lpMAPIProp,
lpProp->Value.bin.cb,
lpProp->Value.bin.lpb,
cPropNames,
lppPropNames,
ulFlags,
lppPropTags));
ulFlags);
}
else
{
hRes = WC_H_GETPROPS(lpMAPIProp->GetIDsFromNames(cPropNames, lppPropNames, ulFlags, lppPropTags));
WC_H_GETPROPS_S(lpMAPIProp->GetIDsFromNames(cPropNames, lppPropNames, ulFlags, &propTags));
// Cache the results
if (SUCCEEDED(hRes))
if (propTags)
{
AddMappingWithoutSignature(cPropNames, lppPropNames, *lppPropTags);
AddMappingWithoutSignature(cPropNames, lppPropNames, propTags);
}
}

MAPIFreeBuffer(lpProp);

return hRes;
return propTags;
}

// TagToString will prepend the http://schemas.microsoft.com/MAPI/ for us since it's a constant
Expand Down
5 changes: 2 additions & 3 deletions MAPI/Cache/NamedPropCache.h
Expand Up @@ -56,12 +56,11 @@ namespace cache
ULONG ulFlags,
_Out_ ULONG* lpcPropNames,
_Out_ _Deref_post_cap_(*lpcPropNames) LPMAPINAMEID** lpppPropNames);
_Check_return_ HRESULT GetIDsFromNames(
_Check_return_ LPSPropTagArray GetIDsFromNames(
_In_ LPMAPIPROP lpMAPIProp,
ULONG cPropNames,
_In_opt_count_(cPropNames) LPMAPINAMEID* lppPropNames,
ULONG ulFlags,
_Out_ _Deref_post_cap_(cPropNames) LPSPropTagArray* lppPropTags);
ULONG ulFlags);

_Check_return_ inline bool fCacheNamedProps()
{
Expand Down
4 changes: 2 additions & 2 deletions MAPI/MAPIFunctions.cpp
Expand Up @@ -1157,9 +1157,9 @@ namespace mapi
if (!lpMessage) return MAPI_E_INVALID_PARAMETER;
output::DebugPrint(DBGNamedProp, L"RemoveOneOff - removing one off named properties.\n");

auto hRes = S_OK;
MAPINAMEID rgnmid[ulNumOneOffIDs];
LPMAPINAMEID rgpnmid[ulNumOneOffIDs];
LPSPropTagArray lpTags = nullptr;

for (ULONG i = 0; i < ulNumOneOffIDs; i++)
{
Expand All @@ -1169,7 +1169,7 @@ namespace mapi
rgpnmid[i] = &rgnmid[i];
}

auto hRes = EC_H(cache::GetIDsFromNames(lpMessage, ulNumOneOffIDs, rgpnmid, 0, &lpTags));
auto lpTags = cache::GetIDsFromNames(lpMessage, ulNumOneOffIDs, rgpnmid, 0);
if (lpTags)
{
LPSPropProblemArray lpProbArray = nullptr;
Expand Down
68 changes: 25 additions & 43 deletions MAPI/MAPIStoreFunctions.cpp
Expand Up @@ -243,24 +243,21 @@ namespace mapi
return serverName;
}

_Check_return_ HRESULT CreateStoreEntryID(
_Check_return_ SBinary CreateStoreEntryID(
_In_ LPMDB lpMDB, // open message store
const std::string& lpszMsgStoreDN, // desired message store DN
const std::string& lpszMailboxDN, // desired mailbox DN or NULL
ULONG ulFlags, // desired flags for CreateStoreEntryID
_Out_opt_ ULONG* lpcbEntryID,
_Deref_out_opt_ LPENTRYID* lppEntryID)
ULONG ulFlags) // desired flags for CreateStoreEntryID
{
auto hRes = S_OK;

if (!lpMDB || lpszMsgStoreDN.empty() || !StoreSupportsManageStore(lpMDB))
{
if (!lpMDB) output::DebugPrint(DBGGeneric, L"CreateStoreEntryID: MDB was NULL\n");
if (lpszMsgStoreDN.empty())
output::DebugPrint(DBGGeneric, L"CreateStoreEntryID: lpszMsgStoreDN was missing\n");
return MAPI_E_INVALID_PARAMETER;
return {};
}

auto eid = SBinary{};
auto lpXManageStore = mapi::safe_cast<LPEXCHANGEMANAGESTORE>(lpMDB);
if (lpXManageStore)
{
Expand All @@ -271,38 +268,35 @@ namespace mapi
lpszMailboxDN.c_str(),
ulFlags);

hRes = EC_MAPI(lpXManageStore->CreateStoreEntryID(
EC_MAPI_S(lpXManageStore->CreateStoreEntryID(
LPSTR(lpszMsgStoreDN.c_str()),
lpszMailboxDN.empty() ? nullptr : LPSTR(lpszMailboxDN.c_str()),
ulFlags,
lpcbEntryID,
lppEntryID));
&eid.cb,
reinterpret_cast<LPENTRYID*>(&eid.lpb)));

lpXManageStore->Release();
}

return hRes;
return eid;
}

_Check_return_ HRESULT CreateStoreEntryID2(
_Check_return_ SBinary CreateStoreEntryID2(
_In_ LPMDB lpMDB, // open message store
const std::string& lpszMsgStoreDN, // desired message store DN
const std::string& lpszMailboxDN, // desired mailbox DN or NULL
const std::wstring& smtpAddress,
ULONG ulFlags, // desired flags for CreateStoreEntryID
_Out_opt_ ULONG* lpcbEntryID,
_Deref_out_opt_ LPENTRYID* lppEntryID)
ULONG ulFlags) // desired flags for CreateStoreEntryID
{
auto hRes = S_OK;

if (!lpMDB || lpszMsgStoreDN.empty() || !StoreSupportsManageStoreEx(lpMDB))
{
if (!lpMDB) output::DebugPrint(DBGGeneric, L"CreateStoreEntryID2: MDB was NULL\n");
if (lpszMsgStoreDN.empty())
output::DebugPrint(DBGGeneric, L"CreateStoreEntryID2: lpszMsgStoreDN was missing\n");
return MAPI_E_INVALID_PARAMETER;
return {};
}

auto eid = SBinary{};
auto lpXManageStoreEx = mapi::safe_cast<LPEXCHANGEMANAGESTOREEX>(lpMDB);
if (lpXManageStoreEx)
{
Expand All @@ -327,31 +321,27 @@ namespace mapi
sProps[3].ulPropTag = PR_PROFILE_USER_SMTP_EMAIL_ADDRESS_W;
sProps[3].Value.lpszW = smtpAddress.empty() ? nullptr : const_cast<LPWSTR>(smtpAddress.c_str());

hRes = EC_MAPI(lpXManageStoreEx->CreateStoreEntryID2(
EC_MAPI_S(lpXManageStoreEx->CreateStoreEntryID2(
smtpAddress.empty() ? _countof(sProps) - 1 : _countof(sProps),
reinterpret_cast<LPSPropValue>(&sProps),
ulFlags,
lpcbEntryID,
lppEntryID));
&eid.cb,
reinterpret_cast<LPENTRYID*>(&eid.lpb)));

lpXManageStoreEx->Release();
}

return hRes;
return eid;
}

_Check_return_ HRESULT CreateStoreEntryID(
_Check_return_ SBinary CreateStoreEntryID(
_In_ LPMDB lpMDB, // open message store
const std::string& lpszMsgStoreDN, // desired message store DN
const std::string& lpszMailboxDN, // desired mailbox DN or NULL
const std::wstring& smtpAddress,
ULONG ulFlags, // desired flags for CreateStoreEntryID
bool bForceServer, // Use CreateStoreEntryID2
_Out_opt_ ULONG* lpcbEntryID,
_Deref_out_opt_ LPENTRYID* lppEntryID)
bool bForceServer) // Use CreateStoreEntryID2
{
auto hRes = S_OK;

// Use an empty MailboxDN to open the public store
if (lpszMailboxDN.empty())
{
Expand All @@ -360,16 +350,12 @@ namespace mapi

if (!bForceServer)
{
hRes =
EC_MAPI(CreateStoreEntryID(lpMDB, lpszMsgStoreDN, lpszMailboxDN, ulFlags, lpcbEntryID, lppEntryID));
return CreateStoreEntryID(lpMDB, lpszMsgStoreDN, lpszMailboxDN, ulFlags);
}
else
{
hRes = EC_MAPI(CreateStoreEntryID2(
lpMDB, lpszMsgStoreDN, lpszMailboxDN, smtpAddress, ulFlags, lpcbEntryID, lppEntryID));
return CreateStoreEntryID2(lpMDB, lpszMsgStoreDN, lpszMailboxDN, smtpAddress, ulFlags);
}

return hRes;
}

// Stolen from MBLogon.c in the EDK to avoid compiling and linking in the entire beast
Expand Down Expand Up @@ -403,37 +389,33 @@ namespace mapi
ULONG ulFlags, // desired flags for CreateStoreEntryID
bool bForceServer) // Use CreateStoreEntryID2
{
SBinary sbEID = {0};

if (!lpMAPISession)
{
output::DebugPrint(DBGGeneric, L"MailboxLogon: Session was NULL\n");
return nullptr;
}

auto hRes = WC_H(CreateStoreEntryID(
auto eid = CreateStoreEntryID(
lpMDB,
lpszMsgStoreDN,
lpszMailboxDN,
smtpAddress,
ulFlags,
bForceServer,
&sbEID.cb,
reinterpret_cast<LPENTRYID*>(&sbEID.lpb)));
bForceServer);

LPMDB lpMailboxMDB = nullptr;
if (SUCCEEDED(hRes))
if (eid.cb && eid.lpb)
{
lpMailboxMDB = CallOpenMsgStore(
lpMAPISession,
NULL,
&sbEID,
&eid,
MDB_NO_DIALOG | MDB_NO_MAIL | // spooler not notified of our presence
MDB_TEMPORARY | // message store not added to MAPI profile
MAPI_BEST_ACCESS); // normally WRITE, but allow access to RO store
}

MAPIFreeBuffer(sbEID.lpb);
MAPIFreeBuffer(eid.lpb);
return lpMailboxMDB;
}

Expand Down
6 changes: 3 additions & 3 deletions UI/Controls/SingleMAPIPropListCtrl.cpp
Expand Up @@ -974,11 +974,11 @@ namespace controls
{
if (!m_lpPropBag) return;

auto hRes = S_OK;
// Exchange can return MAPI_E_NOT_ENOUGH_MEMORY when I call this - give it a try - PSTs support it
output::DebugPrintEx(DBGNamedProp, CLASS, L"FindAllNamedProps", L"Calling GetIDsFromNames with a NULL\n");
LPSPropTagArray lptag = nullptr;
auto hRes = WC_H(cache::GetIDsFromNames(m_lpPropBag->GetMAPIProp(), NULL, NULL, NULL, &lptag));
if (hRes == S_OK && lptag && lptag->cValues)
auto lptag = cache::GetIDsFromNames(m_lpPropBag->GetMAPIProp(), NULL, NULL, NULL);
if (lptag && lptag->cValues)
{
// Now we have an array of tags - add them in:
AddPropsToExtraProps(lptag, false);
Expand Down
6 changes: 1 addition & 5 deletions UI/Dialogs/Editors/PropertyTagEditor.cpp
Expand Up @@ -192,11 +192,7 @@ namespace dialog
if (NamedID.lpguid && (MNID_ID == NamedID.ulKind && NamedID.Kind.lID ||
MNID_STRING == NamedID.ulKind && NamedID.Kind.lpwstrName))
{
LPSPropTagArray lpNamedPropTags = nullptr;

WC_H_GETPROPS_S(
cache::GetIDsFromNames(m_lpMAPIProp, 1, &lpNamedID, bCreate ? MAPI_CREATE : 0, &lpNamedPropTags));

auto lpNamedPropTags = cache::GetIDsFromNames(m_lpMAPIProp, 1, &lpNamedID, bCreate ? MAPI_CREATE : 0);
if (lpNamedPropTags)
{
m_ulPropTag = CHANGE_PROP_TYPE(lpNamedPropTags->aulPropTag[0], ulPropType);
Expand Down

0 comments on commit 0800355

Please sign in to comment.