本论坛为只读模式,仅供查阅,不能注册新用户,不能发帖/回帖,有问题可发邮件 xikug.xp (^) gmail.com
查看: 10365|回复: 27

私货又来了~驱动还原(人气不错出源码) [复制链接]

Rank: 1

发表于 2010-9-13 19:12:14 |显示全部楼层
悄悄的进村,打枪的不要~~
无需重启动态控制IO穿透还原硬盘分区所有文件,动态还原BIOS、硬盘COMS、网卡外置芯片.适合于驱动调试、程序逆向、享受病毒木马、黄站浏览。是计算机放火、毁灭虚拟机必备宝器!!!!!
有图有真相


声明:
   
      驱动偷人家的,程序偷人家的,大家喜欢随意逆向不过记得挂我名字.偷是一门意思。嘿嘿!!!

     PS:小菜一只,大牛勿扰^_^



                                                                                                                         By  小镇祭祀
//------------------------------------------------------------------------------
// Delphi驱动程序开发:FileDisk的Delphi版 v1.0
// 起源于雪软件安全论坛的“Delphi驱动开发研究”主题,因个人兴趣而改写了VC的
// FileDiak.sys的源程序到Delphi版,目的是证明Windows下的驱动开发并不是VC的专利,
// 其他许多开发工具同样可以做到。只要有创造力,就不再拘泥于使用什么工具,不再
// 受工具的限制。
//------------------------------------------------------------------------------
// Delphi版改写作者:张劲松2008年10月于云南大学
// 欢迎爱好Delphi的同道们一起共同探讨驱动开发的主题
// ynzjs@126.com
//------------------------------------------------------------------------------
// 编译:使用KmdKit**工具包在Delphi命令行下编译,完成后改名为FileDisk.sys
//------------------------------------------------------------------------------

unit FDiskEx;
{$A-,C-,D-,G-,H-,I-,L-,P-,V-,W+,Y-}
// 调试信息输出控制-------------------------------------------------------------
{ $DEFINE DBGDRIVE}
{ $DEFINE DEBUG_PRINT_ENABLED}
{ $DEFINE DEBUG_FILEDISK_THREAD}
{ $DEFINE DEBUG_FILEDISK_DEVICECONTROL}
//------------------------------------------------------------------------------
interface
uses Windows, DDKTypes;

//--- Driver Main function -----------------------------------------------------

function _DriverEntry(DriverObject: PDRIVER_OBJECT;
                      RegistryPath: PUNICODE_STRING): NTSTATUS; stdcall


implementation

//--- Internal string Const ----------------------------------------------------
const
NTHAL                     = 'hal.dll';
NTDLL                     = 'ntdll.dll';
NTKERNEL                  = 'ntoskrnl.exe';

NUMBEROFDEVICES_VALUE :
array[0..16] of WideChar  = ('N','u','m','b','e','r','O','f','D','e','v','i',
                             'c','e','s',#$0,#$0);

PARAMETER_KEY :
array[0..13] of WideChar  = ('\','\','P','a','r','a','m','e','t','e','r','s',
                             #$0,#$0);


DEVICE_BASE_NAME :
array[0..10] of WideChar  = ('\','F','i','l','e','D','i','s','k',#$0,#$0);

DEVICE_DIR_NAME :
array[0..17] of WideChar  = ('\','D','e','v','i','c','e','\','F','i','l','e',
                             'D','i','s','k',#$0,#$0);

DEVICE_NAME_PREFIX :
array[0..26] of WideChar  = ('\','D','e','v','i','c','e','\','F','i','l','e',
                             'D','i','s','k','\','F','i','l','e','D','i','s',
                             'k',#$0,#$0);

DEVICE_NAME_FORMAT_CDROM :
array[0..30] of WideChar  = ('\','D','e','v','i','c','e','\','F','i','l','e',
                             'D','i','s','k','\','F','i','l','e','D','i','s',
                             'k','C','D','%','u',#$0,#$0);

DEVICE_NAME_FORMAT_OTHER :
array[0..28] of WideChar  = ('\','D','e','v','i','c','e','\','F','i','l','e',
                             'D','i','s','k','\','F','i','l','e','D','i','s',
                             'k','%','u',#$0,#$0);

//--- Internal code Const ------------------------------------------------------

NULL                              = 0;
MDL_MAPPED_TO_SYSTEM_VA           = $0001;
MDL_PAGES_LOCKED                  = $0002;
MDL_SOURCE_IS_NONPAGED_POOL       = $0004;
MDL_ALLOCATED_FIXED_SIZE          = $0008;
MDL_PARTIAL                       = $0010;
MDL_PARTIAL_HAS_BEEN_MAPPED       = $0020;
MDL_IO_PAGE_READ                  = $0040;
MDL_WRITE_OPERATION               = $0080;
MDL_PARENT_MAPPED_SYSTEM_VA       = $0100;
MDL_LOCK_HELD                     = $0200;
MDL_PHYSICAL_VIEW                 = $0400;
MDL_IO_SPACE                      = $0800;
MDL_NETWORK_HEADER                = $1000;
MDL_MAPPING_CAN_FAIL              = $2000;
MDL_ALLOCATED_MUST_SUCCEED        = $4000;

RTL_REGISTRY_ABSOLUTE             = 0;
RTL_REGISTRY_SERVICES             = 1;
RTL_REGISTRY_CONTROL              = 2;
RTL_REGISTRY_WINDOWS_NT           = 3;
RTL_REGISTRY_DEVICEMAP            = 4;
RTL_REGISTRY_USER                 = 5;
RTL_REGISTRY_MAXIMUM              = 6;

RTL_REGISTRY_HANDLE               = $40000000;
RTL_REGISTRY_OPTIONAL             = $80000000;
RTL_QUERY_REGISTRY_SUBKEY         = $00000001;
RTL_QUERY_REGISTRY_TOPKEY         = $00000002;
RTL_QUERY_REGISTRY_REQUIRED       = $00000004;
RTL_QUERY_REGISTRY_NOVALUE        = $00000008;
RTL_QUERY_REGISTRY_NOEXPAND       = $00000010;
RTL_QUERY_REGISTRY_DIRECT         = $00000020;
RTL_QUERY_REGISTRY_DELETE         = $00000040;

IRP_MJ_CREATE                     = $00;
IRP_MJ_CREATE_NAMED_PIPE          = $01;
IRP_MJ_CLOSE                      = $02;
IRP_MJ_READ                       = $03;
IRP_MJ_WRITE                      = $04;
IRP_MJ_QUERY_INFORMATION          = $05;
IRP_MJ_SET_INFORMATION            = $06;
IRP_MJ_QUERY_EA                   = $07;
IRP_MJ_SET_EA                     = $08;
IRP_MJ_FLUSH_BUFFERS              = $09;
IRP_MJ_QUERY_VOLUME_INFORMATION   = $0a;
IRP_MJ_SET_VOLUME_INFORMATION     = $0b;
IRP_MJ_DIRECTORY_CONTROL          = $0c;
IRP_MJ_FILE_SYSTEM_CONTROL        = $0d;
IRP_MJ_DEVICE_CONTROL             = $0e;
IRP_MJ_INTERNAL_DEVICE_CONTROL    = $0f;
IRP_MJ_SCSI                       = $0f;
IRP_MJ_SHUTDOWN                   = $10;
IRP_MJ_LOCK_CONTROL               = $11;
IRP_MJ_CLEANUP                    = $12;
IRP_MJ_CREATE_MAILSLOT            = $13;
IRP_MJ_QUERY_SECURITY             = $14;
IRP_MJ_SET_SECURITY               = $15;
IRP_MJ_POWER                      = $16;
IRP_MJ_SYSTEM_CONTROL             = $17;
IRP_MJ_DEVICE_CHANGE              = $18;
IRP_MJ_QUERY_QUOTA                = $19;
IRP_MJ_SET_QUOTA                  = $1a;
IRP_MJ_PNP                        = $1b;
IRP_MJ_PNP_POWER                  = $1b;


FILE_DEVICE_DISK                  = $00000007;
FILE_DEVICE_CD_ROM                = $00000002;

DIRECTORY_ALL_ACCESS              = STANDARD_RIGHTS_REQUIRED or $F;

LOW_PRIORITY                      = 0;
LOW_REALTIME_PRIORITY             = 16;
HIGH_PRIORITY                     = 31;
MAXIMUM_PRIORITY                  = 32;
SE_IMPERSONATE_PRIVILEGE          = 29;

DEFAULT_NUMBEROFDEVICES           = 4;
SECTOR_SIZE                       = 512;
TOC_DATA_TRACK                    = $04;
FILE_DEVICE_FILE_DISK             = $8000;
APC_LEVEL                         = 1;
//--- Internal values ----------------------------------------------------------
var
DirHandle                         : HANDLE;

//--- Import External function -------------------------------------------------
//--- ntoskrnl.exe library ---
function DbgPrint(Format: PChar): Cardinal; cdecl; varargs;
external NTDLL name '_DbgPrint';

function ExAllocatePool(PoolType: POOL_TYPE; NumberOfBytes: SIZE_T): PVOID; stdcall;
external NTKERNEL name '_ExAllocatePool';
procedure ExFreePool(P: PVOID); stdcall;
external NTKERNEL name '_ExFreePool';
procedure RtlCopyUnicodeString(DestinationString: PUNICODE_STRING;
                               SourceString : PCUNICODE_STRING); stdcall;
external NTKERNEL name '_RtlCopyUnicodeString';
function RtlAppendUnicodeToString(Destination: PUNICODE_STRING;
                                  Source: PCWSTR): NTSTATUS; stdcall;
external NTKERNEL name '_RtlAppendUnicodeToString';
function MemSet(S: PVOID; Value,Count: Integer): PVOID; cdecl;
external NTKERNEL name '_memset';
function MemCpy(Dst: PVOID; const Src: PVOID; Count: SIZE_T): PVOID; cdecl;
external NTKERNEL name '_memcpy';
function MemCmp(const S1, S2: PVOID; Count: SIZE_T): integer; cdecl;
external NTKERNEL name '_memcmp';
function RtlQueryRegistryValues(RelativeTo: ULONG;
                                Path: PCWSTR;
                                QueryTable: PRTL_QUERY_REGISTRY_TABLE;
                                Context: PVOID;
                                Environment: PVOID): NTSTATUS; stdcall;
external NTKERNEL name '_RtlQueryRegistryValues';
procedure RtlInitUnicodeString(DestinationString: PUNICODE_STRING;
                               SourceString: PCWSTR); stdcall;
external NTKERNEL name '_RtlInitUnicodeString';
function ZwCreateDirectoryObject(DirectoryHandle: PHANDLE;
                                 DesiredAccess: ACCESS_MASK;
                                 ObjectAttributes: POBJECT_ATTRIBUTES): NTSTATUS; stdcall;
external NTKERNEL name '_ZwCreateDirectoryObject';
function ZwMakeTemporaryObject(AHandle: HANDLE): NTSTATUS; stdcall;
external NTKERNEL name '_ZwMakeTemporaryObject';
function ZwClose(AHandle: HANDLE): NTSTATUS; stdcall;
external NTKERNEL name '_ZwClose';
//function KeSetPriorityThread(Thread: PKTHREAD; Priority: KPRIORITY): KPRIORITY; stdcall;
function KeSetPriorityThread(Thread: Pointer; Priority: KPRIORITY): KPRIORITY; stdcall;
external NTKERNEL name '_KeSetPriorityThread';
function KeGetCurrentThread: Pointer; stdcall; //PRKTHREAD;
external NTKERNEL name '_KeGetCurrentThread';
function ZwOpenProcessToken(ProcessHandle: HANDLE; DesiredAccess: ACCESS_MASK;
                            TokenHandle: PHANDLE): NTSTATUS; stdcall;
external NTKERNEL name '_ZwOpenProcessToken';
function NtAdjustPrivilegesToken(TokenHandle: HANDLE;
                                 DisableAllPrivileges: BOOLEAN;
                                 NewState: PTOKEN_PRIVILEGES;
                                 BufferLength: ULONG;
                                 PreviousState: PTOKEN_PRIVILEGES;
                                 ReturnLength: PULONG): NTSTATUS; stdcall;
external NTKERNEL name '_NtAdjustPrivilegesToken';
function RtlAnsiStringToUnicodeString(DestinationString: PUNICODE_STRING;
                                      SourceString: PANSI_STRING;
                   AllocateDestinationString: BOOLEAN): NTSTATUS; stdcall;
external NTKERNEL name '_RtlAnsiStringToUnicodeString';
function ZwCreateFile(FileHandle: PHANDLE;
                      DesiredAccess: ACCESS_MASK;
                      ObjectAttributes: POBJECT_ATTRIBUTES;
                      IoStatusBlock:PIO_STATUS_BLOCK;
                      AllocationSize:PLARGE_INTEGER;
                      FileAttributes: ULONG;
                      ShareAccess: ULONG;
                      CreateDisposition: ULONG;
                      CreateOptions: ULONG;
                      EaBuffer: PVOID;
                      EaLength: ULONG): NTSTATUS; stdcall;
external NTKERNEL name '_ZwCreateFile';
procedure RtlFreeUnicodeString(UnicodeString: PUNICODE_STRING); stdcall;
external NTKERNEL name '_RtlFreeUnicodeString';
function ZwSetInformationFile(FileHandle: HANDLE;
                              IoStatusBlock: PIO_STATUS_BLOCK;
                              FileInformation: PVOID;
                              Length: ULONG;
             FileInformationClass: FILE_INFORMATION_CLASS): NTSTATUS; stdcall;
external NTKERNEL name '_ZwSetInformationFile';
function ZwQueryInformationFile(FileHandle: HANDLE;
                                IoStatusBlock: PIO_STATUS_BLOCK;
                                FileInformation: PVOID;
                                Length: ULONG;
             FileInformationClass:FILE_INFORMATION_CLASS ): NTSTATUS; stdcall;
external NTKERNEL name '_ZwQueryInformationFile';
function KeWaitForSingleObject(AObject: PVOID;
                               WaitReason: KWAIT_REASON;
                               WaitMode: KPROCESSOR_MODE;
                               Alertable: BOOLEAN;
                               Timeout: PLARGE_INTEGER): NTSTATUS; stdcall;
external NTKERNEL name '_KeWaitForSingleObject';
function PsTerminateSystemThread(ExitStatus: NTSTATUS): NTSTATUS; stdcall;
external NTKERNEL name '_PsTerminateSystemThread';
function ExInterlockedRemoveHeadList(ListHead: PLIST_ENTRY;
                                     Lock: PKSPIN_LOCK): PLIST_ENTRY; stdcall;
external NTKERNEL name '_ExInterlockedRemoveHeadList';
function MmMapLockedPagesSpecifyCache(MemoryDescriptorList: PMDL;
                                      AccessMode: KPROCESSOR_MODE;
                                      CacheType: MEMORY_CACHING_TYPE;
                                      BaseAddress: PVOID;
                                      BugCheckOnFailure: ULONG;
                                      Priority: MM_PAGE_PRIORITY): PVOID; stdcall;
external NTKERNEL name '_MmMapLockedPagesSpecifyCache';
function ZwReadFile(FileHandle: HANDLE;
                    Event: HANDLE;
                    ApcRoutine: PIO_APC_ROUTINE;
                    ApcContext: PVOID;
                    IoStatusBlock: PIO_STATUS_BLOCK;
                    Buffer: PVOID;
                    Length: ULONG;
                    ByteOffset: PLARGE_INTEGER;
                    Key: PULONG): NTSTATUS; stdcall;
external NTKERNEL name '_ZwReadFile';
function ZwWriteFile(FileHandle: HANDLE;
                     Event: HANDLE;
                     ApcRoutine: PIO_APC_ROUTINE;
                     ApcContext: PVOID;
                     IoStatusBlock: PIO_STATUS_BLOCK;
                     Buffer: PVOID;
                     Length: ULONG;
                     ByteOffset: PLARGE_INTEGER;
                     Key: PULONG): NTSTATUS; stdcall;
external NTKERNEL name '_ZwWriteFile';
procedure SeImpersonateClient(ClientContext: PSECURITY_CLIENT_CONTEXT;
                              ServerThread: PETHREAD); stdcall;
external NTKERNEL name '_SeImpersonateClient';
procedure PsRevertToSelf; stdcall;
external NTKERNEL name '_PsRevertToSelf';
procedure IoCompleteRequest(AIrp: PIRP; PriorityBoost: CCHAR); stdcall;
external NTKERNEL name '_IoCompleteRequest';
function KeSetEvent(Event: PRKEVENT; Increment: KPRIORITY;
                    Wait: BOOLEAN): LONG; stdcall;
external NTKERNEL name '_KeSetEvent';
function SeTokenType(Token: PACCESS_TOKEN): TOKEN_TYPE; stdcall;
external NTKERNEL name '_SeTokenType';
procedure IoDeleteDevice(DeviceObject: PDEVICE_OBJECT); stdcall;
external NTKERNEL name '_IoDeleteDevice';
function kswprintf(Buffer: PWideChar; const format: PWideChar): Integer; cdecl; varargs;
external NTKERNEL name '_swprintf';
function IoCreateDevice(DriverObject: PDRIVER_OBJECT;
                        DeviceExtensionSize: ULONG;
                        DeviceName: PUNICODE_STRING;
                        DeviceType: DEVICE_TYPE;
                        DeviceCharacteristics: ULONG;
                        Exclusive: BOOLEAN;
                        DeviceObject: PPDEVICE_OBJECT): NTSTATUS; stdcall;
external NTKERNEL name '_IoCreateDevice';
procedure KeInitializeSpinLock(SpinLock: PKSPIN_LOCK); stdcall;
external NTKERNEL name '_KeInitializeSpinLock';
procedure KeInitializeEvent(Event: PRKEVENT; AType: EVENT_TYPE;
                            State: BOOLEAN); stdcall;
external NTKERNEL name '_KeInitializeEvent';
function PsCreateSystemThread(ThreadHandle: PHANDLE;
                              DesiredAccess: ULONG;
                              ObjectAttributes: POBJECT_ATTRIBUTES;
                              ProcessHandle: HANDLE;
                              ClientId: PCLIENT_ID;
                              StartRoutine: PKSTART_ROUTINE;
                              StartContext: PVOID): NTSTATUS; stdcall;
external NTKERNEL name '_PsCreateSystemThread';
function ObReferenceObjectByHandle(Handle: HANDLE;
                                   DesiredAccess: ACCESS_MASK;
                                   ObjectType: PVOID; // ObjectType: POBJECT_TYPE;
                                   AccessMode: KPROCESSOR_MODE;
                                   AObject: PPVOID;
    HandleInformation: POBJECT_HANDLE_INFORMATION): NTSTATUS; stdcall;
external NTKERNEL name '_ObReferenceObjectByHandle';
function ExInterlockedInsertTailList(ListHead: PLIST_ENTRY;
                                     ListEntry: PLIST_ENTRY;
                                     Lock: PKSPIN_LOCK): PLIST_ENTRY; stdcall;
external NTKERNEL name '_ExInterlockedInsertTailList';
function SeCreateClientSecurity(AThread: PETHREAD;
                                QualityOfService: PSECURITY_QUALITY_OF_SERVICE;
                                RemoteClient: BOOLEAN;
                 ClientContext: PSECURITY_CLIENT_CONTEXT): NTSTATUS; stdcall;
external NTKERNEL name '_SeCreateClientSecurity';

//--- hal.dll library ---
function KeGetCurrentIrql : KIRQL; stdcall;
external NTHAL name '_KeGetCurrentIrql';
function HalMakeBeep(Frequency: ULONG): BOOLEAN; stdcall;
external NTHAL name '_HalMakeBeep';
function READ_PORT_UCHAR(Port: PUCHAR): UCHAR; stdcall;
external NTHAL name '_READ_PORT_UCHAR';
procedure WRITE_PORT_UCHAR(Port: PUCHAR; Value: UCHAR); stdcall;
external NTHAL name '_WRITE_PORT_UCHAR';
function KfAcquireSpinLock(SpinLock: PKSPIN_LOCK): KIRQL; register;
external NTHAL name '_KfAcquireSpinLock';
procedure KfReleaseSpinLock(SpinLock: PKSPIN_LOCK; NewIrql: KIRQL); register;
external NTHAL name '_KfReleaseSpinLock';
function KeAcquireSpinLockRaiseToSynch(SpinLock: PKSPIN_LOCK): KIRQL; register;
external NTHAL name '_KeAcquireSpinLockRaiseToSynch';
//
//关于fastcall调用,内核APIs有一部分是fastcall调用约定的,Delphi也支持fastcall
//调用约定,就是register call,但是register call和microsoft的fastcall是有区别
//的,microsoft的fastcall使用两个寄存器ECX和EDX保存前两个参数,其余的按从右到
//左的顺序压栈传送;而register call使用三个寄存器EAX、EDX、ECX传送头三个参数,
//其余按从左到右的顺序压栈传送。所以对使用fastcall调用约定的APIs也必须用delphi
//做个包装函数,举例如下:
procedure krnlObfDereferenceObject(_Object: PVOID); register;
external NTKERNEL name '_ObfDereferenceObject';

procedure ObfDereferenceObject(_Object: PVOID); assembler;
asm
mov  ecx, _Object
call krnlObfDereferenceObject
end;

//--- ntdll.dll library ---

function swprintf(Buffer: PWideChar; const format: PWideChar): Integer; cdecl; varargs;
external NTDLL name '_swprintf';

//--- Internal function and procedure ------------------------------------------

procedure KdPrint(const Info: string); stdcall;
begin
DbgPrint(@Info[1]);
end;

procedure KdPrintEx(const Info: string; var Code: Byte); stdcall; overload;
begin
DbgPrint(@Info[1],Byte(Code));
end;

procedure KdPrintEx(const Info: string; var Code: WORD); stdcall; overload;
begin
DbgPrint(@Info[1],WORD(Code));
end;

procedure KdPrintEx(const Info: string; var Code: DWORD); stdcall; overload;
begin
DbgPrint(@Info[1],DWORD(Code));
end;

procedure KdPrintEx(const Info: string; var Code: Longint); stdcall; overload;
begin
DbgPrint(@Info[1],Longint(Code));
end;

//Sample : KdPrintEx('FileSize = %I64d' + #$0,QuadPart);
procedure KdPrintEx(const Info: string; var Code: Int64); stdcall; overload;
begin
//DbgPrint(@Info[1],LARGE_INTEGER(Code).LowPart,LARGE_INTEGER(Code).HighPart);
DbgPrint(@Info[1],LARGE_INTEGER(Code));
end;

//Sample : KdPrintEx('FileName : %s' + #$0,@AFileName[1])
procedure KdPrintEx(const Info: string; Str: Pointer); stdcall; overload;
begin
DbgPrint(@Info[1],Pointer(Str));
end;

//Sample : KdPrintEx('FileName : %s' + #$0,'sssss');
procedure KdPrintEx(const Info,Str: string); stdcall; overload;
begin
DbgPrint(@Info[1],@Str[1]);
end;

procedure RtlZeroMemory(Destination: PVOID; Length: SIZE_T); stdcall;
begin
MemSet(Destination,0,Length)
end;

function NT_SUCCESS(Status: NTSTATUS): BOOLEAN; stdcall;
begin
Result := Status >= 0
end;

procedure PAGED_CODE; stdcall;
{$IFDEF DBGDRIVE}
var
AIrql : KIRQL;
{$ENDIF}
begin
{$IFDEF DBGDRIVE}
if KeGetCurrentIrql > APC_LEVEL then
begin
  AIrql := KeGetCurrentIrql;
  KdPrintEx('NTDDK: Pageable code called at IRQL > APC_LEVEL (%d)' + #$0,AIrql);
  ASSERT(FALSE);
end;
{$ENDIF}
end;

procedure InitializeObjectAttributes(p: POBJECT_ATTRIBUTES;
                                     n: PUNICODE_STRING;
                                     a: LONG;
                                     r: HANDLE;
                                     s: PVOID); stdcall;
begin
with p^ do
begin
  Length := SizeOf(OBJECT_ATTRIBUTES);
  RootDirectory := r;
  Attributes := a;
  ObjectName := n;
  SecurityDescriptor := s;
  SecurityQualityOfService := nil;
end;
end;

function NtCurrentProcess: HANDLE; stdcall;
begin
LONG_PTR(Result) := -1;
end;

function RtlConvertUlongToLuid(AUlong: ULONG): LUID; stdcall;
var
TempLuid : LUID;
begin
TempLuid.LowPart := AUlong;
TempLuid.HighPart := 0;
Result := TempLuid;
end;

function IoGetCurrentIrpStackLocation(AIrp: PIRP): PIO_STACK_LOCATION;
begin
Result := AIrp^.Tail.Overlay.UNION02.CurrentStackLocation;
end;

function MmGetSystemAddressForMdlSafe(AMdl: PMDL; APriority: MM_PAGE_PRIORITY): PVOID;
begin
  if (AMdl^.MdlFlags and
     (MDL_MAPPED_TO_SYSTEM_VA or MDL_SOURCE_IS_NONPAGED_POOL)) <> 0 then
   Result := AMdl^.MappedSystemVa
  else
   Result := PVOID(MmMapLockedPagesSpecifyCache(AMdl,
                                                KPROCESSOR_MODE(KernelMode),
                                                MmCached,
                                                nil,
                                                ULONG(FALSE),
                                                APriority));
end;

procedure PsDereferencePrimaryToken(T: PACCESS_TOKEN);
begin
ObfDereferenceObject(T)
end;

function ARGUMENT_PRESENT(ArgumentPointer: Pointer): Boolean;
begin
Result := PCHAR(ULONG_PTR(ArgumentPointer)) <> nil;
end;

procedure PsDereferenceImpersonationToken(T: PACCESS_TOKEN);
begin
if ARGUMENT_PRESENT(T) then ObfDereferenceObject(T);
end;

procedure SeDeleteClientSecurity(C: PSECURITY_CLIENT_CONTEXT);
begin
if SeTokenType(C^.ClientToken) = TokenPrimary then
  PsDereferencePrimaryToken(C^.ClientToken)
else
  PsDereferenceImpersonationToken(C^.ClientToken);
end;

procedure InitializeListHead(ListHead: PLIST_ENTRY);
begin
ListHead^.Flink := ListHead^.Blink;
ListHead^.Blink := ListHead;
end;

procedure IoMarkIrpPending(AIrp : PIRP);
var
cc : UCHAR;
begin
cc := IoGetCurrentIrpStackLocation(AIrp)^.Control or SL_PENDING_RETURNED;
IoGetCurrentIrpStackLocation(AIrp)^.Control := cc;
end;

function PsGetCurrentThread: PETHREAD;
begin
Result := PETHREAD(KeGetCurrentThread);
end;

//Delphi 对Int64类型执行div时调用了内部函数,这样就不能在MS的Link中进行链接:
// error LNK2001: unresolved external symbol aa_lldivsqqrv
//因此这里使用自定义的Int64的div和Mul函数:
function _Int64Div(var X, Y : Int64) : Int64;
asm
  push    ebx
  push    esi
  push    edi
  mov     ebx, [edx]
  mov     ecx, [edx + 4]      //ECX:EBX = Y
  mov     edx, [eax + 4]
  mov     eax, [eax]        //EDX:EAX = X
  mov     esi, edx
  mov     edi, ecx
  sar     esi, 31
  xor     eax, esi
  xor     edx, esi
  sub     eax, esi
  sbb     edx, esi          // EDX:EAX := abs(X)
  sar     edi, 31
  xor     esi, edi          // 0 if X and Y have same sign
  xor     ebx, edi
  xor     ecx, edi
  sub     ebx, edi
  sbb     ecx, edi          // ECX:EBX := abs(Y)
  jnz     @@BigDivisor      // divisor > 32^32-1
  cmp     edx, ebx          // only one division needed ? (ecx = 0)
  jb      @@OneDiv          // yes, one division sufficient
  mov     ecx, eax          // save dividend-lo in ecx
  mov     eax, edx          // get dividend-hi
  xor     edx, edx          // zero extend it into edx:eax
  div     ebx               // quotient-hi in eax
  xchg    eax, ecx          // ecx = quotient-hi, eax =dividend-lo
@@OneDiv:
  div     ebx               // eax = quotient-lo
  mov     edx, ecx          // edx = quotient-hi(quotient in edx:eax)
  jmp     @SetSign
@@BigDivisor:
  cmp     edx, ecx
  jae     @BigDiv
@Zero:
  xor     eax, eax
  xor     edx, edx
  jmp     @Done
@BigDiv:
  sub     esp, 12           // Create three local variables.
  mov     [esp  ], eax      // dividend_lo
  mov     [esp + 4], ebx    // divisor_lo
  mov     [esp + 8], edx    // dividend_hi
  mov     edi, ecx          //  edi:ebx and ecx:esi
  shr     edx, 1            // shift both
  rcr     eax, 1            //  divisor and
  ror     edi, 1            //   and dividend
  rcr     ebx, 1            //    right by 1 bit
  bsr     ecx, ecx          // ecx = number of remaining shifts
  shrd    ebx, edi, cl      // scale down divisor and
  shrd    eax, edx, cl      //   dividend such that divisor
  shr     edx, cl           //    less than 2^32 (i.e. fits in ebx)
  rol     edi, 1            // restore original divisor (edi:esi)
  div     ebx               // compute quotient
  mov     ebx, [esp]        // dividend_lo
  mov     ecx, eax          // save quotient
  imul    edi, eax          // quotient * divisor hi-word (low only)
  mul     DWORD PTR [esp + 4] // quotient * divisor low word
  add     edx, edi          // edx:eax = quotient * divisor
  sub     ebx, eax          // dividend-lo - (quot.*divisor)-lo
  mov     eax, ecx          // get quotient
  mov     ecx, [esp + 8]      // dividend_hi
  sbb     ecx, edx          // subtract divisor * quot. from dividend
  sbb     eax, 0            // Adjust quotient if remainder is negative.
  xor     edx, edx          // clear hi-word of quot (eax<=FFFFFFFFh)
  add     esp, 12           // Remove local variables.
@SetSign:
  xor     eax, esi          // If (quotient < 0),
  xor     edx, esi          //   compute 1's complement of result.
  sub     eax, esi          // If (quotient < 0),
  sbb     edx, esi          //   compute 2's complement of result.
@Done:
  pop     edi
  pop     esi
  pop     ebx
end;

function _Int64Mul(var X, Y : Int64) : Int64;
asm  // 36 Bytes
  push  ebx
  push  edi
  lea   ebx, [eax]      //@X
  lea   edi, [edx]      //@Y
  mov   edx, [ebx + 4]  //X-Hi
  mov   ecx, [edi + 4]  //Y-Hi
  or    edx, ecx        //Both 0?
  mov   eax, [ebx]      //X-Lo
  jz    @@LowMul
  mov   edx, [edi]      //Y-Lo
  imul  ecx, eax        //Y-Hi * X-Lo
  imul  edx, [ebx + 4]  //Y-Lo * X-Hi
  add   ecx, edx
@@LowMul:
  mul   dword ptr [edi]
  add   edx, ecx
  pop   edi
  pop   ebx
end;

//### Drive Function ###########################################################

function FileDiskAdjustPrivilege(Privilege: ULONG; Enable: BOOLEAN): NTSTATUS; stdcall;
var
AStatus : NTSTATUS;
ATokenHandle : HANDLE;
ATokenPrivileges : DDKTypes.TOKEN_PRIVILEGES;
begin
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskAdjustPrivilege Start ...' + #$0);
PAGED_CODE();
{$ENDIF}
AStatus := ZwOpenProcessToken(NtCurrentProcess,
                               TOKEN_ALL_ACCESS,
                               @ATokenHandle);

if not NT_SUCCESS(AStatus) then
begin
  Result := AStatus;
  Exit;
end;

ATokenPrivileges.PrivilegeCount := 1;
ATokenPrivileges.Privileges[0].ALuid := RtlConvertUlongToLuid(Privilege);
if Enable then
  ATokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
  ATokenPrivileges.Privileges[0].Attributes := 0;

// Normaly one would use ZwAdjustPrivilegesToken but it is only available
// on Windows 2000 and later versions, however since we are in a system
// thread does ExGetPreviousMode always return KernelMode and therefore
// can NtAdjustPrivilegesToken be used directly.

AStatus := NtAdjustPrivilegesToken(ATokenHandle,
                                    FALSE,
                                    @ATokenPrivileges,
                                    SizeOf(ATokenPrivileges),
                                    nil,
                                    nil);

ZwClose(ATokenHandle);
Result := AStatus;
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskAdjustPrivilege OK ...' + #$0);
{$ENDIF}
end;

function FileDiskCloseFile (DeviceObject: PDEVICE_OBJECT; IRP_P: PIRP): NTSTATUS; stdcall; // update
var
ADeviceExtension : PDEVICE_EXTENSION;
begin
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskCloseFile Start ...' + #$0);
PAGED_CODE;
{$ENDIF}
ASSERT(DeviceObject <> nil);
ASSERT(IRP_P <> nil);
ADeviceExtension := DeviceObject^.DeviceExtension;
ExFreePool(ADeviceExtension^.file_name.Buffer);
ZwClose(ADeviceExtension^.file_handle);
ADeviceExtension^.media_in_device := false;
IRP_P^.IoStatus.Status := STATUS_SUCCESS;
IRP_P^.IoStatus.Information := 0;
Result := STATUS_SUCCESS;
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskCloseFile OK ...' + #$0);
{$ENDIF}
end;

function FileDiskOpenFile(DeviceObject: PDEVICE_OBJECT; IRP_P: PIRP): NTSTATUS; stdcall; // update
var
AStatus : NTSTATUS;
AFileEof : FILE_END_OF_FILE_INFORMATION;
AUFileName : UNICODE_STRING;
AFileBasic : FILE_BASIC_INFORMATION;
AFileStandard : FILE_STANDARD_INFORMATION ;
AFileAlignment : FILE_ALIGNMENT_INFORMATION;
ADeviceExtension : PDEVICE_EXTENSION;
AObjectAttributes : OBJECT_ATTRIBUTES;
AOpenFileInformation : POPEN_FILE_INFORMATION;
AAccessMask : ACCESS_MASK;
AShareAccess : ULONG;
ACreateOptions: ULONG;
begin
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskOpenFile Start ...' + #$0);
PAGED_CODE;
{$ENDIF}
ASSERT(DeviceObject <> nil);
ASSERT(IRP_P <> nil);

ADeviceExtension := PDEVICE_EXTENSION(DeviceObject^.DeviceExtension);
AOpenFileInformation := POPEN_FILE_INFORMATION(IRP_P^.AssociatedIrp.SystemBuffer);

if DeviceObject^.DeviceType <> FILE_DEVICE_CD_ROM then
  ADeviceExtension^.read_only := AOpenFileInformation^.ReadOnly;


ADeviceExtension^.file_name.Length := AOpenFileInformation^.FileNameLength;
ADeviceExtension^.file_name.MaximumLength := AOpenFileInformation^.FileNameLength;
ADeviceExtension^.file_name.Buffer :=
  ExAllocatePool(NonPagedPool,AOpenFileInformation^.FileNameLength + 2);

RtlZeroMemory(ADeviceExtension^.file_name.Buffer,
               AOpenFileInformation^.FileNameLength + 2);

memcpy(ADeviceExtension^.file_name.Buffer,
        @AOpenFileInformation^.FileName,
        AOpenFileInformation^.FileNameLength);

ADeviceExtension^.file_size.QuadPart := AOpenFileInformation^.FileSize.QuadPart;


{$IFDEF DEBUG_PRINT_ENABLED}
KdPrintEx('FileSize = %I64d' + #$0,ADeviceExtension^.file_size.QuadPart);
KdPrintEx('FileNameLength = %d' + #$0,ADeviceExtension^.file_name.Length);
KdPrintEx('FileName = %s' + #$0,ADeviceExtension^.file_name.Buffer);
{$ENDIF}

AStatus := RtlAnsiStringToUnicodeString(@AUFileName,
                                         @ADeviceExtension^.file_name,
                                         true);
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrintEx('UnicodeFileName = %ls' + #$0,Pointer(AUFileName.Buffer));
{$ENDIF}

if not NT_SUCCESS(AStatus) then
begin
  ExFreePool(ADeviceExtension^.file_name.Buffer);
  IRP_P^.IoStatus.Status := AStatus;
  IRP_P^.IoStatus.Information := 0;
  Result := AStatus;
  Exit;
end;

InitializeObjectAttributes(@AObjectAttributes,
                            @AUFileName,
                            OBJ_CASE_INSENSITIVE,
                            NULL,
                            nil);

if ADeviceExtension^.read_only then
begin
  AAccessMask := GENERIC_READ;
  AShareAccess := FILE_SHARE_READ;
end else begin
  AAccessMask := GENERIC_READ or GENERIC_WRITE;
  AShareAccess := 0;
end;

ACreateOptions := FILE_NON_DIRECTORY_FILE or
                   FILE_RANDOM_ACCESS or
                   FILE_NO_INTERMEDIATE_BUFFERING or
                   FILE_SYNCHRONOUS_IO_NONALERT;

AStatus := ZwCreateFile(@ADeviceExtension^.file_handle,
                         AAccessMask,
                         @AObjectAttributes,
                         @IRP_P^.IoStatus,
                         nil,
                         FILE_ATTRIBUTE_NORMAL,
                         AShareAccess,
                         FILE_OPEN,
                         ACreateOptions,
                         nil,
                         0);

if (AStatus = STATUS_OBJECT_NAME_NOT_FOUND) or
    (AStatus = STATUS_NO_SUCH_FILE) then
begin
{$IFDEF DEBUG_PRINT_ENABLED}
  KdPrint('STATUS_OBJECT_NAME_NOT_FOUND or AStatus = STATUS_NO_SUCH_FILE');
{$ENDIF}
  if ADeviceExtension^.read_only or
     (AOpenFileInformation^.FileSize.QuadPart = 0) then
  begin
   ExFreePool(ADeviceExtension^.file_name.Buffer);
   RtlFreeUnicodeString(@AUFileName);

   IRP_P^.IoStatus.Status := STATUS_NO_SUCH_FILE;
   IRP_P^.IoStatus.Information := 0;

   Result := STATUS_NO_SUCH_FILE;
   Exit;
  end else begin
   ACreateOptions := FILE_NON_DIRECTORY_FILE or
                     FILE_RANDOM_ACCESS or
                     FILE_NO_INTERMEDIATE_BUFFERING or
                     FILE_SYNCHRONOUS_IO_NONALERT;


   AStatus := ZwCreateFile(@ADeviceExtension^.file_handle,
                           GENERIC_READ or GENERIC_WRITE,
                           @AObjectAttributes,
                           @IRP_P^.IoStatus,
                           @AOpenFileInformation^.FileSize,
                           FILE_ATTRIBUTE_NORMAL,
                           0,
                           FILE_OPEN_IF,
                           ACreateOptions,
                           nil,
                           0);

   if not NT_SUCCESS(AStatus) then
   begin
    ExFreePool(ADeviceExtension^.file_name.Buffer);
    RtlFreeUnicodeString(@AUFileName);
    Result := AStatus;
    Exit;
   end;

   if IRP_P^.IoStatus.Information = FILE_CREATED then
   begin
    AFileEof.EndOfFile.QuadPart := AOpenFileInformation^.FileSize.QuadPart;
    AStatus := ZwSetInformationFile(ADeviceExtension^.file_handle,
                                    @IRP_P^.IoStatus,
                                    @AFileEof,
                                    sizeof(FILE_END_OF_FILE_INFORMATION),
                                    FileEndOfFileInformation);

    if not NT_SUCCESS(AStatus) then
    begin
     ExFreePool(ADeviceExtension^.file_name.Buffer);
     RtlFreeUnicodeString(@AUFileName);
     ZwClose(ADeviceExtension^.file_handle);
     Result := AStatus;
     Exit;
    end;
   end;
  end;
end else
if not NT_SUCCESS(AStatus) then
begin
  ExFreePool(ADeviceExtension^.file_name.Buffer);
  RtlFreeUnicodeString(@AUFileName);
  Result := AStatus;
  Exit;
end;

RtlFreeUnicodeString(@AUFileName);

AStatus := ZwQueryInformationFile(ADeviceExtension^.file_handle,
                                   @IRP_P^.IoStatus,
                                   @AFileBasic,
                                   sizeof(FILE_BASIC_INFORMATION),
                                   FileBasicInformation);

if not NT_SUCCESS(AStatus) then
begin
  ExFreePool(ADeviceExtension^.file_name.Buffer);
  ZwClose(ADeviceExtension^.file_handle);
  Result := AStatus;
  Exit;
end;

// 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 (AFileBasic.FileAttributes and
//   (FILE_ATTRIBUTE_COMPRESSED or FILE_ATTRIBUTE_ENCRYPTED)) <> 0 then
//begin
// ExFreePool(ADeviceExtension^.file_name.Buffer);
// ZwClose(ADeviceExtension^.file_handle);
// IRP_P^.IoStatus.Status := STATUS_ACCESS_DENIED;
// IRP_P^.IoStatus.Information := 0;
// Result := STATUS_ACCESS_DENIED;
// Exit;
//end;

AStatus := ZwQueryInformationFile(ADeviceExtension^.file_handle,
                                   @IRP_P^.IoStatus,
                                   @AFileStandard,
                                   sizeof(FILE_STANDARD_INFORMATION),
                                   FileStandardInformation);

if not NT_SUCCESS(AStatus) then
begin
  ExFreePool(ADeviceExtension^.file_name.Buffer);
  ZwClose(ADeviceExtension^.file_handle);
  Result := AStatus;
  Exit;
end;

ADeviceExtension^.file_size.QuadPart := AFileStandard.EndOfFile.QuadPart;

{$IFDEF DEBUG_PRINT_ENABLED}
KdPrintEx('QueryFileSize = %I64d' + #$0,ADeviceExtension^.file_size.QuadPart);
{$ENDIF}

AStatus := ZwQueryInformationFile(ADeviceExtension^.file_handle,
                                   @IRP_P^.IoStatus,
                                   @AFileAlignment,
                                   sizeof(FILE_ALIGNMENT_INFORMATION),
                                   FileAlignmentInformation);

if not NT_SUCCESS(AStatus) then
begin
  ExFreePool(ADeviceExtension^.file_name.Buffer);
  ZwClose(ADeviceExtension^.file_handle);
  Result := AStatus;
  Exit;
end;

DeviceObject^.AlignmentRequirement := AFileAlignment.AlignmentRequirement;

if ADeviceExtension^.read_only then
  DeviceObject^.Characteristics := DeviceObject^.Characteristics or
                                   FILE_READ_ONLY_DEVICE
else
  DeviceObject^.Characteristics := DeviceObject^.Characteristics and
                                   (not FILE_READ_ONLY_DEVICE);

ADeviceExtension^.media_in_device := true;

IRP_P^.IoStatus.Status := STATUS_SUCCESS;
IRP_P^.IoStatus.Information := 0;
Result := STATUS_SUCCESS;
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskOpenFile OK ...' + #$0);
{$ENDIF}
end;

procedure FileDiskThread(Context: PVOID); stdcall;
label BreakDone;
var
AIRP : PIRP;
ABuffer : PUCHAR;
ASystemBuffer : PUCHAR;
ARequest : PLIST_ENTRY;
AIOStack : PIO_STACK_LOCATION;
ADeviceObject : PDEVICE_OBJECT;
ADeviceExtension : PDEVICE_EXTENSION;
begin
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskThread Start ...' + #$0);
{$ENDIF}
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
   AIRP := PIRP(ULONG_PTR(ARequest) - ULONG_PTR(@PIRP(0)^.Tail.Overlay.wListEntry));
   AIOStack := IoGetCurrentIrpStackLocation(AIRP);

   case AIOStack^.MajorFunction of
    IRP_MJ_READ:
     begin
{$IFDEF DEBUG_FILEDISK_THREAD}
      KdPrint('THREAD-IRP_MJ_READ IN ...' + #$0);
{$ENDIF}
      ASystemBuffer := MmGetSystemAddressForMdlSafe(AIRP^.MdlAddress,NormalPagePriority);
      if ASystemBuffer = nil then
      begin
       AIRP^.IoStatus.Status := STATUS_INSUFFICIENT_RESOURCES;
       AIRP^.IoStatus.Information := 0;
       goto BreakDone;
      end;

      ABuffer := ExAllocatePool(PagedPool,AIOStack^.Parameters.Read.Length);
      if ABuffer = nil then
      begin
       AIRP^.IoStatus.Status := STATUS_INSUFFICIENT_RESOURCES;
       AIRP^.IoStatus.Information := 0;
       goto BreakDone;
      end;

      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);
{$IFDEF DEBUG_FILEDISK_THREAD}
      KdPrint('THREAD-IRP_MJ_READ OK ...' + #$0);
{$ENDIF}
     end;

    IRP_MJ_WRITE:
     begin
{$IFDEF DEBUG_FILEDISK_THREAD}
      KdPrint('THREAD-IRP_MJ_WRITE IN ...' + #$0);
{$ENDIF}
      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);
{$IFDEF DEBUG_FILEDISK_THREAD}
      KdPrint('THREAD-IRP_MJ_WRITE OK ...' + #$0);
{$ENDIF}
     end;

    IRP_MJ_DEVICE_CONTROL:
     begin
{$IFDEF DEBUG_FILEDISK_THREAD}
      KdPrint('THREAD-IRP_MJ_DEVICE_CONTROL IN ...' + #$0);
{$ENDIF}

      case AIOStack^.Parameters.DeviceIoControl.IoControlCode of
       IOCTL_FILE_DISK_OPEN_FILE:
        begin
{$IFDEF DEBUG_FILEDISK_THREAD}
         KdPrint('THREAD-IOCTL_FILE_DISK_OPEN_FILE IN ...' + #$0);
{$ENDIF}
         SeImpersonateClient(ADeviceExtension^.security_client_context,nil);
         AIRP^.IoStatus.Status := FileDiskOpenFile(ADeviceObject,AIRP);
         PsRevertToSelf;
{$IFDEF DEBUG_FILEDISK_THREAD}
         KdPrint('THREAD-IOCTL_FILE_DISK_OPEN_FILE OK ...' + #$0);
{$ENDIF}
        end;

       IOCTL_FILE_DISK_CLOSE_FILE:
        begin
{$IFDEF DEBUG_FILEDISK_THREAD}
         KdPrint('THREAD-IOCTL_FILE_DISK_CLOSE_FILE IN ...' + #$0);
{$ENDIF}
         AIRP^.IoStatus.Status := FileDiskCloseFile(ADeviceObject,AIRP);
{$IFDEF DEBUG_FILEDISK_THREAD}
         KdPrint('THREAD-IOCTL_FILE_DISK_CLOSE_FILE OK ...' + #$0);
{$ENDIF}
        end;
       else AIRP^.IoStatus.Status := STATUS_DRIVER_INTERNAL_ERROR;
      end;

{$IFDEF DEBUG_FILEDISK_THREAD}
      KdPrint('THREAD-IRP_MJ_DEVICE_CONTROL OK ...' + #$0);
{$ENDIF}
     end;

    else AIRP^.IoStatus.Status := STATUS_DRIVER_INTERNAL_ERROR;
   end;
   BreakDone:

   if NT_SUCCESS(AIRP^.IoStatus.Status) then
    IoCompleteRequest(AIRP,IO_DISK_INCREMENT)
   else
    IoCompleteRequest(AIRP,IO_NO_INCREMENT);

   ARequest := ExInterlockedRemoveHeadList(@ADeviceExtension^.list_head,
                                           @ADeviceExtension^.list_lock);
  end;
end;
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskThread OK ...' + #$0);
{$ENDIF}
end;

function FileDiskCreateDevice(DriverObject: PDRIVER_OBJECT;
                              Number: ULONG;
                              DeviceType: DEVICE_TYPE): NTSTATUS; stdcall; // update
var
AStatus : NTSTATUS;
AThreadHandle : HANDLE;
ADeviceName : UNICODE_STRING;
ADeviceObject : PDEVICE_OBJECT;
ADeviceExtension : PDEVICE_EXTENSION;
ADeviceNameBuffer : array[0..MAXIMUM_FILENAME_LENGTH - 1] of WCHAR;
begin
{$IFDEF DEBUG_PRINT_ENABLED}
KdPrint('FileDiskCreateDevice Start ...' + #$0);
{$ENDIF}
ASSERT(DriverObject <> nil);
if DeviceType = FILE_DEVICE_CD_ROM then
begin
  kswprintf(ADeviceNameBuffer,
            @DEVICE_NAME_FORMAT_CDROM[0],
            Number);

end else begin
  kswprintf(ADeviceNameBuffer,
            @DEVICE_NAME_FORMAT_OTHER[0],
            Number);
end;

RtlInitUnicodeString(@ADeviceName,@ADeviceNameBuffer);

AStatus := IoCreateDevice(DriverObje
图片.jpg

硬盘还原工具.rar

507 KB, 下载次数: 1004

Rank: 2

发表于 2010-9-13 19:44:03 |显示全部楼层
还原代码在哪里?

Rank: 2

发表于 2010-9-13 19:49:43 |显示全部楼层
HOOK用多了伤身体...

Rank: 9Rank: 9Rank: 9

发表于 2010-9-13 20:26:24 |显示全部楼层
我还以为有源码。。。
悟空,退下,为师一个人就够了

Rank: 1

发表于 2010-9-13 22:56:35 |显示全部楼层
支持开源,呵呵

Rank: 1

发表于 2010-9-13 23:58:46 |显示全部楼层
dephi驱动,,有人敢用啊。。

Rank: 1

发表于 2010-9-14 00:47:44 |显示全部楼层
无码的

Rank: 2

发表于 2010-9-14 01:29:31 |显示全部楼层
私货来了~

Rank: 2

发表于 2010-9-15 12:53:31 |显示全部楼层
不错不错,而且有码的

Rank: 1

发表于 2010-9-16 11:26:27 |显示全部楼层
支持开源

Rank: 1

发表于 2010-9-16 12:29:48 |显示全部楼层
改后,VC源代码啦??

Rank: 9Rank: 9Rank: 9

发表于 2010-9-16 12:34:28 |显示全部楼层
又被忽悠进来了。。。你这源码不是还原啊。。。
悟空,退下,为师一个人就够了

Rank: 1

发表于 2010-9-17 13:26:13 |显示全部楼层
看起来只能路过了

Rank: 2

发表于 2010-9-27 18:08:17 |显示全部楼层
可惜不是vc的 不懂dephi~~

Rank: 2

发表于 2010-9-27 18:08:48 |显示全部楼层
被忽悠来了~~晕~

Rank: 1

发表于 2010-9-28 17:04:39 |显示全部楼层
“快速还原”表示压力很大!

Rank: 2

发表于 2010-10-18 13:08:12 |显示全部楼层
看看

Rank: 1

发表于 2010-10-22 23:02:50 |显示全部楼层
不错,收藏了!!

Rank: 1

发表于 2010-10-23 02:30:59 |显示全部楼层
最近正在学,看看代码

Rank: 1

发表于 2010-10-26 11:57:02 |显示全部楼层
这个真强大。
您需要登录后才可以回帖 登录 | 立即加入

Archiver|手机版|第8个男人 - 论坛为只读模式,仅供查阅

GMT+8, 2019-6-19 05:50 , Processed in 0.044491 second(s), 11 queries .

Design by pvo.cn

© 2011 Pvo Inc.

回顶部