/* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This 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 OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * IOFireWireLibUnitDirectory.cpp * IOFireWireLib * * Created by NWG on Thu Apr 27 2000. * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * */ #include <CoreFoundation/CoreFoundation.h> #include <IOKit/IOKitLib.h> #include <IOKit/iokitmig.h> #include "IOFireWireLib.h" #include "IOFireWireLibUnitDirectory.h" //#define __IOFireWireClientDebug__ 1 // ============================================================ // // static interface table // // ============================================================ IOFireWireLocalUnitDirectoryInterface IOFireWireLocalUnitDirectoryImp::sInterface = { INTERFACEIMP_INTERFACE, 1, 0, // version/revision & IOFireWireLocalUnitDirectoryImp::SAddEntry_Ptr, & IOFireWireLocalUnitDirectoryImp::SAddEntry_UInt32, & IOFireWireLocalUnitDirectoryImp::SAddEntry_FWAddress, & IOFireWireLocalUnitDirectoryImp::SPublish, & IOFireWireLocalUnitDirectoryImp::SUnpublish // 0, // set device added callback // 0, // set device removed callback // 0, // command is complete? // 0, // turn on notification // 0, // turn off notification } ; IUnknownVTbl** IOFireWireLocalUnitDirectoryImp::Alloc( IOFireWireDeviceInterfaceImp& inUserClient) { IOFireWireLocalUnitDirectoryImp* me = new IOFireWireLocalUnitDirectoryImp(inUserClient) ; IUnknownVTbl** interface = NULL; if( me ) { // me->AddRef(); interface = (IUnknownVTbl**) &me->mInterface ; } return interface; } HRESULT STDMETHODCALLTYPE IOFireWireLocalUnitDirectoryImp::QueryInterface(REFIID iid, LPVOID* ppv) { HRESULT result = S_OK ; *ppv = nil ; CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ; if (CFEqual(interfaceID, IUnknownUUID) || CFEqual(interfaceID, kIOFireWireLocalUnitDirectoryInterfaceID) ) { *ppv = & mInterface ; AddRef() ; } else { *ppv = nil ; result = E_NOINTERFACE ; } CFRelease(interfaceID) ; return result ; } // ============================================================ // // static interface methods // // ============================================================ IOReturn IOFireWireLocalUnitDirectoryImp::SAddEntry_Ptr( IOFireWireLibLocalUnitDirectoryRef self, int key, void* inBuffer, size_t inLen, CFStringRef inDesc) { return GetThis(self)->AddEntry(key, inBuffer, inLen, inDesc); } IOReturn IOFireWireLocalUnitDirectoryImp::SAddEntry_UInt32( IOFireWireLibLocalUnitDirectoryRef self, int key, UInt32 value, CFStringRef inDesc) { return GetThis(self)->AddEntry(key, value, inDesc); } IOReturn IOFireWireLocalUnitDirectoryImp::SAddEntry_FWAddress( IOFireWireLibLocalUnitDirectoryRef self, int key, const FWAddress* inAddr, CFStringRef inDesc) { return GetThis(self)->AddEntry(key, *inAddr, inDesc); } IOReturn IOFireWireLocalUnitDirectoryImp::SPublish( IOFireWireLibLocalUnitDirectoryRef self) { return GetThis(self)->Publish(); } IOReturn IOFireWireLocalUnitDirectoryImp::SUnpublish( IOFireWireLibLocalUnitDirectoryRef self) { return GetThis(self)->Unpublish(); } // ============================================================ // IOFireWireLocalUnitDirectoryImp implementation // ============================================================ #pragma mark - #pragma mark [constructors/destructors] IOFireWireLocalUnitDirectoryImp::IOFireWireLocalUnitDirectoryImp( IOFireWireDeviceInterfaceImp& inUserClient): IOFireWireIUnknown(), mUserClient(inUserClient), mPublished(false) { #if __IOFireWireClientDebug__ fprintf(stderr, "mUserClient.IsInited=%08lX, mKernUnitDirRef=%08lX\n", mUserClient.IsInited(), mKernUnitDirRef) ; #endif // ask IOFireWireFamily to create a unit directory in the kernel if (mUserClient.IsInited()) { io_connect_t connection ; // if (!mKernUnitDirRef) if ( nil != (connection = mUserClient.GetUserClientConnection()) ) { mach_msg_type_number_t size = 1 ; io_connect_method_scalarI_scalarO( connection, kFWUnitDirCreate, nil, 0, (int*) & mKernUnitDirRef, & size) ; #if __IOFireWireClientDebug__ fprintf(stderr, "IOFireWireLocalUnitDirectoryImp::IOFireWireLocalUnitDirectoryImp(): mKernUnitDir created @ %08lX\n", (UInt32) mKernUnitDirRef) ; #endif } } // COM support mInterface.pseudoVTable = (IUnknownVTbl*) & sInterface ; mInterface.obj = this ; } IOFireWireLocalUnitDirectoryImp::~IOFireWireLocalUnitDirectoryImp() { if (mPublished) Unpublish() ; } #pragma mark - #pragma mark [ IOReturn IOFireWireLocalUnitDirectoryImp::AddEntry( int key, void* inBuffer, size_t inLen, CFStringRef /*inDesc = NULL*/) // zzz don't know what to do with this yet... // zzz should probably make it go into the kernel { #if __IOFireWireClientDebug__ fprintf( stderr, "IOFireWireLib: + IOFireWireLocalUnitDirectoryImp::AddEntry() (inLen = %08lX, inKey = %08lX)\n", (UInt32)inLen, (UInt32)key) ; #endif IOReturn kr = kIOReturnNoDevice ; if (inLen > 0xC00) { #if (__IOFireWireClientDebug__) fprintf(stderr, "IOFireWireLib: IOFireWireLocalUnitDirectoryImp::AddEntry(): input too large\n") ; #endif return kr = kIOReturnBadArgument ; } io_connect_t connection ; if ( nil != (connection = mUserClient.GetUserClientConnection()) ) { io_scalar_inband_t params ; params[0] = (UInt32) mKernUnitDirRef ; params[1] = key ; kr = io_connect_method_scalarI_structureI( connection, kFWUnitDirAddEntry_Buffer, params, 2, (io_struct_inband_t) inBuffer, inLen ) ; #if __IOFireWireClientDebug__ fprintf( stderr, "AddEntry() got %08lX\n", (UInt32) kr) ; #endif } #if __IOFireWireClientDebug__ fprintf( stderr, "IOFireWireLocalUnitDirectoryImp::AddEntry(): result = %08lX\n", (UInt32) kr) ; #endif return kr ; } IOReturn IOFireWireLocalUnitDirectoryImp::AddEntry( int key, UInt32 value, CFStringRef /*inDesc = NULL*/) // zzz don't know what to do with this yet... // zzz should probably go into kernel { #if __IOFireWireClientDebug__ fprintf( stderr, "IOFireWireLib: + IOFireWireLocalUnitDirectoryImp::AddEntry[UInt32]() (inKey = %08lX)\n", (UInt32)key) ; #endif IOReturn kr = kIOReturnNoDevice ; io_connect_t connection ; if ( nil != (connection = mUserClient.GetUserClientConnection()) ) { mach_msg_type_number_t size = 0 ; io_scalar_inband_t params ; params[0] = (UInt32) mKernUnitDirRef ; params[1] = key ; params[2] = value ; fprintf(stderr, "add entry mKernUnitDirRef=%08lX\n", mKernUnitDirRef) ; kr = io_connect_method_scalarI_scalarO( connection, kFWUnitDirAddEntry_UInt32, params, 3, params, & size ) ; #if __IOFireWireClientDebug__ fprintf( stderr, "AddEntry() got %08lX\n", (UInt32) kr) ; #endif } #if __IOFireWireClientDebug__ fprintf( stderr, "IOFireWireLocalUnitDirectoryImp::AddEntry[UInt32](): result = %08lX\n", (UInt32) kr) ; #endif return kr ; } IOReturn IOFireWireLocalUnitDirectoryImp::AddEntry( int key, const FWAddress & value, CFStringRef /*inDesc = NULL*/) // zzz don't know what to do with this yet... // zzz should probably go into kernel { #if __IOFireWireClientDebug__ fprintf( stderr, "IOFireWireLib: + IOFireWireLocalUnitDirectoryImp::AddEntry() (inKey = %08lX)\n", (UInt32)key) ; #endif IOReturn kr = kIOReturnNoDevice ; io_connect_t connection ; if ( nil != (connection = mUserClient.GetUserClientConnection()) ) { io_scalar_inband_t params ; params[0] = (UInt32) mKernUnitDirRef ; params[1] = key ; kr = io_connect_method_scalarI_structureI( connection, kFWUnitDirAddEntry_FWAddr, params, 2, (char*) & value, sizeof(value) ) ; } return kr ; } IOReturn IOFireWireLocalUnitDirectoryImp::Publish() { #if __IOFireWireClientDebug__ fprintf(stderr, "IOFireWireLocalUnitDirectoryImp::Publish()\n") ; #endif io_connect_t connection ; IOReturn kr = kIOReturnSuccess ; if (!mPublished) { if (nil == (connection = mUserClient.GetUserClientConnection()) ) kr = kIOReturnNoDevice ; if ( kIOReturnSuccess == kr ) { io_scalar_inband_t params ; io_scalar_inband_t output ; mach_msg_type_number_t size = 0 ; params[0] = (UInt32) mKernUnitDirRef ; kr = io_connect_method_scalarI_scalarO( connection, kFWUnitDirPublish, params, 1, & output[0], & size ) ; } mPublished = (kr == kIOReturnSuccess) ; } return kr ; } IOReturn IOFireWireLocalUnitDirectoryImp::Unpublish() { io_connect_t connection ; IOReturn kr = kIOReturnSuccess ; if (mPublished) { if (nil == (connection = mUserClient.GetUserClientConnection()) ) kr = kIOReturnNoDevice ; if ( kIOReturnSuccess == kr ) { io_scalar_inband_t params ; io_scalar_inband_t output ; mach_msg_type_number_t size = 0 ; params[0] = (UInt32) mKernUnitDirRef ; kr = io_connect_method_scalarI_scalarO( connection, kFWUnitDirUnpublish, params, 1, & output[0], & size ) ; } if (kIOReturnSuccess == kr) mPublished = false ; } return kr ; }