views:

157

answers:

2

I'm using the WinAPI to set the time zone on a Windows XP SP3 box. I'm reading the time zone information from the HKLM\Software\Microsoft\WindowsNT\Time Zones\<time zone name> key and then setting the time zone to the specified time zone.

I enumerate the keys under the Time Zones key, grab the TZI value and stuff it into a TIME_ZONE_INFORMATION struct to be passed to SetTimeZoneInformation. All seems to work on the first pass. The time zone changes, no error is returned.

The second time I perform this operation (same user, new session, on login before userinit) the call succeeds but the system does not reflect the time zone change. Neither the clock nor time stamps on files are updated to the new time zone. When I navigate to: HKLM\System\CurrentControlSet\Control\TimeZoneInformation my new time zone information is present.

A couple strange things are happening when I'm setting my time zone:

  • Also when I parse the TZI binary value from the registry to store in my TIME_ZONE_INFORMATION struct I'm noticing the struct has the DaylightDate.wDay and StandardDate.wDay field always set to 0
  • I tried to call GetTimeZoneInformation right after I call SetTimeZoneInformation but the call fails with a 1300 error (Not all privileges or groups referenced are assigned to the caller. )

I'm also making sure to send a WM_BROADCAST message so Explorer knows whats going on.

Think it's the parsing of the byte array to the TIME_ZONE_INFORMATION struct? Or am I missing some thing else important?

EDIT:

Found a document stating why this is happening: here. Privilege was introduced in Vista...thanks MSDN docs...

Per the Microsoft documentation I'm enabling the SE_TIME_ZONE_NAME privilege for the current processes
token. But when I attempt to call
LookupPriviledgeValue for
SE_TIME_ZONE_NAME I get a 1313 error (A specified privilege does not exist. ).

+1  A: 

Try to use LsaAddAccountRights instead of LookupPrivilegeValue and AdjustTokenPrivileges to set SE_TIME_ZONE_NAME. See also this topic.

VitalyVal
Thanks for the idea but I think that the AdjustTokenPriviledge was working correctly. I edited the question because the SE_TIME_ZONE_NAME does not exist in XP.
Adam Driscoll
A: 

After messing with this for awhile I've fixed the issue but I'm not quite sure what step fixed it. I added an extra clause to check the OS to verify whether or not to adjust the process token to enable the SE_TIME_ZONE_NAME. It now only does this on post-XP OS's.

I also changed how the TZI registry value was stored into my struct. I realized that on the TIME_ZONE_INFORMATION MSDN document is contained the struct that is used for the registry verison (REG_TZI_FORMAT). Simply reading the binary value straight into the struct eliminated a bit of code.

I also guaranteed that BOTH DaylightName and StandardName were populated.

Finally I called a RegFlushKey(HKEY_LOCAL_MACHINE) right after the SetTimeZoneInformation call. After taking these steps the time zone is changing as expected.

Adam Driscoll