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.
 
 
 
 
 
 

303 lines
7.3 KiB

/*++
Copyright (c) 1996-1997 Microsoft Corporation
Module Name:
oemcom.cxx
Abstract:
Implementation of Windows NT printer driver OEM COM plugins
Environment:
Windows NT
Revision History:
02/06/98 -steveki-
Initial framework.
--*/
#include <lib.h>
#undef IUnknown
#ifdef __cplusplus
extern "C" {
#endif
static const CHAR szDllGetClassObject[] = "DllGetClassObject";
static const CHAR szDllCanUnloadNow[] = "DllCanUnloadNow";
#ifdef WINNT_40
extern "C" EngFindImageProcAddress(HMODULE, CHAR *);
extern "C" EngUnloadImage(HMODULE);
#endif
extern "C" HRESULT
HDriver_CoGetClassObject(
IN REFCLSID rclsid,
IN DWORD dwClsContext,
IN LPVOID pvReservedForDCOM,
IN REFIID riid,
IN LPVOID *ppv,
IN HANDLE hInstance
)
/*++
Routine Description:
Locate and connect to the class factory object associated with the class identifier rclsid.
Arguments:
rclsid - Specifies the class factory component.
dwClsContext - Specifies the context in which the executable code is to be run.
pvReservedForDCOM - Reserved for future use; must be NULL.
riid - Specifies the interface to be used to communicate with the class object.
ppv - Points to where to return the pointer to the requested interface.
hInstance - Handle to the loaded OEM plugin module.
Return Value:
S_OK if successful, E_FAIL if DllGetClassObject entry point is not found. Refer to COM spec
for other possible error codes that can be returned.
--*/
{
HRESULT hr = E_FAIL;
LPFNGETCLASSOBJECT pfnDllGetClassObject = NULL;
//
// Get the class object procedure address.
//
if (hInstance && (pfnDllGetClassObject = (LPFNGETCLASSOBJECT)GetProcAddress((HMODULE)hInstance,
(CHAR *)szDllGetClassObject)))
{
//
// Ask for the class factory interface.
//
hr = pfnDllGetClassObject(rclsid, riid, ppv);
}
return hr;
}
extern "C" HRESULT
HDriver_CoCreateInstance(
IN REFCLSID rclsid,
IN LPUNKNOWN pUnknownOuter,
IN DWORD dwClsContext,
IN REFIID riid,
IN LPVOID *ppv,
IN HANDLE hInstance
)
/*++
Routine Description:
Create an instance of the class rclsid, asking for interface riid using the given execution context.
Arguments:
rclsid - Specifies the class factory component.
pUnknownOuter - Specifies the controlling unknown of the aggregate.
dwClsContext - Specifies the context in which the executable is to be run.
riid - Specifies the interface to be used to communicate with the class object.
ppv - Points to where to return the pointer to the requested interface.
hInstance - Handle to the loaded OEM plugin module.
Return Value:
S_OK if successful. Refer to COM spec for other possible error codes that can be returned.
--*/
{
HRESULT hr = E_FAIL;
IClassFactory *pIFactory = NULL;
//
// Set output parameter to NULL.
//
*ppv = NULL;
//
// We can only support in process servers. We do not have any
// code for marshaling to another process.
//
if (dwClsContext == CLSCTX_INPROC_SERVER)
{
hr = HDriver_CoGetClassObject(rclsid,
dwClsContext,
NULL,
IID_IClassFactory,
(void **)&pIFactory,
hInstance);
if(SUCCEEDED(hr))
{
hr = pIFactory->CreateInstance(pUnknownOuter, riid, ppv);
//
// Release the class factory.
//
pIFactory->Release();
}
}
else
{
hr = E_NOTIMPL;
}
return hr;
}
extern "C" VOID
Driver_CoFreeOEMLibrary(
IN HANDLE hInstance
)
/*++
Routine Description:
Unloads OEM plugin DLL that are no longer serving any components.
Arguments:
hInstance - Handle to the loaded OEM plugin module.
Return Value:
None.
--*/
{
LPFNCANUNLOADNOW pfnDllCanUnloadNow = NULL;
if (hInstance && (pfnDllCanUnloadNow = (LPFNCANUNLOADNOW)GetProcAddress((HMODULE)hInstance,
(CHAR *)szDllCanUnloadNow)))
{
(VOID) pfnDllCanUnloadNow();
//
// We don't look at the return value of DllCanUnloadNow() and always do a FreeLibrary here,
// otherwise we may end up with OEM DLL still remains in memory when all its instances are
// unloaded.
//
// If OEM DLL spins off a working thread which also uses the OEM DLL, the thread needs to
// do LoadLibrary and FreeLibraryExitThread, otherwise it may crash after we called FreeLibrary.
//
FreeLibrary((HMODULE)hInstance);
}
}
extern "C" BOOL
BQILatestOemInterface(
IN HANDLE hInstance,
IN REFCLSID rclsid,
IN const GUID *PrintOem_IIDs[],
OUT PVOID *ppIntfOem,
OUT GUID *piidIntfOem
)
/*++
Routine Description:
Retrieve the latest interface supported by OEM plugin
Arguments:
hInstance - handle to the loaded OEM plugin module
rclsid - specifies the class factory component
PrintOem_IIDs[] - array of IIDs for plugin interfaces (from latest to oldest) driver supports
ppIntfOem - points to where to return the interface pointer we get from OEM plugin
piidIntfOem - points to where to return the IID for the interface we get from OEM plguin
Return Value:
TRUE if retrieving OEM plugin interface is successful. FALSE otherwise.
--*/
{
IUnknown *pIUnknown = NULL;
IUnknown *pIPrintOem = NULL;
HRESULT hr;
INT iid_index;
BOOL bIntfFound;
hr = HDriver_CoCreateInstance(rclsid,
NULL,
CLSCTX_INPROC_SERVER,
IID_IUnknown,
(void **)&pIUnknown,
hInstance);
if (FAILED(hr) || pIUnknown == NULL)
{
ERR(("HDriver_CoCreateInstance failed\n"));
return FALSE;
}
iid_index = 0;
bIntfFound = FALSE;
//
// QI for the driver supported plugin interfaces from latest to oldest,
// until one is supported by the OEM plugin, or until we hit the NULL
// terminator.
//
while (!bIntfFound && PrintOem_IIDs[iid_index] != NULL)
{
hr = pIUnknown->QueryInterface(*PrintOem_IIDs[iid_index], (void **)&pIPrintOem);
if (SUCCEEDED(hr) && pIPrintOem != NULL)
bIntfFound = TRUE;
else
iid_index++;
}
pIUnknown->Release();
if (!bIntfFound)
{
ERR(("Can't get a plugin interface we support!\n"));
return FALSE;
}
*ppIntfOem = (PVOID)pIPrintOem;
*piidIntfOem = *PrintOem_IIDs[iid_index];
return TRUE;
}
#ifdef __cplusplus
}
#endif