[release-branch.go1.11] internal/poll, net: fix sendfile on Windows, add test

Fixes #27085

Change-Id: I4eb3ff7c76e0b8e4d8fe0298f739b0284d74a031
Reviewed-on: https://go-review.googlesource.com/130895
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Andrew Bonventre <andybons@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/internal/poll/sendfile_windows.go b/src/internal/poll/sendfile_windows.go
index 1a4d0ca..dc93e85 100644
--- a/src/internal/poll/sendfile_windows.go
+++ b/src/internal/poll/sendfile_windows.go
@@ -32,8 +32,8 @@
 		return 0, err
 	}
 
-	o.o.OffsetHigh = uint32(curpos)
-	o.o.Offset = uint32(curpos >> 32)
+	o.o.Offset = uint32(curpos)
+	o.o.OffsetHigh = uint32(curpos >> 32)
 
 	done, err := wsrv.ExecIO(o, func(o *operation) error {
 		return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
diff --git a/src/net/sendfile_test.go b/src/net/sendfile_test.go
index ecc00d3..3b98277 100644
--- a/src/net/sendfile_test.go
+++ b/src/net/sendfile_test.go
@@ -149,3 +149,64 @@
 		t.Error(err)
 	}
 }
+
+func TestSendfileSeeked(t *testing.T) {
+	ln, err := newLocalListener("tcp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	const seekTo = 65 << 10
+	const sendSize = 10 << 10
+
+	errc := make(chan error, 1)
+	go func(ln Listener) {
+		// Wait for a connection.
+		conn, err := ln.Accept()
+		if err != nil {
+			errc <- err
+			close(errc)
+			return
+		}
+
+		go func() {
+			defer close(errc)
+			defer conn.Close()
+
+			f, err := os.Open(twain)
+			if err != nil {
+				errc <- err
+				return
+			}
+			defer f.Close()
+			if _, err := f.Seek(seekTo, os.SEEK_SET); err != nil {
+				errc <- err
+				return
+			}
+
+			_, err = io.CopyN(conn, f, sendSize)
+			if err != nil {
+				errc <- err
+				return
+			}
+		}()
+	}(ln)
+
+	c, err := Dial("tcp", ln.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	buf := new(bytes.Buffer)
+	buf.ReadFrom(c)
+
+	if buf.Len() != sendSize {
+		t.Errorf("Got %d bytes; want %d", buf.Len(), sendSize)
+	}
+
+	for err := range errc {
+		t.Error(err)
+	}
+}