286 lines
8.1 KiB
C
286 lines
8.1 KiB
C
/*++
|
||
|
||
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
|