Source code of Windows XP (NT5)
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.

202 lines
5.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: surrogat.cxx
  7. //
  8. // Contents: Entry point for dll surrogate process
  9. //
  10. // Synopsis: this is the entry point for a surrogate process. It must
  11. // perform the following tasks
  12. // 1. Initialize OLE (multithreaded)
  13. // 2. Create an object which implements ISurrogate, and register
  14. // it with COM via CoRegisterSurrogateEx
  15. // 3. Wait for all loaded dlls to be unloadable
  16. // 4. Uninitialize OLE
  17. //
  18. // Functions: WinMain
  19. // GetCommandLineArguments
  20. //
  21. // History: 21-May-96 t-AdamE Created
  22. // 09-Apr-98 WilfR Modified for Unified Surrogate
  23. //
  24. //--------------------------------------------------------------------------
  25. #include <iostream.h>
  26. #include <windows.h>
  27. #include "csrgt.hxx"
  28. #include "surrogat.hxx"
  29. #include "srgtdeb.hxx"
  30. #include "debug.hxx"
  31. DECLARE_INFOLEVEL(Surrogate); // debug only
  32. // defined in unisrgt.idl (*.h)
  33. STDAPI CoRegisterSurrogateEx( REFGUID rguidProcess, ISurrogate* pSurrogate );
  34. int WINAPI WinMain(
  35. HINSTANCE hInstance,
  36. HINSTANCE hPrevInstance,
  37. LPSTR lpCmdLine,
  38. int nCmdShow)
  39. {
  40. GUID guidProcessID; // will hold the ProcessID of this surrogate
  41. CHAR rgargv[cCmdLineArguments][MAX_PATH + 1];
  42. LPSTR argv[] = {rgargv[iProcessIDArgument]};
  43. HRESULT hr;
  44. LPSTR pProcessID;
  45. WCHAR wszProcessID[MAX_GUIDSTR_LEN + 1];
  46. #if DBG == 1
  47. // check registry flags to break on launch (for debug)
  48. if( DebugFlags::DebugBreakOnLaunchDllHost() )
  49. {
  50. DebugBreak();
  51. }
  52. #endif
  53. // command line format should be:
  54. // New Style: (/ProcessID:<process guid>)
  55. // Old style: ({appid guid})
  56. if(GetCommandLineArguments(lpCmdLine, argv,cCmdLineArguments,MAX_PATH) < 1)
  57. {
  58. Win4Assert( !"GetCommandLineArguments failed" );
  59. return 0;
  60. }
  61. // First Try new Style
  62. // separate the cmdline switch from the cmdline arg (at the ':')
  63. for( pProcessID = argv[iProcessIDArgument]; *pProcessID != 0; pProcessID++ )
  64. {
  65. // this will zap the colon
  66. if(*pProcessID == ':')
  67. {
  68. *pProcessID++ = '\0';
  69. break;
  70. }
  71. }
  72. #if 0
  73. // verify that the cmdline switch is what we are looking for
  74. if((*pProcessID == 0) ||
  75. (lstrcmpiA(argv[iProcessIDArgument], szProcessIDSwitch) != 0))
  76. {
  77. Win4Assert( !"Couldn't find /ProcessID:" );
  78. return 0;
  79. }
  80. #else
  81. if((*pProcessID == 0) ||
  82. (lstrcmpiA(argv[iProcessIDArgument], szProcessIDSwitch) != 0))
  83. pProcessID = argv[iProcessIDArgument];
  84. #endif
  85. // we need a unicode string in order to get a guid, so convert
  86. // the ansi clsid string to unicode
  87. if(!(MultiByteToWideChar(CP_ACP, 0, pProcessID, lstrlenA(pProcessID) + 1,
  88. wszProcessID, MAX_GUIDSTR_LEN + 1)))
  89. {
  90. Win4Assert( !"MultiByteToWideChar failed" );
  91. return 0;
  92. }
  93. // convert the ProcessID from a string to a guid
  94. if(FAILED(CLSIDFromString(wszProcessID,&guidProcessID)))
  95. {
  96. Win4Assert( !"CLSIDFromString failed" );
  97. return 0;
  98. }
  99. if(FAILED(CoInitializeEx(NULL,COINIT_MULTITHREADED)))
  100. {
  101. Win4Assert( !"CoInitEx failed" );
  102. return 0;
  103. }
  104. // Hand the thread to OLE for the duration
  105. hr = CoRegisterSurrogateEx(guidProcessID, NULL);
  106. CoUninitialize();
  107. // Because some of our threads don't exit cleanly, and can AV
  108. // in those situations, we don't die gracefully.
  109. TerminateProcess(GetCurrentProcess(), 0);
  110. return 0;
  111. }
  112. //+---------------------------------------------------------------------------
  113. //
  114. // Function: GetCommandLineArguments
  115. //
  116. // Synopsis: Parses a the application's command line into a format
  117. // similar to the
  118. // argv parameter of the entry point main for console apps
  119. // Spaces are the delimiters
  120. //
  121. // Arguments: [rgwszArgs] -- an array of pointers to allocated Unicode
  122. // buffers
  123. // [cMaxArgs] -- This is the size of the rgwszArgs array (the
  124. // maximum number of arguments the array can hold).
  125. // [cMaxArgLen] -- The maximum size of each buffer
  126. //
  127. // Returns: if successful, the function returns the number of arguments
  128. // parsed from the command line. If the length of any argument
  129. // exceeds cMaxArgLen, the function fails and returns 0.
  130. //
  131. // The function quits parsing and returns as soon as either of
  132. // the following conditions is met:
  133. // 1. It reaches the end of the string, or
  134. // 2. It parses cMaxArgs arguments.
  135. //
  136. // Notes: does not work with quoted arguments
  137. //
  138. // History: 6-21-96 t-Adame Created
  139. //
  140. //----------------------------------------------------------------------------
  141. // REVIEW: when we had several commandline parameters this function was
  142. // justified, but now that the Surrogate has only one parameter, is all this
  143. // really necessary?
  144. int GetCommandLineArguments(LPSTR szCmdLine, LPSTR rgszArgs[], int cMaxArgs, int cMaxArgLen)
  145. {
  146. int cchlen = lstrlenA(szCmdLine);
  147. int cArgsRetrieved = 0;
  148. int ichStart = 0;
  149. for(int ich = 0;ich < cchlen; ich++)
  150. {
  151. if(ichStart > cMaxArgLen)
  152. {
  153. return 0;
  154. }
  155. CHAR chcur = *(szCmdLine++);
  156. if(chcur == ' ')// REVIEW: no tab delimiting -- is this good?
  157. {
  158. if(ichStart)
  159. {
  160. rgszArgs[cArgsRetrieved++][ichStart] = '\0';
  161. ichStart = 0;
  162. if(cArgsRetrieved == cMaxArgs)
  163. {
  164. return cArgsRetrieved;
  165. }
  166. }
  167. }
  168. else
  169. {
  170. rgszArgs[cArgsRetrieved][ichStart++] = chcur;
  171. }
  172. }
  173. if(ichStart)
  174. {
  175. rgszArgs[cArgsRetrieved][ichStart] = '\0';
  176. cArgsRetrieved++;
  177. }
  178. return cArgsRetrieved;
  179. }