Background
If we want to pass data between different process, we can use file, Windows Message Queue, or
the network. But a memory-mapped file is the best technique.
Declare in .NET CF using C#:
public class WinCEConst
{
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
public const UInt32 SECTION_QUERY = 0x0001;
public const UInt32 SECTION_MAP_WRITE = 0x0002;
public const UInt32 SECTION_MAP_READ = 0x0004;
public const UInt32 SECTION_MAP_EXECUTE = 0x0008;
public const UInt32 SECTION_EXTEND_SIZE = 0x0010;
public const UInt32 SECTION_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED SECTION_QUERY
SECTION_MAP_WRITE
SECTION_MAP_READ
SECTION_MAP_EXECUTE
SECTION_EXTEND_SIZE);
public const UInt32 FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS;
public static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
public const int PAGE_READWRITE = 0x04;
public const int PAGE_READONLY = 0x02;
public const int FILE_MAP_READ = 0x0004;
public const int FILE_MAP_WRITE = 0x0002;
}
public class WinCE
{
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto)]
public static extern int GetAdaptersInfo(IntPtr pAdapterInfo, ref int pBufOutLen);
[DllImport("Coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("Coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFileMapping(
IntPtr hFile,
object lpFileMappingAttributes,
uint flProtect,
uint dwMaximumSizeHigh,
uint dwMaximumSizeLow,
string lpName);
[DllImport("Coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFileForMapping(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
public static IntPtr OpenFileMapping(uint dwDesiredAccess, bool bInheritHandle, string lpName)
{
IntPtr t_pHandle = CreateFileMapping(new IntPtr(-1), null,
WinCEConst.PAGE_READWRITE, 0, 0, lpName);
return t_pHandle;
}
[DllImport("Coredll.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern IntPtr MapViewOfFile(
IntPtr hFileMappingObject,
uint dwDesiredAccess,
uint dwFileOffsetHigh,
uint dwFileOffsetLow,
uint dwNumberOfBytesToMap);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
}
How to create a memory-mapped file and put data to it
const string MapName = "OrzCloud";
const int MapSize = 1024;
IntPtr m_pMapFile;
IntPtr m_pBuff;
string data = "TestTest";
m_pMapFile = WinCE.CreateFileMapping(
WinCEConst.INVALID_HANDLE_VALUE, null,WinCEConst.PAGE_READWRITE, 0, MapSize, MapName);
t_i4Error = Marshal.GetLastWin32Error();
m_pBuff = WinCE.MapViewOfFile(m_pMapFile,WinCEConst.FILE_MAP_ALL_ACCESS, 0, 0, MapSize);
t_i4Error = Marshal.GetLastWin32Error();
byte[] t_bData = Encoding.ASCII.GetBytes(data);
Marshal.Copy(t_bData, 0, m_pBuff, t_bData.Length);
How to open an existing memory-mapped file and get data
m_pMapFile = WinCE.OpenFileMapping(WinCEConst.FILE_MAP_ALL_ACCESS, false, MapName);
t_i4Error = Marshal.GetLastWin32Error();
m_pBuff = WinCE.MapViewOfFile(m_pMapFile, WinCEConst.FILE_MAP_ALL_ACCESS, 0, 0, MapSize);
byte[] bytData = new byte[MapSize];
Marshal.Copy(m_pBuff, bytData, 0, MapSize);
string data = Encoding.ASCII.GetString(bytData,0,MapSize).Trim();
How to close a memory-mapped file
WinCE.UnmapViewOfFile(m_pBuff);
WinCE.CloseHandle(m_pMapFile);
References