summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/testprot/tpctl/cmd.c
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/cmd.c
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/cmd.c')
-rw-r--r--private/ntos/ndis/testprot/tpctl/cmd.c4160
1 files changed, 4160 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;
+
+}
+
+