了解文件访问代码段的 "Why"
Understanding the "Why" of a file access code snippet
过去几天我一直在努力理解一段代码片段。你可以找到要点 here
概览
代码读取 Windows 驱动器的 MFT,在 MFT 中创建文件映射结构。然后它继续读取 USN 日志以检测这些文件发生了什么变化。
问题
脚本中发生了一些逻辑操作。我可以理解代码部分在做什么,但为什么这样做是过去几天一直困扰我的问题。我偶然发现了各种 Windows 文档,例如 this,但即便如此,它对我来说也没有多大意义。
例如-
switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
case O_RDONLY:
access = GENERIC_READ
case O_WRONLY:
access = GENERIC_WRITE
case O_RDWR:
access = GENERIC_READ | GENERIC_WRITE
}
if mode&O_CREAT != 0 {
access |= GENERIC_WRITE
}
if mode&O_APPEND != 0 {
access &^= GENERIC_WRITE
access |= FILE_APPEND_DATA
}
我们为什么要做这些逻辑运算?代码中还有此类部分的其他实例。如果有人能指出方向或帮助我完成这些操作,那将非常有帮助。谢谢
它是从Linux (POSIX) API open
(man 2 open
; http://man7.org/linux/man-pages/man2/open.2.html) to the Windows API CreateFile
(https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew).
原代码见src/syscall/syscall_windows.go
(https://go.googlesource.com/go):
func Open(path string, mode int, perm uint32) (fd Handle, err error) {
if len(path) == 0 {
return InvalidHandle, ERROR_FILE_NOT_FOUND
}
pathp, err := UTF16PtrFromString(path)
if err != nil {
return InvalidHandle, err
}
var access uint32
switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
case O_RDONLY:
access = GENERIC_READ
case O_WRONLY:
access = GENERIC_WRITE
case O_RDWR:
access = GENERIC_READ | GENERIC_WRITE
}
if mode&O_CREAT != 0 {
access |= GENERIC_WRITE
}
if mode&O_APPEND != 0 {
access &^= GENERIC_WRITE
access |= FILE_APPEND_DATA
}
sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
var sa *SecurityAttributes
if mode&O_CLOEXEC == 0 {
sa = makeInheritSa()
}
var createmode uint32
switch {
case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
createmode = CREATE_NEW
case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
createmode = CREATE_ALWAYS
case mode&O_CREAT == O_CREAT:
createmode = OPEN_ALWAYS
case mode&O_TRUNC == O_TRUNC:
createmode = TRUNCATE_EXISTING
default:
createmode = OPEN_EXISTING
}
h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
return h, e
}
过去几天我一直在努力理解一段代码片段。你可以找到要点 here
概览
代码读取 Windows 驱动器的 MFT,在 MFT 中创建文件映射结构。然后它继续读取 USN 日志以检测这些文件发生了什么变化。
问题
脚本中发生了一些逻辑操作。我可以理解代码部分在做什么,但为什么这样做是过去几天一直困扰我的问题。我偶然发现了各种 Windows 文档,例如 this,但即便如此,它对我来说也没有多大意义。
例如-
switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
case O_RDONLY:
access = GENERIC_READ
case O_WRONLY:
access = GENERIC_WRITE
case O_RDWR:
access = GENERIC_READ | GENERIC_WRITE
}
if mode&O_CREAT != 0 {
access |= GENERIC_WRITE
}
if mode&O_APPEND != 0 {
access &^= GENERIC_WRITE
access |= FILE_APPEND_DATA
}
我们为什么要做这些逻辑运算?代码中还有此类部分的其他实例。如果有人能指出方向或帮助我完成这些操作,那将非常有帮助。谢谢
它是从Linux (POSIX) API open
(man 2 open
; http://man7.org/linux/man-pages/man2/open.2.html) to the Windows API CreateFile
(https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew).
原代码见src/syscall/syscall_windows.go
(https://go.googlesource.com/go):
func Open(path string, mode int, perm uint32) (fd Handle, err error) {
if len(path) == 0 {
return InvalidHandle, ERROR_FILE_NOT_FOUND
}
pathp, err := UTF16PtrFromString(path)
if err != nil {
return InvalidHandle, err
}
var access uint32
switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
case O_RDONLY:
access = GENERIC_READ
case O_WRONLY:
access = GENERIC_WRITE
case O_RDWR:
access = GENERIC_READ | GENERIC_WRITE
}
if mode&O_CREAT != 0 {
access |= GENERIC_WRITE
}
if mode&O_APPEND != 0 {
access &^= GENERIC_WRITE
access |= FILE_APPEND_DATA
}
sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
var sa *SecurityAttributes
if mode&O_CLOEXEC == 0 {
sa = makeInheritSa()
}
var createmode uint32
switch {
case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
createmode = CREATE_NEW
case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
createmode = CREATE_ALWAYS
case mode&O_CREAT == O_CREAT:
createmode = OPEN_ALWAYS
case mode&O_TRUNC == O_TRUNC:
createmode = TRUNCATE_EXISTING
default:
createmode = OPEN_EXISTING
}
h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
return h, e
}