// Main function
int main( int argc, char ** argv )
{
	// Initialize the memory leak detector for Win32 only (ignored by default in linux)
	bitInitMemoryLeak( BIT_NULL );

	// Setting the absolute path in order to read files.
	Bit::SetAbsolutePath( argv[ 0 ] );

	// Initialize the application
	if( LoadAudio( ) != BIT_OK ||
		LoadInput( ) != BIT_OK )
	{
		return CloseApplication( 0 );
	}


	while( 1 )
	{

		// Update the keyboard
		pKeyboard->Update( );

		// Should we exit the program?
		if( pKeyboard->KeyIsJustReleased( Bit::Keyboard::Key_Escape ) )
		{
			break;
		}

		// Play sound
		if( pKeyboard->KeyIsJustReleased( Bit::Keyboard::Key_P ) )
		{
			pAudio->Play( );
		}

	}

	// We are done
	bitTrace( "Closing the program.\n" );
	return CloseApplication( 0 );
}
Exemple #2
0
int main( )
{
	// Open the dictionary
	g_pDict = new Dictionary( );
	if( g_pDict->ReadFile( g_pDictionaryPath ) == false )
	{
		std::cout << "Can not open the dictionary file: \"" << g_pDictionaryPath << "\"" << std::endl;
		CloseApplication( 0 );
	}
	std::cout << "Successfully read the dictionary file." << std::endl;



	return 0;
}
void DlgOnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
	switch (id) {
	case IDOK:
		CreateConnection();
		break;
	case IDR_MENUITEM_ABOUT:
        if (DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT), hwnd, (DLGPROC)DlgAboutProc) == IDOK) {

		}
        else {

		}
		break;
	case IDR_MENUITEM_EXIT:
	case IDCANCEL:
		CloseApplication();
		break;
	default:
		break;
	}
}
Exemple #4
0
/*  This function is called by the Windows function DispatchMessage()  */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  static UINT s_uTaskbarRestart;
  int i;

  switch (message) {
    case WM_CREATE:       

      /* Save Window Handle */
      o.hWnd = hwnd;

      s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));

      WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION);

      /* Load application icon */
      HICON hIcon = LoadLocalizedIcon(ID_ICO_APP);
      if (hIcon) {
        SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
        SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
      }

      CreatePopupMenus();	/* Create popup menus */  
      ShowTrayIcon();
      if (o.allow_service[0]=='1' || o.service_only[0]=='1')
        CheckServiceStatus();	// Check if service is running or not
      if (!AutoStartConnections()) {
        SendMessage(hwnd, WM_CLOSE, 0, 0);
        break;
      }
      break;
    	
    case WM_NOTIFYICONTRAY:
      OnNotifyTray(lParam); 	// Manages message from tray
      break;

    case WM_COMMAND:
      if ( (LOWORD(wParam) >= IDM_CONNECTMENU) && (LOWORD(wParam) < IDM_CONNECTMENU + MAX_CONFIGS) ) {
        StartOpenVPN(&o.conn[LOWORD(wParam) - IDM_CONNECTMENU]);
      }
      if ( (LOWORD(wParam) >= IDM_DISCONNECTMENU) && (LOWORD(wParam) < IDM_DISCONNECTMENU + MAX_CONFIGS) ) {
        StopOpenVPN(&o.conn[LOWORD(wParam) - IDM_DISCONNECTMENU]);
      }
      if ( (LOWORD(wParam) >= IDM_STATUSMENU) && (LOWORD(wParam) < IDM_STATUSMENU + MAX_CONFIGS) ) {
        ShowWindow(o.conn[LOWORD(wParam) - IDM_STATUSMENU].hwndStatus, SW_SHOW);
      }
      if ( (LOWORD(wParam) >= IDM_VIEWLOGMENU) && (LOWORD(wParam) < IDM_VIEWLOGMENU + MAX_CONFIGS) ) {
        ViewLog(LOWORD(wParam) - IDM_VIEWLOGMENU);
      }
      if ( (LOWORD(wParam) >= IDM_EDITMENU) && (LOWORD(wParam) < IDM_EDITMENU + MAX_CONFIGS) ) {
        EditConfig(LOWORD(wParam) - IDM_EDITMENU);
      }
#ifndef DISABLE_CHANGE_PASSWORD
      if ( (LOWORD(wParam) >= IDM_PASSPHRASEMENU) && (LOWORD(wParam) < IDM_PASSPHRASEMENU + MAX_CONFIGS) ) {
        ShowChangePassphraseDialog(&o.conn[LOWORD(wParam) - IDM_PASSPHRASEMENU]);
      }
#endif
      if (LOWORD(wParam) == IDM_SETTINGS) {
        ShowSettingsDialog();
      }
      if (LOWORD(wParam) == IDM_CLOSE) {
        CloseApplication(hwnd);
      }
      if (LOWORD(wParam) == IDM_SERVICE_START) {
        MyStartService();
      }
      if (LOWORD(wParam) == IDM_SERVICE_STOP) {
        MyStopService();
      }     
      if (LOWORD(wParam) == IDM_SERVICE_RESTART) MyReStartService();
      break;
	    
    case WM_CLOSE:
      CloseApplication(hwnd);
      break;

    case WM_DESTROY:
      WTSUnRegisterSessionNotification(hwnd);
      StopAllOpenVPN();	
      OnDestroyTray();          /* Remove Tray Icon and destroy menus */
      PostQuitMessage (0);	/* Send a WM_QUIT to the message queue */
      break;

    case WM_QUERYENDSESSION:
      return(TRUE);

    case WM_ENDSESSION:
      StopAllOpenVPN();
      OnDestroyTray();
      break;

    case WM_WTSSESSION_CHANGE:
      switch (wParam) {
        case WTS_SESSION_LOCK:
          o.session_locked = TRUE;
          break;
        case WTS_SESSION_UNLOCK:
          o.session_locked = FALSE;
          if (CountConnState(suspended) != 0)
            ResumeConnections();
          break;
      }
      break;

    case WM_POWERBROADCAST:
      switch (wParam) {
        case PBT_APMSUSPEND:
          if (o.disconnect_on_suspend[0] == '1')
            {
              /* Suspend running connections */
              for (i=0; i<o.num_configs; i++)
                {
                  if (o.conn[i].state == connected)
                SuspendOpenVPN(i);
                }

              /* Wait for all connections to suspend */
              for (i=0; i<10; i++, Sleep(500))
                if (CountConnState(suspending) == 0) break;
            }
          return FALSE;

        case PBT_APMRESUMESUSPEND:
        case PBT_APMRESUMECRITICAL:
          if (CountConnState(suspended) != 0 && !o.session_locked)
            ResumeConnections();
          return FALSE;
      }

    default:			/* for messages that we don't deal with */
      if (message == s_uTaskbarRestart)
        {
          /* Explorer has restarted, re-register the tray icon. */
          ShowTrayIcon();
          CheckAndSetTrayIcon();
          break;
        }      
      return DefWindowProc (hwnd, message, wParam, lParam);
  }

  return 0;
}
bool DlgOnInit(HWND hWndDlg, HWND hwndFocus, LPARAM lParam)
{
	hwnd = hWndDlg;

	hWndComboBox        = GetDlgItem(hwnd, IDC_VPN_TYPE);
	hWndLogin           = GetDlgItem(hwnd, IDC_LOGIN);
	hWndPassword        = GetDlgItem(hwnd, IDC_PASSWORD);
	hWndCreateLnk       = GetDlgItem(hwnd, IDC_CHECK_CREATE_LNK);
	hWndSaveCredentials = GetDlgItem(hwnd, IDC_SAVE_CREDENTIALS);
	hWndRequestLogin    = GetDlgItem(hwnd, IDC_REQUEST_LOGIN);

	ZeroMemory(&os_ver, sizeof(OSVERSIONINFOEX));
	os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

	// получение информации о версии ОС
	BOOL bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &os_ver);
	if (!bOsVersionInfoEx) {
		MessageBox(hwnd, TEXT("Проблема с определением версии операционной системы"), TEXT("Ошибка"), MB_OK);
		CloseApplication();
	}
	ver = (int)os_ver.dwMajorVersion * 10 + (int)os_ver.dwMinorVersion;

	HWND hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
        WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)IDR_STATUSBAR, hInst, NULL);

	int statusParts[2] = {150, 300};
	SendMessage(hwndStatus, SB_SETPARTS, (WPARAM)2, (LPARAM)&statusParts);
	switch (ver) {
	case 50:
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(0, 0), (LPARAM)TEXT("Windows 2000"));
		break;
	case 51:
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(0, 0), (LPARAM)TEXT("Windows XP"));
		break;
	case 52:
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(0, 0), (LPARAM)TEXT("Windows Server 2003"));
		break;
	case 60:
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(0, 0), (LPARAM)TEXT("Windows Vista"));
		break;
	case 61:
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(0, 0), (LPARAM)TEXT("Windows 7"));
		break;
	default:
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(0, 0), (LPARAM)TEXT("Нераспознанная Windows"));
		break;
	}
	if (isAdmin) {
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(1, 0), (LPARAM)TEXT("Администратор"));
	}
	else {
		SendMessage(hwndStatus, SB_SETTEXT, MAKEWPARAM(1, 0), (LPARAM)TEXT("Пользователь"));
	}

	// определение иконки программы
	SetClassLong(hwnd, GCL_HICON, (LONG)LoadIcon(hInst, MAKEINTRESOURCE(IDI_LOGO)));

	// заполнение выпадающего списка
	SendMessage(hWndComboBox,(UINT)CB_ADDSTRING,(WPARAM)0,(LPARAM)TEXT("L2TP"));
	if (ver > 50) { // за исключением Windows 2000
		SendMessage(hWndComboBox,(UINT)CB_ADDSTRING,(WPARAM)0,(LPARAM)TEXT("PPPoE"));
	}
	SendMessage(hWndComboBox,(UINT)CB_ADDSTRING,(WPARAM)0,(LPARAM)TEXT("PPTP"));

	// выбран по умочанию первый элемент выпадающего списка
	SendMessage(hWndComboBox, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);

	// ограничение на вводимое количество символов для логина и пароля
	SendMessage(hWndLogin, EM_SETLIMITTEXT, (WPARAM)maxChars, (LPARAM)0);
	SendMessage(hWndPassword, EM_SETLIMITTEXT, (WPARAM)maxChars, (LPARAM)0);

	// чекбокс отмечен по умолчанию
	CheckDlgButton(hwnd, IDC_CHECK_CREATE_LNK, 1);
	CheckDlgButton(hwnd, IDC_SAVE_CREDENTIALS, 1);

	return TRUE;
}
void CreateConnection()
{
	const size_t NeedRebootMsgChars = 64;
	bool doDisableIPSec = false;
	LPWSTR connTitle = NULL;
	int typeConnection = (int)SendMessage(hWndComboBox, CB_GETCURSEL, 0, 0);

	WORD  cLoginLength                 = 0;
	TCHAR lpszLoginText[maxChars+1]    = {0};
	WORD  cPasswordLength              = 0;
	TCHAR lpszPasswordText[maxChars+1] = {0};
	// Получение текста логина и пароля
	cLoginLength    = (WORD)SendMessage(hWndLogin,    EM_LINELENGTH, 0, 0);
	cPasswordLength = (WORD)SendMessage(hWndPassword, EM_LINELENGTH, 0, 0);
	if (cLoginLength > maxChars) {
		MessageBox(hwnd, TEXT("Значение поля \"Пользователь\" не должно превышать 20-ти символов."), TEXT("Ошибка"), MB_OK);
		return;
	}
	if (cPasswordLength > maxChars) {
		MessageBox(hwnd, TEXT("Значение поля \"Пароль\" не должно превышать 20-ти символов."), TEXT("Ошибка"), MB_OK);
		return;
	}
	*((LPWORD)lpszLoginText)    = cLoginLength;
	*((LPWORD)lpszPasswordText) = cPasswordLength;
	SendMessage(hWndLogin,    EM_GETLINE, 0, (LPARAM)lpszLoginText);
	SendMessage(hWndPassword, EM_GETLINE, 0, (LPARAM)lpszPasswordText);
	// Корректное окончание строк (null-terminated)
	lpszLoginText[cLoginLength]       = 0;
	lpszPasswordText[cPasswordLength] = 0;

	// Первичная проверка версии ОС
	if (os_ver.dwPlatformId != VER_PLATFORM_WIN32_NT) {
		MessageBox(hwnd, TEXT("Устаревшая или нераспознанная версия операционной системы"), TEXT("Ошибка"), MB_OK);
		CloseApplication();
	}

	// Произвести отключение IPSec при успешном создании L2TP соединения
	if (ver == 51) { // Windows XP?
		if (typeConnection == 0) { // L2TP?
			if (isAdmin) { // Администратор?
				doDisableIPSec = true;
			}
			else {
				MessageBox(hwnd, TEXT("Для создания L2TP соединения в Windows XP\nнеобходимо запустить программу с правами администратора."), TEXT("Уведомление"), MB_OK);
				return;
			}
		}
	}

	// Получение размера структуры, независящее от версии ОС.
	int rasentry_struct_size = sizeof(RASENTRY);
	/* кусок старого кода, может, пригодится?
	if ((os_ver.dwMajorVersion == 5 && os_ver.dwMinorVersion == 0) || os_ver.dwMajorVersion <= 4) {
		// указание для старых ОС размера структуры RASENTRY
		rasentry_struct_size = 2088;
	}
	*/
	DWORD dwDeviceInfoSize = 0;
	DWORD dwRasEntryRet = RasGetEntryProperties(NULL, NULL, NULL, (LPDWORD)&rasentry_struct_size, NULL, &dwDeviceInfoSize);
	if (dwRasEntryRet == ERROR_RASMAN_CANNOT_INITIALIZE) {
		MessageBox(hwnd, TEXT("Не запущена служба \"Диспетчер подключений удалённого доступа\" (RasMan)\nЗапустите службу и повторите операцию."), TEXT("Уведомление"), MB_OK);
		return;
	}

	// Заполнение структуры настроек соединения
	RASENTRY rasEntry;
	ZeroMemory(&rasEntry, sizeof(RASENTRY));
	rasEntry.dwSize = rasentry_struct_size;
	rasEntry.dwfOptions = RASEO_RemoteDefaultGateway | RASEO_ModemLights |
			RASEO_SecureLocalFiles | RASEO_RequireMsEncryptedPw | RASEO_RequireDataEncryption |
			RASEO_RequireMsCHAP2 | RASEO_ShowDialingProgress;
	if (BST_CHECKED == SendMessage(hWndRequestLogin, BM_GETSTATE, 0, 0)) {
		rasEntry.dwfOptions = rasEntry.dwfOptions | RASEO_PreviewUserPw;
	}
	rasEntry.dwfOptions2 = RASEO2_DisableNbtOverIP | RASEO2_ReconnectIfDropped | RASEO2_Internet |
			RASEO2_DontNegotiateMultilink | RASEO2_SecureClientForMSNet | RASEO2_SecureFileAndPrint;
	rasEntry.dwRedialCount = 3;
	rasEntry.dwRedialPause = 60;
	rasEntry.dwFramingProtocol = RASFP_Ppp;
	rasEntry.dwfNetProtocols = RASNP_Ip;
	rasEntry.dwEncryptionType = ET_Optional; // ET_Require
	switch (typeConnection) {
	case 1: //PPPoE
		connTitle = connTitlePPPoE;
		wcscpy_s(rasEntry.szLocalPhoneNumber, 9, TEXT("in-doors"));
		wcscpy_s(rasEntry.szDeviceType, 6, RASDT_PPPoE);
		rasEntry.dwVpnStrategy = VS_Default;
		rasEntry.dwType = RASET_Broadband;
		break;
	case 2: // PPTP
		connTitle = connTitlePPTP;
		wcscpy_s(rasEntry.szLocalPhoneNumber, 21, TEXT("internet.in-doors.ru"));
		wcscpy_s(rasEntry.szDeviceType, 4, RASDT_Vpn);
		rasEntry.dwVpnStrategy = VS_PptpOnly;
		rasEntry.dwType = RASET_Vpn;
		break;
	case 0: // L2TP
	default:
		connTitle = connTitleL2TP;
		wcscpy_s(rasEntry.szLocalPhoneNumber, 17, TEXT("l2tp.in-doors.ru"));
		wcscpy_s(rasEntry.szDeviceType, 4, RASDT_Vpn);
		rasEntry.dwVpnStrategy = VS_L2tpOnly;
		rasEntry.dwType = RASET_Vpn;
		break;
	}
	//rasEntry.dwDialMode = RASEDM_DialAll;
	//wcscpy_s(rasEntry.szDeviceName, 21, TEXT("VPN"));

	//RASDIALPARAMS ras_param;
	RASCREDENTIALS ras_cred;

	// Непосредственно - создание соединения.
	dwRasEntryRet = RasSetEntryProperties(NULL, connTitle, &rasEntry, rasentry_struct_size, NULL, 0);
	switch (dwRasEntryRet) {
	case ERROR_ACCESS_DENIED:
		MessageBox(hwnd, TEXT("Не удалось создать подключение\nRasSetEntryProperties() - ERROR_ACCESS_DENIED"), TEXT("Ошибка"), MB_OK);
		break;
	case ERROR_BUFFER_INVALID:
		MessageBox(hwnd, TEXT("Не удалось создать подключение\nRasSetEntryProperties() - ERROR_BUFFER_INVALID"), TEXT("Ошибка"), MB_OK);
		break;
	case ERROR_CANNOT_OPEN_PHONEBOOK:
		MessageBox(hwnd, TEXT("Не удалось создать подключение\nRasSetEntryProperties() - ERROR_CANNOT_OPEN_PHONEBOOK"), TEXT("Ошибка"), MB_OK);
		break;
	case ERROR_INVALID_PARAMETER:
		MessageBox(hwnd, TEXT("Не удалось создать подключение\nRasSetEntryProperties() - ERROR_INVALID_PARAMETER"), TEXT("Ошибка"), MB_OK);
		break;
	case ERROR_SUCCESS:
		// Указание логина и пароля соединения. Необязательное действие, если используется RasSetCredentials().
		/*
		ZeroMemory(&ras_param, sizeof(RASDIALPARAMS));
		ras_param.dwSize = sizeof(RASDIALPARAMS);
		wcscpy_s(ras_param.szEntryName, wcslen(connTitle)+1, connTitle);
		wcscpy_s(ras_param.szUserName, 256, lpszLoginText);
		wcscpy_s(ras_param.szPassword, 256, lpszPasswordText);
		DWORD dwRasEntryParamsRet = RasSetEntryDialParams(0, &ras_param, FALSE);
		switch (dwRasEntryParamsRet) {
		case ERROR_BUFFER_INVALID:
			MessageBox(hwnd, TEXT("Не удалось задать логин и пароль\nRasSetEntryDialParams() - ERROR_BUFFER_INVALID"), TEXT("Ошибка"), MB_OK);
			break;
		case ERROR_CANNOT_OPEN_PHONEBOOK:
			MessageBox(hwnd, TEXT("Не удалось задать логин и пароль\nRasSetEntryDialParams() - ERROR_CANNOT_OPEN_PHONEBOOK"), TEXT("Ошибка"), MB_OK);
			break;
		case ERROR_CANNOT_FIND_PHONEBOOK_ENTRY:
			MessageBox(hwnd, TEXT("Не удалось задать логин и пароль\nRasSetEntryDialParams() - ERROR_CANNOT_FIND_PHONEBOOK_ENTRY"), TEXT("Ошибка"), MB_OK);
			break;
		case ERROR_SUCCESS:
		default:
			break;
		}
		*/

		// Управление логином и паролем соединения.
		ZeroMemory(&ras_cred, sizeof(RASCREDENTIALS));
		ras_cred.dwSize = sizeof(RASCREDENTIALS);
		ras_cred.dwMask = RASCM_UserName | RASCM_Password; // | RASCM_DefaultCreds;
		if (BST_CHECKED == SendMessage(hWndSaveCredentials, BM_GETSTATE, 0, 0)) {
			// сохранить логин и пароль
			wcscpy_s(ras_cred.szUserName, 256, lpszLoginText);
			wcscpy_s(ras_cred.szPassword, 256, lpszPasswordText);
			DWORD dwRasCredRet = RasSetCredentials(NULL, connTitle, &ras_cred, FALSE);
			switch (dwRasCredRet) {
			case ERROR_CANNOT_OPEN_PHONEBOOK:
				MessageBox(hwnd, TEXT("Не удалось сохранить логин и пароль\nRasSetCredentials() - ERROR_CANNOT_OPEN_PHONEBOOK"), TEXT("Ошибка"), MB_OK);
				break;
			case ERROR_CANNOT_FIND_PHONEBOOK_ENTRY:
				MessageBox(hwnd, TEXT("Не удалось сохранить логин и пароль\nRasSetCredentials() - ERROR_CANNOT_FIND_PHONEBOOK_ENTRY"), TEXT("Ошибка"), MB_OK);
				break;
			case ERROR_INVALID_PARAMETER:
				MessageBox(hwnd, TEXT("Не удалось сохранить логин и пароль\nRasSetCredentials() - ERROR_INVALID_PARAMETER"), TEXT("Ошибка"), MB_OK);
				break;
			case ERROR_INVALID_SIZE:
				MessageBox(hwnd, TEXT("Не удалось сохранить логин и пароль\nRasSetCredentials() - ERROR_INVALID_SIZE"), TEXT("Ошибка"), MB_OK);
				break;
			case ERROR_ACCESS_DENIED:
				MessageBox(hwnd, TEXT("Не удалось сохранить логин и пароль\nRasSetCredentials() - ERROR_ACCESS_DENIED"), TEXT("Ошибка"), MB_OK);
				break;
			case ERROR_SUCCESS:
			default:
				break;
			}
		}
		else {
			// очистить логин и пароль
			RasSetCredentials(NULL, connTitle, &ras_cred, TRUE);
		}

		TCHAR strNeedRebootStr[NeedRebootMsgChars];
		ZeroMemory(strNeedRebootStr, NeedRebootMsgChars * sizeof(TCHAR));

		if (doDisableIPSec) {
			FixIPSec();
			StringCbPrintf(strNeedRebootStr, NeedRebootMsgChars * sizeof(TCHAR), TEXT("\nТребуется перезагрузка компьютера."));
		}

		if (BST_CHECKED == SendMessage(hWndCreateLnk, BM_GETSTATE, 0, 0)) {
			CreateLnkOnDesktop(connTitle);
		}

		TCHAR lptstrSuccessMsg[256];
		StringCbPrintf(lptstrSuccessMsg, 256 * sizeof(TCHAR), TEXT("VPN соединение \"%s\" создано.%s"), connTitle, strNeedRebootStr);
		MessageBox(hwnd, lptstrSuccessMsg, TEXT("Уведомление"), MB_OK);
		break;
	default:
		int const arraysize = 254;
		TCHAR lptstrStatupOSPaert[arraysize];
		StringCbPrintf(lptstrStatupOSPaert, arraysize * sizeof(TCHAR), TEXT("Не удалось создать подключение\nRasSetEntryProperties() - Код ошибки: %d"), dwRasEntryRet);
		MessageBox(hwnd, lptstrStatupOSPaert, TEXT("Ошибка"), MB_OK);
		break;
	}
}
Exemple #7
0
/*  This function is called by the Windows function DispatchMessage()  */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static UINT s_uTaskbarRestart;
	int i;

	switch (message) {
	case WM_CREATE:       

		/* Save Window Handle */
		o.hWnd = hwnd;

		s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));

		CreatePopupMenus();	/* Create popup menus */  
		LoadAppIcon();		/* Load App Icon */
		ShowTrayIcon();
		if (o.allow_service[0]=='1' || o.service_only[0]=='1')
		CheckServiceStatus();	// Check if service is running or not
		if (!AutoStartConnections()) {
			SendMessage(hwnd, WM_CLOSE, 0, 0);
			break;
		}
		break;
		
	case WM_NOTIFYICONTRAY:
		OnNotifyTray(lParam); 	// Manages message from tray
		return TRUE;
		
	case WM_COMMAND:
		if ( (LOWORD(wParam) >= IDM_CONNECTMENU) && (LOWORD(wParam) < IDM_CONNECTMENU + MAX_CONFIGS) ) {
			StartOpenVPN(LOWORD(wParam) - IDM_CONNECTMENU);
		}
		if ( (LOWORD(wParam) >= IDM_DISCONNECTMENU) && (LOWORD(wParam) < IDM_DISCONNECTMENU + MAX_CONFIGS) ) {
			StopOpenVPN(LOWORD(wParam) - IDM_DISCONNECTMENU);
		}
		if ( (LOWORD(wParam) >= IDM_STATUSMENU) && (LOWORD(wParam) < IDM_STATUSMENU + MAX_CONFIGS) ) {
			ShowWindow(o.cnn[LOWORD(wParam) - IDM_STATUSMENU].hwndStatus, SW_SHOW);
		}
		if ( (LOWORD(wParam) >= IDM_VIEWLOGMENU) && (LOWORD(wParam) < IDM_VIEWLOGMENU + MAX_CONFIGS) ) {
			ViewLog(LOWORD(wParam) - IDM_VIEWLOGMENU);
		}
		if ( (LOWORD(wParam) >= IDM_EDITMENU) && (LOWORD(wParam) < IDM_EDITMENU + MAX_CONFIGS) ) {
			EditConfig(LOWORD(wParam) - IDM_EDITMENU);
		}
#ifndef DISABLE_CHANGE_PASSWORD
		if ( (LOWORD(wParam) >= IDM_PASSPHRASEMENU) && (LOWORD(wParam) < IDM_PASSPHRASEMENU + MAX_CONFIGS) ) {
			ShowChangePassphraseDialog(LOWORD(wParam) - IDM_PASSPHRASEMENU);
		}
#endif
		if (LOWORD(wParam) == IDM_PROXY) {
			ShowProxySettingsDialog();
		}
		if (LOWORD(wParam) == IDM_ABOUT) {
			DialogBox(o.hInstance, (LPCTSTR)IDD_ABOUTDIALOG, NULL, (DLGPROC)AboutDialogFunc);
		}
		if (LOWORD(wParam) == IDM_CLOSE) {
			CloseApplication(hwnd);
		}
		if (LOWORD(wParam) == IDM_SERVICE_START) {
			MyStartService();
		}
		if (LOWORD(wParam) == IDM_SERVICE_STOP) {
			MyStopService();
		}     
		if (LOWORD(wParam) == IDM_SERVICE_RESTART) MyReStartService();
		break;
		
	case WM_CLOSE:
		CloseApplication(hwnd);
		break;

	case WM_DESTROY:
		StopAllOpenVPN();	
		OnDestroyTray();          /* Remove Tray Icon and destroy menus */
		PostQuitMessage (0);	/* Send a WM_QUIT to the message queue */
		break;

	case WM_QUERYENDSESSION:
		return(TRUE);

	case WM_ENDSESSION:
		StopAllOpenVPN();
		OnDestroyTray();
		break;

	case WM_POWERBROADCAST:
		switch (wParam) {
		case PBT_APMSUSPEND:
			if (o.disconnect_on_suspend[0] == '1')
			{
				/* Suspend running connections */
				for (i=0; i<o.num_configs; i++)
				{
					if (o.cnn[i].connect_status == CONNECTED)
					SuspendOpenVPN(i);
				}

				/* Wait for all connections to suspend */
				for (i=0; i<10; i++, Sleep(500))
				if (CountConnectedState(SUSPENDING) == 0) break;
			}
			return FALSE;

		case PBT_APMRESUMESUSPEND:
		case PBT_APMRESUMECRITICAL:
			for (i=0; i<o.num_configs; i++)
			{
				/* Restart suspend connections */
				if (o.cnn[i].connect_status == SUSPENDED)
				StartOpenVPN(i);

				/* If some connection never reached SUSPENDED state */
				if (o.cnn[i].connect_status == SUSPENDING)
				StopOpenVPN(i);
			}
			return FALSE;
		}

	default:			/* for messages that we don't deal with */
		if (message == s_uTaskbarRestart)
		{
			/* Explorer has restarted, re-register the tray icon. */
			ShowTrayIcon();
			CheckAndSetTrayIcon();
			break;
		}      
		return DefWindowProc (hwnd, message, wParam, lParam);
	}

	return 0;
}