BOOL PyObject_AsVARDESC(PyObject *ob, VARDESC *v, void *pMore) { if (ob->ob_type != &PyVARDESC::Type) { PyErr_SetString(PyExc_TypeError, "Object is not a VARDESC."); return FALSE; } PyVARDESC *pyv = (PyVARDESC *)ob; v->memid = pyv->memid; v->wVarFlags = pyv->wVarFlags; v->varkind = (VARKIND)pyv->varkind; if (!PyObject_AsELEMDESC(pyv->elemdescVar, &v->elemdescVar, pMore)) return FALSE; if (v->varkind == VAR_PERINSTANCE) { if (!PyInt_Check(pyv->value)) { PyErr_SetString(PyExc_TypeError, "If varkind==VAR_PERINSTANCE, value attribute must be an integer"); return FALSE; } v->oInst = PyInt_AsLong(pyv->value); } else if (v->varkind == VAR_CONST) { VARIANT *pVar = (VARIANT *)AllocMore(pMore, sizeof(VARIANT), TRUE); if (pVar==NULL) return NULL; VariantInit(pVar); if (!PyCom_VariantFromPyObject(pyv->value, pVar)) return NULL; v->lpvarValue = pVar; } else if (v->varkind == VAR_DISPATCH) { // nothing to do - memid is all that is needed by the caller. ; } else { PyCom_LoggerWarning(NULL, "PyObject_AsVARDESC has unknown varkind (%d) - None will be used", v->varkind); } // else ignore value. return TRUE; }
BOOL PyObject_AsFUNCDESC(PyObject *ob, FUNCDESC **ppfd) { BOOL rc = FALSE; if (ob->ob_type != &PyFUNCDESC::Type) { PyErr_SetString(PyExc_TypeError, "The object is not a PyFUNCDESC"); return FALSE; } PyFUNCDESC *pyfd = (PyFUNCDESC *)ob; FUNCDESC *fd = (FUNCDESC *)AllocateMoreBuffer(sizeof(FUNCDESC)); if (fd==NULL) { PyErr_SetString(PyExc_MemoryError, "FUNCDESC"); return FALSE; } fd->memid = pyfd->memid; fd->funckind = (FUNCKIND)pyfd->funckind; fd->invkind = (INVOKEKIND)pyfd->invkind; fd->callconv = (CALLCONV)pyfd->callconv; fd->cParamsOpt = pyfd->cParamsOpt; fd->oVft = pyfd->oVft; fd->wFuncFlags = pyfd->wFuncFlags; // Convert the args and rettype if (pyfd->rettype) { if (!PyObject_AsELEMDESC(pyfd->rettype, &fd->elemdescFunc, fd )) goto done; } if (pyfd->args) { if (!PyObject_AsELEMDESCArray(pyfd->args, &fd->lprgelemdescParam, &fd->cParams, fd)) goto done; } if (pyfd->scodeArray) { // Convert the scode array. if (!PySequence_Check(pyfd->scodeArray)) { PyErr_SetString(PyExc_TypeError, "SCODE array must be a sequence of integers!"); goto done; } fd->cScodes = (short)PySequence_Length(pyfd->scodeArray); fd->lprgscode = (SCODE *)AllocMore(fd, sizeof(SCODE)*fd->cScodes); for (Py_ssize_t i=0;i<fd->cScodes;i++) { PyObject *sub=PySequence_GetItem(ob, i); if (sub==NULL) goto done; BOOL ok = PyInt_Check(sub); if (ok) fd->lprgscode[i] = PyInt_AsLong(sub); else PyErr_SetString(PyExc_TypeError, "SCODE array must be a sequence of integers!"); Py_DECREF(sub); if (!ok) goto done; } } rc = TRUE; done: if (!rc && fd) FreeMoreBuffer(fd); else *ppfd = fd; return rc; }
///////////////////////////////////////////////////////////////////////////// // // TYPEDESC support // ///////////////////////////////////////////////////////////////////////////// BOOL PyObject_AsTYPEDESC( PyObject *ob, TYPEDESC *pDesc, void *pMore) { BOOL rc = FALSE; if (PyInt_Check(ob)) { // a simple VT pDesc->vt = (VARTYPE)PyInt_AsLong(ob); return TRUE; // quick exit! } if (!PySequence_Check(ob) || PySequence_Length(ob)!=2) { PyErr_SetString(PyExc_TypeError, "The object is not an TYPEDESC"); return FALSE; } PyObject *obType = PySequence_GetItem(ob, 0); PyObject *obExtra = PySequence_GetItem(ob, 1); if (!PyInt_Check(obType)) { PyErr_SetString(PyExc_TypeError, "The first sequence item must be an integer"); goto done; } pDesc->vt = (VARTYPE)PyInt_AsLong(obType); switch (pDesc->vt) { case VT_PTR: case VT_SAFEARRAY: pDesc->lptdesc = (TYPEDESC *)AllocMore(pMore, sizeof(TYPEDESC)); if (pDesc->lptdesc==NULL) goto done; if (!PyObject_AsTYPEDESC(obExtra, pDesc->lptdesc, pMore)) goto done; break; case VT_CARRAY: if (!PyObject_AsARRAYDESC(obExtra, &pDesc->lpadesc, pMore)) goto done; break; case VT_USERDEFINED: if (!PyInt_Check(obExtra)) { PyErr_SetString(PyExc_TypeError, "If the TYPEDESC is of type VT_USERDEFINED, the object must be an integer"); goto done; } pDesc->hreftype = (HREFTYPE)PyInt_AsLong(obExtra); break; default: break; } rc = TRUE; done: Py_XDECREF(obType); Py_XDECREF(obExtra); return rc; }
BOOL PyObject_AsELEMDESCArray( PyObject *ob, ELEMDESC **ppDesc, short *pNum, void *pMore ) { if (!PySequence_Check(ob)) { PyErr_SetString(PyExc_TypeError, "ELEMDESCArray must be a sequence of ELEMDESCs"); return FALSE; } *pNum = PySequence_Length(ob); *ppDesc = (ELEMDESC *)AllocMore(pMore, sizeof(ELEMDESC) * *pNum); if (*ppDesc==NULL) return NULL; for (int i=0;i<*pNum;i++) { PyObject *sub = PySequence_GetItem(ob, i); if (sub==NULL) return FALSE; BOOL ok = PyObject_AsELEMDESC(sub, (*ppDesc)+i, pMore); Py_DECREF(sub); if (!ok) return FALSE; } return TRUE; }
///////////////////////////////////////////////////////////////////////////// // // ELEMDESC support // ///////////////////////////////////////////////////////////////////////////// BOOL PyObject_AsELEMDESC( PyObject *ob, ELEMDESC *pDesc, void *pMore ) { // pMore must have come from AllocateMoreBlock() BOOL rc = FALSE; if (!PySequence_Check(ob) || PySequence_Length(ob)!=3) { PyErr_SetString(PyExc_TypeError, "The object is not an ELEMDESC"); return FALSE; } PyObject *obtd = PySequence_GetItem(ob, 0); PyObject *obParamFlags = PySequence_GetItem(ob, 1); PyObject *obDefaultVal = PySequence_GetItem(ob, 2); if (!PyInt_Check(obParamFlags)) { PyErr_SetString(PyExc_TypeError, "The second sequence item must be an integer"); goto done; } pDesc->paramdesc.wParamFlags = (WORD)PyInt_AsLong(obParamFlags); if (obDefaultVal != Py_None) { pDesc->paramdesc.wParamFlags |= PARAMFLAG_FHASDEFAULT; pDesc->paramdesc.pparamdescex = (LPPARAMDESCEX)AllocMore( pMore, sizeof(PARAMDESCEX), TRUE); pDesc->paramdesc.pparamdescex->cBytes = sizeof(PARAMDESCEX); /// XXX - this leaks this variant :-( // To avoid, we could maybe alloc a new More block with VARIANT set // to True, then memcpy this variant into it?? // Or have PyObject_FreeFUNCDESC() do the right thing, looking down // each elemdesc freeing the variant? // However, this is very very rarely used (possibly never in the real world!) VariantInit(&pDesc->paramdesc.pparamdescex->varDefaultValue); if (!PyCom_VariantFromPyObject(obDefaultVal, &pDesc->paramdesc.pparamdescex->varDefaultValue)) goto done; } rc = PyObject_AsTYPEDESC( obtd, &pDesc->tdesc, pMore ); done: Py_XDECREF(obtd); Py_XDECREF(obParamFlags); Py_XDECREF(obDefaultVal); return rc; }
T* prepare_next() { if( m_write == m_end ) AllocMore(); return m_write; }
T* push_next() { if( m_write == m_end ) AllocMore(); return m_write++; }
/* * HeapWalkProc - show task status */ BOOL FAR PASCAL HeapWalkProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { HMENU mh; HMENU mh2; HCURSOR hourglass; HCURSOR oldcursor; DLGPROC dlgproc; DWORD index; heap_list hl; GblWndInfo *info; RECT area; about_info ai; info = (GblWndInfo *)GetWindowLong( hwnd, 0 ); switch( msg ) { case WM_CREATE: InitPaintProc(); info = MemAlloc( sizeof( GblWndInfo ) ); if( info == NULL ) { ErrorBox( hwnd, STR_UNABLE_2_STARTUP, MB_OK | MB_ICONINFORMATION ); PostQuitMessage( 0 ); } memset( info, 0, sizeof( GblWndInfo ) ); SetWindowLong( hwnd, 0, (DWORD)info ); // hdc = GetDC( hwnd ); // ReleaseDC(hwnd, hdc); SetDisplayType( hwnd, &( info->list.title ), HEAPMENU_DISPLAY_INIT ); CreateListBox( hwnd, &info->list, GLOBAL_LB ); info->alloc_dlgproc = MakeProcInstance_DLG( AllocDlgProc, Instance ); info->alloc_dialog = JCreateDialog( Instance, "ALLOC_DLG", hwnd, info->alloc_dlgproc ); memset( &ResHwnd, 0, MAX_RES * sizeof( HWND ) ); break; case WM_MEASUREITEM: break; case WM_MOVE: GetWindowRect( hwnd, &area ); if( !info->minimized ) { Config.last_glob_xpos = Config.glob_xpos; Config.last_glob_ypos = Config.glob_ypos; Config.glob_xpos = area.left; Config.glob_ypos = area.top; } break; case WM_SIZE: ResizeListBox( LOWORD( lparam ), HIWORD( lparam ), &( info->list ) ); if( wparam == SIZE_MINIMIZED || wparam == SIZE_MAXIMIZED ) { Config.glob_xpos = Config.last_glob_xpos; Config.glob_ypos = Config.last_glob_ypos; } if( wparam == SIZE_MINIMIZED ) { info->minimized = TRUE; HideResources( TRUE ); } else if( info->minimized ) { HideResources( FALSE ); info->minimized = FALSE; } else if( wparam != SIZE_MAXIMIZED ) { GetWindowRect( hwnd, &area ); Config.glob_xsize = area.right - area.left; Config.glob_ysize = area.bottom - area.top; } return( DefWindowProc( hwnd, msg, wparam, lparam ) ); break; case WM_CLOSE: PostMessage( hwnd, WM_COMMAND, HEAPMENU_EXIT, 0L ); return( TRUE ); case WM_QUERYENDSESSION: SaveConfigFile( FALSE ); return( TRUE ); break; case WM_DESTROY: FiniPaintProc(); KillPushWin( info->list.title ); SaveConfigFile( FALSE ); if( info != NULL ) { FreeProcInstance_DLG( info->alloc_dlgproc ); MemFree( info ); } DestroyMonoFonts(); CvrCtl3dUnregister( Instance ); CvrCtl3DFini( Instance ); WWinHelp( hwnd, "heapwalk.hlp", HELP_QUIT, 0 ); PostQuitMessage( 0 ); break; case WM_ACTIVATEAPP: if( wparam && !NoRefresh ) { if( info->doing_add ) { info->need_refresh = TRUE; } else { InitHeapList( info->list.box, TRUE ); } } break; case WM_MENUSELECT: if( LOWORD( lparam & MF_POPUP ) ) { mh = GetMenu( hwnd ); mh2 = GetSubMenu( mh, 6 ); if( (HMENU)wparam == mh2 ) { ShowWindow( info->alloc_dialog, SW_SHOWNOACTIVATE ); } else if( (HMENU)wparam != GetSubMenu( mh2, 3 ) && (HMENU)wparam != GetSubMenu( mh2, 4 ) && (HMENU)wparam != GetSubMenu( mh2, 5 ) ) { ShowWindow( info->alloc_dialog, SW_HIDE ); } } return( DefWindowProc( hwnd, msg, wparam, lparam ) ); break; case WM_COMMAND: switch( wparam ) { case HEAPMENU_ABOUT: ai.owner = hwnd; ai.inst = Instance; ai.name = HWAllocRCString( STR_ABOUT_NAME ); ai.version = HWAllocRCString( STR_ABOUT_VERSION ); ai.title = HWAllocRCString( STR_ABOUT_TITLE ); DoAbout( &ai ); HWFreeRCString( ai.title ); HWFreeRCString( ai.version ); HWFreeRCString( ai.name ); break; case HEAPMENU_HELP_CONTENTS: WWinHelp( hwnd, "heapwalk.hlp", HELP_CONTENTS, 0 ); break; case HEAPMENU_HELP_SRCH: WWinHelp( hwnd, "heapwalk.hlp", HELP_PARTIALKEY, (HELP_DATA)(LPCSTR)"" ); break; case HEAPMENU_HELP_ON_HELP: WWinHelp( hwnd, "winhelp.hlp", HELP_HELPONHELP, 0 ); break; case HEAPEX_LIST: if( !info->doing_add ) { if( HIWORD( lparam ) == LBN_DBLCLK ) { ShowHeapObject( (HWND)LOWORD( lparam ) ); } } else { if( HIWORD( lparam ) == LBN_SELCHANGE || HIWORD( lparam ) == LBN_DBLCLK ) { RefreshAdd( info->add_dialog, info->list.box ); RedrawBox( info->list.box, index ); } } break; case HEAPMENU_GLOBAL_REFRESH: InitHeapList( info->list.box, TRUE ); break; case HEAPMENU_FONT: if( ChooseMonoFont( hwnd ) ) { ResetFont( info ); } break; case HEAPMENU_EXIT: DestroyWindow( hwnd ); FreeHeapList(); break; case HEAPMENU_DISPLAY_DPMI: case HEAPMENU_DISPLAY_ENTIRE: case HEAPMENU_DISPLAY_LRU: case HEAPMENU_DISPLAY_FREE: SetDisplayType( hwnd, &( info->list.title ), wparam ); InitHeapList( info->list.box, FALSE ); break; case HEAPMENU_SORT_ADDR: case HEAPMENU_SORT_HANDLE: case HEAPMENU_SORT_MODULE: case HEAPMENU_SORT_SIZE: case HEAPMENU_SORT_TYPE: case HEAPMENU_SORT_GRAN: case HEAPMENU_SORT_DPL: case HEAPMENU_SORT_FLAG: case HEAPMENU_SORT_LRU: mh = GetMenu( hwnd ); CheckMenuItem( mh, GSortType, MF_UNCHECKED | MF_BYCOMMAND ); CheckMenuItem( mh, wparam, MF_CHECKED | MF_BYCOMMAND ); if( GSortType != wparam ) { GSortType = wparam; SortHeapList(); ReDisplayHeapList( info->list.box, NULL ); } break; case HEAPMENU_OBJECT_SHOW: ShowHeapObject( info->list.box ); break; case HEAPMENU_OBJECT_DISCARD: if( GlobDiscardObj( info->list.box ) ) { InitHeapList( info->list.box, TRUE ); } break; case HEAPMENU_OBJECT_NEWEST: if( GlobSetObjPos( info->list.box, FALSE ) ) { if( GSortType == HEAPMENU_SORT_LRU ) { InitHeapList( info->list.box, TRUE ); } } break; case HEAPMENU_OBJECT_OLDEST: if( GlobSetObjPos( info->list.box, TRUE ) ) { if( GSortType == HEAPMENU_SORT_LRU ) { InitHeapList( info->list.box, TRUE ); } } break; case HEAPMENU_OBJECT_GET_SELECTOR: ShowSelector( info->list.box ); break; case HEAPMENU_GLOBAL_HEAPINFO: DisplayGlobHeapInfo( hwnd ); break; case HEAPMENU_GLOBAL_MEMORYINFO: DisplayMemManInfo( hwnd ); break; case HEAPMENU_GLOBAL_COMPACT: GlobalCompact( 0 ); InitHeapList( info->list.box, TRUE ); break; case HEAPMENU_GLOBAL_COMP_DISC: GlobalCompact( -1 ); InitHeapList( info->list.box, TRUE ); break; case HEAPMENU_GLOBAL_CODE_SIZE: dlgproc = MakeProcInstance_DLG( SetCodeDlgProc, Instance ); JDialogBox( Instance, "CODE_AREA_DLG", hwnd, dlgproc ); FreeProcInstance_DLG( dlgproc ); break; case HEAPMENU_FILE_SAVE: InitHeapList( info->list.box, TRUE ); SaveListBox( SLB_SAVE_TMP, PutOutGlobalHeader, DumpGlobalLine, Config.gfname, HeapWalkName, hwnd, info->list.box ); break; case HEAPMENU_FILE_SAVE_TO: InitHeapList( info->list.box, TRUE ); SaveListBox( SLB_SAVE_AS, PutOutGlobalHeader, DumpGlobalLine, Config.gfname, HeapWalkName, hwnd, info->list.box ); break; case HEAPMENU_SAVE_CONFIG: SaveConfigFile( TRUE ); break; case HEAPMENU_CONFIGURE: HWConfigure(); break; case HEAPMENU_LOCAL_MONITOR: index = CheckForLocalSelect( info ); if( index != LB_ERR ) { BeginMonitor( HeapList[index] ); } break; case HEAPMENU_COMPACT_AND_LOCALWALK: LocalCompact( -1 ); /* fall through */ case HEAPMENU_LOCAL_LOCALWALK: index = CheckForLocalSelect( info ); if( index != LB_ERR ) { LocalWalk( HeapList[index] ); } break; case HEAPMENU_GDI_LOCALWALK: if( GetDGroupItem( "GDI", &hl ) ) { LocalWalk( &hl ); } break; case HEAPMENU_USER_LOCALWALK: if( GetDGroupItem( "USER", &hl ) ) { LocalWalk( &hl ); } break; case HEAPMENU_FREE_ALL: MyFreeAllMem(); UpdateAllocInfo( info->alloc_dialog ); PaintAllWindows(); break; case HEAPMENU_FREE_1K: case HEAPMENU_FREE_2K: case HEAPMENU_FREE_5K: case HEAPMENU_FREE_10K: case HEAPMENU_FREE_25K: case HEAPMENU_FREE_50K: hourglass = LoadCursor( NULL, IDC_WAIT ); SetCapture( hwnd ); oldcursor= SetCursor( hourglass ); FreeSomeMem( wparam ); UpdateAllocInfo( info->alloc_dialog ); SetCursor( oldcursor ); ReleaseCapture(); PaintAllWindows(); break; case HEAPMENU_ALLOC_1K: case HEAPMENU_ALLOC_2K: case HEAPMENU_ALLOC_5K: case HEAPMENU_ALLOC_10K: case HEAPMENU_ALLOC_25K: case HEAPMENU_ALLOC_50K: hourglass = LoadCursor( NULL, IDC_WAIT ); SetCapture( hwnd ); oldcursor= SetCursor( hourglass ); AllocMore( wparam ); UpdateAllocInfo( info->alloc_dialog ); SetCursor( oldcursor ); ReleaseCapture(); PaintAllWindows(); break; case HEAPMENU_ALLOC_ALL: case HEAPMENU_ALLOC_BUT_1K: case HEAPMENU_ALLOC_BUT_2K: case HEAPMENU_ALLOC_BUT_5K: case HEAPMENU_ALLOC_BUT_10K: case HEAPMENU_ALLOC_BUT_25K: case HEAPMENU_ALLOC_BUT_50K: hourglass = LoadCursor( NULL, IDC_WAIT ); SetCapture( hwnd ); oldcursor= SetCursor( hourglass ); AllocAllBut( wparam ); UpdateAllocInfo( info->alloc_dialog ); SetCursor( oldcursor ); ReleaseCapture(); PaintAllWindows(); break; case HEAPMENU_ALLOC_NK: case HEAPMENU_ALLOC_BUT_NK: case HEAPMENU_FREE_NK: DoNBytes( hwnd, wparam ); UpdateAllocInfo( info->alloc_dialog ); PaintAllWindows(); break; case HEAPMENU_ADD: info->add_dialog = StartAdd( hwnd, &info->list ); if( info->add_dialog != NULL ) { info->doing_add = TRUE; info->need_refresh = FALSE; } else { ErrorBox( hwnd, STR_UNABLE_TO_ADD, MB_OK| MB_ICONINFORMATION ); } break; } break; case WM_USER: /* an owned window is being destroyed make sure * Windows doesn't take the focus away from us*/ NoRefresh = TRUE; SetFocus( hwnd ); NoRefresh = FALSE; break; default: return( DefWindowProc( hwnd, msg, wparam, lparam ) ); } return( FALSE ); } /* HeapWalkProc */