[Pkg-samba-maint] r2699 - in trunk/openchange: . debian doc libmapi libmapi/conf mapiproxy mapiproxy/documentation mapiproxy/libmapiproxy mapiproxy/libmapiserver mapiproxy/libmapistore mapiproxy/modules mapiproxy/servers/default/emsmdb mapiproxy/servers/default/nspi mapiproxy/servers/default/rfr python/openchange script utils utils/backup utils/mapitest utils/mapitest/modules

jelmer at alioth.debian.org jelmer at alioth.debian.org
Tue Apr 14 14:43:51 UTC 2009


Author: jelmer
Date: 2009-04-14 14:43:51 +0000 (Tue, 14 Apr 2009)
New Revision: 2699

Added:
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcmsg.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxctabl.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxorule.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcmsg.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxctabl.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxorule.c
   trunk/openchange/utils/mapitest/modules/module_oxcnotif.c
Modified:
   trunk/openchange/ChangeLog
   trunk/openchange/Makefile
   trunk/openchange/VERSION
   trunk/openchange/debian/changelog
   trunk/openchange/doc/howto.txt
   trunk/openchange/exchange.idl
   trunk/openchange/libmapi/FXICS.c
   trunk/openchange/libmapi/IMAPIContainer.c
   trunk/openchange/libmapi/IMAPIFolder.c
   trunk/openchange/libmapi/IMAPIProp.c
   trunk/openchange/libmapi/IMAPISession.c
   trunk/openchange/libmapi/IMAPISupport.c
   trunk/openchange/libmapi/IMAPITable.c
   trunk/openchange/libmapi/IMSProvider.c
   trunk/openchange/libmapi/IMessage.c
   trunk/openchange/libmapi/IMsgStore.c
   trunk/openchange/libmapi/IStoreFolder.c
   trunk/openchange/libmapi/IStream.c
   trunk/openchange/libmapi/IUnknown.c
   trunk/openchange/libmapi/IXPLogon.c
   trunk/openchange/libmapi/cdo_mapi.c
   trunk/openchange/libmapi/conf/mapi-properties
   trunk/openchange/libmapi/conf/mparse.pl
   trunk/openchange/libmapi/emsmdb.c
   trunk/openchange/libmapi/mapi_object.c
   trunk/openchange/libmapi/mapi_object.h
   trunk/openchange/libmapi/mapi_provider.h
   trunk/openchange/libmapi/mapidefs.h
   trunk/openchange/libmapi/nspi.c
   trunk/openchange/libmapi/property.c
   trunk/openchange/libmapi/utils.c
   trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
   trunk/openchange/mapiproxy/dcesrv_mapiproxy.h
   trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c
   trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy
   trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c
   trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c
   trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h
   trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c
   trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c
   trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c
   trunk/openchange/mapiproxy/modules/mpm_downgrade.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h
   trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcfold.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c
   trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c
   trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c
   trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c
   trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c
   trunk/openchange/ndr_mapi.c
   trunk/openchange/python/openchange/mailbox.py
   trunk/openchange/python/openchange/provision.py
   trunk/openchange/script/mkrelease.sh
   trunk/openchange/script/mkversion.sh
   trunk/openchange/script/samba4_ver.sh
   trunk/openchange/utils/backup/openchangebackup.c
   trunk/openchange/utils/mapitest/mapitest_common.c
   trunk/openchange/utils/mapitest/module.c
   trunk/openchange/utils/mapitest/modules/module_nspi.c
   trunk/openchange/utils/mapitest/modules/module_oxcmsg.c
   trunk/openchange/utils/mapitest/modules/module_oxcprpt.c
   trunk/openchange/utils/mapitest/modules/module_oxctable.c
   trunk/openchange/utils/openchangeclient.c
Log:
merge in new upstream snapshot

Modified: trunk/openchange/ChangeLog
===================================================================
--- trunk/openchange/ChangeLog	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/ChangeLog	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1,3 +1,299 @@
+2009-04-13
+    bradh
+	[r1311]
+		Add PT_ACTIONS to list of data types.
+		
+		Not fully/correctly handled yet.
+
+2009-04-12
+    jkerihuel
+	[r1309]
+		- Add dcerpc_mapiproxy:delegated_auth option 
+		This option delays mapiproxy-remote server authentication when
+		the client sends the first request on a given pipe. This is
+		mandatory in order to have delegated credentials to work.
+		
+		- Factor remote connection into mapiproxy_op_connect
+
+2009-04-11
+    bradh
+	[r1307]
+		Add session state to the notification.
+		Patch by Paolo Abeni - thanks for the investigation and fix.
+		
+		Also remove a stray debug message.
+	[r1306]
+		Add a new mapitest suite for OXCNOTIF (Core Notifications).
+		
+		Add a test to the OXCNOTIF suite based on test case provided by Paolo Abeni.
+
+2009-04-10
+    bradh
+	[r1304]
+		Update IDL for ModifyRules (0x41) and add IDL for 
+		UpdateDeferredActionMessages (0x57).
+		
+		This is a checkpoint commit, pending further investigation
+		into how we handle PtypRestriction and PtypRuleAction.
+
+2009-04-08
+    bradh
+	[r1302]
+		Mapitest cleanups - remove GetLastError(), and other minor edits.
+	[r1301]
+		Implement LockRegionStream and UnlockRegionStream ROPs.
+		
+		These appear to be a relatively recent addition to the 
+		documentation, possibly only used in Exchange 2007 / Outlook
+		2007.
+		
+		This is complete except for testing of whether the locking
+		actually works.
+
+2009-04-06
+    jkerihuel
+	[r1299]
+		Use parent folder full replica ID: 2 bytes instead of 1 byte
+	[r1297]
+		- Add Implementation for Logon redirect response buffer in OpenChange IDL
+		- Update libmapiserver size calculation routine for Logon call to handle this case
+
+2009-03-30
+    jkerihuel
+	[r1293]
+		Add session and logon_id to the list of parameters to copy between objects.
+		This patch fixes a problem in openchangeclient when using the --folder parameter.
+    bradh
+	[r1294]
+		Remove code relating to free'ing the bookmark returned
+		by SetCollapseState. Initial investigations with MS
+		lead me to believe that you can't free that resource.
+		
+		May be more work in this area as investigation continues.
+
+2009-03-25
+    jkerihuel
+	[r1291]
+		Fix memory leaks for functions relying on pull_emsmdb_property
+
+2009-03-16
+    jkerihuel
+	[r1289]
+		Fix emsabp valgrind errors
+
+2009-03-12
+    jkerihuel
+	[r1287]
+		Make it possible to specify a version number for release different
+		from major/minor from configure.ac
+
+2009-03-11
+    jkerihuel
+	[r1285]
+		Make it possible to open and control up to 255 mailboxes within a 
+		single MAPI session.
+		
+		It implements an internal management of a logon_id array at session
+		level + enable transparent transport/copy of current logon_id value
+		among MAPI calls + finally transparently free the logon_id value when
+		the store object (PF or mailbox) is being released.
+	[r1284]
+		- Retrieve recipients from OpenEmbeddedMessage reply
+		- Test the implementation in mapitest
+		- Avoid potential memory leak: steal context for returned ulPropTags.
+
+2009-03-08
+    jkerihuel
+	[r1282]
+		Be more tolerant with Logon request flags
+	[r1281]
+		Set retval to MAPI_E_INVALID_BOOKMARK rather than returning.
+		This case still needs to be fixed though.
+	[r1280]
+		Delete debug message
+	[r1279]
+		Create a default GetProps reply on error
+
+2009-03-06
+    jkerihuel
+	[r1277]
+		Fix retval problem in libmapi/nspi.c for GetIDsFromNames.
+		Function returns MAPI_E_SUCCESS, but errno is set to 0x0000000b.
+		Set errno to retval to work around this problem.
+		
+		
+		NSPI-GETIDSFROMNAMES
+	[r1276]
+		OXCPRPT-NAME-ID mapitest now passes: The QueryNamedProperties ecMemory retval
+		has been worked-around by setting QueryFlags to NoStrings to limite the results
+		scope. This means the MNID_STRING case is not fully checked anymore. We should maybe
+		add additional tests to do full coverage.
+	[r1275]
+		Fix GetNamesFromIDs IDL and implementation.
+		
+		Note: We should probably update the function prototype
+		so it takes a mapi_SPropTagArray rather than a single property.
+    bradh
+	[r1274]
+		Protect against bad results from GetGALTable().
+		
+		Resolves ticket #142
+
+2009-03-04
+    jkerihuel
+	[r1272]
+		Patch from Paolo Abeni: Add sanity check to Subscribe
+		and prevent applications from crashing if notify context 
+		is uninitialized.
+
+2009-03-03
+    jkerihuel
+	[r1270]
+		Ensure NSPI server functions have a valid dcesrv_handle
+	[r1269]
+		Add quick/additional configuration information on how to setup openchange server
+	[r1268]
+		This commit adds a retval check on private data retrieval function and prevents QueryPosition from causing a 
+		segfault when parent object is meant to come from GetContentsTable.
+	[r1267]
+		- Fix NspiGetMatches server reply when specified username is invalid and
+		search fails.
+		- Make use of talloc hierarchy for NspiGetProps properties fetch + fix
+		a talloc_free bug leading to segfault on failure.
+	[r1265]
+		Prevent from registering same mapistore backend multiple times
+    bradh
+	[r1266]
+		Howto updates.
+
+2009-03-02
+    jkerihuel
+	[r1261]
+		Add skeleton for GetRulesTable 
+	[r1258]
+		- return MAPI_E_SUCCESS when QueryRows reply count is 0
+		- Move Reminders from IPM Subtree to Mailbox root
+	[r1257]
+		- Add QueryPosition implementation
+		- Move from offset to numerator/denominator couple for table objects
+		
+		Outlook now opens properly using openchange server and display the
+		mailbox folder list with icons ;-)
+	[r1256]
+		- Add skeletons for Restrict, SortTable, FindRow calls
+		- Introduce emsmdb provider table object
+		- Add preliminary table implementation for system/special folders
+		- Add preliminary implementation of GetHierarchyTable, SetColumns and QueryRows
+		- Improve creation of GetProps reply blob for Mailbox folder
+		- Fix bug in EcRRegisterPushNotification when associated handle is invalid
+		- Remove some usage of ldb_filter and use format string instead 
+		- Update libmapiserver sanity checks and look for error_code != MAPI_E_SUCCESS
+		  so openchange server is able to return failed replies to MAPI clients
+		- Introduce flaggedPropertyRows in libmapiserver_push_property (needed by QueryRows)
+		
+		This commit makes openchange server work with "openchangeclient --mailbox" ;-)
+		
+		Still preliminary but anyway worthwhile enough to be mentioned ...
+	[r1255]
+		- Add a function to count subfolders of a container
+		- Add a function to wrap MAPI tables over openchangedb
+		- Factorize code used to fetch property values from LDB records
+	[r1254]
+		- Add default properties to folder records while provisioning mailbox
+		- Add few more mapping for PR_* to PidTag
+		- Add a new MAPI property to the list
+	[r1253]
+		Avoid openchangeclient --mailbox to segfault when run vs openchange server
+    bradh
+	[r1263]
+		Remove some ldb_filters, and just use varargs into ldb_search
+	[r1262]
+		warning fix for 64-bit arch.
+	[r1260]
+		Revert previous commit.
+	[r1259]
+		Experimental commit to fix build problems resulting
+		from property changes.
+
+2009-03-01
+    jkerihuel
+	[r1251]
+		- Add PidTagDisplayName property to Mailbox object
+		- Add PidTagParentFolderId to all system/special folders
+	[r1250]
+		- handles array depends if a valid mapi_repl exists. This commit
+		  fixes the destructor semantics.
+		- Fix a mapitest segfault encountered while run vs openchange server
+		- Return 1 in SRowSet_propcpy if an error was encountered.
+	[r1249]
+		Fix libmapi stack segfault when MAPI calls returns 
+		with error_code different from MAPI_E_SUCCESS.
+	[r1248]
+		Do not process NSPI request if we can't find the handle
+	[r1247]
+		Remove unnecessary ldb_filter parameter and replace it
+		with ldb_search format string.
+
+2009-02-28
+    jkerihuel
+	[r1245]
+		- GetPropertyIdsFromNames skeleton added
+	[r1244]
+		- Fix how Release replies are handled in mapi_repl[] array
+		- Remove Release size calculation
+		- Fix QueryRows size in libmapiserver
+		- Add a dummy/skeleton GetPropertiesSpecific function for mapistore objects.
+		- GetHierarchyTable skeleton added
+		- SetProperties skeleton added
+		- CreateMessage skeleton added
+		- SaveChangesMessage skeleton added
+		 
+
+2009-02-27
+    jkerihuel
+	[r1241]
+		Set mapi_response to NULL upon init ... just to get sure
+	[r1240]
+		Fix MAPIUninitialize segfault
+    bradh
+	[r1242]
+		Warning fix.
+
+2009-02-26
+    jkerihuel
+	[r1238]
+		- Add skeleton for GetContentsTable Rop
+		- Add skeleton for some [MS-OXCTABL] Rops: SetColumns, SortTable, QueryRows, SeekRows
+		- Add libmapiserver size calculation functions for all the above
+		- Ensure we only set objects parameter if it exists
+		- Return when dcesrv handle is not available
+	[r1236]
+		Merge s4-alpha7 branch back into trunk
+
+2009-02-25
+    jkerihuel
+	[r1227]
+		- Add several PidTag to openchange.ldb folders
+		- Add provisioning convenient function which adds attribute/value pair
+		to a given folder record
+		- Replace existing special folders reference within Inbox with PidTagIpm* tags
+		- Add new PidTag values to mapi-properties
+		- Add a function to libmapiproxy to build a folder EntryID as described in MS-OXODATA
+		- Add a function which builds special properties for openchangedb folders
+		- Add PT_BOOLEAN case to openchangedb folder get property function
+		- Keep a reference to the mailbox username within emsmdb provider context
+		- Create and return a handle in RegisterNotification
+		 
+	[r1226]
+		Improve PT_I8 dump
+	[r1225]
+		Wrong MessageClass size calculation fixed 
+    jelmer
+	[r1229]
+		Remove duplicate _GNU_SOURCE definition (already specified by Makefile)
+	[r1228]
+		Ignore new binary and trial output.
+
 2009-02-24
     jkerihuel
 	[r1223]

Modified: trunk/openchange/Makefile
===================================================================
--- trunk/openchange/Makefile	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/Makefile	2009-04-14 14:43:51 UTC (rev 2699)
@@ -837,7 +837,10 @@
 mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION):	mapiproxy/libmapiserver/libmapiserver_oxcstor.po	\
 							mapiproxy/libmapiserver/libmapiserver_oxcprpt.po	\
 							mapiproxy/libmapiserver/libmapiserver_oxcfold.po	\
-							mapiproxy/libmapiserver/libmapiserver_oxcnotif.po	
+							mapiproxy/libmapiserver/libmapiserver_oxctabl.po	\
+							mapiproxy/libmapiserver/libmapiserver_oxcmsg.po		\
+							mapiproxy/libmapiserver/libmapiserver_oxcnotif.po	\
+							mapiproxy/libmapiserver/libmapiserver_oxorule.po	
 	@$(CC) -o $@ $(DSOOPT) -Wl,-soname,libmapiserver.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION) $^
 
 mapiproxy/libmapiserver.$(SHLIBEXT).$(LIBMAPISERVER_SO_VERSION): libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION)
@@ -1030,7 +1033,10 @@
 						mapiproxy/servers/default/emsmdb/oxcstor.po			\
 						mapiproxy/servers/default/emsmdb/oxcprpt.po			\
 						mapiproxy/servers/default/emsmdb/oxcfold.po			\
-						mapiproxy/servers/default/emsmdb/oxcnotif.po			
+						mapiproxy/servers/default/emsmdb/oxctabl.po			\
+						mapiproxy/servers/default/emsmdb/oxcmsg.po			\
+						mapiproxy/servers/default/emsmdb/oxcnotif.po			\
+						mapiproxy/servers/default/emsmdb/oxorule.po			
 	@echo "Linking $@"
 	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) \
 						mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION)		\
@@ -1225,6 +1231,7 @@
 		utils/mapitest/modules/module_oxcprpt.o		\
 		utils/mapitest/modules/module_oxctable.o	\
 		utils/mapitest/modules/module_oxorule.o		\
+		utils/mapitest/modules/module_oxcnotif.o	\
 		utils/mapitest/modules/module_oxcfxics.o	\
 		utils/mapitest/modules/module_nspi.o		\
 		utils/mapitest/modules/module_noserver.o	\
@@ -1247,6 +1254,7 @@
 	utils/mapitest/modules/module_oxcprpt.c		\
 	utils/mapitest/modules/module_oxctable.c	\
 	utils/mapitest/modules/module_oxorule.c		\
+	utils/mapitest/modules/module_oxcnotif.c	\
 	utils/mapitest/modules/module_oxcfxics.c	\
 	utils/mapitest/modules/module_nspi.c		\
 	utils/mapitest/modules/module_noserver.c	\

Modified: trunk/openchange/VERSION
===================================================================
--- trunk/openchange/VERSION	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/VERSION	2009-04-14 14:43:51 UTC (rev 2699)
@@ -27,3 +27,12 @@
 #  ->  "0.7 (Nicky Nickname)"                               #
 #############################################################
 OPENCHANGE_VERSION_RELEASE_NICKNAME=Cochrane
+
+
+#############################################################
+# This is for specifying a release number                   #
+#                                                           #
+# e.g. OPENCHANGE_VERSION_RELEASE_VERSION=0.8.2             #
+#  ->  "0.8.2 (Nicky Nickname)"                             #
+#############################################################
+OPENCHANGE_VERSION_RELEASE_NUMBER=
\ No newline at end of file

Modified: trunk/openchange/debian/changelog
===================================================================
--- trunk/openchange/debian/changelog	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/debian/changelog	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1,4 +1,4 @@
-openchange (1:0.8+svn1229-1) experimental; urgency=low
+openchange (1:0.8+svn1312-1) experimental; urgency=low
 
   * New upstream snapshot.
   * Build exchange2ical.

Modified: trunk/openchange/doc/howto.txt
===================================================================
--- trunk/openchange/doc/howto.txt	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/doc/howto.txt	2009-04-14 14:43:51 UTC (rev 2699)
@@ -341,8 +341,10 @@
 correctly. If you have not already installed Samba4, please refer to
 section 2 for further information.
 
-Under your root account, provision the server:
+Under your root account, provision the server from the Samba4 source
+directory:
 
+# cd samba4/source
 # ./setup/provision --domain=OPENCHANGE --realm=OPENCHANGE.LOCAL \
 		    --adminpass=secret --server-role='domain controller'
 
@@ -391,13 +393,13 @@
 [0x5d] Running the Address Book Provider (EMSABP)
 =================================================
 
-The simplest is to just run "smbd", but as a developer you may find
+The simplest is to just run "samba", but as a developer you may find
 the following more useful:
 
-   # smbd -d3 -i -M single
+   # samba -d3 -i -M single
 
-that means "start smbd without messages in stdout, and running a
-single process". That mode of operation makes debugging smbd with gdb
+that means "start samba server without messages in stdout, and running a
+single process". That mode of operation makes debugging samba with gdb
 particularly easy.
 
 

Modified: trunk/openchange/exchange.idl
===================================================================
--- trunk/openchange/exchange.idl	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/exchange.idl	2009-04-14 14:43:51 UTC (rev 2699)
@@ -855,9 +855,12 @@
 			op_MAPI_Progress			= 0x50,
 			op_MAPI_GetNamesFromIDs			= 0x55,
 			op_MAPI_GetIDsFromNames			= 0x56,
+			op_MAPI_UpdateDeferredActionMessages	= 0x57,
 			op_MAPI_EmptyFolder			= 0x58,
 			op_MAPI_ExpandRow			= 0x59,
 			op_MAPI_CollapseRow			= 0x5a,
+			op_MAPI_LockRegionStream		= 0x5b,
+			op_MAPI_UnlockRegionStream		= 0x5c,
 			op_MAPI_CommitStream			= 0x5d,
 			op_MAPI_GetStreamSize			= 0x5e,
 			op_MAPI_QueryNamedProperties		= 0x5f,
@@ -2531,14 +2534,18 @@
 	/*************************/
 	/* EcDoRpc Function 0x41 */
 	typedef [flag(NDR_NOALIGN)] struct {
-		ulRowFlags     		RulesDataFlags;
+		ulRowFlags     		RuleDataFlags;
 		mapi_SPropValue_array	PropertyValues;
-	} RulesData;
+	} RuleData;
 
+	typedef [bitmap8bit] bitmap {
+		ModifyRulesFlag_Replace	= 0x01
+	} ModifyRulesFlag;
+
 	typedef [flag(NDR_NOALIGN)] struct {
-		uint8		ModifyRulesFlags;
+		ModifyRulesFlag	ModifyRulesFlags;
 		uint16		RulesCount;
- 		RulesData	RulesData[RulesCount];
+ 		RuleData	RulesData[RulesCount];
 	} ModifyRules_req;
 
 	typedef [flag(NDR_NOALIGN)] struct {
@@ -2747,7 +2754,8 @@
 	} MAPINAMEID;
 
 	typedef [flag(NDR_NOALIGN)] struct {
-		MAPITAGS	ulPropTag;
+		uint16		PropertyIdCount;
+		uint16		PropertyIds[PropertyIdCount];
 	} GetNamesFromIDs_req;
 
 	typedef [flag(NDR_NOALIGN)] struct {
@@ -2769,6 +2777,16 @@
 	} GetIDsFromNames_repl;
 
 	/*************************/
+	/* EcDoRpc Function 0x57 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	ServerEntryId;
+		SBinary_short	ClientEntryId;
+	} UpdateDeferredActionMessages_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} UpdateDeferredActionMessages_repl;
+
+	/*************************/
 	/* EcDoRpc Function 0x58 */
 	typedef [flag(NDR_NOALIGN)] struct {
 		boolean8	WantAsynchronous;
@@ -2803,6 +2821,28 @@
 	} CollapseRow_repl;
 
 	/*************************/
+	/* EcDoRpc Function 0x5b */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		RegionOffset;
+		hyper		RegionSize;
+		uint32		LockFlags;
+	} LockRegionStream_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} LockRegionStream_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x5c */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		RegionOffset;
+		hyper		RegionSize;
+		uint32		LockFlags;
+	} UnlockRegionStream_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} UnlockRegionStream_repl;
+
+	/*************************/
 	/* EcDoRpc Function 0x5d */
 	typedef [flag(NDR_NOALIGN)] struct {
 	} CommitStream_req;
@@ -3320,6 +3360,13 @@
 		[switch_is(LogonFlags)] LogonType	LogonType;
 	} Logon_repl;
 
+	/* Logon redirect response buffer (error_code == ecWrongServer) */
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		LogonFlags	LogonFlags;
+		uint8		ServerNameSize;
+		astring		ServerName;
+	} Logon_redirect;
+
 	/*************************/
 	/* EcDoRpc Function 0xA5 */
 	typedef [flag(NDR_NOALIGN)] struct {
@@ -3405,9 +3452,12 @@
 		[case(op_MAPI_Progress)] Progress_req mapi_Progress;
 		[case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_req mapi_GetNamesFromIDs;
 		[case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_req mapi_GetIDsFromNames;
+		[case(op_MAPI_UpdateDeferredActionMessages)] UpdateDeferredActionMessages_req mapi_UpdateDeferredActionMessages;
 		[case(op_MAPI_EmptyFolder)] EmptyFolder_req mapi_EmptyFolder;
 		[case(op_MAPI_ExpandRow)] ExpandRow_req mapi_ExpandRow;
 		[case(op_MAPI_CollapseRow)] CollapseRow_req mapi_CollapseRow;
+		[case(op_MAPI_LockRegionStream)] LockRegionStream_req mapi_LockRegionStream;
+		[case(op_MAPI_UnlockRegionStream)] UnlockRegionStream_req mapi_UnlockRegionStream;
 		[case(op_MAPI_CommitStream)] CommitStream_req mapi_CommitStream;
 		[case(op_MAPI_GetStreamSize)] GetStreamSize_req mapi_GetStreamSize;
 		[case(op_MAPI_QueryNamedProperties)] QueryNamedProperties_req mapi_QueryNamedProperties;
@@ -3519,9 +3569,12 @@
 		[case(op_MAPI_Progress)] Progress_repl mapi_Progress;
 		[case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_repl mapi_GetNamesFromIDs;
 		[case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_repl mapi_GetIDsFromNames;
+		[case(op_MAPI_UpdateDeferredActionMessages)] UpdateDeferredActionMessages_repl mapi_UpdateDeferredActionMessages;
 		[case(op_MAPI_EmptyFolder)] EmptyFolder_repl mapi_EmptyFolder;
 		[case(op_MAPI_ExpandRow)] ExpandRow_repl mapi_ExpandRow;
 		[case(op_MAPI_CollapseRow)] CollapseRow_repl mapi_CollapseRow;
+		[case(op_MAPI_LockRegionStream)] LockRegionStream_repl mapi_LockRegionStream;
+		[case(op_MAPI_UnlockRegionStream)] UnlockRegionStream_repl mapi_UnlockRegionStream;
 		[case(op_MAPI_CommitStream)] CommitStream_repl mapi_CommitStream;
 		[case(op_MAPI_GetStreamSize)] GetStreamSize_repl mapi_GetStreamSize;
 		[case(op_MAPI_QueryNamedProperties)] QueryNamedProperties_repl mapi_QueryNamedProperties;
@@ -3560,6 +3613,11 @@
 
 	} EcDoRpc_MAPI_REPL_UNION;
 
+	typedef [public, nodiscriminant] union {
+		[case(op_MAPI_Logon)] Logon_redirect mapi_Logon;
+		[default];
+	} EcDoRpc_MAPI_REPL_UNION_SPECIAL;
+
 	typedef [public,flag(NDR_NOALIGN)] struct {
 		uint8		opnum;
 		uint8		logon_id;
@@ -3572,6 +3630,7 @@
 		uint8		handle_idx;
 		MAPISTATUS	error_code;
 		[switch_is(opnum)] EcDoRpc_MAPI_REPL_UNION u;
+		[switch_is(opnum)] EcDoRpc_MAPI_REPL_UNION_SPECIAL us;
 	} EcDoRpc_MAPI_REPL;
 
 

Modified: trunk/openchange/libmapi/FXICS.c
===================================================================
--- trunk/openchange/libmapi/FXICS.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/FXICS.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -83,7 +83,7 @@
 	/* Fill the MAPI_REQ structure */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetLocalReplicaIds;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetLocalReplicaIds = request;
 	size += 5;

Modified: trunk/openchange/libmapi/IMAPIContainer.c
===================================================================
--- trunk/openchange/libmapi/IMAPIContainer.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMAPIContainer.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -90,6 +90,7 @@
 	enum MAPISTATUS			retval;
 	uint32_t			size = 0;
 	TALLOC_CTX			*mem_ctx;
+	uint8_t				logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -98,6 +99,8 @@
 	session = mapi_object_get_session(obj_container);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_container);
+
 	mem_ctx = talloc_named(NULL, 0, "GetContentsTable");
 	size = 0;
 
@@ -109,7 +112,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetContentsTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetContentsTable = request;
 	size += 5;
@@ -129,9 +132,10 @@
 	retval = mapi_response->mapi_repl->error_code;
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	/* set object session and handle */
+	/* set object session, handle and logon_id */
 	mapi_object_set_session(obj_table, session);
 	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_table, logon_id);
 
 	/* Retrieve RowCount if a valid pointer was set */
 	if (RowCount) {
@@ -210,6 +214,7 @@
 	enum MAPISTATUS			retval;
 	uint32_t			size = 0;
 	TALLOC_CTX			*mem_ctx;
+	uint8_t				logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -218,6 +223,8 @@
 	session = mapi_object_get_session(obj_container);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_container);
+
 	mem_ctx = talloc_named(NULL, 0, "GetHierarchyTable");
 	size = 0;
 
@@ -229,7 +236,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetHierarchyTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetHierarchyTable = request;
 	size += 5;
@@ -249,10 +256,11 @@
 	retval = mapi_response->mapi_repl->error_code;
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	/* set object session and handle */
+	/* set object session, handle and logon_id */
 	mapi_object_set_session(obj_table, session);
 	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
-	
+	mapi_object_set_logon_id(obj_table, logon_id);
+
 	/* Retrieve RowCount if a valid pointer was set */
 	if (RowCount) {
 		*RowCount = mapi_response->mapi_repl->u.mapi_GetHierarchyTable.RowCount;
@@ -299,6 +307,7 @@
 	enum MAPISTATUS		retval;
 	uint32_t		size = 0;
 	TALLOC_CTX		*mem_ctx;
+	uint8_t			logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -307,6 +316,8 @@
 	session = mapi_object_get_session(obj_container);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_container);
+
 	mem_ctx = talloc_named(NULL, 0, "GetTable");
 	size = 0;
 
@@ -318,7 +329,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx= 0;
 	mapi_req->u.mapi_GetTable = request;
 	size += 5;
@@ -338,9 +349,10 @@
 	retval = mapi_response->mapi_repl->error_code;
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	/* set object session and handle */
+	/* set object session, handle and logon_id */
 	mapi_object_set_session(obj_table, session);
 	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_table, logon_id);
 
 	/* new table */
 	mapi_object_table_init((TALLOC_CTX *)session, obj_table);
@@ -387,6 +399,7 @@
 	enum MAPISTATUS			retval;
 	uint32_t			size;
 	TALLOC_CTX			*mem_ctx;
+	uint8_t				logon_id;
 
 	/* Sanity check */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -396,6 +409,8 @@
 	session = mapi_object_get_session(obj_folder);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_folder);
+
 	mem_ctx = talloc_named(NULL, 0, "GetRulesTable");
 	size = 0;
 
@@ -409,7 +424,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetRulesTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetRulesTable = request;
 	size += 5;
@@ -429,9 +444,10 @@
 	retval = mapi_response->mapi_repl->error_code;
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	/* set object session and handle */
+	/* set object session, handle and logon_id */
 	mapi_object_set_session(obj_table, session);
 	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_table, logon_id);
 
 	/* new table */
 	mapi_object_table_init((TALLOC_CTX *)session, obj_table);
@@ -507,7 +523,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_ModifyTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx= 0;
 	mapi_req->u.mapi_ModifyTable = request;
 	size += 5;
@@ -590,7 +606,7 @@
 	enum MAPISTATUS			retval;
 	uint32_t			size;
 	TALLOC_CTX			*mem_ctx;
-	
+
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
@@ -625,7 +641,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetSearchCriteria;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_container);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetSearchCriteria = request;
 	size += 5;
@@ -712,7 +728,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetSearchCriteria;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_container);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetSearchCriteria = request;
 	size += 5;

Modified: trunk/openchange/libmapi/IMAPIFolder.c
===================================================================
--- trunk/openchange/libmapi/IMAPIFolder.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMAPIFolder.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -57,6 +57,7 @@
 	enum MAPISTATUS			retval;
 	uint32_t			size;
 	TALLOC_CTX			*mem_ctx;
+	uint8_t				logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -64,6 +65,8 @@
 	session = mapi_object_get_session(obj_folder);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_folder);
+
 	mem_ctx = talloc_named(NULL, 0, "CreateMessage");
 	size = 0;
 
@@ -80,7 +83,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CreateMessage;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CreateMessage = request;
 	size += 5;
@@ -103,6 +106,7 @@
 	/* set object session and handle */
 	mapi_object_set_session(obj_message, session);
 	mapi_object_set_handle(obj_message, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_message, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -166,7 +170,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_DeleteMessages;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_DeleteMessages = request;
 	size += 5;
@@ -241,7 +245,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetMessageStatus;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetMessageStatus = request;
 	size += 5;
@@ -341,7 +345,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetMessageStatus;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetMessageStatus = request;
 	size += 5;
@@ -440,7 +444,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_MoveCopyMessages;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_src);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_MoveCopyMessages = request;
 	size += 5;
@@ -514,6 +518,7 @@
 	enum MAPISTATUS		retval;
 	uint32_t		size;
 	TALLOC_CTX		*mem_ctx;
+	uint8_t			logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -522,6 +527,8 @@
 	session = mapi_object_get_session(obj_parent);
 	OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_parent);
+
 	/* Sanitify check on the folder type */
 	OPENCHANGE_RETVAL_IF((ulFolderType != FOLDER_GENERIC && 
 			ulFolderType != FOLDER_SEARCH),
@@ -584,7 +591,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CreateFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CreateFolder = request;
 	size += 5;
@@ -609,6 +616,7 @@
 	mapi_object_set_session(obj_child, session);
 	mapi_object_set_handle(obj_child, mapi_response->handles[1]);
 	mapi_object_set_id(obj_child, mapi_response->mapi_repl->u.mapi_CreateFolder.folder_id);
+	mapi_object_set_logon_id(obj_child, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -665,7 +673,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_EmptyFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_EmptyFolder = request;
 	size += 5;
@@ -754,7 +762,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_DeleteFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_parent);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_DeleteFolder = request;
 	size += 5;
@@ -861,7 +869,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_MoveFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_MoveFolder = request;
 	size += 5;
@@ -971,7 +979,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CopyFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CopyFolder = request;
 	size += 5;
@@ -1062,7 +1070,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetReadFlags;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetReadFlags = request;
 	size += 5;

Modified: trunk/openchange/libmapi/IMAPIProp.c
===================================================================
--- trunk/openchange/libmapi/IMAPIProp.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMAPIProp.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -117,7 +117,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetProps;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetProps = request;
 	size += 5;
@@ -235,7 +235,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetProps;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetProps = request;
 	size += 5;
@@ -327,7 +327,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SaveChangesAttachment;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_parent);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SaveChangesAttachment = request;
 	size += 5;
@@ -399,7 +399,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetPropList;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -487,7 +487,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetPropsAll;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetPropsAll = request;
 	size += 5;
@@ -565,7 +565,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_DeleteProps;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_DeleteProps = request;
 	size += 5;
@@ -641,7 +641,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_DeletePropertiesNoReplicate;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_DeletePropertiesNoReplicate = request;
 	size += 5;
@@ -718,13 +718,16 @@
 	size = 0;
 
 	/* Fill the GetNamesFromIDs operation */
-	request.ulPropTag = ulPropTag;
-	size += sizeof (uint32_t);
+	request.PropertyIdCount = 0x1;
+	size += sizeof (uint16_t);
+	request.PropertyIds = talloc_array(mem_ctx, uint16_t, request.PropertyIdCount);
+	request.PropertyIds[0] = ((ulPropTag & 0xFFFF0000) >> 16);
+	size += request.PropertyIdCount * sizeof (uint16_t);
 
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetNamesFromIDs;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetNamesFromIDs = request;
 	size += 5;
@@ -845,7 +848,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetIDsFromNames;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetIDsFromNames = request;
 	size += 5;
@@ -946,7 +949,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_QueryNamedProperties;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_QueryNamedProperties = request;
 	size += 5;
@@ -1056,7 +1059,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CopyProperties;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_src);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CopyProperties = request;
 	size += 5; // sizeof( EcDoRpc_MAPI_REQ )
@@ -1172,7 +1175,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CopyTo;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_src);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CopyTo = request;
 	size += 5; // sizeof( EcDoRpc_MAPI_REQ )

Modified: trunk/openchange/libmapi/IMAPISession.c
===================================================================
--- trunk/openchange/libmapi/IMAPISession.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMAPISession.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -62,12 +62,17 @@
 	uint32_t		size;
 	TALLOC_CTX		*mem_ctx;
 	mapi_object_store_t	*store;
+	uint8_t			logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL);
 
+	/* Find the first available logon id */
+	retval = GetNewLogonId(session, &logon_id);
+	OPENCHANGE_RETVAL_IF(retval, MAPI_E_FAILONEPROVIDER, NULL);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenPublicFolder");
 	size = 0;
 
@@ -83,7 +88,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_Logon;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_Logon = request;
 	size += 5;
@@ -102,9 +107,11 @@
 	retval = mapi_response->mapi_repl->error_code;
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	/* retrieve object session and handle */
+	/* retrieve object session, handle and logon_id */
 	mapi_object_set_session(obj_store, session);
 	mapi_object_set_handle(obj_store, mapi_response->handles[0]);
+	mapi_object_set_logon_id(obj_store, logon_id);
+	mapi_object_set_logon_store(obj_store);
 
 	/* retrieve store content */
 	obj_store->private_data = talloc((TALLOC_CTX *)session, mapi_object_store_t);
@@ -210,12 +217,17 @@
 	TALLOC_CTX		*mem_ctx;
 	mapi_object_store_t	*store;
 	char			*mailbox;
+	uint8_t			logon_id;
 
 	/* sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL);
 
+	/* Find the first available logon id */
+	retval = GetNewLogonId(session, &logon_id);
+	OPENCHANGE_RETVAL_IF(retval, MAPI_E_FAILONEPROVIDER, NULL);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenMsgStore");
 	size = 0;
 
@@ -239,7 +251,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_Logon;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_Logon = request;
 	size += 5;
@@ -258,9 +270,11 @@
 	retval = mapi_response->mapi_repl->error_code;
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	/* set object session and handle */
+	/* set object session, handle and logon_id */
 	mapi_object_set_session(obj_store, session);
 	mapi_object_set_handle(obj_store, mapi_response->handles[0]);
+	mapi_object_set_logon_id(obj_store, logon_id);
+	mapi_object_set_logon_store(obj_store);
 
 	/* retrieve store content */
 	obj_store->private_data = talloc((TALLOC_CTX *)session, mapi_object_store_t);

Modified: trunk/openchange/libmapi/IMAPISupport.c
===================================================================
--- trunk/openchange/libmapi/IMAPISupport.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMAPISupport.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -93,6 +93,7 @@
 
 	session = mapi_object_get_session(obj);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session->notify_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 
 	mem_ctx = talloc_named(NULL, 0, "Subscribe");
 
@@ -116,7 +117,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_RegisterNotification;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_RegisterNotification = request;
 	size += 5;
@@ -148,6 +149,7 @@
 	/* set notification handle */
 	mapi_object_init(&notification->obj_notif);
 	mapi_object_set_handle(&notification->obj_notif, mapi_response->handles[1]);
+	mapi_object_set_session(&notification->obj_notif, session);
 
 	notification->NotificationFlags = NotificationFlags;
 	notification->callback = notify_callback;
@@ -203,7 +205,6 @@
 	while (notification) {
 		if (notification->ulConnection == ulConnection) {
 			retval = Release(&notification->obj_notif);
-			mapi_errstr("Release", GetLastError());
 			OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 			DLIST_REMOVE(notify_ctx->notifications, notification);
 			break;

Modified: trunk/openchange/libmapi/IMAPITable.c
===================================================================
--- trunk/openchange/libmapi/IMAPITable.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMAPITable.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -82,7 +82,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetColumns;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetColumns = request;
 	size += 5;
@@ -169,7 +169,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_QueryPosition;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -263,7 +263,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_QueryRows;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_QueryRows = request;
 	size += 5;
@@ -290,7 +290,7 @@
 	reply = &mapi_response->mapi_repl->u.mapi_QueryRows;
 	rowSet->cRows = reply->RowCount;
 	rowSet->aRow = talloc_array((TALLOC_CTX *)table, struct SRow, rowSet->cRows);
-	emsmdb_get_SRowSet((TALLOC_CTX *)table, global_mapi_ctx->lp_ctx, rowSet, &table->proptags, &reply->RowData);
+	emsmdb_get_SRowSet((TALLOC_CTX *)rowSet->aRow, global_mapi_ctx->lp_ctx, rowSet, &table->proptags, &reply->RowData);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -346,7 +346,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_QueryColumnsAll;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -441,7 +441,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SeekRow;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SeekRow = request;
 	size += 5;
@@ -535,7 +535,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SeekRowBookmark;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SeekRowBookmark = request;
 	size += 5;
@@ -629,7 +629,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SeekRowApprox;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SeekRowApprox = request;
 	size += 5;
@@ -701,7 +701,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CreateBookmark;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -811,7 +811,7 @@
 			/* Fill the MAPI_REQ request */
 			mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 			mapi_req->opnum = op_MAPI_FreeBookmark;
-			mapi_req->logon_id = 0;
+			mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 			mapi_req->handle_idx = 0;
 			mapi_req->u.mapi_FreeBookmark = request;
 			size += 5;
@@ -899,7 +899,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SortTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SortTable = request;
 	size += 5;
@@ -1028,7 +1028,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_ResetTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -1125,7 +1125,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_Restrict;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_Restrict = request;
 	size += 5;
@@ -1246,7 +1246,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_FindRow;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_FindRow = request;
 	size += 5;
@@ -1334,7 +1334,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetStatus;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -1406,7 +1406,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_Abort;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -1510,7 +1510,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_ExpandRow;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_ExpandRow = request;
 	size += 5;
@@ -1606,7 +1606,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CollapseRow;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CollapseRow = request;
 	size += 5;
@@ -1699,7 +1699,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetCollapseState;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetCollapseState = request;
 	size += 5;
@@ -1741,13 +1741,7 @@
 
    \param obj_table the table we are restoring the state for
    \param CollapseState the Collapse State to restore
-   \param lpbkPosition pointer to the bookmark value. This bookmark
-   can be passed in a call to the SeekRowBookmark method
 
-   You obtain the row number and row instance number arguments from
-   the PR_INST_ID and  PR_INST_NUM properties of the row you want to
-   use as the cursor.
-
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 
    \note Developers may also call GetLastError() to retrieve the last
@@ -1760,8 +1754,7 @@
    \sa GetCollapseState
  */
 _PUBLIC_ enum MAPISTATUS SetCollapseState(mapi_object_t *obj_table,
-					  struct SBinary_short *CollapseState,
-					  uint32_t *lpbkPosition)
+					  struct SBinary_short *CollapseState)
 {
 	struct mapi_request		*mapi_request;
 	struct mapi_response		*mapi_response;
@@ -1774,7 +1767,6 @@
 	uint32_t			size;
 	TALLOC_CTX			*mem_ctx;
 	mapi_object_table_t	       	*mapi_table;
-	mapi_object_bookmark_t		*bookmark;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -1797,7 +1789,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetCollapseState;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_table);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetCollapseState = request;
 	size += 5;
@@ -1821,18 +1813,6 @@
 	mapi_table = (mapi_object_table_t *)obj_table->private_data;
 	OPENCHANGE_RETVAL_IF(!mapi_table, MAPI_E_INVALID_PARAMETER, mem_ctx);
 
-	/* Store the bookmark in the mapi_object_table private_data */
-	bookmark = talloc_zero((TALLOC_CTX *)mapi_table->bookmark, mapi_object_bookmark_t);
-	mapi_table->bk_last++;
-	bookmark->index = mapi_table->bk_last;
-	bookmark->bin.cb = reply->bookmark.cb;
-	bookmark->bin.lpb = talloc_array((TALLOC_CTX *)bookmark, uint8_t, reply->bookmark.cb);
-	memcpy(bookmark->bin.lpb, reply->bookmark.lpb, reply->bookmark.cb);
-
-	DLIST_ADD(mapi_table->bookmark, bookmark);
-
-	*lpbkPosition = mapi_table->bk_last;
-
 	obj_table->private_data = mapi_table;
 
 	talloc_free(mapi_response);

Modified: trunk/openchange/libmapi/IMSProvider.c
===================================================================
--- trunk/openchange/libmapi/IMSProvider.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMSProvider.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -256,6 +256,35 @@
 
 
 /**
+   \details Retrieve a free logon identifier within the session
+
+   \param session pointer to the MAPI session context
+   \param logon_id pointer to the logon identifier the function
+   returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI eorr
+ */
+enum MAPISTATUS GetNewLogonId(struct mapi_session *session, uint8_t *logon_id)
+{
+	int	i = 0;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!logon_id, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; i < 255; i++) {
+		if (!session->logon_ids[i]) {
+			session->logon_ids[i] = 1;
+			*logon_id = i;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	return MAPI_E_NOT_FOUND;
+}
+
+
+/**
    \details Initialize the notification subsystem
 
    This function initializes the notification subsystem, binds a local

Modified: trunk/openchange/libmapi/IMessage.c
===================================================================
--- trunk/openchange/libmapi/IMessage.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMessage.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -86,6 +86,7 @@
 	enum MAPISTATUS		retval;
 	uint32_t		size = 0;
 	TALLOC_CTX		*mem_ctx;
+	uint8_t			logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -93,6 +94,8 @@
 	session = mapi_object_get_session(obj_message);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_message);
+
 	mem_ctx = talloc_named(NULL, 0, "CreateAttach");
 	size = 0;
 
@@ -103,7 +106,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CreateAttach;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CreateAttach = request;
 	size += 5;
@@ -126,6 +129,7 @@
 	/* Set object session and handle */
 	mapi_object_set_session(obj_attach, session);
 	mapi_object_set_handle(obj_attach, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_attach, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -181,7 +185,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_DeleteAttach;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_message);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_DeleteAttach = request;
 	size += 5;
@@ -235,6 +239,7 @@
 	enum MAPISTATUS			retval;
 	TALLOC_CTX			*mem_ctx;
 	uint32_t			size = 0;
+	uint8_t				logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -243,6 +248,8 @@
 	session = mapi_object_get_session(obj_message);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_message);
+
 	mem_ctx = talloc_named(NULL, 0, "GetAttachmentTable");
 	size = 0;
 
@@ -256,7 +263,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetAttachmentTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetAttachmentTable = request;
 	size += 5;
@@ -279,6 +286,7 @@
 	/* Set object session and handle */
 	mapi_object_set_session(obj_table, session);
 	mapi_object_set_handle(obj_table, mapi_response->handles[mapi_response->mapi_repl->handle_idx]);
+	mapi_object_set_logon_id(obj_table, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -319,6 +327,7 @@
 	enum MAPISTATUS		retval;
 	uint32_t		size = 0;
 	TALLOC_CTX		*mem_ctx;
+	uint8_t			logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -326,6 +335,8 @@
 	session = mapi_object_get_session(obj_message);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_message);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenAttach");
 	size = 0;
 
@@ -340,7 +351,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_OpenAttach;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_OpenAttach = request;
 	size += 5;
@@ -363,6 +374,7 @@
 	/* Set object session and handle */
 	mapi_object_set_session(obj_attach, session);
 	mapi_object_set_handle(obj_attach, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_attach, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -678,7 +690,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_ModifyRecipients;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_message);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_ModifyRecipients = request;
 	size += 5;
@@ -759,7 +771,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_ReadRecipients;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_message);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_ReadRecipients = request;
 	size += 5;
@@ -834,7 +846,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_RemoveAllRecipients;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_message);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_RemoveAllRecipients = request;
 	size += 5;
@@ -909,7 +921,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SubmitMessage;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_message);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SubmitMessage = request;
 	size += 5;
@@ -997,7 +1009,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_AbortSubmit;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_AbortSubmit = request;
 	size += 5;
@@ -1086,7 +1098,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SaveChangesMessage;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(parent);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SaveChangesMessage = request;
 	size += 5;
@@ -1147,7 +1159,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_TransportSend;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_message);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -1274,7 +1286,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetMessageReadFlag;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetMessageReadFlag = request;
 	size += 5;
@@ -1375,10 +1387,14 @@
 	struct OpenEmbeddedMessage_req	request;
 	struct OpenEmbeddedMessage_repl	*reply;
 	struct mapi_session		*session;
+	mapi_object_message_t		*message;
+	struct SPropValue		lpProp;
 	NTSTATUS			status;
 	enum MAPISTATUS			retval;
 	uint32_t			size = 0;
 	TALLOC_CTX			*mem_ctx;
+	uint32_t			i = 0;
+	uint8_t				logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -1387,6 +1403,8 @@
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!obj_embeddedmsg, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_attach);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenEmbeddedMessage");
 
 	/* Fill the OpenEmbeddedMessage request */
@@ -1400,7 +1418,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_OpenEmbeddedMessage;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_OpenEmbeddedMessage = request;
 	size += 5;
@@ -1423,10 +1441,41 @@
 	/* Set object session and handle */
 	mapi_object_set_session(obj_embeddedmsg, session);
 	mapi_object_set_handle(obj_embeddedmsg, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_embeddedmsg, logon_id);
 
 	/* Store OpenEmbeddedMessage reply data */
 	reply = &mapi_response->mapi_repl->u.mapi_OpenEmbeddedMessage;
 
+	message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t);
+	message->cValues = reply->RecipientCount;
+	message->SRowSet.cRows = reply->RowCount;
+	message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1);
+
+	message->SPropTagArray.cValues = reply->RecipientCount;
+	message->SPropTagArray.aulPropTag = talloc_steal(message, reply->RecipientColumns);
+
+	for (i = 0; i < reply->RowCount; i++) {
+		emsmdb_get_SRow((TALLOC_CTX *)message, global_mapi_ctx->lp_ctx,
+				&(message->SRowSet.aRow[i]), &message->SPropTagArray,
+				reply->RecipientRows[i].RecipientRow.prop_count,
+				&reply->RecipientRows[i].RecipientRow.prop_values,
+				reply->RecipientRows[i].RecipientRow.layout, 1);
+
+		lpProp.ulPropTag = PR_RECIPIENT_TYPE;
+		lpProp.value.l = reply->RecipientRows[i].RecipientType;
+		SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
+
+		lpProp.ulPropTag = PR_INTERNET_CPID;
+		lpProp.value.l = reply->RecipientRows[i].CodePageId;
+		SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
+	}
+
+	/* add SPropTagArray elements we automatically append to SRow */
+	SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_RECIPIENT_TYPE);
+	SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_INTERNET_CPID);
+	
+	obj_embeddedmsg->private_data = (void *) message;
+
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
 

Modified: trunk/openchange/libmapi/IMsgStore.c
===================================================================
--- trunk/openchange/libmapi/IMsgStore.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IMsgStore.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -58,6 +58,7 @@
 	enum MAPISTATUS		retval;
 	uint32_t		size = 0;
 	TALLOC_CTX		*mem_ctx;
+	uint8_t			logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -65,6 +66,8 @@
 	session = mapi_object_get_session(obj_store);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_store);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenFolder");
 
 	/* Fill the OpenFolder operation */
@@ -76,7 +79,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_OpenFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_OpenFolder = request;
 	size += 5;
@@ -100,6 +103,7 @@
 	mapi_object_set_session(obj_folder, session);
 	mapi_object_set_id(obj_folder, id_folder);
 	mapi_object_set_handle(obj_folder, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_folder, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -164,7 +168,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_PublicFolderIsGhosted;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_PublicFolderIsGhosted = request;
 	size += 5;
@@ -222,6 +226,7 @@
 	enum MAPISTATUS				retval;
 	uint32_t				size = 0;
 	TALLOC_CTX				*mem_ctx;
+	uint8_t					logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -231,6 +236,8 @@
 	session = mapi_object_get_session(obj_folder);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_folder);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenPublicFolderByName");
 	size = 0;
 
@@ -245,7 +252,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_OpenPublicFolderByName;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_OpenPublicFolderByName = request;
 	size += 5;
@@ -268,6 +275,7 @@
 	/* Set object session and handle */
 	mapi_object_set_session(obj_child, session);
 	mapi_object_set_handle(obj_child, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_child, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -326,7 +334,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetReceiveFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetReceiveFolder = request;
 	size += 5;
@@ -412,7 +420,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetReceiveFolder;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetReceiveFolder = request;
 	size += 5;
@@ -485,7 +493,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetReceiveFolderTable;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -519,10 +527,16 @@
 		SRowSet->aRow[i].lpProps[0].dwAlignPad = 0x0;
 		SRowSet->aRow[i].lpProps[0].value.d = reply->entries[i].fid;
 
-		SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS;
-		SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0;
-		SRowSet->aRow[i].lpProps[1].value.lpszA = talloc_strdup((TALLOC_CTX *)SRowSet->aRow, reply->entries[i].lpszMessageClass);
-	
+		if (reply->entries[i].lpszMessageClass && strlen(reply->entries[i].lpszMessageClass)) {
+			SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS;
+			SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0;
+			SRowSet->aRow[i].lpProps[1].value.lpszA = talloc_strdup((TALLOC_CTX *)SRowSet->aRow[i].lpProps, reply->entries[i].lpszMessageClass);
+		} else {
+			SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS;
+			SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0;
+			SRowSet->aRow[i].lpProps[1].value.lpszA = "";
+		}
+
 		SRowSet->aRow[i].lpProps[2].ulPropTag = PR_LAST_MODIFICATION_TIME;
 		SRowSet->aRow[i].lpProps[2].dwAlignPad = 0x0;
 		SRowSet->aRow[i].lpProps[2].value.ft.dwLowDateTime = reply->entries[i].modiftime.dwLowDateTime;
@@ -576,7 +590,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetTransportFolder;
-	mapi_req->logon_id =0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -671,7 +685,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetOwningServers;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_GetOwningServers = request;
 	size += 5;
@@ -752,7 +766,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetStoreState;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	size += 5;
 

Modified: trunk/openchange/libmapi/IStoreFolder.c
===================================================================
--- trunk/openchange/libmapi/IStoreFolder.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IStoreFolder.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -78,6 +78,7 @@
 	uint32_t			size = 0;
 	TALLOC_CTX			*mem_ctx;
 	uint32_t			i = 0;
+	uint8_t				logon_id;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -85,6 +86,8 @@
 	session = mapi_object_get_session(obj_store);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_store);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenMessage");
 
 	/* Fill the OpenMessage operation */
@@ -98,7 +101,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_OpenMessage;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_OpenMessage = request;
 	size += 5;
@@ -121,6 +124,7 @@
 	/* Set object session and handle */
 	mapi_object_set_session(obj_message, session);
 	mapi_object_set_handle(obj_message, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_message, logon_id);
 
 	/* Store OpenMessage reply data */
 	reply = &mapi_response->mapi_repl->u.mapi_OpenMessage;
@@ -131,7 +135,7 @@
 	message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1);
 
 	message->SPropTagArray.cValues = reply->RecipientColumns.cValues;
-	message->SPropTagArray.aulPropTag = reply->RecipientColumns.aulPropTag;
+	message->SPropTagArray.aulPropTag = talloc_steal(message, reply->RecipientColumns.aulPropTag);
 
 	for (i = 0; i < reply->RowCount; i++) {
 		emsmdb_get_SRow((TALLOC_CTX *)message, global_mapi_ctx->lp_ctx,

Modified: trunk/openchange/libmapi/IStream.c
===================================================================
--- trunk/openchange/libmapi/IStream.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IStream.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -73,12 +73,15 @@
 	enum MAPISTATUS		retval;
 	uint32_t		size = 0;
 	TALLOC_CTX		*mem_ctx;
+	uint8_t			logon_id;
 
 	/* Sanity checks */
 	session = mapi_object_get_session(obj_related);
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 
+	logon_id = mapi_object_get_logon_id(obj_related);
+
 	mem_ctx = talloc_named(NULL, 0, "OpenStream");
 
 	size = 0;
@@ -94,7 +97,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_OpenStream;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = logon_id;
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_OpenStream = request;
 	size += 5;
@@ -117,6 +120,7 @@
 	/* Set object session and handle */
 	mapi_object_set_session(obj_stream, session);
 	mapi_object_set_handle(obj_stream, mapi_response->handles[1]);
+	mapi_object_set_logon_id(obj_stream, logon_id);
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -186,7 +190,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_ReadStream;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_ReadStream = request;
 	size += 5;
@@ -282,7 +286,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_WriteStream;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_WriteStream = request;
 	size += 5;
@@ -351,7 +355,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CommitStream;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -417,7 +421,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_GetStreamSize;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -466,8 +470,8 @@
    \note Developers may also call GetLastError() to retrieve the last
    MAPI error code. Possible MAPI error codes are:
    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
-   - MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or
-     beyond the last row requested.
+   - MAPI_E_INVALID_PARAMETER: obj_stream is not valid, Origin is out
+   of limits, or NewPosition is null.
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
    transaction
    
@@ -507,7 +511,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SeekStream;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SeekStream = request;
 	size += 5;
@@ -546,8 +550,7 @@
    \note Developers may also call GetLastError() to retrieve the last
    MAPI error code. Possible MAPI error codes are:
    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
-   - MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or
-     beyond the last row requested.
+   - MAPI_E_INVALID_PARAMETER: obj_stream is not valid
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
    transaction
    
@@ -581,7 +584,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetStreamSize;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SetStreamSize = request;
 	size += 5;
@@ -674,7 +677,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_CopyToStream;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_src);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_CopyToStream = request;
 	size += 5;
@@ -702,3 +705,164 @@
 
 	return MAPI_E_SUCCESS;
 }
+
+/**
+   \details Lock a range of bytes within the stream
+
+   \param obj_stream the stream object
+   \param RegionOffset starting point for the range
+   \param RegionSize length of the range
+   \param LockFlags type of locking to apply
+
+   Setting LockFlags to 0x00000001 will provide a write lock (i.e. one
+   writer, any number of readers). Setting LockFlags to any other value
+   will provide a read-write lock (one reader/writer, no other readers
+   or writers).
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+   - MAPI_E_INVALID_PARAMETER: obj_stream is not valid
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa UnlockRegionStream 
+ */
+_PUBLIC_ enum MAPISTATUS LockRegionStream(mapi_object_t *obj_stream, uint64_t RegionOffset, 
+					  uint64_t RegionSize, uint32_t LockFlags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct LockRegionStream_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "LockRegionStream");
+	size = 0;
+
+	/* Fill the LockRegionStream operation */
+	request.RegionOffset = RegionOffset;
+	size += sizeof (uint64_t);
+	request.RegionSize = RegionSize;
+	size += sizeof (uint64_t);
+	request.LockFlags = LockFlags;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_LockRegionStream;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_LockRegionStream = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t);
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
+	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
+
+	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+	retval = mapi_response->mapi_repl->error_code;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Unlock a range of bytes within the stream
+
+   \param obj_stream the stream object
+   \param RegionOffset starting point for the range
+   \param RegionSize length of the range
+   \param LockFlags type of locking
+
+   LockFlags used in unlocking must match the LockFlags used in locking.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+   - MAPI_E_INVALID_PARAMETER: obj_stream is not valid
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa UnlockRegionStream 
+ */
+_PUBLIC_ enum MAPISTATUS UnlockRegionStream(mapi_object_t *obj_stream, uint64_t RegionOffset, 
+					    uint64_t RegionSize, uint32_t LockFlags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct UnlockRegionStream_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "UnlockRegionStream");
+	size = 0;
+
+	/* Fill the LockRegionStream operation */
+	request.RegionOffset = RegionOffset;
+	size += sizeof (uint64_t);
+	request.RegionSize = RegionSize;
+	size += sizeof (uint64_t);
+	request.LockFlags = LockFlags;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_UnlockRegionStream;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_UnlockRegionStream = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t);
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
+	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
+
+	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+	retval = mapi_response->mapi_repl->error_code;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Modified: trunk/openchange/libmapi/IUnknown.c
===================================================================
--- trunk/openchange/libmapi/IUnknown.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IUnknown.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -130,7 +130,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_Release;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -217,7 +217,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_LongTermIdFromId;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_LongTermIdFromId = request;
 	size += 5;
@@ -299,7 +299,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_IdFromLongTermId;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_IdFromLongTermId = request;
 	size += 5;

Modified: trunk/openchange/libmapi/IXPLogon.c
===================================================================
--- trunk/openchange/libmapi/IXPLogon.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/IXPLogon.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -75,7 +75,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_AddressTypes;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -145,7 +145,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SetSpooler;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	size += 5;
 
@@ -230,7 +230,7 @@
 	/* Fill the MAPI_REQ request */
 	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
 	mapi_req->opnum = op_MAPI_SpoolerLockMessage;
-	mapi_req->logon_id = 0;
+	mapi_req->logon_id = mapi_object_get_logon_id(obj_store);
 	mapi_req->handle_idx = 0;
 	mapi_req->u.mapi_SpoolerLockMessage = request;
 	size += 5;

Modified: trunk/openchange/libmapi/cdo_mapi.c
===================================================================
--- trunk/openchange/libmapi/cdo_mapi.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/cdo_mapi.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -132,6 +132,7 @@
 	/* If the session doesn't exist, create a new one */
 	if (!*session) {
 		el = talloc_zero((TALLOC_CTX *)global_mapi_ctx->session, struct mapi_session);
+		memset(el->logon_ids, 0, 255);
 		OPENCHANGE_RETVAL_IF(!el, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
 	} else {
 		/* Lookup the session within the chained list */

Modified: trunk/openchange/libmapi/conf/mapi-properties
===================================================================
--- trunk/openchange/libmapi/conf/mapi-properties	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/conf/mapi-properties	2009-04-14 14:43:51 UTC (rev 2699)
@@ -290,7 +290,7 @@
 0x10f1001e  PR_OWA_URL
 0x10f2000b  PR_DISABLE_FULL_FIDELITY
 0x10f3001e  PR_URL_COMP_NAME
-0x10f4000b  PR_ATTR_HIDDEN
+0x10f4000b  PR_ATTR_HIDDEN				PidTagAttrHidden
 0x10f5000b  PR_ATTR_SYSTEM
 0x10f6000b  PR_ATTR_READONLY
 0x11000102  PR_P1_CONTENT
@@ -300,7 +300,7 @@
 0x3002001e  PR_ADDRTYPE
 0x3003001e  PR_EMAIL_ADDRESS
 0x3004001e  PR_COMMENT
-0x30050003  PR_DEPTH
+0x30050003  PR_DEPTH					PidTagDepth
 0x3006001e  PR_PROVIDER_DISPLAY
 0x30070040  PR_CREATION_TIME
 0x30080040  PR_LAST_MODIFICATION_TIME
@@ -353,7 +353,7 @@
 0x3610000d  PR_FOLDER_ASSOCIATED_CONTENTS
 0x36110102  PR_DEF_CREATE_DL
 0x36120102  PR_DEF_CREATE_MAILUSER
-0x3613001e  PR_CONTAINER_CLASS
+0x3613001e  PR_CONTAINER_CLASS				PidTagContainerClass
 0x36140014  PR_CONTAINER_MODIFY_VERSION
 0x36150102  PR_AB_PROVIDER_ID
 0x36160102  PR_DEFAULT_VIEW_ENTRYID
@@ -368,6 +368,7 @@
 0x36d60102  PR_REMINDERS_OFFLINE_ENTRYID
 0x36d70102  PR_IPM_DRAFTS_ENTRYID			PidTagIpmDraftsEntryId
 0x36d81102  PR_OUTLOOK_2003_ENTRYIDS
+0x36da0102  PR_EXTENDED_FOLDER_FLAGS			PidTagExtendedFolderFlags
 0x36df0102  PR_FOLDER_WEBVIEWINFO
 0x36e00102  PR_FOLDER_XVIEWINFO_E
 0x36e10003  PR_FOLDER_VIEWS_ONLY

Modified: trunk/openchange/libmapi/conf/mparse.pl
===================================================================
--- trunk/openchange/libmapi/conf/mparse.pl	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/conf/mparse.pl	2009-04-14 14:43:51 UTC (rev 2699)
@@ -38,6 +38,7 @@
     0x1e	=> "PT_STRING8",
     0x1f	=> "PT_UNICODE",
     0x40	=> "PT_SYSTIME",
+    0xFE	=> "PT_ACTIONS",
     0x48	=> "PT_CLSID",
     0x102	=> "PT_BINARY",
 # Multi-valued property types
@@ -72,6 +73,7 @@
     "PT_UNICODE"	=>	0x1f,
     "PT_SYSTIME"	=>	0x40,
     "PT_CLSID"		=>	0x48,
+    "PT_ACTIONS"	=>	0xfe,
     "PT_BINARY"		=>	0x102,
 # Multi-valued property types
     "PT_MV_SHORT"	=>	0x1002,

Modified: trunk/openchange/libmapi/emsmdb.c
===================================================================
--- trunk/openchange/libmapi/emsmdb.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/emsmdb.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -257,12 +257,14 @@
 {
 	struct mapi_response	*mapi_response = (struct mapi_response *)data;
 
-	if (mapi_response->handles) {
-		talloc_free(mapi_response->handles);
-	}
+	if (mapi_response->mapi_repl) {
+		if (mapi_response->handles) {
+			talloc_free(mapi_response->handles);
+		}
 
-	if (mapi_response->mapi_repl) {
-		talloc_free(mapi_response->mapi_repl);
+		if (!mapi_response->mapi_repl->error_code) {
+			talloc_free(mapi_response->mapi_repl);
+		}
 	}
 
 	return 0;
@@ -298,7 +300,9 @@
 	r.in.size = emsmdb_ctx->max_data;
 	r.in.offset = 0x0;
 
-	mapi_response = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_response);	
+	mapi_response = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_response);
+	mapi_response->mapi_repl = NULL;
+	mapi_response->handles = NULL;
 	talloc_set_destructor((void *)mapi_response, (int (*)(void *))mapi_response_destructor);
 	r.out.mapi_response = mapi_response;
 
@@ -329,9 +333,11 @@
 			errno = 0;
 			emsmdb_ctx->max_data = 0x7FFF;
 			emsmdb_ctx->setup = true;
+			talloc_free(mapi_response);
 			talloc_free(mem_ctx);
 			goto start;
 		} else {
+			talloc_free(mapi_response);
 			talloc_free(mem_ctx);
 			return status;
 		}
@@ -340,6 +346,10 @@
 	}
 	emsmdb_ctx->cache_size = emsmdb_ctx->cache_count = 0;
 
+	if (r.out.mapi_response->mapi_repl && r.out.mapi_response->mapi_repl->error_code) {
+		r.out.mapi_response->handles = NULL;
+	}
+
 	*repl = r.out.mapi_response;
 
 	talloc_free(mem_ctx);
@@ -684,6 +694,7 @@
 
 		data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, tags->aulPropTag[i_tag], content);
 		if (data) {
+			talloc_steal(*propvals, data);
 			p_propval = &((*propvals)[i_propval]);
 			p_propval->ulPropTag = tags->aulPropTag[i_tag];
 			p_propval->dwAlignPad = 0x0;
@@ -770,6 +781,7 @@
 			if (havePropertyValue) {
 				lpProps[prop].dwAlignPad = 0x0;
 				data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, lpProps[prop].ulPropTag, content);
+				talloc_steal(lpProps, data);
 				set_SPropValue(&lpProps[prop], data);
 			}
 		}
@@ -825,6 +837,7 @@
 		} 
 
 		data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, aulPropTag, content);
+		talloc_steal(aRow->lpProps, data);
 		aRow->lpProps[i].ulPropTag = aulPropTag;
 		aRow->lpProps[i].dwAlignPad = 0x0;
 		set_SPropValue(&(aRow->lpProps[i]), data);

Modified: trunk/openchange/libmapi/mapi_object.c
===================================================================
--- trunk/openchange/libmapi/mapi_object.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/mapi_object.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -45,6 +45,8 @@
 static void mapi_object_reset(mapi_object_t *obj)
 {
 	obj->handle = INVALID_HANDLE_VALUE;
+	obj->logon_id = 0;
+	obj->store = false;
 	obj->id = 0;
 	obj->session = NULL;
 	obj->private_data = NULL;
@@ -99,6 +101,11 @@
 		if (obj->private_data) {
 			talloc_free(obj->private_data);
 		}
+
+		if (obj->store == true && obj->session) {
+			obj->session->logon_ids[obj->logon_id] = 0;
+		}
+
 		mapi_object_reset(obj);
 	}
 }
@@ -141,6 +148,8 @@
 	dst->id = src->id;
 	dst->handle = src->handle;
 	dst->private_data = src->private_data;
+	dst->logon_id = src->logon_id;
+	dst->session = src->session;
 
 	return MAPI_E_SUCCESS;
 }
@@ -204,6 +213,48 @@
 
 
 /**
+   \details Set the logon id for a given MAPI object
+
+   \param obj pointer to the object to set the logon id for
+   \param logon_id the logon identifier to associate to the MAPI
+   object
+ */
+_PUBLIC_ void mapi_object_set_logon_id(mapi_object_t *obj, 
+				       uint8_t logon_id)
+{
+	if (obj) {
+		obj->logon_id = logon_id;
+	}
+}
+
+
+/**
+   \details Retrieve the logon id for a given MAPI object
+
+   \param obj pointer to the object to retrieve the logon id from
+
+   \return the object logon ID on success, otherwise -1
+ */
+_PUBLIC_ uint8_t mapi_object_get_logon_id(mapi_object_t *obj)
+{
+	return (!obj) ? -1 : obj->logon_id;
+}
+
+
+/**
+   \details Mark a MAPI object as a store object
+   
+   \param obj pointer to the object to set the store boolean for
+ */
+_PUBLIC_ void mapi_object_set_logon_store(mapi_object_t *obj)
+{
+	if (obj) {
+		obj->store = true;
+	}
+}
+
+
+/**
    \details Retrieve the handle associated to a MAPI object
 
    \param obj pointer on the MAPI object to retrieve the handle from

Modified: trunk/openchange/libmapi/mapi_object.h
===================================================================
--- trunk/openchange/libmapi/mapi_object.h	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/mapi_object.h	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1,7 +1,7 @@
 /*
    OpenChange MAPI implementation.
 
-   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Julien Kerihuel 2007-2009.
    Copyright (C) Fabien Le Mentec 2007.
 
    This program is free software; you can redistribute it and/or modify
@@ -36,9 +36,11 @@
 typedef uint32_t mapi_handle_t;
 
 typedef struct mapi_object {
+	bool			store;
 	uint64_t		id;
 	mapi_handle_t		handle;
-  struct mapi_session		*session;
+	uint8_t			logon_id;
+	struct mapi_session	*session;
 	void			*private_data;
 } mapi_object_t;
 

Modified: trunk/openchange/libmapi/mapi_provider.h
===================================================================
--- trunk/openchange/libmapi/mapi_provider.h	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/mapi_provider.h	2009-04-14 14:43:51 UTC (rev 2699)
@@ -50,6 +50,7 @@
 	struct mapi_profile		*profile;
 	struct mapi_notify_ctx		*notify_ctx;
 	struct mapi_objects		*objects;
+	uint8_t				logon_ids[255];
 
 	struct mapi_session		*next;
 	struct mapi_session		*prev;

Modified: trunk/openchange/libmapi/mapidefs.h
===================================================================
--- trunk/openchange/libmapi/mapidefs.h	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/mapidefs.h	2009-04-14 14:43:51 UTC (rev 2699)
@@ -47,6 +47,7 @@
 #define	PT_CLSID		0x48
 #define	PT_SVREID		0xFB
 #define	PT_SRESTRICT		0xFD
+#define	PT_ACTIONS		0xFE
 #define	PT_BINARY		0x102
 
 /* Multi valued property types */

Modified: trunk/openchange/libmapi/nspi.c
===================================================================
--- trunk/openchange/libmapi/nspi.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/nspi.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1019,6 +1019,7 @@
 
 	talloc_free(mem_ctx);
 
+	errno = retval;
 	return MAPI_E_SUCCESS;
 }
 

Modified: trunk/openchange/libmapi/property.c
===================================================================
--- trunk/openchange/libmapi/property.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/property.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -596,12 +596,26 @@
 	return MAPI_E_SUCCESS;
 }
 
+
+/**
+   \details Append a SPropValue structure to given SRowSet
+
+   \param mem_ctx pointer to the memory context
+   \param SRowSet pointer to the SRowSet array to update
+   \param SPropValue the SPropValue to append within SRowSet
+
+   \return 0 on success, otherwise 1
+ */
 _PUBLIC_ uint32_t SRowSet_propcpy(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, struct SPropValue SPropValue)
 {
 	uint32_t	rows;
 	uint32_t	cValues;
 	struct SPropValue lpProp;
 
+	/* Sanity checks */
+
+	if (!SRowSet) return 1;
+
 	for (rows = 0; rows < SRowSet->cRows; rows++) {
 		cValues = SRowSet->aRow[rows].cValues + 1;
 		SRowSet->aRow[rows].lpProps = talloc_realloc(mem_ctx, SRowSet->aRow[rows].lpProps, struct SPropValue, cValues);

Modified: trunk/openchange/libmapi/utils.c
===================================================================
--- trunk/openchange/libmapi/utils.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/libmapi/utils.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -150,7 +150,7 @@
 	   ID may change (0x1 or 0x4 values identified so far).
 	   However this byte sounds the same than the parent folder
 	   one */
-	*fid += (parent_fid & 0xFF);
+	*fid += (parent_fid & 0xFFFF);
 
 	return MAPI_E_SUCCESS;
 }

Modified: trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -40,39 +40,38 @@
 	return NT_STATUS_OK;
 }
 
-
-static NTSTATUS mapiproxy_op_bind_proxy(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
+static NTSTATUS mapiproxy_op_connect(struct dcesrv_call_state *dce_call, 
+				     const struct ndr_interface_table *table,
+				     const char *binding)
 {
 	NTSTATUS				status;
-	const struct ndr_interface_table	*table;
 	struct dcesrv_mapiproxy_private		*private;
-	const char				*binding;
 	const char				*user;
 	const char				*pass;
 	const char				*domain;
 	struct cli_credentials			*credentials;
+	bool					acquired_creds = false;
 	bool					machine_account;
 
-	/* Retrieve parametric options */
-	binding = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "binding");
-	machine_account = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "use_machine_account", false);
+	DEBUG(5, ("mapiproxy::mapiproxy_op_connect\n"));
 
-	private = dce_call->context->private;
-
+	/* Retrieve the binding string from parametric options if undefined */
 	if (!binding) {
-		DEBUG(0, ("You must specify a DCE/RPC binding string\n"));
-		return NT_STATUS_INVALID_PARAMETER;
+		binding = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "binding");
+		if (!binding) {
+			DEBUG(0, ("You must specify a DCE/RPC binding string\n"));
+			return NT_STATUS_INVALID_PARAMETER;
+		}
 	}
 
+	/* Retrieve parametric options */
+	machine_account = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "use_machine_account", false);
 	user = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "username");
 	pass = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "password");
 	domain = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "domain");
 
-	table = ndr_table_by_uuid(&iface->syntax_id.uuid);
-	if (!table) {
-		dce_call->fault_code = DCERPC_FAULT_UNK_IF;
-		return NT_STATUS_NET_WRITE_FAULT;
-	}
+	/* Retrieve private mapiproxy data */
+	private = dce_call->context->private_data;
 
 	if (user && pass) {
 		DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using specified account\n"));
@@ -104,6 +103,11 @@
 	} else if (dce_call->conn->auth_state.session_info->credentials) {
 		DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using delegated credentials\n"));
 		credentials = dce_call->conn->auth_state.session_info->credentials;
+		acquired_creds = true;
+	} else if (private->credentials) {
+		DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using acquired deletegated credentials\n"));
+		credentials = private->credentials;
+		acquired_creds = true;
 	} else {
 		DEBUG(1, ("dcerpc_mapiproxy: RPC proxy: You must supply binding, user and password or have delegated credentials\n"));
 		return NT_STATUS_INVALID_PARAMETER;
@@ -133,36 +137,73 @@
 		default:
 			break;
 		}
-
+		
 		pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table,
 							   credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
 		status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(private->c_pipe));
-		
-		talloc_free(credentials);
+
+		if (acquired_creds == false) {
+			talloc_free(credentials);
+		}
+
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
 		dce_call->context->assoc_group_id = private->c_pipe->assoc_group_id;
- 		
+		
 	} else {
 		status = dcerpc_pipe_connect(dce_call->context,
 					     &(private->c_pipe), binding, table,
 					     credentials, dce_call->event_ctx,
 					     dce_call->conn->dce_ctx->lp_ctx);
+		
+		if (acquired_creds == false) {
+			talloc_free(credentials);
+		}
 
-		talloc_free(credentials);
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
 		dce_call->context->assoc_group_id = private->c_pipe->assoc_group_id;
 	}
 
+	private->connected = true;
+
 	DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: CONNECTED\n"));
 
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS mapiproxy_op_bind_proxy(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
+{
+	NTSTATUS				status;
+	const struct ndr_interface_table	*table;
+	struct dcesrv_mapiproxy_private		*private;
+	bool					delegated;
 
+	/* Retrieve private mapiproxy data */
+	private = dce_call->context->private_data;
+
+	table = ndr_table_by_uuid(&iface->syntax_id.uuid);
+	if (!table) {
+		dce_call->fault_code = DCERPC_FAULT_UNK_IF;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	if (dce_call->conn->auth_state.session_info->credentials) {
+		private->credentials = dce_call->conn->auth_state.session_info->credentials;
+		DEBUG(5, ("dcerpc_mapiproxy: Delegated credentials acquired\n"));
+	}
+
+	delegated = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "delegated_auth", false);
+	if (delegated == false) {
+		status = mapiproxy_op_connect(dce_call, table, NULL);
+	}
+
+	return status;
+}
+
+
 /**
    \details This function is called when the client binds to one of
    the interfaces mapiproxy handles.
@@ -193,8 +234,10 @@
 	private->c_pipe = NULL;
 	private->exchname = NULL;
 	private->server_mode = server_mode;
-	dce_call->context->private = private;
+	private->connected = false;
 
+	dce_call->context->private_data = private;
+
 	if (server_mode == false) {
 		return mapiproxy_op_bind_proxy(dce_call, iface);
 	}
@@ -213,7 +256,7 @@
  */
 static void mapiproxy_op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
 {
-	struct dcesrv_mapiproxy_private	*private = (struct dcesrv_mapiproxy_private *) context->private;
+	struct dcesrv_mapiproxy_private	*private = (struct dcesrv_mapiproxy_private *) context->private_data;
 
 	DEBUG(5, ("mapiproxy::mapiproxy_op_unbind\n"));
 
@@ -245,17 +288,37 @@
  */
 static NTSTATUS mapiproxy_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
 {
+	NTSTATUS				status;
 	enum ndr_err_code			ndr_err;
 	const struct ndr_interface_table	*table;
 	uint16_t				opnum;
+	struct dcesrv_mapiproxy_private		*private;
 
+
 	DEBUG(5, ("mapiproxy::mapiproxy_op_ndr_pull\n"));
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	private = dce_call->context->private_data;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 
 	dce_call->fault_code = 0;
 
+	if (!NTLM_AUTH_IS_OK(dce_call)) {
+		DEBUG(0, ("User is not authenticated, cannot process\n"));
+		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	/* If remote connection bind/auth has been delayed */
+	if (private->connected == false) {
+		status = mapiproxy_op_connect(dce_call, table, NULL);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
+			return NT_STATUS_NET_WRITE_FAULT;
+		}
+	}
+
 	if (opnum >= table->num_calls) {
 		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
 		return NT_STATUS_NET_WRITE_FAULT;
@@ -308,8 +371,8 @@
 
 	DEBUG(5, ("mapiproxy::mapiproxy_op_ndr_push\n"));
 
-	private = dce_call->context->private;
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	private = dce_call->context->private_data;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 
 	name = table->calls[opnum].name;
@@ -384,8 +447,8 @@
 	const char				*name;
 	NTSTATUS				status;
 
-	private = dce_call->context->private;
-	table = dce_call->context->iface->private;
+	private = dce_call->context->private_data;
+	table = dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 
 	name = table->calls[opnum].name;
@@ -479,7 +542,7 @@
  */
 static NTSTATUS mapiproxy_register_one_iface(struct dcesrv_context *dce_ctx, const struct dcesrv_interface *iface)
 {
-	const struct ndr_interface_table	*table = iface->private;
+	const struct ndr_interface_table	*table = iface->private_data;
 	int					i;
 
 	for (i = 0; i < table->endpoints->count; i++) {
@@ -558,7 +621,7 @@
 	iface->reply = mapiproxy_op_reply;
 	iface->ndr_push = mapiproxy_op_ndr_push;
 
-	iface->private = tbl;
+	iface->private_data = tbl;
 
 	return true;
 }

Modified: trunk/openchange/mapiproxy/dcesrv_mapiproxy.h
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy.h	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy.h	2009-04-14 14:43:51 UTC (rev 2699)
@@ -49,9 +49,11 @@
 #include <mapiproxy/libmapiproxy/libmapiproxy.h>
 
 struct dcesrv_mapiproxy_private {
-	struct dcerpc_pipe	*c_pipe;
-	char			*exchname;
-	bool			server_mode;
+	struct dcerpc_pipe			*c_pipe;
+	char					*exchname;
+	bool					server_mode;
+	bool					connected;
+	struct cli_credentials			*credentials;
 };
 
 enum exchange_handle {

Modified: trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -130,7 +130,7 @@
 	char			*lpszA;
 	char			*exchname;
 
-	private = dce_call->context->private;
+	private = dce_call->context->private_data;
 
 	/* Sanity checks */
 	if (!r->out.ppRows) return false;
@@ -192,7 +192,7 @@
 	const char			*proxyname;
 	uint32_t			i;
 
-	private = dce_call->context->private;
+	private = dce_call->context->private_data;
 	proxyname = lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
 
 	if (!private->exchname) return false;

Modified: trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy
===================================================================
--- trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy	2009-04-14 14:43:51 UTC (rev 2699)
@@ -81,6 +81,12 @@
 	   <td style="text-align:center"><strong>Revision Content</strong></td>
 	</tr>
 	<tr>
+	   <td style="text-align:center">03/03/09</td>
+	   <td style="text-align:center"><strong>0.6.2</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">Add configuration info for server mode.</td>
+	</tr>	
+	<tr>
 	   <td style="text-align:center">01/02/09</td>
 	   <td style="text-align:center"><strong>0.6.1</strong></td>
 	   <td style="text-align:center">Julien Kerihuel</td>
@@ -1194,7 +1200,24 @@
 OpenChange server
 </li>
 
-<li><strong>[3] Configure OpenChange server options</strong>:<br/>
+<li><strong>[3] Create the OpenChange Dispatcher database</strong>:<br/>
+OpenChange uses a dispatcher database designed to store generic and
+top-level information about user mailbox. The following command will
+create a blank openchangedb ldb database:
+\code
+# ./setup/openchange_provision --openchangedb
+\endcode
+</li>
+
+<li><strong>[4] Create a mailbox for the user in the OpenChange
+Dispatcher database</strong>:<br/>
+Run under the root account:
+\code
+# ./setup/openchange_newuser --mailbox <username>
+\endcode
+</li>
+
+<li><strong>[5] Configure OpenChange server options</strong>:<br/>
 OpenChange server only requires a very limited set of options to be
 added to <i>smb.conf</i> in order to run. Note that the following
 configuration also works with existing MAPIProxy configuration. This

Modified: trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -44,7 +44,7 @@
 	const struct ndr_interface_table	*table;
 	NTSTATUS				status;
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 
 	for (mpm = mpm_list; mpm; mpm = mpm->next) {
 		if (mpm->module->endpoint && 
@@ -68,7 +68,7 @@
 	const struct ndr_interface_table	*table;
 	NTSTATUS				status;
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 
 	for (mpm = mpm_list; mpm; mpm = mpm->next) {
 		if (mpm->module->endpoint && 
@@ -92,7 +92,7 @@
 	const struct ndr_interface_table	*table;
 	NTSTATUS				status;
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 
 	for (mpm = mpm_list; mpm; mpm = mpm->next) {
 		if (mpm->module->endpoint && 
@@ -117,7 +117,7 @@
 	const struct ndr_interface_table	*table;
 	NTSTATUS				status;
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 
 	for (mpm = mpm_list; mpm; mpm = mpm->next) {
 		if (mpm->module->endpoint && 

Modified: trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -47,7 +47,7 @@
 	const struct ndr_interface_table	*table;
 	NTSTATUS				status;
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 
 	for (server = server_list; server; server = server->next) {
 		if (server->module->endpoint && table->name &&

Modified: trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h	2009-04-14 14:43:51 UTC (rev 2699)
@@ -206,6 +206,8 @@
 enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *, void *, const char *, const char *, uint64_t *, const char **);
 enum MAPISTATUS openchangedb_lookup_folder_property(void *, uint32_t, uint64_t);
 enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *, void *, char *, uint32_t, uint64_t, void **);
+enum MAPISTATUS openchangedb_get_folder_count(void *, uint64_t, uint32_t *);
+enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *, void *, char *, char *, uint32_t, uint32_t, void **);
 
 /* definitions from auto-generated openchangedb_property.c */
 const char *openchangedb_property_get_attribute(uint32_t);

Modified: trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -48,7 +48,6 @@
 {
 	TALLOC_CTX			*mem_ctx;
 	struct ldb_result		*res = NULL;
-	char				*ldb_filter;
 	const char * const		attrs[] = { "*", NULL };
 	int				ret;
 	const char			*dn;
@@ -62,10 +61,8 @@
 	mem_ctx = talloc_named(NULL, 0, "get_SystemFolderID");
 
 	/* Step 1. Search Mailbox Root DN */
-	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
 	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
-			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient);
 
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
@@ -86,9 +83,8 @@
 	OPENCHANGE_RETVAL_IF(!ldb_dn, MAPI_E_CORRUPT_STORE, mem_ctx);
 	talloc_free(res);
 
-	ldb_filter = talloc_asprintf(mem_ctx, "(&(objectClass=systemfolder)(SystemIdx=%d))", SystemIdx);
-	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn, LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn, LDB_SCOPE_SUBTREE, attrs, 
+			 "(&(objectClass=systemfolder)(SystemIdx=%d))", SystemIdx);
 
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
@@ -117,7 +113,6 @@
 {
 	TALLOC_CTX			*mem_ctx;
 	struct ldb_result		*res = NULL;
-	char				*ldb_filter;
 	const char			*guid;
 	const char * const		attrs[] = { "*", NULL };
 	int				ret;
@@ -130,11 +125,8 @@
 	mem_ctx = talloc_named(NULL, 0, "get_MailboxGuid");
 
 	/* Step 1. Search Mailbox DN */
-	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
 	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
-			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
-
+			 LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 	
 	/* Step 2. Retrieve MailboxGUID attribute's value */
@@ -166,7 +158,6 @@
 {
 	TALLOC_CTX			*mem_ctx;
 	struct ldb_result		*res = NULL;
-	char				*ldb_filter;
 	const char			*guid;
 	const char * const		attrs[] = { "*", NULL };
 	int				ret;
@@ -180,10 +171,8 @@
 	mem_ctx = talloc_named(NULL, 0, "get_MailboxReplica");
 
 	/* Step 1. Search Mailbox DN */
-	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
 	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
-			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient);
 
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
@@ -221,16 +210,13 @@
 {
 	TALLOC_CTX		*mem_ctx;
 	struct ldb_result	*res = NULL;
-	char			*ldb_filter;
 	const char * const	attrs[] = { "*", NULL };
 	int			ret;
 
 	mem_ctx = talloc_named(NULL, 0, "get_mapistoreURI");
 
-	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagFolderId=0x%.16"PRIx64")", fid);
 	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
-			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=0x%.16"PRIx64")", fid);
 
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
@@ -268,7 +254,6 @@
 	struct ldb_dn			*dn;
 	struct ldb_message_element	*ldb_element;
 	char				*dnstr;
-	char				*ldb_filter;
 	const char * const		attrs[] = { "*", NULL };
 	int				ret;
 	int				i;
@@ -277,10 +262,8 @@
 	mem_ctx = talloc_named(NULL, 0, "get_ReceiveFolder");
 
 	/* Step 1. Search Mailbox DN */
-	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
 	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
-			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
 	dnstr = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL));
@@ -292,9 +275,8 @@
 	dn = ldb_dn_new(mem_ctx, ldb_ctx, dnstr);
 	talloc_free(dnstr);
 
-	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagMessageClass=%s*)", MessageClass);
-	ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, 
+			 "(PidTagMessageClass=%s*)", MessageClass);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 	
 	*fid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0x0);
@@ -327,6 +309,41 @@
 
 
 /**
+   \details Retrieve the number of sub folders for a given fid
+
+   \param ldb_ctx pointer to the openchange LDB context
+   \param fid the folder identifier to use for the search
+   \param RowCount pointer to the returned number of results
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_folder_count(void *ldb_ctx,
+						       uint64_t fid,
+						       uint32_t *RowCount)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct ldb_result	*res;
+	const char * const	attrs[] = { "*", NULL };
+	int			ret;
+
+	mem_ctx = talloc_named(NULL, 0, "get_folder_count");
+	*RowCount = 0;
+
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, 
+			 "(PidTagParentFolderId=0x%.16"PRIx64")(PidTagFolderId=*)", fid);
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx);
+
+	*RowCount = res->count;
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
    \details Check if a property exists within an openchange dispatcher
    database record
 
@@ -342,7 +359,6 @@
 {
 	TALLOC_CTX	       	*mem_ctx;
 	struct ldb_result      	*res = NULL;
-	char		       	*ldb_filter;
 	const char * const     	attrs[] = { "*", NULL };
 	const char	       	*PidTagAttr = NULL;
 	int		       	ret;
@@ -350,10 +366,8 @@
 	mem_ctx = talloc_named(NULL, 0, "get_folder_property");
 
 	/* Step 1. Find PidTagFolderId record */
-	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagFolderId=0x%.16"PRIx64")", fid);
 	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
-			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=0x%.16"PRIx64")", fid);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
 	/* Step 2. Convert proptag into PidTag attribute */
@@ -395,6 +409,7 @@
 	uint16_t		FolderType;
 	uint64_t		FolderId;
 	const char		*tmp;
+	uint32_t		*l;
 
 	switch (proptag) {
 	case PR_IPM_APPOINTMENT_ENTRYID:
@@ -413,6 +428,10 @@
 		retval = entryid_set_folder_EntryID(mem_ctx, &MailboxGUID, &ReplGUID, FolderType, FolderId, &bin);
 		return (void *)bin;
 		break;
+	case PR_DEPTH:
+		l = talloc_zero(mem_ctx, uint32_t);
+		*l = 0;
+		return (void *)l;
 	}
 
 	return NULL;
@@ -420,6 +439,60 @@
 
 
 /**
+   \details Retrieve a MAPI property from a OpenChange LDB message
+
+   \param mem_ctx pointer to the memory context
+   \param res pointer to the LDB results
+   \param pos the LDB result index
+   \param proptag the MAPI property tag to lookup
+   \param PidTagAttr the mapped MAPI property name
+
+   \return valid data pointer on success, otherwise NULL
+ */
+static void *openchangedb_get_folder_property_data(TALLOC_CTX *mem_ctx,
+						   struct ldb_result *res,
+						   uint32_t pos,
+						   uint32_t proptag,
+						   const char *PidTagAttr)
+{
+	void			*data;
+	const char     		*str;
+	uint64_t		*d;
+	uint32_t		*l;
+	int			*b;
+
+	switch (proptag & 0xFFFF) {
+	case PT_BOOLEAN:
+		b = talloc_zero(mem_ctx, int);
+		*b = ldb_msg_find_attr_as_bool(res->msgs[pos], PidTagAttr, 0x0);
+		data = (void *)b;
+		break;
+	case PT_LONG:
+		l = talloc_zero(mem_ctx, uint32_t);
+		*l = ldb_msg_find_attr_as_int(res->msgs[pos], PidTagAttr, 0x0);
+		data = (void *)l;
+		break;
+	case PT_I8:
+		str = ldb_msg_find_attr_as_string(res->msgs[pos], PidTagAttr, 0x0);
+		d = talloc_zero(mem_ctx, uint64_t);
+		*d = strtoull(str, NULL, 16);
+		data = (void *)d;
+		break;
+	case PT_STRING8:
+	case PT_UNICODE:
+		str = ldb_msg_find_attr_as_string(res->msgs[pos], PidTagAttr, NULL);
+		data = (char *) talloc_strdup(mem_ctx, str);
+		break;
+	default:
+		talloc_free(mem_ctx);
+		DEBUG(0, ("[%s:%d] Property Type 0x%.4x not supported\n", __FUNCTION__, __LINE__, (proptag & 0xFFFF)));
+		return NULL;
+	}
+
+	return data;
+}
+
+/**
    \details Retrieve a MAPI property value from a folder record
 
    \param parent_ctx pointer to the memory context
@@ -440,22 +513,15 @@
 {
 	TALLOC_CTX		*mem_ctx;
 	struct ldb_result	*res = NULL;
-	char			*ldb_filter;
 	const char * const	attrs[] = { "*", NULL };
 	const char		*PidTagAttr = NULL;
 	int			ret;
-	const char     		*str;
-	uint64_t		*d;
-	uint32_t		l;
-	int			*b;
 
 	mem_ctx = talloc_named(NULL, 0, "get_folder_property");
 
 	/* Step 1. Find PidTagFolderId record */
-	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagFolderId=0x%.16"PRIx64")", fid);
 	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
-			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=0x%.16"PRIx64")", fid);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
 
 	/* Step 2. Convert proptag into PidTag attribute */
@@ -470,34 +536,67 @@
 	OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx);
 
 	/* Step 5. If this is not a "special property" */
-	switch (proptag & 0xFFFF) {
-	case PT_BOOLEAN:
-		b = talloc_zero(parent_ctx, int);
-		*b = ldb_msg_find_attr_as_bool(res->msgs[0], PidTagAttr, 0x0);
-		*data = (void *)b;
-		break;
-	case PT_LONG:
-		l = ldb_msg_find_attr_as_int(res->msgs[0], PidTagAttr, 0x0);
-		*data = (void *)&l;
-		break;
-	case PT_I8:
-		str = ldb_msg_find_attr_as_string(res->msgs[0], PidTagAttr, 0x0);
-		d = talloc_zero(parent_ctx, uint64_t);
-		*d = strtoull(str, NULL, 16);
-		*data = (void *)d;
-		break;
-	case PT_STRING8:
-	case PT_UNICODE:
-		str = ldb_msg_find_attr_as_string(res->msgs[0], PidTagAttr, NULL);
-		*data = (char *) talloc_strdup(parent_ctx, str);
-		break;
-	default:
-		talloc_free(mem_ctx);
-		DEBUG(0, ("[%s:%d] Property Type 0x%.4x not supported\n", __FUNCTION__, __LINE__, (proptag & 0xFFFF)));
-		return MAPI_E_NOT_FOUND;
-	}
+	*data = openchangedb_get_folder_property_data(parent_ctx, res, 0, proptag, PidTagAttr);
+	OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx);
 
 	talloc_free(mem_ctx);
 
-	return MAPI_E_SUCCESS;
+	return MAPI_E_NOT_FOUND;
 }
+
+
+/**
+   \details Retrieve a MAPI property from a table (ldb search results)
+
+   \param parent_ctx pointer to the memory context
+   \param ldb_ctx pointer to the openchange LDB context
+   \param ldb_filter the ldb search string
+   \param proptag the MAPI property tag to retrieve value for
+   \param pos the record position in search results
+   \param data pointer on pointer to the data the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *parent_ctx,
+							 void *ldb_ctx,
+							 char *recipient,
+							 char *ldb_filter,
+							 uint32_t proptag,
+							 uint32_t pos,
+							 void **data)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct ldb_result	*res = NULL;
+	const char * const	attrs[] = { "*", NULL };
+	const char		*PidTagAttr = NULL;
+	int			ret;
+
+	mem_ctx = talloc_named(NULL, 0, "get_table_property");
+
+	/* Step 1. Fetch table results */
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_INVALID_OBJECT, mem_ctx);
+
+	/* Step 2. Ensure position is within search results range */
+	OPENCHANGE_RETVAL_IF(pos >= res->count, MAPI_E_INVALID_OBJECT, NULL);
+
+	/* Step 3. Convert proptag into PidTag attribute */
+	PidTagAttr = openchangedb_property_get_attribute(proptag);
+	OPENCHANGE_RETVAL_IF(!PidTagAttr, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 4. Ensure the element exists */
+	OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[pos], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 5. Check if this is a "special property" */
+	*data = openchangedb_get_folder_special_property(parent_ctx, ldb_ctx, recipient, res, proptag, PidTagAttr);
+	OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx);
+
+	/* Step 6. Check if this is not a "special property" */
+	*data = openchangedb_get_folder_property_data(parent_ctx, res, pos, proptag, PidTagAttr);
+	OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_NOT_FOUND;
+}

Modified: trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h	2009-04-14 14:43:51 UTC (rev 2699)
@@ -60,18 +60,101 @@
 #define	SIZE_DFLT_ROPOPENFOLDER			2
 
 /**
+   \details GetHierarchyTableTop has fixed response size for:
+   -# RowCount: uint32_t
+ */
+#define	SIZE_DFLT_ROPGETHIERARCHYTABLE		4
+
+/**
+   \details GetContentsTableRop has fixed response size for:
+   -# RowCount: uint32_t
+ */
+#define	SIZE_DFLT_ROPGETCONTENTSTABLE		4
+
+/**
+   \details CreateMessageRop has fixed response size for:
+   -# HasMessageId: uint8_t
+ */
+#define	SIZE_DFLT_ROPCREATEMESSAGE		1
+
+/**
    \details GetPropertiesSpecificRop has fixed response size for:
    -# layout: uint8_t
  */
 #define	SIZE_DFLT_ROPGETPROPERTIESSPECIFIC	1
 
 /**
+   \details: SetPropertiesRop has fixed response size for:
+   -# PropertyProblemCount: uint16_t
+ */
+#define	SIZE_DFLT_ROPSETPROPERTIES		2
+
+/**
+   \details: SaveChangesMessageRop has fixed response size for:
+   -# handle_idx: uint8_t
+   -# MessageId: uint64_t
+ */
+#define	SIZE_DFLT_ROPSAVECHANGESMESSAGE		9
+
+/**
+   \details SetColumnsRop has fixed response size for:
+   -# TableStatus: uint8_t
+ */
+#define	SIZE_DFLT_ROPSETCOLUMNS			1
+
+/**
+   \details SortTableRop has fixed response size for:
+   -# TableStatus: uint8_t
+ */
+#define	SIZE_DFLT_ROPSORTTABLE			1
+
+/**
+   \details RestrictRop has fixed response size for:
+   -# TableStatus: uint8_t
+ */
+#define	SIZE_DFLT_ROPRESTRICT			1
+
+/**
+   \details QueryRowsRop has fixed size for:
+   -# Origin: uint8_t
+   -# RowCount: uint16_t
+ */
+#define	SIZE_DFLT_ROPQUERYROWS			3
+
+/**
+   \details QueryPositionRop has fixed response size for:
+   -# Numerator: uint32_t
+   -# Denominator: uint32_t
+ */
+#define	SIZE_DFLT_ROPQUERYPOSITION		8
+
+/**
+   \details SeekRowRop has fixed response size for:
+   -# HasSought: uint8_t
+   -# RowsSought: uint32_t
+ */
+#define	SIZE_DFLT_ROPSEEKROW			5
+
+/**
    \details GetReceiveFolder has fixed response size for:
    -# folder_id: uint64_t
  */
 #define	SIZE_DFLT_ROPGETRECEIVEFOLDER		8
 
 /**
+   \details FindRow has fixed response size for:
+   -# RowNoLongerVisible: uint8_t
+   -# HasRowData: uint8_t
+ */
+#define	SIZE_DFLT_ROPFINDROW			2
+
+/**
+   \details GetPropertyIdsFromNames has fixed response size for:
+   -# count: uint16_t
+ */
+#define	SIZE_DFLT_ROPGETPROPERTYIDSFROMNAMES	2
+
+/**
    \details LogonRop has a fixed size for mailbox:
    -# LogonFlags: uint8_t
    -# FolderIDs: uint64_t * 13
@@ -85,25 +168,52 @@
  */
 #define	SIZE_DFLT_ROPLOGON_MAILBOX	160
 
+/**
+   \details LogonRop has a fixed size for redirect response:
+   -# LogonFlags: uint8_t
+   -# ServerNameSize: uint8_t
+ */
+#define	SIZE_DFLT_ROPLOGON_REDIRECT	2
+
 #define	SIZE_NULL_TRANSACTION		2
 
 __BEGIN_DECLS
 
 /* definitions from libmapiserver_oxcfold.c */
 uint16_t libmapiserver_RopOpenFolder_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopGetHierarchyTable_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopGetContentsTable_size(struct EcDoRpc_MAPI_REPL *);
 
+/* definitions from libmapiserver_oxcmsg.c */
+uint16_t libmapiserver_RopCreateMessage_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopSaveChangesMessage_size(struct EcDoRpc_MAPI_REPL *);
+
 /* definitions from libmapiserver_oxcnotif.c */
 uint16_t libmapiserver_RopRegisterNotification_size(void);
 
 /* definitions from libmapiserver_oxcprpt.c */
+uint16_t libmapiserver_RopSetProperties_size(struct EcDoRpc_MAPI_REPL *);
 uint16_t libmapiserver_RopGetPropertiesSpecific_size(struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *);
-int libmapiserver_push_property(TALLOC_CTX *, struct smb_iconv_convenience *, uint32_t, const void *, DATA_BLOB *, uint8_t);
+uint16_t libmapiserver_RopGetPropertyIdsFromNames_size(struct EcDoRpc_MAPI_REPL *);
+int libmapiserver_push_property(TALLOC_CTX *, struct smb_iconv_convenience *, uint32_t, const void *, DATA_BLOB *, uint8_t, uint8_t);
 
 /* definitions from libmapiserver_oxcstor.c */
 uint16_t libmapiserver_RopLogon_size(struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *);
 uint16_t libmapiserver_RopRelease_size(void);
 uint16_t libmapiserver_RopGetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *);
 
+/* definitions from libmapiserver_oxctabl.c */
+uint16_t libmapiserver_RopSetColumns_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopSortTable_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopRestrict_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopQueryRows_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopQueryPosition_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopSeekRow_size(struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopFindRow_size(struct EcDoRpc_MAPI_REPL *);
+
+/* definitions from libmapiserver_oxorule.c */
+uint16_t libmapiserver_RopGetRulesTable_size(void);
+
 __END_DECLS
 
 #endif /* ! __LIBMAPISERVER_H__ */

Modified: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -39,7 +39,7 @@
 {
 	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
 
-	if (!response) {
+	if (!response || response->error_code) {
 		return size;
 	}
 
@@ -48,3 +48,47 @@
 	/* No ghosted folder for the moment */
 	return size;
 }
+
+
+/**
+   \details Calculate GetHierarchyTable Rop size
+
+   \param response pointer to the GetHierarchyTable EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of GetHierarchyTable response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopGetHierarchyTable_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPGETHIERARCHYTABLE;
+
+	return size;
+}
+
+
+/**
+   \details Calculate GetContentsTable Rop size
+
+   \param response pointer to the GetContentsTable EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of GetContentsTable response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopGetContentsTable_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPGETCONTENTSTABLE;
+	
+	return size;
+}

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcmsg.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcmsg.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcmsg.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -0,0 +1,80 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+   \file libmapiserver_oxcmsg.c
+
+   \brief OXCMSG Rops
+ */
+
+#include "libmapiserver.h"
+#include <util/debug.h>
+
+/**
+   \details Calculate CreateMessage Rop size
+
+   \param response pointer to the CreateMessage EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of CreateMessage response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopCreateMessage_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPCREATEMESSAGE;
+
+	if (response->u.mapi_CreateMessage.HasMessageId == 1) {
+		size += sizeof (uint64_t);
+	}
+
+	DEBUG(0, ("CreateMessage: %d\n", size));
+
+	return size;
+}
+
+
+/**
+   \details Calculate SaveChangesMessage Rop size
+
+   \param response pointer to the SaveChangesMessage EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of SaveChangesMessage response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopSaveChangesMessage_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPSAVECHANGESMESSAGE;
+
+	DEBUG(0, ("SaveChangesMessage: %d\n", size));
+
+	return size;
+}

Modified: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -29,13 +29,13 @@
 #include <libmapi/mapidefs.h>
 #include <gen_ndr/ndr_exchange.h>
 
-#include <util/debug.h>
-
 /**
    \details Calculate GetPropertiesSpecific Rop size
 
-   \param request pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REQ structure
-   \param response pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REPL structure
+   \param request pointer to the GetPropertiesSpecific
+   EcDoRpc_MAPI_REQ structure
+   \param response pointer to the GetPropertiesSpecific
+   EcDoRpc_MAPI_REPL structure
 
    \return Size of GetPropsSpecific response
  */
@@ -44,7 +44,7 @@
 {
 	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
 
-	if (!response) {
+	if (!response || response->error_code) {
 		return size;
 	}
 
@@ -56,6 +56,58 @@
 
 
 /**
+   \details Calculate SetProperties Rop size
+
+   \param response pointer to the SetProperties EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of SetProperties response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopSetProperties_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPSETPROPERTIES;
+
+	if (response->u.mapi_SetProps.PropertyProblemCount) {
+		size += response->u.mapi_SetProps.PropertyProblemCount * sizeof(struct PropertyProblem);
+	}
+
+	return size;
+}
+
+
+/**
+   \details Calculate GetPropertyIdsFromNames Rop size
+
+   \param response pointer to the GetPropertyIdsFromNames
+   EcDoRpc_MAPI_REPL structure
+
+   \return Size of GetPropertyIdsFromNames response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopGetPropertyIdsFromNames_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPGETPROPERTYIDSFROMNAMES;
+
+	if (response->u.mapi_GetIDsFromNames.count) {
+		size += response->u.mapi_GetIDsFromNames.count * sizeof (uint16_t);
+	}
+
+	return size;
+}
+
+
+/**
    \details Add a property value to a DATA blob. This convenient
    function should be used when creating a GetPropertiesSpecific reply
    response blob.
@@ -67,6 +119,7 @@
    \param value generic pointer on the property value
    \param blob the data blob the function uses to return the blob
    \param layout whether values should be prefixed by a layout
+   \param flagged define if the properties are flagged or not
 
    \note blob.length must be set to 0 before this function is called
    the first time. Also the function only supports a limited set of
@@ -79,7 +132,8 @@
 					 uint32_t property, 
 					 const void *value, 
 					 DATA_BLOB *blob,
-					 uint8_t layout)
+					 uint8_t layout, 
+					 uint8_t flagged)
 {
 	struct ndr_push		*ndr;
 	
@@ -92,15 +146,34 @@
 		ndr->offset = blob->length;
 	}
 
-	/* Step 1. Set the layout */
-	if (layout) {
+	/* Step 1. Is the property flagged */
+	if (flagged) {
 		switch (property & 0xFFFF) {
 		case PT_ERROR:
-			ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR);
+			switch (layout) {
+			case 0x1:
+				ndr_push_uint8(ndr, NDR_SCALARS, layout);
+				goto end;
+			case PT_ERROR:
+				ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR);
+				break;
+			}
 			break;
 		default:
 			ndr_push_uint8(ndr, NDR_SCALARS, 0x0);
+			break;
 		}
+	} else {
+		/* Step 2. Set the layout */
+		if (layout) {
+			switch (property & 0xFFFF) {
+			case PT_ERROR:
+				ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR);
+				break;
+			default:
+				ndr_push_uint8(ndr, NDR_SCALARS, 0x0);
+			}
+		}
 	}
 
 	/* Step 2. Push property data if supported */
@@ -140,7 +213,7 @@
 	default:
 		break;
 	}
-
+end:
 	/* Step 3. Steal ndr context */
 	blob->data = ndr->data;
 	talloc_steal(mem_ctx, blob->data);

Modified: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -41,10 +41,16 @@
 {
 	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
 
-	if (!response) {
+	if (!response || (response->error_code && response->error_code != ecWrongServer)) {
 		return size;
 	}
 
+	if (response->error_code == ecWrongServer) {
+		size += SIZE_DFLT_ROPLOGON_REDIRECT;
+		size += strlen (response->us.mapi_Logon.ServerName) + 1;
+		return size;
+	}
+
 	switch (request->u.mapi_Logon.LogonFlags) {
 	case LogonPrivate:
 		size += SIZE_DFLT_ROPLOGON_MAILBOX;
@@ -57,17 +63,18 @@
 }
 
 
-_PUBLIC_ uint16_t libmapiserver_RopRelease_size(void)
-{
-	return SIZE_NULL_TRANSACTION;
-}
+/**
+   \details Calculate GetReceiveFolder Rop size
 
+   \param response pointer to the GetReceiveFolder EcDoRpc_MAPI_REPL structure
 
+   \return Size of GetReceiveFolder response
+ */
 _PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *response)
 {
 	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
 
-	if (!response || response->error_code != MAPI_E_SUCCESS) {
+	if (!response || response->error_code) {
 		return size;
 	}
 

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxctabl.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxctabl.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxctabl.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -0,0 +1,183 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+   \file libmapiserver_oxctabl.c
+
+   \brief OXCTABL Rops
+ */
+
+#include "libmapiserver.h"
+
+/**
+   \details Calculate SetColumns Rop size
+
+   \param response pointer to the SetColumns EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of SetColumns response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopSetColumns_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPSETCOLUMNS;
+
+	return size;
+}
+
+
+/**
+   \details Calculate SortTable Rop size
+
+   \param response pointer to the SortTable EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of SortTable response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopSortTable_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPSORTTABLE;
+
+	return size;
+}
+
+/**
+   \details Calculate Restrict Rop size
+
+   \param response pointer to the Restrict EcDoRpc_MAPI_REPL structure
+
+   \return Size of Restrict response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopRestrict_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPRESTRICT;
+
+	return size;
+}
+
+
+/**
+   \details Calculate QueryRows Rop size
+
+   \param response pointer to the QueryRows EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of QueryRows response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopQueryRows_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPQUERYROWS;
+	size += response->u.mapi_QueryRows.RowData.length;
+
+	return size;
+}
+
+
+/**
+   \details Calculate QueryPosition Rop size
+
+   \param response pointer to the QueryPosition EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of QueryPosition response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopQueryPosition_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPQUERYPOSITION;
+
+	return size;
+}
+
+
+/**
+   \details Calculate SeekRow Rop size
+
+   \param response pointer to the SeekRow EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of SeekRow response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopSeekRow_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPSEEKROW;
+
+	return size;
+}
+
+
+/**
+   \details Calculate FindRow Rop size
+
+   \param response pointer to the FindRow EcDoRpc_MAPI_REPL structure
+
+   \return Size of FindRow response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopFindRow_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPFINDROW;
+
+	if (response->u.mapi_FindRow.HasRowData) {
+		size += response->u.mapi_FindRow.row.length;
+	}
+
+	return size;
+}

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxorule.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxorule.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxorule.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -0,0 +1,45 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+   \file libmapiserver_oxorule.c
+
+   \brief OXORULE Rops
+ */
+
+#include "libmapiserver.h"
+#include <libmapi/mapidefs.h>
+#include <gen_ndr/ndr_exchange.h>
+
+/**
+   \details Calculate GetRulesTable Rop size
+
+   \param response pointer to the GetRulesTable EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of GetRulesTable response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopGetRulesTable_size(void)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	return size;
+}

Modified: trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -60,7 +60,17 @@
 _PUBLIC_ extern int mapistore_backend_register(const void *_backend)
 {
 	const struct mapistore_backend	*backend = _backend;
+	uint32_t			i;
 
+	for (i = 0; i < num_backends; i++) {
+		if (backends[i].backend && backend && 
+		    backend->name && backends[i].backend->name &&
+		    !strcmp(backends[i].backend->name, backend->name)) {
+			DEBUG(3, ("MAPISTORE backend '%s' already registered\n", backend->name));
+			return MAPISTORE_SUCCESS;
+		}
+	}
+
 	backends = realloc_p(backends, struct mstore_backend, num_backends + 1);
 	if (!backends) {
 		smb_panic("out of memory in mapistore_backend_register");

Modified: trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -276,10 +276,8 @@
 		talloc_free(basedn);
 		if (!dn) return NT_STATUS_UNSUCCESSFUL;
 		
-		attribute = talloc_asprintf(mem_ctx, "(0x%x=*)", stream->PropertyTag);
 		ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, 
-						 attribute);
-		talloc_free(attribute);
+				 "(0x%x=*)", stream->PropertyTag);
 
 		if (ret == LDB_SUCCESS && res->count == 1) {
 			attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag);
@@ -310,9 +308,7 @@
 		talloc_free(basedn);
 		if (!dn) return NT_STATUS_UNSUCCESSFUL;
 
-		attribute = talloc_asprintf(mem_ctx, "(0x%x=*)", stream->PropertyTag);
-		ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, attribute);
-		talloc_free(attribute);
+		ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "(0x%x=*)", stream->PropertyTag);
 
 		if (ret == LDB_SUCCESS && res->count == 1) {
 			attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag);

Modified: trunk/openchange/mapiproxy/modules/mpm_downgrade.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_downgrade.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/modules/mpm_downgrade.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -58,7 +58,7 @@
 	uint16_t				opnum;
 	const char				*name;
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 	name = table->calls[opnum].name;
 
@@ -103,7 +103,7 @@
 	const struct ndr_interface_table	*table;
 	uint16_t				opnum;
 
-	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 	
 	if ((opnum == 0xA) && (table->name && !strcmp(table->name, "exchange_emsmdb"))) {

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -238,6 +238,7 @@
 	uint32_t			handles_length;
 	uint16_t			size = 0;
 	uint32_t			i;
+	uint32_t			idx;
 
 	DEBUG(3, ("exchange_emsmdb: EcDoRpc (0x2)\n"));
 
@@ -248,6 +249,8 @@
 	}
 
 	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	OPENCHANGE_RETVAL_IF(!h, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+
 	emsmdbp_ctx = (struct emsmdbp_context *) h->data;
 
 	mapi_request = r->in.mapi_request;
@@ -261,10 +264,14 @@
 
 	/* Step 2. Process serialized MAPI requests */
 	mapi_response->mapi_repl = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REPL);
-	for (i = 0; mapi_request->mapi_req[i].opnum != 0; i++) {
-		DEBUG(0, ("MAPI Rop: 0x%.2x\n", mapi_request->mapi_req[i].opnum));
-		mapi_response->mapi_repl = talloc_realloc(mem_ctx, mapi_response->mapi_repl,
-							  struct EcDoRpc_MAPI_REPL, i + 2);
+	for (i = 0, idx = 0, size = 0; mapi_request->mapi_req[i].opnum != 0; i++) {
+		DEBUG(0, ("MAPI Rop: 0x%.2x (%d)\n", mapi_request->mapi_req[i].opnum, size));
+
+		if (mapi_request->mapi_req[i].opnum != op_MAPI_Release) {
+			mapi_response->mapi_repl = talloc_realloc(mem_ctx, mapi_response->mapi_repl,
+								  struct EcDoRpc_MAPI_REPL, idx + 2);
+		}
+
 		switch (mapi_request->mapi_req[i].opnum) {
 		case op_MAPI_Release:
 			retval = EcDoRpc_RopRelease(mem_ctx, emsmdbp_ctx, 
@@ -274,41 +281,130 @@
 		case op_MAPI_OpenFolder:
 			retval = EcDoRpc_RopOpenFolder(mem_ctx, emsmdbp_ctx,
 						       &(mapi_request->mapi_req[i]),
-						       &(mapi_response->mapi_repl[i]),
+						       &(mapi_response->mapi_repl[idx]),
 						       mapi_response->handles, &size);
 			break;
+		case op_MAPI_GetHierarchyTable:
+			retval = EcDoRpc_RopGetHierarchyTable(mem_ctx, emsmdbp_ctx,
+							      &(mapi_request->mapi_req[i]),
+							      &(mapi_response->mapi_repl[idx]),
+							      mapi_response->handles, &size);
+			break;
+		case op_MAPI_GetContentsTable:
+			retval = EcDoRpc_RopGetContentsTable(mem_ctx, emsmdbp_ctx,
+							     &(mapi_request->mapi_req[i]),
+							     &(mapi_response->mapi_repl[idx]),
+							     mapi_response->handles, &size);
+			break;
+		case op_MAPI_CreateMessage:
+			retval = EcDoRpc_RopCreateMessage(mem_ctx, emsmdbp_ctx,
+							  &(mapi_request->mapi_req[i]),
+							  &(mapi_response->mapi_repl[idx]),
+							  mapi_response->handles, &size);
+			break;
 		case op_MAPI_GetProps:
 			retval = EcDoRpc_RopGetPropertiesSpecific(mem_ctx, emsmdbp_ctx,
 								  &(mapi_request->mapi_req[i]),
-								  &(mapi_response->mapi_repl[i]),
+								  &(mapi_response->mapi_repl[idx]),
 								  mapi_response->handles, &size);
 			break;
+		case op_MAPI_SetProps:
+			retval = EcDoRpc_RopSetProperties(mem_ctx, emsmdbp_ctx,
+							  &(mapi_request->mapi_req[i]),
+							  &(mapi_response->mapi_repl[idx]),
+							  mapi_response->handles, &size);
+			break;
+		case op_MAPI_SaveChangesMessage:
+			retval = EcDoRpc_RopSaveChangesMessage(mem_ctx, emsmdbp_ctx,
+							  &(mapi_request->mapi_req[i]),
+							  &(mapi_response->mapi_repl[idx]),
+							  mapi_response->handles, &size);
+			break;
+		case op_MAPI_SetColumns:
+			retval = EcDoRpc_RopSetColumns(mem_ctx, emsmdbp_ctx,
+						       &(mapi_request->mapi_req[i]),
+						       &(mapi_response->mapi_repl[idx]),
+						       mapi_response->handles, &size);
+			break;
+		case op_MAPI_SortTable:
+			retval = EcDoRpc_RopSortTable(mem_ctx, emsmdbp_ctx,
+						      &(mapi_request->mapi_req[i]),
+						      &(mapi_response->mapi_repl[idx]),
+						      mapi_response->handles, &size);
+			break;
+		case op_MAPI_Restrict:
+			retval = EcDoRpc_RopRestrict(mem_ctx, emsmdbp_ctx,
+						     &(mapi_request->mapi_req[i]),
+						     &(mapi_response->mapi_repl[idx]),
+						     mapi_response->handles, &size);
+			break;
+		case op_MAPI_QueryRows:
+			retval = EcDoRpc_RopQueryRows(mem_ctx, emsmdbp_ctx,
+						      &(mapi_request->mapi_req[i]),
+						      &(mapi_response->mapi_repl[idx]),
+						      mapi_response->handles, &size);
+			break;
+		case op_MAPI_QueryPosition:
+			retval = EcDoRpc_RopQueryPosition(mem_ctx, emsmdbp_ctx,
+							  &(mapi_request->mapi_req[i]),
+							  &(mapi_response->mapi_repl[idx]),
+							  mapi_response->handles, &size);
+			break;
+		case op_MAPI_SeekRow:
+			retval = EcDoRpc_RopSeekRow(mem_ctx, emsmdbp_ctx,
+						    &(mapi_request->mapi_req[i]),
+						    &(mapi_response->mapi_repl[idx]),
+						    mapi_response->handles, &size);
+			break;
 		case op_MAPI_GetReceiveFolder:
 			retval = EcDoRpc_RopGetReceiveFolder(mem_ctx, emsmdbp_ctx,
 							     &(mapi_request->mapi_req[i]),
-							     &(mapi_response->mapi_repl[i]),
+							     &(mapi_response->mapi_repl[idx]),
 							     mapi_response->handles, &size);
 			break;
 		case op_MAPI_RegisterNotification:
 			retval = EcDoRpc_RopRegisterNotification(mem_ctx, emsmdbp_ctx,
 								 &(mapi_request->mapi_req[i]),
-								 &(mapi_response->mapi_repl[i]),
+								 &(mapi_response->mapi_repl[idx]),
 								 mapi_response->handles, &size);
 			break;
+		case op_MAPI_GetRulesTable:
+			retval = EcDoRpc_RopGetRulesTable(mem_ctx, emsmdbp_ctx,
+							  &(mapi_request->mapi_req[i]),
+							  &(mapi_response->mapi_repl[idx]),
+							  mapi_response->handles, &size);
+			break;
+		case op_MAPI_FindRow:
+			retval = EcDoRpc_RopFindRow(mem_ctx, emsmdbp_ctx, 
+						    &(mapi_request->mapi_req[i]),
+						    &(mapi_response->mapi_repl[idx]),
+						    mapi_response->handles, &size);
+			break;
+		case op_MAPI_GetIDsFromNames:
+			retval = EcDoRpc_RopGetPropertyIdsFromNames(mem_ctx, emsmdbp_ctx,
+								    &(mapi_request->mapi_req[i]),
+								    &(mapi_response->mapi_repl[idx]),
+								    mapi_response->handles, &size);
+			break;
 		case op_MAPI_Logon:
 			retval = EcDoRpc_RopLogon(mem_ctx, emsmdbp_ctx,
 						  &(mapi_request->mapi_req[i]),
-						  &(mapi_response->mapi_repl[i]),
+						  &(mapi_response->mapi_repl[idx]),
 						  mapi_response->handles, &size);
 			break;
 		default:
 			DEBUG(1, ("MAPI Rop: 0x%.2x not implemented!\n",
 				  mapi_request->mapi_req[i].opnum));
 		}
+
+		if (mapi_request->mapi_req[i].opnum != op_MAPI_Release) {
+			idx++;
+		}
+
 	}
 
 	/* Step 3. Notifications/Pending calls should be processed here */
-	mapi_response->mapi_repl[i].opnum = 0;
+	mapi_response->mapi_repl[idx].opnum = 0;
 
 	/* Step 4. Fill mapi_response structure */
 	handles_length = mapi_request->mapi_len - mapi_request->length;
@@ -493,7 +589,7 @@
 	const struct ndr_interface_table	*table;
 	uint16_t				opnum;
 
-	table = (const struct ndr_interface_table *) dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *) dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 
 	/* Sanity checks */

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h	2009-04-14 14:43:51 UTC (rev 2699)
@@ -69,6 +69,7 @@
 };
 
 struct emsmdbp_object_mailbox {
+	uint64_t			folderID;
 	char				*owner_Name;
 	char				*owner_EssDN;
 	char				*szUserDN;
@@ -82,9 +83,20 @@
 	uint32_t			contextID;
 };
 
+
+struct emsmdbp_object_table {
+	uint64_t			folderID;
+	bool				IsSystemTable;
+	uint16_t			prop_count;
+	uint32_t			*properties;
+	uint32_t			numerator;
+	uint32_t			denominator;
+};
+
 union emsmdbp_objects {
 	struct emsmdbp_object_mailbox	*mailbox;
 	struct emsmdbp_object_folder	*folder;
+	struct emsmdbp_object_table	*table;
 };
 
 struct emsmdbp_object {
@@ -128,21 +140,42 @@
 struct emsmdbp_object *emsmdbp_object_init(TALLOC_CTX *, struct emsmdbp_context *);
 struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *);
 struct emsmdbp_object *emsmdbp_object_folder_init(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct mapi_handles *);
+struct emsmdbp_object *emsmdbp_object_table_init(TALLOC_CTX *, struct emsmdbp_context *, struct mapi_handles *);
 
 /* definitions from oxcfold.c */
 enum MAPISTATUS EcDoRpc_RopOpenFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopGetHierarchyTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopGetContentsTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
 
+/* definitions from oxcmsg.c */
+enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopSaveChangesMessage(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+
 /* definitions from oxcnotif.c */
 enum MAPISTATUS EcDoRpc_RopRegisterNotification(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
 
 /* definitions from oxcprpt.c */
 enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopSetProperties(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopGetPropertyIdsFromNames(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
 
 /* definitions from oxcstor.c */
 enum MAPISTATUS	EcDoRpc_RopLogon(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
 enum MAPISTATUS	EcDoRpc_RopRelease(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, uint32_t *, uint16_t *);
 enum MAPISTATUS	EcDoRpc_RopGetReceiveFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
 
+/* definition from oxctabl.c */
+enum MAPISTATUS EcDoRpc_RopSetColumns(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopSortTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopRestrict(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopQueryRows(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopQueryPosition(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopSeekRow(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS EcDoRpc_RopFindRow(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+
+/* definitions from oxorule.c */
+enum MAPISTATUS EcDoRpc_RopGetRulesTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+
 __END_DECLS
 
 #endif	/* __DCESRV_EXCHANGE_EMSMDB_H */

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -209,16 +209,13 @@
 	const char		*username = NULL;
 	int			msExchUserAccountControl;
 	struct ldb_result	*res = NULL;
-	char			*ldb_filter;
 	const char * const	recipient_attrs[] = { "msExchUserAccountControl", NULL };
 
 	username = dce_call->context->conn->auth_state.session_info->server_info->account_name;
 
-	ldb_filter = talloc_asprintf(emsmdbp_ctx, "CN=%s", username);
 	ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx, &res,
 			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
-			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, recipient_attrs, "CN=%s", username);
 
 	/* If the search failed */
 	if (ret != LDB_SUCCESS || !res->count) {
@@ -262,17 +259,15 @@
 	int			ret;
 	int			msExchUserAccountControl;
 	struct ldb_result	*res = NULL;
-	char			*ldb_filter;
 	const char * const	recipient_attrs[] = { "*", NULL };
 
 	/* Sanity Checks */
 	if (!legacyExchangeDN) return false;
 
-	ldb_filter = talloc_asprintf(emsmdbp_ctx, "(legacyExchangeDN=%s)", legacyExchangeDN);
 	ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx, &res,
 			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
-			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)",
+			 legacyExchangeDN);
 
 	/* If the search failed */
 	if (ret != LDB_SUCCESS || !res->count) {

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -122,7 +122,6 @@
 {
 	struct emsmdbp_object		*object;
 	const char			*displayName;
-	char				*ldb_filter;
 	const char * const		recipient_attrs[] = { "*", NULL };
 	int				ret;
 	struct ldb_result		*res = NULL;
@@ -145,20 +144,24 @@
 	object->object.mailbox->owner_Name = NULL;
 	object->object.mailbox->owner_EssDN = NULL;
 	object->object.mailbox->szUserDN = NULL;
+	object->object.mailbox->folderID = 0x0;
 
 	object->object.mailbox->owner_EssDN = talloc_strdup(object->object.mailbox, request->u.mapi_Logon.EssDN);
 	object->object.mailbox->szUserDN = talloc_strdup(object->object.mailbox, emsmdbp_ctx->szUserDN);
 
-	ldb_filter = talloc_asprintf(mem_ctx, "(legacyExchangeDN=%s)", object->object.mailbox->owner_EssDN);
 	ret = ldb_search(emsmdbp_ctx->users_ctx, mem_ctx, &res,
 			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
-			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, recipient_attrs, "legacyExchangeDN=%s", 
+			 object->object.mailbox->owner_EssDN);
 
 	if (res->count == 1) {
 		displayName = ldb_msg_find_attr_as_string(res->msgs[0], "displayName", NULL);
 		if (displayName) {
 			object->object.mailbox->owner_Name = talloc_strdup(object->object.mailbox, displayName);
+
+			/* Retrieve Mailbox folder identifier */
+			openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_Name,
+							0x1, &object->object.mailbox->folderID);
 		}
 	}
 
@@ -234,3 +237,56 @@
 
 	return object;
 }
+
+
+/**
+   \details Initialize a table object
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param parent pointer to the parent MAPI handle
+
+   \return Allocated emsmdbp object on success, otherwise NULL
+ */
+_PUBLIC_ struct emsmdbp_object *emsmdbp_object_table_init(TALLOC_CTX *mem_ctx,
+							  struct emsmdbp_context *emsmdbp_ctx,
+							  struct mapi_handles *parent)
+{
+	enum MAPISTATUS		retval;
+	struct emsmdbp_object	*object;
+	struct emsmdbp_object	*folder;
+	void			*data = NULL;
+	int			mailboxfolder;
+
+	/* Sanity checks */
+	if (!emsmdbp_ctx) return NULL;
+
+	/* Retrieve parent object */
+	retval = mapi_handles_get_private_data(parent, &data);
+	if (retval) return NULL;
+	folder = (struct emsmdbp_object *) data;
+
+	/* Initialize table object */
+	object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx);
+	if (!object) return NULL;
+	
+	object->object.table = talloc_zero(object, struct emsmdbp_object_table);
+	if (!object->object.table) {
+		talloc_free(object);
+		return NULL;
+	}
+
+	object->type = EMSMDBP_OBJECT_TABLE;
+	object->object.table->folderID = folder->object.folder->folderID;
+	object->object.table->prop_count = 0;
+	object->object.table->properties = NULL;
+	object->object.table->numerator = 0;
+	object->object.table->denominator = 0;
+
+	retval = mapi_handles_get_systemfolder(parent, &mailboxfolder);
+	object->object.table->IsSystemTable = (!mailboxfolder) ? true : false;
+
+	/* FIXME: missing mapistore folders support */
+
+	return object;
+}

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcfold.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcfold.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcfold.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -123,9 +123,10 @@
 		retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
 
 		object = emsmdbp_object_folder_init((TALLOC_CTX *)rec, emsmdbp_ctx, mapi_req, parent);
-		retval = mapi_handles_set_systemfolder(rec, object->object.folder->systemfolder);
-		retval = mapi_handles_set_private_data(rec, object);
-
+		if (object) {
+			retval = mapi_handles_set_systemfolder(rec, object->object.folder->systemfolder);
+			retval = mapi_handles_set_private_data(rec, object);
+		}
 		mapi_repl->opnum = mapi_req->opnum;
 		mapi_repl->handle_idx = mapi_req->u.mapi_OpenFolder.handle_idx;
 
@@ -134,3 +135,152 @@
 
 	return MAPI_E_SUCCESS;
 }
+
+
+/**
+   \details EcDoRpc GetHierarchyTable (0x04) Rop. This operation gets
+   the subfolder hierarchy table for a folder.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the GetHierarchyTable EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the GetHierarchyTable EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetHierarchyTable(TALLOC_CTX *mem_ctx,
+						      struct emsmdbp_context *emsmdbp_ctx,
+						      struct EcDoRpc_MAPI_REQ *mapi_req,
+						      struct EcDoRpc_MAPI_REPL *mapi_repl,
+						      uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_handles	*parent;
+	struct mapi_handles	*rec = NULL;
+	struct emsmdbp_object	*object = NULL;
+	void			*data;
+	uint32_t		folderID;
+	uint32_t		handle;
+	int			parentfolder = -1;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCFOLD] GetHierarchyTable (0x04)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	retval = mapi_handles_get_systemfolder(parent, &parentfolder);
+
+	/* Initialize default empty GetHierarchyTable reply */
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->u.mapi_GetHierarchyTable.handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+
+	/* GetHierarchyTable can only be called for mailbox/folder objects */
+	mapi_handles_get_private_data(parent, &data);
+	object = (struct emsmdbp_object *)data;
+	if (!object) {
+		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
+		return MAPI_E_SUCCESS;
+	}
+
+	switch (object->type) {
+	case EMSMDBP_OBJECT_MAILBOX:
+		folderID = object->object.mailbox->folderID;
+		break;
+	case EMSMDBP_OBJECT_FOLDER:
+		folderID = object->object.folder->folderID;
+		break;
+	default:
+		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
+		return MAPI_E_SUCCESS;
+	}
+
+	switch (parentfolder) {
+	case 0x0:
+	case 0x1:
+		/* system/special folder */
+		retval = openchangedb_get_folder_count(emsmdbp_ctx->oc_ctx, folderID, 
+						       &mapi_repl->u.mapi_GetHierarchyTable.RowCount);
+		break;
+	default:
+		/* handled by mapistore */
+		mapi_repl->u.mapi_GetHierarchyTable.RowCount = 0;
+		break;
+	}
+
+	/* Initialize Table object */
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
+	handles[mapi_repl->handle_idx] = rec->handle;
+
+	object = emsmdbp_object_table_init((TALLOC_CTX *)rec, emsmdbp_ctx, parent);
+	if (object) {
+		retval = mapi_handles_set_private_data(rec, object);
+		object->object.table->denominator = mapi_repl->u.mapi_GetHierarchyTable.RowCount;
+	}
+
+	*size += libmapiserver_RopGetHierarchyTable_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc GetContentsTable (0x05) Rop. This operation get
+   the content table of a container.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the GetContentsTable EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the GetContentsTable EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetContentsTable(TALLOC_CTX *mem_ctx,
+						     struct emsmdbp_context *emsmdbp_ctx,
+						     struct EcDoRpc_MAPI_REQ *mapi_req,
+						     struct EcDoRpc_MAPI_REPL *mapi_repl,
+						     uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_handles	*rec = NULL;
+	uint32_t		handle;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCFOLD] GetContentsTable (0x05)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->u.mapi_GetContentsTable.handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->u.mapi_GetContentsTable.RowCount = 0;
+
+	*size += libmapiserver_RopGetContentsTable_size(mapi_repl);
+
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
+	handles[mapi_repl->handle_idx] = rec->handle;
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcmsg.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcmsg.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcmsg.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -0,0 +1,125 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+   \file oxcmsg.c
+
+   \brief Message and Attachment object routines and Rops
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/libmapiserver/libmapiserver.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+
+/**
+   \details EcDoRpc CreateMessage (0x06) Rop. This operation creates a
+   message object in the mailbox.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the CreateMessage EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the CreateMessage EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *mem_ctx,
+						  struct emsmdbp_context *emsmdbp_ctx,
+						  struct EcDoRpc_MAPI_REQ *mapi_req,
+						  struct EcDoRpc_MAPI_REPL *mapi_repl,
+						  uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS			retval;
+	struct mapi_handles		*rec = NULL;
+	uint32_t			handle;
+	
+	DEBUG(4, ("exchange_emsmdb: [OXCMSG] CreateMessage (0x06)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->handle_idx = mapi_req->u.mapi_CreateMessage.handle_idx;
+
+	mapi_repl->u.mapi_CreateMessage.HasMessageId = 0;
+
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
+	handles[mapi_repl->handle_idx] = rec->handle;
+
+	*size += libmapiserver_RopCreateMessage_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc SaveChangesMessage (0x0c) Rop. This operation
+   operation commits the changes made to a message.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the SaveChangesMessage EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the SaveChangesMessage
+   EcDoRpc_MAPI_REPL structure
+
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesMessage(TALLOC_CTX *mem_ctx,
+						       struct emsmdbp_context *emsmdbp_ctx,
+						       struct EcDoRpc_MAPI_REQ *mapi_req,
+						       struct EcDoRpc_MAPI_REPL *mapi_repl,
+						       uint32_t *handles, uint16_t *size)
+{
+	DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesMessage (0x0c)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	
+	mapi_repl->u.mapi_SaveChangesMessage.handle_idx = mapi_req->u.mapi_SaveChangesMessage.handle_idx;
+	mapi_repl->u.mapi_SaveChangesMessage.MessageId = 0;
+
+	*size += libmapiserver_RopSaveChangesMessage_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -73,8 +73,13 @@
 
 	handle = handles[mapi_req->handle_idx];
 	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
+	if (retval) {
+		mapi_repl->error_code = retval;
+		goto end;
+	}
 	handles[mapi_repl->handle_idx] = rec->handle;
 
+end:
 	*size += libmapiserver_RopRegisterNotification_size();
 
 	return MAPI_E_SUCCESS;

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -30,7 +30,44 @@
 #include "mapiproxy/libmapiserver/libmapiserver.h"
 #include "dcesrv_exchange_emsmdb.h"
 
+/**
+   \details Retrieve properties on a mapistore object
+   
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request GetProps request
+   \param response pointer to the GetProps reply
+   \param private_data pointer tot eh private data stored for this
+   object
 
+   \note We do not handle anything yet. This is just a skeleton.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+static enum MAPISTATUS RopGetPropertiesSpecific_mapistore(TALLOC_CTX *mem_ctx,
+							  struct emsmdbp_context *emsmdbp_ctx,
+							  struct GetProps_req request,
+							  struct GetProps_repl *response,
+							  void *private_data)
+{
+	enum MAPISTATUS	retval;
+	void		*data;
+	int		i;
+
+	response->layout = 0x1;
+	for (i = 0; i < request.prop_count; i++) {
+		request.properties[i] = (request.properties[i] & 0xFFFF0000) + PT_ERROR;
+		retval = MAPI_E_NOT_FOUND;
+		data = (void *)&retval;
+		libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+					    request.properties[i], (const void *)data,
+					    &response->prop_data, response->layout, 0);
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
 /**
    \details Retrieve properties on a mailbox object.
 
@@ -53,6 +90,7 @@
 {
 	enum MAPISTATUS			retval;
 	struct emsmdbp_object		*object;
+	void				*data;
 	struct SBinary_short		bin;
 	uint32_t			i;
 	uint32_t			error = 0;
@@ -84,34 +122,39 @@
 			request.properties[i] = (request.properties[i] & 0xFFFF0000) + PT_ERROR;
 			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
 						    request.properties[i], (const void *)&error, 
-						    &response->prop_data, response->layout);
+						    &response->prop_data, response->layout, 0);
 			break;
 		case PR_USER_ENTRYID:
 			retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->szUserDN, &bin);
 			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
 						    request.properties[i], (const void *)&bin,
-						    &response->prop_data, response->layout);
+						    &response->prop_data, response->layout, 0);
 			talloc_free(bin.lpb);
 			break;
 		case PR_MAILBOX_OWNER_ENTRYID:
 			retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->owner_EssDN, &bin);
 			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
 						    request.properties[i], (const void *)&bin,
-						    &response->prop_data, response->layout);
+						    &response->prop_data, response->layout, 0);
 			talloc_free(bin.lpb);
 			break;
 		case PR_MAILBOX_OWNER_NAME:
 		case PR_MAILBOX_OWNER_NAME_UNICODE:
 			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
 						    request.properties[i], (const void *)object->object.mailbox->owner_Name,
-						    &response->prop_data, response->layout);
+						    &response->prop_data, response->layout, 0);
 			break;
 		default:
-			error = MAPI_E_NOT_FOUND;
-			request.properties[i] = (request.properties[i] & 0xFFFF0000) + PT_ERROR;
+			retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx,
+								  emsmdbp_ctx->szDisplayName, request.properties[i],
+								  object->object.mailbox->folderID, (void **)&data);
+			if (retval) {
+				request.properties[i] = (request.properties[i] & 0xFFFF0000) + PT_ERROR;
+				data = (void *)&retval;
+			}
 			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
-						    request.properties[i], (const void *)&error, 
-						    &response->prop_data, response->layout);
+						    request.properties[i], (const void *)data, 
+						    &response->prop_data, response->layout, 0);
 			break;
 		}
 	}
@@ -170,7 +213,7 @@
 		}
 		libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
 					    request.properties[i], (const void *)data,
-					    &response->prop_data, response->layout);
+					    &response->prop_data, response->layout, 0);
 	}
 
 	return MAPI_E_SUCCESS;
@@ -222,9 +265,14 @@
 	response.prop_data.length = 0;
 	response.prop_data.data = NULL;
 
+	/* Fill EcDoRpc_MAPI_REPL reply */
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_NOT_FOUND;
+
 	handle = handles[mapi_req->handle_idx];
 	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
-	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+	if (retval) goto end;
 
 	retval = mapi_handles_get_systemfolder(rec, &systemfolder);
 	retval = mapi_handles_get_private_data(rec, &private_data);
@@ -233,7 +281,8 @@
 
 	switch (systemfolder) {
 	case -1:
-		/* handled by mapistore */
+		/* folder and messages handled by mapistore */
+		retval = RopGetPropertiesSpecific_mapistore(mem_ctx, emsmdbp_ctx, request, &response, private_data);
 		break;
 	case 0x0:
 		/* private mailbox */
@@ -245,13 +294,97 @@
 		break;
 	}
 
-	/* Fill EcDoRpc_MAPI_REPL reply */
-	mapi_repl->opnum = mapi_req->opnum;
-	mapi_repl->handle_idx = mapi_req->handle_idx;
 	mapi_repl->error_code = MAPI_E_SUCCESS;
 	mapi_repl->u.mapi_GetProps = response;
 
+ end:
 	*size += libmapiserver_RopGetPropertiesSpecific_size(mapi_req, mapi_repl);
 
 	return MAPI_E_SUCCESS;
 }
+
+
+/**
+   \details EcDoRpc SetProperties (0x0a) Rop. This operation sets
+   property values for an object.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the SetProperties EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the SetProperties EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetProperties(TALLOC_CTX *mem_ctx,
+						  struct emsmdbp_context *emsmdbp_ctx,
+						  struct EcDoRpc_MAPI_REQ *mapi_req,
+						  struct EcDoRpc_MAPI_REPL *mapi_repl,
+						  uint32_t *handles, uint16_t *size)
+{
+	DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SetProperties (0x0a)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	
+	mapi_repl->u.mapi_SetProps.PropertyProblemCount = 0;
+	mapi_repl->u.mapi_SetProps.PropertyProblem = NULL;
+
+	*size += libmapiserver_RopSetProperties_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc GetPropertyIdsFromNames (0x56) Rop. This operation
+   gets property IDs for specified property names.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the GetPropertyIdsFromNames
+   EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the GetPropertyIdsFromNames
+   EcDoRpc_MAPI_REPL structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+*/
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertyIdsFromNames(TALLOC_CTX *mem_ctx,
+							    struct emsmdbp_context *emsmdbp_ctx,
+							    struct EcDoRpc_MAPI_REQ *mapi_req,
+							    struct EcDoRpc_MAPI_REPL *mapi_repl,
+							    uint32_t *handles, uint16_t *size)
+{
+	DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertyIdsFromNames (0x56)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+
+	mapi_repl->u.mapi_GetIDsFromNames.count = 0;
+	mapi_repl->u.mapi_GetIDsFromNames.propID = NULL;
+
+	*size += libmapiserver_RopGetPropertyIdsFromNames_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -71,7 +71,7 @@
 	/* Step 1. Check if mailbox pointed by recipient belongs to the Exchange organisation */
 
 	/* Step 2. Set LogonFlags */
-	response.LogonFlags = request.LogonFlags & LogonPrivate;
+	response.LogonFlags = request.LogonFlags;
 
 	/* Step 3. Build FolderIds list */
 	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_MAILBOX_ROOT, &response.LogonType.store_mailbox.FolderIds[0]);
@@ -143,11 +143,12 @@
  */
 _PUBLIC_ enum MAPISTATUS EcDoRpc_RopLogon(TALLOC_CTX *mem_ctx,
 					  struct emsmdbp_context *emsmdbp_ctx,
-					  struct EcDoRpc_MAPI_REQ *request,
-					  struct EcDoRpc_MAPI_REPL *response,
+					  struct EcDoRpc_MAPI_REQ *mapi_req,
+					  struct EcDoRpc_MAPI_REPL *mapi_repl,
 					  uint32_t *handles, uint16_t *size)
 {
 	enum MAPISTATUS			retval;
+	struct Logon_req		request;
 	struct mapi_handles		*rec = NULL;
 	struct emsmdbp_object		*object;
 
@@ -155,37 +156,36 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
-	OPENCHANGE_RETVAL_IF(!request, MAPI_E_INVALID_PARAMETER, NULL);
-	OPENCHANGE_RETVAL_IF(!response, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
 
+	request = mapi_req->u.mapi_Logon;
+
 	/* Fill EcDoRpc_MAPI_REPL reply */
-	response->opnum = request->opnum;
-	response->handle_idx = request->handle_idx;
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
 
-	switch (request->u.mapi_Logon.LogonFlags) {
-	case LogonPrivate:
-		retval = RopLogon_Mailbox(mem_ctx, emsmdbp_ctx, request, response);
-		response->error_code = retval;
-		*size = libmapiserver_RopLogon_size(request, response);
-		break;
-	default:
+	if (request.LogonFlags & LogonPrivate) {
+		retval = RopLogon_Mailbox(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl);
+		mapi_repl->error_code = retval;
+		*size = libmapiserver_RopLogon_size(mapi_req, mapi_repl);
+	} else {
 		DEBUG(4, ("exchange_emsmdb: [OXCSTOR] Logon on Public Folders not implemented\n"));
 		retval = MAPI_E_NO_SUPPORT;
-		response->error_code = retval;
-		*size = libmapiserver_RopLogon_size(request, NULL);
-		break;
+		mapi_repl->error_code = retval;
+		*size = libmapiserver_RopLogon_size(mapi_req, NULL);
 	}
 
-	if (!response->error_code) {
+	if (!mapi_repl->error_code) {
 		retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec);
 		retval = mapi_handles_set_systemfolder(rec, 0);
 
-		object = emsmdbp_object_mailbox_init((TALLOC_CTX *)rec, emsmdbp_ctx, request);
+		object = emsmdbp_object_mailbox_init((TALLOC_CTX *)rec, emsmdbp_ctx, mapi_req);
 		retval = mapi_handles_set_private_data(rec, object);
 
-		handles[response->handle_idx] = rec->handle;
+		handles[mapi_repl->handle_idx] = rec->handle;
 	}
 
 	return retval;
@@ -213,8 +213,6 @@
 	enum MAPISTATUS		retval;
 	uint32_t		handle;
 
-	*size = libmapiserver_RopRelease_size();
-
 	handle = handles[request->handle_idx];
 	retval = mapi_handles_delete(emsmdbp_ctx->handles_ctx, handle);
 	OPENCHANGE_RETVAL_IF(retval && retval != MAPI_E_NOT_FOUND, retval, NULL);

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/oxctabl.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxctabl.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxctabl.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -0,0 +1,476 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+   \file oxctabl.c
+
+   \brief Table object routines and Rops
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/libmapiserver/libmapiserver.h"
+#include "dcesrv_exchange_emsmdb.h"
+#include "libmapi/defs_private.h"
+
+/**
+   \details EcDoRpc SetColumns (0x12) Rop. This operation sets the
+   properties to be included in the table.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the SetColumns EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the SetColumns EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetColumns(TALLOC_CTX *mem_ctx,
+					       struct emsmdbp_context *emsmdbp_ctx,
+					       struct EcDoRpc_MAPI_REQ *mapi_req,
+					       struct EcDoRpc_MAPI_REPL *mapi_repl,
+					       uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS			retval;
+	struct mapi_handles		*parent;
+	struct emsmdbp_object		*object;
+	struct emsmdbp_object_table	*table;
+	struct SetColumns_req		request;
+	void				*data = NULL;
+	uint32_t			handle;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCTABL] SetColumns (0x12)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	/* Initialize default empty SetColumns reply */
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->u.mapi_SetColumns.TableStatus = 0;
+
+	*size += libmapiserver_RopSetColumns_size(mapi_repl);
+
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	retval = mapi_handles_get_private_data(parent, &data);
+	object = (struct emsmdbp_object *) data;
+
+	if (object) {
+		table = object->object.table;
+		OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
+
+		request = mapi_req->u.mapi_SetColumns;
+		if (request.prop_count) {
+			table->prop_count = request.prop_count;
+			table->properties = talloc_memdup(table, request.properties, 
+							  request.prop_count * sizeof (uint32_t));
+		}
+	}
+
+	DEBUG(0, ("RopSetColumns: returns MAPI_E_SUCCESS\n"));
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc SortTable (0x13) Rop. This operation defines the
+   order of rows of a table based on sort criteria.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the SortTable EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the SortTable EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSortTable(TALLOC_CTX *mem_ctx,
+					      struct emsmdbp_context *emsmdbp_ctx,
+					      struct EcDoRpc_MAPI_REQ *mapi_req,
+					      struct EcDoRpc_MAPI_REPL *mapi_repl,
+					      uint32_t *handles, uint16_t *size)
+{
+	DEBUG(4, ("exchange_emsmdb: [OXCTABL] SortTable (0x13)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->u.mapi_SortTable.TableStatus = 0;
+
+	*size += libmapiserver_RopSortTable_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc SortTable (0x14) Rop. This operation establishes a
+   filter for a table.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the Restrict EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the Restrict EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRestrict(TALLOC_CTX *mem_ctx,
+					     struct emsmdbp_context *emsmdbp_ctx,
+					     struct EcDoRpc_MAPI_REQ *mapi_req,
+					     struct EcDoRpc_MAPI_REPL *mapi_repl,
+					     uint32_t *handles, uint16_t *size)
+{
+	DEBUG(4, ("exchange_emsmdb: [OXCTABL] Restrict (0x14)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->u.mapi_Restrict.TableStatus = 0;
+
+	*size += libmapiserver_RopRestrict_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;	
+}
+
+
+/**
+   \details EcDoRpc QueryRows (0x15) Rop. This operation retrieves
+   rows from a table.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the QueryRows EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the QueryRows EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryRows(TALLOC_CTX *mem_ctx,
+					      struct emsmdbp_context *emsmdbp_ctx,
+					      struct EcDoRpc_MAPI_REQ *mapi_req,
+					      struct EcDoRpc_MAPI_REPL *mapi_repl,
+					      uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS			retval;
+	struct mapi_handles		*parent;
+	struct emsmdbp_object		*object;
+	struct emsmdbp_object_table	*table;
+	struct QueryRows_req		request;
+	struct QueryRows_repl		response;
+	void				*data;
+	char				*table_filter = NULL;
+	uint32_t			handle;
+	uint32_t			count;
+	uint32_t			property;
+	uint8_t				flagged;
+	uint32_t			i, j;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCTABL] QueryRows (0x15)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	request = mapi_req->u.mapi_QueryRows;
+	response = mapi_repl->u.mapi_QueryRows;
+
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_NOT_FOUND;
+	
+	response.RowData.length = 0;
+
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
+	if (retval) goto end;
+
+	retval = mapi_handles_get_private_data(parent, &data);
+	object = (struct emsmdbp_object *) data;
+
+	/* Ensure referring object exists and is a table */
+	if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) {
+		goto end;
+	}
+
+	table = object->object.table;
+	if (!table->folderID) {
+		goto end;
+	}
+	table_filter = talloc_asprintf(mem_ctx, "(&(PidTagParentFolderId=0x%.16"PRIx64")(PidTagFolderId=*))", table->folderID);
+	DEBUG(0, ("table_filter: %s\n", table_filter));
+
+	if ((request.RowCount + table->numerator) > table->denominator) {
+		request.RowCount = table->denominator - table->numerator;
+	}
+
+	/* Lookup the properties and check if we need to flag the PropertyRow blob */
+	for (i = 0, count = 0; i < request.RowCount; i++, count++) {
+		flagged = 0;
+
+		/* Lookup for flagged property row */
+		for (j = 0; j < table->prop_count; j++) {
+			retval = openchangedb_get_table_property(mem_ctx, emsmdbp_ctx->oc_ctx, 
+								 emsmdbp_ctx->szDisplayName,
+								 table_filter, table->properties[j], 
+								 table->numerator, &data);	
+			if (retval == MAPI_E_INVALID_OBJECT) {
+				goto finish;
+			}
+			if (retval == MAPI_E_NOT_FOUND) {
+				flagged = 1;
+				libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+							    0x0000000b, (const void *)&flagged, &response.RowData,
+							    0, 0);
+				break;
+			}			
+		}
+
+		/* Push the property */
+		for (j = 0; j < table->prop_count; j++) {
+			property = table->properties[j];
+			retval = openchangedb_get_table_property(mem_ctx, emsmdbp_ctx->oc_ctx, 
+								 emsmdbp_ctx->szDisplayName,
+								 table_filter, table->properties[j], 
+								 table->numerator, &data);
+			if (retval == MAPI_E_INVALID_OBJECT) {
+				goto finish;
+			}
+			if (retval == MAPI_E_NOT_FOUND) {
+				property = (property & 0xFFFF0000) + PT_ERROR;
+				data = (void *)&retval;
+			}
+
+			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+						    property, (const void *)data,
+						    &response.RowData, flagged?PT_ERROR:0, flagged);
+
+		}
+
+		table->numerator++;
+	}
+finish:
+	talloc_free(table_filter);
+
+	/* QueryRows reply parameters */
+	if (count) {
+		if (count < request.RowCount) {
+			mapi_repl->u.mapi_QueryRows.Origin = 0;
+		} else {
+			mapi_repl->u.mapi_QueryRows.Origin = 2;
+		}
+		mapi_repl->error_code = MAPI_E_SUCCESS;
+		mapi_repl->u.mapi_QueryRows.RowCount = count;
+		mapi_repl->u.mapi_QueryRows.RowData.length = response.RowData.length;
+		mapi_repl->u.mapi_QueryRows.RowData.data = response.RowData.data;
+	} else {
+		/* useless code for the moment */
+		mapi_repl->error_code = MAPI_E_SUCCESS;
+		mapi_repl->u.mapi_QueryRows.Origin = 2;
+		mapi_repl->u.mapi_QueryRows.RowCount = 0;
+		mapi_repl->u.mapi_QueryRows.RowData.length = 0;
+		mapi_repl->u.mapi_QueryRows.RowData.data = NULL;
+	}
+
+end:
+	*size += libmapiserver_RopQueryRows_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc QueryPosition (0x17) Rop. This operation returns
+   the location of cursor in the table.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the QueryPosition EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the QueryPosition EcDoRpc_MAPI_REPL structure
+   \handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryPosition(TALLOC_CTX *mem_ctx,
+						  struct emsmdbp_context *emsmdbp_ctx,
+						  struct EcDoRpc_MAPI_REQ *mapi_req,
+						  struct EcDoRpc_MAPI_REPL *mapi_repl,
+						  uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS			retval;
+	struct mapi_handles		*parent;
+	struct emsmdbp_object		*object;
+	struct emsmdbp_object_table	*table;
+	void				*data;
+	uint32_t			handle;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCTABL] QueryPosition (0x17)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_NOT_FOUND;
+	
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
+	if (retval) goto end;
+
+	retval = mapi_handles_get_private_data(parent, &data);
+	if (retval) goto end;
+	object = (struct emsmdbp_object *) data;
+
+	/* Ensure object exists and is table type */
+	if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) goto end;
+
+	table = object->object.table;
+	if (!table->folderID) goto end;
+
+	mapi_repl->u.mapi_QueryPosition.Numerator = table->numerator;
+	mapi_repl->u.mapi_QueryPosition.Denominator = table->denominator;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+
+end:
+	*size += libmapiserver_RopQueryPosition_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc SeekRow (0x18) Rop. This operation moves the
+   cursor to a specific position in a table.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the SeekRow EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the SeekRow EcDoRpc_MAPI_REPL structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekRow(TALLOC_CTX *mem_ctx,
+					    struct emsmdbp_context *emsmdbp_ctx,
+					    struct EcDoRpc_MAPI_REQ *mapi_req,
+					    struct EcDoRpc_MAPI_REPL *mapi_repl,
+					    uint32_t *handles, uint16_t *size)
+{
+	DEBUG(4, ("exchange_emsmdb: [OXCTABL] SeekRow (0x18)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->u.mapi_SeekRow.HasSoughtLess = 0;
+	mapi_repl->u.mapi_SeekRow.RowsSought = 0;
+
+	*size += libmapiserver_RopSeekRow_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc FindRow (0x4f) Rop. This operation moves the
+   cursor to a row in a table that matches specific search criteria.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the FindRow EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the FindRow EcDoRpc_MAPI_REPL structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopFindRow(TALLOC_CTX *mem_ctx,
+					    struct emsmdbp_context *emsmdbp_ctx,
+					    struct EcDoRpc_MAPI_REQ *mapi_req,
+					    struct EcDoRpc_MAPI_REPL *mapi_repl,
+					    uint32_t *handles, uint16_t *size)
+{
+	DEBUG(4, ("exchange_emsmdb: [OXCTABL] FindRow (0x4f)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->u.mapi_FindRow.RowNoLongerVisible = 0;
+	mapi_repl->u.mapi_FindRow.HasRowData = 0;
+	mapi_repl->u.mapi_FindRow.row.length = 0;
+	mapi_repl->u.mapi_FindRow.row.data = 0;
+
+	*size += libmapiserver_RopFindRow_size(mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/oxorule.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxorule.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxorule.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -0,0 +1,95 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+   \file oxctabl.c
+
+   \brief E-mail rules object routines and Rops
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/libmapiserver/libmapiserver.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+
+/**
+   \details EcDoRpc GetRulesTable (0x3f) Rop. This operation gets the
+   rules table of a folder.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the GetRulesTable EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the GetRulesTable EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetRulesTable(TALLOC_CTX *mem_ctx,
+						  struct emsmdbp_context *emsmdbp_ctx,
+						  struct EcDoRpc_MAPI_REQ *mapi_req,
+						  struct EcDoRpc_MAPI_REPL *mapi_repl,
+						  uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_handles	*parent;
+	struct mapi_handles	*rec;
+	struct emsmdbp_object	*object;
+	void			*data = NULL;
+	uint32_t		handle;
+
+	DEBUG(4, ("exchange_emsmdb: [OXORULE] GetRulesTable (0x3f)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Ensure parent handle references a folder object */
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Initialize default GetRulesTable reply */
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->u.mapi_GetRulesTable.handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+
+	mapi_handles_get_private_data(parent, &data);
+	object = (struct emsmdbp_object *) data;
+	if (!object || object->type != EMSMDBP_OBJECT_FOLDER) {
+		mapi_repl->error_code = MAPI_E_NOT_FOUND;
+		goto end;
+	}
+
+	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
+	handles[mapi_repl->handle_idx] = rec->handle;
+
+end:
+	*size += libmapiserver_RopGetRulesTable_size();
+
+	return MAPI_E_SUCCESS;
+}

Modified: trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -220,6 +220,7 @@
 	}
 
 	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	if (!h) return MAPI_E_LOGON_FAILED;
 	emsabp_ctx = (struct emsabp_context *) h->data;
 
 	/* Step 1. Sanity Checks (MS-NSPI Server Processing Rules) */
@@ -243,7 +244,7 @@
 
 	if (r->in.lpETable == NULL) {
 		/* FIXME */
-		return MAPI_E_INVALID_BOOKMARK;
+		retval = MAPI_E_INVALID_BOOKMARK;
 	}
 
 	if (retval != MAPI_E_SUCCESS) {
@@ -319,16 +320,19 @@
 	}
 
 	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	if (!h) return MAPI_E_LOGON_FAILED;
 	emsabp_ctx = (struct emsabp_context *) h->data;
 
 	/* Step 1. Retrieve MIds array given search criterias */
 	ppOutMIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	ppOutMIds->cValues = 0;
+	ppOutMIds->aulPropTag = NULL;
+
 	retval = emsabp_search(mem_ctx, emsabp_ctx, ppOutMIds, r->in.Filter, r->in.pStat, r->in.ulRequested);
 	if (retval != MAPI_E_SUCCESS) {
 	failure:
 		r->out.pStat = r->in.pStat;
-		ppOutMIds = NULL;
-		r->out.ppOutMIds = &ppOutMIds;		
+		*r->out.ppOutMIds = ppOutMIds;	
 		r->out.ppRows = talloc(mem_ctx, struct SRowSet *);
 		r->out.ppRows[0] = NULL;
 		r->out.result = retval;
@@ -408,6 +412,9 @@
 	}
 
 	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	if (!h) return MAPI_E_LOGON_FAILED;
+	OPENCHANGE_RETVAL_IF(!h, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+
 	emsabp_ctx = (struct emsabp_context *) h->data;
 	
 	r->out.ppMIds = talloc_array(mem_ctx, struct SPropTagArray *, 2);
@@ -483,6 +490,7 @@
 	}
 
 	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	if (!h) return MAPI_E_LOGON_FAILED;
 	emsabp_ctx = (struct emsabp_context *) h->data;
 
 	MId = r->in.pStat->CurrentRec;
@@ -504,16 +512,14 @@
 
 	/* Step 2. Fetch properties */
 	r->out.ppRows = talloc_array(mem_ctx, struct SRow *, 2);
-	r->out.ppRows[0] = talloc_zero(mem_ctx, struct SRow);
+	r->out.ppRows[0] = talloc_zero(r->out.ppRows, struct SRow);
 	r->out.ppRows[0]->ulAdrEntryPad = 0;
 	r->out.ppRows[0]->cValues = r->in.pPropTags->cValues;
-	r->out.ppRows[0]->lpProps = talloc_array(mem_ctx, struct SPropValue, r->in.pPropTags->cValues);
+	r->out.ppRows[0]->lpProps = talloc_array(r->out.ppRows[0], struct SPropValue, r->in.pPropTags->cValues);
 
 	retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.pPropTags);
 	if (retval != MAPI_E_SUCCESS) {
-		talloc_free(r->out.ppRows[0]->lpProps);
-		talloc_free(r->out.ppRows[0]);
-		talloc_free(r->out.ppRows[0]);
+		talloc_free(r->out.ppRows);
 		r->out.result = MAPI_W_ERRORS_RETURNED;
 		goto failure;
 	}
@@ -591,6 +597,7 @@
 	}
 
 	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	if (!h) return MAPI_E_LOGON_FAILED;
 	emsabp_ctx = (struct emsabp_context *) h->data;
 
 	/* Step 1. (FIXME) We arbitrary set lpVersion to 0x1 */
@@ -796,7 +803,7 @@
 	const struct ndr_interface_table	*table;
 	uint16_t				opnum;
 
-	table = (const struct ndr_interface_table *) dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *) dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 
 	/* Sanity checks */

Modified: trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -152,16 +152,13 @@
 	int			msExchUserAccountControl;
 	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
 	struct ldb_result	*res = NULL;
-	char			*ldb_filter;
 	const char * const	recipient_attrs[] = { "msExchUserAccountControl", NULL };
 
 	username = dce_call->context->conn->auth_state.session_info->server_info->account_name;
 
-	ldb_filter = talloc_asprintf(emsabp_ctx->mem_ctx, "CN=%s", username);
 	ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res, 
 			 ldb_get_default_basedn(emsabp_ctx->users_ctx),
-			 scope, recipient_attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 scope, recipient_attrs, "CN=%s", username);
 
 	/* If the search failed */
 	if (ret != LDB_SUCCESS || !res->count) {
@@ -219,7 +216,6 @@
 	const char		*guid_str = NULL;
 	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
 	struct ldb_result	*res = NULL;
-	char			*ldb_filter;
 	char			*dn = NULL;
 	struct ldb_dn		*ldb_dn = NULL;
 	const char * const	recipient_attrs[] = { "*", NULL };
@@ -231,11 +227,9 @@
 	if (!netbiosname) return NULL;
 
 	/* Step 1. Find the Exchange Organization */
-	ldb_filter = talloc_strdup(emsabp_ctx->mem_ctx, "(objectClass=msExchOrganizationContainer)");
 	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
 			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
-			 scope, recipient_attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 scope, recipient_attrs, "(objectClass=msExchOrganizationContainer)");
 
 	if (ret != LDB_SUCCESS || !res->count) {
 		return NULL;
@@ -841,7 +835,6 @@
 	enum ldb_scope			scope = LDB_SCOPE_SUBTREE;
 	struct ldb_request		*req;
 	struct ldb_result		*res = NULL;
-	char				*ldb_filter;
 	struct ldb_dn			*ldb_dn = NULL;
 	struct ldb_control		**controls;
 	const char * const		recipient_attrs[] = { "*", NULL };
@@ -863,18 +856,16 @@
 	aRow_idx++;
 
 	/* Step 2. Retrieve the object pointed by addressBookRoots attribute: 'All Address Lists' */
-	ldb_filter = talloc_strdup(emsabp_ctx->mem_ctx, "(addressBookRoots=*)");
 	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
 			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
-			 scope, recipient_attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 scope, recipient_attrs, "(addressBookRoots=*)");
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_CORRUPT_STORE, aRow);
 
 	addressBookRoots = ldb_msg_find_attr_as_string(res->msgs[0], "addressBookRoots", NULL);
 	OPENCHANGE_RETVAL_IF(!addressBookRoots, MAPI_E_CORRUPT_STORE, aRow);
-	talloc_free(res);
 
 	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->conf_ctx, addressBookRoots);
+	talloc_free(res);
 	OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, aRow);
 
 	scope = LDB_SCOPE_BASE;
@@ -978,7 +969,6 @@
 	struct PropertyRestriction_r	*res_prop = NULL;
 	const char			*recipient = NULL;
 	const char * const		recipient_attrs[] = { "*", NULL };
-	char				*ldb_filter;
 	int				ret;
 	uint32_t			i;
 	const char			*dn;
@@ -1015,11 +1005,11 @@
 			res_prop->lpProp->value.lpszA :
 			res_prop->lpProp->value.lpszW;
 
-		ldb_filter = talloc_asprintf(emsabp_ctx->mem_ctx, "(&(objectClass=user)(sAMAccountName=*%s*)(!(objectClass=computer)))", recipient);
 		ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res,
 				 ldb_get_default_basedn(emsabp_ctx->users_ctx),
-				 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
-		talloc_free(ldb_filter);
+				 LDB_SCOPE_SUBTREE, recipient_attrs,
+				 "(&(objectClass=user)(sAMAccountName=*%s*)(!(objectClass=computer)))",
+				 recipient);
 
 		if (ret != LDB_SUCCESS || !res->count) {
 			return MAPI_E_NOT_FOUND;
@@ -1101,7 +1091,6 @@
 _PUBLIC_ enum MAPISTATUS emsabp_search_legacyExchangeDN(struct emsabp_context *emsabp_ctx, const char *legacyDN,
 							struct ldb_message **ldb_res)
 {
-	char			*ldb_filter;
 	const char * const	recipient_attrs[] = { "*", NULL };
 	int			ret;
 	struct ldb_result	*res = NULL;
@@ -1110,11 +1099,10 @@
 	OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ldb_res, MAPI_E_INVALID_PARAMETER, NULL);
 
-	ldb_filter = talloc_asprintf(emsabp_ctx->mem_ctx, "(legacyExchangeDN=%s)", legacyDN);
 	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
 			 ldb_get_default_basedn(emsabp_ctx->conf_ctx), 
-			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
-	talloc_free(ldb_filter);
+			 LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)",
+			 legacyDN);
 
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, NULL);
 

Modified: trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -186,8 +186,10 @@
 					      const char *keyname,
 					      uint32_t *MId)
 {
+	TALLOC_CTX	*mem_ctx;
 	TDB_DATA	key;
 	TDB_DATA	dbuf;
+	char		*str;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -201,7 +203,10 @@
 	OPENCHANGE_RETVAL_IF(!dbuf.dptr, MAPI_E_NOT_FOUND, NULL);
 	OPENCHANGE_RETVAL_IF(!dbuf.dsize, MAPI_E_NOT_FOUND, NULL);
 
-	*MId = strtol((const char *)dbuf.dptr, NULL, 16);
+	mem_ctx = talloc_named(NULL, 0, "emsabp_tdb_fetch_MId");
+	str = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize);
+	*MId = strtol((const char *)str, NULL, 16);
+	talloc_free(mem_ctx);
 	free(dbuf.dptr);
 
 	return MAPI_E_SUCCESS;
@@ -321,6 +326,7 @@
 	TALLOC_CTX	*mem_ctx;
 	TDB_DATA	key;
 	TDB_DATA	dbuf;
+	char		*str;
 	int		index;
 	int		ret;
 
@@ -339,9 +345,10 @@
 	retval = emsabp_tdb_fetch(tdb_ctx, EMSABP_TDB_DATA_REC, &dbuf);
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	index = strtol((const char *)dbuf.dptr, NULL, 16);
+	str = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize);
+	index = strtol(str, NULL, 16);
 	index += 1;
-
+	talloc_free(str);
 	free(dbuf.dptr);
 
 	dbuf.dptr = (unsigned char *)talloc_asprintf(mem_ctx, "0x%x", index);

Modified: trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -145,7 +145,7 @@
 	const struct ndr_interface_table	*table;
 	uint16_t				opnum;
 
-	table = (const struct ndr_interface_table *) dce_call->context->iface->private;
+	table = (const struct ndr_interface_table *) dce_call->context->iface->private_data;
 	opnum = dce_call->pkt.u.request.opnum;
 
 	/* Sanity checks */

Modified: trunk/openchange/ndr_mapi.c
===================================================================
--- trunk/openchange/ndr_mapi.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/ndr_mapi.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -283,6 +283,16 @@
 				if (r->error_code == MAPI_E_SUCCESS) {
 					NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->opnum));
 					NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u));
+				} else {
+					switch (r->opnum) {
+					case op_MAPI_Logon: {
+						if (r->error_code == ecWrongServer) {
+							NDR_CHECK(ndr_push_Logon_redirect(ndr, NDR_SCALARS, &(r->us.mapi_Logon)));
+						}
+						break; }
+					default:
+						break;
+					}
 				}
 			}
 		}
@@ -311,6 +321,16 @@
 				if ( r->error_code == MAPI_E_SUCCESS) {
 					NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum));
 					NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u));
+				} else {
+					switch (r->opnum) {
+					case op_MAPI_Logon: {
+						if (r->error_code == ecWrongServer) {
+							NDR_CHECK(ndr_pull_Logon_redirect(ndr, NDR_SCALARS, &(r->us.mapi_Logon)));
+						}
+						break;}
+					default:
+						break;
+					}
 				}
 			}
 		}
@@ -335,6 +355,17 @@
 			if (r->error_code == MAPI_E_SUCCESS) {
 				ndr_print_set_switch_value(ndr, &r->u, r->opnum);
 				ndr_print_EcDoRpc_MAPI_REPL_UNION(ndr, "u", &r->u);
+			} else {
+				switch (r->opnum) {
+				case op_MAPI_Logon: {
+					if (r->error_code == ecWrongServer) {
+						ndr_print_set_switch_value(ndr, &r->us, r->opnum);
+						ndr_print_EcDoRpc_MAPI_REPL_UNION_SPECIAL(ndr, "us", &r->us);
+					}
+					break;}
+				default:
+					break;
+				}
 			}
 		} else {
 			ndr_print_set_switch_value(ndr, &r->u, r->opnum);

Modified: trunk/openchange/python/openchange/mailbox.py
===================================================================
--- trunk/openchange/python/openchange/mailbox.py	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/python/openchange/mailbox.py	2009-04-14 14:43:51 UTC (rev 2699)
@@ -158,6 +158,7 @@
         retdn = "CN=%s,%s" % (username, basedn)
         self.ldb.add({"dn": retdn,
                   "objectClass": ["mailbox", "container"],
+                  "PidTagDisplayName": "OpenChange Mailbox: %s" % (username),
                   "cn": username,
                   "MailboxGUID": mailboxGUID,
                   "ReplicaID": replicaID,
@@ -232,6 +233,8 @@
                   "PidTagParentFolderId": parentfolder,
                   "PidTagFolderId": FID,
                   "PidTagDisplayName": foldername,
+                  "PidTagAttrHidden": str(0),
+                      "PidTagContainerClass": "IPF.Note",
                   "mapistore_uri": "sqlite://%s/%s/%s.db" % (mapistoreURL, username, FID),
                   "FolderType": str(1),
                   "SystemIdx": str(SystemIdx)})
@@ -264,11 +267,13 @@
         self.ldb.add({"dn": "CN=%s,%s" % (FID, res[0].dn),
                       "objectClass": ["specialfolder"],
                       "cn": FID,
+                      "PidTagParentFolderId": parentfolder,
                       "PidTagFolderId": FID,
                       "PidTagDisplayName": foldername,
                       "PidTagContainerClass": containerclass,
                       "mapistore_uri": "sqlite://%s/%s/%s.db" % (mapistoreURL, username, FID),
                       "PidTagContentCount": str(0),
+                      "PidTagAttrHidden": str(0),
                       "PidTagContentUnreadCount": str(0),
                       "PidTagSubFolders": str(0),
                       "FolderType": str(1)})

Modified: trunk/openchange/python/openchange/provision.py
===================================================================
--- trunk/openchange/python/openchange/provision.py	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/python/openchange/provision.py	2009-04-14 14:43:51 UTC (rev 2699)
@@ -271,6 +271,7 @@
         "Search": ({}, 11),
         "Views": ({}, 12),
         "Shortcuts": ({}, 13),
+        "Reminders": ({}, 14),
     }, 1)
 
     fids = {}
@@ -305,11 +306,11 @@
         (("Mailbox Root", "IPM Subtree"), "Journal",    "IPF.Journal",      "PidTagIpmJournalEntryId"),
         (("Mailbox Root", "IPM Subtree"), "Notes",      "IPF.StickyNote",   "PidTagIpmNoteEntryId"),
         (("Mailbox Root", "IPM Subtree"), "Tasks",      "IPF.Task",         "PidTagIpmTaskEntryId"),
-        (("Mailbox Root", "IPM Subtree"), "Reminders",  "Outlook.Reminder", "PidTagRemindersOnlineEntryId"),
         (("Mailbox Root", "IPM Subtree"), "Drafts",     "IPF.Notes",        "PidTagIpmDraftsEntryId")
         ]
 
     fid_inbox = fids[("Mailbox Root", "IPM Subtree", "Inbox")]
+    fid_reminders = fids[("Mailbox Root", "Reminders")]
     fid_mailbox = fids[("Mailbox Root",)]
     for path, foldername, containerclass, pidtag in special_folders:
         GlobalCount = db.get_message_GlobalCount(names.netbiosname)
@@ -344,6 +345,11 @@
     db.add_folder_property(fid_inbox, "PidTagSubFolders", "FALSE")
     db.add_folder_property(fid_inbox, "PidTagAccess", "63")
 
+    print "* Adding additional default properties to Reminders"
+    db.add_folder_property(fid_reminders, "PidTagContainerClass", "Outlook.Reminder");
+    db.add_folder_property(fid_inbox, "PidTagRemindersOnlineEntryId", fid_reminders);
+    db.add_folder_property(fid_mailbox, "PidTagRemindersOnlineEntryId", fid_reminders);
+
     GlobalCount = db.get_message_GlobalCount(names.netbiosname)
     print "* GlobalCount (0x%x)" % GlobalCount
 
@@ -358,8 +364,8 @@
 
     names = guess_names_from_smbconf(lp, None, None)
 
-    db = Ldb(url="users.ldb", session_info=system_session(),
-                  credentials=creds, lp=lp)
+    db = Ldb(url=os.path.join(lp.get("private dir"), "users.ldb"), 
+             session_info=system_session(), credentials=creds, lp=lp)
 
     user_dn = "CN=%s,CN=Users,%s" % (username, names.domaindn)
 
@@ -399,7 +405,7 @@
 
     names = guess_names_from_smbconf(lp, None, None)
 
-    db = Ldb(url="users.ldb", session_info=system_session(),
+    db = Ldb(url=os.path.join(lp.get("private dir"), "users.ldb"), session_info=system_session(),
                   credentials=creds, lp=lp)
 
     user_dn = "CN=%s,CN=Users,%s" % (username, names.domaindn)

Modified: trunk/openchange/script/mkrelease.sh
===================================================================
--- trunk/openchange/script/mkrelease.sh	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/script/mkrelease.sh	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1,20 +1,23 @@
 #!/bin/sh
 
 #
-# ./script/mkrelease.sh VERSION NICKNAME FIRST_REVISION
-# ./script/mkrelease.sh 0.7 PHASER 308
+# ./script/mkrelease.sh VERSION NICKNAME NICKNAME2 FIRST_REVISION
+# ./script/mkrelease.sh 0.7 PHASER Phaser 308
 #
 
 TMPDIR=`mktemp libmapi-XXXXX`
 rm $TMPDIR || exit 1
 svn export . $TMPDIR || exit 1
-svn log -r$3:HEAD > $TMPDIR/CHANGELOG || exit 1
+svn log -r$4:HEAD > $TMPDIR/CHANGELOG || exit 1
 
 ( cd $TMPDIR/
  ./autogen.sh || exit 1
  ./configure || exit 1
  make || exit 1
  sed -i "s/^OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=yes/OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=no/g" VERSION || exit 1
+ sed -i "s/^OPENCHANGE_VERSION_RELEASE_NICKNAME=.*/OPENCHANGE_VERSION_RELEASE_NICKNAME=$3/g" VERSION || exit 1
+ sed -i "s/^OPENCHANGE_VERSION_RELEASE_NUMBER=.*/OPENCHANGE_VERSION_RELEASE_NUMBER=$1/g" VERSION || exit 1
+
  ./autogen.sh || exit 1
  ./configure || exit 1
  make doxygen || exit 1

Modified: trunk/openchange/script/mkversion.sh
===================================================================
--- trunk/openchange/script/mkversion.sh	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/script/mkversion.sh	2009-04-14 14:43:51 UTC (rev 2699)
@@ -19,8 +19,8 @@
 
 OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=`sed -n 's/^OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=//p' $SOURCE_DIR$VERSION_FILE`
 OPENCHANGE_VERSION_RELEASE_NICKNAME=`sed -n 's/^OPENCHANGE_VERSION_RELEASE_NICKNAME=//p' $SOURCE_DIR$VERSION_FILE`
+OPENCHANGE_VERSION_RELEASE_NUMBER=`sed -n 's/^OPENCHANGE_VERSION_RELEASE_NUMBER=//p' $SOURCE_DIR$VERSION_FILE`
 
-
 echo "/* Autogenerated by script/mkversion.h */" >> $OUTPUT_FILE
 echo "#define OPENCHANGE_MAJOR_RELEASE ${OPENCHANGE_MAJOR_RELEASE}" >> $OUTPUT_FILE
 echo "#define OPENCHANGE_MINOR_RELEASE ${OPENCHANGE_MINOR_RELEASE}" >> $OUTPUT_FILE
@@ -51,7 +51,12 @@
     LANG=${_SAVE_LANG}
 fi
 
-echo "#define OPENCHANGE_VERSION_OFFICIAL_STRING \"${OPENCHANGE_VERSION_STRING}\"" >> $OUTPUT_FILE
+if test -z "${OPENCHANGE_VERSION_RELEASE_NUMBER}";then
+    echo "#define OPENCHANGE_VERSION_OFFICIAL_STRING \"${OPENCHANGE_VERSION_STRING}\"" >> $OUTPUT_FILE
+else
+    OPENCHANGE_VERSION_STRING="${OPENCHANGE_VERSION_RELEASE_NUMBER}"
+    echo "#define OPENCHANGE_VERSION_OFFICIAL_STRING \"${OPENCHANGE_VERSION_RELEASE_NUMBER}\"" >> $OUTPUT_FILE
+fi
 
 ##
 ## Add a release nickname

Modified: trunk/openchange/script/samba4_ver.sh
===================================================================
--- trunk/openchange/script/samba4_ver.sh	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/script/samba4_ver.sh	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1,4 +1,4 @@
-SAMBA4_GIT_REV=57f978d
-SAMBA4_GIT_VER=4.0.0alpha6
-SAMBA4_RELEASE=4.0.0alpha6
+SAMBA4_GIT_REV=c3632e4
+SAMBA4_GIT_VER=4.0.0alpha7
+SAMBA4_RELEASE=4.0.0alpha7
 

Modified: trunk/openchange/utils/backup/openchangebackup.c
===================================================================
--- trunk/openchange/utils/backup/openchangebackup.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/backup/openchangebackup.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -92,7 +92,7 @@
 	ldb_ctx = ocb_ctx->ldb_ctx;
 
 	/* Check if the record already exists */
-	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, dn);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "%s", dn);
 	OCB_RETVAL_IF(res->msgs, "Record already exists", NULL);
 
 	/* Retrieve the record basedn */

Modified: trunk/openchange/utils/mapitest/mapitest_common.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_common.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/mapitest/mapitest_common.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -235,6 +235,7 @@
 	const char		*body;
 	uint32_t		msgflag;
 	uint32_t		format;
+	uint32_t		ret;
 
 	/* Sanity checks */
 	if (subject == NULL) return false;
@@ -267,7 +268,8 @@
 
 	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
 	SPropValue.value.l = 0;
-	SRowSet_propcpy(mt->mem_ctx, SRowSet, SPropValue);
+	ret = SRowSet_propcpy(mt->mem_ctx, SRowSet, SPropValue);
+	if (ret) return false;
 
 	/* Set Recipients */
 	SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);

Modified: trunk/openchange/utils/mapitest/module.c
===================================================================
--- trunk/openchange/utils/mapitest/module.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/mapitest/module.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -34,6 +34,7 @@
 	ret += module_oxcmsg_init(mt);
 	ret += module_oxcprpt_init(mt);
 	ret += module_oxorule_init(mt);
+	ret += module_oxcnotif_init(mt);
 	ret += module_oxcfxics_init(mt);
 	ret += module_nspi_init(mt);
 	ret += module_noserver_init(mt);
@@ -242,6 +243,27 @@
 
 
 /**
+   \details Register the Core Notification Protocol test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxcnotif_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXCNOTIF", "Core Notification Protocol", true);
+
+	mapitest_suite_add_test(suite, "REGISTER-NOTIFICATION", "Subscribe to notifications", mapitest_oxcnotif_RegisterNotification);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
    \details Register the Bulk Data Transfer Protocol test suite
 
    \param mt pointer on the top-level mapitest structure

Modified: trunk/openchange/utils/mapitest/modules/module_nspi.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_nspi.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/mapitest/modules/module_nspi.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -765,7 +765,7 @@
 	mapitest_print_retval(mt, "NspiGetNamesFromIDs");
 	MAPIFreeBuffer(ppReturnedPropTags);
 
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(ppNames);
 		return false;
 	}
@@ -776,10 +776,11 @@
 	MAPIFreeBuffer(ppReturnedPropTags);
 	MAPIFreeBuffer(ppNames);
 	
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
+	errno = retval;
 	return true;
 }
 

Modified: trunk/openchange/utils/mapitest/modules/module_oxcmsg.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcmsg.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/mapitest/modules/module_oxcmsg.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1103,6 +1103,8 @@
 	mapi_object_t		obj_embeddedmsg;
 	mapi_id_t		id_msgs[1];                           
 	struct SPropValue	attach[2];
+	struct SRowSet		SRowSet;
+	struct SPropTagArray	SPropTagArray;
 
 	/* Step 1. Logon */
 	mapi_object_init(&obj_store);
@@ -1159,7 +1161,7 @@
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
 		mapi_object_release(&obj_store);
-		return false;;
+		return false;
 	}
 
 	mapi_object_init(&obj_embeddedmsg);
@@ -1170,7 +1172,7 @@
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
 		mapi_object_release(&obj_store);
-		return false;;
+		return false;
 	}
 
 	ret = mapitest_common_message_fill(mt, &obj_embeddedmsg, "[MT] EmbeddedMessage");
@@ -1190,7 +1192,7 @@
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
 		mapi_object_release(&obj_store);
-		return false;;
+		return false;
 	}
 	// Save the changes to the attachment and then the message
 	retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
@@ -1200,7 +1202,7 @@
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
 		mapi_object_release(&obj_store);
-		return false;;
+		return false;
 	}
 
 	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
@@ -1210,10 +1212,38 @@
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
 		mapi_object_release(&obj_store);
-		return false;;
+		return false;
 	}
 
-	/* Step 5. Delete the message */
+	/* Step 5. Open the embedded message */
+	mapi_object_init(&obj_attach);
+	retval = OpenAttach(&obj_message, 0, &obj_attach);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenAttach", retval);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;
+	}
+	retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, 0);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenEmbeddedMessage", retval);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;
+	}
+
+	/* Step 6. Get the recipient table */
+	retval = GetRecipientTable(&obj_embeddedmsg, &SRowSet, &SPropTagArray);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetRecipientTable", retval);
+
+	mapidump_SRowSet(&SRowSet, "\t * ");
+	mapi_object_release(&obj_embeddedmsg);
+
+	/* Step 7. Delete the message */
 	id_msgs[0] = mapi_object_get_id(&obj_message);
 	retval = DeleteMessage(&obj_folder, id_msgs, 1);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "DeleteMessage", GetLastError());

Added: trunk/openchange/utils/mapitest/modules/module_oxcnotif.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcnotif.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxcnotif.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -0,0 +1,99 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - Core Notifications Protocol operation tests
+
+   Copyright (C) Brad Hards 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxcnotif.c
+
+   \brief Core Notifications Protocol test suite
+*/
+
+/* Internal callback functions */
+int cb(uint16_t, void*, void*);
+
+int cb(uint16_t type, void* data, void* priv)
+{
+	return 0;
+}
+
+/**
+   \details Test the RegisterNotification (0x29) operation
+
+   This function:
+   -# 
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcnotif_RegisterNotification(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	uint32_t tcon;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+	
+	/* Step 2. Open Inbox folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox);
+	if (!ret) {
+		return ret;
+	}
+
+	/* Step 3. Register notification */
+	retval = RegisterNotification(fnevObjectCopied);
+	mapitest_print_retval(mt, "RegisterNotification");
+	if ( retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Subscribe for notifications */
+	retval = Subscribe(&obj_store, &tcon, fnevObjectCopied, true, cb);
+	mapitest_print_retval(mt, "Subscribe");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Unsubscribe for notifications */
+	retval = Unsubscribe(mt->session, tcon);
+	mapitest_print_retval(mt, "Unsubscribe");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 6. Cleanup */
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}

Modified: trunk/openchange/utils/mapitest/modules/module_oxcprpt.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcprpt.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/mapitest/modules/module_oxcprpt.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -54,7 +54,7 @@
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}	
 	
@@ -62,14 +62,14 @@
 	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
 	retval = GetPropList(&obj_store, SPropTagArray);
 	mapitest_print_retval(mt, "GetPropList");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	/* Step 3. Call the GetProps operation */
 	retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
 	mapitest_print_retval(mt, "GetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	MAPIFreeBuffer(SPropTagArray);
@@ -102,7 +102,7 @@
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -110,7 +110,7 @@
 	retval = GetPropsAll(&obj_store, &properties_array);
 	mapitest_print_retval(mt, "GetPropsAll");
 	MAPIFreeBuffer(properties_array.lpProps);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -142,7 +142,7 @@
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -151,7 +151,7 @@
 	retval = GetPropList(&obj_store, SPropTagArray);
 	mapitest_print_retval(mt, "GetPropList");
 	MAPIFreeBuffer(SPropTagArray);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -190,7 +190,7 @@
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -198,7 +198,7 @@
 	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
 	retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
 	mapitest_print_retval_step_fmt(mt, "2.", "GetProps", "(%s)", "Retrieve the mailbox name");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	MAPIFreeBuffer(SPropTagArray);
@@ -288,18 +288,19 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SPropValue	*lpProps;
 	uint32_t		cValues;
+	bool			result;
 
 	/* Step 1. Logon Private Mailbox */
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	mapi_object_init(&obj_top_folder);
 	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
 	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -308,15 +309,15 @@
         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
                               OPEN_IF_EXISTS, &obj_ref_folder);
 	mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	/* Step 3: Create reference message */
 	mapi_object_init(&obj_ref_message);
-	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
 	mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (!result != MAPI_E_SUCCESS) {
 		return false;
 	}
 	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
@@ -433,19 +434,20 @@
 	const char		*targ_name = NULL;
 	const char		*targ_dept = NULL;
 	uint16_t		problem_count = 999;
-	struct PropertyProblem *problems = NULL;
+	struct PropertyProblem	*problems = NULL;
+	bool			result;
 
 	/* Step 1. Logon Private Mailbox */
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	mapi_object_init(&obj_top_folder);
 	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
 	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -454,15 +456,15 @@
         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
                               OPEN_IF_EXISTS, &obj_ref_folder);
 	mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	/* Step 3: Create reference message */
 	mapi_object_init(&obj_ref_message);
-	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
 	mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (!result) {
 		return false;
 	}
 	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
@@ -505,9 +507,9 @@
 
 	/* Step 5: Create target message */
 	mapi_object_init(&obj_target_message);
-	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
+	result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
 	mapitest_print_retval_step_fmt(mt, "5.1.", "mapitest_common_message_create", "(%s)", "Create target email");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (!result) {
 		return false;
 	}
 	retval = SaveChangesMessage(&obj_ref_folder, &obj_target_message, KeepOpenReadWrite);
@@ -556,7 +558,7 @@
 			   &problem_count, &problems);
 	mapitest_print_retval_step_fmt(mt, "7.", "CopyProps", "(%s)", "no overwrite");
 	MAPIFreeBuffer(problems);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	MAPIFreeBuffer(SPropTagArray);
@@ -624,7 +626,7 @@
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(problems);
 	mapitest_print_retval_step_fmt(mt, "9.", "CopyProps", "(%s)", "with overwrite");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -692,7 +694,7 @@
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(problems);
 	mapitest_print_retval_step_fmt(mt, "11.", "CopyProps", "(%s)", "move");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -763,7 +765,8 @@
 /**
    \details Test Stream operations. This test uses all related stream
    operations: OpenStream (0x2b), SetStreamSize (0x2f), WriteStream
-   (0x2d), CommitStream (0x5d), ReadStream (0x2c), SeekStream (0x2e)
+   (0x2d), CommitStream (0x5d), ReadStream (0x2c), SeekStream (0x2e),
+   LockRegionStream (0x5b) and UnlockRegionStream (0x5c)
    
    This function:
    -# Logon 
@@ -780,6 +783,9 @@
    -# Read the stream and compare buffers
    -# SeekStream at 0x1000 from the end of the stream
    -# Read the 0x1000 last bytes and check if it matches
+   -# Lock a range of the stream
+   -# TODO: test if the locking works
+   -# Unlock a range of the stream
    -# Delete the message;
 
    \param mt pointer to the top-level mapitest structure
@@ -820,21 +826,21 @@
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	/* Step 2. Open Inbox folder */
 	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
 	mapitest_print_retval(mt, "GetDefaultFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	mapi_object_init(&obj_folder);
 	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
 	mapitest_print_retval(mt, "OpenFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -921,13 +927,13 @@
 	/* Step 9. Save the attachment */
 	retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
 	mapitest_print_retval(mt, "SaveChangesAttachment");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 	}
 
 	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
 	mapitest_print_retval(mt, "SaveChangesMessage");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 	}
 
@@ -989,19 +995,36 @@
 	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 	}
-	
+
 	if (read_size && !strcmp(out_stream, stream + StreamSize - read_size)) {
 		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Comparison");
 	} else {
 		mapitest_print(mt, "* %-35s: [FAILURE]\n", "Comparison");
 	}
 
-	/* Step 14. Delete the message */
+	/* Step 13. Lock a region */
+	retval = LockRegionStream(&obj_stream, 0x2000, 0x1000, 0x0);
+	mapitest_print_retval(mt, "LockRegionStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* TODO: Step 14. Test the locking */
+
+
+	/* Step 15. Unlock the region */
+	retval = UnlockRegionStream(&obj_stream, 0x2000, 0x1000, 0x0);
+	mapitest_print_retval(mt, "UnlockRegionStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 16. Delete the message */
 	errno = 0;
 	id_msgs[0] = mapi_object_get_id(&obj_message);
 	retval = DeleteMessage(&obj_folder, id_msgs, 1);
 	mapitest_print_retval(mt, "DeleteMessage");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 	}
 
@@ -1075,21 +1098,21 @@
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	/* Step 2. Open Inbox folder */
 	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
 	mapitest_print_retval(mt, "GetDefaultFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	mapi_object_init(&obj_folder);
 	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
 	mapitest_print_retval(mt, "OpenFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -1233,7 +1256,7 @@
 	mapitest_print_retval(mt, "SaveChangesAttachment");
 	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
 	mapitest_print_retval(mt, "SaveChangesMessage");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 	}
 
@@ -1284,7 +1307,7 @@
 	id_msgs[0] = mapi_object_get_id(&obj_message);
 	retval = DeleteMessage(&obj_folder, id_msgs, 1);
 	mapitest_print_retval(mt, "DeleteMessage");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 	}
 
@@ -1358,14 +1381,15 @@
 	const char		*targ_name = NULL;
 	const char		*targ_dept = NULL;
 	uint16_t		problem_count = 999;
-	struct PropertyProblem *problems = NULL;
+	struct PropertyProblem  *problems = NULL;
+	bool			result;
 	bool			ret = true;
 
 	/* Step 1. Logon Private Mailbox */
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	mapi_object_init(&obj_top_folder);
@@ -1374,7 +1398,7 @@
 
 	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
 	mapitest_print_retval(mt, "OpenFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1384,24 +1408,24 @@
         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
                               OPEN_IF_EXISTS, &obj_ref_folder);
 	mapitest_print_retval_fmt(mt, "CreateFolder", "(Create test folder)");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
 	lpProp[0].ulPropTag = PR_CONTAINER_CLASS;
 	lpProp[0].value.lpszA = "IPF.Note";
-	SetProps(&obj_ref_folder, lpProp, 1);
+	retval = SetProps(&obj_ref_folder, lpProp, 1);
 	mapitest_print_retval(mt, "SetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
 
 	/* Step 3: Create reference message */
 	mapi_object_init(&obj_ref_message);
-	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
 	mapitest_print_retval(mt, "mapitest_common_message_create");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (!result) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1466,9 +1490,9 @@
 
 	/* Step 5: Create target message */
 	mapi_object_init(&obj_target_message);
-	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
+	result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
 	mapitest_print_retval(mt, "mapitest_common_message_create");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (!result) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1527,7 +1551,7 @@
 	MAPIFreeBuffer(exclude);
 	MAPIFreeBuffer(problems);
 	mapitest_print_retval_fmt(mt, "CopyTo", "(no overwrite)");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1605,7 +1629,7 @@
 	MAPIFreeBuffer(exclude);
 	MAPIFreeBuffer(problems);
 	mapitest_print_retval_fmt(mt, "CopyTo", "(with overwrite)");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -1681,8 +1705,8 @@
 			   &problem_count, &problems);
 	MAPIFreeBuffer(exclude);
 	MAPIFreeBuffer(problems);
-	mapitest_print(mt, "* %-35s: 0x%.8x\n", "Step 11 - CopyTo (move)", GetLastError());
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	mapitest_print_retval(mt, "* Step 11 - CopyTo (move)");
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1737,9 +1761,9 @@
 
 	/* Step 13: Create attachment on reference email, and set properties */
 	mapi_object_init(&obj_ref_attach);
-	CreateAttach(&obj_ref_message, &obj_ref_attach);
+	retval = CreateAttach(&obj_ref_message, &obj_ref_attach);
 	mapitest_print_retval(mt, "CreateAttach");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1749,9 +1773,9 @@
 	lpProp[1].value.l = 0;
 	lpProp[2].ulPropTag = PR_ATTACH_FILENAME;
 	lpProp[2].value.lpszA = MT_MAIL_ATTACH;
-	SetProps(&obj_ref_attach, lpProp, 3);
+	retval = SetProps(&obj_ref_attach, lpProp, 3);
 	mapitest_print_retval(mt, "SetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1760,9 +1784,9 @@
 
 	/* Step 14: Create attachment on target email */
 	mapi_object_init(&obj_targ_attach);
-	CreateAttach(&obj_target_message, &obj_targ_attach);
+	retval = CreateAttach(&obj_target_message, &obj_targ_attach);
 	mapitest_print_retval(mt, "CreateAttach");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1772,9 +1796,9 @@
 	lpProp[1].value.l = 0;
 	lpProp[2].ulPropTag = PR_ATTACH_FILENAME;
 	lpProp[2].value.lpszA = MT_MAIL_ATTACH2;
-	SetProps(&obj_targ_attach, lpProp, 3);
+	retval = SetProps(&obj_targ_attach, lpProp, 3);
 	mapitest_print_retval(mt, "SetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1783,20 +1807,20 @@
 
 	/* Step 15: Copy props from reference email attachment to target email attachment */
 	exclude = set_SPropTagArray(mt->mem_ctx, 0x0);
-	CopyTo(&obj_ref_attach, &obj_targ_attach, exclude, 0x0, &problem_count, &problems);
+	retval = CopyTo(&obj_ref_attach, &obj_targ_attach, exclude, 0x0, &problem_count, &problems);
 	MAPIFreeBuffer(exclude);
 	MAPIFreeBuffer(problems);
 	mapitest_print_retval_fmt(mt, "CopyTo", "(attachments)");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
 
 	/* Step 16: Check properties on both attachments are correct */
 	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME);
-	GetProps(&obj_ref_attach, SPropTagArray, &lpProps, &cValues);
+	retval = GetProps(&obj_ref_attach, SPropTagArray, &lpProps, &cValues);
 	mapitest_print_retval(mt, "GetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1813,9 +1837,9 @@
 		}
 	}	
 	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME);
-	GetProps(&obj_targ_attach, SPropTagArray, &lpProps, &cValues);
+	retval = GetProps(&obj_targ_attach, SPropTagArray, &lpProps, &cValues);
 	mapitest_print_retval(mt, "GetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1837,35 +1861,35 @@
         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, "[MT] Target Folder", NULL,
                               OPEN_IF_EXISTS, &obj_targ_folder);
 	mapitest_print_retval(mt, "CreateFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
 	lpProp[0].ulPropTag = PR_CONTAINER_CLASS;
 	lpProp[0].value.lpszA = "IPF.Journal";
-	SetProps(&obj_targ_folder, lpProp, 1);
+	retval = SetProps(&obj_targ_folder, lpProp, 1);
 	mapitest_print_retval(mt, "SetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
 
 	/* Copy properties from the test folder to the new folder */
 	exclude = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
-	CopyTo(&obj_ref_folder, &obj_targ_folder, exclude, 0x0, &problem_count, &problems);
+	retval = CopyTo(&obj_ref_folder, &obj_targ_folder, exclude, 0x0, &problem_count, &problems);
 	MAPIFreeBuffer(exclude);
 	MAPIFreeBuffer(problems);
 	mapitest_print_retval_fmt(mt, "CopyTo", "(folder)");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}	
 
 	/* Check that the properties on both folders are correct */
 	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS);
-	GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
+	retval = GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
 	mapitest_print_retval(mt, "GetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1893,9 +1917,9 @@
 		}
 	}
 	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS);
-	GetProps(&obj_targ_folder, SPropTagArray, &lpProps, &cValues);
+	retval = GetProps(&obj_targ_folder, SPropTagArray, &lpProps, &cValues);
 	mapitest_print_retval(mt, "GetProps");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -1988,25 +2012,26 @@
 	uint16_t		*propIDs;
 	bool 			ret = true;
 	int			i;
+	bool			result;
 
 	/* Log into the server */
 	mapi_object_init(&obj_store);
-	OpenMsgStore(mt->session, &obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	mapi_object_init(&obj_top_folder);
-	GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
+	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
 	mapitest_print_retval(mt, "GetDefaultFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
 
-	OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
+	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
 	mapitest_print_retval(mt, "OpenFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -2016,21 +2041,21 @@
         CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
 		     OPEN_IF_EXISTS, &obj_ref_folder);
 	mapitest_print_retval(mt, "CreateFolder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
 
 	mapi_object_init(&obj_ref_message);
-	mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
 	mapitest_print_retval(mt, "mapitest_common_message_create");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (!result) {
 		ret = false;
 		goto cleanup;
 	}
-	SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
+	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
 	mapitest_print_retval(mt, "SaveChangesMessage");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		goto cleanup;
 	}
@@ -2043,10 +2068,10 @@
 
 	/* GetIDsFromNames and map property types */
 	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	retval = GetIDsFromNames(&obj_ref_folder, nameid->count, 
+	retval = GetIDsFromNames(&obj_ref_message, nameid->count, 
 				 nameid->nameid, MAPI_CREATE, &SPropTagArray);
 	mapitest_print_retval(mt, "GetIDsFromNames");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
 		MAPIFreeBuffer(nameid);
 		goto cleanup;
@@ -2055,13 +2080,13 @@
 	mapi_nameid_SPropTagArray(nameid, SPropTagArray);
 	MAPIFreeBuffer(nameid);
 	
-	propID = (SPropTagArray->aulPropTag[0] & 0xFFFF0000) | PT_NULL;
+	propID = SPropTagArray->aulPropTag[0];
 	MAPIFreeBuffer(SPropTagArray);
 
 	nameid = mapi_nameid_new(mt->mem_ctx);
-	GetNamesFromIDs(&obj_ref_message, propID, &nameid->count, &nameid->nameid);
+	retval = GetNamesFromIDs(&obj_ref_message, propID, &nameid->count, &nameid->nameid);
 	mapitest_print_retval(mt, "GetNamesFromIDs");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(nameid);
 		ret = false;
 		goto cleanup;
@@ -2083,9 +2108,9 @@
 	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
 
 	mapi_nameid_custom_string_add(nameid, NAMEDPROP_NAME, PT_STRING8, PS_MAPI);
-	GetIDsFromNames(&obj_ref_folder, nameid->count, nameid->nameid, MAPI_CREATE, &SPropTagArray);
+	retval = GetIDsFromNames(&obj_ref_folder, nameid->count, nameid->nameid, MAPI_CREATE, &SPropTagArray);
 	mapitest_print_retval(mt, "GetIDsFromNames");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(nameid);
 		ret = false;
 		goto cleanup;
@@ -2099,11 +2124,10 @@
 
 	/* Builds an array of Name,ID pairs using QueryNamesFromIDs() */
 	nameid = mapi_nameid_new(mt->mem_ctx);
-	propIDs = talloc_zero(mt->mem_ctx, uint16_t);
-	QueryNamedProperties(&obj_ref_message, 0, NULL, &nameid->count, &propIDs, &nameid->nameid);
+	retval = QueryNamedProperties(&obj_ref_message, 0x1, NULL, &nameid->count, &propIDs, &nameid->nameid);
 	nameid->nameid = talloc_steal((TALLOC_CTX *)nameid, nameid->nameid);
 	mapitest_print_retval(mt, "QueryNamedProperties");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(nameid);
 		talloc_free(propIDs);
 		ret = false;
@@ -2126,8 +2150,8 @@
 		}
 
 		SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-		GetIDsFromNames(&obj_ref_folder, 1, &checknameid, 0, &SPropTagArray);
-		if (GetLastError() != MAPI_E_SUCCESS) {
+		retval = GetIDsFromNames(&obj_ref_folder, 1, &checknameid, 0, &SPropTagArray);
+		if (retval != MAPI_E_SUCCESS) {
 			mapitest_print_retval(mt, "GetIDsFromNames");
 			MAPIFreeBuffer(nameid);
 			MAPIFreeBuffer(SPropTagArray);
@@ -2162,8 +2186,8 @@
 	/* Iterates over IDs, and call GetNamesFromIDs() on each ID */
         for (i = 0; i < nameid->count; i++) {
 		nameid2 = mapi_nameid_new(mt->mem_ctx);
-		GetNamesFromIDs(&obj_ref_folder, ((propIDs[i] << 16) & 0xFFFF0000) | PT_NULL, &nameid2->count, &nameid2->nameid);
-		if (GetLastError() != MAPI_E_SUCCESS) {
+		retval = GetNamesFromIDs(&obj_ref_folder, (propIDs[i] << 16), &nameid2->count, &nameid2->nameid);
+		if (retval != MAPI_E_SUCCESS) {
 			mapitest_print_retval(mt, "GetNamesFromIDs");
 			MAPIFreeBuffer(nameid2);
 			ret = false;
@@ -2229,6 +2253,7 @@
 	MAPIFreeBuffer(propIDs);
 
  cleanup:
+	errno = 0;
 	/* Clean up */
 	DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
 		     DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
@@ -2275,18 +2300,22 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SPropValue	*lpProps;
 	uint32_t		cValues;
+	bool			result;
 
 	/* Step 1. Logon Private Mailbox */
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 	mapi_object_init(&obj_top_folder);
 	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
 	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
@@ -2295,15 +2324,15 @@
         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
                               OPEN_IF_EXISTS, &obj_ref_folder);
 	mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
 
 	/* Step 3: Create reference message */
 	mapi_object_init(&obj_ref_message);
-	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
 	mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (!result) {
 		return false;
 	}
 	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);

Modified: trunk/openchange/utils/mapitest/modules/module_oxctable.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxctable.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/mapitest/modules/module_oxctable.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -733,9 +733,7 @@
 	uint32_t		Numerator = 0;
 	uint32_t		Denominator = 0;
 	struct SBinary_short	collapseState;
-	uint32_t		bookmark;
 
-
 	/* Step 1. Logon */
 	if (! mapitest_common_setup(mt, &obj_htable, &count)) {
 		return false;
@@ -870,7 +868,7 @@
 	}
 
 	/* Restore the collapse state  */
-	SetCollapseState(&(obj_test_folder), &collapseState, &bookmark);
+	SetCollapseState(&(obj_test_folder), &collapseState);
 	mapitest_print_retval(mt, "SetCollapseState");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		ret = false;
@@ -892,14 +890,6 @@
 	}
 
  cleanup:
-	if (bookmark) {
-		FreeBookmark(&(obj_test_folder), bookmark);
-		mapitest_print_retval(mt, "FreeBookmark");
-		if (GetLastError() != MAPI_E_SUCCESS) {
-			ret = false;
-		}
-	}
-
 	/* Release */
 	mapi_object_release(&obj_htable);
 	mapi_object_release(&(obj_test_folder));

Modified: trunk/openchange/utils/openchangeclient.c
===================================================================
--- trunk/openchange/utils/openchangeclient.c	2009-04-14 14:39:21 UTC (rev 2698)
+++ trunk/openchange/utils/openchangeclient.c	2009-04-14 14:43:51 UTC (rev 2699)
@@ -1598,10 +1598,11 @@
 				printf("|   ");
 			}
 			newname = utf8tolinux(mem_ctx, name);
-			printf("|---+ %-15s : %-20s (Total: %u / Unread: %u - Container class: %s) [FID: 0x%"PRIx64"]\n", newname, comment, *total, *unread,
+			printf("|---+ %-15s : %-20s (Total: %u / Unread: %u - Container class: %s) [FID: 0x%.16"PRIx64"]\n", 
+			       newname, comment?comment:"", total?*total:0, unread?*unread:0,
 			       get_container_class(mem_ctx, parent, *fid), *fid);
 			MAPIFreeBuffer(newname);
-			if (*child) {
+			if (child && *child) {
 				ret = get_child_folders(mem_ctx, &obj_folder, *fid, count + 1);
 				if (ret == false) return ret;
 			}
@@ -1652,7 +1653,7 @@
 				printf("|   ");
 			}
 			newname = utf8tolinux(mem_ctx, name);
-			printf("|---+ %-15s [FID: 0x%"PRIx64"]\n", newname, *fid);
+			printf("|---+ %-15s [FID: 0x.16%"PRIx64"]\n", newname, *fid);
 			MAPIFreeBuffer(newname);
 			if (*child) {
 				ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1);
@@ -2451,6 +2452,9 @@
 	do {
 		count += 0x2;
 		retval = GetGALTable(session, SPropTagArray, &SRowSet, count, ulFlags);
+		if ((!SRowSet) || (!(SRowSet->aRow))) {
+			return false;
+		}
 		if (SRowSet->cRows) {
 			for (i = 0; i < SRowSet->cRows; i++) {
 				mapidump_PAB_entry(&SRowSet->aRow[i]);
@@ -3135,8 +3139,11 @@
 	}
 
 	if (opt_userlist) {
-		openchangeclient_userlist(mem_ctx, session);
-		exit (0);
+		if (false == openchangeclient_userlist(mem_ctx, session)) {
+			exit(1);
+		} else {
+			exit(0);
+		}
 	}
 
 	/**




More information about the Pkg-samba-maint mailing list