1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4// QCALL.CPP
5//
6
7
8
9#include "common.h"
10
11//
12// Helpers for returning managed string from QCall
13//
14
15void QCall::StringHandleOnStack::Set(const SString& value)
16{
17 STANDARD_VM_CONTRACT;
18
19 GCX_COOP();
20
21 Set(StringObject::NewString(value));
22}
23
24void QCall::StringHandleOnStack::Set(LPCWSTR pwzValue)
25{
26 STANDARD_VM_CONTRACT;
27
28 GCX_COOP();
29
30 Set(StringObject::NewString(pwzValue));
31}
32
33void QCall::StringHandleOnStack::Set(LPCUTF8 pszValue)
34{
35 STANDARD_VM_CONTRACT;
36
37 GCX_COOP();
38
39 Set(StringObject::NewString(pszValue));
40}
41
42//
43// Helpers for returning common managed types from QCall
44//
45
46void QCall::ObjectHandleOnStack::SetByteArray(const BYTE * p, COUNT_T length)
47{
48 STANDARD_VM_CONTRACT;
49
50 GCX_COOP();
51
52 BASEARRAYREF arr = (BASEARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, length);
53 memcpyNoGCRefs(arr->GetDataPtr(), p, length * sizeof(BYTE));
54 Set(arr);
55}
56
57void QCall::ObjectHandleOnStack::SetIntPtrArray(const PVOID * p, COUNT_T length)
58{
59 STANDARD_VM_CONTRACT;
60
61 GCX_COOP();
62
63 BASEARRAYREF arr = (BASEARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_I, length);
64 memcpyNoGCRefs(arr->GetDataPtr(), p, length * sizeof(PVOID));
65 Set(arr);
66}
67
68void QCall::ObjectHandleOnStack::SetGuidArray(const GUID * p, COUNT_T length)
69{
70 STANDARD_VM_CONTRACT;
71
72 GCX_COOP();
73
74 TypeHandle typeHandle = MscorlibBinder::GetClass(CLASS__GUID);
75 BASEARRAYREF arr = (BASEARRAYREF) AllocateValueSzArray(typeHandle, length);
76 memcpyNoGCRefs(arr->GetDataPtr(), p, length * sizeof(GUID));
77 Set(arr);
78}
79
80//
81// Helpers for passing an AppDomain to a QCall
82//
83
84#ifdef _DEBUG
85
86//---------------------------------------------------------------------------------------
87//
88// Verify that the AppDomain being passed from the BCL is valid for use in a QCall. Note: some additional
89// checks are in System.AppDomain.GetNativeHandle()
90//
91
92void QCall::AppDomainHandle::VerifyDomainHandle() const
93{
94 LIMITED_METHOD_CONTRACT;
95
96 // System.AppDomain.GetNativeHandle() should ensure that we're not calling through with a null AppDomain pointer.
97 _ASSERTE(m_pAppDomain);
98
99 // QCalls should only be made with pointers to the current domain
100 _ASSERTE(GetAppDomain() == m_pAppDomain);
101
102 // We should not have a QCall made on an invalid AppDomain. Once unload a domain, we won't let anyone else
103 // in and any threads that are already in will be unwound.
104 _ASSERTE(SystemDomain::GetAppDomainAtIndex(m_pAppDomain->GetIndex()) != NULL);
105}
106
107#endif // _DEBUG
108