Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

918 lines
20 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
rpcsupp.cxx
Abstract:
Contains RPC functions for Gopher server administration.
Author:
Murali R. Krishnan ( MuraliK ) 17-Nov-1994
Project:
Gopher Server DLL
Functions Exported:
DWORD R_GdEnumerateUsers(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
OUT LPGOPHERD_USER_ENUM_STRUCT lpUserBuffer);
DWORD R_GdDisconnectUser(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
IN DWORD dwIdUser)
DWORD R_GdGetStatistics(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
IN LPGOPHERD_STATISTICS_INFO lpStat)
DWORD R_GdClearStatistics(
IN GOPHERD_IMPERSONATE_HANDLE pszServer)
DWORD R_GdGetAdminInformation(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
OUT LPGOPHERD_CONFIG_INFO * ppConfigInfo)
DWORD R_GdSetAdminInformation(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
IN LPGOPHERD_CONFIG_INFO pConfigInfo)
Revision History:
MuraliK 17-Feb-1995 Removed Virtual Volumes APIs
( they are moved to services common APIs).
--*/
/************************************************************
* Include Headers
************************************************************/
# include "gdpriv.h"
extern "C" {
# include "gd_srv.h"
# include "inetinfo.h"
};
# include "gdglobal.hxx"
/************************************************************
* Functions
************************************************************/
extern "C"
DWORD
NET_API_FUNCTION
R_GdEnumerateUsers(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
OUT LPGOPHERD_USER_ENUM_STRUCT lpUserBuffer
)
/*++
Description:
This function enumerates the user information in a buffer.
( This is server side API function for RPC)
Arguments:
pszServer pointer to string containing the target server ( unused)
lpUserBuffer pointer to enumeration buffer
Returns:
Win32 error code.
NO_ERROR on success.
--*/
{
DWORD err = NO_ERROR;
DWORD cbBuffer;
ASSERT( lpUserBuffer != NULL );
UNREFERENCED_PARAMETER(pszServer);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT, "Enumerating Users() ( RPC call)\n"));
});
//
// This functionality is not yet implemented.
//
err = ERROR_CALL_NOT_IMPLEMENTED;
return err;
} // R_GdEnumerateUsers()
extern "C"
DWORD
NET_API_FUNCTION
R_GdDisconnectUser(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
IN DWORD dwIdUser
)
/*++
Description:
Disconnects a specified user from the server.
This is a server-side worker function for RPC.
Arguments:
pszServer
pointer to string containing target server ( unused)
dwIduser
id for the user which is to be disconnected.
If 0 disconnect all the users.
Returns:
Win32 error code. NO_ERROR on success.
--*/
{
DWORD err = NO_ERROR;
UNREFERENCED_PARAMETER(pszServer);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT, "R_GdDisconnectUser() called for user %d\n",
dwIdUser));
});
err = ERROR_CALL_NOT_IMPLEMENTED;
return err;
} // R_GdDisconnectUser()
extern "C"
DWORD
NET_API_FUNCTION
R_GdGetStatistics(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
IN LPGOPHERD_STATISTICS_INFO lpStat
)
/*++
Description:
Copies the server statistics into the buffer passed in.
This is a server-side worker function for RPC.
Arguments:
pszServer
pointer to string containing server name ( unused)
lpStat
pointer to statistics information buffer that will contain
the resulting statistics data.
Returns:
Win32 error code. NO_ERROR on success.
--*/
{
DWORD err;
TCP_ASSERT( lpStat != NULL );
UNREFERENCED_PARAMETER(pszServer);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT, "R_GdGetStatistics() called \n"));
});
//
// Check for proper access.
//
err = TsApiAccessCheck( TCP_QUERY_STATISTICS );
if( err != NO_ERROR ) {
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdGetStatistics failed access check, error %lu\n",
err ));
});
return err;
}
err = g_pstat->CopyToStatBuffer( lpStat);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdGetStatistics() returning statistics. Error = %d \n",
err));
});
return ( err);
} // R_GdGetStatistics();
extern "C"
DWORD
NET_API_FUNCTION
R_GdClearStatistics(
IN GOPHERD_IMPERSONATE_HANDLE pszServer
)
/*++
Description:
Clears the current server statistics.
This is a server-side worker function for RPC.
Arguments:
pszServer
pointer to string containing the server name ( unused)
Returns:
Win32 error code. NO_ERROR on success.
--*/
{
DWORD err;
UNREFERENCED_PARAMETER(pszServer);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT, " R_GdClearStatistics() called\n"));
});
//
// Check for proper access.
//
err = TsApiAccessCheck( TCP_CLEAR_STATISTICS );
if( err != NO_ERROR )
{
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdClearStatistics() failed access check."
" Error = %u\n",
err ));
});
return err;
}
//
// Clear the statistics.
//
g_pstat->ClearStatistics();
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdClearStatistics() returns Error = %d \n",
err));
});
return ( err);
} // R_GdClearStatistics()
extern "C"
DWORD
NET_API_FUNCTION
R_GdGetAdminInformation(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
OUT LPGOPHERD_CONFIG_INFO * ppConfigInfo
)
/*++
Description:
This functions obtains the current configuration information for server.
Arguments:
pszServer
pointer to null-terminated string with the name of the server.
ppConfigInfo
pointer to a location where the pointer to Config data is returned.
The caller should free the pointer after use.
Returns:
Win32 error code. NO_ERROR on success.
--*/
{
DWORD err = NO_ERROR;
LPGOPHERD_CONFIG_INFO pLocalConfigInfo;
UNREFERENCED_PARAMETER(pszServer);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT, "R_GdGetAdminInformation() is called.\n" ));
});
if ( ppConfigInfo == NULL || *ppConfigInfo != NULL ) {
return ( ERROR_INVALID_PARAMETER);
}
//
// Check for proper access.
//
err = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION);
if( err != NO_ERROR ) {
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdGetAdminInformation() failed access check."
" Error = %u\n",
err));
});
return err;
}
//
// Inquire the configuration information from the GSERVER_CONFIG object
//
pLocalConfigInfo = ( LPGOPHERD_CONFIG_INFO )
MIDL_user_allocate( sizeof ( GOPHERD_CONFIG_INFO));
if ( pLocalConfigInfo == NULL) {
return ( ERROR_NOT_ENOUGH_MEMORY);
}
err = g_pGserverConfig->GetConfigInformation( pLocalConfigInfo);
if ( err == NO_ERROR) {
//
// Successful in getting the config information.
// Store in *ppConfigInfo for return
//
*ppConfigInfo = pLocalConfigInfo;
} else {
//
// Cleanup the memory allocated for storing data
//
// Individual Cleanup is done by GSERVER_CONFIG::GetConfigInformation()
MIDL_user_free( pLocalConfigInfo);
}
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdGetAdminInformation() returns Error = %u \n",
err));
});
return ( err);
} // R_GdGetAdminInformation()
extern "C"
DWORD
NET_API_FUNCTION
R_GdSetAdminInformation(
IN GOPHERD_IMPERSONATE_HANDLE pszServer,
IN LPGOPHERD_CONFIG_INFO pConfigInfo
)
/*++
Description:
Sets the configuration information for Gopher server.
Several of the configuration data will become
effective immediately.
The following parameters require a restart of the service, after
successfully setting their new values.
GDA_PORT_NUMBER
Arguments:
pszServer
pointer to null-terminated string with the name of the server.
FieldsToSet
bitmap indicating which fields are to be set.
pConfigInfo
pointer to GOPHERD_CONFIG_INFO containing values for fields whose
value are to be changed.
Returns:
Win32 error code. NO_ERROR on success.
--*/
{
DWORD err;
UNREFERENCED_PARAMETER(pszServer);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT, "R_GdGetAdminInformation() is called.\n" ));
});
if ( pConfigInfo == NULL) {
return ( ERROR_INVALID_PARAMETER);
}
//
// Check for proper access.
//
err = TsApiAccessCheck( TCP_SET_ADMIN_INFORMATION);
if( err != NO_ERROR ) {
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdSetAdminInformation() failed access check."
" Error = %u\n",
err));
});
return ( err);
}
if ( pConfigInfo->FieldControl == 0x0) {
return ( NO_ERROR); // No work to do. Redundant call
}
# if DBG
if ( err == NO_ERROR && pConfigInfo->FieldControl & GDA_DEBUG_FLAGS) {
//
// Set Debugging flags to new value.
//
err = WriteRegistryDword( g_hkeyGdParams,
GOPHERD_DEBUG_FLAGS,
pConfigInfo->dwDebugFlags);
// Only Debug Flags is directly set here
g_GdDebugFlags = pConfigInfo->dwDebugFlags;
SET_DEBUG_FLAGS( pConfigInfo->dwDebugFlags);
}
# endif // DBG
err = g_pGserverConfig->
SetConfigInformation( pConfigInfo);
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"R_GdSetAdminInformation() returns Error = %d \n",
err));
});
return ( err);
} // R_GdSetAdminInformation()
/**********************************************************
* Local functions for RPC interface
**********************************************************/
inline
DWORD BoolToDword( BOOL fValue)
{
return ( fValue) ? 1 : 0;
} // BoolToDword()
inline
VOID GdRpcFree( LPWSTR * ppszBuffer)
{
if ( *ppszBuffer != NULL) {
MIDL_user_free( *ppszBuffer);
*ppszBuffer = NULL;
}
return;
} // GdRpcFree()
BOOL
GdRpcUnicodeCopy(
OUT LPWSTR * ppszDst,
IN STR & strSrc)
/*++
Description:
Makes a unicode copy of the string given into a
new buffer allocated using MIDL_user_allocate
for RPC transfer.
Arguments:
ppszDst pointer to a location where to store the copied string
strSrc string containing the source data
Returns:
BOOL. TRUE on success and FALSE on failure.
--*/
{
DWORD cchBuffer = 0;
// get count of bytes
GOPHERD_REQUIRE( strSrc.CopyToBuffer( NULL, &cchBuffer));
//
// allocate the buffer for copy
//
*ppszDst = (LPWSTR ) MIDL_user_allocate( cchBuffer * sizeof( WCHAR));
if ( *ppszDst == NULL) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY);
return ( FALSE);
}
//
// make a copy of the string
//
return strSrc.CopyToBuffer( *ppszDst, &cchBuffer);
} // GdRpcUnicodeCopy()
DWORD
GSERVER_CONFIG::GetConfigInformation(
OUT LPGOPHERD_CONFIG_INFO pConfigInfo
)
/*++
Description:
Obtains the configuration information from Gopher Server config and
stores it in GOPHERD_CONFIG_INFO object
Arguments:
pConfigInfo
pointer to location where the data for gopher server configuration
is stored on successful return.
Returns:
Win32 error code. NO_ERROR on success.
--*/
{
DWORD dwErr = NO_ERROR;
STR strUnicode;
LPWSTR lpszUnicode;
//
// Initialize contents of *pConfigInfo to be NULL
//
memset( (LPVOID) pConfigInfo, 0, sizeof( GOPHERD_CONFIG_INFO));
//
// Presently we dont lock config on the assumption that the data we read
// from config structure can't change unless R_GdSetAdminInfo() is called,
// which is queued up behind R_GdGetAdminInfo()
// No Locking is done for performance reasons.
//
// LockConfig();
if ( !GdRpcUnicodeCopy( & pConfigInfo->lpszSite, m_strSite) ||
!GdRpcUnicodeCopy( & pConfigInfo->lpszOrganization,
m_strOrganization) ||
!GdRpcUnicodeCopy( & pConfigInfo->lpszLocation, m_strLocation) ||
!GdRpcUnicodeCopy( & pConfigInfo->lpszLanguage, m_strLanguage) ||
!GdRpcUnicodeCopy( & pConfigInfo->lpszGeography, m_strGeography)
) {
dwErr = ERROR_NOT_ENOUGH_MEMORY;
//
// Free up the strings that may have been allocated
//
GdRpcFree( & pConfigInfo->lpszSite);
GdRpcFree( & pConfigInfo->lpszOrganization);
GdRpcFree( & pConfigInfo->lpszLocation);
GdRpcFree( & pConfigInfo->lpszLanguage);
GdRpcFree( & pConfigInfo->lpszGeography);
} else {
//
// Success in copying the strings. Copy the dword data
//
pConfigInfo->fCheckForWaisDb = m_fCheckForWaisDb;
# if DBG
pConfigInfo->dwDebugFlags = g_GdDebugFlags;
# else
pConfigInfo->dwDebugFlags = 0;
# endif // DBG
}
// UnlockConfig();
return ( dwErr);
} // GSERVER_CONFIG::GetConfigInformation()
inline
DWORD
WriteConfigDword(
IN LPCTSTR lpszValueName,
IN DWORD dwNewValue)
/*++
Description:
Thin wrapper for WriteRegistryDword() to enable printing
a log message for errors if any.
Arguments:
lpszValueName name of the registry entry under reg key
to be modified.
dwNewValue new value for the entry
Returns:
Win32 error codes
--*/
{
DWORD err = WriteRegistryDword(
g_hkeyGdParams,
lpszValueName,
dwNewValue);
DEBUG_IF( RPC, {
if ( err != NO_ERROR) {
DBGPRINTF( ( DBG_CONTEXT,
" WriteRegistryDword() failed for %s( %d)\n",
lpszValueName,
dwNewValue));
}
});
return ( err);
} // WriteConfigDword()
DWORD
WriteConfigString(
IN LPCTSTR lpszValueName,
IN LPWSTR lpszNewValue,
IN DWORD fdwType)
/*++
Description:
Writes the new configuration ( string) value to registry name
given using the global registry handle ( g_hkeyGdParams)
A thin wrapper around WriteRegistryStringA() which
converts given string into ANSI and writes data to registry
on success.
If no new value is specified, do nothing and return NO_ERROR.
Arguments:
lpszValueName name of the registry entry to be modified.
lpszNewValue new value for given entry
fdwType type of registry entry
Returns:
Win32 error code. NO_ERROR on success.
--*/
{
DWORD err = NO_ERROR;
char * pszNewValueAnsi;
if ( lpszNewValue == NULL) {
//
// Ignore this field. Dont reset to any new value.
//
return ( NO_ERROR);
}
ASSERT( g_hkeyGdParams != NULL);
pszNewValueAnsi = ConvertUnicodeToAnsi( lpszNewValue, NULL);
if ( pszNewValueAnsi != NULL) {
err = WriteRegistryStringA(
g_hkeyGdParams,
lpszValueName,
pszNewValueAnsi,
strlen( pszNewValueAnsi) + 1,
REG_SZ);
TCP_FREE( pszNewValueAnsi); // free the new value
} else {
err = ERROR_NOT_ENOUGH_MEMORY;
}
DEBUG_IF( RPC, {
if ( err != NO_ERROR) {
DBGPRINTF( ( DBG_CONTEXT,
" WriteRegistryString() failed for %s( %S)\n",
lpszValueName, lpszNewValue));
}
});
return ( err);
} // WriteConfigString()
DWORD
GSERVER_CONFIG::SetConfigInformation(
IN LPGOPHERD_CONFIG_INFO pConfigInfo
)
/*++
Description:
Sets the configuration information for Gopher server.
Several of the configuration data will become
effective immediately.
The following parameters require a restart of the service, after
successfully setting their new values.
GDA_PORT_NUMBER
Arguments:
pConfigInfo
pointer to GOPHERD_CONFIG_INFO containing values for fields whose
value are to be changed.
Returns:
Win32 error code. NO_ERROR on success.
Note:
Error checking is limited to one at a time.
No undo is performed if an error is detected during the updations.
--*/
{
DWORD err = NO_ERROR;
DWORD FieldsToSet = pConfigInfo->FieldControl;
ASSERT( FieldsToSet != 0x0);
//
// The tradeoffs involved here are:
// 1) we need to update the registry before setting it in current config
// 2) multiple attributes being set ==> can lead to compound errors
// 3) We fail at first error
// 4) We dont do any cleanups if we fail half way thru
// 5) i.e. atomicity is not guaranteed.
// 6) Memory allocated is completely freed --> no memory leakages occur
// 7) For performance reasons we may not want to do
// bulk registry reads to reinitialize values.
// So we use the FieldControl to selectively read from registry
//
//
// Phase 1: Do writes of the new data to registry
//
//
// Write all string data to registry
//
if ( err == NO_ERROR && IsFieldSet( FieldsToSet, GDA_CHECK_FOR_WAISDB)) {
err = WriteConfigDword( GOPHERD_CHECK_FOR_WAISDB,
pConfigInfo->fCheckForWaisDb
);
}
if ( err == NO_ERROR && IsFieldSet( FieldsToSet, GDA_SITE)) {
err = WriteConfigString( GOPHERD_SITE,
pConfigInfo->lpszSite,
REG_SZ);
}
if ( err == NO_ERROR && IsFieldSet( FieldsToSet, GDA_ORGANIZATION)) {
err = WriteConfigString( GOPHERD_ORGANIZATION,
pConfigInfo->lpszOrganization,
REG_SZ);
}
if ( err == NO_ERROR && IsFieldSet( FieldsToSet, GDA_LOCATION)) {
err = WriteConfigString( GOPHERD_LOCATION,
pConfigInfo->lpszLocation,
REG_SZ);
}
if ( err == NO_ERROR && IsFieldSet( FieldsToSet, GDA_GEOGRAPHY)) {
err = WriteConfigString( GOPHERD_GEOGRAPHY,
pConfigInfo->lpszGeography,
REG_SZ);
}
if ( err == NO_ERROR && IsFieldSet( FieldsToSet, GDA_LANGUAGE)) {
err = WriteConfigString( GOPHERD_LANGUAGE,
pConfigInfo->lpszLanguage,
REG_SZ);
}
//
// Phase 2: Reinitialize the configuration information.
// By using the InitFromRegistry() member function
//
if ( err == NO_ERROR) {
DEBUG_IF( RPC, {
DBGPRINTF( ( DBG_CONTEXT,
"Successful writing to registry for Fields ( %08x)\n",
FieldsToSet));
});
err = InitFromRegistry( g_hkeyGdParams, FieldsToSet);
}
return ( err);
} // GSERVER_CONFIG::SetConfigInformation()
/************************ End of File ***********************/