BrianPeek.com

A Compendium of Random Uselessness
in Search
  • Weird Vista Registry Issue

    I'm attempting to track down a very strange Windows Vista registry permissions issue that hit me on two machines, that I've found mentioned in random various forum posts across the Internet, that has no known cause or solution, and which I cannot seem to reproduce in a VM though I've seen it happen on 2 machines across 4 Vista installs.  I'm hoping everyone that happens to read this post will take a few minutes to check the following and contact me directly or leave a comment with a way to communicate back to you.  Here's what to do:

    1. Run regedit.exe, everybody's favorite Registry Editor.
    2. At the root node of HKEY_CLASSES_ROOT, right-click and select Permissions from the context menu.
    3. Report what you see.  The first image is correct.  The second image is the problem scenario.

    image reg

    Subsequently, every subkey that is created or modified after this problem occurs has no permissions attached to them, causing all sorts of issues like COM components not being registered, file extensions not being registered, etc.  Permissions on every entry prior to the problem occurring are set properly.

    I first noticed the problem when installing XNA 2.0 Beta, though its problems were caused by the already unnoticed and broken permission state.  Several folks in the XNA forums have reported a similar issue with no evidence of a cause, though I did find a not-so-perfect solution for x86 machines.  I have a feeling this is something that has happened recently, perhaps due to a Windows Update, but that's just a guess.

    I attempted to reproduce this in a VM and failed.  I rebuilt my Vista x64 desktop since this was causing chaos and managed to reproduce it twice by installing Office 2007.  Yet, doing that same thing in a clean Vista VM would not reproduce it.  So that's not it either.  There are reports of it happening on both x86 and x64 installs.  There's obviously some sort of interaction here, but I have yet to find the common link.

    Update:  My original installations were running with UAC off.  My first two re-install attempts ran with UAC off as I typically run.  On the third re-install attempt I left UAC on instead of turning it off and that seemed to make all the difference.  However....note that in attempting to reproduce this in a VM multiple times in multiple ways, UAC was turned off and the problem did not occur.

    The partial solution below does not fix the root of the problem.  One can reset the registry permissions using subinacl from the Windows Resource Kit, but a) it's a 32-bit app so it can only touch the 32-bit reg keys, and b) HKEY_CLASSES_ROOT itself will still randomly reset its permissions to nothing though the subkeys will still retain their fixed permissions.  So, anything which attempts to write to the registry is once again broken.

    To partially fix the issue, do the following:

    1. Install subinacl.
    2. Copy/paste the following to a batch file and run it, replacing YOURUSERNAME with your Windows username:
    cd /d "%programfiles%\Windows Resource Kits\Tools" 
    
    subinacl /subkeyreg HKEY_CURRENT_USER /grant=administrators=f /grant=system=f /grant=restricted=r /grant=YOURUSERNAME=f /grant=restricted=r /setowner=administrators
    subinacl /keyreg HKEY_CURRENT_USER /grant=administrators=f /grant=system=f /grant=restricted=r /grant=YOURUSERNAME=f /grant=restricted=r /setowner=administrators 
    
    subinacl /subkeyreg HKEY_LOCAL_MACHINE /grant=administrators=f /grant=system=f /grant=users=r /grant=everyone=r /setowner=administrators
    subinacl /keyreg HKEY_LOCAL_MACHINE /grant=administrators=f /grant=system=f /grant=users=r /grant=everyone=r /setowner=administrators 
    
    subinacl /subkeyreg HKEY_CLASSES_ROOT /grant=administrators=f /grant=system=f /grant=users=r /setowner=administrators
    subinacl /keyreg HKEY_CLASSES_ROOT /grant=administrators=f /grant=system=f /grant=users=r /setowner=administrators 
    

    So, kind readers, please take a look at the above and let me know what permissions you're seeing on your registry so I can continue to find the root cause.

    Posted Nov 29 2007, 10:01 PM by Brian Peek with 35 comment(s)
    Filed under: ,

  • x64 Development with .NET

    Earlier this year I made the switch to a 64-bit operating system - Vista Ultimate x64 to be exact.  For the most part, this process has been relatively painless, but there have been a few hiccups along the way (x64 compatible drivers, mainly, but that's not the point of this discussion).

    In the world of x64 development, there have been a few struggling points that I thought I'd outline here.  This list will likely grow, so expect future posts on the matter.

    In the wonderful world of .NET development, applications and assemblies can be compiled to target various platforms.  By default, applications and assemblies are compiled as Any CPU in Visual Studio.  In this scenario, the CLR will load the assembly as whatever the default target is for the machine it is being executed on.  For example, when running an executable on an x64 machine, it will be run as a 64-bit process.

    Visual Studio also provides for 3 specific platform targets:  x86, x64 and Itanium (IA-64).  When building an executable as a specific target, it will be loaded as a process of that type.  For example, an x86-targeted executable run on an x64 machine will run as a 32-bit process using the 32-bit CLR and WOW64 layer.  When assemblies are loaded at runtime, they can only be loaded by a process if their target matches that of the hosting process, or it is compiled as Any CPU.  For example, if x64 were set as the target for an assembly, it can only be loaded by an x64 process.

    This has come into play in a few scenarios for me:

    • XNA - XNA is available as a set of 32-bit assemblies only.  Therefore, when referencing the XNA assemblies, the executable/assembly using them must be targeted to the x86 platform.  If it is targeted as x64 (or as Any CPU and run on a 64-bit machine), an error will be thrown when trying to load the XNA assemblies.
    • Microsoft Robotics Studio - The XInputGamepadService uses XNA internally to talk to the Xbox 360 controller.  See above.
    • Managed DirectX - While this is already deprecated and being replaced with XNA, it still has its uses.  The assemblies are not marked for a specific target, however I had difficulty with memory exceptions, especially with the Microsoft.DirectX.AudioVideoPlayback assembly.
    • Phidgets - Depending on what library you download and when, it may or may not be marked as 32-bit only.  The current version (11/8/07) is marked as such, and so requires a 32-bit process to host it.

    The easiest way to determine if an executable or assembly is targeted to a specific platform is to use the corflags application.  To use this, open a Visual Studio Command Prompt from your Start menu and run it against the assembly you wish to check.

    image

    Here's a handy table to decode the resulting information:

    CLR Header NOT the version of the CLR the file is compiled for
    2.0 = .NET 1.0 or 1.1
    2.5 = .NET 2.0
    PE PE header type
    PE32 = 32-bit
    PE32+ = 64-bit
    CorFlags Various flags for endian type, ILONLY, etc.
    ILONLY The file contains IL only (i.e. no unsafe code)
    32BIT 1 = x86 target
    0 = Any CPU target
    Signed 1 = Assembly signed
    0 = Assembly not signed

    And here is a second table showing the mapping from target to flags:

    Any CPU PE32 with 32BIT = 0
    x86 PE32 with 32BIT = 1
    x64/Itanium (IA-64) PE32+ with 32BIT = 0

    So how do you work around using 32-bit assemblies on a 64-bit platform?  There are two answers to this.

    Use corflags against the file with the /32BIT- switch to remove the x86 restriction.  This will make the assembly look like an "Any CPU" compilation.  Note that this will only work on unsigned assemblies.  If the assembly is signed, you can use the /Force switch to make the change, but this will likely just break the assembly and make it unusable.  I don't personally recommend using corflags since it's likely that if an assembly is distributed with this flag set, it's probably done that way for a reason.  So, let's look at method two.

    Create a new configuration which targets x86 and everything should work.  With the host process being forced to run as a 32-bit application, any 32-bit specific libraries will work just fine.  Here's how:

    1. From the Build menu, select Configuration Manager
    2. In the Active solution platform: drop down, select <New...>
      image
    3. In the Type or select new platform drop down, select x86
      image
    4. Click OK to get back to the main Visual Studio window and ensure the x86 configuration is selected in the build bar or in the Platform drop down in the project settings.
      image
    5. Rebuild the project

    Your output will now be located in the bin\x86 directory.

    In the next installment, I'll discuss some of the issues with using P/Invoke in .NET from the 64-bit world.

    Posted Nov 13 2007, 06:01 AM by Brian Peek with no comments
    Filed under: ,

  • Now Running Community Server 2007.1

    After a moderate amount of pain, I have finally updated the site to Community Server 2007.1.  I think everything is working.  I'm likely wrong.  Therefore if anyone sees anything that is not working, broken layouts, broken links, etc. PLEASE contact me and let me know so that I may correct it.

    One noteworthy item:  The new official URL for the blog is www.brianpeek.com/blog/ .  The main site will 301 redirect you here.  The old /blogs address should also 301 you here as well.  If you're seeing any weirdness there, again, please contact me.

    Thanks!

    Posted Nov 02 2007, 04:54 AM by Brian Peek with no comments
    Filed under:

Copyright (C) 2008 Brian Peek
Powered by Community Server (Commercial Edition), by Telligent Systems