Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Неповрежденные части файлов с диска A:\ [D6, Win95/98]


Dr. Genius ©   (2004-10-19 17:35:00) 

Собираюсь сейчас приступить к написанию программы, позволяющей считывать поврежденные файлы из поврежденных дискет (точнее – считывать неповрежденные части файлов с дискет). Я знаю, что существует много программ подобного рода, но мне хочется написать самому. Я не знаю, по какому принципу она должна работать, чтобы уметь считывать неповрежденные части поврежденных файлов. Каким должен быть алгоритм работы такой программы? Если кто знает, подскажите.


VMcL   (2004-10-21 07:37:00) [1]

>> GanibalLector ©  (20.10.04 21:09) [15]

> У меня D5 и Remarks не такой,млин...

А у меня MSDN 2004 и Remarks именно такой.
:-)


GanibalLector   (2004-10-20 21:09:00) [2]

2 VMcL ©  [7]

Remarks
Windows Me/98/95:  For volumes that are larger than 2 GB...


Пардон конечно,но ГДЕ вы взяли такой Remarks??? У меня D5 и Remarks не такой,млин...


Sam Stone   (2004-10-20 13:55:00) [3]


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

Забивать нулями непрочитанное. Так BadCopy делает.

> уметь считывать неповрежденные части поврежденных файлов.
>

и что ты с ними будешь делать? Ты даже не поймешь, файл это или старая инфа.


Игорь Шевченко   (2004-10-20 13:48:00) [4]


> Я не знаю, по какому принципу она должна работать, чтобы
> уметь считывать неповрежденные части поврежденных файлов.
> Каким должен быть алгоритм работы такой программы?


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

Вот только непонятно, нафига такая программа нужна ?


Sam Stone   (2004-10-20 13:27:00) [5]

Уж звиняйте, что на асме. Просто лабу такую писал. Суть: скопировать дискету полностью(просто копирую сектора без разбора, вместе с фатом). Вроде последний вариант, должен быть без ошибок. По крайней мере для начала сойдет.
И еще: изучи фат дискеточный. Если надо - могу кинуть немного теории.
.model small
.486
.stack 100h
.data
eof dw 0
fn db "c:\diska.bin",0
handle dw 0
buf db 18*512 dup(0)
numread dw 0
ptrlo dw 0
ptrhi dw 0
blockSize dw 18*512
errmsg db "error",24h
.code

OpenFile PROC
mov dx, offset fn      ; Загрузка файла
mov handle,0            ; Подготовим идентификатор
mov ah,3Dh               ; Функция открытия
mov al,0                     ; Флаг - Только для чтения (0)
int 21h                       ; Вызов функции
jc OF2                      ; Если ошибка, то выход

OF1:
mov handle,ax

OF2:
ret

OpenFile ENDP

CloseFile PROC
mov bx, handle   ; Загрузка идентификатора
mov ah, 3eh       ; Функция закрытия
int 21h              
ret
CloseFile ENDP

; Создание нового файла
CreateFile PROC

mov dx, offset fn    ; Загрузка имени файла
mov handle,0
mov cx,0
mov ah,3ch         ; Функция создания файла
mov al,0
int 21h
jc CF1                 ; Ошибка открытия
mov handle,ax    ; Сохранение идентификатора

CF1: ret
CreateFile ENDP

; Запись в файл
WriteData PROC

mov ah,40h                ; Функция записи в файл
mov bx, handle         ; Загрузка идентификатора
mov cx, BlockSize           ; Размер буфера для записи
mov dx, offset Buf   ; Указатель на буфер
int 21h
ret
WriteData ENDP

; Чтение из файла
ReadData PROC

mov [eof],0                               ; Сбросим флаг
mov ah,3fh                               ; Функция чтения из файла
mov bx,handle                          ; Загрузить идентификатор
mov cx,BlockSize                             ; Размер буфера
mov dx, offset Buf                   ; Указатель на буфер
int 21h    
jc RD2                                      ; Если ошибка чтения

mov word ptr [numread], ax   ; Сохранить количество прочитанных байт
cmp ax,cx                                ; Все ли байты прочитаны?
je RD3

RD1:
mov [eof],1
jmp RD3

RD2:
cmp ax,0                          ; Обнаружен ли конец файла
cmp ax,0
je RD1
;...                                      ; Здесь должна быть обработка ошибки
RD3:
ret

ReadData ENDP

SetPointer PROC

mov ah,42h              ; Функция перемещения указателя
mov al,01h               ; Флаг - от текущей позиции (1), от начала файла (0), от конца файла (2)
mov bx,handle        ; Загрузка идентификатора
mov cx, ptrHI         ; Старшая часть смещения
mov dx, ptrLO       ; Младшая часть смещения    (CX:DX   - 32 bit Смещение )
int 21h

ret
SetPointer ENDP

i db 0
j db 0
n db 0
start:
mov ax,@data
mov ds,ax
mov es,ax

jmp my111

call CreateFile
m2:
mov j,0
mov n,0
m1:
jmp norstread
rstread:
mov ah,0
int 13h
norstread:
mov ah,2
mov al,18;количество секторов
mov ch,j;дорожка
mov cl,1;сектор
mov dh,i;сторона
mov dl,0;дисковод
lea bx,buf
int 13h

jnc b1
inc n
mov bl,n
cmp bl,3
jb rstread
jnb therend

b1: call WriteData
mov ptrhi,0
mov ptrlo,blockSize
call SetPointer
mov n,0
inc j
mov al,j
cmp al,79
jna m1

inc i
mov al,i
cmp al,1
jna m2
;записали всю дискету в файл
call closefile
jmp theend
mov ah,1
int 21h;ждем смены дискеты

my111: mov ah,0
int 13h
call openfile

mov ptrlo,0
mov ptrhi,0
call SetPointer

mov i,0
r2:
mov j,0
r1:
call ReadData
jmp norst
rst:
mov ah,0
int 13h
norst:
mov ah,3
mov al,18
; xor cx,cx
; mov cl,j
; shl cx,6
; or cl,1
mov ch,j
mov cl,1
mov dh,i
mov dl,0
lea bx,buf
int 13h
jnc n1
inc n
mov bl,n
cmp bl,3
jb rst
jnb therend

n1: mov ptrhi,0
mov ax,BlockSize
mov ptrlo,ax
Call SetPointer
mov n,0
inc j
mov al,j
cmp al,79
jna r1

inc i
mov al,i
cmp al,1
jna r2

;записали все на дискету
jmp theend
therend:
mov ah,09h
mov dx,offset errmsg
int 21h

theend:
mov ax, 4c00h
int 21h
end start


Sun bittern   (2004-10-20 11:54:00) [6]

>> Еденица чтения информации - это кластер.

Это что-то новое


VMcL   (2004-10-20 11:53:00) [7]

>> Pentium133 ©  (20.10.04 11:44) [9]

>> т.к. в случае сбойного файла система не даст его даже открыть.

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


Pentium133   (2004-10-20 11:44:00) [8]

Если быть точнее, нужно работать именно напрямую с секторами диска, т.к. в случае сбойного файла система не даст его даже открыть.
 Коллеги, давайте вспомним MS-DOS! Разве есть системная функция (прерывание), которая позволяет при прямомо обращении к диску прочитать указанно количество байтов? Помоему нет. Еденица чтения информации - это кластер.
 Я правда не знаю как с прямым доступом к дискетам у Windows, но наверника идеология не поменялась.


Amoeba   (2004-10-20 11:40:00) [9]

Удалено модератором


VMcL   (2004-10-20 10:55:00) [10]

>> VMcL ©  (20.10.04 07:39) [5]

> сколько вернет ф-ция GetDiskFreeSpace в параметре lpSectorsPerCluster или хотя бы lpBytesPerSector

Сколько вернет ф-ция GetDiskFreeSpace в параметрах (lpSectorsPerCluster * lpBytesPerSector) или хотя бы просто lpBytesPerSector.

>> GanibalLector ©  (20.10.04 09:41) [6]

Remarks

Windows Me/98/95:  For volumes that are larger than 2 GB, the GetDiskFreeSpace function may return misleading values. The function caps the values stored into *lpNumberOfFreeClusters and *lpTotalNumberOfClusters so as to never report volume sizes that are greater than 2 GB. On volumes that are smaller than 2 GBwith an actual sectors per cluster greater than 64, *lpSectorsPerCluster will be capped at 64 and the values stored into *lpSectorsPerCluster, *lpNumberOfFreeClusters, and *lpTotalNumberOfClusters will be incorrect. That is because the operating system adjusts the values so that computations with them yield the correct volume size with the capped *lpSectorsPerCluster.


Во-первых, про lpBytesPerSector ничего не сказано, а можно обойтись только этим значением.

Во-вторых, дискет размером больше 2 ГБ я лично не встречал, а у тех, которые меньше 2 ГБ, не встречал количество секторов на кластер больше 64.


GanibalLector   (2004-10-20 09:41:00) [11]

2 VMcL
ф-ция GetDiskFreeSpace в параметре lpSectorsPerCluster
Которая корректно работает только в XP


VMcL   (2004-10-20 07:39:00) [12]

>> ЮЮ ©  (20.10.04 03:41) [2]

Поскольку на современных дискетах (гы, современных) размер сектора/кластера = 512 байт, то лучше считывать блоками по 512 байт, ИМХО (а точнее блоками по столько байт, сколько вернет ф-ция GetDiskFreeSpace в параметре lpSectorsPerCluster или хотя бы lpBytesPerSector).


Anatoly Podgoretsky   (2004-10-20 07:38:00) [13]

А зачем по байту? 512 байт размер сектора.


Mim1   (2004-10-20 06:22:00) [14]


>  считываешь по 1-му, обрабатывая ощибки.

С неповрежденной дискеткой это займет годы :). Лучше уменьшать размер буфера в звависимости от наличия ошибок.


ЮЮ   (2004-10-20 03:41:00) [15]

Если файл не текстовый, то этим ничего не спасешь. Открываешь как file of byte и считываешь по 1-му, обрабатывая ощибки.


Pentium133   (2004-10-19 17:42:00) [16]

Наверно напримую работа с FAT и считывание секторов с последующим собиранием в файл. Битые сектора пропускаются.
НО это ИМХО. Я таких программ не писал.


Наверх

Титульная страница Поиск, карта сайта Написать письмо