Implement HrGetOneProp, HrSetOneProp, FPropExists, FreePadrlist,
FreeProws, ScDupPropset, HexFromBin, FBinFromHex, FEqualNames. Fix 2 cases where iterating over value arrays reused a loop variable incorrectly.
This commit is contained in:
parent
bd4cee3200
commit
b1e84873ef
|
@ -29,8 +29,8 @@
|
|||
41 stub WrapProgress@20
|
||||
42 stdcall HrThisThreadAdviseSink@8(ptr ptr) HrThisThreadAdviseSink
|
||||
43 stub ScBinFromHexBounded@12
|
||||
44 stub FBinFromHex@8
|
||||
45 stub HexFromBin@12
|
||||
44 stdcall FBinFromHex@8(ptr ptr) FBinFromHex
|
||||
45 stdcall HexFromBin@12(ptr long ptr) HexFromBin
|
||||
46 stub BuildDisplayTable@40
|
||||
47 stdcall SwapPlong@8(ptr long) SwapPlong
|
||||
48 stdcall SwapPword@8(ptr long) SwapPword
|
||||
|
@ -51,7 +51,7 @@
|
|||
66 stdcall MNLS_MultiByteToWideChar@24(long long str long ptr long) kernel32.MultiByteToWideChar
|
||||
67 stdcall MNLS_WideCharToMultiByte@32(long long wstr long ptr long ptr ptr) kernel32.WideCharToMultiByte
|
||||
68 stdcall MNLS_IsBadStringPtrW@8(ptr long) kernel32.IsBadStringPtrW
|
||||
72 stub FEqualNames@8
|
||||
72 stdcall FEqualNames@8(ptr ptr) FEqualNames
|
||||
73 stub WrapStoreEntryID@24
|
||||
74 stub IsBadBoundedStringPtr@8
|
||||
75 stub HrQueryAllRows@24
|
||||
|
@ -75,12 +75,12 @@
|
|||
131 stdcall SzFindLastCh@8(str str long) shlwapi.StrRChrA
|
||||
132 stdcall SzFindSz@8(str str) shlwapi.StrStrA
|
||||
133 stub UFromSz@4
|
||||
135 stub HrGetOneProp@12
|
||||
136 stub HrSetOneProp@8
|
||||
137 stub FPropExists@8
|
||||
135 stdcall HrGetOneProp@12(ptr long ptr) HrGetOneProp
|
||||
136 stdcall HrSetOneProp@8(ptr ptr) HrSetOneProp
|
||||
137 stdcall FPropExists@8(ptr long) FPropExists
|
||||
138 stdcall PpropFindProp@12(ptr long long) PpropFindProp
|
||||
139 stub FreePadrlist@4
|
||||
140 stub FreeProws@4
|
||||
139 stdcall FreePadrlist@4(ptr) FreePadrlist
|
||||
140 stdcall FreeProws@4(ptr) FreeProws
|
||||
141 stub HrSzFromEntryID@12
|
||||
142 stub HrEntryIDFromSz@12
|
||||
143 stub HrComposeEID@28
|
||||
|
@ -111,7 +111,7 @@
|
|||
171 stdcall ScCopyProps@16(long ptr ptr ptr) ScCopyProps
|
||||
172 stdcall ScRelocProps@20(long ptr ptr ptr ptr) ScRelocProps
|
||||
173 stdcall LpValFindProp@12(long long ptr) LpValFindProp
|
||||
174 stub ScDupPropset@16
|
||||
174 stdcall ScDupPropset@16(long ptr ptr ptr) ScDupPropset
|
||||
175 stdcall FBadRglpszA@8(ptr long) FBadRglpszA
|
||||
176 stdcall FBadRglpszW@8(ptr long) FBadRglpszW
|
||||
177 stdcall FBadRowSet@4(ptr) FBadRowSet
|
||||
|
|
|
@ -154,7 +154,7 @@ SCODE WINAPI PropCopyMore(LPSPropValue lpDest, LPSPropValue lpSrc,
|
|||
{
|
||||
WCHAR *lpNextStr = (WCHAR*)(lpDest->Value.MVszW.lppszW +
|
||||
lpDest->Value.MVszW.cValues);
|
||||
|
||||
|
||||
for (i = 0; i < lpSrc->Value.MVszW.cValues; i++)
|
||||
{
|
||||
ULONG ulStrLen = strlenW(lpSrc->Value.MVszW.lppszW[i]) + 1u;
|
||||
|
@ -513,6 +513,107 @@ LONG WINAPI LPropCompareProp(LPSPropValue lpPropLeft, LPSPropValue lpPropRight)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* HrGetOneProp@8 (MAPI32.135)
|
||||
*
|
||||
* Get a property value from an IMAPIProp object.
|
||||
*
|
||||
* PARAMS
|
||||
* lpIProp [I] IMAPIProp object to get the property value in
|
||||
* ulPropTag [I] Property tag of the property to get
|
||||
* lppProp [O] Destination for the returned property
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. *lppProp contains the property value requested.
|
||||
* Failure: MAPI_E_NOT_FOUND, if no property value has the tag given by ulPropTag.
|
||||
*/
|
||||
HRESULT WINAPI HrGetOneProp(LPMAPIPROP lpIProp, ULONG ulPropTag, LPSPropValue *lppProp)
|
||||
{
|
||||
SPropTagArray pta;
|
||||
ULONG ulCount;
|
||||
HRESULT hRet;
|
||||
|
||||
TRACE("(%p,%ld,%p)\n", lpIProp, ulPropTag, lppProp);
|
||||
|
||||
pta.cValues = 1u;
|
||||
pta.aulPropTag[0] = ulPropTag;
|
||||
hRet = IMAPIProp_GetProps(lpIProp, &pta, 0u, &ulCount, lppProp);
|
||||
if (hRet == MAPI_W_ERRORS_RETURNED)
|
||||
{
|
||||
MAPIFreeBuffer(*lppProp);
|
||||
*lppProp = NULL;
|
||||
hRet = MAPI_E_NOT_FOUND;
|
||||
}
|
||||
return hRet;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* HrSetOneProp@8 (MAPI32.136)
|
||||
*
|
||||
* Set a property value in an IMAPIProp object.
|
||||
*
|
||||
* PARAMS
|
||||
* lpIProp [I] IMAPIProp object to set the property value in
|
||||
* lpProp [I] Property value to set
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. The value in lpProp is set in lpIProp.
|
||||
* Failure: An error result from IMAPIProp_SetProps().
|
||||
*/
|
||||
HRESULT WINAPI HrSetOneProp(LPMAPIPROP lpIProp, LPSPropValue lpProp)
|
||||
{
|
||||
TRACE("(%p,%p)\n", lpIProp, lpProp);
|
||||
|
||||
return IMAPIProp_SetProps(lpIProp, 1u, lpProp, NULL);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* FPropExists@8 (MAPI32.137)
|
||||
*
|
||||
* Find a property with a given property tag in an IMAPIProp object.
|
||||
*
|
||||
* PARAMS
|
||||
* lpIProp [I] IMAPIProp object to find the property tag in
|
||||
* ulPropTag [I] Property tag to find
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE, if ulPropTag matches a property held in lpIProp,
|
||||
* FALSE, otherwise.
|
||||
*
|
||||
* NOTES
|
||||
* if ulPropTag has a property type of PT_UNSPECIFIED, then only the property
|
||||
* Ids need to match for a successful match to occur.
|
||||
*/
|
||||
BOOL WINAPI FPropExists(LPMAPIPROP lpIProp, ULONG ulPropTag)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
TRACE("(%p,%ld)\n", lpIProp, ulPropTag);
|
||||
|
||||
if (lpIProp)
|
||||
{
|
||||
LPSPropTagArray lpTags;
|
||||
ULONG i;
|
||||
|
||||
if (FAILED(IMAPIProp_GetPropList(lpIProp, 0u, &lpTags)))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < lpTags->cValues; i++)
|
||||
{
|
||||
if (!FBadPropTag(lpTags->aulPropTag[i]) &&
|
||||
(lpTags->aulPropTag[i] == ulPropTag ||
|
||||
(PROP_TYPE(ulPropTag) == PT_UNSPECIFIED &&
|
||||
PROP_ID(lpTags->aulPropTag[i]) == lpTags->aulPropTag[i])))
|
||||
{
|
||||
bRet = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
MAPIFreeBuffer(lpTags);
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* PpropFindProp@12 (MAPI32.138)
|
||||
*
|
||||
|
@ -549,6 +650,51 @@ LPSPropValue WINAPI PpropFindProp(LPSPropValue lpProps, ULONG cValues, ULONG ulP
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* FreePadrlist@4 (MAPI32.139)
|
||||
*
|
||||
* Free the memory used by an address book list.
|
||||
*
|
||||
* PARAMS
|
||||
* lpAddrs [I] Address book list to free
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing.
|
||||
*/
|
||||
VOID WINAPI FreePadrlist(LPADRLIST lpAddrs)
|
||||
{
|
||||
TRACE("(%p)\n", lpAddrs);
|
||||
|
||||
/* Structures are binary compatible; use the same implementation */
|
||||
return FreeProws((LPSRowSet)lpAddrs);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* FreeProws@4 (MAPI32.140)
|
||||
*
|
||||
* Free the memory used by a row set.
|
||||
*
|
||||
* PARAMS
|
||||
* lpRowSet [I] Row set to free
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing.
|
||||
*/
|
||||
VOID WINAPI FreeProws(LPSRowSet lpRowSet)
|
||||
{
|
||||
TRACE("(%p)\n", lpRowSet);
|
||||
|
||||
if (lpRowSet)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < lpRowSet->cRows; i++)
|
||||
MAPIFreeBuffer(lpRowSet->aRow[i].lpProps);
|
||||
|
||||
MAPIFreeBuffer(lpRowSet);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* ScCountProps@12 (MAPI32.170)
|
||||
*
|
||||
|
@ -623,7 +769,7 @@ SCODE WINAPI ScCountProps(INT iCount, LPSPropValue lpProps, ULONG *pcBytes)
|
|||
}
|
||||
if (pcBytes)
|
||||
*pcBytes = ulBytes;
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -649,16 +795,16 @@ SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG
|
|||
{
|
||||
LPSPropValue lpDest = (LPSPropValue)lpDst;
|
||||
char *lpDataDest = (char *)(lpDest + cValues);
|
||||
ULONG ulLen, i;
|
||||
|
||||
ULONG ulLen, i, iter;
|
||||
|
||||
TRACE("(%d,%p,%p,%p)\n", cValues, lpProps, lpDst, lpCount);
|
||||
|
||||
|
||||
if (!lpProps || cValues < 0 || !lpDest)
|
||||
return MAPI_E_INVALID_PARAMETER;
|
||||
|
||||
memcpy(lpDst, lpProps, cValues * sizeof(SPropValue));
|
||||
|
||||
for (i = 0; i < cValues; i++)
|
||||
|
||||
for (iter = 0; iter < cValues; iter++)
|
||||
{
|
||||
switch (PROP_TYPE(lpProps->ulPropTag))
|
||||
{
|
||||
|
@ -696,11 +842,11 @@ SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG
|
|||
case PT_MV_STRING8:
|
||||
{
|
||||
lpDataDest += lpProps->Value.MVszA.cValues * sizeof(char *);
|
||||
|
||||
|
||||
for (i = 0; i < lpProps->Value.MVszA.cValues; i++)
|
||||
{
|
||||
ULONG ulStrLen = lstrlenA(lpProps->Value.MVszA.lppszA[i]) + 1u;
|
||||
|
||||
|
||||
lpDest->Value.MVszA.lppszA[i] = lpDataDest;
|
||||
memcpy(lpDataDest, lpProps->Value.MVszA.lppszA[i], ulStrLen);
|
||||
lpDataDest += ulStrLen;
|
||||
|
@ -710,28 +856,28 @@ SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG
|
|||
case PT_MV_UNICODE:
|
||||
{
|
||||
lpDataDest += lpProps->Value.MVszW.cValues * sizeof(WCHAR *);
|
||||
|
||||
|
||||
for (i = 0; i < lpProps->Value.MVszW.cValues; i++)
|
||||
{
|
||||
ULONG ulStrLen = (strlenW(lpProps->Value.MVszW.lppszW[i]) + 1u) * sizeof(WCHAR);
|
||||
|
||||
|
||||
lpDest->Value.MVszW.lppszW[i] = (LPWSTR)lpDataDest;
|
||||
memcpy(lpDataDest, lpProps->Value.MVszW.lppszW[i], ulStrLen);
|
||||
lpDataDest += ulStrLen;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PT_MV_BINARY:
|
||||
{
|
||||
lpDataDest += lpProps->Value.MVszW.cValues * sizeof(SBinary);
|
||||
|
||||
|
||||
for (i = 0; i < lpProps->Value.MVszW.cValues; i++)
|
||||
{
|
||||
lpDest->Value.MVbin.lpbin[i].cb = lpProps->Value.MVbin.lpbin[i].cb;
|
||||
lpDest->Value.MVbin.lpbin[i].lpb = (LPBYTE)lpDataDest;
|
||||
memcpy(lpDataDest, lpProps->Value.MVbin.lpbin[i].lpb, lpDest->Value.MVbin.lpbin[i].cb);
|
||||
lpDataDest += lpDest->Value.MVbin.lpbin[i].cb;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -749,10 +895,10 @@ SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG
|
|||
}
|
||||
if (lpCount)
|
||||
*lpCount = lpDataDest - (char *)lpDst;
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* ScRelocProps@20 (MAPI32.172)
|
||||
*
|
||||
|
@ -784,10 +930,10 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
|||
static const BOOL bBadPtr = TRUE; /* Windows bug - Assumes source is bad */
|
||||
LPSPropValue lpDest = (LPSPropValue)lpProps;
|
||||
ULONG ulCount = cValues * sizeof(SPropValue);
|
||||
ULONG ulLen, i;
|
||||
|
||||
ULONG ulLen, i, iter;
|
||||
|
||||
TRACE("(%d,%p,%p,%p,%p)\n", cValues, lpProps, lpOld, lpNew, lpCount);
|
||||
|
||||
|
||||
if (!lpProps || cValues < 0 || !lpOld || !lpNew)
|
||||
return MAPI_E_INVALID_PARAMETER;
|
||||
|
||||
|
@ -801,13 +947,13 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
|||
* The code below would handle both cases except that the design of this
|
||||
* function makes it impossible to know when the pointers in lpProps are
|
||||
* valid. If both lpOld and lpNew are non-NULL, native reads the pointers
|
||||
* after converting them, so we must do the same. Its seems this
|
||||
* after converting them, so we must do the same. Its seems this
|
||||
* functionality was never tested by MS.
|
||||
*/
|
||||
|
||||
|
||||
#define RELOC_PTR(p) (((char*)(p)) - (char*)lpOld + (char*)lpNew)
|
||||
|
||||
for (i = 0; i < cValues; i++)
|
||||
|
||||
for (iter = 0; iter < cValues; iter++)
|
||||
{
|
||||
switch (PROP_TYPE(lpDest->ulPropTag))
|
||||
{
|
||||
|
@ -841,7 +987,7 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
|||
*/
|
||||
if (bBadPtr)
|
||||
lpDest->Value.MVszA.lppszA = (LPSTR*)RELOC_PTR(lpDest->Value.MVszA.lppszA);
|
||||
|
||||
|
||||
switch (PROP_TYPE(lpProps->ulPropTag))
|
||||
{
|
||||
case PT_MV_STRING8:
|
||||
|
@ -851,7 +997,7 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
|||
for (i = 0; i < lpDest->Value.MVszA.cValues; i++)
|
||||
{
|
||||
ULONG ulStrLen = bBadPtr ? 0 : lstrlenA(lpDest->Value.MVszA.lppszA[i]) + 1u;
|
||||
|
||||
|
||||
lpDest->Value.MVszA.lppszA[i] = (LPSTR)RELOC_PTR(lpDest->Value.MVszA.lppszA[i]);
|
||||
if (bBadPtr)
|
||||
ulStrLen = lstrlenA(lpDest->Value.MVszA.lppszA[i]) + 1u;
|
||||
|
@ -862,27 +1008,27 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
|||
case PT_MV_UNICODE:
|
||||
{
|
||||
ulCount += lpDest->Value.MVszW.cValues * sizeof(WCHAR *);
|
||||
|
||||
|
||||
for (i = 0; i < lpDest->Value.MVszW.cValues; i++)
|
||||
{
|
||||
ULONG ulStrLen = bBadPtr ? 0 : (strlenW(lpDest->Value.MVszW.lppszW[i]) + 1u) * sizeof(WCHAR);
|
||||
|
||||
|
||||
lpDest->Value.MVszW.lppszW[i] = (LPWSTR)RELOC_PTR(lpDest->Value.MVszW.lppszW[i]);
|
||||
if (bBadPtr)
|
||||
ulStrLen = (strlenW(lpDest->Value.MVszW.lppszW[i]) + 1u) * sizeof(WCHAR);
|
||||
ulCount += ulStrLen;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PT_MV_BINARY:
|
||||
{
|
||||
ulCount += lpDest->Value.MVszW.cValues * sizeof(SBinary);
|
||||
|
||||
|
||||
for (i = 0; i < lpDest->Value.MVszW.cValues; i++)
|
||||
{
|
||||
lpDest->Value.MVbin.lpbin[i].lpb = (LPBYTE)RELOC_PTR(lpDest->Value.MVbin.lpbin[i].lpb);
|
||||
ulCount += lpDest->Value.MVbin.lpbin[i].cb;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -898,7 +1044,7 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
|||
}
|
||||
if (lpCount)
|
||||
*lpCount = ulCount;
|
||||
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -935,6 +1081,40 @@ LPSPropValue WINAPI LpValFindProp(ULONG ulPropTag, ULONG cValues, LPSPropValue l
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* ScDupPropset@16 (MAPI32.174)
|
||||
*
|
||||
* Duplicate a property value array into a contigous block of memory.
|
||||
*
|
||||
* PARAMS
|
||||
* cValues [I] Number of properties in lpProps
|
||||
* lpProps [I] Property array to duplicate
|
||||
* lpAlloc [I] Memory allocation function, use MAPIAllocateBuffer()
|
||||
* lpNewProp [O] Destination for the newly duplicated property value array
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK. *lpNewProp contains the duplicated array.
|
||||
* Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid,
|
||||
* MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
|
||||
*/
|
||||
SCODE WINAPI ScDupPropset(int cValues, LPSPropValue lpProps,
|
||||
LPALLOCATEBUFFER lpAlloc, LPSPropValue *lpNewProp)
|
||||
{
|
||||
ULONG ulCount;
|
||||
SCODE sc;
|
||||
|
||||
TRACE("(%d,%p,%p,%p)\n", cValues, lpProps, lpAlloc, lpNewProp);
|
||||
|
||||
sc = ScCountProps(cValues, lpProps, &ulCount);
|
||||
if (SUCCEEDED(sc))
|
||||
{
|
||||
sc = lpAlloc(ulCount, (LPVOID*)lpNewProp);
|
||||
if (SUCCEEDED(sc))
|
||||
sc = ScCopyProps(cValues, lpProps, *lpNewProp, &ulCount);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* FBadRglpszA@8 (MAPI32.175)
|
||||
*
|
||||
|
@ -955,7 +1135,7 @@ BOOL WINAPI FBadRglpszA(LPSTR *lppszStrs, ULONG ulCount)
|
|||
|
||||
if (!ulCount)
|
||||
return FALSE;
|
||||
|
||||
|
||||
if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
|
||||
return TRUE;
|
||||
|
||||
|
@ -980,7 +1160,7 @@ BOOL WINAPI FBadRglpszW(LPWSTR *lppszStrs, ULONG ulCount)
|
|||
|
||||
if (!ulCount)
|
||||
return FALSE;
|
||||
|
||||
|
||||
if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
|
||||
return TRUE;
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ static HMODULE hMapi32 = 0;
|
|||
static SCODE (WINAPI *pScInitMapiUtil)(ULONG);
|
||||
static void (WINAPI *pSwapPword)(PUSHORT,ULONG);
|
||||
static void (WINAPI *pSwapPlong)(PULONG,ULONG);
|
||||
static void (WINAPI *pHexFromBin)(LPBYTE,int,LPWSTR);
|
||||
static void (WINAPI *pFBinFromHex)(LPWSTR,LPBYTE);
|
||||
|
||||
static void test_SwapPword(void)
|
||||
{
|
||||
|
@ -69,10 +71,47 @@ static void test_SwapPlong(void)
|
|||
longs[0], longs[1], longs[2]);
|
||||
}
|
||||
|
||||
static void test_HexFromBin(void)
|
||||
{
|
||||
static const char res[] = { "000102030405060708090A0B0C0D0E0F101112131415161"
|
||||
"718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B"
|
||||
"3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6"
|
||||
"06162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F8081828384"
|
||||
"85868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A"
|
||||
"9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCD"
|
||||
"CECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F"
|
||||
"2F3F4F5F6F7F8F9FAFBFCFDFE\0X" };
|
||||
BYTE data[255];
|
||||
WCHAR strw[256];
|
||||
BOOL bOk;
|
||||
int i;
|
||||
|
||||
pHexFromBin = (void*)GetProcAddress(hMapi32, "HexFromBin@12");
|
||||
pFBinFromHex = (void*)GetProcAddress(hMapi32, "FBinFromHex@8");
|
||||
if (!pHexFromBin || !pFBinFromHex)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 255; i++)
|
||||
data[i] = i;
|
||||
memset(strw, 'X', sizeof(strw));
|
||||
pHexFromBin(data, sizeof(data), strw);
|
||||
|
||||
ok(memcmp(strw, res, sizeof(res) - 1) == 0, "HexFromBin: Result differs\n");
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
pFBinFromHex((LPWSTR)res, data);
|
||||
bOk = TRUE;
|
||||
for (i = 0; i < 255; i++)
|
||||
if (data[i] != i)
|
||||
bOk = FALSE;
|
||||
ok(bOk == TRUE, "FBinFromHex: Result differs\n");
|
||||
}
|
||||
|
||||
|
||||
START_TEST(util)
|
||||
{
|
||||
hMapi32 = LoadLibraryA("mapi32.dll");
|
||||
|
||||
|
||||
pScInitMapiUtil = (void*)GetProcAddress(hMapi32, "ScInitMapiUtil@4");
|
||||
if (!pScInitMapiUtil)
|
||||
return;
|
||||
|
@ -80,4 +119,5 @@ START_TEST(util)
|
|||
|
||||
test_SwapPword();
|
||||
test_SwapPlong();
|
||||
test_HexFromBin();
|
||||
}
|
||||
|
|
|
@ -227,6 +227,85 @@ HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK*
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* FBinFromHex (MAPI32.44)
|
||||
*
|
||||
* Create an array of binary data from a string.
|
||||
*
|
||||
* PARAMS
|
||||
* lpszHex [I] String to convert to binary data
|
||||
* lpOut [O] Destination for resulting binary data
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE. lpOut contains the decoded binary data.
|
||||
* Failure: FALSE, if lpszHex does not represent a binary string.
|
||||
*
|
||||
* NOTES
|
||||
* - lpOut must be at least half the length of lpszHex in bytes.
|
||||
* - Although the Mapi headers prototype this function as both
|
||||
* Ascii and Unicode, there is only one (Ascii) implementation. This
|
||||
* means that lpszHex is treated as an Ascii string (i.e. a single NUL
|
||||
* character in the byte stream terminates the string).
|
||||
*/
|
||||
BOOL WINAPI FBinFromHex(LPWSTR lpszHex, LPBYTE lpOut)
|
||||
{
|
||||
static const BYTE digitsToHex[] = {
|
||||
0,1,2,3,4,5,6,7,8,9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,10,11,12,13,14,15,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,10,11,12,13,
|
||||
14,15 };
|
||||
LPSTR lpStr = (LPSTR)lpszHex;
|
||||
|
||||
TRACE("(%p,%p)\n", lpszHex, lpOut);
|
||||
|
||||
while (*lpStr)
|
||||
{
|
||||
if (lpStr[0] < '0' || lpStr[0] > 'f' || digitsToHex[lpStr[0] - '0'] == 0xff ||
|
||||
lpStr[1] < '0' || lpStr[1] > 'f' || digitsToHex[lpStr[1] - '0'] == 0xff)
|
||||
return FALSE;
|
||||
|
||||
*lpOut++ = (digitsToHex[lpStr[0] - '0'] << 4) | digitsToHex[lpStr[1] - '0'];
|
||||
lpStr += 2;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* HexFromBin (MAPI32.45)
|
||||
*
|
||||
* Create a string from an array of binary data.
|
||||
*
|
||||
* PARAMS
|
||||
* lpHex [I] Binary data to convert to string
|
||||
* iCount [I] Length of lpHex in bytes
|
||||
* lpszOut [O] Destination for resulting hex string
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing.
|
||||
*
|
||||
* NOTES
|
||||
* - lpszOut must be at least 2 * iCount + 1 bytes characters long.
|
||||
* - Although the Mapi headers prototype this function as both
|
||||
* Ascii and Unicode, there is only one (Ascii) implementation. This
|
||||
* means that the resulting string is not properly NUL terminated
|
||||
* if the caller expects it to be a Unicode string.
|
||||
*/
|
||||
void WINAPI HexFromBin(LPBYTE lpHex, int iCount, LPWSTR lpszOut)
|
||||
{
|
||||
static const char hexDigits[] = { "0123456789ABCDEF" };
|
||||
LPSTR lpStr = (LPSTR)lpszOut;
|
||||
|
||||
TRACE("(%p,%d,%p)\n", lpHex, iCount, lpszOut);
|
||||
|
||||
while (iCount-- > 0)
|
||||
{
|
||||
*lpStr++ = hexDigits[*lpHex >> 4];
|
||||
*lpStr++ = hexDigits[*lpHex & 0xf];
|
||||
lpHex++;
|
||||
}
|
||||
*lpStr = '\0';
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SwapPlong@8 (MAPI32.47)
|
||||
*
|
||||
|
@ -348,6 +427,33 @@ INT WINAPI MNLS_CompareStringW(DWORD dwCp, LPCWSTR lpszLeft, LPCWSTR lpszRight)
|
|||
return ret < 0 ? CSTR_LESS_THAN : ret ? CSTR_GREATER_THAN : CSTR_EQUAL;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* FEqualNames@8 (MAPI32.72)
|
||||
*
|
||||
* Compare two Mapi names.
|
||||
*
|
||||
* PARAMS
|
||||
* lpName1 [I] First name to compare to lpName2
|
||||
* lpName2 [I] Second name to compare to lpName1
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE, if the names are the same,
|
||||
* FALSE, Otherwise.
|
||||
*/
|
||||
BOOL WINAPI FEqualNames(LPMAPINAMEID lpName1, LPMAPINAMEID lpName2)
|
||||
{
|
||||
TRACE("(%p,%p)\n", lpName1, lpName2);
|
||||
|
||||
if (!lpName1 || !lpName2 ||
|
||||
!IsEqualGUID(lpName1->lpguid, lpName2->lpguid) ||
|
||||
lpName1->ulKind != lpName2->ulKind)
|
||||
return FALSE;
|
||||
|
||||
if (lpName1->ulKind == MNID_STRING)
|
||||
return !strcmpW(lpName1->Kind.lpwstrName, lpName2->Kind.lpwstrName);
|
||||
|
||||
return lpName1->Kind.lID == lpName2->Kind.lID ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* FtAddFt@16 (MAPI32.121)
|
||||
|
@ -364,7 +470,7 @@ INT WINAPI MNLS_CompareStringW(DWORD dwCp, LPCWSTR lpszLeft, LPCWSTR lpszRight)
|
|||
LONGLONG WINAPI MAPI32_FtAddFt(FILETIME ftLeft, FILETIME ftRight)
|
||||
{
|
||||
LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
|
||||
|
||||
|
||||
return *pl + *pr;
|
||||
}
|
||||
|
||||
|
@ -374,7 +480,7 @@ LONGLONG WINAPI MAPI32_FtAddFt(FILETIME ftLeft, FILETIME ftRight)
|
|||
* Subtract two FILETIME's together.
|
||||
*
|
||||
* PARAMS
|
||||
* ftLeft [I] Initial FILETIME
|
||||
* ftLeft [I] Initial FILETIME
|
||||
* ftRight [I] FILETIME to subtract from ftLeft
|
||||
*
|
||||
* RETURNS
|
||||
|
@ -383,7 +489,7 @@ LONGLONG WINAPI MAPI32_FtAddFt(FILETIME ftLeft, FILETIME ftRight)
|
|||
LONGLONG WINAPI MAPI32_FtSubFt(FILETIME ftLeft, FILETIME ftRight)
|
||||
{
|
||||
LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
|
||||
|
||||
|
||||
return *pr - *pl;
|
||||
}
|
||||
|
||||
|
@ -402,10 +508,10 @@ LONGLONG WINAPI MAPI32_FtSubFt(FILETIME ftLeft, FILETIME ftRight)
|
|||
LONGLONG WINAPI MAPI32_FtMulDw(DWORD dwLeft, FILETIME ftRight)
|
||||
{
|
||||
LONGLONG *pr = (LONGLONG*)&ftRight;
|
||||
|
||||
|
||||
return (LONGLONG)dwLeft * (*pr);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* FtMulDwDw@8 (MAPI32.125)
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue