0

我尝试在我的程序安装程序中集成根证书安装。我必须从证书创建一个对象,然后将其添加到商店。

const std::string cert = R"cert(
-----BEGIN CERTIFICATE-----
/***/
-----END CERTIFICATE-----
)cert";

PCCERT_CONTEXT pCertCtx = NULL;
CRYPT_INTEGER_BLOB blob;
blob.pbData = (BYTE*)cert.c_str();

bool result = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
                               CERT_QUERY_CONTENT_FLAG_CERT,         
                               CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED,
                               0, NULL, NULL, NULL, NULL, NULL, (const void**)&pCertCtx);
            if (!result) {
                    DWORD errorMessageID = ::GetLastError();

                    LPSTR messageBuffer = nullptr;
                    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                                FORMAT_MESSAGE_FROM_SYSTEM |
                                                FORMAT_MESSAGE_IGNORE_INSERTS,
                                                NULL, errorMessageID,
                                                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
                                                (LPSTR)&messageBuffer, 0, NULL);

                    std::string message(messageBuffer, size);
                    //Free the buffer.
                    LocalFree(messageBuffer);
                    return ERROR_INSTALL_FAILURE;
            }

我用这个自定义操作制作了自己的 dll 并将其添加到 WiX。

    <Binary Id="pathFixer" SourceFile="$(var.product.inputFilesDir)\path-fixer.dll" />
    <Binary Id="additionalActions" SourceFile="$(var.product.inputFilesDir)\additional-actions.dll" />

    <CustomAction Id="SetNativeMessageHostPath" BinaryKey="pathFixer" DllEntry="SetNativeMessageHostPath" Execute="deferred" Impersonate="no"/>
    <CustomAction Id="SetInstallDir" Property="SetNativeMessageHostPath" Value="[INSTALLDIR]" Execute="immediate" />

    <CustomAction Id="installRootCert" BinaryKey="additionalActions" DllEntry="installRootCert" Execute="deferred" Impersonate="no"/>

    <CustomAction Id="ResetOldVersionFound" Property="OTHER_VERSION_FOUND" Value="" Execute="immediate" />
    <CustomAction Id="GetPerUserOldVersionFound" Property="USER_OTHER_VERSION_FOUND" Value="[OTHER_VERSION_FOUND]" Execute="immediate" />
    <CustomAction Id="GetPerMachineOldVersionFound" Property="MACHINE_OTHER_VERSION_FOUND" Value="[OTHER_VERSION_FOUND]" Execute="immediate" />
    <CustomAction Id="SetPerUserOldVersionToRemove" Property="OTHER_VERSION_FOUND" Value="[USER_OTHER_VERSION_FOUND]" Execute="immediate" />
    <CustomAction Id="SetPerMachineOldVersionToRemove" Property="OTHER_VERSION_FOUND" Value="[MACHINE_OTHER_VERSION_FOUND]" Execute="immediate" />

    <InstallExecuteSequence>
        <Custom Action="SetPerUserOldVersionToRemove" Before="RemoveExistingProducts">MSIINSTALLPERUSER=1</Custom>
        <Custom Action="SetPerMachineOldVersionToRemove" Before="RemoveExistingProducts">MSIINSTALLPERUSER=""</Custom>
        <Custom Action="SetInstallDir" After="InstallInitialize"/>
        <RemoveExistingProducts After="InstallInitialize" />
        <InstallExecute After="RemoveExistingProducts" />
    </InstallExecuteSequence>

    <Media Id="1" Cabinet="$(var.project.name).cab" EmbedCab="yes" CompressionLevel="high" />

    <CustomAction Id="SetPerUserFolder" Directory="APPLICATIONFOLDER" Value="[AppDataFolder]" Execute="immediate" />
    <CustomAction Id="SetPerMachineFolder" Directory="APPLICATIONFOLDER" Value="[ProgramFilesFolder]" Execute="immediate" />

    <InstallExecuteSequence>
        <Custom Action="SetPerUserFolder" After="CostFinalize">NOT Installed AND MSIINSTALLPERUSER=1</Custom>
        <Custom Action="SetPerMachineFolder" After="SetPerUserFolder">NOT Installed AND MSIINSTALLPERUSER=""</Custom>
        <Custom Action="SetNativeMessageHostPath" After="PublishProduct">NOT REMOVE</Custom>
        <Custom Action="installRootCert" After="PublishProduct">NOT REMOVE</Custom>
    </InstallExecuteSequence>

调试直接说执行了安装功能。但是通过一些神奇的操作,比如加入 MessageBox、调试,我从周期CryptQueryObject truefalse获取,但不是系统地。GetLastErrorParameter is incorrect。为什么会发生这种情况?

4

1 回答 1

0

我解决它只是在 call 之前添加数据的计数(以字节为单位)CryptQueryObject

blob.cbData = cert.length();

小心结构数据。

于 2018-12-13T08:44:32.077 回答