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.

221 lines
5.7 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Internal.c
  5. Abstract:
  6. This module contains "internal" APIs exported by the server service.
  7. --*/
  8. #include "srvsvcp.h"
  9. #include <debugfmt.h>
  10. #include <tstr.h>
  11. #include <lmerr.h>
  12. NET_API_STATUS NET_API_FUNCTION
  13. I_NetrServerSetServiceBitsEx (
  14. IN LPTSTR ServerName,
  15. IN LPTSTR EmulatedServerName OPTIONAL,
  16. IN LPTSTR TransportName OPTIONAL,
  17. IN DWORD ServiceBitsOfInterest,
  18. IN DWORD ServiceBits,
  19. IN DWORD UpdateImmediately
  20. )
  21. /*++
  22. Routine Description:
  23. This routine sets the value of the Server Type as sent in server
  24. announcement messages. It is an internal API used only by the
  25. service controller.
  26. Arguments:
  27. ServerName - Used by RPC to direct the call. This API may only be
  28. issued locally. This is enforced by the client stub.
  29. EmulatedServerName - server name being emulated on this computer
  30. TransportName - parameter optionally giving specific transport for which
  31. to set the bits
  32. ServiceBitsOfInterest - bit mask indicating significant 'ServiceBits'
  33. ServiceBits - Bits (preassigned to various components by Microsoft)
  34. indicating which services are active. This field is not
  35. interpreted by the server service.
  36. Return Value:
  37. NET_API_STATUS - NO_ERROR or ERROR_NOT_SUPPORTED.
  38. --*/
  39. {
  40. BOOL changed = FALSE;
  41. PNAME_LIST_ENTRY Service;
  42. PTRANSPORT_LIST_ENTRY transport;
  43. DWORD newBits;
  44. NET_API_STATUS error;
  45. CHAR serverNameBuf[ MAX_PATH ];
  46. PCHAR emulatedName;
  47. ULONG namelen;
  48. ServerName; // avoid compiler warnings
  49. if( SsData.SsInitialized ) {
  50. error = SsCheckAccess(
  51. &SsConfigInfoSecurityObject,
  52. SRVSVC_CONFIG_INFO_SET
  53. );
  54. if ( error != NO_ERROR ) {
  55. return ERROR_ACCESS_DENIED;
  56. }
  57. }
  58. if( ARGUMENT_PRESENT( EmulatedServerName ) ) {
  59. UNICODE_STRING name;
  60. RtlInitUnicodeString( &name, EmulatedServerName );
  61. error = ConvertStringToTransportAddress( &name, serverNameBuf, &namelen );
  62. if( error != NERR_Success ) {
  63. return error;
  64. }
  65. emulatedName = serverNameBuf;
  66. } else {
  67. emulatedName = SsData.SsServerTransportAddress;
  68. namelen = SsData.SsServerTransportAddressLength;
  69. }
  70. //
  71. // Don't let bits that are controlled by the server be set.
  72. //
  73. ServiceBitsOfInterest &= ~SERVER_TYPE_INTERNAL_BITS;
  74. ServiceBits &= ServiceBitsOfInterest;
  75. //
  76. // Make the modifications under control of the service resource.
  77. //
  78. (VOID)RtlAcquireResourceExclusive( &SsData.SsServerInfoResource, TRUE );
  79. if( SsData.SsServerNameList == NULL && !ARGUMENT_PRESENT( TransportName ) ) {
  80. //
  81. // We have not bound to any transports yet.
  82. // Remember the setting which is being asked for so we can use it later
  83. //
  84. SsData.ServiceBits &= ~ServiceBitsOfInterest;
  85. SsData.ServiceBits |= ServiceBits;
  86. RtlReleaseResource( &SsData.SsServerInfoResource );
  87. return NO_ERROR;
  88. }
  89. //
  90. // Find the entry for the server name of interest
  91. //
  92. for( Service = SsData.SsServerNameList; Service != NULL; Service = Service->Next ) {
  93. if( Service->TransportAddressLength != namelen ) {
  94. continue;
  95. }
  96. if( RtlEqualMemory( emulatedName, Service->TransportAddress, namelen ) ) {
  97. break;
  98. }
  99. }
  100. if( Service == NULL ) {
  101. RtlReleaseResource( &SsData.SsServerInfoResource );
  102. return NERR_NetNameNotFound;
  103. }
  104. //
  105. // Apply any saved ServiceBits
  106. //
  107. if( SsData.ServiceBits != 0 && Service->PrimaryName ) {
  108. Service->ServiceBits = SsData.ServiceBits;
  109. SsData.ServiceBits = 0;
  110. }
  111. if( ARGUMENT_PRESENT( TransportName ) ) {
  112. //
  113. // Transport name specified. Set the bits for that transport only.
  114. //
  115. for( transport = Service->Transports; transport != NULL; transport = transport->Next ) {
  116. if( !STRCMPI( TransportName, transport->TransportName ) ) {
  117. //
  118. // This is the transport of interest!
  119. //
  120. if( (transport->ServiceBits & ServiceBitsOfInterest) != ServiceBits ) {
  121. transport->ServiceBits &= ~ServiceBitsOfInterest;
  122. transport->ServiceBits |= ServiceBits;
  123. changed = TRUE;
  124. }
  125. break;
  126. }
  127. }
  128. if( transport == NULL ) {
  129. //
  130. // The requested transport was not found.
  131. //
  132. RtlReleaseResource( &SsData.SsServerInfoResource );
  133. return ERROR_PATH_NOT_FOUND;
  134. }
  135. } else {
  136. //
  137. // No transport name specified. Change the bits for the whole server
  138. //
  139. if( ( Service->ServiceBits & ServiceBitsOfInterest ) != ServiceBits ) {
  140. Service->ServiceBits &= ~ServiceBitsOfInterest;
  141. Service->ServiceBits |= ServiceBits;
  142. changed = TRUE;
  143. }
  144. }
  145. RtlReleaseResource( &SsData.SsServerInfoResource );
  146. if ( changed ) {
  147. SsSetExportedServerType( NULL, TRUE, (BOOL)UpdateImmediately );
  148. }
  149. return NO_ERROR;
  150. } // I_NetrServerSetServiceBits
  151. NET_API_STATUS NET_API_FUNCTION
  152. I_NetrServerSetServiceBits (
  153. IN LPTSTR ServerName,
  154. IN LPTSTR TransportName OPTIONAL,
  155. IN DWORD ServiceBits,
  156. IN DWORD UpdateImmediately
  157. )
  158. {
  159. return I_NetrServerSetServiceBitsEx (
  160. ServerName,
  161. NULL,
  162. TransportName,
  163. 0xFFFFFFFF, // All bits are of interest (just overlay the old bits)
  164. ServiceBits,
  165. UpdateImmediately
  166. );
  167. }