crypt32: Assign to structs instead of using memcpy.
[wine] / dlls / mapi32 / util.c
index f58b866..b68eceb 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #include <stdarg.h>
+#include <stdio.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #include "windef.h"
 #include "winbase.h"
 #include "winreg.h"
+#include "winuser.h"
 #include "winerror.h"
 #include "winternl.h"
 #include "objbase.h"
 #include "wine/unicode.h"
 #include "mapival.h"
 #include "xcmc.h"
+#include "msi.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mapi);
 
+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 };
+
 /**************************************************************************
  *  ScInitMapiUtil (MAPI32.33)
  *
@@ -54,7 +64,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mapi);
  */
 SCODE WINAPI ScInitMapiUtil(ULONG ulReserved)
 {
-    FIXME("(0x%08lx)stub!\n", ulReserved);
+    FIXME("(0x%08x)stub!\n", ulReserved);
     if (ulReserved)
         return MAPI_E_INVALID_PARAMETER;
     return S_OK;
@@ -108,12 +118,12 @@ SCODE WINAPI MAPIAllocateBuffer(ULONG cbSize, LPVOID *lppBuffer)
 {
     LPMAPIALLOCBUFFER lpBuff;
 
-    TRACE("(%ld,%p)\n", cbSize, lppBuffer);
+    TRACE("(%d,%p)\n", cbSize, lppBuffer);
 
     if (!lppBuffer)
         return E_INVALIDARG;
 
-    lpBuff = (LPMAPIALLOCBUFFER)HeapAlloc(GetProcessHeap(), 0, cbSize + sizeof(*lpBuff));
+    lpBuff = HeapAlloc(GetProcessHeap(), 0, cbSize + sizeof(*lpBuff));
     if (!lpBuff)
         return MAPI_E_NOT_ENOUGH_MEMORY;
 
@@ -148,7 +158,7 @@ SCODE WINAPI MAPIAllocateMore(ULONG cbSize, LPVOID lpOrig, LPVOID *lppBuffer)
 {
     LPMAPIALLOCBUFFER lpBuff = lpOrig;
 
-    TRACE("(%ld,%p,%p)\n", cbSize, lpOrig, lppBuffer);
+    TRACE("(%d,%p,%p)\n", cbSize, lpOrig, lppBuffer);
 
     if (!lppBuffer || !lpBuff || !--lpBuff)
         return E_INVALIDARG;
@@ -201,6 +211,15 @@ ULONG WINAPI MAPIFreeBuffer(LPVOID lpBuffer)
     return S_OK;
 }
 
+/**************************************************************************
+ *  WrapProgress@20 (MAPI32.41)
+ */
+HRESULT WINAPI WrapProgress(PVOID unk1, PVOID unk2, PVOID unk3, PVOID unk4, PVOID unk5)
+{
+    /* Native does not implement this function */
+    return MAPI_E_NO_SUPPORT;
+}
+
 /*************************************************************************
  * HrThisThreadAdviseSink@8 (MAPI32.42)
  *
@@ -249,11 +268,6 @@ HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK*
  */
 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);
@@ -422,7 +436,7 @@ INT WINAPI MNLS_CompareStringW(DWORD dwCp, LPCWSTR lpszLeft, LPCWSTR lpszRight)
 {
     INT ret;
 
-    TRACE("0x%08lx,%s,%s\n", dwCp, debugstr_w(lpszLeft), debugstr_w(lpszRight));
+    TRACE("0x%08x,%s,%s\n", dwCp, debugstr_w(lpszLeft), debugstr_w(lpszRight));
     ret = MNLS_lstrcmpW(lpszLeft, lpszRight);
     return ret < 0 ? CSTR_LESS_THAN : ret ? CSTR_GREATER_THAN : CSTR_EQUAL;
 }
@@ -455,6 +469,26 @@ BOOL WINAPI FEqualNames(LPMAPINAMEID lpName1, LPMAPINAMEID lpName2)
     return lpName1->Kind.lID == lpName2->Kind.lID ? TRUE : FALSE;
 }
 
+/**************************************************************************
+ *  IsBadBoundedStringPtr@8 (MAPI32.71)
+ *
+ * Determine if a string pointer is valid.
+ *
+ * PARAMS
+ *  lpszStr [I] String to check
+ *  ulLen   [I] Maximum length of lpszStr
+ *
+ * RETURNS
+ *  TRUE, if lpszStr is invalid or longer than ulLen,
+ *  FALSE, otherwise.
+ */
+BOOL WINAPI IsBadBoundedStringPtr(LPCSTR lpszStr, ULONG ulLen)
+{
+    if (!lpszStr || IsBadStringPtrA(lpszStr, -1) || strlen(lpszStr) >= ulLen)
+        return TRUE;
+    return FALSE;
+}
+
 /**************************************************************************
  *  FtAddFt@16 (MAPI32.121)
  *
@@ -543,7 +577,7 @@ LONGLONG WINAPI MAPI32_FtMulDwDw(DWORD dwLeft, DWORD dwRight)
 LONGLONG WINAPI MAPI32_FtNegFt(FILETIME ft)
 {
     LONGLONG *p = (LONGLONG*)&ft;
-    
+
     return - *p;
 }
 
@@ -595,6 +629,39 @@ ULONG WINAPI UlRelease(void *lpUnk)
     return IUnknown_Release((LPUNKNOWN)lpUnk);
 }
 
+/**************************************************************************
+ *  UFromSz@4 (MAPI32.133)
+ *
+ * Read an integer from a string
+ *
+ * PARAMS
+ *  lpszStr [I] String to read the integer from.
+ *
+ * RETURNS
+ *  Success: The integer read from lpszStr.
+ *  Failure: 0, if the first character in lpszStr is not 0-9.
+ *
+ * NOTES
+ *  This function does not accept whitespace and stops at the first non-digit
+ *  character.
+ */
+UINT WINAPI UFromSz(LPCSTR lpszStr)
+{
+    ULONG ulRet = 0;
+
+    TRACE("(%s)\n", debugstr_a(lpszStr));
+
+    if (lpszStr)
+    {
+        while (*lpszStr >= '0' && *lpszStr <= '9')
+        {
+            ulRet = ulRet * 10 + (*lpszStr - '0');
+            lpszStr++;
+        }
+    }
+    return ulRet;
+}
+
 /*************************************************************************
  * OpenStreamOnFile@24 (MAPI32.147)
  *
@@ -621,7 +688,7 @@ HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER lpAlloc, LPFREEBUFFER lpFree,
     DWORD dwMode = STGM_READWRITE, dwAttributes = 0;
     HRESULT hRet;
 
-    TRACE("(%p,%p,0x%08lx,%s,%s,%p)\n", lpAlloc, lpFree, ulFlags,
+    TRACE("(%p,%p,0x%08x,%s,%s,%p)\n", lpAlloc, lpFree, ulFlags,
           debugstr_a((LPSTR)lpszPath), debugstr_a((LPSTR)lpszPrefix), lppStream);
 
     if (lppStream)
@@ -647,6 +714,90 @@ HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER lpAlloc, LPFREEBUFFER lpFree,
     return hRet;
 }
 
+/*************************************************************************
+ * UlFromSzHex@4 (MAPI32.155)
+ *
+ * Read an integer from a hexadecimal string.
+ *
+ * PARAMS
+ *  lpSzHex [I] String containing the hexadecimal number to read
+ *
+ * RETURNS
+ * Success: The number represented by lpszHex.
+ * Failure: 0, if lpszHex does not contain a hex string.
+ *
+ * NOTES
+ *  This function does not accept whitespace and stops at the first non-hex
+ *  character.
+ */
+ULONG WINAPI UlFromSzHex(LPCWSTR lpszHex)
+{
+    LPCSTR lpStr = (LPCSTR)lpszHex;
+    ULONG ulRet = 0;
+
+    TRACE("(%s)\n", debugstr_a(lpStr));
+
+    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)
+            break;
+
+        ulRet = ulRet * 16 + ((digitsToHex[lpStr[0] - '0'] << 4) | digitsToHex[lpStr[1] - '0']);
+        lpStr += 2;
+    }
+    return ulRet;
+}
+
+/************************************************************************
+ * FBadEntryList@4 (MAPI32.190)
+ *
+ * Determine is an entry list is invalid.
+ *
+ * PARAMS
+ *  lpEntryList [I] List to check
+ *
+ * RETURNS
+ *  TRUE, if lpEntryList is invalid,
+ *  FALSE, otherwise.
+ */
+BOOL WINAPI FBadEntryList(LPENTRYLIST lpEntryList)
+{
+    ULONG i;
+
+    if (IsBadReadPtr(lpEntryList, sizeof(*lpEntryList)) ||
+        IsBadReadPtr(lpEntryList->lpbin,
+                     lpEntryList->cValues * sizeof(*lpEntryList->lpbin)))
+        return TRUE;
+
+    for (i = 0; i < lpEntryList->cValues; i++)
+        if(IsBadReadPtr(lpEntryList->lpbin[i].lpb, lpEntryList->lpbin[i].cb))
+            return TRUE;
+
+    return FALSE;
+}
+
+/*************************************************************************
+ * CbOfEncoded@4 (MAPI32.207)
+ *
+ * Return the length of an encoded string.
+ *
+ * PARAMS
+ *  lpSzEnc [I] Encoded string to get the length of.
+ *
+ * RETURNS
+ * The length of the encoded string in bytes.
+ */
+ULONG WINAPI CbOfEncoded(LPCSTR lpszEnc)
+{
+    ULONG ulRet = 0;
+
+    TRACE("(%s)\n", debugstr_a(lpszEnc));
+
+    if (lpszEnc)
+        ulRet = (((strlen(lpszEnc) | 3) >> 2) + 1) * 3;
+    return ulRet;
+}
 
 /*************************************************************************
  * cmc_query_configuration (MAPI32.235)
@@ -669,6 +820,85 @@ CMC_return_code WINAPI cmc_query_configuration(
   CMC_buffer reference,
   CMC_extension  *config_extensions)
 {
-       FIXME("stub");
+       FIXME("stub\n");
        return CMC_E_NOT_SUPPORTED;
 }
+
+/**************************************************************************
+ *  FGetComponentPath   (MAPI32.254)
+ *  FGetComponentPath@20 (MAPI32.255)
+ *
+ * Return the installed component path, usually to the private mapi32.dll.
+ *
+ * PARAMS
+ *  component       [I] Component ID
+ *  qualifier       [I] Application LCID
+ *  dll_path        [O] returned component path
+ *  dll_path_length [I] component path length
+ *  install         [I] install mode
+ *
+ * RETURNS
+ *  Success: TRUE.
+ *  Failure: FALSE.
+ *
+ * NOTES
+ *  Previously documented in Q229700 "How to locate the correct path
+ *  to the Mapisvc.inf file in Microsoft Outlook".
+ */
+BOOL WINAPI FGetComponentPath(LPCSTR component, LPCSTR qualifier, LPSTR dll_path,
+                              DWORD dll_path_length, BOOL install)
+{
+    BOOL ret = FALSE;
+    HMODULE hmsi;
+
+    TRACE("%s %s %p %u %d\n", component, qualifier, dll_path, dll_path_length, install);
+
+    dll_path[0] = 0;
+
+    hmsi = LoadLibraryA("msi.dll");
+    if (hmsi)
+    {
+        FARPROC pMsiProvideQualifiedComponentA = GetProcAddress(hmsi, "MsiProvideQualifiedComponentA");
+
+        if (pMsiProvideQualifiedComponentA)
+        {
+            static const char * const fmt[] = { "%d\\NT", "%d\\95", "%d" };
+            char lcid_ver[20];
+            UINT i;
+
+            for (i = 0; i < sizeof(fmt)/sizeof(fmt[0]); i++)
+            {
+                /* FIXME: what's the correct behaviour here? */
+                if (!qualifier || qualifier == lcid_ver)
+                {
+                    sprintf(lcid_ver, fmt[i], GetUserDefaultUILanguage());
+                    qualifier = lcid_ver;
+                }
+
+                if (pMsiProvideQualifiedComponentA(component, qualifier,
+                        install ? INSTALLMODE_DEFAULT : INSTALLMODE_EXISTING,
+                        dll_path, &dll_path_length) == ERROR_SUCCESS)
+                {
+                    ret = TRUE;
+                    break;
+                }
+
+                if (qualifier != lcid_ver) break;
+            }
+        }
+        FreeLibrary(hmsi);
+    }
+    return ret;
+}
+
+/**************************************************************************
+ *  HrQueryAllRows   (MAPI32.75)
+ */
+HRESULT WINAPI HrQueryAllRows(LPMAPITABLE lpTable, LPSPropTagArray lpPropTags,
+    LPSRestriction lpRestriction, LPSSortOrderSet lpSortOrderSet,
+    LONG crowsMax, LPSRowSet *lppRows)
+{
+    FIXME("(%p, %p, %p, %p, %d, %p): stub\n", lpTable, lpPropTags, lpRestriction, lpSortOrderSet, crowsMax, lppRows);
+    *lppRows = NULL;
+    return MAPI_E_CALL_FAILED;
+}