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.

373 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. wow.c
  5. Abstract:
  6. This module contains the WOW vdmdbg functions
  7. Revision History:
  8. --*/
  9. #include <precomp.h>
  10. #pragma hdrstop
  11. typedef WORD HAND16;
  12. #define SHAREWOW_MAIN
  13. #include <sharewow.h>
  14. //----------------------------------------------------------------------------
  15. // VDMKillWOW()
  16. //
  17. // Interface to kill the wow sub-system. This may not be needed and is
  18. // certainly not needed now. We are going to look into fixing the
  19. // debugging interface so this is not necessary.
  20. //
  21. //----------------------------------------------------------------------------
  22. BOOL
  23. WINAPI
  24. VDMKillWOW(
  25. VOID
  26. ) {
  27. return( FALSE );
  28. }
  29. //----------------------------------------------------------------------------
  30. // VDMDetectWOW()
  31. //
  32. // Interface to detect whether the wow sub-system has already been started.
  33. // This may not be needed and is certainly not needed now. We are going
  34. // to look into fixing the debugging interface so this is not necessary.
  35. //
  36. //----------------------------------------------------------------------------
  37. BOOL
  38. WINAPI
  39. VDMDetectWOW(
  40. VOID
  41. ) {
  42. return( FALSE );
  43. }
  44. INT
  45. WINAPI
  46. VDMEnumProcessWOW(
  47. PROCESSENUMPROC fp,
  48. LPARAM lparam
  49. ) {
  50. LPSHAREDTASKMEM lpstm;
  51. LPSHAREDPROCESS lpsp;
  52. DWORD dwOffset;
  53. INT count;
  54. BOOL f;
  55. HANDLE hProcess;
  56. /*
  57. ** Open the shared memory window
  58. */
  59. lpstm = LOCKSHAREWOW();
  60. if ( lpstm == NULL ) {
  61. // Wow must not be running
  62. return( 0 );
  63. }
  64. //
  65. // Now traverse through all of the processes in the
  66. // list, calling the callback function for each.
  67. //
  68. count = 0;
  69. dwOffset = lpstm->dwFirstProcess;
  70. while ( dwOffset != 0 ) {
  71. lpsp = (LPSHAREDPROCESS)((CHAR *)lpstm + dwOffset);
  72. if ( lpsp->dwType != SMO_PROCESS ) {
  73. // Some memory corruption problem
  74. OutputDebugString("VDMDBG: Shared memory object is not a process? (memory corruption)\n");
  75. return( 0 );
  76. }
  77. //
  78. // Make sure the process hasn't gone away because of a
  79. // crash or other rude shutdown that prevents cleanup.
  80. //
  81. hProcess = OpenProcess(
  82. SYNCHRONIZE,
  83. FALSE,
  84. lpsp->dwProcessId
  85. );
  86. if (hProcess) {
  87. CloseHandle(hProcess);
  88. count++;
  89. if ( fp ) {
  90. f = (*fp)( lpsp->dwProcessId, lpsp->dwAttributes, lparam );
  91. if ( f ) {
  92. UNLOCKSHAREWOW();
  93. return( count );
  94. }
  95. }
  96. } else {
  97. //
  98. // This is a ghost entry, change the process ID to zero
  99. // so that the next WOW started will be sure to remove
  100. // this entry even if the process ID is recycled.
  101. //
  102. lpsp->dwProcessId = 0;
  103. }
  104. dwOffset = lpsp->dwNextProcess;
  105. }
  106. UNLOCKSHAREWOW();
  107. return( count );
  108. }
  109. INT
  110. WINAPI
  111. VDMEnumTaskWOWWorker(
  112. DWORD dwProcessId,
  113. void * fp,
  114. LPARAM lparam,
  115. BOOL fEx
  116. ) {
  117. LPSHAREDTASKMEM lpstm;
  118. LPSHAREDPROCESS lpsp;
  119. LPSHAREDTASK lpst;
  120. DWORD dwOffset;
  121. INT count = 0;
  122. BOOL f;
  123. //
  124. // Open the shared memory window
  125. //
  126. lpstm = LOCKSHAREWOW();
  127. if ( lpstm == NULL ) {
  128. // Wow must not be running
  129. return( 0 );
  130. }
  131. //
  132. // Now traverse through all of the processes in the
  133. // list, looking for the one with the proper id.
  134. //
  135. dwOffset = lpstm->dwFirstProcess;
  136. while ( dwOffset != 0 ) {
  137. lpsp = (LPSHAREDPROCESS)((CHAR *)lpstm + dwOffset);
  138. if ( lpsp->dwType != SMO_PROCESS ) {
  139. // Some memory corruption problem
  140. OutputDebugString("VDMDBG: shared memory object is not a process? (memory corruption)\n");
  141. UNLOCKSHAREWOW();
  142. return( 0 );
  143. }
  144. if ( lpsp->dwProcessId == dwProcessId ) {
  145. break;
  146. }
  147. dwOffset = lpsp->dwNextProcess;
  148. }
  149. if ( dwOffset == 0 ) { // We must not have found this Id.
  150. UNLOCKSHAREWOW();
  151. return( 0 );
  152. }
  153. //
  154. // Now enumerate all of the tasks for this process
  155. //
  156. dwOffset = lpsp->dwFirstTask;
  157. while( dwOffset != 0 ) {
  158. lpst = (LPSHAREDTASK)((CHAR *)lpstm + dwOffset );
  159. if ( lpst->dwType != SMO_TASK ) {
  160. // Some memory corruption problem
  161. OutputDebugString("VDMDBG: shared memory object is not a task? (memory corruption)\n");
  162. UNLOCKSHAREWOW();
  163. return( 0 );
  164. }
  165. count++;
  166. if ( fp && lpst->hMod16 ) {
  167. if (fEx) {
  168. f = ((TASKENUMPROCEX)fp)( lpst->dwThreadId, lpst->hMod16, lpst->hTask16,
  169. lpst->szModName, lpst->szFilePath, lparam );
  170. } else {
  171. f = ((TASKENUMPROC)fp)( lpst->dwThreadId, lpst->hMod16, lpst->hTask16, lparam );
  172. }
  173. if ( f ) {
  174. UNLOCKSHAREWOW();
  175. return( count );
  176. }
  177. }
  178. dwOffset = lpst->dwNextTask;
  179. }
  180. UNLOCKSHAREWOW();
  181. return( count );
  182. }
  183. INT
  184. WINAPI
  185. VDMEnumTaskWOW(
  186. DWORD dwProcessId,
  187. TASKENUMPROC fp,
  188. LPARAM lparam
  189. ) {
  190. return VDMEnumTaskWOWWorker(dwProcessId, (void *)fp, lparam, 0);
  191. }
  192. INT
  193. WINAPI
  194. VDMEnumTaskWOWEx(
  195. DWORD dwProcessId,
  196. TASKENUMPROCEX fp,
  197. LPARAM lparam
  198. ) {
  199. return VDMEnumTaskWOWWorker(dwProcessId, (void *)fp, lparam, 1);
  200. }
  201. BOOL
  202. WINAPI
  203. VDMTerminateTaskWOW(
  204. DWORD dwProcessId,
  205. WORD htask
  206. )
  207. {
  208. BOOL fRet = FALSE;
  209. LPSHAREDTASKMEM lpstm;
  210. LPSHAREDPROCESS lpsp;
  211. LPSHAREDTASK lpst;
  212. DWORD dwOffset;
  213. INT count;
  214. HANDLE hProcess;
  215. HANDLE hRemoteThread;
  216. DWORD dwThreadId;
  217. //
  218. // Open the shared memory window
  219. //
  220. lpstm = LOCKSHAREWOW();
  221. if ( lpstm == NULL ) {
  222. // Wow must not be running
  223. return( 0 );
  224. }
  225. //
  226. // Now traverse through all of the processes in the
  227. // list, looking for the one with the proper id.
  228. //
  229. dwOffset = lpstm->dwFirstProcess;
  230. while ( dwOffset != 0 ) {
  231. lpsp = (LPSHAREDPROCESS)((CHAR *)lpstm + dwOffset);
  232. if ( lpsp->dwType != SMO_PROCESS ) {
  233. // Some memory corruption problem
  234. OutputDebugString("VDMDBG: shared memory object is not a process? (memory corruption)\n");
  235. goto UnlockReturn;
  236. }
  237. if ( lpsp->dwProcessId == dwProcessId ) {
  238. break;
  239. }
  240. dwOffset = lpsp->dwNextProcess;
  241. }
  242. if ( dwOffset == 0 ) { // We must not have found this Id.
  243. goto UnlockReturn;
  244. }
  245. //
  246. // Get a handle to the process and start W32HungAppNotifyThread
  247. // running with htask as the parameter.
  248. //
  249. hProcess = OpenProcess(
  250. PROCESS_ALL_ACCESS,
  251. FALSE,
  252. lpsp->dwProcessId
  253. );
  254. if (hProcess) {
  255. hRemoteThread = CreateRemoteThread(
  256. hProcess,
  257. NULL,
  258. 0,
  259. lpsp->pfnW32HungAppNotifyThread,
  260. (LPVOID) htask,
  261. 0,
  262. &dwThreadId
  263. );
  264. if (hRemoteThread) {
  265. fRet = TRUE;
  266. CloseHandle(hRemoteThread);
  267. }
  268. CloseHandle(hProcess);
  269. }
  270. UnlockReturn:
  271. UNLOCKSHAREWOW();
  272. return fRet;
  273. }
  274. BOOL
  275. VDMStartTaskInWOW(
  276. DWORD pidTarget,
  277. LPSTR lpCommandLine,
  278. WORD wShow
  279. )
  280. {
  281. HWND hwnd = NULL;
  282. DWORD pid;
  283. BOOL fRet;
  284. do {
  285. hwnd = FindWindowEx(NULL, hwnd, TEXT("WowExecClass"), NULL);
  286. if (hwnd) {
  287. pid = 0;
  288. GetWindowThreadProcessId(hwnd, &pid);
  289. }
  290. } while (hwnd && pid != pidTarget);
  291. if (hwnd && pid == pidTarget) {
  292. #define WM_WOWEXEC_START_TASK (WM_USER+2)
  293. PostMessage(hwnd, WM_WOWEXEC_START_TASK, GlobalAddAtom(lpCommandLine), wShow);
  294. fRet = TRUE;
  295. } else {
  296. fRet = FALSE;
  297. }
  298. return fRet;
  299. }