netroot.c
来自「winddk src目录下的文件系统驱动源码压缩!」· C语言 代码 · 共 1,128 行 · 第 1/3 页
C
1,128 行
IoFreeMdl(pSmbRequestMdl);
}
RxFreePool(pSmbActualBuffer);
}
} else {
RxFreePool(pSmbActualBuffer);
}
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
return Status;
}
NTSTATUS
SmbConstructNetRootExchangeReceive(
IN struct _SMB_EXCHANGE *pExchange,
IN ULONG BytesIndicated,
IN ULONG BytesAvailable,
OUT ULONG *pBytesTaken,
IN PSMB_HEADER pSmbHeader,
OUT PMDL *pDataBufferPointer,
OUT PULONG pDataSize,
IN ULONG ReceiveFlags)
/*++
Routine Description:
This is the recieve indication handling routine for net root construction exchanges
Arguments:
pExchange - the exchange instance
BytesIndicated - the number of bytes indicated
Bytes Available - the number of bytes available
pBytesTaken - the number of bytes consumed
pSmbHeader - the byte buffer
pDataBufferPointer - the buffer into which the remaining data is to be copied.
pDataSize - the buffer size.
Return Value:
NTSTATUS - The return status for the operation
Notes:
This routine is called at DPC level.
--*/
{
NTSTATUS Status;
PSMB_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange;
pNetRootExchange = (PSMB_CONSTRUCT_NETROOT_EXCHANGE)pExchange;
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("ParseSmbHeader BytesIndicated/Available %ld %ld\n",BytesIndicated,BytesAvailable));
if (BytesAvailable > BytesIndicated ||
!FlagOn(ReceiveFlags,TDI_RECEIVE_ENTIRE_MESSAGE)) {
// The SMB response was not completely returned. Post a copy data request to
// get the remainder of the response. If the response is greater than the original
// buffer size, abort this connection request and consume the bytes available.
if (BytesAvailable > CONSTRUCT_NETROOT_BUFFER_SIZE) {
ASSERT(!"not enough bytes in parsesmbheader.....sigh.............."); // To be removed soon ...
pExchange->Status = STATUS_NOT_IMPLEMENTED;
*pBytesTaken = BytesAvailable;
Status = STATUS_SUCCESS;
} else {
*pBytesTaken = 0;
*pDataBufferPointer = pNetRootExchange->pSmbResponseMdl;
*pDataSize = CONSTRUCT_NETROOT_BUFFER_SIZE;
Status = STATUS_MORE_PROCESSING_REQUIRED;
}
} else {
// The SMB exchange completed without an error.
pExchange->Status = SmbCeParseConstructNetRootResponse(
pNetRootExchange,
pSmbHeader,
BytesAvailable,
BytesIndicated,
pBytesTaken);
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("ParseSmbHeader BytesTaken %ld\n",*pBytesTaken));
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("ParseSmbHeader Return Status %lx\n",pExchange->Status));
Status = STATUS_SUCCESS;
}
return Status;
}
NTSTATUS
SmbConstructNetRootExchangeCopyDataHandler(
IN PSMB_EXCHANGE pExchange,
IN PMDL pCopyDataBuffer,
IN ULONG DataSize)
/*++
Routine Description:
This is the copy data handling routine for net root construction exchanges
Arguments:
pExchange - the exchange instance
Return Value:
NTSTATUS - The return status for the operation
--*/
{
PSMB_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange;
PSMB_HEADER pSmbHeader;
ULONG ResponseSize = DataSize;
ULONG ResponseBytesConsumed = 0;
NTSTATUS Status = STATUS_SUCCESS;
pNetRootExchange = (PSMB_CONSTRUCT_NETROOT_EXCHANGE)pExchange;
ASSERT(pCopyDataBuffer == pNetRootExchange->pSmbResponseMdl);
pSmbHeader = (PSMB_HEADER)MmGetSystemAddressForMdlSafe(pNetRootExchange->pSmbResponseMdl,LowPagePriority);
if (pSmbHeader != NULL) {
pExchange->Status = SmbCeParseConstructNetRootResponse(
pNetRootExchange,
pSmbHeader,
ResponseSize,
ResponseSize,
&ResponseBytesConsumed);
} else {
Status = STATUS_INSUFFICIENT_RESOURCES;
}
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("ParseSmbHeader BytesTaken %ld\n",ResponseBytesConsumed));
return Status;
}
NTSTATUS
SmbCeParseConstructNetRootResponse(
PSMB_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange,
PSMB_HEADER pSmbHeader,
ULONG BytesAvailable,
ULONG BytesIndicated,
ULONG *pBytesTaken)
{
NTSTATUS Status,SmbResponseStatus;
GENERIC_ANDX CommandToProcess;
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("ParseSmbHeader BytesIndicated %ld\n",BytesIndicated));
Status = SmbCeParseSmbHeader(
(PSMB_EXCHANGE)pNetRootExchange,
pSmbHeader,
&CommandToProcess,
&SmbResponseStatus,
BytesAvailable,
BytesIndicated,
pBytesTaken);
if (Status == STATUS_SUCCESS) {
*pBytesTaken = BytesIndicated;
}
return Status;
}
NTSTATUS
SmbConstructNetRootExchangeFinalize(
PSMB_EXCHANGE pExchange,
BOOLEAN *pPostFinalize)
/*++
Routine Description:
This routine finalizes the construct net root exchange. It resumes the RDBSS by invoking
the call back and discards the exchange
Arguments:
pExchange - the exchange instance
CurrentIrql - the current interrupt request level
pPostFinalize - a pointer to a BOOLEAN if the request should be posted
Return Value:
RXSTATUS - The return status for the operation
--*/
{
PSMB_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange;
PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext;
PMRX_NETROOT_CALLBACK pNetRootCallback;
PMRX_V_NET_ROOT pVNetRoot;
PMRX_NET_ROOT pNetRoot;
PSMBCEDB_SERVER_ENTRY pServerEntry = SmbCeGetExchangeServerEntry(pExchange);
PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext;
NTSTATUS Status = pExchange->Status;
if (RxShouldPostCompletion()) {
*pPostFinalize = TRUE;
return STATUS_SUCCESS;
} else {
*pPostFinalize = FALSE;
}
pVNetRoot = SmbCeGetExchangeVNetRoot(pExchange);
pNetRoot = pVNetRoot->pNetRoot;
pVNetRootContext = SmbCeGetAssociatedVNetRootContext(pVNetRoot);
ASSERT((pVNetRoot == NULL) || (pVNetRoot->pNetRoot == pNetRoot));
pNetRootExchange = (PSMB_CONSTRUCT_NETROOT_EXCHANGE)pExchange;
pNetRootCallback = pNetRootExchange->NetRootCallback;
ASSERT(pNetRootExchange->Type == CONSTRUCT_NETROOT_EXCHANGE);
pCreateNetRootContext = pNetRootExchange->pCreateNetRootContext;
pCreateNetRootContext->VirtualNetRootStatus = STATUS_SUCCESS;
pCreateNetRootContext->NetRootStatus = STATUS_SUCCESS;
RxDbgTrace(0,Dbg,("SmbConstructNetRootExchangeFinalize: Net Root Exchange Status %lx\n", pExchange->Status));
if (!NT_SUCCESS(pExchange->Status)) {
if (pCreateNetRootContext->RxContext &&
pCreateNetRootContext->RxContext->Create.ThisIsATreeConnectOpen){
InterlockedIncrement(&MRxSmbStatistics.FailedUseCount);
}
pCreateNetRootContext->VirtualNetRootStatus = Status;
if (pCreateNetRootContext->VirtualNetRootStatus == STATUS_INVALID_HANDLE) {
pCreateNetRootContext->VirtualNetRootStatus = STATUS_UNEXPECTED_NETWORK_ERROR;
}
if (pNetRootExchange->fInitializeNetRoot) {
pCreateNetRootContext->NetRootStatus = Status;
if (pCreateNetRootContext->NetRootStatus == STATUS_INVALID_HANDLE) {
pCreateNetRootContext->NetRootStatus = STATUS_UNEXPECTED_NETWORK_ERROR;
}
}
SmbCeUpdateVNetRootContextState(
pVNetRootContext,
SMBCEDB_MARKED_FOR_DELETION);
} else {
PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry;
pNetRootEntry = SmbCeGetExchangeNetRootEntry(pExchange);
// Update the associated wrapper data structures.
SmbCeUpdateNetRoot(pNetRootEntry,pNetRoot);
}
SmbCeReferenceVNetRootContext(pVNetRootContext);
SmbCeCompleteVNetRootContextInitialization(pVNetRootContext);
pExchange->SmbCeFlags &= ~SMBCE_EXCHANGE_NETROOT_CONSTRUCTOR;
ASSERT((pCreateNetRootContext->VirtualNetRootStatus != STATUS_SUCCESS) || (pVNetRoot->Context != NULL));
if ((pCreateNetRootContext->NetRootStatus == STATUS_CONNECTION_RESET)||(pCreateNetRootContext->NetRootStatus == STATUS_IO_TIMEOUT))
{
SmbCeLog(("!!Remote Reset Status=%x\n", pCreateNetRootContext->NetRootStatus));
}
if (pNetRootExchange->pSmbResponseMdl != NULL) {
MmUnlockPages(pNetRootExchange->pSmbResponseMdl);
IoFreeMdl(pNetRootExchange->pSmbResponseMdl);
}
if (pNetRootExchange->pSmbRequestMdl != NULL) {
RxUnlockHeaderPages(pNetRootExchange->pSmbRequestMdl);
IoFreeMdl(pNetRootExchange->pSmbRequestMdl);
}
if (pNetRootExchange->pSmbActualBuffer != NULL) {
RxFreePool(pNetRootExchange->pSmbActualBuffer);
}
// Tear down the exchange instance ...
SmbCeDiscardExchange(pExchange);
// Callback the RDBSS for resumption
pNetRootCallback(pCreateNetRootContext);
return STATUS_SUCCESS;
}
SMB_EXCHANGE_DISPATCH_VECTOR
ConstructNetRootExchangeDispatch = {
SmbConstructNetRootExchangeStart,
SmbConstructNetRootExchangeReceive,
SmbConstructNetRootExchangeCopyDataHandler,
NULL, // No SendCompletionHandler
SmbConstructNetRootExchangeFinalize,
NULL
};
VOID
MRxSmbExtractNetRootName(
IN PUNICODE_STRING FilePathName,
IN PMRX_SRV_CALL SrvCall,
OUT PUNICODE_STRING NetRootName,
OUT PUNICODE_STRING RestOfName OPTIONAL
)
/*++
Routine Description:
This routine parses the input name into srv, netroot, and the
rest.
Arguments:
--*/
{
UNICODE_STRING xRestOfName;
ULONG length = FilePathName->Length;
PWCH w = FilePathName->Buffer;
PWCH wlimit = (PWCH)(((PCHAR)w)+length);
PWCH wlow;
PAGED_CODE();
w += (SrvCall->pSrvCallName->Length/sizeof(WCHAR));
NetRootName->Buffer = wlow = w;
for (;;) {
if (w>=wlimit) break;
if ( (*w == OBJ_NAME_PATH_SEPARATOR) && (w!=wlow) ){
break;
}
w++;
}
NetRootName->Length = NetRootName->MaximumLength
= (USHORT)((PCHAR)w - (PCHAR)wlow);
if (!RestOfName) RestOfName = &xRestOfName;
RestOfName->Buffer = w;
RestOfName->Length = RestOfName->MaximumLength
= (USHORT)((PCHAR)wlimit - (PCHAR)w);
RxDbgTrace( 0,Dbg,(" MRxSmbExtractNetRootName FilePath=%wZ\n",FilePathName));
RxDbgTrace(0,Dbg,(" Srv=%wZ,Root=%wZ,Rest=%wZ\n",
SrvCall->pSrvCallName,NetRootName,RestOfName));
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?