首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

100分,写磁盘扇区数据得到异常结果

2012-03-26 
100分,写磁盘扇区数据得到错误结果定义结构体并且#pragmapack(1)myMBR的长度刚好是一个扇区512BstructPart

100分,写磁盘扇区数据得到错误结果
定义结构体并且#pragma   pack(1)
myMBR的长度刚好是一个扇区512B


struct   Partition                               //长度16
{
unsigned   char   boottable;
unsigned   char   start_head;
unsigned   short   start_sec_cyl;
unsigned   char   parttype;
unsigned   char   end_head;
unsigned   short   end_sec_cyl;
unsigned   long   part_beg;
unsigne
struct   Partition   myPartition;d   long   plen;
};
//MBR或EBR
struct   MBR                                         //长度512
{
unsigned   char   master_boot[446];
struct   Partition   myPartition[4];
unsigned   short   lasttwo;
};
struct   MBR   myMBR[32];                     //最多保存32个mbr或ebr


读扇区数据时得到正确答案,但写磁盘扇区数据得到错误结果


myMBR_powersearch[0].myPartition[1].part_beg
我给它赋值10233405(十六进制的9C263D)
然后整个myMBR结构体(512B)写到其他的扇区
但为什么再读新写的扇区myMBR_powersearch[0].myPartition[1].part_beg时值是
4096575(十六进制的3E823F)


我就得是写值时的错误,高低位的问题,但搞了好久都不明白,请各位指教一下

[解决办法]
没做过,学习
[解决办法]
绝对读写硬盘扇区的例程
[http://www.china-askpro.com/msg21/qa45.shtml]

DWORD _stdcall CVXD_W32_DeviceIOControl(LPDIOC lpDIOCParms,
CLIENT_STRUCT *pRegs)
{
DWORD dwRetVal = 0,retu;
DWORD *i;
PVMMCB hVM;
DIOC_REGISTERS *lpReg,*lpOutReg;
CLIENT_STRUCT saveregs;
DWORD PageNum;
WORD PageOff;
DWORD Address;
DWORD V86PageNum,MyPage;
WORD seg,offset;

hVM=Get_Cur_VM_Handle();
i=(DWORD *)(lpDIOCParms-> lpvOutBuffer);
lpReg=(DIOC_REGISTERS *)(lpDIOCParms-> lpvInBuffer);
lpOutReg=(DIOC_REGISTERS *)(lpDIOCParms-> lpvOutBuffer);
switch(lpDIOCParms-> dwIoControlCode)
{
.
.
.
case 2:
if(lpDIOCParms-> cbInBuffer!=sizeof(DIOC_REGISTERS))
return dwRetVal=-1;

//保存当前虚拟机的寄存器状态
_asm push edi
_asm lea edi,saveregs
VMMCall(Save_Client_State);
_asm pop edi

//输入的参数,具体怎么用看INT13的说明吧
_ClientEAX=lpReg-> reg_EAX;
_ClientEDX=lpReg-> reg_EDX;
_ClientECX=lpReg-> reg_ECX;
_ClientEFlags=lpReg-> reg_Flags;

/* 以下这一段是编写这个VxD时要考虑的主要问题:把缓冲区的地址映射入虚拟86的地址
区,Win32中用的都是线性地址,先根据它求出页面号,再把缓冲区所在的页映射到虚拟86区
中去,下面程序中有一个Bug,它没有考虑到缓冲区所占页面大于一页时的情形,事实上,缓
冲区可能处在叶面的边界上,而且它的大小可能超过一页,这些都要根据上面参数中给出
的缓冲区大小计算,当时我嫌麻烦,随便应付了一下.用的时候要把这段代码改一下
*/
PageNum=(lpReg-> reg_EBX)> > 12;
PageOff=(lpReg-> reg_EBX)&0xfff;
_asm{
push 0
push 1
push 10
push hVM
push PageNum
}
VMMCall(_LinMapIntoV86);
_asm add esp,14h
_asm mov retu,eax
_asm mov MyPage,edx //返回的页面号在edx寄存器中
if(retu==0) return 3;//这是我自己胡乱选的错误码,你可以自己定成
//其它值
Address=(MyPage < <12)+PageOff;//计算新的线性地址
seg=LOWORD(Address> > 4); //把线性地址转化成传统的段:偏
offset=LOWORD(Address-(seg < <4)); //移量的形式
_ClientAltES=seg;//这里一定不能弄错了,在Win32 Ring3程序中用的


//是_ClientES,而虚拟86方式下用的段寄存器则在
//_ClientAltES中,所以要用它
_ClientBX=offset;

//xixi,好戏开始了
VMMCall(Begin_Nest_V86_Exec);//这一句使得系统转入虚拟86方式
_asm mov eax,13h
VMMCall(Exec_Int);//发出int 13h中断调用
//保存返回值
if(lpDIOCParms-> cbOutBuffer==sizeof(DIOC_REGISTERS))
{
lpOutReg-> reg_Flags=_ClientEFlags;
lpOutReg-> reg_EAX=_ClientEAX;
lpOutReg-> reg_EBX=_ClientEBX;
lpOutReg-> reg_ECX=_ClientECX;
lpOutReg-> reg_EDX=_ClientEDX;
}
End_Nest_Exec();//退出虚拟86方式

//轻轻地我走了,正如我轻轻地来,我挥一挥衣袖,不带走一片云彩
_asm push esi
_asm lea esi,saveregs
VMMCall(Restore_Client_State);
_asm pop esi
//这一段取消原来的映射
VMMCall(_GetNulPageHandle);
_asm mov PageNum,eax
_asm{
push 0
push 0
push 1
push 10
push hVM
push PageNum
}
VMMCall(_MapIntoV86);
_asm add esp,18h

//OK
return dwRetVal=0;
}
return dwRetVal;
}
[解决办法]
读写硬盘扇区的C语言程序
[http://blog.csdn.net/cutemouse/archive/2001/09/16/6066.aspx]

代码太多了,
就不贴了,
楼主自己打开连接看看吧
[解决办法]
mark
[解决办法]
http://dev.csdn.net/article/10/10610.shtm


[解决办法]
http://blog.csdn.net/todototry/archive/2007/03/05/1521249.aspx
C++版本,mbr管理工具代码,呵呵^_^okokok
[解决办法]
牛人啊,学习

热点排行