home *** CD-ROM | disk | FTP | other *** search
- // objview.cpp
- //
- // Created 10/08/98
- //
- // (C)Copyright 1998-1999 Microsoft Corporation, All rights reserved.
- //
-
- #include "pch.hpp"
- #pragma hdrstop
-
- #include "objview.hpp"
- #include "hpmonmgr.hpp"
- #include "resource.h"
- #include "refsview.hpp"
- #include "ansibuf.hpp"
- #include "instview.hpp"
-
-
- BOOL ObjectViewer::s_fRegisteredClass = FALSE;
-
-
- BOOL ObjectViewer::MoveSlider (LPARAM lParam)
- {
- if (GetCapture() == m_hwnd)
- {
- LONG x = (SHORT)LOWORD(lParam);
- //LONG y = HIWORD(lParam);
-
- RECT rc;
- GetClientRect(m_hwnd, &rc);
-
- if (x < 0)
- x = 0;
- if (x+m_sliderwid > rc.right)
- x = rc.right-m_sliderwid;
-
- MoveWindow(m_htree, 0, 0, x, rc.bottom, TRUE);
-
- LONG textx = x+m_sliderwid;
- MoveWindow(m_htext, textx, 0, rc.right-textx, rc.bottom, TRUE);
-
- return TRUE;
- }
-
- return FALSE;
- }
-
-
- VOID ObjectViewer::ClearText ()
- {
- SetWindowText(m_htext, "");
- }
-
-
- //static
- LRESULT CALLBACK ObjectViewer::_WndProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- ObjectViewer *ov = (ObjectViewer*)GetWindowLong(wnd, GWL_USERDATA);
- if (ov != NULL)
- return ov->WndProc(wnd, msg, wParam, lParam);
- return BaseWndProc(wnd, msg, wParam, lParam);
- }
-
-
- LRESULT CALLBACK ObjectViewer::WndProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_SIZE:
- {
- LONG w = LOWORD(lParam);
- LONG h = HIWORD(lParam);
- if (w < m_sliderright)
- {
- m_sliderright = w;
- m_sliderleft = w - m_sliderwid;
- }
- MoveWindow(m_htree, 0, 0, m_sliderleft, h, TRUE);
- MoveWindow(m_htext, m_sliderright, 0, w-m_sliderright, h, TRUE);
- }
- break;
-
- case WM_LBUTTONDOWN:
- SetCapture(wnd);
- return 0;
-
- case WM_MOUSEMOVE:
- if (MoveSlider(lParam))
- return 0;
- break;
-
- case WM_LBUTTONUP:
- if (MoveSlider(lParam))
- {
- ReleaseCapture();
- return 0;
- }
- break;
-
- case WM_NOTIFY:
- {
- LPNMHDR pnmh = (NMHDR*)lParam;
- switch (pnmh->code)
- {
- case TVN_SELCHANGED:
- {
- NM_TREEVIEW *pnmtv = (NM_TREEVIEW*)lParam;
- TV_ITEM *ptvi = &pnmtv->itemNew;
- if (ptvi->hItem != NULL)
- {
- ANSIStringBuffer buf;
- if (GetItemDetailText(ptvi->hItem, &buf))
- {
- SetWindowText(m_htext, buf.GetStr());
- return 0;
- }
- }
- SetWindowText(m_htext, "");
- }
- break;
-
- case NM_RCLICK:
- {
- TVHITTESTINFO tvhtti;
-
- DWORD screenpos = GetMessagePos();
- tvhtti.pt.x = LOWORD(screenpos);
- tvhtti.pt.y = HIWORD(screenpos);
-
- RECT rc;
- GetWindowRect(m_htree, &rc);
- tvhtti.pt.x -= rc.left;
- tvhtti.pt.y -= rc.top;
-
- HTREEITEM htisel = TreeView_HitTest(m_htree, &tvhtti);
- if (htisel != NULL)
- {
- TreeView_Select(m_htree, htisel, TVGN_CARET);
-
- TV_ITEM tvi;
- tvi.mask = TVIF_IMAGE | TVIF_PARAM;
- tvi.hItem = htisel;
- if ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & TVIF_PARAM))
- {
- ObjectID vmid = NULL;
- ID id = NULL;
-
- if ( !(tvi.mask & TVIF_IMAGE)
- || (ObjectViewerTreeItemTypes)tvi.iImage == HVTII_OBJECT)
- {
- vmid = tvi.lParam;
- id = m_mgr->LookupID(vmid);
- }
- else if (tvi.iImage >= HVTII_OBJID && tvi.iImage <= HVTII_LAST_OBJID)
- {
- id = (ID)tvi.lParam;
- vmid = id->vmid;
- }
- else if (tvi.iImage >= HVTII_FIRST_ID)
- {
- id = (ID)tvi.lParam;
- if (id->type == ID_OBJECT && !(id->flags & OID_FL_DEAD))
- vmid = id->vmid;
- }
-
- if ((id || vmid) && OnRightClickItem(id, vmid, wnd, screenpos))
- return 0;
- }
- }
- }
- break;
-
- case TVN_GETDISPINFO:
- {
- TV_DISPINFO *ptvdi = (TV_DISPINFO*)lParam;
- TV_ITEM *ptvi = &ptvdi->item;
- if (ptvi->mask & (TVIF_TEXT | TVIF_SELECTEDIMAGE))
- {
- if (ptvi->mask & TVIF_TEXT)
- {
- PSTR psz = ptvi->pszText;
- int cchTextMax = ptvi->cchTextMax;
- if ( ptvi->cchTextMax > 0
- && GetItemText(ptvi->hItem, psz, cchTextMax))
- {
- ;
- }
- else
- {
- *ptvi->pszText = '\0';
- }
- }
-
- if (ptvi->mask & TVIF_SELECTEDIMAGE)
- {
- TV_ITEM tvi;
- tvi.hItem = ptvi->hItem;
- tvi.mask = TVIF_IMAGE;
- if (TreeView_GetItem(m_htree, &tvi))
- ptvi->iSelectedImage = tvi.iImage;
- else
- break;
- }
-
- return 0;
- }
- }
- break;
-
- case TVN_ITEMEXPANDING:
- {
- NMTREEVIEW *pnmtv = (NMTREEVIEW*)lParam;
- TV_ITEM *ptvi = &pnmtv->itemNew;
- if (pnmtv->action & TVE_EXPAND)
- {
- TV_ITEM tvi;
-
- BOOL fIsObject = FALSE;
-
- if (ptvi->mask & TVIF_IMAGE)
- {
- if (IsObjectType((ObjectViewerTreeItemTypes)ptvi->iImage))
- {
- fIsObject = TRUE;
-
- if (!(ptvi->mask & TVIF_PARAM))
- {
- tvi.mask = TVIF_IMAGE | TVIF_PARAM;
- tvi.hItem = ptvi->hItem;
-
- if ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & (TVIF_IMAGE | TVIF_PARAM)) == (TVIF_IMAGE | TVIF_PARAM))
- {
- ptvi = &tvi;
- }
- else
- {
- fIsObject = FALSE;
- }
- }
- }
- }
- else
- {
- fIsObject = TRUE;
-
- if (!(ptvi->mask & TVIF_PARAM))
- {
- tvi.mask = TVIF_PARAM;
- tvi.hItem = ptvi->hItem;
- if ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & TVIF_PARAM))
- {
- ptvi = &tvi;
- }
- else
- {
- fIsObject = FALSE;
- }
- }
- }
-
- if (fIsObject)
- {
- ASSERT(m_mgr->IsStopped());
-
- ObjectID vmid;
- OBJID id;
-
- if ( !(ptvi->mask & TVIF_IMAGE)
- || ptvi->iImage == HVTII_OBJECT)
- {
- vmid = (ObjectID)ptvi->lParam;
- id = NULL;
- }
- else
- {
- id = (OBJID)ptvi->lParam;
- vmid = id->vmid;
- }
-
- AddReferencesInfo info;
- info.ov = this;
- info.hti = ptvi->hItem;
-
- HeapMonitorManager::ExpandObjectResults res;
- res = m_mgr->ExpandObject(vmid, &id, &AddObjectIDReferences, &AddOBJIDReferences, &info);
- if (res != HeapMonitorManager::EOR_FAILED)
- {
- BOOL fHasReferences = res != HeapMonitorManager::EOR_NO_REFERENCES;
-
- if (!fHasReferences)
- {
- tvi.mask = TVIF_CHILDREN;
- tvi.hItem = ptvi->hItem;
- tvi.cChildren = 0;
- TreeView_SetItem(m_htree, &tvi);
- }
-
- RedrawTree();
-
- return !fHasReferences;
- }
- }
- }
- }
- break;
-
- case TVN_ITEMEXPANDED:
- {
- NMTREEVIEW *pnmtv = (NMTREEVIEW*)lParam;
- TV_ITEM *ptvi = &pnmtv->itemNew;
- if (pnmtv->action & TVE_COLLAPSE)
- {
- ObjectViewerTreeItemTypes type;
- LPARAM tvilParam;
-
- if ((ptvi->mask & (TVIF_IMAGE | TVIF_PARAM)) == (TVIF_IMAGE | TVIF_PARAM))
- {
- type = (ObjectViewerTreeItemTypes)ptvi->iImage;
- tvilParam = ptvi->lParam;
- }
- else
- {
- TV_ITEM tvi;
- tvi.mask = (TVIF_IMAGE | TVIF_PARAM);
- tvi.hItem = ptvi->hItem;
- if ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & TVIF_PARAM))
- {
- if (!(tvi.mask & TVIF_IMAGE))
- type = HVTII_OBJECT;
- else
- type = (ObjectViewerTreeItemTypes)tvi.iImage;
- tvilParam = tvi.lParam;
- }
- else
- {
- break;
- }
- }
-
- if (IsObjectType(type))
- {
- for (;;)
- {
- HTREEITEM htichild = TreeView_GetChild(m_htree, ptvi->hItem);
- if (htichild == NULL)
- break;
- TreeView_DeleteItem(m_htree, htichild);
- }
-
- TV_ITEM tvi;
- tvi.hItem = ptvi->hItem;
- tvi.mask = TVIF_CHILDREN;
- tvi.cChildren = 1;
- TreeView_SetItem(m_htree, &tvi);
-
- return 0;
- }
- }
- }
- break;
-
- case TVN_BEGINLABELEDIT:
- {
- NMTVDISPINFO *ptvdi = (NMTVDISPINFO*)lParam;
- TVITEM tvi;
- tvi.hItem = ptvdi->item.hItem;
- tvi.mask = TVIF_PARAM | TVIF_IMAGE;
- if ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & TVIF_IMAGE))
- {
- switch ((ObjectViewerTreeItemTypes)tvi.iImage)
- {
- case HVTII_FOLDER:
- case HVTII_UNLOADED_CLASS:
- case HVTII_DEAD_THREAD:
- return TRUE;
-
- default:
- if (tvi.iImage > HVTII_FIRST_ID)
- return TRUE;
- break;
- }
- }
- }
- break;
-
- case TVN_ENDLABELEDIT:
- {
- NMTVDISPINFO *ptvdi = (NMTVDISPINFO*)lParam;
-
- TVITEM tvi;
- tvi.hItem = ptvdi->item.hItem;
- tvi.mask = TVIF_PARAM | TVIF_IMAGE;
- if ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & TVIF_PARAM))
- {
- if (ptvdi->item.pszText != NULL)
- {
- OBJID id;
- if (!(tvi.mask & TVIF_IMAGE) || tvi.iImage == HVTII_OBJECT)
- id = m_mgr->LookupObject((ObjectID)tvi.lParam);
- else if (IsObjectType((ObjectViewerTreeItemTypes)tvi.iImage))
- id = (OBJID)tvi.lParam;
- else
- break;
-
- if (id != NULL)
- m_mgr->SetObjectTag(id, ptvdi->item.pszText);
-
- return TRUE;
- }
- }
- }
- break;
- }
- }
- break;
-
- case WM_OVEVENT_PERMIT_EXPANSION:
- WalkTree(0, &PermitItemExpansionCB, this);
- return 0;
-
- case WM_OVEVENT_CLEAR_TRANSIENTS:
- WalkTree(0, &DeleteTransientItemsCB, this);
- return 0;
-
- case WM_OVEVENT_OBJECT_CHANGE:
- WalkTree(0, &UpdateObjectStatusCB, (PVOID)lParam);
- return 0;
- }
-
- return BaseWndProc(wnd, msg, wParam, lParam);
- }
-
-
- BOOL ObjectViewer::OnCreateWindow ()
- {
- BOOL result;
-
- HINSTANCE hinst = m_mgr->GetInstance();
-
- RECT rc;
-
- GetClientRect(m_hwnd, &rc);
-
- m_sliderwid = GetSystemMetrics(SM_CXDLGFRAME);
-
- LONG sliderpos = rc.left+(rc.right-rc.left)/2;
- m_sliderleft = sliderpos-m_sliderwid/2;
- m_sliderright = m_sliderleft+m_sliderwid;
-
- result = (m_htree = CreateWindowEx(
- 0,
- WC_TREEVIEW,
- "tv",
- WS_VISIBLE | WS_CHILD | WS_BORDER | WS_HSCROLL | WS_VSCROLL
- | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_EDITLABELS,
- rc.left, rc.top, m_sliderleft, rc.bottom,
- m_hwnd,
- NULL,
- hinst,
- NULL)) != NULL;
-
- HIMAGELIST himages = NULL;
-
- if (result)
- {
- result = (himages = ImageList_LoadBitmap(hinst, MAKEINTRESOURCE(IDB_TREEIMAGES), 16, 0, CLR_NONE)) != NULL;
- }
-
- if (result)
- {
- TreeView_SetImageList(m_htree, himages, TVSIL_NORMAL);
-
- result = (m_htext = CreateWindowEx(
- 0,
- "Edit",
- "",
- WS_VISIBLE | WS_CHILD | WS_BORDER | WS_HSCROLL | WS_VSCROLL
- | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_LEFT | ES_MULTILINE | ES_READONLY,
- m_sliderright, rc.top, rc.right-m_sliderright, rc.bottom,
- m_hwnd,
- NULL,
- hinst,
- NULL)) != NULL;
- }
-
- return result;
- }
-
-
- BOOL ObjectViewer::OnRightClickItem (ID id, UniqueID vmid, HWND wnd, DWORD screenpos)
- {
- if (!id && vmid || id && id->type == ID_OBJECT)
- {
- OBJID obj = (OBJID)id;
-
- HMENU hpopup = LoadMenu(m_mgr->GetInstance(), MAKEINTRESOURCE(IDR_HEAPVIEW_OBJ_POPUP));
- if (hpopup != NULL)
- {
- hpopup = GetSubMenu(hpopup, 0);
- if (hpopup != NULL)
- {
- if (obj != NULL)
- {
- if (obj->flags & OID_FL_DEAD)
- {
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STATE;
- mii.fState = MFS_DISABLED;
- SetMenuItemInfo(hpopup, IDM_OBJPOPUP_FINDREFERENCES, FALSE, &mii);
- }
-
- if (obj->flags & OID_FL_TRACKED)
- {
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STATE;
- mii.fState = MFS_CHECKED;
- SetMenuItemInfo(hpopup, IDM_OBJPOPUP_TRACK, FALSE, &mii);
- }
- }
-
- // Return value is really a menu item id if TPM_RETURNCMD is specified.
- WORD cmd = (WORD)TrackPopupMenu(
- hpopup,
- TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
- LOWORD(screenpos), HIWORD(screenpos),
- 0,
- wnd,
- NULL);
- if (cmd != 0)
- {
- switch (cmd)
- {
- case IDM_OBJPOPUP_FINDREFERENCES:
- FindObjectReferences(vmid);
- return TRUE;
-
- case IDM_OBJPOPUP_TRACK:
- ToggleObjectTracking(obj, vmid);
- return TRUE;
-
- case IDM_OBJPOPUP_TAG:
- TagObject(vmid);
- return TRUE;
- }
- }
- }
- }
- }
- else if (id && id->type == ID_CLASS)
- {
- HMENU hpopup = LoadMenu(m_mgr->GetInstance(), MAKEINTRESOURCE(IDR_HEAPVIEW_CLS_POPUP));
- if (hpopup != NULL)
- {
- hpopup = GetSubMenu(hpopup, 0);
- if (hpopup != NULL)
- {
- // Return value is really a menu item id if TPM_RETURNCMD is specified.
- WORD cmd = (WORD)TrackPopupMenu(
- hpopup,
- TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
- LOWORD(screenpos), HIWORD(screenpos),
- 0,
- wnd,
- NULL);
- if (cmd != 0)
- {
- switch (cmd)
- {
- case IDM_CLSPOPUP_FINDINSTANCES:
- {
- ClassInstancesViewer *civ = new(ClassInstancesViewer());
- if (civ != NULL)
- {
- civ->Initialize(m_mgr, (CLASSID)id);
-
- civ->Release();
- }
- }
- return TRUE;
- }
- }
- }
- }
- }
-
- return FALSE;
- }
-
-
- BOOL ObjectViewer::GetItemText (HTREEITEM hti, PSTR &psztext, int &cchmaxtext)
- {
- BOOL result;
-
- TV_ITEM tvi;
- tvi.hItem = hti;
- tvi.mask = TVIF_PARAM | TVIF_IMAGE;
- result = ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & (TVIF_PARAM | TVIF_IMAGE)) == (TVIF_PARAM | TVIF_IMAGE));
- if (result)
- {
- ObjectViewerTreeItemTypes type = (ObjectViewerTreeItemTypes)tvi.iImage;
-
- switch (type)
- {
- case HVTII_OBJID:
- case HVTII_MULTIREF_OBJID:
- case HVTII_TRACKED_OBJID:
- case HVTII_MULTIREF_TRACKED_OBJID:
- case HVTII_OBJECT:
- case HVTII_DEAD_OBJID:
- {
- int needed = 8;
- if (type == HVTII_DEAD_OBJID)
- needed = 0;
-
- result = (cchmaxtext > needed);
- if (result)
- {
- ObjectID vmid;
- OBJID id;
- if (type == HVTII_OBJECT)
- {
- vmid = (ObjectID)tvi.lParam;
- id = NULL;
- }
- else
- {
- id = (OBJID)tvi.lParam;
- vmid = id->vmid;
- }
-
- if (id == NULL || !(id->flags & OID_FL_TAGGED))
- {
- if (id == NULL || !(id->flags & OID_FL_DEAD))
- {
- wsprintf(psztext, "%08x", vmid);
- needed++;
- }
-
- if (cchmaxtext > needed+1)
- {
- IJavaEventMonitorIDInfo2 *vminfo = m_mgr->GetVMInfoInterface();
-
- ClassID clsid;
-
- if (id == NULL || !(id->flags & OID_FL_DEAD))
- result = (vminfo->ObjectInformation(vmid, &clsid) == S_OK);
- else
- clsid = m_mgr->GetClassOfDeadObject(id);
-
- if (result)
- {
- PSTR clsnameutf8;
- result = (vminfo->ClassInformation(clsid, &clsnameutf8, NULL, NULL, NULL, NULL) == S_OK);
- if (result)
- {
- // TODO: ANSI conversion
- int len = min((unsigned)cchmaxtext-needed, strlen(clsnameutf8));
- if (needed)
- psztext[needed-1] = ' ';
- CopyMemory(psztext+needed, clsnameutf8, len);
- psztext[needed+len] = '\0';
-
- CoTaskMemFree(clsnameutf8);
- }
- }
-
- vminfo->Release();
- }
- }
- else
- {
- m_mgr->Enter();
- {
- PCSTR tag = m_mgr->GetObjectTag(id);
- ASSERT(tag != NULL);
- int len = min((unsigned)cchmaxtext, strlen(tag));
- CopyMemory(psztext, tag, len);
- psztext[len] = '\0';
- }
- m_mgr->Leave();
- }
- }
- }
- break;
-
- default:
- if (type >= HVTII_FIRST_ID)
- {
- CHAR *p = psztext;
- BOOL fCoFree = FALSE;
-
- ID id = (ID)tvi.lParam;
- PCSTR text = m_mgr->FetchIDFriendlyName(id);
- result = (text != NULL);
- if (!result)
- {
- switch (id->type)
- {
- CONTAINER_TYPE rt_type;
-
- case ID_THREAD:
- case ID_GHOST_THREAD:
-
- // TODO: use thread name (provided by JVM_EVENT_TYPE2_THREAD_SET_NAME)
-
- if (cchmaxtext > 10)
- {
- IJavaEventMonitorIDInfo2 *vminfo = m_mgr->GetVMInfoInterface();
-
- DWORD tid;
- if (vminfo->ThreadInformation(id->vmid, &tid) == S_OK)
- {
- result = TRUE;
-
- wsprintf(psztext, "0x%08x", tid);
- }
-
- vminfo->Release();
- }
- break;
-
- case ID_STACKFRAME:
- if (cchmaxtext > 8)
- {
- result = TRUE;
-
- wsprintf(psztext, "%08x", id->vmid);
-
- if (cchmaxtext > 10)
- {
- p[8] = ' ';
- cchmaxtext -= 9;
- p += 9;
-
- STACKID stkid = (STACKID)id;
- MethodID methodid = stkid->methodid;
- if (methodid != NULL)
- {
- IJavaEventMonitorIDInfo2 *vminfo = m_mgr->GetVMInfoInterface();
-
- result = (vminfo->MethodInformation(methodid, (PSTR*)&text, NULL, NULL, NULL, NULL) == S_OK);
- if (result)
- {
- // TODO: ANSI conversion
- fCoFree = TRUE;
- }
-
- vminfo->Release();
- }
- else
- {
- rt_type = stkid->frmtype;
- goto describe_root;
- }
- }
- }
- break;
-
- case ID_ROOT:
- {
- rt_type = ((ROOTID)id)->roottype;
-
- describe_root:
-
- text = m_mgr->GetVerboseContainerName(rt_type);
- result = (text != NULL);
- }
- break;
- }
- }
-
- if (result && text != NULL)
- {
- int len = strlen(text);
- len = min(len, cchmaxtext-1);
- CopyMemory(p, text, len);
- p[len] = '\0';
-
- if (fCoFree)
- CoTaskMemFree((PSTR)text);
- }
- }
- break;
- }
- }
-
- return result;
- }
-
-
- BOOL ObjectViewer::GetItemDetailText (HTREEITEM hti, ANSIStringBuffer *buf)
- {
- BOOL ret = FALSE;
-
- if (m_mgr->IsStopped())
- {
- TV_ITEM tvi;
-
- tvi.hItem = hti;
- tvi.mask = TVIF_IMAGE | TVIF_PARAM;
- if (TreeView_GetItem(m_htree, &tvi))
- {
- TV_ITEM *ptvi= &tvi;
- ObjectID objid;
- if ( !(ptvi->mask & TVIF_IMAGE)
- || ptvi->iImage == HVTII_OBJECT)
- {
- objid = (ObjectID)ptvi->lParam;
- }
- else
- {
- ObjectViewerTreeItemTypes type = (ObjectViewerTreeItemTypes)ptvi->iImage;
- if (IsObjectType(type))
- {
- OBJID id = (OBJID)ptvi->lParam;
- if (id->flags & OID_FL_DEAD)
- return FALSE;
- objid = id->GetObjectID();
- }
- else if (type == (ObjectViewerTreeItemTypes)(HVTII_FIRST_ID + ID_STACKFRAME))
- {
- STACKID id = (STACKID)ptvi->lParam;
- PCSTR descr = m_mgr->GetVerboseContainerName(id->frmtype);
- if (descr != NULL)
- {
- buf->Append(descr);
- buf->Append("\r\n");
- return TRUE;
- }
-
- return FALSE;
- }
- else
- {
- return FALSE;
- }
- }
-
- IJavaEventMonitorIDInfo2 *pvminfo = m_mgr->GetVMInfoInterface();
-
- ClassID clsid;
- if (pvminfo->ObjectInformation(objid, &clsid) == S_OK)
- {
- // Check if this is a special class that the vm can display better.
-
- CLASSID cls = m_mgr->LookupClass(clsid);
- if (cls && (cls->flags & CID_FL_HAS_DESCRIPTION))
- {
- PWSTR descr;
- if (pvminfo->DescribeObject(objid, &descr) == S_OK)
- {
- buf->Append(descr);
- buf->Append("\r\n");
- ret = TRUE;
-
- CoTaskMemFree(descr);
- }
- }
-
- DWORD objsize;
- if (pvminfo->GetObjectSize(objid, &objsize) == S_OK)
- {
- CHAR sizestr[16];
- wsprintf(sizestr, "%u", objsize);
- buf->Append("Object size: ");
- buf->Append(sizestr);
- buf->Append(" bytes\r\n");
- }
-
- if (!ret && cls)
- {
- unsigned nfields = cls->flds->nfields;
- FieldInfo *flds = &cls->flds->fldinfo[0];
-
- for (unsigned i = 0; i < nfields; i++)
- {
- PSTR fldname = flds[i].name;
-
- buf->AppendUtf8(fldname);
-
- __int64 value;
- if (pvminfo->GetObjectField(objid, flds[i].id, &value) == S_OK)
- {
- buf->Append(" = ");
-
- char *fmt = NULL;
-
- if (flds[i].flags & JVM_FIELD_OBJECTREF)
- {
- if (value)
- {
- buf->Append("object 0x");
- fmt = "%x";
- }
- else
- {
- buf->Append("null");
- }
- }
- else if (strncmp(fldname, "long ", 5) == 0)
- {
- char tmp[100];
- sprintf(tmp, "%I64d", value);
- buf->Append(tmp);
- }
- else if (strncmp(fldname, "float ", 6) == 0)
- {
- union {
- int i;
- float f;
- } v;
- v.i = (int)value;
-
- char tmp[100];
- sprintf(tmp, "%g", v.f);
- buf->Append(tmp);
- }
- else if (strncmp(fldname, "double ", 7) == 0)
- {
- union {
- __int64 l;
- double d;
- } v;
- v.l = value;
-
- char tmp[100];
- sprintf(tmp, "%lg", v.d);
- buf->Append(tmp);
- }
- else if (strncmp(fldname, "boolean ", 8) == 0)
- {
- buf->Append(value ? "true" : "false");
- }
- else
- {
- fmt = "%d";
- }
-
- if (fmt)
- {
- char tmp[9];
- sprintf(tmp, fmt, (int)value);
- buf->Append(tmp);
- }
- }
-
- buf->Append("\r\n");
- }
-
- ret = TRUE;
- }
- }
-
- pvminfo->Release();
- }
- }
-
- return ret;
- }
-
-
- //static
- ObjectViewer::ObjectViewerTreeItemTypes ObjectViewer::GetTreeItemTypeForID (ID id)
- {
- ObjectViewerTreeItemTypes type;
- if (id->type != ID_OBJECT)
- {
- type = (ObjectViewerTreeItemTypes)(HVTII_FIRST_ID + id->type);
- }
- else
- {
- OBJID obj = (OBJID)id;
-
- if (!(obj->flags & OID_FL_DEAD))
- {
- if (obj->flags & OID_FL_MULTIPLE_REFERENCES)
- type = HVTII_MULTIREF_OBJID;
- else
- type = HVTII_OBJID;
-
- if (obj->flags & OID_FL_TRACKED)
- type = (ObjectViewerTreeItemTypes)(type + 1);
- }
- else
- {
- type = HVTII_DEAD_OBJID;
- }
- }
- return type;
- }
-
-
- BOOL ObjectViewer::GetTreeItemTypeInfo (HTREEITEM hti, ObjectViewerTreeItemTypes *ptype, PVOID *ptoken)
- {
- TV_ITEM tvi;
- tvi.mask = TVIF_IMAGE | TVIF_PARAM;
- tvi.hItem = hti;
- BOOL ret = ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.mask & TVIF_PARAM));
- if (ret)
- {
- ObjectViewerTreeItemTypes type = HVTII_OBJECT;
- if (tvi.mask & TVIF_IMAGE)
- type = (ObjectViewerTreeItemTypes)tvi.iImage;
- *ptype = type;
- *ptoken = (PVOID)tvi.lParam;
- }
- return ret;
- }
-
-
- HTREEITEM ObjectViewer::AddTreeItem (HTREEITEM htiParent, HTREEITEM htiafter, ObjectViewerTreeItemTypes type, PVOID token)
- {
- TVINSERTSTRUCT tvis;
- ZeroMemory(&tvis, sizeof(tvis));
- tvis.hParent = htiParent;
- tvis.hInsertAfter = htiafter;
- tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- tvis.item.iImage = type;
- tvis.item.iSelectedImage = I_IMAGECALLBACK;
- tvis.item.pszText = LPSTR_TEXTCALLBACK;
- tvis.item.lParam = (LPARAM)token;
-
- if (IsObjectType(type) && m_mgr->IsStopped())
- {
- tvis.item.mask |= TVIF_CHILDREN;
- tvis.item.cChildren = 1;
- }
-
- return TreeView_InsertItem(m_htree, &tvis);
- }
-
-
- HTREEITEM ObjectViewer::AddTreeItemForID (HTREEITEM htiParent, ID id, BOOL fPermitDuplicates)
- {
- ASSERT(fPermitDuplicates || !FindChildItemForID(htiParent, id));
- return AddTreeItem(htiParent, GetTreeItemTypeForID(id), id);
- }
-
-
- HTREEITEM ObjectViewer::AddTreeItemForID (HTREEITEM htiParent, HTREEITEM htiAfter, ID id, BOOL fPermitDuplicates)
- {
- ASSERT(fPermitDuplicates || !FindChildItemForID(htiParent, id));
- return AddTreeItem(htiParent, htiAfter, GetTreeItemTypeForID(id), id);
- }
-
-
- HTREEITEM ObjectViewer::AddTreeItemForReferencedID (HTREEITEM htiParent, ID id)
- {
- return AddTreeItemForID(htiParent, id, TRUE);
- }
-
-
- HTREEITEM ObjectViewer::AddTreeItemForReferencedID (HTREEITEM htiParent, HTREEITEM htiAfter, ID id, BOOL fPermitDuplicates)
- {
- return AddTreeItemForID(htiParent, htiAfter, id, TRUE);
- }
-
-
- HTREEITEM ObjectViewer::AddStaticTreeItem (HTREEITEM htiParent, PCSTR text, ObjectViewerTreeItemTypes img)
- {
- TVINSERTSTRUCT tvis;
- ZeroMemory(&tvis, sizeof(tvis));
- tvis.hParent = htiParent;
- tvis.hInsertAfter = TVI_LAST;
- tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- tvis.item.pszText = (PSTR)text;
- tvis.item.iImage = img;
- tvis.item.iSelectedImage = I_IMAGECALLBACK;
-
- return TreeView_InsertItem(m_htree, &tvis);
- }
-
-
- HTREEITEM ObjectViewer::AddTreeItem (HTREEITEM htiParent, ObjectViewerTreeItemTypes type, PVOID token)
- {
- return AddTreeItem(htiParent, TVI_LAST, type, token);
- }
-
-
- HTREEITEM ObjectViewer::AddTreeItemForObject (HTREEITEM htiParent, ObjectID vmid)
- {
- TVINSERTSTRUCT tvis;
- ZeroMemory(&tvis, sizeof(tvis));
- tvis.hParent = htiParent;
- tvis.hInsertAfter = TVI_LAST;
- tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_SELECTEDIMAGE;
- tvis.item.pszText = LPSTR_TEXTCALLBACK;
- tvis.item.lParam = (LPARAM)vmid;
- tvis.item.iSelectedImage = I_IMAGECALLBACK;
-
- if (m_mgr->IsStopped())
- {
- tvis.item.cChildren = 1;
- tvis.item.mask |= TVIF_CHILDREN;
- }
-
- return TreeView_InsertItem(m_htree, &tvis);
- }
-
-
- VOID ObjectViewer::DeleteTreeItem (HTREEITEM hti)
- {
- EVAL(TreeView_DeleteItem(m_htree, hti));
- }
-
-
- BOOL ObjectViewer::WalkTree (DWORD flags, PWALKTREECBFN pfn, PVOID token)
- {
- return ::WalkTree(m_htree, NULL, flags, pfn, token);
- }
-
-
- HTREEITEM ObjectViewer::FindChildItemForID (HTREEITEM htiParent, ID id)
- {
- HTREEITEM htichild = TreeView_GetChild(m_htree, htiParent);
- return FindNextSiblingForID(htichild, id);
- }
-
-
- HTREEITEM ObjectViewer::FindNextSiblingForID (HTREEITEM htichild, ID id)
- {
- while (htichild != NULL)
- {
- TV_ITEM tvi;
- tvi.mask = TVIF_PARAM | TVIF_IMAGE;
- tvi.hItem = htichild;
- if ( TreeView_GetItem(m_htree, &tvi)
- && (tvi.iImage >= HVTII_FIRST_ID || (tvi.iImage <= HVTII_DEAD_OBJID && tvi.iImage != HVTII_OBJECT))
- && tvi.lParam == (LPARAM)id)
- {
- break;
- }
-
- htichild = TreeView_GetNextSibling(m_htree, htichild);
- }
- return htichild;
- }
-
-
- HTREEITEM ObjectViewer::CreateRoot (HTREEITEM *proot, PCSTR name, ObjectViewerTreeItemTypes img)
- {
- HTREEITEM root = AddStaticTreeItem(TVI_ROOT, name, img);
- if (root == NULL)
- root = TVI_ROOT;
- return *proot = root;
- }
-
-
- BOOL ObjectViewer::ShouldDeleteTransientObject (HTREEITEM hti, OBJID obj)
- {
- return TRUE;
- }
-
-
- //static
- int ObjectViewer::AddObjectIDReferences (ObjectID vmid, PVOID token)
- {
- AddReferencesInfo *info = (AddReferencesInfo*)token;
-
- return info->ov->AddTreeItemForObject(info->hti, vmid) != NULL;
- }
-
-
- //static
- int ObjectViewer::AddOBJIDReferences (OBJID id, PVOID token)
- {
- AddReferencesInfo *info = (AddReferencesInfo*)token;
-
- return info->ov->AddTreeItem(info->hti, GetTreeItemTypeForID(id), id) != NULL;
- }
-
-
- //static
- WalkTreeCBResults ObjectViewer::UpdateObjectStatusCB (HWND htree, HTREEITEM hti, PVOID token)
- {
- OBJID obj = (OBJID)token;
-
- WalkTreeCBResults result = WTCB_CONTINUE;
-
- TV_ITEM tvi;
- tvi.mask = TVIF_IMAGE | TVIF_PARAM;
- tvi.hItem = hti;
- if ( TreeView_GetItem(htree, &tvi)
- && (tvi.mask & TVIF_PARAM))
- {
- BOOL fModified = FALSE;
-
- if (obj->flags & OID_FL_DEAD)
- {
- if ( (tvi.mask & TVIF_IMAGE)
- && tvi.iImage == HVTII_DEAD_OBJID
- && !(obj->flags & ALL_OID_NONTRANSIENT_FLAGS))
- {
- result = WTCB_DELETE;
- fModified = TRUE;
- }
- }
- else
- {
- if ( !(tvi.mask & TVIF_IMAGE)
- || tvi.iImage == HVTII_OBJECT)
- {
- if (tvi.lParam == (LPARAM)obj->GetObjectID())
- {
- tvi.mask = TVIF_IMAGE | TVIF_PARAM;
- tvi.lParam = (LPARAM)obj;
- tvi.iImage = GetTreeItemTypeForID(obj);
- TreeView_SetItem(htree, &tvi);
- fModified = TRUE;
- }
- }
- else
- {
- ObjectViewerTreeItemTypes newtype;;
-
- if ( IsObjectType((ObjectViewerTreeItemTypes)tvi.iImage)
- && (OBJID)tvi.lParam == obj
- && tvi.iImage != (newtype = GetTreeItemTypeForID(obj)))
- {
- tvi.mask = TVIF_IMAGE;
- tvi.iImage = newtype;
- TreeView_SetItem(htree, &tvi);
- fModified = TRUE;
- }
- }
- }
-
- if (!fModified)
- {
- // Something changed, but we didn't need to do anything special.
- // Just force it to be repainted.
-
- RECT rc;
- if (TreeView_GetItemRect(htree, hti, &rc, FALSE))
- {
- InvalidateRect(htree, &rc, TRUE);
- }
- }
- }
-
- return result;
- }
-
-
- BOOL ObjectViewer::FindObjectReferences (ObjectID vmid)
- {
- ASSERT(vmid);
-
- BOOL result;
-
- ObjectReferencesViewer *orv = new(ObjectReferencesViewer());
- result = (orv != NULL);
- if (result)
- {
- result = orv->Initialize(m_mgr, vmid);
-
- orv->Release();
- }
-
- return result;
- }
-
-
- VOID ObjectViewer::ToggleObjectTracking (OBJID obj, ObjectID vmid)
- {
- m_mgr->ToggleObjectTracking(obj, vmid);
- }
-
-
- VOID ObjectViewer::TagObject (ObjectID vmid)
- {
- ASSERT(vmid);
-
- HTREEITEM htisel = TreeView_GetSelection(m_htree);
- if (EVAL(htisel))
- TreeView_EditLabel(m_htree, htisel);
- }
-
-
- //static
- WalkTreeCBResults ObjectViewer::DeleteTransientItemsCB (HWND htree, HTREEITEM hti, PVOID token)
- {
- WalkTreeCBResults result = WTCB_CONTINUE;
-
- TV_ITEM tvi;
- tvi.mask = TVIF_PARAM | TVIF_IMAGE;
- tvi.hItem = hti;
- if (TreeView_GetItem(htree, &tvi))
- {
- if (tvi.mask & TVIF_IMAGE)
- {
- ObjectViewerTreeItemTypes type = (ObjectViewerTreeItemTypes)tvi.iImage;
-
- for (;;)
- {
- switch (type)
- {
- case HVTII_OBJECT:
- case HVTII_OBJID:
- case HVTII_MULTIREF_OBJID:
- case HVTII_TRACKED_OBJID:
- case HVTII_MULTIREF_TRACKED_OBJID:
- case HVTII_DEAD_OBJID:
- if (tvi.mask & TVIF_PARAM)
- {
- OBJID obj = (OBJID)tvi.lParam;
-
- if ( (obj->flags & ALL_OID_NONTRANSIENT_FLAGS)
- && !((ObjectViewer*)token)->ShouldDeleteTransientObject(hti, obj))
- {
- // This has the useful side-effect of causing a
- // '+' to appear when PermitItemExpansionCB
- // applies the "has children" status.
- TreeView_Expand(htree, hti, TVE_COLLAPSE);
-
- tvi.mask = TVIF_CHILDREN;
- tvi.cChildren = 0;
- EVAL(TreeView_SetItem(htree, &tvi));
-
- break;
- }
- }
- // fall through
- case HVTII_UNLOADED_CLASS:
- case HVTII_DEAD_THREAD:
- result = WTCB_DELETE;
- break;
-
- default:
- if (type >= (HVTII_FIRST_ID + ID_FIRST_TRANSIENT))
- result = WTCB_DELETE;
- break;
- }
-
- break;
- }
- }
- else
- {
- result = WTCB_DELETE;
- }
- }
- else
- {
- ASSERT(!"huh?");
- }
-
- return result;
- }
-
-
- //static
- WalkTreeCBResults ObjectViewer::PermitItemExpansionCB (HWND htree, HTREEITEM hti, PVOID token)
- {
- TV_ITEM tvi;
- tvi.mask = TVIF_PARAM | TVIF_IMAGE;
- tvi.hItem = hti;
- if (TreeView_GetItem(htree, &tvi))
- {
- if (tvi.mask & TVIF_IMAGE)
- {
- ObjectViewerTreeItemTypes type = (ObjectViewerTreeItemTypes)tvi.iImage;
-
- switch (type)
- {
- case HVTII_OBJECT:
- case HVTII_OBJID:
- case HVTII_MULTIREF_OBJID:
- case HVTII_TRACKED_OBJID:
- case HVTII_MULTIREF_TRACKED_OBJID:
- case HVTII_DEAD_OBJID:
- tvi.mask = TVIF_CHILDREN;
- tvi.cChildren = 1;
- EVAL(TreeView_SetItem(htree, &tvi));
- break;
- }
- }
- }
-
- return WTCB_CONTINUE;
- }
-
-
- BOOL ObjectViewer::OVPreInitialize (HeapMonitorManager *mgr, PCSTR wndtitle)
- {
- BOOL result = TRUE;
-
- if (!s_fRegisteredClass)
- {
- WNDCLASS wc;
- ZeroMemory(&wc, sizeof(wc));
- wc.lpfnWndProc = &_WndProc;
- wc.hInstance = mgr->GetInstance();
- wc.lpszClassName = WC_HEAPMONITOR_OBJVIEWER;
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.hCursor = LoadCursor(NULL, IDC_SIZEWE);
- result = RegisterClass(&wc);
-
- s_fRegisteredClass = result;
- }
-
- if (result)
- {
- result = BasePreInitialize(mgr, WC_HEAPMONITOR_OBJVIEWER, wndtitle);
- }
-
- return result;
- }
-
-
- BOOL ObjectViewer::OVPostInitialize (HeapMonitorClientRegistrationInfo *preginfo)
- {
- HeapMonitorClientRegistrationInfo reginfo;
- if (!preginfo)
- {
- ZeroMemory(®info, sizeof(reginfo));
- preginfo = ®info;
- }
-
- preginfo->StoppedEventMask |= HMC_OBJECT_EVENTS;
-
- return BasePostInitialize(preginfo);
- }
-
-