Leaked source code of windows server 2003
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.

265 lines
7.8 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. // 07-Jul-01 EgidioS Set env variable to load server flavor
  24. // of URT when running in a server box.
  25. //
  26. //--------------------------------------------------------------------------
  27. #include <windows.h>
  28. #include "csrgt.hxx"
  29. #include "surrogat.hxx"
  30. #include "srgtdeb.hxx"
  31. #include "debug.hxx"
  32. DECLARE_INFOLEVEL(Surrogate); // debug only
  33. // defined in unisrgt.idl (*.h)
  34. STDAPI CoRegisterSurrogateEx( REFGUID rguidProcess, ISurrogate* pSurrogate );
  35. int WINAPI WinMain(
  36. HINSTANCE hInstance,
  37. HINSTANCE hPrevInstance,
  38. LPSTR lpCmdLine,
  39. int nCmdShow)
  40. {
  41. GUID guidProcessID; // will hold the ProcessID of this surrogate
  42. CHAR rgargv[cCmdLineArguments][MAX_PATH + 1];
  43. LPSTR argv[] = {rgargv[iProcessIDArgument]};
  44. HRESULT hr;
  45. LPSTR pProcessID;
  46. WCHAR wszProcessID[MAX_GUIDSTR_LEN + 1];
  47. #if DBG == 1
  48. // check registry flags to break on launch (for debug)
  49. if( DebugFlags::DebugBreakOnLaunchDllHost() )
  50. {
  51. DebugBreak();
  52. }
  53. #endif
  54. // command line format should be:
  55. // New Style: (/ProcessID:<process guid>)
  56. // Old style: ({appid guid})
  57. if(GetCommandLineArguments(lpCmdLine, argv,cCmdLineArguments,MAX_PATH) < 1)
  58. {
  59. Win4Assert( !"GetCommandLineArguments failed" );
  60. return 0;
  61. }
  62. // First Try new Style
  63. // separate the cmdline switch from the cmdline arg (at the ':')
  64. for( pProcessID = argv[iProcessIDArgument]; *pProcessID != 0; pProcessID++ )
  65. {
  66. // this will zap the colon
  67. if(*pProcessID == ':')
  68. {
  69. *pProcessID++ = '\0';
  70. break;
  71. }
  72. }
  73. #if 0
  74. // verify that the cmdline switch is what we are looking for
  75. if((*pProcessID == 0) ||
  76. (lstrcmpiA(argv[iProcessIDArgument], szProcessIDSwitch) != 0))
  77. {
  78. Win4Assert( !"Couldn't find /ProcessID:" );
  79. return 0;
  80. }
  81. #else
  82. if((*pProcessID == 0) ||
  83. (lstrcmpiA(argv[iProcessIDArgument], szProcessIDSwitch) != 0))
  84. pProcessID = argv[iProcessIDArgument];
  85. #endif
  86. // we need a unicode string in order to get a guid, so convert
  87. // the ansi clsid string to unicode
  88. if(!(MultiByteToWideChar(CP_ACP, 0, pProcessID, lstrlenA(pProcessID) + 1,
  89. wszProcessID, MAX_GUIDSTR_LEN + 1)))
  90. {
  91. Win4Assert( !"MultiByteToWideChar failed" );
  92. return 0;
  93. }
  94. // convert the ProcessID from a string to a guid
  95. if(FAILED(CLSIDFromString(wszProcessID,&guidProcessID)))
  96. {
  97. Win4Assert( !"CLSIDFromString failed" );
  98. return 0;
  99. }
  100. if(FAILED(CoInitializeEx(NULL,COINIT_MULTITHREADED)))
  101. {
  102. Win4Assert( !"CoInitEx failed" );
  103. return 0;
  104. }
  105. // HACK: If Whistler server and above, force the process to use .NET mscorsvr.dll.
  106. // For server apps. this version of the .NET runtime performs better.
  107. if (IsServerOS())
  108. {
  109. SetEnvironmentVariableW(L"ComPlus_BuildFlavor", L"SVR");
  110. }
  111. // Hand the thread to OLE for the duration
  112. hr = CoRegisterSurrogateEx(guidProcessID, NULL);
  113. CoUninitialize();
  114. // Because some of our threads don't exit cleanly, and can AV
  115. // in those situations, we don't die gracefully.
  116. TerminateProcess(GetCurrentProcess(), 0);
  117. return 0;
  118. }
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Function: GetCommandLineArguments
  122. //
  123. // Synopsis: Parses a the application's command line into a format
  124. // similar to the
  125. // argv parameter of the entry point main for console apps
  126. // Spaces are the delimiters
  127. //
  128. // Arguments: [rgwszArgs] -- an array of pointers to allocated Unicode
  129. // buffers
  130. // [cMaxArgs] -- This is the size of the rgwszArgs array (the
  131. // maximum number of arguments the array can hold).
  132. // [cMaxArgLen] -- The maximum size of each buffer
  133. //
  134. // Returns: if successful, the function returns the number of arguments
  135. // parsed from the command line. If the length of any argument
  136. // exceeds cMaxArgLen, the function fails and returns 0.
  137. //
  138. // The function quits parsing and returns as soon as either of
  139. // the following conditions is met:
  140. // 1. It reaches the end of the string, or
  141. // 2. It parses cMaxArgs arguments.
  142. //
  143. // Notes: does not work with quoted arguments
  144. //
  145. // History: 6-21-96 t-Adame Created
  146. //
  147. //----------------------------------------------------------------------------
  148. // REVIEW: when we had several commandline parameters this function was
  149. // justified, but now that the Surrogate has only one parameter, is all this
  150. // really necessary?
  151. int GetCommandLineArguments(LPSTR szCmdLine, LPSTR rgszArgs[], int cMaxArgs, int cMaxArgLen)
  152. {
  153. int cchlen = lstrlenA(szCmdLine);
  154. int cArgsRetrieved = 0;
  155. int ichStart = 0;
  156. for(int ich = 0;ich < cchlen; ich++)
  157. {
  158. if(ichStart > cMaxArgLen)
  159. {
  160. return 0;
  161. }
  162. CHAR chcur = *(szCmdLine++);
  163. if(chcur == ' ')// REVIEW: no tab delimiting -- is this good?
  164. {
  165. if(ichStart)
  166. {
  167. rgszArgs[cArgsRetrieved++][ichStart] = '\0';
  168. ichStart = 0;
  169. if(cArgsRetrieved == cMaxArgs)
  170. {
  171. return cArgsRetrieved;
  172. }
  173. }
  174. }
  175. else
  176. {
  177. rgszArgs[cArgsRetrieved][ichStart++] = chcur;
  178. }
  179. }
  180. if(ichStart)
  181. {
  182. rgszArgs[cArgsRetrieved][ichStart] = '\0';
  183. cArgsRetrieved++;
  184. }
  185. return cArgsRetrieved;
  186. }
  187. //+---------------------------------------------------------------------------
  188. //
  189. // Function: IsServerOS
  190. //
  191. // Synopsis: Checks if we are running on a Whistler server machine.
  192. //
  193. // Arguments: None.
  194. //
  195. // Returns: TRUE if Whistler server/advanced/datacenter.
  196. // FALSE otherwise.
  197. //
  198. // Notes: None.
  199. //
  200. // History: 7-12-01 egidios Created
  201. //
  202. //----------------------------------------------------------------------------
  203. BOOL IsServerOS(void)
  204. {
  205. // Note the following structure is only supported for NT 5.0
  206. OSVERSIONINFOEX osverex;
  207. osverex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  208. if (::GetVersionEx((OSVERSIONINFO*)&osverex))
  209. {
  210. if (osverex.dwPlatformId == VER_PLATFORM_WIN32_NT)
  211. {
  212. if ((osverex.dwMajorVersion == 5 && osverex.dwMinorVersion >= 1) || // >= WinXP
  213. (osverex.dwMajorVersion > 5))
  214. {
  215. if (osverex.wSuiteMask & VER_SUITE_PERSONAL)
  216. {
  217. return FALSE;
  218. }
  219. else if (osverex.wProductType == VER_NT_WORKSTATION)
  220. {
  221. return FALSE;
  222. }
  223. else if (osverex.wProductType == VER_NT_SERVER)
  224. {
  225. return TRUE;
  226. }
  227. else if (osverex.wSuiteMask & VER_SUITE_ENTERPRISE)
  228. {
  229. return TRUE;
  230. }
  231. else if (osverex.wSuiteMask & VER_SUITE_DATACENTER)
  232. {
  233. return TRUE;
  234. }
  235. }
  236. }
  237. }
  238. return FALSE;
  239. }