2024-02-15 17:14:06 -08:00

137 lines
5.8 KiB
Swift

import CWinRT
internal let IID_IMarshal: IID = IID(Data1: 0x01000300, Data2: 0x0000, Data3: 0x0000, Data4: (0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)) // 01000300-0000-0000-C000-00000046
fileprivate extension IUnknownRef {
func copyTo(_ riid: REFIID?, _ ppvObj: UnsafeMutablePointer<LPVOID?>?) -> HRESULT {
self.borrow.pointee.lpVtbl.pointee.QueryInterface(self.borrow, riid, ppvObj)
}
}
func makeMarshaler(_ outer: IUnknownRef, _ result: UnsafeMutablePointer<UnsafeMutableRawPointer?>) throws {
let marshaler = try Marshaler(outer)
let wrapper = MarshalWrapper(marshaler)
try wrapper.toABI {
_ = $0.pointee.lpVtbl.pointee.AddRef($0)
result.pointee = UnsafeMutableRawPointer($0)
}
}
fileprivate class MarshalWrapper: WinRTAbiBridgeWrapper<IMarshalBridge> {
init(_ marshaler: Marshaler){
super.init(IMarshalBridge.makeAbi(), marshaler)
}
}
fileprivate enum IMarshalBridge: AbiBridge {
static func makeAbi() -> C_IMarshal {
return C_IMarshal(lpVtbl: &IMarshalVTable)
}
static func from(abi: ComPtr<C_IMarshal>?) -> Marshaler? {
guard let abi = abi else { return nil }
return try? Marshaler(IUnknownRef(abi))
}
typealias CABI = C_IMarshal
typealias SwiftProjection = Marshaler
}
private var IMarshalVTable: C_IMarshalVtbl = .init(
QueryInterface: { pUnk, riid, ppvObject in
guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG }
switch riid.pointee {
case IID_IMarshal:
_ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk)
return S_OK
default:
guard let obj = MarshalWrapper.tryUnwrapFromBase(raw: pUnk)?.obj else { return E_NOINTERFACE }
return obj.copyTo(riid, ppvObject)
}
},
AddRef: { MarshalWrapper.addRef($0) },
Release: { MarshalWrapper.release($0) },
GetUnmarshalClass: { Marshaler.GetUnmarshalClass($0, $1, $2, $3, $4, $5, $6) },
GetMarshalSizeMax: { Marshaler.GetMarshalSizeMax($0, $1, $2, $3, $4, $5, $6) },
MarshalInterface: { Marshaler.MarshalInterface($0, $1, $2, $3, $4, $5, $6) },
UnmarshalInterface: { Marshaler.UnmarshalInterface($0, $1, $2, $3)},
ReleaseMarshalData: { Marshaler.ReleaseMarshalData($0, $1) },
DisconnectObject: { Marshaler.DisconnectObject($0, $1) }
)
private class Marshaler {
var obj: IUnknownRef
init(_ obj: IUnknownRef) throws {
self.obj = obj
var marshalerPtr: UnsafeMutablePointer<C_IUnknown>?
try CHECKED(CoCreateFreeThreadedMarshaler(nil, &marshalerPtr))
guard let marshalerPtr else { throw WindowsFoundation.Error(hr: E_FAIL) }
marshaler = UnsafeMutableRawPointer(marshalerPtr).bindMemory(to: C_IMarshal.self, capacity: 1)
}
deinit {
_ = marshaler.pointee.lpVtbl.pointee.Release(marshaler)
}
var marshaler: UnsafeMutablePointer<C_IMarshal>
static func GetUnmarshalClass(
_ this: UnsafeMutablePointer<C_IMarshal>?,
_ riid: REFIID?,
_ pv: UnsafeMutableRawPointer?,
_ dwDestContext: DWORD,
_ pvDestContext: UnsafeMutableRawPointer?,
_ mshlflags: DWORD,
_ pCid: UnsafeMutablePointer<CLSID>?) -> HRESULT {
guard let marshaler = MarshalWrapper.tryUnwrapFrom(abi: ComPtr(this))?.marshaler else { return E_FAIL }
return marshaler.pointee.lpVtbl.pointee.GetUnmarshalClass(marshaler, riid, pv, dwDestContext, pvDestContext, mshlflags, pCid)
}
static func GetMarshalSizeMax(
_ this: UnsafeMutablePointer<C_IMarshal>?,
_ riid: REFIID?, _ pv: UnsafeMutableRawPointer?,
_ dwDestContext: DWORD,
_ pvDestContext: UnsafeMutableRawPointer?,
_ mshlflags: DWORD,
_ pSize: UnsafeMutablePointer<DWORD>?) -> HRESULT {
guard let marshaler = MarshalWrapper.tryUnwrapFrom(abi: ComPtr(this))?.marshaler else { return E_FAIL }
return marshaler.pointee.lpVtbl.pointee.GetMarshalSizeMax(marshaler, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize)
}
static func MarshalInterface(
_ this: UnsafeMutablePointer<C_IMarshal>?,
_ pStm: UnsafeMutablePointer<IStream>?,
_ riid: REFIID?,
_ pv: UnsafeMutableRawPointer?,
_ dwDestContext: DWORD,
_ pvDestContext: UnsafeMutableRawPointer?,
_ mshlflags: DWORD) -> HRESULT {
guard let marshaler = MarshalWrapper.tryUnwrapFrom(abi: ComPtr(this))?.marshaler else { return E_FAIL }
return marshaler.pointee.lpVtbl.pointee.MarshalInterface(marshaler, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags)
}
static func UnmarshalInterface(
_ this: UnsafeMutablePointer<C_IMarshal>?,
_ pStm: UnsafeMutablePointer<IStream>?,
_ riid: REFIID?,
_ ppv: UnsafeMutablePointer<UnsafeMutableRawPointer?>?) -> HRESULT {
guard let marshaler = MarshalWrapper.tryUnwrapFrom(abi: ComPtr(this))?.marshaler else { return E_FAIL }
return marshaler.pointee.lpVtbl.pointee.UnmarshalInterface(marshaler, pStm, riid, ppv)
}
static func ReleaseMarshalData(
_ this: UnsafeMutablePointer<C_IMarshal>?,
_ pStm: UnsafeMutablePointer<IStream>?) -> HRESULT {
guard let marshaler = MarshalWrapper.tryUnwrapFrom(abi: ComPtr(this))?.marshaler else { return E_FAIL }
return marshaler.pointee.lpVtbl.pointee.ReleaseMarshalData(marshaler, pStm)
}
static func DisconnectObject(
_ this: UnsafeMutablePointer<C_IMarshal>?,
_ dwReserved: DWORD) -> HRESULT {
guard let marshaler = MarshalWrapper.tryUnwrapFrom(abi: ComPtr(this))?.marshaler else { return E_FAIL }
return marshaler.pointee.lpVtbl.pointee.DisconnectObject(marshaler, dwReserved)
}
}