📄 prefxsup.c
字号:
//
CdDissectName( IrpContext,
&LocalRemainingName,
&FinalName );
//
// Check if this name is in the splay tree for this Scb.
//
if (IgnoreCase) {
NameLink = CdFindNameLink( IrpContext,
&(*CurrentFcb)->IgnoreCaseRoot,
&FinalName );
//
// Get the prefix entry from this NameLink. Don't access any
// fields within it until we verify we have a name link.
//
PrefixEntry = (PPREFIX_ENTRY) CONTAINING_RECORD( NameLink,
PREFIX_ENTRY,
IgnoreCaseName );
} else {
NameLink = CdFindNameLink( IrpContext,
&(*CurrentFcb)->ExactCaseRoot,
&FinalName );
PrefixEntry = (PPREFIX_ENTRY) CONTAINING_RECORD( NameLink,
PREFIX_ENTRY,
ExactCaseName );
}
//
// If we didn't find a match then exit.
//
if (NameLink == NULL) { return; }
//
// If this is a case-insensitive match then copy the exact case of the name into
// the input buffer.
//
if (IgnoreCase) {
RtlCopyMemory( FinalName.Buffer,
PrefixEntry->ExactCaseName.FileName.Buffer,
PrefixEntry->ExactCaseName.FileName.Length );
}
//
// Update the caller's remaining name string to reflect the fact that we found
// a match.
//
*RemainingName = LocalRemainingName;
//
// Move down to the next component in the tree. Acquire without waiting.
// If this fails then lock the Fcb to reference this Fcb and then drop
// the parent and acquire the child.
//
if (!CdAcquireFcbExclusive( IrpContext, PrefixEntry->Fcb, TRUE )) {
//
// If we can't wait then raise CANT_WAIT.
//
if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) {
CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
}
CdLockVcb( IrpContext, IrpContext->Vcb );
PrefixEntry->Fcb->FcbReference += 1;
CdUnlockVcb( IrpContext, IrpContext->Vcb );
CdReleaseFcb( IrpContext, *CurrentFcb );
CdAcquireFcbExclusive( IrpContext, PrefixEntry->Fcb, FALSE );
CdLockVcb( IrpContext, IrpContext->Vcb );
PrefixEntry->Fcb->FcbReference -= 1;
CdUnlockVcb( IrpContext, IrpContext->Vcb );
} else {
CdReleaseFcb( IrpContext, *CurrentFcb );
}
*CurrentFcb = PrefixEntry->Fcb;
}
}
//
// Local support routine
//
PNAME_LINK
CdFindNameLink (
IN PIRP_CONTEXT IrpContext,
IN PRTL_SPLAY_LINKS *RootNode,
IN PUNICODE_STRING Name
)
/*++
Routine Description:
This routine searches through a splay link tree looking for a match for the
input name. If we find the corresponding name we will rebalance the
tree.
Arguments:
RootNode - Supplies the parent to search.
Name - This is the name to search for. Note if we are doing a case
insensitive search the name would have been upcased already.
Return Value:
PNAME_LINK - The name link found or NULL if there is no match.
--*/
{
FSRTL_COMPARISON_RESULT Comparison;
PNAME_LINK Node;
PRTL_SPLAY_LINKS Links;
PAGED_CODE();
Links = *RootNode;
while (Links != NULL) {
Node = CONTAINING_RECORD( Links, NAME_LINK, Links );
//
// Compare the prefix in the tree with the full name
//
Comparison = CdFullCompareNames( IrpContext, &Node->FileName, Name );
//
// See if they don't match
//
if (Comparison == GreaterThan) {
//
// The prefix is greater than the full name
// so we go down the left child
//
Links = RtlLeftChild( Links );
//
// And continue searching down this tree
//
} else if (Comparison == LessThan) {
//
// The prefix is less than the full name
// so we go down the right child
//
Links = RtlRightChild( Links );
//
// And continue searching down this tree
//
} else {
//
// We found it.
//
// Splay the tree and save the new root.
//
*RootNode = RtlSplay( Links );
return Node;
}
}
//
// We didn't find the Link.
//
return NULL;
}
//
// Local support routine
//
BOOLEAN
CdInsertNameLink (
IN PIRP_CONTEXT IrpContext,
IN PRTL_SPLAY_LINKS *RootNode,
IN PNAME_LINK NameLink
)
/*++
Routine Description:
This routine will insert a name in the splay tree pointed to
by RootNode.
The name could already exist in this tree for a case-insensitive tree.
In that case we simply return FALSE and do nothing.
Arguments:
RootNode - Supplies a pointer to the table.
NameLink - Contains the new link to enter.
Return Value:
BOOLEAN - TRUE if the name is inserted, FALSE otherwise.
--*/
{
FSRTL_COMPARISON_RESULT Comparison;
PNAME_LINK Node;
PAGED_CODE();
RtlInitializeSplayLinks( &NameLink->Links );
//
// If we are the first entry in the tree, just become the root.
//
if (*RootNode == NULL) {
*RootNode = &NameLink->Links;
return TRUE;
}
Node = CONTAINING_RECORD( *RootNode, NAME_LINK, Links );
while (TRUE) {
//
// Compare the prefix in the tree with the prefix we want
// to insert.
//
Comparison = CdFullCompareNames( IrpContext, &Node->FileName, &NameLink->FileName );
//
// If we found the entry, return immediately.
//
if (Comparison == EqualTo) { return FALSE; }
//
// If the tree prefix is greater than the new prefix then
// we go down the left subtree
//
if (Comparison == GreaterThan) {
//
// We want to go down the left subtree, first check to see
// if we have a left subtree
//
if (RtlLeftChild( &Node->Links ) == NULL) {
//
// there isn't a left child so we insert ourselves as the
// new left child
//
RtlInsertAsLeftChild( &Node->Links, &NameLink->Links );
//
// and exit the while loop
//
break;
} else {
//
// there is a left child so simply go down that path, and
// go back to the top of the loop
//
Node = CONTAINING_RECORD( RtlLeftChild( &Node->Links ),
NAME_LINK,
Links );
}
} else {
//
// The tree prefix is either less than or a proper prefix
// of the new string. We treat both cases as less than when
// we do insert. So we want to go down the right subtree,
// first check to see if we have a right subtree
//
if (RtlRightChild( &Node->Links ) == NULL) {
//
// These isn't a right child so we insert ourselves as the
// new right child
//
RtlInsertAsRightChild( &Node->Links, &NameLink->Links );
//
// and exit the while loop
//
break;
} else {
//
// there is a right child so simply go down that path, and
// go back to the top of the loop
//
Node = CONTAINING_RECORD( RtlRightChild( &Node->Links ),
NAME_LINK,
Links );
}
}
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -