chore: add windowsupdate COM interface stubs and update third-party licenses
This commit is contained in:
parent
c8b0ee1040
commit
3c510d51c0
29 changed files with 2200 additions and 35 deletions
|
|
@ -5,11 +5,11 @@ This document lists the third-party components and their licenses that are inclu
|
|||
## Windows Update Package (Apache 2.0)
|
||||
|
||||
**Package**: `github.com/ceshihao/windowsupdate`
|
||||
**Version**: Included as vendored code in `aggregator-agent/pkg/windowsupdate/`
|
||||
**Version**: Vendored from master branch (Jan 2026 refactor), in `agent/pkg/windowsupdate/`
|
||||
**License**: Apache License 2.0
|
||||
**Copyright**: Copyright 2022 Zheng Dayu
|
||||
**Source**: https://github.com/ceshihao/windowsupdate
|
||||
**License File**: https://github.com/ceshihao/windowsupdate/blob/main/LICENSE
|
||||
**License File**: https://github.com/ceshihao/windowsupdate/blob/master/LICENSE
|
||||
|
||||
### License Text
|
||||
|
||||
|
|
|
|||
|
|
@ -23,3 +23,132 @@ const (
|
|||
OperationResultCodeOrcFailed
|
||||
OperationResultCodeOrcAborted
|
||||
)
|
||||
|
||||
// DeploymentAction defines the action for which an update is eligible.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-deploymentaction
|
||||
const (
|
||||
DeploymentActionDaNone int32 = iota
|
||||
DeploymentActionDaDetection
|
||||
DeploymentActionDaInstallation
|
||||
DeploymentActionDaUninstallation
|
||||
DeploymentActionDaOptionalInstallation
|
||||
)
|
||||
|
||||
// DownloadPriority defines the priority of a download.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-downloadpriority
|
||||
const (
|
||||
DownloadPriorityDpLow int32 = 1
|
||||
DownloadPriorityDpNormal int32 = 2
|
||||
DownloadPriorityDpHigh int32 = 3
|
||||
)
|
||||
|
||||
// InstallationImpact defines the impact of installing an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-installationimpact
|
||||
const (
|
||||
InstallationImpactIiNormal int32 = iota
|
||||
InstallationImpactIiMinor
|
||||
InstallationImpactIiRequiresExclusiveHandling
|
||||
)
|
||||
|
||||
// InstallationRebootBehavior defines the restart behavior of an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-installationrebootbehavior
|
||||
const (
|
||||
InstallationRebootBehaviorIrbNeverReboots int32 = iota
|
||||
InstallationRebootBehaviorIrbAlwaysRequiresReboot
|
||||
InstallationRebootBehaviorIrbCanRequestReboot
|
||||
)
|
||||
|
||||
// UpdateOperation defines the operation for which an update is being installed or uninstalled.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updateoperation
|
||||
const (
|
||||
UpdateOperationUoInstallation int32 = 1
|
||||
UpdateOperationUoUninstallation int32 = 2
|
||||
)
|
||||
|
||||
// UpdateExceptionContext defines the context in which an IUpdateException object can be provided.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updateexceptioncontext
|
||||
const (
|
||||
UpdateExceptionContextUecGeneral int32 = iota + 1
|
||||
UpdateExceptionContextUecWindowsDriver
|
||||
UpdateExceptionContextUecWindowsInstaller
|
||||
UpdateExceptionContextUecSearchIncomplete
|
||||
)
|
||||
|
||||
// ServerSelection defines the update server that is used for a search or download operation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-serverselection
|
||||
const (
|
||||
ServerSelectionSsDefault int32 = iota // Use the default server.
|
||||
ServerSelectionSsManagedServer // Use the managed server (WSUS).
|
||||
ServerSelectionSsWindowsUpdate // Use Windows Update.
|
||||
ServerSelectionSsOthers // Use a non-Microsoft server.
|
||||
)
|
||||
|
||||
// AutomaticUpdatesNotificationLevel defines the notification level for automatic updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-automaticupdatesnotificationlevel
|
||||
const (
|
||||
AutomaticUpdatesNotificationLevelAunlNotConfigured int32 = iota // Not configured.
|
||||
AutomaticUpdatesNotificationLevelAunlDisabled // Disabled.
|
||||
AutomaticUpdatesNotificationLevelAunlNotifyBeforeDownload // Notify before download.
|
||||
AutomaticUpdatesNotificationLevelAunlNotifyBeforeInstallation // Notify before installation.
|
||||
AutomaticUpdatesNotificationLevelAunlScheduledInstallation // Scheduled installation.
|
||||
)
|
||||
|
||||
// AutomaticUpdatesScheduledInstallationDay defines the days of the week for scheduled automatic updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-automaticupdatesscheduledinstallationday
|
||||
const (
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEveryDay int32 = iota // Every day.
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEverySunday // Every Sunday.
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEveryMonday // Every Monday.
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEveryTuesday // Every Tuesday.
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEveryWednesday // Every Wednesday.
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEveryThursday // Every Thursday.
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEveryFriday // Every Friday.
|
||||
AutomaticUpdatesScheduledInstallationDayAuisdEverySaturday // Every Saturday.
|
||||
)
|
||||
|
||||
// DownloadPhase defines the phase of the download.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-downloadphase
|
||||
const (
|
||||
DownloadPhaseInitializing int32 = iota + 1
|
||||
DownloadPhaseDownloading
|
||||
DownloadPhaseVerifying
|
||||
)
|
||||
|
||||
// AutoDownload defines auto download behavior for IUpdate5.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-autodownloadmode
|
||||
const (
|
||||
AutoDownloadModeForbidAutoDownload int32 = iota
|
||||
AutoDownloadModeAllowAutoDownload
|
||||
)
|
||||
|
||||
// AutoSelection defines auto selection behavior for IUpdate5.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-autoselectionmode
|
||||
const (
|
||||
AutoSelectionModeLetWindowsUpdateDecide int32 = iota
|
||||
AutoSelectionModeAutoSelectIfDownloaded
|
||||
AutoSelectionModeNeverAutoSelect
|
||||
AutoSelectionModeAlwaysAutoSelect
|
||||
)
|
||||
|
||||
// UpdateServiceRegistrationState defines the state of a service registration.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updateserviceregistrationstate
|
||||
const (
|
||||
UpdateServiceRegistrationStateNotRegistered int32 = iota + 1
|
||||
UpdateServiceRegistrationStateRegistrationPending
|
||||
UpdateServiceRegistrationStateRegistered
|
||||
)
|
||||
|
||||
// AddServiceFlag defines flags for AddService2.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-addserviceflag
|
||||
const (
|
||||
AddServiceFlagAsfAllowPendingRegistration int32 = 1
|
||||
AddServiceFlagAsfAllowOnlineRegistration int32 = 2
|
||||
AddServiceFlagAsfRegisterServiceWithAU int32 = 4
|
||||
)
|
||||
|
||||
// UpdateType defines the type of an update.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updatetype
|
||||
const (
|
||||
UpdateTypeSoftware int32 = iota + 1
|
||||
UpdateTypeDriver
|
||||
)
|
||||
|
|
|
|||
143
agent/pkg/windowsupdate/iautomaticupdates.go
Normal file
143
agent/pkg/windowsupdate/iautomaticupdates.go
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IAutomaticUpdates contains the functionality of Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iautomaticupdates
|
||||
type IAutomaticUpdates struct {
|
||||
disp *ole.IDispatch
|
||||
ServiceEnabled bool
|
||||
}
|
||||
|
||||
// NewAutomaticUpdates creates a new IAutomaticUpdates instance.
|
||||
func NewAutomaticUpdates() (*IAutomaticUpdates, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.AutoUpdate")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disp, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toIAutomaticUpdates(disp)
|
||||
}
|
||||
|
||||
func toIAutomaticUpdates(autoUpdatesDisp *ole.IDispatch) (*IAutomaticUpdates, error) {
|
||||
var err error
|
||||
iAutoUpdates := &IAutomaticUpdates{
|
||||
disp: autoUpdatesDisp,
|
||||
}
|
||||
|
||||
if iAutoUpdates.ServiceEnabled, err = toBoolErr(oleutil.GetProperty(autoUpdatesDisp, "ServiceEnabled")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iAutoUpdates, nil
|
||||
}
|
||||
|
||||
// DetectNow begins detection of updates.
|
||||
// The DetectNow method returns immediately without waiting for the detection to complete.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdates-detectnow
|
||||
func (a *IAutomaticUpdates) DetectNow() error {
|
||||
_, err := oleutil.CallMethod(a.disp, "DetectNow")
|
||||
return err
|
||||
}
|
||||
|
||||
// EnableService enables all the components that Automatic Updates requires.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdates-enableservice
|
||||
func (a *IAutomaticUpdates) EnableService() error {
|
||||
_, err := oleutil.CallMethod(a.disp, "EnableService")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.ServiceEnabled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Pause pauses automatic updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdates-pause
|
||||
func (a *IAutomaticUpdates) Pause() error {
|
||||
_, err := oleutil.CallMethod(a.disp, "Pause")
|
||||
return err
|
||||
}
|
||||
|
||||
// Resume restarts automatic updates if paused.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdates-resume
|
||||
func (a *IAutomaticUpdates) Resume() error {
|
||||
_, err := oleutil.CallMethod(a.disp, "Resume")
|
||||
return err
|
||||
}
|
||||
|
||||
// ShowSettingsDialog displays a dialog box that contains settings for Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdates-showsettingsdialog
|
||||
func (a *IAutomaticUpdates) ShowSettingsDialog() error {
|
||||
_, err := oleutil.CallMethod(a.disp, "ShowSettingsDialog")
|
||||
return err
|
||||
}
|
||||
|
||||
// GetSettings retrieves the configuration settings for Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdates-get_settings
|
||||
func (a *IAutomaticUpdates) GetSettings() (*IAutomaticUpdatesSettings, error) {
|
||||
settingsDisp, err := toIDispatchErr(oleutil.GetProperty(a.disp, "Settings"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIAutomaticUpdatesSettings(settingsDisp)
|
||||
}
|
||||
|
||||
// GetResults retrieves the results of the last Automatic Updates search. (IAutomaticUpdates2)
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdates2-get_results
|
||||
func (a *IAutomaticUpdates) GetResults() (*IAutomaticUpdatesResults, error) {
|
||||
resultsDisp, err := toIDispatchErr(oleutil.GetProperty(a.disp, "Results"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIAutomaticUpdatesResults(resultsDisp)
|
||||
}
|
||||
|
||||
// IAutomaticUpdatesResults contains the read-only properties that describe Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iautomaticupdatesresults
|
||||
type IAutomaticUpdatesResults struct {
|
||||
disp *ole.IDispatch
|
||||
LastInstallationSuccessDate *time.Time
|
||||
LastSearchSuccessDate *time.Time
|
||||
}
|
||||
|
||||
func toIAutomaticUpdatesResults(disp *ole.IDispatch) (*IAutomaticUpdatesResults, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
r := &IAutomaticUpdatesResults{disp: disp}
|
||||
|
||||
if r.LastInstallationSuccessDate, err = toTimeErr(oleutil.GetProperty(disp, "LastInstallationSuccessDate")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r.LastSearchSuccessDate, err = toTimeErr(oleutil.GetProperty(disp, "LastSearchSuccessDate")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
124
agent/pkg/windowsupdate/iautomaticupdatessettings.go
Normal file
124
agent/pkg/windowsupdate/iautomaticupdatessettings.go
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IAutomaticUpdatesSettings contains the settings that are available in Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iautomaticupdatessettings
|
||||
type IAutomaticUpdatesSettings struct {
|
||||
disp *ole.IDispatch
|
||||
NotificationLevel int32 // AutomaticUpdatesNotificationLevel enum
|
||||
ReadOnly bool
|
||||
Required bool
|
||||
ScheduledInstallationDay int32 // AutomaticUpdatesScheduledInstallationDay enum (not supported on Windows 8+)
|
||||
ScheduledInstallationTime int32 // Hour of the day (0-23) (not supported on Windows 8+)
|
||||
}
|
||||
|
||||
func toIAutomaticUpdatesSettings(settingsDisp *ole.IDispatch) (*IAutomaticUpdatesSettings, error) {
|
||||
var err error
|
||||
iSettings := &IAutomaticUpdatesSettings{
|
||||
disp: settingsDisp,
|
||||
}
|
||||
|
||||
if iSettings.NotificationLevel, err = toInt32Err(oleutil.GetProperty(settingsDisp, "NotificationLevel")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iSettings.ReadOnly, err = toBoolErr(oleutil.GetProperty(settingsDisp, "ReadOnly")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iSettings.Required, err = toBoolErr(oleutil.GetProperty(settingsDisp, "Required")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iSettings.ScheduledInstallationDay, err = toInt32Err(oleutil.GetProperty(settingsDisp, "ScheduledInstallationDay")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iSettings.ScheduledInstallationTime, err = toInt32Err(oleutil.GetProperty(settingsDisp, "ScheduledInstallationTime")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iSettings, nil
|
||||
}
|
||||
|
||||
// Refresh reads the latest Automatic Updates settings.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdatessettings-refresh
|
||||
func (s *IAutomaticUpdatesSettings) Refresh() error {
|
||||
_, err := oleutil.CallMethod(s.disp, "Refresh")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Re-read properties after refresh
|
||||
refreshed, err := toIAutomaticUpdatesSettings(s.disp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.NotificationLevel = refreshed.NotificationLevel
|
||||
s.ReadOnly = refreshed.ReadOnly
|
||||
s.Required = refreshed.Required
|
||||
s.ScheduledInstallationDay = refreshed.ScheduledInstallationDay
|
||||
s.ScheduledInstallationTime = refreshed.ScheduledInstallationTime
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save applies the current Automatic Updates settings.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdatessettings-save
|
||||
func (s *IAutomaticUpdatesSettings) Save() error {
|
||||
_, err := oleutil.CallMethod(s.disp, "Save")
|
||||
return err
|
||||
}
|
||||
|
||||
// PutNotificationLevel sets the notification level for Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdatessettings-put_notificationlevel
|
||||
func (s *IAutomaticUpdatesSettings) PutNotificationLevel(level int32) error {
|
||||
_, err := oleutil.PutProperty(s.disp, "NotificationLevel", level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.NotificationLevel = level
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutScheduledInstallationDay sets the scheduled installation day.
|
||||
// Note: Not supported on Windows 8 and later.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdatessettings-put_scheduledinstallationday
|
||||
func (s *IAutomaticUpdatesSettings) PutScheduledInstallationDay(day int32) error {
|
||||
_, err := oleutil.PutProperty(s.disp, "ScheduledInstallationDay", day)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.ScheduledInstallationDay = day
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutScheduledInstallationTime sets the scheduled installation time (hour of day, 0-23).
|
||||
// Note: Not supported on Windows 8 and later.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iautomaticupdatessettings-put_scheduledinstallationtime
|
||||
func (s *IAutomaticUpdatesSettings) PutScheduledInstallationTime(hour int32) error {
|
||||
_, err := oleutil.PutProperty(s.disp, "ScheduledInstallationTime", hour)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.ScheduledInstallationTime = hour
|
||||
return nil
|
||||
}
|
||||
|
|
@ -98,29 +98,33 @@ func toICategory(categoryDisp *ole.IDispatch) (*ICategory, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// parentDisp, err := toIDispatchErr(oleutil.GetProperty(categoryDisp, "Parent"))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// if parentDisp != nil {
|
||||
// if iCategory.Parent, err = toICategory(parentDisp); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
/*
|
||||
parentDisp, err := toIDispatchErr(oleutil.GetProperty(categoryDisp, "Parent"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if parentDisp != nil {
|
||||
if iCategory.Parent, err = toICategory(parentDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if iCategory.Type, err = toStringErr(oleutil.GetProperty(categoryDisp, "Type")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// updatesDisp, err := toIDispatchErr(oleutil.GetProperty(categoryDisp, "Updates"))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// if updatesDisp != nil {
|
||||
// if iCategory.Updates, err = toIUpdates(updatesDisp); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
/*
|
||||
updatesDisp, err := toIDispatchErr(oleutil.GetProperty(categoryDisp, "Updates"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if updatesDisp != nil {
|
||||
if iCategory.Updates, err = toIUpdates(updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return iCategory, nil
|
||||
}
|
||||
|
|
|
|||
77
agent/pkg/windowsupdate/idownloadjob.go
Normal file
77
agent/pkg/windowsupdate/idownloadjob.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IDownloadJob contains properties and methods that are available to a download operation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-idownloadjob
|
||||
type IDownloadJob struct {
|
||||
disp *ole.IDispatch
|
||||
AsyncState interface{}
|
||||
IsCompleted bool
|
||||
Updates []*IUpdate
|
||||
}
|
||||
|
||||
func toIDownloadJob(disp *ole.IDispatch) (*IDownloadJob, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
j := &IDownloadJob{disp: disp}
|
||||
|
||||
if j.IsCompleted, err = toBoolErr(oleutil.GetProperty(disp, "IsCompleted")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatesDisp, err := toIDispatchErr(oleutil.GetProperty(disp, "Updates"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if updatesDisp != nil {
|
||||
if j.Updates, err = toIUpdates(updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return j, nil
|
||||
}
|
||||
|
||||
// CleanUp releases the resources held by the download job.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-idownloadjob-cleanup
|
||||
func (j *IDownloadJob) CleanUp() error {
|
||||
_, err := oleutil.CallMethod(j.disp, "CleanUp")
|
||||
return err
|
||||
}
|
||||
|
||||
// RequestAbort requests that the download job be canceled.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-idownloadjob-requestabort
|
||||
func (j *IDownloadJob) RequestAbort() error {
|
||||
_, err := oleutil.CallMethod(j.disp, "RequestAbort")
|
||||
return err
|
||||
}
|
||||
|
||||
// GetProgress returns the current progress of the download.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-idownloadjob-getprogress
|
||||
func (j *IDownloadJob) GetProgress() (*IDownloadProgress, error) {
|
||||
progressDisp, err := toIDispatchErr(oleutil.CallMethod(j.disp, "GetProgress"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIDownloadProgress(progressDisp)
|
||||
}
|
||||
86
agent/pkg/windowsupdate/idownloadprogress.go
Normal file
86
agent/pkg/windowsupdate/idownloadprogress.go
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IDownloadProgress represents the progress of an asynchronous download operation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-idownloadprogress
|
||||
type IDownloadProgress struct {
|
||||
disp *ole.IDispatch
|
||||
CurrentUpdateBytesDownloaded int64
|
||||
CurrentUpdateBytesToDownload int64
|
||||
CurrentUpdateDownloadPhase int32 // DownloadPhase enum
|
||||
CurrentUpdateIndex int32
|
||||
CurrentUpdatePercentComplete int32
|
||||
PercentComplete int32
|
||||
TotalBytesDownloaded int64
|
||||
TotalBytesToDownload int64
|
||||
}
|
||||
|
||||
func toIDownloadProgress(disp *ole.IDispatch) (*IDownloadProgress, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
p := &IDownloadProgress{disp: disp}
|
||||
|
||||
if p.CurrentUpdateBytesDownloaded, err = toInt64Err(oleutil.GetProperty(disp, "CurrentUpdateBytesDownloaded")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.CurrentUpdateBytesToDownload, err = toInt64Err(oleutil.GetProperty(disp, "CurrentUpdateBytesToDownload")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.CurrentUpdateDownloadPhase, err = toInt32Err(oleutil.GetProperty(disp, "CurrentUpdateDownloadPhase")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.CurrentUpdateIndex, err = toInt32Err(oleutil.GetProperty(disp, "CurrentUpdateIndex")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.CurrentUpdatePercentComplete, err = toInt32Err(oleutil.GetProperty(disp, "CurrentUpdatePercentComplete")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.PercentComplete, err = toInt32Err(oleutil.GetProperty(disp, "PercentComplete")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.TotalBytesDownloaded, err = toInt64Err(oleutil.GetProperty(disp, "TotalBytesDownloaded")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.TotalBytesToDownload, err = toInt64Err(oleutil.GetProperty(disp, "TotalBytesToDownload")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// GetUpdateResult returns the result of the download for a specified update.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-idownloadprogress-getupdateresult
|
||||
func (p *IDownloadProgress) GetUpdateResult(updateIndex int32) (*IUpdateDownloadResult, error) {
|
||||
resultDisp, err := toIDispatchErr(oleutil.CallMethod(p.disp, "GetUpdateResult", updateIndex))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateDownloadResult(resultDisp)
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ package windowsupdate
|
|||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IImageInformation contains information about a localized image that is associated with an update or a category.
|
||||
|
|
@ -28,6 +29,26 @@ type IImageInformation struct {
|
|||
}
|
||||
|
||||
func toIImageInformation(imageInformationDisp *ole.IDispatch) (*IImageInformation, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
var err error
|
||||
iImageInformation := &IImageInformation{
|
||||
disp: imageInformationDisp,
|
||||
}
|
||||
|
||||
if iImageInformation.AltText, err = toStringErr(oleutil.GetProperty(imageInformationDisp, "AltText")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iImageInformation.Height, err = toInt64Err(oleutil.GetProperty(imageInformationDisp, "Height")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iImageInformation.Source, err = toStringErr(oleutil.GetProperty(imageInformationDisp, "Source")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iImageInformation.Width, err = toInt64Err(oleutil.GetProperty(imageInformationDisp, "Width")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iImageInformation, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ package windowsupdate
|
|||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IInstallationBehavior represents the installation and uninstallation options of an update.
|
||||
|
|
@ -28,6 +29,26 @@ type IInstallationBehavior struct {
|
|||
}
|
||||
|
||||
func toIInstallationBehavior(installationBehaviorDisp *ole.IDispatch) (*IInstallationBehavior, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
var err error
|
||||
iInstallationBehavior := &IInstallationBehavior{
|
||||
disp: installationBehaviorDisp,
|
||||
}
|
||||
|
||||
if iInstallationBehavior.CanRequestUserInput, err = toBoolErr(oleutil.GetProperty(installationBehaviorDisp, "CanRequestUserInput")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iInstallationBehavior.Impact, err = toInt32Err(oleutil.GetProperty(installationBehaviorDisp, "Impact")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iInstallationBehavior.RebootBehavior, err = toInt32Err(oleutil.GetProperty(installationBehaviorDisp, "RebootBehavior")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iInstallationBehavior.RequiresNetworkConnectivity, err = toBoolErr(oleutil.GetProperty(installationBehaviorDisp, "RequiresNetworkConnectivity")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iInstallationBehavior, nil
|
||||
}
|
||||
|
|
|
|||
77
agent/pkg/windowsupdate/iinstallationjob.go
Normal file
77
agent/pkg/windowsupdate/iinstallationjob.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IInstallationJob contains properties and methods that are available to an installation operation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iinstallationjob
|
||||
type IInstallationJob struct {
|
||||
disp *ole.IDispatch
|
||||
AsyncState interface{}
|
||||
IsCompleted bool
|
||||
Updates []*IUpdate
|
||||
}
|
||||
|
||||
func toIInstallationJob(disp *ole.IDispatch) (*IInstallationJob, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
j := &IInstallationJob{disp: disp}
|
||||
|
||||
if j.IsCompleted, err = toBoolErr(oleutil.GetProperty(disp, "IsCompleted")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatesDisp, err := toIDispatchErr(oleutil.GetProperty(disp, "Updates"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if updatesDisp != nil {
|
||||
if j.Updates, err = toIUpdates(updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return j, nil
|
||||
}
|
||||
|
||||
// CleanUp releases the resources held by the installation job.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iinstallationjob-cleanup
|
||||
func (j *IInstallationJob) CleanUp() error {
|
||||
_, err := oleutil.CallMethod(j.disp, "CleanUp")
|
||||
return err
|
||||
}
|
||||
|
||||
// RequestAbort requests that the installation job be canceled.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iinstallationjob-requestabort
|
||||
func (j *IInstallationJob) RequestAbort() error {
|
||||
_, err := oleutil.CallMethod(j.disp, "RequestAbort")
|
||||
return err
|
||||
}
|
||||
|
||||
// GetProgress returns the current progress of the installation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iinstallationjob-getprogress
|
||||
func (j *IInstallationJob) GetProgress() (*IInstallationProgress, error) {
|
||||
progressDisp, err := toIDispatchErr(oleutil.CallMethod(j.disp, "GetProgress"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIInstallationProgress(progressDisp)
|
||||
}
|
||||
61
agent/pkg/windowsupdate/iinstallationprogress.go
Normal file
61
agent/pkg/windowsupdate/iinstallationprogress.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IInstallationProgress represents the progress of an asynchronous installation operation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iinstallationprogress
|
||||
type IInstallationProgress struct {
|
||||
disp *ole.IDispatch
|
||||
CurrentUpdateIndex int32
|
||||
CurrentUpdatePercentComplete int32
|
||||
PercentComplete int32
|
||||
}
|
||||
|
||||
func toIInstallationProgress(disp *ole.IDispatch) (*IInstallationProgress, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
p := &IInstallationProgress{disp: disp}
|
||||
|
||||
if p.CurrentUpdateIndex, err = toInt32Err(oleutil.GetProperty(disp, "CurrentUpdateIndex")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.CurrentUpdatePercentComplete, err = toInt32Err(oleutil.GetProperty(disp, "CurrentUpdatePercentComplete")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.PercentComplete, err = toInt32Err(oleutil.GetProperty(disp, "PercentComplete")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// GetUpdateResult returns the result of the installation for a specified update.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iinstallationprogress-getupdateresult
|
||||
func (p *IInstallationProgress) GetUpdateResult(updateIndex int32) (*IUpdateInstallationResult, error) {
|
||||
resultDisp, err := toIDispatchErr(oleutil.CallMethod(p.disp, "GetUpdateResult", updateIndex))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateInstallationResult(resultDisp)
|
||||
}
|
||||
56
agent/pkg/windowsupdate/isearchjob.go
Normal file
56
agent/pkg/windowsupdate/isearchjob.go
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// ISearchJob contains properties and methods that are available to a search operation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-isearchjob
|
||||
type ISearchJob struct {
|
||||
disp *ole.IDispatch
|
||||
AsyncState interface{}
|
||||
IsCompleted bool
|
||||
}
|
||||
|
||||
func toISearchJob(disp *ole.IDispatch) (*ISearchJob, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
j := &ISearchJob{disp: disp}
|
||||
|
||||
if j.IsCompleted, err = toBoolErr(oleutil.GetProperty(disp, "IsCompleted")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return j, nil
|
||||
}
|
||||
|
||||
// CleanUp releases the resources held by the search job.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-isearchjob-cleanup
|
||||
func (j *ISearchJob) CleanUp() error {
|
||||
_, err := oleutil.CallMethod(j.disp, "CleanUp")
|
||||
return err
|
||||
}
|
||||
|
||||
// RequestAbort requests that the search job be canceled.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-isearchjob-requestabort
|
||||
func (j *ISearchJob) RequestAbort() error {
|
||||
_, err := oleutil.CallMethod(j.disp, "RequestAbort")
|
||||
return err
|
||||
}
|
||||
|
|
@ -1,3 +1,16 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
|
|
@ -5,7 +18,104 @@ import (
|
|||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-istringcollection
|
||||
// IStringCollection represents a collection of strings.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-istringcollection
|
||||
type IStringCollection struct {
|
||||
disp *ole.IDispatch
|
||||
Count int32
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
// NewStringCollection creates a new empty IStringCollection.
|
||||
func NewStringCollection() (*IStringCollection, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.StringColl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disp, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toIStringCollection(disp)
|
||||
}
|
||||
|
||||
func toIStringCollection(disp *ole.IDispatch) (*IStringCollection, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
sc := &IStringCollection{disp: disp}
|
||||
|
||||
if sc.Count, err = toInt32Err(oleutil.GetProperty(disp, "Count")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sc.ReadOnly, err = toBoolErr(oleutil.GetProperty(disp, "ReadOnly")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
// Item gets a string from the collection at the specified index.
|
||||
func (sc *IStringCollection) Item(index int32) (string, error) {
|
||||
return toStringErr(oleutil.GetProperty(sc.disp, "Item", index))
|
||||
}
|
||||
|
||||
// Add adds a string to the collection.
|
||||
func (sc *IStringCollection) Add(value string) (int32, error) {
|
||||
result, err := oleutil.CallMethod(sc.disp, "Add", value)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sc.Count++
|
||||
return variantToInt32(result), nil
|
||||
}
|
||||
|
||||
// Clear removes all items from the collection.
|
||||
func (sc *IStringCollection) Clear() error {
|
||||
_, err := oleutil.CallMethod(sc.disp, "Clear")
|
||||
if err == nil {
|
||||
sc.Count = 0
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Insert inserts a string at the specified position.
|
||||
func (sc *IStringCollection) Insert(index int32, value string) error {
|
||||
_, err := oleutil.CallMethod(sc.disp, "Insert", index, value)
|
||||
if err == nil {
|
||||
sc.Count++
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveAt removes the item at the specified index.
|
||||
func (sc *IStringCollection) RemoveAt(index int32) error {
|
||||
_, err := oleutil.CallMethod(sc.disp, "RemoveAt", index)
|
||||
if err == nil {
|
||||
sc.Count--
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ToSlice converts the collection to a Go string slice.
|
||||
func (sc *IStringCollection) ToSlice() ([]string, error) {
|
||||
result := make([]string, sc.Count)
|
||||
for i := int32(0); i < sc.Count; i++ {
|
||||
str, err := sc.Item(i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[i] = str
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// iStringCollectionToStringArrayErr is a helper function for backward compatibility.
|
||||
func iStringCollectionToStringArrayErr(disp *ole.IDispatch, err error) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
59
agent/pkg/windowsupdate/isysteminformation.go
Normal file
59
agent/pkg/windowsupdate/isysteminformation.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// ISystemInformation contains information about the specified computer.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-isysteminformation
|
||||
type ISystemInformation struct {
|
||||
disp *ole.IDispatch
|
||||
OemHardwareSupportLink string
|
||||
RebootRequired bool
|
||||
}
|
||||
|
||||
// NewSystemInformation creates a new ISystemInformation instance.
|
||||
func NewSystemInformation() (*ISystemInformation, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.SystemInfo")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disp, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toISystemInformation(disp)
|
||||
}
|
||||
|
||||
func toISystemInformation(systemInfoDisp *ole.IDispatch) (*ISystemInformation, error) {
|
||||
var err error
|
||||
iSystemInformation := &ISystemInformation{
|
||||
disp: systemInfoDisp,
|
||||
}
|
||||
|
||||
if iSystemInformation.OemHardwareSupportLink, err = toStringErr(oleutil.GetProperty(systemInfoDisp, "OemHardwareSupportLink")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iSystemInformation.RebootRequired, err = toBoolErr(oleutil.GetProperty(systemInfoDisp, "RebootRequired")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iSystemInformation, nil
|
||||
}
|
||||
|
|
@ -65,6 +65,17 @@ type IUpdate struct {
|
|||
UninstallationBehavior *IInstallationBehavior
|
||||
UninstallationNotes string
|
||||
UninstallationSteps []string
|
||||
// IUpdate2 properties
|
||||
CveIDs []string // CVE IDs associated with the update
|
||||
IsPresent bool // Indicates if the update is present on the computer
|
||||
RebootRequired bool // Indicates if a reboot is required
|
||||
// IUpdate3 properties
|
||||
BrowseOnly bool // Indicates whether update can be discovered only by browsing
|
||||
// IUpdate4 properties
|
||||
PerUser bool // Indicates whether this is a per-user update
|
||||
// IUpdate5 properties
|
||||
AutoDownload int32 // AutoDownload setting
|
||||
AutoSelection int32 // AutoSelection setting
|
||||
}
|
||||
|
||||
func toIUpdates(updatesDisp *ole.IDispatch) ([]*IUpdate, error) {
|
||||
|
|
@ -334,6 +345,35 @@ func toIUpdate(updateDisp *ole.IDispatch) (*IUpdate, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// IUpdate2 properties (may fail on older systems)
|
||||
if cveIDs, err := iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateDisp, "CveIDs"))); err == nil {
|
||||
iUpdate.CveIDs = cveIDs
|
||||
}
|
||||
if isPresent, err := toBoolErr(oleutil.GetProperty(updateDisp, "IsPresent")); err == nil {
|
||||
iUpdate.IsPresent = isPresent
|
||||
}
|
||||
if rebootRequired, err := toBoolErr(oleutil.GetProperty(updateDisp, "RebootRequired")); err == nil {
|
||||
iUpdate.RebootRequired = rebootRequired
|
||||
}
|
||||
|
||||
// IUpdate3 properties
|
||||
if browseOnly, err := toBoolErr(oleutil.GetProperty(updateDisp, "BrowseOnly")); err == nil {
|
||||
iUpdate.BrowseOnly = browseOnly
|
||||
}
|
||||
|
||||
// IUpdate4 properties
|
||||
if perUser, err := toBoolErr(oleutil.GetProperty(updateDisp, "PerUser")); err == nil {
|
||||
iUpdate.PerUser = perUser
|
||||
}
|
||||
|
||||
// IUpdate5 properties
|
||||
if autoDownload, err := toInt32Err(oleutil.GetProperty(updateDisp, "AutoDownload")); err == nil {
|
||||
iUpdate.AutoDownload = autoDownload
|
||||
}
|
||||
if autoSelection, err := toInt32Err(oleutil.GetProperty(updateDisp, "AutoSelection")); err == nil {
|
||||
iUpdate.AutoSelection = autoSelection
|
||||
}
|
||||
|
||||
return iUpdate, nil
|
||||
}
|
||||
|
||||
|
|
@ -361,3 +401,15 @@ func (iUpdate *IUpdate) AcceptEula() error {
|
|||
_, err := oleutil.CallMethod(iUpdate.disp, "AcceptEula")
|
||||
return err
|
||||
}
|
||||
|
||||
// CopyToCache copies the contents of an update to the Windows Update Agent (WUA) cache. (IUpdate2)
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdate2-copytocache
|
||||
func (iUpdate *IUpdate) CopyToCache(files *IStringCollection) error {
|
||||
_, err := oleutil.CallMethod(iUpdate.disp, "CopyToCache", files.disp)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetDispatch returns the underlying IDispatch interface.
|
||||
func (iUpdate *IUpdate) GetDispatch() *ole.IDispatch {
|
||||
return iUpdate.disp
|
||||
}
|
||||
|
|
|
|||
134
agent/pkg/windowsupdate/iupdatecollection.go
Normal file
134
agent/pkg/windowsupdate/iupdatecollection.go
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateCollection represents a collection of updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatecollection
|
||||
type IUpdateCollection struct {
|
||||
disp *ole.IDispatch
|
||||
Count int32
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
// NewUpdateCollection creates a new empty IUpdateCollection.
|
||||
func NewUpdateCollection() (*IUpdateCollection, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.UpdateColl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disp, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toIUpdateCollection2(disp)
|
||||
}
|
||||
|
||||
func toIUpdateCollection2(disp *ole.IDispatch) (*IUpdateCollection, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
uc := &IUpdateCollection{disp: disp}
|
||||
|
||||
if uc.Count, err = toInt32Err(oleutil.GetProperty(disp, "Count")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if uc.ReadOnly, err = toBoolErr(oleutil.GetProperty(disp, "ReadOnly")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return uc, nil
|
||||
}
|
||||
|
||||
// Item gets an update from the collection at the specified index.
|
||||
func (uc *IUpdateCollection) Item(index int32) (*IUpdate, error) {
|
||||
itemDisp, err := toIDispatchErr(oleutil.GetProperty(uc.disp, "Item", index))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdate(itemDisp)
|
||||
}
|
||||
|
||||
// Add adds an update to the collection.
|
||||
func (uc *IUpdateCollection) Add(update *IUpdate) (int32, error) {
|
||||
result, err := oleutil.CallMethod(uc.disp, "Add", update.disp)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
uc.Count++
|
||||
return variantToInt32(result), nil
|
||||
}
|
||||
|
||||
// Clear removes all items from the collection.
|
||||
func (uc *IUpdateCollection) Clear() error {
|
||||
_, err := oleutil.CallMethod(uc.disp, "Clear")
|
||||
if err == nil {
|
||||
uc.Count = 0
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy creates a shallow copy of the collection.
|
||||
func (uc *IUpdateCollection) Copy() (*IUpdateCollection, error) {
|
||||
copyDisp, err := toIDispatchErr(oleutil.CallMethod(uc.disp, "Copy"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateCollection2(copyDisp)
|
||||
}
|
||||
|
||||
// Insert inserts an update at the specified position.
|
||||
func (uc *IUpdateCollection) Insert(index int32, update *IUpdate) error {
|
||||
_, err := oleutil.CallMethod(uc.disp, "Insert", index, update.disp)
|
||||
if err == nil {
|
||||
uc.Count++
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveAt removes the item at the specified index.
|
||||
func (uc *IUpdateCollection) RemoveAt(index int32) error {
|
||||
_, err := oleutil.CallMethod(uc.disp, "RemoveAt", index)
|
||||
if err == nil {
|
||||
uc.Count--
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ToSlice converts the collection to a Go slice.
|
||||
func (uc *IUpdateCollection) ToSlice() ([]*IUpdate, error) {
|
||||
result := make([]*IUpdate, uc.Count)
|
||||
for i := int32(0); i < uc.Count; i++ {
|
||||
update, err := uc.Item(i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[i] = update
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetDispatch returns the underlying IDispatch for use with other WUA methods.
|
||||
func (uc *IUpdateCollection) GetDispatch() *ole.IDispatch {
|
||||
return uc.disp
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ package windowsupdate
|
|||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateDownloadContent represents the download content of an update.
|
||||
|
|
@ -25,6 +26,37 @@ type IUpdateDownloadContent struct {
|
|||
}
|
||||
|
||||
func toIUpdateDownloadContents(updateDownloadContentsDisp *ole.IDispatch) ([]*IUpdateDownloadContent, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
count, err := toInt32Err(oleutil.GetProperty(updateDownloadContentsDisp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contents := make([]*IUpdateDownloadContent, 0, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
contentDisp, err := toIDispatchErr(oleutil.GetProperty(updateDownloadContentsDisp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
content, err := toIUpdateDownloadContent(contentDisp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contents = append(contents, content)
|
||||
}
|
||||
return contents, nil
|
||||
}
|
||||
|
||||
func toIUpdateDownloadContent(updateDownloadContentDisp *ole.IDispatch) (*IUpdateDownloadContent, error) {
|
||||
var err error
|
||||
iUpdateDownloadContent := &IUpdateDownloadContent{
|
||||
disp: updateDownloadContentDisp,
|
||||
}
|
||||
|
||||
if iUpdateDownloadContent.DownloadUrl, err = toStringErr(oleutil.GetProperty(updateDownloadContentDisp, "DownloadUrl")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iUpdateDownloadContent, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,3 +76,61 @@ func (iUpdateDownloader *IUpdateDownloader) Download(updates []*IUpdate) (*IDown
|
|||
}
|
||||
return toIDownloadResult(downloadResultDisp)
|
||||
}
|
||||
|
||||
// BeginDownload begins an asynchronous download of the content files associated with the updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatedownloader-begindownload
|
||||
func (iUpdateDownloader *IUpdateDownloader) BeginDownload(updates []*IUpdate) (*IDownloadJob, error) {
|
||||
updatesDisp, err := toIUpdateCollection(updates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = oleutil.PutProperty(iUpdateDownloader.disp, "Updates", updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jobDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateDownloader.disp, "BeginDownload", nil, nil, nil))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIDownloadJob(jobDisp)
|
||||
}
|
||||
|
||||
// EndDownload completes an asynchronous download.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatedownloader-enddownload
|
||||
func (iUpdateDownloader *IUpdateDownloader) EndDownload(downloadJob *IDownloadJob) (*IDownloadResult, error) {
|
||||
resultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateDownloader.disp, "EndDownload", downloadJob.disp))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIDownloadResult(resultDisp)
|
||||
}
|
||||
|
||||
// PutClientApplicationID sets the identifier of the current client application.
|
||||
func (iUpdateDownloader *IUpdateDownloader) PutClientApplicationID(value string) error {
|
||||
_, err := oleutil.PutProperty(iUpdateDownloader.disp, "ClientApplicationID", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateDownloader.ClientApplicationID = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutIsForced sets whether the download is forced.
|
||||
func (iUpdateDownloader *IUpdateDownloader) PutIsForced(value bool) error {
|
||||
_, err := oleutil.PutProperty(iUpdateDownloader.disp, "IsForced", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateDownloader.IsForced = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutPriority sets the download priority.
|
||||
func (iUpdateDownloader *IUpdateDownloader) PutPriority(value int32) error {
|
||||
_, err := oleutil.PutProperty(iUpdateDownloader.disp, "Priority", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateDownloader.Priority = value
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ package windowsupdate
|
|||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateDownloadResult contains the properties that indicate the status of a download operation for an update.
|
||||
|
|
@ -26,6 +27,18 @@ type IUpdateDownloadResult struct {
|
|||
}
|
||||
|
||||
func toIUpdateDownloadResult(iUpdateDownloadResultDisp *ole.IDispatch) (*IUpdateDownloadResult, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
var err error
|
||||
iUpdateDownloadResult := &IUpdateDownloadResult{
|
||||
disp: iUpdateDownloadResultDisp,
|
||||
}
|
||||
|
||||
if iUpdateDownloadResult.HResult, err = toInt32Err(oleutil.GetProperty(iUpdateDownloadResultDisp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateDownloadResult.ResultCode, err = toInt32Err(oleutil.GetProperty(iUpdateDownloadResultDisp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iUpdateDownloadResult, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ package windowsupdate
|
|||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateException represents info about the aspects of search results returned in the ISearchResult object that were incomplete. For more info, see Remarks.
|
||||
|
|
@ -27,6 +28,45 @@ type IUpdateException struct {
|
|||
}
|
||||
|
||||
func toIUpdateExceptions(updateExceptionsDisp *ole.IDispatch) ([]*IUpdateException, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
count, err := toInt32Err(oleutil.GetProperty(updateExceptionsDisp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exceptions := make([]*IUpdateException, 0, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
exceptionDisp, err := toIDispatchErr(oleutil.GetProperty(updateExceptionsDisp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exception, err := toIUpdateException(exceptionDisp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exceptions = append(exceptions, exception)
|
||||
}
|
||||
return exceptions, nil
|
||||
}
|
||||
|
||||
func toIUpdateException(updateExceptionDisp *ole.IDispatch) (*IUpdateException, error) {
|
||||
var err error
|
||||
iUpdateException := &IUpdateException{
|
||||
disp: updateExceptionDisp,
|
||||
}
|
||||
|
||||
if iUpdateException.Context, err = toInt32Err(oleutil.GetProperty(updateExceptionDisp, "Context")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateException.HResult, err = toInt64Err(oleutil.GetProperty(updateExceptionDisp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateException.Message, err = toStringErr(oleutil.GetProperty(updateExceptionDisp, "Message")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iUpdateException, nil
|
||||
}
|
||||
|
|
|
|||
51
agent/pkg/windowsupdate/iupdateinstallationresult.go
Normal file
51
agent/pkg/windowsupdate/iupdateinstallationresult.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateInstallationResult represents the result of an installation or uninstallation for an update.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdateinstallationresult
|
||||
type IUpdateInstallationResult struct {
|
||||
disp *ole.IDispatch
|
||||
HResult int32
|
||||
RebootRequired bool
|
||||
ResultCode int32 // OperationResultCode enum
|
||||
}
|
||||
|
||||
func toIUpdateInstallationResult(disp *ole.IDispatch) (*IUpdateInstallationResult, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
r := &IUpdateInstallationResult{disp: disp}
|
||||
|
||||
if r.HResult, err = toInt32Err(oleutil.GetProperty(disp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r.RebootRequired, err = toBoolErr(oleutil.GetProperty(disp, "RebootRequired")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r.ResultCode, err = toInt32Err(oleutil.GetProperty(disp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ func toIUpdateInstaller(updateInstallerDisp *ole.IDispatch) (*IUpdateInstaller,
|
|||
if iUpdateInstaller.ForceQuiet, err = toBoolErr(oleutil.GetProperty(updateInstallerDisp, "ForceQuiet")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
if iUpdateInstaller.RebootRequiredBeforeInstallation, err = toBoolErr(oleutil.GetProperty(updateInstallerDisp, "RebootRequiredBeforeInstallation")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -125,3 +125,97 @@ func (iUpdateInstaller *IUpdateInstaller) PutIsForced(value bool) error {
|
|||
iUpdateInstaller.IsForced = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// Uninstall starts a synchronous uninstallation of the updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller-uninstall
|
||||
func (iUpdateInstaller *IUpdateInstaller) Uninstall(updates []*IUpdate) (*IInstallationResult, error) {
|
||||
updatesDisp, err := toIUpdateCollection(updates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = oleutil.PutProperty(iUpdateInstaller.disp, "Updates", updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uninstallationResultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateInstaller.disp, "Uninstall"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIInstallationResult(uninstallationResultDisp)
|
||||
}
|
||||
|
||||
// BeginInstall begins an asynchronous installation of the updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller-begininstall
|
||||
func (iUpdateInstaller *IUpdateInstaller) BeginInstall(updates []*IUpdate) (*IInstallationJob, error) {
|
||||
updatesDisp, err := toIUpdateCollection(updates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = oleutil.PutProperty(iUpdateInstaller.disp, "Updates", updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jobDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateInstaller.disp, "BeginInstall", nil, nil, nil))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIInstallationJob(jobDisp)
|
||||
}
|
||||
|
||||
// EndInstall completes an asynchronous installation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller-endinstall
|
||||
func (iUpdateInstaller *IUpdateInstaller) EndInstall(installationJob *IInstallationJob) (*IInstallationResult, error) {
|
||||
resultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateInstaller.disp, "EndInstall", installationJob.disp))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIInstallationResult(resultDisp)
|
||||
}
|
||||
|
||||
// BeginUninstall begins an asynchronous uninstallation of the updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller-beginuninstall
|
||||
func (iUpdateInstaller *IUpdateInstaller) BeginUninstall(updates []*IUpdate) (*IInstallationJob, error) {
|
||||
updatesDisp, err := toIUpdateCollection(updates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = oleutil.PutProperty(iUpdateInstaller.disp, "Updates", updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jobDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateInstaller.disp, "BeginUninstall", nil, nil, nil))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIInstallationJob(jobDisp)
|
||||
}
|
||||
|
||||
// EndUninstall completes an asynchronous uninstallation.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller-enduninstall
|
||||
func (iUpdateInstaller *IUpdateInstaller) EndUninstall(installationJob *IInstallationJob) (*IInstallationResult, error) {
|
||||
resultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateInstaller.disp, "EndUninstall", installationJob.disp))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIInstallationResult(resultDisp)
|
||||
}
|
||||
|
||||
// PutAllowSourcePrompts sets whether prompts are allowed during installation.
|
||||
func (iUpdateInstaller *IUpdateInstaller) PutAllowSourcePrompts(value bool) error {
|
||||
_, err := oleutil.PutProperty(iUpdateInstaller.disp, "AllowSourcePrompts", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateInstaller.AllowSourcePrompts = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutClientApplicationID sets the identifier of the current client application.
|
||||
func (iUpdateInstaller *IUpdateInstaller) PutClientApplicationID(value string) error {
|
||||
_, err := oleutil.PutProperty(iUpdateInstaller.disp, "ClientApplicationID", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateInstaller.ClientApplicationID = value
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ func (iUpdateSearcher *IUpdateSearcher) QueryHistory(startIndex int32, count int
|
|||
// GetTotalHistoryCount returns the number of update events on the computer.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-gettotalhistorycount
|
||||
func (iUpdateSearcher *IUpdateSearcher) GetTotalHistoryCount() (int32, error) {
|
||||
// According to MSDN, this is a method with an [out, retval] parameter
|
||||
// In COM automation through IDispatch, such methods return the value directly
|
||||
return toInt32Err(oleutil.CallMethod(iUpdateSearcher.disp, "GetTotalHistoryCount"))
|
||||
}
|
||||
|
||||
|
|
@ -97,3 +99,79 @@ func (iUpdateSearcher *IUpdateSearcher) QueryHistoryAll() ([]*IUpdateHistoryEntr
|
|||
}
|
||||
return iUpdateSearcher.QueryHistory(0, count)
|
||||
}
|
||||
|
||||
// BeginSearch begins an asynchronous search for updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-beginsearch
|
||||
func (iUpdateSearcher *IUpdateSearcher) BeginSearch(criteria string) (*ISearchJob, error) {
|
||||
jobDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateSearcher.disp, "BeginSearch", criteria, nil, nil))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toISearchJob(jobDisp)
|
||||
}
|
||||
|
||||
// EndSearch completes an asynchronous search.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-endsearch
|
||||
func (iUpdateSearcher *IUpdateSearcher) EndSearch(searchJob *ISearchJob) (*ISearchResult, error) {
|
||||
resultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateSearcher.disp, "EndSearch", searchJob.disp))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toISearchResult(resultDisp)
|
||||
}
|
||||
|
||||
// EscapeString converts a string into a string that can be used as a literal value in a search criteria string.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-escapestring
|
||||
func (iUpdateSearcher *IUpdateSearcher) EscapeString(unescaped string) (string, error) {
|
||||
return toStringErr(oleutil.CallMethod(iUpdateSearcher.disp, "EscapeString", unescaped))
|
||||
}
|
||||
|
||||
// PutClientApplicationID sets the identifier of the current client application.
|
||||
func (iUpdateSearcher *IUpdateSearcher) PutClientApplicationID(value string) error {
|
||||
_, err := oleutil.PutProperty(iUpdateSearcher.disp, "ClientApplicationID", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateSearcher.ClientApplicationID = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutServerSelection sets the server to search.
|
||||
func (iUpdateSearcher *IUpdateSearcher) PutServerSelection(value int32) error {
|
||||
_, err := oleutil.PutProperty(iUpdateSearcher.disp, "ServerSelection", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateSearcher.ServerSelection = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutServiceID sets the ServiceID to search.
|
||||
func (iUpdateSearcher *IUpdateSearcher) PutServiceID(value string) error {
|
||||
_, err := oleutil.PutProperty(iUpdateSearcher.disp, "ServiceID", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateSearcher.ServiceID = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutOnline sets whether to search online.
|
||||
func (iUpdateSearcher *IUpdateSearcher) PutOnline(value bool) error {
|
||||
_, err := oleutil.PutProperty(iUpdateSearcher.disp, "Online", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateSearcher.Online = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutIncludePotentiallySupersededUpdates sets whether to include potentially superseded updates.
|
||||
func (iUpdateSearcher *IUpdateSearcher) PutIncludePotentiallySupersededUpdates(value bool) error {
|
||||
_, err := oleutil.PutProperty(iUpdateSearcher.disp, "IncludePotentiallySupersededUpdates", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateSearcher.IncludePotentiallySupersededUpdates = value
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
133
agent/pkg/windowsupdate/iupdateservice.go
Normal file
133
agent/pkg/windowsupdate/iupdateservice.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateService contains information about a service that is registered with Windows Update Agent (WUA).
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdateservice
|
||||
type IUpdateService struct {
|
||||
disp *ole.IDispatch
|
||||
CanRegisterWithAU bool
|
||||
ContentValidationCert []byte
|
||||
ExpirationDate *time.Time
|
||||
IsManaged bool
|
||||
IsRegisteredWithAU bool
|
||||
IsScanPackageService bool
|
||||
IssueDate *time.Time
|
||||
Name string
|
||||
OffersWindowsUpdates bool
|
||||
RedirectUrls []string
|
||||
ServiceID string
|
||||
ServiceUrl string
|
||||
SetupPrefix string
|
||||
// IUpdateService2 properties
|
||||
IsDefaultAUService bool
|
||||
}
|
||||
|
||||
func toIUpdateService(disp *ole.IDispatch) (*IUpdateService, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
s := &IUpdateService{disp: disp}
|
||||
|
||||
if s.CanRegisterWithAU, err = toBoolErr(oleutil.GetProperty(disp, "CanRegisterWithAU")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.IsManaged, err = toBoolErr(oleutil.GetProperty(disp, "IsManaged")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.IsRegisteredWithAU, err = toBoolErr(oleutil.GetProperty(disp, "IsRegisteredWithAU")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.IsScanPackageService, err = toBoolErr(oleutil.GetProperty(disp, "IsScanPackageService")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.IssueDate, err = toTimeErr(oleutil.GetProperty(disp, "IssueDate")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.ExpirationDate, err = toTimeErr(oleutil.GetProperty(disp, "ExpirationDate")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.Name, err = toStringErr(oleutil.GetProperty(disp, "Name")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.OffersWindowsUpdates, err = toBoolErr(oleutil.GetProperty(disp, "OffersWindowsUpdates")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.RedirectUrls, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(disp, "RedirectUrls"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.ServiceID, err = toStringErr(oleutil.GetProperty(disp, "ServiceID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.ServiceUrl, err = toStringErr(oleutil.GetProperty(disp, "ServiceUrl")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if s.SetupPrefix, err = toStringErr(oleutil.GetProperty(disp, "SetupPrefix")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// IUpdateService2 property
|
||||
if isDefault, err := toBoolErr(oleutil.GetProperty(disp, "IsDefaultAUService")); err == nil {
|
||||
s.IsDefaultAUService = isDefault
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func toIUpdateServices(disp *ole.IDispatch) ([]*IUpdateService, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
count, err := toInt32Err(oleutil.GetProperty(disp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
services := make([]*IUpdateService, 0, count)
|
||||
for i := int32(0); i < count; i++ {
|
||||
serviceDisp, err := toIDispatchErr(oleutil.GetProperty(disp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
service, err := toIUpdateService(serviceDisp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
services = append(services, service)
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
141
agent/pkg/windowsupdate/iupdateservicemanager.go
Normal file
141
agent/pkg/windowsupdate/iupdateservicemanager.go
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateServiceManager adds or removes the registration of an update service with Windows Update Agent.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdateservicemanager
|
||||
type IUpdateServiceManager struct {
|
||||
disp *ole.IDispatch
|
||||
Services []*IUpdateService
|
||||
// IUpdateServiceManager2 properties
|
||||
ClientApplicationID string
|
||||
}
|
||||
|
||||
// NewUpdateServiceManager creates a new IUpdateServiceManager instance.
|
||||
func NewUpdateServiceManager() (*IUpdateServiceManager, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.ServiceManager")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disp, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toIUpdateServiceManager(disp)
|
||||
}
|
||||
|
||||
func toIUpdateServiceManager(disp *ole.IDispatch) (*IUpdateServiceManager, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sm := &IUpdateServiceManager{disp: disp}
|
||||
|
||||
servicesDisp, err := toIDispatchErr(oleutil.GetProperty(disp, "Services"))
|
||||
if err == nil && servicesDisp != nil {
|
||||
services, err := toIUpdateServices(servicesDisp)
|
||||
if err == nil {
|
||||
sm.Services = services
|
||||
} else {
|
||||
// If we can't parse services, initialize to empty slice instead of nil
|
||||
sm.Services = make([]*IUpdateService, 0)
|
||||
}
|
||||
} else {
|
||||
// If Services property doesn't exist or fails, initialize to empty slice
|
||||
sm.Services = make([]*IUpdateService, 0)
|
||||
}
|
||||
|
||||
// IUpdateServiceManager2 property
|
||||
if clientAppID, err := toStringErr(oleutil.GetProperty(disp, "ClientApplicationID")); err == nil {
|
||||
sm.ClientApplicationID = clientAppID
|
||||
}
|
||||
|
||||
return sm, nil
|
||||
}
|
||||
|
||||
// AddService registers a service with Windows Update Agent (WUA).
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager-addservice
|
||||
func (sm *IUpdateServiceManager) AddService(serviceID string, authorizationCabPath string) (*IUpdateService, error) {
|
||||
serviceDisp, err := toIDispatchErr(oleutil.CallMethod(sm.disp, "AddService", serviceID, authorizationCabPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateService(serviceDisp)
|
||||
}
|
||||
|
||||
// RegisterServiceWithAU registers a service with Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager-registerservicewithau
|
||||
func (sm *IUpdateServiceManager) RegisterServiceWithAU(serviceID string) error {
|
||||
_, err := oleutil.CallMethod(sm.disp, "RegisterServiceWithAU", serviceID)
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveService removes a service registration from Windows Update Agent (WUA).
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager-removeservice
|
||||
func (sm *IUpdateServiceManager) RemoveService(serviceID string) error {
|
||||
_, err := oleutil.CallMethod(sm.disp, "RemoveService", serviceID)
|
||||
return err
|
||||
}
|
||||
|
||||
// UnregisterServiceWithAU unregisters a service with Automatic Updates.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager-unregisterservicewithau
|
||||
func (sm *IUpdateServiceManager) UnregisterServiceWithAU(serviceID string) error {
|
||||
_, err := oleutil.CallMethod(sm.disp, "UnregisterServiceWithAU", serviceID)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetOption sets options for the update service manager.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager-setoption
|
||||
func (sm *IUpdateServiceManager) SetOption(optionName string, optionValue interface{}) error {
|
||||
_, err := oleutil.CallMethod(sm.disp, "SetOption", optionName, optionValue)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddScanPackageService registers a scan package service.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager-addscanpackageservice
|
||||
func (sm *IUpdateServiceManager) AddScanPackageService(serviceName string, scanFileLocation string, flags int32) (*IUpdateService, error) {
|
||||
serviceDisp, err := toIDispatchErr(oleutil.CallMethod(sm.disp, "AddScanPackageService", serviceName, scanFileLocation, flags))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateService(serviceDisp)
|
||||
}
|
||||
|
||||
// PutClientApplicationID sets the identifier of the current client application. (IUpdateServiceManager2)
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager2-put_clientapplicationid
|
||||
func (sm *IUpdateServiceManager) PutClientApplicationID(value string) error {
|
||||
_, err := oleutil.PutProperty(sm.disp, "ClientApplicationID", value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sm.ClientApplicationID = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddService2 registers a service with Windows Update Agent (WUA). (IUpdateServiceManager2)
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateservicemanager2-addservice2
|
||||
func (sm *IUpdateServiceManager) AddService2(serviceID string, flags int32, authorizationCabPath string) (*IUpdateServiceRegistration, error) {
|
||||
regDisp, err := toIDispatchErr(oleutil.CallMethod(sm.disp, "AddService2", serviceID, flags, authorizationCabPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateServiceRegistration(regDisp)
|
||||
}
|
||||
57
agent/pkg/windowsupdate/iupdateserviceregistration.go
Normal file
57
agent/pkg/windowsupdate/iupdateserviceregistration.go
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IUpdateServiceRegistration represents the registration status of an update service.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdateserviceregistration
|
||||
type IUpdateServiceRegistration struct {
|
||||
disp *ole.IDispatch
|
||||
IsPendingRegistrationWithAU bool
|
||||
RegistrationState int32
|
||||
Service *IUpdateService
|
||||
}
|
||||
|
||||
func toIUpdateServiceRegistration(disp *ole.IDispatch) (*IUpdateServiceRegistration, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
reg := &IUpdateServiceRegistration{disp: disp}
|
||||
|
||||
if reg.IsPendingRegistrationWithAU, err = toBoolErr(oleutil.GetProperty(disp, "IsPendingRegistrationWithAU")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if reg.RegistrationState, err = toInt32Err(oleutil.GetProperty(disp, "RegistrationState")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serviceDisp, err := toIDispatchErr(oleutil.GetProperty(disp, "Service"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if serviceDisp != nil {
|
||||
if reg.Service, err = toIUpdateService(serviceDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return reg, nil
|
||||
}
|
||||
|
|
@ -15,12 +15,13 @@ package windowsupdate
|
|||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IWebProxy contains the HTTP proxy settings.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iwebproxy
|
||||
type IWebProxy struct {
|
||||
disp *ole.Dispatch
|
||||
disp *ole.IDispatch
|
||||
Address string
|
||||
AutoDetect bool
|
||||
BypassList []string
|
||||
|
|
@ -30,6 +31,40 @@ type IWebProxy struct {
|
|||
}
|
||||
|
||||
func toIWebProxy(webProxyDisp *ole.IDispatch) (*IWebProxy, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
var err error
|
||||
iWebProxy := &IWebProxy{
|
||||
disp: webProxyDisp,
|
||||
}
|
||||
|
||||
if iWebProxy.Address, err = toStringErr(oleutil.GetProperty(webProxyDisp, "Address")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iWebProxy.AutoDetect, err = toBoolErr(oleutil.GetProperty(webProxyDisp, "AutoDetect")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bypassListDisp, err := toIDispatchErr(oleutil.GetProperty(webProxyDisp, "BypassList"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bypassListDisp != nil {
|
||||
if iWebProxy.BypassList, err = iStringCollectionToStringArrayErr(bypassListDisp, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iWebProxy.BypassProxyOnLocal, err = toBoolErr(oleutil.GetProperty(webProxyDisp, "BypassProxyOnLocal")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iWebProxy.ReadOnly, err = toBoolErr(oleutil.GetProperty(webProxyDisp, "ReadOnly")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iWebProxy.UserName, err = toStringErr(oleutil.GetProperty(webProxyDisp, "UserName")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iWebProxy, nil
|
||||
}
|
||||
|
|
|
|||
178
agent/pkg/windowsupdate/iwindowsdriverupdate.go
Normal file
178
agent/pkg/windowsupdate/iwindowsdriverupdate.go
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IWindowsDriverUpdate contains the properties and methods available to an update that installs a Windows driver.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iwindowsdriverupdate
|
||||
type IWindowsDriverUpdate struct {
|
||||
*IUpdate
|
||||
DeviceProblemNumber int32
|
||||
DeviceStatus int32
|
||||
DriverClass string
|
||||
DriverHardwareID string
|
||||
DriverManufacturer string
|
||||
DriverModel string
|
||||
DriverProvider string
|
||||
DriverVerDate *time.Time
|
||||
// IWindowsDriverUpdate2 properties
|
||||
RebootRequired2 bool
|
||||
IsPresent2 bool
|
||||
// IWindowsDriverUpdate3 properties
|
||||
BrowseOnly2 bool
|
||||
// IWindowsDriverUpdate4 properties
|
||||
WindowsDriverUpdateEntries []*IWindowsDriverUpdateEntry
|
||||
// IWindowsDriverUpdate5 properties
|
||||
AutoDownload2 int32
|
||||
AutoSelection2 int32
|
||||
}
|
||||
|
||||
// ToWindowsDriverUpdate attempts to cast an IUpdate to IWindowsDriverUpdate.
|
||||
// Returns nil if the update is not a driver update.
|
||||
func (u *IUpdate) ToWindowsDriverUpdate() (*IWindowsDriverUpdate, error) {
|
||||
wdu := &IWindowsDriverUpdate{IUpdate: u}
|
||||
|
||||
var err error
|
||||
|
||||
// Try to get driver-specific properties
|
||||
if wdu.DeviceProblemNumber, err = toInt32Err(oleutil.GetProperty(u.disp, "DeviceProblemNumber")); err != nil {
|
||||
return nil, nil // Not a driver update
|
||||
}
|
||||
|
||||
if wdu.DeviceStatus, err = toInt32Err(oleutil.GetProperty(u.disp, "DeviceStatus")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if wdu.DriverClass, err = toStringErr(oleutil.GetProperty(u.disp, "DriverClass")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if wdu.DriverHardwareID, err = toStringErr(oleutil.GetProperty(u.disp, "DriverHardwareID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if wdu.DriverManufacturer, err = toStringErr(oleutil.GetProperty(u.disp, "DriverManufacturer")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if wdu.DriverModel, err = toStringErr(oleutil.GetProperty(u.disp, "DriverModel")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if wdu.DriverProvider, err = toStringErr(oleutil.GetProperty(u.disp, "DriverProvider")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if wdu.DriverVerDate, err = toTimeErr(oleutil.GetProperty(u.disp, "DriverVerDate")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// IWindowsDriverUpdate4 - WindowsDriverUpdateEntries
|
||||
entriesDisp, err := toIDispatchErr(oleutil.GetProperty(u.disp, "WindowsDriverUpdateEntries"))
|
||||
if err == nil && entriesDisp != nil {
|
||||
wdu.WindowsDriverUpdateEntries, _ = toIWindowsDriverUpdateEntries(entriesDisp)
|
||||
}
|
||||
|
||||
return wdu, nil
|
||||
}
|
||||
|
||||
// IWindowsDriverUpdateEntry contains the properties that are available to a Windows driver update entry.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iwindowsdriverupdateentry
|
||||
type IWindowsDriverUpdateEntry struct {
|
||||
disp *ole.IDispatch
|
||||
DeviceProblemNumber int32
|
||||
DeviceStatus int32
|
||||
DriverClass string
|
||||
DriverHardwareID string
|
||||
DriverManufacturer string
|
||||
DriverModel string
|
||||
DriverProvider string
|
||||
DriverVerDate *time.Time
|
||||
}
|
||||
|
||||
func toIWindowsDriverUpdateEntry(disp *ole.IDispatch) (*IWindowsDriverUpdateEntry, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
entry := &IWindowsDriverUpdateEntry{disp: disp}
|
||||
|
||||
if entry.DeviceProblemNumber, err = toInt32Err(oleutil.GetProperty(disp, "DeviceProblemNumber")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entry.DeviceStatus, err = toInt32Err(oleutil.GetProperty(disp, "DeviceStatus")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entry.DriverClass, err = toStringErr(oleutil.GetProperty(disp, "DriverClass")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entry.DriverHardwareID, err = toStringErr(oleutil.GetProperty(disp, "DriverHardwareID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entry.DriverManufacturer, err = toStringErr(oleutil.GetProperty(disp, "DriverManufacturer")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entry.DriverModel, err = toStringErr(oleutil.GetProperty(disp, "DriverModel")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entry.DriverProvider, err = toStringErr(oleutil.GetProperty(disp, "DriverProvider")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entry.DriverVerDate, err = toTimeErr(oleutil.GetProperty(disp, "DriverVerDate")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
func toIWindowsDriverUpdateEntries(disp *ole.IDispatch) ([]*IWindowsDriverUpdateEntry, error) {
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
count, err := toInt32Err(oleutil.GetProperty(disp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries := make([]*IWindowsDriverUpdateEntry, 0, count)
|
||||
for i := int32(0); i < count; i++ {
|
||||
entryDisp, err := toIDispatchErr(oleutil.GetProperty(disp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entry, err := toIWindowsDriverUpdateEntry(entryDisp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
101
agent/pkg/windowsupdate/iwindowsupdateagentinfo.go
Normal file
101
agent/pkg/windowsupdate/iwindowsupdateagentinfo.go
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Copyright 2022 Zheng Dayu
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// IWindowsUpdateAgentInfo retrieves information about the version of Windows Update Agent (WUA).
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iwindowsupdateagentinfo
|
||||
type IWindowsUpdateAgentInfo struct {
|
||||
disp *ole.IDispatch
|
||||
}
|
||||
|
||||
// NewWindowsUpdateAgentInfo creates a new IWindowsUpdateAgentInfo instance.
|
||||
func NewWindowsUpdateAgentInfo() (*IWindowsUpdateAgentInfo, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.AgentInfo")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disp, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &IWindowsUpdateAgentInfo{disp: disp}, nil
|
||||
}
|
||||
|
||||
// GetInfo retrieves version information about Windows Update Agent.
|
||||
// varInfoIdentifier can be one of: "ApiMajorVersion", "ApiMinorVersion", "ProductVersionString"
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iwindowsupdateagentinfo-getinfo
|
||||
func (info *IWindowsUpdateAgentInfo) GetInfo(varInfoIdentifier string) (interface{}, error) {
|
||||
result, err := oleutil.CallMethod(info.disp, "GetInfo", varInfoIdentifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.Value(), nil
|
||||
}
|
||||
|
||||
// GetApiMajorVersion returns the major version of the WUA API.
|
||||
func (info *IWindowsUpdateAgentInfo) GetApiMajorVersion() (int32, error) {
|
||||
result, err := info.GetInfo("ApiMajorVersion")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Convert result to int32
|
||||
switch v := result.(type) {
|
||||
case int32:
|
||||
return v, nil
|
||||
case int:
|
||||
return int32(v), nil
|
||||
case int64:
|
||||
return int32(v), nil
|
||||
default:
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetApiMinorVersion returns the minor version of the WUA API.
|
||||
func (info *IWindowsUpdateAgentInfo) GetApiMinorVersion() (int32, error) {
|
||||
result, err := info.GetInfo("ApiMinorVersion")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Convert result to int32
|
||||
switch v := result.(type) {
|
||||
case int32:
|
||||
return v, nil
|
||||
case int:
|
||||
return int32(v), nil
|
||||
case int64:
|
||||
return int32(v), nil
|
||||
default:
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetProductVersionString returns the product version string of WUA.
|
||||
func (info *IWindowsUpdateAgentInfo) GetProductVersionString() (string, error) {
|
||||
result, err := info.GetInfo("ProductVersionString")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if str, ok := result.(string); ok {
|
||||
return str, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
Loading…
Reference in a new issue