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.
886 lines
20 KiB
886 lines
20 KiB
/*++
|
|
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()
|