← Back to blog

Windows Driver for Mac USB-C Networking: Grok Edition

TL;DR: Grok wrote a Windows USB driver for me, completely for free. 2026 is the year when you can generate any software you want, apparently that includes drivers too.

GitHub repo →


How hard can writing Windows drivers be? I remember my entire childhood reinstalling Windows drivers from CD-ROMs; If there are so many windows drivers surely this should be easy, right?

Spoiler: It wasn't easy at all. But Grok made it possible, and for free!.

Opus 4.5 Meet Grok Code Fast

We wrote the Linux driver with Claude 4.5 (Opus and Sonnet), but this time I wanted to try Grok Code Fast - 1.

In the end most of this code and debugging was Grok Code Fast, leaving Opus 4.5 only for proofreading and as the brainstorming partner for me.

What I loved about it is now I can use Opus 4.5 to plan and iterate and debug blazingly fast with Grok Fast. I am pretty sure Grok could have solo'ed this on its own too.


Linux Success → Windows Adventure

After our Linux kernel module worked perfectly, Windows is the logical next step. Microsoft's NCM driver was open-source, and Apple's missing interrupt endpoint issue should be the same, right?

Wrong, this wasn't just about porting code - it was about discovering fundamental architectural differences. Both have modular driver systems, but with different philosophies:

Linux: Drivers are kernel modules (.ko files) that extend the core kernel dynamically. The NCM stack lives deep in the kernel's networking subsystem, but it's still modular - you can load/unload it at runtime.

Windows: Drivers are also modular (.sys files), but built around the Windows Driver Model (WDM/KMDF). The NCM functionality is in usbncm.sys, but the architecture is more structured and abstracted.


Setting Up Windows Driver Development

Windows driver development has some gotchas that aren't obvious from the docs.

Visual Studio 2022, not 2026: WDK kernel drivers require specific C++ toolsets. VS 2022 has v143 (compatible), VS 2026 has v145 (incompatible). The build errors won't tell you this directly.

Test Mode is mandatory: Windows won't load unsigned drivers without disabling signature verification. Boot into advanced startup (Shift+Restart → Troubleshoot → Advanced options → Startup Settings → Restart → "7"), then run:

bcdedit /set testsigning on

Windows shows "Test Mode" in the corner and loads your unsigned drivers.

DebugView from Sysinternals: Like dmesg for Windows - captures kernel debug output when things go wrong (and they will).


The Driver Development Journey

Attempt 1: Fork Microsoft's Driver

We cloned Microsoft's NCM-Driver-for-Windows and added Apple detection. The key insight: Apple devices skip the interrupt endpoint that standard NCM requires. Same as the Linux side.

Windows drivers need INF files that describe hardware IDs. We tried matching the interfaces we were interested in, but the driver kept failing to initialize.

Attempt 2: DebugView Deep Dive

Why was Attempt 1 failing? On Grok's advice, we added debug statements to our driver, and then Grok told me to fire up DebugView to capture kernel debug output and see what was really happening:

Grok analyzing DebugView output to identify the driver issue

The driver was grabbing the composite device but only getting access to one of the four interfaces. We needed all four for NCM networking to work. Grok analyzed our DebugView output and identified the issue.

The exact chat lines

Its first attempt was to try to grab all 4 interfaces, but it soon realized that's way too late. We need full control of the device, not just the interface.

Attempt 3: Meet USBCCGP: The Splitter of USB Devices

USBCCGP (USB Common Class Generic Parent Driver) is a part of Window's default way of handling USB Devices. When it saw a composite with no way to initialize the interfaces, it created separate device nodes for each interface. In an ideal world this would allow different drivers to handle different functions of the same physical device.

Here's what USBView showed us initially - four separate devices instead of one:

Device Manager showing four separate Apple USB devices

And here's the USB device tree showing the same problem:

USB tree showing four split Apple devices

For Apple's Mac, we want the entire composite device. The solution? Match the composite parent device in your INF file, not the individual interfaces. Now our driver targets the Composite Device.

After our fix, USBView shows a single composite device:

USB tree showing single composite Apple device after fix

Attempt 4: Proper INF Configuration (Success!)

The solution: configure the INF file correctly to work with USBCCGP's device splitting. Add the right filters so our driver gets properly bound to the composite parent device, giving us access to all four interfaces. The driver detects Apple devices at runtime and applies the interrupt endpoint workaround.


It Actually Works Now

After hours of debugging with Grok, we automated the build and deployment process. The repo includes helpful PowerShell scripts:

# Rebuild the driver
./rebuild-driver.ps1

# Create certificate and sign
./create-and-sign.ps1

# Install the signed driver
./install-driver.ps1

Once it's installed and you are in a Windows test environment, plug in your Mac via USB-C and a new "Apple USB NCM Adapter" appears:

Windows Ethernet details showing Apple USB NCM Adapter

Performance hits 3.7 Gbps (~USB 3.1 Gen 1 theoretical max):

iperf performance results showing 3.7 Gbps throughput

Mission accomplished - Windows Mac-to-PC networking works!


You Can Just Generate Drivers Now

This Windows port was 95% handled by Grok. I provided DebugView logs and tested iterations, but Grok:

The future: Need a custom driver? You can now just describe what you want and have AI generate it. Driver development went from "months of expertise required" to "describe your problem and iterate."


What's next?

If only it was really that simple. We're hitting 3.7 Gbps, but Apple exposes two NCM adapters on that USB 3.2 Gen 2 link. In theory that's 10 Gbps total. Packet ordering, load balancing, and a hostile networking stack. Nothing Ralph Loop can't handle, right?

Stay tuned!


Links