To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / portaudio_20161030_catalina_patch / src / os / win / pa_win_coinitialize.c @ 164:9fa11135915a

History | View | Annotate | Download (5.11 KB)

1
/*
2
 * Microsoft COM initialization routines
3
 * Copyright (c) 1999-2011 Ross Bencina, Dmitry Kostjuchenko
4
 *
5
 * Based on the Open Source API proposed by Ross Bencina
6
 * Copyright (c) 1999-2011 Ross Bencina, Phil Burk
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining
9
 * a copy of this software and associated documentation files
10
 * (the "Software"), to deal in the Software without restriction,
11
 * including without limitation the rights to use, copy, modify, merge,
12
 * publish, distribute, sublicense, and/or sell copies of the Software,
13
 * and to permit persons to whom the Software is furnished to do so,
14
 * subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be
17
 * included in all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
23
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
24
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
 */
27

    
28
/*
29
 * The text above constitutes the entire PortAudio license; however,
30
 * the PortAudio community also makes the following non-binding requests:
31
 *
32
 * Any person wishing to distribute modifications to the Software is
33
 * requested to send the modifications to the original developer so that
34
 * they can be incorporated into the canonical version. It is also
35
 * requested that these non-binding requests be included along with the
36
 * license above.
37
 */
38

    
39
/** @file
40
 @ingroup win_src
41

42
 @brief Microsoft COM initialization routines.
43
*/
44

    
45
#include <windows.h>
46
#include <objbase.h>
47

    
48
#include "portaudio.h"
49
#include "pa_util.h"
50
#include "pa_debugprint.h"
51

    
52
#include "pa_win_coinitialize.h"
53

    
54

    
55
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) /* MSC version 6 and above */
56
#pragma comment( lib, "ole32.lib" )
57
#endif
58

    
59

    
60
/* use some special bit patterns here to try to guard against uninitialized memory errors */
61
#define PAWINUTIL_COM_INITIALIZED       (0xb38f)
62
#define PAWINUTIL_COM_NOT_INITIALIZED   (0xf1cd)
63

    
64

    
65
PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
66
{
67
    HRESULT hr;
68

    
69
    comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
70

    
71
    /*
72
        If COM is already initialized CoInitialize will either return
73
        FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different
74
        threading mode. In either case we shouldn't consider it an error
75
        but we need to be careful to not call CoUninitialize() if 
76
        RPC_E_CHANGED_MODE was returned.
77
    */
78

    
79
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP)
80
    hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */
81
#else
82
        hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
83
#endif
84
    if( FAILED(hr) && hr != RPC_E_CHANGED_MODE )
85
    {
86
        PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr));
87

    
88
        if( hr == E_OUTOFMEMORY )
89
            return paInsufficientMemory;
90

    
91
        {
92
            char *lpMsgBuf;
93
            FormatMessage(
94
                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
95
                NULL,
96
                hr,
97
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
98
                (LPTSTR) &lpMsgBuf,
99
                0,
100
                NULL
101
            );
102
            PaUtil_SetLastHostErrorInfo( hostApiType, hr, lpMsgBuf );
103
            LocalFree( lpMsgBuf );
104
        }
105

    
106
        return paUnanticipatedHostError;
107
    }
108

    
109
    if( hr != RPC_E_CHANGED_MODE )
110
    {
111
        comInitializationResult->state = PAWINUTIL_COM_INITIALIZED;
112

    
113
        /*
114
            Memorize calling thread id and report warning on Uninitialize if 
115
            calling thread is different as CoInitialize must match CoUninitialize 
116
            in the same thread.
117
        */
118
        comInitializationResult->initializingThreadId = GetCurrentThreadId();
119
    }
120

    
121
    return paNoError;
122
}
123

    
124

    
125
void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
126
{
127
    if( comInitializationResult->state != PAWINUTIL_COM_NOT_INITIALIZED
128
            && comInitializationResult->state != PAWINUTIL_COM_INITIALIZED ){
129
    
130
        PA_DEBUG(("ERROR: PaWinUtil_CoUninitialize called without calling PaWinUtil_CoInitialize\n"));
131
    }
132

    
133
    if( comInitializationResult->state == PAWINUTIL_COM_INITIALIZED )
134
    {
135
        DWORD currentThreadId = GetCurrentThreadId();
136
                if( comInitializationResult->initializingThreadId != currentThreadId )
137
                {
138
                        PA_DEBUG(("ERROR: failed PaWinUtil_CoUninitialize calling thread[%d] does not match initializing thread[%d]\n",
139
                                currentThreadId, comInitializationResult->initializingThreadId));
140
                }
141
                else
142
                {
143
                        CoUninitialize();
144

    
145
            comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
146
                }
147
    }
148
}