THISDLL.CPP

//******************************************************************************************* 
//
// Filename : ThisDll.cpp
//
//Generic OLE DLL routines
//
// Copyright 1994 - 1998 Microsoft Corporation. All rights reserved
//
//*******************************************************************************************


#include "pch.h"

// ********************************************************
// Initialize GUIDs
//
#pragma data_seg(".text")
#define INITGUID
#include <initguid.h>
#include <cguid.h>
#include "thisguid.h"
//#undef INITGUID
#pragma data_seg()

#include "thisdll.h"

#include "resource.h"

CThisDll g_ThisDll;

// ******************************************************************
// ******************************************************************
// DllMain
STDAPI_(BOOL) APIENTRY DllMain(
HINSTANCE hDll,
DWORD dwReason,
LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
g_ThisDll.SetInstance(hDll);

// Initialize the various modules.
//

//
// Tell system to fix up alignment faults at runtime
//

SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT);

break;

case DLL_PROCESS_DETACH:
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;

default:
break;

} // switch

return(TRUE);
}


// ******************************************************************
// DllCanUnloadNow
STDAPI DllCanUnloadNow()
{
HRESULT retval = (HRESULT)((g_ThisDll.m_cRef.GetRef() == 0)
&& (g_ThisDll.m_cLock.GetRef() == 0) ? S_OK : S_FALSE);
return(retval);
}


// Procedure for uninstalling this DLL (given an INF file)
void CALLBACK Uninstall(HWND hwndStub, HINSTANCE hInstance, LPSTR lpszCmdLine,
int nCmdShow)
{
RUNDLLPROC pfnCheckAPI = Uninstall;

static char szFmt[] = "rundll.exe setupx.dll,InstallHinfSection DefaultUninstall 132 %s";

if (!lpszCmdLine || lstrlen(lpszCmdLine)>=MAX_PATH)
{
return;
}
if (MessageBox(hwndStub, MAKEINTRESOURCE(IDS_SUREUNINST),
MAKEINTRESOURCE(IDS_THISDLL), MB_YESNO|MB_ICONSTOP) != IDYES)
{
return;
}


char szCmd[sizeof(szFmt)+MAX_PATH];
wsprintf(szCmd, szFmt, lpszCmdLine);

// Note that I use START.EXE, to minimize the chance that this DLL will still be loaded
// when SETUPX tries to delete it
ShellExecute(hwndStub, NULL, "start.exe", szCmd, NULL, SW_SHOWMINIMIZED);
}


// CThisDll::CThisDll()

// ********************************************************************
class CThisDllClassFactory : public IClassFactory
{
public:
// *** IUnknown methods ***
STDMETHODIMP QueryInterface(REFIID riid,
LPVOID FAR* ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);

// *** IClassFactory methods ***
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID FAR* ppvObject);
STDMETHODIMP LockServer(BOOL fLock);

private:
CRefDll m_cRefDll;

CRefCount m_cRef;
};

// ******************************************************************
// ******************************************************************
// DllGetClassObject
STDAPI DllGetClassObject(
REFCLSID rclsid,
REFIID riid,
LPVOID FAR* ppvObj)
{
*ppvObj = NULL;

if(! (rclsid == CLSID_ThisDll))
{
return(E_FAIL);
}

CThisDllClassFactory *pcf = new CThisDllClassFactory;
if (!pcf)
{
return(E_OUTOFMEMORY);
}

// Note if the QueryInterface fails, the Release will delete the object
pcf->AddRef();
HRESULT hRes = pcf->QueryInterface(riid, ppvObj);
pcf->Release();

return(hRes);
}


// ***********************************************************************
// ***********************************************************************
// CImpIClassFactory member functions

// *** IUnknown methods ***
STDMETHODIMP CThisDllClassFactory::QueryInterface(REFIID riid,
LPVOID FAR* ppvObj)
{
*ppvObj = NULL;

// Any interface on this object is the object pointer
if((riid == IID_IUnknown) || (riid == IID_IClassFactory))
{
*ppvObj = (LPVOID)(IClassFactory *)this;
}

if(*ppvObj)
{
((LPUNKNOWN)*ppvObj)->AddRef();
return NOERROR;
}

return(E_NOINTERFACE);
}


STDMETHODIMP_(ULONG) CThisDllClassFactory::AddRef(void)
{
return(m_cRef.AddRef());
}


STDMETHODIMP_(ULONG) CThisDllClassFactory::Release(void)
{
if (!m_cRef.Release())
{
delete this;
return(0);
}

return(m_cRef.GetRef());
}


// *** IClassFactory methods ***
STDMETHODIMP CThisDllClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID FAR* ppvObj)
{
// we do not support aggregation
if(pUnkOuter)
{
return(CLASS_E_NOAGGREGATION);
}

return(::CreateInstance(riid, ppvObj));
}


STDMETHODIMP CThisDllClassFactory::LockServer(BOOL fLock)
{
if(fLock)
{
g_ThisDll.m_cLock.AddRef();
}
else
{
g_ThisDll.m_cLock.Release();
}

return(NOERROR);
}


void * __cdecl operator new(unsigned int nSize)
{
return((LPVOID)LocalAlloc(LMEM_FIXED, nSize));
}


void __cdecl operator delete(void *pv)
{
LocalFree((HLOCAL)pv);
}


extern "C" int __cdecl _purecall()
{
return(0);
}