Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/179: Рейтинг темы: голосов - 179, средняя оценка - 4.60
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62

С++ чтение секторов диска

27.02.2011, 22:36. Показов 35115. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
как по очереди прочитать все сектора на диске?
по идее должна использоваться функция ReadFile(hDevice, buf, 512, &dwBytesRead, NULL); но где подставить номер сектора или как перебрать все?

и как из функции DeviceIoControl вытащить количество секторов

вот сам код до которого додумался, но далее буксую на месте, надеюсь на подсказку)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <windows.h>
 
using namespace std;
 
int main()
{
    HANDLE hDevice;               // handle to the drive to be examined
    DISK_GEOMETRY pdg;           // геометрическая структура дискового устройства
    BOOL bResult;                 // флажок общих результатов
    DWORD junk;                   // сбрасываем результаты
 
    byte buf[512];              //БУФФеР
    DWORD dwBytesRead;
 
 
 
    hDevice = CreateFile("\\\\.\\D:",  // открываемое устройство
                    0,                // нет доступа к устройству
                    FILE_SHARE_READ | // режим совместного использования
                    FILE_SHARE_WRITE, 
                    NULL,             // атрибуты безопасности по умолчанию
                    OPEN_EXISTING,    // расположение
                    0,                // атрибуты файла
                    NULL);            // не копировать атрибуты файла
 
    
    if (hDevice != INVALID_HANDLE_VALUE)
    {
 
 
        bResult = DeviceIoControl(hDevice,  // запрошенное устройство
                IOCTL_DISK_GET_DRIVE_GEOMETRY,  // выполняемая операция
                NULL, 0, // буфера ввода нет
                &pdg, sizeof(pdg),     // буфер вывода
                &junk,                 // # возвращено байтов
                (LPOVERLAPPED) NULL);   // синхронизация ввода/вывода (I/O)
 
 
 
 
        ReadFile(hDevice, buf, 512, &dwBytesRead, NULL); 
 
        CloseHandle(hDevice);
    }
    else cout << "Error Open " << endl;
 
    cin.get();
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.02.2011, 22:36
Ответы с готовыми решениями:

Чтение секторов жёсткого в DOS
Добрый вечер! Проблема заключается именно в том, что программа должна работать под DOS, и ей не важно что есть на диске и какая там...

Чтение секторов жесткого диска
пишу драйвер, считывающий секторы жесткого диска он сохраняет в файл результат проделанной работы. только вот проблема, как узнать то...

Ремап секторов диска с AF
Понадобилось сделать ремап на своём винче, много бэдов и блоков с чтением &gt;600 ms (даже один с 56к ms!) Решил сделать через викторию, но,...

31
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
28.02.2011, 16:56
C++
1
2
3
4
5
6
7
8
9
10
typedef struct _DISK_GEOMETRY
{
    LARGE_INTEGER Cylinders; // Количество цилиндров
    MEDIA_TYPE MediaType;
    DWORD TracksPerCylinder; // Количество дорожек на цилиндр
    DWORD SectorsPerTrack;  // Количество секторов на дорожку
    DWORD BytesPerSector;
} DISK_GEOMETRY;
 
pdg.Cylinders * pdg.TracksPerCylinder * pdg.SectorsPerTrack
Произведение значений этих трех полей даст общее количество секторов

Добавлено через 23 минуты
Цитата Сообщение от partos1 Посмотреть сообщение
как по очереди прочитать все сектора на диске?
по идее должна использоваться функция ReadFile(hDevice, buf, 512, &dwBytesRead, NULL); но где подставить номер сектора или как перебрать все?
Если читать в цикле, то чтение выполняется от начала до конца файла (или дискового устройства). Указатель в файле (диске) сдвигается автоматически. Номер сектора здесь нигде не ставится. Сдвиг указателя осуществляется на количество прочитанных БАЙТ, а не секторов. Но мы то можем узнать, сколько байт в секторе. Обычно 512, но в новых дисках может быть и не так. Поэтому берем это значение из DISK_GEOMETRY pdg.BytesPerSector. Если нужен доступ с произвольного места используется SetFilePointer или SetFilePointerEx (этот сгодится для дисков с огромной емкостью).
Читать дисковые устройства нужно квантами кратными размеру сектора. Если сектор 512 байт, то и читать нужно по 512 байт. Но в целях оптимизации лучше увеличить это значение. Например, по 4096 байт.

Добавлено через 5 часов 46 минут
Кстати, открывается раздел дискового устройства, а запрашиваются сведения о самом дисковом устройстве.
Цитата Сообщение от partos1 Посмотреть сообщение
C++
1
2
hDevice = CreateFile("\\\\.\\D:", ...
bResult = DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY ...
Т.е. то, что будет в структуре DISK_GEOMETRY pdg относится ко всему диску. А на диске может быть несколько разделов. Но даже если на нем будет только один раздел, то размер этого раздела не будет совпадать с размером самого диска. Так что если нужен образ всего диска (с MBR, всеми разделами, неразмеченным пространством), то нужно открывать "\\\\.\\PhysicalDriveX".

Попробуй выполнить запрос
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
PARTITION_INFORMATION pi;
 
if (!DeviceIoControl(hDevice,
    IOCTL_DISK_GET_PARTITION_INFO,
    NULL,
    0,
    &pi,
    sizeof (PARTITION_INFORMATION),
    &bytesReturned,
    (LPOVERLAPPED)NULL))
{
    cout << "Error: " << GetLastError() << endl;
}
И посмотри, что будет в pi.PartitionLength.QuadPart и сравни с pdg.Cylinders.QuadPart * pdg.TracksPerCylinder * pdg.SectorsPerTrack * pdg.BytesPerSector
1
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
28.02.2011, 21:52  [ТС]
спасибо
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
28.02.2011, 23:52
давненько я не занимался дисками (со времен DOS)
но помоему для ОС минимальным значением является не сектор а клястер
для IBM размер сектора 512 (по крайней мере других не видел)
С уважением Валерий

Добавлено через 1 минуту
под ОС я имел ввиду FAT(12,16,32) NTFS
0
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
01.03.2011, 08:55  [ТС]
а можно байты прочтенные функцией
C++
1
ReadFile(hDevice, buf, 512, &dwBytesRead, NULL);
преобразовать в 2 код лучше в 16 код и вывести в файл или сout
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
01.03.2011, 10:20
Цитата Сообщение от ValeryS Посмотреть сообщение
но помоему для ОС минимальным значением является не сектор а клястер
Здесь чтение непосредственно секторов, безотносительно к файловой системе.
Цитата Сообщение от ValeryS Посмотреть сообщение
для IBM размер сектора 512 (по крайней мере других не видел)
Уже существуют и другие (точно не помню, вроде бы 2048)

Добавлено через 2 минуты
partos1,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <iostream>
#include <windows.h>
 
int main()
{
    using namespace std;
 
    // Дескриптор файлового устройства (раздела диска).
    HANDLE partition = INVALID_HANDLE_VALUE;
    // Сведения о разделе.
    PARTITION_INFORMATION partitionInfo = {0};
    // Сведения о геометрии диска, на котором расположен раздел.
    DISK_GEOMETRY diskGeometry = {0};
 
    // Дескриптор файла для сохранения образа раздела.
    HANDLE file = INVALID_HANDLE_VALUE;
 
    // Буфер для чтения.
    BYTE* buffer = NULL;
    // Размер буфера.
    DWORD bufferSize = 0;
 
    // Количество возвращенных байт.
    DWORD bytesReturned = 0;
    // Количество записанных байт.
    DWORD bytesWritten = 0;
 
    // Результат выполнения.
    BOOL result = FALSE;
 
    // Открываем раздел диска.
    if ((partition = CreateFileA("\\\\.\\G:",
        GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL)) == INVALID_HANDLE_VALUE)
    {
        cout << "Error: " << GetLastError() << endl;
        return (-1);
    }
 
    // Запрашиваем сведения о геометрии диска, на котором расположен раздел.
    if (!DeviceIoControl(partition,
        IOCTL_DISK_GET_DRIVE_GEOMETRY,
        NULL,
        0,
        &diskGeometry,
        sizeof (DISK_GEOMETRY),
        &bytesReturned,
        (LPOVERLAPPED)NULL))
    {
        cout << "Error: " << GetLastError() << endl;
        CloseHandle(partition);
        return (-2);
    }
 
    // Запрашиваем сведения о разделе.
    if (!DeviceIoControl(partition,
        IOCTL_DISK_GET_PARTITION_INFO,
        NULL,
        0,
        &partitionInfo,
        sizeof (PARTITION_INFORMATION),
        &bytesReturned,
        (LPOVERLAPPED)NULL))
    {
        cout << "Error: " << GetLastError() << endl;
        CloseHandle(partition);
        return (-3);
    }
 
    // Размер раздела.
    cout << "Partition's size (in bytes): " << partitionInfo.PartitionLength.QuadPart << endl;
    // Размер диска отличается от размера раздела (причем, может значительно отличаться).
    cout << "Disk's size (in bytes):      " << (diskGeometry.Cylinders.QuadPart) *
        diskGeometry.TracksPerCylinder * diskGeometry.SectorsPerTrack *
        diskGeometry.BytesPerSector << endl;
    cout << "Num of cylinders:    " << diskGeometry.Cylinders.QuadPart << endl;
    cout << "Tracks per cylinder: " << diskGeometry.TracksPerCylinder << endl;
    cout << "Sectors per track:   " << diskGeometry.SectorsPerTrack << endl;
    cout << "Bytes per sector:    " << diskGeometry.BytesPerSector << endl;
    system("PAUSE");
 
    // Создание файла для сохранения образа.
    if ((file = CreateFileA("E:\\partition.img",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        0,
        NULL)) == INVALID_HANDLE_VALUE)
    {
        cout << "Error: " << GetLastError() << endl;
        CloseHandle(partition);
        return (-4);
    }
 
 
    // Резервируем место на диске для сохранения образа раздела. Пока у нас файл 0 байт.
    //
    // Здесь мы передвинем указатель в файле за границу его конца на расстояние равное
    // длине нашего раздела. Тем самым мы увеличили размер файла (но это пока теоретически).
    if (!SetFilePointerEx(file, partitionInfo.PartitionLength, NULL, FILE_BEGIN))
    {
        cout << "Error: " << GetLastError() << endl;
        CloseHandle(file);
        CloseHandle(partition);
        return (-5);
    }
    // А вот здесь мы фиксируем новый размер файла физически.
    if (!SetEndOfFile(file))
    {
        cout << "Error: " << GetLastError() << endl;
        CloseHandle(file);
        CloseHandle(partition);
        return (-6);
    }
 
 
    // Устанавливаем размер буфера.
    bufferSize = diskGeometry.BytesPerSector * diskGeometry.SectorsPerTrack;
    // Выделение памяти для буфера указанного размера.
    buffer = new BYTE[bufferSize];
 
    // Переменные используемые для отображения процесса копирования.
    int p = 0;
    __int64 s = 0;
    __int64 t = (partitionInfo.PartitionLength.QuadPart / bufferSize) / 100;
 
 
    // Устанавливаем указатель на начало файла.
    SetFilePointer(file, 0, NULL, FILE_BEGIN);
 
    // Копирование раздела в файл.
    do
    {
        // Чтение секторов раздела.
        result = ReadFile(partition, buffer, bufferSize, &bytesReturned, NULL);
        if (!result)
        {
            cout << "Error: " << GetLastError() << endl;
            delete[] buffer;
            CloseHandle(file);
            CloseHandle(partition);
            return (-7);
        }
 
        // Запись секторов в файл образа.
        result = WriteFile(file, buffer, bytesReturned, &bytesWritten, NULL);
        if (!result)
        {
            cout << "Error: " << GetLastError() << endl;
            delete[] buffer;
            CloseHandle(file);
            CloseHandle(partition);
            return (-8);
        }
 
        if (!(s++ % (t)))
        {
            system("CLS");
            cout << "Copied " << p++ << " %" << endl;
        }
    }
    while (result && bytesReturned);
 
    cout << "Partition copied successfully!\n";
 
    delete[] buffer;
    CloseHandle(file);
    CloseHandle(partition);
 
    system("PAUSE");
    return 0;
}
Попробуй. Открой потом образ в каком-нибудь дисковом редакторе, сравни с разделом диска
1
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
01.03.2011, 23:30  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
#include <windows.h>
 
using namespace std;
 
int main()
{
    HANDLE hDevice;               // handle to the drive to be examined
    HANDLE hFile;
    DISK_GEOMETRY pdg;           // геометрическая структура дискового устройства
    BOOL bResult;                 // флажок общих результатов
    DWORD junk;                   // сбрасываем результаты
    DWORD bytesReturned;
    int a,b,c;
    byte buf[512];              //БУФФеР
    DWORD dwBytesRead;
 
    typedef struct _DISK_GEOMETRY
    {
        LARGE_INTEGER Cylinders; // Количество цилиндров
        MEDIA_TYPE MediaType;
        DWORD TracksPerCylinder; // Количество дорожек на цилиндр
        DWORD SectorsPerTrack;  // Количество секторов на дорожку
        DWORD BytesPerSector;
    } DISK_GEOMETRY;
 
    hDevice = CreateFile("\\\\.\\F:", // открываемое устройство
                    0,                // нет доступа к устройству
                    FILE_SHARE_READ | // режим совместного использования
                    FILE_SHARE_WRITE, 
                    NULL,             // атрибуты безопасности по умолчанию
                    OPEN_EXISTING,    // расположение
                    0,                // атрибуты файла
                    NULL);            // не копировать атрибуты файла
 
    hFile = CreateFile("\\\\.\\H:",   // открываемое устройство
                    0,                // нет доступа к устройству
                    FILE_SHARE_READ | // режим совместного использования
                    FILE_SHARE_WRITE, 
                    NULL,             // атрибуты безопасности по умолчанию
                    OPEN_EXISTING,    // расположение
                    0,                // атрибуты файла
                    NULL);            // не копировать атрибуты файла
 
    if (hDevice != INVALID_HANDLE_VALUE)
    {
        cout << "         dear S.I. " << endl;
        cout << "    " << endl;
        cout << "I am glad to work with you" << endl;
 
        bResult = DeviceIoControl(hDevice,  // запрошенное устройство
                            IOCTL_DISK_GET_DRIVE_GEOMETRY,  // выполняемая операция
                            NULL, 0, // буфера ввода нет
                            &pdg, sizeof(pdg),     // буфер вывода
                            &junk,                 // # возвращено байтов
                            (LPOVERLAPPED) NULL);   // синхронизация ввода/вывода (I/O)
 
        if (bResult!=0)
        {
            cout << "bait v sektore = " << pdg.BytesPerSector << endl;
            cout << "size = " << pdg.Cylinders.QuadPart * pdg.TracksPerCylinder * pdg.SectorsPerTrack * pdg.BytesPerSector << endl;
        }
 
        a = pdg.Cylinders.QuadPart * pdg.TracksPerCylinder * pdg.SectorsPerTrack * pdg.BytesPerSector/512;
 
        cout << c << endl;
 
for (int i = 0; i < c; i++)
{
        ReadFile(hDevice, buf, 512, &dwBytesRead, NULL); 
 
        WriteFile(hFile, buf, 512, &dwBytesRead, NULL); 
                c =i/a*100;
        cout << i << "      " << c << endl;
}
        CloseHandle(hDevice);
    }
    else cout << "Error Open " << endl;
 
    cin.get();
}
программка должна копировать диск F на диск H, но работает не корректно
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
02.03.2011, 10:13
А зачем вы определяете структуру заново
C++
1
2
3
4
5
6
7
8
typedef struct _DISK_GEOMETRY
{
    LARGE_INTEGER Cylinders; // Количество цилиндров
    MEDIA_TYPE MediaType;
    DWORD TracksPerCylinder; // Количество дорожек на цилиндр
    DWORD SectorsPerTrack;  // Количество секторов на дорожку
    DWORD BytesPerSector;
} DISK_GEOMETRY;
В чем выражается некорректная работа?

Добавлено через 23 минуты
Я смотрю вы используете ограничение цикла i < c, а c у вас не инициализирована. Потом в цикле вы присваиваете c = i / a * 100. Все это очень подозрительно выглядит
Еще вы используете очень маленький буфер (512 байт) и выполняете вычисления в цикле. Это на скорость влияет (раздел 8ГБ будет час копироваться). Увеличьте буфер, уберите ненужные вычисления из цикла.
А лучше модифицируйте мой код (выше). Замените в нем file = CreateFileA("E:\\partition.img", на окртытие раздела и выкинте из него перемещения указателей в файле.
0
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 19
02.03.2011, 11:06
Цитата Сообщение от bigredcat Посмотреть сообщение
Здесь чтение непосредственно секторов, безотносительно к файловой системе.

Уже существуют и другие (точно не помню, вроде бы 2048)
2048 у CD/DVD, по сути нет разницы, через DeviceIOControl можно получить размер сектора.
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
02.03.2011, 13:25
barmaley2005 Ошибся я, не 2048, а 4096. Но такие диски уже есть
Переход к жестким дискам нового формата с секторами размером 4 КБ
0
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
02.03.2011, 16:01  [ТС]
почему-то буксует открытие 2 го диска (не рабатывает функций createFile (////.//F)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <iostream>
#include <windows.h>
using namespace std;
 
int main()
{
        
 
        // Дескриптор файлового устройства (раздела диска).
        HANDLE partition = INVALID_HANDLE_VALUE;
        // Сведения о разделе.
        PARTITION_INFORMATION partitionInfo = {0};
        // Сведения о геометрии диска, на котором расположен раздел.
        DISK_GEOMETRY diskGeometry = {0};
 
        // Дескриптор файла для сохранения образа раздела.
        HANDLE file = INVALID_HANDLE_VALUE;
 
        // Буфер для чтения.
        BYTE* buffer = NULL;
        // Размер буфера.
        DWORD bufferSize = 0;
 
        // Количество возвращенных байт.
        DWORD bytesReturned = 0;
        // Количество записанных байт.
        DWORD bytesWritten = 0;
 
        // Результат выполнения.
        BOOL result;BOOL result1;
 
        // Открываем раздел диска читаем.
        partition = CreateFile("\\\\.\\H:",
                GENERIC_READ,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                OPEN_EXISTING,
                0,
                NULL);
                
        if (partition == INVALID_HANDLE_VALUE)
        {
                cout << "read disk (H) dont open" << endl;
                cout << "Error: " << GetLastError() << endl;
        }
 
                // Создание файла для сохранения  пишем.
        file = CreateFile("\\\\.\\F:",
                GENERIC_WRITE,
                0,
                NULL,
                CREATE_ALWAYS,
                0,
                NULL);
 
        if (file == INVALID_HANDLE_VALUE)
                {
                cout << "write disk (F) dont open" << endl;
                cout << "Error: " << GetLastError() << endl;
                }
 
 
        // Запрашиваем сведения о геометрии диска, на котором расположен раздел.
        if (!DeviceIoControl(partition,
                IOCTL_DISK_GET_DRIVE_GEOMETRY,
                NULL,
                0,
                &diskGeometry,
                sizeof (DISK_GEOMETRY),
                &bytesReturned,
                (LPOVERLAPPED)NULL))
        {
                cout << "Error: " << GetLastError() << endl;
                CloseHandle(partition);
                return (-2);
        }
 
        // Запрашиваем сведения о разделе.
        if (!DeviceIoControl(partition,
                IOCTL_DISK_GET_PARTITION_INFO,
                NULL,
                0,
                &partitionInfo,
                sizeof (PARTITION_INFORMATION),
                &bytesReturned,
                (LPOVERLAPPED)NULL))
        {
                cout << "Error: " << GetLastError() << endl;
                CloseHandle(partition);
                return (-3);
        }
 
        // Размер раздела.
        cout << "Partition's size (in bytes): " << partitionInfo.PartitionLength.QuadPart << endl;
        // Размер диска отличается от размера раздела (причем, может значительно отличаться).
        cout << "Disk's size (in bytes):      " << (diskGeometry.Cylinders.QuadPart) *
                diskGeometry.TracksPerCylinder * diskGeometry.SectorsPerTrack *
                diskGeometry.BytesPerSector << endl;
        cout << "Num of cylinders:    " << diskGeometry.Cylinders.QuadPart << endl;
        cout << "Tracks per cylinder: " << diskGeometry.TracksPerCylinder << endl;
        cout << "Sectors per track:   " << diskGeometry.SectorsPerTrack << endl;
        cout << "Bytes per sector:    " << diskGeometry.BytesPerSector << endl;
        system("PAUSE");
 
 
  
        // Устанавливаем размер буфера.
        bufferSize = diskGeometry.BytesPerSector * diskGeometry.SectorsPerTrack;
        // Выделение памяти для буфера указанного размера.
        buffer = new BYTE[bufferSize];
 
        // Переменные используемые для отображения процесса копирования.
        int p = 0;
        __int64 s = 0;
        __int64 t = (partitionInfo.PartitionLength.QuadPart / bufferSize) / 100;
        cout << "t:    " << t << endl;
/*
 
        // Копирование раздела в файл.
        do
        {
                // Чтение секторов раздела.
                result = ReadFile(partition, buffer, bufferSize, &bytesReturned, NULL);
                if (!result)
                {
                        cout << "Error: " << GetLastError() << endl;
                        delete[] buffer;
                        CloseHandle(file);
                        CloseHandle(partition);
                        return (-7);
                }
 
 
                 // Запись секторов в файл образа.
                result1 = WriteFile(file, buffer, bytesReturned, &bytesWritten, NULL);
                if (!result1)
                {
                        cout << "Error: " << GetLastError() << endl;
                        delete[] buffer;
                        CloseHandle(file);
                        CloseHandle(partition);
                        return (-8);
                }
 
                if (!(s++ % (t)))
                {
                        system("CLS");
                        cout << "Copied " << p++ << " %" << endl;
                }
        }
        while (result && bytesReturned);
*/
        cout << "Partition copied successfully!\n";
 
        delete[] buffer;
        CloseHandle(file);
        CloseHandle(partition);
 
        system("PAUSE");
        return 0;
}
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
02.03.2011, 16:50
Я забыл про то, что файл реально создавался. Для дисковых устройств допустим только OPEN_EXISTING - открываем только существующий раздел.
C++
1
2
3
4
5
6
7
8
// Создание файла для сохранения  пишем.
file = CreateFile("\\\\.\\F:",
    GENERIC_WRITE,
    0,
    NULL,
    CREATE_ALWAYS, // <-- так нельзя, нужно OPEN_EXISTING
    0,
    NULL);
Да, и если что, то требуются права администратора.
И, конечно, данные раздела, на который пишешь, потеряешь. Любая ошибка может обернуться серьезными проблемамиО_о. Совету эксперементировать на виртуальной машине
1
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
02.03.2011, 17:47  [ТС]
теперь не хочет работать функция writefile
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
02.03.2011, 18:05
Цитата Сообщение от partos1 Посмотреть сообщение
теперь не хочет работать функция writefile
Код ошибки какой?
0
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
02.03.2011, 18:25  [ТС]
Цитата Сообщение от bigredcat Посмотреть сообщение
Код ошибки какой?
error 6


возвращает -8
0
7 / 7 / 1
Регистрация: 02.03.2011
Сообщений: 19
02.03.2011, 18:34
Цитата Сообщение от partos1 Посмотреть сообщение
error 6


возвращает -8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
        char errMsg[65];
        DWORD dw = GetLastError(); 
 
        FormatMessageA(
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPSTR)&errMsg,
            sizeof(errMsg), NULL );
 
        std::cout << errMsg << std::endl;
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
02.03.2011, 18:42
Цитата Сообщение от partos1 Посмотреть сообщение
error 6
У вас некорректный хендл файла. Вы его не закрыли случаем? Покажите код
0
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
02.03.2011, 18:47  [ТС]
вот сам код
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
#include <windows.h>
using namespace std;
 
int main()
{
        
 
        // Дескриптор файлового устройства (раздела диска).
        HANDLE partition = INVALID_HANDLE_VALUE;
        // Сведения о разделе.
        PARTITION_INFORMATION partitionInfo = {0};
        // Сведения о геометрии диска, на котором расположен раздел.
        DISK_GEOMETRY diskGeometry = {0};
 
        // Дескриптор файла для сохранения образа раздела.
        HANDLE file = INVALID_HANDLE_VALUE;
 
        // Буфер для чтения.
        BYTE* buffer = NULL;
        // Размер буфера.
        DWORD bufferSize = 0;
 
        // Количество возвращенных байт.
        DWORD bytesReturned = 0;
        // Количество записанных байт.
        DWORD bytesWritten = 0;
 
        // Результат выполнения.
        BOOL result;BOOL result1;
 
        // Открываем раздел диска читаем.
        partition = CreateFile("\\\\.\\H:",
                GENERIC_READ,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                OPEN_EXISTING,
                0,
                NULL);
                
        if (partition == INVALID_HANDLE_VALUE)
        {
                cout << "read disk (H) dont open" << endl;
                cout << "Error: " << GetLastError() << endl;
        }
 
                // Создание файла для сохранения  пишем.
        file = CreateFile("\\\\.\\F:",
                GENERIC_WRITE,
                FILE_SHARE_READ|FILE_SHARE_WRITE,
                NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
 
        if (file == INVALID_HANDLE_VALUE)
                {
                cout << "write disk (F) dont open" << endl;
                cout << "Error: " << GetLastError() << endl;
                }
 
 
        // Запрашиваем сведения о геометрии диска, на котором расположен раздел.
        if (!DeviceIoControl(partition,
                IOCTL_DISK_GET_DRIVE_GEOMETRY,
                NULL,
                0,
                &diskGeometry,
                sizeof (DISK_GEOMETRY),
                &bytesReturned,
                (LPOVERLAPPED)NULL))
        {
                cout << "Error: " << GetLastError() << endl;
                CloseHandle(partition);
        }
 
        // Запрашиваем сведения о разделе.
        if (!DeviceIoControl(partition,
                IOCTL_DISK_GET_PARTITION_INFO,
                NULL,
                0,
                &partitionInfo,
                sizeof (PARTITION_INFORMATION),
                &bytesReturned,
                (LPOVERLAPPED)NULL))
        {
                cout << "Error: " << GetLastError() << endl;
                CloseHandle(partition);
        }
 
        // Размер раздела.
        cout << "Partition's size (in bytes): " << partitionInfo.PartitionLength.QuadPart << endl;
        // Размер диска отличается от размера раздела (причем, может значительно отличаться).
        cout << "Disk's size (in bytes):      " << (diskGeometry.Cylinders.QuadPart) *
                diskGeometry.TracksPerCylinder * diskGeometry.SectorsPerTrack *
                diskGeometry.BytesPerSector << endl;
        cout << "Num of cylinders:    " << diskGeometry.Cylinders.QuadPart << endl;
        cout << "Tracks per cylinder: " << diskGeometry.TracksPerCylinder << endl;
        cout << "Sectors per track:   " << diskGeometry.SectorsPerTrack << endl;
        cout << "Bytes per sector:    " << diskGeometry.BytesPerSector << endl;
        system("PAUSE");
 
 
  
        // Устанавливаем размер буфера.
        bufferSize = diskGeometry.BytesPerSector * diskGeometry.SectorsPerTrack;
        // Выделение памяти для буфера указанного размера.
        buffer = new BYTE[bufferSize];
 
        // Переменные используемые для отображения процесса копирования.
        int p = 0;
        __int64 s = 0;
        __int64 t = (partitionInfo.PartitionLength.QuadPart / bufferSize) / 100;
        cout << "t:    " << t << endl;
 
 
        // Копирование раздела в файл.
        do
        {
                // Чтение секторов раздела.
                result = ReadFile(partition, buffer, bufferSize, &bytesReturned, NULL);
                if (!result)
                {
                        cout << "Error: " << GetLastError() << endl;
                        delete[] buffer;
                        CloseHandle(file);
                        CloseHandle(partition);
                        return (-7);
                }
 
 
                 // Запись секторов в файл образа.
                result1 = WriteFile(file, buffer, bytesReturned, &bytesWritten, NULL);
                if (!result1)
                {
 
                        cout << "Error: " << GetLastError() << endl;
                        delete[] buffer;
                        CloseHandle(file);
                        CloseHandle(partition);
                        return (-8);
                }
 
                if (!(s++ % (t)))
                {
                        system("CLS");
                        cout << "Copied " << p++ << " %" << endl;
                }
        }
        while (result && bytesReturned);
 
        cout << "Partition copied successfully!\n";
 
        delete[] buffer;
        CloseHandle(file);
        CloseHandle(partition);
 
        system("PAUSE");
        return 0;
}
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
02.03.2011, 19:23
Странно, но у меня все работает. Сейчас специально добавил в VMware два отдельных диска (виртуальных конечно, с распределением под них дискового пространства), создал на каждом по разделу, задал разные метки, на первый добавил файл. Запустил программу. Все скопировалось. Только результаты были видны не сразу (и F5 не помогло), пришлось в Управлении дисками изменить букву диска (удалить букву, а потом добавить). И все OK. Оба диска стали с одинаковой меткой и файл на втором диске появился и содержимое в нем сохранилось.

У вас вобще процесс копирования не начинается? Вы копируете с флешки на флешку?
0
2 / 2 / 2
Регистрация: 14.11.2010
Сообщений: 62
02.03.2011, 19:33  [ТС]
да с флешки на флешку
цикл do while если функцию writefile убрать читает без проблем
при добавление writefile на первом такте работы валетает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.03.2011, 19:33
Помогаю со студенческими работами здесь

Чтение секторов с CD
Как и многие программеры-извращенцы,решил написать свою ОС в учебных целях. Т.к. нынче флоппиков мало, сразу перешел к чтению секторов с...

Найти количество кластеров и секторов диска
Как найти количество кластеров и секторов локального диска? И возможно ли обойтись без WinApi?

Количество секторов, кластеров и серийник диска
необходимо определить кол-во секторов, кластеров, байт в кластере и серийник диска перерыл функции из серии &quot; DriveInfo HardDisk =...

У свежекупленного диска много секторов с задержкой
Здравствуйте! В связи с проблемами с HDD (https://www.cyberforum.ru/hdd/thread1935738.html) купил новый. Toshiba P300 1 TB. Установил на...

Чтение секторов на диске
Подскажите, как в приложении Win32 прочитать на дискете сектор с заданным цилидром головкой и поверхностью. Не через CreateFile! ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru