Recent

Author Topic: fpc OS X types / functions  (Read 10677 times)

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
Re: fpc OS X types / functions
« Reply #15 on: March 17, 2018, 01:02:23 pm »
Yeah I did dig through the Apple docs, but I'm definitely struggling with that as well.
Or maybe I should say that doing a 1:1 in Lazarus has proven to be challenging for me  :D


I'm trying to list all drives and read/write straight to drives (kind-a like "dd") without using command line options. I've gone the command line route before and noticed that the output of certain statements change per different macOS release (for example the output of diskutil) - so not the most reliable way. So I consider going the "official" route but at times it's a little over my head.

josip

  • New Member
  • *
  • Posts: 19
Re: fpc OS X types / functions
« Reply #16 on: April 23, 2018, 02:43:53 pm »
Would you be able to post some example code on how to use these functions?
It would be very much appreciated  :)

I use it for connected USB device detection by VID / PID. It is working fine till then, but I forgot coding details.
Code: [Select]
{$linkframework IOKit}

//IOKit = '/System/Library/Frameworks/IOKit.framework/IOKit';

type

  io_name_t = array[0..128] of Char;
  io_object_t = mach_port_t;
  io_iterator_t = io_object_t;
  io_service_t = io_object_t;
  io_registry_entry_t = io_object_t;
  IOOptionBits = UInt32;

const

  kIOSerialBSDServiceValue = 'IOSerialBSDClient';
  kIOSerialBSDTypeKey    = 'IOSerialBSDClientType';
  kIOSerialBSDModemType    = 'IOModemSerialStream';
  kIOUSBDeviceClassName    = 'IOUSBDevice';
  kUSBVendorID             = 'idVendor';
  kUSBProductID            = 'idProduct';
  kIOTTYDeviceKey    = 'IOTTYDevice';
  kIOCalloutDeviceKey    = 'IOCalloutDevice';
  kIOServicePlane    = 'IOService';
  kUSBInterfaceNumber      = 'bInterfaceNumber';

function IOServiceMatching(name: PChar): CFMutableDictionaryRef; cdecl; external;

function IOServiceGetMatchingServices(masterPort: mach_port_t; matching: CFDictionaryRef;
  var existing: io_iterator_t): kern_return_t; cdecl; external;

function IOIteratorNext(name: io_iterator_t): io_object_t; cdecl; external;

function IORegistryEntryCreateCFProperty(entry: io_registry_entry_t; key: CFStringRef;
  allocator: CFAllocatorRef; options: IOOptionBits): CFTypeRef; cdecl; external;

function IORegistryEntryGetName(entry: io_registry_entry_t; var name: io_name_t): kern_return_t; cdecl; external;

function IORegistryEntryGetParentEntry(entry: io_registry_entry_t; plane: io_name_t;
  var parent: io_registry_entry_t): kern_return_t; cdecl; external;

function IORegistryEntrySearchCFProperty(entry: io_registry_entry_t; plane: io_name_t;
  key: CFStringRef; allocator: CFAllocatorRef; options: IOOptionBits): CFTypeRef; cdecl; external;

function IOObjectRelease(object_: io_object_t): kern_return_t; cdecl; external;


function RegName(FEntry: io_registry_entry_t): string;
var
  FName: io_name_t;
begin
  FillChar(FName, SizeOf(FName), 0);
  IORegistryEntryGetName(FEntry, FName);
  RegName := StrPas(PChar(@FName));
end;


function RegStr(FEntry: io_registry_entry_t; FKey: PChar): string;
var
  FBuf: array[0..255] of Char;
  FCFStr: CFTypeRef;
  FStr: string;
begin
  FCFStr := IORegistryEntryCreateCFProperty(FEntry, CFSTR(FKey), kCFAllocatorDefault, 0);
  FillChar(FBuf, SizeOf(FBuf), 0);
  CFStringGetPascalString(FCFStr, @FBuf[0], 256, CFStringGetSystemEncoding);
  FStr := StrPas(PChar(@FBuf));
  FStr := RightStr(FStr, Length(FStr) - 1);
  RegStr := FStr;
end;


function RegNum(FEntry: io_registry_entry_t; FKey: PChar; var FRes: Int): Boolean;
var
  FCFNumber: CFTypeRef;
  FNum: SInt32;
begin
  RegNum := False;
  FCFNumber := IORegistryEntrySearchCFProperty(FEntry, kIOServicePlane, CFSTR(FKey), kCFAllocatorDefault, 0);
  if FCFNumber <> nil then
  begin
    CFNumberGetValue(FCFNumber, kCFNumberSInt32Type, @FNum);
    FRes := FNum;
    RegNum := True;
  end;
end;


function CdcPort: Boolean;
var
  FMatchDic: CFMutableDictionaryRef;
  FIterator: io_iterator_t;
  FDevice, FDeviceOld: io_registry_entry_t;
  FGetParentRes: kern_return_t;
  FVid, FPid, FIntNum: Int;
  FPortName, FPortPath: string;
begin
  CdcPort := False;

  FMatchDic := IOServiceMatching(kIOSerialBSDServiceValue);
  CFDictionarySetValue(FMatchDic, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDModemType));

  //if IOServiceGetMatchingServices(kIOMasterPortDefault, FMatchDic, FIterator) = kIOReturnSuccess then
  if IOServiceGetMatchingServices(0, FMatchDic, FIterator) = kIOReturnSuccess then
    while True do
    begin
      FDevice := IOIteratorNext(FIterator);
      if FDevice = 0 then break;

      FPortName := RegStr(FDevice, kIOTTYDeviceKey);
      if LeftStr(FPortName, 8) = 'usbmodem' then
      begin
        FPortPath := RegStr(FDevice, kIOCalloutDeviceKey);
        //WriteLn(FPortName + ':' + FPortPath);
        //WriteLn(RegName(FDevice));
        FVid := -1;
        FGetParentRes := kIOReturnSuccess;
        while (FVid < 0) and (FGetParentRes = kIOReturnSuccess) do
        begin
          //WriteLn(RegName(FDevice));
          FDeviceOld := FDevice;
          FGetParentRes := IORegistryEntryGetParentEntry(FDevice, kIOServicePlane, FDevice);
          if IOObjectRelease(FDeviceOld) = kIOReturnSuccess then ; //WriteLn('*')
          if FGetParentRes = kIOReturnSuccess then
          begin
            RegNum(FDevice, kUSBVendorID, FVid);
            RegNum(FDevice, kUSBProductID, FPid);
    RegNum(FDevice, kUSBInterfaceNumber, FIntNum);
          end;
        end;
        //WriteLn(IntToHex(FVid, 4) + ' ' + IntToHex(FPid, 4) + ' ' + IntToHex(FIntNum, 4));
        if (FVid = $XXXX) and ((FPid = $YYYY) or (FPid = $ZZZZ)) and (FIntNum = 1) then
        begin
          GPortLen := GPortLen + 1;
          GPortName[GPortLen] := FPortName;
          GPortPath[GPortLen] := FPortPath;
          if AnsiCompareText(GPortName[0], GPortName[GPortLen]) = 0 then CdcPort := True;
        end;
      end;
  end;
end;

Hansaplast

  • Hero Member
  • *****
  • Posts: 674
  • Tweaking4All.com
    • Tweaking4All
Re: fpc OS X types / functions
« Reply #17 on: April 23, 2018, 04:22:08 pm »
Awesome! Thanks Josip!  :)

 

TinyPortal © 2005-2018