Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

568 lines
12 KiB

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
parse.c
Abstract:
This routine is the workhorse of the NT redirector test program.
It parses the command to be executed and processes it's arguments.
Author:
Larry Osterman (LarryO) 1-Aug-1990
Revision History:
1-Aug-1990 LarryO
Created
--*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <srvfsctl.h>
//#include <netlocal.h>
#include "tests.h"
#include "getinfo.h"
#include "setinfo.h"
#define REDIR_CMDLINE_SIZE 0x100
PCHAR readBuffer=NULL;
ULONG readBufferLength;
ULONG readBufferIndex;
VOID
DumpHelp(
ULONG ArgC,
PSZ ArgV[]
);
VOID
NetCmd (
IN ULONG ArgC,
IN PSZ ArgV[]
);
VOID
Delay (
IN ULONG ArgC,
IN PSZ ArgV[]
);
typedef VOID (*PTEST_ROUTINE)(ULONG ArgC, PSZ Argv[]);
typedef struct _Redir_Test_Command {
PCHAR Command; // Command name
PTEST_ROUTINE TestRoutine; // Test routine
PCHAR HelpText;
} REDIR_TESTS, *PREDIR_TESTS;
REDIR_TESTS Tests[] = {
{ "Help", DumpHelp, "This command" },
{ "?", DumpHelp, "This command" },
{ "Delay", Delay, "Go to sleep for a while" },
{ "Create", TestCreate, "Create <file> <handle#> "
"<root directory > <access>"
"\n\t\t<allocationsize> <attributes>"
" <share access> <disposition> "
"<options>" },
{ "Open", TestOpen, "Open <file>" },
{ "Close", TestClose, "Close <handle#>" },
{ "Read", TestRead, "Read <handle#> <offset> <numberofbytes> <key>" },
{ "Peek", TestPeek, "Peek <handle#> <offset> <numberofbytes> <key>" },
{ "WaitPipe", TestWaitPipe, "WaitPipe <handle#> <timeout> <name> <timeoutspecified>" },
{ "SetPipe", TestSetPipe, "SetPipe <handle#> <readmode> <completionmode>" },
{ "Write", TestWrite, "Write <handle#> <offset> <numberofbytes> <key>" },
{ "NullRead", TestNullRead, "NullRead <file> <root> <iteration> - Times a null write operation" },
{ "WinNullRead", TestWinNullRead, "WinNullRead <file> <root> <iteration> - Times a null write operation" },
{ "Lock", TestLock, "Lock <handle#> <offset> <numberofbytes> <key>" },
{ "Unlock", TestUnlock, "Unlock <handle#> <offset> <numberofbytes> <key>" },
{ "SetInfoFile", TestSInfoFile, "Sinfofile <handle#> " },
{ "SetInfoVol", TestSInfoVolume,"Sinfovol <handle#> "
"<Fs information class>" },
{ "Qinfofile", TestQInfoFile, "QInfoFile <handle#>" },
{ "Qinfovol", TestQInfoVolume,"Qinfovol <handle#> "
"<Fs information class>" },
{ "Qprint", TestQprint, "Qprint <handle#> <index> " },
{ "Dir", TestDir, "Dir <handle#> "
"<length> <single> <Fs information class> "
"<filename> <restart>" },
{ "type", TestType, "type <file> <root directory>" },
{ "mkdir", TestMkdir, "Mkdir <directory> <root directory>"},
{ "md", TestMkdir, "Mkdir <directory> <root directory>"},
{ "flush", TestFlush, "Flush <handle#>"},
{ "tcon", TestTreeConnect,"tcon <directory> <handle#>" },
{ "Cmd", CmdFile, "Cmd <filename>" },
{ "Verbose", TestVerbose, "Verbose" },
{ "Silent", TestSilent, "Silent" },
{ "Repeat", TestRepeat, "Repeat <count>" }
};
#define NUM_REDIR_TESTS sizeof(Tests) / sizeof(Tests[0])
VOID
ParseCommand(
IN PSZ CommandLine,
OUT PSZ Argv[],
OUT PUSHORT Argc,
IN ULONG MaxArgc
)
{
PSZ cl = CommandLine;
USHORT ac = 0;
while ( *cl && ((ULONG)ac < MaxArgc) ) {
while ( *cl && (*cl <= ' ') ) { // ignore leading blanks
cl++;
}
if ( !*cl ) break;
*Argv++ = cl;
++ac;
while (*cl > ' ') {
cl++;
}
if ( *cl ) {
*cl++ = '\0';
}
}
if ( (ULONG)ac < MaxArgc ) {
*Argv++ = NULL;
} else if ( *cl ) {
dprintf(( "Too many tokens in command; \"%s\" ignored\n", cl ));
}
*Argc = ac;
return;
} // ParseCommand
VOID
Delay (
IN ULONG ArgC,
IN PSZ ArgV[]
)
/*++
Routine Description:
This routine sleeps for a while.
Arguments:
IN ULONG ArgC, - [Supplies | Returns] description-of-argument
IN PSZ ArgV[] - [Supplies | Returns] description-of-argument
Return Value:
None.
--*/
{
ULONG TimeToSleep = atol(ArgV[1]);
dprintf(("Sleeping for %ld seconds", TimeToSleep));
if (TimeToSleep) {
HANDLE SleepTimer;
NTSTATUS Status;
LARGE_INTEGER TimerDueTime;
//
// Create a timer to sleep on.
//
Status = NtCreateTimer(&SleepTimer,
TIMER_ALL_ACCESS,
NULL,
NotificationTimer);
if (!NT_SUCCESS(Status)) {
dprintf(("NtCreateTimer failed, Status = %X\n", Status));
return;
}
while (TimeToSleep--) {
//
// Set the timer to expire when the use specified.
//
// Status = NtQuerySystemTime(&TimerDueTime);
//
// if (!NT_SUCCESS(Status)) {
// dprintf(("NtQuerySystemTime failed, Status = %X\n", Status));
// return;
// }
//
// Wait for 1 second.
//
TimerDueTime.LowPart = - (10*1000*1000);
TimerDueTime.HighPart = -1;
Status = NtSetTimer(SleepTimer,
&TimerDueTime,
NULL,
NULL,
FALSE,
0,
NULL);
if (!NT_SUCCESS(Status)) {
dprintf(("NtSetTimer failed, Status = %X\n", Status));
return;
}
//
// Wait for the timer to expire.
//
Status = NtWaitForSingleObject(SleepTimer, TRUE, NULL);
if (!NT_SUCCESS(Status)) {
dprintf(("NtWaitForSingleObject failed, Status = %X\n", Status));
return;
}
dprintf(("."));
}
NtClose(SleepTimer);
}
dprintf(("Done\n"));
return;
if (ArgC);
}
VOID
DumpHelp (
IN ULONG ArgC,
IN PSZ ArgV[]
)
/*++
Routine Description:
This routine dumps the help texts for the commands to TRDR
.
Arguments:
IN ULONG ArgC, - [Supplies | Returns] description-of-argument
IN PSZ ArgV[] - [Supplies | Returns] description-of-argument
Return Value:
None.
--*/
{
ULONG i;
dprintf(("Help for RdrTest\n"));
dprintf(("\tbreak - Enter debugger\n"));
dprintf(("\texit - Exit program\n"));
for (i=0;i<NUM_REDIR_TESTS;i++) {
if ((i > 0) && (Tests[i].TestRoutine!=Tests[i-1].TestRoutine)) {
dprintf(("\t%s - %s\n", Tests[i].Command, Tests[i].HelpText));
}
}
ArgV;ArgC;
}
VOID
LoadBatchFile(
IN PSTRING Name
)
/*++
Routine Description:
This routine reads reads a file full of commands. It is copied from
the usrv test program.
Arguments:
IN PSTRING Name - Supplies \\SystemRoot\\<Name>.cmd
Return Value:
None.
--*/
{
NTSTATUS status;
CHAR nameBuffer[32];
STRING fileName;
UNICODE_STRING fileNameU;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE fileHandle;
IO_STATUS_BLOCK ioStatusBlock;
RtlMoveMemory( nameBuffer, "\\SystemRoot\\", 12 );
RtlMoveMemory( nameBuffer + 15, Name->Buffer, Name->Length );
RtlMoveMemory( nameBuffer + 15 + Name->Length, ".CMD", 5 );
fileName.Buffer = nameBuffer;
fileName.Length = (SHORT)strlen( nameBuffer );
RtlAnsiStringToUnicodeString(&fileNameU, &fileName, TRUE);
InitializeObjectAttributes(
&objectAttributes,
&fileNameU,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = NtOpenFile(
&fileHandle,
FILE_READ_DATA | SYNCHRONIZE,
&objectAttributes,
&ioStatusBlock,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT
);
RtlFreeUnicodeString(&fileNameU);
if ( !NT_SUCCESS(status) ) {
if ( status == STATUS_OBJECT_NAME_NOT_FOUND ) {
dprintf(( "Batch file %Z not found\n", &fileName ));
} else {
dprintf(( "Error opening batch file %Z: %X\n",
&fileName, status ));
}
return;
}
readBuffer = RtlAllocateHeap( Heap, 0, 4096 );
if ( readBuffer == NULL ) {
NtClose( fileHandle );
return;
}
status = NtReadFile(
fileHandle,
NULL,
NULL,
NULL,
&ioStatusBlock,
readBuffer,
4096,
NULL,
NULL
);
if ( !NT_SUCCESS(status) ) {
dprintf(( "Error reading batch file %Z: %X\n", &fileName, status ));
ioStatusBlock.Information = 0;
}
NtClose( fileHandle );
readBufferIndex = 0;
readBufferLength=ioStatusBlock.Information;
return;
} // ExecuteBatchFile
VOID
TestVerbose(
ULONG ArgC,
PSZ ArgV[]
)
{
Verbose = TRUE;
}
VOID
TestSilent(
ULONG ArgC,
PSZ ArgV[]
)
{
Verbose = FALSE;
}
TESTPARAMS RepeatOptions[] = {
{ "Count", Integer, 1, NULL, NULL, 0, &RepeatCount }
};
VOID
TestRepeat(
ULONG ArgC,
PSZ ArgV[]
)
{
LONG NumArgs;
NumArgs = Parse_Options(RepeatOptions,sizeoftable(RepeatOptions),ArgC,ArgV);
}
VOID
ReadCommand (
IN PCH Prompt,
OUT PCH Response,
IN ULONG MaximumResponse
)
/*++
Routine Description:
This routine reads from the debug port or the command file one command.
Arguments:
IN PCH Prompt,
OUT PCH Response,
IN ULONG MaximumResponse,
Return Value:
None.
--*/
{
PSZ commandBufferPtr;
if (readBuffer==NULL) {
conprompt(Prompt, Response, MaximumResponse);
return;
} else {
dprintf(("%s", Prompt));
for (commandBufferPtr = Response;
(readBufferIndex < readBufferLength) &&
((ULONG)(commandBufferPtr - Response)<MaximumResponse);
readBufferIndex++ ) {
if ( readBuffer[readBufferIndex] == '\n' ) {
*commandBufferPtr = '\0';
dprintf((" %s\n", Response));
break;
}
*commandBufferPtr++ = readBuffer[readBufferIndex];
}
dprintf((" %s\n", Response));
}
readBufferIndex++;
if (readBufferIndex >= readBufferLength) {
RtlFreeHeap( Heap, 0, readBuffer );
readBuffer = NULL;
}
}
VOID
Redir_Test (
VOID
)
/*++
Routine Description:
This routine is the main workhorse of the redirector test program.
Arguments:
None.
Return Value:
None.
--*/
{
#define MAX_ARGC 20
CHAR Buffer[REDIR_CMDLINE_SIZE];
PSZ localArgv[MAX_ARGC];
ULONG i;
ULONG j;
USHORT localArgc;
STRING Default;
RtlInitString(&Default,"RdrAuto");
LoadBatchFile(&Default);
while (TRUE) {
ReadCommand("Redir Test> ", Buffer, REDIR_CMDLINE_SIZE);
ParseCommand( Buffer, localArgv, &localArgc, MAX_ARGC );
//
// If no commands specified, go back for more.
//
if (localArgc <= 0) {
continue ;
}
if ( stricmp ( localArgv[0], "break" ) == 0 ) {
DbgBreakPoint( );
continue;
}
if ( stricmp ( localArgv[0], "exit" ) == 0 ) {
break;
}
for (i = 0; i < NUM_REDIR_TESTS ; i++) {
if (stricmp (localArgv[0], Tests[i].Command) == 0) {
for (j = 0; j < RepeatCount ; j++) {
// Execute test as many times as required
Tests[i].TestRoutine(localArgc, localArgv);
}
break;
}
}
if (i==NUM_REDIR_TESTS) {
dprintf(("Unknown test specified %s\n", localArgv[0]));
}
} // while(TRUE)
}