From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/ndis/testprot/tpctl/cmd.c | 4160 ++++++++++++++++++++++++++++ private/ntos/ndis/testprot/tpctl/cpuperf.c | 307 ++ private/ntos/ndis/testprot/tpctl/globals.c | 390 +++ private/ntos/ndis/testprot/tpctl/info.c | 1497 ++++++++++ private/ntos/ndis/testprot/tpctl/init.c | 1098 ++++++++ private/ntos/ndis/testprot/tpctl/makefile | 6 + private/ntos/ndis/testprot/tpctl/parse.c | 2526 +++++++++++++++++ private/ntos/ndis/testprot/tpctl/parse.h | 312 +++ private/ntos/ndis/testprot/tpctl/results.c | 1312 +++++++++ private/ntos/ndis/testprot/tpctl/sources | 49 + private/ntos/ndis/testprot/tpctl/tp_ndis.h | 180 ++ private/ntos/ndis/testprot/tpctl/tpctl.c | 3852 ++++++++++++++++++++++++++ private/ntos/ndis/testprot/tpctl/tpctl.h | 751 +++++ 13 files changed, 16440 insertions(+) create mode 100644 private/ntos/ndis/testprot/tpctl/cmd.c create mode 100644 private/ntos/ndis/testprot/tpctl/cpuperf.c create mode 100644 private/ntos/ndis/testprot/tpctl/globals.c create mode 100644 private/ntos/ndis/testprot/tpctl/info.c create mode 100644 private/ntos/ndis/testprot/tpctl/init.c create mode 100644 private/ntos/ndis/testprot/tpctl/makefile create mode 100644 private/ntos/ndis/testprot/tpctl/parse.c create mode 100644 private/ntos/ndis/testprot/tpctl/parse.h create mode 100644 private/ntos/ndis/testprot/tpctl/results.c create mode 100644 private/ntos/ndis/testprot/tpctl/sources create mode 100644 private/ntos/ndis/testprot/tpctl/tp_ndis.h create mode 100644 private/ntos/ndis/testprot/tpctl/tpctl.c create mode 100644 private/ntos/ndis/testprot/tpctl/tpctl.h (limited to 'private/ntos/ndis/testprot/tpctl') diff --git a/private/ntos/ndis/testprot/tpctl/cmd.c b/private/ntos/ndis/testprot/tpctl/cmd.c new file mode 100644 index 000000000..ec5ca1465 --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/cmd.c @@ -0,0 +1,4160 @@ +// -------------------------------------------------------------------- +// +// Copyright (c) 1991 Microsoft Corporation +// +// Module Name: +// +// cmd.c +// +// Abstract: +// +// +// +// Author: +// +// Tom Adams (tomad) 11-May-1991 +// +// Revision History: +// +// 11-May-1991 tomad +// +// Created +// +// +// Sanjeev Katariya (sanjeevk) 4-6-1993 +// Bug# 5203: The routine TpctlCopyAdapterAddress() needed modification to support +// the offset introduced by the Media type being returned on an Adapter Open. +// This was done in order to be able to correctly set the OID based on the +// medium +// +// Added support for commands DISABLE, ENABLE, SHELL, RECORDINGENABLE, RECORDINGDISABLE, +// Tpctl Options w,c and ?, fixed multicast address accounting +// +// Tim Wynsma (timothyw) 4-27-94 +// Added performance testing +// 5-18-94 +// Added setglobal command; cleanup +// 6-08-94 +// Chgd perf test to client/server model +// +// --------------------------------------------------------------------- + +#include +#include +#include + +#include + +#include +#include +#include + +#include "tpctl.h" +#include "parse.h" + + +extern CMD_CODE CommandCode[] = { + + { CMD_ERR, "Unknown", "U" }, + { VERBOSE, "Verbose", "V" }, + { SETENV, "SetEnvironment", "SE" }, + { READSCRIPT, "ReadScript", "RS" }, + { BEGINLOGGING, "BeginLogging", "BL" }, + { ENDLOGGING, "EndLogging", "EL" }, + { WAIT, "Wait", "W" }, + { GO, "Go", "G" }, + { PAUSE, "Pause", "P" }, + { LOAD, "Load", "L" }, + { UNLOAD, "Unload", "U" }, + { OPEN, "Open", "O" }, + { CLOSE, "Close", "C" }, + { SETPF, "SetPacketFilter", "SP" }, + { SETLA, "SetLookAheadSize", "LA" }, + { ADDMA, "AddMulticastAddress", "AM" }, + { DELMA, "DeleteMulticastAddress", "DM" }, + { SETFA, "SetFunctionalAddress", "SF" }, + { SETGA, "SetGroupAddress", "SG" }, + { QUERYINFO, "QueryInformation", "QI" }, + { QUERYSTATS, "QueryStatistics", "QS" }, + { SETINFO, "SetInformation", "SI" }, + { RESET, "Reset", "R" }, + { SEND, "Send", "S" }, + { STOPSEND, "StopSend", "SS" }, + { WAITSEND, "WaitSend", "WT" }, + { RECEIVE, "Receive", "RC" }, + { STOPREC, "StopReceive", "SR" }, + { GETEVENTS, "GetEvents", "GE" }, + { STRESS, "Stress", "ST" }, + { STRESSSERVER, "StressServer", "SV" }, + { ENDSTRESS, "EndStress", "ES" }, + { WAITSTRESS, "WaitStress", "WS" }, + { CHECKSTRESS, "CheckStress", "CS" }, + { BREAKPOINT, "BreakPoint", "BP" }, + { QUIT, "Quit", "Q" }, + { HELP, "Help", "H" }, + { SHELL, "Shell", "SH" }, + { RECORDINGENABLE, "RecordingEnable", "RE" }, + { RECORDINGDISABLE,"RecordingDisable", "RD" }, + { DISABLE, "Disable", "DI" }, + { ENABLE, "Enable", "EN" }, + { REGISTRY, "Registry", "RG" }, + { PERFSERVER, "PerformServer", "PS" }, + { PERFCLIENT, "PerformClient", "PC" }, + { SETGLOBAL, "SetGlobalVar", "SET"} +}; + + +extern BOOL WriteThrough; +extern BOOL ContinueOnError; + + +DWORD +TpctlParseCommandLine( + IN WORD argc, + IN LPSTR argv[] + ) + +// ----------------- +// +// Routine Description: +// +// This routine parses the command line arguments. If there is a +// script file and or log file they are loaded, and will be read from +// when that test actually starts. If there is an adapter to be loaded +// it is written to the global var AdapterName and will be loaded +// by a later routine. +// +// Arguments: +// +// argc - the number of arguments passed in at startup. +// +// argv - the argument vector containing the arguments passed in +// from the command line. +// +// Return Value: +// +// DWORD - NO_ERROR if all the arguments are valid, and the +// script and log file are opened and loaded correctly. +// ERROR_INVALID_PARAMETER otherwise. +// +// -------------------- + +{ + DWORD Status; + CHAR *TmpArgv[4]; + CHAR *TmpOptions = "/N"; + INT i; + + // + // Parameter validations + // + if ( ( argc < 1 ) || ( argc > 4 ) ) + { + TpctlErrorLog("\n\tTpctl: Invalid Command Line Argument(s).\n",NULL); + TpctlUsage(); + return ERROR_INVALID_PARAMETER; + } + + // + // Read the command line arguments into the global command buffer. + // We are going to temporarily "fake" that we are reading commands + // from a script so the parse agruments routine will not prompt + // the user for any additional info if all the arguments are not + // given. This will be disabled immediately following the call. + // + + ScriptIndex++; + + // + // This is very specific to this routine. The current method of parsing + // does not lead itself well to optionals + // + TmpArgv[0] = TmpArgv[1] = TmpArgv[2] = TmpArgv[3] = NULL; + for( i = 0; i < argc; i++ ) + { + TmpArgv[i] = argv[i]; + } + + if ( ( argc >= 2 ) && ( argv[1][0] != '/' ) ) + { + if ( argc == 4 ) + { + TpctlErrorLog("\n\tTpctl: Invalid Command Line Argument(s).\n",NULL); + TpctlUsage(); + return ERROR_INVALID_PARAMETER; + } + + // + // We now shift things around. At this point we now that argc must be three + // + argc++; + TmpArgv[1] = TmpOptions; + TmpArgv[2] = argv[1]; + TmpArgv[3] = argv[2]; + + } + else + { + if ( (argc >=2 ) && (argv[1][0] == '/') && + (strlen( argv[1] ) > (TPCTL_OPTION_SIZE-1)) ) + { + TpctlErrorLog("\n\tTpctl: Invalid Command Line Argument(s).\n",NULL); + TpctlUsage(); + return ERROR_INVALID_PARAMETER; + } + + } + + if ( TpctlParseArguments( CommandLineOptions, + Num_CommandLine_Params, + argc, + TmpArgv ) == -1 ) + { + TpctlErrorLog("\n\tTpctl: Invalid Command Line Argument(s)\n",NULL); + TpctlUsage(); + ScriptIndex--; + return ERROR_INVALID_PARAMETER; + } + + ScriptIndex--; + + // + // Check the options + // + + _strupr( GlobalCmdArgs.TpctlOptions ); + + if ( strchr( GlobalCmdArgs.TpctlOptions, '?' ) != NULL ) + { + TpctlUsage(); + return ERROR_INVALID_PARAMETER; + } + + if ( strchr( GlobalCmdArgs.TpctlOptions, 'W' ) != NULL ) + { + WriteThrough = FALSE; + } + + if ( strchr( GlobalCmdArgs.TpctlOptions, 'C' ) != NULL ) + { + ContinueOnError = TRUE; + } + + + // + // If there is a script file to be opened. + // + + if ( GlobalCmdArgs.ARGS.FILES.ScriptFile[0] != '\0' ) + { + // + // Then open it and the log file if it exists. + // + + Status = TpctlLoadFiles( GlobalCmdArgs.ARGS.FILES.ScriptFile, + GlobalCmdArgs.ARGS.FILES.LogFile ); + + if ( Status != NO_ERROR ) + { + TpctlUsage(); + return Status; + } + + // + // Otherwise if there is only a logfile name with no script file + // name print the usage message and return an error. + // + + } + else if ( GlobalCmdArgs.ARGS.FILES.LogFile[0] != '\0' ) + { + TpctlErrorLog("\n\tTpctl: Invalid Command Line Argument(s).\n",NULL); + TpctlUsage(); + return ERROR_INVALID_PARAMETER; + } + + return NO_ERROR; +} + + + +VOID +TpctlUsage ( + VOID + ) + +// ------------------ +// +// Routine Description: +// +// This routine prints out a usage statement. +// +// Arguments: +// +// None +// +// Return Value: +// +// None. +// +// -- ------------- + +{ + printf("\n\tUSAGE: TPCTL [/[?|W|C]] [SCRIPT_FILE_NAME [LOG_FILE_NAME]]\n\n"); + + printf("\tWhere:\n\n"); + + printf("\tSCRIPT_FILE_NAME - is an OPTIONAL script file containing test\n"); + printf("\t commands.\n\n"); + + printf("\tLOG_FILE_NAME - is an OPTIONAL log file for logging test results.\n"); + printf("\t Defaults to TESTPROT.LOG. A SCRIPT_FILE_NAME must\n"); + printf("\t precede a LOG_FILE_NAME.\n\n"); + + printf("\tOPTIONS:\n\n"); + printf("\t W - Disables write through which speeds up TPCTL as\n"); + printf("\t writes to the log files are now cached. Note that\n"); + printf("\t this exposes the risk of the log file not being\n"); + printf("\t updated should the system crash during a test.\n"); + printf("\t WRITE_THROUGH is enabled by default.\n\n"); + + printf("\t C - Enables TPCTL to continue on errors encountered during\n"); + printf("\t script testing. TPCTL will stop script processing on\n"); + printf("\t script errors by default.\n\n"); + + printf("\t ? - Access command online help.\n\n"); + +} + + + + +VOID +TpctlHelp( + LPSTR Command + ) + +// ------------------ +// +// Routine Description: +// +// This routine prints out help statements for each of the supported +// commands. +// +// Arguments: +// +// Command - The command to give the help information for. If no command +// is given then a list of all the commands that are supported +// will be printed. +// +// Return Value: +// +// None. +// +// ----------------- + +{ + DWORD CmdCode; + + if ( GlobalCmdArgs.ARGS.CmdName[0] == '\0' ) + { + CmdCode = HELP; + } + else + { + CmdCode = TpctlGetCommandCode( Command ); + } + + printf("\n\tThe syntax of this command is:\n\n"); + + switch ( CmdCode ) + { + case HELP: + printf("\tHELP [command]\n\n"); + printf("\tHelp is available on the following FUNCTIONAL commands:\n\n"); + printf("\t (AM) AddMulticastAddress (C) Close\n"); + printf("\t (DM) DeleteMulticastAddress (GE) GetEvents\n"); + printf("\t (O) Open (QI) QueryInformation\n"); + printf("\t (QS) QueryStatistics (RC) Receive\n"); + printf("\t (R) Reset (S) Send\n"); + printf("\t (SF) SetFunctionalAddress (SG) SetGroupAddress\n"); + printf("\t (SI) SetInformation (LA) SetLookAheadSize\n"); + printf("\t (SP) SetPacketFilter (SR) StopReceive\n"); + printf("\t (SS) StopSend (WT) WaitSend\n\n"); + printf("\tHelp is available on the following STRESS commands:\n\n"); + printf("\t (CS) CheckStress (ES) EndStress\n"); + printf("\t (ST) Stress (SV) StressServer\n"); + printf("\t (WS) WaitStress\n\n"); + printf("\tHelp is available on the following test control commands:\n\n"); + printf("\t (BL) BeginLogging (BP) BreakPoint\n"); + printf("\t (EL) EndLogging (G) Go\n"); + printf("\t (H) Help (P) Pause\n"); + printf("\t (Q) Quit (RS) ReadScript\n"); + printf("\t (SE) SetEnvirnoment (V) Verbose\n"); + printf("\t (W) Wait (RE) RecordingEnable\n"); + printf("\t (RD) RecordingDisable (SH) CommandShell\n"); + printf("\t (DI) Disable (EN) Enable\n"); + printf("\t (RG) Registry\n\n"); + printf("\tThe command may be entered in either the short form or\n"); + printf("\tthe long form. The short form is described by the letter\n"); + printf("\tor letters in the parentheses, while the long form is the\n"); + printf("\tword or phrase following.\n\n"); + break; + + case VERBOSE: + printf("\tVERBOSE\n\n"); + printf("\tVerbose enables and disables the output of each command and its\n"); + printf("\tresults to the screen. Errors will be printed to the screen\n"); + printf("\tregardless of the state of the Verbose flag.\n\n"); + printf("\t\"V\" - the short form of the command.\n"); + break; + + case SETENV: + printf("\tSETENVIRONMENT [Open_Instance] [Environment_Variable]\n\n"); + printf("\tSetEnvironment allows the user to customize environment\n"); + printf("\tvariables that effect the running of tests.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to set the environment variable\n"); + printf("\t on. The default value is 1.\n\n"); + printf("\tEnvironment_Variable - the variable(s) to set for a given call.\n\n"); + printf("\t All variables are set back to their defaults\n"); + printf("\t on each call unless otherwise specified.\n\n"); + printf("\tEnvironment Variable values that may be set are:\n\n"); + printf("\tWindowSize - the number of packets in the windows buffer of the\n"); + printf("\t windowing algorithm. The default is 10 packets.\n\n"); + printf("\tRandomBuffer - the maximum value passed to the rand routine to\n"); + printf("\t determine the number of buffers in RAND_MAKEUP packets.\n"); + printf("\t The default value is 5 which generates an average\n"); + printf("\t buffer size of 1/5 of the packet size.\n\n"); + printf("\tStressAddress - the multicast or functional address that will be\n"); + printf("\t used to initialize a stress test. All machines in\n"); + printf("\t a given stress test must use the same StressAddress.\n\n"); + printf("\tStressDelay - the standard number of seconds to delay ecah loopp\n"); + printf("\t through a stress test. The default is 1/1000 seconds.\n\n"); + printf("\tUpForAirDelay - the number of seconds to delay on the loop through\n"); + printf("\t a stress test after DelayInterval iterations have\n"); + printf("\t occurred. The default is 1/100 seconds.\n"); + printf("\tDelayInterval - the number of StressDelays between each UpForAirDelay\n"); + printf("\t during a stress test. The default is 10 iterations.\n\n"); + printf("\t\"SE\" - the short form of the command.\n"); + break; + + case READSCRIPT: + printf("\tREADSCRIPT [Script_File] [Log_File]\n\n"); + printf("\tReadScript reads test commands from a script file, executes\n"); + printf("\tthe commands and logs the results of the command to a log file.\n\n"); + printf("\tScript_File - the name of the file containing the test\n"); + printf("\t commands to execute. The default script file name is\n"); + printf("\t \"TESTPROT.TPS\".\n\n"); + printf("\tLog_File - the name of the file to log commands and results to. If\n"); + printf("\t this file exists, it will be overwritten. The default\n"); + printf("\t log file name is \"TESTPROT.LOG\".\n\n"); + printf("\t\"RS\" - the short form of the command.\n"); + break; + + case BEGINLOGGING: + printf("\tBEGINLOGGING [Log_File]\n\n"); + printf("\tBeginLogging enables the logging of commands and their results.\n"); + printf("\tOnce logging is started any commands entered from the command line\n"); + printf("\tare written to the Log_File. If commands are being read from\n"); + printf("\ta script this function is disabled. (see also ENDLOGGING)\n\n"); + printf("\tLog_File - the name of the file to log the commands and results to.\n"); + printf("\t If this file exists, it will be overwritten. The default\n"); + printf("\t log file name is \"CMDLINE.LOG\".\n\n"); + printf("\t\"BL\" - the short form of the command.\n"); + break; + + case ENDLOGGING: + printf("\tENDLOGGING\n\n"); + printf("\tEndLogging disables the logging of commands and their results.\n"); + printf("\t(see also BEGINLOGGING)\n\n"); + printf("\t\"EL\" - the short form of the command.\n"); + break; + + case RECORDINGENABLE: + printf("\tRECORDINGENABLE [ScriptFile]\n\n"); + printf("\tRecordingEnable enables the recording of commands.\n"); + printf("\tOnce recording is started any commands entered from the command line\n"); + printf("\tare written to the ScriptFile. If commands are being read from\n"); + printf("\ta script this function is disabled. (see also RECORDINGDISABLE)\n\n"); + printf("\tScriptFile - the name of the file to record the commands and results to.\n"); + printf("\t If this file exists, it will be overwritten. The default\n"); + printf("\t script file name is \"CMDLINE.TPS\".\n\n"); + printf("\t\"RE\" - the short form of the command.\n"); + break; + + case RECORDINGDISABLE: + printf("\tRECORDINGDISABLE\n\n"); + printf("\tRecordingDisable disables the recording of commands.\n"); + printf("\t(see also RECORDINGENABLE)\n\n"); + printf("\t\"RD\" - the short form of the command.\n"); + break; + + case SHELL: + printf("\tSHELL [Argument_1 Argument2 ... Argument_N]\n\n"); + printf("\tSHELL will from spawn a command shell from within TPCTL or execute\n"); + printf("\tthe command arguments Argument_1 through Argument_N and return back\n"); + printf("\tto the TPCTL command prompt. If using SHELL by itself, to return to\n"); + printf("\tthe TPCTL prompt simply EXIT the command shell.\n\n"); + printf("\t\"SH\" - the short form of the command.\n"); + break; + + + case WAIT: + printf("\tWAIT [Wait_Time]\n\n"); + printf("\tWait allows a script file to wait a given number of seconds prior\n"); + printf("\tto continuing with the next command.\n\n"); + printf("\tWait_Time - the time in seconds the call will wait before\n"); + printf("\t returning control to command processing.\n\n"); + printf("\t\"W\" - the short form of the command.\n"); + break; + + case GO: + printf("\tGO [Open_Instance] [Remote_Address] [Test_Signature]\n\n"); + printf("\tGo sends a TP_GO packet to the Remote Address signalling\n"); + printf("\ta Paused instance of the driver to continue processing its\n"); + printf("\ttest script. Go continuously resends the packet, and will\n"); + printf("\twait, retrying, until it is acknowledged or stopped with\n"); + printf("\t. (see also PAUSE)\n\n"); + printf("\tOpen_Instance - the open instance between the test driver and\n"); + printf("\t the MAC adapter that will send the TP_GO Packet.\n"); + printf("\t The default value is 1.\n\n"); + printf("\tRemote_Address - the address of a remote machine to send the TP_GO\n"); + printf("\t packet to.\n\n"); + printf("\tTest_Signature - a unique test signature used by both machines to\n"); + printf("\t determine if the correct packets have been sent and\n"); + printf("\t acknowledged. This value must match the Test\n"); + printf("\t Signature value on the PAUSED machine.\n\n"); + printf("\t\"G\" - the short form of the command.\n"); + break; + + case PAUSE: + printf("\tPAUSE [Open_Instance] [Remote_Address] [Test_Signature]\n\n"); + printf("\tPause waits for the receipt of a TP_GO packet wit ha matching test\n"); + printf("\tsignature and then acknowledges it6 by sending a TP_GO_ACKL packet.\n"); + printf("\tPause will wait for the receipt of the TP_GO packlet until it arrives,\n"); + printf("\tor the command is cancelled by .\n\n"); + printf("\tOpen_Instance - the open instance between the test driver and\n"); + printf("\t the MAC adapter that will wait for the TP_GO Packet.\n"); + printf("\t The default value is 1.\n\n"); + printf("\tRemote_Address - the address of a remote machine to send the TP_GO_ACK\n"); + printf("\t packet to.\n\n"); + printf("\tTest_Signature - a unique test signature used by both machines to\n"); + printf("\t determine if the correct packets have been sent and\n"); + printf("\t acknowledged. This value must match the Test\n"); + printf("\t Signature value on the machine sending the TP_GO\n"); + printf("\t packet\n\n"); + printf("\t\"P\" - the short form of the command.\n"); + break; + + case LOAD: + printf("\tLOAD [MAC_Driver_Name]\n\n"); + printf("\tLoad issues a call to NtLoadDriver to unload the driver for\n"); + printf("\tthe MAC adapter \"Adapter_Name\".\n\n"); + printf("\tMAC_Driver_Name - the MAC adapter to be loaded. There is no default\n"); + printf("\t value.\n\n"); + printf("\t\"L\" - the short form of the command.\n"); + break; + + case UNLOAD: + printf("\tUNLOAD [MAC_Driver_Name]\n\n"); + printf("\tUnload issues a call to NtUnloadDriver to unload the driver for\n"); + printf("\tthe MAC adapter \"Adapter_Name\".\n\n"); + printf("\tMAC_Driver_Name - the MAC adapter to be unloaded. There is no default\n"); + printf("\t value.\n\n"); + printf("\t\"U\" - the short form of the command.\n"); + break; + + case OPEN: + printf("\tOPEN [Open_Instance] [Adapter_Name]\n\n"); + printf("\tOpen issues a call to NdisOpenAdapter to open the MAC adapter\n"); + printf("\tAdapter_Name, and associates it with the given Open_Instance.\n"); + printf("\tSubsequent calls to the Open_Instance will be directed to\n"); + printf("\tthis adapter.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter this open will be associated\n"); + printf("\t with. The default value is 1.\n\n"); + printf("\tAdapter_Name - the MAC adapter to be unloaded. There is no default\n"); + printf("\t value.\n\n"); + printf("\t\"O\" - the short form of the command.\n"); + break; + + case CLOSE: + printf("\tCLOSE [Open_Instance]\n\n"); + printf("\tClose issues a call to NdisCloseAdapter to close the MAC adapter\n"); + printf("\tassociated with the given Open_Instance.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to be closed. The default\n"); + printf("\t value is 1.\n\n"); + printf("\t\"C\" - the short form of the command.\n"); + break; + + case SETPF: + printf("\tSETPACKETFILTER [Open_Instance] [Packet_Filter]\n\n"); + printf("\tSetPacketFilter issues a call to the MAC using NdisRequest\n"); + printf("\tto set the card's packet filter to a given value.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tPacket_Filter - the packet filter value to set on the MAC adapter.\n"); + printf("\t Multiple filter values may be entered by seperating\n"); + printf("\t each with the \"|\" character. Valid values for\n"); + printf("\t Packet_Filter are:\n\n"); + printf("\t Directed\n"); + printf("\t Multicast\n"); + printf("\t AllMulticast\n"); + printf("\t Broadcast\n"); + printf("\t SourceRouting\n"); + printf("\t Promiscuous\n"); + printf("\t Mac_Frame\n"); + printf("\t Functional\n"); + printf("\t AllFunctional\n"); + printf("\t Group\n"); + printf("\t None\n\n"); + printf("\t The default value is \"Directed\".\n\n"); + printf("\t\"SP\" - the short form of the command.\n"); + break; + + case SETLA: + printf("\tSETLOOKAHEADSIZE [Open_Instance] [LookAhead_Size]\n\n"); + printf("\tSetLookAheadSize issues a call to the MAC using NdisRequest\n"); + printf("\tto set the card's lookahead buffer to a given size.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tLookAhead_Size - the new size of the card's lookahead buffer. The\n"); + printf("\t default value is 100 bytes.\n\n"); + printf("\t\"LA\" - the short form of the command.\n"); + break; + + case ADDMA: + printf("\tADDMULTICASTADDRESS [Open_Instance] [Multicast_Address]\n\n"); + printf("\tAddMulticastAddress issues a call to the MAC using NdisRequest\n"); + printf("\tto add a multicast address to the list of multicast addresses\n"); + printf("\tcurrently set on the card.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tMulticast_Address - the multicast address to add to the list.\n\n"); + printf("\t\"AM\" - the short form of the command.\n"); + break; + + case DELMA: + printf("\tDELETEMULTICASTADDRESS [Open_Instance] [Multicast_Address]\n\n"); + printf("\tDeleteMulticastAddress issues a call to the MAC using NdisRequest\n"); + printf("\tto delete a multicast address from the list of multicast\n"); + printf("\taddresses currently set on the card.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tMulticast_Address - the multicast address to delete from the list.\n\n"); + printf("\t\"DM\" - the short form of the command.\n"); + break; + + case SETFA: + printf("\tSETFUNCTIONALADDRESS [Open_Instance] [Functional_Address]\n\n"); + printf("\tSetFunctionalAddress issues a call to the MAC using NdisRequest\n"); + printf("\tto set a functional address on the card.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tFunctional_Address - the functional address to set on the card.\n\n"); + printf("\t\"SF\" - the short form of the command.\n"); + break; + + case SETGA: + printf("\tSETGROUPADDRESS [Open_Instance] [Group_Address]\n\n"); + printf("\tSetGroupAddress issues a call to the MAC using NdisRequest\n"); + printf("\tto set a group address on the card.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tGroup_Address - the group address to set on the card.\n\n"); + printf("\t\"SG\" - the short form of the command.\n"); + break; + + case QUERYINFO: + printf("\tQUERYINFORMATION [Open_Instance] [OID_Request]\n\n"); + printf("\tQueryInformation issues a call to the MAC using NdisRequest\n"); + printf("\tto query a given class of information from the MAC.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tOID_Request - the information type to query. The default value\n"); + printf("\t is \"SupportedOidList\".\n"); + printf("\t\"QI\" - the short form of the command.\n"); + break; + + case QUERYSTATS: + printf("\tQUERYSTATISTICS [Device_Name] [OID_Request]\n\n"); + printf("\tDevice_Name - the name of the device to issue the request\n"); + printf("\t to. There is no default value.\n\n"); + printf("\tOID_Request - the statistics type to query. The default value\n"); + printf("\t is \"SupportedOidList\".\n"); + printf("\t\"QS\" - the short form of the command.\n"); + break; + + case SETINFO: + printf("\tSETINFORMATION [Open_Instance] [OID_Request] [Type_Specific]\n\n"); + printf("\tSetInformation issues a call to the MAC using NdisRequest\n"); + printf("\tto set a given class of information in the MAC.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tOID_Request - the information type to set. Valid values for\n"); + printf("\t OID_Request are:\n\n"); + printf("\t CurrentPacketFilter\n"); + printf("\t CurrentLookAhead\n"); + printf("\t CurrentMulticastList\n"); + printf("\t CurrentFunctionalAddress\n"); + printf("\t CurrentGroupAddress\n"); + printf("\t The default value is \"CurrentPacketFilter\".\n"); + printf("\tType_Specific - the information to set for a given OID_Request\n"); + printf("\t\"SI\" - the short form of the command.\n"); + break; + + case RESET: + printf("\tRESET [Open_Instance]\n\n"); + printf("\tReset issues a call to the MAC using NdisReset to reset the MAC.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\t\"R\" - the short form of the command.\n"); + break; + + case SEND: + printf("\tSEND [Open_Instance] [Destination_Address] [Packet_Size] [Number]\n"); + printf("\t [Resend_Address]\n\n"); + printf("\tSend issues a call to the MAC using NdisSend to send packets on the\n"); + printf("\tnetwork. Sending more then one packet causes the command to return\n"); + printf("\tasynchronously. If a Resend_Address argument is specified, then\n"); + printf("\teach packet sent will contain a \"resend\" packet in the data field\n"); + printf("\tthat is extracted from the packet by any receiving test and\n"); + printf("\tresent to the address specified. (see also RECEIVE, STOPSEND and\n"); + printf("\tWAITSEND)\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to issue the request(s) to. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tDestination_Address - the network address the packet(s) will be sent\n"); + printf("\t to.\n\n"); + printf("\tPacket_Size - the size of the packet(s) to send.\n\n"); + printf("\tNumber - the number of packets to send. A value of \"-1\" will\n"); + printf("\t cause the test to send packets continuously until\n"); + printf("\t stopped by a call to STOPSEND.\n\n"); + printf("\tResend_Address - OPTIONAL: the address that will be placed in the\n"); + printf("\t destination address of the \"resend\" packet.\n\n"); + printf("\t\"S\" - the short form of the command.\n"); + break; + + case STOPSEND: + printf("\tSTOPSEND [Open_Instance]\n\n"); + printf("\tStopSend stops a previously started SEND command if it is still\n"); + printf("\trunning, and prints the SEND command's results.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to stop the SEND command on.\n"); + printf("\t The default value is 1.\n\n"); + printf("\t\"SS\" - the short form of the command.\n"); + break; + + case WAITSEND: + printf("\tWAITSEND [Open_Instance]\n\n"); + printf("\tWaitSend waits for a send test to end, and then displays the\n"); + printf("\tsend test results. This command may be cancelled by entering\n"); + printf("\tCtrl-C.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to wait for the send test to\n"); + printf("\t end on. The default value is 1.\n\n"); + printf("\t\"WT\" - the short form of the command.\n"); + break; + + case RECEIVE: + printf("\tRECEIVE [Open_Instance]\n\n"); + printf("\tReceive sets the test up in a mode to \"expect\" to receive\n"); + printf("\tpackets from other tests. Each packet will be inspected, and\n"); + printf("\tcounted. If a test packet received contains a \"resend\"\n"); + printf("\tpacket, the \"resend\" packet will be extracted from the packet,\n"); + printf("\tand sent to the address contained within. (see also SEND and STOPRECEIVE)\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to set up to expect packets.\n"); + printf("\t The default value is 1.\n\n"); + printf("\t\"RC\" - the short form of the command.\n"); + break; + + case STOPREC: + printf("\tSTOPRECEIVE [Open_Instance]\n\n"); + printf("\tStopReceive resets a test which has previously had a\n"); + printf("\tRECEIVE commmand issued to it, to no longer \"expect\" packets.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to reset. The default value\n"); + printf("\t is 1.\n\n"); + printf("\t\"SR\" - the short form of the command.\n"); + break; + + case GETEVENTS: + printf("\tGETEVENTS [Open_Instance]\n\n"); + printf("\tGetEvents queries the test for information about \"unexpected\"\n"); + printf("\tindications and completions.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to query the events from. The\n"); + printf("\t default value is 1.\n\n"); + printf("\t\"GE\" - the short form of the command.\n"); + break; + + case STRESS: + printf("\tSTRESS [Open_Instance] [Member_Type] [Packets] [Iterations]\n"); + printf("\t [Packet_Type] [Packet_Size] [Packet_MakeUp] [Response_Type]\n"); + printf("\t [Delay_Type] [Delay_Length] [Windowing] [Data_Checking]\n"); + printf("\t [PacketsFromPool]\n\n"); + printf("\tStress sets the test up to run a stress test. If the test\n"); + printf("\tis started successfully the command will complete asynchronously.\n"); + printf("\tThe test will run until finished or until stopped manually. (see also\n"); + printf("\tENDSTRESS, STOPSTRESS, WAITSTRESS, and CHECKSTRESS)\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to start a stress test on. The\n"); + printf("\t default value is 1.\n\n"); + printf("\tMember_Type - how the protocol will perform in the stress test; as\n"); + printf("\t a client (CLIENT) or as a client and server (BOTH).\n"); + printf("\t The default value is BOTH.\n\n"); + printf("\tPackets - the number of packets that will be sent to each server prior\n"); + printf("\t to the test completing. A value of -1 causes the test to\n"); + printf("\t run forever unless a value is entered for Iterations. The\n"); + printf("\t default value for packets is -1.\n\n"); + printf("\tIterations - the number of iterations this test will run. A value\n"); + printf("\t of -1 causes the test to run forever unless a value is\n"); + printf("\t entered for Packet. The default value for Iterations\n"); + printf("\t is -1.\n\n"); + printf("\tPacket_Type - the type of packet size algorithm used to create the\n"); + printf("\t packets for the test; FIXEDSIZE, RANDOMSIZE or CYCLICAL.\n"); + printf("\t The default type is FIXED.\n\n"); + printf("\tPacket_Size - with the Packet_Type value determines the size of packets\n"); + printf("\t in the test. The default is 512 bytes.\n\n"); + printf("\tPacket_MakeUp - the number and size of the buffers that makeup each\n"); + printf("\t packet; RAND, SMALL, ZEROS, ONES and KNOWN. The\n"); + printf("\t default makeup is RAND.\n\n"); + printf("\tResponse_Type - the method the server will use when responding to test\n"); + printf("\t packets; NO_RESPONSE, FULL_RESPONSE, ACK_EVERY,\n"); + printf("\t or ACK_10_TIMES. The default value is FULL_RESPONSE.\n\n"); + printf("\tDelay_Type - the method used to determine the next interpacket\n"); + printf("\t delay; FIXEDDELAY or RANDOMDELAY. The default value\n"); + printf("\t is FIXEDDELAY.\n\n"); + printf("\tDelay_Length - the minimum number of iterations between two\n"); + printf("\t consecutive sends to the same server in a test.\n"); + printf("\t The default value is 0 iterations.\n\n"); + printf("\tWindowing - a boolean used to determine whether a simple windowing\n"); + printf("\t algorithm will be used between the client and each server.\n"); + printf("\t the default value is TRUE.\n\n"); + printf("\tData_Checking - a boolean used to determine whether data checking\n"); + printf("\t will be performed on each packet received. The\n"); + printf("\t default value is TRUE.\n\n"); + printf("\tPacketsFromPool - a boolean used to determine whether a pool of\n"); + printf("\t packets will be created prior to the test. The\n"); + printf("\t default value is TRUE.\n\n"); + printf("\t\"ST\" - the short form of the command.\n"); + break; + + case STRESSSERVER: + printf("\tSTRESSSERVER [Open_Instance]\n\n"); + printf("\tStressServer sets the test up to participate in a stress\n"); + printf("\ttest as a server receiving and responding to stress packets from\n"); + printf("\tany clients running a stress test.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to start a stress server on. The\n"); + printf("\t default value is 1.\n\n"); + printf("\t\"SV\" - the short form of the command.\n"); + break; + + case ENDSTRESS: + printf("\tENDSTRESS [Open_Instance]\n\n"); + printf("\tEndStress issues a command to the test to stop a currently\n"); + printf("\trunning stress test, whether the protocol is acting as a client or\n"); + printf("\tserver. If the protocol is acting as a client, once the test has\n"); + printf("\tended, the result will be displayed.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to end the stress test on. The\n"); + printf("\t default value is 1.\n\n"); + printf("\t\"ES\" - the short form of the command.\n"); + break; + + case WAITSTRESS: + printf("\tWAITSTRESS [Open_Instance]\n\n"); + printf("\tWaitStress waits for a stress test to end, and then displays the\n"); + printf("\tstress test results. This command may be cancelled by entering\n"); + printf("\tCtrl-C.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to wait for the stress test to\n"); + printf("\t end on. The default value is 1.\n\n"); + printf("\t\"WS\" - the short form of the command.\n"); + break; + + case CHECKSTRESS: + printf("\tCHECKSTRESS [Open_Instance]\n\n"); + printf("\tCheckStress checks to see if a stress test has ended, and if so\n"); + printf("\tdisplays the stress test results.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver\n"); + printf("\t and the MAC adapter to check for the results of a\n"); + printf("\t stress test on. The default value is 1.\n\n"); + printf("\t\"CS\" - the short form of the command.\n"); + break; + + case BREAKPOINT: + printf("\tBREAKPOINT\n\n"); + printf("\tBreakPoint causes an interrupt to break into the debugger.\n\n"); + printf("\t\"BP\" - the short form of the command.\n"); + break; + + case QUIT: + printf("\tQUIT\n\n"); + printf("\tQuit exits the control application. Any tests currently\n"); + printf("\trunning are stopped and any opens to MACs are subsequently\n"); + printf("\tclosed.\n\n"); + printf("\t\"Q\" - the short form of the command.\n"); + break; + + case DISABLE: + printf("\tDISABLE [ENV_VAR_1] [ENV_VAR_2]...[ENV_VAR_N]\n\n"); + printf("\tDisable will prevent the test tool from executing any commands\n"); + printf("\tfollowing it UNLESS all the environment variables passed to it have\n"); + printf("\tbeen declared OR if it encounters the special command ENABLE.\n"); + printf("\tIn that event that all environments variables are set and passed as\n"); + printf("\targuments to DISABLE, the command is ignored and TPCTL remains\n"); + printf("\tactive. Disable by itself will also disable the tool\n\n"); + printf("\t\"DI\" - the short form of the command.\n"); + break; + + case ENABLE: + printf("\tENABLE\n\n"); + printf("\tEnable will enable the tool to accept commands\n\n"); + printf("\t\"EN\" - the short form of the command.\n"); + break; + + case REGISTRY : + printf("\tREGISTRY [Operation_Type] [Key_DataBase] [SubKey] [SubKey_Class]\n"); + printf("\t [SubKey_Value_Name] [SubKey_Value_Type] [SubKey_Value]\n\n"); + printf("\tRegistry is responsible for adding, deleting, modifying and querying\n"); + printf("\texisting registry key entries.\n\n"); + printf("\tOperation_Type - The type of operation to be performed on the registry\n"); + printf("\t key\n"); + printf("\t Types : ADD_KEY, DELETE_KEY, QUERY_KEY, ADD_VALUE,\n"); + printf("\t CHANGE_VALUE, DELETE_VALUE, QUERY_VALUE\n"); + printf("\t Default: QUERY_KEY\n\n"); + printf("\tKey_DataBase - The key database to be interacted with\n"); + printf("\t Databases: CLASSES_ROOT, CURRENT_USER, LOCAL_MACHINE,\n"); + printf("\t USER\n"); + printf("\t Default : LOCAL_MACHINE\n\n"); + printf("\tSubKey - The string value(name) of the subkey being interacted\n"); + printf("\t with\n"); + printf("\t Default:\n"); + printf("\t \"System\\CurrenControlSet\\Services\\Elnkii01\\Parameters\"\n"); + printf("\t NOTE : String values must be contained within double\n"); + printf("\t quotes\n\n"); + printf("\tSubKey_Class - The string value(class) to be associated with this\n"); + printf("\t subkey\n"); + printf("\t Default: \"Network Drivers\"\n"); + printf("\t NOTE : String values must be contained within double\n"); + printf("\t quotes\n\n"); + printf("\tSubKey_Value_Name - The string value(ValueName) to be associated with\n"); + printf("\t this subkey\n"); + printf("\t Default: \"NetworkAddress\"\n"); + printf("\t NOTE : String values must be contained within\n"); + printf("\t double quotes\n\n"); + printf("\tSubKey_Value_Type - The type of value being provided\n"); + printf("\t Types : BINARY, DWORD_REGULAR,\n"); + printf("\t DWORD_LITTLE_ENDIAN, DWORD_BIG_ENDIAN,\n"); + printf("\t EXPAND_SZ, LINK, MULTI_SZ, NONE,\n"); + printf("\t RESOURCE_LIST, SZ\n"); + printf("\t Default: DWORD_REGULAR\n\n"); + printf("\tSubKey_Value - The provided value to set the sub key to\n"); + printf("\t NOTE : Multiple strings must be seperated by\n"); + printf("\t commas. Hex values should be preceeded by 0x.\n"); + printf("\t Octal values are preceded by 0. Decimal values\n"); + printf("\t do not have a leading 0.By default the base\n"); + printf("\t radix is 10\n\n"); + printf("\t\"RG\" - the short form of the command.\n"); + break; + + case PERFSERVER: + printf("\tPERFORMSERVER [Open_Instance] \n\n"); + printf("\tPerfServer starts a server to participate with the specified client in a\n"); + printf("\tperformance test. This command always returns synchronously.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver and the MAC\n"); + printf("\t adapter to issue the request to. Default value is 1.\n\n"); + printf("\t\"PS\" - the short form of the command.\n"); + break; + + case PERFCLIENT: + printf("\tPERFORMRECEIVE [Open_Instance] [Server_Address] [Send_Address] "); + printf(" [Packet_Size] [Num_Packets] [Delay] [Mode] \n\n"); + printf("\tPerfClient starts a client to participate with the specified server in a\n"); + printf("\tperformance test. The specific test is indicated by the mode.\n"); + printf("\tThis command always returns synchronously.\n\n"); + printf("\tOpen_Instance - the open instance between the test driver and the MAC\n"); + printf("\t adapter to issue the request to. Default value is 1.\n\n"); + printf("\tServer_Address - the network address of the server card\n\n"); + printf("\tSend_Address - the network address to which the server sends messages.\n\n"); + printf("\tPacket_Size - total size of the test packets to be sent\n\n"); + printf("\tNum_Packets - total number of test packets to be sent\n\n"); + printf("\tDelay - how much to delay between sends\n\n"); + printf("\tMode - which performance test to use:\n"); + printf("\t 0 = client sends to any address (performance send test)\n"); + printf("\t 1 = client sends to server (performance send test)\n"); + printf("\t 2 = client sends to server, with server ACKs\n"); + printf("\t 3 = two-way sends\n"); + printf("\t 4 = server sends to client (performance receive test)\n"); + printf("\t 5 = client sends REQ to server, server responds with sends\n"); + printf("\t other = shut down server\n\n"); + printf("\t\"PC\" - the short form of the command.\n"); + break; + + default: + printf("\tHELP [ ADDMULTICASTADDRESS | BEGINLOGGING | BREAKPOINT | CHECKSTRESS |\n"); + printf("\t CLOSE | DELETEMULTICASTADDRESS | ENDLOGGING | ENDSTRESS |\n"); + printf("\t GETEVENTS | GO | HELP | LOAD | OPEN | PAUSE | QUERYINFORMATION |\n"); + printf("\t QUERYSTATISTICS | QUIT | READSCRIPT | RECEIVE | RESET | SEND |\n"); + printf("\t SETENVIRONMENT | SETFUNCTIONALADDRESS | SETGROUPADDRESS |\n"); + printf("\t SETINFORMATION | SETLOOKAHEADSIZE | SETPACKETFILTER |\n"); + printf("\t STOPRECEIVE | STOPSEND | STRESS | STRESSSERVER | UNLOAD |\n"); + printf("\t VERBOSE | WAIT | WAITSEND | WAITSTRESS | SHELL |\n"); + printf("\t RECORDINGENABLE | RECORDINGDISABLE | REGISTRY |\n"); + printf("\t PERFSERVER | PERFCLIENT\n\n"); + printf("\tThe command \"%s\" is unknown.\n", _strupr( Command )); + break; + + } // switch() + + printf("\n"); +} + + + +DWORD +TpctlLoadFiles( + LPSTR ScriptFile, + LPSTR LogFile + ) + +// --------------- +// +// Routine Description: +// +// This routine loads a script file into a buffer, and opens a log +// file for logging commands and results to. +// +// Arguments: +// +// IN LPSTR ScriptFile - the name of the script file to open and read. +// IN LPSTR LogFile - the name of the log file to open. +// +// Return Value: +// +// DWORD - NO_ERROR if the script and log files are opened and +// processed correctly, otherwise the error returned on the +// failure from the win32 api that failed. +// +// NOTE: if this routine returns an error, then TpctlUnLoadFiles +// MUST be called next to reset the script structures +// correctly, and deallocate any resources that were +// allocated during this routine. +// +// --------------- + + +{ + DWORD NextScriptIndex; + HANDLE FileHandle; + DWORD Status; + DWORD FileSize; + + NextScriptIndex = ScriptIndex+1; + + // + // First set the lowest level flag(s) in the scripts field to + // delineate which script is the lowest VALID script and should be + // unloaded. (necessary in case the next call to load files fails we + // will know where the high water mark is.) + // + + if ( ScriptIndex >= 0 ) + { + // + // if this is the first script we must ignore the reset of the + // "previous" script. + // + + Scripts[ScriptIndex].IsLowestLevel = FALSE; + } + + Scripts[NextScriptIndex].IsLowestLevel = TRUE; + + // + // We have a script file, so increment the script index, and set the + // the index into the script buffer to zero. Make sure that we have + // not passed the maximum number of recursion in reading scripts. + // + + if ( NextScriptIndex == TPCTL_MAX_SCRIPT_LEVELS ) + { + TpctlErrorLog("\n\tTpctl: Too many levels of script reading recursion; level 0x%lx\n", + (PVOID)(NextScriptIndex+1)); + return (DWORD)STATUS_UNSUCCESSFUL; + } + + // + // First we allocate the memory to store the script file name in. + // + + Scripts[NextScriptIndex].ScriptFile = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, + TPCTL_MAX_PATHNAME_SIZE ); + + if ( Scripts[NextScriptIndex].ScriptFile == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctlLoadFiles: failed to alloc Script file name storage, returned 0x%lx.\n", (PVOID)Status); + return Status; + } + + // + // Then determine what filename to write to it. + // + + if ( ScriptFile[0] == '\0' ) + { + // + // If no script file name was passed, then open the default + // script file TESTPROT.TPS. + // + + strcpy( Scripts[NextScriptIndex].ScriptFile,TPCTL_SCRIPTFILE ); + } + else + { + // + // Otherwise copy the filename passed into place. + // + + strcpy( Scripts[NextScriptIndex].ScriptFile,ScriptFile ); + } + + // + // Open the script file, if it does not exist fail with an error msg. + // + + FileHandle = CreateFile(Scripts[NextScriptIndex].ScriptFile, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + + if ( FileHandle == (HANDLE)-1 ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed to open script file \"%s\", ", + (PVOID)Scripts[NextScriptIndex].ScriptFile); + TpctlErrorLog("returned 0x%lx.\n",(PVOID)Status); + return Status; + } + + // + // and find its size. + // + + FileSize = GetFileSize( FileHandle,NULL ); + + if ( FileSize == -1 ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed find file size - returned 0x%lx.\n", + (PVOID)Status); + return Status; + } + + // + // If necessary allocate memory for the Buffer. + // + + if ( Scripts[NextScriptIndex].Buffer == NULL ) + { + Scripts[NextScriptIndex].Buffer = (LPBYTE)GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, + FileSize ); + + if ( Scripts[NextScriptIndex].Buffer == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctlLoadFiles: failed to alloc script buffer, returned 0x%lx.\n", + (PVOID)Status); + CloseHandle( FileHandle ); + return Status; + } + + } + else if ( FileSize > Scripts[NextScriptIndex].Length ) + { + Scripts[NextScriptIndex].Buffer = + (LPBYTE)GlobalReAlloc( (HANDLE)Scripts[NextScriptIndex].Buffer, + FileSize, + GMEM_ZEROINIT | GMEM_MOVEABLE ); + + if ( Scripts[NextScriptIndex].Buffer == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctlLoadFiles: failed to ReAlloc script buffer, returned 0x%lx.\n", + (PVOID)Status); + CloseHandle( FileHandle ); + return Status; + } + } + + // + // And read the script file into it. + // + + Status = ReadFile( FileHandle, + Scripts[NextScriptIndex].Buffer, + FileSize, + &Scripts[NextScriptIndex].Length, + NULL ); + + if ( Status != TRUE ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctlLoadFiles: failed to read script file \"%s\", ",(PVOID)ScriptFile); + TpctlErrorLog("returned 0x%lx.\n",(PVOID)Status); + CloseHandle( FileHandle ); + return Status; + } + + // + // We are done with script file now, so close it. + // + + if (!CloseHandle(FileHandle)) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctlLoadFiles: failed to close Script file \"%s\", ",(PVOID)ScriptFile); + TpctlErrorLog("returned 0x%lx.\n",(PVOID)Status); + } + + // + // Now handle the log file. If we are not given a log file we need + // to determine the name of the log file we should use. + // First we allocate the memory to store the log file name in. + // + + Scripts[NextScriptIndex].LogFile = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, + TPCTL_MAX_PATHNAME_SIZE ); + + if ( Scripts[NextScriptIndex].LogFile == NULL ) + { + Status = GetLastError(); + TpctlErrorLog( + "\n\tTpctlLoadFiles: failed to alloc Log file name storage, returned 0x%lx.\n", + (PVOID)Status); + return Status; + } + + // + // Then determine what filename to write to it. + // + + if (( LogFile == NULL ) || ( LogFile[0] == '\0' )) + { + if ( NextScriptIndex == 0 ) + { + // + // If this is the first script file and no log file name was + // given, then use the default log file name. + // + + strcpy( Scripts[NextScriptIndex].LogFile,TPCTL_LOGFILE ); + } + else + { + // + // Otherwise, since no new log file name was given, and we are + // recursively reading script files we will use the log file + // used by the last level of script files. + // + + strcpy( Scripts[NextScriptIndex].LogFile,Scripts[ScriptIndex].LogFile ); + Scripts[NextScriptIndex].LogHandle = Scripts[ScriptIndex].LogHandle; + } + + } + else + { + // + // We have a log file name so copy it into the scripts structure. + // + + strcpy(Scripts[NextScriptIndex].LogFile,LogFile); + } + + // + // Now, if the log file has not already been opened, then we must open + // it. If the logfile already exists it WILL be truncated on the open. + // + + if (( LogFile != NULL ) && ( LogFile[0] != '\0' ) || + ( NextScriptIndex == 0 )) + { + if ( WriteThrough ) + { + Scripts[NextScriptIndex].LogHandle = + CreateFile( Scripts[NextScriptIndex].LogFile, + GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, + NULL ); + } + else + { + Scripts[NextScriptIndex].LogHandle = + CreateFile( Scripts[NextScriptIndex].LogFile, + GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL ); + } + + if ( Scripts[NextScriptIndex].LogHandle == (HANDLE)-1 ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed to open log file \"%s\", ", + (PVOID)Scripts[NextScriptIndex].LogFile); + TpctlErrorLog("returned 0x%lx.\n",(PVOID)Status); + return Status; + } + } + + // + // We have successfully opened the script and log files, and are now + // ready to read commands from the script buffer, set the flag stating + // that the commands are coming from the script file, and increment the + // scriptindex to point to the newly create script info. + // + + CommandsFromScript = TRUE; + + ScriptIndex = NextScriptIndex; + + return NO_ERROR; +} + + + +VOID +TpctlFreeFileBuffers( + VOID + ) + +// --------------- +// +// Routine Description: +// +// Arguments: +// +// None. +// +// Return Value: +// +// None. +// +// -------------- + +{ + DWORD si = 0; + HANDLE tmpHandle; + DWORD Status; + + for (si=0;si= Scripts[ScriptIndex].Length ) + { + // + // We are at the end of this script file, clean up the script + // and log files. + // + + TpctlUnLoadFiles(); + + // + // Set the return value in Buffer to null indicating that + // there was no command. + // + + *Buffer = 0x0; + + } + else + { + // + // Null out the Buffer buffer so that we don't use any garbage + // laying around from the last command. + // + + ZeroMemory(Buffer, TPCTL_CMDLINE_SIZE); + + SBuf = Scripts[ScriptIndex].Buffer; + + while ((DWORD)(CmdBufPtr - Buffer) < MaximumResponse ) + { + // + // and null out the temporary command buffer. + // + + ZeroMemory(LineBuf, TPCTL_CMDLINE_SIZE); + + // + // Read the next command line from the script file. + // + + i = (DWORD)-1; + + while ( Scripts[ScriptIndex].BufIndex < + Scripts[ScriptIndex].Length ) + { + // + // If we have found the beginning of an Environment + // Variable argument... + // + + if ( SBuf[Scripts[ScriptIndex].BufIndex] == '%' ) + { + j = (DWORD)-1; + FoundEnvVar = FALSE; + Scripts[ScriptIndex].BufIndex++; + + // + // Copy it into a temp buffer. + // + + while (( SBuf[Scripts[ScriptIndex].BufIndex] != '\n' ) && + (( SBuf[Scripts[ScriptIndex].BufIndex] != ' ' ) && + (( SBuf[Scripts[ScriptIndex].BufIndex] != '\t' ) && + ( SBuf[Scripts[ScriptIndex].BufIndex] != '\r' )))) + { + TmpBuf[++j] = SBuf[Scripts[ScriptIndex].BufIndex++]; + + if ( TmpBuf[j] == '%') + { + TmpBuf[j] = '\0'; + FoundEnvVar = TRUE; + break; + } + } + + // + // And find its true value in the process environment. + // + + if ( FoundEnvVar == TRUE ) + { + EnvVar = getenv( _strupr( TmpBuf )); + + if ( EnvVar == NULL ) + { + TpctlErrorLog("\n\tTpctl: Undefined Environment Variable \"%%%s%%\".\n", + TmpBuf); + return ERROR_ENVVAR_NOT_FOUND; + } + + // + // and copy the value to the line buffer. + // + + do + { + LineBuf[++i] = *EnvVar++; + } while ( *EnvVar != '\0' ); + + } + else + { + TmpBuf[++j] = '\0'; + TpctlErrorLog("\n\tTpctl: Invalid Environment Variable Format \"%%%s\".\n", + TmpBuf); + return ERROR_INVALID_PARAMETER; + } + + // + // Otherwise just copy the next character to the line buffer. + // + + } + else + { + LineBuf[++i] = SBuf[Scripts[ScriptIndex].BufIndex++]; + } + + if ( LineBuf[i] == '\n' ) + { + break; + } + } + + LineBuf[i] = '\0'; + + if ( InitialCommand == TRUE ) + { + TpctlLog("%s ",Prompt); + InitialCommand = FALSE; + } + else + { + TpctlLog("\t ",NULL ); + } + + TpctlLog("%s\n",LineBuf); + + if ( !Verbose ) + { + if ( strstr( LineBuf,"TITLE:" ) != NULL ) + { + TpctlErrorLog("\n%s ",Prompt); + TpctlErrorLog("%s\n\n",LineBuf); + } + } + + // check for comment ending line + + ContinueCommand = FALSE; + if ( (EndOfCmd = strchr( LineBuf, '#')) != NULL) + { + // + // We just have a comment, set the command continue + // flag to exit the command parsing, and null the + // command section of the string. + // + EndOfCmd[0] = '\0'; + } + + // check for a closing parenthesis on line. This is the end of any SETGLOBALS + // command that contains an expression. No other command uses parenthesis + + if ( (EndOfCmd = strchr( LineBuf, ')' )) != NULL) + { + EndOfCmd[1] = '\0'; // closing parenthese is last thing on line + } + else if ( (EndOfCmd = strchr( LineBuf, '+' )) != NULL) + { + // + // This is a Cmd Continuation, set the flag to continue + // the while loop, and ignore the rest of the line. + // + ContinueCommand = TRUE; + EndOfCmd[0] = '\0'; + } + + i=0; + + while ( LineBuf[i] != '\0' ) + { + if ((( LineBuf[i] == ' ' ) || + ( LineBuf[i] == '\t' )) || + ( LineBuf[i] == '\r' )) + { + *CmdBufPtr++ = ' '; + + while ((( LineBuf[i] == ' ' ) || + ( LineBuf[i] == '\t' )) || + ( LineBuf[i] == '\r' )) + { + i++; + } + + } + else + { + *CmdBufPtr++ = LineBuf[i++]; + } + } + + if ( ContinueCommand == FALSE ) + { + return Status; + } + } + } + + return Status; +} + + + +BOOL +TpctlParseCommand( + IN LPSTR CommandLine, + OUT LPSTR Argv[], + OUT PDWORD Argc, + IN DWORD MaxArgc + ) +{ + LPSTR cl = CommandLine; + DWORD ac = 0; + BOOL DoubleQuotesDetected, DetectedEndOfString, StartOfString; + + while ( *cl && (ac < MaxArgc) ) + { + // + // Skip to get to the lvalue + // + while ( *cl && (*cl <= ' ') ) // ignore leading blanks + { + cl++; + } + + if ( !*cl ) + { + break; + } + + // + // Argument detected. Initialize the Argv and increment the counter + // + + *Argv++ = cl; + ++ac; + + DoubleQuotesDetected = DetectedEndOfString = FALSE; + StartOfString = TRUE; + + while( !DetectedEndOfString ) + { + while ( *cl > ' ') + { + if ( StartOfString && (*cl == '"') && (*(cl-1) == '=') ) + { + DoubleQuotesDetected = TRUE; + StartOfString = FALSE; + } + cl++; + } + + if ( DoubleQuotesDetected ) + { + if ( ((*(cl-1) == '"') && (*(cl-2) != '\\')) || + ( *cl != ' ' ) ) + { + DetectedEndOfString = TRUE; + } + else + { + cl++; + } + } + else + { + DetectedEndOfString = TRUE; + } + } + + if ( *cl ) + { + *cl++ = '\0'; + } + + } + + if ( ac < MaxArgc ) + { + *Argv++ = NULL; + } + else if ( *cl ) + { + TpctlErrorLog("\n\tTpctl: Too many tokens in command; \"%s\".\n",(PVOID)cl); + return FALSE; + } + + *Argc = ac; + + return TRUE; +} + + + +VOID +TpctlPrompt( + LPSTR Prompt, + LPSTR Buffer, + DWORD BufferSize + ) + +// ----------- +// +// Routine Description: +// +// +// Arguments: +// +// Prompt - +// Buffer - +// BufferSize - +// +// Return Value: +// +// None. +// +// ---------- + +{ + LPSTR NewLine; + DWORD ReadAmount; + + // + // print out the prompt command, and then read the user's input. + // We are using the TpctlErrorLog routine to print it to the + // screen and the log files because we know that verbose mode + // + + TpctlErrorLog("%s ",Prompt); + + ReadFile( GetStdHandle(STD_INPUT_HANDLE), + (LPVOID )Buffer, + BufferSize, + &ReadAmount, + NULL ); + + // + // If the user typed , then the buffer contains a single + // character. We want to remove this character, and replace it with + // a nul character. + // + + if ( (NewLine = strchr(Buffer, '\r')) != NULL ) + { + *NewLine = '\0'; + } + +} + + + +VOID +TpctlLoadLastEnvironmentVariables( + DWORD OpenInstance + ) + +// -------------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// None. +// +// ------------- + +{ + GlobalCmdArgs.ARGS.ENV.WindowSize = + Open[OpenInstance].EnvVars->WindowSize; + + GlobalCmdArgs.ARGS.ENV.RandomBufferNumber = + Open[OpenInstance].EnvVars->RandomBufferNumber; + + GlobalCmdArgs.ARGS.ENV.StressDelayInterval = + Open[OpenInstance].EnvVars->StressDelayInterval; + + GlobalCmdArgs.ARGS.ENV.UpForAirDelay = + Open[OpenInstance].EnvVars->UpForAirDelay; + + GlobalCmdArgs.ARGS.ENV.StandardDelay = + Open[OpenInstance].EnvVars->StandardDelay; + + strcpy( GlobalCmdArgs.ARGS.ENV.StressAddress, + Open[OpenInstance].EnvVars->StressAddress ); + + strcpy( GlobalCmdArgs.ARGS.ENV.ResendAddress, + Open[OpenInstance].EnvVars->ResendAddress ); +} + + + +VOID +TpctlSaveNewEnvironmentVariables( + DWORD OpenInstance + ) + +// --------------- +// +// Routine Description: +// +// Arguments: +// +// None. +// +// Return Value: +// +// None. +// +// ------------- + +{ + Open[OpenInstance].EnvVars->WindowSize = + GlobalCmdArgs.ARGS.ENV.WindowSize; + + Open[OpenInstance].EnvVars->WindowSize = + GlobalCmdArgs.ARGS.ENV.RandomBufferNumber; + + Open[OpenInstance].EnvVars->StressDelayInterval = + GlobalCmdArgs.ARGS.ENV.StressDelayInterval; + + Open[OpenInstance].EnvVars->UpForAirDelay = + GlobalCmdArgs.ARGS.ENV.UpForAirDelay; + + Open[OpenInstance].EnvVars->StandardDelay = + GlobalCmdArgs.ARGS.ENV.StandardDelay; + + strcpy( Open[OpenInstance].EnvVars->StressAddress, + GlobalCmdArgs.ARGS.ENV.StressAddress ); + + strcpy( Open[OpenInstance].EnvVars->ResendAddress, + GlobalCmdArgs.ARGS.ENV.ResendAddress ); +} + + +// !!check calls here for WIN32!! + +VOID +TpctlPerformRegistryOperation( + IN PCMD_ARGS CmdArgs + ) +{ + DWORD Status,ValueType,ValueSize ; + DWORD ReadValueType, ReadValueSize; + DWORD Disposition , BytesWritten ; + PUCHAR ReadValue = NULL ; + UCHAR PrintStringBuffer[10], TmpChar; + HKEY DbaseHKey, KeyHandle ; + REGSAM SamDesired ; + LPSTR TmpBuf = GlobalBuf, StopString ; + LPSTR SubKeyName = &CmdArgs->ARGS.REGISTRY_ENTRY.SubKey[1] ; + LPSTR ValueName = &CmdArgs->ARGS.REGISTRY_ENTRY.SubKeyValueName[1]; + LPSTR Value = CmdArgs->ARGS.REGISTRY_ENTRY.SubKeyValue ; + LPSTR DbaseName = KeyDbaseTable[CmdArgs->ARGS.REGISTRY_ENTRY.OperationType].FieldName; + LPSTR ClassName = &CmdArgs->ARGS.REGISTRY_ENTRY.SubKeyClass[1] ; + LPSTR Tmp = NULL; + BOOL CompleteQueryStatus; + INT i,j,k,Radix = 16,CopyLength = 2; + + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCommandCode = %s\n", + TpctlGetCmdCode( CmdArgs->CmdCode )); + + // + // Initialize and allocate resources + // + + if ( (ReadValue = calloc( 2, MAX_VALUE_LENGTH )) == NULL ) + { + TpctlErrorLog( "\n\tTpctl: TpctlPeformRegistryOperation: Unable to allocate memory resources\n", NULL ); + return; + } + + // + // Clear and write the buffer responsible for extracting the values + // + + ZeroMemory ( PrintStringBuffer, sizeof( PrintStringBuffer ) ); + sprintf( PrintStringBuffer, "%%%d.%dx", sizeof(DWORD), sizeof(DWORD) ); + + // + // Set the appropriate DataBase key + // + + switch( CmdArgs->ARGS.REGISTRY_ENTRY.KeyDatabase ) + { + case CLASSES_ROOT : + DbaseHKey = HKEY_CLASSES_ROOT; + break; + + case CURRENT_USER : + DbaseHKey = HKEY_CURRENT_USER; + break; + + case LOCAL_MACHINE: + DbaseHKey = HKEY_LOCAL_MACHINE; + break; + + case USERS: + DbaseHKey = HKEY_USERS; + break; + + default: + TpctlErrorLog("\n\tTpctl: %d not a valid Key DataBase", + (PVOID)CmdArgs->ARGS.REGISTRY_ENTRY.KeyDatabase ); + return; + } + + // + // The SubKey Name + // The Value name + // The Class Name + // + if ( (Tmp = strrchr( SubKeyName, '"' )) != NULL ) + { + *Tmp = '\0'; + } + if ( (Tmp = strrchr( ValueName, '"' )) != NULL ) + { + *Tmp = '\0'; + } + if ( (Tmp = strrchr( ClassName, '"' )) != NULL ) + { + *Tmp = '\0'; + } + + // + // The value type and the associated value + // + + switch( CmdArgs->ARGS.REGISTRY_ENTRY.ValueType ) + { + case BINARY : + ValueType = REG_BINARY; + i = 0; + j = 0; // Default begin extraction from String[j=0]:Value buffer starting point + k = 0; // Default:Input Value is in hex or binary - designator. + // 0 is HEX, 1 is BINARY + ValueSize = strlen( Value ); + if( ValueSize >= 2 ) + { + if ( toupper( Value[1] ) == 'B' ) + { + j = 2; + k = 1; + Radix = 2; + CopyLength = 8; + } + } + { + UCHAR BitStream[9]; + PUCHAR PTmpChar; + DWORD BytesToCopy; + + while( j < (INT)ValueSize ) + { + memset( BitStream, '\0', sizeof( BitStream ) ); + memset( BitStream, '0' , sizeof(UCHAR)*CopyLength ); + BytesToCopy = min( strlen( &Value[j] ), (DWORD)CopyLength ); + memcpy( BitStream, &Value[j], BytesToCopy ); + Value[i] = (UCHAR)strtoul( BitStream,&PTmpChar, Radix ); + i++; + j += BytesToCopy; + } + ValueSize = i; + } + break; + + case DWORD_REGULAR : + ValueType = REG_DWORD; + ValueSize = sizeof( DWORD ); + *(LPDWORD)Value = strtoul( Value, &StopString, 0 ); + break; + + case DWORD_LITTLE_ENDIAN : + ValueType = REG_DWORD_LITTLE_ENDIAN; + ValueSize = sizeof( DWORD ); + { + DWORD TmpValue = strtoul( Value, &StopString, 0 ); + sprintf( Value, PrintStringBuffer, TmpValue ); + } + // Reverse the array since this is Big Endian + + for( i = 0, j = ValueSize-1; i < (INT)ValueSize; i++,j-- ) + { + Value[i] -= '0'; + Value[j] -= '0'; + TmpChar = Value[i]; + Value[i] = Value[j]; + Value[j] = TmpChar; + } + break; + + case DWORD_BIG_ENDIAN : + ValueType = REG_DWORD_BIG_ENDIAN; + ValueSize = sizeof( DWORD ); + { + DWORD TmpValue = strtoul( Value, &StopString, 0 ); + sprintf( Value, PrintStringBuffer, TmpValue ); + } + break; + + case EXPAND_SZ : + ValueType = REG_EXPAND_SZ; + ValueSize = strlen( Value ); + break; + + case LINK : + ValueType = REG_LINK; + ValueSize = strlen( Value ); + break; + + case MULTI_SZ : + ValueType = REG_MULTI_SZ; + + // + // The string Value needs to be readjusted. Use ReadValue as a temporary + // buffer + + memset( ReadValue, 0, 2*MAX_VALUE_LENGTH ); + { + UCHAR CanCopy = 0x0; + BOOL IgnoreNext = FALSE; + + for( i = 0, j = 0 ; i < (INT)strlen( Value ); i++ ) + { + if ( ( Value[i] == '"' ) && ( IgnoreNext == FALSE ) ) + { + CanCopy = ~CanCopy; + if ( !CanCopy ) + { + ReadValue[j++] = '\0'; + } + } + if ( Value[i] == '\\' ) + { + IgnoreNext = TRUE; + } + else + { + IgnoreNext = FALSE; + } + if ( CanCopy ) + { + ReadValue[j++] = Value[i]; + } + } + } + + // + // Fill the 2 nulls at the end of the array + // + + ReadValue[j++] = '\0';ReadValue[j++] = '\0'; + ValueSize = j; + memcpy( Value, ReadValue, j ); + memset( ReadValue, 0, 2*MAX_VALUE_LENGTH ); + break; + + case NONE : + ValueType = REG_NONE; + ValueSize = strlen( Value ); + break; + + case RESOURCE_LIST : + ValueType = REG_RESOURCE_LIST; + ValueSize = strlen( Value ); + break; + + case SZ : + ValueType = REG_SZ; + ValueSize = strlen( Value ); + break; + + default : + break; + + } + + // + // Switch to the demanded operation + // + + switch ( CmdArgs->ARGS.REGISTRY_ENTRY.OperationType ) + { + case ADD_KEY: + TmpBuf += (BYTE)sprintf( TmpBuf, "\tSubCommandCode = ADD_KEY\n" ); + + SamDesired = KEY_ALL_ACCESS; + + Status = RegCreateKeyEx( DbaseHKey, SubKeyName, (DWORD)0, + ClassName, REG_OPTION_NON_VOLATILE, + SamDesired, NULL, &KeyHandle, &Disposition ); + + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to create\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + SubKeyName, ClassName, DbaseName ); + break; + + } + + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = SUCCESS\n" ); + TmpBuf += (BYTE)sprintf( TmpBuf, "\tDisposition = " ); + + if ( Disposition == REG_CREATED_NEW_KEY ) + { + TmpBuf += (BYTE)sprintf( TmpBuf, "CREATED A NEW KEY\n" ); + } + else + { + TmpBuf += (BYTE)sprintf( TmpBuf, "KEY ALREADY EXISTS\n" ); + } + break; + + case DELETE_KEY: + TmpBuf += (BYTE)sprintf( TmpBuf, "\tSubCommandCode = DELETE_KEY\n" ); + + Status = RegDeleteKey( DbaseHKey, SubKeyName ); + if ( Status != ERROR_SUCCESS ) { + + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to delete\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + SubKeyName, ClassName, DbaseName ); + break; + + } + + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = SUCCESS\n" ); + break; + + + case QUERY_KEY: + + CompleteQueryStatus = TRUE; + + TmpBuf += (BYTE)sprintf( TmpBuf, "\tSubCommandCode = QUERY_KEY\n" ); + + // + // Open the Registry Key + // + + SamDesired = KEY_READ; + + Status = RegOpenKeyEx( DbaseHKey, SubKeyName, (DWORD)0, SamDesired, &KeyHandle ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to open\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + SubKeyName, ClassName, DbaseName ); + break; + + } + + { + LPSTR TmpKeyClassName = NULL, TmpSubKeyName = NULL, TmpValueName = NULL; + DWORD NumberOfSubKeys, NumberOfValues, TmpValueType, ClassNameSize; + DWORD TmpDwordVar, LongestSubKeyNameSize, LongestSubKeyClassNameSize; + DWORD LongestValueNameSize; + FILETIME LastWriteTime; + SYSTEMTIME SystemTime; + CHAR *DayOfWeek[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday" }; + + if ( (TmpKeyClassName = calloc( 1, MAX_PATH+1 )) == NULL ) + { + TpctlErrorLog( + "\n\tTpctl: TpctlPeformRegistryOperation: QueryKey unable to allocate memory resources\n", + NULL ); + return; + } + + ClassNameSize = MAX_PATH+1; + Status = RegQueryInfoKey( KeyHandle, TmpKeyClassName, &ClassNameSize, + NULL, &NumberOfSubKeys, &LongestSubKeyNameSize, + &LongestSubKeyClassNameSize, &NumberOfValues, + &LongestValueNameSize, + &TmpDwordVar, &TmpDwordVar, &LastWriteTime ); + + if ( (Status == ERROR_MORE_DATA) || (Status == ERROR_INSUFFICIENT_BUFFER) ) + { + free( TmpKeyClassName ); + if ( (TmpKeyClassName = calloc( 1, ClassNameSize+2 )) == NULL ) + { + TpctlErrorLog( "\n\tTpctl: TpctlPeformRegistryOperation: QueryKey unable to allocate memory resources\n", NULL ); + return; + } + Status = RegQueryInfoKey( KeyHandle, TmpKeyClassName, &ClassNameSize, + NULL, &NumberOfSubKeys, &LongestSubKeyNameSize, + &LongestSubKeyClassNameSize, &NumberOfValues, + &LongestValueNameSize, + &TmpDwordVar, &TmpDwordVar, &LastWriteTime ); + } + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to QueryInfo on\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + SubKeyName, ClassName, DbaseName ); + break; + } + + TmpBuf += sprintf( TmpBuf, + "\tKey Class Name = %s\n\tNumber Of SubKeys = %ld\n\tNumber of Values = %ld\n", + TmpKeyClassName, NumberOfSubKeys, NumberOfValues ); + + if ( FileTimeToSystemTime( &LastWriteTime, &SystemTime ) ) + { + TmpBuf += sprintf( TmpBuf, + "\tLast Write Time = %s %2.2d-%2.2d-%4.4d at %2.2d:%2.2d:%2.2d %s\n", + DayOfWeek[SystemTime.wDayOfWeek], + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wYear, + ((SystemTime.wHour > 12) ? (SystemTime.wHour-12) + : SystemTime.wHour), + SystemTime.wMinute, + SystemTime.wSecond, + ((SystemTime.wHour > 12) ? "AM" : "PM") ); + } + else + { + TmpBuf += sprintf( TmpBuf, "\tLast Write Time = Undefined\n" ); + } + + free( TmpKeyClassName ); + + if ( (TmpSubKeyName = calloc( 1, LongestSubKeyNameSize+2 )) == NULL ) + { + TpctlErrorLog( "\n\tTpctl: TpctlPeformRegistryOperation: QueryKey unable to allocate memory resources\n", NULL ); + return; + } + + TmpBuf += sprintf( TmpBuf, "\tSub Key Name(s)\n" ); + + for( i = 0; i < (INT)NumberOfSubKeys; i++ ) + { + memset( TmpSubKeyName, 0, LongestSubKeyNameSize+2 ); + Status = RegEnumKey( KeyHandle, i, TmpSubKeyName, LongestSubKeyNameSize+2 ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to Enumerate Key Index %d from\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + i, SubKeyName, ClassName, DbaseName ); + CompleteQueryStatus = FALSE; + } + else + { + TmpBuf += sprintf( TmpBuf, "\t%2d.\t%s\n", i, TmpSubKeyName ); + } + } + + free( TmpSubKeyName ); + + if ( (TmpValueName = calloc( 1, LongestValueNameSize+2 )) == NULL ) + { + TpctlErrorLog( "\n\tTpctl: TpctlPeformRegistryOperation: QueryKey unable to allocate memory resources\n", NULL ); + return; + } + + TmpBuf += sprintf( TmpBuf, "\tSub Key Value Name(s) and Associated Type(s)\n" ); + + for( i = 0; i < (INT)NumberOfValues; i++ ) + { + memset( TmpValueName, 0, LongestValueNameSize+2 ); + TmpDwordVar = LongestValueNameSize+2; + Status = RegEnumValue( KeyHandle, i, TmpValueName, &TmpDwordVar, NULL, + &TmpValueType, NULL, NULL ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to Enumerate Value Index %d from\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + i, SubKeyName, ClassName, DbaseName ); + CompleteQueryStatus = FALSE; + } + else + { + TmpBuf += sprintf( TmpBuf, + "\t%2d.\t%-30s%-15s\n", i, TmpValueName, TpctlGetValueType( TmpValueType ) ); + + } + } + + free( TmpValueName ); + + } + + if ( CompleteQueryStatus ) + { + TmpBuf += (BYTE)sprintf( TmpBuf, "\tComplete Query Status = SUCCESS\n" ); + } + else + { + TmpBuf += (BYTE)sprintf( TmpBuf, "\tComplete Query Status = FAILURE\n" ); + } + break; + + case ADD_VALUE: + case CHANGE_VALUE: + if ( CmdArgs->ARGS.REGISTRY_ENTRY.OperationType == CHANGE_VALUE ) + { + TmpBuf += (BYTE)sprintf( TmpBuf, "\tSubCommandCode = CHANGE_VALUE\n" ); + SamDesired = KEY_WRITE|KEY_READ; + } + else + { + TmpBuf += (BYTE)sprintf( TmpBuf, "\tSubCommandCode = ADD_VALUE\n" ); + SamDesired = KEY_ALL_ACCESS; + } + + + Status = RegOpenKeyEx( DbaseHKey, SubKeyName, (DWORD)0, SamDesired, &KeyHandle ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to open\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + SubKeyName, ClassName, DbaseName ); + break; + + } + + // + // If this is a request to change a value, make sure that the value exists + // + + if ( CmdArgs->ARGS.REGISTRY_ENTRY.OperationType == CHANGE_VALUE ) + { + // + // Make sure the ValueName exist since this is a change request + // + ReadValueSize = 2*MAX_VALUE_LENGTH; + ReadValueType = ValueType; + Status = RegQueryValueEx( KeyHandle, ValueName, (DWORD)0, &ReadValueType, + ReadValue, &ReadValueSize ); + if ( (Status != ERROR_SUCCESS) && + (Status != ERROR_MORE_DATA) && + (Status != ERROR_INSUFFICIENT_BUFFER) ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, +"\n\tTpctl: Unable to access\n\tValue : %s\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + ValueName, SubKeyName, ClassName, DbaseName ); + break; + + } + } + + // + // Now set the values as expected + // + Status = RegSetValueEx( KeyHandle, ValueName, (DWORD)0, ValueType, Value, ValueSize ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, +"\n\tTpctl: Unable to change\n\tValue : %s\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + ValueName, SubKeyName, ClassName, DbaseName ); + break; + + } + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = SUCCESS\n" ); + break; + + + case DELETE_VALUE: + TmpBuf += (BYTE)sprintf( TmpBuf, "\tSubCommandCode = DELETE_VALUE\n" ); + + // + // Open the Registry Key + // + SamDesired = KEY_SET_VALUE; + + Status = RegOpenKeyEx( DbaseHKey, SubKeyName, (DWORD)0, SamDesired, &KeyHandle ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to open\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + SubKeyName, ClassName, DbaseName ); + break; + + } + + Status = RegDeleteValue( KeyHandle, ValueName ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, +"\n\tTpctl: Unable to delete\n\tValue : %s\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + ValueName, SubKeyName, ClassName, DbaseName ); + break; + + } + + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = SUCCESS\n" ); + break; + + case QUERY_VALUE: + TmpBuf += (BYTE)sprintf( TmpBuf, "\tSubCommandCode = QUERY_VALUE\n" ); + + // + // Open the Registry Key + // + SamDesired = KEY_QUERY_VALUE; + + Status = RegOpenKeyEx( DbaseHKey, SubKeyName, (DWORD)0, SamDesired, &KeyHandle ); + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, + "\n\tTpctl: Unable to open\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + SubKeyName, ClassName, DbaseName ); + break; + } + + // + // Make sure the ValueName exist since this is a change request + // + + ReadValueSize = 2*MAX_VALUE_LENGTH; + Status = RegQueryValueEx( KeyHandle, ValueName, (DWORD)0, &ReadValueType, + ReadValue, &ReadValueSize ); + + if ( (Status == ERROR_MORE_DATA) || (Status == ERROR_INSUFFICIENT_BUFFER) ) + { + free( ReadValue ); + ReadValue = NULL; + ReadValue = calloc( 1, ReadValueSize+1 ); + if ( ReadValue == NULL ) + { + TpctlErrorLog( + "\n\tTpctl: TpctlPeformRegistryOperation: QueryValue unable to allocate memory resources\n", + NULL ); + return; + } + Status = RegQueryValueEx( KeyHandle, ValueName, (DWORD)0, &ReadValueType, + ReadValue, &ReadValueSize ); + } + + if ( Status != ERROR_SUCCESS ) + { + TmpBuf += (BYTE)sprintf( TmpBuf,"\tStatus = %ldL\n", Status ); + TmpBuf += (BYTE)sprintf( TmpBuf, +"\n\tTpctl: Unable to access\n\tValue : %s\n\tSubkey : %s\n\tClassName: %s\n\tDatabase : %s\n", + ValueName, SubKeyName, ClassName, DbaseName ); + break; + + } + + TmpBuf += (BYTE)sprintf( TmpBuf, "\tStatus = SUCCESS\n" ); + TmpBuf = TpctlEnumerateRegistryInfo( TmpBuf, DbaseName, SubKeyName, ValueName, + ReadValueType, ReadValue, ReadValueSize ); + break; + + + default: + break; + + } + + // + // Close any open keys and deallocate any allocated resources + // + + RegCloseKey( KeyHandle ); + free( ReadValue ); + + + // + // Print the buffer + // + + if ( Verbose ) + { + if ( !WriteFile(GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) + { + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } + else if ( CommandLineLogging ) + { + if ( !WriteFile(CommandLineLogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } + + // + // Free up resources + // + free( ReadValue ); + +} + + + +BOOL +TpctlInitCommandBuffer( + OUT PCMD_ARGS CmdArgs, + IN DWORD CmdCode + ) + +// ------------------- +// +// Routine Description: +// +// Initialize the cmd buffer to be passed to the driver with the arguments +// read from the command line or the script file. +// +// Arguments: +// +// CmdArgs - The buffer to store the arguments in. +// +// CmdCode - The command that is being issued, and therefore the command +// to write the arguments for into the buffer. +// Return Value: +// +// BOOL - TRUE if the OpenInstance is valid and all the arguments are +// written to the buffer, FALSE otherwise. +// +// ---------------- + +{ + LPBYTE p, q, s, t; + DWORD i, j; + DWORD OidIndex; + + // + // If the OpenInstance is invalid return immediately. + // + switch ( CmdCode ) + { + case SETENV : + case GO : + case PAUSE : + case OPEN : + case CLOSE : + case QUERYINFO : + case SETPF : + case SETLA : + case ADDMA : + case DELMA : + case SETFA : + case SETGA : + case SETINFO : + case RESET : + case STOPSEND : + case WAITSEND : + case RECEIVE : + case STOPREC : + case GETEVENTS : + case STRESSSERVER: + case ENDSTRESS : + case WAITSTRESS : + case CHECKSTRESS : + case SEND : + case STRESS : + case PERFSERVER: + case PERFCLIENT: + if (( GlobalCmdArgs.OpenInstance < 1 ) || + ( GlobalCmdArgs.OpenInstance > NUM_OPEN_INSTANCES )) + { + TpctlErrorLog("\n\tTpctl: %d not a valid Open Instance Value ", + (PVOID)GlobalCmdArgs.OpenInstance); + TpctlErrorLog("(1-%d).\n", (PVOID)NUM_OPEN_INSTANCES); + return FALSE; + } + + default: + break; + + } + + + // + // Otherwise let's stuff the arguments into the buffer. + // + + CmdArgs->CmdCode = CmdCode; + CmdArgs->OpenInstance = GlobalCmdArgs.OpenInstance; + + // + // Now do the command dependant stuff. + // + + switch( CmdCode ) + { + case SETENV: + + CmdArgs->ARGS.ENV.WindowSize = + GlobalCmdArgs.ARGS.ENV.WindowSize; + + CmdArgs->ARGS.ENV.RandomBufferNumber = + GlobalCmdArgs.ARGS.ENV.RandomBufferNumber; + + CmdArgs->ARGS.ENV.StressDelayInterval = + GlobalCmdArgs.ARGS.ENV.StressDelayInterval; + + CmdArgs->ARGS.ENV.UpForAirDelay = + GlobalCmdArgs.ARGS.ENV.UpForAirDelay; + + CmdArgs->ARGS.ENV.StandardDelay = + GlobalCmdArgs.ARGS.ENV.StandardDelay; + + p = CmdArgs->ARGS.ENV.StressAddress; + q = GlobalCmdArgs.ARGS.ENV.StressAddress; + + s = CmdArgs->ARGS.ENV.ResendAddress; + t = GlobalCmdArgs.ARGS.ENV.ResendAddress; + + for( i=0;iARGS.FILES.LogFile,GlobalCmdArgs.ARGS.FILES.LogFile ); + break; + + case RECORDINGENABLE: + strcpy( CmdArgs->ARGS.RECORD.ScriptFile,GlobalCmdArgs.ARGS.RECORD.ScriptFile ); + break; + + case GO: + case PAUSE: + p = CmdArgs->ARGS.PAUSE_GO.RemoteAddress; + q = GlobalCmdArgs.ARGS.PAUSE_GO.RemoteAddress; + + for( i=0;iARGS.PAUSE_GO.TestSignature = + GlobalCmdArgs.ARGS.PAUSE_GO.TestSignature; + + srand(TpctlSeed); + CmdArgs->ARGS.PAUSE_GO.UniqueSignature = TpctlSeed = rand(); + break; + + case OPEN: + strcpy( CmdArgs->ARGS.OPEN_ADAPTER.AdapterName, + GlobalCmdArgs.ARGS.OPEN_ADAPTER.AdapterName ); + CmdArgs->ARGS.OPEN_ADAPTER.NoArcNet = 0; + if (getenv( "NOARCNET" )) + { + CmdArgs->ARGS.OPEN_ADAPTER.NoArcNet = 1; + } + break; + + case QUERYINFO: + OidIndex = TpLookUpOidInfo( GlobalCmdArgs.ARGS.TPQUERY.OID ); + + if (( OidIndex == -1 ) || ( OidArray[OidIndex].QueryInfo != TRUE )) + { + TpctlErrorLog("\n\tTpctl: 0x%08lX not a valid NdisRequestQueryInformation OID.\n", + (PVOID)GlobalCmdArgs.ARGS.TPQUERY.OID); + return FALSE; + } + CmdArgs->ARGS.TPQUERY.OID = GlobalCmdArgs.ARGS.TPQUERY.OID; + break; + + case SETPF: + case SETLA: + case ADDMA: + case SETFA: + case SETGA: + case SETINFO: + CmdArgs->ARGS.TPSET.OID = 0x0; + + // + // Sanjeevk: Performed a scrub on the multiple if. Bug #5203 + // + + switch ( CmdCode ) + { + case SETINFO: + CmdArgs->ARGS.TPSET.OID = GlobalCmdArgs.ARGS.TPSET.OID; + break; + + case SETPF: + CmdArgs->ARGS.TPSET.OID = OID_GEN_CURRENT_PACKET_FILTER; + break; + + case SETLA: + CmdArgs->ARGS.TPSET.OID = OID_GEN_CURRENT_LOOKAHEAD; + break; + case ADDMA: + if ( Open[CmdArgs->OpenInstance-1].MediumType == NdisMedium802_3 ) + { + CmdArgs->ARGS.TPSET.OID = OID_802_3_MULTICAST_LIST; + } + else + { + // + // Only FDDI and 802.3 permit multicast addressing. Since the + // medium is not 802.3, it must be FDDI + // + CmdArgs->ARGS.TPSET.OID = OID_FDDI_LONG_MULTICAST_LIST; + } + break; + + case SETFA: + CmdArgs->ARGS.TPSET.OID = OID_802_5_CURRENT_FUNCTIONAL; + break; + + case SETGA: + CmdArgs->ARGS.TPSET.OID = OID_802_5_CURRENT_GROUP; + break; + + default: + break; + } + + switch ( CmdArgs->ARGS.TPSET.OID ) + { + case OID_GEN_CURRENT_PACKET_FILTER: + CmdArgs->ARGS.TPSET.U.PacketFilter = + GlobalCmdArgs.ARGS.TPSET.U.PacketFilter; + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + CmdArgs->ARGS.TPSET.U.LookaheadSize = + GlobalCmdArgs.ARGS.TPSET.U.LookaheadSize; + break; + + case OID_802_3_MULTICAST_LIST: + case OID_FDDI_LONG_MULTICAST_LIST: + { + PMULT_ADDR NextMultAddr; + DWORD OI = GlobalCmdArgs.OpenInstance - 1; + + p = CmdArgs->ARGS.TPSET.U.MulticastAddress[0]; + q = GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0]; + + for ( i=0;iARGS.TPSET.U.MulticastAddress[j++]; + + for ( i=0;iMulticastAddress[i]; + } + + NextMultAddr = NextMultAddr->Next; + } + CmdArgs->ARGS.TPSET.NumberMultAddrs = Open[OI].NumberMultAddrs + 1; + break; + } + + case OID_802_5_CURRENT_FUNCTIONAL: + case OID_802_5_CURRENT_GROUP: + p = CmdArgs->ARGS.TPSET.U.FunctionalAddress; + q = GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress; + + for ( i=0;iOpenInstance - 1; + BOOL AddressFound = FALSE; + + j = 0; + + // + // Copy the addresses that do not match the one to be deleted into + // the multicast list buffer to be reset. + // + + // + // Sanjeevk: Another change point. Bug #5203 + // + if ( Open[CmdArgs->OpenInstance-1].MediumType == NdisMedium802_3 ) + { + CmdArgs->ARGS.TPSET.OID = OID_802_3_MULTICAST_LIST; + } + else + { + // + // Only FDDI and 802.3 permit multicast addressing. Since the + // medium is not 802.3, it must be FDDI + // + CmdArgs->ARGS.TPSET.OID = OID_FDDI_LONG_MULTICAST_LIST; + } + + CmdArgs->ARGS.TPSET.NumberMultAddrs = 0; + NextMultAddr = Open[OI].MulticastAddresses; + + while ( NextMultAddr != NULL ) + { + if ( memcmp(GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0], + NextMultAddr->MulticastAddress, + ADDRESS_LENGTH) != 0 ) + { + p = CmdArgs->ARGS.TPSET.U.MulticastAddress[j++]; + + for ( i=0;iMulticastAddress[i]; + } + + CmdArgs->ARGS.TPSET.NumberMultAddrs++; + + } + else + { + AddressFound = TRUE; + } + + NextMultAddr = NextMultAddr->Next; + } + + if ( AddressFound == FALSE ) + { + TpctlErrorLog("\n\tTpctl: The multicast address %02X", + (PVOID)GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0][0]); + TpctlErrorLog("-%02X", + (PVOID)GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0][1]); + TpctlErrorLog("-%02X", + (PVOID)GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0][2]); + TpctlErrorLog("-%02X", + (PVOID)GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0][3]); + TpctlErrorLog("-%02X", + (PVOID)GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0][4]); + TpctlErrorLog("-%02X has not been added.\n", + (PVOID)GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0][5]); + + // + // We will let the call go thru since we expect the driver to agree + // with our findings which is the MA which is being deleted is not present + // + // + } + break; + } + + case SEND: + p = CmdArgs->ARGS.TPSEND.DestAddress; + q = GlobalCmdArgs.ARGS.TPSEND.DestAddress; + s = CmdArgs->ARGS.TPSEND.ResendAddress; + t = GlobalCmdArgs.ARGS.TPSEND.ResendAddress; + + for ( i=0;iARGS.TPSEND.PacketSize = + GlobalCmdArgs.ARGS.TPSEND.PacketSize; + + CmdArgs->ARGS.TPSEND.NumberOfPackets = + GlobalCmdArgs.ARGS.TPSEND.NumberOfPackets; + + break; + + case STRESS: + + CmdArgs->ARGS.TPSTRESS.MemberType = + GlobalCmdArgs.ARGS.TPSTRESS.MemberType; + + CmdArgs->ARGS.TPSTRESS.PacketType = + GlobalCmdArgs.ARGS.TPSTRESS.PacketType; + + CmdArgs->ARGS.TPSTRESS.PacketSize = + GlobalCmdArgs.ARGS.TPSTRESS.PacketSize; + + CmdArgs->ARGS.TPSTRESS.PacketMakeUp = + GlobalCmdArgs.ARGS.TPSTRESS.PacketMakeUp; + + CmdArgs->ARGS.TPSTRESS.ResponseType = + GlobalCmdArgs.ARGS.TPSTRESS.ResponseType; + + CmdArgs->ARGS.TPSTRESS.DelayType = + GlobalCmdArgs.ARGS.TPSTRESS.DelayType; + + CmdArgs->ARGS.TPSTRESS.DelayLength = + GlobalCmdArgs.ARGS.TPSTRESS.DelayLength; + + CmdArgs->ARGS.TPSTRESS.TotalIterations = + GlobalCmdArgs.ARGS.TPSTRESS.TotalIterations; + + CmdArgs->ARGS.TPSTRESS.TotalPackets = + GlobalCmdArgs.ARGS.TPSTRESS.TotalPackets; + + CmdArgs->ARGS.TPSTRESS.WindowEnabled = + GlobalCmdArgs.ARGS.TPSTRESS.WindowEnabled; + + CmdArgs->ARGS.TPSTRESS.DataChecking = + GlobalCmdArgs.ARGS.TPSTRESS.DataChecking; + + CmdArgs->ARGS.TPSTRESS.PacketsFromPool = + GlobalCmdArgs.ARGS.TPSTRESS.PacketsFromPool; + + break; + + + case REGISTRY : + CmdArgs->ARGS.REGISTRY_ENTRY.OperationType = + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.OperationType ; + CmdArgs->ARGS.REGISTRY_ENTRY.KeyDatabase = + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.KeyDatabase ; + CmdArgs->ARGS.REGISTRY_ENTRY.ValueType = + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.ValueType ; + + strcpy( CmdArgs->ARGS.REGISTRY_ENTRY.SubKey , + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKey ); + strcpy( CmdArgs->ARGS.REGISTRY_ENTRY.SubKeyClass , + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyClass ); + + strcpy( CmdArgs->ARGS.REGISTRY_ENTRY.SubKeyValueName, + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyValueName ); + strcpy( CmdArgs->ARGS.REGISTRY_ENTRY.SubKeyValue, + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyValue ); + + break; + + + case PERFCLIENT: + p = CmdArgs->ARGS.TPPERF.PerfServerAddr; + q = GlobalCmdArgs.ARGS.TPPERF.PerfServerAddr; + s = CmdArgs->ARGS.TPPERF.PerfSendAddr; + t = GlobalCmdArgs.ARGS.TPPERF.PerfSendAddr; + + for ( i=0;iARGS.TPPERF.PerfPacketSize = GlobalCmdArgs.ARGS.TPPERF.PerfPacketSize; + CmdArgs->ARGS.TPPERF.PerfNumPackets = GlobalCmdArgs.ARGS.TPPERF.PerfNumPackets; + CmdArgs->ARGS.TPPERF.PerfDelay = GlobalCmdArgs.ARGS.TPPERF.PerfDelay; + CmdArgs->ARGS.TPPERF.PerfMode = GlobalCmdArgs.ARGS.TPPERF.PerfMode; + break; + + case CLOSE: + case RESET: + case STOPSEND: + case WAITSEND: + case RECEIVE: + case STOPREC: + case GETEVENTS: + case STRESSSERVER: + case ENDSTRESS: + case WAITSTRESS: + case CHECKSTRESS: + case WAIT: + case VERBOSE: + case BREAKPOINT: + case QUIT: + case HELP: + case SHELL: + case RECORDINGDISABLE: + case DISABLE: + case ENABLE: + case PERFSERVER: + break; + + default: + TpctlErrorLog("TpctlInitCommandBuffer: Invalid Command code.\n",NULL); + break; + + } // switch(); + + return TRUE; +} + + + +LPSTR +TpctlGetEventType( + TP_EVENT_TYPE TpEventType + ) +{ + static TP_EVENT_TYPE Event[] = { + CompleteOpen, + CompleteClose, + CompleteSend, + CompleteTransferData, + CompleteReset, + CompleteRequest, + IndicateReceive, + IndicateReceiveComplete, + IndicateStatus, + IndicateStatusComplete, + Unknown + }; + +#define EventCount (sizeof(Event)/sizeof(TP_EVENT_TYPE)) + + static LPSTR EventString[] = { // BUGUBUG Add new events open close... + "NdisCompleteOpen", + "NdisCompleteClose", + "NdisCompleteSend", + "NdisCompleteTransferData", + "NdisCompleteReset", + "NdisCompleteRequest", + "NdisIndicateReceive", + "NdisIndicateReceiveComplete", + "NdisIndicateStatus", + "NdisIndicateStatusComplete", + "Unknown Function" + }; + + static BYTE BadEvent[] = "UNDEFINED"; + DWORD i; + + + for (i=0; iInformationBuffer + sizeof( NDIS_MEDIUM ) ); + Destination = (PUCHAR)( Open[OpenInstance].AdapterAddress ); + + for (i=0;i + +#include +#include +#include +#include + +#include + +extern VOID printf(UCHAR *,...); +// extern LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER); + +#define MAX_CPUS 64 // supports maximum of 64 cpus... + +// #include "tpdefs.h" +// #include "media.h" +// #include "tpprocs.h" +// #include "string.h" + +PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pStartData; +PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pEndData; +ULONG NumCpus; +ULONG ProcessorBufSize; +PULONG pKernelPercent; +DWORD StartTestTime; + +// -------------------------------------------------- +// +// Function: TpPerfInitCpuUsage +// +// Arguments: none +// +// Returns: none +// +// Descript: This function allocates and initializes all the structures +// necessary for finding the %cpu usage during performance tests +// +// -------------------------------------------------- + + +VOID +CpuUsageInit(VOID) +{ + if (!NumCpus) // if NumCpus is zero, need to do first pass initializations + { // (allocate all buffers, set NumCpus) + + SYSTEM_BASIC_INFORMATION BasicInfo; + + // + // First get the number of processors... + // + + NtQuerySystemInformation(SystemBasicInformation, + &BasicInfo, + sizeof(SYSTEM_BASIC_INFORMATION), + NULL); + + NumCpus = BasicInfo.NumberOfProcessors; + if ( (NumCpus < 1) || (NumCpus > MAX_CPUS) ) + { + printf("CpuUsageInit: Illegal number of cpus\n"); + goto init_abort; + } + + // + // get the memory for the processor instance data + // + + ProcessorBufSize = NumCpus * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); + + if ( (pStartData = GlobalAlloc(GMEM_FIXED, ProcessorBufSize)) == NULL) + { + printf("CpuUsageInit: unable to allocate pStartData buffer\n"); + goto init_abort; + } + + if ( (pEndData = GlobalAlloc(GMEM_FIXED, ProcessorBufSize)) == NULL) + { + printf("CpuUsageInit: unable to allocate pEndData buffer\n"); + goto init_abort; + } + + if ( (pKernelPercent = GlobalAlloc(GMEM_FIXED , (NumCpus + 1) * sizeof(ULONG))) == NULL) + { + printf("CpuUsageInit: unable to allocate pKernelPercent buffer\n"); +init_abort: + if (pStartData) + { + GlobalFree(pStartData); +// pStartData = NULL; + } + if (pEndData) + { + GlobalFree(pEndData); +// pEndData = NULL + } + if (pKernelPercent) + { + GlobalFree(pKernelPercent); +// pKernelPercent = NULL; + } + NumCpus = 0; + return; + } + } + + NtQuerySystemInformation(SystemProcessorPerformanceInformation, + pStartData, + ProcessorBufSize, + NULL); + StartTestTime = GetTickCount(); + +} + + +// ------------------------------------------------ +// +// Function: TpPerfGetCpuUsage +// +// Arguments: oldptr -- cpu processor performance data from time 0 +// ProcessorTime -- place to put processor times +// KernelTime -- place to put kernel times +// +// Returns: number of processors--0 if error +// +// Descript: This function reads the performance counters +// at the end of the test, stored them in an appropriate +// location, and then cleans up the structures and exits +// +// ------------------------------------------------- + + +ULONG +CpuUsageGetData(PULONG *ppKernPC, + ULONG TestTime) +{ + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *pOldProcessorInformation; + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *pNewProcessorInformation; + ULONG CurProc; + LARGE_INTEGER TotalProcessorTime; + LARGE_INTEGER TotalKernelTime; + LARGE_INTEGER TempUser; + LARGE_INTEGER TempKern; + LARGE_INTEGER TempIdle; + LARGE_INTEGER trash; + LARGE_INTEGER WholeTestTime; + DWORD EndTestTime; + ULONG flag; + + if (!NumCpus) + { + printf("CpuUsageGetData: called before initialization\n"); + return 0; + } + + + NtQuerySystemInformation(SystemProcessorPerformanceInformation, + pEndData, + ProcessorBufSize, + NULL); + // + // find the total time in milliseconds + // + EndTestTime = GetTickCount(); +// if (EndTestTime > StartTestTime) +// { + WholeTestTime.LowPart = EndTestTime - StartTestTime; +// } +// else +// { +// +// } +// WholeTestTime.LowPart = GetTickCount() - StartTestTime; + WholeTestTime.HighPart = 0; +// printf("Kludge factor = %d/%d\n", TestTime, WholeTestTime.LowPart); + + TotalProcessorTime.HighPart = 0; + TotalProcessorTime.LowPart = 0; + TotalKernelTime.HighPart = 0; + TotalKernelTime.LowPart = 0; + + // + // Total time = UserTime + KernelTime + // KernelTime = IdleTime + Priviledged time + // We need total time and priviledged time + // + + pOldProcessorInformation = pStartData; + pNewProcessorInformation = pEndData; + + for ( CurProc = 0; CurProc < NumCpus; CurProc++ ) + { +// DEBUG +// printf("\nCpuUsageGetData: processor %d\n", CurProc); +// printf("Initial Idletime = %08x%08x\n", pOldProcessorInformation->IdleTime.HighPart, +// pOldProcessorInformation->IdleTime.LowPart); +// printf("Initial Usertime = %08x%08x\n", pOldProcessorInformation->UserTime.HighPart, +// pOldProcessorInformation->UserTime.LowPart); +// printf("Initial Kerntime = %08x%08x\n\n", pOldProcessorInformation->KernelTime.HighPart, +// pOldProcessorInformation->KernelTime.LowPart); +// +// printf("Final Idletime = %08x%08x\n", pNewProcessorInformation->IdleTime.HighPart, +// pNewProcessorInformation->IdleTime.LowPart); +// printf("Final Usertime = %08x%08x\n", pNewProcessorInformation->UserTime.HighPart, +// pNewProcessorInformation->UserTime.LowPart); +// printf("Final Kerntime = %08x%08x\n\n", pNewProcessorInformation->KernelTime.HighPart, +// pNewProcessorInformation->KernelTime.LowPart); +// END DEBUG + + // first, find all the deltas... + + TempUser = RtlLargeIntegerSubtract(pNewProcessorInformation->UserTime, + pOldProcessorInformation->UserTime); + TempKern = RtlLargeIntegerSubtract(pNewProcessorInformation->KernelTime, + pOldProcessorInformation->KernelTime); + TempIdle = RtlLargeIntegerSubtract(pNewProcessorInformation->IdleTime, + pOldProcessorInformation->IdleTime); + // check for wrapping +// if (pOldProcessor->UserTime.HighPart > pNewProcessorInformation->UserTime.HighPart) +// { +// +// } + +// printf("Delta IdleTime = %08x%08x\n", TempIdle.HighPart, TempIdle.LowPart); +// printf("Delta UserTime = %08x%08x\n", TempUser.HighPart, TempUser.LowPart); +// printf("Delta KernTime = %08x%08x\n", TempKern.HighPart, TempKern.LowPart); + + // now find the total processor time = UserTime + KernelTime + + TempUser = RtlLargeIntegerAdd(TempUser, TempKern); + +// printf("Total ProcTime = %08x%08x\n", TempUser.HighPart, TempUser.LowPart); + + // adjust by kludge factor -- TestTime/WholeTestTime + + TempUser = RtlExtendedIntegerMultiply(TempUser, TestTime); + TempUser = RtlLargeIntegerDivide(TempUser, WholeTestTime, &trash); + + if ((TempUser.HighPart == 0) && (TempUser.LowPart < 10)) // sanity check + { + flag = 0; + printf("Kludge factor = %d/%d\n", TestTime, WholeTestTime.LowPart); + printf("Adjusted ProcTime = %08x%08x\n", TempUser.HighPart, TempUser.LowPart); + } + else + { + flag = 1; + } + + TotalProcessorTime = RtlLargeIntegerAdd(TotalProcessorTime, TempUser); + + // now find the true kernel time = KernelTime - IdleTime + + TempKern = RtlLargeIntegerSubtract(TempKern, TempIdle); + +// printf("True KernTime = %08x%08x\n", TempKern.HighPart, TempKern.LowPart); + + if (TempKern.HighPart < 0) + { + TempKern.HighPart = 0; + TempKern.LowPart = 0; + } + TotalKernelTime = RtlLargeIntegerAdd(TotalKernelTime, TempKern); + + // + // finally, calc the percent kernel is of total + // + + if (flag) + { + TempKern = RtlExtendedIntegerMultiply(TempKern, 1000); + TempKern = RtlLargeIntegerDivide(TempKern, TempUser, &trash); + } + else + { + TempKern.LowPart = 0; + } + pKernelPercent[CurProc+1] = TempKern.LowPart; + + // move to info for next processor + + pNewProcessorInformation++; + pOldProcessorInformation++; + } + + // + // last of all, calc the percent kernel is of total + // + if ((TotalProcessorTime.HighPart == 0) && (TotalProcessorTime.LowPart < 10)) + { + TempKern.LowPart = 0; + } + else + { + TempKern = RtlExtendedIntegerMultiply(TotalKernelTime, 1000); + TempKern = RtlLargeIntegerDivide(TempKern, TotalProcessorTime, &trash); + } + pKernelPercent[0] = TempKern.LowPart; + + *ppKernPC = pKernelPercent; + + return NumCpus; +} + diff --git a/private/ntos/ndis/testprot/tpctl/globals.c b/private/ntos/ndis/testprot/tpctl/globals.c new file mode 100644 index 000000000..49f9c5d6e --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/globals.c @@ -0,0 +1,390 @@ +// ****************************************************************** +// +// Copyright (c) 1991 Microsoft Corporation +// +// Module Name: +// +// globals.c +// +// Abstract: +// +// This module contains the routines for parsing global variables entered from +// the command line or read from script files. +// +// Author: +// +// Tim Wynsma (timothyw) 5-18-94 +// +// Revision History: +// +// ****************************************************************** + + +#include +#include +#include + +#include + + +#include +#include +#include +#include + +#include "tpctl.h" +#include "parse.h" + +typedef struct _GLOBALS +{ + // String variables + + UCHAR TestCard[64]; + UCHAR TrustedCard[64]; + + // Address6 variables + + UCHAR TestCardAddress[6]; + UCHAR TrustedCardAddress[6]; + UCHAR MulticastAddress[6]; + UCHAR MulticastAddress2[6]; + UCHAR BroadcastAddress[6]; + UCHAR RandomAddress[6]; + UCHAR RemoteTestCardAddress[6]; + UCHAR RemoteTrustedCardAddress[6]; + + // Address4 variables + + UCHAR FunctionalAddress[4]; + UCHAR FunctionalAddress2[4]; + + // Integer variables + + ULONG MaxFrameSize; + ULONG MaxLookaheadSize; + +} GLOBALS; + +GLOBALS glob; + +typedef struct _GLOBALVAR +{ + PUCHAR varname; + PARAMTYPES vartype; + PVOID varaddress; +} GLOBALVAR, *PGLOBALVAR; + + +GLOBALVAR globalvars[] = + { { "test_card", String, glob.TestCard }, + { "trusted_card", String, glob.TrustedCard }, + { "test_card_address", Address6, glob.TestCardAddress }, + { "trusted_card_address", Address6, glob.TrustedCardAddress }, + { "multicast_address", Address6, glob.MulticastAddress }, + { "multicast_address2", Address6, glob.MulticastAddress2 }, + { "broadcast_address", Address6, glob.BroadcastAddress }, + { "random_address", Address6, glob.RandomAddress }, + { "rem_test_card_address", Address6, glob.RemoteTestCardAddress }, + { "rem_trusted_card_address", Address6, glob.RemoteTrustedCardAddress }, + { "functional_address", Address4, glob.FunctionalAddress }, + { "functional_address2", Address4, glob.FunctionalAddress2 }, + { "max_frame_size", Integer, &glob.MaxFrameSize }, + { "max_lookahead_size", Integer, &glob.MaxLookaheadSize } + }; + + +DWORD +NumGlobalVars = sizeof(globalvars) / sizeof(globalvars[0]); + + + +DWORD +ParseGlobalArgs(OUT PUCHAR commandline, + OUT LPSTR tokenptr[], + IN DWORD ArgC, + IN LPSTR ArgV[]); + + + +PVOID +TpctlParseGlobalVariable( + IN BYTE Buffer[], + IN PARAMTYPES reqtype + ) + +// ------------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------------ + +{ + BYTE TmpBuffer[100]; + LPSTR EndOfVar = Buffer; // Anything that isn't NULL. + ULONG count; + + + // + // make sure that there is actually something passed in.. + // + + if ( Buffer == NULL) + { + return NULL; + } + + // + // copy the variable into a temp buffer. + // + + strcpy( TmpBuffer,&Buffer[1] ); + + // + // Now null out the '$' symbol if it exists to allow the querying + // of the global variable. + // + + EndOfVar = strchr( TmpBuffer,'$' ); + + if ( EndOfVar == NULL ) + { + return NULL; + } + + *EndOfVar = '\0'; + + // + // Search for the named global variable + // + + for (count=0; count < NumGlobalVars; count++) + { + if (!_stricmp(TmpBuffer, globalvars[count].varname)) + { + // + // Make sure the required type matched the type of the global + // + if (globalvars[count].vartype != reqtype) + { + return NULL; + } + return globalvars[count].varaddress; + + } + } + + return NULL; +} + +VOID +TpctlInitGlobalVariables(VOID) +{ + ULONG count; + UCHAR NameBuf[128]; + PUCHAR varptr; + LPBYTE NextToken; + + + // + // first, initialize those globals that will always have a certain value... + // (all others should already be zero) + // + + glob.MulticastAddress[0] = 0x01; + glob.MulticastAddress[1] = 0x02; + glob.MulticastAddress[2] = 0x03; + glob.MulticastAddress[3] = 0x04; + glob.MulticastAddress[4] = 0x05; + glob.MulticastAddress[5] = 0x00; + + glob.MulticastAddress2[0] = 0x01; + glob.MulticastAddress2[1] = 0x02; + glob.MulticastAddress2[2] = 0x03; + glob.MulticastAddress2[3] = 0x04; + glob.MulticastAddress2[4] = 0x05; + glob.MulticastAddress2[5] = 0x01; + + glob.BroadcastAddress[0] = 0xFF; + glob.BroadcastAddress[1] = 0xFF; + glob.BroadcastAddress[2] = 0xFF; + glob.BroadcastAddress[3] = 0xFF; + glob.BroadcastAddress[4] = 0xFF; + glob.BroadcastAddress[5] = 0xFF; + + glob.RandomAddress[0] = 0x00; + glob.RandomAddress[1] = 0x02; + glob.RandomAddress[2] = 0x04; + glob.RandomAddress[3] = 0x06; + glob.RandomAddress[4] = 0x08; + glob.RandomAddress[5] = 0x0A; + + glob.FunctionalAddress[0] = 0xC0; + glob.FunctionalAddress[1] = 0x02; + glob.FunctionalAddress[2] = 0x03; + glob.FunctionalAddress[3] = 0x04; + + glob.FunctionalAddress2[0] = 0x00; + glob.FunctionalAddress2[1] = 0x00; + glob.FunctionalAddress2[2] = 0x00; + glob.FunctionalAddress2[3] = 0x00; + + + // + // now, loop thru all the global vars, checking for an associated environment variable + // If the env variable is found, then set that global variable accordingly. + // + + for (count=0; count < NumGlobalVars; count++) + { + strcpy(NameBuf, "tp_"); + strcat(NameBuf, globalvars[count].varname); + varptr = getenv( _strupr( NameBuf )); + if (varptr != NULL) + { + switch ( globalvars[count].vartype ) + { + case Integer: + *(PDWORD)globalvars[count].varaddress = strtol( varptr,&NextToken,0 ); + break; + + case String: + strcpy( (LPSTR)globalvars[count].varaddress,varptr ); + break; + + case Address4: + TpctlParseAddress( varptr, + (PDWORD)globalvars[count].varaddress, + 0, + FUNCTIONAL_ADDRESS_LENGTH ); + break; + + case Address6: + TpctlParseAddress( varptr, + (PDWORD)globalvars[count].varaddress, + 0, + ADDRESS_LENGTH ) ; + break; + } + } + } +} + + +DWORD +TpctlParseSet( + IN DWORD ArgC, + IN LPSTR ArgV[] + ) + +{ + DWORD count; + UCHAR commandline[120]; + LPSTR tokenptr[20]; + DWORD numstrings; + + printf("\nIn TpctlParseSet\n"); + + if (ArgC < 2) + { + printf("Error in setglobalvar command: no arguments\n"); + return 0; + } + + numstrings = ParseGlobalArgs(commandline,tokenptr,ArgC, ArgV); + + for (count=0; count < numstrings; count++) + { + printf("token %d equals \"%s\".\n",count, tokenptr[count]); + } + printf("\n"); + + // now that they are all parsed into separate strings + return 0; +} + + +DWORD +ParseGlobalArgs(OUT PUCHAR clptr, + OUT LPSTR tokenptr[], + IN DWORD ArgC, + IN LPSTR ArgV[]) + +{ + + DWORD count; + DWORD tokencnt = 0; + LPSTR srcptr; + DWORD state; + DWORD chtype; + UCHAR ch; + + // parse into legal strings. For our purposes, the following are legal strings: + // 1) Global variable. Must start and end with a '$'. Legal characters are 'A-Z', 'a-z', + // '0-9', and '_'. Lowercase are converted to uppercase + // 2) Environment variable. Same as global, except must start and end with a '%' + // 3) Number. Must contain only digits '0' thru '9' + // 4) Address. Must start and end with a '&'. Fields are in hex, separated by '-'. + // For example, &00-03-a3-f1-07-54& + // 5) Comparisons Legal strings are "=", "<", ">", "<>", "<=", ">=" + // 6) Operators. Legal strings are '+', '-', '*', '/' + + + for(count=1; count < ArgC; count++) + { + srcptr = ArgV[count]; + state = 0; + + while ( (ch = *srcptr++) != 0) + { + if ((ch >= '0') && (ch <= '9')) + { + chtype = 1; + } + else if ((ch == '%') || (ch == '$') || ((ch >= 'A') && (ch <= 'Z'))) + { + chtype = 2; + } + else if ((ch >= 'a') && (ch <= 'z')) + { + chtype = 2; + ch = toupper(ch); + } + else if ((ch == '(') || (ch == ')') || (ch == '+') || (ch = '-') || + (ch == '*') || (ch == '/') || (ch == '=')) + { + chtype = 3; + } + else + { + printf("Error in setglobalvar command--illegal char\n"); + return 0; + } + + if (chtype != state) + { + if (state != 0) + { + *clptr++ = 0; + } + tokenptr[tokencnt++] = clptr; + if (chtype == 3) + { + state = 4; + } + else + { + state = chtype; + } + } + *clptr++ = ch; + } + *clptr++ = 0; + } + + return tokencnt; +} + diff --git a/private/ntos/ndis/testprot/tpctl/info.c b/private/ntos/ndis/testprot/tpctl/info.c new file mode 100644 index 000000000..96acecd09 --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/info.c @@ -0,0 +1,1497 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + info.c + +Abstract: + + This module handles the printing of the results of the Query and + Set commands. + +Author: + + Tom Adams (tomad) 2-Dec-1991 + +Revision History: + + 2-Apr-1991 tomad + + created + + Sanjeev Katariya (sanjeevk) + 4-12-1993 Added Arcnet support + 4-15-1993 Added additional OIDS + + +--*/ + +#include +#include +#include + +#include + +//#include + +#include +#include +#include + +#include "tpctl.h" +#include "parse.h" + + +#define CHAR_SP 0x20 +#define INDENT 12 +#define MAX_STR_LEN 80 + + +/*++ + +VOID +TpctlDumpNewLine( + LPSTR Buffer + ); + +--*/ + + +#define TpctlDumpNewLine( Buffer ) { \ + Buffer += (BYTE)sprintf( Buffer,"\n" ); \ +} + +/*++ + +VOID +TpctlDumpLabel( + LPSTR Buffer, + PBYTE Label + ); + +--*/ + +#define TpctlDumpLabel( Buffer,Label ) { \ + DWORD i; \ + DWORD Length; \ + BYTE _Str[MAX_STR_LEN]; \ + \ + for ( i=0;iSignature == REQUEST_RESULTS_SIGNATURE ); + //ASSERT(( Results->NdisRequestType == NdisRequestQueryInformation ) || + // ( Results->NdisRequestType == NdisRequestQueryStatistics )); + //ASSERT( Results->OID == OID ); + + TmpBuf = GlobalBuf; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCmdCode = %s\n\n", + TpctlGetCmdCode( CmdCode )); + + + TmpBuf += (BYTE)sprintf(TmpBuf,"\t OID = 0x%08lX\n",OID); + TpctlDumpOID( &TmpBuf,OID ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tReturn Status = %s\n", + TpctlGetStatus( Results->RequestStatus )); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRequest Pended = %s", + Results->RequestPended ? "TRUE" : "FALSE"); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + if (( Results->RequestStatus != NDIS_STATUS_SUCCESS ) && + ( Results->RequestStatus != NDIS_STATUS_NOT_SUPPORTED )) { + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tBytesWritten = %d\n", + Results->BytesReadWritten); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tBytesNeeded = %d\n\n", + Results->BytesNeeded); + + } else if ( Results->RequestStatus == NDIS_STATUS_SUCCESS ) { + + switch ( Results->OID ) { + + // + // GENERAL OBJECTS + // + + // + // General Operational Characteristics + // + + case OID_GEN_SUPPORTED_LIST: // 0x00010101 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tSupported OIDs are:\n\n"); + + Number = Results->BytesReadWritten / sizeof( DWORD ); + + Supported = (LPDWORD)Results->InformationBuffer; + + for ( i=0;iInformationBuffer); + + TpctlDumpHardWareStatus( &TmpBuf,*(LPDWORD)Results->InformationBuffer ); + + break; + + case OID_GEN_MEDIA_SUPPORTED: // 0x00010103 + case OID_GEN_MEDIA_IN_USE: // 0x00010104 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMedia Types Supported are:\n\n"); + + Number = Results->BytesReadWritten / sizeof( DWORD ); + Supported = (LPDWORD)Results->InformationBuffer; + + for ( i=0;iInformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_MAXIMUM_FRAME_SIZE: // 0x00010106 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMaximum Frame Size = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + case OID_GEN_LINK_SPEED: // 0x00010107 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLink Speed (bps) = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: // 0x00010108 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tTransmit Buffer Space = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_RECEIVE_BUFFER_SPACE: // 0x00010109 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tReceive Buffer Space = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_TRANSMIT_BLOCK_SIZE: // 0x0001010A + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tTransmit Block Size = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_RECEIVE_BLOCK_SIZE: // 0x0001010B + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tReceive Block Size = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_VENDOR_ID: // 0x0001010C + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tVendor ID = %u", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_VENDOR_DESCRIPTION: // 0x0001010D + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tVendor Description = %s", + (PCHAR)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER"); + + break; + + case OID_GEN_DRIVER_VERSION: // 0x00010110 + { + LPBYTE Version = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tDriver Version Number = %d.%d\n", + Version[1],Version[0]); + break; + } + case OID_GEN_CURRENT_PACKET_FILTER: // 0x0001010E + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Packet Filter = 0x%lx\n", + *(LPDWORD)Results->InformationBuffer); + + TpctlDumpPacketFilter( &TmpBuf,*(LPDWORD)Results->InformationBuffer ); + + break; + + case OID_GEN_CURRENT_LOOKAHEAD: // 0x0001010F + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Lookahead Size = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_MAXIMUM_TOTAL_SIZE: // 0x00010111 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMaximum Total Size = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_PROTOCOL_OPTIONS: // 0x00010112 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tGeneral Protocol Options = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_MAC_OPTIONS: // 0x00010113 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tGeneral MAC Options = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // General Statitics - Mandatory + // + + case OID_GEN_XMIT_OK: // 0x00020101 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrame Transmits - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_RCV_OK: // 0x00020102 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrame Receives - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_XMIT_ERROR: // 0x00020103 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrame Tranmsits With Error = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_RCV_ERROR: // 0x00020104 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrame Receives With Error = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_RCV_NO_BUFFER: // 0x00020105 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Missed, No Buffers = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // General Statitics - Optional + // + + case OID_GEN_DIRECTED_BYTES_XMIT: // 0x00020201 + + Counters = (LPDWORD)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tDirected Bytes Transmitted - OK = 0x%08lX - 0x%08lX", + Counters[1],Counters[0]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_DIRECTED_FRAMES_XMIT: // 0x00020202 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tDirected Frames Transmitted - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_MULTICAST_BYTES_XMIT: // 0x00020203 + + Counters = (LPDWORD)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMulticast Bytes Transmitted - OK = 0x%08lX - 0x%08lX", + Counters[1],Counters[0]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_MULTICAST_FRAMES_XMIT: // 0x00020204 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMulticast Frames Transmitted - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_BROADCAST_BYTES_XMIT: // 0x00020205 + + Counters = (LPDWORD)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tBroadcast Bytes Transmitted - OK = 0x%08lX - 0x%08lX", + Counters[1],Counters[0]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_BROADCAST_FRAMES_XMIT: // 0x00020206 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tBroadcast Frames Transmitted - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_DIRECTED_BYTES_RCV: // 0x00020207 + + Counters = (LPDWORD)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tDirected Bytes Received - OK = 0x%08lX - 0x%08lX", + Counters[1],Counters[0]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_DIRECTED_FRAMES_RCV: // 0x00020208 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tDirected Frames Received - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_MULTICAST_BYTES_RCV: // 0x00020209 + + Counters = (LPDWORD)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMulticast Bytes Received - OK = 0x%08lX - 0x%08lX", + Counters[1],Counters[0]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_MULTICAST_FRAMES_RCV: // 0x0002020A + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMulticast Frames Received - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_BROADCAST_BYTES_RCV: // 0x0002020B + + Counters = (LPDWORD)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tBroadcast Bytes Received - OK = 0x%08lX - 0x%08lX", + Counters[1],Counters[0]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_BROADCAST_FRAMES_RCV: // 0x0002020C + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tBroadcast Frames Received - OK = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_RCV_CRC_ERROR: // 0x0002020D + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Received With CRC/FCS Errors = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_GEN_TRANSMIT_QUEUE_LENGTH: // 0x0002020E + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLength of Tramsit Queue = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // 802.3 OBJECTS + // + + // + // 802.3 Operation Characteristics + // + + case OID_802_3_PERMANENT_ADDRESS: // 0x01010101 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPermanent Station Address = %02X-%02X-%02X-%02X-%02X-%02X", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_CURRENT_ADDRESS: // 0x01010102 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Station Address = %02X-%02X-%02X-%02X-%02X-%02X\n", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + break; + + case OID_802_3_MULTICAST_LIST: // 0x01010103 + + Number = Results->BytesReadWritten / ADDRESS_LENGTH; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMulticast Address List:\n\n"); + + if ( Number == 0 ) { + TmpBuf += (BYTE)sprintf(TmpBuf,"\t\tNone.\n"); + } else { + + Address = (LPBYTE)&Results->InformationBuffer; + + for ( i=0;iInformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // 802.3 Statitics - Mandatory + // + + case OID_802_3_RCV_ERROR_ALIGNMENT: // 0x01020101 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Received With Alignment Error = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_XMIT_ONE_COLLISION: // 0x01020102 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Transmitted With One Collision = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_XMIT_MORE_COLLISIONS: // 0x01020103 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Transmitted With Greater Than One Collision = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // 802.3 Statitics - Optional + // + + case OID_802_3_XMIT_DEFERRED: // 0x01020201 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Transmitted After Deferral = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_XMIT_MAX_COLLISIONS: // 0x01020202 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Not Transmitted Due To Collisions = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_RCV_OVERRUN: // 0x01020203 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Not Received Due To Overrun = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_XMIT_UNDERRUN: // 0x01020204 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Not Transmitted Due To Underrun = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_XMIT_HEARTBEAT_FAILURE: // 0x01020205 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Transmitted With Heartbeat Failure = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_XMIT_TIMES_CRS_LOST: // 0x01020206 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tTimes CRC Lost During Transmit = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_3_XMIT_LATE_COLLISIONS: // 0x01020207 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLate Collisions Detected = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // 802.5 OBJECTS + // + + // + // 802.5 Operation Characteristics + // + + case OID_802_5_PERMANENT_ADDRESS: // 0x02010101 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPermanent Station Address = %02X-%02X-%02X-%02X-%02X-%02X", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_CURRENT_ADDRESS: // 0x02010102 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Station Address = %02X-%02X-%02X-%02X-%02X-%02X\n", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + break; + + case OID_802_5_CURRENT_FUNCTIONAL: // 0x02010103 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Functional Address = %02X-%02X-%02X-%02X\n", + Address[0],Address[1],Address[2],Address[3]); + + break; + + case OID_802_5_CURRENT_GROUP: // 0x02010104 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Group Address = %02X-%02X-%02X-%02X\n", + Address[0],Address[1],Address[2],Address[3]); + + break; + + case OID_802_5_LAST_OPEN_STATUS: // 0x02010105 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLast Open Status = %d", + *(LPWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_CURRENT_RING_STATUS: // 0x02010106 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Ring Status = %d", + *(LPWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_CURRENT_RING_STATE: // 0x02010107 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Ring State = %d", + *(LPWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // 802.5 Statitics - Mandatory + // + + case OID_802_5_LINE_ERRORS: // 0x02020101 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLine Errors Detected= %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_LOST_FRAMES: // 0x02020102 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLost Frames = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // 802.5 Statitics - Optional + // + + case OID_802_5_BURST_ERRORS: // 0x02020201 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tBurst Errors Detected = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_AC_ERRORS: // 0x02020202 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tA/C Errors = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_ABORT_DELIMETERS: // 0x02020203 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tAbort Delimeter Detected = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_FRAME_COPIED_ERRORS: // 0x02020204 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrame Copied Errors = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_FREQUENCY_ERRORS: // 0x02020205 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrequency Errors Detected = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_TOKEN_ERRORS: // 0x02020206 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tToken Errors = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_802_5_INTERNAL_ERRORS: // 0x02020207 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tInternal Errors = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // FDDI + // + + case OID_FDDI_LONG_PERMANENT_ADDR : // 0x03010101 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLong Permanent Station Address = %02X-%02X-%02X-%02X-%02X-%02X", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_LONG_CURRENT_ADDR : // 0x03010102 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLong Current Station Address = %02X-%02X-%02X-%02X-%02X-%02X\n", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + break; + + case OID_FDDI_LONG_MULTICAST_LIST : // 0x03010103 + + Number = Results->BytesReadWritten / ADDRESS_LENGTH; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLong Multicast Address List:\n\n"); + + if ( Number == 0 ) { + TmpBuf += (BYTE)sprintf(TmpBuf,"\t\tNone.\n"); + } else { + + Address = (LPBYTE)&Results->InformationBuffer; + + for ( i=0;iInformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_SHORT_PERMANENT_ADDR : // 0x03010105 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tShort Permanent Station Address = %02X-%02X", + Address[0],Address[1]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_SHORT_CURRENT_ADDR : // 0x03010106 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tShort Current Station Address = %02X-%02X\n", + Address[0],Address[1]); + + break; + + case OID_FDDI_SHORT_MULTICAST_LIST : // 0x03010107 + + Number = Results->BytesReadWritten / ADDRESS_LENGTH; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tShort Multicast Address List:\n\n"); + + if ( Number == 0 ) { + TmpBuf += (BYTE)sprintf(TmpBuf,"\t\tNone.\n"); + } else { + + Address = (LPBYTE)&Results->InformationBuffer; + + for ( i=0;iInformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_ATTACHMENT_TYPE: // 0x03020101 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tAttachment Type = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_UPSTREAM_NODE_LONG: // 0x03020102 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLong Upstream Node Address = %02X-%02X-%02X-%02X-%02X-%02X", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_DOWNSTREAM_NODE_LONG: // 0x03020103 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLong Downstream Node Address = %02X-%02X-%02X-%02X-%02X-%02X", + Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_FRAME_ERRORS: // 0x03020104 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrame Errors = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_FRAMES_LOST: // 0x03020105 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tFrames Lost = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_RING_MGT_STATE: // 0x03020106 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tRing Management State = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_LCT_FAILURES: // 0x03020107 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLCT Failures = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_LEM_REJECTS: // 0x03020108 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLEM Rejects = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_FDDI_LCONNECTION_STATE: // 0x03020109 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tL Connection State = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // STARTCHANGE ARCNET + // + case OID_ARCNET_PERMANENT_ADDRESS: // 0x06010101 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPermanent Station Address = %02X", Address[0]); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + case OID_ARCNET_CURRENT_ADDRESS: // 0x06010102 + + Address = (LPBYTE)&Results->InformationBuffer; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCurrent Station Address = %02X\n", Address[0]); + + break; + + case OID_ARCNET_RECONFIGURATIONS: // 0x06010103 + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tReconfigurations = %d", + *(LPDWORD)Results->InformationBuffer); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + break; + + // + // STOPCHANGE ARCNET + // + + default: + + TmpBuf +=(BYTE)sprintf(TmpBuf,"\tInvalid OID or OID not yet supported.\n"); + break; + } + } + + if (( CommandsFromScript ) || ( CommandLineLogging )) { + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\t**********************************"); + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + if ( Verbose ) { + + if ( !WriteFile( + GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + (TmpBuf-GlobalBuf), + &BytesWritten, + NULL + )) { + + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) { + + if ( !WriteFile( + Scripts[ScriptIndex].LogHandle, + GlobalBuf, + (TmpBuf-GlobalBuf), + &BytesWritten, + NULL + )) { + + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } else if ( CommandLineLogging ) { + + if ( !WriteFile( + CommandLineLogHandle, + GlobalBuf, + (TmpBuf-GlobalBuf), + &BytesWritten, + NULL + )) { + + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } +} + + +VOID +TpctlPrintSetInfoResults( + PREQUEST_RESULTS Results, + DWORD CmdCode, + NDIS_OID OID + ) + +/*++ + +Routine Description: + +Arguments: + +Return Value: + +--*/ + +{ + DWORD Status; + LPSTR TmpBuf; + DWORD BytesWritten; + BOOL ErrorReturned = FALSE; + + + //ASSERT( Results->Signature == REQUEST_RESULTS_SIGNATURE ); + //ASSERT( Results->NdisRequestType == NdisRequestSetInformation ); + //ASSERT( Results->OID == OID ); + + TmpBuf = GlobalBuf; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCmdCode = %s\n\n", + TpctlGetCmdCode( CmdCode )); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\t OID = 0x%08lX\n",OID); + TpctlDumpOID( &TmpBuf,OID ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tReturn Status = %s\n", + TpctlGetStatus( Results->RequestStatus )); + + if ( Results->RequestStatus != STATUS_SUCCESS ) { + ErrorReturned = TRUE; + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRequest Pended = %s", + Results->RequestPended ? "TRUE" : "FALSE"); + + ADD_DIFF_FLAG( TmpBuf, "\tMAY_DIFFER" ); + + if ( Results->RequestStatus != NDIS_STATUS_SUCCESS ) { + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tBytesRead = %d\n", + Results->BytesReadWritten); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tBytesNeeded = %d\n", + Results->BytesNeeded); + } + + if (( CommandsFromScript ) || ( CommandLineLogging )) { + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\t**********************************"); + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + if ( Verbose ) { + + if ( !WriteFile( + GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + (TmpBuf-GlobalBuf), + &BytesWritten, + NULL + )) { + + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if (( CommandsFromScript ) && + ((( !Verbose ) && ( ErrorReturned )) || ( Verbose ))) { + + if( !WriteFile( + Scripts[ScriptIndex].LogHandle, + GlobalBuf, + (TmpBuf-GlobalBuf), + &BytesWritten, + NULL + )) { + + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } else if ( CommandLineLogging ) { + + if( !WriteFile( + CommandLineLogHandle, + GlobalBuf, + (TmpBuf-GlobalBuf), + &BytesWritten, + NULL + )) { + + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } +} diff --git a/private/ntos/ndis/testprot/tpctl/init.c b/private/ntos/ndis/testprot/tpctl/init.c new file mode 100644 index 000000000..99a289c1a --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/init.c @@ -0,0 +1,1098 @@ +// ******************************** +// +// 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 +#include +#include + +#include +//#include +#include + +#include +#include +#include + +#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;iWindowSize = 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;iEvents, + 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; +} + + diff --git a/private/ntos/ndis/testprot/tpctl/makefile b/private/ntos/ndis/testprot/tpctl/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/ntos/ndis/testprot/tpctl/parse.c b/private/ntos/ndis/testprot/tpctl/parse.c new file mode 100644 index 000000000..613e10473 --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/parse.c @@ -0,0 +1,2526 @@ +// ****************************************************************** +// +// Copyright (c) 1991 Microsoft Corporation +// +// Module Name: +// +// parse.c +// +// Abstract: +// +// This module contains the routines for parsing commands entered from +// the command line or read from script files. +// +// Author: +// +// Tom Adams (tomad) 11-May-1991 +// +// Revision History: +// +// +// Sanjeev Katariya (sanjeevk) +// 4-12-1993 Added ARCNET support +// 4-15-1993 Added additional OIDS +// 7-01-1993 Added suppport for recoring sessions and spawning +// command shells within tpctl +// Tim Wynsma (timothyw) +// 4-27-94 added performance testing +// 5-16-94 added globvars hooks; cleanup +// 6-08-94 chgd to client/server model for perf test +// +// ****************************************************************** + + +#include +#include +#include + +#include + + +#include +#include +#include +#include + +#include "tpctl.h" +#include "parse.h" + + +VOID +TpctlFixBuffer( + IN BYTE Buffer[] + ); + + +DWORD +TpctlParseInteger( + IN BYTE Buffer[], + IN PARSETABLE ParseTable[], + IN DWORD ParseTableSize, + OUT PDWORD Ret + ); + + +BOOL +TpctlParseArgumentPairs( + IN LPSTR Argument, + OUT LPSTR *ArgName, + OUT LPSTR *ArgValue + ); + + +BOOL +TpctlParseSetInfoArguments( + IN OUT DWORD *ArgC, + IN OUT LPSTR ArgV[], + IN OUT DWORD *tmpArgC, + IN OUT LPSTR tmpArgV[] + ); + + +BOOL +TpctlParseEnvironmentVariable( + IN BYTE Buffer[] + ); + + +BOOL +TpctlFirstChar( + IN BYTE Buffer[], + IN BYTE Char + ); + + +DWORD +TpctlGetOptionNumber( + IN PTESTPARAMS Options, + IN DWORD TestSize, + IN LPSTR ArgName + ); + + +DWORD +TpctlGetOpenInstance( + IN DWORD ArgC, + IN LPSTR ArgV[] + ); + + + +PARSETABLE +BooleanTable[] = { + NamedField( TRUE ), + NamedField( FALSE ), + { "T", TRUE }, + { "F", FALSE } +}; + + + +PARSETABLE +PacketFilterTable [] = { + NamedField( NDIS_PACKET_TYPE_DIRECTED ), + NamedField( NDIS_PACKET_TYPE_MULTICAST ), + NamedField( NDIS_PACKET_TYPE_ALL_MULTICAST ), + NamedField( NDIS_PACKET_TYPE_BROADCAST ), + NamedField( NDIS_PACKET_TYPE_SOURCE_ROUTING ), + NamedField( NDIS_PACKET_TYPE_PROMISCUOUS ), + NamedField( NDIS_PACKET_TYPE_MAC_FRAME ), + NamedField( NDIS_PACKET_TYPE_GROUP ), + NamedField( NDIS_PACKET_TYPE_FUNCTIONAL ), + NamedField( NDIS_PACKET_TYPE_ALL_FUNCTIONAL ), + NamedField( NDIS_PACKET_TYPE_NONE ), + + { "Directed", NDIS_PACKET_TYPE_DIRECTED }, + { "Multicast", NDIS_PACKET_TYPE_MULTICAST }, + { "AllMulticast", NDIS_PACKET_TYPE_ALL_MULTICAST }, + { "Broadcast", NDIS_PACKET_TYPE_BROADCAST }, + { "SourceRouting", NDIS_PACKET_TYPE_SOURCE_ROUTING }, + { "Promiscuous", NDIS_PACKET_TYPE_PROMISCUOUS }, + { "MacFrame", NDIS_PACKET_TYPE_MAC_FRAME }, + { "Group", NDIS_PACKET_TYPE_GROUP }, + { "Functional", NDIS_PACKET_TYPE_FUNCTIONAL }, + { "AllFunctional", NDIS_PACKET_TYPE_ALL_FUNCTIONAL }, + { "None", NDIS_PACKET_TYPE_NONE } +}; + + +PARSETABLE +QueryInfoOidTable [] = { + + // + // General Objects + // + + NamedField( OID_GEN_SUPPORTED_LIST ), + NamedField( OID_GEN_HARDWARE_STATUS ), + NamedField( OID_GEN_MEDIA_SUPPORTED ), + NamedField( OID_GEN_MEDIA_IN_USE ), + NamedField( OID_GEN_MAXIMUM_LOOKAHEAD ), + NamedField( OID_GEN_MAXIMUM_FRAME_SIZE ), + NamedField( OID_GEN_LINK_SPEED ), + NamedField( OID_GEN_TRANSMIT_BUFFER_SPACE ), + NamedField( OID_GEN_RECEIVE_BUFFER_SPACE ), + NamedField( OID_GEN_TRANSMIT_BLOCK_SIZE ), + NamedField( OID_GEN_RECEIVE_BLOCK_SIZE ), + NamedField( OID_GEN_VENDOR_ID ), + NamedField( OID_GEN_VENDOR_DESCRIPTION ), + NamedField( OID_GEN_CURRENT_PACKET_FILTER ), + NamedField( OID_GEN_CURRENT_LOOKAHEAD ), + NamedField( OID_GEN_DRIVER_VERSION ), + NamedField( OID_GEN_MAXIMUM_TOTAL_SIZE ), + NamedField( OID_GEN_PROTOCOL_OPTIONS ), + NamedField( OID_GEN_MAC_OPTIONS ), + + NamedField( OID_GEN_XMIT_OK ), + NamedField( OID_GEN_RCV_OK ), + NamedField( OID_GEN_XMIT_ERROR ), + NamedField( OID_GEN_RCV_ERROR ), + NamedField( OID_GEN_RCV_NO_BUFFER ), + + NamedField( OID_GEN_DIRECTED_BYTES_XMIT ), + NamedField( OID_GEN_DIRECTED_FRAMES_XMIT ), + NamedField( OID_GEN_MULTICAST_BYTES_XMIT ), + NamedField( OID_GEN_MULTICAST_FRAMES_XMIT ), + NamedField( OID_GEN_BROADCAST_BYTES_XMIT ), + NamedField( OID_GEN_BROADCAST_FRAMES_XMIT ), + NamedField( OID_GEN_DIRECTED_BYTES_RCV ), + NamedField( OID_GEN_DIRECTED_FRAMES_RCV ), + NamedField( OID_GEN_MULTICAST_BYTES_RCV ), + NamedField( OID_GEN_MULTICAST_FRAMES_RCV ), + NamedField( OID_GEN_BROADCAST_BYTES_RCV ), + NamedField( OID_GEN_BROADCAST_FRAMES_RCV ), + + NamedField( OID_GEN_RCV_CRC_ERROR ), + NamedField( OID_GEN_TRANSMIT_QUEUE_LENGTH ), + + // + // 802.3 Objects + // + + NamedField( OID_802_3_PERMANENT_ADDRESS ), + NamedField( OID_802_3_CURRENT_ADDRESS ), + NamedField( OID_802_3_MULTICAST_LIST ), + NamedField( OID_802_3_MAXIMUM_LIST_SIZE ), + + NamedField( OID_802_3_RCV_ERROR_ALIGNMENT ), + NamedField( OID_802_3_XMIT_ONE_COLLISION ), + NamedField( OID_802_3_XMIT_MORE_COLLISIONS ), + + NamedField( OID_802_3_XMIT_DEFERRED ), + NamedField( OID_802_3_XMIT_MAX_COLLISIONS ), + NamedField( OID_802_3_RCV_OVERRUN ), + NamedField( OID_802_3_XMIT_UNDERRUN ), + NamedField( OID_802_3_XMIT_HEARTBEAT_FAILURE ), + NamedField( OID_802_3_XMIT_TIMES_CRS_LOST ), + NamedField( OID_802_3_XMIT_LATE_COLLISIONS ), + + // + // 802.5 Objects + // + + NamedField( OID_802_5_PERMANENT_ADDRESS ), + NamedField( OID_802_5_CURRENT_ADDRESS ), + NamedField( OID_802_5_CURRENT_FUNCTIONAL ), + NamedField( OID_802_5_CURRENT_GROUP ), + NamedField( OID_802_5_LAST_OPEN_STATUS ), + NamedField( OID_802_5_CURRENT_RING_STATUS ), + NamedField( OID_802_5_CURRENT_RING_STATE ), + + NamedField( OID_802_5_LINE_ERRORS ), + NamedField( OID_802_5_LOST_FRAMES ), + + NamedField( OID_802_5_BURST_ERRORS ), + NamedField( OID_802_5_AC_ERRORS ), + NamedField( OID_802_5_ABORT_DELIMETERS ), + NamedField( OID_802_5_FRAME_COPIED_ERRORS ), + NamedField( OID_802_5_FREQUENCY_ERRORS ), + NamedField( OID_802_5_TOKEN_ERRORS ), + NamedField( OID_802_5_INTERNAL_ERRORS ), + + // + // Fddi objects + // + + NamedField( OID_FDDI_LONG_PERMANENT_ADDR ), + NamedField( OID_FDDI_LONG_CURRENT_ADDR ), + NamedField( OID_FDDI_LONG_MULTICAST_LIST ), + NamedField( OID_FDDI_LONG_MAX_LIST_SIZE ), + NamedField( OID_FDDI_SHORT_PERMANENT_ADDR ), + NamedField( OID_FDDI_SHORT_CURRENT_ADDR ), + NamedField( OID_FDDI_SHORT_MULTICAST_LIST ), + NamedField( OID_FDDI_SHORT_MAX_LIST_SIZE ), + + NamedField( OID_FDDI_ATTACHMENT_TYPE ), + NamedField( OID_FDDI_UPSTREAM_NODE_LONG ), + NamedField( OID_FDDI_DOWNSTREAM_NODE_LONG ), + NamedField( OID_FDDI_FRAME_ERRORS ), + NamedField( OID_FDDI_FRAMES_LOST ), + NamedField( OID_FDDI_RING_MGT_STATE ), + NamedField( OID_FDDI_LCT_FAILURES ), + NamedField( OID_FDDI_LEM_REJECTS ), + NamedField( OID_FDDI_LCONNECTION_STATE ), + + // + // STARTCHANGE + // + // ARCNET objects + // + NamedField( OID_ARCNET_PERMANENT_ADDRESS ), + NamedField( OID_ARCNET_CURRENT_ADDRESS ), + NamedField( OID_ARCNET_RECONFIGURATIONS ), + // + // STOPCHANGE + // + + // + // Async Objects + // + +#if 0 + +// Not currently supported. + + NamedField( OID_ASYNC_PERMANENT_ADDRESS ), + NamedField( OID_ASYNC_CURRENT_ADDRESS ), + NamedField( OID_ASYNC_QUALITY_OF_SERVICE ), + NamedField( OID_ASYNC_PROTOCOL_TYPE ), + +#endif + + // + // LocalTalk Objects + // + +#if 0 + +// Not currently supported. + + NamedField( OID_LTALK_CURRENT_NODE_ID ), + + NamedField( OID_LTALK_IN_BROADCASTS ), + NamedField( OID_LTALK_IN_LENGTH_ERRORS ), + + NamedField( OID_LTALK_OUT_NO_HANDLERS ), + NamedField( OID_LTALK_COLLISIONS ), + NamedField( OID_LTALK_DEFERS ), + NamedField( OID_LTALK_NO_DATA_ERRORS ), + NamedField( OID_LTALK_RANDOM_CTS_ERRORS ), + NamedField( OID_LTALK_FCS_ERRORS ), + +#endif + + // + // General Objects + // + + { "SupportedOIDList", OID_GEN_SUPPORTED_LIST }, + { "HardwareStatus", OID_GEN_HARDWARE_STATUS }, + { "MediaTypeSupported", OID_GEN_MEDIA_SUPPORTED }, + { "MediaTypeInUse", OID_GEN_MEDIA_IN_USE }, + { "MaximumLookahead", OID_GEN_MAXIMUM_LOOKAHEAD }, + { "MaximumFrameSize", OID_GEN_MAXIMUM_FRAME_SIZE }, + { "LinkSpeed", OID_GEN_LINK_SPEED }, + { "TransmitBufferSpace", OID_GEN_TRANSMIT_BUFFER_SPACE }, + { "ReceiveBufferSpace", OID_GEN_RECEIVE_BUFFER_SPACE }, + { "TransmitBlockSize", OID_GEN_TRANSMIT_BLOCK_SIZE }, + { "ReceiveBlockSize", OID_GEN_RECEIVE_BLOCK_SIZE }, + { "VendorID", OID_GEN_VENDOR_ID }, + { "VendorDescription", OID_GEN_VENDOR_DESCRIPTION }, + { "CurrentPacketFilter", OID_GEN_CURRENT_PACKET_FILTER }, + { "CurrentLookahead", OID_GEN_CURRENT_LOOKAHEAD }, + { "DriverVersion", OID_GEN_DRIVER_VERSION }, + { "MaximumTotalSize", OID_GEN_MAXIMUM_TOTAL_SIZE }, + + { "TransmitGood", OID_GEN_XMIT_OK }, + { "ReceiveGood", OID_GEN_RCV_OK }, + { "TransmitBad", OID_GEN_XMIT_ERROR }, + { "ReceiveBad", OID_GEN_RCV_ERROR }, + { "ReciveNoBuffer", OID_GEN_RCV_NO_BUFFER }, + + { "DirectedBytesTransmits", OID_GEN_DIRECTED_BYTES_XMIT }, + { "DirectedFramesTransmits", OID_GEN_DIRECTED_FRAMES_XMIT }, + { "MulticastBytesTransmits", OID_GEN_MULTICAST_BYTES_XMIT }, + { "MulticastFramesTransmits", OID_GEN_MULTICAST_FRAMES_XMIT }, + { "BroadcastBytesTransmits", OID_GEN_BROADCAST_BYTES_XMIT }, + { "BroadcastFramesTransmits", OID_GEN_BROADCAST_FRAMES_XMIT }, + { "DirectedBytesReceives", OID_GEN_DIRECTED_BYTES_RCV }, + { "DirectedFramesReceives", OID_GEN_DIRECTED_FRAMES_RCV }, + { "MulticastBytesReceives", OID_GEN_MULTICAST_BYTES_RCV }, + { "MulticastFramesReceives", OID_GEN_MULTICAST_FRAMES_RCV }, + { "BroadcastBytesReceives", OID_GEN_BROADCAST_BYTES_RCV }, + { "BroadcastFramesReceives", OID_GEN_BROADCAST_FRAMES_RCV }, + + { "ReceiveCRC", OID_GEN_RCV_CRC_ERROR }, + { "TransmitQueueLength", OID_GEN_TRANSMIT_QUEUE_LENGTH }, + + // + // 802.3 Objects + // + + { "EthPermanentAddress", OID_802_3_PERMANENT_ADDRESS }, + { "EthCurrentAddress", OID_802_3_CURRENT_ADDRESS }, + { "CurrentMulticastList", OID_802_3_MULTICAST_LIST }, + { "MaxMulticastListSize", OID_802_3_MAXIMUM_LIST_SIZE }, + + { "ReceiveErrorAlignment", OID_802_3_RCV_ERROR_ALIGNMENT }, + { "TransmitOneCollsion", OID_802_3_XMIT_ONE_COLLISION }, + { "TransmitMoreCollostions", OID_802_3_XMIT_MORE_COLLISIONS }, + + { "TransmitDeferred", OID_802_3_XMIT_DEFERRED }, + { "TransmitMaxCollisions", OID_802_3_XMIT_MAX_COLLISIONS }, + { "ReceiveOverrun", OID_802_3_RCV_OVERRUN }, + { "TransmitUnderrun", OID_802_3_XMIT_UNDERRUN }, + { "TransmitHeartbeatFailure", OID_802_3_XMIT_HEARTBEAT_FAILURE }, + { "TransmitTimesCRSLost", OID_802_3_XMIT_TIMES_CRS_LOST }, + { "TransmitLateCollisions", OID_802_3_XMIT_LATE_COLLISIONS }, + + // + // 802.5 Objects + // + + { "TRPermanentAddress", OID_802_5_PERMANENT_ADDRESS }, + { "TRCurrentAddress", OID_802_5_CURRENT_ADDRESS }, + { "CurrentFunctionalAddress", OID_802_5_CURRENT_FUNCTIONAL }, + { "CurrentGroupAddress", OID_802_5_CURRENT_GROUP }, + { "LastOpenStatus", OID_802_5_LAST_OPEN_STATUS }, + { "CurrentRingStatus", OID_802_5_CURRENT_RING_STATUS }, + { "CurrentRingState", OID_802_5_CURRENT_RING_STATE }, + + { "LineErrors", OID_802_5_LINE_ERRORS }, + { "LostFrames", OID_802_5_LOST_FRAMES }, + + { "BurstErrors", OID_802_5_BURST_ERRORS }, + { "ACErrors", OID_802_5_AC_ERRORS }, + { "AbortDelimeters", OID_802_5_ABORT_DELIMETERS }, + { "FrameCopiedErrors", OID_802_5_FRAME_COPIED_ERRORS }, + { "FrequencyErrors", OID_802_5_FREQUENCY_ERRORS }, + { "TokenErrors", OID_802_5_TOKEN_ERRORS }, + { "InternalErrors", OID_802_5_INTERNAL_ERRORS }, + + // + // Fddi objects + // + + { "FddiLongPermanentAddress", OID_FDDI_LONG_PERMANENT_ADDR }, + { "FddiLongCurrentAddress", OID_FDDI_LONG_CURRENT_ADDR }, + { "FddiLongMulticastList", OID_FDDI_LONG_MULTICAST_LIST }, + { "FddiLongMaxListSize", OID_FDDI_LONG_MAX_LIST_SIZE }, + { "FddiShortPermanentAddress", OID_FDDI_SHORT_PERMANENT_ADDR }, + { "FddiShortCurrentAddress", OID_FDDI_SHORT_CURRENT_ADDR }, + { "FddiShortMulticastList", OID_FDDI_SHORT_MULTICAST_LIST }, + { "FddiShortMaxListSize", OID_FDDI_SHORT_MAX_LIST_SIZE }, + + // + // STARTCHANGE + // + // ARCNET objects + // + { "ArcPermanentAddress", OID_ARCNET_PERMANENT_ADDRESS }, + { "ArcCurrentAddress", OID_ARCNET_CURRENT_ADDRESS }, + { "ArcReconfigurations", OID_ARCNET_RECONFIGURATIONS }, + // + // STOPCHANGE + // + + // + // Async Objects + // + +#if 0 + +// Not currently supported. + + { "AsyncPermanentAddress", OID_ASYNC_PERMANENT_ADDRESS }, + { "AsyncCurrentAddress", OID_ASYNC_CURRENT_ADDRESS }, + { "AsyncQualityOfService", OID_ASYNC_QUALITY_OF_SERVICE }, + { "AsyncProtocolType", OID_ASYNC_PROTOCOL_TYPE }, + +#endif + + // + // LocalTalk Objects + // + +#if 0 + +// Not currently supported. + + { "LTalkCurrentNodeId", OID_LTALK_CURRENT_NODE_ID }, + + { "LTalkInBroadcasts", OID_LTALK_IN_BROADCASTS }, + { "LTalkInLengthErrors", OID_LTALK_IN_LENGTH_ERRORS }, + + { "LTalkOutNoHandlers", OID_LTALK_OUT_NO_HANDLERS }, + { "LTalkCollisions", OID_LTALK_COLLISIONS }, + { "LTalkDefers", OID_LTALK_DEFERS }, + { "LTalkNoDataErrors", OID_LTALK_NO_DATA_ERRORS }, + { "LTalkRandomCTSErrors", OID_LTALK_RANDOM_CTS_ERRORS }, + { "LTalkFCSErrors", OID_LTALK_FCS_ERRORS } + +#endif + +}; + + +PARSETABLE +SetInfoOidTable [] = { + NamedField( OID_GEN_CURRENT_PACKET_FILTER ), + NamedField( OID_GEN_CURRENT_LOOKAHEAD ), + NamedField( OID_802_3_MULTICAST_LIST ), + NamedField( OID_802_5_CURRENT_FUNCTIONAL ), + NamedField( OID_802_5_CURRENT_GROUP ), + NamedField( OID_FDDI_LONG_CURRENT_ADDR ), + NamedField( OID_FDDI_LONG_MULTICAST_LIST ), + NamedField( OID_FDDI_SHORT_CURRENT_ADDR ), + NamedField( OID_FDDI_SHORT_MULTICAST_LIST ), + + // + // STARTCHANGE + // + NamedField( OID_ARCNET_CURRENT_ADDRESS ), + // + // STOPCHANGE + // + + { "CurrentPacketFilter", OID_GEN_CURRENT_PACKET_FILTER }, + { "CurrentLookAhead", OID_GEN_CURRENT_LOOKAHEAD }, + { "CurrentMulticastList", OID_802_3_MULTICAST_LIST }, + { "CurrentFunctionalAddress", OID_802_5_CURRENT_FUNCTIONAL }, + { "CurrentGroupAddress", OID_802_5_CURRENT_GROUP }, + { "FddiLongCurrentAddress", OID_FDDI_LONG_CURRENT_ADDR }, + { "FddiLongMulticastList", OID_FDDI_LONG_MULTICAST_LIST }, + { "FddiShortCurrentAddress", OID_FDDI_SHORT_CURRENT_ADDR }, + { "FddiShortMulticastList", OID_FDDI_SHORT_MULTICAST_LIST }, + + // + // STARTCHANGE + // + { "ArcCurrentAddress", OID_ARCNET_CURRENT_ADDRESS } + // + // STOPCHANGE + // + + +}; + + +PARSETABLE +MemberTypeTable [] = { + NamedField( TP_CLIENT ), + NamedField( TP_SERVER ), + NamedField( BOTH ), + + { "Client", TP_CLIENT }, + { "Server", TP_SERVER }, + { "Both", BOTH } +}; + + +PARSETABLE +PacketTypeTable [] = { + NamedField( FIXEDSIZE ), + NamedField( RANDOMSIZE ), + NamedField( CYCLICAL ), + + { "Fixed", FIXEDSIZE }, + { "Random", RANDOMSIZE }, + { "Cyclic", CYCLICAL } +}; + + +PARSETABLE +PacketMakeUpTable [] = { + NamedField( RAND ), + NamedField( SMALL ), + NamedField( ZEROS ), + NamedField( ONES ), + NamedField( KNOWN ), + + { "Random_MakeUp", RAND }, + { "Small_MakeUp", SMALL }, + { "Zeros_MakeUp", ZEROS }, + { "Ones_MakeUp", ONES }, + { "Known_MakeUp", KNOWN } +}; + + +PARSETABLE +ResponseTypeTable [] = { + NamedField( NO_RESPONSE ), + NamedField( FULL_RESPONSE ), + NamedField( ACK_EVERY ), + NamedField( ACK_10_TIMES ), + + { "No Response", NO_RESPONSE }, + { "Response", FULL_RESPONSE }, + { "ACK", ACK_EVERY }, + { "ACK10", ACK_10_TIMES } +}; + + +PARSETABLE +DelayTable [] = { + NamedField( FIXEDDELAY ), + NamedField( RANDOMDELAY ), + + { "Fixed", FIXEDDELAY }, + { "Random", RANDOMDELAY } +}; + + +PARSETABLE +OperationTypeTable[] = { + NamedField( ADD_KEY ), + NamedField( DELETE_KEY ), + NamedField( QUERY_KEY ), + NamedField( ADD_VALUE ), + NamedField( CHANGE_VALUE ), + NamedField( DELETE_VALUE ), + NamedField( QUERY_VALUE ), + + { "Add Key" , ADD_KEY }, + { "Delete Key" , DELETE_KEY }, + { "Query Key" , QUERY_KEY }, + { "Add Value" , ADD_VALUE }, + { "Change Value" , CHANGE_VALUE }, + { "Delete Value" , DELETE_VALUE }, + { "Query Value" , QUERY_VALUE } +}; + + +PARSETABLE +KeyDbaseTable [] = { + NamedField( CLASSES_ROOT ), + NamedField( CURRENT_USER ), + NamedField( LOCAL_MACHINE ), + NamedField( USERS ), + + { "HKEY_CLASSES_ROOT" , CLASSES_ROOT }, + { "HKEY_CURRENT_USER" , CURRENT_USER }, + { "HKEY_LOCAL_MACHINE", LOCAL_MACHINE }, + { "HKEY_USERS" , USERS } +}; + + +PARSETABLE +ValueTypeTable[] = { + NamedField( BINARY ), + NamedField( DWORD_REGULAR ), + NamedField( DWORD_LITTLE_ENDIAN ), + NamedField( DWORD_BIG_ENDIAN ), + NamedField( EXPAND_SZ ), + NamedField( LINK ), + NamedField( MULTI_SZ ), + NamedField( NONE ), + NamedField( RESOURCE_LIST ), + NamedField( SZ ), + + { "Binary", BINARY }, + { "Double Word", DWORD_REGULAR }, + { "Double Word Litlle Endian", DWORD_LITTLE_ENDIAN }, + { "Double Word Big Endian", DWORD_BIG_ENDIAN }, + { "String with unexpanded environment references", EXPAND_SZ }, + { "Symbolic Link", LINK }, + { "Array of strings", MULTI_SZ }, + { "None", NONE }, + { "Resource List", RESOURCE_LIST }, + { "String", SZ } + +}; + +// +// The Test Parameters Structure and command parameter definitions. +// +// typedef struct _TestOptions { +// DWORD OptionNumber; +// LPSTR TestPrompt; +// LPSTR ArgName; +// LPSTR ArgNameAbbr; +// +// BOOL ArgValueSet; +// PARAMTYPES TestType; +// DWORD IntegerDefault; +// LPSTR StringDefault; +// +// PPARSETABLE ParsedIntTable; +// DWORD ParsedIntTableSize; +// PVOID Destination; +// } TESTPARAMS, *PTESTPARAMS; +// +// + +TESTPARAMS +CommandLineOptions[] = { + + + { 1, "Options", "Options", "OP", FALSE, String, + 0, NULL, NULL, 0, GlobalCmdArgs.TpctlOptions }, + + { 2, "ScriptFile Name", "ScriptFile", "SF", FALSE, String, + 0, NULL, NULL, 0, GlobalCmdArgs.ARGS.FILES.ScriptFile }, + + { 3, "LogFile Name", "LogFile", "LF", FALSE, String, 0, + NULL, NULL, 0, GlobalCmdArgs.ARGS.FILES.LogFile } +}; + + +DWORD +Num_CommandLine_Params = sizeoftable( CommandLineOptions ); + + +TESTPARAMS +SetEnvOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Window Size", "WindowSize", "WS", FALSE, Integer, WINDOW_SIZE, + NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.WindowSize }, + + { 3, "Random Buffer", "RandomBuffer", "RB", FALSE, Integer, BUFFER_NUMBER, + NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.RandomBufferNumber }, + + { 4, "Stress Address", "StressAddress" , "SA", FALSE, Address6, 0, + STRESS_MULTICAST, NULL, 0, GlobalCmdArgs.ARGS.ENV.StressAddress }, + + { 5, "Resend Address", "ResendAddress" , "RA", FALSE, Address6, 0, + NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.ENV.ResendAddress }, + + { 6, "Stress Delay", "StressDelay", "SD", FALSE, Integer, + STANDARD_DELAY, NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.StandardDelay }, + + { 7, "Up-For-Air Delay", "UpForAirDelay", "UD", FALSE, Integer, + UP_FOR_AIR_DELAY, NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.UpForAirDelay }, + + { 8, "Delay Interval", "DelayInterval", "I", FALSE, Integer, DELAY_INTERVAL, + NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.StressDelayInterval } +}; + + +DWORD +Num_SetEnv_Params = sizeoftable( SetEnvOptions ); + + +TESTPARAMS ReadScriptOptions[] = { + + { 1, "ScriptFile Name", "ScriptFile", "SF", FALSE, String, 0, + NULL, NULL, 0, GlobalCmdArgs.ARGS.FILES.ScriptFile }, + + { 2, "LogFile Name", "LogFile", "LF", FALSE, String, 0, NULL, + NULL, 0, GlobalCmdArgs.ARGS.FILES.LogFile } +}; + + +DWORD +Num_ReadScript_Params = sizeoftable( ReadScriptOptions ); + + +TESTPARAMS +LoggingOptions[] = { + + { 1, "LogFile Name", "LogFile", "LF", FALSE, String, 0, + TPCTL_CMDLINE_LOG, NULL, 0, GlobalCmdArgs.ARGS.FILES.LogFile } +}; + + +DWORD +Num_Logging_Params = sizeoftable( LoggingOptions ); + + +TESTPARAMS +RecordingOptions[] = { + + { 1, "ScriptFile Name", "ScriptFile", "SF", FALSE, String, 0, + TPCTL_CMDLINE_SCRIPT, NULL, 0, GlobalCmdArgs.ARGS.RECORD.ScriptFile } +}; + + +DWORD +Num_Recording_Params = sizeoftable( RecordingOptions ); + + +TESTPARAMS +PauseGoOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Remote Address", "RemoteAddress" , "RA", FALSE, Address6, 0, + NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.PAUSE_GO.RemoteAddress }, + + { 3, "Test Signature", "TestSignature", "TS", FALSE, Integer, + 0, NULL, NULL, 0, &GlobalCmdArgs.ARGS.PAUSE_GO.TestSignature }, + + { 4, "Unique Signature", "UniqueSig", "UI", FALSE, Integer, 0, NULL, + NULL, 0, &GlobalCmdArgs.ARGS.PAUSE_GO.UniqueSignature }, +}; + + +DWORD +Num_PauseGo_Params = sizeoftable( PauseGoOptions ); + + +TESTPARAMS +LoadUnloadOptions[] = { + + { 1, "Driver Name", "DriverName", "DN", FALSE, String, 0, + NULL, NULL, 0, GlobalCmdArgs.ARGS.DriverName } +}; + + +DWORD +Num_LoadUnload_Params = sizeoftable( LoadUnloadOptions ); + + +TESTPARAMS +OpenOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Adapter Name", "AdapterName", "AN", FALSE, String, 0, + NULL, NULL, 0, GlobalCmdArgs.ARGS.OPEN_ADAPTER.AdapterName } +}; + + +DWORD +Num_Open_Params = sizeoftable( OpenOptions ); + + +TESTPARAMS +SetPacketFilterOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Packet Filter", "PacketFilter", "PF", FALSE, ParsedInteger, + 0, "DIRECTED", PacketFilterTable, sizeoftable( PacketFilterTable ), + &GlobalCmdArgs.ARGS.TPSET.U.PacketFilter } +}; + + +DWORD +Num_SetPacketFilter_Params = sizeoftable( SetPacketFilterOptions ); + + +TESTPARAMS +SetLookaheadOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Lookahead Buffer Size", "Lookahead", "LA", FALSE, + Integer, LOOKAHEADSIZE, NULL, NULL, 0, + &GlobalCmdArgs.ARGS.TPSET.U.LookaheadSize } +}; + + +DWORD +Num_SetLookahead_Params = sizeoftable( SetLookaheadOptions ); + + +TESTPARAMS +MulticastAddrOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Multicast Address", "MulticastAddress", "MA", + FALSE, Address6, 0, DEFAULT_MULTICAST, NULL, 0, + GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0] } +}; + + +DWORD +Num_MulticastAddr_Params = sizeoftable( MulticastAddrOptions ); + + +TESTPARAMS +FunctionalAddrOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Functional Address", "FunctionalAddress", "FA", + FALSE, Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0, + GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress } +}; + + +DWORD +Num_FunctionalAddr_Params = sizeoftable( FunctionalAddrOptions ); + + +TESTPARAMS +GroupAddrOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Group Address", "GroupAddress", "GA", + FALSE, Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0, + GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress } +}; + + +DWORD +Num_GroupAddr_Params = sizeoftable( GroupAddrOptions ); + + +TESTPARAMS +QueryInfoOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "OID Request", "ObjectIdentifier", "OID", FALSE, ParsedInteger, + 0x00010101, "SupportedOidList", QueryInfoOidTable, + sizeoftable( QueryInfoOidTable ), &GlobalCmdArgs.ARGS.TPQUERY.OID }, +}; + + +DWORD +Num_QueryInfo_Params = sizeoftable( QueryInfoOptions ); + + +TESTPARAMS +QueryStatsOptions[] = { + + + { 1, "Device Name", "DeviceName", "DN", FALSE, String, 0, NULL, + NULL, 0, GlobalCmdArgs.ARGS.TPQUERYSTATS.DeviceName }, + + { 2, "OID Request", "ObjectIdentifier", "OID", FALSE, ParsedInteger, + 0x00010101, "SupportedOidList", QueryInfoOidTable, + sizeoftable( QueryInfoOidTable ), &GlobalCmdArgs.ARGS.TPQUERYSTATS.OID }, +}; + + +DWORD +Num_QueryStats_Params = sizeoftable( QueryStatsOptions ); + + +TESTPARAMS +SetInfoOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "OID Request", "ObjectIdentifier", "OID", FALSE, ParsedInteger, + 0x0001010e, "CurrentPacketFilter", SetInfoOidTable, + sizeoftable( SetInfoOidTable ), &GlobalCmdArgs.ARGS.TPSET.OID } +}; + + +DWORD +Num_SetInfo_Params = sizeoftable( SetInfoOptions ); + + +TESTPARAMS +SetInfoPFOptions[] = { + + { 1, "Packet Filter", "PacketFilter", "PF", FALSE, ParsedInteger, + 0, "DIRECTED", PacketFilterTable, sizeoftable( PacketFilterTable ), + &GlobalCmdArgs.ARGS.TPSET.U.PacketFilter } +}; + + +DWORD +Num_SetInfoPF_Params = sizeoftable( SetInfoPFOptions ); + + +TESTPARAMS +SetInfoLAOptions[] = { + + { 1, "Lookahead Buffer Size", "Lookahead", "LA", + FALSE, Integer, LOOKAHEADSIZE, NULL, NULL, 0, + &GlobalCmdArgs.ARGS.TPSET.U.LookaheadSize } +}; + + +DWORD +Num_SetInfoLA_Params = sizeoftable( SetInfoLAOptions ); + + +TESTPARAMS +SetInfoMAOptions[] = { + + { 1, "Multicast Address", "MulticastAddress", "MA", + FALSE, Address6, 0, DEFAULT_MULTICAST, NULL, 0, + GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0] } +}; + + +DWORD +Num_SetInfoMA_Params = sizeoftable( SetInfoMAOptions ); + +TESTPARAMS +SetInfoFAOptions[] = { + + { 1, "Functional Address", "FunctionalAddress", "FA", + FALSE, Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0, + GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress } +}; + + +DWORD +Num_SetInfoFA_Params = sizeoftable( SetInfoFAOptions ); + + +TESTPARAMS +SetInfoGAOptions[] = { + + { 1, "Group Address", "GroupAddress", "GA", FALSE, + Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0, + GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress } +}; + + +DWORD +Num_SetInfoGA_Params = sizeoftable( SetInfoGAOptions ); + + +TESTPARAMS +SendOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Destination Address", "DestinationAddress", "DA", FALSE, Address6, + 0, NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPSEND.DestAddress }, + + { 3, "Packet Size", "PacketSize", "PS", FALSE, Integer, PACKET_SIZE, + NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSEND.PacketSize }, + + { 4, "Number to Send", "Number", "N", FALSE, Integer, 1, NULL, NULL, + 0, &GlobalCmdArgs.ARGS.TPSEND.NumberOfPackets }, + + { 5, "Resend Address", "ResendAddress", "RA", FALSE, Address6, 0, + NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPSEND.ResendAddress } + + // + // Both Resend and Dest address will default to the local address + // which must be queried and then stored in the application somewhere? + // +}; + + +DWORD +Num_Send_Params = sizeoftable( SendOptions ); + + +TESTPARAMS +PerfClntOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Server Address", "ServerAddress", "SVA", FALSE, Address6, + 0, NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPPERF.PerfServerAddr }, + + { 3, "Send Address", "SendAddress", "SA", FALSE, Address6, + 0, NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPPERF.PerfSendAddr }, + + { 4, "Packet Size", "PacketSize", "PS", FALSE, Integer, PACKET_SIZE, + NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPPERF.PerfPacketSize }, + + { 5, "Number to Send", "Number", "N", FALSE, Integer, 100000, NULL, NULL, + 0, &GlobalCmdArgs.ARGS.TPPERF.PerfNumPackets }, + + { 6, "Delay", "Delay", "D", FALSE, Integer, 0, NULL, NULL, + 0, &GlobalCmdArgs.ARGS.TPPERF.PerfDelay }, + + { 7, "Mode", "Mode", "M", FALSE, Integer, 0, NULL, NULL, + 0, &GlobalCmdArgs.ARGS.TPPERF.PerfMode } +}; + + +DWORD +Num_PerfClnt_Params = sizeoftable( PerfClntOptions ); + + +TESTPARAMS +StressOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }, + + { 2, "Stress Member Type", "MemberType", "MT", FALSE, ParsedInteger, + 0, "TP_CLIENT", MemberTypeTable, sizeoftable( MemberTypeTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.MemberType }, + + { 3, "Total Number of Packets", "Packets", "P", FALSE, Integer, + (DWORD)STRESS_PACKETS, NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSTRESS.TotalPackets }, + + { 4, "Total Number of Iterations", "Iterations", "I", FALSE, Integer, + (DWORD)STRESS_ITERATIONS, NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSTRESS.TotalIterations }, + + { 5, "Packet Type", "PacketType", "PT", FALSE, ParsedInteger, 0, + "FIXEDSIZE", PacketTypeTable, sizeoftable( PacketTypeTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.PacketType }, + + { 6, "Packet Size", "PacketSize", "PS", FALSE, Integer, PACKET_SIZE, + NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSTRESS.PacketSize }, + + { 7, "Packet MakeUp", "PacketMakeUp", "PM", FALSE, ParsedInteger, + 0, "RAND", PacketMakeUpTable, sizeoftable( PacketMakeUpTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.PacketMakeUp }, + + { 8, "Response Type", "ResponseType", "RT", FALSE, ParsedInteger, 0, + "FULL_RESPONSE", ResponseTypeTable, sizeoftable( ResponseTypeTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.ResponseType }, + + { 9, "Interpacket Delay Type", "DelayType", "DT", FALSE, + ParsedInteger, 0, "FIXEDDELAY", DelayTable, sizeoftable( DelayTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.DelayType }, + + { 10, "Interpacket Delay Length", "DelayLength", "DL", FALSE, Integer, + 0, NULL, NULL, DELAY_LENGTH, &GlobalCmdArgs.ARGS.TPSTRESS.DelayLength }, + + { 11, "Windowing Enabled","WindowEnabled","WE", FALSE, ParsedInteger, 0, + WINDOWING_ENABLED, BooleanTable, sizeoftable( BooleanTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.WindowEnabled }, + + { 12, "Data Checking Enabled", "DataChecking", "DC", FALSE, ParsedInteger, + 0, DATA_CHECKING, BooleanTable, sizeoftable( BooleanTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.DataChecking }, + + { 13, "Packets from Pool", "PacketPool", "PP", FALSE, ParsedInteger, + 0, PACKETS_FROM_POOL, BooleanTable, sizeoftable( BooleanTable ), + &GlobalCmdArgs.ARGS.TPSTRESS.PacketsFromPool } +}; + + +DWORD +Num_Stress_Params = sizeoftable( StressOptions ); + + +TESTPARAMS +OpenInstanceOptions[] = { + + { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer, + OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance } +}; + + +DWORD +Num_OpenInstance_Params = sizeoftable( OpenInstanceOptions ); + + +TESTPARAMS +HelpOptions[] = { + + { 1, "Command Name", "CommandName", "CN", FALSE, String, 0, + NULL, NULL, 0, GlobalCmdArgs.ARGS.CmdName } +}; + + +DWORD +Num_Help_Params = sizeoftable( HelpOptions ); + + +TESTPARAMS +RegistryOptions[] = { + + { 1, "Operation Type", "Operation", "OP", FALSE, ParsedInteger, 0, + "QUERY_KEY", OperationTypeTable, sizeoftable( OperationTypeTable ), + &GlobalCmdArgs.ARGS.REGISTRY_ENTRY.OperationType }, + + { 2, "Key Database", "KeyDatabase", "KD", FALSE, ParsedInteger, 0, + "LOCAL_MACHINE", KeyDbaseTable, sizeoftable( KeyDbaseTable ), + &GlobalCmdArgs.ARGS.REGISTRY_ENTRY.KeyDatabase }, + + { 3, "Sub Key Name", "SubKey", "SK", FALSE, String, 0, + "\"System\\CurrentControlSet\\Services\\Sonic01\\Parameters\"", NULL, 0, + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKey }, + + {4, "Sub Key Class", "SubKeyClass", "SC", FALSE, String, 0, + "\"Network Drivers\"", NULL, 0, + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyClass }, + + {5, "Sub Key Value Name", "SubKeyValueName", "SN", FALSE, String, 0, + "\"NetworkAddress\"", NULL, 0, + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyValueName }, + + {6, "Sub Key Value Type", "SubKeyValueType", "ST", FALSE, ParsedInteger, 0, + "DWORD_REGULAR", ValueTypeTable, sizeoftable( ValueTypeTable ), + &GlobalCmdArgs.ARGS.REGISTRY_ENTRY.ValueType }, + + {7, "Sub Key Value", "SubKeyValue", "SV", FALSE, String, 0, + "\0", NULL, 0, + GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyValue } + +}; + + +DWORD +Num_Registry_Params = sizeoftable( RegistryOptions ); + + + + + +DWORD +TpctlParseArguments ( + IN TESTPARAMS Options[], + IN DWORD TestSize, + IN DWORD ArgC, + IN LPSTR ArgV[] + ) + +// --------------------- +// +// Routine Description: +// +// This routine parses a table +// +// Arguments: +// +// IN PARSE_PARAMS Option, - [Supplies | Returns] description-of-argument +// IN DWORD ArgC, - [Supplies | Returns] description-of-argument +// IN LPSTR ArgV[] - [Supplies | Returns] description-of-argument +// +// Return Value: +// +// DWORD = -1 if there was a parse error. +// = The number of parameters "eaten" otherwise. +// +// -------------------- + +{ + DWORD i, j; + BYTE Buffer[TPCTL_CMDLINE_SIZE]; + LPSTR ArgName, ArgValue; + BYTE ArgPrompt[TPCTL_CMDLINE_SIZE]; + LPBYTE NextToken; + DWORD RetVal; + BOOL Reparse; + BOOL Error; + BOOL ParsedArgumentsYet; + BOOL ArgNameValuePair; + DWORD OptionNumber; + DWORD OpenInstance; + LPBYTE p, q; + + // + // First determine the Open Instance, we may need it later. + // + + OpenInstance = TpctlGetOpenInstance( ArgC,ArgV ); + + // + // Lower the argument count thus ignoring the command itself, + // we don't care about that here. + // + + if ( ArgC ) + { + ArgC -= 1; // Don't count command in args. + } + + RetVal = min( ArgC, TestSize ); + + if ( ArgC > TestSize ) + { + ArgC = TestSize; + } + + // + // Load the defaults for each of the arguments into the Destination + // field. + // + + for ( i=0;iArgValueSet = TRUE; + continue; + } + +// globvars access + + if ( ArgValue[0] == '$') + { + PVOID valptr = TpctlParseGlobalVariable(ArgValue, ParsePtr->TestType); + LPBYTE s,d; + ULONG i; + + if (valptr != NULL) + { + switch ( ParsePtr->TestType) + { + case Integer: + *(PDWORD)ParsePtr->Destination = *(PDWORD)valptr; + break; + + case String: + strcpy( (LPSTR)ParsePtr->Destination, (LPSTR)valptr); + break; + + case Address4: + s = (LPBYTE)valptr; + d = (LPBYTE)ParsePtr->Destination; + for (i=0; i < FUNCTIONAL_ADDRESS_LENGTH; i++) + { + *d++ = *s++; + } + break; + + case Address6: + s = (LPBYTE)valptr; + d = (LPBYTE)ParsePtr->Destination; + for (i=0; i < ADDRESS_LENGTH; i++) + { + *d++ = *s++; + } + break; + } + } + continue; + } + +// end of globvars access + + switch( ParsePtr->TestType ) + { + + case Integer: + *(PDWORD)ParsePtr->Destination = strtoul( ArgValue,&NextToken,0 ); + break; + + case String: + strcpy( (LPSTR)ParsePtr->Destination,ArgValue ); + break; + + case Address4: + if ( TpctlParseAddress( ArgValue, + ParsePtr->Destination, + OpenInstance - 1, + FUNCTIONAL_ADDRESS_LENGTH ) != 0 ) + { + Error = TRUE; + } + + break; + + case Address6: + if ( TpctlParseAddress( ArgValue, + ParsePtr->Destination, + OpenInstance - 1, + ADDRESS_LENGTH ) != 0 ) + { + Error = TRUE; + } + break; + + case ParsedInteger: + if ( TpctlParseInteger( ArgValue, + ParsePtr->ParsedIntTable, + ParsePtr->ParsedIntTableSize, + ParsePtr->Destination ) != 0 ) + { + Error = TRUE; + } + + break; + + default: + TpctlErrorLog("ParseArguments: Invalid TestType\n",NULL); + Error = TRUE; + } + + if ( Error == TRUE ) + { + TpctlErrorLog("\n\tTpctl: Invalid Argument Value\n",NULL); + return (DWORD)-1;; + } + + // + // We have set this options new value from the command line, so + // set the flag stating not to prompt the user again if necessary. + // + + ParsePtr->ArgValueSet = TRUE; + + } // end of ParsePtr for now. + } + + // + // Set Up the "ArgPrompt" to request the new value for the argument. + // + + for ( i=1;i<=TestSize;i++ ) + { + + PTESTPARAMS ParsePtr = &Options[i-1]; + PTESTPARAMS OIParsePtr = &Options[0]; + + if (ScriptIndex != -1) + { + + // + // We are reading from a script file, so there is no prompting + // required. + + break; + } + + if ( ParsePtr->ArgValueSet != TRUE ) + { + + // + // If there was a command line argument, use it for the + // argument, otherwise prompt for the argument. + // + + Reparse = TRUE; + + strcpy( ArgPrompt, "\t" ); + strcat( ArgPrompt, ParsePtr->TestPrompt ); + strcat( ArgPrompt, " [" ); + + switch ( ParsePtr->TestType ) + { + case Integer: + { + BYTE Int[20]; + _ltoa( ParsePtr->IntegerDefault, Int , 10 ); + strcat( ArgPrompt, Int ); + } + break; + + case ParsedInteger: + case String: + if ( ParsePtr->StringDefault!=NULL ) + { + strcat( ArgPrompt,ParsePtr->StringDefault ); + } + break; + + case Address4: + if ( ParsePtr->StringDefault != NULL ) + { + p = ArgPrompt + strlen( ArgPrompt ); + q = ParsePtr->StringDefault; + + for( j=0;jStringDefault!=NULL ) + { + p = ArgPrompt + strlen( ArgPrompt ); + q = ParsePtr->StringDefault; + + for( j=0;j" ); + + TpctlPrompt( ArgPrompt,Buffer,TPCTL_CMDLINE_SIZE ); + + // + // and print the response to the log file if requested. + // + + TpctlCmdLneLog( Buffer, NULL ); + TpctlCmdLneLog( "\n", NULL ); + + + while ( Reparse ) + { + + // + // Clean up the buffer, removing any unnecessary spaces. + // + + TpctlFixBuffer( Buffer ); + + // + // If the user entered a ';' meaning all desired values + // have been entered, use the defaults for the rest. + // + + if ( TpctlFirstChar( Buffer,';' )) + { + i = TestSize; + break; + } + + // + // If the user simply hit enter meaning that we should + // use the default value for this argument, then do so. + // + + if ( TpctlFirstChar( Buffer,'\0' )) + { + break; + } + + // + // If the argument starts with '%' then it is an Environment + // variable, and we need to find out its actual value and + // replace it. + // + + if ( Buffer[0] == '%' ) + { + if ( !TpctlParseEnvironmentVariable( Buffer )) + { + return (DWORD)-1;; + } + } + + // + // Now put the newly entered value in its destination. + // + + + Error = FALSE; + + switch ( ParsePtr->TestType ) + { + case Integer: + *(PDWORD)ParsePtr->Destination = + strtol( Buffer,&NextToken,0 ); + Reparse = FALSE; + break; + + case String: + strcpy( (LPSTR)ParsePtr->Destination,Buffer ); + Reparse = FALSE; + break; + + case Address4: + if ( OpenInstance == -1 ) + { + OpenInstance = *(PDWORD)OIParsePtr->Destination; + } + + if ( TpctlParseAddress( Buffer, + ParsePtr->Destination, + OpenInstance - 1, + FUNCTIONAL_ADDRESS_LENGTH) != 0) + { + Error = TRUE; + } + Reparse = FALSE; + break; + + case Address6: + if ( OpenInstance == -1 ) + { + OpenInstance = *(PDWORD)OIParsePtr->Destination; + } + + if ( TpctlParseAddress( Buffer, + ParsePtr->Destination, + OpenInstance - 1, + ADDRESS_LENGTH ) != 0 ) + { + Error = TRUE; + } + Reparse = FALSE; + break; + + case ParsedInteger: + if ( TpctlParseInteger( Buffer, + ParsePtr->ParsedIntTable, + ParsePtr->ParsedIntTableSize, + ParsePtr->Destination ) != 0 ) + { + Error = TRUE; + } + Reparse = FALSE; + break; + } + + if ( Error ) + { + + // + // A bad value was entered for the last variable, see if + // the user would like to enter a new value. + // + + TpctlPrompt("\tTpctl: Argument Error, Re-enter? [Y]", + Buffer, TPCTL_CMDLINE_SIZE); + + // + // and print the response to the log file if requested. + // + + TpctlCmdLneLog( Buffer, NULL); + TpctlCmdLneLog( "\n", NULL); + + if ((( Buffer[0] == '\0' ) || + ( Buffer[0] == 'Y' )) || + ( Buffer[0] == 'y' )) + { + + // + // if so, reprompt the user for a new value. + // + + TpctlPrompt( ArgPrompt,Buffer,TPCTL_CMDLINE_SIZE ); + + // + // and print the response to the log file if requested. + // + + TpctlCmdLneLog( Buffer, NULL); + TpctlCmdLneLog( "\n", NULL); + Reparse = TRUE; + + } + else + { + + // + // Otherwise return an error. + // + + return (DWORD)-1;; + } + } + } + } + } + + return RetVal; +} + + +VOID +TpctlFixBuffer( + IN BYTE Buffer[] + ) + +// --------------------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------------------- + +{ + LPSTR Token = Buffer; + LPSTR NextToken = Buffer; // Anything that isn't NULL. + + if ( Buffer == NULL ) + { + return; + } + + while (( *Token != '\0' ) && ( *Token <= ' ' )) + { + Token++; // ignore leading blanks + } + + NextToken = strchr( Token,' ' ); // now see if there are any spaces. + + if ( NextToken != NULL ) // and if so, null them out. + { + *NextToken++ = '\0'; + } +} + + +DWORD +TpctlParseInteger ( + IN BYTE Buffer[], + IN PPARSETABLE ParseTable, + IN DWORD ParseTableSize, + OUT PDWORD Ret + ) + +// --------------------- +// +// Routine Description: +// +// This routine parses a "parsed integer" and returns it to the caller. +// +// Arguments: +// +// IN BYTE Buffer[], - [Supplies | Returns] description-of-argument +// IN PPARSETABLE ParseTable, - [Supplies | Returns] description-of-argument +// IN DWORD ParseTableSize - [Supplies | Returns] description-of-argument +// OUT PDWORD Ret +// +// Return Value: +// +// DWORD +// +// -------------------- + +{ + LPSTR Token = Buffer; + LPSTR NextToken = Buffer; // Anything that isn't NULL. + LPBYTE savePointer = NULL; + BYTE saveToken; + DWORD i; + + if ( Buffer == NULL ) + { + *Ret = 0; + return 0; + } + + // + // If the user specified an absolute number, return that. + // + + if ( isdigit( *Token )) + { + *Ret = strtoul( Token,&NextToken,0 ); + return 0; + } + + // + // Nope, the user passed in a string, parse that. + // + + // + // Initialize the initial value of the returned value to NULL. + // + + *Ret = 0; + + while ( NextToken != NULL ) + { + NextToken = strchr( Token,'|' ); + + if ( NextToken != NULL ) + { + saveToken = *NextToken; + savePointer = NextToken; + *NextToken++ = '\0'; + } + + for ( i=0;iResendAddress; + + for ( i=0 ; i < AddressLength ; i++ ) + { + *TmpAddr++ = *p++; + } + return 0; + + } + else if ( _stricmp( Buffer,LOCAL_ADDRESS ) == 0 ) + { + + // + // If the user has entered "localaddress" at the command line + // then we will use the local address stored in the Open Block. + // + + p = (LPBYTE)Open[OpenInstance].AdapterAddress; + + for ( i=0 ; i < AddressLength ; i++ ) + { + *TmpAddr++ = *p++; + } + return 0; + } + + i = j = 0; + + // + // Remove any spaces or hyphens from the address. + // + + while ( i < ( AddressLength * 2 )) + { + if (( Buffer[j] != ' ' ) && ( Buffer[j] != '-' )) + { + TmpBuf[i++] = Buffer[j]; + } + + // + // If we run of the end of the buffer return with an error. + // + + if ( ++j==100 ) + { + return (DWORD)-1;; + } + } + + // + // Now parse the "packed" address and turn the characters into numbers. + // + + for( i=0 ; i < AddressLength ; i++ ) + { + digit = '\0'; + + for( j=0;j<2;j++ ) + { + if (( TmpBuf[i*2+j] >= '0' ) && ( TmpBuf[i*2+j] <= '9' )) + { + n[0] = TmpBuf[i*2+j]; + n[1] = '\0'; + digit += (BYTE)(atoi( n )); + + } + else if (( TmpBuf[i*2+j] >= 'a' ) && ( TmpBuf[i*2+j] <= 'f' )) + { + digit += (BYTE)(( TmpBuf[i*2+j] - 'a' ) + 10 ); + } + else if (( TmpBuf[i*2+j] >= 'A' ) && ( TmpBuf[i*2+j] <= 'F' )) + { + digit += (BYTE)(( TmpBuf[i*2+j] - 'A' ) + 10 ); + } + else + { + + // + // We have an invalid Address; return error. + // + + return (DWORD)-1;; + } + + // + // Raise the high half by 0xf. + // + + if ( j==0 ) + { + digit *= 16; + } + } + + *TmpAddr++ = (BYTE)digit; + } + + return 0; +} + + + +BOOL +TpctlParseArgumentPairs( + IN LPSTR Argument, + OUT LPSTR *ArgName, + OUT LPSTR *ArgValue + ) + +// --------------------- +// +// Routine Description: +// +// This routine parses an argument string to determine if it contains +// an argument name/value pair, or just an argument value. +// +// Arguments: +// +// Argument - The argument string. +// +// ArgName - The name of the argument if there is one. +// +// ArgValue - The argument value. +// +// Return Value: +// +// BOOL - TRUE if there is a name/value pair, FALSE otherwise. +// +// ------------------- + +{ + LPSTR temp; + BOOL EqualsSign; + + temp = Argument; + EqualsSign = FALSE; + + if ( strchr(Argument,'=') != NULL ) + { + EqualsSign = TRUE ; + } + + // + // If there is an equals sign, then we have an argument name/value + // pair. Get each, and put them in their respective return strings. + // + + if (EqualsSign) + { + *ArgName = Argument; + temp = Argument; + + // + // Search for the end of the argument name, and null terminate it. + // + + while ((*temp != '=') && (*temp != ' ')) + { + temp++; + } + + *temp++ = '\0'; + + // + // Then search for the beginning of the argument value, and return + // it in ArgValue. + // + + while ((*temp == '=') || (*temp == ' ')) + { + temp++; + } + + *ArgValue = temp; + + } + else + { + + // + // There is only an argument value so null out the ArgName, and + // return the value in ArgValue. + // + + ArgName = '\0'; + *ArgValue = Argument; + } + + return EqualsSign; +} + + + +BOOL +TpctlParseSetInfoArguments( + IN OUT DWORD *ArgC, + IN OUT LPSTR ArgV[], + IN OUT DWORD *tmpArgC, + IN OUT LPSTR tmpArgV[] + ) + +// -------------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// BOOL - +// +// ------------- + +{ + DWORD i; + + *tmpArgC = 1; + tmpArgV[0] = '\0'; + + // + // See if the arguments are name-value pairs, or just the + // argument values, if there is an equal sign in the first + // argument then they are name-value paired arguments. + // + + if ( strchr(ArgV[1],'=') != NULL ) + { + // + // We have name value pairs + // + + for (i=1;i<*ArgC;i++) + { + + // + // So search the ArgV for the correct argument name, and + // if it is found have tmpArgV refernce it. + // + + if (( _strnicmp(ArgV[i],"PacketFilter",12) == 0 ) || + ( _strnicmp(ArgV[i],"StationAddress",14) == 0 ) || + ( _strnicmp(ArgV[i],"FunctionalAddress",17) == 0 ) || + ( _strnicmp(ArgV[i],"GroupAddress",17) == 0 ) || + ( _strnicmp(ArgV[i],"Lookahead",9) == 0 ) || + ( _strnicmp(ArgV[i],"PF",2) == 0 ) || + ( _strnicmp(ArgV[i],"SA",2) == 0 ) || + ( _strnicmp(ArgV[i],"FA",2) == 0 ) || + ( _strnicmp(ArgV[i],"GA",2) == 0 ) || + ( _strnicmp(ArgV[i],"LA",2) == 0 )) + { + + // + // We have found what we are looking for. Set the tmpArgC, + // and set tmpArgV[i] to point to it. + // + + ++*tmpArgC; + tmpArgV[1] = ArgV[i]; + + // + // then make sure that it is at the end of the ArgV. + // This is required by ParseArguments to successfully + // handle parsing the OpenInstance and InfoClass + // arguments first. + // + + if ( i != *ArgC - 1 ) + { + ArgV[i] = ArgV[*ArgC-1]; + //ArgV[*ArgC-1] = //tmpArgV[1]; + } + + ArgV[*ArgC-1] = NULL; + --*ArgC; + + return TRUE; + } + } + + } + else + { + + // + // If there are no name-value pairings for the arguments, then + // we know the commands must be in the correct order, and the + // Class Specific Info argument MUST be last or 4th in ArgV. + // + + if ( *ArgC >= 4 ) + { + + // + // We have found the argument, have tmpArgV reference it and + // return. + // + + *tmpArgC = 2; + tmpArgV[1] = ArgV[3]; + + --*ArgC; + ArgV[3] = NULL; + + return TRUE; + + } + } + + // + // Otherwise there are not enough arguments on the command + // line to include the Class Specific Info, or it simply does + // not exist on the command line, if it is needed, ti will + // have to be prompted for later. + // + + return FALSE; +} + + +BOOL +TpctlParseEnvironmentVariable( + IN BYTE Buffer[] + ) + +// ------------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------------ + +{ + BYTE TmpBuffer[100]; + LPSTR EndOfVar = Buffer; // Anything that isn't NULL. + LPSTR Variable; + + // + // If the environment variable passed in is null, return false now. + // + + if ( Buffer == NULL ) + { + TpctlErrorLog("\n\tTpctl: Invalid Environment Variable Format \"%%\".\n",NULL); + return FALSE; + } + + // + // Otherwise copy the variable into a temp buffer. + // + + strcpy( TmpBuffer,&Buffer[1] ); + + // + // Now null out the '%' symbol if it exists to allow the querying + // of the environment variable. + // + + EndOfVar = strchr( TmpBuffer,'%' ); + + if ( EndOfVar == NULL ) + { + TpctlErrorLog("\n\tTpctl: Invalid Environment Variable Format \"%%%s\".\n",TmpBuffer); + return FALSE; + } + else + { + *EndOfVar = '\0'; + } + + // + // and then query the environment variable. + // + + Variable = getenv( _strupr( TmpBuffer )); + + if ( Variable == NULL ) + { + TpctlErrorLog("\n\tTpctl: Undefined Environment Variable \"%%%s%%\".\n",TmpBuffer); + return FALSE; + } + + strcpy( Buffer,Variable); + + return TRUE; +} + + + +BOOL +TpctlFirstChar( + IN BYTE Buffer[], + IN BYTE Char + ) +{ + LPSTR Token = Buffer; + + if ( Buffer == NULL ) + { + return FALSE; + } + + while (( *Token != '\0' ) && ( *Token == ' ' )) + { + Token++; // ignore leading blanks + } + + if ( *Token == (CHAR)Char ) + { + return TRUE; + } + + return FALSE; +} + + +DWORD +TpctlGetOptionNumber( + IN PTESTPARAMS Options, + IN DWORD TestSize, + IN LPSTR ArgName + ) + +// ------------ +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ----------- + +{ + DWORD i; + + for(i=0; i +#include +#include + +#include + +#include +#include +#include + +#include "tpctl.h" +#include "parse.h" + + + +VOID +TpctlPrintResults( + PREQUEST_RESULTS Results, + DWORD CmdCode, + NDIS_OID OID + ) + +// ---------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// --------- + +{ + DWORD Status; + LPSTR TmpBuf; + DWORD BytesWritten; + BOOL ErrorReturned = FALSE; + + TmpBuf = GlobalBuf; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tCmdCode = %s\n", + TpctlGetCmdCode( CmdCode )); + + if ( CmdCode == SETINFO ) + { + //ASSERT( Results->OID == OID ); + //ASSERT( Results->NdisRequestType == NdisRequestSetInformation ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tOID = %d\n",OID); + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tReturn Status = %s\n", + TpctlGetStatus( Results->RequestStatus )); + + if ( Results->RequestStatus != STATUS_SUCCESS ) + { + ErrorReturned = TRUE; + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRequest Pended = %s", + Results->RequestPended ? "TRUE" : "FALSE"); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + if ( CmdCode == OPEN ) + { + if ( Results->OpenRequestStatus != NDIS_STATUS_SUCCESS ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tWARNING: Secondary Open Request failed.\n"); + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRequest OID = 0x%08lX\n",Results->OID); + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRequest Returned Status = %s\n", + TpctlGetStatus( Results->OpenRequestStatus )); + + if ( Results->OpenRequestStatus != STATUS_SUCCESS ) + { + ErrorReturned = TRUE; + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tBytesWritten = %d\n", + Results->BytesReadWritten); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tBytesNeeded = %d\n\n", + Results->BytesNeeded); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tThe open instance exists but some tests may not\n"); + TmpBuf += (BYTE)sprintf(TmpBuf,"\twork properly due to this failure.\n"); + } + } + + if ( Verbose ) + { + if ( !WriteFile(GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) + { + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } + else if ( CommandLineLogging ) + { + if( !WriteFile( CommandLineLogHandle, + GlobalBuf, + (TmpBuf-GlobalBuf), + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } +} + + + +VOID +TpctlPrintStressResults( + IN PSTRESS_RESULTS Results, + IN BOOL Ack10 + ) + +// --------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// -------- + +{ + PGLOBAL_COUNTERS gc; + PINSTANCE_COUNTERS ic; + DWORD i; + DWORD Status; + LPSTR TmpBuf; + DWORD BytesWritten; + + + //ASSERT( Results->Signature == STRESS_RESULTS_SIGNATURE ); + + TmpBuf = GlobalBuf; + TmpBuf += (BYTE)sprintf(TmpBuf,"\nCLIENT STRESS STATISTICS:\n\n"); + TmpBuf += (BYTE)sprintf(TmpBuf,"Client Address %02X-%02X-%02X-%02X-%02X-%02X - ", + Results->Address[0],Results->Address[1],Results->Address[2], + Results->Address[3],Results->Address[4],Results->Address[5]); + TmpBuf += (BYTE)sprintf(TmpBuf,"OpenInstance %d",Results->OpenInstance); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER\n" ); + gc = &Results->Global; + + for ( i=0;iNumServers;i++ ) + { + ic = &Results->Servers[i].Instance; + gc->Sends += ic->Sends; + gc->Receives += ic->Receives; + gc->CorruptRecs = ic->CorruptRecs; + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"Total Packets Sent:\t\t%10lu\n", + gc->Sends); + TmpBuf += (BYTE)sprintf(TmpBuf,"Total Packets Received:\t\t%10lu\n", + gc->Receives); + + if ( Ack10 == TRUE ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"Total Packets Lost:\t\t%10lu\n\n", + (( 10 * gc->Sends ) - gc->Receives )); + } + else + { + TmpBuf += (BYTE)sprintf(TmpBuf,"Total Packets Lost:\t\t%10lu\n\n", + ( gc->Sends - gc->Receives )); + } + + if ( gc->CorruptRecs > 0 ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"Corrupted Packet Receives:\t%10lu\n\n", + gc->CorruptRecs); + } + + if ( gc->InvalidPacketRecs > 0 ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"Invalid Packet Receives:\t%10lu\n\n", + gc->InvalidPacketRecs); + } + + // + // Display the number of packets sent/received per second. + // + + TmpBuf += (BYTE)sprintf(TmpBuf,"Packets Per Second:\t\t%10lu", + Results->PacketsPerSecond ); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER\n" ); + + // + // And then print out the information about each of the Servers + // involved in the test. + // + + TmpBuf += (BYTE)sprintf(TmpBuf,"The Client had %d Server(s) for this test as follows:", + Results->NumServers); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER\n" ); + + for ( i=0;iNumServers;i++ ) + { + //ASSERT( Results->Servers[i].Signature == STRESS_RESULTS_SIGNATURE ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"Server # %d - ",i+1); + TmpBuf += (BYTE)sprintf(TmpBuf,"Address %02X-%02X-%02X-%02X-%02X-%02X - ", + Results->Servers[i].Address[0],Results->Servers[i].Address[1], + Results->Servers[i].Address[2],Results->Servers[i].Address[3], + Results->Servers[i].Address[4],Results->Servers[i].Address[5]); + + TmpBuf += (BYTE)sprintf(TmpBuf,"OpenInstance %d", + Results->Servers[i].OpenInstance); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + } + + TmpBuf += (BYTE)sprintf(TmpBuf,"\nSERVER STRESS STATISTICS:\n\n"); + TmpBuf += (BYTE)sprintf(TmpBuf,"Server Instance Counters collected on the Client:\n\n"); + TmpBuf += (BYTE)sprintf(TmpBuf,"Server #"); + + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu",i+1); + } + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER\n" ); + + // Number of packets sent to the server. + + TmpBuf += (BYTE)sprintf(TmpBuf,"S:\t"); + + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].Instance.Sends); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of packets received from the server. + + TmpBuf += (BYTE)sprintf(TmpBuf,"R:\t"); + + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].Instance.Receives); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of packets lost in transit to the server and back. + + TmpBuf += (BYTE)sprintf(TmpBuf,"L:\t"); + + for ( i=0;iNumServers;i++ ) + { + if ( Ack10 == TRUE ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + (( 10 * Results->Servers[i].Instance.Sends ) - + Results->Servers[i].Instance.Receives )); + } + else + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + ( Results->Servers[i].Instance.Sends - + Results->Servers[i].Instance.Receives )); + } + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of packet sends that pended. + + TmpBuf += (BYTE)sprintf(TmpBuf,"SP:\t"); + + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].Instance.SendPends); + } + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + // Number of packet sends pending that completed. + + TmpBuf += (BYTE)sprintf(TmpBuf,"SC:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].Instance.SendComps); + } + ADD_DIFF_FLAG( TmpBuf, "EQUAL_LAST" ); + + // Number of packet sends that failed. + + TmpBuf += (BYTE)sprintf(TmpBuf,"SF:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].Instance.SendFails); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of corrupted packets received. + + TmpBuf += (BYTE)sprintf(TmpBuf,"CR:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].Instance.CorruptRecs); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\nServer Instance Counters collected on the Server:\n\n"); + + // Number of packets received from the server. + + TmpBuf += (BYTE)sprintf(TmpBuf,"R:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.Receives); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of packets sent to the server. + + TmpBuf += (BYTE)sprintf(TmpBuf,"S:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.Sends); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of packets lost in transit to the server and back. + + TmpBuf += (BYTE)sprintf(TmpBuf,"L:\t"); + for ( i=0;iNumServers;i++ ) + { + if ( Ack10 == TRUE ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + (( 10 * Results->Servers[i].S_Instance.Receives ) - + Results->Servers[i].S_Instance.Sends )); + } + else + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + ( Results->Servers[i].S_Instance.Receives - + Results->Servers[i].S_Instance.Sends )); + } + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of packets sends that failed. + + TmpBuf += (BYTE)sprintf(TmpBuf,"SF:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.SendFails); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + // Number of packets sends that pended. + + TmpBuf += (BYTE)sprintf(TmpBuf,"SP:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.SendPends); + } + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + // Number of packets sends pending that completed. + + TmpBuf += (BYTE)sprintf(TmpBuf,"SC:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.SendComps); + } + ADD_DIFF_FLAG( TmpBuf, "EQUAL_LAST" ); + + // Number of transfer datas on packets. + + TmpBuf += (BYTE)sprintf(TmpBuf,"TD:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.XferData); + } + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + // Number of transfer datas on packets that pended. + + TmpBuf += (BYTE)sprintf(TmpBuf,"TDP:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.XferDataPends); + } + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + // Number of transfer datas on packets that completed. + + TmpBuf += (BYTE)sprintf(TmpBuf,"TDC:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.XferDataComps); + } + ADD_DIFF_FLAG( TmpBuf, "EQUAL_LAST" ); + + // Number of transfer datas on packets that failed. + + TmpBuf += (BYTE)sprintf(TmpBuf,"TDF:\t"); + for ( i=0;iNumServers;i++ ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"%10lu", + Results->Servers[i].S_Instance.XferDataFails); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); + + if ( Verbose ) + { + if ( !WriteFile(GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) + { + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } + else if ( CommandLineLogging ) + { + if ( !WriteFile(CommandLineLogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } + + TpctlZeroStressStatistics( Results ); +} + + + +VOID +TpctlPrintSendResults( + PSEND_RECEIVE_RESULTS Results + ) + +// ---- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ----- + +{ + DWORD Status; + LPSTR TmpBuf; + DWORD BytesWritten; + + + //ASSERT( Results->Signature == SENDREC_RESULTS_SIGNATURE ); + + TmpBuf = GlobalBuf; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPacket Sends = %10lu\n", + Results->Counters.Sends); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Pends = %10lu", + Results->Counters.SendPends); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Send Completes = %10lu", + Results->Counters.SendComps); + + ADD_DIFF_FLAG( TmpBuf, "EQUAL_LAST" ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Send Fails = %10lu\n", + Results->Counters.SendFails); + + if ( Verbose ) + { + if ( !WriteFile(GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) + { + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } + else if ( CommandLineLogging ) + { + if ( !WriteFile(CommandLineLogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } +} + + + +VOID +TpctlPrintReceiveResults( + PSEND_RECEIVE_RESULTS Results + ) + +// ------ +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ---- + +{ + DWORD Status; + LPSTR TmpBuf; + DWORD BytesWritten; + + //ASSERT( Results->Signature == SENDREC_RESULTS_SIGNATURE ); + + TmpBuf = GlobalBuf; + + // Receive statistics + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPacket Receives = %10lu\n", + Results->Counters.Receives); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Receive Completes = %10lu", + Results->Counters.ReceiveComps); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tCorrupt Receives = %10lu\n", + Results->Counters.CorruptRecs); + + + // RESEND initiated statistics + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tRESEND initiated Packet Sends = %10lu\n", + Results->Counters.Sends); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRESEND initiated Packet Send Pends = %10lu", + Results->Counters.SendPends); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRESEND initiated Packet Send Completes = %10lu", + Results->Counters.SendComps); + + ADD_DIFF_FLAG( TmpBuf, "EQUAL_LAST" ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRESEND initiated Packet Send Fails = %10lu\n", + Results->Counters.SendFails); + + // Transfer Data statistics + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPacket Transfer Data = %10lu\n", + Results->Counters.XferData); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Transfer Data Pends = %10lu", + Results->Counters.XferDataPends); + + ADD_DIFF_FLAG( TmpBuf, "MAY_DIFFER" ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Transfer Data Completes = %10lu", + Results->Counters.XferDataComps); + + ADD_DIFF_FLAG( TmpBuf, "EQUAL_LAST" ); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Transfer Data Fails = %10lu\n", + Results->Counters.XferDataFails); + + if ( Verbose ) + { + if ( !WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) + { + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } + else if ( CommandLineLogging ) + { + if ( !WriteFile(CommandLineLogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } +} + + +VOID +TpctlPrintPerformResults( + PPERF_RESULTS Results + ) + +// ---- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ----- + +{ + DWORD Status; + LPSTR TmpBuf; + DWORD BytesWritten; + ULONG speed; + double d_speed; + PULONG KernelPercent; + ULONG NumCpus; + + ASSERT( Results->Signature == PERF_RESULTS_SIGNATURE ); + if (!Results->ResultsExist) + { + return; + } + + if (Results->Mode < 4) + { + NumCpus = CpuUsageGetData(&KernelPercent, Results->Milliseconds); + } + else if (Results->Mode < 6) + { + NumCpus = CpuUsageGetData(&KernelPercent, Results->S_Milliseconds); + } + TmpBuf = GlobalBuf; + + switch(Results->Mode) + { + case 0: // client -> address + TmpBuf += (BYTE)sprintf(TmpBuf, "\n\nPerformance Test 0: Client -> Address\n\n"); + break; + + case 1: // client -> server + TmpBuf += (BYTE)sprintf(TmpBuf, "\n\nPerformance Test 1: Client -> Server\n\n"); + break; + + case 2: // client -> server, server ACKS + TmpBuf += (BYTE)sprintf(TmpBuf, "\n\nPerformance Test 2: Client -> Server with ACKS\n\n"); + break; + + case 3: // client -> server, server -> client + TmpBuf += (BYTE)sprintf(TmpBuf, "\n\nPerformance Test 3: Client <-> Server\n\n"); + break; + + case 4: // server -> client + TmpBuf += (BYTE)sprintf(TmpBuf, "\n\nPerformance Test 4: Server -> Client\n\n"); + break; + + case 5: // client REQS, server -> client + TmpBuf += (BYTE)sprintf(TmpBuf, "\n\nPerformance Test 5: Server -> Client with REQS\n\n"); + break; + + default: + printf("\n\nUnknown performance Test: %d\n\n", Results->Mode); + return; + + } + if (!NumCpus) + { + TmpBuf += (BYTE)sprintf(TmpBuf, "Cpu usage information not available\n\n"); + } + else if (NumCpus == 1) + { + if (KernelPercent[0] > 1000) + { + KernelPercent[0] = 1000; + } + TmpBuf += (BYTE)sprintf(TmpBuf, "Cpu usage = %d.%d%%\n\n",KernelPercent[0]/10, KernelPercent[0]%10); + } + else + { + ULONG cpucnt; + ULONG *procPercent; + + procPercent = &KernelPercent[1]; + TmpBuf += (BYTE)sprintf(TmpBuf, "Cpu usage per processor: "); + + for(cpucnt=0; cpucnt < NumCpus; cpucnt++) + { + if ( (cpucnt != 0) && ((cpucnt % 4) == 0) ) + { + ADD_SKIP_FLAG( TmpBuf, "SKIP_LINE" ); + TmpBuf += (BYTE)sprintf(TmpBuf, " "); + } + if (*procPercent > 1000) + { + *procPercent = 1000; + } + TmpBuf += (BYTE)sprintf(TmpBuf, "#%d - %d.%d%% ", + cpucnt, *procPercent/10, *procPercent%10); + } + ADD_SKIP_FLAG( TmpBuf, "SKIP_LINE" ); + ADD_SKIP_FLAG( TmpBuf, "SKIP_LINE" ); + TmpBuf += (BYTE)sprintf(TmpBuf, "Average cpu usage = %d.%d%%\n\n", + KernelPercent[0]/10, KernelPercent[0]%10); + } + + + TmpBuf += (BYTE)sprintf(TmpBuf, "Sending %d packets of %d bytes each\n\n", + Results->PacketCount, Results->PacketSize); + + if (Results->Mode < 4) + { + TmpBuf += (BYTE)sprintf(TmpBuf, "Client transmission statistics\n\n"); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPackets Sent = %10lu\n", Results->Sends); + if (Results->SendFails) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Send Failures = %10lu\n", + Results->SendFails); + } + if (Results -> Restarts) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRestarts Required = %10lu\n", + Results->Restarts); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\tElapsed time = %10lu milliseconds\n", + Results->Milliseconds); + + d_speed = (1.0 * Results->Sends) / Results->Milliseconds; + speed = (ULONG)((1000.0 * d_speed) + 0.5); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tTransmit Rate = %10lu packets per second\n", + speed); + + d_speed *= Results->PacketSize; + speed = (ULONG)(d_speed + 0.5); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\t = %10lu Kbytes per second\n\n", + speed); + + if (NumCpus && (Results->Mode < 2)) + { + d_speed *= 100.0; + d_speed /= KernelPercent[0]; + speed = (ULONG)(d_speed + 0.5); + TmpBuf += (BYTE)sprintf(TmpBuf, "\tSend KB/sec/cpu = %8lu.%u\n\n", speed/10, speed%10); + } + + if (Results->Mode > 0) + { + TmpBuf += (BYTE)sprintf(TmpBuf, "Server reception statistics\n\n"); + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPackets Received = %10lu\n", + Results->S_Receives); + if (Results->S_Receives != Results->PacketCount) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPackets Lost = %10lu\n", + Results->PacketCount - Results->S_Receives); + } + if (Results->S_SelfReceives) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tOwn Packets Received = %10lu\n", + Results->S_SelfReceives); + } + } + } + + if (Results->Mode > 2) + { + TmpBuf += (BYTE)sprintf(TmpBuf, "\nServer transmission statistics\n\n"); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPackets Sent = %10lu\n", Results->S_Sends); + if (Results->S_SendFails) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPacket Send Failures = %10lu\n", + Results->S_SendFails); + } + if (Results -> S_Restarts) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tRestarts Required = %10lu\n", + Results->S_Restarts); + } + TmpBuf += (BYTE)sprintf(TmpBuf,"\tElapsed time = %10lu milliseconds\n", + Results->S_Milliseconds); + + d_speed = (1.0 * Results->S_Sends) / Results->S_Milliseconds; + speed = (ULONG)((1000.0 * d_speed) + 0.5); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tTransmit Rate = %10lu packets per second\n", + speed); + + d_speed *= Results->PacketSize; + speed = (ULONG)(d_speed + 0.5); + + TmpBuf += (BYTE)sprintf(TmpBuf,"\t = %10lu Kbytes per second\n\n", + speed); + + + TmpBuf += (BYTE)sprintf(TmpBuf, "Client reception statistics\n\n"); + TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tPackets Received = %10lu\n", + Results->Receives); + + if (NumCpus && (Results->Mode == 4)) + { + d_speed *= 100.0; + d_speed /= KernelPercent[0]; + speed = (ULONG)(d_speed + 0.5); + TmpBuf += (BYTE)sprintf(TmpBuf, "\tReceive KB/sec/cpu = %8lu.%u\n\n", speed/10, speed%10); + } + + if (Results->Receives != Results->PacketCount) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tPackets Lost = %10lu", + Results->PacketCount - Results->Receives); + ADD_SKIP_FLAG( TmpBuf, "SKIP_LINE" ); + } + if (Results->SelfReceives) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tOwn Packets Received = %10lu", + Results->SelfReceives); + ADD_SKIP_FLAG( TmpBuf, "SKIP_LINE" ); + } + + } + + TmpBuf += (BYTE)sprintf(TmpBuf, "\n\n\n"); + + + if ( Verbose ) + { + if ( !WriteFile(GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) + { + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } +} + + + +VOID +TpctlPrintEventResults( + PEVENT_RESULTS Event + ) + +// ---- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// --- + +{ + DWORD Status; + LPSTR TmpBuf; + DWORD BytesWritten; + + + //ASSERT( Event->Signature == EVENT_RESULTS_SIGNATURE ); + + TmpBuf = GlobalBuf; + + TmpBuf += (BYTE)sprintf(TmpBuf,"\tEvent Type = %s", + TpctlGetEventType( Event->TpEventType )); + + // + // SanjeevK : #5963 + // #11324 Enhancement + // + + if ( ( Event->TpEventType == IndicateStatusComplete ) || + ( Event->TpEventType == IndicateStatus ) ) + { + ADD_SKIP_FLAG( TmpBuf, "SKIP_LINE" ); + } + else + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\n" ); + } + + if ( Event->QueueOverFlowed == TRUE ) + { + TmpBuf += (BYTE)sprintf(TmpBuf,"\tEvent Queue Overflowed."); + // + // SanjeevK : #5963 + // + // Note: This flag was added since all this does is cause an + // this line to be ignored. The event however gets + // reported which is the primary aim of this statement. + // + ADD_SKIP_FLAG( TmpBuf, "SKIP_LINE" ); + } + + if ( Verbose ) + { + if ( !WriteFile(GetStdHandle( STD_OUTPUT_HANDLE ), + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to screen failed, returned 0x%lx\n",(PVOID)Status); + } + } + + if ( CommandsFromScript ) + { + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + + } + else if ( CommandLineLogging ) + { + if ( !WriteFile(CommandLineLogHandle, + GlobalBuf, + TmpBuf-GlobalBuf, + &BytesWritten, + NULL )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: WriteFile to logfile failed, returned 0x%lx\n",(PVOID)Status); + } + } +} + + + +VOID +TpctlZeroStressStatistics( + PSTRESS_RESULTS Results + ) + +// ---- +// +// Routine Description: +// +// This routine zeros out the stress results buffer. +// +// Arguments: +// +// Results - the buffer to zero out the contents of. +// +// Return Value: +// +// None. +// +// ---- + +{ + DWORD i; + + ZeroMemory (Results->Address, ADDRESS_LENGTH); + + Results->OpenInstance = 0xFFFFFFFF; + Results->NumServers = 0; + + Results->Global.Sends = 0; + Results->Global.Receives = 0; + Results->Global.CorruptRecs = 0; + Results->Global.InvalidPacketRecs = 0; + + for ( i=0;iServers[i].Address, ADDRESS_LENGTH); + + Results->Servers[i].OpenInstance = 0xFFFFFFFF; + Results->Servers[i].StatsRcvd = FALSE; + + Results->Servers[i].Instance.Sends = 0; + Results->Servers[i].Instance.SendPends = 0; + Results->Servers[i].Instance.SendComps = 0; + Results->Servers[i].Instance.SendFails = 0; + Results->Servers[i].Instance.Receives = 0; + Results->Servers[i].Instance.CorruptRecs = 0; + + Results->Servers[i].S_Instance.Sends = 0; + Results->Servers[i].S_Instance.SendPends = 0; + Results->Servers[i].S_Instance.SendComps = 0; + Results->Servers[i].S_Instance.SendFails = 0; + Results->Servers[i].S_Instance.Receives = 0; + Results->Servers[i].S_Instance.CorruptRecs = 0; + + Results->Servers[i].S_Global.Sends = 0; + Results->Servers[i].S_Global.Receives = 0; + Results->Servers[i].S_Global.CorruptRecs = 0; + Results->Servers[i].S_Global.InvalidPacketRecs = 0; + } +} + + + +DWORD +TpctlLog( + LPSTR String, + PVOID Input + ) +{ + DWORD Status; + + // + // If we are in verbose mode, then print the string to the screen. + // + + if ( Verbose ) + { + printf( String,Input ); + + // + // If we are reading commands from a script write the string to + // the script log file. + // + + if ( CommandsFromScript ) + { + Status = TpctlScriptLog( String, Input ); + } + + // + // Otherwise if we are logging commands entered by hand write + // the string to the commandline log file. + // + + else if ( CommandLineLogging ) + { + Status = TpctlCmdLneLog( String,Input ); + } + } + + return NO_ERROR; +} + + + +DWORD +TpctlErrorLog( + LPSTR String, + PVOID Input + ) +{ + DWORD Status; + + // + // First print the error message to the screen. + // + + printf( String,Input ); + + // + // If we are reading commands from a script write the string to + // the script log file. + // + + if ( CommandsFromScript ) + { + Status = TpctlScriptLog( String, Input ); + } + + // + // Otherwise we are logging commands entered by hand write the + // string to the commandline log file. + // + + else if ( CommandLineLogging ) + { + Status = TpctlCmdLneLog( String,Input ); + } + + return NO_ERROR; +} + + + +DWORD +TpctlScriptLog( + LPSTR String, + PVOID Input + ) +{ + DWORD Status; + BYTE Buffer[0x100]; + DWORD BytesWritten; + + // + // If we are reading commands from a script write the string to + // the script's log file. + // + + if ( CommandsFromScript ) + { + // + // set up the buffer that will print it to the logfile, and write + // it out. + // + + sprintf( Buffer,String,Input ); + + if ( !WriteFile(Scripts[ScriptIndex].LogHandle, + Buffer, + strlen( Buffer ), + &BytesWritten, + NULL )) + { + Status = GetLastError(); + printf("\n\tTpctlScriptLog: write to logfile failed, returned 0x%lx\n",Status); + return Status; + } + } + + return NO_ERROR; +} + + + +DWORD +TpctlCmdLneLog( + LPSTR String, + PVOID Input + ) +{ + DWORD Status; + BYTE Buffer[0x100]; + DWORD BytesWritten; + + // + // If we are logging commands entered by hand write the + // string to that log file. We will not do this if we are + // already logging commands to a scriptfile log file.. + // + + if (( CommandLineLogging ) && ( !CommandsFromScript )) + { + // + // Then set up the buffer that will print it to the logfile + // + + sprintf( Buffer,String,Input ); + + // + // and print it. + // + + if ( !WriteFile(CommandLineLogHandle, + Buffer, + strlen( Buffer ), + &BytesWritten, + NULL )) + { + Status = GetLastError(); + printf("\n\tTpctlCmdLneLog: write to command logging file failed, returned 0x%lx\n", + Status); + return Status; + } + } + + return NO_ERROR; +} + + diff --git a/private/ntos/ndis/testprot/tpctl/sources b/private/ntos/ndis/testprot/tpctl/sources new file mode 100644 index 000000000..a1cbfb202 --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/sources @@ -0,0 +1,49 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +UMLIBS=obj\*\tpctl.lib ..\tplib\obj\*\tplib.lib \nt\public\sdk\lib\*\setargv.obj +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=testprot +MINORCOMP=tpctl + +TARGETNAME=tpctl +TARGETPATH=obj +TARGETTYPE=PROGRAM + +INCLUDES=..\inc;..\..\..\inc + +SOURCES=init.c \ + cmd.c \ + parse.c \ + results.c \ + globals.c \ + info.c \ + cpuperf.c \ + tpctl.c + +RELATIVE_DEPTH=..\..\.. + +UMTYPE=console +UMLIBS=..\tplib\obj\*\tplib.lib \ + $(BASEDIR)\public\sdk\lib\*\setargv.obj \ + $(BASEDIR)\public\sdk\lib\*\ntdll.lib diff --git a/private/ntos/ndis/testprot/tpctl/tp_ndis.h b/private/ntos/ndis/testprot/tpctl/tp_ndis.h new file mode 100644 index 000000000..ac633213a --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/tp_ndis.h @@ -0,0 +1,180 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + tpc_ndis.h + +Abstract: + + This module defines NDIS 3.0 specific DEFINE for the TPCTL app. + +Author: + + Tom Adams (tomad) 20-Nov-1992 + +Revision History: + + 20-Nov-1992 tomad + + Created + +--*/ + +#include + +typedef int NDIS_STATUS, *PNDIS_STATUS; // note default size + +// +// Request types used by NdisRequest; constants are added for +// all entry points in the MAC, for those that want to create +// their own internal requests. +// + +typedef enum _NDIS_REQUEST_TYPE { + NdisRequestQueryInformation, + NdisRequestSetInformation, + NdisRequestQueryStatistics, + NdisRequestOpen, + NdisRequestClose, + NdisRequestSend, + NdisRequestTransferData, + NdisRequestReset, + NdisRequestGeneric1, + NdisRequestGeneric2, + NdisRequestGeneric3, + NdisRequestGeneric4 +} NDIS_REQUEST_TYPE, *PNDIS_REQUEST_TYPE; + + +/* + * Medium Ndis Driver is running on + * + * + * typedef enum _NDIS_MEDIUM { + * NdisMedium802_3, + * NdisMedium802_5, + * NdisMediumFddi, + * NdisMediumAsync, + * NdisMediumLocalTalk, + * NdisMediumDix + * } NDIS_MEDIUM, *PNDIS_MEDIUM + * + * SanjeevK: Took out this definition since this structure is now defined in + * NTDDNDIS.H + * + */ + +// +// NDIS_STATUS values +// + +#define NDIS_STATUS_SUCCESS ((NDIS_STATUS) STATUS_SUCCESS) +#define NDIS_STATUS_PENDING ((NDIS_STATUS) STATUS_PENDING) +#define NDIS_STATUS_NOT_RECOGNIZED ((NDIS_STATUS)0x00010001L) +#define NDIS_STATUS_NOT_COPIED ((NDIS_STATUS)0x00010002L) + +#define NDIS_STATUS_ONLINE ((NDIS_STATUS)0x40010003L) +#define NDIS_STATUS_RESET_START ((NDIS_STATUS)0x40010004L) +#define NDIS_STATUS_RESET_END ((NDIS_STATUS)0x40010005L) +#define NDIS_STATUS_RING_STATUS ((NDIS_STATUS)0x40010006L) +#define NDIS_STATUS_CLOSED ((NDIS_STATUS)0x40010007L) +#define NDIS_STATUS_WAN_LINE_UP ((NDIS_STATUS)0x40010008L) +#define NDIS_STATUS_WAN_LINE_DOWN ((NDIS_STATUS)0x40010009L) +#define NDIS_STATUS_WAN_FRAGMENT ((NDIS_STATUS)0x4001000AL) + +#define NDIS_STATUS_NOT_RESETTABLE ((NDIS_STATUS)0x80010001L) +#define NDIS_STATUS_SOFT_ERRORS ((NDIS_STATUS)0x80010003L) +#define NDIS_STATUS_HARD_ERRORS ((NDIS_STATUS)0x80010004L) + +#define NDIS_STATUS_FAILURE ((NDIS_STATUS) STATUS_UNSUCCESSFUL) +#define NDIS_STATUS_RESOURCES ((NDIS_STATUS) \ + STATUS_INSUFFICIENT_RESOURCES) +#define NDIS_STATUS_CLOSING ((NDIS_STATUS)0xC0010002L) +#define NDIS_STATUS_BAD_VERSION ((NDIS_STATUS)0xC0010004L) +#define NDIS_STATUS_BAD_CHARACTERISTICS ((NDIS_STATUS)0xC0010005L) +#define NDIS_STATUS_ADAPTER_NOT_FOUND ((NDIS_STATUS)0xC0010006L) +#define NDIS_STATUS_OPEN_FAILED ((NDIS_STATUS)0xC0010007L) +#define NDIS_STATUS_DEVICE_FAILED ((NDIS_STATUS)0xC0010008L) +#define NDIS_STATUS_MULTICAST_FULL ((NDIS_STATUS)0xC0010009L) +#define NDIS_STATUS_MULTICAST_EXISTS ((NDIS_STATUS)0xC001000AL) +#define NDIS_STATUS_MULTICAST_NOT_FOUND ((NDIS_STATUS)0xC001000BL) +#define NDIS_STATUS_REQUEST_ABORTED ((NDIS_STATUS)0xC001000CL) +#define NDIS_STATUS_RESET_IN_PROGRESS ((NDIS_STATUS)0xC001000DL) +#define NDIS_STATUS_CLOSING_INDICATING ((NDIS_STATUS)0xC001000EL) +#define NDIS_STATUS_NOT_SUPPORTED ((NDIS_STATUS)STATUS_NOT_SUPPORTED) +#define NDIS_STATUS_INVALID_PACKET ((NDIS_STATUS)0xC001000FL) +#define NDIS_STATUS_OPEN_LIST_FULL ((NDIS_STATUS)0xC0010010L) +#define NDIS_STATUS_ADAPTER_NOT_READY ((NDIS_STATUS)0xC0010011L) +#define NDIS_STATUS_ADAPTER_NOT_OPEN ((NDIS_STATUS)0xC0010012L) +#define NDIS_STATUS_NOT_INDICATING ((NDIS_STATUS)0xC0010013L) +#define NDIS_STATUS_INVALID_LENGTH ((NDIS_STATUS)0xC0010014L) +#define NDIS_STATUS_INVALID_DATA ((NDIS_STATUS)0xC0010015L) +#define NDIS_STATUS_BUFFER_TOO_SHORT ((NDIS_STATUS)0xC0010016L) +#define NDIS_STATUS_INVALID_OID ((NDIS_STATUS)0xC0010017L) +#define NDIS_STATUS_ADAPTER_REMOVED ((NDIS_STATUS)0xC0010018L) +#define NDIS_STATUS_UNSUPPORTED_MEDIA ((NDIS_STATUS)0xC0010019L) +#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((NDIS_STATUS)0xC001001AL) +#define NDIS_STATUS_FILE_NOT_FOUND ((NDIS_STATUS)0xC001001BL) +#define NDIS_STATUS_ERROR_READING_FILE ((NDIS_STATUS)0xC001001CL) +#define NDIS_STATUS_ALREADY_MAPPED ((NDIS_STATUS)0xC001001DL) +#define NDIS_STATUS_RESOURCE_CONFLICT ((NDIS_STATUS)0xC001001EL) + +#define NDIS_STATUS_TOKEN_RING_OPEN_ERROR ((NDIS_STATUS)0xC0011000L) + + +// +// used in error logging +// + +#define NDIS_ERROR_CODE ULONG + +#define NDIS_ERROR_CODE_RESOURCE_CONFLICT EVENT_NDIS_RESOURCE_CONFLICT +#define NDIS_ERROR_CODE_OUT_OF_RESOURCES EVENT_NDIS_OUT_OF_RESOURCE +#define NDIS_ERROR_CODE_HARDWARE_FAILURE EVENT_NDIS_HARDWARE_FAILURE +#define NDIS_ERROR_CODE_ADAPTER_NOT_FOUND EVENT_NDIS_ADAPTER_NOT_FOUND +#define NDIS_ERROR_CODE_INTERRUPT_CONNECT EVENT_NDIS_INTERRUPT_CONNECT +#define NDIS_ERROR_CODE_DRIVER_FAILURE EVENT_NDIS_DRIVER_FAILURE +#define NDIS_ERROR_CODE_BAD_VERSION EVENT_NDIS_BAD_VERSION +#define NDIS_ERROR_CODE_TIMEOUT EVENT_NDIS_TIMEOUT +#define NDIS_ERROR_CODE_NETWORK_ADDRESS EVENT_NDIS_NETWORK_ADDRESS +#define NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION EVENT_NDIS_UNSUPPORTED_CONFIGURATION +#define NDIS_ERROR_CODE_INVALID_VALUE_FROM_ADAPTER EVENT_NDIS_INVALID_VALUE_FROM_ADAPTER +#define NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER EVENT_NDIS_MISSING_CONFIGURATION_PARAMETER +#define NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS EVENT_NDIS_BAD_IO_BASE_ADDRESS +#define NDIS_ERROR_CODE_RECEIVE_SPACE_SMALL EVENT_NDIS_RECEIVE_SPACE_SMALL +#define NDIS_ERROR_CODE_ADAPTER_DISABLED EVENT_NDIS_ADAPTER_DISABLED + + + +// +// Ndis Packet Filter Bits +// + +#define NDIS_PACKET_TYPE_DIRECTED 0x0001 +#define NDIS_PACKET_TYPE_MULTICAST 0x0002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x0004 +#define NDIS_PACKET_TYPE_BROADCAST 0x0008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x0010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x0020 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x8000 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x4000 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x2000 +#define NDIS_PACKET_TYPE_GROUP 0x1000 + +// +// Ndis Token-Ring Ring Status Codes +// + +#define NDIS_RING_SIGNAL_LOSS 0x00008000 +#define NDIS_RING_HARD_ERROR 0x00004000 +#define NDIS_RING_SOFT_ERROR 0x00002000 +#define NDIS_RING_TRANSMIT_BEACON 0x00001000 +#define NDIS_RING_LOBE_WIRE_FAULT 0x00000800 +#define NDIS_RING_AUTO_REMOVAL_ERROR 0x00000400 +#define NDIS_RING_REMOVE_RECEIVED 0x00000200 +#define NDIS_RING_COUNTER_OVERFLOW 0x00000100 +#define NDIS_RING_SINGLE_STATION 0x00000080 +#define NDIS_RING_RING_RECOVERY 0x00000040 + diff --git a/private/ntos/ndis/testprot/tpctl/tpctl.c b/private/ntos/ndis/testprot/tpctl/tpctl.c new file mode 100644 index 000000000..83b75b1a5 --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/tpctl.c @@ -0,0 +1,3852 @@ +// -------------------------------------- +// +// 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 +// +// Sanjeev Katariya (sanjeevk) 4-6-1993 +// +// Bug #5203: Changed the routine TpRunTest() at the point where the OPEN returns +// and the InformationBuffer contains information about the address and +// the Medium Type. This was made in order to satisfy the correct setting +// of the OID on multicast addresses(FDDI, 802.3). +// Added support for commands DISABLE, ENABLE, SHELL, RECORDINGENABLE, RECORDINGDISABLE, +// Tpctl Options w,c and ?, fixed multicast address accounting +// +// Tim Wynsma (timothyw) 4-27-94 +// Added performance testing +// 5-18-94 +// Added hooks for globvars; cleanup +// 6-08-94 +// Chgd perf test to client/server model +// +// -------------------------------- + +#include +#include +#include + +#include + +#include +#include +#include + +#include "tpctl.h" +#include "parse.h" + +BOOL ToolActive = TRUE; + +extern BOOL WriteThrough ; +extern BOOL ContinueOnError; + + + +DWORD +TpctlRunTest( + IN HANDLE hFileHandle + ) + +// ----- +// +// Routine Description: +// +// This routine is the main funciton of the TPCTL program. It +// prompts the user for commands, or reads them from the script +// file, and then issues the call to NtDeviceIoControlFile. +// +// Arguments: +// +// IN HANDLE hFileHandle - Supplies the handle to the Test Protocol +// driver where the IOCTLs will be directed. +// +// Return Value: +// +// DWORD - the status of the last call to take place. +// +// ----- + +{ + BYTE Buffer[TPCTL_CMDLINE_SIZE]; + LPSTR localArgv[TPCTL_MAX_ARGC]; + DWORD localArgc; + DWORD CmdCode; + DWORD Status = NO_ERROR; + NTSTATUS NtStatus; + HANDLE Event; + HANDLE Event1; + IO_STATUS_BLOCK IoStatusBlock; + IO_STATUS_BLOCK IoStatusBlock2; + HANDLE InputBuffer; + DWORD InputBufferSize = 8*IOCTL_BUFFER_SIZE; + HANDLE OutputBuffer; + HANDLE OutputBuffer2; + DWORD OutputBufferSize = 8*IOCTL_BUFFER_SIZE; + DWORD OutputBufferSize2; + DWORD WaitTime; + BOOL IoctlCommand = FALSE; + PCMD_ARGS CmdArgs; + DWORD OpenInstance; + + + InputBuffer = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,InputBufferSize ); + + if ( InputBuffer == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tGlobalAlloc failed to alloc InputBuffer: returned 0x%lx.\n", + (PVOID)Status); + return Status; + } + + CmdArgs = (PCMD_ARGS)InputBuffer; + + OutputBuffer = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,OutputBufferSize ); + + if ( OutputBuffer == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tGlobalAlloc failed to alloc OutputBuffer: returned 0x%lx.\n", + (PVOID)Status); + GlobalFree( InputBuffer ); + return Status; + } + + Event = CreateEvent( NULL,FALSE,FALSE,NULL ); + + if (Event == NULL) + { + Status = GetLastError(); + TpctlErrorLog("\n\tCreateEvent failed: returned 0x%lx.\n",(PVOID)Status); + GlobalFree( InputBuffer ); + GlobalFree( OutputBuffer ); + return Status; + } + + while ( ExitFlag == FALSE ) + { + if ( ContinueLooping == FALSE ) + { + // + // A Ctrl-c has been entered, If we are reading commands + // from a script file then reset all the open blocks, and + // close the script files. + // + + TpctlResetAllOpenStates( hFileHandle ); + TpctlCloseScripts(); + + ContinueLooping = TRUE; + } + + Status = TpctlReadCommand( TPCTL_PROMPT,Buffer,TPCTL_CMDLINE_SIZE ); + + if ( Status != NO_ERROR ) + { + printf("STATUS == Some error\n"); + + // + // there was an error in the last command entered. If we + // are reading commands from a script file then reset all + // the open blocks, and close the script files. + // + if ( !ContinueOnError ) + { + TpctlResetAllOpenStates( hFileHandle ); + TpctlCloseScripts(); + } + continue; + } + else if (( !TpctlParseCommand( Buffer, + localArgv, + &localArgc, + TPCTL_MAX_ARGC )) && + ( CommandsFromScript == TRUE )) + { + printf("which means parse command failed.\n"); + + if ( !ContinueOnError ) + { + TpctlResetAllOpenStates( hFileHandle ); + TpctlCloseScripts(); + } + continue; + } + + if (( localArgc <= 0 ) || ( localArgv[0][0] == ';' )) + { + continue; + } + + CmdCode = TpctlGetCommandCode( localArgv[0] ); + + switch( CmdCode ) + { + case VERBOSE: + if ( ToolActive ) + { + Verbose = ( Verbose ) ? FALSE : TRUE; + TpctlLog("\n\tTpctl: Verbose Mode enabled.\n",NULL); + + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + 1, + localArgv ); + + } + + } + CmdCode = CMD_COMPLETED; + break; + + case SETENV: + if ( ToolActive ) + { + if ( TpctlParseArguments( SetEnvOptions, + Num_SetEnv_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( SetEnvOptions, + Num_SetEnv_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + TpctlSaveNewEnvironmentVariables( CmdArgs->OpenInstance - 1 ); + + } + CmdCode = CMD_COMPLETED; + break; + + case READSCRIPT: + if ( ToolActive ) + { + if ( TpctlParseArguments( ReadScriptOptions, + Num_ReadScript_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( ReadScriptOptions, + Num_ReadScript_Params, + localArgc, + localArgv ); + } + + Status = TpctlLoadFiles(GlobalCmdArgs.ARGS.FILES.ScriptFile, + GlobalCmdArgs.ARGS.FILES.LogFile ); + + if ( Status != NO_ERROR ) + { + if ( !ContinueOnError ) + { + TpctlResetAllOpenStates( hFileHandle ); + TpctlCloseScripts(); + } + } + } + CmdCode = CMD_COMPLETED; + break; + + case BEGINLOGGING: + if( ToolActive ) + { + if ( CommandsFromScript == TRUE ) + { + TpctlErrorLog("\n\tTpctl: Already logging results to \"%s\".\n", + (PVOID)Scripts[ScriptIndex].LogFile); + } + else if ( CommandLineLogging == TRUE ) + { + TpctlErrorLog("\n\tTpctl: Command Line Logging is already enabled.\n",NULL); + } + else + { + if ( TpctlParseArguments( LoggingOptions, + Num_Logging_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( LoggingOptions, + Num_Logging_Params, + localArgc, + localArgv ); + } + + CommandLineLogHandle = TpctlOpenLogFile(); + + if ( CommandLineLogHandle == (HANDLE)-1 ) + { + TpctlErrorLog("\n\tTpctl: failed to open Log File.\n",NULL); + } + else + { + CommandLineLogging = TRUE; + } + } + } + CmdCode = CMD_COMPLETED; + break; + + case ENDLOGGING: + if ( ToolActive ) + { + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + 1, + localArgv ); + } + + if ( CommandLineLogging == TRUE ) + { + TpctlCloseLogFile(); + CommandLineLogging = FALSE; + } + else + { + TpctlErrorLog("\n\tTpctl: Logging is not enabled.\n\n",NULL); + } + } + CmdCode = CMD_COMPLETED; + break; + + case RECORDINGENABLE: + if( ToolActive ) + { + if ( RecordToScript == TRUE ) + { + TpctlErrorLog("\n\tTpctl: Already recording commands to \"%s\".\n", + (PVOID)RecordScriptName ); + } + else + { + if ( TpctlParseArguments( RecordingOptions, + Num_Recording_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + ScriptRecordHandle = TpctlOpenScriptFile(); + + if ( ScriptRecordHandle == (HANDLE)-1 ) + { + TpctlErrorLog("\n\tTpctl: failed to open script record File.\n",NULL); + } + else + { + RecordToScript = TRUE; + } + } + } + CmdCode = CMD_COMPLETED; + break; + + case RECORDINGDISABLE: + if ( ToolActive ) + { + if ( RecordToScript == TRUE ) + { + TpctlCloseScriptFile(); + RecordToScript = FALSE; + } + else + { + TpctlErrorLog("\n\tTpctl: Script Recording is not enabled.\n\n",NULL); + } + } + CmdCode = CMD_COMPLETED; + break; + + + case WAIT: + if ( ToolActive ) + { + if ( localArgv[1] != NULL ) + { + WaitTime = atol( localArgv[1] ); + } + else + { + WaitTime = 0; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + min(2,localArgc), + localArgv ); + } + + TpctlLog("\n\tTpctl: Waiting for %d seconds.\n",(PVOID)WaitTime); + + // + // Multiply by 1000 to convert seconds to msecs for us by + // Sleep(). + // + + Sleep( WaitTime * 1000 ); + } + CmdCode = CMD_COMPLETED; + break; + + case GO: + case PAUSE: + if ( ToolActive ) + { + if ( TpctlParseArguments( PauseGoOptions, + Num_PauseGo_Params - 1, // Ignore Unique Signature + // while parsing arguments. + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( PauseGoOptions, + Num_PauseGo_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + TpctlPauseGo( hFileHandle,CmdArgs,InputBufferSize,CmdCode ); + } + CmdCode = CMD_COMPLETED; + break; + + case LOAD: + case UNLOAD: + if ( ToolActive ) + { + if ( TpctlParseArguments( LoadUnloadOptions, + Num_LoadUnload_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( LoadUnloadOptions, + Num_LoadUnload_Params, + localArgc, + localArgv ); + } + TpctlLoadUnload( CmdCode ); + } + CmdCode = CMD_COMPLETED; + break; + + case OPEN: // NdisOpenAdapter + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenOptions, + Num_Open_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenOptions, + Num_Open_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == TRUE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter is already opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case CLOSE: // NdisCloseAdapter + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_COMPLETED; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case SETPF: + if ( ToolActive ) + { + if ( TpctlParseArguments( SetPacketFilterOptions, + Num_SetPacketFilter_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( SetPacketFilterOptions, + Num_SetPacketFilter_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case SETLA: + if ( ToolActive ) + { + if ( TpctlParseArguments( SetLookaheadOptions, + Num_SetLookahead_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( SetLookaheadOptions, + Num_SetLookahead_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case ADDMA: + case DELMA: + if ( ToolActive ) + { + if ( TpctlParseArguments( MulticastAddrOptions, + Num_MulticastAddr_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( MulticastAddrOptions, + Num_MulticastAddr_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case SETFA: + if ( ToolActive ) + { + if ( TpctlParseArguments( FunctionalAddrOptions, + Num_FunctionalAddr_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( FunctionalAddrOptions, + Num_FunctionalAddr_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case SETGA: + if ( ToolActive ) + { + if ( TpctlParseArguments( GroupAddrOptions, + Num_GroupAddr_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( GroupAddrOptions, + Num_GroupAddr_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case SETINFO: // NdisSetInformation + if ( ToolActive ) + { + DWORD tmpArgc = 1; + LPSTR tmpArgv[2]; + + if ( localArgc > 1 ) + { + TpctlParseSetInfoArguments( &localArgc, + localArgv, + &tmpArgc, + tmpArgv ); + } + + if ( TpctlParseArguments( SetInfoOptions, + Num_SetInfo_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( SetInfoOptions, + Num_SetInfo_Params, + localArgc, + localArgv ); + } + + // + // If the information class argument is one of Station Address, + // Functional Address, or Lookahead Size, then we need to + // continue parsing the arguments because we have not found + // the class specific argument needed in these three cases. + // + + switch ( GlobalCmdArgs.ARGS.TPSET.OID ) + { + case OID_GEN_CURRENT_PACKET_FILTER: + if ( TpctlParseArguments( SetInfoPFOptions, + Num_SetInfoPF_Params, + tmpArgc, + tmpArgv ) == -1 ) + { + CmdCode = CMD_ERR; + } + if ( RecordToScript ) + { + TpctlRecordArguments( SetInfoPFOptions, + Num_SetInfoPF_Params, + tmpArgc, + tmpArgv ); + } + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + if ( TpctlParseArguments( SetInfoLAOptions, + Num_SetInfoLA_Params, + tmpArgc, + tmpArgv ) == -1 ) + { + CmdCode = CMD_ERR; + } + if ( RecordToScript ) + { + TpctlRecordArguments( SetInfoLAOptions, + Num_SetInfoLA_Params, + tmpArgc, + tmpArgv ); + } + break; + + case OID_802_3_MULTICAST_LIST: + if ( TpctlParseArguments( SetInfoMAOptions, + Num_SetInfoMA_Params, + tmpArgc, + tmpArgv ) == -1 ) + { + CmdCode = CMD_ERR; + } + if ( RecordToScript ) + { + TpctlRecordArguments( SetInfoMAOptions, + Num_SetInfoMA_Params, + tmpArgc, + tmpArgv ); + } + break; + + case OID_FDDI_LONG_MULTICAST_LIST : + if ( TpctlParseArguments( SetInfoMAOptions, + Num_SetInfoMA_Params, + tmpArgc, + tmpArgv ) == -1 ) + { + CmdCode = CMD_ERR; + } + if ( RecordToScript ) + { + TpctlRecordArguments( SetInfoMAOptions, + Num_SetInfoMA_Params, + tmpArgc, + tmpArgv ); + } + break; + + case OID_FDDI_SHORT_CURRENT_ADDR : + + // + // Not implemented yet + // + + break; + + case OID_FDDI_LONG_CURRENT_ADDR : + + // + // Not implemented yet + // + + break; + + case OID_FDDI_SHORT_MULTICAST_LIST : + + // + // Not implemented yet + // + + break; + + case OID_802_5_CURRENT_FUNCTIONAL: + if ( TpctlParseArguments( SetInfoFAOptions, + Num_SetInfoFA_Params, + tmpArgc, + tmpArgv ) == -1 ) + { + CmdCode = CMD_ERR; + } + if ( RecordToScript ) + { + TpctlRecordArguments( SetInfoFAOptions, + Num_SetInfoFA_Params, + tmpArgc, + tmpArgv ); + } + break; + + case OID_802_5_CURRENT_GROUP: + if ( TpctlParseArguments( SetInfoGAOptions, + Num_SetInfoGA_Params, + tmpArgc, + tmpArgv ) == -1 ) + { + CmdCode = CMD_ERR; + } + if ( RecordToScript ) + { + TpctlRecordArguments( SetInfoGAOptions, + Num_SetInfoGA_Params, + tmpArgc, + tmpArgv ); + } + break; + + } // end switch + + if ( CmdCode == CMD_ERR ) + { + break; + } + + if ( !TpctlInitCommandBuffer(CmdArgs,SETINFO)) + { + CmdCode = CMD_COMPLETED; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + break; + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case QUERYINFO: + if ( ToolActive ) + { + if ( TpctlParseArguments( QueryInfoOptions, + Num_QueryInfo_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( QueryInfoOptions, + Num_QueryInfo_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_COMPLETED; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case QUERYSTATS: + if ( ToolActive ) + { + if ( TpctlParseArguments( QueryStatsOptions, + Num_QueryStats_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( QueryStatsOptions, + Num_QueryStats_Params, + localArgc, + localArgv ); + } + + TpctlQueryStatistics( GlobalCmdArgs.ARGS.TPQUERYSTATS.DeviceName, + GlobalCmdArgs.ARGS.TPQUERYSTATS.OID, + NULL, //StatsBuffer, + 0); //BufLen + + } + CmdCode = CMD_COMPLETED; + break; + + case RESET: // NdisReset + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case SEND: // NdisSend + if ( ToolActive ) + { + if ( TpctlParseArguments( SendOptions, + Num_Send_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( SendOptions, + Num_Send_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Is this Open Instance already sending packets? + // + + if ( Open[OpenInstance].Sending == TRUE ) + { + // + // If so, print an error message and prompt for next command. + // + + TpctlErrorLog( + "\n\tTpctl: Packets are currently being sent on Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + else if ( Open[OpenInstance].SendResultsCompleted == TRUE ) + { + // + // A previous SEND test has left some results in the SEND + // RESULTS buffer, and they have not been printed. + // + + TpctlLog("\n\tTpctl: Results exist for a prior SEND test.\n",NULL); + + TpctlPrintSendResults( Open[OpenInstance].SendResults ); + Open[OpenInstance].SendResultsCompleted = FALSE; + } + + // + // Set up the IoStatusBlock to point to this Open Instance's + // Send IoStatusBlock, and the OutputBuffer to point to its + // SendResults structure. + // + + IoStatusBlock2 = Open[OpenInstance].SendStatusBlock; + OutputBuffer2 = Open[OpenInstance].SendResults; + OutputBufferSize2 = sizeof( SEND_RECEIVE_RESULTS ); + + // + // Set up the Send Event to wait on. + // + + Event1 = Open[OpenInstance].Events[TPSEND]; + + if ( !ResetEvent( Open[OpenInstance].SendEvent )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed to reset Send Event 0x%lx.\n", + (PVOID)Status); + CmdCode = CMD_ERR; + break; + } + + // + // Finally set the Sending flag for this Open Instance, + // + + Open[OpenInstance].Sending = TRUE; + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case STOPSEND: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + // + // Is this Open Instance currently sending packets? + // + + if ( Open[OpenInstance].Sending == FALSE ) + { + // + // If not are the any results to report? + // + + if ( Open[OpenInstance].SendResultsCompleted == FALSE ) + { + // + // If not, print an error message and prompt for next + // command. + // + + TpctlErrorLog( + "\n\tTpctl: A SEND test is not currently running for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_COMPLETED; + break; + } + else // SendResultsCompleted == TRUE + { + // + // If there are results from a previous send, then print + // them, reset the flags, and prompt for the command. + // + + TpctlPrintSendResults(Open[OpenInstance].SendResults); + + Open[OpenInstance].SendResultsCompleted = FALSE; + Open[OpenInstance].Sending = FALSE; + + CmdCode = CMD_COMPLETED; + break; + } + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case WAITSEND: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + if ( Open[OpenInstance].SendResultsCompleted == TRUE ) + { + TpctlPrintSendResults( Open[OpenInstance].SendResults ); + + Open[OpenInstance].SendResultsCompleted = FALSE; + Open[OpenInstance].Sending = FALSE; + } + else if ( Open[OpenInstance].Sending == TRUE ) + { + ContinueLooping = TRUE; + do + { + Status = WaitForSingleObject( Open[OpenInstance].SendEvent, + 1000); // One_Second + if (( Status != NO_ERROR ) && + ( Status != WAIT_TIMEOUT )) + { + TpctlErrorLog("\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + } + } while (( Status != NO_ERROR ) && ( ContinueLooping == TRUE )); + + if ( ContinueLooping == FALSE ) + { + TpctlLog("\n\tTpctl: Cancelling WaitSend command.\n",NULL); + } + else + { + TpctlPrintSendResults( Open[OpenInstance].SendResults ); + + Open[OpenInstance].SendResultsCompleted = FALSE; + Open[OpenInstance].Sending = FALSE; + } + } + else + { + TpctlErrorLog("\n\tTpctl: No Send results exist, and no Send test is\n", + NULL); + TpctlErrorLog("\t currently running for Open Instance %lu.\n", + (PVOID)CmdArgs->OpenInstance); + } + } + CmdCode = CMD_COMPLETED; + break; + + case RECEIVE: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Is this Open Instance already receiveing packets? + // + + if ( Open[OpenInstance].Receiving == TRUE ) + { + // + // If so, print an error message and prompt for next command. + // + + TpctlErrorLog( + "\n\tTpctl: Packets are currently being received on Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + + } + else if ( Open[OpenInstance].ReceiveResultsCompleted == TRUE ) + { + // + // A previous RECEIVE test has left some results in the RECEIVE + // RESULTS buffer, and they have not been printed. + // + + TpctlLog("\n\tTpctl: Results exist for a prior RECEIVE test.\n",NULL); + TpctlPrintReceiveResults(Open[OpenInstance].ReceiveResults); + Open[OpenInstance].ReceiveResultsCompleted = FALSE; + } + + // + // Set up the IoStatusBlock to point to this Open Instance's + // Send IoStatusBlock, and the OutputBuffer to point to its + // ReceiveResults structure. + // + + IoStatusBlock2 = Open[OpenInstance].ReceiveStatusBlock; + OutputBuffer2 = Open[OpenInstance].ReceiveResults; + OutputBufferSize2 = sizeof( SEND_RECEIVE_RESULTS ); + + // + // Set up the Receive Event to wait on. + // + + Event1 = Open[OpenInstance].Events[TPRECEIVE]; + + if (!ResetEvent(Open[OpenInstance].ReceiveEvent)) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed to reset Receive Event 0x%lx.\n", + (PVOID)Status); + CmdCode = CMD_ERR; + break; + } + + // + // Finally set the Receiving flag for this Open Instance, + // + + Open[OpenInstance].Receiving = TRUE; + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case STOPREC: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + // + // Is this Open Instance receiving packets? + // + + if ( Open[OpenInstance].Receiving == FALSE ) + { + // + // If not are the any results to report? + // + + if ( Open[OpenInstance].ReceiveResultsCompleted == FALSE ) + { + // + // If not, print an error message and prompt for next + // command. + // + + TpctlErrorLog( + "\n\tTpctl: A RECEIVE test is not currently running for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + + } + else // ReceiveResultsCompleted == TRUE + { + TpctlPrintReceiveResults( Open[OpenInstance].ReceiveResults ); + + Open[OpenInstance].ReceiveResultsCompleted = FALSE; + Open[OpenInstance].Receiving = FALSE; + + CmdCode = CMD_COMPLETED; + break; + } + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case GETEVENTS: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + TpctlGetEvents( hFileHandle,CmdArgs,InputBufferSize ); + } + CmdCode = CMD_COMPLETED; + break; + + case STRESS: + if ( ToolActive ) + { + if ( TpctlParseArguments( StressOptions, + Num_Stress_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( StressOptions, + Num_Stress_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Is this Open Instance already running a stress test? + // + + if ( Open[OpenInstance].Stressing == TRUE ) + { + // + // If so, print an error message and prompt for next command. + // + + TpctlErrorLog( + "\n\tTpctl: A Stress test is currently running for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + else if ( Open[OpenInstance].StressResultsCompleted == TRUE ) + { + // + // A previous STRESS test has left some results in the STRESS + // RESULTS buffer, and they have not been printed. + // + + TpctlLog("\n\tTpctl: Results exist for a prior STRESS test.\n",NULL); + + TpctlPrintStressResults(Open[OpenInstance].StressResults, + Open[OpenInstance].Ack10 ); + + Open[OpenInstance].StressResultsCompleted = FALSE; + } + + // + // Set up the IoStatusBlock to point to this Open Instance's + // Stress IoStatusBlock, and the OutputBuffer to point to its + // StressResults structure. + // + + IoStatusBlock2 = Open[OpenInstance].StressStatusBlock; + OutputBuffer2 = Open[OpenInstance].StressResults; + OutputBufferSize2 = sizeof( STRESS_RESULTS ); + + // + // Set up the Stress Event to wait on. + // + + Event1 = Open[OpenInstance].Events[TPSTRESS]; + + if (!ResetEvent(Open[OpenInstance].StressEvent)) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed to reset Stress Event 0x%lx.\n", + (PVOID)Status); + CmdCode = CMD_ERR; + break; + } + + // + // if we are running a stress test with a response type of + // ack 10 times for every packet, set the flag for displaying. + // + + if ( CmdArgs->ARGS.TPSTRESS.ResponseType == ACK_10_TIMES ) + { + Open[OpenInstance].Ack10 = TRUE; + } + else + { + Open[OpenInstance].Ack10 = FALSE; + } + + // + // Finally set the Stressing flag for this Open Instance, + // + + Open[OpenInstance].Stressing = TRUE; + + // + // the flag indicating that a Client is running on this Open + // Instance, + // + + Open[OpenInstance].StressClient = TRUE; + + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case STRESSSERVER: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Is this Open Instance already running a stress test? + // + + if ( Open[OpenInstance].Stressing == TRUE ) + { + // + // If so, print an error message and prompt for next command. + // + + TpctlErrorLog( + "\n\tTpctl: A Stress test is currently running for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Set up the IoStatusBlock to point to this Open Instance's + // IoStatusBlock, and the OutputBuffer to point to its + // StressResults structure. + // + + IoStatusBlock2 = Open[OpenInstance].StressStatusBlock; + OutputBuffer2 = Open[OpenInstance].StressResults; + OutputBufferSize2 = sizeof( STRESS_RESULTS ); + + // + // Set up the Stress Event to wait on. + // + + Event1 = Open[OpenInstance].Events[TPSTRESS]; + + if (!ResetEvent(Open[OpenInstance].StressEvent)) + { + Status = GetLastError(); + TpctlErrorLog( + "\n\tTpctl: failed to reset Stress Event 0x%lx.\n",(PVOID)Status); + CmdCode = CMD_ERR; + break; + } + + // + // Finally set the Stressing flag for this Open Instance, + // + + Open[OpenInstance].Stressing = TRUE; + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case ENDSTRESS: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + // + // Is this Open Instance running a stress test? + // + + if ( Open[OpenInstance].Stressing == FALSE ) + { + // + // If not, print an error message and prompt for next command. + // + + TpctlErrorLog( + "\n\tTpctl: A Stress test is not currently running for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_COMPLETED; + } + + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case WAITSTRESS: + case CHECKSTRESS: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + if ( Open[OpenInstance].StressResultsCompleted == TRUE ) + { + TpctlPrintStressResults(Open[OpenInstance].StressResults, + Open[OpenInstance].Ack10 ); + + Open[OpenInstance].StressResultsCompleted = FALSE; + Open[OpenInstance].Stressing = FALSE; + + } + else if ( Open[OpenInstance].Stressing == TRUE ) + { + if ( Open[OpenInstance].StressClient != TRUE ) + { + TpctlErrorLog("\n\tTpctl: %s command valid only for Stress Clients.\n", + TpctlGetCommandName( localArgv[0] )); + CmdCode = CMD_ERR; + break; + } + + if ( CmdCode == WAITSTRESS ) + { + ContinueLooping = TRUE; + + do + { + Status = WaitForSingleObject( Open[OpenInstance].StressEvent, + 1000); // One_Second + if (( Status != NO_ERROR ) && + ( Status != WAIT_TIMEOUT )) + { + TpctlErrorLog( + "\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + } + + } while (( Status != NO_ERROR ) && + ( ContinueLooping == TRUE )); + + if ( ContinueLooping == FALSE ) + { + TpctlLog("\n\tTpctl: Cancelling WaitStress command.\n",NULL); + } + else + { + TpctlPrintStressResults(Open[OpenInstance].StressResults, + Open[OpenInstance].Ack10 ); + + Open[OpenInstance].StressResultsCompleted = FALSE; + Open[OpenInstance].Stressing = FALSE; + } + } + else + { + TpctlLog("\n\tTpctl: The Stress test is still running.\n",NULL); + } + } + else + { + TpctlErrorLog("\n\tTpctl: No Stress results exist, and no Stress test is\n", + NULL); + TpctlErrorLog("\t currently running for Open Instance %lu.\n", + (PVOID)CmdArgs->OpenInstance); + } + } + CmdCode = CMD_COMPLETED; + break; + + case BREAKPOINT: + if ( !ToolActive ) + { + CmdCode = CMD_COMPLETED; + } + else + { + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + 1, + localArgv ); + } + } + break; + + case QUIT: + if ( ToolActive ) + { + DWORD i; + + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + 1, + localArgv ); + } + + // + // If there are any outstanding ASYNC IRPs print a message + // to the user to wait patiently. + // + + for (i=0;i 1 ) + { + strcat( ShellCommand, " /C " ); + for( TmpCount = 1; TmpCount < (INT)localArgc; TmpCount++ ) + { + strcat( ShellCommand, localArgv[TmpCount] ); + strcat( ShellCommand, " " ); + } + } + system( ShellCommand ); + } + + // + // Reset the console foregrounds and background colors to the old settings + // + if( NoErrorsAccessingConsole ) + { + SetConsoleTextAttribute( OutputHandle, ScreenBuffer.wAttributes ); + FillConsoleOutputAttribute( OutputHandle, ScreenBuffer.wAttributes, + 0xFFFFFFFF, Start, + &CharactersWritten ); + } + } + printf("\n"); + } + CmdCode = CMD_COMPLETED; + break; + + case DISABLE: + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + localArgc, + localArgv ); + } + + if ( Disable( localArgc, localArgv ) ) + { + printf( "\n\tDisabling TPCTL...\n\n" ); + } + CmdCode = CMD_COMPLETED; + break; + + case ENABLE: + ToolActive = TRUE; + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + localArgc, + localArgv ); + } + printf( "\n\tEnabling TPCTL...\n\n" ); + CmdCode = CMD_COMPLETED; + break; + + case REGISTRY: + if ( ToolActive ) + { + if ( TpctlParseArguments( RegistryOptions, + Num_Registry_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( RegistryOptions, + Num_Registry_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + TpctlPerformRegistryOperation( CmdArgs ); + } + CmdCode = CMD_COMPLETED; + break; + + + case PERFSERVER: + if ( ToolActive ) + { + if ( TpctlParseArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( OpenInstanceOptions, + Num_OpenInstance_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Is this Open Instance already sending or receiving packets? + // + + if ( (Open[OpenInstance].Sending == TRUE ) || + (Open[OpenInstance].Receiving == TRUE ) || + (Open[OpenInstance].ReceiveResultsCompleted == TRUE ) || + (Open[OpenInstance].SendResultsCompleted == TRUE ) ) + { + // + // If so, print an error message and prompt for next command. + // + + TpctlErrorLog( + "\n\tTpctl: Packets are currently being sent or received on Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Set up the IoStatusBlock to point to this Open Instance's + // Send IoStatusBlock, and the OutputBuffer to point to its + // SendResults structure. + // + + IoStatusBlock2 = Open[OpenInstance].PerfStatusBlock; + OutputBuffer2 = Open[OpenInstance].PerfResults; + OutputBufferSize2 = sizeof( PERF_RESULTS ); + + // + // Set up the Send Event to wait on. + // + + Event1 = Open[OpenInstance].Events[TPPERF]; + + if ( !ResetEvent( Open[OpenInstance].PerfEvent )) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed to reset Perf Event 0x%lx.\n", + (PVOID)Status); + CmdCode = CMD_ERR; + break; + } + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + case PERFCLIENT: + if ( ToolActive ) + { + if ( TpctlParseArguments( PerfClntOptions, + Num_PerfClnt_Params, + localArgc, + localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( PerfClntOptions, + Num_PerfClnt_Params, + localArgc, + localArgv ); + } + + if ( !TpctlInitCommandBuffer( CmdArgs,CmdCode )) + { + CmdCode = CMD_ERR; + break; + } + + OpenInstance = CmdArgs->OpenInstance - 1; + + if ( Open[OpenInstance].AdapterOpened == FALSE ) + { + TpctlErrorLog( + "\n\tTpctl: The adapter has not been opened for Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // + // Is this Open Instance already sending or receiving packets? + // + + if ( (Open[OpenInstance].Sending == TRUE ) || + (Open[OpenInstance].Receiving == TRUE ) || + (Open[OpenInstance].ReceiveResultsCompleted == TRUE ) || + (Open[OpenInstance].SendResultsCompleted == TRUE ) ) + { + // + // If so, print an error message and prompt for next command. + // + + TpctlErrorLog( + "\n\tTpctl: Packets are currently being sent or received on Open Instance %lu.\n", + (PVOID)(CmdArgs->OpenInstance)); + CmdCode = CMD_ERR; + break; + } + + // + // Set up the IoStatusBlock to point to this Open Instance's + // Send IoStatusBlock, and the OutputBuffer to point to its + // ReceiveResults structure. + // + + IoStatusBlock2 = Open[OpenInstance].PerfStatusBlock; + OutputBuffer2 = Open[OpenInstance].PerfResults; + OutputBufferSize2 = sizeof( PERF_RESULTS ); + + // + // Set up the Receive Event to wait on. + // + + Event1 = Open[OpenInstance].Events[TPPERF]; + + if (!ResetEvent(Open[OpenInstance].PerfEvent)) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: failed to reset Perf Event 0x%lx.\n", + (PVOID)Status); + CmdCode = CMD_ERR; + break; + } + CpuUsageInit(); + } + else + { + CmdCode = CMD_COMPLETED; + } + break; + + + case SETGLOBAL: + if (ToolActive) + { + if ( TpctlParseSet( localArgc, localArgv ) == -1 ) + { + CmdCode = CMD_ERR; + break; + } + + if ( RecordToScript ) + { + TpctlRecordArguments( NULL, + 0, + min(2,localArgc), + localArgv ); + } + + } + CmdCode = CMD_COMPLETED; + break; + + default: + CmdCode = CMD_COMPLETED; + if( ToolActive ) + { + TpctlErrorLog("\n\tTpctl: Invalid Command Entered.\n",NULL); + CmdCode = CMD_ERR; + } + break; + + } // switch(); + + // + // If we have a command to issue to the driver and the tool + // is active, do it now. + // + + if ( ( CmdCode == STRESS ) || ( CmdCode == STRESSSERVER ) || + ( CmdCode == SEND ) || ( CmdCode == RECEIVE ) || + ( CmdCode == PERFSERVER ) || ( CmdCode == PERFCLIENT ) ) + { + +//!!NOT WIN32!! + + NtStatus = NtDeviceIoControlFile( hFileHandle, + Event1, + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock2, + TP_CONTROL_CODE( CmdCode,IOCTL_METHOD ), + (PVOID)InputBuffer, + InputBufferSize, + (PVOID)OutputBuffer2, + OutputBufferSize2 ); + + if (( NtStatus == STATUS_SUCCESS ) || + ( NtStatus == STATUS_PENDING )) + { + TpctlLog("\n\tTpctl: The %s command has been issued.\n", + TpctlGetCommandName( localArgv[0] )); + } + + } + else if (( CmdCode != CMD_ERR ) && ( CmdCode != CMD_COMPLETED )) + { +// !!NOT WIN32!! + + NtStatus = NtDeviceIoControlFile( hFileHandle, + Event, + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, + TP_CONTROL_CODE( CmdCode,IOCTL_METHOD ), + (PVOID)InputBuffer, + InputBufferSize, + (PVOID)OutputBuffer, + OutputBufferSize ); + + if (( NtStatus != STATUS_SUCCESS ) && + ( NtStatus != STATUS_PENDING )) + { + // + // If the IOCTL call failed then close any script files + // and break out of while loop by setting the ExitFlag + // to true. + // + + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + ExitFlag = TRUE; + Status = NtStatus; + break; + } + else + { + TpctlLog("\n\tTpctl: The %s command has been issued.\n", + TpctlGetCommandName( localArgv[0] )); + + if ( NtStatus == STATUS_PENDING ) + { + // + // 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 a + // request, because the IRP was never completed + // by the test protocol driver. + // + + TpctlErrorLog( + "\n\tTpctl: WARNING - WaitForSingleObject unexpectedly timed out.\n", + NULL); + TpctlErrorLog( + "\t IRP was never completed in protocol driver.\n", + NULL); + CmdCode = CMD_ERR; + } + 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; + CmdCode = CMD_ERR; + } + 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; + } + } + } + } + + switch ( CmdCode ) + { + case CMD_ERR: + // + // NOTE: if commands are being read from a script file setting + // the CmdCode to CMD_ERR causes this routine to unload ALL + // script files, and wait at the prompt for the next command + // to process, use CMD_ERR wisely. + // + + if( !ContinueOnError ) + { + TpctlResetAllOpenStates( hFileHandle ); + TpctlCloseScripts(); + } + break; + + case SETENV: + break; + + case OPEN: + if (((PREQUEST_RESULTS)OutputBuffer)->RequestStatus == NDIS_STATUS_SUCCESS ) + { + // + // The open request succeeded so mark this open instance + // as opened. + // + + Open[OpenInstance].AdapterOpened = TRUE; + + // + // if the open "initialization" requests all succeeded + // copy the adapter address into the open, and set the + // open instance. + // + + if (((PREQUEST_RESULTS)OutputBuffer)->OpenRequestStatus == + NDIS_STATUS_SUCCESS ) + { + // + // STARTCHANGE + // + // Sanjeevk: Bug #5203 + // + PNDIS_MEDIUM MediumType = + (PNDIS_MEDIUM)((PREQUEST_RESULTS)OutputBuffer)->InformationBuffer; + + // + // Copy the Media Type + // + Open[OpenInstance].MediumType = *MediumType; + + // + // STOPCHANGE + // + + // + // Copy the address of the adapter + // + TpctlCopyAdapterAddress(OpenInstance, + (PREQUEST_RESULTS)OutputBuffer ); + + Open[OpenInstance].OpenInstance = (UCHAR)OpenInstance; + } + } + + // + // Now print the Open request results regardless of success or + // failure. + // + + TpctlPrintResults( (PREQUEST_RESULTS)OutputBuffer,CmdCode,0 ); + break; + + case CLOSE: + if (((PREQUEST_RESULTS)OutputBuffer)->RequestStatus == + NDIS_STATUS_SUCCESS ) + { + // + // The close request succeeded, set the flag stating so, + // and reset the open structure to its initial state. + // + + Open[OpenInstance].AdapterOpened = FALSE; + Open[OpenInstance].OpenInstance = (UCHAR)-1; + + TpctlResetOpenState( &Open[OpenInstance],hFileHandle ); + } + + // + // Now print the results regardless of success or failure. + // + + TpctlPrintResults( (PREQUEST_RESULTS)OutputBuffer,CmdCode,0 ); + break; + + case SETPF: + case SETLA: + case ADDMA: + case SETFA: + case SETGA: + case SETINFO: + { + PMULT_ADDR MultAddr = NULL; + BOOL AddressFound = FALSE; + DWORD i; + + if (((PREQUEST_RESULTS)OutputBuffer)->RequestStatus == + NDIS_STATUS_SUCCESS ) + { + // + // If the command succeeded, then update the local + // state to reflect the changed info. + // + + switch ( CmdArgs->ARGS.TPSET.OID ) + { + case OID_GEN_CURRENT_PACKET_FILTER: + Open[OpenInstance].PacketFilter = + CmdArgs->ARGS.TPSET.U.PacketFilter; + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + Open[OpenInstance].LookaheadSize = + CmdArgs->ARGS.TPSET.U.LookaheadSize; + break; + + case OID_FDDI_LONG_MULTICAST_LIST : + case OID_802_3_MULTICAST_LIST : + // + // We successfully added the multicast address to the + // card, if it is not in our local list already, then + // put it on the local multicast address list + // for accounting purposes. + // + // XXX: The stress tests be required to add and delete + // the stress multicast address to/from this list? + // + + MultAddr = Open[OpenInstance].MulticastAddresses; + + if ( MultAddr != NULL ) + { + // + // if the list is not empty see if this addr is + // in it yet. + // + + while ( MultAddr != NULL ) + { + if ( memcmp(CmdArgs->ARGS.TPSET.U.MulticastAddress[0], + MultAddr->MulticastAddress, + ADDRESS_LENGTH ) == 0 ) + { + // + // We found the address in the list already, + // so skip adding it in again. + // + + AddressFound = TRUE; + break; + } + + // + // Otherwise, get the next list entry. + // + + MultAddr = MultAddr->Next; + } + } + + if ( AddressFound == FALSE ) + { + MultAddr = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, + sizeof( MULT_ADDR ) ); + + if ( MultAddr == NULL ) + { + Status = GetLastError(); + TpctlErrorLog( + "\n\tGlobalAlloc failed to alloc a MultAddr stuct: returned 0x%lx.\n", + (PVOID)Status); + break; + } + + for ( i=0;iMulticastAddress[i] = + CmdArgs->ARGS.TPSET.U.MulticastAddress[0][i]; + } + + MultAddr->Next = Open[OpenInstance].MulticastAddresses; + Open[OpenInstance].MulticastAddresses = MultAddr; + + Open[OpenInstance].NumberMultAddrs++; + } + break; + + case OID_802_5_CURRENT_FUNCTIONAL: + for (i=0;iARGS.TPSET.U.FunctionalAddress[i]; + } + break; + + case OID_802_5_CURRENT_GROUP: + for (i=0;iARGS.TPSET.U.GroupAddress[i]; + } + break; + } + } + + TpctlPrintSetInfoResults( (PREQUEST_RESULTS)OutputBuffer, + CmdCode, + CmdArgs->ARGS.TPSET.OID ); + break; + } + + case DELMA: + { + PMULT_ADDR MultAddr = NULL; + PMULT_ADDR BaseMultAddr = NULL; + // + // We successfully deleted the multicast address from the + // card, if it is in our local list already, then remove + // it from the local multicast address list for accounting + // purposes. + // + // The stress tests be required to add and delete the stress + // multicast address to/from this list? + // + + MultAddr = Open[OpenInstance].MulticastAddresses; + + if ( MultAddr != NULL ) + { + // + // if the list is not empty see if this addr is + // in it, first check the initial entry. + // + + if ( memcmp(GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0], + MultAddr->MulticastAddress, + ADDRESS_LENGTH ) == 0 ) + { + // + // and if found remove from list and free + // + Open[OpenInstance].MulticastAddresses = MultAddr->Next; + GlobalFree( MultAddr ); + Open[OpenInstance].NumberMultAddrs--; + } + else + { + // + // Otherwise check the rest of the list. + // + + while ( MultAddr->Next != NULL ) + { + if (memcmp( GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0], + MultAddr->Next->MulticastAddress, + ADDRESS_LENGTH ) == 0 ) + { + // + // We found the address in the list, so remove + // it and deallocate the memory + // + MultAddr->Next = MultAddr->Next->Next; + GlobalFree( MultAddr->Next ); + Open[OpenInstance].NumberMultAddrs--; + break; + } + // + // Otherwise, get the next list entry. + // + + MultAddr = MultAddr->Next; + } + } + } + + TpctlPrintSetInfoResults( (PREQUEST_RESULTS)OutputBuffer, + CmdCode, + CmdArgs->ARGS.TPSET.OID ); + + break; + } + + case QUERYINFO: + TpctlPrintQueryInfoResults( (PREQUEST_RESULTS)OutputBuffer, + CmdCode, + CmdArgs->ARGS.TPQUERY.OID ); + break; + + case RESET: + TpctlPrintResults( (PREQUEST_RESULTS)OutputBuffer,CmdCode,0 ); + break; + + case SEND: + // + // If the IOCTL call failed then break out of while loop + // by setting the ExitFlag to true. + // + + if (( NtStatus != STATUS_SUCCESS ) && + ( NtStatus != STATUS_PENDING )) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + ExitFlag = TRUE; + Status = NtStatus; + break; + } + // + // If we have only attempted to SEND one packet, then we will + // print the results here and now. + // + + else if ( CmdArgs->ARGS.TPSEND.NumberOfPackets == 1 ) + { + // + // Wait for the SEND event to be signaled telling us that + // the results are complete. + // + + Status = WaitForSingleObject( Open[OpenInstance].SendEvent, + 0xFFFFFFFF ); + + if ( Status != NO_ERROR ) + { + // + // If the wait for single object failed, then exit the + // test app with the error. + // + + TpctlErrorLog("\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + ExitFlag = TRUE; + break; + } + else if ( IoStatusBlock2.Status != STATUS_SUCCESS ) + { + // + // If the send did not completed successfully then + // exit the test app with the error. + // + + TpctlErrorLog("\n\tTpctl: The SEND command failed, returned 0x%lx.\n", + (PVOID)IoStatusBlock2.Status); + ExitFlag = TRUE; + Status = IoStatusBlock2.Status; + break; + } + else + { + // + // Otherwise print the send test results. + // + + TpctlPrintSendResults( Open[OpenInstance].SendResults ); + } + + // + // then reset the SEND control flags to the initial state + // and return. + // + + Open[OpenInstance].SendResultsCompleted = FALSE; + Open[OpenInstance].Sending = FALSE; + } + break; + + case STOPSEND: + // + // Wait for the SEND event to be signaled telling us that + // the results are complete. + // + + Status = WaitForSingleObject( Open[OpenInstance].SendEvent, + 0xFFFFFFFF ); + + if ( Status != NO_ERROR ) + { + // + // If the wait for single object failed, then exit the + // test app with the error. + // + + TpctlErrorLog("\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + ExitFlag = TRUE; + break; + } + else if ( IoStatusBlock2.Status != STATUS_SUCCESS ) + { + // + // If the send did not completed successfully then + // exit the test app with the error. + // + + TpctlErrorLog("\n\tTpctl: The STOPSEND command failed, returned 0x%lx.\n", + (PVOID)IoStatusBlock2.Status); + ExitFlag = TRUE; + Status = IoStatusBlock2.Status; + break; + } + else + { + // + // Otherwise print the send test results. + // + + TpctlPrintSendResults( Open[OpenInstance].SendResults ); + } + + // + // then reset the SEND control flags to the initial state + // and return. + // + Open[OpenInstance].SendResultsCompleted = FALSE; + Open[OpenInstance].Sending = FALSE; + break; + + case RECEIVE: + // + // If the IOCTL call failed then break out of while loop + // by setting the ExitFlag to true. + // + + if (( NtStatus != STATUS_SUCCESS ) && + ( NtStatus != STATUS_PENDING )) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + ExitFlag = TRUE; + Status = NtStatus; + } + + // + // otherwise the RECEIVE test has been started successfully, and + // there is nothing more to do. + // + break; + + case STOPREC: + // + // Wait for the RECEIVE event to be signaled telling us that + // the results are complete. + // + + Status = WaitForSingleObject( Open[OpenInstance].ReceiveEvent, + 0xFFFFFFFF ); + + if ( Status != NO_ERROR ) + { + // + // If the wait for single object failed, then exit the + // test app with the error. + // + + TpctlErrorLog("\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + ExitFlag = TRUE; + break; + } + else if ( IoStatusBlock2.Status != STATUS_SUCCESS ) + { + // + // If the receive did not completed successfully then + // exit the test app with the error. + // + + TpctlErrorLog("\n\tTpctl: The STOPRECEIVE command failed, returned 0x%lx.\n", + (PVOID)IoStatusBlock2.Status); + ExitFlag = TRUE; + Status = IoStatusBlock2.Status; + break; + } + else + { + // + // Otherwise print the receive test results. + // + TpctlPrintReceiveResults( Open[OpenInstance].ReceiveResults ); + } + + // + // then reset the RECEIVE control flags to the initial state + // and return. + // + + Open[OpenInstance].ReceiveResultsCompleted = FALSE; + Open[OpenInstance].Receiving = FALSE; + break; + + case STRESS: + // + // If the Ioctl call failed then the attempt to start the + // stress test has failed, then break out of while loop by + // setting the ExitFlag to true. + // + + if ((( NtStatus != TP_STATUS_NO_SERVERS ) && + ( NtStatus != STATUS_SUCCESS )) && + ( NtStatus != STATUS_PENDING )) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + ExitFlag = TRUE; + Status = NtStatus; + } + else if ( NtStatus == TP_STATUS_NO_SERVERS ) + { + // + // No Stress Servers where found to participate in the + // test, reset the Stress Test control flags to show that + // the test did not start properly. + // + + Open[OpenInstance].Stressing = FALSE; + Open[OpenInstance].StressResultsCompleted = FALSE; + Open[OpenInstance].StressClient = FALSE; + + // + // Then Display the error to the user. + // + + TpctlErrorLog("\n\tTpctl: failed to start STRESS test, returned %s.\n", + (PVOID)TpctlGetStatus( NtStatus )); + + // + // And, if we are reading commands from a script, assume + // that the failure should force the test to stop, therefore + // unload the script files. + // + + if ( !ContinueOnError ) + { + TpctlResetAllOpenStates( hFileHandle ); + TpctlCloseScripts(); + } + + } + break; + + case STRESSSERVER: + // + // If the IOCTL call failed then break out of while loop + // by setting the ExitFlag to true. + // + + if (( NtStatus != STATUS_SUCCESS ) && + ( NtStatus != STATUS_PENDING )) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + ExitFlag = TRUE; + Status = NtStatus; + } + + // + // otherwise the STRESS SERVER has been started successfully, and + // there is nothing more to do here. + // + break; + + case ENDSTRESS: + // + // Wait for the STRESS event to be signaled telling us that + // the results are complete. + // + + Status = WaitForSingleObject( Open[OpenInstance].StressEvent, + 0xFFFFFFFF ); + + if ( Status != NO_ERROR ) + { + // + // If the wait for single object failed, then exit the + // test app with the error. + // + + TpctlErrorLog("\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + ExitFlag = TRUE; + break; + + } + else if ( IoStatusBlock2.Status != STATUS_SUCCESS ) + { + // + // If the receive did not completed successfully then + // exit the test app with the error. + // + + TpctlErrorLog("\n\tTpctl: The ENDSTRESS command failed, returned 0x%lx.\n", + (PVOID)IoStatusBlock2.Status); + ExitFlag = TRUE; + Status = IoStatusBlock2.Status; + break; + } + else if ( Open[OpenInstance].StressClient == TRUE ) + { + TpctlPrintStressResults(Open[OpenInstance].StressResults, + Open[OpenInstance].Ack10 ); + + Open[OpenInstance].StressResultsCompleted = FALSE; + Open[OpenInstance].StressClient = FALSE; + Open[OpenInstance].Stressing = FALSE; + } + break; + + case BREAKPOINT: + break; + + case CMD_COMPLETED: + break; + + + case PERFSERVER: + // + // If the IOCTL call failed then break out of while loop + // by setting the ExitFlag to true. + // + Status = NtStatus; + + if (( Status != STATUS_SUCCESS ) && ( Status != STATUS_PENDING )) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + ExitFlag = TRUE; + break; + } + // + // Wait for the PERFSEND event to be signaled telling us that + // the results are complete. + // + + if (Status == STATUS_PENDING) + { + for(;;) + { + Status = WaitForSingleObject( Open[OpenInstance].PerfEvent, + 2000 ); + if (Status == WAIT_TIMEOUT) + { + if (!ContinueLooping) // ctl-C was pressed + { + ContinueLooping = TRUE; // just quit this command + + NtStatus = + NtDeviceIoControlFile( hFileHandle, + Event, + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, + IOCTL_TP_PERF_ABORT, + (PVOID)InputBuffer, + InputBufferSize, + (PVOID)OutputBuffer, + OutputBufferSize ); + + if (( NtStatus != STATUS_SUCCESS ) && + ( NtStatus != STATUS_PENDING )) + { + TpctlErrorLog( + "\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + Status = NtStatus; + } + ExitFlag = TRUE; + break; + } + } + else if ( Status != NO_ERROR ) + { + // + // If the wait for single object failed, then exit the + // test app with the error. + // + + TpctlErrorLog("\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + ExitFlag = TRUE; + break; + } + else if ( IoStatusBlock2.Status != STATUS_SUCCESS ) + { + // + // If the command did not complete successfully then + // exit the test app with the error. + // + + TpctlErrorLog( + "\n\tTpctl: The PERFSERVER command failed,returned 0x%lx.\n", + (PVOID)IoStatusBlock2.Status); + ExitFlag = TRUE; + Status = IoStatusBlock2.Status; + break; + } + else + { + break; + } + } + } + // + // then reset the SEND control flags to the initial state + // and return. + // + Open[OpenInstance].PerfResultsCompleted = FALSE; + break; + + + case PERFCLIENT: + // + // If the IOCTL call failed then break out of while loop + // by setting the ExitFlag to true. + // + + if (( NtStatus != STATUS_SUCCESS ) && ( NtStatus != STATUS_PENDING )) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + ExitFlag = TRUE; + Status = NtStatus; + break; + } + // + // Wait for the RECEIVE event to be signaled telling us that + // the results are complete. + // + + for(;;) + { + Status = WaitForSingleObject( Open[OpenInstance].PerfEvent, + 2000 ); + if (Status == WAIT_TIMEOUT) + { + if (!ContinueLooping) // ctl-C was pressed + { + ContinueLooping = TRUE; // just quit this command + + NtStatus = NtDeviceIoControlFile( hFileHandle, + Event, + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, + IOCTL_TP_PERF_ABORT, + (PVOID)InputBuffer, + InputBufferSize, + (PVOID)OutputBuffer, + OutputBufferSize ); + + if (( NtStatus != STATUS_SUCCESS ) && + ( NtStatus != STATUS_PENDING )) + { + TpctlErrorLog( + "\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)NtStatus); + Status = NtStatus; + } + ExitFlag = TRUE; + break; + } + } + + else if ( Status != NO_ERROR ) + { + // + // If the wait for single object failed, then exit the + // test app with the error. + // + + TpctlErrorLog("\n\tWaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + ExitFlag = TRUE; + break; + } + else if ( IoStatusBlock2.Status != STATUS_SUCCESS ) + { + // + // If the receive did not completed successfully then + // exit the test app with the error. + // + + TpctlErrorLog("\n\tTpctl: The PERFCLIENT command failed, returned 0x%lx.\n", + (PVOID)IoStatusBlock2.Status); + ExitFlag = TRUE; + Status = IoStatusBlock2.Status; + break; + } + + // + // If here, status was succes. Print the send test results. + // + + else + { + TpctlPrintPerformResults( Open[OpenInstance].PerfResults); + + // + // then reset the RECEIVE control flags to the initial state + // and return. + // + + Open[OpenInstance].PerfResultsCompleted = FALSE; + break; + } + } + break; + + default: + TpctlErrorLog("\n\tTpctl: Invalid Command Entered.\n",NULL); + break; + + } // switch(); + + // + // Now zero out the input and output buffers to guarantee no + // random garbage on the next call. + // + + ZeroMemory( InputBuffer,InputBufferSize ); + + if (((( CmdCode == STRESS ) || ( CmdCode == STRESSSERVER )) || + ( CmdCode == SEND )) || ( CmdCode == RECEIVE )) + { + ZeroMemory( OutputBuffer2,OutputBufferSize2 ); + } + else if (( CmdCode != CMD_ERR ) && ( CmdCode != CMD_COMPLETED )) + { + ZeroMemory( OutputBuffer,OutputBufferSize ); + } + } + + // + // The test has ended either successfully or not, close any opened + // script files, deallocate the memory buffers, and return status. + // + + TpctlCloseScripts(); + + // Reset State + + GlobalFree( InputBuffer ); + GlobalFree( OutputBuffer ); + CloseHandle( Event ); + + return Status; +} + + + +VOID +TpctlGetEvents( + IN HANDLE FileHandle, + IN HANDLE InputBuffer, + IN DWORD InputBufferSize + ) +{ + DWORD Status; + HANDLE OutputBuffer; + DWORD OutputBufferSize = IOCTL_BUFFER_SIZE; + HANDLE Event; + IO_STATUS_BLOCK IoStatusBlock; + BOOL ReadFromEventQueue = FALSE; + + ContinueLooping = TRUE; + + OutputBuffer = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,OutputBufferSize ); + + if ( OutputBuffer == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: GlobalAlloc failed to alloc OutputBuffer: returned 0x%lx.\n", + (PVOID)Status); + return; + } + + Event = CreateEvent( NULL,FALSE,FALSE,NULL ); + + if ( Event == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: CreateEvent failed: returned 0x%lx.\n",(PVOID)Status); + GlobalFree( OutputBuffer ); + return; + } + + TpctlLog("\n",NULL); + + do + { + // + // We want to continuously call the driver for the + // event information, until the event queue is empty. + // this is represented by the IoStatusBlock.Status + // being STATUS_FAILURE. + // + +// !!NOT WIN32!! + + Status = NtDeviceIoControlFile( FileHandle, + Event, + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, + TP_CONTROL_CODE( GETEVENTS,IOCTL_METHOD ), + (PVOID)InputBuffer, + InputBufferSize, + (PVOID)OutputBuffer, + OutputBufferSize ); + + if ((( Status != TP_STATUS_NO_EVENTS ) && + ( Status != STATUS_SUCCESS )) && + ( Status != STATUS_PENDING )) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)Status); + } + else if ( Status == TP_STATUS_NO_EVENTS ) + { + TpctlLog("\tTpctl: Event Queue is empty.\tMAY_DIFFER\n",NULL); + } + else + { + Status = WaitForSingleObject( Event,0xFFFFFFFF ); + + if ( Status != STATUS_SUCCESS ) + { + TpctlErrorLog("\n\tTpctl: WaitForSingleObject failed: returned 0x%lx.\n", + (PVOID)Status); + } + else if ( IoStatusBlock.Status == TP_STATUS_NO_EVENTS ) + { + TpctlLog("\tTpctl: Event Queue is empty.\tMAY_DIFFER\n",NULL); + } + else if ( IoStatusBlock.Status == STATUS_SUCCESS ) + { + TpctlPrintEventResults( (PEVENT_RESULTS)OutputBuffer ); + } + else + { + TpctlErrorLog("\tTpctl: Error getting events from driver.\n",NULL); + } + } + } while ((( IoStatusBlock.Status == STATUS_SUCCESS ) && + ( ContinueLooping == TRUE )) && + ( Status == STATUS_SUCCESS )); + + GlobalFree( OutputBuffer ); + CloseHandle( Event ); + + return; +} + + + +VOID +TpctlPauseGo( + IN HANDLE FileHandle, + IN HANDLE InputBuffer, + IN DWORD InputBufferSize, + IN DWORD CmdCode + ) +{ + DWORD Status; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE OutputBuffer; + DWORD OutputBufferSize = IOCTL_BUFFER_SIZE; + ULONG TimedOut = 0; + + OutputBuffer = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,OutputBufferSize ); + + if ( OutputBuffer == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: GlobalAlloc failed to alloc OutputBuffer: returned 0x%lx.\n", + (PVOID)Status); + return; + } + + ContinueLooping = TRUE; + + do + { + // + // We want to continuously call the driver for PAUSE or GO + // until a Go is received or the Pause is acknowledged. + // + +// !!NOT WIN32!! + + Status = NtDeviceIoControlFile( FileHandle, + NULL, // Event, + NULL, // ApcRoutine + NULL, // ApcContext + &IoStatusBlock, + TP_CONTROL_CODE( CmdCode,IOCTL_METHOD ), + (PVOID)InputBuffer, + InputBufferSize, + (PVOID)OutputBuffer, + OutputBufferSize ); + + if ( Status != STATUS_SUCCESS ) + { + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n", + (PVOID)Status); + } + else if (((PREQUEST_RESULTS)OutputBuffer)->RequestStatus == TP_STATUS_TIMEDOUT ) + { + // + // The GO or PAUSE timed out, if we have looped ten times + // display the error to the user. + // + + if (( ++TimedOut % 12 ) == 0 ) // Two Minutes + { + if ( CmdCode == GO ) + { + printf("\n\tTpctl: GO timed out prior to receiving acknowledgment packet.\n", + NULL); + printf("\t Re-Sending...\n",NULL); + } + else + { + printf("\n\tTpctl: PAUSE timed out prior to receiving GO packet.\n",NULL); + printf("\t Re-Waiting...\n",NULL); + } + } + } + else if (((PREQUEST_RESULTS)OutputBuffer)->RequestStatus != NDIS_STATUS_SUCCESS ) + { + // + // The call to send a GO or GO_ACK packet failed, display the + // error to the user. + // + + if ( CmdCode == GO ) + { + TpctlErrorLog("\n\tTpctl: Failed to send the GO packet: returned %s.\n", + (PVOID)TpctlGetStatus(((PREQUEST_RESULTS)OutputBuffer)->RequestStatus)); + } + else + { + TpctlErrorLog("\n\tTpctl: Failed to send the acknowledgment packet: returned %s.\n", + (PVOID)TpctlGetStatus(((PREQUEST_RESULTS)OutputBuffer)->RequestStatus)); + } + + Status = ((PREQUEST_RESULTS)OutputBuffer)->RequestStatus; + } + else + { + // + // The GO or PAUSE has completed successfully, break + // out of the loop. + // + break; + } + } while (( ContinueLooping == TRUE ) && ( Status == NO_ERROR )); + + if (( Status != NO_ERROR ) || ( ContinueLooping == FALSE )) + { + // + // If we are reading commands from a script, assume + // that the failure should force the test to stop, + // therefore unload the script files, and reset the + // state all opens back to the initial state. + // + + if ( !ContinueOnError ) + { + TpctlResetAllOpenStates( FileHandle ); + TpctlCloseScripts(); + } + } + + GlobalFree( OutputBuffer ); + + return; +} + + + +VOID +TpctlLoadUnload( + IN DWORD CmdCode + ) +{ + SERVICE_STATUS ServiceStatus ; + SC_HANDLE ServiceControlMgrHandle ; + SC_HANDLE ServiceHandle ; + NTSTATUS Status ; + + // + // Open the service control manager + // + ServiceControlMgrHandle = OpenSCManager( NULL, NULL, GENERIC_EXECUTE ); + ServiceHandle = OpenService(ServiceControlMgrHandle, + GlobalCmdArgs.ARGS.DriverName, + SERVICE_START|SERVICE_STOP ); + + if ( CmdCode == LOAD ) + { + if ( !StartService( ServiceHandle, 0, NULL ) ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: Failed to load MAC driver : %s\n", + (PVOID)GlobalCmdArgs.ARGS.DriverName); + TpctlErrorLog("\tError Code Status = %ldL.\n",(PVOID)Status); + } + else + { + TpctlLog( "\n\tLoaded driver %s successfully\tMAY_DIFFER\n", + GlobalCmdArgs.ARGS.DriverName ); + } + } + else + { + if ( !ControlService( ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus ) ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tTpctl: Failed to unload MAC driver : %s\n", + (PVOID)GlobalCmdArgs.ARGS.DriverName); + TpctlErrorLog("\tError Code Status = %ldL with a Service State of ",(PVOID)Status); + TpctlErrorLog("%ld\n",(PVOID)ServiceStatus.dwCurrentState); + } + else + { + TpctlLog( "\n\tUnloaded driver %s successfully.\tMAY_DIFFER\n", + GlobalCmdArgs.ARGS.DriverName ); + } + } + +} + + + +VOID +TpctlQueryStatistics( + IN PUCHAR DriverName, + IN NDIS_OID OID, + IN PUCHAR StatsBuffer, + IN DWORD BufLen + ) +{ + HANDLE FileHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + ANSI_STRING DrvrNameString; + UNICODE_STRING UnicodeDrvrName; + DWORD NameLength; + LPSTR NameBuffer; + NTSTATUS Status; + PUCHAR TmpBuf[265]; + + NameLength = strlen( DriverName ) + 1 + 8; + + NameBuffer = (LPSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + NameLength ); + + if ( NameBuffer == NULL ) + { + Status = GetLastError(); + TpctlErrorLog("\n\tGlobalAlloc failed to alloc NameBuffer: returned 0x%lx.\n", + (PVOID)Status); + return; + } + + ZeroMemory( NameBuffer, NameLength ); + + memcpy( NameBuffer,"\\Device\\",8 ); + memcpy( NameBuffer + 8, DriverName, NameLength - 8 ); + +// !!NOT WIN32!! + + RtlInitString( &DrvrNameString, NameBuffer ); + +// !!NOT WIN32!! + + RtlAnsiStringToUnicodeString( &UnicodeDrvrName, &DrvrNameString, TRUE ); + +// !!NOT WIN32!! + + InitializeObjectAttributes( &ObjectAttributes, + &UnicodeDrvrName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + +// !!NOT WIN32!! + + Status = NtOpenFile(&FileHandle, + SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_ALERT ); + + if (Status != STATUS_SUCCESS ) + { + TpctlErrorLog("\n\tTpctl: NtOpenFile returned %lx\n\n", (PVOID)Status); + return; + } + +// !!NOT WIN32!! + + Status = NtDeviceIoControlFile( FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_NDIS_QUERY_GLOBAL_STATS, + (PVOID)&OID, + sizeof( NDIS_OID ), + (PVOID)TmpBuf, //StatsBuffer, + 256); //Buflen + + if (( Status != STATUS_SUCCESS ) && + ( IoStatusBlock.Status != STATUS_SUCCESS )) + { + + TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile returned %lx\n\n", + (PVOID)IoStatusBlock.Status); + return; + } + + TpctlLog("\n\tOID 0x%8.8lx ", (PVOID)OID); + TpctlLog("len %d ", (PVOID)IoStatusBlock.Information ); + TpctlLog("value %u\tMAY_DIFFER\n\n", (PVOID)TmpBuf[0]); + +// !!NOT WIN32!! + + RtlFreeUnicodeString( &UnicodeDrvrName ); + +// !!NOT WIN32!! + + Status = NtClose( FileHandle ); +} + + +BOOL +Disable( + IN DWORD argc, + IN LPSTR argv[] + ) +{ + UINT EnvCounter1 = 0 , EnvCounter2 = 0 ; + DWORD i; + CHAR TmpBuffer[256]; + + ZeroMemory( TmpBuffer, 256 ); + + // + // Detected command Disable + // + for( i = 1; i < argc; i++ ) + { + EnvCounter1++; + + ZeroMemory ( TmpBuffer, sizeof( TmpBuffer ) ); + strncpy( TmpBuffer, argv[i], strlen( argv[i] ) ); + + if ( getenv( TmpBuffer ) != NULL ) + { + EnvCounter2++; + } + } + + // + // If all the environment variables have been enabled + // we must re-enable the tool. Setting of all the + // enviornment variables indicates that all those + // modes are supported and there is no need to disable + // the tool. If has been disabled by a previous disable + // it would require an enable to activate the tool + // + if ( (EnvCounter1 == EnvCounter2) && (EnvCounter1 != 0) ) + { + printf("\n\tSupport for "); + for( i = 1; i < argc; i++ ) + { + if ( i == (argc-1) ) + { + printf("%s ", argv[i] ); + } + else + { + if ( (i%2) == 0 ) + { + printf("\n\t"); + } + printf("%s, ", argv[i] ); + } + } + printf("modes has been detected.\n\tTPCTL has not been disabled.\n\n"); + return FALSE; + } + + // + // Disable TPCTL + // + ToolActive = FALSE; + return TRUE; +} + + diff --git a/private/ntos/ndis/testprot/tpctl/tpctl.h b/private/ntos/ndis/testprot/tpctl/tpctl.h new file mode 100644 index 000000000..129562c1f --- /dev/null +++ b/private/ntos/ndis/testprot/tpctl/tpctl.h @@ -0,0 +1,751 @@ +// ----------------------------------- +// +// Copyright (c) 1990 Microsoft Corporation +// +// Module Name: +// +// tpctl.h +// +// Abstract: +// +// This module defines the external definitions used for the MAC Tester +// +// Author: +// +// Tom Adams (tomad) 11-May-1991 +// +// Revision History: +// +// 11-May-1991 tomad +// Created +// +// 4-27-94 timothyw +// Added performance test; CPP style comments +// 5-18-94 +// Added globvars; fixed warnings +// 6-08-94 +// chgs for client/server model, perf tests +// +// ----------------------------------- + +#include "tp_ndis.h" +#include "common.h" + +// +// +// + +extern CMD_ARGS GlobalCmdArgs; + +extern LPSTR GlobalBuf; + +extern BOOL Verbose; + +extern BOOL CommandsFromScript; + +extern BOOL CommandLineLogging; + +extern BOOL RecordToScript; + +extern HANDLE CommandLineLogHandle; + +extern HANDLE ScriptRecordHandle; + +extern CHAR RecordScriptName[TPCTL_MAX_PATHNAME_SIZE]; + +extern BOOL ExitFlag; + +extern BOOL ContinueLooping; + +extern INT TpctlSeed; + +// +// Script Control is used to keep track of where in a script file the +// application is, and where to log the next set of results in the +// respective log file. +// + +typedef struct _SCRIPTCONTROL { + LPSTR ScriptFile; + BOOL IsLowestLevel; + LPBYTE Buffer; + DWORD Length; + + DWORD BufIndex; + HANDLE LogHandle; + LPSTR LogFile; +} SCRIPTCONTROL, * PSCRIPTCONTROL; + +// +// Scripts is an array of 10 script control structures allowing recursion +// of upto ten script files at any one time. Any more then 10 and an error +// occurs resulting in the closing of all upper recursive levels of script +// files. +// + +#define TPCTL_MAX_SCRIPT_LEVELS 10 + +extern SCRIPTCONTROL Scripts[TPCTL_MAX_SCRIPT_LEVELS+1]; + +extern DWORD ScriptIndex; + +// +// Initialize the script array. +// + +// ------ +// +// VOID +// TpctlInitializeScripts( +// VOID +// ); +// +// ----- + +#define TpctlInitializeScripts() { \ + DWORD i; \ + ScriptIndex = 0xFFFFFFFF; \ + for (i=0;i