From 7143f4a4e1bc39be785a4482e622a206457450c4 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Mon, 7 Oct 2024 12:34:12 +0200 Subject: [PATCH] windows: manually initialize NewNTUnicodeString MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `RtlInitUnicodeString` syscall can be avoided by manually initializing the `NTUnicodeString`. The process is described in [WdmlibRtlInitUnicodeStringEx](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdmsec/nf-wdmsec-wdmlibrtlinitunicodestringex). The less syscalls, the better. It also makes the function faster: ``` goos: windows goarch: amd64 pkg: golang.org/x/sys/windows cpu: Intel(R) Core(TM) i7-10850H CPU @ 2.70GHz │ old.txt │ new.txt │ │ sec/op │ sec/op vs base │ NewNTUnicodeString-12 181.05n ± 15% 96.32n ± 11% -46.80% (p=0.000 n=10) ``` Change-Id: Iaf079acdcc2024cdca6b6b649a711f6be99c5b87 Reviewed-on: https://go-review.googlesource.com/c/sys/+/618175 Reviewed-by: Damien Neil Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI --- windows/syscall_windows.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 5cee9a314..63471b0e4 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -1685,13 +1685,16 @@ func (s NTStatus) Error() string { // do not use NTUnicodeString, and instead UTF16PtrFromString should be used for // the more common *uint16 string type. func NewNTUnicodeString(s string) (*NTUnicodeString, error) { - var u NTUnicodeString - s16, err := UTF16PtrFromString(s) + s16, err := UTF16FromString(s) if err != nil { return nil, err } - RtlInitUnicodeString(&u, s16) - return &u, nil + n := uint16(len(s16) * 2) + return &NTUnicodeString{ + Length: n - 2, // subtract 2 bytes for the NULL terminator + MaximumLength: n, + Buffer: &s16[0], + }, nil } // Slice returns a uint16 slice that aliases the data in the NTUnicodeString.