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.
1055 lines
25 KiB
1055 lines
25 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
file.c
|
|
|
|
Abstract:
|
|
|
|
Make and Verify routines for File class SMBs.
|
|
|
|
Author:
|
|
|
|
David Treadwell (davidtr) 20-Nov-1989
|
|
Chuck Lenzmeier (chuckl)
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define INCLUDE_SMB_FILE_CONTROL
|
|
|
|
#include "usrv.h"
|
|
|
|
//
|
|
// NOTE: This macro requires the local variable "status" and the
|
|
// function parameters "Redir", "DebugString", "IdSelections", and
|
|
// "IdValues".
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
#define DO_FLUSH(title,fid,pid,expectedClass,expectedError) { \
|
|
status = DoFlush( \
|
|
(title), \
|
|
Redir, \
|
|
DebugString, \
|
|
IdSelections, \
|
|
IdValues, \
|
|
(fid), \
|
|
(pid), \
|
|
(expectedClass), \
|
|
(expectedError) \
|
|
); \
|
|
if ( !NT_SUCCESS(status) ) { \
|
|
return status; \
|
|
} \
|
|
}
|
|
|
|
#else
|
|
#define DO_FLUSH(title,fid,pid,expectedStatus) { \
|
|
status = DoFlush( \
|
|
(title), \
|
|
Redir, \
|
|
DebugString, \
|
|
IdSelections, \
|
|
IdValues, \
|
|
(fid), \
|
|
(pid), \
|
|
(expectedStatus) \
|
|
); \
|
|
if ( !NT_SUCCESS(status) ) { \
|
|
return status; \
|
|
} \
|
|
}
|
|
|
|
#endif
|
|
|
|
NTSTATUS
|
|
MakeDeleteSmb(
|
|
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 Params;
|
|
NTSTATUS status;
|
|
STRING fileName;
|
|
|
|
LONG argPointer;
|
|
PCHAR s;
|
|
USHORT searchAttributes = 0;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_DELETE)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_DELETE,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_DELETE)(ForcedParams);
|
|
|
|
}
|
|
|
|
for ( argPointer = 2; argPointer < Redir->argc; argPointer++ ) {
|
|
|
|
if ( *Redir->argv[argPointer] != '-' &&
|
|
*Redir->argv[argPointer] != '/' ) {
|
|
goto usage;
|
|
}
|
|
|
|
switch ( *(Redir->argv[argPointer]+1) ) {
|
|
|
|
case 'S':
|
|
case 's':
|
|
|
|
for ( s = (Redir->argv[argPointer]+2); *s != '\0'; s++ ) {
|
|
switch ( *s ) {
|
|
|
|
case 'r':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_READONLY;
|
|
continue;
|
|
|
|
case 'h':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_HIDDEN;
|
|
continue;
|
|
|
|
case 's':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_SYSTEM;
|
|
continue;
|
|
|
|
case 'a':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_ARCHIVE;
|
|
continue;
|
|
|
|
default:
|
|
goto usage;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
goto usage;
|
|
}
|
|
}
|
|
|
|
IF_DEBUG(4) printf( "Search Attributes = 0x%lx\n", searchAttributes );
|
|
|
|
if ( IdSelections->Fid != 0xF ) {
|
|
|
|
fileName.Length = FileDefs[IdSelections->Fid].Name.Length;
|
|
fileName.Buffer = FileDefs[IdSelections->Fid].Name.Buffer + 1;
|
|
|
|
} else {
|
|
|
|
PCHAR namePtr = Redir->argv[1];
|
|
|
|
if ( Redir->argc < 2 ) {
|
|
printf( "Insufficient number of arguments.\n" );
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( *(namePtr+1) == ':' ) {
|
|
namePtr += 2;
|
|
}
|
|
|
|
fileName.Length = (SHORT)(strlen( namePtr ) + 2);
|
|
fileName.Buffer = namePtr;
|
|
}
|
|
|
|
Params->WordCount = 1;
|
|
SmbPutUshort( &Params->SearchAttributes, searchAttributes );
|
|
SmbPutUshort( &Params->ByteCount, fileName.Length );
|
|
|
|
Params->Buffer[0] = '\004';
|
|
|
|
RtlMoveMemory( Params->Buffer + 1, fileName.Buffer, fileName.Length );
|
|
|
|
Params->Buffer[fileName.Length] = '\0';
|
|
|
|
*SmbSize = GET_ANDX_OFFSET(
|
|
Header,
|
|
Params,
|
|
REQ_DELETE,
|
|
SmbGetUshort( &Params->ByteCount )
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
usage:
|
|
printf( "Usage: delete X:\\filename -shras\n" );
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
} // MakeDeleteSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyDelete(
|
|
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 Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand, SmbSize; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_DELETE)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_DELETE
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_DELETE)ForcedParams;
|
|
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyDelete
|
|
|
|
|
|
NTSTATUS
|
|
MakeMoveSmb(
|
|
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_MOVE Params;
|
|
NTSTATUS status;
|
|
|
|
LONG argPointer;
|
|
PCHAR s;
|
|
|
|
USHORT flags = 0;
|
|
USHORT openFunction = SMB_OFUN_CREATE_CREATE | SMB_OFUN_OPEN_TRUNCATE;
|
|
USHORT searchAttributes = 0;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_MOVE)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
(USHORT)( strcmp( "MV", Redir->argv[0] ) == 0 ?
|
|
SMB_COM_MOVE : SMB_COM_COPY ),
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_MOVE)(ForcedParams);
|
|
|
|
}
|
|
|
|
//
|
|
// Use command-line options.
|
|
//
|
|
|
|
for ( argPointer = 3; argPointer < Redir->argc; argPointer++ ) {
|
|
|
|
if ( *Redir->argv[argPointer] != '-' &&
|
|
*Redir->argv[argPointer] != '/' ) {
|
|
printf( "Illegal argument: %s\n", Redir->argv[argPointer] );
|
|
}
|
|
|
|
switch ( *(Redir->argv[argPointer]+1) ) {
|
|
|
|
case 'T': // Tree copy
|
|
case 't':
|
|
flags |= SMB_COPY_TREE | SMB_TARGET_IS_DIRECTORY;
|
|
break;
|
|
|
|
case 'S': // source file options
|
|
case 's':
|
|
if ( *(Redir->argv[argPointer]+2) == 'a' || // ASCII
|
|
*(Redir->argv[argPointer]+2) == 'A' ) {
|
|
flags |= SMB_COPY_SOURCE_ASCII;
|
|
} else if ( *(Redir->argv[argPointer]+2) == 'b' ||
|
|
*(Redir->argv[argPointer]+2) == 'B' ) { // Binary
|
|
flags &= ~SMB_COPY_SOURCE_ASCII;
|
|
} else {
|
|
goto usage;
|
|
}
|
|
break;
|
|
|
|
case 'D': // destination file options
|
|
case 'd':
|
|
|
|
for ( s = (Redir->argv[argPointer]+2); *s != '\0'; s++ ) {
|
|
|
|
switch ( *s ) {
|
|
|
|
case 'A': // ASCII
|
|
case 'a':
|
|
flags |= SMB_COPY_TARGET_ASCII;
|
|
break;
|
|
|
|
case 'B': // Binary
|
|
case 'b':
|
|
flags &= ~SMB_COPY_TARGET_ASCII;
|
|
break;
|
|
|
|
case 'C': // Only create destination; no overwrite
|
|
case 'c':
|
|
openFunction &= ~SMB_OFUN_OPEN_MASK;
|
|
break;
|
|
|
|
case 'D': // Destination is a directory
|
|
case 'd':
|
|
flags |= SMB_TARGET_IS_DIRECTORY;
|
|
break;
|
|
|
|
case 'F': // Destination is a file
|
|
case 'f':
|
|
flags |= SMB_TARGET_IS_FILE;
|
|
break;
|
|
|
|
case 'O': // Only open destination; no create
|
|
case 'o':
|
|
openFunction &= ~SMB_OFUN_CREATE_MASK;
|
|
break;
|
|
|
|
case 'P': // Append to destination
|
|
case 'p':
|
|
openFunction &= ~SMB_OFUN_OPEN_MASK;
|
|
openFunction |= SMB_OFUN_OPEN_APPEND;
|
|
break;
|
|
|
|
case 'T': // Truncate destination
|
|
case 't':
|
|
openFunction &= ~SMB_OFUN_OPEN_MASK;
|
|
openFunction |= SMB_OFUN_OPEN_TRUNCATE;
|
|
break;
|
|
|
|
default:
|
|
goto usage;
|
|
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Skip over the \004 in the filedefs.
|
|
//
|
|
|
|
Params->WordCount = 3;
|
|
|
|
if ( IdSelections->Fid != 0xF ) {
|
|
|
|
SmbPutUshort(
|
|
&Params->OpenFunction,
|
|
FileDefs[IdSelections->Fid].OpenFunction
|
|
);
|
|
SmbPutUshort( &Params->Flags, 0 );
|
|
SmbPutUshort( &Params->Tid2, IdValues->Tid[IdSelections->Tid+1] );
|
|
|
|
SmbPutUshort(
|
|
&Params->ByteCount,
|
|
(USHORT)(FileDefs[IdSelections->Fid].Name.Length +
|
|
FileDefs[IdSelections->Fid+1].Name.Length - 2)
|
|
);
|
|
|
|
RtlMoveMemory(
|
|
Params->Buffer,
|
|
FileDefs[IdSelections->Fid].Name.Buffer + 1,
|
|
FileDefs[IdSelections->Fid].Name.Length - 1
|
|
);
|
|
|
|
RtlMoveMemory(
|
|
Params->Buffer + FileDefs[IdSelections->Fid].Name.Length - 1,
|
|
FileDefs[IdSelections->Fid+1].Name.Buffer + 1,
|
|
FileDefs[IdSelections->Fid+1].Name.Length - 1
|
|
);
|
|
|
|
} else {
|
|
|
|
PSZ oldName;
|
|
PSZ newName;
|
|
|
|
SmbPutUshort( &Params->OpenFunction, openFunction );
|
|
SmbPutUshort( &Params->Flags, flags );
|
|
|
|
SmbPutUshort(
|
|
&Params->Tid2,
|
|
IdValues->Tid[GetTreeConnectIndex( Redir->argv[2] )] );
|
|
|
|
oldName = Redir->argv[1];
|
|
if ( *(oldName+1) == ':' ) {
|
|
oldName += 2;
|
|
}
|
|
|
|
newName = Redir->argv[2];
|
|
if ( *(newName+1) == ':' ) {
|
|
newName += 2;
|
|
}
|
|
|
|
SmbPutUshort(
|
|
&Params->ByteCount,
|
|
(USHORT)(strlen( oldName ) + strlen( newName ) + 2)
|
|
);
|
|
|
|
RtlMoveMemory(
|
|
Params->Buffer,
|
|
oldName,
|
|
strlen( oldName ) + 1
|
|
);
|
|
|
|
RtlMoveMemory(
|
|
Params->Buffer + strlen( oldName ) + 1,
|
|
newName,
|
|
strlen( newName ) + 1
|
|
);
|
|
}
|
|
|
|
*SmbSize = GET_ANDX_OFFSET(
|
|
Header,
|
|
Params,
|
|
REQ_MOVE,
|
|
SmbGetUshort( &Params->ByteCount )
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
usage:
|
|
|
|
printf( "Usage: mv|cp sourcefile destfile [-t] [-s[ab]] [-d[abcdfopt]]\n" );
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
} // MakeMoveSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyMove(
|
|
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_MOVE Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand, SmbSize; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_MOVE)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
(USHORT)( strcmp( "MV", Redir->argv[0] ) == 0 ?
|
|
SMB_COM_MOVE : SMB_COM_COPY )
|
|
);
|
|
|
|
#ifdef DOSERROR
|
|
if( (Header->ErrorClass != 0 || SmbGetUshort( &Header->Error ) != 0) &&
|
|
#else
|
|
if( SmbGetUlong( (PULONG)&Header->ErrorClass ) != 0 &&
|
|
#endif
|
|
SmbGetUshort( &Params->ByteCount ) > 0 ) {
|
|
if ( SmbGetUshort( &Params->ByteCount ) != 0 ) {
|
|
printf( "Error processing file %s\n", Params->Buffer );
|
|
}
|
|
}
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_MOVE)ForcedParams;
|
|
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyMove
|
|
|
|
|
|
NTSTATUS
|
|
MakeRenameSmb(
|
|
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_RENAME Params;
|
|
NTSTATUS status;
|
|
PSZ namePtr;
|
|
PCHAR bufferPtr;
|
|
|
|
LONG argPointer;
|
|
PCHAR s;
|
|
USHORT searchAttributes = 0;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_RENAME)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_RENAME,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_RENAME)(ForcedParams);
|
|
|
|
}
|
|
|
|
for ( argPointer = 3; argPointer < Redir->argc; argPointer++ ) {
|
|
|
|
if ( *Redir->argv[argPointer] != '-' &&
|
|
*Redir->argv[argPointer] != '/' ) {
|
|
goto usage;
|
|
}
|
|
|
|
switch ( *(Redir->argv[argPointer]+1) ) {
|
|
|
|
case 'S':
|
|
case 's':
|
|
|
|
for ( s = (Redir->argv[argPointer]+2); *s != '\0'; s++ ) {
|
|
switch ( *s ) {
|
|
|
|
case 'r':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_READONLY;
|
|
continue;
|
|
|
|
case 'h':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_HIDDEN;
|
|
continue;
|
|
|
|
case 's':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_SYSTEM;
|
|
continue;
|
|
|
|
case 'a':
|
|
searchAttributes |= SMB_FILE_ATTRIBUTE_ARCHIVE;
|
|
continue;
|
|
|
|
default:
|
|
goto usage;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
goto usage;
|
|
}
|
|
}
|
|
|
|
IF_DEBUG(4) printf( "Search Attributes = 0x%lx\n", searchAttributes );
|
|
|
|
SmbPutUshort( &Params->SearchAttributes, searchAttributes );
|
|
Params->WordCount = 1;
|
|
|
|
if ( Redir->argc < 3 ) {
|
|
printf( "Usage: rename file1 file2\n" );
|
|
}
|
|
|
|
namePtr = Redir->argv[1];
|
|
if ( *(namePtr+1) == ':' ) {
|
|
namePtr += 2;
|
|
}
|
|
|
|
bufferPtr = Params->Buffer;
|
|
*bufferPtr++ = '\004';
|
|
|
|
RtlMoveMemory( bufferPtr, namePtr, strlen( namePtr ) + 1 );
|
|
|
|
bufferPtr += strlen( namePtr ) + 1;
|
|
*bufferPtr++ = '\004';
|
|
|
|
namePtr = Redir->argv[2];
|
|
if ( *(namePtr+1) == ':' ) {
|
|
namePtr += 2;
|
|
}
|
|
|
|
RtlMoveMemory( bufferPtr, namePtr, strlen( namePtr ) + 1 );
|
|
|
|
bufferPtr += strlen( namePtr ) + 1;
|
|
|
|
SmbPutUshort( &Params->ByteCount, (USHORT)(bufferPtr - Params->Buffer) );
|
|
|
|
*SmbSize = GET_ANDX_OFFSET(
|
|
Header,
|
|
Params,
|
|
REQ_RENAME,
|
|
SmbGetUshort( &Params->ByteCount )
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
usage:
|
|
printf( "Usage: rename X:\\filename X:\\newname -shras\n" );
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
} // MakeRenameSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyRename(
|
|
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_RENAME Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand, SmbSize; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_RENAME)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_RENAME
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_RENAME)ForcedParams;
|
|
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyRename
|
|
|
|
|
|
STATIC
|
|
NTSTATUS
|
|
DoFlush(
|
|
IN PSZ Title,
|
|
IN PDESCRIPTOR Redir,
|
|
IN PSZ DebugString,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
IN USHORT Fid,
|
|
IN USHORT Pid,
|
|
#ifdef DOSERROR
|
|
IN UCHAR ExpectedClass,
|
|
IN USHORT ExpectedError
|
|
#else
|
|
IN NTSTATUS ExpectedStatus
|
|
#endif
|
|
)
|
|
|
|
{
|
|
NTSTATUS status;
|
|
CLONG smbSize;
|
|
|
|
PSMB_HEADER header;
|
|
PREQ_FLUSH request;
|
|
|
|
#ifdef DOSERROR
|
|
UCHAR class;
|
|
USHORT error;
|
|
#else
|
|
NTSTATUS smbStatus;
|
|
#endif
|
|
|
|
IF_DEBUG(3) printf( "'%s' start\n", Title );
|
|
|
|
header = (PSMB_HEADER)Redir->Data[0];
|
|
request = (PREQ_FLUSH)(header + 1);
|
|
|
|
(VOID)MakeSmbHeader(
|
|
Redir,
|
|
header,
|
|
SMB_COM_FLUSH,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
request->WordCount = 1;
|
|
SmbPutUshort( &header->Pid, Pid );
|
|
SmbPutUshort( &request->Fid, Fid );
|
|
SmbPutUshort( &request->ByteCount, 0 );
|
|
|
|
smbSize = GET_ANDX_OFFSET( header, request, REQ_FLUSH, 0 );
|
|
|
|
status = SendAndReceiveSmb(
|
|
Redir,
|
|
DebugString,
|
|
smbSize,
|
|
0,
|
|
1
|
|
);
|
|
CHECK_STATUS( Title );
|
|
|
|
header = (PSMB_HEADER)Redir->Data[1];
|
|
|
|
#ifdef DOSERROR
|
|
class = header->ErrorClass;
|
|
error = SmbGetUshort( &header->Error );
|
|
CHECK_ERROR( Title, ExpectedClass, ExpectedError );
|
|
|
|
IF_DEBUG(3) {
|
|
printf( "'%s' complete. Class %ld, Error %ld\n",
|
|
Title, class, error );
|
|
}
|
|
|
|
#else
|
|
smbStatus = SmbGetUshort( (PULONG)&header->ErrorClass );
|
|
CHECK_ERROR( Title, smbStatus, ExpectedStatus );
|
|
|
|
IF_DEBUG(3) {
|
|
printf( "'%s' complete. Status %lx\n", Title, smbStatus );
|
|
}
|
|
|
|
#endif
|
|
return STATUS_SUCCESS;
|
|
|
|
} // DoFlush
|
|
|
|
|
|
NTSTATUS
|
|
FlushController(
|
|
IN PDESCRIPTOR Redir,
|
|
IN PSZ DebugString,
|
|
IN PVOID Unused,
|
|
IN UCHAR SubCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
OUT PULONG Unused2
|
|
)
|
|
|
|
{
|
|
NTSTATUS status;
|
|
|
|
USHORT fid1, fid2, fid3, fid4;
|
|
STRING file1, file2, file3, file4;
|
|
|
|
#if 0
|
|
FSCTL_SRV_SET_DEBUG_IN_OUT newValues;
|
|
FSCTL_SRV_SET_DEBUG_IN_OUT oldValues;
|
|
#endif
|
|
|
|
Unused, SubCommand, Unused2;
|
|
|
|
RtlInitString( &file1, "\\flush1xx.tst" );
|
|
RtlInitString( &file2, "\\flush2xx.tst" );
|
|
RtlInitString( &file3, "\\flush3xx.tst" );
|
|
RtlInitString( &file4, "\\flush4xx.tst" );
|
|
|
|
//
|
|
// Open all three remote files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open file 1, PID = 1",
|
|
0,
|
|
1, // PID
|
|
&file1,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open file 1, PID = 1",
|
|
0,
|
|
1, // PID
|
|
&file1,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open file 2, PID = 1",
|
|
0,
|
|
1, // PID
|
|
&file2,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open file 2, PID = 1",
|
|
0,
|
|
1, // PID
|
|
&file2,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open file 3, PID = 2",
|
|
0,
|
|
2, // PID
|
|
&file3,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid3,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open file 3, PID = 2",
|
|
0,
|
|
2, // PID
|
|
&file3,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid3,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
#if 0
|
|
newValues.SrvDebugOff = 0;
|
|
newValues.SrvDebugOn = 0;
|
|
newValues.SmbDebugOff = 0;
|
|
newValues.SmbDebugOn = 0x200; // SMB_DEBUG_FILE_CONTROL2
|
|
newValues.HeuristicsChangeMask = 0;
|
|
NetLocalSetServerDebug( 0, NULL, &newValues, &oldValues );
|
|
#endif
|
|
|
|
printf( "*** This should flush FID %lx...\n", fid1 );
|
|
#ifdef DOSERROR
|
|
DO_FLUSH( "Flush file 1", fid1, 1, 0, 0 );
|
|
#else
|
|
DO_FLUSH( "Flush file 1", fid1, 1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
printf( "*** This should flush FID %lx...\n", fid2 );
|
|
#ifdef DOSERROR
|
|
DO_FLUSH( "Flush file 2", fid2, 1, 0, 0 );
|
|
#else
|
|
DO_FLUSH( "Flush file 2", fid2, 1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
printf( "*** This should flush FID %lx...\n", fid3 );
|
|
#ifdef DOSERROR
|
|
DO_FLUSH( "Flush file 3", fid3, 2, 0, 0 );
|
|
#else
|
|
DO_FLUSH( "Flush file 3", fid3, 2, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
printf( "*** This should flush FIDs %lx and %lx...\n", fid1, fid2 );
|
|
#ifdef DOSERROR
|
|
DO_FLUSH( "Flush FID=-1", -1, 1, 0, 0 );
|
|
#else
|
|
DO_FLUSH( "Flush FID=-1", -1, 1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open file 4, PID = 1",
|
|
0,
|
|
1, // PID
|
|
&file4,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid4,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open file 4, PID = 1",
|
|
0,
|
|
1, // PID
|
|
&file4,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid4,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
printf( "*** This should flush FIDs %lx, %lx and %lx...\n", fid1, fid2, fid4 );
|
|
#ifdef DOSERROR
|
|
DO_FLUSH( "Flush FID=-1", -1, 1, 0, 0 );
|
|
#else
|
|
DO_FLUSH( "Flush FID=-1", -1, 1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
printf( "*** This should flush just FID %lx...\n", fid3 );
|
|
#ifdef DOSERROR
|
|
DO_FLUSH( "Flush FID=-1", -1, 2, 0, 0 );
|
|
#else
|
|
DO_FLUSH( "Flush FID=-1", -1, 2, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Close file 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Close file 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Close file 2", 0, fid2, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Close file 2", 0, fid2, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Close file 3", 0, fid3, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Close file 3", 0, fid3, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Close file 4", 0, fid4, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Close file 4", 0, fid4, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_DELETE( "Delete file 1", 0, &file1, 0, 0 );
|
|
#else
|
|
DO_DELETE( "Delete file 1", 0, &file1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_DELETE( "Delete file 2", 0, &file2, 0, 0 );
|
|
#else
|
|
DO_DELETE( "Delete file 2", 0, &file2, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_DELETE( "Delete file 3", 0, &file3, 0, 0 );
|
|
#else
|
|
DO_DELETE( "Delete file 3", 0, &file3, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_DELETE( "Delete file 4", 0, &file4, 0, 0 );
|
|
#else
|
|
DO_DELETE( "Delete file 4", 0, &file4, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#if 0
|
|
NetLocalSetServerDebug( 0, NULL, &oldValues, NULL );
|
|
#endif
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // FlushController
|
|
|