mirror of https://github.com/lianthony/NT4.0
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
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
|
|
|