summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/testprot/tpctl
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/testprot/tpctl
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/testprot/tpctl')
-rw-r--r--private/ntos/ndis/testprot/tpctl/cmd.c4160
-rw-r--r--private/ntos/ndis/testprot/tpctl/cpuperf.c307
-rw-r--r--private/ntos/ndis/testprot/tpctl/globals.c390
-rw-r--r--private/ntos/ndis/testprot/tpctl/info.c1497
-rw-r--r--private/ntos/ndis/testprot/tpctl/init.c1098
-rw-r--r--private/ntos/ndis/testprot/tpctl/makefile6
-rw-r--r--private/ntos/ndis/testprot/tpctl/parse.c2526
-rw-r--r--private/ntos/ndis/testprot/tpctl/parse.h312
-rw-r--r--private/ntos/ndis/testprot/tpctl/results.c1312
-rw-r--r--private/ntos/ndis/testprot/tpctl/sources49
-rw-r--r--private/ntos/ndis/testprot/tpctl/tp_ndis.h180
-rw-r--r--private/ntos/ndis/testprot/tpctl/tpctl.c3852
-rw-r--r--private/ntos/ndis/testprot/tpctl/tpctl.h751
13 files changed, 16440 insertions, 0 deletions
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 <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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<Ctrl-C>. (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 <Ctrl-c>.\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<TPCTL_MAX_SCRIPT_LEVELS;si++)
+ {
+ if ( Scripts[si].Buffer != NULL )
+ {
+ tmpHandle = GlobalFree( (HANDLE)Scripts[si].Buffer );
+
+ if ( tmpHandle != NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctlFreeFileBuffers: GlobalFree failed: returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+ }
+
+ Scripts[si].Buffer = NULL;
+ Scripts[si].Length = 0;
+ }
+}
+
+
+
+VOID
+TpctlUnLoadFiles(
+ VOID
+ )
+
+// ---------------
+//
+// Routine Description:
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+// --------------
+
+{
+ DWORD si;
+ HANDLE tmpHandle;
+ DWORD Status;
+
+ //
+ // TpctlUnloadFiles may be called to unload a file that is no longer
+ // needed, or a file that was not successfully loaded by TpctlLoadFiles.
+ // If the file to be unloaded is one that failed to load during the load
+ // files routine, then the ScriptIndex does not point to the correct
+ // field in the script array, so we must adjust the index pointer
+ // to the next field, otherwise just unload the file pointed by the
+ // ScriptIndex.
+ //
+
+ si = ScriptIndex;
+
+ if (( ScriptIndex < 0 ) || ( Scripts[si].IsLowestLevel == FALSE ))
+ {
+ si++;
+ }
+
+ //
+ // Free up the memory used to store the file names, and the
+ // script file commands.
+ //
+
+ if ( Scripts[si].ScriptFile != NULL )
+ {
+ tmpHandle = GlobalFree( Scripts[si].ScriptFile );
+
+ if ( tmpHandle != NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctlUnLoadFiles: GlobalFree failed: returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+ }
+
+ if ( Scripts[si].LogFile != NULL )
+ {
+ tmpHandle = GlobalFree( Scripts[si].LogFile );
+
+ if ( tmpHandle != NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctlUnLoadFiles: GlobalFree failed: returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+ }
+
+ //
+ // Do we have a unique log file, or was the log file opened by a higher
+ // order recursion of the TpctlLoadFiles routine?
+ //
+
+ if (( Scripts[si].LogHandle != (HANDLE)-1 ) && // log handle exists
+ (( si == 0 ) || // first level of recursion
+ ( Scripts[si].LogHandle != Scripts[si-1].LogHandle )))
+ {
+
+ //
+ // This level of the ReadScript command opened the log file, so
+ // we must close it now.
+ //
+
+ CloseHandle( Scripts[si].LogHandle );
+ }
+
+ //
+ // Now set all the fields to their intial state.
+ //
+
+ Scripts[si].ScriptFile = NULL;
+ Scripts[si].BufIndex = 0;
+ Scripts[si].LogHandle = (HANDLE)-1;
+ Scripts[si].LogFile = NULL;
+ Scripts[si].IsLowestLevel = FALSE;
+
+ //
+ // If we are simply unloading a script that we are finished with
+ // then decrement the index into the Scripts array to reference the
+ // next higher level, if it exists, in the ReadScript recursion.
+ // If we are unloading the highest level script file then reset
+ // the commandsfromscript flag to state that we no longer are
+ // reading the commands from a script file.
+ //
+
+ if ( si == ScriptIndex )
+ {
+ if ( --ScriptIndex == -1 )
+ {
+ CommandsFromScript = FALSE;
+ TpctlFreeFileBuffers();
+ }
+ }
+
+ if ( si != 0 )
+ {
+ Scripts[si-1].IsLowestLevel = TRUE;
+ }
+}
+
+
+
+HANDLE
+TpctlOpenLogFile(
+ VOID
+ )
+
+// -------------
+//
+// Routine Description:
+//
+// Arguments:
+//
+// Return Value:
+//
+// ------------
+
+{
+ HANDLE LogHandle;
+ DWORD Status;
+
+ if ( WriteThrough )
+ {
+ LogHandle = CreateFile( GlobalCmdArgs.ARGS.FILES.LogFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
+ NULL );
+ }
+ else
+ {
+ LogHandle = CreateFile( GlobalCmdArgs.ARGS.FILES.LogFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL );
+ }
+
+
+ if ( LogHandle == (HANDLE)-1 )
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctl: failed to open log file\"%s\", ",
+ (PVOID)GlobalCmdArgs.ARGS.FILES.LogFile);
+ TpctlErrorLog("returned 0x%lx.\n",(PVOID)Status);
+ }
+
+ return LogHandle;
+}
+
+
+
+VOID
+TpctlCloseLogFile(
+ VOID
+ )
+
+{
+ DWORD Status;
+
+ if (!CloseHandle( CommandLineLogHandle ))
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctlCloseLogFile: failed to close Log file; returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+
+ return;
+}
+
+
+
+HANDLE
+TpctlOpenScriptFile(
+ VOID
+ )
+
+// ----------------
+//
+// Routine Description:
+//
+// Created Sanjeevk 7-1-93
+//
+// This is a new function defined for the purpose of opening up a file
+// to which commands will be written
+//
+// Arguments:
+//
+// None
+//
+// Global Arguments effected:
+//
+// RecordScriptName
+//
+// Return Value:
+//
+// A HANDLE to the script file or NULL
+//
+// ---------------
+
+{
+ HANDLE ScriptHandle;
+ DWORD Status;
+
+
+ //
+ // 1. Clear the global variable and copy in the name of the file
+ // to be opened
+ //
+
+ memset( RecordScriptName, 0, (TPCTL_MAX_PATHNAME_SIZE*sizeof(CHAR)) );
+ strcpy( RecordScriptName, GlobalCmdArgs.ARGS.RECORD.ScriptFile );
+
+ if ( WriteThrough )
+ {
+ ScriptHandle = CreateFile( GlobalCmdArgs.ARGS.RECORD.ScriptFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
+ NULL );
+ }
+ else
+ {
+ ScriptHandle = CreateFile( GlobalCmdArgs.ARGS.RECORD.ScriptFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL );
+ }
+
+
+ if ( ScriptHandle == (HANDLE)-1 )
+ {
+ Status = GetLastError();
+ ZeroMemory( RecordScriptName, (TPCTL_MAX_PATHNAME_SIZE*sizeof(CHAR)) );
+ TpctlErrorLog("\n\tTpctl: failed to open script recording file\"%s\", ",
+ (PVOID)GlobalCmdArgs.ARGS.RECORD.ScriptFile);
+ TpctlErrorLog("returned 0x%lx.\n",(PVOID)Status);
+ }
+
+ return ScriptHandle;
+}
+
+
+
+VOID
+TpctlCloseScriptFile(
+ VOID
+ )
+
+// ---------------
+//
+// Routine Description:
+//
+// Created Sanjeevk 7-1-93
+//
+// This is a new function defined for the purpose of closing a file
+// to which commands were being written
+//
+// Arguments:
+//
+// None
+//
+// Global Arguments effected:
+//
+// RecordScriptName
+// ScriptRecordHandle
+//
+// Return Value:
+//
+// None
+//
+// ---------------
+
+{
+ DWORD Status;
+
+ ZeroMemory( RecordScriptName, (TPCTL_MAX_PATHNAME_SIZE*sizeof(CHAR)) );
+
+ if (!CloseHandle( ScriptRecordHandle ))
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlCloseScriptFile: failed to close script record file; returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+
+ return;
+}
+
+
+
+
+DWORD
+TpctlReadCommand(
+ IN LPSTR Prompt,
+ OUT LPSTR Buffer,
+ IN DWORD MaximumResponse
+ )
+
+// --------------
+//
+// Routine Description:
+//
+// This routine reads from the debug port or the command file one command.
+//
+// Arguments:
+//
+// IN LPSTR Prompt,
+// OUT LPSTR Buffer,
+// IN DWORD MaximumResponse,
+//
+// Return Value:
+//
+// DWORD - NO_ERROR
+//
+// -------------
+
+{
+ DWORD Status = NO_ERROR;
+ LPSTR CmdBufPtr = Buffer;
+ DWORD i, j, k;
+ BYTE LineBuf[TPCTL_CMDLINE_SIZE];
+ BYTE TmpBuf[TPCTL_CMDLINE_SIZE];
+ LPBYTE EndOfCmd;
+ LPBYTE SBuf;
+ BOOL ContinueCommand = FALSE;
+ BOOL InitialCommand = TRUE;
+ BOOL FoundEnvVar;
+ LPSTR EnvVar;
+
+ //
+ // If the ScriptIndex equals -1 we are reading commands from the
+ // command line, so we will prompt the user to enter commands.
+ //
+
+ if ( ScriptIndex == -1 )
+ {
+ TpctlPrompt( Prompt,LineBuf,MaximumResponse );
+
+ i = 0; // LineBuf index
+ k = 0; // Buffer index
+
+ while (( i < TPCTL_CMDLINE_SIZE ) &&
+ (( LineBuf[i] != '\n' ) &&
+ ( LineBuf[i] != '\r' )))
+ {
+ //
+ // If we have found the beginning of an Environment
+ // Variable argument
+ //
+
+ if ( LineBuf[i] == '%' )
+ {
+ j = (DWORD)-1;
+ FoundEnvVar = FALSE;
+ i++;
+
+ //
+ // Copy it into a temp buffer.
+ //
+
+ while (( LineBuf[i] != '\n' ) &&
+ (( LineBuf[i] != ' ' ) &&
+ (( LineBuf[i] != '\t' ) &&
+ ( LineBuf[i] != '\r' ))))
+ {
+ TmpBuf[++j] = LineBuf[i++];
+
+ if ( TmpBuf[j] == '%')
+ {
+ TmpBuf[j] = '\0';
+ FoundEnvVar = TRUE;
+ break;
+ }
+ }
+
+ TmpBuf[j] = '\0';
+
+ //
+ // 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
+ {
+ Buffer[k++] = *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
+ {
+ Buffer[k++] = LineBuf[i++];
+ }
+ }
+
+ //
+ // and then print the commands to the log file if necessary.
+ //
+
+ TpctlCmdLneLog(" %s\n", Buffer);
+
+ //
+ // Otherwise we are reading commands from a script file, so return
+ // the next command in the file.
+ //
+
+ }
+ else if ( Scripts[ScriptIndex].BufIndex >= 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 <CR>, then the buffer contains a single
+ // <CR> 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;i<ADDRESS_LENGTH;i++ )
+ {
+ *p++ = *q++;
+ *s++ = *t++;
+ }
+ break;
+
+ case BEGINLOGGING:
+ strcpy( CmdArgs->ARGS.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;i<ADDRESS_LENGTH;i++ )
+ {
+ *p++ = *q++;
+ }
+
+ CmdArgs->ARGS.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;i<ADDRESS_LENGTH;i++ )
+ {
+ *p++ = *q++;
+ }
+
+ NextMultAddr = Open[OI].MulticastAddresses;
+
+ //
+ // XXX: Should the stress tests be required to add and
+ // delete the stress multicast address to/from this list?
+ //
+
+ j = 1;
+
+ while ( NextMultAddr != NULL )
+ {
+ p = CmdArgs->ARGS.TPSET.U.MulticastAddress[j++];
+
+ for ( i=0;i<ADDRESS_LENGTH;i++ )
+ {
+ *p++ = NextMultAddr->MulticastAddress[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;i<FUNCTIONAL_ADDRESS_LENGTH;i++ )
+ {
+ *p++ = *q++;
+ }
+ break;
+
+ default:
+ TpctlErrorLog("\n\tTpctl: 0x%08lX not a valid NdisRequestSetInformation OID.\n",
+ (PVOID)GlobalCmdArgs.ARGS.TPSET.OID);
+ return FALSE;
+ }
+ break;
+
+ case DELMA:
+ {
+ PMULT_ADDR NextMultAddr;
+ DWORD OI = CmdArgs->OpenInstance - 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;i<ADDRESS_LENGTH;i++ )
+ {
+ *p++ = NextMultAddr->MulticastAddress[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;i<ADDRESS_LENGTH;i++ )
+ {
+ *p++ = *q++;
+ *s++ = *t++;
+ }
+
+ CmdArgs->ARGS.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;i<ADDRESS_LENGTH;i++ )
+ {
+ *p++ = *q++;
+ *s++ = *t++;
+ }
+ CmdArgs->ARGS.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; i<EventCount; i++)
+ {
+ if (TpEventType == Event[i])
+ {
+ return EventString[i];
+ }
+ }
+
+ return BadEvent;
+
+#undef StatusCount
+}
+
+
+
+LPSTR
+TpctlGetStatus(
+ NDIS_STATUS GeneralStatus
+ )
+{
+
+ static NDIS_STATUS Status[] = {
+ NDIS_STATUS_SUCCESS,
+ NDIS_STATUS_PENDING,
+ NDIS_STATUS_NOT_RECOGNIZED,
+ NDIS_STATUS_NOT_COPIED,
+ NDIS_STATUS_ONLINE,
+ NDIS_STATUS_RESET_START,
+ NDIS_STATUS_RESET_END,
+ NDIS_STATUS_RING_STATUS,
+ NDIS_STATUS_CLOSED,
+
+ NDIS_STATUS_WAN_LINE_UP,
+ NDIS_STATUS_WAN_LINE_DOWN,
+ NDIS_STATUS_WAN_FRAGMENT,
+
+ NDIS_STATUS_NOT_RESETTABLE,
+ NDIS_STATUS_SOFT_ERRORS,
+ NDIS_STATUS_HARD_ERRORS,
+ NDIS_STATUS_FAILURE,
+ NDIS_STATUS_RESOURCES,
+ NDIS_STATUS_CLOSING,
+ NDIS_STATUS_BAD_VERSION,
+ NDIS_STATUS_BAD_CHARACTERISTICS,
+ NDIS_STATUS_ADAPTER_NOT_FOUND,
+ NDIS_STATUS_OPEN_FAILED,
+ NDIS_STATUS_DEVICE_FAILED,
+ NDIS_STATUS_MULTICAST_FULL,
+ NDIS_STATUS_MULTICAST_EXISTS,
+ NDIS_STATUS_MULTICAST_NOT_FOUND,
+ NDIS_STATUS_REQUEST_ABORTED,
+ NDIS_STATUS_RESET_IN_PROGRESS,
+ NDIS_STATUS_CLOSING_INDICATING,
+ NDIS_STATUS_NOT_SUPPORTED,
+ NDIS_STATUS_INVALID_PACKET,
+ NDIS_STATUS_OPEN_LIST_FULL,
+ NDIS_STATUS_ADAPTER_NOT_READY,
+ NDIS_STATUS_ADAPTER_NOT_OPEN,
+ NDIS_STATUS_NOT_INDICATING,
+ NDIS_STATUS_INVALID_LENGTH,
+ NDIS_STATUS_INVALID_DATA,
+ NDIS_STATUS_BUFFER_TOO_SHORT,
+ NDIS_STATUS_INVALID_OID,
+ NDIS_STATUS_ADAPTER_REMOVED,
+ NDIS_STATUS_UNSUPPORTED_MEDIA,
+ NDIS_STATUS_GROUP_ADDRESS_IN_USE,
+ NDIS_STATUS_FILE_NOT_FOUND,
+ NDIS_STATUS_ERROR_READING_FILE,
+ NDIS_STATUS_ALREADY_MAPPED,
+ NDIS_STATUS_RESOURCE_CONFLICT,
+ NDIS_STATUS_TOKEN_RING_OPEN_ERROR,
+ TP_STATUS_NO_SERVERS,
+ TP_STATUS_NO_EVENTS
+ };
+
+#define StatusCount (sizeof(Status)/sizeof(NDIS_STATUS))
+
+ static PUCHAR String[] = {
+ "NDIS_STATUS_SUCCESS",
+ "NDIS_STATUS_PENDING",
+ "NDIS_STATUS_NOT_RECOGNIZED",
+ "NDIS_STATUS_NOT_COPIED",
+ "NDIS_STATUS_ONLINE",
+ "NDIS_STATUS_RESET_START",
+ "NDIS_STATUS_RESET_END",
+ "NDIS_STATUS_RING_STATUS",
+ "NDIS_STATUS_CLOSED",
+ "NDIS_STATUS_WAN_LINE_UP",
+ "NDIS_STATUS_WAN_LINE_DOWN",
+ "NDIS_STATUS_WAN_FRAGMENT",
+ "NDIS_STATUS_NOT_RESETTABLE",
+ "NDIS_STATUS_SOFT_ERRORS",
+ "NDIS_STATUS_HARD_ERRORS",
+ "NDIS_STATUS_FAILURE",
+ "NDIS_STATUS_RESOURCES",
+ "NDIS_STATUS_CLOSING",
+ "NDIS_STATUS_BAD_VERSION",
+ "NDIS_STATUS_BAD_CHARACTERISTICS",
+ "NDIS_STATUS_ADAPTER_NOT_FOUND",
+ "NDIS_STATUS_OPEN_FAILED",
+ "NDIS_STATUS_DEVICE_FAILED",
+ "NDIS_STATUS_MULTICAST_FULL",
+ "NDIS_STATUS_MULTICAST_EXISTS",
+ "NDIS_STATUS_MULTICAST_NOT_FOUND",
+ "NDIS_STATUS_REQUEST_ABORTED",
+ "NDIS_STATUS_RESET_IN_PROGRESS",
+ "NDIS_STATUS_CLOSING_INDICATING",
+ "NDIS_STATUS_NOT_SUPPORTED",
+ "NDIS_STATUS_INVALID_PACKET",
+ "NDIS_STATUS_OPEN_LIST_FULL",
+ "NDIS_STATUS_ADAPTER_NOT_READY",
+ "NDIS_STATUS_ADAPTER_NOT_OPEN",
+ "NDIS_STATUS_NOT_INDICATING",
+ "NDIS_STATUS_INVALID_LENGTH",
+ "NDIS_STATUS_INVALID_DATA",
+ "NDIS_STATUS_BUFFER_TOO_SHORT",
+ "NDIS_STATUS_INVALID_OID",
+ "NDIS_STATUS_ADAPTER_REMOVED",
+ "NDIS_STATUS_UNSUPPORTED_MEDIA",
+ "NDIS_STATUS_GROUP_ADDRESS_IN_USE",
+ "NDIS_STATUS_FILE_NOT_FOUND",
+ "NDIS_STATUS_ERROR_READING_FILE",
+ "NDIS_STATUS_ALREADY_MAPPED",
+ "NDIS_STATUS_RESOURCE_CONFLICT",
+ "NDIS_STATUS_TOKEN_RING_OPEN_ERROR",
+ "TP_STATUS_NO_SERVERS",
+ "TP_STATUS_NO_EVENTS"
+ };
+
+ static BYTE BadStatus[] = "UNDEFINED";
+ DWORD i;
+
+ for (i=0; i<StatusCount; i++)
+ {
+ if (GeneralStatus == Status[i])
+ {
+ return String[i];
+ }
+ }
+ return BadStatus;
+
+#undef StatusCount
+}
+
+
+
+DWORD
+TpctlGetCommandCode(
+ LPSTR Argument
+ )
+
+{
+ DWORD i;
+
+ for ( i=1;i<NUM_COMMANDS;i++ )
+ {
+ if (_stricmp( Argument, CommandCode[i].CmdAbbr ) == 0 )
+ {
+ return CommandCode[i].CmdCode;
+ }
+
+ if (_stricmp( Argument, CommandCode[i].CmdName ) == 0 )
+ {
+ return CommandCode[i].CmdCode;
+ }
+ }
+ return CMD_ERR;
+}
+
+
+
+LPSTR
+TpctlGetCommandName(
+ LPSTR Command
+ )
+
+{
+ DWORD i;
+
+ for ( i=1;i<NUM_COMMANDS;i++ )
+ {
+ if (_stricmp(Command,CommandCode[i].CmdAbbr) == 0 )
+ {
+ return CommandCode[i].CmdName;
+ }
+ if (_stricmp(Command,CommandCode[i].CmdName) == 0 )
+ {
+ return CommandCode[i].CmdName;
+ }
+ }
+ return CommandCode[CMD_ERR].CmdName;
+}
+
+
+
+LPSTR
+TpctlGetCmdCode(
+ DWORD CmdCode
+ )
+{
+ static BYTE BadCmdCode[] = "UNDEFINED";
+
+ DWORD i;
+
+ for(i=1; i<NUM_COMMANDS; i++)
+ {
+ if ( CmdCode == CommandCode[i].CmdCode )
+ {
+ return(CommandCode[i].CmdName);
+ }
+ }
+ return BadCmdCode;
+}
+
+
+
+VOID
+TpctlCopyAdapterAddress(
+ DWORD OpenInstance,
+ PREQUEST_RESULTS Results
+ )
+{
+ DWORD i;
+ PUCHAR Source, Destination;
+
+ //
+ // Sanjeevk: Bug# 5203: This routine needed modification to support
+ // the additional NDIS_MEDIUM information sent
+ // back
+ //
+
+ Source = (PUCHAR)( Results->InformationBuffer + sizeof( NDIS_MEDIUM ) );
+ Destination = (PUCHAR)( Open[OpenInstance].AdapterAddress );
+
+ for (i=0;i<ADDRESS_LENGTH;i++)
+ {
+ *Destination++ = *Source++;
+ }
+}
+
+
+
+VOID
+TpctlRecordArguments(
+ IN TESTPARAMS Options[],
+ IN DWORD OptionTableSize,
+ IN DWORD argc,
+ IN LPSTR argv[TPCTL_MAX_ARGC]
+ )
+
+// -----------------
+//
+// Routine Description:
+//
+// Create Sanjeevk 7-1-93
+//
+// This function is responsible for creating the command in parts and records
+// it to the file accessed by ScriptRecordHandle
+//
+// Arguments:
+//
+// Options The TestParameter options from which the command is created
+//
+// OptionTableSize The size of the table for the option under consideration
+//
+// argc The number of arguments passed on the TPCTL command line
+// prompt
+//
+// argv The arguments passed on the TPCTL command line prompt
+//
+//
+// Return Value:
+//
+// None
+//
+// -------------------
+
+
+{
+ DWORD i;
+ CHAR TmpBuffer[256];
+ DWORD BytesWritten,Status ;
+ DWORD CmdCode = TpctlGetCommandCode( argv[0] );
+
+
+ //
+ // 1. Clear the temporary buffer which will be used to construct an option
+ // one at a time
+ //
+ ZeroMemory ( TmpBuffer, 256 );
+
+ //
+ // 2. Attempt to access the complete name of the command code.
+ //
+ if ( CmdCode == CMD_ERR )
+ {
+ sprintf( TmpBuffer, "%s", argv[0] );
+ }
+ else
+ {
+ sprintf( TmpBuffer, "%s", TpctlGetCommandName(argv[0]) );
+ }
+
+ //
+ // 3. Write the first argument accessed into the script file
+ //
+
+ if ( !WriteFile(ScriptRecordHandle,
+ TmpBuffer,
+ strlen( TmpBuffer ),
+ &BytesWritten,
+ NULL ))
+ {
+ Status = GetLastError();
+ printf("\n\tTpctlRecordArguments: write to script record file failed, returned 0x%lx\n",
+ Status);
+ return;
+ }
+
+ //
+ // 4. Set up the buffer for reuse
+ //
+ ZeroMemory ( TmpBuffer, 256 );
+
+ //
+ // 5. Now for the number of argument passed on the TPCTL command prompt, reconstruct
+ // each sub option one at a time
+ //
+ for( i = 1; i < argc; i++ )
+ {
+ //
+ // 5.a Check if a valid Option Table has been provided and if so get the
+ // the lvalue and rvalue and combine them to form an expression
+ //
+
+ if ( Options != NULL )
+ {
+ sprintf( TmpBuffer, "\t+\n %s=%s", Options[i-1].ArgName, argv[i] );
+ }
+ else
+ {
+ if ( CmdCode != CMD_ERR )
+ {
+ sprintf( TmpBuffer, "\t+\n %s", argv[i] );
+ }
+ else
+ {
+ sprintf( TmpBuffer, " %s", argv[i] );
+ }
+ }
+
+ //
+ // 5.b Write this reconstructed string which now signifies the complete
+ // sub-option into the script file
+ //
+
+ if ( !WriteFile(ScriptRecordHandle,
+ TmpBuffer,
+ strlen( TmpBuffer ),
+ &BytesWritten,
+ NULL ))
+ {
+ Status = GetLastError();
+ printf("\n\tTpctlRecordArguments: write to script record file failed, returned 0x%lx\n",
+ Status);
+ return;
+ }
+
+ //
+ // 5.c And clear the buffer for reuse(next sub-option)
+ //
+ ZeroMemory ( TmpBuffer, 256 );
+
+ }
+
+ //
+ // 6. Since it is possible to specifiy one or more suboptions and the command prompt
+ // we must dteremine all of the lvalues and rvalues of the current option
+ // Since we can also specify a semicolon to accept default values, we must
+ // carefully consider the various types of data associated with the rvalues
+ //
+ for( i = argc; i <= OptionTableSize; i++ )
+ {
+ PUCHAR p;
+
+ switch ( Options[i-1].TestType )
+ {
+ case Integer :
+ sprintf( TmpBuffer, "\t+\n %s=%ld", Options[i-1].ArgName,
+ *(PDWORD)Options[i-1].Destination );
+ break;
+
+ case String :
+ sprintf(TmpBuffer, "\t+\n %s=%s", Options[i-1].ArgName, Options[i-1].Destination);
+ break;
+
+ case Address4 :
+ p = Options[i-1].Destination;
+ sprintf( TmpBuffer, "\t+\n %s=%02x-%02x-%02x-%02x", Options[i-1].ArgName,
+ *p, *(p+1), *(p+2), *(p+3) );
+ break;
+
+ case Address6 :
+ p = Options[i-1].Destination;
+ sprintf( TmpBuffer, "\t+\n %s=%02x-%02x-%02x-%02x-%02x-%02x", Options[i-1].ArgName,
+ *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5) );
+ break;
+
+ case ParsedInteger :
+ p = Options[i-1].Destination;
+ sprintf( TmpBuffer, "\t+\n %s=0x%4.4x", Options[i-1].ArgName, *(LPDWORD)p );
+ break;
+ }
+
+ if ( !WriteFile(ScriptRecordHandle,
+ TmpBuffer,
+ strlen( TmpBuffer ),
+ &BytesWritten,
+ NULL ))
+ {
+ Status = GetLastError();
+ printf("\n\tTpctlRecordArguments: write to script record file failed, returned 0x%lx\n", Status);
+ return;
+ }
+
+ ZeroMemory ( TmpBuffer, 256 );
+
+ }
+
+ //
+ // 7. Finally add the newline to end the command
+ //
+ sprintf( TmpBuffer, "\n\n" );
+ if ( !WriteFile(ScriptRecordHandle,
+ TmpBuffer,
+ strlen( TmpBuffer ),
+ &BytesWritten,
+ NULL ))
+ {
+ Status = GetLastError();
+ printf("\n\tTpctlRecordArguments: write to script record file failed, returned 0x%lx\n",
+ Status);
+ }
+
+}
+
+
+LPSTR
+TpctlEnumerateRegistryInfo(
+ IN PUCHAR TmpBuf,
+ IN PUCHAR DbaseName,
+ IN PUCHAR SubKeyName,
+ IN PUCHAR ValueName,
+ IN DWORD ReadValueType,
+ IN PUCHAR ReadValue,
+ IN DWORD ReadValueSize )
+{
+
+ INT i;
+
+ TmpBuf += sprintf( TmpBuf,
+ "\tDataBase Name = %s\n\tSub Key Name = %s\n\tValue Name = %s\n",
+ DbaseName, SubKeyName, ValueName );
+
+ TmpBuf += sprintf( TmpBuf, "\tValue Type = %s\n", TpctlGetValueType( ReadValueType ) );
+
+ switch( ReadValueType )
+ {
+ case REG_BINARY :
+ TmpBuf += sprintf( TmpBuf, "\tValue(IN HEX) = ");
+ for( i = 0; i < (INT)ReadValueSize; i++ )
+ {
+ if ( i%6 || (i == 0) )
+ {
+ TmpBuf += sprintf( TmpBuf, "%2.2x ", ReadValue[i] );
+ }
+ else
+ {
+ TmpBuf += sprintf( TmpBuf, "\n\t %2.2x ", ReadValue[i] );
+ }
+ }
+ TmpBuf += sprintf( TmpBuf, "\n" );
+ break;
+
+ case REG_DWORD :
+ TmpBuf += sprintf( TmpBuf, "\tValue = 0x%lx\n", *(LPDWORD)ReadValue );
+ break;
+
+ //
+ // This code section had to be commented out because the idiot who defined
+ // the types made LITTLE_ENDIAN = DWORD. If we were to port over to a
+ // BIG_ENDIAN system, we would have to comment out the code for BIG_ENDIAN
+ //
+ // case REG_DWORD_LITTLE_ENDIAN :
+ // TmpBuf += sprintf( TmpBuf, "\tValue = LITTLE_ENDIAN 0x" );
+ // for( i = 0 ; i < ReadValueSize ; i++ )
+ // {
+ // TmpBuf += sprintf( TmpBuf, "%2.2x", ReadValue[i] );
+ // }
+ // TmpBuf += sprintf( TmpBuf, " DWORD VALUE 0x%lx\n", *(LPDWORD)ReadValue );
+ // break;
+
+ case REG_DWORD_BIG_ENDIAN:
+ TmpBuf += sprintf( TmpBuf, "\tValue = BIG_ENDIAN 0x" );
+ for( i = 0 ; i < (INT)ReadValueSize ; i++ )
+ {
+ TmpBuf += sprintf( TmpBuf, "%2.2x", ReadValue[i] );
+ }
+ TmpBuf += sprintf( TmpBuf, " DWORD VALUE 0x" );
+ for( i = 0 ; i < (INT)ReadValueSize ; i++ )
+ {
+ TmpBuf += sprintf( TmpBuf, "%2.2x", ReadValue[i] );
+ }
+ TmpBuf += sprintf( TmpBuf, "\n" );
+ break;
+
+ case REG_LINK:
+ case REG_EXPAND_SZ:
+ TmpBuf += sprintf( TmpBuf, "\tValue = %s\n", ReadValue );
+ break;
+
+ case REG_MULTI_SZ:
+ TmpBuf += sprintf( TmpBuf, "\tValue(s)\n" );
+ {
+ PUCHAR Tmp1 = ReadValue;
+
+ while ( strlen( Tmp1 ) != 0 )
+ {
+ TmpBuf += sprintf( TmpBuf, "\t\t%s\n", Tmp1 );
+ Tmp1 += (strlen( Tmp1 ) + 1);
+ }
+ }
+ break;
+
+ case REG_NONE:
+ TmpBuf += sprintf( TmpBuf, "\tValue = %s\n", ReadValue );
+ break;
+
+ case REG_RESOURCE_LIST:
+ TmpBuf += sprintf( TmpBuf, "\tValue = %s\n", ReadValue );
+ break;
+
+ case REG_SZ:
+ TmpBuf += sprintf( TmpBuf, "\tValue = %s\n", ReadValue );
+ break;
+
+ default:
+ TmpBuf += sprintf( TmpBuf, "\tValue = UNKNOWN\n" );
+ break;
+
+ }
+
+ return TmpBuf;
+
+}
+
+
+LPSTR
+TpctlGetValueType(
+ IN DWORD ValueType
+ )
+{
+ static UCHAR ValueTypeString[20];
+
+ ZeroMemory( ValueTypeString, 20 );
+
+ switch ( ValueType )
+ {
+ case REG_BINARY :
+ strcpy( ValueTypeString, "REG_BINARY" );
+ break;
+
+ case REG_DWORD :
+ strcpy( ValueTypeString, "REG_DWORD" );
+ break;
+ //
+ // This code section had to be commented out because the idiot who defined
+ // the types made LITTLE_ENDIAN = DWORD. If we were to port over to a
+ // BIG_ENDIAN system, we would have to comment out the code for BIG_ENDIAN
+ //
+ // case REG_DWORD_LITTLE_ENDIAN :
+ // strcpy( ValueTypeString, "REG_DWORD_LITTLE_ENDIAN" );
+ // break;
+ //
+
+ case REG_DWORD_BIG_ENDIAN :
+ strcpy( ValueTypeString, "REG_DWORD_BIG_ENDIAN" );
+ break;
+
+ case REG_EXPAND_SZ :
+ strcpy( ValueTypeString, "REG_EXPAND_SZ" );
+ break;
+
+ case REG_LINK :
+ strcpy( ValueTypeString, "REG_LINK" );
+ break;
+
+ case REG_MULTI_SZ :
+ strcpy( ValueTypeString, "REG_MULTI_SZ" );
+ break;
+
+ case REG_NONE :
+ strcpy( ValueTypeString, "REG_NONE" );
+ break;
+
+ case REG_RESOURCE_LIST :
+ strcpy( ValueTypeString, "REG_RESOURCE_LIST" );
+ break;
+
+ case REG_SZ :
+ strcpy( ValueTypeString, "REG_SZ" );
+ break;
+
+ default :
+ strcpy( ValueTypeString, "UNDEFINED" );
+ break;
+ }
+
+ return ValueTypeString;
+
+}
+
+
diff --git a/private/ntos/ndis/testprot/tpctl/cpuperf.c b/private/ntos/ndis/testprot/tpctl/cpuperf.c
new file mode 100644
index 000000000..ebd92cb11
--- /dev/null
+++ b/private/ntos/ndis/testprot/tpctl/cpuperf.c
@@ -0,0 +1,307 @@
+//
+// Include files
+//
+// #include <ntos.h>
+
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+#include <ntexapi.h>
+
+#include <windows.h>
+
+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 <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#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 <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+
+//#include <ndis.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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;i<INDENT;i++ ) { \
+ _Str[i] = CHAR_SP; \
+ } \
+ Length = strlen( Label ); \
+ strncpy( &_Str[INDENT],#Label,Length+2 ); \
+ \
+ for ( i=strlen( _Str ) ; i<MAX_STR_LEN ; i++ ) { \
+ _Str[i] = CHAR_SP; \
+ } \
+ _Str[INDENT+Length+2] = '\0'; \
+ Buffer += (BYTE)sprintf( Buffer,"%s",_Str ); \
+ \
+ TpctlDumpNewLine( Buffer ); \
+}
+
+/*++
+
+VOID
+TpctlDumpEquality(
+ LPSTR Buffer,
+ DWORD Value,
+ DWORD String
+ );
+
+--*/
+
+#define TpctlDumpEquality( Buffer,Value,String ) { \
+ \
+ if ( Value == String ) { \
+ TpctlDumpLabel( Buffer,#String ); \
+ return; \
+ } \
+}
+
+/*++
+
+VOID
+TpctlDumpBitField(
+ LPSTR Buffer,
+ DWORD PacketFilter,
+ DWORD BitField
+ );
+
+--*/
+
+#define TpctlDumpBitfield( Buffer,Value,BitField ) { \
+ \
+ if (( Value ) & BitField ) { \
+ TpctlDumpLabel( Buffer,#BitField ); \
+ } \
+}
+
+VOID
+TpctlDumpOID(
+ LPSTR *B,
+ DWORD OID
+ )
+{
+ //
+ // General Objects
+ //
+
+ TpctlDumpEquality( *B,OID,OID_GEN_SUPPORTED_LIST );
+ TpctlDumpEquality( *B,OID,OID_GEN_HARDWARE_STATUS );
+ TpctlDumpEquality( *B,OID,OID_GEN_MEDIA_SUPPORTED );
+ TpctlDumpEquality( *B,OID,OID_GEN_MEDIA_IN_USE );
+ TpctlDumpEquality( *B,OID,OID_GEN_MAXIMUM_LOOKAHEAD );
+ TpctlDumpEquality( *B,OID,OID_GEN_MAXIMUM_FRAME_SIZE );
+ TpctlDumpEquality( *B,OID,OID_GEN_LINK_SPEED );
+ TpctlDumpEquality( *B,OID,OID_GEN_TRANSMIT_BUFFER_SPACE );
+ TpctlDumpEquality( *B,OID,OID_GEN_RECEIVE_BUFFER_SPACE );
+ TpctlDumpEquality( *B,OID,OID_GEN_TRANSMIT_BLOCK_SIZE );
+ TpctlDumpEquality( *B,OID,OID_GEN_RECEIVE_BLOCK_SIZE );
+ TpctlDumpEquality( *B,OID,OID_GEN_VENDOR_ID );
+ TpctlDumpEquality( *B,OID,OID_GEN_VENDOR_DESCRIPTION );
+ TpctlDumpEquality( *B,OID,OID_GEN_CURRENT_PACKET_FILTER );
+ TpctlDumpEquality( *B,OID,OID_GEN_CURRENT_LOOKAHEAD );
+ TpctlDumpEquality( *B,OID,OID_GEN_DRIVER_VERSION );
+ TpctlDumpEquality( *B,OID,OID_GEN_MAXIMUM_TOTAL_SIZE );
+ TpctlDumpEquality( *B,OID,OID_GEN_PROTOCOL_OPTIONS );
+ TpctlDumpEquality( *B,OID,OID_GEN_MAC_OPTIONS );
+
+ TpctlDumpEquality( *B,OID,OID_GEN_XMIT_OK );
+ TpctlDumpEquality( *B,OID,OID_GEN_RCV_OK );
+ TpctlDumpEquality( *B,OID,OID_GEN_XMIT_ERROR );
+ TpctlDumpEquality( *B,OID,OID_GEN_RCV_ERROR );
+ TpctlDumpEquality( *B,OID,OID_GEN_RCV_NO_BUFFER );
+
+ TpctlDumpEquality( *B,OID,OID_GEN_DIRECTED_BYTES_XMIT );
+ TpctlDumpEquality( *B,OID,OID_GEN_DIRECTED_FRAMES_XMIT );
+ TpctlDumpEquality( *B,OID,OID_GEN_MULTICAST_BYTES_XMIT );
+ TpctlDumpEquality( *B,OID,OID_GEN_MULTICAST_FRAMES_XMIT );
+ TpctlDumpEquality( *B,OID,OID_GEN_BROADCAST_BYTES_XMIT );
+ TpctlDumpEquality( *B,OID,OID_GEN_BROADCAST_FRAMES_XMIT );
+ TpctlDumpEquality( *B,OID,OID_GEN_DIRECTED_BYTES_RCV );
+ TpctlDumpEquality( *B,OID,OID_GEN_DIRECTED_FRAMES_RCV );
+ TpctlDumpEquality( *B,OID,OID_GEN_MULTICAST_BYTES_RCV );
+ TpctlDumpEquality( *B,OID,OID_GEN_MULTICAST_FRAMES_RCV );
+ TpctlDumpEquality( *B,OID,OID_GEN_BROADCAST_BYTES_RCV );
+ TpctlDumpEquality( *B,OID,OID_GEN_BROADCAST_FRAMES_RCV );
+
+ TpctlDumpEquality( *B,OID,OID_GEN_RCV_CRC_ERROR );
+ TpctlDumpEquality( *B,OID,OID_GEN_TRANSMIT_QUEUE_LENGTH );
+
+ //
+ // 802.3 Objects
+ //
+
+ TpctlDumpEquality( *B,OID,OID_802_3_PERMANENT_ADDRESS );
+ TpctlDumpEquality( *B,OID,OID_802_3_CURRENT_ADDRESS );
+ TpctlDumpEquality( *B,OID,OID_802_3_MULTICAST_LIST );
+ TpctlDumpEquality( *B,OID,OID_802_3_MAXIMUM_LIST_SIZE );
+
+ TpctlDumpEquality( *B,OID,OID_802_3_RCV_ERROR_ALIGNMENT );
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_ONE_COLLISION );
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_MORE_COLLISIONS );
+
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_DEFERRED);
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_MAX_COLLISIONS );
+ TpctlDumpEquality( *B,OID,OID_802_3_RCV_OVERRUN );
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_UNDERRUN );
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_HEARTBEAT_FAILURE );
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_TIMES_CRS_LOST );
+ TpctlDumpEquality( *B,OID,OID_802_3_XMIT_LATE_COLLISIONS );
+
+ //
+ // 802.5 Objects
+ //
+
+ TpctlDumpEquality( *B,OID,OID_802_5_PERMANENT_ADDRESS );
+ TpctlDumpEquality( *B,OID,OID_802_5_CURRENT_ADDRESS );
+ TpctlDumpEquality( *B,OID,OID_802_5_CURRENT_FUNCTIONAL );
+ TpctlDumpEquality( *B,OID,OID_802_5_CURRENT_GROUP );
+ TpctlDumpEquality( *B,OID,OID_802_5_LAST_OPEN_STATUS );
+ TpctlDumpEquality( *B,OID,OID_802_5_CURRENT_RING_STATUS );
+ TpctlDumpEquality( *B,OID,OID_802_5_CURRENT_RING_STATE );
+
+ TpctlDumpEquality( *B,OID,OID_802_5_LINE_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_802_5_LOST_FRAMES );
+
+ TpctlDumpEquality( *B,OID,OID_802_5_BURST_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_802_5_AC_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_802_5_ABORT_DELIMETERS );
+ TpctlDumpEquality( *B,OID,OID_802_5_FRAME_COPIED_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_802_5_FREQUENCY_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_802_5_TOKEN_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_802_5_INTERNAL_ERRORS );
+
+ //
+ // Fddi object
+ //
+
+ TpctlDumpEquality( *B,OID,OID_FDDI_LONG_PERMANENT_ADDR );
+ TpctlDumpEquality( *B,OID,OID_FDDI_LONG_CURRENT_ADDR );
+ TpctlDumpEquality( *B,OID,OID_FDDI_LONG_MULTICAST_LIST );
+ TpctlDumpEquality( *B,OID,OID_FDDI_LONG_MAX_LIST_SIZE );
+ TpctlDumpEquality( *B,OID,OID_FDDI_SHORT_PERMANENT_ADDR );
+ TpctlDumpEquality( *B,OID,OID_FDDI_SHORT_CURRENT_ADDR );
+ TpctlDumpEquality( *B,OID,OID_FDDI_SHORT_MULTICAST_LIST );
+ TpctlDumpEquality( *B,OID,OID_FDDI_SHORT_MAX_LIST_SIZE);
+
+ TpctlDumpEquality( *B,OID,OID_FDDI_ATTACHMENT_TYPE );
+ TpctlDumpEquality( *B,OID,OID_FDDI_UPSTREAM_NODE_LONG );
+ TpctlDumpEquality( *B,OID,OID_FDDI_DOWNSTREAM_NODE_LONG );
+ TpctlDumpEquality( *B,OID,OID_FDDI_FRAME_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_FDDI_FRAMES_LOST );
+ TpctlDumpEquality( *B,OID,OID_FDDI_RING_MGT_STATE );
+ TpctlDumpEquality( *B,OID,OID_FDDI_LCT_FAILURES );
+ TpctlDumpEquality( *B,OID,OID_FDDI_LEM_REJECTS );
+ TpctlDumpEquality( *B,OID,OID_FDDI_LCONNECTION_STATE );
+
+ //
+ // STARTCHANGE
+ //
+ TpctlDumpEquality( *B,OID,OID_ARCNET_PERMANENT_ADDRESS );
+ TpctlDumpEquality( *B,OID,OID_ARCNET_CURRENT_ADDRESS ) ;
+ TpctlDumpEquality( *B,OID,OID_ARCNET_RECONFIGURATIONS ) ;
+ //
+ // STOPCHANGE
+ //
+
+ //
+ // Async Objects
+ //
+
+/* Not currently supported.
+
+ TpctlDumpEquality( *B,OID,OID_ASYNC_PERMANENT_ADDRESS );
+ TpctlDumpEquality( *B,OID,OID_ASYNC_CURRENT_ADDRESS );
+ TpctlDumpEquality( *B,OID,OID_ASYNC_QUALITY_OF_SERVICE );
+ TpctlDumpEquality( *B,OID,OID_ASYNC_PROTOCOL_TYPE );
+*/
+ //
+ // LocalTalk Objects
+ //
+
+/* Not currently supported.
+
+ TpctlDumpEquality( *B,OID,OID_LTALK_CURRENT_NODE_ID );
+
+ TpctlDumpEquality( *B,OID,OID_LTALK_IN_BROADCASTS );
+ TpctlDumpEquality( *B,OID,OID_LTALK_IN_LENGTH_ERRORS );
+
+ TpctlDumpEquality( *B,OID,OID_LTALK_OUT_NO_HANDLERS );
+ TpctlDumpEquality( *B,OID,OID_LTALK_COLLISIONS );
+ TpctlDumpEquality( *B,OID,OID_LTALK_DEFERS );
+ TpctlDumpEquality( *B,OID,OID_LTALK_NO_DATA_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_LTALK_RANDOM_CTS_ERRORS );
+ TpctlDumpEquality( *B,OID,OID_LTALK_FCS_ERRORS );
+*/
+}
+
+
+VOID
+TpctlDumpHardWareStatus(
+ LPSTR *B,
+ DWORD Status
+ )
+{
+ TpctlDumpNewLine( *B );
+ TpctlDumpEquality( *B,Status,NdisHardwareStatusClosing );
+ TpctlDumpEquality( *B,Status,NdisHardwareStatusInitializing );
+ TpctlDumpEquality( *B,Status,NdisHardwareStatusNotReady );
+ TpctlDumpEquality( *B,Status,NdisHardwareStatusReady );
+ TpctlDumpEquality( *B,Status,NdisHardwareStatusReset );
+ TpctlDumpNewLine( *B );
+}
+
+VOID
+TpctlDumpPacketFilter(
+ LPSTR *B,
+ DWORD PacketFilter
+ )
+{
+ TpctlDumpNewLine( *B );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_DIRECTED );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_MULTICAST );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_ALL_MULTICAST );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_BROADCAST );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_SOURCE_ROUTING );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_PROMISCUOUS );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_MAC_FRAME );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_GROUP );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_FUNCTIONAL );
+ TpctlDumpBitfield( *B,PacketFilter,NDIS_PACKET_TYPE_ALL_FUNCTIONAL );
+ TpctlDumpNewLine( *B );
+}
+
+VOID
+TpctlDumpNdisMedium(
+ LPSTR *B,
+ DWORD NdisMedium
+ )
+{
+ TpctlDumpEquality( *B,NdisMedium,NdisMedium802_3 );
+ TpctlDumpEquality( *B,NdisMedium,NdisMedium802_5 );
+ TpctlDumpEquality( *B,NdisMedium,NdisMediumFddi );
+ //
+ // STARTCHANGE ARCNET
+ //
+ TpctlDumpEquality( *B,NdisMedium,NdisMediumArcnet878_2 );
+ //
+ // STOPCHANGE ARCNET
+ //
+
+}
+
+
+VOID
+TpctlPrintQueryInfoResults(
+ PREQUEST_RESULTS Results,
+ DWORD CmdCode,
+ NDIS_OID OID
+ )
+
+/*++
+
+Routine Description:
+
+Arguments:
+
+Return Value:
+
+--*/
+
+{
+ DWORD Status;
+ LPSTR TmpBuf;
+ LPBYTE Address;
+ LPDWORD Counters;
+ DWORD BytesWritten;
+ DWORD i;
+ DWORD Number;
+ LPDWORD Supported;
+
+
+ //ASSERT( Results->Signature == 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;i<Number;i++ ) {
+ TpctlDumpOID( &TmpBuf,*Supported++ );
+ }
+
+ ADD_DIFF_FLAG( TmpBuf, "\t MAY_DIFFER" );
+
+ break;
+
+ case OID_GEN_HARDWARE_STATUS: // 0x00010102
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tHardware Status = 0x%lx\n",
+ *(LPDWORD)Results->InformationBuffer);
+
+ 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;i<Number;i++ ) {
+
+ TpctlDumpNdisMedium( &TmpBuf,*Supported++ );
+ }
+
+ break;
+
+ case OID_GEN_MAXIMUM_LOOKAHEAD: // 0x00010105
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMaximum Lookahead Size = %d",
+ *(LPDWORD)Results->InformationBuffer);
+
+ 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;i<Number;i++ ) {
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\t\t%02X-%02X-%02X-%02X-%02X-%02X\n",
+ Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]);
+
+ Address += (BYTE)ADDRESS_LENGTH;
+ }
+ }
+
+ break;
+
+ case OID_802_3_MAXIMUM_LIST_SIZE: // 0x01010104
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tMaximum Multicast List Size = %d",
+ *(LPDWORD)Results->InformationBuffer);
+
+ 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;i<Number;i++ ) {
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\t\t%02X-%02X-%02X-%02X-%02X-%02X\n",
+ Address[0],Address[1],Address[2],Address[3],Address[4],Address[5]);
+
+ Address += (BYTE)ADDRESS_LENGTH;
+ }
+ }
+
+ break;
+
+ case OID_FDDI_LONG_MAX_LIST_SIZE : // 0x03010104
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tLong Maximum Multicast List Size = %d",
+ *(LPDWORD)Results->InformationBuffer);
+
+ 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;i<Number;i++ ) {
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\t\t%02X-%02X\n",
+ Address[0],Address[1]);
+
+ Address += (BYTE)ADDRESS_LENGTH;
+ }
+ }
+
+ break;
+
+ case OID_FDDI_SHORT_MAX_LIST_SIZE: // 0x03010108
+
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\n\tShort Maximum Multicast List Size = %d",
+ *(LPDWORD)Results->InformationBuffer);
+
+ 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 <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+//#include <ndis.h>
+#include <ntddndis.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tpctl.h"
+#include "parse.h"
+
+BOOL Verbose = TRUE;
+
+BOOL CommandsFromScript = FALSE;
+
+BOOL CommandLineLogging = FALSE;
+
+BOOL RecordToScript = FALSE;
+
+HANDLE CommandLineLogHandle;
+
+HANDLE ScriptRecordHandle;
+
+BOOL ExitFlag = FALSE;
+
+SCRIPTCONTROL Scripts[TPCTL_MAX_SCRIPT_LEVELS+1];
+
+DWORD ScriptIndex;
+
+CHAR RecordScriptName[TPCTL_MAX_PATHNAME_SIZE];
+
+OPEN_BLOCK Open[NUM_OPEN_INSTANCES];
+
+CMD_ARGS GlobalCmdArgs;
+
+LPSTR GlobalBuf = NULL;
+
+BOOL ContinueLooping = TRUE;
+
+BOOL WriteThrough = TRUE;
+
+BOOL ContinueOnError = FALSE;
+
+INT TpctlSeed = 0;
+
+//
+// the MAIN routine
+//
+
+
+VOID _cdecl
+main(
+ IN WORD argc,
+ IN LPSTR argv[]
+ )
+
+// ---------
+//
+// Routine Description:
+//
+// This routine initializes the TPCTL control structures, opens the
+// TPDRVR driver, and send it a wakeup ioctl. Once this has completed
+// the user is presented with the test prompt to enter commands,
+// or if a script file was entered at the command line, it is opened,
+// and the commands are read from the file.
+//
+// Arguments:
+//
+// IN WORD argc - Supplies the number of parameters
+// IN LPSTR argv[] - Supplies the parameter list.
+//
+// Return Value:
+//
+// None.
+//
+// ----------
+
+{
+ HANDLE TpdrvrHandle;
+ DWORD Status;
+
+
+ //
+ // Adding this for version control recognition
+ //
+ printf( "\nMAC NDIS 3.0 Tester - Test Control Tool Version 1.5.3\n\n" );
+
+
+ //
+ // First we will disable Ctrl-C by installing a handler.
+ //
+
+ if ( !SetConsoleCtrlHandler( TpctlCtrlCHandler,TRUE ))
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctl: failed to install Ctrl-C handler, returned 0x%lx.\n",
+ (PVOID)Status);
+ ExitProcess(Status);
+ }
+
+ //
+ // Initialize the Scripts control structure before we check to
+ // see if there are any scripts on the command line to be read.
+ //
+
+ TpctlInitializeScripts();
+
+ //
+ // Initialize the script-accessible global variables
+ //
+
+ TpctlInitGlobalVariables();
+
+ //
+ // Check the command line parameters, and if there is a script file
+ // and log file open each.
+ //
+
+ Status = TpctlParseCommandLine( argc,argv );
+
+ if ( Status != NO_ERROR )
+ {
+ ExitProcess((DWORD)Status);
+ }
+
+ //
+ // Initialize the Open Block Structure and Environment Variables.
+ //
+
+ Status = TpctlInitializeOpenArray();
+
+ if ( Status != NO_ERROR )
+ {
+ TpctlFreeOpenArray();
+ TpctlCloseScripts();
+ ExitProcess((DWORD)Status);
+ }
+
+ //
+ // Open the first instance of the Test Protocol driver.
+ //
+
+ Status = TpctlOpenTpdrvr( &TpdrvrHandle );
+
+ if ( Status != NO_ERROR )
+ {
+ TpctlFreeOpenArray();
+ TpctlCloseScripts();
+ ExitProcess((DWORD)Status);
+ }
+
+ //
+ // Start the actual tests, TpctlRunTest prompts for the commands or
+ // reads the script files and then drives the tests.
+ //
+
+ Status = TpctlRunTest( TpdrvrHandle );
+
+ if ( Status != NO_ERROR )
+ {
+ TpctlCloseTpdrvr( TpdrvrHandle );
+ TpctlFreeOpenArray();
+ TpctlCloseScripts();
+ ExitProcess((DWORD)Status);
+ }
+
+ //
+ // Close the Test Protocol driver, and free the Open Array data structs.
+ //
+
+ TpctlCloseTpdrvr( TpdrvrHandle );
+
+ TpctlFreeOpenArray();
+
+ TpctlCloseScripts();
+
+ if ( !SetConsoleCtrlHandler( TpctlCtrlCHandler,FALSE ))
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctl: failed to remove Ctrl-C handler, returned 0x%lx.\n",
+ (PVOID)Status);
+ ExitProcess(Status);
+ }
+
+ ExitProcess((DWORD)NO_ERROR);
+}
+
+
+DWORD
+TpctlInitializeOpenArray(
+ VOID
+ )
+
+// ----------------
+//
+// Routine Description:
+//
+//
+// Arguments:
+//
+//
+// Return Value:
+//
+// ---------------
+
+{
+ DWORD Status;
+ DWORD i;
+
+ ZeroMemory( Open,NUM_OPEN_INSTANCES * sizeof( OPEN_BLOCK ));
+
+ for ( i=0;i<NUM_OPEN_INSTANCES;i++ )
+ {
+ Open[i].Signature = OPEN_BLOCK_SIGNATURE;
+ Open[i].OpenInstance = 0xFF;
+ Open[i].AdapterOpened = FALSE;
+
+ Open[i].MediumType = 0;
+ Open[i].NdisVersion = 0;
+
+ Open[i].AdapterName = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
+ MAX_ADAPTER_NAME_LENGTH );
+
+ if ( Open[i].AdapterName == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Adapter Name, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Open[i].AdapterName[0] = '\0';
+ Open[i].LookaheadSize = 0;
+ Open[i].PacketFilter = NDIS_PACKET_TYPE_NONE;
+ Open[i].MulticastAddresses = NULL;
+ Open[i].NumberMultAddrs = 0;
+
+ Open[i].EnvVars = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof( ENVIRONMENT_VARIABLES ) );
+
+ if ( Open[i].EnvVars == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc EnvVars structure, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Open[i].EnvVars->WindowSize = WINDOW_SIZE;
+ Open[i].EnvVars->RandomBufferNumber = BUFFER_NUMBER;
+ Open[i].EnvVars->StressDelayInterval = DELAY_INTERVAL;
+ Open[i].EnvVars->UpForAirDelay = UP_FOR_AIR_DELAY;
+ Open[i].EnvVars->StandardDelay = STANDARD_DELAY;
+
+ strcpy( Open[i].EnvVars->StressAddress,STRESS_MULTICAST );
+ strcpy( Open[i].EnvVars->ResendAddress,NULL_ADDRESS );
+
+ Open[i].EventThreadStarted = FALSE;
+ Open[i].Events[TPCONTROL] = CreateEvent( NULL,FALSE,FALSE,NULL );
+ Open[i].Events[TPSTRESS] = CreateEvent( NULL,FALSE,FALSE,NULL );
+ Open[i].Events[TPSEND] = CreateEvent( NULL,FALSE,FALSE,NULL );
+ Open[i].Events[TPRECEIVE] = CreateEvent( NULL,FALSE,FALSE,NULL );
+ Open[i].Events[TPPERF] = CreateEvent( NULL,FALSE,FALSE,NULL );
+
+ Open[i].Stressing = FALSE;
+ Open[i].StressEvent = CreateEvent( NULL,FALSE,FALSE,NULL );
+ Open[i].StressResultsCompleted = FALSE;
+ Open[i].StressClient = FALSE;
+
+ Open[i].StressResults = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof( STRESS_RESULTS ) );
+
+ if ( Open[i].StressResults == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Stress Results structure, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Open[i].StressArgs = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof( CMD_ARGS ) );
+
+ if ( Open[i].StressArgs == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Stress Args structure, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Open[i].Sending = FALSE;
+ Open[i].SendEvent = CreateEvent( NULL,FALSE,FALSE,NULL );
+ Open[i].SendResultsCompleted = FALSE;
+
+ Open[i].SendResults = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof( SEND_RECEIVE_RESULTS ) );
+
+ if ( Open[i].SendResults == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Send Results structure, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Open[i].SendArgs = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof( CMD_ARGS ) );
+
+ if ( Open[i].SendArgs == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Send Args structure, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Open[i].Receiving = FALSE;
+ Open[i].ReceiveEvent = CreateEvent( NULL,FALSE,FALSE,NULL );
+ Open[i].ReceiveResultsCompleted = FALSE;
+
+ Open[i].ReceiveResults = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof( SEND_RECEIVE_RESULTS ) );
+
+ if ( Open[i].ReceiveResults == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Receive Results structure, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Open[i].PerfEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
+ Open[i].PerfResultsCompleted = FALSE;
+ Open[i].PerfResults = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof (PERF_RESULTS) );
+
+ if ( Open[i].PerfResults == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Perf Results structure, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ Status = TpctlStartEventHandlerThread( &Open[i] );
+
+ if ( Status != NO_ERROR )
+ {
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to start EventHandler thread, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+ else
+ {
+ Open[i].EventThreadStarted = TRUE;
+ }
+ }
+
+ GlobalBuf = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
+ 0x1000 + ( MAX_SERVERS * 0x400 ) );
+
+ if ( GlobalBuf == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog(
+ "\n\tTpctlInitializeOpenArray: failed to alloc Global Statistics buffer, returned 0x%lx.\n",
+ (PVOID)Status);
+ return Status;
+ }
+
+ return NO_ERROR;
+}
+
+
+DWORD
+TpctlResetOpenState(
+ IN POPEN_BLOCK Open,
+ IN HANDLE FileHandle
+ )
+
+// -------------
+//
+// Routine Description:
+//
+// This routine reset the state of an open to its initial state.
+//
+// Arguments:
+//
+// IN POPEN_BLOCK Open - the open block to reset to it initial state.
+// IN HANDLE FileHandle - the handle to the driver to close the open
+// iff already opened.
+//
+// Return Value:
+//
+// DWORD - NO_ERROR if the adapter was closed successfully or was never
+// opened. Otherwise, the result of the close if it fails.
+//
+// -----------
+
+{
+ DWORD Status = NO_ERROR;
+ PMULT_ADDR MultAddr = NULL;
+ PMULT_ADDR NextMultAddr = NULL;
+
+ //
+ // If the adapter is closed attempt to close it, and then
+ // set the opened flag to FALSE.
+ //
+
+ if ( Open->AdapterOpened == TRUE )
+ {
+ HANDLE Event;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PBYTE InputBuffer[0x100];
+ DWORD InputBufferSize = 0x100;
+ PBYTE OutputBuffer[0x100];
+ DWORD OutputBufferSize = 0x100;
+ PCMD_ARGS CmdArgs;
+
+ Event = CreateEvent( NULL,FALSE,FALSE,NULL );
+
+ if (Event == NULL)
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tCreateEvent failed: returned 0x%lx.\n",(PVOID)Status);
+ }
+
+ CmdArgs = (PCMD_ARGS)InputBuffer;
+
+ CmdArgs->CmdCode = CLOSE;
+ CmdArgs->OpenInstance = Open->OpenInstance + 1;
+
+// !!NOT WIN32!!
+
+ Status = NtDeviceIoControlFile( FileHandle,
+ Event,
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &IoStatusBlock,
+ TP_CONTROL_CODE( CLOSE,IOCTL_METHOD ),
+ InputBuffer,
+ InputBufferSize,
+ OutputBuffer,
+ OutputBufferSize );
+
+ if (( Status != STATUS_SUCCESS ) && ( Status != STATUS_PENDING ))
+ {
+ TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile failed: returned 0x%lx.\n",
+ (PVOID)Status);
+ ExitFlag = TRUE;
+
+ }
+ else
+ {
+ if (( Status == STATUS_PENDING ) && ( Event != NULL ))
+ {
+ //
+ // If the ioctl pended, then wait for it to complete.
+ //
+
+ Status = WaitForSingleObject( Event,60000 ); // ONE_MINUTE
+
+ if ( Status == WAIT_TIMEOUT )
+ {
+ //
+ // The wait timed out, this probable means there
+ // was a failure in the MAC not completing the
+ // close.
+ //
+
+ TpctlErrorLog(
+ "\n\tTpctl: WARNING - WaitForSingleObject unexpectedly timed out.\n",NULL);
+ TpctlErrorLog(
+ "\t IRP was never completed in protocol driver.\n",NULL);
+ }
+ else if ( Status != NO_ERROR )
+ {
+ //
+ // If the wait for single object failed, then exit
+ // the test app with the error.
+ //
+
+ TpctlErrorLog(
+ "\n\tTpctl: ERROR - WaitForSingleObject failed: returned 0x%lx.\n",
+ (PVOID)Status);
+ ExitFlag = TRUE;
+ }
+ else if ( IoStatusBlock.Status != STATUS_SUCCESS )
+ {
+ //
+ // else if the pending ioctl returned failure again
+ // exit the test app with the error.
+ //
+
+ TpctlErrorLog("\n\tTpctl: NtDeviceIoControlFile pended.\n",NULL);
+ TpctlErrorLog("\n\t NtDeviceIoControlFile failed: returned 0x%lx.\n",
+ (PVOID)IoStatusBlock.Status);
+ ExitFlag = TRUE;
+ Status = IoStatusBlock.Status;
+ }
+ }
+ }
+
+ Open->AdapterOpened = FALSE;
+ }
+
+ //
+ // Then reset the various card and test specific flags to their
+ // original state.
+ //
+
+ Open->OpenInstance = 0xFF;
+ Open->MediumType = 0;
+ Open->NdisVersion = 0;
+
+ Open->AdapterName = NULL;
+ Open->LookaheadSize = 0;
+ Open->PacketFilter = NDIS_PACKET_TYPE_NONE;
+ Open->MulticastAddresses = NULL;
+ Open->NumberMultAddrs = 0;
+
+ // Environment variables.
+
+ Open->EnvVars->WindowSize = WINDOW_SIZE;
+ Open->EnvVars->RandomBufferNumber = BUFFER_NUMBER;
+ Open->EnvVars->StressDelayInterval = DELAY_INTERVAL;
+ Open->EnvVars->UpForAirDelay = UP_FOR_AIR_DELAY;
+ Open->EnvVars->StandardDelay = STANDARD_DELAY;
+
+ strcpy( Open->EnvVars->StressAddress,STRESS_MULTICAST );
+ strcpy( Open->EnvVars->ResendAddress,NULL_ADDRESS );
+
+ // Stress test flags.
+
+ Open->Stressing = FALSE;
+ Open->StressResultsCompleted = FALSE;
+ Open->StressClient = FALSE;
+
+ // Send test flags.
+
+ Open->Sending = FALSE;
+ Open->SendResultsCompleted = FALSE;
+
+ // Receive test flags.
+
+ Open->Receiving = FALSE;
+ Open->ReceiveResultsCompleted = FALSE;
+
+ // performance test flags
+
+ Open->PerfResultsCompleted = FALSE;
+
+ // Card state variables and structures.
+
+ MultAddr = Open->MulticastAddresses;
+
+ while ( MultAddr != NULL )
+ {
+ NextMultAddr = MultAddr->Next;
+ GlobalFree( MultAddr );
+ MultAddr = NextMultAddr;
+ }
+
+ Open->MulticastAddresses = NULL;
+ Open->NumberMultAddrs = 0;
+
+ ZeroMemory(Open->FunctionalAddress, FUNCTIONAL_ADDRESS_LENGTH);
+ ZeroMemory(Open->GroupAddress, FUNCTIONAL_ADDRESS_LENGTH);
+
+ return Status;
+}
+
+
+
+VOID
+TpctlFreeOpenArray(
+ VOID
+ )
+
+// -------------
+//
+// Routine Description:
+//
+//
+// Arguments:
+//
+//
+// Return Value:
+//
+// ---------------
+
+{
+ DWORD i;
+
+ for ( i=0;i<NUM_OPEN_INSTANCES;i++ )
+ {
+ //
+ // First free up all of the allocated data structs,
+ //
+
+ if ( Open[i].AdapterName != NULL )
+ {
+ GlobalFree( Open[i].AdapterName );
+ }
+
+ if ( Open[i].EnvVars != NULL )
+ {
+ GlobalFree( Open[i].EnvVars );
+ }
+
+ if ( Open[i].StressResults != NULL )
+ {
+ GlobalFree( Open[i].StressResults );
+ }
+
+ if ( Open[i].StressArgs != NULL )
+ {
+ GlobalFree( Open[i].StressArgs );
+ }
+
+ if ( Open[i].SendResults != NULL )
+ {
+ GlobalFree( Open[i].SendResults );
+ }
+
+ if ( Open[i].StressArgs != NULL )
+ {
+ GlobalFree( Open[i].SendArgs );
+ }
+
+ if ( Open[i].ReceiveResults != NULL )
+ {
+ GlobalFree( Open[i].ReceiveResults );
+ }
+
+ if ( Open[i].PerfResults != NULL )
+ {
+ GlobalFree( Open[i].PerfResults );
+ }
+
+ //
+ // Then stop the EventHandler thread,
+ //
+
+ TpctlStopEventHandlerThread( &Open[i] );
+
+ //
+ // And finally close all of the event handles.
+ //
+
+ if ( Open[i].Events[TPCONTROL] != NULL )
+ {
+ CloseHandle( Open[i].Events[TPCONTROL] );
+ }
+
+ if ( Open[i].Events[TPCONTROL] != NULL )
+ {
+ CloseHandle( Open[i].Events[TPSTRESS] );
+ }
+
+ if ( Open[i].Events[TPSEND] != NULL )
+ {
+ CloseHandle( Open[i].Events[TPSEND] );
+ }
+
+ if ( Open[i].Events[TPRECEIVE] != NULL )
+ {
+ CloseHandle( Open[i].Events[TPRECEIVE] );
+ }
+
+ if ( Open[i].Events[TPPERF] != NULL )
+ {
+ CloseHandle( Open[i].Events[TPPERF] );
+ }
+
+ if ( Open[i].StressEvent != NULL )
+ {
+ CloseHandle( Open[i].StressEvent );
+ }
+
+ if ( Open[i].SendEvent != NULL )
+ {
+ CloseHandle( Open[i].SendEvent );
+ }
+
+ if ( Open[i].ReceiveEvent != NULL )
+ {
+ CloseHandle( Open[i].ReceiveEvent );
+ }
+
+ if ( Open[i].PerfEvent != NULL )
+ {
+ CloseHandle( Open[i].PerfEvent );
+ }
+ }
+
+ GlobalFree( GlobalBuf );
+}
+
+
+DWORD
+TpctlOpenTpdrvr(
+ IN OUT PHANDLE lphFileHandle
+ )
+
+// -------------
+//
+// Routine Description:
+//
+// This routine calls CreateFile to open the TPDRVR.SYS device driver.
+//
+// Arguments:
+//
+// lphFileHandle - the file handle of the file to be opened.
+//
+// Return Value:
+//
+// lphFileHandle contains a positive value if successful, -1 if not.
+//
+// -------------
+
+{
+ DWORD Status = NO_ERROR;
+
+ *lphFileHandle = CreateFile(DEVICE_NAME,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, // lpSecurityAttirbutes
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ NULL); // lpTemplateFile
+
+ if ( *lphFileHandle == (HANDLE)-1 )
+ {
+ Status = GetLastError();
+ if ( Status == STATUS_DEVICE_ALREADY_ATTACHED )
+ {
+ TpctlErrorLog("\n\tTpctl: Tpdrvr.sys already opened by another instance of\n",NULL);
+ TpctlErrorLog("\t the control application. Only one open allowed.\n",NULL);
+ }
+ else
+ {
+ TpctlErrorLog("\n\tTpctlOpenTpdrvr: CreateFile failed: returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+ }
+
+ return Status;
+}
+
+
+
+VOID
+TpctlCloseTpdrvr(
+ IN HANDLE hFileHandle
+ )
+
+// ----------------
+//
+// Routine Description:
+//
+// This routine calls CloseHandle to close the first instance of the
+// TPDRVR.EXE driver.
+//
+// Arguments:
+//
+// hFileHandle - the file handle returned from the call to OpenFile.
+//
+// Return Value:
+//
+// STATUS - the status of the CloseHandle call.
+//
+// -----------------
+
+{
+ DWORD Status;
+
+ if ( !CloseHandle( hFileHandle ))
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctlCloseTpdrvr: CloseHandle failed: returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+
+ return;
+}
+
+
+
+DWORD
+TpctlStartEventHandlerThread(
+ POPEN_BLOCK Open
+ )
+
+// -----------
+//
+// Routine Description:
+//
+//
+// Arguments:
+//
+//
+// Return Value:
+//
+// --------------
+
+{
+ DWORD Status = NO_ERROR;
+ DWORD StackSize = 0x1000;
+ DWORD ThreadId;
+ HANDLE EventThread;
+
+
+ EventThread = CreateThread( NULL,
+ StackSize,
+ TpctlEventHandler,
+ (LPVOID)Open,
+ 0,
+ &ThreadId );
+
+ if ( EventThread == NULL )
+ {
+ Status = GetLastError();
+ TpctlErrorLog("TpctlStartEventHandlerThread: CreateThread failed; returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+ else
+ {
+ //
+ // the CreateT succeeded, we don't need the handle so close it.
+ //
+
+ if ( !CloseHandle( EventThread ) )
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctlStartEventHandlerThread: CloseHandle failed; returned 0x%lx\n",
+ (PVOID)Status);
+ }
+ }
+
+ return Status;
+}
+
+
+
+DWORD
+TpctlEventHandler(
+ LPVOID Open
+ )
+
+// --------------
+//
+// Routine Description:
+//
+// Arguments:
+//
+// Return Value:
+//
+// ----------
+
+{
+ BOOL Continue = TRUE;
+ DWORD EventNumber;
+ DWORD Status;
+
+ while ( Continue == TRUE )
+ {
+ EventNumber = WaitForMultipleObjects( 5,
+ (LPHANDLE)((POPEN_BLOCK)Open)->Events,
+ FALSE,
+ INFINITE );
+
+ switch ( EventNumber )
+ {
+ case TPCONTROL: // ResetWaitEvent;
+ Continue = FALSE;
+ break;
+
+ case TPSTRESS: // StressEvent
+ //
+ // Set the Stressing flag to false to indicate that we have
+ // finished the STRESS test, and the ResultsCompleted flag to
+ // true to indicate that the results are ready to be displayed.
+ //
+
+ ((POPEN_BLOCK)Open)->Stressing = FALSE;
+
+ if (((POPEN_BLOCK)Open)->StressClient == TRUE )
+ {
+ ((POPEN_BLOCK)Open)->StressResultsCompleted = TRUE;
+ }
+
+ //
+ // And then signal the app that we have finished.
+ //
+
+ if (!SetEvent(((POPEN_BLOCK)Open)->StressEvent))
+ {
+ Status = GetLastError();
+ OutputDebugString("TpctlEventHandler: failed to signal Stress Event 0x%lx.\n");
+ }
+ break;
+
+ case TPSEND: // SendEvent
+ //
+ // Set the Sending flag to false to indicate that we have
+ // finished the SEND test, and the ResultsCompleted flag to
+ // true to indicate that the results are ready to be displayed.
+ //
+
+ ((POPEN_BLOCK)Open)->Sending = FALSE;
+ ((POPEN_BLOCK)Open)->SendResultsCompleted = TRUE;
+
+ //
+ // And then signal the app that we have finished.
+ //
+
+ if (!SetEvent( ((POPEN_BLOCK)Open)->SendEvent ))
+ {
+ Status = GetLastError();
+ OutputDebugString("TpctlEventHandler: failed to signal Send Event 0x%lx.\n");
+ }
+ break;
+
+ case TPRECEIVE: // ReceiveEvent
+ //
+ // Set the Receiving flag to false to indicate that we have
+ // finished the RECEIVE test, and the ResultsCompleted flag to
+ // true to indicate that the results are ready to be displayed.
+ //
+
+ ((POPEN_BLOCK)Open)->Receiving = FALSE;
+ ((POPEN_BLOCK)Open)->ReceiveResultsCompleted = TRUE;
+
+ //
+ // And then signal the app that we have finished.
+ //
+
+ if (!SetEvent( ((POPEN_BLOCK)Open)->ReceiveEvent ))
+ {
+ Status = GetLastError();
+ OutputDebugString("TpctlEventHandler: failed to signal Receive Event.\n");
+ }
+ break;
+
+ case TPPERF: // PerfEvent
+ //
+ // Set the PerfResultsCompleted flag to
+ // true to indicate that the results are ready to be displayed.
+ //
+
+ ((POPEN_BLOCK)Open)->PerfResultsCompleted = TRUE;
+
+ //
+ // And then signal the app that we have finished.
+ //
+
+ if (!SetEvent( ((POPEN_BLOCK)Open)->PerfEvent ))
+ {
+ Status = GetLastError();
+ OutputDebugString("TpctlEventHandler: failed to signal Perf Event.\n");
+ }
+ break;
+ }
+ }
+
+ return EventNumber;
+}
+
+
+
+VOID
+TpctlStopEventHandlerThread(
+ POPEN_BLOCK Open
+ )
+
+// ----------------
+//
+// Routine Description:
+//
+//
+// Arguments:
+//
+//
+// Return Value:
+//
+// ----------------
+
+{
+ DWORD Status;
+
+ //
+ // First signal the thread to stop the Wait call.
+ //
+
+ if ( Open->EventThreadStarted == TRUE )
+ {
+ if ( !SetEvent( Open->Events[TPCONTROL] ))
+ {
+ Status = GetLastError();
+ TpctlErrorLog("\n\tTpctlStopEventHandlerThread: SetEvent failed; returned 0x%lx.\n",
+ (PVOID)Status);
+ }
+ }
+}
+
+
+
+BOOL
+TpctlCtrlCHandler(
+ IN DWORD CtrlType
+ )
+
+// --------------
+//
+// Routine Description:
+//
+// This routine catches any instances of Ctrl-C and sets the
+// ContinueLooping flag to FALSE. WaitStress, WaitSend, GetEvents,
+// Pause and Go, and parsing of script file commands will halt
+// when this flag is set to true.
+//
+// Arguments:
+//
+// DWORD CtrlType - the event passed in by the system.
+//
+// Return Value:
+//
+// BOOL - TRUE if this event should be ignored by the system, FALSE
+// otherwise.
+//
+// --------------
+
+
+{
+ if ( CtrlType == CTRL_BREAK_EVENT )
+ {
+ return FALSE;
+ }
+ else if ( CtrlType == CTRL_C_EVENT )
+ {
+ if ( ContinueLooping == TRUE )
+ {
+ ContinueLooping = FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
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 <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#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;i<TestSize;i++ )
+ {
+ Options[i].ArgValueSet = FALSE;
+
+ switch ( Options[i].TestType )
+ {
+ case Integer:
+ *(PDWORD)Options[i].Destination = Options[i].IntegerDefault;
+ break;
+
+ case String:
+ if ( Options[i].StringDefault != NULL )
+ {
+ strcpy( (LPSTR)Options[i].Destination, Options[i].StringDefault );
+ }
+ else
+ {
+ ((LPSTR)Options[i].Destination)[0] = '\0';
+ }
+ break;
+
+ case Address4:
+ p = Options[i].Destination;
+ q = Options[i].StringDefault;
+
+ for ( j=0;j<FUNCTIONAL_ADDRESS_LENGTH;j++ )
+ {
+ *p++ = *q++;
+ }
+ break;
+
+ case Address6:
+ p = Options[i].Destination;
+ q = Options[i].StringDefault;
+
+ for ( j=0;j<ADDRESS_LENGTH;j++ )
+ {
+ *p++ = *q++;
+ }
+ break;
+
+
+ case ParsedInteger:
+ TpctlParseInteger( Options[i].StringDefault,
+ Options[i].ParsedIntTable,
+ Options[i].ParsedIntTableSize,
+ Options[i].Destination);
+
+ break;
+
+ default:
+ TpctlErrorLog("\nTpctl: ParseArguments: Invalid TestType\n",NULL);
+ return (DWORD)-1;
+ }
+ }
+
+ //
+ // Now parse the input command line, and determine if any arguments
+ // exist on the command line. The command line may be made up in one
+ // of the following ways:
+ //
+ // 1) nothing, prompt the user for all of the arguments to the given
+ // command.
+ //
+ // 2) argument name=value pairs, parse each pair and set up the options
+ // structure. if the line ends with a semicolon ';' then return the
+ // options structure to the caller, otherwise prompt the user for the
+ // remainder of the commands for the given command then return.
+ //
+ // 3) arguments values only, parse each value and place in the options
+ // structure. if the line ends with a semicolon ';' then return the
+ // options structure to the caller, otherwise prompt the user for the
+ // remainder of the commands for the given command then return.
+ //
+ // NOTE: a command line may not contain name=value pairs, and values, it
+ // may only contain one type or the other.
+ //
+
+ ArgNameValuePair = FALSE;
+ ParsedArgumentsYet = FALSE;
+
+ for( i=1;i<=ArgC;i++ )
+ {
+ if ( ArgV[i][0] == ';' )
+ {
+ return RetVal;
+ }
+
+ if ( TpctlParseArgumentPairs( ArgV[i],&ArgName,&ArgValue ))
+ {
+ if ( ParsedArgumentsYet == FALSE )
+ {
+ //
+ // We have an argument name/value pair, and this is the
+ // first argument in the command line, all the rest of the
+ // arguments MUST have an arguments name-value pairing, set
+ // the flags appropriately, and continue.
+ //
+
+ ArgNameValuePair = TRUE;
+ ParsedArgumentsYet = TRUE;
+
+ }
+ else if ( ArgNameValuePair == FALSE )
+ {
+
+ //
+ // The first argument was an argument value only, and now
+ // we have an argument name=value pair. This is an illegal
+ // entry on the command line, report the error, and return.
+ // if we are running a script file end it now reporting an
+ // error.
+ //
+
+ TpctlErrorLog("\n\tTpctl: ERROR - \"%s",ArgName);
+ TpctlErrorLog("=%s\"\n",ArgValue);
+ TpctlErrorLog("\n\tArgument values and argument name-value pairs\n",NULL);
+ TpctlErrorLog("\tmay not be combined in the same command.\n",NULL);
+ return (DWORD)-1;;
+ }
+
+ }
+ else // We have only a Argument Value.
+ {
+ if ( ParsedArgumentsYet == FALSE )
+ {
+
+ //
+ // This is the first arugment, set the flags appropriately,
+ // and continue.
+ //
+
+ ParsedArgumentsYet = TRUE;
+
+ }
+ else if ( ArgNameValuePair == TRUE )
+ {
+
+ //
+ // The first argument was an argument name=value pair, and
+ // now we have an argument value only. This is an illegal
+ // entry on the command line, report the error, and return.
+ // if we are running a script file end it now reporting an
+ // error.
+ //
+
+ TpctlErrorLog("\n\tTpctl: ERROR - \"%s\"\n",ArgValue);
+ TpctlErrorLog("\n\tArgument name-value pairs and argument values\n",NULL);
+ TpctlErrorLog("\tmay not be combined in the same command.\n",NULL);
+ return (DWORD)-1;;
+ }
+ }
+
+ if ( ArgNameValuePair == TRUE )
+ {
+
+ OptionNumber = TpctlGetOptionNumber( Options,TestSize,ArgName );
+
+ if ( OptionNumber == -1 )
+ {
+
+ //
+ // This is an invalid option number report the error, and return.
+ // if we are running a script file end it now reporting an error.
+ //
+
+ TpctlErrorLog("\n\tTpctl: Invalid Argument Name: \"%s\"",ArgName);
+ TpctlErrorLog("\n\tThis argument does not exist for this command\n",NULL);
+ return (DWORD)-1;;
+ }
+ }
+ else
+ {
+ OptionNumber = i;
+ }
+
+ { // ParsePtr scope.
+
+ PTESTPARAMS ParsePtr = &Options[OptionNumber-1];
+
+ Error = FALSE;
+
+ //
+ // If the argument passed in from the command line is the
+ // '*' symbol, the user wants to use the default argument for
+ // this variable, set the argument value and set flag to TRUE
+ // indicating that we do not need to prompt for it further, and
+ // continue with the next argument.
+ //
+
+ if ( ArgValue[0] == '*' )
+ {
+ ParsePtr->ArgValueSet = 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;j<FUNCTIONAL_ADDRESS_LENGTH;j++ )
+ {
+ p += (BYTE)sprintf(p,"%02X",*q++);
+
+ if ( j < ( FUNCTIONAL_ADDRESS_LENGTH - 1 ))
+ {
+ *p++ = '-';
+ }
+ }
+ *p = '\0';
+ }
+ break;
+
+ case Address6:
+ if ( ParsePtr->StringDefault!=NULL )
+ {
+ p = ArgPrompt + strlen( ArgPrompt );
+ q = ParsePtr->StringDefault;
+
+ for( j=0;j<ADDRESS_LENGTH;j++ )
+ {
+ p += (BYTE)sprintf(p,"%02X",*q++);
+
+ if ( j < ( ADDRESS_LENGTH - 1 ))
+ {
+ *p++ = '-';
+ }
+ }
+ *p = '\0';
+ }
+ break;
+
+ } // switch
+
+ //
+ // Now prompt the user for the new value.
+ //
+
+ strcat( ArgPrompt,"] >" );
+
+ 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;i<ParseTableSize;i++ )
+ {
+ if ( _stricmp( Token,ParseTable[i].FieldName ) == 0 )
+ {
+ *Ret |= ParseTable[i].FieldValue;
+ break;
+ }
+ }
+
+ if ( i == ParseTableSize )
+ {
+ TpctlErrorLog("\n\tTpctl: Unknown option \"%s\" entered.\n",
+ (PVOID)Token);
+ TpctlErrorLog("\n\t\tValid options are:\n\n",NULL);
+
+ for ( i=0;i<ParseTableSize;i++ )
+ {
+ TpctlErrorLog("\t\t\t%s\n", (PVOID)ParseTable[i].FieldName);
+ }
+
+ TpctlErrorLog("\n",NULL);
+ return (DWORD)-1;;
+ }
+
+ if ( savePointer != NULL )
+ {
+ *savePointer = saveToken; // Restore byte trompled on.
+ }
+
+ Token = NextToken;
+ }
+
+ return 0;
+}
+
+
+
+DWORD
+TpctlParseAddress(
+ IN BYTE Buffer[],
+ OUT PDWORD RetAddr,
+ IN DWORD OpenInstance,
+ IN DWORD AddressLength
+ )
+
+// -----------------
+//
+// Routine Description:
+//
+// This routine parses a network address and returns it to the caller.
+//
+// Arguments:
+//
+// IN BYTE Buffer[], - [Supplies | Returns] description-of-argument
+// OUT PDWORD RetAddr
+//
+// Return Value:
+//
+// DWORD
+//
+// ----------------
+
+{
+ BYTE TmpBuf[100];
+ PBYTE TmpAddr;
+ BYTE digit;
+ DWORD i, j;
+ BYTE n[2];
+ LPBYTE p;
+
+
+ if ( Buffer == NULL )
+ {
+ *RetAddr = 0;
+ return 0;
+ }
+
+ TmpAddr = (PBYTE)RetAddr;
+
+ //
+ // See if the user entered one of the text string addresses at the
+ // command line.
+ //
+
+ if ( _stricmp( Buffer,RESEND_ADDRESS ) == 0 )
+ {
+
+ //
+ // If the user has entered "resendaddress" at the command line,
+ // then we will use the resend address stored in the ResendAddress
+ // environment variable.
+ //
+
+ p = (LPBYTE)Open[OpenInstance].EnvVars->ResendAddress;
+
+ 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<TestSize; i++)
+ {
+ if (_stricmp(ArgName,Options[i].ArgName) == 0 )
+ {
+ return Options[i].OptionNumber;
+ }
+ if (_stricmp(ArgName,Options[i].ArgNameAbbr) == 0 )
+ {
+ return Options[i].OptionNumber;
+ }
+ }
+ return (DWORD)-1;;
+}
+
+
+DWORD
+TpctlGetOpenInstance(
+ IN DWORD ArgC,
+ IN LPSTR ArgV[]
+ )
+
+{
+ DWORD i;
+ LPSTR EqualSign;
+ LPBYTE NextToken;
+
+ //
+ // If we have no arguments, only the command, then return an error.
+ //
+
+ if ( ArgC <= 0 )
+ {
+ return (DWORD)-1;
+ }
+
+ //
+ // Otherwise walk the argument vector looking for an instance of either
+ // an OpenInstance = Value or simply return the first argument.
+ //
+
+ for (i=1; i<ArgC; i++)
+ {
+ if (( EqualSign = strchr(ArgV[i],'=')) == NULL ) // no = sign.
+ {
+ //
+ // Since there is no equal sign we know that the Open Instance
+ // must be the first argument, so simply return it.
+ //
+
+ return (strtoul(ArgV[i], &NextToken, 0));
+
+ }
+ else
+ {
+
+ //
+ // we have an argument value pair, check if its the
+ // Open Instance.
+ //
+
+ if ((_strnicmp(ArgV[i],"OI",2) == 0 ) ||
+ (_strnicmp(ArgV[i],"OpenInstance",12)))
+ {
+
+ //
+ // It is the open instance so return the value.
+ //
+
+ ++(EqualSign);
+ return ( strtoul( EqualSign,&NextToken,0 ));
+ }
+ }
+ }
+
+ return (DWORD)-1;;
+}
diff --git a/private/ntos/ndis/testprot/tpctl/parse.h b/private/ntos/ndis/testprot/tpctl/parse.h
new file mode 100644
index 000000000..c3206263a
--- /dev/null
+++ b/private/ntos/ndis/testprot/tpctl/parse.h
@@ -0,0 +1,312 @@
+// ---------------------------------------------------
+//
+// Copyright (c) 1991 Microsoft Corporation
+//
+// Module Name:
+//
+// parse.h
+//
+// Abstract:
+//
+//
+// Author:
+//
+// Tom Adams (tomad) 11-May-1991
+//
+// Revision History:
+//
+// 11-May-1991 tomad
+// Created
+//
+// 4-27-94 timothyw
+// added externs for performance test
+// 6-8-94 timothyw
+// changes for client/server model, perf tests
+//
+// -------------------------------------------------
+
+#define sizeoftable(TableName) (sizeof(TableName) / sizeof(TableName[0]))
+
+#define NamedField(Flag) {#Flag, Flag}
+
+
+//
+// external declarations of the Command Option Argument Parse
+// Tables and their sizes.
+//
+
+
+extern
+PARSETABLE
+BooleanTable[];
+
+extern
+PARSETABLE
+PacketFilterTable [];
+
+extern
+PARSETABLE
+QueryInfoOidTable [];
+
+extern
+PARSETABLE
+SetInfoOidTable [];
+
+extern
+PARSETABLE
+MemberTypeTable [];
+
+extern
+PARSETABLE
+PacketTypeTable [];
+
+extern
+PARSETABLE
+PacketMakeUpTable [];
+
+extern
+PARSETABLE
+ResponseTypeTable [];
+
+extern
+PARSETABLE
+DelayTable [];
+
+extern
+PARSETABLE
+TestDurationTable [];
+
+extern
+PARSETABLE
+OperationTypeTable[];
+
+extern
+PARSETABLE
+KeyDbaseTable [];
+
+extern
+PARSETABLE
+ValueTypeTable[];
+
+
+//
+// external declarations of the Test Parameter Arrays and their sizes.
+//
+
+extern
+TESTPARAMS
+CommandLineOptions[];
+
+extern
+DWORD
+Num_CommandLine_Params;
+
+extern
+TESTPARAMS
+SetEnvOptions[];
+
+extern
+DWORD
+Num_SetEnv_Params;
+
+extern
+TESTPARAMS
+ReadScriptOptions[];
+
+extern
+DWORD
+Num_ReadScript_Params;
+
+extern
+TESTPARAMS
+LoggingOptions[];
+
+extern
+DWORD
+Num_Logging_Params;
+
+extern
+TESTPARAMS
+RecordingOptions[];
+
+extern
+DWORD
+Num_Recording_Params;
+
+extern
+TESTPARAMS
+PauseGoOptions[];
+
+extern
+DWORD
+Num_PauseGo_Params;
+
+extern
+TESTPARAMS
+LoadUnloadOptions[];
+
+extern
+DWORD
+Num_LoadUnload_Params;
+
+extern
+TESTPARAMS
+OpenOptions[];
+
+extern
+DWORD
+Num_Open_Params;
+
+extern
+TESTPARAMS
+SetPacketFilterOptions[];
+
+extern
+DWORD
+Num_SetPacketFilter_Params;
+
+extern
+TESTPARAMS
+SetLookaheadOptions[];
+
+extern
+DWORD
+Num_SetLookahead_Params;
+
+extern
+TESTPARAMS
+MulticastAddrOptions[];
+
+extern
+DWORD
+Num_MulticastAddr_Params;
+
+extern
+TESTPARAMS
+FunctionalAddrOptions[];
+
+extern
+DWORD
+Num_FunctionalAddr_Params;
+
+extern
+TESTPARAMS
+GroupAddrOptions[];
+
+extern
+DWORD
+Num_GroupAddr_Params;
+
+extern
+TESTPARAMS
+QueryInfoOptions[];
+
+extern
+DWORD
+Num_QueryInfo_Params;
+
+extern
+TESTPARAMS
+QueryStatsOptions[];
+
+extern
+DWORD
+Num_QueryStats_Params;
+
+extern
+TESTPARAMS
+SetInfoOptions[];
+
+extern
+DWORD
+Num_SetInfo_Params;
+
+extern
+TESTPARAMS
+SetInfoPFOptions[];
+
+extern
+DWORD
+Num_SetInfoPF_Params;
+
+extern
+TESTPARAMS
+SetInfoLAOptions[];
+
+extern
+DWORD
+Num_SetInfoLA_Params;
+
+extern
+TESTPARAMS
+SetInfoMAOptions[];
+
+extern
+DWORD
+Num_SetInfoMA_Params;
+
+extern
+TESTPARAMS
+SetInfoFAOptions[];
+
+extern
+DWORD
+Num_SetInfoFA_Params;
+
+extern
+TESTPARAMS
+SetInfoGAOptions[];
+
+extern
+DWORD
+Num_SetInfoGA_Params;
+
+extern
+TESTPARAMS
+SendOptions[];
+
+extern
+DWORD
+Num_Send_Params;
+
+extern
+TESTPARAMS
+PerfClntOptions[];
+
+extern
+DWORD
+Num_PerfClnt_Params;
+
+extern
+TESTPARAMS
+StressOptions[];
+
+extern
+DWORD
+Num_Stress_Params;
+
+extern
+TESTPARAMS
+OpenInstanceOptions[];
+
+extern
+DWORD
+Num_OpenInstance_Params;
+
+extern
+TESTPARAMS
+HelpOptions[];
+
+extern
+DWORD
+Num_Help_Params;
+
+extern
+TESTPARAMS
+RegistryOptions[];
+
+extern
+DWORD
+Num_Registry_Params;
+
+
diff --git a/private/ntos/ndis/testprot/tpctl/results.c b/private/ntos/ndis/testprot/tpctl/results.c
new file mode 100644
index 000000000..02665bf03
--- /dev/null
+++ b/private/ntos/ndis/testprot/tpctl/results.c
@@ -0,0 +1,1312 @@
+// --------------------------------------------
+//
+// Copyright (c) 1990 Microsoft Corporation
+//
+// Module Name:
+//
+// results.c
+//
+// Abstract:
+//
+// This module handles the printing of the results of a given command.
+//
+// Author:
+//
+// Tom Adams (tomad) 2-Apr-1991
+//
+// Revision History:
+//
+// 2-Apr-1991 tomad
+//
+// created
+//
+// Sanjeev Katariya (sanjeevk)
+// 4-12-1993 #5963 Events printed out are not being used/tested for one to one
+// correspondence The IndicationStatus. Thereby I am adding a
+// MAY_DIFFER flag to the event
+//
+// Tim Wynsma (timothyw) 4-27-94
+// Added performance testing
+// 5-18-94
+// Revised output format for performance tests; cleanup
+// 6-08-94
+// Chgd perf output format for client/server model
+//
+// --------------------------------------------
+
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<Results->NumServers;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;i<MAX_SERVERS;i++ )
+ {
+ ZeroMemory (Results->Servers[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 <ntddndis.h>
+
+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 <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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<NUM_OPEN_INSTANCES;i++ )
+ {
+ if ((( Open[i].Stressing == TRUE ) ||
+ ( Open[i].Sending == TRUE )) ||
+ ( Open[i].Receiving == TRUE ))
+ {
+ TpctlErrorLog(
+ "\n\tTpctl: Cancelling outstanding IRPs, please wait...\n",NULL);
+ break;
+ }
+ }
+ ExitFlag = TRUE;
+ Status = NO_ERROR;
+ }
+ CmdCode = CMD_COMPLETED;
+ break;
+
+ case HELP:
+ if ( ToolActive )
+ {
+ DWORD TmpScriptIndex = ScriptIndex;
+
+ //
+ // We are going to temporarily override the script index
+ // to fool the TpctlParseArguments routine into not prompting
+ // for an argument if none is give with the help command.
+ //
+
+ if ( RecordToScript )
+ {
+ TpctlRecordArguments( NULL,
+ 0,
+ 1,
+ localArgv );
+ }
+
+ ScriptIndex = (DWORD)1;
+
+ if ( TpctlParseArguments( HelpOptions,
+ Num_Help_Params,
+ localArgc,
+ localArgv ) == -1 )
+ {
+ break;
+ }
+ TpctlHelp( GlobalCmdArgs.ARGS.CmdName );
+ ScriptIndex = TmpScriptIndex;
+ }
+ CmdCode = CMD_COMPLETED;
+ break;
+
+ case SHELL:
+ if ( ToolActive )
+ {
+ if ( RecordToScript )
+ {
+ TpctlRecordArguments( NULL,
+ 0,
+ 1,
+ localArgv );
+ }
+
+ {
+ CONSOLE_SCREEN_BUFFER_INFO ScreenBuffer;
+ HANDLE OutputHandle;
+ COORD Start;
+ BOOL NoErrorsAccessingConsole = FALSE;
+ DWORD CharactersWritten;
+
+ ZeroMemory( (PVOID)&ScreenBuffer, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
+ Start.X = 0;
+ Start.Y = 0;
+
+ OutputHandle = GetStdHandle( STD_OUTPUT_HANDLE );
+ //
+ // Record the old console settings
+ //
+ if ( GetConsoleScreenBufferInfo( OutputHandle, &ScreenBuffer ) )
+ {
+ NoErrorsAccessingConsole = TRUE;
+ }
+
+ //
+ // Set the console foregrounds and background colors to the new settings
+ //
+ if( NoErrorsAccessingConsole )
+ {
+ WORD Colors;
+
+ if ( ScreenBuffer.wAttributes & BACKGROUND_BLUE )
+ {
+ Colors = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|
+ FOREGROUND_INTENSITY|BACKGROUND_RED;
+ }
+ else
+ {
+ Colors = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|
+ FOREGROUND_INTENSITY|BACKGROUND_BLUE;
+ }
+
+ SetConsoleTextAttribute( OutputHandle, Colors );
+ FillConsoleOutputAttribute( OutputHandle, Colors,
+ 0xFFFFFFFF, Start,
+ &CharactersWritten );
+ }
+
+ //
+ // And spawn the command shell
+ //
+ {
+ CHAR ShellCommand[256];
+ INT TmpCount;
+
+ ZeroMemory( ShellCommand, sizeof( ShellCommand ));
+ strcpy( ShellCommand, "CMD" );
+
+ if ( localArgc > 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;i<ADDRESS_LENGTH;i++ )
+ {
+ MultAddr->MulticastAddress[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;i<FUNCTIONAL_ADDRESS_LENGTH;i++)
+ {
+ Open[OpenInstance].FunctionalAddress[i] =
+ CmdArgs->ARGS.TPSET.U.FunctionalAddress[i];
+ }
+ break;
+
+ case OID_802_5_CURRENT_GROUP:
+ for (i=0;i<FUNCTIONAL_ADDRESS_LENGTH;i++)
+ {
+ Open[OpenInstance].GroupAddress[i] =
+ CmdArgs->ARGS.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<TPCTL_MAX_SCRIPT_LEVELS+1;i++) { \
+ Scripts[i].ScriptFile = NULL; \
+ Scripts[i].IsLowestLevel = FALSE; \
+ Scripts[i].Buffer = NULL; \
+ Scripts[i].Length = 0; \
+ Scripts[i].BufIndex = 0; \
+ Scripts[i].LogHandle = (HANDLE)-1; \
+ Scripts[i].LogFile = NULL; \
+ } \
+}
+
+//
+// TPCTLCLOSESCRIPTS close any and all script files that
+// are currently opened.
+//
+
+// -----
+//
+// VOID
+// TpctlCloseScripts(
+// VOID
+// );
+//
+// -----
+
+#define TpctlCloseScripts() { \
+ if ( CommandsFromScript == TRUE ) { \
+ while ( ScriptIndex != (ULONG)-1 ) { \
+ TpctlUnLoadFiles(); \
+ } \
+ } \
+}
+
+//
+// PRINT_DIFF_FLAG will print the diff flag string S into the buffer B
+// if we are printing the results to a logfile.
+//
+
+// -----
+//
+// VOID
+// ADD_DIFF_FLAG(
+// LPSTR B
+// LPSTR S
+// );
+//
+// -----
+
+#define ADD_DIFF_FLAG( B,S ) { \
+ if (( CommandsFromScript ) || ( CommandLineLogging )) { \
+ B += (BYTE)sprintf(B,"\t%s",S); \
+ } \
+ TmpBuf += (BYTE)sprintf(TmpBuf,"\n"); \
+}
+
+#define ADD_SKIP_FLAG( B,S ) ADD_DIFF_FLAG( B,S )
+
+//
+// Reset all opens to their initial state.
+//
+
+// -----
+//
+// VOID
+// TpctlResetAllOpenStates(
+// HANDLE fh
+// );
+//
+// -----
+
+#define TpctlResetAllOpenStates( fh ) { \
+ DWORD i; \
+ if ( CommandsFromScript ) { \
+ TpctlErrorLog("\n\tTpctl: Resetting the state of all Open Instances.\n",NULL); \
+ for ( i = 0 ; i < NUM_OPEN_INSTANCES ; i++ ) { \
+ TpctlResetOpenState( &Open[i],fh ); \
+ } \
+ } \
+}
+
+//
+// Parse Tables are the structures used to contain each of the possible
+// argument names for a given command, and their value.
+//
+
+typedef struct _ParsedIntTable {
+ LPSTR FieldName;
+ DWORD FieldValue;
+} PARSETABLE, *PPARSETABLE;
+
+//
+// Paramtypes are the different types of parameters that may be parsed
+// by the ParseOptions routine for each command.
+//
+
+//
+// STARTCHANGE
+//
+typedef enum {
+ Integer,
+ String,
+ ParsedInteger,
+// Address2, // Accomodate 802.3, 802.4, 802.5, FDDI addresses
+ Address4, // Accomodate 802.4, 802.5 addresses
+ Address6, // Accomodate 802.3, 802.4, 802.5, FDDI addresses
+// Address2or6 // Conjugate type in which addresses can be 2 or 6 octets
+} PARAMTYPES;
+//
+// STOPCHANGE
+//
+
+
+//
+// The Test Options structures is used by the ParseOptions routine to
+// load the default value for a given argument, set up the prompt for
+// the argument and prompt the user for the argument. If the command is
+// entered from a script file the Test Options structures is used to
+// determine the Argument names or abbreviations and then stores the
+// values in their proper destinations.
+//
+
+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;
+
+//
+// Array entries for the Events in the Open Block
+//
+
+typedef enum {
+ TPCONTROL,
+ TPSTRESS,
+ TPSEND,
+ TPRECEIVE,
+ TPPERF
+} TPEVENT_TYPE;
+
+//
+// Multicast Address struct used to create a list of all the
+// address set on a given open.
+//
+
+typedef struct _MULT_ADDR {
+ struct _MULT_ADDR *Next;
+ BYTE MulticastAddress[ADDRESS_LENGTH];
+} MULT_ADDR, *PMULT_ADDR;
+
+//
+// the Open Block holding the info about the state of the open,
+// particulars about the card opened, and the control structs for
+// each of the given test types.
+//
+
+typedef struct _OPEN_BLOCK {
+ DWORD Signature;
+ UCHAR OpenInstance;
+ BOOL AdapterOpened;
+ NDIS_MEDIUM MediumType;
+ DWORD NdisVersion;
+
+ LPBYTE AdapterName;
+ BYTE AdapterAddress[ADDRESS_LENGTH];
+ PENVIRONMENT_VARIABLES EnvVars;
+
+ BOOL EventThreadStarted;
+ HANDLE Events[5];
+
+ BOOL Stressing;
+ PCMD_ARGS StressArgs;
+ IO_STATUS_BLOCK StressStatusBlock;
+ HANDLE StressEvent;
+ PSTRESS_RESULTS StressResults;
+ BOOL StressResultsCompleted;
+ BOOL StressClient;
+ BOOL Ack10;
+
+ BOOL Sending;
+ PCMD_ARGS SendArgs;
+ IO_STATUS_BLOCK SendStatusBlock;
+ HANDLE SendEvent;
+ PSEND_RECEIVE_RESULTS SendResults;
+ BOOL SendResultsCompleted;
+
+ BOOL Receiving;
+ IO_STATUS_BLOCK ReceiveStatusBlock;
+ HANDLE ReceiveEvent;
+ PSEND_RECEIVE_RESULTS ReceiveResults;
+ BOOL ReceiveResultsCompleted;
+
+ IO_STATUS_BLOCK PerfStatusBlock;
+ HANDLE PerfEvent;
+ PPERF_RESULTS PerfResults;
+ BOOL PerfResultsCompleted;
+
+ DWORD PacketFilter;
+
+ DWORD LookaheadSize;
+ PMULT_ADDR MulticastAddresses;
+ ULONG NumberMultAddrs;
+ BYTE FunctionalAddress[FUNCTIONAL_ADDRESS_LENGTH];
+
+ BYTE GroupAddress[FUNCTIONAL_ADDRESS_LENGTH];
+} OPEN_BLOCK, *POPEN_BLOCK;
+
+extern OPEN_BLOCK Open[NUM_OPEN_INSTANCES];
+
+#define OPEN_BLOCK_SIGNATURE 0x12121212
+
+//
+// TPCTL.C function prototypes
+//
+
+DWORD
+TpctlInitializeOpenArray(
+ VOID
+ );
+
+VOID
+TpctlFreeOpenArray(
+ VOID
+ );
+
+DWORD
+TpctlOpenTpdrvr(
+ IN OUT PHANDLE lphFileHandle
+ );
+
+VOID
+TpctlCloseTpdrvr(
+ IN HANDLE hFileHandle
+ );
+
+DWORD
+TpctlStartEventHandlerThread(
+ IN POPEN_BLOCK Open
+ );
+
+VOID
+TpctlStopEventHandlerThread(
+ IN POPEN_BLOCK Open
+ );
+
+DWORD
+TpctlEventHandler(
+ IN LPVOID Open
+ );
+
+BOOL
+TpctlCtrlCHandler(
+ IN DWORD CtrlType
+ );
+
+//
+//
+//
+
+DWORD
+TpctlRunTest(
+ IN HANDLE hFileHandle
+ );
+
+VOID
+TpctlGetEvents(
+ IN HANDLE FileHandle,
+ IN HANDLE InputBuffer,
+ IN DWORD InputBufferSize
+ );
+
+VOID
+TpctlPauseGo(
+ IN HANDLE FileHandle,
+ IN HANDLE InputBuffer,
+ IN DWORD InputBufferSize,
+ IN DWORD CmdCode
+ );
+
+DWORD
+TpctlResetOpenState(
+ IN POPEN_BLOCK Open,
+ IN HANDLE FileHandle
+ );
+
+VOID
+TpctlLoadUnload(
+ IN DWORD CmdCode
+ );
+
+VOID
+TpctlQueryStatistics(
+ IN PUCHAR DriverName,
+ IN NDIS_OID OID,
+ IN PUCHAR StatsBuffer,
+ IN DWORD BufLen
+ );
+
+BOOL
+Disable(
+ IN DWORD argc,
+ IN LPSTR argv[]
+ );
+
+//
+//
+//
+
+
+VOID
+TpctlPrintResults(
+ PREQUEST_RESULTS Results,
+ DWORD CmdCode,
+ NDIS_OID OID
+ );
+
+VOID
+TpctlPrintQueryInfoResults(
+ PREQUEST_RESULTS Results,
+ DWORD CmdCode,
+ NDIS_OID OID
+ );
+
+VOID
+TpctlPrintSetInfoResults(
+ PREQUEST_RESULTS Results,
+ DWORD CmdCode,
+ NDIS_OID OID
+ );
+
+VOID
+TpctlPrintSendResults(
+ PSEND_RECEIVE_RESULTS Results
+ );
+
+VOID
+TpctlPrintReceiveResults(
+ PSEND_RECEIVE_RESULTS Results
+ );
+
+VOID
+TpctlPrintPerformResults(
+ PPERF_RESULTS Results
+ );
+
+VOID
+TpctlPrintStressResults1(
+ IN PSTRESS_RESULTS Results,
+ IN BOOL Ack10
+ );
+
+VOID
+TpctlPrintStressResults(
+ PSTRESS_RESULTS Results,
+ IN BOOL Ack10
+ );
+
+VOID
+TpctlPrintEventResults(
+ PEVENT_RESULTS Event
+ );
+
+VOID
+TpctlZeroStressStatistics(
+ PSTRESS_RESULTS Results
+ );
+
+DWORD
+TpctlLog(
+ LPSTR String,
+ PVOID Input
+ );
+
+DWORD
+TpctlErrorLog(
+ LPSTR String,
+ PVOID Input
+ );
+
+DWORD
+TpctlScriptLog(
+ LPSTR String,
+ PVOID Input
+ );
+
+DWORD
+TpctlCmdLneLog(
+ LPSTR String,
+ PVOID Input
+ );
+
+//
+// CMD.C function prototypes
+//
+
+DWORD
+TpctlParseCommandLine(
+ IN WORD argc,
+ IN LPSTR argv[]
+ );
+
+VOID
+TpctlUsage(
+ VOID
+ );
+
+VOID
+TpctlHelp(
+ LPSTR Command
+ );
+
+DWORD
+TpctlLoadFiles(
+ IN LPSTR ScriptFile,
+ IN LPSTR LogFile
+ );
+
+
+VOID
+TpctlUnLoadFiles(
+ VOID
+ );
+
+
+HANDLE
+TpctlOpenLogFile(
+ VOID
+ );
+
+
+VOID
+TpctlCloseLogFile(
+ VOID
+ );
+
+
+HANDLE
+TpctlOpenScriptFile(
+ VOID
+ );
+
+
+VOID
+TpctlCloseScriptFile(
+ VOID
+ );
+
+DWORD
+TpctlReadCommand(
+ IN LPSTR Prompt,
+ OUT LPSTR Response,
+ IN DWORD MaximumResponse
+ );
+
+
+BOOL
+TpctlParseCommand(
+ IN LPSTR CommandLine,
+ OUT LPSTR Argv[],
+ OUT PDWORD Argc,
+ IN DWORD MaxArgc
+ );
+
+
+VOID
+TpctlPrompt(
+ LPSTR Prompt,
+ LPSTR Buffer,
+ DWORD BufferSize
+ );
+
+
+VOID
+TpctlLoadLastEnvironmentVariables(
+ DWORD OpenInstance
+ );
+
+
+VOID
+TpctlSaveNewEnvironmentVariables(
+ DWORD OpenInstance
+ );
+
+VOID
+TpctlPerformRegistryOperation(
+ IN PCMD_ARGS CmdArgs
+ );
+BOOL
+TpctlInitCommandBuffer(
+ IN OUT PCMD_ARGS CmdArgs,
+ IN DWORD CmdType
+ );
+
+
+LPSTR
+TpctlGetEventType(
+ TP_EVENT_TYPE TpEventType
+ );
+
+
+LPSTR
+TpctlGetStatus(
+ NDIS_STATUS GeneralStatus
+ );
+
+
+DWORD
+TpctlGetCommandCode(
+ LPSTR Argument
+ );
+
+
+LPSTR
+TpctlGetCommandName(
+ LPSTR Command
+ );
+
+LPSTR
+TpctlGetCmdCode(
+ DWORD CmdCode
+ );
+
+
+VOID
+TpctlCopyAdapterAddress(
+ DWORD OpenInstance,
+ PREQUEST_RESULTS Results
+ );
+
+VOID
+TpctlRecordArguments(
+ IN TESTPARAMS Options[],
+ IN DWORD OptionTableSize,
+ IN DWORD argc,
+ IN LPSTR argv[TPCTL_MAX_ARGC]
+ );
+
+LPSTR
+TpctlEnumerateRegistryInfo(
+ IN PUCHAR TmpBuf,
+ IN PUCHAR DbaseName,
+ IN PUCHAR SubKeyName,
+ IN PUCHAR ValueName,
+ IN DWORD ReadValueType,
+ IN PUCHAR ReadValue,
+ IN DWORD ReadValueSize
+ );
+
+LPSTR
+TpctlGetValueType(
+ IN DWORD ValueType
+ );
+
+
+//
+// PARSE.C Function Prototypes
+//
+
+DWORD
+TpctlParseArguments(
+ IN TESTPARAMS Options[],
+ IN DWORD TestSize,
+ IN DWORD ArgC,
+ IN LPSTR ArgV[]
+ );
+
+
+BOOL
+TpctlParseSetInfoArguments(
+ IN OUT DWORD *ArgC,
+ IN OUT LPSTR ArgV[],
+ IN OUT DWORD *tmpArgC,
+ IN OUT LPSTR tmpArgV[]
+ );
+
+
+DWORD
+TpctlParseAddress(
+ IN BYTE Buffer[],
+ OUT PDWORD Ret,
+ IN DWORD OpenInstance,
+ IN DWORD AddressLength
+ );
+
+
+VOID
+Dump_Desired_PacketFilter(
+ LPSTR Buffer,
+ DWORD PacketFilter
+ );
+
+
+VOID
+Dump_Information_Class(
+ LPSTR Buffer,
+ DWORD InfoClass
+ );
+
+
+VOID
+Dump_Ndis_Medium(
+ LPSTR Buffer,
+ DWORD Medium
+ );
+
+//
+// GLOBALS.C Function Prototypes
+//
+
+
+PVOID
+TpctlParseGlobalVariable(
+ IN BYTE Buffer[],
+ IN PARAMTYPES reqtype
+ );
+
+VOID
+TpctlInitGlobalVariables(
+ VOID
+ );
+
+
+DWORD
+TpctlParseSet(
+ IN DWORD ArgC,
+ IN LPSTR ArgV[]
+ );
+
+
+// functions from cpuperf.c
+
+
+VOID CpuUsageInit(VOID);
+
+
+ULONG CpuUsageGetData(PULONG *KernPercent,
+ ULONG NumCpus);