Skip to main content

Posts

Showing posts from 2019

How to emulate special Apple keys (Media navigation, power, etc)

Media keys along with some other keys are not handled through the standard apple keyboard event subsystem. They are treated differently, and therefore emulating them from software requires special code (EventTap won't work!).

Here's a function that does this:
void HIDPostAuxKey(uint32_t key, bool down) { @autoreleasepool { NSEvent* ev = [NSEvent otherEventWithType:NSEventTypeSystemDefined location:NSZeroPoint modifierFlags:(down ? 0xa00 : 0xb00) timestamp:0 windowNumber:0 context:nil subtype:8 data1:(key << 16)| ((down ? 0xa : 0xb) << 8) data2:-1 ]; CGEventPost(kCGHIDEventTap, [ev CGEvent]); } } This Objective-C code is adapted from an SO post that shows…

Converting a std::vector into an NSArray

An excellent piece of code to do the above is here:

//clang++ -std=c++11 -stdlib=libc++ -framework Foundation nsarray.mm -o nsarray /* Note: * - libstdc++ has been frozen by Apple at a pre-C++11 version, so you must opt for the newer, BSD-licensed libc++ * - Apple clang 4.0 (based on LLVM 3.1svn) does not default to C++11 yet, so you must explicitly specify this language standard. */ /* @file nsarray.mm * @author Jeremy W. Sherman * * Demonstrates three different approaches to converting a std::vector * into an NSArray. */ #import #include #include #include int main(void) { @autoreleasepool { /* initializer list */ std::vector strings = {"a", "b", "c"}; /* uniform initialization */ //std::vector strings{"a", "b", "c"}; /* Exploiting Clang's block->lambda bridging. */ id nsstrings = [NSMutableArray new]; std::for_each(strings.begin(), strings.end(), ^(std::string str) { id nsstr = [NSStri…

Set/get volume in OS X

How to get/set master volume in OS X. Many sample codes online use the deprecated API. This uses the currently 'legal' API.

#include <CoreAudio/CoreAudio.h> #include <AudioToolbox/AudioToolbox.h> #include <AudioToolbox/AudioServices.h> #include <AppKit/AppKit.h> #include <CoreGraphics/CGEvent.h> static AudioDeviceID getDefaultOutputDeviceID() { AudioDeviceID outputDeviceID = kAudioObjectUnknown; // get output device device OSStatus status = noErr; AudioObjectPropertyAddress propertyAOPA; propertyAOPA.mScope = kAudioObjectPropertyScopeGlobal; propertyAOPA.mElement = kAudioObjectPropertyElementMaster; propertyAOPA.mSelector = kAudioHardwarePropertyDefaultOutputDevice; if (!AudioObjectHasProperty( kAudioObjectSystemObject, &propertyAOPA)) { printf("Cannot find default output device!"); return outputDeviceID; } status = AudioObjectGetPropertyD…

WiX Tips

Some tips on using WiX to generate MSI installers:


The GUID used as Product Id has to be unique for each release of the package. That is version 1.0 & 1.1 should have different product ids. So it's best to use auto-generated GUIDs for this like this:
<product Id="*"... />In other words do not hard code the product id.
MSI only recognizes three quadrant product version numbers.Product upgrades essentially work by uninstalling the current version and then installing the new version.From MSI v3.5 onward upgrades are supported through the <MajorUpgrade.. />tag.MSI does not define special actions for uninstallation. In fact, uninstallation is also treated as a type of installation. So if you want to run a custom action during uninstall, you have to use Condition predicates that cause them to run only during uninstallation. For example the following custom action is only run during uninstall as REMOVE="ALL" evaluates to TRUE only when all components are…

Setting up a Windows VM for Kernel Debugging

If you search the web using the title of this post, you'll get many links to articles most of which explain how to set this up using a virtual COM port on the VM. Coming from driver background that goes back over 20 years, at first this seemed quite natural. But then I remembered that using WinDBG over COM port to be painfully slow. And recent adventures in OSX land using LLDB led me to wonder if WinDBG over network would to be possible?

Well it turns out that WinDBG over Ethernet is indeed possible and is documented by Microsoft here. However, they miss out on certain key steps, which won't be obvious for the casual reader unless one reads the entire driver debugging documentation from the beginning.

This post captures all the requisite steps as a quick reference guide. I used one of the freely available MSEdge on Windows 10 VM for  VirtualBox. It's only valid for 90 days, but 90 days was more than enough for my little excursion into the driver land. If you want a more p…

Javascript Promises

While explaining Promises to a friend I remembered reading a blog post couple of years back that explained the concept very well and made it all clear to me. However, I never bookmarked and searching for it, I can't find the specific post. Then I thought why not recreate some of the samples that the blog author had used to explain the concepts.

Here's what I came up with:

// Function to convert setTimeout into a Promise based // abstraction function delaySeconds(seconds) { return new Promise((resolve, reject) => { setTimeout(resolve, seconds*1000); }); } /* * A simple function that converts clunky setTimeout * callback based interface to a promise based * abstraction. */ function delayAndReturn(seconds, retval) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(retval); }, seconds*1000); }); } // example of how to use the above abstraction console.log("Calling delaySeconds with 10 seconds delay"…

Setting up OS X for kernel debugging

Here are the steps to prepare an OS X system for debugging kernel modules such as drivers. The instructions are deliberately brief to save the reader from tons of text.
If you search the web, you will come across may resources that point to using GDB to debug the kernel. These resources were written in the early days of OS X when versions 10.4 or 10.5 were prevalent. Since around v10.9 (or thereabouts), Mac moved to lldb as their debugger of choice and have continually improved it to enable easier setup & more efficient workflow.

This short post has the instructions to setting up lldb for debugging OS X kernel versions 10.11 and above.

My setup is using a Parallels VM as the target on the development system. But it should work on a separate hardware that is connected via network to the host.

Debuggee is the target system where drivers are deployed and tested. This also referred to as the target system. Debugger is the host system, typically running your development tools with the …

How to view kernel logs in OS X

How to view kernel logs is OS X You can use the command line tool log for this.

This command accepts a predicate argument that can be used to , well build predicates, that when evaluates to true, the log message will be printed. It takes a command argument that decides how the logs are to be displayed. For instance

log stream

produces a streaming output of the log. That is new log messages are displayed as they come (asynchronously).

log show

displays messages from the log history.

log --process 0

displays messages from process with ID 0, which is kernel. This can be used to display all kext log messages.

log show --predicate 'processID == 0'

displays messages printed by processID 0, which is the kernel process. This is the same as the previous command.

To display messages from a driver, you may use the sender predicate filter argument. So if your driver is named mytestdriver, you may display messages from it using the command:

log stream --predicate 'sender == "mytestdri…