Tree View Controls and FindFirst/NextFile Problems When Attribute=16h

Started by xandaz, October 18, 2009, 03:19:32 PM

Previous topic - Next topic

xandaz

   Hi again masters. I have some more doubts that maybe you can help me with. The program i'm making has a tree view control with the drives and directories and i've been experiencing some probs when the attribute is FILE_ATTR_DIR+HIDDEN+SYSTEM (16h if i'm not wrong). I'm not sure if there's something i'm not doing to get full access to those directories or what. Windows pops up a window to close the program. For the attribute FILE_ATTR_DIRECTORY i encountered some probs too but i excluded characters in directory names from outside '09','az' and it seems to be working tho i have the feeling that some dirs have been excluded. Im not sure if the problem is in FindFile function or if the theeview control gives errors given the insertion of invalid characters in treeview items since these days filenames may contain weird characters.
   Best regards and would pls someone look into it?
   ty ty asmers and byez :U

xandaz

   Here goes the search and tree view fill procedure.


InsertTreeViewItems     PROC


        pushad
        push    esp
        push    ebp
        mov     cnt,0
loop_0:
        invoke  FindFirstFile,addr Buffer,addr w32fd
        cmp     eax,INVALID_HANDLE_VALUE
        je      error_ihv
        cmp     eax,0ffffffffh
        je      error_ihv
        mov     hFind,eax
_cmps:
        cmp     w32fd.cFileName,NULL
        je      chg_alternate
        cmp     w32fd.cFileName,'0'
        jl      next_1
        cmp     w32fd.cFileName,'z'
        ja      next_1
@@1:       
        cmp     w32fd.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
        je      do_1
        cmp     w32fd.dwFileAttributes,11h
        je      do_1
;       cmp     w32fd.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY+FILE_ATTRIBUTE_SYSTEM+FILE_ATTRIBUTE_HIDDEN   ; i had to exclude this to make it work
;                                                                                                                                                                       but \windows and programs dirs dont show
;       je      do_1
        mov     tvis.item.pszText,offset w32fd.cFileName
        jmp     next_1
cmps_1:
        cmp     w32fd.cAlternate,'0'
        jl      next_1
        cmp     w32fd.cAlternate,'z'
        ja      next_1
        jmp     @@1
chg_alternate:
        mov     tvis.item.pszText,offset w32fd.cAlternate
        jmp     cmps_1
do_1:
        invoke  SendMessage,hTreeView,TVM_INSERTITEM,NULL,addr tvis
        cmp     eax,NULL
        je      @@2
        push    tvis.hParent
        mov     tvis.hParent,eax
        push    hFind
        inc     cnt
        invoke  SNTS,addr Buffer       ;subs string
        invoke  ANTS,addr Buffer,tvis.item.pszText     ;add currently found dir to filespec
        invoke  ANTS,addr Buffer,addr DivBar      ;adds a '\' to filespec
        invoke  ANTS,addr Buffer,addr FilterAll    ;adds '*.*' filter to filespec
        jmp     loop_0

next_1:
        invoke  FindNextFile,hFind,addr w32fd
        cmp     eax,NULL
        je      error_nmf
        jmp     _cmps
error_nmf:
        cmp     cnt,NULL
        je      error_ihv
skip_1:       
        invoke  FindClose,hFind       
        pop     hFind
        pop     tvis.hParent
        dec     cnt
        invoke  SNTSTB,addr Buffer       ; subtracts strings till '\'
        invoke  ANTS,addr Buffer,addr FilterAll    ;adds string '*.*' to filespec
@@2:       
        jmp     next_1
error_ihv:
        invoke  FindClose,hFind
        pop     ebp
        pop     esp
        popad   
        ret

InsertTreeViewItems     endp

ty guys

evlncrn8

its probably best you use a unicode implimentation, or it will bite you in the ass later on on other machines, especially ones using other non english languages
you should also be using TEST value, other value for the bit flags for the attributes

      cmp     eax,INVALID_HANDLE_VALUE
        je      error_ihv
        cmp     eax,0ffffffffh
        je      error_ihv

is redundant, INVALID_HANDLE_VALUE equates to -1 (0FFFFFFFFh)

xandaz

   Can u explain that better to me? How do i use a unicode implementation? And how about the TEST insted of CMP ? what's the big difference?
   Thanks man. See if you can help me some more when you have some time to spare.
   best regards .... xandaz

xandaz

   I can't get it. I've been useing CharToOem, to convert the strings but still it errors on me on Windows and Programs directories. When attr is FILE_ATTRIBUTE_DIR+SYSTEM+HIDDEN the damn thing closes the program. Could this have something to do with permissions? Can someone gimme a hand on UNICODE implementation?
   Thanks , appreciate it.
   Bye and stay well

jj2007

Can you reproduce the crash? Did you try with Olly? if Olly is too cumbersome, try the deb macro from the MasmBasic library:

deb 1, "Test 1", eax, esi$

Insert deb's until you can track down where the crash happens.

Quotedeb 1, "The first loop", ecx, esi$, edi$, MyReal10, ST(1)
   deb 2, "Second loop:", al, ecx, esi$, $My$

Rem   the debug macro preserves registers but not flags
   can show FPU registers once but trashes them afterwards
   the string content of registers can be shown by using esi$
   global and local variables can be shown as strings by using e.g. $buffer
   cancelling deb 1, ... does not cancel deb 2, ..., so you can test several loops in one go
   deb 1, ... deb 4, ... are being displayed, while deb 5, writes to a file:
   deb 5, "ToFile", eax, esi$, edi$ saves contents (without showing them) to DebLog.txt

xandaz

   Hi jj and thanks. I just downloaded MasmBasic and im going to look into it. Thanks for the help and stay well. :U
   Best regards....
   ....xandaz

evlncrn8

unicode is simply using the W variants of the api's FindFirstFileW etc.. so you get the widechar names, then to display them in the treeview you would use SendMessageW
which would require no conversion (at least it didn't when i played with it) of the text, so it should be faster :) you'd also need to use the WIN32_FIND_DATAW struct
instead of the WIN32_FIND_DATAA one..

you should use test, as the values returned are bit flags

http://msdn.microsoft.com/en-us/library/ee332330%28VS.85%29.aspx

contains the flag values, the strange thing here is that 16h would be

FILE_ATTRIBUTE_DIRECTORY (10h) + FILE_ATTRIBUTE_HIDDEN (2h) + FILE_ATTRIBUTE_SYSTEM (4h)

i think you're actually messing up the stack in your loop with the

push    tvis.hParent
mov     tvis.hParent,eax
push    hFind

to loop thing, as if there are a lot of files etc, and you're working recursively you're pusing 2x dwords each time, and only popping them at the end
it might be a good idea to split up the code into seperate clean tidy functions, i'm not so sure its the attribute messing you up :)





xandaz

   Many thanls evl. I'm not sure about the stack tho. The routine works fine with other FileAttributes but i'll give it a look. Hey i didn't even know about any other W32_FIND_DATA. Thanks for the help evlncrn8. You sure seem to know your ways around asm.
   Best regards from I
   xandaz

xandaz

   Hey evlncrn8. You're right. I just remmembered why i put those stack pushes/pops. When dwFileAttributes=016h FindFirst/NextFile returns error and the routines jumps to error_ihv. Even tho the pops are there when returning from the routine it goes to a different ip. Not sure how to go around this. I think it would be good to know why the function returns the error. I already asked this but , could it have something to do with permissions since its a system dir?
   Feel free to give oppinion when you have some time.
   Thanks evl and byez

evlncrn8

well, use GetLastError, and see what the error code it returns is, access wise, it should be able to still list the files, i mean, you're not opening them,
and if there's no permissions on the folder, i think FindFirstFile etc.. should return that there are no more files, or that there was some failure
i think you should split the code up into tiny little routines, that makes it easier to debug, and allows you to have tidier code, then perhaps the
error might go away :) if i have some time over the weekend i'll try and do the code for you, but i have a lot of stuff to do atm in real life, so
im not sure if i'll have time

xandaz

    Hey evl. Yeah, I'm very grateful for the help. If you have some time go ahead but don't go out of your way for me. Thanks for the advice. You've been very helpful. You guys are the best. Thanks a lot. May the Blessed one praise the forum.
   Thanks
   Your friend xandaz

xandaz

   Hi again. I haven't solved the prob yet but it was a stack problem. I feel stupid for having put those stack registers pushes and pops when the pushes inside the routine disalign the stack so when i do the poping it doesnt return the propper values to the due regs. Anyway i saved the stack pointer and its working but not all the way. The FindFirstFile func gives error when i try to find the directories present in Config.msi. Could it be that this is not a dir, And so the problem? why would it return FILE_ATTR_DIR in w32fd.dwFileAttributes? Well i'm going to look a little more into it to see if i can solve the damn thing.
   Thanks for the help guys.
   best regards from xandaz

evlncrn8

msi files can technically be 'seen' as containers, as they're sort of like zip files.. which could explain the attributes.. but are you erasing the win32 find data
structure each time? as there could be 'crap' in it from the last call :)

xandaz

   Should i erase w32fd? Thanks, i'll try that. I got it working except for config.msi and Documents and Settings. I think it may be as you said. Maybe these aren't directories. I made some changes to the rountine and it now works except i must tune it up becase i sense it's taking a bit more to show the tree than it should. I see that wait sign for long. I'll post here the final result. Maybe it'll become useful for someone else.

.data

SafeStack               dd              ?

.code

InsertTreeViewItems    PROC

        pushad
        push    esp
        push    ebp
        pushfd
        mov     SafeStack,esp           ;case something goes wrong this keeps it from crashing
       
        mov     tvis.item.pszText,offset w32fd.cFileName
        mov     cnt,0
@@1:       
        invoke  FindFirstFile,addr Buffer,addr w32fd
        cmp     eax,INVALID_HANDLE_VALUE
        je      @@3
        mov     hFind,eax
compares:
        cmp     w32fd.cFileName,'0'
        jl      @@2
        cmp     w32fd.cFileName,'z'
        ja      @@2
        test    w32fd.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
        jnz     do       
@@2:
        invoke  FindNextFile,hFind,addr w32fd
        cmp     eax,NULL
        je      error_nmf
        jmp     compares
do:
        invoke  SendMessage,hTreeView,TVM_INSERTITEM,NULL,addr tvis
        push    tvis.hParent
        mov     tvis.hParent,eax
        push    hFind
        inc     cnt
       
        invoke  SNTS,addr Buffer                            ;add last
        invoke  ANTS,addr Buffer,tvis.item.pszText   ;found directory
        invoke  ANTS,addr Buffer,addr DivBar           ;to the buffer
        invoke  ANTS,addr Buffer,addr FilterAll          ;for FindFirstFile function
        jmp     @@1
error_nmf:
        invoke  FindClose,hFind
        cmp     cnt,0
        je        end_itvi
@@3:
        pop     hFind       
        pop     tvis.hParent
        dec     cnt
        invoke  SNTSTB,addr Buffer                   ;Subtract current dir from buffer
        invoke  ANTS,addr Buffer,addr FilterAll     ;Add filter *.*
        jmp     @@2

end_itvi:       
        mov     esp,SafeStack              ; restore stack pointer
        popfd
        pop     ebp
        pop     esp
        popad
        ret                 
       
InsertTreeViewItems    endp

Thanks, you've all been very helpful
best regards
xandaz