阅读:1483回复:2
100分寻驱动中获取磁盘物理序列号的方法
如何在磁盘下层过滤驱动中获取物理序列号,或者在内核线程中获取物理序列号.
|
|
最新喜欢:![]() |
沙发#
发布于:2007-04-13 11:53
应用层的有 diskid32 你google一下
|
|
|
板凳#
发布于: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例程. |
|