mirror of https://github.com/lianthony/NT4.0
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.
1098 lines
27 KiB
1098 lines
27 KiB
// ********************************
|
|
//
|
|
// Copyright (c) 1990 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// tpctl.c
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This is the main component of the NDIS 3.0 MAC Tester control program.
|
|
//
|
|
// Author:
|
|
//
|
|
// Tom Adams (tomad) 2-Apr-1991
|
|
//
|
|
// Revision History:
|
|
//
|
|
// 2-Apr-1991 tomad
|
|
//
|
|
// created
|
|
//
|
|
// 7-1-1993 SanjeevK
|
|
//
|
|
// Added support for recording of sessions to a script file
|
|
// Added support for write through and error handling conditions
|
|
//
|
|
// 5-18-1994 timothyw
|
|
// added hooks for global variable access; cleanup
|
|
// 6-08-1994 timothyw
|
|
// changed to client/server model for perf tests
|
|
//
|
|
// *********************************
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h>
|
|
//#include <ndis.h>
|
|
#include <ntddndis.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "tpctl.h"
|
|
#include "parse.h"
|
|
|
|
BOOL Verbose = TRUE;
|
|
|
|
BOOL CommandsFromScript = FALSE;
|
|
|
|
BOOL CommandLineLogging = FALSE;
|
|
|
|
BOOL RecordToScript = FALSE;
|
|
|
|
HANDLE CommandLineLogHandle;
|
|
|
|
HANDLE ScriptRecordHandle;
|
|
|
|
BOOL ExitFlag = FALSE;
|
|
|
|
SCRIPTCONTROL Scripts[TPCTL_MAX_SCRIPT_LEVELS+1];
|
|
|
|
DWORD ScriptIndex;
|
|
|
|
CHAR RecordScriptName[TPCTL_MAX_PATHNAME_SIZE];
|
|
|
|
OPEN_BLOCK Open[NUM_OPEN_INSTANCES];
|
|
|
|
CMD_ARGS GlobalCmdArgs;
|
|
|
|
LPSTR GlobalBuf = NULL;
|
|
|
|
BOOL ContinueLooping = TRUE;
|
|
|
|
BOOL WriteThrough = TRUE;
|
|
|
|
BOOL ContinueOnError = FALSE;
|
|
|
|
INT TpctlSeed = 0;
|
|
|
|
//
|
|
// the MAIN routine
|
|
//
|
|
|
|
|
|
VOID _cdecl
|
|
main(
|
|
IN WORD argc,
|
|
IN LPSTR argv[]
|
|
)
|
|
|
|
// ---------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine initializes the TPCTL control structures, opens the
|
|
// TPDRVR driver, and send it a wakeup ioctl. Once this has completed
|
|
// the user is presented with the test prompt to enter commands,
|
|
// or if a script file was entered at the command line, it is opened,
|
|
// and the commands are read from the file.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// IN WORD argc - Supplies the number of parameters
|
|
// IN LPSTR argv[] - Supplies the parameter list.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
// ----------
|
|
|
|
{
|
|
HANDLE TpdrvrHandle;
|
|
DWORD Status;
|
|
|
|
|
|
//
|
|
// Adding this for version control recognition
|
|
//
|
|
printf( "\nMAC NDIS 3.0 Tester - Test Control Tool Version 1.5.3\n\n" );
|
|
|
|
|
|
//
|
|
// First we will disable Ctrl-C by installing a handler.
|
|
//
|
|
|
|
if ( !SetConsoleCtrlHandler( TpctlCtrlCHandler,TRUE ))
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog("\n\tTpctl: failed to install Ctrl-C handler, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
ExitProcess(Status);
|
|
}
|
|
|
|
//
|
|
// Initialize the Scripts control structure before we check to
|
|
// see if there are any scripts on the command line to be read.
|
|
//
|
|
|
|
TpctlInitializeScripts();
|
|
|
|
//
|
|
// Initialize the script-accessible global variables
|
|
//
|
|
|
|
TpctlInitGlobalVariables();
|
|
|
|
//
|
|
// Check the command line parameters, and if there is a script file
|
|
// and log file open each.
|
|
//
|
|
|
|
Status = TpctlParseCommandLine( argc,argv );
|
|
|
|
if ( Status != NO_ERROR )
|
|
{
|
|
ExitProcess((DWORD)Status);
|
|
}
|
|
|
|
//
|
|
// Initialize the Open Block Structure and Environment Variables.
|
|
//
|
|
|
|
Status = TpctlInitializeOpenArray();
|
|
|
|
if ( Status != NO_ERROR )
|
|
{
|
|
TpctlFreeOpenArray();
|
|
TpctlCloseScripts();
|
|
ExitProcess((DWORD)Status);
|
|
}
|
|
|
|
//
|
|
// Open the first instance of the Test Protocol driver.
|
|
//
|
|
|
|
Status = TpctlOpenTpdrvr( &TpdrvrHandle );
|
|
|
|
if ( Status != NO_ERROR )
|
|
{
|
|
TpctlFreeOpenArray();
|
|
TpctlCloseScripts();
|
|
ExitProcess((DWORD)Status);
|
|
}
|
|
|
|
//
|
|
// Start the actual tests, TpctlRunTest prompts for the commands or
|
|
// reads the script files and then drives the tests.
|
|
//
|
|
|
|
Status = TpctlRunTest( TpdrvrHandle );
|
|
|
|
if ( Status != NO_ERROR )
|
|
{
|
|
TpctlCloseTpdrvr( TpdrvrHandle );
|
|
TpctlFreeOpenArray();
|
|
TpctlCloseScripts();
|
|
ExitProcess((DWORD)Status);
|
|
}
|
|
|
|
//
|
|
// Close the Test Protocol driver, and free the Open Array data structs.
|
|
//
|
|
|
|
TpctlCloseTpdrvr( TpdrvrHandle );
|
|
|
|
TpctlFreeOpenArray();
|
|
|
|
TpctlCloseScripts();
|
|
|
|
if ( !SetConsoleCtrlHandler( TpctlCtrlCHandler,FALSE ))
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog("\n\tTpctl: failed to remove Ctrl-C handler, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
ExitProcess(Status);
|
|
}
|
|
|
|
ExitProcess((DWORD)NO_ERROR);
|
|
}
|
|
|
|
|
|
DWORD
|
|
TpctlInitializeOpenArray(
|
|
VOID
|
|
)
|
|
|
|
// ----------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ---------------
|
|
|
|
{
|
|
DWORD Status;
|
|
DWORD i;
|
|
|
|
ZeroMemory( Open,NUM_OPEN_INSTANCES * sizeof( OPEN_BLOCK ));
|
|
|
|
for ( i=0;i<NUM_OPEN_INSTANCES;i++ )
|
|
{
|
|
Open[i].Signature = OPEN_BLOCK_SIGNATURE;
|
|
Open[i].OpenInstance = 0xFF;
|
|
Open[i].AdapterOpened = FALSE;
|
|
|
|
Open[i].MediumType = 0;
|
|
Open[i].NdisVersion = 0;
|
|
|
|
Open[i].AdapterName = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
|
|
MAX_ADAPTER_NAME_LENGTH );
|
|
|
|
if ( Open[i].AdapterName == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Adapter Name, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Open[i].AdapterName[0] = '\0';
|
|
Open[i].LookaheadSize = 0;
|
|
Open[i].PacketFilter = NDIS_PACKET_TYPE_NONE;
|
|
Open[i].MulticastAddresses = NULL;
|
|
Open[i].NumberMultAddrs = 0;
|
|
|
|
Open[i].EnvVars = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
|
|
sizeof( ENVIRONMENT_VARIABLES ) );
|
|
|
|
if ( Open[i].EnvVars == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc EnvVars structure, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Open[i].EnvVars->WindowSize = WINDOW_SIZE;
|
|
Open[i].EnvVars->RandomBufferNumber = BUFFER_NUMBER;
|
|
Open[i].EnvVars->StressDelayInterval = DELAY_INTERVAL;
|
|
Open[i].EnvVars->UpForAirDelay = UP_FOR_AIR_DELAY;
|
|
Open[i].EnvVars->StandardDelay = STANDARD_DELAY;
|
|
|
|
strcpy( Open[i].EnvVars->StressAddress,STRESS_MULTICAST );
|
|
strcpy( Open[i].EnvVars->ResendAddress,NULL_ADDRESS );
|
|
|
|
Open[i].EventThreadStarted = FALSE;
|
|
Open[i].Events[TPCONTROL] = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
Open[i].Events[TPSTRESS] = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
Open[i].Events[TPSEND] = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
Open[i].Events[TPRECEIVE] = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
Open[i].Events[TPPERF] = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
|
|
Open[i].Stressing = FALSE;
|
|
Open[i].StressEvent = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
Open[i].StressResultsCompleted = FALSE;
|
|
Open[i].StressClient = FALSE;
|
|
|
|
Open[i].StressResults = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
|
|
sizeof( STRESS_RESULTS ) );
|
|
|
|
if ( Open[i].StressResults == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Stress Results structure, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Open[i].StressArgs = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
|
|
sizeof( CMD_ARGS ) );
|
|
|
|
if ( Open[i].StressArgs == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Stress Args structure, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Open[i].Sending = FALSE;
|
|
Open[i].SendEvent = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
Open[i].SendResultsCompleted = FALSE;
|
|
|
|
Open[i].SendResults = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
|
|
sizeof( SEND_RECEIVE_RESULTS ) );
|
|
|
|
if ( Open[i].SendResults == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Send Results structure, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Open[i].SendArgs = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
|
|
sizeof( CMD_ARGS ) );
|
|
|
|
if ( Open[i].SendArgs == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Send Args structure, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Open[i].Receiving = FALSE;
|
|
Open[i].ReceiveEvent = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
Open[i].ReceiveResultsCompleted = FALSE;
|
|
|
|
Open[i].ReceiveResults = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
|
|
sizeof( SEND_RECEIVE_RESULTS ) );
|
|
|
|
if ( Open[i].ReceiveResults == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Receive Results structure, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Open[i].PerfEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
|
|
Open[i].PerfResultsCompleted = FALSE;
|
|
Open[i].PerfResults = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
|
|
sizeof (PERF_RESULTS) );
|
|
|
|
if ( Open[i].PerfResults == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Perf Results structure, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
Status = TpctlStartEventHandlerThread( &Open[i] );
|
|
|
|
if ( Status != NO_ERROR )
|
|
{
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to start EventHandler thread, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
else
|
|
{
|
|
Open[i].EventThreadStarted = TRUE;
|
|
}
|
|
}
|
|
|
|
GlobalBuf = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
|
|
0x1000 + ( MAX_SERVERS * 0x400 ) );
|
|
|
|
if ( GlobalBuf == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog(
|
|
"\n\tTpctlInitializeOpenArray: failed to alloc Global Statistics buffer, returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
return Status;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
TpctlResetOpenState(
|
|
IN POPEN_BLOCK Open,
|
|
IN HANDLE FileHandle
|
|
)
|
|
|
|
// -------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine reset the state of an open to its initial state.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// IN POPEN_BLOCK Open - the open block to reset to it initial state.
|
|
// IN HANDLE FileHandle - the handle to the driver to close the open
|
|
// iff already opened.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// DWORD - NO_ERROR if the adapter was closed successfully or was never
|
|
// opened. Otherwise, the result of the close if it fails.
|
|
//
|
|
// -----------
|
|
|
|
{
|
|
DWORD Status = NO_ERROR;
|
|
PMULT_ADDR MultAddr = NULL;
|
|
PMULT_ADDR NextMultAddr = NULL;
|
|
|
|
//
|
|
// If the adapter is closed attempt to close it, and then
|
|
// set the opened flag to FALSE.
|
|
//
|
|
|
|
if ( Open->AdapterOpened == TRUE )
|
|
{
|
|
HANDLE Event;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
PBYTE InputBuffer[0x100];
|
|
DWORD InputBufferSize = 0x100;
|
|
PBYTE OutputBuffer[0x100];
|
|
DWORD OutputBufferSize = 0x100;
|
|
PCMD_ARGS CmdArgs;
|
|
|
|
Event = CreateEvent( NULL,FALSE,FALSE,NULL );
|
|
|
|
if (Event == NULL)
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog("\n\tCreateEvent failed: returned 0x%lx.\n",(PVOID)Status);
|
|
}
|
|
|
|
CmdArgs = (PCMD_ARGS)InputBuffer;
|
|
|
|
CmdArgs->CmdCode = CLOSE;
|
|
CmdArgs->OpenInstance = Open->OpenInstance + 1;
|
|
|
|
// !!NOT WIN32!!
|
|
|
|
Status = NtDeviceIoControlFile( FileHandle,
|
|
Event,
|
|
NULL, // ApcRoutine
|
|
NULL, // ApcContext
|
|
&IoStatusBlock,
|
|
TP_CONTROL_CODE( CLOSE,IOCTL_METHOD ),
|
|
InputBuffer,
|
|
InputBufferSize,
|
|
OutputBuffer,
|
|
OutputBufferSize );
|
|
|
|
if (( Status != STATUS_SUCCESS ) && ( Status != STATUS_PENDING ))
|
|
{
|
|
TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
ExitFlag = TRUE;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (( Status == STATUS_PENDING ) && ( Event != NULL ))
|
|
{
|
|
//
|
|
// If the ioctl pended, then wait for it to complete.
|
|
//
|
|
|
|
Status = WaitForSingleObject( Event,60000 ); // ONE_MINUTE
|
|
|
|
if ( Status == WAIT_TIMEOUT )
|
|
{
|
|
//
|
|
// The wait timed out, this probable means there
|
|
// was a failure in the MAC not completing the
|
|
// close.
|
|
//
|
|
|
|
TpctlErrorLog(
|
|
"\n\tTpctl: WARNING - WaitForSingleObject unexpectedly timed out.\n",NULL);
|
|
TpctlErrorLog(
|
|
"\t IRP was never completed in protocol driver.\n",NULL);
|
|
}
|
|
else if ( Status != NO_ERROR )
|
|
{
|
|
//
|
|
// If the wait for single object failed, then exit
|
|
// the test app with the error.
|
|
//
|
|
|
|
TpctlErrorLog(
|
|
"\n\tTpctl: ERROR - WaitForSingleObject failed: returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
ExitFlag = TRUE;
|
|
}
|
|
else if ( IoStatusBlock.Status != STATUS_SUCCESS )
|
|
{
|
|
//
|
|
// else if the pending ioctl returned failure again
|
|
// exit the test app with the error.
|
|
//
|
|
|
|
TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile pended.\n",NULL);
|
|
TpctlErrorLog("\n\t NtDeviceIoControlFile failed: returned 0x%lx.\n",
|
|
(PVOID)IoStatusBlock.Status);
|
|
ExitFlag = TRUE;
|
|
Status = IoStatusBlock.Status;
|
|
}
|
|
}
|
|
}
|
|
|
|
Open->AdapterOpened = FALSE;
|
|
}
|
|
|
|
//
|
|
// Then reset the various card and test specific flags to their
|
|
// original state.
|
|
//
|
|
|
|
Open->OpenInstance = 0xFF;
|
|
Open->MediumType = 0;
|
|
Open->NdisVersion = 0;
|
|
|
|
Open->AdapterName = NULL;
|
|
Open->LookaheadSize = 0;
|
|
Open->PacketFilter = NDIS_PACKET_TYPE_NONE;
|
|
Open->MulticastAddresses = NULL;
|
|
Open->NumberMultAddrs = 0;
|
|
|
|
// Environment variables.
|
|
|
|
Open->EnvVars->WindowSize = WINDOW_SIZE;
|
|
Open->EnvVars->RandomBufferNumber = BUFFER_NUMBER;
|
|
Open->EnvVars->StressDelayInterval = DELAY_INTERVAL;
|
|
Open->EnvVars->UpForAirDelay = UP_FOR_AIR_DELAY;
|
|
Open->EnvVars->StandardDelay = STANDARD_DELAY;
|
|
|
|
strcpy( Open->EnvVars->StressAddress,STRESS_MULTICAST );
|
|
strcpy( Open->EnvVars->ResendAddress,NULL_ADDRESS );
|
|
|
|
// Stress test flags.
|
|
|
|
Open->Stressing = FALSE;
|
|
Open->StressResultsCompleted = FALSE;
|
|
Open->StressClient = FALSE;
|
|
|
|
// Send test flags.
|
|
|
|
Open->Sending = FALSE;
|
|
Open->SendResultsCompleted = FALSE;
|
|
|
|
// Receive test flags.
|
|
|
|
Open->Receiving = FALSE;
|
|
Open->ReceiveResultsCompleted = FALSE;
|
|
|
|
// performance test flags
|
|
|
|
Open->PerfResultsCompleted = FALSE;
|
|
|
|
// Card state variables and structures.
|
|
|
|
MultAddr = Open->MulticastAddresses;
|
|
|
|
while ( MultAddr != NULL )
|
|
{
|
|
NextMultAddr = MultAddr->Next;
|
|
GlobalFree( MultAddr );
|
|
MultAddr = NextMultAddr;
|
|
}
|
|
|
|
Open->MulticastAddresses = NULL;
|
|
Open->NumberMultAddrs = 0;
|
|
|
|
ZeroMemory(Open->FunctionalAddress, FUNCTIONAL_ADDRESS_LENGTH);
|
|
ZeroMemory(Open->GroupAddress, FUNCTIONAL_ADDRESS_LENGTH);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TpctlFreeOpenArray(
|
|
VOID
|
|
)
|
|
|
|
// -------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ---------------
|
|
|
|
{
|
|
DWORD i;
|
|
|
|
for ( i=0;i<NUM_OPEN_INSTANCES;i++ )
|
|
{
|
|
//
|
|
// First free up all of the allocated data structs,
|
|
//
|
|
|
|
if ( Open[i].AdapterName != NULL )
|
|
{
|
|
GlobalFree( Open[i].AdapterName );
|
|
}
|
|
|
|
if ( Open[i].EnvVars != NULL )
|
|
{
|
|
GlobalFree( Open[i].EnvVars );
|
|
}
|
|
|
|
if ( Open[i].StressResults != NULL )
|
|
{
|
|
GlobalFree( Open[i].StressResults );
|
|
}
|
|
|
|
if ( Open[i].StressArgs != NULL )
|
|
{
|
|
GlobalFree( Open[i].StressArgs );
|
|
}
|
|
|
|
if ( Open[i].SendResults != NULL )
|
|
{
|
|
GlobalFree( Open[i].SendResults );
|
|
}
|
|
|
|
if ( Open[i].StressArgs != NULL )
|
|
{
|
|
GlobalFree( Open[i].SendArgs );
|
|
}
|
|
|
|
if ( Open[i].ReceiveResults != NULL )
|
|
{
|
|
GlobalFree( Open[i].ReceiveResults );
|
|
}
|
|
|
|
if ( Open[i].PerfResults != NULL )
|
|
{
|
|
GlobalFree( Open[i].PerfResults );
|
|
}
|
|
|
|
//
|
|
// Then stop the EventHandler thread,
|
|
//
|
|
|
|
TpctlStopEventHandlerThread( &Open[i] );
|
|
|
|
//
|
|
// And finally close all of the event handles.
|
|
//
|
|
|
|
if ( Open[i].Events[TPCONTROL] != NULL )
|
|
{
|
|
CloseHandle( Open[i].Events[TPCONTROL] );
|
|
}
|
|
|
|
if ( Open[i].Events[TPCONTROL] != NULL )
|
|
{
|
|
CloseHandle( Open[i].Events[TPSTRESS] );
|
|
}
|
|
|
|
if ( Open[i].Events[TPSEND] != NULL )
|
|
{
|
|
CloseHandle( Open[i].Events[TPSEND] );
|
|
}
|
|
|
|
if ( Open[i].Events[TPRECEIVE] != NULL )
|
|
{
|
|
CloseHandle( Open[i].Events[TPRECEIVE] );
|
|
}
|
|
|
|
if ( Open[i].Events[TPPERF] != NULL )
|
|
{
|
|
CloseHandle( Open[i].Events[TPPERF] );
|
|
}
|
|
|
|
if ( Open[i].StressEvent != NULL )
|
|
{
|
|
CloseHandle( Open[i].StressEvent );
|
|
}
|
|
|
|
if ( Open[i].SendEvent != NULL )
|
|
{
|
|
CloseHandle( Open[i].SendEvent );
|
|
}
|
|
|
|
if ( Open[i].ReceiveEvent != NULL )
|
|
{
|
|
CloseHandle( Open[i].ReceiveEvent );
|
|
}
|
|
|
|
if ( Open[i].PerfEvent != NULL )
|
|
{
|
|
CloseHandle( Open[i].PerfEvent );
|
|
}
|
|
}
|
|
|
|
GlobalFree( GlobalBuf );
|
|
}
|
|
|
|
|
|
DWORD
|
|
TpctlOpenTpdrvr(
|
|
IN OUT PHANDLE lphFileHandle
|
|
)
|
|
|
|
// -------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine calls CreateFile to open the TPDRVR.SYS device driver.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// lphFileHandle - the file handle of the file to be opened.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// lphFileHandle contains a positive value if successful, -1 if not.
|
|
//
|
|
// -------------
|
|
|
|
{
|
|
DWORD Status = NO_ERROR;
|
|
|
|
*lphFileHandle = CreateFile(DEVICE_NAME,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, // lpSecurityAttirbutes
|
|
CREATE_NEW,
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
NULL); // lpTemplateFile
|
|
|
|
if ( *lphFileHandle == (HANDLE)-1 )
|
|
{
|
|
Status = GetLastError();
|
|
if ( Status == STATUS_DEVICE_ALREADY_ATTACHED )
|
|
{
|
|
TpctlErrorLog("\n\tTpctl: Tpdrvr.sys already opened by another instance of\n",NULL);
|
|
TpctlErrorLog("\t the control application. Only one open allowed.\n",NULL);
|
|
}
|
|
else
|
|
{
|
|
TpctlErrorLog("\n\tTpctlOpenTpdrvr: CreateFile failed: returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TpctlCloseTpdrvr(
|
|
IN HANDLE hFileHandle
|
|
)
|
|
|
|
// ----------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine calls CloseHandle to close the first instance of the
|
|
// TPDRVR.EXE driver.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// hFileHandle - the file handle returned from the call to OpenFile.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// STATUS - the status of the CloseHandle call.
|
|
//
|
|
// -----------------
|
|
|
|
{
|
|
DWORD Status;
|
|
|
|
if ( !CloseHandle( hFileHandle ))
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog("\n\tTpctlCloseTpdrvr: CloseHandle failed: returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
TpctlStartEventHandlerThread(
|
|
POPEN_BLOCK Open
|
|
)
|
|
|
|
// -----------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
// --------------
|
|
|
|
{
|
|
DWORD Status = NO_ERROR;
|
|
DWORD StackSize = 0x1000;
|
|
DWORD ThreadId;
|
|
HANDLE EventThread;
|
|
|
|
|
|
EventThread = CreateThread( NULL,
|
|
StackSize,
|
|
TpctlEventHandler,
|
|
(LPVOID)Open,
|
|
0,
|
|
&ThreadId );
|
|
|
|
if ( EventThread == NULL )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog("TpctlStartEventHandlerThread: CreateThread failed; returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// the CreateT succeeded, we don't need the handle so close it.
|
|
//
|
|
|
|
if ( !CloseHandle( EventThread ) )
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog("\n\tTpctlStartEventHandlerThread: CloseHandle failed; returned 0x%lx\n",
|
|
(PVOID)Status);
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
TpctlEventHandler(
|
|
LPVOID Open
|
|
)
|
|
|
|
// --------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ----------
|
|
|
|
{
|
|
BOOL Continue = TRUE;
|
|
DWORD EventNumber;
|
|
DWORD Status;
|
|
|
|
while ( Continue == TRUE )
|
|
{
|
|
EventNumber = WaitForMultipleObjects( 5,
|
|
(LPHANDLE)((POPEN_BLOCK)Open)->Events,
|
|
FALSE,
|
|
INFINITE );
|
|
|
|
switch ( EventNumber )
|
|
{
|
|
case TPCONTROL: // ResetWaitEvent;
|
|
Continue = FALSE;
|
|
break;
|
|
|
|
case TPSTRESS: // StressEvent
|
|
//
|
|
// Set the Stressing flag to false to indicate that we have
|
|
// finished the STRESS test, and the ResultsCompleted flag to
|
|
// true to indicate that the results are ready to be displayed.
|
|
//
|
|
|
|
((POPEN_BLOCK)Open)->Stressing = FALSE;
|
|
|
|
if (((POPEN_BLOCK)Open)->StressClient == TRUE )
|
|
{
|
|
((POPEN_BLOCK)Open)->StressResultsCompleted = TRUE;
|
|
}
|
|
|
|
//
|
|
// And then signal the app that we have finished.
|
|
//
|
|
|
|
if (!SetEvent(((POPEN_BLOCK)Open)->StressEvent))
|
|
{
|
|
Status = GetLastError();
|
|
OutputDebugString("TpctlEventHandler: failed to signal Stress Event 0x%lx.\n");
|
|
}
|
|
break;
|
|
|
|
case TPSEND: // SendEvent
|
|
//
|
|
// Set the Sending flag to false to indicate that we have
|
|
// finished the SEND test, and the ResultsCompleted flag to
|
|
// true to indicate that the results are ready to be displayed.
|
|
//
|
|
|
|
((POPEN_BLOCK)Open)->Sending = FALSE;
|
|
((POPEN_BLOCK)Open)->SendResultsCompleted = TRUE;
|
|
|
|
//
|
|
// And then signal the app that we have finished.
|
|
//
|
|
|
|
if (!SetEvent( ((POPEN_BLOCK)Open)->SendEvent ))
|
|
{
|
|
Status = GetLastError();
|
|
OutputDebugString("TpctlEventHandler: failed to signal Send Event 0x%lx.\n");
|
|
}
|
|
break;
|
|
|
|
case TPRECEIVE: // ReceiveEvent
|
|
//
|
|
// Set the Receiving flag to false to indicate that we have
|
|
// finished the RECEIVE test, and the ResultsCompleted flag to
|
|
// true to indicate that the results are ready to be displayed.
|
|
//
|
|
|
|
((POPEN_BLOCK)Open)->Receiving = FALSE;
|
|
((POPEN_BLOCK)Open)->ReceiveResultsCompleted = TRUE;
|
|
|
|
//
|
|
// And then signal the app that we have finished.
|
|
//
|
|
|
|
if (!SetEvent( ((POPEN_BLOCK)Open)->ReceiveEvent ))
|
|
{
|
|
Status = GetLastError();
|
|
OutputDebugString("TpctlEventHandler: failed to signal Receive Event.\n");
|
|
}
|
|
break;
|
|
|
|
case TPPERF: // PerfEvent
|
|
//
|
|
// Set the PerfResultsCompleted flag to
|
|
// true to indicate that the results are ready to be displayed.
|
|
//
|
|
|
|
((POPEN_BLOCK)Open)->PerfResultsCompleted = TRUE;
|
|
|
|
//
|
|
// And then signal the app that we have finished.
|
|
//
|
|
|
|
if (!SetEvent( ((POPEN_BLOCK)Open)->PerfEvent ))
|
|
{
|
|
Status = GetLastError();
|
|
OutputDebugString("TpctlEventHandler: failed to signal Perf Event.\n");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return EventNumber;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TpctlStopEventHandlerThread(
|
|
POPEN_BLOCK Open
|
|
)
|
|
|
|
// ----------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ----------------
|
|
|
|
{
|
|
DWORD Status;
|
|
|
|
//
|
|
// First signal the thread to stop the Wait call.
|
|
//
|
|
|
|
if ( Open->EventThreadStarted == TRUE )
|
|
{
|
|
if ( !SetEvent( Open->Events[TPCONTROL] ))
|
|
{
|
|
Status = GetLastError();
|
|
TpctlErrorLog("\n\tTpctlStopEventHandlerThread: SetEvent failed; returned 0x%lx.\n",
|
|
(PVOID)Status);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
TpctlCtrlCHandler(
|
|
IN DWORD CtrlType
|
|
)
|
|
|
|
// --------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine catches any instances of Ctrl-C and sets the
|
|
// ContinueLooping flag to FALSE. WaitStress, WaitSend, GetEvents,
|
|
// Pause and Go, and parsing of script file commands will halt
|
|
// when this flag is set to true.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// DWORD CtrlType - the event passed in by the system.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// BOOL - TRUE if this event should be ignored by the system, FALSE
|
|
// otherwise.
|
|
//
|
|
// --------------
|
|
|
|
|
|
{
|
|
if ( CtrlType == CTRL_BREAK_EVENT )
|
|
{
|
|
return FALSE;
|
|
}
|
|
else if ( CtrlType == CTRL_C_EVENT )
|
|
{
|
|
if ( ContinueLooping == TRUE )
|
|
{
|
|
ContinueLooping = FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|