mirror of https://github.com/tongzx/nt5src
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.
285 lines
8.1 KiB
285 lines
8.1 KiB
/*++
|
|
|
|
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
|