windows-nt/Source/XPSP1/NT/base/win32/fusion/appweek/common/create.cpp

72 lines
2.2 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "stdinc.h"
#include "SxApwHandle.h"
#include "SxApwCreate.h"
typedef HRESULT (STDMETHODCALLTYPE* PFN_DLL_GET_CLASS_OBJECT)(REFCLSID rclsid, REFIID riid, LPVOID* ppv);
HRESULT
SxApwCreateObject(
REFCLSID rclsid,
REFIID riid,
void** pp
)
/*
Strategy:
Enumerate .dlls in the same directory as the .exe, calling DllGetClassObject on each, etc..
This is subject to change.
This code is presently shared both by the host and the managers...maybe this is wrong.
*/
{
HRESULT hr = E_FAIL;
CFindFile findFile;
WCHAR exePath[MAX_PATH];
WIN32_FIND_DATAW findData;
PWSTR filePart;
GetModuleFileName(GetModule()->m_hInst, exePath, RTL_NUMBER_OF(exePath));
filePart = 1 + wcsrchr(exePath, '\\');
wcscpy(filePart, L"*.dll");
if (findFile.Win32Create(exePath, &findData))
{
do
{
PCWSTR dot = wcsrchr(findData.cFileName, '.');
if (dot != NULL && _wcsicmp(dot, L".dll") == 0)
{
CDynamicLinkLibrary dll;
PFN_DLL_GET_CLASS_OBJECT pfn;
ATL::CComPtr<IClassFactory> classFactory;
wcscpy(filePart, findData.cFileName);
IFFALSE_WIN32TOHR_EXIT(hr, dll.Win32Create(exePath));
if ( !dll.GetProcAddress( "DllGetClassObject", &pfn ) )
{
if ( ::GetLastError() == ERROR_PROC_NOT_FOUND )
continue;
else
{
DWORD LastError = ::GetLastError();
TRACE_WIN32_FAILURE( GetProcAddress );
hr = HRESULT_FROM_WIN32( LastError );
goto Exit;
}
}
if (FAILED(hr = pfn(rclsid, __uuidof(classFactory), reinterpret_cast<void**>(&classFactory))))
continue;
if (FAILED(hr = classFactory->CreateInstance(NULL, riid, pp)))
continue;
// hold the .dll open
dll.Detach();
goto Exit;
}
} while (FindNextFileW(findFile, &findData));
}
Exit:
return hr;
}