IOFireWireLibUnitDirectory.cpp [plain text]
#import "IOFireWireLibUnitDirectory.h"
#import "IOFireWireLibDevice.h"
#import <System/libkern/OSCrossEndian.h>
namespace IOFireWireLib {
LocalUnitDirectory::Interface LocalUnitDirectory::sInterface =
{
INTERFACEIMP_INTERFACE,
1, 0, & LocalUnitDirectory::SAddEntry_Ptr,
& LocalUnitDirectory::SAddEntry_UInt32,
& LocalUnitDirectory::SAddEntry_FWAddress,
& LocalUnitDirectory::SPublish,
& LocalUnitDirectory::SUnpublish
} ;
LocalUnitDirectory::LocalUnitDirectory( Device& userclient )
: IOFireWireIUnknown( reinterpret_cast<const IUnknownVTbl &>( sInterface) ),
mUserClient(userclient),
mPublished(false)
{
IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(), kLocalConfigDirectory_Create,
0, 1, & mKernUnitDirRef ) ;
}
LocalUnitDirectory::~LocalUnitDirectory()
{
if (mPublished)
Unpublish() ;
}
LocalUnitDirectory::Interface**
LocalUnitDirectory::Alloc( Device& userclient )
{
LocalUnitDirectory* me = new LocalUnitDirectory( userclient ) ;
if( !me )
return nil ;
return reinterpret_cast<Interface**>(&me->GetInterface()) ;
}
HRESULT STDMETHODCALLTYPE
LocalUnitDirectory::QueryInterface(REFIID iid, LPVOID* ppv)
{
HRESULT result = S_OK ;
*ppv = nil ;
CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ;
if (CFEqual(interfaceID, IUnknownUUID) || CFEqual(interfaceID, kIOFireWireLocalUnitDirectoryInterfaceID) )
{
*ppv = & GetInterface() ;
AddRef() ;
}
else
{
*ppv = nil ;
result = E_NOINTERFACE ;
}
CFRelease(interfaceID) ;
return result ;
}
inline const char *
CFStringGetChars( CFStringRef string, unsigned & outLen )
{
CFIndex stringLength = ::CFStringGetLength( string ) ;
const char * result = ::CFStringGetCStringPtr( string, kCFStringEncodingUTF8 ) ;
if ( result )
{
outLen = (unsigned)stringLength ;
return result ;
}
CFIndex bufferSize = ::CFStringGetBytes( string, ::CFRangeMake( 0, stringLength ), kCFStringEncodingUTF8,
0xFF, false, NULL, 0, NULL ) ;
UInt8 inlineBuffer[ bufferSize ] ;
result = (char*)inlineBuffer ;
::CFStringGetBytes( string, ::CFRangeMake( 0, stringLength ), kCFStringEncodingUTF8, 0xFF, false, inlineBuffer, bufferSize, NULL ) ;
outLen = bufferSize ;
return result ;
}
IOReturn
LocalUnitDirectory::AddEntry( int key, void* buffer, size_t len, CFStringRef desc )
{
unsigned descLen = 0;
const char * descCString = NULL;
if( desc )
{
descCString = CFStringGetChars( desc, descLen ) ;
}
return ::IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(), kLocalConfigDirectory_AddEntry_Buffer, 6, 0,
mKernUnitDirRef, key, buffer, len, descCString, descLen ) ;
}
IOReturn
LocalUnitDirectory::AddEntry(
int key,
UInt32 value,
CFStringRef desc )
{
unsigned descLen = 0;
const char * descCString = NULL;
if( desc )
{
descCString = CFStringGetChars( desc, descLen ) ;
}
IOReturn err = IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(),
kLocalConfigDirectory_AddEntry_UInt32, 5, 0, mKernUnitDirRef, key, value, descCString, descLen ) ;
DebugLogCond( err, "LocalUnitDirectory::AddEntry[UInt32](): result = 0x%08x\n", err ) ;
return err ;
}
IOReturn
LocalUnitDirectory::AddEntry(
int key,
const FWAddress & value,
CFStringRef desc )
{
unsigned descLen = 0;
const char * descCString = NULL;
if( desc )
{
descCString = CFStringGetChars( desc, descLen ) ;
}
FWAddress host_value(value);
ROSETTA_ONLY(
{
host_value.nodeID = OSSwapInt16( value.nodeID );
host_value.addressHi = OSSwapInt16( value.addressHi );
host_value.addressLo = OSSwapInt32( value.addressLo );
}
);
return IOConnectMethodScalarIStructureI( mUserClient.GetUserClientConnection(),
kLocalConfigDirectory_AddEntry_FWAddr,
4, sizeof(value), mKernUnitDirRef, key, descCString, descLen, & host_value) ;
}
IOReturn
LocalUnitDirectory::Publish()
{
if (mPublished)
return kIOReturnSuccess ;
IOReturn err = IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(),
kLocalConfigDirectory_Publish,
1, 0, mKernUnitDirRef ) ;
mPublished = ( kIOReturnSuccess == err ) ;
return err ;
}
IOReturn
LocalUnitDirectory::Unpublish()
{
if (!mPublished)
return kIOReturnSuccess ;
IOReturn err = IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(),
kLocalConfigDirectory_Unpublish, 1, 0, mKernUnitDirRef) ;
mPublished = (!err) ;
return err ;
}
IOReturn
LocalUnitDirectory::SAddEntry_Ptr(
DirRef self,
int key,
void* inBuffer,
size_t inLen,
CFStringRef inDesc)
{
return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->AddEntry(key, inBuffer, inLen, inDesc);
}
IOReturn
LocalUnitDirectory::SAddEntry_UInt32(
DirRef self,
int key,
UInt32 value,
CFStringRef inDesc)
{
return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->AddEntry(key, value, inDesc);
}
IOReturn
LocalUnitDirectory::SAddEntry_FWAddress(
DirRef self,
int key,
const FWAddress* inAddr,
CFStringRef inDesc)
{
return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->AddEntry(key, *inAddr, inDesc);
}
IOReturn
LocalUnitDirectory::SPublish(
DirRef self)
{
return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->Publish();
}
IOReturn
LocalUnitDirectory::SUnpublish(
DirRef self)
{
return IOFireWireIUnknown::InterfaceMap<LocalUnitDirectory>::GetThis(self)->Unpublish();
}
}