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

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by _nic, 23 Jun 2009.

  1. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    С обычными сд все ОК а с двд копирование может оборватся на средине :(
    Code:
    #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*1024)*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;
    }
    
    Почему так?Какая то ошибка чтения?
     
  2. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    SetFilePointer(d,curpos,NULL,FILE_BEGIN);
    если третий параметр NULL то она не работает с размерами больше 2гигов...
    вот примерчик приведен для упрощения небольшого
    Code:
    __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;
    }
    
     
    _________________________
    #2 Gar|k, 23 Jun 2009
    Last edited: 23 Jun 2009
  3. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    То есть смещение надо в моем случае совать в lpDistanceToMoveHigh ?
     
  4. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    нет...
    берешь функцию которую я написал и меняешь в своей проге это:
    unsigned long curpos=0; на это __int64 curpos=0;

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

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    Да я понял как можно твей ф-цией воспользоватся.Но мне хотелось бы понять как просчитывается lpDistanceToMoveHigh
    ЗЫ: ещё такой вопрос ,систем при дамп диска начинает лагать.Когда делаю дамп ультра исо лагов нет.В чем моя ошибка?
     
    #5 _nic, 23 Jun 2009
    Last edited: 23 Jun 2009
  6. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    "Но мне хотелось бы понять как просчитывается lpDistanceToMoveHigh" - RTFM (сам не знаю долго помню ипался когда работу с жестким на прямую делал...)

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

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

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

    я просто не знаю что тебе конкретно надо
     
    _________________________
    #6 Gar|k, 23 Jun 2009
    Last edited: 23 Jun 2009
  7. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    Выделить 4гига(при условии 64 разрядности ОС)? О_о А если двд не 5го а 8го формата попадется?Что тогда? :D
     
    #7 _nic, 23 Jun 2009
    Last edited: 23 Jun 2009
  8. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    мда.... 4 гига это не предел... я тебе говорю смотри в сторону файл маппинга.
     
    _________________________
  9. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    Кстати с твоей ф-цией то же на 2х гигах спотыкается.
    Насчет маппинга- надо спроецировать файл в память?
     
  10. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    _nic за тебя программу написать? RTFM!!!
    http://wasm.ru/article.php?article=1001013
     
    _________________________
  11. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    как ни крути но даже на 64 битных системах получить боьше 4 гигов на проц не получится потому как прожка всё равно под 32 бита.
    По этому и на 32 битках незя больше 2 гигов (теоретически) (если ядро негрузить за третим гигом.)

    А чтобы юзать SetFilePointer для данных больше 4 гигов то вычесляется так:
    Code:
    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 бит, то зададим её адрес.
    А вообще есть прекрасный флаг - передвинуться от текущей позиции а не от начала.
     
  12. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    slesh имеешь ввиду FILE_CURRENT ?
    ЗЫ:я так и непонял как нада выделить память под MapViewOfFile в моём случае :(
    ЗЫЫ:
    Code:
    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:
     
    #12 _nic, 24 Jun 2009
    Last edited: 24 Jun 2009