Source code of Windows XP (NT5)
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.

611 lines
18 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. //
  126. // store the time increment count
  127. //
  128. keTimeIncrement = KeQueryTimeIncrement();
  129. //
  130. // Grab the lock that protects configuration changes.
  131. //
  132. ACQUIRE_LOCK( &SrvConfigurationLock );
  133. //
  134. // Set all configuration information in the server.
  135. //
  136. try {
  137. SrvMaxUsers = sv102->sv102_users;
  138. //
  139. // The autodisconnect timeout must be converted from minutes to NT
  140. // time, which has a base of 100s of nanoseconds. If the specified
  141. // value is negative (top bit set), set the timeout to 0, indicating
  142. // that no autodisconnect should be done. If the specified value is
  143. // 0, meaning to autodisconnect immediately, set the timeout to a
  144. // small value, but not 0.
  145. //
  146. if ( (sv102->sv102_disc & 0x80000000) == 0 ) {
  147. if ( sv102->sv102_disc != 0 ) {
  148. SrvAutodisconnectTimeout.QuadPart =
  149. Int32x32To64( sv102->sv102_disc, 10*1000*1000*60 );
  150. } else {
  151. SrvAutodisconnectTimeout.QuadPart = 1;
  152. }
  153. } else {
  154. SrvAutodisconnectTimeout.QuadPart = 0;
  155. }
  156. SrvInitialSessionTableSize = (USHORT)sv599->sv599_initsesstable;
  157. SrvInitialTreeTableSize = (USHORT)sv599->sv599_initconntable;
  158. SrvInitialFileTableSize = (USHORT)sv599->sv599_initfiletable;
  159. SrvInitialSearchTableSize = (USHORT)sv599->sv599_initsearchtable;
  160. SrvMaxFileTableSize = (USHORT)sv599->sv599_sessopens;
  161. SrvMaxNumberVcs = sv599->sv599_sessvcs;
  162. SrvMaxSearchTableSize = (USHORT)sv599->sv599_opensearch;
  163. SrvReceiveBufferLength = sv599->sv599_sizreqbuf;
  164. SrvReceiveBufferSize = (SrvReceiveBufferLength + SrvCacheLineSize) & ~SrvCacheLineSize;
  165. SrvReceiveMdlSize = (ULONG)(MmSizeOfMdl( (PVOID)(PAGE_SIZE-1), SrvReceiveBufferSize ) + 7) & ~7;
  166. SrvMaxMdlSize = (ULONG)(MmSizeOfMdl( (PVOID)(PAGE_SIZE-1), MAX_PARTIAL_BUFFER_SIZE ) + 7) & ~7;
  167. SrvInitialReceiveWorkItemCount = sv599->sv599_initworkitems;
  168. SrvMaxReceiveWorkItemCount = sv599->sv599_maxworkitems;
  169. SrvInitialRawModeWorkItemCount = sv599->sv599_rawworkitems;
  170. SrvReceiveIrpStackSize = (CCHAR)sv599->sv599_irpstacksize;
  171. SrvReceiveIrpSize = (IoSizeOfIrp( SrvReceiveIrpStackSize ) + 7) & ~7;
  172. SrvMaxSessionTableSize = (USHORT)sv599->sv599_sessusers;
  173. SrvMaxTreeTableSize = (USHORT)sv599->sv599_sessconns;
  174. SrvMaxPagedPoolUsage = sv599->sv599_maxpagedmemoryusage;
  175. SrvMaxNonPagedPoolUsage = sv599->sv599_maxnonpagedmemoryusage;
  176. SrvEnableSoftCompatibility = (BOOLEAN)sv599->sv599_enablesoftcompat;
  177. SrvEnableForcedLogoff = (BOOLEAN)sv599->sv599_enableforcedlogoff;
  178. SrvCoreSearchTimeout = sv599->sv599_maxkeepsearch;
  179. SrvSearchMaxTimeout = SecondsToTime( SrvCoreSearchTimeout, FALSE );
  180. SrvScavengerTimeoutInSeconds = sv599->sv599_scavtimeout;
  181. scavengerTimeout = SecondsToTime( SrvScavengerTimeoutInSeconds, FALSE );
  182. SrvMaxMpxCount = (USHORT)sv599->sv599_maxmpxct;
  183. SrvWaitForOplockBreakTime = SecondsToTime( sv599->sv599_oplockbreakwait, FALSE );
  184. SrvWaitForOplockBreakRequestTime = SecondsToTime( sv599->sv599_oplockbreakresponsewait, FALSE );
  185. SrvMinReceiveQueueLength = sv599->sv599_minrcvqueue;
  186. SrvMinFreeWorkItemsBlockingIo = sv599->sv599_minfreeworkitems;
  187. SrvXsSectionSize.QuadPart = sv599->sv599_xactmemsize;
  188. SrvThreadPriority = (KPRIORITY)sv599->sv599_threadpriority;
  189. SrvEnableOplockForceClose = (BOOLEAN)sv599->sv599_enableoplockforceclose;
  190. SrvEnableFcbOpens = (BOOLEAN)sv599->sv599_enablefcbopens;
  191. SrvEnableRawMode = (BOOLEAN)sv599->sv599_enableraw;
  192. SrvFreeConnectionMinimum = sv599->sv599_minfreeconnections;
  193. SrvFreeConnectionMaximum = sv599->sv599_maxfreeconnections;
  194. //
  195. // Max work item idle time is in ticks
  196. //
  197. li = SecondsToTime( sv599->sv599_maxworkitemidletime, FALSE );
  198. li.QuadPart /= keTimeIncrement;
  199. if ( li.HighPart != 0 ) {
  200. li.LowPart = 0xffffffff;
  201. }
  202. SrvWorkItemMaxIdleTime = li.LowPart;
  203. //
  204. // Oplocks should not be enabled if SrvMaxMpxCount == 1
  205. //
  206. if ( SrvMaxMpxCount > 1 ) {
  207. SrvEnableOplocks = (BOOLEAN)sv599->sv599_enableoplocks;
  208. } else {
  209. SrvEnableOplocks = FALSE;
  210. }
  211. SrvProductTypeServer = MmIsThisAnNtAsSystem( );
  212. SrvServerSize = sv598->sv598_serversize;
  213. SrvMaxRawModeWorkItemCount = sv598->sv598_maxrawworkitems;
  214. SrvMaxThreadsPerQueue = sv598->sv598_maxthreadsperqueue;
  215. ipxdisc = sv598->sv598_connectionlessautodisc;
  216. SrvConnectionNoSessionsTimeout = sv598->sv598_ConnectionNoSessionsTimeout;
  217. SrvRemoveDuplicateSearches =
  218. (BOOLEAN)sv598->sv598_removeduplicatesearches;
  219. SrvMaxOpenSearches = sv598->sv598_maxglobalopensearch;
  220. SrvSharingViolationRetryCount = sv598->sv598_sharingviolationretries;
  221. SrvSharingViolationDelay.QuadPart =
  222. Int32x32To64( sv598->sv598_sharingviolationdelay, -1*10*1000 );
  223. SrvLockViolationDelay = sv598->sv598_lockviolationdelay;
  224. SrvLockViolationOffset = sv598->sv598_lockviolationoffset;
  225. SrvCachedOpenLimit = sv598->sv598_cachedopenlimit;
  226. SrvMdlReadSwitchover = sv598->sv598_mdlreadswitchover;
  227. SrvEnableWfW311DirectIpx =
  228. (BOOLEAN)sv598->sv598_enablewfw311directipx;
  229. SrvRestrictNullSessionAccess =
  230. (BOOLEAN)sv598->sv598_restrictnullsessaccess;
  231. SrvQueueCalc = SecondsToTime( sv598->sv598_queuesamplesecs, FALSE );
  232. SrvPreferredAffinity = sv598->sv598_preferredaffinity;
  233. SrvOtherQueueAffinity = sv598->sv598_otherqueueaffinity;
  234. SrvBalanceCount = sv598->sv598_balancecount;
  235. SrvMaxFreeRfcbs = sv598->sv598_maxfreerfcbs;
  236. SrvMaxFreeMfcbs = sv598->sv598_maxfreemfcbs;
  237. SrvMaxPagedPoolChunkSize = sv598->sv598_maxpagedpoolchunksize;
  238. SrvMaxCachedDirectory = sv598->sv598_cacheddirectorylimit;
  239. SrvMaxCopyLength = sv598->sv598_maxcopylength;
  240. SrvMinClientBufferSize = sv598->sv598_minclientbuffersize;
  241. SrvMinClientBufferSize &= ~03;
  242. SrvSupportsCompression = (sv598->sv598_enablecompression != FALSE);
  243. SrvSmbSecuritySignaturesEnabled = (sv598->sv598_enablesecuritysignature != FALSE);
  244. SrvSmbSecuritySignaturesRequired = (sv598->sv598_requiresecuritysignature != FALSE);
  245. SrvEnableW9xSecuritySignatures = (sv598->sv598_enableW9xsecuritysignature != FALSE);
  246. ServerGuid = sv598->sv598_serverguid;
  247. SrvEnforceLogoffTimes = (sv598->sv598_enforcekerberosreauthentication != FALSE);
  248. SrvDisableDoSChecking = (sv598->sv598_disabledos != FALSE);
  249. SrvDisableStrictNameChecking = (sv598->sv598_disablestrictnamechecking != FALSE);
  250. SrvFreeDiskSpaceCeiling = sv598->sv598_lowdiskspaceminimum;
  251. //
  252. // Make sure the settings are consistent!
  253. //
  254. if( SrvSmbSecuritySignaturesEnabled == FALSE ) {
  255. SrvSmbSecuritySignaturesRequired = FALSE;
  256. }
  257. SrvMaxNonPagedPoolChunkSize = SrvMaxPagedPoolChunkSize;
  258. SrvLockViolationDelayRelative.QuadPart =
  259. Int32x32To64( sv598->sv598_lockviolationdelay, -1*10*1000 );
  260. //
  261. // Convert the idle thread timeout from seconds to ticks
  262. //
  263. SrvIdleThreadTimeOut =
  264. Int32x32To64( sv598->sv598_IdleThreadTimeOut, -1*10*1000*1000 );
  265. //
  266. // Calculate switchover number for mpx
  267. //
  268. bufferOffset = (sizeof(SMB_HEADER) + sizeof(RESP_READ_MPX) - 1 + 3) & ~3;
  269. if ( SrvMdlReadSwitchover > (SrvReceiveBufferLength - bufferOffset) ) {
  270. SrvMpxMdlReadSwitchover = SrvReceiveBufferLength - bufferOffset;
  271. } else {
  272. SrvMpxMdlReadSwitchover = SrvMdlReadSwitchover;
  273. }
  274. //
  275. // The IPX autodisconnect timeout must be converted from minutes to
  276. // ticks. If 0 is specified, use 15 minutes.
  277. //
  278. if ( ipxdisc == 0 ) {
  279. ipxdisc = 15;
  280. }
  281. li.QuadPart = Int32x32To64( ipxdisc, 10*1000*1000*60 );
  282. li.QuadPart /= keTimeIncrement;
  283. if ( li.HighPart != 0 ) {
  284. li.LowPart = 0xffffffff;
  285. }
  286. SrvIpxAutodisconnectTimeout = li.LowPart;
  287. //
  288. // The "idle connection without sessions" timeout must be converted from
  289. // minutes to ticks.
  290. //
  291. li.QuadPart = Int32x32To64( SrvConnectionNoSessionsTimeout, 10*1000*1000*60 );
  292. li.QuadPart /= keTimeIncrement;
  293. if( li.HighPart != 0 ) {
  294. li.LowPart = 0xffffffff;
  295. }
  296. SrvConnectionNoSessionsTimeout = li.LowPart;
  297. //
  298. // Event logging and alerting information.
  299. //
  300. alerterTimeout = MinutesToTime( sv599->sv599_alertschedule, FALSE );
  301. SrvAlertMinutes = sv599->sv599_alertschedule;
  302. SrvErrorRecord.ErrorThreshold = sv599->sv599_errorthreshold;
  303. SrvNetworkErrorRecord.ErrorThreshold =
  304. sv599->sv599_networkerrorthreshold;
  305. SrvFreeDiskSpaceThreshold = sv599->sv599_diskspacethreshold;
  306. SrvCaptureScavengerTimeout( &scavengerTimeout, &alerterTimeout );
  307. //
  308. // Link Speed Parameters
  309. //
  310. SrvMaxLinkDelay = SecondsToTime( sv599->sv599_maxlinkdelay, FALSE );
  311. SrvMinLinkThroughput.QuadPart = sv599->sv599_minlinkthroughput;
  312. SrvLinkInfoValidTime =
  313. SecondsToTime ( sv599->sv599_linkinfovalidtime, FALSE );
  314. SrvScavengerUpdateQosCount =
  315. sv599->sv599_scavqosinfoupdatetime / sv599->sv599_scavtimeout;
  316. //
  317. // Override parameters that cannot be set on WinNT (vs. NTAS).
  318. //
  319. // We override the parameters passed by the service in case somebody
  320. // figures out the FSCTL that changes parameters. We also override
  321. // in the service in order to keep the service's view consistent
  322. // with the server's. If you make any changes here, also make them
  323. // in srvsvc\server\registry.c.
  324. //
  325. //
  326. // For Embedded systems, just take the registry value. They do their own
  327. // validation of settings.
  328. //
  329. if( !IsEmbedded() )
  330. {
  331. if ( !SrvProductTypeServer ) {
  332. //
  333. // On WinNT, the maximum value of certain parameters is fixed at
  334. // build time. These include: concurrent users, SMB buffers,
  335. //
  336. #define MINIMIZE(_param,_max) _param = MIN( _param, _max );
  337. MINIMIZE( SrvMaxUsers, MAX_USERS_WKSTA );
  338. MINIMIZE( SrvMaxReceiveWorkItemCount, MAX_MAXWORKITEMS_WKSTA );
  339. MINIMIZE( SrvMaxThreadsPerQueue, MAX_THREADS_WKSTA );
  340. if( IsPersonal() )
  341. {
  342. MINIMIZE( SrvMaxUsers, MAX_USERS_PERSONAL );
  343. }
  344. //
  345. // On WinNT, we do not cache the following:
  346. //
  347. SrvCachedOpenLimit = 0; // don't cache close'd files
  348. SrvMaxCachedDirectory = 0; // don't cache directory names
  349. SrvMaxFreeRfcbs = 0; // don't cache free'd RFCB structs
  350. SrvMaxFreeMfcbs = 0; // don't cache free'd NONPAGED_MFCB structs
  351. }
  352. if( IsWebBlade() )
  353. {
  354. MINIMIZE( SrvMaxUsers, MAX_USERS_WEB_BLADE );
  355. MINIMIZE( SrvMaxReceiveWorkItemCount, MAX_MAXWORKITEMS_WKSTA );
  356. MINIMIZE( SrvMaxThreadsPerQueue, MAX_THREADS_WKSTA );
  357. }
  358. }
  359. if( (SrvMaxUsers < UINT_MAX) && (SrvMaxUsers > 0) )
  360. {
  361. // Increment by 1 to allow the "emergency admin" user. Essentially, the final user
  362. // to connect must be an administrator in case something is going wrong, such as DoS
  363. SrvMaxUsers += 1;
  364. }
  365. //
  366. // The following items are generally per-processor. Ensure they
  367. // are a multiple of the number of processors in the system.
  368. //
  369. SrvMaxReceiveWorkItemCount =
  370. MultipleOfProcessors( SrvMaxReceiveWorkItemCount );
  371. SrvInitialReceiveWorkItemCount =
  372. MultipleOfProcessors( SrvInitialReceiveWorkItemCount );
  373. SrvMinReceiveQueueLength =
  374. MultipleOfProcessors( SrvMinReceiveQueueLength );
  375. SrvMaxRawModeWorkItemCount =
  376. MultipleOfProcessors( SrvMaxRawModeWorkItemCount );
  377. SrvInitialRawModeWorkItemCount =
  378. MultipleOfProcessors( SrvInitialRawModeWorkItemCount );
  379. status = STATUS_SUCCESS;
  380. } except( EXCEPTION_EXECUTE_HANDLER ) {
  381. status = GetExceptionCode();
  382. }
  383. RELEASE_LOCK( &SrvConfigurationLock );
  384. return status;
  385. } // SrvNetServerSetInfo
  386. LARGE_INTEGER
  387. SecondsToTime (
  388. IN ULONG Seconds,
  389. IN BOOLEAN MakeNegative
  390. )
  391. /*++
  392. Routine Description:
  393. This routine converts a time interval specified in seconds to
  394. the NT time base in 100s on nanoseconds.
  395. Arguments:
  396. Seconds - the interval in seconds.
  397. MakeNegative - if TRUE, the time returned is a negative, i.e. relative
  398. time.
  399. Return Value:
  400. LARGE_INTEGER - the interval in NT time.
  401. --*/
  402. {
  403. LARGE_INTEGER ntTime;
  404. PAGED_CODE( );
  405. if ( MakeNegative ) {
  406. ntTime.QuadPart = Int32x32To64( Seconds, -1*10*1000*1000 );
  407. } else {
  408. ntTime.QuadPart = Int32x32To64( Seconds, 1*10*1000*1000 );
  409. }
  410. return ntTime;
  411. } // SecondsToTime
  412. LARGE_INTEGER
  413. MinutesToTime (
  414. IN ULONG Minutes,
  415. IN BOOLEAN MakeNegative
  416. )
  417. /*++
  418. Routine Description:
  419. This routine converts a time interval specified in minutes to
  420. the NT time base in 100s on nanoseconds.
  421. Arguments:
  422. Minutes - the interval in minutes.
  423. MakeNegative - if TRUE, the time returned is a negative, i.e. relative
  424. time.
  425. Return Value:
  426. LARGE_INTEGER - the interval in NT time.
  427. --*/
  428. {
  429. PAGED_CODE( );
  430. return SecondsToTime( 60*Minutes, MakeNegative );
  431. } // MinutesToTime
  432. ULONG
  433. MultipleOfProcessors(
  434. IN ULONG value
  435. )
  436. /*++
  437. Routine Description:
  438. This routine ensures the passed in value is a multiple of the number
  439. of processors in the system. The value will be adjusted upward if
  440. necessary.
  441. Arguments:
  442. value - the value to be adjusted
  443. Return Value:
  444. the adjusted value
  445. --*/
  446. {
  447. value += SrvNumberOfProcessors - 1;
  448. value /= SrvNumberOfProcessors;
  449. value *= SrvNumberOfProcessors;
  450. return value;
  451. }