2020-09-30 17:12:29 +02:00

403 lines
11 KiB
C++

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
ObjEx.cxx
Abstract:
Main entry point for the object exporter service.
Author:
Mario Goertzel [MarioGo]
Revision History:
MarioGo 02-28-95 Bits 'n pieces
--*/
#include <or.hxx>
#ifndef _CHICAGO_
DECLARE_INFOLEVEL(Cairole) // BUGBUG: strictly for private memory stuff from storage
// elide ASAP
#endif // _CHICAGO_
#if DBG
#include <fstream.h>
#endif
extern "C"
{
#define SECURITY_WIN32 // Used by sspi.h
#include <sspi.h> // EnumerateSecurityPackages
}
//
// Process globals - read-only except during init.
//
// MID of the string bindings for this machine -- the bindings are phoney
// for this shared memory version of the resolver.
DUALSTRINGARRAY *gpLocalDSA;
MID gLocalMID;
CMid *gpLocalMid;
CProcess *gpProcess; // pointer to our process object
CProcess *gpPingProcess; // pointer to pinging process
//
// Process globals - read-write
//
void * pSharedBase;
CSharedGlobals *GlobalBlock;
#ifndef _CHICAGO_
CSmAllocator gsmDCOMAllocator;
#endif // _CHICAGO_
COxidTable * gpOxidTable;
COidTable * gpOidTable;
CMidTable * gpMidTable;
CProcessTable * gpProcessTable;
USHORT *gpcRemoteProtseqs; // count of remote protseqs
USHORT *gpRemoteProtseqIds; // array of remote protseq ids
PWSTR gpwstrProtseqs; // remote protseqs strings catenated
DUALSTRINGARRAY *gpdsaMyBindings; // DUALSTRINGARRAY of local OR's bindings
LONG * gpIdSequence;
FILETIME MyCreationTime;
DWORD MyProcessId;
DWORD *gpdwLastCrashedProcessCheckTime;
DWORD *gpNextThreadID;
CGlobalMutex *gpMutex; // global mutex to protect shared memory
BOOL DCOM_Started = FALSE;
ID ProcessMarker; // sanity checking marker for the process object
CResolverHashTable *gpClientSetTable = 0;
//+-------------------------------------------------------------------------
//
// Function: ComputeSecurity
//
// Synopsis: Looks up some registry keys and enumerates the security
// packages on this machine.
//
//--------------------------------------------------------------------------
// These variables hold values read out of the registry and cached.
// s_fEnableDCOM is false if DCOM is disabled. The others contain
// authentication information for legacy applications.
BOOL s_fEnableDCOM;
DWORD s_lAuthnLevel;
DWORD s_lImpLevel;
BOOL s_fMutualAuth;
BOOL s_fSecureRefs;
// s_sServerSvc is a list of security providers that OLE servers can use.
// s_aClientSvc is a list of security providers that OLE clients can use.
// The difference is that Chicago only supports the client side of some
// security providers and OLE servers must know how to determine the
// principal name for the provider. Clients get the principal name from
// the server.
DWORD s_cServerSvc = 0;
USHORT *s_aServerSvc = NULL;
DWORD s_cClientSvc = 0;
USHORT *s_aClientSvc = NULL;
BOOL fSecurityComputed = FALSE;
void ComputeSecurity()
{
SecPkgInfo *pAllPkg;
SecPkgInfo *pNext;
HRESULT hr;
DWORD i;
DWORD lMaxLen;
HKEY hKey;
DWORD lType;
DWORD lData;
DWORD lDataSize;
if (fSecurityComputed) return;
fSecurityComputed = TRUE;
// Get the list of security packages.
hr = EnumerateSecurityPackages( &lMaxLen, &pAllPkg );
if (hr == 0)
{
// Allocate memory for both service lists.
s_aServerSvc = new USHORT[lMaxLen];
s_aClientSvc = new USHORT[lMaxLen];
if (s_aServerSvc == NULL || s_aClientSvc == NULL)
{
hr = E_OUTOFMEMORY;
delete s_aServerSvc;
delete s_aClientSvc;
s_aServerSvc = NULL;
s_aClientSvc = NULL;
}
else
{
// Check all packages.
ASSERT((s_cClientSvc == 0) && (s_cServerSvc == 0));
pNext = pAllPkg;
for (i = 0; i < lMaxLen; i++)
{
// Determine if clients can use the package.
if ((pNext->fCapabilities & (SECPKG_FLAG_DATAGRAM |
SECPKG_FLAG_CONNECTION)))
{
s_aClientSvc[s_cClientSvc++] = pNext->wRPCID;
}
// BUGBUG - Add flag for NT principal names
// Determine is servers can use the package.
if ( (pNext->fCapabilities & (SECPKG_FLAG_DATAGRAM |
SECPKG_FLAG_CONNECTION)) &&
~(pNext->fCapabilities & (SECPKG_FLAG_CLIENT_ONLY)))
{
s_aServerSvc[s_cServerSvc++] = pNext->wRPCID;
}
pNext++;
}
}
// Release the list of security packages.
FreeContextBuffer( pAllPkg );
}
// Set all the security flags to their default values.
#ifdef _CAIRO_
s_fEnableDCOM = TRUE;
#else
s_fEnableDCOM = FALSE;
#endif
s_lAuthnLevel = RPC_C_AUTHN_LEVEL_NONE; // BUGBUG: temp workaround
s_lImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
s_fMutualAuth = FALSE;
s_fSecureRefs = FALSE;
// Open the security key.
hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\OLE",
NULL, KEY_QUERY_VALUE, &hKey );
if (hr != ERROR_SUCCESS)
return;
// Query the value for DisableDCOM.
lDataSize = sizeof(lData );
hr = RegQueryValueEx( hKey, L"EnableDCOM", NULL, &lType,
(unsigned char *) &lData, &lDataSize );
if (hr == ERROR_SUCCESS && lType == REG_SZ && lDataSize != 0)
{
if (*((WCHAR *) &lData) == L'y' ||
*((WCHAR *) &lData) == L'Y')
s_fEnableDCOM = TRUE;
}
// Query the value for the authentication level.
lDataSize = sizeof(lData );
hr = RegQueryValueEx( hKey, L"LegacyAuthenticationLevel", NULL,
&lType, (unsigned char *) &lData, &lDataSize );
if (hr == ERROR_SUCCESS && lType == REG_DWORD)
{
s_lAuthnLevel = lData;
}
// Query the value for the impersonation level.
lDataSize = sizeof(lData );
hr = RegQueryValueEx( hKey, L"LegacyImpersonationLevel", NULL,
&lType, (unsigned char *) &lData, &lDataSize );
if (hr == ERROR_SUCCESS && lType == REG_DWORD)
{
s_lImpLevel = lData;
}
// Query the value for mutual authentication.
lDataSize = sizeof(lData );
hr = RegQueryValueEx( hKey, L"LegacyMutualAuthentication", NULL,
&lType, (unsigned char *) &lData, &lDataSize );
if (hr == ERROR_SUCCESS && lType == REG_SZ && lDataSize != 0)
{
if (*((WCHAR *) &lData) == L'y' ||
*((WCHAR *) &lData) == L'Y')
s_fMutualAuth = TRUE;
}
// Query the value for secure interface references.
lDataSize = sizeof(lData );
hr = RegQueryValueEx( hKey, L"LegacySecureReferences", NULL,
&lType, (unsigned char *) &lData, &lDataSize );
if (hr == ERROR_SUCCESS && lType == REG_SZ && lDataSize != 0)
{
if (*((WCHAR *) &lData) == L'y' ||
*((WCHAR *) &lData) == L'Y')
s_fSecureRefs = TRUE;
}
// Close the registry key.
RegCloseKey( hKey );
}
//
// Startup
//
//+-------------------------------------------------------------------------
//
// Function: InitDCOMSharedAllocator
//
// Synopsis: Initialises a shared memory region for this process for DCOM use.
//
// Returns: status code
//
// History: 20-Nov-95 HenryLee Created (SatishT modifiied)
//
// Notes: This routine is called indirectly by DfCreateSharedAllocator
// such a way that in most circumstances it will be executed
// exactly once per docfile open.
//
//--------------------------------------------------------------------------
HRESULT InitDCOMSharedAllocator(ULONG DCOMSharedHeapName, void * &pSharedBase)
{
HRESULT hr = S_OK;
CSmAllocator *pMalloc = &gSharedAllocator;
if (pSharedBase == NULL) // allocate a new heap
{
#ifdef MULTIHEAP
// reset the allocator state to initialize it properly
pMalloc->SetState (NULL, NULL, NULL, NULL, 0);
#endif // MULTIHEAP
hr = pMalloc->Init (
#ifdef MULTIHEAP
DCOMSharedHeapName, FALSE
#else
L"DCOMResolverSharedHeap"
#endif // MULTIHEAP
);
if ( SUCCEEDED(hr) )
{
pMalloc->AddRef();
pSharedBase = pMalloc->GetBase();
pMalloc->Alloc(8); // avoid using NULL value for based pointer
}
}
return hr;
}
static CONST PWSTR gpwstrProtocolsPath = L"Software\\Microsoft\\Rpc";
static CONST PWSTR gpwstrProtocolsValue = L"DCOM Protocols";
HRESULT MallocInitialize(BOOL fForceLocalAlloc);
ORSTATUS StartDCOM(
void
)
/*++
Routine Description:
Primes the distributed object mechanisms, in particular by initializing
shared memory access and structures.
Arguments:
None
Return Value:
None
--*/
{
ORSTATUS status = OR_OK;
if (DCOM_Started)
{
return OR_REPEAT_START;
}
// initialize process identity variables
MyProcessId = GetCurrentProcessId();
// create or find the global mutex
gpMutex = new CGlobalMutex(status);
Win4Assert((status == OR_OK) && "CSharedGlobals create global mutex failed");
{
CProtectSharedMemory protector; // locks throughout lexical scope
// Lookup security data.
ComputeSecurity();
#if DBG // read names from sm.ini to avoid reboot
#ifndef _CHICAGO_
ULONG DCOMSharedHeapName = GetProfileInt(
TEXT("DCOM95 Test"), // section name
TEXT("SharedHeapName"), // key name
1111 // default name
);
WCHAR SharedGlobalBlockName[10];
swprintf(SharedGlobalBlockName,TEXT("DCOMB%d"),DCOMSharedHeapName);
#else
WCHAR *SharedGlobalBlockName = DCOMSharedGlobalBlockName;
#endif // _CHICAGO_
#endif // DBG
// Allocate tables, but only if we are in first
ComDebOut((DEB_ITRACE,"DCOMSharedHeapName = %d\n", DCOMSharedHeapName));
ComDebOut((DEB_ITRACE,"SharedGlobalBlockName = %ws\n", SharedGlobalBlockName));
InitDCOMSharedAllocator(DCOMSharedHeapName,pSharedBase);
CSharedGlobals *GlobalBlock
= new CSharedGlobals(SharedGlobalBlockName,status);
}
// BUGBUG: check status, and if not good, do what??
// Allocate lists
gLocalMID = gpLocalMid->GetMID();
// initialize timestamp for crash checking
*gpdwLastCrashedProcessCheckTime = 0;
if ( status != OR_OK
|| !gpOxidTable
|| !gpOidTable
|| !gpMidTable
|| !gpLocalDSA
|| !gpLocalMid
|| !gpPingProcess
|| !gpIdSequence
)
{
return(OR_NOMEM);
}
DCOM_Started = TRUE;
return(OR_OK);
}