gpt4 book ai didi

c - 如何修复创建缓冲区并将其直接写入磁盘(WriteFile)

转载 作者:行者123 更新时间:2023-11-30 15:46:05 30 4
gpt4 key购买 nike

代码:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <Windows.h>

HANDLE creatFile(void);
long WriteBuffer(HANDLE);
char * GetBuffer(void);

void main(void)
{
HANDLE hFile;
printf("CreateFile: ");
hFile = creatFile();
if(hFile != NULL)
{
WriteBuffer(hFile);
FlushFileBuffers(hFile);
}
CloseHandle(hFile);
printf("\n\rDone");
getchar();
}

HANDLE creatFile(void)
{
HANDLE hFile;
LPCWSTR sFileName = L"\\\\.\\E:";
DWORD dwDesiredAccess = GENERIC_WRITE;
DWORD fShareMode = FILE_SHARE_WRITE | FILE_SHARE_WRITE;
DWORD fCreationDisposition = OPEN_EXISTING;
DWORD fFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;

hFile = CreateFile(sFileName, dwDesiredAccess,fShareMode,
NULL, fCreationDisposition, fFlagsAndAttributes,
NULL);

if (hFile == INVALID_HANDLE_VALUE)
{
hFile = NULL;
printf("INVALID_HANDLE_VALUE: ");

switch (GetLastError())
{
case 5:
printf("\n\r Administrative Account required to run this program\n\r");
break;
case 87:
printf("\n\r Invalid Parameter in CreateFile Call \n\r");
break;
default:

printf("Error %d\n",GetLastError());
break;
}




return NULL;
}
else
{
printf("Attached -> %d\n\r",hFile);
return hFile;
}
}


long WriteBuffer(HANDLE hFile)
{
char *str = GetBuffer(); // x 64 will give us 512 (sector sized buffer) ;
DWORD bytesWritten;
long totalBytesWritten = 0;
long idx = 0;
int len = strlen(str);

for(idx = 0; idx < 100000; idx ++)
{

if(WriteFile(hFile, str, 512 * sizeof(char), &bytesWritten, NULL))
{

totalBytesWritten += bytesWritten;
printf("Sectors Written : %d\r",idx+1);
}
else
{
int le = GetLastError();
printf("Last Error : %d\r",GetLastError());
break;
}
}
printf("\n\r");
printf("Bytes Written: %d\n\r", totalBytesWritten);
printf("Handle -> %d\n\r",hFile);
return totalBytesWritten;
}

char * GetBuffer(void)
{
int i = 0, idx = 0;
const char * cstr_init = "ERASED1 ";
char *buffer = (char*)malloc(512);
char word2[512];

for (idx = 0; idx < 512; idx+=8) {
for (i = 0; i < 8; i++) {
buffer[idx+i] = cstr_init[i];
if(strlen(buffer) == 512)
break;
}
}


return buffer;
}

问题:

  1. char * GetBuffer 中有 16 字节的无关数据。我修改了 WriteFile,使其只写入缓冲区实际保存的 512 个(而不是 528 个)字符。
  2. 写入 16 个扇区后 - WriteFile 失败,GetLastError = 5(访问被拒绝)

问题:

  1. 如何修复 WriteFile,使其在 16 个扇区后不会失败并且...

  2. 如何修复 GetBuffer,使其实际上生成 512 缓冲区而不是 528?

注释该应用程序是 ANSI C,并且该程序正在以管理员身份运行。

最佳答案

我无法用 WriteFile() 来说明错误,但是,您的字符串操作遇到了问题。

C 字符串以 null 结尾,即字符串文字 "abc" 实际上是一个字符数组,例如:{'a','b','c','\0'} 所有 str...() 操作都依赖于这一事实。任何地方都没有存储有关字符串长度的信息,仅存储了预计以 '\0' 结尾的事实。

您的 GetBuffer() 函数已改进:

char * GetBuffer(void)
{
int i = 0, idx = 0;
const char * cstr_init = "ERASED1 ";
char *buffer = malloc(513); // Space for a '\0'

for (idx = 0; idx < 512; idx+=8) {
for (i = 0; i < 8; i++) {
buffer[idx+i] = cstr_init[i];
}
}
}

您在 strlen() 中得到了奇怪的结果,因为它查找 '\0' 并且只在 528 字节处找到一个,读取的内容超出了 512 字节malloced 正在调用未定义的行为,您可能在 513 字节处找到了“\0”,或者从未找到过。

其他评论,在调用 GetBuffer() 之后,你永远不会 free() 返回的 char * ,这是内存泄漏,因为它是在该上下文之外分配和丢失。另外,GetBuffer() 的更好实现是:

char * GetBuffer(void)
{
const char * cstr_init = "ERASED1 ";
const int cstr_init_len = strlen(cstr_init);
char * buffer = calloc(1,513); // Guaranteed zeroed
int i;
for (i = 0; i < 512; i+=8) {
memcpy(buffer+i, cstr_init, cstr_init_len);
// Or strcpy(buffer+1, cstr_init);
// Or strcat(buffer, cstr_init); // Inefficient because each call runs from buffer[0] to find a '\0' for where to start appending
}
return buffer;
}

关于c - 如何修复创建缓冲区并将其直接写入磁盘(WriteFile),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18625915/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com