diff --git a/internal/winapi/cimfs.go b/internal/winapi/cimfs.go index 56c7b442fb..51277ab6f1 100644 --- a/internal/winapi/cimfs.go +++ b/internal/winapi/cimfs.go @@ -40,23 +40,23 @@ type CimFsImagePath struct { //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) = 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 *CimFsFileMetadata, 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 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) = 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 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 diff --git a/internal/winapi/utils.go b/internal/winapi/utils.go index 70c43fc1cc..de16750d76 100644 --- a/internal/winapi/utils.go +++ b/internal/winapi/utils.go @@ -81,3 +81,8 @@ func ConvertStringSetToSlice(buf []byte) ([]string, error) { func ParseUtf16LE(b []byte) string { return windows.UTF16PtrToString((*uint16)(unsafe.Pointer(&b[0]))) } + +// CimFsSupported checks if CIM FS dlls are present on the system. +func CimFsSupported() bool { + return modcimfs.Load() == nil && modcimwriter.Load() == nil +} diff --git a/internal/winapi/zsyscall_windows.go b/internal/winapi/zsyscall_windows.go index 0aa948a8fb..84778cccc8 100644 --- a/internal/winapi/zsyscall_windows.go +++ b/internal/winapi/zsyscall_windows.go @@ -42,6 +42,7 @@ var ( modbindfltapi = windows.NewLazySystemDLL("bindfltapi.dll") modcfgmgr32 = windows.NewLazySystemDLL("cfgmgr32.dll") modcimfs = windows.NewLazySystemDLL("cimfs.dll") + modcimwriter = windows.NewLazySystemDLL("cimwriter.dll") modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll") modkernel32 = windows.NewLazySystemDLL("kernel32.dll") modnetapi32 = windows.NewLazySystemDLL("netapi32.dll") @@ -58,27 +59,27 @@ var ( procCM_Get_Device_Interface_ListW = modcfgmgr32.NewProc("CM_Get_Device_Interface_ListW") procCM_Get_Device_Interface_List_SizeW = modcfgmgr32.NewProc("CM_Get_Device_Interface_List_SizeW") procCM_Locate_DevNodeW = modcfgmgr32.NewProc("CM_Locate_DevNodeW") - procCimAddFsToMergedImage = modcimfs.NewProc("CimAddFsToMergedImage") - procCimAddFsToMergedImage2 = modcimfs.NewProc("CimAddFsToMergedImage2") - procCimCloseImage = modcimfs.NewProc("CimCloseImage") - procCimCloseStream = modcimfs.NewProc("CimCloseStream") - procCimCommitImage = modcimfs.NewProc("CimCommitImage") - procCimCreateAlternateStream = modcimfs.NewProc("CimCreateAlternateStream") - procCimCreateFile = modcimfs.NewProc("CimCreateFile") - procCimCreateHardLink = modcimfs.NewProc("CimCreateHardLink") - procCimCreateImage = modcimfs.NewProc("CimCreateImage") - procCimCreateImage2 = modcimfs.NewProc("CimCreateImage2") - procCimCreateMergeLink = modcimfs.NewProc("CimCreateMergeLink") - procCimDeletePath = modcimfs.NewProc("CimDeletePath") procCimDismountImage = modcimfs.NewProc("CimDismountImage") procCimGetVerificationInformation = modcimfs.NewProc("CimGetVerificationInformation") procCimMergeMountImage = modcimfs.NewProc("CimMergeMountImage") procCimMergeMountVerifiedImage = modcimfs.NewProc("CimMergeMountVerifiedImage") procCimMountImage = modcimfs.NewProc("CimMountImage") procCimMountVerifiedImage = modcimfs.NewProc("CimMountVerifiedImage") - procCimSealImage = modcimfs.NewProc("CimSealImage") - procCimTombstoneFile = modcimfs.NewProc("CimTombstoneFile") - procCimWriteStream = modcimfs.NewProc("CimWriteStream") + procCimAddFsToMergedImage = modcimwriter.NewProc("CimAddFsToMergedImage") + procCimAddFsToMergedImage2 = modcimwriter.NewProc("CimAddFsToMergedImage2") + procCimCloseImage = modcimwriter.NewProc("CimCloseImage") + procCimCloseStream = modcimwriter.NewProc("CimCloseStream") + procCimCommitImage = modcimwriter.NewProc("CimCommitImage") + procCimCreateAlternateStream = modcimwriter.NewProc("CimCreateAlternateStream") + procCimCreateFile = modcimwriter.NewProc("CimCreateFile") + procCimCreateHardLink = modcimwriter.NewProc("CimCreateHardLink") + procCimCreateImage = modcimwriter.NewProc("CimCreateImage") + procCimCreateImage2 = modcimwriter.NewProc("CimCreateImage2") + procCimCreateMergeLink = modcimwriter.NewProc("CimCreateMergeLink") + procCimDeletePath = modcimwriter.NewProc("CimDeletePath") + procCimSealImage = modcimwriter.NewProc("CimSealImage") + procCimTombstoneFile = modcimwriter.NewProc("CimTombstoneFile") + procCimWriteStream = modcimwriter.NewProc("CimWriteStream") procSetJobCompartmentId = modiphlpapi.NewProc("SetJobCompartmentId") procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole") procCopyFileW = modkernel32.NewProc("CopyFileW") @@ -245,6 +246,129 @@ func _CMLocateDevNode(pdnDevInst *uint32, pDeviceID *uint16, uFlags uint32) (hr return } +func CimDismountImage(volumeID *g) (hr error) { + hr = procCimDismountImage.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimDismountImage.Addr(), uintptr(unsafe.Pointer(volumeID))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + +func CimGetVerificationInformation(blockCimPath string, isSealed *uint32, hashSize *uint64, signatureSize *uint64, fixedHeaderSize *uint64, hash *byte, signature *byte) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(blockCimPath) + if hr != nil { + return + } + return _CimGetVerificationInformation(_p0, isSealed, hashSize, signatureSize, fixedHeaderSize, hash, signature) +} + +func _CimGetVerificationInformation(blockCimPath *uint16, isSealed *uint32, hashSize *uint64, signatureSize *uint64, fixedHeaderSize *uint64, hash *byte, signature *byte) (hr error) { + hr = procCimGetVerificationInformation.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimGetVerificationInformation.Addr(), uintptr(unsafe.Pointer(blockCimPath)), uintptr(unsafe.Pointer(isSealed)), uintptr(unsafe.Pointer(hashSize)), uintptr(unsafe.Pointer(signatureSize)), uintptr(unsafe.Pointer(fixedHeaderSize)), uintptr(unsafe.Pointer(hash)), uintptr(unsafe.Pointer(signature))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + +func CimMergeMountImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g) (hr error) { + hr = procCimMergeMountImage.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimMergeMountImage.Addr(), uintptr(numCimPaths), uintptr(unsafe.Pointer(backingImagePaths)), uintptr(flags), uintptr(unsafe.Pointer(volumeID))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + +func CimMergeMountVerifiedImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) { + r0, _, _ := syscall.SyscallN(procCimMergeMountVerifiedImage.Addr(), uintptr(numCimPaths), uintptr(unsafe.Pointer(backingImagePaths)), uintptr(flags), uintptr(unsafe.Pointer(volumeID)), uintptr(hashSize), uintptr(unsafe.Pointer(hash))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + +func CimMountImage(imagePath string, fsName string, flags uint32, volumeID *g) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(imagePath) + if hr != nil { + return + } + var _p1 *uint16 + _p1, hr = syscall.UTF16PtrFromString(fsName) + if hr != nil { + return + } + return _CimMountImage(_p0, _p1, flags, volumeID) +} + +func _CimMountImage(imagePath *uint16, fsName *uint16, flags uint32, volumeID *g) (hr error) { + hr = procCimMountImage.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimMountImage.Addr(), uintptr(unsafe.Pointer(imagePath)), uintptr(unsafe.Pointer(fsName)), uintptr(flags), uintptr(unsafe.Pointer(volumeID))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + +func CimMountVerifiedImage(imagePath string, fsName string, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(imagePath) + if hr != nil { + return + } + var _p1 *uint16 + _p1, hr = syscall.UTF16PtrFromString(fsName) + if hr != nil { + return + } + return _CimMountVerifiedImage(_p0, _p1, flags, volumeID, hashSize, hash) +} + +func _CimMountVerifiedImage(imagePath *uint16, fsName *uint16, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) { + hr = procCimMountVerifiedImage.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimMountVerifiedImage.Addr(), uintptr(unsafe.Pointer(imagePath)), uintptr(unsafe.Pointer(fsName)), uintptr(flags), uintptr(unsafe.Pointer(volumeID)), uintptr(hashSize), uintptr(unsafe.Pointer(hash))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + func CimAddFsToMergedImage(cimFSHandle FsHandle, path string) (hr error) { var _p0 *uint16 _p0, hr = syscall.UTF16PtrFromString(path) @@ -510,129 +634,6 @@ func _CimDeletePath(cimFSHandle FsHandle, path *uint16) (hr error) { return } -func CimDismountImage(volumeID *g) (hr error) { - hr = procCimDismountImage.Find() - if hr != nil { - return - } - r0, _, _ := syscall.SyscallN(procCimDismountImage.Addr(), uintptr(unsafe.Pointer(volumeID))) - if int32(r0) < 0 { - if r0&0x1fff0000 == 0x00070000 { - r0 &= 0xffff - } - hr = syscall.Errno(r0) - } - return -} - -func CimGetVerificationInformation(blockCimPath string, isSealed *uint32, hashSize *uint64, signatureSize *uint64, fixedHeaderSize *uint64, hash *byte, signature *byte) (hr error) { - var _p0 *uint16 - _p0, hr = syscall.UTF16PtrFromString(blockCimPath) - if hr != nil { - return - } - return _CimGetVerificationInformation(_p0, isSealed, hashSize, signatureSize, fixedHeaderSize, hash, signature) -} - -func _CimGetVerificationInformation(blockCimPath *uint16, isSealed *uint32, hashSize *uint64, signatureSize *uint64, fixedHeaderSize *uint64, hash *byte, signature *byte) (hr error) { - hr = procCimGetVerificationInformation.Find() - if hr != nil { - return - } - r0, _, _ := syscall.SyscallN(procCimGetVerificationInformation.Addr(), uintptr(unsafe.Pointer(blockCimPath)), uintptr(unsafe.Pointer(isSealed)), uintptr(unsafe.Pointer(hashSize)), uintptr(unsafe.Pointer(signatureSize)), uintptr(unsafe.Pointer(fixedHeaderSize)), uintptr(unsafe.Pointer(hash)), uintptr(unsafe.Pointer(signature))) - if int32(r0) < 0 { - if r0&0x1fff0000 == 0x00070000 { - r0 &= 0xffff - } - hr = syscall.Errno(r0) - } - return -} - -func CimMergeMountImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g) (hr error) { - hr = procCimMergeMountImage.Find() - if hr != nil { - return - } - r0, _, _ := syscall.SyscallN(procCimMergeMountImage.Addr(), uintptr(numCimPaths), uintptr(unsafe.Pointer(backingImagePaths)), uintptr(flags), uintptr(unsafe.Pointer(volumeID))) - if int32(r0) < 0 { - if r0&0x1fff0000 == 0x00070000 { - r0 &= 0xffff - } - hr = syscall.Errno(r0) - } - return -} - -func CimMergeMountVerifiedImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) { - r0, _, _ := syscall.SyscallN(procCimMergeMountVerifiedImage.Addr(), uintptr(numCimPaths), uintptr(unsafe.Pointer(backingImagePaths)), uintptr(flags), uintptr(unsafe.Pointer(volumeID)), uintptr(hashSize), uintptr(unsafe.Pointer(hash))) - if int32(r0) < 0 { - if r0&0x1fff0000 == 0x00070000 { - r0 &= 0xffff - } - hr = syscall.Errno(r0) - } - return -} - -func CimMountImage(imagePath string, fsName string, flags uint32, volumeID *g) (hr error) { - var _p0 *uint16 - _p0, hr = syscall.UTF16PtrFromString(imagePath) - if hr != nil { - return - } - var _p1 *uint16 - _p1, hr = syscall.UTF16PtrFromString(fsName) - if hr != nil { - return - } - return _CimMountImage(_p0, _p1, flags, volumeID) -} - -func _CimMountImage(imagePath *uint16, fsName *uint16, flags uint32, volumeID *g) (hr error) { - hr = procCimMountImage.Find() - if hr != nil { - return - } - r0, _, _ := syscall.SyscallN(procCimMountImage.Addr(), uintptr(unsafe.Pointer(imagePath)), uintptr(unsafe.Pointer(fsName)), uintptr(flags), uintptr(unsafe.Pointer(volumeID))) - if int32(r0) < 0 { - if r0&0x1fff0000 == 0x00070000 { - r0 &= 0xffff - } - hr = syscall.Errno(r0) - } - return -} - -func CimMountVerifiedImage(imagePath string, fsName string, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) { - var _p0 *uint16 - _p0, hr = syscall.UTF16PtrFromString(imagePath) - if hr != nil { - return - } - var _p1 *uint16 - _p1, hr = syscall.UTF16PtrFromString(fsName) - if hr != nil { - return - } - return _CimMountVerifiedImage(_p0, _p1, flags, volumeID, hashSize, hash) -} - -func _CimMountVerifiedImage(imagePath *uint16, fsName *uint16, flags uint32, volumeID *g, hashSize uint16, hash *byte) (hr error) { - hr = procCimMountVerifiedImage.Find() - if hr != nil { - return - } - r0, _, _ := syscall.SyscallN(procCimMountVerifiedImage.Addr(), uintptr(unsafe.Pointer(imagePath)), uintptr(unsafe.Pointer(fsName)), uintptr(flags), uintptr(unsafe.Pointer(volumeID)), uintptr(hashSize), uintptr(unsafe.Pointer(hash))) - if int32(r0) < 0 { - if r0&0x1fff0000 == 0x00070000 { - r0 &= 0xffff - } - hr = syscall.Errno(r0) - } - return -} - func CimSealImage(blockCimPath string, hashSize *uint64, fixedHeaderSize *uint64, hash *byte) (hr error) { var _p0 *uint16 _p0, hr = syscall.UTF16PtrFromString(blockCimPath) diff --git a/pkg/cimfs/cimfs.go b/pkg/cimfs/cimfs.go index 3fb95df011..5c2f2616c8 100644 --- a/pkg/cimfs/cimfs.go +++ b/pkg/cimfs/cimfs.go @@ -4,6 +4,7 @@ package cimfs import ( + "github.com/Microsoft/hcsshim/internal/winapi" "path/filepath" "github.com/Microsoft/hcsshim/osversion" @@ -18,7 +19,7 @@ func IsCimFSSupported() bool { build := osversion.Build() // CimFS support is backported to LTSC2022 starting with revision 2031 and should // otherwise be available on all builds >= V25H1Server - return build >= osversion.V25H1Server || (build == osversion.V21H2Server && rv >= 2031) + return (build >= osversion.V25H1Server || (build == osversion.V21H2Server && rv >= 2031)) && winapi.CimFsSupported() } // IsBlockCimSupported returns true if block formatted CIMs (i.e block device CIM & @@ -28,7 +29,7 @@ func IsBlockCimSupported() bool { // TODO(ambarve): Currently we are checking against a higher build number since there is no // official build with block CIM support yet. Once we have that build, we should // update the build number here. - return build >= 27766 + return build >= 27766 && winapi.CimFsSupported() } // IsVerifiedCimSupported returns true if block CIM format supports also writing verification information in the CIM. @@ -37,7 +38,7 @@ func IsVerifiedCimSupported() bool { // TODO(ambarve): Currently we are checking against a higher build number since there is no // official build with block CIM support yet. Once we have that build, we should // update the build number here. - return build >= 27800 + return build >= 27800 && winapi.CimFsSupported() } func IsMergedCimSupported() bool {