Welcome to MSDN Blogs Sign in | Join | Help

Error synchronizing message 'OBA Settings' after installing HF1 / SP1

This was an interesting issue I encountered when troubleshooting a Duet 1.0 client after installing HF1 (the update from the following article):

928954    Description of the Duet for Microsoft Office and SAP hotfix package: December 3, 2006
http://support.microsoft.com/default.aspx?scid=kb;EN-US;928954

Symptoms:

------------------------------------------

After installing Duet HF1, deployment fails and clients become "secondary" Duet clients. We also saw an error message created in Outlook’s "Sync Issues\Local Failures" folder with information similar to the following:

Error synchronizing message 'OBA Settings'

                [80070005-508-0-1380]

                You do not have sufficient permission to perform this operation on this object. See the folder contact or your system administrator

                Microsoft Exchange Server Information Store

 

Analysis:

-------------------------------------------

This synchronization error means we did not have permission to synchronize an item from Outlook’s offline cached store to the online Exchange Server store.

We identified that this failure is specific to attempting to create custom field (or Named Properties) in the Exchange store.  One of the key changes in Duet 1.0 HF1 is a change in how the Primary Machine IDs are handled and includes the addition of a new field, called PrimaryMachineIDV2, to Duet’s "OBA Settings" message which is stored in the hidden "OBAControlMessages" folder in the user's mailbox. After a successful install of HF1 the OBA Settings message should contain both a PrimaryMachineID field and PrimaryMachineIDV2 field. But, due to the failure we only saw the original PrimaryMachineID property on the "OBA Settings" message in the OBAControlMessages folder. If we looked at the "OBA Settings" message that ended up in the "Sync Issues\Local Failures" folder we could see both custom properties.

NOTE: The tool MAPI Editor can be used to see the fields on the OBAControlMessages folder.

Based on this information we were able to find a repro that didn't involve Duet. We did this by adding a custom field to a simple test item following these steps:

1. Open an existing test message from your inbox.

2. Enter design mode (Tools -> Forms -> Design This Form)

3. Select the "All Fields" page of the form.

4. Click the "New…"  button, provide a name for the new field, and click OK.

5. Type some text into the "Value" column for the new field.

6. Close and save the item.

If Outlook is in Online Mode (instead of cached mode) we will immediately get the error: "The Operation Failed" when trying to save the item. In cached mode we will get the error mentioned above in the "Sync Issues\Local Failures" folder.

This behavior is what we expect if a Deny permission has been set for the ability to "Create named properties in the information store" on the Exchange Server.  By default the "Everyone" group should be allowed to "Create named properties in the information store" at the Organizational level and this is required both for Outlook and applications like Duet to function properly.

Resolution:

-----------------------------------------------

In this case, no Deny was set, but we found that inheritance of the "Create named properties in the information store" permission had been broken just below the Organizational level.

At the bottom of the "Security" dialog we removed the check from the option labeled "Apply these permissions to objects and/or containers within this container only". This setting was blocking the required inheritance and once that was removed and the information store was restarted, the problem was resolved.

Here are the steps to remove the setting:

1. To check the permission at the Organization level we needed to enable the following registry key, which will display the "Security" tab on all Exchange objects:

                HKEY_CURRENT_USER\Software\Microsoft\Exchange\ExAdmin

                ShowSecurityPage: 0x1    (REG_DWORD)

                This is documented in:259221 - XADM: Security Tab Not Available on All Objects in System Manager

2. Right-click on the Organization object in Exchange System Manager and choose "Properties"

3. Select the "Security" tab.

4. Click on the "Advanced…" button.

5. Sort by the "Name" column.

6. Find the entries for "Everyone" and select the Permission labeled "Create named properties in the information store".

7. Click the "Edit" button.

8. Make sure the following checkbox at the bottom is not checked: "Apply these permissions to objects and/or containers within this container only"

9. After making the change, restart the Exchange information store service if you wish to refresh the permissions immediately.

Posted by waltwa | 1 Comments
Filed under:

Outlook Forms - Troubleshooting one-off behavior

Here are some suggestions to help identify and eliminate the cause of one-off behavior when working with Outlook forms.

1. While in design mode, make sure "Send Form Definition with Item" is not checked on the "Properties" page/tab of your custom form. If it is checked, uncheck it and re-publish the form. "Send Form Definition with Item" tells Outlook that you want all items based on this form to be one-offs.

2. Make sure you are creating items based on the Published form (i.e. File --> New --> Choose Form..), and not by doing Form --> "Run This Form" while in design mode. "Run This Form" is for quick testing only and will always create a one-off item. Also, items created by double-clicking an .oft file will always be one-offs.

3. If you are still getting one-off items and don't know why, comment out all of the VBScript code in the form, republish, and confirm that your item no longer becomes a one-off. If the one-off behavior continues then it is not related to your VBScript code in the form and you should look for other Add-ins, VBA code, etc. that could be modifying the items and causing one-off behvior.

4. Assuming the one-off behavior is related to your VBScript code, start adding back parts of your code until you identify which piece of your code results in the one-off behavior. Typical causes of one-off behavior are changes to the form definition such as adding a new user-defined field or modifying the controls. You may also want to add code to the Item_PropertyChange event in your form's VBScript to see when the MessageClass changes. Something like this:

Sub Item_PropertyChange(ByVal Name)
     Select Case Name
          Case "MessageClass"
               Msgbox "MessageClass Changed"
     End Select
End Sub

5. If you identify the code that causes the item to become a one-off, examine what the code does and search for workarounds.  There may be another way to do what you need to do that doesn't result in a one-off.

6. If you can't eliminate the cause of the one-off behavior due to your design requirements your last resort is to reset the MessageClass to your custom MessageClass in the Item_Write and/or Item_PropertyChange events. The custom MessageClass will tell Outlook to use the form definition from the published form and ignore the internal one-off form definition, which results in your form being "trusted" again. If you are concerned about the extra size of the items, since the one-off form definition is still stored with the item, you'll need to remove the form definition properties as described on Steve's blog here.

Additional Resources:

290657 Description of form definitions and one-off forms in Outlook 2002
http://support.microsoft.com/default.aspx?scid=kb;EN-US;290657
207913 Why Outlook displays a security warning message or does not run VBScript Code when you open an item
http://support.microsoft.com/default.aspx?scid=kb;EN-US;207913
287530 Frequently asked questions about custom forms and Outlook solutions
http://support.microsoft.com/default.aspx?scid=kb;EN-US;287530

 

Posted by waltwa | 0 Comments

DST: CDO 1.21 issue related to having Outlook installed on Exchange Server

SYMPTOMS:

========================

I recently assisted with a CDO 1.21 DST related issue where custom date field values set programmatically with CDO 1.21 (after the DST change on 3/11) were off by 1 hour. The CDO 1.21 code was running in a Scripting Agent on an Exchange 5.5 Server that had all of the DST updates installed.

 

We could see that the correct DST build of CDO.DLL was in the System32 directory, and by searching HKCR for “MAPI.Session” we found the CLSID for CDO 1.21 and confirmed that our InProcServer32 value was pointing to the correct build of CDO.DLL.

 

But the problem still happened and was easily reproducible with a test user by running the simple CDO 1.21 sample code below from VB6. To see the incorrect date value we would login to Outlook on a client machine as the same test user and add our test date field “DateTest” to the current view using Outlook’s Field Chooser. Once added, we could see that the value of our custom Date field was off by 1 hour.

 

Sample CDO 1.21 code to create and populate an Outlook date property:

-------------------------------------------------------------------------------------------------

Sub CDO_AddTestUserProperty()

    Dim objSession As MAPI.Session
    Dim objMessage As MAPI.Message
    Dim oFields As MAPI.Fields
    Const CdoPropSetID = "2903020000000000C000000000000046"
   
    Set objSession = New MAPI.Session
    objSession.Logon , , , True, , , "MyExServer" & vbLf & "testuser@address.com"
   
    'Get the most recent item in the Inbox of testuser
    Set objMessage = objSession.Inbox.Messages.GetLast
    Set oFields = objMessage.Fields
   
    Dim dateFieldValue As Date
    strFieldName = "DateTest"
    dateFieldValue = Now()
    Debug.Print dateFieldValue
   
    Set oField = oFields.Add(strFieldName, vbDate, dateFieldValue, CdoPropSetID)
    objMessage.Update
   
    Set oField = Nothing
    Set oFields = Nothing
    Set objMessage = Nothing
    objSession.Logoff
    Set objSession = Nothing
  
End Sub


 

PROBLEM:

===============================

It turned out that Outlook 2000 was installed on this Exchange 5.5 server (which is a bad idea) and the un-patched Outlook build of CDO.DLL kept being loaded instead of the patched version for Exchange.  

 

RESOLUTION:

===============================

We were able to resolve the immediate issue by following these steps:

1.       Uninstall Outlook’s Collaboration Data Objects component.

1.       Make sure Outlook is closed on the server

2.       Control Panel --> Add or Remove Programs

3.       Select your install of Office/Outlook (i.e. “Microsoft Office 2000” or “Microsoft Outlook 2000”)

4.       Click “Change”

5.       Click “Add or Remove Features”

6.       Expand the list of components under “Microsoft Outlook for Windows”

7.       Click on the down arrow next to “Collaboration Data Objects”

8.       Select “Not Available” (it should appear as a red X)

9.       Click “Update Now” and complete the steps.

2.       Re-register the correct version of CDO.DLL in the System32 directory using Regsvr32.exe.

 

 

For some other CDO 1.21 DST related issues see: FYI: DST 2007 exposes those who misuse CDO 1.21

 

Posted by waltwa | 1 Comments
Filed under: ,

Finding appointments within a specific time frame

When programmatically searching for Appointments within a given time frame, it may seem logical to search for items that Start at the Start of your time frame and End at the End of your time frame. For example using a restriction similar to this with the Outlook Object Model:

          [Start] >= MyStartDate AND [End] <= MyEndDate

But, what does this actually do?  It will only find items that Start AND End within your time frame. This may sound correct at first and may be exactly what you want, but usually this is not what people want to do since it will not find any appointments that overlap your Start and/or End times 

Here is a simple diagram to help explain why this is important. The query above will find the appointment in this scenario (where S = Start & E = End of my time frame on the timeline “------“ )

 

------------------S------------------------------E--------------------------

                                        |---Appt---|

 

 

But it will not find these appointments that overlap the Start or End of the time frame:

------------------S------------------------------E--------------------------

                                      |-------------Appt_1----------|

        |--------Appt_2-----------|

  |----------------------------Appt_3---------------------------|

 

 

To reliably find all appointments that occur within a time frame you need to use a query that looks for appointments that Start before the End of your time frame:

 

------------------S------------------------------E--------------------------

          ß----------------------------------------|

 

And End after the start of your time frame.

 

------------------S------------------------------E--------------------------

                           |---------------------------------------------à

 

 

Using this logic will return all of the Appointments that occur within the specified time frame.

Here is the updated restriction:

          [Start] <= MyEndDate AND [End] >= MyStartDate

This is what it looks like with real dates:

[Start] <= '3/19/2007 12:00 AM' AND [End] >= '3/14/2007 12:00 AM'

Here are some samples:

 

Outlook Object Model (OOM) VBA sample:

==================================

Sub FindApptsInTimeFrame()

    myStart = Format(
Date, "mm/dd/yyyy hh:mm AMPM")
    myEnd = DateAdd(
"d", 5, myStart)
    myEnd = Format(myEnd,
"mm/dd/yyyy hh:mm AMPM")
    Debug.Print
"Start:", myStart
    Debug.Print
"End:", myEnd
   
   
Set oSession = Application.Session
   
Set oCalendar = oSession.GetDefaultFolder(olFolderCalendar)
   
Set oItems = oCalendar.Items
   
    oItems.IncludeRecurrences =
True
    oItems.Sort "[Start]"
   
    strRestriction =
"[Start] <= '" & myEnd _
    &
"' AND [End] >= '" & myStart & "'"
    Debug.Print strRestriction
   
   
Set oResitems = oItems.Restrict(strRestriction)
    oResitems.Sort
"[Start]"
   
   
For Each oAppt In oResitems
        Debug.Print oAppt.Start, oAppt.Subject
   
Next
   
End Sub

 

 

CDO 1.21 sample:

==================================

Sub CDOGetApptsInTimeFrame()

    'Requires a Reference to Microsoft CDO version 1.21.
    Dim oSession As MAPI.Session
    Dim oCalendar As MAPI.FOLDER
    Dim oAppt As MAPI.AppointmentItem
    Dim oRecurPat As MAPI.RecurrencePattern
  
    Set oSession = New MAPI.Session
   
    oSession.Logon
    Set oCalendar = oSession.GetDefaultFolder(CdoDefaultFolderCalendar)
    Set oMsgColl = oCalendar.Messages
   
    Set oMsgFilter = oMsgColl.Filter
    oMsgFilter.Fields.Add CdoPR_START_DATE, "3/19/07"
    oMsgFilter.Fields.Add CdoPR_END_DATE, "3/14/07"
    Set oAppt = oMsgColl.GetFirst
   
    Do While (Not oAppt Is Nothing)
        Debug.Print oAppt.StartTime, oAppt.Subject
        Set oAppt = oMsgColl.GetNext
    Loop

End
Sub

 

WebDAV Sample:

==================================

Sub GetApptsInTimeFrame()

    Const SERVERNAME = "ExchangeServer"
    Const MAILBOXNAME = "TestUser"
    Const UserName = "" '"TestDomain\TestUser"
    Const Password = "" '"TestPassword"
    Const FOLDER = "Calendar/"

    sURL = "http://" & SERVERNAME & "/exchange/" & MAILBOXNAME & "/" & FOLDER

    sStartTime = "2007-03-14T00:00:00.000Z"
    sEndTime = "2007-03-19T00:00:00.000Z"

    Debug.Print sURL
    Dim strPropReq As String

    strPropReq = "<?xml version='1.0'?>" & _
        "<d:searchrequest" & _
        " xmlns:d=""DAV:""" & _
        " xmlns:cal=""urn:schemas:calendar:"" >"

    strPropReq = strPropReq & "<d:sql> SELECT ""DAV:href"", " & _
        " ""urn:schemas:calendar:dtstart"", " & _
        " ""urn:schemas:calendar:dtend"" " & _
        " FROM Scope('SHALLOW TRAVERSAL OF """ & sURL & """ ')" & _
        "WHERE ""DAV:contentclass"" = 'urn:content-classes:appointment'" & _
        "AND ""urn:schemas:calendar:dtstart"" &lt;= " & _
        "CAST(""" & sEndTime & """ AS ""dateTime.tz"")" & _
        "AND ""urn:schemas:calendar:dtend"" &gt;= " & _
        "CAST(""" & sStartTime & """ AS ""dateTime.tz"")"

    strPropReq = strPropReq & "</></>"

    Dim oXMLHttp As XMLHTTPRequest
    Set oXMLHttp = CreateObject("Microsoft.XMLHTTP")
    With oXMLHttp
        .Open "SEARCH", sURL, False, UserName, Password
        .setRequestHeader "Content-type:", "text/xml"
        .setRequestHeader "Depth", "1,noroot"
        .Send (strPropReq)
        Debug.Print .Status
        strOutPutFile = Environ("USERPROFILE") & "\Desktop\XMLOutput.xml"
        Open strOutPutFile For Output As #1
            Print #1, .responseText
        Close #1
    End With
  
End Sub

 

 

VB.NET Sample:

==================================

Imports Outlook = Microsoft.Office.Interop.Outlook
Imports System.Runtime.InteropServices


Public
Class Form1
    ' NOTE: Requires a COM reference to the Microsoft Outloook 12.0 Object Library
    Private Sub cmdGetApptsInTimeFrame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdGetAppointments.Click
        Dim OL As Outlook.Application
        OL = New Outlook.Application()


        Dim myStart As String = Format(#6/1/2008#, "MM/dd/yyyy hh:mm tt")
        Dim myEnd As String = Format(#7/1/2008#, "MM/dd/yyyy hh:mm tt")
        Debug.Print("Looking for appointments between " & myStart & " and " & myEnd)


        Dim oSession As Outlook.NameSpace = OL.Session()
        Dim oCalendar As Outlook.MAPIFolder = oSession.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar)
        Dim oItems As Outlook.Items = oCalendar.Items()


        oItems.IncludeRecurrences = True
        oItems.Sort("[Start]")


        Dim strRestriction As String = "[Start] <= '" & myEnd _
                            & "' AND [End] >= '" & myStart & "'"
        Debug.Print(strRestriction)


        Dim oResitems As Outlook.Items = oItems.Restrict(strRestriction)
        oResitems.Sort("[Start]")

        Dim oAppt As Outlook.AppointmentItem
        oAppt = Nothing
        For Each oAppt In oResitems
            Debug.Print(oAppt.Start().ToString & " - " & oAppt.Subject().ToString)
        Next

        ' Clean up
        If Not oAppt Is Nothing Then Marshal.ReleaseComObject(oAppt)
        oAppt = Nothing
        If Not oResitems Is Nothing Then Marshal.ReleaseComObject(oResitems)
        oResitems = Nothing
        If Not oItems Is Nothing Then Marshal.ReleaseComObject(oItems)
        oItems = Nothing
        If Not oCalendar Is Nothing Then Marshal.ReleaseComObject(oCalendar)
        oCalendar = Nothing
        If Not oSession Is Nothing Then Marshal.ReleaseComObject(oSession)
        oSession = Nothing
        If Not OL Is Nothing Then Marshal.ReleaseComObject(OL)
        OL = Nothing


    End Sub


End
Class

 
Page view tracker