首页
社区
课程
招聘
[求助]求驱动中获取硬盘物理序列号代码
发表于: 2008-2-19 11:44 8201

[求助]求驱动中获取硬盘物理序列号代码

2008-2-19 11:44
8201
如题,最好是C的.或是给我指点一下思路.

还有就是哪位帮我看看下面这段代码,是在网上找的,说是可以得到硬盘序列号
可我在驱动中添加这个函数,调用时却得不到,谁能给我指点一下,谢谢

void GetDiskNumber()
{
        unsigned   int   dd[256];   /*   DiskData   */     
        unsigned   int   dd_off;   /*   DiskData   offset   */     
            
        while(inp(0x1F7)!=0x50);   /*   Wait   for   controller   not   busy   */
            
        outp(0x1F6, 0xA0);   /*   Get   first/second   drive   */     
            
        outp(0x1F7, 0xEC);   /*   Get   drive   info   data   */     
            
        while(inp(0x1F7) != 0x58);   /*   Wait   for   data   ready   */     
            
        for(dd_off = 0;dd_off!=256;dd_off++)   /*   Read   "sector"   */     
        dd[dd_off] = inpw(0x1F0);     
            
        DbgPrint("The   Serial   Number   Hard   Disk   is   %s \n",getascii(dd,10,19));
}

char   *getascii(unsigned   int   in_data[],   int   off_start,   int   off_end)     
{     
        static   char   ret_val[255];     
        int   loop,   loop1;     
            
        for(loop = off_start, loop1 = 0; loop <=off_end; loop++)     
        {     
                ret_val[loop1++] =(char)(in_data[loop]/256);   /*   Get   High   byte   */     
                ret_val[loop1++]=(char)(in_data[loop]%256);   /*   Get   Low   byte   */     
        }     
        ret_val[loop1]=' ';   /*   Make   sure   it   ends   in   a   NULL   character   */     
        return(ret_val);     
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
2
inp和outp都是直接访问I/O端口的操作, 在DOS/Win95下还行, NT/2000/XP以后就没戏了.
2008-2-19 21:13
0
雪    币: 228
活跃值: (119)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
如果是IDE 硬盘,如果代码中的思路没错,有可能可以得到。

如果是sata 硬盘,这段代码肯定无法得到序列号。

驱动中获得序列号,最好还是发送IOCTL_更稳定,好像有个开源的获得序列号的app,下移到驱动中就满好的,你可以找一找。
2008-2-20 11:26
0
雪    币: 187
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
多谢两位老兄,我考虑下发IRP吧,如果可以得到,我会考虑贴份代码.
再次感谢...
2008-2-20 17:31
0
雪    币: 247
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
网上有代码的搜索 disk32 scsi和sata硬盘都可以得到 不过有的硬盘是没号的
2008-2-21 17:19
0
雪    币: 187
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
DiskId32是应用层的代码,调用DeviceIoControl,发送IOCTL_就可以了
可我想在内核过滤驱动中得到硬盘物理序列号

我写了如下程序,就是把DiskId32改成驱动版的了

#include <ntifs.h>
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <stdio.h>
#include "..\DiskID.h"

char IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];

VOID
MyUnload(
    IN PDRIVER_OBJECT  DriverObject
    )
{

}

BOOLEAN getDiskID( PDEVICE_OBJECT DeviceObject )
{
    PUCHAR buffer;
    PSRB_IO_CONTROL srbControl;
    ULONG         controlCode = 0;
    PIRP irp2;
    KEVENT event;
    IO_STATUS_BLOCK ioStatus;   
    NTSTATUS status;
    ULONG length;
        PSENDCMDINPARAMS cmdInParameters;
        ULONG drive = 0;

        SENDCMDINPARAMS  scip;

        memset (&scip, 0, sizeof(scip));
    memset (IdOutCmd, 0, sizeof(IdOutCmd));
        scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
        scip.irDriveRegs.bFeaturesReg = 0;
        scip.irDriveRegs.bSectorCountReg = 1;
        scip.irDriveRegs.bSectorNumberReg = 1;
        scip.irDriveRegs.bCylLowReg = 0;
        scip.irDriveRegs.bCylHighReg = 0;

          // Compute the drive number.
        scip.irDriveRegs.bDriveHeadReg = 0xA0 | (((UCHAR)drive & 1) << 4);

          // The command can either be IDE identify or ATAPI identify.
        scip.irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
        scip.bDriveNumber = (UCHAR)drive;
        scip.cBufferSize = IDENTIFY_BUFFER_SIZE;

    //
    // Copy the IOCTL parameters to the srb control buffer area.
    //
    irp2 = IoBuildDeviceIoControlRequest(DFP_RECEIVE_DRIVE_DATA,
                            DeviceObject,
                            &scip,
                            sizeof(SENDCMDINPARAMS) - 1,
                            IdOutCmd,
                            sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
                            FALSE,
                            &event,
                            &ioStatus);

    if (irp2 == NULL) {
        DbgPrint("Build DeviceIoControl Error \n");
                return FALSE;
    }

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

    status = IoCallDriver(DeviceObject, 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.
    //
   
    if (NT_SUCCESS(status)) {
          ULONG diskdata [256];
          int ijk = 0;
          USHORT *pIdSector = (USHORT *)
                             ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;
                  DbgPrint("successs in read disk id \n");   

          for (ijk = 0; ijk < 256; ijk++)
            diskdata [ijk] = pIdSector [ijk];
         
        PrintIdeInfo (drive, diskdata);
                IoCompleteRequest( irp2,IO_NO_INCREMENT );
        return TRUE;     
         
    } else {
       DbgPrint("get disk id error\n");
   
    }
   
    return FALSE;
}

NTSTATUS
DriverEntry( IN PDRIVER_OBJECT DriverObject,
                         IN PUNICODE_STRING RegistryPath )
{
        UNICODE_STRING DeviceName;
        PFILE_OBJECT FileObject = NULL;
        PDEVICE_OBJECT DeviceObject = NULL;

        RtlInitUnicodeString( &DeviceName,L"\\Device\\ScsiPort0" );       

        IoGetDeviceObjectPointer( &DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject );

        DriverObject->DriverUnload = MyUnload;

        if( NULL == DeviceObject )
        {
                DbgPrint(" Error get Disk DeviceObject \n" );
                return STATUS_SUCCESS;
        }

        if( FALSE == getDiskID( DeviceObject ) )
        {
                DbgPrint(" Get DiskID ERROR \n");
                return STATUS_SUCCESS;
        }
        DbgPrint(" read Success \n" );

        return STATUS_SUCCESS;       
}

void PrintIdeInfo (int drive, ULONG diskdata [256])
{
        char string1 [1024];

        strcpy (string1, ConvertToString (diskdata, 10, 19));

        DbgPrint("DiskID %s \n",ConvertToString (diskdata, 10, 19));
}

char *ConvertToString (ULONG diskdata [256], int firstIndex, int lastIndex)
{
   static char string [1024];
   int index = 0;
   int position = 0;

      //  each integer has two characters stored in it backwards
   for (index = firstIndex; index <= lastIndex; index++)
   {
         //  get high byte for 1st character
      string [position] = (char) (diskdata [index] / 256);
      position++;

         //  get low byte for 2nd character
      string [position] = (char) (diskdata [index] % 256);
      position++;
   }

      //  end the string
   string [position] = '\0';

      //  cut off the trailing blanks
   for (index = position - 1; index > 0 && ' ' == string [index]; index--)
      string [index] = '\0';

   return string;
}

读取硬盘ID的时候总是不成功,是在下发IRP的时候有问题,应该是这句

status = IoCallDriver(DeviceObject, irp2);

    if (status == STATUS_PENDING) {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = ioStatus.Status;
    }
ioStatus.Status不是STATUS_SUCCESS;
请问各位,怎么设置物理设备对象才能让这段代码发送成功啊???

RtlInitUnicodeString( &DeviceName,L"\\Device\\ScsiPort0" );       
IoGetDeviceObjectPointer( &DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject );
这个方法得到的设备对象正确吗?
2008-2-23 15:56
0
游客
登录 | 注册 方可回帖
返回
//