I have a .Net application that during handling of WM_NCPAINT for one of its windows genarates exception "Arithmetic operation resulted in an overflow.". This happens only in a 64-bit prefix and only for WPARAM that contains an HRGN handle with value over than 0x7fffffff.
The application does the following: public static IntPtr GetNativeDC(Message m, IntPtr handle) { if (m.Msg != 0x85) // WM_NCPAINT { return NUser32.GetWindowDC(handle); } int num = 0x200013; // DCX_VALIDATE | DCX_CLIPSIBLINGS | DCX_CACHE | DCX_WINDOW IntPtr intPtr = IntPtr.Zero; IntPtr wParam = m.WParam; if (wParam.ToInt32() != 1) { num |= 0x80; // DCX_INTERSECTRGN intPtr = CreateRectRgn(0, 0, 1, 1); CombineRgn(intPtr, wParam, IntPtr.Zero, 5); // RGN_COPY } return NUser32.GetDCEx(handle, intPtr, num); } The exception is generated by wParam.ToInt32(). MSDN description for ToInt32() https://learn.microsoft.com/en-us/dotnet/api/system.intptr.toint32?view=net-... states Exceptions OverflowException In a 64-bit process, the value of this instance is too large or too small to represent as a 32-bit signed integer.
MSDN also has a reference to ToInt32() source: https://github.com/dotnet/runtime/blob/5535e31a712343a63f5d7d796cd874e563e5a... public int ToInt32() { #if TARGET_64BIT return checked((int)_value); #else return (int)_value; #endif } It's not clear why a sign extension may lead to an overflow exception.
This patch fixes the problem, and provides a test case that confirms that entry.Generation field of a GDI32 object is limited by 127 on a 64-bit platform, while 32-bit Windows doesn't have such a limitation.