mirror of
https://github.com/tenrok/Rfid-Credential-Provider.git
synced 2026-05-15 11:59:44 +03:00
179 lines
3.1 KiB
C++
179 lines
3.1 KiB
C++
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// Standard dll required functions and class factory implementation.
|
|
|
|
#include <windows.h>
|
|
#include "Dll.h"
|
|
#include "guid.h"
|
|
|
|
static LONG g_cRef = 0; // global dll reference count
|
|
|
|
// IClassFactory ///////////////////////////////////////////////////////////////////////
|
|
|
|
extern HRESULT RfidProvider_CreateInstance(REFIID riid, void** ppv);
|
|
|
|
HINSTANCE g_hinst = nullptr; // global dll hinstance
|
|
|
|
class CClassFactory : public IClassFactory
|
|
{
|
|
public:
|
|
// IUnknown
|
|
STDMETHOD_(ULONG, AddRef)()
|
|
{
|
|
return _cRef++;
|
|
}
|
|
|
|
STDMETHOD_(ULONG, Release)()
|
|
{
|
|
LONG cRef = _cRef--;
|
|
if (!cRef)
|
|
{
|
|
delete this;
|
|
}
|
|
return cRef;
|
|
}
|
|
|
|
STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
|
|
{
|
|
HRESULT hr;
|
|
if (ppv != NULL)
|
|
{
|
|
if (IID_IClassFactory == riid || IID_IUnknown == riid)
|
|
{
|
|
*ppv = static_cast<IUnknown*>(this);
|
|
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// IClassFactory
|
|
STDMETHOD(CreateInstance)(IUnknown* pUnkOuter, REFIID riid, void** ppv)
|
|
{
|
|
HRESULT hr;
|
|
if (!pUnkOuter)
|
|
{
|
|
hr = RfidProvider_CreateInstance(riid, ppv);
|
|
}
|
|
else
|
|
{
|
|
hr = CLASS_E_NOAGGREGATION;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHOD(LockServer)(BOOL bLock)
|
|
{
|
|
if (bLock)
|
|
{
|
|
DllAddRef();
|
|
}
|
|
else
|
|
{
|
|
DllRelease();
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
private:
|
|
CClassFactory() : _cRef(1) {}
|
|
~CClassFactory() {}
|
|
|
|
private:
|
|
LONG _cRef;
|
|
friend HRESULT CClassFactory_CreateInstance(REFCLSID rclsid, REFIID riid, void** ppv);
|
|
};
|
|
|
|
HRESULT CClassFactory_CreateInstance(REFCLSID rclsid, REFIID riid, void** ppv)
|
|
{
|
|
HRESULT hr;
|
|
if (CLSID_RfidProvider == rclsid)
|
|
{
|
|
CClassFactory* pcf = new CClassFactory;
|
|
if (pcf)
|
|
{
|
|
hr = pcf->QueryInterface(riid, ppv);
|
|
pcf->Release();
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = CLASS_E_CLASSNOTAVAILABLE;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// DLL Functions ///////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL WINAPI DllMain(
|
|
HINSTANCE hinstDll,
|
|
DWORD dwReason,
|
|
LPVOID pReserved
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(pReserved);
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
DisableThreadLibraryCalls(hinstDll);
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
g_hinst = hinstDll;
|
|
return TRUE;
|
|
}
|
|
|
|
void DllAddRef()
|
|
{
|
|
InterlockedIncrement(&g_cRef);
|
|
}
|
|
|
|
void DllRelease()
|
|
{
|
|
InterlockedDecrement(&g_cRef);
|
|
}
|
|
|
|
// DLL entry point.
|
|
STDAPI DllCanUnloadNow()
|
|
{
|
|
HRESULT hr;
|
|
if (g_cRef > 0)
|
|
{
|
|
hr = S_FALSE; // cocreated objects still exist, don't unload
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK; // refcount is zero, ok to unload
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// DLL entry point.
|
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
|
|
{
|
|
return CClassFactory_CreateInstance(rclsid, riid, ppv);
|
|
}
|