There were some advantages in working with the encryption examples, a good technique for very fast disk writes.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
; This example is how to use an operating system process for very fast file output
; by using the file mapping technique, you write directly to the system paging file
; which in this context is limited to the amount of available memory installed on
; the computer. It allows you to write very large files to disk in a method that is
; much faster than normal file IO as it saves you the time taken to write memory to
; disk after allocated memory has been processed.
; It comes with some limitations, the requested memory must always be less than the
; available memory at the time of making the request. If more memory is requested
; than is available, the operating system will lock up and will require a hardware
; reset to restart the computer.
; There is a technique that is beyond the scope of this example where you create the
; file mapping and use a sliding window with MapViewOfFile() that is less than the
; amount of available memory and keep changing the MapViewOfFile() address.
; In most instances this sliding window technique is not needed as very large files
; are not commonly used and for normal sized files, the example will do the job with
; no problems.
; There is another consideration, this example unmaps the file and leaves the final
; output to the operating system through a method called "lazy write" and while the
; operating system lazy writes the data to disk, less memory is available while the
; lazy write is taking place.
; This example is protected from requesting more memory than is available.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include64\masm64rt.inc
IFNDEF MEMORYSTATUSEX
MEMORYSTATUSEX STRUCT 16
dwLength dd ?
dwMemoryLoad dd ?
ullTotalPhys dq ?
ullAvailPhys dq ?
ullTotalPageFile dq ?
ullAvailPageFile dq ?
ullTotalVirtual dq ?
ullAvailVirtual dq ?
ullAvailExtendedVirtual dq ?
MEMORYSTATUSEX ENDS
ENDIF
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
entry_point proc
USING r12
LOCAL pMMF :QWORD ; mapped file pointer
LOCAL hMMF :QWORD ; mapped handle
LOCAL hFile :QWORD ; open file handle
LOCAL bcnt :QWORD ; size of mapped file
LOCAL mstat :QWORD
SaveRegs
mov rax, 1024*1024*1024*2 ; load immediate into register
mov bcnt, rax ; store register into variable
; ********************************************************
; Protection from requesting more memory than is available
; ********************************************************
mov mstat, rvcall(GetAvailableMemoryStatus) ; get current available memory
.If bcnt gt mstat
conout "Request exceeds available memory",lf
RestoreRegs
.exit
.EndIf
; ********************************************************
mov hFile, flcreate("testfile.txt") ; create a test file
invoke OpenMappedFile,hFile,"testfile", \
bcnt,ADDR pMMF,ADDR hMMF ; map the open file
; *********************************************************
; perform required task for file output here
; *********************************************************
conout "Mapped file opened at ",str$(bcnt)," bytes",lf ; display the mapped file size
waitkey ; pause so you can see the result
; *********************************************************
rcall CloseMappedFile,pMMF,hMMF ; close the file mapping
flclose hFile ; close the open file
RestoreRegs
.exit
entry_point endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
OpenMappedFile proc hFile:QWORD,lpName:QWORD,bcnt:QWORD,pHandle:QWORD,pMemory:QWORD
LOCAL hi32 :DWORD
LOCAL lo32 :DWORD
mov lo32, r8d ; split hi and lo DWORDS of bcnt
rol r8, 32
mov hi32, r8d
invoke CreateFileMapping, \
hFile, \ ; open file handle
NULL, \
PAGE_READWRITE, \ ; read write access to memory
hi32, \ ; high DWORD of bcnt
lo32, \ ; low DWORD of bcnt
lpName ; set file object name here
mov rdx, rax ; MMF handle in RDX
mov rcx, pHandle ; address of variable in RCX
mov [rcx], rax ; write MMF handle to variable
invoke MapViewOfFile, \
rdx, FILE_MAP_WRITE,0,0,0
mov rcx, pMemory ; address of variable in RCX
mov [rcx], rax ; write start address to variable
ret
OpenMappedFile endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
CloseMappedFile proc fmem:QWORD,hmem:QWORD
; ----------------------------------------
; unmapping the file first means you don't
; have to wait for the Windows lazy write.
; ----------------------------------------
rcall UnmapViewOfFile,fmem ; unmap file
rcall CloseMMF,fmem,hmem ; close the file mapping
ret
CloseMappedFile endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
GetAvailableMemoryStatus proc
LOCAL mse :MEMORYSTATUSEX
mov mse.dwLength, SIZEOF MEMORYSTATUSEX ; initialise length
invoke GlobalMemoryStatusEx,ADDR mse ; call API
mov rax, mse.ullAvailPhys ; return available memory
ret
GetAvailableMemoryStatus endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end