This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tools/W3DShellExt/shellext.cpp

209 lines
5.5 KiB
C++

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdAfx.h"
#include "priv.h"
#include "Chunkio.h"
#include "io.h"
#include "wdump.h"
#include "WdumpDoc.h"
//#include "w3d2dat.h" /// LFeenanEA: Header file missing, perhaps this tool is outdated?
//
// Initialize GUIDs (should be done only and at-least once per DLL/EXE)
//
#pragma data_seg(".text")
#define INITGUID
#include <initguid.h>
#include <shlguid.h>
#include "shellext.h"
#pragma data_seg()
// Global variables
//
UINT g_DllRefCount = 0; // Reference count of this DLL.
HINSTANCE g_DllInstance = NULL; // Handle to this DLL itself.
//===============================================================
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved){
if (dwReason == DLL_PROCESS_ATTACH){
g_DllInstance = hInstance;
}else
if (dwReason == DLL_PROCESS_DETACH){
ODS3("Detaching Process");
}
return 1; // ok
}
//---------------------------------------------------------------------------
// DllCanUnloadNow
//---------------------------------------------------------------------------
STDAPI DllCanUnloadNow(void)
{
return (g_DllRefCount == 0 ? S_OK : S_FALSE);
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut)
{
*ppvOut = NULL;
if (IsEqualIID(rclsid, CLSID_ShellExtension)) {
CShellExtClassFactory* pcf = new CShellExtClassFactory;
return pcf->QueryInterface(riid, ppvOut);
}
return CLASS_E_CLASSNOTAVAILABLE;
}
//======================================================================================
CShellExtClassFactory::CShellExtClassFactory()
{
m_cRef = 0L;
g_DllRefCount++;
}
//======================================================================================
CShellExtClassFactory::~CShellExtClassFactory(){
g_DllRefCount--;
}
//======================================================================================
STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, LPVOID FAR *ppv){
*ppv = NULL;
// Any interface on this object is the object pointer
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)){
*ppv = (LPCLASSFACTORY)this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
//======================================================================================
STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CShellExtClassFactory::Release()
{
if (--m_cRef)
return m_cRef;
delete this;
return 0L;
}
STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,REFIID riid,LPVOID *ppvObj){
*ppvObj = NULL;
// Shell extensions typically don't support aggregation (inheritance)
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
// Create the main shell extension object. The shell will then call
// QueryInterface with IID_IShellExtInit--this is how shell extensions are
// initialized.
LPCSHELLEXT pShellExt = new CShellExt(); //Create the CShellExt object
if (NULL == pShellExt)
return E_OUTOFMEMORY;
return pShellExt->QueryInterface(riid, ppvObj);
}
STDMETHODIMP CShellExtClassFactory::LockServer(BOOL fLock)
{
return NOERROR;
}
// *********************** CShellExt *************************
CShellExt::CShellExt(): m_FileInMemory(false),
m_NumAdded(0),
m_FoundMeshes(0){
m_cRef = 0L;
m_pDataObj = NULL;
g_DllRefCount++;
}
CShellExt::~CShellExt()
{
if (m_pDataObj)
m_pDataObj->Release();
g_DllRefCount--;
}
STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) {
*ppv = (LPSHELLEXTINIT)this;
}else {
if (IsEqualIID(riid, IID_IContextMenu)) {
*ppv = (LPCONTEXTMENU)this;
}else{
if (IsEqualIID(riid, IID_IExtractIcon)){
*ppv = (LPEXTRACTICON)this;
}else {
if (IsEqualIID(riid, IID_IPersistFile)){
*ppv = (LPPERSISTFILE)this;
}else {
if (IsEqualIID(riid, IID_IShellPropSheetExt)){
*ppv = (LPSHELLPROPSHEETEXT)this;
}else {
if (IsEqualIID(riid, IID_IShellCopyHook)){
*ppv = (LPCOPYHOOK)this;
}
}
}
}
}
}
if (*ppv){
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CShellExt::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CShellExt::Release()
{
if (--m_cRef){
return m_cRef;
}
delete this;
return 0L;
}
void CShellExt::Read_SelectedFile(){
m_WdumpDocument.Read_File(m_SelectedFile);
m_FileInMemory = true;
}
bool CShellExt::NotAdded(char* name){
CString str = name;
for(int pos(0); pos < m_NumAdded; pos ++){
if(str == m_Textures[pos]){
return false;
}
}
m_Textures[m_NumAdded ++ ] = str;
return true;
}
/////////////////////////////////////////////////////////////