今天在写个工具,功能是将一些数据写到磁盘的绝对扇区上.
但是发现ReadFile没问题,可是WriteFile总是报87错误(参数不正确).
Google上查了一会,发现碰到问题的人不少,可惜没有正确答案....
没辙,还是啃MSDN,终于还是自己解决了~呵呵
赶紧记下来,免得忘了...
其实主要是写入的数据大小,必须是BytesOfSector大小的倍数,一般是512字节,ReadFile却无所谓...
另外,MSDN上还说,WriteFile前最好先用FSCTL_LOCK_VOLUME或者FSCTL_DISMOUNT_VOLUME将磁盘锁定或卸载,不过我试下来好像没什么影响...
代码摘录如下:
1
UINT CDevInfo::Write(LPVOID pData, UINT nSize)
2 {
3 if ( ! pData && nSize <= 0 )
4 return 0 ;
5
6 TCHAR szDevName[ 30 ];
7 _stprintf(szDevName, _T( " \\\\.\\PHYSICALDRIVE%d " ), m_nDevNum); // DeviceNumber
8
9 HANDLE hDev = ::CreateFile(szDevName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
10 if (hDev == INVALID_HANDLE_VALUE)
11 return 0 ;
12
13 DWORD dwCount;
14 if ( ! ::DeviceIoControl(hDev, FSCTL_LOCK_VOLUME, NULL, 0 , NULL, 0 , & dwCount, NULL))
15 return 0 ;
16
17 DWORD dwWritten( 0 );
18 ::SetFilePointer(hDev, SECTOR_NUM * GetSectorSize(), NULL, FILE_BEGIN);
19 if ( ! ::WriteFile(hDev, pData, nSize, & dwWritten, NULL))
20 dwWritten = 0 ;
21
22 ::DeviceIoControl(hDev, FSCTL_UNLOCK_VOLUME, NULL, 0 , NULL, 0 , & dwCount, NULL);
23 ::CloseHandle(hDev);
24 return dwWritten;
25 }
2 {
3 if ( ! pData && nSize <= 0 )
4 return 0 ;
5
6 TCHAR szDevName[ 30 ];
7 _stprintf(szDevName, _T( " \\\\.\\PHYSICALDRIVE%d " ), m_nDevNum); // DeviceNumber
8
9 HANDLE hDev = ::CreateFile(szDevName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
10 if (hDev == INVALID_HANDLE_VALUE)
11 return 0 ;
12
13 DWORD dwCount;
14 if ( ! ::DeviceIoControl(hDev, FSCTL_LOCK_VOLUME, NULL, 0 , NULL, 0 , & dwCount, NULL))
15 return 0 ;
16
17 DWORD dwWritten( 0 );
18 ::SetFilePointer(hDev, SECTOR_NUM * GetSectorSize(), NULL, FILE_BEGIN);
19 if ( ! ::WriteFile(hDev, pData, nSize, & dwWritten, NULL))
20 dwWritten = 0 ;
21
22 ::DeviceIoControl(hDev, FSCTL_UNLOCK_VOLUME, NULL, 0 , NULL, 0 , & dwCount, NULL);
23 ::CloseHandle(hDev);
24 return dwWritten;
25 }