Skip to content
Jan 6 / Michaël Hompus

Remote Desktop Client doesn’t use stored credentials

The problem

When I’ve to connect to the same development machine over and over again using RDP I store the credentials.

First logon attempt

But when I later connect again I’ve to still provide a password.

Second logon attempt

After entering my password 1387 times in the last year I started searching for the reason why it doesn’t use my stored credentials. As it turns out this is because of a local policy.

The solution

1. Start “GPEdit.msc” and navigate to “Computer Configuration\Administrative Templates\System\Credentials Delegation”

2. Open the policy “Allow Saved Credentials with NTLM-only Server Authentication” (or “Allow Delegating Saved Credentials with NTLM-only Server Authentication” for Windows 7)

3. Select “Enabled” and click on “Show”.

4. Enter the server where you want to connect to with the stored credentials. You’re allowed to use wildcards, so I choose “TERMSRV/*.int” (my development machines are always in a domain ending with “.int”).

5. Close the screens and run “gpupdate”.

Now it’s possible to connect to the server without providing the same password over and over again.

Allow delegating saved credentials

Jan 6 / Michaël Hompus

Blog now running on WordPress

After having major, and unsolvable, problems with MovableType (MovableType was causing segfaults in Perl) for over half a year I finally switched to WordPress for hosting my blog.

I did consider SharePoint Server 2010 for hosting my blog, but the out-of-the-box support is nowhere near the possibilities with WordPress (or any other major blogging framework).

Configuration

After trying some themes I settled for the Punchcut Theme by Jestro.

This is completed with the following plugins:

  • Akismet
    Akismet checks your comments against the Akismet web service to see if they look like spam or not.
  • Google XML Sitemaps
    This plugin will generate a special XML sitemap which will help search engines like Google, Yahoo, Bing and Ask.com to better index your blog.
  • SI CAPTCHA Anti-Spam
    Adds CAPTCHA anti-spam methods to WordPress on the comment form, registration form, login, or all. This prevents spam from automated bots.
  • TweetMeme Retweet Button
    Adds a button which easily lets you retweet your blog posts.
  • Twitter Widget Pro
    A widget that properly handles twitter feeds, including @username, #hashtag, and link parsing.
  • WP Super Cache
    Very fast caching plugin for WordPress.

If somebody has comments or suggestions, please let me now.

Jul 9 / Michaël Hompus

MOSS 2007 – C# Protocol Handler errors fixed

On CodePlex you can find the MOSS 2007 – C# Protocol Handler project. I’m currently using this in a project to index a custom content source.

When working with the code I discovered 2 issues which I both fixed. Both solutions are posted in the discussions and/or submitted as patch and I will summarize them here.

Running on x64

The first problem is the code not working on x64 environments. Since we are talking to native code there are a lot of structs in the code. These structs are containing metadata to indicate the layout in memory. This is done using the StructLayoutAttribute class which contains a Value property with a LayoutKind enumeration and a Pack field.

The problem is the Pack value was set to 1. This is normal for 32bit systems, but not for 64bit where a pack of 8 is expected.

Lucky enough the following is written in the remarks section:

A value of 0 indicates that the packing alignment is set to the default for the current platform.

This solves our problem! Now the same code runs fine on both x86 and x64 systems.

Using Security Descriptors

One of the most important features of SharePoint search is security trimming. To make this possible an ACL structure is stored with the crawled item in the index database. The problem is when the ACL is larger then 1kB the crawler goes into an endless loop.

The way it should go is the search service calling the GetSecurityDescriptor method with a pointer and a size. This size is 1024 by default. When the ACL is larger an ERROR_INSUFFICIENT_BUFFER error message should be returned and the required size should be set. The search service then should allocate enough memory and call the GetSecurityDescriptor method again, which is now able to assign the complete ACL to the pointer.

The problem with the current version on CodePlex is the value of the error message is incorrect. Instead of 0×00000122 it should be 0x8007007A (which is also 112). After changing this the ACL will be stored (as long as it’s staying <64kB).

May 12 / Michaël Hompus

SharePoint 2010 and Project Server 2010 System Requirements

As announced yesterday by Microsoft the 2010 product will be 64bit only. Well no surprise there, we already knew that. But they went even further. Because of their experience with customer implementations of the 2007 series they recognize that having Windows Server 2008 and SQL Server on 64bit is a must for ensuring the best performance possible. There for the 2010 will only be available on those versions!

Also on the client side there will be an improvement as Internet Explorer 6 won’t be supported anymore.

So to summarize:

  • SharePoint Server & Project Server 2010 will be 64-bit only
  • SharePoint Server & Project Server 2010 will require 64-bit Windows Server 2008 or Windows Server R2
  • SharePoint Server & Project Server 2010 will require 64-bit SQL 2005 or 2008 (But you should choose 2008)
  • SharePoint Server & Project Server 2010 will only support Internet Explorer 7 or 8
Mar 25 / Michaël Hompus

Generate integer lists using LINQ

I was working on some old code which created three DropDown controls with hours, minutes and seconds.

This was the original code:

for (var i = 0; i < 24; i++)
{
    Hour.Items.Add(new ListItem(i.ToString()));
}

for (var i = 0; i < 60; i++)
{
    Minute.Items.Add(new ListItem(i.ToString()));
    Second.Items.Add(new ListItem(i.ToString()));
}

I wanted to LINQify it using the LINQ Range method:

Enumerable.Range(int start, int count)

This returns an IEnumerable<int> collection with the corresponding range of values. So my DropDown controls are now created with the following code:

Hour.Items.AddRange(Enumerable.Range(0, 24).Select(i =>
                                   new ListItem(i.ToString())).ToArray());
Minute.Items.AddRange(Enumerable.Range(0, 60).Select(i =>
                                   new ListItem(i.ToString())).ToArray());
Second.Items.AddRange(Enumerable.Range(0, 60).Select(i =>
                                   new ListItem(i.ToString())).ToArray());

This could be optimized by using a variable for the sixty values which could be used twice.

Mar 23 / Michaël Hompus

SharePoint Incremental Crawl takes much longer after adding or removing a user

It’s a sad and known fact that having lot’s of ACL’s in your SharePoint database has a negative effect on the performance of your site. What I didn’t know yet was that changes to the ACL will impact you incremental crawls. Vikram Lakhotia has posted a description about this in his blogpost: “Sharepoint Incremental Crawl taking a long time after adding or removing a user”

Mar 13 / Michaël Hompus

Recording Converter for Microsoft Office Live Meeting 2007

This week I gave a presentation at Winvision and recorded it in Microsoft Office Live Meeting 2007. The resulting recording is a webpage with multiple streams: desktop video, presenter video and audio. The problem is that the codec used doesn’t work on x64 systems or Windows 7 (Server). Watching the separate streams isn’t really an option because there is no audio included in the video streams.

But I got lucky as it seems Microsoft has released a new tool called “Recording Converter for Microsoft Office Live Meeting 2007” only last month.

This tool allows you to convert a Live Meeting recording into a WMV file. You can choose the output resolution and, optionally, you can include the presenter and/or panoramic video streams. Takes an hour to process (my presentation was nearly 2 hours) and now I have a file most video players can render.

Mar 12 / Michaël Hompus

Access Denied when crawling mysite / people on localhost with a different hostname

I have a clean install on the latest and greatest: Windows Server 2008, SQL Server 2008 and MOSS 2007 SP1 with all updates. This is the layout of my farm:

http://<server>:80 – Portal
http://<server>:8000 – Central Admin
http://<server>:8001 – SSP
http://mysite – MySites

Everything works fine, except the search crawl gave Access Denied errors on http://mysite and sps3://mysite. I checked everything, but could only find this in the Application event log:

The start address <http://mysite> cannot be crawled.
Context: Application 'SharedServices1', Catalog 'Portal_Content'
Details:
Access is denied. Check that the Default Content Access Account
has access to this content, or add a crawl rule to crawl this
content.   (0x80041205)

Also the Secutiry event log says:

An account failed to log on.
Subject:
Security ID:              NULL SID
Account Name:             -
Account Domain:           -
Logon ID:                 0x0
Logon Type:                  3
Account For Which Logon Failed:
Security ID:              NULL SID
Account Name:             <DCA account>
Account Domain:           <Domain>
Failure Information:
Failure Reason:           An Error occured during Logon.
Status:                   0xc000006d
Sub Status:               0x0
Process Information:
Caller Process ID:        0x0
Caller Process Name:      -
Network Information:
Workstation Name:         <Server>
Source Network Address:   127.0.0.1
Source Port:              50678
Detailed Authentication Information:
Logon Process:
Authentication Package:   NTLM
Transited Services:       -
Package Name (NTLM only): -
Key Length:               0

I had a hard time finding the solution, until I encountered Ron Grzywacz’s Blog: http://blogs.msdn.com/ronalg/archive/2008/10/27/crawling-issue-with-net-3-5-sp1.aspx

Although http://support.microsoft.com/kb/896861 only mentions Windows XP and 2003, it seems to fix the issue on Windows Server 2008 as well.

So to fix this:

  1. Click Start, click Run, type regedit, and then click OK.
  2. In Registry Editor, locate and then click the following registry key:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0

  3. Right-click MSV1_0, point to New, and then click Multi-String Value.
  4. Type BackConnectionHostNames, and then press ENTER.
  5. Right-click BackConnectionHostNames, and then click Modify.
  6. In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.
  7. Quit Registry Editor, and then restart the IISAdmin service.

It worked immediately!

Mar 9 / Michaël Hompus

Working with URL’s in SharePoint

While working on a project with some existing code I noticed the developer did write large portions of code to get from an URL to a SPList. He probably didn’t know some of the hidden gems in SharePoint.

Get the full URL

Sometimes you need the full URL and only have the relative one. For example when opening a new SPSite or when writing code in a NavigationProvider. For this you could use:

SPUtility.GetFullUrl(SPSite Site, string WebUrl)

For example:

string webUrl = "/sub/default.aspx";
SPUtility.GetFullUrl(SPContext.Current.Site, webUrl);
    == "http://localhost/sub/default.aspx"

There is one catch:

string webUrl = "http://localhost/sub/default.aspx";
SPUtility.GetFullUrl(SPContext.Current.Site, webUrl);
    == "http://localhosthttp://localhost/sub/default.aspx"

Check the type of URL

The former example is nice, but you would still need to write code to check if the input already contains the full URL. Nope!

For this, two gems are found in SPUrlUtility.

SPUrlUtility.IsUrlRelative(string url);
SPUrlUtility.IsUrFull(string url);

These methods do exactly what their names imply: check if the URL is relative or full. So for example:

string fullUrl = "http://localhost/sub/default.aspx";
string relUrl = "/sub/default.aspx";
SPUrlUtility.IsUrlRelative(fullUrl); == false
SPUrlUtility.IsUrlRelative(relUrl); == true
SPUrlUtility.IsUrlFull(fullUrl); == true
SPUrlUtility.IsUrlFull(relUrl); == false

Great! Now we can combine the two:

if (string.IsNullOrEmpty(webUrl) || SPUrlUtility.IsUrlRelative(webUrl))
{
    webUrl = SPUtility.GetFullUrl(SPContext.Current.Site, webUrl);
}

Now webUrl will always be the full URL.

URL concatenation

Ever did web.ServerRelativeUrl + “/something” and found out it did work nicely except it start doing something really weird on your root web? On the rootweb the relative URL is “/”, and this results in the URL “//something” which on it’s own turn gets translated to “http://something”, and that URL doesn’t exist (most of the time).

When working with file system locations, you should always use Path.Combine() instead of concatenating path’s yourself. But the is no Uri.Combine().

You could write an extension method. But the SharePoint team made it more easy.

SPUrlUtility.CombineUrl(string baseUrlPath, string additionalNodes)

This method does the same thing like Path.Combine(). For example:

string root = "/";
string path = "/sub"
string doc = "/sub/default.aspx";
SPUrlUtility.CombineUrl(root, path); == "/sub"
SPUrlUtility.CombineUrl(root, doc); == "/sub/default.aspx"
SPUrlUtility.CombineUrl(path, doc); == "/sub/sub/default.aspx"

That’s the final (hidden) gem for today.

Mar 4 / Michaël Hompus

"CS0122: 'x' is inaccessible due to its protection level" but you don't want to go public

Sometimes you have to split your code into different assemblies. For example when I created a custom Admin Page which inherits from WebAdminPageBase (Microsoft.SharePoint.ApplicationPages). The problem with Microsoft.SharePoint.ApplicationPages is that it’s not deployed to the GAC.

Putting a reference to this assembly from my assembly, also containing custom webparts and other controls which have to be registered as SafeControls in the web.config, will result in deployment troubles when you use a WSP file. The problem is when SharePoint is going to register the safecontrols it will reflect your assemby and won’t be able to access the Microsoft.SharePoint.ApplicationPages assembly because it’s not available in the GAC. The same problem can be found using the Content Deployment option.

So you split your code in 2 assemblies, for example foo.bar and foo.bar.ApplicationPages. But when your custom application page is depending on an internal type declared in foo.bar you are in trouble. When compiling you will get the following message:

"CS0122: 'foo.bar.x' is inaccessible due to its protection level"

No you have only one choice: make x public. Or not?

It’s also possible to make your assembly share it’s internals with other assemblies. Add the following to you code (in foo.bar):

[assembly: InternalsVisibleTo("foo.bar.ApplicationPages,
PublicKey=0a240a ... c2f34c7")]

But the public key is not your public key token. Thanks to Burt Harris’s comment at the InternalsVisibleToAttribute Class you can find your real public key using the following command:

sn.exe -Tp foo.bar.dll

Now compile your project and there you go!