代码:

#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;
}


问题:


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


问题:


我该如何修复WriteFile,使其在16个扇区后不会失败并...
如何修复GetBuffer,使其实际上产生512缓冲区而不是528?


笔记
该应用程序是ANSI C,程序正在以admin身份运行。

最佳答案

我无法说出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;
}

10-08 06:16