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.
1537 lines
35 KiB
1537 lines
35 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cmpt-fcb.c
|
|
|
|
Abstract:
|
|
|
|
Control routines (etc.) for the compatibility mode _open test.
|
|
|
|
Author:
|
|
|
|
Chuck Lenzmeier (chuckl) 14-Apr-1990
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define INCLUDE_SMB_FILE_CONTROL
|
|
#define INCLUDE_SMB_OPEN_CLOSE
|
|
|
|
#include "usrv.h"
|
|
|
|
/*
|
|
file already open:
|
|
error if FILE_CREATE
|
|
not compatibility mode:
|
|
DoNormalOpen if mapped
|
|
error if not mapped
|
|
compatibility mode:
|
|
error if different session
|
|
error if writing to readonly file
|
|
OK otherwise
|
|
file not open:
|
|
DoNormalOpen if mapped
|
|
Open for read/write/delete
|
|
Open for read/write
|
|
Open for write *or* read
|
|
OK otherwise
|
|
*/
|
|
|
|
#define DO_LOCAL_OPEN(title,file,_access,share,disp,handle) { \
|
|
status = DoLocalOpen( \
|
|
(title), \
|
|
Redir, \
|
|
(file), \
|
|
(_access), \
|
|
(share), \
|
|
(disp), \
|
|
(handle) \
|
|
); \
|
|
if ( !NT_SUCCESS(status) ) { \
|
|
return status; \
|
|
} \
|
|
}
|
|
|
|
#define DO_LOCAL_SET_INFO(title,handle,attr) { \
|
|
status = DoLocalSetInfo( \
|
|
(title), \
|
|
Redir, \
|
|
(handle), \
|
|
(attr) \
|
|
); \
|
|
if ( !NT_SUCCESS(status) ) { \
|
|
return status; \
|
|
} \
|
|
}
|
|
|
|
#define DO_LOCAL_CLOSE(title,handle) { \
|
|
status = DoLocalClose( \
|
|
(title), \
|
|
Redir, \
|
|
(handle) \
|
|
); \
|
|
if ( !NT_SUCCESS(status) ) { \
|
|
return status; \
|
|
} \
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DoLocalOpen(
|
|
IN PSZ Title,
|
|
IN PDESCRIPTOR Redir,
|
|
IN PSTRING File,
|
|
IN ACCESS_MASK DesiredAccess,
|
|
IN ULONG ShareAccess,
|
|
IN ULONG Disposition,
|
|
OUT PHANDLE Handle
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
IO_STATUS_BLOCK iosb;
|
|
UNICODE_STRING unicodeFile;
|
|
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
|
|
IF_DEBUG(3) printf( "'%s' start\n", Title );
|
|
|
|
status = RtlAnsiStringToUnicodeString( &unicodeFile, File, TRUE );
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes,
|
|
&unicodeFile,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
status = NtCreateFile(
|
|
Handle,
|
|
DesiredAccess,
|
|
&objectAttributes,
|
|
&iosb,
|
|
NULL,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
ShareAccess,
|
|
Disposition,
|
|
0,
|
|
NULL,
|
|
0
|
|
);
|
|
RtlFreeUnicodeString( &unicodeFile );
|
|
CHECK_IO_STATUS( Title );
|
|
|
|
IF_DEBUG(3) {
|
|
printf( "'%s' complete. Handle 0x%lx\n", Title, *Handle );
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // DoLocalOpen
|
|
|
|
|
|
NTSTATUS
|
|
DoLocalSetInfo(
|
|
IN PSZ Title,
|
|
IN PDESCRIPTOR Redir,
|
|
IN HANDLE Handle,
|
|
IN ULONG Attributes
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
IO_STATUS_BLOCK iosb;
|
|
|
|
FILE_BASIC_INFORMATION info;
|
|
|
|
IF_DEBUG(3) printf( "'%s' start\n", Title );
|
|
|
|
RtlZeroMemory( &info, sizeof(info) );
|
|
info.FileAttributes = Attributes;
|
|
|
|
status = NtSetInformationFile(
|
|
Handle,
|
|
&iosb,
|
|
&info,
|
|
sizeof(info),
|
|
FileBasicInformation
|
|
);
|
|
CHECK_IO_STATUS( Title );
|
|
|
|
IF_DEBUG(3) {
|
|
printf( "'%s' complete.\n", Title );
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // DoLocalSetInfo
|
|
|
|
|
|
NTSTATUS
|
|
DoLocalClose(
|
|
IN PSZ Title,
|
|
IN PDESCRIPTOR Redir,
|
|
IN HANDLE Handle
|
|
)
|
|
{
|
|
Redir; // prevent compiler warnings
|
|
|
|
IF_DEBUG(3) printf( "'%s' start\n", Title );
|
|
|
|
NtClose( Handle );
|
|
|
|
IF_DEBUG(3) {
|
|
printf( "'%s' complete.\n", Title );
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // DoLocalClose
|
|
|
|
|
|
NTSTATUS
|
|
CompatibilityController(
|
|
IN PDESCRIPTOR Redir,
|
|
IN PSZ DebugString,
|
|
IN PVOID Unused,
|
|
IN UCHAR SubCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
OUT PULONG Unused2
|
|
)
|
|
|
|
/*
|
|
file already open:
|
|
error if FILE_CREATE
|
|
not compatibility mode:
|
|
DoNormalOpen if mapped
|
|
error if not mapped
|
|
compatibility mode:
|
|
error if different session
|
|
error if writing to readonly file
|
|
OK otherwise
|
|
file not open:
|
|
DoNormalOpen if mapped
|
|
Open for read/write/delete
|
|
Open for read/write
|
|
Open for write *or* read
|
|
OK otherwise
|
|
*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
|
|
STRING file, fullFile;
|
|
USHORT fid1, fid2, fid3;
|
|
HANDLE handle1;
|
|
|
|
#if 0
|
|
FSCTL_SRV_SET_DEBUG_IN_OUT newValues;
|
|
FSCTL_SRV_SET_DEBUG_IN_OUT oldValues;
|
|
#endif
|
|
|
|
Unused, SubCommand, Unused2; // prevent compiler warnings
|
|
|
|
file.Buffer = "tmp\\cmpt-fcb.tmp";
|
|
file.Length = 16;
|
|
|
|
fullFile.Buffer = "\\BootDevice\\tmp\\cmpt-fcb.tmp";
|
|
fullFile.Length = 28;
|
|
|
|
//
|
|
// *** The first few phases of this test must be done with soft
|
|
// compatibility mapping enabled.
|
|
//
|
|
|
|
#if 0
|
|
newValues.SrvDebugOff = 0;
|
|
newValues.SrvDebugOn = 0;
|
|
newValues.SmbDebugOff = 0;
|
|
newValues.SmbDebugOn = 0;
|
|
newValues.HeuristicsChangeMask = SRV_HEUR_SOFT_COMPATIBILITY;
|
|
newValues.EnableSoftCompatibility = TRUE;
|
|
NetLocalSetServerDebug( 0, NULL, &newValues, &oldValues );
|
|
#else
|
|
DbgPrint( "Please enable soft compatibility mode\n" );
|
|
DbgBreakPoint( );
|
|
#endif
|
|
|
|
//
|
|
// Create a temporary file locally. Make sure the file is writable.
|
|
// Close the handle.
|
|
//
|
|
|
|
DO_LOCAL_OPEN(
|
|
"Create temporary file locally",
|
|
&fullFile,
|
|
FILE_WRITE_ATTRIBUTES,
|
|
0,
|
|
FILE_OPEN_IF,
|
|
&handle1
|
|
);
|
|
|
|
DO_LOCAL_SET_INFO(
|
|
"Make file writable",
|
|
handle1,
|
|
FILE_ATTRIBUTE_NORMAL
|
|
);
|
|
|
|
DO_LOCAL_CLOSE(
|
|
"Phase 0 close local handle",
|
|
handle1
|
|
);
|
|
|
|
//
|
|
// Now, reopen the file through the server for normal sharing.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open temporary file, normal sharing",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open temporary file, normal sharing",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to create the same file for read/write in compatibility
|
|
// mode. This should fail, because the file already exists.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Hard compatibility create after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_FAIL | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
SMB_ERR_CLASS_DOS,
|
|
SMB_ERR_FILE_EXISTS
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Hard compatibility create after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_FAIL | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_OBJECT_NAME_COLLISION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file for read/write in compatibility
|
|
// mode, from the same session. This should fail, because the
|
|
// file is already open in normal mode.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Hard compatibility open after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
(UCHAR)( Redir->Dialect == SmbDialectDosLanMan20 ||
|
|
Redir->Dialect >= SmbDialectMsNet30 ? SMB_ERR_CLASS_HARDWARE :
|
|
SMB_ERR_CLASS_DOS ),
|
|
SMB_ERR_BAD_SHARE
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Hard compatibility open after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SHARING_VIOLATION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file for read ONLY in compatibility
|
|
// mode, from the same session. This should work, due to soft
|
|
// compatibility mapping.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Soft compatibility open after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Soft compatibility open after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// End of phase 1. Close files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 1 close FID 2", 0, fid2, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 1 close FID 2", 0, fid2, STATUS_SUCCESS );
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 1 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 1 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// Reopen in compatibility mode.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Hard compatibility reopen",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Hard compatibility reopen",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file for read ONLY in compatibility
|
|
// mode, from a differrent session. This should fail.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Conflicting soft compatibility open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
(UCHAR)( Redir->Dialect == SmbDialectDosLanMan20 ||
|
|
Redir->Dialect >= SmbDialectMsNet30 ? SMB_ERR_CLASS_HARDWARE :
|
|
SMB_ERR_CLASS_DOS ),
|
|
SMB_ERR_BAD_SHARE
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Conflicting soft compatibility open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SHARING_VIOLATION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file for read ONLY in compatibility
|
|
// mode, from the same session. This should work.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Duplicate soft compatibility open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Duplicate soft compatibility open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file for read/write in compatibility
|
|
// mode, from the same session. This should work.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Duplicate hard compatibility open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid3,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Duplicate hard compatibility open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid3,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// End of phase 2. Close files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 2 close FID 3", 0, fid3, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 2 close FID 3", 0, fid3, STATUS_SUCCESS );
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 2 close FID 2", 0, fid2, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 2 close FID 2", 0, fid2, STATUS_SUCCESS );
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 2 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 2 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// Test soft compatibility mapping by reopening it in compatibility
|
|
// mode for read ONLY from two different sessions. These should
|
|
// both be mapped to SHARE=READ.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Shared soft compatibility 1",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Shared soft compatibility 1",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Shared soft compatibility 2",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Shared soft compatibility 2",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// End of phase 3. Close files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 3 close FID 2", 1, fid2, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 3 close FID 2", 1, fid2, STATUS_SUCCESS );
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 3 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 3 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// Open the file locally. Then try to do a compatibility mode open
|
|
// of the file. This should fail, because the server will try to
|
|
// get exclusive access to the file.
|
|
//
|
|
|
|
DO_LOCAL_OPEN(
|
|
"Local open",
|
|
&fullFile,
|
|
GENERIC_WRITE,
|
|
0L,
|
|
FILE_OPEN,
|
|
&handle1
|
|
);
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Compatibility open conflicting with local open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
(UCHAR)( Redir->Dialect == SmbDialectDosLanMan20 ||
|
|
Redir->Dialect >= SmbDialectMsNet30 ? SMB_ERR_CLASS_HARDWARE :
|
|
SMB_ERR_CLASS_DOS ),
|
|
SMB_ERR_BAD_SHARE
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Compatibility open conflicting with local open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SHARING_VIOLATION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now make the file readonly, using the local handle. Then close
|
|
// the local handle.
|
|
//
|
|
|
|
DO_LOCAL_SET_INFO(
|
|
"Make file readonly",
|
|
handle1,
|
|
FILE_ATTRIBUTE_READONLY
|
|
);
|
|
|
|
DO_LOCAL_CLOSE(
|
|
"Close local handle",
|
|
handle1
|
|
);
|
|
|
|
//
|
|
// *** The next phase of this test must be done with soft
|
|
// compatibility mapping disabled.
|
|
//
|
|
|
|
#if 0
|
|
newValues.SrvDebugOff = 0;
|
|
newValues.SrvDebugOn = 0;
|
|
newValues.SmbDebugOff = 0;
|
|
newValues.SmbDebugOn = 0;
|
|
newValues.HeuristicsChangeMask = SRV_HEUR_SOFT_COMPATIBILITY;
|
|
newValues.EnableSoftCompatibility = FALSE;
|
|
NetLocalSetServerDebug( 0, NULL, &newValues, NULL );
|
|
#else
|
|
DbgPrint( "Please disable soft compatibility mode\n" );
|
|
DbgBreakPoint( );
|
|
#endif
|
|
|
|
//
|
|
// Try to open the file for read/write in compatibility mode. This
|
|
// should fail, because the file is readonly.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Read/write open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
SMB_ERR_CLASS_DOS,
|
|
SMB_ERR_ACCESS_DENIED
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Read/write open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_ACCESS_DENIED
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Try to open the file for read ONLY in compatibility mode. This
|
|
// should work.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Readonly open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Readonly open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Make sure that the file was opened in compatibility mode by
|
|
// trying to open the same file for read ONLY in compatibility mode,
|
|
// from a differrent session. This should fail.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Conflicting compatibility open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
(UCHAR)( Redir->Dialect == SmbDialectDosLanMan20 ||
|
|
Redir->Dialect >= SmbDialectMsNet30 ? SMB_ERR_CLASS_HARDWARE :
|
|
SMB_ERR_CLASS_DOS ),
|
|
SMB_ERR_BAD_SHARE
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Conflicting compatibility open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SHARING_VIOLATION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Try again to open the file for read/write in compatibility mode.
|
|
// This should still fail, in spite of the existing (readonly) open.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Read/write open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid2,
|
|
SMB_ERR_CLASS_DOS,
|
|
SMB_ERR_ACCESS_DENIED
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Read/write open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid2,
|
|
STATUS_ACCESS_DENIED
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 4 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 4 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// End of phase 4. Delete files.
|
|
//
|
|
|
|
DO_LOCAL_OPEN(
|
|
"Local open to make file writable",
|
|
&fullFile,
|
|
FILE_WRITE_ATTRIBUTES,
|
|
0L,
|
|
FILE_OPEN,
|
|
&handle1
|
|
);
|
|
|
|
DO_LOCAL_SET_INFO(
|
|
"Make file writable for delete",
|
|
handle1,
|
|
FILE_ATTRIBUTE_NORMAL
|
|
);
|
|
|
|
DO_LOCAL_CLOSE(
|
|
"Close for delete",
|
|
handle1
|
|
);
|
|
|
|
//
|
|
// *** Turn soft compatibility mapping back on for the final phase.
|
|
//
|
|
|
|
#if 0
|
|
newValues.SrvDebugOff = 0;
|
|
newValues.SrvDebugOn = 0;
|
|
newValues.SmbDebugOff = 0;
|
|
newValues.SmbDebugOn = 0;
|
|
newValues.HeuristicsChangeMask = SRV_HEUR_SOFT_COMPATIBILITY;
|
|
newValues.EnableSoftCompatibility = TRUE;
|
|
NetLocalSetServerDebug( 0, NULL, &newValues, NULL );
|
|
#else
|
|
DbgPrint( "Please enable soft compatibility mode\n" );
|
|
DbgBreakPoint( );
|
|
#endif
|
|
|
|
//
|
|
// Open the file a few times--these will be closed by the DELETE.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open before delete 1",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open before delete 1",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open before delete 2",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open before delete 2",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open before delete 3",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid3,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open before delete 3",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid3,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_DELETE( "Delete after compatibility opens", 0, &file, 0, 0 );
|
|
#else
|
|
DO_DELETE( "Delete after compatibility opens", 0, &file, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Delete close FID 1", 0, fid1, SMB_ERR_CLASS_DOS, SMB_ERR_BAD_FID );
|
|
#else
|
|
DO_CLOSE( "Delete close FID 1", 0, fid1, STATUS_INVALID_HANDLE );
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Delete close FID 2", 0, fid2, SMB_ERR_CLASS_DOS, SMB_ERR_BAD_FID );
|
|
#else
|
|
DO_CLOSE( "Delete close FID 2", 0, fid2, STATUS_INVALID_HANDLE);
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Delete close FID 3", 0, fid3, SMB_ERR_CLASS_DOS, SMB_ERR_BAD_FID );
|
|
#else
|
|
DO_CLOSE( "Delete close FID 3", 0, fid3, STATUS_INVALID_HANDLE );
|
|
#endif
|
|
|
|
//
|
|
// *** Restore the original soft compatibility mapping setting.
|
|
//
|
|
|
|
#if 0
|
|
NetLocalSetServerDebug( 0, NULL, &oldValues, NULL );
|
|
#else
|
|
DbgPrint( "Please restore soft compatibility mode to its original setting\n" );
|
|
DbgBreakPoint( );
|
|
#endif
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // CompatibilityController
|
|
|
|
|
|
NTSTATUS
|
|
FcbController(
|
|
IN PDESCRIPTOR Redir,
|
|
IN PSZ DebugString,
|
|
IN PVOID Unused,
|
|
IN UCHAR SubCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
OUT PULONG Unused2
|
|
)
|
|
|
|
/*
|
|
file already open:
|
|
error if FILE_CREATE
|
|
fold if session already has FCB open for file
|
|
compatibility open:
|
|
error if different session
|
|
OK if same session
|
|
file not open:
|
|
file open, not compatibility:
|
|
Open for read/write/delete
|
|
check sharing violation on above
|
|
access denied:
|
|
Open for read/write
|
|
access denied:
|
|
Open for read
|
|
check sharing violation on above
|
|
*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
|
|
STRING file, fullFile;
|
|
USHORT fid1, fid2;
|
|
HANDLE handle1;
|
|
|
|
Unused, SubCommand, Unused2; // prevent compiler warnings
|
|
|
|
file.Buffer = "tmp\\cmpt-fcb.tmp";
|
|
file.Length = 16;
|
|
|
|
fullFile.Buffer = "\\BootDevice\\tmp\\cmpt-fcb.tmp";
|
|
fullFile.Length = 28;
|
|
|
|
//
|
|
// Create a temporary file locally. Make sure the file is writable.
|
|
// Close the handle.
|
|
//
|
|
|
|
DO_LOCAL_OPEN(
|
|
"Create temporary file locally",
|
|
&fullFile,
|
|
FILE_WRITE_ATTRIBUTES,
|
|
0,
|
|
FILE_OPEN_IF,
|
|
&handle1
|
|
);
|
|
|
|
DO_LOCAL_SET_INFO(
|
|
"Make file writable",
|
|
handle1,
|
|
FILE_ATTRIBUTE_NORMAL
|
|
);
|
|
|
|
DO_LOCAL_CLOSE(
|
|
"Phase 0 close local handle",
|
|
handle1
|
|
);
|
|
|
|
//
|
|
// Now, reopen the file through the server for normal sharing.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Open temporary file, normal sharing",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Open temporary file, normal sharing",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ | SMB_DA_SHARE_DENY_NONE,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to create the same file in FCB mode. This should fail,
|
|
// because the file already exists.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"FCB create after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_FAIL | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
SMB_ERR_CLASS_DOS,
|
|
SMB_ERR_FILE_EXISTS
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"FCB create after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_FAIL | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_OBJECT_NAME_COLLISION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file in FCB mode. This should fail,
|
|
// because the file is already open in normal mode and the client
|
|
// has write access to the file.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"FCB open of writeable file after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
(UCHAR)( Redir->Dialect == SmbDialectDosLanMan20 ||
|
|
Redir->Dialect >= SmbDialectMsNet30 ? SMB_ERR_CLASS_HARDWARE :
|
|
SMB_ERR_CLASS_DOS ),
|
|
SMB_ERR_BAD_SHARE
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"FCB open of writeable file after normal open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SHARING_VIOLATION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// End of phase 1. Close files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 1 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 1 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the file in FCB mode. This should work.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"FCB open of writeable file; only open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"FCB open of writeable file; only open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file in FCB mode, from the same session.
|
|
// This should work, returning the same FID.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Duplicate FCB open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Duplicate FCB open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
if ( fid1 != fid2 ) {
|
|
printf( "'Duplicate FCB open' didn't get same FID: (1)=0x%lx, "
|
|
"(2)=0x%lx\n", fid1, fid2 );
|
|
SMB_ERROR_BREAK;
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
//
|
|
// Now try to open the same file in FCB mode, from a different session.
|
|
// This should fail with a sharing violation.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Conflicting FCB open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
(UCHAR)( Redir->Dialect == SmbDialectDosLanMan20 ||
|
|
Redir->Dialect >= SmbDialectMsNet30 ? SMB_ERR_CLASS_HARDWARE :
|
|
SMB_ERR_CLASS_DOS ),
|
|
SMB_ERR_BAD_SHARE
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Conflicting FCB open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SHARING_VIOLATION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// End of phase 2. Close files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 2 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 2 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// Reopen in compatibility mode, not FCB mode.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Hard compatibility reopen",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Hard compatibility reopen",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_ACCESS_READ_WRITE | SMB_DA_SHARE_COMPATIBILITY,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now try to open the same file in FCB mode, from the same session.
|
|
// This should work, returning a different FID.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"FCB open after compatibility open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"FCB open after compatibility open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
if ( fid1 == fid2 ) {
|
|
printf( "'Duplicate FCB open' got same FID: (1)=0x%lx, "
|
|
"(2)=0x%lx\n", fid1, fid2 );
|
|
SMB_ERROR_BREAK;
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
//
|
|
// End of phase 3. Close files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 3 close FID 2", 0, fid2, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 3 close FID 2", 0, fid2, STATUS_SUCCESS );
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 3 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 3 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// Open the file locally. Then try to do a FCB open of the file.
|
|
// This should fail, because the server will try to get exclusive
|
|
// access to the file.
|
|
//
|
|
|
|
DO_LOCAL_OPEN(
|
|
"Local open",
|
|
&fullFile,
|
|
GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
FILE_OPEN,
|
|
&handle1
|
|
);
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"FCB open conflicting with local open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
(UCHAR)( Redir->Dialect == SmbDialectDosLanMan20 ||
|
|
Redir->Dialect >= SmbDialectMsNet30 ? SMB_ERR_CLASS_HARDWARE :
|
|
SMB_ERR_CLASS_DOS ),
|
|
SMB_ERR_BAD_SHARE
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"FCB open conflicting with local open",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SHARING_VIOLATION
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Now make the file readonly, using the local handle. Then close
|
|
// the local handle.
|
|
//
|
|
|
|
DO_LOCAL_SET_INFO(
|
|
"Make file readonly",
|
|
handle1,
|
|
FILE_ATTRIBUTE_READONLY
|
|
);
|
|
|
|
DO_LOCAL_CLOSE(
|
|
"Close local handle",
|
|
handle1
|
|
);
|
|
|
|
//
|
|
// Try to open the file in FCB mode. This should work, resulting in
|
|
// a readonly, shared read (if soft compatibility enabled) open.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"FCB open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"FCB open of readonly file",
|
|
0,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_FAIL,
|
|
&fid1,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Make sure that the file was opened for normal sharing by trying
|
|
// to open the same file in FCB mode, from a differrent session.
|
|
// This should work.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_OPEN(
|
|
"Softly compatible FCB open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
0,
|
|
0
|
|
);
|
|
#else
|
|
DO_OPEN(
|
|
"Softly compatible FCB open",
|
|
1,
|
|
0,
|
|
&file,
|
|
SMB_DA_FCB_MASK,
|
|
SMB_OFUN_OPEN_OPEN | SMB_OFUN_CREATE_CREATE,
|
|
&fid2,
|
|
STATUS_SUCCESS
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// End of phase 4. Close files.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 4 close FID 2", 1, fid2, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 4 close FID 2", 1, fid2, STATUS_SUCCESS );
|
|
#endif
|
|
#ifdef DOSERROR
|
|
DO_CLOSE( "Phase 4 close FID 1", 0, fid1, 0, 0 );
|
|
#else
|
|
DO_CLOSE( "Phase 4 close FID 1", 0, fid1, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
//
|
|
// Open the file locally to turn off the READONLY bit. This
|
|
// must be done in order to delete the file.
|
|
//
|
|
|
|
DO_LOCAL_OPEN(
|
|
"Local open",
|
|
&fullFile,
|
|
FILE_WRITE_ATTRIBUTES,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
FILE_OPEN,
|
|
&handle1
|
|
);
|
|
|
|
//
|
|
// Now make the file normal, using the local handle. Then close
|
|
// the local handle.
|
|
//
|
|
|
|
DO_LOCAL_SET_INFO(
|
|
"Make file writable",
|
|
handle1,
|
|
FILE_ATTRIBUTE_NORMAL
|
|
);
|
|
|
|
DO_LOCAL_CLOSE(
|
|
"Close local handle",
|
|
handle1
|
|
);
|
|
|
|
//
|
|
// All done. Delete the file.
|
|
//
|
|
|
|
#ifdef DOSERROR
|
|
DO_DELETE( "Delete temporary file", 0, &file, 0, 0 );
|
|
#else
|
|
DO_DELETE( "Delete temporary file", 0, &file, STATUS_SUCCESS );
|
|
#endif
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // FcbController
|