Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 140 additions & 54 deletions internal/winapi/cimfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,146 @@
package winapi

import (
"unsafe"

"github.com/Microsoft/go-winio/pkg/guid"
"golang.org/x/sys/windows"

"github.com/Microsoft/hcsshim/internal/winapi/cimfs"
"github.com/Microsoft/hcsshim/internal/winapi/cimwriter"
"github.com/Microsoft/hcsshim/internal/winapi/types"
)

type g = guid.GUID
type FsHandle uintptr
type StreamHandle uintptr

type CimFsFileMetadata struct {
Attributes uint32
FileSize int64

CreationTime windows.Filetime
LastWriteTime windows.Filetime
ChangeTime windows.Filetime
LastAccessTime windows.Filetime

SecurityDescriptorBuffer unsafe.Pointer
SecurityDescriptorSize uint32

ReparseDataBuffer unsafe.Pointer
ReparseDataSize uint32

ExtendedAttributes unsafe.Pointer
EACount uint32
}

type CimFsImagePath struct {
ImageDir *uint16
ImageName *uint16
}

//sys CimMountImage(imagePath string, fsName string, flags uint32, volumeID *g) (hr error) = cimfs.CimMountImage?
//sys CimDismountImage(volumeID *g) (hr error) = cimfs.CimDismountImage?

//sys CimCreateImage(imagePath string, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimwriter.CimCreateImage?
//sys CimCreateImage2(imagePath string, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimwriter.CimCreateImage2?
//sys CimCloseImage(cimFSHandle FsHandle) = cimwriter.CimCloseImage?
//sys CimCommitImage(cimFSHandle FsHandle) (hr error) = cimwriter.CimCommitImage?

//sys CimCreateFile(cimFSHandle FsHandle, path string, file *CimFsFileMetadata, cimStreamHandle *StreamHandle) (hr error) = cimwriter.CimCreateFile?
//sys CimCloseStream(cimStreamHandle StreamHandle) (hr error) = cimwriter.CimCloseStream?
//sys CimWriteStream(cimStreamHandle StreamHandle, buffer uintptr, bufferSize uint32) (hr error) = cimwriter.CimWriteStream?
//sys CimDeletePath(cimFSHandle FsHandle, path string) (hr error) = cimwriter.CimDeletePath?
//sys CimCreateHardLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimwriter.CimCreateHardLink?
//sys CimCreateAlternateStream(cimFSHandle FsHandle, path string, size uint64, cimStreamHandle *StreamHandle) (hr error) = cimwriter.CimCreateAlternateStream?
//sys CimAddFsToMergedImage(cimFSHandle FsHandle, path string) (hr error) = cimwriter.CimAddFsToMergedImage?
//sys CimAddFsToMergedImage2(cimFSHandle FsHandle, path string, flags uint32) (hr error) = cimwriter.CimAddFsToMergedImage2?
//sys CimMergeMountImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g) (hr error) = cimfs.CimMergeMountImage?
//sys CimTombstoneFile(cimFSHandle FsHandle, path string) (hr error) = cimwriter.CimTombstoneFile?
//sys CimCreateMergeLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimwriter.CimCreateMergeLink?
//sys CimSealImage(blockCimPath string, hashSize *uint64, fixedHeaderSize *uint64, hash *byte) (hr error) = cimwriter.CimSealImage?
//sys CimGetVerificationInformation(blockCimPath string, isSealed *uint32, hashSize *uint64, signatureSize *uint64, fixedHeaderSize *uint64, hash *byte, signature *byte) (hr error) = cimfs.CimGetVerificationInformation?
//sys CimMountVerifiedImage(imagePath string, fsName string, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) = cimfs.CimMountVerifiedImage?
//sys CimMergeMountVerifiedImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) = cimfs.CimMergeMountVerifiedImage
// pickSupported makes sure we use appropriate syscalls depending on which DLLs are present.
func pickSupported[F any](cimWriterFunc, cimfsFunc F) F {
if cimwriter.Supported() {
return cimWriterFunc
}
return cimfsFunc
}

func CimMountImage(imagePath string, fsName string, flags uint32, volumeID *guid.GUID) error {
return cimfs.CimMountImage(imagePath, fsName, flags, volumeID)
}

func CimDismountImage(volumeID *guid.GUID) error {
return cimfs.CimDismountImage(volumeID)
}

func CimCreateImage(imagePath string, oldFSName *uint16, newFSName *uint16, cimFSHandle *types.FsHandle) error {
return pickSupported(
cimwriter.CimCreateImage,
cimfs.CimCreateImage,
)(imagePath, oldFSName, newFSName, cimFSHandle)
}

func CimCreateImage2(imagePath string, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *types.FsHandle) error {
return pickSupported(
cimwriter.CimCreateImage2,
cimfs.CimCreateImage2,
)(imagePath, flags, oldFSName, newFSName, cimFSHandle)
}

func CimCloseImage(cimFSHandle types.FsHandle) error {
return pickSupported(
cimwriter.CimCloseImage,
cimfs.CimCloseImage,
)(cimFSHandle)
}

func CimCommitImage(cimFSHandle types.FsHandle) error {
return pickSupported(
cimwriter.CimCommitImage,
cimfs.CimCommitImage,
)(cimFSHandle)
}

func CimCreateFile(cimFSHandle types.FsHandle, path string, file *types.CimFsFileMetadata, cimStreamHandle *types.StreamHandle) error {
return pickSupported(
cimwriter.CimCreateFile,
cimfs.CimCreateFile,
)(cimFSHandle, path, file, cimStreamHandle)
}

func CimCloseStream(cimStreamHandle types.StreamHandle) error {
return pickSupported(
cimwriter.CimCloseStream,
cimfs.CimCloseStream,
)(cimStreamHandle)
}

func CimWriteStream(cimStreamHandle types.StreamHandle, buffer uintptr, bufferSize uint32) error {
return pickSupported(
cimwriter.CimWriteStream,
cimfs.CimWriteStream,
)(cimStreamHandle, buffer, bufferSize)
}

func CimDeletePath(cimFSHandle types.FsHandle, path string) error {
return pickSupported(
cimwriter.CimDeletePath,
cimfs.CimDeletePath,
)(cimFSHandle, path)
}

func CimCreateHardLink(cimFSHandle types.FsHandle, newPath string, oldPath string) error {
return pickSupported(
cimwriter.CimCreateHardLink,
cimfs.CimCreateHardLink,
)(cimFSHandle, newPath, oldPath)
}

func CimCreateAlternateStream(cimFSHandle types.FsHandle, path string, size uint64, cimStreamHandle *types.StreamHandle) error {
return pickSupported(
cimwriter.CimCreateAlternateStream,
cimfs.CimCreateAlternateStream,
)(cimFSHandle, path, size, cimStreamHandle)
}

func CimAddFsToMergedImage(cimFSHandle types.FsHandle, path string) error {
return pickSupported(
cimwriter.CimAddFsToMergedImage,
cimfs.CimAddFsToMergedImage,
)(cimFSHandle, path)
}

func CimAddFsToMergedImage2(cimFSHandle types.FsHandle, path string, flags uint32) error {
return pickSupported(
cimwriter.CimAddFsToMergedImage2,
cimfs.CimAddFsToMergedImage2,
)(cimFSHandle, path, flags)
}

func CimMergeMountImage(numCimPaths uint32, backingImagePaths *types.CimFsImagePath, flags uint32, volumeID *guid.GUID) error {
return cimfs.CimMergeMountImage(numCimPaths, backingImagePaths, flags, volumeID)
}

func CimTombstoneFile(cimFSHandle types.FsHandle, path string) error {
return pickSupported(
cimwriter.CimTombstoneFile,
cimfs.CimTombstoneFile,
)(cimFSHandle, path)
}

func CimCreateMergeLink(cimFSHandle types.FsHandle, newPath string, oldPath string) (hr error) {
return pickSupported(
cimwriter.CimCreateMergeLink,
cimfs.CimCreateMergeLink,
)(cimFSHandle, newPath, oldPath)
}

func CimSealImage(blockCimPath string, hashSize *uint64, fixedHeaderSize *uint64, hash *byte) (hr error) {
return pickSupported(
cimwriter.CimSealImage,
cimfs.CimSealImage,
)(blockCimPath, hashSize, fixedHeaderSize, hash)
}

func CimGetVerificationInformation(blockCimPath string, isSealed *uint32, hashSize *uint64, signatureSize *uint64, fixedHeaderSize *uint64, hash *byte, signature *byte) (hr error) {
return cimfs.CimGetVerificationInformation(blockCimPath, isSealed, hashSize, signatureSize, fixedHeaderSize, hash, signature)
}

func CimMountVerifiedImage(imagePath string, fsName string, flags uint32, volumeID *guid.GUID, hashSize uint16, hash *byte) error {
return cimfs.CimMountVerifiedImage(imagePath, fsName, flags, volumeID, hashSize, hash)
}

func CimMergeMountVerifiedImage(numCimPaths uint32, backingImagePaths *types.CimFsImagePath, flags uint32, volumeID *guid.GUID, hashSize uint16, hash *byte) error {
return cimfs.CimMergeMountVerifiedImage(numCimPaths, backingImagePaths, flags, volumeID, hashSize, hash)
}
46 changes: 46 additions & 0 deletions internal/winapi/cimfs/cimfs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//go:build windows

package cimfs

import (
"github.com/Microsoft/go-winio/pkg/guid"

"github.com/Microsoft/hcsshim/internal/winapi/types"
)

// Type aliases

type GUID = guid.GUID
type FsHandle = types.FsHandle
type StreamHandle = types.StreamHandle
type FileMetadata = types.CimFsFileMetadata
type ImagePath = types.CimFsImagePath

//sys CimMountImage(imagePath string, fsName string, flags uint32, volumeID *GUID) (hr error) = cimfs.CimMountImage?
//sys CimDismountImage(volumeID *GUID) (hr error) = cimfs.CimDismountImage?

//sys CimCreateImage(imagePath string, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimfs.CimCreateImage?
//sys CimCreateImage2(imagePath string, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimfs.CimCreateImage2?
//sys CimCloseImage(cimFSHandle FsHandle) = cimfs.CimCloseImage?
//sys CimCommitImage(cimFSHandle FsHandle) (hr error) = cimfs.CimCommitImage?

//sys CimCreateFile(cimFSHandle FsHandle, path string, file *FileMetadata, cimStreamHandle *StreamHandle) (hr error) = cimfs.CimCreateFile?
//sys CimCloseStream(cimStreamHandle StreamHandle) (hr error) = cimfs.CimCloseStream?
//sys CimWriteStream(cimStreamHandle StreamHandle, buffer uintptr, bufferSize uint32) (hr error) = cimfs.CimWriteStream?
//sys CimDeletePath(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimDeletePath?
//sys CimCreateHardLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimfs.CimCreateHardLink?
//sys CimCreateAlternateStream(cimFSHandle FsHandle, path string, size uint64, cimStreamHandle *StreamHandle) (hr error) = cimfs.CimCreateAlternateStream?
//sys CimAddFsToMergedImage(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimAddFsToMergedImage?
//sys CimAddFsToMergedImage2(cimFSHandle FsHandle, path string, flags uint32) (hr error) = cimfs.CimAddFsToMergedImage2?
//sys CimMergeMountImage(numCimPaths uint32, backingImagePaths *ImagePath, flags uint32, volumeID *GUID) (hr error) = cimfs.CimMergeMountImage?
//sys CimTombstoneFile(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimTombstoneFile?
//sys CimCreateMergeLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimfs.CimCreateMergeLink?
//sys CimSealImage(blockCimPath string, hashSize *uint64, fixedHeaderSize *uint64, hash *byte) (hr error) = cimfs.CimSealImage?
//sys CimGetVerificationInformation(blockCimPath string, isSealed *uint32, hashSize *uint64, signatureSize *uint64, fixedHeaderSize *uint64, hash *byte, signature *byte) (hr error) = cimfs.CimGetVerificationInformation?
//sys CimMountVerifiedImage(imagePath string, fsName string, flags uint32, volumeID *GUID, hashSize uint16, hash *byte) (hr error) = cimfs.CimMountVerifiedImage?
//sys CimMergeMountVerifiedImage(numCimPaths uint32, backingImagePaths *ImagePath, flags uint32, volumeID *GUID, hashSize uint16, hash *byte) (hr error) = cimfs.CimMergeMountVerifiedImage?

// Supported checks if cimfs.dll is present on the system.
func Supported() bool {
return modcimfs.Load() == nil
}
3 changes: 3 additions & 0 deletions internal/winapi/cimfs/syscall.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package cimfs

//go:generate go tool github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./*.go
Loading