1 Introduction
In the Windows program, there is often a need to exchange data between each process for data communication. Win32 API provides many functions that allow us to easily and efficiently perform communication between processes. Through these functions, we can control data exchange between different processes, just like reading and writing in Win16.
Typical Win16 two processes can be exchanged by shared memory: (1) Process A Assign GlobalAlloc (GMEM_SHARE ...) API to a certain length of memory; (2) Process A Pass the handle returned by the GlobalLoc function to the process B ( Through a login message); (3) Process B invoking this handle to access the data using the pointer returned by the GlobalLock function. This method may fail in Win32, because the GlobalLock function returns to the process A of the process A, because the process is used by virtual addresses, this pointer is only related to the A process, while the B process Not related.
This paper explores several implementation methods of communication between several Win32 processes, readers can use different methods to achieve efficient and reliable purposes.
2, memory space management of the process in Windows 95
Win32 process communication with Windows 95's memory management has a close relationship, understanding Windows95's memory management will have a lot of help to our programming, let us discuss memory space management of the process in Windows 95.
Under Win16, all Windows applications share a single address, any process can belong to this space to share a single address space, and any process can read and write the memory that belongs to other processes in this space, and even save Take the data of the operating system itself, which may damage the data segment code of other programs.
Under Win32, each process has its own address space, a Win32 process cannot access private data for another address, two processes can be addressed by pointer with the same value, but what they read is just their respective data. This reduces the mutual interference between the processes. On the other hand, each Win32 process has 4GB of address space, but does not represent it truly 4GB of actual physical memory, but only the operating system utilizes the virtual address space provided by the CPU's memory allocation function. In general, most of the virtual addresses do not have physical memory to correspond to it, and the actual physical memory (this process called "submitted" commit) by the operating system before actually using these address spaces. In different cases, the physical memory submitted by the system is different, which may be RAM, or the virtual memory of the hard disk simulation.
3, communication between processes in Win32
In Windows 95, users can have the following options for data exchange between the process between processes.
* Using a memory map file
* Share memory by shared memory DLL
* Send WM_COPYDATA messages to another process
* Call the ReadProcessMemory and the WriteProcessMemory function, the user can send the handle of the Globalock (GMEM_SHARE, ...) function call extracted, the pointer returned by the GLOBALLOCK function and the pointer returned by the VirtualAlloc function.
3.1, using the memory map file to implement communication between the Win32 processes
The mechanism of memory map files in Windows 95 provides a way to our efficient operation file, which allows us to keep a memory area in the Win32 process, map the target file to this virtual memory. Synchronization between the processes must be considered in the program implementation. The specific implementation steps are as follows:
First we need to create a famous shared memory by calling the memory mapping API function CreateFileMapping in the process of sending data: Handle CreateFilemapping
Handle Hfile, // Map the file handle,
/ / Set to 0xfffffffff to create a program shared between processes
LPSecurity_attributes lpfilemappingattributes, // security properties
DWORD flprotect, // protection
DWORD dwmaximumsizehigh, // Size
DWORD DWMAXIMUMSIZELOW,
LPCTSTR LPNAME / / must be named mapping file
);
Similar to virtual memory, the protection mode can be Page_Readonly or Page_Readwrite. If the multi-process is written to the same shared memory, you must keep synchronization between each other. The mapping file can also specify the Page_WriteCopy flag, which ensures that its original data will not be damaged while allowing other processes to copy the copy of the operation data when necessary.
Use the MapViewOffile function after creating a file mapping object to map to the address space of this process.
Hereinafter, a famous mapping file that created a length of 4096 bytes called mysharedmem:
Handle HmysharedMapFile = CREATEFILEMAPPING ((Handle) 0xfffffffff),
NULL, Page_Readwrite, 0,0x1000, "mysharedmem");
And map cache area view:
LPSTR PSZMYSHAREDMAPVIEW = (LPSTR) MapViewOffile (HMYSharedMapFile,
FILE_MAP_READ | File_Map_Write, 0,0,0);
Other processes access shared objects, you need to get the object name and call the OpenFileMapping function.
Handle HmysharedMapFile = OpenFilemapping (file_map_write,
False, "mysharedmem");
Once other processes get the handle of the mapping object, you can map the MapViewOffile function as you create a process to map object views. Users can use the object view to perform data read and write operations to achieve the purpose of data communication.
When the user process ends using the shared memory, call the unmapViewOffile function to cancel the view within its address space:
IF (! unmapViewoffile (pszmysharedmapview))
{AFXMessageBox ("Could Not Unmap View of File);
3.2 Using Shared Memory DLL
The shared data DLL allows the process to access read / write data in a way similar to Windows 3.1 DLL sharing data, and multiple processes can perform data operations on the shared data DLL to achieve the purpose of sharing data. In Win32, the following steps must be performed for establishing shared memory:
First create a famous data area. This is used in Visual C to use Data_SEG PRAGMA macros. Use the data_seg pragma macro must pay attention to the initialization of the data:
#pragma data_seg ("mysec")
CHAR MYSHAREDDATA [4096] = {0};
#pragma data_seg ()
The shared properties are then set for the named data area in the user's DEF file.
Library test
Data Read Write
Sections
.Mysec read Write Shared This process that is attached to the DLL will receive its own data copy, and the data change of a process will not be reflected in the data of other processes.
The data is appropriately output in the DEF file. The following DEF file item illustrates how to output mysharedData in the form of a constant variable.
Exports
MysharedData Constant
Finally, in the application (process), the shared data is referenced by external variables.
Extern _export "c" {char * myshareddata [];
Use this variable in the process should pay attention to indirect references.
M_PSTATIC = (CEDIT *) getdlgitem (idc_shared);
m_pstatic-> getLine (0, * mysharedData, 80);
3.3, WM_COPYDATA for transmitting read-only data
Transferring read-only data can use WM_COPYDATA messages in WIN32. The main purpose of this message is to allow only read-only data between processes. Windows95 does not provide inheritance synchronization mode during transmission through WM_COPYDATA messages. The SDK document recommends that the user uses the sendMessage function, the acceptor does not return before the data copy is completed, so the sender cannot delete and modify the data:
SendMessage (HWND, WM_COPYDATA, WPARAM, LPARAM);
Where WPARAM is set to the handle of the window containing the data. LPARAM points to a copyDataStruct structure:
Typedef struct tagcopydatatruct {
DWORD DWDATA; / / User Defines Data
DWORD CBDATA; // Data Size
PVOID LPDATA; / / Pointer to point to data
} CopyDataStruct;
This structure is used to define user data.
3.4, call the READPROCESSMORY and WRITEPROCESSMEMORY functions to implement inter-process communication
By calling readProcessMemory and WriteProcessMemory function users can implement inter-process communication with Windows 3.1, allocating a memory storage data in the transmission process, can call GlobalLalloc or VirtualalAlloc functions:
PAPP-> M_HGLOBALHANDLE = GLOBALLOC (GMEM_SHARE, 1024);
You can get a pointer address:
PAP-> MPSZGLOBALHANDLEPTR = (LPSTR) Globalock
(PAPP-> M_HGLOBALHANDLE);
In the receiving process, you want to use the open handle of the process of the user you want to affect. To read and write another process, you should call the OpenProcess function as follows:
Handle htargetprocess = OpenProcess
STANDARD_RIGHTS_REQUIRED |
Process_vm_reda |
Process_vm_write |
Process_vm_operation, // Access
False, // inheritance
dwprocessid; // Process ID
To ensure that the OpenProcess function call is successful, the process that the user affects must be created by the above flag.
Once the user gets a valid handle of a process, you can call the ReadProcessMemory function to read the process of the process:
Bool ReadprocessMemory
Handle hprocess, // process pointer
LPCVOID LPBASEADDRESS, // The address of the data block
LPVOID LPBUFFER, // Read data required buffer
DWORD CBREAD, / / The number of bytes to read
LPDWORD LPNUMBEROFBYTESREAD
);
The same handle can also be written to the process of the process:
Bool WriteProcessMemory (Handle HProcess, // Process Pointer
LPVOID LPBASEADDRESS, / / The first address to write
LPVOID LPBUFFER, / / buffer address
DWORD CBWRITE, / / The number of bytes to write
LPDWORD LPNUMBEROFBYTESWRITTEN
);
The following is the data in the shared memory that reads and writes another process:
ReadProcessMemory ((Handle) htargetprocess,
(LPSTR) LPSZ, M_STRGLOBAL.GETBUFFER (_MAX_FIELD),
_MAX_FIELD, & CB);
WriteProcessMemory (Handle) htargetprocess,
(LPSTR) LPSZ, (LPSTR) stars,
M_Strglobal.getlength (), & CB);
4. Message transmission and reception between processes
In the actual application, the Windows message needs to be transmitted and received to notify the process between inter-one, send communication messages to notify the recipient, and the recipient can read and write the memory after receiving the sender's message.
We use the Windows Registration Message in programming to pass messaging, first in the process of sending process initialization, registration:
m_nmsgmapped = :: registerWindowsMessage ("mapped");
m_nmsghandle = :: registerWindowsMessage ("Handle");
m_nmsgshared = :: registerWindowsMessage ("shared");
Send a message to the receiving process in the program run:
CWND * PWNDRECV = FINDWINDOW (LPClassName, "Receive");
PWNDRECV-> SendMessage (m_msgmapped, 0,0);
PWNDRECV-> SendMessage (m_nmsghandle,
(Uint) getCurrentProcessid (), (long) PAPP-> M_HGLOBALHANDLE);
PWNDRECV-> SendMessage (m_nmsgshared, 0, 0);
You can send WM_COPYDATA messages as follows:
Static CopyDataStruct CDS; // User Store Data
PWND-> SendMessage (WM_CopyData, NULL, (long) & cds;
Receiver process initialization must also be registered:
Unit CRECVAPP :: m_nmsgmapped = :: registerWindowsMessage ("mapped");
Unit crecvapp :: m_nmsghandle = :: registerWindowsMessage ("Handle");
Unit CRECVAPP :: M_nmsgshared = :: RegisterWindowsMessage ("shared");
Simultaneous mapping message functions are as follows:
ON_REGISTERED_MASSAGE (CRECVAPP :: m_nmsgmapped, onregmsgmapped)
ON_REGISTERED_MASSAGE (CRECVAPP :: m_nmsghandle, onregmsghandle)
ON_REGISTERED_MASSAGE (CRECVAPP :: M_nmsgshared, OnRegmsgshared)
In these message functions, we can implement the read and write operations of data in the receiving process using the above techniques.
5, conclude