⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcdtable.cpp

📁 Windows 图形编程 书籍
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------------//
//              Windows Graphics Programming: Win32 GDI and DirectDraw               //
//                             ISBN  0-13-086985-6                                   //
//                                                                                   //
//  Written            by  Yuan, Feng                             www.fengyuan.com   //
//  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
//  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
//                                                                                   //
//  FileName   : dcdtable.cpp					                                     //
//  Description: Decode GDI handle table, Chapter 3                                  //
//  Version    : 1.00.000, May 31, 2000                                              //
//-----------------------------------------------------------------------------------//

#define STRICT
#include <windows.h>
#include <assert.h>
#include <stdio.h>
#include <tchar.h>
#include <winioctl.h>

#include "dialog.h"
#include "gditable.h"
#include "fxstring.h"

#include "resource.h"
#include "handles.h"
#include "creator.h"
#include "dcdtable.h"
#include "device.h"
#include "MemDump.h"
#include "..\\Periscope\Periscope.h"

#define _WIN32_WINNT 0x0500

#include "dcattr.h"

KDecodeTablePage::KDecodeTablePage()
{
	m_hInst = NULL;
}


class KTemp
{
public:
	KString<512> mess;

	HGDIOBJ Select(HDC hDC, HGDIOBJ hHandle);
};


HGDIOBJ KTemp::Select(HDC hDC, HGDIOBJ hHandle)
{
	HGDIOBJ hRslt;

	if ( GetObjectType(hHandle) == OBJ_PAL )
	{
		hRslt = SelectPalette(hDC, (HPALETTE) hHandle, FALSE);
		mess.Append("SelectPalette() returns 0x%x", (unsigned) hRslt);
	}
	else
	{
		hRslt = SelectObject(hDC, hHandle);
		mess.Append("SelectObject() returns 0x%x", (unsigned) hRslt);
	}
	
//	assert(hRslt);
	return hRslt;
}


void KDecodeTablePage::TestnCount(int obj, HDC hDC1, HDC hDC2, bool testdelete)
{
	KTemp temp;
	BOOL rslt;

	// create an object
	HGDIOBJ hHandle = CreateObject(obj, hDC1);

	assert(hHandle);

	temp.mess.Append("Create...() returns 0x%x", (unsigned) hHandle);
	temp.mess.Append(", nCount=%d\r\n", m_GDITable.GetCount(hHandle));

	// select into a DC1
	HGDIOBJ hOld1 = temp.Select(hDC1, hHandle); 
	temp.mess.Append(" nCount=%d\r\n", m_GDITable.GetCount(hHandle));

	// select into a DC2
	HGDIOBJ hOld2 = temp.Select(hDC2, hHandle); 
	temp.mess.Append(" nCount=%d\r\n", m_GDITable.GetCount(hHandle));

	if ( testdelete )
	{
		rslt = DeleteObject(hHandle);
		temp.mess.Append("DeleteObject() returns %d\n", rslt);
	}
	
	// deselect from a DC2
	temp.mess.Append("(De)");
	temp.Select(hDC2, hOld2);
	temp.mess.Append(", nCount=%d\r\n", m_GDITable.GetCount(hHandle));

	// deselect from a DC1
	temp.mess.Append("(De)");
	temp.Select(hDC1, hOld1);
	temp.mess.Append(", nCount=%d\r\n", m_GDITable.GetCount(hHandle));

	rslt = DeleteObject(hHandle);
	temp.mess.Append("DeleteObject() returns %d", rslt);
	
	MessageBox(NULL, temp.mess, Commands[obj], MB_OK);
}


void KDecodeTablePage::TestnCount(bool testdelete)
{
	HDC hDC = GetDC(m_hWnd);
	HDC hMemDC1 = CreateCompatibleDC(hDC);
	HDC hMemDC2 = CreateCompatibleDC(hDC);

	TestnCount(obj_CreateSolidBrush,   hMemDC1, hMemDC2, testdelete);
	TestnCount(obj_CreatePen,		   hMemDC1, hMemDC2, testdelete);
	TestnCount(obj_CreateBitmap,	   hMemDC1, hMemDC2, testdelete);
	TestnCount(obj_CreateFont,		   hMemDC1, hMemDC2, testdelete);
	TestnCount(obj_CreatePalette,      hMemDC1, hMemDC2, testdelete);

	DeleteDC(hMemDC1);
	DeleteDC(hMemDC2);

	ReleaseDC(m_hWnd, hDC);
}


// check reuse of rectangle region
void KDecodeTablePage::TestpUserRectRegion(void)
{
	KString<1024> mess;

	for (int i=0; i<8; i++)
	{
		HRGN hRgn = CreateRectRgn(i, i, i+10, i+10);

		mess.Append("%d  ", i+1);
		mess.Append("%08lx\t",     (unsigned) hRgn);
		mess.Append("pKernel=%x\t", (unsigned) m_GDITable[hRgn].pKernel);
		mess.Append("pUser=%x  ",    (unsigned) m_GDITable[hRgn].pUser);

		RECT * pRect = (RECT *) ((unsigned char *)m_GDITable[hRgn].pUser+8);
		mess.Append("[%d, ", pRect->left);
        mess.Append("%d, ", pRect->top);
        mess.Append("%d, ", pRect->right);
        mess.Append("%d]\r\n", pRect->bottom);

		KString<128> t;
		t.Append("%x, ", (unsigned) m_GDITable[hRgn].pKernel);
		t.Append("%x, ",            m_GDITable[hRgn].nUpper);
		t.Append("%x ",  (unsigned) m_GDITable[hRgn].pUser);

		DeleteObject(hRgn);

		t.Append(" -> delete -> ");
		t.Append("%x, ", (unsigned) m_GDITable[hRgn].pKernel);
		t.Append("%x, ",            m_GDITable[hRgn].nUpper);
		t.Append("%x ",  (unsigned) m_GDITable[hRgn].pUser);

		OutputDebugString(t);
		OutputDebugString("\n");
	}

	MessageBox(NULL, mess, "CreateRectRgn", MB_OK);
}


void KDecodeTablePage::TestpUserSolidBrush(void)
{
	KString<1024> mess;

	for (int i=0; i<8; i++)
	{
		HGDIOBJ hBrush = CreateSolidBrush(RGB(i*32, i*32, i*32));

		mess.Append("%d  ", i+1);
		mess.Append("%08lx\t",     (unsigned) hBrush);
		mess.Append("pKernel=%x\t", (unsigned) m_GDITable[hBrush].pKernel);
		mess.Append("pUser=%x  ",    (unsigned) m_GDITable[hBrush].pUser);

		LOGBRUSH * pLogBrush = (LOGBRUSH *) m_GDITable[hBrush].pUser;
		mess.Append("color=%x\r\n", pLogBrush->lbColor);

	    OutputDebugString(mess);

        KString<128> t;
		t.Append("%x, ", (unsigned) m_GDITable[hBrush].pKernel);
		t.Append("%x, ",            m_GDITable[hBrush].nUpper);
		t.Append("%x ",  (unsigned) m_GDITable[hBrush].pUser);

		DeleteObject(hBrush);

		t.Append(" -> delete -> ");
		t.Append("%x, ", (unsigned) m_GDITable[hBrush].pKernel);
		t.Append("%x, ",            m_GDITable[hBrush].nUpper);
		t.Append("%x ",  (unsigned) m_GDITable[hBrush].pUser);

	//	OutputDebugString(t);
	//	OutputDebugString("\n");
	}

	MessageBox(NULL, mess, "CreateSolidBrush", MB_OK);
}


BOOL KDecodeTablePage::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	HWND hExp = GetDlgItem(hWnd, IDC_EXPERIMENT);

    switch (uMsg)
    {
	    case WM_INITDIALOG:
			m_hWnd = hWnd;
            
			m_Objects.FromDlgItem(hWnd, IDC_GDITABLE);
			
			m_Objects.AddColumn(0, 50, "Index");
			m_Objects.AddColumn(1, 90, "pKernel");
		
			m_Objects.AddColumn(2, 60, "nCount");
        	
			m_Objects.AddColumn(3, 60, "nProc");
		    
			m_Objects.AddColumn(4, 60, "nUpper");
			m_Objects.AddColumn(5, 60, "nType");

            m_Objects.AddColumn(6, 90, "pUser");

			SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("Query GDI Table"));
			SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("nCount: SelectObject"));
			SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("nCount: DeleteObject"));
			SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("pUser: CreateSolidBrush"));
            SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("pUser: CreateRectRgn"));
            SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("Dump GDI Table"));
			SendMessage(hExp, CB_SETCURSEL, 0, 0);
			return TRUE;
		
		case WM_COMMAND:
			if ( LOWORD(wParam) == IDC_GO )
			switch ( SendMessage(hExp, CB_GETCURSEL, 0, 0) )
			{
				case 0: Query();		   return TRUE;
				case 1: TestnCount(false); return TRUE;
				case 2: TestnCount(true);  return TRUE;
				case 3: TestpUserSolidBrush(); return TRUE;
                case 4: TestpUserRectRegion(); return TRUE;
                case 5: DumpGDITable(); return TRUE;
			}
			break;

		case WM_NOTIFY:
			if (wParam == IDC_GDITABLE)
			{
				NM_LISTVIEW * pInfo = (NM_LISTVIEW *) lParam;
				
				if ( (pInfo->hdr.code == NM_CLICK) && (pInfo->iItem != -1) )  
				{
					TCHAR sIndex[16];
					unsigned nIndex;

					m_Objects.GetItemText(pInfo->iItem, 0, sIndex, sizeof(sIndex));
					sscanf(sIndex, "%x", & nIndex);

					ShowDetails(nIndex);
					return TRUE;
				}
				else if ( (pInfo->hdr.code == NM_DBLCLK) && (pInfo->iItem != -1) )  
				{
					TCHAR sIndex[16];
					unsigned nIndex;

					m_Objects.GetItemText(pInfo->iItem, 0, sIndex, sizeof(sIndex));
					sscanf(sIndex, "%x", & nIndex);

				//	HDC hDC = GetDC(NULL);
				//	Modify((unsigned) hDC & 0x3FFF);
				//	ReleaseDC(NULL, hDC);

					Modify(nIndex);
					return TRUE;
				}
	
			}

			break;

		case WM_DESTROY:
			m_Objects.DeleteAll();
			break;
    }
    
    return FALSE;
}


void KDecodeTablePage::Query(void)
{
	m_Objects.DeleteAll();

	DWORD nProcId;

	// determine if user is interested in single process or all processes
	if ( SendDlgItemMessage(m_hWnd, IDC_PROCESSONLY, BM_GETCHECK, 0, 0) == BST_CHECKED ) 
		nProcId = GetCurrentProcessId();
	else
		nProcId = 0;

	for (int i=0; i<=0x3FFF; i++)
	{
		GDITableCell cell = m_GDITable[i];

		if ( (nProcId == 0) || (nProcId==m_GDITable.GetProcess(i)) ) // process matches
		if ( (unsigned) cell.pKernel >= 0x80000000 )	  // valid pointer to kernel address space
		{
			KString<64> s;

			m_Objects.AddItem(0, s.Format("%4x",  i));
			m_Objects.AddItem(1, s.Format("%8x",  (unsigned) cell.pKernel));
			m_Objects.AddItem(2, s.Format("%x",   m_GDITable.GetCount(i)));
			m_Objects.AddItem(3, s.Format("%x",   m_GDITable.GetProcess(i)));
			m_Objects.AddItem(4, s.Format("%04x", cell.nUpper));
			m_Objects.AddItem(5, s.Format("%04x", cell.nType));
			m_Objects.AddItem(6, s.Format("%x",   (unsigned) cell.pUser));
		}
	}
}


const char * GDIObjectTypeName(HGDIOBJ obj)
{
    static char rslt[32];

    switch ( HIWORD(obj) & 0x7F )
    {
        case 0x01: return "dc";
        case 0x04: return "region";
        case 0x05: return "bitmap";
        case 0x08: return "palette";
        case 0x0a: return "font";
        case 0x10: return "brush";
        case 0x21: return "enhmetafile";
        case 0x30: return "pen";
        case 0x50: return "extpen";
    
        default:   
            wsprintfA(rslt, "unknown(%xh)", HIWORD(obj) & 0x7F);
            return rslt;
    }
}


class KPeriscopeClient : public KDevice
{
public:
    KPeriscopeClient(const TCHAR * DeviceName) : KDevice(DeviceName)
    {
    }

    bool Read(void * dst, const void * src, unsigned len);
};


bool KPeriscopeClient::Read(void * dst, const void * src, unsigned len)
{
    unsigned      cmd[2] = { (unsigned) src, len };
    unsigned long dwRead;
   
    return IoControl(IOCTL_PERISCOPE, cmd, sizeof(cmd), dst, len, &dwRead) && (dwRead==len);
}


void KDecodeTablePage::DumpGDITable(void)
{
    bool pagetouched[16*256]; // 16 Mb in pages
    char temp[MAX_PATH];
    KMemDump  memdump;
        
    memset(pagetouched, 0, sizeof(pagetouched));

    memdump.OpenDump();
        
	for (int i=0; i<=0x3FFF; i++)
	{
		GDITableCell cell = m_GDITable[i];

		if ( (unsigned) cell.pKernel >= 0x80000000 )
		{
            wsprintf(temp, "%4x %8x %8x %s", i, cell.pKernel, cell.pUser, 
                GDIObjectTypeName((HGDIOBJ) MAKELONG(i, cell.nUpper)));
            memdump.Writeln(temp);

            unsigned addr = (unsigned) cell.pKernel;

            if ( (addr>>24)==0xE1 )
                pagetouched[(addr & 0xFFFFFF)>>12] = true;
		}
	}
    memdump.Newline();

    KPeriscopeClient scope("PeriScope");
    
    if ( scope.Load("c:\\periscope.sys")==ERROR_SUCCESS )
    {
        unsigned char buf[4096];

        for (i=0; i<4096; i++)
            if ( pagetouched[i] )
            {
                unsigned addr = 0xE1000000 + i * 4096;
                scope.Read(buf, (void *) addr, sizeof(buf));

                memdump.Dump(buf, addr - (unsigned)buf, 4096, sizeof(unsigned long));
                memdump.Newline();
            }
        
        memdump.CloseDump();
        
        scope.Close();
    }
    else
        MessageBox(NULL, "Unable to load periscope", NULL, MB_OK);
}


const LPCTSTR DCProperty[] =
{
	TEXT("GetBkColor/SetBkColor"),
	TEXT("GetBkMode/SetBkMode"),
	TEXT("GetPolyFillMode/SetPolyFillMode"),
	TEXT("GetRop2/SetRop2"),
	TEXT("GetStretchBltMode/SetStretchBltMode"),
	TEXT("GetTextColor/SetTextColor"),
	TEXT("GetMapMode/SetMapMode"),
	TEXT("GetViewportOrg/SetViewportOrg"),
	TEXT("GetViewportExt/SetViewportExt"),
	TEXT("GetWindowOrg/SetWindowOrg"),
	TEXT("GetWindowExt/SetWindowExt"),
	TEXT("GetClipBox/SetClipBox"),
	TEXT("GetTextAlign/SetTxtAlign"),
	TEXT("GetTextJustification/SetTextJustification"),
	TEXT("GetTextCharacterExtra/SetTextCharacterExtra"),
	TEXT("GetAspectRatioFilterEx/SetMapperFlags")
};
	

#define Cap(name) DeviceCap(#name, name)

class KDecodeDC
{
	unsigned * m_addr;
	unsigned buffer[sizeof(DCAttr)/sizeof(unsigned)];
	HDC		   m_hDC;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -