доброго времени суток сущесвует довольно большое количество утилит, которые выполняют поставленную задачу, в них даже есть навороты как-то чтение сбойного сектора в обратном направлении, детализация. у меня задача намного тривиальнее нужно просто скопировать поврежденный файл с сд, сектора которые не читаются заменить 0. я пробывал реализовывать данную задачу рааазличнейшими методами, на различных языках. как вариант -с# с помощью filestream beginread и manualresetevent.waitfor(timeout). по идеи, если операция завершится успешно(быстрее чем таймаут) то я в процедуре указанной как коллбэк выставлю флаг, что данные готовы и сброшу событие. или же мы прождем таймаут и по сброшенному флагу поймем, что данных нет. реализовал, но на практике это не работает. пробывал копать в строну createfile / readfile / deviceiocontrol НО там мы можем скопировать сектор, т.е. еще нужно будет узнать в каких секторах находится нужный файл И не факт, что это поможет как-то пробывал в отдельных процессах запускать операцию чтения, а из главного потока пытался все это контролировать, но все тщетно. приложения выходя корявые, ОООЧЕНЬ громоздкие и ресурсоемкие. по сути вся проблема в том, что бы было возможно через какой-то промежуток времени, если данных нет прервать операцию чтения. НО как это сделать ИЛИ даже хотя-бы в какую сторону копать абсолютно не могу понять. перерыл как русскоязычный так и англоязычный интернет, включая мсдн. может не правильно формирую запрос...
Когда у меня не читался файл с CD, я открывал этот файл в HexEd by KetilO и сохранял куда нужно Странно, но работало. Он файлы открывает через CreateFileMapping/MapViewOfFile...
Надо забыть про файлы и сделать посекторную копию. Мною замечено, что при посекторном копировании и с хардов и с СиДи инфа читается лучше, а при пофайловом - "впадает в кому" или "висит". А уж потом извлечешь файл с образа, например утилитой IsoBuster. Возможно IsoBuster может и файл так вытащить, но я его использовал при логичеких глюках, а не при физических сбоях. Как вариант - выянить в каких секторах лежит файл и в Линуксе сделать копию этого куска(там это проще, чем в Винде).
>пробывал копать в строну createfile / readfile / deviceiocontrol НО там мы можем скопировать сектор, т.е. еще нужно >будет узнать в каких секторах находится нужный файл И не факт, что это поможет как-то Так вы пробовали или остановились на этой фраэе? Помнится, у меня была задача обеспечить проверку нескольких одинаковых CD (подряд на одном компе). Проблема была в буферизации виндой... всего диска и при попытке проверки второго диска винда брала копию файлов из буфера... Пришлось открывать файл примерно так: Код (Text): dFlags |= FILE_FLAG_NO_BUFFERING; // hFile = ::CreateFile( pszFile, dAccess, FILE_SHARE_READ, NULL, dOptions, dFlags, NULL); И от ReadFile не стоит отказыватьться прежде времени - определите размер сектора и читайте файл посекторно.
на заре молодости такое писал для флешки: Код (Text): //Посекторно в отдельном потоке //Sdisk- это от куда //Dfold - это типа куда bool DiskRAWCopy(LPCSTR Sdisk,LPCSTR Dfold) { char Fdisk[MAX_PATH]="\\\\.\\"; char Serial[MAX_PATH]={'\0'}; DWORD DriveSerial=0; DWORD dwFileSystemFlags = 0; strncat(Fdisk,Sdisk,2); char tmpstr[]="(?)Flash.iso"; tmpstr[1]=*Sdisk; GetVolumeInformation(Sdisk,NULL,0,&DriveSerial,NULL,&dwFileSystemFlags,NULL,0); sprintf(Serial,"%d",DriveSerial); HANDLE hFlash = CreateFile(Fdisk,GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE|FILE_SHARE_DELETE,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL); if(INVALID_HANDLE_VALUE == hFlash) goto __err; DWORD TmpVar=0; VOLUME_DISK_EXTENTS VDE; DeviceIoControl(hFlash,IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,NULL,0,&VDE, sizeof(VDE),&TmpVar,(LPOVERLAPPED) NULL); CloseHandle(hFlash); Fdisk[4]='\0'; strncat(Fdisk,"PhysicalDrive",13); char u[2]={'\0'}; sprintf(u,"%d",VDE.Extents->DiskNumber); strncat(Fdisk,u,strlen(u)); hFlash=INVALID_HANDLE_VALUE; hFlash = CreateFile(Fdisk, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_DEVICE, NULL ); if(INVALID_HANDLE_VALUE == hFlash) goto __err; PARTITION_INFORMATION PartInfo; DWORD Ret; DeviceIoControl(hFlash, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &PartInfo, sizeof(PartInfo), &Ret, NULL ); DISK_GEOMETRY pdg; DeviceIoControl(hFlash,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&pdg, sizeof(pdg),&TmpVar,(LPOVERLAPPED) NULL); //ULONGLONG DiskSize =PartInfo.PartitionLength.QuadPart; èëè pdg.Cylinders.QuadPart *pdg.TracksPerCylinder *pdg.SectorsPerTrack *pdg.BytesPerSector; Fdisk[4]='\0'; strncat(Fdisk,Dfold,strlen(Dfold)); strncat(Fdisk,Serial,strlen(Serial)); strncat(Fdisk,tmpstr,strlen(tmpstr)); HANDLE hVirtual = CreateFile(Fdisk,GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE|FILE_SHARE_DELETE,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL); if(INVALID_HANDLE_VALUE == hVirtual) goto __err; DWORD BlockSize=pdg.BytesPerSector*pdg.SectorsPerTrack; DWORD TrackSize=pdg.TracksPerCylinder*BlockSize; char* buffer=(char*)LocalAlloc(LMEM_ZEROINIT,BlockSize); DWORD bytes=0; LONG Poz=0; for(DWORD Cil=0;pdg.Cylinders.QuadPart>=Cil;Cil++) { if(F_STOP) { //RemoveFSPH(NULL); break; } else { TmpVar=Cil*TrackSize; for(DWORD Track=0;pdg.TracksPerCylinder>=Track && Poz<=PartInfo.PartitionLength.QuadPart;Track++) { if(F_STOP) { //RemoveFSPH(NULL); break; } else { Poz=TmpVar+Track*BlockSize; SetFilePointer(hFlash,Poz,NULL,FILE_BEGIN); if( !ReadFile(hFlash, buffer, BlockSize, &bytes, NULL) ) goto __er; SetFilePointer(hVirtual,Poz,NULL,FILE_BEGIN); if( !WriteFile(hVirtual, buffer,BlockSize, &bytes, NULL) ) goto __er; } } } } CloseHandle(hFlash); CloseHandle(hVirtual); LocalFree(buffer); return true; __er: LocalFree(buffer); __err: CloseHandle(hFlash); CloseHandle(hVirtual); return false; }
сорри, что выпал из темы. не было возможности. 1-ых я не спрашивал какими сторонними программи это можно сделать. (у меня и у самого есть и бэдкопи, и нскопи, и еще парочка подобных утилит). я не спрашивал как пользоваться сторонними программами. 2-ых to gorodon реализовал копирование посекторно, НО проблема в том, что мне на выходе не нужен образ. зы не пробывал на поврежденном из-за конечного результата. зы2: в ваших словах есть доля истины, про FILE_FLAG_NO_BUFFERING, нашел инфу про это в другом исчтонике и про ReadFile. Раньше про это не знал и не пробывал. to RET спасибо за код. сегодня-завтра разберусь более деталально. мне из него точно нужно будет определение размера сектора, а полностью не подходет ибо на выходе мне нужен файл, а не образ. и как я понял тут совсем не реализован пропуск ошибок. нашел некоторую доп инфу. сегодня-завтра потестирую и отпишусь.
Дополнение: в статье http://www.wasm.ru/article.php?article=lockfileswork дан код посекторного копирования файлов (в проекте RawRead.rar) - FileCopy вызывает GetFileClusters(определение цепочки кластеров, в которых расположен файл).