Commit b1e84873 authored by Jon Griffiths's avatar Jon Griffiths Committed by Alexandre Julliard

Implement HrGetOneProp, HrSetOneProp, FPropExists, FreePadrlist,

FreeProws, ScDupPropset, HexFromBin, FBinFromHex, FEqualNames. Fix 2 cases where iterating over value arrays reused a loop variable incorrectly.
parent bd4cee32
......@@ -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;
......@@ -514,6 +514,107 @@ LONG WINAPI LPropCompareProp(LPSPropValue lpPropLeft, LPSPropValue lpPropRight)
}
/*************************************************************************
* 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)
*
* Find a property with a given property tag in a property array.
......@@ -550,6 +651,51 @@ LPSPropValue WINAPI PpropFindProp(LPSPropValue lpProps, ULONG cValues, ULONG ulP
}
/*************************************************************************
* 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)
*
* Validate and determine the length of an array of properties.
......@@ -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;
}
......@@ -936,6 +1082,40 @@ LPSPropValue WINAPI LpValFindProp(ULONG ulPropTag, ULONG cValues, LPSPropValue l
}
/*************************************************************************
* 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)
*
* Determine if an array of strings is invalid
......@@ -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();
}
......@@ -228,6 +228,85 @@ HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK*
}
/*************************************************************************
* 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)
*
* Swap the bytes in a ULONG array.
......@@ -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)
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment