|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
ApiStats.c
Abstract:
This module contains individual API handlers for the NetStatistics APIs.
SUPPORTED : NetStatisticsGet2.
Author:
Shanku Niyogi (w-shanku) 04-Apr-1991
Revision History:
--*/
#define LM20_WORKSTATION_STATISTICS
#include "XactSrvP.h"
#include <ntddnfs.h>
#include <lmstats.h>
//
// Declaration of descriptor strings.
//
STATIC const LPDESC Desc16_stat_server_0 = REM16_stat_server_0; STATIC const LPDESC Desc32_stat_server_0 = REM32_stat_server_0; STATIC const LPDESC Desc16_stat_workstation_0 = REM16_stat_workstation_0; STATIC const LPDESC Desc32_stat_workstation_0 = REM32_stat_workstation_0;
NTSTATUS XsNetStatisticsGet2 ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetStatisticsGet.
Arguments:
API_HANDLER_PARAMETERS - information about the API call. See XsTypes.h for details.
Return Value:
NTSTATUS - STATUS_SUCCESS or reason for failure.
--*/
{ NET_API_STATUS status;
PXS_NET_STATISTICS_GET_2 parameters = Parameters; LPTSTR nativeService = NULL; // Native parameters
LPVOID outBuffer = NULL; LPVOID statBuffer = NULL;
LPBYTE stringLocation = NULL; // Conversion variables
DWORD bytesRequired = 0; DWORD options; LPDESC actualStructureDesc; LPDESC nativeStructureDesc; STAT_WORKSTATION_0 wkstaStats; PREDIR_STATISTICS ntRedirStats;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
IF_DEBUG(STATISTICS) { NetpKdPrint(( "XsNetStatisticsGet2: header at %lx, " "params at %lx, level %ld\n", Header, parameters, SmbGetUshort( ¶meters->Level ) )); }
try { //
// Translate parameters, check for errors.
//
if ( SmbGetUshort( ¶meters->Level ) != 0 || SmbGetUlong( ¶meters->Reserved ) != 0 ) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
//
// No options currently supported by both rdr and srv
//
if ( SmbGetUlong( ¶meters->Options ) != 0 ) { Header->Status = ERROR_NOT_SUPPORTED; goto cleanup; }
XsConvertTextParameter( nativeService, (LPSTR)XsSmbGetPointer( ¶meters->Service ) );
//
// Make the local call.
//
status = NetStatisticsGet( NULL, XS_MAP_SERVICE_NAME( nativeService ), (DWORD)SmbGetUshort( ¶meters->Level ), 0, // Options MBZ
(LPBYTE *)&outBuffer );
if ( !XsApiSuccess( status )) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetStatisticsGet2: NetStatisticsGet failed: " "%X\n", status )); } Header->Status = (WORD)status; goto cleanup;
}
//
// Use the name of the service to determine the format of the 32-bit
// structure we got back from NetStatisticsGet, and the format of what
// the resulting 16-bit structure should be. If the service name is not
// one supported in LM2.x, return ERROR_NOT_SUPPORTED now, as required.
//
if ( !_stricmp( (LPSTR)XsSmbGetPointer( ¶meters->Service ), "SERVER" )) {
statBuffer = outBuffer; nativeStructureDesc = Desc32_stat_server_0; actualStructureDesc = Desc16_stat_server_0;
} else if ( !_stricmp( (LPSTR)XsSmbGetPointer( ¶meters->Service ), "WORKSTATION" )) {
//
// The structure we got back is an nt structure. We need to convert
// it by hand here.
//
statBuffer = &wkstaStats; ntRedirStats = (PREDIR_STATISTICS)outBuffer; RtlZeroMemory( &wkstaStats, sizeof(STAT_WORKSTATION_0) );
(VOID)RtlTimeToSecondsSince1970( &ntRedirStats->StatisticsStartTime, &wkstaStats.stw0_start );
wkstaStats.stw0_sesstart = ntRedirStats->Sessions; wkstaStats.stw0_sessfailcon = ntRedirStats->FailedSessions; wkstaStats.stw0_sessbroke = ntRedirStats->ServerDisconnects + ntRedirStats->HungSessions; wkstaStats.stw0_uses = ntRedirStats->CoreConnects + ntRedirStats->Lanman20Connects + ntRedirStats->Lanman21Connects + ntRedirStats->LanmanNtConnects;
wkstaStats.stw0_usefail = ntRedirStats->FailedUseCount; wkstaStats.stw0_autorec = ntRedirStats->Reconnects;
wkstaStats.stw0_bytessent_r_hi = ntRedirStats->BytesTransmitted.HighPart; wkstaStats.stw0_bytessent_r_lo = ntRedirStats->BytesTransmitted.LowPart;
wkstaStats.stw0_bytesrcvd_r_hi = ntRedirStats->BytesReceived.HighPart; wkstaStats.stw0_bytesrcvd_r_lo = ntRedirStats->BytesReceived.LowPart;
nativeStructureDesc = Desc32_stat_workstation_0; actualStructureDesc = Desc16_stat_workstation_0;
} else {
Header->Status = ERROR_NOT_SUPPORTED; goto cleanup; }
//
// Convert the structure returned by the 32-bit call to a 16-bit
// structure. The last possible location for variable data is
// calculated from buffer location and length.
//
stringLocation = (LPBYTE)( XsSmbGetPointer( ¶meters->Buffer ) + SmbGetUshort( ¶meters->BufLen ) );
status = RapConvertSingleEntry( statBuffer, nativeStructureDesc, FALSE, (LPBYTE)XsSmbGetPointer( ¶meters->Buffer ), (LPBYTE)XsSmbGetPointer( ¶meters->Buffer ), actualStructureDesc, TRUE, &stringLocation, &bytesRequired, Response, NativeToRap );
if ( status != NERR_Success ) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetStatisticsGet2: RapConvertSingleEntry failed: " "%X\n", status )); }
Header->Status = NERR_InternalError; goto cleanup; }
IF_DEBUG(STATISTICS) { NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR\n", outBuffer, SmbGetUlong( ¶meters->Buffer ), bytesRequired )); }
//
// Determine return code based on the size of the buffer. Statistics
// structures don't have any variable data to pack.
//
if ( !XsCheckBufferSize( SmbGetUshort( ¶meters->BufLen ), actualStructureDesc, FALSE // not in native format
)) {
IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetStatisticsGet2: Buffer too small.\n" )); } Header->Status = NERR_BufTooSmall;
}
//
// Set up the response parameters.
//
SmbPutUshort( ¶meters->TotalAvail, (WORD)bytesRequired );
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
NetApiBufferFree( outBuffer ); NetpMemoryFree( nativeService );
//
// Determine return buffer size.
//
XsSetDataCount( ¶meters->BufLen, actualStructureDesc, Header->Converter, 1, Header->Status );
return STATUS_SUCCESS;
} // XsNetStatisticsGet2
|