作者:陆麟
转载请征得作者同意.
1999.6.16

好象所有的NT DRIVER书里的例子都是真正的DRIVER.所有的DRIVER都负责某一类硬件的驱动.他们都没有提过如何来写一个不负责任何硬件运转的驱动程序.今天.我来演示一个.这个演示很简单.他什么都不干.只负责映射一个Z盘的驱动器符.任何对该驱动器的OPEN,CLOSE操作将被LOG.如果有时间的话,我想把这个DRIVER改写一下,写成类似于PGP6.0X里PGPDISK的DRIVER.把文件映射成驱动器.当然.如果愿意的话.我可以写成提供对应用提供DEVICEIO的DRIVER.现在这里的只不过是个简单到极点的演示.
里面同时演示了DRIVER如何进行文件操作和映射驱动器符.使系统可见.
/*----------------------------------------------------------------*\
 NTDRIVER DEMOSTRATION.
 WRITTEN BY LULIN.
 1999.6.16
 欢迎转载.请通知作者.
\*----------------------------------------------------------------*/
#include <ntddk.h>
NTSTATUS DrvLog(char* buffer){
 NTSTATUS ntstatus;
 ANSI_STRING ansistring;
 UNICODE_STRING filename;
 //WCHAR file[]=L"\\SystemRoot\\DRV.LOG";
 WCHAR file[]=L"\\??\\C:\\DRV.LOG";
 HANDLE hf=0;
 IO_STATUS_BLOCK IoStatusBlock;
 OBJECT_ATTRIBUTES ObjectAttributes;
 FILE_POSITION_INFORMATION FileInformation;
 FILE_STANDARD_INFORMATION stdinf;
 RtlInitAnsiString(
  &ansistring,
  buffer
 );
 RtlInitUnicodeString(
  &filename,
  file
  );
 InitializeObjectAttributes(
  &ObjectAttributes,
  &filename,
  OBJ_CASE_INSENSITIVE,
  NULL,
  NULL
  );
 ntstatus=ZwCreateFile(
  &hf,
  GENERIC_WRITE|SYNCHRONIZE|GENERIC_READ,
  &ObjectAttributes,
  &IoStatusBlock,
  0,
  FILE_ATTRIBUTE_NORMAL,
  FILE_SHARE_DELETE,
  FILE_OPEN_IF,
  FILE_SYNCHRONOUS_IO_NONALERT,
  NULL,
  0
  );
 if (!NT_SUCCESS(ntstatus)){
  return ntstatus;
 }
 ZwQueryInformationFile(
  hf,
  &IoStatusBlock,
  (void*)&stdinf,
  sizeof(stdinf),
  FileStandardInformation
  );
 if (!NT_SUCCESS(IoStatusBlock.Status)){
  return IoStatusBlock.Status;
 }
 FileInformation.CurrentByteOffset=stdinf.EndOfFile;
    ZwSetInformationFile(
  hf,
  &IoStatusBlock,
  (void*)&FileInformation,
  sizeof(FileInformation),
  FilePositionInformation
  );
 if (!NT_SUCCESS(IoStatusBlock.Status)){
  return IoStatusBlock.Status;
 }
 ZwWriteFile(
  hf,
  0,
  0,
  0,
  &IoStatusBlock,
  buffer,
  ansistring.Length,
  NULL,
  NULL
  );
 ZwClose(hf);
 return IoStatusBlock.Status;
}
NTSTATUS Create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){
 Irp->IoStatus.Status = STATUS_SUCCESS;
 return DrvLog("Createing Device\a\n");
}
NTSTATUS Close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){
 Irp->IoStatus.Status = STATUS_SUCCESS;
 return DrvLog("Closing Device\a\n");
}
NTSTATUS CreateDevice(PDRIVER_OBJECT  DriverObject,PWCHAR devicename){
 NTSTATUS ntstatus;
 PDEVICE_OBJECT  DeviceObject;
 UNICODE_STRING devname;
 WCHAR buff[100];
 UNICODE_STRING  SymbolicLinkName;
 devname.Buffer=buff;
 devname.MaximumLength=100;
 RtlAppendUnicodeToString(&devname,L"\\Device\\");
 RtlAppendUnicodeToString(&devname,devicename);
 RtlInitUnicodeString(&SymbolicLinkName,L"\\??\\Z:");
//创建DEVICE OBJECT.有了DEVICE OBJECT.才能创建符号联接.
//创建符号联接,才使系统可见,系统可见,才使应用程序能进行
//各种操作,能使应用程序进行各种操作,DRIVER才真正有用...
 ntstatus=IoCreateDevice(
  DriverObject,
  0,
  &devname,
  FILE_DEVICE_UNKNOWN,
  0,
  1,
  &DeviceObject
  );
 if (!NT_SUCCESS(ntstatus)){
  return ntstatus;
 }
//IoCreateSymbolicLink用来创建系统可见的对象.
//要使系统可见.符号联接必须位于\??\下.老的NT
//用\DosDevices\.当然目前的NT也支持\DosDevices\
//格式.但\DosDevices\仅是\??\的一个符号联接.
ntstatus=IoCreateSymbolicLink(
  &SymbolicLinkName,
  &devname
  );
 return ntstatus;

}
//DRIVERENTRY是NT驱动程序的标准入口.
//它传入2个参数.一个系统创建的DRIVER对象.和指向属于DRIVER的注册表关键字.
//我这DRIVER里面仅有CREATE,CLOSE的支持.是个不完整的DRIVER.
DriverEntry(PDRIVER_OBJECT pdrv,PUNICODE_STRING pus){
 pdrv->MajorFunction[IRP_MJ_CREATE]=Create;
 pdrv->MajorFunction[IRP_MJ_CLOSE]=Close;
 CreateDevice(pdrv,L"drv"); //DRIVER HELPER FUNCTION. HELP TO FULFIL
                            //ROUTIONES TO CREATE DEVICE OBJECT...
 return 0;
}
//--------------------------------END---------------------------