📄 biosdisk.cpp
字号:
#include <windows.h>
#include <winioctl.h>
#define TESTMSG MessageBox(hwnd,"I know",NULL,MB_OK)
/******************************************************************
软盘扇区绝对读取函数 WinBiosDisk()
作者: 周化 编译平台: Virusal C++ 6.0
为了方便, 本函数的参数设计得同 Turbo C 2.0 的 biosdisk() 函数一样.
本函数还有以下两个缺点以待改进:
1.本函数还只能读能读 A: 和 B:,即只能对软盘操作
2.不能改变磁盘扇区大小,只能是标准的 512 个字节。
参数说明:
command 操作:
0 重置磁盘
2 读扇区
3 写扇区
4 校验磁道
5 格式化磁道
8 得到设备参数 (int 1EH)
drive 驱动器 A:=0 B:=1
head 磁头号,范围 0 - 1
track 磁道号,范围 0 - 84 ( 80 - 84 为特殊磁道,通常用来加密 )
sector 扇区号,范围 0 - 255 ( 19 - 255 为非标准扇区编号,通常用来加密)
nsectors 每次读或写的扇区数,不能超出每磁道的最大扇区数
buffer 数据写入或读出的缓冲区,大小为 512 个字节
返回值 ( 同 Int 13H ):
0x0 成功
0x1 无效的命令
0x3 磁盘被写保护
0x4 扇区没有找到
0xa 发现坏扇区
0x80 磁盘没有准备好
******************************************************************/
int WinBiosDisk(unsigned char command,unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char nsectors,void *buffer)
{
HANDLE hd;
DWORD dw;
//int13 寄存器参数块
typedef struct tagPackage
{
void *buffer; // ebx 寄存器
unsigned char drive; // edx 寄存器
unsigned char head; //
unsigned short edx_high; //
unsigned char sector; // ecx 寄存器
unsigned char track; //
unsigned short ecx_high; //
unsigned char number; // eax 寄存器
unsigned char option; //
unsigned short eax_high; //
unsigned int edi; // edi 寄存器
unsigned int esi;
unsigned int eflag;
} PK;
PK pk;
memset(&pk,0,sizeof PK);
pk.buffer=buffer;
pk.drive=drive;
pk.head=head;
pk.sector=sector;
pk.track=track;
pk.option=command;
pk.number=nsectors;
if(command==0x18)pk.edi=(int)buffer;
hd=CreateFile("\\\\.\\vWin32",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
if(hd==NULL)return 1;
DeviceIoControl(hd,4,&pk,0x1c,&pk,0x1c,&dw,NULL);
if(command==0x8)memcpy(buffer,(unsigned char *)pk.edi,11);
CloseHandle(hd);
return pk.option;
}
int WinReadDisk(unsigned char drive,unsigned char sector,unsigned char nsectors,void *buffer)
{
HANDLE hd;
DWORD dw;
struct PARA
{
unsigned int start_sector;
unsigned short number;
void *buffer;
}para;
typedef struct tagPackage
{
DWORD ebx;
DWORD edx;
DWORD ecx;
DWORD eax;
DWORD edi;
DWORD esi;
DWORD eflag;
} REGPACK;
REGPACK pk;
para.start_sector=sector;
para.number=nsectors;
para.buffer=buffer;
memset(&pk,0,sizeof REGPACK);
memset(¶,0,sizeof (struct PARA));
pk.eax=0x7305;
pk.ecx=0xffff;
pk.edx=drive+1;
pk.esi=0;
pk.ebx=(DWORD)¶
hd=CreateFile("\\\\.\\vWin32",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
if(hd==NULL)return 1;
DeviceIoControl(hd,6,&pk,0x1c,&pk,0x1c,&dw,NULL);
CloseHandle(hd);
return pk.eflag;
}
/***********************************
制作密纹函数 MakeSector()
参数同上
***********************************/
int MakeSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer)
{
int i,ret,retry;
unsigned char ctemp[513],cmd[3]={5,3,2};
for(i=0;i<3;i++)
{
retry=5;
while(retry)
{
if(i==0)
{ctemp[0]=track;
ctemp[1]=head;
ctemp[2]=sector;
ctemp[3]=2;
}
else if(i==1)
memcpy(ctemp,buffer,512);
ret=WinBiosDisk(cmd[i],drive,head,track,sector,1,ctemp);
if(ret==0)break;
else if(ret==0x3)return ret;
WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,ctemp); //重置磁头
retry--;
}
if(!retry)return ret;
}
ret=memcmp(ctemp,buffer,512);
if(ret)return 0xffff;
else return 0;
}
/************************************
读取密纹函数 ReadSector()
参数同上
************************************/
int ReadSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer)
{
int i,retry=5;
while(retry)
{
i=WinBiosDisk(2,drive,head,track,sector,1,buffer);
if(i==0)break;
WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,buffer); //重置磁头
retry--;
}
return i;
}
int WriteSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer)
{
int i,retry=5;
char *buffer1;
buffer1=new char[8196];
while(retry)
{
i=WinBiosDisk(3,drive,head,track,sector,1,buffer);
if(i==0)break;
WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,buffer1); //重置磁头
retry--;
}
delete []buffer1;
return i;
}
/************************************************
演示程序
本程序用两种方法调用了上列函数:
1, 直接调用以上三个函数。
2, 用我自己编的动态链接库 BIOS.DLL
这个库中有以上的三个函数,方便用其它语
言调用。
*************************************************/
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
HINSTANCE hInst;
unsigned char drive,is_use_dll;
unsigned char para[3],buffer[2][512];
static HWND hwndButton[9],hwndEdit[5],hwndSt,hwndSt1,hwndSt2,hwndtemp,hwndCh[4];
static int text_x=200,text_y=55,win_x=490,win_y=345,cxChar,cyChar,absX=11,ascX=49;
char szEditName[]="Hex Edit";
typedef struct tagHEXEDIT
{
int start,line,totle,is_show,is_readonly;
HWND hwnd;
unsigned char *buffer;
}HEXEDIT;
static HEXEDIT *pHexEdit[100],*pNow;
//使用读动态库中的 MakeSector()
int DllMakeSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer)
{
typedef int (*FPBIOS)(unsigned char,unsigned char,unsigned char,unsigned char,void *);
HINSTANCE hd;
FPBIOS MkSector;
hd=LoadLibrary("BIOS.DLL");
if(hd==NULL)return 0xfffc;
MkSector=(FPBIOS )GetProcAddress(hd,"MakeSector");
if(MkSector==NULL)return 0xfffd;
return MkSector(drive,head,track,sector,buffer);
}
//使用动态库中的 ReadSector()
int DllReadSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer)
{
typedef int (*FPBIOS)(unsigned char,unsigned char,unsigned char,unsigned char,void *);
int ret;
HINSTANCE hd;
FPBIOS RdSector;
hd=LoadLibrary("BIOS.DLL");
if(hd==NULL)return 0xfffc;
RdSector=(FPBIOS)GetProcAddress(hd,"ReadSector");
if(RdSector==NULL)return 0xfffd;
ret=RdSector(drive,head,track,sector,buffer);
FreeLibrary(hd);
return ret ;
}
int DllWriteSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer)
{
typedef int (*FPBIOS)(unsigned char,unsigned char,unsigned char,unsigned char,unsigned char,unsigned char,void *);
int ret;
HINSTANCE hd;
FPBIOS WtSector;
hd=LoadLibrary("BIOS.DLL");
if(hd==NULL)return 0xfffc;
WtSector=(FPBIOS)GetProcAddress(hd,"WinBiosDisk");
if(WtSector==NULL)return 0xfffd;
ret=WtSector(drive,3,head,track,sector,1,buffer);
FreeLibrary(hd);
return ret;
}
WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
static char szAppName[] = "磁盘编辑";
HWND hwnd ;
MSG msg;
WNDCLASSEX wndclass ;
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon =NULL ;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = LoadIcon (NULL,IDC_ARROW);
RegisterClassEx (&wndclass) ;
hInstance=hInst;
hwnd = CreateWindow(szAppName,szAppName,
WS_SYSMENU|WS_MINIMIZEBOX,
100,100,win_x,win_y,
NULL,NULL,hInstance,NULL) ;
ShowWindow (hwnd, SW_SHOW) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
void ErrorMsg(HWND hwnd,int i)
{
char buffer[100];
switch(i)
{
case 0:
wsprintf(buffer,"操作成功!");
break;
case 1:
wsprintf(buffer,"无效的操作!");
break;
case 2:
wsprintf(buffer,"地址标记没有找到!");
break;
case 3:
wsprintf(buffer,"磁盘被写保护!");
break;
case 4:
wsprintf(buffer,"扇区没有找到!");
break;
case 6:
wsprintf(buffer,"磁盘被更换!");
break;
case 0xa:
wsprintf(buffer,"发现坏扇区!");
break;
case 0x80:
wsprintf(buffer,"磁盘没有准备好");
break;
case 0xfffc:
wsprintf(buffer,"打开动态链接库 BIOS.DLL 失败!");
break;
case 0xfffd:
wsprintf(buffer,"BIOS.DLL 没有 export 函数 ");
break;
case 0xffff:
wsprintf(buffer,"数据错误!");
break;
default:
wsprintf(buffer,"错误代码: 0x%X",i);
break;
}
if(i)MessageBoxEx(hwnd,buffer,NULL,MB_OK|MB_ICONSTOP,0x804);
else MessageBoxEx(hwnd,buffer,"成功",MB_OK|MB_ICONINFORMATION,0x804);
}
void SubProc(HWND hwnd,int mode)
{
char ctemp[600];
int t[3];
int i;
drive=0;
is_use_dll=0;
if(SendMessage(hwndButton[5],BM_GETCHECK,0,0)==BST_CHECKED)drive=1;
if(SendMessage(hwndButton[7],BM_GETCHECK,0,0)==BST_CHECKED)is_use_dll=1;
for(i=0;i<3;i++)
{
GetWindowText(hwndEdit[i],ctemp,512);
t[i]=atoi(ctemp);
}
if(t[2]==0||t[2]>255)
MessageBoxEx(hwnd,"扇区号必须在1至255之间",NULL,MB_OK,0x804);
else if(t[0]>1)
MessageBoxEx(hwnd,"磁头号只能为0或1",NULL,MB_OK,0x804);
else if(t[1]>84)
MessageBoxEx(hwnd,"磁道号必须在0至84之间",NULL,MB_OK,0x804);
else
{
for(i=0;i<3;i++)para[i]=t[i];
switch(mode)
{
case 0:
if(is_use_dll)i=DllMakeSector(drive,para[0],para[1],para[2],buffer[0]);
else i=MakeSector(drive,para[0],para[1],para[2],buffer[0]);
break;
case 1:
if(is_use_dll)i=DllWriteSector(drive,para[0],para[1],para[2],buffer[0]);
else i=WriteSector(drive,para[0],para[1],para[2],buffer[0]);
break;
case 2:
if(is_use_dll)i=DllReadSector(drive,para[0],para[1],para[2],buffer[1]);
else i=ReadSector(drive,para[0],para[1],para[2],buffer[1]);
if(i)memset(buffer[1],0,512);
InvalidateRect(hwndEdit[4],NULL,TRUE);
}
ErrorMsg(hwnd,i);
}
}
void outxy(HWND hwnd,int x,int y,unsigned char c)
{
char p[10];
HDC hdc;
HideCaret(hwnd);
hdc=GetDC(hwnd);
SelectObject(hdc,GetStockObject(DEFAULT_GUI_FONT));
wsprintf(p,"%c",isprint(c)?c:'.');
TextOut(hdc,(ascX+absX+x)*cxChar,y*cyChar,p,1);
wsprintf(p,"%02X",c);
TextOut(hdc,(absX+x*3)*cxChar,y*cyChar,p,2);
ReleaseDC(hwnd,hdc);
ShowCaret(hwnd);
}
LRESULT CALLBACK EditProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -