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 | |
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 '')
-rw-r--r-- | private/nw/test/attach.c | 404 | ||||
-rw-r--r-- | private/nw/test/encrypt.c | 243 | ||||
-rw-r--r-- | private/nw/test/fileio.c | 210 | ||||
-rw-r--r-- | private/nw/test/getmsg.c | 178 | ||||
-rw-r--r-- | private/nw/test/lock.c | 80 | ||||
-rw-r--r-- | private/nw/test/lock2.c | 65 | ||||
-rw-r--r-- | private/nw/test/lock3.c | 159 | ||||
-rw-r--r-- | private/nw/test/lock4.c | 157 | ||||
-rw-r--r-- | private/nw/test/makefile | 6 | ||||
-rw-r--r-- | private/nw/test/open.c | 144 | ||||
-rw-r--r-- | private/nw/test/sources | 44 | ||||
-rw-r--r-- | private/nw/test/testnw.c | 124 | ||||
-rw-r--r-- | private/nw/test/tex.c | 740 | ||||
-rw-r--r-- | private/nw/test/tp1.c | 1637 | ||||
-rw-r--r-- | private/nw/test/tp2.c | 1560 | ||||
-rw-r--r-- | private/nw/test/tp3.c | 1715 | ||||
-rw-r--r-- | private/nw/test/tp4.c | 1668 | ||||
-rw-r--r-- | private/nw/test/userncp.c | 246 |
18 files changed, 9380 insertions, 0 deletions
diff --git a/private/nw/test/attach.c b/private/nw/test/attach.c new file mode 100644 index 000000000..92fb54e7c --- /dev/null +++ b/private/nw/test/attach.c @@ -0,0 +1,404 @@ + +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + Attach.c + +Abstract: + + This module implements the routines for the NetWare + redirector to connect and disconnect from a server. + +Author: + + Colin Watson [ColinW] 10-Jan-1992 + +Revision History: + +--*/ +#include <stdio.h> +#include <nt.h> +#include <ntrtl.h> +//#include "Procs.h" + + +#define DebugTrace(INDENT,LEVEL,X,Y) { \ + printf(X,Y); \ +} + + + +VOID +ExtractNextComponentName ( + OUT PUNICODE_STRING Name, + IN PUNICODE_STRING Path + ) + +/*++ + +Routine Description: + + This routine extracts a the "next" component from a path string. + + It assumes that + +Arguments: + + Name - Returns a pointer to the component. + + Path - Supplies a pointer to the backslash seperated pathname. + +Return Value: + + None + +--*/ + +{ + register USHORT i; // Index into Name string. + + if (Path->Length == 0) { + RtlInitUnicodeString(Name, NULL); + return; + } + + // + // Initialize the extracted name to the name passed in skipping the + // leading backslash. + // + + ASSERT(Path->Buffer[0] == OBJ_NAME_PATH_SEPARATOR); + + Name->Buffer = Path->Buffer + 1; + Name->Length = Path->Length - sizeof(WCHAR); + Name->MaximumLength = Path->MaximumLength - sizeof(WCHAR); + + // + // Scan forward finding the terminal "\" in the server name. + // + + for (i=0;i<(USHORT)(Name->Length/sizeof(WCHAR));i++) { + + if (Name->Buffer[i] == OBJ_NAME_PATH_SEPARATOR) { + break; + } + } + + // + // Update the length and maximum length of the structure + // to match the new length. + // + + Name->Length = Name->MaximumLength = (USHORT)(i*sizeof(WCHAR)); +} + + +NTSTATUS +ExtractPathAndFileName ( + IN PUNICODE_STRING EntryPath, + OUT PUNICODE_STRING PathString, + OUT PUNICODE_STRING FileName + ) + +/*++ + +Routine Description: + + This routine cracks the entry path into two pieces, the path and the file +name component at the start of the name. + + +Arguments: + + IN PUNICODE_STRING EntryPath - Supplies the path to disect. + OUT PUNICODE_STRING PathString - Returns the directory containing the file. + OUT PUNICODE_STRING FileName - Returns the file name specified. + +Return Value: + + NTSTATUS - SUCCESS + + +--*/ + +{ + UNICODE_STRING Component; + UNICODE_STRING FilePath = *EntryPath; + + // Strip trailing separators + while ( (FilePath.Length != 0) && + FilePath.Buffer[(FilePath.Length-1)/sizeof(WCHAR)] == + OBJ_NAME_PATH_SEPARATOR ) { + + FilePath.Length -= sizeof(WCHAR); + FilePath.MaximumLength -= sizeof(WCHAR); + } + + // PathString will become EntryPath minus FileName and trailing separators + *PathString = FilePath; + + // Initialize FileName just incase there are no components at all. + RtlInitUnicodeString( FileName, NULL ); + + // + // Scan through the current file name to find the entire path + // up to (but not including) the last component in the path. + // + + do { + + // + // Extract the next component from the name. + // + + ExtractNextComponentName(&Component, &FilePath); + + // + // Bump the "remaining name" pointer by the length of this + // component + // + + if (Component.Length != 0) { + + FilePath.Length -= Component.Length+sizeof(WCHAR); + FilePath.MaximumLength -= Component.MaximumLength+sizeof(WCHAR); + FilePath.Buffer += (Component.Length/sizeof(WCHAR))+1; + + *FileName = Component; + } + + + } while (Component.Length != 0); + + // + // Take the name, subtract the last component of the name + // and concatenate the current path with the new path. + // + + if ( FileName->Length != 0 ) { + + // + // Set the path's name based on the original name, subtracting + // the length of the name portion (including the "\") + // + + PathString->Length -= (FileName->Length + sizeof(WCHAR)); + if ( PathString->Length != 0 ) { + PathString->MaximumLength -= (FileName->MaximumLength + sizeof(WCHAR)); + } else{ + RtlInitUnicodeString( PathString, NULL ); + } + } else { + + // There was no path or filename + + RtlInitUnicodeString( PathString, NULL ); + } + + return STATUS_SUCCESS; +} + + +NTSTATUS +CrackPath ( + IN PUNICODE_STRING BaseName, + OUT PUNICODE_STRING DriveName, + OUT PUNICODE_STRING ServerName, + OUT PUNICODE_STRING VolumeName, + OUT PUNICODE_STRING PathName, + OUT PUNICODE_STRING FileName + ) + +/*++ + +Routine Description: + + This routine extracts the relevant portions from BaseName to extract + the components of the user's string. + + +Arguments: + + BaseName - Supplies the base user's path. + + DriveName - Supplies a string to hold the drive specifier. + + ServerName - Supplies a string to hold the remote server name. + + VolumeName - Supplies a string to hold the volume name. + + PathName - Supplies a string to hold the remaining part of the path. + + FileName - Supplies a string to hold the final component of the path. + +Return Value: + + NTSTATUS - Status of operation + + +--*/ + +{ + UNICODE_STRING BaseCopy = *BaseName; + UNICODE_STRING ShareName; + + RtlInitUnicodeString( DriveName, NULL); + RtlInitUnicodeString( ServerName, NULL); + RtlInitUnicodeString( VolumeName, NULL); + RtlInitUnicodeString( PathName, NULL); + RtlInitUnicodeString( FileName, NULL); + + // + // If the name is "\", or empty, there is nothing to do. + // + + if ( BaseName->Length <= sizeof( WCHAR ) ) { + return STATUS_SUCCESS; + } + + ExtractNextComponentName(ServerName, &BaseCopy); + + // + // Skip over the server name. + // + + BaseCopy.Buffer += (ServerName->Length / sizeof(WCHAR)) + 1; + BaseCopy.Length -= ServerName->Length + sizeof(WCHAR); + BaseCopy.MaximumLength -= ServerName->MaximumLength + sizeof(WCHAR); + + if ((ServerName->Length == sizeof(L"X:") - sizeof(WCHAR) ) && + (ServerName->Buffer[(ServerName->Length / sizeof(WCHAR)) - 1] == L':')) { + + // + // The file name is of the form x:\server\volume\foo\bar + // + + *DriveName = *ServerName; + + RtlInitUnicodeString( ServerName, NULL ); + ExtractNextComponentName(ServerName, &BaseCopy); + + if ( ServerName->Length != 0 ) { + + // + // Skip over the server name. + // + + BaseCopy.Buffer += (ServerName->Length / sizeof(WCHAR)) + 1; + BaseCopy.Length -= ServerName->Length + sizeof(WCHAR); + BaseCopy.MaximumLength -= ServerName->MaximumLength + sizeof(WCHAR); + } + } + + if ( ServerName->Length != 0 ) { + + // + // The file name is of the form \\server\volume\foo\bar + // Set volume name to server\volume. + // + + ExtractNextComponentName( &ShareName, &BaseCopy); + + // + // Set volume name = \server\share + // + + VolumeName->Buffer = ServerName->Buffer - 1; + ASSERT( VolumeName->Buffer[0] == '\\' ); + + if ( ShareName.Length != 0 ) { + + VolumeName->Length = ServerName->Length + ShareName.Length + 2 * sizeof( WCHAR ); + + BaseCopy.Buffer += ShareName.Length / sizeof(WCHAR) + 1; + BaseCopy.Length -= ShareName.Length + sizeof(WCHAR); + BaseCopy.MaximumLength -= ShareName.MaximumLength + sizeof(WCHAR); + + } else { + + VolumeName->Length = ServerName->Length + ShareName.Length + sizeof( WCHAR ); + + return( STATUS_SUCCESS ); + } + } + + return ExtractPathAndFileName ( &BaseCopy, PathName, FileName ); + +} + + +NTSTATUS +TestCrackPath ( + IN PUNICODE_STRING BaseName + ) { + NTSTATUS Status; + UNICODE_STRING DriveName; + UNICODE_STRING ServerName; + UNICODE_STRING VolumeName; + UNICODE_STRING PathName; + UNICODE_STRING FileName; + RtlInitUnicodeString( &DriveName, L"Error" ); + RtlInitUnicodeString( &ServerName, L"Error" ); + RtlInitUnicodeString( &PathName, L"Error" ); + RtlInitUnicodeString( &FileName, L"Error" ); + DebugTrace( 0, Dbg, "\nName = %Z\n", BaseName ); + Status = CrackPath( BaseName, &DriveName, &ServerName, &VolumeName, &PathName, &FileName ); + DebugTrace( 0, Dbg, " DriveName = %Z\n", &DriveName ); + DebugTrace( 0, Dbg, " ServerName= %Z\n", &ServerName ); + DebugTrace( 0, Dbg, " VolumeName= %Z\n", &VolumeName ); + DebugTrace( 0, Dbg, " PathName = %Z\n", &PathName ); + DebugTrace( 0, Dbg, " FileName = %Z\n", &FileName ); + return Status; + +} +int +_cdecl +main( + int argc, + char *argv[] + ) +{ + UNICODE_STRING Name; + RtlInitUnicodeString( &Name, L"\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server\\FileName" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server\\FileName\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server\\Path\\FileName" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server\\Path\\FileName\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server\\Path\\Path2\\FileName" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\x:\\Server\\Path\\Path2\\FileName\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server\\FileName" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server\\FileName\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server\\Path\\FileName" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server\\Path\\FileName\\" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server\\Path\\Path2\\FileName" ); + TestCrackPath( &Name ); + RtlInitUnicodeString( &Name, L"\\Server\\Path\\Path2\\FileName\\" ); + TestCrackPath( &Name ); + return 0; +} diff --git a/private/nw/test/encrypt.c b/private/nw/test/encrypt.c new file mode 100644 index 000000000..6884a9277 --- /dev/null +++ b/private/nw/test/encrypt.c @@ -0,0 +1,243 @@ +// +// This file pulled from logon.pas +// + +#include <string.h> +#define WIN32_CONSOLE_APP +#include <windows.h> + +typedef unsigned short int WORD; +typedef unsigned char UCHAR; +typedef unsigned long ULONG; +typedef unsigned long *PULONG; + + +UCHAR Table[] = +{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; + +UCHAR Keys[32] = +{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +#define XorArray( DEST, SRC ) { \ + PULONG D = (PULONG)DEST; \ + PULONG S = (PULONG)SRC; \ + int i; \ + for ( i = 0; i <= 7 ; i++ ) { \ + D[i] ^= S[i]; \ + } \ +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ); + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ) + +/*++ + +Routine Description: + + This routine shuffles around the object ID with the password + +Arguments: + + IN achObjectId - Supplies the 4 byte user's bindery object id + + IN szUpperPassword - Supplies the user's uppercased password on the + first call to process the password. On the second and third calls + this parameter contains the OutputBuffer from the first call + + IN iPasswordLen - length of uppercased password + + OUT achOutputBuffer - Returns the 8 byte sub-calculation + +Return Value: + + none. + +--*/ + +{ + int iTempIndex; + int iOutputIndex; + UCHAR achTemp[32]; + + // + // Initialize the achTemp buffer. Initialization consists of taking + // the password and dividing it up into chunks of 32. Any bytes left + // over are the remainder and do not go into the initialization. + // + // achTemp[0] = szUpperPassword[0] ^ szUpperPassword[32] ^ szUpper... + // achTemp[1] = szUpperPassword[1] ^ szUpperPassword[33] ^ szUpper... + // etc. + // + + if ( iPasswordLen > 32) { + + // At least one chunk of 32. Set the buffer to the first chunk. + + RtlCopyMemory( achTemp, szUpperPassword, 32 ); + + szUpperPassword +=32; // Remove the first chunk + iPasswordLen -=32; + + while ( iPasswordLen >= 32 ) { + // + // Xor this chunk with the characters already loaded into + // achTemp. + // + + XorArray( achTemp, szUpperPassword); + + szUpperPassword +=32; // Remove this chunk + iPasswordLen -=32; + } + + } else { + + // No chunks of 32 so set the buffer to zero's + + RtlZeroMemory( achTemp, sizeof(achTemp)); + + } + + // + // achTemp is now initialized. Load the remainder into achTemp. + // The remainder is repeated to fill achTemp. + // + // The corresponding character from Keys is taken to seperate + // each repitition. + // + // As an example, take the remainder "ABCDEFG". The remainder is expanded + // to "ABCDEFGwABCDEFGxABCDEFGyABCDEFGz" where w is Keys[7], + // x is Keys[15], y is Keys[23] and z is Keys[31]. + // + // + + if (iPasswordLen > 0) { + int iPasswordOffset = 0; + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) { + + if (iPasswordLen == iPasswordOffset) { + iPasswordOffset = 0; + achTemp[iTempIndex] ^= Keys[iTempIndex]; + } else { + achTemp[iTempIndex] ^= szUpperPassword[iPasswordOffset++]; + } + } + } + + // + // achTemp has been loaded with the users password packed into 32 + // bytes. Now take the objectid that came from the server and use + // that to munge every byte in achTemp. + // + + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) + achTemp[iTempIndex] ^= achObjectId[ iTempIndex & 3]; + + Scramble( Scramble( 0, achTemp ), achTemp ); + + // + // Finally take pairs of bytes in achTemp and return the two + // nibbles obtained from Table. The pairs of bytes used + // are achTemp[n] and achTemp[n+16]. + // + + for (iOutputIndex = 0; iOutputIndex < 16; iOutputIndex++) { + + achOutputBuffer[iOutputIndex] = + Table[achTemp[iOutputIndex << 1]] | + (Table[achTemp[(iOutputIndex << 1) + 1]] << 4); + } + + return; +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ) + +/*++ + +Routine Description: + + This routine scrambles around the contents of the buffer. Each buffer + position is updated to include the contents of at least two character + positions plus an EncryptKey value. The buffer is processed left to right + and so if a character position chooses to merge with a buffer position + to its left then this buffer position will include bits derived from at + least 3 bytes of the original buffer contents. + +Arguments: + + IN iSeed + IN OUT achBuffer[32] + +Return Value: + + none. + +--*/ + +{ + int iBufferIndex; + + for (iBufferIndex = 0; iBufferIndex < 32; iBufferIndex++) { + achBuffer[iBufferIndex] = + (UCHAR)( + ((UCHAR)(achBuffer[iBufferIndex] + iSeed)) ^ + ((UCHAR)( achBuffer[(iBufferIndex+iSeed) & 31] - + Keys[iBufferIndex] ))); + + iSeed += achBuffer[iBufferIndex]; + } + return iSeed; +} + + +ULONG Key = 0x95000009; +UCHAR szUpperPassword[129] = { 0x00 }; +UCHAR achBuf[32] = {0}; + +int +_cdecl +main( + int argc, + char *argv[] + ) +{ + Shuffle((UCHAR *) &Key, szUpperPassword, 0, achBuf); + + return(1); +} +// eof. + diff --git a/private/nw/test/fileio.c b/private/nw/test/fileio.c new file mode 100644 index 000000000..ed535206b --- /dev/null +++ b/private/nw/test/fileio.c @@ -0,0 +1,210 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + fileio.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=fileio'. + +Author: + + Manny Weiser (mannyw) 17-May-1993 + +Revision History: + +--*/ + +#include <stdio.h> +#include <string.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +// +// Local definitions +// + +VOID +DisplayUsage( + PSZ ProgramName + ); + + +BOOLEAN +OpenFile( + PSZ Name, + PHANDLE Handle + ); + +QueryFileInfo( + IN HANDLE Handle + ); + + +cdecl +main( + int argc, + char *argv[], + ) +{ + HANDLE handle; + BOOLEAN success; + char *fileName; + + if ( argc > 1) { + fileName = argv[1]; + } else { + fileName = "testfile.txt"; + } + + success = OpenFile( fileName, &handle ); + if ( !success) { + return 1; + } + + success = QueryFileInfo( handle ); + if ( !success) { + return 1; + } + + printf( "%s exiting\n", argv[0]); + return 0; +} + + +VOID +DisplayUsage( + PSZ ProgramName + ) +{ + printf( "Usage: %s [filename]", ProgramName); +} + + +BOOLEAN +OpenFile( + PSZ Name, + PHANDLE Handle + ) +{ + UNICODE_STRING nameString; + NTSTATUS status; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + RTL_RELATIVE_NAME RelativeName; + STRING AnsiFileName; + UNICODE_STRING FileName; + BOOLEAN TranslationStatus; + + RtlInitString( &AnsiFileName, Name ); + RtlOemStringToUnicodeString( &FileName, &AnsiFileName, TRUE ); + + TranslationStatus = RtlDosPathNameToNtPathName_U( + FileName.Buffer, + &FileName, + NULL, + &RelativeName + ); + + if ( !TranslationStatus ) { + return FALSE; + } + + if ( RelativeName.RelativeName.Length ) { + FileName = *(PUNICODE_STRING)&RelativeName.RelativeName; + } else { + RelativeName.ContainingDirectory = NULL; + } + + // + // Open the file + // + + InitializeObjectAttributes( + &objectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + RelativeName.ContainingDirectory, + NULL + ); + + status = NtOpenFile ( + Handle, + FILE_GENERIC_READ, + &objectAttributes, + &ioStatusBlock, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0L + ); + + if (!NT_SUCCESS(status) ) { + printf( "Open status = %x for file %Z\n", status, &nameString ); + } + + RtlFreeHeap(RtlProcessHeap(), 0, FileName.Buffer ); + return ( (BOOLEAN) NT_SUCCESS( status ) ); +} + + +DoSleep( + IN ULONG time + ) +{ + ULONG ms; + LARGE_INTEGER delayTime; + + ms = time * 100; + delayTime = RtlEnlargedIntegerMultiply( ms, -10000 ); + NtDelayExecution( TRUE, (PLARGE_INTEGER)&delayTime ); + + return( 0 ); +} + +QueryFileInfo( + IN HANDLE Handle + ) +{ + NTSTATUS status; + IO_STATUS_BLOCK IoStatusBlock; + char buffer[200]; + PFILE_ALL_INFORMATION allInfo = (PFILE_ALL_INFORMATION)buffer; + + status = NtQueryInformationFile( + Handle, + &IoStatusBlock, + allInfo, + 200, + FileAllInformation ); + + if ( NT_SUCCESS( status ) ) { + status = IoStatusBlock.Status; + } + + if ( !NT_SUCCESS( status ) ) { + printf("NtQueryInformation file returns %08lx\n", status ); + return( status ); + } + + printf( "File attributes = %x\n", allInfo->BasicInformation.FileAttributes ); + printf( "File size = %d\n", allInfo->StandardInformation.AllocationSize.LowPart ); + printf( "Is a dir = %d\n", allInfo->StandardInformation.Directory ); + printf( "Index = %x\n", allInfo->InternalInformation.IndexNumber ); + printf( "Easiz = %d\n", allInfo->EaInformation.EaSize ); + printf( "Access flags = %x\n", allInfo->AccessInformation.AccessFlags ); + printf( "Current offset = %d\n", allInfo->PositionInformation.CurrentByteOffset.LowPart ); + printf( "Mode = %x\n", allInfo->ModeInformation.Mode ); + printf( "Alignment info = %d\n", allInfo->AlignmentInformation.AlignmentRequirement ); + allInfo->NameInformation.FileName[ allInfo->NameInformation.FileNameLength / 2 ] = '\0'; + printf( "Name = %ws\n", allInfo->NameInformation.FileName ); + + return( status ); +} + + diff --git a/private/nw/test/getmsg.c b/private/nw/test/getmsg.c new file mode 100644 index 000000000..35c3146d2 --- /dev/null +++ b/private/nw/test/getmsg.c @@ -0,0 +1,178 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + fileio.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=fileio'. + +Author: + + Manny Weiser (mannyw) 17-May-1993 + +Revision History: + +--*/ + +#include <stdio.h> +#include <string.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <ntddnwfs.h> + +// +// Local definitions +// + +VOID +DisplayUsage( + PSZ ProgramName + ); + + +BOOLEAN +OpenRedir( + PHANDLE Handle + ); + +GetMessage( + IN HANDLE Handle + ); + +#define BUFFER_SIZE 200 + + +_cdecl +main( + int argc, + char *argv[], + ) +{ + HANDLE handle; + BOOLEAN success; + + success = OpenRedir( &handle ); + if ( !success) { + return 1; + } + + printf("Opened redirector\n" ); + + success = GetMessage( handle ); + if ( !success) { + return 1; + } + + printf( "%s exiting\n", argv[0]); + NtClose( handle ); + return 0; + + +} + + +BOOLEAN +OpenRedir( + PHANDLE Handle + ) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + UNICODE_STRING FileName; + + FileName.Buffer = DD_NWFS_DEVICE_NAME_U; + FileName.Length = sizeof( DD_NWFS_DEVICE_NAME_U ) - sizeof( WCHAR ); + FileName.MaximumLength = sizeof( DD_NWFS_DEVICE_NAME_U ); + + // + // 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 ) ); +} + + + +GetMessage( + IN HANDLE Handle + ) +{ + NTSTATUS status; + IO_STATUS_BLOCK IoStatusBlock; + char OutputBuffer[200]; + PWCHAR ServerName; + PWCHAR Message; + PNWR_SERVER_MESSAGE ServerMessage; + + printf("Waiting for message\n" ); + + status = NtFsControlFile( + Handle, + NULL, + NULL, + NULL, + &IoStatusBlock, + FSCTL_NWR_GET_MESSAGE, + NULL, + 0, + OutputBuffer, + sizeof(OutputBuffer) + ); + +#if 0 + if ( NT_SUCCESS( status ) ) { + + status = NtWaitForSingleObject( Handle, 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" ); + } + + ServerMessage = (PNWR_SERVER_MESSAGE)OutputBuffer; + ServerName = ServerMessage->Server; + Message = (PWCHAR)((PCHAR)ServerMessage + ServerMessage->MessageOffset); + + printf("From %S, Message = %S\n", ServerName, Message ); +#endif + + return( status ); +} + + diff --git a/private/nw/test/lock.c b/private/nw/test/lock.c new file mode 100644 index 000000000..89eb4d4b2 --- /dev/null +++ b/private/nw/test/lock.c @@ -0,0 +1,80 @@ + + +/* LOCKING.C: This program opens a file with sharing. It locks + + * some bytes before reading them, then unlocks them. Note that the + * program works correctly only if the following conditions are met: + * - The file exists + * - The program is run with MS-DOS version 3.0 or later + * with file sharing installed (SHARE.COM or SHARE.EXE), or + * if a Microsoft Networks compatible network is running + + */ + +#include <crt\io.h> +#include <sys\types.h> +#include <sys\stat.h> +#include <sys\locking.h> +#include <share.h> +#include <fcntl.h> +#include <stdio.h> + +#include <stdlib.h> + +#define STRING "0123456789012345678901234567890123456789012345678" + +void +_cdecl +main( void ) +{ + int fh, numread; + + char buffer[60]; + /* Quit if can't open file or MS-DOS version doesn't support sharing. */ + fh = _sopen( "test.txt", + _O_CREAT | _O_TRUNC | _O_RDWR, + _SH_DENYNO, + _S_IREAD | _S_IWRITE ); + + if( (fh == -1) || (_osmajor < 3) ) { + printf( "Cannot create/open file\n" ); + exit( 1 ); + } + + _write( fh, STRING, sizeof(STRING)); + _write( fh, STRING, sizeof(STRING)); + _write( fh, STRING, sizeof(STRING)); + _write( fh, STRING, sizeof(STRING)); + _write( fh, STRING, sizeof(STRING)); + _write( fh, STRING, sizeof(STRING)); + + /* Lock some bytes and read them. Then unlock. */ + lseek( fh, 0L, SEEK_SET ); + if( _locking( fh, LK_NBLCK, 50L ) != -1 ) + { + printf( "No one can change these bytes while I'm reading them\n" ); + numread = _read( fh, buffer, 50 ); + printf( "%d bytes read: %.50s\n", numread, buffer ); + lseek( fh, 0L, SEEK_SET ); + _locking( fh, LK_UNLCK, 50L ); + printf( "Now I'm done. Do what you will with them\n" ); + } + else + + perror( "Locking failed\n" ); + + lseek( fh, 4096L, SEEK_SET ); + if( _locking( fh, LK_NBLCK, 1024L ) != -1 ) + { + printf( "The lock off the end of the file worked ok\n" ); + //lseek( fh, 4096L, SEEK_SET ); + if( _locking( fh, LK_UNLCK, 1024L ) == -1 ) + printf( "The second unlock failed\n" ); + } + else + + perror( "Locking failed\n" ); + + _close( fh ); +} + diff --git a/private/nw/test/lock2.c b/private/nw/test/lock2.c new file mode 100644 index 000000000..d1e0ba45c --- /dev/null +++ b/private/nw/test/lock2.c @@ -0,0 +1,65 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + tfile.c + +Abstract: + + Test program for Win32 Base File API calls + +Author: + + Mark Lucovsky (markl) 26-Sep-1990 + +Revision History: + +--*/ + +#include <windows.h> +#include <assert.h> + +DWORD +_cdecl +main( + int argc, + char *argv[], + char *envp[] + ) +{ + + HANDLE iFile; + + iFile = CreateFile( + "testfile.txt", + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + assert(iFile != INVALID_HANDLE_VALUE); + + assert(LockFile(iFile,0,0,10,0)); + assert(LockFile(iFile,10,0,10,0)); + assert(!LockFile(iFile,1,0,1,0)); + assert(!LockFile(iFile,0,0,11,0)); + assert(!LockFile(iFile,0,0,20,0)); + assert(!UnlockFile(iFile,1,0,1,0)); + assert(!UnlockFile(iFile,0,0,11,0)); + assert(!UnlockFile(iFile,0,0,20,0)); + assert(UnlockFile(iFile,0,0,10,0)); + assert(UnlockFile(iFile,10,0,10,0)); + assert(LockFile(iFile,0,0,10,0)); + assert(LockFile(iFile,10,0,10,0)); + + Sleep(60 * 1000); + + CloseHandle(iFile); + + return 1; + +} diff --git a/private/nw/test/lock3.c b/private/nw/test/lock3.c new file mode 100644 index 000000000..eff9d0d55 --- /dev/null +++ b/private/nw/test/lock3.c @@ -0,0 +1,159 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + tfile.c + +Abstract: + + Test program for Win32 Base File API calls + +Author: + + Mark Lucovsky (markl) 26-Sep-1990 + +Revision History: + +--*/ + +#include <windows.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +VOID +TryLock( + int Type, + HANDLE Handle, + DWORD Offset, + DWORD StartOffset, + DWORD Range, + BOOL ExpectedResult + ); + +#define Lock 1 +#define Unlock 2 + +DWORD +_cdecl +main( + int argc, + char *argv[], + char *envp[] + ) +{ + + HANDLE iFile; + BOOL success; + STARTUPINFO startupInfo; + PROCESS_INFORMATION processInfo; + SECURITY_ATTRIBUTES security; + char commandLine[80]; + int offset; + + printf( "Number of arguments = %d\n", argc ); + + if ( argc == 1 ) { + + security.nLength = sizeof( security ); + security.lpSecurityDescriptor = NULL; + security.bInheritHandle = TRUE; + + iFile = CreateFile( + "testfile.txt", + GENERIC_READ, + FILE_SHARE_READ, + &security, + OPEN_EXISTING, + 0, + NULL + ); + + printf("Created file, handle = %d\n", iFile ); + + memset( &startupInfo, 0, sizeof( startupInfo ) ); + sprintf( commandLine, "%s %d\n", argv[0], iFile ); + + success = CreateProcess( + "D:\\444\\nt\\system32\\lock3.exe", + commandLine, + NULL, // Process security + NULL, // Thread security + TRUE, // Inherit Handles + 0, // Create flags + NULL, // Environment + NULL, // Current Directory + &startupInfo, + &processInfo ); + + if ( !success ) { + printf("Create process failed, err = %d\n", GetLastError() ); + } + offset = 0; + } else { + + iFile = (HANDLE)atoi( argv[1] ); + printf("Inherited file handle = %d\n", iFile ); + offset = 100; + } + + assert(iFile != INVALID_HANDLE_VALUE); + + TryLock( Lock, iFile, offset, 0, 10, TRUE ); + TryLock( Lock, iFile, offset, 10, 10, TRUE ); + TryLock( Lock, iFile, offset, 1, 1, FALSE ); + TryLock( Lock, iFile, offset, 0, 11, FALSE ); + TryLock( Lock, iFile, offset, 0, 20, FALSE ); + TryLock( Unlock, iFile, offset, 1, 1, FALSE ); + TryLock( Unlock, iFile, offset, 0, 12, FALSE ); + TryLock( Unlock, iFile, offset, 0, 20, FALSE ); + TryLock( Unlock, iFile, offset, 0, 10, TRUE ); + TryLock( Unlock, iFile, offset, 10, 10, TRUE ); + TryLock( Lock, iFile, offset, 0, 10, TRUE ); + TryLock( Lock, iFile, offset, 10, 10, TRUE ); + + Sleep(5 * argc * 1000); + + CloseHandle(iFile); + printf("Done\n"); + return 1; + +} + +VOID +TryLock( + int Type, + HANDLE Handle, + DWORD Offset, + DWORD StartOffset, + DWORD Range, + BOOL ExpectedResult + ) +{ + BOOL result; + DWORD err; + + if ( Type == Lock ) { + result = LockFile( Handle, StartOffset + Offset, 0, Range, 0 ); + } else { + result = UnlockFile( Handle, StartOffset + Offset, 0, Range, 0 ); + } + + if ( result == ExpectedResult ) { + return; + } else { + err = GetLastError(); + printf("Expected %d got %d for %slock at %d L%d\n", + ExpectedResult, result, + Type == Lock ? "" : "un", + StartOffset + Offset, Range ); + if ( !result ) { + printf("Unexpected error = %08lx\n", err ); + } + } +} + + + diff --git a/private/nw/test/lock4.c b/private/nw/test/lock4.c new file mode 100644 index 000000000..7ce0a3544 --- /dev/null +++ b/private/nw/test/lock4.c @@ -0,0 +1,157 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + tfile.c + +Abstract: + + Test program for Win32 Base File API calls + +Author: + + Mark Lucovsky (markl) 26-Sep-1990 + +Revision History: + +--*/ + +#include <windows.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +VOID +TryLock( + int Type, + HANDLE Handle, + DWORD Offset, + DWORD StartOffset, + DWORD Range, + BOOL ExpectedResult + ); + +#define Lock 1 +#define Unlock 2 + +DWORD +_cdecl +main( + int argc, + char *argv[], + char *envp[] + ) +{ + + HANDLE iFile; + int offset; + char *fileName; + + printf( "Number of arguments = %d\n", argc ); + + if ( argc >= 2 ) { + fileName = argv[1]; + } else { + fileName = "testfile.txt"; + } + + + iFile = CreateFile( + fileName, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if ( iFile != INVALID_HANDLE_VALUE ) { + printf("Opened file, handle = %d\n", iFile ); + } else { + printf("Failed to open %s, err = %d\n", fileName, GetLastError() ); + } + + if ( argc == 3 ) { + offset = atoi( argv[2] ); + } else { + offset = 0; + } + + printf("File offset = %d\n", offset ); + + TryLock( Lock, iFile, offset, 10, 10, TRUE ); // 10 - 19 + TryLock( Lock, iFile, offset, 10, 20, TRUE ); // 10 - 29 + TryLock( Lock, iFile, offset, 0, 30, TRUE ); // 0 - 29 +// TryLock( Lock, iFile, offset, 1, 1, FALSE ); +// TryLock( Lock, iFile, offset, 0, 11, FALSE ); +// TryLock( Lock, iFile, offset, 0, 20, FALSE ); +// TryLock( Unlock, iFile, offset, 1, 1, FALSE ); +// TryLock( Unlock, iFile, offset, 0, 12, FALSE ); +// TryLock( Unlock, iFile, offset, 0, 20, FALSE ); +// TryLock( Lock, iFile, offset, 0, 10, TRUE ); +// TryLock( Lock, iFile, offset, 10, 10, TRUE ); + +// Sleep(20 * 1000); + + TryLock( Unlock, iFile, offset, 0, 10, TRUE ); + TryLock( Unlock, iFile, offset, 10, 10, TRUE ); + + CloseHandle(iFile); + printf("Done\n"); + return 1; + +} + +VOID +TryLock( + int Type, + HANDLE Handle, + DWORD Offset, + DWORD StartOffset, + DWORD Range, + BOOL ExpectedResult + ) +{ + BOOL result; + DWORD err; + OVERLAPPED overlapped; + + if ( Type == Lock ) { + overlapped.Offset = StartOffset + Offset; + overlapped.OffsetHigh = 0; + result = LockFileEx( Handle, LOCKFILE_EXCLUSIVE_LOCK, 0, Range, 0, &overlapped ); + if (!result && GetLastError() == ERROR_IO_PENDING) { + err = WaitForSingleObject( Handle, INFINITE ); + if ( err == WAIT_OBJECT_0 ) { + err = overlapped.Internal; + } + + if ( err == 0 ) { + result = TRUE; + } else { + result = FALSE; + } + } + } else { + result = UnlockFile( Handle, StartOffset + Offset, 0, Range, 0 ); + } + + if ( result == ExpectedResult ) { + return; + } else { + err = GetLastError(); + printf("Expected %d got %d for %slock at %d L%d\n", + ExpectedResult, result, + Type == Lock ? "" : "un", + StartOffset + Offset, Range ); + if ( !result ) { + printf("Unexpected error = %08lx\n", err ); + } + } +} + + + diff --git a/private/nw/test/makefile b/private/nw/test/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/nw/test/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/nw/test/open.c b/private/nw/test/open.c new file mode 100644 index 000000000..fa3984438 --- /dev/null +++ b/private/nw/test/open.c @@ -0,0 +1,144 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + fileio.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=open'. + +Author: + + Manny Weiser (mannyw) 17-May-1993 + +Revision History: + +--*/ + +#include <stdio.h> +#include <string.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +// +// Local definitions +// + +VOID +DisplayUsage( + PSZ ProgramName + ); + + +BOOLEAN +OpenFile( + PSZ Name, + PHANDLE Handle + ); + + +cdecl +main( + int argc, + char *argv[], + ) +{ + HANDLE handle; + BOOLEAN success; + char *fileName; + + if ( argc == 1) { + DisplayUsage( argv[0] ); + return( 1 ); + } + + fileName = argv[1]; + + success = OpenFile( fileName, &handle ); + if ( !success) { + return 1; + } + + NtClose( handle ); + + printf( "%s exiting\n", argv[0]); + return 0; +} + + +VOID +DisplayUsage( + PSZ ProgramName + ) +{ + printf( "Usage: %s [filename]", ProgramName); +} + + +BOOLEAN +OpenFile( + PSZ Name, + PHANDLE Handle + ) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + STRING AnsiFileName; + UNICODE_STRING FileName; + + RtlInitString( &AnsiFileName, Name ); + RtlOemStringToUnicodeString( &FileName, &AnsiFileName, TRUE ); + + // + // Open the file + // + + InitializeObjectAttributes( + &objectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + status = NtOpenFile ( + Handle, + FILE_GENERIC_READ, + &objectAttributes, + &ioStatusBlock, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0L + ); + + if (!NT_SUCCESS(status) ) { + printf( "Open status = %x for file %Z\n", status, &FileName ); + } + + RtlFreeHeap(RtlProcessHeap(), 0, FileName.Buffer ); + return ( (BOOLEAN) NT_SUCCESS( status ) ); +} + + +DoSleep( + IN ULONG time + ) +{ + ULONG ms; + LARGE_INTEGER delayTime; + + ms = time * 100; + delayTime = RtlEnlargedIntegerMultiply( ms, -10000 ); + NtDelayExecution( TRUE, (PLARGE_INTEGER)&delayTime ); + + return( 0 ); +} + + diff --git a/private/nw/test/sources b/private/nw/test/sources new file mode 100644 index 000000000..f3f344158 --- /dev/null +++ b/private/nw/test/sources @@ -0,0 +1,44 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=ntos +MINORCOMP=nwrdr + +TARGETNAME=testnw +TARGETPATH=obj +TARGETTYPE=library + +UMTYPE=console +UMAPPL=testnw*attach*encrypt*lock2*userncp*lock3*fileio*lock4*getmsg*tex*open +UMLIBS= +UNICODE=1 +NTDEBUGTYPE=both +NTDEBUG=ntsd +386_OPTIMIZATION=/Od + +INCLUDES=..\inc;$(_NTROOT)\private\ntos\inc;$(_NTROOT)\private\inc;..\rdr + +SOURCES= + +USE_CL860_LARGE_MODEL=1 diff --git a/private/nw/test/testnw.c b/private/nw/test/testnw.c new file mode 100644 index 000000000..7c95555f1 --- /dev/null +++ b/private/nw/test/testnw.c @@ -0,0 +1,124 @@ +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#define WIN32_CONSOLE_APP +#include <windows.h> +#include <stdio.h> +#include <ntddnwfs.h> + +#define CANCEL + + +BOOLEAN test1(); + +int +_cdecl +main( + int argc, + char *argv[] + ) +{ + UCHAR error = FALSE; + DefineDosDevice(DDD_RAW_TARGET_PATH, "R:", "\\Device\\NwRdr\\R:\\NETWARE311"); + printf( "Test1...\n" ); + if (!test1()) { + printf("Error: Test 1 failed\n"); + error = TRUE; + } + return error; +} + + + +BOOLEAN +test1() +{ + HANDLE FileHandle; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING UnicodeString; + IO_STATUS_BLOCK IoStatus; + + NWR_REQUEST_PACKET Input; + + printf( "test 1: opening\n"); + + RtlInitUnicodeString( &UnicodeString, L"\\Device\\NwRdr" ); + + InitializeObjectAttributes( &ObjectAttributes, + &UnicodeString, + 0, + NULL, + NULL + ); +/* Status = NtCreateFile( &FileHandle, + FILE_LIST_DIRECTORY | SYNCHRONIZE, + &ObjectAttributes, + &IoStatus, + (PLARGE_INTEGER) NULL, + 0L, + 0L, + FILE_CREATE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT, + (PVOID) NULL, + 0L ); +*/ + Status = NtOpenFile ( &FileHandle, + FILE_LIST_DIRECTORY | SYNCHRONIZE, + &ObjectAttributes, + &IoStatus, + FILE_SHARE_READ, + FILE_DIRECTORY_FILE); + + if (Status != STATUS_SUCCESS) { + printf( "test 1: Wrong return value %X - open \n",Status); + return FALSE; + } + + if (IoStatus.Status != STATUS_SUCCESS) { + printf( "test 2: Wrong I/O Status value %X - open \n",IoStatus.Status); + return FALSE; + } + + printf( "test 1: opened device successfully\n"); + + Input.Version = REQUEST_PACKET_VERSION; + Input.Parameters.DebugValue.DebugFlags = 0xffffffff; + + NtFsControlFile( FileHandle, + NULL, + NULL, + NULL, + &IoStatus, + FSCTL_NWR_DEBUG, + &Input, + sizeof(Input), + NULL, + 0); + + if (Status != STATUS_SUCCESS) { + printf( "test 1: Wrong return value %X - SetDebug \n",Status); + return FALSE; + } + + if (IoStatus.Status != STATUS_SUCCESS) { + printf( "test 2: Wrong I/O Status value %X - SetDebug \n",IoStatus.Status); + return FALSE; + } + + printf( "test 1: set debug trace level successfully\n"); + + // + // Now close the device + // + + printf("test 1: closing device\n"); + + Status = NtClose( FileHandle ); + if (Status != STATUS_SUCCESS) { + printf( "test 1: Wrong return value %lX - close \n",Status); + return FALSE; + } + return TRUE; +} + 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 ); +} + + diff --git a/private/nw/test/tp1.c b/private/nw/test/tp1.c new file mode 100644 index 000000000..5ce2ebc57 --- /dev/null +++ b/private/nw/test/tp1.c @@ -0,0 +1,1637 @@ +/*++ + +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 <conio.h> +#include <stdio.h> +#include <string.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <ntddnwfs.h> +#include <STDARG.H> + +#define OT_USER 1 + + +// Hex dump +ULONG MaxDump = 256; + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ); + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ); + + +// End Hex dump + +VOID +ResetPassword( + PUCHAR Vnew + ); + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ); + +SendMessage( + IN char* Format, + ... + ); + +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 + ); + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ); + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ); + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ); + +#define BUFFER_SIZE 200 + +WCHAR *ServerName = L"YIHSINS3"; +UCHAR Pid = 255; +UCHAR Object[4]; + +WCHAR FileNameBuffer[100]; +UNICODE_STRING FileName; + +#define NW_USER "ANDYHE" + + +HANDLE ServerHandle; +_cdecl +main( + int argc, + char *argv[], + ) +{ + BOOLEAN success; + UCHAR Challenge[8]; + UCHAR fileValue[17]; + UCHAR ResponseP2[16]; + int x, y; + NTSTATUS status; + + +#if 0 + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + +#endif + +#define START_POSITION 0x00 + + UCHAR Vold[] = { +0x00,0x23,0x45,0x67,0x89,0xAB,0xCD,0x3F,0x00,0x24,0x45,0x67,0x89,0xAB,0xCD,0x4F,0x11, +0x00,0x23,0x45,0x67,0x29,0x2B,0xCD,0xEF,0x00,0x23,0x45,0x67,0x79,0x7B,0xCD,0xEF,0x11 + }; + + UCHAR Vc[] = { +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 +#if 0 + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +#endif + }; + + success = OpenServer( &ServerHandle, ServerName ); + if ( !success) { + return 1; + } + + printf("Opened server, %wS\n", ServerName ); + + // + // Setup the file name that we'll be opening every time. + // + + 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"\\" ); + status = RtlAppendUnicodeToString( &FileName, ServerName ); + status = RtlAppendUnicodeToString( &FileName, L"\\SYS:\\SYSTEM\\NET$VAL.SYS" ); + + // Get objectid + SendMessage( + "Swp", + 0x17, 0x35, + OT_USER, + NW_USER); + + ParseResponse("r", Object, 4 ); + + // jump into the middle of a run... + + x = 0; + y = START_POSITION * 17; + goto start; + + for ( x = 0 ; x < sizeof(Vold) ; x+= 17 ) { + + for ( y = 0 ; y < sizeof(Vc) ; y+= 17 ) { + +start: + // + // Set the password on the server to be the value of Vold required for + // the second part of the test. + // + + ResetPassword( Vold + x ); + + // + // We now know that Vold on the server is the same as the Vold vector. + // We can now set the password to any Vnew. + // We can do this without the real password because the + // server will believe we know the real password if we give it + // the result of taking Vold and the Challenge key and passing + // it through RespondToChallengePart2 + // + + printf( "Getting a challenge key.... " ); + + SendMessage( + "S", + 0x17, 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + // Fabricate the number the server will use to validate the password change + RespondToChallengePart2( Vold + x, Challenge, ResponseP2 ); + + printf( "Vold= " ); dump( Vold + x, 17); + + // Put out results to console... + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "File= " ); + dump( fileValue, 17); + } + printf( " Vc= "); dump( Vc + y, 17); + + printf( "Setting the new password... " ); + + // Send the set password + SendMessage("Srwpr", 0x17, 0x4b, + ResponseP2, 8, + OT_USER, + NW_USER, + Vc + y, 17 ); + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "Vnew= "); + dump( fileValue, 17); + } + +// printf( "Press a key...\n" ); getch(); + +// printf( "\n" ); + printf( "\n\n" ); + } + } + + printf( "%s exiting\n", argv[0]); + return 0; +} + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ) +// +// This routine reads the current password from the file. +// +{ + HANDLE fileHandle; + LARGE_INTEGER filePosition; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + int i; + PCHAR ch; + NTSTATUS status; + + ch = OutputValue; + for (i = 0; i < 17; i++) { + + *(ch++) = '0'; + } + + // Send a Close Bindery to the server + + printf( "Closing the bindery... " ); + + SendMessage( + "S", + 0x17, 0x44); + + // + // Open the server\sys:system\net$val.sys file which the server just + // closed. + // + + InitializeObjectAttributes( + &objectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + status = NtOpenFile ( + &fileHandle, + FILE_GENERIC_READ | SYNCHRONIZE, + &objectAttributes, + &ioStatusBlock, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0L + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Open failed. Status = 0x%x\n", status ); + + } else { + + // + // Seek to the spot in the file that has the supervisor's password. + // This will be different for different servers. Here's a table : + // ObjectID = Supervisor AndyHe + // Netware311 : 0x097C + // Mars312 : 0x16CC + // YihsinS3 : 0x59EA 0x050C + // + + filePosition.HighPart = 0L; + filePosition.LowPart = 0x050C; + + // Read the 17 bytes at that offset and close the file + + status = NtReadFile ( + fileHandle, + NULL, + NULL, + NULL, + &ioStatusBlock, + OutputValue, + 17, + &filePosition, + NULL + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Read failed. Status = 0x%x\n", status ); + } + + NtClose( fileHandle ); + } + + // Send an Open Bindery to the server + + printf( "Opening the bindery... " ); + SendMessage( + "S", + 0x17, 0x45); + + return(status); +} + +VOID +ResetPassword( + PUCHAR Vnew + ) +{ +// +// Note Vc[0] specifies the length. To derive new values of Vnew use the following +// table. For each nibble desired in Vnew, scan the appropriate column and +// read off the corresponding Vc nibble value on the left. +// + + UCHAR Vc[17]; + + UCHAR Challenge[8]; + OEM_STRING Password = {0,0,""}; + UCHAR EncryptKey[8]; + + int x; + + //printf( "Get Login key for set password using NULL password\n"); + + printf( "Getting a challenge key.... " ); + + SendMessage( + "S", + 0x17, 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + RespondToChallenge( Object, &Password, Challenge, EncryptKey ); + // dump( EncryptKey, 8); + + // + // Build Vc so that the server will get Vnew stored in the bindery. + // Note Vols/Vnew have the length at V[17] whereas Vc has it at Vc[0]. + // + + for ( x = 0 ; x < 16; x++ ) { + Vc[x+1] = LookUp( Vnew[x], 0xf0, x) | LookUp( Vnew[x], 0x0f, x); + } + + Vc[0] = LookUp( Vnew[16], 0xf0, 16) | LookUp( Vnew[16], 0x0f, 16); + + //printf( "Vnew "); dump( Vnew, 17); + //printf( "Vc "); dump( Vc, 17); + + // + // This uses the null password, objectid=1 and our supervisor privilege + // to set it, regardless of the and our ability to figure out what + // Vnew will be created for a particular Vc. + // + + printf( "Setting the old password... " ); + + SendMessage("Srwpr", 0x17, 0x4b, + EncryptKey, sizeof(EncryptKey), + OT_USER, + NW_USER, + Vc, 17 ); + + ParseResponse( "" ); +} + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ) +{ + +#if 0 + +UCHAR Vtab[] = { + + // This table is for the supervisor + +0x97, 0xE3, 0x73, 0xD8, 0x70, 0x5B, 0x85, 0xD3, 0xF5, 0xCD, 0xDB, 0xFA, 0xDC, 0xEB, 0x98, 0x64, 0x18, //0// +0x31, 0x6B, 0x88, 0x1E, 0x88, 0x09, 0x10, 0x29, 0x0B, 0x84, 0x61, 0x03, 0x43, 0xA1, 0xD5, 0x5A, 0x09, //1// +0xCB, 0xFF, 0x67, 0x70, 0xB6, 0xE3, 0x4E, 0x9A, 0x63, 0x27, 0x1A, 0x3C, 0x5A, 0x9A, 0x3B, 0xFC, 0x3A, //2// +0xEF, 0xA8, 0x44, 0x42, 0xDB, 0x1E, 0x59, 0x31, 0x17, 0xEB, 0xF5, 0x99, 0x18, 0x8E, 0x63, 0xAE, 0x2B, //3// +0x23, 0x07, 0xEB, 0xC9, 0xCD, 0xD6, 0xC7, 0xCF, 0xC8, 0xBF, 0x0F, 0xE2, 0x01, 0x16, 0x42, 0xD3, 0x1C, //4// +0x8A, 0xC4, 0x06, 0xB6, 0x51, 0xCA, 0x6F, 0xA7, 0x2E, 0x33, 0x82, 0xBD, 0x65, 0x58, 0xC0, 0xCB, 0x0D, //5// +0x0D, 0xBD, 0x5D, 0x65, 0x92, 0x77, 0x0D, 0x50, 0xAC, 0x79, 0x40, 0x86, 0x34, 0x45, 0x8F, 0x42, 0x3E, //6// +0x12, 0x8C, 0xA0, 0xAF, 0x07, 0xA1, 0xD3, 0x7D, 0x86, 0x5C, 0xA3, 0x2B, 0x80, 0x3F, 0x1D, 0x29, 0x2F, //7// +0x68, 0x15, 0xD1, 0x34, 0xE4, 0x2F, 0xF6, 0xFC, 0xEF, 0xDA, 0x5C, 0x57, 0xCF, 0xB4, 0x5A, 0x90, 0x10, //8// +0x7C, 0x49, 0xF2, 0x5A, 0xF3, 0x34, 0xBC, 0x88, 0x3A, 0x91, 0xB8, 0xC8, 0xAD, 0x03, 0x01, 0x77, 0x01, //9// +0xB0, 0x91, 0xBA, 0x23, 0x1E, 0x42, 0x72, 0xEB, 0xD2, 0xF8, 0x7E, 0x1E, 0xF7, 0x69, 0xE9, 0x0F, 0x32, //a// +0xA6, 0x32, 0x9C, 0x9D, 0x49, 0xB5, 0x98, 0x4E, 0x49, 0x00, 0xC9, 0x7F, 0x92, 0xC0, 0x2E, 0x3D, 0x23, //b// +0x54, 0x2A, 0x25, 0x07, 0x6C, 0x6C, 0xAA, 0xB2, 0xB1, 0x45, 0x27, 0xD4, 0x76, 0x27, 0xBC, 0xE8, 0x14, //c// +0xD9, 0xD0, 0xCE, 0x8C, 0x25, 0x98, 0xEB, 0x66, 0x74, 0x62, 0xE6, 0xA0, 0xEE, 0xFD, 0xF4, 0x86, 0x05, //d// +0xF5, 0x7E, 0x1F, 0xEB, 0x3F, 0xFD, 0x34, 0x04, 0x50, 0x16, 0x3D, 0x61, 0x29, 0xDC, 0xA7, 0xB5, 0x36, //e// +0x4E, 0x56, 0x39, 0xF1, 0xAA, 0x80, 0x21, 0x15, 0x9D, 0xAE, 0x94, 0x45, 0xBB, 0x72, 0x76, 0x11, 0x27 //f// +}; + +#endif + + +UCHAR Vtab[] = { + + // This table is for user AndyHe on Yihsins3, object id = 9000095 + +0xDC, 0x9D, 0xA3, 0x3C, 0x61, 0xCA, 0x98, 0xF2, 0xBB, 0xB5, 0xAE, 0x34, 0x04, 0x43, 0xB0, 0xC9, 0x1B, +0x3F, 0xF0, 0xCF, 0x12, 0x36, 0x49, 0xC1, 0x29, 0x93, 0x4E, 0x9A, 0x58, 0x52, 0xC8, 0x3D, 0x13, 0x0A, +0xC9, 0xBC, 0x9A, 0x26, 0x58, 0x7F, 0x1F, 0x4D, 0xD0, 0xA4, 0x77, 0xB7, 0xB8, 0x39, 0x72, 0xFB, 0x39, +0x7E, 0xDB, 0x66, 0x08, 0xDC, 0x51, 0x3A, 0x81, 0xFD, 0x8B, 0x2B, 0xC5, 0x8F, 0x8C, 0x49, 0x9D, 0x28, +0x4D, 0xA9, 0x25, 0xB4, 0xBB, 0x18, 0xF3, 0x3A, 0x86, 0x3D, 0x06, 0x23, 0x77, 0xAA, 0x1E, 0xD8, 0x1F, +0xA5, 0x43, 0xBC, 0x91, 0xC9, 0x0B, 0x79, 0xBF, 0xCF, 0xCC, 0x58, 0x00, 0xE5, 0x1F, 0xC1, 0x81, 0x0E, +0x83, 0x51, 0x01, 0x73, 0xEF, 0x27, 0x66, 0x13, 0x6C, 0x6F, 0xE4, 0x7F, 0xC9, 0x2D, 0x04, 0xBE, 0x3D, +0x21, 0xCF, 0x82, 0xF7, 0x93, 0xA6, 0x47, 0x76, 0x19, 0x06, 0x85, 0x4D, 0x4D, 0xFB, 0x23, 0x4F, 0x2C, +0x54, 0x3A, 0xFE, 0xED, 0x72, 0x9D, 0xBB, 0x65, 0x45, 0xE3, 0x3D, 0x61, 0x1B, 0x04, 0x6A, 0x37, 0x13, +0x18, 0x08, 0x47, 0x5E, 0x4A, 0xF0, 0xD0, 0x9E, 0x77, 0x9A, 0x69, 0x92, 0x31, 0x55, 0xD5, 0x0C, 0x02, +0xE0, 0x87, 0x3B, 0x85, 0x04, 0xB4, 0x55, 0xAB, 0x58, 0x22, 0xFF, 0xAB, 0xF0, 0x76, 0xF6, 0x74, 0x31, +0xF2, 0x15, 0xD9, 0xD9, 0xA0, 0xD3, 0x02, 0x0C, 0x01, 0xF0, 0xB1, 0xFE, 0x63, 0xD2, 0xEF, 0xE6, 0x20, +0x9B, 0x76, 0x70, 0x4B, 0x87, 0x65, 0xE4, 0xC8, 0x22, 0x59, 0xD0, 0x19, 0x9A, 0xB7, 0x88, 0x60, 0x17, +0xB7, 0xE4, 0xE4, 0xA0, 0x25, 0x3C, 0x8D, 0x50, 0xAE, 0x17, 0xC2, 0xEC, 0xAE, 0x90, 0xA7, 0x52, 0x06, +0x06, 0x2E, 0x18, 0x6F, 0xFD, 0x82, 0x2C, 0xE7, 0xE4, 0x78, 0x4C, 0xDA, 0xDC, 0xE1, 0x9C, 0xA5, 0x35, +0x6A, 0x62, 0x5D, 0xCA, 0x1E, 0xEE, 0xAE, 0xD4, 0x3A, 0xD1, 0x13, 0x86, 0x26, 0x6E, 0x5B, 0x2A, 0x24 +}; + +UCHAR Ch = Value & Mask; +int x; + +// +// Scan down the column of Vtab looking for a nibble that matches Ch +// return the index in the nibble indicated by Mask. +// + +for ( x = 0 ; x < 16 ; x++) { + + if ( (Vtab[ (x*17) + index] & Mask) == Ch ) { + + x |= x << 4; // Copy into both nibbles + return( x & Mask ); + + } +} + +printf(" Not found Value %x, Mask %x, Index %x\n", Value, Mask, index); +return( 0 ); + +} + +BOOLEAN +OpenServer( + PHANDLE Handle, + PWCH ServerName + ) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + WCHAR ServerNameBuffer[100]; + UNICODE_STRING ServerNameString; + + ServerNameString.Buffer = ServerNameBuffer; + ServerNameString.Length = 0; + ServerNameString.MaximumLength = 100; + + status = RtlAppendUnicodeToString( &ServerNameString, DD_NWFS_DEVICE_NAME_U ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, L"\\" ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, ServerName ); + ASSERT( status == STATUS_SUCCESS ); + + // + // Open the file + // + + InitializeObjectAttributes( + &objectAttributes, + &ServerNameString, + 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, &ServerName ); + } + + return ( (BOOLEAN) NT_SUCCESS( status ) ); +} + + +CHAR Buffer1[100]; +CHAR Buffer2[100]; + +SendMessage( + IN char* Format, + ... + ) +{ + NTSTATUS status = -1; + 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" ); + //dump( Buffer1, SendBufferSize + 1); + + status = NtFsControlFile( + ServerHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NWR_ANY_NCP(0x17), // packet already contains the code necessary + Buffer1 + 1, + SendBufferSize, + Buffer2, + ReceiveBufferSize + ); + if ( NT_SUCCESS( status ) ) { + + status = NtWaitForSingleObject( ServerHandle, FALSE, NULL ); + if ( NT_SUCCESS( status )) { + status = IoStatusBlock.Status; + } + } + + + if ( !NT_SUCCESS( status ) ) { + printf("SendPacket returns %08lx\n", status ); + } else { + printf("Send succeeded.\n" ); + //dump( Buffer2, IoStatusBlock.Information ); + } + 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 ); +} + + +// Hex dump + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ) +/*++ + +Routine Description: + Dump Min(len, MaxDump) bytes in classic hex dump style. + +Arguments: + + IN far_p - address of buffer to start dumping from. + + IN len - length in bytes of buffer. + +Return Value: + + None. + +--*/ +{ + ULONG l; + char s[80], t[80]; + PCHAR far_pchar = (PCHAR)far_p; + + if (len > MaxDump) + len = MaxDump; + + while (len) { + l = len < 17 ? len : 17; + + // printf("\n%lx ", far_pchar); + HexDumpLine (far_pchar, l, s, t, 0); + // printf("%s%.*s%s", s, 1 + ((16 - l) * 3), "", t); + printf("%s", s); + + len -= l; + far_pchar += l; + } + printf("\n"); +} + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ) +{ + static UCHAR rghex[] = "0123456789ABCDEF"; + + UCHAR c; + UCHAR *hex, *asc; + + + hex = s; + asc = t; + + *(asc++) = '*'; + while (len--) { + c = *(pch++); + *(hex++) = rghex [c >> 4] ; + *(hex++) = rghex [c & 0x0F]; + *(hex++) = ' '; + *(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c; + } + *(asc++) = '*'; + *asc = 0; + *hex = 0; + + flag; +} + +// End Hex dump + +UCHAR Table[] = +{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; + +UCHAR Keys[32] = +{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +#define XorArray( DEST, SRC ) { \ + PULONG D = (PULONG)DEST; \ + PULONG S = (PULONG)SRC; \ + int i; \ + for ( i = 0; i <= 7 ; i++ ) { \ + D[i] ^= S[i]; \ + } \ +} + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + Shuffle( &pChallenge[0], achBuf, 16, &achK[0] ); + Shuffle( &pChallenge[4], achBuf, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 16 byte response held by the server + +Return Value: + + none. + +--*/ + +{ + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + memmove(pResponse, achBuf, 16); +} + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the result of Shuffling the ObjectId and the Password + and processes it with a challenge key. + +Arguments: + IN PUCHAR pResponsePart1 - Supplies the 16 byte output of + RespondToChallengePart1. + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + + Shuffle( &pChallenge[0], pResponsePart1, 16, &achK[0] ); + Shuffle( &pChallenge[4], pResponsePart1, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ) + +/*++ + +Routine Description: + + This routine shuffles around the object ID with the password + +Arguments: + + IN achObjectId - Supplies the 4 byte user's bindery object id + + IN szUpperPassword - Supplies the user's uppercased password on the + first call to process the password. On the second and third calls + this parameter contains the OutputBuffer from the first call + + IN iPasswordLen - length of uppercased password + + OUT achOutputBuffer - Returns the 8 byte sub-calculation + +Return Value: + + none. + +--*/ + +{ + int iTempIndex; + int iOutputIndex; + UCHAR achTemp[32]; + + // + // Initialize the achTemp buffer. Initialization consists of taking + // the password and dividing it up into chunks of 32. Any bytes left + // over are the remainder and do not go into the initialization. + // + // achTemp[0] = szUpperPassword[0] ^ szUpperPassword[32] ^ szUpper... + // achTemp[1] = szUpperPassword[1] ^ szUpperPassword[33] ^ szUpper... + // etc. + // + + if ( iPasswordLen > 32) { + + // At least one chunk of 32. Set the buffer to the first chunk. + + RtlCopyMemory( achTemp, szUpperPassword, 32 ); + + szUpperPassword +=32; // Remove the first chunk + iPasswordLen -=32; + + while ( iPasswordLen >= 32 ) { + // + // Xor this chunk with the characters already loaded into + // achTemp. + // + + XorArray( achTemp, szUpperPassword); + + szUpperPassword +=32; // Remove this chunk + iPasswordLen -=32; + } + + } else { + + // No chunks of 32 so set the buffer to zero's + + RtlZeroMemory( achTemp, sizeof(achTemp)); + + } + + // + // achTemp is now initialized. Load the remainder into achTemp. + // The remainder is repeated to fill achTemp. + // + // The corresponding character from Keys is taken to seperate + // each repitition. + // + // As an example, take the remainder "ABCDEFG". The remainder is expanded + // to "ABCDEFGwABCDEFGxABCDEFGyABCDEFGz" where w is Keys[7], + // x is Keys[15], y is Keys[23] and z is Keys[31]. + // + // + + if (iPasswordLen > 0) { + int iPasswordOffset = 0; + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) { + + if (iPasswordLen == iPasswordOffset) { + iPasswordOffset = 0; + achTemp[iTempIndex] ^= Keys[iTempIndex]; + } else { + achTemp[iTempIndex] ^= szUpperPassword[iPasswordOffset++]; + } + } + } + + // + // achTemp has been loaded with the users password packed into 32 + // bytes. Now take the objectid that came from the server and use + // that to munge every byte in achTemp. + // + + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) + achTemp[iTempIndex] ^= achObjectId[ iTempIndex & 3]; + + Scramble( Scramble( 0, achTemp ), achTemp ); + + // + // Finally take pairs of bytes in achTemp and return the two + // nibbles obtained from Table. The pairs of bytes used + // are achTemp[n] and achTemp[n+16]. + // + + for (iOutputIndex = 0; iOutputIndex < 16; iOutputIndex++) { + + achOutputBuffer[iOutputIndex] = + Table[achTemp[iOutputIndex << 1]] | + (Table[achTemp[(iOutputIndex << 1) + 1]] << 4); + } + + return; +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ) + +/*++ + +Routine Description: + + This routine scrambles around the contents of the buffer. Each buffer + position is updated to include the contents of at least two character + positions plus an EncryptKey value. The buffer is processed left to right + and so if a character position chooses to merge with a buffer position + to its left then this buffer position will include bits derived from at + least 3 bytes of the original buffer contents. + +Arguments: + + IN iSeed + IN OUT achBuffer[32] + +Return Value: + + none. + +--*/ + +{ + int iBufferIndex; + + for (iBufferIndex = 0; iBufferIndex < 32; iBufferIndex++) { + achBuffer[iBufferIndex] = + (UCHAR)( + ((UCHAR)(achBuffer[iBufferIndex] + iSeed)) ^ + ((UCHAR)( achBuffer[(iBufferIndex+iSeed) & 31] - + Keys[iBufferIndex] ))); + + iSeed += achBuffer[iBufferIndex]; + } + return iSeed; +} + +#if 0 + +// this data was gathered for object id = 9000095 from yihsins3 with +// this program by reseting the password to null manually and then +// sending over the specified Vc + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Vnew= DC 9D A3 3C 61 CA 98 F2 BB B5 AE 34 04 43 B0 C9 1B + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 +Vnew= 3F F0 CF 12 36 49 C1 29 93 4E 9A 58 52 C8 3D 13 0A + +File= 3F F0 CF 12 36 49 C1 29 93 4E 9A 58 52 C8 3D 13 0A + Vc= 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 +Vnew= C9 BC 9A 26 58 7F 1F 4D D0 A4 77 B7 B8 39 72 FB 39 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 +Vnew= 7E DB 66 08 DC 51 3A 81 FD 8B 2B C5 8F 8C 49 9D 28 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 +Vnew= 4D A9 25 B4 BB 18 F3 3A 86 3D 06 23 77 AA 1E D8 1F + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +Vnew= A5 43 BC 91 C9 0B 79 BF CF CC 58 00 E5 1F C1 81 0E + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 +Vnew= 83 51 01 73 EF 27 66 13 6C 6F E4 7F C9 2D 04 BE 3D + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 +Vnew= 21 CF 82 F7 93 A6 47 76 19 06 85 4D 4D FB 23 4F 2C + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 +Vnew= 54 3A FE ED 72 9D BB 65 45 E3 3D 61 1B 04 6A 37 13 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 +Vnew= 18 08 47 5E 4A F0 D0 9E 77 9A 69 92 31 04 6A 37 02 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA +Vnew= E0 87 3B 85 04 B4 55 AB 58 22 FF AB F0 76 F6 74 31 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB +Vnew= F2 15 D9 D9 A0 D3 02 0C 01 F0 B1 FE 63 D2 EF E6 20 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC +Vnew= 9B 76 70 4B 87 65 E4 C8 22 59 D0 19 9A B7 88 60 17 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD +Vnew= B7 E4 E4 A0 25 3C 8D 50 AE 17 C2 EC AE 90 A7 52 06 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE +Vnew= 06 2E 18 6F FD 82 2C E7 E4 78 4C DA DC E1 9C A5 35 + +File= 06 2E 18 6F FD 82 2C E7 E4 78 4C DA DC E1 9C A5 35 + Vc= FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +Vnew= 6A 62 5D CA 1E EE AE D4 3A D1 13 86 26 6E 5B 2A 24 + + +0xEA, 0x91, 0x6C, 0x3D, 0xAB, 0x59, 0xB9, 0xBD, 0xB2, 0x7B, 0x4C, 0x , 0x , 0x , 0x , 0x , 0x , //0// +0x97, 0xB6, 0xE6, 0x15, 0xF0, 0x43, 0x21, 0x63, 0x7B, 0xDF, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //1// +0x7B, 0xEF, 0x47, 0x21, 0xD8, 0x6E, 0xEB, 0x10, 0xCC, 0xAA, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //2// +0x16, 0x85, 0xA0, 0x06, 0x17, 0xDB, 0x34, 0x46, 0xF1, 0x48, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //3// +0x48, 0x5D, 0x9D, 0xC4, 0x9A, 0x1A, 0x7C, 0x2F, 0x8E, 0x12, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //4// +0x85, 0x6B, 0xF4, 0x9A, 0x2D, 0x3C, 0xAA, 0xD8, 0xA8, 0xC0, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //5// +0xFE, 0xFC, 0x33, 0xE2, 0x01, 0xC7, 0x66, 0x87, 0x64, 0x67, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //6// +0x3D, 0xCA, 0xC9, 0x67, 0x8C, 0x26, 0x57, 0x7E, 0x99, 0xED, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //7// +0x69, 0xA9, 0x7E, 0xA3, 0xC2, 0xE4, 0xD0, 0x3C, 0x4A, 0x3E, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //8// +0xC2, 0x04, 0x2B, 0x5B, 0x75, 0x81, 0x05, 0x91, 0x17, 0x9C, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //9// +0x5F, 0x48, 0x02, 0xDF, 0xB9, 0x70, 0xF3, 0xA4, 0xDF, 0x29, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //A// +0xDC, 0x23, 0x5A, 0x4C, 0x44, 0xA5, 0x88, 0x5A, 0x00, 0x03, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //B// +0x20, 0x72, 0x15, 0xF0, 0x53, 0x0D, 0x1E, 0xCB, 0x56, 0x55, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //C// +0x04, 0x30, 0xBF, 0xB8, 0x3E, 0xB8, 0x9D, 0xF2, 0x23, 0xF4, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //D// +0xA3, 0xDE, 0xD8, 0x89, 0x6F, 0xFF, 0xF3, 0xE9, 0xED, 0x81, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //E// +0xB1, 0x17, 0x81, 0x7E, 0xE6, 0x92, 0x42, 0x05, 0x35, 0xB6, 0x , 0x , 0x , 0x , 0x , 0x , 0x //F// + }; + 00 = AE 34 04 43 B0 C9 1B + 11 = 9A 58 52 C8 3D 13 0A + 22 = 77 B7 B8 39 72 FB 39 + 33 = 2B C5 8F 8C 49 9D 28 + 44 = 06 23 77 AA 1E D8 1F + 55 = 58 00 E5 1F C1 81 0E + 66 = E4 7F C9 2D 04 BE 3D + 77 = 85 4D 4D FB 23 4F 2C + 88 = 3D 61 1B 04 6A 37 13 + 99 = 69 92 31 55 D5 0C 02 + AA = FF AB F0 76 F6 74 31 + BB = B1 FE 63 D2 EF E6 20 + CC = D0 19 9A B7 88 60 17 + DD = C2 EC AE 90 A7 52 06 + EE = 4C DA DC E1 9C A5 35 + FF = 13 86 26 6E 5B 2A 24 + + + + +#endif + diff --git a/private/nw/test/tp2.c b/private/nw/test/tp2.c new file mode 100644 index 000000000..004161df8 --- /dev/null +++ b/private/nw/test/tp2.c @@ -0,0 +1,1560 @@ +/*++ + +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 <conio.h> +#include <stdio.h> +#include <string.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <ntddnwfs.h> +#include <ntddnwp.h> +#include <STDARG.H> + +#define OT_USER 1 + + +// Hex dump +ULONG MaxDump = 256; + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ); + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ); + + +// End Hex dump + +VOID +ResetPassword( + PUCHAR Vnew + ); + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ); + +SendMessage( + IN char* Format, + ... + ); + +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 + ); + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ); + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ); + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ); + +#define BUFFER_SIZE 200 + +WCHAR *ServerName = L"NETWARE311"; +UCHAR Pid = 255; +UCHAR Object[4]; + +WCHAR FileNameBuffer[100]; +UNICODE_STRING FileName; + + +HANDLE ServerHandle; +_cdecl +main( + int argc, + char *argv[], + ) +{ + BOOLEAN success; + UCHAR Challenge[8]; + UCHAR fileValue[17]; + UCHAR ResponseP2[16]; + int x, y; + NTSTATUS status; + + +#if 0 + UCHAR Vold[] = { + 0x31, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x31, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, + 0x32, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x11, + 0x32, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x11, + 0x23, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x22, + 0x54, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, + 0x54, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, + 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x11, + 0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x22, + 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x11, + 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x22, + 0xF7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x11, + 0xF7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x22, + 0x98, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x11, + 0x98, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x22, + 0x89, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x11, + 0x89, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x22, + 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x11, + 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x22, + 0xab, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x11, + 0xab, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x22, + 0xdc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x11, + 0xdc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x22, + 0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x11, + 0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x22, + 0xfe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x11, + 0xfe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x22, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22 }; + + + UCHAR Vc[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +#endif + + UCHAR Vold[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xfe, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xfe, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x22, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x11, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x22 }; + + UCHAR Vc[] = { + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; + + + success = OpenServer( &ServerHandle, ServerName ); + if ( !success) { + return 1; + } + + printf("Opened server, %wS\n", ServerName ); + + // + // Setup the file name that we'll be opening every time. + // + + 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"\\" ); + status = RtlAppendUnicodeToString( &FileName, ServerName ); + status = RtlAppendUnicodeToString( &FileName, L"\\SYS:\\SYSTEM\\NET$VAL.SYS" ); + + // Get objectid + SendMessage( + "Swp", + 0x17, 0x35, + OT_USER, + "SUPERVISOR"); + + ParseResponse("r", Object, 4 ); + + for ( x = 0 ; x < sizeof(Vold) ; x+= 17 ) { + + for ( y = 0 ; y < sizeof(Vc) ; y+= 17 ) { + + // + // Set the password on the server to be the value of Vold required for + // the second part of the test. + // + + ResetPassword( Vold + x ); + + // + // We now know that Vold on the server is the same as the Vold vector. + // We can now set the password to any Vnew. + // We can do this without the real password because the + // server will believe we know the real password if we give it + // the result of taking Vold and the Challenge key and passing + // it through RespondToChallengePart2 + // + + printf( "Getting a challenge key.... " ); + + SendMessage( + "S", + 0x17, 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + // Fabricate the number the server will use to validate the password change + RespondToChallengePart2( Vold + x, Challenge, ResponseP2 ); + + printf( "Vold= " ); dump( Vold + x, 17); + + // Put out results to console... + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "File= " ); + dump( fileValue, 17); + } + printf( " Vc= "); dump( Vc + y, 17); + + printf( "Setting the new password... " ); + + // Send the set password + SendMessage("Srwpr", 0x17, 0x4b, + ResponseP2, 8, + OT_USER, + "SUPERVISOR", + Vc + y, 17 ); + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "Vnew= "); + dump( fileValue, 17); + } + + printf( "\n\n" ); + } + } + + printf( "%s exiting\n", argv[0]); + return 0; +} + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ) +// +// This routine reads the current password from the file. +// +{ + HANDLE fileHandle; + LARGE_INTEGER filePosition; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + int i; + PCHAR ch; + NTSTATUS status; + + ch = OutputValue; + for (i = 0; i < 17; i++) { + + *(ch++) = '0'; + } + + // Send a Close Bindery to the server + + printf( "Closing the bindery... " ); + + SendMessage( + "S", + 0x17, 0x44); + + // + // Open the server\sys:system\net$val.sys file which the server just + // closed. + // + + InitializeObjectAttributes( + &objectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + status = NtOpenFile ( + &fileHandle, + FILE_GENERIC_READ | SYNCHRONIZE, + &objectAttributes, + &ioStatusBlock, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0L + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Open failed. Status = 0x%x\n", status ); + + } else { + + // + // Seek to the spot in the file that has the supervisor's password. + // This will be different for different servers. Here's a table : + // + // Netware311 : 0x097C + // + + filePosition.HighPart = 0L; + filePosition.LowPart = 0x097C; + + // Read the 17 bytes at that offset and close the file + + status = NtReadFile ( + fileHandle, + NULL, + NULL, + NULL, + &ioStatusBlock, + OutputValue, + 17, + &filePosition, + NULL + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Read failed. Status = 0x%x\n", status ); + } + + NtClose( fileHandle ); + } + + // Send an Open Bindery to the server + + printf( "Opening the bindery... " ); + SendMessage( + "S", + 0x17, 0x45); + + return(status); +} + +VOID +ResetPassword( + PUCHAR Vnew + ) +{ +// +// Note Vc[0] specifies the length. To derive new values of Vnew use the following +// table. For each nibble desired in Vnew, scan the appropriate column and +// read off the corresponding Vc nibble value on the left. +// + + UCHAR Vc[17]; + + UCHAR Challenge[8]; + OEM_STRING Password = {0,0,""}; + UCHAR EncryptKey[8]; + + int x; + + //printf( "Get Login key for set password using NULL password\n"); + + printf( "Getting a challenge key.... " ); + + SendMessage( + "S", + 0x17, 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + RespondToChallenge( Object, &Password, Challenge, EncryptKey ); + // dump( EncryptKey, 8); + + // + // Build Vc so that the server will get Vnew stored in the bindery. + // Note Vols/Vnew have the length at V[17] whereas Vc has it at Vc[0]. + // + + for ( x = 0 ; x < 16; x++ ) { + Vc[x+1] = LookUp( Vnew[x], 0xf0, x) | LookUp( Vnew[x], 0x0f, x); + } + + Vc[0] = LookUp( Vnew[16], 0xf0, 16) | LookUp( Vnew[16], 0x0f, 16); + + //printf( "Vnew "); dump( Vnew, 17); + //printf( "Vc "); dump( Vc, 17); + + // + // This uses the null password, objectid=1 and our supervisor privilege + // to set it, regardless of the and our ability to figure out what + // Vnew will be created for a particular Vc. + // + + printf( "Setting the old password... " ); + + SendMessage("Srwpr", 0x17, 0x4b, + EncryptKey, sizeof(EncryptKey), + OT_USER, + "SUPERVISOR", + Vc, 17 ); + + ParseResponse( "" ); +} + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ) +{ +UCHAR Vtab[] = { + +0x97, 0xE3, 0x73, 0xD8, 0x70, 0x5B, 0x85, 0xD3, 0xF5, 0xCD, 0xDB, 0xFA, 0xDC, 0xEB, 0x98, 0x64, 0x18, //0// +0x31, 0x6B, 0x88, 0x1E, 0x88, 0x09, 0x10, 0x29, 0x0B, 0x84, 0x61, 0x03, 0x43, 0xA1, 0xD5, 0x5A, 0x09, //1// +0xCB, 0xFF, 0x67, 0x70, 0xB6, 0xE3, 0x4E, 0x9A, 0x63, 0x27, 0x1A, 0x3C, 0x5A, 0x9A, 0x3B, 0xFC, 0x3A, //2// +0xEF, 0xA8, 0x44, 0x42, 0xDB, 0x1E, 0x59, 0x31, 0x17, 0xEB, 0xF5, 0x99, 0x18, 0x8E, 0x63, 0xAE, 0x2B, //3// +0x23, 0x07, 0xEB, 0xC9, 0xCD, 0xD6, 0xC7, 0xCF, 0xC8, 0xBF, 0x0F, 0xE2, 0x01, 0x16, 0x42, 0xD3, 0x1C, //4// +0x8A, 0xC4, 0x06, 0xB6, 0x51, 0xCA, 0x6F, 0xA7, 0x2E, 0x33, 0x82, 0xBD, 0x65, 0x58, 0xC0, 0xCB, 0x0D, //5// +0x0D, 0xBD, 0x5D, 0x65, 0x92, 0x77, 0x0D, 0x50, 0xAC, 0x79, 0x40, 0x86, 0x34, 0x45, 0x8F, 0x42, 0x3E, //6// +0x12, 0x8C, 0xA0, 0xAF, 0x07, 0xA1, 0xD3, 0x7D, 0x86, 0x5C, 0xA3, 0x2B, 0x80, 0x3F, 0x1D, 0x29, 0x2F, //7// +0x68, 0x15, 0xD1, 0x34, 0xE4, 0x2F, 0xF6, 0xFC, 0xEF, 0xDA, 0x5C, 0x57, 0xCF, 0xB4, 0x5A, 0x90, 0x10, //8// +0x7C, 0x49, 0xF2, 0x5A, 0xF3, 0x34, 0xBC, 0x88, 0x3A, 0x91, 0xB8, 0xC8, 0xAD, 0x03, 0x01, 0x77, 0x01, //9// +0xB0, 0x91, 0xBA, 0x23, 0x1E, 0x42, 0x72, 0xEB, 0xD2, 0xF8, 0x7E, 0x1E, 0xF7, 0x69, 0xE9, 0x0F, 0x32, //a// +0xA6, 0x32, 0x9C, 0x9D, 0x49, 0xB5, 0x98, 0x4E, 0x49, 0x00, 0xC9, 0x7F, 0x92, 0xC0, 0x2E, 0x3D, 0x23, //b// +0x54, 0x2A, 0x25, 0x07, 0x6C, 0x6C, 0xAA, 0xB2, 0xB1, 0x45, 0x27, 0xD4, 0x76, 0x27, 0xBC, 0xE8, 0x14, //c// +0xD9, 0xD0, 0xCE, 0x8C, 0x25, 0x98, 0xEB, 0x66, 0x74, 0x62, 0xE6, 0xA0, 0xEE, 0xFD, 0xF4, 0x86, 0x05, //d// +0xF5, 0x7E, 0x1F, 0xEB, 0x3F, 0xFD, 0x34, 0x04, 0x50, 0x16, 0x3D, 0x61, 0x29, 0xDC, 0xA7, 0xB5, 0x36, //e// +0x4E, 0x56, 0x39, 0xF1, 0xAA, 0x80, 0x21, 0x15, 0x9D, 0xAE, 0x94, 0x45, 0xBB, 0x72, 0x76, 0x11, 0x27 //f// +}; + +UCHAR Ch = Value & Mask; +int x; + +// +// Scan down the column of Vtab looking for a nibble that matches Ch +// return the index in the nibble indicated by Mask. +// + +for ( x = 0 ; x < 16 ; x++) { + + if ( (Vtab[ (x*17) + index] & Mask) == Ch ) { + + x |= x << 4; // Copy into both nibbles + return( x & Mask ); + + } +} + +printf(" Not found Value %x, Mask %x, Index %x\n", Value, Mask, index); +return( 0 ); + +} + +BOOLEAN +OpenServer( + PHANDLE Handle, + PWCH ServerName + ) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + WCHAR ServerNameBuffer[100]; + UNICODE_STRING ServerNameString; + + ServerNameString.Buffer = ServerNameBuffer; + ServerNameString.Length = 0; + ServerNameString.MaximumLength = 100; + + status = RtlAppendUnicodeToString( &ServerNameString, DD_NWFS_DEVICE_NAME_U ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, L"\\" ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, ServerName ); + ASSERT( status == STATUS_SUCCESS ); + + // + // Open the file + // + + InitializeObjectAttributes( + &objectAttributes, + &ServerNameString, + 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, &ServerName ); + } + + return ( (BOOLEAN) NT_SUCCESS( status ) ); +} + + +CHAR Buffer1[100]; +CHAR Buffer2[100]; + +SendMessage( + IN char* Format, + ... + ) +{ + NTSTATUS status = -1; + 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" ); + //dump( Buffer1, SendBufferSize + 1); + + 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("SendPacket returns %08lx\n", status ); + } else { + printf("Send succeeded.\n" ); + //dump( Buffer2, IoStatusBlock.Information ); + } + 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 ); +} + + +// Hex dump + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ) +/*++ + +Routine Description: + Dump Min(len, MaxDump) bytes in classic hex dump style. + +Arguments: + + IN far_p - address of buffer to start dumping from. + + IN len - length in bytes of buffer. + +Return Value: + + None. + +--*/ +{ + ULONG l; + char s[80], t[80]; + PCHAR far_pchar = (PCHAR)far_p; + + if (len > MaxDump) + len = MaxDump; + + while (len) { + l = len < 17 ? len : 17; + + // printf("\n%lx ", far_pchar); + HexDumpLine (far_pchar, l, s, t, 0); + // printf("%s%.*s%s", s, 1 + ((16 - l) * 3), "", t); + printf("%s", s); + + len -= l; + far_pchar += l; + } + printf("\n"); +} + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ) +{ + static UCHAR rghex[] = "0123456789ABCDEF"; + + UCHAR c; + UCHAR *hex, *asc; + + + hex = s; + asc = t; + + *(asc++) = '*'; + while (len--) { + c = *(pch++); + *(hex++) = rghex [c >> 4] ; + *(hex++) = rghex [c & 0x0F]; + *(hex++) = ' '; + *(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c; + } + *(asc++) = '*'; + *asc = 0; + *hex = 0; + + flag; +} + +// End Hex dump + +UCHAR Table[] = +{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; + +UCHAR Keys[32] = +{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +#define XorArray( DEST, SRC ) { \ + PULONG D = (PULONG)DEST; \ + PULONG S = (PULONG)SRC; \ + int i; \ + for ( i = 0; i <= 7 ; i++ ) { \ + D[i] ^= S[i]; \ + } \ +} + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + Shuffle( &pChallenge[0], achBuf, 16, &achK[0] ); + Shuffle( &pChallenge[4], achBuf, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 16 byte response held by the server + +Return Value: + + none. + +--*/ + +{ + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + memmove(pResponse, achBuf, 16); +} + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the result of Shuffling the ObjectId and the Password + and processes it with a challenge key. + +Arguments: + IN PUCHAR pResponsePart1 - Supplies the 16 byte output of + RespondToChallengePart1. + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + + Shuffle( &pChallenge[0], pResponsePart1, 16, &achK[0] ); + Shuffle( &pChallenge[4], pResponsePart1, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ) + +/*++ + +Routine Description: + + This routine shuffles around the object ID with the password + +Arguments: + + IN achObjectId - Supplies the 4 byte user's bindery object id + + IN szUpperPassword - Supplies the user's uppercased password on the + first call to process the password. On the second and third calls + this parameter contains the OutputBuffer from the first call + + IN iPasswordLen - length of uppercased password + + OUT achOutputBuffer - Returns the 8 byte sub-calculation + +Return Value: + + none. + +--*/ + +{ + int iTempIndex; + int iOutputIndex; + UCHAR achTemp[32]; + + // + // Initialize the achTemp buffer. Initialization consists of taking + // the password and dividing it up into chunks of 32. Any bytes left + // over are the remainder and do not go into the initialization. + // + // achTemp[0] = szUpperPassword[0] ^ szUpperPassword[32] ^ szUpper... + // achTemp[1] = szUpperPassword[1] ^ szUpperPassword[33] ^ szUpper... + // etc. + // + + if ( iPasswordLen > 32) { + + // At least one chunk of 32. Set the buffer to the first chunk. + + RtlCopyMemory( achTemp, szUpperPassword, 32 ); + + szUpperPassword +=32; // Remove the first chunk + iPasswordLen -=32; + + while ( iPasswordLen >= 32 ) { + // + // Xor this chunk with the characters already loaded into + // achTemp. + // + + XorArray( achTemp, szUpperPassword); + + szUpperPassword +=32; // Remove this chunk + iPasswordLen -=32; + } + + } else { + + // No chunks of 32 so set the buffer to zero's + + RtlZeroMemory( achTemp, sizeof(achTemp)); + + } + + // + // achTemp is now initialized. Load the remainder into achTemp. + // The remainder is repeated to fill achTemp. + // + // The corresponding character from Keys is taken to seperate + // each repitition. + // + // As an example, take the remainder "ABCDEFG". The remainder is expanded + // to "ABCDEFGwABCDEFGxABCDEFGyABCDEFGz" where w is Keys[7], + // x is Keys[15], y is Keys[23] and z is Keys[31]. + // + // + + if (iPasswordLen > 0) { + int iPasswordOffset = 0; + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) { + + if (iPasswordLen == iPasswordOffset) { + iPasswordOffset = 0; + achTemp[iTempIndex] ^= Keys[iTempIndex]; + } else { + achTemp[iTempIndex] ^= szUpperPassword[iPasswordOffset++]; + } + } + } + + // + // achTemp has been loaded with the users password packed into 32 + // bytes. Now take the objectid that came from the server and use + // that to munge every byte in achTemp. + // + + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) + achTemp[iTempIndex] ^= achObjectId[ iTempIndex & 3]; + + Scramble( Scramble( 0, achTemp ), achTemp ); + + // + // Finally take pairs of bytes in achTemp and return the two + // nibbles obtained from Table. The pairs of bytes used + // are achTemp[n] and achTemp[n+16]. + // + + for (iOutputIndex = 0; iOutputIndex < 16; iOutputIndex++) { + + achOutputBuffer[iOutputIndex] = + Table[achTemp[iOutputIndex << 1]] | + (Table[achTemp[(iOutputIndex << 1) + 1]] << 4); + } + + return; +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ) + +/*++ + +Routine Description: + + This routine scrambles around the contents of the buffer. Each buffer + position is updated to include the contents of at least two character + positions plus an EncryptKey value. The buffer is processed left to right + and so if a character position chooses to merge with a buffer position + to its left then this buffer position will include bits derived from at + least 3 bytes of the original buffer contents. + +Arguments: + + IN iSeed + IN OUT achBuffer[32] + +Return Value: + + none. + +--*/ + +{ + int iBufferIndex; + + for (iBufferIndex = 0; iBufferIndex < 32; iBufferIndex++) { + achBuffer[iBufferIndex] = + (UCHAR)( + ((UCHAR)(achBuffer[iBufferIndex] + iSeed)) ^ + ((UCHAR)( achBuffer[(iBufferIndex+iSeed) & 31] - + Keys[iBufferIndex] ))); + + iSeed += achBuffer[iBufferIndex]; + } + return iSeed; +} + diff --git a/private/nw/test/tp3.c b/private/nw/test/tp3.c new file mode 100644 index 000000000..f33ffc123 --- /dev/null +++ b/private/nw/test/tp3.c @@ -0,0 +1,1715 @@ +/*++ + +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 <conio.h> +#include <stdio.h> +#include <string.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <ntddnwfs.h> +#include <STDARG.H> + +#define OT_USER 1 + + +// Hex dump +ULONG MaxDump = 256; + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ); + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ); + + +// End Hex dump + +VOID +ResetPassword( + PUCHAR Vnew + ); + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ); + +SendMessage( + IN char* Format, + ... + ); + +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 + ); + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ); + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ); + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ); + +#define BUFFER_SIZE 200 + +WCHAR *ServerName = L"YIHSINS3"; +UCHAR Pid = 255; +UCHAR Object[4]; + +WCHAR FileNameBuffer[100]; +UNICODE_STRING FileName; + +#define NW_USER "ANDYHE" + + +HANDLE ServerHandle; +_cdecl +main( + int argc, + char *argv[] + ) +{ + BOOLEAN success; + UCHAR Challenge[8]; + UCHAR fileValue[17]; + UCHAR ResponseP2[16]; + int x, y; + NTSTATUS status; + + +#if 0 + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + +#endif + +#define START_POSITION 0x00 + + UCHAR Vold[] = { +0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x11, +0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x10, 0xe0, 0x00, 0x00, 0x11, +0x00, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x20, 0xd0, 0x00, 0x00, 0x11, +0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 0x11, +0x00, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x40, 0xb0, 0x00, 0x00, 0x11, +0x00, 0x05, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x50, 0xa0, 0x00, 0x00, 0x11, +0x00, 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x60, 0x90, 0x00, 0x00, 0x11, +0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x11, +0x00, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x00, 0x00, 0x11, +0x00, 0x09, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x90, 0x60, 0x00, 0x00, 0x11, +0x00, 0x0a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xa0, 0x50, 0x00, 0x00, 0x11, +0x00, 0x0b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xb0, 0x40, 0x00, 0x00, 0x11, +0x00, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x00, 0x00, 0x11, +0x00, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xd0, 0x20, 0x00, 0x00, 0x11, +0x00, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x00, 0x00, 0x11, +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x11, +0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00, 0x11, +0x50, 0x61, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x10, 0x11, +0x50, 0x62, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x20, 0x11, +0x50, 0x63, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x30, 0x11, +0x50, 0x64, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x40, 0x11, +0x50, 0x65, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x50, 0x11, +0x50, 0x66, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x60, 0x11, +0x50, 0x67, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x70, 0x11, +0x50, 0x68, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x80, 0x11, +0x50, 0x69, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x90, 0x11, +0x50, 0x6a, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xa0, 0x11, +0x50, 0x6b, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xb0, 0x11, +0x50, 0x6c, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xc0, 0x11, +0x50, 0x6d, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xd0, 0x11, +0x50, 0x6e, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xe0, 0x11, +0x50, 0x6f, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xf0, 0x11 + }; + + UCHAR Vc[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#if 0 + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +#endif + }; + + success = OpenServer( &ServerHandle, ServerName ); + if ( !success) { + return 1; + } + + printf("Opened server, %wS\n", ServerName ); + + // + // Setup the file name that we'll be opening every time. + // + + 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"\\" ); + status = RtlAppendUnicodeToString( &FileName, ServerName ); + status = RtlAppendUnicodeToString( &FileName, L"\\SYS:\\SYSTEM\\NET$VAL.SYS" ); + + // Get objectid +// SendMessage( +// "Swp", +// 0x17, 0x35, +// OT_USER, +// NW_USER); + SendMessage( + "Swp", + 0x35, + OT_USER, + NW_USER); + + ParseResponse("r", Object, 4 ); + + // jump into the middle of a run... + + x = 0; + y = START_POSITION * 17; + goto start; + + for ( x = 0 ; x < sizeof(Vold) ; x+= 17 ) { + + for ( y = 0 ; y < sizeof(Vc) ; y+= 17 ) { + +start: + // + // Set the password on the server to be the value of Vold required for + // the second part of the test. + // + + ResetPassword( Vold + x ); + + // + // We now know that Vold on the server is the same as the Vold vector. + // We can now set the password to any Vnew. + // We can do this without the real password because the + // server will believe we know the real password if we give it + // the result of taking Vold and the Challenge key and passing + // it through RespondToChallengePart2 + // + + printf( "Getting a challenge key.... " ); + +// SendMessage( +// "S", +// 0x17, 0x17); + SendMessage( "S", + 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + // Fabricate the number the server will use to validate the password change + RespondToChallengePart2( Vold + x, Challenge, ResponseP2 ); + + printf( "Vold= " ); dump( Vold + x, 17); + + // Put out results to console... + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "File= " ); + dump( fileValue, 17); + } + printf( " Vc= "); dump( Vc + y, 17); + + printf( "Setting the new password... " ); + + // Send the set password +// SendMessage("Srwpr", 0x17, 0x4b, +// ResponseP2, 8, +/// OT_USER, +// NW_USER, +// Vc + y, 17 ); + SendMessage("Srwpr", + 0x4b, + ResponseP2, 8, + OT_USER, + NW_USER, + Vc + y, 17 ); + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "Vnew= "); + dump( fileValue, 17); + } + +// printf( "Press a key...\n" ); getch(); + +// printf( "\n" ); + printf( "\n\n" ); + } + } + + printf( "%s exiting\n", argv[0]); + return 0; +} + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ) +// +// This routine reads the current password from the file. +// +{ + HANDLE fileHandle; + LARGE_INTEGER filePosition; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + int i; + PCHAR ch; + NTSTATUS status; + + ch = OutputValue; + for (i = 0; i < 17; i++) { + + *(ch++) = '0'; + } + + // Send a Close Bindery to the server + + printf( "Closing the bindery... " ); + +// SendMessage( +// "S", +// 0x17, 0x44); + SendMessage( + "S", + 0x44); + + // + // Open the server\sys:system\net$val.sys file which the server just + // closed. + // + + InitializeObjectAttributes( + &objectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + status = NtOpenFile ( + &fileHandle, + FILE_GENERIC_READ | SYNCHRONIZE, + &objectAttributes, + &ioStatusBlock, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0L + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Open failed. Status = 0x%x\n", status ); + + } else { + + // + // Seek to the spot in the file that has the supervisor's password. + // This will be different for different servers. Here's a table : + // ObjectID = Supervisor AndyHe + // Netware311 : 0x097C + // Mars312 : 0x16CC + // YihsinS3 : 0x59EA 0x050C + // + + filePosition.HighPart = 0L; + filePosition.LowPart = 0x050C; + + // Read the 17 bytes at that offset and close the file + + status = NtReadFile ( + fileHandle, + NULL, + NULL, + NULL, + &ioStatusBlock, + OutputValue, + 17, + &filePosition, + NULL + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Read failed. Status = 0x%x\n", status ); + } + + NtClose( fileHandle ); + } + + // Send an Open Bindery to the server + + printf( "Opening the bindery... " ); +// SendMessage( +// "S", +// 0x17, 0x45); + SendMessage( + "S", + 0x45); + + return(status); +} + +VOID +ResetPassword( + PUCHAR Vnew + ) +{ +// +// Note Vc[0] specifies the length. To derive new values of Vnew use the following +// table. For each nibble desired in Vnew, scan the appropriate column and +// read off the corresponding Vc nibble value on the left. +// + + UCHAR Vc[17]; + + UCHAR Challenge[8]; + OEM_STRING Password = {0,0,""}; + UCHAR EncryptKey[8]; + + int x; + + //printf( "Get Login key for set password using NULL password\n"); + + printf( "Getting a challenge key.... " ); + +// SendMessage( +// "S", +// 0x17, 0x17); + SendMessage( + "S", + 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + RespondToChallenge( Object, &Password, Challenge, EncryptKey ); + // dump( EncryptKey, 8); + + // + // Build Vc so that the server will get Vnew stored in the bindery. + // Note Vols/Vnew have the length at V[17] whereas Vc has it at Vc[0]. + // + + for ( x = 0 ; x < 16; x++ ) { + Vc[x+1] = LookUp( Vnew[x], 0xf0, x) | LookUp( Vnew[x], 0x0f, x); + } + + Vc[0] = LookUp( Vnew[16], 0xf0, 16) | LookUp( Vnew[16], 0x0f, 16); + + //printf( "Vnew "); dump( Vnew, 17); + //printf( "Vc "); dump( Vc, 17); + + // + // This uses the null password, objectid=1 and our supervisor privilege + // to set it, regardless of the and our ability to figure out what + // Vnew will be created for a particular Vc. + // + + printf( "Setting the old password... " ); + +// SendMessage("Srwpr", 0x17, 0x4b, +// EncryptKey, sizeof(EncryptKey), +// OT_USER, +// NW_USER, +// Vc, 17 ); + SendMessage("Srwpr", + 0x4b, + EncryptKey, sizeof(EncryptKey), + OT_USER, + NW_USER, + Vc, 17 ); + + ParseResponse( "" ); +} + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ) +{ + +#if 0 + +UCHAR Vtab[] = { + + // This table is for the supervisor + +0x97, 0xE3, 0x73, 0xD8, 0x70, 0x5B, 0x85, 0xD3, 0xF5, 0xCD, 0xDB, 0xFA, 0xDC, 0xEB, 0x98, 0x64, 0x18, //0// +0x31, 0x6B, 0x88, 0x1E, 0x88, 0x09, 0x10, 0x29, 0x0B, 0x84, 0x61, 0x03, 0x43, 0xA1, 0xD5, 0x5A, 0x09, //1// +0xCB, 0xFF, 0x67, 0x70, 0xB6, 0xE3, 0x4E, 0x9A, 0x63, 0x27, 0x1A, 0x3C, 0x5A, 0x9A, 0x3B, 0xFC, 0x3A, //2// +0xEF, 0xA8, 0x44, 0x42, 0xDB, 0x1E, 0x59, 0x31, 0x17, 0xEB, 0xF5, 0x99, 0x18, 0x8E, 0x63, 0xAE, 0x2B, //3// +0x23, 0x07, 0xEB, 0xC9, 0xCD, 0xD6, 0xC7, 0xCF, 0xC8, 0xBF, 0x0F, 0xE2, 0x01, 0x16, 0x42, 0xD3, 0x1C, //4// +0x8A, 0xC4, 0x06, 0xB6, 0x51, 0xCA, 0x6F, 0xA7, 0x2E, 0x33, 0x82, 0xBD, 0x65, 0x58, 0xC0, 0xCB, 0x0D, //5// +0x0D, 0xBD, 0x5D, 0x65, 0x92, 0x77, 0x0D, 0x50, 0xAC, 0x79, 0x40, 0x86, 0x34, 0x45, 0x8F, 0x42, 0x3E, //6// +0x12, 0x8C, 0xA0, 0xAF, 0x07, 0xA1, 0xD3, 0x7D, 0x86, 0x5C, 0xA3, 0x2B, 0x80, 0x3F, 0x1D, 0x29, 0x2F, //7// +0x68, 0x15, 0xD1, 0x34, 0xE4, 0x2F, 0xF6, 0xFC, 0xEF, 0xDA, 0x5C, 0x57, 0xCF, 0xB4, 0x5A, 0x90, 0x10, //8// +0x7C, 0x49, 0xF2, 0x5A, 0xF3, 0x34, 0xBC, 0x88, 0x3A, 0x91, 0xB8, 0xC8, 0xAD, 0x03, 0x01, 0x77, 0x01, //9// +0xB0, 0x91, 0xBA, 0x23, 0x1E, 0x42, 0x72, 0xEB, 0xD2, 0xF8, 0x7E, 0x1E, 0xF7, 0x69, 0xE9, 0x0F, 0x32, //a// +0xA6, 0x32, 0x9C, 0x9D, 0x49, 0xB5, 0x98, 0x4E, 0x49, 0x00, 0xC9, 0x7F, 0x92, 0xC0, 0x2E, 0x3D, 0x23, //b// +0x54, 0x2A, 0x25, 0x07, 0x6C, 0x6C, 0xAA, 0xB2, 0xB1, 0x45, 0x27, 0xD4, 0x76, 0x27, 0xBC, 0xE8, 0x14, //c// +0xD9, 0xD0, 0xCE, 0x8C, 0x25, 0x98, 0xEB, 0x66, 0x74, 0x62, 0xE6, 0xA0, 0xEE, 0xFD, 0xF4, 0x86, 0x05, //d// +0xF5, 0x7E, 0x1F, 0xEB, 0x3F, 0xFD, 0x34, 0x04, 0x50, 0x16, 0x3D, 0x61, 0x29, 0xDC, 0xA7, 0xB5, 0x36, //e// +0x4E, 0x56, 0x39, 0xF1, 0xAA, 0x80, 0x21, 0x15, 0x9D, 0xAE, 0x94, 0x45, 0xBB, 0x72, 0x76, 0x11, 0x27 //f// +}; + +#endif + + +UCHAR Vtab[] = { + + // This table is for user AndyHe on Yihsins3, object id = 9000095 + +0xDC, 0x9D, 0xA3, 0x3C, 0x61, 0xCA, 0x98, 0xF2, 0xBB, 0xB5, 0xAE, 0x34, 0x04, 0x43, 0xB0, 0xC9, 0x1B, +0x3F, 0xF0, 0xCF, 0x12, 0x36, 0x49, 0xC1, 0x29, 0x93, 0x4E, 0x9A, 0x58, 0x52, 0xC8, 0x3D, 0x13, 0x0A, +0xC9, 0xBC, 0x9A, 0x26, 0x58, 0x7F, 0x1F, 0x4D, 0xD0, 0xA4, 0x77, 0xB7, 0xB8, 0x39, 0x72, 0xFB, 0x39, +0x7E, 0xDB, 0x66, 0x08, 0xDC, 0x51, 0x3A, 0x81, 0xFD, 0x8B, 0x2B, 0xC5, 0x8F, 0x8C, 0x49, 0x9D, 0x28, +0x4D, 0xA9, 0x25, 0xB4, 0xBB, 0x18, 0xF3, 0x3A, 0x86, 0x3D, 0x06, 0x23, 0x77, 0xAA, 0x1E, 0xD8, 0x1F, +0xA5, 0x43, 0xBC, 0x91, 0xC9, 0x0B, 0x79, 0xBF, 0xCF, 0xCC, 0x58, 0x00, 0xE5, 0x1F, 0xC1, 0x81, 0x0E, +0x83, 0x51, 0x01, 0x73, 0xEF, 0x27, 0x66, 0x13, 0x6C, 0x6F, 0xE4, 0x7F, 0xC9, 0x2D, 0x04, 0xBE, 0x3D, +0x21, 0xCF, 0x82, 0xF7, 0x93, 0xA6, 0x47, 0x76, 0x19, 0x06, 0x85, 0x4D, 0x4D, 0xFB, 0x23, 0x4F, 0x2C, +0x54, 0x3A, 0xFE, 0xED, 0x72, 0x9D, 0xBB, 0x65, 0x45, 0xE3, 0x3D, 0x61, 0x1B, 0x04, 0x6A, 0x37, 0x13, +0x18, 0x08, 0x47, 0x5E, 0x4A, 0xF0, 0xD0, 0x9E, 0x77, 0x9A, 0x69, 0x92, 0x31, 0x55, 0xD5, 0x0C, 0x02, +0xE0, 0x87, 0x3B, 0x85, 0x04, 0xB4, 0x55, 0xAB, 0x58, 0x22, 0xFF, 0xAB, 0xF0, 0x76, 0xF6, 0x74, 0x31, +0xF2, 0x15, 0xD9, 0xD9, 0xA0, 0xD3, 0x02, 0x0C, 0x01, 0xF0, 0xB1, 0xFE, 0x63, 0xD2, 0xEF, 0xE6, 0x20, +0x9B, 0x76, 0x70, 0x4B, 0x87, 0x65, 0xE4, 0xC8, 0x22, 0x59, 0xD0, 0x19, 0x9A, 0xB7, 0x88, 0x60, 0x17, +0xB7, 0xE4, 0xE4, 0xA0, 0x25, 0x3C, 0x8D, 0x50, 0xAE, 0x17, 0xC2, 0xEC, 0xAE, 0x90, 0xA7, 0x52, 0x06, +0x06, 0x2E, 0x18, 0x6F, 0xFD, 0x82, 0x2C, 0xE7, 0xE4, 0x78, 0x4C, 0xDA, 0xDC, 0xE1, 0x9C, 0xA5, 0x35, +0x6A, 0x62, 0x5D, 0xCA, 0x1E, 0xEE, 0xAE, 0xD4, 0x3A, 0xD1, 0x13, 0x86, 0x26, 0x6E, 0x5B, 0x2A, 0x24 +}; + +UCHAR Ch = Value & Mask; +int x; + +// +// Scan down the column of Vtab looking for a nibble that matches Ch +// return the index in the nibble indicated by Mask. +// + +for ( x = 0 ; x < 16 ; x++) { + + if ( (Vtab[ (x*17) + index] & Mask) == Ch ) { + + x |= x << 4; // Copy into both nibbles + return( x & Mask ); + + } +} + +printf(" Not found Value %x, Mask %x, Index %x\n", Value, Mask, index); +return( 0 ); + +} + +BOOLEAN +OpenServer( + PHANDLE Handle, + PWCH ServerName + ) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + WCHAR ServerNameBuffer[100]; + UNICODE_STRING ServerNameString; + + ServerNameString.Buffer = ServerNameBuffer; + ServerNameString.Length = 0; + ServerNameString.MaximumLength = 100; + + status = RtlAppendUnicodeToString( &ServerNameString, DD_NWFS_DEVICE_NAME_U ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, L"\\" ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, ServerName ); + ASSERT( status == STATUS_SUCCESS ); + + // + // Open the file + // + + InitializeObjectAttributes( + &objectAttributes, + &ServerNameString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + status = NtOpenFile ( + Handle, + SYNCHRONIZE, + &objectAttributes, + &ioStatusBlock, + FILE_SHARE_VALID_FLAGS, + FILE_SYNCHRONOUS_IO_NONALERT + ); + + if (!NT_SUCCESS(status) ) { + printf( "Open status = %x for file %Z\n", status, &ServerName ); + } + + return ( (BOOLEAN) NT_SUCCESS( status ) ); +} + + +CHAR Buffer1[100]; +CHAR Buffer2[100]; + +SendMessage( + IN char* Format, + ... + ) +{ + NTSTATUS status = -1; + IO_STATUS_BLOCK IoStatusBlock; + + va_list Arguments; + NTSTATUS Status; + ULONG ReceiveBufferSize = 100; + ULONG SendBufferSize = 100; + + va_start( Arguments, Format ); + + Status = FormatRequest( &Buffer1[0], &SendBufferSize, Format, Arguments ); + if ( !NT_SUCCESS( Status ) ) { + return( Status ); + } + + Buffer1[0] = 0; + Buffer1[0] = SendBufferSize - 2; + + printf("Sending message\n" ); + dump( Buffer1, SendBufferSize + 1); + + status = NtFsControlFile( + ServerHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NWR_ANY_NCP(0x17), + Buffer1, + SendBufferSize, + Buffer2, + ReceiveBufferSize + ); + + if (NT_SUCCESS(status)) { + status = IoStatusBlock.Status; +// FormattedDump( Reply, ReplyLength ); + } + +#if 0 + status = NtFsControlFile( + ServerHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NWR_ANY_NCP(0x17), // packet already contains the code necessary + Buffer1, + SendBufferSize +1, + Buffer2, + ReceiveBufferSize + ); + if ( NT_SUCCESS( status ) ) { + + status = NtWaitForSingleObject( ServerHandle, FALSE, NULL ); + if ( NT_SUCCESS( status )) { + status = IoStatusBlock.Status; + } + } +#endif + + if ( !NT_SUCCESS( status ) ) { + printf("SendPacket returns %08lx\n", status ); + } else { + printf("Send succeeded.\n" ); + //dump( Buffer2, IoStatusBlock.Information ); + } + 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 ); +} + + +// Hex dump + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ) +/*++ + +Routine Description: + Dump Min(len, MaxDump) bytes in classic hex dump style. + +Arguments: + + IN far_p - address of buffer to start dumping from. + + IN len - length in bytes of buffer. + +Return Value: + + None. + +--*/ +{ + ULONG l; + char s[80], t[80]; + PCHAR far_pchar = (PCHAR)far_p; + + if (len > MaxDump) + len = MaxDump; + + while (len) { + l = len < 17 ? len : 17; + + // printf("\n%lx ", far_pchar); + HexDumpLine (far_pchar, l, s, t, 0); + // printf("%s%.*s%s", s, 1 + ((16 - l) * 3), "", t); + printf("%s", s); + + len -= l; + far_pchar += l; + } + printf("\n"); +} + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ) +{ + static UCHAR rghex[] = "0123456789ABCDEF"; + + UCHAR c; + UCHAR *hex, *asc; + + + hex = s; + asc = t; + + *(asc++) = '*'; + while (len--) { + c = *(pch++); + *(hex++) = rghex [c >> 4] ; + *(hex++) = rghex [c & 0x0F]; + *(hex++) = ' '; + *(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c; + } + *(asc++) = '*'; + *asc = 0; + *hex = 0; + + flag; +} + +// End Hex dump + +UCHAR Table[] = +{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; + +UCHAR Keys[32] = +{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +#define XorArray( DEST, SRC ) { \ + PULONG D = (PULONG)DEST; \ + PULONG S = (PULONG)SRC; \ + int i; \ + for ( i = 0; i <= 7 ; i++ ) { \ + D[i] ^= S[i]; \ + } \ +} + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + Shuffle( &pChallenge[0], achBuf, 16, &achK[0] ); + Shuffle( &pChallenge[4], achBuf, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 16 byte response held by the server + +Return Value: + + none. + +--*/ + +{ + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + memmove(pResponse, achBuf, 16); +} + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the result of Shuffling the ObjectId and the Password + and processes it with a challenge key. + +Arguments: + IN PUCHAR pResponsePart1 - Supplies the 16 byte output of + RespondToChallengePart1. + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + + Shuffle( &pChallenge[0], pResponsePart1, 16, &achK[0] ); + Shuffle( &pChallenge[4], pResponsePart1, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ) + +/*++ + +Routine Description: + + This routine shuffles around the object ID with the password + +Arguments: + + IN achObjectId - Supplies the 4 byte user's bindery object id + + IN szUpperPassword - Supplies the user's uppercased password on the + first call to process the password. On the second and third calls + this parameter contains the OutputBuffer from the first call + + IN iPasswordLen - length of uppercased password + + OUT achOutputBuffer - Returns the 8 byte sub-calculation + +Return Value: + + none. + +--*/ + +{ + int iTempIndex; + int iOutputIndex; + UCHAR achTemp[32]; + + // + // Initialize the achTemp buffer. Initialization consists of taking + // the password and dividing it up into chunks of 32. Any bytes left + // over are the remainder and do not go into the initialization. + // + // achTemp[0] = szUpperPassword[0] ^ szUpperPassword[32] ^ szUpper... + // achTemp[1] = szUpperPassword[1] ^ szUpperPassword[33] ^ szUpper... + // etc. + // + + if ( iPasswordLen > 32) { + + // At least one chunk of 32. Set the buffer to the first chunk. + + RtlCopyMemory( achTemp, szUpperPassword, 32 ); + + szUpperPassword +=32; // Remove the first chunk + iPasswordLen -=32; + + while ( iPasswordLen >= 32 ) { + // + // Xor this chunk with the characters already loaded into + // achTemp. + // + + XorArray( achTemp, szUpperPassword); + + szUpperPassword +=32; // Remove this chunk + iPasswordLen -=32; + } + + } else { + + // No chunks of 32 so set the buffer to zero's + + RtlZeroMemory( achTemp, sizeof(achTemp)); + + } + + // + // achTemp is now initialized. Load the remainder into achTemp. + // The remainder is repeated to fill achTemp. + // + // The corresponding character from Keys is taken to seperate + // each repitition. + // + // As an example, take the remainder "ABCDEFG". The remainder is expanded + // to "ABCDEFGwABCDEFGxABCDEFGyABCDEFGz" where w is Keys[7], + // x is Keys[15], y is Keys[23] and z is Keys[31]. + // + // + + if (iPasswordLen > 0) { + int iPasswordOffset = 0; + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) { + + if (iPasswordLen == iPasswordOffset) { + iPasswordOffset = 0; + achTemp[iTempIndex] ^= Keys[iTempIndex]; + } else { + achTemp[iTempIndex] ^= szUpperPassword[iPasswordOffset++]; + } + } + } + + // + // achTemp has been loaded with the users password packed into 32 + // bytes. Now take the objectid that came from the server and use + // that to munge every byte in achTemp. + // + + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) + achTemp[iTempIndex] ^= achObjectId[ iTempIndex & 3]; + + Scramble( Scramble( 0, achTemp ), achTemp ); + + // + // Finally take pairs of bytes in achTemp and return the two + // nibbles obtained from Table. The pairs of bytes used + // are achTemp[n] and achTemp[n+16]. + // + + for (iOutputIndex = 0; iOutputIndex < 16; iOutputIndex++) { + + achOutputBuffer[iOutputIndex] = + Table[achTemp[iOutputIndex << 1]] | + (Table[achTemp[(iOutputIndex << 1) + 1]] << 4); + } + + return; +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ) + +/*++ + +Routine Description: + + This routine scrambles around the contents of the buffer. Each buffer + position is updated to include the contents of at least two character + positions plus an EncryptKey value. The buffer is processed left to right + and so if a character position chooses to merge with a buffer position + to its left then this buffer position will include bits derived from at + least 3 bytes of the original buffer contents. + +Arguments: + + IN iSeed + IN OUT achBuffer[32] + +Return Value: + + none. + +--*/ + +{ + int iBufferIndex; + + for (iBufferIndex = 0; iBufferIndex < 32; iBufferIndex++) { + achBuffer[iBufferIndex] = + (UCHAR)( + ((UCHAR)(achBuffer[iBufferIndex] + iSeed)) ^ + ((UCHAR)( achBuffer[(iBufferIndex+iSeed) & 31] - + Keys[iBufferIndex] ))); + + iSeed += achBuffer[iBufferIndex]; + } + return iSeed; +} + +#if 0 + +// this data was gathered for object id = 9000095 from yihsins3 with +// this program by reseting the password to null manually and then +// sending over the specified Vc + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Vnew= DC 9D A3 3C 61 CA 98 F2 BB B5 AE 34 04 43 B0 C9 1B + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 +Vnew= 3F F0 CF 12 36 49 C1 29 93 4E 9A 58 52 C8 3D 13 0A + +File= 3F F0 CF 12 36 49 C1 29 93 4E 9A 58 52 C8 3D 13 0A + Vc= 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 +Vnew= C9 BC 9A 26 58 7F 1F 4D D0 A4 77 B7 B8 39 72 FB 39 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 +Vnew= 7E DB 66 08 DC 51 3A 81 FD 8B 2B C5 8F 8C 49 9D 28 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 +Vnew= 4D A9 25 B4 BB 18 F3 3A 86 3D 06 23 77 AA 1E D8 1F + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +Vnew= A5 43 BC 91 C9 0B 79 BF CF CC 58 00 E5 1F C1 81 0E + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 +Vnew= 83 51 01 73 EF 27 66 13 6C 6F E4 7F C9 2D 04 BE 3D + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 +Vnew= 21 CF 82 F7 93 A6 47 76 19 06 85 4D 4D FB 23 4F 2C + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 +Vnew= 54 3A FE ED 72 9D BB 65 45 E3 3D 61 1B 04 6A 37 13 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 +Vnew= 18 08 47 5E 4A F0 D0 9E 77 9A 69 92 31 04 6A 37 02 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA +Vnew= E0 87 3B 85 04 B4 55 AB 58 22 FF AB F0 76 F6 74 31 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB +Vnew= F2 15 D9 D9 A0 D3 02 0C 01 F0 B1 FE 63 D2 EF E6 20 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC +Vnew= 9B 76 70 4B 87 65 E4 C8 22 59 D0 19 9A B7 88 60 17 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD +Vnew= B7 E4 E4 A0 25 3C 8D 50 AE 17 C2 EC AE 90 A7 52 06 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE +Vnew= 06 2E 18 6F FD 82 2C E7 E4 78 4C DA DC E1 9C A5 35 + +File= 06 2E 18 6F FD 82 2C E7 E4 78 4C DA DC E1 9C A5 35 + Vc= FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +Vnew= 6A 62 5D CA 1E EE AE D4 3A D1 13 86 26 6E 5B 2A 24 + + +0xEA, 0x91, 0x6C, 0x3D, 0xAB, 0x59, 0xB9, 0xBD, 0xB2, 0x7B, 0x4C, 0x , 0x , 0x , 0x , 0x , 0x , //0// +0x97, 0xB6, 0xE6, 0x15, 0xF0, 0x43, 0x21, 0x63, 0x7B, 0xDF, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //1// +0x7B, 0xEF, 0x47, 0x21, 0xD8, 0x6E, 0xEB, 0x10, 0xCC, 0xAA, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //2// +0x16, 0x85, 0xA0, 0x06, 0x17, 0xDB, 0x34, 0x46, 0xF1, 0x48, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //3// +0x48, 0x5D, 0x9D, 0xC4, 0x9A, 0x1A, 0x7C, 0x2F, 0x8E, 0x12, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //4// +0x85, 0x6B, 0xF4, 0x9A, 0x2D, 0x3C, 0xAA, 0xD8, 0xA8, 0xC0, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //5// +0xFE, 0xFC, 0x33, 0xE2, 0x01, 0xC7, 0x66, 0x87, 0x64, 0x67, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //6// +0x3D, 0xCA, 0xC9, 0x67, 0x8C, 0x26, 0x57, 0x7E, 0x99, 0xED, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //7// +0x69, 0xA9, 0x7E, 0xA3, 0xC2, 0xE4, 0xD0, 0x3C, 0x4A, 0x3E, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //8// +0xC2, 0x04, 0x2B, 0x5B, 0x75, 0x81, 0x05, 0x91, 0x17, 0x9C, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //9// +0x5F, 0x48, 0x02, 0xDF, 0xB9, 0x70, 0xF3, 0xA4, 0xDF, 0x29, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //A// +0xDC, 0x23, 0x5A, 0x4C, 0x44, 0xA5, 0x88, 0x5A, 0x00, 0x03, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //B// +0x20, 0x72, 0x15, 0xF0, 0x53, 0x0D, 0x1E, 0xCB, 0x56, 0x55, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //C// +0x04, 0x30, 0xBF, 0xB8, 0x3E, 0xB8, 0x9D, 0xF2, 0x23, 0xF4, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //D// +0xA3, 0xDE, 0xD8, 0x89, 0x6F, 0xFF, 0xF3, 0xE9, 0xED, 0x81, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //E// +0xB1, 0x17, 0x81, 0x7E, 0xE6, 0x92, 0x42, 0x05, 0x35, 0xB6, 0x , 0x , 0x , 0x , 0x , 0x , 0x //F// + }; + 00 = AE 34 04 43 B0 C9 1B + 11 = 9A 58 52 C8 3D 13 0A + 22 = 77 B7 B8 39 72 FB 39 + 33 = 2B C5 8F 8C 49 9D 28 + 44 = 06 23 77 AA 1E D8 1F + 55 = 58 00 E5 1F C1 81 0E + 66 = E4 7F C9 2D 04 BE 3D + 77 = 85 4D 4D FB 23 4F 2C + 88 = 3D 61 1B 04 6A 37 13 + 99 = 69 92 31 55 D5 0C 02 + AA = FF AB F0 76 F6 74 31 + BB = B1 FE 63 D2 EF E6 20 + CC = D0 19 9A B7 88 60 17 + DD = C2 EC AE 90 A7 52 06 + EE = 4C DA DC E1 9C A5 35 + FF = 13 86 26 6E 5B 2A 24 + + + + +#endif + diff --git a/private/nw/test/tp4.c b/private/nw/test/tp4.c new file mode 100644 index 000000000..6788bbcba --- /dev/null +++ b/private/nw/test/tp4.c @@ -0,0 +1,1668 @@ +/*++ + +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 <conio.h> +#include <stdio.h> +#include <string.h> +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <ntddnwfs.h> +#include <STDARG.H> + +#define OT_USER 1 + + +// Hex dump +ULONG MaxDump = 256; + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ); + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ); + + +// End Hex dump + +VOID +ResetPassword( + PUCHAR Vnew + ); + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ); + +SendMessage( + IN char* Format, + ... + ); + +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 + ); + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ); + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ); + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ); + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ); + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ); + +#define BUFFER_SIZE 200 + +//WCHAR *ServerName = L"YIHSINS3"; +WCHAR *ServerName = L"MARS312"; +UCHAR Pid = 255; +UCHAR Object[4]; + +WCHAR FileNameBuffer[100]; +UNICODE_STRING FileName; + +//#define NW_USER "ANDYHE" +#define NW_USER "COLINW" + + +HANDLE ServerHandle; +_cdecl +main( + int argc, + char *argv[] + ) +{ + BOOLEAN success; + UCHAR Challenge[8]; + UCHAR fileValue[17]; + UCHAR ResponseP2[16]; + int x, y; + NTSTATUS status; + + +#if 0 + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + +#endif + +#define START_POSITION 0x00 + + UCHAR Vold[] = { +0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x11, +0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x10, 0xe0, 0x00, 0x00, 0x11, +0x00, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x20, 0xd0, 0x00, 0x00, 0x11, +0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 0x11, +0x00, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x40, 0xb0, 0x00, 0x00, 0x11, +0x00, 0x05, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x50, 0xa0, 0x00, 0x00, 0x11, +0x00, 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x60, 0x90, 0x00, 0x00, 0x11, +0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x11, +0x00, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x00, 0x00, 0x11, +0x00, 0x09, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x90, 0x60, 0x00, 0x00, 0x11, +0x00, 0x0a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xa0, 0x50, 0x00, 0x00, 0x11, +0x00, 0x0b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xb0, 0x40, 0x00, 0x00, 0x11, +0x00, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x00, 0x00, 0x11, +0x00, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xd0, 0x20, 0x00, 0x00, 0x11, +0x00, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x00, 0x00, 0x11, +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x11, +0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00, 0x11, +0x50, 0x61, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x10, 0x11, +0x50, 0x62, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x20, 0x11, +0x50, 0x63, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x30, 0x11, +0x50, 0x64, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x40, 0x11, +0x50, 0x65, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x50, 0x11, +0x50, 0x66, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x60, 0x11, +0x50, 0x67, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x70, 0x11, +0x50, 0x68, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x80, 0x11, +0x50, 0x69, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x90, 0x11, +0x50, 0x6a, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xa0, 0x11, +0x50, 0x6b, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xb0, 0x11, +0x50, 0x6c, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xc0, 0x11, +0x50, 0x6d, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xd0, 0x11, +0x50, 0x6e, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xe0, 0x11, +0x50, 0x6f, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0x00,0x50, 0x60, 0x00, 0x09, 0x0a, 0x0b, 0x50, 0xf0, 0x11 + }; + + UCHAR Vc[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#if 0 + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +#endif + }; + + success = OpenServer( &ServerHandle, ServerName ); + if ( !success) { + return 1; + } + + printf("Opened server, %wS\n", ServerName ); + + // + // Setup the file name that we'll be opening every time. + // + + 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"\\" ); + status = RtlAppendUnicodeToString( &FileName, ServerName ); + status = RtlAppendUnicodeToString( &FileName, L"\\SYS:\\SYSTEM\\NET$VAL.SYS" ); + + // Get objectid + SendMessage( + "Swp", + 0x17, 0x35, + OT_USER, + NW_USER); + + ParseResponse("r", Object, 4 ); + + // jump into the middle of a run... + + x = 0; + y = START_POSITION * 17; + goto start; + + for ( x = 0 ; x < sizeof(Vold) ; x+= 17 ) { + + for ( y = 0 ; y < sizeof(Vc) ; y+= 17 ) { + +start: + // + // Set the password on the server to be the value of Vold required for + // the second part of the test. + // + + ResetPassword( Vold + x ); + + // + // We now know that Vold on the server is the same as the Vold vector. + // We can now set the password to any Vnew. + // We can do this without the real password because the + // server will believe we know the real password if we give it + // the result of taking Vold and the Challenge key and passing + // it through RespondToChallengePart2 + // + + printf( "Getting a challenge key.... " ); + + SendMessage( + "S", + 0x17, 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + // Fabricate the number the server will use to validate the password change + RespondToChallengePart2( Vold + x, Challenge, ResponseP2 ); + + printf( "Vold= " ); dump( Vold + x, 17); + + // Put out results to console... + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "File= " ); + dump( fileValue, 17); + } + printf( " Vc= "); dump( Vc + y, 17); + + printf( "Setting the new password... " ); + + // Send the set password + SendMessage("Srwpr", 0x17, 0x4b, + ResponseP2, 8, + OT_USER, + NW_USER, + Vc + y, 17 ); + + status = GetCurrentPasswordValue( &fileValue[0] ); + + if ( NT_SUCCESS( status ) ) { + + printf( "Vnew= "); + dump( fileValue, 17); + } + +// printf( "Press a key...\n" ); getch(); + +// printf( "\n" ); + printf( "\n\n" ); + } + } + + printf( "%s exiting\n", argv[0]); + return 0; +} + +NTSTATUS +GetCurrentPasswordValue ( + IN OUT PCHAR OutputValue + ) +// +// This routine reads the current password from the file. +// +{ + HANDLE fileHandle; + LARGE_INTEGER filePosition; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + int i; + PCHAR ch; + NTSTATUS status; + + ch = OutputValue; + for (i = 0; i < 17; i++) { + + *(ch++) = '0'; + } + + // Send a Close Bindery to the server + + printf( "Closing the bindery... " ); + + SendMessage( + "S", + 0x17, 0x44); + + // + // Open the server\sys:system\net$val.sys file which the server just + // closed. + // + + InitializeObjectAttributes( + &objectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + status = NtOpenFile ( + &fileHandle, + FILE_GENERIC_READ | SYNCHRONIZE, + &objectAttributes, + &ioStatusBlock, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0L + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Open failed. Status = 0x%x\n", status ); + + } else { + + // + // Seek to the spot in the file that has the supervisor's password. + // This will be different for different servers. Here's a table : + // ObjectID = Supervisor AndyHe + // Netware311 : 0x097C + // Mars312 : 0x16CC + // YihsinS3 : 0x59EA 0x050C + // + + filePosition.HighPart = 0L; + filePosition.LowPart = 0x050C; + + // Read the 17 bytes at that offset and close the file + + status = NtReadFile ( + fileHandle, + NULL, + NULL, + NULL, + &ioStatusBlock, + OutputValue, + 17, + &filePosition, + NULL + ); + + if (!NT_SUCCESS(status) ) { + + printf( " Read failed. Status = 0x%x\n", status ); + } + + NtClose( fileHandle ); + } + + // Send an Open Bindery to the server + + printf( "Opening the bindery... " ); + SendMessage( + "S", + 0x17, 0x45); + + return(status); +} + +VOID +ResetPassword( + PUCHAR Vnew + ) +{ +// +// Note Vc[0] specifies the length. To derive new values of Vnew use the following +// table. For each nibble desired in Vnew, scan the appropriate column and +// read off the corresponding Vc nibble value on the left. +// + + UCHAR Vc[17]; + + UCHAR Challenge[8]; + OEM_STRING Password = {0,0,""}; + UCHAR EncryptKey[8]; + + int x; + + //printf( "Get Login key for set password using NULL password\n"); + + printf( "Getting a challenge key.... " ); + + SendMessage( + "S", + 0x17, 0x17); + + ParseResponse("r", Challenge, sizeof(Challenge) ); + + RespondToChallenge( Object, &Password, Challenge, EncryptKey ); + // dump( EncryptKey, 8); + + // + // Build Vc so that the server will get Vnew stored in the bindery. + // Note Vols/Vnew have the length at V[17] whereas Vc has it at Vc[0]. + // + + for ( x = 0 ; x < 16; x++ ) { + Vc[x+1] = LookUp( Vnew[x], 0xf0, x) | LookUp( Vnew[x], 0x0f, x); + } + + Vc[0] = LookUp( Vnew[16], 0xf0, 16) | LookUp( Vnew[16], 0x0f, 16); + + //printf( "Vnew "); dump( Vnew, 17); + //printf( "Vc "); dump( Vc, 17); + + // + // This uses the null password, objectid=1 and our supervisor privilege + // to set it, regardless of the and our ability to figure out what + // Vnew will be created for a particular Vc. + // + + printf( "Setting the old password... " ); + + SendMessage("Srwpr", 0x17, 0x4b, + EncryptKey, sizeof(EncryptKey), + OT_USER, + NW_USER, + Vc, 17 ); + + ParseResponse( "" ); +} + +UCHAR +LookUp( + UCHAR Value, + UCHAR Mask, + int index + ) +{ + +#if 0 + +UCHAR Vtab[] = { + + // This table is for the supervisor + +0x97, 0xE3, 0x73, 0xD8, 0x70, 0x5B, 0x85, 0xD3, 0xF5, 0xCD, 0xDB, 0xFA, 0xDC, 0xEB, 0x98, 0x64, 0x18, //0// +0x31, 0x6B, 0x88, 0x1E, 0x88, 0x09, 0x10, 0x29, 0x0B, 0x84, 0x61, 0x03, 0x43, 0xA1, 0xD5, 0x5A, 0x09, //1// +0xCB, 0xFF, 0x67, 0x70, 0xB6, 0xE3, 0x4E, 0x9A, 0x63, 0x27, 0x1A, 0x3C, 0x5A, 0x9A, 0x3B, 0xFC, 0x3A, //2// +0xEF, 0xA8, 0x44, 0x42, 0xDB, 0x1E, 0x59, 0x31, 0x17, 0xEB, 0xF5, 0x99, 0x18, 0x8E, 0x63, 0xAE, 0x2B, //3// +0x23, 0x07, 0xEB, 0xC9, 0xCD, 0xD6, 0xC7, 0xCF, 0xC8, 0xBF, 0x0F, 0xE2, 0x01, 0x16, 0x42, 0xD3, 0x1C, //4// +0x8A, 0xC4, 0x06, 0xB6, 0x51, 0xCA, 0x6F, 0xA7, 0x2E, 0x33, 0x82, 0xBD, 0x65, 0x58, 0xC0, 0xCB, 0x0D, //5// +0x0D, 0xBD, 0x5D, 0x65, 0x92, 0x77, 0x0D, 0x50, 0xAC, 0x79, 0x40, 0x86, 0x34, 0x45, 0x8F, 0x42, 0x3E, //6// +0x12, 0x8C, 0xA0, 0xAF, 0x07, 0xA1, 0xD3, 0x7D, 0x86, 0x5C, 0xA3, 0x2B, 0x80, 0x3F, 0x1D, 0x29, 0x2F, //7// +0x68, 0x15, 0xD1, 0x34, 0xE4, 0x2F, 0xF6, 0xFC, 0xEF, 0xDA, 0x5C, 0x57, 0xCF, 0xB4, 0x5A, 0x90, 0x10, //8// +0x7C, 0x49, 0xF2, 0x5A, 0xF3, 0x34, 0xBC, 0x88, 0x3A, 0x91, 0xB8, 0xC8, 0xAD, 0x03, 0x01, 0x77, 0x01, //9// +0xB0, 0x91, 0xBA, 0x23, 0x1E, 0x42, 0x72, 0xEB, 0xD2, 0xF8, 0x7E, 0x1E, 0xF7, 0x69, 0xE9, 0x0F, 0x32, //a// +0xA6, 0x32, 0x9C, 0x9D, 0x49, 0xB5, 0x98, 0x4E, 0x49, 0x00, 0xC9, 0x7F, 0x92, 0xC0, 0x2E, 0x3D, 0x23, //b// +0x54, 0x2A, 0x25, 0x07, 0x6C, 0x6C, 0xAA, 0xB2, 0xB1, 0x45, 0x27, 0xD4, 0x76, 0x27, 0xBC, 0xE8, 0x14, //c// +0xD9, 0xD0, 0xCE, 0x8C, 0x25, 0x98, 0xEB, 0x66, 0x74, 0x62, 0xE6, 0xA0, 0xEE, 0xFD, 0xF4, 0x86, 0x05, //d// +0xF5, 0x7E, 0x1F, 0xEB, 0x3F, 0xFD, 0x34, 0x04, 0x50, 0x16, 0x3D, 0x61, 0x29, 0xDC, 0xA7, 0xB5, 0x36, //e// +0x4E, 0x56, 0x39, 0xF1, 0xAA, 0x80, 0x21, 0x15, 0x9D, 0xAE, 0x94, 0x45, 0xBB, 0x72, 0x76, 0x11, 0x27 //f// +}; + +#endif + + +UCHAR Vtab[] = { + + // This table is for user AndyHe on Yihsins3, object id = 9000095 + +0xDC, 0x9D, 0xA3, 0x3C, 0x61, 0xCA, 0x98, 0xF2, 0xBB, 0xB5, 0xAE, 0x34, 0x04, 0x43, 0xB0, 0xC9, 0x1B, +0x3F, 0xF0, 0xCF, 0x12, 0x36, 0x49, 0xC1, 0x29, 0x93, 0x4E, 0x9A, 0x58, 0x52, 0xC8, 0x3D, 0x13, 0x0A, +0xC9, 0xBC, 0x9A, 0x26, 0x58, 0x7F, 0x1F, 0x4D, 0xD0, 0xA4, 0x77, 0xB7, 0xB8, 0x39, 0x72, 0xFB, 0x39, +0x7E, 0xDB, 0x66, 0x08, 0xDC, 0x51, 0x3A, 0x81, 0xFD, 0x8B, 0x2B, 0xC5, 0x8F, 0x8C, 0x49, 0x9D, 0x28, +0x4D, 0xA9, 0x25, 0xB4, 0xBB, 0x18, 0xF3, 0x3A, 0x86, 0x3D, 0x06, 0x23, 0x77, 0xAA, 0x1E, 0xD8, 0x1F, +0xA5, 0x43, 0xBC, 0x91, 0xC9, 0x0B, 0x79, 0xBF, 0xCF, 0xCC, 0x58, 0x00, 0xE5, 0x1F, 0xC1, 0x81, 0x0E, +0x83, 0x51, 0x01, 0x73, 0xEF, 0x27, 0x66, 0x13, 0x6C, 0x6F, 0xE4, 0x7F, 0xC9, 0x2D, 0x04, 0xBE, 0x3D, +0x21, 0xCF, 0x82, 0xF7, 0x93, 0xA6, 0x47, 0x76, 0x19, 0x06, 0x85, 0x4D, 0x4D, 0xFB, 0x23, 0x4F, 0x2C, +0x54, 0x3A, 0xFE, 0xED, 0x72, 0x9D, 0xBB, 0x65, 0x45, 0xE3, 0x3D, 0x61, 0x1B, 0x04, 0x6A, 0x37, 0x13, +0x18, 0x08, 0x47, 0x5E, 0x4A, 0xF0, 0xD0, 0x9E, 0x77, 0x9A, 0x69, 0x92, 0x31, 0x55, 0xD5, 0x0C, 0x02, +0xE0, 0x87, 0x3B, 0x85, 0x04, 0xB4, 0x55, 0xAB, 0x58, 0x22, 0xFF, 0xAB, 0xF0, 0x76, 0xF6, 0x74, 0x31, +0xF2, 0x15, 0xD9, 0xD9, 0xA0, 0xD3, 0x02, 0x0C, 0x01, 0xF0, 0xB1, 0xFE, 0x63, 0xD2, 0xEF, 0xE6, 0x20, +0x9B, 0x76, 0x70, 0x4B, 0x87, 0x65, 0xE4, 0xC8, 0x22, 0x59, 0xD0, 0x19, 0x9A, 0xB7, 0x88, 0x60, 0x17, +0xB7, 0xE4, 0xE4, 0xA0, 0x25, 0x3C, 0x8D, 0x50, 0xAE, 0x17, 0xC2, 0xEC, 0xAE, 0x90, 0xA7, 0x52, 0x06, +0x06, 0x2E, 0x18, 0x6F, 0xFD, 0x82, 0x2C, 0xE7, 0xE4, 0x78, 0x4C, 0xDA, 0xDC, 0xE1, 0x9C, 0xA5, 0x35, +0x6A, 0x62, 0x5D, 0xCA, 0x1E, 0xEE, 0xAE, 0xD4, 0x3A, 0xD1, 0x13, 0x86, 0x26, 0x6E, 0x5B, 0x2A, 0x24 +}; + +UCHAR Ch = Value & Mask; +int x; + +// +// Scan down the column of Vtab looking for a nibble that matches Ch +// return the index in the nibble indicated by Mask. +// + +for ( x = 0 ; x < 16 ; x++) { + + if ( (Vtab[ (x*17) + index] & Mask) == Ch ) { + + x |= x << 4; // Copy into both nibbles + return( x & Mask ); + + } +} + +printf(" Not found Value %x, Mask %x, Index %x\n", Value, Mask, index); +return( 0 ); + +} + +BOOLEAN +OpenServer( + PHANDLE Handle, + PWCH ServerName + ) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES objectAttributes; + IO_STATUS_BLOCK ioStatusBlock; + WCHAR ServerNameBuffer[100]; + UNICODE_STRING ServerNameString; + + ServerNameString.Buffer = ServerNameBuffer; + ServerNameString.Length = 0; + ServerNameString.MaximumLength = 100; + + status = RtlAppendUnicodeToString( &ServerNameString, DD_NWFS_DEVICE_NAME_U ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, L"\\" ); + ASSERT( status == STATUS_SUCCESS ); + status = RtlAppendUnicodeToString( &ServerNameString, ServerName ); + ASSERT( status == STATUS_SUCCESS ); + + // + // Open the file + // + + InitializeObjectAttributes( + &objectAttributes, + &ServerNameString, + 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, &ServerName ); + } + + return ( (BOOLEAN) NT_SUCCESS( status ) ); +} + + +CHAR Buffer1[100]; +CHAR Buffer2[100]; + +SendMessage( + IN char* Format, + ... + ) +{ + NTSTATUS status = -1; + IO_STATUS_BLOCK IoStatusBlock; + + va_list Arguments; + NTSTATUS Status; + ULONG ReceiveBufferSize = 100; + ULONG SendBufferSize = 100; + + va_start( Arguments, Format ); + + + Status = FormatRequest( Buffer1, &SendBufferSize, Format, Arguments ); + if ( !NT_SUCCESS( Status ) ) { + return( Status ); + } + + //printf("Sending message\n" ); + //dump( Buffer1, SendBufferSize + 1); + + status = NtFsControlFile( + ServerHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NWR_ANY_NCP(Buffer1[0]), + Buffer1+3, + SendBufferSize - 3, + Buffer2, + ReceiveBufferSize + ); + if ( NT_SUCCESS( status ) ) { + + status = NtWaitForSingleObject( ServerHandle, FALSE, NULL ); + if ( NT_SUCCESS( status )) { + status = IoStatusBlock.Status; + } + } + + + if ( !NT_SUCCESS( status ) ) { + printf("SendPacket returns %08lx\n", status ); + } else { + printf("Send succeeded.\n" ); + //dump( Buffer2, IoStatusBlock.Information ); + } + 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 ); +} + + +// Hex dump + +VOID +dump( + IN PVOID far_p, + IN ULONG len + ) +/*++ + +Routine Description: + Dump Min(len, MaxDump) bytes in classic hex dump style. + +Arguments: + + IN far_p - address of buffer to start dumping from. + + IN len - length in bytes of buffer. + +Return Value: + + None. + +--*/ +{ + ULONG l; + char s[80], t[80]; + PCHAR far_pchar = (PCHAR)far_p; + + if (len > MaxDump) + len = MaxDump; + + while (len) { + l = len < 17 ? len : 17; + + // printf("\n%lx ", far_pchar); + HexDumpLine (far_pchar, l, s, t, 0); + // printf("%s%.*s%s", s, 1 + ((16 - l) * 3), "", t); + printf("%s", s); + + len -= l; + far_pchar += l; + } + printf("\n"); +} + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ) +{ + static UCHAR rghex[] = "0123456789ABCDEF"; + + UCHAR c; + UCHAR *hex, *asc; + + + hex = s; + asc = t; + + *(asc++) = '*'; + while (len--) { + c = *(pch++); + *(hex++) = rghex [c >> 4] ; + *(hex++) = rghex [c & 0x0F]; + *(hex++) = ' '; + *(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c; + } + *(asc++) = '*'; + *asc = 0; + *hex = 0; + + flag; +} + +// End Hex dump + +UCHAR Table[] = +{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8, + 0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9, + 0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6, + 0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0, + 0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD, + 0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE, + 0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7, + 0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1, + 0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4, + 0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2, + 0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3, + 0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0, + 0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8, + 0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3, + 0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0, + 0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD}; + +UCHAR Keys[32] = +{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D, + 0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35, + 0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11, + 0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0}; + +#define XorArray( DEST, SRC ) { \ + PULONG D = (PULONG)DEST; \ + PULONG S = (PULONG)SRC; \ + int i; \ + for ( i = 0; i <= 7 ; i++ ) { \ + D[i] ^= S[i]; \ + } \ +} + +VOID +RespondToChallenge( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + Shuffle( &pChallenge[0], achBuf, 16, &achK[0] ); + Shuffle( &pChallenge[4], achBuf, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +RespondToChallengePart1( + IN PUCHAR achObjectId, + IN POEM_STRING Password, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the ObjectId and Challenge key from the server and + encrypts the user supplied password to develop a credential for the + server to verify. + +Arguments: + IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id + IN POEM_STRING Password - Supplies the user's uppercased password + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 16 byte response held by the server + +Return Value: + + none. + +--*/ + +{ + UCHAR achBuf[32]; + + Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf); + memmove(pResponse, achBuf, 16); +} + +VOID +RespondToChallengePart2( + IN PUCHAR pResponsePart1, + IN PUCHAR pChallenge, + OUT PUCHAR pResponse + ) + +/*++ + +Routine Description: + + This routine takes the result of Shuffling the ObjectId and the Password + and processes it with a challenge key. + +Arguments: + IN PUCHAR pResponsePart1 - Supplies the 16 byte output of + RespondToChallengePart1. + IN PUCHAR pChallenge - Supplies the 8 byte challenge key + OUT PUCHAR pResponse - Returns the 8 byte response + +Return Value: + + none. + +--*/ + +{ + int index; + UCHAR achK[32]; + + Shuffle( &pChallenge[0], pResponsePart1, 16, &achK[0] ); + Shuffle( &pChallenge[4], pResponsePart1, 16, &achK[16] ); + + for (index = 0; index < 16; index++) + achK[index] ^= achK[31-index]; + + for (index = 0; index < 8; index++) + pResponse[index] = achK[index] ^ achK[15-index]; +} + +VOID +Shuffle( + UCHAR *achObjectId, + UCHAR *szUpperPassword, + int iPasswordLen, + UCHAR *achOutputBuffer + ) + +/*++ + +Routine Description: + + This routine shuffles around the object ID with the password + +Arguments: + + IN achObjectId - Supplies the 4 byte user's bindery object id + + IN szUpperPassword - Supplies the user's uppercased password on the + first call to process the password. On the second and third calls + this parameter contains the OutputBuffer from the first call + + IN iPasswordLen - length of uppercased password + + OUT achOutputBuffer - Returns the 8 byte sub-calculation + +Return Value: + + none. + +--*/ + +{ + int iTempIndex; + int iOutputIndex; + UCHAR achTemp[32]; + + // + // Initialize the achTemp buffer. Initialization consists of taking + // the password and dividing it up into chunks of 32. Any bytes left + // over are the remainder and do not go into the initialization. + // + // achTemp[0] = szUpperPassword[0] ^ szUpperPassword[32] ^ szUpper... + // achTemp[1] = szUpperPassword[1] ^ szUpperPassword[33] ^ szUpper... + // etc. + // + + if ( iPasswordLen > 32) { + + // At least one chunk of 32. Set the buffer to the first chunk. + + RtlCopyMemory( achTemp, szUpperPassword, 32 ); + + szUpperPassword +=32; // Remove the first chunk + iPasswordLen -=32; + + while ( iPasswordLen >= 32 ) { + // + // Xor this chunk with the characters already loaded into + // achTemp. + // + + XorArray( achTemp, szUpperPassword); + + szUpperPassword +=32; // Remove this chunk + iPasswordLen -=32; + } + + } else { + + // No chunks of 32 so set the buffer to zero's + + RtlZeroMemory( achTemp, sizeof(achTemp)); + + } + + // + // achTemp is now initialized. Load the remainder into achTemp. + // The remainder is repeated to fill achTemp. + // + // The corresponding character from Keys is taken to seperate + // each repitition. + // + // As an example, take the remainder "ABCDEFG". The remainder is expanded + // to "ABCDEFGwABCDEFGxABCDEFGyABCDEFGz" where w is Keys[7], + // x is Keys[15], y is Keys[23] and z is Keys[31]. + // + // + + if (iPasswordLen > 0) { + int iPasswordOffset = 0; + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) { + + if (iPasswordLen == iPasswordOffset) { + iPasswordOffset = 0; + achTemp[iTempIndex] ^= Keys[iTempIndex]; + } else { + achTemp[iTempIndex] ^= szUpperPassword[iPasswordOffset++]; + } + } + } + + // + // achTemp has been loaded with the users password packed into 32 + // bytes. Now take the objectid that came from the server and use + // that to munge every byte in achTemp. + // + + for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) + achTemp[iTempIndex] ^= achObjectId[ iTempIndex & 3]; + + Scramble( Scramble( 0, achTemp ), achTemp ); + + // + // Finally take pairs of bytes in achTemp and return the two + // nibbles obtained from Table. The pairs of bytes used + // are achTemp[n] and achTemp[n+16]. + // + + for (iOutputIndex = 0; iOutputIndex < 16; iOutputIndex++) { + + achOutputBuffer[iOutputIndex] = + Table[achTemp[iOutputIndex << 1]] | + (Table[achTemp[(iOutputIndex << 1) + 1]] << 4); + } + + return; +} + +int +Scramble( + int iSeed, + UCHAR achBuffer[32] + ) + +/*++ + +Routine Description: + + This routine scrambles around the contents of the buffer. Each buffer + position is updated to include the contents of at least two character + positions plus an EncryptKey value. The buffer is processed left to right + and so if a character position chooses to merge with a buffer position + to its left then this buffer position will include bits derived from at + least 3 bytes of the original buffer contents. + +Arguments: + + IN iSeed + IN OUT achBuffer[32] + +Return Value: + + none. + +--*/ + +{ + int iBufferIndex; + + for (iBufferIndex = 0; iBufferIndex < 32; iBufferIndex++) { + achBuffer[iBufferIndex] = + (UCHAR)( + ((UCHAR)(achBuffer[iBufferIndex] + iSeed)) ^ + ((UCHAR)( achBuffer[(iBufferIndex+iSeed) & 31] - + Keys[iBufferIndex] ))); + + iSeed += achBuffer[iBufferIndex]; + } + return iSeed; +} + +#if 0 + +// this data was gathered for object id = 9000095 from yihsins3 with +// this program by reseting the password to null manually and then +// sending over the specified Vc + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +Vnew= DC 9D A3 3C 61 CA 98 F2 BB B5 AE 34 04 43 B0 C9 1B + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 +Vnew= 3F F0 CF 12 36 49 C1 29 93 4E 9A 58 52 C8 3D 13 0A + +File= 3F F0 CF 12 36 49 C1 29 93 4E 9A 58 52 C8 3D 13 0A + Vc= 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 +Vnew= C9 BC 9A 26 58 7F 1F 4D D0 A4 77 B7 B8 39 72 FB 39 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 +Vnew= 7E DB 66 08 DC 51 3A 81 FD 8B 2B C5 8F 8C 49 9D 28 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 +Vnew= 4D A9 25 B4 BB 18 F3 3A 86 3D 06 23 77 AA 1E D8 1F + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 +Vnew= A5 43 BC 91 C9 0B 79 BF CF CC 58 00 E5 1F C1 81 0E + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 +Vnew= 83 51 01 73 EF 27 66 13 6C 6F E4 7F C9 2D 04 BE 3D + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 +Vnew= 21 CF 82 F7 93 A6 47 76 19 06 85 4D 4D FB 23 4F 2C + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 +Vnew= 54 3A FE ED 72 9D BB 65 45 E3 3D 61 1B 04 6A 37 13 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 +Vnew= 18 08 47 5E 4A F0 D0 9E 77 9A 69 92 31 04 6A 37 02 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA +Vnew= E0 87 3B 85 04 B4 55 AB 58 22 FF AB F0 76 F6 74 31 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB +Vnew= F2 15 D9 D9 A0 D3 02 0C 01 F0 B1 FE 63 D2 EF E6 20 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC +Vnew= 9B 76 70 4B 87 65 E4 C8 22 59 D0 19 9A B7 88 60 17 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD +Vnew= B7 E4 E4 A0 25 3C 8D 50 AE 17 C2 EC AE 90 A7 52 06 + +File= 41 1A 23 1F E3 FF 5C 0D 5B DF 40 52 52 DE 9C EC 00 + Vc= EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE +Vnew= 06 2E 18 6F FD 82 2C E7 E4 78 4C DA DC E1 9C A5 35 + +File= 06 2E 18 6F FD 82 2C E7 E4 78 4C DA DC E1 9C A5 35 + Vc= FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +Vnew= 6A 62 5D CA 1E EE AE D4 3A D1 13 86 26 6E 5B 2A 24 + + +0xEA, 0x91, 0x6C, 0x3D, 0xAB, 0x59, 0xB9, 0xBD, 0xB2, 0x7B, 0x4C, 0x , 0x , 0x , 0x , 0x , 0x , //0// +0x97, 0xB6, 0xE6, 0x15, 0xF0, 0x43, 0x21, 0x63, 0x7B, 0xDF, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //1// +0x7B, 0xEF, 0x47, 0x21, 0xD8, 0x6E, 0xEB, 0x10, 0xCC, 0xAA, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //2// +0x16, 0x85, 0xA0, 0x06, 0x17, 0xDB, 0x34, 0x46, 0xF1, 0x48, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //3// +0x48, 0x5D, 0x9D, 0xC4, 0x9A, 0x1A, 0x7C, 0x2F, 0x8E, 0x12, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //4// +0x85, 0x6B, 0xF4, 0x9A, 0x2D, 0x3C, 0xAA, 0xD8, 0xA8, 0xC0, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //5// +0xFE, 0xFC, 0x33, 0xE2, 0x01, 0xC7, 0x66, 0x87, 0x64, 0x67, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //6// +0x3D, 0xCA, 0xC9, 0x67, 0x8C, 0x26, 0x57, 0x7E, 0x99, 0xED, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //7// +0x69, 0xA9, 0x7E, 0xA3, 0xC2, 0xE4, 0xD0, 0x3C, 0x4A, 0x3E, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //8// +0xC2, 0x04, 0x2B, 0x5B, 0x75, 0x81, 0x05, 0x91, 0x17, 0x9C, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //9// +0x5F, 0x48, 0x02, 0xDF, 0xB9, 0x70, 0xF3, 0xA4, 0xDF, 0x29, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //A// +0xDC, 0x23, 0x5A, 0x4C, 0x44, 0xA5, 0x88, 0x5A, 0x00, 0x03, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //B// +0x20, 0x72, 0x15, 0xF0, 0x53, 0x0D, 0x1E, 0xCB, 0x56, 0x55, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //C// +0x04, 0x30, 0xBF, 0xB8, 0x3E, 0xB8, 0x9D, 0xF2, 0x23, 0xF4, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //D// +0xA3, 0xDE, 0xD8, 0x89, 0x6F, 0xFF, 0xF3, 0xE9, 0xED, 0x81, 0x , 0x , 0x , 0x , 0x , 0x , 0x , //E// +0xB1, 0x17, 0x81, 0x7E, 0xE6, 0x92, 0x42, 0x05, 0x35, 0xB6, 0x , 0x , 0x , 0x , 0x , 0x , 0x //F// + }; + 00 = AE 34 04 43 B0 C9 1B + 11 = 9A 58 52 C8 3D 13 0A + 22 = 77 B7 B8 39 72 FB 39 + 33 = 2B C5 8F 8C 49 9D 28 + 44 = 06 23 77 AA 1E D8 1F + 55 = 58 00 E5 1F C1 81 0E + 66 = E4 7F C9 2D 04 BE 3D + 77 = 85 4D 4D FB 23 4F 2C + 88 = 3D 61 1B 04 6A 37 13 + 99 = 69 92 31 55 D5 0C 02 + AA = FF AB F0 76 F6 74 31 + BB = B1 FE 63 D2 EF E6 20 + CC = D0 19 9A B7 88 60 17 + DD = C2 EC AE 90 A7 52 06 + EE = 4C DA DC E1 9C A5 35 + FF = 13 86 26 6E 5B 2A 24 + + + + +#endif + diff --git a/private/nw/test/userncp.c b/private/nw/test/userncp.c new file mode 100644 index 000000000..ce3e95195 --- /dev/null +++ b/private/nw/test/userncp.c @@ -0,0 +1,246 @@ +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#define WIN32_CONSOLE_APP +#include <windows.h> +#include <stdio.h> +#include <ntddnwfs.h> + +#define CANCEL + +VOID +dump( + IN ULONG Level, + IN PVOID far_p, + IN ULONG len + ); + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ); + +BOOLEAN test1(); + +int +_cdecl +main( + int argc, + char *argv[] + ) +{ + UCHAR error = FALSE; + + printf( "Test1...\n" ); + if (!test1()) { + printf("Error: Test 1 failed\n"); + error = TRUE; + } + return error; +} + + + +BOOLEAN +test1() +{ + HANDLE FileHandle; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING UnicodeString; + IO_STATUS_BLOCK IoStatus; + + CHAR Input1[] = { 0, 1, 1, 1, '\\' }; + CHAR Input2[] = { 1, 1 }; + CHAR Output[20]; + + printf( "test 1: opening\n"); + + RtlInitUnicodeString( &UnicodeString, L"\\Device\\NwRdr\\Netware311" ); + + InitializeObjectAttributes( + &ObjectAttributes, + &UnicodeString, + 0, + NULL, + NULL + ); + + Status = NtOpenFile ( + &FileHandle, + FILE_GENERIC_READ | FILE_GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatus, + FILE_SHARE_READ, + 0 ); + + if (Status != STATUS_SUCCESS) { + printf( "test 1: NtOpenFile failed, error = %08lx\n",Status); + return FALSE; + } + + if (IoStatus.Status != STATUS_SUCCESS) { + printf( "test 1: NtOpenFile failed, error = %08lx\n",IoStatus.Status); + return FALSE; + } + + printf( "test 1: opened server successfully\n"); + + // + // Send set path + // + + NtFsControlFile( FileHandle, + NULL, + NULL, + NULL, + &IoStatus, + FSCTL_NWR_NCP_E2H, + &Input1, + sizeof(Input1), + &Output, + sizeof(Output) ); + + if (Status != STATUS_SUCCESS) { + printf( "test 1: NtFsControlFile failed, error = %0x08lx\n",Status); + return FALSE; + } + + printf( "test 1: Nt fs control file succeeded\n"); + + if ( IoStatus.Information != 0) { + dump( 0, &Output, IoStatus.Information ); + } else { + printf("Received empty buffer\n"); + } + + // + // Send get path + // + + NtFsControlFile( FileHandle, + NULL, + NULL, + NULL, + &IoStatus, + FSCTL_NWR_NCP_E2H, + &Input2, + sizeof(Input2), + &Output, + sizeof(Output) ); + + if (Status != STATUS_SUCCESS) { + printf( "test 1: NtFsControlFile failed, error = %0x08lx\n",Status); + return FALSE; + } + + printf( "test 1: Nt fs control file succeeded\n"); + + if ( IoStatus.Information != 0) { + dump( 0, &Output, IoStatus.Information ); + } else { + printf("Received empty buffer\n"); + } + + + // + // Now close the device + // + + printf("test 1: closing device\n"); + + Status = NtClose( FileHandle ); + if (Status != STATUS_SUCCESS) { + printf( "test 1: Wrong return value %lX - close \n",Status); + return FALSE; + } + return TRUE; +} + +VOID +dump( + IN ULONG Level, + IN PVOID far_p, + IN ULONG len + ) +/*++ + +Routine Description: + Dump Min(len, MaxDump) bytes in classic hex dump style if debug + output is turned on for this level. + +Arguments: + + IN Level - 0 if always display. Otherwise only display if a + corresponding bit is set in NwDebug. + + IN far_p - address of buffer to start dumping from. + + IN len - length in bytes of buffer. + +Return Value: + + None. + +--*/ +{ + ULONG l; + char s[80], t[80]; + PCHAR far_pchar = (PCHAR)far_p; + ULONG MaxDump = 256; + + if (Level == 0) { + if (len > MaxDump) + len = MaxDump; + + while (len) { + l = len < 16 ? len : 16; + + printf("\n%lx ", far_pchar); + HexDumpLine (far_pchar, l, s, t, 0); + printf("%s%.*s%s", s, 1 + ((16 - l) * 3), "", t); + + len -= l; + far_pchar += l; + } + printf("\n"); + } +} + +VOID +HexDumpLine ( + PCHAR pch, + ULONG len, + PCHAR s, + PCHAR t, + USHORT flag + ) +{ + static UCHAR rghex[] = "0123456789ABCDEF"; + + UCHAR c; + UCHAR *hex, *asc; + + + hex = s; + asc = t; + + *(asc++) = '*'; + while (len--) { + c = *(pch++); + *(hex++) = rghex [c >> 4] ; + *(hex++) = rghex [c & 0x0F]; + *(hex++) = ' '; + *(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c; + } + *(asc++) = '*'; + *asc = 0; + *hex = 0; + + flag; +} + |