dxd - dynax driver framework 3.0.2
cross platform open source driver development framework
Loading...
Searching...
No Matches
Customization

A product is a directory beside dxd/ holding its version.h, its device description and compositions (drv.h), one source per driver and its CMakeLists.txt. The framework reads nothing product specific of its own: every value comes through these files.

All platforms

  • CMakeLists.txt - the product's build: it includes dxd.cmake ahead of its project() - the product's root PRODUCT, the macOS architectures and deployment target, the ASIO SDK, each the product's own where it sets it first -, adds ${DXD}/interface and a subtree per binary, which states its target and sources and leaves the rest to dxd: dxd_test, dxd_asio, dxd_service, dxd_installer, dxd_coreaudio, dxd_coremidi, dxd_daemon (interface/CMakeLists.txt, each returning on a platform without its kind), dxd_driver (kernel/wdm); a dext needs no subtree, dxd_driverkit builds it in dxd's tree kernel/driverkit/dext out of the sources it names. A subtree builds as part of the product alone - if(NOT DEFINED CMAKE_PROJECT_NAME) never fires there, CMake puts an implicit project() ahead of a top level file without one:
    if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
    message(FATAL_ERROR "the test application builds as part of the product")
    endif()
    dxd_test(test test.cpp)
  • version.h - the product's identity, included by every binary, the plists, the infs and the installer
    #define DX_VERSION_MAJOR 1 // major version: range 0..99
    #define DX_VERSION_MINOR 0 // minor version: range 0..9
    #define DX_VERSION_SUB 0 // sub version: range 0..9
    #define DX_VERSION_DEPLOYMENT b // 'd'evelopment, 'a'lpha, 'b'eta, release 'c'andidate, 'f'inal
    #define DX_VERSION_BUILD 1 // bumped by the release script
    #define DX_VENDOR My Company // the vendor as displayed
    #define DX_VENDOR_SHORT MyCompany
    #define DX_VENDOR_ID com_mycompany // identifier form
    #define DX_VENDOR_URID com.mycompany // reverse DNS form
    #define DX_TEAM_ID XXXXXXXXXX // the Apple Developer ID team, the binaries' signature check
    #define DX_PROVIDER_APPSTORE_KEY XXXXXXXXXX // the team's App Store Connect API key
    #define DX_PROVIDER_APPSTORE_ISSUER xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // its issuer
    #define DX_FILENAME MyCompanyMyProduct // every binary's name, the targets derive theirs (Service, ASIO, Install, ...)
    #define DX_PRODUCT My Product
    #define DX_PRODUCT_ID DX_CAT(DX_VENDOR_ID,_myproduct)
    #define DX_PRODUCT_URID DX_VENDOR_URID.myproduct // the service, the registry root, the plugin bundle, the daemon
    #define DX_PRODUCT_GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // the device interface class, the installer's upgrade code
    #define DX_CLASS_GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // optional: the devices' setup class, the generic inf installing it - System there, media in the installer otherwise
    #define DX_MACH_SERVICES <string>DX_PRODUCT_URID.daemon</string> // Info.plist: the Mach services the plugin looks up
  • drv.h - the device description (dx::stream::desc, a constexpr table of models: vendor and model with their names and bus ids, endpoints, clocks, streams, pins - the one place the devices are stated: the matching, the daemon's captures (dx::daemon::app{argc, argv, models}) and the infs' hardware ids follow it) and the compositions of the drivers - which layers make the USB device, the proxy device, the service client, the CoreAudio client - plus the product's license (its root CA, its subject) as the base of every device
  • the license: certificates issued by the product's root CA (license/ in the product's tree: the CA, license.sh, the license server), bound to a device serial number or a machine, in the platform's certificate store; the software refuses an unbound one
  • dxd_target_icon(<target> <icon>) (interface/CMakeLists.txt): a target's icon, an SVG or an Icon Composer icon (<name>.icon: icon.json and its layers in Assets/) - on macOS an application's compiled by actool (Xcode 26), every other bundle's the SVG its visible layers compose, rsvg-convert and iconutil rasterizing it; called ahead of dxd_target_sign(). An SVG stating its layers (icon:layer, icon:group and their values in the namespace http://dynax.at/icon, dxd_icon_composer()) is an application's Icon Composer icon as well - one file drawn as the light appearance shows it, any viewer opening it

macOS

  • the Xcode projects reference interface/macOS/dx.xcodeproj; the plugin's Info.plist and the daemon's launchd.plist are generated from the templates under interface/macOS/plist/ with version.h's macros; etc/<product>/postinstall are the package scripts
  • the driver's subtree states dxd_driverkit(<name> ... [MODELS <header> <models>]) for the dext and dxd_iokit(<name> ... [MODELS <header> <models>]) for the kext: MODELS as dxd_driver()'s, the plist made at build time off dxd's templates kernel/driverkit/dxd.plist and kernel/iokit/dxd.plist (INFO_PLIST a product's own) - a personality per model by its bus (PCI IOPCIMatch, a PCI model without vendor id its class code's IOPCIClassMatch, USB idVendor/idProduct, a virtual one the driver shell on IOUserResources making its devices off DeviceProperties), the kext's libraries by the buses; DX_USAGE_DESCRIPTION states what the dext serves

Windows

  • the kernel driver's subtree adds ${DXD}/kernel/wdm and states dxd_driver(<target> <source>.. [INF <inf>] [KMDF <minor>] [MODELS <header> <models>]), whose dxd_driver_package(<target> INF <inf> [FILES ...]) stages, stamps and catalogs the driver package (build\<dir>\package\<config>\<target>) and copies it to bin\<platform>\<config>; KMDF binds a KMDF driver to the framework version 1.<minor> (KMDF_VERSION_MINOR, FxDriverEntry), an inf template (.inx) is preprocessed at build time against version.h and the driver's macros into <product>.inf, as dxd_plist() makes a plist - MODELS names the header and the constexpr array of the product's model desc, whose models the template includes (kernel/dxd_models.cpp: each a line, its hardware id dx::hwid, as the installer's); without INF the template is dxd's generic kernel/wdm/dxd.inx: the class DX_CLASS_GUID where version.h names one, System otherwise, the driver run from the driver store, users reading and writing the devices. The entry is dxd::create<driver_t>(driver, registry, args...) in every form
  • the inf: $ARCH$ and DriverVer stamped by stampinf, the class the devices belong to, the models' hardware ids; a WinUSB inf publishes DeviceInterfaceGUIDs = DX_PRODUCT_GUID for the user mode driver to enumerate
  • installer/version.wxi: what the module and the .msi carry
    <?define vendor="My Company"?>
    <?define product="My Product"?>
    <?define guid="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"?>
    <?define urid="com.mycompany.myproduct"?>
    <?define filename="$(var.SolutionName)"?>
    <?define driver="$(var.filename)"?> <!-- the kernel driver package: <driver>.inf/.cat/.sys -->
    <?define winusb="$(var.filename)WinUSB"?> <!-- a WinUSB package: <winusb>.inf/.cat; both defined: DRIVER=portcls|winusb selects -->
    <?define install="$(var.filename)Install.exe"?> <!-- the install executable the custom actions run -->
    <?define service="$(var.filename)Service.exe"?>
    <?define asio="$(var.filename)ASIO.dll"?>
    <?define license_purpose="My Company License"?> <!-- the license certificates' extended key usage as the viewer names it -->
    optional: asio32 (the 32 bit ASIO driver on x64), cpl/cpl32 (a control panel), misc (further files beside the driver package), icon