Skip to content

Commit

Permalink
compare low-level windows eof and check temporary flag
Browse files Browse the repository at this point in the history
  • Loading branch information
sonroyaalmerol committed Nov 14, 2024
1 parent d4b22ea commit eb11c3f
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 4 deletions.
2 changes: 1 addition & 1 deletion internal/agent/sftp/filelister.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (h *SftpHandler) FileLister(dirPath string) (*FileLister, error) {
}

fullPath := filepath.Join(dirPath, entry.Name())
if skipFile(fullPath) {
if h.skipFile(fullPath) {
continue
}
fileInfos = append(fileInfos, info)
Expand Down
25 changes: 22 additions & 3 deletions internal/agent/sftp/filter.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build windows

package sftp

import (
Expand Down Expand Up @@ -113,15 +115,32 @@ func compileExcludedPaths() []*regexp.Regexp {
// Precompiled regex patterns for excluded paths
var excludedPathRegexes = compileExcludedPaths()

func skipFile(path string) bool {
normalizedPath := strings.TrimPrefix(path, "C:\\Windows\\TEMP\\pbs-plus-vss\\")
normalizedPath = strings.ToUpper(normalizedPath)
func (h *SftpHandler) skipFile(path string) bool {
snapSplit := strings.Split(h.Snapshot.SnapshotPath, "\\")
snapRoot := strings.Join(snapSplit[:len(snapSplit)-1], "\\")

pathWithoutSnap := strings.TrimPrefix(path, snapRoot)
normalizedPath := strings.ToUpper(strings.TrimPrefix(pathWithoutSnap, "\\"))

if strings.TrimSpace(normalizedPath) == "" {
return false
}

for _, regex := range excludedPathRegexes {
if regex.MatchString(normalizedPath) {
return true
}
}

isTmp, err := isTemporary(path)
if err != nil || isTmp {
return true
}

probablyLocked, err := inconsistentSize(path)
if err != nil || probablyLocked {
return true
}

return false
}
69 changes: 69 additions & 0 deletions internal/agent/sftp/windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//go:build windows

package sftp

import (
"os"
"unsafe"

"golang.org/x/sys/windows"
)

// FileStandardInfo contains extended information for the file.
// FILE_STANDARD_INFO in WinBase.h
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info
type FileStandardInfo struct {
AllocationSize, EndOfFile int64
NumberOfLinks uint32
DeletePending, Directory bool
}

type FileAttributeTagInfo struct {
FileAttributes uint32
ReparseTag uint32
}

func isTemporary(path string) (bool, error) {
file, err := os.Open(path)
if err != nil {
return true, err
}
defer file.Close()

at := &FileAttributeTagInfo{}
err = windows.GetFileInformationByHandleEx(windows.Handle(file.Fd()), windows.FileAttributeTagInfo, (*byte)(unsafe.Pointer(at)), uint32(unsafe.Sizeof(*at)))
if err != nil {
return true, err
}

if at.FileAttributes&windows.FILE_ATTRIBUTE_TEMPORARY == windows.FILE_ATTRIBUTE_TEMPORARY {
return true, nil
}

return false, nil
}

func inconsistentSize(path string) (bool, error) {
file, err := os.Open(path)
if err != nil {
return true, err
}
defer file.Close()

si := &FileStandardInfo{}
err = windows.GetFileInformationByHandleEx(windows.Handle(file.Fd()), windows.FileStandardInfo, (*byte)(unsafe.Pointer(si)), uint32(unsafe.Sizeof(*si)))
if err != nil {
return true, err
}

stat, err := os.Lstat(path)
if err != nil {
return true, err
}

if si.EndOfFile == stat.Size() {
return false, nil
}

return true, nil
}

0 comments on commit eb11c3f

Please sign in to comment.