feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.LookupDnsWindows
const LookupDnsWindows = struct
File
Code
const LookupDnsWindows = struct {
threaded: *Threaded,
thread: Thread.Handle,
resolved: *Io.Queue(HostName.LookupResult),
options: HostName.LookupOptions,
results: windows.DNS.QUERY.RESULT,
done: bool,
fn completed(
pQueryContext: ?*anyopaque,
pQueryResults: *windows.DNS.QUERY.RESULT,
) callconv(.winapi) void {
_ = pQueryContext;
const lookup_dns: *LookupDnsWindows = @fieldParentPtr("results", pQueryResults);
lookup_dns.completedFallible() catch |err| switch (err) {
error.Closed => unreachable,
error.Canceled => unreachable,
};
@atomicStore(bool, &lookup_dns.done, true, .release);
_ = windows.ntdll.NtAlertThread(lookup_dns.thread);
}
fn completedFallible(lookup_dns: *LookupDnsWindows) (Io.QueueClosedError || Io.Cancelable)!void {
assert(!lookup_dns.done);
const t = lookup_dns.threaded;
defer t.dl.DnsFree.raw.?(lookup_dns.results.pQueryRecords, .RecordList);
if (lookup_dns.results.QueryStatus != .SUCCESS) return;
const t_io = t.io();
var record_it = lookup_dns.results.pQueryRecords;
while (record_it) |record| : (record_it = record.pNext) switch (record.wType) {
else => {},
.A => try lookup_dns.resolved.putOne(t_io, .{
.address = .{ .ip4 = .{ .bytes = record.Data.A, .port = lookup_dns.options.port } },
}),
.AAAA => {
const ip6: net.Ip6Address = .{
.bytes = record.Data.AAAA,
.port = lookup_dns.options.port,
};
try lookup_dns.resolved.putOne(t_io, .{
.address = if (lookup_dns.options.family) |_| .{ .ip6 = ip6 } else .fromIp6(ip6),
});
},
};
if (lookup_dns.results.pQueryRecords) |record| {
if (lookup_dns.options.canonical_name_buffer) |buf| {
const name_wtf16 = std.mem.span(
@as([*:0]const windows.WCHAR, @ptrCast(@alignCast(record.pName))),
);
const len = std.unicode.wtf16LeToWtf8(buf, name_wtf16);
try lookup_dns.resolved.putOne(t_io, .{
.canonical_name = .{ .bytes = buf[0..len] },
});
}
}
}
}