📄 openclos.c
字号:
RX_BLOCK_CONDITION FinalSrvOpenCondition;
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
PMRX_SRV_CALL SrvCall = RxContext->Create.pSrvCall;
PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
PAGED_CODE();
RxContext->pFobx = (PMRX_FOBX)RxCreateNetFobx( RxContext, SrvOpen);
if (RxContext->pFobx != NULL) {
ASSERT ( RxIsFcbAcquiredExclusive ( capFcb ) );
RxContext->pFobx->OffsetOfNextEaToReturn = 1;
Status = STATUS_SUCCESS;
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
return Status;
}
NTSTATUS
MRxSmbComputeNewBufferingState(
IN OUT PMRX_SRV_OPEN pMRxSrvOpen,
IN PVOID pMRxContext,
OUT PULONG pNewBufferingState)
/*++
Routine Description:
This routine maps the SMB specific oplock levels into the appropriate RDBSS
buffering state flags
Arguments:
pMRxSrvOpen - the MRX SRV_OPEN extension
pMRxContext - the context passed to RDBSS at Oplock indication time
pNewBufferingState - the place holder for the new buffering state
Return Value:
Notes:
--*/
{
ULONG OplockLevel,NewBufferingState;
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(pMRxSrvOpen);
PMRX_SMB_FCB smbFcb = MRxSmbGetFcbExtension(pMRxSrvOpen->pFcb);
PAGED_CODE();
ASSERT(pNewBufferingState != NULL);
OplockLevel = PtrToUlong(pMRxContext);
if (OplockLevel == SMB_OPLOCK_LEVEL_II) {
NewBufferingState = (FCB_STATE_READBUFFERING_ENABLED |
FCB_STATE_READCACHING_ENABLED);
} else {
NewBufferingState = 0;
}
pMRxSrvOpen->BufferingFlags = NewBufferingState;
MRxSmbMungeBufferingIfWriteOnlyHandles(
smbFcb->WriteOnlySrvOpenCount,
pMRxSrvOpen);
*pNewBufferingState = pMRxSrvOpen->BufferingFlags;
return STATUS_SUCCESS;
}
NTSTATUS
MRxSmbConstructDeferredOpenContext (
PRX_CONTEXT RxContext)
/*++
Routine Description:
This routine saves enough state that we can come back later and really do an
open if needed. We only do this for NT servers.
Arguments:
OrdinaryExchange - the exchange instance
Return Value:
NTSTATUS - The return status for the operation
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
RxCaptureFobx;
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
PSMBCEDB_SERVER_ENTRY pServerEntry = (PSMBCEDB_SERVER_ENTRY)RxContext->Create.pSrvCall->Context;
PSMBCE_SERVER pServer = &pServerEntry->Server;
PMRX_SMB_DEFERRED_OPEN_CONTEXT DeferredOpenContext;
PDFS_NAME_CONTEXT pDNC=NULL;
DWORD cbSize;
PAGED_CODE();
RxDbgTrace(+1, Dbg, ("MRxSmbConstructDeferredOpenContext\n"));
ASSERT(smbSrvOpen->DeferredOpenContext == NULL);
cbSize = sizeof(MRX_SMB_DEFERRED_OPEN_CONTEXT);
// if there is a dfs name context, we need to allocate memory
// fot aht too, because the name that is included in the
// context is deallocated by DFS when it returns from the create call
if(pDNC = RxContext->Create.NtCreateParameters.DfsNameContext)
{
cbSize += (sizeof(DFS_NAME_CONTEXT)+pDNC->UNCFileName.MaximumLength+sizeof(DWORD));
}
DeferredOpenContext = RxAllocatePoolWithTag(
NonPagedPool,
cbSize,
MRXSMB_DEFROPEN_POOLTAG);
if (DeferredOpenContext == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto FINALLY;
}
smbSrvOpen->DeferredOpenContext = DeferredOpenContext;
DeferredOpenContext->NtCreateParameters = RxContext->Create.NtCreateParameters;
DeferredOpenContext->RxContextCreateFlags = RxContext->Create.Flags;
DeferredOpenContext->RxContextFlags = RxContext->Flags;
DeferredOpenContext->NtCreateParameters.SecurityContext = NULL;
MRxSmbAdjustCreateParameters(RxContext, &DeferredOpenContext->SmbCp);
SetFlag(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_DEFERRED_OPEN);
if (pDNC)
{
PDFS_NAME_CONTEXT pDNCDeferred=NULL;
// point the dfs name context after the rxcontext
pDNCDeferred = (PDFS_NAME_CONTEXT)((PBYTE)DeferredOpenContext+sizeof(MRX_SMB_DEFERRED_OPEN_CONTEXT));
DeferredOpenContext->NtCreateParameters.DfsNameContext = pDNCDeferred;
// copy the info
*pDNCDeferred = *pDNC;
if (pDNC->UNCFileName.Length)
{
ASSERT(pDNC->UNCFileName.Buffer);
// point the name buffer after deferredcontext+dfs_name_context
pDNCDeferred->UNCFileName.Buffer = (PWCHAR)((PBYTE)pDNCDeferred+sizeof(DFS_NAME_CONTEXT));
memcpy(pDNCDeferred->UNCFileName.Buffer,
pDNC->UNCFileName.Buffer,
pDNC->UNCFileName.Length);
}
}
FINALLY:
RxDbgTrace(-1, Dbg, ("MRxSmbConstructDeferredOpenContext, Status=%08lx\n",Status));
return Status;
}
VOID
MRxSmbAdjustCreateParameters (
PRX_CONTEXT RxContext,
PMRXSMB_CREATE_PARAMETERS smbcp
)
/*++
Routine Description:
This uses the RxContext as a base to reeach out and get the values of the NT
create parameters. It also (a) implements the SMB idea that unbuffered is
translated to write-through and (b) gets the SMB security flags.
Arguments:
Return Value:
Notes:
--*/
{
PNT_CREATE_PARAMETERS cp = &RxContext->Create.NtCreateParameters;
PAGED_CODE();
RxDbgTrace(+1, Dbg, ("MRxSmbAdjustCreateParameters\n"));
if (!FlagOn(RxContext->Flags,RX_CONTEXT_FLAG_MINIRDR_INITIATED)) {
cp->CreateOptions = cp->CreateOptions & ~(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT);
//the NT SMB spec says we have to change no-intermediate-buffering to write-through
if (FlagOn(cp->CreateOptions,FILE_NO_INTERMEDIATE_BUFFERING)) {
ASSERT (RxContext->CurrentIrpSp!=NULL);
if (RxContext->CurrentIrpSp!=NULL) {
PFILE_OBJECT capFileObject = RxContext->CurrentIrpSp->FileObject;
ClearFlag(cp->CreateOptions,FILE_NO_INTERMEDIATE_BUFFERING);
SetFlag(cp->CreateOptions,FILE_WRITE_THROUGH);
SetFlag(RxContext->Flags,RX_CONTEXT_FLAG_WRITE_THROUGH);
SetFlag(capFileObject->Flags,FO_WRITE_THROUGH);
}
}
smbcp->Pid = RxGetRequestorProcessId(RxContext);
smbcp->SecurityFlags = 0;
if (cp->SecurityContext != NULL) {
if (cp->SecurityContext->SecurityQos != NULL) {
if (cp->SecurityContext->SecurityQos->ContextTrackingMode == SECURITY_DYNAMIC_TRACKING) {
smbcp->SecurityFlags |= SMB_SECURITY_DYNAMIC_TRACKING;
}
if (cp->SecurityContext->SecurityQos->EffectiveOnly) {
smbcp->SecurityFlags |= SMB_SECURITY_EFFECTIVE_ONLY;
}
}
}
} else {
//here, we have a defered open!!!
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
//the parameters have already been adjusted...BUT null the security context.......
cp->SecurityContext = NULL;
*smbcp = smbSrvOpen->DeferredOpenContext->SmbCp;
}
RxDbgTrace(-1, Dbg, ("MRxSmbAdjustCreateParameters\n"));
}
INLINE VOID
MRxSmbAdjustReturnedCreateAction(
IN OUT PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine repairs a bug in NT servers whereby the create action is
contaminated by an oplock break. Basically, we make sure that if the guy
asked for FILE_OPEN and it works then he does not get FILE_SUPERCEDED or
FILE_CREATED as the result.
Arguments:
RxContext - the context for the operation so as to find the place where
info is returned
Return Value:
none
Notes:
--*/
{
ULONG q = RxContext->Create.ReturnedCreateInformation;
PAGED_CODE();
if ((q==FILE_SUPERSEDED)||(q==FILE_CREATED)||(q >FILE_MAXIMUM_DISPOSITION)) {
RxContext->Create.ReturnedCreateInformation = FILE_OPENED;
}
}
UNICODE_STRING UnicodeBackslash = {2,4,L"\\"};
NTSTATUS
MRxSmbBuildNtCreateAndX (
PSMBSTUFFER_BUFFER_STATE StufferState,
PMRXSMB_CREATE_PARAMETERS smbcp
)
/*++
Routine Description:
This builds an NtCreateAndX SMB. we don't have to worry about login id and such
since that is done by the connection engine....pretty neat huh? all we have to do
is to format up the bits
Arguments:
StufferState - the state of the smbbuffer from the stuffer's point of view
Return Value:
NTSTATUS
SUCCESS
NOT_IMPLEMENTED something has appeared in the arguments that i can't handle
Notes:
--*/
{
NTSTATUS Status;
PRX_CONTEXT RxContext = StufferState->RxContext;
PNT_CREATE_PARAMETERS cp = &RxContext->Create.NtCreateParameters;
RxCaptureFcb;
ACCESS_MASK DesiredAccess;
ULONG OplockFlags;
PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PSMBCE_SERVER pServer;
PAGED_CODE();
RxDbgTrace(+1, Dbg, ("MRxSmbBuildNtCreateAndX\n", 0 ));
pServer = SmbCeGetExchangeServer(StufferState->Exchange);
if (!(cp->CreateOptions & FILE_DIRECTORY_FILE) &&
(cp->DesiredAccess & (FILE_READ_DATA | FILE_WRITE_DATA | FILE_EXECUTE )) &&
!MRxSmbOplocksDisabled) {
DesiredAccess = cp->DesiredAccess & ~SYNCHRONIZE;
OplockFlags = (NT_CREATE_REQUEST_OPLOCK | NT_CREATE_REQUEST_OPBATCH);
} else {
DesiredAccess = cp->DesiredAccess;
OplockFlags = 0;
}
if ((RemainingName->Length==0)
&& (FlagOn(RxContext->Create.Flags,RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH)) ) {
RemainingName = &UnicodeBackslash;
}
COVERED_CALL(MRxSmbStartSMBCommand (StufferState, SetInitialSMB_Never,
SMB_COM_NT_CREATE_ANDX, SMB_REQUEST_SIZE(NT_CREATE_ANDX),
NO_EXTRA_DATA,SMB_BEST_ALIGNMENT(4,0),RESPONSE_HEADER_SIZE_NOT_SPECIFIED,
0,0,0,0 STUFFERTRACE(Dbg,'FC'))
);
SmbCeSetFullProcessIdInHeader(
StufferState->Exchange,
smbcp->Pid,
((PNT_SMB_HEADER)StufferState->BufferBase));
MRxSmbStuffSMB (StufferState,
"XmwdddDdddDddyB",
// X UCHAR WordCount; // Count of parameter words = 24
// . UCHAR AndXCommand; // Secondary command; 0xFF = None
// . UCHAR AndXReserved; // MBZ
// . _USHORT( AndXOffset ); // Offset to next command wordcount
// m UCHAR Reserved; // MBZ
BooleanFlagOn(pServer->DialectFlags,DF_UNICODE)?
RemainingName->Length:RtlxUnicodeStringToOemSize(RemainingName),
// w _USHORT( NameLength ); // Length of Name[] in bytes
OplockFlags, // d _ULONG( Flags ); // Create flags
0, //not used // d _ULONG( RootDirectoryFid ); // If non-zero, open is relative to this directory
DesiredAccess, // d ACCESS_MASK DesiredAccess; // NT access desired
// Dd LARGE_INTEGER AllocationSize; // Initial allocation size
SMB_OFFSET_CHECK(NT_CREATE_ANDX,AllocationSize)
cp->AllocationSize.LowPart, cp->AllocationSize.HighPart,
cp->FileAttributes, // d _ULONG( FileAttributes ); // File attributes for creation
cp->ShareAccess, // d _ULONG( ShareAccess ); // Type of share access
// D _ULONG( CreateDisposition ); // Action to take if file exists or not
SMB_OFFSET_CHECK(NT_CREATE_ANDX,CreateDisposition)
cp->Disposition,
cp->CreateOptions, // d _ULONG( CreateOptions ); // Options to use if creating a file
cp->ImpersonationLevel,// d _ULONG( ImpersonationLevel ); // Security QOS information
smbcp->SecurityFlags, // y UCHAR SecurityFlags; // Security QOS information
SMB_WCT_CHECK(24) 0 // B _USHORT( ByteCount ); // Length of byte parameters
// . UCHAR Buffer[1];
// . //UCHAR Name[]; // File to open or create
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -