Loading...
iokit/Tests/TestServices/TestDextRematchKernel.cpp xnu-12377.101.15 /dev/null
--- xnu/xnu-12377.101.15/iokit/Tests/TestServices/TestDextRematchKernel.cpp
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (c) 2025 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <IOKit/IOLib.h>
-#include <IOKit/IOUserServer.h>
-#include <IOKit/IOCatalogue.h>
-#include <IOKit/IOKitKeysPrivate.h>
-#include <sys/proc.h>
-
-#if DEVELOPMENT || DEBUG
-
-#include "TestDextRematchKernel.h"
-
-#define super IOService
-OSDefineMetaClassAndStructors(TestDextRematchProvider, IOService)
-
-bool TestDextRematchProvider::_personalitiesInjected = false;
-
-bool
-TestDextRematchProvider::matchPropertyTable(OSDictionary *table)
-{
-	OSString * className = OSDynamicCast(OSString, table->getObject(gIOClassKey));
-	bool bootComplete = __atomic_load_n(&_bootComplete, __ATOMIC_RELAXED);
-	if ((className->isEqualTo("TestDextRematch") || className->isEqualTo("TestDextRematchCompetitor")) && !bootComplete) {
-		// Start fresh and prevent either candidate from matching at the first service registration
-		return false;
-	}
-	return true;
-}
-
-bool
-TestDextRematchProvider::start(IOService *provider)
-{
-	if (!super::start(provider)) {
-		IOLog("%s: super::start failed\n", getName());
-		return false;
-	}
-	_lock = IOLockAlloc();
-	super::registerService();
-
-	OSString * userClientClassName = OSString::withCString("TestDextRematchProviderUserClient");
-	setProperty(gIOUserClientClassKey, userClientClassName);
-	OSSafeReleaseNULL(userClientClassName);
-
-	// Inject kernel side personalities
-	if (!_personalitiesInjected) {
-		OSArray * personalities = OSArray::withCapacity(1);
-		OSDictionary * dict = OSDictionary::withCapacity(3);
-		OSString * ioClassName = OSString::withCString("TestDextRematchCompetitor");
-		OSString * ioProviderClassName = OSString::withCString("TestDextRematchProvider");
-		OSString * ioMatchCategory = OSString::withCString("com.apple.driver.TestDextRematch");
-		dict->setObject(gIOClassKey, ioClassName);
-		dict->setObject(gIOProviderClassKey, ioProviderClassName);
-		dict->setObject(gIOMatchCategoryKey, ioMatchCategory);
-		personalities->setObject(dict);
-
-		if (!gIOCatalogue->addDrivers(personalities)) {
-			IOLog("%s::%s: failed to inject personalities\n", getName(), __func__);
-		}
-		_personalitiesInjected = true;
-
-		OSSafeReleaseNULL(ioMatchCategory);
-		OSSafeReleaseNULL(ioProviderClassName);
-		OSSafeReleaseNULL(ioClassName);
-		OSSafeReleaseNULL(dict);
-		OSSafeReleaseNULL(personalities);
-	}
-
-	IOLog("%s::%s\n", getName(), __func__);
-
-	return true;
-}
-
-void
-TestDextRematchProvider::registerService(IOOptionBits options)
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	__atomic_store_n(&_bootComplete, true, __ATOMIC_RELAXED);
-	super::registerService(options);
-}
-
-void
-TestDextRematchProvider::free()
-{
-	if (_lock) {
-		IOLockFree(_lock);
-		_lock = NULL;
-	}
-	super::free();
-}
-
-bool
-TestDextRematchProvider::shouldStartFail(bool kernel)
-{
-	IOLog("%s::%s: %u\n", getName(), __func__, kernel);
-	bool ret;
-	IOLockLock(_lock);
-	if (kernel) {
-		ret = _childStartFailKernel;
-		_childStartFailKernel = false;
-	} else {
-		ret = _childStartFailUser;
-		_childStartFailUser = false;
-	}
-	IOLockUnlock(_lock);
-	return ret;
-}
-
-bool
-TestDextRematchProvider::shouldRematch()
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	bool ret;
-	IOLockLock(_lock);
-	ret = _childRematchPending;
-	_childRematchPending = false;
-	IOLockUnlock(_lock);
-	return ret;
-}
-
-void
-TestDextRematchProvider::anticipateChildStartFailure(bool kernel)
-{
-	IOLog("%s::%s: %u\n", getName(), __func__, kernel);
-	IOLockLock(_lock);
-	if (kernel) {
-		_childStartFailKernel = true;
-	} else {
-		_childStartFailUser = true;
-	}
-	IOLockUnlock(_lock);
-}
-
-void
-TestDextRematchProvider::anticipateRematch()
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	IOLockLock(_lock);
-	_childRematchPending = true;
-	IOLockUnlock(_lock);
-}
-
-void
-TestDextRematchProvider::terminateChildren()
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	OSIterator * iter = getClientIterator();
-	if (iter) {
-		IOService * child;
-		while ((child = (IOService *)iter->getNextObject()) != NULL) {
-			if (OSDynamicCast(TestDextRematch, child) || OSDynamicCast(TestDextRematchCompetitor, child)) {
-				child->terminate(kIOServiceTerminateNeedWillTerminate);
-			}
-		}
-		iter->release();
-	}
-}
-
-void
-TestDextRematchProvider::clearAllPendingActions()
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	IOLockLock(_lock);
-	_childStartFailKernel = false;
-	_childStartFailUser = false;
-	_childRematchPending = false;
-	IOLockUnlock(_lock);
-}
-
-uint32_t
-TestDextRematchProvider::getClientInstanceCount(uint32_t clientType)
-{
-	IOLog("%s::%s: type %u\n", getName(), __func__, clientType);
-	if (clientType == kTestDextRematchClientTypeDefault) {
-		return TestDextRematch::metaClass->getInstanceCount();
-	} else if (clientType == kTestDextRematchClientTypeCompetitor) {
-		return TestDextRematchCompetitor::metaClass->getInstanceCount();
-	} else {
-		return -1;
-	}
-}
-
-uint32_t
-TestDextRematchProvider::getClientCount(uint32_t clientType)
-{
-	IOLog("%s::%s: type %u\n", getName(), __func__, clientType);
-	OSMetaClass * theMetaClass = NULL;
-	if (clientType == kTestDextRematchClientTypeDefault) {
-		theMetaClass = const_cast<OSMetaClass *>(TestDextRematch::metaClass);
-	} else if (clientType == kTestDextRematchClientTypeCompetitor) {
-		theMetaClass = const_cast<OSMetaClass *>(TestDextRematchCompetitor::metaClass);
-	} else {
-		return -1;
-	}
-
-	OSIterator * it = getClientIterator();
-	uint32_t count = 0;
-	if (it) {
-		IOService * client;
-		while ((client = (IOService *)it->getNextObject())) {
-			if (client->metaCast(theMetaClass)) {
-				count++;
-			}
-		}
-		it->release();
-	}
-	return count;
-}
-
-IOUserServer *
-TestDextRematchProvider::copyMatchingUserServer(IOService * whose)
-{
-	__block IOUserServer * userServer = NULL;
-	OSDictionary * dict = serviceMatching("IOUserServer");
-	OSIterator * iter = getMatchingServices(dict);
-	uint64_t id = whose->getRegistryEntryID();
-	if (iter) {
-		IOService * candidate;
-		while (!userServer && (candidate = (IOService *)iter->getNextObject()) != NULL) {
-			OSObject * obj = candidate->copyProperty("IOAssociatedServices");
-			OSArray * services = OSDynamicCast(OSArray, obj);
-			if (services) {
-				services->iterateObjects(^bool (OSObject *object) {
-					if (((OSNumber *)object)->unsigned64BitValue() == id) {
-					        userServer = OSDynamicCast(IOUserServer, candidate);
-					        assert(userServer);
-					        userServer->retain();
-					        return true;
-					}
-					return false;
-				});
-			}
-			OSSafeReleaseNULL(obj);
-		}
-		iter->release();
-	}
-	dict->release();
-
-	return userServer;
-}
-
-#undef super
-#define super IOUserClient
-OSDefineMetaClassAndStructors(TestDextRematchProviderUserClient, IOUserClient)
-
-IOExternalMethodDispatch
-TestDextRematchProviderUserClient::_methods[] = {
-	{ // Register
-		(IOExternalMethodAction) & TestDextRematchProviderUserClient::_reRegisterService,
-		0, 0,
-		0, 0
-	},
-	{ // Terminate children
-		(IOExternalMethodAction) & TestDextRematchProviderUserClient::_terminateChildren,
-		0, 0,
-		0, 0
-	},
-	{ // Clear all pending actions
-		(IOExternalMethodAction) & TestDextRematchProviderUserClient::_clearAllPendingActions,
-		0, 0,
-		0, 0
-	},
-	{ // Anticipate start failure
-		(IOExternalMethodAction) & TestDextRematchProviderUserClient::_anticipateChildStartFailure,
-		1, 0,
-		0, 0
-	},
-	{ // Anticipate rematch
-		(IOExternalMethodAction) & TestDextRematchProviderUserClient::_anticipateRematch,
-		0, 0,
-		0, 0
-	},
-	{ // Get client instance count
-		(IOExternalMethodAction) & TestDextRematchProviderUserClient::_getClientInstanceCount,
-		1, 0,
-		1, 0
-	},
-	{ // Get attached client instance count
-		(IOExternalMethodAction) & TestDextRematchProviderUserClient::_getClientCount,
-		1, 0,
-		1, 0
-	},
-};
-
-IOReturn
-TestDextRematchProviderUserClient::externalMethod(uint32_t selector, IOExternalMethodArguments * arguments,
-    IOExternalMethodDispatch * dispatch, OSObject * target, void * reference)
-{
-	if (selector < sizeof(_methods) / sizeof(_methods[0])) {
-		dispatch = (IOExternalMethodDispatch *)&_methods[selector];
-		if (!target) {
-			target = this;
-		}
-	}
-
-	return super::externalMethod(selector, arguments, dispatch, target, reference);
-}
-
-bool
-TestDextRematchProviderUserClient::start(IOService *provider)
-{
-	if (!super::start(provider)) {
-		IOLog("%s: super::start failed\n", getName());
-		return false;
-	}
-	_provider = OSDynamicCast(TestDextRematchProvider, provider);
-	assert(_provider);
-	return true;
-}
-
-IOReturn
-TestDextRematchProviderUserClient::_reRegisterService(TestDextRematchProviderUserClient *target, void *reference, IOExternalMethodArguments *arguments)
-{
-	target->reRegisterService();
-	return kIOReturnSuccess;
-}
-
-void
-TestDextRematchProviderUserClient::reRegisterService()
-{
-	_provider->registerService();
-}
-
-IOReturn
-TestDextRematchProviderUserClient::_terminateChildren(TestDextRematchProviderUserClient *target, void *reference, IOExternalMethodArguments *arguments)
-{
-	target->terminateChildren();
-	return kIOReturnSuccess;
-}
-
-void
-TestDextRematchProviderUserClient::terminateChildren()
-{
-	_provider->terminateChildren();
-}
-
-IOReturn
-TestDextRematchProviderUserClient::_clearAllPendingActions(TestDextRematchProviderUserClient *target, void *reference, IOExternalMethodArguments *arguments)
-{
-	target->clearAllPendingActions();
-	return kIOReturnSuccess;
-}
-
-void
-TestDextRematchProviderUserClient::clearAllPendingActions()
-{
-	_provider->clearAllPendingActions();
-}
-
-IOReturn
-TestDextRematchProviderUserClient::_anticipateChildStartFailure(TestDextRematchProviderUserClient *target, void *reference, IOExternalMethodArguments *arguments)
-{
-	assert(arguments->scalarInputCount >= 1);
-	target->anticipateChildStartFailure(arguments->scalarInput[0]);
-	return kIOReturnSuccess;
-}
-
-void
-TestDextRematchProviderUserClient::anticipateChildStartFailure(bool kernel)
-{
-	_provider->anticipateChildStartFailure(kernel);
-}
-
-IOReturn
-TestDextRematchProviderUserClient::_anticipateRematch(TestDextRematchProviderUserClient *target, void *reference, IOExternalMethodArguments *arguments)
-{
-	target->anticipateRematch();
-	return kIOReturnSuccess;
-}
-
-void
-TestDextRematchProviderUserClient::anticipateRematch()
-{
-	_provider->anticipateRematch();
-}
-
-IOReturn
-TestDextRematchProviderUserClient::_getClientInstanceCount(TestDextRematchProviderUserClient *target, void *reference, IOExternalMethodArguments *arguments)
-{
-	arguments->scalarOutput[0] = target->getClientInstanceCount((uint32_t)arguments->scalarInput[0]);
-	arguments->scalarOutputCount = 1;
-	return kIOReturnSuccess;
-}
-
-uint32_t
-TestDextRematchProviderUserClient::getClientInstanceCount(uint32_t clientType)
-{
-	return _provider->getClientInstanceCount(clientType);
-}
-
-IOReturn
-TestDextRematchProviderUserClient::_getClientCount(TestDextRematchProviderUserClient *target, void *reference, IOExternalMethodArguments *arguments)
-{
-	arguments->scalarOutput[0] = target->getClientCount((uint32_t)arguments->scalarInput[0]);
-	arguments->scalarOutputCount = 1;
-	return kIOReturnSuccess;
-}
-
-uint32_t
-TestDextRematchProviderUserClient::getClientCount(uint32_t clientType)
-{
-	return _provider->getClientCount(clientType);
-}
-
-IOReturn
-TestDextRematchProviderUserClient::clientClose()
-{
-	terminate();
-	return kIOReturnSuccess;
-}
-
-#undef super
-#define super IOService
-OSDefineMetaClassAndStructors(TestDextRematch, IOService)
-
-IOService *
-TestDextRematch::probe(IOService * provider, SInt32 * score)
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	*score = 2000;
-	return this;
-}
-
-bool
-TestDextRematch::start(IOService *provider)
-{
-	IOReturn ret;
-
-	IOLog("%s::%s\n", getName(), __func__);
-
-	if (!super::start(provider)) {
-		IOLog("%s: super start failed\n", getName());
-		return false;
-	}
-
-	_provider = OSDynamicCast(TestDextRematchProvider, provider);
-	assert(_provider);
-
-	if (_provider->shouldRematch()) {
-		IOLog("%s: triggering rematch logic\n", getName());
-
-		// Now, kill the user server before leaving
-		IOUserServer * userServer;
-		uint32_t retries = 10; // 5s
-		while ((userServer = _provider->copyMatchingUserServer(this)) == NULL && retries--) {
-			IOSleep(500);
-		}
-		if (!userServer) {
-			IOLog("%s: did not find matching user server\n", getName());
-		} else {
-			userServer->kill("test required");
-			uint32_t retries = 10;
-			while (!userServer->isInactive() && retries--) {
-				IOSleep(500);
-			}
-			if (!userServer->isInactive()) {
-				IOLog("%s: user server failed to be terminated\n", getName());
-			}
-			OSSafeReleaseNULL(userServer);
-		}
-		return false;
-	}
-
-	if (_provider->shouldStartFail(true)) {
-		IOLog("%s: start is forced to fail by test parent\n", getName());
-		return false;
-	}
-
-	ret = Start(provider);
-	IOLog("%s: Start returned 0x%x\n", getName(), ret);
-
-	return ret == kIOReturnSuccess;
-}
-
-void
-TestDextRematch::stop(IOService *provider)
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	super::stop(provider);
-}
-
-void
-TestDextRematch::free()
-{
-	IOLog("%s::%s\n", getName(), __func__);
-	super::free();
-}
-
-bool
-IMPL(TestDextRematch, ShouldStartFail)
-{
-	return _provider->shouldStartFail(false);
-}
-
-kern_return_t
-IMPL(TestDextRematch, Start)
-{
-	return Start(provider, SUPERDISPATCH);
-}
-
-kern_return_t
-IMPL(TestDextRematch, Stop)
-{
-	return Stop(provider, SUPERDISPATCH);
-}
-
-OSDefineMetaClassAndStructors(TestDextRematchCompetitor, IOService)
-
-IOService *
-TestDextRematchCompetitor::probe(IOService * provider, SInt32 * score)
-{
-	IOLog("%s: probe\n", getName());
-	*score = 1000;
-	return this;
-}
-
-bool
-TestDextRematchCompetitor::start(IOService *provider)
-{
-	if (!super::start(provider)) {
-		IOLog("%s: super start failed\n", getName());
-		return false;
-	}
-	IOLog("%s: started\n", getName());
-	return true;
-}
-
-#endif /* DEVELOPMENT || DEBUG */