📄 fileinfo.c
字号:
if (smbFobx->Enumeration.ResumeInfo!=NULL) {
PREQ_FIND_NEXT2 pFindNext2Request;
RxDbgTrace(0, Dbg, ("-->FINDNEXT\n"));
if (smbFobx->Enumeration.ErrorStatus != STATUS_SUCCESS) {
Status = smbFobx->Enumeration.ErrorStatus;
RxDbgTrace(0, Dbg, ("-->ERROR EARLY OUT\n"));
goto FINALLY;
}
Setup = TRANS2_FIND_NEXT2;
pFindNext2Request = &smbFobx->Enumeration.ResumeInfo->FindNext2_Request;
pFindNext2Request->Sid = smbFobx->Enumeration.SearchHandle;
pFindNext2Request->SearchCount = NumEntries;
pFindNext2Request->InformationLevel = IsNonNtT2Find?SMB_INFO_QUERY_EA_SIZE:SmbFileInfoLevel;
//pFindNext2Request->ResumeKey and pFindNext2Request->Buffer are setup by the previous pass
pFindNext2Request->Flags = SearchFlags;
SendParamsBuffer = (PBYTE)pFindNext2Request;
SendParamsBufferLength = smbFobx->Enumeration.ResumeInfo->ParametersLength;
ReceiveParamsBuffer = (PBYTE)&XX.FindNext2Response;
ReceiveParamsBufferLength = sizeof(XX.FindNext2Response);
if (IsNonNtT2Find) {
//
// The LMX server wants this to be 10 instead of 8, for some reason.
// If you set it to 8, the server gets very confused. Also, warp.
//
ReceiveParamsBufferLength = 10; //....sigh
}
} else {
// if the ResumeInfo buffer was not allocated, the end of the search has been reached.
Status = STATUS_NO_MORE_FILES;
smbFobx->Enumeration.EndOfSearchReached = TRUE;
smbFobx->Enumeration.ErrorStatus = STATUS_NO_MORE_FILES;
ClearFlag(smbFobx->Enumeration.Flags,SMBFOBX_ENUMFLAG_READ_FROM_CACHE);
goto FINALLY;
}
}
if ((DirEntriesAreUaligned) &&
(smbFobx->Enumeration.UnalignedDirEntrySideBuffer == NULL)) {
MRxSmbAllocateSideBuffer(RxContext,smbFobx,
Setup, &smbtemplate
);
if (smbFobx->Enumeration.UnalignedDirEntrySideBuffer == NULL) {
RxDbgTrace(0, Dbg, (" --> Couldn't get the win95 sidebuffer!\n"));
Status = STATUS_INSUFFICIENT_RESOURCES;
goto FINALLY;
}
UnalignedDirEntrySideBuffer = smbFobx->Enumeration.UnalignedDirEntrySideBuffer;
smbFobx->Enumeration.IsUnicode = IsUnicode;
smbFobx->Enumeration.IsNonNtT2Find = IsNonNtT2Find;
}
{
PSIDE_BUFFER SideBuffer;
SideBuffer = (PSIDE_BUFFER)CONTAINING_RECORD(
smbFobx->Enumeration.UnalignedDirEntrySideBuffer,
SIDE_BUFFER,
Buffer);
ASSERT(SideBuffer->Signature == 'JLBS');
ASSERT(SideBuffer->Fobx == capFobx);
ASSERT(SideBuffer->Fcb == capFcb);
ASSERT(SideBuffer->smbFobx == smbFobx);
ASSERT(smbFobx->Enumeration.SerialNumber == SideBuffer->SerialNumber);
}
Status = SmbCeTransact(
RxContext,
pTransactionOptions,
&Setup,
sizeof(Setup),
NULL,
0,
SendParamsBuffer,
SendParamsBufferLength,
ReceiveParamsBuffer,
ReceiveParamsBufferLength,
NULL,
0,
DirEntriesAreUaligned?UnalignedDirEntrySideBuffer:Buffer, // the buffer for data
DirEntriesAreUaligned?UnalignedDirEntrySideBufferSize:*pLengthRemaining, // the length of the buffer
&ResumptionContext);
if (NT_SUCCESS(Status)) {
BOOLEAN EndOfSearchReached;
{
PSIDE_BUFFER SideBuffer;
SideBuffer = (PSIDE_BUFFER)CONTAINING_RECORD(
smbFobx->Enumeration.UnalignedDirEntrySideBuffer,
SIDE_BUFFER,
Buffer);
ASSERT(SideBuffer->Signature == 'JLBS');
ASSERT(SideBuffer->Fobx == capFobx);
ASSERT(SideBuffer->Fcb == capFcb);
ASSERT(SideBuffer->smbFobx == smbFobx);
ASSERT(smbFobx->Enumeration.SerialNumber == SideBuffer->SerialNumber);
}
if (NT_SUCCESS(Status)) {
// a) need to set the length remaining correctly
// b) need to setup for a resume and see if the search was closed
ULONG LastNameOffset=0;
PMRX_SMB_DIRECTORY_RESUME_INFO ResumeInfo = NULL;
ULONG OriginalBufferLength = *pLengthRemaining;
IF_DEBUG { LastNameOffset = 0x40000000; }
RetryCount = 0;
smbFobx->Enumeration.Flags |= SMBFOBX_ENUMFLAG_SEARCH_NOT_THE_FIRST;
smbFobx->Enumeration.TotalDataBytesReturned = ResumptionContext.DataBytesReceived;
if (Setup == TRANS2_FIND_FIRST2) {
smbFobx->Enumeration.SearchHandle = FindFirst2Response.Sid;
smbFobx->Enumeration.Version = ResumptionContext.ServerVersion;
smbFobx->Enumeration.Flags |= SMBFOBX_ENUMFLAG_SEARCH_HANDLE_OPEN; //but look right below
EndOfSearchReached = (BOOLEAN)FindFirst2Response.EndOfSearch;
FilesReturned = FindFirst2Response.SearchCount;
LastNameOffset = FindFirst2Response.LastNameOffset;
} else {
EndOfSearchReached = (BOOLEAN)XX.FindNext2Response.EndOfSearch;
FilesReturned = XX.FindNext2Response.SearchCount;
LastNameOffset = XX.FindNext2Response.LastNameOffset;
}
//
// Please note: LANMAN 2.x servers prematurely set the
// EndOfSearch flag, so we must ignore it on LM 2.x servers.
//
// NT Returns the correct information, none of the LM varients
// appear to do so.
//
if (IsNonNtT2Find) {
EndOfSearchReached = FALSE;
}
if (Status==STATUS_SUCCESS && FilesReturned==0) {
RxDbgTrace( 0, Dbg, ("MRxSmbQueryDirectory: no files returned...switch status\n"));
EndOfSearchReached = TRUE;
Status = STATUS_NO_MORE_FILES;
}
if (!DirEntriesAreUaligned) {
*pLengthRemaining -= ResumptionContext.DataBytesReceived;
if (EndOfSearchReached) {
smbFobx->Enumeration.ErrorStatus = STATUS_NO_MORE_FILES;
}
}
if (EndOfSearchReached ||
SearchFlags & SMB_FIND_CLOSE_AFTER_REQUEST) {
ClearFlag(smbFobx->Enumeration.Flags,SMBFOBX_ENUMFLAG_SEARCH_HANDLE_OPEN);
}
if (FlagOn(smbFobx->Enumeration.Flags,SMBFOBX_ENUMFLAG_SEARCH_HANDLE_OPEN)) {
//if the search handle is open, then we set up to resume
RxDbgTrace(0,Dbg,("MRxSmbQueryDirectory: rinfo = %08lx\n", smbFobx->Enumeration.ResumeInfo));
if (smbFobx->Enumeration.ResumeInfo==NULL) {
smbFobx->Enumeration.ResumeInfo =
(PMRX_SMB_DIRECTORY_RESUME_INFO)RxAllocatePoolWithTag(
PagedPool,
sizeof(MRX_SMB_DIRECTORY_RESUME_INFO),
MRXSMB_DIRCTL_POOLTAG);
RxDbgTrace(0,Dbg,("MRxSmbQueryDirectory: allocatedinfo = %08lx\n", ResumeInfo));
if (smbFobx->Enumeration.ResumeInfo == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto FINALLY;
}
}
ResumeInfo = smbFobx->Enumeration.ResumeInfo;
ASSERT (ResumeInfo!=NULL);
{
PSIDE_BUFFER SideBuffer;
SideBuffer = (PSIDE_BUFFER)CONTAINING_RECORD(
smbFobx->Enumeration.UnalignedDirEntrySideBuffer,
SIDE_BUFFER,
Buffer);
ASSERT(SideBuffer->Signature == 'JLBS');
ASSERT(SideBuffer->Fobx == capFobx);
ASSERT(SideBuffer->Fcb == capFcb);
ASSERT(SideBuffer->smbFobx == smbFobx);
ASSERT(smbFobx->Enumeration.SerialNumber == SideBuffer->SerialNumber);
}
RxLog(("MRxqdir: rinfo = %lx", smbFobx->Enumeration.ResumeInfo));
RxLog(("MRxqdir2: olen = %lx, thisl = %lx",
OriginalBufferLength, ResumptionContext.DataBytesReceived));
if (!DirEntriesAreUaligned) {
PBYTE LastEntry = ((PBYTE)Buffer)+LastNameOffset;
RxDbgTrace(0,Dbg,("MRxSmbQueryDirectory: lastentry = %08lx\n", LastEntry));
//this is for NT....the data is already in the buffer.......just setup the resume info
if (SmbFileInfoLevel>=SMB_FIND_FILE_DIRECTORY_INFO) { //we may start sending nonNT levels...could be an assert
PREQ_FIND_NEXT2 pFindNext2Request = &ResumeInfo->FindNext2_Request;
ULONG resumekey = ((PFILE_FULL_DIR_INFORMATION)LastEntry)->FileIndex;
ULONG FileNameLength; PWCHAR FileNameBuffer;
pFindNext2Request->ResumeKey = resumekey;
RxDbgTrace(0,Dbg,("MRxSmbQueryDirectory: resumekey = %08lx\n", resumekey));
FileNameLength = *((PULONG)(LastEntry+smbFobx->Enumeration.FileNameLengthOffset));
FileNameBuffer = (PWCHAR)(LastEntry+smbFobx->Enumeration.FileNameOffset);
IF_DEBUG {
UNICODE_STRING LastName;
LastName.Buffer = FileNameBuffer;
LastName.Length = (USHORT)FileNameLength;
RxDbgTrace(0,Dbg,("MRxSmbQueryDirectory: resumename = %wZ\n", &LastName));
}
ASSERT ( (((PBYTE)FileNameBuffer)+FileNameLength)
<=(((PBYTE)Buffer)+OriginalBufferLength) );
RtlCopyMemory(&pFindNext2Request->Buffer[0],FileNameBuffer,FileNameLength);
//buffer is a UCHAR...not WCHAR
pFindNext2Request->Buffer[FileNameLength] = 0; //nullterminated in unicode
pFindNext2Request->Buffer[FileNameLength+1] = 0; //nullterminated in unicode
smbFobx->Enumeration.ResumeInfo->ParametersLength
= (USHORT)(&pFindNext2Request->Buffer[FileNameLength+2] - (PBYTE)pFindNext2Request);
} else {
ASSERT(!"don't know how to get resume key/name for nonNT");
}
}
}
{
PSIDE_BUFFER SideBuffer;
SideBuffer = (PSIDE_BUFFER)CONTAINING_RECORD(
smbFobx->Enumeration.UnalignedDirEntrySideBuffer,
SIDE_BUFFER,
Buffer);
ASSERT(SideBuffer->Signature == 'JLBS');
ASSERT(SideBuffer->Fobx == capFobx);
ASSERT(SideBuffer->Fcb == capFcb);
ASSERT(SideBuffer->smbFobx == smbFobx);
ASSERT(smbFobx->Enumeration.SerialNumber == SideBuffer->SerialNumber);
}
//for NT we are finished. for win95 we have to go thru the side buffer and
// 1) copy in the data transforming ascii->unicode on the names, and
// 2) remember the resume key and the filename of the last guy that we process
// because win95 doesn't 8byte aling things and because of unicode, we could end up
// with more data in the sidebuffer than we can return.
// the code is moved down because we want to do it after the unlock
}
if (DirEntriesAreUaligned && (Status == STATUS_SUCCESS)) {
smbFobx->Enumeration.FilesReturned = FilesReturned;
smbFobx->Enumeration.EntryOffset = 0;
//smbFobx->Enumeration.ReturnedEntryOffset = 0;
smbFobx->Enumeration.EndOfSearchReached = EndOfSearchReached;
//smbFobx->Enumeration.UnalignedDirEntrySideBuffer = UnalignedDirEntrySideBuffer;
Status = MrxSmbUnalignedDirEntryCopyTail(
/*IN OUT PRX_CONTEXT */ RxContext,
/*IN FILE_INFORMATION_CLASS */ FileInformationClass,
/*IN OUT PVOID */ Buffer,
/*IN OUT PULONG */ pLengthRemaining,
/*IN OUT PMRX_SMB_FOBX */ smbFobx
);
}
} else {
// CODE IMPROVEMENT we should cache the file not found for findfirst as well
}
FINALLY:
//for downlevel-T2, we will have to go back to the server for some more.....sigh.......
if (Status==STATUS_MORE_PROCESSING_REQUIRED) {
goto RETRY_____;
}
//
// under stress, the win95 server returns this......
if ( (Status == STATUS_UNEXPECTED_NETWORK_ERROR)
&& FlagOn(pServerEntry->Server.DialectFlags,DF_W95)
&& (RetryCount < 10) ) {
RetryCount++;
MRxSmbWin95Retries++;
goto RETRY_____;
}
if (pFindFirst2Request) RxFreePool(pFindFirst2Request);
if (!NT_SUCCESS(Status)) {
RxDbgTrace( 0, Dbg, ("MRxSmbQueryDirectory: Failed .. returning %lx\n",Status));
//smbFobx->Enumeration.Flags &= ~SMBFOBX_ENUMFLAG_SEARCH_HANDLE_OPEN;
smbFobx->Enumeration.ErrorStatus = Status; //keep returning this
MRxSmbDeallocateSideBuffer(RxContext,smbFobx,"ErrOut");
if (smbFobx->Enumeration.ResumeInfo!=NULL) {
RxFreePool(smbFobx->Enumeration.ResumeInfo);
smbFobx->Enumeration.ResumeInfo = NULL;
}
}
RxDbgTraceUnIndent(-1,Dbg);
return Status;
}
RXDT_DefineCategory(VOLINFO);
#undef Dbg
#define Dbg (DEBUG_TRACE_VOLINFO)
NTSTATUS
MRxSmbQueryVolumeInformationWithFullBuffer(
IN OUT PRX_CONTEXT RxContext
);
NTSTATUS
MRxSmbQueryVolumeInformation(
IN OUT PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine queries the volume information. Since the NT server does not
handle bufferoverflow gracefully on query-fs-info, we allocate a buffer here
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -