FCIMPLEND // Note: Arguments checked in IL. FCIMPL1(Object*, SystemNative::_GetEnvironmentVariable, StringObject* strVarUNSAFE) { FCALL_CONTRACT; STRINGREF refRetVal; STRINGREF strVar; refRetVal = NULL; strVar = ObjectToSTRINGREF(strVarUNSAFE); HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, strVar); int len; // Get the length of the environment variable. PathString envPath; // prefix complains if pass a null ptr in, so rely on the final length parm instead len = WszGetEnvironmentVariable(strVar->GetBuffer(), envPath); if (len != 0) { // Allocate the string. refRetVal = StringObject::NewString(len); wcscpy_s(refRetVal->GetBuffer(), len + 1, envPath); } HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(refRetVal); }
FCIMPLEND FCIMPL1(Object*, AssemblyNameNative::ToString, Object* refThisUNSAFE) { FCALL_CONTRACT; OBJECTREF pObj = NULL; ASSEMBLYNAMEREF pThis = (ASSEMBLYNAMEREF) (OBJECTREF) refThisUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_1(pThis); if (pThis == NULL) COMPlusThrow(kNullReferenceException, W("NullReference_This")); Thread *pThread = GetThread(); CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease AssemblySpec spec; spec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &pThis, FALSE, FALSE); StackSString name; #ifndef FEATURE_FUSION spec.GetFileOrDisplayName(ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE | ASM_DISPLAYF_PUBLIC_KEY_TOKEN, name); #else spec.GetFileOrDisplayName(0, name); #endif // FEATURE_FUSION pObj = (OBJECTREF) StringObject::NewString(name); HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(pObj); }
FCIMPL3(DWORD, SynchronizationContextNative::WaitHelper, PTRArray *handleArrayUNSAFE, CLR_BOOL waitAll, DWORD millis) { DWORD ret = 0; PTRARRAYREF handleArrayObj = (PTRARRAYREF) handleArrayUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_1(handleArrayObj); CONTRACTL { GC_TRIGGERS; THROWS; MODE_COOPERATIVE; SO_TOLERANT; } CONTRACTL_END; CQuickArray<HANDLE> qbHandles; int cHandles = handleArrayObj->GetNumComponents(); // Since DoAppropriateWait could cause a GC, we need to copy the handles to an unmanaged block // of memory to ensure they aren't relocated during the call to DoAppropriateWait. qbHandles.AllocThrows(cHandles); memcpy(qbHandles.Ptr(), handleArrayObj->GetDataPtr(), cHandles * sizeof(HANDLE)); Thread * pThread = GetThread(); ret = pThread->DoAppropriateWait(cHandles, qbHandles.Ptr(), waitAll, millis, (WaitMode)(WaitMode_Alertable | WaitMode_IgnoreSyncCtx)); HELPER_METHOD_FRAME_END(); return ret; }
FCIMPLEND FCIMPL0(StringObject*, SystemNative::_GetModuleFileName) { FCALL_CONTRACT; STRINGREF refRetVal = NULL; HELPER_METHOD_FRAME_BEGIN_RET_1(refRetVal); if (g_pCachedModuleFileName) { refRetVal = StringObject::NewString(g_pCachedModuleFileName); } else { SString wszFilePathString; WCHAR * wszFile = wszFilePathString.OpenUnicodeBuffer(MAX_LONGPATH); DWORD lgth = WszGetModuleFileName(NULL, wszFile, MAX_LONGPATH); if (!lgth) { COMPlusThrowWin32(); } wszFilePathString.CloseBuffer(lgth); refRetVal = StringObject::NewString(wszFilePathString.GetUnicode()); } HELPER_METHOD_FRAME_END(); return (StringObject*)OBJECTREFToObject(refRetVal); }
//=============================================================================================== // Attaches an unmanaged symwriter to a newly created dynamic module. //=============================================================================================== FCIMPL2(LPVOID, COMModule::nCreateISymWriterForDynamicModule, ReflectModuleBaseObject* reflectionModuleUNSAFE, StringObject* filenameUNSAFE) { FCALL_CONTRACT; REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(reflectionModuleUNSAFE); ReflectionModule *mod = (ReflectionModule*)refModule->GetModule(); STRINGREF filename = (STRINGREF)filenameUNSAFE; LPVOID pInternalSymWriter = NULL; HELPER_METHOD_FRAME_BEGIN_RET_2(filename, refModule); SString name; if (filename != NULL) { filename->GetSString(name); } GCX_PREEMP(); pInternalSymWriter = CreateISymWriterForDynamicModule(mod, name.GetUnicode()); HELPER_METHOD_FRAME_END(); return pInternalSymWriter; } // COMModule::nCreateISymWriterForDynamicModule
FCIMPL0(Object*, SystemNative::GetCommandLineArgs) { FCALL_CONTRACT; PTRARRAYREF strArray = NULL; HELPER_METHOD_FRAME_BEGIN_RET_1(strArray); LPWSTR commandLine; commandLine = WszGetCommandLine(); if (commandLine==NULL) COMPlusThrowOM(); DWORD numArgs = 0; LPWSTR* argv = SegmentCommandLine(commandLine, &numArgs); if (!argv) COMPlusThrowOM(); _ASSERTE(numArgs > 0); strArray = (PTRARRAYREF) AllocateObjectArray(numArgs, g_pStringClass); // Copy each argument into new Strings. for(unsigned int i=0; i<numArgs; i++) { STRINGREF str = StringObject::NewString(argv[i]); STRINGREF * destData = ((STRINGREF*)(strArray->GetDataPtr())) + i; SetObjectReference((OBJECTREF*)destData, (OBJECTREF)str, strArray->GetAppDomain()); } delete [] argv; HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(strArray); }
FCIMPLEND // Return a method info for the method were the exception was thrown FCIMPL1(ReflectMethodObject*, SystemNative::GetMethodFromStackTrace, ArrayBase* pStackTraceUNSAFE) { FCALL_CONTRACT; I1ARRAYREF pArray(static_cast<I1Array *>(pStackTraceUNSAFE)); StackTraceArray stackArray(pArray); if (!stackArray.Size()) return NULL; // The managed stacktrace classes always returns typical method definition, so we don't need to bother providing exact instantiation. // Generics::GetExactInstantiationsOfMethodAndItsClassFromCallInformation(pElements[0].pFunc, pElements[0].pExactGenericArgsToken, pTypeHandle, &pMD); MethodDesc* pFunc = stackArray[0].pFunc; // Strip the instantiation to make sure that the reflection never gets a bad method desc back. REFLECTMETHODREF refRet = NULL; HELPER_METHOD_FRAME_BEGIN_RET_0() pFunc = pFunc->LoadTypicalMethodDefinition(); refRet = pFunc->GetStubMethodInfo(); _ASSERTE(pFunc->IsRuntimeMethodHandle()); HELPER_METHOD_FRAME_END(); return (ReflectMethodObject*)OBJECTREFToObject(refRet); }
FCIMPL1(void, ArrayNative::Initialize, ArrayBase* array) { FCALL_CONTRACT; if (array == NULL) { FCThrowVoid(kNullReferenceException); } MethodTable* pArrayMT = array->GetMethodTable(); TypeHandle thElem = pArrayMT->GetApproxArrayElementTypeHandle(); if (thElem.IsTypeDesc()) return; MethodTable * pElemMT = thElem.AsMethodTable(); if (!pElemMT->HasDefaultConstructor() || !pElemMT->IsValueType()) return; ARRAYBASEREF arrayRef (array); HELPER_METHOD_FRAME_BEGIN_1(arrayRef); ArrayInitializeWorker(&arrayRef, pArrayMT, pElemMT); HELPER_METHOD_FRAME_END(); }
FCIMPLEND FCIMPL0(StringObject*, SystemNative::GetRuntimeDirectory) { FCALL_CONTRACT; STRINGREF refRetVal = NULL; DWORD dwFile = MAX_LONGPATH+1; HELPER_METHOD_FRAME_BEGIN_RET_1(refRetVal); SString wszFilePathString; WCHAR * wszFile = wszFilePathString.OpenUnicodeBuffer(dwFile); HRESULT hr = GetInternalSystemDirectory(wszFile, &dwFile); wszFilePathString.CloseBuffer(dwFile); if(FAILED(hr)) COMPlusThrowHR(hr); dwFile--; // remove the trailing NULL if(dwFile) refRetVal = StringObject::NewString(wszFile, dwFile); HELPER_METHOD_FRAME_END(); return (StringObject*)OBJECTREFToObject(refRetVal); }
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); }
FCIMPLEND /// "parse" tells us to parse the simple name of the assembly as if it was the full name /// almost never the right thing to do, but needed for compat /* static */ FCIMPL3(FC_BOOL_RET, AssemblyNameNative::ReferenceMatchesDefinition, AssemblyNameBaseObject* refUNSAFE, AssemblyNameBaseObject* defUNSAFE, CLR_BOOL fParse) { FCALL_CONTRACT; struct _gc { ASSEMBLYNAMEREF pRef; ASSEMBLYNAMEREF pDef; } gc; gc.pRef = (ASSEMBLYNAMEREF)ObjectToOBJECTREF (refUNSAFE); gc.pDef = (ASSEMBLYNAMEREF)ObjectToOBJECTREF (defUNSAFE); BOOL result = FALSE; HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); Thread *pThread = GetThread(); CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease if (gc.pRef == NULL) COMPlusThrow(kArgumentNullException, W("ArgumentNull_AssemblyName")); if (gc.pDef == NULL) COMPlusThrow(kArgumentNullException, W("ArgumentNull_AssemblyName")); AssemblySpec refSpec; refSpec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &gc.pRef, fParse, FALSE); AssemblySpec defSpec; defSpec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &gc.pDef, fParse, FALSE); #ifdef FEATURE_FUSION SafeComHolder<IAssemblyName> pRefName (NULL); IfFailThrow(refSpec.CreateFusionName(&pRefName, FALSE)); SafeComHolder <IAssemblyName> pDefName (NULL); IfFailThrow(defSpec.CreateFusionName(&pDefName, FALSE)); // Order matters: Ref->IsEqual(Def) result = (S_OK == pRefName->IsEqual(pDefName, ASM_CMPF_IL_ALL)); #else result=AssemblySpec::RefMatchesDef(&refSpec,&defSpec); #endif HELPER_METHOD_FRAME_END(); FC_RETURN_BOOL(result); }
FCIMPLEND // Note: Arguments checked in IL. FCIMPL1(Object*, SystemNative::_GetEnvironmentVariable, StringObject* strVarUNSAFE) { FCALL_CONTRACT; STRINGREF refRetVal; STRINGREF strVar; refRetVal = NULL; strVar = ObjectToSTRINGREF(strVarUNSAFE); HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, strVar); // We loop round getting the length of the env var and then trying to copy // the value into a managed string. Usually we'll go through this loop // precisely once, but the caution is ncessary in case the variable mutates // beneath us. int len, newLen; // Get the length of the environment variable. WCHAR dummy; // prefix complains if pass a null ptr in, so rely on the final length parm instead len = WszGetEnvironmentVariable(strVar->GetBuffer(), &dummy, 0); while (len != 0) { // Allocate the string. refRetVal = StringObject::NewString(len); // Get the value. newLen = WszGetEnvironmentVariable(strVar->GetBuffer(), refRetVal->GetBuffer(), len); if (newLen != (len - 1)) { // The envvar changed, need to do this again. Let GC collect the // string we just allocated. refRetVal = NULL; // Go back and try again. len = newLen; } else break; } HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(refRetVal); }
FCIMPLEND FCIMPL1(void, FreeNativeOverlapped, LPOVERLAPPED lpOverlapped) { FCALL_CONTRACT; HELPER_METHOD_FRAME_BEGIN_0(); CONSISTENCY_CHECK(g_pOverlappedDataClass && (OverlappedDataObject::GetOverlapped(lpOverlapped)->GetMethodTable() == g_pOverlappedDataClass)); DestroyAsyncPinningHandle(((NATIVEOVERLAPPED_AND_HANDLE*)lpOverlapped)->m_handle); delete lpOverlapped; HELPER_METHOD_FRAME_END(); }
FCIMPLEND #endif // !FEATURE_CORECLR FCIMPL4(void, AssemblyNameNative::Init, Object * refThisUNSAFE, OBJECTREF * pAssemblyRef, CLR_BOOL fForIntrospection, CLR_BOOL fRaiseResolveEvent) { FCALL_CONTRACT; ASSEMBLYNAMEREF pThis = (ASSEMBLYNAMEREF) (OBJECTREF) refThisUNSAFE; HRESULT hr = S_OK; HELPER_METHOD_FRAME_BEGIN_1(pThis); *pAssemblyRef = NULL; if (pThis == NULL) COMPlusThrow(kNullReferenceException, W("NullReference_This")); Thread * pThread = GetThread(); CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease AssemblySpec spec; hr = spec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF *) &pThis, TRUE, FALSE); if (SUCCEEDED(hr)) { spec.AssemblyNameInit(&pThis,NULL); } else if ((hr == FUSION_E_INVALID_NAME) && fRaiseResolveEvent) { Assembly * pAssembly = GetAppDomain()->RaiseAssemblyResolveEvent(&spec, fForIntrospection, FALSE); if (pAssembly == NULL) { EEFileLoadException::Throw(&spec, hr); } else { *((OBJECTREF *) (&(*pAssemblyRef))) = pAssembly->GetExposedObject(); } } else { ThrowHR(hr); } HELPER_METHOD_FRAME_END(); }
// Block waiting for data to become available on the console stream indicated by the safe file handle passed. // Ensure that the thread remains abortable in the process. FCIMPL2(void, ConsoleStreamHelper::WaitForAvailableConsoleInput, SafeHandle* refThisUNSAFE, CLR_BOOL bIsPipe) { FCALL_CONTRACT; SAFEHANDLEREF refConsoleHandle(refThisUNSAFE); HELPER_METHOD_FRAME_BEGIN_1(refConsoleHandle); // Prevent the console handle being closed under our feet. SafeHandleHolder shh(&refConsoleHandle); // Don't pass the address of the native handle within the safe handle to DoAppropriateWait since the safe // handle is on the GC heap and could be moved. Instead copy the native handle out into a stack location // (this is safe because we've ref-counted the safe handle to prevent it being disposed on us). HANDLE hNativeConsoleHandle = refConsoleHandle->GetHandle(); bool skipWait = false; // If we are reading from a pipe and the other end of the pipe was closed, then do not block. No one can write to it. // Also we can skip blocking if we do have data available. We should block if nothing is available, with the assumption // that Windows is smart enough to handle pipes where the other end is closed. if (bIsPipe) { DWORD cBytesRead, cTotalBytesAvailable, cBytesLeftThisMessage; int r = PeekNamedPipe(hNativeConsoleHandle, NULL, 0, &cBytesRead, &cTotalBytesAvailable, &cBytesLeftThisMessage); if (r != 0) { skipWait = cTotalBytesAvailable > 0; } else { // Windows returns ERROR_BROKEN_PIPE if the other side of a pipe is closed. However, we've seen // pipes return ERROR_NO_DATA and ERROR_PIPE_NOT_CONNECTED. Check for those too. int errorCode = GetLastError(); skipWait = errorCode == ERROR_BROKEN_PIPE || errorCode == ERROR_NO_DATA || errorCode == ERROR_PIPE_NOT_CONNECTED; } } // Perform the wait (DoAppropriateWait automatically handles thread aborts). if (!skipWait) { GetThread()->DoAppropriateWait(1, &hNativeConsoleHandle, TRUE, INFINITE, WaitMode_Alertable); } HELPER_METHOD_FRAME_END(); }
FCIMPLEND #ifndef FEATURE_CORECLR FCIMPL1(Object*, AssemblyNameNative::EscapeCodeBase, StringObject* filenameUNSAFE) { FCALL_CONTRACT; STRINGREF rv = NULL; STRINGREF filename = (STRINGREF) filenameUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_1(filename); LPWSTR pCodeBase = NULL; DWORD dwCodeBase = 0; CQuickBytes qb; if (filename != NULL) { WCHAR* pString; int iString; filename->RefInterpretGetStringValuesDangerousForGC(&pString, &iString); dwCodeBase = (DWORD) iString; pCodeBase = (LPWSTR) qb.AllocThrows((++dwCodeBase) * sizeof(WCHAR)); memcpy(pCodeBase, pString, dwCodeBase*sizeof(WCHAR)); } if(pCodeBase) { CQuickBytes qb2; DWORD dwEscaped = 1; DWORD flags = 0; if (RunningOnWin7()) flags |= URL_ESCAPE_AS_UTF8; UrlEscape(pCodeBase, (LPWSTR) qb2.Ptr(), &dwEscaped, flags); LPWSTR result = (LPWSTR)qb2.AllocThrows((++dwEscaped) * sizeof(WCHAR)); HRESULT hr = UrlEscape(pCodeBase, result, &dwEscaped, flags); if (SUCCEEDED(hr)) rv = StringObject::NewString(result); else COMPlusThrowHR(hr); } HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(rv); }
FCIMPLEND FCIMPL1(Object*, AssemblyNameNative::GetPublicKeyToken, Object* refThisUNSAFE) { FCALL_CONTRACT; OBJECTREF orOutputArray = NULL; OBJECTREF refThis = (OBJECTREF) refThisUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_1(refThis); if (refThis == NULL) COMPlusThrow(kNullReferenceException, W("NullReference_This")); ASSEMBLYNAMEREF orThis = (ASSEMBLYNAMEREF)refThis; U1ARRAYREF orPublicKey = orThis->GetPublicKey(); if (orPublicKey != NULL) { DWORD cb = orPublicKey->GetNumComponents(); StrongNameBufferHolder<BYTE> pbToken; if (cb) { CQuickBytes qb; BYTE *pbKey = (BYTE*) qb.AllocThrows(cb); memcpy(pbKey, orPublicKey->GetDataPtr(), cb); { GCX_PREEMP(); if (!StrongNameTokenFromPublicKey(pbKey, cb, &pbToken, &cb)) COMPlusThrowHR(StrongNameErrorInfo()); } } Security::CopyEncodingToByteArray(pbToken, cb, &orOutputArray); } HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(orOutputArray); }
FCIMPL1(unsigned __int64, COMCoverage::nativeCoverBlock, INT32 id) { FCALL_CONTRACT; unsigned __int64 retVal = 0; HELPER_METHOD_FRAME_BEGIN_RET_0(); HMODULE ilcovnat = 0; if (id == 1) { ilcovnat = CLRLoadLibrary(W("Ilcovnat.dll")); if (ilcovnat) { retVal = (unsigned __int64)GetProcAddress(ilcovnat, "CoverBlockNative"); } } else if (id == 2) { ilcovnat = CLRLoadLibrary(W("coverage.dll")); if (ilcovnat) { retVal = (unsigned __int64)GetProcAddress(ilcovnat, "CoverageRegisterBinaryWithStruct"); } } else if (id == 3) { ilcovnat = CLRLoadLibrary(W("Ilcovnat.dll")); if (ilcovnat) { retVal = (unsigned __int64)GetProcAddress(ilcovnat, "CoverMonRegisterMscorlib"); } } HELPER_METHOD_FRAME_END(); return retVal; }
FCIMPLEND FCIMPL0(StringObject*, SystemNative::GetDeveloperPath) { #ifdef FEATURE_FUSION FCALL_CONTRACT; STRINGREF refDevPath = NULL; LPWSTR pPath = NULL; DWORD lgth = 0; HELPER_METHOD_FRAME_BEGIN_RET_1(refDevPath); SystemDomain::System()->GetDevpathW(&pPath, &lgth); if(lgth) refDevPath = StringObject::NewString(pPath, lgth); HELPER_METHOD_FRAME_END(); return (StringObject*)OBJECTREFToObject(refDevPath); #else return NULL; #endif }
FCIMPL2(void, COMCurrency::DoToDecimal, DECIMAL * result, CY c) { FCALL_CONTRACT; // GC could only happen when exception is thrown, no need to protect result HELPER_METHOD_FRAME_BEGIN_0(); _ASSERTE(result); HRESULT hr = VarDecFromCy(c, result); if (FAILED(hr)) { // Didn't expect to get here. Update code for this HR. _ASSERTE(S_OK == hr); COMPlusThrowHR(hr); } if (FAILED(DecimalCanonicalize(result))) COMPlusThrow(kOverflowException, W("Overflow_Currency")); result->wReserved = 0; HELPER_METHOD_FRAME_END(); }
//+---------------------------------------------------------------------------- // // Method: CStackBuilderSink::PrivateProcessMessage, public // // Synopsis: Builds the stack and calls an object // //+---------------------------------------------------------------------------- FCIMPL7(Object*, CStackBuilderSink::PrivateProcessMessage, Object* pSBSinkUNSAFE, ReflectBaseObject* pMethodBaseUNSAFE, PTRArray* pArgsUNSAFE, Object* pServerUNSAFE, void* iMethodPtr, BOOL fContext, PTRARRAYREF* ppVarOutParams) { OBJECTREF ret = NULL; struct _gc { REFLECTBASEREF pMethodBase; PTRARRAYREF pArgs; OBJECTREF pServer; OBJECTREF pSBSink; } gc; gc.pMethodBase = (REFLECTBASEREF) pMethodBaseUNSAFE; gc.pArgs = (PTRARRAYREF) pArgsUNSAFE; gc.pServer = (OBJECTREF) pServerUNSAFE; gc.pSBSink = (OBJECTREF) pSBSinkUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_NOPOLL(Frame::FRAME_ATTR_RETURNOBJ); GCPROTECT_BEGIN(gc); HELPER_METHOD_POLL(); //-[autocvtpro]------------------------------------------------------- THROWSCOMPLUSEXCEPTION(); TRIGGERSGC(); LOG((LF_REMOTING, LL_INFO10, "CStackBuilderSink::PrivateProcessMessage\n")); _ASSERTE(gc.pMethodBase != NULL); ReflectMethod *pRM = (ReflectMethod *)gc.pMethodBase->GetData(); MethodDesc *pMD = pRM->pMethod; // Either pServer is non-null or the method is static (but not both) _ASSERTE((gc.pServer!=NULL) == !(pMD->IsStatic())); // Check if this is an interface invoke, if yes, then we have to find the // real method descriptor on the class of the server object. if(pMD->GetMethodTable()->IsInterface()) { _ASSERTE(gc.pServer != NULL); MethodDesc* pTemp = pMD; // NOTE: This method can trigger GC pMD = gc.pServer->GetMethodTable()->GetMethodDescForInterfaceMethod(pMD, gc.pServer); if(NULL == pMD) { MAKE_WIDEPTR_FROMUTF8(wName, pTemp->GetName()) COMPlusThrow(kMissingMethodException, IDS_EE_MISSING_METHOD, NULL, wName); } } MetaSig mSig(pMD->GetSig(), pMD->GetModule()); // get the target depending on whether the method is virtual or non-virtual // like a constructor, private or final method const BYTE* pTarget = NULL; if (iMethodPtr) { pTarget = (const BYTE*) iMethodPtr; } else { // Get the address of the code pTarget = MethodTable::GetTargetFromMethodDescAndServer(pMD, &(gc.pServer), fContext); } VASigCookie *pCookie = NULL; _ASSERTE(NULL != pTarget); GCPROTECT_BEGIN (ret); // this function does the work ::CallDescrWithObjectArray( gc.pServer, pRM, pTarget, &mSig, pCookie, gc.pServer==NULL?TRUE:FALSE, //fIsStatic gc.pArgs, &ret, ppVarOutParams); GCPROTECT_END (); LOG((LF_REMOTING, LL_INFO10, "CStackBuilderSink::PrivateProcessMessage OUT\n")); //-[autocvtepi]------------------------------------------------------- GCPROTECT_END(); HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(ret); }
FCIMPLEND FCIMPL1(LPOVERLAPPED, AllocateNativeOverlapped, OverlappedDataObject* overlappedUNSAFE) { FCALL_CONTRACT; LPOVERLAPPED lpOverlapped; OVERLAPPEDDATAREF overlapped = ObjectToOVERLAPPEDDATAREF(overlappedUNSAFE); OBJECTREF userObject = overlapped->m_userObject; HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_NONE, overlapped, userObject); if (g_pOverlappedDataClass == NULL) { g_pOverlappedDataClass = MscorlibBinder::GetClass(CLASS__OVERLAPPEDDATA); // We have optimization to avoid creating event if IO is in default domain. This depends on default domain // can not be unloaded. _ASSERTE(SystemDomain::System()->DefaultDomain()->GetId().m_dwId == DefaultADID); } CONSISTENCY_CHECK(overlapped->GetMethodTable() == g_pOverlappedDataClass); if (userObject != NULL) { if (userObject->GetMethodTable() == g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT]->GetMethodTable()) { BASEARRAYREF asArray = (BASEARRAYREF) userObject; OBJECTREF *pObj = (OBJECTREF*)(asArray->GetDataPtr()); SIZE_T num = asArray->GetNumComponents(); SIZE_T i; for (i = 0; i < num; i ++) { ValidatePinnedObject(pObj[i]); } } else { ValidatePinnedObject(userObject); } } NewHolder<NATIVEOVERLAPPED_AND_HANDLE> overlappedHolder(new NATIVEOVERLAPPED_AND_HANDLE()); overlappedHolder->m_handle = GetAppDomain()->CreateTypedHandle(overlapped, HNDTYPE_ASYNCPINNED); lpOverlapped = &(overlappedHolder.Extract()->m_overlapped); lpOverlapped->Internal = 0; lpOverlapped->InternalHigh = 0; lpOverlapped->Offset = overlapped->m_offsetLow; lpOverlapped->OffsetHigh = overlapped->m_offsetHigh; lpOverlapped->hEvent = (HANDLE)overlapped->m_eventHandle; overlapped->m_pNativeOverlapped = lpOverlapped; HELPER_METHOD_FRAME_END(); LOG((LF_INTEROP, LL_INFO10000, "In AllocNativeOperlapped thread 0x%x\n", GetThread())); if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ThreadPoolIODequeue)) FireEtwThreadPoolIOPack(lpOverlapped, overlappedUNSAFE, GetClrInstanceId()); return lpOverlapped; }