/*++ 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); }