?? filediskopenfile.c
字號:
#include <ntddk.h>
#include "ntifs.h"
NTSTATUS
FileDiskOpenFile (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
POPEN_FILE_INFORMATION open_file_information;
UNICODE_STRING ufile_name;
NTSTATUS status;
OBJECT_ATTRIBUTES object_attributes;
FILE_END_OF_FILE_INFORMATION file_eof;
FILE_BASIC_INFORMATION file_basic;
FILE_STANDARD_INFORMATION file_standard;
FILE_ALIGNMENT_INFORMATION file_alignment;
PAGED_CODE();
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
open_file_information = (POPEN_FILE_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
if (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
//FILE_DEVICE_CD_ROM在ntddk.h中定義為0x00000002
{
device_extension->read_only = open_file_information->ReadOnly;
}
device_extension->file_name.Length = open_file_information->FileNameLength;
device_extension->file_name.MaximumLength = open_file_information->FileNameLength;
device_extension->file_name.Buffer = ExAllocatePool(NonPagedPool, open_file_information->FileNameLength);
RtlCopyMemory(
device_extension->file_name.Buffer,
open_file_information->FileName,
open_file_information->FileNameLength
);
status = RtlAnsiStringToUnicodeString(
&ufile_name,
&device_extension->file_name,
TRUE
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
return status;
}
InitializeObjectAttributes(
&object_attributes,
&ufile_name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
//OBJ_CASE_INSENSITIVE在ntdef.h中定義為0x00000040L
status = ZwCreateFile(
&device_extension->file_handle,
device_extension->read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
&object_attributes,
&Irp->IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
device_extension->read_only ? FILE_SHARE_READ : 0,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE |
FILE_RANDOM_ACCESS |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
//GENERIC_READ在ntddk.h中定義為0x80000000L
//GENERIC_WRITE在ntddk.h中定義為0x40000000L
//FILE_ATTRIBUTE_NORMAL在ntddk.h中定義為0x00000080
//FILE_OPEN在ntddk.h中定義為0x00000001
//FILE_NON_DIRECTORY_FILE在ntddk.h中定義為0x00000040
//FILE_RANDOM_ACCESS在ntddk.h中定義為0x00000800
//FILE_NO_INTERMEDIATE_BUFFERING在ntddk.h中定義為0x00000008
//FILE_SYNCHRONOUS_IO_NONALERT在ntddk.h中定義為0x00000020
if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_NO_SUCH_FILE)
//STATUS_OBJECT_NAME_NOT_FOUND在ntstatus.h中定義為((NTSTATUS)0xC0000034L)
//STATUS_NO_SUCH_FILE在ntstatus.h中定義為((NTSTATUS)0xC000000FL)
{
if (device_extension->read_only || open_file_information->FileSize.QuadPart == 0)
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
Irp->IoStatus.Status = STATUS_NO_SUCH_FILE;
Irp->IoStatus.Information = 0;
return STATUS_NO_SUCH_FILE;
}
else
{
status = ZwCreateFile(
&device_extension->file_handle,
GENERIC_READ | GENERIC_WRITE,
&object_attributes,
&Irp->IoStatus,
&open_file_information->FileSize,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE |
FILE_RANDOM_ACCESS |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
//FILE_OPEN_IF在ntddk.h中定義為0x00000003
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
return status;
}
if (Irp->IoStatus.Information == FILE_CREATED)
{
file_eof.EndOfFile.QuadPart = open_file_information->FileSize.QuadPart;
status = ZwSetInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_eof,
sizeof(FILE_END_OF_FILE_INFORMATION),
FileEndOfFileInformation
);
//FILE_END_OF_FILE_INFORMATION結構參見ntddk.h
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
ZwClose(device_extension->file_handle);
return status;
}
}
}
}
else if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
return status;
}
RtlFreeUnicodeString(&ufile_name);
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_basic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation
);
//FILE_STANDARD_INFORMATION結構參見ntddk.h
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
return status;
}
//
// The NT cache manager can deadlock if a filesystem that is using the cache
// manager is used in a virtual disk that stores its file on a filesystem
// that is also using the cache manager, this is why we open the file with
// FILE_NO_INTERMEDIATE_BUFFERING above, however if the file is compressed
// or encrypted NT will not honor this request and cache it anyway since it
// need to store the decompressed/unencrypted data somewhere, therefor we put
// an extra check here and don't alow disk images to be compressed/encrypted.
//
if (file_basic.FileAttributes & (FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_ENCRYPTED))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
return STATUS_ACCESS_DENIED;
}
//FILE_ATTRIBUTE_COMPRESSED在ntddk.h中定義為0x00000800
//FILE_ATTRIBUTE_ENCRYPTED在ntddk.h中定義為0x00004000
//STATUS_ACCESS_DENIED在ntstatus.h中定義為((NTSTATUS)0xC0000022L)
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_standard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
return status;
}
device_extension->file_size.QuadPart = file_standard.EndOfFile.QuadPart;
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_alignment,
sizeof(FILE_ALIGNMENT_INFORMATION),
FileAlignmentInformation
);
//FILE_ALIGNMENT_INFORMATION結構參見ntddk.h
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
return status;
}
DeviceObject->AlignmentRequirement = file_alignment.AlignmentRequirement;
if (device_extension->read_only)
{
DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
//FILE_READ_ONLY_DEVICE在ntddk.h中定義為0x00000002
}
else
{
DeviceObject->Characteristics &= ~FILE_READ_ONLY_DEVICE;
}
device_extension->media_in_device = TRUE;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -