Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

389 lines
12 KiB

/* File: D:\wacker\ext\pageext.c (Created: 01-Mar-1994)
*
* Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
* All rights reserved
*
* $Revision: 3 $
* $Date: 3/25/02 3:52p $
*/
#define _INC_OLE // WIN32, get ole2 from windows.h
#define CONST_VTABLE
#define INITGUID
#include <windows.h>
#pragma hdrstop
//
// Initialize GUIDs (should be done only and at-least once per DLL/EXE)
//
#pragma data_seg(".text")
#include <objbase.h>
#include <initguid.h>
//#include <coguid.h>
//#include <oleguid.h>
#include <shlguid.h>
#include <shlobj.h>
#include "pageext.hh"
#pragma data_seg()
//
// Function prototypes
//
HRESULT CALLBACK PageExt_CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR*);
//
// Global variables
//
UINT g_cRefThisDll = 0; // Reference count of this DLL.
//---------------------------------------------------------------------------
// DllCanUnloadNow
//---------------------------------------------------------------------------
STDAPI DllCanUnloadNow(void)
{
return ResultFromScode((g_cRefThisDll==0) ? S_OK : S_FALSE);
}
//---------------------------------------------------------------------------
//
// DllGetClassObject
//
// This is the entry of this DLL, which all the In-Proc server DLLs should
// export. See the description of "DllGetClassObject" of OLE 2.0 reference
// manual for detail.
//
//---------------------------------------------------------------------------
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppvOut)
{
//
// This DLL has only one class (CLSID_SamplePageExt). If a DLL supports
// multiple classes, it should have either multiple if-statements or
// efficient table lookup code.
//
// We need to put the icon handler in a separate DLL so when CAB32.EXE
// calls it we don't implicitly link to TAPI and other system DLL's.
// This is mostly for speed and to work around a bug in the Chicago
// beta 1. Of course, we want to keep one source. So the main DLL
// will link to the icon DLL to get icons, and the SHCreateDefClassObject(),
// etc. Sorry for the complexity but its in the interest of system
// performance. - mrw
if (IsEqualIID(rclsid, &CLSID_SamplePageExt))
{
//
// We are supposed return the class object for this class. Instead
// of fully implementing it in this DLL, we just call a helper
// function in the shell DLL which creates a default class factory
// object for us. When its CreateInstance member is called, it
// will call back our create instance function (PageExt_CreateInstance).
//
return SHCreateDefClassObject(
riid,
ppvOut,
PageExt_CreateInstance, // callback function
&g_cRefThisDll, // reference count of this DLL
&IID_IShellExtInit // init interface
);
}
return ResultFromScode(CLASS_E_CLASSNOTAVAILABLE);
}
//---------------------------------------------------------------------------
//
// CSamplePageExt class
//
// In C++:
// class CSamplePageExt : protected IShellPropSheetExt, protected IShellExtInit
// {
// protected:
// UINT _cRef;
// LPDATAOBJECT _pdtobj;
// HKEY _hkeyProgID;
// public:
// CSamplePageExt() _cRef(1), _pdtobj(NULL), _hkeyProgID(NULL) {};
// ...
// };
//
//---------------------------------------------------------------------------
typedef struct _CSamplePageExt // smx
{
IShellPropSheetExt _spx; // 1st base class
IShellExtInit _sxi; // 2nd base class
UINT _cRef; // reference count
LPDATAOBJECT _pdtobj; // data object
HKEY _hkeyProgID; // reg. database key to ProgID
} CSamplePageExt, * PSAMPLEPAGEEXT;
//
// Useful macros, which casts interface pointers to class pointers.
//
#define SMX_OFFSETOF(x) ((UINT_PTR)(&((PSAMPLEPAGEEXT)0)->x))
#define PVOID2PSMX(pv,offset) ((PSAMPLEPAGEEXT)(((LPBYTE)pv)-offset))
#define PSPX2PSMX(pspx) PVOID2PSMX(pspx, SMX_OFFSETOF(_spx))
#define PSXI2PSMX(psxi) PVOID2PSMX(psxi, SMX_OFFSETOF(_sxi))
//
// Vtable prototype
//
extern IShellPropSheetExtVtbl c_SamplePageExt_SPXVtbl;
extern IShellExtInitVtbl c_SamplePageExt_SXIVtbl;
//---------------------------------------------------------------------------
//
// PageExt_CreateInstance
//
// This function is called back from within IClassFactory::CreateInstance()
// of the default class factory object, which is created by Shell_CreateClassObject.
//
//---------------------------------------------------------------------------
HRESULT CALLBACK PageExt_CreateInstance(LPUNKNOWN punkOuter,
REFIID riid, LPVOID FAR* ppvOut)
{
HRESULT hres;
PSAMPLEPAGEEXT psmx;
//
// Shell extentions typically does not support aggregation.
//
if (punkOuter)
return ResultFromScode(CLASS_E_NOAGGREGATION);
//
// in C++:
// psmx = new CSamplePageExt();
//
psmx = LocalAlloc(LPTR, sizeof(CSamplePageExt));
if (!psmx)
return ResultFromScode(E_OUTOFMEMORY);
psmx->_spx.lpVtbl = &c_SamplePageExt_SPXVtbl;
psmx->_sxi.lpVtbl = &c_SamplePageExt_SXIVtbl;
psmx->_cRef = 1;
psmx->_pdtobj = NULL;
psmx->_hkeyProgID = NULL;
g_cRefThisDll++;
//
// in C++:
// hres = psmx->QueryInterface(riid, ppvOut);
// psmx->Release();
//
// Note that the Release member will free the object, if QueryInterface
// failed.
//
hres = c_SamplePageExt_SPXVtbl.QueryInterface(&psmx->_spx, riid, ppvOut);
c_SamplePageExt_SPXVtbl.Release(&psmx->_spx);
return hres; // S_OK or E_NOINTERFACE
}
//---------------------------------------------------------------------------
// CSamplePageExt::Initialize (IShellExtInit override)
//
// The shell always calls this member function to initialize this object
// immediately after creating it (by calling CoCreateInstance).
//
// Arguments:
// pdtobj -- Specifies one or more objects for which the shell is about to
// open the property sheet. Typically, they are selected objects
// in the explorer. If they are file system objects, it supports
// CF_FILELIST; if they are network resource objects, it supports
// "Net Resource" clipboard format.
// hkeyProgID -- Specifies the program ID of the primary object (typically
// the object which has the focus in the explorer's content pane).
//
// Comments:
// The extension should "duplicate" the parameters if it needs them later.
// Call AddRef() member function for the pdtobj and RegOpenKeyEx() API for the
// hkeyProgID.
//---------------------------------------------------------------------------
STDMETHODIMP PageExt_Initialize(LPSHELLEXTINIT psxi,
LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pdtobj, HKEY hkeyProgID)
{
PSAMPLEPAGEEXT this = PSXI2PSMX(psxi);
//
// Initialize can be called more than once.
//
if (this->_pdtobj)
{
this->_pdtobj->lpVtbl->Release(this->_pdtobj);
this->_pdtobj = NULL;
}
if (this->_hkeyProgID)
{
RegCloseKey(this->_hkeyProgID);
this->_hkeyProgID = NULL;
}
//
// Duplicate the pdtobj pointer
//
if (pdtobj)
{
this->_pdtobj = pdtobj;
pdtobj->lpVtbl->AddRef(pdtobj);
}
//
// Duplicate the handle (althogh we don't use it in this sample)
//
if (hkeyProgID)
RegOpenKeyEx(hkeyProgID, 0, 0, KEY_READ, &this->_hkeyProgID);
return NOERROR;
}
//---------------------------------------------------------------------------
// CSamplePageExt::AddPages (IShellPropSheetExt override)
//---------------------------------------------------------------------------
STDMETHODIMP PageExt_AddPages(LPSHELLPROPSHEETEXT pspx,
LPFNADDPROPSHEETPAGE lpfnAddPage,
LPARAM lParam)
{
PSAMPLEPAGEEXT this = PSPX2PSMX(pspx);
//
// This is the place where this extension may add pages to the property
// sheet the shell is about to create. In this example, we add the
// "FSPage" if the selected objects are file system objects and add
// the "NETPage" if the selected objects are file system objects.
//
// Typically, a shell extension is registered either file system object
// class or network resource classe, and does not need to deal with two
// different kinds of objects.
//
FSPage_AddPages(this->_pdtobj, lpfnAddPage, lParam);
//NETPage_AddPages(this->_pdtobj, lpfnAddPage, lParam);
return NOERROR;
}
//---------------------------------------------------------------------------
// CSamplePageExt::AddRef (IShellPropSheetExt override)
//---------------------------------------------------------------------------
STDMETHODIMP_(UINT) PageExt_SPX_AddRef(LPSHELLPROPSHEETEXT pspx)
{
PSAMPLEPAGEEXT this = PSPX2PSMX(pspx);
return ++this->_cRef;
}
//---------------------------------------------------------------------------
// CSamplePageExt::AddRef (IShellExtInit override)
//---------------------------------------------------------------------------
STDMETHODIMP_(UINT) PageExt_SXI_AddRef(LPSHELLEXTINIT psxi)
{
PSAMPLEPAGEEXT this = PSXI2PSMX(psxi);
return ++this->_cRef;
}
//---------------------------------------------------------------------------
// CSamplePageExt::Release (IShellPropSheetExt override)
//---------------------------------------------------------------------------
STDMETHODIMP_(UINT) PageExt_SPX_Release(LPSHELLPROPSHEETEXT pspx)
{
PSAMPLEPAGEEXT this = PSPX2PSMX(pspx);
if (--this->_cRef)
return this->_cRef;
if (this->_pdtobj)
this->_pdtobj->lpVtbl->Release(this->_pdtobj);
if (this->_hkeyProgID)
RegCloseKey(this->_hkeyProgID);
LocalFree((HLOCAL)this);
g_cRefThisDll--;
return 0;
}
//---------------------------------------------------------------------------
// CSamplePageExt::Release (IShellExtInit thunk)
//---------------------------------------------------------------------------
STDMETHODIMP_(UINT) PageExt_SXI_Release(LPSHELLEXTINIT psxi)
{
PSAMPLEPAGEEXT this = PSXI2PSMX(psxi);
return PageExt_SPX_Release(&this->_spx);
}
//---------------------------------------------------------------------------
// CSamplePageExt::QueryInterface (IShellPropSheetExt override)
//---------------------------------------------------------------------------
STDMETHODIMP PageExt_SPX_QueryInterface(LPSHELLPROPSHEETEXT pspx, REFIID riid, LPVOID FAR* ppvOut)
{
PSAMPLEPAGEEXT this = PSPX2PSMX(pspx);
if (IsEqualIID(riid, &IID_IShellPropSheetExt) ||
IsEqualIID(riid, &IID_IUnknown))
{
(LPSHELLPROPSHEETEXT)*ppvOut=pspx;
this->_cRef++;
return NOERROR;
}
if (IsEqualIID(riid, &IID_IShellExtInit))
{
(LPSHELLEXTINIT)*ppvOut=&this->_sxi;
this->_cRef++;
return NOERROR;
}
*ppvOut=NULL;
return ResultFromScode(E_NOINTERFACE);
}
//---------------------------------------------------------------------------
// CSamplePageExt::QueryInterface (IShellExtInit thunk)
//---------------------------------------------------------------------------
STDMETHODIMP PageExt_SXI_QueryInterface(LPSHELLEXTINIT psxi, REFIID riid, LPVOID FAR* ppv)
{
PSAMPLEPAGEEXT this = PSXI2PSMX(psxi);
return PageExt_SPX_QueryInterface(&this->_spx, riid, ppv);
}
//---------------------------------------------------------------------------
// CSamplePageExt class : Vtables
//
// VTables should be placed in the read only section unless we need to alter
// them at runtime.
//---------------------------------------------------------------------------
#pragma data_seg(".text")
IShellPropSheetExtVtbl c_SamplePageExt_SPXVtbl =
{
PageExt_SPX_QueryInterface,
PageExt_SPX_AddRef,
PageExt_SPX_Release,
PageExt_AddPages
};
IShellExtInitVtbl c_SamplePageExt_SXIVtbl =
{
PageExt_SXI_QueryInterface,
PageExt_SXI_AddRef,
PageExt_SXI_Release,
PageExt_Initialize
};
#pragma data_seg()