DosSetMem

From EDM2
Jump to: navigation, search

Syntax

rc = DosSetMem( pBaseAddress, 
                ulRegionSize, 
                ulAttributeFlags );

Parameters

PVOID pBaseAddress (input)
The base address of the memory pages that should have their attributes changed.
ULONG ulRegionSize (input)
This is the size, given in bytes, of the pages that should have their attributes changed. This value is rounded up to include all the pages addressed by the base address and size.
ULONG ulAttributeFlags (input)
This is a set of flags describing commitment, decommitment and access protection for the requested memory pages.

Commit Type

Setting PAG_COMMIT (0x00000010) will make the memory pages commited.

Setting PAG_DECOMMIT (0x00000020) will make the memory pages decommited.

If neither PAG_COMMIT nor PAG_DECOMMIT is specified, no changes to the commitment will be made.

Access protection

Setting PAG_EXECUTE (0x00000004) tells the system that 'execute access' to the commited pages is desired in the memory block.

Setting PAG_READ (0x00000001) tells the system that 'read access' is desired.

Setting PAG_WRITE (0x00000002) tells the system that 'write access' is desired.

Setting PAG_GUARD (0x00000008) tells the system that an access to the committed pages should cause a guard page exception to be raised.

Setting PAG_DEFAULT (0x00000400) will assign the memory pages the same access protection as they had when they originally was allocated into the address space of the process.

If PAG_DECOMMIT is not specified, then PAG_DEFAULT or at least one of PAG_READ, PAG_WRITE or PAG_EXECUTE must be specified.

Bits not used by the flags must be clear.

Returns

APIRET rc

The following values can be returned

0 NO_ERROR
5 ERROR_ACCESS_DENIED
8 ERROR_NOT_ENOUGH_MEMORY
87 ERROR_INVALID_PARAMETER
95 ERROR_INTERRUPT
212 ERROR_LOCKED
487 ERROR_INVALID_ADDRESS
32798 ERROR_CROSSES_OBJECT_BOUNDARY

Usage Explanation

DosSetMem is used to commit or decommit allocated memory pages. If the memory pages are already commited DosSetMem can be used to change the access protection of the pages.

A page within the virtual address space of the process is either free, shared or private.

An attempt to access a free page will result in an error. This since the virtual address of the free page is not reserved, not commited and not accessible.

For shared and private pages the virtual address space is reserved during allocation of the memory block. Then each page of the memory block can be in two states:

  1. Committed. A committed page in a shared memory block may not be decommitted, but in the case of a private memory block it may be decommitted. Trying to commit an already committed page will result in an error.
  2. Decommitted. A decommitted page is not committed and not accessible. You may commit a decommitted page, providing the backing storage is available. Trying to decommit a page already decommitted will result in an error.

Committing a page in a shared object will cause the memory page to be committed for all processes that shares the memory block which the memory page belongs to.

Access protection can be given to a committed page, while a decommitted page gets an access protection of 'no access'.

Decommiting a private page (a shared page can not be decommited) will release the backing storage it had as a committed page.

If something goes wrong an error code will be returned, and no changes will be made at all.

You may only change the access protection on a committed page. If the page is not committed, nor being committed at the same time as setting the access protection, an error is returned.

Sample Code

#define INCL_DOSMEMMGR
#include <os2.h>
#include <bsememf.h>

PVOID BaseAddress;
      /* A pointer to the base of the memory block */
      /* that should have its attributes changed.  */

ULONG RegionSize;
      /* Size in bytes of the memory area that should */
      /* have its attributes changed.                 */

ULONG AttributeFlags;
      /* Flags describing the requested characteristics */
      /* of the memory object.                          */

APIRET rc;
      /* Just to take care of the return code. */

AttributeFlags = PAG_COMMIT | PAG_READ;
      /* This will commit the pages and give them read-only */
      /* access.                                            */

RegionSize = 8192;
      /* This size specifies two pages in the memory. If the      */
      /* size had not specified exactly two pages, the value      */
      /* would have been rounded up to the closest page boundary. */

/* Allocate a memory block and store the base address in BaseAddress */

rc = DosSetMem( BaseAddress, RegionSize, AttributeFlags);

if (rc != 0)
{
   /* We have an error we must take care of. */
}

See Also