Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

626 lines
14 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
All rights reserved.
Module Name:
dbgutil.hxx
Abstract:
LSA Utility functions header
Author:
Larry Zhu (Lzhu) May 1, 2001
Revision History:
--*/
#ifndef _LSAUTIL_HXX_
#define _LSAUTIL_HXX_
#include <string.h>
#include <stdio.h>
#include <align.h>
namespace LSA_NS {
enum ELsaExceptionCode {
kInvalid,
kIncorrectSymbols,
kExitOnControlC,
};
LPCTSTR
StripPathFromFileName(
IN LPCTSTR pszFile
);
ULONG
GetStructFieldVerbose(
IN ULONG64 addrStructBase,
IN PCSTR pszStructTypeName,
IN PCSTR pszStructFieldName,
IN ULONG BufferSize,
OUT PVOID Buffer);
ULONG
GetStructPtrFieldVerbose(
IN ULONG64 addrStructBase,
IN PCSTR pszStructTypeName,
IN PCSTR pszStructFieldName,
OUT PULONG64 Buffer);
HRESULT
GetCurrentProcessor(
IN PDEBUG_CLIENT Client,
OPTIONAL OUT PULONG pProcessor,
OPTIONAL OUT PHANDLE phCurrentThread);
PCSTR
ReadStructStrField(
IN ULONG64 addrStructBase,
IN PCSTR pszStructTypeName,
IN PCSTR pszStructStringFieldName);
PCWSTR
ReadStructWStrField(
IN ULONG64 addrStructBase,
IN PCSTR pszStructTypeName,
IN PCSTR pszStructWStringFieldName);
BOOL
WINAPI
LsaLookupAccountNameA(
IN LPCSTR lpSystemName,
IN LPCSTR lpAccountName,
OUT PSID Sid,
IN OUT LPDWORD cbSid,
OUT LPSTR ReferencedDomainName,
IN OUT LPDWORD cbReferencedDomainName,
OUT PSID_NAME_USE peUse
);
BOOL
WINAPI
LsaLookupAccountSidA(
IN LPCSTR lpSystemName,
IN PSID Sid,
OUT LPSTR Name,
IN OUT LPDWORD cbName,
OUT LPSTR ReferencedDomainName,
IN OUT LPDWORD cbReferencedDomainName,
OUT PSID_NAME_USE peUse
);
void LocalPrintGuid(IN const GUID *pGuid);
BOOL IsAddressInNonePAEKernelAddressSpace(IN ULONG64 addr);
HRESULT HResultFromWin32(IN DWORD dwError);
HRESULT GetLastErrorAsHResult(void);
BOOLEAN IsEmpty(IN PCSTR pszArgs);
void debugPrintHandle(IN HANDLE handle);
NTSTATUS NtStatusFromWin32(IN DWORD dwError);
NTSTATUS GetLastErrorAsNtStatus(void);
HRESULT ProcessKnownOptions(IN PCSTR pszArgs OPTIONAL);
HRESULT ProcessHelpRequest(IN PCSTR pszArgs OPTIONAL);
LARGE_INTEGER
ULONG642LargeInteger(
IN ULONG64 value
);
VOID
ShowSystemTimeAsLocalTime(
IN PCSTR pszBanner,
IN ULONG64 ul64Time
);
void handleLsaException(
IN ELsaExceptionCode eExceptionCode,
IN PCSTR pszMsg, OPTIONAL
IN PCSTR pszSymHint OPTIONAL
);
HRESULT GetFileNamePart(IN PCSTR pszFullPath, OUT PCSTR *ppszFileName);
void debugPrintHex(IN const void* buffer, IN ULONG cbBuffer);
#define LSA_NONE 0x00
#define LSA_WARN 0x01
#define LSA_ERROR 0x02
#define LSA_LOG 0x04
#define LSA_LOG_MORE 0x08
#define LSA_LOG_ALL 0x10
inline void debugPrintLevel(IN ULONG ulLevel)
{
PCSTR pszText = NULL;
switch (ulLevel) {
case LSA_WARN:
pszText = "[warn] ";
break;
case LSA_ERROR:
pszText = "[error] ";
break;
case LSA_LOG:
pszText = "[log] ";
break;
case LSA_LOG_MORE:
pszText = "[more] ";
break;
case LSA_LOG_ALL:
pszText = "[all] ";
break;
default:
pszText = kstrInvalid;
break;
}
OutputDebugStringA(pszText);
}
inline void debugPrintf(IN PCSTR pszFmt, ...)
{
CHAR szBuffer[4096] = {0};
OutputDebugStringA(g_Globals.pszDbgPrompt ? g_Globals.pszDbgPrompt : kstrEmptyA);
va_list pArgs;
va_start(pArgs, pszFmt);
_vsnprintf(szBuffer, sizeof(szBuffer) - 1, pszFmt, pArgs);
OutputDebugStringA(szBuffer);
va_end(pArgs);
}
inline PCSTR IoctlErrorStatusToStr(IN PCSTR pszPad, IN ULONG err)
{
static CHAR szBuf[1024] = {0};
#define BRANCH_AND_PRINT(x) \
\
do { \
if (x == err) { \
_snprintf(szBuf, sizeof(szBuf) - 1, "%s%s", pszPad, #x); \
return szBuf; \
} \
} while (0)
BRANCH_AND_PRINT(MEMORY_READ_ERROR);
BRANCH_AND_PRINT(SYMBOL_TYPE_INDEX_NOT_FOUND);
BRANCH_AND_PRINT(SYMBOL_TYPE_INFO_NOT_FOUND);
BRANCH_AND_PRINT(FIELDS_DID_NOT_MATCH);
BRANCH_AND_PRINT(NULL_SYM_DUMP_PARAM);
BRANCH_AND_PRINT(NULL_FIELD_NAME);
BRANCH_AND_PRINT(INCORRECT_VERSION_INFO);
BRANCH_AND_PRINT(EXIT_ON_CONTROLC);
BRANCH_AND_PRINT(CANNOT_ALLOCATE_MEMORY);
BRANCH_AND_PRINT(INSUFFICIENT_SPACE_TO_COPY);
#undef BRANCH_AND_PRINT
_snprintf(szBuf, sizeof(szBuf) - 1, "%s%#x", pszPad, err);
return szBuf;
}
BOOL IsPtr64WithVoidStar(void);
inline ULONG64 toPtr(IN ULONG64 addr)
{
static BOOL bIsPtr64 = IsPtr64WithVoidStar();
if (!bIsPtr64) {
addr = static_cast<ULONG>(addr);
}
return addr;
}
inline ULONG GetPtrSize(void)
{
static ULONG cbPtrSize = 0;
if (!cbPtrSize) {
cbPtrSize = IsPtr64WithVoidStar() ? sizeof(ULONG64) : sizeof(ULONG);
}
return cbPtrSize;
}
inline ULONG ReadPtrSize(void)
{
static ULONG cbPtrSize = GetPtrSize();
if (!cbPtrSize) {
throw "ReadPtrSize failed";
}
return cbPtrSize;
}
inline ULONG GetPtrWithVoidStar(IN ULONG64 Addr, IN ULONG64* pPointer)
{
return GetFieldData(Addr, kstrVoidStar, NULL, sizeof(ULONG64), (PVOID) pPointer);
}
inline PCSTR EasyStr(IN PCSTR pszName)
{
return pszName ? pszName : kstrNullPtrA;
}
inline void HandleIoctlErrors(IN PCSTR pszBanner, IN ULONG ErrorCode)
{
if (SYMBOL_TYPE_INFO_NOT_FOUND == ErrorCode) {
throw kIncorrectSymbols;
} else if (ErrorCode) {
DBG_LOG(LSA_ERROR, ("%s: Ioctl failed with error code %s\n", EasyStr(pszBanner), EasyStr(IoctlErrorStatusToStr(kstrEmptyA, ErrorCode))));
throw "Ioctl failed";
}
}
inline ULONG64 ReadPtrWithVoidStar(IN ULONG64 Addr)
{
ULONG64 Pointer = 0;
HandleIoctlErrors("ReadPtrWithVoidStar", GetFieldData(Addr, kstrVoidStar, NULL, sizeof(ULONG64), &Pointer));
return Pointer;
}
inline ULONG64 ReadStructPtrField(IN ULONG64 addrStructBase, IN PCSTR pszStructTypeName, IN PCSTR pszStructFieldName)
{
ULONG64 addr = 0;
DBG_LOG(LSA_LOG, ("ReadStructPtrField %s %#I64x %s\n", EasyStr(pszStructTypeName), addrStructBase, EasyStr(pszStructFieldName)));
HandleIoctlErrors("ReadStructPtrField", GetStructPtrFieldVerbose(addrStructBase, pszStructTypeName, pszStructFieldName, &addr));
return toPtr(addr);
}
inline ULONG64 ForwardAdjustPtrAddr(IN ULONG64 addr)
{
static ULONG uPtrSize = ReadPtrSize();
ULONG64 alignedPtrAddr = addr;
//
// Only 64bit machines have alignment requirement
//
if (uPtrSize == sizeof(ULONG64)) {
alignedPtrAddr = ROUND_UP_COUNT(addr, sizeof(ULONG64)); // ((addr + uPtrSize - 1) / uPtrSize) * uPtrSize;
if (alignedPtrAddr != addr) {
DBG_LOG(LSA_LOG, ("ForwardAdjustPtrAddr adjusted addr from %#I64x to %#I64x\n", addr, alignedPtrAddr));
}
}
return alignedPtrAddr;
}
inline ULONG64 ReadPtrVar(IN ULONG64 addr)
{
static uPtrSize = ReadPtrSize();
ULONG64 value = 0;
ULONG errorCode = 0;
//
// Assume 64 bit machine has alignment requirement for pointers
//
if (uPtrSize == sizeof(ULONG64)) {
ULONG64 alignedAddr = addr;
alignedAddr = ForwardAdjustPtrAddr(addr);
if (alignedAddr != addr) {
DBG_LOG(LSA_WARN, ("Adjust pointer address %#I64x to 8 byte boundary %#I64x\n", addr, alignedAddr));
}
addr = alignedAddr;
}
HandleIoctlErrors("ReadPtrVar", GetPtrWithVoidStar(addr, &value));
return toPtr(value);
}
inline UCHAR ReadUCHARVar(IN ULONG64 addr)
{
UCHAR value = 0;
if (!ReadMemory(addr, &value, sizeof(value), NULL)) {
DBG_LOG(LSA_ERROR, ("Can not ReadUCHARVar at %#I64x\n", addr));
throw "ReadUCHARVar failed";
}
return value;
}
inline USHORT ReadUSHORTVar(IN ULONG64 addr)
{
USHORT value = 0;
if (!ReadMemory(addr, &value, sizeof(value), NULL)) {
DBG_LOG(LSA_ERROR, ("Can not ReadUSHORTVar at %#I64x\n", addr));
throw "ReadUSHORTVar failed";
}
return value;
}
inline ULONG ReadULONGVar(IN ULONG64 addr)
{
ULONG value = 0;
if (!ReadMemory(addr, &value, sizeof(value), NULL)) {
DBG_LOG(LSA_ERROR, ("Can not ReadULONGVar at %#I64x\n", addr));
throw "ReadULONGVar failed";
}
return value;
}
inline ULONG64 ReadULONG64Var(IN ULONG64 addr)
{
ULONG64 value = 0;
if (!ReadMemory(addr, &value, sizeof(value), NULL)) {
DBG_LOG(LSA_ERROR, ("Can not ReadULONG64Var at %#I64x\n", addr));
throw "ReadULONG64Var failed";
}
return value;
}
inline ULONG ReadTypeSize(IN PCSTR pszTypeName)
{
ULONG typeSize = 0;
typeSize = GetTypeSize(pszTypeName);
DBG_LOG(LSA_LOG, ("Read type size of \"%s\"\n", EasyStr(pszTypeName)));
if (!typeSize) {
DBG_LOG(LSA_ERROR, ("Can not GetTypeSize on %s\n", EasyStr(pszTypeName)));
throw "ReadTypeSize failed\n";
}
return typeSize;
}
inline ULONG ReadFieldOffset(IN PCSTR pszTypeName, IN PCSTR pszFieldName)
{
ULONG fieldOffset = 0;
DBG_LOG(LSA_LOG, ("Read field offset of \"%s\" from \"%s\"\n", EasyStr(pszFieldName), EasyStr(pszTypeName)));
HandleIoctlErrors("ReadFieldOffset", GetFieldOffset(pszTypeName, pszFieldName, &fieldOffset));
return fieldOffset;
}
inline void ReadStructField(IN ULONG64 addrStructBase, IN PCSTR pszStructTypeName, IN PCSTR pszStructFieldName, IN ULONG fieldSize, OUT void* pFieldValue)
{
DBG_LOG(LSA_LOG, ("ReadStructField %s %#I64x %s\n", EasyStr(pszStructTypeName), addrStructBase, EasyStr(pszStructFieldName)));
HandleIoctlErrors("ReadStructField", GetStructFieldVerbose(addrStructBase, pszStructTypeName, pszStructFieldName, fieldSize, pFieldValue));
}
inline void LsaReadMemory(IN ULONG64 addr, IN ULONG cbBuffer, OUT void* buffer)
{
if (!ReadMemory(addr, buffer, cbBuffer, NULL)) {
DBG_LOG(LSA_ERROR, ("Unable to read %#x bytes from memory location %#I64x\n", cbBuffer, toPtr(addr)));
throw "LsaReadMemory failed";
}
}
//
// Used to read in value of a short (<= 8 bytes) fields
//
// This is essentially the same as GetShortField with one difference that
// it throws exceptions on failures
//
inline ULONG64 ReadShortField(IN ULONG64 TypeAddress, IN PCSTR pszName, IN USHORT StoreAddress)
{
static ULONG64 SavedAddress = 0;
static PCSTR pszSavedName = NULL;
static ULONG ReadPhysical = 0;
ULONG Err = 0;
FIELD_INFO flds = {reinterpret_cast<UCHAR*>(const_cast<PSTR>(pszName)), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL};
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), reinterpret_cast<UCHAR*>(const_cast<PSTR>(pszSavedName)), DBG_DUMP_NO_PRINT | ((StoreAddress & 2) ? DBG_DUMP_READ_PHYSICAL : 0),
SavedAddress, NULL, NULL, NULL, 1, &flds
};
if (StoreAddress) {
Sym.sName = reinterpret_cast<UCHAR*>(const_cast<PSTR>(pszName));
Sym.nFields = 0;
pszSavedName = pszName;
Sym.addr = SavedAddress = TypeAddress;
ReadPhysical = (StoreAddress & 2);
if (!SavedAddress) {
throw "Invalid arguments to ReadShortField";
}
Err = Ioctl(IG_DUMP_SYMBOL_INFO, &Sym, Sym.size);
DBG_LOG(LSA_LOG, ("Save address %s %#I64x\n", EasyStr(pszName), TypeAddress));
HandleIoctlErrors("ReadShortField (save address) failed", Err);
return 0; // zero on success
} else {
Sym.Options |= ReadPhysical ? DBG_DUMP_READ_PHYSICAL : 0;
}
Err = Ioctl(IG_DUMP_SYMBOL_INFO, &Sym, Sym.size);
DBG_LOG(LSA_LOG, ("Read %s %#I64x %s\n", EasyStr(pszSavedName), SavedAddress, EasyStr(pszName)));
HandleIoctlErrors("ReadShortField (read value) failed", Err);
return flds.address;
}
inline ULONG ReadTypeSizeInArray(IN PCSTR pszType)
{
ULONG cbOneItem = 0;
ULONG cbTwoItems = 0;
CHAR szTypeTmp[256] = {0};
DBG_LOG(LSA_LOG, ("ReadTypeSizeInArray %s\n", pszType));
cbOneItem = GetTypeSize(pszType);
if (_snprintf(szTypeTmp, sizeof(szTypeTmp) - 1, "%s[2]", pszType) < 0) {
throw "ReadTypeSizeInArray failed with insufficient buffer";
}
cbTwoItems = GetTypeSize(szTypeTmp);
cbOneItem = cbTwoItems - cbOneItem;
if (!cbOneItem) {
dprintf("Unable to read type size in array for %s\n", pszType);
throw "ReadTypeSizeInArray failed";
}
return cbOneItem;
}
inline ULONG64 ReadPtrField(IN PCSTR Field)
{
return toPtr(ReadShortField(0, Field, 0));
}
inline void ExitIfControlC(void)
{
if (CheckControlC()) {
throw kExitOnControlC;
}
}
//
// This func is not thread safe
//
inline PCSTR PtrToStr(IN ULONG64 addr)
{
static CHAR szBuffer[64] = {0};
if (!addr) {
return kstrNullPtrA;
}
_snprintf(szBuffer, sizeof(szBuffer) - 1, "%#I64x", addr);
return szBuffer;
}
//
// This func is not thread safe because it calls PtrToStr which is not
// thread safe
//
inline PCSTR GetSymbolStr(IN ULONG64 addr, IN PCSTR pszBuffer)
{
ExitIfControlC();
//
// null
//
if (!addr) {
return kstrNullPtrA;
}
//
// No symbols resolved, return address
//
if (!pszBuffer || !*pszBuffer) {
return PtrToStr(addr);
}
//
// Return symbols
//
return pszBuffer;
}
inline void PrintPtrWithSymbolsLn(IN PCSTR pszBanner, IN ULONG64 addr)
{
CHAR szBuffer[MAX_PATH] = {0};
ULONG64 Disp = 0;
GetSymbol(addr, szBuffer, &Disp);
dprintf(kstr2StrLn, pszBanner, GetSymbolStr(addr, szBuffer));
}
inline void PrintSpaces(IN LONG cSpaces)
{
for (LONG i = 0; i < cSpaces; i++) {
dprintf(kstrSpace);
}
}
} // LSA_NS
#endif