Thursday, May 31, 2007

XPe tip #45: EWF and Cloning

I guess the topic has been discussed in the newsgroup quite many times but since I just happened to run into a related issue and fixed the runtime I thought I should cover this in some details on this blog.

What if you are tasked to create an embedded image that must include EWF and will be deployed to devices as is. In other words, there won't be technicians who can fix known issues with the image deployment in field.

I am only going to cover here the case where all the target devices are identical - the same type of the hardware and number and type of peripherals attached. If this is not the case, it should be adopted/modified dependning on what hardware modifications you plan to do in the field (such as changing partition setup and so on).

The task first seem to be trivial - you just have to properly clone the image on multiple target devices. Dependening on how you plan the clonig process (factory mode, etc.) and what's the target working environment will be (LAN, domain network, Internet, etc.) you will or will not include and setup the System Cloning Tool component.

Unfortunately, that is only going to be that easy if you use EWF RAM Reg mode. The reason is simple - in RAM Reg mode EWF stores all the configuration settings in registry. So when you copy the image to another device, all the EWF settings will be properly copied along with that. No need to worry about hidden partitions and such. You can simply use xcopy to copy the image files. Certainly, cloning tools such as Ghost or Altiris can be used as well no problem.

However, in you happened to use EWF RAM or Disk mode you got yourself in troubles. If you just xcopy the image (or use ghost tools the same way you'd use to capture as smallest image as possible) at the cloned system launch you will notice that EWF is not working. If you execute EwfMgr commands it will report the it cannot find the EWF volume (and there it will refer to the EWF config volume that stores all the EWF configuration settings and, in case of EWF Disk mode, the overlay data). Obviosly, with the Windows standard tools (xcopy and etc.) you won't be even able to see the EWF partition. So another approach shuld be taken and here is a few I can think of:

1) Use Ghost's -IR switch (or similar switch of another cloning tool if suported) when capturing the golden image. It forces the ghost to grab every raw data byte of the source disk vs going through the file system to copy only files as the ghost without IR switch does.
Big disadvanges of this solution is that depending on the target device's hard disk setup you may end up with a GHO file with a huge size (ghost with IR switch doesn't know anything about files on the disk and capturing every single byte of the specified storage device). Also, this way you won't be able to operate and clone partitions, only entire disks.

2) Create a tool that will copy over the hidden EWF partition to all the target devices. Something like WinHEX editor or any partition management tool that allows you to view and save the content of disk sectors would help you here. I typically use Paragon Partition Manager for that.
This approach is quite complicated and not easy to automate without a 3rd party tool which may add some extra licensing to your device production.

3) Have EWF disabled in the golden image and re-enable it on the cloned runtime very early at the first boot. You can then xcopy the image files to target devices or use Ghost the regular way (FS aware).
However, this would only work if you re-create the EWF Config partition on the cloned image. Here is the command that will help you to accomplish that:
rundll32 ewfdll.dll, ConfigureEwf
- or -
rundll32 ewfdll.dll, ConfigureEwf Start
(both seem to have worked for me)

You can launch this command with a FBA Generic command set up to run after the cloning phase (phase number > 12000) or use [HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce] key or Startup Menu item if the Explorer Shell is used in the runtime. Otherwise you can use [HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon],"UserInit" key to add more command you want to run at run time. Just make sure to clean up that key and return its value to original (default) when the job is done. If you do all the commands from a batch file that will also add some .reg files that will do it.

Obviously, after you created the EWF Config partition you will need to issue "ewfmgr : -enable" command and reboot the target device so that EWF can take that command in affect. Again, all these commands are easy to combine in one batch script file.

4) Switch to use EWF RAM Reg mode. After all, there is almost no advantages of EWF RAM mode over the RAM Reg mode (except the ability to use -disable command). However, EWF with Disk Overlay has its own value that would be hard to replace with EWF RAM.

Friday, May 25, 2007

XPe tip #44: Where are the system shurtcuts?

Where the system shortcuts are coming from? Administrative Tools, Programs, Programs\Accessories (Accessibility, Communications, System Tools, Entertainment), Games, Messenger, Movie Maker, Wireless Network Setup Wizard, Remote Assistance, Windows Media Player?
The answer is trivial - "Standard Start Menu Shortcuts"component.

Btw, that component is a great resource for those who wants to learn how to create shortcuts on XPe directly in TD.

XPe tip #43: CDFS/UDFS

Problems accessing the content of CD or DVD under XPe keep being posted in the newsgroup.

The tip here is very simple - include the CDFS/UDFS components - CD/DVD file systems.
This is surely going to work assuming you've got all the CD-ROM/DVD-ROM driver issues resolved first.

XPe tip #42: Media file metadata access

This interesting post in the newsgroup led me to discovering another nasty bug of latest XP Embedded bits (SP2, FP2007).

Basically the issue was that the poster was having troubles accessing the metadata of media files on an NTFS partition. More specifically, their script code that called to getDetailsOf method of the Shell.Application object was failing to return proper results but returned the success error code.

The issue showed up when the developer moved to FP2007. First thought was the problem was there due to a missing component that could disappear (vs old builds) because of the major re-factoring Microsoft did in that Feature Pack.

However, the source of the problem was in the new component that was added to the database update - "Windows Media Player 10.0". The previous player components - "Windows Media Player 8.0" and "Windows Media Player 9.0" (this one is ghost component) - included the shmedia.dll library but the Player 10 didn't. That library is actually responsible for parsing file content, that shell API are loading up, and extracting and parsing the metadata that file may contain. That metadata is heavily used by newest media file grouping feature of Explorer shell with Windows Media Player instead on XP system.

Conclusion: make sure to include shmedia.dll library and register it (it is a COM object so you want to use the regsvr32 tool at run time or simply add a FBA DLL/COM Registration resource command in TD.
Note that the shmedia.dll library is surely in the XPe repository because of the previous versions of the player component.

Wednesday, May 23, 2007

XPe tip #41: "Processor scheduling" registry setting

How to preset Processor scheduling settings in TD?
These settings you can get to from Control Panel-->System-->Advanced-->Settings (Performance)-->Advanced (Processor scheduling section).
Answered here.

The Processor scheduling settings are mapped to the following registry value:
[HKLM\SYSTEM\CurrentControlSet\Control\PriorityControl],"Win32PrioritySeparation".

You can overwrite this value in the Registry Data section of the "Client / Server Runtime (Console)" component.

This binary mask value should be set to (or just include) 0x18 to optimize the system to use a greater share of processor time to run background services.

The mask can actually be tuned much more precisely with setting particular bits of the value. More info on the bits meanings can be found here.
For instance. Clicking Background services sets the value of this entry to 011000 (0x18), and provides for longer, fixed-length processor intervals in which foreground processes and background processes get equal processor priority.

XPe tip #40: "Adjust for best performance" registry setting

How to preset Visual Effects settings in TD? These settings you can get to from Control Panel-->System-->Advanced-->Settings (Performance)-->Visual Effects.
Answered here.

The Visual Effects settings are mapped to the following registry value:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects],"VisualFXSetting".
That flag should be set to 2 to optimize the system for best performance. Value 1 is for best appearance.

The same value could be set under HKEY_LOCAL_MACHINE branch to affect all user accounts (global policy). Or under HKEY_USERS\.DEFAULT branch to effect the default user accounts as well as all other user accounts since on XPe they all use Default User settings for defaults during FBA.

No component in TD brings in that registry value by default. It is probably getting [re]set during FBA.

XPe tip #39: Prevent BSOD from locking device

There was a topic we have covered in the newsgroup long time ago I thought I'd want to have listed here as a tip.

We are all familiar with XP famous BSOD - blue screen of death - a stop error displayed after encountering a critical system error. BSOD on 2K/XP is basically first chance exception within the kernel space (the kernel code or a kernel driver) that the system cannot recover and therefore has to shutdown the system. Instead they first show the exception info and, if set up properly, dumping the memory to a crash dump file.

How to prevent the system from showing BSOD? That may be important on an embedded device that is setup to be headless or does not require user interaction during normal hours of operation.

Only way to do that I know of is by setting the following registry entry:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CrashControl],"AutoReboot"=dword:1
that is mapped to XP's Control Panel/System/Advanced/Settings (Startup & Recovery)/System Failure/Check-Automatically Restart GUI element.

This registry value belongs to "Computer Prototype" component and in TD can be set (modified) under HAL (PC) component registry data section (e.g., "Standard PC" or "Advanced Configuration and Power Interface (ACPI)").

Sunday, May 20, 2007

XPe tip #38: Ramdisk drivers

Newbies on XPe often confuse the "Windows Ram Disk driver" component with a ramdisk that they may want to use a a temporarily file storage for things like Internet Explorer cache and etc. That component, however, is only a ramdisk driver that is used in RAM boot (Remote boot) scenarios and gets loaded by the loader to emulate the system running off a ramdisk (the entire image is copied to RAM and launched from there).
More info about the RAM boot can be found here.

There are quite many ramdisk driver for creating a device that can be used as a temporary storage available on the Web and created for Windows 2K/XP. For instance, the one from picobay.com.

However, I prefer not dealing with extra software licensing on XPe and tend to use sample driver from sources like Microsoft, CodeProject.com, CodeGuru.com and such where I can always modify the driver to meet my system requirements or simply compile it and use for free.
Here is a couple driver with their sources I used on XPe:
- Microsoft RamDisk sample driver.
Note: this one was created for Windows 2000 but an extremely easy to port to XP and the require porting steps are mentioned in the knowledge base article linked.

- CodeGuru's driver.

Note that for both drivers there are some settings (the ramdisk size and so on) that you may want to preset in the registry while integrating into your XPe.

Honestly I have happened to use other 3rd party ramdisk drivers on XPe but those were tied to customer's SKU's, required an additional license costs and not to be listed here. More ramdisk driver sources I mentioned in the newsgroup.

XPe tip #37: mpnotify.exe is not held by any component

There was an important and interesting post in the newsgroup recently that I have missed due to the MEDC and WinHEC conference attending.

The problem posted was about some API function (such as NPLogonNotify) not working under a full blown XPProEmulation XPe image. Obviously the issue was there not due to a missing component since XPProEmulation virtually includes all software components from the XPe database.
From the newsgroup thread you will see that the debugging the poster team has done showed that their own credential manager was working fine on Desktop OS and only failed to get notifications under XPe with interactive logon.

It appeared that the issue was there due to missing mpnotify.exe - the executable that is responsible for issuing Winlogon notification to registered network credential providers. The NPLogonNotify won't work if mpnotify.exe is not running (e.g., missing or crashed). Basically, it is the mpnotify.exe process who calls the NPLogonNotify function of the network provider .dll file.
The above fact is perfectly documented in this Microsoft Knowledge Base article.

The problems with XP Embedded is that although the mpnotify.exeis in the XPe Repository it doesn't belong to any component. It is basically left out from the component database which makes it harder to include in the image if you don't know what is required to get Network Providers to work and being notified by Winlogon.

A couple more useful links for the proper credential manager Dll integration into your image:
- Required authentication registry keys
- A very good guide written for Logon Filters - a sample credential manager from CodeProject.com.

Saturday, May 19, 2007

XPe tip #36: Changing IP with EWF/FBWF On

There was an interesting topic recently covered in the newsgroup where I had to spend some time to answer the poster questions and got some new knowledge (as very usual while answering other's questions in the newsgroup, btw :-) ) about Microsoft's Registry Filter component.

I won't go into details of that conversation (read in on the newsgroup archive if you wish) but I will just summarize the task, the problem and the solution.

Prerequisites: We have an embedded device running XP Embedded image with EWF or FBWF filter protecting the system partition including system registry hives.

The task: For a person administrating the device (IT, end user, whoever with the sufficient rights to access the network stack on the device) it is required to change system network settings to either switch to required static IP or, if already a static IP used, change the IP address.

The problem: With the write filter protecting the system registry it will be required to commit the entire system registry hive in order to make the IP address change persistent. With EWF it is even worse - you have to commit the entire system volume to accomplish that. The bad part there is that along with the IP changed you will commit all user modifications he might have done on the device and in the system registry. Often, those modifications are undesirable and lead to an unstable device (the beauty of the WF protection of the system volume is getting lost). I am not even touching the sensitive area of viruses and malicious software that a networked device might be exposed to.

The solution: What if we only commit the changes related to the IP settings in registry (what those are? see below...) and leave the system with the fully protected system volume yet.
Yes, it is possible with the component called Registry Filter which has become public within Feature Pack 2007 (there was a QFE for SP2 release that brought in the Registry Filter but that QFE was only available to OEMs).

The Registry Filter was only created by Microsoft to fix the famous issues with Domain Secret Key and TSCAL (license for Terminal Server client). However, the way the component works allows you (undocumentaly, of course) to use it in the purpose of working around some other issues with Write Filter protecting the system volume.

The way Registry Filter works is that it allows you to specify registry keys to make them persistent across reboots while the write filter is ON. Basically Registry Filter creates and initializes a file-backed ramdisk - the hidden system regfData file under the root of the system volume. On that ramdisk it stores files that contain the selected key contents.

My suspicion (as I indicated here) is that the way the \regfData gets away from the EWF protection is through a mechanism similar to the EwfMgrCommitFile. On FBWF, of course, it is much easier to by-pass the protection for the selected file since this filter is file system aware and doesn't require a hack like the EwfMgrCommitFile API.

Now, when we know how the Registry Filter works, lets try to use its functionality to "unprotect" other registry keys we may need to may persistent across reboots with the write filter enabled on the system volume and system registry hives.
Sample registry entries that have to be added to your XPe image at the design time (at run time of design) I already showed in the newgroup. (Note: now we know the time zone info is not the right key for monitoring because of the way Registry Filter gets started - it gets started after the system checks for time)
Here is a sample for reference:
[HKEY_LOCAL_MACHINE\ControlSet001\Services\RegFilter\Parameters\MonitoredKe­ys\2]
"ClassKey"="HKLM"
"FileNameForSaving"="YourFileName.rgf"
"RelativeKeyName"="Software\YourRegistryBranch"

But what are the keys that have to be set for monitoring by Registry Filter to make the IP change persistent?
Initially I thought these:
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{}],"IPAddress"
and
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\{}\Parameters\Tcpip],"IPAddress"

But after I've done some tcpip driver stack debugging it is clear to me that the first key is the important one. The second will be auto-reset by the system (tcpip driver will refresh the values there grabbing the values from the first key).

So, cool, this means that we just have to add in registry at run time something like the following and it should work:
[HKEY_LOCAL_MACHINE\ControlSet001\Services\RegFilter\Parameters\MonitoredKe­ys\2]
"ClassKey"="HKLM"
"FileNameForSaving"="TcpIp.rgf"

"RelativeKeyName"="SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{}"

Note1: The CurrentControlSet is used here correctly. But in case you like the actual ControlSet00X key please make sure you work with the right one that gets used for the hardware configuration you are working with (typically the ControlSet001 on the XPe images by default).
Note2: Replace the interface GUID with the real GUID you can read off the registry at run time and that gets generated unique for your NIC adapter and interface.

The problem #2: No, the above didn't work and that is what the initial poster indicated.
The IP gets changed and the system is ping'able. However, as soon as you reboot the ipconfig.exe tool will report the old IP address that you had before the IP change. While the Tcpip GUI (the UI you get to when you go to the network connection properties) or netsh commands report the new IP. I should also note here that the actual IP of the system that you can feel on the network is still the old IP.
Why?

The upgraded solution: After some debugging I've done for the tcpip stack on XP as well as the Registry Filter and EWF components the issue appeared to be related to the loading order of the filter driver. Let me quote myself from the newsgroup.

First I created an image where I could perfectly repro the problem (Minlogon, netsh, EWF, RegFilter). Then I debugged some system stacks to understand what's going on there when we change the IP with the RegFilter on and set to monitor the keys I mentioned earlier. (I picked up EWF vs FBWF to simplify the debugging, having FBWF there won't change the picture)

I must admit the result was a bit surprising to me. Despite the fact that the behavior of the protected system with IP changed and rebooted was quite strange - no sync in the results from ipconfig.exe tool and "netsh interface ip show address" command (the same as you'd do with TCPIP GUI) - the source of the problem was not in the Tcpip stack or the registry keys picked up for the monitoring. The tcpip driver (or a driver from the ipv4 stack) indeed reads the network adapters info into a buffer (link list) at initialization from the registry's Tcpip\Interfaces key. This, of course, includes the IP address settings. When you do "ipconfig /all" it doesn't really go into the registry again but rather queries the driver for that info stored in the cache (buffer). While the netsh commands are more "dynamic" and will scan and return the results from the registry.

It is important to understand that RegFilter doesn't make the monitored keys transparent to the registry hives. The RegFilter rather applies the new registry values - the values that were saved in the monitored key hives on the protected system volume's ramdisk - to the image's registry hives at the next boot time. Some time during the driver init it loads the ramdisk and reads the files on it. Then it sets the actual values in registry to whatever values it reads from the file contents on ramdisk.

The tcpip driver will populate the internal stack buffer very early during the system boot. Looks like the initialization actually happens before the RegFilter is loaded. This leads to the Tcpip structures populated with the old data but the registry info already reflected the new data (laid out by the RegFilter) after the boot. So we end up with the IP addresses reported out of sync between the ipconfig and the registry.

To summarize the above, the real problem there seems to be that the Regfilter and one of the drivers from Tcpip stack belong to the same driver load group. Without the RegFilter enabled the IP would be changed properly (assuming the change can be flushed). This fact is extremely easy to prove with the following simple experiment.
Forgot for a minute about the RegFilter. In fact remove the Tcpip related registry paths from its MonitorKeys branch, commit EWF and gracefully shutdown the image (now the RegFilter doesn't "unprotect" the tcpip keys). Load up the image SYSTEM hive offline (open it with a regedit on a XP Pro machine). Go to the [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{}] key and modify the value of the "IPAddress" property there. Unload the hive and boot to the embedded image and verify that the address has changed and is in sync between ipconfig and netsh results (or GUI). Note that you don't even have to mess with the [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\{}\Parameters\Tcpip] key as it will be automatically updated during the boot (tcpip driver does that at the init time).

It is also easy to confirm with a hex editor that the ramdisk image from the runtime contains the new registry value (new IP address) but the system registry hive has gotten the old one (and this is ok when you think about the Regfilter architecture and design).

So, what's left to fix the solution we created is to change the loading order of the interfering drivers. We can't mess much around the RegFilter driver - it is very dependent on the EWF/FBWF and, the same time, must be launched early at the system boot. So we only can fix the issue by moving the tcpip driver to load it later than the RegFilter and thus pick up the right values from registry hives.

The easiest way, perhaps, to accomplish that would be starting the tcpip driver by the Service Control Manager (SCM) instead of the kernel. The following value would do that:
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip],"Start"=dword:2.
That will put the driver in the auto-start group (started by the service control manager) instead of the system started (kernel or loader started).
This is a pretty safe change unless you've got some custom drivers in your image that demand the network connectivity (IP) very early at the system boot.

With the changes above committed (if you mess with all this at run time), you can try to change the IP and reboot (without an extra commit) and the IP should be the correct one reported by the netsh (or GUI) and the ipconfig as well. At least this is what I am seeing working here.

Just a side note: Domain Secret Key and TSCAL issues were "easier" to fix for Microsoft with the RegFilter approach since those keys are only read late at the boot process (by Winlogon and Terminal Services components).

Thursday, May 10, 2007

MCE tip #3: Filter "More Programs" items

I had a need to hide some items under "More Programs" menu in Vista Media Center app.
Unfortunately there appeared to be no way to create a real filter that would help me to apply some "programmatic" criteria to such area of MCE. However, I just found the simplest way to hide items there. All you need to do is to remove the entry points (application registered in MCE) from the following key:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Extensibility\Entry Points]

For instance, I knews that the following registry key:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Extensibility\Entry Points\{115EADF1-41C4-471b-8FE5-7A52B91BFE75}]
is the entrypoint for Chess Game item of the "More Programs" menu. It is easy to prove if you look under the key and find the "Run" value there. It points to %ProgramFiles%\Microsoft Games\Chess\ChessMCE.lnk shortcut which is obviously responsible for launching the Chess Game.
All I had to do to hide the Chess is to remove the entrypoint registry key.

The main reason I wanted to hide the game items (or any other registered program items) is that some of them still don't comply to the 10 foot UI requirements. Some games are totally 2' UI based and require mouse and keyboard - not sure who decided to put those in the MCE which is supposed to target TV users as well (and hopefully soon will not target PC users!).

Wednesday, May 9, 2007

MCE tip #2: How to launch Media Center app directly to the setup screen

There a re a few places on the web (e.g., The Green Button, Media Center Sandbox Blog, driverheaven.net, etc.) that discussed various way how to launch Media Center and direct it to particular applications. Two most command ways - command line arguments (directmedia and homepage switches) or sending a Win32 message to the MCE window with certain wParam and lParam settings.

I have read all the info and played with it myself. Too many limitations there. Basically you can only redirect the MCE to some [very few] applications - to Live TV, Video Library, etc..

A hacky way I tried - to grab the XML resource names off the MCE binaries - didn't work well. Most of the XML pages there require some machine state variables being passed from the main application entrypoint and this makes the MCE unstable. Mostly it just crashes at the launch.

Only helpful XML page I found I could bring up that way, that wasn't mentioned on the Web, was the Media Center Setup page. All you have to do is to launch MCE with the following command line:
%SystemRoot%\ehome\ehshell.exe /homepage:Options.SetupMediaCenter.xml /PushStartPage:True

Extending and fixing MCE

What you can do if you want to change some functional behaviour of MCE (Media Center application) or add some more functionality there? Or what you can do if you need to fix some 2 or 10 foot UI issues of the Media Center app?

Well, the only way I could come up with is - a global hook or Dll-injection. There are a few techniques known in Win32 world (I wish those exist in Windows CE as well :-) ) how to do the Dll injections (from writing to another process address space to the supported global hooks). Despite the fact that it may be a dangerous implementation (stability issues, lowering security, etc.) this is the only way that seems viable. Two main reasons:
- to have a better and faster implementation for your own monitoring agent application you'd probably want to stick to C/C++ to easier the access to Win32 APIs (P-Invoke's are costly and require lots of coding for missing header). MCE SDK doesn't allow you to write add-ins in native C++. (or perhaps it does but I didn't investigate this deep enough)
- too many limitations there on background add-ins for Vista MCE. You will always lose the MCE launch moment and some other events as well.

I have implemented a MCE hook-up agent that keeps monitoring the Media Center app on a complex of things - messages, windows, positions, etc. - including WM_INPUT (raw input messages), keyboard and mouse messages and etc.

A piece of advice - if you are playing with MCE on Vista, try to stay away from a service implementation for your app. On Vista, services are running in a separate, isolated Windows session (session 0) and it may take you an effort to implement the cross-session interface between your hook into MCE and the service. (not impossible but just over-complicates the implementation)

Tuesday, May 8, 2007

MVP Heroes Campaign

My photo got published on MSDN again :-)
I got a chance to participate in MVP Heroes Campaign program. My take-out from the campaign - Microsoft has an awesome Studio!

Monday, May 7, 2007

XPe tip #35: Language Packs

Recently I have forwarded a reply from Microsoft to the newsgroup in response to the question whether XPe supports Ukrainian MUI. The reply was negative - no, XPe doesn't have the Ukrainian language pack despite of the fact that there is XP Pro Language Pack exists for Ukraine locale.

Basically this means not all Language Packs that have been created for XP Professional were "ported" (componentized) for XP Embedded. Complete list of all the Language Packs for XPe (RTM, SP1, SP2) can be found here.