asCScriptObject::asCScriptObject(asCObjectType *ot)
{
	refCount.set(1);
	objType          = ot;
	objType->AddRef();
	isDestructCalled = false;

	// Notify the garbage collector of this object
	if( objType->flags & asOBJ_GC )
		objType->engine->gc.AddScriptObjectToGC(this, objType);

	// Construct all properties
	asCScriptEngine *engine = objType->engine;
	for( asUINT n = 0; n < objType->properties.GetLength(); n++ )
	{
		asCObjectProperty *prop = objType->properties[n];
		if( prop->type.IsObject() )
		{
			size_t *ptr = (size_t*)(((char*)this) + prop->byteOffset);

			if( prop->type.IsObjectHandle() )
				*ptr = 0;
			else
			{
				// Allocate the object and call it's constructor
				*ptr = (size_t)AllocateObject(prop->type.GetObjectType(), engine);
			}
		}
	}
}
예제 #2
0
Bool LoadObject(int object_id,char *class_name)
{
   class_node *c;

   c = GetClassByName(class_name);
   if (c == NULL) 
   {
      eprintf("LoadObject can't find class name %s\n",class_name);
      return False;
   }

   if (AllocateObject(c->class_id) != object_id)
   {
      eprintf("LoadObject didn't make object id %i\n",object_id);
      return False;
   }

   /* set self = prop 0 */
   objects[object_id].p[0].id = 0;
   objects[object_id].p[0].val.v.tag = TAG_OBJECT; 
   objects[object_id].p[0].val.v.data = object_id;

   /* if no kod changed, then setting the properties shouldn't be
    * necessary.  however, who knows.
    */
   SetObjectProperties(object_id,c);

   return True;
}
예제 #3
0
FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameUNSAFE)
{
    FCALL_CONTRACT;

    struct _gc
    {
        ASSEMBLYNAMEREF result;
        STRINGREF       filename;
    } gc;

    gc.result   = NULL;
    gc.filename = (STRINGREF) filenameUNSAFE;

    HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);

    if (gc.filename == NULL)
        COMPlusThrow(kArgumentNullException, W("ArgumentNull_FileName"));

    if (gc.filename->GetStringLength() == 0)
        COMPlusThrow(kArgumentException, W("Argument_EmptyFileName"));

    gc.result = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME));


    ///////////////////////////////////////////////
    SString sFileName(gc.filename->GetBuffer());
    PEImageHolder pImage = PEImage::OpenImage(sFileName, MDInternalImport_NoCache);

    EX_TRY
    {
#ifdef FEATURE_CORECLR
        // Allow AssemblyLoadContext.GetAssemblyName for native images on CoreCLR
        if (pImage->HasNTHeaders() && pImage->HasCorHeader() && pImage->HasNativeHeader())
            pImage->VerifyIsNIAssembly();
        else
            pImage->VerifyIsAssembly();
#else
        pImage->VerifyIsAssembly();
#endif
    }
    EX_CATCH
    {
        Exception *ex = GET_EXCEPTION();
        EEFileLoadException::Throw(sFileName,ex->GetHR(),ex);
    }
    EX_END_CATCH_UNREACHABLE;

    SString sUrl = sFileName;
    PEAssembly::PathToUrl(sUrl);

    AssemblySpec spec;
    spec.InitializeSpec(TokenFromRid(mdtAssembly,1),pImage->GetMDImport(),NULL,TRUE);
    spec.SetCodeBase(sUrl);
    spec.AssemblyNameInit(&gc.result, pImage);
    
    HELPER_METHOD_FRAME_END();
    return OBJECTREFToObject(gc.result);
}
예제 #4
0
파일: drives.c 프로젝트: mingpen/OpenNT
LPDRIVE_INFO
CreateDriveInfoStructure(
    void
    )

/*++

Routine Description:

    Create a DRIVE_INFO object for the supplied drive.

Arguments:

    None

Return Value:

    LPDRIVE_INFO    - Allocates and returns a pointer to a DRIVE_INFO object

--*/

{
    LPDRIVE_INFO    DriveInfo;

    //
    // Allocate a DRIVE_INFO object.
    //

    DriveInfo = AllocateObject( DRIVE_INFO, 1 );
    DbgPointerAssert( DriveInfo );
    if( DriveInfo == NULL ) {
        return NULL;
    }

    //
    // Initialize buffers with empty strings.
    //

    ZeroMemory( DriveInfo, sizeof(DRIVE_INFO) );

    //
    // Set the signature
    //
    SetSignature( DriveInfo );

    //
    // Mark Structure as invalid since it is not filled out yet.
    //
    DriveInfo->ValidDetails = FALSE;


    return DriveInfo;
}
예제 #5
0
static OBJECTREF GetOleAutBinder()
{
    THROWSCOMPLUSEXCEPTION();

    // If we have already create the instance of the OleAutBinder then simply return it.
    if (s_hndOleAutBinder)
        return ObjectFromHandle(s_hndOleAutBinder);

    MethodTable *pOleAutBinderClass = g_Mscorlib.GetClass(CLASS__OLE_AUT_BINDER);

    // Allocate an instance of the OleAutBinder class.
    OBJECTREF OleAutBinder = AllocateObject(pOleAutBinderClass);

    // Keep a handle to the OleAutBinder instance.
    s_hndOleAutBinder = CreateGlobalHandle(OleAutBinder);

    return OleAutBinder;
}
예제 #6
0
int CreateObject(int class_id,int num_parms,parm_node parms[])
{
   int new_object_id;
   class_node *c;

   new_object_id = AllocateObject(class_id);

   if (new_object_id == INVALID_OBJECT)
      return INVALID_OBJECT;
   
   /* set self = prop 0 */
   objects[new_object_id].p[0].id = 0; 
   objects[new_object_id].p[0].val.v.tag = TAG_OBJECT; 
   objects[new_object_id].p[0].val.v.data = new_object_id;

   c = GetClassByID(class_id);
   if (c == NULL) /* can't ever be, because AllocateObject checks */
   {
      eprintf("CreateObject can't find class id %i\n",class_id);
      return INVALID_OBJECT;
   }

   SetObjectProperties(new_object_id,c);

   /* might not be top level message, since can be called from blakod.  If it
      really IS a top level message, then it better not post anything, since
      post messages won't be handled */
   if (IsInterpreting())
      SendBlakodMessage(new_object_id,CONSTRUCTOR_MSG,num_parms,parms);
   else
      SendTopLevelBlakodMessage(new_object_id,CONSTRUCTOR_MSG,num_parms,parms);

   if (ConfigBool(DEBUG_UNINITIALIZED))
   {
      int i;
      for (i = 0; i < (1+c->num_properties); i++)
	 if (objects[new_object_id].p[i].val.v.tag == TAG_INVALID)
	    eprintf("Uninitialized properties after constructor, class %s\n",
	       c->class_name);
   }

   return new_object_id;
}
예제 #7
0
파일: corhost.cpp 프로젝트: ArildF/masters
HRESULT CorHost::CreateEvidence(IUnknown **pEvidence)
{
    HRESULT hr = S_OK;
    if (!pEvidence)
        return E_POINTER;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();
    // Create the domain. 
    Thread* pThread = GetThread();
    if (!pThread)
        IfFailGo(E_UNEXPECTED);

    IfFailGo(QuickCOMStartup());

    BOOL fWasGCEnabled;
    fWasGCEnabled = !pThread->PreemptiveGCDisabled();
    if (fWasGCEnabled)
        pThread->DisablePreemptiveGC();

    COMPLUS_TRY {
        struct _gc {
            OBJECTREF pEvidence;
        } gc;
        ZeroMemory(&gc, sizeof(gc));

        MethodTable* pMT = g_Mscorlib.GetClass(CLASS__EVIDENCE);
        GCPROTECT_BEGIN(gc);
        gc.pEvidence = AllocateObject(pMT);
        IfFailThrow(QuickCOMStartup());   
        *pEvidence = GetComIPFromObjectRef((OBJECTREF*) &gc.pEvidence);
        GCPROTECT_END();
    } COMPLUS_CATCH {
        hr = SecurityHelper::MapToHR(GETTHROWABLE());
    } COMPLUS_END_CATCH
          
    if (fWasGCEnabled)
        pThread->EnablePreemptiveGC();

ErrExit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return hr;
}
예제 #8
0
파일: corhost.cpp 프로젝트: ArildF/masters
HRESULT CorHost::CreateDomainSetup(IUnknown **pAppDomainSetup)
{
    HRESULT hr = S_OK;

    if (!pAppDomainSetup)
        return E_POINTER;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();
    // Create the domain. 
    Thread* pThread = GetThread();
    if (!pThread)
        IfFailGo(E_UNEXPECTED);

    IfFailGo(QuickCOMStartup());

    BEGIN_ENSURE_COOPERATIVE_GC();

    COMPLUS_TRY {
        struct _gc {
            OBJECTREF pSetup;
        } gc;
        ZeroMemory(&gc, sizeof(gc));

        MethodTable* pMT = g_Mscorlib.GetClass(CLASS__APPDOMAIN_SETUP);
        GCPROTECT_BEGIN(gc);
        gc.pSetup = AllocateObject(pMT);
        IfFailThrow(QuickCOMStartup());   
        *pAppDomainSetup = GetComIPFromObjectRef((OBJECTREF*) &gc.pSetup);
        GCPROTECT_END();
    } COMPLUS_CATCH {
        hr = SecurityHelper::MapToHR(GETTHROWABLE());
    } COMPLUS_END_CATCH
          
    END_ENSURE_COOPERATIVE_GC();

 ErrExit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return hr;
}
asCScriptStruct::asCScriptStruct(asCObjectType *ot)
{
	gc.Init(ot);

	// Construct all properties
	asCScriptEngine *engine = gc.objType->engine;
	for( asUINT n = 0; n < gc.objType->properties.GetLength(); n++ )
	{
		asCProperty *prop = gc.objType->properties[n];
		if( prop->type.IsObject() )
		{
			size_t *ptr = (size_t*)(((char*)this) + prop->byteOffset);

			if( prop->type.IsObjectHandle() )
				*ptr = 0;
			else
			{
				// Allocate the object and call it's constructor
				*ptr = (size_t)AllocateObject(prop->type.GetObjectType(), engine);
			}
		}
	}
}
예제 #10
0
int __cdecl main(int argc, char* argv[])
{
    //
    // Initialize system info
    //
    if (!GCToOSInterface::Initialize())
    {
        return -1;
    }

    // 
    // Initialize free object methodtable. The GC uses a special array-like methodtable as placeholder
    // for collected free space.
    //
    static MethodTable freeObjectMT;
    freeObjectMT.InitializeFreeObject();
    g_pFreeObjectMethodTable = &freeObjectMT;

    //
    // Initialize GC heap
    //
    GcDacVars dacVars;
    IGCHeap *pGCHeap;
    IGCHandleManager *pGCHandleManager;
    if (!InitializeGarbageCollector(nullptr, &pGCHeap, &pGCHandleManager, &dacVars))
    {
        return -1;
    }

    if (FAILED(pGCHeap->Initialize()))
        return -1;

    //
    // Initialize handle manager
    //
    if (!pGCHandleManager->Initialize())
        return -1;

    //
    // Initialize current thread
    //
    ThreadStore::AttachCurrentThread();

    //
    // Create a Methodtable with GCDesc
    //

    class My : Object {
    public:
        Object * m_pOther1;
        int dummy_inbetween;
        Object * m_pOther2;
    };

    static struct My_MethodTable
    {
        // GCDesc
        CGCDescSeries m_series[2];
        size_t m_numSeries;

        // The actual methodtable
        MethodTable m_MT;
    }
    My_MethodTable;

    // 'My' contains the MethodTable*
    uint32_t baseSize = sizeof(My);
    // GC expects the size of ObjHeader (extra void*) to be included in the size.
    baseSize = baseSize + sizeof(ObjHeader);
    // Add padding as necessary. GC requires the object size to be at least MIN_OBJECT_SIZE.
    My_MethodTable.m_MT.m_baseSize = max(baseSize, MIN_OBJECT_SIZE);

    My_MethodTable.m_MT.m_componentSize = 0;    // Array component size
    My_MethodTable.m_MT.m_flags = MTFlag_ContainsPointers;

    My_MethodTable.m_numSeries = 2;

    // The GC walks the series backwards. It expects the offsets to be sorted in descending order.
    My_MethodTable.m_series[0].SetSeriesOffset(offsetof(My, m_pOther2));
    My_MethodTable.m_series[0].SetSeriesCount(1);
    My_MethodTable.m_series[0].seriessize -= My_MethodTable.m_MT.m_baseSize;

    My_MethodTable.m_series[1].SetSeriesOffset(offsetof(My, m_pOther1));
    My_MethodTable.m_series[1].SetSeriesCount(1);
    My_MethodTable.m_series[1].seriessize -= My_MethodTable.m_MT.m_baseSize;

    MethodTable * pMyMethodTable = &My_MethodTable.m_MT;

    // Allocate instance of MyObject
    Object * pObj = AllocateObject(pMyMethodTable);
    if (pObj == NULL)
        return -1;

    // Create strong handle and store the object into it
    OBJECTHANDLE oh = HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_DEFAULT, pObj);
    if (oh == NULL)
        return -1;

    for (int i = 0; i < 1000000; i++)
    {
        Object * pBefore = ((My *)HndFetchHandle(oh))->m_pOther1;

        // Allocate more instances of the same object
        Object * p = AllocateObject(pMyMethodTable);
        if (p == NULL)
            return -1;

        Object * pAfter = ((My *)HndFetchHandle(oh))->m_pOther1;

        // Uncomment this assert to see how GC triggered inside AllocateObject moved objects around
        // assert(pBefore == pAfter);

        // Store the newly allocated object into a field using WriteBarrier
        WriteBarrier(&(((My *)HndFetchHandle(oh))->m_pOther1), p);
    }

    // Create weak handle that points to our object
    OBJECTHANDLE ohWeak = HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_WEAK_DEFAULT, HndFetchHandle(oh));
    if (ohWeak == NULL)
        return -1;

    // Destroy the strong handle so that nothing will be keeping out object alive
    HndDestroyHandle(HndGetHandleTable(oh), HNDTYPE_DEFAULT, oh);

    // Explicitly trigger full GC
    pGCHeap->GarbageCollect();

    // Verify that the weak handle got cleared by the GC
    assert(HndFetchHandle(ohWeak) == NULL);

    printf("Done\n");

    return 0;
}
예제 #11
0
파일: resp.c 프로젝트: mingpen/OpenNT
BOOL InitializeSystemResourceLists(
    IN HREGKEY hRegKey
    )

/*++

Routine Description:

    InitializeSystemResourceLists recursively walks the resource map in the
    registry and builds the SYSTEM_RESOURCE lists. This is a data structure
    that links all resources of the same type together, as well as linking all
    resources belonging to a specific device/driver together. Lastly each
    resource is independently linked to the device/driver that owns it. This
    leds to a 'mesh' of linked lists with back pointers to the owning
    device/driver object.

Arguments:

    hRegKey - Supplies a handle to a REGKEY object where the search is to
              continue.

Return Value:

    BOOL    - returns TRUE if the resource lists are succesfully built.

--*/

{
    BOOL    Success;
    HREGKEY hRegSubkey;

    DbgHandleAssert( hRegKey );

    //
    // While there are still more device/driver resource descriptors...
    //

    while( QueryNextValue( hRegKey )) {

        PCM_FULL_RESOURCE_DESCRIPTOR    FullResource;
        LPSYSTEM_RESOURCES              SystemResource;
        LPDEVICE                        Device;
        LPTSTR                          Extension;
        DWORD                           Count;
        DWORD                           i;
        DWORD                           j;

        //
        // Based on the type of key, prepare to walk the list of
        // RESOURCE_DESCRIPTORS (the list may be one in length).
        //

        if( hRegKey->Type == REG_FULL_RESOURCE_DESCRIPTOR ) {

            Count           = 1;
            FullResource    = ( PCM_FULL_RESOURCE_DESCRIPTOR ) hRegKey->Data;

        } else if( hRegKey->Type == REG_RESOURCE_LIST ) {

            Count           = (( PCM_RESOURCE_LIST ) hRegKey->Data )->Count;
            FullResource    = (( PCM_RESOURCE_LIST ) hRegKey->Data )->List;

        } else {

            DbgAssert( FALSE );
            continue;
        }

        //
        // Allocate a DEVICE object.
        //

        Device = AllocateObject( DEVICE, 1 );
        DbgPointerAssert( Device );
        if( Device == NULL ) {
            Success = DestroySystemResourceLists( _SystemResourceLists );
            DbgAssert( Success );
            return FALSE;
        }

        //
        // Allocate a buffer for the device/driver name. The maximum size of
        // the name will be the number of characters in both the key and
        // value name.
        //

        Device->Name = AllocateObject(
                            TCHAR,
                              _tcslen( hRegKey->Name )
                            + _tcslen( hRegKey->ValueName )
                            + sizeof( TCHAR )
                            );
        DbgPointerAssert( Device->Name );
        if( Device->Name == NULL ) {
            Success = DestroySystemResourceLists( _SystemResourceLists );
            DbgAssert( Success );
            return FALSE;
        }

        //
        // Rationalize the device name such that it is of the form Device.Raw
        // or Device.Translated.
        //

        Device->Name[ 0 ] = TEXT( '\0' );
        if(     ( _tcsnicmp( hRegKey->ValueName, TEXT( ".Raw" ), 4 ) == 0 )
            ||  ( _tcsnicmp( hRegKey->ValueName, TEXT( ".Translated" ), 11 ) == 0 )) {

            _tcscpy( Device->Name, hRegKey->Name );
        }
        _tcscat( Device->Name, hRegKey->ValueName );

        //
        // Based on the device name, determine if the resource descriptors
        // should be added to the RAW or TRANSLATED lists.
        //

        if( Extension = _tcsstr( Device->Name, TEXT( ".Raw" ))) {

            SystemResource = &_SystemResourceLists[ RAW ];

        } else if( Extension = _tcsstr( Device->Name, TEXT( ".Translated" ))) {

            SystemResource = &_SystemResourceLists[ TRANSLATED ];

        } else {

            DbgAssert( FALSE );
            Success = DestroySystemResourceLists( _SystemResourceLists );
            DbgAssert( Success );
            return FALSE;
        }

        //
        // Strip off the extension (.Raw or .Translated) from the device name.
        //

        Device->Name[ Extension - Device->Name ] = TEXT( '\0' );

        //
        // Set the signature in the DEVICE object.
        //

        SetSignature( Device );

        //
        // If the DEVICE object list is empty, add the device to the beginning
        // of the list else add it to the end of the list.
        //

        if( SystemResource->DeviceHead == NULL ) {

            SystemResource->DeviceHead = Device;
            SystemResource->DeviceTail = Device;

        } else {

            LPDEVICE    ExistingDevice;

            //
            // See if the DEVICE object is already in the list.
            //

            ExistingDevice = SystemResource->DeviceHead;
            while( ExistingDevice ) {

                if( _tcsicmp( ExistingDevice->Name, Device->Name ) == 0 ) {
                    break;
                }
                ExistingDevice = ExistingDevice->Next;
            }

            //
            // If the DEVICE object is not already in the list, add it else
            // free the DEICE object.
            //

            if( ExistingDevice == NULL ) {

                SystemResource->DeviceTail->Next = Device;
                SystemResource->DeviceTail       = Device;

            } else {

                Success = FreeObject( Device );
                DbgAssert( Success );
            }
        }

        //
        // NULL terminate the DEVICE object list.
        //

        SystemResource->DeviceTail->Next = NULL;

        //
        // For each CM_FULL_RESOURCE DESCRIPTOR in the current value...
        //

        for( i = 0; i < Count; i++ ) {

            PCM_PARTIAL_RESOURCE_DESCRIPTOR   PartialResourceDescriptor;

            //
            // For each CM_PARTIAL_RESOURCE_DESCRIPTOR in the list...
            //

            for( j = 0; j < FullResource->PartialResourceList.Count; j++ ) {

                LPRESOURCE_DESCRIPTOR   ResourceDescriptor;
                LPRESOURCE_DESCRIPTOR*  Head;
                LPRESOURCE_DESCRIPTOR*  Tail;

                //
                // Allocate a RESOURCE_DESCRIPTOR object.
                //

                ResourceDescriptor = AllocateObject( RESOURCE_DESCRIPTOR, 1 );
                DbgPointerAssert( ResourceDescriptor );
                if( ResourceDescriptor == NULL ) {
                    Success = DestroySystemResourceLists( _SystemResourceLists );
                    DbgAssert( Success );
                    return FALSE;
                }

                //
                // Get a pointer to the current CM_PARTIAL_RESOURCE_DESCRIPTOR
                // in the current CM_FULLRESOURCE_DESCRIPTOR in the list.
                //

                PartialResourceDescriptor = &( FullResource[ i ].PartialResourceList.PartialDescriptors[ j ]);

                //
                // Based on the resource type grab the pointers to the head and
                // tail of the appropriate list.
                //

                switch( PartialResourceDescriptor->Type ) {

                case CmResourceTypePort:

                    Head = &SystemResource->PortHead;
                    Tail = &SystemResource->PortTail;
                    break;

                case CmResourceTypeInterrupt:

                    Head = &SystemResource->InterruptHead;
                    Tail = &SystemResource->InterruptTail;
                    break;

                case CmResourceTypeMemory:

                    Head = &SystemResource->MemoryHead;
                    Tail = &SystemResource->MemoryTail;
                    break;

                case CmResourceTypeDma:

                    Head = &SystemResource->DmaHead;
                    Tail = &SystemResource->DmaTail;
                    break;

                case CmResourceTypeDeviceSpecific:

                    //
                    // Since device specific data is not be collected, free the
                    // associated RESOURCCE_DESCRIPTOR object.
                    //

                    Success = FreeObject( ResourceDescriptor );
                    DbgAssert( Success );
                    break;

                default:

                    DbgPrintf(( L"Winmsd : Unknown PartialResourceDescriptor->Type == %1!d!\n", PartialResourceDescriptor->Type ));
                    continue;
                }

                //
                // If the list is empty add the RESOURCE_DESCRIPTOR object to
                // the beginning of the list, else add it to the end.
                //

                if( *Head == NULL ) {

                    *Head = ResourceDescriptor;
                    *Tail = ResourceDescriptor;

                } else {

                    ( *Tail )->NextSame = ResourceDescriptor;
                    *Tail = ResourceDescriptor;
                }

                //
                // NULL terminate the list.
                //

                ( *Tail )->NextSame = NULL;

                //
                // Make a copy of the actual resource descriptor data.
                //

                CopyMemory(
                    &ResourceDescriptor->CmResourceDescriptor,
                    PartialResourceDescriptor,
                    sizeof( CM_PARTIAL_RESOURCE_DESCRIPTOR )
                    );

                //
                // Note the owner (device/driver) of this resource descriptor.
                //

                ResourceDescriptor->Owner = SystemResource->DeviceTail;

                //
                // The RESOURCE_DESCRIPTOR is complete so set its signature.
                //

                SetSignature( ResourceDescriptor );

                //
                // Add the RESOURCE_DESCRIPTOR to the list of resources owned
                // by the current DEVICE.
                //

                if( SystemResource->DeviceTail->ResourceDescriptorHead == NULL ) {

                    SystemResource->DeviceTail->ResourceDescriptorHead
                        = ResourceDescriptor;

                    SystemResource->DeviceTail->ResourceDescriptorTail
                        = ResourceDescriptor;

                } else {

                    SystemResource->DeviceTail->ResourceDescriptorTail->NextDiff
                        = ResourceDescriptor;

                    SystemResource->DeviceTail->ResourceDescriptorTail
                        = ResourceDescriptor;

                }

                //
                // NULL terminate the list.
                //

                SystemResource->DeviceTail->ResourceDescriptorTail->NextDiff
                    = NULL;
            }

            //
            // Get the next CM_FULL_RESOURCE_DESCRIPTOR from the list.
            //

            FullResource = ( PCM_FULL_RESOURCE_DESCRIPTOR )( PartialResourceDescriptor + 1 );
        }
    }

    //
    // Traverse the list of keys in the resource descriptor portion of the
    // registry and continue building the lists.
    //

    while(( hRegSubkey = QueryNextSubkey( hRegKey )) != NULL ) {

        Success = InitializeSystemResourceLists( hRegSubkey );
        DbgAssert( Success );
        if( Success == FALSE ) {

            Success = DestroySystemResourceLists( _SystemResourceLists );
            DbgAssert( Success );
            return FALSE;
        }

        Success = CloseRegistryKey( hRegSubkey );
        DbgAssert( Success );
        if( Success == FALSE ) {

            Success = DestroySystemResourceLists( _SystemResourceLists );
            DbgAssert( Success );
            return FALSE;
        }
    }

    //
    // Set the signatures in both of the fully initialized lists.
    //

    SetSignature( &_SystemResourceLists[ RAW ]);
    SetSignature( &_SystemResourceLists[ TRANSLATED ]);

    return TRUE;
}
예제 #12
0
//+----------------------------------------------------------------------------
//
//  Function:   CallDescrWithObjectArray, private
//
//  Synopsis:   Builds the stack from a object array and call the object
//
// Note this function triggers GC and assumes that pServer, pArguments, pVarRet, and ppVarOutParams are
// all already protected!!
//+----------------------------------------------------------------------------
void CallDescrWithObjectArray(OBJECTREF& pServer, 
                  ReflectMethod *pRM, 
                  const BYTE *pTarget, 
                  MetaSig* sig, 
                  VASigCookie *pCookie,
                  BOOL fIsStatic,  
                  PTRARRAYREF& pArgArray,
                  OBJECTREF *pVarRet,
                  PTRARRAYREF *ppVarOutParams) 
{
    THROWSCOMPLUSEXCEPTION();
    TRIGGERSGC();       // the debugger, profiler code triggers a GC

    LOG((LF_REMOTING, LL_INFO10,
         "CallDescrWithObjectArray IN\n"));

    ByRefInfo *pByRefs = NULL;
    INT64 retval = 0;
    UINT  nActualStackBytes = 0;
    LPBYTE pAlloc = 0;
    LPBYTE pFrameBase = 0;
    UINT32 numByRef = 0;
    DWORD attr = pRM->dwFlags;
#ifdef _DEBUG
    MethodDesc *pMD = pRM->pMethod;
#endif

    // check the calling convention

    BYTE callingconvention = sig->GetCallingConvention();
    if (!isCallConv(callingconvention, IMAGE_CEE_CS_CALLCONV_DEFAULT))
    {
        _ASSERTE(!"This calling convention is not supported.");
        COMPlusThrow(kInvalidProgramException);
    }

#ifdef DEBUGGING_SUPPORTED
    // debugger goo What does this do? can someone put a comment here?
    if (CORDebuggerTraceCall())
        g_pDebugInterface->TraceCall(pTarget);
#endif // DEBUGGING_SUPPORTED

#ifdef PROFILING_SUPPORTED
    // If we're profiling, notify the profiler that we're about to invoke the remoting target
    if (CORProfilerTrackRemoting())
        g_profControlBlock.pProfInterface->RemotingServerInvocationStarted(
            reinterpret_cast<ThreadID>(GetThread()));
#endif // PROFILING_SUPPORTED
        
    // Create a fake FramedMethodFrame on the stack.
    nActualStackBytes = sig->SizeOfActualFixedArgStack(fIsStatic);
    pAlloc = (LPBYTE)_alloca(FramedMethodFrame::GetNegSpaceSize() + sizeof(FramedMethodFrame) + nActualStackBytes);
    pFrameBase = pAlloc + FramedMethodFrame::GetNegSpaceSize();


    // cycle through the parameters and see if there are byrefs

    BYTE typ = 0;
    BOOL   fHasByRefs = FALSE;

    if (attr & RM_ATTR_BYREF_FLAG_SET)
        fHasByRefs = attr & RM_ATTR_HAS_BYREF_ARG;
    else
    {
        sig->Reset();
        while ((typ = sig->NextArg()) != ELEMENT_TYPE_END)
        {
            if (typ == ELEMENT_TYPE_BYREF)
            {
                fHasByRefs = TRUE;
                attr |= RM_ATTR_HAS_BYREF_ARG;
                break;
            }
        }
        attr |= RM_ATTR_BYREF_FLAG_SET;
        pRM->dwFlags = attr;
        sig->Reset();
    }

    int nFixedArgs = sig->NumFixedArgs();
    // if there are byrefs allocate and array for the out parameters

    if (fHasByRefs)
    {
        *ppVarOutParams = PTRARRAYREF(AllocateObjectArray(sig->NumFixedArgs(), g_pObjectClass));

        // Null out the array
        memset(&(*ppVarOutParams)->m_Array, 0, sizeof(OBJECTREF) * sig->NumFixedArgs());
    }

    ArgIterator argit(pFrameBase, sig, fIsStatic);

    // set the this pointer
    OBJECTREF *ppThis = (OBJECTREF*)argit.GetThisAddr();
    *ppThis = NULL;

    // if there is a return buffer, allocate it
    if (sig->HasRetBuffArg()) 
    {
        EEClass *pEECValue = sig->GetRetEEClass();
        _ASSERTE(pEECValue->IsValueClass());
        MethodTable * mt = pEECValue->GetMethodTable();
        *pVarRet = AllocateObject(mt);

        *(argit.GetRetBuffArgAddr()) = (*pVarRet)->UnBox();

#if defined(_PPC_) || defined(_SPARC_) // retbuf
        // the CallDescrWorker callsite for methods with return buffer is 
        //  different for RISC CPUs - we pass this information along by setting 
        //  the lowest bit in pTarget
        pTarget = (const BYTE *)((UINT_PTR)pTarget | 0x1);
#endif
    }



    // gather data about the parameters by iterating over the sig:
    UINT32 arg = 0;    
    UINT32 structSize = 0;
    int    ofs = 0;
    // REVIEW: need to use actual arg count if VarArgs are supported
    ArgInfo* pArgInfo = (ArgInfo*) _alloca(nFixedArgs*sizeof(ArgInfo));
#ifdef _DEBUG
    // We expect to write useful data over every part of this so need
    // not do this in retail!
    memset((void *)pArgInfo, 0, sizeof(ArgInfo)*nFixedArgs);
#endif
    for( ; 0 != (ofs = argit.GetNextOffset(&typ, &structSize)); arg++, pArgInfo++ )
    {


        if (typ == ELEMENT_TYPE_BYREF)
        {
            EEClass *pClass = NULL;
            CorElementType brType = sig->GetByRefType(&pClass);
            if (CorIsPrimitiveType(brType))
            {
                pArgInfo->dataSize = gElementTypeInfo[brType].m_cbSize;
            }
            else if (pClass->IsValueClass())
            {
                pArgInfo->dataSize = pClass->GetAlignedNumInstanceFieldBytes();
                numByRef ++;
            }
            else
            {

                pArgInfo->dataSize = sizeof(Object *);
                numByRef ++;
            }
            ByRefInfo *brInfo = (ByRefInfo *) _alloca(offsetof(ByRefInfo,data) + pArgInfo->dataSize);
            brInfo->argIndex = arg;
            brInfo->typ = brType;
            brInfo->pClass = pClass;
            brInfo->pNext = pByRefs;
            pByRefs = brInfo;
            pArgInfo->dataLocation = (BYTE*)brInfo->data;
            *((void**)(pFrameBase + ofs)) = (void*)pArgInfo->dataLocation;
            pArgInfo->dataClass = pClass;
            pArgInfo->dataType = brType;
            pArgInfo->byref = TRUE;
        }
        else
        {
            pArgInfo->dataLocation = pFrameBase + ofs;
            pArgInfo->dataSize = StackElemSize(structSize);
            pArgInfo->dataClass = sig->GetTypeHandle().GetClass(); // this may cause GC!
            pArgInfo->dataType = typ;
            pArgInfo->byref = FALSE;
        }  
    }

    if (!fIsStatic) {
        // If this isn't a value class, verify the objectref
#ifdef _DEBUG
        if (pMD->GetClass()->IsValueClass() == FALSE)
        {
            VALIDATEOBJECTREF(pServer);
        }
#endif //_DEBUG
        *ppThis = pServer;
     }

    // There should be no GC when we fill up the stack with parameters, as we don't protect them
    // Assignment of "*ppThis" above triggers the point where we become unprotected.
    BEGINFORBIDGC();


    // reset pArgInfo to point to the start of the block we _alloca-ed
    pArgInfo = pArgInfo-nFixedArgs;

    PBYTE             dataLocation;
    INT32             dataSize;
    EEClass          *dataClass;
    BYTE              dataType;

    OBJECTREF* pArguments = pArgArray->m_Array;
    UINT32 i, j = arg;
    for (i=0; i<j; i++)
    {
        dataSize = pArgInfo->dataSize;
        dataLocation = pArgInfo->dataLocation;
        dataClass = pArgInfo->dataClass;
        dataType = pArgInfo->dataType;

        switch (dataSize) 
        {
            case 1:
                // This "if" statement is necessary to make the assignement big-endian aware
                if (pArgInfo->byref)
                    *((INT8*)dataLocation) = *((INT8*)pArguments[i]->GetData());
                else
                    *(StackElemType*)dataLocation = (StackElemType)*((INT8*)pArguments[i]->GetData());
                break;
            case 2:
                // This "if" statement is necessary to make the assignement big-endian aware
                if (pArgInfo->byref)
                    *((INT16*)dataLocation) = *((INT16*)pArguments[i]->GetData());
                else
                    *(StackElemType*)dataLocation = (StackElemType)*((INT16*)pArguments[i]->GetData());
                break;
            case 4:
                if ((dataType == ELEMENT_TYPE_STRING)  ||
                    (dataType == ELEMENT_TYPE_OBJECT)  ||
                    (dataType == ELEMENT_TYPE_CLASS)   ||
                    (dataType == ELEMENT_TYPE_SZARRAY) ||
                    (dataType == ELEMENT_TYPE_ARRAY))
                {
                    *(OBJECTREF *)dataLocation = pArguments[i];
                }
                else
                {
                    *(StackElemType*)dataLocation = (StackElemType)*((INT32*)pArguments[i]->GetData());
                }
                break;

            case 8:
                *((INT64*)dataLocation) = *((INT64*)pArguments[i]->GetData());
                break;

            default:
            {
                memcpy(dataLocation, pArguments[i]->UnBox(), dataSize);
            }
        }

        pArgInfo++;
    }
#ifdef _DEBUG
    // Should not be using this any more
    pArgInfo = pArgInfo - nFixedArgs;
    memset((void *)pArgInfo, 0, sizeof(ArgInfo)*nFixedArgs);
#endif

    // if there were byrefs, push a protection frame

    ProtectByRefsFrame *pProtectionFrame = NULL;    
    if (pByRefs && numByRef > 0)
    {
        char *pBuffer = (char*)_alloca (sizeof (ProtectByRefsFrame));
        pProtectionFrame = new (pBuffer) ProtectByRefsFrame(GetThread(), pByRefs);
    }

    // call the correct worker function depending of if the method
    // is varargs or not

    ENDFORBIDGC();

#ifdef _PPC_
    FramedMethodFrame::Enregister(pFrameBase, sig, fIsStatic, nActualStackBytes);
#endif

    INSTALL_COMPLUS_EXCEPTION_HANDLER();

    retval = CallDescrWorker(
                pFrameBase + sizeof(FramedMethodFrame) + nActualStackBytes,
                nActualStackBytes / STACK_ELEM_SIZE,
#if defined(_X86_) || defined(_PPC_) // argregs
                (ArgumentRegisters*)(pFrameBase + FramedMethodFrame::GetOffsetOfArgumentRegisters()),
#endif
                (LPVOID)pTarget);

    UNINSTALL_COMPLUS_EXCEPTION_HANDLER();

    // set floating point return values

    getFPReturn(sig->GetFPReturnSize(), &retval);

    // need to build a object based on the return type.
    
    if (!sig->HasRetBuffArg()) 
    {
        BYTE *pRetVal = (BYTE*)&retval;

#ifdef BIGENDIAN
        switch (sig->GetReturnTypeSize())
        {
        case 1:
            pRetVal += sizeof(void*)-1;
            break;
        case 2:
            pRetVal += sizeof(void*)-2;
            break;
        default:
            // nothing to do
            break;
        }
#endif

        GetObjectFromStack(pVarRet, pRetVal, sig->GetReturnType(), sig->GetRetEEClass());
    }

    // extract the out args from the byrefs

    if (pByRefs)
    {     
        do
        {
            // Always extract the data ptr every time we enter this loop because
            // calls to GetObjectFromStack below can cause a GC.
            // Even this is not enough, because that we are passing a pointer to GC heap
            // to GetObjectFromStack .  If GC happens, nobody is protecting the passed in pointer.

            OBJECTREF pTmp = NULL;
            GetObjectFromStack(&pTmp, pByRefs->data, pByRefs->typ, pByRefs->pClass);
            (*ppVarOutParams)->SetAt(pByRefs->argIndex, pTmp);
            pByRefs = pByRefs->pNext;
        }
        while (pByRefs);
        if (pProtectionFrame) pProtectionFrame->Pop();
    }

#ifdef PROFILING_SUPPORTED
    // If we're profiling, notify the profiler that we're about to invoke the remoting target
    if (CORProfilerTrackRemoting())
        g_profControlBlock.pProfInterface->RemotingServerInvocationReturned(
            reinterpret_cast<ThreadID>(GetThread()));
#endif // PROFILING_SUPPORTED

    LOG((LF_REMOTING, LL_INFO10, "CallDescrWithObjectArray OUT\n"));
}
예제 #13
0
파일: clb.c 프로젝트: mingpen/OpenNT
BOOL
ClbSetColumnWidths(
    IN HWND hWnd,
    IN int ControlId,
    IN LPDWORD Widths
    )

/*++

Routine Description:

    ClbSetColumnWidths sets the width of each column based on the supplied
    widths in characters. Note that the column on the far right extends to
    the edge of the Clb.

Arguments:

    hWnd        - Supplies the window handle for the parent window.
    ControlId   - Supplies the control id for this Clb for the supplied hWnd.
    Widths      - Supplies an array of widths, one less then the number of
                  columns, in characters.

Return Value:

    BOOL        - Returns TRUE if the widths were successfully adjusted.


--*/

{
    BOOL        Success;
    DWORD       Columns;
    LPCLB_INFO  ClbInfo;
    HWND        hWndClb;
    LONG        CharWidth;
    LONG        CharHeight;
    DWORD       i;
    LPLONG      WidthsInPixels;
    LONG        TotalPixels;
    HDC         hDCClientHeader;
    HD_ITEM     hdi;
    UINT        iRight;

    //
    // Validate arguments.
    //

    DbgHandleAssert( hWnd );
    DbgPointerAssert( Widths );

    //
    // Retrieve information for this ColumnListBox.
    //

    hWndClb = GetDlgItem( hWnd, ControlId );
    DbgHandleAssert( hWndClb );
    ClbInfo = RestoreClbInfo( hWndClb );
    DbgPointerAssert( ClbInfo );
    DbgAssert( CheckSignature( ClbInfo ));

    //
    // Get thd HDC for the header.
    //

    hDCClientHeader = GetDC( ClbInfo->hWndHeader );
    DbgHandleAssert( hDCClientHeader );

    //
    // Get the width of a character.
    //

    Success = GetCharMetrics(
                hDCClientHeader,
                &CharWidth,
                &CharHeight
                );
    DbgAssert( Success );

    //
    // Release the DC for the header.
    //

    Success = ReleaseDC( ClbInfo->hWndHeader, hDCClientHeader );
    DbgAssert( Success );

    //
    // Allocate an array of pixel widths, one for each column.
    //

    WidthsInPixels = AllocateObject( LONG, ClbInfo->Columns );
    DbgPointerAssert( WidthsInPixels );

    //
    // Compute the width of each column (not including the rightmost) in pixels,
    // and the total number of pixels used by these columns.
    //

    TotalPixels = 0;
    for( i = 0; i < ClbInfo->Columns - 1; i++ ) {

        WidthsInPixels[ i ] = Widths[ i ] * CharWidth;
        TotalPixels += WidthsInPixels[ i ];
    }

    //
    // The caller did not specify the width of the rightmost column.
    //

    if( Widths[ i ] == -1 ) {

        RECT    Rect;

        //
        // Set the width of the rightmost column to the remainder of the width
        // of the header window.
        //

        Success = GetClientRect(
                            ClbInfo->hWndHeader,
                            &Rect
                            );
        DbgAssert( Success );

        WidthsInPixels[ i ] = ( Rect.right - Rect.left ) - TotalPixels;

    } else {

        //
        // Set the width of the rightmost column to the value supplied
        // by the caller.
        //

        WidthsInPixels[ i ] = Widths[ i ] * CharWidth;
    }

    //
    // Tell the header window the width of each column.
    //

    hdi.mask = HDI_WIDTH;

    for( i = 0; i < ClbInfo->Columns - 1; i++ ) {

        hdi.cxy = WidthsInPixels[i];
        Success = Header_SetItem(ClbInfo->hWndHeader, i, &hdi);

        DbgAssert( Success );
    }

    //
    // Calc the array of right edges.
    //

    iRight = 0;

    for( i = 0; i < ClbInfo->Columns - 1; i++ ) {
        iRight += WidthsInPixels[i];
        ClbInfo->Right[i] = iRight;
    }

    //
    // Free the array of pixel widths.
    //

    Success = FreeObject( WidthsInPixels );
    DbgAssert( Success );

    return TRUE;
}
예제 #14
0
파일: clb.c 프로젝트: mingpen/OpenNT
BOOL
AdjustClbHeadings(
    IN HWND hWnd,
    IN LPCLB_INFO ClbInfo,
    IN LPCWSTR Headings OPTIONAL
    )

/*++

Routine Description:

    AdjustClbHeadings adjust the number of columns, the widths an header text
    bbased on the optional Headings parameter. If Headings is NULL then the
    column widths are adjusted based on the old headings and the current size
    of the Clb. If Headings are supplied then they consist of ';' separated
    strings, each of which is a column heading. The number of columns and their
    widths is then computed based on these new headings.

Arguments:

    hWnd        - Supplies a window handle for this Clb.
    ClbInfo     - Supplies a pointer the CLB_INFO structure for this Clb.
    Headings    - Supplies an optional pointer to a ';' separated series of
                  column header strings.

Return Value:

    BOOL        - Returns TRUE if the adjustment was succesfully made.

--*/

{
    BOOL    Success;
    DWORD   Columns;
    DWORD   ColumnWidth;
    DWORD   i;
    TCHAR   Buffer[ MAX_PATH ];
    LPCWSTR Heading;
    RECT    ClientRectHeader;
    HD_ITEM hdi;
    UINT    iCount, j, iRight;


    DbgPointerAssert( ClbInfo );
    DbgAssert( ! (( ClbInfo->Columns == 0 ) && ( Headings == NULL )));


    //
    // If the user supplied headings, compute the new number of columns.
    //

    if( ARGUMENT_PRESENT( Headings )) {

        //
        // Initialize the column counter.
        //

        Columns = 0;

        //
        // Make a copy of the new headings in the Clb object.
        //

        lstrcpy( ClbInfo->Headings, Headings );

        //
        // Make a copy of the heading string so that it can be tokenized.
        // i.e. wcstok destroys the string.
        //

        lstrcpy( Buffer, Headings );

        //
        // Grab the first token (heading).
        //

        Heading = _tcstok( Buffer, HEADING_SEPARATOR );

        //
        // For each heading...
        //

        while( Heading != NULL ) {

            //
            // Increment the number of columns.
            //

            Columns++;

            //
            // Get the next heading.
            //

            Heading = _tcstok( NULL, HEADING_SEPARATOR );
        }
    } else {

        //
        // Same number of Columns as before.
        //

        Columns = ClbInfo->Columns;
    }

    //
    // If the number of columns in the Clb is zero (i.e. this is the first
    // time it is being initialized) allocate the right edge array. Otherwise
    // reallocate the existing array if the number of columns has changed.
    //

    if( ClbInfo->Columns == 0 ) {

        ClbInfo->Right = AllocateObject( LONG, Columns );
        DbgPointerAssert( ClbInfo->Right );

    } else if( Columns != ClbInfo->Columns ) {

        ClbInfo->Right = ReallocateObject( LONG, ClbInfo->Right, Columns );
        DbgPointerAssert( ClbInfo->Right );

    }

    //
    // Update the number of columns in the Clb (note this may be the same
    // number as before).
    //

    ClbInfo->Columns = Columns;

    //
    // Compute the default column width by dividing the available space by the
    // number of columns.
    //

    Success = GetClientRect( ClbInfo->hWndHeader, &ClientRectHeader );
    DbgAssert( Success );

    ColumnWidth =   ( ClientRectHeader.right - ClientRectHeader.left )
                  / ClbInfo->Columns;


    //
    // Initialize the array of right edges to the width of each column.
    //

    for( i = 0; i < ClbInfo->Columns; i++ ) {

        ClbInfo->Right[ i ] = ColumnWidth;
    }

    //
    // Update the existing header items
    //

    iCount = Header_GetItemCount(ClbInfo->hWndHeader);

    j = 0;
    hdi.mask = HDI_WIDTH;

    while ((j < iCount) && (j < Columns)) {

        hdi.cxy = ClbInfo->Right[j];
        Header_SetItem (ClbInfo->hWndHeader, j, &hdi);
        j++;
    }

    //
    // Add new header items if necessary.
    //

    hdi.mask = HDI_WIDTH;
    for (; j < Columns; j++) {
        hdi.cxy = ClbInfo->Right[j];
        Header_InsertItem (ClbInfo->hWndHeader, j, &hdi);
    }


    //
    // Query the header for the array of right edges.
    //

    iRight = 0;

    for( i = 0; i < ClbInfo->Columns - 1; i++ ) {
        iRight += ClbInfo->Right[i];
        ClbInfo->Right[i] = iRight;
    }

    ClbInfo->Right[i] = ClientRectHeader.right;

    //
    // Copy and parse the headings so that each column's heading
    // can be set. These can be new or old headings.
    //

    lstrcpy( Buffer, ClbInfo->Headings );

    Heading = _tcstok( Buffer, HEADING_SEPARATOR );

    hdi.mask = HDI_TEXT | HDI_FORMAT;
    hdi.fmt  = HDF_STRING;
    for( i = 0; i < ClbInfo->Columns; i++ ) {

        hdi.pszText = (LPTSTR)Heading;
        Header_SetItem (ClbInfo->hWndHeader, i, &hdi);
        Heading = _tcstok( NULL, HEADING_SEPARATOR );
    }

    return TRUE;
}
예제 #15
0
파일: clb.c 프로젝트: mingpen/OpenNT
BOOL
ClbAddData(
    IN HWND hWnd,
    IN int ControlId,
    IN LPCLB_ROW ClbRow
    )

/*++

Routine Description:

    ClbAddData adds a new row of data to the Clb control's List Box.

Arguments:

    hWnd        - Supplies the window handle for the parent window.
    ControlId   - Supplies the control id for this Clb for the supplied hWnd.
    ClbRow      - Supplies a pointer to a CLB_ROW object which contains user
                  define per row data along with an array of CLB_STRINGs.

Return Value:

    BOOL        - Returns TRUE if the data was successfully added.


--*/

{
    LPCLB_INFO      ClbInfo;
    LRESULT         LbErr;
    DWORD           i;
    HWND            hWndClb;
    LPCLB_ROW       TempRow;

    //
    // Validate arguments.
    //

    DbgHandleAssert( hWnd );
    DbgPointerAssert( ClbRow );

    //
    // Retrieve information for this ColumnListBox.
    //

    hWndClb = GetDlgItem( hWnd, ControlId );
    DbgHandleAssert( hWndClb );
    ClbInfo = RestoreClbInfo( hWndClb );
    DbgPointerAssert( ClbInfo );
    DbgAssert( CheckSignature( ClbInfo ));

    //
    // Validate the count of strings.
    //

    DbgAssert( ClbRow->Count == ClbInfo->Columns );

    //
    // Capture the CLB_ROW object.
    //

    TempRow = AllocateObject( CLB_ROW, 1 );
    DbgPointerAssert( TempRow );

    CopyMemory(
        TempRow,
        ClbRow,
        sizeof( CLB_ROW)
        );

    //
    // Capture the strings.
    //

    TempRow->Strings = AllocateObject( CLB_STRING, ClbInfo->Columns );
    DbgPointerAssert( TempRow->Strings );

    for( i = 0; i < ClbInfo->Columns; i++ ) {

        //
        // Copy the header.
        //

        CopyMemory(
            &TempRow->Strings[ i ],
            &ClbRow->Strings[ i ],
            sizeof( CLB_STRING )
            );

        //
        // Copy the string.
        //

        TempRow->Strings[ i ].String = _wcsdup( ClbRow->Strings[ i ].String );
    }

    //
    // Store the CLB_ROW object in the listbox.
    //

    LbErr = SendMessage(
                ClbInfo->hWndListBox,
                LB_ADDSTRING,
                0,
                ( LPARAM ) TempRow
                );
    DbgAssert(( LbErr != LB_ERR ) && ( LbErr != LB_ERRSPACE ));

    return TRUE;
}
예제 #16
0
파일: clb.c 프로젝트: mingpen/OpenNT
LRESULT
ClbWndProc(
    IN HWND hWnd,
    IN UINT message,
    IN WPARAM wParam,
    IN LPARAM lParam
    )

/*++

Routine Description:

    This function is the window procedure for the Clb custom control.

Arguments:

    Standard window procedure parameters.

Return Value:

    LRESULT - dependent on the supplied message.

--*/

{
    BOOL            Success;
    LPCLB_INFO      ClbInfo;




    if( message == WM_NCCREATE ) {

        LONG    Long;

        //
        // Save the original styles.
        //

        Long = SetWindowLong(
                        hWnd,
                        GWL_USERDATA,
                        (( LPCREATESTRUCT ) lParam )->style
                        );
        DbgAssert( Long == 0 );


        //
        // Get rid of any styles that are uninteresting to the Clb.
        //

        SetWindowLong(
                hWnd,
                GWL_STYLE,
                  (( LPCREATESTRUCT ) lParam )->style
                & CLBS_CLB
                );

        return TRUE;
    }


    if( message == WM_CREATE ) {

        //
        // Assert that there is no prior per window information associated
        // with this Clb.
        //

        DbgAssert( RestoreClbInfo( hWnd ) == NULL );

        //
        // Restore the original styles.
        //

        (( LPCREATESTRUCT ) lParam )->style = GetWindowLong(
                                                hWnd,
                                                GWL_USERDATA
                                                );


        //
        // Allocate a CLB_INFO object for this Clb and initialize the Clb
        // relevant fields.
        //

        ClbInfo = AllocateObject( CLB_INFO, 1 );
        DbgPointerAssert( ClbInfo );

        //
        // Set the number of columns to zero so that remainder of creation
        // understands the state of the Clb.
        //

        ClbInfo->Columns = 0;

        //
        // Create the header portion of the Clb.
        //

        Success = CreateHeader( hWnd, ClbInfo, ( LPCREATESTRUCT ) lParam );
        DbgAssert( Success );

        //
        // Create the list box portion of the Clb.
        //

        Success = CreateListBox( hWnd, ClbInfo, ( LPCREATESTRUCT ) lParam );
        DbgAssert( Success );

        //
        // Adjust the column number, widths based on the heading text.
        //

        Success = AdjustClbHeadings( hWnd, ClbInfo, (( LPCREATESTRUCT ) lParam )->lpszName );
        DbgAssert( Success );

        //
        // Everything was succesfully created so set the Clb's signature
        // and save it away as part of the per window data.
        //

        SetSignature( ClbInfo );

        SaveClbInfo( ClbInfo );

        return 0;
    }

    //
    // Get the ClbInfo object for this Clb and make sure that its already
    // been created i.e. WM_CREATE was already executed and thereby initialized
    // and saved a ClbInfo object.
    //

    ClbInfo = RestoreClbInfo( hWnd );

    if( ClbInfo != NULL ) {

        //
        // Validate that this really is a ClbInfo object.
        //

        DbgAssert( CheckSignature( ClbInfo ));

        switch( message ) {

        case WM_DESTROY:
            {
                //
                // Delete the font used in the list box.
                //

                Success = DeleteObject( ClbInfo->hFontListBox );
                DbgAssert( Success );

                //
                // Delete the array of right habd edges.
                //

                Success = FreeObject( ClbInfo->Right );
                DbgAssert( Success );

                //
                // Delete the CLB_INFO object for this window.
                //

                Success = FreeObject( ClbInfo );
                DbgAssert( Success );

                SaveClbInfo ( ClbInfo );
                return 0;
            }

        case WM_PAINT:
            {
                PAINTSTRUCT     ps;
                RECT            Rect;
                POINT           Points[ 2 ];
                HDC             hDC;
                HPEN            hPen;

                hDC = BeginPaint( hWnd, &ps );
                DbgAssert( hDC == ps.hdc );

                Success = GetClientRect( hWnd, &Rect );
                DbgAssert( Success );

                Points[ 0 ].x = 0;
                Points[ 0 ].y = ClbInfo->HeaderHeight + 1;
                Points[ 1 ].x = Rect.right - Rect.left;
                Points[ 1 ].y = ClbInfo->HeaderHeight + 1;

                hPen = GetStockObject( BLACK_PEN );
                DbgHandleAssert( hPen );

                hPen = SelectObject( hDC, hPen );

                Success = Polyline( hDC, Points, NumberOfEntries( Points ));
                DbgAssert( Success );

                hPen = SelectObject( hDC, hPen );

                Success = DeleteObject( hPen );
                DbgAssert( Success );

                Success = EndPaint( hWnd, &ps );
                DbgAssert( Success );

                return 0;
            }

        case WM_COMMAND:

            switch( LOWORD( wParam )) {

            case ID_LISTBOX:

                switch( HIWORD( wParam )) {

                case LBN_DBLCLK:
                case LBN_KILLFOCUS:
                case LBN_SELCHANGE:
                    {
                        //
                        // These messages come to ClbWndProc because it is the parent
                        // of the list box, but they are really intended for the parent
                        // of the Clb.
                        //

                        HWND    hWndParent;

                        //
                        // Forward the message to the Clb's parent if it has a parent.
                        //

                        hWndParent = GetParent( hWnd );
                        DbgHandleAssert( hWndParent );

                        if( hWndParent != NULL ) {

                            //
                            // Replace the control id and handle with the Clb's.
                            //

                            LOWORD( wParam ) = GetDlgCtrlID( hWnd );
                            DbgAssert( LOWORD( wParam ) != 0 );

                            lParam = ( LPARAM ) hWnd;

                            //
                            // Forward the message...
                            //

                            return SendMessage(
                                        hWndParent,
                                        message,
                                        wParam,
                                        lParam
                                        );
                        }
                    }
                }
                break;

            }
            break;

        //
        // Forward to listbox.
        //

        case LB_GETCURSEL:
        case LB_SETCURSEL:
        case LB_FINDSTRING:
        case LB_GETITEMDATA:
        case LB_RESETCONTENT:
        case WM_CHAR:
        case WM_GETDLGCODE:
        case WM_KILLFOCUS:

            return SendMessage(
                    ClbInfo->hWndListBox,
                    message,
                    wParam,
                    lParam
                    );

        case WM_SETFOCUS:
            {
                SetFocus(
                    ClbInfo->hWndListBox
                    );

                return 0;
            }

        case WM_COMPAREITEM:
            {
                //
                // This message comes to ClbWndProc because it is the parent
                // of the list box, but is really intended for the parent
                // of the Clb.
                //

                HWND    hWndParent;

                //
                // Forward the message to the Clb's parent if it has a parent.
                //

                hWndParent = GetParent( hWnd );
                DbgHandleAssert( hWndParent );

                if( hWndParent != NULL ) {

                    int                     ControlId;
                    LPCOMPAREITEMSTRUCT     lpcis;

                    lpcis = ( LPCOMPAREITEMSTRUCT ) lParam;

                    ControlId = GetDlgCtrlID( hWnd );
                    DbgAssert( ControlId != 0 );

                    //
                    // Modify the COMPAREITEMSTRUCT so that it refers to the Clb.
                    //

                    lpcis->CtlID    = ControlId;
                    lpcis->hwndItem = hWnd;

                    //
                    // Forward the message...
                    //

                    return SendMessage(
                                hWndParent,
                                message,
                                ( WPARAM ) ControlId,
                                lParam
                                );
                }

                break;
            }

        case WM_DELETEITEM:
            {
                LPDELETEITEMSTRUCT  lpditms;
                LPCLB_ROW           ClbRow;
                DWORD               i;


                DbgAssert( wParam == ID_LISTBOX );

                //
                // Retrieve the pointer to the DELETEITEMSTRUCT.
                //

                lpditms = ( LPDELETEITEMSTRUCT ) lParam;
                DbgAssert(( lpditms->CtlType == ODT_LISTBOX )
                        &&( lpditms->CtlID == ID_LISTBOX ));

                //
                // If there is no data, just return.
                //

                if( lpditms->itemData == 0 ) {

                    return TRUE;
                }

                //
                // Retrieve the CLB_ROW object for this row.
                //

                ClbRow = ( LPCLB_ROW ) lpditms->itemData;

                //
                // For each column delete the string.
                //

                for( i = 0; i < ClbInfo->Columns; i++ ) {

                    //
                    // Strings were copied with _tcsdup so they must be
                    // freed with free( ).
                    //

                    free( ClbRow->Strings[ i ].String );
                }

                //
                // Free the CLB_STRING object.
                //

                Success = FreeObject( ClbRow->Strings );
                DbgAssert( Success );

                //
                // Free the CLB_ROW object.
                //

                Success = FreeObject( ClbRow );
                DbgAssert( Success );

                return TRUE;
            }

        case WM_DRAWITEM:
            {
                LPDRAWITEMSTRUCT    lpdis;
                BOOL                DrawFocus;

                DbgAssert( wParam == ID_LISTBOX );

                //
                // Retrieve the pointer to the DRAWITEMSTRUCT.
                //

                lpdis = ( LPDRAWITEMSTRUCT ) lParam;
                DbgAssert(( lpdis->CtlType == ODT_LISTBOX )
                        &&( lpdis->CtlID == ID_LISTBOX ));

                //
                // If there is no data, just return.
                //

                if( lpdis->itemData == 0 ) {

                    return TRUE;
                }

                if( lpdis->itemAction & ( ODA_DRAWENTIRE | ODA_SELECT )) {

                    DWORD               i;
                    LPCLB_ROW           ClbRow;
                    COLORREF            TextColor;
                    COLORREF            BkColor;

                    //
                    // Retrieve the CLB_ROW object for this row.
                    //

                    ClbRow = ( LPCLB_ROW ) lpdis->itemData;

                    //
                    // If the item is selected, set the selection colors.
                    //

                    if( lpdis->itemState & ODS_SELECTED ) {

                        BkColor     = COLOR_HIGHLIGHT;
                        TextColor   = COLOR_HIGHLIGHTTEXT;

                    } else {

                        BkColor     = COLOR_WINDOW;
                        TextColor   = COLOR_WINDOWTEXT;
                    }

                    BkColor = GetSysColor( BkColor );
                    TextColor = GetSysColor( TextColor );

                    BkColor = SetBkColor( lpdis->hDC, BkColor );
                    DbgAssert( BkColor != CLR_INVALID );

                    TextColor = SetTextColor( lpdis->hDC, TextColor );
                    DbgAssert( TextColor != CLR_INVALID );


                    //
                    // For each column display the text.
                    //

                    for( i = 0; i < ClbInfo->Columns; i++ ) {

                        RECT    ClipOpaqueRect;
                        int     x;
                        int     Left;
                        UINT    GdiErr;

                        //
                        // Depending on the format, adjust the alignment reference
                        // point (x) and the clipping rectangles left edge so that
                        // there are five pixels between each column.
                        //

                        switch( ClbRow->Strings[ i ].Format ) {

                        case CLB_LEFT:

                            if( i == 0 ) {

                                x = 2;

                            } else {

                                x = ClbInfo->Right[ i - 1 ] + 2;
                            }

                            Left = x - 2;

                            break;

                        case CLB_RIGHT:

                            if( i == 0 ) {

                                Left = 0;

                            } else {

                                Left = ClbInfo->Right[ i - 1 ];
                            }

                            x = ClbInfo->Right[ i ] - 3;

                            break;

                        default:

                            DbgAssert( FALSE );
                        }


                        //
                        // Set the format for this column.
                        //

                        GdiErr = SetTextAlign(
                                        lpdis->hDC,
                                          ClbRow->Strings[ i ].Format
                                        | TA_TOP
                                        );
                        DbgAssert( GdiErr != GDI_ERROR );

                        //
                        // Clip each string to its column width less two pixels
                        // (for asthetics).
                        //

                        Success = SetRect(
                                    &ClipOpaqueRect,
                                    Left,
                                    lpdis->rcItem.top,
                                    ClbInfo->Right[ i ],
                                    lpdis->rcItem.bottom
                                    );
                        DbgAssert( Success );

                        Success = ExtTextOut(
                                    lpdis->hDC,
                                    x,
                                    lpdis->rcItem.top,
                                      ETO_CLIPPED
                                    | ETO_OPAQUE,
                                    &ClipOpaqueRect,
                                    ClbRow->Strings[ i ].String,
                                    ClbRow->Strings[ i ].Length,
                                    NULL
                                    );
                        DbgAssert( Success );

                        //
                        // If the item has the focus, draw the focus rectangle.
                        //

                        DrawFocus = lpdis->itemState & ODS_FOCUS;
                    }

                } else {

                    //
                    // If the Clb has the focus, display a focus rectangle
                    // around the selected item.
                    //

                    DrawFocus = lpdis->itemAction & ODA_FOCUS;
                }

                //
                // If needed, toggle the focus rectangle.
                //

                if( DrawFocus ) {

                    Success = DrawFocusRect(
                                lpdis->hDC,
                                &lpdis->rcItem
                                );
                    DbgAssert( Success );
                }

                return TRUE;
            }

        case WM_NOTIFY:
            {
            HD_NOTIFY * lpNot;
            HD_ITEM   *pHDI;

            lpNot = (HD_NOTIFY *)lParam;
            pHDI = lpNot->pitem;

            switch( lpNot->hdr.code) {

            static
            DRAW_ERASE_LINE DrawEraseLine;

            static
            HPEN            hPen;

            static
            HDC             hDCClientListBox;
            HD_ITEM         hdi;
            UINT            iRight;
            UINT            i;
            RECT            ClientRectHeader;


            case HDN_BEGINTRACK:
                {

                    RECT    ClientRectListBox;

                    //
                    // Get thd HDC for the list box.
                    //

                    hDCClientListBox = GetDC( ClbInfo->hWndListBox );
                    DbgHandleAssert( hDCClientListBox );

                    //
                    // Create the pen used to display the drag position and
                    // select it into the in list box client area DC. Also set
                    // the ROP2 code so that drawing with the pen twice in the
                    // same place will erase it. This is what allows the
                    // line to drag.
                    //

                    hPen = CreatePen( PS_DOT, 1, RGB( 255, 255, 255 ));
                    DbgHandleAssert( hPen );

                    hPen = SelectObject( hDCClientListBox, hPen );
                    SetROP2( hDCClientListBox, R2_XORPEN );

                    //
                    // Set up the DRAW_ERASE_LINE structure so that the drag line is
                    // drawn from the top to the bottom of the list box at the
                    // current drag position.
                    //

                    Success = GetClientRect(
                                    ClbInfo->hWndListBox,
                                    &ClientRectListBox
                                    );
                    DbgAssert( Success );

                    //
                    // Draw the initial drag line from the top to the bottom
                    // of the list box equivalent with the header edge grabbed
                    // by the user.
                    //

                    DrawEraseLine.Draw.Src.x = ClbInfo->Right[ pHDI->cxy ];
                    DrawEraseLine.Draw.Src.y = 0;
                    DrawEraseLine.Draw.Dst.x = ClbInfo->Right[ pHDI->cxy ];
                    DrawEraseLine.Draw.Dst.y =   ClientRectListBox.bottom
                                               - ClientRectListBox.top;

                    Success = DrawLine( hDCClientListBox, &DrawEraseLine );
                    DbgAssert( Success );

                    return 0;
                }

            case HDN_TRACK:
                {

                    //DWORD           Columns;

                    //
                    // Get new drag position.
                    //

                    iRight = 0;
                    hdi.mask = HDI_WIDTH;

                    for( i = 0; i < ClbInfo->Columns - 1; i++ ) {
                        if (i != (UINT)lpNot->iItem) {
                          Header_GetItem(ClbInfo->hWndHeader, i, &hdi);
                        } else {
                          hdi.cxy = pHDI->cxy;
                        }
                        iRight += hdi.cxy;
                        ClbInfo->Right[i] = iRight;
                    }

                    GetClientRect( ClbInfo->hWndHeader, &ClientRectHeader );
                    ClbInfo->Right[i] = ClientRectHeader.right;

                    //
                    // Erase the old line and draw the new one at the new
                    // drag position.
                    //

                    Success = RedrawVerticalLine(
                                hDCClientListBox,
                                ClbInfo->Right[lpNot->iItem],
                                &DrawEraseLine
                                );
                    DbgAssert( Success );

                    return 0;
                }

            case HDN_ENDTRACK:

                //
                // Replace the old pen and delete the one created
                // during HBN_BEGINDRAG.
                //

                hPen = SelectObject( hDCClientListBox, hPen );
                Success = DeleteObject( hPen );
                DbgAssert( Success );

                //
                // Release the DC for the list box.
                //

                Success = ReleaseDC( ClbInfo->hWndListBox, hDCClientListBox );
                DbgAssert( Success );

                Success = RedrawWindow(
                                hWnd,
                                NULL,
                                NULL,
                                  RDW_ERASE
                                | RDW_INVALIDATE
                                | RDW_UPDATENOW
                                | RDW_ALLCHILDREN
                                );
                DbgAssert( Success );

                return 0;
            }

            break;
            }

        case WM_SETTEXT:

            //
            // Adjust the column number and widths based on the heading text.
            //

            Success = AdjustClbHeadings( hWnd, ClbInfo, ( LPCWSTR ) lParam );
            DbgAssert( Success );

            return Success;

        case WM_SIZE:
            {
                HDWP    hDWP;
                LONG    Width;
                LONG    Height;
                LONG    Style;
                LONG    VScrollWidth;

                Width   = LOWORD( lParam );
                Height  = HIWORD( lParam );

                hDWP = BeginDeferWindowPos( 2 );
                DbgHandleAssert( hDWP );

                //
                // Retrieve the list box's styles.
                //

                Style = GetWindowLong(
                            ClbInfo->hWndListBox,
                            GWL_STYLE
                            );

                //
                // If the list box has a vertical scroll bar compute its
                // width so that the header window's width can be adjusted
                // appropriately.
                //

                VScrollWidth =   ( Style & WS_VSCROLL )
                               ?   GetSystemMetrics( SM_CXVSCROLL )
                                 + ( GetSystemMetrics( SM_CXBORDER ) * 2 )
                               : 0;

                //
                // Size the header window to the width of the Clb and its
                // default / original height.
                //

                hDWP = DeferWindowPos(
                            hDWP,
                            ClbInfo->hWndHeader,
                            NULL,
                            0,
                            0,
                            Width - VScrollWidth,
                            ClbInfo->HeaderHeight,
                              SWP_NOACTIVATE
                            | SWP_NOMOVE
                            | SWP_NOZORDER
                            );
                DbgHandleAssert( hDWP );

                //
                // If the list box has a vertical scroll bar, bump the width
                // and height by two so that its border overwrites the Clb
                // border. This eliminates a double border (and a gap) between
                // the right and bottom edges of the scroll bar and the Clb.
                //

                if( Style & WS_VSCROLL ) {

                    Height += 2;
                    Width += 2;
                }

                //
                // Size the list box so that it is the size of the Clb less
                // the height of the header window less the height of the
                // border.
                //

                hDWP = DeferWindowPos(
                            hDWP,
                            ClbInfo->hWndListBox,
                            NULL,
                            0,
                            0,
                            Width,
                              Height
                            - ClbInfo->HeaderHeight
                            - 3,
                              SWP_NOACTIVATE
                            | SWP_NOMOVE
                            | SWP_NOZORDER
                            );
                DbgHandleAssert( hDWP );

                Success = EndDeferWindowPos( hDWP );
                DbgAssert( Success );

                break;
            }

        }
    }

    return DefWindowProc( hWnd, message, wParam, lParam );
}
예제 #17
0
파일: corhost.cpp 프로젝트: ArildF/masters
HRESULT STDMETHODCALLTYPE ICorDBPrivHelperImpl::CreateManagedObject(
    /*in*/  WCHAR *wszAssemblyName,
    /*in*/  WCHAR *wszModuleName,
    /*in*/  mdTypeDef classToken,
    /*in*/  void *rawData,
    /*out*/ IUnknown **ppUnk)
{
    _ASSERTE(TypeFromToken((mdTypeDef)classToken) == mdtTypeDef);
    _ASSERTE(wszAssemblyName && wszModuleName && ppUnk);

    if (!wszAssemblyName || !wszModuleName || classToken == mdTokenNil) 
        return E_INVALIDARG;

    if (!ppUnk) 
        return E_POINTER;

    HRESULT hr = S_OK;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();

    // This will set up a managed thread object if one does not already exist
    // for this particular thread.
    Thread* pThread = SetupThread();

    if (pThread == NULL) {
        hr = E_OUTOFMEMORY;
        goto Exit;
    }
    
    // Start up COM Interop
    if (FAILED(hr = QuickCOMStartup()))
        goto Exit;

    {
    // Don't want to be interrupted...
    BOOL fWasGCEnabled = !pThread->PreemptiveGCDisabled();

    if (fWasGCEnabled)
        pThread->DisablePreemptiveGC();
    
    Assembly  *pAssembly;
    Module    *pModule;
     
    if (GetAppDomain() == NULL)
        hr = E_INVALIDARG;
    else
    {
        // Try and load the assembly, given the name provided.
        OBJECTREF pThrowable = NULL;
        GCPROTECT_BEGIN(pThrowable);

        hr = AssemblySpec::LoadAssembly(wszAssemblyName, &pAssembly, &pThrowable);

        GCPROTECT_END();

        if (SUCCEEDED(hr))
        {
            _ASSERTE(pAssembly);

            // Try and load the module, given the name provided.
            hr = pAssembly->GetModuleFromFilename(wszModuleName, &pModule);

            if (SUCCEEDED(hr))
            {
                _ASSERTE(pModule);

                // If the class isn't known,then don't try and create it.
                if (!pModule->GetMDImport()->IsValidToken(classToken))
                    hr = E_INVALIDARG;
                else
                {                    
                    COMPLUS_TRY
                    {
                        OBJECTREF obj = NULL;
                        GCPROTECT_BEGIN(obj);

                        // Now try and get the TypeHandle for the given token
                        NameHandle nameHandle(pModule, classToken);
                        TypeHandle typeHandle =
                            pAssembly->LoadTypeHandle(&nameHandle, &obj);

                        // If an exception was thrown at some point, convert
                        // it to an HRESULT
                        if (obj != NULL)
                            hr = SecurityHelper::MapToHR(obj);

                        // No longer need the object, can be GC'd if desired
                        obj = NULL;

                        if (SUCCEEDED(hr))
                        {
                            _ASSERTE(typeHandle.AsMethodTable());
                            MethodTable *pMT = typeHandle.AsMethodTable();
        
                            if (!pMT->GetClass()->IsValueClass() ||
                                pMT->ContainsPointers())
                                hr = CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS;

                            if (SUCCEEDED(hr))
                            {
                                // Now run the class initialiser
                                if (!pMT->CheckRunClassInit(&obj))
                                    hr = SecurityHelper::MapToHR(obj);

                                // No longer need the object, can be GC'd if
                                // desired
                                obj = NULL;

                                if (SUCCEEDED(hr))
                                {
                                    // If successful, allocate an instance of
                                    // the class
                                    
                                    // This may throw an
                                    // OutOfMemoryException, but the below
                                    // COMPLUS_CATCH should handle it.  If
                                    // the class is a ValueClass, the
                                    // created object will be a boxed
                                    // ValueClass.
                                    obj = AllocateObject(pMT);

                                    // Now create a COM wrapper around
                                    // this object.  Note that this can
                                    // also throw.
                                    *ppUnk = GetComIPFromObjectRef(&obj);
                                    _ASSERTE(ppUnk);

                                    // This is the nasty part. We're gonna
                                    // copy the raw data we're given over
                                    // the new instance of the value
                                    // class...
                                    CopyValueClass(obj->UnBox(), rawData, pMT, obj->GetAppDomain());

                                    // No longer need the object, can be GC'd
                                    // if desired
                                    obj = NULL;
                                }
                            }
                        }

                        GCPROTECT_END();  // obj
                    }
                    COMPLUS_CATCH
                    {
                        // If there's an exception, convert it to an HR
                        hr = SecurityHelper::MapToHR(GETTHROWABLE());
                    }
                    COMPLUS_END_CATCH
                }
            }
        }
    }
    
    if (fWasGCEnabled)
        pThread->EnablePreemptiveGC();

    }
Exit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return (hr);
}
예제 #18
0
static Object* InitializeAppDomain()
{
	Object* appDomain = AllocateObject(&System_AppDomain_rtti);
	return appDomain;
}
예제 #19
0
int __cdecl main(int argc, char* argv[])
{
    //
    // Initialize system info
    //
    if (!GCToOSInterface::Initialize())
    {
        return -1;
    }

    // 
    // Initialize free object methodtable. The GC uses a special array-like methodtable as placeholder
    // for collected free space.
    //
    static MethodTable freeObjectMT;
    freeObjectMT.InitializeFreeObject();
    g_pFreeObjectMethodTable = &freeObjectMT;

    //
    // Initialize handle table
    //
    if (!Ref_Initialize())
        return -1;

    //
    // Initialize GC heap
    //
    GCHeap *pGCHeap = GCHeap::CreateGCHeap();
    if (!pGCHeap)
        return -1;

    if (FAILED(pGCHeap->Initialize()))
        return -1;

    //
    // Initialize current thread
    //
    ThreadStore::AttachCurrentThread();

    //
    // Create a Methodtable with GCDesc
    //

    class My : Object {
    public:
        Object * m_pOther1;
        int dummy_inbetween;
        Object * m_pOther2;
    };

    static struct My_MethodTable
    {
        // GCDesc
        CGCDescSeries m_series[2];
        size_t m_numSeries;

        // The actual methodtable
        MethodTable m_MT;
    }
    My_MethodTable;

    // 'My' contains the MethodTable*
    uint32_t baseSize = sizeof(My);
    // GC expects the size of ObjHeader (extra void*) to be included in the size.
    baseSize = baseSize + sizeof(ObjHeader);
    // Add padding as necessary. GC requires the object size to be at least MIN_OBJECT_SIZE.
    My_MethodTable.m_MT.m_baseSize = max(baseSize, MIN_OBJECT_SIZE);

    My_MethodTable.m_MT.m_componentSize = 0;    // Array component size
    My_MethodTable.m_MT.m_flags = MTFlag_ContainsPointers;

    My_MethodTable.m_numSeries = 2;

    // The GC walks the series backwards. It expects the offsets to be sorted in descending order.
    My_MethodTable.m_series[0].SetSeriesOffset(offsetof(My, m_pOther2));
    My_MethodTable.m_series[0].SetSeriesCount(1);
    My_MethodTable.m_series[0].seriessize -= My_MethodTable.m_MT.m_baseSize;

    My_MethodTable.m_series[1].SetSeriesOffset(offsetof(My, m_pOther1));
    My_MethodTable.m_series[1].SetSeriesCount(1);
    My_MethodTable.m_series[1].seriessize -= My_MethodTable.m_MT.m_baseSize;

    MethodTable * pMyMethodTable = &My_MethodTable.m_MT;

    // Allocate instance of MyObject
    Object * pObj = AllocateObject(pMyMethodTable);
    if (pObj == NULL)
        return -1;

    // Create strong handle and store the object into it
    OBJECTHANDLE oh = CreateGlobalHandle(pObj);
    if (oh == NULL)
        return -1;

    for (int i = 0; i < 1000000; i++)
    {
        Object * pBefore = ((My *)ObjectFromHandle(oh))->m_pOther1;

        // Allocate more instances of the same object
        Object * p = AllocateObject(pMyMethodTable);
        if (p == NULL)
            return -1;

        Object * pAfter = ((My *)ObjectFromHandle(oh))->m_pOther1;

        // Uncomment this assert to see how GC triggered inside AllocateObject moved objects around
        // assert(pBefore == pAfter);

        if (pBefore != pAfter)
		{
            printf("%8i) pBefore = 0x%08x, pAfter = 0x%08x, diff = 0x%08x (%i)\n", i, pBefore, pAfter, pBefore - pAfter, pBefore - pAfter);
            PrintGCStats(pGCHeap);
		}

        // Store the newly allocated object into a field using WriteBarrier
        WriteBarrier(&(((My *)ObjectFromHandle(oh))->m_pOther1), p);
    }

    // Create weak handle that points to our object
    OBJECTHANDLE ohWeak = CreateGlobalWeakHandle(ObjectFromHandle(oh));
    if (ohWeak == NULL)
        return -1;

    // Destroy the strong handle so that nothing will be keeping out object alive
    DestroyGlobalHandle(oh);

    // Verify that the weak handle has not yet been cleared (i.e. before the GC has run)
    assert(ObjectFromHandle(ohWeak) != NULL);

	printf("\nBEFORE Final Call to pGCHeap->GarbageCollect()");
	PrintGCStats(pGCHeap);

    // Explicitly trigger full GC
    pGCHeap->GarbageCollect();

	printf("\nAFTER  Final Call to pGCHeap->GarbageCollect()");
	PrintGCStats(pGCHeap);

    // Verify that the weak handle got cleared by the GC
    assert(ObjectFromHandle(ohWeak) == NULL);

    printf("Done\n");

    return 0;
}