1

Тема: Зчитування з диску

Добрий день. Пишу утиліту для зчитування бінарних даних з файлової системи диска. При запуску потрібно вказати номер диска, який зчитується і номер сектору, який зчитується. Завдання - прочитати дані які заховані в комірці бінарного файлу, на яку вказує вказівник (В моєму випадку це зміщення 510 байт від початку сектору диска). Власне проблема: змінна типу "DWORD" має розмір - 4 байта. Потрібні мені значення швидше за все типу "long". Тому, коли я хочу отримати дані з комірки я відповідно отримую невірне значення. Іншими способами як через функцію ReadFile я не знаю як реалізувати ідею. Прошу допомоги. Власне ось сам код:

#include "mbr.h"
 
char    *concat(const char *s1, const char *s2)
{
    char *result;
 
    if(!(result = (char *)malloc(strlen(s1) + strlen(s2) + 1)))
        return NULL;
    strcpy(result, s1);
    strcat(result, s2);
    return (result);
}
 
void    ReadSect(const char *dsk, unsigned long sector, int offset)
{
    DWORD   dwRead;   
    HANDLE  hDisk;
    char    *buff;
    int     *ptr;
 
    buff = (char*)malloc(sizeof(char) * 1024);
    dwRead = (long unsigned int)512;
    printf("SIZE OF dwRead %I64i\n", sizeof(dwRead));
    hDisk = CreateFile(dsk, GENERIC_READ, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
    SetFilePointer(hDisk, sector * 512, 0, FILE_BEGIN);
    ReadFile(hDisk, buff, 512, &dwRead, 0);
    ptr = (int*)(buff + offset);
    printf("OFFSET DATA: %i\n", *ptr);
    CloseHandle(hDisk);
}
 
int     main(int argc, char **argv)
{
    int     sector; 
    char    *dsk;
 
    if (argc == 3)
    {
        sector = atoi(argv[2]);
        dsk = concat("\\\\.\\PhysicalDrive", argv[1]);
        ReadSect(dsk, sector, 510);
    }
    else
        printf("%s\n", "Usage: MBRInfo.exe [Disk Number] [Number of Sector]");
    return (0);
}
Подякували: PRY1

2 Востаннє редагувалося koala (18.02.2019 12:43:00)

Re: Зчитування з диску

LONG у Win32 має ті самі 32 біти, що й DWORD, тільки він знаковий (щоб не було непорозумінь: long та int у Win32 - одне й те саме).
І я не бачу, щоб ви читали від початку сектора - бо розмір сектора не обов'язково 512 байт (гляньте GetDiskFreeSpace).

SetFilePointer(hDisk, sector * 512 + offset, NULL, FILE_BEGIN);

має розв'язувати вашу проблему для невеликих дисків; для великих треба використовувати щось на кшталт LARGE_INTEGER - в lDistanceToMove іде LowPart, в lpDistanceToMoveHigh - &HighPart, а присвоювати треба QuadPart:

LARGE_INTEGER liOffset;
liOffset.QuadPart = sector * 512ll; //ще раз, тут має бути не 512!
SetFilePointer(hDisk, liOffset.LowPart, &liOffset.HighPart, FILE_BEGIN);

Ну і якби ви написали, що намагаєтеся зробити - можливо, щось би ще підказав.

Подякували: PRY1

3 Востаннє редагувалося koala (18.02.2019 12:45:17)

Re: Зчитування з диску

А, і так - ніколи не ставте 0 замість NULL чи FALSE! Тільки зіпсуєте собі півдня у той момент, коли два сусідні параметри будуть мати різні типи, а ви напишете 1 чи -1 не там. Пустий вказівник - це NULL і тільки NULL.