windows: add memory-related VirtualX calls and associated constants

Fixes golang/go#20086

Change-Id: Ifdc2561fe6cc125fa45a57bad9750f3f3f055e66
Reviewed-on: https://go-review.googlesource.com/47335
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
diff --git a/windows/memory_windows.go b/windows/memory_windows.go
new file mode 100644
index 0000000..6688497
--- /dev/null
+++ b/windows/memory_windows.go
@@ -0,0 +1,22 @@
+// Copyright 2017 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+const (
+	MEM_COMMIT      = 0x00001000
+	MEM_RESERVE     = 0x00002000
+	MEM_DECOMMIT    = 0x00004000
+	MEM_RELEASE     = 0x00008000
+	MEM_RESET       = 0x00080000
+	MEM_TOP_DOWN    = 0x00100000
+	MEM_WRITE_WATCH = 0x00200000
+	MEM_PHYSICAL    = 0x00400000
+	MEM_RESET_UNDO  = 0x01000000
+	MEM_LARGE_PAGES = 0x20000000
+
+	PAGE_NOACCESS  = 0x01
+	PAGE_READONLY  = 0x02
+	PAGE_READWRITE = 0x04
+)
diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go
index e439c48..518250e 100644
--- a/windows/syscall_windows.go
+++ b/windows/syscall_windows.go
@@ -154,6 +154,9 @@
 //sys	FlushViewOfFile(addr uintptr, length uintptr) (err error)
 //sys	VirtualLock(addr uintptr, length uintptr) (err error)
 //sys	VirtualUnlock(addr uintptr, length uintptr) (err error)
+//sys	VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc
+//sys	VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree
+//sys	VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect
 //sys	TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
 //sys	ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
 //sys	CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go
index b9ee827..d588e1d 100644
--- a/windows/zsyscall_windows.go
+++ b/windows/zsyscall_windows.go
@@ -139,6 +139,9 @@
 	procFlushViewOfFile                    = modkernel32.NewProc("FlushViewOfFile")
 	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
 	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
+	procVirtualAlloc                       = modkernel32.NewProc("VirtualAlloc")
+	procVirtualFree                        = modkernel32.NewProc("VirtualFree")
+	procVirtualProtect                     = modkernel32.NewProc("VirtualProtect")
 	procTransmitFile                       = modmswsock.NewProc("TransmitFile")
 	procReadDirectoryChangesW              = modkernel32.NewProc("ReadDirectoryChangesW")
 	procCertOpenSystemStoreW               = modcrypt32.NewProc("CertOpenSystemStoreW")
@@ -1384,6 +1387,43 @@
 	return
 }
 
+func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) {
+	r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0)
+	value = uintptr(r0)
+	if value == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
 	r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
 	if r1 == 0 {
diff --git a/windows/ztypes_windows.go b/windows/ztypes_windows.go
index a907ff2..1f05b6c 100644
--- a/windows/ztypes_windows.go
+++ b/windows/ztypes_windows.go
@@ -165,8 +165,6 @@
 	PROCESS_QUERY_INFORMATION = 0x00000400
 	SYNCHRONIZE               = 0x00100000
 
-	PAGE_READONLY          = 0x02
-	PAGE_READWRITE         = 0x04
 	PAGE_WRITECOPY         = 0x08
 	PAGE_EXECUTE_READ      = 0x20
 	PAGE_EXECUTE_READWRITE = 0x40