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.

272 lines
9.6 KiB

  1. #include "stdinc.h"
  2. #include "st.h"
  3. #include "create.h"
  4. CDeque<CREATEACTCTX_THREAD_PROC_DATA, offsetof(CREATEACTCTX_THREAD_PROC_DATA, Linkage)> g_ActCtxs;
  5. #define DATA_DIRECTORY_NAME L"createactctx"
  6. #define INI_FILE L"createactctx.ini"
  7. #define INI_FILE2 L"assembly.ini" /* reuse install test cases */
  8. const static FUSION_FLAG_FORMAT_MAP_ENTRY CreateActCtxFlagData[] =
  9. {
  10. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID, "ProcessorArchitecture")
  11. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_LANGID_VALID, "Langid")
  12. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID, "AssemblyDirectory")
  13. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_RESOURCE_NAME_VALID, "ResourceName")
  14. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_SET_PROCESS_DEFAULT, "SetProcessDefault")
  15. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_APPLICATION_NAME_VALID, "ApplicationName")
  16. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF, "AssemblyRef")
  17. DEFINE_FUSION_FLAG_FORMAT_MAP_ENTRY(ACTCTX_FLAG_HMODULE_VALID, "Hmodule")
  18. };
  19. BOOL InitializeCreateActCtx()
  20. {
  21. FN_PROLOG_WIN32
  22. CFindFile hFind;
  23. WIN32_FIND_DATAW wfd;
  24. CStringBuffer TempDirectory;
  25. CDequeIterator<CREATEACTCTX_THREAD_PROC_DATA, offsetof(CREATEACTCTX_THREAD_PROC_DATA, Linkage)> iter(&g_ActCtxs);
  26. CSmallStringBuffer IniFilePath;
  27. if (!TempDirectory.Win32Assign(BaseDirectory))
  28. goto Exit;
  29. if (!TempDirectory.Win32AppendPathElement(DATA_DIRECTORY_NAME, NUMBER_OF(DATA_DIRECTORY_NAME) - 1))
  30. goto Exit;
  31. if ((wfd.dwFileAttributes = ::GetFileAttributesW(TempDirectory)) == 0xffffffff
  32. && (wfd.dwFileAttributes = ::FusionpGetLastWin32Error()) == ERROR_FILE_NOT_FOUND)
  33. {
  34. printf("no %ls tests, skipping\n", DATA_DIRECTORY_NAME);
  35. FN_SUCCESSFUL_EXIT();
  36. }
  37. if (!TempDirectory.Win32AppendPathElement(L"*", 1))
  38. goto Exit;
  39. hFind = ::FindFirstFileW(TempDirectory, &wfd);
  40. if (hFind == INVALID_HANDLE_VALUE)
  41. {
  42. ::ReportFailure("Failed to find any files matching \"%ls\"\n", static_cast<PCWSTR>(TempDirectory));
  43. goto Exit;
  44. }
  45. for (;;)
  46. {
  47. CTinyStringBuffer TempString;
  48. CTinyStringBuffer BaseDirectory2;
  49. CREATEACTCTX_THREAD_PROC_DATA *pData = NULL;
  50. if (FusionpIsDotOrDotDot(wfd.cFileName))
  51. goto Skip;
  52. if (!BaseDirectory2.Win32Assign(BaseDirectory))
  53. goto Exit;
  54. if (!BaseDirectory2.Win32AppendPathElement(DATA_DIRECTORY_NAME, NUMBER_OF(DATA_DIRECTORY_NAME) - 1))
  55. goto Exit;
  56. if (!BaseDirectory2.Win32AppendPathElement(wfd.cFileName, wcslen(wfd.cFileName)))
  57. goto Exit;
  58. if ((pData = new CREATEACTCTX_THREAD_PROC_DATA) == NULL)
  59. {
  60. ::FusionpSetLastWin32Error(ERROR_OUTOFMEMORY);
  61. ::ReportFailure("Failed to allocate CREATEACTCTX_THREAD_PROC_DATA\n");
  62. goto Exit;
  63. }
  64. if (!IniFilePath.Win32Assign(BaseDirectory2))
  65. goto Exit;
  66. if (!IniFilePath.Win32AppendPathElement(INI_FILE, NUMBER_OF(INI_FILE) - 1))
  67. goto Exit;
  68. if (::GetFileAttributesW(IniFilePath) == 0xffffffff
  69. && ::FusionpGetLastWin32Error() == ERROR_FILE_NOT_FOUND)
  70. {
  71. if (!IniFilePath.Win32Assign(BaseDirectory2))
  72. goto Exit;
  73. if (!IniFilePath.Win32AppendPathElement(INI_FILE2, NUMBER_OF(INI_FILE2) - 1))
  74. goto Exit;
  75. }
  76. TempString.Clear();
  77. //if (!SxStressToolGetStringSetting(0, IniFilePath, L"create", L"source", L"assembly.manifest", TempString, NULL))
  78. if (!SxStressToolGetStringSetting(0, IniFilePath, L"assembly", L"manifest", L"assembly.manifest", TempString, NULL))
  79. goto Exit;
  80. if (TempString.Cch() != 0)
  81. {
  82. if (!pData->Source.Win32Assign(BaseDirectory2))
  83. goto Exit;
  84. if (!pData->Source.Win32AppendPathElement(TempString))
  85. goto Exit;
  86. pData->ActCtx.lpSource = pData->Source;
  87. }
  88. TempString.Clear();
  89. if (!SxStressToolGetStringSetting(0, IniFilePath, L"create", L"dllname", L"", pData->DllName, NULL))
  90. goto Exit;
  91. if (!SxStressToolGetStringSetting(0, IniFilePath, L"create", L"assemblydirectory", L"", pData->AssemblyDirectory, &pData->ActCtx.lpAssemblyDirectory))
  92. goto Exit;
  93. if (!SxStressToolGetStringSetting(0, IniFilePath, L"create", L"applicationname", L"", pData->ApplicationName, &pData->ActCtx.lpApplicationName))
  94. goto Exit;
  95. if (!SxStressToolGetFlagSetting(0, IniFilePath, L"create", L"flags", pData->ActCtx.dwFlags, CreateActCtxFlagData, NUMBER_OF(CreateActCtxFlagData)))
  96. goto Exit;
  97. if (!SxStressToolGetResourceIdSetting(0, IniFilePath, L"create", L"resourcename", pData->ResourceName, &pData->ActCtx.lpResourceName))
  98. goto Exit;
  99. g_ActCtxs.AddToTail(pData);
  100. Skip:
  101. if (!::FindNextFileW(hFind, &wfd))
  102. {
  103. if (::FusionpGetLastWin32Error() != ERROR_NO_MORE_FILES)
  104. {
  105. ::ReportFailure("Error iterating over assemblies\n");
  106. goto Exit;
  107. }
  108. break;
  109. }
  110. }
  111. for (iter.Reset(); iter.More(); iter.Next())
  112. {
  113. if (!iter->Thread.Win32CreateThread(&CreateActCtxThreadProc, iter.Current()))
  114. {
  115. ::ReportFailure("Error launching install thread\n");
  116. goto Exit;
  117. }
  118. TotalThreads += 1;
  119. }
  120. FN_EPILOG
  121. }
  122. void RequestShutdownCreateActCtxThreads()
  123. {
  124. CDequeIterator<CREATEACTCTX_THREAD_PROC_DATA, offsetof(CREATEACTCTX_THREAD_PROC_DATA, Linkage)> iter(&g_ActCtxs);
  125. for (iter.Reset(); iter.More(); iter.Next())
  126. {
  127. iter->Stop = true;
  128. }
  129. }
  130. void WaitForCreateActCtxThreads()
  131. {
  132. CDequeIterator<CREATEACTCTX_THREAD_PROC_DATA, offsetof(CREATEACTCTX_THREAD_PROC_DATA, Linkage)> iter(&g_ActCtxs);
  133. for (iter.Reset(); iter.More(); iter.Next())
  134. {
  135. DWORD WaitResult = ::WaitForSingleObject(iter->Thread, INFINITE);
  136. switch (WaitResult)
  137. {
  138. case WAIT_OBJECT_0:
  139. break;
  140. case WAIT_FAILED:
  141. ::ReportFailure("Failed to WaitForSingleObject.\n");
  142. break;
  143. default:
  144. ::FusionpSetLastWin32Error(WaitResult);
  145. ::ReportFailure("Failed to WaitForSingleObject.\n");
  146. break;
  147. }
  148. iter->Thread.Win32Close();
  149. }
  150. }
  151. void CleanupCreateActCtx()
  152. {
  153. g_ActCtxs.ClearAndDeleteAll();
  154. }
  155. DWORD
  156. WINAPI
  157. CreateActCtxThreadProc(
  158. LPVOID pvData
  159. )
  160. {
  161. DWORD dwReturnValue = ERROR_INTERNAL_ERROR;
  162. DWORD WaitResult = 0;
  163. CREATEACTCTX_THREAD_PROC_DATA *pData = reinterpret_cast<CREATEACTCTX_THREAD_PROC_DATA *>(pvData);
  164. InterlockedIncrement(&ThreadsWaiting);
  165. WaitResult = WaitForSingleObject(ResumeThreadsEvent, INFINITE);
  166. switch (WaitResult)
  167. {
  168. case WAIT_OBJECT_0:
  169. break;
  170. case WAIT_FAILED:
  171. dwReturnValue = ::FusionpGetLastWin32Error();
  172. ::ReportFailure("Failed to WaitForSingleObject.\n");
  173. goto Exit;
  174. default:
  175. dwReturnValue = WaitResult;
  176. ::FusionpSetLastWin32Error(WaitResult);
  177. ::ReportFailure("Failed to WaitForSingleObject.\n");
  178. goto Exit;
  179. }
  180. while (!pData->Stop)
  181. {
  182. CFusionActCtxHandle ActCtxHandle;
  183. if (!ActCtxHandle.Win32Create(&pData->ActCtx))
  184. {
  185. dwReturnValue = ::FusionpGetLastWin32Error();
  186. ::ReportFailure("[%lx.%lx] CreateActCtx(\"%ls\", 0x%lx) failed %lu\n",
  187. SxStressToolGetCurrentProcessId(), SxStressToolGetCurrentThreadId(),
  188. pData->ActCtx.lpSource,
  189. pData->ActCtx.dwFlags,
  190. dwReturnValue);
  191. //goto Exit;
  192. }
  193. else
  194. {
  195. printf("[%lx.%lx] CreateActCtx(%ls, 0x%lx) succeeded\n",
  196. SxStressToolGetCurrentProcessId(), SxStressToolGetCurrentThreadId(),
  197. pData->ActCtx.lpSource, pData->ActCtx.dwFlags
  198. );
  199. if (pData->DllName.Cch() != 0)
  200. {
  201. CDynamicLinkLibrary Dll;
  202. if (Dll.Win32LoadLibrary(pData->DllName))
  203. {
  204. ::FusionpSetLastWin32Error(NO_ERROR);
  205. ::ReportFailure("[%lx.%lx] CreateActCtx(\"%ls\", 0x%lx) succeeded\n",
  206. SxStressToolGetCurrentProcessId(), SxStressToolGetCurrentThreadId(),
  207. pData->ActCtx.lpSource,
  208. pData->ActCtx.dwFlags
  209. );
  210. }
  211. else
  212. {
  213. ::ReportFailure("[%lx.%lx] CreateActCtx(\"%ls\", 0x%lx) failed %lu\n",
  214. SxStressToolGetCurrentProcessId(), SxStressToolGetCurrentThreadId(),
  215. pData->ActCtx.lpSource,
  216. pData->ActCtx.dwFlags,
  217. ::FusionpGetLastWin32Error()
  218. );
  219. }
  220. }
  221. }
  222. ::WaitForSingleObject(StopEvent, pData->Sleep);
  223. }
  224. dwReturnValue = ERROR_SUCCESS;
  225. Exit:
  226. printf("[%lx.%lx] CreateActCtx(%ls, 0x%lx) thread exiting 0x%lx\n",
  227. SxStressToolGetCurrentProcessId(), SxStressToolGetCurrentThreadId(),
  228. pData->ActCtx.lpSource, pData->ActCtx.dwFlags,
  229. dwReturnValue);
  230. return dwReturnValue;
  231. }