1/* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22/* 23 * IOFireWireLibUnitDirectory.cpp 24 * IOFireWireLib 25 * 26 * Created by NWG on Thu Apr 27 2000. 27 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 28 * 29 */ 30 31#import "IOFireWireLibUnitDirectory.h" 32#import "IOFireWireLibDevice.h" 33 34#import <System/libkern/OSCrossEndian.h> 35 36namespace IOFireWireLib { 37 38 // static interface table 39 LocalUnitDirectory::Interface LocalUnitDirectory::sInterface = 40 { 41 INTERFACEIMP_INTERFACE, 42 1, 0, // version/revision 43 & LocalUnitDirectory::SAddEntry_Ptr, 44 & LocalUnitDirectory::SAddEntry_UInt32, 45 & LocalUnitDirectory::SAddEntry_FWAddress, 46 & LocalUnitDirectory::SPublish, 47 & LocalUnitDirectory::SUnpublish 48 } ; 49 50 // ============================================================ 51 // LocalUnitDirectory implementation 52 // ============================================================ 53 54 LocalUnitDirectory::LocalUnitDirectory( Device& userclient ) 55 : IOFireWireIUnknown( reinterpret_cast<const IUnknownVTbl &>( sInterface) ), 56 mUserClient(userclient), 57 mPublished(false) 58 { 59 uint32_t outputCnt = 1; 60 uint64_t outputVal = 0; 61 IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 62 kLocalConfigDirectory_Create, 63 NULL,0,&outputVal,&outputCnt); 64 mKernUnitDirRef = (UserObjectHandle) outputVal; 65 } 66 67 LocalUnitDirectory::~LocalUnitDirectory() 68 { 69 if (mPublished) 70 Unpublish() ; 71 } 72 73 LocalUnitDirectory::Interface** 74 LocalUnitDirectory::Alloc( Device& userclient ) 75 { 76 LocalUnitDirectory* me = new LocalUnitDirectory( userclient ) ; 77 78 if( !me ) 79 return nil ; 80 81 return reinterpret_cast<Interface**>(&me->GetInterface()) ; 82 } 83 84 HRESULT STDMETHODCALLTYPE 85 LocalUnitDirectory::QueryInterface(REFIID iid, LPVOID* ppv) 86 { 87 HRESULT result = S_OK ; 88 *ppv = nil ; 89 90 CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ; 91 92 if (CFEqual(interfaceID, IUnknownUUID) || CFEqual(interfaceID, kIOFireWireLocalUnitDirectoryInterfaceID) ) 93 { 94 *ppv = & GetInterface() ; 95 AddRef() ; 96 } 97 else 98 { 99 *ppv = nil ; 100 result = E_NOINTERFACE ; 101 } 102 103 CFRelease(interfaceID) ; 104 return result ; 105 } 106 107 inline const char * 108 CFStringGetChars( CFStringRef string, unsigned & outLen ) 109 { 110 CFIndex stringLength = ::CFStringGetLength( string ) ; 111 112 const char * result = ::CFStringGetCStringPtr( string, kCFStringEncodingUTF8 ) ; 113 if ( result ) 114 { 115 outLen = (unsigned)stringLength ; 116 return result ; 117 } 118 119 CFIndex bufferSize = ::CFStringGetBytes( string, ::CFRangeMake( 0, stringLength ), kCFStringEncodingUTF8, 120 0xFF, false, NULL, 0, NULL ) ; 121 122 UInt8 inlineBuffer[ bufferSize ] ; 123 result = (char*)inlineBuffer ; 124 125 ::CFStringGetBytes( string, ::CFRangeMake( 0, stringLength ), kCFStringEncodingUTF8, 0xFF, false, inlineBuffer, bufferSize, NULL ) ; 126 127 outLen = bufferSize ; 128 return result ; 129 } 130 131 IOReturn 132 LocalUnitDirectory::AddEntry( int key, void* buffer, size_t len, CFStringRef desc ) 133 { 134 unsigned descLen = 0; 135 const char * descCString = NULL; 136 137 if( desc ) 138 { 139 descCString = CFStringGetChars( desc, descLen ) ; 140 } 141 142 uint32_t outputCnt = 0; 143 const uint64_t inputs[6] = {(const uint64_t)mKernUnitDirRef, key, (const uint64_t)buffer,len, (const uint64_t)descCString, descLen}; 144 return IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), kLocalConfigDirectory_AddEntry_Buffer, 145 inputs,6, 146 NULL,&outputCnt); 147 } 148 149 IOReturn 150 LocalUnitDirectory::AddEntry( 151 int key, 152 UInt32 value, 153 CFStringRef desc ) 154 { 155 unsigned descLen = 0; 156 const char * descCString = NULL; 157 158 if( desc ) 159 { 160 descCString = CFStringGetChars( desc, descLen ) ; 161 } 162 163 uint32_t outputCnt = 0; 164 const uint64_t inputs[5] = {(const uint64_t)mKernUnitDirRef, key, value, (const uint64_t)descCString, descLen}; 165 IOReturn err = IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), kLocalConfigDirectory_AddEntry_UInt32, 166 inputs,5, 167 NULL,&outputCnt); 168 169 DebugLogCond( err, "LocalUnitDirectory::AddEntry[UInt32](): result = 0x%08x\n", err ) ; 170 171 return err ; 172 } 173 174 IOReturn 175 LocalUnitDirectory::AddEntry( 176 int key, 177 const FWAddress & value, 178 CFStringRef desc ) 179 { 180 unsigned descLen = 0; 181 const char * descCString = NULL; 182 183 if( desc ) 184 { 185 descCString = CFStringGetChars( desc, descLen ) ; 186 } 187 188 FWAddress host_value(value); 189 190#ifndef __LP64__ 191 ROSETTA_ONLY( 192 { 193 host_value.nodeID = OSSwapInt16( value.nodeID ); 194 host_value.addressHi = OSSwapInt16( value.addressHi ); 195 host_value.addressLo = OSSwapInt32( value.addressLo ); 196 } 197 ); 198#endif 199 uint32_t outputCnt = 0; 200 size_t outputStructSize = 0 ; 201 const uint64_t inputs[4] = {(const uint64_t)mKernUnitDirRef, key, (const uint64_t)descCString,descLen}; 202 return IOConnectCallMethod(mUserClient.GetUserClientConnection(), 203 kLocalConfigDirectory_AddEntry_FWAddr, 204 inputs,4, 205 &host_value,sizeof(value), 206 NULL,&outputCnt, 207 NULL,&outputStructSize); 208 } 209 210 IOReturn 211 LocalUnitDirectory::Publish() 212 { 213 if (mPublished) 214 return kIOReturnSuccess ; 215 216 uint32_t outputCnt = 0; 217 const uint64_t inputs[1]={(const uint64_t)mKernUnitDirRef}; 218 219 IOReturn err = IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 220 kLocalConfigDirectory_Publish, 221 inputs,1, 222 NULL,&outputCnt); 223 224 mPublished = ( kIOReturnSuccess == err ) ; 225 226 return err ; 227 } 228 229 IOReturn 230 LocalUnitDirectory::Unpublish() 231 { 232 if (!mPublished) 233 return kIOReturnSuccess ; 234 235 uint32_t outputCnt = 0; 236 const uint64_t inputs[1]={(const uint64_t)mKernUnitDirRef}; 237 IOReturn err = IOConnectCallScalarMethod(mUserClient.GetUserClientConnection(), 238 kLocalConfigDirectory_Unpublish, 239 inputs,1, 240 NULL,&outputCnt); 241 242 mPublished = (!err) ; 243 244 return err ; 245 } 246 247 // ============================================================ 248 // 249 // static interface methods 250 // 251 // ============================================================ 252 253 IOReturn 254 LocalUnitDirectory::SAddEntry_Ptr( 255 DirRef self, 256 int key, 257 void* inBuffer, 258 size_t inLen, 259 CFStringRef inDesc) 260 { 261 return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->AddEntry(key, inBuffer, inLen, inDesc); 262 } 263 264 IOReturn 265 LocalUnitDirectory::SAddEntry_UInt32( 266 DirRef self, 267 int key, 268 UInt32 value, 269 CFStringRef inDesc) 270 { 271 return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->AddEntry(key, value, inDesc); 272 } 273 274 IOReturn 275 LocalUnitDirectory::SAddEntry_FWAddress( 276 DirRef self, 277 int key, 278 const FWAddress* inAddr, 279 CFStringRef inDesc) 280 { 281 return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->AddEntry(key, *inAddr, inDesc); 282 } 283 284 IOReturn 285 LocalUnitDirectory::SPublish( 286 DirRef self) 287 { 288 return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->Publish(); 289 } 290 291 IOReturn 292 LocalUnitDirectory::SUnpublish( 293 DirRef self) 294 { 295 return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->Unpublish(); 296 } 297} 298