копирование файла с поврежденного CD

Тема в разделе "WASM.WIN32", создана пользователем FlasH, 25 фев 2010.

  1. FlasH

    FlasH New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2008
    Сообщения:
    4
    доброго времени суток

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

    я пробывал реализовывать данную задачу рааазличнейшими методами, на различных языках.
    как вариант
    -с# с помощью filestream beginread и manualresetevent.waitfor(timeout). по идеи, если операция завершится успешно(быстрее чем таймаут) то я в процедуре указанной как коллбэк выставлю флаг, что данные готовы и сброшу событие. или же мы прождем таймаут и по сброшенному флагу поймем, что данных нет.

    реализовал, но на практике это не работает.

    пробывал копать в строну createfile / readfile / deviceiocontrol НО там мы можем скопировать сектор, т.е. еще нужно будет узнать в каких секторах находится нужный файл И не факт, что это поможет как-то

    пробывал в отдельных процессах запускать операцию чтения, а из главного потока пытался все это контролировать, но все тщетно. приложения выходя корявые, ОООЧЕНЬ громоздкие и ресурсоемкие.

    по сути вся проблема в том, что бы было возможно через какой-то промежуток времени, если данных нет прервать операцию чтения. НО как это сделать ИЛИ даже хотя-бы в какую сторону копать абсолютно не могу понять.


    перерыл как русскоязычный так и англоязычный интернет, включая мсдн.
    может не правильно формирую запрос...
     
  2. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Когда у меня не читался файл с CD, я открывал этот файл в HexEd by KetilO и сохранял куда нужно :) Странно, но работало.
    Он файлы открывает через CreateFileMapping/MapViewOfFile...
     
  3. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Надо забыть про файлы и сделать посекторную копию. Мною замечено, что при посекторном копировании и с хардов и с СиДи инфа читается лучше, а при пофайловом - "впадает в кому" или "висит". А уж потом извлечешь файл с образа, например утилитой IsoBuster. Возможно IsoBuster может и файл так вытащить, но я его использовал при логичеких глюках, а не при физических сбоях.
    Как вариант - выянить в каких секторах лежит файл и в Линуксе сделать копию этого куска(там это проще, чем в Винде).
     
  4. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    bad copy pro
     
  5. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    В аттаче
     
  6. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    >пробывал копать в строну createfile / readfile / deviceiocontrol НО там мы можем скопировать сектор, т.е. еще нужно >будет узнать в каких секторах находится нужный файл И не факт, что это поможет как-то
    Так вы пробовали или остановились на этой фраэе?

    Помнится, у меня была задача обеспечить проверку нескольких одинаковых CD (подряд на одном компе). Проблема была в буферизации виндой... всего диска и при попытке проверки второго диска винда брала копию файлов из буфера...
    Пришлось открывать файл примерно так:
    Код (Text):
    1.     dFlags |= FILE_FLAG_NO_BUFFERING;
    2.     //
    3.     hFile = ::CreateFile(
    4.                 pszFile,
    5.                 dAccess,
    6.                 FILE_SHARE_READ,
    7.                 NULL,
    8.                 dOptions,
    9.                 dFlags,
    10.                 NULL);
    И от ReadFile не стоит отказыватьться прежде времени - определите размер сектора и читайте файл посекторно.
     
  7. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    на заре молодости такое писал для флешки:
    Код (Text):
    1. //Посекторно в отдельном потоке
    2. //Sdisk- это от куда
    3. //Dfold - это типа куда
    4. bool DiskRAWCopy(LPCSTR Sdisk,LPCSTR Dfold)
    5. {
    6.     char Fdisk[MAX_PATH]="\\\\.\\";
    7.     char Serial[MAX_PATH]={'\0'};
    8.     DWORD DriveSerial=0;
    9.     DWORD dwFileSystemFlags = 0;
    10.     strncat(Fdisk,Sdisk,2);
    11.     char tmpstr[]="(?)Flash.iso";
    12.     tmpstr[1]=*Sdisk;
    13.     GetVolumeInformation(Sdisk,NULL,0,&DriveSerial,NULL,&dwFileSystemFlags,NULL,0);
    14.     sprintf(Serial,"%d",DriveSerial);
    15.     HANDLE hFlash = CreateFile(Fdisk,GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE|FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    16.     if(INVALID_HANDLE_VALUE == hFlash) goto __err;
    17.     DWORD TmpVar=0;
    18.     VOLUME_DISK_EXTENTS VDE;
    19.     DeviceIoControl(hFlash,IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,NULL,0,&VDE, sizeof(VDE),&TmpVar,(LPOVERLAPPED) NULL);
    20.     CloseHandle(hFlash);
    21.     Fdisk[4]='\0';
    22.     strncat(Fdisk,"PhysicalDrive",13);
    23.     char u[2]={'\0'};
    24.     sprintf(u,"%d",VDE.Extents->DiskNumber);
    25.     strncat(Fdisk,u,strlen(u));
    26.     hFlash=INVALID_HANDLE_VALUE;
    27.     hFlash = CreateFile(Fdisk, GENERIC_READ|GENERIC_WRITE,
    28.                       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    29.                       NULL,
    30.                       OPEN_EXISTING,
    31.                       FILE_ATTRIBUTE_DEVICE,
    32.                       NULL );
    33.     if(INVALID_HANDLE_VALUE == hFlash) goto __err;
    34.     PARTITION_INFORMATION PartInfo;
    35.     DWORD Ret;
    36.     DeviceIoControl(hFlash, IOCTL_DISK_GET_PARTITION_INFO,
    37.                            NULL, 0,
    38.                            &PartInfo, sizeof(PartInfo),
    39.                            &Ret, NULL );
    40.     DISK_GEOMETRY pdg;
    41.     DeviceIoControl(hFlash,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&pdg, sizeof(pdg),&TmpVar,(LPOVERLAPPED) NULL);
    42.     //ULONGLONG DiskSize =PartInfo.PartitionLength.QuadPart; èëè pdg.Cylinders.QuadPart *pdg.TracksPerCylinder *pdg.SectorsPerTrack *pdg.BytesPerSector;
    43.     Fdisk[4]='\0';
    44.     strncat(Fdisk,Dfold,strlen(Dfold));
    45.     strncat(Fdisk,Serial,strlen(Serial));
    46.     strncat(Fdisk,tmpstr,strlen(tmpstr));
    47.     HANDLE hVirtual = CreateFile(Fdisk,GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE|FILE_SHARE_DELETE,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    48.     if(INVALID_HANDLE_VALUE == hVirtual) goto __err;
    49.     DWORD BlockSize=pdg.BytesPerSector*pdg.SectorsPerTrack;
    50.     DWORD TrackSize=pdg.TracksPerCylinder*BlockSize;
    51.     char* buffer=(char*)LocalAlloc(LMEM_ZEROINIT,BlockSize);
    52.     DWORD bytes=0;
    53.     LONG Poz=0;
    54.     for(DWORD Cil=0;pdg.Cylinders.QuadPart>=Cil;Cil++)
    55.     {  
    56.         if(F_STOP)
    57.         {
    58.             //RemoveFSPH(NULL);
    59.             break;
    60.         }
    61.         else
    62.         {
    63.             TmpVar=Cil*TrackSize;
    64.             for(DWORD Track=0;pdg.TracksPerCylinder>=Track && Poz<=PartInfo.PartitionLength.QuadPart;Track++)
    65.             {
    66.                 if(F_STOP)
    67.                 {
    68.                     //RemoveFSPH(NULL);
    69.                     break;
    70.                 }
    71.                 else
    72.                 {
    73.                     Poz=TmpVar+Track*BlockSize;
    74.                     SetFilePointer(hFlash,Poz,NULL,FILE_BEGIN);
    75.                     if( !ReadFile(hFlash, buffer, BlockSize, &bytes, NULL) ) goto __er;
    76.                     SetFilePointer(hVirtual,Poz,NULL,FILE_BEGIN);
    77.                     if( !WriteFile(hVirtual, buffer,BlockSize, &bytes, NULL) ) goto __er;
    78.                 }
    79.             }
    80.         }
    81.     }
    82.     CloseHandle(hFlash);
    83.     CloseHandle(hVirtual);
    84.     LocalFree(buffer);
    85.     return true;
    86.     __er:
    87.     LocalFree(buffer);
    88.     __err:
    89.     CloseHandle(hFlash);
    90.     CloseHandle(hVirtual);
    91. return false;
    92. }
     
  8. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    ADD: в результате получается iso-образ
     
  9. FlasH

    FlasH New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2008
    Сообщения:
    4
    сорри, что выпал из темы. не было возможности.

    1-ых я не спрашивал какими сторонними программи это можно сделать. (у меня и у самого есть и бэдкопи, и нскопи, и еще парочка подобных утилит).
    я не спрашивал как пользоваться сторонними программами.

    2-ых to gorodon реализовал копирование посекторно, НО проблема в том, что мне на выходе не нужен образ. зы не пробывал на поврежденном из-за конечного результата.
    зы2: в ваших словах есть доля истины, про FILE_FLAG_NO_BUFFERING, нашел инфу про это в другом исчтонике и про ReadFile. Раньше про это не знал и не пробывал.

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

    нашел некоторую доп инфу. сегодня-завтра потестирую и отпишусь.
     
  10. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Дополнение:
    в статье http://www.wasm.ru/article.php?article=lockfileswork дан код посекторного копирования файлов (в проекте RawRead.rar) - FileCopy вызывает GetFileClusters(определение цепочки кластеров, в которых расположен файл).