void HandleCommandLine(LPSTR lpCmdLine) { char *ptr = strstr(lpCmdLine, "/kill:"); if (ptr) { DWORD pid = (DWORD)atoi(ptr + strlen("/kill:")); HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, pid); if (hProcess) { if (::WaitForSingleObject(hProcess, 5000) != WAIT_OBJECT_0) { CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Killing previous TGitCache PID %d\n", pid); if (!::TerminateProcess(hProcess, (UINT)-1)) CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Kill previous TGitCache PID %d failed\n", pid); ::WaitForSingleObject(hProcess, 5000); } ::CloseHandle(hProcess); for (int i = 0; i < 5; i++) { HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, GetCacheMutexName()); if (!hMutex) break; ::CloseHandle(hMutex); ::Sleep(1000); } } } }
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*cmdShow*/) { SetDllDirectory(L""); CAutoGeneralHandle hReloadProtection = ::CreateMutex(NULL, FALSE, GetCacheMutexName()); if ((!hReloadProtection) || (GetLastError() == ERROR_ALREADY_EXISTS)) { // An instance of TGitCache is already running ATLTRACE("TGitCache ignoring restart\n"); return 0; } CGitStatusCache::Create(); CGitStatusCache::Instance().Init(); SecureZeroMemory(szCurrentCrawledPath, sizeof(szCurrentCrawledPath)); DWORD dwThreadId; MSG msg; TCHAR szWindowClass[] = {TGIT_CACHE_WINDOW_NAME}; // create a hidden window to receive window messages. WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = 0; wcex.hCursor = 0; wcex.hbrBackground = 0; wcex.lpszMenuName = NULL; wcex.lpszClassName = szWindowClass; wcex.hIconSm = 0; RegisterClassEx(&wcex); hWnd = CreateWindow(TGIT_CACHE_WINDOW_NAME, TGIT_CACHE_WINDOW_NAME, WS_CAPTION, 0, 0, 800, 300, NULL, 0, hInstance, 0); hTrayWnd = hWnd; if (hWnd == NULL) { return 0; } if (CRegStdDWORD(_T("Software\\TortoiseGit\\CacheTrayIcon"), FALSE)==TRUE) { SecureZeroMemory(&niData,sizeof(NOTIFYICONDATA)); DWORD dwMajor = 0; DWORD dwMinor = 0; GetShellVersion(&dwMajor, &dwMinor); DWORD dwVersion = PACKVERSION(dwMajor, dwMinor); if (dwVersion >= PACKVERSION(6,0)) niData.cbSize = sizeof(NOTIFYICONDATA); else if (dwVersion >= PACKVERSION(5,0)) niData.cbSize = NOTIFYICONDATA_V2_SIZE; else niData.cbSize = NOTIFYICONDATA_V1_SIZE; niData.uID = TRAY_ID; // own tray icon ID niData.hWnd = hWnd; niData.uFlags = NIF_ICON|NIF_MESSAGE; // load the icon niData.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_TGITCACHE), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); // set the message to send // note: the message value should be in the // range of WM_APP through 0xBFFF niData.uCallbackMessage = TRAY_CALLBACK; Shell_NotifyIcon(NIM_ADD,&niData); // free icon handle if(niData.hIcon && DestroyIcon(niData.hIcon)) niData.hIcon = NULL; } // Create a thread which waits for incoming pipe connections CAutoGeneralHandle hPipeThread = CreateThread( NULL, // no security attribute 0, // default stack size PipeThread, (LPVOID) &bRun, // thread parameter 0, // not suspended &dwThreadId); // returns thread ID if (!hPipeThread) { //OutputDebugStringA("TSVNCache: Could not create pipe thread\n"); //DebugOutputLastError(); return 0; } else hPipeThread.CloseHandle(); // Create a thread which waits for incoming pipe connections CAutoGeneralHandle hCommandWaitThread = CreateThread( NULL, // no security attribute 0, // default stack size CommandWaitThread, (LPVOID) &bRun, // thread parameter 0, // not suspended &dwThreadId); // returns thread ID if (!hCommandWaitThread) { //OutputDebugStringA("TSVNCache: Could not create command wait thread\n"); //DebugOutputLastError(); return 0; } // loop to handle window messages. BOOL bLoopRet; while (bRun) { bLoopRet = GetMessage(&msg, NULL, 0, 0); if ((bLoopRet != -1)&&(bLoopRet != 0)) { DispatchMessage(&msg); } } bRun = false; Shell_NotifyIcon(NIM_DELETE,&niData); CGitStatusCache::Destroy(); return 0; }
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*cmdShow*/) { SetDllDirectory(L""); CAutoGeneralHandle hReloadProtection = ::CreateMutex(NULL, FALSE, GetCacheMutexName()); if ((!hReloadProtection) || (GetLastError() == ERROR_ALREADY_EXISTS)) { // An instance of TSVNCache is already running CTraceToOutputDebugString::Instance()(__FUNCTION__ ": TSVNCache ignoring restart\n"); return 0; } // set the current directory to the users temp dir TCHAR pathbuf[MAX_PATH] = { 0 }; GetTempPath(_countof(pathbuf), pathbuf); SetCurrentDirectory(pathbuf); apr_initialize(); svn_dso_initialize2(); svn_error_set_malfunction_handler(svn_error_handle_malfunction); g_SVNAdminDir.Init(); CSVNStatusCache::Create(); CSVNStatusCache::Instance().Init(); SecureZeroMemory(szCurrentCrawledPath, sizeof(szCurrentCrawledPath)); // create a hidden window to receive window messages. hWndHidden = CreateHiddenWindow(hInstance); hTrayWnd = hWndHidden; if (hWndHidden == NULL) { return 0; } if (CRegStdDWORD(L"Software\\TortoiseSVN\\CacheTrayIcon", FALSE)==TRUE) { SecureZeroMemory(&niData,sizeof(NOTIFYICONDATA)); DWORD dwMajor = 0; DWORD dwMinor = 0; GetShellVersion(&dwMajor, &dwMinor); DWORD dwVersion = PACKVERSION(dwMajor, dwMinor); if (dwVersion >= PACKVERSION(6,0)) niData.cbSize = sizeof(NOTIFYICONDATA); else if (dwVersion >= PACKVERSION(5,0)) niData.cbSize = NOTIFYICONDATA_V2_SIZE; else niData.cbSize = NOTIFYICONDATA_V1_SIZE; niData.uID = TRAY_ID; // own tray icon ID niData.hWnd = hWndHidden; niData.uFlags = NIF_ICON|NIF_MESSAGE; // load the icon niData.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_TSVNCACHE), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); // set the message to send // note: the message value should be in the // range of WM_APP through 0xBFFF niData.uCallbackMessage = TRAY_CALLBACK; Shell_NotifyIcon(NIM_ADD,&niData); // free icon handle if(niData.hIcon && DestroyIcon(niData.hIcon)) niData.hIcon = NULL; } // Create a thread which waits for incoming pipe connections unsigned int threadId = 0; CAutoGeneralHandle hPipeThread = (HANDLE)_beginthreadex(NULL, 0, PipeThread, &bRun, 0, &threadId); if (!hPipeThread) return 0; // Create a thread which waits for incoming pipe connections CAutoGeneralHandle hCommandWaitThread = (HANDLE)_beginthreadex(NULL, 0, CommandWaitThread, &bRun, 0, &threadId); if (hCommandWaitThread) { // loop to handle window messages. MSG msg; while (bRun) { const BOOL bLoopRet = GetMessage(&msg, NULL, 0, 0); if ((bLoopRet != -1)&&(bLoopRet != 0)) { DispatchMessage(&msg); } } } bRun = false; Shell_NotifyIcon(NIM_DELETE,&niData); CSVNStatusCache::Destroy(); g_SVNAdminDir.Close(); apr_terminate(); return 0; }