windows-nt/Source/XPSP1/NT/com/ole32/dllhost/surrogat.cxx
2020-09-26 16:20:57 +08:00

203 lines
5.6 KiB
C++

//+-------------------------------------------------------------------------
//
// 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
//
//--------------------------------------------------------------------------
#include <iostream.h>
#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;
}
// 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;
}