summaryrefslogtreecommitdiffstats
path: root/private/nw/test/tex.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/nw/test/tex.c')
-rw-r--r--private/nw/test/tex.c740
1 files changed, 740 insertions, 0 deletions
diff --git a/private/nw/test/tex.c b/private/nw/test/tex.c
new file mode 100644
index 000000000..b251aa063
--- /dev/null
+++ b/private/nw/test/tex.c
@@ -0,0 +1,740 @@
+/*++
+
+Copyright (c) 1993 Microsoft Corporation
+
+Module Name:
+
+ tex.c
+
+Abstract:
+
+ User mode test program for the Microsoft Netware redir file system.
+
+ This test program can be built from the command line using the
+ command 'nmake UMTEST=tex'.
+
+Author:
+
+ Manny Weiser (mannyw) 7-Jun-1993
+
+Revision History:
+
+--*/
+
+#include <stdio.h>
+#include <string.h>
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+#include <ntddnwfs.h>
+#include <ntddnwp.h>
+#include <STDARG.H>
+
+//
+// Local definitions
+//
+
+
+VOID
+DisplayUsage(
+ PSZ ProgramName
+ );
+
+SendMessage(
+ IN char* Format,
+ ...
+ );
+
+VOID
+SetLock(
+ PCHAR FileHandle,
+ BOOLEAN Exclusive,
+ ULONG ByteOffset,
+ ULONG Length,
+ ULONG Timeout
+ );
+
+NTSTATUS
+FormatRequest(
+ PCHAR SendBuffer,
+ PULONG SendBufferLength,
+ char* Format,
+ va_list a
+ );
+
+BOOLEAN
+OpenServer(
+ PHANDLE Handle,
+ PWCH ServerName
+ );
+
+NTSTATUS
+_cdecl
+ParseResponse(
+ char* FormatString,
+ ... // format specific parameters
+ );
+
+#define BUFFER_SIZE 200
+
+WCHAR *ServerName = L"NETWARE311";
+UCHAR Pid = 255;
+
+HANDLE ServerHandle;
+_cdecl
+main(
+ int argc,
+ char *argv[],
+ )
+{
+ BOOLEAN success;
+ UCHAR DirectoryHandle;
+ UCHAR FileHandle1[6];
+ UCHAR FileHandle2[6];
+
+ success = OpenServer( &ServerHandle, ServerName );
+ if ( !success) {
+ return 1;
+ }
+
+ printf("Opened server, %S\n", ServerName );
+
+ // Get directory handle for SYS:
+
+ SendMessage( "Sbbp", 0x16, 0x12, 0, 0, "SYS:" );
+ ParseResponse( "b", &DirectoryHandle );
+
+ // Open FILE1
+
+ Pid = 100;
+ SendMessage( "Fbbbp", 0x4C, DirectoryHandle, 0x07, 01, "File1" );
+ ParseResponse( "r", FileHandle1, 6 );
+
+ // Open FILE1
+
+ Pid = 101;
+ SendMessage( "Fbbbp", 0x4C, DirectoryHandle, 0x07, 01, "File1" );
+ ParseResponse( "r", FileHandle2, 6 );
+
+ // Lock test
+
+ Pid = 100;
+ SetLock( FileHandle1, TRUE, 0, 10, 0xFFFF );
+ SetLock( FileHandle1, TRUE, 10, 10, 0xFFFF );
+ SetLock( FileHandle1, TRUE, 5, 10, 0xFFFF );
+ SetLock( FileHandle1, TRUE, 10, 10, 0xFFFF );
+
+ Pid = 101;
+ SetLock( FileHandle2, TRUE, 6, 10, 0xFFFF );
+ SetLock( FileHandle2, TRUE, 7, 10, 0xFFFF );
+ SetLock( FileHandle2, TRUE, 0, 10, 0xFFFF );
+
+ Sleep( 10 * 1000 );
+
+ // Close FILE1
+
+ SendMessage( "F-r", 0x42, FileHandle1, 6 );
+ ParseResponse( "" );
+
+ // Close FILE1
+
+ SendMessage( "F-r", 0x42, FileHandle2, 6 );
+ ParseResponse( "" );
+
+ // End Job
+
+ Pid = 100;
+ SendMessage( "F-", 0x18 );
+ Pid = 101;
+ SendMessage( "F-", 0x18 );
+
+ // Close the directory
+
+ SendMessage( "Sb", 0x16, 0x14, DirectoryHandle );
+ ParseResponse( "" );
+
+ printf( "%s exiting\n", argv[0]);
+ return 0;
+}
+
+VOID
+SetLock(
+ PCHAR FileHandle,
+ BOOLEAN Exclusive,
+ ULONG ByteOffset,
+ ULONG Length,
+ ULONG Timeout
+ )
+{
+ USHORT Flags;
+
+ if ( Exclusive ) {
+ Flags = 1;
+ } else {
+ Flags = 3;
+ }
+
+ SendMessage( "Fbrddw", 0x1A, Flags, FileHandle, 6, ByteOffset, Length, Timeout );
+ ParseResponse( "" );
+}
+
+BOOLEAN
+OpenServer(
+ PHANDLE Handle,
+ PWCH ServerName
+ )
+{
+ NTSTATUS status;
+ OBJECT_ATTRIBUTES objectAttributes;
+ IO_STATUS_BLOCK ioStatusBlock;
+ WCHAR FileNameBuffer[100];
+ UNICODE_STRING FileName;
+
+ FileName.Buffer = FileNameBuffer;
+ FileName.Length = 0;
+ FileName.MaximumLength = 100;
+
+ status = RtlAppendUnicodeToString( &FileName, DD_NWFS_DEVICE_NAME_U );
+ ASSERT( status == STATUS_SUCCESS );
+ status = RtlAppendUnicodeToString( &FileName, L"\\" );
+ ASSERT( status == STATUS_SUCCESS );
+ status = RtlAppendUnicodeToString( &FileName, ServerName );
+ ASSERT( status == STATUS_SUCCESS );
+
+ //
+ // Open the file
+ //
+
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL
+ );
+
+ status = NtOpenFile (
+ Handle,
+ FILE_GENERIC_READ | SYNCHRONIZE,
+ &objectAttributes,
+ &ioStatusBlock,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ 0L
+ );
+
+ if (!NT_SUCCESS(status) ) {
+ printf( "Open status = %x for file %Z\n", status, &FileName );
+ }
+
+ return ( (BOOLEAN) NT_SUCCESS( status ) );
+}
+
+
+CHAR Buffer1[100];
+CHAR Buffer2[100];
+
+SendMessage(
+ IN char* Format,
+ ...
+ )
+{
+ NTSTATUS status;
+ IO_STATUS_BLOCK IoStatusBlock;
+
+ va_list Arguments;
+ NTSTATUS Status;
+ ULONG ReceiveBufferSize = 100;
+ ULONG SendBufferSize = 100;
+
+ va_start( Arguments, Format );
+
+ Buffer1[0] = Pid;
+
+ Status = FormatRequest( &Buffer1[1], &SendBufferSize, Format, Arguments );
+ if ( !NT_SUCCESS( Status ) ) {
+ return( Status );
+ }
+
+ printf("Sending message\n" );
+
+ status = NtFsControlFile(
+ ServerHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_ANY_NCP,
+ Buffer1,
+ SendBufferSize + 1,
+ Buffer2,
+ ReceiveBufferSize
+ );
+
+ if ( NT_SUCCESS( status ) ) {
+
+ status = NtWaitForSingleObject( ServerHandle, FALSE, NULL );
+ if ( NT_SUCCESS( status )) {
+ status = IoStatusBlock.Status;
+ }
+ }
+
+ if ( !NT_SUCCESS( status ) ) {
+ printf("NtFsControlFile returns %08lx\n", status );
+ return( status );
+ } else {
+ printf("Message received\n" );
+ }
+
+
+ return( status );
+}
+
+
+NTSTATUS
+FormatRequest(
+ PCHAR SendBuffer,
+ PULONG SendBufferLength,
+ char* Format,
+ va_list a
+ )
+/*++
+
+Routine Description:
+
+ Send the packet described by Format and the additional parameters.
+
+Arguments:
+
+ Format - the information needed to create the request to the
+ server. The first byte indicates the packet type and the
+ following bytes contain field types.
+
+ Packet types:
+
+ 'A' SAP broadcast ( void )
+ 'C' NCP connect ( void )
+ 'F' NCP function ( byte )
+ 'S' NCP subfunction ( byte, byte )
+ 'D' NCP disconnect ( void )
+
+ Field types, request/response:
+
+ 'b' byte ( byte / byte* )
+ 'w' hi-lo word ( word / word* )
+ 'd' hi-lo dword ( dword / dword* )
+ '-' zero/skip byte ( void )
+ '=' zero/skip word ( void )
+ ._. zero/skip string ( word )
+ 'p' pstring ( char* )
+ 'u' p unicode string ( UNICODE_STRING * )
+ 'c' cstring ( char* )
+ 'r' raw bytes ( byte*, word )
+ 'u' p unicode string ( UNICODE_STRING * )
+ 'U' p uppercase string( UNICODE_STRING * )
+ 'f' separate fragment ( PMDL )
+
+ An 'f' field must be last, and in a response it cannot be
+ preceeded by 'p' or 'c' fields.
+
+
+Return Value:
+
+ Normally returns STATUS_PENDING.
+
+--*/
+{
+ NTSTATUS status;
+ char* pFormatCharacter;
+ USHORT t = 1;
+ ULONG data_size;
+ ULONG length;
+
+ data_size = 1;
+
+ SendBuffer[ 0 ] = va_arg( a, UCHAR );
+
+ if ( *Format == 'S' ) {
+ data_size += 2;
+ SendBuffer[data_size++] = va_arg( a, UCHAR );
+ }
+
+ pFormatCharacter = Format;
+
+ while ( *++pFormatCharacter && *pFormatCharacter != 'f' )
+ {
+ switch ( *pFormatCharacter ) {
+
+ case '=':
+ SendBuffer[data_size++] = 0;
+ case '-':
+ SendBuffer[data_size++] = 0;
+ break;
+
+ case '_':
+ length = va_arg ( a, USHORT );
+
+ if ( data_size + length > *SendBufferLength ) {
+ printf("***exch:!0!\n");
+ return( FALSE );
+ }
+
+ while ( length-- ) {
+ SendBuffer[data_size++] = 0;
+ }
+
+ break;
+
+ case 'b':
+ SendBuffer[data_size++] = va_arg ( a, UCHAR );
+ break;
+
+ case 'w':
+ {
+ USHORT w = va_arg ( a, USHORT );
+
+ SendBuffer[data_size++] = (UCHAR) (w >> 8);
+ SendBuffer[data_size++] = (UCHAR) (w >> 0);
+ break;
+ }
+
+ case 'd':
+ {
+ ULONG d = va_arg ( a, ULONG );
+
+ SendBuffer[data_size++] = (UCHAR) (d >> 24);
+ SendBuffer[data_size++] = (UCHAR) (d >> 16);
+ SendBuffer[data_size++] = (UCHAR) (d >> 8);
+ SendBuffer[data_size++] = (UCHAR) (d >> 0);
+ break;
+ }
+
+ case 'c':
+ {
+ char* c = va_arg ( a, char* );
+
+ length = strlen( c );
+
+ if ( data_size + length > *SendBufferLength ) {
+ printf("***exch:!1!\n");
+ return( FALSE );
+ }
+
+ RtlCopyMemory( &SendBuffer[data_size], c, length + 1 );
+ data_size += length + 1;
+ break;
+ }
+
+ case 'p':
+ {
+ char* c = va_arg ( a, char* );
+
+ length = strlen( c );
+
+ if ( data_size + length > *SendBufferLength ) {
+ printf("***exch:!2!\n");
+ return FALSE;
+ }
+
+ SendBuffer[data_size++] = (UCHAR)length;
+ RtlCopyMemory( &SendBuffer[data_size], c, length );
+ data_size += length;
+ break;
+ }
+
+ case 'u':
+ {
+ PUNICODE_STRING pUString = va_arg ( a, PUNICODE_STRING );
+ OEM_STRING OemString;
+
+ //
+ // Calculate required string length, excluding trailing NUL.
+ //
+
+ length = (USHORT)RtlUnicodeStringToOemSize( pUString ) - 1;
+ ASSERT( length < 0x100 );
+
+ if ( data_size + length > *SendBufferLength ) {
+ printf("***exch:!4!\n");
+ return( FALSE );
+ }
+
+ SendBuffer[data_size++] = (UCHAR)length;
+ OemString.Buffer = &SendBuffer[data_size];
+ OemString.MaximumLength = (USHORT)length + 1;
+ status = RtlUnicodeStringToCountedOemString( &OemString, pUString, FALSE );
+ ASSERT( NT_SUCCESS( status ));
+ data_size += (USHORT)length;
+ break;
+ }
+
+ case 'U':
+ {
+ USHORT i;
+
+ //
+ // UPPERCASE the string, copy it from unicode to the packet
+ //
+
+ PUNICODE_STRING pUString = va_arg ( a, PUNICODE_STRING );
+ UNICODE_STRING UUppercaseString;
+ OEM_STRING OemString;
+
+ if ( pUString->Length > 0 ) {
+
+ RtlUpcaseUnicodeString( &UUppercaseString, pUString, TRUE );
+
+ //
+ // Change all '\' to '/'
+ //
+
+ for ( i = 0 ; i < UUppercaseString.Length ; i++ ) {
+ if ( UUppercaseString.Buffer[i] == L'\\' ) {
+ UUppercaseString.Buffer[i] = L'/';
+ }
+ }
+
+ //
+ // Calculate required string length, excluding trailing NUL.
+ //
+
+ length = (USHORT)RtlUnicodeStringToOemSize( &UUppercaseString ) - 1;
+ ASSERT( length < 0x100 );
+
+ } else {
+ UUppercaseString = *pUString;
+ length = 0;
+ }
+
+ if ( data_size + length > *SendBufferLength ) {
+ printf("***exch:!5!\n");
+ return( FALSE );
+ }
+
+ SendBuffer[data_size++] = (UCHAR)length;
+ OemString.Buffer = &SendBuffer[data_size];
+ OemString.MaximumLength = (USHORT)length + 1;
+ status = RtlUnicodeStringToCountedOemString( &OemString,
+ &UUppercaseString,
+ FALSE );
+ ASSERT( NT_SUCCESS( status ));
+
+ if ( pUString->Length > 0 ) {
+ RtlFreeUnicodeString( &UUppercaseString );
+ }
+
+ data_size += (USHORT)length;
+ break;
+ }
+
+ case 'r':
+ {
+ UCHAR* b = va_arg ( a, UCHAR* );
+ length = va_arg ( a, USHORT );
+
+ if ( data_size + length > *SendBufferLength ) {
+ printf("***exch:!6!\n");
+ return( FALSE );
+ }
+
+ RtlCopyMemory( &SendBuffer[data_size], b, length );
+ data_size += length;
+ break;
+ }
+
+ default:
+ printf ( "*****exchange: invalid request field, %x\n", *pFormatCharacter);
+ return( FALSE );
+ }
+
+ if ( data_size > *SendBufferLength ) {
+ printf( "*****exchange: CORRUPT, too much request data\n" );
+ va_end( a );
+ return FALSE;
+ }
+ }
+
+ if ( *Format == 'S' )
+ {
+ SendBuffer[1] = (UCHAR)((data_size-3) >> 8);
+ SendBuffer[2] = (UCHAR)(data_size-3);
+ }
+
+ va_end( a );
+
+ *SendBufferLength = data_size;
+ return TRUE;
+}
+
+NTSTATUS
+_cdecl
+ParseResponse(
+ char* FormatString,
+ ... // format specific parameters
+ )
+/*++
+
+Routine Description:
+
+ This routine parse an NCP response.
+
+Arguments:
+
+ FormatString - supplies the information needed to create the request to the
+ server. The first byte indicates the packet type and the
+ following bytes contain field types.
+
+ Field types, request/response:
+
+ 'b' byte ( byte* )
+ 'w' hi-lo word ( word* )
+ 'd' hi-lo dword ( dword* )
+ '-' zero/skip byte ( void )
+ '=' zero/skip word ( void )
+ ._. zero/skip string ( word )
+ 'p' pstring ( char* )
+ 'c' cstring ( char* )
+ 'r' raw bytes ( byte*, word )
+ 'R' ASCIIZ to Unicode ( UNICODE_STRING *, word )
+
+Return Value:
+
+ STATUS - The converted error code from the NCP response.
+
+--*/
+
+{
+ PCHAR FormatByte;
+ va_list Arguments;
+ int Length = 0;
+
+ va_start( Arguments, FormatString );
+
+ FormatByte = FormatString;
+ while ( *FormatByte ) {
+
+ switch ( *FormatByte ) {
+
+ case '-':
+ Length += 1;
+ break;
+
+ case '=':
+ Length += 2;
+ break;
+
+ case '_':
+ {
+ USHORT l = va_arg ( Arguments, USHORT );
+ Length += l;
+ break;
+ }
+
+ case 'b':
+ {
+ UCHAR* b = va_arg ( Arguments, UCHAR* );
+ *b = Buffer2[Length++];
+ break;
+ }
+
+ case 'w':
+ {
+ UCHAR* b = va_arg ( Arguments, UCHAR* );
+ b[1] = Buffer2[Length++];
+ b[0] = Buffer2[Length++];
+ break;
+ }
+
+ case 'd':
+ {
+ UCHAR* b = va_arg ( Arguments, UCHAR* );
+ b[3] = Buffer2[Length++];
+ b[2] = Buffer2[Length++];
+ b[1] = Buffer2[Length++];
+ b[0] = Buffer2[Length++];
+ break;
+ }
+
+ case 'c':
+ {
+ char* c = va_arg ( Arguments, char* );
+ USHORT l = strlen( &Buffer2[Length] );
+ memcpy ( c, &Buffer2[Length], l+1 );
+ Length += l+1;
+ break;
+ }
+
+ case 'p':
+ {
+ char* c = va_arg ( Arguments, char* );
+ UCHAR l = Buffer2[Length++];
+ memcpy ( c, &Buffer2[Length], l );
+ c[l+1] = 0;
+ break;
+ }
+
+#if 0
+ case 'P':
+ {
+ PUNICODE_STRING pUString = va_arg ( Arguments, PUNICODE_STRING );
+ OEM_STRING OemString;
+
+ OemString.Length = Buffer2[Length++];
+ OemString.Buffer = &Buffer2[Length];
+
+ Status = RtlOemStringToCountedUnicodeString( pUString, &OemString, FALSE );
+ ASSERT( NT_SUCCESS( Status ));
+
+ break;
+ }
+#endif
+
+ case 'r':
+ {
+ UCHAR* b = va_arg ( Arguments, UCHAR* );
+ USHORT l = va_arg ( Arguments, USHORT );
+ RtlCopyMemory( b, &Buffer2[Length], l );
+ Length += l;
+ break;
+ }
+
+#if 0
+ case 'R':
+ {
+ //
+ // Interpret the buffer as an ASCIIZ string. Convert
+ // it to unicode in the preallocated buffer.
+ //
+
+ PUNICODE_STRING pUString = va_arg ( Arguments, PUNICODE_STRING );
+ OEM_STRING OemString;
+ USHORT len = va_arg ( Arguments, USHORT );
+
+ OemString.Buffer = &Buffer2[Length];
+ OemString.Length = strlen( OemString.Buffer );
+ OemString.MaximumLength = OemString.Length;
+
+ Status = RtlOemStringToCountedUnicodeString( pUString, &OemString, FALSE );
+ ASSERT( NT_SUCCESS( Status ));
+ Length += len;
+ break;
+ }
+#endif
+
+ default:
+ printf ( "*****exchange: invalid response field, %x\n", *FormatByte );
+ return( FALSE );
+ }
+
+#if 0
+ if ( Length > PacketLength )
+ {
+ printf ( "*****exchange: not enough response data, %d\n", i );
+ }
+#endif
+ FormatByte++;
+ }
+
+ va_end( Arguments );
+}
+
+