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
|
41 stub WrapProgress@20
|
||||||
42 stdcall HrThisThreadAdviseSink@8(ptr ptr) HrThisThreadAdviseSink
|
42 stdcall HrThisThreadAdviseSink@8(ptr ptr) HrThisThreadAdviseSink
|
||||||
43 stub ScBinFromHexBounded@12
|
43 stub ScBinFromHexBounded@12
|
||||||
44 stub FBinFromHex@8
|
44 stdcall FBinFromHex@8(ptr ptr) FBinFromHex
|
||||||
45 stub HexFromBin@12
|
45 stdcall HexFromBin@12(ptr long ptr) HexFromBin
|
||||||
46 stub BuildDisplayTable@40
|
46 stub BuildDisplayTable@40
|
||||||
47 stdcall SwapPlong@8(ptr long) SwapPlong
|
47 stdcall SwapPlong@8(ptr long) SwapPlong
|
||||||
48 stdcall SwapPword@8(ptr long) SwapPword
|
48 stdcall SwapPword@8(ptr long) SwapPword
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
66 stdcall MNLS_MultiByteToWideChar@24(long long str long ptr long) kernel32.MultiByteToWideChar
|
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
|
67 stdcall MNLS_WideCharToMultiByte@32(long long wstr long ptr long ptr ptr) kernel32.WideCharToMultiByte
|
||||||
68 stdcall MNLS_IsBadStringPtrW@8(ptr long) kernel32.IsBadStringPtrW
|
68 stdcall MNLS_IsBadStringPtrW@8(ptr long) kernel32.IsBadStringPtrW
|
||||||
72 stub FEqualNames@8
|
72 stdcall FEqualNames@8(ptr ptr) FEqualNames
|
||||||
73 stub WrapStoreEntryID@24
|
73 stub WrapStoreEntryID@24
|
||||||
74 stub IsBadBoundedStringPtr@8
|
74 stub IsBadBoundedStringPtr@8
|
||||||
75 stub HrQueryAllRows@24
|
75 stub HrQueryAllRows@24
|
||||||
|
@ -75,12 +75,12 @@
|
||||||
131 stdcall SzFindLastCh@8(str str long) shlwapi.StrRChrA
|
131 stdcall SzFindLastCh@8(str str long) shlwapi.StrRChrA
|
||||||
132 stdcall SzFindSz@8(str str) shlwapi.StrStrA
|
132 stdcall SzFindSz@8(str str) shlwapi.StrStrA
|
||||||
133 stub UFromSz@4
|
133 stub UFromSz@4
|
||||||
135 stub HrGetOneProp@12
|
135 stdcall HrGetOneProp@12(ptr long ptr) HrGetOneProp
|
||||||
136 stub HrSetOneProp@8
|
136 stdcall HrSetOneProp@8(ptr ptr) HrSetOneProp
|
||||||
137 stub FPropExists@8
|
137 stdcall FPropExists@8(ptr long) FPropExists
|
||||||
138 stdcall PpropFindProp@12(ptr long long) PpropFindProp
|
138 stdcall PpropFindProp@12(ptr long long) PpropFindProp
|
||||||
139 stub FreePadrlist@4
|
139 stdcall FreePadrlist@4(ptr) FreePadrlist
|
||||||
140 stub FreeProws@4
|
140 stdcall FreeProws@4(ptr) FreeProws
|
||||||
141 stub HrSzFromEntryID@12
|
141 stub HrSzFromEntryID@12
|
||||||
142 stub HrEntryIDFromSz@12
|
142 stub HrEntryIDFromSz@12
|
||||||
143 stub HrComposeEID@28
|
143 stub HrComposeEID@28
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
171 stdcall ScCopyProps@16(long ptr ptr ptr) ScCopyProps
|
171 stdcall ScCopyProps@16(long ptr ptr ptr) ScCopyProps
|
||||||
172 stdcall ScRelocProps@20(long ptr ptr ptr ptr) ScRelocProps
|
172 stdcall ScRelocProps@20(long ptr ptr ptr ptr) ScRelocProps
|
||||||
173 stdcall LpValFindProp@12(long long ptr) LpValFindProp
|
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
|
175 stdcall FBadRglpszA@8(ptr long) FBadRglpszA
|
||||||
176 stdcall FBadRglpszW@8(ptr long) FBadRglpszW
|
176 stdcall FBadRglpszW@8(ptr long) FBadRglpszW
|
||||||
177 stdcall FBadRowSet@4(ptr) FBadRowSet
|
177 stdcall FBadRowSet@4(ptr) FBadRowSet
|
||||||
|
|
|
@ -513,6 +513,107 @@ LONG WINAPI LPropCompareProp(LPSPropValue lpPropLeft, LPSPropValue lpPropRight)
|
||||||
return 0;
|
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)
|
* PpropFindProp@12 (MAPI32.138)
|
||||||
*
|
*
|
||||||
|
@ -549,6 +650,51 @@ LPSPropValue WINAPI PpropFindProp(LPSPropValue lpProps, ULONG cValues, ULONG ulP
|
||||||
return NULL;
|
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)
|
* ScCountProps@12 (MAPI32.170)
|
||||||
*
|
*
|
||||||
|
@ -649,7 +795,7 @@ SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG
|
||||||
{
|
{
|
||||||
LPSPropValue lpDest = (LPSPropValue)lpDst;
|
LPSPropValue lpDest = (LPSPropValue)lpDst;
|
||||||
char *lpDataDest = (char *)(lpDest + cValues);
|
char *lpDataDest = (char *)(lpDest + cValues);
|
||||||
ULONG ulLen, i;
|
ULONG ulLen, i, iter;
|
||||||
|
|
||||||
TRACE("(%d,%p,%p,%p)\n", cValues, lpProps, lpDst, lpCount);
|
TRACE("(%d,%p,%p,%p)\n", cValues, lpProps, lpDst, lpCount);
|
||||||
|
|
||||||
|
@ -658,7 +804,7 @@ SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG
|
||||||
|
|
||||||
memcpy(lpDst, lpProps, cValues * sizeof(SPropValue));
|
memcpy(lpDst, lpProps, cValues * sizeof(SPropValue));
|
||||||
|
|
||||||
for (i = 0; i < cValues; i++)
|
for (iter = 0; iter < cValues; iter++)
|
||||||
{
|
{
|
||||||
switch (PROP_TYPE(lpProps->ulPropTag))
|
switch (PROP_TYPE(lpProps->ulPropTag))
|
||||||
{
|
{
|
||||||
|
@ -784,7 +930,7 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
||||||
static const BOOL bBadPtr = TRUE; /* Windows bug - Assumes source is bad */
|
static const BOOL bBadPtr = TRUE; /* Windows bug - Assumes source is bad */
|
||||||
LPSPropValue lpDest = (LPSPropValue)lpProps;
|
LPSPropValue lpDest = (LPSPropValue)lpProps;
|
||||||
ULONG ulCount = cValues * sizeof(SPropValue);
|
ULONG ulCount = cValues * sizeof(SPropValue);
|
||||||
ULONG ulLen, i;
|
ULONG ulLen, i, iter;
|
||||||
|
|
||||||
TRACE("(%d,%p,%p,%p,%p)\n", cValues, lpProps, lpOld, lpNew, lpCount);
|
TRACE("(%d,%p,%p,%p,%p)\n", cValues, lpProps, lpOld, lpNew, lpCount);
|
||||||
|
|
||||||
|
@ -807,7 +953,7 @@ SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
|
||||||
|
|
||||||
#define RELOC_PTR(p) (((char*)(p)) - (char*)lpOld + (char*)lpNew)
|
#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))
|
switch (PROP_TYPE(lpDest->ulPropTag))
|
||||||
{
|
{
|
||||||
|
@ -935,6 +1081,40 @@ LPSPropValue WINAPI LpValFindProp(ULONG ulPropTag, ULONG cValues, LPSPropValue l
|
||||||
return NULL;
|
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)
|
* FBadRglpszA@8 (MAPI32.175)
|
||||||
*
|
*
|
||||||
|
|
|
@ -34,6 +34,8 @@ static HMODULE hMapi32 = 0;
|
||||||
static SCODE (WINAPI *pScInitMapiUtil)(ULONG);
|
static SCODE (WINAPI *pScInitMapiUtil)(ULONG);
|
||||||
static void (WINAPI *pSwapPword)(PUSHORT,ULONG);
|
static void (WINAPI *pSwapPword)(PUSHORT,ULONG);
|
||||||
static void (WINAPI *pSwapPlong)(PULONG,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)
|
static void test_SwapPword(void)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +71,43 @@ static void test_SwapPlong(void)
|
||||||
longs[0], longs[1], longs[2]);
|
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)
|
START_TEST(util)
|
||||||
{
|
{
|
||||||
hMapi32 = LoadLibraryA("mapi32.dll");
|
hMapi32 = LoadLibraryA("mapi32.dll");
|
||||||
|
@ -80,4 +119,5 @@ START_TEST(util)
|
||||||
|
|
||||||
test_SwapPword();
|
test_SwapPword();
|
||||||
test_SwapPlong();
|
test_SwapPlong();
|
||||||
|
test_HexFromBin();
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,6 +227,85 @@ HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK*
|
||||||
return S_OK;
|
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)
|
* 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;
|
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)
|
* FtAddFt@16 (MAPI32.121)
|
||||||
|
|
Loading…
Reference in New Issue