diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/test/tex.c | |
download | NT4.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/nw/test/tex.c')
-rw-r--r-- | private/nw/test/tex.c | 740 |
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 ); +} + + |