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

📄 hexview.c

📁 直接IRP操作文件的实现问题
💻 C
📖 第 1 页 / 共 3 页
字号:
}

VOID HV_OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	PHEXVIEW pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
	int i;
	NMHDR n;

	if (pHex->NoCursor == TRUE)
	{
		switch ((TCHAR)wParam)
		{
		case VK_UP:
			if (pHex->PageOffset > 0)
				pHex->PageOffset -= pHex->LineWidth;
			break;
		case VK_DOWN:
			if (pHex->PageLength >= pHex->LineWidth)
				pHex->PageOffset += pHex->LineWidth;
			break;
		}
		RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
	}
	else
	{
		switch ((TCHAR)wParam)
		{
		case VK_UP:
			i = HV_MoveCursor(pHex, 0, -1);
			break;
		case VK_DOWN:
			i = HV_MoveCursor(pHex, 0, 1);
			break;
		case VK_LEFT:
			i = HV_MoveCursor(pHex, -1, 0);
			break;
		case VK_RIGHT:
			i = HV_MoveCursor(pHex, 1, 0);
			break;
		default:
			return;
		}

		pHex->SelEnd = -1;
		HV_UpdatePage(hWnd, i);

		n.code = HV_EN_SELCHANGE;
		n.idFrom = GetDlgCtrlID(hWnd);
		n.hwndFrom = hWnd;
		SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
	}
}

VOID HV_MouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	PHEXVIEW pHex;
	ULONG i;
	INT TopPos, BottomPos;
	NMHDR n;

	if (wParam & MK_LBUTTON)
	{
		pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
		TopPos = pHex->CharHeight;
		BottomPos = (pHex->PageMaxLength / pHex->LineWidth) * pHex->CharHeight;

		if ((short)HIWORD(lParam) < TopPos)
		{
			HV_OnVscroll(hWnd, SB_LINEUP, 0);
			//SendMessage(hWnd, WM_MOUSEMOVE, wParam, lParam);
		}

		if ((short)HIWORD(lParam) >= BottomPos)
		{
			HV_OnVscroll(hWnd, SB_LINEDOWN, 0);
			//SendMessage(hWnd, WM_MOUSEMOVE, wParam, lParam);
		}

		i = HV_GetCurrentCursor(pHex, LOWORD(lParam), HIWORD(lParam), NULL);
		pHex->SelEnd = i;
		pHex->Cursor = i;
		RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);

		n.code = HV_EN_SELCHANGE;
		n.idFrom = GetDlgCtrlID(hWnd);
		n.hwndFrom = hWnd;
		SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
	}
}

VOID HV_ResetSize(HWND hWnd)
{
	HDC hDC;
	HFONT hFont, hOldFont;
	SIZE charSize;
	RECT rect;
	UINT nWndHeight;
	PHEXVIEW pHex;
	SCROLLINFO si;

	pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
	hFont = CreateFont(-12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New");
	hDC = GetDC(hWnd);
	hOldFont = SelectObject(hDC, hFont);

	GetTextExtentPoint32(hDC, "0", 1, &charSize);
	pHex->CharWidth = charSize.cx;
	pHex->CharHeight = charSize.cy;

	SelectObject(hDC, hOldFont);
	DeleteObject(hFont);
	ReleaseDC(hWnd, hDC);

	GetClientRect(hWnd, &rect);
	nWndHeight = rect.bottom - rect.top;

	pHex->PageMaxLength = (nWndHeight / pHex->CharHeight - 1) * pHex->LineWidth;
	pHex->PageLength = MIN(pHex->Length - pHex->PageOffset, pHex->PageMaxLength);

	si.cbSize = sizeof(SCROLLINFO);
	si.fMask = SIF_ALL;
	si.nMin = 0;
	si.nMax = pHex->Length / pHex->LineWidth + 
		(pHex->Length % pHex->LineWidth == 0 ? 0 : 1);
	si.nPage = pHex->PageMaxLength / pHex->LineWidth + 1;
	si.nPos = 0;
	SetScrollInfo(hWnd, SB_VERT, &si, TRUE);

	if (pHex->Length > pHex->PageMaxLength)
	{
		EnableScrollBar(hWnd, SB_VERT, ESB_ENABLE_BOTH);
	}
	else
	{
		EnableScrollBar(hWnd, SB_VERT, ESB_DISABLE_BOTH);
	}
}

int HV_FindText(HWND hWnd, PHV_FIND hv_find)
{
	PBYTE p1, p2, pp;
	DWORD i, n, count;
	PHEXVIEW pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
	NMHDR nm;

	if (hv_find->nLen > 0x8000)
		return -1;

	if (pHex->Length == 0)
		return -1;

	if (hv_find->dwFlags & ~HV_FIND_MATCHCASE)
	{
		n = MIN(pHex->Length, 0x10000);

		p1 = VirtualAlloc(	NULL,
							n + hv_find->nLen,
							MEM_COMMIT,
							PAGE_READWRITE);

		if (p1 == NULL)
			return -1;

		p2 = p1 + n;
		pp = hv_find->pMem;

		for (i = 0; i < hv_find->nLen; i++)
		{
			if (pp[i] >= 'a' && pp[i] <= 'z')
				p2[i] = pp[i] - 'a' + 'A';
			else
				p2[i] = pp[i];
		}
	}
	else
	{
		n = MIN(pHex->Length, 0x10000);

		p1 = VirtualAlloc(	NULL,
							n,
							MEM_COMMIT,
							PAGE_READWRITE);

		if (p1 == NULL)
			return -1;

		p2 = hv_find->pMem;
	}


	for (count = hv_find->cpMin;;)
	{
		n = MIN(pHex->Length - count, 0x10000);
		HV_GetModifyData(&pHex->hv_modl, count, p1, n);

		if (hv_find->dwFlags & ~HV_FIND_MATCHCASE)
		{
			for (i = 0; i < n; i++)
			{
				if (p1[i] >= 'a' && p1[i] <= 'z')
					p1[i] -= 'a' - 'A';
			}
		}

		pp = HV_MemSearchR(p1, n, p2, hv_find->nLen);

		if (pp != NULL)
		{
			n = pp - p1 + count;
			pHex->SelStart = n;
			pHex->SelEnd = n + hv_find->nLen - 1;
			pHex->Cursor = n;

			if (n >= pHex->PageOffset + pHex->PageLength)
			{
				n /= pHex->LineWidth;
				n -= pHex->PageMaxLength / pHex->LineWidth - 1;
				pHex->PageOffset = n * pHex->LineWidth;
				pHex->PageLength = MIN(pHex->PageMaxLength, pHex->Length - pHex->PageOffset);
				HV_UpdatePage(hWnd, n);
			}
			else if (n < pHex->PageOffset)
			{
				n /= pHex->LineWidth;
				pHex->PageOffset = n * pHex->LineWidth;
				pHex->PageLength = MIN(pHex->PageMaxLength, pHex->Length - pHex->PageOffset);
				HV_UpdatePage(hWnd, n);
			}

			nm.code = HV_EN_SELCHANGE;
			nm.idFrom = GetDlgCtrlID(hWnd);
			nm.hwndFrom = hWnd;
			SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&nm);
			break;
		}

		if (pHex->Length - i > 0x10000)
		{
			i += 0x10000 - hv_find->nLen;
		}
		else
			break;
	}

	VirtualFree(p1, 0, MEM_RELEASE);

	return 0;
}

LRESULT CALLBACK HV_HexViewProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	PHEXVIEW p;
	HGLOBAL hGlobal;
	PBYTE pGlobal, pSource;
	LONG i, SelLength, MemSize;
	NMHDR n;

	switch (uMsg)
	{
	case WM_MOUSEMOVE:
		HV_MouseMove(hWnd, wParam, lParam);
		break;

	case WM_LBUTTONDOWN:
		SetCapture(hWnd);
		SetFocus(hWnd);
		HV_LButtonDown(hWnd, wParam, lParam);
		break;

	case WM_LBUTTONUP:
		ReleaseCapture();
		break;

	case WM_VSCROLL:
		HV_OnVscroll(hWnd, wParam, lParam);
		break;

	case WM_MOUSEWHEEL:
		if ((short)HIWORD(wParam) > 0)
		{
			HV_OnVscroll(hWnd, SB_LINEUP, 0);
		}
		else
		{
			HV_OnVscroll(hWnd, SB_LINEDOWN, 0);
		}
		break;

	case WM_PAINT:
		HV_OnPaint(hWnd);
		break;

	case WM_CHAR:
		HV_OnChar(hWnd, wParam);
		break;

	case WM_KEYDOWN:
		HV_OnKeyDown(hWnd, wParam, lParam);
		break;

	case WM_SETFOCUS:
		SetTimer(hWnd, WM_TIMER, 500, HV_TimerProc);
		break;

	case WM_KILLFOCUS:
		KillTimer(hWnd, WM_TIMER);
		RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
		break;

	case WM_SIZE:
		HV_ResetSize(hWnd);
		break;

	case HV_SETHANDLE:
		if ((ULONG)wParam < 512 * 1024 * 1024)
		{
			p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
			p->Buffer = (LPSTR)lParam;
			p->Length = (ULONG)wParam;
			p->PageOffset = 0;
			p->SelEnd = -1;
			p->Cursor = 0;
			p->EditMode = EM_HEX_HIGH;
			HV_ResetModifyLog(&p->hv_modl, p->Buffer, p->Length);
			HV_AddModifyLog(&p->hv_modl, 39, 3, "324");
			HV_AddModifyLog(&p->hv_modl, 41, 7, "abcdefg");
			HV_AddModifyLog(&p->hv_modl, 22, 14, "happy new year");
			p->hv_modl.nLog = 0;
			HV_ResetSize(hWnd);
			RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);

			n.code = HV_EN_CHANGE;
			n.idFrom = GetDlgCtrlID(hWnd);
			n.hwndFrom = hWnd;
			SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
			n.code = HV_EN_SELCHANGE;
			SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
		}
		break;

	case HV_CANUNDO:
		return HV_LogUndo(hWnd, TRUE);

	case HV_CANREDO:
		return HV_LogRedo(hWnd, TRUE);

	case HV_UNDO:
		return HV_LogUndo(hWnd, FALSE);

	case HV_REDO:
		return HV_LogRedo(hWnd, FALSE);

	case HV_GETSEL:
		p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
		*(DWORD *)wParam = p->SelStart;
		*(DWORD *)lParam = p->SelEnd;
		break;

	case HV_SETSEL:
		p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
		p->SelStart = (DWORD)wParam;
		p->SelEnd = (DWORD)lParam;
		RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);

		n.code = HV_EN_SELCHANGE;
		n.idFrom = GetDlgCtrlID(hWnd);
		n.hwndFrom = hWnd;
		SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
		break;

	case HV_SELALL:
		p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
		p->SelStart = 0;
		p->SelEnd = p->Length;
		p->Cursor = (p->Length << 1) - 1;
		RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);

		n.code = HV_EN_SELCHANGE;
		n.idFrom = GetDlgCtrlID(hWnd);
		n.hwndFrom = hWnd;
		SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
		break;

	case HV_COPY:
		p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
		SelLength = p->SelEnd - p->SelStart;
		SelLength = MAX(SelLength, -SelLength) + 1;

		hGlobal = GlobalAlloc(GHND | GMEM_SHARE, SelLength + 1);
		if (hGlobal == NULL)
			break;
		pGlobal = GlobalLock(hGlobal);
		pSource = p->Buffer + MIN(p->SelEnd, p->SelStart);
		strncpy(pGlobal, pSource, SelLength);
		GlobalUnlock(hGlobal);

		OpenClipboard(hWnd);
		EmptyClipboard();
		SetClipboardData(CF_TEXT, hGlobal);
		CloseClipboard();
		break;

	case HV_COPYHEX:
		p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
		SelLength = p->SelEnd - p->SelStart;
		SelLength = MAX(SelLength, -SelLength) + 1;
		MemSize = SelLength * 3 + SelLength / 16;

		hGlobal = GlobalAlloc(GHND | GMEM_SHARE, MemSize + 1);
		if (hGlobal == NULL)
			break;
		pGlobal = GlobalLock(hGlobal);
		pSource = p->Buffer + MIN(p->SelEnd, p->SelStart);

		for (i = 0; i < SelLength;)
		{
			*pGlobal++ = "0123456789ABCDEF"[pSource[i] >> 4];
			*pGlobal++ = "0123456789ABCDEF"[pSource[i] & 15];
			*pGlobal++ = ' ';

			if (!(++i & 15))
			{
				*(pGlobal - 1) = '\r';
				*pGlobal++ = '\n';
			}
		}
		*pGlobal = '\0';
		GlobalUnlock(hGlobal);

		OpenClipboard(hWnd);
		EmptyClipboard();
		SetClipboardData(CF_TEXT, hGlobal);
		CloseClipboard();
		break;

	case HV_SETCOLOR:
		if ((DWORD)wParam < 10)
		{
			p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
			p->color[(DWORD)wParam] = lParam;
			RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
		}
		break;

	case HV_APPLYMODIFY:
		p = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
		HV_ApplyModifyLog(&p->hv_modl, (PBYTE)lParam);
		if ((PBYTE)lParam != NULL) p->Buffer = (PBYTE)lParam;
		RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
		break;

	case HV_FINDTEXT:
		HV_FindText(hWnd, (PHV_FIND)lParam);
		break;

	case WM_CREATE:
		p = xmalloc(sizeof(HEXVIEW));
		p->NoCursor = FALSE;
		p->ReadOnly = TRUE;
		p->BaseAddress = 0;
		p->PageOffset = 0;
		p->Length = 0;
		p->Buffer = NULL;
		p->AddressWidth = 4;
		p->LineWidth = 16;
		p->SelStart = 0;
		p->SelEnd = -1;
		p->color[HV_COLOR_BG0] = RGB(255, 255, 255);
		p->color[HV_COLOR_BG1] = RGB(192, 192, 192);
		p->color[HV_COLOR_ADDR] = RGB(0, 0, 255);
		p->color[HV_COLOR_HEX] = RGB(0, 0, 0);
		p->color[HV_COLOR_TEXT] = RGB(0, 0, 0);
		p->color[HV_COLOR_MODIFY] = RGB(255, 0, 0);
		SetWindowLong(hWnd, GWL_HEXINFO, (LONG)p);
		HV_ResetSize(hWnd);
		HV_InitModifyLog(&p->hv_modl, p->Buffer, p->Length);
		break;

	case WM_DESTROY:
		p = (void *)GetWindowLong(hWnd, GWL_HEXINFO);
		HV_FreeModifyLog(&p->hv_modl);
		xfree(p);
		break;

	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}

	return 0;
}

BOOL InitHexViewClass(VOID)
{
	LPSTR lpClass = "HexView";
	WNDCLASS wc;
	HINSTANCE hInstance;

	hInstance = GetModuleHandle(NULL);

	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
	wc.lpfnWndProc		= (WNDPROC)HV_HexViewProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= sizeof(void *);
	wc.hInstance		= hInstance;
	wc.hIcon			= NULL;
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName		= NULL;
	wc.lpszClassName	= lpClass;

	if (!RegisterClass(&wc))
	{
		if (!GetClassInfo(hInstance, lpClass, &wc))
			return FALSE;
		if (wc.lpfnWndProc != (WNDPROC)HV_HexViewProc)
			return FALSE;
	}

	return TRUE;
}

⌨️ 快捷键说明

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