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.

380 lines
11 KiB

  1. #include "stdinc.h"
  2. #include "st.h"
  3. #include "create.h"
  4. #include "install.h"
  5. #include "csrss.h"
  6. #include "wfp.h"
  7. extern "C" { void (__cdecl * _aexit_rtn)(int); }
  8. CEvent ResumeThreadsEvent;
  9. CEvent StopEvent;
  10. LONG ThreadsWaiting;
  11. LONG TotalThreads;
  12. CStringBuffer BaseDirectory;
  13. PCWSTR g_pszImage = L"st";
  14. FILE *g_pLogFile = NULL;
  15. void ReportFailure(const char szFormat[], ...);
  16. extern "C"
  17. {
  18. BOOL WINAPI SxsDllMain(HINSTANCE hInst, DWORD dwReason, PVOID pvReserved);
  19. void __cdecl wmainCRTStartup();
  20. };
  21. void ExeEntry()
  22. {
  23. if (!::SxsDllMain(GetModuleHandleW(NULL), DLL_PROCESS_ATTACH, NULL))
  24. goto Exit;
  25. ::wmainCRTStartup();
  26. Exit:
  27. ::SxsDllMain(GetModuleHandleW(NULL), DLL_PROCESS_DETACH, NULL);
  28. }
  29. void
  30. ReportFailure(
  31. const char szFormat[],
  32. ...
  33. )
  34. {
  35. const DWORD dwLastError = ::FusionpGetLastWin32Error();
  36. va_list ap;
  37. char rgchBuffer[4096];
  38. WCHAR rgchWin32Error[4096];
  39. va_start(ap, szFormat);
  40. _vsnprintf(rgchBuffer, sizeof(rgchBuffer) / sizeof(rgchBuffer[0]), szFormat, ap);
  41. va_end(ap);
  42. if (!::FormatMessageW(
  43. FORMAT_MESSAGE_FROM_SYSTEM,
  44. NULL,
  45. dwLastError,
  46. 0,
  47. rgchWin32Error,
  48. NUMBER_OF(rgchWin32Error),
  49. &ap))
  50. {
  51. const DWORD dwLastError2 = ::FusionpGetLastWin32Error();
  52. _snwprintf(rgchWin32Error, sizeof(rgchWin32Error) / sizeof(rgchWin32Error[0]), L"Error formatting Win32 error %lu\nError from FormatMessage is %lu", dwLastError, dwLastError2);
  53. }
  54. fprintf(stderr, "%ls: %s\n%ls\n", g_pszImage, rgchBuffer, rgchWin32Error);
  55. if (g_pLogFile != NULL)
  56. fprintf(g_pLogFile, "%ls: %s\n%ls\n", g_pszImage, rgchBuffer, rgchWin32Error);
  57. }
  58. BOOL Win32Cleanup()
  59. {
  60. FN_PROLOG_WIN32
  61. //
  62. // delete the stuff in the registry and under %windir%\winsxs
  63. //
  64. const static PCWSTR StuffToDelete[] =
  65. {
  66. #if !defined(_AMD64_) && !defined(_M_AMD64)
  67. L"amd64_",
  68. #endif
  69. #if !defined(_IA64_) && !defined(_M_IA64)
  70. L"ia64_",
  71. #endif
  72. L"test"
  73. };
  74. ULONG i = 0;
  75. ULONG j = 0;
  76. CRegKey RegKey;
  77. const static WCHAR RegRootBlah[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Installations";
  78. CStringBuffer WindowsDirectory;
  79. IFREGFAILED_ORIGINATE_AND_EXIT(
  80. RegOpenKeyExW(
  81. HKEY_LOCAL_MACHINE,
  82. RegRootBlah,
  83. 0,
  84. KEY_ALL_ACCESS | FUSIONP_KEY_WOW64_64KEY,
  85. &RegKey
  86. ));
  87. for (j = 0 ; j != NUMBER_OF(StuffToDelete); ++j)
  88. {
  89. SIZE_T k = ::wcslen(StuffToDelete[j]);
  90. BOOL Done = FALSE;
  91. for (i = 0 ; !Done; )
  92. {
  93. CStringBuffer SubKeyName;
  94. FILETIME LastWriteTime;
  95. IFW32FALSE_EXIT(RegKey.EnumKey(i, SubKeyName, &LastWriteTime, &Done));
  96. if (Done)
  97. break;
  98. if (::_wcsnicmp(SubKeyName, StuffToDelete[j], k) == 0)
  99. {
  100. CRegKey SubKey;
  101. printf("stresstool : cleanup : deleting HKLM\\%ls\\%ls\n", RegRootBlah, static_cast<PCWSTR>(SubKeyName));
  102. IFW32FALSE_EXIT(RegKey.OpenSubKey(SubKey, SubKeyName, KEY_ALL_ACCESS | FUSIONP_KEY_WOW64_64KEY));
  103. IFW32FALSE_EXIT(SubKey.DestroyKeyTree());
  104. IFW32FALSE_EXIT(RegKey.DeleteKey(SubKeyName));
  105. }
  106. else
  107. {
  108. ++i;
  109. }
  110. }
  111. }
  112. IFW32FALSE_EXIT(WindowsDirectory.Win32ResizeBuffer(MAX_PATH, eDoNotPreserveBufferContents));
  113. {
  114. CStringBufferAccessor StringAccessor(&WindowsDirectory);
  115. IFW32FALSE_EXIT(GetSystemDirectoryW(StringAccessor, StringAccessor.GetBufferCchAsUINT()));
  116. }
  117. IFW32FALSE_EXIT(WindowsDirectory.Win32RemoveLastPathElement());
  118. for (j = 0 ; j != NUMBER_OF(StuffToDelete); ++j)
  119. {
  120. SIZE_T k = ::wcslen(StuffToDelete[j]);
  121. CSmallStringBuffer StringBuffer;
  122. CSmallStringBuffer StringBuffer2;
  123. WIN32_FIND_DATAW wfd;
  124. IFW32FALSE_EXIT(StringBuffer.Win32Assign(WindowsDirectory));
  125. #define X L"Winsxs\\Manifests"
  126. IFW32FALSE_EXIT(StringBuffer.Win32AppendPathElement(X, NUMBER_OF(X) - 1));
  127. #undef X
  128. IFW32FALSE_EXIT(StringBuffer2.Win32Assign(StringBuffer));
  129. IFW32FALSE_EXIT(StringBuffer.Win32AppendPathElement(L"*", 1));
  130. IFW32FALSE_EXIT(StringBuffer.Win32Append(StuffToDelete[j], k));
  131. IFW32FALSE_EXIT(StringBuffer.Win32Append(L"*", 1));
  132. {
  133. CFindFile FindFileHandle;
  134. if (FindFileHandle.Win32FindFirstFile(StringBuffer, &wfd))
  135. {
  136. do
  137. {
  138. CSmallStringBuffer StringBuffer3;
  139. IFW32FALSE_EXIT(StringBuffer3.Win32Assign(StringBuffer2));
  140. IFW32FALSE_EXIT(StringBuffer3.Win32AppendPathElement(wfd.cFileName, ::wcslen(wfd.cFileName)));
  141. printf("stresstool : cleanup : deleting %ls\n", static_cast<PCWSTR>(StringBuffer3));
  142. DeleteFileW(StringBuffer3);
  143. } while (::FindNextFileW(FindFileHandle, &wfd));
  144. }
  145. }
  146. IFW32FALSE_EXIT(StringBuffer.Win32Assign(WindowsDirectory));
  147. #define X L"Winsxs"
  148. IFW32FALSE_EXIT(StringBuffer.Win32AppendPathElement(X, NUMBER_OF(X) - 1));
  149. #undef X
  150. IFW32FALSE_EXIT(StringBuffer2.Win32Assign(StringBuffer));
  151. IFW32FALSE_EXIT(StringBuffer.Win32AppendPathElement(L"*", 1));
  152. IFW32FALSE_EXIT(StringBuffer.Win32Append(StuffToDelete[j], k));
  153. IFW32FALSE_EXIT(StringBuffer.Win32Append(L"*", 1));
  154. {
  155. CFindFile FindFileHandle;
  156. if (FindFileHandle.Win32FindFirstFile(StringBuffer, &wfd))
  157. {
  158. do
  159. {
  160. CSmallStringBuffer StringBuffer3;
  161. IFW32FALSE_EXIT(StringBuffer3.Win32Assign(StringBuffer2));
  162. IFW32FALSE_EXIT(StringBuffer3.Win32AppendPathElement(wfd.cFileName, ::wcslen(wfd.cFileName)));
  163. printf("deleting %ls\n", static_cast<PCWSTR>(StringBuffer3));
  164. SxspDeleteDirectory(StringBuffer3);
  165. } while (::FindNextFileW(FindFileHandle, &wfd));
  166. }
  167. }
  168. }
  169. FN_EPILOG
  170. }
  171. //
  172. // If we don't do this, control-c makes us fail assertions.
  173. // Instead, handle it more gracefully.
  174. //
  175. BOOL
  176. WINAPI
  177. ConsoleCtrlHandler(
  178. DWORD Event
  179. )
  180. {
  181. if (IsDebuggerPresent())
  182. {
  183. OutputDebugStringA("hardcoded breakpoint upon control-c while in debugger\n");
  184. DebugBreak();
  185. }
  186. switch (Event)
  187. {
  188. default:
  189. case CTRL_C_EVENT:
  190. case CTRL_BREAK_EVENT:
  191. case CTRL_CLOSE_EVENT:
  192. case CTRL_LOGOFF_EVENT:
  193. case CTRL_SHUTDOWN_EVENT:
  194. ::SetEvent(StopEvent); // wake up the controller thread
  195. ::SetEvent(ResumeThreadsEvent); // in case control-c pressed near the start
  196. break;
  197. }
  198. return TRUE;
  199. }
  200. extern "C" int __cdecl wmain(int argc, wchar_t** argv)
  201. {
  202. int iReturnStatus = EXIT_FAILURE;
  203. //
  204. // Default of 6 hour runtime? Wow..
  205. //
  206. DWORD iRunTime = 6 * 60;
  207. CWfpJobManager WfpStresser;
  208. CStressJobManager* StressManagers[] = { &WfpStresser };
  209. if ((argc < 2) || (argc > 3))
  210. {
  211. fprintf(stderr,
  212. "%ls: Usage:\n"
  213. " %ls <sourcedir> [minutesofstress]\n",
  214. argv[0], argv[0]);
  215. goto Exit;
  216. }
  217. if ( argc == 3 )
  218. {
  219. int iMaybeRunTime = ::_wtoi(argv[2]);
  220. if ( iMaybeRunTime <= 0 )
  221. {
  222. fprintf(stderr, "%ls: Usage: \n %ls <sourcedir> [minutesofstress]\n",
  223. argv[0],
  224. argv[0]);
  225. goto Exit;
  226. }
  227. iRunTime = iMaybeRunTime;
  228. }
  229. ThreadsWaiting = 0;
  230. if (!ResumeThreadsEvent.Win32CreateEvent(TRUE, FALSE))
  231. {
  232. ::ReportFailure("CreateEvent\n");
  233. goto Exit;
  234. }
  235. if (!StopEvent.Win32CreateEvent(TRUE, FALSE))
  236. {
  237. ::ReportFailure("CreateEvent\n");
  238. goto Exit;
  239. }
  240. ::SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
  241. if (!BaseDirectory.Win32Assign(argv[1], wcslen(argv[1])))
  242. goto Exit;
  243. if (!Win32Cleanup())
  244. goto Exit;
  245. if (!InitializeMSIInstallTest())
  246. goto Exit;
  247. if (!InitializeInstall())
  248. goto Exit;
  249. if (!InitializeCreateActCtx())
  250. goto Exit;
  251. if (!InitializeCsrssStress(BaseDirectory, 0))
  252. goto Exit;
  253. {
  254. ULONG ulThreadsCreated;
  255. if (!CsrssStressStartThreads(ulThreadsCreated))
  256. goto Exit;
  257. else
  258. TotalThreads += ulThreadsCreated;
  259. }
  260. for ( ULONG ul = 0; ul < NUMBER_OF(StressManagers); ul++ )
  261. {
  262. CStressJobManager *pManager = StressManagers[ul];
  263. CSmallStringBuffer buffTestDirPath;
  264. ULONG ulThreads;
  265. if ((!buffTestDirPath.Win32Assign(BaseDirectory)) ||
  266. (!buffTestDirPath.Win32AppendPathElement(
  267. pManager->GetGroupName(),
  268. ::wcslen(pManager->GetGroupName()))))
  269. goto Exit;
  270. if ((!pManager->LoadFromDirectory(buffTestDirPath)) ||
  271. (!pManager->CreateWorkerThreads(&ulThreads)))
  272. goto Exit;
  273. }
  274. // wait for them all to get to their starts (should use a semaphore here)
  275. while (ThreadsWaiting != TotalThreads)
  276. {
  277. Sleep(0);
  278. }
  279. OutputDebugStringA("********************************\n");
  280. OutputDebugStringA("* *\n");
  281. OutputDebugStringA("* start *\n");
  282. OutputDebugStringA("* *\n");
  283. OutputDebugStringA("********************************\n");
  284. // Go!
  285. if (!::SetEvent(ResumeThreadsEvent))
  286. {
  287. ::ReportFailure("SetEvent(ResumeThreadsEvent)\n");
  288. goto Exit;
  289. }
  290. //
  291. // Start the WFP stresser
  292. //
  293. for ( ULONG ul = 0; ul < NUMBER_OF(StressManagers); ul++ )
  294. {
  295. if (!StressManagers[ul]->StartJobs())
  296. goto Exit;
  297. }
  298. //
  299. // Let them run a while.
  300. //
  301. iRunTime = iRunTime * 60 * 1000;
  302. ::WaitForSingleObject(StopEvent, iRunTime);
  303. RequestShutdownMSIInstallTestThreads();
  304. RequestShutdownInstallThreads();
  305. RequestShutdownCreateActCtxThreads();
  306. RequestCsrssStressShutdown();
  307. for ( ULONG ul = 0; ul < NUMBER_OF(StressManagers); ul++ )
  308. {
  309. StressManagers[ul]->StopJobs();
  310. }
  311. ::Sleep(1000);
  312. WaitForMSIInstallTestThreads();
  313. WaitForInstallThreads();
  314. WaitForCreateActCtxThreads();
  315. WaitForCsrssStressShutdown();
  316. for ( ULONG ul = 0; ul < NUMBER_OF(StressManagers); ul++ )
  317. {
  318. StressManagers[ul]->WaitForAllJobsComplete();
  319. }
  320. iReturnStatus = EXIT_SUCCESS;
  321. Exit:
  322. CleanupMSIInstallTest();
  323. CleanupCreateActCtx();
  324. CleanupInstall();
  325. CleanupCsrssTests();
  326. for ( ULONG ul = 0; ul < NUMBER_OF(StressManagers); ul++ )
  327. {
  328. StressManagers[ul]->CleanupJobs();
  329. }
  330. Win32Cleanup();
  331. return iReturnStatus;
  332. }