#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <servers/bootstrap.h>
#include <mach/mach.h>
#include <unistd.h>
#include <Security/Authorization.h>
#include <DiskArbitration.h>
#include <CoreFoundation/CoreFoundation.h>
#include "ClientToServer.h"
#include "ServerToClient_server.h"
#ifndef DEBUG
#define DEBUG 0
#endif
#if DEBUG
#define dwarning(args) printf args
#else
#define dwarning(args)
#endif
static mach_port_t gDiskArbSndPort = MACH_PORT_NULL;
static mach_port_t gDiskArbRcvPort = MACH_PORT_NULL;
CFMutableDictionaryRef gDiskArbitration_CallbackHandlers = NULL;
int gDiskArbitration_ClientFlags = kDiskArbNotifyNone;
CFArrayRef DiskArbCallbackHandlersForCallback(int callbackType)
{
CFNumberRef numberForType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &callbackType);
CFArrayRef array = nil;
if (!gDiskArbitration_CallbackHandlers) {
CFRelease(numberForType);
return array;
}
if (CFDictionaryContainsKey(gDiskArbitration_CallbackHandlers, numberForType)) {
array = CFDictionaryGetValue(gDiskArbitration_CallbackHandlers, numberForType);
}
CFRelease(numberForType);
return array;
}
boolean_t updateClientFlags(void)
{
int flags = kDiskArbNotifyNone;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED_WITHOUT_MT) != NULL )
flags |= kDiskArbNotifyDiskAppearedWithoutMountpoint;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED_WITH_MT) != NULL )
flags |= kDiskArbNotifyDiskAppearedWithMountpoint;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED1) != NULL )
flags |= kDiskArbNotifyDiskAppeared;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED) != NULL )
flags |= kDiskArbNotifyDiskAppeared2;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT) != NULL )
flags |= kDiskArbNotifyUnmount;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT_PRE_NOTIFY) != NULL || DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT_POST_NOTIFY) != NULL || DiskArbCallbackHandlersForCallback(kDA_DISK_EJECT_PRE_NOTIFY) != NULL || DiskArbCallbackHandlersForCallback(kDA_DISK_EJECT_POST_NOTIFY) != NULL ) {
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT_PRE_NOTIFY) != NULL && DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT_POST_NOTIFY) != NULL && DiskArbCallbackHandlersForCallback(kDA_DISK_EJECT_PRE_NOTIFY) != NULL && DiskArbCallbackHandlersForCallback(kDA_DISK_EJECT_POST_NOTIFY) != NULL ) {
flags |= kDiskArbNotifyAsync;
} else {
return FALSE;
}
}
if ( DiskArbCallbackHandlersForCallback(kDA_BLUE_BOX_UPDATED) != NULL )
flags |= kDiskArbNotifyBlueBoxBootVolumeUpdated;
if ( DiskArbCallbackHandlersForCallback(kDA_NOTIFICATIONS_COMPLETE) != NULL )
flags |= kDiskArbNotifyCompleted;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_CHANGED) != NULL )
flags |= kDiskArbNotifyChangedDisks;
if ( DiskArbCallbackHandlersForCallback(kDA_DISK_WILL_BE_CHECKED) != NULL )
flags |= kDiskArbNotifyDiskWillBeChecked;
if ( DiskArbCallbackHandlersForCallback(kDA_CALL_FAILED) != NULL )
flags |= kDiskArbNotifyCallFailed;
if ( DiskArbCallbackHandlersForCallback(kDA_CLIENT_WILL_HANDLE_UNRECOGNIZED_DISK) != NULL )
flags |= kDiskArbArbitrateUnrecognizedVolumes;
if ( DiskArbCallbackHandlersForCallback(kDA_UNKNOWN_DISK_APPEARED) != NULL )
flags |= kDiskArbNotifyUnrecognizedVolumes;
if (flags != gDiskArbitration_ClientFlags) {
gDiskArbitration_ClientFlags = flags;
return TRUE;
}
return FALSE;
}
void DiskArbAddCallbackHandler(int callbackType, void * callback, int overwrite)
{
CFNumberRef numberForType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &callbackType);
if (!gDiskArbitration_CallbackHandlers) {
gDiskArbitration_CallbackHandlers = CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
}
if (!callback) {
CFRelease(numberForType);
return;
}
if (CFDictionaryContainsKey(gDiskArbitration_CallbackHandlers, numberForType)) {
if (overwrite) {
CFMutableArrayRef callbackArray = CFArrayCreateMutable(NULL, 0, NULL);
CFArrayAppendValue(callbackArray, callback);
CFDictionaryReplaceValue(gDiskArbitration_CallbackHandlers, numberForType, callbackArray);
} else {
CFMutableArrayRef callbackArray = CFDictionaryGetValue(gDiskArbitration_CallbackHandlers, numberForType);
DiskArbRemoveCallbackHandler(callbackType, callback);
CFArrayAppendValue(callbackArray, callback);
}
} else {
CFMutableArrayRef callbackArray = CFArrayCreateMutable(NULL, 0, NULL);
CFArrayAppendValue(callbackArray, callback);
CFDictionaryAddValue(gDiskArbitration_CallbackHandlers, numberForType, callbackArray);
}
if (updateClientFlags()) {
}
CFRelease(numberForType);
return;
}
void DiskArbRemoveCallbackHandler(int callbackType, void * callback)
{
CFNumberRef numberForType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &callbackType);
if (!gDiskArbitration_CallbackHandlers) {
CFRelease(numberForType);
return;
}
if (CFDictionaryContainsKey(gDiskArbitration_CallbackHandlers, numberForType)) {
CFMutableArrayRef callbackArray = CFDictionaryGetValue(gDiskArbitration_CallbackHandlers, numberForType);
CFIndex index = CFArrayGetFirstIndexOfValue(callbackArray, CFRangeMake(0, CFArrayGetCount(callbackArray)), callback);
while (index >= 0) {
CFArrayRemoveValueAtIndex(callbackArray, index);
index = CFArrayGetFirstIndexOfValue(callbackArray, CFRangeMake(0, CFArrayGetCount(callbackArray)), callback);
}
}
CFRelease(numberForType);
return;
}
void DiskArbRegisterCallback_DiskAppearedWithMountpoint( DiskArbCallback_DiskAppearedWithMountpoint_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_APPEARED_WITH_MT, callback, 0); }
void DiskArbRegisterCallback_DiskAppearedWithoutMountpoint( DiskArbCallback_DiskAppearedWithoutMountpoint_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_APPEARED_WITHOUT_MT, callback, 0); }
void DiskArbRegisterCallback_DiskAppeared( DiskArbCallback_DiskAppeared_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_APPEARED1, callback, 0); }
void DiskArbRegisterCallback_DiskAppeared2( DiskArbCallback_DiskAppeared2_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_APPEARED, callback, 0); }
void DiskArbRegisterCallback_UnmountNotification( DiskArbCallback_UnmountNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_UNMOUNT, callback, 0); }
void DiskArbRegisterCallback_UnmountPreNotification( DiskArbCallback_UnmountPreNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_UNMOUNT_PRE_NOTIFY, callback, 1); }
void DiskArbRegisterCallback_UnmountPostNotification( DiskArbCallback_UnmountPostNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_UNMOUNT_POST_NOTIFY, callback, 0); }
void DiskArbRegisterCallback_EjectPreNotification( DiskArbCallback_EjectPreNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_EJECT_PRE_NOTIFY, callback, 1); }
void DiskArbRegisterCallback_EjectPostNotification( DiskArbCallback_EjectPostNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_EJECT_POST_NOTIFY, callback, 0); }
void DiskArbRegisterCallback_ClientDisconnectedNotification( DiskArbCallback_ClientDisconnectedNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_CLIENT_DISCONNECTED, callback, 0); }
void DiskArbRegisterCallback_BlueBoxBootVolumeUpdated( DiskArbCallback_BlueBoxBootVolumeUpdated_t callback )
{ DiskArbAddCallbackHandler(kDA_BLUE_BOX_UPDATED, callback, 0); }
void DiskArbRegisterCallback_DiskChangedNotification( DiskArbCallback_DiskChangedNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_CHANGED, callback, 0); }
void DiskArbRegisterCallback_DiskWillBeCheckedNotification( DiskArbCallback_DiskWillBeCheckedNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_DISK_WILL_BE_CHECKED, callback, 0); }
void DiskArbRegisterCallback_CallFailedNotification( DiskArbCallback_CallFailedNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_CALL_FAILED, callback, 0); }
void DiskArbRegisterCallback_NotificationComplete( DiskArbCallback_NotificationComplete_t callback )
{ DiskArbAddCallbackHandler(kDA_NOTIFICATIONS_COMPLETE, callback, 0); }
void DiskArbRegisterCallback_Printer_FinalRequest( DiskArbCallback_Printer_FinalRequest_t callback )
{ DiskArbAddCallbackHandler(kDA_PRINTER_FINAL_REQUEST, callback, 0); }
void DiskArbRegisterCallback_Printer_FinalResponse( DiskArbCallback_Printer_FinalResponse_t callback )
{ DiskArbAddCallbackHandler(kDA_PRINTER_FINAL_RESPONSE, callback, 0); }
void DiskArbRegisterCallback_Printer_FinalRelease( DiskArbCallback_Printer_FinalRelease_t callback )
{ DiskArbAddCallbackHandler(kDA_PRINTER_FINAL_RELEASE, callback, 0); }
void DiskArbRegisterCallback_Will_Client_Release( DiskArbCallback_Will_Client_Release_t callback )
{ DiskArbAddCallbackHandler(kDA_WILL_CLIENT_RELEASE_DEVICE, callback, 0); }
void DiskArbRegisterCallback_Device_Reservation_Status( DiskArbCallback_Device_Reservation_Status_t callback )
{ DiskArbAddCallbackHandler(kDA_DEVICE_RESERVATION_STATUS, callback, 0); }
void DiskArbRegisterCallback_UnknownFileSystemNotification( DiskArbCallback_UnknownFileSystemNotification_t callback )
{ DiskArbAddCallbackHandler(kDA_UNKNOWN_DISK_APPEARED, callback, 0); }
boolean_t DiskArbHandleMsg(
mach_msg_header_t *InHeadP,
mach_msg_header_t *OutHeadP)
{
return ServerToClient_server( InHeadP, OutHeadP );
}
kern_return_t DiskArbRegister(
mach_port_t server,
mach_port_t client,
unsigned flags)
{
gDiskArbRcvPort = client;
return DiskArbRegister_rpc( server, client, flags );
}
kern_return_t DiskArbDeregister(
mach_port_t server,
mach_port_t client)
{
return DiskArbDeregister_rpc( server, client );
}
kern_return_t DiskArbDiskAppearedWithMountpointPing(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags,
DiskArbMountpoint mountpoint)
{
return DiskArbDiskAppearedWithMountpointPing_rpc( server, diskIdentifier, flags, mountpoint );
}
kern_return_t DiskArbDiskDisappearedPing(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
return DiskArbDiskDisappearedPing_rpc( server, diskIdentifier, flags );
}
kern_return_t DiskArbRequestMount(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier)
{
return DiskArbRequestMount_rpc( server, diskIdentifier, FALSE );
}
kern_return_t DiskArbRequestMountAndOwn(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier)
{
return DiskArbRequestMount_rpc( server, diskIdentifier, TRUE );
}
kern_return_t DiskArbRefresh(
mach_port_t server)
{
return DiskArbRefresh_rpc( server );
}
kern_return_t DiskArbRegisterWithPID(
mach_port_t server,
mach_port_t client,
unsigned flags)
{
gDiskArbRcvPort = client;
return DiskArbRegisterWithPID_rpc( server, client, getpid(), flags );
}
kern_return_t DiskArbDiskAppearedWithoutMountpoint_rpc (
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED_WITHOUT_MT);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_DiskAppearedWithoutMountpoint_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, flags );
}
}
Return:
return err;
}
kern_return_t DiskArbDiskAppearedWithMountpoint_rpc (
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags,
DiskArbMountpoint mountpoint)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED_WITH_MT);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_DiskAppearedWithMountpoint_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, flags, mountpoint );
}
}
Return:
return err;
}
kern_return_t DiskArbDiskAppeared_rpc (
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags,
DiskArbMountpoint mountpoint,
DiskArbIOContent ioContent)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED1);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_DiskAppeared_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, flags, mountpoint, ioContent );
}
}
Return:
return err;
}
kern_return_t DiskArbDiskAppeared2_rpc (
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags,
DiskArbMountpoint mountpoint,
DiskArbIOContent ioContent,
DiskArbDeviceTreePath deviceTreePath,
unsigned sequenceNumber)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_APPEARED);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_DiskAppeared2_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, flags, mountpoint, ioContent, deviceTreePath, sequenceNumber );
}
}
Return:
return err;
}
kern_return_t DiskArbUnmountNotification_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
int pastOrFuture,
int willEject)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_UnmountNotification_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, pastOrFuture, willEject );
}
}
Return:
return err;
}
kern_return_t DiskArbUnmountPreNotify_async_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT_PRE_NOTIFY);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_UnmountPreNotification_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, flags );
}
}
Return:
return err;
}
kern_return_t DiskArbUnmountPostNotify_async_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
int errorCode,
int dissenter)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_UNMOUNT_POST_NOTIFY);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_UnmountPostNotification_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, errorCode, dissenter );
}
}
Return:
return err;
}
kern_return_t DiskArbEjectPreNotify_async_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_EJECT_PRE_NOTIFY);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_EjectPreNotification_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, flags );
}
}
Return:
return err;
}
kern_return_t DiskArbEjectPostNotify_async_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
int errorCode,
int dissenter)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_EJECT_POST_NOTIFY);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_EjectPostNotification_t) CFArrayGetValueAtIndex(callbacks,i) )( diskIdentifier, errorCode, dissenter );
}
}
Return:
return err;
}
kern_return_t DiskArbClientDisconnected_rpc(
mach_port_t server)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_CLIENT_DISCONNECTED);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_ClientDisconnectedNotification_t) CFArrayGetValueAtIndex(callbacks,i) )();
}
}
Return:
return err;
}
kern_return_t DiskArbBlueBoxBootVolumeUpdated_async_rpc(
mach_port_t server,
int seqno)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_BLUE_BOX_UPDATED);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_BlueBoxBootVolumeUpdated_t) CFArrayGetValueAtIndex(callbacks,i) )( seqno );
}
}
Return:
return err;
}
kern_return_t DiskArbDiskChanged_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
DiskArbMountpoint newMountPoint,
DiskArbMountpoint newVolumeName,
unsigned flags,
int success)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_CHANGED);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_DiskChangedNotification_t) CFArrayGetValueAtIndex(callbacks,i) )(diskIdentifier, newMountPoint, newVolumeName, flags, success);
}
}
Return:
return err;
}
kern_return_t DiskArbDiskWillBeChecked_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags,
DiskArbIOContent content)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DISK_WILL_BE_CHECKED);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_DiskWillBeCheckedNotification_t) CFArrayGetValueAtIndex(callbacks,i) )(diskIdentifier, flags, content);
}
}
Return:
return err;
}
kern_return_t DiskArbPreviousCallFailed_rpc(
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
int failedCallType,
int error)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_CALL_FAILED);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_CallFailedNotification_t) CFArrayGetValueAtIndex(callbacks,i) )(diskIdentifier, failedCallType, error);
}
}
Return:
return err;
}
kern_return_t DiskArbNotificationComplete_rpc(
mach_port_t server,
int messageType)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_NOTIFICATIONS_COMPLETE);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_NotificationComplete_t) CFArrayGetValueAtIndex(callbacks,i) )(messageType);
}
}
Return:
return err;
}
kern_return_t DiskArbRegistrationComplete_rpc(
mach_port_t server)
{
kern_return_t err = 0;
#warning NOT CURRENTLY DOING A THING!!!!
dwarning(("%s\n", __FUNCTION__));
return err;
}
kern_return_t DiskArbPrinter_FinalRequest_rpc (
mach_port_t server,
int pid,
int locationID)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_PRINTER_FINAL_REQUEST);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_Printer_FinalRequest_t) CFArrayGetValueAtIndex(callbacks,i) )(pid, locationID);
}
}
Return:
return err;
}
kern_return_t DiskArbPrinter_FinalResponse_rpc (
mach_port_t server,
int locationID,
int answer)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_PRINTER_FINAL_RESPONSE);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_Printer_FinalResponse_t) CFArrayGetValueAtIndex(callbacks,i) )(locationID, answer);
}
}
Return:
return err;
}
kern_return_t DiskArbPrinter_FinalRelease_rpc (
mach_port_t server,
int locationID)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_PRINTER_FINAL_RELEASE);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_Printer_FinalRelease_t) CFArrayGetValueAtIndex(callbacks,i) )(locationID);
}
}
Return:
return err;
}
kern_return_t DiskArbWillClientRelinquish_rpc (
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
int releaseToClientPid)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_WILL_CLIENT_RELEASE_DEVICE);
if ( NULL == callbacks)
{
DiskArbClientRelinquishesReservation ( diskIdentifier, releaseToClientPid, 0); goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_Will_Client_Release_t) CFArrayGetValueAtIndex(callbacks,i) )(diskIdentifier, releaseToClientPid);
}
}
Return:
return err;
}
kern_return_t DiskArbDeviceReservationStatus_rpc (
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
int status,
int pid)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_DEVICE_RESERVATION_STATUS);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_Device_Reservation_Status_t) CFArrayGetValueAtIndex(callbacks,i) )(diskIdentifier, status, pid);
}
}
Return:
return err;
}
kern_return_t DiskArbWillClientHandleUnrecognizedDisk_rpc (
mach_port_t server,
DiskArbDiskIdentifier diskIdentifier,
int diskType,
char * fsType,
char * deviceType,
int isWritable,
int isRemovable,
int isWhole)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_CLIENT_WILL_HANDLE_UNRECOGNIZED_DISK);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_Will_Client_Handle_Unrecognized_Disk_t) CFArrayGetValueAtIndex(callbacks,i) )(diskIdentifier, diskType, fsType, deviceType, isWritable, isRemovable, isWhole);
}
}
Return:
return err;
}
kern_return_t DiskArbUnknownFileSystemInserted_rpc(
mach_port_t server,
char * diskIdentifier,
char * fsType,
char * deviceType,
int isWritable,
int isRemovable,
int isWhole)
{
kern_return_t err = 0;
CFArrayRef callbacks = DiskArbCallbackHandlersForCallback(kDA_UNKNOWN_DISK_APPEARED);
if ( NULL == callbacks)
{
goto Return;
} else {
int i;
for (i=0; i < CFArrayGetCount(callbacks);i++) {
( (DiskArbCallback_UnknownFileSystemNotification_t) CFArrayGetValueAtIndex(callbacks,i) )(diskIdentifier, fsType, deviceType, isWritable, isRemovable, isWhole);
}
}
Return:
return err;
}
kern_return_t DiskArbStart(mach_port_t * portPtr)
{
kern_return_t result;
static mach_port_t pre_registered_port = 0x0;
result = bootstrap_look_up( bootstrap_port, DISKARB_SERVER_NAME, & gDiskArbSndPort );
if ( result )
{
dwarning(("%s(): {%s:%d} bootstrap_look_up() failed: $%x\n", __FUNCTION__, __FILE__, __LINE__, (int)result));
goto Return;
}
dwarning(("%s(): gDiskArbSndPort = %d\n", __FUNCTION__, (int)gDiskArbSndPort));
if (!pre_registered_port) {
result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, portPtr);
if ( result != KERN_SUCCESS)
{
dwarning(("%s(): (%s:%d) mach_port_allocate failed: $%x: %s\n", __FUNCTION__, __FILE__, __LINE__, result, mach_error_string(result)));
goto Return;
}
} else {
* portPtr = pre_registered_port;
}
dwarning(("%s(): port = $%x\n", __FUNCTION__, (int)*portPtr));
updateClientFlags();
dwarning(("%s(): flags = %08x\n", __FUNCTION__, gDiskArbitration_ClientFlags));
if (!pre_registered_port) {
result = DiskArbRegisterWithPID_auto( *portPtr, gDiskArbitration_ClientFlags);
DiskArbMsgLoopWithTimeout(5000);
if ( result )
{
dwarning(("%s(): {%s:%d} DiskArbRegister(sendPort=$%08x, *portPtr=$%08x, flags=$%08x) failed: $%x\n", __FUNCTION__, __FILE__, __LINE__, gDiskArbSndPort, *portPtr, gDiskArbitration_ClientFlags, (int)result));
goto Return;
}
}
pre_registered_port = *portPtr;
Return:
return result;
}
kern_return_t DiskArbInit(void)
{
kern_return_t result;
if ( gDiskArbSndPort != MACH_PORT_NULL )
{
result = 0;
goto Return;
}
result = bootstrap_look_up( bootstrap_port, DISKARB_SERVER_NAME, & gDiskArbSndPort );
if ( result )
{
dwarning(("%s(): {%s:%d} bootstrap_look_up() failed: $%x\n", __FUNCTION__, __FILE__, __LINE__, (int)result));
goto Return;
}
dwarning(("%s(): gDiskArbSndPort = %d\n", __FUNCTION__, (int)gDiskArbSndPort));
Return:
return result;
}
kern_return_t DiskArbRegister_auto(
mach_port_t client,
unsigned flags)
{
gDiskArbRcvPort = client;
return DiskArbRegister_rpc( gDiskArbSndPort, client, flags );
}
kern_return_t DiskArbDeregister_auto(
mach_port_t client)
{
return DiskArbDeregister_rpc( gDiskArbSndPort, client );
}
kern_return_t DiskArbDiskAppearedWithMountpointPing_auto(
DiskArbDiskIdentifier diskIdentifier,
unsigned flags,
DiskArbMountpoint mountpoint)
{
SetSecure();
return DiskArbDiskAppearedWithMountpointPing_rpc( gDiskArbSndPort, diskIdentifier, flags, mountpoint );
}
kern_return_t DiskArbDiskDisappearedPing_auto(
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
SetSecure();
return DiskArbDiskDisappearedPing_rpc( gDiskArbSndPort, diskIdentifier, flags );
}
kern_return_t DiskArbRequestMount_auto(
DiskArbDiskIdentifier diskIdentifier)
{
SetSecure();
return DiskArbRequestMount_rpc( gDiskArbSndPort, diskIdentifier, FALSE );
}
kern_return_t DiskArbRequestMountAndOwn_auto(
DiskArbDiskIdentifier diskIdentifier)
{
SetSecure();
return DiskArbRequestMount_rpc( gDiskArbSndPort, diskIdentifier, TRUE );
}
kern_return_t DiskArbRefresh_auto()
{
return DiskArbRefresh_rpc( gDiskArbSndPort );
}
kern_return_t DiskArbRegisterWithPID_auto(
mach_port_t client,
unsigned flags)
{
gDiskArbRcvPort = client;
return DiskArbRegisterWithPID_rpc( gDiskArbSndPort, client, getpid(), flags );
}
kern_return_t DiskArbUpdateClientWithPID_auto(
unsigned flags)
{
return DiskArbUpdateClientWithPID_rpc( gDiskArbSndPort, getpid(), flags );
}
kern_return_t DiskArbDeregisterWithPID_auto(
mach_port_t client)
{
gDiskArbRcvPort = client;
return DiskArbDeregisterWithPID_rpc( gDiskArbSndPort, client, getpid());
}
kern_return_t DiskArbMarkPIDNew_auto(
mach_port_t client,
unsigned flags)
{
gDiskArbRcvPort = client;
SetSecure();
return DiskArbMarkPIDNew_rpc( gDiskArbSndPort, client, getpid(), flags);
}
kern_return_t DiskArbRequestDiskChange_auto(
DiskArbDiskIdentifier diskIdentifier,
DiskArbGenericString mountPoint,
int flags)
{
SetSecure();
return DiskArbRequestDiskChange_rpc( gDiskArbSndPort, getpid(), diskIdentifier, mountPoint, flags);
}
kern_return_t DiskArbSetCurrentUser_auto( int user)
{
SetSecure();
return DiskArbSetCurrentUser_rpc(gDiskArbSndPort, getpid(), user);
}
kern_return_t DiskArbVSDBAdoptVolume_auto(DiskArbDiskIdentifier diskIdentifier)
{
SetSecure();
return DiskArbVSDBAdoptVolume_rpc(gDiskArbSndPort, getpid(), diskIdentifier);
}
kern_return_t DiskArbVSDBDisownVolume_auto(DiskArbDiskIdentifier diskIdentifier)
{
SetSecure();
return DiskArbVSDBDisownVolume_rpc(gDiskArbSndPort, getpid(), diskIdentifier);
}
int DiskArbVSDBGetVolumeStatus_auto(DiskArbDiskIdentifier diskIdentifier)
{
int status;
SetSecure();
DiskArbVSDBGetVolumeStatus_rpc(gDiskArbSndPort, diskIdentifier, &status);
return status;
}
kern_return_t DiskArbSetVolumeEncoding_auto(DiskArbDiskIdentifier diskIdentifier, int volumeEncoding)
{
SetSecure();
return DiskArbSetVolumeEncoding_rpc(gDiskArbSndPort, getpid(), diskIdentifier, volumeEncoding);
}
int DiskArbGetVolumeEncoding_auto(DiskArbDiskIdentifier diskIdentifier)
{
int status;
SetSecure();
DiskArbGetVolumeEncoding_rpc(gDiskArbSndPort, diskIdentifier, &status);
return status;
}
kern_return_t DiskArbClientHandlesUninitializedDisks_auto(
int flag)
{
SetSecure();
return DiskArbClientHandlesUninitializedDisks_rpc( gDiskArbSndPort, getpid(), flag );
}
kern_return_t DiskArbUnmountRequest_async_auto(
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
SetSecure();
return DiskArbUnmountRequest_async_rpc( gDiskArbSndPort, getpid(), diskIdentifier, flags );
}
kern_return_t DiskArbUnmountPreNotifyAck_async_auto(
DiskArbDiskIdentifier diskIdentifier,
int errorCode)
{
SetSecure();
return DiskArbUnmountPreNotifyAck_async_rpc( gDiskArbSndPort, getpid(), diskIdentifier, errorCode );
}
kern_return_t DiskArbEjectRequest_async_auto(
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
SetSecure();
return DiskArbEjectRequest_async_rpc( gDiskArbSndPort, getpid(), diskIdentifier, flags );
}
kern_return_t DiskArbEjectPreNotifyAck_async_auto(
DiskArbDiskIdentifier diskIdentifier,
int errorCode)
{
SetSecure();
return DiskArbEjectPreNotifyAck_async_rpc( gDiskArbSndPort, getpid(), diskIdentifier, errorCode );
}
kern_return_t DiskArbUnmountAndEjectRequest_async_auto(
DiskArbDiskIdentifier diskIdentifier,
unsigned flags)
{
SetSecure();
return DiskArbUnmountAndEjectRequest_async_rpc( gDiskArbSndPort, getpid(), diskIdentifier, flags );
}
kern_return_t DiskArbSetBlueBoxBootVolume_async_auto(
int pid,
int seqno)
{
SetSecure();
return DiskArbSetBlueBoxBootVolume_async_rpc( gDiskArbSndPort, pid, seqno );
}
kern_return_t DiskArbMsgLoop( void )
{
return DiskArbMsgLoopWithTimeout ( MACH_MSG_TIMEOUT_NONE );
}
void DiskArbNoOp( void)
{
return;
}
kern_return_t DiskArbMsgLoopWithTimeout( mach_msg_timeout_t millisecondTimeout )
{
kern_return_t err = 0;
unsigned msgReceiveBufLength;
mach_msg_header_t * msgReceiveBufPtr = NULL;
unsigned msgSendBufLength;
mach_msg_header_t * msgSendBufPtr = NULL;
mach_msg_return_t receiveResult;
msgSendBufLength = sizeof( mach_msg_empty_send_t ) + 20;
msgSendBufPtr = (mach_msg_header_t * )malloc( msgSendBufLength );
if ( msgSendBufPtr == NULL )
{
dwarning(( "FAILURE: msgSendBufPtr = malloc(%d)\n", msgSendBufLength ));
err = -1;
goto Return;
}
else
{
dwarning(( "SUCCESS: msgSendBufPtr = malloc(%d)\n", msgSendBufLength ));
}
msgReceiveBufLength = sizeof( mach_msg_empty_rcv_t );
msgReceiveBufPtr = NULL;
while ( 1 )
{
if ( msgReceiveBufPtr == NULL )
{
msgReceiveBufPtr = (mach_msg_header_t * )malloc( msgReceiveBufLength );
if ( msgReceiveBufPtr == NULL )
{
dwarning(( "FAILURE: msgReceiveBufPtr = malloc(%d)\n", msgReceiveBufLength ));
err = -2;
goto Return;
}
else
{
dwarning(( "SUCCESS: msgReceiveBufPtr = malloc(%d)\n", msgReceiveBufLength ));
}
}
dwarning(("gDiskArbRcvPort = $%x", gDiskArbRcvPort));
dwarning(("%s: Waiting for a message (millisecondTimeount = %d)...\n", __FUNCTION__, millisecondTimeout));
receiveResult = mach_msg( msgReceiveBufPtr,
MACH_RCV_MSG | MACH_RCV_LARGE | (MACH_MSG_TIMEOUT_NONE == millisecondTimeout ? 0 : MACH_RCV_TIMEOUT),
0,
msgReceiveBufLength,
gDiskArbRcvPort,
millisecondTimeout,
MACH_PORT_NULL);
if ( receiveResult == MACH_RCV_TOO_LARGE )
{
dwarning(( "%s(): mach_msg: $%08x: %s\n", __FUNCTION__, receiveResult, mach_error_string(receiveResult) ));
dwarning(( "msgReceiveBufPtr->msgh_size = %d\n", msgReceiveBufPtr->msgh_size ));
msgReceiveBufLength = msgReceiveBufPtr->msgh_size + sizeof(mach_msg_trailer_t);
free( msgReceiveBufPtr );
msgReceiveBufPtr = NULL;
continue;
}
else
if ( receiveResult != MACH_MSG_SUCCESS )
{
dwarning(( "%s(): mach_msg: $%08x: %s\n", __FUNCTION__, receiveResult, mach_error_string(receiveResult) ));
err = receiveResult;
goto Return;
}
if ( msgReceiveBufPtr->msgh_local_port == gDiskArbRcvPort )
{
bzero( msgSendBufPtr, sizeof( mach_msg_header_t ) );
dwarning(("%s: DiskArbHandleMsg...\n", __FUNCTION__));
(void) DiskArbHandleMsg( msgReceiveBufPtr, msgSendBufPtr );
dwarning(("%s: mach_msg_send...\n", __FUNCTION__));
(void) mach_msg_send( msgSendBufPtr );
goto Return;
}
else
{
dwarning(("FAILURE: unrecognized msgh_local_port = $%x\n", (int)msgReceiveBufPtr->msgh_local_port));
err = -3;
goto Return;
}
}
Return:
if ( msgReceiveBufPtr ) free ( msgReceiveBufPtr );
if ( msgSendBufPtr ) free ( msgSendBufPtr );
return err;
}
kern_return_t DiskArbPrinter_Request_auto (
int locationID)
{
SetSecure();
return DiskArbPrinter_Request_rpc( gDiskArbSndPort, getpid(), locationID );
}
kern_return_t DiskArbPrinter_Response_auto (
int pid,
int locationID,
int answer)
{
SetSecure();
return DiskArbPrinter_Response_rpc( gDiskArbSndPort, pid, locationID, answer );
}
kern_return_t DiskArbPrinter_Release_auto (
int locationID)
{
SetSecure();
return DiskArbPrinter_Release_rpc( gDiskArbSndPort, locationID );
}
kern_return_t DiskArbIsDeviceReservedForClient( DiskArbDiskIdentifier diskIdentifier)
{
SetSecure();
return DiskArbIsDeviceReservedForClient_rpc(gDiskArbSndPort, diskIdentifier, getpid());
}
kern_return_t DiskArbRetainClientReservationForDevice ( DiskArbDiskIdentifier diskIdentifier)
{
SetSecure();
return DiskArbRetainClientReservationForDevice_rpc(gDiskArbSndPort, diskIdentifier, getpid());
}
kern_return_t DiskArbReleaseClientReservationForDevice ( DiskArbDiskIdentifier diskIdentifier)
{
SetSecure();
return DiskArbReleaseClientReservationForDevice_rpc(gDiskArbSndPort, diskIdentifier, getpid());
}
kern_return_t DiskArbClientRelinquishesReservation ( DiskArbDiskIdentifier diskIdentifier, int releaseToClientPid, int status)
{
SetSecure();
return DiskArbClientRelinquishesReservation_rpc(gDiskArbSndPort, diskIdentifier, getpid(), releaseToClientPid, status);
}
kern_return_t DiskArbClientHandlesUnrecognizedDisks ( int diskTypes, int priority)
{
SetSecure();
return DiskArbClientHandlesUnrecognizedDisks_rpc(gDiskArbSndPort, getpid(), diskTypes, priority);
}
kern_return_t DiskArbClientWillHandleUnrecognizedDisk ( DiskArbDiskIdentifier diskIdentifier, int yesNo)
{
SetSecure();
return DiskArbClientWillHandleUnrecognizedDisk_rpc(gDiskArbSndPort, diskIdentifier, getpid(), yesNo );
}
void DiskArbUpdateClientFlags()
{
DiskArbUpdateClientWithPID_auto(gDiskArbitration_ClientFlags);
return;
}
int DiskArbIsActive()
{
if (gDiskArbSndPort != NULL && gDiskArbRcvPort != NULL) {
return 1;
}
return 0;
}
void SetSecure(void)
{
static int securityTokenPassed = 0;
if (!securityTokenPassed) {
AuthorizationRef ref;
int error;
int flags = kAuthorizationFlagPreAuthorize | kAuthorizationFlagPartialRights | kAuthorizationFlagExtendRights;
error = AuthorizationCreate(NULL, NULL, flags, &ref);
if (!error) {
AuthorizationExternalForm externalForm;
error = AuthorizationMakeExternalForm(ref, &externalForm);
if (!error) {
DiskArbSetSecuritySettingsForClient_rpc(gDiskArbSndPort, getpid(), externalForm.bytes);
}
}
securityTokenPassed++;
}
return;
}
kern_return_t DiskArb_EjectKeyPressed()
{
return DiskArbEjectKeyPressed_rpc(gDiskArbSndPort);
}