Понимание «почему» фрагмента кода доступа к файлу - PullRequest
0 голосов
/ 29 ноября 2018

Последние несколько дней я пытался разобраться в фрагменте кода.Вы можете найти суть здесь

Обзор

Код читает MFT диска Windows, создает структуру карт файлов в 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 голосов
/ 29 ноября 2018

Это преобразование из Linux (POSIX) API open (man 2 open; http://man7.org/linux/man-pages/man2/open.2.html) в 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
}
...