//go:build windows // +build windows package integration import ( "fmt" "sync" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/service/mgr" "golang.org/x/sys/windows" ) type OSSpecific struct { dll *windows.DLL etwFunctions *ETWFunctions } // Initialize loads the dll and finds all the needed functions from it. func (i *OSIntegration) Initialize() error { // Try to load dll err := i.loadDLL() if err != nil { log.Errorf("integration: failed to load dll: %s", err) callbackLock := sync.Mutex{} // listen for event from the updater and try to load again if any. i.instance.BinaryUpdates().EventResourcesUpdated.AddCallback("core-dll-loader", func(wc *mgr.WorkerCtx, s struct{}) (cancel bool, err error) { // Make sure no multiple callas are executed at the same time. callbackLock.Lock() defer callbackLock.Unlock() // Try to load again. err = i.loadDLL() if err != nil { log.Errorf("integration: failed to load dll: %s", err) } else { log.Info("integration: initialize successful after updater event") } return false, nil }) } else { log.Info("integration: initialize successful") } return nil } func (i *OSIntegration) loadDLL() error { // Find path to the dll. file, err := i.instance.BinaryUpdates().GetFile("portmaster-core.dll") if err != nil { return err } // Load the DLL. i.os.dll, err = windows.LoadDLL(file.Path()) if err != nil { return fmt.Errorf("failed to load dll: %q", err) } // Enumerate all needed dll functions. i.os.etwFunctions, err = initializeETW(i.os.dll) if err != nil { return err } // Notify listeners i.OnInitializedEvent.Submit(struct{}{}) return nil } // CleanUp releases any resources allocated during initialization. func (i *OSIntegration) CleanUp() error { if i.os.dll != nil { return i.os.dll.Release() } return nil } // GetETWInterface return struct containing all the ETW related functions, and nil if it was not loaded yet func (i *OSIntegration) GetETWInterface() *ETWFunctions { return i.os.etwFunctions }