这个问题在这里已有答案:
首先,我看到了几个链接......
Read and write hard disk sector directly and efficiently
Read specific sector on hard drive using C language on windows
我正在尝试做几乎相同的事情 . 我遇到的问题是多次读取设备,因此我可以从DEVICE(USB)存储读取的字节,然后将它们写入文件 .
这就是我想要做的......
-
声明变量
-
初始化变量
-
SetFilePointer()
-
ReadFile()
-
将读取的字节输出到文件
-
使用ReadFile()获取更多字节
-
再次将读取的字节输出到同一文件
-
重复6和7(实际上只重复4和5)
这似乎不起作用 . 我想读取x个字节并将这些值存储到一个文件中然后读取更多并将这些值存储在与上次相同的文件中 . 我希望它重复这个过程,直到它读到设备的末尾 . 我希望这个程序适用于任何大小的设备 . 如果我可以把它放在一个循环中,那么我可以读写无限大小的设备 .
这是一个如何读/写,所以我也想反过来 . 读取文件中的值,然后将其写入设备 .
我使用的是128MB USB . 它包含131858432字节 . 如果需要更多信息,我会发布它,如果我有它 .
我的代码:
#include <windows.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
BYTE sector[0x400] = {0};
DWORD bytesRead;
HANDLE device = NULL;
int numSector = 1;
int maxRead = 1;
FILE *readChar = fopen("G:\\usb_128MB_Dec2.txt", "w+");
device = CreateFile("\\\\.\\L:", // Drive to open
GENERIC_READ|GENERIC_WRITE, // Access mode
FILE_SHARE_READ|FILE_SHARE_WRITE, // Share Mode
NULL, // Security Descriptor
OPEN_EXISTING, // How to create
0, // File attributes
NULL); // Handle to template
if(device == INVALID_HANDLE_VALUE)
{
printf("CreateFile: %u\n", GetLastError());
system("pause");
return 1;
}
// set the file pointer for first time
SetFilePointer(device, numSector, NULL, FILE_BEGIN);
// Edit 1. Comment 2.
if(GetLastError() != NO_ERROR)
{
printf("GetLastError: %d\n", GetLastError());
goto end; // end: is before closing files or handles at end of main()
}
// read device for maxRead number of bytes and store the reading into a file
ReadFile(device, sector, maxRead, &bytesRead, NULL);
fprintf(readChar, "%d\n", sector[0]);
// This part of code does not act like expected
SetFilePointer(device, numSector, NULL, FILE_CURRENT);
if(!ReadFile(device, sector, maxRead, &bytesRead, NULL))
printf("err\n");
else
fprintf(readChar, "%d", sector[0]);
end: // Edit 1. Comment 2.
CloseHandle(device);
fclose(readChar);
system("pause");
return 0;
}
屏幕输出:
GetLastError: 87
文件输出:
Nothing is in the file.
该文件应包含8位十进制值而不是无或0 .
编辑1:
87表示INVALID PARAMETER . 你的读取必须是扇区对齐的,所以你不能寻求偏移1,但只有0,sector_size,2 * sector_size,...,n * sector_size,你的读取也是扇区大小和你的内存缓冲区的倍数必须与sector_size对齐 . 可以使用GetDiskFreeSpace检索扇区大小,并且可以使用VirtualAlloc获取对齐的内存 . 也许你应该检查FSCTL_LOCK_VOLUME和FSCTL_DISMOUNT_VOLUME .
这是用于一次读取设备的其他代码
#include <windows.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
BYTE sector[0x200] = {0};
DWORD bytesRead;
HANDLE device = NULL;
int numSector = 1;
int maxRead = 0x200;
long long int i;
FILE *readChar = fopen("G:\\usb_128MB_Dec.txt", "w+");
device = CreateFile("\\\\.\\L:", // Drive to open
GENERIC_READ|GENERIC_WRITE, // Access mode
FILE_SHARE_READ|FILE_SHARE_WRITE, // Share Mode
NULL, // Security Descriptor
OPEN_EXISTING, // How to create
0, // File attributes
NULL); // Handle to template
if(device == INVALID_HANDLE_VALUE)
{
printf("CreateFile: %u\n", GetLastError());
system("pause");
return 1;
}
SetFilePointer(device, numSector, NULL, FILE_BEGIN);
if (!ReadFile(device, sector, maxRead, &bytesRead, NULL))
{
printf("ReadFile: %u\n", GetLastError());
goto end;
}
else
{
printf("Success!\n");
}
if(readChar == NULL)
{
printf("Did not open file. Exit 2.");
goto end;
}
for(i = 0; i < maxRead - 1; i++)
{
fprintf(readChar, "%d\n", sector[i]);
}
fprintf(readChar, "%d", sector[i]); // so the previous loop wont add \n to the last read wanted
end:
CloseHandle(device);
fclose(readChar);
system("pause");
return 0;
}
文件内容:
235
88
...
读取的每个字节以十进制值存储在新行上 .
所以我可能会更好地理解我正在尝试做什么,这里是代码:
// What I want to do..
// This part works
SetFilePointer(device, numSector, NULL, FILE_BEGIN);
ReadFile(device, sector, maxRead, &bytesRead, NULL);
for(i = 0; i < size_of_device - 0x200; i += 512)
{
for(j = 0; j < maxRead; j++)
{
fprintf(readChar, "%d\n", sector[j]);
}
// stops working
SetFilePointer(device, numSector, NULL, FILE_CURRENT);
ReadFile(device, sector, maxRead, &bytesRead, NULL);
}
for(j = 0; j < maxRead - 1; j++)
{
fprintf(readChar, "%d\n", sector[j]);
}
fprintf(readChar, "%d", sector[j]);
// .. end of what i want to do
编辑2:现在多次阅读 .
#include <windows.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
BYTE sector[0x200] = {0};
DWORD bytesRead;
HANDLE device = NULL;
//int numSector = 512; // original value was 1 not 512 but variable is not needed
int maxRead = 512;
int i, j, k = 0, l; // loop variables
FILE *readChar = fopen("G:\\wii u hdd image\\usb_128MB_Dec3.txt", "w+");
if(readChar == NULL)
{
printf("Error creating file.\n");
goto end;
}
device = CreateFile("\\\\.\\L:", // Drive to open
GENERIC_READ|GENERIC_WRITE, // Access mode
FILE_SHARE_READ|FILE_SHARE_WRITE, // Share Mode
NULL, // Security Descriptor
OPEN_EXISTING, // How to create
0, // File attributes
NULL); // Handle to template
// If device does not contain a handle value
if(device == INVALID_HANDLE_VALUE)
{
printf("Error. GetLastError: %u\n", GetLastError());
goto end;
}
for(i = 0; i < maxRead*503; i++) // maxRead * 503 = 257536
{
// If ReadFile() fails it will exit the program without adding a '\n' to the readChar file.
if(!ReadFile(device, sector, maxRead, &bytesRead, NULL))
{
printf("Error of ReadFile(). GetLastError(): %u\n", GetLastError());
goto end;
}
// If this is the first time through the loop then '\n' won't be added to the readChar file.
if(i != 0)
{
fprintf(readChar, "\n");
system("cls");
printf("%.2f%%\n", (i / 257536));
}
// Runs for 511 times. Then prints the 512th decimal value after the loop.
for(j = 0; j < maxRead - 1; j++)
{
fprintf(readChar, "%d\n", sector[j]);
}
fprintf(readChar, "%d", sector[j]);
}
end:
CloseHandle(device);
fclose(readChar);
system("pause");
return 0;
}
编辑3:
这个问题在另一篇文章中没有得到回答 . 这些帖子表示答案不是该主题 Headers 中问题的答案 . 请仔细阅读 Headers . 提供的“答案”是关于SetFilePointer . 这里的一个答案也不是答案 . 这都是因为所谓的答案都不包含如何在C中读/写HDD / USB字节 .
1 回答
87表示INVALID PARAMETER .
你的读取必须是扇区对齐的,所以你不能寻求偏移1,但只有0,sector_size,2 * sector_size,...,n * sector_size,你的读取也是扇区大小和你的内存缓冲区的倍数必须与sector_size对齐 .
可以使用
GetDiskFreeSpace
检索扇区大小,并使用VirtualAlloc
获取对齐的内存 .也许你应该检查
FSCTL_LOCK_VOLUME
和FSCTL_DISMOUNT_VOLUME
.Edit
因为直接读取(或写入)没有缓冲,如果你想在更小的尺寸和扇区尺寸上操作,你必须自己处理缓冲 .
该代码使用一个扇区缓冲方案实现从任意位置读取单个字节 . 免责声明:需要通过测试 . 小心可能的错误 .
GetMyDeviceByte
和GetMyDeviceBytes
是针对小字节传输的随机搜索 . 如果有人需要按顺序传输大量数据,那么SetMyDevicePos
和LoadNextMyDeviceSector
在main
中的速度要快得多 .我更愿意用C编写这段代码 .