[ExcludeFromCodeCoverage] — Oh, the Pain!

If you make use of Visual Studio’s built-in code coverage feature, you are probably aware of the existence of the ExcludeFromCodeCoverage attribute. This attribute, when decorating a piece of code, will exclude that code from all code coverage instrumentation. The end effect of its use is the total exclusion of the method or type from the code coverage report we all are treated with at the conclusion of the testing session.

While it does its job, its use is a bit intrusive, especially since all we are doing is appeasing a specific testing tool. It would be nice if there was some sort of coverage configuration file one could edit in order to exclude specific code elements, but no such thing exists in Visual Studio’s code coverage system. Perhaps the visibility of such things is a benefit, because it makes the fact that the code isn’t being counted in the coverage metric blatantly obvious. But it’s only obvious if you are actually looking at that code and not just a coverage report along with some top-level project files. Plus, the assumption is, is that you are a competent individual who wouldn’t be itching to exclude something from coverage analysis unless you had a good reason to do so.

With all that said, it’s my opinion the process of realizing code coverage exclusion through the use of the ExcludeFromCodeCoverage attribute is clumsy and not ideal. This gets further exacerbated when we want to go beyond the type-level and exclude an entire namespace from code coverage. That isn’t an option with the ExcludeFromCodeCoverage attribute; you are limited to types, methods, properties, indexers, and events.

Well there is a better way. Using PostSharp, we can devise our own scheme of coverage exclusion by creating a very simple aspect that will allow us to target entire namespaces if we wish, as well as smaller items in scope, all without having to touch any of the code being excluded.

The DisableCoverage Aspect

The aspect we’ll be designing here will act as a vehicle for the efficient delivery of our adored ExcludeFromCodeCoverage attribute to the intended pieces of code we wish to exclude. We will then make use of PostSharp’s multicasting feature in order to steer this vehicle.

The code for the aspect can be found, and, as you can see, it’s extremely simple:

[Serializable]
[AttributeUsage(AttributeTargets.Assembly)]
[MulticastAttributeUsage(MulticastTargets.Class | MulticastTargets.Struct)]
[ProvideAspectRole(StandardRoles.PerformanceInstrumentation)]
public sealed class DisableCoverageAttribute : TypeLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        Type disabledType = (Type) targetElement;

        CustomAttributeIntroductionAspect introducedExclusion
            = new CustomAttributeIntroductionAspect(
                new ObjectConstruction(typeof (ExcludeFromCodeCoverageAttribute)));

        return new[] {new AspectInstance(disabledType, introducedExclusion)};
    }
}

All this aspect does is introduce the ExcludeFromCodeCoverage attribute into all applied targets. I have the AttributeUsage of this attribute set to target only assemblies because using this aspect in any other way defeats its entire purpose. The MulticastAttributeUsage of this attribute, on the other hand, is targeting classes and structs. The reason I do this is so that the ExcludeFromCodeCoverage attributes we’re introducing are done so at the type-level, which is the most granular level of scope I wish to specify when using this aspect.

Let’s say you have a namespace named Bad.Tomato containing a bunch of classes you wish to exclude from coverage. To use our aspect in order to realize this wish, you would open up your project’s AssemblyInfo.cs file and add the following assembly-level attribute declaration:

[assembly: DisableCoverage(AttributeTargetTypes="Bad.Tomato.*")]

This will then result in the exclusion of all code elements belonging to the Bad.Tomato namespace from coverage analysis.

Maybe targeting a whole namespace is a bit too drastic for your tastes…maybe we only want to exclude a single class named Bad.Tomato.Farmer. Ok…then:

[assembly: DisableCoverage(AttributeTargetTypes="Bad.Tomato.Farmer")]

Hooray, no more ExcludeFromCodeCoverage! If you want to get even more granular, you can, and I believe you can make use of regular expressions here as well.

 

Note: The following article is more an exploratory piece than anything; using any of the code or the approaches discussed in a production setting is not recommended. This article is meant to be as part of a build-up for an ultimate conclusion on the matter.

The Problem

In my previous article on the topic, I got into how we can extend PostSharp’s weaving capabilities in order to add support for special parameter validation aspects.

If you happened to examine any assemblies built using this technology with a static analysis tool like NDepend, you might have had alarms going off complaining about an excessive amount of boxing occurring. This is never a good thing, so let’s dissect this a bit.

The sole concrete validation attribute provided in the example was the NotNullAttribute. The base definition of the validation method employed by this attribute and all other validation attributes looked like the following:

        public abstract void Validate(object target, object value, string parameterName);

So, as we can see, all parameter types must be upcasted to the object type prior to being passed to the above method. Consequently, this also implies that all value type parameter values be boxed prior to being passed to Validate as well.

However, our sole concrete validation attribute (NotNullAttribute) is something we would never decorate a parameter known to be a value type anyway, since value types cannot be null! To do so would be silly, and (if you implemented the compile-time validation routine correctly), would result in a compile-time error.

But even if it is true that no value type parameters are decorated with a validation attribute, you may still have excessive boxing occurring in your assembly. This is because in the example provided in the previous article, box instructions are issued for both value type and generic type parameters.

So, if you’re like me, in that a large number of your methods use generic type parameters and you happen to be validating those parameters, you will have excessive instances of the box instruction in your code. So why does our previous example box generic type parameters? Simply because it takes the lazy way out: those generic type parameters may be bound to value types, they may not, so we box just in case they are.

What happens when you box a generic type parameter that is bound to a value type? Well, it boxes it like normal. What happens when you box a generic type parameter that is bound to a reference type? Nothing, it is essentially a nop. So, in actuality, because boxing will only actually be occurring when we’re binding the generic type parameters to value types, this may not seem like a very big deal to you anymore.

However, we can do better, and avoid boxing altogether for the most part. Among other things, the boxing metric from the analysis tool is rendered useless if we don’t clean up the number of box instructions in the IL. I’m going to go over how to go about doing just this; be aware, though, that my solution is not 100% complete, and I’m still trying to figure out how to support a few “corner” (yeah…not exactly) cases.

The Solution

Let’s take a look at how we can solve this problem.

A Generic Validation Method

One of the simplest ways to address this problem is to have a validation method that will accept a generic type parameter. So…something like the following:

public void GenericValidate<T>(object target, T value, string parameterName)
{...}

We then need to modify our actual weaving code so that it calls this method. Calling generic methods using IL is much more involved than it is when using C#, as the C# compiler handles all the required nasty business for us. All of my weaving code is in a class named ValidationInstructionWriter. One of its responsibilities is emitting calls to the parameter’s validation method, and it is this code that we need to change.

Before we go into those changes, however, let’s go over the general strategy at play here. Or, to put it another way, let’s look at the strategy that arises from some limitations encountered when trying to correct this problem.

Limitations and Things to Do

First of all, I’m not entirely replacing my original validation method with this new generic one. Only when we have a generic type parameter will we be calling the generic validation method. If, instead, we have a non-generic value or reference type, we will actually be calling the original method. Obviously, in the latter case, no box instruction is emitted when the parameter is known to be a reference type, however one is emitted if it is known to be a value type obviously.

Why? Well, the reason is very simple: I don’t know how to call generic methods using the PostSharp SDK unless I already have a generic type parameter. Indeed, this is the very reason as to why I originally only had a the validation method accept object types in the previous article on this topic. I certainly have attempted to figure out how to do this, however I have been unsuccessful so far. It certainly isn’t trivial, and isn’t expected to be, even though it would seem to be fairly standard thing at first (welcome to MSIL, by the way). If anyone out there does know how to do this, I’d love to know.

The PostSharp SDK is an unsupported tool, so I refrain from bothering the PostSharp developers with questions related to it. I’m also going to refrain sharing the problems I encounter when doing this here as well, although I will if there’s some interest. Regardless, I will continue to attempt to figure out how to do it, and I will be sure to let the world know once I figure it out.

In order to insert some balance into this approach, our validation attributes are designed so that the validation method that actually gets overridden in all concrete validation attribute types is the original validation method and not the new generic method. Having to override two different methods would be a bit ridiculous, and would kill this whole thing for me. The generic validation method, thus, is not virtual or abstract; all it does is simply do a direct call to the original validation method.

What’s the point of all of this then? Well, it gets rid of all those extraneous box instructions that would have been littering our code, and it also defers the details of the generic type parameter conversion to the C# compiler. It is also one step closer to the totally correct solution, and it gets the discussion on this topic rolling. Besides, if you remember, if a generic type parameter is bound to a reference type, a box instruction causes no performance hit. However, if it is bound to a value type, then we will get the penalty that comes with boxing. Indeed, that very case is the only one that is negatively impacted by this decision.

Frankly, it’s hardly a setback to have to work with object types instead of unconstrained generic types anyways, which offer no additional capabilities over object typed values. Taking it all into account, this compromise is acceptable under the standards I have for my projects. Frankly, even the original solution is, given of the immense benefits I’ve been discovering from being able to validate parameters in this fashion. Regardless, I’m not completely pleased with the final solution.

Let’s go over some constructs you’re going to see in the code. I’m not going to completely go over everything, as some things were described in the previous article, and other things you’ll need to figure out for yourself.

EntityDescription

I have a custom type I use named EntityDescription. This object basically consists of the  ParameterDeclaration‘s ParameterType, system Type, and name. Assuming you have a field set to the ParameterDeclaration of the parameter we’re validating, it is initialized like so:

EntityDescription description = new EntityDescription(
  _parameter.ParameterType,
  _parameter.ParameterType.GetSystemType(_genericTypeArguments, _genericMethodArguments),
  _parameter.Name);

This is basically just used as a container for commonly needed entity information, and is used outside of the specific scenario we’re covering today.

ValidationCallParameters

Another custom type I use if the ValidationCallParameters type. This is a type specifically purposed for containing the data required for emitting a call to one of our validation methods. I use this type for emitting both parameter and method validation calls, however this article (and the previous article) only concerns parameter validation. Assuming the index of the parameter you are validating is stored in a variable named targetIndex, you would initialize an instance of this type like so:

ValidationCallParameters parameters = new ValidationCallParameters(
    OpCodeNumber.Ldarg,
    targetIndex,
    description.EntityType.IsGenericParameter
        ? Validator.GenericValidationMethod
        : Validator.ValidationMethod);

Note that, for the validation method, I tell it use the GenericValidationMethod only if the parameter type is generic.

Let’s go over the actual code that emits a call to our new validation method.

EmitValidationCall

/// <summary>
/// Emits a call to a method responsible for validating a described entity, using the provided parameters
/// to arm it.
/// </summary>
/// <param name="parameters">The set of data required in order to weave this validation call.</param>
/// <param name="description">A full description of the entity being validated.</param>
public void EmitValidationCall(ValidationCallParameters parameters, EntityDescription description)
{
    // This adds a new instruction sequence to the current block.
    CreateInstructionSequence(NodePosition.Before);

    IMethod validationMethod = FindValidationMethod(parameters, description);

    Writer.EmitInstructionField(OpCodeNumber.Ldsfld, _validatorField);
    Writer.EmitInstruction(!Context.Method.DeclaringType.IsNullable()
                                ? OpCodeNumber.Ldnull
                                : Context.Method.GetFirstParameterCode());

    Writer.EmitInstructionInt16(parameters.TargetOpCode, (short)parameters.TargetIndex);

    if (description.EntityType.IsValueType)
        Writer.EmitInstructionType(OpCodeNumber.Box, description.EntityTypeSignature);

    Writer.EmitInstructionString(OpCodeNumber.Ldstr, description.EntityName);
    Writer.EmitInstructionMethod(parameters.ValidationMethod.GetFirstParameterCode(),
                                    validationMethod);

    Writer.DetachInstructionSequence();
}

The CreateInstructionSequence is a simple routine that behaves in the manner described by the comments above its call. The GetFirstParameterCode extension method is described in my previous article.

As we can see here, we do emit an explicit box instruction if the type of a known value type. If it is not a known value type, however, we won’t box. There really isn’t much new in here from the previous article, except for the call being made to FindValidationMethod, which is a new method introduced to solve this problem. Let’s take a look at that method.

FindValidationMethod

/// <summary>
/// Locates the <see cref="IMethod"/> instance for our validation method.
/// </summary>
/// <param name="parameters">The set of data required for the validation call.</param>
/// <param name="description">Optional. The description of the entity we're validating.</param>
/// <returns>The <see cref="IMethod"/> instance for our validation method.</returns>
private IMethod FindValidationMethod(ValidationCallParameters parameters, EntityDescription description=null)
{
  if (null == description)
      return Context.Method.Module.FindMethod(parameters.ValidationMethod, BindingOptions.Default);

  if (description.EntityType.IsGenericParameter)
  {
      MethodInfo validationInfo = (MethodInfo) parameters.ValidationMethod;

      MethodInfo genericValidationInfo =
          validationInfo.GetGenericMethodDefinition().MakeGenericMethod(description.EntityType);

      return
        Context.Method.Module.FindMethod(
           genericValidationInfo, BindingOptions.RequireGenericInstance & BindingOptions.RequireGenericMask);
  }

  return Context.Method.Module.FindMethod(parameters.ValidationMethod, BindingOptions.Default);
}

This method has an optional parameter for purposes outside of what we’re covering.

So, as we can see here, if we have a generic parameter, we need to call our method in a special way. You may want to add a check in there that ensures ValidationMethod is a generic method before attempting to get a generic method definition from it (which will throw an exception if it isn’t). This is taken care of in our original initialization of the ValidationCallParameters object.

There you go, this is a step on the path to making our validation solution use generics.

(Aphex Twin’s Analord series is some great stuff, by the way).

 

Immutable Properties

Microsoft likes to say that an auto-implemented property declared with a private set accessor is immutable. This is not entirely true, in a number of ways. One can always use reflection to assign values to a property, regardless of whether the set accessor is private or public. But putting conspiracy theory cases like that to the side, these properties still cannot be considered immutable due to the fact that, although the outside world cannot set their values, they are settable from anywhere inside the class.

The only type of property I would consider immutable is one that returns a read-only field and lacks a set accessor entirely. Of course, the very field that gets returned, provided it is not a value type, may very well not be immutable itself, but I digress.

I found an interesting way to assign a value to a property declared with a private set accessor that doesn’t use reflection. It does, however require some participation from the class itself. I’m not recommending actually using the approach I’m going to go over in any real-world code, as most of the time a read-only property is read-only for a good reason. Having to skirt around accessibility levels should never be the only way to proceed with an implementation, and if it is, then there is a problem with your design or approach as a whole. But, if you know what you’re doing, this may be of interest to you.

But putting all that sensible stuff aside, I’ve found an interesting one can go about setting the value of a property with a private set accessor using Expressions. More specifically, we can take an expression of a property’s get accessor being accessed and turn it into one where a value is being assigned to the property’s set accessor. This could be useful for instances where you need to initialize some sort of domain object that features limited accessibility in regards to setting the values of its properties.

An Example: PropertyMap

I developed a PropertyMap type which allows you to define values for a type of object’s properties outside of and independent of any instance of that type. The PropertyMap is populated with values that should be set to different properties of the target type. The properties are specified through the use of an ExpressionReader class that features a ReadName method that returns the name of a member being accessed. There are plenty of examples online as to how to use Expressions in order to get the names of code elements, so I’ll defer you to those examples if you wish to learn more about this.

As a side note, before we get to the code, just note I had to condense the names of the type parameters in order for the code to fit on the page the best. Typically, they’re a bit more descriptive.

Here’s the code for the Add method:

/// <summary>
/// Adds a mapping entry for the property being expressed.
/// </summary>
/// <typeparam name="TValue">The type of value returned by the property.</typeparam>
/// <param name="propertyExpression">An expression accessing a property's getter method.</param>
/// <param name="value">
/// The value to be assigned to the property during a future mapping operation.
/// </param>
public void Add<TValue>([NotNull]Expression<Func<T,TValue>> propertyExpression, TValue value)
{
    string propertyName = ExpressionReader.ReadName(propertyExpression);

    if (!ContainsKey(propertyName))
        Add(propertyName, value);
}

Alright, nothing too crazy here.

You can then pass the PropertyMap to an instance of the targeted type, which the instance can then use to assign values to its properties via successive calls to a Map function, each time providing an expression that accesses a different property.

/// <summary>
/// Maps a preconfigured value to the property being expressed.
/// </summary>
/// <typeparam name="TValue">The type of value returned by the property.</typeparam>
/// <param name="propertyExpression">
/// An expression accessing the getter method of the property to map to.
/// </param>
public void Map<TValue>([NotNull]Expression<Func<TValue>> propertyExpression)
{
    string propertyName = ExpressionReader.ReadName(propertyExpression);

    // Validation occurs here...Excluding this from the post.

    MemberExpression propertyGetterExpression
        = (MemberExpression) propertyExpression.Body;
    ConstantExpression instanceExpression
        = (ConstantExpression) propertyGetterExpression.Expression;

    T instance = (T) instanceExpression.Value;
    Action<T, TValue> propertySetter = CompileSetter<TValue>(propertyGetterExpression);

    propertySetter(instance, (TValue) this[propertyName]);
}

The above extracts the property getter expression and then calls CompileSetter to create an Action that invokes the set accessor of the type.

/// <summary>
/// Compiles a property setter method derived from the provided property getter expression.
/// </summary>
/// <typeparam name="TValue">The type of value returned by the property.</typeparam>
/// <param name="propertyGetterExpression">
/// An expression accessing a property's getter method.
/// </param>
/// <returns>
/// A compiled <see cref="Action{T,TValue}"/> which will set the value of the property
/// accessed by
/// <c>propertyGetterExpression</c> to what's provided.
/// </returns>
private static Action<T, TValue> CompileSetter<TValue>(Expression propertyGetterExpression)
{
    ParameterExpression valueParameterExpression
        = Expression.Parameter(typeof (TValue), "value");
    ParameterExpression instanceParameterExpression
        = Expression.Parameter(typeof (T), "x");

    BinaryExpression assignValueExpression
        = Expression.Assign(propertyGetterExpression, valueParameter);

    Expression<Action<T, TValue>> propertySetterExpression
        = Expression.Lambda<Action<T, TValue>>(assignValueExpression,
                                               instanceParameterExpression,
                                               valueParameterExpression);
    return propertySetterExpression.Compile();
}

Let’s go over a very rough example of this in action. Here’s the participating class:

public class Example
{
    public string Label
    { get; private set; }

    public void Map(PropertyMap<Example> map)
    {
        map.Map(() => Label);
    }
}

And here’s an example of invoking that class:

PropertyMap<Example> map = new PropertyMap<Example>
                {
                    { x => x.Label, "This works!" }
                };

Example example = new Example();

example.Map(map);

// The string variable below will be set to "This works!"
string label = example.Label;

I was initially somewhat surprised that this worked, we are basically changing the x => x.Label expression into a (x,value) => x.Label = value expression. Obviously this all fails if there is no set accessor at all.

The reasons why this works is something I’ll cover in another post in the future.

Should I Use This in My Code?

If you are unsure and have to ask me, then no, you shouldn’t use this in your code. For most cases where you could use this, you would be at best clever, and at worst irresponsible; however, for some situations, this could be considered an appropriate approach. Going into what those specific situations might be is far and beyond outside the scope of this article.

 

If there is one piece of an Exchange or Outlook appointment that is as important as it tends to be misunderstood, it would certainly have to be the Organizer property.

This lovely little fellow returns a string which represents the name of the individual who owns the appointment, or, as Microsoft puts it in the Outlook Object Model (OOM) documentation, it is “…the name of the organizer of the appointment.” As helpful as that is, what does it even mean for one to be an organizer of an appointment? I’m going to cover these questions as well as go over why it is very dangerous to rely on this property in your product’s code.

What is an Organizer?

Exchange server protocol documentation defines the organizer as “the owner or creator of a conference or event.”

I hate to contradict official Exchange white papers, but although the organizer is indeed the owner of an event, they are not necessarily always the “creator”. A delegate for a manager can create an appointment on that manager’s calendar, however the delegate will not be marked as the organizer; rather, the manager will be the organizer. You may say, “Well, the delegate carries out actions in the manager’s name.” which is not entirely correct, because a normal delegate actually very much retains their own identity, and this is reflected by some various properties which will reflect the delegate’s name on the appointment.

Let’s do a better job in defining what an organizer is: The organizer of an appointment can be described as the owner of the calendar in which an appointment is first created. By saying “owner of the calendar”, I’m referring to the individual for which the mailbox store containing the calendar belongs to. The organizer is commonly referred to (by Microsoft and others) as the meeting organizer, however it is important to remember that not all appointments are meetings, but all appointments have an organizer. This fact is important in the very definition of what a meeting is, which is an appointment that is extended “…to contain attendees in addition to the organizer.” [MS-OXOCAL - 1.3.1.2]

So what’s the importance of being an organizer? What special privileges or capabilities does one acquire when donning the Organizer cap? What are some important limitations?

  • The fact that an individual is an organizer is displayed to attendees in the meeting request; this alone is probably one of the most important consequences of being the organizer, at least as far as day-to-day business dealings are concerned.
  • The organizer is the individual that will receive all responses to any meeting requests sent by or through the organizer; that is, unless it has been configured for all responses to go to a delegate instead.
  • Once an appointment object has been saved, you cannot change who the organizer is (or so they say). This little factoid is probably one of the first bits of information developers or users may encounter when inquiring about the nature of the appointment’s organizer. In fact, I’ll bet that’s the reason you’re reading this very article.
  • Other than some special do’s and don’ts that one must follow when working with appointments in the very low levels of things, there’s really not much else.

While there are certainly other actions an organizer can take that a normal attendee typically cannot (such as adding an attendee, removing an attendee, etc.), all of these types of actions are wholly dependent on the permissions and type of access the individual has in relation to the original appointment item; they have nothing to do with being the organizer. This is why a delegate can do everything an organizer can.

Regardless of the actual limited number of automatic perks that come with being an organizer, many third-party solutions out there tend to use the fact that someone is an organizer as a simple way to see if the user owns and thus can modify/mess around with an appointment. Although nothing is easier than checking if the current user’s name matches the string returned by the Organizer property, this is a dangerous way to proceed for a number of reasons we’ll get into later.

How is the Organizer’s Identity Determined?

Folks who work with Outlook solutions generally refer to the OOM’s Organizer property of an appointment item to determine who the organizer is. As I’ve stated before, this property returns a string representing the name of the organizer. So…is that it then? Is the identity of the organizer persisted through a simple string property on the appointment object? Where does this Organizer property actually get its value?

These are all questions with, surprisingly, unclear answers. While some of the above is addressed by Microsoft on the MSDN, they do not, in particular, (from what I’ve seen) seem to mention the exact origin of the value returned by the Organizer property anywhere.

It takes only simple deduction to realize that Outlook is aware of more about the organizer than simply the name of the organizer. For instance, create a new appointment on your calendar, and then click on the Scheduling Assistant ribbon button in the Show group. You’ll see something similar to the following:

Scheduling Assistant Displaying the Organizer

Scheduling Assistant Displaying the Organizer

If you look at the icon next to my name, you’ll that I’m the organizer of the meeting (the icon being the “organizer” icon and all). So, we see that it knows the name of the organizer. Isn’t that what we get by looking at the Organizer property?

Well my friends, you’ll be pleased (horrified) to know, that the name shown in the above picture and the value returned by the Organizer property do not come from the same place. In fact, they are not linked at all, the fact that they tend to be the same value is merely a consequence of actions taken by the client. It is indeed possible for them to differ in value (even if they originally were the same value) as well, however that’s outside the scope of this article.

Back on topic, if we take a closer look at the entry above, we’ll see that Outlook is actually aware of the true identity of the user that is marked as the organizer. You can see this simple by moving your mouse over the name. This will result in something similar to the image below:

Scheduling Assistant Displaying the Organizer with Additional Information

Scheduling Assistant Displaying the Organizer + Additional Information

Simply based on the fact that we’re seeing the card pictured above should tell us that we are looking at the user’s actual address entry as well as some other information. Indeed, clicking on one of the icons in the above card will lead us to the user’s contact details.

What does this all tell us? This tells us that Outlook and Exchange are intimately aware of the identity of the organizer of the appointment; they do not rely simply on a literal name for the organizer. They are aware of enough information regarding the organizer to be able to pull the contact information for the user. What does that require? It requires the entry ID of the entry for the user in an address book (i.e. the GAL).

So where is the organizer’s information stored in the appointment, and in what form? Roughly speaking, information regarding the organizer is stored in two separate places, one of them being, in my opinion, the most official of the two as far as what makes some an actual “organizer”; however, each has its own set of consequences realized with regards to the user indicated as being the organizer. Let’s go over those two places that collectively determine who the organizer is.

I: The Recipient Table

The designation of the organizer in a meeting’s recipient PropertyRowSet is what, I believe, actually decides who the organizer is, as it has the greatest amount of influence on the functional implications of having the status of being the organizer.

A PropertyRowSet is a data structure discussed in the [MS-OXCDATA] Exchange server protocol document is simply a structure that has a counted number of PropertyRow structures. Essentially, it is a table where the number of columns in each row is not exactly set in stone (sounds like something right up Microsoft’s alley). When discussing a recipient table, these PropertyRow structures are actually RecipientRow structures, which are also introduced in the [MS-OXCDATA], but expanded upon in [MS-OXOCAL - 2.2.4.10], which begins to go over the actual properties one may encounter in an entry in the recipient table.

By the way, I love how Microsoft introduces the concept of a RecipientRow: “It is rather complex but can be considered as a sequence of three different parts…”

When we step outside of the design and into the more real-world side of things, we’ll find implementations of the recipient table on any type of message, including appointments and meetings. We can retrieve the recipient table by making an IMAPIProp::OpenProperty call, specifying PR_MESSAGE_RECIPIENTS for the property tag and IID_IMAPITable for the interface identifier. You’ll be able to do this more easily by using either OutlookSpy, MFCMapi, which all have options named something similar to “Open Recipients Table”. I’m not sure how easy it is to get to what we want her from the OOM, or even Redemption, but it should be accessible using the appropriate property tags (at least in Redemption’s case…I try to avoid the OOM when doing anything off the beaten path).

Inside the recipient table, we’ll find a RecipientRow for every single attendee to the meeting, including one for the organizer. On each row is one particular property of importance, and that is the PR_RECIPIENT_FLAGS property. You can find information regarding the specifics of this property in the [MS-OXOCAL], however I’ll help you out a bit and plop a picture relevant to what we’re talking about below:

Structure of the PR_RECIPIENT_FLAGS Property

Structure of the PR_RECIPIENT_FLAGS Property

We can see above a number of bit fields we can set. The bit we’re interested in is the second bit, which is known as the recipOrganizer bit. Setting this bit to 1 makes the user associated with the RecipientRow that this property is in the de facto organizer of the appointment. This then implies that only a single RecipientRow can have this bit set. I’m not sure what’ll happen if more than one does have it set, you’ll have to build a custom MAPI client to find out.

So, in other words: the organizer is officially determined to be the user whose has the recipOrganizer bit set in their associated RecipientRow in the appointment’s recipient table. There are other properties in the RecipientRow besides the recipient flags, including one or more that store the recipient’s entry ID. No doubt, then, it is through the user’s RecipientRow that Outlook is able to retrieve the kind of information we were being treated to earlier when hovering our mouse over our name in the Scheduling Assistant.

Unfortunately, this is not the entire story. Despite the designation via the user’s RecipientRow being the official way of becoming the organizer, it may surprise you to know that the Organizer property returned by the OOM (I can’t speak as for Redemption, didn’t test it out), which is the most common means of exposure of the organizer’s identity to the outside via an API (in the case of an Outlook solution, at least) is in no way influenced by the recipOrganizer bit, the PR_RECIPIENT_FLAGS property, or any at all to do with the recipient table!

This leads us to the second place an organizer is “set”.

II. PR_SENT_REPRESENTING_NAME

The value returned by the Organizer property does not originate from the appointment’s recipient table at all. Instead, it actually comes from the PR_SENT_REPRESENTING_NAME property, found on the appointment itself. So, there you go…that’s where the money is.

You’re probably already aware (from being told so somewhere else) that you cannot change the organizer. Consequentially, the Organizer property is read-only. You cannot set the Organizer property. Well, while it is more or less true that you cannot change who the real organizer is, you can have influence on what Organizer returns.

It may surprise you to know that by changing the value of PR_SENT_REPRESENTING_NAME, you will change what the Organizer property returns. Some places in Outlook do use this property to display the organizer’s name, so you will influence those areas. In some places, however, Outlook defers to the display name stored in the recipient table. It does not seem possible to edit a RecipientRow once a message has been saved; at least, I am unable to do so using OutlookSpy and MFCMapi. Perhaps it is still technically possible to with the Redemption library or raw Extended MAPI. I’d be interested to know if anyone has any insight on that.

Here’s some code to demonstrate how to change the Organizer property in Outlook (when we’re in Outlook, we have to get the correct DASL property name):

private void ChangeOrganizer(AppointmentItem appointment)
{
  PropertyAccessor accessor = appointment.PropertyAccessor;

  accessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x0042001F", "Matt Weber");

  // 'appointment.Organizer' will now return "Matt Weber".
}

And here’s some code to do the same with Redemption, which is a little bit simpler:

private void ChangeOrganizer(RDOAppointmentItem appointment)
{
  appointment.SentOnBehalfOfName = "Matt Weber";
}

An interesting thing to note is that the PR_SENT_REPRESENTING_NAME property can be found on both appointment and normal mail messages, and thus can be set on either. Regardless, only appointment objects will have an actual “organizer”. Changing the PR_SENT_REPRESENTING_NAME property on an email will change the name of the sender of the email.

Why Relying on the Organizer Property is Dangerous

Seeing how the Organizer (and thus the PR_SENT_REPRESENTING_NAME property) is not actually (guaranteed to be) based on who the real organizer is, relying on it in your program code can be very dangerous. It is really a bad idea, and I’ll provide a very real-world example showing why.

If you cater to customers that belong to the corporate world, you should be aware of and always plan on the possibility of a merger or acquisition involving that customer occurring. Many times, during the process of the merger of acquisition, company-wide changes to the display names of their users will be rolled out via Active Directory. Perhaps the company is now becoming a more “world-wide” company, and thus needs to append the name of a country to all employees’ display names based on the location of their office.

When changes are made to User objects in Active Directory, those changes are going to eventually propagate to Exchange’s Global Address List via a management agent. This means, then, that those changes will be reflected in all address entry objects returned when operating within an Outlook or Exchange environment. Guess what happens to the values returned by properties like PR_SENT_REPRESENTING_NAME and, ultimately, the OOM’s Organizer property? Nothing! They will remain the same; they are not synchronized or hooked up to Active Directory in any way shape or form.

So what will happen then, if you happen to have code responsible for determining if the current user is the organizer of an appointment, which happens to use current Active Directory information for figuring out who the current user is, and the appointment’s Organizer property for figuring out who the organizer is? It won’t work anymore, because they will be completely out of sync.

Therefore, it is very dangerous to rely on, frankly, any string property relating to users exposed by MAPI’s data model.

What’s the alternative here?

The proper way to establish organizer identity is to look past the OOM’s Organizer property and PR_SENT_REPRESENTING_NAME property, and instead use the PR_SENT_REPRESENTING_ENTRYID property (which is exposed by Redemption with the SentOnBehalfOfEntryId property) to retrieve the address entry of the user. This method will survive abrupt, organization-wide changes committed to Active Directory.

The best alternative, however, would be to defer to the recipient table. You would need to go over each RecipientRow until you located the one with the recipOrganizer bit set, and then use the PR_ENTRYID property located in that RecipientRow in order to open up the user’s associated address entry. Note that there is also a PR_RECIPIENT_ENTRYID which may be available and I am not sure as to what the different might be between the two properties; in all instances I’ve observed, both the PR_ENTRYID and PR_RECIPIENT_ENTRYID properties had the same value.

© 2012-2013 Matt Weber. All Rights Reserved. Terms of Use.