diff --git a/programs/fs/unz/dialogs.inc b/programs/fs/unz/dialogs.inc new file mode 100644 index 0000000000..e4bc8bd717 --- /dev/null +++ b/programs/fs/unz/dialogs.inc @@ -0,0 +1,211 @@ + +;SayErr int num_strings, const char* strings[], +; int num_buttons, const char* buttons[]); + +proc SayErr num_strings:dword, strings:dword,num_buttons:dword, buttons:dword + pushad + cmp [num_strings],1 + je @f + m2m [errmess0], strErrorExc + jmp .l1 + @@: + mov ebx,[strings] + m2m [errmess0], dword [ebx] + .l1: + mcall 51,1,threadSayErr,stackDlg + popad + mov eax,1 + ret +endp + +proc SimpleSayErr str:dword + pushad + m2m [errmess0],[str] + mcall 51,1,threadSayErr,stackDlg + popad + ret +endp + + +proc threadSayErr + mcall 40, 000111b+0C000000h + +.wm_redraw: + mcall 12, 1 + mcall 48, 3, sc, sizeof.system_colors + mov edx, [sc.work] + + or edx, 0x33000000 + mcall 0, <220,420>, <220,110>, , , title + + mov ecx,[sc.work_text] + or ecx,90000000h + mov edx,[errmess0] + mcall 4, <15,11> + + mcall 8, <105,100>,<45,25>,1,[sc.work_button] + mov ecx,[sc.work_button_text] + or ecx,90000000h + mcall 4, <147,51>, , strOk + + mcall 12, 2 + +.still: + mcall 10 + cmp eax, 1 + je .wm_redraw + cmp eax, 2 + je .wm_key + cmp eax, 3 + je .wm_button + jmp .still + +.wm_button: + mcall 17 + + cmp ah, 1 + je .exit + jmp .still + +.wm_key: + mcall 2 + jmp .still +.exit: + mcall -1 +endp + +;------------------------------------------------------------------------------- +;------------------------------------------------------------------------------- +;------------------------------------------------------------------------------- + ; "enter password" dialog for KFar +;password_dlg: +; dd 1 ; use standard dialog colors +; dd -1 ; center window by x +; dd -1 ; center window by y +;.width dd ? ; width (will be filled according to current console width) +; dd 2 ; height +; dd 4, 2 ; border size +; dd aEnterPasswordTitle ; title +; dd ? ; colors (will be set by KFar) +; dd 0 ; used internally by dialog manager, ignored +; dd 0, 0 ; reserved for DlgProc +; dd 2 ; 2 controls +;; the string "enter password" +; dd 1 ; type: static +; dd 1,0 ; upper-left position +;.width1 dd ?,0 ; bottom-right position +; dd aEnterPassword ; data +; dd 0 ; flags +;; editbox for password +; dd 3 ; type: edit +; dd 1,1 ; upper-left position +;.width2 dd ?,0 ; bottom-right position +; dd password_data ; data +; dd 2Ch ; flags + + + +proc DialogBox dlgInfo:dword + pushad + mov ebx,[dlgInfo] + mov eax,[ebx+19*4] + mov [forpassword],eax + mov byte[eax], 0 + mov [stateDlg], 0 + mcall 51,1,threadDialogBox,stackDlg + + ;wait thread... + @@: cmp [stateDlg],0 + jne @f + mcall 5,1 + jmp @b + @@: + popad + cmp [stateDlg], 1 + jne @f + xor eax, eax + ret + @@: + or eax, -1 + ret +endp + +proc threadDialogBox + + mcall 40, 100111b+0C000000h + mov eax,[forpassword] + mov [edtPassword+4*9],eax + xor eax,eax + mov dword[edtPassword.size], eax + mov dword[edtPassword.pos], eax + +.wm_redraw: + mcall 12, 1 + mcall 48, 3, sc, sizeof.system_colors + mov edx, [sc.work] + or edx, 0x33000000 + mcall 0, <200,320>, <200,140>, , , title + + edit_boxes_set_sys_color edtPack,endEdits,sc + stdcall [edit_box_draw],edtPassword + + + mov ecx,[sc.work_text] + or ecx,90000000h + mcall 4, <56,12>, , strGetPass + + mcall 8, <70,80>,<74,22>,2,[sc.work_button] + mov ecx,[sc.work_button_text] + or ecx,90000000h + mcall 4, <103,79>, , strOk + + mcall 8, <165,80>,<74,22>,1,[sc.work_button] + mov ecx,[sc.work_button_text] + or ecx,90000000h + mcall 4, <182,79>, , strCancel + + + mcall 12, 2 + +.still: + mcall 10 + cmp eax, 1 + je .wm_redraw + cmp eax, 2 + je .wm_key + cmp eax, 3 + je .wm_button + cmp eax, 6 + je .wm_mouse + + jmp .still + +.wm_key: + mcall 2 + stdcall [edit_box_key],edtPassword + jmp .still + + +.wm_button: + mcall 17 + + cmp ah, 2 ;OK + jne @f + mov [stateDlg],1 + jmp .exit + @@: + + cmp ah, 1 ;Close window or Cancel + jne .still + mov [stateDlg],2 + jmp .exit + +.wm_mouse: + stdcall [edit_box_mouse],edtPassword + + + jmp .still + +.exit: + mcall -1 +endp diff --git a/programs/fs/unz/file_tree.inc b/programs/fs/unz/file_tree.inc new file mode 100644 index 0000000000..9e92bb04d2 --- /dev/null +++ b/programs/fs/unz/file_tree.inc @@ -0,0 +1,1655 @@ +;как устроено дерево: +;массив, на который указывает PTree содержит записи _tree +; +;0 0,szRoot +;1 1,dir1 +;2 1,dir2 +;3 2,dir21 +;4 2,dir22 +;5 3,dir221 +;6 2,dir23 +;7 1,dir3 +;8 1,dir4 +;9 2,dir41 + + + + +RAZD equ 1 ;Знак разделителя строк + +F_ONLY_READ equ 1b +F_HIDDEN equ 10b +F_SYSTEM equ 100b +F_LABEL equ 1000b +F_FOLDER equ 10000b +F_NOT_BACKUP equ 100000b + +TR_LINE_H equ 18 +TR_STEP_W equ 10 +NUM_READ_FILES = 26 +TR_BACKGROUND = 0EFF8FFh + + + + +macro p2p r1,r2 +{ + push dword r2 + pop dword r1 +} + +macro CopyStr strOut,strIn +{ + mov edi,strOut + mov esi,strIn + @@: lodsb + stosb + test al,al + jnz @b +} + + +struct _BDWK + flags rd 1 ;bit0: only read , hidden , system , label , folder , not backup + encod rb 1 ;0-ASCII, 1-UNICODE + res rb 3 + timeCreated rd 1 + dataCreated rd 1 + lastTimeAccess rd 1 + lastDataAccess rd 1 + lastTimeModify rd 1 + lastDataModify rd 1 + size rq 1 + name rb 263 +ends + +proc d_OutTree + pushad + pushfd + + mov edi,[PTree] + dps 'Дерево:' + dnl + @@: cmp dword[edi+4],0 + je .exit + dph [edi] + dps ' ' + dph [edi+4] + dps ' ' + dpsP [edi+4] + dnl + add edi,8 + jmp @b + .exit: + + popfd + popad + ret +endp + + + +struct _tree + open rd 1 ;0, либо количество подкаталогов(учитывая подкаталоги открытых подкаталогов) + name rd 1 ;указатель на строку относительно PStrings +ends + + + + +uglobal +;-------------- file_tree.inc + +openDir rb 1024 ;здесь путь для чтения папки +tmpStr rb 1024 + +treeDirBuf rb 32+304*NUM_READ_FILES +PTree rd 1 ;указатель на массив структур _tree. Последняя - _tree.name = 0 +TreeSize rd 1 + +endg + +iglobal +;------------- file_tree.inc +szRoot db 'hd0',0 + +tree_info: + .x dd 13 + .y dd 110 + .w dd 284 + .h dd 300 + .numLines dd 200/TR_LINE_H + .firstLine dd 0 + +fiTree dd 1 + .numBlock dd 0 + .flags dd 0 + .numRead dd NUM_READ_FILES + .buff dd treeDirBuf;buf + db 0 + .path dd openDir + + +imgFree: + file 'free.raw' +imgOk: + file 'ok.raw' +imgMinus: + file 'minus.raw' +imgPlus: + file 'plus.raw' +i_end: + +readFolder dd rdFoldforTree ;функция, которой читается папка + + +endg + + +DDD123 = 0 + + +proc file_tree_Init + stdcall MM_AllocMem,4000 + mov [TVROOT],eax + mov dword[eax],0 + mov dword[eax+4],4000 + + mcall 68,12,4096 + mov [PTree],eax + + mov [eax+_tree.open],dword 0 + mov [eax+_tree.name],dword szRoot + mov [eax+8+_tree.open],dword 0 + mov [eax+8+_tree.name],dword 0 + + +DDD123 = 0 +if DDD123 + mov [1*8+eax+_tree.open],dword 1 + mov [1*8+eax+_tree.name],dword sz_d1 + mov [2*8+eax+_tree.open],dword 1 + mov [2*8+eax+_tree.name],dword sz_d2 + mov [3*8+eax+_tree.open],dword 2 + mov [3*8+eax+_tree.name],dword sz_d21 + mov [4*8+eax+_tree.open],dword 2 + mov [4*8+eax+_tree.name],dword sz_d22 + mov [5*8+eax+_tree.open],dword 3 + mov [5*8+eax+_tree.name],dword sz_d221 + mov [6*8+eax+_tree.open],dword 2 + mov [6*8+eax+_tree.name],dword sz_d23 + mov [7*8+eax+_tree.open],dword 1 + mov [7*8+eax+_tree.name],dword sz_d3 + mov [8*8+eax+_tree.open],dword 1 + mov [8*8+eax+_tree.name],dword sz_d4 + mov [9*8+eax+_tree.open],dword 2 + mov [9*8+eax+_tree.name],dword sz_d41 + mov [0Ah*8+eax+_tree.open],dword 0 + mov [0Ah*8+eax+_tree.name],dword 0 +end if + mov [TreeSize],1 + +;Fantomer ; mcall 68,12,4096 + ; mov [PWoSearch],eax + ; mov dword[eax],searchPath + ; mov dword[eax+4],0 + ret +endp +if DDD123 +sz_d1 db 'dir1',0 +sz_d2 db 'dir2',0 +sz_d21 db 'dir21',0 +sz_d22 db 'dir22',0 +sz_d221 db 'dir221',0 +sz_d23 db 'dir23',0 +sz_d3 db 'dir3',0 +sz_d4 db 'dir4',0 +sz_d41 db 'dir41',0 +end if + +uglobal + bufImg rb 384*300*3 +endg + +proc file_tree_Draw +locals + tr_y rd 1 + tr_numLine rd 1 +endl + + mcall 13,<[tree_info.x],[tree_info.w]>,\ + <[tree_info.y],[tree_info.h]>,TR_BACKGROUND + + mov [tr_numLine],0 + p2p [tr_y],[tree_info.y] + mov eax,[PTree] + mov eax,[eax+_tree.open] + inc eax + + + mov ecx,[TreeSize] + .drawLine: + push ecx + + mov edi,[tr_numLine] + shl edi,3 + add edi,[PTree] + + ; mov eax,[edi+_tree.open] + ; mov bx,TR_LINE_H + ; mul bx + ; add eax,[tree_info.x] + ; mpack ebx,eax,[tr_y] + +POPRDLJAKART = 4 + mov eax,[edi+_tree.open] + mov bx,TR_STEP_W + mul bx + add eax,[tree_info.x] + mpack edx,eax,[tr_y] + add edx,POPRDLJAKART ;поправка для картинок + + mov eax,[edi+_tree.open] + inc eax + cmp eax,[edi+8+_tree.open] + je @f + mov ebx,imgPlus + jmp .draw1 + @@: + mov ebx,imgMinus + .draw1: + mcall 7,,<9,9> + + push edx + + ;mov eax,edi + ;call getPath + ;mov ebx,eax + ;stdcall findVetka,eax + ;push ecx + ;stdcall strCpy,ebx, + ;stdcall MM_DelMem,ebx + mov ebx,edi + call getFullPath + stdcall findVetka,openDir + + test ecx,ecx + jnz .l1 + mov ebx,imgOk + jmp .l2 +.l1: + mov ebx,imgFree +.l2: + + pop edx + add edx,15 shl 16 + mov ebx,imgOk + mcall 7,,<9,9> + sub edx,POPRDLJAKART ;убираем поправку для картинок + + lea ebx,[edx+1+10*10000h] + + + mov ecx,90000000h + or ecx,[sc.work_text] + + mov edx,[edi+_tree.name] + mcall 4 + + add [tr_y],TR_LINE_H + inc [tr_numLine] + + mov eax,[tree_info.y] + add eax,[tree_info.h] + cmp [tr_y],eax + jae .end + + pop ecx + dec ecx + jnz .drawLine +.end: + + ret +endp + + + +proc file_tree_Mouse +locals + m_x rd 1 +endl + ;mcall 37,0 абсолютные координаты мыши + + mcall 37,2 ;кнопки + test al,1 + jz .exit + + + mcall 37,1 ;координаты относительно окна + mov bx,ax ;y + shr eax,16 ;x + mov [m_x],eax + + cmp eax,[tree_info.x] ;отбрасываем клики вне дерева + jb .exit + + sub eax,[tree_info.x] + cmp eax,[tree_info.w] + ja .exit + + cmp ebx,[tree_info.y] + jb .exit + sub ebx,[tree_info.y] + mov edx,ebx + cmp edx,[tree_info.h] + ja .exit + + mov eax,edx + + mov bx,TR_LINE_H + xor edx,edx + div bx + + mov ebx,[PTree] + lea ebx,[ebx+eax*8] + ;eax=номер строки, ebx - указатель на _tree, + + ;пропускаем все клики ниже дерева + + mov edx,[TreeSize] + dec edx + cmp eax,edx + ja .exit + + mov eax,[ebx+_tree.open] + mov dx,TR_STEP_W + mul dx + add eax,[tree_info.x] + cmp eax,[m_x] + ja .mark + add eax,9 + cmp eax,[m_x] + jb .mark + + ;проверяем: закрыть или открыть папку + mov edx,[ebx+_tree.open] + inc edx + cmp [ebx+_tree.open+8],edx + jne @f + call tree_closeFolder + call file_tree_Draw + ret + @@: + call tree_openFolder + + call file_tree_Draw + jmp .exit + .mark: + ;клик по строке + + .exit: + ret +endp + + +;------------------------------------------------------------------------------- +;---------------------- закрывает папку ---------------------------------------- +;------------------------------------------------------------------------------- +; inp: ebx - указатель на _tree, +;------------------------------------------------------------------------------- +proc tree_closeFolder + + mov esi,[ebx+_tree.open] + lea edi,[ebx+8] + @@: + cmp [edi+_tree.open],esi + jbe @f + stdcall MM_DelMem,[edi+_tree.name] + add edi,8 + jmp @b + @@: + + + mov esi,edi + lea edi,[ebx+8] + + mov eax,esi + sub eax,edi + shr eax,3 + sub [TreeSize],eax + + ;сдвигаем все структуры, которые ниже закрываемой, вверх + @@: movsd + lodsd + stosd + test eax,eax + jnz @b + + ret +endp + +;------------------------------------------------------------------------------- +;-------------------- открывает папку ------------------------------------------ +;------------------------------------------------------------------------------- +; inp: eax=номер строки, ebx - указатель на _tree, +;------------------------------------------------------------------------------- + +proc tree_openFolder +locals + p_treeOpen rd 1 + currLine rd 1 + PTmpTree rd 1 + endTmpTree rd 1 + lEOF rd 1 + numFolds rd 1 + openLine rd 1 + +endl + mov [p_treeOpen],ebx + ; int3 + call getFullPath + +;----- Читаем папку и заполняем tmpTree--------------------------------------------------------- + + mcall 68,12,8192 + mov [PTmpTree],eax ;память для списка каталогов + + mov [lEOF],0 + mov [endTmpTree],0 + mov [numFolds],0 + + mov [fiTree.numBlock],0 + + .stepLoadFold: ;чтение папки +; dpsP [fiTree+21] +; dnl + + mcall 70,fiTree +; mov eax, fiTree +; call [readFolder] + + test eax,eax + je @f + cmp eax,6 + jne .err + @@: + + cmp ebx,NUM_READ_FILES + je @f + mov [lEOF],1 ;ставим EOF + @@: + mov ecx,ebx + + mov edi,treeDirBuf+32 + + .testRec: ;обработка записей в treeDirBuf + push ecx + + lea eax,[edi+_BDWK.name] ;отбрасываем не папки и папки . и .. + cmp word[eax],'.' + je .endtestRec + + cmp word[eax],'..' + jne @f + cmp byte[eax+2],0 + je .endtestRec + @@: + + ; cmp [edi+_BDWK.flags],F_FOLDER + ; jne .endtestRec + + inc [numFolds] + push edi + + lea esi,[edi+_BDWK.name] + + + ;;;;;;;;; ;добавление папки в список + mov edi,esi ;получаем длину строки + xor al,al + mov ecx,260 + repne scasb + mov eax,260 + sub eax,ecx + + stdcall MM_AllocMem,eax +;dph eax +;dnl + mov edi,eax + mov ebx,[endTmpTree] + add ebx,[PTmpTree] + mov [ebx],eax + add [endTmpTree],4 + + mov ecx,ebx ;если мало места под записи, то перераспределить + add ecx,4 ;больше памяти + test ecx,0FFFh + jz @f + and ecx,0FFFFF000h + add ecx,1000h + @@: sub ecx,4 + cmp ecx,ebx + jne @f + mcall 68,20,,[PTmpTree] + mov [PTmpTree],eax + + @@: lodsb + stosb + test al,al + jnz @b + + + pop edi + + .endtestRec: + add edi,304 + pop ecx + dec ecx + jnz .testRec + + + add [fiTree.numBlock],NUM_READ_FILES + + cmp [lEOF],1 + jne .stepLoadFold + + cmp [numFolds],0 + je .exit + ;;;;;;;;;;;; вписываем в основное дерево + ;смещаем записи вниз, чтоб вписать новую ветку дерева + + mov esi,[PTree] + mov eax,[TreeSize] + inc eax + shl eax,3 + add esi,eax + + mov edi,esi + mov eax,[numFolds] + shl eax,3 + add edi,eax + + mov eax,esi + sub eax,[p_treeOpen] + shr eax,2 + mov ecx,eax + add esi,4 + add edi,4 + std + rep movsd + cld + + ;теперь записываем в [PTree] + mov ebx,[p_treeOpen] + mov eax,[ebx+_tree.open] + inc eax + mov esi,[PTmpTree] + lea edi,[ebx+8] + mov ecx,[numFolds] + @@: mov [edi+_tree.open],eax + p2p [edi+_tree.name],[esi] + add esi,4 + add edi,8 + loop @b + + mov eax,[numFolds] + add [TreeSize],eax + +.exit: + .err: + + mcall 68,13,[PTmpTree] + + call d_OutTree + ret +endp + +;------------------------------------------------------------------------------- +;--- находит полный путь до элемента ------------------------------------------- +;------------------------------------------------------------------------------- +;inp: ebx = Pointer to _tree. +;outp: openDir содержит полный путь (после последней папки имеется /) +;------------------------------------------------------------------------------- +proc getFullPath +;нужно пробежаться от последней папки в пути вверх, по родительским +;сначала записываем папки в tmpStr, разделяя их символом RAZD, затем +;скопиpуем их в обратном порядке в готовый путь в openDir + push ebx edi esi + mov eax,[ebx+_tree.open] + mov edi,tmpStr+1 + mov byte[edi-1],RAZD + + cmp [ebx+_tree.name],0 + je .copyIn_openDir + + jmp .addFoldToPath + .testLine: + cmp [ebx+_tree.open],eax + jb .addFoldToPath + + sub ebx,8 + cmp ebx,[PTree] + jne .testLine + ; jmp .copyIn_openDir + + .addFoldToPath: + mov byte[edi-1],RAZD + mov esi,[ebx+_tree.name] + @@: lodsb + stosb + test al,al + jnz @b + + mov eax,[ebx+_tree.open] + cmp ebx,[PTree] + je .copyIn_openDir + + cmp ebx,[PTree] + jne .testLine + sub ebx,8 + cmp ebx,[PTree] + jne .testLine + + .copyIn_openDir: + sub edi,2 + mov edx,openDir+1 + mov byte[edx-1],'/' + mov byte[edx],0 + cmp edi,tmpStr-1 + je .endConv + @@: + mov al,RAZD + mov ecx,1024 + std + repne scasb + cld + + push edi + add edi,2 + mov eax,1024 + sub eax,ecx + mov ecx,eax + mov esi,edi + mov edi,edx + rep movsb + mov byte[edi-1],'/' + mov byte[edi],0 + mov edx,edi + pop edi + + cmp edi,tmpStr-1 + jne @b + .endConv: + + pop esi edi ebx + ret +endp + + +;inp eax = Pointer to _tree +;outp eax = Pointer to string - full path +;Память с именем освободить!!! +proc getPath +locals + strTmp rb 256 + reslt rd 1 +endl + push ebx edi esi + mov ebx,eax + mov eax,[eax+_tree.open] + lea edi,[strTmp+1] + mov byte[edi-1],RAZD + + cmp ebx,[PTree] + je .copyIn_openDir + jmp .addFoldToPath + .testLine: + cmp [ebx+_tree.open],eax + jb .addFoldToPath + + sub ebx,8 + cmp ebx,[PTree] + jne .testLine + jmp .copyIn_openDir + + .addFoldToPath: + mov byte[edi-1],RAZD + mov esi,[ebx+_tree.name] + @@: lodsb + stosb + test al,al + jnz @b + + mov eax,[ebx+_tree.open] + sub ebx,8 + cmp ebx,[PTree] + jne .testLine + + .copyIn_openDir: + lea eax,[strTmp] + stdcall strLen,eax + stdcall MM_AllocMem,eax + mov [reslt],eax + mov edx,eax + inc edx + sub edi,2 + mov byte[edx-1],'/' + mov byte[edx],0 + lea eax,[strTmp-1] + cmp edi,eax + je .endConv + @@: + mov al,RAZD + mov ecx,1024 + std + repne scasb + cld + + push edi + add edi,2 + mov eax,1024 + sub eax,ecx + mov ecx,eax + mov esi,edi + mov edi,edx + rep movsb + mov byte[edi-1],'/' + mov byte[edi],0 + mov edx,edi + pop edi + + lea eax,[strTmp-1] + cmp edi,eax + jne @b + .endConv: + mov eax,[reslt] + pop esi edi ebx + ret +endp + +;#################################################################################################### +;#################################################################################################### +;#################################################################################################### +;#################################################################################################### + + +;tree_ функции, хранящие отмеченные пути. построены в виде дерева папок\файлов +;в памяти храняться как список структур (usel) + +;tree_Add(path) +;добавляет путь в дерево отмеченых файлов +;вывод +;еах = 0 - добавлено +; 1 - такой путь уже есть +; -1 - неверный путь +; +; +;tree_Del(path) + + + + + +;#################################################################################################### +struct _vetka + + sizeused rd 1 + sizebuf rd 1 +ends + +struct _usel + + pName rd 1 + pNext rd 1 +ends + + +;''''''''''''''''' ГОТОВА +;добавляет путь в дерево отмеченых файлов +;вывод +;еах = 0 - добавлено +; 1 - такой путь уже есть +; -1 - неверный путь +proc tree_Add path:DWORD +locals + numFolds rd 1 + vetB rd 1 + uselB rd 1 +endl + push ebx edi esi +;int3 + stdcall getNumFolds, [path] + cmp eax,-1 + je .error + + mov ecx,eax + inc eax + mov [numFolds],eax + ;ищем каталог, с которого начинаем дописывание дерева +.searchBegin: + push ecx + mov eax,[numFolds] + sub eax,ecx + stdcall getFirstTailPath, [path], eax + push eax + stdcall findVetka,eax + mov ebx,ecx + mov [vetB],eax + mov [uselB],edx + pop eax + stdcall MM_DelMem,eax + cmp ebx,0 + jne .foundBegin + pop ecx + loop .searchBegin + jmp .exitNotAdded +.foundBegin: ;в стеке ещё есх от прошлого loop'a +;int3 + mov eax,[uselB] + mov ebx,[eax+_usel.pNext] + cmp ebx,0 + jne @f + mov ebx,eax + stdcall MM_AllocMem,4000 + mov [ebx+_usel.pNext],eax + mov dword[eax],0 + mov dword[eax+4],4000 + mov ebx,eax +@@: + mov eax,ebx + add [eax+_vetka.sizeused],8 + mov edx,[eax+_vetka.sizebuf] + sub edx,8 + cmp [eax+_vetka.sizeused],edx + jb .noOverflow + + add edx,8 + push eax ;увеличиваем размер буфера + push edx ;функции realloc нет - потому такое извращение - Fantom + add edx,4000 + mov esi,eax + stdcall MM_AllocMem, edx + mov ebx,eax + mov edi,eax + pop ecx + shr ecx,2 + rep movsd + pop eax + stdcall MM_DelMem,eax + mov eax,ebx + +.noOverflow: + mov ebx, [eax+_vetka.sizeused] + lea ebx, [ebx+eax] + ;ebx = PU_ - usel + ;eax = P_ - vetka + mov eax,[numFolds] + sub eax,[esp] ;- в стеке всё ещё есх от .searchBegin + dec eax + stdcall getFoldByNum ,[path], eax + mov [ebx+_usel.pName],eax + mov [ebx+_usel.pNext],0 + +;call D_OutTree +;dps '--------------------------------' +;dnl + pop ecx + dec ecx + jnz .searchBegin + mov eax, 0 + jmp .exit +.exitNotAdded: + mov eax,1 + jmp .exit +.error: + mov eax,-1 + +.exit: +;dps '-- ИТОГ ------------------------' +;dnl +;call D_OutTree + pop esi edi ebx + ret +endp + +DDt dd 0 + +;------------------------------------------------------------------------------- +; ДЛЯ ОТЛАДКИ +proc D_OutTree + mov eax,[TVROOT] + call D_OutTree2 + ret +endp + +proc D_OutTree2 + inc [DDt] + mov ecx,[eax] + shr ecx,3 + add eax,8 +.loop: + push eax ecx + mov ecx,[DDt] +.space: dps ' ' + loop .space + + dpsP [eax] + dps ' ' + dph dword[eax+4] + dnl + cmp dword[eax+4],0 + je @f + mov eax,[eax+4] + call D_OutTree2 + @@: + pop ecx eax + add eax,8 + loop .loop + dec [DDt] + + ret +endp +;------------------------------------------------------------------------------- + + +;tree_Del(path) +; если в указанном узле есть указатель на ветку, то +; treeDelIn(path) +; удалить указанный узел +; если он не последний в списке, то +; если он не стоит последним, то +; сдвинуть все последующие структуры узел вверх на 8 +;last_elem: иначе +; удалить эту ветку +; tree_Del(путь - 1 элемент) + +;treeDelIn(path) +; если это ветка, то +; пока есть узлы { +; если у узла есть ветка, то +; treeDelIn(путь до текущего узла) +; иначе +; освободить память с именем +; } +;ГОТОВ +;return: +;eax = 0 - success, -1 - error +proc tree_Del path:DWORD +locals + PU rd 1 + P rd 1 + path2 rb 256 +endl +;int3 + push ebx edi esi + stdcall findVetka,[path] + test ecx,ecx + jne .err + mov edi,edx + mov esi,eax + cmp [edi+_usel.pNext],dword 0 + je @f + mov eax,edi + push edi esi + call treeDelIn + pop esi edi +@@: + stdcall MM_DelMem,[edi+_usel.pName] + mov eax,[esi+_vetka.sizeused] + cmp eax,8 + je .last_elem + + add eax,esi ; - last _usel + cmp edi,eax ;if last _usel, then do not + je @f + push esi + sub eax,edi ;move all _usel up + shr eax,2 + mov ecx,eax + mov esi,edi + add esi,8 + rep movsd + pop esi + +@@: sub dword [esi+_vetka.sizeused],8 + jmp .exit + +.last_elem: + stdcall MM_DelMem,esi + stdcall findUselMinusOne,[path] + cmp ecx,0 + jne .exit + mov [edx+_usel.pNext],0 +.exit: + xor eax,eax + pop esi edi ebx + ret + +.err: + or eax,-1 + pop esi edi ebx + ret + +endp + +;!!!! не сохраняет регистры + +;input: eax = pointer to _usel +proc treeDelIn + ;mov eax,[eax+_usel.pNext] ;опасно, но и так везде проверяется перед вызовом + ;cmp eax,0 + ;je .exit + + lea ebx,[eax+8] + mov ecx,[eax] + shr ecx,3 ;количество узлов +.loop: + push ecx + mov eax,[ebx+_usel.pNext] + test eax,eax + jz @f + push ebx + call treeDelIn + pop ebx + @@: + stdcall MM_DelMem,[ebx+_usel.pName] + stdcall MM_DelMem,[ebx+_usel.pNext] + add ebx,8 + pop ecx + dec ecx + jnz .loop +.exit: + + ret +endp + +; """""""""""""""" ГОТОВА +;path = /hd0/1/kol -folder +;TV1 -> us'hd0' -> us'1' -> us'kol' +;path = /hd0/1/mtldr -file +;path = /rd/1/kernel.mnt - file in ramdisk + +;находит ветку в которой находится узел с нужной нам папкой +;вывод: +;eax - ветка +;edx - узел, который найден последним, т. е. для пути /rd/1/lib/qwe будет узел lib, так как файла qwe нет +;ecx - 0 - нужный ветка/узел успешно найден +; 1 - нужный ветка/узел не найден - на выходе последний найденый узел +; 2 - неверный параметр +proc findVetka path:DWORD +locals + curFold rd 1 + num_f rd 1 + old_vetk rd 1 + old_usel rd 1 +endl +;int3 + mov eax, [TVROOT] + cmp dword[eax],0 + jne @f + mov edx, 0 + mov ecx,2 + xor eax,eax + ret + @@: + push ebx edi esi + mov [num_f], 0 + xor edx, edx + stdcall getFoldByNum, [path], 0 + test eax, eax + jz .error2 +;dpsP eax +;dnl + + mov [curFold], eax + mov esi, [TVROOT] +.goLoop: + mov ebx, 8 + mov ecx, [esi] + shr ecx, 3 ;столько в TVROOT структур usel +.loop: + push ecx + stdcall strCmp, [curFold], [esi+ebx] + test al, al + jz .find + add ebx, 8 + pop ecx + loop .loop + jmp .error1 + +.find: + pop eax ; выровняли + inc [num_f] + stdcall MM_DelMem, [curFold] + stdcall getFoldByNum, [path], [num_f] + test eax, eax + jz .end + mov [curFold], eax + + + cmp dword[esi+ebx+4], 0 + jz .error + lea eax, [esi+ebx] + mov [old_vetk],esi + mov [old_usel],eax + mov esi, [esi+ebx+4] + jmp .goLoop +.end: + + mov eax, esi + lea edx, [esi+ebx] + xor ecx,ecx + jmp .exit + +.error: + stdcall MM_DelMem, [curFold] + mov eax, esi + lea edx, [esi+ebx] + mov ecx,1 + jmp .exit +.error1: + stdcall MM_DelMem, [curFold] + mov eax, [old_vetk] + mov edx, [old_usel] + mov ecx,1 + jmp .exit +.error2: + stdcall MM_DelMem, [curFold] + mov eax, 0 + mov edx, 0 + mov ecx,2 + +.exit: + pop esi edi ebx + ret +endp + + ;ГОТОВА +;находит узел, который ссылается на заданный узел +;вернёт в edx usel, для предпоследней папки в пути +;eax - ветка, в которой этот узел +;есх - статус(0, 1, 2, -1) +proc findUselMinusOne path:DWORD +locals + path2 rb 256 +endl + push ebx edi esi + + stdcall strLen,[path] + cmp eax,255 + ja .err + lea eax,[path2] + stdcall strCpy,[path],eax + + lea edi,[path2] + xor al,al + mov ecx,256 + repne scasb ; V + test ecx,ecx ;/hd0/1/kol + jz .err ;только одна папка + sub ecx,255 + xor ecx,-1 + inc ecx + sub edi,2 + cmp byte [edi], '/' + jne @f + dec edi + dec ecx + @@: + mov al,'/' + std + repne scasb + cld + test ecx,ecx + jz .err ; только одна папка + + inc edi + mov byte[edi],0 + + lea eax,[path2] + stdcall findVetka,eax + jmp @f +.err: + xor eax,eax + xor edx,edx + or ecx,-1 +@@: + pop esi edi ebx + ret +endp + +;--------------Готова +;находит узел для заданного каталога в пути +;eax = Pointer to _vetka +;edx = Pointer to _usel +;ecx = status (0 - success, 1 - found path not full, +; 2 - path not corrected, -1 - only one folder in path) + +proc findUselByNum path:DWORD,num:DWORD +locals + path2 rb 256 +endl + push ebx edi esi + + stdcall getNumFolds,[path] + cmp eax,[num] + jl .err + + xor ebx,ebx + lea edi,[path2] + mov esi,[path] + cmp byte[esi],'/' + jne .l2 + dec ebx +.l2: lodsb + stosb + cmp al,'/' + jne @f + inc ebx + cmp ebx,[num] + ja .go + @@: + test al,al + jnz .l2 + +.go: + mov byte[esi-1],0 + lea eax,[path2] + stdcall findVetka,eax + jmp @f +.err: + xor eax,eax + xor edx,edx + or ecx,-1 +@@: + pop esi edi ebx + ret +endp + +;''''''''''''''' ГОТОВА +;Возвращает имя файла/каталога из всего пути +; --- !!! Память нужно будет освободить +proc getName path:DWORD + push esi edi + + stdcall strLen,[path] + mov edi,[path] + add edi,eax + sub edi,2 + cmp byte[edi],'/' + jne @f + dec edi +@@: + mov ecx,eax + mov al,'/' + std + repne scasb + cld + add edi,2 + stdcall strLen,edi + mov esi,eax + stdcall MM_AllocMem, ecx + push eax + add esi,eax + stdcall strCpy,edi, eax + cmp byte[esi-2],'/' + jne @f + mov byte[esi-2],0 +@@: + pop eax + pop edi esi + ret +endp + + + +; """""""""""""""" ГОТОВА +proc strCpy src:DWORD,dest:DWORD + push esi edi + mov edi,[dest] + mov esi,[src] +@@: lodsb + stosb + test al,al + jnz @b + pop edi esi + ret +endp + +; """""""""""""""" ГОТОВА +; с учётом завершающего 0 +proc strLen strz:DWORD + push edi + mov edi,[strz] + xor al,al + mov ecx,1024 + repnz scasb + mov eax,1024 + sub eax,ecx + pop edi + ret +endp + +; """""""""""""""" ГОТОВА +proc strCmp src1:DWORD, src2:DWORD + push esi edi + mov edi, [src1] + mov esi, [src2] + mov eax, 1 +@@: test al, al + jz .end + lodsb + scasb + jz @b + + ja .low + mov eax, 1 + jmp @f +.low: + mov eax, -1 +@@: + pop edi esi + ret +.end: + xor eax,eax + jmp @b +endp + + +; """""""""""""""" ГОТОВА +;возращает имя папки из всего пути по его номеру. +;! Счёт начинается с 0 +; --- !!! Память нужно будет освободить +proc getFoldByNum strz:DWORD, num:DWORD + push ebx edi esi + + mov esi, [strz] + mov ecx, 1024 + stdcall MM_AllocMem, 256 + mov ebx, eax + cmp byte[esi], '/' + jne @f + inc esi + @@: + +.find_begin: + cmp [num], 0 + jz .copy + + @@: lodsb + cmp al, '/' + je @f + cmp al, 0 + je .error + loop @b + @@: dec [num] + jmp .find_begin + +.copy: + ;dec esi + mov edi, ebx + mov byte[edi], 1 ;это метка того, что ни один байт не записан + @@: + lodsb + cmp al, '/' + je @f + cmp al, 0 + je @f + stosb + loop @b + @@: + cmp byte[edi], 1 + jne @f +.error: + stdcall MM_DelMem, ebx + xor ebx, ebx + jmp .end + @@: + xor al, al + stosb +.end: + mov eax, ebx + pop esi edi ebx + ret +endp + + +; """""""""""""""" ГОТОВА +;возращает количество элементов +;ret: eax = Num or -1 +proc getNumFolds path:DWORD + push ebx edi esi + + stdcall strLen,[path] + cmp eax,255 + ja .err + + xor ebx,ebx + mov esi,[path] + cmp byte[esi],'/' + jne .l1 + dec ebx +.l1: lodsb + cmp al,'/' + jne @f + inc ebx + @@: + test al,al + jnz .l1 + + cmp [esi-2],byte '/' + je @f + inc ebx +@@: + + mov eax,ebx + jmp .exit +.err: + or eax,-1 +.exit: + pop esi edi ebx + ret +endp + + +;''''''''''''''''ГОТОВА +;возвращает часть пути: первые num каталогов +;ret: Указатель на строку. +; --- !!! Память нужно будет освободить +proc getFirstTailPath path:DWORD, num:DWORD + push ebx edi esi + + cmp [num],0 + je .err + + + stdcall strLen,[path] + cmp eax,255 + ja .err + + stdcall MM_AllocMem, eax + mov edi,eax + push eax + + + xor ebx,ebx + mov esi,[path] + cmp byte[esi],'/' + jne .l1 +.l1: lodsb + stosb + cmp al,'/' + jne @f + inc ebx + cmp ebx,[num] + ja .endloop + @@: + test al,al + jnz .l1 +.endloop: + + cmp [esi-2],byte '/' + je @f + mov byte[edi-1],0 + jmp .l2 +@@: + mov byte[edi-2],0 +.l2: + + pop eax + jmp .exit +.err: + + or eax,-1 + +.exit: + + pop esi edi ebx + ret +endp + + +proc TESTINIT +;---- чтобы струтуры менеджера памяти были в норме нужно именно им выделить память под это дерево + +;;TEST getFoldByNum +;tstStr db '/hd0/1/dqw',0 +; stdcall getFoldByNum,tstStr,2 +; dpsP eax +; dps '|' +; dnl +; ret + stdcall MM_AllocMem,4000 + mov [TVROOT],eax + stdcall MM_AllocMem,4000 + mov [Tus1+4],eax + stdcall MM_AllocMem,4000 + mov [Tus2+4],eax + + stdcall MM_AllocMem,4 + mov [Tus1],eax + stdcall MM_AllocMem,4 + mov [Tus2],eax + stdcall MM_AllocMem,4 + mov [Tus3],eax + + stdcall strCpy,sname1,[Tus1] + stdcall strCpy,sname2,[Tus2] + stdcall strCpy,sname3,[Tus3] + + mov esi,TvetkaHD0 + mov edi,[TVROOT] + mov ecx,4 + rep movsd + + mov esi,Tvetka1 + mov edi,[Tus1+4] + mov ecx,4 + rep movsd + + mov esi,TvetkaKOL + mov edi,[Tus2+4] + mov ecx,4 + rep movsd + + +;int3 +; stdcall tree_Add,strTets1 + ; stdcall tree_Add,strTets2 + ; stdcall tree_Add,strTets3 +;dps '----------' +;dnl +;call D_OutTree + +; stdcall tree_Del,strTets2 +;dps '----------' +;dnl +;call D_OutTree +;dps '-------------------------' +;dnl + ; stdcall getFoldByNum,strTets,0 +;mov edi,eax +;dpsP edi +;dnl + ;int3 + mov eax,[PTree] + lea eax, [5*8+eax+_tree.open] + call GetPath + dpsP eax + dnl + ret +endp + + +;;TEST +strTets1 db '/hd0/kol/asd1',0 +strTets2 db '/hd0/kol/asd2',0 +strTets3 db '/hd0/kol/asd3',0 + +TvetkaHD0: + dd 2*4 + dd 4000 + + Tus1: + dd sname1 + dd Tvetka1 +;--------------------- + + + +Tvetka1: + dd 2*4 + dd 4000 + + Tus2: + dd sname2 + dd TvetkaKOL +;--------------------- + + +TvetkaKOL: + dd 2*4 + dd 4000 + + Tus3: + dd sname3 + dd 0 +;--------------------- + +sname1 db 'hd0',0 +sname2 db '1',0 +sname3 db 'kol',0 + +_TBUFSIZE dd 4000 - $ + + +TVROOT rd 1 + +;будет буфер отмеченных файлов/папок +;открыть папку +; если она отмечена вся, то ничего не делать +; если в ней убрать галку, то добавить в список отмеченных все остальные, +; а папку убрать из списка +; если поставить галку на последнем не выделенном файле, то ничего. просто добавить его в список,манипуляции с папками незачем +; + +;vetka: +; sizeused +; sizebuf(def - 4000) +; array of usel +; +; --- реализация --- +;дерево выделенных объектов: +; узел (usel): +; pName - двслово - указатель на строку имя узла +; pNext - двслово - указатель на vetka или 0 + + +;vetka {2*8,4000-2*8, +;usel [Program_Files,0], +;usel [Doc,v2] +;} +;v2: +;vetka {1*8,4000-8, +;usel [fold1,0] +;} diff --git a/programs/fs/unz/free.raw b/programs/fs/unz/free.raw new file mode 100644 index 0000000000..24e29ca745 Binary files /dev/null and b/programs/fs/unz/free.raw differ diff --git a/programs/fs/unz/fs.inc b/programs/fs/unz/fs.inc index 3306f05e54..fb8b631284 100644 --- a/programs/fs/unz/fs.inc +++ b/programs/fs/unz/fs.inc @@ -653,10 +653,10 @@ endp proc myAddDir name:dword, bdfe_info:dword - dps 'log adddir' +; dps 'log adddir' mov eax,[name] - dpsP eax - dnl +; dpsP eax +; dnl pusha mov eax,[name] diff --git a/programs/fs/unz/lang.inc b/programs/fs/unz/lang.inc new file mode 100644 index 0000000000..6ae37e1048 --- /dev/null +++ b/programs/fs/unz/lang.inc @@ -0,0 +1 @@ +lang fix ru diff --git a/programs/fs/unz/memory_manager.inc b/programs/fs/unz/memory_manager.inc new file mode 100644 index 0000000000..283526f011 --- /dev/null +++ b/programs/fs/unz/memory_manager.inc @@ -0,0 +1,330 @@ +;MM_ = MemoryManager +;Этот модуль позволяет выделять память маленькими кусочками, оптимально используя +;страницы памяти +;Блоки - это одна или несколько страниц, которые имеют запись +;в MM_BlockInfo и которые в конце имеют стекообразную структуру(в смысле +;растёт к меньшим адресам), заканчивающейся dword 0. В начале блока +;находятся данные. В структуре находятся пары dword'ов: начало +;участков, их конец(посл. байт+1). Эти пары всегда сортируются по +;расположению описываемых +;участков в обратном порядке, т.е. в самом конце блока будет пара данных +;на самый первый участок. Для выделения памяти нужно найти блок, в котором +;достаточно места (причём необходимое место = запрашиваемый объём + место +;под пару с данными в конце блока) и вставить пару с нужными данными. +;Для удаления участка нужно только убрать из пар пару с нужным участком +;и поправить расположение остальных пар. +;begData1.....endData1,begData2...endData2,.......0,beg2,end2,beg1,end1 + + +;выделяет память +;return eax = указатель на выделеный блок +;proc MM_AllocMem stdcall,Size:DWORD + +;БАГ в выделении крупных кусков: всегда выделяет новую страницу + + + +align 4 +MM_AllocMem: + Size equ ebp+8 + begFree equ ebp-8 ;начало + endFree equ ebp-4 ;и конец свободного места от конца инфы до + endArea equ ebp-12 + push ebp + mov ebp,esp + add esp,-4*3 + push ebx edi esi +;dps 'MEM: ' +;dph [Size] +;dps ' ' + ;начала пар записей + mov edx,[MM_NBlocks] + cmp edx,0 + jne .BegTestBlocks ;если блоков нет, то добавить новый + mov ecx,[Size] + call AddBlock + jmp .return +align 4 + .BegTestBlocks: + + + xor ebx,ebx + mov ecx,edx +align 4 + .TestBlock: ;проверка блока + ;проверка: есть ли место для ещё одной пары + mov edi,[MM_BlocksInfo+ebx] + add edi,[MM_BlocksInfo+ebx+4] + mov [endArea], edi + sub edi,4 + + cmp dword[edi],0 ;если в блоке нет ни одной записи + jne .NoEmptyBlock + mov eax,[MM_BlocksInfo+ebx] + mov dword[edi-4],eax + mov dword[edi],eax + mov edx,[Size] + add dword[edi],edx + mov dword[edi-8],0 + jmp .return +align 4 + .NoEmptyBlock: + xor eax,eax + push ecx + or ecx,-1 + std + repne scasd + cld + pop ecx + mov eax,[edi+12] ;конец посл участка + add eax,4 + cmp eax,edi + jb @f + + add ebx,8 + dec ecx + jnz .TestBlock + + mov ecx,[Size] + call AddBlock + jmp .return + @@: + + + mov [begFree],eax ;eax = конец посл. участка + 4 + mov [endFree],edi ;edi = указатель на конец посл участка - 12 + sub dword[begFree],4 + add dword[endFree],12 + + ;проверка перед всеми участками + mov edi,[MM_BlocksInfo+ebx] + mov eax,[endArea] + mov eax,[eax-8] + sub eax,[MM_BlocksInfo+ebx] + cmp eax,[Size] + ja .AddInBegBlock + + ;проверка между участками + mov eax,[endArea] + cmp dword[eax-12],0 + je .EndTest ;если в блоке только 1 участок + + sub eax,4 + @@: + mov edi,[eax-12] + sub edi,[eax] + cmp edi,[Size] + jae .AddInMiddle + sub eax,8 + cmp dword[eax-8],0 + jne @b + + .EndTest: + + ;проверка после всех блоков + mov eax,[begFree] + mov edi,[endFree] + lea esi,[edi-8] ;8 - место под запись + sub esi,eax + + cmp esi,[Size] + ja .AddInEnd + + add ebx,8 + dec ecx + jnz .TestBlock + + mov ecx,[Size] + call AddBlock + + jmp .return +align 4 + .AddInBegBlock: ;Добавить в начало. В edi начало блока + ;pop eax + + mov eax,edi + add eax,[MM_BlocksInfo+ebx+4] + sub eax,4 + push eax + call MoveRecordsLeft + pop eax + mov [eax-4],edi + push edi + add edi,[Size] + mov [eax],edi + pop eax + + jmp .return +align 4 + .AddInMiddle: ;Добавить между участками, еах=конец участка перед свободным местом + + ;pop ecx ;add esp,4 + push eax + sub eax,8 + call MoveRecordsLeft + pop eax + + mov edx,[eax] + mov [eax-12],edx + add edx,[Size] + mov [eax-8],edx + mov eax,[eax] + jmp .return +align 4 + .AddInEnd: ;Добавить после участков. еdi=указатель на 2ой элем пары с инфой о посл участке + + ;add esp,4 + mov eax,[edi] + mov [edi-12],eax + push eax + add eax,[Size] + mov [edi-8],eax + pop eax + +.return: + + pop esi edi ebx + leave + ret 4 + +restore Xren +restore Size +restore begFree +restore endFree + + + +;eax - первый сдвигаемый dword +;сдвигает пары dword'ов на 8B назад включая dword 0 +align 4 +proc MoveRecordsLeft +local var1:DWORD,\ + var2:DWORD + + p2p [var1],[eax] + p2p [var2],[eax-4] + + @@: + sub eax,8 + cmp dword[var1],0 + je @f + + push dword[eax] + p2p [eax],[var1] + pop dword[var1] + + push dword[eax-4] + p2p [eax-4],[var2] + pop dword[var2] + jmp @b + @@: + + mov dword[eax],0 + ret +endp + +;ecx = размер требуемого участка +;добавляет блок и создаёт в нём участок размером ecx +align 4 +proc AddBlock + mov edx,[MM_NBlocks] + inc edx + cmp edx,MM_MAX_BLOCKS + ja .ErrAlloc + + push ecx + add ecx,12 + + test ecx,0FFFh ;округляем до большей границы страницы + jz @f + add ecx,1000h + and ecx,0FFFFF000h + @@: + + mcall 68,12,ecx + mov [MM_NBlocks],edx ;заполнение данных о блоке + mov [edx*4*2-4*2+MM_BlocksInfo],eax ;begin + mov [edx*4*2-4+MM_BlocksInfo],ecx ;size +;dps 'Block ' +;dph eax +;dps ' ' +;dph ecx +;dnl + mov edx,eax + add edx,ecx + mov [edx-8],eax + pop dword[edx-4] + add [edx-4],eax + mov dword[edx-12],0 + ret + + .ErrAlloc: + pop ecx + xor eax,eax + ret +endp +;------------------------------------------------------------------------------- + + +;удаляет память +;proc MM_DelMem Pointer:DWORD +align 4 +MM_DelMem: + Pointer equ ebp+8 + push ebp + mov ebp,esp +; int3 + push ebx + mov ecx,[MM_NBlocks] + test ecx,ecx + jnz @f + xor eax,eax + pop ebx + leave + ret 4 + @@: + + mov eax,[Pointer] + xor ebx,ebx ;ebx - (номер блока)*8 + .TestBlocks: + mov edx,[MM_BlocksInfo+ebx] + add edx,[MM_BlocksInfo+ebx+4] + sub edx,8 ;edx - указатель на 1ую пару + + .TestMems: + cmp [edx],eax + je .FoundMem + + sub edx,8 + cmp dword[edx+4],0 + jne .TestMems + + add ebx,4 + loop .TestBlocks + + xor eax,eax + pop ebx + leave + ret 4 + + .FoundMem: + cmp dword[edx-4],0 + jz .EndDelMem + + .NextMoveMem: + p2p [edx+4],[edx-4] + p2p [edx],[edx-8] + sub edx,8 + cmp dword[edx-4],0 + jnz .NextMoveMem + + .EndDelMem: + mov dword[edx+4],0 + mov dword[edx],0 + + mov eax,1 + pop ebx + leave + ret 4 + +restore Pointer diff --git a/programs/fs/unz/minus.raw b/programs/fs/unz/minus.raw new file mode 100644 index 0000000000..d8b18ced35 Binary files /dev/null and b/programs/fs/unz/minus.raw differ diff --git a/programs/fs/unz/ok.raw b/programs/fs/unz/ok.raw new file mode 100644 index 0000000000..6336b4ef31 Binary files /dev/null and b/programs/fs/unz/ok.raw differ diff --git a/programs/fs/unz/parse.inc b/programs/fs/unz/parse.inc index 07a2d5fb4e..a69b848bfa 100644 --- a/programs/fs/unz/parse.inc +++ b/programs/fs/unz/parse.inc @@ -4,7 +4,7 @@ ; 2 - error parsing proc getLastParam ;последний параметр пишет в fInp -xor al, al ;to end sring + xor al, al ;to end string mov edi, params mov ecx, 4096 repne scasb @@ -100,26 +100,30 @@ xor al, al ;to end sring xor eax, eax endp - -proc getParam2 +;заполняе pathOut +proc getParamOutPath locals retrn rd 0 endl mov [retrn], 0 mov ebx, params + .find_o: cmp [ebx], word '-o' jne .find_o2 + mov edx, ebx lea esi, [ebx+3] + @@: ;skiping spaces - cmp esi, pathOut+1024 + cmp esi, params+4096 jae .errorParsing cmp byte[esi], ' ' jne @f inc esi jmp @b - @@: ;copying ; -o "file" + @@: + ;copying ; -o "file" mov ecx, 3 cmp byte[esi], '"' jne ._notspace @@ -132,7 +136,7 @@ endl je .clear stosb inc ecx - cmp esi, pathOut+1024 + cmp esi, params+1024 jae errorParsing jmp @b @@ -143,7 +147,7 @@ endl inc ecx cmp al, ' ' je .clear - cmp esi, pathOut+1024 + cmp esi, params+1024 jae errorParsing jmp @b @@ -159,7 +163,7 @@ endl .find_o2: inc ebx - cmp ebx, pathOut+1024 + cmp ebx, params+1024 jae @f cmp byte[ebx], 0 je @f @@ -200,7 +204,7 @@ endl jmp @b @@: - ;copying ; -f "file" + ;variant1: copying ; -f "file" mov ecx, 3 cmp byte[esi], '"' jne ._notspace @@ -217,7 +221,7 @@ endl jae errorParsing jmp @b - ._notspace: ;copying ; -f file + ._notspace: ;variant2: copying ; -f file mov edi, [endPointer] @@: lodsb stosb diff --git a/programs/fs/unz/plus.raw b/programs/fs/unz/plus.raw new file mode 100644 index 0000000000..5f8a95b391 Binary files /dev/null and b/programs/fs/unz/plus.raw differ diff --git a/programs/fs/unz/unz.asm b/programs/fs/unz/unz.asm index 972a32ce41..f3127ca1da 100644 --- a/programs/fs/unz/unz.asm +++ b/programs/fs/unz/unz.asm @@ -43,14 +43,22 @@ include '../../macros.inc' include '../../proc32.inc' include '../../develop/libraries/box_lib/trunk/box_lib.mac' include '../../dll.inc' +;include '../../debug.inc' + + +;include 'include/macros.inc' +;include 'include/proc32.inc' +;include 'include/box_lib.mac' +;include 'include/dll.inc' include 'debug.inc' -version equ '0.65' -version_dword equ 0*10000h + 65 +version equ '0.70' +version_dword equ 0*10000h + 70 WIN_W = 400 - SIZE_COPY_BUF = 1024*1024*2 +MM_MAX_BLOCKS equ 1024 + virtual at 0 kfar_info_struc: @@ -82,15 +90,19 @@ end virtual - +;-- CODE ------------------------------------------------------------------- include 'parse.inc' include 'fs.inc' - -;-- CODE ------------------------------------------------------------------- +include 'file_tree.inc' +include 'memory_manager.inc' +include 'dialogs.inc' start: +;dnl +;dpsP params +;dnl mcall 68, 11 mcall 40, 100111b + 0C0000000h stdcall dll.Load, IMPORTS @@ -98,8 +110,6 @@ start: jnz exit mov [pathOut],0 -;stdcall SayErr,strErrorExc -;mcall -1 ;---------------------------- ;1. find input file, clear ;2. find -o, copy data, clear @@ -115,7 +125,7 @@ start: .arbeit: ;2. - call getParam2 + call getParamOutPath cmp eax, 2 je errorParsing @@ -145,9 +155,10 @@ start: je @f jmp @b .check: - call startUnpack - mcall -1 + call startUnpack + mcall -1 @@: + stdcall [OpenDialog_Init],OpenDialog_data ;init edit fields -------------- @@ -171,6 +182,9 @@ start: mov dword[edtUnpPath.size], eax mov dword[edtUnpPath.pos], eax +;-------- +; call file_tree_Init + ;main loop -------------------- wm_redraw: @@ -218,9 +232,9 @@ wm_button: cmp ah, 2 jne @f - ;mcall 51,1,startUnpack,stackUnpack - ;mov [bWinChild],1 - call startUnpack + mcall 51,1,startUnpack,stackUnpack + mov [bWinChild],1 + ;call startUnpack jmp wm_redraw @@: @@ -233,14 +247,16 @@ wm_mouse: jne still stdcall [edit_box_mouse],edtPack stdcall [edit_box_mouse],edtUnpPath - +; stdcall file_tree_Mouse jmp still exit: mcall -1 errorParsing: - dps 'errorParsing' +dph edx + + dps ' errorParsing' mcall -1 ;--- functions ------------------------------------------------------------------ @@ -259,7 +275,7 @@ proc winRedraw stdcall [edit_box_draw],edtPack stdcall [edit_box_draw],edtUnpPath - ; plain window labels + cmp [redInput],0 jne @f mov ecx,[sc.work_text] @@ -272,8 +288,6 @@ proc winRedraw mov ecx,[sc.work_text] or ecx,90000000h mcall 4, <15,37>, , strPath - - ; text on buttons mov ecx,[sc.work_button_text] or ecx,90000000h if lang eq ru @@ -284,6 +298,8 @@ end if mcall 4, <(WIN_W-47),12>, , strDots mcall 4, <(WIN_W-47),37>, , strDots +; call file_tree_Draw + mcall 12, 2 ret endp @@ -388,39 +404,26 @@ endl jnz @f cmp ebx,0 ;;/ КОСТЫЛЬ!!!! je .errNotFound ;;значение ebx получено опытным путём. - cmp ebx,400h ;;как оно будет работать с другими версиями - je .errNotSupp ;;библиотеки - не ясно! + cmp ebx,400h + je .errNotSupp @@: mov [hPlugin],eax ;get num of all files -; stdcall calcSizeArch,[hPlugin] -; push ebp -; stdcall [aReadFolder], [hPlugin] -; pop ebp - - - -; push ebp -; stdcall [aOpen], [hPlugin], .str1, O_READ -; pop ebp -; -; push ebp -; stdcall [aSetpos],[hPlugin],0,POSEND -; pop ebp -; add [numbytes],eax - - - + ; stdcall calcSizeArch,[hPlugin] + push ebp + stdcall [aSetFolder],[hPlugin], .strRoot,0 + pop ebp ;unpack ; void __stdcall GetFiles(HANDLE hPlugin, int NumItems, void* items[], void* addfile, void* adddir); push ebp stdcall [aGetFiles], [hPlugin], -1, 0, myAddFile, myAddDir pop ebp -;jmp @f -; .str1 db '/LICENSE.txt',0 -;@@: +jmp @f + .str1 db '/LICENSE.txt',0 + .strRoot db '.svn',0 +@@: ;HANDLE __stdcall open(HANDLE hPlugin, const char* filename, int mode); ;Открыть файл filename. Параметр mode зарезервирован и в текущей версии kfar всегда равен 1. @@ -491,13 +494,83 @@ proc debugInt3 endp +allnumbytes dd 0 +strBackFold db '../',0 + proc calcSizeArch hPlugin:dword +locals + bdwk rb 560 + num rd 1 +endl +;int __stdcall ReadFolder(HANDLE hPlugin, unsigned dirinfo_start, +; unsigned dirinfo_size, void* dirdata); + mov [num],0 + ; int3 +.mainloop: + push ebp + lea eax, [bdwk] + stdcall [aReadFolder], [hPlugin],[num],1,eax + pop ebp + + cmp eax,6 + je .lastFile +;?????????????????????????????????????????????????????????????????????????????????????????????????? + lea ebx,[bdwk+0x20] ;почему либа пишет в смещение +0x20 - неизестно + test [ebx],dword 10h + jz @f +;bool __stdcall SetFolder(HANDLE hPlugin, const char* relative_path, +; const char* absolute_path); + + push ebp + lea eax,[ebx+40] +dps 'Folder: ' +dpsP eax +dnl + stdcall [aSetFolder],[hPlugin], eax,0 + + pop ebp + stdcall calcSizeArch, [hPlugin] + inc [num] + jmp .mainloop + @@: + + lea ebx,[bdwk+0x20] +lea eax,[ebx+40] +dps 'File: ' +dpsP eax +dnl + mov eax,[ebx+32] + add [allnumbytes],eax + inc [num] + jmp .mainloop + +.lastFile: +; lea ebx,[bdwk+0x20] +; test [ebx],dword 10h +; jz @f +; +; push ebp +; lea eax,[ebx+40] +; stdcall [aSetFolder],[hPlugin], eax,0 +; pop ebp +; stdcall calcSizeArch, [hPlugin] +; @@: + + + push ebp + stdcall [aSetFolder],[hPlugin], strBackFold,0 + pop ebp + ret +endp + + +proc rec_calcSize hPlugin:dword locals bdwk rb 560 endl ;int __stdcall ReadFolder(HANDLE hPlugin, unsigned dirinfo_start, ; unsigned dirinfo_size, void* dirdata); -int3 +;bool __stdcall SetFolder(HANDLE hPlugin, const char* relative_path, const char* absolute_path); push ebp lea eax,[bdwk] stdcall [aReadFolder], [hPlugin],1,560,eax @@ -509,165 +582,37 @@ endp ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- -;SayErr int num_strings, const char* strings[], -; int num_buttons, const char* buttons[]); +hTrPlugin dd 0 -proc SayErr num_strings:dword, strings:dword,num_buttons:dword, buttons:dword - pushad - cmp [num_strings],1 - je @f - m2m [errmess0], strErrorExc - jmp .l1 - @@: - mov ebx,[strings] - m2m [errmess0], dword [ebx] - .l1: +;eax - file struct for sys70 - m2m [fsRunNotifyOK.param],[errmess0] - mcall 70,fsRunNotifyOK +proc rdFoldforTree +locals + fi rd 0 +endl + cmp [hTrPlugin],0 + je .exit + push ebx edi esi - popad - mov eax,1 - ret -endp + mov [fi],eax + push ebp + stdcall [aSetFolder],[hTrPlugin], [eax+20],0 + mov ebp,[esp] + ;hPlug,startBlock,numBlocks,buffer + stdcall [aReadFolder], [hTrPlugin],dword[eax+4],\ + dword[eax+12],dword[eax+16] + pop ebp -;------------------------------------------------------------------------------- -;------------------------------------------------------------------------------- -;------------------------------------------------------------------------------- - ; "enter password" dialog for KFar -;password_dlg: -; dd 1 ; use standard dialog colors -; dd -1 ; center window by x -; dd -1 ; center window by y -;.width dd ? ; width (will be filled according to current console width) -; dd 2 ; height -; dd 4, 2 ; border size -; dd aEnterPasswordTitle ; title -; dd ? ; colors (will be set by KFar) -; dd 0 ; used internally by dialog manager, ignored -; dd 0, 0 ; reserved for DlgProc -; dd 2 ; 2 controls -;; the string "enter password" -; dd 1 ; type: static -; dd 1,0 ; upper-left position -;.width1 dd ?,0 ; bottom-right position -; dd aEnterPassword ; data -; dd 0 ; flags -;; editbox for password -; dd 3 ; type: edit -; dd 1,1 ; upper-left position -;.width2 dd ?,0 ; bottom-right position -; dd password_data ; data -; dd 2Ch ; flags + ;cmp eax,6 + ;je .lastFile + ;lea ebx,[bdwk+0x20] ;почему либа пишет в смещение +0x20 - неизестно - -proc DialogBox dlgInfo:dword - pushad - mov ebx,[dlgInfo] - mov eax,[ebx+19*4] - mov [forpassword],eax - mov byte[eax], 0 - mov [stateDlg], 0 - mcall 51,1,threadDialogBox,stackDlg - - ;wait thread... - @@: cmp [stateDlg],0 - jne @f - mcall 5,1 - jmp @b - @@: - popad - cmp [stateDlg], 1 - jne @f - xor eax, eax - ret - @@: - or eax, -1 - ret -endp - -proc threadDialogBox - - mcall 40, 100111b+0C000000h - mov eax,[forpassword] - mov [edtPassword+4*9],eax - xor eax,eax - mov dword[edtPassword.size], eax - mov dword[edtPassword.pos], eax - -.wm_redraw: - mcall 12, 1 - mcall 48, 3, sc, sizeof.system_colors - mov edx, [sc.work] - or edx, 0x33000000 - mcall 0, <200,320>, <200,140>, , , title - - edit_boxes_set_sys_color edtPack,endEdits,sc - stdcall [edit_box_draw],edtPassword - - - mov ecx,[sc.work_text] - or ecx,90000000h - mcall 4, <56,12>, , strGetPass - - mcall 8, <70,80>,<74,22>,2,[sc.work_button] - mov ecx,[sc.work_button_text] - or ecx,90000000h - mcall 4, <103,79>, , strOk - - mcall 8, <165,80>,<74,22>,1,[sc.work_button] - mov ecx,[sc.work_button_text] - or ecx,90000000h - mcall 4, <182,79>, , strCancel - - - mcall 12, 2 - -.still: - mcall 10 - cmp eax, 1 - je .wm_redraw - cmp eax, 2 - je .wm_key - cmp eax, 3 - je .wm_button - cmp eax, 6 - je .wm_mouse - - jmp .still - -.wm_key: - mcall 2 - stdcall [edit_box_key],edtPassword - jmp .still - - -.wm_button: - mcall 17 - - cmp ah, 2 ;OK - jne @f - mov [stateDlg],1 - jmp .exit - @@: - - cmp ah, 1 ;Close window or Cancel - jne .still - mov [stateDlg],2 - jmp .exit - -.wm_mouse: - stdcall [edit_box_mouse],edtPassword - - - jmp .still - + pop esi edi ebx .exit: - mcall -1 + ret endp - ;-- DATA ------------------------------------------------------------------- @@ -679,7 +624,7 @@ bWinChild db 0 ;1 - redInput db 0 ;1 - подсветить красным надпись if lang eq ru - title db 'uNZ v0.12 - Распаковщик Zip и 7z',0 + title db 'uNZ v0.2 - Распаковщик Zip и 7z',0 strGo db 'Распаковать',0 strInp db ' Архив',0 strPath db 'Извлечь в',0 @@ -693,7 +638,7 @@ if lang eq ru strNotSupport db "'Неподдерживаемый формат архива' -E",0 strNotFound db "'Файл не найден' -E",0 else if lang eq es - title db 'uNZ v0.12 - Desarchivador para Zip y 7z',0 + title db 'uNZ v0.2 - Desarchivador para Zip y 7z',0 strGo db 'Desarchivar',0 strInp db 'Archivar',0 strPath db 'Extraer en',0 @@ -707,7 +652,7 @@ else if lang eq es strNotSupport db "'El formato del archivo no es soportado' -E",0 strNotFound db "'Archivo no encontrado' -E",0 else - title db 'uNZ v0.12 - Unarchiver of Zip and 7z',0 + title db 'uNZ v0.2 - Unarchiver of Zip and 7z',0 strGo db 'Unpack',0 strInp db 'Archive',0 strPath db 'Extract to',0 @@ -722,8 +667,9 @@ else strNotFound db "'File not found' -E",0 end if -strNull db 0 -strDots db '...',0 + + +strDots db '...', 0 ;-------- ; int __stdcall SayErr(int num_strings, const char* strings[], @@ -764,7 +710,7 @@ kfar_info: ;-------- -iFiles dd 0 ;количество выгружаемых файлов +iFiles dd 0 ;количество распаковываемых файлов endPointer dd buffer @@ -828,13 +774,15 @@ fsRunNotifyOK: edtPack edit_box (WIN_W-100-60),100,10,0FFFFFFh,0xff,0x80ff,0h,0x90000000,\ - 255, fInp, mouse_dd,0,0,0 + 255, fInp, 0,0,0,0 edtUnpPath edit_box (WIN_W-100-60),100,35,0FFFFFFh,0xff,0x80ff,0h,0x90000000,\ - 255, pathOut, mouse_dd,0,0,0 + 255, pathOut, 0,0,0,0 edtPassword edit_box 200,56,70,0FFFFFFh,0xff,0x80ff,0h,0x90000000,255,\ - password, mouse_dd,0,0,0 + password, 0,0,0,0 endEdits: + + ;------------------------------------------------------------------------------- OpenDialog_data: .type dd 0 ;0-open, 1-save, 2-select folder @@ -914,25 +862,24 @@ import box_lib,\ IncludeIGlobals +params1 db '-o "/hd0/1/unz/pig" -h "/hd0/1/unz/abc1"',0 ;-- UDATA ----------------------------------------------------------------------------- init_end: align 16 IncludeUGlobals +path rb 512 ;params db 'unz -o "fil epar1" -f "arch1.txt" -f "ar ch2.txt" file1',0 ;params db 'unz -o "fil epar1" -f arch1.txt -f "ar ch2.txt" file1',0 -;params db '/hd0/1/unz/xboot-1-0-build-14-en-win.zip',0 -;rb 4096 fInp rb 1024 -pathOut rb 1024 +pathOut rb 1024 ;путь, куда распакуется всё files rd 256 password rb 256 fZipInfo rb 40 -mouse_dd rd 1 RBProcInfo rb 1024 temp_dir_pach rb 1024 ODAreaPath rb 1024 @@ -954,9 +901,17 @@ CopyDestEditBuf rb 12+512+1 bdvkPack rb 560 + + +;------------ memory_manager.inc +align 4 +MM_NBlocks rd 1 ;количество выделенных блоков памяти +MM_BlocksInfo rd 2*MM_MAX_BLOCKS ;begin,size + + ;-------- -buffer rb 4096 ;for string of file name or extract +buffer rb 4096 ;for string of file name for extract params rb 4096 rb 1024