Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. svcsrv.c
  5. Abstract:
  6. This module contains routines for supporting the server APIs in the
  7. server service, SrvNetServerDiskEnum, and SrvNetServerSetInfo.
  8. Author:
  9. David Treadwell (davidtr) 31-Jan-1991
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #include "svcsrv.tmh"
  14. #pragma hdrstop
  15. //
  16. // Forward declarations.
  17. //
  18. LARGE_INTEGER
  19. SecondsToTime (
  20. IN ULONG Seconds,
  21. IN BOOLEAN MakeNegative
  22. );
  23. LARGE_INTEGER
  24. MinutesToTime (
  25. IN ULONG Seconds,
  26. IN BOOLEAN MakeNegative
  27. );
  28. ULONG
  29. MultipleOfProcessors (
  30. IN ULONG value
  31. );
  32. BOOL
  33. IsSuiteVersion(
  34. IN USHORT Version
  35. );
  36. #ifdef ALLOC_PRAGMA
  37. #pragma alloc_text( PAGE, SrvNetServerDiskEnum )
  38. #pragma alloc_text( PAGE, SrvNetServerSetInfo )
  39. #pragma alloc_text( PAGE, SecondsToTime )
  40. #pragma alloc_text( PAGE, MinutesToTime )
  41. #pragma alloc_text( PAGE, MultipleOfProcessors )
  42. #pragma alloc_text( PAGE, IsSuiteVersion )
  43. #endif
  44. #define IsWebBlade() IsSuiteVersion(VER_SUITE_BLADE)
  45. #define IsPersonal() IsSuiteVersion(VER_SUITE_PERSONAL)
  46. #define IsEmbedded() IsSuiteVersion(VER_SUITE_EMBEDDEDNT)
  47. BOOL
  48. IsSuiteVersion(USHORT Version)
  49. {
  50. OSVERSIONINFOEX Osvi;
  51. DWORD TypeMask;
  52. DWORDLONG ConditionMask;
  53. memset(&Osvi, 0, sizeof(OSVERSIONINFOEX));
  54. Osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  55. Osvi.wSuiteMask = Version;
  56. TypeMask = VER_SUITENAME;
  57. ConditionMask = 0;
  58. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR);
  59. return(NT_SUCCESS(RtlVerifyVersionInfo(&Osvi, TypeMask, ConditionMask)));
  60. }
  61. NTSTATUS
  62. SrvNetServerDiskEnum (
  63. IN PSERVER_REQUEST_PACKET Srp,
  64. IN PVOID Buffer,
  65. IN ULONG BufferLength
  66. )
  67. {
  68. PAGED_CODE( );
  69. Srp, Buffer, BufferLength;
  70. return STATUS_NOT_IMPLEMENTED;
  71. } // SrvNetServerDiskEnum
  72. NTSTATUS
  73. SrvNetServerSetInfo (
  74. IN PSERVER_REQUEST_PACKET Srp,
  75. IN PVOID Buffer,
  76. IN ULONG BufferLength
  77. )
  78. /*++
  79. Routine Description:
  80. This routine processes the NetServerSetInfo API in the server FSD.
  81. Arguments:
  82. Srp - a pointer to the server request packet that contains all
  83. the information necessary to satisfy the request. This includes:
  84. INPUT:
  85. None.
  86. OUTPUT:
  87. None.
  88. Buffer - a pointer to a SERVER_INFO_102, followed immediately by a
  89. SERVER_INFO_599 structure, followed by a SERVER_INFO_559a
  90. structure. All information is always reset in this routine; the
  91. server service also tracks this data, so when it gets a
  92. NetServerSetInfo it overwrites the appropriate fields and sends
  93. all the data.
  94. BufferLength - total length of this buffer.
  95. Return Value:
  96. NTSTATUS - result of operation to return to the server service.
  97. --*/
  98. {
  99. NTSTATUS status = STATUS_INVALID_PARAMETER;
  100. PSERVER_INFO_102 sv102;
  101. PSERVER_INFO_599 sv599;
  102. PSERVER_INFO_598 sv598;
  103. LARGE_INTEGER scavengerTimeout;
  104. LARGE_INTEGER alerterTimeout;
  105. ULONG ipxdisc;
  106. LARGE_INTEGER li;
  107. ULONG bufferOffset;
  108. ULONG keTimeIncrement;
  109. PAGED_CODE( );
  110. //
  111. // Make sure that the input buffer length is correct.
  112. //
  113. if ( BufferLength < sizeof(SERVER_INFO_102) +
  114. sizeof(SERVER_INFO_599) + sizeof(SERVER_INFO_598) ) {
  115. return status;
  116. }
  117. //
  118. // Set up buffer pointers as appropriate. The SERVER_INFO_599
  119. // structure must immediately follow the SERVER_INFO_102 structure
  120. // in the buffer.
  121. //
  122. sv102 = Buffer;
  123. sv599 = (PSERVER_INFO_599)(sv102 + 1);
  124. sv598 = (PSERVER_INFO_598)(sv599 + 1);
  125. if( sv599->sv599_scavtimeout == 0 )
  126. {
  127. // This will cause a divide by zero later on
  128. return STATUS_INVALID_PARAMETER;
  129. }
  130. //
  131. // store the time increment count
  132. //
  133. keTimeIncrement = KeQueryTimeIncrement();
  134. //
  135. // Grab the lock that protects configuration changes.
  136. //
  137. ACQUIRE_LOCK( &SrvConfigurationLock );
  138. //
  139. // Set all configuration information in the server.
  140. //
  141. try {
  142. SrvMaxUsers = sv102->sv102_users;
  143. //
  144. // The autodisconnect timeout must be converted from minutes to NT
  145. // time, which has a base of 100s of nanoseconds. If the specified
  146. // value is negative (top bit set), set the timeout to 0, indicating
  147. // that no autodisconnect should be done. If the specified value is
  148. // 0, meaning to autodisconnect immediately, set the timeout to a
  149. // small value, but not 0.
  150. //
  151. if ( (sv102->sv102_disc & 0x80000000) == 0 ) {
  152. if ( sv102->sv102_disc != 0 ) {
  153. SrvAutodisconnectTimeout.QuadPart =
  154. Int32x32To64( sv102->sv102_disc, 10*1000*1000*60 );
  155. } else {
  156. SrvAutodisconnectTimeout.QuadPart = 1;
  157. }
  158. } else {
  159. SrvAutodisconnectTimeout.QuadPart = 0;
  160. }
  161. SrvInitialSessionTableSize = (USHORT)sv599->sv599_initsesstable;
  162. SrvInitialTreeTableSize = (USHORT)sv599->sv599_initconntable;
  163. SrvInitialFileTableSize = (USHORT)sv599->sv599_initfiletable;
  164. SrvInitialSearchTableSize = (USHORT)sv599->sv599_initsearchtable;
  165. SrvMaxFileTableSize = (USHORT)sv599->sv599_sessopens;
  166. SrvMaxNumberVcs = sv599->sv599_sessvcs;
  167. SrvMaxSearchTableSize = (USHORT)sv599->sv599_opensearch;
  168. SrvReceiveBufferLength = sv599->sv599_sizreqbuf;
  169. SrvReceiveBufferSize = (SrvReceiveBufferLength + SrvCacheLineSize) & ~SrvCacheLineSize;
  170. SrvReceiveMdlSize = (ULONG)(MmSizeOfMdl( (PVOID)(PAGE_SIZE-1), SrvReceiveBufferSize ) + 7) & ~7;
  171. SrvMaxMdlSize = (ULONG)(MmSizeOfMdl( (PVOID)(PAGE_SIZE-1), MAX_PARTIAL_BUFFER_SIZE ) + 7) & ~7;
  172. SrvInitialReceiveWorkItemCount = sv599->sv599_initworkitems;
  173. SrvMaxReceiveWorkItemCount = sv599->sv599_maxworkitems;
  174. SrvInitialRawModeWorkItemCount = sv599->sv599_rawworkitems;
  175. SrvReceiveIrpStackSize = (CCHAR)sv599->sv599_irpstacksize;
  176. SrvReceiveIrpSize = (IoSizeOfIrp( SrvReceiveIrpStackSize ) + 7) & ~7;
  177. SrvMaxSessionTableSize = (USHORT)sv599->sv599_sessusers;
  178. SrvMaxTreeTableSize = (USHORT)sv599->sv599_sessconns;
  179. SrvMaxPagedPoolUsage = sv599->sv599_maxpagedmemoryusage;
  180. SrvMaxNonPagedPoolUsage = sv599->sv599_maxnonpagedmemoryusage;
  181. SrvEnableSoftCompatibility = (BOOLEAN)sv599->sv599_enablesoftcompat;
  182. SrvEnableForcedLogoff = (BOOLEAN)sv599->sv599_enableforcedlogoff;
  183. SrvCoreSearchTimeout = sv599->sv599_maxkeepsearch;
  184. SrvSearchMaxTimeout = SecondsToTime( SrvCoreSearchTimeout, FALSE );
  185. SrvScavengerTimeoutInSeconds = sv599->sv599_scavtimeout;
  186. scavengerTimeout = SecondsToTime( SrvScavengerTimeoutInSeconds, FALSE );
  187. SrvMaxMpxCount = (USHORT)sv599->sv599_maxmpxct;
  188. SrvWaitForOplockBreakTime = SecondsToTime( sv599->sv599_oplockbreakwait, FALSE );
  189. SrvWaitForOplockBreakRequestTime = SecondsToTime( sv599->sv599_oplockbreakresponsewait, FALSE );
  190. SrvMinReceiveQueueLength = sv599->sv599_minrcvqueue;
  191. SrvMinFreeWorkItemsBlockingIo = sv599->sv599_minfreeworkitems;
  192. SrvXsSectionSize.QuadPart = sv599->sv599_xactmemsize;
  193. SrvThreadPriority = (KPRIORITY)sv599->sv599_threadpriority;
  194. SrvEnableOplockForceClose = (BOOLEAN)sv599->sv599_enableoplockforceclose;
  195. SrvEnableFcbOpens = (BOOLEAN)sv599->sv599_enablefcbopens;
  196. SrvEnableRawMode = (BOOLEAN)sv599->sv599_enableraw;
  197. SrvFreeConnectionMinimum = sv599->sv599_minfreeconnections;
  198. SrvFreeConnectionMaximum = sv599->sv599_maxfreeconnections;
  199. //
  200. // Max work item idle time is in ticks
  201. //
  202. li = SecondsToTime( sv599->sv599_maxworkitemidletime, FALSE );
  203. li.QuadPart /= keTimeIncrement;
  204. if ( li.HighPart != 0 ) {
  205. li.LowPart = 0xffffffff;
  206. }
  207. SrvWorkItemMaxIdleTime = li.LowPart;
  208. //
  209. // Oplocks should not be enabled if SrvMaxMpxCount == 1
  210. //
  211. if ( SrvMaxMpxCount > 1 ) {
  212. SrvEnableOplocks = (BOOLEAN)sv599->sv599_enableoplocks;
  213. } else {
  214. SrvEnableOplocks = FALSE;
  215. }
  216. SrvProductTypeServer = MmIsThisAnNtAsSystem( );
  217. SrvServerSize = sv598->sv598_serversize;
  218. SrvMaxRawModeWorkItemCount = sv598->sv598_maxrawworkitems;
  219. SrvMaxThreadsPerQueue = sv598->sv598_maxthreadsperqueue;
  220. ipxdisc = sv598->sv598_connectionlessautodisc;
  221. SrvConnectionNoSessionsTimeout = sv598->sv598_ConnectionNoSessionsTimeout;
  222. SrvRemoveDuplicateSearches =
  223. (BOOLEAN)sv598->sv598_removeduplicatesearches;
  224. SrvMaxOpenSearches = sv598->sv598_maxglobalopensearch;
  225. SrvSharingViolationRetryCount = sv598->sv598_sharingviolationretries;
  226. SrvSharingViolationDelay.QuadPart =
  227. Int32x32To64( sv598->sv598_sharingviolationdelay, -1*10*1000 );
  228. SrvLockViolationDelay = sv598->sv598_lockviolationdelay;
  229. SrvLockViolationOffset = sv598->sv598_lockviolationoffset;
  230. SrvCachedOpenLimit = sv598->sv598_cachedopenlimit;
  231. SrvMdlReadSwitchover = sv598->sv598_mdlreadswitchover;
  232. SrvEnableWfW311DirectIpx =
  233. (BOOLEAN)sv598->sv598_enablewfw311directipx;
  234. SrvRestrictNullSessionAccess =
  235. (BOOLEAN)sv598->sv598_restrictnullsessaccess;
  236. SrvQueueCalc = SecondsToTime( sv598->sv598_queuesamplesecs, FALSE );
  237. SrvPreferredAffinity = sv598->sv598_preferredaffinity;
  238. SrvOtherQueueAffinity = sv598->sv598_otherqueueaffinity;
  239. SrvBalanceCount = sv598->sv598_balancecount;
  240. SrvMaxFreeRfcbs = sv598->sv598_maxfreerfcbs;
  241. SrvMaxFreeMfcbs = sv598->sv598_maxfreemfcbs;
  242. SrvMaxPagedPoolChunkSize = sv598->sv598_maxpagedpoolchunksize;
  243. SrvMaxCachedDirectory = sv598->sv598_cacheddirectorylimit;
  244. SrvMaxCopyLength = sv598->sv598_maxcopylength;
  245. SrvMinClientBufferSize = sv598->sv598_minclientbuffersize;
  246. SrvMinClientBufferSize &= ~03;
  247. SrvSmbSecuritySignaturesEnabled = (sv598->sv598_enablesecuritysignature != FALSE);
  248. SrvSmbSecuritySignaturesRequired = (sv598->sv598_requiresecuritysignature != FALSE);
  249. SrvEnableW9xSecuritySignatures = (sv598->sv598_enableW9xsecuritysignature != FALSE);
  250. ServerGuid = sv598->sv598_serverguid;
  251. SrvEnforceLogoffTimes = (sv598->sv598_enforcekerberosreauthentication != FALSE);
  252. SrvDisableDoSChecking = (sv598->sv598_disabledos != FALSE);
  253. SrvDisableStrictNameChecking = (sv598->sv598_disablestrictnamechecking != FALSE);
  254. SrvFreeDiskSpaceCeiling = sv598->sv598_lowdiskspaceminimum;
  255. //
  256. // Make sure the settings are consistent!
  257. //
  258. if( SrvSmbSecuritySignaturesEnabled == FALSE ) {
  259. SrvSmbSecuritySignaturesRequired = FALSE;
  260. }
  261. SrvMaxNonPagedPoolChunkSize = SrvMaxPagedPoolChunkSize;
  262. SrvLockViolationDelayRelative.QuadPart =
  263. Int32x32To64( sv598->sv598_lockviolationdelay, -1*10*1000 );
  264. //
  265. // Convert the idle thread timeout from seconds to ticks
  266. //
  267. SrvIdleThreadTimeOut =
  268. Int32x32To64( sv598->sv598_IdleThreadTimeOut, -1*10*1000*1000 );
  269. //
  270. // Calculate switchover number for mpx
  271. //
  272. bufferOffset = (sizeof(SMB_HEADER) + sizeof(RESP_READ_MPX) - 1 + 3) & ~3;
  273. if ( SrvMdlReadSwitchover > (SrvReceiveBufferLength - bufferOffset) ) {
  274. SrvMpxMdlReadSwitchover = SrvReceiveBufferLength - bufferOffset;
  275. } else {
  276. SrvMpxMdlReadSwitchover = SrvMdlReadSwitchover;
  277. }
  278. //
  279. // The IPX autodisconnect timeout must be converted from minutes to
  280. // ticks. If 0 is specified, use 15 minutes.
  281. //
  282. if ( ipxdisc == 0 ) {
  283. ipxdisc = 15;
  284. }
  285. li.QuadPart = Int32x32To64( ipxdisc, 10*1000*1000*60 );
  286. li.QuadPart /= keTimeIncrement;
  287. if ( li.HighPart != 0 ) {
  288. li.LowPart = 0xffffffff;
  289. }
  290. SrvIpxAutodisconnectTimeout = li.LowPart;
  291. //
  292. // The "idle connection without sessions" timeout must be converted from
  293. // minutes to ticks.
  294. //
  295. li.QuadPart = Int32x32To64( SrvConnectionNoSessionsTimeout, 10*1000*1000*60 );
  296. li.QuadPart /= keTimeIncrement;
  297. if( li.HighPart != 0 ) {
  298. li.LowPart = 0xffffffff;
  299. }
  300. SrvConnectionNoSessionsTimeout = li.LowPart;
  301. //
  302. // Event logging and alerting information.
  303. //
  304. alerterTimeout = MinutesToTime( sv599->sv599_alertschedule, FALSE );
  305. SrvAlertMinutes = sv599->sv599_alertschedule;
  306. SrvErrorRecord.ErrorThreshold = sv599->sv599_errorthreshold;
  307. SrvNetworkErrorRecord.ErrorThreshold =
  308. sv599->sv599_networkerrorthreshold;
  309. SrvFreeDiskSpaceThreshold = sv599->sv599_diskspacethreshold;
  310. SrvCaptureScavengerTimeout( &scavengerTimeout, &alerterTimeout );
  311. //
  312. // Link Speed Parameters
  313. //
  314. SrvMaxLinkDelay = SecondsToTime( sv599->sv599_maxlinkdelay, FALSE );
  315. SrvMinLinkThroughput.QuadPart = sv599->sv599_minlinkthroughput;
  316. SrvLinkInfoValidTime =
  317. SecondsToTime ( sv599->sv599_linkinfovalidtime, FALSE );
  318. SrvScavengerUpdateQosCount =
  319. sv599->sv599_scavqosinfoupdatetime / sv599->sv599_scavtimeout;
  320. //
  321. // Override parameters that cannot be set on WinNT (vs. NTAS).
  322. //
  323. // We override the parameters passed by the service in case somebody
  324. // figures out the FSCTL that changes parameters. We also override
  325. // in the service in order to keep the service's view consistent
  326. // with the server's. If you make any changes here, also make them
  327. // in srvsvc\server\registry.c.
  328. //
  329. //
  330. // For Embedded systems, just take the registry value. They do their own
  331. // validation of settings.
  332. //
  333. if( !IsEmbedded() )
  334. {
  335. if ( !SrvProductTypeServer ) {
  336. //
  337. // On WinNT, the maximum value of certain parameters is fixed at
  338. // build time. These include: concurrent users, SMB buffers,
  339. //
  340. #define MINIMIZE(_param,_max) _param = MIN( _param, _max );
  341. MINIMIZE( SrvMaxUsers, MAX_USERS_WKSTA );
  342. MINIMIZE( SrvMaxReceiveWorkItemCount, MAX_MAXWORKITEMS_WKSTA );
  343. MINIMIZE( SrvMaxThreadsPerQueue, MAX_THREADS_WKSTA );
  344. if( IsPersonal() )
  345. {
  346. MINIMIZE( SrvMaxUsers, MAX_USERS_PERSONAL );
  347. }
  348. //
  349. // On WinNT, we do not cache the following:
  350. //
  351. SrvCachedOpenLimit = 0; // don't cache close'd files
  352. SrvMaxCachedDirectory = 0; // don't cache directory names
  353. SrvMaxFreeRfcbs = 0; // don't cache free'd RFCB structs
  354. SrvMaxFreeMfcbs = 0; // don't cache free'd NONPAGED_MFCB structs
  355. }
  356. if( IsWebBlade() )
  357. {
  358. MINIMIZE( SrvMaxUsers, MAX_USERS_WEB_BLADE );
  359. MINIMIZE( SrvMaxReceiveWorkItemCount, MAX_MAXWORKITEMS_WKSTA );
  360. MINIMIZE( SrvMaxThreadsPerQueue, MAX_THREADS_WKSTA );
  361. }
  362. }
  363. if( (SrvMaxUsers < UINT_MAX) && (SrvMaxUsers > 0) )
  364. {
  365. // Increment by 1 to allow the "emergency admin" user. Essentially, the final user
  366. // to connect must be an administrator in case something is going wrong, such as DoS
  367. SrvMaxUsers += 1;
  368. }
  369. //
  370. // The following items are generally per-processor. Ensure they
  371. // are a multiple of the number of processors in the system.
  372. //
  373. SrvMaxReceiveWorkItemCount =
  374. MultipleOfProcessors( SrvMaxReceiveWorkItemCount );
  375. SrvInitialReceiveWorkItemCount =
  376. MultipleOfProcessors( SrvInitialReceiveWorkItemCount );
  377. SrvMinReceiveQueueLength =
  378. MultipleOfProcessors( SrvMinReceiveQueueLength );
  379. SrvMaxRawModeWorkItemCount =
  380. MultipleOfProcessors( SrvMaxRawModeWorkItemCount );
  381. SrvInitialRawModeWorkItemCount =
  382. MultipleOfProcessors( SrvInitialRawModeWorkItemCount );
  383. status = STATUS_SUCCESS;
  384. } except( EXCEPTION_EXECUTE_HANDLER ) {
  385. status = GetExceptionCode();
  386. }
  387. RELEASE_LOCK( &SrvConfigurationLock );
  388. return status;
  389. } // SrvNetServerSetInfo
  390. LARGE_INTEGER
  391. SecondsToTime (
  392. IN ULONG Seconds,
  393. IN BOOLEAN MakeNegative
  394. )
  395. /*++
  396. Routine Description:
  397. This routine converts a time interval specified in seconds to
  398. the NT time base in 100s on nanoseconds.
  399. Arguments:
  400. Seconds - the interval in seconds.
  401. MakeNegative - if TRUE, the time returned is a negative, i.e. relative
  402. time.
  403. Return Value:
  404. LARGE_INTEGER - the interval in NT time.
  405. --*/
  406. {
  407. LARGE_INTEGER ntTime;
  408. PAGED_CODE( );
  409. if ( MakeNegative ) {
  410. ntTime.QuadPart = Int32x32To64( Seconds, -1*10*1000*1000 );
  411. } else {
  412. ntTime.QuadPart = Int32x32To64( Seconds, 1*10*1000*1000 );
  413. }
  414. return ntTime;
  415. } // SecondsToTime
  416. LARGE_INTEGER
  417. MinutesToTime (
  418. IN ULONG Minutes,
  419. IN BOOLEAN MakeNegative
  420. )
  421. /*++
  422. Routine Description:
  423. This routine converts a time interval specified in minutes to
  424. the NT time base in 100s on nanoseconds.
  425. Arguments:
  426. Minutes - the interval in minutes.
  427. MakeNegative - if TRUE, the time returned is a negative, i.e. relative
  428. time.
  429. Return Value:
  430. LARGE_INTEGER - the interval in NT time.
  431. --*/
  432. {
  433. PAGED_CODE( );
  434. return SecondsToTime( 60*Minutes, MakeNegative );
  435. } // MinutesToTime
  436. ULONG
  437. MultipleOfProcessors(
  438. IN ULONG value
  439. )
  440. /*++
  441. Routine Description:
  442. This routine ensures the passed in value is a multiple of the number
  443. of processors in the system. The value will be adjusted upward if
  444. necessary.
  445. Arguments:
  446. value - the value to be adjusted
  447. Return Value:
  448. the adjusted value
  449. --*/
  450. {
  451. value += SrvNumberOfProcessors - 1;
  452. value /= SrvNumberOfProcessors;
  453. value *= SrvNumberOfProcessors;
  454. return value;
  455. }