windows-nt/Source/XPSP1/NT/com/ole32/dbgexts/util.cxx
2020-09-26 16:20:57 +08:00

544 lines
12 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995
//
// File: ole.cxx
//
// Contents: Implements ntsd extensions to dump ole tables
//
// Functions:
//
//
// History: 06-01-95 BruceMa Created
//
//
//--------------------------------------------------------------------------
#include <ole2int.h>
#include <windows.h>
#include "ole.h"
//+-------------------------------------------------------------------------
//
// Function: readMemory
//
// Synopsis: Transfer memory from debuggee virtual space to a local
// kernel memory
//
// Arguments: [lpArgumentString] - command line string
// [a] - where to return next argument
//
// Returns: -
//
//--------------------------------------------------------------------------
void readMemory(HANDLE hProcess, PNTSD_EXTENSION_APIS lpExtensionApis,
BYTE *to, BYTE *from, INT cbSize)
{
__try
{
NtReadVirtualMemory(hProcess, (void *) from, (void *) to,
cbSize , NULL);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Printf("...Exception reading %08x-%08x\n", from, from + cbSize - 1);
}
}
//+-------------------------------------------------------------------------
//
// Function: writeMemory
//
// Synopsis: Transfer memory from local memoryto debuggee virtual space
//
// Arguments:
//
// Returns: -
//
//--------------------------------------------------------------------------
void writeMemory(HANDLE hProcess, PNTSD_EXTENSION_APIS lpExtensionApis,
BYTE *to, BYTE *from, INT cbSize)
{
__try
{
NtWriteVirtualMemory(hProcess, (void *) to, (void *) from,
cbSize, NULL);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Printf("...Exception writing %08x-%08x\n", to, to + cbSize - 1);
}
}
//+-------------------------------------------------------------------------
//
// Function: getArgument
//
// Synopsis: Return next command line argument
//
// Arguments: [lpArgumentString] - command line string
// [a] - where to return next argument
//
// Returns: -
//
//--------------------------------------------------------------------------
void getArgument(LPSTR *lpArgumentString, LPSTR a)
{
char *s = *lpArgumentString;
// Skip whitespace
while (*s && (*s == ' ' || *s == '\t'))
{
s++;
}
while (*s && *s != ' ' && *s != '\t')
{
*a++ = *s++;
}
*a = '\0';
*lpArgumentString = s;
}
//+-------------------------------------------------------------------------
//
// Function: IsEqualGUID
//
// Synopsis: Compares two guids for equality
//
// Arguments: [pClsid1] - the first clsid
// [pClsid2] - the second clsid to compare the first one with
//
// Returns: TRUE if equal, FALSE if not.
//
//--------------------------------------------------------------------------
BOOL IsEqualCLSID(CLSID *pClsid1, CLSID *pClsid2)
{
return !memcmp((void *) pClsid1,(void *) pClsid2, sizeof(CLSID));
}
//+-------------------------------------------------------------------------
//
// Function: ScanAddr
//
// Synopsis: Parse the indput string as a hexadecimal address
//
// Arguments: [lpsz] - the hex string to convert
//
// Returns: TRUE for success
//
//--------------------------------------------------------------------------
ULONG ScanAddr(char *lpsz)
{
ULONG val = NULL;
// Peel off any leading "0x"
if (lpsz[0] == '0' && lpsz[1] == 'x')
{
lpsz += 2;
}
// Parse as a hex address
while (*lpsz)
{
if (*lpsz >= '0' && *lpsz <= '9')
{
val = (val << 4) + *lpsz - '0';
}
else if (*lpsz >= 'A' && *lpsz <= 'F')
{
val = (val << 4) + *lpsz - 'A' + 10;
}
else if (*lpsz >= 'a' && *lpsz <= 'f')
{
val = (val << 4) + *lpsz - 'a' + 10;
}
else
{
return NULL;
}
lpsz++;
}
return val;
}
//+-------------------------------------------------------------------------
//
// Function: HexStringToDword
//
// Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
// return value in Value; check for chDelim;
//
// Arguments: [lpsz] - the hex string to convert
// [Value] - the returned value
// [cDigits] - count of digits
//
// Returns: TRUE for success
//
//--------------------------------------------------------------------------
static BOOL HexStringToDword(LPSTR &lpsz, DWORD &Value,
int cDigits, WCHAR chDelim)
{
int Count;
Value = 0;
for (Count = 0; Count < cDigits; Count++, lpsz++)
{
if (*lpsz >= '0' && *lpsz <= '9')
Value = (Value << 4) + *lpsz - '0';
else if (*lpsz >= 'A' && *lpsz <= 'F')
Value = (Value << 4) + *lpsz - 'A' + 10;
else if (*lpsz >= 'a' && *lpsz <= 'f')
Value = (Value << 4) + *lpsz - 'a' + 10;
else
return(FALSE);
}
if (chDelim != 0)
return *lpsz++ == chDelim;
else
return TRUE;
}
//+-------------------------------------------------------------------------
//
// Function: CLSIDFromString
//
// Synopsis: Parse above format; always writes over *pguid.
//
// Arguments: [lpsz] - the guid string to convert
// [pguid] - guid to return
//
// Returns: TRUE if successful
//
//--------------------------------------------------------------------------
BOOL ScanCLSID(LPSTR lpsz, CLSID *pClsid)
{
DWORD dw;
if (*lpsz++ != '{')
return FALSE;
if (!HexStringToDword(lpsz, pClsid->Data1, sizeof(DWORD)*2, '-'))
return FALSE;
if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
return FALSE;
pClsid->Data2 = (WORD)dw;
if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
return FALSE;
pClsid->Data3 = (WORD)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
return FALSE;
pClsid->Data4[0] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-'))
return FALSE;
pClsid->Data4[1] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
return FALSE;
pClsid->Data4[2] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
return FALSE;
pClsid->Data4[3] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
return FALSE;
pClsid->Data4[4] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
return FALSE;
pClsid->Data4[5] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
return FALSE;
pClsid->Data4[6] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, /*(*/ '}'))
return FALSE;
pClsid->Data4[7] = (BYTE)dw;
return TRUE;
}
//+-------------------------------------------------------------------------
//
// Function: FormatCLSID
//
// Synopsis: converts GUID into {...} form without leading identifier;
//
// Arguments: [rguid] - the guid to convert
// [lpszy] - buffer to hold the results
// [cbMax] - sizeof the buffer
//
// Returns: amount of data copied to lpsz if successful
// 0 if buffer too small.
//
//--------------------------------------------------------------------------
void FormatCLSID(REFGUID rguid, LPSTR lpsz)
{
wsprintf(lpsz, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\0",
rguid.Data1, rguid.Data2, rguid.Data3,
rguid.Data4[0], rguid.Data4[1],
rguid.Data4[2], rguid.Data4[3],
rguid.Data4[4], rguid.Data4[5],
rguid.Data4[6], rguid.Data4[7]);
}
extern BOOL fScmNeedsInit;
extern BOOL fInScm;
//+-------------------------------------------------------------------------
//
// Function: CheckForScm
//
// Synopsis: Checks whether the debuggee is 'scm'
//
// Arguments: -
//
// Returns: Sets global boolean fInScm to TRUE if this is the scm;
// FALSE otherwise
//
//--------------------------------------------------------------------------
void checkForScm(PNTSD_EXTENSION_APIS lpExtensionApis)
{
ULONG padr = NULL;
if (fScmNeedsInit)
{
fScmNeedsInit = FALSE;
padr = GetExpression("scm!CPerMachineROT__CPerMachineROT");
fInScm = padr != NULL ? TRUE : FALSE;
}
}
//+-------------------------------------------------------------------------
//
// Function: NotInScm
//
// Synopsis: Prints error message
//
// Arguments: -
//
// Returns:
//
//--------------------------------------------------------------------------
void NotInScm(PNTSD_EXTENSION_APIS lpExtensionApis)
{
Printf("...not meaningful in the scm\n");
}
//+-------------------------------------------------------------------------
//
// Function: NotInOle
//
// Synopsis: Prints error message
//
// Arguments: -
//
// Returns:
//
//--------------------------------------------------------------------------
void NotInOle(PNTSD_EXTENSION_APIS lpExtensionApis)
{
Printf("...only meaningful in the scm\n");
}
///////////////////////////////////////////////////////////////////
// F O R D E B U G G I N G
void dbTrace(char *sz, DWORD *adr, ULONG amt,
PNTSD_EXTENSION_APIS lpExtensionApis)
{
UINT k;
Printf("\n%s", sz);
for (k = 0; k < amt; k++)
{
if (k % 8 == 0)
{
Printf("\n");
}
Printf("%08x ", *adr++);
}
Printf("\n");
}
//+--------------------------------------------------------
//
// Function: GetRegistryInterfaceName
//
// Algorithm: Fetch the name from the registry for the specified interface
//
// History: 21-Jun-95 BruceMa Created
//
//---------------------------------------------------------
BOOL GetRegistryInterfaceName(REFIID iid, char *szValue, DWORD *pcbValue)
{
DWORD dwRESERVED = 0;
HKEY hKey;
char szIID[CLSIDSTR_MAX];
char szInterface[32 + 1 + CLSIDSTR_MAX];
DWORD dwValueType;
HKEY hClsidKey;
HKEY hInproc32Key;
// Prepare to open the "...Interface\<iid>" key
FormatCLSID(iid, szIID);
lstrcpy(szInterface, "Interface\\");
lstrcat(szInterface, szIID);
// Open the key for the specified interface
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szInterface, dwRESERVED,
KEY_READ, &hKey) != ERROR_SUCCESS)
{
return FALSE;
}
// Read the value as the interface name
if (RegQueryValueEx(hKey, NULL, NULL, &dwValueType,
(LPBYTE) szValue, pcbValue) != ERROR_SUCCESS)
{
CloseHandle(hKey);
return FALSE;
}
// Close registry handle and return success
CloseHandle(hKey);
return TRUE;
}
//+--------------------------------------------------------
//
// Function: GetRegistryClsidKey
//
// Algorithm: Fetch the value from the registry for the specified clsid
// and key
//
// History: 21-Jun-95 BruceMa Created
//
//---------------------------------------------------------
BOOL GetRegistryClsidKey(REFCLSID clsid, char *szKey,
char *szValue, DWORD *pcbValue)
{
DWORD dwRESERVED = 0;
HKEY hKey;
char szCLSID[CLSIDSTR_MAX];
char szClsid[5 + 1 + CLSIDSTR_MAX + 1 + 32];
DWORD dwValueType;
HKEY hClsidKey;
HKEY hInproc32Key;
// Prepare to open the "...Interface\<clsid>" key
FormatCLSID(clsid, szCLSID);
lstrcpy(szClsid, "CLSID\\");
lstrcat(szClsid, szCLSID);
lstrcat(szClsid,"\\");
lstrcat(szClsid, szKey);
// Open the key for the specified clsid and key
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szClsid, dwRESERVED,
KEY_READ, &hKey) != ERROR_SUCCESS)
{
return FALSE;
}
// Read the value for the specified key
if (RegQueryValueEx(hKey, NULL, NULL, &dwValueType,
(LPBYTE) szValue, pcbValue) != ERROR_SUCCESS)
{
CloseHandle(hKey);
return FALSE;
}
// Close registry handle and return success
CloseHandle(hKey);
return TRUE;
}