Tutorials to .com

Tutorials to .com » Software » Asm » WIN32 compilation: 13. Memory-mapped file

WIN32 compilation: 13. Memory-mapped file

Print View , by: iSee ,Total views: 20 ,Word Count: 3165 ,Date: Fri, 8 May 2009 Time: 10:36 AM

Memory-mapped file class 13th


This lesson we are going to explain the memory-mapped file, and demonstrate how to use it. You will find the use of memory-mapped file is very simple.

Theory:

If you carefully study the example of the previous lesson, you will find it has a serious flaw: If you would like to read more than the contents of the memory block allocation system how to do? If you want to search for the string just over the border block of memory should do? For the first problem, you might say, as long as time will not continue to solve it. As to the second question, you will say that the memory block in the border to do some special processing, for example, a number of flags placed on it. The principle is indeed feasible, but that with the deepening of the complexity of the problem and it is very difficult to handle. The second issue which is known to determine the issue of borders, many procedures are caused by errors. Think about it, if we can assign an entire document to accommodate the large memory blocks nice ah, do not these two issues are solved it? Yes, WIN32 memory mapping file allows us to actually pretend to be allocated under a reality that may exist in the document is large enough memory.

Use memory-mapped files that the operating system you can have all your documents into memory, and then you can move files to read and write to a pointer. So you call those who do not even need the distribution of the release of the memory block and file input / output API function, the other you can put a different process for sharing data between an option. In fact the use of memory-mapped file a document does not involve the actual operation, it is more like for each process to maintain a visible memory space. As for the memory-mapped file as a process of sharing data between the approach to use, will be more careful, because you had to deal with the issue of data synchronization, or perhaps your application is likely to be outdated or wrong information or even collapse. The main lesson we will talk about memory-mapped files, would not be involved in the process of synchronization between. WIN32 memory mapping file in a wide range of applications, such as: Even if the core of the system --- PE format module loader is also used by memory-mapped file, because of the PE file format is not a one-time to load into memory, such as He loaded the first time when it is necessary to load only part of load, while the other parts when in use to load, which can be used precisely to the strengths of memory-mapped file. Most of the actual file access and PE loader are similar, so you in dealing with such issues should also take full advantage of memory-mapped file.

Memory-mapped file itself, there are some limitations, for example, once you generate a memory-mapped file, then during the conversation that you can not change its size. Therefore, memory-mapped file for read-only file and will not affect the size of the file operations are very useful. Of course, this does not mean that the change will cause the file size must not be used to operate on the memory of documents alluding to, you can operate after the pre-estimated the possible size of the file, and then generate a piece of such a size of the memory-mapped file, and then document length can be increased to such a size. Our explanation enough, then we will look at the details of the achievement:

  1. Call CreateFile to open the file you want to map.
  2. Call CreateFileMapping, which calls CreateFile to return to the previous introduction of the handle, the function generates a function based on CreateFile to create the document object on the basis of memory-mapped object.
  3. Mapping function to call the entire document MapViewOfFile a regional or the entire document into memory. The point is mapped to the function to return the first byte of memory pointer.
  4. Using the pointer to read and write files.
  5. UnmapViewOfFile call to lift the file mapping.
  6. Call CloseHandle to close the memory-mapped file. Attention must be introduced to handle memory-mapped file.
  7. Call CloseHandle to close the file. Attention must be imported from files created by CreateFile handle.

Examples:

The following example allows the user through the "Open File" dialog box to open a file, and then use memory-mapped file to open the file, if successful, will be the title of the window shows the name of the file open, you can choose "File / Save "menu item to the exchange of preservation. The program will be open to keep the contents of the documents to the new document. Note that this whole process did not you used to do GlobalAlloc a function of the allocation of memory.

.386
. model flat, stdcall
WinMain proto: DWORD,: DWORD,: DWORD,: DWORD
include \ masm32 \ include \ windows.inc
include \ masm32 \ include \ user32.inc
include \ masm32 \ include \ kernel32.inc
include \ masm32 \ include \ comdlg32.inc
includelib \ masm32 \ lib \ user32.lib
includelib \ masm32 \ lib \ kernel32.lib
includelib \ masm32 \ lib \ comdlg32.lib

. const
IDM_OPEN equ 1
IDM_SAVE equ 2
IDM_EXIT equ 3
MAXSIZE equ 260

. data
ClassName db "Win32ASMFileMappingClass", 0
AppName db "Win32 asm File Mapping Example", 0
MenuName db "FirstMenu", 0
ofn OPENFILENAME <>
FilterString db "All Files", 0 ,"*.*", 0
db "Text Files", 0, "*. txt", 0,0
buffer db MAXSIZE dup (0)
hMapFile HANDLE 0; Handle to the memory mapped file, must be
; initialized with 0 because we also use it as
; a flag in WM_DESTROY section too

. data?
hInstance HINSTANCE?
CommandLine LPSTR?
hFileRead HANDLE?; Handle to the source file
hFileWrite HANDLE?; Handle to the output file
hMenu HANDLE?
pMemory DWORD?; pointer to the data in the source file
SizeWritten DWORD?; Number of bytes actually written by WriteFile

. code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax

WinMain proc hInst: HINSTANCE, hPrevInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD
LOCAL wc: WNDCLASSEX
LOCAL msg: MSG
LOCAL hwnd: HWND
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW +1
mov wc.lpszMenuName, OFFSET MenuName
mov wc.lpszClassName, OFFSET ClassName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassName, \
ADDR AppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, \
CW_USEDEFAULT, 300,200, NULL, NULL, \
hInst, NULL
mov hwnd, eax
invoke ShowWindow, hwnd, SW_SHOWNORMAL
invoke UpdateWindow, hwnd
. WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0,0
. BREAK. IF (! Eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
. ENDW
mov eax, msg.wParam
ret
WinMain endp

WndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM
. IF uMsg == WM_CREATE
invoke GetMenu, hWnd; Obtain the menu handle
mov hMenu, eax
mov ofn.lStructSize, SIZEOF ofn
push hWnd
pop ofn.hWndOwner
push hInstance
pop ofn.hInstance
mov ofn.lpstrFilter, OFFSET FilterString
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile, MAXSIZE
. ELSEIF uMsg == WM_DESTROY
. if hMapFile! = 0
call CloseMapFile
. endif
invoke PostQuitMessage, NULL
. ELSEIF uMsg == WM_COMMAND
mov eax, wParam
. if lParam == 0
. if ax == IDM_OPEN
mov ofn.Flags, OFN_FILEMUSTEXIST or \
OFN_PATHMUSTEXIST or OFN_LONGNAMES or \
OFN_EXPLORER or OFN_HIDEREADONLY
invoke GetOpenFileName, ADDR ofn
. if eax == TRUE
invoke CreateFile, ADDR buffer, \
GENERIC_READ, \
0, \
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, \
NULL
mov hFileRead, eax
invoke CreateFileMapping, hFileRead, NULL, PAGE_READONLY, 0,0, NULL
mov hMapFile, eax
mov eax, OFFSET buffer
movzx edx, ofn.nFileOffset
add eax, edx
invoke SetWindowText, hWnd, eax
invoke EnableMenuItem, hMenu, IDM_OPEN, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_SAVE, MF_ENABLED
. endif
. elseif ax == IDM_SAVE
mov ofn.Flags, OFN_LONGNAMES or \
OFN_EXPLORER or OFN_HIDEREADONLY
invoke GetSaveFileName, ADDR ofn
. if eax == TRUE
invoke CreateFile, ADDR buffer, \
GENERIC_READ or GENERIC_WRITE, \
FILE_SHARE_READ or FILE_SHARE_WRITE, \
NULL, CREATE_NEW, FILE_ATTRIBUTE_ARCHIVE, \
NULL
mov hFileWrite, eax
invoke MapViewOfFile, hMapFile, FILE_MAP_READ, 0,0,0
mov pMemory, eax
invoke GetFileSize, hFileRead, NULL
invoke WriteFile, hFileWrite, pMemory, eax, ADDR SizeWritten, NULL
invoke UnmapViewOfFile, pMemory
call CloseMapFile
invoke CloseHandle, hFileWrite
invoke SetWindowText, hWnd, ADDR AppName
invoke EnableMenuItem, hMenu, IDM_OPEN, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_SAVE, MF_GRAYED
. endif
. else
invoke DestroyWindow, hWnd
. endif
. endif
. ELSE
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
. ENDIF
xor eax, eax
ret
WndProc endp

CloseMapFile PROC
invoke CloseHandle, hMapFile
mov hMapFile, 0
invoke CloseHandle, hFileRead
ret
CloseMapFile endp

end start

Analysis:

invoke CreateFile, ADDR buffer, \
GENERIC_READ, \
0, \
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, \
NULL

When the user selects to open the file, we call CreateFile to open. Note that we specify GENERIC_READ (general time) to open the document that we can only read out dwShareMode set to 0, that we do not want other processes to operate in our files to access the file.

invoke CreateFileMapping, hFileRead, NULL, PAGE_READONLY, 0,0, NULL

We call in the open CreateFileMapping the basis of a document to generate memory-mapped file. CreateFileMapping syntax is as follows:

CreateFileMapping proto hFile: DWORD, \
lpFileMappingAttributes: DWORD, \
flProtect: DWORD, \
dwMaximumSizeHigh: DWORD, \
dwMaximumSizeLow: DWORD, \
lpName: DWORD

You should be aware that this function does not need to map the entire file into memory, and you can use this function to only part of the mapping file. You can dwMaximumSizeHigh and dwMaximumSizeLow parameters specified in the size of memory-mapped file, if you specify a value greater than the actual file, the actual document to grow to the size specified, if you want to map the memory and file size is the actual size of equivalent, while two parameters are set to become 0. You can set lpFileMappingAttributes for NULL, so WINDOWS given the memory-mapped file in the default security attributes.
flProtect memory mapping file defines the protection of property, we have designated it PAGE_READONLY to the provisions of the memory-mapped file can only be read. Attention to the attributes specified in CreateFile can not contradict the properties, otherwise will not be able to generate memory-mapped file.
lpName specify the name of memory-mapped file, if you want the memory-mapped file at the same time the process can be used for the other, it is necessary to get a name to it. But in our case, the process only if we use the memory-mapped file and we ignore the parameters.

mov eax, OFFSET buffer
movzx edx, ofn.nFileOffset
add eax, edx
invoke SetWindowText, hWnd, eax

CreateFileMapping If the function call is successful, we the title of the window be replaced by the name of the file is opened. Stored in the buffer with the file name is the full path to the file name, so in order to display only the file name we need to use OPENFILENAME structure nFileOffset members to find the value of the file name of the starting address.

invoke EnableMenuItem, hMenu, IDM_OPEN, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_SAVE, MF_ENABLED

In order to avoid the user to open multiple files at one time, we let the "open file" menu item was grayed out, making the menu item to open the file invalid. EnableMenuItem function can be used to change the properties menu item. After the user may save the file or close the application directly. If users choose to close the application, it must be closed prior memory-mapped file and open the file, the code is as follows:

. ELSEIF uMsg == WM_DESTROY
. if hMapFile! = 0
call CloseMapFile
. endif
invoke PostQuitMessage, NULL

In the above code segment, when the news WINDOWS processing WM_DESTROY message received, it is first detected hMapFile value to 0. 0 if not relevant documents that did not shut down, so will need to call to shut down their CloseMapFile.

CloseMapFile PROC
invoke CloseHandle, hMapFile
mov hMapFile, 0
invoke CloseHandle, hFileRead
ret
CloseMapFile endp

The above procedure call is used to close the memory-mapped file and open the original file, so that procedures can be made out of resources when there is no leakage. If users choose to save the file, it will pop up a "Save file" dialog box when the user enters the name of the new document, we call the CreateFile function to create a new document --- output file.

invoke MapViewOfFile, hMapFile, FILE_MAP_READ, 0,0,0
mov pMemory, eax

In the output file is created to map MapViewOfFile we want to call is mapped to the memory part. The function syntax is as follows:

MapViewOfFile proto hFileMappingObject: DWORD, \
dwDesiredAccess: DWORD, \
dwFileOffsetHigh: DWORD, \
dwFileOffsetLow: DWORD, \
dwNumberOfBytesToMap: DWORD

We would like to dwDesiredAccess used to specify the operation of the document. In our example, we just want to read, it is designated signs FILE_MAP_READ.
dwFileOffsetHigh and open the file used to specify dwFileOffsetLow For mapping of the location of the initial migration. The example we want to map the entire file, it specified the value of 0.
For mapping dwNumberOfBytesToMap used to specify the number of bytes, if you want to map the entire document, set the value to 0.
MapViewOfFile call, we hope that some have been mapped to the memory went. You will get a starting point to the memory block pointer.

invoke GetFileSize, hFileRead, NULL

Call this function can be the size of the file, the value sent through eax, if the file is longer than 4G, then DWORD length of high-value part (that is also part of more than 4G) in FileSizeHighWord saved in. Because we estimate that in general there will be no such a big file, so ignore the value.

invoke WriteFile, hFileWrite, pMemory, eax, ADDR SizeWritten, NULL

The memory-mapped file writes the data to the output file.

invoke UnmapViewOfFile, pMemory

Finished, we lift the map.

call CloseMapFile
invoke CloseHandle, hFileWrite

Memory-mapped file and close the output file handle.

invoke SetWindowText, hWnd, ADDR AppName

To restore the title of the window to be the name of the application.

invoke EnableMenuItem, hMenu, IDM_OPEN, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_SAVE, MF_GRAYED

The restoration of "open file" and "Save the file" menu item so that the can start a new open, edit and save cycle.



Assembly Language Tutorial Articles


Can't Find What You're Looking For?


Rating: Not yet rated

Comments

No comments posted.