📄 dirsup.c
字号:
// The names didn't match. If the input name is a possible short
// name and we are at the correct offset in the directory then
// check if the short names match.
//
if (((Dirent->DirentOffset >> SHORT_NAME_SHIFT) == ShortNameDirentOffset) &&
(Name->VersionString.Length == 0) &&
!CdIs8dot3Name( IrpContext,
Dirent->CdFileName.FileName )) {
//
// Create the short name and check for a match.
//
CdGenerate8dot3Name( IrpContext,
&Dirent->CdCaseFileName.FileName,
Dirent->DirentOffset,
FileContext->ShortName.FileName.Buffer,
&FileContext->ShortName.FileName.Length );
//
// Now check whether we have a name match.
// We exit the loop if we have a match.
//
if (CdIsNameInExpression( IrpContext,
&FileContext->ShortName,
Name,
0,
FALSE )) {
*MatchingName = &FileContext->ShortName,
Found = TRUE;
break;
}
}
}
//
// Go to the next initial dirent for a file.
//
} while (CdLookupNextInitialFileDirent( IrpContext, Fcb, FileContext ));
//
// If we find the file then collect all of the dirents.
//
if (Found) {
CdLookupLastFileDirent( IrpContext, Fcb, FileContext );
}
return Found;
}
BOOLEAN
CdFindDirectory (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCD_NAME Name,
IN BOOLEAN IgnoreCase,
IN OUT PFILE_ENUM_CONTEXT FileContext
)
/*++
Routine Description:
This routine is called to search a dirctory for a directory matching the input
name. This name has been upcased at this point if this a case-insensitive
search. We look for an exact match in the name and do not look for shortname
equivalents.
Arguments:
Fcb - Fcb for the directory being scanned.
Name - Name to search for.
IgnoreCase - Indicates the case of the search.
FileContext - File context to use for the search. This has already been
initialized.
Return Value:
BOOLEAN - TRUE if matching entry is found, FALSE otherwise.
--*/
{
PDIRENT Dirent;
BOOLEAN Found = FALSE;
PAGED_CODE();
//
// Make sure there is a stream file for this Fcb.
//
CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
//
// Position ourselves at the first entry.
//
CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, Fcb->StreamOffset );
//
// Loop while there are more entries in this directory.
//
do {
Dirent = &FileContext->InitialDirent->Dirent;
//
// We only look for directories. Directories cannot have the
// associated bit set.
//
if (FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_DIRECTORY )) {
//
// Update the name in the current dirent.
//
CdUpdateDirentName( IrpContext, Dirent, IgnoreCase );
//
// Don't bother with constant entries.
//
if (FlagOn( Dirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY )) {
continue;
}
//
// Now check whether we have a name match.
// We exit the loop if we have a match.
//
if (CdIsNameInExpression( IrpContext,
&Dirent->CdCaseFileName,
Name,
0,
TRUE )) {
Found = TRUE;
break;
}
}
//
// Go to the next initial dirent.
//
} while (CdLookupNextInitialFileDirent( IrpContext, Fcb, FileContext ));
return Found;
}
BOOLEAN
CdFindFileByShortName (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCD_NAME Name,
IN BOOLEAN IgnoreCase,
IN ULONG ShortNameDirentOffset,
IN OUT PFILE_ENUM_CONTEXT FileContext
)
/*++
Routine Description:
This routine is called to find the file name entry whose short name
is defined by the input DirentOffset. The dirent offset here is
multiplied by 32 and we look for the dirent begins in this 32 byte offset in
directory. The minimum dirent length is 34 so we are guaranteed that only
one dirent can begin in each 32 byte block in the directory.
Arguments:
Fcb - Fcb for the directory being scanned.
Name - Name we are trying to match. We know this contains the tilde
character followed by decimal characters.
IgnoreCase - Indicates whether we need to upcase the long name and
generated short name.
ShortNameDirentOffset - This is the shifted value for the offset of the
name in the directory.
FileContext - This is the initialized file context to use for the search.
Return Value:
BOOLEAN - TRUE if a matching name was found, FALSE otherwise.
--*/
{
BOOLEAN Found = FALSE;
PDIRENT Dirent;
ULONG ThisShortNameDirentOffset;
PAGED_CODE();
//
// Make sure there is a stream file for this Fcb.
//
CdVerifyOrCreateDirStreamFile( IrpContext, Fcb);
//
// Position ourselves at the start of the directory and update
//
//
CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, Fcb->StreamOffset );
//
// Loop until we have found the entry or are beyond this dirent.
//
do {
//
// Compute the short name dirent offset for the current dirent.
//
Dirent = &FileContext->InitialDirent->Dirent;
ThisShortNameDirentOffset = Dirent->DirentOffset >> SHORT_NAME_SHIFT;
//
// If beyond the target then exit.
//
if (ThisShortNameDirentOffset > ShortNameDirentOffset) {
break;
}
//
// If equal to the target then check if we have a name match.
// We will either match or fail here.
//
if (ThisShortNameDirentOffset == ShortNameDirentOffset) {
//
// If this is an associated file then get out.
//
if (FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_ASSOC )) {
break;
}
//
// Update the name in the dirent and check if it is not
// an 8.3 name.
//
CdUpdateDirentName( IrpContext, Dirent, IgnoreCase );
if (CdIs8dot3Name( IrpContext,
Dirent->CdFileName.FileName )) {
break;
}
//
// Generate the 8.3 name see if it matches our input name.
//
CdGenerate8dot3Name( IrpContext,
&Dirent->CdCaseFileName.FileName,
Dirent->DirentOffset,
FileContext->ShortName.FileName.Buffer,
&FileContext->ShortName.FileName.Length );
//
// Check if this name matches.
//
if (CdIsNameInExpression( IrpContext,
Name,
&FileContext->ShortName,
0,
FALSE )) {
//
// Let our caller know we found an entry.
//
Found = TRUE;
}
//
// Break out of the loop.
//
break;
}
//
// Continue until there are no more entries.
//
} while (CdLookupNextInitialFileDirent( IrpContext, Fcb, FileContext ));
//
// If we find the file then collect all of the dirents.
//
if (Found) {
CdLookupLastFileDirent( IrpContext, Fcb, FileContext );
}
return Found;
}
BOOLEAN
CdLookupNextInitialFileDirent (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_ENUM_CONTEXT FileContext
)
/*++
Routine Description:
This routine is called to walk through the directory until we find the
first possible dirent for file. We are positioned at some point described
by the FileContext. We will walk through any remaing dirents for the
current file until we find the first dirent for some subsequent file.
We can be called when we have found just one dirent for a file or all
of them. We first check the CurrentDirContext. In the typical
single-extent case this is unused. Then we look to the InitialDirContext
which must be initialized.
This routine will save the initial DirContext to the PriorDirContext and
clean up any existing DirContext for the Prior or Current positions in
the enumeration context.
Arguments:
Fcb - This is the directory to scan.
FileContext - This is the file enumeration context. It is currently pointing
at some file in the directory.
Return Value:
--*/
{
PRAW_DIRENT RawDirent;
PDIRENT_ENUM_CONTEXT CurrentDirContext;
PDIRENT_ENUM_CONTEXT TargetDirContext;
PCOMPOUND_DIRENT TempDirent;
BOOLEAN FoundDirent = FALSE;
BOOLEAN FoundLastDirent;
PAGED_CODE();
//
// Start by saving the initial dirent of the current file as the
// previous file.
//
TempDirent = FileContext->PriorDirent;
FileContext->PriorDirent = FileContext->InitialDirent;
FileContext->InitialDirent = TempDirent;
//
// We will use the initial dirent of the prior file unless the
// previous search returned multiple extents.
//
CurrentDirContext = &FileContext->PriorDirent->DirContext;
if (FlagOn( FileContext->Flags, FILE_CONTEXT_MULTIPLE_DIRENTS )) {
CurrentDirContext = &FileContext->CurrentDirent->DirContext;
}
//
// Clear all of the flags and file size for the next file.
//
FileContext->Flags = 0;
FileContext->FileSize = 0;
FileContext->ShortName.FileName.Length = 0;
//
// We always want to store the result into the updated initial dirent
// context.
//
TargetDirContext = &FileContext->InitialDirent->DirContext;
//
// Loop until we find the first dirent after the last dirent of the
// current file. We may not be at the last dirent for the current file yet
// so we may walk forward looking for the last and then find the
// initial dirent for the next file after that.
//
while (TRUE) {
//
// Remember if the last dirent we visited was the last dirent for
// a file.
//
RawDirent = CdRawDirent( IrpContext, CurrentDirContext );
FoundLastDirent = !FlagOn( CdRawDirentFlags( IrpContext, RawDirent ), CD_ATTRIBUTE_MULTI );
//
// Try to find another dirent.
//
FoundDirent = CdLookupNextDirent( IrpContext,
Fcb,
CurrentDirContext,
TargetDirContext );
//
// Exit the loop if no entry found.
//
if (!FoundDirent) {
break;
}
//
// Update the in-memory dirent.
//
CdUpdateDirentFromRawDirent( IrpContext,
Fcb,
TargetDirContext,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -