WindowsXP/base/fs/utils/ulib/src/message.cxx
2025-04-27 07:49:33 -04:00

897 lines
15 KiB
C++

#include <pch.cxx>
#define _ULIB_MEMBER_
#include "ulib.hxx"
#include "message.hxx"
#include "hmem.hxx"
extern "C" {
#include "stdio.h"
#if defined(_AUTOCHECK_)
#include "ntos.h"
#endif
}
DEFINE_EXPORTED_CONSTRUCTOR(MESSAGE, OBJECT, ULIB_EXPORT);
MESSAGE::~MESSAGE(
)
/*++
Routine Description:
Destructor for MESSAGE.
Arguments:
None.
Return Value:
None.
--*/
{
Destroy();
}
VOID
MESSAGE::Construct(
)
/*++
Routine Description:
This routine initializes the object to a default initial state.
Arguments:
None.
Return Value:
None.
--*/
{
_logged_chars = 0;
_next_message_offset = 0;
_logging_enabled = FALSE;
_msgid = 0;
_inuse = 0;
_timeout.QuadPart = 0;
}
VOID
MESSAGE::Destroy(
)
/*++
Routine Description:
This routine returns the object to a default initial state.
Arguments:
None.
Return Value:
None.
--*/
{
_logged_chars = 0;
_next_message_offset = 0;
_logging_enabled = FALSE;
_msgid = 0;
_inuse = 0;
_timeout.QuadPart = 0;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::Initialize(
)
/*++
Routine Description:
This routine initializes the class to a valid initial state.
Arguments:
DotsOnly - Autochk should produce only dots instead of messages.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
Destroy();
_timeout.QuadPart = -10000;
return _log_buffer.Initialize();
}
ULIB_EXPORT
BOOLEAN
MESSAGE::IsSuppressedMessage(
)
/*++
Routine Description:
This function determines whether the specified message ID
should be suppressed, i.e. not recorded in the message log.
Arguments:
MessageId -- Supplies the Message ID in question.
Return Value:
TRUE if this message ID is in the set which is not recorded
in the message log.
--*/
{
BOOLEAN result;
switch( _msgid ) {
case MSG_HIDDEN_STATUS:
case MSG_PERCENT_COMPLETE:
case MSG_PERCENT_COMPLETE2:
case MSG_CHK_NTFS_CHECKING_FILES:
case MSG_CHK_NTFS_CHECKING_INDICES:
case MSG_CHK_NTFS_INDEX_VERIFICATION_COMPLETED:
case MSG_CHK_NTFS_FILE_VERIFICATION_COMPLETED:
case MSG_CHK_NTFS_CHECKING_SECURITY:
case MSG_CHK_NTFS_SECURITY_VERIFICATION_COMPLETED:
case MSG_CHK_VOLUME_CLEAN:
case MSG_CHK_CHECKING_FILES:
case MSG_CHK_DONE_CHECKING:
result = TRUE;
break;
default:
result = FALSE;
break;
}
return result;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::Display(
IN PCSTR Format ...
)
/*++
Routine Description:
This routine displays the message with the specified parameters.
Arguments:
Format ... - Supplies a printf style list of arguments.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
va_list ap;
BOOLEAN r;
// unreferenced parameters
(void)(this);
va_start(ap, Format);
r = DisplayV(Format, ap);
va_end(ap);
return r;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::DisplayMsg(
IN MSGID MsgId,
IN PCSTR Format ...
)
/*++
Routine Description:
This routine displays the message with the specified parameters.
It performs the operation atomically.
Arguments:
Format ... - Supplies a printf style list of arguments.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
va_list ap;
BOOLEAN r;
while (InterlockedCompareExchange(&_inuse, 1, 0)) {
NtDelayExecution(FALSE, &_timeout);
}
Set(MsgId);
va_start(ap, Format);
r = DisplayV(Format, ap);
va_end(ap);
InterlockedDecrement(&_inuse);
return r;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::DisplayMsg(
IN MSGID MsgId,
IN MESSAGE_TYPE MessageType,
IN ULONG MessageVisual,
IN PCSTR Format ...
)
/*++
Routine Description:
This routine displays the message with the specified parameters.
It performs the operation atomically.
Arguments:
Format ... - Supplies a printf style list of arguments.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
va_list ap;
BOOLEAN r;
while (InterlockedCompareExchange(&_inuse, 1, 0)) {
NtDelayExecution(FALSE, &_timeout);
}
Set(MsgId, MessageType, MessageVisual);
va_start(ap, Format);
r = DisplayV(Format, ap);
va_end(ap);
InterlockedDecrement(&_inuse);
return r;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::LogMsg(
IN MSGID MsgId,
IN PCSTR Format ...
)
/*++
Routine Description:
This routine logs the message with the specified parameters.
It performs the operation atomically.
Arguments:
Format ... - Supplies a printf style list of arguments.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
va_list ap;
BOOLEAN r;
while (InterlockedCompareExchange(&_inuse, 1, 0)) {
NtDelayExecution(FALSE, &_timeout);
}
Set(MsgId);
va_start(ap, Format);
r = LogV(Format, ap);
va_end(ap);
InterlockedDecrement(&_inuse);
return r;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::Log(
IN PCSTR Format ...
)
/*++
Routine Description:
This routine logs the message with the specified parameters.
Arguments:
Format ... - Supplies a printf style list of arguments.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
va_list ap;
BOOLEAN r;
// unreferenced parameters
(void)(this);
va_start(ap, Format);
r = LogV(Format, ap);
va_end(ap);
return r;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::DumpDataToLog(
IN PVOID Data,
IN ULONG Length
)
/*++
Routine Description:
This routine dumps the binary data to the log.
Arguments:
Data - Supplies a pointer to the data to be dumped
Length - Supplies the number of bytes to dump
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
PUCHAR pdata = (PUCHAR)Data;
ULONG block;
BOOLEAN rst = TRUE;
WCHAR buffer[50], buffer2[20];
USHORT i;
block = ((Length + 0xf) >> 4) + 1;
Set(MSG_CHKLOG_DUMP_DATA);
while (rst && block--) {
for (i=0; i<16; i++) {
__try {
swprintf(buffer+i*3, L"%02x ", pdata[i]);
if (isprint(pdata[i]))
swprintf(buffer2+i, L"%c", pdata[i]);
else
buffer2[i] = '.';
} __except (EXCEPTION_EXECUTE_HANDLER) {
buffer[i*3] = '?';
buffer[i*3+1] = '?';
buffer[i*3+2] = ' ';
buffer2[i] = '.';
}
}
buffer[48] = ' ';
buffer[49] = 0;
buffer2[16] = 0;
pdata += 0x10;
rst = rst && Log("%ws%ws", buffer, buffer2);
}
return rst;
}
BOOLEAN
MESSAGE::DisplayV(
IN PCSTR Format,
IN va_list VarPointer
)
/*++
Routine Description:
This routine displays the message with the specified parameters.
Arguments:
Format - Supplies a printf style list of arguments.
VarPointer - Supplies a varargs pointer to the arguments.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
// unreferenced parameters
(void)(this);
(void)(Format);
(void)(VarPointer);
return TRUE;
}
BOOLEAN
MESSAGE::LogV(
IN PCSTR Format,
IN va_list VarPointer
)
/*++
Routine Description:
This routine logs the message with the specified parameters.
Arguments:
Format - Supplies a printf style list of arguments.
VarPointer - Supplies a varargs pointer to the arguments.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
DSTRING display_string;
CHAR buffer[512];
if (IsLoggingEnabled()) {
if (!BASE_SYSTEM::QueryResourceStringV(&display_string, _msgid, Format,
VarPointer)) {
return FALSE;
}
if (display_string.QuerySTR(0, TO_END, buffer, 512, TRUE)) {
DebugPrintTrace(("%s", buffer));
}
return LogMessage(&display_string);
}
return TRUE;
}
PMESSAGE
MESSAGE::Dup(
)
/*++
Routine Description:
This routine returns a new MESSAGE of the same type.
Arguments:
None.
Return Value:
A pointer to a new MESSAGE object.
--*/
{
// unreferenced parameters
(void)(this);
return NEW MESSAGE;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::IsYesResponse(
IN BOOLEAN Default
)
/*++
Routine Description:
This routine queries to see if the response to a message is either
yes or no.
Arguments:
Default - Supplies a default answer to the question.
Return Value:
FALSE - A "no" response.
TRUE - A "yes" response.
--*/
{
// unreferenced parameters
(void)(this);
return Default;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::QueryStringInput(
OUT PWSTRING String
)
/*++
Routine Description:
This routine queries a string from the user.
Arguments:
String - Supplies a buffer to return the string into.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
// unreferenced parameters
(void)(this);
return String->Initialize("");
}
ULIB_EXPORT
MSGID
MESSAGE::SelectResponse(
IN ULONG NumberOfSelections ...
)
/*++
Routine Descriptions:
This routine queries a response from the user. It returns the
message id of the response inputted.
Arguments:
NumberOfSelections - Supplies the number of possible message
responses.
... - Supplies 'NumberOfSelections' message identifiers.
Return Value:
The first message id on the list.
--*/
{
va_list ap;
MSGID msg;
// unreferenced parameters
(void)(this);
va_start(ap, NumberOfSelections);
msg = va_arg(ap, MSGID);
va_end(ap);
return msg;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::IsInAutoChk(
)
/*++
Routine Description:
This routine simply returns FALSE to indicate it is not
in regular autochk.
Arguments:
None.
Return Value:
FALSE - Not in autochk
--*/
{
return FALSE;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::IsInSetup(
)
/*++
Routine Description:
This routine simply returns FALSE to indicate it is not
in setup.
Arguments:
None.
Return Value:
FALSE - Not in setup
--*/
{
return FALSE;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::IsKeyPressed(
MSGID MsgId,
ULONG TimeOutInSeconds
)
/*++
Routine Description:
This routine simply returns FALSE to indicate no
key has been pressed.
Arguments:
None.
Return Value:
FALSE - No key is pressed within the time out period.
--*/
{
// unreferenced parameters
(void)(this);
UNREFERENCED_PARAMETER( MsgId );
UNREFERENCED_PARAMETER( TimeOutInSeconds );
return FALSE;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::WaitForUserSignal(
)
/*++
Routine Description:
This routine waits for a signal from the user.
Arguments:
None.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
// unreferenced parameters
(void)(this);
return TRUE;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::SetDotsOnly(
IN BOOLEAN DotsState
)
{
// unreferenced parameters
(void)this;
(void)DotsState;
return FALSE;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::QueryPackedLog(
IN OUT PHMEM Mem,
OUT PULONG PackedDataLength
)
/*++
Routine Description:
Arguments:
Mem -- Supplies a container for the packed log.
PackedDataLength -- Receives the number of bytes written to Mem.
Return Value:
TRUE upon successful completion.
--*/
{
FSTRING CurrentString;
PWCHAR Buffer;
ULONG NewBufferSize, CurrentOffset;
if( !IsLoggingEnabled() ) {
return FALSE;
}
ResetLoggingIterator();
CurrentOffset = 0;
while( QueryNextLoggedMessage( &CurrentString ) ) {
NewBufferSize = (CurrentOffset + CurrentString.QueryChCount()) * sizeof(WCHAR);
if( NewBufferSize > Mem->QuerySize() &&
!Mem->Resize( (NewBufferSize + 1023)/1024 * 1024, 0x1 ) ) {
return FALSE;
}
Buffer = (PWCHAR)Mem->GetBuf();
memcpy( Buffer + CurrentOffset,
CurrentString.GetWSTR(),
CurrentString.QueryChCount() * sizeof(WCHAR) );
CurrentOffset += CurrentString.QueryChCount();
}
*PackedDataLength = CurrentOffset * sizeof(WCHAR);
return TRUE;
}
BOOLEAN
MESSAGE::QueryNextLoggedMessage(
OUT PFSTRING MessageText
)
{
PWCHAR Buffer = (PWCHAR)_log_buffer.GetBuf();
BOOLEAN Result;
if( _next_message_offset >= _logged_chars ) {
// No more logged messages.
//
return FALSE;
}
Result = (MessageText->Initialize( Buffer + _next_message_offset ) != NULL) ?
TRUE : FALSE;
// Push _next_message_offset to the next message. Note
// that _next_message_offset is also incremented if this
// loop terminates because a zero was found, so that it
// will be one character past the next NULL character.
//
while( _next_message_offset < _logged_chars &&
Buffer[_next_message_offset++] );
return Result;
}
ULIB_EXPORT
BOOLEAN
MESSAGE::LogMessage(
PCWSTRING Message
)
{
ULONG NewBufferSize;
PWCHAR Buffer;
// The buffer must be large enough to accept this message plus
// a trailing null. To cut down the number of memory allocation
// calls, grow the buffer by 1K chunks.
//
NewBufferSize = (_logged_chars + Message->QueryChCount() + 1) * sizeof(WCHAR);
// Don't allow the buffer to grow more than 0.5MB
// otherwise we may use up all the pages.
if (NewBufferSize > 512000)
return FALSE;
if( _log_buffer.QuerySize() < NewBufferSize &&
!_log_buffer.Resize( (NewBufferSize + 1023)/1024 * 1024, 0x1 ) ) {
return FALSE;
}
Buffer = (PWCHAR)_log_buffer.GetBuf();
// QueryWSTR will append a trailing NULL.
//
Message->QueryWSTR( 0, TO_END,
Buffer + _logged_chars,
_log_buffer.QuerySize()/sizeof(WCHAR) - _logged_chars );
_logged_chars += Message->QueryChCount() + 1;
return TRUE;
}
ULIB_EXPORT
VOID
MESSAGE::Lock(
)
{
while (InterlockedCompareExchange(&_inuse, 1, 0)) {
NtDelayExecution(FALSE, &_timeout);
}
}
ULIB_EXPORT
VOID
MESSAGE::Unlock(
)
{
InterlockedDecrement(&_inuse);
}