如何初始化未注册的COM DLL?

时间:2016-01-14 17:57:31

标签: winapi dll com xaudio2

最近,我们的一些客户从他们的C:/ Windows / System32目录丢失了他们的XAudio2_7.dll,现在他们听不到任何音频。通常重新安装DirectX或注册dll足以解决此问题,但我们正在寻找不需要管理员权限的解决方案。这适用于Windows 7.应用程序是用CPP编写的,其中一些是32位,其余的是64位。

在exe的同一目录中有一个XAudio2_7.dll的本地副本,但除非已注册该dll,否则不会加载该副本,因为它是一个COM dll。注册当前用户(使用“Regsvr32.exe / n / i:user XAudio2_7.dll”)不起作用,因为dll没有实现所需的接口“DllInstall”。

我尝试过的一种方法是静态链接XAudio的.lib而不是使用动态链接。 Microsoft不会使用DirectX SDK分发XAudio2_7.lib。 “没有版本的DirectX SDK包含xaudio2.lib导入库.DirectX SDK版本使用COM创建新的XAudio2对象。” msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.xaudio2.xaudio2create%28v=vs.85%29.aspx

当然,这表明即使我创建一个静态XAudio库也可能无法使用静态XAudio库,因为它听起来像是依赖于其他库中定义的外部对象。如果我的假设不正确,仍然值得测试。

按照此链接中提到的步骤:adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll /

我对这种方法没有太大的了解。在约会的文章之外,有一些问题。博客中的MS链接提到这是针对32位dll。即使对于32位dll,dumpbin也不起作用,因为它只导出了接口函数。     转储文件C:\ XAudioTest \ 32Bit \ XAudio2_7.dll

File Type: DLL

  Section contains the following exports for xaudio2.dll

    00000000 characteristics
    4C064181 time date stamp Wed Jun 02 07:33:21 2010
        0.00 version
           1 ordinal base
           4 number of functions
           4 number of names

    ordinal hint RVA      name

          1    0 00030AA0 DllCanUnloadNow
          2    1 00031150 DllGetClassObject
          3    2 00031470 DllRegisterServer
          4    3 000314D0 DllUnregisterServer

  Summary

        C000 .data
        1000 .no_bbt
        4000 .reloc
        1000 .rsrc
       7B000 .text

后来,我从另一篇MSDN文章中找到了这句话。 “COM标准要求COM DLL导出DllCanUnloadNow,DllGetClassObject,DllRegisterServer和DllUnregisterServer。通常它们不会导出任何其他内容。这意味着您无法使用dumpbin.exe获取COM对象或方法信息。” msdn.microsoft.com/en-us/library/aa446532.aspx

我也尝试过使用第三方程序,声称它可以从COM dll创建.lib。 www.binary-soft.com/dll2lib/dll2lib.htm

虽然这确实生成了32位.lib文件,但使用lib文件编译生成了未解析的外部符号。此实用程序带有处理未解析符号的方法,但在Symbol Finder或Advanced Conversion Options中输入任何内容都会崩溃。查看最新发行说明(3.00),我发现他们添加了对Vista的支持而没有提及Windows 7.此外,这对64位dll也不起作用。

我尝试过另一种方法是更改​​初始化序列以使用此链接中描述的非注册COM DLL:Use COM Object from DLL without register 初始化代码类似于:

    HMODULE audioLib = LoadLibrary(TEXT("XAudio2_7.dll"));
    if (audioLib == NULL)
    {
        debugf(TEXT("Failed to create COM object.  Unable to load XAudio2_7.dll library.  GetLastError:  %d"), GetLastError());
        return;
    }

    typedef HRESULT (WINAPI* Function_DllGCO) (REFCLSID, REFIID, LPVOID*);
    Function_DllGCO processAddress = (Function_DllGCO)GetProcAddress(audioLib, "DllGetClassObject");

    if (processAddress == NULL)
    {
        debugf(TEXT("COM DLL failed to find the process address to interface function 'DllgetClassObject' within the XAudio2_7.dll.  GetLastError:  %d"), GetLastError());
        return;
    }

    class __declspec(uuid("{5a508685-a254-4fba-9b82-9a24b00306af}")) xAudioGUID;
    REFCLSID classID = __uuidof(xAudioGUID);

    class __declspec(uuid("{00000001-0000-0000-c000-000000000046}")) classFactoryGUID;
    REFIID classFactoryID = __uuidof(classFactoryGUID);

    IClassFactory* ClassFactory = NULL;
    if (processAddress(classID, classFactoryID, reinterpret_cast<LPVOID*>(&ClassFactory)) != S_OK)
    {
        debugf(TEXT("Failed to execute function pointer to DLLGetClassObject.  GetLastError:  %d"), GetLastError());
    return;
    }

    class __declspec(uuid("{00000000-0000-0000-C000-000000000046}")) unknownGUID;
    REFIID unknownID = __uuidof(unknownGUID);
    if (ClassFactory->CreateInstance(NULL, unknownID, reinterpret_cast<void**>(&ClassFactory)) != S_OK)
    {
        debugf(TEXT("Class factory for XAudio2_7 failed to create an object instance.  GetLastError:  %d"), GetLastError());
        ClassFactory->Release();
        return;
    }

    if( XAudio2Create( &XAudio2, 0, AUDIO_THREAD) != S_OK ) //Fails here with error number:  1008 (An attempt was made to reference a token that does not exist.)
    {
        debugf( NAME_Init, TEXT( "Failed to create XAudio2 interface:  GetLastError:  %d" ), GetLastError());
        return;
    }
    //Do other things

传递所有WinAPI函数调用,不包括XAudio2Create函数。我不确定为什么XAudio2Create没有使用从工厂创建的对象,我不知道我需要做什么才能让它使用该对象。我还在调查我在这里可以做些什么,但很难调试封闭的源代码库。

在我了解COM DLL之前,我尝试过的方法是使用DLL重定向来强制应用程序使用特定的DLL。使用此处描述的流程:DLL redirection using manifests XAudio2Create仍然失败。我没有一个强有力的策略来确定清单的错误。我还没有找到关于dll重定向清单的最新文档。从这个声音来看,这主要用于加载特定的DLL版本。我不认为DLL重定向是我需要的方法,因为在exe的同一目录中已经存在XAudio2_7的本地副本,这意味着它应该优先于系统目录中的XAudio2_7,具体如下:msdn.microsoft.com /en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx

注意:我删除了某些地址的超链接,因为我没有足够的信誉点来发布超过2个链接。

1 个答案:

答案 0 :(得分:2)

您是否尝试过registration-free activation