|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996.
//
// File: surrogat.cxx
//
// Contents: Entry point for dll surrogate process
//
// Synopsis: this is the entry point for a surrogate process. It must
// perform the following tasks
// 1. Initialize OLE (multithreaded)
// 2. Create an object which implements ISurrogate, and register
// it with COM via CoRegisterSurrogateEx
// 3. Wait for all loaded dlls to be unloadable
// 4. Uninitialize OLE
//
// Functions: WinMain
// GetCommandLineArguments
//
// History: 21-May-96 t-AdamE Created
// 09-Apr-98 WilfR Modified for Unified Surrogate
// 07-Jul-01 EgidioS Set env variable to load server flavor
// of URT when running in a server box.
//
//--------------------------------------------------------------------------
#include <windows.h>
#include "csrgt.hxx"
#include "surrogat.hxx"
#include "srgtdeb.hxx"
#include "debug.hxx"
DECLARE_INFOLEVEL(Surrogate); // debug only
// defined in unisrgt.idl (*.h)
STDAPI CoRegisterSurrogateEx( REFGUID rguidProcess, ISurrogate* pSurrogate );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { GUID guidProcessID; // will hold the ProcessID of this surrogate
CHAR rgargv[cCmdLineArguments][MAX_PATH + 1]; LPSTR argv[] = {rgargv[iProcessIDArgument]}; HRESULT hr; LPSTR pProcessID; WCHAR wszProcessID[MAX_GUIDSTR_LEN + 1];
#if DBG == 1
// check registry flags to break on launch (for debug)
if( DebugFlags::DebugBreakOnLaunchDllHost() ) { DebugBreak(); } #endif
// command line format should be:
// New Style: (/ProcessID:<process guid>)
// Old style: ({appid guid})
if(GetCommandLineArguments(lpCmdLine, argv,cCmdLineArguments,MAX_PATH) < 1) { Win4Assert( !"GetCommandLineArguments failed" ); return 0; }
// First Try new Style
// separate the cmdline switch from the cmdline arg (at the ':')
for( pProcessID = argv[iProcessIDArgument]; *pProcessID != 0; pProcessID++ ) { // this will zap the colon
if(*pProcessID == ':') { *pProcessID++ = '\0'; break; } }
#if 0
// verify that the cmdline switch is what we are looking for
if((*pProcessID == 0) || (lstrcmpiA(argv[iProcessIDArgument], szProcessIDSwitch) != 0)) { Win4Assert( !"Couldn't find /ProcessID:" ); return 0; } #else
if((*pProcessID == 0) || (lstrcmpiA(argv[iProcessIDArgument], szProcessIDSwitch) != 0)) pProcessID = argv[iProcessIDArgument]; #endif
// we need a unicode string in order to get a guid, so convert
// the ansi clsid string to unicode
if(!(MultiByteToWideChar(CP_ACP, 0, pProcessID, lstrlenA(pProcessID) + 1, wszProcessID, MAX_GUIDSTR_LEN + 1))) { Win4Assert( !"MultiByteToWideChar failed" ); return 0; }
// convert the ProcessID from a string to a guid
if(FAILED(CLSIDFromString(wszProcessID,&guidProcessID))) { Win4Assert( !"CLSIDFromString failed" ); return 0; }
if(FAILED(CoInitializeEx(NULL,COINIT_MULTITHREADED))) { Win4Assert( !"CoInitEx failed" ); return 0; }
// HACK: If Whistler server and above, force the process to use .NET mscorsvr.dll.
// For server apps. this version of the .NET runtime performs better.
if (IsServerOS()) { SetEnvironmentVariableW(L"ComPlus_BuildFlavor", L"SVR"); }
// Hand the thread to OLE for the duration
hr = CoRegisterSurrogateEx(guidProcessID, NULL);
CoUninitialize();
// Because some of our threads don't exit cleanly, and can AV
// in those situations, we don't die gracefully.
TerminateProcess(GetCurrentProcess(), 0); return 0; }
//+---------------------------------------------------------------------------
//
// Function: GetCommandLineArguments
//
// Synopsis: Parses a the application's command line into a format
// similar to the
// argv parameter of the entry point main for console apps
// Spaces are the delimiters
//
// Arguments: [rgwszArgs] -- an array of pointers to allocated Unicode
// buffers
// [cMaxArgs] -- This is the size of the rgwszArgs array (the
// maximum number of arguments the array can hold).
// [cMaxArgLen] -- The maximum size of each buffer
//
// Returns: if successful, the function returns the number of arguments
// parsed from the command line. If the length of any argument
// exceeds cMaxArgLen, the function fails and returns 0.
//
// The function quits parsing and returns as soon as either of
// the following conditions is met:
// 1. It reaches the end of the string, or
// 2. It parses cMaxArgs arguments.
//
// Notes: does not work with quoted arguments
//
// History: 6-21-96 t-Adame Created
//
//----------------------------------------------------------------------------
// REVIEW: when we had several commandline parameters this function was
// justified, but now that the Surrogate has only one parameter, is all this
// really necessary?
int GetCommandLineArguments(LPSTR szCmdLine, LPSTR rgszArgs[], int cMaxArgs, int cMaxArgLen) { int cchlen = lstrlenA(szCmdLine); int cArgsRetrieved = 0; int ichStart = 0;
for(int ich = 0;ich < cchlen; ich++) { if(ichStart > cMaxArgLen) { return 0; }
CHAR chcur = *(szCmdLine++); if(chcur == ' ')// REVIEW: no tab delimiting -- is this good?
{ if(ichStart) { rgszArgs[cArgsRetrieved++][ichStart] = '\0'; ichStart = 0;
if(cArgsRetrieved == cMaxArgs) { return cArgsRetrieved; }
} } else { rgszArgs[cArgsRetrieved][ichStart++] = chcur; } }
if(ichStart) { rgszArgs[cArgsRetrieved][ichStart] = '\0'; cArgsRetrieved++; }
return cArgsRetrieved; }
//+---------------------------------------------------------------------------
//
// Function: IsServerOS
//
// Synopsis: Checks if we are running on a Whistler server machine.
//
// Arguments: None.
//
// Returns: TRUE if Whistler server/advanced/datacenter.
// FALSE otherwise.
//
// Notes: None.
//
// History: 7-12-01 egidios Created
//
//----------------------------------------------------------------------------
BOOL IsServerOS(void) { // Note the following structure is only supported for NT 5.0
OSVERSIONINFOEX osverex; osverex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (::GetVersionEx((OSVERSIONINFO*)&osverex)) { if (osverex.dwPlatformId == VER_PLATFORM_WIN32_NT) { if ((osverex.dwMajorVersion == 5 && osverex.dwMinorVersion >= 1) || // >= WinXP
(osverex.dwMajorVersion > 5)) { if (osverex.wSuiteMask & VER_SUITE_PERSONAL) { return FALSE; } else if (osverex.wProductType == VER_NT_WORKSTATION) { return FALSE; } else if (osverex.wProductType == VER_NT_SERVER) { return TRUE; } else if (osverex.wSuiteMask & VER_SUITE_ENTERPRISE) { return TRUE; } else if (osverex.wSuiteMask & VER_SUITE_DATACENTER) { return TRUE; } } } }
return FALSE; }
|