Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

534 lines
11 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
dir.c
Abstract:
Make and Verify routines for Directory class SMBs.
Author:
David Treadwell (davidtr) 20-Nov-1989
Chuck Lenzmeier (chuckl)
Revision History:
--*/
#define INCLUDE_SMB_DIRECTORY
#include "usrv.h"
NTSTATUS
MakeCreateDirectorySmb(
IN OUT PDESCRIPTOR Redir,
IN OUT PVOID Buffer,
IN OUT PVOID ForcedParams OPTIONAL,
IN UCHAR AndXCommand,
IN PID_SELECTIONS IdSelections,
IN PID_VALUES IdValues,
OUT PULONG SmbSize
)
{
PSMB_HEADER Header;
PREQ_CREATE_DIRECTORY Params;
NTSTATUS status;
AndXCommand; // prevent compiler warnings
Header = (PSMB_HEADER)Buffer;
if ( ForcedParams == NULL ) {
Params = (PREQ_CREATE_DIRECTORY)(Header + 1);
status = MakeSmbHeader(
Redir,
Header,
SMB_COM_CREATE_DIRECTORY,
IdSelections,
IdValues
);
if ( !NT_SUCCESS(status) ) {
return status;
}
} else {
Params = (PREQ_CREATE_DIRECTORY)(ForcedParams);
}
Params->WordCount = 0;
SmbPutUshort(
&Params->ByteCount,
(USHORT)(FileDefs[IdSelections->Fid].Name.Length + 1)
);
RtlMoveMemory(
Params->Buffer,
FileDefs[IdSelections->Fid].Name.Buffer,
FileDefs[IdSelections->Fid].Name.Length + 1
);
*SmbSize = GET_ANDX_OFFSET(
Header,
Params,
REQ_CREATE_DIRECTORY,
SmbGetUshort( &Params->ByteCount )
);
return STATUS_SUCCESS;
} // MakeCreateDirectorySmb
NTSTATUS
VerifyCreateDirectory(
IN OUT PDESCRIPTOR Redir,
IN PVOID ForcedParams OPTIONAL,
IN UCHAR AndXCommand,
IN PID_SELECTIONS IdSelections,
IN OUT PID_VALUES IdValues,
OUT PULONG SmbSize,
IN PVOID Buffer
)
{
PSMB_HEADER Header;
PRESP_CREATE_DIRECTORY Params;
NTSTATUS status;
AndXCommand, SmbSize; // prevent compiler warnings
Header = (PSMB_HEADER)(Buffer);
if ( ForcedParams == NULL ) {
Params = (PRESP_CREATE_DIRECTORY)(Header + 1);
status = VerifySmbHeader(
Redir,
IdSelections,
IdValues,
Header,
SMB_COM_CREATE_DIRECTORY
);
if( !NT_SUCCESS(status) ) {
return status;
}
} else {
Params = (PRESP_CREATE_DIRECTORY)ForcedParams;
}
return STATUS_SUCCESS;
} // VerifyCreateDirectory
NTSTATUS
CreateDirectory2(
IN OUT PDESCRIPTOR Redir,
IN PSZ DebugString,
IN PVOID Unused,
IN UCHAR SubCommand,
IN PID_SELECTIONS IdSelections,
IN PID_VALUES IdValues,
OUT PULONG Unused2
)
{
NTSTATUS status;
PSZ dirName;
USHORT setup;
CLONG inSetupCount;
CLONG outSetupCount;
PVOID parameters;
CLONG inParameterCount;
CLONG outParameterCount;
PVOID data = NULL;
CLONG inDataCount = 0;
CLONG outDataCount = 0;
PREQ_CREATE_DIRECTORY2 request;
Unused, Unused2, SubCommand;
inSetupCount = 1;
outSetupCount = 0;
setup = TRANS2_CREATE_DIRECTORY;
dirName = Redir->argv[1];
if ( *(dirName+1) == ':' ) {
dirName += 2;
}
inParameterCount = sizeof(REQ_CREATE_DIRECTORY2) + strlen( dirName );
outParameterCount = 2;
parameters = malloc( inParameterCount );
request = parameters;
SmbPutUlong( &request->Reserved, 0 );
RtlMoveMemory( request->Buffer, dirName, strlen( dirName ) + 1 );
AllocateAndBuildFeaList(
&data,
&inDataCount,
&Redir->argv[1],
(SHORT)(Redir->argc-1)
);
//
// If the size of the list was four, then there were no eas, so
// don't send any.
//
if ( inDataCount == 4 ) {
inDataCount = 0;
}
status = SendAndReceiveTransaction(
Redir,
DebugString,
IdSelections,
IdValues,
SMB_COM_TRANSACTION2,
&setup,
inSetupCount,
&outSetupCount,
"",
0,
parameters,
inParameterCount,
&outParameterCount,
data,
inDataCount,
&outDataCount
);
if ( !NT_SUCCESS(status) ) {
goto exit;
}
if ( outSetupCount != 0 ) {
printf( "CreateDirectory2: bad return setup count: %ld\n",
outSetupCount );
status = STATUS_UNSUCCESSFUL;
goto exit;
}
if ( outParameterCount != 2 ) {
printf( "CreateDirectory2: bad return parameter count: %ld\n",
outParameterCount );
status = STATUS_UNSUCCESSFUL;
goto exit;
}
#if 0 // OS/2 server doesn't set this field.
if ( ((PRESP_CREATE_DIRECTORY2)parameters)->EaErrorOffset != 0 ) {
printf( "CreateDirectory2: EA error. Offset: %ld\n",
((PRESP_CREATE_DIRECTORY2)parameters)->EaErrorOffset );
status = STATUS_UNSUCCESSFUL;
goto exit;
}
#endif
status = STATUS_PENDING;
exit:
free( parameters );
if ( data != NULL ) {
free( data );
}
return status;
} // CreateDirectory2
NTSTATUS
MakeDeleteDirectorySmb(
IN OUT PDESCRIPTOR Redir,
IN OUT PVOID Buffer,
IN OUT PVOID ForcedParams OPTIONAL,
IN UCHAR AndXCommand,
IN PID_SELECTIONS IdSelections,
IN PID_VALUES IdValues,
OUT PULONG SmbSize
)
{
PSMB_HEADER Header;
PREQ_DELETE_DIRECTORY Params;
NTSTATUS status;
AndXCommand; // prevent compiler warnings
Header = (PSMB_HEADER)Buffer;
if ( ForcedParams == NULL ) {
Params = (PREQ_DELETE_DIRECTORY)(Header + 1);
status = MakeSmbHeader(
Redir,
Header,
SMB_COM_DELETE_DIRECTORY,
IdSelections,
IdValues
);
if ( !NT_SUCCESS(status) ) {
return status;
}
} else {
Params = (PREQ_DELETE_DIRECTORY)(ForcedParams);
}
Params->WordCount = 0;
if ( IdSelections->Fid != 0xF ) {
SmbPutUshort(
&Params->ByteCount,
(USHORT)(FileDefs[IdSelections->Fid].Name.Length + 1)
);
RtlMoveMemory(
Params->Buffer,
FileDefs[IdSelections->Fid].Name.Buffer,
FileDefs[IdSelections->Fid].Name.Length + 1
);
} else {
PSZ dirName = Redir->argv[1];
if ( *(dirName+1) == ':' ) {
dirName += 2;
}
SmbPutUshort( &Params->ByteCount, (USHORT)(strlen( dirName ) + 2) );
RtlMoveMemory( Params->Buffer + 1, dirName, strlen( dirName ) + 1 );
}
*SmbSize = GET_ANDX_OFFSET(
Header,
Params,
REQ_DELETE_DIRECTORY,
SmbGetUshort( &Params->ByteCount )
);
return STATUS_SUCCESS;
} // MakeDeleteDirectorySmb
NTSTATUS
VerifyDeleteDirectory(
IN OUT PDESCRIPTOR Redir,
IN PVOID ForcedParams OPTIONAL,
IN UCHAR AndXCommand,
IN PID_SELECTIONS IdSelections,
IN OUT PID_VALUES IdValues,
OUT PULONG SmbSize,
IN PVOID Buffer
)
{
PSMB_HEADER Header;
PRESP_DELETE_DIRECTORY Params;
NTSTATUS status;
AndXCommand, SmbSize; // prevent compiler warnings
Header = (PSMB_HEADER)(Buffer);
if ( ForcedParams == NULL ) {
Params = (PRESP_DELETE_DIRECTORY)(Header + 1);
status = VerifySmbHeader(
Redir,
IdSelections,
IdValues,
Header,
SMB_COM_DELETE_DIRECTORY
);
if( !NT_SUCCESS(status) ) {
return status;
}
} else {
Params = (PRESP_DELETE_DIRECTORY)ForcedParams;
}
return STATUS_SUCCESS;
} // VerifyDeleteDirectory
NTSTATUS
NtNotifyChange(
IN OUT PDESCRIPTOR Redir,
IN PSZ DebugString,
IN PVOID Unused,
IN UCHAR SubCommand,
IN PID_SELECTIONS IdSelections,
IN PID_VALUES IdValues,
OUT PULONG Unused2
)
{
NTSTATUS status;
REQ_NOTIFY_CHANGE setup;
CLONG inSetupCount;
CLONG outSetupCount;
PVOID parameters = NULL;
CLONG inParameterCount;
CLONG outParameterCount;
CHAR data[1];
CLONG inDataCount = 0;
CLONG outDataCount = 0;
ULONG CompletionMask = 0;
BOOLEAN WatchTree = FALSE;
BOOLEAN done = FALSE;
int i;
PCH arg;
Unused, Unused2, SubCommand;
inSetupCount = 4;
outSetupCount = 0;
outDataCount = 0;
inDataCount = 0;
inParameterCount = 0;
outParameterCount = 1000;
parameters = malloc( outParameterCount );
if ( parameters == NULL ) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Default parameters
//
setup.CompletionFilter = 0;
setup.Fid = IdValues->Fid[IdSelections->Fid];
setup.WatchTree = FALSE;
setup.Reserved = 0;
for ( i = 1; i < Redir->argc ; i++ ) {
arg = Redir->argv[i];
if ( *arg == '-') {
if ( *(arg +1) == 'T' ) {
setup.WatchTree = TRUE;
printf ("Setting WatchTree to TRUE\n");
} else if ( *(arg+1) == 'F') {
setup.CompletionFilter = atolx( arg+2 );
printf (
"Setting completion filter to: 0x%lx\n",
setup.CompletionFilter
);
}
}
}
status = SendAndReceiveTransaction(
Redir,
DebugString,
IdSelections,
IdValues,
SMB_COM_NT_TRANSACT,
&setup,
inSetupCount,
&outSetupCount,
"",
NT_TRANSACT_NOTIFY_CHANGE,
parameters,
inParameterCount,
&outParameterCount,
data,
inDataCount,
&outDataCount
);
if ( !NT_SUCCESS(status) ) {
goto exit;
}
if ( outSetupCount != 0 ) {
printf( "NtNotify: bad return setup count: %ld\n", outSetupCount );
status = STATUS_UNSUCCESSFUL;
goto exit;
}
if ( outParameterCount == 0 ) {
printf( "NtNotify: bad return parameter count: %ld\n",
outParameterCount );
status = STATUS_UNSUCCESSFUL;
goto exit;
}
do {
PFILE_NOTIFY_INFORMATION notifyBuffer;
UNICODE_STRING fileName;
notifyBuffer = parameters;
fileName.Buffer = notifyBuffer->FileName;
fileName.Length = (USHORT)notifyBuffer->FileNameLength;
printf (
"File %wZ changed, action = %lx\n",
&fileName,
notifyBuffer->Action
);
if ( notifyBuffer->NextEntryOffset == 0 ) {
done = TRUE;
} else {
notifyBuffer = (PFILE_NOTIFY_INFORMATION)
((PCHAR)notifyBuffer + notifyBuffer->NextEntryOffset);
}
} while ( !done );
status = STATUS_PENDING;
exit:
free( parameters );
return status;
} // NtNotifyChange