PDA

Просмотр полной версии : Проблемка с дампом оптических дисков


_nic
23.06.2009, 17:58
С обычными сд все ОК а с двд копирование может оборватся на средине :(

#include <windows.h>
#include <stdlib.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hh=GetProcessHeap();
ULARGE_INTEGER TNOFB;
DWORD rb,wb;unsigned long curpos=0;
char *buf=(char*)HeapAlloc(hh,HEAP_ZERO_MEMORY,(1024*10 24)*10);
char dsk[35],dd[5],buff[1024];
strcpy(dsk,"\\\\.\\");
cout<<"DISK name:"<<endl;
cin>>dd;strcat(dsk,dd);
HANDLE d=CreateFile(dsk,GENERIC_READ,FILE_SHARE_READ,NULL ,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL);
if(d==INVALID_HANDLE_VALUE){cout<<dsk<<" oups :("<<endl;goto End;}
HANDLE f=CreateFile("D:\\dump.iso",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS,NULL);
GetDiskFreeSpaceEx(dd,0,&TNOFB,0);
wsprintf(buff,"%I64u",TNOFB.QuadPart);
cout<<"ds:"<<buff;
for(;;)
{
ReadFile(d,buf,(1024*1024)*10,&rb,NULL);
system("cls");
if(rb==0){break;}
curpos=curpos+rb;
cout<<curpos<<endl<<"FROM:"<<endl<<buff;
SetFilePointer(d,curpos,NULL,FILE_BEGIN);
WriteFile(f,buf,rb,&wb,0);
}
CloseHandle(d);
CloseHandle(f);
cout<<"DONE";
End:
getch();
HeapFree(hh,0,buf);
return 0;
}

Почему так?Какая то ошибка чтения?

Gar|k
23.06.2009, 18:35
SetFilePointer(d,curpos,NULL,FILE_BEGIN);
если третий параметр NULL то она не работает с размерами больше 2гигов...
Хотя параметр lpDistanceToMoveHigh используется, чтобы управлять огромными файлами, значение этого параметра должно устанавливаться при перемещении в файлах любого размера. Если он устанавливается в ПУСТО (NULL), то lDistanceToMove имеет максимальное значение 2(31)-2, или 2 гигабайта без двух байтов. Это так потому, что все значения указателя позиции в файле - значения со знаком. Поэтому, даже если есть маленький шанс, что файл будет расти до этого размера, вам следует рассматривать его как огромный файл и работать с 64-разрядными указателями позиции в файле.

вот примерчик приведен для упрощения небольшого

__int64 myFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
{
LARGE_INTEGER li;

li.QuadPart = distance;

li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart,
MoveMethod);

if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError()
!= NO_ERROR)
{
li.QuadPart = -1;
}

return li.QuadPart;
}

_nic
23.06.2009, 19:13
То есть смещение надо в моем случае совать в lpDistanceToMoveHigh ?

Gar|k
23.06.2009, 19:20
нет...
берешь функцию которую я написал и меняешь в своей проге это:
unsigned long curpos=0; на это __int64 curpos=0;

далее меняешь это SetFilePointer(d,curpos,NULL,FILE_BEGIN); на это myFileSeek(d,curpos,FILE_BEGIN);

_nic
23.06.2009, 19:25
нет...
берешь функцию которую я написал и меняешь в своей проге это:
unsigned long curpos=0; на это __int64 curpos=0;

далее меняешь это SetFilePointer(d,curpos,NULL,FILE_BEGIN); на это myFileSeek(d,curpos,FILE_BEGIN);
Да я понял как можно твей ф-цией воспользоватся.Но мне хотелось бы понять как просчитывается lpDistanceToMoveHigh
ЗЫ: ещё такой вопрос ,систем при дамп диска начинает лагать.Когда делаю дамп ультра исо лагов нет.В чем моя ошибка?

Gar|k
23.06.2009, 20:04
"Но мне хотелось бы понять как просчитывается lpDistanceToMoveHigh" - RTFM (сам не знаю долго помню ипался когда работу с жестким на прямую делал...)

Лагает возможно из-за твоей кривизны... мне кажется у тебя с потолка берутся значения выделяемой памяти, непонятный бесконечный цикл.... ты что не можешь получить сначала размер файла потом выделить нужное количество памяти и прочесть его туда?

еще посмотри по теме файлового маппинга в память... http://msdn.microsoft.com/en-us/library/aa366556(VS.85).aspx

http://wasm.ru/article.php?article=1001013

я просто не знаю что тебе конкретно надо

_nic
23.06.2009, 20:25
Выделить 4гига(при условии 64 разрядности ОС)? О_о А если двд не 5го а 8го формата попадется?Что тогда? :D

Gar|k
23.06.2009, 20:39
мда.... 4 гига это не предел... я тебе говорю смотри в сторону файл маппинга.

_nic
23.06.2009, 20:44
мда.... 4 гига это не предел... я тебе говорю смотри в сторону файл маппинга.
Кстати с твоей ф-цией то же на 2х гигах спотыкается.
Насчет маппинга- надо спроецировать файл в память?

Gar|k
23.06.2009, 21:36
_nic за тебя программу написать? RTFM!!!
http://wasm.ru/article.php?article=1001013

slesh
23.06.2009, 21:52
как ни крути но даже на 64 битных системах получить боьше 4 гигов на проц не получится потому как прожка всё равно под 32 бита.
По этому и на 32 битках незя больше 2 гигов (теоретически) (если ядро негрузить за третим гигом.)

А чтобы юзать SetFilePointer для данных больше 4 гигов то вычесляется так:

int64 size;
size = хзхзхзхзхзхз очень много короче
long hs,ls;
ulong hi_addr = NULL;
hs = size >> 32;
ls = (LONG) size;
if (hs) hi_addr = &hs; else hi_addr = NULL;

SetFilePointer (h, ls, hi_addr, dwMoveMethod)

т.е. если есть часть выше 32 бит, то зададим её адрес.
А вообще есть прекрасный флаг - передвинуться от текущей позиции а не от начала.

_nic
24.06.2009, 17:03
slesh имеешь ввиду FILE_CURRENT ?
ЗЫ:я так и непонял как нада выделить память под MapViewOfFile в моём случае :(
ЗЫЫ:

GetDiskFreeSpaceEx(dd,0,&TNOFB,0);
wsprintf(buff,"%I64u",TNOFB.QuadPart);
DWORD sz=atoi(buff);
......................
HANDLE mf=CreateFileMapping(d,NULL,PAGE_READWRITE,0,sz,"MUF");
WriteFile(f,MapViewOfFile (mf,FILE_MAP_READ,0,0,8),sz,&wb,0);
......................

И получаю ошибку "Invalid access to memory location" :confused: