void __cdecl FailFast(const wchar_t* format, ...) { wchar_t message[1024]{}; va_list args; va_start(args, format); vswprintf_s(message, format, args); va_end(args); OutputDebugString(message); OutputDebugString(L"\n"); FailFast(); }
/* * HndCreateHandle * * Entrypoint for allocating an individual handle. * */ OBJECTHANDLE HndCreateHandle(HHANDLETABLE hTable, UINT uType, OBJECTREF object, LPARAM lExtraInfo) { // update perf-counters: track number of handles COUNTER_ONLY(GetGlobalPerfCounters().m_GC.cHandles ++); COUNTER_ONLY(GetPrivatePerfCounters().m_GC.cHandles ++); VALIDATEOBJECTREF(object); // fetch the handle table pointer HandleTable *pTable = Table(hTable); // sanity check the type index _ASSERTE(uType < pTable->uTypeCount); // get a handle from the table's cache OBJECTHANDLE handle = TableAllocSingleHandleFromCache(pTable, uType); // did the allocation succeed? if (handle) { // yep - the handle better not point at anything yet _ASSERTE(*(_UNCHECKED_OBJECTREF *)handle == NULL); // we are not holding the lock - check to see if there is nonzero extra info if (lExtraInfo) { // initialize the user data BEFORE assigning the referent // this ensures proper behavior if we are currently scanning HandleQuickSetUserData(handle, lExtraInfo); } // store the referent HndAssignHandle(handle, object); } else FailFast(GetThread(), FatalOutOfMemory); #ifdef _DEBUG DEBUG_TrackAlloc(handle); #endif // return the result return handle; }