DiskArbitrationServerMain.h [plain text]
#ifndef __DISK_ARB_SERVER_MAIN__
#define __DISK_ARB_SERVER_MAIN__
#include <mach/mach.h>
#include <sys/types.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Authorization.h>
#include <IOKit/IOKitLib.h>
#include "DiskArbitrationTypes.h"
#define PID_FILE "/var/run/autodiskmount.pid"
void LogErrorMessage(const char *format, ...);
extern int gDebug;
#define dwarning(a) { if (gDebug) { printf a; fflush(stdout); } }
#if 1
#define pwarning(a) { LogErrorMessage a; }
#else
#define pwarning(a) { printf a; fflush(stdout); }
#endif
#define DISKSTATE(x) (x)==kDiskStateIdle ? "Idle" : \
(x)==kDiskStateNew ? "New" : \
(x)==kDiskStateNewlyUnmounted ? "NewlyUnmounted" : \
(x)==kDiskStateNewlyEjected ? "NewlyEjected" : \
(x)==kDiskStateToBeUnmounted ? "ToBeUnmounted" : \
(x)==kDiskStateToBeEjected ? "ToBeEjected" : \
(x)==kDiskStateToBeUnmountedAndEjected ? "ToBeUnmountedAndEjected" : \
"<UNKNOWN>"
#define STR(x) (x) ? (x) : "(null)"
void SetBlueBoxBootVolume( int seqno );
int GetBlueBoxBootVolume( void );
enum ClientState {
kClientStateIdle = 0,
kClientStateNew,
};
typedef enum ClientState ClientState;
enum
{
kDiskArbIAmBlueBox = 1 << 31,
kDiskArbClientHandlesUninitializedDisks = 1 << 30,
};
struct Client {
struct Client * next;
mach_port_t port;
pid_t pid;
unsigned flags;
ClientState state;
unsigned numAcksRequired;
int notifyOnDiskTypes;
int unrecognizedPriority;
void * ackOnUnrecognizedDisk;
AuthorizationRef clientAuthRef;
};
typedef struct Client Client;
typedef struct Client * ClientPtr;
ClientPtr NewClient( mach_port_t port, unsigned pid, unsigned flags );
void PrintClient(ClientPtr clientPtr);
void PrintClients(void);
ClientPtr LookupClientByPID( pid_t pid );
ClientPtr LookupClientByMachPort( mach_port_t port );
unsigned NumClientsDesiringAsyncNotification( void );
enum AckState {
kSendMsg,
kWaitingForAck,
kAckReceived,
};
typedef enum AckState AckState;
struct AckValue {
pid_t pid;
AckState state;
int errorCode;
};
typedef struct AckValue AckValue;
struct AckValues {
int physicalLength;
int logicalLength;
AckValue * ackValues; };
typedef struct AckValues AckValues;
extern int currentConsoleUser;
AckValues * NewAckValues( int size );
void FreeAckValues( AckValues * p );
void InitAckValue( AckValues * p, pid_t pid );
void UpdateAckValue( AckValues * p, pid_t pid, int errorCode );
int NumUnsetAckValues( AckValues * p );
int NumUnsetAckValuesForAllDisks( void );
void PrintAckValues( AckValues * p );
AckValue * GetDissenterFromAckValues( AckValues * ackValuesPtr );
AckValue * GetDissenterFromAckValuesForAllDisks( void );
AckValue * GetUnresponderFromAckValues( AckValues * ackValuesPtr );
AckValue * GetUnresponderFromAckValuesForAllDisks( void );
void MakeDeadClientAgreeable( ClientPtr clientPtr );
void StartDiskRegistrationCompleteThread(ClientPtr client);
enum DiskState {
kDiskStateIdle = 0,
kDiskStateNew,
kDiskStateNewlyUnmounted,
kDiskStateNewlyEjected,
kDiskStateToBeUnmounted,
kDiskStateToBeEjected,
kDiskStateToBeUnmountedAndEjected,
kDiskStateUnrecognized,
kDiskStatePostponed,
};
typedef enum DiskState DiskState;
enum DiskFamily {
kDiskFamily_Null = 0,
kDiskFamily_SCSI,
kDiskFamily_IDE,
kDiskFamily_Floppy,
kDiskFamily_File,
kDiskFamily_AFP,
};
typedef enum DiskFamily DiskFamily;
struct Disk {
struct Disk * next;
char * ioBSDName;
int ioBSDUnit;
char * ioContent;
char * ioMediaNameOrNull;
char * ioDeviceTreePath;
char * mountpoint;
char * mountedFilesystemName;
DiskFamily family;
unsigned flags;
int sequenceNumber; DiskState state;
AckValues * ackValues; int mountedUser;
io_object_t service;
int retainingClient; ClientPtr lastClientAttemptedForUnrecognizedMessages;
unsigned int wholeDiskContainsMountedChild:1; unsigned int wholeDiskHasBeenYanked:1; unsigned int mountAttempted:1; unsigned int admCreatedMountPoint:1;
unsigned int ejectOnLogout:1;
};
typedef struct Disk Disk;
typedef struct Disk * DiskPtr;
DiskState AreWeBusy( void );
DiskState AreWeBusyForDisk( DiskPtr diskPtr );
DiskPtr NewDisk( char * ioBSDName,
int ioBSDUnit,
char * ioContentOrNull,
DiskFamily family,
char * mountpoint,
char * ioMediaNameOrNull,
char * ioDeviceTreePathOrNull,
io_object_t service,
int mountingUIDFromDevice,
unsigned flags );
void FreeDisk( DiskPtr diskPtr );
void PrintDisks(void);
void DiskSetMountpoint( DiskPtr diskPtr, const char * mountpoint );
DiskPtr LookupDiskByIOBSDName( char * ioBSDName );
int UnmountDisk( DiskPtr diskPtr, int forceUnmount );
int UnmountAllPartitions( DiskPtr diskPtr, int forceUnmount );
int EjectDisk( DiskPtr diskPtr );
void SetStateForOnePartition( DiskPtr diskPtr, DiskState newState );
void SetStateForAllPartitions( DiskPtr diskPtr, DiskState newState );
int NumPartitionsMountedFromThisDisk( DiskPtr diskPtr );
int NumPartitionsToBeUnmountedAndEjectedFromThisDisk( DiskPtr diskPtr );
DiskPtr LookupWholeDiskForThisPartition( DiskPtr diskPtr );
typedef void (*LookupWholeDisksForThisPartitionApplierFunction)( DiskPtr diskPtr );
void LookupWholeDisksForThisPartition( io_registry_entry_t service, LookupWholeDisksForThisPartitionApplierFunction applier );
DiskPtr LookupWholeDiskToBeEjected( void );
boolean_t IsWhole( DiskPtr diskPtr );
boolean_t IsNetwork( DiskPtr diskPtr );
void PrepareToSendPreUnmountMsgs( void );
void PrepareToSendPreEjectMsgs( void );
void SendUnrecognizedDiskMsgs(mach_port_t port, char *devname, char *fstype, char *deviceType, int isWritable, int isRemovable, int isWhole );
void SendUnrecognizedDiskArbitrationMsgs(mach_port_t port, char *devname, char *fstype, char *deviceType, int isWritable, int isRemovable, int isWhole, int diskType );
void SendDiskChangedMsgs(char *devname, char *newMountpoint, char *newVolumeName, int flags, int success);
void SendDiskWillBeCheckedMessages( DiskPtr disk );
void SendCallFailedMessage(ClientPtr clientPtr, DiskPtr diskPtr, int failedType, int error);
int SendDiskAppearedMsgs( void );
void SendUnmountCommitMsgs( void );
void SendPreUnmountMsgs( void );
void SendPreEjectMsgs( void );
void SendUnmountPostNotifyMsgsForOnePartition( char * ioBSDName, int errorCode, pid_t pid );
void SendEjectPostNotifyMsgsForOnePartition( char * ioBSDName, int errorCode, pid_t pid );
void SendEjectPostNotifyMsgsForAllPartitions( DiskPtr diskPtr, int errorCode, pid_t pid );
void SendBlueBoxBootVolumeUpdatedMsgs( void );
void SendCompletedMsgs( int messageType, int newDisks );
void SendClientWasDisconnectedMsg(ClientPtr Client);
void CompleteEject( void );
void CompleteUnmount( void );
char *mountPath( void );
void cleanUpAfterFork(void);
int requestingClientHasPermissionToModifyDisk(pid_t pid, DiskPtr diskPtr, char *right);
kern_return_t DiskArbUnmountAndEjectRequest_async_rpc (
mach_port_t server, pid_t pid,
DiskArbDiskIdentifier diskIdentifier,
unsigned flags);
int DiskTypeForDisk(DiskPtr diskPtr);
ClientPtr GetNextClientForDisk(DiskPtr diskPtr);
int DiskArbitrationServerMain(int argc, char* argv[]);
kern_return_t EnableDeathNotifications(mach_port_t port);
typedef struct {
boolean_t verbose;
boolean_t debug;
DiskPtr Disks;
unsigned NumDisks;
int NumDisksAddedOrDeleted; ClientPtr Clients;
unsigned NumClients;
} GlobalStruct;
extern GlobalStruct g;
#define INTERNAL_MSG 10 // some random number I picked :)
extern CFStringRef yankedHeader;
extern CFStringRef yankedMessage;
extern CFStringRef unrecognizedHeader;
extern CFStringRef unrecognizedHeaderNoInitialize;
extern CFStringRef unrecognizedMessage;
extern CFStringRef ejectString;
extern CFStringRef ignoreString;
extern CFStringRef initString;
extern CFStringRef launchString;
extern CFStringRef someDisk;
extern CFStringRef mountOrFsckFailed;
extern CFStringRef unknownString;
extern CFStringRef mountOrFsckFailedWithDiskUtility;
#define YANKED_MESSAGE CFSTR("")
#define UNINITED_MESSAGE CFSTR("")
#define UNINITED_HEADER CFSTR("You have inserted a disk containing no volumes that Mac OS X can read. To use the unreadable volumes, click Initialize. To continue with the disk inserted, click Continue.")
#define UNINITED_HEADER_NO_INIT CFSTR("You have inserted a disk containing no volumes that Mac OS X can read. To continue with the disk inserted, click Continue.")
#define YANKED_HEADER CFSTR("The storage device that you just removed was not properly put away before being removed from this computer. Data on writable volumes on the device may have been damaged or lost. In the future, please put away the device (Choose its icon and Eject it or Drag it to trash) before removing the device.")
#define EJECT_BUTTON CFSTR("Eject")
#define IGNORE_BUTTON CFSTR("Continue")
#define INIT_BUTTON CFSTR("Initialize...")
#define LAUNCH_BUTTON CFSTR("Launch Disk Utility...")
#define A_DISK CFSTR("A disk attempting to mount as ")
#define MOUNT_FAILED_WITH_DU CFSTR(" has failed verification or has failed to mount. Please use Disk Utility to check the disk and correct any errors.")
#define MOUNT_FAILED CFSTR(" has failed verification or has failed to mount.")
#define UNKNOWN_STRING CFSTR("Unknown")
#endif