Import mapi32 from Wine
authorGé van Geldorp <ge@gse.nl>
Sat, 14 Jan 2006 19:36:04 +0000 (19:36 +0000)
committerGé van Geldorp <ge@gse.nl>
Sat, 14 Jan 2006 19:36:04 +0000 (19:36 +0000)
svn path=/trunk/; revision=20861

21 files changed:
reactos/baseaddress.xml
reactos/bootdata/packages/reactos.dff
reactos/include/wine/shlwapi.h
reactos/lib/directory.xml
reactos/lib/mapi32/imalloc.c [new file with mode: 0644]
reactos/lib/mapi32/mapi32.spec [new file with mode: 0644]
reactos/lib/mapi32/mapi32.xml [new file with mode: 0644]
reactos/lib/mapi32/mapi32_main.c [new file with mode: 0644]
reactos/lib/mapi32/prop.c [new file with mode: 0644]
reactos/lib/mapi32/util.c [new file with mode: 0644]
reactos/lib/uuid/uuid.c
reactos/media/doc/README.WINE
reactos/w32api/include/mapicode.h [new file with mode: 0644]
reactos/w32api/include/mapidefs.h [new file with mode: 0644]
reactos/w32api/include/mapiguid.h [new file with mode: 0644]
reactos/w32api/include/mapitags.h [new file with mode: 0644]
reactos/w32api/include/mapiutil.h [new file with mode: 0644]
reactos/w32api/include/mapival.h [new file with mode: 0644]
reactos/w32api/include/mapix.h [new file with mode: 0644]
reactos/w32api/include/wtypes.h
reactos/w32api/include/xcmc.h [new file with mode: 0644]

index 8187b79..9eef028 100644 (file)
@@ -10,6 +10,7 @@
 <property name="BASEADDRESS_OBJSEL" value="0x5B400000" />
 <property name="BASEADDRESS_SLAYER" value="0x5C7E0000" />
 <property name="BASEADDRESS_DINPUT" value="0x5F580000" />
+<property name="BASEADDRESS_MAPI32" value="0x62250000" />
 <property name="BASEADDRESS_HDWWIZ" value="0x64D40000" />
 <property name="BASEADDRESS_TIMEDATE" value="0x64DA0000" />
 <property name="BASEADDRESS_SYSDM" value="0x64DD0000" />
index 50e57c8..0d5aeae 100755 (executable)
@@ -120,6 +120,7 @@ lib\keyboard\kbdus\kbdus.dll            1
 lib\kernel32\kernel32.dll               1
 lib\lsasrv\lsasrv.dll                   1
 lib\lzexpand\lz32.dll                   1
+lib\mapi32\mapi32.dll                   1
 lib\mesa32\mesa32.dll                   1
 lib\winmm\midimap\midimap.dll           1
 lib\mmdrv\mmdrv.dll                     1
index ff155b8..ea570ba 100644 (file)
@@ -14,6 +14,8 @@
 
 #define URL_FILE_USE_PATHURL 0x00010000
 
+HRESULT WINAPI SHCreateStreamOnFileEx(LPCWSTR,DWORD,DWORD,BOOL,struct IStream*,struct IStream**);
+
 #define INTERFACE IQueryAssociations
 DECLARE_INTERFACE_(IQueryAssociations,IUnknown)
 {
index f266065..e478ebf 100644 (file)
 <directory name="lzexpand">
        <xi:include href="lzexpand/lz32.xml" />
 </directory>
+<directory name="mapi32">
+       <xi:include href="mapi32/mapi32.xml" />
+</directory>
 <directory name="mesa32">
        <xi:include href="mesa32/mesa32.xml" />
 </directory>
diff --git a/reactos/lib/mapi32/imalloc.c b/reactos/lib/mapi32/imalloc.c
new file mode 100644 (file)
index 0000000..1ea9442
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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 "mapiutil.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(LMEM_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(LMEM_FIXED, cb);
+
+    if (cb)
+        return LocalReAlloc((HANDLE) pv, cb, LMEM_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/reactos/lib/mapi32/mapi32.spec b/reactos/lib/mapi32/mapi32.spec
new file mode 100644 (file)
index 0000000..c94bc12
--- /dev/null
@@ -0,0 +1,191 @@
+  8 stub @
+ 10 stdcall MAPILogonEx(long ptr ptr long ptr)
+ 11 stdcall MAPILogonEx@20(long ptr ptr long ptr) MAPILogonEx
+ 12 stdcall MAPIAllocateBuffer(long ptr)
+ 13 stdcall MAPIAllocateBuffer@8(long ptr) MAPIAllocateBuffer
+ 14 stdcall MAPIAllocateMore(long ptr ptr)
+ 15 stdcall MAPIAllocateMore@12(long ptr ptr) MAPIAllocateMore
+ 16 stdcall MAPIFreeBuffer(ptr)
+ 17 stdcall MAPIFreeBuffer@4(ptr) MAPIFreeBuffer
+ 18 stub MAPIAdminProfiles
+ 19 stub MAPIAdminProfiles@8
+ 20 stdcall MAPIInitialize(ptr)
+ 21 stdcall MAPIInitialize@4(ptr) MAPIInitialize
+ 22 stdcall MAPIUninitialize()
+ 23 stdcall MAPIUninitialize@0() MAPIUninitialize
+ 24 stub PRProviderInit
+ 25 stub LAUNCHWIZARD
+ 26 stub LaunchWizard@20
+ 27 stub DllGetClassObject
+ 28 stdcall -private DllCanUnloadNow()
+ 29 stub MAPIOpenFormMgr
+ 30 stub MAPIOpenFormMgr@8
+ 31 stub MAPIOpenLocalFormContainer
+ 32 stub MAPIOpenLocalFormContainer@4
+ 33 stdcall ScInitMapiUtil@4(long) ScInitMapiUtil
+ 34 stdcall DeinitMapiUtil@0() DeinitMapiUtil
+ 35 stub ScGenerateMuid@4
+ 36 stub HrAllocAdviseSink@12
+ 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
+ 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
+ 49 stub MAPIInitIdle@4
+ 50 stub MAPIDeinitIdle@0
+ 51 stub InstallFilterHook@4
+ 52 stub FtgRegisterIdleRoutine@20
+ 53 stub EnableIdleRoutine@8
+ 54 stub DeregisterIdleRoutine@4
+ 55 stub ChangeIdleRoutine@28
+ 59 stdcall MAPIGetDefaultMalloc@0() MAPIGetDefaultMalloc
+ 60 stdcall CreateIProp@24(ptr ptr ptr ptr ptr ptr) CreateIProp
+ 61 stub CreateTable@36
+ 62 stdcall MNLS_lstrlenW@4(wstr) MNLS_lstrlenW
+ 63 stdcall MNLS_lstrcmpW@8(wstr wstr) MNLS_lstrcmpW
+ 64 stdcall MNLS_lstrcpyW@8(ptr wstr) MNLS_lstrcpyW
+ 65 stdcall MNLS_CompareStringW@24(long wstr wstr) MNLS_CompareStringW
+ 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 stdcall FEqualNames@8(ptr ptr) FEqualNames
+ 73 stub WrapStoreEntryID@24
+ 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
+ 78 stdcall FPropContainsProp@12(ptr ptr long) FPropContainsProp
+ 79 stdcall FPropCompareProp@12(ptr long ptr) FPropCompareProp
+ 80 stdcall LPropCompareProp@8(ptr ptr) LPropCompareProp
+ 81 stub HrAddColumns@16
+ 82 stub HrAddColumnsEx@20
+121 stdcall -ret64 FtAddFt@16(double double) MAPI32_FtAddFt
+122 stub FtAdcFt@20
+123 stdcall -ret64 FtSubFt@16(double double) MAPI32_FtSubFt
+124 stdcall -ret64 FtMulDw@12(long double) MAPI32_FtMulDw
+125 stdcall -ret64 FtMulDwDw@8(long long) MAPI32_FtMulDwDw
+126 stdcall -ret64 FtNegFt@8(double) MAPI32_FtNegFt
+127 stub FtDivFtBogus@20
+128 stdcall UlAddRef@4(ptr) UlAddRef
+129 stdcall UlRelease@4(ptr) UlRelease
+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 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
+138 stdcall PpropFindProp@12(ptr long long) PpropFindProp
+139 stdcall FreePadrlist@4(ptr) FreePadrlist
+140 stdcall FreeProws@4(ptr) FreeProws
+141 stub HrSzFromEntryID@12
+142 stub HrEntryIDFromSz@12
+143 stub HrComposeEID@28
+144 stub HrDecomposeEID@28
+145 stub HrComposeMsgID@24
+146 stub HrDecomposeMsgID@24
+147 stdcall OpenStreamOnFile@24(ptr ptr ptr ptr ptr ptr) OpenStreamOnFile
+148 stdcall OpenStreamOnFile(ptr ptr ptr ptr ptr ptr)
+149 stub OpenTnefStream@28
+150 stub OpenTnefStream
+151 stub OpenTnefStreamEx@32
+152 stub OpenTnefStreamEx
+153 stub GetTnefStreamCodepage@12
+154 stub GetTnefStreamCodepage
+155 stdcall UlFromSzHex@4(ptr) UlFromSzHex
+156 stub UNKOBJ_ScAllocate@12
+157 stub UNKOBJ_ScAllocateMore@16
+158 stub UNKOBJ_Free@8
+159 stub UNKOBJ_FreeRows@8
+160 stub UNKOBJ_ScCOAllocate@12
+161 stub UNKOBJ_ScCOReallocate@12
+162 stub UNKOBJ_COFree@8
+163 stub UNKOBJ_ScSzFromIdsAlloc@20
+164 stub ScCountNotifications@12
+165 stub ScCopyNotifications@16
+166 stub ScRelocNotifications@20
+170 stdcall ScCountProps@12(long ptr ptr) ScCountProps
+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 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
+178 stub FBadRglpNameID@8
+179 stdcall FBadPropTag@4(long) FBadPropTag
+180 stdcall FBadRow@4(ptr) FBadRow
+181 stdcall FBadProp@4(ptr) FBadProp
+182 stdcall FBadColumnSet@4(ptr) FBadColumnSet
+183 stub RTFSync@12
+184 stub RTFSync
+185 stub WrapCompressedRTFStream@12
+186 stub WrapCompressedRTFStream
+187 stub __ValidateParameters@8
+188 stub __CPPValidateParameters@8
+189 stub FBadSortOrderSet@4
+190 stdcall FBadEntryList@4(ptr) FBadEntryList
+191 stub FBadRestriction@4
+192 stub ScUNCFromLocalPath@12
+193 stub ScLocalPathFromUNC@12
+194 stub HrIStorageFromStream@16
+195 stub HrValidateIPMSubtree@20
+196 stub OpenIMsgSession@12
+197 stub CloseIMsgSession@4
+198 stub OpenIMsgOnIStg@44
+199 stub SetAttribIMsgOnIStg@16
+200 stub GetAttribIMsgOnIStg@12
+201 stub MapStorageSCode@4
+202 stub ScMAPIXFromCMC
+203 stub ScMAPIXFromSMAPI
+204 stub EncodeID@12
+205 stub FDecodeID@12
+206 stub CchOfEncoding@4
+207 stdcall CbOfEncoded@4(ptr) CbOfEncoded
+208 stub MAPISendDocuments
+209 stdcall MAPILogon(long ptr ptr long long ptr)
+210 stub MAPILogoff
+211 stub MAPISendMail
+212 stub MAPISaveMail
+213 stub MAPIReadMail
+214 stub MAPIFindNext
+215 stub MAPIDeleteMail
+217 stub MAPIAddress
+218 stub MAPIDetails
+219 stub MAPIResolveName
+220 stub BMAPISendMail
+221 stub BMAPISaveMail
+222 stub BMAPIReadMail
+223 stub BMAPIGetReadMail
+224 stub BMAPIFindNext
+225 stub BMAPIAddress
+226 stub BMAPIGetAddress
+227 stub BMAPIDetails
+228 stub BMAPIResolveName
+229 stub cmc_act_on
+230 stub cmc_free
+231 stub cmc_list
+232 stub cmc_logoff
+233 stub cmc_logon
+234 stub cmc_look_up
+235 stdcall cmc_query_configuration( long long ptr ptr )
+236 stub cmc_read
+237 stub cmc_send
+238 stub cmc_send_documents
+239 stub HrDispatchNotifications@4
+241 stub HrValidateParameters@8
+244 stub ScCreateConversationIndex@16
+246 stub HrGetOmiProvidersFlags
+247 stub HrGetOmiProvidersFlags@8
+248 stub HrSetOmiProvidersFlagsInvalid
+249 stub HrSetOmiProvidersFlagsInvalid@4
+250 stub GetOutlookVersion
+251 stub GetOutlookVersion@0
+252 stub FixMAPI
+253 stub FixMAPI@0
+# This entry point is sometimes used to detect if the mapi dll came from Outlook
+#254 stub FGetComponentPath
+#255 stub FGetComponentPath@20
diff --git a/reactos/lib/mapi32/mapi32.xml b/reactos/lib/mapi32/mapi32.xml
new file mode 100644 (file)
index 0000000..7db672d
--- /dev/null
@@ -0,0 +1,19 @@
+<module name="mapi32" type="win32dll" baseaddress="${BASEADDRESS_MAPI32}" installbase="system32" installname="mapi32.dll">
+       <importlibrary definition="mapi32.spec.def" />
+       <include base="mapi32">.</include>
+       <include base="ReactOS">include/wine</include>
+       <define name="__USE_W32API" />
+       <define name="_WIN32_WINNT">0x501</define>
+       <define name="__WINESRC__" />
+       <library>ntdll</library>
+       <library>kernel32</library>
+       <library>shlwapi</library>
+       <library>wine</library>
+       <library>uuid</library>
+       <library>advapi32</library>
+       <file>mapi32_main.c</file>
+       <file>imalloc.c</file>
+       <file>prop.c</file>
+       <file>util.c</file>
+       <file>mapi32.spec</file>
+</module>
diff --git a/reactos/lib/mapi32/mapi32_main.c b/reactos/lib/mapi32/mapi32_main.c
new file mode 100644 (file)
index 0000000..5fadb5a
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *             MAPI basics
+ *
+ * Copyright 2001 CodeWeavers Inc.
+ *
+ * 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>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "objbase.h"
+#include "mapix.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mapi);
+
+LONG MAPI_ObjectCount = 0;
+
+/***********************************************************************
+ *              DllMain (MAPI32.init)
+ */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
+{
+    TRACE("(%p,%ld,%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 DllCanUnloadNow(void)
+{
+    return MAPI_ObjectCount == 0 ? S_OK : S_FALSE;
+}
+
+HRESULT WINAPI MAPIInitialize ( LPVOID lpMapiInit )
+{
+    ERR("Stub\n");
+    return MAPI_E_NOT_INITIALIZED;
+}
+
+ULONG WINAPI MAPILogon(ULONG ulUIParam, LPSTR lpszProfileName, LPSTR
+lpszPassword, FLAGS flFlags, ULONG ulReserver, LPLHANDLE lplhSession)
+{
+    ERR("Stub\n");
+    return MAPI_E_LOGON_FAILED;
+}
+
+HRESULT WINAPI MAPILogonEx(ULONG_PTR ulUIParam, LPWSTR lpszProfileName,
+                           LPWSTR lpszPassword, ULONG flFlags,
+                           LPMAPISESSION *lppSession)
+{
+    ERR("Stub\n");
+    return MAPI_E_LOGON_FAILED;
+}
+
+VOID WINAPI MAPIUninitialize(void)
+{
+    ERR("Stub\n");
+}
diff --git a/reactos/lib/mapi32/prop.c b/reactos/lib/mapi32/prop.c
new file mode 100644 (file)
index 0000000..2477b21
--- /dev/null
@@ -0,0 +1,2549 @@
+/*
+ * Property 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
+ */
+
+#include <stdarg.h>
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winerror.h"
+#include "winternl.h"
+#include "objbase.h"
+#include "shlwapi.h"
+#include "wine/list.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "mapival.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mapi);
+
+BOOL WINAPI FBadRglpszA(LPSTR*,ULONG);
+
+/* Internal: Check if a property value array is invalid */
+static inline ULONG PROP_BadArray(LPSPropValue lpProp, size_t elemSize)
+{
+    return IsBadReadPtr(lpProp->Value.MVi.lpi, lpProp->Value.MVi.cValues * elemSize);
+}
+
+/*************************************************************************
+ * PropCopyMore@16 (MAPI32.76)
+ *
+ * Copy a property value.
+ *
+ * PARAMS
+ *  lpDest [O] Destination for the copied value
+ *  lpSrc  [I] Property value to copy to lpDest
+ *  lpMore [I] Linked memory allocation function (pass MAPIAllocateMore())
+ *  lpOrig [I] Original allocation to which memory will be linked
+ *
+ * RETURNS
+ *  Success: S_OK. lpDest contains a deep copy of lpSrc.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid,
+ *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
+ *
+ * NOTES
+ *  Any elements within the property returned should not be individually
+ *  freed, as they will be freed when lpOrig is.
+ */
+SCODE WINAPI PropCopyMore(LPSPropValue lpDest, LPSPropValue lpSrc,
+                          ALLOCATEMORE *lpMore, LPVOID lpOrig)
+{
+    ULONG ulLen, i;
+    SCODE scode = S_OK;
+
+    TRACE("(%p,%p,%p,%p)\n", lpDest, lpSrc, lpMore, lpOrig);
+
+    if (!lpDest || IsBadWritePtr(lpDest, sizeof(SPropValue)) ||
+        FBadProp(lpSrc) || !lpMore)
+        return MAPI_E_INVALID_PARAMETER;
+
+    /* Shallow copy first, this is sufficient for properties without pointers */
+    *lpDest = *lpSrc;
+
+   switch (PROP_TYPE(lpSrc->ulPropTag))
+    {
+    case PT_CLSID:
+        scode = lpMore(sizeof(GUID), lpOrig, (LPVOID*)&lpDest->Value.lpguid);
+        if (SUCCEEDED(scode))
+            memcpy(lpDest->Value.lpguid, lpSrc->Value.lpguid, sizeof(GUID));
+        break;
+    case PT_STRING8:
+        ulLen = lstrlenA(lpSrc->Value.lpszA) + 1u;
+        scode = lpMore(ulLen, lpOrig, (LPVOID*)&lpDest->Value.lpszA);
+        if (SUCCEEDED(scode))
+            memcpy(lpDest->Value.lpszA, lpSrc->Value.lpszA, ulLen);
+        break;
+    case PT_UNICODE:
+        ulLen = (strlenW(lpSrc->Value.lpszW) + 1u) * sizeof(WCHAR);
+        scode = lpMore(ulLen, lpOrig, (LPVOID*)&lpDest->Value.lpszW);
+        if (SUCCEEDED(scode))
+            memcpy(lpDest->Value.lpszW, lpSrc->Value.lpszW, ulLen);
+        break;
+    case PT_BINARY:
+        scode = lpMore(lpSrc->Value.bin.cb, lpOrig, (LPVOID*)&lpDest->Value.bin.lpb);
+        if (SUCCEEDED(scode))
+            memcpy(lpDest->Value.bin.lpb, lpSrc->Value.bin.lpb, lpSrc->Value.bin.cb);
+        break;
+    default:
+        if (lpSrc->ulPropTag & MV_FLAG)
+        {
+            ulLen = UlPropSize(lpSrc);
+
+            if (PROP_TYPE(lpSrc->ulPropTag) == PT_MV_STRING8 ||
+                PROP_TYPE(lpSrc->ulPropTag) == PT_MV_UNICODE)
+            {
+                /* UlPropSize doesn't account for the string pointers */
+                ulLen += lpSrc->Value.MVszA.cValues * sizeof(char*);
+            }
+            else if (PROP_TYPE(lpSrc->ulPropTag) == PT_MV_BINARY)
+            {
+               /* UlPropSize doesn't account for the SBinary structs */
+               ulLen += lpSrc->Value.MVbin.cValues * sizeof(SBinary);
+            }
+
+            lpDest->Value.MVi.cValues = lpSrc->Value.MVi.cValues;
+            scode = lpMore(ulLen, lpOrig, (LPVOID*)&lpDest->Value.MVi.lpi);
+            if (FAILED(scode))
+                break;
+
+            /* Note that we could allocate the memory for each value in a
+             * multi-value property seperately, however if an allocation failed
+             * we would be left with a bunch of allocated memory, which (while
+             * not really leaked) is unusable until lpOrig is freed. So for
+             * strings and binary arrays we make a single allocation for all
+             * of the data. This is consistent since individual elements can't
+             * be freed anyway.
+             */
+
+            switch (PROP_TYPE(lpSrc->ulPropTag))
+            {
+            case PT_MV_STRING8:
+            {
+                char *lpNextStr = (char*)(lpDest->Value.MVszA.lppszA +
+                                          lpDest->Value.MVszA.cValues);
+
+                for (i = 0; i < lpSrc->Value.MVszA.cValues; i++)
+                {
+                    ULONG ulStrLen = lstrlenA(lpSrc->Value.MVszA.lppszA[i]) + 1u;
+
+                    lpDest->Value.MVszA.lppszA[i] = lpNextStr;
+                    memcpy(lpNextStr, lpSrc->Value.MVszA.lppszA[i], ulStrLen);
+                    lpNextStr += ulStrLen;
+                }
+                break;
+            }
+            case PT_MV_UNICODE:
+            {
+                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;
+
+                    lpDest->Value.MVszW.lppszW[i] = lpNextStr;
+                    memcpy(lpNextStr, lpSrc->Value.MVszW.lppszW[i], ulStrLen * sizeof(WCHAR));
+                    lpNextStr += ulStrLen;
+                }
+                break;
+            }
+            case PT_MV_BINARY:
+            {
+                LPBYTE lpNext = (LPBYTE)(lpDest->Value.MVbin.lpbin +
+                                         lpDest->Value.MVbin.cValues);
+
+                for (i = 0; i < lpSrc->Value.MVszW.cValues; i++)
+                {
+                    lpDest->Value.MVbin.lpbin[i].cb = lpSrc->Value.MVbin.lpbin[i].cb;
+                    lpDest->Value.MVbin.lpbin[i].lpb = lpNext;
+                    memcpy(lpNext, lpSrc->Value.MVbin.lpbin[i].lpb, lpDest->Value.MVbin.lpbin[i].cb);
+                    lpNext += lpDest->Value.MVbin.lpbin[i].cb;
+                }
+                break;
+            }
+            default:
+                /* No embedded pointers, just copy the data over */
+                memcpy(lpDest->Value.MVi.lpi, lpSrc->Value.MVi.lpi, ulLen);
+                break;
+            }
+            break;
+        }
+    }
+    return scode;
+}
+
+/*************************************************************************
+ * UlPropSize@4 (MAPI32.77)
+ *
+ * Determine the size of a property in bytes.
+ *
+ * PARAMS
+ *  lpProp [I] Property to determine the size of
+ *
+ * RETURNS
+ *  Success: The size of the value in lpProp.
+ *  Failure: 0, if a multi-value (array) property is invalid or the type of lpProp
+ *           is unknown.
+ *
+ * NOTES
+ *  - The size returned does not include the size of the SPropValue struct
+ *    or the size of the array of pointers for multi-valued properties that
+ *    contain pointers (such as PT_MV_STRING8 or PT-MV_UNICODE).
+ *  - MSDN incorrectly states that this function returns MAPI_E_CALL_FAILED if
+ *    lpProp is invalid. In reality no checking is performed and this function
+ *    will crash if passed an invalid property, or return 0 if the property
+ *    type is PT_OBJECT or is unknown.
+ */
+ULONG WINAPI UlPropSize(LPSPropValue lpProp)
+{
+    ULONG ulRet = 1u, i;
+
+    TRACE("(%p)\n", lpProp);
+
+    switch (PROP_TYPE(lpProp->ulPropTag))
+    {
+    case PT_MV_I2:       ulRet = lpProp->Value.MVi.cValues;
+    case PT_BOOLEAN:
+    case PT_I2:          ulRet *= sizeof(USHORT);
+                         break;
+    case PT_MV_I4:       ulRet = lpProp->Value.MVl.cValues;
+    case PT_ERROR:
+    case PT_I4:          ulRet *= sizeof(LONG);
+                         break;
+    case PT_MV_I8:       ulRet = lpProp->Value.MVli.cValues;
+    case PT_I8:          ulRet *= sizeof(LONG64);
+                         break;
+    case PT_MV_R4:       ulRet = lpProp->Value.MVflt.cValues;
+    case PT_R4:          ulRet *= sizeof(float);
+                         break;
+    case PT_MV_APPTIME:
+    case PT_MV_R8:       ulRet = lpProp->Value.MVdbl.cValues;
+    case PT_APPTIME:
+    case PT_R8:          ulRet *= sizeof(double);
+                         break;
+    case PT_MV_CURRENCY: ulRet = lpProp->Value.MVcur.cValues;
+    case PT_CURRENCY:    ulRet *= sizeof(CY);
+                         break;
+    case PT_MV_SYSTIME:  ulRet = lpProp->Value.MVft.cValues;
+    case PT_SYSTIME:     ulRet *= sizeof(FILETIME);
+                         break;
+    case PT_MV_CLSID:    ulRet = lpProp->Value.MVguid.cValues;
+    case PT_CLSID:       ulRet *= sizeof(GUID);
+                         break;
+    case PT_MV_STRING8:  ulRet = 0u;
+                         for (i = 0; i < lpProp->Value.MVszA.cValues; i++)
+                             ulRet += (lstrlenA(lpProp->Value.MVszA.lppszA[i]) + 1u);
+                         break;
+    case PT_STRING8:     ulRet = lstrlenA(lpProp->Value.lpszA) + 1u;
+                         break;
+    case PT_MV_UNICODE:  ulRet = 0u;
+                         for (i = 0; i < lpProp->Value.MVszW.cValues; i++)
+                             ulRet += (strlenW(lpProp->Value.MVszW.lppszW[i]) + 1u);
+                         ulRet *= sizeof(WCHAR);
+                         break;
+    case PT_UNICODE:     ulRet = (lstrlenW(lpProp->Value.lpszW) + 1u) * sizeof(WCHAR);
+                         break;
+    case PT_MV_BINARY:   ulRet = 0u;
+                         for (i = 0; i < lpProp->Value.MVbin.cValues; i++)
+                             ulRet += lpProp->Value.MVbin.lpbin[i].cb;
+                         break;
+    case PT_BINARY:      ulRet = lpProp->Value.bin.cb;
+                         break;
+    case PT_OBJECT:
+    default:             ulRet = 0u;
+                         break;
+    }
+
+    return ulRet;
+}
+
+/*************************************************************************
+ * FPropContainsProp@12 (MAPI32.78)
+ *
+ * Find a property with a given property tag in a property array.
+ *
+ * PARAMS
+ *  lpHaystack [I] Property to match to
+ *  lpNeedle   [I] Property to find in lpHaystack
+ *  ulFuzzy    [I] Flags controlling match type and strictness (FL_* flags from "mapidefs.h")
+ *
+ * RETURNS
+ *  TRUE, if lpNeedle matches lpHaystack according to the criteria of ulFuzzy.
+ *
+ * NOTES
+ *  Only property types of PT_STRING8 and PT_BINARY are handled by this function.
+ */
+BOOL WINAPI FPropContainsProp(LPSPropValue lpHaystack, LPSPropValue lpNeedle, ULONG ulFuzzy)
+{
+    TRACE("(%p,%p,0x%08lx)\n", lpHaystack, lpNeedle, ulFuzzy);
+
+    if (FBadProp(lpHaystack) || FBadProp(lpNeedle) ||
+        PROP_TYPE(lpHaystack->ulPropTag) != PROP_TYPE(lpNeedle->ulPropTag))
+        return FALSE;
+
+    /* FIXME: Do later versions support Unicode as well? */
+
+    if (PROP_TYPE(lpHaystack->ulPropTag) == PT_STRING8)
+    {
+        DWORD dwFlags = 0, dwNeedleLen, dwHaystackLen;
+
+        if (ulFuzzy & FL_IGNORECASE)
+            dwFlags |= NORM_IGNORECASE;
+        if (ulFuzzy & FL_IGNORENONSPACE)
+            dwFlags |= NORM_IGNORENONSPACE;
+        if (ulFuzzy & FL_LOOSE)
+            dwFlags |= (NORM_IGNORECASE|NORM_IGNORENONSPACE|NORM_IGNORESYMBOLS);
+
+        dwNeedleLen = lstrlenA(lpNeedle->Value.lpszA);
+        dwHaystackLen = lstrlenA(lpHaystack->Value.lpszA);
+
+        if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_PREFIX)
+        {
+            if (dwNeedleLen <= dwHaystackLen &&
+                CompareStringA(LOCALE_USER_DEFAULT, dwFlags,
+                               lpHaystack->Value.lpszA, dwNeedleLen,
+                               lpNeedle->Value.lpszA, dwNeedleLen) == CSTR_EQUAL)
+                return TRUE; /* needle is a prefix of haystack */
+        }
+        else if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_SUBSTRING)
+        {
+            LPSTR (WINAPI *pStrChrFn)(LPCSTR,WORD) = StrChrA;
+            LPSTR lpStr = lpHaystack->Value.lpszA;
+
+            if (dwFlags & NORM_IGNORECASE)
+                pStrChrFn = StrChrIA;
+
+            while ((lpStr = pStrChrFn(lpStr, *lpNeedle->Value.lpszA)) != NULL)
+            {
+                dwHaystackLen -= (lpStr - lpHaystack->Value.lpszA);
+                if (dwNeedleLen <= dwHaystackLen &&
+                    CompareStringA(LOCALE_USER_DEFAULT, dwFlags,
+                               lpStr, dwNeedleLen,
+                               lpNeedle->Value.lpszA, dwNeedleLen) == CSTR_EQUAL)
+                    return TRUE; /* needle is a substring of haystack */
+                lpStr++;
+            }
+        }
+        else if (CompareStringA(LOCALE_USER_DEFAULT, dwFlags,
+                                lpHaystack->Value.lpszA, dwHaystackLen,
+                                lpNeedle->Value.lpszA, dwNeedleLen) == CSTR_EQUAL)
+            return TRUE; /* full string match */
+    }
+    else if (PROP_TYPE(lpHaystack->ulPropTag) == PT_BINARY)
+    {
+        if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_PREFIX)
+        {
+            if (lpNeedle->Value.bin.cb <= lpHaystack->Value.bin.cb &&
+                !memcmp(lpNeedle->Value.bin.lpb, lpHaystack->Value.bin.lpb,
+                        lpNeedle->Value.bin.cb))
+                return TRUE; /* needle is a prefix of haystack */
+        }
+        else if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_SUBSTRING)
+        {
+            ULONG ulLen = lpHaystack->Value.bin.cb;
+            LPBYTE lpb = lpHaystack->Value.bin.lpb;
+
+            while ((lpb = memchr(lpb, *lpNeedle->Value.bin.lpb, ulLen)) != NULL)
+            {
+                ulLen = lpHaystack->Value.bin.cb - (lpb - lpHaystack->Value.bin.lpb);
+                if (lpNeedle->Value.bin.cb <= ulLen &&
+                    !memcmp(lpNeedle->Value.bin.lpb, lpb, lpNeedle->Value.bin.cb))
+                    return TRUE; /* needle is a substring of haystack */
+                lpb++;
+            }
+        }
+        else if (!LPropCompareProp(lpHaystack, lpNeedle))
+            return TRUE; /* needle is an exact match with haystack */
+
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ * FPropCompareProp@12 (MAPI32.79)
+ *
+ * Compare two properties.
+ *
+ * PARAMS
+ *  lpPropLeft  [I] Left hand property to compare to lpPropRight
+ *  ulOp        [I] Comparison operator (RELOP_* enum from "mapidefs.h")
+ *  lpPropRight [I] Right hand property to compare to lpPropLeft
+ *
+ * RETURNS
+ *  TRUE, if the comparison is true, FALSE otherwise.
+ */
+BOOL WINAPI FPropCompareProp(LPSPropValue lpPropLeft, ULONG ulOp, LPSPropValue lpPropRight)
+{
+    LONG iCmp;
+
+    TRACE("(%p,%ld,%p)\n", lpPropLeft, ulOp, lpPropRight);
+
+    if (ulOp > RELOP_RE || FBadProp(lpPropLeft) || FBadProp(lpPropRight))
+        return FALSE;
+
+    if (ulOp == RELOP_RE)
+    {
+        FIXME("Comparison operator RELOP_RE not yet implemented!\n");
+        return FALSE;
+    }
+
+    iCmp = LPropCompareProp(lpPropLeft, lpPropRight);
+
+    switch (ulOp)
+    {
+    case RELOP_LT: return iCmp <  0 ? TRUE : FALSE;
+    case RELOP_LE: return iCmp <= 0 ? TRUE : FALSE;
+    case RELOP_GT: return iCmp >  0 ? TRUE : FALSE;
+    case RELOP_GE: return iCmp >= 0 ? TRUE : FALSE;
+    case RELOP_EQ: return iCmp == 0 ? TRUE : FALSE;
+    case RELOP_NE: return iCmp != 0 ? TRUE : FALSE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ * LPropCompareProp@8 (MAPI32.80)
+ *
+ * Compare two properties.
+ *
+ * PARAMS
+ *  lpPropLeft  [I] Left hand property to compare to lpPropRight
+ *  lpPropRight [I] Right hand property to compare to lpPropLeft
+ *
+ * RETURNS
+ *  An integer less than, equal to or greater than 0, indicating that
+ *  lpszStr is less than, the same, or greater than lpszComp.
+ */
+LONG WINAPI LPropCompareProp(LPSPropValue lpPropLeft, LPSPropValue lpPropRight)
+{
+    LONG iRet;
+
+    TRACE("(%p->0x%08lx,%p->0x%08lx)\n", lpPropLeft, lpPropLeft->ulPropTag,
+          lpPropRight, lpPropRight->ulPropTag);
+
+    /* If the properties are not the same, sort by property type */
+    if (PROP_TYPE(lpPropLeft->ulPropTag) != PROP_TYPE(lpPropRight->ulPropTag))
+        return (LONG)PROP_TYPE(lpPropLeft->ulPropTag) - (LONG)PROP_TYPE(lpPropRight->ulPropTag);
+
+    switch (PROP_TYPE(lpPropLeft->ulPropTag))
+    {
+    case PT_UNSPECIFIED:
+    case PT_NULL:
+        return 0; /* NULLs are equal */
+    case PT_I2:
+        return lpPropLeft->Value.i - lpPropRight->Value.i;
+    case PT_I4:
+        return lpPropLeft->Value.l - lpPropRight->Value.l;
+    case PT_I8:
+        if (lpPropLeft->Value.li.QuadPart > lpPropRight->Value.li.QuadPart)
+            return 1;
+        if (lpPropLeft->Value.li.QuadPart == lpPropRight->Value.li.QuadPart)
+            return 0;
+        return -1;
+    case PT_R4:
+        if (lpPropLeft->Value.flt > lpPropRight->Value.flt)
+            return 1;
+        if (lpPropLeft->Value.flt == lpPropRight->Value.flt)
+            return 0;
+        return -1;
+    case PT_APPTIME:
+    case PT_R8:
+        if (lpPropLeft->Value.dbl > lpPropRight->Value.dbl)
+            return 1;
+        if (lpPropLeft->Value.dbl == lpPropRight->Value.dbl)
+            return 0;
+        return -1;
+    case PT_CURRENCY:
+        if (lpPropLeft->Value.cur.int64 > lpPropRight->Value.cur.int64)
+            return 1;
+        if (lpPropLeft->Value.cur.int64 == lpPropRight->Value.cur.int64)
+            return 0;
+        return -1;
+    case PT_SYSTIME:
+        return CompareFileTime(&lpPropLeft->Value.ft, &lpPropRight->Value.ft);
+    case PT_BOOLEAN:
+        return (lpPropLeft->Value.b ? 1 : 0) - (lpPropRight->Value.b ? 1 : 0);
+    case PT_BINARY:
+        if (lpPropLeft->Value.bin.cb == lpPropRight->Value.bin.cb)
+            iRet = memcmp(lpPropLeft->Value.bin.lpb, lpPropRight->Value.bin.lpb,
+                          lpPropLeft->Value.bin.cb);
+        else
+        {
+            iRet = memcmp(lpPropLeft->Value.bin.lpb, lpPropRight->Value.bin.lpb,
+                          min(lpPropLeft->Value.bin.cb, lpPropRight->Value.bin.cb));
+
+            if (!iRet)
+                iRet = lpPropLeft->Value.bin.cb - lpPropRight->Value.bin.cb;
+        }
+        return iRet;
+    case PT_STRING8:
+        return lstrcmpA(lpPropLeft->Value.lpszA, lpPropRight->Value.lpszA);
+    case PT_UNICODE:
+        return strcmpW(lpPropLeft->Value.lpszW, lpPropRight->Value.lpszW);
+    case PT_ERROR:
+        if (lpPropLeft->Value.err > lpPropRight->Value.err)
+            return 1;
+        if (lpPropLeft->Value.err == lpPropRight->Value.err)
+            return 0;
+        return -1;
+    case PT_CLSID:
+        return memcmp(lpPropLeft->Value.lpguid, lpPropRight->Value.lpguid,
+                      sizeof(GUID));
+    }
+    FIXME("Unhandled property type %ld", PROP_TYPE(lpPropLeft->ulPropTag));
+    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)
+ *
+ * Find a property with a given property tag in a property array.
+ *
+ * PARAMS
+ *  lpProps   [I] Property array to search
+ *  cValues   [I] Number of properties in lpProps
+ *  ulPropTag [I] Property tag to find
+ *
+ * RETURNS
+ *  A pointer to the matching property, or NULL if none was found.
+ *
+ * NOTES
+ *  if ulPropTag has a property type of PT_UNSPECIFIED, then only the property
+ *  Ids need to match for a successful match to occur.
+ */
+LPSPropValue WINAPI PpropFindProp(LPSPropValue lpProps, ULONG cValues, ULONG ulPropTag)
+{
+    TRACE("(%p,%ld,%ld)\n", lpProps, cValues, ulPropTag);
+
+    if (lpProps && cValues)
+    {
+        ULONG i;
+        for (i = 0; i < cValues; i++)
+        {
+            if (!FBadPropTag(lpProps[i].ulPropTag) &&
+                (lpProps[i].ulPropTag == ulPropTag ||
+                 (PROP_TYPE(ulPropTag) == PT_UNSPECIFIED &&
+                  PROP_ID(lpProps[i].ulPropTag) == PROP_ID(ulPropTag))))
+                return &lpProps[i];
+        }
+    }
+    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)
+ *
+ * Validate and determine the length of an array of properties.
+ *
+ * PARAMS
+ *  iCount  [I] Length of the lpProps array
+ *  lpProps [I] Array of properties to validate/size
+ *  pcBytes [O] If non-NULL, destination for the size of the property array
+ *
+ * RETURNS
+ *  Success: S_OK. If pcBytes is non-NULL, it contains the size of the propery array.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid or validation
+ *           of the property array fails.
+ */
+SCODE WINAPI ScCountProps(INT iCount, LPSPropValue lpProps, ULONG *pcBytes)
+{
+    ULONG i, ulCount = iCount, ulBytes = 0;
+
+    TRACE("(%d,%p,%p)\n", iCount, lpProps, pcBytes);
+
+    if (iCount <= 0 || !lpProps ||
+        IsBadReadPtr(lpProps, iCount * sizeof(SPropValue)))
+        return MAPI_E_INVALID_PARAMETER;
+
+    for (i = 0; i < ulCount; i++)
+    {
+        ULONG ulPropSize = 0;
+
+        if (FBadProp(&lpProps[i]) || lpProps[i].ulPropTag == PROP_ID_NULL ||
+            lpProps[i].ulPropTag == PROP_ID_INVALID)
+            return MAPI_E_INVALID_PARAMETER;
+
+            if (PROP_TYPE(lpProps[i].ulPropTag) != PT_OBJECT)
+            {
+                ulPropSize = UlPropSize(&lpProps[i]);
+                if (!ulPropSize)
+                    return MAPI_E_INVALID_PARAMETER;
+            }
+
+            switch (PROP_TYPE(lpProps[i].ulPropTag))
+            {
+            case PT_STRING8:
+            case PT_UNICODE:
+            case PT_CLSID:
+            case PT_BINARY:
+            case PT_MV_I2:
+            case PT_MV_I4:
+            case PT_MV_I8:
+            case PT_MV_R4:
+            case PT_MV_R8:
+            case PT_MV_CURRENCY:
+            case PT_MV_SYSTIME:
+            case PT_MV_APPTIME:
+                ulPropSize += sizeof(SPropValue);
+                break;
+            case PT_MV_CLSID:
+                ulPropSize += lpProps[i].Value.MVszA.cValues * sizeof(char*) + sizeof(SPropValue);
+                break;
+            case PT_MV_STRING8:
+            case PT_MV_UNICODE:
+                ulPropSize += lpProps[i].Value.MVszA.cValues * sizeof(char*) + sizeof(SPropValue);
+                break;
+            case PT_MV_BINARY:
+                ulPropSize += lpProps[i].Value.MVbin.cValues * sizeof(SBinary) + sizeof(SPropValue);
+                break;
+            default:
+                ulPropSize = sizeof(SPropValue);
+                break;
+            }
+            ulBytes += ulPropSize;
+    }
+    if (pcBytes)
+        *pcBytes = ulBytes;
+
+    return S_OK;
+}
+
+/*************************************************************************
+ * ScCopyProps@16 (MAPI32.171)
+ *
+ * Copy an array of property values into a buffer suited for serialisation.
+ *
+ * PARAMS
+ *  cValues   [I] Number of properties in lpProps
+ *  lpProps   [I] Property array to copy
+ *  lpDst     [O] Destination for the serialised data
+ *  lpCount   [O] If non-NULL, destination for the number of bytes of data written to lpDst
+ *
+ * RETURNS
+ *  Success: S_OK. lpDst contains the serialised data from lpProps.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
+ *
+ * NOTES
+ *  The resulting property value array is stored in a contiguous block starting at lpDst.
+ */
+SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG *lpCount)
+{
+    LPSPropValue lpDest = (LPSPropValue)lpDst;
+    char *lpDataDest = (char *)(lpDest + cValues);
+    ULONG ulLen, i;
+    int 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 (iter = 0; iter < cValues; iter++)
+    {
+        switch (PROP_TYPE(lpProps->ulPropTag))
+        {
+        case PT_CLSID:
+            lpDest->Value.lpguid = (LPGUID)lpDataDest;
+            memcpy(lpDest->Value.lpguid, lpProps->Value.lpguid, sizeof(GUID));
+            lpDataDest += sizeof(GUID);
+            break;
+        case PT_STRING8:
+            ulLen = lstrlenA(lpProps->Value.lpszA) + 1u;
+            lpDest->Value.lpszA = lpDataDest;
+            memcpy(lpDest->Value.lpszA, lpProps->Value.lpszA, ulLen);
+            lpDataDest += ulLen;
+            break;
+        case PT_UNICODE:
+            ulLen = (strlenW(lpProps->Value.lpszW) + 1u) * sizeof(WCHAR);
+            lpDest->Value.lpszW = (LPWSTR)lpDataDest;
+            memcpy(lpDest->Value.lpszW, lpProps->Value.lpszW, ulLen);
+            lpDataDest += ulLen;
+            break;
+        case PT_BINARY:
+            lpDest->Value.bin.lpb = (LPBYTE)lpDataDest;
+            memcpy(lpDest->Value.bin.lpb, lpProps->Value.bin.lpb, lpProps->Value.bin.cb);
+            lpDataDest += lpProps->Value.bin.cb;
+            break;
+        default:
+            if (lpProps->ulPropTag & MV_FLAG)
+            {
+                lpDest->Value.MVi.cValues = lpProps->Value.MVi.cValues;
+                /* Note: Assignment uses lppszA but covers all cases by union aliasing */
+                lpDest->Value.MVszA.lppszA = (char**)lpDataDest;
+
+                switch (PROP_TYPE(lpProps->ulPropTag))
+                {
+                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;
+                    }
+                    break;
+                }
+                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:
+                    /* No embedded pointers, just copy the data over */
+                    ulLen = UlPropSize(lpProps);
+                    memcpy(lpDest->Value.MVi.lpi, lpProps->Value.MVi.lpi, ulLen);
+                    lpDataDest += ulLen;
+                    break;
+                }
+                break;
+            }
+        }
+        lpDest++;
+        lpProps++;
+    }
+    if (lpCount)
+        *lpCount = lpDataDest - (char *)lpDst;
+
+    return S_OK;
+}
+
+/*************************************************************************
+ * ScRelocProps@20 (MAPI32.172)
+ *
+ * Relocate the pointers in an array of property values after it has been copied.
+ *
+ * PARAMS
+ *  cValues   [I] Number of properties in lpProps
+ *  lpProps   [O] Property array to relocate the pointers in.
+ *  lpOld     [I] Position where the data was copied from
+ *  lpNew     [I] Position where the data was copied to
+ *  lpCount   [O] If non-NULL, destination for the number of bytes of data at lpDst
+ *
+ * RETURNS
+ *  Success: S_OK. Any pointers in lpProps are relocated.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
+ *
+ * NOTES
+ *  MSDN states that this function can be used for serialisation by passing
+ *  NULL as either lpOld or lpNew, thus converting any pointers in lpProps
+ *  between offsets and pointers. This does not work in native (it crashes),
+ *  and cannot be made to work in Wine because the original interface design
+ *  is deficient. The only use left for this function is to remap pointers
+ *  in a contiguous property array that has been copied with memcpy() to
+ *  another memory location.
+ */
+SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
+                          LPVOID lpNew, ULONG *lpCount)
+{
+    static const BOOL bBadPtr = TRUE; /* Windows bug - Assumes source is bad */
+    LPSPropValue lpDest = (LPSPropValue)lpProps;
+    ULONG ulCount = cValues * sizeof(SPropValue);
+    ULONG ulLen, i;
+    int iter;
+
+    TRACE("(%d,%p,%p,%p,%p)\n", cValues, lpProps, lpOld, lpNew, lpCount);
+
+    if (!lpProps || cValues < 0 || !lpOld || !lpNew)
+        return MAPI_E_INVALID_PARAMETER;
+
+    /* The reason native doesn't work as MSDN states is that it assumes that
+     * the lpProps pointer contains valid pointers. This is obviously not
+     * true if the array is being read back from serialisation (the pointers
+     * are just offsets). Native can't actually work converting the pointers to
+     * offsets either, because it converts any array pointers to offsets then
+     * _dereferences the offset_ in order to convert the array elements!
+     *
+     * 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. It seems this
+     * functionality was never tested by MS.
+     */
+
+#define RELOC_PTR(p) (((char*)(p)) - (char*)lpOld + (char*)lpNew)
+
+    for (iter = 0; iter < cValues; iter++)
+    {
+        switch (PROP_TYPE(lpDest->ulPropTag))
+        {
+        case PT_CLSID:
+            lpDest->Value.lpguid = (LPGUID)RELOC_PTR(lpDest->Value.lpguid);
+            ulCount += sizeof(GUID);
+            break;
+        case PT_STRING8:
+            ulLen = bBadPtr ? 0 : lstrlenA(lpDest->Value.lpszA) + 1u;
+            lpDest->Value.lpszA = (LPSTR)RELOC_PTR(lpDest->Value.lpszA);
+            if (bBadPtr)
+                ulLen = lstrlenA(lpDest->Value.lpszA) + 1u;
+            ulCount += ulLen;
+            break;
+        case PT_UNICODE:
+            ulLen = bBadPtr ? 0 : (lstrlenW(lpDest->Value.lpszW) + 1u) * sizeof(WCHAR);
+            lpDest->Value.lpszW = (LPWSTR)RELOC_PTR(lpDest->Value.lpszW);
+            if (bBadPtr)
+                ulLen = (strlenW(lpDest->Value.lpszW) + 1u) * sizeof(WCHAR);
+            ulCount += ulLen;
+            break;
+        case PT_BINARY:
+            lpDest->Value.bin.lpb = (LPBYTE)RELOC_PTR(lpDest->Value.bin.lpb);
+            ulCount += lpDest->Value.bin.cb;
+            break;
+        default:
+            if (lpDest->ulPropTag & MV_FLAG)
+            {
+                /* Since we have to access the array elements, don't map the
+                 * array unless it is invalid (otherwise, map it at the end)
+                 */
+                if (bBadPtr)
+                    lpDest->Value.MVszA.lppszA = (LPSTR*)RELOC_PTR(lpDest->Value.MVszA.lppszA);
+
+                switch (PROP_TYPE(lpProps->ulPropTag))
+                {
+                case PT_MV_STRING8:
+                {
+                    ulCount += lpDest->Value.MVszA.cValues * sizeof(char *);
+
+                    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;
+                        ulCount += ulStrLen;
+                    }
+                    break;
+                }
+                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:
+                    ulCount += UlPropSize(lpDest);
+                    break;
+                }
+                if (!bBadPtr)
+                    lpDest->Value.MVszA.lppszA = (LPSTR*)RELOC_PTR(lpDest->Value.MVszA.lppszA);
+                break;
+            }
+        }
+        lpDest++;
+    }
+    if (lpCount)
+        *lpCount = ulCount;
+
+    return S_OK;
+}
+
+/*************************************************************************
+ * LpValFindProp@12 (MAPI32.173)
+ *
+ * Find a property with a given property id in a property array.
+ *
+ * PARAMS
+ *  ulPropTag [I] Property tag containing property id to find
+ *  cValues   [I] Number of properties in lpProps
+ *  lpProps   [I] Property array to search
+ *
+ * RETURNS
+ *  A pointer to the matching property, or NULL if none was found.
+ *
+ * NOTES
+ *  This function matches only on the property id and does not care if the
+ *  property types differ.
+ */
+LPSPropValue WINAPI LpValFindProp(ULONG ulPropTag, ULONG cValues, LPSPropValue lpProps)
+{
+    TRACE("(%ld,%ld,%p)\n", ulPropTag, cValues, lpProps);
+
+    if (lpProps && cValues)
+    {
+        ULONG i;
+        for (i = 0; i < cValues; i++)
+        {
+            if (PROP_ID(ulPropTag) == PROP_ID(lpProps[i].ulPropTag))
+                return &lpProps[i];
+        }
+    }
+    return NULL;
+}
+
+/*************************************************************************
+ * ScDupPropset@16 (MAPI32.174)
+ *
+ * Duplicate a property value array into a contiguous 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
+ *
+ * PARAMS
+ *  lppszStrs [I] Array of strings to check
+ *  ulCount   [I] Number of strings in lppszStrs
+ *
+ * RETURNS
+ *  TRUE, if lppszStrs is invalid, FALSE otherwise.
+ */
+BOOL WINAPI FBadRglpszA(LPSTR *lppszStrs, ULONG ulCount)
+{
+    ULONG i;
+
+    TRACE("(%p,%ld)\n", lppszStrs, ulCount);
+
+    if (!ulCount)
+        return FALSE;
+
+    if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
+        return TRUE;
+
+    for (i = 0; i < ulCount; i++)
+    {
+        if (!lppszStrs[i] || IsBadStringPtrA(lppszStrs[i], -1))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ * FBadRglpszW@8 (MAPI32.176)
+ *
+ * See FBadRglpszA.
+ */
+BOOL WINAPI FBadRglpszW(LPWSTR *lppszStrs, ULONG ulCount)
+{
+    ULONG i;
+
+    TRACE("(%p,%ld)\n", lppszStrs, ulCount);
+
+    if (!ulCount)
+        return FALSE;
+
+    if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
+        return TRUE;
+
+    for (i = 0; i < ulCount; i++)
+    {
+        if (!lppszStrs[i] || IsBadStringPtrW(lppszStrs[i], -1))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ * FBadRowSet@4 (MAPI32.177)
+ *
+ * Determine if a row is invalid
+ *
+ * PARAMS
+ *  lpRow [I] Row to check
+ *
+ * RETURNS
+ *  TRUE, if lpRow is invalid, FALSE otherwise.
+ */
+BOOL WINAPI FBadRowSet(LPSRowSet lpRowSet)
+{
+    ULONG i;
+    TRACE("(%p)\n", lpRowSet);
+
+    if (!lpRowSet || IsBadReadPtr(lpRowSet, CbSRowSet(lpRowSet)))
+        return TRUE;
+
+    for (i = 0; i < lpRowSet->cRows; i++)
+    {
+        if (FBadRow(&lpRowSet->aRow[i]))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ * FBadPropTag@4 (MAPI32.179)
+ *
+ * Determine if a property tag is invalid
+ *
+ * PARAMS
+ *  ulPropTag [I] Property tag to check
+ *
+ * RETURNS
+ *  TRUE, if ulPropTag is invalid, FALSE otherwise.
+ */
+ULONG WINAPI FBadPropTag(ULONG ulPropTag)
+{
+    TRACE("(0x%08lx)\n", ulPropTag);
+
+    switch (ulPropTag & (~MV_FLAG & PROP_TYPE_MASK))
+    {
+    case PT_UNSPECIFIED:
+    case PT_NULL:
+    case PT_I2:
+    case PT_LONG:
+    case PT_R4:
+    case PT_DOUBLE:
+    case PT_CURRENCY:
+    case PT_APPTIME:
+    case PT_ERROR:
+    case PT_BOOLEAN:
+    case PT_OBJECT:
+    case PT_I8:
+    case PT_STRING8:
+    case PT_UNICODE:
+    case PT_SYSTIME:
+    case PT_CLSID:
+    case PT_BINARY:
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/*************************************************************************
+ * FBadRow@4 (MAPI32.180)
+ *
+ * Determine if a row is invalid
+ *
+ * PARAMS
+ *  lpRow [I] Row to check
+ *
+ * RETURNS
+ *  TRUE, if lpRow is invalid, FALSE otherwise.
+ */
+ULONG WINAPI FBadRow(LPSRow lpRow)
+{
+    ULONG i;
+    TRACE("(%p)\n", lpRow);
+
+    if (!lpRow || IsBadReadPtr(lpRow, sizeof(SRow)) || !lpRow->lpProps ||
+        IsBadReadPtr(lpRow->lpProps, lpRow->cValues * sizeof(SPropValue)))
+        return TRUE;
+
+    for (i = 0; i < lpRow->cValues; i++)
+    {
+        if (FBadProp(&lpRow->lpProps[i]))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ * FBadProp@4 (MAPI32.181)
+ *
+ * Determine if a property is invalid
+ *
+ * PARAMS
+ *  lpProp [I] Property to check
+ *
+ * RETURNS
+ *  TRUE, if lpProp is invalid, FALSE otherwise.
+ */
+ULONG WINAPI FBadProp(LPSPropValue lpProp)
+{
+    if (!lpProp || IsBadReadPtr(lpProp, sizeof(SPropValue)) ||
+        FBadPropTag(lpProp->ulPropTag))
+        return TRUE;
+
+    switch (PROP_TYPE(lpProp->ulPropTag))
+    {
+    /* Single value properties containing pointers */
+    case PT_STRING8:
+        if (!lpProp->Value.lpszA || IsBadStringPtrA(lpProp->Value.lpszA, -1))
+            return TRUE;
+        break;
+    case PT_UNICODE:
+        if (!lpProp->Value.lpszW || IsBadStringPtrW(lpProp->Value.lpszW, -1))
+            return TRUE;
+        break;
+    case PT_BINARY:
+        if (IsBadReadPtr(lpProp->Value.bin.lpb, lpProp->Value.bin.cb))
+            return TRUE;
+        break;
+    case PT_CLSID:
+        if (IsBadReadPtr(lpProp->Value.lpguid, sizeof(GUID)))
+            return TRUE;
+        break;
+
+    /* Multiple value properties (arrays) containing no pointers */
+    case PT_MV_I2:
+        return PROP_BadArray(lpProp, sizeof(SHORT));
+    case PT_MV_LONG:
+        return PROP_BadArray(lpProp, sizeof(LONG));
+    case PT_MV_LONGLONG:
+        return PROP_BadArray(lpProp, sizeof(LONG64));
+    case PT_MV_FLOAT:
+        return PROP_BadArray(lpProp, sizeof(float));
+    case PT_MV_SYSTIME:
+        return PROP_BadArray(lpProp, sizeof(FILETIME));
+    case PT_MV_APPTIME:
+    case PT_MV_DOUBLE:
+        return PROP_BadArray(lpProp, sizeof(double));
+    case PT_MV_CURRENCY:
+        return PROP_BadArray(lpProp, sizeof(CY));
+    case PT_MV_CLSID:
+        return PROP_BadArray(lpProp, sizeof(GUID));
+
+    /* Multiple value properties containing pointers */
+    case PT_MV_STRING8:
+        return FBadRglpszA(lpProp->Value.MVszA.lppszA,
+                           lpProp->Value.MVszA.cValues);
+    case PT_MV_UNICODE:
+        return FBadRglpszW(lpProp->Value.MVszW.lppszW,
+                           lpProp->Value.MVszW.cValues);
+    case PT_MV_BINARY:
+        return FBadEntryList((LPENTRYLIST)&lpProp->Value.MVbin);
+    }
+    return FALSE;
+}
+
+/*************************************************************************
+ * FBadColumnSet@4 (MAPI32.182)
+ *
+ * Determine if an array of property tags is invalid
+ *
+ * PARAMS
+ *  lpCols [I] Property tag array to check
+ *
+ * RETURNS
+ *  TRUE, if lpCols is invalid, FALSE otherwise.
+ */
+ULONG WINAPI FBadColumnSet(LPSPropTagArray lpCols)
+{
+    ULONG ulRet = FALSE, i;
+
+    TRACE("(%p)\n", lpCols);
+
+    if (!lpCols || IsBadReadPtr(lpCols, CbSPropTagArray(lpCols)))
+        ulRet = TRUE;
+    else
+    {
+        for (i = 0; i < lpCols->cValues; i++)
+        {
+            if ((lpCols->aulPropTag[i] & PROP_TYPE_MASK) == PT_ERROR ||
+                FBadPropTag(lpCols->aulPropTag[i]))
+            {
+                ulRet = TRUE;
+                break;
+            }
+        }
+    }
+    TRACE("Returning %s\n", ulRet ? "TRUE" : "FALSE");
+    return ulRet;
+}
+
+
+/**************************************************************************
+ *  IMAPIProp {MAPI32}
+ *
+ * The default Mapi interface for manipulating object properties.
+ *
+ * DESCRIPTION
+ *  This object provides an interface to an objects properties. It is exposed
+ *  by several types of Mapi objects in order to simplify the querying and
+ *  modification of properties.
+ *
+ * METHODS
+ */
+
+/* A single property in a property data collection */
+typedef struct
+{
+  struct list  entry;
+  ULONG        ulAccess; /* The property value access level */
+  LPSPropValue value;    /* The property value */
+} IPropDataItem, *LPIPropDataItem;
+
+ /* The main property data collection structure */
+typedef struct
+{
+    const IPropDataVtbl   *lpVtbl;
+    LONG             lRef;        /* Reference count */
+    ALLOCATEBUFFER  *lpAlloc;     /* Memory allocation routine */
+    ALLOCATEMORE    *lpMore;      /* Linked memory allocation routine */
+    FREEBUFFER      *lpFree;      /* Memory free routine */
+    ULONG            ulObjAccess; /* Object access level */
+    ULONG            ulNumValues; /* Number of items in values list */
+    struct list      values;      /* List of property values */
+    RTL_CRITICAL_SECTION cs;          /* Lock for thread safety */
+} IPropDataImpl;
+
+/* Internal - Get a property value, assumes lock is held */
+static IPropDataItem *IMAPIPROP_GetValue(IPropDataImpl *This, ULONG ulPropTag)
+{
+    struct list *cursor;
+
+    LIST_FOR_EACH(cursor, &This->values)
+    {
+        LPIPropDataItem current = LIST_ENTRY(cursor, IPropDataItem, entry);
+        /* Note that propery types don't have to match, just Id's */
+        if (PROP_ID(current->value->ulPropTag) == PROP_ID(ulPropTag))
+            return current;
+    }
+    return NULL;
+}
+
+/* Internal - Add a new property value, assumes lock is held */
+static IPropDataItem *IMAPIPROP_AddValue(IPropDataImpl *This,
+                                         LPSPropValue lpProp)
+{
+    LPVOID lpMem;
+    LPIPropDataItem lpNew;
+    HRESULT hRet;
+
+    hRet = This->lpAlloc(sizeof(IPropDataItem), &lpMem);
+
+    if (SUCCEEDED(hRet))
+    {
+        lpNew = lpMem;
+        lpNew->ulAccess = IPROP_READWRITE;
+
+        /* Allocate the value seperately so we can update it easily */
+        lpMem = NULL;
+        hRet = This->lpAlloc(sizeof(SPropValue), &lpMem);
+        if (SUCCEEDED(hRet))
+        {
+            lpNew->value = lpMem;
+
+            hRet = PropCopyMore(lpNew->value, lpProp, This->lpMore, lpMem);
+            if (SUCCEEDED(hRet))
+            {
+                list_add_tail(&This->values, &lpNew->entry);
+                This->ulNumValues++;
+                return lpNew;
+            }
+            This->lpFree(lpNew->value);
+        }
+        This->lpFree(lpNew);
+    }
+    return NULL;
+}
+
+/* Internal - Lock an IPropData object */
+static inline void IMAPIPROP_Lock(IPropDataImpl *This)
+{
+    RtlEnterCriticalSection(&This->cs);
+}
+
+/* Internal - Unlock an IPropData object */
+static inline void IMAPIPROP_Unlock(IPropDataImpl *This)
+{
+    RtlLeaveCriticalSection(&This->cs);
+}
+
+/* This one seems to be missing from mapidefs.h */
+#define CbNewSPropProblemArray(c) \
+    (offsetof(SPropProblemArray,aProblem)+(c)*sizeof(SPropProblem))
+
+/**************************************************************************
+ *  IMAPIProp_QueryInterface {MAPI32}
+ *
+ * Inherited method from the IUnknown Interface.
+ * See IUnknown_QueryInterface.
+ *
+ * NOTES
+ * This object exposes the following interfaces:
+ * - IUnknown() : The default interface for all COM-Objects.
+ * - IMAPIProp() : The default Mapi interface for manipulating object properties.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnQueryInterface(LPMAPIPROP iface, REFIID riid, LPVOID *ppvObj)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+
+    TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppvObj);
+
+    if (!ppvObj || !riid)
+        return MAPI_E_INVALID_PARAMETER;
+
+    *ppvObj = NULL;
+
+    if(IsEqualIID(riid, &IID_IUnknown) ||
+       IsEqualIID(riid, &IID_IMAPIProp) ||
+       IsEqualIID(riid, &IID_IMAPIPropData))
+    {
+        *ppvObj = This;
+        IPropData_AddRef(iface);
+        TRACE("returning %p\n", *ppvObj);
+        return S_OK;
+    }
+
+    TRACE("returning E_NOINTERFACE\n");
+    return MAPI_E_INTERFACE_NOT_SUPPORTED;
+}
+
+/**************************************************************************
+ *  IMAPIProp_AddRef {MAPI32}
+ *
+ * Inherited method from the IUnknown Interface.
+ * See IUnknown_AddRef.
+ */
+static inline ULONG WINAPI IMAPIProp_fnAddRef(LPMAPIPROP iface)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+
+    TRACE("(%p)->(count before=%lu)\n", This, This->lRef);
+
+    return InterlockedIncrement(&This->lRef);
+}
+
+/**************************************************************************
+ *  IMAPIProp_Release {MAPI32}
+ *
+ * Inherited method from the IUnknown Interface.
+ * See IUnknown_Release.
+ */
+static inline ULONG WINAPI IMAPIProp_fnRelease(LPMAPIPROP iface)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+    LONG lRef;
+
+    TRACE("(%p)->(count before=%lu)\n", This, This->lRef);
+
+    lRef = InterlockedDecrement(&This->lRef);
+    if (!lRef)
+    {
+        TRACE("Destroying IPropData (%p)\n",This);
+
+        /* Note: No need to lock, since no other thread is referencing iface */
+        while (!list_empty(&This->values))
+        {
+            struct list *head = list_head(&This->values);
+            LPIPropDataItem current = LIST_ENTRY(head, IPropDataItem, entry);
+            list_remove(head);
+            This->lpFree(current->value);
+            This->lpFree(current);
+        }
+        RtlDeleteCriticalSection(&This->cs);
+        This->lpFree(This);
+    }
+    return (ULONG)lRef;
+}
+
+/**************************************************************************
+ *  IMAPIProp_GetLastError {MAPI32}
+ *
+ * Get information about the last error that ocurred in an IMAPIProp object.
+ *
+ * PARAMS
+ *  iface    [I] IMAPIProp object that experienced the error
+ *  hRes     [I] Result of the call that returned an error
+ *  ulFlags  [I] 0=return Ascii strings, MAPI_UNICODE=return Unicode strings
+ *  lppError [O] Destination for detailed error information
+ *
+ * RETURNS
+ *  Success: S_OK. *lppError contains details about the last error.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid,
+ *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
+ *
+ * NOTES
+ *  - If this function succeeds, the returned information in *lppError must be
+ *  freed using MAPIFreeBuffer() once the caller is finished with it.
+ *  - It is possible for this function to suceed and set *lppError to NULL,
+ *  if there is no further information to report about hRes.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnGetLastError(LPMAPIPROP iface, HRESULT hRes,
+                         ULONG ulFlags, LPMAPIERROR *lppError)
+{
+    TRACE("(%p,0x%08lX,0x%08lX,%p)\n", iface, hRes, ulFlags, lppError);
+
+    if (!lppError  || SUCCEEDED(hRes) || (ulFlags & ~MAPI_UNICODE))
+        return MAPI_E_INVALID_PARAMETER;
+
+    *lppError = NULL;
+    return S_OK;
+}
+
+/**************************************************************************
+ *  IMAPIProp_SaveChanges {MAPI32}
+ *
+ * Update any changes made to a tansactional IMAPIProp object.
+ *
+ * PARAMS
+ *  iface    [I] IMAPIProp object to update
+ *  ulFlags  [I] Flags controlling the update.
+ *
+ * RETURNS
+ *  Success: S_OK. Any outstanding changes are committed to the object.
+ *  Failure: An HRESULT error code describing the error.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnSaveChanges(LPMAPIPROP iface, ULONG ulFlags)
+{
+    TRACE("(%p,0x%08lX)\n", iface, ulFlags);
+
+     /* Since this object is not transacted we do not need to implement this */
+     /* FIXME: Should we set the access levels to clean? */
+    return S_OK;
+}
+
+/**************************************************************************
+ *  IMAPIProp_GetProps {MAPI32}
+ *
+ * Get property values from an IMAPIProp object.
+ *
+ * PARAMS
+ *  iface    [I] IMAPIProp object to get the property values from
+ *  lpTags   [I] Property tage of property values to be retrieved
+ *  ulFlags  [I] Return 0=Ascii MAPI_UNICODE=Unicode strings for
+ *                 unspecified types
+ *  lpCount  [O] Destination for number of properties returned
+ *  lppProps [O] Destination for returned property values
+ *
+ * RETURNS
+ *  Success: S_OK. *lppProps and *lpCount are updated.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
+ *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails, or
+ *           MAPI_W_ERRORS_RETURNED if not all properties were retrieved
+ *           successfully.
+ * NOTES
+ *  - If MAPI_W_ERRORS_RETURNED is returned, any properties that could not be
+ *    retrieved from iface are present in lppProps with their type
+ *    changed to PT_ERROR and Id unchanged.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnGetProps(LPMAPIPROP iface, LPSPropTagArray lpTags,
+                     ULONG ulFlags, ULONG *lpCount, LPSPropValue *lppProps)
+{
+    ULONG i;
+    HRESULT hRet = S_OK;
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+
+    TRACE("(%p,%p,0x%08lx,%p,%p) stub\n", iface, lpTags, ulFlags,
+          lpCount, lppProps);
+
+    if (!iface || ulFlags & ~MAPI_UNICODE || !lpTags || *lpCount || !lppProps)
+        return MAPI_E_INVALID_PARAMETER;
+
+    FIXME("semi-stub, flags not supported\n");
+
+    *lpCount = lpTags->cValues;
+    *lppProps = NULL;
+
+    if (*lpCount)
+    {
+        hRet = MAPIAllocateBuffer(*lpCount * sizeof(SPropValue), (LPVOID*)lppProps);
+        if (FAILED(hRet))
+            return hRet;
+
+        IMAPIPROP_Lock(This);
+
+        for (i = 0; i < lpTags->cValues; i++)
+        {
+            HRESULT hRetTmp = E_INVALIDARG;
+            LPIPropDataItem item;
+
+            item = IMAPIPROP_GetValue(This, lpTags->aulPropTag[i]);
+
+            if (item)
+                hRetTmp = PropCopyMore(&(*lppProps)[i], item->value,
+                                       This->lpMore, *lppProps);
+            if (FAILED(hRetTmp))
+            {
+                hRet = MAPI_W_ERRORS_RETURNED;
+                (*lppProps)[i].ulPropTag =
+                    CHANGE_PROP_TYPE(lpTags->aulPropTag[i], PT_ERROR);
+            }
+        }
+
+        IMAPIPROP_Unlock(This);
+    }
+    return hRet;
+}
+
+/**************************************************************************
+ *  MAPIProp_GetPropList {MAPI32}
+ *
+ * Get the list of property tags for all values in an IMAPIProp object.
+ *
+ * PARAMS
+ *  iface   [I] IMAPIProp object to get the property tag list from
+ *  ulFlags [I] Return 0=Ascii MAPI_UNICODE=Unicode strings for
+ *              unspecified types
+ *  lppTags [O] Destination for the retrieved peoperty tag list
+ *
+ * RETURNS
+ *  Success: S_OK. *lppTags contains the tags for all available properties.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
+ *           MAPI_E_BAD_CHARWIDTH, if Ascii or Unicode strings are requested
+ *           and that type of string is not supported.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnGetPropList(LPMAPIPROP iface, ULONG ulFlags,
+                        LPSPropTagArray *lppTags)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+    ULONG i;
+    HRESULT hRet;
+
+    TRACE("(%p,0x%08lx,%p) stub\n", iface, ulFlags, lppTags);
+
+    if (!iface || ulFlags & ~MAPI_UNICODE || !lppTags)
+        return MAPI_E_INVALID_PARAMETER;
+
+    FIXME("semi-stub, flags not supported\n");
+
+    *lppTags = NULL;
+
+    IMAPIPROP_Lock(This);
+
+    hRet = MAPIAllocateBuffer(CbNewSPropTagArray(This->ulNumValues),
+                              (LPVOID*)lppTags);
+    if (SUCCEEDED(hRet))
+    {
+        struct list *cursor;
+
+        i = 0;
+        LIST_FOR_EACH(cursor, &This->values)
+        {
+            LPIPropDataItem current = LIST_ENTRY(cursor, IPropDataItem, entry);
+            (*lppTags)->aulPropTag[i] = current->value->ulPropTag;
+            i++;
+        }
+        (*lppTags)->cValues = This->ulNumValues;
+    }
+
+    IMAPIPROP_Unlock(This);
+    return hRet;
+}
+
+/**************************************************************************
+ *  IMAPIProp_OpenProperty {MAPI32}
+ *
+ * Not documented at this time.
+ *
+ * RETURNS
+ *  An HRESULT success/failure code.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnOpenProperty(LPMAPIPROP iface, ULONG ulPropTag, LPCIID iid,
+                         ULONG ulOpts, ULONG ulFlags, LPUNKNOWN *lpUnk)
+{
+    FIXME("(%p,%lu,%s,%lu,0x%08lx,%p) stub\n", iface, ulPropTag,
+          debugstr_guid(iid), ulOpts, ulFlags, lpUnk);
+    return MAPI_E_NO_SUPPORT;
+}
+
+
+/**************************************************************************
+ *  IMAPIProp_SetProps {MAPI32}
+ *
+ * Add or edit the property values in an IMAPIProp object.
+ *
+ * PARAMS
+ *  iface    [I] IMAPIProp object to get the property tag list from
+ *  ulValues [I] Number of properties in lpProps
+ *  lpProps  [I] Property values to set
+ *  lppProbs [O] Optional destination for any problems that occurred
+ *
+ * RETURNS
+ *  Success: S_OK. The properties in lpProps are added to iface if they don't
+ *           exist, or changed to the values in lpProps if they do
+ *  Failure: An HRESULT error code describing the error
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnSetProps(LPMAPIPROP iface, ULONG ulValues,
+                     LPSPropValue lpProps, LPSPropProblemArray *lppProbs)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+    HRESULT hRet = S_OK;
+    ULONG i;
+
+    TRACE("(%p,%lu,%p,%p)\n", iface, ulValues, lpProps, lppProbs);
+
+    if (!iface || !lpProps)
+      return MAPI_E_INVALID_PARAMETER;
+
+    for (i = 0; i < ulValues; i++)
+    {
+        if (FBadProp(&lpProps[i]) ||
+            PROP_TYPE(lpProps[i].ulPropTag) == PT_OBJECT ||
+            PROP_TYPE(lpProps[i].ulPropTag) == PT_NULL)
+          return MAPI_E_INVALID_PARAMETER;
+    }
+
+    IMAPIPROP_Lock(This);
+
+    /* FIXME: Under what circumstances is lpProbs created? */
+    for (i = 0; i < ulValues; i++)
+    {
+        LPIPropDataItem item = IMAPIPROP_GetValue(This, lpProps[i].ulPropTag);
+
+        if (item)
+        {
+            HRESULT hRetTmp;
+            LPVOID lpMem = NULL;
+
+            /* Found, so update the existing value */
+            if (item->value->ulPropTag != lpProps[i].ulPropTag)
+                FIXME("semi-stub, overwriting type (not coercing)\n");
+
+            hRetTmp = This->lpAlloc(sizeof(SPropValue), &lpMem);
+            if (SUCCEEDED(hRetTmp))
+            {
+                hRetTmp = PropCopyMore(lpMem, &lpProps[i], This->lpMore, lpMem);
+                if (SUCCEEDED(hRetTmp))
+                {
+                    This->lpFree(item->value);
+                    item->value = lpMem;
+                    continue;
+                }
+                This->lpFree(lpMem);
+            }
+            hRet = hRetTmp;
+        }
+        else
+        {
+            /* Add new value */
+            if (!(item = IMAPIPROP_AddValue(This, &lpProps[i])))
+                hRet = MAPI_E_NOT_ENOUGH_MEMORY;
+        }
+    }
+
+    IMAPIPROP_Unlock(This);
+    return hRet;
+}
+
+/**************************************************************************
+ *  IMAPIProp_DeleteProps {MAPI32}
+ *
+ * Delete one or more property values from an IMAPIProp object.
+ *
+ * PARAMS
+ *  iface    [I] IMAPIProp object to remove property values from.
+ *  lpTags   [I] Collection of property Id's to remove from iface.
+ *  lppProbs [O] Destination for problems encountered, if any.
+ *
+ * RETURNS
+ *  Success: S_OK. Any properties in iface matching property Id's in lpTags have
+ *           been deleted. If lppProbs is non-NULL it contains details of any
+ *           errors that occurred.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
+ *           E_ACCESSDENIED, if this object was created using CreateIProp() and
+ *           a subsequent call to IPropData_SetObjAcess() was made specifying
+ *           IPROP_READONLY as the access type.
+ *
+ * NOTES
+ *  - lppProbs will not be populated for cases where a property Id is present
+ *    in lpTags but not in iface.
+ *  - lppProbs should be deleted with MAPIFreeBuffer() if returned.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnDeleteProps(LPMAPIPROP iface, LPSPropTagArray lpTags,
+                        LPSPropProblemArray *lppProbs)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+    ULONG i, numProbs = 0;
+    HRESULT hRet = S_OK;
+
+    TRACE("(%p,%p,%p)\n", iface, lpTags, lppProbs);
+
+    if (!iface || !lpTags)
+        return MAPI_E_INVALID_PARAMETER;
+
+    if (lppProbs)
+        *lppProbs = NULL;
+
+    for (i = 0; i < lpTags->cValues; i++)
+    {
+        if (FBadPropTag(lpTags->aulPropTag[i]) ||
+            PROP_TYPE(lpTags->aulPropTag[i]) == PT_OBJECT ||
+            PROP_TYPE(lpTags->aulPropTag[i]) == PT_NULL)
+          return MAPI_E_INVALID_PARAMETER;
+    }
+
+    IMAPIPROP_Lock(This);
+
+    if (This->ulObjAccess != IPROP_READWRITE)
+    {
+        IMAPIPROP_Unlock(This);
+        return E_ACCESSDENIED;
+    }
+
+    for (i = 0; i < lpTags->cValues; i++)
+    {
+        LPIPropDataItem item = IMAPIPROP_GetValue(This, lpTags->aulPropTag[i]);
+
+        if (item)
+        {
+            if (item->ulAccess & IPROP_READWRITE)
+            {
+                /* Everything hunky-dory, remove the item */
+                list_remove(&item->entry);
+                This->lpFree(item->value); /* Also frees value pointers */
+                This->lpFree(item);
+                This->ulNumValues--;
+            }
+            else if (lppProbs)
+            {
+                 /* Can't write the value. Create/populate problems array */
+                 if (!*lppProbs)
+                 {
+                     /* Create problems array */
+                     ULONG ulSize = CbNewSPropProblemArray(lpTags->cValues - i);
+                     HRESULT hRetTmp = MAPIAllocateBuffer(ulSize, (LPVOID*)lppProbs);
+                     if (FAILED(hRetTmp))
+                         hRet = hRetTmp;
+                 }
+                 if (*lppProbs)
+                 {
+                     LPSPropProblem lpProb = &(*lppProbs)->aProblem[numProbs];
+                     lpProb->ulIndex = i;
+                     lpProb->ulPropTag = lpTags->aulPropTag[i];
+                     lpProb->scode = E_ACCESSDENIED;
+                     numProbs++;
+                 }
+            }
+        }
+    }
+    if (lppProbs && *lppProbs)
+        (*lppProbs)->cProblem = numProbs;
+
+    IMAPIPROP_Unlock(This);
+    return hRet;
+}
+
+
+/**************************************************************************
+ *  IMAPIProp_CopyTo {MAPI32}
+ *
+ * Not documented at this time.
+ *
+ * RETURNS
+ *  An HRESULT success/failure code.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnCopyTo(LPMAPIPROP iface, ULONG niids, LPCIID lpiidExcl,
+                   LPSPropTagArray lpPropsExcl, ULONG ulParam,
+                   LPMAPIPROGRESS lpIProgress, LPCIID lpIfaceIid, LPVOID lpDstObj,
+                   ULONG ulFlags, LPSPropProblemArray *lppProbs)
+{
+    FIXME("(%p,%lu,%p,%p,%lx,%p,%s,%p,0x%08lX,%p) stub\n", iface, niids,
+          lpiidExcl, lpPropsExcl, ulParam, lpIProgress,
+          debugstr_guid(lpIfaceIid), lpDstObj, ulFlags, lppProbs);
+    return MAPI_E_NO_SUPPORT;
+}
+
+/**************************************************************************
+ *  IMAPIProp_CopyProps {MAPI32}
+ *
+ * Not documented at this time.
+ *
+ * RETURNS
+ *  An HRESULT success/failure code.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnCopyProps(LPMAPIPROP iface, LPSPropTagArray lpInclProps,
+                      ULONG ulParam, LPMAPIPROGRESS lpIProgress, LPCIID lpIface,
+                      LPVOID lpDstObj, ULONG ulFlags,
+                      LPSPropProblemArray *lppProbs)
+{
+    FIXME("(%p,%p,%lx,%p,%s,%p,0x%08lX,%p) stub\n", iface, lpInclProps,
+          ulParam, lpIProgress, debugstr_guid(lpIface), lpDstObj, ulFlags,
+          lppProbs);
+    return MAPI_E_NO_SUPPORT;
+}
+
+/**************************************************************************
+ *  IMAPIProp_GetNamesFromIDs {MAPI32}
+ *
+ * Get the names of properties from their identifiers.
+ *
+ * PARAMS
+ *  iface       [I]   IMAPIProp object to operate on
+ *  lppPropTags [I/O] Property identifiers to get the names for, or NULL to
+ *                    get all names
+ *  iid         [I]   Property set identifier, or NULL
+ *  ulFlags     [I]   MAPI_NO_IDS=Don't return numeric named properties,
+ *                    or MAPI_NO_STRINGS=Don't return strings
+ *  lpCount     [O]   Destination for number of properties returned
+ *  lpppNames   [O]   Destination for returned names
+ *
+ * RETURNS
+ *  Success: S_OK. *lppPropTags and lpppNames contain the returned
+ *           name/identifiers.
+ *  Failure: MAPI_E_NO_SUPPORT, if the object does not support named properties,
+ *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails, or
+ *           MAPI_W_ERRORS_RETURNED if not all properties were retrieved
+ *           successfully.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnGetNamesFromIDs(LPMAPIPROP iface, LPSPropTagArray *lppPropTags,
+                            LPGUID iid, ULONG ulFlags, ULONG *lpCount,
+                            LPMAPINAMEID **lpppNames)
+{
+    FIXME("(%p,%p,%s,0x%08lX,%p,%p) stub\n", iface, lppPropTags,
+          debugstr_guid(iid), ulFlags, lpCount, lpppNames);
+    return MAPI_E_NO_SUPPORT;
+}
+
+/**************************************************************************
+ *  IMAPIProp_GetIDsFromNames {MAPI32}
+ *
+ * Get property identifiers associated with one or more named properties.
+ *
+ * PARAMS
+ *  iface       [I] IMAPIProp object to operate on
+ *  ulNames     [I] Number of names in lppNames
+ *  lppNames    [I] Names to query or create, or NULL to query all names
+ *  ulFlags     [I] Pass MAPI_CREATE to create new named properties
+ *  lppPropTags [O] Destination for queried or created property identifiers
+ *
+ * RETURNS
+ *  Success: S_OK. *lppPropTags contains the property tags created or requested.
+ *  Failure: MAPI_E_NO_SUPPORT, if the object does not support named properties,
+ *           MAPI_E_TOO_BIG, if the object cannot process the number of
+ *           properties involved.
+ *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails, or
+ *           MAPI_W_ERRORS_RETURNED if not all properties were retrieved
+ *           successfully.
+ */
+static inline HRESULT WINAPI
+IMAPIProp_fnGetIDsFromNames(LPMAPIPROP iface, ULONG ulNames,
+                            LPMAPINAMEID *lppNames, ULONG ulFlags,
+                            LPSPropTagArray *lppPropTags)
+{
+    FIXME("(%p,%ld,%p,0x%08lX,%p) stub\n",
+          iface, ulNames, lppNames, ulFlags, lppPropTags);
+    return MAPI_E_NO_SUPPORT;
+}
+
+/**************************************************************************
+ *  IPropData {MAPI32}
+ *
+ * A default Mapi interface to provide manipulation of object properties.
+ *
+ * DESCRIPTION
+ *  This object provides a default interface suitable in some cases as an
+ *  implementation of the IMAPIProp interface (which has no default
+ *  implementation). In addition to the IMAPIProp() methods inherited, this
+ *  interface allows read/write control over access to the object and its
+ *  individual properties.
+ *
+ *  To obtain the default implementation of this interface from Mapi, call
+ *  CreateIProp().
+ *
+ * METHODS
+ */
+
+/**************************************************************************
+ *  IPropData_QueryInterface {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_QueryInterface.
+ */
+static HRESULT WINAPI
+IPropData_fnQueryInterface(LPPROPDATA iface, REFIID riid, LPVOID *ppvObj)
+{
+    return IMAPIProp_fnQueryInterface((LPMAPIPROP)iface, riid, ppvObj);
+}
+
+/**************************************************************************
+ *  IPropData_AddRef {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_AddRef.
+ */
+static ULONG WINAPI
+IPropData_fnAddRef(LPPROPDATA iface)
+{
+    return IMAPIProp_fnAddRef((LPMAPIPROP)iface);
+}
+
+/**************************************************************************
+ *  IPropData_Release {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_Release.
+ */
+static ULONG WINAPI
+IPropData_fnRelease(LPPROPDATA iface)
+{
+    return IMAPIProp_fnRelease((LPMAPIPROP)iface);
+}
+
+/**************************************************************************
+ *  IPropData_GetLastError {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_GetLastError.
+ */
+static HRESULT WINAPI
+IPropData_fnGetLastError(LPPROPDATA iface, HRESULT hRes, ULONG ulFlags,
+                         LPMAPIERROR *lppError)
+{
+    return IMAPIProp_fnGetLastError((LPMAPIPROP)iface, hRes, ulFlags, lppError);
+}
+
+/**************************************************************************
+ *  IPropData_SaveChanges {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_SaveChanges.
+ */
+static HRESULT WINAPI
+IPropData_fnSaveChanges(LPPROPDATA iface, ULONG ulFlags)
+{
+    return IMAPIProp_fnSaveChanges((LPMAPIPROP)iface, ulFlags);
+}
+
+/**************************************************************************
+ *  IPropData_GetProps {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_GetProps.
+ */
+static HRESULT WINAPI
+IPropData_fnGetProps(LPPROPDATA iface, LPSPropTagArray lpPropTags,
+                     ULONG ulFlags, ULONG *lpCount, LPSPropValue *lppProps)
+{
+    return IMAPIProp_fnGetProps((LPMAPIPROP)iface, lpPropTags, ulFlags,
+                                lpCount, lppProps);
+}
+
+/**************************************************************************
+ *  IPropData_GetPropList {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_GetPropList.
+ */
+static HRESULT WINAPI
+IPropData_fnGetPropList(LPPROPDATA iface, ULONG ulFlags,
+                                              LPSPropTagArray *lppPropTags)
+{
+    return IMAPIProp_fnGetPropList((LPMAPIPROP)iface, ulFlags, lppPropTags);
+}
+
+/**************************************************************************
+ *  IPropData_OpenProperty {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_OpenProperty.
+ */
+static HRESULT WINAPI
+IPropData_fnOpenProperty(LPPROPDATA iface, ULONG ulPropTag, LPCIID iid,
+                         ULONG ulOpts, ULONG ulFlags, LPUNKNOWN *lpUnk)
+{
+    return IMAPIProp_fnOpenProperty((LPMAPIPROP)iface, ulPropTag, iid,
+                                    ulOpts, ulFlags, lpUnk);
+}
+
+/**************************************************************************
+ *  IPropData_SetProps {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_SetProps.
+ */
+static HRESULT WINAPI
+IPropData_fnSetProps(LPPROPDATA iface, ULONG cValues, LPSPropValue lpProps,
+                     LPSPropProblemArray *lppProbs)
+{
+    return IMAPIProp_fnSetProps((LPMAPIPROP)iface, cValues, lpProps, lppProbs);
+}
+
+/**************************************************************************
+ *  IPropData_DeleteProps {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_DeleteProps.
+ */
+static HRESULT WINAPI
+IPropData_fnDeleteProps(LPPROPDATA iface, LPSPropTagArray lpPropTags,
+                        LPSPropProblemArray *lppProbs)
+{
+    return IMAPIProp_fnDeleteProps((LPMAPIPROP)iface, lpPropTags, lppProbs);
+}
+
+/**************************************************************************
+ *  IPropData_CopyTo {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_CopyTo.
+ */
+static HRESULT WINAPI
+IPropData_fnCopyTo(LPPROPDATA iface, ULONG ciidExclude, LPCIID lpIid,
+                   LPSPropTagArray lpProps, ULONG ulParam,
+                   LPMAPIPROGRESS lpProgress, LPCIID lpIface, LPVOID lpDst,
+                   ULONG ulFlags, LPSPropProblemArray *lppProbs)
+{
+    return IMAPIProp_fnCopyTo((LPMAPIPROP)iface, ciidExclude, lpIid, lpProps,
+                              ulParam, lpProgress, lpIface, lpDst,
+                              ulFlags, lppProbs);
+}
+
+/**************************************************************************
+ *  IPropData_CopyProps {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_CopyProps.
+ */
+static HRESULT WINAPI
+IPropData_fnCopyProps(LPPROPDATA iface, LPSPropTagArray lpProps,
+                      ULONG ulParam, LPMAPIPROGRESS lpProgress, LPCIID lpIface,
+                      LPVOID lpDst, ULONG ulFlags, LPSPropProblemArray *lppProbs)
+{
+    return IMAPIProp_fnCopyProps((LPMAPIPROP)iface, lpProps, ulParam,
+                                 lpProgress, lpIface, lpDst, ulFlags, lppProbs);
+}
+
+/**************************************************************************
+ *  IPropData_GetNamesFromIDs {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_GetNamesFromIDs.
+ */
+static HRESULT WINAPI
+IPropData_fnGetNamesFromIDs(LPPROPDATA iface, LPSPropTagArray *lppPropTags,
+                            LPGUID iid, ULONG ulFlags, ULONG *lpCount,
+                            LPMAPINAMEID **lpppNames)
+{
+    return IMAPIProp_fnGetNamesFromIDs((LPMAPIPROP)iface, lppPropTags, iid,
+                                       ulFlags, lpCount, lpppNames);
+}
+
+/**************************************************************************
+ *  IPropData_GetIDsFromNames {MAPI32}
+ *
+ * Inherited method from the IMAPIProp Interface.
+ * See IMAPIProp_GetIDsFromNames.
+ */
+static HRESULT WINAPI
+IPropData_fnGetIDsFromNames(LPPROPDATA iface, ULONG ulNames,
+                            LPMAPINAMEID *lppNames, ULONG ulFlags,
+                            LPSPropTagArray *lppPropTags)
+{
+    return IMAPIProp_fnGetIDsFromNames((LPMAPIPROP)iface, ulNames, lppNames,
+                                       ulFlags, lppPropTags);
+}
+
+/**************************************************************************
+ *  IPropData_HrSetObjAccess {MAPI32}
+ *
+ * Set the access level of an IPropData object.
+ *
+ * PARAMS
+ *  iface    [I] IPropData object to set the access on
+ *  ulAccess [I] Either IPROP_READONLY or IPROP_READWRITE for read or
+ *               read/write access respectively.
+ *
+ * RETURNS
+ *  Success: S_OK. The objects access level is changed.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
+ */
+static HRESULT WINAPI
+IPropData_fnHrSetObjAccess(LPPROPDATA iface, ULONG ulAccess)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+
+    TRACE("(%p,%lx)\n", iface, ulAccess);
+
+    if (!iface || ulAccess < IPROP_READONLY || ulAccess > IPROP_READWRITE)
+        return MAPI_E_INVALID_PARAMETER;
+
+    IMAPIPROP_Lock(This);
+
+    This->ulObjAccess = ulAccess;
+
+    IMAPIPROP_Unlock(This);
+    return S_OK;
+}
+
+/* Internal - determine if an access value is bad */
+static inline BOOL PROP_IsBadAccess(ULONG ulAccess)
+{
+    switch (ulAccess)
+    {
+    case IPROP_READONLY|IPROP_CLEAN:
+    case IPROP_READONLY|IPROP_DIRTY:
+    case IPROP_READWRITE|IPROP_CLEAN:
+    case IPROP_READWRITE|IPROP_DIRTY:
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/**************************************************************************
+ *  IPropData_HrSetPropAccess {MAPI32}
+ *
+ * Set the access levels for a group of property values in an IPropData object.
+ *
+ * PARAMS
+ *  iface    [I] IPropData object to set access levels in.
+ *  lpTags   [I] List of property Id's to set access for.
+ *  lpAccess [O] Access level for each property in lpTags.
+ *
+ * RETURNS
+ *  Success: S_OK. The access level of each property value in lpTags that is
+ *           present in iface is changed.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
+ *
+ * NOTES
+ *  - Each access level in lpAccess must contain at least one of IPROP_READONLY
+ *    or IPROP_READWRITE, but not both, and also IPROP_CLEAN or IPROP_DIRTY,
+ *    but not both. No other bits should be set.
+ *  - If a property Id in lpTags is not present in iface, it is ignored.
+ */
+static HRESULT WINAPI
+IPropData_fnHrSetPropAccess(LPPROPDATA iface, LPSPropTagArray lpTags,
+                            ULONG *lpAccess)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+
+    ULONG i;
+
+    TRACE("(%p,%p,%p)\n", iface, lpTags, lpAccess);
+
+    if (!iface || !lpTags || !lpAccess)
+        return MAPI_E_INVALID_PARAMETER;
+
+    for (i = 0; i < lpTags->cValues; i++)
+    {
+        if (FBadPropTag(lpTags->aulPropTag[i]) || PROP_IsBadAccess(lpAccess[i]))
+            return MAPI_E_INVALID_PARAMETER;
+    }
+
+    IMAPIPROP_Lock(This);
+
+    for (i = 0; i < lpTags->cValues; i++)
+    {
+        LPIPropDataItem item = IMAPIPROP_GetValue(This, lpTags->aulPropTag[i]);
+
+        if (item)
+            item->ulAccess = lpAccess[i];
+    }
+
+    IMAPIPROP_Unlock(This);
+    return S_OK;
+}
+
+/**************************************************************************
+ *  IPropData_HrGetPropAccess {MAPI32}
+ *
+ * Get the access levels for a group of property values in an IPropData object.
+ *
+ * PARAMS
+ *  iface     [I] IPropData object to get access levels from.
+ *  lppTags   [O] Destination for the list of property Id's in iface.
+ *  lppAccess [O] Destination for access level for each property in lppTags.
+ *
+ * RETURNS
+ *  Success: S_OK. lppTags and lppAccess contain the property Id's and the
+ *           Access level of each property value in iface.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid, or
+ *           MAPI_E_NOT_ENOUGH_MEMORY if memory allocation fails.
+ *
+ * NOTES
+ *  - *lppTags and *lppAccess should be freed with MAPIFreeBuffer() by the caller.
+ */
+static HRESULT WINAPI
+IPropData_fnHrGetPropAccess(LPPROPDATA iface, LPSPropTagArray *lppTags,
+                            ULONG **lppAccess)
+{
+    IPropDataImpl *This = (IPropDataImpl*)iface;
+    LPVOID lpMem;
+    HRESULT hRet;
+    ULONG i;
+
+    TRACE("(%p,%p,%p) stub\n", iface, lppTags, lppAccess);
+
+    if (!iface || !lppTags || !lppAccess)
+        return MAPI_E_INVALID_PARAMETER;
+
+    *lppTags = NULL;
+    *lppAccess = NULL;
+
+    IMAPIPROP_Lock(This);
+
+    hRet = This->lpAlloc(CbNewSPropTagArray(This->ulNumValues), &lpMem);
+    if (SUCCEEDED(hRet))
+    {
+        *lppTags = lpMem;
+
+        hRet = This->lpAlloc(This->ulNumValues * sizeof(ULONG), &lpMem);
+        if (SUCCEEDED(hRet))
+        {
+            struct list *cursor;
+
+            *lppAccess = lpMem;
+            (*lppTags)->cValues = This->ulNumValues;
+
+            i = 0;
+            LIST_FOR_EACH(cursor, &This->values)
+            {
+                LPIPropDataItem item = LIST_ENTRY(cursor, IPropDataItem, entry);
+                (*lppTags)->aulPropTag[i] = item->value->ulPropTag;
+                (*lppAccess)[i] = item->ulAccess;
+                i++;
+            }
+            IMAPIPROP_Unlock(This);
+            return S_OK;
+        }
+        This->lpFree(*lppTags);
+        *lppTags = 0;
+    }
+    IMAPIPROP_Unlock(This);
+    return MAPI_E_NOT_ENOUGH_MEMORY;
+}
+
+/**************************************************************************
+ *  IPropData_HrAddObjProps {MAPI32}
+ *
+ * Not documented at this time.
+ *
+ * RETURNS
+ *  An HRESULT success/failure code.
+ */
+static HRESULT WINAPI
+IPropData_fnHrAddObjProps(LPPROPDATA iface, LPSPropTagArray lpTags,
+                          LPSPropProblemArray *lppProbs)
+{
+#if 0
+    ULONG i;
+    HRESULT hRet;
+    LPSPropValue lpValues;
+#endif
+
+    FIXME("(%p,%p,%p) stub\n", iface, lpTags, lppProbs);
+
+    if (!iface || !lpTags)
+        return MAPI_E_INVALID_PARAMETER;
+
+    /* FIXME: Below is the obvious implementation, adding all the properties
+     *        in lpTags to the object. However, it doesn't appear that this
+     *        is what this function does.
+     */
+    return S_OK;
+#if 0
+    if (!lpTags->cValues)
+        return S_OK;
+
+    lpValues = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                         lpTags->cValues * sizeof(SPropValue));
+    if (!lpValues)
+        return MAPI_E_NOT_ENOUGH_MEMORY;
+
+    for (i = 0; i < lpTags->cValues; i++)
+        lpValues[i].ulPropTag = lpTags->aulPropTag[i];
+
+    hRet = IPropData_SetProps(iface, lpTags->cValues, lpValues, lppProbs);
+    HeapFree(GetProcessHeap(), 0, lpValues);
+    return hRet;
+#endif
+}
+
+static const IPropDataVtbl IPropDataImpl_vtbl =
+{
+    IPropData_fnQueryInterface,
+    IPropData_fnAddRef,
+    IPropData_fnRelease,
+    IPropData_fnGetLastError,
+    IPropData_fnSaveChanges,
+    IPropData_fnGetProps,
+    IPropData_fnGetPropList,
+    IPropData_fnOpenProperty,
+    IPropData_fnSetProps,
+    IPropData_fnDeleteProps,
+    IPropData_fnCopyTo,
+    IPropData_fnCopyProps,
+    IPropData_fnGetNamesFromIDs,
+    IPropData_fnGetIDsFromNames,
+    IPropData_fnHrSetObjAccess,
+    IPropData_fnHrSetPropAccess,
+    IPropData_fnHrGetPropAccess,
+    IPropData_fnHrAddObjProps
+};
+
+/*************************************************************************
+ * CreateIProp@24 (MAPI32.60)
+ *
+ * Create an IPropData object.
+ *
+ * PARAMS
+ *  iid         [I] GUID of the object to create. Use &IID_IMAPIPropData or NULL
+ *  lpAlloc     [I] Memory allocation function. Use MAPIAllocateBuffer()
+ *  lpMore      [I] Linked memory allocation function. Use MAPIAllocateMore()
+ *  lpFree      [I] Memory free function. Use MAPIFreeBuffer()
+ *  lpReserved  [I] Reserved, set to NULL
+ *  lppPropData [O] Destination for created IPropData object
+ *
+ * RETURNS
+ *  Success: S_OK. *lppPropData contains the newly created object.
+ *  Failure: MAPI_E_INTERFACE_NOT_SUPPORTED, if iid is non-NULL and not supported,
+ *           MAPI_E_INVALID_PARAMETER, if any parameter is invalid
+ */
+SCODE WINAPI CreateIProp(LPCIID iid, ALLOCATEBUFFER *lpAlloc,
+                         ALLOCATEMORE *lpMore, FREEBUFFER *lpFree,
+                         LPVOID lpReserved, LPPROPDATA *lppPropData)
+{
+    IPropDataImpl *lpPropData;
+    SCODE scode;
+
+    TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_guid(iid), lpAlloc, lpMore, lpFree,
+          lpReserved, lppPropData);
+
+    if (lppPropData)
+        *lppPropData = NULL;
+
+    if (iid && !IsEqualGUID(iid, &IID_IMAPIPropData))
+        return MAPI_E_INTERFACE_NOT_SUPPORTED;
+
+    if (!lpAlloc || !lpMore || !lpFree || lpReserved || !lppPropData)
+        return MAPI_E_INVALID_PARAMETER;
+
+    scode = lpAlloc(sizeof(IPropDataImpl), (LPVOID*)&lpPropData);
+
+    if (SUCCEEDED(scode))
+    {
+        lpPropData->lpVtbl = &IPropDataImpl_vtbl;
+        lpPropData->lRef = 1;
+        lpPropData->lpAlloc = lpAlloc;
+        lpPropData->lpMore = lpMore;
+        lpPropData->lpFree = lpFree;
+        lpPropData->ulObjAccess = IPROP_READWRITE;
+        lpPropData->ulNumValues = 0;
+        list_init(&lpPropData->values);
+        RtlInitializeCriticalSection(&lpPropData->cs);
+        *lppPropData = (LPPROPDATA)lpPropData;
+    }
+    return scode;
+}
diff --git a/reactos/lib/mapi32/util.c b/reactos/lib/mapi32/util.c
new file mode 100644 (file)
index 0000000..3b7fcc2
--- /dev/null
@@ -0,0 +1,823 @@
+/*
+ * MAPI Utility 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
+ */
+
+#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"
+#include "wine/unicode.h"
+#include "mapival.h"
+#include "xcmc.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)
+ *
+ * Initialise Mapi utility functions.
+ *
+ * PARAMS
+ *  ulReserved [I] Reserved, pass 0.
+ *
+ * RETURNS
+ *  Success: S_OK. Mapi utility functions may be called.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if ulReserved is not 0.
+ *
+ * NOTES
+ *  Your application does not need to call this function unless it does not
+ *  call MAPIInitialize()/MAPIUninitialize().
+ */
+SCODE WINAPI ScInitMapiUtil(ULONG ulReserved)
+{
+    FIXME("(0x%08lx)stub!\n", ulReserved);
+    if (ulReserved)
+        return MAPI_E_INVALID_PARAMETER;
+    return S_OK;
+}
+
+/**************************************************************************
+ *  DeinitMapiUtil (MAPI32.34)
+ *
+ * Uninitialise Mapi utility functions.
+ *
+ * PARAMS
+ *  None.
+ *
+ * RETURNS
+ *  Nothing.
+ *
+ * NOTES
+ *  Your application does not need to call this function unless it does not
+ *  call MAPIInitialize()/MAPIUninitialize().
+ */
+VOID WINAPI DeinitMapiUtil(void)
+{
+    FIXME("()stub!\n");
+}
+
+typedef LPVOID *LPMAPIALLOCBUFFER;
+
+/**************************************************************************
+ *  MAPIAllocateBuffer   (MAPI32.12)
+ *  MAPIAllocateBuffer@8 (MAPI32.13)
+ *
+ * Allocate a block of memory.
+ *
+ * PARAMS
+ *  cbSize    [I] Size of the block to allocate in bytes
+ *  lppBuffer [O] Destination for pointer to allocated memory
+ *
+ * RETURNS
+ *  Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
+ *           length cbSize bytes.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if lppBuffer is NULL.
+ *           MAPI_E_NOT_ENOUGH_MEMORY, if the memory allocation fails.
+ *
+ * NOTES
+ *  Memory allocated with this function should be freed with MAPIFreeBuffer().
+ *  Further allocations of memory may be linked to the pointer returned using
+ *  MAPIAllocateMore(). Linked allocations are freed when the initial pointer
+ *  is feed.
+ */
+SCODE WINAPI MAPIAllocateBuffer(ULONG cbSize, LPVOID *lppBuffer)
+{
+    LPMAPIALLOCBUFFER lpBuff;
+
+    TRACE("(%ld,%p)\n", cbSize, lppBuffer);
+
+    if (!lppBuffer)
+        return E_INVALIDARG;
+
+    lpBuff = HeapAlloc(GetProcessHeap(), 0, cbSize + sizeof(*lpBuff));
+    if (!lpBuff)
+        return MAPI_E_NOT_ENOUGH_MEMORY;
+
+    TRACE("initial allocation:%p, returning %p\n", lpBuff, lpBuff + 1);
+    *lpBuff++ = NULL;
+    *lppBuffer = lpBuff;
+    return S_OK;
+}
+
+/**************************************************************************
+ *  MAPIAllocateMore    (MAPI32.14)
+ *  MAPIAllocateMore@12 (MAPI32.15)
+ *
+ * Allocate a block of memory linked to a previous allocation.
+ *
+ * PARAMS
+ *  cbSize    [I] Size of the block to allocate in bytes
+ *  lpOrig    [I] Initial allocation to link to, from MAPIAllocateBuffer()
+ *  lppBuffer [O] Destination for pointer to allocated memory
+ *
+ * RETURNS
+ *  Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
+ *           length cbSize bytes.
+ *  Failure: MAPI_E_INVALID_PARAMETER, if lpOrig or lppBuffer is invalid.
+ *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
+ *
+ * NOTES
+ *  Memory allocated with this function and stored in *lppBuffer is freed
+ *  when lpOrig is passed to MAPIFreeBuffer(). It should not be freed independently.
+ */
+SCODE WINAPI MAPIAllocateMore(ULONG cbSize, LPVOID lpOrig, LPVOID *lppBuffer)
+{
+    LPMAPIALLOCBUFFER lpBuff = lpOrig;
+
+    TRACE("(%ld,%p,%p)\n", cbSize, lpOrig, lppBuffer);
+
+    if (!lppBuffer || !lpBuff || !--lpBuff)
+        return E_INVALIDARG;
+
+    /* Find the last allocation in the chain */
+    while (*lpBuff)
+    {
+        TRACE("linked:%p->%p\n", lpBuff, *lpBuff);
+        lpBuff = *lpBuff;
+    }
+
+    if (SUCCEEDED(MAPIAllocateBuffer(cbSize, lppBuffer)))
+    {
+        *lpBuff = ((LPMAPIALLOCBUFFER)*lppBuffer) - 1;
+        TRACE("linking %p->%p\n", lpBuff, *lpBuff);
+    }
+    return *lppBuffer ? S_OK : MAPI_E_NOT_ENOUGH_MEMORY;
+}
+
+/**************************************************************************
+ *  MAPIFreeBuffer   (MAPI32.16)
+ *  MAPIFreeBuffer@4 (MAPI32.17)
+ *
+ * Free a block of memory and any linked allocations associated with it.
+ *
+ * PARAMS
+ *  lpBuffer [I] Memory to free, returned from MAPIAllocateBuffer()
+ *
+ * RETURNS
+ *  S_OK.
+ */
+ULONG WINAPI MAPIFreeBuffer(LPVOID lpBuffer)
+{
+    LPMAPIALLOCBUFFER lpBuff = lpBuffer;
+
+    TRACE("(%p)\n", lpBuffer);
+
+    if (lpBuff && --lpBuff)
+    {
+        while (lpBuff)
+        {
+            LPVOID lpFree = lpBuff;
+
+            lpBuff = *lpBuff;
+
+            TRACE("linked:%p->%p, freeing %p\n", lpFree, lpBuff, lpFree);
+            HeapFree(GetProcessHeap(), 0, lpFree);
+        }
+    }
+    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)
+ *
+ * Ensure that an advise sink is only notified in its originating thread.
+ *
+ * PARAMS
+ *  lpSink     [I] IMAPIAdviseSink interface to be protected
+ *  lppNewSink [I] Destination for wrapper IMAPIAdviseSink interface
+ *
+ * RETURNS
+ * Success: S_OK. *lppNewSink contains a new sink to use in place of lpSink.
+ * Failure: E_INVALIDARG, if any parameter is invalid.
+ */
+HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK* lppNewSink)
+{
+    FIXME("(%p,%p)semi-stub\n", lpSink, lppNewSink);
+
+    if (!lpSink || !lppNewSink)
+        return E_INVALIDARG;
+
+    /* Don't wrap the sink for now, just copy it */
+    *lppNewSink = lpSink;
+    IMAPIAdviseSink_AddRef(lpSink);
+    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)
+{
+    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.
+ *
+ * PARAMS
+ *  lpData [O] Array to swap bytes in
+ *  ulLen  [I] Number of ULONG element to swap the bytes of
+ *
+ * RETURNS
+ *  Nothing.
+ */
+VOID WINAPI SwapPlong(PULONG lpData, ULONG ulLen)
+{
+    ULONG i;
+
+    for (i = 0; i < ulLen; i++)
+        lpData[i] = RtlUlongByteSwap(lpData[i]);
+}
+
+/*************************************************************************
+ * SwapPword@8 (MAPI32.48)
+ *
+ * Swap the bytes in a USHORT array.
+ *
+ * PARAMS
+ *  lpData [O] Array to swap bytes in
+ *  ulLen  [I] Number of USHORT element to swap the bytes of
+ *
+ * RETURNS
+ *  Nothing.
+ */
+VOID WINAPI SwapPword(PUSHORT lpData, ULONG ulLen)
+{
+    ULONG i;
+
+    for (i = 0; i < ulLen; i++)
+        lpData[i] = RtlUshortByteSwap(lpData[i]);
+}
+
+/**************************************************************************
+ *  MNLS_lstrlenW@4 (MAPI32.62)
+ *
+ * Calculate the length of a Unicode string.
+ *
+ * PARAMS
+ *  lpszStr [I] String to calculate the length of
+ *
+ * RETURNS
+ *  The length of lpszStr in Unicode characters.
+ */
+ULONG WINAPI MNLS_lstrlenW(LPCWSTR lpszStr)
+{
+    TRACE("(%s)\n", debugstr_w(lpszStr));
+    return strlenW(lpszStr);
+}
+
+/*************************************************************************
+ * MNLS_lstrcmpW@8 (MAPI32.63)
+ *
+ * Compare two Unicode strings.
+ *
+ * PARAMS
+ *  lpszLeft  [I] First string to compare
+ *  lpszRight [I] Second string to compare
+ *
+ * RETURNS
+ *  An integer less than, equal to or greater than 0, indicating that
+ *  lpszLeft is less than, the same, or greater than lpszRight.
+ */
+INT WINAPI MNLS_lstrcmpW(LPCWSTR lpszLeft, LPCWSTR lpszRight)
+{
+    TRACE("(%s,%s)\n", debugstr_w(lpszLeft), debugstr_w(lpszRight));
+    return strcmpW(lpszLeft, lpszRight);
+}
+
+/*************************************************************************
+ * MNLS_lstrcpyW@8 (MAPI32.64)
+ *
+ * Copy a Unicode string to another string.
+ *
+ * PARAMS
+ *  lpszDest [O] Destination string
+ *  lpszSrc  [I] Source string
+ *
+ * RETURNS
+ *  The length lpszDest in Unicode characters.
+ */
+ULONG WINAPI MNLS_lstrcpyW(LPWSTR lpszDest, LPCWSTR lpszSrc)
+{
+    ULONG len;
+
+    TRACE("(%p,%s)\n", lpszDest, debugstr_w(lpszSrc));
+    len = (strlenW(lpszSrc) + 1) * sizeof(WCHAR);
+    memcpy(lpszDest, lpszSrc, len);
+    return len;
+}
+
+/*************************************************************************
+ * MNLS_CompareStringW@12 (MAPI32.65)
+ *
+ * Compare two Unicode strings.
+ *
+ * PARAMS
+ *  dwCp      [I] Code page for the comparison
+ *  lpszLeft  [I] First string to compare
+ *  lpszRight [I] Second string to compare
+ *
+ * RETURNS
+ *  CSTR_LESS_THAN, CSTR_EQUAL or CSTR_GREATER_THAN, indicating that
+ *  lpszLeft is less than, the same, or greater than lpszRight.
+ */
+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));
+    ret = MNLS_lstrcmpW(lpszLeft, 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;
+}
+
+/**************************************************************************
+ *  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.
+ *
+ * PARAMS
+ *  ftLeft  [I] FILETIME to add to ftRight
+ *  ftRight [I] FILETIME to add to ftLeft
+ *
+ * RETURNS
+ *  The sum of ftLeft and ftRight
+ */
+LONGLONG WINAPI MAPI32_FtAddFt(FILETIME ftLeft, FILETIME ftRight)
+{
+    LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
+
+    return *pl + *pr;
+}
+
+/**************************************************************************
+ *  FtSubFt@16 (MAPI32.123)
+ *
+ * Subtract two FILETIME's together.
+ *
+ * PARAMS
+ *  ftLeft  [I] Initial FILETIME
+ *  ftRight [I] FILETIME to subtract from ftLeft
+ *
+ * RETURNS
+ *  The remainder after ftRight is subtracted from ftLeft.
+ */
+LONGLONG WINAPI MAPI32_FtSubFt(FILETIME ftLeft, FILETIME ftRight)
+{
+    LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
+
+    return *pr - *pl;
+}
+
+/**************************************************************************
+ *  FtMulDw@12 (MAPI32.124)
+ *
+ * Multiply a FILETIME by a DWORD.
+ *
+ * PARAMS
+ *  dwLeft  [I] DWORD to multiply with ftRight
+ *  ftRight [I] FILETIME to multiply with dwLeft
+ *
+ * RETURNS
+ *  The product of dwLeft and ftRight
+ */
+LONGLONG WINAPI MAPI32_FtMulDw(DWORD dwLeft, FILETIME ftRight)
+{
+    LONGLONG *pr = (LONGLONG*)&ftRight;
+
+    return (LONGLONG)dwLeft * (*pr);
+}
+
+/**************************************************************************
+ *  FtMulDwDw@8 (MAPI32.125)
+ *
+ * Multiply two DWORD, giving the result as a FILETIME.
+ *
+ * PARAMS
+ *  dwLeft  [I] DWORD to multiply with dwRight
+ *  dwRight [I] DWORD to multiply with dwLeft
+ *
+ * RETURNS
+ *  The product of ftMultiplier and ftMultiplicand as a FILETIME.
+ */
+LONGLONG WINAPI MAPI32_FtMulDwDw(DWORD dwLeft, DWORD dwRight)
+{
+    return (LONGLONG)dwLeft * (LONGLONG)dwRight;
+}
+
+/**************************************************************************
+ *  FtNegFt@8 (MAPI32.126)
+ *
+ * Negate a FILETIME.
+ *
+ * PARAMS
+ *  ft [I] FILETIME to negate
+ *
+ * RETURNS
+ *  The negation of ft.
+ */
+LONGLONG WINAPI MAPI32_FtNegFt(FILETIME ft)
+{
+    LONGLONG *p = (LONGLONG*)&ft;
+
+    return - *p;
+}
+
+/**************************************************************************
+ *  UlAddRef@4 (MAPI32.128)
+ *
+ * Add a reference to an object.
+ *
+ * PARAMS
+ *  lpUnk [I] Object to add a reference to.
+ *
+ * RETURNS
+ *  The new reference count of the object, or 0 if lpUnk is NULL.
+ *
+ * NOTES
+ * See IUnknown_AddRef.
+ */
+ULONG WINAPI UlAddRef(void *lpUnk)
+{
+    TRACE("(%p)\n", lpUnk);
+
+    if (!lpUnk)
+        return 0UL;
+    return IUnknown_AddRef((LPUNKNOWN)lpUnk);
+}
+
+/**************************************************************************
+ *  UlRelease@4 (MAPI32.129)
+ *
+ * Remove a reference from an object.
+ *
+ * PARAMS
+ *  lpUnk [I] Object to remove reference from.
+ *
+ * RETURNS
+ *  The new reference count of the object, or 0 if lpUnk is NULL. If lpUnk is
+ *  non-NULL and this function returns 0, the object pointed to by lpUnk has
+ *  been released.
+ *
+ * NOTES
+ * See IUnknown_Release.
+ */
+ULONG WINAPI UlRelease(void *lpUnk)
+{
+    TRACE("(%p)\n", lpUnk);
+
+    if (!lpUnk)
+        return 0UL;
+    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)
+ *
+ * Create a stream on a file.
+ *
+ * PARAMS
+ *  lpAlloc    [I] Memory allocation function
+ *  lpFree     [I] Memory free function
+ *  ulFlags    [I] Flags controlling the opening process
+ *  lpszPath   [I] Path of file to create stream on
+ *  lpszPrefix [I] Prefix of the temporary file name (if ulFlags includes SOF_UNIQUEFILENAME)
+ *  lppStream  [O] Destination for created stream
+ *
+ * RETURNS
+ * Success: S_OK. lppStream contains the new stream object
+ * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
+ *          describing the error.
+ */
+HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER lpAlloc, LPFREEBUFFER lpFree,
+                                ULONG ulFlags, LPWSTR lpszPath, LPWSTR lpszPrefix,
+                                LPSTREAM *lppStream)
+{
+    WCHAR szBuff[MAX_PATH];
+    DWORD dwMode = STGM_READWRITE, dwAttributes = 0;
+    HRESULT hRet;
+
+    TRACE("(%p,%p,0x%08lx,%s,%s,%p)\n", lpAlloc, lpFree, ulFlags,
+          debugstr_a((LPSTR)lpszPath), debugstr_a((LPSTR)lpszPrefix), lppStream);
+
+    if (lppStream)
+        *lppStream = NULL;
+
+    if (ulFlags & SOF_UNIQUEFILENAME)
+    {
+        FIXME("Should generate a temporary name\n");
+        return E_INVALIDARG;
+    }
+
+    if (!lpszPath || !lppStream)
+        return E_INVALIDARG;
+
+    /* FIXME: Should probably munge mode and attributes, and should handle
+     *        Unicode arguments (I assume MAPI_UNICODE is set in ulFlags if
+     *        we are being passed Unicode strings; MSDN doesn't say).
+     *        This implementation is just enough for Outlook97 to start.
+     */
+    MultiByteToWideChar(CP_ACP, 0, (LPSTR)lpszPath, -1, szBuff, MAX_PATH);
+    hRet = SHCreateStreamOnFileEx(szBuff, dwMode, dwAttributes, TRUE,
+                                  NULL, lppStream);
+    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)
+{
+    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;
+}
+
+/************************************************************************
+ * 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)
+ *
+ * Retrieves the configuration information for the installed CMC
+ *
+ * PARAMS
+ *  session          [I]   MAPI session handle
+ *  item             [I]   Enumerated variable that identifies which 
+ *                         configuration information is being requested
+ *  reference        [O]   Buffer where configuration information is written
+ *  config_extensions[I/O] Path of file to create stream on
+ *
+ * RETURNS
+ * A CMD define
+ */
+CMC_return_code WINAPI cmc_query_configuration(
+  CMC_session_id session,
+  CMC_enum item,
+  CMC_buffer reference,
+  CMC_extension  *config_extensions)
+{
+       FIXME("stub");
+       return CMC_E_NOT_SUPPORTED;
+}
index 047bc5b..c470ccf 100644 (file)
@@ -60,6 +60,7 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 /* other GUIDs */
 
 #include "vfw.h"
+#include "mapiguid.h"
 
 #if 0 /* FIXME */
 #include "uuids.h"
index 798b0ab..f07d28d 100644 (file)
@@ -51,6 +51,7 @@ reactos/lib/icmp              # Synced to Wine-0_9_5
 reactos/lib/imm32              # Synced to Wine-0_9_5
 reactos/lib/iphlpapi           # Out of sync
 reactos/lib/imagehlp           # Patches for BindImage need review and submission to winehq.
+reactos/lib/mapi32             # Synced to Wine-0_9_5
 reactos/lib/msvcrt20           # Out of sync
 reactos/lib/mpr                 # Synced to Wine-0_9_5
 reactos/lib/msacm              # Out of sync
diff --git a/reactos/w32api/include/mapicode.h b/reactos/w32api/include/mapicode.h
new file mode 100644 (file)
index 0000000..77172f5
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Status codes returned by MAPI
+ *
+ * Copyright (C) 2002 Aric Stewart
+ *
+ * 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
+ */
+
+#ifndef MAPICODE_H
+#define MAPICODE_H
+
+#include <winerror.h>
+
+#define MAKE_MAPI_SCODE(sev,fac,code) \
+    ((SCODE)(((ULONG)(sev)<<31)|((ULONG)(fac)<<16)|((ULONG)(code))))
+
+#define MAKE_MAPI_E(e) (MAKE_MAPI_SCODE(1,FACILITY_ITF,(e)))
+#define MAKE_MAPI_S(e) (MAKE_MAPI_SCODE(0,FACILITY_ITF,(e)))
+
+/* Errors */
+#define MAPI_E_ACCOUNT_DISABLED            ((SCODE)0x80040124)
+#define MAPI_E_AMBIGUOUS_RECIP             ((SCODE)0x80040700)
+#define MAPI_E_BAD_CHARWIDTH               ((SCODE)0x80040103)
+#define MAPI_E_BAD_COLUMN                  ((SCODE)0x80040118)
+#define MAPI_E_BAD_VALUE                   ((SCODE)0x80040301)
+#define MAPI_E_BUSY                        ((SCODE)0x8004010B)
+#define MAPI_E_CALL_FAILED                 E_FAIL
+#define MAPI_E_CANCEL                      ((SCODE)0x80040501)
+#define MAPI_E_COLLISION                   ((SCODE)0x80040604)
+#define MAPI_E_COMPUTED                    ((SCODE)0x8004011A)
+#define MAPI_E_CORRUPT_DATA                ((SCODE)0x8004011B)
+#define MAPI_E_CORRUPT_STORE               ((SCODE)0x80040600)
+#define MAPI_E_DECLINE_COPY                ((SCODE)0x80040306)
+#define MAPI_E_DISK_ERROR                  ((SCODE)0x80040116)
+#define MAPI_E_END_OF_SESSION              ((SCODE)0x80040200)
+#define MAPI_E_EXTENDED_ERROR              ((SCODE)0x80040119)
+#define MAPI_E_FAILONEPROVIDER             ((SCODE)0x8004011D)
+#define MAPI_E_FOLDER_CYCLE                ((SCODE)0x8004060B)
+#define MAPI_E_HAS_FOLDERS                 ((SCODE)0x80040609)
+#define MAPI_E_HAS_MESSAGES                ((SCODE)0x8004060A)
+#define MAPI_E_INTERFACE_NOT_SUPPORTED     E_NOINTERFACE
+#define MAPI_E_INVALID_ACCESS_TIME         ((SCODE)0x80040123)
+#define MAPI_E_INVALID_BOOKMARK            ((SCODE)0x80040405)
+#define MAPI_E_INVALID_ENTRYID             ((SCODE)0x80040107)
+#define MAPI_E_INVALID_OBJECT              ((SCODE)0x80040108)
+#define MAPI_E_INVALID_PARAMETER           E_INVALIDARG
+#define MAPI_E_INVALID_TYPE                ((SCODE)0x80040302)
+#define MAPI_E_INVALID_WORKSTATION_ACCOUNT ((SCODE)0x80040122)
+#define MAPI_E_LOGON_FAILED                ((SCODE)0x80040111)
+#define MAPI_E_MISSING_REQUIRED_COLUMN     ((SCODE)0x80040202)
+#define MAPI_E_NETWORK_ERROR               ((SCODE)0x80040115)
+#define MAPI_E_NO_ACCESS                   E_ACCESSDENIED
+#define MAPI_E_NON_STANDARD                ((SCODE)0x80040606)
+#define MAPI_E_NO_RECIPIENTS               ((SCODE)0x80040607)
+#define MAPI_E_NO_SUPPORT                  ((SCODE)0x80040102)
+#define MAPI_E_NO_SUPPRESS                 ((SCODE)0x80040602)
+#define MAPI_E_NOT_ENOUGH_DISK             ((SCODE)0x8004010D)
+#define MAPI_E_NOT_ENOUGH_MEMORY           E_OUTOFMEMORY
+#define MAPI_E_NOT_ENOUGH_RESOURCES        ((SCODE)0x8004010E)
+#define MAPI_E_NOT_FOUND                   ((SCODE)0x8004010F)
+#define MAPI_E_NOT_INITIALIZED             ((SCODE)0x80040605)
+#define MAPI_E_NOT_IN_QUEUE                ((SCODE)0x80040601)
+#define MAPI_E_NOT_ME                      ((SCODE)0x80040502)
+#define MAPI_E_OBJECT_CHANGED              ((SCODE)0x80040109)
+#define MAPI_E_OBJECT_DELETED              ((SCODE)0x8004010A)
+#define MAPI_E_PASSWORD_CHANGE_REQUIRED    ((SCODE)0x80040120)
+#define MAPI_E_PASSWORD_EXPIRED            ((SCODE)0x80040121)
+#define MAPI_E_SESSION_LIMIT               ((SCODE)0x80040112)
+#define MAPI_E_STRING_TOO_LONG             ((SCODE)0x80040105)
+#define MAPI_E_SUBMITTED                   ((SCODE)0x80040608)
+#define MAPI_E_TABLE_EMPTY                 ((SCODE)0x80040402)
+#define MAPI_E_TABLE_TOO_BIG               ((SCODE)0x80040403)
+#define MAPI_E_TIMEOUT                     ((SCODE)0x80040401)
+#define MAPI_E_TOO_BIG                     ((SCODE)0x80040305)
+#define MAPI_E_TOO_COMPLEX                 ((SCODE)0x80040117)
+#define MAPI_E_TYPE_NO_SUPPORT             ((SCODE)0x80040303)
+#define MAPI_E_UNABLE_TO_ABORT             ((SCODE)0x80040114)
+#define MAPI_E_UNABLE_TO_COMPLETE          ((SCODE)0x80040400)
+#define MAPI_E_UNCONFIGURED                ((SCODE)0x8004011C)
+#define MAPI_E_UNEXPECTED_ID               ((SCODE)0x80040307)
+#define MAPI_E_UNEXPECTED_TYPE             ((SCODE)0x80040304)
+#define MAPI_E_UNKNOWN_CPID                ((SCODE)0x8004011E)
+#define MAPI_E_UNKNOWN_ENTRYID             ((SCODE)0x80040201)
+#define MAPI_E_UNKNOWN_FLAGS               ((SCODE)0x80040106)
+#define MAPI_E_UNKNOWN_LCID                ((SCODE)0x8004011F)
+#define MAPI_E_USER_CANCEL                 ((SCODE)0x80040113)
+#define MAPI_E_VERSION                     ((SCODE)0x80040110)
+#define MAPI_E_WAIT                        ((SCODE)0x80040500)
+
+/* Warnings */
+#define MAPI_W_APPROX_COUNT                ((SCODE)0x00040482)
+#define MAPI_W_CANCEL_MESSAGE              ((SCODE)0x00040580)
+#define MAPI_W_ERRORS_RETURNED             ((SCODE)0x00040380)
+#define MAPI_W_NO_SERVICE                  ((SCODE)0x00040203)
+#define MAPI_W_PARTIAL_COMPLETION          ((SCODE)0x00040680)
+#define MAPI_W_POSITION_CHANGED            ((SCODE)0x00040481)
+
+#endif /* MAPICODE_H */
diff --git a/reactos/w32api/include/mapidefs.h b/reactos/w32api/include/mapidefs.h
new file mode 100644 (file)
index 0000000..3be0d92
--- /dev/null
@@ -0,0 +1,953 @@
+/*
+ * Copyright (C) 1998 Justin Bradford
+ *
+ * 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
+ */
+
+#ifndef MAPIDEFS_H
+#define MAPIDEFS_H
+
+#ifndef __WINESRC__
+# include <windows.h>
+#endif
+
+#include <winerror.h>
+#ifndef _OBJBASE_H_
+#include <objbase.h>
+#endif
+
+/* Some types from other headers */
+#ifndef __LHANDLE
+#define __LHANDLE
+typedef ULONG_PTR LHANDLE, *LPLHANDLE;
+#endif
+
+#ifndef _tagCY_DEFINED
+#define _tagCY_DEFINED
+typedef union tagCY
+{
+    struct
+    {
+#ifdef WORDS_BIGENDIAN
+        LONG  Hi;
+        ULONG Lo;
+#else
+        ULONG Lo;
+        LONG  Hi;
+#endif
+    } DUMMYSTRUCTNAME;
+    LONGLONG int64;
+} CY;
+typedef CY CURRENCY;
+#endif /* _tagCY_DEFINED */
+
+
+#ifndef _FILETIME_
+#define _FILETIME_
+typedef struct _FILETIME
+{
+#ifdef WORDS_BIGENDIAN
+    DWORD dwHighDateTime;
+    DWORD dwLowDateTime;
+#else
+    DWORD dwLowDateTime;
+    DWORD dwHighDateTime;
+#endif
+} FILETIME, *PFILETIME, *LPFILETIME;
+#endif
+
+/* Memory allocation routines */
+typedef SCODE (WINAPI ALLOCATEBUFFER)(ULONG,LPVOID*);
+typedef SCODE (WINAPI ALLOCATEMORE)(ULONG,LPVOID,LPVOID*);
+typedef ULONG (WINAPI FREEBUFFER)(LPVOID);
+
+typedef ALLOCATEBUFFER *LPALLOCATEBUFFER;
+typedef ALLOCATEMORE *LPALLOCATEMORE;
+typedef FREEBUFFER *LPFREEBUFFER;
+
+/* MAPI exposed interfaces */
+typedef const IID *LPCIID;
+
+typedef struct IAddrBook IAddrBook;
+typedef IAddrBook *LPADRBOOK;
+typedef struct IABContainer IABContainer;
+typedef IABContainer *LPABCONT;
+typedef struct IAttach IAttach;
+typedef IAttach *LPATTACH;
+typedef struct IDistList IDistList;
+typedef IDistList *LPDISTLIST;
+typedef struct IMailUser IMailUser;
+typedef IMailUser *LPMAILUSER;
+typedef struct IMAPIAdviseSink *LPMAPIADVISESINK;
+typedef struct IMAPIContainer IMAPIContainer;
+typedef IMAPIContainer *LPMAPICONTAINER;
+typedef struct IMAPIFolder IMAPIFolder;
+typedef IMAPIFolder *LPMAPIFOLDER;
+typedef struct IMAPIProgress IMAPIProgress;
+typedef IMAPIProgress *LPMAPIPROGRESS;
+typedef struct IMAPIStatus IMAPIStatus;
+typedef IMAPIStatus *LPMAPISTATUS;
+typedef struct IMessage IMessage;
+typedef IMessage *LPMESSAGE;
+typedef struct IMsgStore IMsgStore;
+typedef IMsgStore *LPMDB;
+typedef struct IProfSect IProfSect;
+typedef IProfSect *LPPROFSECT;
+typedef struct IProviderAdmin IProviderAdmin;
+typedef IProviderAdmin *LPPROVIDERADMIN;
+
+#ifndef MAPI_DIM
+# define MAPI_DIM 1 /* Default to one dimension for variable length arrays */
+#endif
+
+/* Flags for abFlags[0] */
+#define MAPI_NOTRESERVED 0x08
+#define MAPI_NOW         0x10
+#define MAPI_THISSESSION 0x20
+#define MAPI_NOTRECIP    0x40
+#define MAPI_SHORTTERM   0x80
+
+/* Flags for abFlags[1]  */
+#define MAPI_COMPOUND    0x80
+
+typedef struct _ENTRYID
+{
+    BYTE abFlags[4];
+    BYTE ab[MAPI_DIM];
+} ENTRYID, *LPENTRYID;
+
+/* MAPI GUID's */
+typedef struct _MAPIUID
+{
+    BYTE ab[sizeof(GUID)];
+} MAPIUID, *LPMAPIUID;
+
+#define IsEqualMAPIUID(pl,pr) (!memcmp((pl),(pr),sizeof(MAPIUID)))
+
+#define MAPI_ONE_OFF_UID { 0x81,0x2b,0x1f,0xa4,0xbe,0xa3,0x10,0x19,0x9d,0x6e, \
+                           0x00,0xdd,0x01,0x0f,0x54,0x02 }
+#define MAPI_ONE_OFF_UNICODE      0x8000
+#define MAPI_ONE_OFF_NO_RICH_INFO 0x0001
+
+/* Object types */
+#define MAPI_STORE    1U
+#define MAPI_ADDRBOOK 2U
+#define MAPI_FOLDER   3U
+#define MAPI_ABCONT   4U
+#define MAPI_MESSAGE  5U
+#define MAPI_MAILUSER 6U
+#define MAPI_ATTACH   7U
+#define MAPI_DISTLIST 8U
+#define MAPI_PROFSECT 9U
+#define MAPI_STATUS   10U
+#define MAPI_SESSION  11U
+#define MAPI_FORMINFO 12U
+
+/* Flags for various calls */
+#define MAPI_MODIFY                   0x00000001U /* Object can be modified */
+#define MAPI_ACCESS_MODIFY            MAPI_MODIFY /* Want write access */
+#define MAPI_ACCESS_READ              0x00000002U /* Want read access */
+#define MAPI_ACCESS_DELETE            0x00000004U /* Want delete access */
+#define MAPI_ACCESS_CREATE_HIERARCHY  0x00000008U
+#define MAPI_ACCESS_CREATE_CONTENTS   0x00000010U
+#define MAPI_ACCESS_CREATE_ASSOCIATED 0x00000020U
+#define MAPI_UNICODE                  0x80000000U /* Strings in this call are Unicode */
+
+#if defined (UNICODE) || defined (__WINESRC__)
+#define fMapiUnicode MAPI_UNICODE
+#else
+#define fMapiUnicode 0U
+#endif
+
+/* Types of message receivers */
+#ifndef MAPI_ORIG
+#define MAPI_ORIG      0          /* The original author */
+#define MAPI_TO        1          /* The primary message receiver */
+#define MAPI_CC        2          /* A carbon copy receiver */
+#define MAPI_BCC       3          /* A blind carbon copy receiver */
+#define MAPI_P1        0x10000000 /* A message resend */
+#define MAPI_SUBMITTED 0x80000000 /* This message has already been sent */
+#endif
+
+#ifndef cchProfileNameMax
+#define cchProfileNameMax 64 /* Maximum length of a profile name */
+#define cchProfilePassMax 64 /* Maximum length of a profile password */
+#endif
+
+/* Properties: The are the contents of cells in MAPI tables, as well as the
+ * values returned when object properties are queried.
+ */
+
+/* Property types */
+#define PT_UNSPECIFIED 0U
+#define PT_NULL        1U
+#define PT_I2          2U
+#define PT_SHORT       PT_I2
+#define PT_LONG        3U
+#define PT_I4          PT_LONG
+#define PT_R4          4U
+#define PT_FLOAT       PT_R4
+#define PT_DOUBLE      5U
+#define PT_R8          PT_DOUBLE
+#define PT_CURRENCY    6U
+#define PT_APPTIME     7U
+#define PT_ERROR       10U
+#define PT_BOOLEAN     11U
+#define PT_OBJECT      13U
+#define PT_I8          20U
+#define PT_LONGLONG    PT_I8
+#define PT_STRING8     30U
+#define PT_UNICODE     31U
+#define PT_SYSTIME     64U
+#define PT_CLSID       72U
+#define PT_BINARY      258U
+
+#define MV_FLAG     0x1000 /* This property type is multi-valued (an array) */
+#define MV_INSTANCE 0x2000
+#define MVI_FLAG    (MV_FLAG|MV_INSTANCE)
+#define MVI_PROP(t) ((t)|MVI_FLAG)
+
+#ifndef __WINESRC__
+# ifdef UNICODE
+# define PT_TSTRING      PT_UNICODE
+# define PT_MV_TSTRING   (MV_FLAG|PT_UNICODE)
+# define LPSZ            lpszW
+# define LPPSZ           lppszW
+# define MVSZ            MVszW
+# else
+# define PT_TSTRING      PT_STRING8
+# define PT_MV_TSTRING   (MV_FLAG|PT_STRING8)
+# define LPSZ            lpszA
+# define LPPSZ           lppszA
+# define MVSZ            MVszA
+# endif
+#endif
+
+#define PROP_TYPE_MASK  0xFFFFU
+#define PROP_TYPE(t)    ((t) & PROP_TYPE_MASK)
+#define PROP_ID(t)      ((t) >> 16)
+#define PROP_TAG(t,id)  (((id) << 16) | t)
+#define PROP_ID_NULL    0
+#define PROP_ID_INVALID 0xFFFF
+#define PR_NULL         PROP_TAG(PT_NULL, PROP_ID_NULL)
+
+#define CHANGE_PROP_TYPE(t,typ) ((0xFFFF0000 & t) | typ)
+
+/* Multi-valued property types */
+#define PT_MV_I2       (MV_FLAG|PT_I2)
+#define PT_MV_SHORT    PT_MV_I2
+#define PT_MV_LONG     (MV_FLAG|PT_LONG)
+#define PT_MV_I4       PT_MV_LONG
+#define PT_MV_R4       (MV_FLAG|PT_R4)
+#define PT_MV_FLOAT    PT_MV_R4
+#define PT_MV_DOUBLE   (MV_FLAG|PT_DOUBLE)
+#define PT_MV_R8       PT_MV_DOUBLE
+#define PT_MV_CURRENCY (MV_FLAG|PT_CURRENCY)
+#define PT_MV_APPTIME  (MV_FLAG|PT_APPTIME)
+#define PT_MV_SYSTIME  (MV_FLAG|PT_SYSTIME)
+#define PT_MV_STRING8  (MV_FLAG|PT_STRING8)
+#define PT_MV_BINARY   (MV_FLAG|PT_BINARY)
+#define PT_MV_UNICODE  (MV_FLAG|PT_UNICODE)
+#define PT_MV_CLSID    (MV_FLAG|PT_CLSID)
+#define PT_MV_I8       (MV_FLAG|PT_I8)
+#define PT_MV_LONGLONG PT_MV_I8
+
+
+/* The property tag structure. This describes a list of columns */
+typedef struct _SPropTagArray
+{
+    ULONG cValues;              /* Number of elements in aulPropTag */
+    ULONG aulPropTag[MAPI_DIM]; /* Property tags */
+} SPropTagArray, *LPSPropTagArray;
+
+#define CbNewSPropTagArray(c) (offsetof(SPropTagArray,aulPropTag)+(c)*sizeof(ULONG))
+#define CbSPropTagArray(p)    CbNewSPropTagArray((p)->cValues)
+#define SizedSPropTagArray(n,id) \
+    struct _SPropTagArray_##id { ULONG cValues; ULONG aulPropTag[n]; } id
+
+/* Multi-valued PT_APPTIME property value */
+typedef struct _SAppTimeArray
+{
+    ULONG   cValues; /* Number of doubles in lpat */
+    double *lpat;    /* Pointer to double array of length cValues */
+} SAppTimeArray;
+
+/* PT_BINARY property value */
+typedef struct _SBinary
+{
+    ULONG  cb;  /* Number of bytes in lpb */
+    LPBYTE lpb; /* Pointer to byte array of length cb */
+} SBinary, *LPSBinary;
+
+/* Multi-valued PT_BINARY property value */
+typedef struct _SBinaryArray
+{
+    ULONG    cValues; /* Number of SBinarys in lpbin */
+    SBinary *lpbin;   /* Pointer to SBinary array of length cValues */
+} SBinaryArray;
+
+typedef SBinaryArray ENTRYLIST, *LPENTRYLIST;
+
+/* Multi-valued PT_CY property value */
+typedef struct _SCurrencyArray
+{
+    ULONG  cValues; /* Number of CYs in lpcu */
+    CY    *lpcur;   /* Pointer to CY array of length cValues */
+} SCurrencyArray;
+
+/* Multi-valued PT_SYSTIME property value */
+typedef struct _SDateTimeArray
+{
+    ULONG     cValues; /* Number of FILETIMEs in lpft */
+    FILETIME *lpft;    /* Pointer to FILETIME array of length cValues */
+} SDateTimeArray;
+
+/* Multi-valued PT_DOUBLE property value */
+typedef struct _SDoubleArray
+{
+    ULONG   cValues; /* Number of doubles in lpdbl */
+    double *lpdbl;   /* Pointer to double array of length cValues */
+} SDoubleArray;
+
+/* Multi-valued PT_CLSID property value */
+typedef struct _SGuidArray
+{
+    ULONG cValues; /* Number of GUIDs in lpguid */
+    GUID *lpguid;  /* Pointer to GUID array of length cValues */
+} SGuidArray;
+
+/* Multi-valued PT_LONGLONG property value */
+typedef struct _SLargeIntegerArray
+{
+    ULONG          cValues; /* Number of long64s in lpli */
+    LARGE_INTEGER *lpli;    /* Pointer to long64 array of length cValues */
+} SLargeIntegerArray;
+
+/* Multi-valued PT_LONG property value */
+typedef struct _SLongArray
+{
+    ULONG  cValues; /* Number of longs in lpl */
+    LONG  *lpl;     /* Pointer to long array of length cValues */
+} SLongArray;
+
+/* Multi-valued PT_STRING8 property value */
+typedef struct _SLPSTRArray
+{
+    ULONG  cValues; /* Number of Ascii strings in lppszA */
+    LPSTR *lppszA;  /* Pointer to Ascii string array of length cValues */
+} SLPSTRArray;
+
+/* Multi-valued PT_FLOAT property value */
+typedef struct _SRealArray
+{
+    ULONG cValues; /* Number of floats in lpflt */
+    float *lpflt;  /* Pointer to float array of length cValues */
+} SRealArray;
+
+/* Multi-valued PT_SHORT property value */
+typedef struct _SShortArray
+{
+    ULONG      cValues; /* Number of shorts in lpb */
+    short int *lpi;     /* Pointer to short array of length cValues */
+} SShortArray;
+
+/* Multi-valued PT_UNICODE property value */
+typedef struct _SWStringArray
+{
+    ULONG   cValues; /* Number of Unicode strings in lppszW */
+    LPWSTR *lppszW;  /* Pointer to Unicode string array of length cValues */
+} SWStringArray;
+
+/* A property value */
+typedef union _PV
+{
+    short int          i;
+    LONG               l;
+    ULONG              ul;
+    float              flt;
+    double             dbl;
+    unsigned short     b;
+    CY                 cur;
+    double             at;
+    FILETIME           ft;
+    LPSTR              lpszA;
+    SBinary            bin;
+    LPWSTR             lpszW;
+    LPGUID             lpguid;
+    LARGE_INTEGER      li;
+    SShortArray        MVi;
+    SLongArray         MVl;
+    SRealArray         MVflt;
+    SDoubleArray       MVdbl;
+    SCurrencyArray     MVcur;
+    SAppTimeArray      MVat;
+    SDateTimeArray     MVft;
+    SBinaryArray       MVbin;
+    SLPSTRArray        MVszA;
+    SWStringArray      MVszW;
+    SGuidArray         MVguid;
+    SLargeIntegerArray MVli;
+    SCODE              err;
+    LONG               x;
+} __UPV;
+
+/* Property value structure. This is essentially a mini-Variant */
+typedef struct _SPropValue
+{
+    ULONG     ulPropTag;  /* The property type */
+    ULONG     dwAlignPad; /* Alignment, treat as reserved */
+    union _PV Value;      /* The property value */
+} SPropValue, *LPSPropValue;
+
+/* Structure describing a table row (a collection of property values) */
+typedef struct _SRow
+{
+    ULONG        ulAdrEntryPad; /* Padding, treat as reserved */
+    ULONG        cValues;       /* Count of property values in lpProbs */
+    LPSPropValue lpProps;       /* Pointer to an array of property values of length cValues */
+} SRow, *LPSRow;
+
+/* Structure describing a set of table rows */
+typedef struct _SRowSet
+{
+    ULONG cRows;          /* Count of rows in aRow */
+    SRow  aRow[MAPI_DIM]; /* Array of rows of length cRows */
+} SRowSet, *LPSRowSet;
+
+#define CbNewSRowSet(c) (offsetof(SRowSet,aRow)+(c)*sizeof(SRow))
+#define CbSRowSet(p)    CbNewSRowSet((p)->cRows)
+#define SizedSRowSet(n,id) \
+    struct _SRowSet_##id { ULONG cRows; SRow aRow[n]; } id
+
+/* Structure describing a problem with a property */
+typedef struct _SPropProblem
+{
+    ULONG ulIndex;   /* Index of the property */
+    ULONG ulPropTag; /* Proprty tag of the property */
+    SCODE scode;     /* Error code of the problem */
+} SPropProblem, *LPSPropProblem;
+
+/* A collection of property problems */
+typedef struct _SPropProblemArray
+{
+    ULONG        cProblem;           /* Number of problems in aProblem */
+    SPropProblem aProblem[MAPI_DIM]; /* Array of problems of length cProblem */
+} SPropProblemArray, *LPSPropProblemArray;
+
+/* FPropContainsProp flags */
+#define FL_FULLSTRING     0x00000ul /* Exact string match */
+#define FL_SUBSTRING      0x00001ul /* Substring match */
+#define FL_PREFIX         0x00002ul /* Prefix match */
+#define FL_IGNORECASE     0x10000ul /* Case insensitive */
+#define FL_IGNORENONSPACE 0x20000ul /* Ignore non spacing characters */
+#define FL_LOOSE          0x40000ul /* Try very hard to match */
+
+
+/* Table types returned by IMAPITable_GetStatus() */
+#define TBLTYPE_SNAPSHOT 0U /* Table is fixed at creation time and contents do not change */
+#define TBLTYPE_KEYSET   1U /* Table has a fixed number of rows, but row values may change */
+#define TBLTYPE_DYNAMIC  2U /* Table values and the number of rows may change */
+
+/* Table status returned by IMAPITable_GetStatus() */
+#define TBLSTAT_COMPLETE       0U  /* All operations have completed (normal status) */
+#define TBLSTAT_QCHANGED       7U  /* Table data has changed as expected */
+#define TBLSTAT_SORTING        9U  /* Table is being asynchronously sorted */
+#define TBLSTAT_SORT_ERROR     10U /* An error occurred while sorting the table */
+#define TBLSTAT_SETTING_COLS   11U /* Table columns are being asynchronously changed */
+#define TBLSTAT_SETCOL_ERROR   13U /* An error occurred during column changing */
+#define TBLSTAT_RESTRICTING    14U /* Table rows are being asynchronously restricted */
+#define TBLSTAT_RESTRICT_ERROR 15U /* An error occurred during row restriction */
+
+/* Flags for IMAPITable operations that can be asynchronous */
+#define TBL_NOWAIT 1U         /* Perform the operation asynchronously */
+#define TBL_BATCH  2U         /* Perform the operation when the results are needed */
+#define TBL_ASYNC  TBL_NOWAIT /* Synonym for TBL_NOWAIT */
+
+/* Flags for IMAPITable_FindRow() */
+#define DIR_BACKWARD 1U /* Read rows backwards from the start bookmark */
+
+/* Table bookmarks */
+typedef ULONG BOOKMARK;
+
+#define BOOKMARK_BEGINNING ((BOOKMARK)0) /* The first row */
+#define BOOKMARK_CURRENT   ((BOOKMARK)1) /* The curent table row */
+#define BOOKMARK_END       ((BOOKMARK)2) /* The last row */
+
+/* Row restrictions */
+typedef struct _SRestriction* LPSRestriction;
+
+typedef struct _SAndRestriction
+{
+    ULONG          cRes;
+    LPSRestriction lpRes;
+} SAndRestriction;
+
+typedef struct _SBitMaskRestriction
+{
+    ULONG relBMR;
+    ULONG ulPropTag;
+    ULONG ulMask;
+} SBitMaskRestriction;
+
+typedef struct _SCommentRestriction
+{
+    ULONG          cValues;
+    LPSRestriction lpRes;
+    LPSPropValue   lpProp;
+} SCommentRestriction;
+
+#define RELOP_LT 0U
+#define RELOP_LE 1U
+#define RELOP_GT 2U
+#define RELOP_GE 3U
+#define RELOP_EQ 4U
+#define RELOP_NE 5U
+#define RELOP_RE 6U
+
+typedef struct _SComparePropsRestriction
+{
+    ULONG relop;
+    ULONG ulPropTag1;
+    ULONG ulPropTag2;
+} SComparePropsRestriction;
+
+typedef struct _SContentRestriction
+{
+    ULONG        ulFuzzyLevel;
+    ULONG        ulPropTag;
+    LPSPropValue lpProp;
+} SContentRestriction;
+
+typedef struct _SExistRestriction
+{
+    ULONG ulReserved1;
+    ULONG ulPropTag;
+    ULONG ulReserved2;
+} SExistRestriction;
+
+typedef struct _SNotRestriction
+{
+    ULONG          ulReserved;
+    LPSRestriction lpRes;
+} SNotRestriction;
+
+typedef struct _SOrRestriction
+{
+    ULONG          cRes;
+    LPSRestriction lpRes;
+} SOrRestriction;
+
+typedef struct _SPropertyRestriction
+{
+    ULONG        relop;
+    ULONG        ulPropTag;
+    LPSPropValue lpProp;
+} SPropertyRestriction;
+
+typedef struct _SSizeRestriction
+{
+    ULONG relop;
+    ULONG ulPropTag;
+    ULONG cb;
+} SSizeRestriction;
+
+typedef struct _SSubRestriction
+{
+    ULONG          ulSubObject;
+    LPSRestriction lpRes;
+} SSubRestriction;
+
+/* Restriction types */
+#define RES_AND            0U
+#define RES_OR             1U
+#define RES_NOT            2U
+#define RES_CONTENT        3U
+#define RES_PROPERTY       4U
+#define RES_COMPAREPROPS   5U
+#define RES_BITMASK        6U
+#define RES_SIZE           7U
+#define RES_EXIST          8U
+#define RES_SUBRESTRICTION 9U
+#define RES_COMMENT        10U
+
+typedef struct _SRestriction
+{
+    ULONG rt;
+    union
+    {
+        SAndRestriction          resAnd;
+        SBitMaskRestriction      resBitMask;
+        SCommentRestriction      resComment;
+        SComparePropsRestriction resCompareProps;
+        SContentRestriction      resContent;
+        SExistRestriction        resExist;
+        SNotRestriction          resNot;
+        SOrRestriction           resOr;
+        SPropertyRestriction     resProperty;
+        SSizeRestriction         resSize;
+        SSubRestriction          resSub;
+    } res;
+} SRestriction;
+
+/* Errors */
+typedef struct _MAPIERROR
+{
+    ULONG  ulVersion;       /* Mapi version */
+#if defined (UNICODE) || defined (__WINESRC__)
+    LPWSTR lpszError;       /* Error and component strings. These are Ascii */
+    LPWSTR lpszComponent;   /* unless the MAPI_UNICODE flag is passed in */
+#else
+    LPSTR  lpszError;
+    LPSTR  lpszComponent;
+#endif
+    ULONG  ulLowLevelError;
+    ULONG  ulContext;
+} MAPIERROR, *LPMAPIERROR;
+
+/* Sorting */
+#define TABLE_SORT_ASCEND  0U
+#define TABLE_SORT_DESCEND 1U
+#define TABLE_SORT_COMBINE 2U
+
+typedef struct _SSortOrder
+{
+    ULONG ulPropTag;
+    ULONG ulOrder;
+} SSortOrder, *LPSSortOrder;
+
+typedef struct _SSortOrderSet
+{
+    ULONG      cSorts;
+    ULONG      cCategories;
+    ULONG      cExpanded;
+    SSortOrder aSort[MAPI_DIM];
+} SSortOrderSet, * LPSSortOrderSet;
+
+#define MNID_ID     0
+#define MNID_STRING 1
+
+typedef struct _MAPINAMEID
+{
+    LPGUID lpguid;
+    ULONG ulKind;
+    union
+    {
+        LONG lID;
+        LPWSTR lpwstrName;
+    } Kind;
+} MAPINAMEID, *LPMAPINAMEID;
+
+/* Desired notification types (bitflags) */
+#define fnevCriticalError        0x00000001UL
+#define fnevNewMail              0x00000002UL
+#define fnevObjectCreated        0x00000004UL
+#define fnevObjectDeleted        0x00000008UL
+#define fnevObjectModified       0x00000010UL
+#define fnevObjectMoved          0x00000020UL
+#define fnevObjectCopied         0x00000040UL
+#define fnevSearchComplete       0x00000080UL
+#define fnevTableModified        0x00000100UL
+#define fnevStatusObjectModified 0x00000200UL
+#define fnevReservedForMapi      0x40000000UL
+#define fnevExtended             0x80000000UL
+
+/* Type of notification event */
+#define TABLE_CHANGED       1U
+#define TABLE_ERROR         2U
+#define TABLE_ROW_ADDED     3U
+#define TABLE_ROW_DELETED   4U
+#define TABLE_ROW_MODIFIED  5U
+#define TABLE_SORT_DONE     6U
+#define TABLE_RESTRICT_DONE 7U
+#define TABLE_SETCOL_DONE   8U
+#define TABLE_RELOAD        9U
+
+/* fnevCriticalError notification */
+typedef struct _ERROR_NOTIFICATION
+{
+    ULONG       cbEntryID;
+    LPENTRYID   lpEntryID;
+    SCODE       scode;
+    ULONG       ulFlags;
+    LPMAPIERROR lpMAPIError;
+} ERROR_NOTIFICATION;
+
+/* fnevNewMail notification */
+typedef struct _NEWMAIL_NOTIFICATION
+{
+    ULONG     cbEntryID;
+    LPENTRYID lpEntryID;
+    ULONG     cbParentID;
+    LPENTRYID lpParentID;
+    ULONG     ulFlags;
+#if defined (UNICODE) || defined (__WINESRC__)
+    LPWSTR    lpszMessageClass;
+#else
+    LPSTR     lpszMessageClass;
+#endif
+    ULONG     ulMessageFlags;
+} NEWMAIL_NOTIFICATION;
+
+/* fnevObjectCreated/Deleted/Modified/Moved/Copied notification */
+typedef struct _OBJECT_NOTIFICATION
+{
+    ULONG           cbEntryID;
+    LPENTRYID       lpEntryID;
+    ULONG           ulObjType;
+    ULONG           cbParentID;
+    LPENTRYID       lpParentID;
+    ULONG           cbOldID;
+    LPENTRYID       lpOldID;
+    ULONG           cbOldParentID;
+    LPENTRYID       lpOldParentID;
+    LPSPropTagArray lpPropTagArray;
+} OBJECT_NOTIFICATION;
+
+/* fnevTableModified notification */
+typedef struct _TABLE_NOTIFICATION
+{
+    ULONG      ulTableEvent;
+    HRESULT    hResult;
+    SPropValue propIndex;
+    SPropValue propPrior;
+    SRow       row;
+    ULONG      ulPad;
+} TABLE_NOTIFICATION;
+
+/* fnevExtended notification */
+typedef struct _EXTENDED_NOTIFICATION
+{
+    ULONG  ulEvent;
+    ULONG  cb;
+    LPBYTE pbEventParameters;
+} EXTENDED_NOTIFICATION;
+
+/* fnevStatusObjectModified notification */
+typedef struct
+{
+    ULONG        cbEntryID;
+    LPENTRYID    lpEntryID;
+    ULONG        cValues;
+    LPSPropValue lpPropVals;
+} STATUS_OBJECT_NOTIFICATION;
+
+/* The notification structure passed to advise sinks */
+typedef struct _NOTIFICATION
+{
+    ULONG ulEventType;
+    ULONG ulAlignPad;
+    union
+    {
+        ERROR_NOTIFICATION         err;
+        NEWMAIL_NOTIFICATION       newmail;
+        OBJECT_NOTIFICATION        obj;
+        TABLE_NOTIFICATION         tab;
+        EXTENDED_NOTIFICATION      ext;
+        STATUS_OBJECT_NOTIFICATION statobj;
+    } info;
+} NOTIFICATION, *LPNOTIFICATION;
+
+typedef LONG (WINAPI NOTIFCALLBACK)(LPVOID,ULONG,LPNOTIFICATION);
+typedef NOTIFCALLBACK *LPNOTIFCALLBACK;
+
+/*****************************************************************************
+ * IMAPITable interface
+ *
+ * This is the read-only 'view' over an I(MAPI)TableData object.
+ */
+#define INTERFACE IMAPITable
+DECLARE_INTERFACE_(IMAPITable,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IMAPITable methods ***/
+    STDMETHOD(GetLastError)(THIS_ HRESULT hRes, ULONG ulFlags, LPMAPIERROR *lppError) PURE;
+    STDMETHOD(Advise)(THIS_ ULONG ulMask, LPMAPIADVISESINK lpSink, ULONG *lpCxn) PURE;
+    STDMETHOD(Unadvise)(THIS_ ULONG ulCxn) PURE;
+    STDMETHOD(GetStatus)(THIS_ ULONG *lpStatus, ULONG *lpType) PURE;
+    STDMETHOD(SetColumns)(THIS_ LPSPropTagArray lpProps, ULONG ulFlags) PURE;
+    STDMETHOD(QueryColumns)(THIS_ ULONG ulFlags, LPSPropTagArray *lpCols) PURE;
+    STDMETHOD(GetRowCount)(THIS_ ULONG ulFlags, ULONG *lpCount) PURE;
+    STDMETHOD(SeekRow)(THIS_ BOOKMARK lpStart, LONG lRows, LONG *lpSeeked) PURE;
+    STDMETHOD(SeekRowApprox)(THIS_ ULONG ulNum, ULONG ulDenom) PURE;
+    STDMETHOD(QueryPosition)(THIS_ ULONG *lpRow, ULONG *lpNum, ULONG *lpDenom) PURE;
+    STDMETHOD(FindRow)(THIS_ LPSRestriction lpRestrict, BOOKMARK lpOrigin, ULONG ulFlags) PURE;
+    STDMETHOD(Restrict)(THIS_ LPSRestriction lpRestrict, ULONG ulFlags) PURE;
+    STDMETHOD(CreateBookmark)(THIS_ BOOKMARK *lppPos) PURE;
+    STDMETHOD(FreeBookmark)(THIS_ BOOKMARK lpPos) PURE;
+    STDMETHOD(SortTable)(THIS_ LPSSortOrderSet lpSortOpts, ULONG ulFlags) PURE;
+    STDMETHOD(QuerySortOrder)(THIS_ LPSSortOrderSet *lppSortOpts) PURE;
+    STDMETHOD(QueryRows)(THIS_ LONG lRows, ULONG ulFlags, LPSRowSet *lppRows) PURE;
+    STDMETHOD(Abort) (THIS) PURE;
+    STDMETHOD(ExpandRow)(THIS_ ULONG cbKey, LPBYTE lpKey, ULONG ulRows,
+                         ULONG ulFlags, LPSRowSet *lppRows, ULONG *lpMore) PURE;
+    STDMETHOD(CollapseRow)(THIS_ ULONG cbKey, LPBYTE lpKey, ULONG ulFlags, ULONG *lpRows) PURE;
+    STDMETHOD(WaitForCompletion)(THIS_ ULONG ulFlags, ULONG ulTime, ULONG *lpState) PURE;
+    STDMETHOD(GetCollapseState)(THIS_ ULONG ulFlags, ULONG cbKey, LPBYTE lpKey,
+                                ULONG *lpStateLen, LPBYTE *lpState) PURE;
+    STDMETHOD(SetCollapseState)(THIS_ ULONG ulFlags, ULONG ulLen,
+                                LPBYTE lpStart, BOOKMARK *lppWhere) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+        /*** IUnknown methods ***/
+#define IMAPITable_QueryInterface(p,a,b)         (p)->lpVtbl->QueryInterface(p,a,b)
+#define IMAPITable_AddRef(p)                     (p)->lpVtbl->AddRef(p)
+#define IMAPITable_Release(p)                    (p)->lpVtbl->Release(p)
+        /*** IMAPITable methods ***/
+#define IMAPITable_GetLastError(p,a,b,c)         (p)->lpVtbl->GetLastError(p,a,b,c)
+#define IMAPITable_Advise(p,a,b,c)               (p)->lpVtbl->Advise(p,a,b,c)
+#define IMAPITable_Unadvise(p,a)                 (p)->lpVtbl->Unadvise(p,a)
+#define IMAPITable_GetStatus(p,a,b)              (p)->lpVtbl->GetStatus(p,a,b)
+#define IMAPITable_SetColumns(p,a,b)             (p)->lpVtbl->SetColumns(p,a,b)
+#define IMAPITable_QueryColumns(p,a,b)           (p)->lpVtbl->QueryColumns(p,a,b)
+#define IMAPITable_GetRowCount(p,a,b)            (p)->lpVtbl->GetRowCount(p,a,b)
+#define IMAPITable_SeekRow(p,a,b)                (p)->lpVtbl->SeekRow(p,a,b)
+#define IMAPITable_SeekRowApprox(p,a,b)          (p)->lpVtbl->SeekRowApprox(p,a,b)
+#define IMAPITable_QueryPosition(p,a,b)          (p)->lpVtbl->QueryPosition(p,a,b)
+#define IMAPITable_FindRow(p,a,b,c)              (p)->lpVtbl->FindRow(p,a,b,c)
+#define IMAPITable_Restrict(p,a,b)               (p)->lpVtbl->Recstrict(p,a,b)
+#define IMAPITable_CreateBookmark(p,a)           (p)->lpVtbl->CreateBookmark(p,a)
+#define IMAPITable_FreeBookmark(p,a)             (p)->lpVtbl->FreeBookmark(p,a)
+#define IMAPITable_SortTable(p,a,b)              (p)->lpVtbl->SortTable(p,a,b)
+#define IMAPITable_QuerySortOrder(p,a)           (p)->lpVtbl->QuerySortOrder(p,a)
+#define IMAPITable_QueryRows(p,a,b,c)            (p)->lpVtbl->QueryRows(p,a,b,c)
+#define IMAPITable_Abort(p)                      (p)->lpVtbl->Abort(p)
+#define IMAPITable_ExpandRow(p,a,b,c,d,e,f)      (p)->lpVtbl->ExpandRow(p,a,b,c,d,e,f)
+#define IMAPITable_CollapseRow(p,a,b,c,d)        (p)->lpVtbl->CollapseRow(p,a,b,c,d)
+#define IMAPITable_WaitForCompletion(p,a,b,c)    (p)->lpVtbl->WaitForCompletion(p,a,b,c)
+#define IMAPITable_GetCollapseState(p,a,b,c,d,e) (p)->lpVtbl->GetCollapseState(p,a,b,c,d,e)
+#define IMAPITable_SetCollapseState(p,a,b,c,d)   (p)->lpVtbl->SetCollapseState(p,a,b,c,d)
+#endif
+
+typedef IMAPITable *LPMAPITABLE;
+
+/*****************************************************************************
+ * IMAPIAdviseSink interface
+ */
+#define INTERFACE IMAPIAdviseSink
+DECLARE_INTERFACE_(IMAPIAdviseSink,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IMAPIAdviseSink methods ***/
+    STDMETHOD(OnNotify)(THIS_ ULONG NumNotif, LPNOTIFICATION lpNotif) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+        /*** IUnknown methods ***/
+#define IMAPIAdviseSink_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IMAPIAdviseSink_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IMAPIAdviseSink_Release(p)            (p)->lpVtbl->Release(p)
+        /*** IMAPIAdviseSink methods ***/
+#define IMAPIAdviseSink_OnNotify(p,a,b)       (p)->lpVtbl->OnNotify(p,a,b)
+#endif
+
+/*****************************************************************************
+ * IMAPIProp interface
+ */
+#define INTERFACE IMAPIProp
+DECLARE_INTERFACE_(IMAPIProp,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IMAPIProp methods ***/
+    STDMETHOD(GetLastError)(THIS_ HRESULT hRes, ULONG ulFlags, LPMAPIERROR *lppErr) PURE;
+    STDMETHOD(SaveChanges)(THIS_ ULONG ulFlags) PURE;
+    STDMETHOD(GetProps)(THIS_ LPSPropTagArray lpPropTags, ULONG ulFlags, ULONG *lpValues, LPSPropValue *lppProps) PURE;
+    STDMETHOD(GetPropList)(THIS_ ULONG  ulFlags, LPSPropTagArray *lppPropTagArray) PURE;
+    STDMETHOD(OpenProperty)(THIS_ ULONG ulPropTag, LPCIID lpIid, ULONG ulOpts, ULONG ulFlags, LPUNKNOWN *lppUnk) PURE;
+    STDMETHOD(SetProps)(THIS_ ULONG cValues, LPSPropValue lpProps, LPSPropProblemArray *lppProbs) PURE;
+    STDMETHOD(DeleteProps)(THIS_ LPSPropTagArray lpPropTags, LPSPropProblemArray *lppProbs) PURE;
+    STDMETHOD(CopyTo)(THIS_ ULONG ciidExclude, LPCIID lpIid, LPSPropTagArray lpProps, ULONG ulParam,
+                      LPMAPIPROGRESS lpProgress, LPCIID lpIface,LPVOID lpDest, ULONG ulFlags,
+                      LPSPropProblemArray *lppProbs) PURE;
+    STDMETHOD(CopyProps)(THIS_ LPSPropTagArray lpIncludeProps, ULONG ulParam, LPMAPIPROGRESS lpProgress,
+                         LPCIID lpIid, LPVOID lpDestObj, ULONG ulFlags, LPSPropProblemArray *lppProblems) PURE;
+    STDMETHOD(GetNamesFromIDs)(THIS_ LPSPropTagArray *lppPropTags, LPGUID lpIid, ULONG ulFlags, ULONG *lpCount,
+                               LPMAPINAMEID **lpppNames) PURE;
+    STDMETHOD(GetIDsFromNames)(THIS_ ULONG cPropNames, LPMAPINAMEID *lppNames, ULONG ulFlags, LPSPropTagArray *lppPropTags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+        /*** IUnknown methods ***/
+#define IMAPIProp_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IMAPIProp_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IMAPIProp_Release(p)                   (p)->lpVtbl->Release(p)
+        /*** IMAPIProp methods ***/
+#define IMAPIProp_GetLastError(p,a,b,c)        (p)->lpVtbl->GetLastError(p,a,b,c)        
+#define IMAPIProp_SaveChanges(p,a)             (p)->lpVtbl->SaveChanges(p,a)             
+#define IMAPIProp_GetProps(p,a,b,c,d)          (p)->lpVtbl->GetProps(p,a,b,c,d)          
+#define IMAPIProp_GetPropList(p,a,b)           (p)->lpVtbl->GetPropList(p,a,b)           
+#define IMAPIProp_OpenProperty(p,a,b,c,d,e)    (p)->lpVtbl->OpenProperty(p,a,b,c,d,e)    
+#define IMAPIProp_SetProps(p,a,b,c)            (p)->lpVtbl->SetProps(p,a,b,c)            
+#define IMAPIProp_DeleteProps(p,a,b)           (p)->lpVtbl->DeleteProps(p,a,b)           
+#define IMAPIProp_CopyTo(p,a,b,c,d,e,f,g,h,i)  (p)->lpVtbl->CopyTo(p,a,b,c,d,e,f,g,h,i)  
+#define IMAPIProp_CopyProps(p,a,b,c,d,e,f,g)   (p)->lpVtbl->CopyProps(p,a,b,c,d,e,f,g)   
+#define IMAPIProp_GetNamesFromIDs(p,a,b,c,d,e) (p)->lpVtbl->GetNamesFromIDs(p,a,b,c,d,e) 
+#define IMAPIProp_GetIDsFromNames(p,a,b,c,d)   (p)->lpVtbl->GetIDsFromNames(p,a,b,c,d)   
+#endif
+
+typedef IMAPIProp *LPMAPIPROP;
+
+typedef struct
+{
+    ULONG cb;
+    BYTE  abEntry[MAPI_DIM];
+} FLATENTRY, *LPFLATENTRY;
+
+typedef struct
+{
+    ULONG cEntries;
+    ULONG cbEntries;
+    BYTE  abEntries[MAPI_DIM];
+} FLATENTRYLIST, *LPFLATENTRYLIST;
+
+typedef struct
+{
+    ULONG cb;
+    BYTE  ab[MAPI_DIM];
+} MTSID, *LPMTSID;
+
+typedef struct
+{
+    ULONG cMTSIDs;
+    ULONG cbMTSIDs;
+    BYTE  abMTSIDs[MAPI_DIM];
+} FLATMTSIDLIST, *LPFLATMTSIDLIST;
+
+typedef struct _ADRENTRY
+{
+    ULONG        ulReserved1;
+    ULONG        cValues;
+    LPSPropValue rgPropVals;
+} ADRENTRY, *LPADRENTRY;
+
+typedef struct _ADRLIST
+{
+    ULONG    cEntries;
+    ADRENTRY aEntries[MAPI_DIM];
+} ADRLIST, *LPADRLIST;
+
+#endif /*MAPIDEFS_H*/
diff --git a/reactos/w32api/include/mapiguid.h b/reactos/w32api/include/mapiguid.h
new file mode 100644 (file)
index 0000000..2c8e34a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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
+ */
+
+#ifndef MAPIGUID_H
+#define MAPIGUID_H
+
+#define DEFINE_MAPIGUID(n,l,w1,w2) DEFINE_OLEGUID(n,l,w1,w2)
+
+DEFINE_MAPIGUID(IID_IABContainer,0x2030D,0,0);
+DEFINE_MAPIGUID(IID_IABLogon,0x20314,0,0);
+DEFINE_MAPIGUID(IID_IABProvider,0x20311,0,0);
+DEFINE_MAPIGUID(IID_IAddrBook,0x20309,0,0);
+DEFINE_MAPIGUID(IID_IAttachment,0x20308,0,0);
+DEFINE_MAPIGUID(IID_IDistList,0x2030E,0,0);
+DEFINE_MAPIGUID(IID_IEnumMAPIFormProp,0x20323,0,0);
+DEFINE_MAPIGUID(IID_IMailUser,0x2030A,0,0);
+DEFINE_MAPIGUID(IID_IMAPIAdviseSink,0x20302,0,0);
+DEFINE_MAPIGUID(IID_IMAPIContainer,0x2030B,0,0);
+DEFINE_MAPIGUID(IID_IMAPIControl,0x2031B,0,0);
+DEFINE_MAPIGUID(IID_IMAPIFolder,0x2030C,0,0);
+DEFINE_MAPIGUID(IID_IMAPIForm,0x20327,0,0);
+DEFINE_MAPIGUID(IID_IMAPIFormAdviseSink,0x2032F,0,0);
+DEFINE_MAPIGUID(IID_IMAPIFormContainer,0x2032E,0,0);
+DEFINE_MAPIGUID(IID_IMAPIFormFactory,0x20350,0,0);
+DEFINE_MAPIGUID(IID_IMAPIFormInfo,0x20324,0,0);
+DEFINE_MAPIGUID(IID_IMAPIFormMgr,0x20322,0,0);
+DEFINE_MAPIGUID(IID_IMAPIFormProp,0x2032D,0,0);
+DEFINE_MAPIGUID(IID_IMAPIMessageSite,0x20370,0,0);
+DEFINE_MAPIGUID(IID_IMAPIProgress,0x2031F,0,0);
+DEFINE_MAPIGUID(IID_IMAPIProp,0x20303,0,0);
+DEFINE_MAPIGUID(IID_IMAPIPropData,0x2031A,0,0);
+DEFINE_MAPIGUID(IID_IMAPISession,0x20300,0,0);
+DEFINE_MAPIGUID(IID_IMAPISpoolerInit,0x20317,0,0);
+DEFINE_MAPIGUID(IID_IMAPISpoolerService,0x2031E,0,0);
+DEFINE_MAPIGUID(IID_IMAPISpoolerSession,0x20318,0,0);
+DEFINE_MAPIGUID(IID_IMAPIStatus,0x20305,0,0);
+DEFINE_MAPIGUID(IID_IMAPISup,0x2030F,0,0);
+DEFINE_MAPIGUID(IID_IMAPITable,0x20301,0,0);
+DEFINE_MAPIGUID(IID_IMAPITableData,0x20316,0,0);
+DEFINE_MAPIGUID(IID_IMAPIViewAdviseSink,0x2032B,0,0);
+DEFINE_MAPIGUID(IID_IMAPIViewContext,0x20321,0,0);
+DEFINE_MAPIGUID(IID_IMessage,0x20307,0,0);
+DEFINE_MAPIGUID(IID_IMsgServiceAdmin,0x2031D,0,0);
+DEFINE_MAPIGUID(IID_IMsgStore,0x20306,0,0);
+DEFINE_MAPIGUID(IID_IMSLogon,0x20313,0,0);
+DEFINE_MAPIGUID(IID_IMSProvider,0x20310,0,0);
+DEFINE_MAPIGUID(IID_IPersistMessage,0x2032A,0,0);
+DEFINE_MAPIGUID(IID_IProfAdmin,0x2031C,0,0);
+DEFINE_MAPIGUID(IID_IProfSect,0x20304,0,0);
+DEFINE_MAPIGUID(IID_IProviderAdmin,0x20325,0,0);
+DEFINE_MAPIGUID(IID_ISpoolerHook,0x20320,0,0);
+DEFINE_MAPIGUID(IID_IStreamDocfile,0x2032C,0,0);
+DEFINE_MAPIGUID(IID_IStreamTnef,0x20330,0,0);
+DEFINE_MAPIGUID(IID_ITNEF,0x20319,0,0);
+DEFINE_MAPIGUID(IID_IXPLogon,0x20315,0,0);
+DEFINE_MAPIGUID(IID_IXPProvider,0x20312,0,0);
+DEFINE_MAPIGUID(MUID_PROFILE_INSTANCE,0x20385,0,0);
+DEFINE_MAPIGUID(PS_MAPI,0x20328,0,0);
+DEFINE_MAPIGUID(PS_PUBLIC_STRINGS,0x20329,0,0);
+DEFINE_MAPIGUID(PS_ROUTING_ADDRTYPE,0x20381,0,0);
+DEFINE_MAPIGUID(PS_ROUTING_DISPLAY_NAME,0x20382,0,0);
+DEFINE_MAPIGUID(PS_ROUTING_EMAIL_ADDRESSES,0x20380,0,0);
+DEFINE_MAPIGUID(PS_ROUTING_ENTRYID,0x20383,0,0);
+DEFINE_MAPIGUID(PS_ROUTING_SEARCH_KEY,0x20384,0,0);
+
+#endif/* MAPIGUID_H */
diff --git a/reactos/w32api/include/mapitags.h b/reactos/w32api/include/mapitags.h
new file mode 100644 (file)
index 0000000..f1de434
--- /dev/null
@@ -0,0 +1,813 @@
+/*
+ * MAPI property tag declarations
+ *
+ * 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
+ */
+#ifndef MAPITAGS_H
+#define MAPITAGS_H
+
+#define FIsTransmittable(t) (PROP_ID(t) < 0x0E00 || PROP_ID(t) >= 0x8000 || \
+ (PROP_ID(t) >= 0x1000 && PROP_ID(t) < 0x6000) || \
+ (PROP_ID(t) >= 0x6800 && PROP_ID(t) < 0x7C00))
+
+#define PR_ACKNOWLEDGEMENT_MODE PROP_TAG(PT_I4,0x01)
+#define PR_ALTERNATE_RECIPIENT_ALLOWED PROP_TAG(PT_BOOLEAN,0x02)
+#define PR_AUTHORIZING_USERS PROP_TAG(PT_BINARY,0x03)
+/* Comment on an automatically forwarded message */
+#define PR_AUTO_FORWARD_COMMENT_W PROP_TAG(PT_UNICODE,0x04)
+#define PR_AUTO_FORWARD_COMMENT_A PROP_TAG(PT_STRING8,0x04)
+#define PR_AUTO_FORWARD_COMMENT   WINELIB_NAME_AW(PR_AUTO_FORWARD_COMMENT_)
+/* Whether a message has been automatically forwarded */
+#define PR_AUTO_FORWARDED PROP_TAG(PT_BOOLEAN,0x05)
+#define PR_CONTENT_CONFIDENTIALITY_ALGORITHM_ID PROP_TAG(PT_BINARY,0x06)
+#define PR_CONTENT_CORRELATOR PROP_TAG(PT_BINARY,0x07)
+#define PR_CONTENT_IDENTIFIER_W PROP_TAG(PT_UNICODE,0x08)
+#define PR_CONTENT_IDENTIFIER_A PROP_TAG(PT_STRING8,0x08)
+#define PR_CONTENT_IDENTIFIER   WINELIB_NAME_AW(PR_CONTENT_IDENTIFIER_)
+/* MIME content length */
+#define PR_CONTENT_LENGTH PROP_TAG(PT_I4,0x09)
+#define PR_CONTENT_RETURN_REQUESTED PROP_TAG(PT_BOOLEAN,0x0A)
+#define PR_CONVERSATION_KEY PROP_TAG(PT_BINARY,0x0B)
+#define PR_CONVERSION_EITS PROP_TAG(PT_BINARY,0x0C)
+#define PR_CONVERSION_WITH_LOSS_PROHIBITED PROP_TAG(PT_BOOLEAN,0x0D)
+#define PR_CONVERTED_EITS PROP_TAG(PT_BINARY,0x0E)
+/* Time to deliver for delayed delivery messages */
+#define PR_DEFERRED_DELIVERY_TIME PROP_TAG(PT_SYSTIME,0x0F)
+#define PR_DELIVER_TIME PROP_TAG(PT_SYSTIME,0x10)
+/* Reason a message was discarded */
+#define PR_DISCARD_REASON PROP_TAG(PT_I4,0x11)
+#define PR_DISCLOSURE_OF_RECIPIENTS PROP_TAG(PT_BOOLEAN,0x12)
+#define PR_DL_EXPANSION_HISTORY PROP_TAG(PT_BINARY,0x13)
+#define PR_DL_EXPANSION_PROHIBITED PROP_TAG(PT_BOOLEAN,0x14)
+#define PR_EXPIRY_TIME PROP_TAG(PT_SYSTIME,0x15)
+#define PR_IMPLICIT_CONVERSION_PROHIBITED PROP_TAG(PT_BOOLEAN,0x16)
+/* Message importance */
+#define PR_IMPORTANCE PROP_TAG(PT_I4,0x17)
+#define PR_IPM_ID PROP_TAG(PT_BINARY,0x18)
+#define PR_LATEST_DELIVERY_TIME PROP_TAG(PT_SYSTIME,0x19)
+#define PR_MESSAGE_CLASS_W PROP_TAG(PT_UNICODE,0x1A)
+#define PR_MESSAGE_CLASS_A PROP_TAG(PT_STRING8,0x1A)
+#define PR_MESSAGE_CLASS   WINELIB_NAME_AW(PR_MESSAGE_CLASS_)
+#define PR_MESSAGE_DELIVERY_ID PROP_TAG(PT_BINARY,0x1B)
+#define PR_MESSAGE_SECURITY_LABEL PROP_TAG(PT_BINARY,0x1E)
+#define PR_OBSOLETED_IPMS PROP_TAG(PT_BINARY,0x1F)
+/* Person a message was originally for */
+#define PR_ORIGINALLY_INTENDED_RECIPIENT_NAME PROP_TAG(PT_BINARY,0x20)
+#define PR_ORIGINAL_EITS PROP_TAG(PT_BINARY,0x21)
+#define PR_ORIGINATOR_CERTIFICATE PROP_TAG(PT_BINARY,0x22)
+#define PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED PROP_TAG(PT_BOOLEAN,0x23)
+/* Address of the message sender */
+#define PR_ORIGINATOR_RETURN_ADDRESS PROP_TAG(PT_BINARY,0x24)
+#define PR_PARENT_KEY PROP_TAG(PT_BINARY,0x25)
+#define PR_PRIORITY PROP_TAG(PT_I4,0x26)
+#define PR_ORIGIN_CHECK PROP_TAG(PT_BINARY,0x27)
+#define PR_PROOF_OF_SUBMISSION_REQUESTED PROP_TAG(PT_BOOLEAN,0x28)
+/* Whether a read receipt is desired */
+#define PR_READ_RECEIPT_REQUESTED PROP_TAG(PT_BOOLEAN,0x29)
+/* Time a message was received */
+#define PR_RECEIPT_TIME PROP_TAG(PT_SYSTIME,0x2A)
+#define PR_RECIPIENT_REASSIGNMENT_PROHIBITED PROP_TAG(PT_BOOLEAN,0x2B)
+#define PR_REDIRECTION_HISTORY PROP_TAG(PT_BINARY,0x2C)
+#define PR_RELATED_IPMS PROP_TAG(PT_BINARY,0x2D)
+/* Sensitivity of the original message */
+#define PR_ORIGINAL_SENSITIVITY PROP_TAG(PT_I4,0x2E)
+#define PR_LANGUAGES_W PROP_TAG(PT_UNICODE,0x2F)
+#define PR_LANGUAGES_A PROP_TAG(PT_STRING8,0x2F)
+#define PR_LANGUAGES   WINELIB_NAME_AW(PR_LANGUAGES_)
+#define PR_REPLY_TIME PROP_TAG(PT_SYSTIME,0x30)
+#define PR_REPORT_TAG PROP_TAG(PT_BINARY,0x31)
+#define PR_REPORT_TIME PROP_TAG(PT_SYSTIME,0x32)
+#define PR_RETURNED_IPM PROP_TAG(PT_BOOLEAN,0x33)
+#define PR_SECURITY PROP_TAG(PT_I4,0x34)
+#define PR_INCOMPLETE_COPY PROP_TAG(PT_BOOLEAN,0x35)
+#define PR_SENSITIVITY PROP_TAG(PT_I4,0x36)
+/* The message subject */
+#define PR_SUBJECT_W PROP_TAG(PT_UNICODE,0x37)
+#define PR_SUBJECT_A PROP_TAG(PT_STRING8,0x37)
+#define PR_SUBJECT   WINELIB_NAME_AW(PR_SUBJECT_)
+#define PR_SUBJECT_IPM PROP_TAG(PT_BINARY,0x38)
+#define PR_CLIENT_SUBMIT_TIME PROP_TAG(PT_SYSTIME,0x39)
+#define PR_REPORT_NAME_W PROP_TAG(PT_UNICODE,0x3A)
+#define PR_REPORT_NAME_A PROP_TAG(PT_STRING8,0x3A)
+#define PR_REPORT_NAME   WINELIB_NAME_AW(PR_REPORT_NAME_)
+#define PR_SENT_REPRESENTING_SEARCH_KEY PROP_TAG(PT_BINARY,0x3B)
+#define PR_X400_CONTENT_TYPE PROP_TAG(PT_BINARY,0x3C)
+#define PR_SUBJECT_PREFIX_W PROP_TAG(PT_UNICODE,0x3D)
+#define PR_SUBJECT_PREFIX_A PROP_TAG(PT_STRING8,0x3D)
+#define PR_SUBJECT_PREFIX   WINELIB_NAME_AW(PR_SUBJECT_PREFIX_)
+#define PR_NON_RECEIPT_REASON PROP_TAG(PT_I4,0x3E)
+#define PR_RECEIVED_BY_ENTRYID PROP_TAG(PT_BINARY,0x3F)
+/* Received by: entry */
+#define PR_RECEIVED_BY_NAME_W PROP_TAG(PT_UNICODE,0x40)
+#define PR_RECEIVED_BY_NAME_A PROP_TAG(PT_STRING8,0x40)
+#define PR_RECEIVED_BY_NAME   WINELIB_NAME_AW(PR_RECEIVED_BY_NAME_)
+#define PR_SENT_REPRESENTING_ENTRYID PROP_TAG(PT_BINARY,0x41)
+#define PR_SENT_REPRESENTING_NAME_W PROP_TAG(PT_UNICODE,0x42)
+#define PR_SENT_REPRESENTING_NAME_A PROP_TAG(PT_STRING8,0x42)
+#define PR_SENT_REPRESENTING_NAME   WINELIB_NAME_AW(PR_SENT_REPRESENTING_NAME_)
+#define PR_RCVD_REPRESENTING_ENTRYID PROP_TAG(PT_BINARY,0x43)
+#define PR_RCVD_REPRESENTING_NAME_W PROP_TAG(PT_UNICODE,0x44)
+#define PR_RCVD_REPRESENTING_NAME_A PROP_TAG(PT_STRING8,0x44)
+#define PR_RCVD_REPRESENTING_NAME   WINELIB_NAME_AW(PR_RCVD_REPRESENTING_NAME_)
+#define PR_REPORT_ENTRYID PROP_TAG(PT_BINARY,0x45)
+#define PR_READ_RECEIPT_ENTRYID PROP_TAG(PT_BINARY,0x46)
+#define PR_MESSAGE_SUBMISSION_ID PROP_TAG(PT_BINARY,0x47)
+#define PR_PROVIDER_SUBMIT_TIME PROP_TAG(PT_SYSTIME,0x48)
+/* Subject of the original message */
+#define PR_ORIGINAL_SUBJECT_W PROP_TAG(PT_UNICODE,0x49)
+#define PR_ORIGINAL_SUBJECT_A PROP_TAG(PT_STRING8,0x49)
+#define PR_ORIGINAL_SUBJECT   WINELIB_NAME_AW(PR_ORIGINAL_SUBJECT_)
+#define PR_DISC_VAL PROP_TAG(PT_BOOLEAN,0x4A)
+#define PR_ORIG_MESSAGE_CLASS_W PROP_TAG(PT_UNICODE,0x4B)
+#define PR_ORIG_MESSAGE_CLASS_A PROP_TAG(PT_STRING8,0x4B)
+#define PR_ORIG_MESSAGE_CLASS   WINELIB_NAME_AW(PR_ORIG_MESSAGE_CLASS_)
+#define PR_ORIGINAL_AUTHOR_ENTRYID PROP_TAG(PT_BINARY,0x4C)
+/* Author of the original message */
+#define PR_ORIGINAL_AUTHOR_NAME_W PROP_TAG(PT_UNICODE,0x4D)
+#define PR_ORIGINAL_AUTHOR_NAME_A PROP_TAG(PT_STRING8,0x4D)
+#define PR_ORIGINAL_AUTHOR_NAME   WINELIB_NAME_AW(PR_ORIGINAL_AUTHOR_NAME_)
+/* Time the original message was submitted */
+#define PR_ORIGINAL_SUBMIT_TIME PROP_TAG(PT_SYSTIME,0x4E)
+#define PR_REPLY_RECIPIENT_ENTRIES PROP_TAG(PT_BINARY,0x4F)
+#define PR_REPLY_RECIPIENT_NAMES_W PROP_TAG(PT_UNICODE,0x50)
+#define PR_REPLY_RECIPIENT_NAMES_A PROP_TAG(PT_STRING8,0x50)
+#define PR_REPLY_RECIPIENT_NAMES   WINELIB_NAME_AW(PR_REPLY_RECIPIENT_NAMES_)
+#define PR_RECEIVED_BY_SEARCH_KEY PROP_TAG(PT_BINARY,0x51)
+#define PR_RCVD_REPRESENTING_SEARCH_KEY PROP_TAG(PT_BINARY,0x52)
+#define PR_READ_RECEIPT_SEARCH_KEY PROP_TAG(PT_BINARY,0x53)
+#define PR_REPORT_SEARCH_KEY PROP_TAG(PT_BINARY,0x54)
+#define PR_ORIGINAL_DELIVERY_TIME PROP_TAG(PT_SYSTIME,0x55)
+#define PR_ORIGINAL_AUTHOR_SEARCH_KEY PROP_TAG(PT_BINARY,0x56)
+#define PR_MESSAGE_TO_ME PROP_TAG(PT_BOOLEAN,0x57)
+#define PR_MESSAGE_CC_ME PROP_TAG(PT_BOOLEAN,0x58)
+#define PR_MESSAGE_RECIP_ME PROP_TAG(PT_BOOLEAN,0x59)
+/* Sender of the original message */
+#define PR_ORIGINAL_SENDER_NAME_W PROP_TAG(PT_UNICODE,0x5A)
+#define PR_ORIGINAL_SENDER_NAME_A PROP_TAG(PT_STRING8,0x5A)
+#define PR_ORIGINAL_SENDER_NAME   WINELIB_NAME_AW(PR_ORIGINAL_SENDER_NAME_)
+#define PR_ORIGINAL_SENDER_ENTRYID PROP_TAG(PT_BINARY,0x5B)
+#define PR_ORIGINAL_SENDER_SEARCH_KEY PROP_TAG(PT_BINARY,0x5C)
+#define PR_ORIGINAL_SENT_REPRESENTING_NAME_W PROP_TAG(PT_UNICODE,0x5D)
+#define PR_ORIGINAL_SENT_REPRESENTING_NAME_A PROP_TAG(PT_STRING8,0x5D)
+#define PR_ORIGINAL_SENT_REPRESENTING_NAME   WINELIB_NAME_AW(PR_ORIGINAL_SENT_REPRESENTING_NAME_)
+#define PR_ORIGINAL_SENT_REPRESENTING_ENTRYID PROP_TAG(PT_BINARY,0x5E)
+#define PR_ORIGINAL_SENT_REPRESENTING_SEARCH_KEY PROP_TAG(PT_BINARY,0x5F)
+#define PR_START_DATE PROP_TAG(PT_SYSTIME,0x60)
+#define PR_END_DATE PROP_TAG(PT_SYSTIME,0x61)
+#define PR_OWNER_APPT_ID PROP_TAG(PT_I4,0x62)
+/* Whether a response to the message is desired */
+#define PR_RESPONSE_REQUESTED PROP_TAG(PT_BOOLEAN,0x63)
+#define PR_SENT_REPRESENTING_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x64)
+#define PR_SENT_REPRESENTING_ADDRTYPE_A PROP_TAG(PT_STRING8,0x64)
+#define PR_SENT_REPRESENTING_ADDRTYPE   WINELIB_NAME_AW(PR_SENT_REPRESENTING_ADDRTYPE_)
+#define PR_SENT_REPRESENTING_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x65)
+#define PR_SENT_REPRESENTING_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x65)
+#define PR_SENT_REPRESENTING_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_SENT_REPRESENTING_EMAIL_ADDRESS_)
+#define PR_ORIGINAL_SENDER_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x66)
+#define PR_ORIGINAL_SENDER_ADDRTYPE_A PROP_TAG(PT_STRING8,0x66)
+#define PR_ORIGINAL_SENDER_ADDRTYPE   WINELIB_NAME_AW(PR_ORIGINAL_SENDER_ADDRTYPE_)
+/* Email of the original message sender */
+#define PR_ORIGINAL_SENDER_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x67)
+#define PR_ORIGINAL_SENDER_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x67)
+#define PR_ORIGINAL_SENDER_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_ORIGINAL_SENDER_EMAIL_ADDRESS_)
+#define PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x68)
+#define PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE_A PROP_TAG(PT_STRING8,0x68)
+#define PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE   WINELIB_NAME_AW(PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE_)
+#define PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x69)
+#define PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x69)
+#define PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS_)
+#define PR_CONVERSATION_TOPIC_W PROP_TAG(PT_UNICODE,0x70)
+#define PR_CONVERSATION_TOPIC_A PROP_TAG(PT_STRING8,0x70)
+#define PR_CONVERSATION_TOPIC   WINELIB_NAME_AW(PR_CONVERSATION_TOPIC_)
+#define PR_CONVERSATION_INDEX PROP_TAG(PT_BINARY,0x71)
+#define PR_ORIGINAL_DISPLAY_BCC_W PROP_TAG(PT_UNICODE,0x72)
+#define PR_ORIGINAL_DISPLAY_BCC_A PROP_TAG(PT_STRING8,0x72)
+#define PR_ORIGINAL_DISPLAY_BCC   WINELIB_NAME_AW(PR_ORIGINAL_DISPLAY_BCC_)
+#define PR_ORIGINAL_DISPLAY_CC_W PROP_TAG(PT_UNICODE,0x73)
+#define PR_ORIGINAL_DISPLAY_CC_A PROP_TAG(PT_STRING8,0x73)
+#define PR_ORIGINAL_DISPLAY_CC   WINELIB_NAME_AW(PR_ORIGINAL_DISPLAY_CC_)
+#define PR_ORIGINAL_DISPLAY_TO_W PROP_TAG(PT_UNICODE,0x74)
+#define PR_ORIGINAL_DISPLAY_TO_A PROP_TAG(PT_STRING8,0x74)
+#define PR_ORIGINAL_DISPLAY_TO   WINELIB_NAME_AW(PR_ORIGINAL_DISPLAY_TO_)
+#define PR_RECEIVED_BY_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x75)
+#define PR_RECEIVED_BY_ADDRTYPE_A PROP_TAG(PT_STRING8,0x75)
+#define PR_RECEIVED_BY_ADDRTYPE   WINELIB_NAME_AW(PR_RECEIVED_BY_ADDRTYPE_)
+#define PR_RECEIVED_BY_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x76)
+#define PR_RECEIVED_BY_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x76)
+#define PR_RECEIVED_BY_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_RECEIVED_BY_EMAIL_ADDRESS_)
+#define PR_RCVD_REPRESENTING_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x77)
+#define PR_RCVD_REPRESENTING_ADDRTYPE_A PROP_TAG(PT_STRING8,0x77)
+#define PR_RCVD_REPRESENTING_ADDRTYPE   WINELIB_NAME_AW(PR_RCVD_REPRESENTING_ADDRTYPE_)
+#define PR_RCVD_REPRESENTING_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x78)
+#define PR_RCVD_REPRESENTING_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x78)
+#define PR_RCVD_REPRESENTING_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_RCVD_REPRESENTING_EMAIL_ADDRESS_)
+#define PR_ORIGINAL_AUTHOR_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x79)
+#define PR_ORIGINAL_AUTHOR_ADDRTYPE_A PROP_TAG(PT_STRING8,0x79)
+#define PR_ORIGINAL_AUTHOR_ADDRTYPE   WINELIB_NAME_AW(PR_ORIGINAL_AUTHOR_ADDRTYPE_)
+#define PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x7A)
+#define PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x7A)
+#define PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS_)
+#define PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x7B)
+#define PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE_A PROP_TAG(PT_STRING8,0x7B)
+#define PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE   WINELIB_NAME_AW(PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE_)
+#define PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x7C)
+#define PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x7C)
+#define PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS_)
+#define PR_TRANSPORT_MESSAGE_HEADERS_W PROP_TAG(PT_UNICODE,0x7D)
+#define PR_TRANSPORT_MESSAGE_HEADERS_A PROP_TAG(PT_STRING8,0x7D)
+#define PR_TRANSPORT_MESSAGE_HEADERS   WINELIB_NAME_AW(PR_TRANSPORT_MESSAGE_HEADERS_)
+#define PR_DELEGATION PROP_TAG(PT_BINARY,0x7E)
+#define PR_TNEF_CORRELATION_KEY PROP_TAG(PT_BINARY,0x7F)
+#define PR_BODY_W PROP_TAG(PT_UNICODE,0x1000)
+#define PR_BODY_A PROP_TAG(PT_STRING8,0x1000)
+#define PR_BODY   WINELIB_NAME_AW(PR_BODY_)
+#define PR_REPORT_TEXT_W PROP_TAG(PT_UNICODE,0x1001)
+#define PR_REPORT_TEXT_A PROP_TAG(PT_STRING8,0x1001)
+#define PR_REPORT_TEXT   WINELIB_NAME_AW(PR_REPORT_TEXT_)
+#define PR_ORIGINATOR_AND_DL_EXPANSION_HISTORY PROP_TAG(PT_BINARY,0x1002)
+#define PR_REPORTING_DL_NAME PROP_TAG(PT_BINARY,0x1003)
+#define PR_REPORTING_MTA_CERTIFICATE PROP_TAG(PT_BINARY,0x1004)
+#define PR_RTF_SYNC_BODY_CRC PROP_TAG(PT_I4,0x1006)
+#define PR_RTF_SYNC_BODY_COUNT PROP_TAG(PT_I4,0x1007)
+#define PR_RTF_SYNC_BODY_TAG_W PROP_TAG(PT_UNICODE,0x1008)
+#define PR_RTF_SYNC_BODY_TAG_A PROP_TAG(PT_STRING8,0x1008)
+#define PR_RTF_SYNC_BODY_TAG   WINELIB_NAME_AW(PR_RTF_SYNC_BODY_TAG_)
+#define PR_RTF_COMPRESSED PROP_TAG(PT_BINARY,0x1009)
+#define PR_RTF_SYNC_PREFIX_COUNT PROP_TAG(PT_I4,0x1010)
+#define PR_RTF_SYNC_TRAILING_COUNT PROP_TAG(PT_I4,0x1011)
+#define PR_ORIGINALLY_INTENDED_RECIP_ENTRYID PROP_TAG(PT_BINARY,0x1012)
+#define PR_CONTENT_INTEGRITY_CHECK PROP_TAG(PT_BINARY,0x0C00)
+#define PR_EXPLICIT_CONVERSION PROP_TAG(PT_I4,0x0C01)
+#define PR_IPM_RETURN_REQUESTED PROP_TAG(PT_BOOLEAN,0x0C02)
+#define PR_MESSAGE_TOKEN PROP_TAG(PT_BINARY,0x0C03)
+#define PR_NDR_REASON_CODE PROP_TAG(PT_I4,0x0C04)
+#define PR_NDR_DIAG_CODE PROP_TAG(PT_I4,0x0C05)
+#define PR_NON_RECEIPT_NOTIFICATION_REQUESTED PROP_TAG(PT_BOOLEAN,0x0C06)
+#define PR_DELIVERY_POINT PROP_TAG(PT_I4,0x0C07)
+#define PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED PROP_TAG(PT_BOOLEAN,0x0C08)
+#define PR_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT PROP_TAG(PT_BINARY,0x0C09)
+#define PR_PHYSICAL_DELIVERY_BUREAU_FAX_DELIVERY PROP_TAG(PT_BOOLEAN,0x0C0A)
+#define PR_PHYSICAL_DELIVERY_MODE PROP_TAG(PT_I4,0x0C0B)
+#define PR_PHYSICAL_DELIVERY_REPORT_REQUEST PROP_TAG(PT_I4,0x0C0C)
+#define PR_PHYSICAL_FORWARDING_ADDRESS PROP_TAG(PT_BINARY,0x0C0D)
+#define PR_PHYSICAL_FORWARDING_ADDRESS_REQUESTED PROP_TAG(PT_BOOLEAN,0x0C0E)
+#define PR_PHYSICAL_FORWARDING_PROHIBITED PROP_TAG(PT_BOOLEAN,0x0C0F)
+#define PR_PHYSICAL_RENDITION_ATTRIBUTES PROP_TAG(PT_BINARY,0x0C10)
+#define PR_PROOF_OF_DELIVERY PROP_TAG(PT_BINARY,0x0C11)
+#define PR_PROOF_OF_DELIVERY_REQUESTED PROP_TAG(PT_BOOLEAN,0x0C12)
+#define PR_RECIPIENT_CERTIFICATE PROP_TAG(PT_BINARY,0x0C13)
+#define PR_RECIPIENT_NUMBER_FOR_ADVICE_W PROP_TAG(PT_UNICODE,0x0C14)
+#define PR_RECIPIENT_NUMBER_FOR_ADVICE_A PROP_TAG(PT_STRING8,0x0C14)
+#define PR_RECIPIENT_NUMBER_FOR_ADVICE   WINELIB_NAME_AW(PR_RECIPIENT_NUMBER_FOR_ADVICE_)
+#define PR_RECIPIENT_TYPE PROP_TAG(PT_I4,0x0C15)
+#define PR_REGISTERED_MAIL_TYPE PROP_TAG(PT_I4,0x0C16)
+#define PR_REPLY_REQUESTED PROP_TAG(PT_BOOLEAN,0x0C17)
+#define PR_REQUESTED_DELIVERY_METHOD PROP_TAG(PT_I4,0x0C18)
+#define PR_SENDER_ENTRYID PROP_TAG(PT_BINARY,0x0C19)
+#define PR_SENDER_NAME_W PROP_TAG(PT_UNICODE,0x0C1A)
+#define PR_SENDER_NAME_A PROP_TAG(PT_STRING8,0x0C1A)
+#define PR_SENDER_NAME   WINELIB_NAME_AW(PR_SENDER_NAME_)
+#define PR_SUPPLEMENTARY_INFO_W PROP_TAG(PT_UNICODE,0x0C1B)
+#define PR_SUPPLEMENTARY_INFO_A PROP_TAG(PT_STRING8,0x0C1B)
+#define PR_SUPPLEMENTARY_INFO   WINELIB_NAME_AW(PR_SUPPLEMENTARY_INFO_)
+#define PR_TYPE_OF_MTS_USER PROP_TAG(PT_I4,0x0C1C)
+#define PR_SENDER_SEARCH_KEY PROP_TAG(PT_BINARY,0x0C1D)
+#define PR_SENDER_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x0C1E)
+#define PR_SENDER_ADDRTYPE_A PROP_TAG(PT_STRING8,0x0C1E)
+#define PR_SENDER_ADDRTYPE   WINELIB_NAME_AW(PR_SENDER_ADDRTYPE_)
+#define PR_SENDER_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x0C1F)
+#define PR_SENDER_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x0C1F)
+#define PR_SENDER_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_SENDER_EMAIL_ADDRESS_)
+#define PR_CURRENT_VERSION PROP_TAG(PT_I8,0x0E00)
+#define PR_DELETE_AFTER_SUBMIT PROP_TAG(PT_BOOLEAN,0x0E01)
+#define PR_DISPLAY_BCC_W PROP_TAG(PT_UNICODE,0x0E02)
+#define PR_DISPLAY_BCC_A PROP_TAG(PT_STRING8,0x0E02)
+#define PR_DISPLAY_BCC   WINELIB_NAME_AW(PR_DISPLAY_BCC_)
+#define PR_DISPLAY_CC_W PROP_TAG(PT_UNICODE,0x0E03)
+#define PR_DISPLAY_CC_A PROP_TAG(PT_STRING8,0x0E03)
+#define PR_DISPLAY_CC   WINELIB_NAME_AW(PR_DISPLAY_CC_)
+#define PR_DISPLAY_TO_W PROP_TAG(PT_UNICODE,0x0E04)
+#define PR_DISPLAY_TO_A PROP_TAG(PT_STRING8,0x0E04)
+#define PR_DISPLAY_TO   WINELIB_NAME_AW(PR_DISPLAY_TO_)
+#define PR_PARENT_DISPLAY_W PROP_TAG(PT_UNICODE,0x0E05)
+#define PR_PARENT_DISPLAY_A PROP_TAG(PT_STRING8,0x0E05)
+#define PR_PARENT_DISPLAY   WINELIB_NAME_AW(PR_PARENT_DISPLAY_)
+#define PR_MESSAGE_DELIVERY_TIME PROP_TAG(PT_SYSTIME,0x0E06)
+#define PR_MESSAGE_FLAGS PROP_TAG(PT_I4,0x0E07)
+#define PR_MESSAGE_SIZE PROP_TAG(PT_I4,0x0E08)
+#define PR_PARENT_ENTRYID PROP_TAG(PT_BINARY,0x0E09)
+#define PR_SENTMAIL_ENTRYID PROP_TAG(PT_BINARY,0x0E0A)
+#define PR_CORRELATE PROP_TAG(PT_BOOLEAN,0x0E0C)
+#define PR_CORRELATE_MTSID PROP_TAG(PT_BINARY,0x0E0D)
+#define PR_DISCRETE_VALUES PROP_TAG(PT_BOOLEAN,0x0E0E)
+#define PR_RESPONSIBILITY PROP_TAG(PT_BOOLEAN,0x0E0F)
+#define PR_SPOOLER_STATUS PROP_TAG(PT_I4,0x0E10)
+#define PR_TRANSPORT_STATUS PROP_TAG(PT_I4,0x0E11)
+#define PR_MESSAGE_RECIPIENTS PROP_TAG(PT_OBJECT,0x0E12)
+#define PR_MESSAGE_ATTACHMENTS PROP_TAG(PT_OBJECT,0x0E13)
+#define PR_SUBMIT_FLAGS PROP_TAG(PT_I4,0x0E14)
+#define PR_RECIPIENT_STATUS PROP_TAG(PT_I4,0x0E15)
+#define PR_TRANSPORT_KEY PROP_TAG(PT_I4,0x0E16)
+#define PR_MSG_STATUS PROP_TAG(PT_I4,0x0E17)
+#define PR_MESSAGE_DOWNLOAD_TIME PROP_TAG(PT_I4,0x0E18)
+#define PR_CREATION_VERSION PROP_TAG(PT_I8,0x0E19)
+#define PR_MODIFY_VERSION PROP_TAG(PT_I8,0x0E1A)
+#define PR_HASATTACH PROP_TAG(PT_BOOLEAN,0x0E1B)
+#define PR_BODY_CRC PROP_TAG(PT_I4, 0x0E1C)
+#define PR_NORMALIZED_SUBJECT_W PROP_TAG(PT_UNICODE,0x0E1D)
+#define PR_NORMALIZED_SUBJECT_A PROP_TAG(PT_STRING8,0x0E1D)
+#define PR_NORMALIZED_SUBJECT   WINELIB_NAME_AW(PR_NORMALIZED_SUBJECT_)
+#define PR_RTF_IN_SYNC PROP_TAG(PT_BOOLEAN,0x0E1F)
+#define PR_ATTACH_SIZE PROP_TAG(PT_I4,0x0E20)
+#define PR_ATTACH_NUM PROP_TAG(PT_I4,0x0E21)
+#define PR_PREPROCESS PROP_TAG(PT_BOOLEAN,0x0E22)
+#define PR_ORIGINATING_MTA_CERTIFICATE PROP_TAG(PT_BINARY,0x0E25)
+#define PR_PROOF_OF_SUBMISSION PROP_TAG(PT_BINARY,0x0E26)
+/* A unique identifier for editing the properties of a MAPI object */
+#define PR_ENTRYID PROP_TAG(PT_BINARY,0x0FFF)
+/* The type of an object */
+#define PR_OBJECT_TYPE PROP_TAG(PT_I4,0x0FFE)
+#define PR_ICON PROP_TAG(PT_BINARY,0x0FFD)
+#define PR_MINI_ICON PROP_TAG(PT_BINARY,0x0FFC)
+#define PR_STORE_ENTRYID PROP_TAG(PT_BINARY,0x0FFB)
+#define PR_STORE_RECORD_KEY PROP_TAG(PT_BINARY,0x0FFA)
+/* Binary identifer for an individual object */
+#define PR_RECORD_KEY PROP_TAG(PT_BINARY,0x0FF9)
+#define PR_MAPPING_SIGNATURE PROP_TAG(PT_BINARY,0x0FF8)
+#define PR_ACCESS_LEVEL PROP_TAG(PT_I4,0x0FF7)
+/* The primary key of a column in a table */
+#define PR_INSTANCE_KEY PROP_TAG(PT_BINARY,0x0FF6)
+#define PR_ROW_TYPE PROP_TAG(PT_I4,0x0FF5)
+#define PR_ACCESS PROP_TAG(PT_I4,0x0FF4)
+#define PR_ROWID PROP_TAG(PT_I4,0x3000)
+/* The name to display for a given MAPI object */
+#define PR_DISPLAY_NAME_W PROP_TAG(PT_UNICODE,0x3001)
+#define PR_DISPLAY_NAME_A PROP_TAG(PT_STRING8,0x3001)
+#define PR_DISPLAY_NAME   WINELIB_NAME_AW(PR_DISPLAY_NAME_)
+#define PR_ADDRTYPE_W PROP_TAG(PT_UNICODE,0x3002)
+#define PR_ADDRTYPE_A PROP_TAG(PT_STRING8,0x3002)
+#define PR_ADDRTYPE   WINELIB_NAME_AW(PR_ADDRTYPE_)
+/* An email address */
+#define PR_EMAIL_ADDRESS_W PROP_TAG(PT_UNICODE,0x3003)
+#define PR_EMAIL_ADDRESS_A PROP_TAG(PT_STRING8,0x3003)
+#define PR_EMAIL_ADDRESS   WINELIB_NAME_AW(PR_EMAIL_ADDRESS_)
+/* A comment field */
+#define PR_COMMENT_W PROP_TAG(PT_UNICODE,0x3004)
+#define PR_COMMENT_A PROP_TAG(PT_STRING8,0x3004)
+#define PR_COMMENT   WINELIB_NAME_AW(PR_COMMENT_)
+#define PR_DEPTH PROP_TAG(PT_I4,0x3005)
+/* Provider-defined display name for a service provider */
+#define PR_PROVIDER_DISPLAY_W PROP_TAG(PT_UNICODE,0x3006)
+#define PR_PROVIDER_DISPLAY_A PROP_TAG(PT_STRING8,0x3006)
+#define PR_PROVIDER_DISPLAY   WINELIB_NAME_AW(PR_PROVIDER_DISPLAY_)
+/* The time an object was created */
+#define PR_CREATION_TIME PROP_TAG(PT_SYSTIME,0x3007)
+/* The time an object was last modified */
+#define PR_LAST_MODIFICATION_TIME PROP_TAG(PT_SYSTIME,0x3008)
+/* Flags describing a service provider, message service, or status object */
+#define PR_RESOURCE_FLAGS PROP_TAG(PT_I4,0x3009)
+/* The name of a provider dll, minus any "32" suffix and ".dll" */
+#define PR_PROVIDER_DLL_NAME_W PROP_TAG(PT_UNICODE,0x300A)
+#define PR_PROVIDER_DLL_NAME_A PROP_TAG(PT_STRING8,0x300A)
+#define PR_PROVIDER_DLL_NAME   WINELIB_NAME_AW(PR_PROVIDER_DLL_NAME_)
+#define PR_SEARCH_KEY PROP_TAG(PT_BINARY,0x300B)
+#define PR_PROVIDER_UID PROP_TAG(PT_BINARY,0x300C)
+#define PR_PROVIDER_ORDINAL PROP_TAG(PT_I4,0x300D)
+#define PR_FORM_VERSION_W PROP_TAG(PT_UNICODE,0x3301)
+#define PR_FORM_VERSION_A PROP_TAG(PT_STRING8,0x3301)
+#define PR_FORM_VERSION   WINELIB_NAME_AW(PR_FORM_VERSION_)
+#define PR_FORM_CLSID PROP_TAG(PT_CLSID,0x3302)
+#define PR_FORM_CONTACT_NAME_W PROP_TAG(PT_UNICODE,0x3303)
+#define PR_FORM_CONTACT_NAME_A PROP_TAG(PT_STRING8,0x3303)
+#define PR_FORM_CONTACT_NAME   WINELIB_NAME_AW(PR_FORM_CONTACT_NAME_)
+#define PR_FORM_CATEGORY_W PROP_TAG(PT_UNICODE,0x3304)
+#define PR_FORM_CATEGORY_A PROP_TAG(PT_STRING8,0x3304)
+#define PR_FORM_CATEGORY   WINELIB_NAME_AW(PR_FORM_CATEGORY_)
+#define PR_FORM_CATEGORY_SUB_W PROP_TAG(PT_UNICODE,0x3305)
+#define PR_FORM_CATEGORY_SUB_A PROP_TAG(PT_STRING8,0x3305)
+#define PR_FORM_CATEGORY_SUB   WINELIB_NAME_AW(PR_FORM_CATEGORY_SUB_)
+#define PR_FORM_HOST_MAP PROP_TAG(PT_MV_LONG,0x3306)
+#define PR_FORM_HIDDEN PROP_TAG(PT_BOOLEAN,0x3307)
+#define PR_FORM_DESIGNER_NAME_W PROP_TAG(PT_UNICODE,0x3308)
+#define PR_FORM_DESIGNER_NAME_A PROP_TAG(PT_STRING8,0x3308)
+#define PR_FORM_DESIGNER_NAME   WINELIB_NAME_AW(PR_FORM_DESIGNER_NAME_)
+#define PR_FORM_DESIGNER_GUID PROP_TAG(PT_CLSID,0x3309)
+#define PR_FORM_MESSAGE_BEHAVIOR PROP_TAG(PT_I4,0x330A)
+/* Is this row the default message store? */
+#define PR_DEFAULT_STORE PROP_TAG(PT_BOOLEAN,0x3400)
+#define PR_STORE_SUPPORT_MASK PROP_TAG(PT_I4,0x340D)
+#define PR_STORE_STATE PROP_TAG(PT_I4,0x340E)
+#define PR_IPM_SUBTREE_SEARCH_KEY PROP_TAG(PT_BINARY,0x3410)
+#define PR_IPM_OUTBOX_SEARCH_KEY PROP_TAG(PT_BINARY,0x3411)
+#define PR_IPM_WASTEBASKET_SEARCH_KEY PROP_TAG(PT_BINARY,0x3412)
+#define PR_IPM_SENTMAIL_SEARCH_KEY PROP_TAG(PT_BINARY,0x3413)
+/* Provder-defined message store type */
+#define PR_MDB_PROVIDER PROP_TAG(PT_BINARY,0x3414)
+#define PR_RECEIVE_FOLDER_SETTINGS PROP_TAG(PT_OBJECT,0x3415)
+#define PR_VALID_FOLDER_MASK PROP_TAG(PT_I4,0x35DF)
+#define PR_IPM_SUBTREE_ENTRYID PROP_TAG(PT_BINARY,0x35E0)
+#define PR_IPM_OUTBOX_ENTRYID PROP_TAG(PT_BINARY,0x35E2)
+#define PR_IPM_WASTEBASKET_ENTRYID PROP_TAG(PT_BINARY,0x35E3)
+#define PR_IPM_SENTMAIL_ENTRYID PROP_TAG(PT_BINARY,0x35E4)
+#define PR_VIEWS_ENTRYID PROP_TAG(PT_BINARY,0x35E5)
+#define PR_COMMON_VIEWS_ENTRYID PROP_TAG(PT_BINARY,0x35E6)
+#define PR_FINDER_ENTRYID PROP_TAG(PT_BINARY,0x35E7)
+#define PR_CONTAINER_FLAGS PROP_TAG(PT_I4,0x3600)
+#define PR_FOLDER_TYPE PROP_TAG(PT_I4,0x3601)
+#define PR_CONTENT_COUNT PROP_TAG(PT_I4,0x3602)
+#define PR_CONTENT_UNREAD PROP_TAG(PT_I4,0x3603)
+#define PR_CREATE_TEMPLATES PROP_TAG(PT_OBJECT,0x3604)
+#define PR_DETAILS_TABLE PROP_TAG(PT_OBJECT,0x3605)
+#define PR_SEARCH PROP_TAG(PT_OBJECT,0x3607)
+#define PR_SELECTABLE PROP_TAG(PT_BOOLEAN,0x3609)
+#define PR_SUBFOLDERS PROP_TAG(PT_BOOLEAN,0x360A)
+#define PR_STATUS PROP_TAG(PT_I4,0x360B)
+#define PR_ANR_W PROP_TAG(PT_UNICODE,0x360C)
+#define PR_ANR_A PROP_TAG(PT_STRING8,0x360C)
+#define PR_ANR   WINELIB_NAME_AW(PR_ANR_)
+#define PR_CONTENTS_SORT_ORDER PROP_TAG(PT_MV_LONG,0x360D)
+#define PR_CONTAINER_HIERARCHY PROP_TAG(PT_OBJECT,0x360E)
+#define PR_CONTAINER_CONTENTS PROP_TAG(PT_OBJECT,0x360F)
+#define PR_FOLDER_ASSOCIATED_CONTENTS PROP_TAG(PT_OBJECT,0x3610)
+#define PR_DEF_CREATE_DL PROP_TAG(PT_BINARY,0x3611)
+#define PR_DEF_CREATE_MAILUSER PROP_TAG(PT_BINARY,0x3612)
+#define PR_CONTAINER_CLASS_W PROP_TAG(PT_UNICODE,0x3613)
+#define PR_CONTAINER_CLASS_A PROP_TAG(PT_STRING8,0x3613)
+#define PR_CONTAINER_CLASS   WINELIB_NAME_AW(PR_CONTAINER_CLASS_)
+#define PR_CONTAINER_MODIFY_VERSION PROP_TAG(PT_I8,0x3614)
+#define PR_AB_PROVIDER_ID PROP_TAG(PT_BINARY,0x3615)
+#define PR_DEFAULT_VIEW_ENTRYID PROP_TAG(PT_BINARY,0x3616)
+#define PR_ASSOC_CONTENT_COUNT PROP_TAG(PT_I4,0x3617)
+#define PR_ATTACHMENT_X400_PARAMETERS PROP_TAG(PT_BINARY,0x3700)
+#define PR_ATTACH_DATA_OBJ PROP_TAG(PT_OBJECT,0x3701)
+#define PR_ATTACH_DATA_BIN PROP_TAG(PT_BINARY,0x3701)
+#define PR_ATTACH_ENCODING PROP_TAG(PT_BINARY,0x3702)
+#define PR_ATTACH_EXTENSION_W PROP_TAG(PT_UNICODE,0x3703)
+#define PR_ATTACH_EXTENSION_A PROP_TAG(PT_STRING8,0x3703)
+#define PR_ATTACH_EXTENSION   WINELIB_NAME_AW(PR_ATTACH_EXTENSION_)
+#define PR_ATTACH_FILENAME_W PROP_TAG(PT_UNICODE,0x3704)
+#define PR_ATTACH_FILENAME_A PROP_TAG(PT_STRING8,0x3704)
+#define PR_ATTACH_FILENAME   WINELIB_NAME_AW(PR_ATTACH_FILENAME_)
+#define PR_ATTACH_METHOD PROP_TAG(PT_I4,0x3705)
+#define PR_ATTACH_LONG_FILENAME_W PROP_TAG(PT_UNICODE,0x3707)
+#define PR_ATTACH_LONG_FILENAME_A PROP_TAG(PT_STRING8,0x3707)
+#define PR_ATTACH_LONG_FILENAME   WINELIB_NAME_AW(PR_ATTACH_LONG_FILENAME_)
+#define PR_ATTACH_PATHNAME_W PROP_TAG(PT_UNICODE,0x3708)
+#define PR_ATTACH_PATHNAME_A PROP_TAG(PT_STRING8,0x3708)
+#define PR_ATTACH_PATHNAME   WINELIB_NAME_AW(PR_ATTACH_PATHNAME_)
+#define PR_ATTACH_RENDERING PROP_TAG(PT_BINARY, 0x3709)
+#define PR_ATTACH_TAG PROP_TAG(PT_BINARY,0x370A)
+#define PR_RENDERING_POSITION PROP_TAG(PT_I4,0x370B)
+#define PR_ATTACH_TRANSPORT_NAME_W PROP_TAG(PT_UNICODE,0x370C)
+#define PR_ATTACH_TRANSPORT_NAME_A PROP_TAG(PT_STRING8,0x370C)
+#define PR_ATTACH_TRANSPORT_NAME   WINELIB_NAME_AW(PR_ATTACH_TRANSPORT_NAME_)
+#define PR_ATTACH_LONG_PATHNAME_W PROP_TAG(PT_UNICODE,0x370D)
+#define PR_ATTACH_LONG_PATHNAME_A PROP_TAG(PT_STRING8,0x370D)
+#define PR_ATTACH_LONG_PATHNAME   WINELIB_NAME_AW(PR_ATTACH_LONG_PATHNAME_)
+#define PR_ATTACH_MIME_TAG_W PROP_TAG(PT_UNICODE,0x370E)
+#define PR_ATTACH_MIME_TAG_A PROP_TAG(PT_STRING8,0x370E)
+#define PR_ATTACH_MIME_TAG   WINELIB_NAME_AW(PR_ATTACH_MIME_TAG_)
+#define PR_ATTACH_ADDITIONAL_INFO PROP_TAG(PT_BINARY,0x370F)
+#define PR_DISPLAY_TYPE PROP_TAG(PT_I4,0x3900)
+#define PR_TEMPLATEID PROP_TAG(PT_BINARY,0x3902)
+#define PR_PRIMARY_CAPABILITY PROP_TAG(PT_BINARY,0x3904)
+#define PR_7BIT_DISPLAY_NAME PROP_TAG(PT_STRING8,0x39FF)
+#define PR_ACCOUNT_W PROP_TAG(PT_UNICODE,0x3A00)
+#define PR_ACCOUNT_A PROP_TAG(PT_STRING8,0x3A00)
+#define PR_ACCOUNT   WINELIB_NAME_AW(PR_ACCOUNT_)
+#define PR_ALTERNATE_RECIPIENT PROP_TAG(PT_BINARY,0x3A01)
+#define PR_CALLBACK_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A02)
+#define PR_CALLBACK_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A02)
+#define PR_CALLBACK_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_CALLBACK_TELEPHONE_NUMBER_)
+#define PR_CONVERSION_PROHIBITED PROP_TAG(PT_BOOLEAN,0x3A03)
+#define PR_DISCLOSE_RECIPIENTS PROP_TAG(PT_BOOLEAN,0x3A04)
+#define PR_GENERATION_W PROP_TAG(PT_UNICODE,0x3A05)
+#define PR_GENERATION_A PROP_TAG(PT_STRING8,0x3A05)
+#define PR_GENERATION   WINELIB_NAME_AW(PR_GENERATION_)
+#define PR_GIVEN_NAME_W PROP_TAG(PT_UNICODE,0x3A06)
+#define PR_GIVEN_NAME_A PROP_TAG(PT_STRING8,0x3A06)
+#define PR_GIVEN_NAME   WINELIB_NAME_AW(PR_GIVEN_NAME_)
+#define PR_GOVERNMENT_ID_NUMBER_W PROP_TAG(PT_UNICODE,0x3A07)
+#define PR_GOVERNMENT_ID_NUMBER_A PROP_TAG(PT_STRING8,0x3A07)
+#define PR_GOVERNMENT_ID_NUMBER   WINELIB_NAME_AW(PR_GOVERNMENT_ID_NUMBER_)
+#define PR_BUSINESS_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A08)
+#define PR_BUSINESS_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A08)
+#define PR_BUSINESS_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_BUSINESS_TELEPHONE_NUMBER_)
+#define PR_OFFICE_TELEPHONE_NUMBER_W PR_BUSINESS_TELEPHONE_NUMBER_W
+#define PR_OFFICE_TELEPHONE_NUMBER_A PR_BUSINESS_TELEPHONE_NUMBER_A
+#define PR_OFFICE_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_OFFICE_TELEPHONE_NUMBER_)
+#define PR_HOME_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A09)
+#define PR_HOME_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A09)
+#define PR_HOME_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_HOME_TELEPHONE_NUMBER_)
+#define PR_INITIALS_W PROP_TAG(PT_UNICODE,0x3A0A)
+#define PR_INITIALS_A PROP_TAG(PT_STRING8,0x3A0A)
+#define PR_INITIALS   WINELIB_NAME_AW(PR_INITIALS_)
+#define PR_KEYWORD_W PROP_TAG(PT_UNICODE,0x3A0B)
+#define PR_KEYWORD_A PROP_TAG(PT_STRING8,0x3A0B)
+#define PR_KEYWORD   WINELIB_NAME_AW(PR_KEYWORD_)
+#define PR_LANGUAGE_W PROP_TAG(PT_UNICODE,0x3A0C)
+#define PR_LANGUAGE_A PROP_TAG(PT_STRING8,0x3A0C)
+#define PR_LANGUAGE   WINELIB_NAME_AW(PR_LANGUAGE_)
+#define PR_LOCATION_W PROP_TAG(PT_UNICODE,0x3A0D)
+#define PR_LOCATION_A PROP_TAG(PT_STRING8,0x3A0D)
+#define PR_LOCATION   WINELIB_NAME_AW(PR_LOCATION_)
+#define PR_MAIL_PERMISSION PROP_TAG(PT_BOOLEAN,0x3A0E)
+#define PR_MHS_COMMON_NAME_W PROP_TAG(PT_UNICODE,0x3A0F)
+#define PR_MHS_COMMON_NAME_A PROP_TAG(PT_STRING8,0x3A0F)
+#define PR_MHS_COMMON_NAME   WINELIB_NAME_AW(PR_MHS_COMMON_NAME_)
+#define PR_ORGANIZATIONAL_ID_NUMBER_W PROP_TAG(PT_UNICODE,0x3A10)
+#define PR_ORGANIZATIONAL_ID_NUMBER_A PROP_TAG(PT_STRING8,0x3A10)
+#define PR_ORGANIZATIONAL_ID_NUMBER   WINELIB_NAME_AW(PR_ORGANIZATIONAL_ID_NUMBER_)
+#define PR_SURNAME_W PROP_TAG(PT_UNICODE,0x3A11)
+#define PR_SURNAME_A PROP_TAG(PT_STRING8,0x3A11)
+#define PR_SURNAME   WINELIB_NAME_AW(PR_SURNAME_)
+#define PR_ORIGINAL_ENTRYID PROP_TAG(PT_BINARY,0x3A12)
+#define PR_ORIGINAL_DISPLAY_NAME_W PROP_TAG(PT_UNICODE,0x3A13)
+#define PR_ORIGINAL_DISPLAY_NAME_A PROP_TAG(PT_STRING8,0x3A13)
+#define PR_ORIGINAL_DISPLAY_NAME   WINELIB_NAME_AW(PR_ORIGINAL_DISPLAY_NAME_)
+#define PR_ORIGINAL_SEARCH_KEY PROP_TAG(PT_BINARY,0x3A14)
+#define PR_POSTAL_ADDRESS_W PROP_TAG(PT_UNICODE,0x3A15)
+#define PR_POSTAL_ADDRESS_A PROP_TAG(PT_STRING8,0x3A15)
+#define PR_POSTAL_ADDRESS   WINELIB_NAME_AW(PR_POSTAL_ADDRESS_)
+#define PR_COMPANY_NAME_W PROP_TAG(PT_UNICODE,0x3A16)
+#define PR_COMPANY_NAME_A PROP_TAG(PT_STRING8,0x3A16)
+#define PR_COMPANY_NAME   WINELIB_NAME_AW(PR_COMPANY_NAME_)
+#define PR_TITLE_W PROP_TAG(PT_UNICODE,0x3A17)
+#define PR_TITLE_A PROP_TAG(PT_STRING8,0x3A17)
+#define PR_TITLE   WINELIB_NAME_AW(PR_TITLE_)
+#define PR_DEPARTMENT_NAME_W PROP_TAG(PT_UNICODE,0x3A18)
+#define PR_DEPARTMENT_NAME_A PROP_TAG(PT_STRING8,0x3A18)
+#define PR_DEPARTMENT_NAME   WINELIB_NAME_AW(PR_DEPARTMENT_NAME_)
+#define PR_OFFICE_LOCATION_W PROP_TAG(PT_UNICODE,0x3A19)
+#define PR_OFFICE_LOCATION_A PROP_TAG(PT_STRING8,0x3A19)
+#define PR_OFFICE_LOCATION   WINELIB_NAME_AW(PR_OFFICE_LOCATION_)
+#define PR_PRIMARY_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A1A)
+#define PR_PRIMARY_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A1A)
+#define PR_PRIMARY_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_PRIMARY_TELEPHONE_NUMBER_)
+#define PR_BUSINESS2_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A1B)
+#define PR_BUSINESS2_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A1B)
+#define PR_BUSINESS2_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_BUSINESS2_TELEPHONE_NUMBER_)
+#define PR_OFFICE2_TELEPHONE_NUMBER_W PR_BUSINESS2_TELEPHONE_NUMBER_W
+#define PR_OFFICE2_TELEPHONE_NUMBER_A PR_BUSINESS2_TELEPHONE_NUMBER_A
+#define PR_OFFICE2_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_OFFICE2_TELEPHONE_NUMBER_)
+#define PR_MOBILE_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A1C)
+#define PR_MOBILE_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A1C)
+#define PR_MOBILE_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_MOBILE_TELEPHONE_NUMBER_)
+#define PR_CELLULAR_TELEPHONE_NUMBER_W PR_MOBILE_TELEPHONE_NUMBER_W
+#define PR_CELLULAR_TELEPHONE_NUMBER_A PR_MOBILE_TELEPHONE_NUMBER_A
+#define PR_CELLULAR_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_CELLULAR_TELEPHONE_NUMBER_)
+#define PR_RADIO_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A1D)
+#define PR_RADIO_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A1D)
+#define PR_RADIO_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_RADIO_TELEPHONE_NUMBER_)
+#define PR_CAR_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A1E)
+#define PR_CAR_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A1E)
+#define PR_CAR_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_CAR_TELEPHONE_NUMBER_)
+#define PR_OTHER_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A1F)
+#define PR_OTHER_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A1F)
+#define PR_OTHER_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_OTHER_TELEPHONE_NUMBER_)
+#define PR_TRANSMITABLE_DISPLAY_NAME_W PROP_TAG(PT_UNICODE,0x3A20)
+#define PR_TRANSMITABLE_DISPLAY_NAME_A PROP_TAG(PT_STRING8,0x3A20)
+#define PR_TRANSMITABLE_DISPLAY_NAME   WINELIB_NAME_AW(PR_TRANSMITABLE_DISPLAY_NAME_)
+#define PR_PAGER_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A21)
+#define PR_PAGER_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A21)
+#define PR_PAGER_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_PAGER_TELEPHONE_NUMBER_)
+#define PR_BEEPER_TELEPHONE_NUMBER_W PR_PAGER_TELEPHONE_NUMBER_W
+#define PR_BEEPER_TELEPHONE_NUMBER_A PR_PAGER_TELEPHONE_NUMBER_A
+#define PR_BEEPER_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_BEEPER_TELEPHONE_NUMBER_)
+#define PR_USER_CERTIFICATE PROP_TAG(PT_BINARY,0x3A22)
+#define PR_PRIMARY_FAX_NUMBER_W PROP_TAG(PT_UNICODE,0x3A23)
+#define PR_PRIMARY_FAX_NUMBER_A PROP_TAG(PT_STRING8,0x3A23)
+#define PR_PRIMARY_FAX_NUMBER   WINELIB_NAME_AW(PR_PRIMARY_FAX_NUMBER_)
+#define PR_BUSINESS_FAX_NUMBER_W PROP_TAG(PT_UNICODE,0x3A24)
+#define PR_BUSINESS_FAX_NUMBER_A PROP_TAG(PT_STRING8,0x3A24)
+#define PR_BUSINESS_FAX_NUMBER   WINELIB_NAME_AW(PR_BUSINESS_FAX_NUMBER_)
+#define PR_HOME_FAX_NUMBER_W PROP_TAG(PT_UNICODE,0x3A25)
+#define PR_HOME_FAX_NUMBER_A PROP_TAG(PT_STRING8,0x3A25)
+#define PR_HOME_FAX_NUMBER   WINELIB_NAME_AW(PR_HOME_FAX_NUMBER_)
+#define PR_COUNTRY_W PROP_TAG(PT_UNICODE,0x3A26)
+#define PR_COUNTRY_A PROP_TAG(PT_STRING8,0x3A26)
+#define PR_COUNTRY   WINELIB_NAME_AW(PR_COUNTRY_)
+#define PR_BUSINESS_ADDRESS_COUNTRY_W PR_COUNTRY_W
+#define PR_BUSINESS_ADDRESS_COUNTRY_A PR_COUNTRY_A
+#define PR_BUSINESS_ADDRESS_COUNTRY   WINELIB_NAME_AW(PR_BUSINESS_ADDRESS_COUNTRY_)
+#define PR_LOCALITY_W PROP_TAG(PT_UNICODE,0x3A27)
+#define PR_LOCALITY_A PROP_TAG(PT_STRING8,0x3A27)
+#define PR_LOCALITY   WINELIB_NAME_AW(PR_LOCALITY_)
+#define PR_BUSINESS_ADDRESS_CITY_W PR_LOCALITY_W
+#define PR_BUSINESS_ADDRESS_CITY_A PR_LOCALITY_A
+#define PR_BUSINESS_ADDRESS_CITY   WINELIB_NAME_AW(PR_BUSINESS_ADDRESS_CITY_)
+#define PR_STATE_OR_PROVINCE_W PROP_TAG(PT_UNICODE,0x3A28)
+#define PR_STATE_OR_PROVINCE_A PROP_TAG(PT_STRING8,0x3A28)
+#define PR_STATE_OR_PROVINCE   WINELIB_NAME_AW(PR_STATE_OR_PROVINCE_)
+#define PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE_W PR_STATE_OR_PROVINCE_W
+#define PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE_A PR_STATE_OR_PROVINCE_A
+#define PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE   WINELIB_NAME_AW(PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE_)
+#define PR_STREET_ADDRESS_W PROP_TAG(PT_UNICODE,0x3A29)
+#define PR_STREET_ADDRESS_A PROP_TAG(PT_STRING8,0x3A29)
+#define PR_STREET_ADDRESS   WINELIB_NAME_AW(PR_STREET_ADDRESS_)
+#define PR_BUSINESS_ADDRESS_STREET_W PR_STREET_ADDRESS_W
+#define PR_BUSINESS_ADDRESS_STREET_A PR_STREET_ADDRESS_A
+#define PR_BUSINESS_ADDRESS_STREET   WINELIB_NAME_AW(PR_BUSINESS_ADDRESS_STREET_)
+#define PR_POSTAL_CODE_W PROP_TAG(PT_UNICODE,0x3A2A)
+#define PR_POSTAL_CODE_A PROP_TAG(PT_STRING8,0x3A2A)
+#define PR_POSTAL_CODE   WINELIB_NAME_AW(PR_POSTAL_CODE_)
+#define PR_BUSINESS_ADDRESS_POSTAL_CODE_W PR_POSTAL_CODE_W
+#define PR_BUSINESS_ADDRESS_POSTAL_CODE_A PR_POSTAL_CODE_A
+#define PR_BUSINESS_ADDRESS_POSTAL_CODE   WINELIB_NAME_AW(PR_BUSINESS_ADDRESS_POSTAL_CODE_)
+#define PR_POST_OFFICE_BOX_W PROP_TAG(PT_UNICODE,0x3A2B)
+#define PR_POST_OFFICE_BOX_A PROP_TAG(PT_STRING8,0x3A2B)
+#define PR_POST_OFFICE_BOX   WINELIB_NAME_AW(PR_POST_OFFICE_BOX_)
+#define PR_BUSINESS_ADDRESS_POST_OFFICE_BOX_W PR_POST_OFFICE_BOX_W
+#define PR_BUSINESS_ADDRESS_POST_OFFICE_BOX_A PR_POST_OFFICE_BOX_A
+#define PR_BUSINESS_ADDRESS_POST_OFFICE_BOX   WINELIB_NAME_AW(PR_BUSINESS_ADDRESS_POST_OFFICE_BOX_)
+#define PR_TELEX_NUMBER_W PROP_TAG(PT_UNICODE,0x3A2C)
+#define PR_TELEX_NUMBER_A PROP_TAG(PT_STRING8,0x3A2C)
+#define PR_TELEX_NUMBER   WINELIB_NAME_AW(PR_TELEX_NUMBER_)
+#define PR_ISDN_NUMBER_W PROP_TAG(PT_UNICODE,0x3A2D)
+#define PR_ISDN_NUMBER_A PROP_TAG(PT_STRING8,0x3A2D)
+#define PR_ISDN_NUMBER   WINELIB_NAME_AW(PR_ISDN_NUMBER_)
+#define PR_ASSISTANT_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A2E)
+#define PR_ASSISTANT_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A2E)
+#define PR_ASSISTANT_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_ASSISTANT_TELEPHONE_NUMBER_)
+#define PR_HOME2_TELEPHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A2F)
+#define PR_HOME2_TELEPHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A2F)
+#define PR_HOME2_TELEPHONE_NUMBER   WINELIB_NAME_AW(PR_HOME2_TELEPHONE_NUMBER_)
+#define PR_ASSISTANT_W PROP_TAG(PT_UNICODE,0x3A30)
+#define PR_ASSISTANT_A PROP_TAG(PT_STRING8,0x3A30)
+#define PR_ASSISTANT   WINELIB_NAME_AW(PR_ASSISTANT_)
+#define PR_SEND_RICH_INFO PROP_TAG(PT_BOOLEAN,0x3A40)
+#define PR_WEDDING_ANNIVERSARY PROP_TAG(PT_SYSTIME,0x3A41)
+#define PR_BIRTHDAY PROP_TAG(PT_SYSTIME,0x3A42)
+#define PR_HOBBIES_W PROP_TAG(PT_UNICODE,0x3A43)
+#define PR_HOBBIES_A PROP_TAG(PT_STRING8,0x3A43)
+#define PR_HOBBIES   WINELIB_NAME_AW(PR_HOBBIES_)
+#define PR_MIDDLE_NAME_W PROP_TAG(PT_UNICODE,0x3A44)
+#define PR_MIDDLE_NAME_A PROP_TAG(PT_STRING8,0x3A44)
+#define PR_MIDDLE_NAME   WINELIB_NAME_AW(PR_MIDDLE_NAME_)
+#define PR_DISPLAY_NAME_PREFIX_W PROP_TAG(PT_UNICODE,0x3A45)
+#define PR_DISPLAY_NAME_PREFIX_A PROP_TAG(PT_STRING8,0x3A45)
+#define PR_DISPLAY_NAME_PREFIX   WINELIB_NAME_AW(PR_DISPLAY_NAME_PREFIX_)
+#define PR_PROFESSION_W PROP_TAG(PT_UNICODE,0x3A46)
+#define PR_PROFESSION_A PROP_TAG(PT_STRING8,0x3A46)
+#define PR_PROFESSION   WINELIB_NAME_AW(PR_PROFESSION_)
+#define PR_PREFERRED_BY_NAME_W PROP_TAG(PT_UNICODE,0x3A47)
+#define PR_PREFERRED_BY_NAME_A PROP_TAG(PT_STRING8,0x3A47)
+#define PR_PREFERRED_BY_NAME   WINELIB_NAME_AW(PR_PREFERRED_BY_NAME_)
+#define PR_SPOUSE_NAME_W PROP_TAG(PT_UNICODE,0x3A48)
+#define PR_SPOUSE_NAME_A PROP_TAG(PT_STRING8,0x3A48)
+#define PR_SPOUSE_NAME   WINELIB_NAME_AW(PR_SPOUSE_NAME_)
+#define PR_COMPUTER_NETWORK_NAME_W PROP_TAG(PT_UNICODE,0x3A49)
+#define PR_COMPUTER_NETWORK_NAME_A PROP_TAG(PT_STRING8,0x3A49)
+#define PR_COMPUTER_NETWORK_NAME   WINELIB_NAME_AW(PR_COMPUTER_NETWORK_NAME_)
+#define PR_CUSTOMER_ID_W PROP_TAG(PT_UNICODE,0x3A4A)
+#define PR_CUSTOMER_ID_A PROP_TAG(PT_STRING8,0x3A4A)
+#define PR_CUSTOMER_ID   WINELIB_NAME_AW(PR_CUSTOMER_ID_)
+#define PR_TTYTDD_PHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A4B)
+#define PR_TTYTDD_PHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A4B)
+#define PR_TTYTDD_PHONE_NUMBER   WINELIB_NAME_AW(PR_TTYTDD_PHONE_NUMBER_)
+#define PR_FTP_SITE_W PROP_TAG(PT_UNICODE,0x3A4C)
+#define PR_FTP_SITE_A PROP_TAG(PT_STRING8,0x3A4C)
+#define PR_FTP_SITE   WINELIB_NAME_AW(PR_FTP_SITE_)
+#define PR_GENDER PROP_TAG(PT_I2,0x3A4D)
+#define PR_MANAGER_NAME_W PROP_TAG(PT_UNICODE,0x3A4E)
+#define PR_MANAGER_NAME_A PROP_TAG(PT_STRING8,0x3A4E)
+#define PR_MANAGER_NAME   WINELIB_NAME_AW(PR_MANAGER_NAME_)
+#define PR_NICKNAME_W PROP_TAG(PT_UNICODE,0x3A4F)
+#define PR_NICKNAME_A PROP_TAG(PT_STRING8,0x3A4F)
+#define PR_NICKNAME   WINELIB_NAME_AW(PR_NICKNAME_)
+#define PR_PERSONAL_HOME_PAGE_W PROP_TAG(PT_UNICODE,0x3A50)
+#define PR_PERSONAL_HOME_PAGE_A PROP_TAG(PT_STRING8,0x3A50)
+#define PR_PERSONAL_HOME_PAGE   WINELIB_NAME_AW(PR_PERSONAL_HOME_PAGE_)
+#define PR_BUSINESS_HOME_PAGE_W PROP_TAG(PT_UNICODE,0x3A51)
+#define PR_BUSINESS_HOME_PAGE_A PROP_TAG(PT_STRING8,0x3A51)
+#define PR_BUSINESS_HOME_PAGE   WINELIB_NAME_AW(PR_BUSINESS_HOME_PAGE_)
+#define PR_CONTACT_VERSION PROP_TAG(PT_CLSID,0x3A52)
+#define PR_CONTACT_ENTRYIDS PROP_TAG(PT_MV_BINARY,0x3A53)
+#define PR_CONTACT_ADDRTYPES_W PROP_TAG(PT_MV_UNICODE,0x3A54)
+#define PR_CONTACT_ADDRTYPES_A PROP_TAG(PT_MV_STRING8,0x3A54)
+#define PR_CONTACT_ADDRTYPES   WINELIB_NAME_AW(PR_CONTACT_ADDRTYPES_)
+#define PR_CONTACT_DEFAULT_ADDRESS_INDEX PROP_TAG(PT_I4,0x3A55)
+#define PR_CONTACT_EMAIL_ADDRESSES_W PROP_TAG(PT_MV_UNICODE,0x3A56)
+#define PR_CONTACT_EMAIL_ADDRESSES_A PROP_TAG(PT_MV_STRING8,0x3A56)
+#define PR_CONTACT_EMAIL_ADDRESSES   WINELIB_NAME_AW(PR_CONTACT_EMAIL_ADDRESSES_)
+#define PR_COMPANY_MAIN_PHONE_NUMBER_W PROP_TAG(PT_UNICODE,0x3A57)
+#define PR_COMPANY_MAIN_PHONE_NUMBER_A PROP_TAG(PT_STRING8,0x3A57)
+#define PR_COMPANY_MAIN_PHONE_NUMBER   WINELIB_NAME_AW(PR_COMPANY_MAIN_PHONE_NUMBER_)
+#define PR_CHILDRENS_NAMES_W PROP_TAG(PT_MV_UNICODE,0x3A58)
+#define PR_CHILDRENS_NAMES_A PROP_TAG(PT_MV_STRING8,0x3A58)
+#define PR_CHILDRENS_NAMES   WINELIB_NAME_AW(PR_CHILDRENS_NAMES_)
+#define PR_HOME_ADDRESS_CITY_W PROP_TAG(PT_UNICODE,0x3A59)
+#define PR_HOME_ADDRESS_CITY_A PROP_TAG(PT_STRING8,0x3A59)
+#define PR_HOME_ADDRESS_CITY   WINELIB_NAME_AW(PR_HOME_ADDRESS_CITY_)
+#define PR_HOME_ADDRESS_COUNTRY_W PROP_TAG(PT_UNICODE,0x3A5A)
+#define PR_HOME_ADDRESS_COUNTRY_A PROP_TAG(PT_STRING8,0x3A5A)
+#define PR_HOME_ADDRESS_COUNTRY   WINELIB_NAME_AW(PR_HOME_ADDRESS_COUNTRY_)
+#define PR_HOME_ADDRESS_POSTAL_CODE_W PROP_TAG(PT_UNICODE,0x3A5B)
+#define PR_HOME_ADDRESS_POSTAL_CODE_A PROP_TAG(PT_STRING8,0x3A5B)
+#define PR_HOME_ADDRESS_POSTAL_CODE   WINELIB_NAME_AW(PR_HOME_ADDRESS_POSTAL_CODE_)
+#define PR_HOME_ADDRESS_STATE_OR_PROVINCE_W PROP_TAG(PT_UNICODE,0x3A5C)
+#define PR_HOME_ADDRESS_STATE_OR_PROVINCE_A PROP_TAG(PT_STRING8,0x3A5C)
+#define PR_HOME_ADDRESS_STATE_OR_PROVINCE   WINELIB_NAME_AW(PR_HOME_ADDRESS_STATE_OR_PROVINCE_)
+#define PR_HOME_ADDRESS_STREET_W PROP_TAG(PT_UNICODE,0x3A5D)
+#define PR_HOME_ADDRESS_STREET_A PROP_TAG(PT_STRING8,0x3A5D)
+#define PR_HOME_ADDRESS_STREET   WINELIB_NAME_AW(PR_HOME_ADDRESS_STREET_)
+#define PR_HOME_ADDRESS_POST_OFFICE_BOX_W PROP_TAG(PT_UNICODE,0x3A5E)
+#define PR_HOME_ADDRESS_POST_OFFICE_BOX_A PROP_TAG(PT_STRING8,0x3A5E)
+#define PR_HOME_ADDRESS_POST_OFFICE_BOX   WINELIB_NAME_AW(PR_HOME_ADDRESS_POST_OFFICE_BOX_)
+#define PR_OTHER_ADDRESS_CITY_W PROP_TAG(PT_UNICODE,0x3A5F)
+#define PR_OTHER_ADDRESS_CITY_A PROP_TAG(PT_STRING8,0x3A5F)
+#define PR_OTHER_ADDRESS_CITY   WINELIB_NAME_AW(PR_OTHER_ADDRESS_CITY_)
+#define PR_OTHER_ADDRESS_COUNTRY_W PROP_TAG(PT_UNICODE,0x3A60)
+#define PR_OTHER_ADDRESS_COUNTRY_A PROP_TAG(PT_STRING8,0x3A60)
+#define PR_OTHER_ADDRESS_COUNTRY   WINELIB_NAME_AW(PR_OTHER_ADDRESS_COUNTRY_)
+#define PR_OTHER_ADDRESS_POSTAL_CODE_W PROP_TAG(PT_UNICODE,0x3A61)
+#define PR_OTHER_ADDRESS_POSTAL_CODE_A PROP_TAG(PT_STRING8,0x3A61)
+#define PR_OTHER_ADDRESS_POSTAL_CODE   WINELIB_NAME_AW(PR_OTHER_ADDRESS_POSTAL_CODE_)
+#define PR_OTHER_ADDRESS_STATE_OR_PROVINCE_W PROP_TAG(PT_UNICODE,0x3A62)
+#define PR_OTHER_ADDRESS_STATE_OR_PROVINCE_A PROP_TAG(PT_STRING8,0x3A62)
+#define PR_OTHER_ADDRESS_STATE_OR_PROVINCE   WINELIB_NAME_AW(PR_OTHER_ADDRESS_STATE_OR_PROVINCE_)
+#define PR_OTHER_ADDRESS_STREET_W PROP_TAG(PT_UNICODE,0x3A63)
+#define PR_OTHER_ADDRESS_STREET_A PROP_TAG(PT_STRING8,0x3A63)
+#define PR_OTHER_ADDRESS_STREET   WINELIB_NAME_AW(PR_OTHER_ADDRESS_STREET_)
+#define PR_OTHER_ADDRESS_POST_OFFICE_BOX_W PROP_TAG(PT_UNICODE,0x3A64)
+#define PR_OTHER_ADDRESS_POST_OFFICE_BOX_A PROP_TAG(PT_STRING8,0x3A64)
+#define PR_OTHER_ADDRESS_POST_OFFICE_BOX   WINELIB_NAME_AW(PR_OTHER_ADDRESS_POST_OFFICE_BOX_)
+#define PR_STORE_PROVIDERS PROP_TAG(PT_BINARY,0x3D00)
+#define PR_AB_PROVIDERS PROP_TAG(PT_BINARY,0x3D01)
+#define PR_TRANSPORT_PROVIDERS PROP_TAG(PT_BINARY,0x3D02)
+#define PR_DEFAULT_PROFILE PROP_TAG(PT_BOOLEAN,0x3D04)
+#define PR_AB_SEARCH_PATH PROP_TAG(PT_MV_BINARY,0x3D05)
+#define PR_AB_DEFAULT_DIR PROP_TAG(PT_BINARY,0x3D06)
+#define PR_AB_DEFAULT_PAB PROP_TAG(PT_BINARY,0x3D07)
+#define PR_FILTERING_HOOKS PROP_TAG(PT_BINARY, 0x3D08)
+#define PR_SERVICE_NAME_W PROP_TAG(PT_UNICODE,0x3D09)
+#define PR_SERVICE_NAME_A PROP_TAG(PT_STRING8,0x3D09)
+#define PR_SERVICE_NAME   WINELIB_NAME_AW(PR_SERVICE_NAME_)
+#define PR_SERVICE_DLL_NAME_W PROP_TAG(PT_UNICODE,0x3D0A)
+#define PR_SERVICE_DLL_NAME_A PROP_TAG(PT_STRING8,0x3D0A)
+#define PR_SERVICE_DLL_NAME   WINELIB_NAME_AW(PR_SERVICE_DLL_NAME_)
+#define PR_SERVICE_ENTRY_NAME PROP_TAG(PT_STRING8,0x3D0B)
+#define PR_SERVICE_UID PROP_TAG(PT_BINARY,0x3D0C)
+#define PR_SERVICE_EXTRA_UIDS PROP_TAG(PT_BINARY,0x3D0D)
+#define PR_SERVICES PROP_TAG(PT_BINARY,0x3D0E)
+#define PR_SERVICE_SUPPORT_FILES_W PROP_TAG(PT_MV_UNICODE,0x3D0F)
+#define PR_SERVICE_SUPPORT_FILES_A PROP_TAG(PT_MV_STRING8,0x3D0F)
+#define PR_SERVICE_SUPPORT_FILES   WINELIB_NAME_AW(PR_SERVICE_SUPPORT_FILES_)
+#define PR_SERVICE_DELETE_FILES_W PROP_TAG(PT_MV_UNICODE,0x3D10)
+#define PR_SERVICE_DELETE_FILES_A PROP_TAG(PT_MV_STRING8,0x3D10)
+#define PR_SERVICE_DELETE_FILES   WINELIB_NAME_AW(PR_SERVICE_DELETE_FILES_)
+#define PR_AB_SEARCH_PATH_UPDATE PROP_TAG(PT_BINARY,0x3D11)
+#define PR_PROFILE_NAME_A PROP_TAG(PT_STRING8,0x3D12)
+#define PR_PROFILE_NAME_W PROP_TAG(PT_UNICODE,0x3D12)
+#define PR_PROFILE_NAME   WINELIB_NAME_AW(PR_PROFILE_NAME_)
+#define PR_IDENTITY_DISPLAY_W PROP_TAG(PT_UNICODE,0x3E00)
+#define PR_IDENTITY_DISPLAY_A PROP_TAG(PT_STRING8,0x3E00)
+#define PR_IDENTITY_DISPLAY   WINELIB_NAME_AW(PR_IDENTITY_DISPLAY_)
+#define PR_IDENTITY_ENTRYID PROP_TAG(PT_BINARY,0x3E01)
+#define PR_RESOURCE_METHODS PROP_TAG(PT_I4,0x3E02)
+/* Service provider type */
+#define PR_RESOURCE_TYPE PROP_TAG(PT_I4,0x3E03)
+#define PR_STATUS_CODE PROP_TAG(PT_I4,0x3E04)
+#define PR_IDENTITY_SEARCH_KEY PROP_TAG(PT_BINARY,0x3E05)
+#define PR_OWN_STORE_ENTRYID PROP_TAG(PT_BINARY,0x3E06)
+#define PR_RESOURCE_PATH_W PROP_TAG(PT_UNICODE,0x3E07)
+#define PR_RESOURCE_PATH_A PROP_TAG(PT_STRING8,0x3E07)
+#define PR_RESOURCE_PATH   WINELIB_NAME_AW(PR_RESOURCE_PATH_)
+#define PR_STATUS_STRING_W PROP_TAG(PT_UNICODE,0x3E08)
+#define PR_STATUS_STRING_A PROP_TAG(PT_STRING8,0x3E08)
+#define PR_STATUS_STRING   WINELIB_NAME_AW(PR_STATUS_STRING_)
+#define PR_X400_DEFERRED_DELIVERY_CANCEL PROP_TAG(PT_BOOLEAN,0x3E09)
+#define PR_HEADER_FOLDER_ENTRYID PROP_TAG(PT_BINARY,0x3E0A)
+#define PR_REMOTE_PROGRESS PROP_TAG(PT_I4,0x3E0B)
+#define PR_REMOTE_PROGRESS_TEXT_W PROP_TAG(PT_UNICODE,0x3E0C)
+#define PR_REMOTE_PROGRESS_TEXT_A PROP_TAG(PT_STRING8,0x3E0C)
+#define PR_REMOTE_PROGRESS_TEXT   WINELIB_NAME_AW(PR_REMOTE_PROGRESS_TEXT_)
+#define PR_REMOTE_VALIDATE_OK PROP_TAG(PT_BOOLEAN,0x3E0D)
+#define PR_CONTROL_FLAGS PROP_TAG(PT_I4,0x3F00)
+#define PR_CONTROL_STRUCTURE PROP_TAG(PT_BINARY,0x3F01)
+#define PR_CONTROL_TYPE PROP_TAG(PT_I4,0x3F02)
+#define PR_DELTAX PROP_TAG(PT_I4,0x3F03)
+#define PR_DELTAY PROP_TAG(PT_I4,0x3F04)
+#define PR_XPOS PROP_TAG(PT_I4,0x3F05)
+#define PR_YPOS PROP_TAG(PT_I4,0x3F06)
+#define PR_CONTROL_ID PROP_TAG(PT_BINARY,0x3F07)
+#define PR_INITIAL_DETAILS_PANE PROP_TAG(PT_I4,0x3F08)
+
+#define PROP_ID_SECURE_MIN 0x67F0
+#define PROP_ID_SECURE_MAX 0x67FF
+
+#endif /* MAPITAGS_H */
diff --git a/reactos/w32api/include/mapiutil.h b/reactos/w32api/include/mapiutil.h
new file mode 100644 (file)
index 0000000..408144e
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * 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
+ */
+
+#ifndef MAPIUTIL_H_
+#define MAPIUTIL_H_
+
+#include <mapix.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TAD_ALL_ROWS 1 /* Delete all rows */
+
+LPMALLOC WINAPI MAPIGetDefaultMalloc(void);
+
+#define SOF_UNIQUEFILENAME 0x80000000U /* Create a unique (temporary) filename */
+
+#if defined (UNICODE) || defined (__WINESRC__)
+typedef HRESULT (WINAPI * LPOPENSTREAMONFILE)(LPALLOCATEBUFFER,LPFREEBUFFER,
+                                              ULONG,LPWSTR,LPWSTR,LPSTREAM*);
+HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER,LPFREEBUFFER,
+                                ULONG,LPWSTR,LPWSTR,LPSTREAM*);
+#else
+typedef HRESULT (WINAPI * LPOPENSTREAMONFILE)(LPALLOCATEBUFFER,LPFREEBUFFER,
+                                              ULONG,LPSTR,LPSTR,LPSTREAM*);
+HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER,LPFREEBUFFER,
+                                ULONG,LPSTR,LPSTR,LPSTREAM*);
+#endif
+#define OPENSTREAMONFILE "OpenStreamOnFile"
+
+BOOL WINAPI FEqualNames(LPMAPINAMEID,LPMAPINAMEID);
+
+typedef struct IPropData *LPPROPDATA;
+
+#define IPROP_READONLY  0x00001U
+#define IPROP_READWRITE 0x00002U
+#define IPROP_CLEAN     0x10000U
+#define IPROP_DIRTY     0x20000U
+
+SCODE WINAPI CreateIProp(LPCIID,ALLOCATEBUFFER*,ALLOCATEMORE*,FREEBUFFER*,
+                         LPVOID,LPPROPDATA*);
+SCODE WINAPI PropCopyMore(LPSPropValue,LPSPropValue,ALLOCATEMORE*,LPVOID);
+ULONG WINAPI UlPropSize(LPSPropValue);
+VOID  WINAPI GetInstance(LPSPropValue,LPSPropValue,ULONG);
+BOOL  WINAPI FPropContainsProp(LPSPropValue,LPSPropValue,ULONG);
+BOOL  WINAPI FPropCompareProp(LPSPropValue,ULONG,LPSPropValue);
+LONG  WINAPI LPropCompareProp(LPSPropValue,LPSPropValue);
+
+HRESULT WINAPI HrAddColumns(LPMAPITABLE,LPSPropTagArray,LPALLOCATEBUFFER,LPFREEBUFFER);
+HRESULT WINAPI HrAddColumnsEx(LPMAPITABLE,LPSPropTagArray,LPALLOCATEBUFFER,
+                              LPFREEBUFFER,void (*)(LPSPropTagArray));
+HRESULT WINAPI HrAllocAdviseSink(LPNOTIFCALLBACK,LPVOID,LPMAPIADVISESINK*);
+HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK,LPMAPIADVISESINK*);
+HRESULT WINAPI HrDispatchNotifications (ULONG);
+
+ULONG WINAPI UlAddRef(void*);
+ULONG WINAPI UlRelease(void*);
+
+HRESULT WINAPI HrGetOneProp(LPMAPIPROP,ULONG,LPSPropValue*);
+HRESULT WINAPI HrSetOneProp(LPMAPIPROP,LPSPropValue);
+BOOL    WINAPI FPropExists(LPMAPIPROP,ULONG);
+void    WINAPI FreePadrlist(LPADRLIST);
+void    WINAPI FreeProws(LPSRowSet);
+HRESULT WINAPI HrQueryAllRows(LPMAPITABLE,LPSPropTagArray,LPSRestriction,
+                              LPSSortOrderSet,LONG,LPSRowSet*);
+LPSPropValue WINAPI PpropFindProp(LPSPropValue,ULONG,ULONG);
+
+#if defined (UNICODE) || defined (__WINESRC__)
+BOOL   WINAPI FBinFromHex(LPWSTR,LPBYTE);
+SCODE  WINAPI ScBinFromHexBounded(LPWSTR,LPBYTE,ULONG);
+void   WINAPI HexFromBin(LPBYTE,int,LPWSTR);
+ULONG  WINAPI UlFromSzHex(LPCWSTR);
+LPWSTR WINAPI SzFindCh(LPCWSTR,USHORT);
+LPWSTR WINAPI SzFindLastCh(LPCWSTR,USHORT);
+LPWSTR WINAPI SzFindSz(LPCWSTR,LPCWSTR);
+UINT   WINAPI UFromSz(LPCSTR);
+#else
+BOOL  WINAPI FBinFromHex(LPSTR,LPBYTE);
+SCODE WINAPI ScBinFromHexBounded(LPSTR,LPBYTE,ULONG);
+void  WINAPI HexFromBin(LPBYTE,int,LPSTR);
+ULONG WINAPI UlFromSzHex(LPCSTR);
+LPSTR WINAPI SzFindCh(LPCSTR,USHORT);
+LPSTR WINAPI SzFindLastCh(LPCSTR,USHORT);
+LPSTR WINAPI SzFindSz(LPCSTR,LPCSTR);
+UINT  WINAPI UFromSz(LPCSTR);
+#endif
+
+SCODE WINAPI ScInitMapiUtil(ULONG);
+void  WINAPI DeinitMapiUtil(void);
+
+#define szHrDispatchNotifications "_HrDispatchNotifications@4"
+#define szScCreateConversationIndex "_ScCreateConversationIndex@16"
+
+typedef HRESULT (WINAPI DISPATCHNOTIFICATIONS)(ULONG);
+typedef DISPATCHNOTIFICATIONS *LPDISPATCHNOTIFICATIONS;
+typedef SCODE (WINAPI CREATECONVERSATIONINDEX)(ULONG,LPBYTE,ULONG*,LPBYTE*);
+typedef CREATECONVERSATIONINDEX *LPCREATECONVERSATIONINDEX;
+
+typedef struct ITableData *LPTABLEDATA;
+
+typedef void (WINAPI CALLERRELEASE)(ULONG,LPTABLEDATA,LPMAPITABLE);
+
+/*****************************************************************************
+ * ITableData interface
+ *
+ * The underlying table data structure for IMAPITable.
+ */
+#define INTERFACE ITableData
+DECLARE_INTERFACE_(ITableData,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** ITableData methods ***/
+    STDMETHOD(HrGetView)(THIS_ LPSSortOrderSet lpSort, CALLERRELEASE *lpRel,
+                         ULONG ulData, LPMAPITABLE *lppTable) PURE;
+    STDMETHOD(HrModifyRow)(THIS_ LPSRow lpRow) PURE;
+    STDMETHOD(HrDeleteRow)(THIS_ LPSPropValue lpKey) PURE;
+    STDMETHOD(HrQueryRow)(THIS_ LPSPropValue lpKey, LPSRow *lppRow, ULONG *lpRowNum) PURE;
+    STDMETHOD(HrEnumRow)(THIS_ ULONG ulRowNum, LPSRow *lppRow) PURE;
+    STDMETHOD(HrNotify)(THIS_ ULONG ulFlags, ULONG cValues, LPSPropValue lpValues) PURE;
+    STDMETHOD(HrInsertRow)(THIS_ ULONG ulRow, LPSRow lpRow) PURE;
+    STDMETHOD(HrModifyRows)(THIS_ ULONG ulFlags, LPSRowSet lpRows) PURE;
+    STDMETHOD(HrDeleteRows)(THIS_ ULONG ulFlags, LPSRowSet lpRows, ULONG *lpCount) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+        /*** IUnknown methods ***/
+#define ITableData_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define ITableData_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define ITableData_Release(p)            (p)->lpVtbl->Release(p)
+        /*** ITableData methods ***/
+#define ITableData_HrGetView(p,a,b,c,d)  (p)->lpVtbl->HrGetView(p,a,b,c,d)
+#define ITableData_HrModifyRow(p,a)      (p)->lpVtbl->HrModifyRow(p,a)
+#define ITableData_HrDeleteRow(p,a)      (p)->lpVtbl->HrDeleteRow(p,a)
+#define ITableData_HrQueryRow(p,a,b,c)   (p)->lpVtbl->HrQueryRow(p,a,b,c)
+#define ITableData_HrEnumRow(p,a,b)      (p)->lpVtbl->HrEnumRow(p,a,b)
+#define ITableData_HrNotify(p,a,b,c)     (p)->lpVtbl->HrNotify(p,a,b,c)
+#define ITableData_HrInsertRow(p,a,b)    (p)->lpVtbl->HrInsertRow(p,a,b)
+#define ITableData_HrModifyRows(p,a,b)   (p)->lpVtbl->HrModifyRows(p,a,b)
+#define ITableData_HrDeleteRows(p,a,b,c) (p)->lpVtbl->HrDeleteRows(p,a,b,c)
+#endif
+
+SCODE WINAPI CreateTable(LPCIID,ALLOCATEBUFFER*,ALLOCATEMORE*,FREEBUFFER*,
+                         LPVOID,ULONG,ULONG,LPSPropTagArray,LPTABLEDATA*);
+
+SCODE WINAPI ScCountNotifications(int,LPNOTIFICATION,ULONG*);
+SCODE WINAPI ScCountProps(int,LPSPropValue,ULONG*);
+SCODE WINAPI ScCopyNotifications(int,LPNOTIFICATION,LPVOID,ULONG*);
+SCODE WINAPI ScCopyProps(int,LPSPropValue,LPVOID,ULONG*);
+SCODE WINAPI ScDupPropset(int,LPSPropValue,LPALLOCATEBUFFER,LPSPropValue*);
+SCODE WINAPI ScRelocNotifications(int,LPNOTIFICATION,LPVOID,LPVOID,ULONG*);
+SCODE WINAPI ScRelocProps(int,LPSPropValue,LPVOID,LPVOID,ULONG*);
+
+LPSPropValue WINAPI LpValFindProp(ULONG,ULONG,LPSPropValue);
+
+static inline FILETIME FtAddFt(FILETIME ftLeft, FILETIME ftRight)
+{
+    LONG64 *pl = (LONG64*)&ftLeft, *pr = (LONG64*)&ftRight;
+    union { FILETIME ft; LONG64 ll; } ftmap;    
+    ftmap.ll = *pl + *pr;
+    return ftmap.ft;
+}
+
+static inline FILETIME FtSubFt(FILETIME ftLeft, FILETIME ftRight)
+{
+    LONG64 *pl = (LONG64*)&ftLeft, *pr = (LONG64*)&ftRight;
+    union { FILETIME ft; LONG64 ll; } ftmap;    
+    ftmap.ll = *pl - *pr;
+    return ftmap.ft;
+}
+
+static inline FILETIME FtNegFt(FILETIME ftLeft)
+{
+    LONG64 *p = (LONG64*)&ftLeft;
+    union { FILETIME ft; LONG64 ll; } ftmap;    
+    ftmap.ll = -*p;
+    return ftmap.ft;
+}
+
+static inline FILETIME FtMulDw(DWORD dwLeft, FILETIME ftRight)
+{
+    LONG64 l = (LONG64)dwLeft, *pr = (LONG64*)&ftRight;
+    union { FILETIME ft; LONG64 ll; } ftmap;    
+    ftmap.ll = l * (*pr);
+    return ftmap.ft;
+}
+
+static inline FILETIME FtMulDwDw(DWORD dwLeft, DWORD dwRight)
+{
+    LONG64 l = (LONG64)dwLeft, r = (LONG64)dwRight;
+    union { FILETIME ft; LONG64 ll; } ftmap;    
+    ftmap.ll = l * r;
+    return ftmap.ft;
+}
+
+/*****************************************************************************
+ * IPropData interface
+ *
+ */
+#define INTERFACE IPropData
+DECLARE_INTERFACE_(IPropData,IMAPIProp)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IMAPIProp methods ***/
+    STDMETHOD(GetLastError)(THIS_ HRESULT hRes, ULONG ulFlags, LPMAPIERROR *lppErr) PURE;
+    STDMETHOD(SaveChanges)(THIS_ ULONG ulFlags) PURE;
+    STDMETHOD(GetProps)(THIS_ LPSPropTagArray lpPropTags, ULONG ulFlags, ULONG *lpValues, LPSPropValue *lppProps) PURE;
+    STDMETHOD(GetPropList)(THIS_ ULONG  ulFlags, LPSPropTagArray *lppPropTagArray) PURE;
+    STDMETHOD(OpenProperty)(THIS_ ULONG ulPropTag, LPCIID lpIid, ULONG ulOpts, ULONG ulFlags, LPUNKNOWN *lppUnk) PURE;
+    STDMETHOD(SetProps)(THIS_ ULONG cValues, LPSPropValue lpProps, LPSPropProblemArray *lppProbs) PURE;
+    STDMETHOD(DeleteProps)(THIS_ LPSPropTagArray lpPropTags, LPSPropProblemArray *lppProbs) PURE;
+    STDMETHOD(CopyTo)(THIS_ ULONG ciidExclude, LPCIID lpIid, LPSPropTagArray lpProps, ULONG ulParam,
+                      LPMAPIPROGRESS lpProgress, LPCIID lpIface,LPVOID lpDest, ULONG ulFlags,
+                      LPSPropProblemArray *lppProbs) PURE;
+    STDMETHOD(CopyProps)(THIS_ LPSPropTagArray lpIncludeProps, ULONG ulParam, LPMAPIPROGRESS lpProgress,
+                         LPCIID lpIid, LPVOID lpDestObj, ULONG ulFlags, LPSPropProblemArray *lppProblems) PURE;
+    STDMETHOD(GetNamesFromIDs)(THIS_ LPSPropTagArray *lppPropTags, LPGUID lpIid, ULONG ulFlags, ULONG *lpCount,
+                               LPMAPINAMEID **lpppNames) PURE;
+    STDMETHOD(GetIDsFromNames)(THIS_ ULONG cPropNames, LPMAPINAMEID *lppNames, ULONG ulFlags, LPSPropTagArray *lppPropTags) PURE;
+    /*** IPropData methods ***/
+    STDMETHOD(HrSetObjAccess)(THIS_ ULONG ulAccess) PURE;
+    STDMETHOD(HrSetPropAccess)(THIS_ LPSPropTagArray lpPropTags, ULONG *lpAccess) PURE;
+    STDMETHOD(HrGetPropAccess)(THIS_ LPSPropTagArray *lppPropTags, ULONG **lppAccess) PURE;
+    STDMETHOD(HrAddObjProps)(THIS_ LPSPropTagArray lppPropTags, LPSPropProblemArray *lppProbs) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+        /*** IUnknown methods ***/
+#define IPropData_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IPropData_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IPropData_Release(p)                   (p)->lpVtbl->Release(p)
+        /*** IMAPIProp methods ***/
+#define IPropData_GetLastError(p,a,b,c)        (p)->lpVtbl->GetLastError(p,a,b,c)        
+#define IPropData_SaveChanges(p,a)             (p)->lpVtbl->SaveChanges(p,a)             
+#define IPropData_GetProps(p,a,b,c,d)          (p)->lpVtbl->GetProps(p,a,b,c,d)          
+#define IPropData_GetPropList(p,a,b)           (p)->lpVtbl->GetPropList(p,a,b)           
+#define IPropData_OpenProperty(p,a,b,c,d,e)    (p)->lpVtbl->OpenProperty(p,a,b,c,d,e)    
+#define IPropData_SetProps(p,a,b,c)            (p)->lpVtbl->SetProps(p,a,b,c)            
+#define IPropData_DeleteProps(p,a,b)           (p)->lpVtbl->DeleteProps(p,a,b)           
+#define IPropData_CopyTo(p,a,b,c,d,e,f,g,h,i)  (p)->lpVtbl->CopyTo(p,a,b,c,d,e,f,g,h,i)  
+#define IPropData_CopyProps(p,a,b,c,d,e,f,g)   (p)->lpVtbl->CopyProps(p,a,b,c,d,e,f,g)   
+#define IPropData_GetNamesFromIDs(p,a,b,c,d,e) (p)->lpVtbl->GetNamesFromIDs(p,a,b,c,d,e) 
+#define IPropData_GetIDsFromNames(p,a,b,c,d)   (p)->lpVtbl->GetIDsFromNames(p,a,b,c,d)   
+#define IPropData_HrSetObjAccess(p,a)          (p)->lpVtbl->HrSetObjAccess(p,a)
+#define IPropData_HrSetPropAccess(p,a,b)       (p)->lpVtbl->HrSetPropAccess(p,a,b)
+#define IPropData_HrGetPropAccess(p,a,b)       (p)->lpVtbl->HrGetPropAccess(p,a,b)
+#define IPropData_HrAddObjProps(p,a,b)         (p)->lpVtbl->HrAddObjProps(p,a,b)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAPIUTIL_H_ */
diff --git a/reactos/w32api/include/mapival.h b/reactos/w32api/include/mapival.h
new file mode 100644 (file)
index 0000000..465f9e4
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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
+ */
+
+#ifndef MAPIVAL_H
+#define MAPIVAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mapiutil.h>
+
+BOOL  WINAPI FBadRglpszW(LPWSTR*,ULONG);
+BOOL  WINAPI FBadRowSet(LPSRowSet);
+BOOL  WINAPI FBadRglpNameID(LPMAPINAMEID*,ULONG);
+BOOL  WINAPI FBadEntryList(LPENTRYLIST);
+ULONG WINAPI FBadRestriction(LPSRestriction);
+ULONG WINAPI FBadPropTag(ULONG);
+ULONG WINAPI FBadRow(LPSRow);
+ULONG WINAPI FBadProp(LPSPropValue);
+ULONG WINAPI FBadSortOrderSet(LPSSortOrderSet);
+ULONG WINAPI FBadColumnSet(LPSPropTagArray);
+
+#define FBadRgPropVal(p,n) FAILED(ScCountProps((n),(p),NULL))
+#define FBadPropVal(p)     FBadRgPropVal(1,(p))
+#define FBadAdrList(p)     FBadRowSet((LPSRowSet)(p))
+
+#define BAD_STANDARD_OBJ(a,b,c,d)         FALSE
+#define FBadUnknown(a)                    FALSE
+#define FBadQueryInterface(a,b,c)         FALSE
+#define FBadAddRef(a)                     FALSE
+#define FBadRelease(a)                    FALSE
+#define FBadGetLastError(a,b,c,d)         FALSE
+#define FBadSaveChanges(a,b)              FALSE
+#define FBadGetProps(a,b,c,d)             FALSE
+#define FBadGetPropList(a,b)              FALSE
+#define FBadOpenProperty(a,b,c,d,e,f)     FALSE
+#define FBadSetProps(a,b,c,d)             FALSE
+#define FBadDeleteProps(a,b,c)            FALSE
+#define FBadCopyTo(a,b,c,d,e,f,g,h,i,j)   FALSE
+#define FBadCopyProps(a,b,c,d,e,f,g,h)    FALSE
+#define FBadGetNamesFromIDs(a,b,c,d,e,f)  FALSE
+#define FBadGetIDsFromNames(a,b,c,d,e)    FALSE
+
+#define ValidateParms(x)   do { } while(0)
+#define UlValidateParms(x) do { } while(0)
+#define CheckParms(x)      do { } while(0)
+
+#define ValidateParameters1(a,b) do { } while(0)
+#define ValidateParameters2(a,b,c) do { } while(0)
+#define ValidateParameters3(a,b,c,d) do { } while(0)
+#define ValidateParameters4(a,b,c,d,e) do { } while(0)
+#define ValidateParameters5(a,b,c,d,e,f) do { } while(0)
+#define ValidateParameters6(a,b,c,d,e,f,g) do { } while(0)
+#define ValidateParameters7(a,b,c,d,e,f,g,h) do { } while(0)
+#define ValidateParameters8(a,b,c,d,e,f,g,h,i) do { } while(0)
+#define ValidateParameters9(a,b,c,d,e,f,g,h,i,j) do { } while(0)
+#define ValidateParameters10(a,b,c,d,e,f,g,h,i,j,k) do { } while(0)
+#define ValidateParameters11(a,b,c,d,e,f,g,h,i,j,k,l) do { } while(0)
+#define ValidateParameters12(a,b,c,d,e,f,g,h,i,j,k,l,m) do { } while(0)
+#define ValidateParameters13(a,b,c,d,e,f,g,h,i,j,k,l,m,n) do { } while(0)
+#define ValidateParameters14(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) do { } while(0)
+#define ValidateParameters15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) do { } while(0)
+#define ValidateParameters16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) do { } while(0)
+
+#define UlValidateParameters1(a,b) do { } while(0)
+#define UlValidateParameters2(a,b,c) do { } while(0)
+#define UlValidateParameters3(a,b,c,d) do { } while(0)
+#define UlValidateParameters4(a,b,c,d,e) do { } while(0)
+#define UlValidateParameters5(a,b,c,d,e,f) do { } while(0)
+#define UlValidateParameters6(a,b,c,d,e,f,g) do { } while(0)
+#define UlValidateParameters7(a,b,c,d,e,f,g,h) do { } while(0)
+#define UlValidateParameters8(a,b,c,d,e,f,g,h,i) do { } while(0)
+#define UlValidateParameters9(a,b,c,d,e,f,g,h,i,j) do { } while(0)
+#define UlValidateParameters10(a,b,c,d,e,f,g,h,i,j,k) do { } while(0)
+#define UlValidateParameters11(a,b,c,d,e,f,g,h,i,j,k,l) do { } while(0)
+#define UlValidateParameters12(a,b,c,d,e,f,g,h,i,j,k,l,m) do { } while(0)
+#define UlValidateParameters13(a,b,c,d,e,f,g,h,i,j,k,l,m,n) do { } while(0)
+#define UlValidateParameters14(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) do { } while(0)
+#define UlValidateParameters15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) do { } while(0)
+#define UlValidateParameters16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) do { } while(0)
+
+#define CheckParameters1(a,b) do { } while(0)
+#define CheckParameters2(a,b,c) do { } while(0)
+#define CheckParameters3(a,b,c,d) do { } while(0)
+#define CheckParameters4(a,b,c,d,e) do { } while(0)
+#define CheckParameters5(a,b,c,d,e,f) do { } while(0)
+#define CheckParameters6(a,b,c,d,e,f,g) do { } while(0)
+#define CheckParameters7(a,b,c,d,e,f,g,h) do { } while(0)
+#define CheckParameters8(a,b,c,d,e,f,g,h,i) do { } while(0)
+#define CheckParameters9(a,b,c,d,e,f,g,h,i,j) do { } while(0)
+#define CheckParameters10(a,b,c,d,e,f,g,h,i,j,k) do { } while(0)
+#define CheckParameters11(a,b,c,d,e,f,g,h,i,j,k,l) do { } while(0)
+#define CheckParameters12(a,b,c,d,e,f,g,h,i,j,k,l,m) do { } while(0)
+#define CheckParameters13(a,b,c,d,e,f,g,h,i,j,k,l,m,n) do { } while(0)
+#define CheckParameters14(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) do { } while(0)
+#define CheckParameters15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) do { } while(0)
+#define CheckParameters16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) do { } while(0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAPIVAL_H */
diff --git a/reactos/w32api/include/mapix.h b/reactos/w32api/include/mapix.h
new file mode 100644 (file)
index 0000000..5300b3b
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * 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
+ */
+
+#ifndef MAPIX_H
+#define MAPIX_H
+
+#ifndef MAPIDEFS_H
+#include <mapidefs.h>
+#endif
+#ifndef MAPICODE_H
+#include <mapicode.h>
+#endif
+#ifndef MAPIGUID_H
+#include <mapiguid.h>
+#endif
+#ifndef MAPITAGS_H
+#include <mapitags.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct IProfAdmin IProfAdmin;
+typedef IProfAdmin *LPPROFADMIN;
+typedef struct IMsgServiceAdmin IMsgServiceAdmin;
+typedef IMsgServiceAdmin *LPSERVICEADMIN;
+typedef struct IMAPISession *LPMAPISESSION;
+
+typedef unsigned long FLAGS;
+
+/* Flags for MAPILogon and MAPILogonEx */
+#define MAPI_LOGON_UI          0x000001
+#define MAPI_NEW_SESSION       0x000002
+#define MAPI_EXTENDED          0x000020
+#define MAPI_FORCE_DOWNLOAD    0x001000
+#define MAPI_PASSWORD_UI       0x020000
+#define MAPI_ALLOW_OTHERS      0x000008
+#define MAPI_EXPLICIT_PROFILE  0x000010
+#define MAPI_SERVICE_UI_ALWAYS 0x002000
+#define MAPI_NO_MAIL           0x008000
+#define MAPI_NT_SERVICE        0x010000
+#define MAPI_TIMEOUT_SHORT     0x100000
+
+#define MAPI_SIMPLE_DEFAULT  (MAPI_LOGON_UI|MAPI_ALLOW_OTHERS|MAPI_FORCE_DOWNLOAD)
+#define MAPI_SIMPLE_EXPLICIT (MAPI_NEW_SESSION|MAPI_EXPLICIT_PROFILE|MAPI_FORCE_DOWNLOAD)
+
+typedef struct tagMAPIINIT_0
+{
+    ULONG ulVersion;
+    ULONG ulFlags;
+} MAPIINIT_0, *LPMAPIINIT_0;
+
+typedef MAPIINIT_0 MAPIINIT, *LPMAPIINIT;
+
+#define MAPI_INIT_VERSION 0U
+
+typedef HRESULT (WINAPI MAPIINITIALIZE)(void*);
+typedef MAPIINITIALIZE *LPMAPIINITIALIZE;
+MAPIINITIALIZE MAPIInitialize;
+
+typedef void (WINAPI MAPIUNINITIALIZE)(void);
+typedef MAPIUNINITIALIZE *LPMAPIUNINITIALIZE;
+MAPIUNINITIALIZE MAPIUninitialize;
+
+#if defined (UNICODE) || defined (__WINESRC__)
+typedef HRESULT (STDMETHODCALLTYPE MAPILOGONEX)(ULONG_PTR,LPWSTR,LPWSTR,ULONG,LPMAPISESSION*);
+#else
+typedef HRESULT (STDMETHODCALLTYPE MAPILOGONEX)(ULONG_PTR,LPSTR,LPSTR,ULONG,LPMAPISESSION *);
+#endif
+typedef MAPILOGONEX *LPMAPILOGONEX;
+MAPILOGONEX MAPILogonEx;
+
+typedef SCODE (WINAPI MAPIALLOCATEBUFFER)(ULONG,LPVOID*);
+typedef MAPIALLOCATEBUFFER *LPMAPIALLOCATEBUFFER;
+MAPIALLOCATEBUFFER MAPIAllocateBuffer;
+
+typedef SCODE (WINAPI MAPIALLOCATEMORE)(ULONG,LPVOID,LPVOID*);
+typedef MAPIALLOCATEMORE *LPMAPIALLOCATEMORE;
+MAPIALLOCATEMORE MAPIAllocateMore;
+
+typedef ULONG (WINAPI MAPIFREEBUFFER)(LPVOID);
+typedef MAPIFREEBUFFER *LPMAPIFREEBUFFER;
+MAPIFREEBUFFER MAPIFreeBuffer;
+
+/*****************************************************************************
+ * IMAPISession interface
+ */
+#define INTERFACE IMAPISession
+DECLARE_INTERFACE_(IMAPISession,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IMAPISession methods ***/
+    STDMETHOD(GetLastError)(THIS_ HRESULT hResult, ULONG ulFlags, LPMAPIERROR *lppMAPIError) PURE;
+    STDMETHOD(GetMsgStoresTable)(THIS_ ULONG ulFlags, LPMAPITABLE *lppTable) PURE;
+    STDMETHOD(OpenMsgStore)(THIS_ ULONG_PTR ulUIParam, ULONG cbId,
+                            LPENTRYID lpId, LPCIID lpIFace, ULONG ulFlags, LPMDB *lppMDB) PURE;
+    STDMETHOD(OpenAddressBook)(THIS_ ULONG_PTR ulUIParam, LPCIID iid, ULONG ulFlags, LPADRBOOK *lppAdrBook) PURE;
+    STDMETHOD(OpenProfileSection)(THIS_ LPMAPIUID lpUID, LPCIID iid, ULONG ulFlags, LPPROFSECT *lppProf) PURE;
+    STDMETHOD(GetStatusTable)(THIS_ ULONG ulFlags, LPMAPITABLE *lppTable) PURE;
+    STDMETHOD(OpenEntry)(THIS_ ULONG cbId, LPENTRYID lpId, LPCIID iid,
+                         ULONG ulFlags, ULONG *lpType, LPUNKNOWN *lppUnk) PURE;
+    STDMETHOD(CompareEntryIDs)(THIS_ ULONG cbLID, LPENTRYID lpLID, ULONG cbRID,
+                               LPENTRYID lpRID, ULONG ulFlags, ULONG *lpRes) PURE;
+    STDMETHOD(Advise)(THIS_ ULONG cbId, LPENTRYID lpId, ULONG ulMask,
+                      LPMAPIADVISESINK lpSink, ULONG *lpCxn) PURE;
+    STDMETHOD(Unadvise)(THIS_ ULONG ulConnection) PURE;
+    STDMETHOD(MessageOptions)(THIS_ ULONG_PTR ulUIParam, ULONG ulFlags, LPSTR lpszAddr, LPMESSAGE lpMsg) PURE;
+    STDMETHOD(QueryDefaultMessageOpt)(THIS_ LPSTR lpszAddr, ULONG ulFlags,
+                                      ULONG *lpcVals, LPSPropValue *lppOpts) PURE;
+    STDMETHOD(EnumAdrTypes)(THIS_ ULONG ulFlags, ULONG *lpcTypes, LPSTR **lpppszTypes) PURE;
+    STDMETHOD(QueryIdentity)(THIS_ ULONG *lpcbId, LPENTRYID *lppEntryID) PURE;
+    STDMETHOD(Logoff)(THIS_ ULONG_PTR ulUIParam, ULONG ulFlags, ULONG ulReserved) PURE;
+    STDMETHOD(SetDefaultStore)(THIS_ ULONG ulFlags, ULONG cbId, LPENTRYID lpId) PURE;
+    STDMETHOD(AdminServices)(THIS_ ULONG ulFlags, LPSERVICEADMIN *lppAdmin) PURE;
+    STDMETHOD(ShowForm)(THIS_ ULONG_PTR ulUIParam, LPMDB lpStore,
+                        LPMAPIFOLDER lpParent, LPCIID iid, ULONG ulToken,
+                        LPMESSAGE lpSent, ULONG ulFlags, ULONG ulStatus,
+                        ULONG ulMsgFlags, ULONG ulAccess, LPSTR lpszClass) PURE;
+    STDMETHOD(PrepareForm)(THIS_ LPCIID lpIFace, LPMESSAGE lpMsg, ULONG *lpToken) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+        /*** IUnknown methods ***/
+#define IMAPISession_QueryInterface(p,a,b)          (p)->lpVtbl->QueryInterface(p,a,b)
+#define IMAPISession_AddRef(p)                      (p)->lpVtbl->AddRef(p)
+#define IMAPISession_Release(p)                     (p)->lpVtbl->Release(p)
+        /*** IMAPISession methods ***/
+#define IMAPISession_GetLastError(p,a,b,c)          (p)->lpVtbl->GetLastError(p,a,b,c)
+#define IMAPISession_GetMsgStoresTable(p,a,b)       (p)->lpVtbl->GetMsgStoresTable(p,a,b)
+#define IMAPISession_OpenMsgStore(p,a,b,c,d,e,f)    (p)->lpVtbl->OpenMsgStore(p,a,b,c,d,e,f)
+#define IMAPISession_OpenAddressBook(p,a,b,c,d)     (p)->lpVtbl->OpenAddressBook(p,a,b,c,d)
+#define IMAPISession_OpenProfileSection(p,a,b,c,d)  (p)->lpVtbl->OpenProfileSection(p,a,b,c,d)
+#define IMAPISession_GetStatusTable(p,a,b)          (p)->lpVtbl->GetStatusTable(p,a,b)
+#define IMAPISession_OpenEntry(p,a,b,c,d,e,f)       (p)->lpVtbl->OpenEntry(p,a,b,c,d,e,f)
+#define IMAPISession_CompareEntryIDs(p,a,b,c,d,e,f) (p)->lpVtbl->CompareEntryIDs(p,a,b,c,d,e,f)
+#define IMAPISession_Advise(p,a,b,c,d,e)            (p)->lpVtbl->Advise(p,a,b,c,d,e)
+#define IMAPISession_Unadvise(p,a)                  (p)->lpVtbl->Unadvise(p,a)
+#define IMAPISession_MessageOptions(p,a,b,c,d)      (p)->lpVtbl->MessageOptions)(p,a,b,c,d)
+#define IMAPISession_QueryDefaultMessageOpt(p,a,b,c,d) \
+                                                    (p)->lpVtbl->QueryDefaultMessageOpt(p,a,b,c,d)
+#define IMAPISession_EnumAdrTypes(p,a,b,c)          (p)->lpVtbl->EnumAdrTypes(p,a,b,c)
+#define IMAPISession_QueryIdentity(p,a,b)           (p)->lpVtbl->QueryIdentity(p,a,b)
+#define IMAPISession_Logoff(p,a,b,c)                (p)->lpVtbl->Logoff(p,a,b,c)
+#define IMAPISession_SetDefaultStore(p,a,b,c)       (p)->lpVtbl->SetDefaultStore(p,a,b,c)
+#define IMAPISession_AdminServices(p,a,b)           (p)->lpVtbl->AdminServices(p,a,b)
+#define IMAPISession_ShowForm(p,a,b,c,d,e,f,g,h,i,j,k) \
+                                                    (p)->lpVtbl->ShowForm(p,a,b,c,d,e,f,g,h,i,j,k)
+#define IMAPISession_PrepareForm(p,a,b,c)           (p)->lpVtbl->PrepareForm(p,a,b,c)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAPIX_H */
index 2808613..cdd80e5 100644 (file)
@@ -89,6 +89,8 @@ typedef FLAGGED_WORD_BLOB *wireBSTR;
 typedef BSTR *LPBSTR;
 typedef LONG SCODE;
 typedef void *HCONTEXT;
+#ifndef _tagCY_DEFINED
+#define _tagCY_DEFINED
 typedef union tagCY {
        _ANONYMOUS_STRUCT struct {
                unsigned long Lo;
@@ -96,6 +98,7 @@ typedef union tagCY {
        }_STRUCT_NAME(s);
        LONGLONG int64;
 } CY;
+#endif /* _tagCY_DEFINED */
 typedef double DATE;
 typedef struct  tagBSTRBLOB {
        ULONG cbSize;
diff --git a/reactos/w32api/include/xcmc.h b/reactos/w32api/include/xcmc.h
new file mode 100644 (file)
index 0000000..e4ff491
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2004 Chris Morgan
+ *
+ * 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
+ */
+
+#ifndef _XCMC_H
+#define _XCMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef char                CMC_sint8;
+typedef short               CMC_sint16;
+typedef long int            CMC_sint32;
+typedef unsigned short int  CMC_uint16;
+typedef unsigned long int   CMC_uint32;
+typedef void*               CMC_buffer;
+typedef char*               CMC_string;
+
+typedef CMC_uint16          CMC_boolean;
+typedef CMC_sint32          CMC_enum;
+typedef CMC_uint32          CMC_return_code;
+typedef CMC_uint32          CMC_flags;
+typedef CMC_string          CMC_object_identifier;
+typedef CMC_uint32          CMC_session_id;
+typedef CMC_uint32          CMC_ui_id;
+
+#define CMC_FALSE   ((CMC_boolean)0)
+#define CMC_TRUE    ((CMC_boolean)1)
+
+#define CMC_SUCCESS                         ((CMC_return_code) 0)
+
+#define CMC_E_AMBIGUOUS_RECIPIENT           ((CMC_return_code) 1)
+#define CMC_E_ATTACHMENT_NOT_FOUND          ((CMC_return_code) 2)
+#define CMC_E_ATTACHMENT_OPEN_FAILURE       ((CMC_return_code) 3)
+#define CMC_E_ATTACHMENT_READ_FAILURE       ((CMC_return_code) 4)
+#define CMC_E_ATTACHMENT_WRITE_FAILURE      ((CMC_return_code) 5)
+#define CMC_E_COUNTED_STRING_UNSUPPORTED    ((CMC_return_code) 6)
+#define CMC_E_DISK_FULL                     ((CMC_return_code) 7)
+#define CMC_E_FAILURE                       ((CMC_return_code) 8)
+#define CMC_E_INSUFFICIENT_MEMORY           ((CMC_return_code) 9)
+#define CMC_E_INVALID_CONFIGURATION         ((CMC_return_code) 10)
+#define CMC_E_INVALID_ENUM                  ((CMC_return_code) 11)
+#define CMC_E_INVALID_FLAG                  ((CMC_return_code) 12)
+#define CMC_E_INVALID_MEMORY                ((CMC_return_code) 13)
+#define CMC_E_INVALID_MESSAGE_PARAMETER     ((CMC_return_code) 14)
+#define CMC_E_INVALID_MESSAGE_REFERENCE     ((CMC_return_code) 15)
+#define CMC_E_INVALID_PARAMETER             ((CMC_return_code) 16)
+#define CMC_E_INVALID_SESSION_ID            ((CMC_return_code) 17)
+#define CMC_E_INVALID_UI_ID                 ((CMC_return_code) 18)
+#define CMC_E_LOGON_FAILURE                 ((CMC_return_code) 19)
+#define CMC_E_MESSAGE_IN_USE                ((CMC_return_code) 20)
+#define CMC_E_NOT_SUPPORTED                 ((CMC_return_code) 21)
+#define CMC_E_PASSWORD_REQUIRED             ((CMC_return_code) 22)
+#define CMC_E_RECIPIENT_NOT_FOUND           ((CMC_return_code) 23)
+#define CMC_E_SERVICE_UNAVAILABLE           ((CMC_return_code) 24)
+#define CMC_E_TEXT_TOO_LARGE                ((CMC_return_code) 25)
+#define CMC_E_TOO_MANY_FILES                ((CMC_return_code) 26)
+#define CMC_E_TOO_MANY_RECIPIENTS           ((CMC_return_code) 27)
+#define CMC_E_UNABLE_TO_NOT_MARK_AS_READ    ((CMC_return_code) 28)
+#define CMC_E_UNRECOGNIZED_MESSAGE_TYPE     ((CMC_return_code) 29)
+#define CMC_E_UNSUPPORTED_ACTION            ((CMC_return_code) 30)
+#define CMC_E_UNSUPPORTED_CHARACTER_SET     ((CMC_return_code) 31)
+#define CMC_E_UNSUPPORTED_DATA_EXT          ((CMC_return_code) 32)
+#define CMC_E_UNSUPPORTED_FLAG              ((CMC_return_code) 33)
+#define CMC_E_UNSUPPORTED_FUNCTION_EXT      ((CMC_return_code) 34)
+#define CMC_E_UNSUPPORTED_VERSION           ((CMC_return_code) 35)
+#define CMC_E_USER_CANCEL                   ((CMC_return_code) 36)
+#define CMC_E_USER_NOT_LOGGED_ON            ((CMC_return_code) 37)
+
+#define CMC_ERROR_DISPLAYED                 ((CMC_return_code) 0x00008000)
+#define CMC_ERROR_RSV_MASK                  ((CMC_return_code) 0x0000FFFF)
+#define CMC_ERROR_IMPL_MASK                 ((CMC_return_code) 0xFFFF0000)
+
+typedef struct {
+    CMC_uint32          length;
+    char                string[1];
+} CMC_counted_string;
+
+typedef CMC_counted_string CMC_message_reference;
+
+typedef struct {
+    CMC_sint8  second;
+    CMC_sint8  minute;
+    CMC_sint8  hour;
+    CMC_sint8  day;
+    CMC_sint8  month;
+    CMC_sint8  year;
+    CMC_sint8  isdst;
+    CMC_sint8  unused1;
+    CMC_sint16 tmzone;
+    CMC_sint16 unused2;
+} CMC_time;
+
+#define CMC_NO_TIMEZONE ((CMC_sint16) 0x8000)
+
+
+typedef struct {
+    CMC_uint32 item_code;
+    CMC_uint32 item_data;
+    CMC_buffer item_reference;
+    CMC_flags  extension_flags;
+} CMC_extension;
+
+#define CMC_EXT_REQUIRED                    ((CMC_flags) 0x00010000)
+#define CMC_EXT_OUTPUT                      ((CMC_flags) 0x00020000)
+#define CMC_EXT_LAST_ELEMENT                ((CMC_flags) 0x80000000)
+#define CMC_EXT_RSV_FLAG_MASK               ((CMC_flags) 0xFFFF0000)
+#define CMC_EXT_ITEM_FLAG_MASK              ((CMC_flags) 0x0000FFFF)
+
+
+typedef struct CMC_attachment_s {
+    CMC_string              attach_title;
+    CMC_object_identifier   attach_type;
+    CMC_string              attach_filename;
+    CMC_flags               attach_flags;
+    CMC_extension          *attach_extensions;
+} CMC_attachment;
+
+#define CMC_ATT_APP_OWNS_FILE  ((CMC_flags) 1)
+#define CMC_ATT_LAST_ELEMENT   ((CMC_flags) 0x80000000)
+
+#define CMC_ATT_OID_BINARY      "? ? ? ? ? ?"
+#define CMC_ATT_OID_TEXT        "? ? ? ? ? ?"
+
+
+typedef struct {
+    CMC_string              name;
+    CMC_enum                name_type;
+    CMC_string              address;
+    CMC_enum                role;
+    CMC_flags               recip_flags;
+    CMC_extension          *recip_extensions;
+} CMC_recipient;
+
+#define CMC_TYPE_UNKNOWN                    ((CMC_enum) 0)
+#define CMC_TYPE_INDIVIDUAL                 ((CMC_enum) 1)
+#define CMC_TYPE_GROUP                      ((CMC_enum) 2)
+
+#define CMC_ROLE_TO                         ((CMC_enum) 0)
+#define CMC_ROLE_CC                         ((CMC_enum) 1)
+#define CMC_ROLE_BCC                        ((CMC_enum) 2)
+#define CMC_ROLE_ORIGINATOR                 ((CMC_enum) 3)
+#define CMC_ROLE_AUTHORIZING_USER           ((CMC_enum) 4)
+
+#define CMC_RECIP_IGNORE                    ((CMC_flags) 1)
+#define CMC_RECIP_LIST_TRUNCATED            ((CMC_flags) 2)
+#define CMC_RECIP_LAST_ELEMENT              ((CMC_flags) 0x80000000)
+
+
+typedef struct {
+    CMC_message_reference  *message_reference;
+    CMC_string              message_type;
+    CMC_string              subject;
+    CMC_time                time_sent;
+    CMC_string              text_note;
+    CMC_recipient          *recipients;
+    CMC_attachment         *attachments;
+    CMC_flags               message_flags;
+    CMC_extension          *message_extensions;
+} CMC_message;
+
+#define CMC_MSG_READ                        ((CMC_flags) 1)
+#define CMC_MSG_TEXT_NOTE_AS_FILE           ((CMC_flags) 2)
+#define CMC_MSG_UNSENT                      ((CMC_flags) 4)
+#define CMC_MSG_LAST_ELEMENT                ((CMC_flags) 0x80000000)
+
+
+typedef struct {
+    CMC_message_reference  *message_reference;
+    CMC_string              message_type;
+    CMC_string              subject;
+    CMC_time                time_sent;
+    CMC_uint32              byte_length;
+    CMC_recipient          *originator;
+    CMC_flags               summary_flags;
+    CMC_extension          *message_summary_extensions;
+} CMC_message_summary;
+
+#define CMC_SUM_READ                        ((CMC_flags) 1)
+#define CMC_SUM_UNSENT                      ((CMC_flags) 2)
+#define CMC_SUM_LAST_ELEMENT                ((CMC_flags) 0x80000000)
+
+#define CMC_ERROR_UI_ALLOWED                ((CMC_flags) 0x01000000)
+#define CMC_LOGON_UI_ALLOWED                ((CMC_flags) 0x02000000)
+#define CMC_COUNTED_STRING_TYPE             ((CMC_flags) 0x04000000)
+
+CMC_return_code WINAPI cmc_send(
+    CMC_session_id          session,
+    CMC_message            *message,
+    CMC_flags               send_flags,
+    CMC_ui_id               ui_id,
+    CMC_extension          *send_extensions
+);
+
+#define CMC_SEND_UI_REQUESTED               ((CMC_flags) 1)
+
+
+CMC_return_code WINAPI cmc_send_documents(
+    CMC_string              recipient_addresses,
+    CMC_string              subject,
+    CMC_string              text_note,
+    CMC_flags               send_doc_flags,
+    CMC_string              file_paths,
+    CMC_string              file_names,
+    CMC_string              delimiter,
+    CMC_ui_id               ui_id
+);
+
+#define CMC_FIRST_ATTACH_AS_TEXT_NOTE       ((CMC_flags) 2)
+
+
+CMC_return_code WINAPI cmc_act_on(
+    CMC_session_id          session,
+    CMC_message_reference  *message_reference,
+    CMC_enum                operation,
+    CMC_flags               act_on_flags,
+    CMC_ui_id               ui_id,
+    CMC_extension          *act_on_extensions
+);
+
+#define CMC_ACT_ON_EXTENDED                 ((CMC_enum) 0)
+#define CMC_ACT_ON_DELETE                   ((CMC_enum) 1)
+
+
+CMC_return_code WINAPI cmc_list(
+    CMC_session_id          session,
+    CMC_string              message_type,
+    CMC_flags               list_flags,
+    CMC_message_reference  *seed,
+    CMC_uint32             *count,
+    CMC_ui_id               ui_id,
+    CMC_message_summary   **result,
+    CMC_extension          *list_extensions
+);
+
+#define CMC_LIST_UNREAD_ONLY                ((CMC_flags) 1)
+#define CMC_LIST_MSG_REFS_ONLY              ((CMC_flags) 2)
+#define CMC_LIST_COUNT_ONLY                 ((CMC_flags) 4)
+
+#define CMC_LENGTH_UNKNOWN          0xFFFFFFFF
+
+
+CMC_return_code WINAPI cmc_read(
+    CMC_session_id          session,
+    CMC_message_reference  *message_reference,
+    CMC_flags               read_flags,
+    CMC_message           **message,
+    CMC_ui_id               ui_id,
+    CMC_extension          *read_extensions
+);
+
+#define CMC_DO_NOT_MARK_AS_READ             ((CMC_flags) 1)
+#define CMC_MSG_AND_ATT_HDRS_ONLY           ((CMC_flags) 2)
+#define CMC_READ_FIRST_UNREAD_MESSAGE       ((CMC_flags) 4)
+
+
+CMC_return_code WINAPI cmc_look_up(
+    CMC_session_id          session,
+    CMC_recipient          *recipient_in,
+    CMC_flags               look_up_flags,
+    CMC_ui_id               ui_id,
+    CMC_uint32             *count,
+    CMC_recipient         **recipient_out,
+    CMC_extension          *look_up_extensions
+);
+
+#define CMC_LOOKUP_RESOLVE_PREFIX_SEARCH    ((CMC_flags) 1)
+#define CMC_LOOKUP_RESOLVE_IDENTITY         ((CMC_flags) 2)
+#define CMC_LOOKUP_RESOLVE_UI               ((CMC_flags) 4)
+#define CMC_LOOKUP_DETAILS_UI               ((CMC_flags) 8)
+#define CMC_LOOKUP_ADDRESSING_UI            ((CMC_flags) 16)
+
+
+CMC_return_code WINAPI cmc_free( CMC_buffer memory );
+
+CMC_return_code WINAPI cmc_logoff(
+    CMC_session_id          session,
+    CMC_ui_id               ui_id,
+    CMC_flags               logoff_flags,
+    CMC_extension          *logoff_extensions
+);
+
+CMC_return_code WINAPI cmc_logon(
+    CMC_string              service,
+    CMC_string              user,
+    CMC_string              password,
+    CMC_object_identifier   character_set,
+    CMC_ui_id               ui_id,
+    CMC_uint16              caller_cmc_version,
+    CMC_flags               logon_flags,
+    CMC_session_id         *session,
+    CMC_extension          *logon_extensions
+);
+
+#define CMC_VERSION         ((CMC_uint16) 100)
+
+CMC_return_code WINAPI cmc_query_configuration(
+    CMC_session_id          session,
+    CMC_enum                item,
+    CMC_buffer              reference,
+    CMC_extension          *config_extensions
+);
+
+#define CMC_CONFIG_CHARACTER_SET            ((CMC_enum) 1)
+#define CMC_CONFIG_LINE_TERM                ((CMC_enum) 2)
+#define CMC_CONFIG_DEFAULT_SERVICE          ((CMC_enum) 3)
+#define CMC_CONFIG_DEFAULT_USER             ((CMC_enum) 4)
+#define CMC_CONFIG_REQ_PASSWORD             ((CMC_enum) 5)
+#define CMC_CONFIG_REQ_SERVICE              ((CMC_enum) 6)
+#define CMC_CONFIG_REQ_USER                 ((CMC_enum) 7)
+#define CMC_CONFIG_UI_AVAIL                 ((CMC_enum) 8)
+#define CMC_CONFIG_SUP_NOMKMSGREAD          ((CMC_enum) 9)
+#define CMC_CONFIG_SUP_COUNTED_STR          ((CMC_enum) 10)
+#define CMC_CONFIG_VER_IMPLEM               ((CMC_enum) 11)
+#define CMC_CONFIG_VER_SPEC                 ((CMC_enum) 12)
+
+#define CMC_LINE_TERM_CRLF                  ((CMC_enum) 0)
+#define CMC_LINE_TERM_CR                    ((CMC_enum) 1)
+#define CMC_LINE_TERM_LF                    ((CMC_enum) 2)
+
+#define CMC_REQUIRED_NO                     ((CMC_enum) 0)
+#define CMC_REQUIRED_YES                    ((CMC_enum) 1)
+#define CMC_REQUIRED_OPT                    ((CMC_enum) 2)
+
+#define CMC_CHAR_CP437                      "1 2 840 113556 3 2 437"
+#define CMC_CHAR_CP850                      "1 2 840 113556 3 2 85"
+#define CMC_CHAR_CP1252                     "1 2 840 113556 3 2 1252"
+#define CMC_CHAR_ISTRING                    "1 2 840 113556 3 2 0"
+#define CMC_CHAR_UNICODE                    "1 2 840 113556 3 2 1"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _XCMC_H */