Remko Weijnen's Blog (Remko's Blog)

About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like

Archive for the ‘Windows Internals’ Category

When I was trying to delete a folder from my local harddrive (cygwin64 in my case) I got the following error message: “Invalid file handle.“:

Invalid file handle

I then attempted to delete the folder from the command prompt which failed as well with an “Access is denied” error:



Replacing WFP Protected files

imageOn Windows 2000, XP and Server 2003 a mechanism called Windows File Protection (WFP) is used to protect system integrity.

How does WFP Work?
Inside SFCFILES.DLL a list of files is kept that are monitored for changes. When a monitored file gets deleted, modified or overwritten WFP will restore the original from one of the following locations:

  • Cache Folder (%systemroot%\System32\DllCache)
  • Network Installation Path
  • Windows CD (or i386 folder on harddisk)

But what if we need to replace such a file? You could write a batch file that copies the modified file to the cache folder, installation path and destination. And this may work if it’s quick enough.

A more reliable method is to use an undocumented export from sfc_os.dll called SfcFileException (only exported by ordinal #5).


My Network Places Internals

Nethood IconI am using a PowerShell script to copy some elements of from the users old profile location to a new location. This includes the Nethood ("My Network Places") folder which contains the Network Places shortcuts.

A user reported that she could not save documents to Network Places anymore and after inspection the Network Places shortcuts were broken.

I started comparing the old Nethood folder to the new and observed the following difference in Explorer:


When copying entries from the Nethood folder with Explorer manually they worked fine, so somehow Explorer gives the Nethood folder special treatment.


DefaultPassword Dumper

Just a small post today: a small commandline utility that reads the “DefaultPassword” LSA secret.

This secret is stored in the registry under the SECURITY Hive:



If you want to check if you are running on a Server Core edition of Windows you can use the GetProductInfo API.

GetProductInfo takes 4 input parameters that can be obtained using GetVersionEx and the OSVERSIONINFOEX structure:

No we call GetProductInfo:




So a few days ago I got new memory for a development box – an upgrade from 4 to 6 GiB (later on even 8 GiB). Much appreciated as you can imagine. After dismissing the BIOS warning about changed amount of memory (oh really? :mrgreen:), I booted into Ubuntu and happily looked at the memory stats. After that I booted into Windows (a Windows 2003 Server Standard, but I’ll just use Windows from here on) and was disappointed to see only 4 GiB available. This is apparently a limitation specific to the Standard edition.

After some pouting, I decided to take action. Of course one of my first thoughts was to ask Remko, because he had done similar things for some other Windows versions. He pointed me to MmInitSystem, which was not an immediate hit, though. I loaded my kernel .exe into a disassembler to look at the details, but MmInitSystem was a lengthy and rather boring function. However, the advice was good and got me a good bit closer, especially when Remko also mentioned the use of ExVerifySuite in the logic that would set the limits. So I brought up the references to ExVerifySuite and – surprise surprise – only seven other functions used it and out of these only one was not recognized by name from the exports and debug symbols. And since the inspection of that function (at 0x00615FB0 in my kernel) proved that it was being called from MmInitSystem, this was an immediate hit.



In the previous parts (part 1 part 2) i’ve described the theoretical part and implementation problems. So, now we can write the code:

1) In case we login the user, we just call LsaLogonUser to get the token:

Windows XP introduced the ability to use Fast User Switching (FUS from here on), which is implemented using Terminal Services.

But in some cases (i.e. when FUS is not enabled, or when you connect to the console in Windows 2003 server), the Winlogon process in an RDP session needs to transfer credentials to Session 0.

Although not documented in MSDN, the process of transferring credentials is described by Keith Brown in the June 2005 issue of MSDN magazine: Customizing GINA, Part 2.

WlxQueryConsoleSwitchCredentials and WlxGetConsoleSwitchCredentials are used in the transfer with the semi-documented WLX_SAS_TYPE_AUTHENTICATED SAS code constant.

Internally, winlogon.exe uses a Named Pipe, \\.\Pipe\TerminalServer\AutoReconnect, to implement both of these functions.

The pipe format is described in this structure:

As you may know, Fast User Switching (FUS) is not available (disabled) on Windows XP computers joined to a domain, Microsoft confirms this in kb280758.

However, Microsoft doesn’t tell us there’s an undocumented registry value that allows us to have FUS when joined to a domain!

To enable FUS you need to set the DWORD registry value HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceFriendlyUI.

It can also be set by Group Policy at HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System.

When the value is set to 1, and LogonType key is also set to 1, it allows you to use a Friendly UI on a computer joined in a domain:

If you want to obtain a user’s token in a Terminal Server or Citrix session (eg to launch a process in a session) you can call the WTSQueryUserToken function.

On the x64 versions of Windows XP and Server 2003 this function fails however and returns ERROR_INSUFFICIENT_BUFFER (“The data area passed to a system call is too small.”) when called from a 32 bit process.

Internally WTSQueryUserToken calls the undocumented function WinstationQueryInformationW with the WinStationUserToken class (14) and passing a WINSTATIONUSERTOKEN struct, filled with caller ProcessId and ThreadId.

But on x64 Windows the size of this structure is 24 bytes, while on 32 bit Windows the size of the structure is 12 bytes!