Wednesday, February 18, 2009

STSADM Properties

Wait...There's Another Flag

If you've ever felt like theNewTask STSADM utility is taxed with doing more than Emacs, there's a good chance you're in the majority. I was recently trying to figure out what SharePoint settings affect the "New" icon when I stumbled upon the stsadm's getproperty and setproperty flags.

Essentially there's a bunch of SharePoint settings (some of which there's no admin UI screen for) that can be manipulated using this utility. The new icon is one such property.

It might be worth looking at some of these, they include both server and web application level properties.

Server Properties

Web Application Properties

As it turns out the default value for the new icon is 2 days. You can show and change this property by using the following commands:

stsadm -o setproperty -pn days-to-show-new-icon -pv 2 -url [WebAppUrl]

stsadm -o getproperty -pn days-to-show-new-icon -url [WebAppUrl]

This probably wont interest you in the least until you start to think about scripting and how this might help you ensure certain settings have been set when it comes time to deployment.

While many of these settings might be alterable using the SharePoint API, there are still many types of changes that deserve to be versioned in some kind of script rather than C#.

Best,
Tyler

Sunday, February 15, 2009

Start Your April Fools Jokes Early

Time Waits For No One

For some reason Valentines Day always reminds me that April Fools is coming up. This most likely draws from the fact that I'm the youngest of two siblings, and it's become a personality trait to express my affection by irritating the crap out of an individual.

Needless to say I have very few close friends.

Since nothing says "I care about you" like a good practical joke, I'd like to take the time to remind you that April Fools day is a very short 32 business days away, and depending on how deep your pranks run, you may need to get some infrastructure in place.

The Right Joke For The Right Bloke

A good practical joke is tailored to theapril-fool individual. Knowledge of their technical depth, their patience, any history of violence, and past convictions are key to finding just the right level of crazy.

If you'd like to go shopping for ideas, I'd suggest starting here. My only advise is to be prepared for retaliation. Most pranks usually deserve another, and the minute your cover gets blow, it'll already be too late to start wearing a helmet.

Get Going

So get on it. Usually most April Fools jokes fall apart because people leave them to the last minute. DNS records may need to get updated, proxies may need to get provisioned, machines may need to get hacked. Don't risk leaving it to the last minute, start being devious and subversive today!

I'll share this years war story on April 2nd.

Best,
Tyler

Monday, February 9, 2009

How SharePoint Found Its Content Database

Good Question

I was talking a client through a SharePoint web.config change a couple of weeks ago and he ended up asking a dynamite question.

How does the web application know where its content database is at?

You might say something like "it gets it from the config database", but that would beg another question, "how does it know where the config database is?". In reality, we're curious about how a web application orients itself to its environment when it comes time to respond to a request.

You'll notice that SharePoint web.configs don't have any connectionString elements in them that point to a particular content or configuration database, and SharePoint installs don't make any changes to parent web.configs or machine.configs. So how does this web application orient itself at runtime?

Lets Reflect, Literally

If you think about it, there's a few clues to where this code "ought to be". Pretend for a minute that you were tasked with authoring some piece of functionality that let a web application figure out where its database was at runtime. There's some typical places you'd hook in (besides the web.config). You'd know that this piece of functionality would need to be populated in time to serve requests who would need to know where the content db is at.

You might think about putting it in global.asax Application_OnStart or some http module event that's relatively early in the ASP.NET pipeline.

Lets look at how a typical SharePoint request gets resolved and see if we can't flush out some details. This is the path I took to piece this answer together.

  1. A request comes in and gets handled by IIS. The request matches either a port number or a host header on a web site in the web server.
  2. The matching SharePoint web site has wild card ISAPI mappings that pass all request to ASP.NET. Remember that in a typical ASP.NET web site there mappings for known ASP.NET file extensions (.aspx, .asmx, .ascx, etc...) to the ASP.NET ISAPI filter. When IIS gets a request that ends with the given file extension, it knows that this is an ASP.NET request and hands it off to the aspnet_isapi.dll ISAPI. In a SharePoint IIS web site, we pass everything to ASP.NET. This includes .gifs, .jpegs, .PSDs etc... SharePoint gets a chance to fulfill every requests that gets picked up by the site. Below is a screen cap the wild card mapping present in all SharePoint sites. This is created for you automatically when you provision a new web application. If you were to remove it, your SharePoint instance would no longer be able to serve non ASP.NET files out of the content database. Wildcard mapping that sends ALL requests to the .NET frameowrk and eventually to our SharePoint web application.
  3. Once the request gets handed to ASP.NET, its fair game for the web application to start doing some magic. In fact, it had better figure it out soon cause odds are this request is going to want something from the content database before the page life cycle hits. Because we're talking about the ASP.NET request pipeline (and early in it), it's a reasonable guess to assume an http module could be in play. If we look in the web.config under the <httpModules> section we find that SharePoint has registered an HttpModule named "SPRequest", it's fulfilled by code found in the Microsoft.SharePoint.ApplicationRuntime namespace by a class called SPRequestModule.The SPRequest HttpModule.
  4. If you reflect on SPRequestModule and look into BeginRequestHandler (one of the earlier events in the ASP.NET pipeline), it's obfuscated, but you can read it anyway. BeginRequestHandler makes a call to SPFarm.Local which ends up calling SPFarm.FindLocal in an effort to find the farm that this machine belongs to.
  5. SPFindLocal finally calls into SPConfigurationDatabase.Local which runs to the registry looking for HKLM\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Secure\ConfigDB. This is where your "connection string" for the current farm lives.
  6. This is also how SharePoint finds the config database, from there it simply takes the current request and uses it to find the content database (if any) associated with the given request. After all this has been figured out, a lot of it gets cached.
  7. Finally BeginRequestHandler starts through the complex task of mapping your request to a bunch of content in the web applications content database. The regular Page Life Cycle kicks off and at the end of the day we end up with an HttpResponse built up by SharePoint.

Thought that someone else might enjoy the answer. This is kind of a neat piece of functionality too, it allows the psconfig tool to move this machine from farm to farm without changing any web.config files, so long as you can tell it where it should remap the registry key to. And with that, there's a little less magic in the world.

Best,
Tyler

Friday, February 6, 2009

When the Reflector Tells You To Hit The Road

Seeing Obfuscated Code

Like every other .NET developer out here, I'm a big fan of the .NET Reflector. It was originally written by Lutz Roeder but is now maintained by the kind gentleman at Red Gate. One of the elements that make the tool stand out (in addition to the ease at which it lets you navigate/disassembling code), is the ton of add ins on CodePlex that extend the base functionality. If you haven't already, you should explore them some time.

I mostly use the .NET Reflector when it comes to things that I don't quite understand and I can't seem to find an adequate answer on the web. Ninety percent of the time, this tool will usually make it easy for you to look underneath the hood and you can find your own answers.

Every now and then when you're reflecting on code that someone doesn't thing you should see, you'll get the following message from the tool.

This item is obfuscated and can not be translated.

This item is obfuscated and can not be translated.

If your stubborn like most rural mules or have never heard of "no means no", you can carry onward by going to View->Options->Click Dissassembler and set the language to IL.

Changing the language to IL in reflector will let you see obfuscated code.

If you're simply asking for the IL, Reflector will gladly show you the contents of the function (if you can make any sense out of it). Intermediate Language is even harder to read than disassembled MISL that's mapped to C# or VB.NET (which unreadable for another variety of reasons).

Code that was previously obfuscated.

In fact if you're just going to be looking at IL, you can actually skip the .NET Reflector in the first place and use the MSIL Disassembler (ildasm.exe) that comes with the .NET framework. May not look as pretty, but you're guaranteed to have it on any machine which as the .NET SDK.

Here's a disclaimer.

It's also worth mentioning that by reverse engineering code you could be violating an EULA, and I'm hear to tell you that you should never do that. In fact, if you're ever given a piece of code that doesn't function correctly, you should never try to fix it or do anything to further your understand what's going wrong. Often the most legally sound action, is to turn off the computer and go home.

Hope that helps someone find an answer.

Best,
Tyler