public AweStream(UInt32 capacity) { unsafe { // Enable the privilege of lock memory. lock (_SetLockPagesPrivilegeLockObj) { if (!_SetLockPagesPrivilegeOk) { LoggedSetLockPagesPrivilege.SetLockPagesPrivilege(System.Diagnostics.Process.GetCurrentProcess(), true); _SetLockPagesPrivilegeOk = true; } } General.SYSTEM_INFO sysInfo; General.GetSystemInfo(out sysInfo); // fill the system information structure _PageSize = sysInfo.dwPageSize; if ((capacity % _PageSize) != 0) { _NumberOfPages = capacity / _PageSize + 1; } else { _NumberOfPages = capacity / _PageSize; } _PFNArraySize = (UInt32)(_NumberOfPages * sizeof(UInt64 *)); // memory to request for PFN array _PFNArray = Marshal.AllocHGlobal((int)_PFNArraySize); UInt32 numberOfPagesInitial = _NumberOfPages; if (!AweApi.AllocateUserPhysicalPages(System.Diagnostics.Process.GetCurrentProcess().Handle, ref _NumberOfPages, _PFNArray)) { Dispose(); throw new AweStreamException("Cannot allocate physical pages", AweStreamException.Reason.CannotAllocatePhysicalPages); } _AweAllocated = true; if (numberOfPagesInitial != _NumberOfPages) { Dispose(); throw new AweStreamException(string.Format("Allocated only {0} pages.", _NumberOfPages), AweStreamException.Reason.AweMemoryNotEnough); } _Capacity = _PageSize * _NumberOfPages; } }
public new void Dispose() { try { UnMap(); } catch { } try { if (_AweAllocated) { AweApi.FreeUserPhysicalPages(System.Diagnostics.Process.GetCurrentProcess().Handle, ref _NumberOfPages, _PFNArray); _AweAllocated = false; } } catch { } try { if (_PFNArray != IntPtr.Zero) { Marshal.FreeHGlobal(_PFNArray); _PFNArray = IntPtr.Zero; } } catch { } try { } catch { base.Dispose(); } }
public void UnMap() { unsafe { if (_VirtualAddress != null) { if (!AweApi.MapUserPhysicalPages(_VirtualAddress, _NumberOfPages, IntPtr.Zero)) { throw new AweStreamException(string.Format("UnMapUserPhysicalPages failed ({0})", General.GetLastError()), AweStreamException.Reason.UnMapUserPhysicalPagesFail); } if (!AweApi.VirtualFree(_VirtualAddress, 0, AweApi.MEM_RELEASE)) { throw new AweStreamException(string.Format("VitualFree failed ({0})", General.GetLastError()), AweStreamException.Reason.VitualFreeFail); } _VirtualAddress = null; } } }
public void Map(bool readOnly) { unsafe { if (IsMapped) { return; } if (readOnly) { _VirtualAddress = AweApi.VirtualAlloc(null, Capacity, AweApi.MEM_RESERVE | AweApi.MEM_PHYSICAL, AweApi.PAGE_READONLY); } else { _VirtualAddress = AweApi.VirtualAlloc(null, Capacity, AweApi.MEM_RESERVE | AweApi.MEM_PHYSICAL, AweApi.PAGE_READWRITE); } if (_VirtualAddress == null) { throw new AweStreamException("Cannot reserve memory.", AweStreamException.Reason.CannotReserveMemory); } if (!AweApi.MapUserPhysicalPages(_VirtualAddress, _NumberOfPages, _PFNArray)) { AweApi.VirtualFree(_VirtualAddress, Capacity, AweApi.MEM_RELEASE); _VirtualAddress = null; throw new AweStreamException(string.Format("MapUserPhysicalPages failed ({0})", General.GetLastError()), AweStreamException.Reason.MapUserPhysicalPagesFail); } _CanWrite = !readOnly; } }