PsGetVersion, the only DDI1 to get the OS version information such as minor and major version, service pack level etc in Windows 2000, was behaving odd in a driver that I was debugging the other day. The DDI is declared in ntddk.h like below.
The DDI is supposed to return the service pack string (SP4 would show up as “Service Pack 4“) in the last parameter CSDVersion. But it was returning NULL string always. Obviously this problem could not have been happening all the time since the driver had been in use for some time.
It turns out that this is documented behaviour of this DDI. In the description for parameter CSDVersion documentation says
…returns the current service-pack version as a Unicode string only during system driver initialization. This optional parameter can be NULL.
In the Comments section documentation helpfully reiterates
…When the registry is initialized, a driver cannot obtain this string from PsGetVersion, but must read the CmCSDVersionString2 value from the registry.
That would explain why PsGetVersion works during boot but does not work if the driver is loaded later. Interestingly, PsGetVersion‘s younger sibling, RtlGetVersion , does not seem to have any eccentricity like that according to documentation but it actually does. It never3 fills in the RTL_OSVERSIONINFOW.szCSDVersion or RTL_OSVERSIONINFOEXW.szCSDVersion regardless of whether the call is made at boot time or afterwards4.
For a Windows 2000 demand start driver, one has to query registry for the service pack string which is an annoyance. But this has me befuddled and curious as to what purpose clearing out service pack string during Session Manager startup serves.5
1 You are supposed to use RtlGetVersion on Windows XP onwards to get the version information. RtlGetVersion is not available on Windows 2000 Update Rollup 1 v2.
2What the documentation means is CSDVersion REG_SZ value (which lives under HKLM\Software\Microsoft\Windows NT\CurrentVersion)
3I checked on x86 Vista Service Pack 1
4 The wServicePackMajor and wServicePackMinor members indicate the Service Pack so this really does not turn out to be an issue. But this is a deviation from the documentation none the less.
5 Given all this one cannot help but ask how difficult would it have been to add support for RtlGetVersion in Windows 2000 as part of the rollup package so drivers can check the service pack level without hassles ? Trivial would be my guess.