了解文件访问代码段的“为什么”

时间:2018-11-29 07:40:32

标签: go winapi file-permissions logical-operators file-access

过去几天来,我一直在尝试理解代码段。您可以找到要点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
}

我们为什么要执行这些逻辑操作?代码中还存在此类部分的其他实例。如果有人可以指出我的方向或帮助我解释为什么要进行这些操作,那将非常有帮助。谢谢

1 个答案:

答案 0 :(得分:2)

这是从Linux(POSIX)API openman 2 open; http://man7.org/linux/man-pages/man2/open.2.html)到Windows API CreateFilehttps://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew)的转换。 / p>


有关原始代码,请参见src/syscall/syscall_windows.gohttps://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
}