summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/testprot/tpctl/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/ndis/testprot/tpctl/parse.c')
-rw-r--r--private/ntos/ndis/testprot/tpctl/parse.c2526
1 files changed, 2526 insertions, 0 deletions
diff --git a/private/ntos/ndis/testprot/tpctl/parse.c b/private/ntos/ndis/testprot/tpctl/parse.c
new file mode 100644
index 000000000..613e10473
--- /dev/null
+++ b/private/ntos/ndis/testprot/tpctl/parse.c
@@ -0,0 +1,2526 @@
+// ******************************************************************
+//
+// Copyright (c) 1991 Microsoft Corporation
+//
+// Module Name:
+//
+// parse.c
+//
+// Abstract:
+//
+// This module contains the routines for parsing commands entered from
+// the command line or read from script files.
+//
+// Author:
+//
+// Tom Adams (tomad) 11-May-1991
+//
+// Revision History:
+//
+//
+// Sanjeev Katariya (sanjeevk)
+// 4-12-1993 Added ARCNET support
+// 4-15-1993 Added additional OIDS
+// 7-01-1993 Added suppport for recoring sessions and spawning
+// command shells within tpctl
+// Tim Wynsma (timothyw)
+// 4-27-94 added performance testing
+// 5-16-94 added globvars hooks; cleanup
+// 6-08-94 chgd to client/server model for perf test
+//
+// ******************************************************************
+
+
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windows.h>
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "tpctl.h"
+#include "parse.h"
+
+
+VOID
+TpctlFixBuffer(
+ IN BYTE Buffer[]
+ );
+
+
+DWORD
+TpctlParseInteger(
+ IN BYTE Buffer[],
+ IN PARSETABLE ParseTable[],
+ IN DWORD ParseTableSize,
+ OUT PDWORD Ret
+ );
+
+
+BOOL
+TpctlParseArgumentPairs(
+ IN LPSTR Argument,
+ OUT LPSTR *ArgName,
+ OUT LPSTR *ArgValue
+ );
+
+
+BOOL
+TpctlParseSetInfoArguments(
+ IN OUT DWORD *ArgC,
+ IN OUT LPSTR ArgV[],
+ IN OUT DWORD *tmpArgC,
+ IN OUT LPSTR tmpArgV[]
+ );
+
+
+BOOL
+TpctlParseEnvironmentVariable(
+ IN BYTE Buffer[]
+ );
+
+
+BOOL
+TpctlFirstChar(
+ IN BYTE Buffer[],
+ IN BYTE Char
+ );
+
+
+DWORD
+TpctlGetOptionNumber(
+ IN PTESTPARAMS Options,
+ IN DWORD TestSize,
+ IN LPSTR ArgName
+ );
+
+
+DWORD
+TpctlGetOpenInstance(
+ IN DWORD ArgC,
+ IN LPSTR ArgV[]
+ );
+
+
+
+PARSETABLE
+BooleanTable[] = {
+ NamedField( TRUE ),
+ NamedField( FALSE ),
+ { "T", TRUE },
+ { "F", FALSE }
+};
+
+
+
+PARSETABLE
+PacketFilterTable [] = {
+ NamedField( NDIS_PACKET_TYPE_DIRECTED ),
+ NamedField( NDIS_PACKET_TYPE_MULTICAST ),
+ NamedField( NDIS_PACKET_TYPE_ALL_MULTICAST ),
+ NamedField( NDIS_PACKET_TYPE_BROADCAST ),
+ NamedField( NDIS_PACKET_TYPE_SOURCE_ROUTING ),
+ NamedField( NDIS_PACKET_TYPE_PROMISCUOUS ),
+ NamedField( NDIS_PACKET_TYPE_MAC_FRAME ),
+ NamedField( NDIS_PACKET_TYPE_GROUP ),
+ NamedField( NDIS_PACKET_TYPE_FUNCTIONAL ),
+ NamedField( NDIS_PACKET_TYPE_ALL_FUNCTIONAL ),
+ NamedField( NDIS_PACKET_TYPE_NONE ),
+
+ { "Directed", NDIS_PACKET_TYPE_DIRECTED },
+ { "Multicast", NDIS_PACKET_TYPE_MULTICAST },
+ { "AllMulticast", NDIS_PACKET_TYPE_ALL_MULTICAST },
+ { "Broadcast", NDIS_PACKET_TYPE_BROADCAST },
+ { "SourceRouting", NDIS_PACKET_TYPE_SOURCE_ROUTING },
+ { "Promiscuous", NDIS_PACKET_TYPE_PROMISCUOUS },
+ { "MacFrame", NDIS_PACKET_TYPE_MAC_FRAME },
+ { "Group", NDIS_PACKET_TYPE_GROUP },
+ { "Functional", NDIS_PACKET_TYPE_FUNCTIONAL },
+ { "AllFunctional", NDIS_PACKET_TYPE_ALL_FUNCTIONAL },
+ { "None", NDIS_PACKET_TYPE_NONE }
+};
+
+
+PARSETABLE
+QueryInfoOidTable [] = {
+
+ //
+ // General Objects
+ //
+
+ NamedField( OID_GEN_SUPPORTED_LIST ),
+ NamedField( OID_GEN_HARDWARE_STATUS ),
+ NamedField( OID_GEN_MEDIA_SUPPORTED ),
+ NamedField( OID_GEN_MEDIA_IN_USE ),
+ NamedField( OID_GEN_MAXIMUM_LOOKAHEAD ),
+ NamedField( OID_GEN_MAXIMUM_FRAME_SIZE ),
+ NamedField( OID_GEN_LINK_SPEED ),
+ NamedField( OID_GEN_TRANSMIT_BUFFER_SPACE ),
+ NamedField( OID_GEN_RECEIVE_BUFFER_SPACE ),
+ NamedField( OID_GEN_TRANSMIT_BLOCK_SIZE ),
+ NamedField( OID_GEN_RECEIVE_BLOCK_SIZE ),
+ NamedField( OID_GEN_VENDOR_ID ),
+ NamedField( OID_GEN_VENDOR_DESCRIPTION ),
+ NamedField( OID_GEN_CURRENT_PACKET_FILTER ),
+ NamedField( OID_GEN_CURRENT_LOOKAHEAD ),
+ NamedField( OID_GEN_DRIVER_VERSION ),
+ NamedField( OID_GEN_MAXIMUM_TOTAL_SIZE ),
+ NamedField( OID_GEN_PROTOCOL_OPTIONS ),
+ NamedField( OID_GEN_MAC_OPTIONS ),
+
+ NamedField( OID_GEN_XMIT_OK ),
+ NamedField( OID_GEN_RCV_OK ),
+ NamedField( OID_GEN_XMIT_ERROR ),
+ NamedField( OID_GEN_RCV_ERROR ),
+ NamedField( OID_GEN_RCV_NO_BUFFER ),
+
+ NamedField( OID_GEN_DIRECTED_BYTES_XMIT ),
+ NamedField( OID_GEN_DIRECTED_FRAMES_XMIT ),
+ NamedField( OID_GEN_MULTICAST_BYTES_XMIT ),
+ NamedField( OID_GEN_MULTICAST_FRAMES_XMIT ),
+ NamedField( OID_GEN_BROADCAST_BYTES_XMIT ),
+ NamedField( OID_GEN_BROADCAST_FRAMES_XMIT ),
+ NamedField( OID_GEN_DIRECTED_BYTES_RCV ),
+ NamedField( OID_GEN_DIRECTED_FRAMES_RCV ),
+ NamedField( OID_GEN_MULTICAST_BYTES_RCV ),
+ NamedField( OID_GEN_MULTICAST_FRAMES_RCV ),
+ NamedField( OID_GEN_BROADCAST_BYTES_RCV ),
+ NamedField( OID_GEN_BROADCAST_FRAMES_RCV ),
+
+ NamedField( OID_GEN_RCV_CRC_ERROR ),
+ NamedField( OID_GEN_TRANSMIT_QUEUE_LENGTH ),
+
+ //
+ // 802.3 Objects
+ //
+
+ NamedField( OID_802_3_PERMANENT_ADDRESS ),
+ NamedField( OID_802_3_CURRENT_ADDRESS ),
+ NamedField( OID_802_3_MULTICAST_LIST ),
+ NamedField( OID_802_3_MAXIMUM_LIST_SIZE ),
+
+ NamedField( OID_802_3_RCV_ERROR_ALIGNMENT ),
+ NamedField( OID_802_3_XMIT_ONE_COLLISION ),
+ NamedField( OID_802_3_XMIT_MORE_COLLISIONS ),
+
+ NamedField( OID_802_3_XMIT_DEFERRED ),
+ NamedField( OID_802_3_XMIT_MAX_COLLISIONS ),
+ NamedField( OID_802_3_RCV_OVERRUN ),
+ NamedField( OID_802_3_XMIT_UNDERRUN ),
+ NamedField( OID_802_3_XMIT_HEARTBEAT_FAILURE ),
+ NamedField( OID_802_3_XMIT_TIMES_CRS_LOST ),
+ NamedField( OID_802_3_XMIT_LATE_COLLISIONS ),
+
+ //
+ // 802.5 Objects
+ //
+
+ NamedField( OID_802_5_PERMANENT_ADDRESS ),
+ NamedField( OID_802_5_CURRENT_ADDRESS ),
+ NamedField( OID_802_5_CURRENT_FUNCTIONAL ),
+ NamedField( OID_802_5_CURRENT_GROUP ),
+ NamedField( OID_802_5_LAST_OPEN_STATUS ),
+ NamedField( OID_802_5_CURRENT_RING_STATUS ),
+ NamedField( OID_802_5_CURRENT_RING_STATE ),
+
+ NamedField( OID_802_5_LINE_ERRORS ),
+ NamedField( OID_802_5_LOST_FRAMES ),
+
+ NamedField( OID_802_5_BURST_ERRORS ),
+ NamedField( OID_802_5_AC_ERRORS ),
+ NamedField( OID_802_5_ABORT_DELIMETERS ),
+ NamedField( OID_802_5_FRAME_COPIED_ERRORS ),
+ NamedField( OID_802_5_FREQUENCY_ERRORS ),
+ NamedField( OID_802_5_TOKEN_ERRORS ),
+ NamedField( OID_802_5_INTERNAL_ERRORS ),
+
+ //
+ // Fddi objects
+ //
+
+ NamedField( OID_FDDI_LONG_PERMANENT_ADDR ),
+ NamedField( OID_FDDI_LONG_CURRENT_ADDR ),
+ NamedField( OID_FDDI_LONG_MULTICAST_LIST ),
+ NamedField( OID_FDDI_LONG_MAX_LIST_SIZE ),
+ NamedField( OID_FDDI_SHORT_PERMANENT_ADDR ),
+ NamedField( OID_FDDI_SHORT_CURRENT_ADDR ),
+ NamedField( OID_FDDI_SHORT_MULTICAST_LIST ),
+ NamedField( OID_FDDI_SHORT_MAX_LIST_SIZE ),
+
+ NamedField( OID_FDDI_ATTACHMENT_TYPE ),
+ NamedField( OID_FDDI_UPSTREAM_NODE_LONG ),
+ NamedField( OID_FDDI_DOWNSTREAM_NODE_LONG ),
+ NamedField( OID_FDDI_FRAME_ERRORS ),
+ NamedField( OID_FDDI_FRAMES_LOST ),
+ NamedField( OID_FDDI_RING_MGT_STATE ),
+ NamedField( OID_FDDI_LCT_FAILURES ),
+ NamedField( OID_FDDI_LEM_REJECTS ),
+ NamedField( OID_FDDI_LCONNECTION_STATE ),
+
+ //
+ // STARTCHANGE
+ //
+ // ARCNET objects
+ //
+ NamedField( OID_ARCNET_PERMANENT_ADDRESS ),
+ NamedField( OID_ARCNET_CURRENT_ADDRESS ),
+ NamedField( OID_ARCNET_RECONFIGURATIONS ),
+ //
+ // STOPCHANGE
+ //
+
+ //
+ // Async Objects
+ //
+
+#if 0
+
+// Not currently supported.
+
+ NamedField( OID_ASYNC_PERMANENT_ADDRESS ),
+ NamedField( OID_ASYNC_CURRENT_ADDRESS ),
+ NamedField( OID_ASYNC_QUALITY_OF_SERVICE ),
+ NamedField( OID_ASYNC_PROTOCOL_TYPE ),
+
+#endif
+
+ //
+ // LocalTalk Objects
+ //
+
+#if 0
+
+// Not currently supported.
+
+ NamedField( OID_LTALK_CURRENT_NODE_ID ),
+
+ NamedField( OID_LTALK_IN_BROADCASTS ),
+ NamedField( OID_LTALK_IN_LENGTH_ERRORS ),
+
+ NamedField( OID_LTALK_OUT_NO_HANDLERS ),
+ NamedField( OID_LTALK_COLLISIONS ),
+ NamedField( OID_LTALK_DEFERS ),
+ NamedField( OID_LTALK_NO_DATA_ERRORS ),
+ NamedField( OID_LTALK_RANDOM_CTS_ERRORS ),
+ NamedField( OID_LTALK_FCS_ERRORS ),
+
+#endif
+
+ //
+ // General Objects
+ //
+
+ { "SupportedOIDList", OID_GEN_SUPPORTED_LIST },
+ { "HardwareStatus", OID_GEN_HARDWARE_STATUS },
+ { "MediaTypeSupported", OID_GEN_MEDIA_SUPPORTED },
+ { "MediaTypeInUse", OID_GEN_MEDIA_IN_USE },
+ { "MaximumLookahead", OID_GEN_MAXIMUM_LOOKAHEAD },
+ { "MaximumFrameSize", OID_GEN_MAXIMUM_FRAME_SIZE },
+ { "LinkSpeed", OID_GEN_LINK_SPEED },
+ { "TransmitBufferSpace", OID_GEN_TRANSMIT_BUFFER_SPACE },
+ { "ReceiveBufferSpace", OID_GEN_RECEIVE_BUFFER_SPACE },
+ { "TransmitBlockSize", OID_GEN_TRANSMIT_BLOCK_SIZE },
+ { "ReceiveBlockSize", OID_GEN_RECEIVE_BLOCK_SIZE },
+ { "VendorID", OID_GEN_VENDOR_ID },
+ { "VendorDescription", OID_GEN_VENDOR_DESCRIPTION },
+ { "CurrentPacketFilter", OID_GEN_CURRENT_PACKET_FILTER },
+ { "CurrentLookahead", OID_GEN_CURRENT_LOOKAHEAD },
+ { "DriverVersion", OID_GEN_DRIVER_VERSION },
+ { "MaximumTotalSize", OID_GEN_MAXIMUM_TOTAL_SIZE },
+
+ { "TransmitGood", OID_GEN_XMIT_OK },
+ { "ReceiveGood", OID_GEN_RCV_OK },
+ { "TransmitBad", OID_GEN_XMIT_ERROR },
+ { "ReceiveBad", OID_GEN_RCV_ERROR },
+ { "ReciveNoBuffer", OID_GEN_RCV_NO_BUFFER },
+
+ { "DirectedBytesTransmits", OID_GEN_DIRECTED_BYTES_XMIT },
+ { "DirectedFramesTransmits", OID_GEN_DIRECTED_FRAMES_XMIT },
+ { "MulticastBytesTransmits", OID_GEN_MULTICAST_BYTES_XMIT },
+ { "MulticastFramesTransmits", OID_GEN_MULTICAST_FRAMES_XMIT },
+ { "BroadcastBytesTransmits", OID_GEN_BROADCAST_BYTES_XMIT },
+ { "BroadcastFramesTransmits", OID_GEN_BROADCAST_FRAMES_XMIT },
+ { "DirectedBytesReceives", OID_GEN_DIRECTED_BYTES_RCV },
+ { "DirectedFramesReceives", OID_GEN_DIRECTED_FRAMES_RCV },
+ { "MulticastBytesReceives", OID_GEN_MULTICAST_BYTES_RCV },
+ { "MulticastFramesReceives", OID_GEN_MULTICAST_FRAMES_RCV },
+ { "BroadcastBytesReceives", OID_GEN_BROADCAST_BYTES_RCV },
+ { "BroadcastFramesReceives", OID_GEN_BROADCAST_FRAMES_RCV },
+
+ { "ReceiveCRC", OID_GEN_RCV_CRC_ERROR },
+ { "TransmitQueueLength", OID_GEN_TRANSMIT_QUEUE_LENGTH },
+
+ //
+ // 802.3 Objects
+ //
+
+ { "EthPermanentAddress", OID_802_3_PERMANENT_ADDRESS },
+ { "EthCurrentAddress", OID_802_3_CURRENT_ADDRESS },
+ { "CurrentMulticastList", OID_802_3_MULTICAST_LIST },
+ { "MaxMulticastListSize", OID_802_3_MAXIMUM_LIST_SIZE },
+
+ { "ReceiveErrorAlignment", OID_802_3_RCV_ERROR_ALIGNMENT },
+ { "TransmitOneCollsion", OID_802_3_XMIT_ONE_COLLISION },
+ { "TransmitMoreCollostions", OID_802_3_XMIT_MORE_COLLISIONS },
+
+ { "TransmitDeferred", OID_802_3_XMIT_DEFERRED },
+ { "TransmitMaxCollisions", OID_802_3_XMIT_MAX_COLLISIONS },
+ { "ReceiveOverrun", OID_802_3_RCV_OVERRUN },
+ { "TransmitUnderrun", OID_802_3_XMIT_UNDERRUN },
+ { "TransmitHeartbeatFailure", OID_802_3_XMIT_HEARTBEAT_FAILURE },
+ { "TransmitTimesCRSLost", OID_802_3_XMIT_TIMES_CRS_LOST },
+ { "TransmitLateCollisions", OID_802_3_XMIT_LATE_COLLISIONS },
+
+ //
+ // 802.5 Objects
+ //
+
+ { "TRPermanentAddress", OID_802_5_PERMANENT_ADDRESS },
+ { "TRCurrentAddress", OID_802_5_CURRENT_ADDRESS },
+ { "CurrentFunctionalAddress", OID_802_5_CURRENT_FUNCTIONAL },
+ { "CurrentGroupAddress", OID_802_5_CURRENT_GROUP },
+ { "LastOpenStatus", OID_802_5_LAST_OPEN_STATUS },
+ { "CurrentRingStatus", OID_802_5_CURRENT_RING_STATUS },
+ { "CurrentRingState", OID_802_5_CURRENT_RING_STATE },
+
+ { "LineErrors", OID_802_5_LINE_ERRORS },
+ { "LostFrames", OID_802_5_LOST_FRAMES },
+
+ { "BurstErrors", OID_802_5_BURST_ERRORS },
+ { "ACErrors", OID_802_5_AC_ERRORS },
+ { "AbortDelimeters", OID_802_5_ABORT_DELIMETERS },
+ { "FrameCopiedErrors", OID_802_5_FRAME_COPIED_ERRORS },
+ { "FrequencyErrors", OID_802_5_FREQUENCY_ERRORS },
+ { "TokenErrors", OID_802_5_TOKEN_ERRORS },
+ { "InternalErrors", OID_802_5_INTERNAL_ERRORS },
+
+ //
+ // Fddi objects
+ //
+
+ { "FddiLongPermanentAddress", OID_FDDI_LONG_PERMANENT_ADDR },
+ { "FddiLongCurrentAddress", OID_FDDI_LONG_CURRENT_ADDR },
+ { "FddiLongMulticastList", OID_FDDI_LONG_MULTICAST_LIST },
+ { "FddiLongMaxListSize", OID_FDDI_LONG_MAX_LIST_SIZE },
+ { "FddiShortPermanentAddress", OID_FDDI_SHORT_PERMANENT_ADDR },
+ { "FddiShortCurrentAddress", OID_FDDI_SHORT_CURRENT_ADDR },
+ { "FddiShortMulticastList", OID_FDDI_SHORT_MULTICAST_LIST },
+ { "FddiShortMaxListSize", OID_FDDI_SHORT_MAX_LIST_SIZE },
+
+ //
+ // STARTCHANGE
+ //
+ // ARCNET objects
+ //
+ { "ArcPermanentAddress", OID_ARCNET_PERMANENT_ADDRESS },
+ { "ArcCurrentAddress", OID_ARCNET_CURRENT_ADDRESS },
+ { "ArcReconfigurations", OID_ARCNET_RECONFIGURATIONS },
+ //
+ // STOPCHANGE
+ //
+
+ //
+ // Async Objects
+ //
+
+#if 0
+
+// Not currently supported.
+
+ { "AsyncPermanentAddress", OID_ASYNC_PERMANENT_ADDRESS },
+ { "AsyncCurrentAddress", OID_ASYNC_CURRENT_ADDRESS },
+ { "AsyncQualityOfService", OID_ASYNC_QUALITY_OF_SERVICE },
+ { "AsyncProtocolType", OID_ASYNC_PROTOCOL_TYPE },
+
+#endif
+
+ //
+ // LocalTalk Objects
+ //
+
+#if 0
+
+// Not currently supported.
+
+ { "LTalkCurrentNodeId", OID_LTALK_CURRENT_NODE_ID },
+
+ { "LTalkInBroadcasts", OID_LTALK_IN_BROADCASTS },
+ { "LTalkInLengthErrors", OID_LTALK_IN_LENGTH_ERRORS },
+
+ { "LTalkOutNoHandlers", OID_LTALK_OUT_NO_HANDLERS },
+ { "LTalkCollisions", OID_LTALK_COLLISIONS },
+ { "LTalkDefers", OID_LTALK_DEFERS },
+ { "LTalkNoDataErrors", OID_LTALK_NO_DATA_ERRORS },
+ { "LTalkRandomCTSErrors", OID_LTALK_RANDOM_CTS_ERRORS },
+ { "LTalkFCSErrors", OID_LTALK_FCS_ERRORS }
+
+#endif
+
+};
+
+
+PARSETABLE
+SetInfoOidTable [] = {
+ NamedField( OID_GEN_CURRENT_PACKET_FILTER ),
+ NamedField( OID_GEN_CURRENT_LOOKAHEAD ),
+ NamedField( OID_802_3_MULTICAST_LIST ),
+ NamedField( OID_802_5_CURRENT_FUNCTIONAL ),
+ NamedField( OID_802_5_CURRENT_GROUP ),
+ NamedField( OID_FDDI_LONG_CURRENT_ADDR ),
+ NamedField( OID_FDDI_LONG_MULTICAST_LIST ),
+ NamedField( OID_FDDI_SHORT_CURRENT_ADDR ),
+ NamedField( OID_FDDI_SHORT_MULTICAST_LIST ),
+
+ //
+ // STARTCHANGE
+ //
+ NamedField( OID_ARCNET_CURRENT_ADDRESS ),
+ //
+ // STOPCHANGE
+ //
+
+ { "CurrentPacketFilter", OID_GEN_CURRENT_PACKET_FILTER },
+ { "CurrentLookAhead", OID_GEN_CURRENT_LOOKAHEAD },
+ { "CurrentMulticastList", OID_802_3_MULTICAST_LIST },
+ { "CurrentFunctionalAddress", OID_802_5_CURRENT_FUNCTIONAL },
+ { "CurrentGroupAddress", OID_802_5_CURRENT_GROUP },
+ { "FddiLongCurrentAddress", OID_FDDI_LONG_CURRENT_ADDR },
+ { "FddiLongMulticastList", OID_FDDI_LONG_MULTICAST_LIST },
+ { "FddiShortCurrentAddress", OID_FDDI_SHORT_CURRENT_ADDR },
+ { "FddiShortMulticastList", OID_FDDI_SHORT_MULTICAST_LIST },
+
+ //
+ // STARTCHANGE
+ //
+ { "ArcCurrentAddress", OID_ARCNET_CURRENT_ADDRESS }
+ //
+ // STOPCHANGE
+ //
+
+
+};
+
+
+PARSETABLE
+MemberTypeTable [] = {
+ NamedField( TP_CLIENT ),
+ NamedField( TP_SERVER ),
+ NamedField( BOTH ),
+
+ { "Client", TP_CLIENT },
+ { "Server", TP_SERVER },
+ { "Both", BOTH }
+};
+
+
+PARSETABLE
+PacketTypeTable [] = {
+ NamedField( FIXEDSIZE ),
+ NamedField( RANDOMSIZE ),
+ NamedField( CYCLICAL ),
+
+ { "Fixed", FIXEDSIZE },
+ { "Random", RANDOMSIZE },
+ { "Cyclic", CYCLICAL }
+};
+
+
+PARSETABLE
+PacketMakeUpTable [] = {
+ NamedField( RAND ),
+ NamedField( SMALL ),
+ NamedField( ZEROS ),
+ NamedField( ONES ),
+ NamedField( KNOWN ),
+
+ { "Random_MakeUp", RAND },
+ { "Small_MakeUp", SMALL },
+ { "Zeros_MakeUp", ZEROS },
+ { "Ones_MakeUp", ONES },
+ { "Known_MakeUp", KNOWN }
+};
+
+
+PARSETABLE
+ResponseTypeTable [] = {
+ NamedField( NO_RESPONSE ),
+ NamedField( FULL_RESPONSE ),
+ NamedField( ACK_EVERY ),
+ NamedField( ACK_10_TIMES ),
+
+ { "No Response", NO_RESPONSE },
+ { "Response", FULL_RESPONSE },
+ { "ACK", ACK_EVERY },
+ { "ACK10", ACK_10_TIMES }
+};
+
+
+PARSETABLE
+DelayTable [] = {
+ NamedField( FIXEDDELAY ),
+ NamedField( RANDOMDELAY ),
+
+ { "Fixed", FIXEDDELAY },
+ { "Random", RANDOMDELAY }
+};
+
+
+PARSETABLE
+OperationTypeTable[] = {
+ NamedField( ADD_KEY ),
+ NamedField( DELETE_KEY ),
+ NamedField( QUERY_KEY ),
+ NamedField( ADD_VALUE ),
+ NamedField( CHANGE_VALUE ),
+ NamedField( DELETE_VALUE ),
+ NamedField( QUERY_VALUE ),
+
+ { "Add Key" , ADD_KEY },
+ { "Delete Key" , DELETE_KEY },
+ { "Query Key" , QUERY_KEY },
+ { "Add Value" , ADD_VALUE },
+ { "Change Value" , CHANGE_VALUE },
+ { "Delete Value" , DELETE_VALUE },
+ { "Query Value" , QUERY_VALUE }
+};
+
+
+PARSETABLE
+KeyDbaseTable [] = {
+ NamedField( CLASSES_ROOT ),
+ NamedField( CURRENT_USER ),
+ NamedField( LOCAL_MACHINE ),
+ NamedField( USERS ),
+
+ { "HKEY_CLASSES_ROOT" , CLASSES_ROOT },
+ { "HKEY_CURRENT_USER" , CURRENT_USER },
+ { "HKEY_LOCAL_MACHINE", LOCAL_MACHINE },
+ { "HKEY_USERS" , USERS }
+};
+
+
+PARSETABLE
+ValueTypeTable[] = {
+ NamedField( BINARY ),
+ NamedField( DWORD_REGULAR ),
+ NamedField( DWORD_LITTLE_ENDIAN ),
+ NamedField( DWORD_BIG_ENDIAN ),
+ NamedField( EXPAND_SZ ),
+ NamedField( LINK ),
+ NamedField( MULTI_SZ ),
+ NamedField( NONE ),
+ NamedField( RESOURCE_LIST ),
+ NamedField( SZ ),
+
+ { "Binary", BINARY },
+ { "Double Word", DWORD_REGULAR },
+ { "Double Word Litlle Endian", DWORD_LITTLE_ENDIAN },
+ { "Double Word Big Endian", DWORD_BIG_ENDIAN },
+ { "String with unexpanded environment references", EXPAND_SZ },
+ { "Symbolic Link", LINK },
+ { "Array of strings", MULTI_SZ },
+ { "None", NONE },
+ { "Resource List", RESOURCE_LIST },
+ { "String", SZ }
+
+};
+
+//
+// The Test Parameters Structure and command parameter definitions.
+//
+// typedef struct _TestOptions {
+// DWORD OptionNumber;
+// LPSTR TestPrompt;
+// LPSTR ArgName;
+// LPSTR ArgNameAbbr;
+//
+// BOOL ArgValueSet;
+// PARAMTYPES TestType;
+// DWORD IntegerDefault;
+// LPSTR StringDefault;
+//
+// PPARSETABLE ParsedIntTable;
+// DWORD ParsedIntTableSize;
+// PVOID Destination;
+// } TESTPARAMS, *PTESTPARAMS;
+//
+//
+
+TESTPARAMS
+CommandLineOptions[] = {
+
+
+ { 1, "Options", "Options", "OP", FALSE, String,
+ 0, NULL, NULL, 0, GlobalCmdArgs.TpctlOptions },
+
+ { 2, "ScriptFile Name", "ScriptFile", "SF", FALSE, String,
+ 0, NULL, NULL, 0, GlobalCmdArgs.ARGS.FILES.ScriptFile },
+
+ { 3, "LogFile Name", "LogFile", "LF", FALSE, String, 0,
+ NULL, NULL, 0, GlobalCmdArgs.ARGS.FILES.LogFile }
+};
+
+
+DWORD
+Num_CommandLine_Params = sizeoftable( CommandLineOptions );
+
+
+TESTPARAMS
+SetEnvOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Window Size", "WindowSize", "WS", FALSE, Integer, WINDOW_SIZE,
+ NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.WindowSize },
+
+ { 3, "Random Buffer", "RandomBuffer", "RB", FALSE, Integer, BUFFER_NUMBER,
+ NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.RandomBufferNumber },
+
+ { 4, "Stress Address", "StressAddress" , "SA", FALSE, Address6, 0,
+ STRESS_MULTICAST, NULL, 0, GlobalCmdArgs.ARGS.ENV.StressAddress },
+
+ { 5, "Resend Address", "ResendAddress" , "RA", FALSE, Address6, 0,
+ NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.ENV.ResendAddress },
+
+ { 6, "Stress Delay", "StressDelay", "SD", FALSE, Integer,
+ STANDARD_DELAY, NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.StandardDelay },
+
+ { 7, "Up-For-Air Delay", "UpForAirDelay", "UD", FALSE, Integer,
+ UP_FOR_AIR_DELAY, NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.UpForAirDelay },
+
+ { 8, "Delay Interval", "DelayInterval", "I", FALSE, Integer, DELAY_INTERVAL,
+ NULL, NULL, 0, &GlobalCmdArgs.ARGS.ENV.StressDelayInterval }
+};
+
+
+DWORD
+Num_SetEnv_Params = sizeoftable( SetEnvOptions );
+
+
+TESTPARAMS ReadScriptOptions[] = {
+
+ { 1, "ScriptFile Name", "ScriptFile", "SF", FALSE, String, 0,
+ NULL, NULL, 0, GlobalCmdArgs.ARGS.FILES.ScriptFile },
+
+ { 2, "LogFile Name", "LogFile", "LF", FALSE, String, 0, NULL,
+ NULL, 0, GlobalCmdArgs.ARGS.FILES.LogFile }
+};
+
+
+DWORD
+Num_ReadScript_Params = sizeoftable( ReadScriptOptions );
+
+
+TESTPARAMS
+LoggingOptions[] = {
+
+ { 1, "LogFile Name", "LogFile", "LF", FALSE, String, 0,
+ TPCTL_CMDLINE_LOG, NULL, 0, GlobalCmdArgs.ARGS.FILES.LogFile }
+};
+
+
+DWORD
+Num_Logging_Params = sizeoftable( LoggingOptions );
+
+
+TESTPARAMS
+RecordingOptions[] = {
+
+ { 1, "ScriptFile Name", "ScriptFile", "SF", FALSE, String, 0,
+ TPCTL_CMDLINE_SCRIPT, NULL, 0, GlobalCmdArgs.ARGS.RECORD.ScriptFile }
+};
+
+
+DWORD
+Num_Recording_Params = sizeoftable( RecordingOptions );
+
+
+TESTPARAMS
+PauseGoOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Remote Address", "RemoteAddress" , "RA", FALSE, Address6, 0,
+ NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.PAUSE_GO.RemoteAddress },
+
+ { 3, "Test Signature", "TestSignature", "TS", FALSE, Integer,
+ 0, NULL, NULL, 0, &GlobalCmdArgs.ARGS.PAUSE_GO.TestSignature },
+
+ { 4, "Unique Signature", "UniqueSig", "UI", FALSE, Integer, 0, NULL,
+ NULL, 0, &GlobalCmdArgs.ARGS.PAUSE_GO.UniqueSignature },
+};
+
+
+DWORD
+Num_PauseGo_Params = sizeoftable( PauseGoOptions );
+
+
+TESTPARAMS
+LoadUnloadOptions[] = {
+
+ { 1, "Driver Name", "DriverName", "DN", FALSE, String, 0,
+ NULL, NULL, 0, GlobalCmdArgs.ARGS.DriverName }
+};
+
+
+DWORD
+Num_LoadUnload_Params = sizeoftable( LoadUnloadOptions );
+
+
+TESTPARAMS
+OpenOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Adapter Name", "AdapterName", "AN", FALSE, String, 0,
+ NULL, NULL, 0, GlobalCmdArgs.ARGS.OPEN_ADAPTER.AdapterName }
+};
+
+
+DWORD
+Num_Open_Params = sizeoftable( OpenOptions );
+
+
+TESTPARAMS
+SetPacketFilterOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Packet Filter", "PacketFilter", "PF", FALSE, ParsedInteger,
+ 0, "DIRECTED", PacketFilterTable, sizeoftable( PacketFilterTable ),
+ &GlobalCmdArgs.ARGS.TPSET.U.PacketFilter }
+};
+
+
+DWORD
+Num_SetPacketFilter_Params = sizeoftable( SetPacketFilterOptions );
+
+
+TESTPARAMS
+SetLookaheadOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Lookahead Buffer Size", "Lookahead", "LA", FALSE,
+ Integer, LOOKAHEADSIZE, NULL, NULL, 0,
+ &GlobalCmdArgs.ARGS.TPSET.U.LookaheadSize }
+};
+
+
+DWORD
+Num_SetLookahead_Params = sizeoftable( SetLookaheadOptions );
+
+
+TESTPARAMS
+MulticastAddrOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Multicast Address", "MulticastAddress", "MA",
+ FALSE, Address6, 0, DEFAULT_MULTICAST, NULL, 0,
+ GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0] }
+};
+
+
+DWORD
+Num_MulticastAddr_Params = sizeoftable( MulticastAddrOptions );
+
+
+TESTPARAMS
+FunctionalAddrOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Functional Address", "FunctionalAddress", "FA",
+ FALSE, Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0,
+ GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress }
+};
+
+
+DWORD
+Num_FunctionalAddr_Params = sizeoftable( FunctionalAddrOptions );
+
+
+TESTPARAMS
+GroupAddrOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Group Address", "GroupAddress", "GA",
+ FALSE, Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0,
+ GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress }
+};
+
+
+DWORD
+Num_GroupAddr_Params = sizeoftable( GroupAddrOptions );
+
+
+TESTPARAMS
+QueryInfoOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "OID Request", "ObjectIdentifier", "OID", FALSE, ParsedInteger,
+ 0x00010101, "SupportedOidList", QueryInfoOidTable,
+ sizeoftable( QueryInfoOidTable ), &GlobalCmdArgs.ARGS.TPQUERY.OID },
+};
+
+
+DWORD
+Num_QueryInfo_Params = sizeoftable( QueryInfoOptions );
+
+
+TESTPARAMS
+QueryStatsOptions[] = {
+
+
+ { 1, "Device Name", "DeviceName", "DN", FALSE, String, 0, NULL,
+ NULL, 0, GlobalCmdArgs.ARGS.TPQUERYSTATS.DeviceName },
+
+ { 2, "OID Request", "ObjectIdentifier", "OID", FALSE, ParsedInteger,
+ 0x00010101, "SupportedOidList", QueryInfoOidTable,
+ sizeoftable( QueryInfoOidTable ), &GlobalCmdArgs.ARGS.TPQUERYSTATS.OID },
+};
+
+
+DWORD
+Num_QueryStats_Params = sizeoftable( QueryStatsOptions );
+
+
+TESTPARAMS
+SetInfoOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "OID Request", "ObjectIdentifier", "OID", FALSE, ParsedInteger,
+ 0x0001010e, "CurrentPacketFilter", SetInfoOidTable,
+ sizeoftable( SetInfoOidTable ), &GlobalCmdArgs.ARGS.TPSET.OID }
+};
+
+
+DWORD
+Num_SetInfo_Params = sizeoftable( SetInfoOptions );
+
+
+TESTPARAMS
+SetInfoPFOptions[] = {
+
+ { 1, "Packet Filter", "PacketFilter", "PF", FALSE, ParsedInteger,
+ 0, "DIRECTED", PacketFilterTable, sizeoftable( PacketFilterTable ),
+ &GlobalCmdArgs.ARGS.TPSET.U.PacketFilter }
+};
+
+
+DWORD
+Num_SetInfoPF_Params = sizeoftable( SetInfoPFOptions );
+
+
+TESTPARAMS
+SetInfoLAOptions[] = {
+
+ { 1, "Lookahead Buffer Size", "Lookahead", "LA",
+ FALSE, Integer, LOOKAHEADSIZE, NULL, NULL, 0,
+ &GlobalCmdArgs.ARGS.TPSET.U.LookaheadSize }
+};
+
+
+DWORD
+Num_SetInfoLA_Params = sizeoftable( SetInfoLAOptions );
+
+
+TESTPARAMS
+SetInfoMAOptions[] = {
+
+ { 1, "Multicast Address", "MulticastAddress", "MA",
+ FALSE, Address6, 0, DEFAULT_MULTICAST, NULL, 0,
+ GlobalCmdArgs.ARGS.TPSET.U.MulticastAddress[0] }
+};
+
+
+DWORD
+Num_SetInfoMA_Params = sizeoftable( SetInfoMAOptions );
+
+TESTPARAMS
+SetInfoFAOptions[] = {
+
+ { 1, "Functional Address", "FunctionalAddress", "FA",
+ FALSE, Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0,
+ GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress }
+};
+
+
+DWORD
+Num_SetInfoFA_Params = sizeoftable( SetInfoFAOptions );
+
+
+TESTPARAMS
+SetInfoGAOptions[] = {
+
+ { 1, "Group Address", "GroupAddress", "GA", FALSE,
+ Address4, 0, &DEFAULT_FUNCTIONAL[2], NULL, 0,
+ GlobalCmdArgs.ARGS.TPSET.U.FunctionalAddress }
+};
+
+
+DWORD
+Num_SetInfoGA_Params = sizeoftable( SetInfoGAOptions );
+
+
+TESTPARAMS
+SendOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Destination Address", "DestinationAddress", "DA", FALSE, Address6,
+ 0, NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPSEND.DestAddress },
+
+ { 3, "Packet Size", "PacketSize", "PS", FALSE, Integer, PACKET_SIZE,
+ NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSEND.PacketSize },
+
+ { 4, "Number to Send", "Number", "N", FALSE, Integer, 1, NULL, NULL,
+ 0, &GlobalCmdArgs.ARGS.TPSEND.NumberOfPackets },
+
+ { 5, "Resend Address", "ResendAddress", "RA", FALSE, Address6, 0,
+ NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPSEND.ResendAddress }
+
+ //
+ // Both Resend and Dest address will default to the local address
+ // which must be queried and then stored in the application somewhere?
+ //
+};
+
+
+DWORD
+Num_Send_Params = sizeoftable( SendOptions );
+
+
+TESTPARAMS
+PerfClntOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Server Address", "ServerAddress", "SVA", FALSE, Address6,
+ 0, NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPPERF.PerfServerAddr },
+
+ { 3, "Send Address", "SendAddress", "SA", FALSE, Address6,
+ 0, NULL_ADDRESS, NULL, 0, GlobalCmdArgs.ARGS.TPPERF.PerfSendAddr },
+
+ { 4, "Packet Size", "PacketSize", "PS", FALSE, Integer, PACKET_SIZE,
+ NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPPERF.PerfPacketSize },
+
+ { 5, "Number to Send", "Number", "N", FALSE, Integer, 100000, NULL, NULL,
+ 0, &GlobalCmdArgs.ARGS.TPPERF.PerfNumPackets },
+
+ { 6, "Delay", "Delay", "D", FALSE, Integer, 0, NULL, NULL,
+ 0, &GlobalCmdArgs.ARGS.TPPERF.PerfDelay },
+
+ { 7, "Mode", "Mode", "M", FALSE, Integer, 0, NULL, NULL,
+ 0, &GlobalCmdArgs.ARGS.TPPERF.PerfMode }
+};
+
+
+DWORD
+Num_PerfClnt_Params = sizeoftable( PerfClntOptions );
+
+
+TESTPARAMS
+StressOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance },
+
+ { 2, "Stress Member Type", "MemberType", "MT", FALSE, ParsedInteger,
+ 0, "TP_CLIENT", MemberTypeTable, sizeoftable( MemberTypeTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.MemberType },
+
+ { 3, "Total Number of Packets", "Packets", "P", FALSE, Integer,
+ (DWORD)STRESS_PACKETS, NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSTRESS.TotalPackets },
+
+ { 4, "Total Number of Iterations", "Iterations", "I", FALSE, Integer,
+ (DWORD)STRESS_ITERATIONS, NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSTRESS.TotalIterations },
+
+ { 5, "Packet Type", "PacketType", "PT", FALSE, ParsedInteger, 0,
+ "FIXEDSIZE", PacketTypeTable, sizeoftable( PacketTypeTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.PacketType },
+
+ { 6, "Packet Size", "PacketSize", "PS", FALSE, Integer, PACKET_SIZE,
+ NULL, NULL, 0, &GlobalCmdArgs.ARGS.TPSTRESS.PacketSize },
+
+ { 7, "Packet MakeUp", "PacketMakeUp", "PM", FALSE, ParsedInteger,
+ 0, "RAND", PacketMakeUpTable, sizeoftable( PacketMakeUpTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.PacketMakeUp },
+
+ { 8, "Response Type", "ResponseType", "RT", FALSE, ParsedInteger, 0,
+ "FULL_RESPONSE", ResponseTypeTable, sizeoftable( ResponseTypeTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.ResponseType },
+
+ { 9, "Interpacket Delay Type", "DelayType", "DT", FALSE,
+ ParsedInteger, 0, "FIXEDDELAY", DelayTable, sizeoftable( DelayTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.DelayType },
+
+ { 10, "Interpacket Delay Length", "DelayLength", "DL", FALSE, Integer,
+ 0, NULL, NULL, DELAY_LENGTH, &GlobalCmdArgs.ARGS.TPSTRESS.DelayLength },
+
+ { 11, "Windowing Enabled","WindowEnabled","WE", FALSE, ParsedInteger, 0,
+ WINDOWING_ENABLED, BooleanTable, sizeoftable( BooleanTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.WindowEnabled },
+
+ { 12, "Data Checking Enabled", "DataChecking", "DC", FALSE, ParsedInteger,
+ 0, DATA_CHECKING, BooleanTable, sizeoftable( BooleanTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.DataChecking },
+
+ { 13, "Packets from Pool", "PacketPool", "PP", FALSE, ParsedInteger,
+ 0, PACKETS_FROM_POOL, BooleanTable, sizeoftable( BooleanTable ),
+ &GlobalCmdArgs.ARGS.TPSTRESS.PacketsFromPool }
+};
+
+
+DWORD
+Num_Stress_Params = sizeoftable( StressOptions );
+
+
+TESTPARAMS
+OpenInstanceOptions[] = {
+
+ { 1, "Open Instance", "OpenInstance", "OI", FALSE, Integer,
+ OPEN_INSTANCE, NULL, NULL, 0, &GlobalCmdArgs.OpenInstance }
+};
+
+
+DWORD
+Num_OpenInstance_Params = sizeoftable( OpenInstanceOptions );
+
+
+TESTPARAMS
+HelpOptions[] = {
+
+ { 1, "Command Name", "CommandName", "CN", FALSE, String, 0,
+ NULL, NULL, 0, GlobalCmdArgs.ARGS.CmdName }
+};
+
+
+DWORD
+Num_Help_Params = sizeoftable( HelpOptions );
+
+
+TESTPARAMS
+RegistryOptions[] = {
+
+ { 1, "Operation Type", "Operation", "OP", FALSE, ParsedInteger, 0,
+ "QUERY_KEY", OperationTypeTable, sizeoftable( OperationTypeTable ),
+ &GlobalCmdArgs.ARGS.REGISTRY_ENTRY.OperationType },
+
+ { 2, "Key Database", "KeyDatabase", "KD", FALSE, ParsedInteger, 0,
+ "LOCAL_MACHINE", KeyDbaseTable, sizeoftable( KeyDbaseTable ),
+ &GlobalCmdArgs.ARGS.REGISTRY_ENTRY.KeyDatabase },
+
+ { 3, "Sub Key Name", "SubKey", "SK", FALSE, String, 0,
+ "\"System\\CurrentControlSet\\Services\\Sonic01\\Parameters\"", NULL, 0,
+ GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKey },
+
+ {4, "Sub Key Class", "SubKeyClass", "SC", FALSE, String, 0,
+ "\"Network Drivers\"", NULL, 0,
+ GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyClass },
+
+ {5, "Sub Key Value Name", "SubKeyValueName", "SN", FALSE, String, 0,
+ "\"NetworkAddress\"", NULL, 0,
+ GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyValueName },
+
+ {6, "Sub Key Value Type", "SubKeyValueType", "ST", FALSE, ParsedInteger, 0,
+ "DWORD_REGULAR", ValueTypeTable, sizeoftable( ValueTypeTable ),
+ &GlobalCmdArgs.ARGS.REGISTRY_ENTRY.ValueType },
+
+ {7, "Sub Key Value", "SubKeyValue", "SV", FALSE, String, 0,
+ "\0", NULL, 0,
+ GlobalCmdArgs.ARGS.REGISTRY_ENTRY.SubKeyValue }
+
+};
+
+
+DWORD
+Num_Registry_Params = sizeoftable( RegistryOptions );
+
+
+
+
+
+DWORD
+TpctlParseArguments (
+ IN TESTPARAMS Options[],
+ IN DWORD TestSize,
+ IN DWORD ArgC,
+ IN LPSTR ArgV[]
+ )
+
+// ---------------------
+//
+// Routine Description:
+//
+// This routine parses a table
+//
+// Arguments:
+//
+// IN PARSE_PARAMS Option, - [Supplies | Returns] description-of-argument
+// IN DWORD ArgC, - [Supplies | Returns] description-of-argument
+// IN LPSTR ArgV[] - [Supplies | Returns] description-of-argument
+//
+// Return Value:
+//
+// DWORD = -1 if there was a parse error.
+// = The number of parameters "eaten" otherwise.
+//
+// --------------------
+
+{
+ DWORD i, j;
+ BYTE Buffer[TPCTL_CMDLINE_SIZE];
+ LPSTR ArgName, ArgValue;
+ BYTE ArgPrompt[TPCTL_CMDLINE_SIZE];
+ LPBYTE NextToken;
+ DWORD RetVal;
+ BOOL Reparse;
+ BOOL Error;
+ BOOL ParsedArgumentsYet;
+ BOOL ArgNameValuePair;
+ DWORD OptionNumber;
+ DWORD OpenInstance;
+ LPBYTE p, q;
+
+ //
+ // First determine the Open Instance, we may need it later.
+ //
+
+ OpenInstance = TpctlGetOpenInstance( ArgC,ArgV );
+
+ //
+ // Lower the argument count thus ignoring the command itself,
+ // we don't care about that here.
+ //
+
+ if ( ArgC )
+ {
+ ArgC -= 1; // Don't count command in args.
+ }
+
+ RetVal = min( ArgC, TestSize );
+
+ if ( ArgC > TestSize )
+ {
+ ArgC = TestSize;
+ }
+
+ //
+ // Load the defaults for each of the arguments into the Destination
+ // field.
+ //
+
+ for ( i=0;i<TestSize;i++ )
+ {
+ Options[i].ArgValueSet = FALSE;
+
+ switch ( Options[i].TestType )
+ {
+ case Integer:
+ *(PDWORD)Options[i].Destination = Options[i].IntegerDefault;
+ break;
+
+ case String:
+ if ( Options[i].StringDefault != NULL )
+ {
+ strcpy( (LPSTR)Options[i].Destination, Options[i].StringDefault );
+ }
+ else
+ {
+ ((LPSTR)Options[i].Destination)[0] = '\0';
+ }
+ break;
+
+ case Address4:
+ p = Options[i].Destination;
+ q = Options[i].StringDefault;
+
+ for ( j=0;j<FUNCTIONAL_ADDRESS_LENGTH;j++ )
+ {
+ *p++ = *q++;
+ }
+ break;
+
+ case Address6:
+ p = Options[i].Destination;
+ q = Options[i].StringDefault;
+
+ for ( j=0;j<ADDRESS_LENGTH;j++ )
+ {
+ *p++ = *q++;
+ }
+ break;
+
+
+ case ParsedInteger:
+ TpctlParseInteger( Options[i].StringDefault,
+ Options[i].ParsedIntTable,
+ Options[i].ParsedIntTableSize,
+ Options[i].Destination);
+
+ break;
+
+ default:
+ TpctlErrorLog("\nTpctl: ParseArguments: Invalid TestType\n",NULL);
+ return (DWORD)-1;
+ }
+ }
+
+ //
+ // Now parse the input command line, and determine if any arguments
+ // exist on the command line. The command line may be made up in one
+ // of the following ways:
+ //
+ // 1) nothing, prompt the user for all of the arguments to the given
+ // command.
+ //
+ // 2) argument name=value pairs, parse each pair and set up the options
+ // structure. if the line ends with a semicolon ';' then return the
+ // options structure to the caller, otherwise prompt the user for the
+ // remainder of the commands for the given command then return.
+ //
+ // 3) arguments values only, parse each value and place in the options
+ // structure. if the line ends with a semicolon ';' then return the
+ // options structure to the caller, otherwise prompt the user for the
+ // remainder of the commands for the given command then return.
+ //
+ // NOTE: a command line may not contain name=value pairs, and values, it
+ // may only contain one type or the other.
+ //
+
+ ArgNameValuePair = FALSE;
+ ParsedArgumentsYet = FALSE;
+
+ for( i=1;i<=ArgC;i++ )
+ {
+ if ( ArgV[i][0] == ';' )
+ {
+ return RetVal;
+ }
+
+ if ( TpctlParseArgumentPairs( ArgV[i],&ArgName,&ArgValue ))
+ {
+ if ( ParsedArgumentsYet == FALSE )
+ {
+ //
+ // We have an argument name/value pair, and this is the
+ // first argument in the command line, all the rest of the
+ // arguments MUST have an arguments name-value pairing, set
+ // the flags appropriately, and continue.
+ //
+
+ ArgNameValuePair = TRUE;
+ ParsedArgumentsYet = TRUE;
+
+ }
+ else if ( ArgNameValuePair == FALSE )
+ {
+
+ //
+ // The first argument was an argument value only, and now
+ // we have an argument name=value pair. This is an illegal
+ // entry on the command line, report the error, and return.
+ // if we are running a script file end it now reporting an
+ // error.
+ //
+
+ TpctlErrorLog("\n\tTpctl: ERROR - \"%s",ArgName);
+ TpctlErrorLog("=%s\"\n",ArgValue);
+ TpctlErrorLog("\n\tArgument values and argument name-value pairs\n",NULL);
+ TpctlErrorLog("\tmay not be combined in the same command.\n",NULL);
+ return (DWORD)-1;;
+ }
+
+ }
+ else // We have only a Argument Value.
+ {
+ if ( ParsedArgumentsYet == FALSE )
+ {
+
+ //
+ // This is the first arugment, set the flags appropriately,
+ // and continue.
+ //
+
+ ParsedArgumentsYet = TRUE;
+
+ }
+ else if ( ArgNameValuePair == TRUE )
+ {
+
+ //
+ // The first argument was an argument name=value pair, and
+ // now we have an argument value only. This is an illegal
+ // entry on the command line, report the error, and return.
+ // if we are running a script file end it now reporting an
+ // error.
+ //
+
+ TpctlErrorLog("\n\tTpctl: ERROR - \"%s\"\n",ArgValue);
+ TpctlErrorLog("\n\tArgument name-value pairs and argument values\n",NULL);
+ TpctlErrorLog("\tmay not be combined in the same command.\n",NULL);
+ return (DWORD)-1;;
+ }
+ }
+
+ if ( ArgNameValuePair == TRUE )
+ {
+
+ OptionNumber = TpctlGetOptionNumber( Options,TestSize,ArgName );
+
+ if ( OptionNumber == -1 )
+ {
+
+ //
+ // This is an invalid option number report the error, and return.
+ // if we are running a script file end it now reporting an error.
+ //
+
+ TpctlErrorLog("\n\tTpctl: Invalid Argument Name: \"%s\"",ArgName);
+ TpctlErrorLog("\n\tThis argument does not exist for this command\n",NULL);
+ return (DWORD)-1;;
+ }
+ }
+ else
+ {
+ OptionNumber = i;
+ }
+
+ { // ParsePtr scope.
+
+ PTESTPARAMS ParsePtr = &Options[OptionNumber-1];
+
+ Error = FALSE;
+
+ //
+ // If the argument passed in from the command line is the
+ // '*' symbol, the user wants to use the default argument for
+ // this variable, set the argument value and set flag to TRUE
+ // indicating that we do not need to prompt for it further, and
+ // continue with the next argument.
+ //
+
+ if ( ArgValue[0] == '*' )
+ {
+ ParsePtr->ArgValueSet = TRUE;
+ continue;
+ }
+
+// globvars access
+
+ if ( ArgValue[0] == '$')
+ {
+ PVOID valptr = TpctlParseGlobalVariable(ArgValue, ParsePtr->TestType);
+ LPBYTE s,d;
+ ULONG i;
+
+ if (valptr != NULL)
+ {
+ switch ( ParsePtr->TestType)
+ {
+ case Integer:
+ *(PDWORD)ParsePtr->Destination = *(PDWORD)valptr;
+ break;
+
+ case String:
+ strcpy( (LPSTR)ParsePtr->Destination, (LPSTR)valptr);
+ break;
+
+ case Address4:
+ s = (LPBYTE)valptr;
+ d = (LPBYTE)ParsePtr->Destination;
+ for (i=0; i < FUNCTIONAL_ADDRESS_LENGTH; i++)
+ {
+ *d++ = *s++;
+ }
+ break;
+
+ case Address6:
+ s = (LPBYTE)valptr;
+ d = (LPBYTE)ParsePtr->Destination;
+ for (i=0; i < ADDRESS_LENGTH; i++)
+ {
+ *d++ = *s++;
+ }
+ break;
+ }
+ }
+ continue;
+ }
+
+// end of globvars access
+
+ switch( ParsePtr->TestType )
+ {
+
+ case Integer:
+ *(PDWORD)ParsePtr->Destination = strtoul( ArgValue,&NextToken,0 );
+ break;
+
+ case String:
+ strcpy( (LPSTR)ParsePtr->Destination,ArgValue );
+ break;
+
+ case Address4:
+ if ( TpctlParseAddress( ArgValue,
+ ParsePtr->Destination,
+ OpenInstance - 1,
+ FUNCTIONAL_ADDRESS_LENGTH ) != 0 )
+ {
+ Error = TRUE;
+ }
+
+ break;
+
+ case Address6:
+ if ( TpctlParseAddress( ArgValue,
+ ParsePtr->Destination,
+ OpenInstance - 1,
+ ADDRESS_LENGTH ) != 0 )
+ {
+ Error = TRUE;
+ }
+ break;
+
+ case ParsedInteger:
+ if ( TpctlParseInteger( ArgValue,
+ ParsePtr->ParsedIntTable,
+ ParsePtr->ParsedIntTableSize,
+ ParsePtr->Destination ) != 0 )
+ {
+ Error = TRUE;
+ }
+
+ break;
+
+ default:
+ TpctlErrorLog("ParseArguments: Invalid TestType\n",NULL);
+ Error = TRUE;
+ }
+
+ if ( Error == TRUE )
+ {
+ TpctlErrorLog("\n\tTpctl: Invalid Argument Value\n",NULL);
+ return (DWORD)-1;;
+ }
+
+ //
+ // We have set this options new value from the command line, so
+ // set the flag stating not to prompt the user again if necessary.
+ //
+
+ ParsePtr->ArgValueSet = TRUE;
+
+ } // end of ParsePtr for now.
+ }
+
+ //
+ // Set Up the "ArgPrompt" to request the new value for the argument.
+ //
+
+ for ( i=1;i<=TestSize;i++ )
+ {
+
+ PTESTPARAMS ParsePtr = &Options[i-1];
+ PTESTPARAMS OIParsePtr = &Options[0];
+
+ if (ScriptIndex != -1)
+ {
+
+ //
+ // We are reading from a script file, so there is no prompting
+ // required.
+
+ break;
+ }
+
+ if ( ParsePtr->ArgValueSet != TRUE )
+ {
+
+ //
+ // If there was a command line argument, use it for the
+ // argument, otherwise prompt for the argument.
+ //
+
+ Reparse = TRUE;
+
+ strcpy( ArgPrompt, "\t" );
+ strcat( ArgPrompt, ParsePtr->TestPrompt );
+ strcat( ArgPrompt, " [" );
+
+ switch ( ParsePtr->TestType )
+ {
+ case Integer:
+ {
+ BYTE Int[20];
+ _ltoa( ParsePtr->IntegerDefault, Int , 10 );
+ strcat( ArgPrompt, Int );
+ }
+ break;
+
+ case ParsedInteger:
+ case String:
+ if ( ParsePtr->StringDefault!=NULL )
+ {
+ strcat( ArgPrompt,ParsePtr->StringDefault );
+ }
+ break;
+
+ case Address4:
+ if ( ParsePtr->StringDefault != NULL )
+ {
+ p = ArgPrompt + strlen( ArgPrompt );
+ q = ParsePtr->StringDefault;
+
+ for( j=0;j<FUNCTIONAL_ADDRESS_LENGTH;j++ )
+ {
+ p += (BYTE)sprintf(p,"%02X",*q++);
+
+ if ( j < ( FUNCTIONAL_ADDRESS_LENGTH - 1 ))
+ {
+ *p++ = '-';
+ }
+ }
+ *p = '\0';
+ }
+ break;
+
+ case Address6:
+ if ( ParsePtr->StringDefault!=NULL )
+ {
+ p = ArgPrompt + strlen( ArgPrompt );
+ q = ParsePtr->StringDefault;
+
+ for( j=0;j<ADDRESS_LENGTH;j++ )
+ {
+ p += (BYTE)sprintf(p,"%02X",*q++);
+
+ if ( j < ( ADDRESS_LENGTH - 1 ))
+ {
+ *p++ = '-';
+ }
+ }
+ *p = '\0';
+ }
+ break;
+
+ } // switch
+
+ //
+ // Now prompt the user for the new value.
+ //
+
+ strcat( ArgPrompt,"] >" );
+
+ TpctlPrompt( ArgPrompt,Buffer,TPCTL_CMDLINE_SIZE );
+
+ //
+ // and print the response to the log file if requested.
+ //
+
+ TpctlCmdLneLog( Buffer, NULL );
+ TpctlCmdLneLog( "\n", NULL );
+
+
+ while ( Reparse )
+ {
+
+ //
+ // Clean up the buffer, removing any unnecessary spaces.
+ //
+
+ TpctlFixBuffer( Buffer );
+
+ //
+ // If the user entered a ';' meaning all desired values
+ // have been entered, use the defaults for the rest.
+ //
+
+ if ( TpctlFirstChar( Buffer,';' ))
+ {
+ i = TestSize;
+ break;
+ }
+
+ //
+ // If the user simply hit enter meaning that we should
+ // use the default value for this argument, then do so.
+ //
+
+ if ( TpctlFirstChar( Buffer,'\0' ))
+ {
+ break;
+ }
+
+ //
+ // If the argument starts with '%' then it is an Environment
+ // variable, and we need to find out its actual value and
+ // replace it.
+ //
+
+ if ( Buffer[0] == '%' )
+ {
+ if ( !TpctlParseEnvironmentVariable( Buffer ))
+ {
+ return (DWORD)-1;;
+ }
+ }
+
+ //
+ // Now put the newly entered value in its destination.
+ //
+
+
+ Error = FALSE;
+
+ switch ( ParsePtr->TestType )
+ {
+ case Integer:
+ *(PDWORD)ParsePtr->Destination =
+ strtol( Buffer,&NextToken,0 );
+ Reparse = FALSE;
+ break;
+
+ case String:
+ strcpy( (LPSTR)ParsePtr->Destination,Buffer );
+ Reparse = FALSE;
+ break;
+
+ case Address4:
+ if ( OpenInstance == -1 )
+ {
+ OpenInstance = *(PDWORD)OIParsePtr->Destination;
+ }
+
+ if ( TpctlParseAddress( Buffer,
+ ParsePtr->Destination,
+ OpenInstance - 1,
+ FUNCTIONAL_ADDRESS_LENGTH) != 0)
+ {
+ Error = TRUE;
+ }
+ Reparse = FALSE;
+ break;
+
+ case Address6:
+ if ( OpenInstance == -1 )
+ {
+ OpenInstance = *(PDWORD)OIParsePtr->Destination;
+ }
+
+ if ( TpctlParseAddress( Buffer,
+ ParsePtr->Destination,
+ OpenInstance - 1,
+ ADDRESS_LENGTH ) != 0 )
+ {
+ Error = TRUE;
+ }
+ Reparse = FALSE;
+ break;
+
+ case ParsedInteger:
+ if ( TpctlParseInteger( Buffer,
+ ParsePtr->ParsedIntTable,
+ ParsePtr->ParsedIntTableSize,
+ ParsePtr->Destination ) != 0 )
+ {
+ Error = TRUE;
+ }
+ Reparse = FALSE;
+ break;
+ }
+
+ if ( Error )
+ {
+
+ //
+ // A bad value was entered for the last variable, see if
+ // the user would like to enter a new value.
+ //
+
+ TpctlPrompt("\tTpctl: Argument Error, Re-enter? [Y]",
+ Buffer, TPCTL_CMDLINE_SIZE);
+
+ //
+ // and print the response to the log file if requested.
+ //
+
+ TpctlCmdLneLog( Buffer, NULL);
+ TpctlCmdLneLog( "\n", NULL);
+
+ if ((( Buffer[0] == '\0' ) ||
+ ( Buffer[0] == 'Y' )) ||
+ ( Buffer[0] == 'y' ))
+ {
+
+ //
+ // if so, reprompt the user for a new value.
+ //
+
+ TpctlPrompt( ArgPrompt,Buffer,TPCTL_CMDLINE_SIZE );
+
+ //
+ // and print the response to the log file if requested.
+ //
+
+ TpctlCmdLneLog( Buffer, NULL);
+ TpctlCmdLneLog( "\n", NULL);
+ Reparse = TRUE;
+
+ }
+ else
+ {
+
+ //
+ // Otherwise return an error.
+ //
+
+ return (DWORD)-1;;
+ }
+ }
+ }
+ }
+ }
+
+ return RetVal;
+}
+
+
+VOID
+TpctlFixBuffer(
+ IN BYTE Buffer[]
+ )
+
+// ---------------------
+//
+// Routine Description:
+//
+// Arguments:
+//
+// Return Value:
+//
+// -------------------
+
+{
+ LPSTR Token = Buffer;
+ LPSTR NextToken = Buffer; // Anything that isn't NULL.
+
+ if ( Buffer == NULL )
+ {
+ return;
+ }
+
+ while (( *Token != '\0' ) && ( *Token <= ' ' ))
+ {
+ Token++; // ignore leading blanks
+ }
+
+ NextToken = strchr( Token,' ' ); // now see if there are any spaces.
+
+ if ( NextToken != NULL ) // and if so, null them out.
+ {
+ *NextToken++ = '\0';
+ }
+}
+
+
+DWORD
+TpctlParseInteger (
+ IN BYTE Buffer[],
+ IN PPARSETABLE ParseTable,
+ IN DWORD ParseTableSize,
+ OUT PDWORD Ret
+ )
+
+// ---------------------
+//
+// Routine Description:
+//
+// This routine parses a "parsed integer" and returns it to the caller.
+//
+// Arguments:
+//
+// IN BYTE Buffer[], - [Supplies | Returns] description-of-argument
+// IN PPARSETABLE ParseTable, - [Supplies | Returns] description-of-argument
+// IN DWORD ParseTableSize - [Supplies | Returns] description-of-argument
+// OUT PDWORD Ret
+//
+// Return Value:
+//
+// DWORD
+//
+// --------------------
+
+{
+ LPSTR Token = Buffer;
+ LPSTR NextToken = Buffer; // Anything that isn't NULL.
+ LPBYTE savePointer = NULL;
+ BYTE saveToken;
+ DWORD i;
+
+ if ( Buffer == NULL )
+ {
+ *Ret = 0;
+ return 0;
+ }
+
+ //
+ // If the user specified an absolute number, return that.
+ //
+
+ if ( isdigit( *Token ))
+ {
+ *Ret = strtoul( Token,&NextToken,0 );
+ return 0;
+ }
+
+ //
+ // Nope, the user passed in a string, parse that.
+ //
+
+ //
+ // Initialize the initial value of the returned value to NULL.
+ //
+
+ *Ret = 0;
+
+ while ( NextToken != NULL )
+ {
+ NextToken = strchr( Token,'|' );
+
+ if ( NextToken != NULL )
+ {
+ saveToken = *NextToken;
+ savePointer = NextToken;
+ *NextToken++ = '\0';
+ }
+
+ for ( i=0;i<ParseTableSize;i++ )
+ {
+ if ( _stricmp( Token,ParseTable[i].FieldName ) == 0 )
+ {
+ *Ret |= ParseTable[i].FieldValue;
+ break;
+ }
+ }
+
+ if ( i == ParseTableSize )
+ {
+ TpctlErrorLog("\n\tTpctl: Unknown option \"%s\" entered.\n",
+ (PVOID)Token);
+ TpctlErrorLog("\n\t\tValid options are:\n\n",NULL);
+
+ for ( i=0;i<ParseTableSize;i++ )
+ {
+ TpctlErrorLog("\t\t\t%s\n", (PVOID)ParseTable[i].FieldName);
+ }
+
+ TpctlErrorLog("\n",NULL);
+ return (DWORD)-1;;
+ }
+
+ if ( savePointer != NULL )
+ {
+ *savePointer = saveToken; // Restore byte trompled on.
+ }
+
+ Token = NextToken;
+ }
+
+ return 0;
+}
+
+
+
+DWORD
+TpctlParseAddress(
+ IN BYTE Buffer[],
+ OUT PDWORD RetAddr,
+ IN DWORD OpenInstance,
+ IN DWORD AddressLength
+ )
+
+// -----------------
+//
+// Routine Description:
+//
+// This routine parses a network address and returns it to the caller.
+//
+// Arguments:
+//
+// IN BYTE Buffer[], - [Supplies | Returns] description-of-argument
+// OUT PDWORD RetAddr
+//
+// Return Value:
+//
+// DWORD
+//
+// ----------------
+
+{
+ BYTE TmpBuf[100];
+ PBYTE TmpAddr;
+ BYTE digit;
+ DWORD i, j;
+ BYTE n[2];
+ LPBYTE p;
+
+
+ if ( Buffer == NULL )
+ {
+ *RetAddr = 0;
+ return 0;
+ }
+
+ TmpAddr = (PBYTE)RetAddr;
+
+ //
+ // See if the user entered one of the text string addresses at the
+ // command line.
+ //
+
+ if ( _stricmp( Buffer,RESEND_ADDRESS ) == 0 )
+ {
+
+ //
+ // If the user has entered "resendaddress" at the command line,
+ // then we will use the resend address stored in the ResendAddress
+ // environment variable.
+ //
+
+ p = (LPBYTE)Open[OpenInstance].EnvVars->ResendAddress;
+
+ for ( i=0 ; i < AddressLength ; i++ )
+ {
+ *TmpAddr++ = *p++;
+ }
+ return 0;
+
+ }
+ else if ( _stricmp( Buffer,LOCAL_ADDRESS ) == 0 )
+ {
+
+ //
+ // If the user has entered "localaddress" at the command line
+ // then we will use the local address stored in the Open Block.
+ //
+
+ p = (LPBYTE)Open[OpenInstance].AdapterAddress;
+
+ for ( i=0 ; i < AddressLength ; i++ )
+ {
+ *TmpAddr++ = *p++;
+ }
+ return 0;
+ }
+
+ i = j = 0;
+
+ //
+ // Remove any spaces or hyphens from the address.
+ //
+
+ while ( i < ( AddressLength * 2 ))
+ {
+ if (( Buffer[j] != ' ' ) && ( Buffer[j] != '-' ))
+ {
+ TmpBuf[i++] = Buffer[j];
+ }
+
+ //
+ // If we run of the end of the buffer return with an error.
+ //
+
+ if ( ++j==100 )
+ {
+ return (DWORD)-1;;
+ }
+ }
+
+ //
+ // Now parse the "packed" address and turn the characters into numbers.
+ //
+
+ for( i=0 ; i < AddressLength ; i++ )
+ {
+ digit = '\0';
+
+ for( j=0;j<2;j++ )
+ {
+ if (( TmpBuf[i*2+j] >= '0' ) && ( TmpBuf[i*2+j] <= '9' ))
+ {
+ n[0] = TmpBuf[i*2+j];
+ n[1] = '\0';
+ digit += (BYTE)(atoi( n ));
+
+ }
+ else if (( TmpBuf[i*2+j] >= 'a' ) && ( TmpBuf[i*2+j] <= 'f' ))
+ {
+ digit += (BYTE)(( TmpBuf[i*2+j] - 'a' ) + 10 );
+ }
+ else if (( TmpBuf[i*2+j] >= 'A' ) && ( TmpBuf[i*2+j] <= 'F' ))
+ {
+ digit += (BYTE)(( TmpBuf[i*2+j] - 'A' ) + 10 );
+ }
+ else
+ {
+
+ //
+ // We have an invalid Address; return error.
+ //
+
+ return (DWORD)-1;;
+ }
+
+ //
+ // Raise the high half by 0xf.
+ //
+
+ if ( j==0 )
+ {
+ digit *= 16;
+ }
+ }
+
+ *TmpAddr++ = (BYTE)digit;
+ }
+
+ return 0;
+}
+
+
+
+BOOL
+TpctlParseArgumentPairs(
+ IN LPSTR Argument,
+ OUT LPSTR *ArgName,
+ OUT LPSTR *ArgValue
+ )
+
+// ---------------------
+//
+// Routine Description:
+//
+// This routine parses an argument string to determine if it contains
+// an argument name/value pair, or just an argument value.
+//
+// Arguments:
+//
+// Argument - The argument string.
+//
+// ArgName - The name of the argument if there is one.
+//
+// ArgValue - The argument value.
+//
+// Return Value:
+//
+// BOOL - TRUE if there is a name/value pair, FALSE otherwise.
+//
+// -------------------
+
+{
+ LPSTR temp;
+ BOOL EqualsSign;
+
+ temp = Argument;
+ EqualsSign = FALSE;
+
+ if ( strchr(Argument,'=') != NULL )
+ {
+ EqualsSign = TRUE ;
+ }
+
+ //
+ // If there is an equals sign, then we have an argument name/value
+ // pair. Get each, and put them in their respective return strings.
+ //
+
+ if (EqualsSign)
+ {
+ *ArgName = Argument;
+ temp = Argument;
+
+ //
+ // Search for the end of the argument name, and null terminate it.
+ //
+
+ while ((*temp != '=') && (*temp != ' '))
+ {
+ temp++;
+ }
+
+ *temp++ = '\0';
+
+ //
+ // Then search for the beginning of the argument value, and return
+ // it in ArgValue.
+ //
+
+ while ((*temp == '=') || (*temp == ' '))
+ {
+ temp++;
+ }
+
+ *ArgValue = temp;
+
+ }
+ else
+ {
+
+ //
+ // There is only an argument value so null out the ArgName, and
+ // return the value in ArgValue.
+ //
+
+ ArgName = '\0';
+ *ArgValue = Argument;
+ }
+
+ return EqualsSign;
+}
+
+
+
+BOOL
+TpctlParseSetInfoArguments(
+ IN OUT DWORD *ArgC,
+ IN OUT LPSTR ArgV[],
+ IN OUT DWORD *tmpArgC,
+ IN OUT LPSTR tmpArgV[]
+ )
+
+// --------------
+//
+// Routine Description:
+//
+// Arguments:
+//
+// Return Value:
+//
+// BOOL -
+//
+// -------------
+
+{
+ DWORD i;
+
+ *tmpArgC = 1;
+ tmpArgV[0] = '\0';
+
+ //
+ // See if the arguments are name-value pairs, or just the
+ // argument values, if there is an equal sign in the first
+ // argument then they are name-value paired arguments.
+ //
+
+ if ( strchr(ArgV[1],'=') != NULL )
+ {
+ //
+ // We have name value pairs
+ //
+
+ for (i=1;i<*ArgC;i++)
+ {
+
+ //
+ // So search the ArgV for the correct argument name, and
+ // if it is found have tmpArgV refernce it.
+ //
+
+ if (( _strnicmp(ArgV[i],"PacketFilter",12) == 0 ) ||
+ ( _strnicmp(ArgV[i],"StationAddress",14) == 0 ) ||
+ ( _strnicmp(ArgV[i],"FunctionalAddress",17) == 0 ) ||
+ ( _strnicmp(ArgV[i],"GroupAddress",17) == 0 ) ||
+ ( _strnicmp(ArgV[i],"Lookahead",9) == 0 ) ||
+ ( _strnicmp(ArgV[i],"PF",2) == 0 ) ||
+ ( _strnicmp(ArgV[i],"SA",2) == 0 ) ||
+ ( _strnicmp(ArgV[i],"FA",2) == 0 ) ||
+ ( _strnicmp(ArgV[i],"GA",2) == 0 ) ||
+ ( _strnicmp(ArgV[i],"LA",2) == 0 ))
+ {
+
+ //
+ // We have found what we are looking for. Set the tmpArgC,
+ // and set tmpArgV[i] to point to it.
+ //
+
+ ++*tmpArgC;
+ tmpArgV[1] = ArgV[i];
+
+ //
+ // then make sure that it is at the end of the ArgV.
+ // This is required by ParseArguments to successfully
+ // handle parsing the OpenInstance and InfoClass
+ // arguments first.
+ //
+
+ if ( i != *ArgC - 1 )
+ {
+ ArgV[i] = ArgV[*ArgC-1];
+ //ArgV[*ArgC-1] = //tmpArgV[1];
+ }
+
+ ArgV[*ArgC-1] = NULL;
+ --*ArgC;
+
+ return TRUE;
+ }
+ }
+
+ }
+ else
+ {
+
+ //
+ // If there are no name-value pairings for the arguments, then
+ // we know the commands must be in the correct order, and the
+ // Class Specific Info argument MUST be last or 4th in ArgV.
+ //
+
+ if ( *ArgC >= 4 )
+ {
+
+ //
+ // We have found the argument, have tmpArgV reference it and
+ // return.
+ //
+
+ *tmpArgC = 2;
+ tmpArgV[1] = ArgV[3];
+
+ --*ArgC;
+ ArgV[3] = NULL;
+
+ return TRUE;
+
+ }
+ }
+
+ //
+ // Otherwise there are not enough arguments on the command
+ // line to include the Class Specific Info, or it simply does
+ // not exist on the command line, if it is needed, ti will
+ // have to be prompted for later.
+ //
+
+ return FALSE;
+}
+
+
+BOOL
+TpctlParseEnvironmentVariable(
+ IN BYTE Buffer[]
+ )
+
+// -------------
+//
+// Routine Description:
+//
+// Arguments:
+//
+// Return Value:
+//
+// ------------
+
+{
+ BYTE TmpBuffer[100];
+ LPSTR EndOfVar = Buffer; // Anything that isn't NULL.
+ LPSTR Variable;
+
+ //
+ // If the environment variable passed in is null, return false now.
+ //
+
+ if ( Buffer == NULL )
+ {
+ TpctlErrorLog("\n\tTpctl: Invalid Environment Variable Format \"%%\".\n",NULL);
+ return FALSE;
+ }
+
+ //
+ // Otherwise copy the variable into a temp buffer.
+ //
+
+ strcpy( TmpBuffer,&Buffer[1] );
+
+ //
+ // Now null out the '%' symbol if it exists to allow the querying
+ // of the environment variable.
+ //
+
+ EndOfVar = strchr( TmpBuffer,'%' );
+
+ if ( EndOfVar == NULL )
+ {
+ TpctlErrorLog("\n\tTpctl: Invalid Environment Variable Format \"%%%s\".\n",TmpBuffer);
+ return FALSE;
+ }
+ else
+ {
+ *EndOfVar = '\0';
+ }
+
+ //
+ // and then query the environment variable.
+ //
+
+ Variable = getenv( _strupr( TmpBuffer ));
+
+ if ( Variable == NULL )
+ {
+ TpctlErrorLog("\n\tTpctl: Undefined Environment Variable \"%%%s%%\".\n",TmpBuffer);
+ return FALSE;
+ }
+
+ strcpy( Buffer,Variable);
+
+ return TRUE;
+}
+
+
+
+BOOL
+TpctlFirstChar(
+ IN BYTE Buffer[],
+ IN BYTE Char
+ )
+{
+ LPSTR Token = Buffer;
+
+ if ( Buffer == NULL )
+ {
+ return FALSE;
+ }
+
+ while (( *Token != '\0' ) && ( *Token == ' ' ))
+ {
+ Token++; // ignore leading blanks
+ }
+
+ if ( *Token == (CHAR)Char )
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+DWORD
+TpctlGetOptionNumber(
+ IN PTESTPARAMS Options,
+ IN DWORD TestSize,
+ IN LPSTR ArgName
+ )
+
+// ------------
+//
+// Routine Description:
+//
+// Arguments:
+//
+// Return Value:
+//
+// -----------
+
+{
+ DWORD i;
+
+ for(i=0; i<TestSize; i++)
+ {
+ if (_stricmp(ArgName,Options[i].ArgName) == 0 )
+ {
+ return Options[i].OptionNumber;
+ }
+ if (_stricmp(ArgName,Options[i].ArgNameAbbr) == 0 )
+ {
+ return Options[i].OptionNumber;
+ }
+ }
+ return (DWORD)-1;;
+}
+
+
+DWORD
+TpctlGetOpenInstance(
+ IN DWORD ArgC,
+ IN LPSTR ArgV[]
+ )
+
+{
+ DWORD i;
+ LPSTR EqualSign;
+ LPBYTE NextToken;
+
+ //
+ // If we have no arguments, only the command, then return an error.
+ //
+
+ if ( ArgC <= 0 )
+ {
+ return (DWORD)-1;
+ }
+
+ //
+ // Otherwise walk the argument vector looking for an instance of either
+ // an OpenInstance = Value or simply return the first argument.
+ //
+
+ for (i=1; i<ArgC; i++)
+ {
+ if (( EqualSign = strchr(ArgV[i],'=')) == NULL ) // no = sign.
+ {
+ //
+ // Since there is no equal sign we know that the Open Instance
+ // must be the first argument, so simply return it.
+ //
+
+ return (strtoul(ArgV[i], &NextToken, 0));
+
+ }
+ else
+ {
+
+ //
+ // we have an argument value pair, check if its the
+ // Open Instance.
+ //
+
+ if ((_strnicmp(ArgV[i],"OI",2) == 0 ) ||
+ (_strnicmp(ArgV[i],"OpenInstance",12)))
+ {
+
+ //
+ // It is the open instance so return the value.
+ //
+
+ ++(EqualSign);
+ return ( strtoul( EqualSign,&NextToken,0 ));
+ }
+ }
+ }
+
+ return (DWORD)-1;;
+}