|
|
/*++
Copyright (c) 2002 Microsoft Corporation Module Name: powermsg.c Abstract: Classes for manipulating power logging error messages. Author: Andrew Ritz (andrewr) 1-May-2002 Revision History: Andrew Ritz (andrewr) 1-May-2002 - created it. --*/
#include "powercfg.h"
#include "resource.h"
PowerLoggingMessage::PowerLoggingMessage( IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason, IN DWORD SStateBaseMessageIndex, IN HINSTANCE hInstance ) /*++
Routine Description: Base PowerLoggingMessage class constructor. Arguments: LoggingReason - structure containing the reason data we're wrapping. SStateBaseMessageIndex - base message id we use for looking up a resource string associated with this problem. hInstance - module handle for looking up resource associated with this problem. Return Value: none. --*/
{ //
// save off the logging reason data.
//
_LoggingReason = (PSYSTEM_POWER_STATE_DISABLE_REASON) LocalAlloc(LPTR, sizeof(SYSTEM_POWER_STATE_DISABLE_REASON)+LoggingReason->PowerReasonLength);
if (!_LoggingReason) { throw(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY)); }
CopyMemory(_LoggingReason,LoggingReason, sizeof(SYSTEM_POWER_STATE_DISABLE_REASON)+LoggingReason->PowerReasonLength);
//
// the message resource is offset from the supplied base index.
//
if (_LoggingReason->PowerReasonCode == SPSD_REASON_UNKNOWN) { _MessageResourceId = SStateBaseMessageIndex + MAX_REASON_OFFSET; } else { _MessageResourceId = SStateBaseMessageIndex + _LoggingReason->PowerReasonCode; }
ASSERT(_MessageResourceId <= SStateBaseMessageIndex + MAX_REASON_OFFSET); _hInst = hInstance; //
// this is a cache of the reason, initialized to NULL, filled in when we
// call GetString
//
_MessageResourceString = NULL;
} PowerLoggingMessage::~PowerLoggingMessage( VOID ) /*++
Routine Description: Base PowerLoggingMessage class destructor. deletes some member data. Arguments: none. Return Value: none. --*/
{ //
// delete member data.
//
if (_LoggingReason) { LocalFree(_LoggingReason); }
if (_MessageResourceString) { LocalFree(_MessageResourceString); } }
PWSTR PowerLoggingMessage::DuplicateString( IN PWSTR String ) /*++
Routine Description: PowerLoggingMessage helper for copying a string to a newly allocated heap buffer. Arguments: String - null terminated unicode string to duplicate. Return Value: pointer to new heap buffer with copy of string if successful, else NULL. --*/ { PWSTR MyString; DWORD StringLength;
StringLength = (wcslen(String)+1); MyString = (PWSTR)LocalAlloc(LPTR, StringLength*sizeof(WCHAR)); if (MyString) { CopyMemory(MyString,String,StringLength*sizeof(WCHAR)); }
return(MyString); }
BOOL PowerLoggingMessage::GetResourceString( OUT PWSTR *pString ) /*++
Routine Description: PowerLoggingMessage wrapper for LoadString. Arguments: pString - receives a pointer to a string with the resource. Return Value: TRUE inidicates success. --*/ { PWSTR MyString; DWORD StringLength,RetVal;
ASSERT(pString != NULL);
//
// arbitrary string length of 200 should hopefully be enough for any
// resource string.
//
StringLength = 200; RetVal = 0; MyString = (PWSTR)LocalAlloc(LPTR, StringLength*sizeof(WCHAR)); if (MyString) { RetVal = ::LoadString( _hInst, _MessageResourceId, MyString, StringLength); }
if (RetVal != 0) { *pString = MyString; }
return(*pString != NULL); }
SubstituteNtStatusPowerLoggingMessage::SubstituteNtStatusPowerLoggingMessage( IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason, IN DWORD SStateBaseMessageIndex, IN HINSTANCE hInstance ) : PowerLoggingMessage(LoggingReason,SStateBaseMessageIndex,hInstance) /*++
Routine Description: specialized class constructor. Arguments: LoggingReason - structure containing the reason data we're wrapping. SStateBaseMessageIndex - base message id we use for looking up a resource string associated with this problem. hInstance - module handle for looking up resource associated with this problem. Return Value: none. --*/ { //
//We just inherit the base case behavior.
//
}
NoSubstitutionPowerLoggingMessage::NoSubstitutionPowerLoggingMessage( IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason, IN DWORD SStateBaseMessageIndex, IN HINSTANCE hInstance ) : PowerLoggingMessage(LoggingReason,SStateBaseMessageIndex,hInstance) /*++
Routine Description: specialized class constructor. Arguments: LoggingReason - structure containing the reason data we're wrapping. SStateBaseMessageIndex - base message id we use for looking up a resource string associated with this problem. hInstance - module handle for looking up resource associated with this problem. Return Value: none. --*/ { //
//We just inherit the base case behavior.
//
}
SubstituteMultiSzPowerLoggingMessage::SubstituteMultiSzPowerLoggingMessage( IN PSYSTEM_POWER_STATE_DISABLE_REASON LoggingReason, IN DWORD SStateBaseMessageIndex, IN HINSTANCE hInstance ) : PowerLoggingMessage(LoggingReason,SStateBaseMessageIndex,hInstance) /*++
Routine Description: specialized class constructor. Arguments: LoggingReason - structure containing the reason data we're wrapping. SStateBaseMessageIndex - base message id we use for looking up a resource string associated with this problem. hInstance - module handle for looking up resource associated with this problem. Return Value: none. --*/ { //
//We just inherit the base case behavior.
//
}
BOOL NoSubstitutionPowerLoggingMessage::GetString( PWSTR *String ) /*++
Routine Description: specialized GetString method, gets a string appropriate for display to the end user. This one is just looking up a resource string. Arguments: String - receives a pointer to a heap allocated string. must be freed with LocalFree() when complete. Return Value: BOOL indicating outcome. --*/ {
ASSERT(String != NULL);
//
// lookup and cache the message.
//
if (!_MessageResourceString) { if (!GetResourceString(&_MessageResourceString)) { _MessageResourceString = NULL; return(FALSE); } }
ASSERT(_MessageResourceString != NULL);
//
// dup the cached string and return to caller.
//
*String = DuplicateString(_MessageResourceString); return(*String != NULL); }
BOOL SubstituteNtStatusPowerLoggingMessage::GetString( PWSTR *String ) /*++
Routine Description: specialized GetString method, gets a string appropriate for display to the end user. this one takes a string with a %d in it and returns a formatted string. Arguments: String - receives a pointer to a heap allocated string. must be freed with LocalFree() when complete. Return Value: BOOL indicating outcome. --*/ { PWSTR MyString; PDWORD NtStatusCode = (PDWORD)(PCHAR)((PCHAR)_LoggingReason + sizeof(SYSTEM_POWER_STATE_DISABLE_REASON)); if (!_MessageResourceString) { if (!GetResourceString(&MyString)) { _MessageResourceString = NULL; return(FALSE); }
//
// 10 is the maximum # of digits for the substituted NTSTATUS code.
// 1 for the NULL.
//
_MessageResourceString = (PWSTR)LocalAlloc(LPTR,(wcslen(MyString)+10+1)*sizeof(WCHAR)); if (!_MessageResourceString) { LocalFree(MyString); return(FALSE); }
wsprintf(_MessageResourceString,MyString,*NtStatusCode);
LocalFree(MyString);
}
ASSERT(_MessageResourceString != NULL);
//
// dup the cached string and return to caller.
//
*String = DuplicateString(_MessageResourceString); return(*String != NULL); }
BOOL SubstituteMultiSzPowerLoggingMessage::GetString( PWSTR *String ) /*++
Routine Description: specialized GetString method, gets a string appropriate for display to the end user. this one massages a multi-sz string and substitutes that into the resource. Arguments: String - receives a pointer to a heap allocated string. must be freed with LocalFree() when complete. Return Value: BOOL indicating outcome. --*/ { PWSTR MyString; PWSTR SubstitutionString; DWORD NumberOfStrings; DWORD StringSize; PWSTR CurrentString; DWORD CurrentStringLength; PWSTR BaseOfString = (PWSTR)(PCHAR)((PCHAR)_LoggingReason + sizeof(SYSTEM_POWER_STATE_DISABLE_REASON));
PWSTR SeparatorString = L"\n\t\t"; DWORD SeparatorLength = wcslen(SeparatorString); if (!_MessageResourceString) { //
// get the resource
//
if (!GetResourceString(&MyString)) { _MessageResourceString = NULL; return(FALSE); }
//
// get the multi-sz into a prettier format
// first figure out the size, then alloc space and print it out into
// a buffer.
//
NumberOfStrings = 0; StringSize = 0; CurrentString = BaseOfString; CurrentStringLength = 0; while (*CurrentString) { CurrentStringLength = wcslen(CurrentString)+1; StringSize +=CurrentStringLength; CurrentString += CurrentStringLength; NumberOfStrings += 1; }
SubstitutionString = (PWSTR)LocalAlloc(LPTR,(StringSize+1+(NumberOfStrings*SeparatorLength))*sizeof(WCHAR)); if (!SubstitutionString) { LocalFree(MyString); return(FALSE); }
CurrentString = BaseOfString; do { CurrentStringLength = wcslen(CurrentString)+1;
wcscat(SubstitutionString,SeparatorString); wcscat(SubstitutionString,CurrentString);
CurrentString += CurrentStringLength; NumberOfStrings -= 1;
} while (NumberOfStrings != 0);
//
// alloc space for the substitution string PLUS the base message.
//
_MessageResourceString = (PWSTR)LocalAlloc( LPTR, (wcslen(SubstitutionString) + wcslen(MyString) + 1) *sizeof(WCHAR)); if (!_MessageResourceString) { LocalFree(SubstitutionString); LocalFree(MyString); return(FALSE); }
//
// finally "sprintf" them together to get the final string.
// free the strings we allocated along the way.
//
wsprintf(_MessageResourceString,MyString,SubstitutionString);
LocalFree(SubstitutionString); LocalFree(MyString);
}
ASSERT(_MessageResourceString != NULL);
//
// dup the cached string and return to caller.
//
*String = DuplicateString(_MessageResourceString); return(*String != NULL); }
|