You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
615 lines
19 KiB
615 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
svcsrv.c
|
|
|
|
Abstract:
|
|
|
|
This module contains routines for supporting the server APIs in the
|
|
server service, SrvNetServerDiskEnum, and SrvNetServerSetInfo.
|
|
|
|
Author:
|
|
|
|
David Treadwell (davidtr) 31-Jan-1991
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include "svcsrv.tmh"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// Forward declarations.
|
|
//
|
|
|
|
LARGE_INTEGER
|
|
SecondsToTime (
|
|
IN ULONG Seconds,
|
|
IN BOOLEAN MakeNegative
|
|
);
|
|
|
|
LARGE_INTEGER
|
|
MinutesToTime (
|
|
IN ULONG Seconds,
|
|
IN BOOLEAN MakeNegative
|
|
);
|
|
|
|
ULONG
|
|
MultipleOfProcessors (
|
|
IN ULONG value
|
|
);
|
|
|
|
BOOL
|
|
IsSuiteVersion(
|
|
IN USHORT Version
|
|
);
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( PAGE, SrvNetServerDiskEnum )
|
|
#pragma alloc_text( PAGE, SrvNetServerSetInfo )
|
|
#pragma alloc_text( PAGE, SecondsToTime )
|
|
#pragma alloc_text( PAGE, MinutesToTime )
|
|
#pragma alloc_text( PAGE, MultipleOfProcessors )
|
|
#pragma alloc_text( PAGE, IsSuiteVersion )
|
|
#endif
|
|
|
|
#define IsWebBlade() IsSuiteVersion(VER_SUITE_BLADE)
|
|
#define IsPersonal() IsSuiteVersion(VER_SUITE_PERSONAL)
|
|
#define IsEmbedded() IsSuiteVersion(VER_SUITE_EMBEDDEDNT)
|
|
|
|
BOOL
|
|
IsSuiteVersion(USHORT Version)
|
|
{
|
|
OSVERSIONINFOEX Osvi;
|
|
DWORD TypeMask;
|
|
DWORDLONG ConditionMask;
|
|
|
|
memset(&Osvi, 0, sizeof(OSVERSIONINFOEX));
|
|
Osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
Osvi.wSuiteMask = Version;
|
|
TypeMask = VER_SUITENAME;
|
|
ConditionMask = 0;
|
|
VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR);
|
|
return(NT_SUCCESS(RtlVerifyVersionInfo(&Osvi, TypeMask, ConditionMask)));
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
SrvNetServerDiskEnum (
|
|
IN PSERVER_REQUEST_PACKET Srp,
|
|
IN PVOID Buffer,
|
|
IN ULONG BufferLength
|
|
)
|
|
{
|
|
PAGED_CODE( );
|
|
|
|
Srp, Buffer, BufferLength;
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
} // SrvNetServerDiskEnum
|
|
|
|
|
|
NTSTATUS
|
|
SrvNetServerSetInfo (
|
|
IN PSERVER_REQUEST_PACKET Srp,
|
|
IN PVOID Buffer,
|
|
IN ULONG BufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine processes the NetServerSetInfo API in the server FSD.
|
|
|
|
Arguments:
|
|
|
|
Srp - a pointer to the server request packet that contains all
|
|
the information necessary to satisfy the request. This includes:
|
|
|
|
INPUT:
|
|
|
|
None.
|
|
|
|
OUTPUT:
|
|
|
|
None.
|
|
|
|
Buffer - a pointer to a SERVER_INFO_102, followed immediately by a
|
|
SERVER_INFO_599 structure, followed by a SERVER_INFO_559a
|
|
structure. All information is always reset in this routine; the
|
|
server service also tracks this data, so when it gets a
|
|
NetServerSetInfo it overwrites the appropriate fields and sends
|
|
all the data.
|
|
|
|
BufferLength - total length of this buffer.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - result of operation to return to the server service.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS status = STATUS_INVALID_PARAMETER;
|
|
PSERVER_INFO_102 sv102;
|
|
PSERVER_INFO_599 sv599;
|
|
PSERVER_INFO_598 sv598;
|
|
|
|
LARGE_INTEGER scavengerTimeout;
|
|
LARGE_INTEGER alerterTimeout;
|
|
|
|
ULONG ipxdisc;
|
|
LARGE_INTEGER li;
|
|
ULONG bufferOffset;
|
|
ULONG keTimeIncrement;
|
|
|
|
PAGED_CODE( );
|
|
|
|
//
|
|
// Make sure that the input buffer length is correct.
|
|
//
|
|
if ( BufferLength < sizeof(SERVER_INFO_102) +
|
|
sizeof(SERVER_INFO_599) + sizeof(SERVER_INFO_598) ) {
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Set up buffer pointers as appropriate. The SERVER_INFO_599
|
|
// structure must immediately follow the SERVER_INFO_102 structure
|
|
// in the buffer.
|
|
//
|
|
|
|
sv102 = Buffer;
|
|
sv599 = (PSERVER_INFO_599)(sv102 + 1);
|
|
sv598 = (PSERVER_INFO_598)(sv599 + 1);
|
|
|
|
if( sv599->sv599_scavtimeout == 0 )
|
|
{
|
|
// This will cause a divide by zero later on
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// store the time increment count
|
|
//
|
|
|
|
keTimeIncrement = KeQueryTimeIncrement();
|
|
|
|
//
|
|
// Grab the lock that protects configuration changes.
|
|
//
|
|
|
|
ACQUIRE_LOCK( &SrvConfigurationLock );
|
|
|
|
//
|
|
// Set all configuration information in the server.
|
|
//
|
|
|
|
try {
|
|
|
|
SrvMaxUsers = sv102->sv102_users;
|
|
|
|
//
|
|
// The autodisconnect timeout must be converted from minutes to NT
|
|
// time, which has a base of 100s of nanoseconds. If the specified
|
|
// value is negative (top bit set), set the timeout to 0, indicating
|
|
// that no autodisconnect should be done. If the specified value is
|
|
// 0, meaning to autodisconnect immediately, set the timeout to a
|
|
// small value, but not 0.
|
|
//
|
|
|
|
if ( (sv102->sv102_disc & 0x80000000) == 0 ) {
|
|
if ( sv102->sv102_disc != 0 ) {
|
|
SrvAutodisconnectTimeout.QuadPart =
|
|
Int32x32To64( sv102->sv102_disc, 10*1000*1000*60 );
|
|
} else {
|
|
SrvAutodisconnectTimeout.QuadPart = 1;
|
|
}
|
|
} else {
|
|
SrvAutodisconnectTimeout.QuadPart = 0;
|
|
}
|
|
|
|
SrvInitialSessionTableSize = (USHORT)sv599->sv599_initsesstable;
|
|
SrvInitialTreeTableSize = (USHORT)sv599->sv599_initconntable;
|
|
SrvInitialFileTableSize = (USHORT)sv599->sv599_initfiletable;
|
|
SrvInitialSearchTableSize = (USHORT)sv599->sv599_initsearchtable;
|
|
SrvMaxFileTableSize = (USHORT)sv599->sv599_sessopens;
|
|
SrvMaxNumberVcs = sv599->sv599_sessvcs;
|
|
SrvMaxSearchTableSize = (USHORT)sv599->sv599_opensearch;
|
|
SrvReceiveBufferLength = sv599->sv599_sizreqbuf;
|
|
SrvReceiveBufferSize = (SrvReceiveBufferLength + SrvCacheLineSize) & ~SrvCacheLineSize;
|
|
SrvReceiveMdlSize = (ULONG)(MmSizeOfMdl( (PVOID)(PAGE_SIZE-1), SrvReceiveBufferSize ) + 7) & ~7;
|
|
SrvMaxMdlSize = (ULONG)(MmSizeOfMdl( (PVOID)(PAGE_SIZE-1), MAX_PARTIAL_BUFFER_SIZE ) + 7) & ~7;
|
|
SrvInitialReceiveWorkItemCount = sv599->sv599_initworkitems;
|
|
SrvMaxReceiveWorkItemCount = sv599->sv599_maxworkitems;
|
|
SrvInitialRawModeWorkItemCount = sv599->sv599_rawworkitems;
|
|
SrvReceiveIrpStackSize = (CCHAR)sv599->sv599_irpstacksize;
|
|
SrvReceiveIrpSize = (IoSizeOfIrp( SrvReceiveIrpStackSize ) + 7) & ~7;
|
|
SrvMaxSessionTableSize = (USHORT)sv599->sv599_sessusers;
|
|
SrvMaxTreeTableSize = (USHORT)sv599->sv599_sessconns;
|
|
SrvMaxPagedPoolUsage = sv599->sv599_maxpagedmemoryusage;
|
|
SrvMaxNonPagedPoolUsage = sv599->sv599_maxnonpagedmemoryusage;
|
|
SrvEnableSoftCompatibility = (BOOLEAN)sv599->sv599_enablesoftcompat;
|
|
SrvEnableForcedLogoff = (BOOLEAN)sv599->sv599_enableforcedlogoff;
|
|
SrvCoreSearchTimeout = sv599->sv599_maxkeepsearch;
|
|
SrvSearchMaxTimeout = SecondsToTime( SrvCoreSearchTimeout, FALSE );
|
|
SrvScavengerTimeoutInSeconds = sv599->sv599_scavtimeout;
|
|
scavengerTimeout = SecondsToTime( SrvScavengerTimeoutInSeconds, FALSE );
|
|
SrvMaxMpxCount = (USHORT)sv599->sv599_maxmpxct;
|
|
SrvWaitForOplockBreakTime = SecondsToTime( sv599->sv599_oplockbreakwait, FALSE );
|
|
SrvWaitForOplockBreakRequestTime = SecondsToTime( sv599->sv599_oplockbreakresponsewait, FALSE );
|
|
SrvMinReceiveQueueLength = sv599->sv599_minrcvqueue;
|
|
SrvMinFreeWorkItemsBlockingIo = sv599->sv599_minfreeworkitems;
|
|
SrvXsSectionSize.QuadPart = sv599->sv599_xactmemsize;
|
|
SrvThreadPriority = (KPRIORITY)sv599->sv599_threadpriority;
|
|
SrvEnableOplockForceClose = (BOOLEAN)sv599->sv599_enableoplockforceclose;
|
|
SrvEnableFcbOpens = (BOOLEAN)sv599->sv599_enablefcbopens;
|
|
SrvEnableRawMode = (BOOLEAN)sv599->sv599_enableraw;
|
|
SrvFreeConnectionMinimum = sv599->sv599_minfreeconnections;
|
|
SrvFreeConnectionMaximum = sv599->sv599_maxfreeconnections;
|
|
|
|
//
|
|
// Max work item idle time is in ticks
|
|
//
|
|
|
|
li = SecondsToTime( sv599->sv599_maxworkitemidletime, FALSE );
|
|
li.QuadPart /= keTimeIncrement;
|
|
if ( li.HighPart != 0 ) {
|
|
li.LowPart = 0xffffffff;
|
|
}
|
|
SrvWorkItemMaxIdleTime = li.LowPart;
|
|
|
|
//
|
|
// Oplocks should not be enabled if SrvMaxMpxCount == 1
|
|
//
|
|
|
|
if ( SrvMaxMpxCount > 1 ) {
|
|
SrvEnableOplocks = (BOOLEAN)sv599->sv599_enableoplocks;
|
|
} else {
|
|
SrvEnableOplocks = FALSE;
|
|
}
|
|
|
|
SrvProductTypeServer = MmIsThisAnNtAsSystem( );
|
|
|
|
SrvServerSize = sv598->sv598_serversize;
|
|
|
|
SrvMaxRawModeWorkItemCount = sv598->sv598_maxrawworkitems;
|
|
SrvMaxThreadsPerQueue = sv598->sv598_maxthreadsperqueue;
|
|
ipxdisc = sv598->sv598_connectionlessautodisc;
|
|
SrvConnectionNoSessionsTimeout = sv598->sv598_ConnectionNoSessionsTimeout;
|
|
|
|
SrvRemoveDuplicateSearches =
|
|
(BOOLEAN)sv598->sv598_removeduplicatesearches;
|
|
SrvMaxOpenSearches = sv598->sv598_maxglobalopensearch;
|
|
SrvSharingViolationRetryCount = sv598->sv598_sharingviolationretries;
|
|
SrvSharingViolationDelay.QuadPart =
|
|
Int32x32To64( sv598->sv598_sharingviolationdelay, -1*10*1000 );
|
|
|
|
SrvLockViolationDelay = sv598->sv598_lockviolationdelay;
|
|
|
|
SrvLockViolationOffset = sv598->sv598_lockviolationoffset;
|
|
|
|
SrvCachedOpenLimit = sv598->sv598_cachedopenlimit;
|
|
SrvMdlReadSwitchover = sv598->sv598_mdlreadswitchover;
|
|
SrvEnableWfW311DirectIpx =
|
|
(BOOLEAN)sv598->sv598_enablewfw311directipx;
|
|
SrvRestrictNullSessionAccess =
|
|
(BOOLEAN)sv598->sv598_restrictnullsessaccess;
|
|
|
|
SrvQueueCalc = SecondsToTime( sv598->sv598_queuesamplesecs, FALSE );
|
|
SrvPreferredAffinity = sv598->sv598_preferredaffinity;
|
|
SrvOtherQueueAffinity = sv598->sv598_otherqueueaffinity;
|
|
SrvBalanceCount = sv598->sv598_balancecount;
|
|
|
|
SrvMaxFreeRfcbs = sv598->sv598_maxfreerfcbs;
|
|
SrvMaxFreeMfcbs = sv598->sv598_maxfreemfcbs;
|
|
SrvMaxPagedPoolChunkSize = sv598->sv598_maxpagedpoolchunksize;
|
|
|
|
SrvMaxCachedDirectory = sv598->sv598_cacheddirectorylimit;
|
|
|
|
SrvMaxCopyLength = sv598->sv598_maxcopylength;
|
|
|
|
SrvMinClientBufferSize = sv598->sv598_minclientbuffersize;
|
|
SrvMinClientBufferSize &= ~03;
|
|
|
|
SrvSmbSecuritySignaturesEnabled = (sv598->sv598_enablesecuritysignature != FALSE);
|
|
SrvSmbSecuritySignaturesRequired = (sv598->sv598_requiresecuritysignature != FALSE);
|
|
SrvEnableW9xSecuritySignatures = (sv598->sv598_enableW9xsecuritysignature != FALSE);
|
|
|
|
ServerGuid = sv598->sv598_serverguid;
|
|
|
|
SrvEnforceLogoffTimes = (sv598->sv598_enforcekerberosreauthentication != FALSE);
|
|
SrvDisableDoSChecking = (sv598->sv598_disabledos != FALSE);
|
|
SrvDisableStrictNameChecking = (sv598->sv598_disablestrictnamechecking != FALSE);
|
|
SrvFreeDiskSpaceCeiling = sv598->sv598_lowdiskspaceminimum;
|
|
|
|
//
|
|
// Make sure the settings are consistent!
|
|
//
|
|
if( SrvSmbSecuritySignaturesEnabled == FALSE ) {
|
|
SrvSmbSecuritySignaturesRequired = FALSE;
|
|
}
|
|
|
|
SrvMaxNonPagedPoolChunkSize = SrvMaxPagedPoolChunkSize;
|
|
|
|
SrvLockViolationDelayRelative.QuadPart =
|
|
Int32x32To64( sv598->sv598_lockviolationdelay, -1*10*1000 );
|
|
|
|
//
|
|
// Convert the idle thread timeout from seconds to ticks
|
|
//
|
|
SrvIdleThreadTimeOut =
|
|
Int32x32To64( sv598->sv598_IdleThreadTimeOut, -1*10*1000*1000 );
|
|
|
|
//
|
|
// Calculate switchover number for mpx
|
|
//
|
|
|
|
bufferOffset = (sizeof(SMB_HEADER) + sizeof(RESP_READ_MPX) - 1 + 3) & ~3;
|
|
|
|
if ( SrvMdlReadSwitchover > (SrvReceiveBufferLength - bufferOffset) ) {
|
|
|
|
SrvMpxMdlReadSwitchover = SrvReceiveBufferLength - bufferOffset;
|
|
|
|
} else {
|
|
|
|
SrvMpxMdlReadSwitchover = SrvMdlReadSwitchover;
|
|
}
|
|
|
|
//
|
|
// The IPX autodisconnect timeout must be converted from minutes to
|
|
// ticks. If 0 is specified, use 15 minutes.
|
|
//
|
|
|
|
if ( ipxdisc == 0 ) {
|
|
ipxdisc = 15;
|
|
}
|
|
li.QuadPart = Int32x32To64( ipxdisc, 10*1000*1000*60 );
|
|
li.QuadPart /= keTimeIncrement;
|
|
if ( li.HighPart != 0 ) {
|
|
li.LowPart = 0xffffffff;
|
|
}
|
|
SrvIpxAutodisconnectTimeout = li.LowPart;
|
|
|
|
//
|
|
// The "idle connection without sessions" timeout must be converted from
|
|
// minutes to ticks.
|
|
//
|
|
li.QuadPart = Int32x32To64( SrvConnectionNoSessionsTimeout, 10*1000*1000*60 );
|
|
li.QuadPart /= keTimeIncrement;
|
|
if( li.HighPart != 0 ) {
|
|
li.LowPart = 0xffffffff;
|
|
}
|
|
SrvConnectionNoSessionsTimeout = li.LowPart;
|
|
|
|
//
|
|
// Event logging and alerting information.
|
|
//
|
|
|
|
alerterTimeout = MinutesToTime( sv599->sv599_alertschedule, FALSE );
|
|
SrvAlertMinutes = sv599->sv599_alertschedule;
|
|
SrvErrorRecord.ErrorThreshold = sv599->sv599_errorthreshold;
|
|
SrvNetworkErrorRecord.ErrorThreshold =
|
|
sv599->sv599_networkerrorthreshold;
|
|
SrvFreeDiskSpaceThreshold = sv599->sv599_diskspacethreshold;
|
|
|
|
SrvCaptureScavengerTimeout( &scavengerTimeout, &alerterTimeout );
|
|
|
|
//
|
|
// Link Speed Parameters
|
|
//
|
|
|
|
SrvMaxLinkDelay = SecondsToTime( sv599->sv599_maxlinkdelay, FALSE );
|
|
|
|
SrvMinLinkThroughput.QuadPart = sv599->sv599_minlinkthroughput;
|
|
|
|
SrvLinkInfoValidTime =
|
|
SecondsToTime ( sv599->sv599_linkinfovalidtime, FALSE );
|
|
|
|
SrvScavengerUpdateQosCount =
|
|
sv599->sv599_scavqosinfoupdatetime / sv599->sv599_scavtimeout;
|
|
|
|
//
|
|
// Override parameters that cannot be set on WinNT (vs. NTAS).
|
|
//
|
|
// We override the parameters passed by the service in case somebody
|
|
// figures out the FSCTL that changes parameters. We also override
|
|
// in the service in order to keep the service's view consistent
|
|
// with the server's. If you make any changes here, also make them
|
|
// in srvsvc\server\registry.c.
|
|
//
|
|
|
|
//
|
|
// For Embedded systems, just take the registry value. They do their own
|
|
// validation of settings.
|
|
//
|
|
if( !IsEmbedded() )
|
|
{
|
|
if ( !SrvProductTypeServer ) {
|
|
|
|
//
|
|
// On WinNT, the maximum value of certain parameters is fixed at
|
|
// build time. These include: concurrent users, SMB buffers,
|
|
//
|
|
|
|
#define MINIMIZE(_param,_max) _param = MIN( _param, _max );
|
|
|
|
MINIMIZE( SrvMaxUsers, MAX_USERS_WKSTA );
|
|
MINIMIZE( SrvMaxReceiveWorkItemCount, MAX_MAXWORKITEMS_WKSTA );
|
|
MINIMIZE( SrvMaxThreadsPerQueue, MAX_THREADS_WKSTA );
|
|
|
|
if( IsPersonal() )
|
|
{
|
|
MINIMIZE( SrvMaxUsers, MAX_USERS_PERSONAL );
|
|
}
|
|
|
|
//
|
|
// On WinNT, we do not cache the following:
|
|
//
|
|
|
|
SrvCachedOpenLimit = 0; // don't cache close'd files
|
|
SrvMaxCachedDirectory = 0; // don't cache directory names
|
|
SrvMaxFreeRfcbs = 0; // don't cache free'd RFCB structs
|
|
SrvMaxFreeMfcbs = 0; // don't cache free'd NONPAGED_MFCB structs
|
|
}
|
|
|
|
if( IsWebBlade() )
|
|
{
|
|
MINIMIZE( SrvMaxUsers, MAX_USERS_WEB_BLADE );
|
|
MINIMIZE( SrvMaxReceiveWorkItemCount, MAX_MAXWORKITEMS_WKSTA );
|
|
MINIMIZE( SrvMaxThreadsPerQueue, MAX_THREADS_WKSTA );
|
|
}
|
|
}
|
|
|
|
if( (SrvMaxUsers < UINT_MAX) && (SrvMaxUsers > 0) )
|
|
{
|
|
// Increment by 1 to allow the "emergency admin" user. Essentially, the final user
|
|
// to connect must be an administrator in case something is going wrong, such as DoS
|
|
SrvMaxUsers += 1;
|
|
}
|
|
|
|
//
|
|
// The following items are generally per-processor. Ensure they
|
|
// are a multiple of the number of processors in the system.
|
|
//
|
|
SrvMaxReceiveWorkItemCount =
|
|
MultipleOfProcessors( SrvMaxReceiveWorkItemCount );
|
|
|
|
SrvInitialReceiveWorkItemCount =
|
|
MultipleOfProcessors( SrvInitialReceiveWorkItemCount );
|
|
|
|
SrvMinReceiveQueueLength =
|
|
MultipleOfProcessors( SrvMinReceiveQueueLength );
|
|
|
|
SrvMaxRawModeWorkItemCount =
|
|
MultipleOfProcessors( SrvMaxRawModeWorkItemCount );
|
|
|
|
SrvInitialRawModeWorkItemCount =
|
|
MultipleOfProcessors( SrvInitialRawModeWorkItemCount );
|
|
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
|
|
status = GetExceptionCode();
|
|
}
|
|
|
|
RELEASE_LOCK( &SrvConfigurationLock );
|
|
|
|
return status;
|
|
|
|
} // SrvNetServerSetInfo
|
|
|
|
|
|
LARGE_INTEGER
|
|
SecondsToTime (
|
|
IN ULONG Seconds,
|
|
IN BOOLEAN MakeNegative
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine converts a time interval specified in seconds to
|
|
the NT time base in 100s on nanoseconds.
|
|
|
|
Arguments:
|
|
|
|
Seconds - the interval in seconds.
|
|
|
|
MakeNegative - if TRUE, the time returned is a negative, i.e. relative
|
|
time.
|
|
|
|
Return Value:
|
|
|
|
LARGE_INTEGER - the interval in NT time.
|
|
|
|
--*/
|
|
|
|
{
|
|
LARGE_INTEGER ntTime;
|
|
|
|
PAGED_CODE( );
|
|
|
|
if ( MakeNegative ) {
|
|
ntTime.QuadPart = Int32x32To64( Seconds, -1*10*1000*1000 );
|
|
} else {
|
|
ntTime.QuadPart = Int32x32To64( Seconds, 1*10*1000*1000 );
|
|
}
|
|
|
|
return ntTime;
|
|
|
|
} // SecondsToTime
|
|
|
|
|
|
LARGE_INTEGER
|
|
MinutesToTime (
|
|
IN ULONG Minutes,
|
|
IN BOOLEAN MakeNegative
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine converts a time interval specified in minutes to
|
|
the NT time base in 100s on nanoseconds.
|
|
|
|
Arguments:
|
|
|
|
Minutes - the interval in minutes.
|
|
|
|
MakeNegative - if TRUE, the time returned is a negative, i.e. relative
|
|
time.
|
|
|
|
Return Value:
|
|
|
|
LARGE_INTEGER - the interval in NT time.
|
|
|
|
--*/
|
|
|
|
{
|
|
PAGED_CODE( );
|
|
|
|
return SecondsToTime( 60*Minutes, MakeNegative );
|
|
|
|
} // MinutesToTime
|
|
|
|
ULONG
|
|
MultipleOfProcessors(
|
|
IN ULONG value
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine ensures the passed in value is a multiple of the number
|
|
of processors in the system. The value will be adjusted upward if
|
|
necessary.
|
|
|
|
Arguments:
|
|
|
|
value - the value to be adjusted
|
|
|
|
Return Value:
|
|
|
|
the adjusted value
|
|
|
|
--*/
|
|
{
|
|
value += SrvNumberOfProcessors - 1;
|
|
value /= SrvNumberOfProcessors;
|
|
value *= SrvNumberOfProcessors;
|
|
|
|
return value;
|
|
}
|