Skip to content

Commit

Permalink
w32 fix: re-initialization of COM no longer causes NFD to fail
Browse files Browse the repository at this point in the history
semantic compress COM lifetime handling
#72
  • Loading branch information
mlabbe committed Sep 27, 2019
1 parent b950c3d commit 51287f6
Showing 1 changed file with 56 additions and 48 deletions.
104 changes: 56 additions & 48 deletions src/nfd_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@
#include "nfd_common.h"


#define COM_INITFLAGS ::COINIT_APARTMENTTHREADED | ::COINIT_DISABLE_OLE1DDE

static BOOL COMIsInitialized(HRESULT coResult)
{
if (coResult == RPC_E_CHANGED_MODE)
{
// If COM was previously initialized with different init flags,
// NFD still needs to operate. Eat this warning.
return TRUE;
}

return SUCCEEDED(coResult);
}

static HRESULT COMInit(void)
{
return ::CoInitializeEx(NULL, COM_INITFLAGS);
}

static void COMUninit(HRESULT coResult)
{
// do not uninitialize if RPC_E_CHANGED_MODE occurred -- this
// case does not refcount COM.
if (SUCCEEDED(coResult))
::CoUninitialize();
}

// allocs the space in outPath -- call free()
static void CopyWCharToNFDChar( const wchar_t *inStr, nfdchar_t **outStr )
{
Expand Down Expand Up @@ -364,22 +391,17 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
nfdchar_t **outPath )
{
nfdresult_t nfdResult = NFD_ERROR;

// Init COM library.
HRESULT coResult = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );

::IFileOpenDialog *fileOpenDialog(NULL);

if ( !SUCCEEDED(coResult))
{
fileOpenDialog = NULL;

HRESULT coResult = COMInit();
if (!COMIsInitialized(coResult))
{
NFDi_SetError("Could not initialize COM.");
goto end;
return nfdResult;
}

// Create dialog
::IFileOpenDialog *fileOpenDialog(NULL);
HRESULT result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
CLSCTX_ALL, ::IID_IFileOpenDialog,
reinterpret_cast<void**>(&fileOpenDialog) );
Expand Down Expand Up @@ -449,8 +471,7 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
if (fileOpenDialog)
fileOpenDialog->Release();

if (SUCCEEDED(coResult))
::CoUninitialize();
COMUninit(coResult);

return nfdResult;
}
Expand All @@ -460,20 +481,17 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
nfdpathset_t *outPaths )
{
nfdresult_t nfdResult = NFD_ERROR;

// Init COM library.
HRESULT coResult = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
if ( !SUCCEEDED(coResult))


HRESULT coResult = COMInit();
if (!COMIsInitialized(coResult))
{
NFDi_SetError("Could not initialize COM.");
return NFD_ERROR;
NFDi_SetError("Could not initialize COM.");
return nfdResult;
}

::IFileOpenDialog *fileOpenDialog(NULL);

// Create dialog
::IFileOpenDialog *fileOpenDialog(NULL);
HRESULT result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
CLSCTX_ALL, ::IID_IFileOpenDialog,
reinterpret_cast<void**>(&fileOpenDialog) );
Expand Down Expand Up @@ -547,8 +565,7 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
if ( fileOpenDialog )
fileOpenDialog->Release();

if (SUCCEEDED(coResult))
::CoUninitialize();
COMUninit(coResult);

return nfdResult;
}
Expand All @@ -558,20 +575,16 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
nfdchar_t **outPath )
{
nfdresult_t nfdResult = NFD_ERROR;

// Init COM library.
HRESULT coResult = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
if ( !SUCCEEDED(coResult))

HRESULT coResult = COMInit();
if (!COMIsInitialized(coResult))
{
NFDi_SetError("Could not initialize COM.");
return NFD_ERROR;
return nfdResult;
}

::IFileSaveDialog *fileSaveDialog(NULL);


// Create dialog
::IFileSaveDialog *fileSaveDialog(NULL);
HRESULT result = ::CoCreateInstance(::CLSID_FileSaveDialog, NULL,
CLSCTX_ALL, ::IID_IFileSaveDialog,
reinterpret_cast<void**>(&fileSaveDialog) );
Expand Down Expand Up @@ -642,9 +655,8 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
if ( fileSaveDialog )
fileSaveDialog->Release();

if (SUCCEEDED(coResult))
::CoUninitialize();

COMUninit(coResult);

return nfdResult;
}

Expand All @@ -655,18 +667,15 @@ nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,
{
nfdresult_t nfdResult = NFD_ERROR;

// Init COM
HRESULT coResult = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE);
if (!SUCCEEDED(coResult))
HRESULT coResult = COMInit();
if (!COMIsInitialized(coResult))
{
NFDi_SetError("CoInitializeEx failed.");
return NFD_ERROR;
return nfdResult;
}

// Create dialog
::IFileOpenDialog *fileDialog(NULL);

if (!SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog,
NULL,
CLSCTX_ALL,
Expand Down Expand Up @@ -747,9 +756,8 @@ nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,

if (fileDialog)
fileDialog->Release();

if (SUCCEEDED(coResult))
::CoUninitialize();

COMUninit(coResult);

return nfdResult;
}

0 comments on commit 51287f6

Please sign in to comment.