这是FileDiskThread的更正:
procedure FileDiskThread(Context: PVOID); stdcall;
var
AIRP : PIRP;
ABuffer : PUCHAR;
ARequest : PLIST_ENTRY;
ASystemBuffer : PUCHAR;
AIOStack : PIO_STACK_LOCATION;
ADeviceObject : PDEVICE_OBJECT;
ADeviceExtension : PDEVICE_EXTENSION;
ADelta : CCHAR;
begin
ASSERT(Context <> nil);
ADeviceObject := Context;
ADeviceExtension := ADeviceObject^.DeviceExtension;
KeSetPriorityThread(KeGetCurrentThread,LOW_REALTIME_PRIORITY);
FileDiskAdjustPrivilege(SE_IMPERSONATE_PRIVILEGE,true);
while true do
begin
KeWaitForSingleObject(
@ADeviceExtension^.request_event,
Executive,
Byte(KernelMode),
FALSE,
nil);
if ADeviceExtension^.terminate_thread then
PsTerminateSystemThread(STATUS_SUCCESS);
ARequest := ExInterlockedRemoveHeadList(@ADeviceExtension^.list_head,
@ADeviceExtension^.list_lock);
while ARequest <> nil do
begin
// #define CONTAINING_RECORD(address, type, field) \
// ((type *)(((ULONG_PTR)address) - (ULONG_PTR)(&(((type *)0)->field))))
// AIRP := CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry);
AIRP := PIRP(ULONG_PTR(ARequest) - ULONG_PTR(@PIRP(0)^.Tail.Overlay.wListEntry));
AIOStack := IoGetCurrentIrpStackLocation(AIRP);
case AIOStack^.MajorFunction of
IRP_MJ_READ:
begin
ASystemBuffer := MmGetSystemAddressForMdlSafe(AIRP^.MdlAddress,NormalPagePriority);
if ASystemBuffer = nil then
begin
AIRP^.IoStatus.Status := STATUS_INSUFFICIENT_RESOURCES;
AIRP^.IoStatus.Information := 0;
end else begin
ABuffer := ExAllocatePool(PagedPool,AIOStack^.Parameters.Read.Length);
if ABuffer = nil then
begin
AIRP^.IoStatus.Status := STATUS_INSUFFICIENT_RESOURCES;
AIRP^.IoStatus.Information := 0;
end else begin
ZwReadFile(ADeviceExtension^.file_handle,
NULL,
nil,
nil,
@AIRP^.IoStatus,
ABuffer,
AIOStack^.Parameters.Read.Length,
@AIOStack^.Parameters.Read.ByteOffset,
nil);
memcpy(ASystemBuffer,ABuffer,AIOStack^.Parameters.Read.Length);
ExFreePool(ABuffer);
end;
end;
end;
IRP_MJ_WRITE:
begin
if (AIOStack^.Parameters.Write.ByteOffset.QuadPart +
AIOStack^.Parameters.Write.Length) >
ADeviceExtension^.file_size.QuadPart then
begin
AIRP^.IoStatus.Status := STATUS_INVALID_PARAMETER;
AIRP^.IoStatus.Information := 0;
end;
ZwWriteFile(ADeviceExtension^.file_handle,
NULL,
nil,
nil,
@AIRP^.IoStatus,
MmGetSystemAddressForMdlSafe(AIRP^.MdlAddress,NormalPagePriority),
AIOStack^.Parameters.Write.Length,
@AIOStack^.Parameters.Write.ByteOffset,
nil);
end;
IRP_MJ_DEVICE_CONTROL:
begin
case AIOStack^.Parameters.DeviceIoControl.IoControlCode of
IOCTL_FILE_DISK_OPEN_FILE:
begin
SeImpersonateClient(ADeviceExtension^.security_client_context,nil);
AIRP^.IoStatus.Status := FileDiskOpenFile(ADeviceObject,AIRP);
PsRevertToSelf;
end;
IOCTL_FILE_DISK_CLOSE_FILE:
begin
AIRP^.IoStatus.Status := FileDiskCloseFile(ADeviceObject,AIRP);
end;
else AIRP^.IoStatus.Status := STATUS_DRIVER_INTERNAL_ERROR;
end;
end;
else AIRP^.IoStatus.Status := STATUS_DRIVER_INTERNAL_ERROR;
end;
if NT_SUCCESS(AIRP^.IoStatus.Status) then
ADelta := CCHAR(IO_DISK_INCREMENT)
else
ADelta := CCHAR(IO_NO_INCREMENT);
IoCompleteRequest(AIRP,ADelta);
ARequest := ExInterlockedRemoveHeadList(@ADeviceExtension^.list_head,
@ADeviceExtension^.list_lock);
end;
end;
end;