+/*
+ * Copyright (c) 2002-2016 Apple 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@
+ */
/*
* DINetBootHook.c
* DiskImages
*
* Created by Byron Han on Sat Apr 13 2002.
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
*
* Revision History
*
* $Log: DINetBootHook.cpp,v $
+ * Revision 1.4 2005/07/29 21:49:57 lindak
+ * Merge of branch "chardonnay" to pick up all chardonnay changes in Leopard
+ * as of xnu-792.7.4
+ *
* Revision 1.3.1558.1 2005/06/24 01:47:25 lindak
* Bringing over all of the Karma changes into chardonnay.
- *
+ *
* Revision 1.1.1.1 2005/02/24 21:48:06 akosut
* Import xnu-764 from Tiger8A395
*
#include <sys/types.h>
#include <IOKit/IOService.h>
#include <IOKit/IOLib.h>
+#include "DINetBootHook.h"
#define kIOHDIXControllerClassName "IOHDIXController"
#define kDIRootImageKey "di-root-image"
#define kDIRootImageResultKey "di-root-image-result"
#define kDIRootImageDevNameKey "di-root-image-devname"
#define kDIRootImageDevTKey "di-root-image-devt"
+#define kDIRootRamFileKey "di-root-ram-file"
+
+static IOService *
+di_load_controller( void )
+{
+ OSIterator * controllerIterator = 0;
+ OSDictionary * matchDictionary = 0;
+ IOService * controller = 0;
+
+ do {
+ IOService::getResourceService()->publishResource("com.apple.AppleDiskImageController.load", kOSBooleanTrue);
+ IOService::getResourceService()->waitQuiet();
+
+ // first find IOHDIXController
+ matchDictionary = IOService::serviceMatching(kIOHDIXControllerClassName);
+ if (!matchDictionary)
+ break;
+
+ controllerIterator = IOService::getMatchingServices(matchDictionary);
+ if (!controllerIterator)
+ break;
+
+ controller = OSDynamicCast(IOService, controllerIterator->getNextObject());
+ if (!controller)
+ break;
+
+ controller->retain();
+ } while (false);
+
+ if (matchDictionary) matchDictionary->release();
+ if (controllerIterator) controllerIterator->release();
+
+ return controller;
+}
extern "C" {
/*
dev_p <- device number generated from major/minor numbers
Comments:
*/
-int di_root_image(const char *path, char devname[], dev_t *dev_p)
+int di_root_image(const char *path, char *devname, size_t devsz, dev_t *dev_p)
{
IOReturn res = 0;
- OSIterator * controllerIterator = 0;
- OSDictionary * matchDictionary = 0;
IOService * controller = 0;
OSString * pathString = 0;
OSNumber * myResult = 0;
if (!devname) return kIOReturnBadArgument;
if (!dev_p) return kIOReturnBadArgument;
- (void)IOService::getResourceService()->publishResource("com.apple.AppleDiskImageController.load", kOSBooleanTrue);
- IOService::getResourceService()->waitQuiet();
-
- // first find IOHDIXController
- matchDictionary = IOService::serviceMatching(kIOHDIXControllerClassName);
- if (!matchDictionary) {
- res = kIOReturnNoMemory;
- goto serviceMatching_FAILED;
- }
-
- controllerIterator = IOService::getMatchingServices(matchDictionary);
- if (!controllerIterator) {
- res = kIOReturnNoMemory;
- goto getMatchingServices_FAILED;
- }
-
- // use the "setProperty" method of IOHDIXController to trigger the desired behaviour
- controller = OSDynamicCast(IOService, controllerIterator->getNextObject());
+ controller = di_load_controller();
if (!controller) {
res = kIOReturnNotFound;
goto NoIOHDIXController;
}
myDevName = OSDynamicCast(OSString, controller->getProperty(kDIRootImageDevNameKey));
- if (myDevName)
- strcpy(devname, myDevName->getCStringNoCopy());
- else {
+ if (myDevName) {
+ strlcpy(devname, myDevName->getCStringNoCopy(), devsz);
+ } else {
IOLog("could not get %s\n", kDIRootImageDevNameKey);
res = kIOReturnError;
goto di_root_image_FAILED;
di_root_image_FAILED:
CannotCreatePathOSString:
-serviceMatching_FAILED:
NoIOHDIXController:
-getMatchingServices_FAILED:
// clean up memory allocations
if (pathString) pathString->release();
- if (matchDictionary) matchDictionary->release();
- if (controllerIterator) controllerIterator->release();
+ if (controller) controller->release();
+
+ return res;
+}
+
+int
+di_root_ramfile_buf(void *buf, size_t bufsz, char *devname, size_t devsz, dev_t *dev_p)
+{
+ IOReturn res = 0;
+ IOService *controller = 0;
+ OSNumber *myResult = 0;
+ OSString *myDevName = 0;
+ OSNumber *myDevT = 0;
+ IOMemoryDescriptor *mem = 0;
+
+ mem = IOMemoryDescriptor::withAddress(buf, bufsz, kIODirectionInOut);
+ assert(mem);
+
+ controller = di_load_controller();
+ if (controller) {
+ /* attach the image */
+ controller->setProperty(kDIRootRamFileKey, mem);
+ controller->release();
+ } else {
+ res = kIOReturnNotFound;
+ goto out;
+ }
+
+ myResult = OSDynamicCast(OSNumber, controller->getProperty(kDIRootImageResultKey));
+ res = kIOReturnError;
+ if (myResult) {
+ res = myResult->unsigned32BitValue();
+ }
+
+ if (res) {
+ IOLog("%s is 0x%08X/%d\n", kDIRootImageResultKey, res, res);
+ goto out;
+ }
+
+ myDevT = OSDynamicCast(OSNumber, controller->getProperty(kDIRootImageDevTKey));
+ if (myDevT)
+ *dev_p = myDevT->unsigned32BitValue();
+ else {
+ IOLog("could not get %s\n", kDIRootImageDevTKey);
+ res = kIOReturnError;
+ goto out;
+ }
+
+ myDevName = OSDynamicCast(OSString, controller->getProperty(kDIRootImageDevNameKey));
+ if (myDevName) {
+ strlcpy(devname, myDevName->getCStringNoCopy(), devsz);
+ } else {
+ IOLog("could not get %s\n", kDIRootImageDevNameKey);
+ res = kIOReturnError;
+ goto out;
+ }
+
+out:
+ if (res) {
+ OSSafeReleaseNULL(mem);
+ }
return res;
}
+void di_root_ramfile( IORegistryEntry * entry )
+{
+ OSData * data;
+ IOMemoryDescriptor * mem;
+ uint64_t dmgSize;
+ uint64_t remain, length;
+ OSData * extentData = 0;
+ IOAddressRange * extentList;
+ uint64_t extentSize;
+ uint32_t extentCount;
+
+ do {
+ data = OSDynamicCast(OSData, entry->getProperty("boot-ramdmg-size"));
+ if (!data || (data->getLength() != sizeof(uint64_t)))
+ break; // bad disk image size
+
+ dmgSize = *(uint64_t *) data->getBytesNoCopy();
+ if (!dmgSize)
+ break;
+
+ data = OSDynamicCast(OSData, entry->getProperty("boot-ramdmg-extents"));
+ if (!data || (data->getLength() == 0) ||
+ ((data->getLength() & (sizeof(IOAddressRange)-1)) != 0))
+ break; // bad extents
+
+ // make modifications to local copy
+ extentData = OSData::withData(data);
+ assert(extentData);
+
+ extentList = (IOAddressRange *) extentData->getBytesNoCopy();
+ extentCount = extentData->getLength() / sizeof(IOAddressRange);
+ extentSize = 0;
+ remain = dmgSize;
+
+ // truncate extent length to enclosing disk image
+ for (uint32_t i = 0; i < extentCount; i++)
+ {
+ length = extentList[i].length;
+ if (!length) break;
+
+ extentSize += length;
+ if (length >= remain)
+ {
+ extentList[i].length = remain;
+ extentCount = i + 1;
+ break;
+ }
+ remain -= length;
+ }
+ if (extentSize < dmgSize)
+ break; // not enough extent bytes for enclosing disk image
+
+ mem = IOMemoryDescriptor::withAddressRanges(
+ extentList, extentCount,
+ kIODirectionOut | kIOMemoryMapperNone, NULL);
+
+ if (mem)
+ {
+ IOService * controller = di_load_controller();
+ if (controller)
+ {
+ controller->setProperty(kDIRootRamFileKey, mem);
+ controller->release();
+ }
+ mem->release();
+ }
+ } while (false);
+
+ if (extentData)
+ extentData->release();
+}
+
};