Replace Blackbird_controller_runtime.c, blackbird_controller_node_runtime.c, and
blackbird_controller_symbol_service.c with runtime.cpp, node_runtime.cpp, and
symbol_service.cpp respectively. Node-runtime thread management uses std::thread
and the symbol service uses std::string for path handling. Refs #11.
Two regressions landed in the same control path.
First, interface authentication was bound to the transient control client that
issued MarkInterfaceReady. Follow-on handles from the same interface process
were treated as unauthenticated and immediately hit ACCESS_DENIED, which broke
OpenControlDevice and later controller calls even when the interface was the
trusted client.
Second, usermode hook events were published into the ETW transport with the
origin address but with StackCount zeroed, so the controller/UI stack chain
collapsed before symbol enrichment could do any useful work.
Restructure the controller side to keep the auth chain and hook evidence intact:
- persist the authorized interface process/session after MarkInterfaceReady
- allow later control handles from that same trusted interface session to
resume authenticated access
- accept both published and repo-build interface paths when establishing trust
- carry captured hook stack frames into the mapped ETW event instead of
discarding them
- prime and symbol-enrich every captured frame up to the ETW stack limit
This restores the expected control-device handshake while also keeping caller
origin and stack evidence available to downstream analysis surfaces.