//+------------------------------------------------------------------------- // // 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 #include #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\" 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\" 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; }