WindowsXP-SP1/ds/nw/nwscript/time.c
2020-09-30 16:53:49 +02:00

183 lines
6.5 KiB
C

/*
* TIME.C - Various time subroutines needed by NetWare Login Script
*
* Copyright (c) 1995 Microsoft Corporation
*/
#include "common.h"
// Needed to convert netware net date to DOS date
#define _70_to_80_bias 0x012CEA600L
#define SECS_IN_DAY (60L*60L*24L)
#define SEC2S_IN_DAY (30L*60L*24L)
#define FOURYEARS (3*365+366)
WORD MonTotal[] = { 0, // dummy entry for month 0
0, // days before Jan 1
31, // days before Feb 1
31+28, // days before Mar 1
31+28+31, // days before Apr 1
31+28+31+30, // days before May 1
31+28+31+30+31, // days before Jun 1
31+28+31+30+31+30, // days before Jul 1
31+28+31+30+31+30+31, // days before Aug 1
31+28+31+30+31+30+31+31, // days before Sep 1
31+28+31+30+31+30+31+31+30, // days before Oct 1
31+28+31+30+31+30+31+31+30+31, // days before Nov 1
31+28+31+30+31+30+31+31+30+31+30, // days before Dec 1
31+28+31+30+31+30+31+31+30+31+30+31 // days before end of year
};
#define YR_MASK 0xFE00
#define LEAPYR_MASK 0x0600
#define YR_BITS 7
#define MON_MASK 0x01E0
#define MON_BITS 4
#define DAY_MASK 0x001F
#define DAY_BITS 5
#define HOUR_MASK 0xF800
#define HOUR_BITS 5
#define MIN_MASK 0x07E0
#define MIN_BITS 6
#define SEC2_MASK 0x001F
#define SEC2_BITS 5
static void NetToDosDate( DWORD time, WORD * dosdate, WORD * dostime )
{
DWORD secs, days;
WORD r;
time = (time - _70_to_80_bias) / 2; // # of 2 second periods since 1980
secs = time % SEC2S_IN_DAY; // 2 second period into day
days = time / SEC2S_IN_DAY; // days since Jan 1 1980
r = (WORD) ( secs % 30 ); // # of 2 second steps
secs /= 30;
r |= (secs % 60) << SEC2_BITS; // # of minutes
r |= (secs / 60) << (SEC2_BITS+MIN_BITS); // # of hours
*dostime = r;
r = (WORD) ( days / FOURYEARS );// (r) = four year period past 1980
days %= FOURYEARS; // (days) = days into four year period
r *= 4; // (r) = years since 1980 (within 3)
if (days == 31+28) {
//* Special case for FEB 29th
r = (r<<(MON_BITS+DAY_BITS)) + (2<<DAY_BITS) + 29;
} else {
if (days > 31+28)
--days; // compensate for leap year
while (days >= 365) {
++r;
days -= 365;
}
for (secs = 1; days >= MonTotal[secs+1] ; ++secs)
;
days -= MonTotal[secs];
r <<= MON_BITS;
r += (WORD)secs;
r <<= DAY_BITS;
r += (WORD)days+1;
}
*dosdate = r;
}
void nwShowLastLoginTime(VOID)
{
LONG lTime = 0L;
SYSTEMTIME st;
FILETIME ft;
TIME_ZONE_INFORMATION tz;
WCHAR szTimeBuf[TIMEDATE_SIZE];
WCHAR szDateBuf[TIMEDATE_SIZE];
int ret;
WORD dostime, dosdate;
DWORD tzStat;
if ( ret = NDSGetUserProperty ("Last Login Time", (PBYTE)&lTime,
4, NULL, NULL) )
{
#ifdef DEBUG
OutputDebugString("NWLSPROC: error getting LOGIN TIME\n\r");
#endif
return;
}
// From NetWare we get seconds from 1970, need to go through
// several conversions to get system time for NLS
// First deduct bias from UTC time to correct for local time
tzStat = GetTimeZoneInformation(&tz);
if ( tzStat != (DWORD)-1 ) {
if (tzStat == TIME_ZONE_ID_STANDARD)
tz.Bias += tz.StandardBias;
else if (tzStat == TIME_ZONE_ID_DAYLIGHT)
tz.Bias += tz.DaylightBias;
lTime -= tz.Bias*60;
}
#ifdef DEBUG
else {
OutputDebugString("NWLSPROC: GetTimeZoneInformation failed\n\r");
}
#endif // DEBUG
NetToDosDate( lTime, &dosdate, &dostime );
DosDateTimeToFileTime ( dosdate, dostime, &ft );
FileTimeToSystemTime ( &ft, &st );
#ifdef notdef
// I don't understand this comment, this code doesn't seem to be
// needed for NT. - terry
//
// This code will work on NT, but not on Win95.
// Convert the resulting system (UTC) time to local time
if ( GetTimeZoneInformation(&tz) != (DWORD)-1 ) {
SYSTEMTIME utcTime = st;
SystemTimeToTzSpecificLocalTime ( &tz, &utcTime, &st );
}
#ifdef DEBUG
else {
OutputDebugString("NWLSPROC: GetTimeZoneInformation failed\n\r");
}
#endif // DEBUG
#endif
wcscpy(szTimeBuf, L"");
ret = GetTimeFormat ( GetSystemDefaultLCID(),
TIME_FORCE24HOURFORMAT|TIME_NOTIMEMARKER,
&st,
NULL,
szTimeBuf,
TIMEDATE_SIZE );
#ifdef DEBUG
if ( !ret ) {
char buf[80];
wsprintf(buf,"NWLSPROC: GetTimeFormatA failure: %d sec:%ld\n\r",
GetLastError(), lTime );
OutputDebugString(buf);
}
#endif
ret = GetDateFormat(LOCALE_USER_DEFAULT,
DATE_LONGDATE,
&st,
NULL,
szDateBuf,
TIMEDATE_SIZE );
#ifdef DEBUG
if ( !ret ) {
char buf[80];
wsprintf(buf,"NWLSPROC: GetDateFormatA failure: %d sec:%ld\n\r",
GetLastError(), lTime );
OutputDebugString(buf);
}
#endif
DisplayMessage( IDR_LASTLOGIN, szDateBuf, szTimeBuf );
}