|
|
/*++
Copyright (c) 1994 Microsoft Corporation
Module Name: rpcsupp.cxx
Abstract:
This module contains the server side RPC admin APIs
Author:
John Ludeman (johnl) 02-Dec-1994
Project:
Internet Servers Common Server DLL
--*/
//
// Include Headers
//
#include <tcpdllp.hxx>
#include <tsunami.hxx>
extern "C" { #include <info_srv.h>
};
#include <atq.h>
#include "inetreg.h"
#include <iistypes.hxx>
#include <iiscnfg.h>
#include <imd.h>
#include <inetreg.h>
#include <mb.hxx>
//
// number of capabilities DWORD
//
#define NUM_CAPABILITIES_FLAGS 1
NET_API_STATUS NET_API_FUNCTION R_InetInfoGetVersion( IN LPWSTR pszServer OPTIONAL, IN DWORD dwReserved, OUT DWORD * pdwVersion ) /*++
Description
Returns the version of the TCP server package. Primarily intended to detect downlevel servers for future versions of the admin tool.
Arguments:
pszServer - unused dwReserved - unused (may eventually indicate an individual server) pdwVersion - Receives the major version in the hi-word and the minor version in the low word
Note:
--*/ { *pdwVersion = MAKELONG( IIS_VERSION_MAJOR, IIS_VERSION_MINOR );
return NO_ERROR; } // R_InetInfoGetVersion
NET_API_STATUS NET_API_FUNCTION R_InetInfoGetServerCapabilities( IN LPWSTR pszServer OPTIONAL, IN DWORD dwReserved, OUT LPINET_INFO_CAPABILITIES_STRUCT *ppCap ) /*++
Description
Returns the information about the server and its capabilities.
Arguments:
pszServer - unused dwReserved - unused (may eventually indicate an individual server) ppCap - Receives the INET_INFO_CAPABILITIES structure
--*/ { DWORD err = NO_ERROR; LPINET_INFO_CAPABILITIES_STRUCT pCap;
IF_DEBUG( DLL_RPC) {
DBGPRINTF( ( DBG_CONTEXT, " Entering R_InetInfoGetServerCapabilities()\n" )); }
if ( ( err = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION)) != NO_ERROR) {
IF_DEBUG( DLL_RPC) {
DBGPRINTF( ( DBG_CONTEXT, " TsApiAccessCheck() Failed. Error = %u\n", err)); }
} else {
OSVERSIONINFO verInfo; DWORD bufSize = sizeof(INET_INFO_CAPABILITIES_STRUCT) + NUM_CAPABILITIES_FLAGS * sizeof(INET_INFO_CAP_FLAGS);
pCap = (LPINET_INFO_CAPABILITIES_STRUCT) MIDL_user_allocate( bufSize ); *ppCap = pCap;
if ( pCap == NULL ) { return ERROR_NOT_ENOUGH_MEMORY; }
ZeroMemory(pCap, bufSize); pCap->CapFlags = (LPINET_INFO_CAP_FLAGS) ((PCHAR)pCap + sizeof(INET_INFO_CAPABILITIES));
//
// Fill in the version and product type
//
pCap->CapVersion = 1; switch (IISGetPlatformType()) { case PtNtServer: pCap->ProductType = INET_INFO_PRODUCT_NTSERVER; break; case PtNtWorkstation: pCap->ProductType = INET_INFO_PRODUCT_NTWKSTA; break; default: pCap->ProductType = INET_INFO_PRODUCT_UNKNOWN; }
//
// Fill in GetVersionEx information
//
verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if ( GetVersionEx( &verInfo ) ) { pCap->BuildNumber = verInfo.dwBuildNumber; } else { pCap->BuildNumber = 0; }
pCap->MajorVersion = IIS_VERSION_MAJOR; pCap->MinorVersion = IIS_VERSION_MINOR;
//
// Fill in the capabilities
//
pCap->NumCapFlags = NUM_CAPABILITIES_FLAGS;
pCap->CapFlags[0].Mask = IIS_CAP1_ALL;
if ( pCap->ProductType == INET_INFO_PRODUCT_NTSERVER ) {
//
// For downlevel purposes, we take out the multi-instance and virtual
// sever support since the downlevel version of the RPC api
// doesn't support those concepts.
//
pCap->CapFlags[0].Flag = (IIS_CAP1_NTS & ~(IIS_CAP1_MULTIPLE_INSTANCE | IIS_CAP1_VIRTUAL_SERVER));
} else {
pCap->CapFlags[0].Flag = IIS_CAP1_NTW; } }
return ( err );
} // R_InetInfoGetServerCapabilities
NET_API_STATUS NET_API_FUNCTION R_InetInfoSetGlobalAdminInformation( IN LPWSTR pszServer OPTIONAL, IN DWORD dwReserved, IN INETA_GLOBAL_CONFIG_INFO * pConfig ) /*++
Description
Sets the global service admin information
Arguments:
pszServer - unused dwReserved pConfig - Admin information to set
Note:
--*/ { DWORD err; HKEY hkey = NULL; HKEY CacheKey = NULL; HKEY FilterKey = NULL; DWORD dwDummy;
if ( ( err = TsApiAccessCheck( TCP_SET_ADMIN_INFORMATION)) != NO_ERROR) {
IF_DEBUG( DLL_RPC) {
DBGPRINTF( ( DBG_CONTEXT, " TsApiAccessCheck() Failed. Error = %u\n", err)); }
return err; }
err = ERROR_NOT_SUPPORTED;
return err; } // R_InetInfoSetGlobalAdminInformation
NET_API_STATUS NET_API_FUNCTION R_InetInfoGetGlobalAdminInformation( IN LPWSTR pszServer OPTIONAL, IN DWORD dwReserved, OUT LPINETA_GLOBAL_CONFIG_INFO * ppConfig ) /*++
Description
Gets the global service admin information
Arguments:
pszServer - unused dwReserved ppConfig - Receives current operating values of the server
Note:
--*/ { DWORD err = NO_ERROR; INETA_GLOBAL_CONFIG_INFO * pConfig;
IF_DEBUG( DLL_RPC) {
DBGPRINTF( ( DBG_CONTEXT, " Entering R_InetInfoGetGlobalAdminInformation()\n" )); }
if ( ( err = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION)) != NO_ERROR) {
IF_DEBUG( DLL_RPC) {
DBGPRINTF( ( DBG_CONTEXT, " TsApiAccessCheck() Failed. Error = %u\n", err)); }
} else {
*ppConfig = (INETA_GLOBAL_CONFIG_INFO *) MIDL_user_allocate( sizeof( INET_INFO_GLOBAL_CONFIG_INFO ));
if ( !*ppConfig ) { return ERROR_NOT_ENOUGH_MEMORY; }
pConfig = *ppConfig;
memset( pConfig, 0, sizeof( *pConfig ));
pConfig->FieldControl = FC_GINET_INFO_ALL;
pConfig->cbMemoryCacheSize = 0; pConfig->BandwidthLevel = (DWORD)AtqGetInfo( AtqBandwidthThrottle);
if( err != NO_ERROR ) {
//
// clean up the allocated memory
//
MIDL_user_free( pConfig );
} else {
*ppConfig = pConfig;
} }
IF_DEBUG( DLL_RPC) {
DBGPRINTF(( DBG_CONTEXT, "R_InetInfoGetGlobalAdminInformation() returns Error = %u \n", err )); }
return ( err );
} // R_InetInfoGetGlobalAdminInformation()
NET_API_STATUS NET_API_FUNCTION R_InetInfoSetAdminInformation( IN LPWSTR pszServer OPTIONAL, IN DWORD dwServerMask, IN INETA_CONFIG_INFO * pConfig ) /*++
Description
Sets the common service admin information for the servers specified in dwServerMask.
Arguments:
pszServer - unused dwServerMask - Bitfield of servers to set the information for pConfig - Admin information to set
Note:
--*/ { DWORD err;
LPINET_INFO_VIRTUAL_ROOT_LIST rootList = NULL;
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Entering R_InetInfoSetAdminInformation. Mask %x\n", dwServerMask)); }
//
// Do we have permissions?
//
if ( (err = TsApiAccessCheck( TCP_SET_ADMIN_INFORMATION )) != NO_ERROR) { IF_DEBUG( DLL_RPC) {
DBGPRINTF( ( DBG_CONTEXT, " TsApiAccessCheck() Failed. Error = %u\n", err)); } return(err); }
//
// Loop through the services and set the information for each one
//
if ( !IIS_SERVICE::SetServiceAdminInfo( 1, dwServerMask, 1, // Instance - may be overidden with downlevel instance
TRUE, // common config
pConfig )) {
err = GetLastError(); IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, "SetServiceAdminInfo failed. Error = %u\n", err)); } }
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Leaving R_InetInfoSetAdminInformation. Err = %d\n", err )); }
return(err);
} // R_InetInfoSetAdminInformation
NET_API_STATUS NET_API_FUNCTION R_InetInfoGetAdminInformation( IN LPWSTR pszServer OPTIONAL, IN DWORD dwServerMask, OUT LPINETA_CONFIG_INFO * ppConfig ) /*++
Description
Gets the common service admin information for the specified server in dwServerMask.
Arguments:
pszServer - unused dwServerMask - Bitfield of server to get the information for pConfig - Receives current operating values of the server
Note:
--*/ { DWORD err = NO_ERROR; DWORD nEntries = 0; PCHAR buffer = NULL; DWORD nRead = 0;
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Entering R_InetInfoGetAdminInformation.\n")); }
*ppConfig = NULL;
//
// Call the new API
//
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Entering R_InetInfoGetAdminInformation. Mask %x\n", dwServerMask)); }
if ( !IIS_SERVICE::GetServiceAdminInfo( 1, dwServerMask, 1, // Instance - my get overidden by downlevel instance
TRUE, // common config
&nRead, ppConfig )) {
DBG_ASSERT(buffer == NULL); DBG_ASSERT(nRead == 0);
err = GetLastError(); DBG_ASSERT(err != NO_ERROR); IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, "GetServiceAdminInfo failed. Error = %u\n", err)); } } else {
DBG_ASSERT(nRead == 1); }
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Leaving R_InetInfoGetAdminInformation. Err = %d\n", err )); }
return(err);
} // R_InetInfoGetAdminInformation()
NET_API_STATUS NET_API_FUNCTION R_InetInfoGetSites( IN LPWSTR pszServer OPTIONAL, IN DWORD dwServerMask, OUT LPINET_INFO_SITE_LIST * ppSites ) /*++
Description
Gets the list of instances for the specified server in dwServerMask.
Arguments:
pszServer - unused dwServerMask - Bitfield of server to get the information for ppSites - Receives current site list
Note:
--*/ { BOOL fRet = FALSE; DWORD err = NO_ERROR;
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Entering R_InetInfoGetSites.\n")); }
*ppSites = NULL;
//
// Call the new API
//
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Entering R_InetInfoGetSites. Mask %x\n", dwServerMask)); }
fRet = IIS_SERVICE::GetServiceSiteInfo ( dwServerMask, ppSites ); if (!fRet) {
err = GetLastError();
DBG_ASSERT(err != NO_ERROR); IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, "GetServiceSiteInfo failed. Error = %u\n", err)); } }
IF_DEBUG( DLL_RPC) { DBGPRINTF( ( DBG_CONTEXT, " Leaving R_InetInfoGetSiteInformation. Err = %d\n", err )); }
return(err);
} // R_InetInfoGetSiteInformation()
NET_API_STATUS NET_API_FUNCTION R_InetInfoQueryStatistics( IN LPWSTR pszServer OPTIONAL, IN DWORD Level, IN DWORD dwServerMask, LPINET_INFO_STATISTICS_INFO StatsInfo ) { DWORD err;
err = TsApiAccessCheck( TCP_QUERY_STATISTICS );
if ( err ) { return err; }
switch ( Level ) {
case 0: { INET_INFO_STATISTICS_0 * pstats0; ATQ_STATISTICS atqStats;
pstats0 = (INET_INFO_STATISTICS_0 *) MIDL_user_allocate( sizeof( INET_INFO_STATISTICS_0 ));
if ( !pstats0 ) { return ERROR_NOT_ENOUGH_MEMORY; }
#ifndef NO_AUX_PERF
// init count of counters that are valid
pstats0->nAuxCounters = 0;
//
// IF THERE ARE VALID UNNAMED COUNTERS THAT WE WISH TO TRACK
// WE SHOULD DO SO HERE........
// For Future Additions, this comment is added.
// MuraliK 20-Sept-1995
//
#endif // NO_AUX_PERF
if ( !TsCacheQueryStatistics( Level, dwServerMask, &pstats0->CacheCtrs ) || !AtqGetStatistics( &atqStats)) { MIDL_user_free( pstats0 ); err = GetLastError(); } else {
// copy Atq Statistics to stats
INETA_ATQ_STATISTICS * pAtqStats = &pstats0->AtqCtrs; pAtqStats->TotalBlockedRequests = atqStats.cBlockedRequests; pAtqStats->TotalAllowedRequests = atqStats.cAllowedRequests; pAtqStats->TotalRejectedRequests = atqStats.cRejectedRequests; pAtqStats->CurrentBlockedRequests= atqStats.cCurrentBlockedRequests; pAtqStats->MeasuredBandwidth = atqStats.MeasuredBandwidth;
StatsInfo->InetStats0 = pstats0; } } break;
default: err = ERROR_INVALID_LEVEL; break; }
return err; }
NET_API_STATUS NET_API_FUNCTION R_InetInfoClearStatistics( IN LPWSTR pszServer OPTIONAL, IN DWORD dwServerMask ) { DWORD err;
err = TsApiAccessCheck( TCP_SET_ADMIN_INFORMATION );
if ( err == NO_ERROR) { if (!TsCacheClearStatistics( dwServerMask ) || !AtqClearStatistics()) {
err = GetLastError(); } }
return err; } // R_InetInfoClearStatistics
NET_API_STATUS NET_API_FUNCTION R_InetInfoFlushMemoryCache( IN LPWSTR pszServer OPTIONAL, IN DWORD dwServerMask ) { DWORD err;
err = TsApiAccessCheck( TCP_SET_ADMIN_INFORMATION );
if ( err ) { return err; }
if ( !TsCacheFlush( dwServerMask )) { return GetLastError(); }
return NO_ERROR; }
BOOL ReadRegString( HKEY hkey, CHAR * * ppchstr, LPCSTR pchValue, LPCSTR pchDefault ) /*++
Description
Gets the specified string from the registry. If *ppchstr is not NULL, then the value is freed. If the registry call fails, *ppchstr is restored to its previous value.
Arguments:
hkey - Handle to open key ppchstr - Receives pointer of allocated memory of the new value of the string pchValue - Which registry value to retrieve pchDefault - Default string if value isn't found
--*/ { CHAR * pch = *ppchstr;
*ppchstr = ReadRegistryString( hkey, pchValue, pchDefault, TRUE );
if ( !*ppchstr ) { *ppchstr = pch; return FALSE; }
if ( pch ) { TCP_FREE( pch ); }
return TRUE;
} // ReadRegString
BOOL ConvertStringToRpc( WCHAR * * ppwch, LPCSTR pch ) /*++
Description
Allocates, copies and converts pch to *ppwch
Arguments:
ppwch - Receives allocated destination string pch - ANSI string to copy from
--*/ { int cch; int iRet;
if ( !pch ) { *ppwch = NULL; return TRUE; }
cch = strlen( pch );
if ( !(*ppwch = (WCHAR *) MIDL_user_allocate( (cch + 1) * sizeof(WCHAR))) ) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return FALSE; }
iRet = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pch, cch + 1, *ppwch, cch + 1 );
if ( !iRet ) { MIDL_user_free( *ppwch ); return FALSE; }
return TRUE; } // ConvertStringToRpc
VOID FreeRpcString( WCHAR * pwch ) { if ( pwch ) { MIDL_user_free( pwch ); }
} // FreeRpcString
DWORD InitGlobalConfigFromReg( VOID ) /*++
Loads the global configuration parameters from registry. Should be called after Atq Module is initialized.
Returns: Win32 error code. NO_ERROR on success
--*/
{ DWORD dwError; HKEY hkey = NULL; DWORD dwVal; MB mb( (IMDCOM*) IIS_SERVICE::QueryMDObject() );
dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE, INET_INFO_PARAMETERS_KEY, 0, KEY_ALL_ACCESS, &hkey);
if ( dwError == NO_ERROR) {
DWORD dwChangeNumber;
// See if we need to migrate the bandwidth to the
// metabase.
if (!mb.GetSystemChangeNumber(&dwChangeNumber) || dwChangeNumber == 0) { if (!mb.Open( "/lm", METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE )) { return GetLastError(); }
dwVal = ReadRegistryDword( hkey, INETA_BANDWIDTH_LEVEL, INETA_DEF_BANDWIDTH_LEVEL);
mb.SetDword("", MD_MAX_BANDWIDTH, IIS_MD_UT_SERVER, dwVal); mb.Close(); }
}
if (mb.Open("/lm", METADATA_PERMISSION_READ)) { if ( mb.GetDword("", MD_MAX_BANDWIDTH_BLOCKED, IIS_MD_UT_SERVER, &dwVal )) { AtqSetInfo( AtqBandwidthThrottleMaxBlocked, (ULONG_PTR)dwVal ); }
if (!mb.GetDword("", MD_MAX_BANDWIDTH, IIS_MD_UT_SERVER, &dwVal)) { DBGPRINTF( ( DBG_CONTEXT, "Could not read MD_MAX_BANDWIDTH\n" ) ); dwVal = INETA_DEF_BANDWIDTH_LEVEL; } } else { DBGPRINTF( ( DBG_CONTEXT, "Couldn't open; error=%d\n", GetLastError() ) ); dwVal = INETA_DEF_BANDWIDTH_LEVEL; } DBGPRINTF( ( DBG_CONTEXT, " Setting Global throttle value to %d\n", dwVal ));
AtqSetInfo( AtqBandwidthThrottle, (ULONG_PTR)dwVal);
if ( hkey ) { RegCloseKey( hkey ); }
return NO_ERROR;
} // InitGlobalConfigFromReg()
|