Fix windowsupdate package missing in fresh clones
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -271,7 +271,6 @@ test-results/
|
||||
dev/
|
||||
|
||||
# Development packages and scripts
|
||||
aggregator-agent/pkg/
|
||||
aggregator-server/scripts/
|
||||
|
||||
# Build artifacts
|
||||
|
||||
25
aggregator-agent/pkg/windowsupdate/enum.go
Normal file
25
aggregator-agent/pkg/windowsupdate/enum.go
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
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
|
||||
|
||||
// OperationResultCode defines the possible results of a download, install, uninstall, or verification operation on an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-operationresultcode
|
||||
const (
|
||||
OperationResultCodeOrcNotStarted int32 = iota
|
||||
OperationResultCodeOrcInProgress
|
||||
OperationResultCodeOrcSucceeded
|
||||
OperationResultCodeOrcSucceededWithErrors
|
||||
OperationResultCodeOrcFailed
|
||||
OperationResultCodeOrcAborted
|
||||
)
|
||||
126
aggregator-agent/pkg/windowsupdate/icategory.go
Normal file
126
aggregator-agent/pkg/windowsupdate/icategory.go
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// ICategory represents the category to which an update belongs.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-icategory
|
||||
type ICategory struct {
|
||||
disp *ole.IDispatch
|
||||
CategoryID string
|
||||
Children []*ICategory
|
||||
Description string
|
||||
Image *IImageInformation
|
||||
Name string
|
||||
Order int32
|
||||
Parent *ICategory
|
||||
Type string
|
||||
Updates []*IUpdate
|
||||
}
|
||||
|
||||
func toICategories(categoriesDisp *ole.IDispatch) ([]*ICategory, error) {
|
||||
count, err := toInt32Err(oleutil.GetProperty(categoriesDisp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
categories := make([]*ICategory, 0, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
categoryDisp, err := toIDispatchErr(oleutil.GetProperty(categoriesDisp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
category, err := toICategory(categoryDisp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
categories = append(categories, category)
|
||||
}
|
||||
return categories, nil
|
||||
}
|
||||
|
||||
func toICategory(categoryDisp *ole.IDispatch) (*ICategory, error) {
|
||||
var err error
|
||||
iCategory := &ICategory{
|
||||
disp: categoryDisp,
|
||||
}
|
||||
|
||||
if iCategory.CategoryID, err = toStringErr(oleutil.GetProperty(categoryDisp, "CategoryID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
childrenDisp, err := toIDispatchErr(oleutil.GetProperty(categoryDisp, "Children"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if childrenDisp != nil {
|
||||
if iCategory.Children, err = toICategories(childrenDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iCategory.Description, err = toStringErr(oleutil.GetProperty(categoryDisp, "Description")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imageDisp, err := toIDispatchErr(oleutil.GetProperty(categoryDisp, "Image"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if imageDisp != nil {
|
||||
if iCategory.Image, err = toIImageInformation(imageDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iCategory.Name, err = toStringErr(oleutil.GetProperty(categoryDisp, "Name")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iCategory.Order, err = toInt32Err(oleutil.GetProperty(categoryDisp, "Order")); 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
|
||||
// }
|
||||
// }
|
||||
|
||||
return iCategory, nil
|
||||
}
|
||||
66
aggregator-agent/pkg/windowsupdate/idownloadresult.go
Normal file
66
aggregator-agent/pkg/windowsupdate/idownloadresult.go
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IDownloadResult represents the result of a download operation.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-idownloadresult
|
||||
type IDownloadResult struct {
|
||||
disp *ole.IDispatch
|
||||
HResult int32
|
||||
ResultCode int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-operationresultcode
|
||||
}
|
||||
|
||||
func toIDownloadResult(downloadResultDisp *ole.IDispatch) (*IDownloadResult, error) {
|
||||
var err error
|
||||
iDownloadResult := &IDownloadResult{
|
||||
disp: downloadResultDisp,
|
||||
}
|
||||
|
||||
if iDownloadResult.HResult, err = toInt32Err(oleutil.GetProperty(downloadResultDisp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iDownloadResult.ResultCode, err = toInt32Err(oleutil.GetProperty(downloadResultDisp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iDownloadResult, nil
|
||||
}
|
||||
|
||||
// GetUpdateResult returns an IUpdateDownloadResult interface that contains the download information for a specified update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-idownloadresult-getupdateresult
|
||||
func (iDownloadResult *IDownloadResult) GetUpdateResult(updateIndex int32) (*IUpdateDownloadResult, error) {
|
||||
var err error
|
||||
iUpdateDownloadResult := &IUpdateDownloadResult{
|
||||
disp: iDownloadResult.disp,
|
||||
}
|
||||
updatesDisp, err := toIDispatchErr(oleutil.CallMethod(iDownloadResult.disp, "GetUpdateResult", updateIndex))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateDownloadResult.HResult, err = toInt32Err(oleutil.GetProperty(updatesDisp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateDownloadResult.ResultCode, err = toInt32Err(oleutil.GetProperty(updatesDisp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iUpdateDownloadResult, nil
|
||||
}
|
||||
33
aggregator-agent/pkg/windowsupdate/iimageinformation.go
Normal file
33
aggregator-agent/pkg/windowsupdate/iimageinformation.go
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IImageInformation contains information about a localized image that is associated with an update or a category.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iimageinformation
|
||||
type IImageInformation struct {
|
||||
disp *ole.IDispatch
|
||||
AltText string
|
||||
Height int64
|
||||
Source string
|
||||
Width int64
|
||||
}
|
||||
|
||||
func toIImageInformation(imageInformationDisp *ole.IDispatch) (*IImageInformation, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
}
|
||||
33
aggregator-agent/pkg/windowsupdate/iinstallationbehavior.go
Normal file
33
aggregator-agent/pkg/windowsupdate/iinstallationbehavior.go
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IInstallationBehavior represents the installation and uninstallation options of an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iinstallationbehavior
|
||||
type IInstallationBehavior struct {
|
||||
disp *ole.IDispatch
|
||||
CanRequestUserInput bool
|
||||
Impact int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-installationimpact
|
||||
RebootBehavior int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-installationrebootbehavior
|
||||
RequiresNetworkConnectivity bool
|
||||
}
|
||||
|
||||
func toIInstallationBehavior(installationBehaviorDisp *ole.IDispatch) (*IInstallationBehavior, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
}
|
||||
71
aggregator-agent/pkg/windowsupdate/iinstallationresult.go
Normal file
71
aggregator-agent/pkg/windowsupdate/iinstallationresult.go
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IInstallationResult represents the result of an installation or uninstallation.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iinstallationresult
|
||||
type IInstallationResult struct {
|
||||
disp *ole.IDispatch
|
||||
HResult int32
|
||||
RebootRequired bool
|
||||
ResultCode int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-operationresultcode
|
||||
}
|
||||
|
||||
func toIInstallationResult(installationResultDisp *ole.IDispatch) (*IInstallationResult, error) {
|
||||
var err error
|
||||
iInstallationResult := &IInstallationResult{
|
||||
disp: installationResultDisp,
|
||||
}
|
||||
|
||||
if iInstallationResult.HResult, err = toInt32Err(oleutil.GetProperty(installationResultDisp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iInstallationResult.RebootRequired, err = toBoolErr(oleutil.GetProperty(installationResultDisp, "RebootRequired")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iInstallationResult.ResultCode, err = toInt32Err(oleutil.GetProperty(installationResultDisp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iInstallationResult, nil
|
||||
}
|
||||
|
||||
// GetUpdateResult returns an IInstallationResult interface that contains the installation information for a specified update.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iinstallationresult
|
||||
func (iInstallationResult *IInstallationResult) GetUpdateResult(updateIndex int32) (*IInstallationResult, error) {
|
||||
var err error
|
||||
iUpdateInstallationResult := &IInstallationResult{
|
||||
disp: iInstallationResult.disp,
|
||||
}
|
||||
updatesDisp, err := toIDispatchErr(oleutil.CallMethod(iInstallationResult.disp, "GetUpdateResult", updateIndex))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateInstallationResult.HResult, err = toInt32Err(oleutil.GetProperty(updatesDisp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateInstallationResult.ResultCode, err = toInt32Err(oleutil.GetProperty(updatesDisp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iUpdateInstallationResult, nil
|
||||
}
|
||||
72
aggregator-agent/pkg/windowsupdate/isearchresult.go
Normal file
72
aggregator-agent/pkg/windowsupdate/isearchresult.go
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// ISearchResult represents the result of a search.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-isearchresult
|
||||
type ISearchResult struct {
|
||||
disp *ole.IDispatch
|
||||
ResultCode int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-operationresultcode
|
||||
RootCategories []*ICategory
|
||||
Updates []*IUpdate
|
||||
Warnings []*IUpdateException
|
||||
}
|
||||
|
||||
func toISearchResult(searchResultDisp *ole.IDispatch) (*ISearchResult, error) {
|
||||
var err error
|
||||
iSearchResult := &ISearchResult{
|
||||
disp: searchResultDisp,
|
||||
}
|
||||
|
||||
if iSearchResult.ResultCode, err = toInt32Err(oleutil.GetProperty(searchResultDisp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rootCategoriesDisp, err := toIDispatchErr(oleutil.GetProperty(searchResultDisp, "RootCategories"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rootCategoriesDisp != nil {
|
||||
if iSearchResult.RootCategories, err = toICategories(rootCategoriesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
updatesDisp, err := toIDispatchErr(oleutil.GetProperty(searchResultDisp, "Updates"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if updatesDisp != nil {
|
||||
if iSearchResult.Updates, err = toIUpdates(updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
warningsDisp, err := toIDispatchErr(oleutil.GetProperty(searchResultDisp, "Warnings"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if warningsDisp != nil {
|
||||
if iSearchResult.Warnings, err = toIUpdateExceptions(warningsDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return iSearchResult, nil
|
||||
}
|
||||
34
aggregator-agent/pkg/windowsupdate/istringcollection.go
Normal file
34
aggregator-agent/pkg/windowsupdate/istringcollection.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package windowsupdate
|
||||
|
||||
import (
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-istringcollection
|
||||
func iStringCollectionToStringArrayErr(disp *ole.IDispatch, err error) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if disp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
count, err := toInt32Err(oleutil.GetProperty(disp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stringCollection := make([]string, count)
|
||||
|
||||
for i := 0; i < int(count); i++ {
|
||||
str, err := toStringErr(oleutil.GetProperty(disp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stringCollection[i] = str
|
||||
}
|
||||
return stringCollection, nil
|
||||
}
|
||||
363
aggregator-agent/pkg/windowsupdate/iupdate.go
Normal file
363
aggregator-agent/pkg/windowsupdate/iupdate.go
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdate contains the properties and methods that are available to an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdate
|
||||
type IUpdate struct {
|
||||
disp *ole.IDispatch
|
||||
AutoSelectOnWebSites bool
|
||||
BundledUpdates []*IUpdateIdentity
|
||||
CanRequireSource bool
|
||||
Categories []*ICategory
|
||||
Deadline *time.Time
|
||||
DeltaCompressedContentAvailable bool
|
||||
DeltaCompressedContentPreferred bool
|
||||
DeploymentAction int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-deploymentaction
|
||||
Description string
|
||||
DownloadContents []*IUpdateDownloadContent
|
||||
DownloadPriority int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-downloadpriority
|
||||
EulaAccepted bool
|
||||
EulaText string
|
||||
HandlerID string
|
||||
Identity *IUpdateIdentity
|
||||
Image *IImageInformation
|
||||
InstallationBehavior *IInstallationBehavior
|
||||
IsBeta bool
|
||||
IsDownloaded bool
|
||||
IsHidden bool
|
||||
IsInstalled bool
|
||||
IsMandatory bool
|
||||
IsUninstallable bool
|
||||
KBArticleIDs []string
|
||||
Languages []string
|
||||
LastDeploymentChangeTime *time.Time
|
||||
MaxDownloadSize int64
|
||||
MinDownloadSize int64
|
||||
MoreInfoUrls []string
|
||||
MsrcSeverity string
|
||||
RecommendedCpuSpeed int32
|
||||
RecommendedHardDiskSpace int32
|
||||
RecommendedMemory int32
|
||||
ReleaseNotes string
|
||||
SecurityBulletinIDs []string
|
||||
SupersededUpdateIDs []string
|
||||
SupportUrl string
|
||||
Title string
|
||||
UninstallationBehavior *IInstallationBehavior
|
||||
UninstallationNotes string
|
||||
UninstallationSteps []string
|
||||
}
|
||||
|
||||
func toIUpdates(updatesDisp *ole.IDispatch) ([]*IUpdate, error) {
|
||||
count, err := toInt32Err(oleutil.GetProperty(updatesDisp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updates := make([]*IUpdate, 0, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
updateDisp, err := toIDispatchErr(oleutil.GetProperty(updatesDisp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
update, err := toIUpdate(updateDisp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updates = append(updates, update)
|
||||
}
|
||||
return updates, nil
|
||||
}
|
||||
|
||||
// toIUpdates takes a IUpdateCollection and returns the a
|
||||
// []*IUpdateIdentity of the contained IUpdates. This is *not* recursive, though possible should be
|
||||
func toIUpdatesIdentities(updatesDisp *ole.IDispatch) ([]*IUpdateIdentity, error) {
|
||||
if updatesDisp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
count, err := toInt32Err(oleutil.GetProperty(updatesDisp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
identities := make([]*IUpdateIdentity, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
updateDisp, err := toIDispatchErr(oleutil.GetProperty(updatesDisp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
identityDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "Identity"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if identityDisp != nil {
|
||||
if identities[i], err = toIUpdateIdentity(identityDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return identities, nil
|
||||
}
|
||||
|
||||
func toIUpdate(updateDisp *ole.IDispatch) (*IUpdate, error) {
|
||||
var err error
|
||||
iUpdate := &IUpdate{
|
||||
disp: updateDisp,
|
||||
}
|
||||
|
||||
if iUpdate.AutoSelectOnWebSites, err = toBoolErr(oleutil.GetProperty(updateDisp, "AutoSelectOnWebSites")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bundledUpdatesDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "BundledUpdates"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bundledUpdatesDisp != nil {
|
||||
if iUpdate.BundledUpdates, err = toIUpdatesIdentities(bundledUpdatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iUpdate.CanRequireSource, err = toBoolErr(oleutil.GetProperty(updateDisp, "CanRequireSource")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
categoriesDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "Categories"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if categoriesDisp != nil {
|
||||
if iUpdate.Categories, err = toICategories(categoriesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iUpdate.Deadline, err = toTimeErr(oleutil.GetProperty(updateDisp, "Deadline")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.DeltaCompressedContentAvailable, err = toBoolErr(oleutil.GetProperty(updateDisp, "DeltaCompressedContentAvailable")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.DeltaCompressedContentPreferred, err = toBoolErr(oleutil.GetProperty(updateDisp, "DeltaCompressedContentPreferred")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.DeploymentAction, err = toInt32Err(oleutil.GetProperty(updateDisp, "DeploymentAction")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.Description, err = toStringErr(oleutil.GetProperty(updateDisp, "Description")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
downloadContentsDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "DownloadContents"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if downloadContentsDisp != nil {
|
||||
if iUpdate.DownloadContents, err = toIUpdateDownloadContents(downloadContentsDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iUpdate.DownloadPriority, err = toInt32Err(oleutil.GetProperty(updateDisp, "DownloadPriority")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.EulaAccepted, err = toBoolErr(oleutil.GetProperty(updateDisp, "EulaAccepted")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.EulaText, err = toStringErr(oleutil.GetProperty(updateDisp, "EulaText")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.HandlerID, err = toStringErr(oleutil.GetProperty(updateDisp, "HandlerID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
identityDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "Identity"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if identityDisp != nil {
|
||||
if iUpdate.Identity, err = toIUpdateIdentity(identityDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
imageDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "Image"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if imageDisp != nil {
|
||||
if iUpdate.Image, err = toIImageInformation(imageDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
installationBehaviorDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "InstallationBehavior"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if installationBehaviorDisp != nil {
|
||||
if iUpdate.InstallationBehavior, err = toIInstallationBehavior(installationBehaviorDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iUpdate.IsBeta, err = toBoolErr(oleutil.GetProperty(updateDisp, "IsBeta")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.IsDownloaded, err = toBoolErr(oleutil.GetProperty(updateDisp, "IsDownloaded")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.IsHidden, err = toBoolErr(oleutil.GetProperty(updateDisp, "IsHidden")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.IsInstalled, err = toBoolErr(oleutil.GetProperty(updateDisp, "IsInstalled")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.IsMandatory, err = toBoolErr(oleutil.GetProperty(updateDisp, "IsMandatory")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.IsUninstallable, err = toBoolErr(oleutil.GetProperty(updateDisp, "IsUninstallable")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.KBArticleIDs, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateDisp, "KBArticleIDs"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.Languages, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateDisp, "Languages"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.LastDeploymentChangeTime, err = toTimeErr(oleutil.GetProperty(updateDisp, "LastDeploymentChangeTime")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.MaxDownloadSize, err = toInt64Err(oleutil.GetProperty(updateDisp, "MaxDownloadSize")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.MinDownloadSize, err = toInt64Err(oleutil.GetProperty(updateDisp, "MinDownloadSize")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.MoreInfoUrls, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateDisp, "MoreInfoUrls"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.MsrcSeverity, err = toStringErr(oleutil.GetProperty(updateDisp, "MsrcSeverity")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.RecommendedCpuSpeed, err = toInt32Err(oleutil.GetProperty(updateDisp, "RecommendedCpuSpeed")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.RecommendedHardDiskSpace, err = toInt32Err(oleutil.GetProperty(updateDisp, "RecommendedHardDiskSpace")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.RecommendedMemory, err = toInt32Err(oleutil.GetProperty(updateDisp, "RecommendedMemory")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.ReleaseNotes, err = toStringErr(oleutil.GetProperty(updateDisp, "ReleaseNotes")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.SecurityBulletinIDs, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateDisp, "SecurityBulletinIDs"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.SupersededUpdateIDs, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateDisp, "SupersededUpdateIDs"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.SupportUrl, err = toStringErr(oleutil.GetProperty(updateDisp, "SupportUrl")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.Title, err = toStringErr(oleutil.GetProperty(updateDisp, "Title")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uninstallationBehaviorDisp, err := toIDispatchErr(oleutil.GetProperty(updateDisp, "UninstallationBehavior"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uninstallationBehaviorDisp != nil {
|
||||
if iUpdate.UninstallationBehavior, err = toIInstallationBehavior(uninstallationBehaviorDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if iUpdate.UninstallationNotes, err = toStringErr(oleutil.GetProperty(updateDisp, "UninstallationNotes")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdate.UninstallationSteps, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateDisp, "UninstallationSteps"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iUpdate, nil
|
||||
}
|
||||
|
||||
func toIUpdateCollection(updates []*IUpdate) (*ole.IDispatch, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.UpdateColl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
coll, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, update := range updates {
|
||||
_, err := oleutil.CallMethod(coll, "Add", update.disp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return coll, nil
|
||||
}
|
||||
|
||||
// AcceptEula accepts the Microsoft Software License Terms that are associated with Windows Update. Administrators and power users can call this method.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdate-accepteula
|
||||
func (iUpdate *IUpdate) AcceptEula() error {
|
||||
_, err := oleutil.CallMethod(iUpdate.disp, "AcceptEula")
|
||||
return err
|
||||
}
|
||||
30
aggregator-agent/pkg/windowsupdate/iupdatedownloadcontent.go
Normal file
30
aggregator-agent/pkg/windowsupdate/iupdatedownloadcontent.go
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateDownloadContent represents the download content of an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatedownloadcontent
|
||||
type IUpdateDownloadContent struct {
|
||||
disp *ole.IDispatch
|
||||
DownloadUrl string
|
||||
}
|
||||
|
||||
func toIUpdateDownloadContents(updateDownloadContentsDisp *ole.IDispatch) ([]*IUpdateDownloadContent, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
}
|
||||
78
aggregator-agent/pkg/windowsupdate/iupdatedownloader.go
Normal file
78
aggregator-agent/pkg/windowsupdate/iupdatedownloader.go
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateDownloader downloads updates from the server.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatedownloaders
|
||||
type IUpdateDownloader struct {
|
||||
disp *ole.IDispatch
|
||||
ClientApplicationID string
|
||||
IsForced bool
|
||||
Priority int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-downloadpriority
|
||||
Updates []*IUpdate
|
||||
}
|
||||
|
||||
func toIUpdateDownloader(updateDownloaderDisp *ole.IDispatch) (*IUpdateDownloader, error) {
|
||||
var err error
|
||||
iUpdateDownloader := &IUpdateDownloader{
|
||||
disp: updateDownloaderDisp,
|
||||
}
|
||||
|
||||
if iUpdateDownloader.ClientApplicationID, err = toStringErr(oleutil.GetProperty(updateDownloaderDisp, "ClientApplicationID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateDownloader.IsForced, err = toBoolErr(oleutil.GetProperty(updateDownloaderDisp, "IsForced")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateDownloader.Priority, err = toInt32Err(oleutil.GetProperty(updateDownloaderDisp, "Priority")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatesDisp, err := toIDispatchErr(oleutil.GetProperty(updateDownloaderDisp, "Updates"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if updatesDisp != nil {
|
||||
if iUpdateDownloader.Updates, err = toIUpdates(updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return iUpdateDownloader, nil
|
||||
}
|
||||
|
||||
// Download starts a synchronous download of the content files that are associated with the updates.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatedownloader-download
|
||||
func (iUpdateDownloader *IUpdateDownloader) Download(updates []*IUpdate) (*IDownloadResult, error) {
|
||||
updatesDisp, err := toIUpdateCollection(updates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = oleutil.PutProperty(iUpdateDownloader.disp, "Updates", updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
downloadResultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateDownloader.disp, "Download"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIDownloadResult(downloadResultDisp)
|
||||
}
|
||||
31
aggregator-agent/pkg/windowsupdate/iupdatedownloadresult.go
Normal file
31
aggregator-agent/pkg/windowsupdate/iupdatedownloadresult.go
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateDownloadResult contains the properties that indicate the status of a download operation for an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatedownloadresult
|
||||
type IUpdateDownloadResult struct {
|
||||
disp *ole.IDispatch
|
||||
HResult int32
|
||||
ResultCode int32
|
||||
}
|
||||
|
||||
func toIUpdateDownloadResult(iUpdateDownloadResultDisp *ole.IDispatch) (*IUpdateDownloadResult, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
}
|
||||
32
aggregator-agent/pkg/windowsupdate/iupdateexception.go
Normal file
32
aggregator-agent/pkg/windowsupdate/iupdateexception.go
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateException represents info about the aspects of search results returned in the ISearchResult object that were incomplete. For more info, see Remarks.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdateexception
|
||||
type IUpdateException struct {
|
||||
disp *ole.IDispatch
|
||||
Context int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updateexceptioncontext
|
||||
HResult int64
|
||||
Message string
|
||||
}
|
||||
|
||||
func toIUpdateExceptions(updateExceptionsDisp *ole.IDispatch) ([]*IUpdateException, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
}
|
||||
135
aggregator-agent/pkg/windowsupdate/iupdatehistoryentry.go
Normal file
135
aggregator-agent/pkg/windowsupdate/iupdatehistoryentry.go
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateHistoryEntry represents the recorded history of an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatehistoryentry
|
||||
type IUpdateHistoryEntry struct {
|
||||
disp *ole.IDispatch
|
||||
ClientApplicationID string
|
||||
Date *time.Time
|
||||
Description string
|
||||
HResult int32
|
||||
Operation int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updateoperation
|
||||
ResultCode int32 // enum https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-operationresultcode
|
||||
ServerSelection int32 // enum
|
||||
ServiceID string
|
||||
SupportUrl string
|
||||
Title string
|
||||
UninstallationNotes string
|
||||
UninstallationSteps []string
|
||||
UnmappedResultCode int32
|
||||
UpdateIdentity *IUpdateIdentity
|
||||
}
|
||||
|
||||
func toIUpdateHistoryEntries(updateHistoryEntriesDisp *ole.IDispatch) ([]*IUpdateHistoryEntry, error) {
|
||||
count, err := toInt32Err(oleutil.GetProperty(updateHistoryEntriesDisp, "Count"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updateHistoryEntries := make([]*IUpdateHistoryEntry, 0, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
updateHistoryEntryDisp, err := toIDispatchErr(oleutil.GetProperty(updateHistoryEntriesDisp, "Item", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updateHistoryEntry, err := toIUpdateHistoryEntry(updateHistoryEntryDisp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updateHistoryEntries = append(updateHistoryEntries, updateHistoryEntry)
|
||||
}
|
||||
return updateHistoryEntries, nil
|
||||
}
|
||||
|
||||
func toIUpdateHistoryEntry(updateHistoryEntryDisp *ole.IDispatch) (*IUpdateHistoryEntry, error) {
|
||||
var err error
|
||||
iUpdateHistoryEntry := &IUpdateHistoryEntry{
|
||||
disp: updateHistoryEntryDisp,
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.ClientApplicationID, err = toStringErr(oleutil.GetProperty(updateHistoryEntryDisp, "ClientApplicationID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.Date, err = toTimeErr(oleutil.GetProperty(updateHistoryEntryDisp, "Date")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.Description, err = toStringErr(oleutil.GetProperty(updateHistoryEntryDisp, "Description")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.HResult, err = toInt32Err(oleutil.GetProperty(updateHistoryEntryDisp, "HResult")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.Operation, err = toInt32Err(oleutil.GetProperty(updateHistoryEntryDisp, "Operation")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.ResultCode, err = toInt32Err(oleutil.GetProperty(updateHistoryEntryDisp, "ResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.ServerSelection, err = toInt32Err(oleutil.GetProperty(updateHistoryEntryDisp, "ServerSelection")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.ServiceID, err = toStringErr(oleutil.GetProperty(updateHistoryEntryDisp, "ServiceID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.SupportUrl, err = toStringErr(oleutil.GetProperty(updateHistoryEntryDisp, "SupportUrl")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.Title, err = toStringErr(oleutil.GetProperty(updateHistoryEntryDisp, "Title")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.UninstallationNotes, err = toStringErr(oleutil.GetProperty(updateHistoryEntryDisp, "UninstallationNotes")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.UninstallationSteps, err = iStringCollectionToStringArrayErr(toIDispatchErr(oleutil.GetProperty(updateHistoryEntryDisp, "UninstallationSteps"))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateHistoryEntry.UnmappedResultCode, err = toInt32Err(oleutil.GetProperty(updateHistoryEntryDisp, "UnmappedResultCode")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updateIdentityDisp, err := toIDispatchErr(oleutil.GetProperty(updateHistoryEntryDisp, "UpdateIdentity"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if updateIdentityDisp != nil {
|
||||
if iUpdateHistoryEntry.UpdateIdentity, err = toIUpdateIdentity(updateIdentityDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return iUpdateHistoryEntry, nil
|
||||
}
|
||||
44
aggregator-agent/pkg/windowsupdate/iupdateidentity.go
Normal file
44
aggregator-agent/pkg/windowsupdate/iupdateidentity.go
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateIdentity represents the unique identifier of an update.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdateidentity
|
||||
type IUpdateIdentity struct {
|
||||
disp *ole.IDispatch
|
||||
RevisionNumber int32
|
||||
UpdateID string
|
||||
}
|
||||
|
||||
func toIUpdateIdentity(updateIdentityDisp *ole.IDispatch) (*IUpdateIdentity, error) {
|
||||
var err error
|
||||
iUpdateIdentity := &IUpdateIdentity{
|
||||
disp: updateIdentityDisp,
|
||||
}
|
||||
|
||||
if iUpdateIdentity.RevisionNumber, err = toInt32Err(oleutil.GetProperty(updateIdentityDisp, "RevisionNumber")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateIdentity.UpdateID, err = toStringErr(oleutil.GetProperty(updateIdentityDisp, "UpdateID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iUpdateIdentity, nil
|
||||
}
|
||||
127
aggregator-agent/pkg/windowsupdate/iupdateinstaller.go
Normal file
127
aggregator-agent/pkg/windowsupdate/iupdateinstaller.go
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateInstaller installs or uninstalls updates from or onto a computer.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdateinstaller
|
||||
type IUpdateInstaller struct {
|
||||
disp *ole.IDispatch
|
||||
AllowSourcePrompts bool
|
||||
ClientApplicationID string
|
||||
IsBusy bool
|
||||
IsForced bool
|
||||
ForceQuiet bool
|
||||
// ParentHwnd HWND
|
||||
// ParentWindow IUnknown
|
||||
RebootRequiredBeforeInstallation bool
|
||||
Updates []*IUpdate
|
||||
}
|
||||
|
||||
func toIUpdateInstaller(updateInstallerDisp *ole.IDispatch) (*IUpdateInstaller, error) {
|
||||
var err error
|
||||
iUpdateInstaller := &IUpdateInstaller{
|
||||
disp: updateInstallerDisp,
|
||||
}
|
||||
|
||||
if iUpdateInstaller.AllowSourcePrompts, err = toBoolErr(oleutil.GetProperty(updateInstallerDisp, "AllowSourcePrompts")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateInstaller.ClientApplicationID, err = toStringErr(oleutil.GetProperty(updateInstallerDisp, "ClientApplicationID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateInstaller.IsBusy, err = toBoolErr(oleutil.GetProperty(updateInstallerDisp, "IsBusy")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateInstaller.IsForced, err = toBoolErr(oleutil.GetProperty(updateInstallerDisp, "IsForced")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
updatesDisp, err := toIDispatchErr(oleutil.GetProperty(updateInstallerDisp, "Updates"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if updatesDisp != nil {
|
||||
if iUpdateInstaller.Updates, err = toIUpdates(updatesDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return iUpdateInstaller, nil
|
||||
}
|
||||
|
||||
// Install starts a synchronous installation of the updates.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller-install
|
||||
func (iUpdateInstaller *IUpdateInstaller) Install(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
|
||||
}
|
||||
|
||||
installationResultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateInstaller.disp, "Install"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIInstallationResult(installationResultDisp)
|
||||
}
|
||||
|
||||
// Finalizes updates that were previously staged or installed.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller4-commit
|
||||
func (iUpdateInstaller *IUpdateInstaller) Commit(dwFlags int32) error {
|
||||
_, err := toIDispatchErr(oleutil.CallMethod(iUpdateInstaller.disp, "Commit", dwFlags))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sets a Boolean value that indicates whether Windows Installer is forced to install the updates without user interaction.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller2-put_forcequiet
|
||||
func (iUpdateInstaller *IUpdateInstaller) PutForceQuiet(value bool) error {
|
||||
_, err := toIDispatchErr(oleutil.PutProperty(iUpdateInstaller.disp, "ForceQuiet", value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateInstaller.ForceQuiet = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sets a Boolean value that indicates whether to forcibly install or uninstall an update.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdateinstaller-put_isforced
|
||||
func (iUpdateInstaller *IUpdateInstaller) PutIsForced(value bool) error {
|
||||
_, err := toIDispatchErr(oleutil.PutProperty(iUpdateInstaller.disp, "IsForced", value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iUpdateInstaller.IsForced = value
|
||||
return nil
|
||||
}
|
||||
99
aggregator-agent/pkg/windowsupdate/iupdatesearcher.go
Normal file
99
aggregator-agent/pkg/windowsupdate/iupdatesearcher.go
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateSearcher searches for updates on a server.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatesearcher
|
||||
type IUpdateSearcher struct {
|
||||
disp *ole.IDispatch
|
||||
CanAutomaticallyUpgradeService bool
|
||||
ClientApplicationID string
|
||||
IncludePotentiallySupersededUpdates bool
|
||||
Online bool
|
||||
ServerSelection int32
|
||||
ServiceID string
|
||||
}
|
||||
|
||||
func toIUpdateSearcher(updateSearcherDisp *ole.IDispatch) (*IUpdateSearcher, error) {
|
||||
var err error
|
||||
iUpdateSearcher := &IUpdateSearcher{
|
||||
disp: updateSearcherDisp,
|
||||
}
|
||||
|
||||
if iUpdateSearcher.CanAutomaticallyUpgradeService, err = toBoolErr(oleutil.GetProperty(updateSearcherDisp, "CanAutomaticallyUpgradeService")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateSearcher.ClientApplicationID, err = toStringErr(oleutil.GetProperty(updateSearcherDisp, "ClientApplicationID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateSearcher.IncludePotentiallySupersededUpdates, err = toBoolErr(oleutil.GetProperty(updateSearcherDisp, "IncludePotentiallySupersededUpdates")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateSearcher.Online, err = toBoolErr(oleutil.GetProperty(updateSearcherDisp, "Online")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateSearcher.ServerSelection, err = toInt32Err(oleutil.GetProperty(updateSearcherDisp, "ServerSelection")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateSearcher.ServiceID, err = toStringErr(oleutil.GetProperty(updateSearcherDisp, "ServiceID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iUpdateSearcher, nil
|
||||
}
|
||||
|
||||
// Search performs a synchronous search for updates. The search uses the search options that are currently configured.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-search
|
||||
func (iUpdateSearcher *IUpdateSearcher) Search(criteria string) (*ISearchResult, error) {
|
||||
searchResultDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateSearcher.disp, "Search", criteria))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toISearchResult(searchResultDisp)
|
||||
}
|
||||
|
||||
// QueryHistory synchronously queries the computer for the history of the update events.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-queryhistory
|
||||
func (iUpdateSearcher *IUpdateSearcher) QueryHistory(startIndex int32, count int32) ([]*IUpdateHistoryEntry, error) {
|
||||
updateHistoryEntriesDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateSearcher.disp, "QueryHistory", startIndex, count))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateHistoryEntries(updateHistoryEntriesDisp)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return toInt32Err(oleutil.CallMethod(iUpdateSearcher.disp, "GetTotalHistoryCount"))
|
||||
}
|
||||
|
||||
// QueryHistoryAll synchronously queries the computer for the history of all update events.
|
||||
func (iUpdateSearcher *IUpdateSearcher) QueryHistoryAll() ([]*IUpdateHistoryEntry, error) {
|
||||
count, err := iUpdateSearcher.GetTotalHistoryCount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iUpdateSearcher.QueryHistory(0, count)
|
||||
}
|
||||
100
aggregator-agent/pkg/windowsupdate/iupdatesession.go
Normal file
100
aggregator-agent/pkg/windowsupdate/iupdatesession.go
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// IUpdateSession represents a session in which the caller can perform operations that involve updates.
|
||||
// For example, this interface represents sessions in which the caller performs a search, download, installation, or uninstallation operation.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatesession
|
||||
type IUpdateSession struct {
|
||||
disp *ole.IDispatch
|
||||
ClientApplicationID string
|
||||
ReadOnly bool
|
||||
WebProxy *IWebProxy
|
||||
}
|
||||
|
||||
func toIUpdateSession(updateSessionDisp *ole.IDispatch) (*IUpdateSession, error) {
|
||||
var err error
|
||||
iUpdateSession := &IUpdateSession{
|
||||
disp: updateSessionDisp,
|
||||
}
|
||||
|
||||
if iUpdateSession.ClientApplicationID, err = toStringErr(oleutil.GetProperty(updateSessionDisp, "ClientApplicationID")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iUpdateSession.ReadOnly, err = toBoolErr(oleutil.GetProperty(updateSessionDisp, "ReadOnly")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
webProxyDisp, err := toIDispatchErr(oleutil.GetProperty(updateSessionDisp, "WebProxy"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if webProxyDisp != nil {
|
||||
if iUpdateSession.WebProxy, err = toIWebProxy(webProxyDisp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return iUpdateSession, nil
|
||||
}
|
||||
|
||||
// NewUpdateSession creates a new IUpdateSession interface.
|
||||
func NewUpdateSession() (*IUpdateSession, error) {
|
||||
unknown, err := oleutil.CreateObject("Microsoft.Update.Session")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disp, err := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateSession(disp)
|
||||
}
|
||||
|
||||
// CreateUpdateDownloader returns an IUpdateDownloader interface for this session.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesession-createupdatedownloader
|
||||
func (iUpdateSession *IUpdateSession) CreateUpdateDownloader() (*IUpdateDownloader, error) {
|
||||
updateDownloaderDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateSession.disp, "CreateUpdateDownloader"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateDownloader(updateDownloaderDisp)
|
||||
}
|
||||
|
||||
// CreateUpdateInstaller returns an IUpdateInstaller interface for this session.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesession-createupdateinstaller
|
||||
func (iUpdateSession *IUpdateSession) CreateUpdateInstaller() (*IUpdateInstaller, error) {
|
||||
updateInstallerDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateSession.disp, "CreateUpdateInstaller"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toIUpdateInstaller(updateInstallerDisp)
|
||||
}
|
||||
|
||||
// CreateUpdateSearcher returns an IUpdateSearcher interface for this session.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesession-createupdatesearcher
|
||||
func (iUpdateSession *IUpdateSession) CreateUpdateSearcher() (*IUpdateSearcher, error) {
|
||||
updateSearcherDisp, err := toIDispatchErr(oleutil.CallMethod(iUpdateSession.disp, "CreateUpdateSearcher"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toIUpdateSearcher(updateSearcherDisp)
|
||||
}
|
||||
35
aggregator-agent/pkg/windowsupdate/iwebproxy.go
Normal file
35
aggregator-agent/pkg/windowsupdate/iwebproxy.go
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
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"
|
||||
)
|
||||
|
||||
// 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
|
||||
Address string
|
||||
AutoDetect bool
|
||||
BypassList []string
|
||||
BypassProxyOnLocal bool
|
||||
ReadOnly bool
|
||||
UserName string
|
||||
}
|
||||
|
||||
func toIWebProxy(webProxyDisp *ole.IDispatch) (*IWebProxy, error) {
|
||||
// TODO
|
||||
return nil, nil
|
||||
}
|
||||
141
aggregator-agent/pkg/windowsupdate/oleconv.go
Normal file
141
aggregator-agent/pkg/windowsupdate/oleconv.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 (
|
||||
"time"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
)
|
||||
|
||||
func toIDispatchErr(result *ole.VARIANT, err error) (*ole.IDispatch, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return variantToIDispatch(result), nil
|
||||
}
|
||||
|
||||
func toInt64Err(result *ole.VARIANT, err error) (int64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return variantToInt64(result), nil
|
||||
}
|
||||
|
||||
func toInt32Err(result *ole.VARIANT, err error) (int32, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return variantToInt32(result), nil
|
||||
}
|
||||
|
||||
func toFloat64Err(result *ole.VARIANT, err error) (float64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return variantToFloat64(result), nil
|
||||
}
|
||||
|
||||
func toFloat32Err(result *ole.VARIANT, err error) (float32, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return variantToFloat32(result), nil
|
||||
}
|
||||
|
||||
func toStringErr(result *ole.VARIANT, err error) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return variantToString(result), nil
|
||||
}
|
||||
|
||||
func toBoolErr(result *ole.VARIANT, err error) (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return variantToBool(result), nil
|
||||
}
|
||||
|
||||
func toTimeErr(result *ole.VARIANT, err error) (*time.Time, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return variantToTime(result), nil
|
||||
}
|
||||
|
||||
func variantToIDispatch(v *ole.VARIANT) *ole.IDispatch {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
return v.ToIDispatch()
|
||||
}
|
||||
|
||||
func variantToInt64(v *ole.VARIANT) int64 {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return 0
|
||||
}
|
||||
return value.(int64)
|
||||
}
|
||||
|
||||
func variantToInt32(v *ole.VARIANT) int32 {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return 0
|
||||
}
|
||||
return value.(int32)
|
||||
}
|
||||
|
||||
func variantToFloat64(v *ole.VARIANT) float64 {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return 0
|
||||
}
|
||||
return value.(float64)
|
||||
}
|
||||
|
||||
func variantToFloat32(v *ole.VARIANT) float32 {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return 0
|
||||
}
|
||||
return value.(float32)
|
||||
}
|
||||
|
||||
func variantToString(v *ole.VARIANT) string {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return ""
|
||||
}
|
||||
return value.(string)
|
||||
}
|
||||
|
||||
func variantToBool(v *ole.VARIANT) bool {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return false
|
||||
}
|
||||
return value.(bool)
|
||||
}
|
||||
|
||||
func variantToTime(v *ole.VARIANT) *time.Time {
|
||||
value := v.Value()
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
valueTime := value.(time.Time)
|
||||
return &valueTime
|
||||
}
|
||||
Reference in New Issue
Block a user