Рекурсия, с чего начать?

Тема в разделе "WASM.BEGINNERS", создана пользователем Everhest, 1 июн 2008.

  1. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    Здраствуйте, я тут собрался сделать маленькую процедурку для поиска файлов по всему компьютеру и в голову пришла мысль о организации рекурсии. Проблема в том, что самая большая рекурсионная процедура которую я делал:

    Код (Text):
    1. proc Factorial r_fact
    2.    push bp
    3.    mov  bp, sp
    4.    mov  cx, [bp+4]
    5.    mov  ax, cx
    6.    mul   [r_fact]
    7.    mov  [r_fact], ax
    8.    dec   cx
    9.    jz      end_p
    10.    push  cx
    11.    call    Factorial
    12.  end_p:
    13.    mov   sp, bp
    14.    pop    bp
    15.    ret
    16. end
    Передо мной встало несколько вопросов:

    1. Стек по сути дела не потходит, значит сколько нам надо выделить памяти для процедуры.
    2. Как основать структуру для поиска:
    3. В чем я не прав? Моя фича заходит только в первый найденый каталог.

    Код (Text):
    1. include '..\..\include\win32ax.inc'
    2. include '..\..\include\encoding\win1251.inc'
    3.  
    4. .data
    5.         path            db 'C:\*.*',0
    6.         ext             db '*.*',0
    7.  
    8.         hmem            dd ?
    9.  
    10.         buffer          rb 260
    11.         string_buffer   rb 260
    12.         path_buffer     rb 260
    13.         path_default    rb 260
    14.  
    15.         fdata           rb 100*(sizeof.WIN32_FIND_DATA)
    16.  
    17. .code
    18.   start:
    19.         invoke  GetModuleHandle,0
    20.         invoke  DialogBoxParam,eax,IDD_FIND,HWND_DESKTOP,DialogProc,0
    21.   close:
    22.         invoke  ExitProcess,0
    23.  
    24. proc DialogProc hwnddlg,msg,wparam,lparam
    25.         push    ebx esi edi
    26.         cmp     [msg],WM_INITDIALOG
    27.         je      .wminitdialog
    28.         cmp     [msg],WM_COMMAND
    29.         je      .wmcommand
    30.         cmp     [msg],WM_CLOSE
    31.         je      .wmclose
    32.         xor     eax,eax
    33.         jmp     .finish
    34.   .wminitdialog:
    35.         jmp     .processed
    36.   .wmcommand:
    37.         movsx   eax,word[wparam]
    38.         cmp     eax,IDB_CLOSE
    39.         je      .wmclose
    40.         cmp     eax,IDB_FIND
    41.         je      .find
    42.         jmp     .processed
    43.  
    44.   .find:
    45.         invoke  GetDlgItem,[hwnddlg],IDB_LIST
    46.         xchg    eax, ebx
    47.         invoke  SendMessage,ebx,LB_RESETCONTENT,0,0
    48.         stdcall FindFiles,ebx,path,FLAG_FIND_DIRECTORIES
    49.         jmp     .processed
    50.  
    51.   .wmclose:
    52.         invoke  EndDialog,[hwnddlg],0
    53.   .processed:
    54.         mov     eax,1
    55.   .finish:
    56.         pop     edi esi ebx
    57.         ret
    58. endp
    59.  
    60.  
    61. proc AssignArray array, mem, size
    62.  
    63.         cld
    64.         mov     esi, [mem]
    65.         mov     edi, [array]
    66.         mov     ecx, [size]
    67.         rep     movsb
    68.         ret
    69. endp
    70.  
    71.  
    72. ;  size   = 20
    73. ;  index  = 2
    74. ;  mem    = 4
    75. ;  result = 44
    76.  
    77.  
    78. proc GetBaseItem mem, size, index          ; size*index+mem=result
    79.  
    80.         mov     eax, dword[index]
    81.         imul    eax, dword[size]
    82.         add     eax, dword[mem]
    83.         ret
    84. endp
    85.  
    86. proc ExtractFilePath buffer, path
    87.      push       eax
    88.      push       ecx
    89.      push       esi
    90.      push       edi
    91.      pushf
    92.      stdcall    ScanDecimalStr, [path]
    93.    local
    94.    extract_of_str:
    95.      cld
    96.      mov        esi, [path]
    97.      mov        edi, [buffer]
    98.    local
    99.    extract_path:
    100.      lodsb
    101.      cmp        al, '\'
    102.      je         dec_str
    103.      cmp        al, '/'
    104.      je         dec_str
    105.      cmp        ecx, 0
    106.      je         end_of_str
    107.      stosb
    108.      jmp        extract_path
    109.    local
    110.    dec_str:
    111.      stosb
    112.      sub        ecx, 1
    113.      jmp        extract_path
    114.    local
    115.    end_of_str:
    116.      mov        al, 0
    117.      stosb
    118.      popf
    119.      pop        edi
    120.      pop        esi
    121.      pop        ecx
    122.      pop        eax
    123.      ret
    124. endp
    125.  
    126. proc ScanDecimalStr buffer
    127.  
    128.      push       eax
    129.      push       esi
    130.      pushf
    131.      cld
    132.      mov        esi, [buffer]
    133.      xor        ecx, ecx
    134.    local
    135.    .str_find_decimal:
    136.      lodsb
    137.      cmp        al, '\'
    138.      je         .ok_separator
    139.      cmp        al, '/'
    140.      je         .ok_separator
    141.      cmp        al, 0
    142.      je         .end_find
    143.      jmp        .str_find_decimal
    144.    local
    145.    .ok_separator:
    146.      add        ecx, 1
    147.      jmp        .str_find_decimal
    148.    local
    149.    .end_find:
    150.      popf
    151.      pop        esi
    152.      pop        eax
    153.      ret
    154. endp
    155.  
    156. proc SetDownDir buffer, path, ext
    157.  
    158.         invoke wsprintf,[buffer],format.path, [path], [ext]
    159.         ret
    160.  
    161.         format.path     db '%s\%s',0
    162. endp
    163.  
    164. proc IsBackDir buffer
    165.  
    166.         invoke  lstrcmpi,back.catalog1,[buffer]
    167.         je      catalog.true
    168.  
    169.         invoke  lstrcmpi,back.catalog2,[buffer]
    170.         je      catalog.true
    171.         xor     eax, eax
    172.         ret
    173.       catalog.true:
    174.         xor     eax, eax
    175.         inc     eax
    176.         ret
    177.  
    178.         back.catalog1    db '..',0
    179.         back.catalog2    db '.', 0
    180. endp
    181.  
    182. ;struct WIN32_FIND_DATA                bytes
    183. ;  dwFileAttributes   dd ?               4
    184. ;  ftCreationTime     FILETIME           8
    185. ;  ftLastAccessTime   FILETIME           8
    186. ;  ftLastWriteTime    FILETIME           8
    187. ;  nFileSizeHigh      dd ?               4
    188. ;  nFileSizeLow       dd ?               4
    189. ;  dwReserved0        dd ?               4
    190. ;  dwReserved1        dd ?               4        44
    191. ;  cFileName          TCHAR MAX_PATH dup (?)
    192. ;  cAlternateFileName TCHAR 14 dup (?)
    193. ;ends
    194.  
    195.  
    196. proc FindFiles hlist, buffer, param
    197.      local hfind     :dd 0
    198.      local offset    :dd 0
    199.      local nesting   :dd 0
    200.  
    201.       find.init:
    202.         stdcall ExtractFilePath,path_default,[buffer]
    203.         stdcall GetBaseItem,fdata,sizeof.WIN32_FIND_DATA,[param]
    204.         mov     [offset], eax
    205.         mov     eax, [param]
    206.         mov     [nesting], eax
    207.  
    208.       find.first:
    209.         mov     eax, dword[fdata]
    210.         add     eax, [offset]
    211.         invoke  FindFirstFile,[buffer],eax
    212.         cmp     eax, INVALID_HANDLE_VALUE
    213.         jz      find.error
    214.         mov     [hfind], eax
    215.       find.next:
    216.         mov     ebx, dword[fdata]
    217.         add     ebx, [offset]
    218.         add     ebx, 44
    219.         stdcall IsBackDir, ebx
    220.         test    eax, eax
    221.         jne      find.data
    222.         sub     ebx, 44
    223.         cmp     dword[ebx], FILE_ATTRIBUTE_DIRECTORY
    224.         je      find.dir
    225.  
    226.       find.file:
    227.         mov     eax, dword[fdata]
    228.         add     eax, [offset]
    229.         add     eax, 44
    230.         invoke  SendMessage,[hlist],LB_ADDSTRING,0,eax
    231.         jmp     find.data
    232.  
    233.       find.dir:
    234.         mov     eax, dword[fdata]
    235.         add     eax, [offset]
    236.         add     eax, 44
    237.         inc     [nesting]
    238.         invoke  lstrcat,path_default, eax
    239.         stdcall SetDownDir,path_buffer,path_default,ext
    240.  
    241.         invoke  MessageBox,0,path_buffer,0,0
    242.         invoke  SendMessage,[hlist],LB_ADDSTRING,0,string_buffer
    243.         stdcall FindFiles,[hlist],path_buffer, [nesting]
    244.         jmp     find.data
    245.  
    246.       find.data:
    247.         mov     eax, dword[fdata]
    248.         add     eax, [offset]
    249.         invoke  FindNextFile,[hfind], eax
    250.         cmp     eax,0
    251.         je      find.close
    252.         jmp     find.next
    253.       find.close:
    254.         invoke  FindClose,[hfind]
    255.         ret
    256.       find.error:
    257.         invoke  FindClose,[hfind]
    258.         xor     eax, eax
    259.         dec     eax
    260.         ret
    261. endp
    262.  
    263.         IDD_FIND        = WM_USER+0
    264.         IDB_FIND        = WM_USER+1
    265.         IDB_CLOSE       = WM_USER+2
    266.         IDB_LIST        = WM_USER+3
    267.  
    268.         FLAG_FIND_ERROR           = -1     ; Возрат ошибки
    269.         FLAG_FIND_DIRECTORIES     =  0     ; Искать в каталогах
    270.         FLAG_FIND_NOT_DIRECTORIES = -2     ; Не искать в папках
    271.  
    272. .end    start
    273.  
    274. section '.rsrc' resource data readable
    275.  
    276.   directory RT_DIALOG,dialogs
    277.  
    278.   resource dialogs,\
    279.            IDD_FIND,LANG_ENGLISH+SUBLANG_DEFAULT,find_dialog
    280.  
    281.   dialog find_dialog,'Рекурсивный поиск фалов',60,60,254,172,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME
    282.     dialogitem 'LISTBOX',0,IDB_LIST,4,4,200,170,WS_VISIBLE+WS_CHILD+WS_BORDER
    283.     dialogitem 'BUTTON','Искать',IDB_FIND,206,6,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON
    284.     dialogitem 'BUTTON','Выход',IDB_CLOSE,206,22,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON
    285.   enddialog
    Жду вашей помощи.

    Прошу не ругать, FASM'ом занимаюсь меньше года, а программированием в целом меньше двух.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Нафиг темы дублировать ?
    Тебе сюда:
    http://www.wasm.ru/forum/viewtopic.php?id=25322&p=2
    EnumerateFiles()
     
  3. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    Clerk

    Знаешь спасибо за подсказку, но мне нужен хороший рекурсионный пример и кстати ссылка твоя не работает.
     
  4. asmlamo

    asmlamo Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    1.742
    Чтобы начать с рекурсии нужно начать с рекурcии :)

    Вот код по поиску файла пробегал:

    Код (Text):
    1. SearchForFile PROC StartPath:DWORD,FileToFind:DWORD
    2.  
    3.     LOCAL   WFD:WIN32_FIND_DATA ; used for file/folder search
    4.     LOCAL   fPath[260]:BYTE     ; used to store StartPath locally
    5.     LOCAL   fPath2[260]:BYTE    ; we add sub-folders names onto this to form full paths
    6.     LOCAL   hFind:DWORD     ; find handle
    7.  
    8.     ; Below is just some little data's that we need in order for function to work
    9.    
    10.     jmp @F
    11.     WildCard db "\*",0      ; search ALL files
    12.     CRLF db 13,10,0         ; tell me you don't know what this is
    13.     foundat db "Found: ",0      ; tell the user we found a file that matches
    14.     @@:
    15.         lea edi,fPath
    16.         push edi    ; save EDI in stack
    17.         mov esi,StartPath   ; we are copying supplied StartPath to our buffer
    18.         mov ecx,256     ; all 256 bytes
    19.         rep movsb       ; copy path
    20.  
    21.         pop edi     ; put the path back in EDI
    22.  
    23.         xor al,al       ; clear AL
    24.  
    25.         @GetToChar      ; Find the first zero
    26.  
    27.         mov al,'\'      ; now equals Drive:\Path\*
    28.         stosb           ; e.g.: C:\Windows\*
    29.         mov al,'*'
    30.         stosb          
    31.        
    32.         @ClearFN        ; clears the cFileName field in Win32_Find_Data
    33.            
    34.         invoke FindFirstFile,addr fPath,addr WFD    ; find first file
    35.        
    36.         push eax        ;
    37.         mov hFind,eax       ; save FindHandle
    38.         pop ebx         ; put handle in EBX
    39.        
    40.         .while ebx > 0      ; while a file is found..
    41.             lea esi,WFD.cFileName
    42.             lodsw       ; get first two chars
    43.  
    44.             .if AX!=02E2Eh && AX!=0002Eh    ; '..' and '.'     
    45.  
    46.               lea edi,WFD
    47.               mov eax,[edi] ; file attributes
    48.               .if ax & FILE_ATTRIBUTE_DIRECTORY ; is it a directory?
    49.                 sub esi,2       ; undo the lodsw
    50.                 lea edi,fPath2      ; load up the secondary path in EDI
    51.                 push edi        ; save it on the stack...
    52.            
    53.                 xor al,al       ; clear secondary path
    54.                 mov ecx,260     ; ..
    55.                 rep stosb
    56.                
    57.                 mov edi,[esp]       ; restore EDI
    58.                
    59.                 lea eax,fPath       ; first path
    60.                
    61.                 invoke lstrcpy,edi,eax  ; copy first to second
    62.                
    63.                 mov al,'*'      ; get to the end....
    64.                 @GetToChar
    65.                
    66.                 mov byte ptr [edi],00h  ; delete the wildcard
    67.                
    68.                 invoke lstrcat,edi,esi  ; tack on the new directory name
    69.                 pop edi         ; restore EDI from stack
    70.  
    71.                 pushad          ; must save ALL regs or errors will ocur :)
    72.                     invoke SearchForFile,edi,FileToFind  ; call function again
    73.                 popad           ; restore all regs
    74.                
    75.               .else
    76.              
    77.                 sub esi,2   ; undo the lodsw
    78.                 invoke lstrcmpi,FileToFind,esi  ; case insensitive compare
    79.                 or eax,eax  ; are they equal?
    80.                 jz found_file   ; if eax=0 they are equal
    81.              
    82.               .endif
    83.            
    84.             .endif
    85.            
    86.             @ClearFN    ; Clear the cFileName field again
    87.                
    88.             invoke FindNextFile,hFind,addr WFD
    89.             mov ebx,eax
    90.        
    91.         .endw
    92. __cls_fnd:
    93.             invoke FindClose,hFind  ; close it up
    94.        
    95.         ret
    96.  
    97. found_file:                      ; Если найден файл !
    98.     lea edi,fPath2
    99.     invoke lstrcpy,edi,addr fPath
    100.    
    101.     mov al,'*'
    102.     scasb
    103.     jnz $-1
    104.    
    105.     dec edi
    106.     mov byte ptr [edi],00h
    107.    
    108.     lea edi,WFD.cFileName
    109.     invoke lstrcat,addr fPath2,edi ; Выводим результат поиска
    110. ;   invoke StdOut,addr foundat
    111.  
    112. ;   invoke StdOut,addr fPath2 ; Имя файла
    113.  
    114.        invoke  MessageBox,0,addr fPath2,addr fPath2 ,0 ; Выводим сообщение
    115.  
    116. ;   invoke StdOut,addr CRLF
    117.  
    118. ;       invoke CreateProcess, ADDR fPath2, NULL, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS, NULL, NULL,ADDR sInfo, ADDR pInfo
    119.  
    120. ;   jmp __cls_fnd
    121.  
    122. jmp leave_prog
    123.  
    124. SearchForFile ENDP
     
  5. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    asmlamo

    Пример и вправду хороший, благодарю. Моя цель в том, что бы осмыслить код, а не заниматься COPY\PASTE, помогите сказав в чем мои ошибки.
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Everhest
    Вот тупо на винапи старый код:
    Код (Text):
    1. SRC32FILES struct
    2. nFile   dd ?
    3. nDir    dd ?
    4. SRC32FILES ends
    5.  
    6. FIND32 struct
    7. SignL   dd ?        ;Сигнатура 'xSea'
    8. SignH   dd ?        ;Сигнатура 'rch_'
    9. hMem    dd ?        ;хэндл памяти
    10. nFile   dd ?        ;число найденных файлов
    11. nDir    dd ?        ;число найденных папок
    12. pHandle dd ?        ;номер текущего элемента таблицы дескрипторов *4
    13. Handles dd MAX_PATH dup (0) ;таблица дескрипторов FindFirstFile
    14. wfd WIN32_FIND_DATA <>  ;Структура принимающая информацию о найденном файле
    15. lBuf    db MAX_PATH dup (0) ;буфер строки с путём + '\*'
    16. FIND32 ends
    17. .code
    18. ;-------------------------------------------------------------------------------   
    19. StartSearch proc uses edi esi lpDir:dword,srcWfd:dword
    20. Local Vari:dword,srcfiles:SRC32FILES
    21. ;Процедура инициализации параметров поиска
    22. ;Выделяем память
    23.     invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,sizeof FIND32 ;выделяем блок памяти
    24.     mov Vari,eax        ;hMem
    25.     invoke GlobalLock,eax   ;Определяем адрес его
    26.     mov edi,eax ;указатель на FIND32
    27.     assume edi:ptr FIND32
    28.     mov eax,Vari
    29.     mov [edi].hMem,eax      ;хэндл памяти
    30.     mov [edi].SignL,'xSea'  ;младший DWORD сигнатуры структуры
    31.     mov [edi].SignH,'rch_'  ;старший DWORD сигнатуры структуры
    32.     xor eax,eax
    33.     mov [edi].pHandle,eax       ;pHandle указывает на первый элемент Handles
    34.     mov [edi].nFile,eax
    35.     mov [edi].nDir,eax     
    36.     lea esi,[edi].lBuf      ;esi-адрес строки в буфере
    37.     invoke lstrcpy,esi,lpDir    ;копируем путь в буфер
    38.     invoke GetFileAttributes,esi    ;<ERROR_PATH_NOT_FOUND>
    39.     cmp eax,-1
    40.     jz initerr_
    41.     invoke lstrlen,esi      ;определяем длину пути
    42.     add eax,esi     ;...0
    43.     cmp byte ptr [eax-1],'\'
    44.     .if Zero?
    45.     dec eax
    46.     .endif
    47.     mov dword ptr [eax],'*\'    ;добавляем его
    48.     lea eax,[edi].wfd  
    49.     invoke FindFirstFile,esi,eax    ;начинаем поиск
    50.     mov Vari,eax        ;хэндл поиска
    51.     cmp eax,INVALID_HANDLE_VALUE
    52.     jz initerr_
    53.     lea ecx,[edi].Handles   ;адрес текущего элемента таблицы хэндлов
    54.     mov [ecx],eax       ;сохраняем хэндл поиска
    55.     add [edi].pHandle,4     ;указатель на следующий элемент таблица
    56.     cmp byte ptr [edi].wfd.cFileName,'.'   
    57.     .if !Zero?
    58.        mov eax,[edi].wfd.dwFileAttributes
    59.        test eax,16
    60.        .if Zero?
    61.        inc [edi].nFile
    62.        .else
    63.        inc [edi].nDir
    64.        .endif
    65.     .else
    66.     invoke Search,edi,addr srcfiles
    67.     test eax,eax
    68.     jz pexit_
    69.     .endif
    70. findok_:
    71.     mov edx,srcWfd      ;указатель на адрес wfd
    72.     lea eax,[edi].wfd       ;адрес wfd
    73.     mov [edx],eax       ;сохраняем pWfd   
    74.     mov eax,edi     ;адрес структуры возвращаем в качестве хэндла поиска  
    75.     jmp pexit_         
    76. initerr_:      
    77.     mov edi,[edi].hMem
    78.     invoke GlobalUnlock,edi
    79.     invoke GlobalFree,edi
    80.     xor eax,eax
    81. pexit_:
    82.     ret
    83. StartSearch endp
    84. ;-------------------------------------------------------------------------------
    85. FindSlash proc
    86.     lea eax,[edi].lBuf
    87.     invoke lstrlen,eax
    88.     sub eax,3
    89.     lea edx,[edi].lBuf
    90.     add eax,edx
    91. slashlp:
    92.     dec eax
    93.     cmp byte ptr [eax],'\'
    94.     jz slashok
    95.     cmp byte ptr [eax],'\'
    96.     jz slashok 
    97.     cmp eax,edx
    98.     ja slashlp
    99.     xor eax,eax    
    100. slashok:
    101.     test eax,eax
    102.     .if !Zero?
    103.     mov dword ptr [eax],'*\'    ;...\*
    104.     .endif
    105.     ret
    106. FindSlash endp
    107. ;-------------------------------------------------------------------------------
    108. Search proc uses edi esi pMem:dword,pInfo:dword
    109. Local Vari:dword
    110.     mov edi,pMem
    111.     assume edi:ptr FIND32
    112.     mov eax,[edi].SignL         ;проверяем сигнатуру
    113.     cmp eax,'xSea'
    114.     jnz handleerr_
    115.     mov eax,[edi].SignH
    116.     cmp eax,'rch_'
    117.     jnz handleerr_
    118.     lea esi,[edi].lBuf          ;адрес строки в буфере
    119. next1_:
    120.     mov eax,[edi].pHandle
    121.     test eax,eax
    122.     jz closesrc_
    123.     mov al,byte ptr [edi].wfd.cFileName
    124.     cmp al,'.'          ;если вызывается из StartSearch
    125.     jz findfile_       
    126.     mov eax,[edi].wfd.dwFileAttributes
    127.     test eax,16         ;если не ноль то файл - каталог
    128.     jz findfile_
    129.     invoke lstrlen,esi
    130.     add eax,esi         ;Path\*0
    131.     dec eax             ;Path\*
    132.     lea edx,[edi].wfd.cFileName
    133.     invoke lstrcpy,eax,edx      ;дописываем имя каталога,Path\FileName0
    134.     invoke lstrlen,esi          ;длина строки в буфере
    135.     add eax,esi         ;...0
    136.     mov dword ptr [eax],'*\'        ;Path\FileName0\*
    137.     lea eax,[edi].wfd
    138.     invoke FindFirstFile,esi,eax   
    139.     cmp eax,INVALID_HANDLE_VALUE   
    140.     jz finddirerr_
    141.     mov edx,[edi].pHandle
    142.     lea ecx,[edi].Handles
    143.     mov [edx+ecx],eax
    144.     add [edi].pHandle,4
    145.     jmp nextfile_          
    146. finddirerr_:
    147.     invoke FindSlash
    148. findfile_:
    149.     lea edx,[edi].wfd           ;адрес Wfd
    150.     lea ecx,[edi].Handles - 4
    151.     mov eax,[edi].pHandle          
    152.     mov eax,[eax+ecx]
    153.     invoke FindNextFile,eax,edx
    154.     test eax,eax
    155.     jnz nextfile_
    156.     invoke GetLastError
    157.     cmp eax,ERROR_NO_MORE_FILES     ;в директории больше файлов не найдено
    158.     jnz findfile_  
    159.     mov edx,[edi].pHandle       ;указатель на хэндл поиска   
    160.     lea ecx,[edi].Handles - 4
    161.     mov eax,[edx+ecx]
    162.     invoke FindClose,eax
    163.     sub [edi].pHandle,4
    164.     jz closesrc_
    165.     invoke FindSlash            ;в каталоге больше нет файлов
    166.     jmp findfile_      
    167. nextfile_:
    168.     mov al,byte ptr [edi].wfd.cFileName
    169.     cmp al,'.'
    170.     jz findfile_
    171.     mov eax,[edi].wfd.dwFileAttributes
    172.     test eax,16
    173.     .if Zero?
    174.     inc [edi].nFile
    175.     .else
    176.     inc [edi].nDir
    177.     .endif
    178.     mov edx,pInfo
    179.     mov eax,[edi].nFile
    180.     mov dword ptr [edx],eax
    181.     mov eax,[edi].nDir
    182.     mov [edx+4],eax
    183.     mov eax,edi         ;адрес структуры возвращаем в качестве хэндла поиска  
    184.     jmp pexit_
    185. handleerr_:
    186.     invoke SetLastError,ERROR_INVALID_HANDLE
    187.     mov eax,INVALID_HANDLE_VALUE   
    188.     jmp pexit_ 
    189. closesrc_:
    190.     mov edi,[edi].hMem
    191.     invoke GlobalUnlock,edi ;освобождаем память
    192.     invoke GlobalFree,edi
    193.     invoke SetLastError,ERROR_NO_MORE_FILES
    194.     xor eax,eax
    195. pexit_:        
    196.     ret
    197. Search endp
    198. ;-------------------------------------------------------------------------------
    199. StopSearch proc uses edi esi pMem:dword
    200.     mov edi,pMem
    201.     assume edi:ptr FIND32
    202.     mov eax,[edi].SignL     ;проверяем сигнатуру
    203.     cmp eax,'xSea'
    204.     jnz memerr_
    205.     mov eax,[edi].SignH
    206.     cmp eax,'rch_'
    207.     jnz memerr_
    208.     mov esi,[edi].pHandle
    209.     test esi,esi
    210.     jz freemem_
    211.    
    212.     push edi
    213.     lea edi,[edi].Handles - 4
    214. stoplp_:
    215.     mov eax,dword ptr [edi+esi]
    216.     invoke FindClose,eax
    217.     sub esi,4
    218.     jnc stoplp_
    219.     pop edi
    220.  
    221.     mov edi,[edi].hMem
    222.     invoke GlobalUnlock,edi ;освобождаем память
    223.     invoke GlobalFree,edi
    224.     mov eax,TRUE
    225.     jmp pexit_
    226. freemem_:
    227.     invoke SetLastError,ERROR_SUCCESS
    228.     mov eax,TRUE
    229.     jmp pexit_
    230. memerr_:
    231.     invoke SetLastError,ERROR_INVALID_HANDLE
    232.     mov eax,INVALID_HANDLE_VALUE   
    233. pexit_:
    234.     ret
    235. StopSearch endp
    236. end
    Код (Text):
    1. StartSearch proto :dword,:dword     ;ptr lpPath,ptr dwWfd
    2. ;Начинает перечисление файлов
    3. ;1-й параметр: указатель на путь поиска например C:\Windows или D:\
    4. ;2-й параметр: указатель на двойное слово принимающее адрес структуры SRC32 через которую передаётся информация о найденном файле
    5. ;Возвращается в случае успеха хэндл поиска,иначе ноль
    6. Search      proto :dword,:dword     ;hSrc,ptr SRC32FILES
    7. ;вызывается циклически для перечисления файлов.
    8. ;1-й параметр: хэндл поиска,возвращённый StartSearch
    9. ;2-й параметр: указатель на структуру SRC32FILES,принимающую общее число найденых файлов и папок
    10. ;Возвращается в случае успеха указатель на двойное слово принимающее адрес структуры SRC32 через которую передаётся информация о найденном файле,
    11. ;если ноль то поиск закончен
    12. StopSearch  proto :dword        ;hSrc
    13. ;Принудительно завершает перечисление.
    14. ;1-й параметр: хэндл поиска
    15.  
    16. SRC32FILES struct  
    17. nFiles  dd ?    ;Число файлов,увеличивается на 1 с каждым найденным файлом
    18. nDir    dd ?    ;Число папок,увеличивается на 1 с каждой найденной папкой
    19. SRC32FILES ends
    20.  
    21. SRC32 struct
    22. wfd WIN32_FIND_DATA <>  ;Структура принимающая информацию о найденном файле
    23. lBuf    db MAX_PATH dup (0) ;буфер строки с путём + '\*'
    24. SRC32 ends
    Код (Text):
    1. .data
    2. WinDir  db MAX_PATH dup (0)
    3. SrcFiles    SRC32FILES <>
    4. dwWfd   dd ?
    5. hSrc    dd ?
    6. ;.....................................................................
    7. lpExt   db ".exe",".dll",".ocx",".avi",".bmp",".jpg",".gif",".ico",".doc",".hlp",".sys",0,0,0,0
    8. ;.....................................................................
    9. nExe    dd 0
    10. nDll    dd 0
    11. nOcx    dd 0
    12. nAvi    dd 0
    13. nBmp    dd 0
    14. nJpg    dd 0
    15. nGif    dd 0
    16. nIco    dd 0
    17. nDoc    dd 0
    18. nHlp    dd 0
    19. nSys    dd 0
    20.  
    21. nSystem dd 0
    22. nHidden dd 0
    23. nRead   dd 0
    24. ;.....................................................................
    25. lpMsgCapt   db "Íàéäåíî_",0
    26. lpFiles db "Ôàéëîâ ",0
    27. lpDir   db "Ïàïîê ",0
    28. lpSys   db "Ñèñòåìíûõ ",0 
    29. lpHid   db "Ñêðûòûõ ",0
    30. lpRead  db "Äëÿ ÷òåíèÿ ",0
    31. .code
    32. NumToMsg proc pMsg_:dword,sizeMsg:dword,Value:dword
    33.     invoke lstrlen,esi 
    34.     add esi,eax
    35.     mov byte ptr [esi],13
    36.     inc esi        
    37.     invoke lstrcpy,esi,pMsg_   
    38.     add esi,sizeMsg
    39.     dec esi
    40.     mov dword ptr [esi],0
    41.     mov dword ptr [esi+4],0
    42.     invoke udw2str,Value,esi
    43.     ret
    44. NumToMsg endp  
    45. ;-------------------------------------------------------------------------------
    46. start:
    47.     invoke GetWindowsDirectory,addr WinDir,MAX_PATH
    48.     invoke StartSearch,addr WinDir,addr dwWfd
    49.     test eax,eax
    50.     jz exit_
    51.     mov hSrc,eax
    52. loopsrc_:
    53.     mov edx,dwWfd
    54.     assume edx:ptr SRC32
    55.     mov eax,[edx].wfd.dwFileAttributes
    56.     test eax,FILE_ATTRIBUTE_HIDDEN
    57.     .if !Zero?
    58.     inc nHidden
    59.     .endif
    60.     test eax,FILE_ATTRIBUTE_SYSTEM
    61.     .if !Zero?
    62.     inc nSystem
    63.     .endif
    64.     test eax,FILE_ATTRIBUTE_READONLY
    65.     .if !Zero?
    66.     inc nRead
    67.     .endif
    68.     test eax,FILE_ATTRIBUTE_DIRECTORY
    69.     jnz findnext_       ;êàòàëîã
    70.     lea eax,[edx].wfd.cFileName
    71.     push eax
    72.     invoke lstrlen,eax
    73.     pop edx
    74.     add edx,eax     ;...0
    75.     cmp eax,4
    76.     jc findnext_
    77.     mov eax,dword ptr [edx-4]
    78.     or eax,00100000001000000010000000000000b
    79.     cmp eax,'exe.'
    80.     jnz @F
    81.     inc nExe
    82.     jmp findnext_
    83. @@:
    84.     cmp eax,'lld.'
    85.     jnz @F
    86.     inc nDll
    87.     jmp findnext_
    88. @@:
    89.     cmp eax,'xco.'
    90.     jnz @F
    91.     inc nOcx
    92.     jmp findnext_
    93. @@:
    94.     cmp eax,'iva.'
    95.     jnz @F
    96.     inc nAvi
    97.     jmp findnext_
    98. @@:
    99.     cmp eax,'pmb.'
    100.     jnz @F
    101.     inc nBmp
    102.     jmp findnext_  
    103. @@:
    104.     cmp eax,'gpj.'
    105.     jnz @F
    106.     inc nJpg
    107.     jmp findnext_
    108. @@:
    109.     cmp eax,'fig.'
    110.     jnz @F
    111.     inc nGif
    112.     jmp findnext_  
    113. @@:
    114.     cmp eax,'oci.'
    115.     jnz @F
    116.     inc nIco
    117.     jmp findnext_
    118. @@:
    119.     cmp eax,'cod.'
    120.     jnz @F
    121.     inc nDoc
    122.     jmp findnext_          
    123. @@:
    124.     cmp eax,'plh.'
    125.     jnz @F
    126.     inc nHlp
    127.     jmp findnext_
    128. @@:
    129.     cmp eax,'sys.'
    130.     jnz findnext_
    131.     inc nSys
    132. findnext_:
    133.     invoke Search,hSrc,addr SrcFiles
    134.     test eax,eax
    135.     jnz loopsrc_
    136.     lea esi,WinDir
    137.     lea edi,lpExt
    138. enumlp_:
    139.     invoke lstrlen,esi
    140.     add esi,eax
    141.     mov byte ptr [esi],13
    142.     inc esi
    143.     mov eax,[edi]
    144.     test eax,eax
    145.     jz endenum_
    146.     mov dword ptr [esi],eax
    147.     mov dword ptr [esi+4],'    '
    148.     add esi,8
    149.     mov dword ptr [esi],0
    150.     mov dword ptr [esi+4],0
    151.     mov dword ptr [esi+8],0
    152.     mov eax,dword ptr [edi + sizeof lpExt]
    153.     add edi,4
    154.     invoke udw2str,eax,esi
    155.     jmp enumlp_
    156. endenum_:
    157.     invoke lstrcpy,esi,addr lpFiles
    158.     add esi,sizeof lpFiles - 1
    159.     mov dword ptr [esi],0
    160.     mov dword ptr [esi+4],0
    161.     lea eax,SrcFiles
    162.     mov eax,[eax]
    163.     invoke udw2str,eax,esi
    164.     lea eax,SrcFiles
    165.     mov eax,[eax+4]
    166.     invoke NumToMsg,addr lpDir,sizeof lpDir,eax
    167.     invoke NumToMsg,addr lpSys,sizeof lpSys,nSystem
    168.     invoke NumToMsg,addr lpHid,sizeof lpHid,nHidden
    169.     invoke NumToMsg,addr lpRead,sizeof lpRead,nRead
    170.     invoke MessageBox,0,addr WinDir,addr lpMsgCapt,MB_OK   
    171.     invoke StopSearch,hSrc
    172. exit_:
    173.     invoke ExitProcess,0
    174. end start
     
  7. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Everhest
    Может в вызове этого?

    PS архивируйте длинные листинги и аттачте. Очень вас прошу.
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Вот из пакета на нативе, рекурсия:
    Код (Text):
    1. EnumerateFileInDirectoryW proc uses ebx DirectoryName:PUNICODE_STRING, DirectoryHandle:HANDLE, EnumerateCallback:PVOID, EnumerateParameter:DWORD
    2. Local FileHandle:HANDLE
    3. Local ObjAttr:OBJECT_ATTRIBUTES
    4. Local IoStatusBlock:IO_STATUS_BLOCK
    5. Local Buffer:PVOID, BufferSize:ULONG
    6. Local RestartScan:BOOLEAN
    7.     _setseh_
    8.     xor eax,eax
    9.     mov ebx,1000h
    10.     mov edx,DirectoryName
    11.     mov ecx,DirectoryHandle
    12.     mov ObjAttr.uLength,SizeOf OBJECT_ATTRIBUTES   
    13.     mov ObjAttr.hRootDirectory,eax 
    14.     mov ObjAttr.pSecurityDescriptor,eax
    15.     mov ObjAttr.pSecurityQualityOfService,eax
    16.     mov ObjAttr.pObjectName,eax
    17.     mov ObjAttr.uAttributes,eax
    18.     mov RestartScan,ebx ;TRUE
    19.     .if Edx
    20.     mov ObjAttr.pObjectName,edx
    21.     .endif
    22.     .if Ecx
    23.     mov ObjAttr.hRootDirectory,ecx
    24.     .endif
    25.     invoke ZwOpenFile, addr FileHandle, FILE_LIST_DIRECTORY or SYNCHRONIZE, addr ObjAttr, addr IoStatusBlock, FILE_SHARE_READ or FILE_SHARE_WRITE, FILE_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT or FILE_OPEN_FOR_BACKUP_INTENT
    26.     test eax,eax
    27.     jnz exit_
    28.     mov Buffer,eax
    29.     mov BufferSize,ebx
    30.     invoke ZwAllocateVirtualMemory, NtCurrentProcess, addr Buffer, NULL, addr BufferSize, MEM_COMMIT, PAGE_READWRITE
    31.     test eax,eax
    32.     jnz close_
    33. query_loop_:
    34.     mov ebx,Buffer
    35.     assume ebx:PFILE_DIRECTORY_INFORMATION
    36.     invoke ZwQueryDirectoryFile, FileHandle, NULL, NULL, NULL, addr IoStatusBlock, Buffer, BufferSize, FileDirectoryInformation, FALSE, NULL, RestartScan
    37.     test eax,eax
    38.     mov RestartScan,eax
    39.     jz enum_loop_
    40.     cmp eax,STATUS_NO_MORE_FILES
    41.     jne return_
    42.     xor eax,eax
    43.     jmp return_
    44. enum_loop_:
    45.     _subsetseh_
    46.     push ebx    ;Сохраняем
    47.     push EnumerateParameter
    48.     push ebx    ;PFILE_DIRECTORY_INFORMATION
    49.     push FileHandle
    50.     Call EnumerateCallback
    51.     pop ebx
    52.     _subendseh_
    53.     test eax,eax
    54.     mov edx,[ebx].NextEntryOffset
    55.     jnz return_
    56.     test edx,edx
    57.     jz query_loop_
    58.     add ebx,edx
    59.     jmp enum_loop_
    60. return_:
    61.     push eax
    62.     invoke ZwFreeVirtualMemory, NtCurrentProcess, addr Buffer, addr BufferSize, MEM_RELEASE
    63.     pop eax
    64. close_:
    65.     push eax
    66.     invoke ZwClose,FileHandle
    67.     pop eax
    68. exit_:
    69.     _endseh_
    70.     ret
    71. err_param_1_:
    72.     mov eax,STATUS_INVALID_PARAMETER_1
    73.     jmp exit_
    74. EnumerateFileInDirectoryW endp
    Код (Text):
    1. EnumerateFileInDirectory proc DirectoryName:PSTR, DirectoryHandle:HANDLE, EnumerateCallback:PVOID, EnumerateParameter:DWORD
    2. Local UnicodeFileName:UNICODE_STRING
    3.     _setseh_
    4.     invoke RtlCreateUnicodeStringFromAsciiz, addr UnicodeFileName, DirectoryName
    5.     test eax,eax
    6.     jz err_param_1_
    7.     invoke RtlDosPathNameToNtPathName_U, UnicodeFileName.Buffer, addr UnicodeFileName, NULL, NULL
    8.     test eax,eax
    9.     jz err_param_1_
    10.     invoke EnumerateFileInDirectoryW, addr UnicodeFileName, DirectoryHandle, EnumerateCallback, EnumerateParameter
    11.     push eax
    12.     invoke RtlFreeUnicodeString, addr UnicodeFileName
    13.     pop eax
    14. exit_:
    15.     _endseh_
    16.     ret
    17. err_param_1_:
    18.     mov eax,STATUS_INVALID_PARAMETER_1
    19.     jmp exit_
    20. EnumerateFileInDirectory endp
    Код (Text):
    1. ENUMERATE_FS_DATA struct
    2. CallbackRoutine PVOID ?
    3. CallbackPatameter   DWORD ?
    4. ENUMERATE_FS_DATA ends
    5. PENUMERATE_FS_DATA typedef ptr ENUMERATE_FS_DATA
    6. .code
    7. ;Рекурсивный вызов
    8. EnumerateFilesCallback proc uses ebx DirectoryHandle:HANDLE, FileInformation:PFILE_DIRECTORY_INFORMATION, EnumerateData:PENUMERATE_FS_DATA
    9. Local DirectoryName:UNICODE_STRING
    10.     xor eax,eax
    11.     mov ebx,FileInformation
    12.     assume ebx:PFILE_DIRECTORY_INFORMATION
    13.     cmp word ptr [ebx].FileName,'.'
    14.     je exit_
    15.     mov edx,EnumerateData
    16.     assume edx:PENUMERATE_FS_DATA
    17.     push [edx].CallbackPatameter
    18.     push ebx
    19.     push DirectoryHandle
    20.     call [edx].CallbackRoutine
    21.     test eax,eax
    22.     jnz exit_
    23.     test [ebx].FileAttributes,FILE_ATTRIBUTE_DIRECTORY
    24.     jz exit_
    25.     mov edx,[ebx].FileNameLength
    26.     lea eax,[ebx].FileName
    27.     mov DirectoryName.Buffer,eax
    28.     mov DirectoryName._Length,dx
    29.     mov DirectoryName.MaximumLength,dx
    30.     invoke EnumerateFileInDirectoryW, addr DirectoryName, DirectoryHandle, addr EnumerateFilesCallback, EnumerateData
    31. exit_:
    32.     ret
    33. EnumerateFilesCallback endp
    34.  
    35. EnumerateFiles proc DirectoryName:PSTR, DirectoryHandle:HANDLE, EnumerateCallback:PVOID, EnumerateParameter:DWORD
    36. Local EnumerateData:ENUMERATE_FS_DATA
    37.     mov eax,EnumerateCallback
    38.     mov edx,EnumerateParameter
    39.     mov EnumerateData.CallbackRoutine,eax
    40.     mov EnumerateData.CallbackPatameter,edx
    41.     invoke EnumerateFileInDirectory, DirectoryName, DirectoryHandle, addr EnumerateFilesCallback, addr EnumerateData
    42.     ret
    43. EnumerateFiles endp
    44.  
    45. EnumerateFilesW proc DirectoryName:PUNICODE_STRING, DirectoryHandle:HANDLE, EnumerateCallback:PVOID, EnumerateParameter:DWORD
    46. Local EnumerateData:ENUMERATE_FS_DATA
    47.     mov eax,EnumerateCallback
    48.     mov edx,EnumerateParameter
    49.     mov EnumerateData.CallbackRoutine,eax
    50.     mov EnumerateData.CallbackPatameter,edx
    51.     invoke EnumerateFileInDirectoryW, DirectoryName, DirectoryHandle, addr EnumerateFilesCallback, addr EnumerateData
    52.     ret
    53. EnumerateFilesW endp
    Код (Text):
    1. EnumerateFileInDirectoryW(
    2. IN PUNICODE_STRING DirectoryName,   ;"\??\c:\windows\system32"
    3. IN HANDLE DirectoryHandle OPTIONAL,
    4. IN PVOID EnumerateCallback,
    5. IN DWORD EnumerateParameter):NTSTATUS
    6. EnumerateCallback proto DirectoryHandle:HANDLE, FileInformation:PFILE_DIRECTORY_INFORMATION, EnumerateParameter:DWORD
    7.  
    8. EnumerateFileInDirectory(
    9. IN PSTR DirectoryName,  ;"c:\windows\system32"
    10. IN HANDLE DirectoryHandle OPTIONAL,
    11. IN PVOID EnumerateCallback,
    12. IN DWORD EnumerateParameter):NTSTATUS
    13. EnumerateCallback proto DirectoryHandle:HANDLE, FileInformation:PFILE_DIRECTORY_INFORMATION, EnumerateParameter:DWORD
    14.  
    15. EnumerateFiles(
    16. IN PSTR DirectoryName,  ;"c:\windows\system32"
    17. IN HANDLE DirectoryHandle OPTIONAL,
    18. IN PVOID EnumerateCallback,
    19. IN DWORD EnumerateParameter):NTSTATUS
    20.  
    21. EnumerateFiles(
    22. IN PUNICODE_STRING DirectoryName,   ;"\??\c:\windows\system32"
    23. IN HANDLE DirectoryHandle OPTIONAL,
    24. IN PVOID EnumerateCallback,
    25. IN DWORD EnumerateParameter):NTSTATUS
    26. EnumerateCallback proto DirectoryHandle:HANDLE, FileInformation:PFILE_DIRECTORY_INFORMATION, EnumerateParameter:DWORD'
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    _basmp_
    Учту.
     
  10. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    _basmp_

    Разве одну структуру WIN32_FIND_DATA и один хендл мы не используем для одного каталога?
     
  11. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Everhest
    Моя ошибка.

    Не выдержал, скомпилил вашу прогу. Беда у вас не в рекурсии. У меня она находит все каталоги (сужу по МБ еррор), а в неправильном заполнении path_buffer. При его переполнении прога слетает.
     
  12. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    _basmp_

    А вот с этого момента поподробней...

    Где именно происходит это переполнение. Здесь что ли на 239 строке?

    Код (Text):
    1. proc SetDownDir buffer, path, ext
    2.  
    3.         invoke wsprintf,[buffer],format.path, [path], [ext]
    4.         ret
    5.  
    6.         format.path     db '%s\%s',0
    7. endp
     
  13. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Everhest
    Не знаю. Я уже закрыл все. Иду спать.

    Попробуйте отладить самостоятельно.
    Найдите все упоминания, определитесь где меняться может. Смотрите что до и что после распространяясь от места обнаружения ошибки назад по ходу алга. Думайте как оно должно быть, при несовпадении думайте еще раз и если надумаете - правьте. Итд пока не все не заработает.

    Все. Удачи. Спокойной ночи.
     
  14. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    _basmp_

    Спокойной ноч... Спокойного утра. :)
    Ладно надо и мне поспать, а то чет голова уже не работает.

    Спасибо всем...
     
  15. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Everhest
    Если честно, Вашу кучу-малу прочитать нелегко. ИМХО Вам всю процедуру заново переписать лучше. И самое главное для рекурсивной процедуры - она должна быть реентерабельна!!! Т.е. при каждом вхождении иметь свою копию ВСЕХ используемых ей данных. Вот у Вас path_buffer где объявлена? Глобально? Дальше можно не смотреть: вся Ваша рекурсия идет на все три.
    Вы пишете:
    С чего бы это стэк не подходил? Стэк - это источник жизни рекурсии. Именно в него стоит загонять все Ваши WIN32_FIND_DATA, строки и т.п. Можно выделять память и отдельно(в куче, например), хотя это - не лучшая идея. НО! если отдельно, то в самом начале функции выделяете динамически память, а в самом конце освобождаете, храня при этом указатель в стэке (либо каждый рекурсивный вызов обрамляете выделением/освобождением памяти). И никаких внешних глобальных массивов в рассчете на всю глубину вхождения ф-ии в саму себя! Только усложняете этим задачу. А ведь смысл рекурсии исключительно в ее простоте для понимания при решении определенных задач. Никаких других преимуществ она не дает: объемов памяти не жалеет, а производительность в общем случае понижает.
    Надо полагать, что nesting должна считать глубину вхождения. Плохая идея. Незачем для данной задачи считать глубину вхождения. От этого портится вся красота/простота рекурсивного подхода.
     
  16. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    - Рекурсия, с чего начать?
    - с рекурсии.
     
  17. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    В принципе я с вами согласен, процедура с самого начала пошла по иксу. А на счет динамического выделения памяти, попробую сегодня этот вариант.
     
  18. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    invoke wsprintf -> cinvoke wsprintf
     
  19. Everhest

    Everhest New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2007
    Сообщения:
    105
    asmfan
    В следующий раз учту, а процедурку сейчас переписываю. Кто хочет может глянуть, коряво правда: