liumaliang
驱动牛犊
驱动牛犊
  • 注册日期2006-07-14
  • 最后登录2010-05-28
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望33点
  • 贡献值0点
  • 好评度31点
  • 原创分0分
  • 专家分0分
阅读:1484回复:2

100分寻驱动中获取磁盘物理序列号的方法

楼主#
更多 发布于:2007-04-13 11:47
  如何在磁盘下层过滤驱动中获取物理序列号,或者在内核线程中获取物理序列号.

最新喜欢:

LeopardLeopar...
liumaliang
驱动牛犊
驱动牛犊
  • 注册日期2006-07-14
  • 最后登录2010-05-28
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望33点
  • 贡献值0点
  • 好评度31点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-04-17 19:54
多谢znsoft的指导,现在已经按照其实现思想在过滤驱动中读出了磁盘物理序列号.
相关代码如下.
BOOLX getDiskID(char *v_diskID,ULONGX length1,PDISKFT_DEVICE_EXTENSION dx,CHAR idemap)
{
        PUCHAR buffer;
        PSRB_IO_CONTROL  srbControl;
     ULONG            controlCode = 0;
     PIRP irp2;
        KEVENT event;
     IO_STATUS_BLOCK ioStatus;    
     NTSTATUS status;
     ULONGX length;
      KeInitializeEvent(&event, SynchronizationEvent, FALSE);
        length = 512 + sizeof(SENDCMDOUTPARAMS)+sizeof(SENDCMDINPARAMS);
         controlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;

      srbControl =(PSRB_IO_CONTROL)ExAllocatePoolWithTag(NonPagedPool,
                                           sizeof(SRB_IO_CONTROL) + length,
                                           DISK_TAG_SMART);

         if (!srbControl) {
              status =  STATUS_INSUFFICIENT_RESOURCES;
        MyDebugPrint("alloc srb error\n");      
               return NSS_FALSE;
               }

        //
        // fill in srbControl fields
        //

        srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
        RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
        srbControl->Timeout = 100;
        srbControl->Length = length;
        srbControl->ControlCode = controlCode;

        //
        // Point to the 'buffer' portion of the SRB_CONTROL
        //

        buffer = (PUCHAR)srbControl;
        buffer += srbControl->HeaderLength;
    PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)buffer);

        //
        // Ensure correct target is set in the cmd parameters.
        //

           cmdInParameters->bDriveNumber = dx->ScsiAddress.TargetId;
     cmdInParameters->cBufferSize = 512;
           cmdInParameters->irDriveRegs.bFeaturesReg = 0;
      cmdInParameters->irDriveRegs.bSectorCountReg = 1;
        cmdInParameters->irDriveRegs.bSectorNumberReg = 1;
        cmdInParameters->irDriveRegs.bCylLowReg = 0;
        cmdInParameters->irDriveRegs.bCylHighReg = 0;
     cmdInParameters->irDriveRegs.bDriveHeadReg =   0xA0 | ((((UCHAR)(dx->diskID))  &  1) << 4);
     cmdInParameters->irDriveRegs.bCommandReg = ID_CMD;
     cmdInParameters->bDriveNumber = (UCHAR) (dx->diskID);
     cmdInParameters->cBufferSize = 512;
        //
        // Copy the IOCTL parameters to the srb control buffer area.
        //

        irp2 = IoBuildDeviceIoControlRequest(IOCTL_SCSI_MINIPORT,
                                            dx->LowerDeviceObject,
                                            srbControl,
                                            sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1,
                                            srbControl,
                                            sizeof(SRB_IO_CONTROL) + length,
                                            FALSE,
                                            &event,
                                            &ioStatus);

        if (irp2 == NULL) {
            status = STATUS_INSUFFICIENT_RESOURCES;
            ExFreePool(srbControl);
         MyDebugPrint("build io irp error\n");        
            return NSS_FALSE;
        }

        //
        // Call the port driver with the request and wait for it to complete.
        //

        status = IoCallDriver(dx->LowerDeviceObject, irp2);

        if (status == STATUS_PENDING) {
            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
            status = ioStatus.Status;
        }

        //
        // Copy the data received into the output buffer. Since the status buffer
        // contains error information also, always perform this copy. IO will will
        // either pass this back to the app, or zero it, in case of error.
        //

        buffer = (PUCHAR)srbControl;
        buffer += srbControl->HeaderLength;

        if (NT_SUCCESS(status)) {
        MyDebugPrint("successs in read disk id");    
               ULONG diskdata [256];
               int ijk = 0;
               USHORT *pIdSector = (USHORT *)
                             ((PSENDCMDOUTPARAMS) buffer) -> bBuffer;

               for (ijk = 0; ijk < 256; ijk++)
                  diskdata [ijk] = pIdSector [ijk];
                GetDiskInfo(diskdata,v_diskID,length1);
          ExFreePool(srbControl);
          return NSS_TRUE;    
              
        } else {
        MyDebugPrint("get disk id error\n");
        
        }

        ExFreePool(srbControl);
        return NSS_FALSE;
}
但是有一个问题,就是在虚拟机中测试时,只能够读出IDE0:0和IDE0:1两块硬盘,如果增加
IDE1:1硬盘,程序读不出来.SCSI硬盘就更读不出来了.
还有一个问题,为什么在虚拟机中新加一块IDE硬盘,会调用AddDevice例程两次,一次是系统启动时调用的,然后当提示发现新硬件时又会调用过滤驱动的AddDevice例程.
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
板凳#
发布于:2007-04-13 11:53
应用层的有 diskid32  你google一下
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
游客

返回顶部