/// <summary> /// Fills the memory block with the zeros. /// </summary> /// <param name="ptr">The starting address of the memory block to fill.</param> /// <param name="length">The length of the memory block.</param> public static void SetToZero(IntPtr ptr, ulong length) { SafeNativeMethods.memset(ptr, 0, new UIntPtr(length)); }
private unsafe static void GetRegionScans(IntPtr hRgn, out Rectangle[] scans) { uint bytes = 0; int countdown = 100; int error = 0; // HACK: It seems that sometimes the GetRegionData will return ERROR_INVALID_HANDLE // even though the handle (the HRGN) is fine. Maybe the function is not // re-entrant? I'm not sure, but trying it again seems to fix it. while (countdown > 0) { bytes = SafeNativeMethods.GetRegionData(hRgn, 0, (NativeStructs.RGNDATA *)IntPtr.Zero); error = Marshal.GetLastWin32Error(); if (bytes == 0) { --countdown; System.Threading.Thread.Sleep(5); } else { break; } } // But if we retry several times and it still messes up then we will finally give up. if (bytes == 0) { throw new Win32Exception(error, "GetRegionData returned " + bytes.ToString(CultureInfo.CurrentCulture) + ", GetLastError() = " + error.ToString(CultureInfo.CurrentCulture)); } byte *data; // Up to 512 bytes, allocate on the stack. Otherwise allocate from the heap. if (bytes <= 512) { byte *data1 = stackalloc byte[(int)bytes]; data = data1; } else { data = (byte *)Memory.Allocate(bytes, false).ToPointer(); } try { NativeStructs.RGNDATA *pRgnData = (NativeStructs.RGNDATA *)data; uint result = SafeNativeMethods.GetRegionData(hRgn, bytes, pRgnData); if (result != bytes) { throw new OutOfMemoryException("SafeNativeMethods.GetRegionData returned 0"); } NativeStructs.RECT *pRects = NativeStructs.RGNDATA.GetRectsPointer(pRgnData); scans = new Rectangle[pRgnData->rdh.nCount]; for (int i = 0; i < scans.Length; ++i) { scans[i] = Rectangle.FromLTRB(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom); } pRects = null; pRgnData = null; } finally { if (bytes > 512) { Memory.Free(new IntPtr(data)); } } }
/// <summary> /// Fills the memory block with the specified value. /// </summary> /// <param name="ptr">The starting address of the memory block to fill.</param> /// <param name="value">The value to place in the memory block.</param> /// <param name="length">The length of the memory block.</param> public static void FillMemory(IntPtr ptr, byte value, ulong length) { SafeNativeMethods.memset(ptr, value, new UIntPtr(length)); }
/// <summary> /// Copies bytes from one area of memory to another. Since this function only /// takes pointers, it can not do any bounds checking. /// </summary> /// <param name="dst">The starting address of where to copy bytes to.</param> /// <param name="src">The starting address of where to copy bytes from.</param> /// <param name="length">The number of bytes to copy</param> public static unsafe void Copy(void *dst, void *src, ulong length) { SafeNativeMethods.memcpy(dst, src, new UIntPtr(length)); }