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




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

        .data
                szSysCRLF       db  13,10,0
                szDrive         db  "X:\",0

        .code

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

GetSysInfoOutput proc uses edi esi ebx
        LOCAL mst: MEMORYSTATUS, ovi: OSVERSIONINFO
        LOCAL lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD
        LOCAL nSize: DWORD

        ; Write the greet message
        szText  szSystemInfoGreet, "[SI]",13,10
        invoke  lstrcat, GlobalBuffer, addr szSystemInfoGreet

        ; -----------------
        ; Get the user's OS
        ; -----------------

        mov     ovi.dwOSVersionInfoSize, sizeof OSVERSIONINFO
        invoke  GetVersionEx, addr ovi

        szText  szSysOSFmt, "OS: %lu %lu %lu",13,10
        invoke  wsprintf, offset lpBuf1, addr szSysOSFmt, ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwPlatformId
        invoke  lstrcat, GlobalBuffer, offset lpBuf1

        ; ---------------------------------
        ; Get total and free memory avaible
        ; ---------------------------------

        invoke  GlobalMemoryStatus, addr mst
        szText  szSysMemFmt, "M: %lu %lu",13,10
        invoke  wsprintf, offset lpBuf1, addr szSysMemFmt, mst.dwTotalPhys, mst.dwAvailPhys
        invoke  lstrcat, GlobalBuffer, offset lpBuf1

        ; ------------------------------
        ; Get logical drives information
        ; ------------------------------

        ; Get all avaible logical drives
        invoke  GetLogicalDrives

        lea     edi, lpBuf2
        mov     dl, 'A'
        mov     ecx, 26

@drive_loop:
        test    eax, 1
        jz      @next
        mov     [edi], dl
        inc     edi

@next:
        shr     eax, 1
        inc     dl
        dec     ecx
        jnz     @drive_loop

        inc     edi
        mov     byte ptr[edi], 0

        invoke  lstrlen, offset lpBuf2

        mov     edi, eax
        lea     esi, lpBuf2

        ; Get information about each logical drive (free space, etc)
@drv_info_loop:
        mov     dl, [esi]
        mov     byte ptr [szDrive], dl

        invoke  GetDriveType, offset szDrive

        push    eax

        lea     edx, szDrive
        mov     byte ptr[edx+1], 0

        szText  szSysDriveFmt, "D: %s (%lu)"
        invoke  wsprintf, offset lpBuf1, addr szSysDriveFmt, offset szDrive, eax
        invoke  lstrcat, GlobalBuffer, offset lpBuf1

        lea     edx, szDrive
        mov     byte ptr[edx+1], ':'


        pop     eax

        .IF     eax == DRIVE_FIXED
                szText  szSysDriveLenFmt, "; %lu %lu %lu",13,10
                invoke  GetDiskFreeSpace, offset szDrive, addr lpSectorsPerCluster, addr lpBytesPerSector, addr lpNumberOfFreeClusters, addr lpTotalNumberOfClusters

                mov     eax, lpSectorsPerCluster
                mul     lpBytesPerSector
                invoke  wsprintf, offset lpBuf1, addr szSysDriveLenFmt, eax, lpTotalNumberOfClusters, lpNumberOfFreeClusters
                invoke  lstrcat, GlobalBuffer, offset lpBuf1
        .ELSE
                invoke  lstrcat, GlobalBuffer, offset szSysCRLF
        .ENDIF

        inc     esi
        dec     edi
        jnz     @drv_info_loop

        ; ---------------------------------------------------------
        ; Get the name of the user currently logged onto the system
        ; ---------------------------------------------------------

        IFNDEF MOD_TEXT
                IFNDEF MOD_HTTP
                        mov     nSize, 257 ; UNLEN+1
                        invoke  GetUserName, offset lpBuf2, addr nSize
                        test    eax, eax
                        jz      @get_name_err
        
                        szText  szSysUserNameFmt, "U: %s", 13, 10
                        invoke  wsprintf, offset lpBuf1, addr szSysUserNameFmt, offset lpBuf2
                        invoke  lstrcat, GlobalBuffer, offset lpBuf1
                ENDIF
        ENDIF
@get_name_err:

        ; -------------------
        ; Get CPU information
        ; -------------------

        mov     edi, offset lpBuf2
        xor     eax, eax
        cpuid
        mov     [edi  ], ebx
        mov     [edi+4], edx
        mov     [edi+8], ecx
        mov     byte ptr [edi+12], 0

        xor     ecx, ecx
        test    eax, eax
        jz      @cpu_output
        mov     eax, 1
        cpuid

@cpu_output:
        .IF     eax == 0
                ; CPU doesn't support "CPU signature" function
                szText  szSysCPUShortFmt, "CPV: %s", 13, 10
                invoke  wsprintf, offset lpBuf1, addr szSysCPUShortFmt, edi
        .ELSE
                ; Get CPU stepping, model and family
                xor     ecx, ecx
                xor     edx, edx
                xor     ebx, ebx
                mov     cl, al
                and     cl, 1111b
                shr     eax, 4
                mov     dl, al
                and     dl, 1111b
                shr     eax, 4
                mov     bl, al
                and     bl, 1111b
                szText  szSysCPUFullFmt, "CPV: %s", 13, 10, "CPS: %lu", 13, 10, "CPM: %lu", 13, 10, "CPF: %lu", 13, 10
                invoke  wsprintf, offset lpBuf1, addr szSysCPUFullFmt, edi, ecx, edx, ebx
        .ENDIF
        invoke  lstrcat, GlobalBuffer, offset lpBuf1


        ; --------------------
        ; Get Local IP Address
        ; --------------------
        invoke  gethostname, offset lpBuf1, MAXGETHOSTSTRUCT
        invoke  gethostbyname, offset lpBuf1
        test    eax, eax
        jz      @ip_err

        mov     edx, [eax][hostent.h_list]
        test    edx, edx
        jz      @ip_err

        mov     eax, [edx][in_addr.S_un.S_addr]
        mov     eax, [eax]
        szText  szSysIPFmt, "IP: (%s) %lu",13,10
        invoke  wsprintf, offset lpBuf2, addr szSysIPFmt, offset lpBuf1, eax
        invoke  lstrcat, GlobalBuffer, offset lpBuf2

@ip_err:
        ret
GetSysInfoOutput endp
