InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Exchange library updated

Another maintenance update with a bunch of bugfixes...

Changelog

  • Fixed bugs in the ItemCollection.Add, ItemCollection<T>.Add and FolderCollection.Add method
  • Fixed NullReferenceException bugs in the ItemBase constructors
  • New Interface IKeyedCollection 
  • Contact EmailAddresses and PhysicalAddresses are now of type IKeyedCollection
  • The Item Class and all its descendents now have an Url property (delegated from BaseItem
  • Fixed a bug in the ContactItem class regarding the population of the PhysicalAddress list
  • Fixes a bug in the search method, which occured when the number of items in the search query where an exact multiple of the pagesize
  • New class SearchResult, which is used in the Methods.Search method. It contains the result items of the search, as well as the total number of items of the search.

Downloads

InfiniTec.Exchange_Release.zip (453,287 Bytes)
Binaries (Release build with debug symbols) with a strong-name
InfiniTec.Exchange.zip (1,725,519 Bytes)
Source, Documentation and Example application

Technorati:

Posted by Henning Krause on Thursday, February 15, 2007 12:00 AM, last modified on Thursday, February 15, 2007 12:00 PM
Permalink | Post RSSRSS comment feed

Antivirus software breaks .NET application [Updated]

Since a few days I got an exception saying

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I got this exception while debugging my InfiniTec.Exchange libray, which does a lot web requests using the HttpWebRequest class. I though it was some sort of multi-threading issue on my side, since I use my InfiniTec.Threading library in that project. Furthermore, I thought it could have something to do with the fact that I now have dual core processor....

Well, turned out that it was all wrong. It was my virus scanner.... Which is rather curious, because all I had activated was the filesystem scanner - network scanning was deactivated... But when I deinstalled it, the symptoms disappeared instantly.

Surprisingly, this issue has been around for a while now - I found a posting in a Microsoft forum dated February 28, 2006 - almost a year old (The forum post can be found here)

Anyway - now I have to find a new virus scanner which doesn't break .NET applications.

Update

Wow - that was fast. I opened a support incident at Eset, the creators of NOD32, and within one hour, they responded to my question.

The solution is to reinstall NOD32, but disable the IMON feature all together. The support technician told me that this feature will be removed in the next version completely, because of this very reason. So, no need to get another virus scanner.


Technorati:

Posted by Henning Krause on Tuesday, February 13, 2007 12:00 AM, last modified on Tuesday, February 13, 2007 12:00 PM
Permalink | Post RSSRSS comment feed

Enumerating attachments in a users inbox folder

One reader recently asked how he could use my InfiniTec.Exchange library to scan the mails in the inbox folder of a users mailbox for attachments. Here is an example:

    1 classProgram

    2 {

    3     staticvoid Main(string[] args)

    4     {

    5         ServicePointManager.ServerCertificateValidationCallback = delegate { returntrue; };

    6 

    7         using (Connection connection = newConnection("server", ConnectionProtocol.Secure, newCredential("username", "password", AuthenticationType.Ntlm)))

    8         {

    9             Mailbox mbx;

   10 

   11             Console.Out.WriteLine("Refreshing mailbox....");

   12             mbx = newMailbox("exchange/useralias", connection);

   13             mbx.Refresh();

   14 

   15             ItemCollection<MessageItem> children = mbx.Inbox.ChildItems;

   16 

   17             children.Constraints +=

   18                 string.Format("AND Cast(\"{0}\" as \"boolean\") = true", WellknownProperties.Item.HasAttachments);

   19 

   20             Console.Out.WriteLine("Enumerating child items with attachments in inbox...");

   21 

   22             children.Refresh();

   23 

   24             Console.Out.WriteLine("Found {0} items", children.Count);

   25 

   26             foreach (MessageItem item in children)

   27             {

   28                 Console.Out.WriteLine("Processing " + item.Subject);

   29                 item.Attachments.Refresh();

   30 

   31                 foreach (Attachment attachment in item.Attachments)

   32                 {

   33                     Console.Out.WriteLine("\t{0} ({1}, {2}, {3} bytes)", attachment.Name, attachment.MimeType, attachment.ContentDisposition, attachment.Size);

   34                 }

   35             }

   36 

   37             Console.Out.WriteLine("Finished");

   38             Console.ReadLine();

   39         }

   40     }

   41 }

This is a console application, so you'll just have to replace the main class of a newly created console application with this code. Then, add a reference to my library (At least version 0.99.2).

The most tricky part here clearly is the modification of the constraints in line 17; The default constraint is initialized with this value:

    1 _Searcher.Constraints = string.Format(CultureInfo.InvariantCulture, "(\"{0}\" = false) ", WellknownProperties.Dav.IsFolder);

This restricts the result set to child elements which are not folders. To restrict the result set further, you can just append additional constraints with an "AND". The full constraint being used here is this:

    1 ("DAV:isfolder" = false) AND Cast("http://schemas.microsoft.com/mapi/proptag/xe1b000b" as "boolean") = true

You'll probably wonder why I used the MAPI property 0xe1b00b instead of the urn:schemas:httpmail:hasattachment property. In the past, I've found the latter property not very reliable - it was false, even though a message had an attachment. And since I'm using a non-standard property here, I have to cast it to boolean to make the request work. If you don't do this, you'll end up with a Bad Request error from exchange.


Technorati:

Posted by Henning Krause on Sunday, February 11, 2007 12:00 AM, last modified on Monday, November 29, 2010 8:50 PM
Permalink | Post RSSRSS comment feed

Exchange library updated again

This is a maintenance update with a number of bugfixes and a few new features to ease access to child items and folders: The Folder classes now expose two properties, ChildItems and ChildFolders, which provide access to the child elements of the folder. Both, the ItemCollection and the FolderCollection, have a Refresh operation, which must be called before the child elements can be accessed. Furthermore, both classes have a Constraints property, which restricts the items enumerated by the Refresh operation. Here is a class diagram of the new classes:


Class diagram of the ItemCollection and FolderCollection classes (click to enlarge)

I will post an example tomorrow on how to use these new methods to enumerate the attachments of all items in the inbox folder of a users mailbox.

Changelog for this version

  • Many minor changes to comply with static code-analysis
  • Fixed an bug with the Mailbox class
  • Fixed several bugs in the Initialize() method of the typed item classes
  • New class FolderCollection, which provides access to subfolders of an item.
  • New class ItemCollection<ItemType>, which provide access to child elements of a folder
  • The Folder<ItemType> now have a property ChildItems
  • The Folder classes now has a property ChildFolders;
  • The Folder class now has a property ChildItems.
  • The Attachment.Name property is now more accurate
  • All Item and Folder classes now expose a method ResetSecurityDescriptor and ResetSecurityDescriptorAsync, which does exactly that.
  • The Contact, CalendarItem now sets the content class correctly on new items
  • The Find Method on the Searcher and Searcher<ItemType> has been renamed to FindAll
  • The FindAsync Method on the Searcher and Searcher<ItemType> has been renamed to FindAllAsync
  • New method FindPage on the Searcher and Searcher<ItemType> 
  • New method FindPageAsync on the Searcher and Searcher<ItemType> 
  • The constructor of FolderSecurity is now internal
  • Constructor in ContactEmailAddress now saves the displayname correctly
  • Upgraded the threading library to version 2.5.2. This fixes a bug with all the synchronous methods blocking in a deadlock.

Downloads

InfiniTec.Exchange.zip (1,858,836 Bytes)
Binaries, Source, Documentation and Example application of version 0.99.2

Technorati:

Posted by Henning Krause on Saturday, February 10, 2007 12:00 AM, last modified on Saturday, February 10, 2007 12:00 PM
Permalink | Post RSSRSS comment feed

Fresh layout

I've just uploaded this new layout... didn't like the old one any longer. There are a few bugs with this design an IE 6... I will fix them in the next few days. But Firefox 2 and Internet Explorer 7 are ok.

Hope you like it.


Technorati:

Posted by Henning Krause on Saturday, February 3, 2007 12:00 AM, last modified on Saturday, February 3, 2007 12:00 PM
Permalink | Post RSSRSS comment feed

How to use applications settings from an event sink

A while ago, I posted an article on how to create managed event sinks. This is a follow-up on that article covering application settings.

Normally, application files are named after the .EXE file which hosts a managed component: An .exe file called myapplication.exe has a configuration file of myapplication.exe.config which resides in the same directory as the myapplication.exe file.

There are two issues when dealing with Exchange event sinks: First, the working directory is %systemroot%\system32. And second, the executable host is svchost.exe. With .NET 1.1, the only option here was to create a svchost.exe.config in %systemroot%\system32. Bad days for those with more than one managed COM+ application on one server.

Since .NET 2.0, the world has become a better place. At least, in this scenario. You can now place your configuration data in a file named application.config and place that file into the folder where your COM+ application resides. You must then create an xml file in that directory with the name application.manifest and the following content:

    1 <?xmlversion="1.0"encoding="UTF-8"standalone="yes"?>

    2 <assemblyxmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="1.0" />

Now, you must reconfigure your COM+ application to set the working directory to the directory where your COM+ DLLs reside: Open Component Services, navigate to your applicatoin and open the properties.


Activation propertysheet in component services (click to enlarge)
In the text box Application Root Directory, specify the path your event sink.

That's all.


Technorati:

Posted by Henning Krause on Wednesday, January 31, 2007 12:00 AM, last modified on Wednesday, January 31, 2007 12:00 PM
Permalink | Post RSSRSS comment feed

Minor update on my multi threading library

Here is a small update on my multi threading framework. After some background reading on how the BackgroundWorker synchronizes event invocations, I decided to implement a similar functionality into my framework as well.

UI Synchronization

The Background worker allows updates to the UI without the need to call Control.Invoke. It does this by utilizing the SynchronizationContext class (A good article on this topic can be found here on CodeProject).

This version of my multithreading framework also uses this mechanism to call the Completed, ProgressChanged and Error events. And best of all, this is agnostic to the UI framework used: It works with Windows Forms as well as Windows Presentation Foundation.

Locking inside an asynchronous method

Another issue you should know when working with my framework is this: You must never return a NestedOperation or a ParallelOperaton from within a region protected by either a Monitor (explicitly or via the lock (SyncLock in Visual Basic) keyword) or a Mutex. This is because these synchronization primitives are thread-dependent. Use a Semaphore instead.

Consider the following code:

    1 if (_ConfigurationNamingContext == null)

    2 {

    3     lock (_ConfigurationNamingContextLock)

    4     {

    5         if (_ConfigurationNamingContext == null)

    6         {

    7             using (

    8                 AsyncOperation<int, Item> operation =

    9                     ActiveDirectoryEntry.GetConfigurationNamingContext(_Connection.ActiveDirectoryConnection)

   10                 )

   11             {

   12                 yieldreturnnewNestedOperation(operation, false);

   13                 _ConfigurationNamingContext = operation.Result;

   14             }

   15         }

   16     }

   17 }

The code from line 3 through line 16 are protected by a Monitor to ensure that the code is not executed twice (which could hapen when the method is called in parellel). In line 12, a nested operation is executed, doing the hard work. But when the displayed method is resumed in line 13, the code may run on a different thread than before. This will cause the Monitor.Exit (which is implicitly called in line 16) to throw a SynchronizationLockException.

To avoid this, use a Semaphore instead.

Create a semaphore with a maximum count of 1:

    1 privatestaticSemaphore _ConfigurationNamingContextLock = newSemaphore(1, 1);

Now, use the semaphore as outlined here:

    1 if (_ConfigurationNamingContext == null)

    2 {

    3     try

    4     {

    5         _ConfigurationNamingContextLock.WaitOne();

    6 

    7         if (_ConfigurationNamingContext == null)

    8         {

    9             using (

   10                 AsyncOperation<int, Item> operation =

   11                     ActiveDirectoryEntry.GetConfigurationNamingContext(_Connection.ActiveDirectoryConnection)

   12                 )

   13             {

   14                 yieldreturnnewNestedOperation(operation, false);

   15                 _ConfigurationNamingContext = operation.Result;

   16             }

   17         }

   18     }

   19     finally

   20     {

   21         _ConfigurationNamingContextLock.Release();

   22     }

   23 }

It's not as neat as using the lock keyword, but it works :-)

Change log for version 2.5.1

  • Events are now called via a SynchronizationContext. This makes the usage of Invoke() methods unnecessary when reporting progress to Windows Forms or WPF applications.

Downloads

InfiniTec.Threading.zip (277,385 Bytes)
Source, Binaries and Documentation for version 2.5.1

Technorati:

Posted by Henning Krause on Sunday, January 28, 2007 12:00 AM, last modified on Sunday, January 28, 2007 12:00 PM
Permalink | Post RSSRSS comment feed

Minor update on the Exchange library

This is a minor update on the InfiniTec.Exchange library due to the issues found within the multi threading library today. The Example application has also been updated accordingly.

Change log

  • Fixed a multi-threading bug in the ActiveDirectoryResolver class.
  • Upgraded the threading library to version 2.5.1. It's no longer necessary to call Control.Invoke() methods when reporting progress to the UI.

Downloads

InfiniTec.Exchange.zip (1,660,202 Bytes)
Source, binaries, documentation and example application for 0.99.1

Technorati:

Posted by Henning Krause on Sunday, January 28, 2007 12:00 AM, last modified on Sunday, January 28, 2007 12:00 PM
Permalink | Post RSSRSS comment feed

Extreme threading...

This is a major upgrade for my multithreading library. If you are not familiar about what this library does, please read the other articles in this section.

New in this release are parallel operations: You can return ParallelOperation from within an asynchronous operation. The execution of the current operation will be suspended until all nested operations are executed. Additionally, a maximum number of parallel executions can be passed along, which allows you to further control the execution of the nested operations. And of course, you can select which exceptions you want to catch on each of the nested operation.

I'm primarily using these parallel operations in my InfiniTec.Exchange library to speed up lookups to Active Directory and the Exchange store. For example, when looking up members of a distribution list, I get a bunch of references, either to user in Active Directory, or references to contacts on an Exchange folder. Take a look at this method:

    1 privateIEnumerable<OperationAction> RefreshInternal(AsyncOperation baseOperation)

    2 {

    3     Dictionary<NestedOperation,EntryIdReference> operations;

    4     ExchangeStoreReference entryId;

    5     List<IAddressListEntry> result;

    6 

    7     _UnresolvableEntries = 0;

    8 

    9     yieldreturnnewNestedOperation(baseOperation, false);

   10 

   11 

   12     if (!_ResolveMembers)

   13     {

   14         _ResolveMembers = true;

   15         yieldbreak;

   16     }

   17 

   18     entryId = newExchangeStoreReference(Properties.GetProperty<byte[]>(WellknownProperties.Item.EntryId).Value);

   19 

   20     operations = newDictionary<NestedOperation, EntryIdReference>();

   21 

   22     foreach (EntryIdReference reference in DecodeMembers(entryId.StoreId))

   23     {

   24         operations.Add(

   25             newNestedOperation(reference.GetResolveOperation(BaseItem.Connection), false),

   26             reference);

   27     }

   28 

   29     yieldreturnnewParallelOperations(operations.Keys, 5);

   30 

   31     result = newList<IAddressListEntry>();

   32 

   33     foreach (KeyValuePair<NestedOperation, EntryIdReference> entry in operations)

   34     {

   35         AsyncOperation<IAddressListEntry> operation;

   36 

   37         operation = (AsyncOperation<IAddressListEntry>) entry.Key.Operation;

   38         if (operation.StatusInformation != null)

   39         {

   40             result.Add(operation.StatusInformation);

   41         }

   42         else

   43         {

   44             _UnresolvableEntries++;

   45         }

   46     }

   47 

   48     _Members = result.AsReadOnly();

   49 }

In Line 9, I call the original refresh method, using the NestedOperation operation action. After that, I decode those member entries in lines 22 to 27 and put them in a dictionary. The interesting thing happens in line 29. At this point, I return a ParallelOperation operation action with a list of those member references. Additionally, a maximum number of concurrent operations of 5 is specified.

When the method resumes it's operation in line 31, all nested operations have been completed.

Changelog

  • Introduced parallel operations: Using the ParallelOperations action, you can now return multiple nested operations which will be executed in parallel. Once all nested operations are finished, the parent operation is resumed.
  • The AsyncOperation<StatusType> can now also be used to return a result. Just return an OperationResult<StatusType> in the enumerator.
  • Fixed a bug with nested operations and exception handling

Downloads

InfiniTec.Threading.zip (268,722 Bytes)
Version 2.5. Includes source, binaries and documentation

Technorati:

Posted by Henning Krause on Saturday, January 27, 2007 12:00 AM, last modified on Monday, November 29, 2010 8:27 PM
Permalink | Post RSSRSS comment feed

Exchange library updated again

Again, an update on my exchange library.

This update fixes a bunch of issues (many thanks to Mr. Heinen for his input), and some new features, as listed in the change log below.

Messing with distribution lists

This release adds experimental support for distribution lists in exchange folder. But instead of relying on the OWA commands to decode them (as described here), I decoded the binary member properties. Turned out, that the entry ids contained in that folder can be translated into a permannt url.

This release allows only read-only access to the member list.

The Members property of the DistributionList class returns a list of IAddressEntry instances. This interface currently exposes only one property, the name of the element. The element is one of the following:

  • User - A reference to an Active Directory user.
  • Contact - A reference to an Active Directory contact
  • Group - A reference to an Active Directory group
  • DistributionList - A nested distribution list
  • EmailAddress - A so called One-Off member. This is just name with an email address.

Calendar permissions

When giving other people access to a calendar folder on a mailbox, it's not enough, to set those permissions on the calendar folder itself. The trustee must be given access to the local free busy data as well (This folder resides in the NON_IPM_SUBTREE/FreeBusy Data folder). The Mailbox class now returns a special folder instance for the mailbox.Calendar folder which handles this. More information on this topic can be found here.

Changelog for version 0.99

  • Connection class now implements IDisposable (explicit implementation) and has a Close() method. Call either of these methods to close the underlying active directory connection.
  • Optimized the resolution of mailbox urls.
  • Added DistributionList class, which provides read-only access to the members of a distribution list stored on an Exchange folder.
  • Added new CalendarFolder class, which is returned from the Mailbox class. This class propagates security changes made to the folder to the local free/busy folder, as described in KB (237924). See http://support.microsoft.com/kb/237924/en-us.
  • Fixed several NullReferenceExceptions
  • Fixed some issues with TaskItem and CalendarItem
  • Added some validation logic to TaskItem and CalendarItem
  • Added some auto-calculations to the TaskItem an CalendarItem (e.g. End = Start + Duration and so on, modifying IsAllDayEvent accordingly)
  • Added the GetContent and SetContent functionality to the Item class
  • Fixed a bug with the PUT method (and the SetContent functionality as well)
  • Fixed a bug with setting the Free/Busy property on CalendarItems
  • Fixed a bug in the save method which occured when the Save operation was called when no properties were changed.
  • The SetContent and Attachment.Add methods now require a content type to be specified
  • New Class WellknownContentTypes, which has some definitions of common content types.
  • Renamed the FreeBusyType OOF to OutOfOffice
  • Removed the SearchScope property from the SearcherBase class, as it was redundant. Use the Scope property instead.

Downloads

InfiniTec.Exchange_0.99.zip (2,023,427 Bytes)
All-in-wonder package, including source, binaries, documentation and example application.

Technorati:

Posted by Henning Krause on Saturday, January 27, 2007 12:00 AM, last modified on Saturday, January 27, 2007 12:00 PM
Permalink | Post RSSRSS comment feed