LINE_FEED equ 13,10 system_init: invoke GetStdHandle,STD_OUTPUT_HANDLE mov [stdout],eax invoke GetStdHandle,STD_ERROR_HANDLE mov [stderr],eax invoke HeapCreate,0,20000h,0 mov [memory],eax test eax,eax jz out_of_memory invoke GetSystemTime,systemtime invoke SystemTimeToFileTime,systemtime,filetime mov ebx,[filetime.dwLowDateTime] mov eax,[filetime.dwHighDateTime] sub ebx,116444736000000000 and 0FFFFFFFFh sbb eax,116444736000000000 shr 32 xor edx,edx mov ecx,10000000 div ecx mov dword [timestamp+4],eax mov eax,ebx div ecx mov dword [timestamp],eax retn system_shutdown: cmp [memory],0 je memory_released invoke HeapDestroy,[memory] memory_released: invoke CloseHandle,[stdout] invoke CloseHandle,[stderr] retn malloc: malloc_fixed: malloc_growable: ; in: ecx = requested size ; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return) ; preserves: ebx, esi, edi ; note: ; use of malloc_fixed hints that block will be kept as is until the end of assembly ; use of malloc_growable hints that block is likely to be resized invoke HeapAlloc,[memory],0,ecx test eax,eax jz out_of_memory memory_allocated: push eax invoke HeapSize,[memory],0,eax mov ecx,eax pop eax cmp ecx,-1 je out_of_memory retn realloc: ; in: eax - memory block, ecx = requested size ; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return) ; preserves: ebx, esi, edi invoke HeapReAlloc,[memory],0,eax,ecx test eax,eax jnz memory_allocated jmp out_of_memory mfree: ; in: eax - memory block ; out: cf set on error ; preserves: ebx, esi, edi ; note: eax may have value 0 or -1, it should be treated as invalid input then test eax,eax jz interface_error cmp eax,-1 je interface_error invoke HeapFree,[memory],0,eax test eax,eax jz interface_error clc retn interface_error: stc retn open: ; in: edx - path to file ; out: ebx = file handle, cf set on error ; preserves: esi, edi invoke CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 cmp eax,-1 je interface_error mov ebx,eax clc retn create: ; in: edx - path to file ; out: ebx = file handle, cf set on error ; preserves: esi, edi invoke CreateFile,edx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0 cmp eax,-1 je interface_error mov ebx,eax clc retn write: ; in: ebx = file handle, edx - data, ecx = number of bytes ; out: cf set on error ; preserves: ebx, esi, edi push ecx invoke WriteFile,ebx,edx,ecx,systmp,0 pop ecx test eax,eax jz interface_error cmp ecx,[systmp] jne interface_error clc retn read: ; in: ebx = file handle, edx - buffer, ecx = number of bytes ; out: cf set on error ; preserves: ebx, esi, edi push ecx invoke ReadFile,ebx,edx,ecx,systmp,0 pop ecx test eax,eax jz interface_error cmp ecx,[systmp] jne interface_error clc retn close: ; in: ebx = file handle ; preserves: ebx, esi, edi invoke CloseHandle,ebx retn lseek: ; in: ebx = file handle, cl = method, edx:eax = offset ; out: edx:eax = new offset from the beginning of file, cf set on error ; preserves: ebx, esi, edi movzx ecx,cl mov [systmp],edx invoke SetFilePointer,ebx,eax,systmp,ecx cmp eax,-1 jne lseek_ok invoke GetLastError test eax,eax jnz interface_error not eax lseek_ok: mov edx,[systmp] clc retn get_timestamp: ; out: edx:eax = timestamp ; preserves: ebx, ecx, esi, edi ; note: during the passes of a single assembly this function should always return the same value mov eax,dword [timestamp] mov edx,dword [timestamp+4] retn display_string: ; in: ; esi - string ; ecx = string length, zero for ASCIIZ string ; preserves: ebx, esi push ebx mov ebx,[stdout] jmp write_string display_error_string: ; in: ; esi - string ; ecx = string length, zero for ASCIIZ string ; preserves: ebx, esi push ebx mov ebx,[stderr] write_string: test ecx,ecx jnz write_string_to_stdout xor al,al mov edi,esi or ecx,-1 repne scasb neg ecx sub ecx,2 write_string_to_stdout: mov edx,esi write_portion_to_stdout: mov eax,51200 cmp ecx,eax jbe final_write_to_stdout sub ecx,eax add eax,edx push eax ecx invoke WriteFile,ebx,edx,51200,systmp,0 pop ecx edx jmp write_portion_to_stdout final_write_to_stdout: invoke WriteFile,ebx,edx,ecx,systmp,0 pop ebx retn get_environment_variable: ; in: ; esi - name ; edi - buffer for value ; ecx = size of buffer ; out: ; eax = length of value ; preserves: ebx, esi, edi push ecx invoke GetEnvironmentVariable,esi,edi,ecx pop ecx cmp eax,ecx jae environment_variable_ready mov byte [edi+eax],0 environment_variable_ready: inc eax retn