📄 format.c
字号:
//**********************************************************************
//
// Filename: format.c
//
// Description: This file contains simple formatted output string
// support for the boot loader.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to
// use this source code. For a copy of the EULA, please see the
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//
//**********************************************************************
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the EULA.RTF on your
// install media.
//
/*
* Module Name:
* format.c
*
* Abstract:
* This file contains simple formatted output string support for the
* boot loader.
*
* Notes:
* supported, with no frills: x d s u X, H, and B
* backslash n is converted to backslash n backslash r.
*
* X is equivalent to 08x; B, 02x; and H, 04x in printf format.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
* All Rights Reserved
*/
#include <windows.h>
#include <stdarg.h>
#include <nkintr.h>
//
// Functional Prototypes
//
static void pOutputByte(unsigned char c);
static void pOutputNumHex(unsigned long n,long depth);
static void pOutputNumDecimal(unsigned long n);
static void OutputString(const unsigned char *s);
char *szSprintf = 0;
/**********************************************************************/
//
// @func void | EdbgOutPutDebugString | Simple formatted output
// string routine
//
// @rdesc none
//
// @parm const unsigned char * | sz,... |
// Format String:
//
// @flag Format string | type
// @flag u | unsigned
// @flag d | int
// @flag c | char
// @flag s | string
// @flag x | 4-bit hex number
// @flag B | 8-bit hex number
// @flag H | 16-bit hex number
// @flag X | 32-bit hex number
//
// @comm
// Same as FormatString, but output to serial port instead of buffer.
//
void EdbgOutputDebugString(const unsigned char *sz, ...)
{
unsigned char c;
va_list vl;
va_start(vl, sz);
while (*sz)
{
c = *sz++;
switch (c)
{
case (unsigned char)'%':
c = *sz++;
switch (c)
{
case 'x':
pOutputNumHex(va_arg(vl, unsigned long), 0);
break;
case 'B':
pOutputNumHex(va_arg(vl, unsigned long), 2);
break;
case 'H':
pOutputNumHex(va_arg(vl, unsigned long), 4);
break;
case 'X':
pOutputNumHex(va_arg(vl, unsigned long), 8);
break;
case 'd':
{
long l;
l = va_arg(vl, long);
if (l < 0)
{
pOutputByte('-');
l = -l;
}
pOutputNumDecimal((unsigned long)l);
}
break;
case 'u':
pOutputNumDecimal(va_arg(vl, unsigned long));
break;
case 'a':
case 's':
OutputString(va_arg(vl, char *));
break;
case '%':
pOutputByte('%');
break;
case 'c':
c = va_arg(vl, unsigned char);
pOutputByte(c);
break;
default:
pOutputByte(' ');
break;
}
break;
case '\n':
pOutputByte('\r');
// fall through
default:
pOutputByte(c);
}
}
va_end(vl);
}
/**********************************************************************/
//
// @func void | NKDbgPrintfW | Similar function to EdbgOutputDebugString
// but working on wide strings
//
// XXX
//
// Function only really works with "wide ASCII" strings, not with true
// unicode.
//
// @rdesc none
//
// @parm const unsigned short *sz,... |
// Format String:
//
// @flag Format string | type
// @flag u | unsigned
// @flag d | int
// @flag c | char
// @flag s | string
// @flag x | 4-bit hex number
// @flag B | 8-bit hex number
// @flag H | 16-bit hex number
// @flag X | 32-bit hex number
//
// @comm
// Same as FormatString, but output to serial port instead of buffer.
//
void NKDbgPrintfW(LPCWSTR sz, ...)
{
unsigned char c;
va_list vl;
va_start(vl, sz);
while (*sz)
{
c = (*sz++) & 0xff;
switch (c)
{
case '%':
c = (*sz++) & 0xff;
switch (c)
{
case 'x':
pOutputNumHex(va_arg(vl, unsigned long), 0);
break;
case 'B':
pOutputNumHex(va_arg(vl, unsigned long), 2);
break;
case 'H':
pOutputNumHex(va_arg(vl, unsigned long), 4);
break;
case 'X':
pOutputNumHex(va_arg(vl, unsigned long), 8);
break;
case 'd':
{
long l;
l = va_arg(vl, long);
if (l < 0)
{
pOutputByte('-');
l = -l;
}
pOutputNumDecimal((unsigned long)l);
}
break;
case 'u':
pOutputNumDecimal(va_arg(vl, unsigned long));
break;
case 'a':
case 's':
OutputString(va_arg(vl, char *));
break;
case '%':
pOutputByte('%');
break;
case 'c':
c = va_arg(vl, unsigned char);
pOutputByte(c);
break;
default:
pOutputByte(' ');
break;
}
break;
case '\n':
pOutputByte('\r');
// fall through
default:
pOutputByte(c);
}
}
va_end(vl);
}
/**********************************************************************/
//
// @func void | FormatString | Simple formatted output string routine
//
// @rdesc Returns length of formatted string
//
// @parm unsigned char * | pBuf |
// Pointer to string to return formatted output. User must ensure
// that buffer is large enough.
//
// @parm const unsigned char * | sz,... |
// Format String:
//
// @flag Format string | type
// @flag u | unsigned
// @flag d | int
// @flag c | char
// @flag s | string
// @flag x | 4-bit hex number
// @flag B | 8-bit hex number
// @flag H | 16-bit hex number
// @flag X | 32-bit hex number
//
// @comm Same as OutputFormatString, but output to buffer instead of
// serial port.
//
unsigned int FormatString(unsigned char *pBuf, const unsigned char *sz, ...)
{
unsigned char c;
va_list vl;
va_start(vl, sz);
szSprintf = pBuf;
while (*sz)
{
c = *sz++;
switch (c)
{
case (unsigned char)'%':
c = *sz++;
switch (c)
{
case 'x':
pOutputNumHex(va_arg(vl, unsigned long), 0);
break;
case 'B':
pOutputNumHex(va_arg(vl, unsigned long), 2);
break;
case 'H':
pOutputNumHex(va_arg(vl, unsigned long), 4);
break;
case 'X':
pOutputNumHex(va_arg(vl, unsigned long), 8);
break;
case 'd':
{
long l;
l = va_arg(vl, long);
if (l < 0)
{
pOutputByte('-');
l = -l;
}
pOutputNumDecimal((unsigned long)l);
}
break;
case 'u':
pOutputNumDecimal(va_arg(vl, unsigned long));
break;
case 's':
OutputString(va_arg(vl, char *));
break;
case '%':
pOutputByte('%');
break;
case 'c':
c = va_arg(vl, unsigned char);
pOutputByte(c);
break;
default:
pOutputByte(' ');
break;
}
break;
case '\n':
pOutputByte('\r');
// fall through
default:
pOutputByte(c);
}
}
pOutputByte(0);
c = szSprintf - pBuf;
szSprintf = 0;
va_end(vl);
return (c);
}
/**********************************************************************/
//
// @func void | pOutputByte | Sends a byte out of the monitor port.
//
// @rdesc none
//
// @parm unsigned int | c | Byte to send.
//
static void pOutputByte(unsigned char c)
{
if (szSprintf)
*szSprintf++ = c;
else
OEMWriteDebugByte(c);
}
//
// @func void | pOutputNumHex | Print the hex representation of a number
// through the monitor port.
//
// @rdesc none
//
// @parm unsigned long | n | The number to print.
//
// @parm long | depth | Minimum number of digits to print.
//
static void pOutputNumHex(unsigned long n, long depth)
{
if (depth)
depth--;
if ((n & ~0xf) || depth)
{
pOutputNumHex(n >> 4, depth);
n &= 0xf;
}
if (n < 10)
pOutputByte((unsigned char)(n + '0'));
else
pOutputByte((unsigned char)(n - 10 + 'A'));
}
//
// @func void | pOutputNumDecimal | Print the decimal representation
// of a number through the monitor
// port.
//
// @rdesc none
//
// @parm unsigned long | n | The number to print.
//
static void pOutputNumDecimal(unsigned long n)
{
if (n >= 10)
{
pOutputNumDecimal(n / 10);
n %= 10;
}
pOutputByte((unsigned char)(n + '0'));
}
//
// @func void | OutputString | Sends an unformatted string to the
// monitor port.
//
// @rdesc none
//
// @parm const unsigned char * | s | Points to the string to be printed.
//
// @comm Backslash n is converted to backslash r backslash n
//
static void OutputString(const unsigned char *s)
{
while (*s)
{
if (*s == '\n')
OEMWriteDebugByte('\r');
OEMWriteDebugByte(*s++);
}
}
//
// This routine will take a binary IP address as represent here and
// return a dotted decimal version of it
//
char *inet_ntoa(DWORD dwIP)
{
static char szDottedD[16];
FormatString(szDottedD, "%u.%u.%u.%u",
(BYTE)dwIP, (BYTE)(dwIP >> 8),
(BYTE)(dwIP >> 16), (BYTE)(dwIP >> 24));
return szDottedD;
}
int AsciiToInt(const char* szNumber)
{
char c;
int total = 0;
c = *szNumber++;
while ((c >= '0') && (c <= '9'))
{
total = 10 * total + (c - '0');
c = *szNumber++;
}
return (total);
}
//
// This routine will take a dotted decimal IP address as represent
// here and return a binary version of it
//
DWORD inet_addr(char *pszDottedD)
{
DWORD dwIP = 0;
DWORD cBytes;
char *pszLastNum;
int atoi (const char *s);
// Replace the dots with NULL terminators
pszLastNum = pszDottedD;
for( cBytes = 0; cBytes < 4; cBytes++ )
{
while(*pszDottedD != '.' && *pszDottedD != '\0')
pszDottedD++;
if (pszDottedD == '\0' && cBytes != 3)
return 0;
*pszDottedD = '\0';
dwIP |= (AsciiToInt(pszLastNum) & 0xFF) << (8*cBytes);
pszLastNum = ++pszDottedD;
}
return dwIP;
}
#define ENTRIES_PER_LINE 16
void EdbgDumpHexBuf(PUCHAR pBuf, DWORD Count)
{
DWORD i,j;
EdbgOutputDebugString("Dump of %u bytes @ 0x%X\n", Count, (DWORD)pBuf);
for (i = 0; i < Count; i += ENTRIES_PER_LINE)
{
EdbgOutputDebugString("\n0x%X ",i);
for (j = 0; j < ENTRIES_PER_LINE; j++)
if ((i+j) >= Count)
EdbgOutputDebugString("\n");
else
EdbgOutputDebugString("%B ", pBuf[i+j]);
}
EdbgOutputDebugString("\n");
}
/* EOF format.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -