在' _coreaudiod'下停止并重新启动CoreAudio守护程序用户而不是root

时间:2014-03-28 12:24:11

标签: c++ macos core-audio root daemon

我正在开发一款需要独家访问USB声音设备的应用。我发现当使用此设备播放音乐时,有时无法访问。所以我需要停止并重启CoreAudio守护进程 我正在使用这段代码(下面)来使它工作。但问题是在coreaudiod停止后我只能在root用户下运行它。默认情况下,它在_coreaudiod用户下运行。 如何在操作系统完成后在_coreaudiod用户下运行?

#include <CoreFoundation/CFDictionary.h>
#include <Security/Authorization.h>

class ScopedAudioServiceStopper
{
public:
    ScopedAudioServiceStopper();
    ~ScopedAudioServiceStopper();
    void stop();

private:
    void start();

private:
    AuthorizationRef m_authorizationRef;
    CFDictionaryRef m_coreAudiodDictionary;
};
ScopedAudioServiceStopper::~ScopedAudioServiceStopper()
{
    start();
    if (m_coreAudiodDictionary)
            CFRelease(m_coreAudiodDictionary);
    if (m_authorizationRef)
            AuthorizationFree(m_authorizationRef, kAuthorizationFlagDestroyRights);
}

void ScopedAudioServiceStopper::stop()
{
    m_coreAudiodDictionary = SMJobCopyDictionary(kSMDomainSystemLaunchd, CFSTR("com.apple.audio.coreaudiod"));
    if (!m_coreAudiodDictionary) //means daemon is not started
            return;

    if (errAuthorizationSuccess != AuthorizationCreate(nullptr, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &m_authorizationRef)) {
            m_authorizationRef = nullptr;
            return;
    }

    AuthorizationItem authItem          = { kSMRightModifySystemDaemons, 0, nullptr, 0 };
    AuthorizationRights authRights  = { 1, &authItem };
    AuthorizationFlags flags                =   kAuthorizationFlagDefaults                          |
                                                                            kAuthorizationFlagInteractionAllowed        |
                                                                            kAuthorizationFlagPreAuthorize                  |
                                                                            kAuthorizationFlagExtendRights;
    // Obtain the right to install our privileged helper tool (kSMRightModifySystemDaemons).
    if (errAuthorizationSuccess != AuthorizationCopyRights(m_authorizationRef, &authRights, kAuthorizationEmptyEnvironment, flags, nullptr)) {
            m_authorizationRef = nullptr;
            return;
    }

    CFErrorRef  cfError;
    if (!SMJobRemove(kSMDomainSystemLaunchd, CFSTR("com.apple.audio.coreaudiod"), m_authorizationRef, TRUE, &cfError)) {
            CFRelease(cfError);
    }
}

void ScopedAudioServiceStopper::start()
{
    if (!m_authorizationRef || !m_coreAudiodDictionary)
            return;

    CFErrorRef  cfError;
    if (!SMJobSubmit(kSMDomainSystemLaunchd, m_coreAudiodDictionary, m_authorizationRef, &cfError)) {
            CFRelease(cfError);
    }
}

0 个答案:

没有答案