diff options
Diffstat (limited to 'private/net/svcdlls/srvsvc/server/internal.c')
-rw-r--r-- | private/net/svcdlls/srvsvc/server/internal.c | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/private/net/svcdlls/srvsvc/server/internal.c b/private/net/svcdlls/srvsvc/server/internal.c new file mode 100644 index 000000000..d038cfa85 --- /dev/null +++ b/private/net/svcdlls/srvsvc/server/internal.c @@ -0,0 +1,214 @@ +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + Internal.c + +Abstract: + + This module contains "internal" APIs exported by the server service. + +--*/ + +#include "srvsvcp.h" +#include "ssdata.h" + +#include <debugfmt.h> +#include <tstr.h> +#include <lmerr.h> + + +NET_API_STATUS NET_API_FUNCTION +I_NetrServerSetServiceBitsEx ( + IN LPTSTR ServerName, + IN LPTSTR EmulatedServerName OPTIONAL, + IN LPTSTR TransportName OPTIONAL, + IN DWORD ServiceBitsOfInterest, + IN DWORD ServiceBits, + IN DWORD UpdateImmediately + ) + +/*++ + +Routine Description: + + This routine sets the value of the Server Type as sent in server + announcement messages. It is an internal API used only by the + service controller. + +Arguments: + + ServerName - Used by RPC to direct the call. This API may only be + issued locally. This is enforced by the client stub. + + EmulatedServerName - server name being emulated on this computer + + TransportName - parameter optionally giving specific transport for which + to set the bits + + ServiceBitsOfInterest - bit mask indicating significant 'ServiceBits' + + ServiceBits - Bits (preassigned to various components by Microsoft) + indicating which services are active. This field is not + interpreted by the server service. + +Return Value: + + NET_API_STATUS - NO_ERROR or ERROR_NOT_SUPPORTED. + +--*/ + +{ + BOOL changed = FALSE; + PNAME_LIST_ENTRY Service; + PTRANSPORT_LIST_ENTRY transport; + DWORD newBits; + NET_API_STATUS error; + CHAR serverNameBuf[ MAX_PATH ]; + PCHAR emulatedName; + ULONG namelen; + + ServerName; // avoid compiler warnings + + if( ARGUMENT_PRESENT( EmulatedServerName ) ) { + UNICODE_STRING name; + + RtlInitUnicodeString( &name, EmulatedServerName ); + + error = ConvertStringToTransportAddress( &name, serverNameBuf, &namelen ); + if( error != NERR_Success ) { + return error; + } + + emulatedName = serverNameBuf; + + } else { + + emulatedName = SsServerTransportAddress; + namelen = SsServerTransportAddressLength; + } + + // + // Don't let bits that are controlled by the server be set. + // + + ServiceBitsOfInterest &= ~SERVER_TYPE_INTERNAL_BITS; + ServiceBits &= ServiceBitsOfInterest; + + // + // Make the modifications under control of the service resource. + // + + (VOID)RtlAcquireResourceExclusive( &SsServerInfoResource, TRUE ); + +#ifdef SRV_PNP_POWER + if( SsServerNameList == NULL && !ARGUMENT_PRESENT( TransportName ) ) { + + // + // We have not bound to any transports yet. + // Remember the setting which is being asked for so we can use it later + // + + SsData.ServiceBits &= ~ServiceBitsOfInterest; + SsData.ServiceBits |= ServiceBits; + RtlReleaseResource( &SsServerInfoResource ); + return NO_ERROR; + } +#endif + + // + // Find the entry for the server name of interest + // + for( Service = SsServerNameList; Service != NULL; Service = Service->Next ) { + + if( Service->TransportAddressLength != namelen ) { + continue; + } + + if( RtlEqualMemory( emulatedName, Service->TransportAddress, namelen ) ) { + break; + } + } + + if( Service == NULL ) { + RtlReleaseResource( &SsServerInfoResource ); + return NERR_NetNameNotFound; + } + +#ifdef SRV_PNP_POWER + + if( SsData.ServiceBits != 0 && Service->PrimaryName ) { + Service->ServiceBits = SsData.ServiceBits; + SsData.ServiceBits = 0; + } + +#endif + + if( ARGUMENT_PRESENT( TransportName ) ) { + // + // Transport name specified. Set the bits for that transport only. + // + + for( transport = Service->Transports; transport != NULL; transport = transport->Next ) { + if( !STRCMPI( TransportName, transport->TransportName ) ) { + // + // This is the transport of interest! + // + if( (transport->ServiceBits & ServiceBitsOfInterest) != ServiceBits ) { + transport->ServiceBits &= ~ServiceBitsOfInterest; + transport->ServiceBits |= ServiceBits; + changed = TRUE; + } + break; + } + } + if( transport == NULL ) { + // + // The requested transport was not found. + // + RtlReleaseResource( &SsServerInfoResource ); + return ERROR_PATH_NOT_FOUND; + } + + } else { + // + // No transport name specified. Change the bits for the whole server + // + + if( ( Service->ServiceBits & ServiceBitsOfInterest ) != ServiceBits ) { + Service->ServiceBits &= ~ServiceBitsOfInterest; + Service->ServiceBits |= ServiceBits; + changed = TRUE; + + } + } + + RtlReleaseResource( &SsServerInfoResource ); + + if ( changed ) { + SsSetExportedServerType( NULL, TRUE, (BOOL)UpdateImmediately ); + } + + return NO_ERROR; + +} // I_NetrServerSetServiceBits + +NET_API_STATUS NET_API_FUNCTION +I_NetrServerSetServiceBits ( + IN LPTSTR ServerName, + IN LPTSTR TransportName OPTIONAL, + IN DWORD ServiceBits, + IN DWORD UpdateImmediately + ) +{ + return I_NetrServerSetServiceBitsEx ( + ServerName, + NULL, + TransportName, + 0xFFFFFFFF, // All bits are of interest (just overlay the old bits) + ServiceBits, + UpdateImmediately + ); +} |