Artifact 2332aa99dd7cdd6627e5479c2fdb19927e48a578:
- File
source/CCList.asm
— part of check-in
[59854f6efd]
at
2015-05-14 19:33:50
on branch WithoutWinproc
— Fixed "dispatch" macro use in many files.
Implemented new format for index.help, supporting titles for the help files.
Implemented new feature "Open Linux terminal". Added new icon for this feature. (user: johnfound size: 29777) [more...]
MAX_CCITEMS = 100 uglobal hCCList dd 0 hCCPrefix dd 0 endg idCCList = 763 proc CreateCCList, .parent begin push ebx invoke CreateWindowExA, WS_EX_CLIENTEDGE, cFormClassName, 0, WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN, \ 0, 0, 300, 120, 0, 0, [hInstance], 0 mov [hCCList], eax invoke SetWindowLongA, [hCCList], GWL_HWNDPARENT, [.parent] stdcall SubclassWindow, [hCCList], CCParentProc invoke CreateWindowExA, 0, cListboxClassName, 0, \ WS_CHILD or WS_VSCROLL or WS_VISIBLE or LBS_NOINTEGRALHEIGHT or LBS_OWNERDRAWFIXED or LBS_NODATA, \ 0, 0, 300, 120, [hCCList], idCCList, [hInstance], 0 mov ebx, eax stdcall SubclassWindow, ebx, CCListProc stdcall SetAlign, ebx, waClient stdcall GetDefaultFont, gdfMessage invoke SendMessageA, ebx, WM_SETFONT, eax, TRUE mov [hCCPrefix], 0 pop ebx return endp ; returns pointer to the string in ebx proc GetCCListSelected begin push eax ecx edx invoke SendMessageA, [hCCList], LB_GETCURSEL, 0, 0 add eax, 1 jc .err mov ebx, eax invoke GetWindowLongA, [hCCList], GWL_USERDATA cmp [eax+TArray.count], ebx jb .err mov ebx, [eax+TArray.array+4*ebx-4] mov ebx, [ebx+TLabel.iName] add ebx, [ptrNames] clc .err: pop edx ecx eax return endp proc ClearCCList begin invoke SendMessageA, [hCCList], LB_SETCOUNT, 0, 0 invoke GetWindowLongA, [hCCList], GWL_USERDATA stdcall FreeMem, eax stdcall CreateArray, 4 ; dword array. invoke SetWindowLongA, [hCCList], GWL_USERDATA, eax return endp proc SelectCCList, .hStr begin push ebx esi edi stdcall StrPtr, [.hStr] mov edi, eax invoke GetWindowLongA, [hCCList], GWL_USERDATA mov ebx, [eax+TArray.count] lea esi, [eax+TArray.array] or eax, -1 .matchloop: inc eax cmp eax, ebx je .notfound mov ecx, [esi] lea esi, [esi+4] mov ecx, [ecx+TLabel.iName] add ecx, [ptrNames] stdcall StringMatch, ecx, edi jnc .matchloop invoke SendMessageA, [hCCList], LB_SETCURSEL, eax, 0 clc return .notfound: invoke SendMessageA, [hCCList], LB_SETCURSEL, 0, 0 stc return endp proc CCParentProc, .hwnd, .wmsg, .wparam, .lparam begin cmp ebx, WM_KEYDOWN je .relay cmp ebx, LB_ADDSTRING jl .process cmp ebx, LB_ITEMFROMPOINT ja .process .relay: invoke SendDlgItemMessageA, [.hwnd], idCCList, [.wmsg], [.wparam], [.lparam] clc return .process: dispatch ebx .ondefault: stc return oncase WM_SETFOCUS xor eax, eax clc return oncase AM_INITWINDOW stdcall CreateArray, 4 ; dword array. invoke SetWindowLongA, [.hwnd], GWL_USERDATA, eax clc return oncase WM_SIZE invoke GetDlgItem, [.hwnd], idCCList invoke InvalidateRect, eax, 0, 0 xor eax, eax clc return oncase WM_CLOSE invoke DestroyWindow, [.hwnd] xor eax, eax mov [hCCList], eax clc return oncase WM_DESTROY invoke GetWindowLongA, [.hwnd], GWL_USERDATA stdcall FreeMem, eax stc return oncase WM_MEASUREITEM locals .ccrect RECT endl mov esi, [.lparam] cmp [esi+MEASUREITEMSTRUCT.CtlType], ODT_LISTBOX jne .ondefault cmp [esi+MEASUREITEMSTRUCT.CtlID], idCCList jne .ondefault invoke GetDlgItem, [.hwnd], idCCList mov ebx, eax lea ecx, [.ccrect] invoke GetClientRect, ebx, ecx push [.ccrect.right] pop [esi+MEASUREITEMSTRUCT.itemWidth] or eax, -1 clc return oncase WM_DRAWITEM locals .rectL RECT .rectR RECT .bkbrush dd ? .buffer rb 32 endl cmp [.wparam], idCCList jne .ondefault mov esi, [.lparam] mov eax, [esi+DRAWITEMSTRUCT.hwndItem] mov eax, COLOR_HIGHLIGHT mov ebx, COLOR_HIGHLIGHTTEXT test [esi+DRAWITEMSTRUCT.itemState], ODS_SELECTED or ODS_FOCUS jnz @f mov eax, COLOR_WINDOW mov ebx, COLOR_WINDOWTEXT @@: invoke GetSysColor, eax invoke CreateSolidBrush, eax mov [.bkbrush], eax invoke GetSysColor, ebx invoke SetTextColor, [esi+DRAWITEMSTRUCT.hDC], eax invoke SetBkMode, [esi+DRAWITEMSTRUCT.hDC], TRANSPARENT ; First fill the background lea eax, [esi+DRAWITEMSTRUCT.rcItem] invoke FillRect, [esi+DRAWITEMSTRUCT.hDC], eax, [.bkbrush] ; then compute the rectangles mov eax, [esi+DRAWITEMSTRUCT.rcItem.left] mov ecx, [esi+DRAWITEMSTRUCT.rcItem.right] mov [.rectL.left], eax mov [.rectL.right], ecx mov [.rectR.left], ecx mov [.rectR.right], ecx sub ecx, eax shr ecx, 1 ; 1/2 of the field for the value. sub [.rectL.right], ecx sub [.rectR.left], ecx mov eax, [esi+DRAWITEMSTRUCT.rcItem.top] mov ecx, [esi+DRAWITEMSTRUCT.rcItem.bottom] mov [.rectL.top], eax mov [.rectL.bottom], ecx mov [.rectR.top], eax mov [.rectR.bottom], ecx add [.rectL.left], 4 add [.rectR.left], 4 invoke GetSysColor, COLOR_BTNFACE invoke CreatePen, PS_SOLID, 0, eax invoke SelectObject, [esi+DRAWITEMSTRUCT.hDC], eax push eax invoke MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.top], NULL invoke LineTo, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.bottom] mov edi, [.rectL.bottom] dec edi invoke MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [esi+DRAWITEMSTRUCT.rcItem.left], edi, NULL invoke LineTo, [esi+DRAWITEMSTRUCT.hDC], [.rectR.right], edi invoke SelectObject, [esi+DRAWITEMSTRUCT.hDC] ; from the stack invoke DeleteObject, eax ; then write the text mov edi, [esi+DRAWITEMSTRUCT.itemID] cmp edi, -1 je .cleanup invoke GetWindowLongA, [.hwnd], GWL_USERDATA cmp edi, [eax+TArray.count] jae .cleanup mov edi, [eax+TArray.array + 4*edi] mov eax, [edi+TLabel.iName] add eax, [ptrNames] lea ecx, [.rectL] invoke DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS ; then write the value stdcall SymbolToStr, edi push eax stdcall StrPtr, eax lea ecx, [.rectR] invoke DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER stdcall StrDel ; from the stack. .cleanup: invoke DeleteObject, [.bkbrush] or eax, -1 clc return enddispatch endp cVirtual text 'virtual' proc SymbolToStr, .ptrLabel begin pushad mov edi, [.ptrLabel] test [edi+TLabel.flags], lfDefined jz .notdefined stdcall StrNew mov ebx, eax mov cl, [edi+TLabel.DataSize] mov eax, 'b ' cmp cl, 1 je .sz_ok mov eax, 'w ' cmp cl, 2 je .sz_ok mov eax, 'dw ' cmp cl, 4 je .sz_ok mov eax, 'pw ' cmp cl, 6 je .sz_ok mov eax, 'qw ' cmp cl, 8 je .sz_ok mov eax, 'tw ' cmp cl, 10 jne .prefix_ok .sz_ok: stdcall StrCharCat, ebx, eax .prefix_ok: ; type: cmp [edi+TLabel.type], ltAbsolute je .type_ok stdcall StrCharCat, ebx, 'r ' .type_ok: ; registers xor edx, edx cmp [edi+TLabel.SIBEx], 0 je .reg_ok2 or edx, 1 ; close the bracket stdcall StrCharCat, ebx, '[' movzx eax, byte [edi+TLabel.SIBEx+2] cmp eax, 1 je .mul_ok1 test eax, eax jz .reg_ok1 add eax, '0' stdcall StrCharCat, ebx, eax stdcall StrCharCat, ebx, '*' or edx, 2 ; at lease one register .mul_ok1: movzx eax, byte [edi+TLabel.SIBEx] test eax, eax jz .reg_ok1 stdcall GetRegisterName, eax stdcall StrCharCat, ebx, eax or edx, 2 ; at lease one register .reg_ok1: movzx eax, byte [edi+TLabel.SIBEx+3] cmp eax, 1 je .mul_ok2 test eax, eax jz .reg_ok2 add eax, '0' test edx, 2 jz @f stdcall StrCharCat, ebx, '+' @@: stdcall StrCharCat, ebx, eax stdcall StrCharCat, ebx, '*' .mul_ok2: movzx eax, byte [edi+TLabel.SIBEx+1] test eax, eax jz .reg_ok2 stdcall GetRegisterName, eax stdcall StrCharCat, ebx, eax .reg_ok2: mov ecx, ntsHex or ntsUnsigned test edx, 2 ; is there at least one register? jz .add_number mov eax, [edi+TLabel.ValueHi] test eax, eax jns .add_sign mov ecx, ntsHex or ntsSigned jmp .add_number .add_sign: stdcall StrCharCat, ebx, '+' .add_number: stdcall NumToStr64, [edi+TLabel.ValueLo], [edi+TLabel.ValueHi], ecx stdcall StrCharCat, eax, 'h' stdcall StrCat, ebx, eax stdcall StrDel, eax test edx, 1 jz .value_ok stdcall StrCharCat, ebx, ']' .value_ok: mov eax, ebx jmp .finish .notdefined: stdcall StrDup, 'undefined' jmp .finish .finish: mov [esp+4*regEAX], eax popad return endp proc GetRegisterName, .index begin push ecx mov ecx, [.index] cmp ecx, $f4 je .eip cmp ecx, $f8 je .rip and ecx, $0f mov eax, [cSIBStrings+4*ecx] mov ecx, [.index] shr ecx, 4 ; 2, 4 or 8 mov ch, byte [.index] and ch, $0f cmp cl, 2 je .finish cmp cl, 4 jne .qword ;dword cmp ch, 8 jb .e_prefix mov ecx, 'd' shl 16 cmp ch, 10 jb @f shl ecx, 8 @@: or eax, ecx jmp .finish .e_prefix: shl eax, 8 mov al, 'e' jmp .finish .qword: cmp ch, 8 jae .finish shl eax, 8 mov al, 'r' .finish: pop ecx return .eip: mov eax, 'eip' jmp .finish .rip: mov eax, 'rip' jmp .finish endp iglobal cSIBStrings dd 'ax', 'cx', 'dx', 'bx' dd 'sp', 'bp', 'si', 'di' dd 'r8', 'r9', 'r10', 'r11' dd 'r12', 'r13', 'r14', 'r15' endg proc CCListProc, .hwnd, .wmsg, .wparam, .lparam begin mov ebx, [.wmsg] dispatch ebx .ondefault: stc return ;----------------------------------------------------------------------- oncase WM_LBUTTONDBLCLK invoke GetParent, [.hwnd] invoke GetWindowLongA, eax, GWL_HWNDPARENT invoke PostMessageA, eax, WM_KEYDOWN, VK_RETURN, 0 clc return ;----------------------------------------------------------------------- oncase WM_KEYDOWN mov ebx, [.wparam] call JumpTo MessageList \ VK_DOWN, .ondefault, \ VK_UP, .ondefault, \ VK_PRIOR, .ondefault, \ VK_NEXT, .ondefault, \ VK_HOME, .ondefault, \ VK_END, .ondefault ; invoke SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0 invoke GetParent, [.hwnd] invoke GetWindowLongA, eax, GWL_HWNDPARENT invoke PostMessageA, eax, [.wmsg], [.wparam], [.lparam] xor eax, eax clc return enddispatch endp proc UpdateCCPosition .aepos AEPOS .caret AECARETXY .rect RECT ; .workrect RECT .prefix rb $100 .word rb $100 .aedit dd ? .info MONITORINFO ; benchmark variables ; .time dd ? ; .count dd ? begin cmp [hCCList], 0 je .finish stdcall WaitForCompiler jc .finish invoke GetWindowLongA, [hCCList], GWL_HWNDPARENT mov [.aedit], eax lea eax, [.aepos] invoke SendMessageA, [.aedit], AEM_GETPOS, eax, 0 lea ebx, [.caret] invoke SendMessageA, [.aedit], AEM_GETCARETXY, ebx, 0 invoke ClientToScreen, [.aedit], ebx add ebx, 8 invoke ClientToScreen, [.aedit], ebx sub ebx, 8 lea eax, [.rect] invoke GetWindowRect, [hCCList], eax mov eax, [.rect.right] mov ecx, [.rect.bottom] sub eax, [.rect.left] sub ecx, [.rect.top] mov [.rect.right], eax mov [.rect.bottom], ecx invoke MonitorFromWindow, [.aedit], 2 mov [.info.cbSize], sizeof.MONITORINFO lea ecx, [.info] invoke GetMonitorInfoA, eax, ecx mov eax, [.info.rcWork.right] sub eax, [.rect.right] mov ecx, [.caret.x0] cmp eax, ecx jle @f mov eax, ecx @@: mov edx, [.info.rcWork.bottom] sub edx, [.rect.bottom] mov ecx, [.caret.y1] add ecx, 1 cmp edx, ecx jg @f mov ecx, [.caret.y0] sub ecx, [.rect.bottom] sub ecx, 2 @@: invoke SetWindowPos, [hCCList], NULL, eax, ecx, 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOCOPYBITS lea ebx, [.word] invoke SendMessageA, [.aedit], AEM_GETWORDATCARET, $100, ebx cmp byte [.word], '.' jne .localok cmp [hCCPrefix], 0 jne .prefixok stdcall SearchForLabelPrefixInEditor, [.aedit], [.aepos.caretLine] mov [hCCPrefix], eax .prefixok: cmp [hCCPrefix], 0 je .localok stdcall StrLen, [hCCPrefix] mov ecx, eax jecxz .localok ; the prefix was not found or there is no prefix. stdcall StrPtr, [hCCPrefix] lea esi, [eax+ecx] ; the end of the string .copy_prefix: dec esi mov al, [esi] dec ebx mov [ebx], al loop .copy_prefix ; here ebx contains a pointer to the whole name including the parent label. .localok: stdcall ClearCCList stdcall SearchTree, ebx, ptrLabels test eax, eax jz .destroycc mov esi, [eax] test esi, esi jz .destroycc mov ebx, [esi+TArray.count] lea esi, [esi+TArray.array] test ebx, ebx jz .destroycc mov edi, edx ; The last word invoke GetWindowLongA, [hCCList], GWL_USERDATA mov edx, eax test edx, edx jz .destroycc xor ecx, ecx ; benchmark code. ; mov [.count], ecx ; stdcall GetTimestamp ; mov [.time], eax .fill_loop: ; inc [.count] ; benchmark mov eax, [esi+TLabel.iName] test eax, eax jz .next add eax, [ptrNames] stdcall StringMatch, eax, edi jnc .next stdcall AddArrayItems, edx, 1 mov [eax], esi inc ecx cmp ecx, MAX_CCITEMS jae .end_fill_loop .next: add esi, sizeof.TLabel dec ebx jnz .fill_loop .end_fill_loop: ; benchmark code... ; pushad ; stdcall GetTimestamp ; sub eax, [.time] ; stdcall Output, 'Fill loop time:' ; stdcall OutputNumber, eax, 10, 8 ; stdcall Output, <' ms ', 13, 10> ; ; stdcall Output, 'Total processed:' ; stdcall OutputNumber, [.count], 10, 8 ; stdcall Output, <' records ', 13, 10> ; ; popad push ecx invoke SetWindowLongA, [hCCList], GWL_USERDATA, edx pop ecx test ecx, ecx jz .destroycc invoke SendMessageA, [hCCList], LB_SETCOUNT, ecx stdcall SelectCCList, edi stdcall StrDel, edi invoke SetWindowPos, [hCCList], NULL, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_SHOWWINDOW or SWP_NOACTIVATE .finish: return .destroycc: invoke PostMessageA, [hCCList], WM_CLOSE, 0, 0 return endp ; If str1 begins with str2 then returns CF=1 ; else CF=0 ; preserves all registers. proc StringMatch, .str1, .str2 begin push esi edi eax mov esi, [.str1] mov edi, [.str2] .loop: mov al, [edi] lea edi, [edi+1] test al,al jz .match mov ah, [esi] lea esi, [esi+1] test ah,ah jz .notmatch or eax, $2020 cmp al,ah je .loop .notmatch: clc pop eax edi esi return .match: stc pop eax edi esi return endp ; searches the preprocessed source for the last global label definition before the ; specified line in the file. Returns the name of this label as a string in eax. ; If such label is not found, returns eax=0 proc SearchForLabelPrefixInEditor, .editor, .caretY begin push ecx edx stdcall GetEditorFile, [.editor] test eax, eax jz @f stdcall SearchForLabelPrefix, [eax+TOpenFile.hFileName], [.caretY] @@: pop edx ecx return endp ; searches the preprocessed source for the last global label definition before the ; specified line in the file. Returns the name of this label as a string in eax. ; If such label is not found, returns eax=0 proc SearchForLabelPrefix, .hFilename, .line begin push edx esi stdcall SearchFileInGlobalIndex, [.hFilename] jc .not_found mov esi, eax ; pointer to TArray of strinigs for needed file. mov edx, [.line] dec edx cmp edx, [esi+TArray.count] jb .lineok mov edx, [esi+TArray.count] dec edx .lineok: mov eax, [esi+TArray.array+4*edx] ; handle to the global label name test eax, eax jz .not_found pop esi edx clc return .not_found: pop esi edx stc return endp struct TGlobalIndexItem .iFilename dd ? .ptrLines dd ? ends proc FreeGlobalIndex begin push eax ecx esi mov esi, [ptrGlobalsList] test esi, esi jz .finish mov ecx, [esi+TArray.count] .loop: dec ecx js .end_free mov eax, [esi+TArray.array + sizeof.TGlobalIndexItem * ecx + TGlobalIndexItem.ptrLines] test eax, eax jz .loop stdcall FreeMem, eax jmp .loop .end_free: stdcall ListFree, [esi+TArray.lparam], StrDel stdcall FreeMem, esi mov [ptrGlobalsList], 0 .finish: pop esi ecx eax return endp proc CreateGlobalIndex .end dd ? .current dd ? ; handle of string with the current root label. .fLabel dd ? .fSkip dd ? begin pushad stdcall FreeGlobalIndex mov [.current], 0 stdcall CreateArray, sizeof.TGlobalIndexItem mov [ptrGlobalsList], eax mov esi, eax stdcall CreateArray, 4 mov [esi+TArray.lparam], eax ; array with all defined strings for later free. mov esi, [ptrPreprocessed] mov eax, [lenPreprocessed] add eax, esi mov [.end], eax test esi, esi jz .finish ; start of a preprocessor line... .line_loop: cmp esi, [.end] jae .end_of_file test [esi+TIntLine.LineNumber], $80000000 jnz .process_line ; this line is generated by macro and thus is nor in the source. stdcall SearchInGIndex, [ptrGlobalsList], [esi+TIntLine.ofsGenerator] jnc .fileok stdcall AddArrayItems, [ptrGlobalsList], 1 mov [ptrGlobalsList], edx .fileok: mov edi, eax mov eax, [esi+TIntLine.ofsGenerator] mov [edi+TGlobalIndexItem.iFilename], eax mov eax,[edi+TGlobalIndexItem.ptrLines] test eax, eax jnz .linesok stdcall CreateArray, 4 mov [edi+TGlobalIndexItem.ptrLines], eax .linesok: mov edx, eax mov eax, [esi+TIntLine.LineNumber] sub eax, [edx+TArray.count] jb .this_line_ok stdcall AddArrayItems, edx, eax mov [edi+TGlobalIndexItem.ptrLines], edx .this_line_ok: mov eax, [esi+TIntLine.LineNumber] dec eax lea edi, [edx+TArray.array+4*eax] ; pointer to the memory for the global label string. .process_line: add esi, sizeof.TIntLine mov [.fLabel], 0 mov [.fSkip], 0 .pre_loop: lodsb cmp al, $1a je .symbol cmp al, $22 je .string cmp al, $3b je .preprocessor test al, al jnz .pre_loop ; line end... mov eax, [.current] mov [edi], eax jmp .line_loop .preprocessor: mov [.fSkip], 1 .symbol: movzx eax, byte [esi] lea esi, [esi+1] mov ebx, esi add esi, eax cmp [.fSkip], 0 jne .pre_loop cmp [.fLabel], 0 jne .label_name cmp byte [esi], ':' ; this symbol is label, so check it. je .label_name call .check_for_dd jc .label_name cmp eax, 5 jne .pre_loop mov eax, [ebx] or eax, $20202020 cmp eax, 'labe' jne .pre_loop mov al, [ebx+4] or al, $20 cmp al, 'l' jne .pre_loop mov [.fLabel], 1 jmp .pre_loop .label_name: mov [.fSkip], 1 ; after processing the label name, skip to the end of the line. cmp byte [ebx], '.' ; it is local label je .pre_loop cmp word [ebx], '@@' je .pre_loop mov ecx, eax stdcall StrNew mov [.current], eax stdcall StrCopyPart, eax, ebx, 0, ecx ; save the string in one place for later free. push eax mov ecx, [ptrGlobalsList] stdcall AddArrayItems, [ecx+TArray.lparam], 1 mov [ecx+TArray.lparam], edx pop dword [eax] mov [.fLabel], 0 jmp .pre_loop .string: lodsd add esi, eax jmp .pre_loop ; check for data definition directive .check_for_dd: push eax cmp byte [esi], $1a jne .no_dd cmp byte [esi+1], 4 jne .no_file mov eax, [esi+2] or eax, $20202020 cmp eax, 'file' jne .no_dd .yes_dd: pop eax stc retn .no_file: cmp byte [esi+1], 2 jne .no_dd mov ax, [esi+2] or ax, $2020 cmp ax, 'rb' je .yes_dd cmp ax, 'rw' je .yes_dd cmp ax, 'rd' je .yes_dd cmp ax, 'rp' je .yes_dd cmp ax, 'rf' je .yes_dd cmp ax, 'rq' je .yes_dd cmp ax, 'rt' je .yes_dd cmp ax, 'db' je .yes_dd cmp ax, 'dw' je .yes_dd cmp ax, 'du' je .yes_dd cmp ax, 'dd' je .yes_dd cmp ax, 'dp' je .yes_dd cmp ax, 'df' je .yes_dd cmp ax, 'dq' je .yes_dd cmp ax, 'dt' je .yes_dd .no_dd: pop eax clc retn .end_of_file: .finish: popad return endp proc SearchInGIndex, .ptrGIndex, .value begin push ecx esi mov esi, [.ptrGIndex] mov ecx, [esi+TArray.count] .loop: dec ecx js .not_found mov eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx+TGlobalIndexItem.iFilename] cmp eax, [.value] jne .loop .found: lea eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx] pop esi ecx return .not_found: stc pop esi ecx return endp proc SearchFileInGlobalIndex, .hFilename begin push ecx esi mov esi, [ptrGlobalsList] test esi, esi jz .not_found mov ecx, [esi+TArray.count] .loop: dec ecx js .not_found mov eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx+TGlobalIndexItem.iFilename] test eax, eax jnz .fileok mov eax, [ptrMainFilename] jmp .compare .fileok: add eax, [ptrPreprocessed] .compare: stdcall StrCompFilename, eax, [.hFilename] jnc .loop ; equal files mov eax, [esi+TArray.array+sizeof.TGlobalIndexItem*ecx+TGlobalIndexItem.ptrLines] test eax, eax jz .not_found clc pop esi ecx return .not_found: xor eax, eax stc pop esi ecx return endp proc StrCompFilename, .hName1, .hName2 .file1 rb 1024 .file2 rb 1024 .name dd ? begin pushad lea esi, [.file1] lea edi, [.file2] stdcall StrPtr, [.hName1] lea edx, [.name] invoke GetFullPathNameA, eax, 1024, esi, edx cmp eax, 1023 ja .not_equal test eax, eax jz .not_equal mov ebx, eax stdcall StrPtr, [.hName2] lea edx, [.name] invoke GetFullPathNameA, eax, 1024, edi, edx cmp eax, 1023 ja .not_equal test eax, eax jz .not_equal cmp eax, ebx jne .not_equal mov ecx, ebx jecxz .equal .loop: mov al, [esi] mov ah, [edi] lea esi, [esi+1] lea edi, [edi+1] ; cmp al, '\' ; jne @f ; mov al, '/' ; ;@@: ; cmp ah, '\' ; jne @f ; mov ah, '/' ;@@: cmp al, $41 jb @f cmp al, $5f ja @f add al, $20 @@: cmp ah, $41 jb @f cmp ah, $5f ja @f add ah, $20 @@: cmp al, ah jne .not_equal loop .loop .equal: stc popad return .not_equal: clc popad return endp