[add] first

This commit is contained in:
2023-10-08 10:24:48 +08:00
commit b1ae0510a9
1048 changed files with 3254361 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
#pragma once
#include <utility>
#include <hstring.h>
#include <Unknwn.h>
namespace il2cpp
{
namespace winrt
{
template<typename T, bool isIUnknown = std::is_base_of<IUnknown, std::remove_pointer<T>::type>::value>
struct ReferenceCounter;
template<typename T>
struct ReferenceCounter<T, false>
{
static inline void AddRef(T& value)
{
}
static inline void Release(T& value)
{
}
};
template<typename T>
struct ReferenceCounter<T, true>
{
static inline void AddRef(T& value)
{
if (value == nullptr)
return;
value->AddRef();
}
static inline void Release(T& value)
{
if (value == nullptr)
return;
value->Release();
}
};
template<>
struct ReferenceCounter<HSTRING, false>
{
static inline void AddRef(HSTRING& value)
{
if (value == nullptr)
return;
auto hr = WindowsDuplicateString(value, &value);
Assert(SUCCEEDED(hr));
}
static inline void Release(HSTRING& value)
{
if (value == nullptr)
return;
auto hr = WindowsDeleteString(value);
Assert(SUCCEEDED(hr));
}
};
}
}

View File

@@ -0,0 +1,142 @@
#pragma once
#include "ReferenceCounter.h"
#include "os/Win32/WindowsHeaders.h"
#include <windows.foundation.h>
#include <windows.foundation.collections.h>
#include <wrl.h>
#include <vector>
namespace il2cpp
{
namespace winrt
{
template<typename T>
struct ResultTypeTraits
{
typedef typename ABI::Windows::Foundation::Internal::GetLogicalType<typename T::TResult_complex>::type LogicalType;
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<typename T::TResult_complex>::type ResultType;
};
template<>
struct ResultTypeTraits<ABI::Windows::Foundation::IAsyncAction>
{
typedef void LogicalType;
typedef void ResultType;
};
template<typename OperationType, typename HandlerType>
class SynchronousOperationBase : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, Microsoft::WRL::FtmBase, HandlerType>
{
protected:
HANDLE m_Event;
HRESULT m_HR;
typedef OperationType OperationType;
inline SynchronousOperationBase(OperationType* op)
{
m_Event = CreateEventExW(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
Assert(m_Event && "CreateEventExW failed.");
}
inline ~SynchronousOperationBase()
{
CloseHandle(m_Event);
// This will be not 0 if it's allocated on the stack
// This class must be allocated on the heap for correct COM ref counting!
IL2CPP_ASSERT(GetRefCount() == 0);
}
public:
inline HRESULT Wait()
{
auto waitResult = WaitForSingleObjectEx(m_Event, INFINITE, FALSE);
if (waitResult != WAIT_OBJECT_0)
return E_FAIL;
return m_HR;
}
};
template<typename T>
class SynchronousOperation : public SynchronousOperationBase<ABI::Windows::Foundation::IAsyncOperation<T>, ABI::Windows::Foundation::IAsyncOperationCompletedHandler<T> >
{
private:
typedef typename ResultTypeTraits<OperationType>::ResultType ResultType;
ResultType m_Result;
public:
inline SynchronousOperation(OperationType* op) :
SynchronousOperationBase(op),
m_Result(ResultType())
{
// NOTE: this is in the derived class because it might immediately complete.
// If this was called from the base class, you'd get a callback on a partially
// constructed vtable and crash.
auto hr = op->put_Completed(this);
Assert(SUCCEEDED(hr) && "IAsyncOperation<T>::put_Completed failed.");
}
~SynchronousOperation()
{
ReferenceCounter<ResultType>::Release(m_Result);
}
HRESULT GetResults(ResultType* result)
{
auto hr = Wait();
if (FAILED(hr))
return hr;
*result = m_Result;
ReferenceCounter<ResultType>::AddRef(*result);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Invoke(ABI::Windows::Foundation::IAsyncOperation<T>* asyncInfo, ABI::Windows::Foundation::AsyncStatus status) override
{
m_HR = asyncInfo->GetResults(&m_Result);
SetEvent(m_Event);
return S_OK;
}
static Microsoft::WRL::ComPtr<SynchronousOperation<T> > Make(OperationType* op)
{
return Microsoft::WRL::Make<SynchronousOperation<T> >(op);
}
};
template<>
class SynchronousOperation<void> : public SynchronousOperationBase<ABI::Windows::Foundation::IAsyncAction, ABI::Windows::Foundation::IAsyncActionCompletedHandler>
{
public:
inline SynchronousOperation(OperationType* op) :
SynchronousOperationBase(op)
{
// NOTE: this is in the derived class because it might immediately complete.
// If this was called from the base class, you'd get a callback on a partially
// constructed vtable and crash.
auto hr = op->put_Completed(this);
Assert(SUCCEEDED(hr) && "IAsyncAction::put_Completed failed.");
}
virtual HRESULT STDMETHODCALLTYPE Invoke(ABI::Windows::Foundation::IAsyncAction* asyncInfo, ABI::Windows::Foundation::AsyncStatus status) override
{
m_HR = asyncInfo->GetResults();
SetEvent(m_Event);
return S_OK;
}
};
template<typename T>
Microsoft::WRL::ComPtr<SynchronousOperation<typename ResultTypeTraits<T>::LogicalType> > MakeSynchronousOperation(T* op)
{
return Microsoft::WRL::Make<SynchronousOperation<typename ResultTypeTraits<T>::LogicalType> >(op);
}
}
}

View File

@@ -0,0 +1,181 @@
#pragma once
#if IL2CPP_TARGET_WINRT || IL2CPP_TARGET_XBOXONE
#include "os/Win32/WindowsHeaders.h"
#include <wrl.h>
#if WINDOWS_SDK_BUILD_VERSION < 16299 // This got readded on Windows 10 Fall Creators Update
#define MAX_COMPUTERNAME_LENGTH 31
#define GetComputerName GetComputerNameW
#endif
namespace il2cpp
{
namespace winrt
{
inline DWORD WIN32_FROM_HRESULT(HRESULT hr)
{
if ((hr & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0))
return HRESULT_CODE(hr);
if (hr == S_OK)
return HRESULT_CODE(hr);
return ERROR_SUCCESS;
}
inline static BOOL CopyHStringToBuffer(Microsoft::WRL::Wrappers::HString& source, LPWSTR target, LPDWORD targetSize)
{
unsigned int sourceLength;
auto sourceBuffer = source.GetRawBuffer(&sourceLength);
if (sourceLength + 1 > *targetSize)
{
SetLastError(ERROR_BUFFER_OVERFLOW);
*targetSize = sourceLength + 1;
return FALSE;
}
*targetSize = sourceLength;
if (target != nullptr)
{
memcpy(target, sourceBuffer, sourceLength * sizeof(wchar_t));
target[sourceLength] = L'\0';
return TRUE;
}
return FALSE;
}
}
}
#if WINDOWS_SDK_BUILD_VERSION < 16299 // These APIs got readded on Windows 10 Fall Creators Update
extern "C"
{
inline BOOL WINAPI CopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
{
COPYFILE2_EXTENDED_PARAMETERS params;
params.dwSize = sizeof(params);
params.dwCopyFlags = bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0;
params.pfCancel = FALSE;
params.pProgressRoutine = nullptr;
params.pvCallbackContext = nullptr;
auto hr = CopyFile2(lpExistingFileName, lpNewFileName, &params);
if (FAILED(hr))
{
SetLastError(il2cpp::winrt::WIN32_FROM_HRESULT(hr));
return FALSE;
}
return TRUE;
}
inline UINT WINAPI GetACP()
{
return CP_ACP;
}
BOOL WINAPI GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize);
} // extern "C"
#endif
#if WINDOWS_SDK_BUILD_VERSION < 15063
extern "C"
{
typedef struct
{
char String[4 * 4];
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
typedef struct _IP_ADDR_STRING
{
struct _IP_ADDR_STRING* Next;
IP_ADDRESS_STRING IpAddress;
IP_MASK_STRING IpMask;
DWORD Context;
} IP_ADDR_STRING, *PIP_ADDR_STRING;
#define MAX_HOSTNAME_LEN 128
#define MAX_DOMAIN_NAME_LEN 128
#define MAX_SCOPE_ID_LEN 256
typedef struct
{
char HostName[MAX_HOSTNAME_LEN + 4];
char DomainName[MAX_DOMAIN_NAME_LEN + 4];
PIP_ADDR_STRING CurrentDnsServer;
IP_ADDR_STRING DnsServerList;
UINT NodeType;
char ScopeId[MAX_SCOPE_ID_LEN + 4];
UINT EnableRouting;
UINT EnableProxy;
UINT EnableDns;
} FIXED_INFO, *PFIXED_INFO;
DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen);
} // extern "C"
#endif
#if IL2CPP_TARGET_WINRT
extern "C"
{
#if WINDOWS_SDK_BUILD_VERSION < 15063
#define MAX_INTERFACE_NAME_LEN 256
#define MAXLEN_PHYSADDR 8
typedef enum
{
IF_OPER_STATUS_NON_OPERATIONAL = 0,
IF_OPER_STATUS_UNREACHABLE = 1,
IF_OPER_STATUS_DISCONNECTED = 2,
IF_OPER_STATUS_CONNECTING = 3,
IF_OPER_STATUS_CONNECTED = 4,
IF_OPER_STATUS_OPERATIONAL = 5,
} INTERNAL_IF_OPER_STATUS;
#define MAXLEN_IFDESCR 256
typedef struct
{
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
IF_INDEX dwIndex;
IFTYPE dwType;
DWORD dwMtu;
DWORD dwSpeed;
DWORD dwPhysAddrLen;
UCHAR bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
INTERNAL_IF_OPER_STATUS dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets;
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets;
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
UCHAR bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;
#endif
DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow);
} // extern "C"
#endif // IL2CPP_TARGET_WINRT
#endif

View File

@@ -0,0 +1,89 @@
#pragma once
#if IL2CPP_TARGET_WINRT
extern "C"
{
#if WINDOWS_SDK_BUILD_VERSION < 16299 // These APIs got readded on Windows 10 Fall Creators Update
#define CreateEvent CreateEventW
#define FreeEnvironmentStrings FreeEnvironmentStringsW
#define GetEnvironmentStrings GetEnvironmentStringsW
#define GetEnvironmentVariable GetEnvironmentVariableW
#define GetVersionEx GetVersionExW
#define SetEnvironmentVariable SetEnvironmentVariableW
#endif
#define GetUserName GetUserNameW
#if WINDOWS_SDK_BUILD_VERSION < 16299
inline HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
{
DWORD flags = 0;
if (bManualReset)
flags |= CREATE_EVENT_MANUAL_RESET;
if (bInitialState)
flags |= CREATE_EVENT_INITIAL_SET;
return CreateEventExW(lpEventAttributes, lpName, flags, EVENT_ALL_ACCESS);
}
#endif
inline HANDLE WINAPI CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
const DWORD kFileAttributeMask = 0x0000FFFF;
const DWORD kFileFlagMask = 0xFFFF0000;
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
extendedParameters.dwFileAttributes = dwFlagsAndAttributes & kFileAttributeMask;
extendedParameters.dwFileFlags = dwFlagsAndAttributes & kFileFlagMask;
extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParameters.lpSecurityAttributes = lpSecurityAttributes;
extendedParameters.hTemplateFile = hTemplateFile;
return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, &extendedParameters);
}
#if WINDOWS_SDK_BUILD_VERSION < 16299
BOOL WINAPI FreeEnvironmentStringsW(LPWCH strings);
LPWCH WINAPI GetEnvironmentStringsW();
DWORD WINAPI GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize);
BOOL WINAPI GetVersionExW(LPOSVERSIONINFOW lpVersionInformation);
#endif
BOOL WINAPI GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer);
inline HMODULE WINAPI LoadLibraryW(LPCWSTR lpLibFileName)
{
return LoadPackagedLibrary(lpLibFileName, 0);
}
#if WINDOWS_SDK_BUILD_VERSION < 16299
BOOL WINAPI SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue);
#endif
#define CreateFileMappingW(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName) \
CreateFileMappingFromApp(hFile, lpFileMappingAttributes, flProtect, (static_cast<ULONG64>(dwMaximumSizeHigh) << 32) | dwMaximumSizeLow, lpName);
#define MapViewOfFile(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap) \
MapViewOfFileFromApp(hFileMappingObject, dwDesiredAccess, (static_cast<ULONG64>(dwFileOffsetHigh) << 32) | dwFileOffsetLow, dwNumberOfBytesToMap);
#if WINDOWS_SDK_BUILD_VERSION < 14393
#define TlsAlloc() FlsAlloc(NULL)
#define TlsGetValue FlsGetValue
#define TlsSetValue FlsSetValue
#define TlsFree FlsFree
#endif
} // extern "C"
#endif

View File

@@ -0,0 +1,243 @@
#pragma once
// This class was copied from Unity's source code and modified to not depend on Unity's MemoryManager
#include "ReferenceCounter.h"
#include <vector>
#include <Windows.Foundation.Collections.h>
#include <wrl.h>
namespace Internal
{
template<typename T>
inline void AddItemRef(T& value)
{
il2cpp::winrt::ReferenceCounter<T>::AddRef(value);
}
template<typename T>
inline void ReleaseItem(T& value)
{
il2cpp::winrt::ReferenceCounter<T>::Release(value);
value = T();
}
}
namespace il2cpp
{
namespace winrt
{
template<typename T>
struct Vector :
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
Microsoft::WRL::FtmBase,
ABI::Windows::Foundation::Collections::IVector<T>,
ABI::Windows::Foundation::Collections::IVectorView<T>,
ABI::Windows::Foundation::Collections::IIterable<T> >
{
private:
struct Iterator :
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, Microsoft::WRL::FtmBase, ABI::Windows::Foundation::Collections::IIterator<T> >
{
private:
Microsoft::WRL::ComPtr<Vector<T> > m_Vector;
size_t m_Position;
public:
Iterator(Vector<T>* vector) :
m_Vector(vector), m_Position(0)
{
}
virtual HRESULT STDCALL get_Current(T* current) override
{
if (m_Position >= m_Vector->m_Vector.size())
{
return E_BOUNDS;
}
*current = m_Vector->m_Vector[m_Position];
::Internal::AddItemRef(*current);
return S_OK;
}
virtual HRESULT STDCALL get_HasCurrent(boolean* hasCurrent) override
{
*hasCurrent = m_Position < m_Vector->m_Vector.size();
return S_OK;
}
virtual HRESULT STDCALL MoveNext(boolean* hasCurrent) override
{
if (m_Position < m_Vector->m_Vector.size())
{
m_Position++;
*hasCurrent = m_Position < m_Vector->m_Vector.size();
}
else
{
*hasCurrent = false;
}
return S_OK;
}
virtual HRESULT STDCALL GetMany(uint32_t capacity, T* dest, uint32_t* actualCount) override
{
return m_Vector->GetMany(0, capacity, dest, actualCount);
}
};
friend struct Iterator;
std::vector<T> m_Vector;
inline void ClearInternal()
{
for (size_t i = 0; i < m_Vector.size(); i++)
::Internal::ReleaseItem(m_Vector[i]);
m_Vector.clear();
}
public:
Vector()
{
}
virtual ~Vector()
{
ClearInternal();
}
virtual HRESULT STDCALL GetAt(uint32_t index, T* item) override
{
*item = m_Vector[index];
::Internal::AddItemRef(*item);
return S_OK;
}
virtual HRESULT STDCALL GetMany(uint32_t startIndex, uint32_t capacity, T* dest, uint32_t* actualCount) override
{
ZeroMemory(dest, sizeof(T) * capacity);
if (startIndex > m_Vector.size())
return E_BOUNDS;
uint32_t count = std::min(capacity, static_cast<uint32_t>(m_Vector.size()) - startIndex);
for (uint32_t i = 0; i < count; i++)
{
dest[i] = m_Vector[i + startIndex];
::Internal::AddItemRef(dest[i]);
}
*actualCount = count;
return S_OK;
}
virtual HRESULT STDCALL get_Size(uint32_t* size) override
{
*size = static_cast<unsigned>(m_Vector.size());
return S_OK;
}
virtual HRESULT STDCALL GetView(ABI::Windows::Foundation::Collections::IVectorView<T>** view) override
{
AddRef();
*view = this;
return S_OK;
}
virtual HRESULT STDCALL IndexOf(T value, uint32_t* index, boolean* found) override
{
*found = false;
for (*index = 0; *index < m_Vector.size(); (*index)++)
{
if (value == m_Vector[*index])
{
*found = true;
break;
}
}
return S_OK;
}
virtual HRESULT STDCALL SetAt(uint32_t index, T item) override
{
::Internal::ReleaseItem(m_Vector[index]);
m_Vector[index] = item;
::Internal::AddItemRef(m_Vector[index]);
return S_OK;
}
virtual HRESULT STDCALL InsertAt(uint32_t index, T item) override
{
m_Vector.insert(m_Vector.begin() + index, item);
::Internal::AddItemRef(m_Vector[index]);
return S_OK;
}
virtual HRESULT STDCALL RemoveAt(uint32_t index) override
{
if (m_Vector.size() <= index)
return E_FAIL;
::Internal::ReleaseItem(m_Vector[index]);
m_Vector.erase(m_Vector.begin() + index);
return S_OK;
}
virtual HRESULT STDCALL Append(T item) override
{
m_Vector.push_back(item);
::Internal::AddItemRef(m_Vector.back());
return S_OK;
}
virtual HRESULT STDCALL RemoveAtEnd() override
{
if (m_Vector.empty())
return E_FAIL;
::Internal::ReleaseItem(m_Vector.back());
m_Vector.pop_back();
return S_OK;
}
virtual HRESULT STDCALL ReplaceAll(uint32_t count, T* values) override
{
ClearInternal();
m_Vector.reserve(count);
for (uint32_t i = 0; i < count; i++)
{
m_Vector.push_back(values[i]);
::Internal::AddItemRef(m_Vector.back());
}
return S_OK;
}
virtual HRESULT STDCALL Clear() override
{
ClearInternal();
return S_OK;
}
virtual HRESULT STDCALL First(ABI::Windows::Foundation::Collections::IIterator<T>** first) override
{
*first = Microsoft::WRL::Make<Iterator>(this).Detach();
return S_OK;
}
void Reserve(size_t count)
{
m_Vector.reserve(count);
}
};
}
}