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.

310 lines
7.3 KiB

  1. #include "migwiz.h"
  2. #include "migutil.h"
  3. #include "resource.h"
  4. #include "container.h"
  5. #include <string.h>
  6. #include <tchar.h>
  7. typedef struct _THREADSTARTUPINFO
  8. {
  9. HWND hWnd;
  10. HINSTANCE hInstance;
  11. LPTSTR lpCmdLine;
  12. } THREADSTARTUPINFO, *LPTHREADSTARTUPINFO;
  13. #define WINDOWCLASS TEXT("USMTCobraApp")
  14. #define WINDOWNAME TEXT("Migwiz")
  15. #define ANOTHERUSER_RESLEN 100
  16. BOOL g_ConfirmedLogOff = FALSE;
  17. BOOL g_ConfirmedReboot = FALSE;
  18. static HANDLE g_hThread = NULL;
  19. static DWORD g_dwThreadId = 0;
  20. Container *g_WebContainer = NULL;
  21. DWORD
  22. WINAPI
  23. MigwizThread(
  24. IN LPVOID lpParameter
  25. )
  26. {
  27. HRESULT hr;
  28. TCHAR szAppPath[MAX_PATH] = TEXT("");
  29. TCHAR* pszAppPathOffset;
  30. CoInitialize(NULL);
  31. OleInitialize(NULL);
  32. GetModuleFileName (NULL, szAppPath, ARRAYSIZE(szAppPath));
  33. pszAppPathOffset = _tcsrchr (szAppPath, TEXT('\\'));
  34. if (pszAppPathOffset) {
  35. *pszAppPathOffset = 0;
  36. SetCurrentDirectory (szAppPath);
  37. }
  38. MigrationWizard* pMigWiz = new MigrationWizard();
  39. if (pMigWiz)
  40. {
  41. LPTSTR lpszUsername = NULL;
  42. LPTSTR lpszCmdLine = ((LPTHREADSTARTUPINFO)lpParameter)->lpCmdLine;
  43. if (lpszCmdLine && 0 == _tcsncmp (lpszCmdLine, TEXT("/t:"), 3))
  44. {
  45. // BUGBUG: need to make this more stable
  46. lpszUsername = lpszCmdLine + 3;
  47. }
  48. hr = pMigWiz->Init(((LPTHREADSTARTUPINFO)lpParameter)->hInstance, lpszUsername);
  49. if (SUCCEEDED(hr))
  50. {
  51. pMigWiz->Execute();
  52. }
  53. // ISSUE: leak
  54. //delete pMigWiz;
  55. }
  56. SendMessage (((LPTHREADSTARTUPINFO)lpParameter)->hWnd, WM_USER_THREAD_COMPLETE, NULL, NULL);
  57. OleUninitialize();
  58. CoUninitialize();
  59. return 0;
  60. }
  61. BOOL
  62. CALLBACK
  63. _SetMigwizActive(
  64. IN HWND hWnd,
  65. IN LPARAM lParam
  66. )
  67. {
  68. SetForegroundWindow( hWnd );
  69. return FALSE;
  70. }
  71. LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  72. {
  73. switch (message)
  74. {
  75. case WM_ACTIVATE:
  76. if (g_hThread != NULL && g_dwThreadId != 0)
  77. {
  78. EnumThreadWindows( g_dwThreadId, _SetMigwizActive, (LPARAM)NULL );
  79. }
  80. break;
  81. case WM_USER_THREAD_COMPLETE:
  82. CloseHandle( g_hThread );
  83. PostQuitMessage( 0 );
  84. break;
  85. default:
  86. return DefWindowProc( hWnd, message, wParam, lParam );
  87. }
  88. return 0;
  89. }
  90. LRESULT CALLBACK WebHostProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  91. {
  92. switch (message)
  93. {
  94. case WM_SETFOCUS:
  95. if (g_WebContainer) {
  96. g_WebContainer->setFocus(TRUE);
  97. return 0;
  98. }
  99. break;
  100. }
  101. return DefWindowProc(hWnd, message, wParam, lParam);
  102. }
  103. INT
  104. WINAPI
  105. WinMain(
  106. IN HINSTANCE hInstance,
  107. IN HINSTANCE hPrevInstance,
  108. IN LPSTR lpszCmdLine,
  109. IN INT nCmdShow)
  110. {
  111. WNDCLASSEX wcx;
  112. MSG msg;
  113. HANDLE hMutex = NULL;
  114. OSVERSIONINFO vi;
  115. HWND hwnd;
  116. DWORD dwResult = 0;
  117. THREADSTARTUPINFO StartInfo;
  118. PSID pSid = NULL;
  119. PTSTR commandLine = NULL;
  120. #ifdef UNICODE
  121. commandLine = _ConvertToUnicode (CP_ACP, lpszCmdLine);
  122. #else
  123. commandLine = lpszCmdLine;
  124. #endif
  125. hwnd = FindWindow (WINDOWCLASS, WINDOWNAME);
  126. if (hwnd)
  127. {
  128. SetForegroundWindow (hwnd);
  129. goto END;
  130. }
  131. CoInitialize(NULL);
  132. OleInitialize(NULL);
  133. vi.dwOSVersionInfoSize = sizeof (vi);
  134. if (GetVersionEx (&vi) &&
  135. vi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
  136. vi.dwMajorVersion > 4)
  137. {
  138. hMutex = CreateMutex (NULL, TRUE, TEXT("Global\\migwiz.mutex"));
  139. }
  140. else
  141. {
  142. hMutex = CreateMutex (NULL, TRUE, TEXT("migwiz.mutex"));
  143. }
  144. if ((hMutex && GetLastError() == ERROR_ALREADY_EXISTS) ||
  145. (!hMutex && GetLastError() == ERROR_ACCESS_DENIED))
  146. {
  147. TCHAR szTmpBuf[512];
  148. PVOID lpBuf = NULL;
  149. LPTSTR lpUsername = NULL;
  150. lpUsername = (LPTSTR)LocalAlloc(LPTR, ANOTHERUSER_RESLEN * sizeof (TCHAR));
  151. LoadString (hInstance, IDS_ANOTHER_USER, lpUsername, ANOTHERUSER_RESLEN);
  152. LoadString (hInstance, IDS_ALREADY_RUN_USER, szTmpBuf, ARRAYSIZE(szTmpBuf));
  153. FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  154. szTmpBuf,
  155. 0,
  156. 0,
  157. (LPTSTR)&lpBuf,
  158. 0,
  159. (va_list *)(&lpUsername));
  160. MessageBox (NULL, (LPCTSTR)lpBuf, NULL, MB_OK);
  161. LocalFree (lpBuf);
  162. LocalFree (lpUsername);
  163. goto END;
  164. }
  165. ZeroMemory (&wcx, sizeof (WNDCLASSEX));
  166. wcx.cbSize = sizeof (WNDCLASSEX);
  167. wcx.hInstance = hInstance;
  168. wcx.lpszClassName = WINDOWCLASS;
  169. wcx.lpfnWndProc = (WNDPROC)WndProc;
  170. if (!RegisterClassEx (&wcx))
  171. {
  172. dwResult = GetLastError();
  173. goto END;
  174. }
  175. ZeroMemory (&wcx, sizeof (WNDCLASSEX));
  176. wcx.cbSize = sizeof (WNDCLASSEX);
  177. wcx.hInstance = hInstance;
  178. wcx.lpszClassName = TEXT("WebHost");
  179. wcx.lpfnWndProc = (WNDPROC)WebHostProc;
  180. if (!RegisterClassEx (&wcx))
  181. {
  182. dwResult = GetLastError();
  183. goto END;
  184. }
  185. hwnd = CreateWindow (WINDOWCLASS,
  186. WINDOWNAME,
  187. WS_OVERLAPPEDWINDOW,
  188. CW_USEDEFAULT,
  189. CW_USEDEFAULT,
  190. 400, 300,
  191. NULL, NULL,
  192. hInstance,
  193. NULL);
  194. if (!hwnd)
  195. {
  196. dwResult = GetLastError();
  197. goto END;
  198. }
  199. StartInfo.hWnd = hwnd;
  200. StartInfo.hInstance = hInstance;
  201. StartInfo.lpCmdLine = commandLine;
  202. g_hThread = CreateThread( NULL,
  203. 0,
  204. MigwizThread,
  205. (PVOID)&StartInfo,
  206. 0,
  207. &g_dwThreadId );
  208. if (g_hThread == NULL)
  209. {
  210. dwResult = GetLastError();
  211. goto END;
  212. }
  213. // Main message loop:
  214. while (GetMessage( &msg, NULL, 0, 0 ))
  215. {
  216. TranslateMessage( &msg );
  217. DispatchMessage( &msg );
  218. }
  219. END:
  220. OleUninitialize();
  221. CoUninitialize();
  222. if (hMutex)
  223. {
  224. CloseHandle (hMutex);
  225. }
  226. if (pSid)
  227. {
  228. LocalFree (pSid);
  229. }
  230. #ifdef UNICODE
  231. if (commandLine)
  232. {
  233. LocalFree (commandLine);
  234. }
  235. #endif
  236. if (g_ConfirmedReboot) {
  237. HANDLE token;
  238. TOKEN_PRIVILEGES newPrivileges;
  239. LUID luid;
  240. if (OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) {
  241. if (LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &luid)) {
  242. newPrivileges.PrivilegeCount = 1;
  243. newPrivileges.Privileges[0].Luid = luid;
  244. newPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  245. if (AdjustTokenPrivileges(
  246. token,
  247. FALSE,
  248. &newPrivileges,
  249. 0,
  250. NULL,
  251. NULL
  252. )) {
  253. ExitWindowsEx (EWX_REBOOT, 0);
  254. }
  255. }
  256. CloseHandle (token);
  257. }
  258. } else if (g_ConfirmedLogOff) {
  259. ExitWindowsEx (EWX_LOGOFF, 0);
  260. }
  261. return dwResult;
  262. }