diff options
Diffstat (limited to 'private/nw/test/attach.c')
-rw-r--r-- | private/nw/test/attach.c | 404 |
1 files changed, 404 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; +} |