WIN7 64位系统下获取不了硬盘序列号,而且获取的CPU ID 居然有重复的, 请帮忙分析一下

eisldkw 2018-10-05 09:15:03
WIN7 64位系统下获取不了硬盘序列号,请帮忙分析一下原因

代码如下:


Public Name1 As String '定义姓名1为字符串
Public StrNums As Integer '定义编号为整形
Public Temps '定义一个变体类型的公共变量


Private Const MAX_IDE_DRIVES As Long = 4 ' Max number of drives assuming primary/secondary, master/slave topology
Private Const READ_ATTRIBUTE_BUFFER_SIZE As Long = 512
Private Const IDENTIFY_BUFFER_SIZE As Long = 512
Private Const READ_THRESHOLD_BUFFER_SIZE As Long = 512
Private Const DFP_GET_VERSION As Long = &H74080
Private Const DFP_SEND_DRIVE_COMMAND As Long = &H7C084
Private Const DFP_RECEIVE_DRIVE_DATA As Long = &H7C088

Private Type GETVERSIONOUTPARAMS '获得提取出来的版本号参数
bVersion As Byte ' Binary driver version.
bRevision As Byte ' Binary driver revision.
bReserved As Byte ' Not used.
bIDEDeviceMap As Byte ' Bit map of IDE devices.
fCapabilities As Long ' Bit mask of driver capabilities.
dwReserved(3) As Long ' For future use.
End Type

Private Const CAP_IDE_ID_FUNCTION As Long = 1 ' ATA ID command supported
Private Const CAP_IDE_ATAPI_ID As Long = 2 ' ATAPI ID command supported
Private Const CAP_IDE_EXECUTE_SMART_FUNCTION As Long = 4 ' SMART commannds supported

Private Type IDEREGS
bFeaturesReg As Byte ' Used for specifying SMART "commands".
bSectorCountReg As Byte ' IDE sector count register
bSectorNumberReg As Byte ' IDE sector number register
bCylLowReg As Byte ' IDE low order cylinder value
bCylHighReg As Byte ' IDE high order cylinder value
bDriveHeadReg As Byte ' IDE drive/head register
bCommandReg As Byte ' Actual IDE command.
bReserved As Byte ' reserved for future use. Must be zero.
End Type

Private Type SENDCMDINPARAMS
cBufferSize As Long ' Buffer size in bytes
irDriveRegs As IDEREGS ' Structure with drive register values.
bDriveNumber As Byte ' Physical drive number to send
' command to (0,1,2,3).
bReserved(2) As Byte ' Reserved for future expansion.
dwReserved(3) As Long ' For future use.
bBuffer(0) As Byte ' Input buffer.
End Type

Private Const IDE_ATAPI_ID As Long = &HA1 ' Returns ID sector for ATAPI.
Private Const IDE_ID_FUNCTION As Long = &HEC ' Returns ID sector for ATA.
Private Const IDE_EXECUTE_SMART_FUNCTION As Long = &HB0 ' Performs SMART cmd.
Private Const SMART_CYL_LOW As Long = &H4F
Private Const SMART_CYL_HI As Long = &HC2

Private Type DRIVERSTATUS ' 驱动器状态
bDriverError As Byte ' Error code from driver,
bIDEStatus As Byte ' Contents of IDE Error register.
bReserved(1) As Byte ' Reserved for future expansion.
dwReserved(1) As Long ' Reserved for future expansion.
End Type

Private Const SMART_NO_ERROR As Long = 0 ' No error
Private Const SMART_IDE_ERROR As Long = 1 ' Error from IDE controller
Private Const SMART_INVALID_FLAG As Long = 2 ' Invalid command flag
Private Const SMART_INVALID_COMMAND As Long = 3 ' Invalid command byte
Private Const SMART_INVALID_BUFFER As Long = 4 ' Bad buffer (null, invalid addr..)
Private Const SMART_INVALID_DRIVE As Long = 5 ' Drive number not valid
Private Const SMART_INVALID_IOCTL As Long = 6 ' Invalid IOCTL
Private Const SMART_ERROR_NO_MEM As Long = 7 ' Could not lock user's buffer
Private Const SMART_INVALID_REGISTER As Long = 8 ' Some IDE Register not valid
Private Const SMART_NOT_SUPPORTED As Long = 9 ' Invalid cmd flag set
Private Const SMART_NO_IDE_DEVICE As Long = 10 ' Cmd issued to device not present

Private Type SENDCMDOUTPARAMS ' 发送提取出的参数命令
cBufferSize As Long ' Size of bBuffer in bytes
drvStatus As DRIVERSTATUS ' Driver status structure.
bBuffer(0) As Byte ' Buffer of arbitrary length in which to store the data read from the ' drive.
End Type

Private Const SMART_READ_ATTRIBUTE_VALUES As Long = &HD0 ' ATA4: Renamed
Private Const SMART_READ_ATTRIBUTE_THRESHOLDS As Long = &HD1 ' Obsoleted in ATA4!
Private Const SMART_ENABLE_DISABLE_ATTRIBUTE_AUTOSAVE As Long = &HD2
Private Const SMART_SAVE_ATTRIBUTE_VALUES As Long = &HD3
Private Const SMART_EXECUTE_OFFLINE_IMMEDIATE As Long = &HD4 ' ATA4
Private Const SMART_ENABLE_SMART_OPERATIONS As Long = &HD8
Private Const SMART_DISABLE_SMART_OPERATIONS As Long = &HD9
Private Const SMART_RETURN_SMART_STATUS As Long = &HDA

Private Type DRIVEATTRIBUTE ' 驱动器属性
bAttrID As Byte ' Identifies which attribute
wStatusFlags As Integer ' see bit definitions below
bAttrValue As Byte ' Current normalized value
bWorstValue As Byte ' How bad has it ever been?
bRawValue(5) As Byte ' Un-normalized value
bReserved As Byte ' ...
End Type

Private Type ATTRTHRESHOLD '阈值属性
bAttrID As Byte ' Identifies which attribute
bWarrantyThreshold As Byte ' Triggering value
bReserved(9) As Byte ' ...
End Type

Private Type IDSECTOR '扇区编号
wGenConfig As Integer
wNumCyls As Integer
wReserved As Integer
wNumHeads As Integer
wBytesPerTrack As Integer
wBytesPerSector As Integer
wSectorsPerTrack As Integer
wVendorUnique(2) As Integer
sSerialNumber(19) As Byte
wBufferType As Integer
wBufferSize As Integer
wECCSize As Integer
sFirmwareRev(7) As Byte
sModelNumber(39) As Byte
wMoreVendorUnique As Integer
wDoubleWordIO As Integer
wCapabilities As Integer
wReserved1 As Integer
wPIOTiming As Integer
wDMATiming As Integer
wBS As Integer
wNumCurrentCyls As Integer
wNumCurrentHeads As Integer
wNumCurrentSectorsPerTrack As Integer
ulCurrentSectorCapacity(3) As Byte '这里只能用byte,因为VB没有无符号的LONG型变量
wMultSectorStuff As Integer
ulTotalAddressableSectors(3) As Byte '这里只能用byte,因为VB没有无符号的LONG型变量
wSingleWordDMA As Integer
wMultiWordDMA As Integer
bReserved(127) As Byte
End Type

Private Const ATTR_INVALID As Long = 0
Private Const ATTR_READ_ERROR_RATE As Long = 1
Private Const ATTR_THROUGHPUT_PERF As Long = 2
Private Const ATTR_SPIN_UP_TIME As Long = 3
Private Const ATTR_START_STOP_COUNT As Long = 4
Private Const ATTR_REALLOC_SECTOR_COUNT As Long = 5
Private Const ATTR_READ_CHANNEL_MARGIN As Long = 6
Private Const ATTR_SEEK_ERROR_RATE As Long = 7
Private Const ATTR_SEEK_TIME_PERF As Long = 8
Private Const ATTR_POWER_ON_HRS_COUNT As Long = 9
Private Const ATTR_SPIN_RETRY_COUNT As Long = 10
Private Const ATTR_CALIBRATION_RETRY_COUNT As Long = 11
Private Const ATTR_POWER_CYCLE_COUNT As Long = 12

Private Const PRE_FAILURE_WARRANTY As Long = &H1
Private Const ON_LINE_COLLECTION As Long = &H2
Private Const PERFORMANCE_ATTRIBUTE As Long = &H4
Private Const ERROR_RATE_ATTRIBUTE As Long = &H8
Private Const EVENT_COUNT_ATTRIBUTE As Long = &H10
Private Const SELF_PRESERVING_ATTRIBUTE As Long = &H20

Private Const NUM_ATTRIBUTE_STRUCTS As Long = 30
Private Const INVALID_HANDLE_VALUE As Long = -1

Private Const VER_PLATFORM_WIN32s As Long = 0
Private Const VER_PLATFORM_WIN32_WINDOWS As Long = 1
Private Const VER_PLATFORM_WIN32_NT As Long = 2

Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128 ' Maintenance string for PSS usage
End Type

Private Const CREATE_NEW As Long = 1
Private Const GENERIC_READ As Long = &H80000000
Private Const GENERIC_WRITE As Long = &H40000000
Private Const FILE_SHARE_READ As Long = &H1
Private Const FILE_SHARE_WRITE As Long = &H2
Private Const OPEN_EXISTING As Long = 3

Private m_DiskInfo As IDSECTOR

Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As Any, ByVal nOutBufferSize As Long, lpBytesReturned As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long

'信息类型枚举
Enum eumInfoType
hdmodelsn = 0
hdOnlyModel = 1
hdOnlySN = 2
End Enum

'磁盘通道枚举
Enum eumDiskNo
hdPrimaryMaster = 0
hdPrimarySlave = 1
hdSecondaryMaster = 2
hdSecondarySlave = 3
End Enum

Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long

...全文
2273 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_41506221 2019-06-05
  • 打赏
  • 举报
回复
win10系统,装的pci的固态硬盘,也是各种方法读不到序列号,愁死了
tansx 2018-11-30
  • 打赏
  • 举报
回复
学习了!不错!
xxxli 2018-11-25
  • 打赏
  • 举报
回复
虚拟机安装的windows读取硬盘序列号也是空
xxxli 2018-11-25
  • 打赏
  • 举报
回复
我的软件,需要用到读取硬盘序列号,经过用户反应,各个windows平台都能正确读取硬盘序列号,只是一些电脑,比如苹果电脑安装windows系统,读取硬盘序列号一定是空。代码与上面的代码差不多。
threenewbee 2018-11-06
  • 打赏
  • 举报
回复
引用 40 楼 zhllxt 的回复:
[quote=引用 13 楼 caozhy 的回复:] cpu id又不是cpu序列号(只有PIII CPU有序列号,后来因为用户强烈反对,Intel才不搞了,而就是PIII CPU,大部分主板bios默认也是禁止序列号读取的) 如果cpu的型号、步进完全相同,cpu id就相同。同一个步进的cpu有成千上万。
这个说法看来在理儿,我很早也发现获取的CPUID在不少机器上是一样的,只是不知道原因。 另外,获取CPUID有个专门的开源库,上github.com搜libcpuid[/quote] 获取cpu id不需要什么另外的库,有一条指令就叫cpuid,不过vb嵌入汇编需要一点点技巧。
XBoy410 2018-11-05
  • 打赏
  • 举报
回复
引用 61 楼 Chen8013 的回复:
[quote=引用 60 楼 qq_36623634 的回复:]
[quote=引用 59 楼 Chen8013 的回复:]
. . . . . . . . . . .



技术讨论,不带耍脾气玩的。-_-"

我上面说的方案是CPUID+MAC,如果不安全,可以加密。同时,服务端对客户端认证,也是一种排除并限制MAC地址相同(信息相同)冲突的手段。
当然,按你所说的理解:用户都知道了你的版权保护的方法了,硬盘ID就安全了?
我们用的Window系统都不是正版的吧……
[/quote]
耍脾气? 误会了……我没这必要。
我的主要观点是,平常的“改MAC”的操作,真没难度……
有N多种方法,打开“硬件管理”,然后进入到下图这个界面:


默认是“不存在”的,这时系统就是用的硬件本身的MAC数据;
 要更改的话,选择上面的那个单选,输入一个新的MAC数据就行了。
别人写个“教程”,即使“不懂”的人,按步就班的进行操作,这不难吧!
  不过就是鼠标左键右键的点一串……然后输入给定的12个字符而已。
但真有照着教程还说这个“不知道如何完成操作”的人,呵呵……你说呢?

在这“硬件属性”中更改,然后“确定”之后是“立即生效”的,
就算不“人工修改”,在“破解程序”中用代码完成修改操作,也是小事一桩。
用程序代码修改后,重启计算机后就可生效(当然也有办法“不用重启就能生效”)。
当然也有无论如何“改MAC”也能读取到“硬件本身的MAC”的方法,
具体的方法,我就不在这儿说了,有兴趣自己查资料。

相比之下,硬盘的序列号,恐怕基本上处于“没法修改”的状态。
至少,在操作系统中没有现成的方法!就算要修改也必须有相应的工具软件。
在几个月前,也有人说过这事,但当时我在网上找了两个号称“专家”的软件,
 在虚拟机系统中试过,没有任何效果(难道我的打开方式不对?)。
它说要“注册”之后,可以让修改“永久生效”;
没注册的“试用”只能临时生效(重启计算机会还原)。
但我的程序代码在它“临时更改硬盘序列号”之后,读取到的还是原来的序列号。
当然我也不可能“注册”他的软件,因为我根本没这需求。
何况“试验”完全没效果,谁会放心的“花钱买”呢!!!
[/quote]



你说的一点没有错,我都研究过,单一的MAC地址等加密,肯定是不行的。所以,还是组合式硬件加密,会安全些。
脆皮大雪糕 2018-11-05
  • 打赏
  • 举报
回复
换个思路,为啥一定要取某个硬件的信息?取某几个不行么?
硬盘编号、MAC、主板ID、bios信息……啥啥啥的,只要能取的硬件信息都取,不管取不取得到,不管取到啥。然后把所有这些信息按一定的顺序或规则拼接起来,弄个hash比如MD5、SHA1、SHA256之类的,形成针对这台机器的硬件的特征信息。
好处在于:
1、除非所有的信息都取不到,否则只要一项硬件特征被取到了,那么就会产生一个唯一的hash结果,由于取的点多了,同时都取不到的概率就降低了好多,不必像现在这样条条大路都只有部分能走通。
2、除非侵权者能够修改你获取的所有硬件信息,只要有一个改不动,且你能取到,他就复制不了。

坏处在
1、如果换了系统,突然某个API通了或者不通了,会导致特征码变化。但这个几率小,而且重装了系统要求重新注册貌似也说得过去。
2、如果装在虚拟机里,然后拷贝多份虚拟机的确可能完成复制,而躲开检查。但是如果辅以是否运行在虚拟机里的检查(像vmware会提供虚拟机特征信息供应用识别,VMware的默认mac号头几个字节是固定的。当然修改注册表改mac号没辙)会好一点。

不管咋折腾,最后都躲不过人家反编译或动态跟踪。不过真愿意花时间下这个手段,说明你的东西真值了。要值到这程度,花点小钱搞硬件保护吧,虽然也不一定保证不被破,但把破解成本提到你的软件购买成本之上就行了。
舉杯邀明月 2018-10-11
  • 打赏
  • 举报
回复
引用 60 楼 qq_36623634 的回复:
[quote=引用 59 楼 Chen8013 的回复:]
. . . . . . . . . . .



技术讨论,不带耍脾气玩的。-_-"

我上面说的方案是CPUID+MAC,如果不安全,可以加密。同时,服务端对客户端认证,也是一种排除并限制MAC地址相同(信息相同)冲突的手段。
当然,按你所说的理解:用户都知道了你的版权保护的方法了,硬盘ID就安全了?
我们用的Window系统都不是正版的吧……
[/quote]
耍脾气? 误会了……我没这必要。
我的主要观点是,平常的“改MAC”的操作,真没难度……
有N多种方法,打开“硬件管理”,然后进入到下图这个界面:


默认是“不存在”的,这时系统就是用的硬件本身的MAC数据;
 要更改的话,选择上面的那个单选,输入一个新的MAC数据就行了。
别人写个“教程”,即使“不懂”的人,按步就班的进行操作,这不难吧!
  不过就是鼠标左键右键的点一串……然后输入给定的12个字符而已。
但真有照着教程还说这个“不知道如何完成操作”的人,呵呵……你说呢?

在这“硬件属性”中更改,然后“确定”之后是“立即生效”的,
就算不“人工修改”,在“破解程序”中用代码完成修改操作,也是小事一桩。
用程序代码修改后,重启计算机后就可生效(当然也有办法“不用重启就能生效”)。
当然也有无论如何“改MAC”也能读取到“硬件本身的MAC”的方法,
具体的方法,我就不在这儿说了,有兴趣自己查资料。

相比之下,硬盘的序列号,恐怕基本上处于“没法修改”的状态。
至少,在操作系统中没有现成的方法!就算要修改也必须有相应的工具软件。
在几个月前,也有人说过这事,但当时我在网上找了两个号称“专家”的软件,
 在虚拟机系统中试过,没有任何效果(难道我的打开方式不对?)。
它说要“注册”之后,可以让修改“永久生效”;
没注册的“试用”只能临时生效(重启计算机会还原)。
但我的程序代码在它“临时更改硬盘序列号”之后,读取到的还是原来的序列号。
当然我也不可能“注册”他的软件,因为我根本没这需求。
何况“试验”完全没效果,谁会放心的“花钱买”呢!!!
XBoy410 2018-10-10
  • 打赏
  • 举报
回复
引用 59 楼 Chen8013 的回复:
[quote=引用 58 楼 qq_36623634 的回复:]

[quote=引用 57 楼 Chen8013 的回复:]
[quote=引用 54 楼 qq_36623634 的回复:]
MAC地址不是更方便吗?

CPUID是有重复的,后了改了方案CPUID+MAC,问题就解决。

现在主板都是集成网卡,修改MAC的可能性不大吧?!

那要看你是如何获取的MAC…………

在网卡的设备属性中,可以设置一个新的MAC值,
然而“一般的方法”获取MAC,很有可能获取到的就是这个更改后的MAC。
[/quote]

说的有很道理。

但,读取硬盘的ID,还是读取MAC,目的都是为了版本保护及授权。换硬盘或修改MAC,软件检测到就认为是新客户,需重新授权即可。好像也没啥毛病。再者,普通用户,也没那个技术吧。[/quote]
修改我说的那个MAC,还真不需要什么“技术”。
若“说了方法、步骤”还不知道如何修改(真的太简单了),恐怕是“电脑白痴+智商余额不足”。
在网卡的硬件属性中更改后,然后重启电脑,
在操作系统中“各处”看到的MAC信息,都是修改过后的那个了。

如果你用MAC来“保护版权”,并且还只会读取到修改后的MAC,那么“盗版”就太容易了。
只要把“已经注册”了的一份相关信息备份下来,
然后“另一台电脑”改为相同的MAC,并“还原”相关的注册信息,就成了“正版”了。
[/quote]


技术讨论,不带耍脾气玩的。-_-"

我上面说的方案是CPUID+MAC,如果不安全,可以加密。同时,服务端对客户端认证,也是一种排除并限制MAC地址相同(信息相同)冲突的手段。
当然,按你所说的理解:用户都知道了你的版权保护的方法了,硬盘ID就安全了?
我们用的Window系统都不是正版的吧……
舉杯邀明月 2018-10-10
  • 打赏
  • 举报
回复
引用 58 楼 qq_36623634 的回复:
[quote=引用 57 楼 Chen8013 的回复:]
[quote=引用 54 楼 qq_36623634 的回复:]
MAC地址不是更方便吗?

CPUID是有重复的,后了改了方案CPUID+MAC,问题就解决。

现在主板都是集成网卡,修改MAC的可能性不大吧?!

那要看你是如何获取的MAC…………

在网卡的设备属性中,可以设置一个新的MAC值,
然而“一般的方法”获取MAC,很有可能获取到的就是这个更改后的MAC。
[/quote]

说的有很道理。

但,读取硬盘的ID,还是读取MAC,目的都是为了版本保护及授权。换硬盘或修改MAC,软件检测到就认为是新客户,需重新授权即可。好像也没啥毛病。再者,普通用户,也没那个技术吧。[/quote]
修改我说的那个MAC,还真不需要什么“技术”。
若“说了方法、步骤”还不知道如何修改(真的太简单了),恐怕是“电脑白痴+智商余额不足”。
在网卡的硬件属性中更改后,然后重启电脑,
在操作系统中“各处”看到的MAC信息,都是修改过后的那个了。

如果你用MAC来“保护版权”,并且还只会读取到修改后的MAC,那么“盗版”就太容易了。
只要把“已经注册”了的一份相关信息备份下来,
然后“另一台电脑”改为相同的MAC,并“还原”相关的注册信息,就成了“正版”了。
XBoy410 2018-10-10
  • 打赏
  • 举报
回复

引用 57 楼 Chen8013 的回复:
[quote=引用 54 楼 qq_36623634 的回复:]
MAC地址不是更方便吗?

CPUID是有重复的,后了改了方案CPUID+MAC,问题就解决。

现在主板都是集成网卡,修改MAC的可能性不大吧?!

那要看你是如何获取的MAC…………

在网卡的设备属性中,可以设置一个新的MAC值,
然而“一般的方法”获取MAC,很有可能获取到的就是这个更改后的MAC。
[/quote]

说的有很道理。

但,读取硬盘的ID,还是读取MAC,目的都是为了版本保护及授权。换硬盘或修改MAC,软件检测到就认为是新客户,需重新授权即可。好像也没啥毛病。再者,普通用户,也没那个技术吧。
舉杯邀明月 2018-10-10
  • 打赏
  • 举报
回复
引用 54 楼 qq_36623634 的回复:
MAC地址不是更方便吗?

CPUID是有重复的,后了改了方案CPUID+MAC,问题就解决。

现在主板都是集成网卡,修改MAC的可能性不大吧?!

那要看你是如何获取的MAC…………

在网卡的设备属性中,可以设置一个新的MAC值,
然而“一般的方法”获取MAC,很有可能获取到的就是这个更改后的MAC。
舉杯邀明月 2018-10-10
  • 打赏
  • 举报
回复
因为WinXP不支持STAT接口,而你的硬盘本身却是STAT的,
 在WinXP中要使用STAT硬盘的话,必须是主板支持把STAT“模拟”成IDE。
(需要主板支持,并在BIOS中进行这项设置)
因此不清楚我的这份代码读取失败,是否与这个因素有关。

还有,你不妨用我的份代码,编译成exe,在别的电脑上运行试试,
最好是Win7、Win10之类的系统。
为了“可靠测试”,建议窗体代码用这样的方式:


我现在没法找WinXP + STAT硬盘的电脑来试验,因此现在无法验证楼主所遇到的问题。
就目前我的那份代码来说,你的“0#盘”没有读取到序列号,
但硬盘型号、固件版本是读取到了的。
你可以在执行 Call CloseHandle(hDevice) 之后 ,在立即窗口中执行:
? strconv(arrData ,vbUnicode)
可以看到字符串中有你的硬盘型号 ST2000DM001-1ER164
 和固件版本 CC26 这些字符串。

至于“序列号”读取不到,有两种可能的原因:
1. STAT模拟IDE后,用这种方式获取不到序列号;
2. 传递的 stcQueryInput 参数设置不正确。
舉杯邀明月 2018-10-10
  • 打赏
  • 举报
回复
你的这组数据还真是有点怪。

这个返回的数据,你的arrData(4)的值是101,按理说arrData(100)的值就应该是0了,
 在这“之后”应该是“全0”的(因我的过程中是用的固定数组,其值就是0)。
而你的却从100到102填充了“32”(即空格符)、在103处为0(即NULL),
相当于是返回了104字节数据,这跟arrData(4)的值不一致啊……
并且,arrData(24)的值是114,比arrData(4)的值还大,这“不科学”嘛!


比如刚才我这儿运行,测试对1#盘(机械硬盘,1GB的)的信息读取:
arrData(4)的值是167,arrData(24)的值是126,
这样从arrData(126)到arrData(165)这40字节就是硬盘序列号的编码数据,
 arrData(166)就是0 (结束符 NULL),这样就共有167字节返回数据。
跟 arrData(4)的值相符,同时也与执行 lResult = DeviceIoControl(hDevice, . . . . . . )
 之后,lRetNum的值相符!
你也再看看,当此句执行后 ,lRetNum的值是多少? 是101吗…………
XBoy410 2018-10-10
  • 打赏
  • 举报
回复
MAC地址不是更方便吗?

CPUID是有重复的,后了改了方案CPUID+MAC,问题就解决。

现在主板都是集成网卡,修改MAC的可能性不大吧?!
eisldkw 2018-10-10
  • 打赏
  • 举报
回复
引用 52 楼 eisldkw 的回复:
[quote=引用 51 楼 Chen8013 的回复:]
显然你的这个“WinXP”中只有一块硬盘,物理设备为: \\.\PhysicalDrive0
调用 DiskReadSN( ) 时第2个参数传入0,才是正确的。


你的这个“WinXP系统”,是物理机还是虚拟机?
你注意一下:上面图中,在“即将跳转到函数出口”时,lRetNum的值是 114
 把arrData( )这个数组的数据给我看看,元素下标从 lRetNum的值开始的那40字节。
 理论上说是要“40字节”,不过实际上也许用不着看这么多。
 从arrData(114)到arrData(153),后面的那一部分如果有“连续的、全0的”,可以不要。

我想看看它到底是什么样的数据。
另外,你可以用工具软件(比如 HDTune )看看它显示的硬盘序列号是什么。
这样可以参考分析一下。



[/quote]

非常感谢。
eisldkw 2018-10-10
  • 打赏
  • 举报
回复
引用 51 楼 Chen8013 的回复:
显然你的这个“WinXP”中只有一块硬盘,物理设备为: \\.\PhysicalDrive0
调用 DiskReadSN( ) 时第2个参数传入0,才是正确的。


你的这个“WinXP系统”,是物理机还是虚拟机?
你注意一下:上面图中,在“即将跳转到函数出口”时,lRetNum的值是 114
 把arrData( )这个数组的数据给我看看,元素下标从 lRetNum的值开始的那40字节。
 理论上说是要“40字节”,不过实际上也许用不着看这么多。
 从arrData(114)到arrData(153),后面的那一部分如果有“连续的、全0的”,可以不要。

我想看看它到底是什么样的数据。
另外,你可以用工具软件(比如 HDTune )看看它显示的硬盘序列号是什么。
这样可以参考分析一下。



舉杯邀明月 2018-10-09
  • 打赏
  • 举报
回复
显然你的这个“WinXP”中只有一块硬盘,物理设备为: \\.\PhysicalDrive0
调用 DiskReadSN( ) 时第2个参数传入0,才是正确的。


你的这个“WinXP系统”,是物理机还是虚拟机?
你注意一下:上面图中,在“即将跳转到函数出口”时,lRetNum的值是 114
 把arrData( )这个数组的数据给我看看,元素下标从 lRetNum的值开始的那40字节。
 理论上说是要“40字节”,不过实际上也许用不着看这么多。
 从arrData(114)到arrData(153),后面的那一部分如果有“连续的、全0的”,可以不要。

我想看看它到底是什么样的数据。
另外,你可以用工具软件(比如 HDTune )看看它显示的硬盘序列号是什么。
这样可以参考分析一下。

eisldkw 2018-10-09
  • 打赏
  • 举报
回复
引用 49 楼 Chen8013 的回复:
你看不见这个吗!!!


不管是用“断点”,还是单步执行,在hDevice = CreateFile( . . . . . . . )失败后,
马上看看 Err.LastDllError 的值是多少啊!
你要让我分析失败原因,我需要的信息(分析依据)你却还跟我“保密”么!!!!!


非常感谢。以下是参数为0和为1时,抓取到的错误,请帮忙给分析一下



舉杯邀明月 2018-10-09
  • 打赏
  • 举报
回复
你看不见这个吗!!!


不管是用“断点”,还是单步执行,在hDevice = CreateFile( . . . . . . . )失败后,
马上看看 Err.LastDllError 的值是多少啊!
你要让我分析失败原因,我需要的信息(分析依据)你却还跟我“保密”么!!!!!
加载更多回复(26)

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧