首页
社区
课程
招聘
[原创]Delphi驱动开发研究第九篇--文件与目录
发表于: 2009-12-8 10:56 11341

[原创]Delphi驱动开发研究第九篇--文件与目录

2009-12-8 10:56
11341

提供对文件的读写功能是操作系统的一项重要任务。我们来看一下NT家族的操作系统都为我们提供了那些功能。
9.1 核心句柄表
在开始讨论本文的主题之前,我们先来讨论一个重要的问题,我们之前并未对其给予应有的注意。为了取得对象的句柄需要填充OBJECT_ATTRIBUTES结构体——我们已经做过很多遍了,其样子如下:

InitializeObjectAttributes(oa, @g_usName,OBJ_CASE_INSENSITIVE,0, nil); 
unit FileWorks;

interface

uses
  nt_status, ntoskrnl, ntifs, native, winioctl, fcall, macros;

function _DriverEntry(pDriverObject:PDRIVER_OBJECT;
                      pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;

implementation

var
  g_usDirName: UNICODE_STRING;
  g_usFileName: UNICODE_STRING;

procedure CreateDirectory;
var
  oa: OBJECT_ATTRIBUTES;
  iosb: IO_STATUS_BLOCK;
  hDirectory: THANDLE;
  RtnCode: NTSTATUS;
begin
  { 还记得吧, 传递给DbgPrint函数的用于格式化Unicode的代码(%C, %S, %lc, %ls, %wc, %ws, %wZ)只能在
    IRQL = PASSIVE_LEVEL下调用! }
  DbgPrint(#13#10'FileWorks: Creating %ws directory'#13#10, g_usDirName.Buffer);

  InitializeObjectAttributes(oa, @g_usDirName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwCreateFile(@hDirectory, SYNCHRONIZE, @oa, @iosb, nil,
                          FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF,
                          FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT,
                          nil, 0);
  if RtnCode = STATUS_SUCCESS then
  begin
    if iosb.Information = FILE_CREATED then
    begin
      DbgPrint('FileWorks: Directory created'#13#10);
    end else if iosb.Information = FILE_OPENED then
    begin
      DbgPrint('FileWorks: Directory exists and was opened'#13#10);
    end;
    ZwClose(hDirectory);
  end else
  begin
    DbgPrint('FileWorks: Can''t create directory. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure CreateFile;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THANDLE;
  RtnCode: NTSTATUS;
begin
  DbgPrint(#13#10'FileWorks: Creating %ws file'#13#10, g_usFileName.Buffer);
  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);

  RtnCode := ZwCreateFile(@hFile, SYNCHRONIZE, @oa, @iosb, nil,
                          FILE_ATTRIBUTE_NORMAL, 0,
                          FILE_CREATE,
                          FILE_SYNCHRONOUS_IO_NONALERT, nil, 0);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File created'#13#10);
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t create file. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure WriteFile;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THANDLE;
  RtnCode: NTSTATUS;
  g_szData: PAnsiChar;
begin
  DbgPrint(#13#10'FileWorks: Opening file for writing'#13#10);

  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwCreateFile(@hFile, FILE_WRITE_DATA + SYNCHRONIZE,
                          @oa, @iosb, nil, 0, FILE_SHARE_READ,
                          FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
                          nil, 0);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File openeded'#13#10);
    g_szData := 'Data can be written to an open file';
    //RtlInitUnicodeString(g_szData, 'Data can be written to an open file');
    RtnCode := ZwWriteFile(hFile, 0, nil, nil, @iosb, g_szData,
                           strlen(g_szData), nil, nil);
    if RtnCode = STATUS_SUCCESS then
    begin
      DbgPrint('FileWorks: File was written'#13#10);
    end else
    begin
      DbgPrint('FileWorks: Can''t write to the file. Status: %08X\n', RtnCode);
    end;
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure MarkAsReadOnly;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THandle;
  fbi:FILE_BASIC_INFORMATION;
  RtnCode:NTSTATUS;
begin
  DbgPrint(#13#10'FileWorks: Opening file for changing attributes'#13#10);
  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwCreateFile(@hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE,
                          @oa, @iosb, nil, 0, FILE_SHARE_READ,
                          FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
                          nil, 0);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File openeded'#13#10);
    RtnCode := ZwQueryInformationFile(hFile, @iosb, @fbi,
                                      sizeof(fbi),
                                      FileBasicInformation);
    if RtnCode = STATUS_SUCCESS then
    begin
      DbgPrint('FileWorks: File attributes were: %08X'#13#10, fbi.FileAttributes);
      fbi.FileAttributes := fbi.FileAttributes or FILE_ATTRIBUTE_READONLY;
      RtnCode := ZwSetInformationFile(hFile, @iosb, @fbi,
                                      sizeof(fbi), FileBasicInformation);
      if RtnCode = STATUS_SUCCESS then
      begin
        DbgPrint('FileWorks: Now file marked as read-only'#13#10);
      end else
      begin
        DbgPrint('FileWorks: Can''t change file attributes. Status: %08X'#13#10, RtnCode);
      end;
    end else
    begin
      DbgPrint('FileWorks: Can''t query file attributes. Status: %08X'#13#10, RtnCode);
    end;
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t open file. Status: %08X\n', RtnCode);
  end;
end;

procedure ReadFile;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THANDLE;
  p:PVOID;
  cb:DWORD;
  fsi:FILE_STANDARD_INFORMATION;
  RtnCode: NTSTATUS;
begin
  DbgPrint(#13#10'FileWorks: Opening file for reading'#13#10);
  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwOpenFile(@hFile, FILE_READ_DATA + SYNCHRONIZE,
                        @oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
                        FILE_SYNCHRONOUS_IO_NONALERT);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File openeded'#13#10);
    RtnCode := ZwQueryInformationFile(hFile, @iosb, @fsi,
                                      sizeof(fsi),
                                      FileStandardInformation);
    if RtnCode = STATUS_SUCCESS then
    begin
      cb := fsi.EndOfFile.LowPart + 1;
      p := ExAllocatePool(PagedPool, cb);
      if p <> nil then
      begin
        memset(p, 0, cb);
        RtnCode := ZwReadFile(hFile, 0, nil, nil, @iosb, p, cb, nil, nil);
        if RtnCode = STATUS_SUCCESS then
        begin
          DbgPrint('FileWorks: File content: \=%s\='#13#10, p);
        end else
        begin
          DbgPrint('FileWorks: Can''t read from the file. Status: %08X'#13#10, RtnCode);
        end;
        ExFreePool(p);
      end else
      begin
        DbgPrint('FileWorks: Can''t allocate memory. Status: %08X'#13#10, RtnCode);
      end;
    end else
    begin
      DbgPrint('FileWorks: Can''t query file size. Status: %08X'#13#10, RtnCode);
    end;
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure UnmarkAsReadOnly;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THANDLE;
  fbi:FILE_BASIC_INFORMATION;
  RtnCode:NTSTATUS;
begin
  DbgPrint(#13#10'FileWorks: Opening file for changing attributes'#13#10);
  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwCreateFile(@hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE,
                          @oa, @iosb, nil, 0, FILE_SHARE_READ,
                          FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
                          nil, 0);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File openeded'#13#10);
    RtnCode := ZwQueryInformationFile(hFile, @iosb, @fbi,
                                      sizeof(fbi), FileBasicInformation);
    if RtnCode = STATUS_SUCCESS then
    begin
      DbgPrint('FileWorks: File attributes were: %08X'#13#10, fbi.FileAttributes);
      fbi.FileAttributes := fbi.FileAttributes and (not FILE_ATTRIBUTE_READONLY);
      RtnCode := ZwSetInformationFile(hFile, @iosb, @fbi, sizeof(fbi), FileBasicInformation);
      if RtnCode = STATUS_SUCCESS then
      begin
        DbgPrint('FileWorks: Now file can be written or deleted'#13#10);
      end else
      begin
        DbgPrint('FileWorks: Can''t change file attributes. Status: %08X'#13#10, RtnCode);
      end;
    end else
    begin
      DbgPrint('FileWorks: Can''t query file attributes. Status: %08X'#13#10, RtnCode);
    end;
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure AppendFile;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THANDLE;
  g_szDataToAppend:PAnsiChar;
  RtnCode:NTSTATUS;
begin
  DbgPrint(#13#10'FileWorks: Opening file to append data'#13#10);
  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwOpenFile(@hFile, FILE_APPEND_DATA + SYNCHRONIZE,
                        @oa, @iosb, FILE_SHARE_READ,
                        FILE_SYNCHRONOUS_IO_NONALERT);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File openeded'#13#10);
    g_szDataToAppend := ' using ZwWriteFile';
    RtnCode := ZwWriteFile(hFile, 0, nil, nil, @iosb, g_szDataToAppend,
                           strlen(g_szDataToAppend), nil, nil);
    if RtnCode = STATUS_SUCCESS then
    begin
      DbgPrint('FileWorks: Data appended to the file'#13#10);
    end else
    begin
      DbgPrint('FileWorks: Can''t append data to file. Status: %08X'#13#10, RtnCode);
    end;
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure TruncateFile;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THANDLE;
  fsi:FILE_STANDARD_INFORMATION;
  feofi:FILE_END_OF_FILE_INFORMATION;
  RtnCode:NTSTATUS;
begin
  DbgPrint(#13#10'FileWorks: Opening file to truncate'#13#10);
  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwOpenFile(@hFile, FILE_WRITE_DATA + SYNCHRONIZE,
                        @oa, @iosb, FILE_SHARE_READ,
                        FILE_SYNCHRONOUS_IO_NONALERT);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File openeded'#13#10);
    RtnCode := ZwQueryInformationFile(hFile, @iosb, @fsi,
                                      sizeof(fsi),
                                      FileStandardInformation);
    if RtnCode = STATUS_SUCCESS then
    begin
      DbgPrint('FileWorks: EOF was: %08X'#13#10, fsi.EndOfFile.LowPart);
      feofi.EndOfFile.HighPart := 0;
      feofi.EndOfFile.LowPart := (fsi.EndOfFile.LowPart) shr 1;
      RtnCode := ZwSetInformationFile(hFile, @iosb, @feofi,
                                      sizeof(feofi),
                                      FileEndOfFileInformation);
      if RtnCode = STATUS_SUCCESS then
      begin
        DbgPrint('FileWorks: File truncated to its half size'#13#10);
      end else
      begin
        DbgPrint('FileWorks: Can''t truncate file. Status: %08X'#13#10, RtnCode);
      end;
    end else
    begin
      DbgPrint('FileWorks: Can''t query file info. Status: %08X'#13#10, RtnCode);
    end;
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure DeleteFile;
var
  oa:OBJECT_ATTRIBUTES;
  iosb:IO_STATUS_BLOCK;
  hFile:THANDLE;
  fdi:FILE_DISPOSITION_INFORMATION;
  RtnCode:NTSTATUS;
begin
  DbgPrint(#13#10'FileWorks: Opening file for deletion'#13#10);
  InitializeObjectAttributes(oa, @g_usFileName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwCreateFile(@hFile, _DELETE + SYNCHRONIZE,
                          @oa, @iosb, nil, 0, FILE_SHARE_DELETE,
                          FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
                          nil, 0);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint('FileWorks: File openeded'#13#10);
    fdi.DeleteFile := True;
    RtnCode := ZwSetInformationFile(hFile, @iosb, @fdi,
                                    sizeof(fdi),
                                    FileDispositionInformation);
    if RtnCode = STATUS_SUCCESS then
    begin
      DbgPrint('FileWorks: File has been marked for deletion'#13#10);
      DbgPrint('FileWorks: It should be deleted when the last open handle is closed'#13#10);
    end else
    begin
      DbgPrint('FileWorks: Can''t mark file for deletion. Status: %08X'#13#10, RtnCode);
    end;
    ZwClose(hFile);
  end else
  begin
    DbgPrint('FileWorks: Can''t open file. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure DeleteDirectory;
var
  oa:OBJECT_ATTRIBUTES;
  RtnCode:NTSTATUS;
begin
  InitializeObjectAttributes(oa, @g_usDirName,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwDeleteFile(@oa);
  if RtnCode = STATUS_SUCCESS then
  begin
    DbgPrint(#13#10'FileWorks: Directory should be deleted'#13#10);
  end else
  begin
    DbgPrint(#13#10'FileWorks: Can''t delete directory. Status: %08X'#13#10, RtnCode);
  end;
end;

procedure EnumerateFiles;
var
  oa:OBJECT_ATTRIBUTES;
  hSystemRootDirectory:THANDLE;
  hDriversDirectory:THANDLE;
  _as:ANSI_STRING;
  us:UNICODE_STRING;
  iosb:IO_STATUS_BLOCK;
  tf:TIME_FIELDS;
  cb:DWORD;
  pfdi:PFILE_DIRECTORY_INFORMATION;
  RtnCode:NTSTATUS;
  g_usTemp:UNICODE_STRING;
begin
  DbgPrint(#13#10'FileWorks: Opening directory to enumerate files'#13#10);
  RtlInitUnicodeString(g_usTemp, '\SystemRoot');
  InitializeObjectAttributes(oa, @g_usTemp,
                             OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                             0, nil);
  RtnCode := ZwOpenFile(@hSystemRootDirectory, FILE_LIST_DIRECTORY + SYNCHRONIZE,
                        @oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
                        FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT);
  if RtnCode = STATUS_SUCCESS then
  begin
    RtlInitUnicodeString(g_usTemp, 'system32\drivers');
    InitializeObjectAttributes(oa, @g_usTemp,
                               OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,
                               hSystemRootDirectory, nil);
    RtnCode := ZwOpenFile(@hDriversDirectory, FILE_LIST_DIRECTORY + SYNCHRONIZE,
                          @oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
                          FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT);
    if RtnCode = STATUS_SUCCESS then
    begin
      cb := sizeof(FILE_DIRECTORY_INFORMATION) + 256;
      pfdi := ExAllocatePool(PagedPool, cb);
      if pfdi <> nil then
      begin
        RtlInitUnicodeString(g_usTemp, 'c*');
        DbgPrint(#13#10'FileWorks: ---------- Starting enumerate files ----------'#13#10);
        RtnCode := ZwQueryDirectoryFile(hDriversDirectory, 0, nil, nil, @iosb,
                                        pfdi, cb, FileDirectoryInformation,
                                        true, @g_usTemp, true);
        while RtnCode <> STATUS_NO_MORE_FILES do
        begin
          if RtnCode = STATUS_SUCCESS then
          begin
            us.Length := pfdi^.FileNameLength;
            us.MaximumLength := pfdi^.FileNameLength;
            us.Buffer := PWideChar(@pfdi^.FileName);
            if RtlUnicodeStringToAnsiString(@_as, @us, true) = STATUS_SUCCESS then
            begin
              RtlTimeToTimeFields(@pfdi^.CreationTime, @tf);
              DbgPrint(' %s size=%d created on %d.%02d.%04d'#13#10,
                       _as.Buffer, pfdi^.EndOfFile.LowPart,
                       BYTE(tf.Day), BYTE(tf.Month), WORD(tf.Year));
              RtlFreeAnsiString(@_as);
            end;
          end;
          RtnCode := ZwQueryDirectoryFile(hDriversDirectory, 0, nil, nil, @iosb,
                                          pfdi, cb, FileDirectoryInformation,
                                          true, nil, false);
        end; {End While}
        DbgPrint('FileWorks: ------------------------------------------------'#13#10);
        ExFreePool(pfdi);
      end;
      ZwClose(hDriversDirectory);
    end else
    begin
      DbgPrint('FileWorks: Can''t open drivers directory. Status: %08X', RtnCode);
    end;
    ZwClose(hSystemRootDirectory);
  end else
  begin
    DbgPrint('FileWorks: Can''t open system root directory. Status: %08X'#13#10, RtnCode);
  end;
end;

function _DriverEntry(pDriverObject:PDRIVER_OBJECT;
                      pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;
begin
  DbgPrint(#13#10'FileWorks: Entering DriverEntry'#13#10);
  RtlInitUnicodeString(g_usFileName, '\??\c:\FileWorks\test.txt');
  RtlInitUnicodeString(g_usDirName, '\??\c:\FileWorks');
  CreateDirectory;
  CreateFile;
  WriteFile;
  MarkAsReadOnly;
  ReadFile;
  UnmarkAsReadOnly;
  AppendFile;
  ReadFile;
  TruncateFile;
  ReadFile;
  DeleteFile;
  DeleteDirectory;
  EnumerateFiles;
  DbgPrint(#13#10'FileWorks: Leaving DriverEntry'#13#10);
  result := STATUS_DEVICE_CONFIGURATION_ERROR;
end;

end. 
InitializeObjectAttributes(oa, @g_usDirName, OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, 0, nil);
RtnCode := ZwCreateFile(@hDirectory, SYNCHRONIZE, @oa, @iosb, nil,FILE_ATTRIBUTE_NORMAL, 0, 
                                    FILE_OPEN_IF,FILE_DIRECTORY_FILE+FILE_SYNCHRONOUS_IO_NONALERT,
                                    nil, 0);
NTSTATUS 
ZwCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
); 
if RtnCode = STATUS_SUCCESS then
begin
    if iosb.Information = FILE_CREATED then
    begin
      ……      
    end else if iosb.Information = FILE_OPENED then
    begin
      ……      
end; 
p_Irp^.IoStatus.Status := STATUS_SUCCESS;
p_Irp^.IoStatus.Information := 0;
IofCompleteRequest(p_Irp, IO_NO_INCREMENT); 
RtnCode := ZwCreateFile(@hFile, SYNCHRONIZE, @oa, @iosb, nil,
                     FILE_ATTRIBUTE_NORMAL, 0,
                     FILE_CREATE,
                     FILE_SYNCHRONOUS_IO_NONALERT, nil, 0); 
TFileObject=packed record
    wType:Word;
    Size:Word;
    DeviceObject:PDeviceObject;
    DoNotUser1:Pointer;
    FsContext:Pointer;
    FsContext2:Pointer;
    SectionObjectPointer:Pointer;
    PrivateCacheMap:Pointer;
    FinalStatus:NTSTATUS;
    RelatedFileObject:PFileObject;
    LockOperation:Boolean;
    DeletePending:Boolean;
    ReadAccess:Boolean;
    WriteAccess:Boolean;
    DeleteAccess:Boolean;
    SharedRead:Boolean;
    SharedWrite:Boolean;
    SharedDelete:Boolean;
    Flags:Cardinal;
    FileName:TUnicodeString;
    CurrentByteOffset:TLargeInteger;
    Waiters:Cardinal;
    Busy:Cardinal;
    LastLock:Pointer;
    Lock:TKEvent;
    Event:TKEvent;
   CompletionContext:Pointer;
end; 
var
pFileObject:PFILE_OBJECT;
. . .
begin
RtnCode := ObReferenceObjectByHandle(hFile, FILE_READ_DATA, nil, KernelMode, @pFileObject,nil);
  if RtnCode = STATUS_SUCCESS then
begin
    {pFileObject指向对应于hFile的FILE_OBJECT}
    ObfDereferenceObject(pFileObject);
end;
end;
RtnCode := ZwCreateFile(@hFile, FILE_WRITE_DATA + SYNCHRONIZE,
                     @oa, @iosb, nil, 0, FILE_SHARE_READ,
                     FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
                     nil, 0); 
FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE or
                                    FILE_WRITE_DATA or
                                    FILE_WRITE_ATTRIBUTES or
                                    FILE_WRITE_EA or
                                    FILE_APPEND_DATA or
                                    SYNCHRONIZE); 
if RtnCode = STATUS_SUCCESS then
begin
    DbgPrint('FileWorks: File openeded'#13#10);
    g_szData := 'Data can be written to an open file';
    RtnCode := ZwWriteFile(hFile, 0, nil, nil, @iosb, g_szData,
                           strlen(g_szData), nil, nil);
NTSTATUS 
ZwWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
); 
RtnCode := ZwCreateFile(@hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES +  SNCHRONIZE, @oa, @iosb, nil, 0, FILE_SHARE_READ,
                          FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT,
                          nil, 0); 
if RtnCode = STATUS_SUCCESS then
begin
  DbgPrint('FileWorks: File openeded'#13#10);
  RtnCode := ZwQueryInformationFile(hFile, @iosb, @fbi,
                                sizeof(fbi),
                                FileBasicInformation);
  if RtnCode = STATUS_SUCCESS then
  begin
fbi.FileAttributes := fbi.FileAttributes or FILE_ATTRIBUTE_READONLY;
RtnCode := ZwSetInformationFile(hFile, @iosb, @fbi,
                            sizeof(fbi), FileBasicInformation); 
fbi.FileAttributes := fbi.FileAttributes and (not FILE_ATTRIBUTE_READONLY); 
NTSTATUS
ZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
); 
RtnCode := ZwOpenFile(@hFile, FILE_READ_DATA + SYNCHRONIZE,
                        @oa, @iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE,
                        FILE_SYNCHRONOUS_IO_NONALERT); 

FILE_READ_DATA——在这里我们只从文件中读取数据。标志FILE_SHARE_READ、FILE_SHARE_WRITE和FILE_SHARE_DELETE的组合允许对文件进行完全的访问。
if RtnCode = STATUS_SUCCESS then
begin
  DbgPrint('FileWorks: File openeded'#13#10);
  RtnCode := ZwQueryInformationFile(hFile, @iosb, @fsi,
                                sizeof(fsi),
                                FileStandardInformation);
 if RtnCode = STATUS_SUCCESS then
  begin 
 p := ExAllocatePool(PagedPool, cb);
      if p <> nil then
      begin
        memset(p, 0, cb);
        RtnCode := ZwReadFile(hFile, 0, nil, nil, @iosb, p, cb, nil, nil);
        if RtnCode = STATUS_SUCCESS then
        begin
          DbgPrint('FileWorks: File content: \=%s\='#13#10, p);
        End;
        ExFreePool(p);
     end;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
2
up之。。。。。
2009-12-8 17:28
0
雪    币: 150
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶~~出本书吧!!
2009-12-8 21:06
0
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
mickeylan终于更新了
2009-12-8 23:24
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
5
太强大了,不懂dephi 的人飘过!
2009-12-8 23:53
0
雪    币: 2015
活跃值: (902)
能力值: ( LV12,RANK:1000 )
在线值:
发帖
回帖
粉丝
6
请问楼主,delphi编写驱动可以带源码调试吗?没有实践过,对此知之甚少。本人其实也很喜欢delphi,喜欢它的ide。
2009-12-13 18:54
0
雪    币: 1004
活跃值: (75)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
7
就是没有办法源级调试,不过到驱动这层很多问题还是要汇编级调试才能搞定了。
2009-12-14 12:01
0
雪    币: 2015
活跃值: (902)
能力值: ( LV12,RANK:1000 )
在线值:
发帖
回帖
粉丝
8
感谢lz释疑,我也觉得没有pdb文件不知道如何源码调试。前辈能否介绍一下你的驱动调试环境以及要注意的地方,真心向前辈学习。
2009-12-15 19:44
0
雪    币: 1004
活跃值: (75)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
9
我都是用windbg双机调试的,用analyze -v分析dump文件,再配合IDA反编译的程序,调试起来也很轻松,还能提高你的汇编水平,一举数得。
2009-12-15 22:09
0
雪    币: 602
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
希望Delphi驱动资料汇集成册
2010-3-9 16:32
0
雪    币: 163
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
佩服楼主的坚持与精神
2010-12-15 15:47
0
游客
登录 | 注册 方可回帖
返回
//