Recent

Author Topic: DiskArbitration implementation  (Read 4300 times)

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
DiskArbitration implementation
« on: May 12, 2018, 10:23:39 am »
Hi All,

I have seen that quite a few functions of DiskArbitration and IOKit have been implemented.
Using both I have succeeded in pulling up all kinds of disk information.

Now I'd like to use functions DADiskUnmount, DADiskMount, DADiskEject, DARegisterDiskAppearedCallback, DARegisterDiskDisappearedCallback etc.
Some of the DiskArbitration functions (like DADiskCreateFromBSDName, DADiskGetBSDName, etc) have already been implemented (DADisk.pas and DASession.pas in fpc/pacakages/univint), but some of the functions I'd like to use have not been "implemented" yet.

Since I'm very unfamiliar with bringing in functions like this, and/or how to create a wrapper for DiskArbitration.h, I was wondering if anyone would be willing to help with this.
I have been looking online, and been experimenting with creating my own, but without any luck.

Example:

Code: C  [Select][+][-]
  1. extern void DADiskEject( DADiskRef                      disk,
  2.                          DADiskEjectOptions             options,
  3.                          DADiskEjectCallback __nullable callback,
  4.                          void * __nullable              context );
  5.  
  6.  
  7. /*!
  8.  * @typedef    DADiskEjectApprovalCallback
  9.  * @abstract   Type of the callback function used by DARegisterDiskEjectApprovalCallback().
  10.  * @param      disk    A disk object.
  11.  * @param      context The user-defined context parameter given to the registration function.
  12.  * @result     A dissenter reference.  Pass NULL to approve.
  13.  * @discussion
  14.  * The caller of this callback receives a reference to the returned object.  The
  15.  * caller also implicitly retains the object and is responsible for releasing it
  16.  * with CFRelease().
  17.  */

On of my attempts was:


Code: Pascal  [Select][+][-]
  1. procedure DADiskEject(disk:DADiskRef; options:UInt32; callback:UnivPtr; context:UnivPtrPtr); external name '_DADiskEject';


For those experienced with creating wrappers, you'll probably see that things aren't perfect, caused by my inexperience with this.
Any help would be appreciated, even if it's just pointers in the right direction.

For example;
- are there any tools out there to convert Objective-C to pascal? (with or without the need to manual correct a few things)
- is there any documentation available how this should be done the right way?

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
Re: DiskArbitration implementation
« Reply #1 on: May 12, 2018, 10:40:41 am »
p.s. the link in the ObjCParser Wiki page to the parser points to a dead page;


SNV https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/bindings/pascocoa/parser/


Not sure where it is supposed to point to, just thought I'd mention it here.
Should it point to this GitHub page?
https://github.com/genericptr/Framework-Parser

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
Re: DiskArbitration implementation
« Reply #2 on: May 12, 2018, 10:47:18 am »
For those interested, I've attached the .h files;


DADisk.h
DADissenter.h
DASession.h
DiskArbitration.h

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
Re: DiskArbitration implementation
« Reply #3 on: May 13, 2018, 10:44:19 am »

Here an example of what I'm trying to get to work in Lazarus:
Code: C  [Select][+][-]
  1. /* @typedef    DADiskEjectCallback
  2.  * @abstract   Type of the callback function used by DADiskEject().
  3.  * @param      disk      The disk object.
  4.  * @param      dissenter A dissenter object on failure or NULL on success.
  5.  * @param      context   The user-defined context parameter given to the eject function.
  6.  */
  7. typedef void ( *DADiskEjectCallback )( DADiskRef disk, DADissenterRef __nullable dissenter, void * __nullable context );
  8. /* @function   DADiskEject
  9.  * @abstract   Ejects the specified disk object.
  10.  * @param      disk     The disk object.
  11.  * @param      options  The eject options.
  12.  * @param      callback The callback function to call once the ejection completes.
  13.  * @param      context  The user-defined context parameter to pass to the callback function.
  14.  */
  15. extern void DADiskEject( DADiskRef                      disk,
  16.                          DADiskEjectOptions             options,
  17.                          DADiskEjectCallback __nullable callback,
  18.                          void * __nullable              context );


Most other items I can "translate" myself (by looking at code from DADisk.pas, DASession.pas). But constructs like these are a little over my head. Any help would be greatly appreciated ...

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
Re: DiskArbitration implementation
« Reply #4 on: May 22, 2018, 05:52:39 pm »

So I have most functions working, even those that need a callback - just the callback never happens.
In the example below, unmount does work, a share or device does get unmounted (unless the system has the mount locked for some good reason).
I'm sure I did a few things wrong as I may not know what I'm doing (I did look at other units done by others):


Code: Pascal  [Select][+][-]
  1. const
  2.   { DADiskUnmountOptions }
  3.   kDADiskUnmountOptionDefault = $00000000;
  4.   kDADiskUnmountOptionForce   = $00080000;
  5.   kDADiskUnmountOptionWhole   = $00000001;
  6.  
  7. ...
  8.  
  9.  
  10. {
  11.   @typedef    DADissenterRef
  12.   Type of a reference to DADissenter instances.
  13. }
  14. DADissenterRef = ^SInt32; { an opaque type }
  15.  
  16. ...
  17.  
  18.  
  19. {
  20.  typedef    DADiskUnmountCallback
  21.  abstract   Type of the callback function used by DADiskUnmount().
  22.  param      disk      The disk object.
  23.  param      dissenter A dissenter object on failure or NULL on success.
  24.  param      context   The user-defined context parameter given to the unmount function.
  25. }
  26. // Was:
  27. // typedef void ( *DADiskUnmountCallback )( DADiskRef disk, DADissenterRef __nullable dissenter, void * __nullable context );
  28.   DADiskUnmountCallback = procedure( disk: DADiskRef; dissenter: DADissenterRef; context: univptr); cdecl;  
  29.  
  30.  
  31. ...
  32.  
  33.  
  34. {
  35.  function   DADiskUnmount
  36.  abstract   Unmounts the volume at the specified disk object.
  37.  param      disk     The disk object.
  38.  param      options  The unmount options.
  39.  param      callback The callback function to call once the unmount completes.
  40.  param      context  The user-defined context parameter to pass to the callback function.
  41. }
  42. procedure DADiskUnmount( disk: DADiskRef;
  43.                          options: DADiskUnmountOptions;
  44.                          callback: DADiskUnmountCallback;
  45.                          context: UnivPtr); external name '_DADiskUnmount';


Elsewhere I'd call it this way:


Code: Pascal  [Select][+][-]
  1. procedure ejectCallback(disk:DADiskRef; dissenter:DADissenterRef; context:UnivPtr); cdecl;
  2. begin
  3.   ShowMessage('Eject Callback:' + DADiskGetBSDName(disk));
  4. end;
  5.  
  6.  
  7. ...
  8.  
  9.  
  10. // TODO: UnMount works, Eject works both individually, callback does not.
  11. DADiskUnmount(disk,kDADiskUnmountOptionForce+kDADiskUnmountOptionWhole,@ejectCallback,nil);


I'm sure that I am not using it right - just some of the concepts are new to me.
Any input and/or help would really be appreciated.

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
Re: DiskArbitration implementation
« Reply #5 on: May 22, 2018, 07:43:39 pm »

Probably not 100% correct, but I did get the callback to work with the code above by calling 'DADiskUnmount' after calling 'DASessionScheduleWithRunLoop'.


Code: Pascal  [Select][+][-]
  1.   DASessionScheduleWithRunLoop(daSession,CFRunLoopGetCurrent, kCFRunLoopDefaultMode);
  2.   CFRunLoopRun;
  3.   DADiskUnmount(disk,kDADiskUnmountOptionForce+kDADiskUnmountOptionWhole,@unmountCallback,nil);
  4.  
 

 

TinyPortal © 2005-2018