Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

449 lines
12 KiB

//---------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation 1994
//
//---------------------------------------------------------------------------
// OLE DOCFile property page--from sample shell extension
#include "priv.h"
#pragma hdrstop
#include "extdef.h"
#include <stdio.h>
// All the objects that dialogs need.
typedef struct _ALLOBJS
{
LPSIOBJ lpSIObj;
LPDSIOBJ lpDSIObj;
LPUDOBJ lpUDObj;
LPSTR lpszFileName;
WIN32_FIND_DATA filedata;
BOOL fFiledataInit;
DWQUERYLD lpfnDwQueryLinkData;
DWORD dwMask;
} ALLOBJS, FAR * LPALLOBJS;
ALLOBJS g_allobjs;
#define fFalse (0)
#define fTrue (1)
#ifdef VERBOSE
#define DLLREF(A) {char psz[100];wsprintf(psz,A", g_cRefThis is %d\r\n",g_cRefThisDll);OutputDebugString(psz);}
#define TRACKREF(A) {char psz[100];wsprintf(psz,"In "A" reference count is %d\r\n",this->_cRef);OutputDebugString(psz);}
#else
#define DLLREF(A)
#define TRACKREF(A)
#endif //verbose
// Initialize GUIDs (should be done only and at-least once per DLL/EXE)
#ifndef WINNT
#pragma data_seg(".text")
#endif
#define INITGUID
#include <initguid.h>
#include <coguid.h>
#include <oleguid.h>
#include <shlguid.h>
#include "guid.h" //This must be reincluded, even though it's in priv.h
#ifndef WINNT
#pragma data_seg()
#endif
// Global variables
UINT g_cRefThisDll = 0; // Reference count of this DLL.
HANDLE g_hmodThisDll = NULL; // Handle to this DLL itself.
// Function prototypes
HRESULT CALLBACK OLEDOCProp_CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR*);
//
// Callback needed for Office code.
//
BOOL OFC_CALLBACK FCPConvert( LPSTR lpsz, DWORD dwFrom, DWORD dwTo, BOOL fMacintosh )
{
return TRUE;
}
//
// Callback needed for Office code.
//
static BOOL OFC_CALLBACK FSzToNum(double *lpdbl, LPSTR lpsz)
{
char *pc;
errno = 0;
*lpdbl = (double) strtod (lpsz, &pc);
return ((!errno) && (*pc == '\0'));
}
//
// Callback needed for Office code.
//
static BOOL OFC_CALLBACK FNumToSz(double *lpdbl, LPSTR lpsz, DWORD cbMax)
{
sprintf (lpsz, "%g", *(double *) lpdbl);
return(TRUE);
}
//
// Callback needed for Office code.
//
static BOOL OFC_CALLBACK FUpdateStats(HWND hwndParent, LPSIOBJ lpSIObj, LPDSIOBJ lpDSIObj)
{
// MessageBox (hwndParent, "This is when the app would update the stats", "Office 95 Test App", MB_OK);
return(TRUE);
}
BOOL APIENTRY LibMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
static void *rglpfnProp[] = {
(void *) FCPConvert,
(void *) FSzToNum,
(void *) FNumToSz,
(void *) FUpdateStats
};
MESSAGE("Oleprop dll main");
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
MESSAGE("DocProp: DLL_PROCESS_ATTACH");
g_hmodThisDll = hDll;
// Initialize Office property code
FOfficeCreateAndInitObjects( &g_allobjs.lpSIObj,
&g_allobjs.lpDSIObj,
&g_allobjs.lpUDObj,
rglpfnProp
);
g_allobjs.lpfnDwQueryLinkData = NULL;
g_allobjs.dwMask = 0;
break;
case DLL_PROCESS_DETACH:
MESSAGE("DocProp: DLL_PROCESS_DETACH");
FOfficeDestroyObjects( &g_allobjs.lpSIObj,
&g_allobjs.lpDSIObj,
&g_allobjs.lpUDObj
);
break;
case DLL_THREAD_DETACH:
break;
case DLL_THREAD_ATTACH:
default:
break;
} // end switch()
return TRUE;
}
STDAPI DllCanUnloadNow(void)
{
DLLREF("DocProp: In DLLCanUnloadNow");
if (g_cRefThisDll == 0 && g_hOle)
{
MESSAGE("DocProp: Unloading OLE32.DLL\r\n");
FreeLibrary(g_hOle);
g_hOle = NULL;
}
return ResultFromScode((g_cRefThisDll==0) ? S_OK : S_FALSE);
}
// CDefClassFactory class ... From defclsf.c
typedef struct
{
IClassFactory cf;
UINT cRef; // Reference count
LPFNCREATEINSTANCE lpfnCI; // CreateInstance callback entry
UINT FAR * pcRefDll; // Reference count of the DLL
const IID FAR * riidInst; // Optional interface for instance
} CDefClassFactory;
extern CDefClassFactory * NEAR PASCAL CDefClassFactory_Create(
LPFNCREATEINSTANCE lpfnCI, UINT FAR * pcRefDll, REFIID riidInst);
//---------------------------------------------------------------------------
//
// 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)
{
DLLREF("Before DllGetClassObject");
*ppvOut = NULL; // Assume Failure
if (IsEqualIID(rclsid, &CLSID_OLEDOCProp))
{
if (IsEqualIID(riid, &IID_IClassFactory)
|| IsEqualIID(riid, &IID_IUnknown) )
{
CDefClassFactory * pacf = CDefClassFactory_Create(
OLEDOCProp_CreateInstance,
&g_cRefThisDll,
NULL);
DLLREF("After CDefClassFactory_Create");
if (pacf)
{
(IClassFactory FAR *)*ppvOut = &pacf->cf;
return NOERROR;
}
return ResultFromScode(E_OUTOFMEMORY);
}
return ResultFromScode(E_NOINTERFACE);
}
else
{
return ResultFromScode(CLASS_E_CLASSNOTAVAILABLE);
}
}
//---------------------------------------------------------------------------
//
// CShellExtSample class
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// ShellExtSample_CreateInstance
//
// This function is called back from within IClassFactory::CreateInstance()
// of the default class factory object, which is created by CreateClassObject.
//
//---------------------------------------------------------------------------
HRESULT CALLBACK OLEDOCProp_CreateInstance(LPUNKNOWN punkOuter,
REFIID riid, LPVOID FAR* ppvOut)
{
HRESULT hres;
POLEDOCPROP psmx;
//
// Shell extentions typically does not support aggregation.
//
if (punkOuter) {
return ResultFromScode(CLASS_E_NOAGGREGATION);
}
//
// in C++:
// psmx = new COLEDOCProp();
//
psmx = LocalAlloc(LPTR, sizeof(COLEDOCProp));
if (!psmx) {
return ResultFromScode(E_OUTOFMEMORY);
}
psmx->_sxi.lpVtbl = &c_OLEDOCProp_SXIVtbl;
psmx->_spx.lpVtbl = &c_OLEDOCProp_SPXVtbl;
MESSAGE("Setting cRef to 1");
psmx->_cRef = 1;
psmx->_pdtobj = NULL;
psmx->_hkeyProgID = NULL;
g_cRefThisDll++;
DLLREF("After OledocpropcreateInstance");
//
// in C++:
// hres = psmx->QueryInterface(riid, ppvOut);
// psmx->Release();
//
// Note that the Release member will free the object, if QueryInterface
// failed.
//
hres = E_NOINTERFACE;
if (IsEqualIID(riid, &IID_IShellExtInit)) {
hres = c_OLEDOCProp_SPXVtbl.QueryInterface(&psmx->_spx, riid, ppvOut);
c_OLEDOCProp_SPXVtbl.Release(&psmx->_spx);
}
return hres; // S_OK or E_NOINTERFACE
}
STDMETHODIMP_(UINT) SHE_PageExt_AddRef(LPSHELLPROPSHEETEXT pspx)
{
POLEDOCPROP this = PSPX2PSMX(pspx);
TRACKREF("PageExt_Addref, before adding");
return ++this->_cRef;
}
STDMETHODIMP_(UINT) SHE_PageExt_Release(LPSHELLPROPSHEETEXT pspx)
{
POLEDOCPROP this = PSPX2PSMX(pspx);
TRACKREF("PageExt_release, before releasing");
if (--this->_cRef) {
return this->_cRef;
}
if (this->_pdtobj) {
this->_pdtobj->lpVtbl->Release(this->_pdtobj);
}
if (this->_hkeyProgID)
{
RegCloseKey(this->_hkeyProgID);
}
LocalFree((HLOCAL)this);
MESSAGE ("Freed PageExt");
g_cRefThisDll--;
DLLREF("After SHE_PageExtRelease");
return 0;
}
STDMETHODIMP SHE_PageExt_QueryInterface(LPSHELLPROPSHEETEXT pspx, REFIID riid, LPVOID FAR* ppvOut)
{
POLEDOCPROP this;
if (NULL == pspx) {
MESSAGE ("QI on NULL--pageext");
return (E_FAIL);
}
this = PSPX2PSMX(pspx);
if (IsEqualIID(riid, &IID_IShellPropSheetExt) ||
IsEqualIID(riid, &IID_IUnknown))
{
(LPSHELLPROPSHEETEXT)*ppvOut=pspx;
TRACKREF("QI addref, before adding, propsheet");
this->_cRef++;
return NOERROR;
}
if (IsEqualIID(riid, &IID_IShellExtInit))
{
(LPSHELLEXTINIT)*ppvOut=&this->_sxi;
TRACKREF("QI addref, before adding, shellext");
this->_cRef++;
return NOERROR;
}
MESSAGE ("QueryInterface failed");
*ppvOut=NULL;
return ResultFromScode(E_NOINTERFACE);
}
//---------------------------------------------------------------------------
//
// Shell Extension Sample's IShellExtInit Interface
//
//---------------------------------------------------------------------------
STDMETHODIMP SHE_ShellExtInit_Initialize(LPSHELLEXTINIT psxi,
LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pdtobj, HKEY hkeyProgID)
{
POLEDOCPROP this = PSXI2PSMX(psxi);
// Initialize can be called more than once.
if (this->_pdtobj) {
this->_pdtobj->lpVtbl->Release(this->_pdtobj);
}
if (this->_hkeyProgID) {
RegCloseKey(this->_hkeyProgID);
}
// Duplicate the pdtobj pointer
if (pdtobj) {
this->_pdtobj = pdtobj;
pdtobj->lpVtbl->AddRef(pdtobj);
}
// Duplicate the handle
if (hkeyProgID) {
RegOpenKeyEx(hkeyProgID, NULL, 0L, MAXIMUM_ALLOWED, &this->_hkeyProgID);
}
return NOERROR;
}
STDMETHODIMP_(UINT) SHE_ShellExtInit_AddRef(LPSHELLEXTINIT psxi)
{
POLEDOCPROP this = PSXI2PSMX(psxi);
TRACKREF("ShellExtInit before Addref");
return ++this->_cRef;
}
STDMETHODIMP_(UINT) SHE_ShellExtInit_Release(LPSHELLEXTINIT psxi)
{
POLEDOCPROP this = PSXI2PSMX(psxi);
return SHE_PageExt_Release(&this->_spx);
return 0;
}
STDMETHODIMP SHE_ShellExtInit_QueryInterface(LPSHELLEXTINIT psxi, REFIID riid, LPVOID FAR* ppv)
{
POLEDOCPROP this;
if (NULL == psxi) {
MESSAGE ("QI on null -- shellextinit");
return (E_FAIL);
}
this = PSXI2PSMX(psxi);
if (IsEqualIID(riid, &IID_IShellPropSheetExt)) {
return SHE_PageExt_QueryInterface(&this->_spx, riid, ppv);
}
}
//---------------------------------------------------------------------------
// CShellExtSample class : Vtables
//---------------------------------------------------------------------------
#ifndef WINNT
#pragma data_seg(".text")
#endif
IShellPropSheetExtVtbl c_OLEDOCProp_SPXVtbl = {
SHE_PageExt_QueryInterface,
SHE_PageExt_AddRef,
SHE_PageExt_Release,
OleProp_AddPages
};
IShellExtInitVtbl c_OLEDOCProp_SXIVtbl = {
SHE_ShellExtInit_QueryInterface,
SHE_ShellExtInit_AddRef,
SHE_ShellExtInit_Release,
SHE_ShellExtInit_Initialize
};
#ifndef WINNT
#pragma data_seg()
#endif