VBoxVideoWinDbg.cpp revision 40bd0fc692d21a6d579862d7ccdc20c2ccf361a5
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync/* $Id$ */
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync/** @file
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * Copyright (C) 2011 Oracle Corporation
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync *
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * available from http://www.virtualbox.org. This file is free software;
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * General Public License (GPL) as published by the Free Software
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync */
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync#include <windows.h>
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync#define KDEXT_64BIT
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync#include <wdbgexts.h>
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync#define VBOXVWD_VERSION_MAJOR 1
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync#define VBOXVWD_VERSION_MINOR 1
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsyncstatic EXT_API_VERSION g_VBoxVWDVersion = {
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync VBOXVWD_VERSION_MAJOR,
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync VBOXVWD_VERSION_MINOR,
4346537134a6c1454fc906711dbe4e987ebe9f33vboxsync EXT_API_VERSION_NUMBER64,
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync 0
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync};
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/**
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * DLL entry point.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync */
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncBOOL WINAPI DllMain(HINSTANCE hInstance,
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync DWORD dwReason,
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync LPVOID lpReserved)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync{
de6e321f351aa489a6a62bed474390a0056e8093vboxsync BOOL bOk = TRUE;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
7af218a7441de38fc9e814919db04bae3e917664vboxsync switch (dwReason)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync {
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync case DLL_PROCESS_ATTACH:
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync {
de6e321f351aa489a6a62bed474390a0056e8093vboxsync break;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync case DLL_PROCESS_DETACH:
de6e321f351aa489a6a62bed474390a0056e8093vboxsync {
de6e321f351aa489a6a62bed474390a0056e8093vboxsync break;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync default:
de6e321f351aa489a6a62bed474390a0056e8093vboxsync break;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync return bOk;
044af0d1e6474076366759db86f101778c5f20ccvboxsync}
044af0d1e6474076366759db86f101778c5f20ccvboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync/* note: need to name it this way to make dprintf & other macros defined in wdbgexts.h work */
de6e321f351aa489a6a62bed474390a0056e8093vboxsyncWINDBG_EXTENSION_APIS64 ExtensionApis = {0};
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncUSHORT SavedMajorVersion;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncUSHORT SavedMinorVersion;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#ifdef __cplusplus
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncextern "C"
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
de6e321f351aa489a6a62bed474390a0056e8093vboxsync#endif
044af0d1e6474076366759db86f101778c5f20ccvboxsyncLPEXT_API_VERSION WDBGAPI ExtensionApiVersion();
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncVOID WDBGAPI CheckVersion();
044af0d1e6474076366759db86f101778c5f20ccvboxsyncVOID WDBGAPI WinDbgExtensionDllInit(PWINDBG_EXTENSION_APIS64 lpExtensionApis, USHORT MajorVersion, USHORT MinorVersion);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#ifdef __cplusplus
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#endif
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsyncLPEXT_API_VERSION WDBGAPI ExtensionApiVersion()
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return &g_VBoxVWDVersion;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync}
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsyncVOID WDBGAPI CheckVersion()
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return;
044af0d1e6474076366759db86f101778c5f20ccvboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsyncVOID WDBGAPI WinDbgExtensionDllInit(PWINDBG_EXTENSION_APIS64 lpExtensionApis, USHORT MajorVersion, USHORT MinorVersion)
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
044af0d1e6474076366759db86f101778c5f20ccvboxsync ExtensionApis = *lpExtensionApis;
044af0d1e6474076366759db86f101778c5f20ccvboxsync SavedMajorVersion = MajorVersion;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync SavedMinorVersion = MinorVersion;
044af0d1e6474076366759db86f101778c5f20ccvboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsyncDECLARE_API(help)
de6e321f351aa489a6a62bed474390a0056e8093vboxsync{
de6e321f351aa489a6a62bed474390a0056e8093vboxsync dprintf("**** VirtulBox Video Driver debugging extension ****\n"
de6e321f351aa489a6a62bed474390a0056e8093vboxsync " The following commands are supported: \n"
de6e321f351aa489a6a62bed474390a0056e8093vboxsync " !ms - save memory (video data) to clipboard \n"
044af0d1e6474076366759db86f101778c5f20ccvboxsync " usage: !ms <virtual memory address> <width> <height> [bitsPerPixel (default is 32)] [pitch (default is ((width * bpp + 7) >> 3) + 3) & ~3)]\n");
de6e321f351aa489a6a62bed474390a0056e8093vboxsync}
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsyncDECLARE_API(ms)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync{
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ULONG64 u64Mem;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync ULONG64 u64Width;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync ULONG64 u64Height;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync ULONG64 u64Bpp = 32;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync ULONG64 u64NumColors = 3;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync ULONG64 u64Pitch;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync ULONG64 u64DefaultPitch;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync PCSTR pExpr = args;
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /* address */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (!pExpr) { dprintf("address not specified\n"); return; }
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (!GetExpressionEx(pExpr, &u64Mem, &pExpr)) { dprintf("error evaluating address\n"); return; }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (!u64Mem) { dprintf("address value can not be NULL\n"); return; }
044af0d1e6474076366759db86f101778c5f20ccvboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /* width */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (!pExpr) { dprintf("width not specified\n"); return; }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (!GetExpressionEx(pExpr, &u64Width, &pExpr)) { dprintf("error evaluating width\n"); return; }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (!u64Width) { dprintf("width value can not be NULL\n"); return; }
044af0d1e6474076366759db86f101778c5f20ccvboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /* height */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (!pExpr) { dprintf("height not specified\n"); return; }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (!GetExpressionEx(pExpr, &u64Height, &pExpr)) { dprintf("error evaluating height\n"); return; }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (!u64Height) { dprintf("height value can not be NULL\n"); return; }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync#if 0
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (pExpr && GetExpressionEx(pExpr, &u64NumColors, &pExpr))
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (!u64NumColors) { dprintf("Num Colors value can not be NULL\n"); return; }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync#endif
de6e321f351aa489a6a62bed474390a0056e8093vboxsync
de6e321f351aa489a6a62bed474390a0056e8093vboxsync /* bpp */
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (pExpr && GetExpressionEx(pExpr, &u64Bpp, &pExpr))
de6e321f351aa489a6a62bed474390a0056e8093vboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (!u64Bpp) { dprintf("bpp value can not be NULL\n"); return; }
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /* pitch */
044af0d1e6474076366759db86f101778c5f20ccvboxsync u64DefaultPitch = (((((u64Width * u64Bpp) + 7) >> 3) + 3) & ~3ULL);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (pExpr && GetExpressionEx(pExpr, &u64Pitch, &pExpr))
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync if (u64Pitch < u64DefaultPitch) { dprintf("pitch value can not be less than (%d)\n", (UINT)u64DefaultPitch); return; }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync u64Pitch = u64DefaultPitch;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("processing data for address(0x%p), width(%d), height(%d), bpp(%d), pitch(%d)...\n",
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync u64Mem, (UINT)u64Width, (UINT)u64Height, (UINT)u64Bpp, (UINT)u64Pitch);
044af0d1e6474076366759db86f101778c5f20ccvboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ULONG64 cbSize = u64DefaultPitch * u64Height;
044af0d1e6474076366759db86f101778c5f20ccvboxsync PVOID pvBuf = malloc(cbSize);
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (!pvBuf)
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync dprintf("failed to allocate memory buffer of size(%d)\n", (UINT)cbSize);
044af0d1e6474076366759db86f101778c5f20ccvboxsync return;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ULONG uRc = 0;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#if 0
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if(u64DefaultPitch == u64Pitch)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if(0)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#endif
de6e321f351aa489a6a62bed474390a0056e8093vboxsync {
de6e321f351aa489a6a62bed474390a0056e8093vboxsync ULONG cbRead = 0;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("reading the entire memory buffer...\n");
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync uRc = ReadMemory(u64Mem, pvBuf, cbSize, &cbRead);
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync if (!uRc)
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("Failed to read the memory buffer of size(%d)\n", (UINT)cbSize);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else if (cbRead != cbSize)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("the actual number of bytes read(%d) no equal the requested size(%d)\n", (UINT)cbRead, (UINT)cbSize);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync uRc = 0;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ULONG64 u64Offset = u64Mem;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync char* pvcBuf = (char*)pvBuf;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ULONG64 i;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("reading memory by chunks since custom pitch is specified...\n");
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync for (i = 0; i < u64Height; ++i, u64Offset+=u64Pitch, pvcBuf+=u64DefaultPitch)
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync ULONG cbRead = 0;
044af0d1e6474076366759db86f101778c5f20ccvboxsync uRc = ReadMemory(u64Offset, pvcBuf, u64DefaultPitch, &cbRead);
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (!uRc)
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync {
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync dprintf("WARNING!!! Failed to read the memory buffer of size(%d), chunk(%d)\n", (UINT)u64DefaultPitch, (UINT)i);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync dprintf("ignoring this one and the all the rest, using height(%d)\n", (UINT)i);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync u64Height = i;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync uRc = 1;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync break;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync else if (cbRead != u64DefaultPitch)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("WARNING!!! the actual number of bytes read(%d) not equal the requested size(%d), chunk(%d)\n", (UINT)cbRead, (UINT)u64DefaultPitch, (UINT)i);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("ignoring this one and the all the rest, using height(%d)\n", (UINT)i);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync u64Height = i;
044af0d1e6474076366759db86f101778c5f20ccvboxsync break;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (!uRc)
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync dprintf("read memory failed\n");
044af0d1e6474076366759db86f101778c5f20ccvboxsync free(pvBuf);
044af0d1e6474076366759db86f101778c5f20ccvboxsync return;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (!u64Height)
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync dprintf("no data to be processed since height it 0\n");
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync free(pvBuf);
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync return;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync }
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync switch (u64Bpp)
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync case 32:
044af0d1e6474076366759db86f101778c5f20ccvboxsync case 24:
044af0d1e6474076366759db86f101778c5f20ccvboxsync case 16:
044af0d1e6474076366759db86f101778c5f20ccvboxsync#if 0
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (u64NumColors != 3)
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync dprintf("WARNING: unsupported number colors: (%d)\n", (UINT)u64NumColors);
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync#else
044af0d1e6474076366759db86f101778c5f20ccvboxsync u64NumColors = 3;
044af0d1e6474076366759db86f101778c5f20ccvboxsync#endif
044af0d1e6474076366759db86f101778c5f20ccvboxsync break;
044af0d1e6474076366759db86f101778c5f20ccvboxsync case 8:
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#if 1
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync u64NumColors = 1;
044af0d1e6474076366759db86f101778c5f20ccvboxsync#endif
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (u64NumColors == 1)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync ULONG64 cbSize32 = u64DefaultPitch * 4 * u64Height;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PVOID pvBuf32 = malloc(cbSize32);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync if (!pvBuf32)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("ERROR: failed to allocate memory buffer of size(%d)", cbSize32);
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync free(pvBuf);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync return;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync byte* pByteBuf32 = (byte*)pvBuf32;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync byte* pByteBuf = (byte*)pvBuf;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync memset(pvBuf32, 0, cbSize32);
044af0d1e6474076366759db86f101778c5f20ccvboxsync for (UINT i = 0; i < u64Height; ++i)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync for (UINT j = 0; j < u64Width; ++j)
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync pByteBuf32[0] = pByteBuf[0];
044af0d1e6474076366759db86f101778c5f20ccvboxsync pByteBuf32[1] = pByteBuf[0];
044af0d1e6474076366759db86f101778c5f20ccvboxsync pByteBuf32[2] = pByteBuf[0];
044af0d1e6474076366759db86f101778c5f20ccvboxsync pByteBuf32 += 4;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync pByteBuf += 1;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync free(pvBuf);
044af0d1e6474076366759db86f101778c5f20ccvboxsync pvBuf = pvBuf32;
044af0d1e6474076366759db86f101778c5f20ccvboxsync u64DefaultPitch *= 4;
044af0d1e6474076366759db86f101778c5f20ccvboxsync u64Bpp *= 4;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync else
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync dprintf("WARNING: unsupported number colors: (%d)\n", (UINT)u64NumColors);
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync break;
044af0d1e6474076366759db86f101778c5f20ccvboxsync }
044af0d1e6474076366759db86f101778c5f20ccvboxsync BITMAP Bmp = {0};
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync HBITMAP hBmp;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("read memory succeeded..\n");
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Bmp.bmType = 0;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Bmp.bmWidth = (LONG)u64Width;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Bmp.bmHeight = (LONG)u64Height;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Bmp.bmWidthBytes = (LONG)u64DefaultPitch;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Bmp.bmPlanes = 1;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Bmp.bmBitsPixel = (WORD)u64Bpp;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync Bmp.bmBits = (LPVOID)pvBuf;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync hBmp = CreateBitmapIndirect(&Bmp);
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync if (hBmp)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync {
de6e321f351aa489a6a62bed474390a0056e8093vboxsync if (OpenClipboard(GetDesktopWindow()))
2d8870843ff566fee9bd3a6a5942414254106479vboxsync {
a1df400bbe9d64aad400442e56eb637019300a5evboxsync if (EmptyClipboard())
de6e321f351aa489a6a62bed474390a0056e8093vboxsync {
044af0d1e6474076366759db86f101778c5f20ccvboxsync if (SetClipboardData(CF_BITMAP, hBmp))
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("succeeded!! You can now do <ctrl>+v in your favourite image editor\n");
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync DWORD winEr = GetLastError();
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("SetClipboardData failed, err(%d)\n", winEr);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
9d020a0622f95aec3aabaff436a495e88dbbd71avboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync DWORD winEr = GetLastError();
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync dprintf("EmptyClipboard failed, err(%d)\n", winEr);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync CloseClipboard();
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync DWORD winEr = GetLastError();
2d8870843ff566fee9bd3a6a5942414254106479vboxsync dprintf("OpenClipboard failed, err(%d)\n", winEr);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync DeleteObject(hBmp);
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync }
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync else
a1df400bbe9d64aad400442e56eb637019300a5evboxsync {
de6e321f351aa489a6a62bed474390a0056e8093vboxsync DWORD winEr = GetLastError();
de6e321f351aa489a6a62bed474390a0056e8093vboxsync dprintf("CreateBitmapIndirect failed, err(%d)\n", winEr);
de6e321f351aa489a6a62bed474390a0056e8093vboxsync }
de6e321f351aa489a6a62bed474390a0056e8093vboxsync}
a1df400bbe9d64aad400442e56eb637019300a5evboxsync