11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst cp = require('child_process')
41cb0ef41Sopenharmony_ciconst path = require('path')
51cb0ef41Sopenharmony_ciconst { openSync, closeSync } = require('graceful-fs')
61cb0ef41Sopenharmony_ciconst log = require('./log')
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst execFile = async (...args) => new Promise((resolve) => {
91cb0ef41Sopenharmony_ci  const child = cp.execFile(...args, (...a) => resolve(a))
101cb0ef41Sopenharmony_ci  child.stdin.end()
111cb0ef41Sopenharmony_ci})
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciasync function regGetValue (key, value, addOpts) {
141cb0ef41Sopenharmony_ci  const outReValue = value.replace(/\W/g, '.')
151cb0ef41Sopenharmony_ci  const outRe = new RegExp(`^\\s+${outReValue}\\s+REG_\\w+\\s+(\\S.*)$`, 'im')
161cb0ef41Sopenharmony_ci  const reg = path.join(process.env.SystemRoot, 'System32', 'reg.exe')
171cb0ef41Sopenharmony_ci  const regArgs = ['query', key, '/v', value].concat(addOpts)
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci  log.silly('reg', 'running', reg, regArgs)
201cb0ef41Sopenharmony_ci  const [err, stdout, stderr] = await execFile(reg, regArgs, { encoding: 'utf8' })
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci  log.silly('reg', 'reg.exe stdout = %j', stdout)
231cb0ef41Sopenharmony_ci  if (err || stderr.trim() !== '') {
241cb0ef41Sopenharmony_ci    log.silly('reg', 'reg.exe err = %j', err && (err.stack || err))
251cb0ef41Sopenharmony_ci    log.silly('reg', 'reg.exe stderr = %j', stderr)
261cb0ef41Sopenharmony_ci    if (err) {
271cb0ef41Sopenharmony_ci      throw err
281cb0ef41Sopenharmony_ci    }
291cb0ef41Sopenharmony_ci    throw new Error(stderr)
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  const result = outRe.exec(stdout)
331cb0ef41Sopenharmony_ci  if (!result) {
341cb0ef41Sopenharmony_ci    log.silly('reg', 'error parsing stdout')
351cb0ef41Sopenharmony_ci    throw new Error('Could not parse output of reg.exe')
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  log.silly('reg', 'found: %j', result[1])
391cb0ef41Sopenharmony_ci  return result[1]
401cb0ef41Sopenharmony_ci}
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ciasync function regSearchKeys (keys, value, addOpts) {
431cb0ef41Sopenharmony_ci  for (const key of keys) {
441cb0ef41Sopenharmony_ci    try {
451cb0ef41Sopenharmony_ci      return await regGetValue(key, value, addOpts)
461cb0ef41Sopenharmony_ci    } catch {
471cb0ef41Sopenharmony_ci      continue
481cb0ef41Sopenharmony_ci    }
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci}
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci/**
531cb0ef41Sopenharmony_ci * Returns the first file or directory from an array of candidates that is
541cb0ef41Sopenharmony_ci * readable by the current user, or undefined if none of the candidates are
551cb0ef41Sopenharmony_ci * readable.
561cb0ef41Sopenharmony_ci */
571cb0ef41Sopenharmony_cifunction findAccessibleSync (logprefix, dir, candidates) {
581cb0ef41Sopenharmony_ci  for (let next = 0; next < candidates.length; next++) {
591cb0ef41Sopenharmony_ci    const candidate = path.resolve(dir, candidates[next])
601cb0ef41Sopenharmony_ci    let fd
611cb0ef41Sopenharmony_ci    try {
621cb0ef41Sopenharmony_ci      fd = openSync(candidate, 'r')
631cb0ef41Sopenharmony_ci    } catch (e) {
641cb0ef41Sopenharmony_ci      // this candidate was not found or not readable, do nothing
651cb0ef41Sopenharmony_ci      log.silly(logprefix, 'Could not open %s: %s', candidate, e.message)
661cb0ef41Sopenharmony_ci      continue
671cb0ef41Sopenharmony_ci    }
681cb0ef41Sopenharmony_ci    closeSync(fd)
691cb0ef41Sopenharmony_ci    log.silly(logprefix, 'Found readable %s', candidate)
701cb0ef41Sopenharmony_ci    return candidate
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  return undefined
741cb0ef41Sopenharmony_ci}
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_cimodule.exports = {
771cb0ef41Sopenharmony_ci  execFile,
781cb0ef41Sopenharmony_ci  regGetValue,
791cb0ef41Sopenharmony_ci  regSearchKeys,
801cb0ef41Sopenharmony_ci  findAccessibleSync
811cb0ef41Sopenharmony_ci}
82