diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/convert/nwconv/loghours.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to '')
-rw-r--r-- | private/nw/convert/nwconv/loghours.c | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/private/nw/convert/nwconv/loghours.c b/private/nw/convert/nwconv/loghours.c new file mode 100644 index 000000000..5276767a5 --- /dev/null +++ b/private/nw/convert/nwconv/loghours.c @@ -0,0 +1,310 @@ +/*++ + +Copyright (c) 1987-1993 Microsoft Corporation + +Module Name: + + loghours.c + +Abstract: + + Private routines to support rotation of logon hours between local time + and GMT time. + +Author: + + Cliff Van Dyke (cliffv) 16-Mar-93 + +Environment: + + User mode only. + Contains NT-specific code. + Requires ANSI C extensions: slash-slash comments, long external names. + +Revision History: + +--*/ + +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +#include <windef.h> +#include <winbase.h> + +#include <limits.h> +#include <math.h> + +#include <lmcons.h> +#include <lmaccess.h> +#include <loghours.h> + + + +BOOLEAN +NetpRotateLogonHoursPhase1( + IN BOOL ConvertToGmt, + OUT PULONG RotateCount + ) + +/*++ + +Routine Description: + + Determine the amount to rotate the logon hours by to convert to/from GMT + +Arguments: + + ConvertToGmt - + True to convert the logon hours from local time to GMT relative + False to convert the logon hours from GMT relative to local time + + RotateCount - Returns the number of bits to shift by. + +Return Value: + + TRUE if the RotateCount could be computed + FALSE if a RotateCount could not be computed + +--*/ +{ + RTL_TIME_ZONE_INFORMATION tzi; + LONG BiasInHours; + NTSTATUS Status; + + // + // Get the timezone data from the registry + // + + Status = RtlQueryTimeZoneInformation( &tzi ); + if ( !NT_SUCCESS(Status) ) { + return FALSE; + } + + // + // Compute the amount to rotate the logon hours by + // + // Round the bias in minutes to the closest bias in hours. + // Take into consideration that Bias can be negative. + // Do this by forcing the Bias to be positive, rounding, + // then adjusting it back negative again. + // + + ASSERT( tzi.Bias > -(24*60) ); + BiasInHours = ((tzi.Bias + (24*60) + 30)/60) - 24; + + if ( !ConvertToGmt ) { + BiasInHours = - BiasInHours; + } + + *RotateCount = BiasInHours; + return TRUE; + +} + + +BOOLEAN +NetpRotateLogonHoursPhase2( + IN PBYTE LogonHours, + IN DWORD UnitsPerWeek, + IN LONG RotateCount + ) + +/*++ + +Routine Description: + + Rotate the LogonHours bit mask by the required amount. + + +Arguments: + + LogonHours - Pointer to LogonHour bit mask + + UnitsPerWeek - Number of bits in the bit mask. Must be UNITS_PER_WEEK (168). + + RotateCount - Number of bits to rotate by. Must be between 31 and -31. + Negative means to rotate left. + Positive means to rotate right. + +Return Value: + + TRUE if the rotation succeeded. + FALSE if a parameter was out of range + +--*/ +{ + // + // Useful constants + // + +#define DWORDS_PER_WEEK ((UNITS_PER_WEEK+31)/32) +#define BYTES_PER_WEEK (UNITS_PER_WEEK/8) + + DWORD AlignedLogonHours[DWORDS_PER_WEEK+1]; + LONG i; + + BOOLEAN RotateLeft; + + // + // Ensure there are 8 bits per byte, + // 32 bits per DWORD and + // units per week is even number of bytes. + // + + ASSERT( CHAR_BIT == 8 ); + ASSERT( sizeof(DWORD) * CHAR_BIT == 32 ); + ASSERT( UNITS_PER_WEEK/8*8 == UNITS_PER_WEEK ); + + + // + // Validate the input parameters + // + + if ( UnitsPerWeek != UNITS_PER_WEEK ) { + ASSERT( UnitsPerWeek == UNITS_PER_WEEK ); + return FALSE; + } + + if ( RotateCount == 0 ) { + return TRUE; + } + + RotateLeft = (RotateCount < 0); + RotateCount = labs( RotateCount ); + if ( RotateCount > 31 ) { + ASSERT ( RotateCount <= 31 ); + return FALSE; + } + + + // + // Do the left rotate. + // + + if (RotateLeft) { + + + // + // Copy the logon hours to a DWORD aligned buffer. + // + // Duplicate the first dword at the end of the buffer to make + // the rotation code trivial. + // + + RtlCopyMemory(AlignedLogonHours, LogonHours, BYTES_PER_WEEK ); + + RtlCopyMemory( ((PBYTE)AlignedLogonHours)+BYTES_PER_WEEK, + LogonHours, + sizeof(DWORD) ); + + // + // Actually rotate the data. + // + + for ( i=0; i < DWORDS_PER_WEEK; i++ ) { + AlignedLogonHours[i] = + (AlignedLogonHours[i] >> RotateCount) | + (AlignedLogonHours[i+1] << (32-RotateCount)); + } + + // + // Copy the logon hours back to the input buffer. + // + + RtlCopyMemory( LogonHours, AlignedLogonHours, BYTES_PER_WEEK ); + + + // + // Do the right rotate. + // + + } else { + + + // + // Copy the logon hours to a DWORD aligned buffer. + // + // Duplicate the last DWORD at the front of the buffer to make + // the rotation code trivial. + // + + RtlCopyMemory( &AlignedLogonHours[1], LogonHours, BYTES_PER_WEEK ); + RtlCopyMemory( AlignedLogonHours, + &LogonHours[BYTES_PER_WEEK-4], + sizeof(DWORD)); + + // + // Actually rotate the data. + // + + for ( i=DWORDS_PER_WEEK-1; i>=0; i-- ) { + AlignedLogonHours[i+1] = + (AlignedLogonHours[i+1] << RotateCount) | + (AlignedLogonHours[i] >> (32-RotateCount)); + } + + // + // Copy the logon hours back to the input buffer. + // + + RtlCopyMemory( LogonHours, &AlignedLogonHours[1], BYTES_PER_WEEK ); + + } + + // + // Done + // + + return TRUE; + +} + + + +BOOLEAN +NetpRotateLogonHours( + IN PBYTE LogonHours, + IN DWORD UnitsPerWeek, + IN BOOL ConvertToGmt + ) + +/*++ + +Routine Description: + + Rotate the LogonHours bit mask to/from GMT relative time. + + +Arguments: + + LogonHours - Pointer to LogonHour bit mask + + UnitsPerWeek - Number of bits in the bit mask. Must be UNITS_PER_WEEK (168). + + ConvertToGmt - + True to convert the logon hours from local time to GMT relative + False to convert the logon hours from GMT relative to local time + +Return Value: + + TRUE if the rotation succeeded. + FALSE if a parameter was out of range + +--*/ +{ + ULONG RotateCount; + + // + // Break the functionality into two phases so that if the caller is doing + // this multiple time, he just calls Phase 1 once and Phase 2 multiple + // times. + // + + if ( !NetpRotateLogonHoursPhase1( ConvertToGmt, &RotateCount ) ) { + return FALSE; + } + + return NetpRotateLogonHoursPhase2( LogonHours, UnitsPerWeek, RotateCount ); + +} |