#include "migwiz.h" #include "migutil.h" #include "resource.h" #include "container.h" #include #include typedef struct _THREADSTARTUPINFO { HWND hWnd; HINSTANCE hInstance; LPTSTR lpCmdLine; } THREADSTARTUPINFO, *LPTHREADSTARTUPINFO; #define WINDOWCLASS TEXT("USMTCobraApp") #define WINDOWNAME TEXT("Migwiz") #define ANOTHERUSER_RESLEN 100 BOOL g_ConfirmedLogOff = FALSE; BOOL g_ConfirmedReboot = FALSE; static HANDLE g_hThread = NULL; static DWORD g_dwThreadId = 0; Container *g_WebContainer = NULL; DWORD WINAPI MigwizThread( IN LPVOID lpParameter ) { HRESULT hr; TCHAR szAppPath[MAX_PATH] = TEXT(""); TCHAR* pszAppPathOffset; CoInitialize(NULL); OleInitialize(NULL); GetModuleFileName (NULL, szAppPath, ARRAYSIZE(szAppPath)); pszAppPathOffset = _tcsrchr (szAppPath, TEXT('\\')); if (pszAppPathOffset) { *pszAppPathOffset = 0; SetCurrentDirectory (szAppPath); } MigrationWizard* pMigWiz = new MigrationWizard(); if (pMigWiz) { LPTSTR lpszUsername = NULL; LPTSTR lpszCmdLine = ((LPTHREADSTARTUPINFO)lpParameter)->lpCmdLine; if (lpszCmdLine && 0 == _tcsncmp (lpszCmdLine, TEXT("/t:"), 3)) { // BUGBUG: need to make this more stable lpszUsername = lpszCmdLine + 3; } hr = pMigWiz->Init(((LPTHREADSTARTUPINFO)lpParameter)->hInstance, lpszUsername); if (SUCCEEDED(hr)) { pMigWiz->Execute(); } // ISSUE: leak //delete pMigWiz; } SendMessage (((LPTHREADSTARTUPINFO)lpParameter)->hWnd, WM_USER_THREAD_COMPLETE, NULL, NULL); OleUninitialize(); CoUninitialize(); return 0; } BOOL CALLBACK _SetMigwizActive( IN HWND hWnd, IN LPARAM lParam ) { SetForegroundWindow( hWnd ); return FALSE; } LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { case WM_ACTIVATE: if (g_hThread != NULL && g_dwThreadId != 0) { EnumThreadWindows( g_dwThreadId, _SetMigwizActive, (LPARAM)NULL ); } break; case WM_USER_THREAD_COMPLETE: CloseHandle( g_hThread ); PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0; } LRESULT CALLBACK WebHostProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { case WM_SETFOCUS: if (g_WebContainer) { g_WebContainer->setFocus(TRUE); return 0; } break; } return DefWindowProc(hWnd, message, wParam, lParam); } INT WINAPI WinMain( IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpszCmdLine, IN INT nCmdShow) { WNDCLASSEX wcx; MSG msg; HANDLE hMutex = NULL; OSVERSIONINFO vi; HWND hwnd; DWORD dwResult = 0; THREADSTARTUPINFO StartInfo; PSID pSid = NULL; PTSTR commandLine = NULL; #ifdef UNICODE commandLine = _ConvertToUnicode (CP_ACP, lpszCmdLine); #else commandLine = lpszCmdLine; #endif hwnd = FindWindow (WINDOWCLASS, WINDOWNAME); if (hwnd) { SetForegroundWindow (hwnd); goto END; } CoInitialize(NULL); OleInitialize(NULL); vi.dwOSVersionInfoSize = sizeof (vi); if (GetVersionEx (&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_NT && vi.dwMajorVersion > 4) { hMutex = CreateMutex (NULL, TRUE, TEXT("Global\\migwiz.mutex")); } else { hMutex = CreateMutex (NULL, TRUE, TEXT("migwiz.mutex")); } if ((hMutex && GetLastError() == ERROR_ALREADY_EXISTS) || (!hMutex && GetLastError() == ERROR_ACCESS_DENIED)) { TCHAR szTmpBuf[512]; PVOID lpBuf = NULL; LPTSTR lpUsername = NULL; lpUsername = (LPTSTR)LocalAlloc(LPTR, ANOTHERUSER_RESLEN * sizeof (TCHAR)); LoadString (hInstance, IDS_ANOTHER_USER, lpUsername, ANOTHERUSER_RESLEN); LoadString (hInstance, IDS_ALREADY_RUN_USER, szTmpBuf, ARRAYSIZE(szTmpBuf)); FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, szTmpBuf, 0, 0, (LPTSTR)&lpBuf, 0, (va_list *)(&lpUsername)); MessageBox (NULL, (LPCTSTR)lpBuf, NULL, MB_OK); LocalFree (lpBuf); LocalFree (lpUsername); goto END; } ZeroMemory (&wcx, sizeof (WNDCLASSEX)); wcx.cbSize = sizeof (WNDCLASSEX); wcx.hInstance = hInstance; wcx.lpszClassName = WINDOWCLASS; wcx.lpfnWndProc = (WNDPROC)WndProc; if (!RegisterClassEx (&wcx)) { dwResult = GetLastError(); goto END; } ZeroMemory (&wcx, sizeof (WNDCLASSEX)); wcx.cbSize = sizeof (WNDCLASSEX); wcx.hInstance = hInstance; wcx.lpszClassName = TEXT("WebHost"); wcx.lpfnWndProc = (WNDPROC)WebHostProc; if (!RegisterClassEx (&wcx)) { dwResult = GetLastError(); goto END; } hwnd = CreateWindow (WINDOWCLASS, WINDOWNAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInstance, NULL); if (!hwnd) { dwResult = GetLastError(); goto END; } StartInfo.hWnd = hwnd; StartInfo.hInstance = hInstance; StartInfo.lpCmdLine = commandLine; g_hThread = CreateThread( NULL, 0, MigwizThread, (PVOID)&StartInfo, 0, &g_dwThreadId ); if (g_hThread == NULL) { dwResult = GetLastError(); goto END; } // Main message loop: while (GetMessage( &msg, NULL, 0, 0 )) { TranslateMessage( &msg ); DispatchMessage( &msg ); } END: OleUninitialize(); CoUninitialize(); if (hMutex) { CloseHandle (hMutex); } if (pSid) { LocalFree (pSid); } #ifdef UNICODE if (commandLine) { LocalFree (commandLine); } #endif if (g_ConfirmedReboot) { HANDLE token; TOKEN_PRIVILEGES newPrivileges; LUID luid; if (OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) { if (LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &luid)) { newPrivileges.PrivilegeCount = 1; newPrivileges.Privileges[0].Luid = luid; newPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges( token, FALSE, &newPrivileges, 0, NULL, NULL )) { ExitWindowsEx (EWX_REBOOT, 0); } } CloseHandle (token); } } else if (g_ConfirmedLogOff) { ExitWindowsEx (EWX_LOGOFF, 0); } return dwResult; }