2008年10月22日 星期三

程序與程序間共用記憶體(Shared Memory)

CreateFileMapping

The CreateFileMapping function creates or opens a named or unnamed file mapping object for a specified file.

HANDLE CreateFileMapping(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCTSTR lpName
);

Parameters

hFile
[in] A handle to the file from which to create a mapping object.

The file must be opened with access rights that are compatible with the protection flags that the flProtect parameter specifies. It is not required, but it is recommended that files you intend to map be opened for exclusive access. For more information, see File Security and Access Rights.

If hFile is INVALID_HANDLE_VALUE, the calling process must also specify a mapping object size in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. In this scenario, CreateFileMapping creates a file mapping object of a specified size that the operating system paging file backs, instead of by a named file in the file system.

The file mapping object can be shared by duplication, inheritance, or by name. The initial contents of the pages in a file mapping object are 0 (zero).

lpAttributes
[in] A pointer to a SECURITY_ATTRIBUTES structure that determines whether or not a returned handle can be inherited by child processes.

If lpAttributes is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for a new file mapping object.

If lpAttributes is NULL, the file mapping object gets a default security descriptor. The access control lists (ACL) in the default security descriptor for a file mapping object come from the primary or impersonation token of the creator. However, doing this involves potential security risks. To avoid the risks, use a valid SECURITY_ATTRIBUTES structure.

flProtect
[in] The protection for the file view, when the file is mapped.

This parameter can be one of the following values.

Value Meaning
PAGE_READONLY Gives read-only access to a specific region of pages.

An attempt to write to a specific region results in an access violation. The file that the hFile parameter specifies must be created with the GENERIC_READ access right.

PAGE_READWRITE Gives read/write access to a specific region of pages.

The file that hFile specifies must be created with the GENERIC_READ and GENERIC_WRITE access rights.

PAGE_WRITECOPY Gives copy-on-write access to a specific region of pages.

The files that the hFile parameter specifies must be created with the GENERIC_READ and GENERIC_WRITE access rights.

PAGE_EXECUTE_READ Gives read and execute access to a specific region of pages.

The file specified by hFile must be created with the GENERIC_READ and GENERIC_EXECUTE access rights.

Windows Server 2003 and Windows XP: This feature is not available until Windows XP SP2 and Windows Server 2003 SP1.
PAGE_EXECUTE_READWRITE Gives read, write, and execute access to a specific region of pages.

The file that hFile specifies must be created with the GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access rights.

Windows Server 2003 and Windows XP: This feature is not available until Windows XP SP2 and Windows Server 2003 SP1.

An application can specify section attributes by combining (using the bitwise OR operator) one or more of the following section attribute values with one of the preceding page protection values.

Value Meaning
SEC_COMMIT Allocates physical storage in memory or the paging file on disk for all pages of a section.

This is the default setting.

SEC_IMAGE Sets the file that is specified for section file mapping to be an executable image file.

Because the mapping information and file protection are taken from the image file, no other attributes are valid with SEC_IMAGE.

Windows Me/98/95: This flag is not supported.
SEC_NOCACHE Sets all pages of a section to non-cashable.

Applications should not use this flag except when explicitly required for a device. Using the interlocked functions with memory mapped by a SEC_NOCACHE section can result in an EXCEPTION_ILLEGAL_INSTRUCTION exception.

SEC_NOCACHE requires either the SEC_RESERVE or SEC_COMMIT to be set.

Windows Me/98/95: This flag is not supported.
SEC_RESERVE Reserves all pages of a section without allocating physical storage.

The reserved range of pages cannot be used by any other allocation operations until the range of pages is released.

Reserved pages can be identified in subsequent calls to the VirtualAlloc function. This attribute is valid only if the hFile parameter is INVALID_HANDLE_VALUE; that is, a file mapping object that the operating system paging file backs.

dwMaximumSizeHigh
[in] A high-order DWORD for the maximum size of a file mapping object.
dwMaximumSizeLow
[in] A low-order DWORD for the maximum size of a file mapping object.

If this parameter and dwMaximumSizeHigh are 0 (zero), the maximum size of the file mapping object is equal to the current size of the file that hFile identifies.

An attempt to map a file with a length of 0 (zero) fails with an error code of ERROR_FILE_INVALID. Applications should test for files with a length of 0 (zero) and reject those files.

lpName
[in] A pointer to a null-terminated string that specifies the name of a mapping object.

If this parameter matches the name of an existing mapping object that is named, the function requests access to the mapping object with the protection that flProtect specifies.

If this parameter is NULL, the mapping object is created without a name.

If lpName matches the name of an existing event, semaphore, mutex, waitable timer, or job object, the function fails, and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace.

Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces.
Windows XP: Fast user switching is implemented by using Terminal Services sessions. The first user to log on uses session 0 (zero), the next user to log on uses session 1 (one), and so on. Kernel object names must follow the guidelines that are outlined for Terminal Services so that applications can support multiple users.
Windows 2000: If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character.
Windows NT: The name can contain any character except the backslash character.
Windows Me/98/95: The name can contain any character except the backslash character. An empty string ("") is a valid object name.

Return Values

If the function succeeds, the return value is a handle to the file mapping object.

If the object exists before the function call, the function returns a handle to the existing object (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

After a file mapping object is created, the size of the file must not exceed the size of the file mapping object; if it does, not all of the file contents are available for sharing.

If an application specifies a size for the file mapping object that is larger than the size of the actual named file on disk, the file on disk is increased to match the specified size of the file mapping object.

If the file cannot be increased, the result is a failure to create the file mapping object, and GetLastError returns ERROR_DISK_FULL.

The handle that CreateFileMapping returns has full access to a new file mapping object, and can be used with any function that requires a handle to a file mapping object. A file mapping object can be shared through process creation, handle duplication, or by name. For more information, see DuplicateHandle and OpenFileMapping.

Windows Me/98/95: File handles that are used to create file mapping objects must not be used in subsequent calls to file I/O functions, such as ReadFile and WriteFile. In general, if a file handle is used in a successful call to the CreateFileMapping function, do not use that handle until you close the corresponding file mapping object.

Creating a file mapping object creates the potential for mapping a view of the file, but does not map the view. The MapViewOfFile and MapViewOfFileEx functions map a view of a file into a process address space.

With one important exception, file views derived from a single file mapping object are coherent or identical at a specific time. If multiple processes have handles of the same file mapping object, they see a coherent view of the data when they map a view of the file.

The exception is related to remote files. Although CreateFileMapping works with remote files, it does not keep them coherent. For example, if two computers both map a file as writable, and both change the same page, each computer only sees its own writes to the page. When the data gets updated on the disk, it is not merged.

A mapped file and a file that is accessed by using the input and output (I/O) functions (ReadFile and WriteFile) are not necessarily coherent.

To fully close a file mapping object, an application must unmap all mapped views of the file mapping object by calling UnmapViewOfFile, and then close the file mapping object handle by calling CloseHandle.

These functions can be called in any order. The call to UnmapViewOfFile is necessary, because mapped views of a file mapping object maintain internal open handles to the object, and a file mapping object does not close until all open handles to it are closed.

Terminal Services sessions can use shared memory blocks to transfer data between processes those sessions spawn. If you do this, keep in mind that shared memory cannot be used in situations where both of the following conditions exist:

  • All of the processes that use a shared memory block are not spawned by one session.
  • All of the sessions share the same user logon credential.

To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory mapped view. For more information, see Reading and Writing From a File View.

To have a mapping with executable permissions, an application must call CreateFileMapping with either PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_READ, and then call MapViewOfFile with FILE_MAP_EXECUTE | FILE_MAP_WRITE or FILE_MAP_EXECUTE | FILE_MAP_READ.

Example Code [C++]

To implement a mapping object creation function that fails if the object already exists, an application can use the following code.

hMap = CreateFileMapping(...);

if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMap);
hMap = NULL;
}
return hMap;

Example Code

Creating Named Shared Memory

To share data, multiple processes can use memory-mapped files that are backed by the system paging file.

First Process

The first process creates the file mapping object by calling the CreateFileMapping function with INVALID_HANDLE_VALUE and a name for the object. By using the PAGE_READWRITE flag, the process has read/write permission to the memory through any file views that are created.

Then the process uses the file mapping object handle that CreateFileMapping returns in a call to MapViewOfFile to create a view of the file in the process address space. The MapViewOfFile function returns a pointer to the file view.

When the process does not need access to the file mapping object, it should call the CloseHandle function. When all handles are closed, the system can free the section of the paging file that the object uses.

#include 
#include
#include

#define BUF_SIZE 256
TCHAR szName[]=TEXT("MyFileMappingObject");
TCHAR szMsg[]=TEXT("Message from first process");

void main()
{
HANDLE hMapFile;
LPCTSTR pBuf;

hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // max. object size
BUF_SIZE, // buffer size
szName); // name of mapping object

if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE)
{
printf("Could not create file mapping object (%d).\n",
GetLastError());
return;
}
pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);

if (pBuf == NULL)
{
printf("Could not map view of file (%d).\n",
GetLastError());
return;
}


CopyMemory((PVOID)pBuf, szMsg, strlen(szMsg));
getch();

UnmapViewOfFile(pBuf);

CloseHandle(hMapFile);
}

Second Process

A second process can access the same data by calling the OpenFileMapping function with the same name as the first process. Then it can use the MapViewOfFile function to obtain a pointer to the file view.

#include 
#include
#include
#include

#define BUF_SIZE 256
TCHAR szName[]=TEXT("MyFileMappingObject");

void main()
{
HANDLE hMapFile;
LPCTSTR pBuf;

hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szName); // name of mapping object

if (hMapFile == NULL)
{
printf("Could not open file mapping object (%d).\n",
GetLastError());
return;
}

pBuf = MapViewOfFile(hMapFile, // handle to mapping object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);

if (pBuf == NULL)
{
printf("Could not map view of file (%d).\n",
GetLastError());
return;
}

MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK);

UnmapViewOfFile(pBuf);

CloseHandle(hMapFile);
}

Text Source:MSDN

0 意見: