Пример #1
0
void CBSThirdPartyPM::detectOneCBSPackageUpdate(
        const QString& superPackage,
        QList<InstalledPackageVersion*>* installed,
        Repository *rep,
        const QString& registryPath,
        WindowsRegistry& k,
        bool superPackageInstalled) const
{
    QString err;
    QStringList values = k.listValues(&err);

    if (err.isEmpty()) {
        for (int i = 0; i < values.size(); i++) {
            QString name = values.at(i);
            DWORD value = k.getDWORD(name, &err);
            if (!err.isEmpty())
                break;

            QString shortPackageName = name;
            shortPackageName.replace('-', '.');
            QString packageName = WPMUtils::makeValidFullPackageName(
                    superPackage + "." + shortPackageName);

            QString title = name;
            title.replace('-', ' ');

            QScopedPointer<Package> p(new Package(packageName, title));
            p->description = title; // TODO
            p->categories.append(QObject::tr("Component-Based Servicing"));
            rep->savePackage(p.data(), true);

            Version version;

            QScopedPointer<PackageVersion> pv(new PackageVersion(packageName));
            pv->version = version;
            PackageVersionFile* pvf = new PackageVersionFile(
                    ".Npackd\\Uninstall.bat", "\r\n"); // TODO
            pv->files.append(pvf);
            rep->savePackageVersion(pv.data(), true);

            if (superPackageInstalled && value == 1) {
                InstalledPackageVersion* ipv = new InstalledPackageVersion(
                        packageName,
                        version, "");
                ipv->detectionInfo = "cbs:" + registryPath + "\\" + name;
                installed->append(ipv);
            }
        }
    }
}
Пример #2
0
QStringList AbstractRepository::getRepositoryURLs(HKEY hk, const QString& path,
        QString* err, bool* keyExists)
{
    *keyExists = false;

    WindowsRegistry wr;
    *err = wr.open(hk, path, false, KEY_READ);
    QStringList urls;
    if (err->isEmpty()) {
        *keyExists = true;
        int size = wr.getDWORD("size", err);
        if (err->isEmpty()) {
            for (int i = 1; i <= size; i++) {
                WindowsRegistry er;
                *err = er.open(wr, QString("%1").arg(i), KEY_READ);
                if (err->isEmpty()) {
                    QString url = er.get("repository", err);
                    if (err->isEmpty())
                        urls.append(url);
                }
            }

            // ignore any errors while reading the entries
            *err = "";
        }
    }

    return urls;
}
Пример #3
0
void CBSThirdPartyPM::
        detectCBSPackagesFrom(QList<InstalledPackageVersion*>* installed,
        Repository* rep, HKEY root,
        const QString& path, bool useWoWNode) const {
    WindowsRegistry wr;
    QString err;
    err = wr.open(root, path, useWoWNode, KEY_READ);
    if (err.isEmpty()) {
        QString fullPath;
        if (root == HKEY_CLASSES_ROOT)
            fullPath = "HKEY_CLASSES_ROOT";
        else if (root == HKEY_CURRENT_USER)
            fullPath = "HKEY_CURRENT_USER";
        else if (root == HKEY_LOCAL_MACHINE)
            fullPath = "HKEY_LOCAL_MACHINE";
        else if (root == HKEY_USERS)
            fullPath = "HKEY_USERS";
        else if (root == HKEY_PERFORMANCE_DATA)
            fullPath = "HKEY_PERFORMANCE_DATA";
        else if (root == HKEY_CURRENT_CONFIG)
            fullPath = "HKEY_CURRENT_CONFIG";
        else if (root == HKEY_DYN_DATA)
            fullPath = "HKEY_DYN_DATA";
        else
            fullPath = QString("%1").arg((uintptr_t) root);
        fullPath += "\\" + path;

        QStringList entries = wr.list(&err);
        for (int i = 0; i < entries.count(); i++) {
            WindowsRegistry k;
            err = k.open(wr, entries.at(i), KEY_READ);
            if (err.isEmpty()) {
                detectOneCBSPackage(installed, rep,
                        fullPath + "\\" + entries.at(i),
                        k, entries.at(i));
            }
        }
    }
}
SettingsFrame::SettingsFrame(QWidget *parent) :
    QFrame(parent),
    ui(new Ui::SettingsFrame)
{
    ui->setupUi(this);

    WindowsRegistry wr;
    QString err = wr.open(HKEY_LOCAL_MACHINE,
            "Software\\Npackd\\Npackd\\InstallationDirs", false, KEY_READ);
    QStringList dirs;
    if (err.isEmpty()) {
        dirs = wr.loadStringList(&err);
    }

    dirs.append(WPMUtils::getInstallationDirectory());
    dirs.append(WPMUtils::getProgramFilesDir());
    if (WPMUtils::is64BitWindows())
        dirs.append(WPMUtils::getShellDir(CSIDL_PROGRAM_FILESX86));

    dirs.removeDuplicates();
    this->ui->comboBoxDir->addItems(dirs);
}
Пример #5
0
void AbstractRepository::setRepositoryURLs(QList<QUrl*>& urls, QString* err)
{
    WindowsRegistry wr;
    *err = wr.open(HKEY_LOCAL_MACHINE, "",
            false, KEY_CREATE_SUB_KEY);
    if (err->isEmpty()) {
        WindowsRegistry wrr = wr.createSubKey(
                "Software\\Npackd\\Npackd\\Reps", err,
                KEY_ALL_ACCESS);
        if (err->isEmpty()) {
            wrr.setDWORD("size", urls.count());
            for (int i = 0; i < urls.count(); i++) {
                WindowsRegistry r = wrr.createSubKey(QString("%1").arg(i + 1),
                        err, KEY_ALL_ACCESS);
                if (err->isEmpty()) {
                    r.set("repository", urls.at(i)->toString());
                }
            }
        }
    }
}
Пример #6
0
QString InstalledPackages::saveToRegistry(InstalledPackageVersion *ipv)
{
    WindowsRegistry machineWR(HKEY_LOCAL_MACHINE, false);
    QString r;
    QString keyName = "SOFTWARE\\Npackd\\Npackd\\Packages";
    Version v = ipv->version;
    v.normalize();
    QString pn = ipv->package + "-" + v.getVersionString();

    /*WPMUtils::outputTextConsole(
            "InstalledPackages::saveToRegistry " + ipv->directory + " " +
            ipv->package + " " + ipv->version.getVersionString() + " " +
            ipv->detectionInfo + "\r\n");*/

    if (!ipv->directory.isEmpty()) {
        WindowsRegistry wr = machineWR.createSubKey(keyName + "\\" + pn, &r);
        if (r.isEmpty()) {
            wr.set("DetectionInfo", ipv->detectionInfo);

            // for compatibility with Npackd 1.16 and earlier. They
            // see all package versions by default as "externally installed"
            wr.setDWORD("External", 0);

            r = wr.set("Path", ipv->directory);
        }
        // qDebug() << "saveToRegistry 1 " << r;
    } else {
        // qDebug() << "deleting " << pn;
        WindowsRegistry packages;
        r = packages.open(machineWR, keyName, KEY_ALL_ACCESS);
        if (r.isEmpty()) {
            r = packages.remove(pn);
        }
        // qDebug() << "saveToRegistry 2 " << r;
    }
    //qDebug() << "InstalledPackageVersion::save " << pn << " " <<
    //        this->directory;

    // qDebug() << "saveToRegistry returns " << r;

    return r;
}
Пример #7
0
QString InstalledPackages::findPath_npackdcl(const Dependency& dep)
{
    QString ret;

    QString err;
    WindowsRegistry packagesWR;
    LONG e;
    err = packagesWR.open(HKEY_LOCAL_MACHINE,
            "SOFTWARE\\Npackd\\Npackd\\Packages", false, KEY_READ, &e);

    if (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) {
        err = "";
    } else if (err.isEmpty()) {
        Version found = Version::EMPTY;

        QStringList entries = packagesWR.list(&err);
        for (int i = 0; i < entries.count(); ++i) {
            QString name = entries.at(i);
            int pos = name.lastIndexOf("-");
            if (pos <= 0)
                continue;

            QString packageName = name.left(pos);
            if (packageName != dep.package)
                continue;

            QString versionName = name.right(name.length() - pos - 1);
            Version version;
            if (!version.setVersion(versionName))
                continue;

            if (!dep.test(version))
                continue;

            if (found != Version::EMPTY) {
                if (version.compare(found) < 0)
                    continue;
            }

            WindowsRegistry entryWR;
            err = entryWR.open(packagesWR, name, KEY_READ);
            if (!err.isEmpty())
                continue;

            QString p = entryWR.get("Path", &err).trimmed();
            if (!err.isEmpty())
                continue;

            QString dir;
            if (p.isEmpty())
                dir = "";
            else {
                QDir d(p);
                if (d.exists()) {
                    dir = p;
                } else {
                    dir = "";
                }
            }

            if (dir.isEmpty())
                continue;

            found = version;
            ret = dir;
        }
    }

    return ret;
}
Пример #8
0
QString InstalledPackages::readRegistryDatabase()
{
    // qDebug() << "start reading registry database";

    // "data" is only used at the bottom of this method

    QString err;

    WindowsRegistry packagesWR;
    LONG e;
    err = packagesWR.open(HKEY_LOCAL_MACHINE,
            "SOFTWARE\\Npackd\\Npackd\\Packages", false, KEY_READ, &e);

    QList<InstalledPackageVersion*> ipvs;
    if (e == ERROR_FILE_NOT_FOUND || e == ERROR_PATH_NOT_FOUND) {
        err = "";
    } else if (err.isEmpty()) {
        QStringList entries = packagesWR.list(&err);
        for (int i = 0; i < entries.count(); ++i) {
            QString name = entries.at(i);
            int pos = name.lastIndexOf("-");
            if (pos <= 0)
                continue;

            QString packageName = name.left(pos);
            if (!Package::isValidName(packageName))
                continue;

            QString versionName = name.right(name.length() - pos - 1);
            Version version;
            if (!version.setVersion(versionName))
                continue;

            WindowsRegistry entryWR;
            err = entryWR.open(packagesWR, name, KEY_READ);
            if (!err.isEmpty())
                continue;

            QString p = entryWR.get("Path", &err).trimmed();
            if (!err.isEmpty())
                continue;

            QString dir;
            if (p.isEmpty())
                dir = "";
            else {
                QDir d(p);
                if (d.exists()) {
                    dir = p;
                } else {
                    dir = "";
                }
            }

            if (dir.isEmpty()) {
                packagesWR.remove(name);
            } else {
                dir = WPMUtils::normalizePath(dir, false);

                InstalledPackageVersion* ipv = new InstalledPackageVersion(
                        packageName, version, dir);
                ipv->detectionInfo = entryWR.get("DetectionInfo", &err);
                if (!err.isEmpty()) {
                    // ignore
                    ipv->detectionInfo = "";
                    err = "";
                }

                if (!ipv->directory.isEmpty()) {
                    /*
                    qDebug() << "adding " << ipv->package <<
                            ipv->version.getVersionString() << "in" <<
                            ipv->directory;*/
                    ipvs.append(ipv);
                } else {
                    delete ipv;
                }
            }
        }
    }

    this->mutex.lock();
    qDeleteAll(this->data);
    this->data.clear();
    for (int i = 0; i < ipvs.count(); i++) {
        InstalledPackageVersion* ipv = ipvs.at(i);
        this->data.insert(PackageVersion::getStringId(ipv->package,
                ipv->version), ipv->clone());
    }
    this->mutex.unlock();

    for (int i = 0; i < ipvs.count(); i++) {
        InstalledPackageVersion* ipv = ipvs.at(i);
        fireStatusChanged(ipv->package, ipv->version);
    }
    qDeleteAll(ipvs);

    // qDebug() << "stop reading";

    return err;
}
Пример #9
0
void CBSThirdPartyPM::detectOneCBSPackage(
        QList<InstalledPackageVersion*>* installed,
        Repository *rep,
        const QString& registryPath,
        WindowsRegistry& k,
        const QString& keyName) const
{
    QString err;

    QStringList keyNameParts = keyName.split('~');

    if (keyNameParts.size() != 5) {
        err = "Wrong number of parts";
    }

    // find the package name
    QString package;

    if (err.isEmpty()) {
        package = keyNameParts.at(0);
        package.replace('-', '.');
        package = WPMUtils::makeValidFullPackageName(
                "cbs." + package);
    }

    if (err.isEmpty()) {
        QString title = keyNameParts.at(0);
        title.replace('-', ' ');
        QScopedPointer<Package> p(new Package(package, title));
        p->categories.append(QObject::tr("Component-Based Servicing"));
        rep->savePackage(p.data(), true);
    }

    // find the version number
    Version version;
    if (err.isEmpty()) {
        if (version.setVersion(keyNameParts.at(4))) {
            version.normalize();
        } else {
            err = "Invalid version number";
        }
    }

    if (err.isEmpty()) {
        QScopedPointer<PackageVersion> pv(new PackageVersion(package));
        pv->version = version;
        PackageVersionFile* pvf = new PackageVersionFile(
                ".Npackd\\Uninstall.bat", "\r\n"); // TODO
        pv->files.append(pvf);
        rep->savePackageVersion(pv.data(), true);
    }

    DWORD state = 0;
    if (err.isEmpty()) {
        state = k.getDWORD("CurrentState", &err);
    }

    bool packageInstalled = false;

    if (err.isEmpty()) {
        if (state & 0x20) {
            InstalledPackageVersion* ipv = new InstalledPackageVersion(package,
                    version, "");
            ipv->detectionInfo = "cbs:" + registryPath;
            installed->append(ipv);

            packageInstalled = true;
        }
    }

    if (!err.isEmpty()) {
        qDebug() << keyName << err;
    }

    if (err.isEmpty()) {
        WindowsRegistry updates;
        err = updates.open(k, "Updates", KEY_READ);
        if (err.isEmpty())
            detectOneCBSPackageUpdate(package, installed, rep,
                    registryPath + "\\Updates",
                    updates, packageInstalled);
    }
}
void SettingsFrame::on_buttonBox_clicked(QAbstractButton *button)
{
    MainWindow* mw = MainWindow::getInstance();

    if (mw->hardDriveScanRunning) {
        mw->addErrorMessage(QObject::tr("Cannot change settings now. The hard drive scan is running."));
        return;
    }

    QString err;
    PackageVersion* locked = PackageVersion::findLockedPackageVersion(&err);
    if (locked) {
        err = QObject::tr("Cannot find locked package versions: %1").
                arg(err);
        mw->addErrorMessage(err);
        delete locked;
        return;
    }

    if (locked) {
        QString msg(QObject::tr("Cannot change settings now. The package %1 is locked by a currently running installation/removal."));
        mw->addErrorMessage(msg.arg(locked->toString()));
        delete locked;
        return;
    }

    QStringList list = getRepositoryURLs();

    if (err.isEmpty() && list.count() == 0)
        err = QObject::tr("No repositories defined");

    if (err.isEmpty()) {
        err = WPMUtils::checkInstallationDirectory(getInstallationDirectory());
    }

    QList<QUrl*> urls;
    if (err.isEmpty()) {
        for (int i = 0; i < list.count(); i++) {
            QUrl* url = new QUrl(list.at(i));
            urls.append(url);
            if (!url->isValid()) {
                err = QString(QObject::tr("%1 is not a valid repository address")).arg(
                        list.at(i));
                break;
            }
        }
    }

    if (err.isEmpty()) {
        WPMUtils::setInstallationDirectory(getInstallationDirectory());
        WPMUtils::setCloseProcessType(getCloseProcessType());
    }

    bool repsChanged = false;

    if (err.isEmpty()) {
        QList<QUrl*> oldList = Repository::getRepositoryURLs(&err);
        repsChanged = oldList.count() != urls.count();
        if (!repsChanged) {
            for (int i = 0; i < oldList.count(); i++) {
                if ((*oldList.at(i)) != (*urls.at(i))) {
                    repsChanged = true;
                    break;
                }
            }
        }
        qDeleteAll(oldList);
        oldList.clear();
    }

    if (err.isEmpty()) {
        if (repsChanged) {
            if (mw->reloadRepositoriesThreadRunning) {
                err = QObject::tr("Cannot change settings now. The repositories download is running.");
            } else {
                Repository::setRepositoryURLs(urls, &err);
                if (err.isEmpty()) {
                    mw->closeDetailTabs();
                    mw->recognizeAndLoadRepositories(false);
                }
            }
        }
    }

    qDeleteAll(urls);
    urls.clear();

    if (err.isEmpty()) {
        WindowsRegistry m(HKEY_LOCAL_MACHINE, false, KEY_ALL_ACCESS);
        WindowsRegistry wr = m.createSubKey(
                "Software\\Npackd\\Npackd\\InstallationDirs", &err,
                KEY_ALL_ACCESS);

        QStringList dirs;
        for (int i = 0; i < this->ui->comboBoxDir->count(); i++)
            dirs.append(this->ui->comboBoxDir->itemText(i));
        if (err.isEmpty()) {
            wr.saveStringList(dirs);
        }

        // it is not important, whether the list of directories is saved or not
        err = "";
    }

    if (!err.isEmpty())
        mw->addErrorMessage(err, err, true, QMessageBox::Critical);
}
void ControlPanelThirdPartyPM::detectOneControlPanelProgram(
        QList<InstalledPackageVersion*>* installed,
        Repository *rep,
        const QString& registryPath,
        WindowsRegistry& k,
        const QString& keyName) const
{
    // see http://msdn.microsoft.com/en-us/library/aa372105(v=vs.85).aspx

    // find the package name
    QString package = keyName;
    package.replace('.', '_');
    package = WPMUtils::makeValidFullPackageName(
            "control-panel." + package);

    // find the version number
    bool versionFound = false;
    Version version;
    QString err;
    QString version_ = k.get("DisplayVersion", &err);
    if (err.isEmpty()) {
        if (version.setVersion(version_)) {
            version.normalize();
            versionFound = true;
        }
    }
    if (!versionFound) {
        DWORD major = k.getDWORD("VersionMajor", &err);
        if (err.isEmpty()) {
            DWORD minor = k.getDWORD("VersionMinor", &err);
            if (err.isEmpty())
                version.setVersion(major, minor);
            else
                version.setVersion(major, 0);
            version.normalize();
            versionFound = true;
        }
    }
    if (!versionFound) {
        QString major = k.get("VersionMajor", &err);
        if (err.isEmpty()) {
            QString minor = k.get("VersionMinor", &err);
            if (err.isEmpty()) {
                if (version.setVersion(major)) {
                    versionFound = true;
                    version.normalize();
                }
            } else {
                if (version.setVersion(major + "." + minor)) {
                    versionFound = true;
                    version.normalize();
                }
            }
        }
    }
    if (!versionFound) {
        QString displayName = k.get("DisplayName", &err);
        if (err.isEmpty()) {
            QStringList parts = displayName.split(' ');
            if (parts.count() > 1 && parts.last().contains('.')) {
                version.setVersion(parts.last());
                version.normalize();
            }
        }
    }

    //qDebug() << "InstalledPackages::detectOneControlPanelProgram.0";

    QScopedPointer<Package> p(new Package(package, package));

    QString title = k.get("DisplayName", &err);
    if (!err.isEmpty() || title.isEmpty())
        title = keyName;
    p->title = title;
    p->description = "[Control Panel] " + p->title;

    QString url = k.get("URLInfoAbout", &err);
    if (!err.isEmpty() || url.isEmpty() || !QUrl(url).isValid())
        url = "";
    if (url.isEmpty())
        url = k.get("URLUpdateInfo", &err);
    if (!err.isEmpty() || url.isEmpty() || !QUrl(url).isValid())
        url = "";
    p->url = url;

    p->setChangeLog(k.get("URLUpdateInfo", &err));
    if (!err.isEmpty() || !Package::isValidURL(p->getChangeLog()))
        p->setChangeLog("");

    p->categories.append(QObject::tr("Control panel software"));

    QString icon = k.get("DisplayIcon", &err);
    if (err.isEmpty())
        p->setIcon(WPMUtils::extractIconURL(icon));

    // Crystal Icons
    // p->icon = "data:image/png;base64,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";

    //qDebug() << "CP: adding package " << p.data()->name << p.data()->title;

    rep->savePackage(p.data());

    QDir d;

    bool useThisEntry = true;

    QString uninstall;
    if (useThisEntry) {
        uninstall = k.get("QuietUninstallString", &err);
        if (!err.isEmpty())
            uninstall = "";
        if (uninstall.isEmpty())
            uninstall = k.get("UninstallString", &err);
        if (!err.isEmpty())
            uninstall = "";

        // some programs store in UninstallString the complete path to
        // the uninstallation program with spaces
        if (!uninstall.isEmpty() && uninstall.contains(" ") &&
                !uninstall.contains("\"") &&
                d.exists(uninstall))
            uninstall = "\"" + uninstall + "\"";

        if (uninstall.trimmed().isEmpty())
            useThisEntry = false;

        // qDebug() << uninstall;
    }

    // already detected as an MSI package
    if (uninstall.length() == 14 + 38 &&
            (uninstall.indexOf("MsiExec.exe /X", 0, Qt::CaseInsensitive) == 0 ||
            uninstall.indexOf("MsiExec.exe /I", 0, Qt::CaseInsensitive) == 0) &&
            WPMUtils::validateGUID(uninstall.right(38)) == "") {
        useThisEntry = false;
    }

    QString dir;
    if (useThisEntry) {
        dir = k.get("InstallLocation", &err);
        if (!err.isEmpty() || dir.trimmed().isEmpty() || !d.exists(dir))
            dir = "";

        if (dir.isEmpty() && !uninstall.isEmpty()) {
            QStringList params = WPMUtils::parseCommandLine(uninstall, &err);
            // qDebug() << uninstall << params.count();
            if (err.isEmpty() && params.count() > 0) {
                if (!params[0].trimmed().isEmpty() && d.exists(params[0])) {
                    dir = WPMUtils::parentDirectory(params[0]);
                } else
                    useThisEntry = false;
            } /* DEBUG else {
                qDebug() << "cannot parse " << uninstall << " " << err <<
                        " " << params.count();
                if (params.count() > 0)
                    qDebug() << "cannot parse2 " << params[0] << " " <<
                            d.exists(params[0]);
            }*/
        }
    }

    if (useThisEntry) {
        if (!dir.isEmpty()) {
            dir = WPMUtils::normalizePath(dir, false);
        }
    }

    if (useThisEntry) {
        // qDebug() << "adding " << registryPath << package << dir;

        // qDebug() << package << version.getVersionString() << dir;
        InstalledPackageVersion* ipv = new InstalledPackageVersion(package,
                version, dir);
        ipv->detectionInfo = "control-panel:" + registryPath;
        installed->append(ipv);

        QScopedPointer<PackageVersion> pv(new PackageVersion(package));
        pv->version = version;

        PackageVersionFile* pvf = new PackageVersionFile(
                ".Npackd\\Uninstall.bat", uninstall + "\r\n");
        pv->files.append(pvf);

        pvf = new PackageVersionFile(
                ".Npackd\\Stop.bat",
                "rem the program should be stopped by the uninstaller\r\n");
        pv->files.append(pvf);

        rep->savePackageVersion(pv.data());
    }
}