Chromium Code Reviews| Index: skia/ext/bitmap_platform_device_win.cc |
| diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc |
| index 63108209abc313b305256319246a06fa7d03424c..ccffc9bdf4468babcc6afb1925fead5b7993b742 100644 |
| --- a/skia/ext/bitmap_platform_device_win.cc |
| +++ b/skia/ext/bitmap_platform_device_win.cc |
| @@ -16,6 +16,27 @@ |
| namespace { |
| +typedef decltype(GetProcessMitigationPolicy)* GetProcessMitigationPolicyType; |
| + |
| +bool IsWin32kLockdownEnabled() { |
| + GetProcessMitigationPolicyType GetProcessMitigationPolicyFunc = |
|
scottmg
2015/09/04 02:46:19
GetProcessMitigationPolicyFunc should be get_proce
forshaw
2015/09/04 09:58:05
Done.
|
| + reinterpret_cast<GetProcessMitigationPolicyType>(::GetProcAddress( |
|
scottmg
2015/09/04 02:46:19
remove unnecessary :: qualifiers (or add them ever
forshaw
2015/09/04 09:58:05
Done.
|
| + ::GetModuleHandle(L"kernel32.dll"), |
| + "GetProcessMitigationPolicy")); |
| + |
| + if (!GetProcessMitigationPolicyFunc) |
| + return false; |
| + |
| + PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {0}; |
| + if (GetProcessMitigationPolicyFunc(GetCurrentProcess(), |
| + ProcessSystemCallDisablePolicy, |
| + &policy, |
| + sizeof(policy))) |
| + return policy.DisallowWin32kSystemCalls != 0; |
| + |
| + return false; |
|
Will Harris
2015/09/04 02:25:50
can you cache the result of this function with a s
forshaw
2015/09/04 09:58:05
Will cache with static, don't think it needs to be
|
| +} |
| + |
| HBITMAP CreateHBitmap(int width, int height, bool is_opaque, |
| HANDLE shared_section, void** data) { |
| // CreateDIBSection appears to get unhappy if we create an empty bitmap, so |
| @@ -57,6 +78,7 @@ namespace skia { |
| void DrawToNativeContext(SkCanvas* canvas, HDC hdc, int x, int y, |
| const RECT* src_rect) { |
| + DCHECK(!IsWin32kLockdownEnabled()); |
| PlatformDevice* platform_device = GetPlatformDevice(GetTopDevice(*canvas)); |
| if (platform_device) |
| platform_device->DrawToHDC(hdc, x, y, src_rect); |
| @@ -65,6 +87,7 @@ void DrawToNativeContext(SkCanvas* canvas, HDC hdc, int x, int y, |
| void PlatformDevice::DrawToHDC(HDC, int x, int y, const RECT* src_rect) {} |
| HDC BitmapPlatformDevice::GetBitmapDC() { |
| + DCHECK(!IsWin32kLockdownEnabled()); |
| if (!hdc_) { |
| hdc_ = CreateCompatibleDC(NULL); |
| InitializeDC(hdc_); |
| @@ -76,11 +99,13 @@ HDC BitmapPlatformDevice::GetBitmapDC() { |
| } |
| void BitmapPlatformDevice::ReleaseBitmapDC() { |
| - SkASSERT(hdc_); |
| - SelectObject(hdc_, old_hbitmap_); |
| - DeleteDC(hdc_); |
| - hdc_ = NULL; |
| - old_hbitmap_ = NULL; |
| + if (!IsWin32kLockdownEnabled()) { |
| + SkASSERT(hdc_); |
| + SelectObject(hdc_, old_hbitmap_); |
| + DeleteDC(hdc_); |
| + hdc_ = NULL; |
| + old_hbitmap_ = NULL; |
| + } |
| } |
| bool BitmapPlatformDevice::IsBitmapDCCreated() |
| @@ -108,7 +133,12 @@ void BitmapPlatformDevice::LoadConfig() { |
| } |
| static void DeleteHBitmapCallback(void* addr, void* context) { |
| - DeleteObject(static_cast<HBITMAP>(context)); |
| + // If context is not NULL then it's a valid HBITMAP to delete. |
| + // Otherwise we just unmap the pixel memory. |
| + if (context) |
| + DeleteObject(static_cast<HBITMAP>(context)); |
| + else |
| + UnmapViewOfFile(addr); |
| } |
| static bool InstallHBitmapPixels(SkBitmap* bitmap, int width, int height, |
| @@ -117,6 +147,7 @@ static bool InstallHBitmapPixels(SkBitmap* bitmap, int width, int height, |
| const SkImageInfo info = SkImageInfo::MakeN32(width, height, at); |
| const size_t rowBytes = info.minRowBytes(); |
| SkColorTable* color_table = NULL; |
| + |
|
Will Harris
2015/09/04 02:25:50
nit: line
|
| return bitmap->installPixels(info, data, rowBytes, color_table, |
| DeleteHBitmapCallback, hbitmap); |
| } |
| @@ -133,10 +164,22 @@ BitmapPlatformDevice* BitmapPlatformDevice::Create( |
| bool do_clear) { |
| void* data; |
| - HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, shared_section, |
| + |
| + HBITMAP hbitmap = NULL; |
|
scottmg
2015/09/04 02:46:19
NULL -> nullptr, and elsewhere
forshaw
2015/09/04 09:58:05
Was just being consistent with the rest of the fil
|
| + |
| + if (IsWin32kLockdownEnabled()) { |
| + CHECK(shared_section != NULL); |
| + data = MapViewOfFile(shared_section, FILE_MAP_WRITE, |
| + 0, 0, width * height * 4); |
| + DCHECK(data != NULL); |
| + if (!data) |
| + return NULL; |
| + } else { |
| + hbitmap = CreateHBitmap(width, height, is_opaque, shared_section, |
| &data); |
| - if (!hbitmap) |
| - return NULL; |
| + if (!hbitmap) |
| + return NULL; |
| + } |
| SkBitmap bitmap; |
| if (!InstallHBitmapPixels(&bitmap, width, height, is_opaque, data, hbitmap)) |
| @@ -180,12 +223,14 @@ BitmapPlatformDevice::BitmapPlatformDevice( |
| // The data object is already ref'ed for us by create(). |
| SkDEBUGCODE(begin_paint_count_ = 0); |
| SetPlatformDevice(this, this); |
| - // Initialize the clip region to the entire bitmap. |
| - BITMAP bitmap_data; |
| - if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) { |
| - SkIRect rect; |
| - rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight); |
| - clip_region_ = SkRegion(rect); |
| + if (hbitmap) { |
| + // Initialize the clip region to the entire bitmap. |
| + BITMAP bitmap_data; |
| + if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) { |
| + SkIRect rect; |
| + rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight); |
| + clip_region_ = SkRegion(rect); |
| + } |
| } |
| } |
| @@ -213,6 +258,8 @@ void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, |
| void BitmapPlatformDevice::DrawToHDC(HDC dc, int x, int y, |
| const RECT* src_rect) { |
| + DCHECK(!IsWin32kLockdownEnabled()); |
| + |
| bool created_dc = !IsBitmapDCCreated(); |
| HDC source_dc = BeginPlatformPaint(); |
| @@ -305,6 +352,7 @@ PlatformBitmap::~PlatformBitmap() { |
| } |
| bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) { |
| + DCHECK(!IsWin32kLockdownEnabled()); |
| void* data; |
| HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, 0, &data); |
| if (!hbitmap) |