Implement DllMain, DllCanUnloadNow, WrapProgress,
MAPIGetDefaultMalloc, IsBadBoundedStringPtr, UFromSz, UlFromSzHex,
CbOfEncoded.
Add tests for the above.
diff --git a/dlls/mapi32/Makefile.in b/dlls/mapi32/Makefile.in
index 58426d2..72d3da6 100644
--- a/dlls/mapi32/Makefile.in
+++ b/dlls/mapi32/Makefile.in
@@ -3,10 +3,11 @@
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = mapi32.dll
-IMPORTS = shlwapi ole32 kernel32
+IMPORTS = shlwapi ole32 user32 kernel32
EXTRALIBS = -luuid $(LIBUNICODE)
C_SRCS = \
+ imalloc.c \
mapi32_main.c \
prop.c \
util.c
diff --git a/dlls/mapi32/imalloc.c b/dlls/mapi32/imalloc.c
new file mode 100644
index 0000000..52ea5a7
--- /dev/null
+++ b/dlls/mapi32/imalloc.c
@@ -0,0 +1,181 @@
+/*
+ * MAPI Default IMalloc implementation
+ *
+ * Copyright 2004 Jon Griffiths
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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
+ */
+
+#include <stdarg.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 "shlwapi.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mapi);
+
+static const IMallocVtbl MAPI_IMalloc_vt;
+
+typedef struct
+{
+ const IMallocVtbl *lpVtbl;
+ LONG lRef;
+} MAPI_IMALLOC;
+
+static MAPI_IMALLOC MAPI_IMalloc = { &MAPI_IMalloc_vt, 0u };
+
+extern LONG MAPI_ObjectCount; /* In mapi32_main.c */
+
+/*************************************************************************
+ * MAPIGetDefaultMalloc@0 (MAPI32.59)
+ *
+ * Get the default MAPI IMalloc interface.
+ *
+ * PARAMS
+ * None.
+ *
+ * RETURNS
+ * A pointer to the MAPI default allocator.
+ */
+LPMALLOC WINAPI MAPIGetDefaultMalloc(void)
+{
+ TRACE("()\n");
+
+ IMalloc_AddRef((LPMALLOC)&MAPI_IMalloc);
+ return (LPMALLOC)&MAPI_IMalloc;
+}
+
+/**************************************************************************
+ * IMAPIMalloc_QueryInterface
+ */
+static HRESULT WINAPI IMAPIMalloc_fnQueryInterface(LPMALLOC iface, REFIID refiid,
+ LPVOID *ppvObj)
+{
+ TRACE("(%s,%p)\n", debugstr_guid(refiid), ppvObj);
+
+ if (IsEqualIID(refiid, &IID_IUnknown) ||
+ IsEqualIID(refiid, &IID_IMalloc))
+ {
+ *ppvObj = (LPMALLOC) &MAPI_IMalloc;
+ TRACE("Returning IMalloc (%p)\n", *ppvObj);
+ return S_OK;
+ }
+ TRACE("Returning E_NOINTERFACE\n");
+ return E_NOINTERFACE;
+}
+
+/**************************************************************************
+ * IMAPIMalloc_AddRef
+ */
+static ULONG WINAPI IMAPIMalloc_fnAddRef(LPMALLOC iface)
+{
+ TRACE("(%p)\n", iface);
+ InterlockedIncrement(&MAPI_ObjectCount);
+ return 1u;
+}
+
+/**************************************************************************
+ * IMAPIMalloc_Release
+ */
+static ULONG WINAPI IMAPIMalloc_fnRelease(LPMALLOC iface)
+{
+ TRACE("(%p)\n", iface);
+ InterlockedDecrement(&MAPI_ObjectCount);
+ return 1u;
+}
+
+/**************************************************************************
+ * IMAPIMalloc_Alloc
+ */
+static LPVOID WINAPI IMAPIMalloc_fnAlloc(LPMALLOC iface, DWORD cb)
+{
+ TRACE("(%p)->(%ld)\n", iface, cb);
+
+ return LocalAlloc(GMEM_FIXED, cb);
+}
+
+/**************************************************************************
+ * IMAPIMalloc_Realloc
+ */
+static LPVOID WINAPI IMAPIMalloc_fnRealloc(LPMALLOC iface, LPVOID pv, DWORD cb)
+{
+ TRACE("(%p)->(%p, %ld)\n", iface, pv, cb);
+
+ if (!pv)
+ return LocalAlloc(GMEM_FIXED, cb);
+
+ if (cb)
+ return LocalReAlloc((HANDLE) pv, cb, GMEM_MOVEABLE);
+
+ LocalFree((HANDLE) pv);
+ return NULL;
+}
+
+/**************************************************************************
+ * IMAPIMalloc_Free
+ */
+static void WINAPI IMAPIMalloc_fnFree(LPMALLOC iface, LPVOID pv)
+{
+ TRACE("(%p)->(%p)\n", iface, pv);
+ LocalFree((HANDLE) pv);
+}
+
+/**************************************************************************
+ * IMAPIMalloc_GetSize
+ */
+static DWORD WINAPI IMAPIMalloc_fnGetSize(LPMALLOC iface, LPVOID pv)
+{
+ TRACE("(%p)->(%p)\n", iface, pv);
+ return LocalSize((HANDLE) pv);
+}
+
+/**************************************************************************
+ * IMAPIMalloc_DidAlloc
+ */
+static INT WINAPI IMAPIMalloc_fnDidAlloc(LPMALLOC iface, LPVOID pv)
+{
+ TRACE("(%p)->(%p)\n", iface, pv);
+ return -1;
+}
+
+/**************************************************************************
+ * IMAPIMalloc_HeapMinimize
+ */
+static void WINAPI IMAPIMalloc_fnHeapMinimize(LPMALLOC iface)
+{
+ TRACE("(%p)\n", iface);
+}
+
+static const IMallocVtbl MAPI_IMalloc_vt =
+{
+ IMAPIMalloc_fnQueryInterface,
+ IMAPIMalloc_fnAddRef,
+ IMAPIMalloc_fnRelease,
+ IMAPIMalloc_fnAlloc,
+ IMAPIMalloc_fnRealloc,
+ IMAPIMalloc_fnFree,
+ IMAPIMalloc_fnGetSize,
+ IMAPIMalloc_fnDidAlloc,
+ IMAPIMalloc_fnHeapMinimize
+};
diff --git a/dlls/mapi32/mapi32.spec b/dlls/mapi32/mapi32.spec
index 8f3dc02..b39c158 100644
--- a/dlls/mapi32/mapi32.spec
+++ b/dlls/mapi32/mapi32.spec
@@ -17,7 +17,7 @@
25 stub LAUNCHWIZARD
26 stub LaunchWizard@20
27 stub DllGetClassObject
- 28 stub DllCanUnloadNow
+ 28 stdcall -private DllCanUnloadNow() MAPI32_DllCanUnloadNow
29 stub MAPIOpenFormMgr
30 stub MAPIOpenFormMgr@8
31 stub MAPIOpenLocalFormContainer
@@ -26,7 +26,7 @@
34 stdcall DeinitMapiUtil@0() DeinitMapiUtil
35 stub ScGenerateMuid@4
36 stub HrAllocAdviseSink@12
- 41 stub WrapProgress@20
+ 41 stdcall WrapProgress@20(ptr ptr ptr ptr ptr) WrapProgress
42 stdcall HrThisThreadAdviseSink@8(ptr ptr) HrThisThreadAdviseSink
43 stub ScBinFromHexBounded@12
44 stdcall FBinFromHex@8(ptr ptr) FBinFromHex
@@ -41,7 +41,7 @@
53 stub EnableIdleRoutine@8
54 stub DeregisterIdleRoutine@4
55 stub ChangeIdleRoutine@28
- 59 stub MAPIGetDefaultMalloc@0
+ 59 stdcall MAPIGetDefaultMalloc@0() MAPIGetDefaultMalloc
60 stub CreateIProp@24
61 stub CreateTable@36
62 stdcall MNLS_lstrlenW@4(wstr) MNLS_lstrlenW
@@ -53,7 +53,7 @@
68 stdcall MNLS_IsBadStringPtrW@8(ptr long) kernel32.IsBadStringPtrW
72 stdcall FEqualNames@8(ptr ptr) FEqualNames
73 stub WrapStoreEntryID@24
- 74 stub IsBadBoundedStringPtr@8
+ 74 stdcall IsBadBoundedStringPtr@8(ptr long) IsBadBoundedStringPtr
75 stub HrQueryAllRows@24
76 stdcall PropCopyMore@16(ptr ptr ptr ptr) PropCopyMore
77 stdcall UlPropSize@4(ptr) UlPropSize
@@ -74,7 +74,7 @@
130 stdcall SzFindCh@8(str long) shlwapi.StrChrA
131 stdcall SzFindLastCh@8(str str long) shlwapi.StrRChrA
132 stdcall SzFindSz@8(str str) shlwapi.StrStrA
-133 stub UFromSz@4
+133 stdcall UFromSz@4(str) UFromSz
135 stdcall HrGetOneProp@12(ptr long ptr) HrGetOneProp
136 stdcall HrSetOneProp@8(ptr ptr) HrSetOneProp
137 stdcall FPropExists@8(ptr long) FPropExists
@@ -95,7 +95,7 @@
152 stub OpenTnefStreamEx
153 stub GetTnefStreamCodepage@12
154 stub GetTnefStreamCodepage
-155 stub UlFromSzHex@4
+155 stdcall UlFromSzHex@4(ptr) UlFromSzHex
156 stub UNKOBJ_ScAllocate@12
157 stub UNKOBJ_ScAllocateMore@16
158 stub UNKOBJ_Free@8
@@ -144,7 +144,7 @@
204 stub EncodeID@12
205 stub FDecodeID@12
206 stub CchOfEncoding@4
-207 stub CbOfEncoded@4
+207 stdcall CbOfEncoded@4(ptr) CbOfEncoded
208 stub MAPISendDocuments
209 stdcall MAPILogon(long ptr ptr long long ptr)
210 stub MAPILogoff
diff --git a/dlls/mapi32/mapi32_main.c b/dlls/mapi32/mapi32_main.c
index ac6cc97..c9d0c00 100644
--- a/dlls/mapi32/mapi32_main.c
+++ b/dlls/mapi32/mapi32_main.c
@@ -29,6 +29,44 @@
WINE_DEFAULT_DEBUG_CHANNEL(mapi);
+LONG MAPI_ObjectCount = 0;
+
+/***********************************************************************
+ * DllMain (MAPI32.init)
+ */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
+{
+ TRACE("(%p,0x%lx,%p)\n", hinstDLL, fdwReason, fImpLoad);
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ break;
+ case DLL_PROCESS_DETACH:
+ TRACE("DLL_PROCESS_DETACH: %ld objects remaining\n", MAPI_ObjectCount);
+ break;
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * DllCanUnloadNow (MAPI32.28)
+ *
+ * Determine if this dll can be unloaded from the callers address space.
+ *
+ * PARAMS
+ * None.
+ *
+ * RETURNS
+ * S_OK, if the dll can be unloaded,
+ * S_FALSE, otherwise.
+ */
+HRESULT WINAPI MAPI32_DllCanUnloadNow(void)
+{
+ return MAPI_ObjectCount == 0 ? S_OK : S_FALSE;
+}
+
HRESULT WINAPI MAPIInitialize ( LPVOID lpMapiInit )
{
ERR("Stub\n");
diff --git a/dlls/mapi32/tests/.cvsignore b/dlls/mapi32/tests/.cvsignore
index 526e3c4..705f9ae 100644
--- a/dlls/mapi32/tests/.cvsignore
+++ b/dlls/mapi32/tests/.cvsignore
@@ -1,4 +1,5 @@
Makefile
+imalloc.ok
prop.ok
testlist.c
util.ok
diff --git a/dlls/mapi32/tests/Makefile.in b/dlls/mapi32/tests/Makefile.in
index 9b93876..6267887 100644
--- a/dlls/mapi32/tests/Makefile.in
+++ b/dlls/mapi32/tests/Makefile.in
@@ -7,6 +7,7 @@
EXTRALIBS = -luuid
CTESTS = \
+ imalloc.c \
prop.c \
util.c
diff --git a/dlls/mapi32/tests/imalloc.c b/dlls/mapi32/tests/imalloc.c
new file mode 100644
index 0000000..7fb013f
--- /dev/null
+++ b/dlls/mapi32/tests/imalloc.c
@@ -0,0 +1,101 @@
+/*
+ * Unit test suite for MAPI IMalloc functions
+ *
+ * Copyright 2004 Jon Griffiths
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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
+ */
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "wine/test.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "winnt.h"
+#include "mapiutil.h"
+
+static HMODULE hMapi32 = 0;
+
+static SCODE (WINAPI *pScInitMapiUtil)(ULONG);
+static LPMALLOC (WINAPI *pMAPIGetDefaultMalloc)(void);
+
+static void test_IMalloc(void)
+{
+ LPVOID lpMem;
+ ULONG ulRef;
+ int iRet;
+ HRESULT hRet;
+ LPMALLOC lpMalloc;
+ LPVOID lpVoid;
+
+ pMAPIGetDefaultMalloc = (void*)GetProcAddress(hMapi32,
+ "MAPIGetDefaultMalloc@0");
+ if (!pMAPIGetDefaultMalloc)
+ return;
+
+ lpMalloc = pMAPIGetDefaultMalloc();
+ ok (lpMalloc != NULL, "iMAPIGetDefaultMalloc returned null\n");
+ if (!lpMalloc)
+ return;
+
+ lpVoid = NULL;
+ hRet = IMalloc_QueryInterface(lpMalloc, &IID_IUnknown, &lpVoid);
+ ok (hRet == S_OK && lpVoid != NULL,
+ "IID_IUnknown: exepected S_OK, non-null, got 0x%08lx, %p\n",
+ hRet, lpVoid);
+
+ lpVoid = NULL;
+ hRet = IMalloc_QueryInterface(lpMalloc, &IID_IMalloc, &lpVoid);
+ ok (hRet == S_OK && lpVoid != NULL,
+ "IID_IIMalloc: exepected S_OK, non-null, got 0x%08lx, %p\n",
+ hRet, lpVoid);
+
+ /* Prove that native mapi uses LocalAlloc/LocalFree */
+ lpMem = IMalloc_Alloc(lpMalloc, 61);
+ ok (lpMem && IMalloc_GetSize(lpMalloc, lpMem) ==
+ LocalSize((HANDLE)lpMem),
+ "Expected non-null, same size, got %p, %s size\n", lpMem,
+ lpMem ? "different" : "same");
+
+ iRet = IMalloc_DidAlloc(lpMalloc, lpMem);
+ ok (iRet == -1, "DidAlloc, expected -1. got %d\n", iRet);
+
+ IMalloc_HeapMinimize(lpMalloc);
+
+ LocalFree(lpMem);
+
+ ulRef = IMalloc_AddRef(lpMalloc);
+ ok (ulRef == 1u, "AddRef expected 1, returned %ld\n", ulRef);
+
+ ulRef = IMalloc_Release(lpMalloc);
+ ok (ulRef == 1u, "AddRef expected 1, returned %ld\n", ulRef);
+
+ IMalloc_Release(lpMalloc);
+}
+
+START_TEST(imalloc)
+{
+ hMapi32 = LoadLibraryA("mapi32.dll");
+
+ pScInitMapiUtil = (void*)GetProcAddress(hMapi32, "ScInitMapiUtil@4");
+ if (!pScInitMapiUtil)
+ return;
+ pScInitMapiUtil(0);
+
+ test_IMalloc();
+}
diff --git a/dlls/mapi32/tests/util.c b/dlls/mapi32/tests/util.c
index 8a070ad..927008c 100644
--- a/dlls/mapi32/tests/util.c
+++ b/dlls/mapi32/tests/util.c
@@ -36,6 +36,10 @@
static void (WINAPI *pSwapPlong)(PULONG,ULONG);
static void (WINAPI *pHexFromBin)(LPBYTE,int,LPWSTR);
static void (WINAPI *pFBinFromHex)(LPWSTR,LPBYTE);
+static UINT (WINAPI *pUFromSz)(LPCSTR);
+static ULONG (WINAPI *pUlFromSzHex)(LPCSTR);
+static ULONG (WINAPI *pCbOfEncoded)(LPCSTR);
+static BOOL (WINAPI *pIsBadBoundedStringPtr)(LPCSTR,ULONG);
static void test_SwapPword(void)
{
@@ -107,6 +111,63 @@
ok(bOk == TRUE, "FBinFromHex: Result differs\n");
}
+static void test_UFromSz(void)
+{
+ pUFromSz = (void*)GetProcAddress(hMapi32, "UFromSz@4");
+ if (!pUFromSz)
+ return;
+
+ ok(pUFromSz("105679") == 105679u,
+ "UFromSz: expected 105679, got %d\n", pUFromSz("105679"));
+
+ ok(pUFromSz(" 4") == 0, "UFromSz: exected 0. got %d\n",
+ pUFromSz(" 4"));
+}
+
+static void test_UlFromSzHex(void)
+{
+ pUlFromSzHex = (void*)GetProcAddress(hMapi32, "UlFromSzHex@4");
+ if (!pUlFromSzHex)
+ return;
+
+ ok(pUlFromSzHex("fF") == 0xffu,
+ "UlFromSzHex: expected 0xff, got 0x%lx\n", pUlFromSzHex("fF"));
+
+ ok(pUlFromSzHex(" c") == 0, "UlFromSzHex: exected 0x0. got 0x%lx\n",
+ pUlFromSzHex(" c"));
+}
+
+static void test_CbOfEncoded(void)
+{
+ char buff[129];
+ size_t i;
+
+ pCbOfEncoded = (void*)GetProcAddress(hMapi32, "CbOfEncoded@4");
+ if (!pCbOfEncoded)
+ return;
+
+ for (i = 0; i < sizeof(buff) - 1; i++)
+ {
+ ULONG ulRet, ulExpected = (((i | 3) >> 2) + 1) * 3;
+
+ memset(buff, '\0', sizeof(buff));
+ memset(buff, '?', i);
+ ulRet = pCbOfEncoded(buff);
+ ok(ulRet == ulExpected, "CbOfEncoded(length %d): expected %ld, got %ld\n",
+ i, ulExpected, ulRet);
+ }
+}
+
+static void test_IsBadBoundedStringPtr(void)
+{
+ pIsBadBoundedStringPtr = (void*)GetProcAddress(hMapi32, "IsBadBoundedStringPtr@8");
+ if (!pIsBadBoundedStringPtr)
+ return;
+
+ ok(pIsBadBoundedStringPtr(NULL, 0) == TRUE, "IsBadBoundedStringPtr: expected TRUE\n");
+ ok(pIsBadBoundedStringPtr("TEST", 4) == TRUE, "IsBadBoundedStringPtr: expected TRUE\n");
+ ok(pIsBadBoundedStringPtr("TEST", 5) == FALSE, "IsBadBoundedStringPtr: expected FALSE\n");
+}
START_TEST(util)
{
@@ -120,4 +181,8 @@
test_SwapPword();
test_SwapPlong();
test_HexFromBin();
+ test_UFromSz();
+ test_UlFromSzHex();
+ test_CbOfEncoded();
+ test_IsBadBoundedStringPtr();
}
diff --git a/dlls/mapi32/util.c b/dlls/mapi32/util.c
index 72da46f..ee158d4 100644
--- a/dlls/mapi32/util.c
+++ b/dlls/mapi32/util.c
@@ -23,10 +23,10 @@
#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"
@@ -38,6 +38,12 @@
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)
*
@@ -203,6 +209,15 @@
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)
*
@@ -251,11 +266,6 @@
*/
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);
@@ -458,6 +468,26 @@
}
/**************************************************************************
+ * 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)
*
* Add two FILETIME's together.
@@ -545,7 +575,7 @@
LONGLONG WINAPI MAPI32_FtNegFt(FILETIME ft)
{
LONGLONG *p = (LONGLONG*)&ft;
-
+
return - *p;
}
@@ -597,6 +627,39 @@
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 = CharNextA(lpszStr);
+ }
+ }
+ return ulRet;
+}
+
/*************************************************************************
* OpenStreamOnFile@24 (MAPI32.147)
*
@@ -649,6 +712,62 @@
return hRet;
}
+/*************************************************************************
+ * UlFromSzHex@4 (MAPI32.155)
+ *
+ * Read an integer from a hexadecimal string.
+ *
+ * PARAMS
+ * lpSzHex [I] String containing the hexidecimal 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)
+{
+ LPSTR lpStr = (LPSTR)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;
+}
+
+/*************************************************************************
+ * 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)