Interop.VirtualAlloc C# (CSharp) Method

VirtualAlloc() public static method

public static VirtualAlloc ( SafeHandle baseAddress, UIntPtr size, int allocationType, int protection ) : IntPtr
baseAddress SafeHandle
size UIntPtr
allocationType int
protection int
return IntPtr
    public static IntPtr VirtualAlloc(
            SafeHandle baseAddress,
            UIntPtr size,
            int allocationType,
            int protection)
    {
        return Interop.Kernel32.VirtualAllocFromApp(baseAddress, size, allocationType, protection);
    }
}

Usage Example

        public static unsafe MemoryMappedView CreateView(SafeMemoryMappedFileHandle memMappedFileHandle,
                                                         MemoryMappedFileAccess access, long offset, long size)
        {
            // MapViewOfFile can only create views that start at a multiple of the system memory allocation
            // granularity. We decided to hide this restriction from the user by creating larger views than the
            // user requested and hiding the parts that the user did not request.  extraMemNeeded is the amount of
            // extra memory we allocate before the start of the requested view. MapViewOfFile will also round the
            // capacity of the view to the nearest multiple of the system page size.  Once again, we hide this
            // from the user by preventing them from writing to any memory that they did not request.
            ulong nativeSize;
            long  extraMemNeeded, newOffset;

            ValidateSizeAndOffset(
                size, offset, GetSystemPageAllocationGranularity(),
                out nativeSize, out extraMemNeeded, out newOffset);

            // if request is >= than total virtual, then MapViewOfFile will fail with meaningless error message
            // "the parameter is incorrect"; this provides better error message in advance
            Interop.CheckForAvailableVirtualMemory(nativeSize);

            // create the view
            SafeMemoryMappedViewHandle viewHandle = Interop.MapViewOfFile(memMappedFileHandle,
                                                                          (int)MemoryMappedFile.GetFileMapAccess(access), newOffset, new UIntPtr(nativeSize));

            if (viewHandle.IsInvalid)
            {
                viewHandle.Dispose();
                throw Win32Marshal.GetExceptionForLastWin32Error();
            }

            // Query the view for its size and allocation type
            Interop.Kernel32.MEMORY_BASIC_INFORMATION viewInfo = new Interop.Kernel32.MEMORY_BASIC_INFORMATION();
            Interop.Kernel32.VirtualQuery(viewHandle, ref viewInfo, (UIntPtr)Marshal.SizeOf(viewInfo));
            ulong viewSize = (ulong)viewInfo.RegionSize;

            // Allocate the pages if we were using the MemoryMappedFileOptions.DelayAllocatePages option
            // OR check if the allocated view size is smaller than the expected native size
            // If multiple overlapping views are created over the file mapping object, the pages in a given region
            // could have different attributes(MEM_RESERVE OR MEM_COMMIT) as MapViewOfFile preserves coherence between
            // views created on a mapping object backed by same file.
            // In which case, the viewSize will be smaller than nativeSize required and viewState could be MEM_COMMIT
            // but more pages may need to be committed in the region.
            // This is because, VirtualQuery function(that internally invokes VirtualQueryEx function) returns the attributes
            // and size of the region of pages with matching attributes starting from base address.
            // VirtualQueryEx: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366907(v=vs.85).aspx
            if (((viewInfo.State & Interop.Kernel32.MemOptions.MEM_RESERVE) != 0) || ((ulong)viewSize < (ulong)nativeSize))
            {
                IntPtr tempHandle = Interop.VirtualAlloc(
                    viewHandle, (UIntPtr)(nativeSize != MemoryMappedFile.DefaultSize ? nativeSize : viewSize),
                    Interop.Kernel32.MemOptions.MEM_COMMIT, MemoryMappedFile.GetPageAccess(access));
                int lastError = Marshal.GetLastWin32Error();
                if (viewHandle.IsInvalid)
                {
                    viewHandle.Dispose();
                    throw Win32Marshal.GetExceptionForWin32Error(lastError);
                }
                // again query the view for its new size
                viewInfo = new Interop.Kernel32.MEMORY_BASIC_INFORMATION();
                Interop.Kernel32.VirtualQuery(viewHandle, ref viewInfo, (UIntPtr)Marshal.SizeOf(viewInfo));
                viewSize = (ulong)viewInfo.RegionSize;
            }

            // if the user specified DefaultSize as the size, we need to get the actual size
            if (size == MemoryMappedFile.DefaultSize)
            {
                size = (long)(viewSize - (ulong)extraMemNeeded);
            }
            else
            {
                Debug.Assert(viewSize >= (ulong)size, "viewSize < size");
            }

            viewHandle.Initialize((ulong)size + (ulong)extraMemNeeded);
            return(new MemoryMappedView(viewHandle, extraMemNeeded, size, access));
        }