mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
added alignment support to PhFormat
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@3719 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
+29
-12
@@ -34,7 +34,9 @@ extern ULONG PhMaxSizeUnit;
|
||||
#define SMALL_BUFFER_LENGTH (PHOBJ_SMALL_OBJECT_SIZE - FIELD_OFFSET(PH_STRING, Buffer) - sizeof(WCHAR))
|
||||
#define BUFFER_SIZE 512
|
||||
|
||||
#define PHP_FORMAT_NEGATIVE 0x1000
|
||||
#define PHP_FORMAT_NEGATIVE 0x1
|
||||
#define PHP_FORMAT_POSITIVE 0x2
|
||||
#define PHP_FORMAT_PAD 0x4
|
||||
|
||||
// Internal CRT routines needed for floating-point conversion
|
||||
|
||||
@@ -61,6 +63,31 @@ static WCHAR PhpFormatDecimalSeparator = '.';
|
||||
static WCHAR PhpFormatThousandSeparator = ',';
|
||||
static _locale_t PhpFormatUserLocale = NULL;
|
||||
|
||||
PPH_STRING PhpResizeFormatBuffer(
|
||||
__in PPH_STRING String,
|
||||
__inout PSIZE_T AllocatedLength,
|
||||
__in SIZE_T UsedLength,
|
||||
__in SIZE_T NeededLength
|
||||
)
|
||||
{
|
||||
PPH_STRING newString;
|
||||
SIZE_T allocatedLength;
|
||||
|
||||
allocatedLength = *AllocatedLength;
|
||||
allocatedLength *= 2;
|
||||
|
||||
if (allocatedLength < UsedLength + NeededLength)
|
||||
allocatedLength = UsedLength + NeededLength;
|
||||
|
||||
newString = PhCreateStringEx(NULL, allocatedLength);
|
||||
memcpy(newString->Buffer, String->Buffer, UsedLength);
|
||||
PhDereferenceObject(String);
|
||||
|
||||
*AllocatedLength = allocatedLength;
|
||||
|
||||
return newString;
|
||||
}
|
||||
|
||||
PPH_STRING PhFormat(
|
||||
__in PPH_FORMAT Format,
|
||||
__in ULONG Count,
|
||||
@@ -90,17 +117,7 @@ PPH_STRING PhFormat(
|
||||
do { \
|
||||
if (allocatedLength < usedLength + (NeededLength)) \
|
||||
{ \
|
||||
PPH_STRING newString; \
|
||||
\
|
||||
allocatedLength *= 2; \
|
||||
\
|
||||
if (allocatedLength < usedLength + (NeededLength)) \
|
||||
allocatedLength = usedLength + (NeededLength); \
|
||||
\
|
||||
newString = PhCreateStringEx(NULL, allocatedLength); \
|
||||
memcpy(newString->Buffer, string->Buffer, usedLength); \
|
||||
PhDereferenceObject(string); \
|
||||
string = newString; \
|
||||
string = PhpResizeFormatBuffer(string, &allocatedLength, usedLength, (NeededLength)); \
|
||||
buffer = string->Buffer + usedLength / sizeof(WCHAR); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
+147
-20
@@ -127,6 +127,8 @@
|
||||
PWSTR temp; \
|
||||
ULONG tempCount; \
|
||||
ULONG r; \
|
||||
ULONG preCount; \
|
||||
ULONG padCount; \
|
||||
\
|
||||
radix = 10; \
|
||||
if (((Format)->Type & FormatUseRadix) && (Format)->Radix >= 2 && (Format)->Radix <= 69) \
|
||||
@@ -169,22 +171,42 @@
|
||||
tempCount++; \
|
||||
} \
|
||||
\
|
||||
preCount = 0; \
|
||||
\
|
||||
if (flags & PHP_FORMAT_NEGATIVE) \
|
||||
{ \
|
||||
*temp-- = '-'; \
|
||||
tempCount++; \
|
||||
} \
|
||||
preCount++; \
|
||||
else if ((Format)->Type & FormatPrefixSign) \
|
||||
preCount++; \
|
||||
\
|
||||
if (((Format)->Type & FormatPadZeros) && !((Format)->Type & FormatGroupDigits)) \
|
||||
{ \
|
||||
*temp-- = '+'; \
|
||||
tempCount++; \
|
||||
if (preCount + tempCount < (Format)->Width) \
|
||||
{ \
|
||||
flags |= PHP_FORMAT_PAD; \
|
||||
padCount = (Format)->Width - (preCount + tempCount); \
|
||||
preCount += padCount; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
temp++; \
|
||||
ENSURE_BUFFER(tempCount * sizeof(WCHAR)); \
|
||||
ENSURE_BUFFER((preCount + tempCount) * sizeof(WCHAR)); \
|
||||
if (OK_BUFFER) \
|
||||
{ \
|
||||
if (flags & PHP_FORMAT_NEGATIVE) \
|
||||
*buffer++ = '-'; \
|
||||
else if ((Format)->Type & FormatPrefixSign) \
|
||||
*buffer++ = '+'; \
|
||||
\
|
||||
if (flags & PHP_FORMAT_PAD) \
|
||||
{ \
|
||||
wmemset(buffer, '0', padCount); \
|
||||
buffer += padCount; \
|
||||
} \
|
||||
\
|
||||
memcpy(buffer, temp, tempCount * sizeof(WCHAR)); \
|
||||
ADVANCE_BUFFER(tempCount * sizeof(WCHAR)); \
|
||||
buffer += tempCount; \
|
||||
} \
|
||||
usedLength += (preCount + tempCount) * sizeof(WCHAR); \
|
||||
} while (0)
|
||||
|
||||
#ifdef _M_IX86
|
||||
@@ -241,14 +263,15 @@ CommonInt64Format:
|
||||
ULONG precision; \
|
||||
DOUBLE value; \
|
||||
CHAR c; \
|
||||
PSTR temp; \
|
||||
ULONG length; \
|
||||
\
|
||||
if ((Format)->Type & FormatUsePrecision) \
|
||||
{ \
|
||||
precision = (Format)->Precision; \
|
||||
\
|
||||
if (precision > BUFFER_SIZE - _CVTBUFSIZE) \
|
||||
precision = BUFFER_SIZE - _CVTBUFSIZE; \
|
||||
if (precision > BUFFER_SIZE - 1 - _CVTBUFSIZE) \
|
||||
precision = BUFFER_SIZE - 1 - _CVTBUFSIZE; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
@@ -268,10 +291,11 @@ CommonInt64Format:
|
||||
/* Use MS CRT routines to do the work. */ \
|
||||
\
|
||||
value = (Format)->u.Double; \
|
||||
temp = (PSTR)tempBuffer + 1; /* leave one character so we can insert a prefix if needed */ \
|
||||
_cfltcvt_l( \
|
||||
&value, \
|
||||
(PSTR)tempBuffer, \
|
||||
sizeof(tempBuffer), \
|
||||
temp, \
|
||||
sizeof(tempBuffer) - 1, \
|
||||
c, \
|
||||
precision, \
|
||||
!!((Format)->Type & FormatUpperCase), \
|
||||
@@ -281,9 +305,20 @@ CommonInt64Format:
|
||||
/* if (((Format)->Type & FormatForceDecimalPoint) && precision == 0) */ \
|
||||
/* _forcdecpt_l(tempBufferAnsi, PhpFormatUserLocale); */ \
|
||||
if ((Format)->Type & FormatCropZeros) \
|
||||
_cropzeros_l((PSTR)tempBuffer, PhpFormatUserLocale); \
|
||||
_cropzeros_l(temp, PhpFormatUserLocale); \
|
||||
\
|
||||
length = (ULONG)strlen((PSTR)tempBuffer); \
|
||||
length = (ULONG)strlen(temp); \
|
||||
\
|
||||
if (temp[0] == '-') \
|
||||
{ \
|
||||
flags |= PHP_FORMAT_NEGATIVE; \
|
||||
temp++; \
|
||||
length--; \
|
||||
} \
|
||||
else if ((Format)->Type & FormatPrefixSign) \
|
||||
{ \
|
||||
flags |= PHP_FORMAT_POSITIVE; \
|
||||
} \
|
||||
\
|
||||
if (((Format)->Type & FormatGroupDigits) && !((Format)->Type & (FormatStandardForm | FormatHexadecimalForm))) \
|
||||
{ \
|
||||
@@ -291,14 +326,15 @@ CommonInt64Format:
|
||||
PSTR decimalPoint; \
|
||||
ULONG wholeCount; \
|
||||
ULONG sepsCount; \
|
||||
ULONG ensureLength; \
|
||||
ULONG copyCount; \
|
||||
ULONG needsSep; \
|
||||
\
|
||||
/* Find the first non-digit character and assume that is the */ \
|
||||
/* decimal point (or the end of the string). */ \
|
||||
\
|
||||
whole = (PSTR)tempBuffer; \
|
||||
decimalPoint = (PSTR)tempBuffer; \
|
||||
whole = temp; \
|
||||
decimalPoint = temp; \
|
||||
\
|
||||
while ((UCHAR)(*decimalPoint - '0') < 10) \
|
||||
decimalPoint++; \
|
||||
@@ -306,20 +342,28 @@ CommonInt64Format:
|
||||
/* Copy the characters to the output buffer, and at the same time */ \
|
||||
/* insert the separators. */ \
|
||||
\
|
||||
wholeCount = (ULONG)(decimalPoint - (PSTR)tempBuffer); \
|
||||
wholeCount = (ULONG)(decimalPoint - temp); \
|
||||
\
|
||||
if (wholeCount != 0) \
|
||||
sepsCount = (wholeCount + 2) / 3 - 1; \
|
||||
else \
|
||||
sepsCount = 0; \
|
||||
\
|
||||
ENSURE_BUFFER((length + sepsCount) * sizeof(WCHAR)); \
|
||||
ensureLength = (length + sepsCount) * sizeof(WCHAR); \
|
||||
if (flags & (PHP_FORMAT_NEGATIVE | PHP_FORMAT_POSITIVE)) \
|
||||
ensureLength += sizeof(WCHAR); \
|
||||
ENSURE_BUFFER(ensureLength); \
|
||||
\
|
||||
copyCount = wholeCount; \
|
||||
needsSep = (wholeCount + 2) % 3; \
|
||||
\
|
||||
if (OK_BUFFER) \
|
||||
{ \
|
||||
if (flags & PHP_FORMAT_NEGATIVE) \
|
||||
*buffer++ = '-'; \
|
||||
else if (flags & PHP_FORMAT_POSITIVE) \
|
||||
*buffer++ = '+'; \
|
||||
\
|
||||
while (copyCount--) \
|
||||
{ \
|
||||
*buffer++ = *whole++; \
|
||||
@@ -332,6 +376,8 @@ CommonInt64Format:
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (flags & (PHP_FORMAT_NEGATIVE | PHP_FORMAT_POSITIVE)) \
|
||||
usedLength += sizeof(WCHAR); \
|
||||
usedLength += (wholeCount + sepsCount) * sizeof(WCHAR); \
|
||||
\
|
||||
/* Copy the rest. */ \
|
||||
@@ -351,16 +397,50 @@ CommonInt64Format:
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SIZE_T preLength; \
|
||||
SIZE_T padLength; \
|
||||
\
|
||||
/* Take care of the sign and zero padding. */ \
|
||||
preLength = 0; \
|
||||
\
|
||||
if (flags & (PHP_FORMAT_NEGATIVE | PHP_FORMAT_POSITIVE)) \
|
||||
preLength++; \
|
||||
\
|
||||
if ((Format)->Type & FormatPadZeros) \
|
||||
{ \
|
||||
if (preLength + length < (Format)->Width) \
|
||||
{ \
|
||||
flags |= PHP_FORMAT_PAD; \
|
||||
padLength = (Format)->Width - (preLength + length); \
|
||||
preLength += padLength; \
|
||||
} \
|
||||
} \
|
||||
/* We don't need to group digits, so directly copy the characters */ \
|
||||
/* to the output buffer. */ \
|
||||
\
|
||||
ENSURE_BUFFER(length * sizeof(WCHAR)); \
|
||||
ENSURE_BUFFER((preLength + length) * sizeof(WCHAR)); \
|
||||
\
|
||||
if (OK_BUFFER) \
|
||||
{ \
|
||||
if (flags & PHP_FORMAT_NEGATIVE) \
|
||||
*buffer++ = '-'; \
|
||||
else if (flags & PHP_FORMAT_POSITIVE) \
|
||||
*buffer++ = '+'; \
|
||||
\
|
||||
if (flags & PHP_FORMAT_PAD) \
|
||||
{ \
|
||||
wmemset(buffer, '0', padLength); \
|
||||
buffer += padLength; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
usedLength += preLength * sizeof(WCHAR); \
|
||||
\
|
||||
if (!OK_BUFFER || NT_SUCCESS(RtlMultiByteToUnicodeN( \
|
||||
buffer, \
|
||||
length * sizeof(WCHAR), \
|
||||
NULL, \
|
||||
(PSTR)tempBuffer, \
|
||||
(PSTR)temp, \
|
||||
length \
|
||||
))) \
|
||||
{ \
|
||||
@@ -370,6 +450,7 @@ CommonInt64Format:
|
||||
} while (0)
|
||||
|
||||
case DoubleFormatType:
|
||||
flags = 0;
|
||||
COMMON_DOUBLE_FORMAT(format);
|
||||
break;
|
||||
|
||||
@@ -412,7 +493,9 @@ CommonInt64Format:
|
||||
|
||||
doubleFormat.Type = DoubleFormatType | FormatUsePrecision | FormatCropZeros | FormatGroupDigits;
|
||||
doubleFormat.Precision = 2;
|
||||
doubleFormat.Width = 0; // stupid compiler
|
||||
doubleFormat.u.Double = s;
|
||||
flags = 0;
|
||||
COMMON_DOUBLE_FORMAT(&doubleFormat);
|
||||
|
||||
ENSURE_BUFFER(sizeof(WCHAR) + PhpSizeUnitNamesCounted[i].Length);
|
||||
@@ -428,5 +511,49 @@ CommonInt64Format:
|
||||
|
||||
ContinueLoop:
|
||||
partLength = usedLength - partLength;
|
||||
|
||||
if (format->Type & (FormatLeftAlign | FormatRightAlign))
|
||||
{
|
||||
SIZE_T newLength;
|
||||
SIZE_T addLength;
|
||||
|
||||
newLength = format->Width * sizeof(WCHAR);
|
||||
|
||||
// We only pad and never truncate.
|
||||
if (partLength < newLength)
|
||||
{
|
||||
addLength = newLength - partLength;
|
||||
ENSURE_BUFFER(addLength);
|
||||
|
||||
if (OK_BUFFER)
|
||||
{
|
||||
WCHAR pad;
|
||||
|
||||
if (format->Type & FormatUsePad)
|
||||
pad = format->Pad;
|
||||
else
|
||||
pad = ' ';
|
||||
|
||||
if (format->Type & FormatLeftAlign)
|
||||
{
|
||||
// Left alignment is easy; we just fill the remaining space
|
||||
// with the pad character.
|
||||
wmemset(buffer, pad, addLength / sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
PWSTR start;
|
||||
|
||||
// Right alignment is much slower and involves moving the
|
||||
// text forward, then filling in the space before it.
|
||||
start = buffer - partLength / sizeof(WCHAR);
|
||||
memmove(start + addLength / sizeof(WCHAR), start, partLength);
|
||||
wmemset(start, pad, addLength / sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
|
||||
ADVANCE_BUFFER(addLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2999,26 +2999,44 @@ typedef enum _PH_FORMAT_TYPE
|
||||
UIntPtrFormatType,
|
||||
DoubleFormatType,
|
||||
SizeFormatType,
|
||||
FormatTypeMask = 0xff,
|
||||
FormatTypeMask = 0x3f,
|
||||
|
||||
FormatUsePrecision = 0x100,
|
||||
FormatUseWidth = 0x200,
|
||||
FormatUseRadix = 0x400,
|
||||
/** If not specified, for floating-point 6 is assumed **/
|
||||
FormatUsePrecision = 0x40,
|
||||
/** If not specified, ' ' is assumed */
|
||||
FormatUsePad = 0x80,
|
||||
/** If not specified, 10 is assumed */
|
||||
FormatUseRadix = 0x100,
|
||||
/** Reserved */
|
||||
FormatUseReserved = 0x200,
|
||||
|
||||
// Floating-point flags
|
||||
FormatStandardForm = 0x1000, // Use standard form instead of normal form
|
||||
FormatHexadecimalForm = 0x2000, // Use hexadecimal form instead of normal form
|
||||
FormatForceDecimalPoint = 0x4000, // Reserved
|
||||
/** Use standard form instead of normal form */
|
||||
FormatStandardForm = 0x1000,
|
||||
/** Use hexadecimal form instead of normal form */
|
||||
FormatHexadecimalForm = 0x2000,
|
||||
/** Reserved */
|
||||
FormatForceDecimalPoint = 0x4000,
|
||||
/** Trailing zeros and possibly the decimal point are trimmed */
|
||||
FormatCropZeros = 0x8000,
|
||||
|
||||
// Floating-point and integer flags
|
||||
FormatGroupDigits = 0x10000, // Group digits (with floating-point, only works when in normal form)
|
||||
FormatPrefixSign = 0x20000, // Always insert a prefix, '+' for positive and '-' for negative
|
||||
/** Group digits (with floating-point, only works when in normal form) */
|
||||
FormatGroupDigits = 0x10000,
|
||||
/** Always insert a prefix, '+' for positive and '-' for negative */
|
||||
FormatPrefixSign = 0x20000,
|
||||
/** Pad left with zeros, taking into consideration the sign. Width must be specified.
|
||||
* Format*Align cannot be used in conjunction with this flag. If FormatGroupDigits is specified,
|
||||
* this flag is ignored. */
|
||||
FormatPadZeros = 0x40000,
|
||||
|
||||
// General flags
|
||||
/** Applies left alignment. Width must be specified. */
|
||||
FormatLeftAlign = 0x80000000,
|
||||
/** Applies right alignment. Width must be specified. */
|
||||
FormatRightAlign = 0x40000000,
|
||||
FormatUpperCase = 0x20000000 // Make characters uppercase (only available for some types)
|
||||
/** Make characters uppercase (only available for some types) */
|
||||
FormatUpperCase = 0x20000000
|
||||
} PH_FORMAT_TYPE;
|
||||
|
||||
typedef struct _PH_FORMAT
|
||||
|
||||
@@ -1426,10 +1426,19 @@ PPH_STRING PhGetFileVersionInfoString2(
|
||||
)
|
||||
{
|
||||
WCHAR subBlock[65];
|
||||
PH_FORMAT format[4];
|
||||
|
||||
_snwprintf(subBlock, 64, L"\\StringFileInfo\\%08X\\%s", LangCodePage, StringName);
|
||||
PhInitFormatS(&format[0], L"\\StringFileInfo\\");
|
||||
PhInitFormatX(&format[1], LangCodePage);
|
||||
format[1].Type |= FormatPadZeros | FormatUpperCase;
|
||||
format[1].Width = 8;
|
||||
PhInitFormatC(&format[2], '\\');
|
||||
PhInitFormatS(&format[3], StringName);
|
||||
|
||||
return PhGetFileVersionInfoString(VersionInfo, subBlock);
|
||||
if (PhFormatToBuffer(format, 4, subBlock, sizeof(subBlock), NULL))
|
||||
return PhGetFileVersionInfoString(VersionInfo, subBlock);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOLEAN PhInitializeImageVersionInfo(
|
||||
|
||||
Reference in New Issue
Block a user