了解文件访问代码段的 "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
}