summaryrefslogtreecommitdiffstats
path: root/private/nw/ndsutils
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/ndsutils
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/nw/ndsutils')
-rw-r--r--private/nw/ndsutils/browser.c273
-rw-r--r--private/nw/ndsutils/conninfo.c156
-rw-r--r--private/nw/ndsutils/cx.c133
-rw-r--r--private/nw/ndsutils/getps.c102
-rw-r--r--private/nw/ndsutils/getuser.c133
-rw-r--r--private/nw/ndsutils/listconn.c235
-rw-r--r--private/nw/ndsutils/makefile6
-rw-r--r--private/nw/ndsutils/ndschpw.c173
-rw-r--r--private/nw/ndsutils/netperf.c138
-rw-r--r--private/nw/ndsutils/rdstrm.c195
-rw-r--r--private/nw/ndsutils/setshare.c88
-rw-r--r--private/nw/ndsutils/sources46
-rw-r--r--private/nw/ndsutils/treebn.c182
-rw-r--r--private/nw/ndsutils/userfrag.c149
-rw-r--r--private/nw/ndsutils/volinfo.c119
15 files changed, 2128 insertions, 0 deletions
diff --git a/private/nw/ndsutils/browser.c b/private/nw/ndsutils/browser.c
new file mode 100644
index 000000000..0c1195aba
--- /dev/null
+++ b/private/nw/ndsutils/browser.c
@@ -0,0 +1,273 @@
+//
+// NDS Browser Test App
+//
+// Cory West
+//
+
+#include "ndsapi32.h"
+#include "nds.h"
+
+VOID
+ConsoleDumpSubordinates(
+ PNDS_RESPONSE_SUBORDINATE_LIST pSubList
+);
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS Status;
+
+ //
+ // For NwNdsOpenTreeHandle
+ //
+
+ HANDLE hRdr;
+ OEM_STRING oemStr;
+ UNICODE_STRING ObjectName;
+ WCHAR NdsStr[256];
+
+ //
+ // For NwNdsResolveName
+ //
+
+ PNDS_RESPONSE_RESOLVE_NAME psResolveName;
+ DWORD dwOid;
+ UNICODE_STRING ReferredServer;
+ WCHAR ServerName[48];
+ HANDLE hReferredServer;
+ DWORD dwHandleType;
+
+ //
+ // For NwNdsReadObjectInfo
+ //
+
+ BYTE RawResponse[1024];
+ PNDS_RESPONSE_GET_OBJECT_INFO psGetInfo;
+ PBYTE pbRawGetInfo;
+ DWORD dwStrLen;
+
+ //
+ // For NwNdsList
+ //
+
+ DWORD dwIterHandle;
+
+ /**************************************************/
+
+ //
+ // Examine the argument count and hope for the best.
+ //
+
+ if ( argc != 3 ) {
+ printf( "Usage: browser <tree name> <ds object path>\n" );
+ printf( "For example, browser marsdev dev.mars\n");
+ return -1;
+ }
+
+ //
+ // Convert the tree name string to unicode.
+ //
+
+ oemStr.Length = strlen( argv[1] );
+ oemStr.MaximumLength = oemStr.Length;
+ oemStr.Buffer = argv[1];
+
+ ObjectName.Length = 0;
+ ObjectName.MaximumLength = sizeof( NdsStr );
+ ObjectName.Buffer = NdsStr;
+
+ RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE );
+
+ //
+ // Get a handle to the redirector.
+ //
+
+ Status = NwNdsOpenTreeHandle( &ObjectName,
+ &hRdr );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "*** Open Handle to Nds Tree: Status = %08lx\n", Status );
+ return -1;
+ }
+
+ //
+ // Resolve the name that we have to an object id.
+ //
+
+ oemStr.Length = strlen(argv[2]);
+ oemStr.MaximumLength = oemStr.Length;
+ oemStr.Buffer = argv[2];
+
+ ObjectName.Length = 0;
+ ObjectName.MaximumLength = sizeof(NdsStr);
+ ObjectName.Buffer = NdsStr;
+
+ RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE );
+
+ ReferredServer.Buffer = ServerName;
+ ReferredServer.MaximumLength = sizeof( ServerName );
+ ReferredServer.Length = 0;
+
+ Status = NwNdsResolveName ( hRdr,
+ &ObjectName,
+ &dwOid,
+ &ReferredServer,
+ NULL,
+ 0 );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "*** Resolve Name: Status = %08lx\n", Status );
+ goto Exit;
+ }
+
+ if ( ReferredServer.Length != 0 ) {
+
+ //
+ // We have to jump servers.
+ //
+
+ Status = NwNdsOpenGenericHandle( &ReferredServer,
+ &dwHandleType,
+ &hReferredServer );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "*** Couldn't open referred server: Status = %08lx\n", Status );
+ goto Exit;
+ }
+
+ CloseHandle( hRdr );
+ hRdr = hReferredServer;
+ }
+
+ printf( "=========================== NDS Object Info ===========================\n" );
+ printf( "Object ID = 0x%08lx\n", dwOid );
+
+ //
+ // Go for the object information.
+ //
+
+ Status = NwNdsReadObjectInfo( hRdr,
+ dwOid,
+ RawResponse,
+ sizeof( RawResponse ) );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "*** Get Object Info: Status = %08lx\n", Status );
+ goto Exit;
+ }
+
+ psGetInfo = ( PNDS_RESPONSE_GET_OBJECT_INFO ) RawResponse;
+
+ printf( "Flags = 0x%08lx\n", psGetInfo->EntryFlags );
+ printf( "Subordinate Count = 0x%08lx\n", psGetInfo->SubordinateCount );
+ printf( "Last Modified Time = 0x%08lx\n", psGetInfo->ModificationTime );
+
+ //
+ // Dig out the two unicode strings for class name and object name.
+ //
+
+ pbRawGetInfo = RawResponse;
+
+ pbRawGetInfo += sizeof ( NDS_RESPONSE_GET_OBJECT_INFO );
+
+ dwStrLen = * ( DWORD * ) pbRawGetInfo;
+ pbRawGetInfo += sizeof( DWORD );
+ printf( "Class Name: %S\n", pbRawGetInfo );
+
+ pbRawGetInfo += ROUNDUP4( dwStrLen );
+ dwStrLen = * ( DWORD * ) pbRawGetInfo;
+ pbRawGetInfo += sizeof( DWORD );
+ printf( "Object Name: %S\n", pbRawGetInfo );
+
+ //
+ // Get the subordinate list.
+ //
+
+ if ( psGetInfo->SubordinateCount ) {
+
+ dwIterHandle = INITIAL_ITERATION;
+
+ do {
+
+ Status = NwNdsList( hRdr,
+ dwOid,
+ &dwIterHandle,
+ RawResponse,
+ sizeof( RawResponse ) );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "*** List Subordinates: Status = %08lx\n", Status );
+ goto Exit;
+ }
+
+ ConsoleDumpSubordinates( (PNDS_RESPONSE_SUBORDINATE_LIST) RawResponse );
+
+ } while ( dwIterHandle != INITIAL_ITERATION );
+
+ }
+
+
+Exit:
+
+ CloseHandle( hRdr );
+
+ if ( NT_SUCCESS( Status ) ) {
+ return 0;
+ } else {
+ return -1;
+ }
+
+}
+
+
+VOID
+ConsoleDumpSubordinates(
+ PNDS_RESPONSE_SUBORDINATE_LIST pSubList
+) {
+
+ NTSTATUS Status;
+ PNDS_RESPONSE_SUBORDINATE_ENTRY pSubEntry;
+
+ PBYTE pbRaw;
+ DWORD dwStrLen, dwEntries;
+
+ dwEntries = pSubList->SubordinateEntries;
+
+ printf( "======================== Subordinate List (%d) ========================\n", dwEntries );
+
+ pSubEntry = ( PNDS_RESPONSE_SUBORDINATE_ENTRY )
+ ( ( (BYTE *)pSubList ) + sizeof( NDS_RESPONSE_SUBORDINATE_LIST ) );
+
+ while ( dwEntries ) {
+
+ printf( "EntryID (0x%08lx),\tFlags (0x%08lx)\n",
+ pSubEntry->EntryId, pSubEntry->Flags );
+
+ printf( "Subordinate Count (%d),\tMod Time (0x%08lx)\n",
+ pSubEntry->SubordinateCount, pSubEntry->ModificationTime );
+
+ pbRaw = (BYTE *) pSubEntry;
+ pbRaw += sizeof( NDS_RESPONSE_SUBORDINATE_ENTRY );
+
+ dwStrLen = * ( DWORD * ) pbRaw;
+ pbRaw += sizeof( DWORD );
+ printf( "Class Name: %S\t", pbRaw );
+
+ pbRaw += ROUNDUP4( dwStrLen );
+ dwStrLen = * ( DWORD * ) pbRaw;
+ pbRaw += sizeof( DWORD );
+ printf( "Object Name: %S\n", pbRaw );
+
+ pSubEntry = ( PNDS_RESPONSE_SUBORDINATE_ENTRY ) ( pbRaw + ROUNDUP4( dwStrLen ) );
+ dwEntries--;
+
+ printf( "-----------------------------------------------------------------------\n" );
+
+ }
+
+ return;
+
+}
diff --git a/private/nw/ndsutils/conninfo.c b/private/nw/ndsutils/conninfo.c
new file mode 100644
index 000000000..f2a9a878c
--- /dev/null
+++ b/private/nw/ndsutils/conninfo.c
@@ -0,0 +1,156 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ ConnInfo.c
+
+Abstract:
+
+ Command line test for getting the connection information
+ for various connections.
+
+Author:
+
+ Cory West [corywest] 14-Nov-95
+
+***/
+
+#include "ndsapi32.h"
+#include "ntddnwfs.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS ntstatus;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
+ HANDLE hRdr;
+
+ WCHAR OpenString[] = L"\\Device\\Nwrdr\\*";
+ UNICODE_STRING OpenName;
+
+ OEM_STRING OemArg;
+ UNICODE_STRING ConnectionName;
+ WCHAR ConnectionBuffer[512];
+
+ ULONG BufferSize = 512;
+ ULONG RequestSize, ReplyLen;
+ PNWR_REQUEST_PACKET Request;
+ BYTE *Reply;
+
+ PCONN_INFORMATION pConnInfo;
+ UNICODE_STRING Name;
+
+ //
+ // Check the arguments.
+ //
+
+ if ( argc != 2 ) {
+ printf( "Usage: conninfo [connection name]\n" );
+ printf( "For Example: conninfo x:, conninfo lpt1:, or conninfo \\\\server\\share\n" );
+ return -1;
+ }
+
+ //
+ // Allocate buffer space.
+ //
+
+ Request = (PNWR_REQUEST_PACKET) LocalAlloc( LMEM_ZEROINIT, BufferSize );
+
+ if ( !Request ) {
+ printf( "Insufficient memory to complete the request.\n" );
+ return -1;
+ }
+
+ //
+ // Convert the connect name to unicode.
+ //
+
+ ConnectionName.Length = 0;
+ ConnectionName.MaximumLength = sizeof( ConnectionBuffer );
+ ConnectionName.Buffer = ConnectionBuffer;
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ RtlOemStringToUnicodeString( &ConnectionName, &OemArg, FALSE );
+
+ //
+ // Set up the object attributes.
+ //
+
+ RtlInitUnicodeString( &OpenName, OpenString );
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &OpenName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL );
+
+ ntstatus = NtOpenFile( &hRdr,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT );
+
+ if ( !NT_SUCCESS(ntstatus) )
+ return ntstatus;
+
+ //
+ // Fill out the request packet for FSCTL_NWR_GET_CONN_INFO.
+ //
+
+ Request->Parameters.GetConnInfo.ConnectionNameLength = ConnectionName.Length;
+ RtlCopyMemory( &(Request->Parameters.GetConnInfo.ConnectionName[0]),
+ ConnectionBuffer,
+ ConnectionName.Length );
+
+ RequestSize = sizeof( Request->Parameters.GetConnInfo ) + ConnectionName.Length;
+ Reply = ((PBYTE)Request) + RequestSize;
+ ReplyLen = BufferSize - RequestSize;
+
+ ntstatus = NtFsControlFile( hRdr,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_GET_CONN_INFO,
+ (PVOID) Request,
+ RequestSize,
+ (PVOID) Reply,
+ ReplyLen );
+
+ if ( !NT_SUCCESS( ntstatus ) ) {
+ goto ExitWithClose;
+ }
+
+ //
+ // Print out the CONN_INFO that is in the reply buffer.
+ //
+
+ pConnInfo = (PCONN_INFORMATION) Reply;
+
+ Name.Length = Name.MaximumLength = (USHORT) pConnInfo->HostServerLength;
+ Name.Buffer = pConnInfo->HostServer;
+ printf( "Host Server: %wZ\n", &Name );
+
+ Name.Length = Name.MaximumLength = (USHORT) pConnInfo->UserNameLength;
+ Name.Buffer = pConnInfo->UserName;
+ printf( "User Name: %wZ\n", &Name );
+
+
+ExitWithClose:
+
+ LocalFree( Request );
+ NtClose( hRdr );
+ return ntstatus;
+
+}
diff --git a/private/nw/ndsutils/cx.c b/private/nw/ndsutils/cx.c
new file mode 100644
index 000000000..b1147b2cc
--- /dev/null
+++ b/private/nw/ndsutils/cx.c
@@ -0,0 +1,133 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ Cx.c
+
+Abstract:
+
+ This is the command line NDS utility for setting contexts.
+
+Author:
+
+ Cory West [corywest] 25-Oct-95
+
+***/
+
+#include "ndsapi32.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS Status;
+ HANDLE hNdsTree;
+ OEM_STRING OemArg;
+
+ UNICODE_STRING NdsTree;
+ WCHAR TreeBuffer[1024];
+
+ UNICODE_STRING Context;
+ WCHAR ContextBuffer[1024];
+
+ //
+ // Who do we want to monkey with?
+ //
+
+ if ( argc < 2 ) {
+ printf( "Usage: cx [tree name] [optional context]\n" );
+ return -1;
+ }
+
+ //
+ // Get the tree.
+ //
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ NdsTree.Length = 0;
+ NdsTree.MaximumLength = sizeof( TreeBuffer );
+ NdsTree.Buffer = TreeBuffer;
+
+ RtlOemStringToUnicodeString( &NdsTree, &OemArg, FALSE );
+
+ //
+ // Open up a handle to the tree.
+ //
+
+ Status = NwNdsOpenTreeHandle( &NdsTree,
+ &hNdsTree );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The supplied tree name is invalid or the tree is unavailable.\n" );
+ return -1;
+ }
+
+ //
+ // Get or set the context, depending.
+ //
+
+ Context.Length = 0;
+ Context.MaximumLength = sizeof( ContextBuffer );
+ Context.Buffer = ContextBuffer;
+
+ Status = STATUS_UNSUCCESSFUL;
+
+ if ( argc == 2 ) {
+
+ //
+ // Get the context.
+ //
+
+ Status = NwNdsGetTreeContext ( hNdsTree,
+ &NdsTree,
+ &Context );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "You are not logged into the specified tree.\n" );
+ goto Exit;
+ }
+
+ ContextBuffer[Context.Length/sizeof(WCHAR)] = L'\0';
+ printf( "%S", ContextBuffer );
+
+ } else {
+
+ //
+ // Set the context.
+ //
+
+ OemArg.Length = strlen( argv[2] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[2];
+
+ RtlOemStringToUnicodeString( &Context, &OemArg, FALSE );
+
+ Status = NwNdsSetTreeContext ( hNdsTree,
+ &NdsTree,
+ &Context );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "*** Set context: Status = %08lx\n", Status );
+ }
+
+ }
+
+
+Exit:
+
+ CloseHandle( hNdsTree );
+
+ if ( !NT_SUCCESS( Status )) {
+ return -1;
+ }
+
+ return 0;
+
+}
diff --git a/private/nw/ndsutils/getps.c b/private/nw/ndsutils/getps.c
new file mode 100644
index 000000000..a0634bad6
--- /dev/null
+++ b/private/nw/ndsutils/getps.c
@@ -0,0 +1,102 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ GetPs.c
+
+Abstract:
+
+ Command line test for getting the preferred server.
+
+Author:
+
+ Cory West [corywest] 14-Nov-95
+
+***/
+
+#include "ndsapi32.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS ntstatus;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
+ HANDLE hRdr;
+
+ WCHAR OpenString[] = L"\\Device\\Nwrdr\\*";
+ UNICODE_STRING OpenName;
+
+ BYTE Reply[64];
+
+ //
+ // Check the arguments.
+ //
+
+ if ( argc != 1 ) {
+ printf( "Usage: getps\n" );
+ printf( "Retrieves the current preferred server.\n" );
+ return -1;
+ }
+
+ //
+ // Set up the object attributes.
+ //
+
+ RtlInitUnicodeString( &OpenName, OpenString );
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &OpenName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL );
+
+ ntstatus = NtOpenFile( &hRdr,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT );
+
+ if ( !NT_SUCCESS(ntstatus) )
+ return ntstatus;
+
+ //
+ // Call the nwrdr.
+ //
+
+ ntstatus = NtFsControlFile( hRdr,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_GET_PREFERRED_SERVER,
+ NULL,
+ 0,
+ (PVOID) Reply,
+ sizeof( Reply ) );
+
+ if ( !NT_SUCCESS( ntstatus ) ) {
+ printf( "No preferred server is currently set.\n" );
+ goto ExitWithClose;
+ }
+
+ //
+ // On success the output buffer contains a UNICODE_STRING
+ // with the string packed in afterwards.
+ //
+
+ printf( "Preferred Server: %wZ\n", (PUNICODE_STRING) Reply );
+
+ExitWithClose:
+
+ NtClose( hRdr );
+ return ntstatus;
+
+}
diff --git a/private/nw/ndsutils/getuser.c b/private/nw/ndsutils/getuser.c
new file mode 100644
index 000000000..833a0e2f7
--- /dev/null
+++ b/private/nw/ndsutils/getuser.c
@@ -0,0 +1,133 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ GetUser.c
+
+Abstract:
+
+ This is the command line NDS utility for getting the
+ user name used to log into a specified tree or server.
+
+Author:
+
+ Cory West [corywest] 25-Oct-95
+
+***/
+
+#include "ndsapi32.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS ntstatus;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
+ HANDLE hRdr;
+
+ WCHAR DevicePreamble[] = L"\\Device\\Nwrdr\\";
+ UINT PreambleLength = 14;
+
+ WCHAR NameStr[64];
+ UNICODE_STRING OpenName;
+ UINT i;
+
+ OEM_STRING OemArg;
+ UNICODE_STRING NdsTree;
+ WCHAR TreeBuffer[64];
+
+ WCHAR Reply[64];
+
+ //
+ // Check the arguments.
+ //
+
+ if ( argc != 2 ) {
+ printf( "Usage: getuser [tree | server]\n" );
+ return -1;
+ }
+
+ //
+ // Copy over the preamble.
+ //
+
+ OpenName.MaximumLength = sizeof( NameStr );
+
+ for ( i = 0; i < PreambleLength ; i++ )
+ NameStr[i] = DevicePreamble[i];
+
+ //
+ // Convert the argument name to unicode.
+ //
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ NdsTree.Length = 0;
+ NdsTree.MaximumLength = sizeof( TreeBuffer );
+ NdsTree.Buffer = TreeBuffer;
+
+ RtlOemStringToUnicodeString( &NdsTree, &OemArg, FALSE );
+
+ //
+ // Copy the server or tree name.
+ //
+
+ for ( i = 0 ; i < ( NdsTree.Length / sizeof( WCHAR ) ) ; i++ ) {
+ NameStr[i + PreambleLength] = NdsTree.Buffer[i];
+ }
+
+ OpenName.Length = ( i * sizeof( WCHAR ) ) +
+ ( PreambleLength * sizeof( WCHAR ) );
+ OpenName.Buffer = NameStr;
+
+ //
+ // Set up the object attributes.
+ //
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &OpenName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL );
+
+ ntstatus = NtOpenFile( &hRdr,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT );
+
+ if ( !NT_SUCCESS(ntstatus) )
+ return ntstatus;
+
+ ntstatus = NtFsControlFile( hRdr,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_GET_USERNAME,
+ (PVOID) TreeBuffer,
+ NdsTree.Length,
+ (PVOID) Reply,
+ sizeof( Reply ) );
+
+ if ( NT_SUCCESS( ntstatus )) {
+
+ NdsTree.Length = (USHORT)IoStatusBlock.Information;
+ NdsTree.MaximumLength = NdsTree.Length;
+ NdsTree.Buffer = Reply;
+ printf( "%wZ", &NdsTree );
+ }
+
+ NtClose( hRdr );
+ return ntstatus;
+
+}
diff --git a/private/nw/ndsutils/listconn.c b/private/nw/ndsutils/listconn.c
new file mode 100644
index 000000000..75a9e3c8b
--- /dev/null
+++ b/private/nw/ndsutils/listconn.c
@@ -0,0 +1,235 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ ListConn.c
+
+Abstract:
+
+ Command line test for getting the CONN_STATUS structures
+ for various connections.
+
+Author:
+
+ Cory West [corywest] 14-Nov-95
+
+***/
+
+#include "ndsapi32.h"
+#include "ntddnwfs.h"
+
+ULONG DumpConnStatus(
+ PCONN_STATUS pStatus
+);
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS ntstatus;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
+ HANDLE hRdr;
+
+ WCHAR OpenString[] = L"\\Device\\Nwrdr\\*";
+ UNICODE_STRING OpenName;
+
+ OEM_STRING OemArg;
+ UNICODE_STRING NdsTree;
+ WCHAR TreeBuffer[64];
+
+ ULONG BufferSize = 256;
+ ULONG RequestSize, ReplyLen;
+ PNWR_REQUEST_PACKET Request;
+ BYTE *Reply, *LocalBlock;
+ DWORD Entries, BlockLen;
+
+ //
+ // Check the arguments.
+ //
+
+ if ( argc > 2 ) {
+ printf( "Usage: listconn [tree | server]\n" );
+ return -1;
+ }
+
+ //
+ // Allocate buffer space.
+ //
+
+ Request = (PNWR_REQUEST_PACKET) LocalAlloc( LMEM_ZEROINIT, BufferSize );
+
+ if ( !Request ) {
+ printf( "Insufficient memory to complete the request.\n" );
+ return -1;
+ }
+
+ //
+ // Convert the argument name to unicode.
+ //
+
+ NdsTree.Length = 0;
+ NdsTree.MaximumLength = sizeof( TreeBuffer );
+ NdsTree.Buffer = TreeBuffer;
+
+ if ( argc == 2 ) {
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ NdsTree.Length = 0;
+ NdsTree.MaximumLength = sizeof( TreeBuffer );
+ NdsTree.Buffer = TreeBuffer;
+
+ RtlOemStringToUnicodeString( &NdsTree, &OemArg, FALSE );
+
+ }
+
+ //
+ // Set up the object attributes.
+ //
+
+ RtlInitUnicodeString( &OpenName, OpenString );
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &OpenName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL );
+
+ ntstatus = NtOpenFile( &hRdr,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT );
+
+ if ( !NT_SUCCESS(ntstatus) )
+ return ntstatus;
+
+ //
+ // Fill out the request packet for FSCTL_NWR_GET_CONN_STATUS.
+ //
+
+ Request->Parameters.GetConnStatus.ConnectionNameLength = NdsTree.Length;
+ RtlCopyMemory( &(Request->Parameters.GetConnStatus.ConnectionName[0]),
+ TreeBuffer,
+ NdsTree.Length );
+
+ RequestSize = sizeof( NWR_REQUEST_PACKET ) + NdsTree.Length;
+ Reply = ((PBYTE)Request) + RequestSize;
+ ReplyLen = BufferSize - RequestSize;
+
+ do {
+
+ ntstatus = NtFsControlFile( hRdr,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_GET_CONN_STATUS,
+ (PVOID) Request,
+ RequestSize,
+ (PVOID) Reply,
+ ReplyLen );
+
+ if ( !NT_SUCCESS( ntstatus ) ) {
+ goto ExitWithClose;
+ }
+
+ //
+ // Print out this batch and see if we need to continue.
+ //
+ // ATTN!!! The only time that the caller needs to resize
+ // the buffer is when there are no entries returned and the
+ // status is STATUS_BUFFER_TOO_SMALL. When this happens,
+ // the BytesNeeded field contains the smallest usable
+ // buffer size.
+ //
+
+ Entries = Request->Parameters.GetConnStatus.EntriesReturned;
+ printf( "%d entries returned for this call.\n", Entries );
+
+ LocalBlock = Reply;
+
+ while ( Entries-- ) {
+
+ BlockLen = DumpConnStatus( (PCONN_STATUS) LocalBlock );
+ LocalBlock += BlockLen;
+ }
+
+ } while ( Request->Parameters.GetConnStatus.ResumeKey != 0 );
+
+
+ExitWithClose:
+
+ LocalFree( Request );
+ NtClose( hRdr );
+ return ntstatus;
+
+}
+
+ULONG DumpConnStatus(
+ PCONN_STATUS pStatus
+) {
+
+ printf( "--------------------------------------------\n" );
+
+ printf( "Server: %S\n", pStatus->pszServerName );
+ printf( "User: %S\n", pStatus->pszUserName );
+ printf( "NDS Tree: %S\n", pStatus->pszTreeName );
+
+ printf( "Connection Number: %d\n", pStatus->nConnNum );
+
+ if ( pStatus->fNds ) {
+ printf( "Nds Connection: TRUE\n" );
+ } else {
+ printf( "Nds Connection: FALSE\n" );
+ }
+
+ if ( pStatus->fPreferred ) {
+ printf( "Preferred Server: TRUE\n" );
+ } else {
+ printf( "Preferred Server: FALSE\n" );
+ }
+
+ switch ( pStatus->dwConnType ) {
+
+ case NW_CONN_NOT_AUTHENTICATED:
+
+ printf( "Authentication: NOT AUTHENTICATED\n" );
+ break;
+
+ case NW_CONN_BINDERY_LOGIN:
+
+ printf( "Authentication: BINDERY LOGIN\n" );
+ break;
+
+ case NW_CONN_NDS_AUTHENTICATED_NO_LICENSE:
+
+ printf( "Authentication: NDS AUTHENTICATED, NOT LICENSED\n" );
+ break;
+
+ case NW_CONN_NDS_AUTHENTICATED_LICENSED:
+
+ printf( "Authentication: NDS AUTHENTICATED, LICENSED\n" );
+ break;
+
+ case NW_CONN_DISCONNECTED:
+
+ printf( "Authentication: DISCONNECTED\n" );
+ break;
+
+ }
+
+ printf( "--------------------------------------------\n" );
+
+ return pStatus->dwTotalLength;
+}
+
diff --git a/private/nw/ndsutils/makefile b/private/nw/ndsutils/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/nw/ndsutils/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/ndsutils/ndschpw.c b/private/nw/ndsutils/ndschpw.c
new file mode 100644
index 000000000..25eedc513
--- /dev/null
+++ b/private/nw/ndsutils/ndschpw.c
@@ -0,0 +1,173 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ NdsChPw.c
+
+Abstract:
+
+ This is the command line NDS utility for changing a
+ user's NDS password.
+
+Author:
+
+ Cory West [corywest] 12-Jan-96
+
+***/
+
+#include <ndsapi32.h>
+#include <nds.h>
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS ntstatus;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
+ HANDLE hRdr;
+
+ WCHAR DevicePreamble[] = L"\\Device\\Nwrdr\\";
+ UINT PreambleLength = 14;
+
+ UNICODE_STRING OpenName;
+ WCHAR NameStr[64];
+ UINT i;
+
+ OEM_STRING OemArg;
+
+ UNICODE_STRING NdsTree;
+ WCHAR TreeBuffer[MAX_NDS_TREE_NAME_LEN];
+
+ UNICODE_STRING UserName;
+ WCHAR UserBuffer[MAX_NDS_NAME_CHARS];
+
+ UNICODE_STRING CurrPass;
+ WCHAR CurrPassBuffer[64];
+
+ UNICODE_STRING NewPass;
+ WCHAR NewPassBuffer[64];
+
+ //
+ // Check the arguments.
+ //
+
+ if ( argc != 5 ) {
+ printf( "Usage: ndschpw tree user current_pw new_pw\n" );
+ return -1;
+ }
+
+ //
+ // Copy over the preamble.
+ //
+
+ OpenName.MaximumLength = sizeof( NameStr );
+
+ for ( i = 0; i < PreambleLength ; i++ )
+ NameStr[i] = DevicePreamble[i];
+
+ //
+ // Convert the argument name to unicode.
+ //
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ NdsTree.Length = 0;
+ NdsTree.MaximumLength = sizeof( TreeBuffer );
+ NdsTree.Buffer = TreeBuffer;
+
+ RtlOemStringToUnicodeString( &NdsTree, &OemArg, FALSE );
+
+ //
+ // Copy the server or tree name.
+ //
+
+ for ( i = 0 ; i < ( NdsTree.Length / sizeof( WCHAR ) ) ; i++ ) {
+ NameStr[i + PreambleLength] = NdsTree.Buffer[i];
+ }
+
+ OpenName.Length = ( i * sizeof( WCHAR ) ) +
+ ( PreambleLength * sizeof( WCHAR ) );
+ OpenName.Buffer = NameStr;
+
+ //
+ // Set up the object attributes.
+ //
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &OpenName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL );
+
+ ntstatus = NtOpenFile( &hRdr,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT );
+
+ if ( !NT_SUCCESS(ntstatus) )
+ return ntstatus;
+
+ //
+ // Convert the other args to unicode.
+ //
+
+ OemArg.Length = strlen( argv[2] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[2];
+
+ UserName.Length = 0;
+ UserName.MaximumLength = sizeof( UserBuffer );
+ UserName.Buffer = UserBuffer;
+
+ RtlOemStringToUnicodeString( &UserName, &OemArg, FALSE );
+
+ OemArg.Length = strlen( argv[3] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[3];
+
+ CurrPass.Length = 0;
+ CurrPass.MaximumLength = sizeof( CurrPassBuffer );
+ CurrPass.Buffer = CurrPassBuffer;
+
+ RtlOemStringToUnicodeString( &CurrPass, &OemArg, FALSE );
+
+ OemArg.Length = strlen( argv[4] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[4];
+
+ NewPass.Length = 0;
+ NewPass.MaximumLength = sizeof( NewPassBuffer );
+ NewPass.Buffer = NewPassBuffer;
+
+ RtlOemStringToUnicodeString( &NewPass, &OemArg, FALSE );
+
+ //
+ // Submit the request.
+ //
+
+ ntstatus = NwNdsChangePassword( hRdr,
+ &NdsTree,
+ &UserName,
+ &CurrPass,
+ &NewPass );
+
+ if ( NT_SUCCESS( ntstatus )) {
+ printf( "Password changed.\n" );
+ } else {
+ printf( "Password change failed!\n" );
+ }
+
+ NtClose( hRdr );
+ return ntstatus;
+
+}
diff --git a/private/nw/ndsutils/netperf.c b/private/nw/ndsutils/netperf.c
new file mode 100644
index 000000000..e509f3fe7
--- /dev/null
+++ b/private/nw/ndsutils/netperf.c
@@ -0,0 +1,138 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ netperf.c
+
+Abstract:
+
+ Command line test for getting the connection performance.
+
+Author:
+
+ Cory West [corywest] 17-April-96
+
+***/
+
+#include "ndsapi32.h"
+#include "ntddnwfs.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS ntstatus;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
+ HANDLE hRdr;
+
+ WCHAR OpenString[] = L"\\Device\\Nwrdr\\*";
+ UNICODE_STRING OpenName;
+
+ OEM_STRING OemArg;
+ UNICODE_STRING ConnectionName;
+
+ PNWR_REQUEST_PACKET Request;
+ ULONG BufferSize = 512;
+ ULONG RequestSize;
+
+ //
+ // Check the arguments.
+ //
+
+ if ( argc != 2 ) {
+ printf( "Usage: netperf [remote name]\n" );
+ return -1;
+ }
+
+ //
+ // Allocate buffer space.
+ //
+
+ Request = (PNWR_REQUEST_PACKET) LocalAlloc( LMEM_ZEROINIT, BufferSize );
+
+ if ( !Request ) {
+ printf( "Insufficient memory to complete the request.\n" );
+ return -1;
+ }
+
+ //
+ // Convert the connect name to unicode.
+ //
+
+ ConnectionName.Length = 0;
+ ConnectionName.MaximumLength = (USHORT) ( BufferSize - sizeof( NWR_REQUEST_PACKET ) );
+ ConnectionName.Buffer = &(Request->Parameters.GetConnPerformance.RemoteName[0]);
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ RtlOemStringToUnicodeString( &ConnectionName, &OemArg, FALSE );
+
+ //
+ // Set up the object attributes.
+ //
+
+ RtlInitUnicodeString( &OpenName, OpenString );
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &OpenName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL );
+
+ ntstatus = NtOpenFile( &hRdr,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT );
+
+ if ( !NT_SUCCESS(ntstatus) )
+ return ntstatus;
+
+ //
+ // Fill out the request packet for FSCTL_NWR_GET_CONN_PERFORMANCE.
+ //
+
+ Request->Parameters.GetConnPerformance.RemoteNameLength = ConnectionName.Length;
+ RequestSize = sizeof( NWR_REQUEST_PACKET ) + ConnectionName.Length;
+
+ ntstatus = NtFsControlFile( hRdr,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_GET_CONN_PERFORMANCE,
+ (PVOID) Request,
+ RequestSize,
+ NULL,
+ 0 );
+
+ if ( !NT_SUCCESS( ntstatus ) ) {
+ goto ExitWithClose;
+ }
+
+ //
+ // Print out the speed and packet size.
+ //
+
+ printf( "Speed: %d\n", Request->Parameters.GetConnPerformance.dwSpeed );
+ printf( "Flags: %d\n", Request->Parameters.GetConnPerformance.dwFlags );
+ printf( "Delay: %d\n", Request->Parameters.GetConnPerformance.dwDelay );
+ printf( "Packet Size: %d\n", Request->Parameters.GetConnPerformance.dwOptDataSize );
+
+
+ExitWithClose:
+
+ LocalFree( Request );
+ NtClose( hRdr );
+ return ntstatus;
+
+}
diff --git a/private/nw/ndsutils/rdstrm.c b/private/nw/ndsutils/rdstrm.c
new file mode 100644
index 000000000..f7e8b1491
--- /dev/null
+++ b/private/nw/ndsutils/rdstrm.c
@@ -0,0 +1,195 @@
+//
+// NDS File Stream Cat
+// Cory West
+//
+
+#include "ndsapi32.h"
+#include <nds.h>
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS Status;
+
+ //
+ // For NwNdsOpenTreeHandle
+ //
+
+ HANDLE hRdr;
+ OEM_STRING oemStr;
+ UNICODE_STRING ObjectName;
+ WCHAR NdsStr[1024];
+
+ //
+ // For NwNdsResolveName
+ //
+
+ PNDS_RESPONSE_RESOLVE_NAME psResolveName;
+ DWORD dwOid;
+ HANDLE hReferredServer;
+ DWORD dwHandleType;
+ UNICODE_STRING ReferredServer;
+ WCHAR ServerName[48];
+
+ //
+ // For ReadFile of an open stream.
+ //
+
+ DWORD dwBytesRead, dwFileLength, dwBytesShown;
+ BOOL bRead;
+ BYTE RawResponse[1024];
+
+ /**************************************************/
+
+ //
+ // Examine the argument count and hope for the best.
+ //
+
+ if ( argc < 3 ) {
+ printf( "Usage: rdstrm <tree name> <ds object path> <file stream>\n" );
+ printf( "For example, rdstrm tree user.orgunit.org \"Login Script\"\n");
+ return -1;
+ }
+
+ //
+ // Convert the tree name string to unicode.
+ //
+
+ oemStr.Length = strlen( argv[1] );
+ oemStr.MaximumLength = oemStr.Length;
+ oemStr.Buffer = argv[1];
+
+ ObjectName.Length = 0;
+ ObjectName.MaximumLength = sizeof( NdsStr );
+ ObjectName.Buffer = NdsStr;
+
+ RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE );
+
+ //
+ // Get a handle to the redirector.
+ //
+
+ Status = NwNdsOpenTreeHandle( &ObjectName, &hRdr );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The tree is not available. Status was %08lx.\n", Status );
+ return -1;
+ }
+
+ //
+ // Resolve the name that we have to an object id.
+ //
+
+ oemStr.Length = strlen(argv[2]);
+ oemStr.MaximumLength = oemStr.Length;
+ oemStr.Buffer = argv[2];
+
+ ObjectName.Length = 0;
+ ObjectName.MaximumLength = sizeof(NdsStr);
+ ObjectName.Buffer = NdsStr;
+
+ RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE );
+
+ ReferredServer.Buffer = ServerName;
+ ReferredServer.MaximumLength = sizeof( ServerName );
+ ReferredServer.Length = 0;
+
+ Status = NwNdsResolveName ( hRdr,
+ &ObjectName,
+ &dwOid,
+ &ReferredServer,
+ NULL,
+ 0 );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The object is not available. Status = %08lx.\n", Status );
+ goto Exit;
+ }
+
+ if ( ReferredServer.Length != 0 ) {
+
+ Status = NwNdsOpenGenericHandle( &ReferredServer,
+ &dwHandleType,
+ &hReferredServer );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The object's referred server is not available. Status = %08lx.\n", Status );
+ goto Exit;
+ }
+
+ CloseHandle( hRdr );
+ hRdr = hReferredServer;
+ }
+
+ //
+ // Try to open a file stream for read access.
+ //
+
+ oemStr.Length = strlen(argv[3]);
+ oemStr.MaximumLength = oemStr.Length;
+ oemStr.Buffer = argv[3];
+
+ ObjectName.Length = 0;
+ ObjectName.MaximumLength = sizeof(NdsStr);
+ ObjectName.Buffer = NdsStr;
+
+ RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE );
+
+ Status = NwNdsOpenStream( hRdr,
+ dwOid,
+ &ObjectName,
+ 1,
+ &dwFileLength );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The file stream is not available. Status = %08lx.\n", Status );
+ goto Exit;
+ }
+
+ //
+ // Dump the file stream.
+ //
+
+ printf( "---------- There are %d bytes in file stream %s ----------\n", dwFileLength, argv[3] );
+
+ while ( dwFileLength ) {
+
+ bRead = ReadFile( hRdr,
+ RawResponse,
+ sizeof( RawResponse ),
+ &dwBytesRead,
+ NULL );
+
+ if ( !bRead ) {
+
+ printf( "*** Couldn't read data from file stream.\n" );
+ goto Exit;
+ }
+
+ dwFileLength -= dwBytesRead;
+ dwBytesShown = 0;
+
+ while ( dwBytesRead-- ) {
+ printf( "%c", RawResponse[dwBytesShown++] );
+ }
+
+
+ }
+
+ printf( "\n-----------------------------------------------------------------------\n" );
+
+Exit:
+
+ CloseHandle( hRdr );
+
+ if ( !NT_SUCCESS( Status )) {
+ return -1;
+ } else {
+ return 0;
+ }
+
+}
+
diff --git a/private/nw/ndsutils/setshare.c b/private/nw/ndsutils/setshare.c
new file mode 100644
index 000000000..92caf2ee8
--- /dev/null
+++ b/private/nw/ndsutils/setshare.c
@@ -0,0 +1,88 @@
+/***
+
+Copyright (c) 1996 Microsoft Corporation
+
+Module Name:
+
+ SetShare.c
+
+Abstract:
+
+ This is a command line test utility for setting the
+ shareable bit on a file on a Netware server.
+
+Author:
+
+ Cory West [corywest] 25-April-96
+
+***/
+
+#include "ndsapi32.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS Status;
+ int ReturnCode = 0;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE hFile;
+
+ //
+ // Check the command line arguments for a file.
+ //
+
+ if ( argc < 1 ) {
+ printf( "Usage: setshare [path to file]\n" );
+ return -1;
+ }
+
+ //
+ // Open the file.
+ //
+
+ hFile = CreateFile( argv[1], // file name
+ GENERIC_READ, // read access
+ 0, // exclusive
+ NULL, // no security specifications
+ OPEN_EXISTING, // do not create
+ 0, // no attributes that we care about
+ NULL ); // no template
+
+ if ( hFile == INVALID_HANDLE_VALUE ) {
+ printf( "Couldn't open the request file. Error = %08lx\n", Status );
+ return -1;
+ }
+
+ //
+ // Tell the redirector to set the shareable bit.
+ //
+
+ Status = NtFsControlFile( hFile,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_SET_SHAREBIT,
+ NULL,
+ 0,
+ NULL,
+ 0 );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "A parameter was not correct. This only works for a file\n" );
+ printf( "on a Netware volume. Status = %08lx\n", Status );
+ ReturnCode = -1;
+ }
+
+ CloseHandle( hFile );
+
+ //
+ // The bit actually gets set when you close the file.
+ //
+
+ return ReturnCode;
+
+}
diff --git a/private/nw/ndsutils/sources b/private/nw/ndsutils/sources
new file mode 100644
index 000000000..595e412ff
--- /dev/null
+++ b/private/nw/ndsutils/sources
@@ -0,0 +1,46 @@
+!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=cx
+TARGETPATH=obj
+TARGETTYPE=library
+
+UMTYPE=console
+UMAPPL=cx*rdstrm*getuser*listconn*volinfo*conninfo*getps*browser*userfrag*ndschpw*treebn*netperf*setshare
+UMLIBS=
+UNICODE=1
+NTDEBUGTYPE=both
+NTDEBUG=ntsd
+386_OPTIMIZATION=/Od
+
+INCLUDES=..\inc;$(_NTROOT)\private\ntos\inc;$(_NTROOT)\private\inc;..\rdr
+
+SOURCES=
+
+UMLIBS=$(BASEDIR)\public\sdk\lib\*\ntdll.lib \
+ $(BASEDIR)\public\sdk\lib\*\nwapi32.lib
+
diff --git a/private/nw/ndsutils/treebn.c b/private/nw/ndsutils/treebn.c
new file mode 100644
index 000000000..77a735e37
--- /dev/null
+++ b/private/nw/ndsutils/treebn.c
@@ -0,0 +1,182 @@
+/***
+
+Copyright (c) 1996 Microsoft Corporation
+
+Module Name:
+
+ Treebn.c
+
+Abstract:
+
+ Command line test for getting the connection information
+ for a particular NT user name.
+
+Author:
+
+ Cory West [corywest] 1-March-1996
+
+***/
+
+#include "ndsapi32.h"
+#include "ntddnwfs.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS ntstatus;
+ IO_STATUS_BLOCK IoStatusBlock;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
+ HANDLE hRdr;
+
+ WCHAR OpenString[] = L"\\Device\\Nwrdr\\*";
+ UNICODE_STRING OpenName;
+
+ OEM_STRING OemArg;
+ UNICODE_STRING NtUserName;
+ WCHAR NtUserBuffer[512];
+
+ ULONG BufferSize = 4096;
+ BYTE *Reply;
+
+ PNWR_NDS_REQUEST_PACKET Request;
+ BYTE RequestBuffer[2048];
+ ULONG RequestSize;
+
+ PCONN_INFORMATION pConnInfo;
+ UNICODE_STRING Name;
+ DWORD dwTrees, dwSize;
+
+ //
+ // Check the arguments.
+ //
+
+ if ( argc != 2 ) {
+ printf( "Usage: treebn [nt user name]\n" );
+ return -1;
+ }
+
+ //
+ // Allocate buffer space.
+ //
+
+ Reply = LocalAlloc( LMEM_ZEROINIT, BufferSize );
+
+ if ( !Reply ) {
+ printf( "Insufficient memory to complete the request.\n" );
+ return -1;
+ }
+
+ //
+ // Convert the user name to unicode.
+ //
+
+ NtUserName.Length = 0;
+ NtUserName.MaximumLength = sizeof( NtUserBuffer );
+ NtUserName.Buffer = NtUserBuffer;
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ RtlOemStringToUnicodeString( &NtUserName, &OemArg, FALSE );
+
+ //
+ // Set up the object attributes.
+ //
+
+ RtlInitUnicodeString( &OpenName, OpenString );
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &OpenName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL );
+
+ ntstatus = NtOpenFile( &hRdr,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT );
+
+ if ( !NT_SUCCESS(ntstatus) )
+ return ntstatus;
+
+ //
+ // Fill out the request packet for FSCTL_NWR_NDS_LIST_TREES;
+ //
+
+ Request = ( PNWR_NDS_REQUEST_PACKET ) RequestBuffer;
+
+ Request->Parameters.ListTrees.NtUserNameLength = NtUserName.Length;
+
+ RtlCopyMemory( &(Request->Parameters.ListTrees.NtUserName[0]),
+ NtUserBuffer,
+ NtUserName.Length );
+
+ RequestSize = sizeof( Request->Parameters.ListTrees ) +
+ NtUserName.Length +
+ sizeof( DWORD );
+
+ ntstatus = NtFsControlFile( hRdr,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_NWR_NDS_LIST_TREES,
+ (PVOID) Request,
+ RequestSize,
+ (PVOID) Reply,
+ BufferSize );
+
+ if ( !NT_SUCCESS( ntstatus ) ) {
+ goto ExitWithClose;
+ }
+
+ //
+ // Print out the CONN_INFO array that is in the reply buffer.
+ //
+
+ dwTrees = Request->Parameters.ListTrees.TreesReturned;
+ printf( "Returned %d trees.\n", dwTrees );
+ printf( "Luid was %08lx\n", Request->Parameters.ListTrees.UserLuid.LowPart );
+
+ printf( "------------------------\n" );
+
+ pConnInfo = (PCONN_INFORMATION) Reply;
+
+ while ( dwTrees > 0 ) {
+
+ dwSize = sizeof( CONN_INFORMATION );
+
+ Name.Length = Name.MaximumLength = (USHORT) pConnInfo->HostServerLength;
+ Name.Buffer = pConnInfo->HostServer;
+ printf( "Tree: %wZ\n", &Name );
+
+ dwSize += Name.Length;
+
+ Name.Length = Name.MaximumLength = (USHORT) pConnInfo->UserNameLength;
+ Name.Buffer = pConnInfo->UserName;
+ printf( "User Name: %wZ\n", &Name );
+
+ dwSize += Name.Length;
+
+ pConnInfo = (PCONN_INFORMATION) ( ((BYTE *)pConnInfo) + dwSize );
+ dwTrees--;
+
+ printf( "------------------------\n" );
+ }
+
+ ntstatus = STATUS_SUCCESS;
+
+ExitWithClose:
+
+ LocalFree( Request );
+ NtClose( hRdr );
+ return ntstatus;
+
+}
diff --git a/private/nw/ndsutils/userfrag.c b/private/nw/ndsutils/userfrag.c
new file mode 100644
index 000000000..7b8d7efef
--- /dev/null
+++ b/private/nw/ndsutils/userfrag.c
@@ -0,0 +1,149 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ UserFrag.c
+
+Abstract:
+
+ User mode fragment exchange test.
+
+Author:
+
+ Cory West [corywest] 05-Jan-1996
+
+***/
+
+#include "ndsapi32.h"
+#include <nds.h>
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS Status;
+ HANDLE hNdsTree;
+ OEM_STRING OemArg;
+
+ UNICODE_STRING NdsTree;
+ WCHAR TreeBuffer[48]; // Max nds tree name length.
+
+ UNICODE_STRING Object;
+ WCHAR ObjectBuffer[256]; // Max nds name length.
+
+ DWORD dwResolverFlags;
+ DWORD dwOid;
+ DWORD dwReplyLength;
+ BYTE NdsReply[NDS_BUFFER_SIZE];
+
+ //
+ // Who do we want to monkey with?
+ //
+
+ if ( argc != 3 ) {
+ printf( "Usage: userfrag [server name] [nds object]\n" );
+ return -1;
+ }
+
+ //
+ // Get the server.
+ //
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ NdsTree.Length = 0;
+ NdsTree.MaximumLength = sizeof( TreeBuffer );
+ NdsTree.Buffer = TreeBuffer;
+
+ RtlOemStringToUnicodeString( &NdsTree, &OemArg, FALSE );
+
+ //
+ // Open up a handle to the tree.
+ //
+
+ Status = NwNdsOpenTreeHandle( &NdsTree,
+ &hNdsTree );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The supplied tree name is invalid or the tree is unavailable.\n" );
+ return -1;
+ }
+
+ //
+ // Get the object information.
+ //
+
+ OemArg.Length = strlen( argv[2] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[2];
+
+ Object.Length = 0;
+ Object.MaximumLength = sizeof( ObjectBuffer );
+ Object.Buffer = ObjectBuffer;
+
+ RtlOemStringToUnicodeString( &Object, &OemArg, FALSE );
+
+ dwResolverFlags = RSLV_DEREF_ALIASES | RSLV_WALK_TREE | RSLV_WRITABLE;
+
+ Status = FragExWithWait( hNdsTree,
+ NDSV_RESOLVE_NAME,
+ NdsReply,
+ NDS_BUFFER_SIZE,
+ &dwReplyLength,
+ "DDDSDDDD",
+ 0, // version
+ dwResolverFlags, // flags
+ 0, // scope
+ &Object, // distinguished name
+ 1,0, // transport type
+ 1,0 ); // treeWalker type
+
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The resolve name failed.\n" );
+ goto ExitWithClose;
+ }
+
+ Status = ParseResponse( NdsReply,
+ dwReplyLength,
+ "G_D",
+ 2 * sizeof( DWORD ), // Skip the first two DWORDs
+ &dwOid );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The resolve name response was undecipherable.\n" );
+ goto ExitWithClose;
+ }
+
+ Status = FragExWithWait( hNdsTree,
+ NDSV_READ_ENTRY_INFO,
+ NdsReply,
+ NDS_BUFFER_SIZE,
+ &dwReplyLength,
+ "DD",
+ 0,
+ dwOid );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The get object info failed.\n" );
+ goto ExitWithClose;
+ }
+
+ExitWithClose:
+
+ CloseHandle( hNdsTree );
+
+ if ( NT_SUCCESS( Status ) ) {
+ return 0;
+ }
+
+ printf( "Unable to complete the requested operation: 0x%08lx\n", Status );
+ return -1;
+
+}
diff --git a/private/nw/ndsutils/volinfo.c b/private/nw/ndsutils/volinfo.c
new file mode 100644
index 000000000..1e2d838a3
--- /dev/null
+++ b/private/nw/ndsutils/volinfo.c
@@ -0,0 +1,119 @@
+/***
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ VolInfo.c
+
+Abstract:
+
+ A command line NDS utility for resolving volume objects.
+
+Author:
+
+ Cory West [corywest] 25-Oct-95
+
+***/
+
+#include "ndsapi32.h"
+
+int
+_cdecl main(
+ int argc,
+ char **argv
+) {
+
+ NTSTATUS Status;
+ HANDLE hNdsTree;
+ OEM_STRING OemArg;
+
+ UNICODE_STRING NdsTree;
+ WCHAR TreeBuffer[48]; // Max nds tree name length.
+
+ UNICODE_STRING Volume;
+ WCHAR VolumeBuffer[256]; // Max nds name length.
+
+ UNICODE_STRING HostServer, HostVolume;
+ WCHAR HostServerBuffer[48];
+ WCHAR HostVolumeBuffer[256];
+
+ //
+ // Who do we want to monkey with?
+ //
+
+ if ( argc != 3 ) {
+ printf( "Usage: volinfo [tree name] [volume object]\n" );
+ return -1;
+ }
+
+ //
+ // Get the tree.
+ //
+
+ OemArg.Length = strlen( argv[1] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[1];
+
+ NdsTree.Length = 0;
+ NdsTree.MaximumLength = sizeof( TreeBuffer );
+ NdsTree.Buffer = TreeBuffer;
+
+ RtlOemStringToUnicodeString( &NdsTree, &OemArg, FALSE );
+
+ //
+ // Open up a handle to the tree.
+ //
+
+ Status = NwNdsOpenTreeHandle( &NdsTree,
+ &hNdsTree );
+
+ if ( !NT_SUCCESS( Status ) ) {
+ printf( "The supplied tree name is invalid or the tree is unavailable.\n" );
+ return -1;
+ }
+
+ //
+ // Get the volume information.
+ //
+
+ OemArg.Length = strlen( argv[2] );
+ OemArg.MaximumLength = OemArg.Length;
+ OemArg.Buffer = argv[2];
+
+ Volume.Length = 0;
+ Volume.MaximumLength = sizeof( VolumeBuffer );
+ Volume.Buffer = VolumeBuffer;
+
+ RtlOemStringToUnicodeString( &Volume, &OemArg, FALSE );
+
+ //
+ // Set up the reply strings.
+ //
+
+ HostServer.Length = 0;
+ HostServer.MaximumLength = sizeof( HostServerBuffer );
+ HostServer.Buffer = HostServerBuffer;
+
+ HostVolume.Length = 0;
+ HostVolume.MaximumLength = sizeof( HostVolumeBuffer );
+ HostVolume.Buffer = HostVolumeBuffer;
+
+ Status = NwNdsGetVolumeInformation( hNdsTree,
+ &Volume,
+ &HostServer,
+ &HostVolume );
+
+
+ CloseHandle( hNdsTree );
+
+ if ( NT_SUCCESS( Status )) {
+ printf( "Host Server: %wZ\n", &HostServer );
+ printf( "Host Volume: %wZ\n", &HostVolume );
+ return 0;
+ }
+
+ printf( "Unable to complete the requested operation: 0x%08lx\n", Status );
+ return -1;
+
+}