;format PE GUI 4.0
format PE64 console
;format PE64 GUI
entry start

;include 'c:\fasm\include\win32a.inc'
include 'win64a.inc'

;include 'c:\fasm\include\MACRO\IF.inc'
;include 'c:\fasm\INCLUDE\ERROR_CODES.inc'


;-----------------------------------------------------------------------------
; Uninitialized data
;-----------------------------------------------------------------------------
section '.bss' readable writeable executable

		hFile           dq      ?


;-----------------------------------------------------------------------------
; Initialized data
;-----------------------------------------------------------------------------
section '.data' data readable writeable

		;Test_File    db      'c:\temp\cmd_x86.exe',0
	   ; Test_File    db 'c:\temp\test.txt',0
		;Test_File    db 'c:\\temp\\test.txt',0
		Test_File    db 'test.txt',0
		; For wide-character
		;Test_File    db 'c',0,':',0,'\',0,'t',0,'e',0,'m',0,'p',0,'\',0,'t',0,'e',0,'s',0,'t',0,'.',0,'t',0,'x',0,'t',0,0,0
		File_Size       dq      0

;        lpBuffer        dq      0


section '.text' code readable writeable executable


start:
		sub rsp, 8
;proc start
		;stdcall Get_Filesize
		stdcall ExecuteCode

		;.if eax <> 0
		;    push 0
		;    call ShowLastError
		;.endif

		mov         rax, TRUE
		invoke      ExitProcess, 0

;        ret
;endp

proc ExecuteCode
	 stdcall Get_Filesize
	 ret
endp

proc Get_Filesize

	; Open the file
				;push ecx
						xor rcx, rcx

								lea rcx, [Test_File]

								invoke CreateFile, rcx, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
								;invoke CreateFile, ecx, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL
								;invoke CreateFile,ecx,GENERIC_READ Or GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
								;invoke CreateFile,ecx,GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0
								cmp rax, INVALID_HANDLE_VALUE
								jne CreateFile_SUCCESS
								;push eax
								;        invoke GetLastError
								;        .if eax <> ERROR_SUCCESS
								;                 pop eax
							   ; .if eax = INVALID_HANDLE_VALUE

												push 0
												call ShowLastError

												;pop ebx
												;pop ecx
												ret
								;        .endif
								;pop eax
								CreateFile_SUCCESS:
										mov [hFile], rax

				;        pop ebx
			   ; pop ecx

	; Get the file size
			;push ecx
				;push ebx
				xor rcx, rcx

						;invoke GetFileSize, hFile, 0
						;push eax
						;invoke GetLastError
						;.if eax <> ERROR_SUCCESS

						invoke GetFileSizeEx, hFile, File_Size
						cmp rax, 0
						jne GetFileSizeEx_SUCCESS
						; GetFileSizeEx returns non-zero if it succeeds as per:
						; https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfilesizeex
						;.if eax = 0

							;pop eax

							push 0
							call ShowLastError

							;pop ebx
							;pop ecx
							ret
						;.endif
				GetFileSizeEx_SUCCESS:
					add rax, 1
					mov [File_Size], rax

				;pop ebx
			;pop ecx

;        mov         eax, TRUE
;        invoke      ExitProcess, 0

		ret
endp




proc ShowErrorMessage hWnd,dwError
;  local lpBuffer:DWORD
local lpBuffer:QWORD
		;lea     rax,[lpBuffer]
		;mov rax, lpBuffer
		invoke  FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,[dwError],LANG_NEUTRAL,[lpBuffer],0,0
		;invoke  MessageBox,[hWnd],[lpBuffer],NULL,MB_ICONERROR+MB_OK
		invoke  MessageBox,NULL,[lpBuffer],NULL,MB_ICONERROR+MB_OK
		;invoke  MessageBox,NULL,eax,NULL,MB_ICONERROR+MB_OK
		;invoke  LocalFree,[lpBuffer]
		mov rax, [lpBuffer]
		invoke  LocalFree,eax
		ret
endp

proc ShowLastError hWnd
		invoke  GetLastError
		;stdcall ShowErrorMessage,[hWnd],rax
		stdcall ShowErrorMessage,NULL,rax
		ret
endp



section '.idata' import data readable writeable

	library kernel32,'KERNEL32.DLL',\
		  user32,'USER32.DLL'

	include 'api/kernel32.inc'

	import user32,\
		 MessageBox,'MessageBoxA'



section '.edata' export data readable

	export 'Test_GetFileSize.EXE',\
		ShowErrorMessage,'ShowErrorMessage',\
		ShowLastError,'ShowLastError',\
		Get_Filesize,'Get_Filesize'
