windows: add Find*ChangeNotification APIs for file and directory monitoring
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstchangenotificationw
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findnextchangenotification
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findclosechangenotification
Change-Id: If7abfd63cd7a60e7f95ffad9aca2b7b7b74c94f0
Reviewed-on: https://go-review.googlesource.com/c/sys/+/285713
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go
index 1c2e80a..fda9c55 100644
--- a/windows/syscall_windows.go
+++ b/windows/syscall_windows.go
@@ -264,6 +264,9 @@
//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 FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.FindFirstChangeNotificationW
+//sys FindNextChangeNotification(handle Handle) (err error)
+//sys FindCloseChangeNotification(handle Handle) (err error)
//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore
//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
diff --git a/windows/types_windows.go b/windows/types_windows.go
index b3bd0da..dc8017d 100644
--- a/windows/types_windows.go
+++ b/windows/types_windows.go
@@ -227,7 +227,7 @@
)
const (
- // filters for ReadDirectoryChangesW
+ // filters for ReadDirectoryChangesW and FindFirstChangeNotificationW
FILE_NOTIFY_CHANGE_FILE_NAME = 0x001
FILE_NOTIFY_CHANGE_DIR_NAME = 0x002
FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x004
diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go
index 8a79ea1..a164e98 100644
--- a/windows/zsyscall_windows.go
+++ b/windows/zsyscall_windows.go
@@ -183,9 +183,12 @@
procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
procExitProcess = modkernel32.NewProc("ExitProcess")
procFindClose = modkernel32.NewProc("FindClose")
+ procFindCloseChangeNotification = modkernel32.NewProc("FindCloseChangeNotification")
+ procFindFirstChangeNotificationW = modkernel32.NewProc("FindFirstChangeNotificationW")
procFindFirstFileW = modkernel32.NewProc("FindFirstFileW")
procFindFirstVolumeMountPointW = modkernel32.NewProc("FindFirstVolumeMountPointW")
procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW")
+ procFindNextChangeNotification = modkernel32.NewProc("FindNextChangeNotification")
procFindNextFileW = modkernel32.NewProc("FindNextFileW")
procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW")
procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW")
@@ -1525,6 +1528,36 @@
return
}
+func FindCloseChangeNotification(handle Handle) (err error) {
+ r1, _, e1 := syscall.Syscall(procFindCloseChangeNotification.Addr(), 1, uintptr(handle), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(path)
+ if err != nil {
+ return
+ }
+ return _FindFirstChangeNotification(_p0, watchSubtree, notifyFilter)
+}
+
+func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) {
+ var _p1 uint32
+ if watchSubtree {
+ _p1 = 1
+ }
+ r0, _, e1 := syscall.Syscall(procFindFirstChangeNotificationW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter))
+ handle = Handle(r0)
+ if handle == InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
+
func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
handle = Handle(r0)
@@ -1552,6 +1585,14 @@
return
}
+func FindNextChangeNotification(handle Handle) (err error) {
+ r1, _, e1 := syscall.Syscall(procFindNextChangeNotification.Addr(), 1, uintptr(handle), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
func findNextFile1(handle Handle, data *win32finddata1) (err error) {
r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
if r1 == 0 {