Created
April 11, 2017 08:57
-
-
Save cosysn/64596fe3f6eb1ec167c0047832295d9e to your computer and use it in GitHub Desktop.
移植 Linux Kernel 的 print_hex_dump 函数到 Windows 驱动中,帮助 dump 二进制数据。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CHAR hex_asc[] = "0123456789abcdef"; | |
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] | |
#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] | |
#define TracePrintEx(Fmt, ...) \ | |
do\ | |
{\ | |
DbgPrintEx(DPFLTR_FASTFAT_ID, DPFLTR_ERROR_LEVEL, Fmt, __VA_ARGS__); \ | |
}while (0) | |
INT32 hex_dump_to_buffer(PVOID buf, INT32 len, INT32 rowsize, INT32 groupsize, | |
PCHAR linebuf, INT32 linebuflen, BOOLEAN ascii) | |
{ | |
const PUINT8 ptr = (PUINT8)buf; | |
INT32 ngroups = 0;; | |
UINT8 ch; | |
INT32 j, lx = 0; | |
INT32 ascii_column = 0; | |
INT32 ret = 0; | |
if (rowsize != 16 && rowsize != 32) | |
rowsize = 16; | |
if (len > rowsize) /* limit to one line at a time */ | |
len = rowsize; | |
if ((len % groupsize) != 0) /* no mixed size output */ | |
groupsize = 1; | |
ngroups = len / groupsize; | |
ascii_column = rowsize * 2 + rowsize / groupsize + 1; | |
if (!linebuflen) | |
goto overflow1; | |
if (!len) | |
goto nil; | |
if (groupsize == 8) { | |
PUINT64 ptr8 = (PUINT64)buf; | |
for (j = 0; j < ngroups; j++) { | |
ret = RtlStringCbPrintfA(linebuf + lx, linebuflen - lx, | |
"%s%16.16llx", j ? " " : "", | |
(PUINT64)(ptr8 + j)); | |
if (ret >= linebuflen - lx) | |
goto overflow1; | |
lx += ret; | |
} | |
} | |
else if (groupsize == 4) { | |
PUINT32 ptr4 = (PUINT32)buf; | |
for (j = 0; j < ngroups; j++) { | |
ret = RtlStringCbPrintfA(linebuf + lx, linebuflen - lx, | |
"%s%8.8x", j ? " " : "", | |
(PUINT32)(ptr4 + j)); | |
if (ret >= linebuflen - lx) | |
goto overflow1; | |
lx += ret; | |
} | |
} | |
else if (groupsize == 2) { | |
PUINT16 ptr2 = (PUINT16)buf; | |
for (j = 0; j < ngroups; j++) { | |
ret = RtlStringCbPrintfA(linebuf + lx, linebuflen - lx, | |
"%s%4.4x", j ? " " : "", | |
(PUINT16)(ptr2 + j)); | |
if (ret >= linebuflen - lx) | |
goto overflow1; | |
lx += ret; | |
} | |
} | |
else { | |
for (j = 0; j < len; j++) { | |
if (linebuflen < lx + 2) | |
goto overflow2; | |
ch = ptr[j]; | |
linebuf[lx++] = hex_asc_hi(ch); | |
if (linebuflen < lx + 2) | |
goto overflow2; | |
linebuf[lx++] = hex_asc_lo(ch); | |
if (linebuflen < lx + 2) | |
goto overflow2; | |
linebuf[lx++] = ' '; | |
} | |
if (j) | |
lx--; | |
} | |
if (!ascii) | |
goto nil; | |
while (lx < ascii_column) { | |
if (linebuflen < lx + 2) | |
goto overflow2; | |
linebuf[lx++] = ' '; | |
} | |
for (j = 0; j < len; j++) { | |
if (linebuflen < lx + 2) | |
goto overflow2; | |
ch = ptr[j]; | |
linebuf[lx++] = ch; | |
} | |
nil: | |
linebuf[lx] = '\0'; | |
return lx; | |
overflow2: | |
linebuf[lx++] = '\0'; | |
overflow1: | |
return ascii ? ascii_column + len : (groupsize * 2 + 1) * ngroups - 1; | |
} | |
void TracePrintHexDump(PVOID pBuffer, INT32 BufferLen) | |
{ | |
PUINT8 ptr = (PUINT8)pBuffer; | |
INT32 i, linelen, remaining = BufferLen; | |
CHAR linebuf[32 * 3 + 2 + 32 + 1]; | |
INT32 rowsize = 32; | |
INT32 groupsize = 1; | |
BOOLEAN ascii = TRUE; | |
if (rowsize != 16 && rowsize != 32) | |
rowsize = 16; | |
for (i = 0; i < BufferLen; i += rowsize) { | |
linelen = min(remaining, rowsize); | |
remaining -= rowsize; | |
hex_dump_to_buffer((PVOID)(ptr + i), linelen, rowsize, groupsize, | |
linebuf, (INT32)sizeof(linebuf), ascii); | |
TracePrintEx("%08x: %s\n", i, linebuf); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://lxr.free-electrons.com/source/lib/hexdump.c#L108