| Main | Site Index | Download | Disclaimer | Privacy |


 

 

 

 

 

 

WINDOWS DLL: A SUPPLEMENTARY NOTE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

This supplementary notes contain Dynamic-Link Library (DLL) related Win32 functions used in program examples of the DLL part 1 and DLL part 2 tutorials or wherever applicable. To learn about function you can jump to C &C++ functions tutorials.

 

The Page Index

  1. DllMain()

  2. LoadLibrary()

  3. GetProcAddress()

  4. FreeLibrary()

  5. CreateFileMapping()

  6. MapViewOfFile()

  7. memset(), wmemset()

  8. UnmapViewOfFile()

 

The DllMain()

 

If you already gone through this C/C++ tutorial from the beginning till this one, there are many main functions that have been introduced.  They are:

 

  1. Standard main() as discussed in main() and command line argument.

  2. wmain() for wide character/Unicode discussed in Unicode & Multibyte part 1 and used in Unicode & Multibyte part 2.

  3. Dllmain() function for DLL program, discussed in this Module.

  4. main function for Windows service program, discussed in Windows Services main function.

  5. Other main function that you will find in MFC programs.

 

Item

Description

Function

DllMain().

Use

Is an optional entry point into a dynamic-link library (DLL). If the function is used, it is called by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary() and FreeLibrary() functions. DllMain() is a placeholder for the library-defined function name. You must specify the actual name you use when you build your DLL. For more information, see the documentation included with your development tools.

Prototype

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);

Parameters

See below.

Return value

When the system calls the DllMain() function with the DLL_PROCESS_ATTACH value, the function returns TRUE if it succeeds or FALSE if initialization fails. If the return value is FALSE when DllMain() is called because the process uses the LoadLibrary() function, LoadLibrary() returns NULL. The system immediately calls your entry-point function with DLL_PROCESS_DETACH and unloads the DLL. If the return value is FALSE when DllMain() is called during process initialization, the process terminates with an error. To get extended error information, call GetLastError(). When the system calls the DllMain() function with any value other than DLL_PROCESS_ATTACH, the return value is ignored.

Include file

-

Remark

See below.

 

Table 1.

 

Parameters

 

hinstDLL - [in] Handle to the DLL module. The value is the base address of the DLL. The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in calls to functions that require a module handle.

fdwReason - [in] Indicates why the DLL entry-point function is being called. This parameter can be one of the following values.

 

Value

Meaning

DLL_PROCESS_ATTACH

The DLL is being loaded into the virtual address space of the current process as a result of the process starting up or as a result of a call to LoadLibrary. DLLs can use this opportunity to initialize any instance data or to use the TlsAlloc() function to allocate a thread local storage (TLS) index.

DLL_THREAD_ATTACH

The current process is creating a new thread. When this occurs, the system calls the entry-point function of all DLLs currently attached to the process. The call is made in the context of the new thread. DLLs can use this opportunity to initialize a TLS slot for the thread. A thread calling the DLL entry-point function with DLL_PROCESS_ATTACH does not call the DLL entry-point function with DLL_THREAD_ATTACH.

Note that a DLL's entry-point function is called with this value only by threads created after the DLL is loaded by the process. When a DLL is loaded using LoadLibrary(), existing threads do not call the entry-point function of the newly loaded DLL.

DLL_THREAD_DETACH

A thread is exiting cleanly. If the DLL has stored a pointer to allocated memory in a TLS slot, it should use this opportunity to free the memory. The system calls the entry-point function of all currently loaded DLLs with this value. The call is made in the context of the exiting thread.

DLL_PROCESS_DETACH

The DLL is being unloaded from the virtual address space of the calling process as a result of unsuccessfully loading the DLL, termination of the process, or a call to FreeLibrary(). The DLL can use this opportunity to call the TlsFree() function to free any TLS indices allocated by using TlsAlloc() and to free any thread local data.

Note that the thread that receives the DLL_PROCESS_DETACH notification is not necessarily the same thread that received the DLL_PROCESS_ATTACH notification.

 

Table 2.

 

lpvReserved - [in] If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads and non-NULL for static loads.

If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if DllMain() has been called by using FreeLibrary() and non-NULL if DllMain() has been called during process termination.

 

Some Remarks

 

During initial process startup or after a call to LoadLibrary(), the system scans the list of loaded DLLs for the process. For each DLL that has not already been called with the DLL_PROCESS_ATTACH value, the system calls the DLL's entry-point function. This call is made in the context of the thread that caused the process address space to change, such as the primary thread of the process or the thread that called LoadLibrary(). Access to the entry point is serialized by the system on a process-wide basis. There are cases in which the entry-point function is called for a terminating thread even if the entry-point function was never called with DLL_THREAD_ATTACH for the thread:

  1. The thread was the initial thread in the process, so the system called the entry-point function with the DLL_PROCESS_ATTACH value.

  2. The thread was already running when a call to the LoadLibrary() function was made, so the system never called the entry-point function for it.

 

When a DLL is unloaded from a process as a result of an unsuccessful load of the DLL, termination of the process, or a call to FreeLibrary(), the system does not call the DLL's entry-point function with the DLL_THREAD_DETACH value for the individual threads of the process. The DLL is only sent a DLL_PROCESS_DETACH notification. DLLs can take this opportunity to clean up all resources for all threads known to the DLL. However, if the DLL does not successfully complete a DLL_PROCESS_ATTACH notification, the DLL does not receive either a DLL_THREAD_DETACH or DLL_PROCESS_DETACH notification. If you terminate a process by calling TerminateProcess() or TerminateJobObject(), the DLLs of that process do not receive DLL_PROCESS_DETACH notifications. If you terminate a thread by calling TerminateThread(), the DLLs of that thread do not receive DLL_THREAD_DETACH notifications. The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary() or LoadLibraryEx() function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary() function (or a function that calls FreeLibrary()), because this can result in a DLL being used after the system has executed its termination code.

It is safe to call other functions in Kernel32.dll, because this DLL is guaranteed to be loaded in the process address space when the entry-point function is called. It is common for the entry-point function to create synchronization objects such as critical sections and mutexes, and use TLS. Do not call the registry functions, because they are located in Advapi32.dll. If you are dynamically linking with the C run-time library, do not call malloc(); instead, call HeapAlloc(). Calling imported functions other than those located in Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions in their DLLs call LoadLibrary() to load other system components. Conversely, calling those functions during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized. Because DLL notifications are serialized, entry-point functions should not attempt to communicate with other threads or processes. Deadlocks may occur as a result. Note:  To provide more complex initialization, create an initialization routine for the DLL. You can require applications to call the initialization routine before calling any other routines in the DLL. Otherwise, you can have the initialization routine create a named mutex, and have each routine in the DLL call the initialization routine if the mutex does not exist. Be sure to use a unique mutex name for each process that loads the DLL.

 

LoadLibrary()

 

Item

Description

Function

LoadLibrary().

Use

Maps the specified executable module into the address space of the calling process. For additional load options, use the LoadLibraryEx() function.

Prototype

HMODULE LoadLibrary(LPCTSTR lpFileName);

Parameters

lpFileName - [in] Pointer to a null-terminated string that names the executable module (either a .dll or .exe file). The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.def) file.

If the string specifies a path but the file does not exist in the specified directory, the function fails. When specifying a path, be sure to use backslashes (\), not forward slashes (/).

If the string does not specify a path, the function uses a standard search strategy to find the file. See the Remarks for more information.

Return value

If the function succeeds, the return value is a handle to the module. If the function fails, the return value is NULL. To get extended error information, call GetLastError().

For Windows Me/98/95:  If you are using LoadLibrary() to load a module that contains a resource whose numeric identifier is greater than 0x7FFF, LoadLibrary() fails. If you are attempting to load a 16-bit DLL directly from 32-bit code, LoadLibrary() fails. If you are attempting to load a DLL whose subsystem version is greater than 4.0, LoadLibrary() fails. If your DllMain() function tries to call the Unicode version of a function, LoadLibrary() fails.

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode. More remarks below.

 

Table 3.

 

Some Remarks

 

To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode() function. LoadLibrary() can be used to map a DLL module and return a handle that can be used in GetProcAddress() to get the address of a DLL function. LoadLibrary() can also be used to map other executable modules. For example, the function can specify an .exe file to get a handle that can be used in FindResource() or LoadResource(). However, do not use LoadLibrary() to run an .exe file, use the CreateProcess() function.

If the module is a DLL not already mapped for the calling process, the system calls the DLL's DllMain() function with the DLL_PROCESS_ATTACH value. If the DLL's entry-point function does not return TRUE, LoadLibrary() fails and returns NULL. The system immediately calls your entry-point function with DLL_PROCESS_DETACH and unloads the DLL. It is not safe to call LoadLibrary() from DllMain(). Module handles are not global or inheritable. A call to LoadLibrary() by one process does not produce a handle that another process can use.  For example, in calling GetProcAddress(). The other process must make its own call to LoadLibrary() for the module before calling GetProcAddress(). If no file name extension is specified in the lpFileName parameter, the default library extension .dll is appended. However, the file name string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for loaded modules whose base name matches the base name of the module to be loaded. If the name matches, the load succeeds. Otherwise, the function searches for the file in the following sequence:

 

  1. The directory from which the application loaded.

  2. The current directory.

  3. The system directory. Use the GetSystemDirectory() function to get the path of this directory.

  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. Windows Me/98/95:  This directory does not exist.

  5. The Windows directory. Use the GetWindowsDirectory() function to get the path of this directory.

  6. The directories that are listed in the PATH environment variable.

 

Windows Server 2003, Windows XP SP1:  The default value of HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode is 1 (current directory is searched after the system and Windows directories). Windows XP:  If HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode is 1, the current directory is searched after the system and Windows directories, but before the directories in the PATH environment variable. The default value is 0 (current directory is searched before the system and Windows directories).

The first directory searched is the one directory containing the image file used to create the calling process. Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process's installed directory to the PATH environment variable. The search path can be altered using the SetDllDirectory() function. This solution is recommended instead of using SetCurrentDirectory() or hard-coding the full path to the DLL.

If a path is specified and there is a redirection file for the application, the function searches for the module in the application's directory. If the module exists in the application's directory, the LoadLibrary() function ignores the specified path and loads the module from the application's directory. If the module does not exist in the application's directory, LoadLibrary() loads the module from the specified directory. The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary() or LoadLibraryEx(). If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread). Windows Me/98/95:  LoadLibraryW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

 

GetProcAddress()

 

Item

Description

Function

GetProcAddress().

Use

Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).

Prototype

FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);

Parameters

hModule - [in] Handle to the DLL module that contains the function or variable. The LoadLibrary() or GetModuleHandle() function returns this handle.

lpProcName - [in] Pointer to a null-terminated string that specifies the function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.

Return value

If the function succeeds, the return value is the address of the exported function or variable. If the function fails, the return value is NULL. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

The spelling and case of a function name pointed to by lpProcName must be identical to that in the EXPORTS statement of the source DLL's module-definition (.def) file. The exported names of functions may differ from the names you use when calling these functions in your code. This difference is hidden by macros used in the SDK header files.

The lpProcName parameter can identify the DLL function by specifying an ordinal value associated with the function in the EXPORTS statement. GetProcAddress() verifies that the specified ordinal is in the range 1 through the highest ordinal value exported in the .def file. The function then uses the ordinal as an index to read the function's address from a function table. If the .def file does not number the functions consecutively from 1 to N (where N is the number of exported functions), an error can occur where GetProcAddress() returns an invalid, non-NULL address, even though there is no function with the specified ordinal.

In cases where the function may not exist, the function should be specified by name rather than by ordinal value.

 

Table 4.

 

FreeLibrary()

 

Item

Description

Function

FreeLibrary().

Use

Decrements the reference count of the loaded dynamic-link library (DLL). When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid.

Prototype

BOOL FreeLibrary(HMODULE hModule);

Parameters

hModule - [in] Handle to the loaded DLL module. The LoadLibrary() or GetModuleHandle() function returns this handle.

Return value

If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

Each process maintains a reference count for each loaded library module. This reference count is incremented each time LoadLibrary() is called and is decremented each time FreeLibrary() is called. A DLL module loaded at process initialization due to load-time dynamic linking has a reference count of one. This count is incremented if the same module is loaded by a call to LoadLibrary(). Before unmapping a library module, the system enables the DLL to detach from the process by calling the DLL's DllMain() function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the DLL an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process. It is not safe to call FreeLibrary() from DllMain(). Calling FreeLibrary() does not affect other processes using the same library module.

 

Table 5.

 

CreateFileMapping()

 

Item

Description

Function

CreateFileMapping().

Use

Creates or opens a named or unnamed file mapping object for the specified file.

Prototype

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

Parameters

See below.

Return value

If the function succeeds, the return value is a handle to the file mapping object. If the object existed 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().

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode. More remarks below.

 

Table 6.

 

Parameters

 

hFile - [in] Handle to the file from which to create a mapping object. The file must be opened with access rights compatible with the protection flags specified by the flProtect parameter. It is recommended, though not required, that files you intend to map be opened for exclusive access. If hFile is INVALID_HANDLE_VALUE, the calling process must also specify a mapping object size in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. In this case, CreateFileMapping() creates a file mapping object of the specified size backed by the operating-system paging file rather than by a named file in the file system. The file mapping object can be shared through duplication, through inheritance, or by name. The initial contents of the pages in the file mapping object are zero.

lpAttributes - [in] Pointer to a SECURITY_ATTRIBUTES structure that determines whether the 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 the new file mapping object. If lpAttributes is NULL, the file mapping object gets a default security descriptor. The ACLs in the default security descriptor for a file mapping object come from the primary or impersonation token of the creator. Note that doing this involves potential security risks. To avoid these risks, use a valid SECURITY_ATTRIBUTES structure.

flProtect - [in] Protection desired 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 the committed region of pages. An attempt to write to or execute the committed region results in an access violation. The file specified by the hFile parameter must have been created with the GENERIC_READ access right.

PAGE_READWRITE

Gives read/write access to the committed region of pages. The file specified by hFile must have been created with the GENERIC_READ and GENERIC_WRITE access rights.

PAGE_WRITECOPY

Gives copy-on-write access to the committed region of pages. The files specified by the hFile parameter must have been created with the GENERIC_READ and GENERIC_WRITE access rights.

 

Table 7.

 

In addition, an application can specify certain 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 in the paging file on disk for all pages of a section. This is the default setting.

SEC_IMAGE

The file specified for a section's file mapping is 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.  For Windows Me/98/95:  This flag is not supported.

SEC_NOCACHE

All pages of a section are to be set as non-cacheable. 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 a STATUS_ILLEGAL_INSTRUCTION exception. Note that SEC_NOCACHE requires either the SEC_RESERVE or SEC_COMMIT to also be set. For 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 it is released. Reserved pages can be committed 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 backed by the operating system paging file.

 

Table 8.

 

dwMaximumSizeHigh - [in] High-order DWORD of the maximum size of the file mapping object.

dwMaximumSizeLow - [in] Low-order DWORD of the maximum size of the file mapping object. If this parameter and dwMaximumSizeHigh are zero, the maximum size of the file mapping object is equal to the current size of the file identified by hFile.

An attempt to map a file with a length of zero in this manner fails with an error code of ERROR_FILE_INVALID. Applications should test for files with a length of zero and reject such files.

lpName - [in] Pointer to a null-terminated string specifying the name of the mapping object. If this parameter matches the name of an existing named mapping object, the function requests access to the mapping object with the protection specified by flProtect. 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 name space.

Terminal Services:  The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\).

Windows XP Home Edition:  Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines 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. The empty string ("") is a valid object name.

 

Some Notes

 

After a file mapping object has been created, the size of the file must not exceed the size of the file mapping object; if it does, not all of the file's contents will be 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 grown to match the specified size of the file mapping object. If the file cannot be grown, this results in a failure to create the file mapping object. GetLastError() will return ERROR_DISK_FULL.

The handle that CreateFileMapping() returns has full access to the new file mapping object. It can be used with any function that requires a handle to a file mapping object. File mapping objects can be shared either through process creation, through handle duplication, or by name.

Windows Me/98/95:  File handles that have been 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 has been used in a successful call to the CreateFileMapping() function, do not use that handle unless you first 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's address space.

With one important exception, file views derived from a single file mapping object are coherent, or identical, at a given 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 has to do with 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 will only see its own writes to the page. When the data gets updated on the disk, it is not merged. A mapped file and a file accessed by means of 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 close the file mapping object handle by calling CloseHandle(). The order in which these functions are called does not matter. 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 will not close until all open handles to it are closed. Terminal Services sessions can use shared memory blocks to transfer data between processes spawned by those sessions. If you do this, keep in mind that shared memory cannot be used in situations where both of the following conditions exist:

  1. All of the processes using the shared memory block were not spawned by one session.

  2. 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.

Windows Me/98/95:  CreateFileMappingW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems. 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;

MapViewOfFile()

 

Item

Description

Function

MapViewOfFile().

Use

Maps a view of a file into the address space of the calling process. To specify a suggested base address, use the MapViewOfFileEx() function.

Prototype

LPVOID MapViewOfFile( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap);

Parameters

See below.

Return value

If the function succeeds, the return value is the starting address of the mapped view. If the function fails, the return value is NULL. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

See below.

 

Table 9.

 

Parameters

 

hFileMappingObject - [in] Handle to an open handle of a file mapping object. The CreateFileMapping() and OpenFileMapping() functions return this handle.

dwDesiredAccess - [in] Type of access to the file view and, therefore, the protection of the pages mapped by the file. This parameter can be one of the following values.

 

Value

Meaning

FILE_MAP_WRITE

Read/write access. The mapping object must have been created with PAGE_READWRITE protection. A read/write view of the file is mapped.

FILE_MAP_READ

Read-only access. The mapping object must have been created with PAGE_READWRITE or PAGE_READONLY protection. A read-only view of the file is mapped.

FILE_MAP_COPY

Copy-on-write access. The mapping object must have been created with PAGE_WRITECOPY protection. The system commits physical storage from the paging file at the time MapViewOfFile() is called. The actual physical storage is not used until a thread in your process writes to an address in the view. At that point, the system copies the original page to a new page backed by the paging file, maps the page into the process address space, and changes the page protection to PAGE_READWRITE. The threads in your process can access only this local copy of the data, not the original data. If this page is ever trimmed from your process’ working set, it can then be written to the paging file storage that was committed when MapViewOfFile() was called.

This process only allocates physical memory when a virtual address is actually written to. Changes are never written back to the original file, and are freed when the thread in your process unmaps the view.

Paging file space for the entire view is committed when copy-on-write access is specified, because it is possible that the thread in your process will write to every single page. Therefore, enough physical storage space must be obtained at the time MapViewOfFile() was called.

 

Table 10.

 

dwFileOffsetHigh - [in] High-order DWORD of the file offset where mapping is to begin.

dwFileOffsetLow - [in] Low-order DWORD of the file offset where mapping is to begin. The combination of the high and low offsets must specify an offset within the file that matches the system's memory allocation granularity, or the function fails. That is, the offset must be a multiple of the allocation granularity. Use the GetSystemInfo() function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity.

dwNumberOfBytesToMap - [in] Number of bytes of the file to map. If this parameter is zero, the entire file is mapped.

 

Some Remarks

 

Mapping a file makes the specified portion of the file visible in the address space of the calling process. Multiple views of a file (or a file mapping object and its mapped file) are said to be "coherent" if they contain identical data at a specified time. This occurs if the file views are derived from the same file mapping object. A process can duplicate a file mapping object handle into another process by using the DuplicateHandle() function, or another process can open a file mapping object by name by using the OpenFileMapping() function. A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile() or WriteFile() function:

To guard against STATUS_IN_PAGE_ERROR exceptions, use structured exception handling to protect any code that writes to or reads from a memory mapped view. If the file mapping object is backed by the paging file (hFile is INVALID_HANDLE_VALUE), the paging file must be large enough to hold the entire mapping. If it is not, MapViewOfFile() fails. For Windows Me/98/95:  MapViewOfFile() may require the swapfile to grow. If the swapfile cannot grow, the function fails.

 

memset(), wmemset()

 

Item

Description

Function

memset(), wmemset().

Use

Sets buffers to a specified character.

Prototype

void *memset(void *dest, int c, size_t count);

 

wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count);

Parameters

dest - Pointer to destination.

c - Character to set.

count - Number of characters.

Return value

The value of dest.

Include file

memset() - <memory.h> or <string.h>, wmemset() - <wchar.h>

Remark

-

 

Table 11.

 

UnmapViewOfFile()

 

Item

Description

Function

UnmapViewOfFile().

Use

Unmaps a mapped view of a file from the calling process's address space.

Prototype

BOOL  UnmapViewOfFile(LPCVOID   lpBaseAddress);

Parameters

lpBaseAddress - [in] Pointer to the base address of the mapped view of a file that is to be unmapped. This value must be identical to the value returned by a previous call to the MapViewOfFile() or MapViewOfFileEx() function.

Return value

If the function succeeds, the return value is nonzero, and all dirty pages within the specified range are written "lazily" to disk. If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

Although an application may close the file handle used to create a file mapping object, the system holds the corresponding file open until the last view of the file is unmapped:

Files for which the last view has not yet been unmapped are held open with no sharing restrictions. For Windows Me/98/95:  Files for which the last view has not yet been unmapped are held open with the same sharing restrictions as the original file handle.

 

Table 12.

 

 

-----------------------------------------------------End DLL functions---------------------------------------------------

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Microsoft Visual C++, online MSDN.

  2. Structure, enum, union and typedef story can be found at C enum, typedef, define etc..

  3. For Multibytes, Unicode characters and Localization please refer to Unicode & Multibyte 1 (Story) and Unicode & Multibyte 2 (Implementation).

  4. Windows data type information is in Windows data type.

  5. Check the best selling C / C++ and Windows books at Amazon.com.

 

 

 

 

 

| Main | Site Index | Download | Disclaimer | Privacy |