IOHIDIUnknown2.m   [plain text]

//
// IOHIDIUnknown2.m
// IOHIDLib
//
// Created by dekom on 11/14/17.
//

#import <Foundation/Foundation.h>
#import <IOKit/hid/IOHIDDevicePlugIn.h>
#import "IOHIDIUnknown2.h"

@implementation IOHIDIUnknown2

static HRESULT _queryInterface(void *iunknown,
REFIID uuidBytes,
LPVOID *outInterface)
{
IOHIDIUnknown2 *me = (__bridge id)((*((IUnknownVTbl**)iunknown))->_reserved);

return [me queryInterface:uuidBytes outInterface:outInterface];
}

- (HRESULT)queryInterface:(REFIID __unused)uuidBytes
outInterface:(LPVOID * __unused)outInterface
{
return E_NOINTERFACE;
}

static ULONG _addRef(void *iunknown)
{
IOHIDIUnknown2 *me = (__bridge id)((*((IUnknownVTbl**)iunknown))->_reserved);

CFIndex rc = CFGetRetainCount((CFTypeRef)me);
CFRetain((CFTypeRef)me);
return (ULONG)(rc+1);
}

static ULONG _release(void *iunknown)
{
IOHIDIUnknown2 *me = (__bridge id)((*((IUnknownVTbl**)iunknown))->_reserved);

CFIndex rc = CFGetRetainCount((CFTypeRef)me);
CFRelease((CFTypeRef)me);
return (ULONG)(rc-1);
}

-(instancetype)init
{
self = [super init];

if (!self) {
return nil;
}

_vtbl = (IUnknownVTbl *)malloc(sizeof(*_vtbl));

*_vtbl = (IUnknownVTbl) {
._reserved = (__bridge void *)self,
.QueryInterface = _queryInterface,
.AddRef = _addRef,
.Release = _release,
};

return self;
}

-(void)dealloc
{
free(_vtbl);
}

@end

@implementation IOHIDPlugin

static IOReturn _probe(void *iunknown,
CFDictionaryRef properties,
io_service_t service,
SInt32 *outScore)
{
IOHIDPlugin *me = (__bridge id)((*((IUnknownVTbl**)iunknown))->_reserved);

return [me probe:(__bridge NSDictionary *)properties
service:service
outScore:outScore];
}

- (IOReturn)probe:(NSDictionary * _Nonnull __unused)properties
service:(io_service_t __unused)service
outScore:(SInt32 * _Nonnull __unused)outScore
{
return kIOReturnUnsupported;
}

static IOReturn _start(void *iunknown,
CFDictionaryRef properties,
io_service_t service)
{
IOHIDPlugin *me = (__bridge id)((*((IUnknownVTbl**)iunknown))->_reserved);

return [me start:(__bridge NSDictionary *)properties service:service];
}

- (IOReturn)start:(NSDictionary * _Nonnull __unused)properties
service:(io_service_t __unused)service
{
return kIOReturnUnsupported;
}

static IOReturn _stop(void *iunknown)
{
IOHIDPlugin *me = (__bridge id)((*((IUnknownVTbl**)iunknown))->_reserved);

return [me stop];
}

- (IOReturn)stop
{
return kIOReturnUnsupported;
}

-(instancetype)init
{
self = [super init];

if (!self) {
return nil;
}

_plugin = (IOCFPlugInInterface *)malloc(sizeof(*_plugin));

*_plugin = (IOCFPlugInInterface) {
// IUNKNOWN_C_GUTS
._reserved = (__bridge void *)self,
.QueryInterface = self->_vtbl->QueryInterface,
.AddRef = self->_vtbl->AddRef,
.Release = self->_vtbl->Release,

// IOCFPLUGINBASE
.version = 1,
.revision = 0,
.Probe = _probe,
.Start = _start,
.Stop = _stop,
};

CFPlugInAddInstanceForFactory(kIOHIDDeviceFactoryID);

return self;
}

-(void)dealloc
{
CFPlugInRemoveInstanceForFactory(kIOHIDDeviceFactoryID);
free(_plugin);
}

@end