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.
 
 
 
 
 
 

505 lines
12 KiB

/*
* E N T R Y . C P P
*
* Entrypoints for Caligula DLLs
*
* Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
*/
#include "_davfs.h"
#include "_shlkmgr.h"
#include <langtocpid.h>
#include <ex\idlethrd.h>
#include <ntverp.h>
#include <iisver.h>
// Global items --------------------------------------------------------------
//
EXTERN_C const CHAR gc_szSignature[] = "HTTPEXT";
EXTERN_C const WCHAR gc_wszSignature[] = L"HTTPEXT";
HINSTANCE g_hinst = NULL;
WCHAR gc_wszDllPath[MAX_PATH+1];
CHAR gc_szVersion[] = VER_PRODUCTVERSION_STR;
// Per process instance data -------------------------------------------------
//
class CImplInst : private RefCountedGlobal<CImplInst, HSE_VERSION_INFO *>
{
//
// Friend declarations required by RefCountedGlobal template
//
friend class Singleton<CImplInst>;
friend class RefCountedGlobal<CImplInst, HSE_VERSION_INFO *>;
//
// Flags to track initialization progress so we know
// how much to uninitialize if initialization fails overall
//
BOOL m_fInitializedHeap;
// CREATORS
//
// Declared private to ensure that arbitrary instances
// of this class cannot be created. The Singleton
// template (declared as a friend above) controls
// the sole instance of this class.
//
CImplInst() :
m_fInitializedHeap(FALSE)
{
}
BOOL FInit( HSE_VERSION_INFO * pver );
~CImplInst();
//
// Array of strings used in service state change
// event log messages.
//
static LPCSTR mc_rgszLogServiceStateChange[];
// NOT IMPLEMENTED
//
CImplInst( const CImplInst& );
CImplInst& operator=( const CImplInst& );
public:
using RefCountedGlobal<CImplInst, HSE_VERSION_INFO *>::DwInitRef;
using RefCountedGlobal<CImplInst, HSE_VERSION_INFO *>::DeinitRef;
};
LPCSTR CImplInst::mc_rgszLogServiceStateChange[] = { gc_szSignature, gc_szVersion };
STGOPENSTORAGEONHANDLE g_pfnStgOpenStorageOnHandle = NULL;
#ifdef DBG
BOOL g_fDavTrace = FALSE;
DEC_CONST CHAR gc_szDbgIni[] = "HTTPEXT.INI";
DEC_CONST INT gc_cchDbgIni = CchConstString(gc_szDbgIni);
#endif
// ------------------------------------------------------------------------
//
// CImplInst::FInit()
//
// Second-phase (failable) CImplInst constructor. Code that instantiates
// the CImplInst should call this function after instantiation. If the
// call returns FALSE, calling code should immediately destroy the
// CImplInst.
//
BOOL
CImplInst::FInit( HSE_VERSION_INFO * pver )
{
BOOL fSuccess = FALSE;
//
// Handle exceptions locally. If anything below throws
// an exception then fail the initialization.
//
try
{
HINSTANCE hLib;
// First and foremost, check to ensure that
// our resources are well attached and accessible
// if this fails, then we want to fail our loading.
//
if (!LoadStringA (g_hinst,
IDS_ExtensionName,
pver->lpszExtensionDesc,
sizeof(pver->lpszExtensionDesc)))
goto Exit;
// Setup the HSE version numbering
//
pver->dwExtensionVersion = MAKELONG (HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
#ifdef DBG
// Do the DBG tracing initialization
//
g_fDavTrace = GetPrivateProfileIntA (gc_szDbgTraces,
gc_szSignature,
FALSE,
gc_szDbgIni);
#endif // DBG
// Init the heap allocators
//
if ( !g_heap.FInit() )
goto Exit;
m_fInitializedHeap = TRUE;
// Initialize the resource string cache
//
if ( !FInitResourceStringCache() )
goto Exit;
// Init the volume type cache
//
if ( !FInitVolumeTypeCache() )
goto Exit;
// Init the parser
//
if ( !CDAVExt::FVersion (pver) )
goto Exit;
// Create shared lock mgr
//
if (FAILED(CSharedLockMgr::CreateInstance().HrInitialize()))
goto Exit;
// Create the thread pool
//
if (!CPoolManager::FInit())
goto Exit;
// Start the idle thread
//
if ( !FInitIdleThread() )
goto Exit;
// Init the cache mapping accept language string to cpid
// cache used to decode non-UTF8 characters in URLs
//
if (!CLangToCpidCache::FCreateInstance())
goto Exit;
// If this API is not available on ole32.dll. we'll not be able
// to operate properties, but we should still work to some extent
// so we'll take care of the NULL function pointer in our code.
// don't fail now
//
// Don't use relative paths for dlls, It is easy to put suspect dlls
// somewhere in an application's path. Always use absolute paths.
//
CHAR szOle32Path[MAX_PATH+1];
UINT cSystemDir;
// Get the system directory
//
cSystemDir = GetSystemDirectory (szOle32Path, CElems(szOle32Path));
// GetSystemDirectory will return
// 1. the number of characters copied if it succeeds (excluding the
// terminating NULL)
// 2. 0 if it fails
// 3. the number of characters required if the supplied buffer is
// too smallto hold the path.
// Since we gave enough space for the system
// directory, we will treat "buffer not enough" errors as failures.
//
if ((0 < cSystemDir) && (CElems(szOle32Path) > cSystemDir))
{
// GetSystemDirectory path does not end with a backslash
//
if (CElems("\\ole32.dll") + cSystemDir <= CElems(szOle32Path))
{
strcat(szOle32Path, "\\ole32.dll");
hLib = LoadLibraryA (szOle32Path);
if (hLib)
{
g_pfnStgOpenStorageOnHandle = (STGOPENSTORAGEONHANDLE)
GetProcAddress (hLib, "StgOpenStorageOnHandle");
}
}
}
// Start up event log message takes two parameters
// the signature and the version
//
#undef LOG_STARTUP_EVENT
#ifdef LOG_STARTUP_EVENT
LogEvent (DAVPRS_SERVICE_STARTUP,
EVENTLOG_INFORMATION_TYPE,
sizeof(mc_rgszLogServiceStateChange) / sizeof(LPCSTR),
mc_rgszLogServiceStateChange,
0,
NULL);
#endif // LOG_STARTUP_EVENT
}
catch ( CDAVException& )
{
goto Exit;
}
fSuccess = TRUE;
Exit:
return fSuccess;
}
// ------------------------------------------------------------------------
//
// CImplInst::~CImplInst()
//
CImplInst::~CImplInst()
{
//
// DO NOT allow exceptions to propagate out of this call.
// This is intended as a safety valve only. In order to
// avoid leaking instance data, individual instance data
// components should handle any exceptions themselves.
//
try
{
//
// If we logged a startup message, then log a shutdown message
//
#undef LOG_STARTUP_EVENT
#ifdef LOG_STARTUP_EVENT
LogEvent (DAVPRS_SERVICE_SHUTDOWN,
EVENTLOG_INFORMATION_TYPE,
sizeof(mc_rgszLogServiceStateChange) / sizeof(LPCSTR),
mc_rgszLogServiceStateChange,
0,
NULL);
#endif // LOG_STARTUP_EVENT
//
// Deinit the idle thread. Do this before taking down the
// thread pool there may be delayed thread pool work items
// pending on the idle thread.
//
DeleteIdleThread();
//
// Deinit the thread pool
//
CPoolManager::Deinit();
// Deinit the language string to cpid cache
//
CLangToCpidCache::DestroyInstance();
//
// remove the IDBCreateCommand if exist
//
ReleaseDBCreateCommandObject();
// Destroy shared lock mgr
//
CSharedLockMgr::DestroyInstance();
// Shutdown the parser
//
(void) CDAVExt::FTerminate ();
// Deinit the volume type cache
//
DeinitVolumeTypeCache();
// Clean out the security-thread-token cache.
//
CleanupSecurityToken();
// Deinit the resource string cache
//
DeinitResourceStringCache();
// Destroy allocators
//
if ( m_fInitializedHeap )
g_heap.Deinit();
}
catch ( CDAVException& )
{
}
}
// ------------------------------------------------------------------------
//
// Instance refcounting callouts from _davprs
//
VOID AddRefImplInst()
{
HSE_VERSION_INFO lVer;
DWORD cRef;
cRef = CImplInst::DwInitRef(&lVer);
//
// We should already have at least one ref on the instance
// before we called DwInitRef(), so we should more than one
// ref after the call.
//
Assert( cRef > 1 );
}
VOID ReleaseImplInst()
{
CImplInst::DeinitRef();
}
// IIS Entrypoints -----------------------------------------------------------
//
EXTERN_C BOOL WINAPI
FGetExtensionVersion (HSE_VERSION_INFO * pver)
{
CWin32ExceptionHandler win32ExceptionHandler;
//
// Initialize one instance reference and return whether it succeeded.
//
return !!CImplInst::DwInitRef( pver );
}
EXTERN_C BOOL WINAPI
FTerminateDavFS (DWORD)
{
CWin32ExceptionHandler win32ExceptionHandler;
//
// Deinitialize one instance reference
//
CImplInst::DeinitRef();
//
// After the instance data has been released, we are ready to terminate.
//
return TRUE;
}
EXTERN_C DWORD WINAPI
DwDavFSExtensionProc (LPEXTENSION_CONTROL_BLOCK pecb)
{
HSE_VERSION_INFO lVer;
DWORD dwHSEStatusRet = HSE_STATUS_ERROR;
if ( CImplInst::DwInitRef(&lVer) )
{
dwHSEStatusRet = CDAVExt::DwMain(pecb);
CImplInst::DeinitRef();
}
return dwHSEStatusRet;
}
// Win32 DLL Entrypoints -----------------------------------------------------
//
EXTERN_C BOOL WINAPI
DllMain (HINSTANCE hinst, DWORD dwReason, LPVOID lpvReserved)
{
switch (dwReason)
{
default:
{
DebugTrace ("FInitHttpExtDll(), unknown reason\n");
return FALSE;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
{
//
// We disable thread library calls (see below),
// so we should never see DLL_THREAD_ATTACH or
// DLL_THREAD_DETACH.
//
Assert (FALSE);
//
// But if we do, it doesn't harm anything.
//
return TRUE;
}
case DLL_PROCESS_ATTACH:
{
//
// Init .INI file tagged debug traces
//
InitTraces();
// Cache the inst
//
g_hinst = hinst;
// And the full path to the DLL
//
if ( !GetModuleFileNameW( hinst, gc_wszDllPath, sizeof(gc_wszDllPath)/sizeof(WCHAR) ) )
{
DebugTrace( "FInitHttpExtDll() - GetModuleFileName() failed in DLL_PROCESS_ATTACH\n" );
return FALSE;
}
// Call the parser's initialization for every call into our
// DLL initialization proc. The order of operations here is
// fairly important. The parser should be called after we do
// our processing in the non-DETACH case.
//
if ( !CDAVExt::FInitializeDll (hinst, dwReason) )
return FALSE;
// We are going to disable thread library calls. If the parser
// really ever needs these then the this needs to change.
//
DisableThreadLibraryCalls (hinst);
return TRUE;
}
case DLL_PROCESS_DETACH:
{
// And in the detach case, the impl. gets the last word.
// Ignore any failures -- the DLL is being unloaded and
// the process is going away whether we like it or not.
//
(void) CDAVExt::FInitializeDll (hinst, dwReason);
return TRUE;
}
}
}
// OLE Entrypoints -----------------------------------------------------------
//
STDAPI
HrDllCanUnloadNowDavFS (VOID)
{
return S_OK;
}
STDAPI
HrDllGetClassObjectDavFS (REFCLSID rclsid, REFIID riid, LPVOID * ppv)
{
return E_NOINTERFACE;
}
STDAPI
HrDllRegisterServerDavFS (VOID)
{
HRESULT hr;
// This is a "first line" entrypoint into our dll. Need to init some stuff.
// Right now, the heap is the only important piece.
//
g_heap.FInit();
// Everybody gets to register regardless of failures
//
hr = EventLogDllRegisterServer( gc_wszDllPath );
return hr;
}
STDAPI
HrDllUnregisterServerDavFS (VOID)
{
HRESULT hr;
// This is a "first line" entrypoint into our dll. Need to init some stuff.
// Right now, the heap is the only important piece.
//
g_heap.FInit();
// Everybody gets to unregister regardless of failures
//
hr = EventLogDllUnregisterServer();
return hr;
}