github.com/google/osv-scalibr@v0.4.1/extractor/standalone/windows/dismpatch/dismpatch_windows.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build windows 16 17 // Package dismpatch extract patch level from the DISM command line tool. 18 package dismpatch 19 20 import ( 21 "context" 22 "os/exec" 23 24 "github.com/google/osv-scalibr/common/windows/registry" 25 "github.com/google/osv-scalibr/extractor/standalone" 26 "github.com/google/osv-scalibr/extractor/standalone/windows/common/winproducts" 27 "github.com/google/osv-scalibr/inventory" 28 "github.com/google/osv-scalibr/plugin" 29 ) 30 31 const ( 32 // Name of the extractor 33 Name = "windows/dismpatch" 34 ) 35 36 // Extractor implements the dismpatch extractor. 37 type Extractor struct{} 38 39 // New returns a new instance of the extractor. 40 func New() standalone.Extractor { 41 return &Extractor{} 42 } 43 44 // Name of the extractor. 45 func (e Extractor) Name() string { return Name } 46 47 // Version of the extractor. 48 func (e Extractor) Version() int { return 0 } 49 50 // Requirements of the extractor. 51 func (e Extractor) Requirements() *plugin.Capabilities { 52 return &plugin.Capabilities{OS: plugin.OSWindows, RunningSystem: true} 53 } 54 55 // Extract retrieves the patch level from the DISM command line tool. 56 func (e *Extractor) Extract(ctx context.Context, input *standalone.ScanInput) (inventory.Inventory, error) { 57 opener := registry.NewLiveOpener() 58 reg, err := opener.Open() 59 if err != nil { 60 return inventory.Inventory{}, err 61 } 62 63 defer reg.Close() 64 output, err := runDISM(ctx) 65 if err != nil { 66 return inventory.Inventory{}, err 67 } 68 69 flavor := winproducts.WindowsFlavorFromRegistry(reg) 70 return inventoryFromOutput(flavor, output) 71 } 72 73 // runDISM executes the dism command line tool. 74 func runDISM(ctx context.Context) (string, error) { 75 cmd := exec.CommandContext(ctx, "dism", "/online", "/get-packages", "/format:list") 76 output, err := cmd.CombinedOutput() 77 return string(output), err 78 }