311 lines
6.2 KiB
C
311 lines
6.2 KiB
C
/*++
|
||
|
||
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 );
|
||
|
||
}
|