CreateDCA -> CreateDCW

Jon Griffiths jon_p_griffiths at yahoo.com
Sun Sep 12 10:50:22 CDT 2004


Hi,

Partial sync of my local mapi tree. Note some patch lines merely
remove
trailing whitespace.

Cheers,
Jon

Changelog:

   +dlls/mapi32/mapi32.spec dlls/mapi32/prop.c
    Implement HrGetOneProp, HrSetOneProp, FPropExists, FreePadrlist,
    FreeProws, ScDupPropset
    Fix 2 cases where iterating over value arrays reused a loop 
    variable incorrectly

   +dlls/mapi32/util.c
    Implement HexFromBin, FBinFromHex, FEqualNames

   +dlls/mapi32/tests/util.c
    Test HexFromBin, FBinFromHex


=====
"Don't wait for the seas to part, or messiahs to come;
 Don't you sit around and waste this chance..." - Live

jon_p_griffiths at yahoo.com


		
_______________________________
Do you Yahoo!?
Shop for Back-to-School deals on Yahoo! Shopping.
http://shopping.yahoo.com/backtoschool
-------------- next part --------------
diff -ur wine/dlls/mapi32/mapi32.spec wine-develop/dlls/mapi32/mapi32.spec
--- wine/dlls/mapi32/mapi32.spec	2004-06-23 08:33:09.000000000 +0000
+++ wine-develop/dlls/mapi32/mapi32.spec	2004-09-11 12:15:09.000000000 +0000
@@ -29,8 +29,8 @@
  41 stub WrapProgress at 20
  42 stdcall HrThisThreadAdviseSink at 8(ptr ptr) HrThisThreadAdviseSink
  43 stub ScBinFromHexBounded at 12
- 44 stub FBinFromHex at 8
- 45 stub HexFromBin at 12
+ 44 stdcall FBinFromHex at 8(ptr ptr) FBinFromHex
+ 45 stdcall HexFromBin at 12(ptr long ptr) HexFromBin
  46 stub BuildDisplayTable at 40
  47 stdcall SwapPlong at 8(ptr long) SwapPlong
  48 stdcall SwapPword at 8(ptr long) SwapPword
@@ -51,7 +51,7 @@
  66 stdcall MNLS_MultiByteToWideChar at 24(long long str long ptr long) kernel32.MultiByteToWideChar
  67 stdcall MNLS_WideCharToMultiByte at 32(long long wstr long ptr long ptr ptr) kernel32.WideCharToMultiByte
  68 stdcall MNLS_IsBadStringPtrW at 8(ptr long) kernel32.IsBadStringPtrW
- 72 stub FEqualNames at 8
+ 72 stdcall FEqualNames at 8(ptr ptr) FEqualNames
  73 stub WrapStoreEntryID at 24
  74 stub IsBadBoundedStringPtr at 8
  75 stub HrQueryAllRows at 24
@@ -75,12 +75,12 @@
 131 stdcall SzFindLastCh at 8(str str long) shlwapi.StrRChrA
 132 stdcall SzFindSz at 8(str str) shlwapi.StrStrA
 133 stub UFromSz at 4
-135 stub HrGetOneProp at 12
-136 stub HrSetOneProp at 8
-137 stub FPropExists at 8
+135 stdcall HrGetOneProp at 12(ptr long ptr) HrGetOneProp
+136 stdcall HrSetOneProp at 8(ptr ptr) HrSetOneProp
+137 stdcall FPropExists at 8(ptr long) FPropExists
 138 stdcall PpropFindProp at 12(ptr long long) PpropFindProp
-139 stub FreePadrlist at 4
-140 stub FreeProws at 4
+139 stdcall FreePadrlist at 4(ptr) FreePadrlist
+140 stdcall FreeProws at 4(ptr) FreeProws
 141 stub HrSzFromEntryID at 12
 142 stub HrEntryIDFromSz at 12
 143 stub HrComposeEID at 28
@@ -111,7 +111,7 @@
 171 stdcall ScCopyProps at 16(long ptr ptr ptr) ScCopyProps
 172 stdcall ScRelocProps at 20(long ptr ptr ptr ptr) ScRelocProps
 173 stdcall LpValFindProp at 12(long long ptr) LpValFindProp
-174 stub ScDupPropset at 16
+174 stdcall ScDupPropset at 16(long ptr ptr ptr) ScDupPropset
 175 stdcall FBadRglpszA at 8(ptr long) FBadRglpszA
 176 stdcall FBadRglpszW at 8(ptr long) FBadRglpszW
 177 stdcall FBadRowSet at 4(ptr) FBadRowSet
diff -ur wine/dlls/mapi32/prop.c wine-develop/dlls/mapi32/prop.c
--- wine/dlls/mapi32/prop.c	2004-05-03 20:19:00.000000000 +0000
+++ wine-develop/dlls/mapi32/prop.c	2004-09-11 12:19:09.000000000 +0000
@@ -154,7 +154,7 @@
             {
                 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 @@
 }
 
 /*************************************************************************
+ * HrGetOneProp at 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 at 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 at 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 at 12 (MAPI32.138)
  *
  * Find a property with a given property tag in a property array.
@@ -550,6 +651,51 @@
 }
 
 /*************************************************************************
+ * FreePadrlist at 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 at 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 at 12 (MAPI32.170)
  *
  * Validate and determine the length of an array of properties.
@@ -623,7 +769,7 @@
     }
     if (pcBytes)
         *pcBytes = ulBytes;
-    
+
     return S_OK;
 }
 
@@ -649,16 +795,16 @@
 {
     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 @@
                 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 @@
                 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 @@
     }
     if (lpCount)
         *lpCount = lpDataDest - (char *)lpDst;
-        
+
     return S_OK;
 }
- 
+
 /*************************************************************************
  * ScRelocProps at 20 (MAPI32.172)
  *
@@ -784,10 +930,10 @@
     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 @@
      * 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 @@
                  */
                 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 @@
                     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 @@
                 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 @@
     }
     if (lpCount)
         *lpCount = ulCount;
-        
+
     return S_OK;
 }
 
@@ -936,6 +1082,40 @@
 }
 
 /*************************************************************************
+ * ScDupPropset at 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 at 8 (MAPI32.175)
  *
  * Determine if an array of strings is invalid
@@ -955,7 +1135,7 @@
 
     if (!ulCount)
         return FALSE;
-        
+
     if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
         return TRUE;
 
@@ -980,7 +1160,7 @@
 
     if (!ulCount)
         return FALSE;
- 
+
     if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
         return TRUE;
 
diff -ur wine/dlls/mapi32/tests/util.c wine-develop/dlls/mapi32/tests/util.c
--- wine/dlls/mapi32/tests/util.c	2004-04-23 23:30:00.000000000 +0000
+++ wine-develop/dlls/mapi32/tests/util.c	2004-09-11 11:46:16.000000000 +0000
@@ -34,6 +34,8 @@
 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 @@
        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 at 12");
+    pFBinFromHex = (void*)GetProcAddress(hMapi32, "FBinFromHex at 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 at 4");
     if (!pScInitMapiUtil)
         return;
@@ -80,4 +119,5 @@
 
     test_SwapPword();
     test_SwapPlong();
+    test_HexFromBin();
 }
diff -ur wine/dlls/mapi32/util.c wine-develop/dlls/mapi32/util.c
--- wine/dlls/mapi32/util.c	2004-05-01 02:39:34.000000000 +0000
+++ wine-develop/dlls/mapi32/util.c	2004-09-11 11:52:03.000000000 +0000
@@ -228,6 +228,85 @@
 }
 
 /*************************************************************************
+ * 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 at 8 (MAPI32.47)
  *
  * Swap the bytes in a ULONG array.
@@ -348,6 +427,33 @@
     return ret < 0 ? CSTR_LESS_THAN : ret ? CSTR_GREATER_THAN : CSTR_EQUAL;
 }
 
+/**************************************************************************
+ *  FEqualNames at 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 at 16 (MAPI32.121)
@@ -364,7 +470,7 @@
 LONGLONG WINAPI MAPI32_FtAddFt(FILETIME ftLeft, FILETIME ftRight)
 {
     LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
-    
+
     return *pl + *pr;
 }
 
@@ -374,7 +480,7 @@
  * 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_FtSubFt(FILETIME ftLeft, FILETIME ftRight)
 {
     LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
-    
+
     return *pr - *pl;
 }
 
@@ -402,10 +508,10 @@
 LONGLONG WINAPI MAPI32_FtMulDw(DWORD dwLeft, FILETIME ftRight)
 {
     LONGLONG *pr = (LONGLONG*)&ftRight;
-    
+
     return (LONGLONG)dwLeft * (*pr);
 }
- 
+
 /**************************************************************************
  *  FtMulDwDw at 8 (MAPI32.125)
  *


More information about the wine-patches mailing list