mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 16:03:00 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
524
drivers/filesystems/ntfs/dirctl.c
Normal file
524
drivers/filesystems/ntfs/dirctl.c
Normal file
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002, 2003, 2014 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/filesystem/ntfs/dirctl.c
|
||||
* PURPOSE: NTFS filesystem driver
|
||||
* PROGRAMMERS: Eric Kohl
|
||||
* Pierre Schweitzer (pierre@reactos.org)
|
||||
* Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "ntfs.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
||||
ULONGLONG
|
||||
NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_RECORD_HEADER FileRecord,
|
||||
PCWSTR Stream,
|
||||
ULONG StreamLength,
|
||||
PULONGLONG AllocatedSize)
|
||||
{
|
||||
ULONGLONG Size = 0ULL;
|
||||
ULONGLONG Allocated = 0ULL;
|
||||
NTSTATUS Status;
|
||||
PNTFS_ATTR_CONTEXT DataContext;
|
||||
|
||||
Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Stream, StreamLength, &DataContext);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Size = AttributeDataLength(&DataContext->Record);
|
||||
Allocated = AttributeAllocatedLength(&DataContext->Record);
|
||||
ReleaseAttributeContext(DataContext);
|
||||
}
|
||||
|
||||
if (AllocatedSize != NULL) *AllocatedSize = Allocated;
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NtfsGetNameInformation(PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_RECORD_HEADER FileRecord,
|
||||
ULONGLONG MFTIndex,
|
||||
PFILE_NAMES_INFORMATION Info,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
ULONG Length;
|
||||
PFILENAME_ATTRIBUTE FileName;
|
||||
|
||||
DPRINT("NtfsGetNameInformation() called\n");
|
||||
|
||||
FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
|
||||
if (FileName == NULL)
|
||||
{
|
||||
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
|
||||
NtfsDumpFileAttributes(DeviceExt, FileRecord);
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
Length = FileName->NameLength * sizeof (WCHAR);
|
||||
if ((sizeof(FILE_NAMES_INFORMATION) + Length) > BufferLength)
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
Info->FileNameLength = Length;
|
||||
Info->NextEntryOffset =
|
||||
ROUND_UP(sizeof(FILE_NAMES_INFORMATION) + Length, sizeof(ULONG));
|
||||
RtlCopyMemory(Info->FileName, FileName->Name, Length);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NtfsGetDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_RECORD_HEADER FileRecord,
|
||||
ULONGLONG MFTIndex,
|
||||
PFILE_DIRECTORY_INFORMATION Info,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
ULONG Length;
|
||||
PFILENAME_ATTRIBUTE FileName;
|
||||
PSTANDARD_INFORMATION StdInfo;
|
||||
|
||||
DPRINT("NtfsGetDirectoryInformation() called\n");
|
||||
|
||||
FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
|
||||
if (FileName == NULL)
|
||||
{
|
||||
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
|
||||
NtfsDumpFileAttributes(DeviceExt, FileRecord);
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
|
||||
ASSERT(StdInfo != NULL);
|
||||
|
||||
Length = FileName->NameLength * sizeof (WCHAR);
|
||||
if ((sizeof(FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
Info->FileNameLength = Length;
|
||||
Info->NextEntryOffset =
|
||||
ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION) + Length, sizeof(ULONG));
|
||||
RtlCopyMemory(Info->FileName, FileName->Name, Length);
|
||||
|
||||
Info->CreationTime.QuadPart = FileName->CreationTime;
|
||||
Info->LastAccessTime.QuadPart = FileName->LastAccessTime;
|
||||
Info->LastWriteTime.QuadPart = FileName->LastWriteTime;
|
||||
Info->ChangeTime.QuadPart = FileName->ChangeTime;
|
||||
|
||||
/* Convert file flags */
|
||||
NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
|
||||
|
||||
Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
|
||||
|
||||
Info->FileIndex = MFTIndex;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NtfsGetFullDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_RECORD_HEADER FileRecord,
|
||||
ULONGLONG MFTIndex,
|
||||
PFILE_FULL_DIRECTORY_INFORMATION Info,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
ULONG Length;
|
||||
PFILENAME_ATTRIBUTE FileName;
|
||||
PSTANDARD_INFORMATION StdInfo;
|
||||
|
||||
DPRINT("NtfsGetFullDirectoryInformation() called\n");
|
||||
|
||||
FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
|
||||
if (FileName == NULL)
|
||||
{
|
||||
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
|
||||
NtfsDumpFileAttributes(DeviceExt, FileRecord);
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
|
||||
ASSERT(StdInfo != NULL);
|
||||
|
||||
Length = FileName->NameLength * sizeof (WCHAR);
|
||||
if ((sizeof(FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
Info->FileNameLength = Length;
|
||||
Info->NextEntryOffset =
|
||||
ROUND_UP(sizeof(FILE_FULL_DIRECTORY_INFORMATION) + Length, sizeof(ULONG));
|
||||
RtlCopyMemory(Info->FileName, FileName->Name, Length);
|
||||
|
||||
Info->CreationTime.QuadPart = FileName->CreationTime;
|
||||
Info->LastAccessTime.QuadPart = FileName->LastAccessTime;
|
||||
Info->LastWriteTime.QuadPart = FileName->LastWriteTime;
|
||||
Info->ChangeTime.QuadPart = FileName->ChangeTime;
|
||||
|
||||
/* Convert file flags */
|
||||
NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
|
||||
|
||||
Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
|
||||
|
||||
Info->FileIndex = MFTIndex;
|
||||
Info->EaSize = 0;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NtfsGetBothDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_RECORD_HEADER FileRecord,
|
||||
ULONGLONG MFTIndex,
|
||||
PFILE_BOTH_DIR_INFORMATION Info,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
ULONG Length;
|
||||
PFILENAME_ATTRIBUTE FileName, ShortFileName;
|
||||
PSTANDARD_INFORMATION StdInfo;
|
||||
|
||||
DPRINT("NtfsGetBothDirectoryInformation() called\n");
|
||||
|
||||
FileName = GetBestFileNameFromRecord(DeviceExt, FileRecord);
|
||||
if (FileName == NULL)
|
||||
{
|
||||
DPRINT1("No name information for file ID: %#I64x\n", MFTIndex);
|
||||
NtfsDumpFileAttributes(DeviceExt, FileRecord);
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
ShortFileName = GetFileNameFromRecord(DeviceExt, FileRecord, NTFS_FILE_NAME_DOS);
|
||||
|
||||
StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
|
||||
ASSERT(StdInfo != NULL);
|
||||
|
||||
Length = FileName->NameLength * sizeof (WCHAR);
|
||||
if ((sizeof(FILE_BOTH_DIR_INFORMATION) + Length) > BufferLength)
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
Info->FileNameLength = Length;
|
||||
Info->NextEntryOffset =
|
||||
ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, sizeof(ULONG));
|
||||
RtlCopyMemory(Info->FileName, FileName->Name, Length);
|
||||
|
||||
if (ShortFileName)
|
||||
{
|
||||
/* Should we upcase the filename? */
|
||||
ASSERT(ShortFileName->NameLength <= ARRAYSIZE(Info->ShortName));
|
||||
Info->ShortNameLength = ShortFileName->NameLength * sizeof(WCHAR);
|
||||
RtlCopyMemory(Info->ShortName, ShortFileName->Name, Info->ShortNameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info->ShortName[0] = 0;
|
||||
Info->ShortNameLength = 0;
|
||||
}
|
||||
|
||||
Info->CreationTime.QuadPart = FileName->CreationTime;
|
||||
Info->LastAccessTime.QuadPart = FileName->LastAccessTime;
|
||||
Info->LastWriteTime.QuadPart = FileName->LastWriteTime;
|
||||
Info->ChangeTime.QuadPart = FileName->ChangeTime;
|
||||
|
||||
/* Convert file flags */
|
||||
NtfsFileFlagsToAttributes(FileName->FileAttributes | StdInfo->FileAttribute, &Info->FileAttributes);
|
||||
|
||||
Info->EndOfFile.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, (PULONGLONG)&Info->AllocationSize.QuadPart);
|
||||
|
||||
Info->FileIndex = MFTIndex;
|
||||
Info->EaSize = 0;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PIRP Irp;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
LONG BufferLength = 0;
|
||||
PUNICODE_STRING SearchPattern = NULL;
|
||||
FILE_INFORMATION_CLASS FileInformationClass;
|
||||
ULONG FileIndex = 0;
|
||||
PUCHAR Buffer = NULL;
|
||||
PFILE_NAMES_INFORMATION Buffer0 = NULL;
|
||||
PNTFS_FCB Fcb;
|
||||
PNTFS_CCB Ccb;
|
||||
BOOLEAN First = FALSE;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PFILE_OBJECT FileObject;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PFILE_RECORD_HEADER FileRecord;
|
||||
ULONGLONG MFTRecord, OldMFTRecord = 0;
|
||||
UNICODE_STRING Pattern;
|
||||
|
||||
DPRINT1("NtfsQueryDirectory() called\n");
|
||||
|
||||
ASSERT(IrpContext);
|
||||
Irp = IrpContext->Irp;
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = Stack->FileObject;
|
||||
|
||||
Ccb = (PNTFS_CCB)FileObject->FsContext2;
|
||||
Fcb = (PNTFS_FCB)FileObject->FsContext;
|
||||
|
||||
/* Obtain the callers parameters */
|
||||
BufferLength = Stack->Parameters.QueryDirectory.Length;
|
||||
SearchPattern = Stack->Parameters.QueryDirectory.FileName;
|
||||
FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
|
||||
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
|
||||
|
||||
if (NtfsFCBIsCompressed(Fcb))
|
||||
{
|
||||
DPRINT1("Compressed directory!\n");
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!ExAcquireResourceSharedLite(&Fcb->MainResource,
|
||||
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
|
||||
{
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
if (SearchPattern != NULL)
|
||||
{
|
||||
if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
First = TRUE;
|
||||
Pattern.Length = 0;
|
||||
Pattern.MaximumLength = SearchPattern->Length + sizeof(WCHAR);
|
||||
Ccb->DirectorySearchPattern = Pattern.Buffer =
|
||||
ExAllocatePoolWithTag(NonPagedPool, Pattern.MaximumLength, TAG_NTFS);
|
||||
if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
ExReleaseResourceLite(&Fcb->MainResource);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
memcpy(Ccb->DirectorySearchPattern, SearchPattern->Buffer, SearchPattern->Length);
|
||||
Ccb->DirectorySearchPattern[SearchPattern->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
}
|
||||
else if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
First = TRUE;
|
||||
Ccb->DirectorySearchPattern = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), TAG_NTFS);
|
||||
if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
ExReleaseResourceLite(&Fcb->MainResource);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Ccb->DirectorySearchPattern[0] = L'*';
|
||||
Ccb->DirectorySearchPattern[1] = 0;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&Pattern, Ccb->DirectorySearchPattern);
|
||||
DPRINT("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
|
||||
DPRINT("In: '%S'\n", Fcb->PathName);
|
||||
|
||||
/* Determine directory index */
|
||||
if (Stack->Flags & SL_INDEX_SPECIFIED)
|
||||
{
|
||||
Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
|
||||
}
|
||||
else if (First || (Stack->Flags & SL_RESTART_SCAN))
|
||||
{
|
||||
Ccb->Entry = 0;
|
||||
}
|
||||
|
||||
/* Get Buffer for result */
|
||||
Buffer = NtfsGetUserBuffer(Irp, FALSE);
|
||||
|
||||
DPRINT("Buffer=%p tofind=%S\n", Buffer, Ccb->DirectorySearchPattern);
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(&DeviceExtension->DirResource,
|
||||
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
|
||||
{
|
||||
ExReleaseResourceLite(&Fcb->MainResource);
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
while (Status == STATUS_SUCCESS && BufferLength > 0)
|
||||
{
|
||||
Status = NtfsFindFileAt(DeviceExtension,
|
||||
&Pattern,
|
||||
&Ccb->Entry,
|
||||
&FileRecord,
|
||||
&MFTRecord,
|
||||
Fcb->MFTIndex);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* HACK: files with both a short name and a long name are present twice in the index.
|
||||
* Ignore the second entry, if it is immediately following the first one.
|
||||
*/
|
||||
if (MFTRecord == OldMFTRecord)
|
||||
{
|
||||
DPRINT1("Ignoring duplicate MFT entry 0x%x\n", MFTRecord);
|
||||
Ccb->Entry++;
|
||||
ExFreePoolWithTag(FileRecord, TAG_NTFS);
|
||||
continue;
|
||||
}
|
||||
OldMFTRecord = MFTRecord;
|
||||
|
||||
switch (FileInformationClass)
|
||||
{
|
||||
case FileNameInformation:
|
||||
Status = NtfsGetNameInformation(DeviceExtension,
|
||||
FileRecord,
|
||||
MFTRecord,
|
||||
(PFILE_NAMES_INFORMATION)Buffer,
|
||||
BufferLength);
|
||||
break;
|
||||
|
||||
case FileDirectoryInformation:
|
||||
Status = NtfsGetDirectoryInformation(DeviceExtension,
|
||||
FileRecord,
|
||||
MFTRecord,
|
||||
(PFILE_DIRECTORY_INFORMATION)Buffer,
|
||||
BufferLength);
|
||||
break;
|
||||
|
||||
case FileFullDirectoryInformation:
|
||||
Status = NtfsGetFullDirectoryInformation(DeviceExtension,
|
||||
FileRecord,
|
||||
MFTRecord,
|
||||
(PFILE_FULL_DIRECTORY_INFORMATION)Buffer,
|
||||
BufferLength);
|
||||
break;
|
||||
|
||||
case FileBothDirectoryInformation:
|
||||
Status = NtfsGetBothDirectoryInformation(DeviceExtension,
|
||||
FileRecord,
|
||||
MFTRecord,
|
||||
(PFILE_BOTH_DIR_INFORMATION)Buffer,
|
||||
BufferLength);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_INFO_CLASS;
|
||||
}
|
||||
|
||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
if (Buffer0)
|
||||
{
|
||||
Buffer0->NextEntryOffset = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Buffer0)
|
||||
{
|
||||
Buffer0->NextEntryOffset = 0;
|
||||
}
|
||||
|
||||
if (First)
|
||||
{
|
||||
Status = STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_NO_MORE_FILES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Buffer0 = (PFILE_NAMES_INFORMATION)Buffer;
|
||||
Buffer0->FileIndex = FileIndex++;
|
||||
Ccb->Entry++;
|
||||
|
||||
if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
BufferLength -= Buffer0->NextEntryOffset;
|
||||
Buffer += Buffer0->NextEntryOffset;
|
||||
ExFreePoolWithTag(FileRecord, TAG_NTFS);
|
||||
}
|
||||
|
||||
if (Buffer0)
|
||||
{
|
||||
Buffer0->NextEntryOffset = 0;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&DeviceExtension->DirResource);
|
||||
ExReleaseResourceLite(&Fcb->MainResource);
|
||||
|
||||
if (FileIndex > 0)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NtfsDirectoryControl(PNTFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
DPRINT1("NtfsDirectoryControl() called\n");
|
||||
|
||||
switch (IrpContext->MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_DIRECTORY:
|
||||
Status = NtfsQueryDirectory(IrpContext);
|
||||
break;
|
||||
|
||||
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
|
||||
DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status == STATUS_PENDING && IrpContext->Flags & IRPCONTEXT_COMPLETE)
|
||||
{
|
||||
return NtfsMarkIrpContextForQueue(IrpContext);
|
||||
}
|
||||
|
||||
IrpContext->Irp->IoStatus.Information = 0;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue