⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcpserver.cpp

📁 远程控制软件源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

		return Shell_NotifyIcon( NIM_ADD, &g_nid );
			
	case WM_VERSIONUPDATE:
		DWORD iCmp;
		if( CURRENT_VERSION > wParam ) 
			iCmp = (DWORD)VERSION_LOW;
		else if( CURRENT_VERSION == wParam )
			iCmp = (DWORD)VERSION_EQUAL;
		else
			iCmp = (DWORD)VERSION_HIGH;
		
		PostThreadMessage( lParam, WM_VERSIONUPDATE, iCmp, CURRENT_VERSION );
		if( iCmp == VERSION_HIGH ) // 正在运行的 RCA 版本较低,应该退出,现在尝试退出
		{
			DestroyWindow( hwnd );
			PostThreadMessage( lParam, WM_OLDVERSIONEXIT, 0, 0 );
		}

		return 0;

	case WM_DESTROY:
		g_bMustExit = TRUE;
		DWORD ret;
		SetEvent( g_hExitEvent );


		ret = WaitForSingleObject ( ::g_hServiceMainThreadHandle, 10000 );
		if ( ret != WAIT_OBJECT_0 )
		{	
		
			MessageBox( hwnd, "严重错误", "报告", MB_ICONINFORMATION );
			exit(0);
		}

		PostQuitMessage(0);
		CloseHandle( g_hExitEvent );
		Shell_NotifyIcon( NIM_DELETE, &g_nid );
		break;

	case WM_CLOSE:
		DestroyWindow( hwnd );
		break;

	case WM_TIMER:
		if( wParam == 3 )
			DestroyWindow( hwnd );
		break;

	default:
		return DefWindowProc(hwnd, msg, wParam, lParam );

	}

	return DefWindowProc(hwnd, msg, wParam, lParam );
}



INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
//int _cdecl main()
{
	//ShellExecute( NULL, NULL, "notepad", "", NULL, SW_SHOWNORMAL );
	g_hInstance = GetModuleHandle(NULL);

	
	// 执行必须的初始化

	if( RCAInit() )
	{

		DWORD dwResult;
		//////////////////////////////////////
		// 
		// CanGoon 函数进行必要的版本控制. 如果函数返回 TRUE,
		// 将表示当前这个 RCAServer 可以运行,具体说明参考 CanGoon 函数
		// 
		//
		if( CanGoon( &dwResult ) ) 
		{
			
			g_hExitEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

			// 创建服务主线程, 线程将监听客户的请求
			if( ServiceInit() == TRUE )
			{
				if( ServiceMainThreadStartup() == TRUE )
				{
					ResumeThread( ::g_hServiceMainThreadHandle );
				} else
					goto init_failed;
			} else
				goto init_failed;
					

			SetTimer( g_hWnd, 3, TIME_LIMIT * 60 * 1000, NULL );
			MSG msg;
			while( GetMessage( &msg, NULL, 0, 0 ) )
			{
 				
				TranslateMessage( &msg );
				DispatchMessage( &msg );

			}

init_failed:
			if( g_hRunningControlSemaphore != NULL )
				ReleaseSemaphore( g_hRunningControlSemaphore, 1, NULL );
			SAFE_CLOSE_HANDLE( g_hRunningControlSemaphore );
			ServiceUninit();

		}
	
		RCAUninit();
	}
	else 
	{
		//RCAUninit();
		return -1;
	}


	return 0;

}



///////////////////////////////////////////////
//
//	函数原型:	BOOL RCAInit();
//
//	功能:		执行时必须进行的初始化部分
//				
//	返回值		TRUE -- 初始化成功, RCA将继续运行
//				FALSE-- 失败, RCA 必须退出
//
BOOL WINAPI RCAInit() 
{
	
	
	
	// 获取版本信息 ---- g_SysVer;
	
	g_SysVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx( &g_SysVer);

	switch( g_SysVer.dwPlatformId )
	{
	case VER_PLATFORM_WIN32s:// Windows 3.x , return FALSE, 不支持
		return FALSE;
		
	case VER_PLATFORM_WIN32_WINDOWS:	// Win9x/ME
		if( g_SysVer.dwMinorVersion == 0 )
			lstrcpy( g_pszOS, "WIN95" );
		else
			lstrcpy( g_pszOS, "WIN98" );
		g_bCanAcceptEx = FALSE;					// Win9x/ME 不支持 AcceptEx 函数
		break;

	case VER_PLATFORM_WIN32_NT:			// Windows NT/2000;
		switch( g_SysVer.dwMajorVersion )
		{
		case 4:
			lstrcpy( g_pszOS, "WINNT" ); break;
		case 5:
			if( g_SysVer.dwMinorVersion > 0 )
			{ 
				lstrcpy( g_pszOS, "WINXP" ); break;
			}
			else
			{
				lstrcpy( g_pszOS, "WIN2K" ); break;
			}

		default:
			return FALSE;
		}
		g_bCanAcceptEx = TRUE;					// Windows NT/2000 支持 套接字函数 AcceptEx
		break;
	default:			// 无法识别
		return FALSE;
	}
	
	// 获取计算机名 g_pszComputerName

	DWORD dwSize = MAX_COMPUTERNAME_LENGTH +1;
	if( !GetComputerName( g_pszComputerName, &dwSize ) )
	{
		DEBUGOUTPUT1( "Call GetComputerName failed" );
		return FALSE;
	}

	DEBUGOUTPUT2( "计算机名: ", g_pszComputerName );


	
	//////////////////////////////////////////////////
	// 获系统目录路径 g_pszSystemDir;
	//	
	//	example:
	//	for win9x		c:\Windows\system
	//	for winnt/2000	c:\winnt\system32

	dwSize = 0;
	dwSize = GetSystemDirectory( NULL, 0 );
	if( dwSize == NULL )
		return FALSE;

	dwSize ++;
	g_pszSystemDir = NULL;
	g_pszSystemDir = new CHAR[ dwSize ];
	if( g_pszSystemDir == NULL )
	{
		DEBUGOUTPUT1( "ERROR - not enough memory" );
		return FALSE;
	}
	dwSize = GetSystemDirectory( g_pszSystemDir, dwSize );

	DEBUGOUTPUT2( "当前系统目录是: ", g_pszSystemDir );

	
	
	////////////////////////////////////////////////////
	// 获取当前用户名

	dwSize = UNLEN +1;
	if( ! GetUserName( g_pszUserName, &dwSize ) )
	{
		DEBUGOUTPUT1( "Call GetUserName failed" );
		return FALSE;
	}
	DEBUGOUTPUT2( "当前用户名:", g_pszUserName );


	
	/////////////////////////////////////////////////////
	// 获取 Windows  目录
	// 
	// example: 
	// for Win9x		C:\Windows
	// for WinNT/2000	C:\winnt
	
	dwSize = 0;
	dwSize = GetWindowsDirectory( NULL, 0 );
	if( dwSize == NULL )
		return FALSE;

	dwSize ++;

	g_pszWindowsDir = NULL;
	g_pszWindowsDir = new CHAR[ dwSize ];
	if( g_pszWindowsDir == NULL )
	{
		DEBUGOUTPUT1( "ERROR - not enough memory" );
		delete[] g_pszSystemDir;
		return FALSE;
	}

	dwSize = GetWindowsDirectory( g_pszWindowsDir, dwSize );

	DEBUGOUTPUT2( "Windows 目录是: ", g_pszWindowsDir );


	////////////////////////////////////////////////////////
	// 获取内存信息
	//
	GlobalMemoryStatus( &g_MemoryStatus );

	g_hBig		= LoadIcon( g_hInstance, MAKEINTRESOURCE(IDI_BIG) );
	g_hSmall	= LoadIcon( g_hInstance, MAKEINTRESOURCE(IDI_SMALL) );
	g_hShellIconMenu = CreatePopupMenu();

	AppendMenu( g_hShellIconMenu,
		MF_STRING, 1, "打开 RCA 服务管理器(&O) (beta版未实现)" );

	AppendMenu( g_hShellIconMenu,
		MF_SEPARATOR, 0, NULL );

	AppendMenu( g_hShellIconMenu,
		MF_STRING, 2, "退出(&E)" );
	


	return TRUE;
}


/////////////////////////////////////////////////////////////
//
//	原型:	BOOL RCAUninit();
// 
//	功能:	程序退出时,进行清除操作
//
//	返回值: 返回 TRUE 表示成功清除, FALSE 表示失败
//

BOOL WINAPI RCAUninit()
{
	DestroyMenu( g_hShellIconMenu );
	
	SAFE_DELETE_ARRAY( g_pszSystemDir );
	SAFE_DELETE_ARRAY( g_pszWindowsDir );

	return TRUE;
}


//////////////////////////////////////////////////////////////
//	
//	原型:	void OutputAddr( unsigned int u );
//
//	功能:	在控制台输出一个描述 IP 地址的无符号整数
//
//	注:		这个无符号整数已经被字节反序编码过的,
//			输出时最低字节将被先输出,最高字节最后输出
//	
//	返回值:	无
//


void WINAPI OutputAddr( unsigned int u )
{
	cout<< ((u & 0xFF000000) >> 24) << "." 
		<< ((u & 0x00ff0000) >> 16) << "."
		<< ((u & 0x0000ff00) >> 8) << "."
		<< ((u & 0x000000ff) >> 0) ;
}



////////////////////////////////////////////////////////////
//
// CanGoon 函数进行必要的版本控制. 如果函数返回 TRUE,
// 将表示当前这个 RCAServer 可以运行,这将发生在以下两种情况:
// 
// 1.	当前系统没有任何 RCAServer 在运行,这时本 RCAServer 将顺利运行。
//		这是通过一个 Semaphore 对象对正在运行的任何版本的 RCAServer 进行控制实现的
// 2.	首先说明一点,Semaphore 对象将保证当前系统绝不会有三个或三个以上的无论什么版本的RCAServer 同时运行
//		若当前系统有一个 RCAServer 在运行, CanGoon 将试图查找正运行的 RCAServer 的主窗口, 找不到将退出
//		找到后会给窗口 Post 一个 WM_VERSIONUPDATE 消息, 以校验两个 RCAServer 的版本到底谁年轻谁 TMD 老该死
//
//		几种情况:	
//			更早运行的 RCAServer 版本低, 并且没有活动的连接,更早运行的 RCAServer 版本将退出
//			新版本的将继续初始化并替代老版本的执行 RCP 服务
//    
//			更早运行的 RCAServer 版本低,但有活动的连接,新版本的将等待一段时间(不长,几秒钟),若这
//			若这段时间内老版本的所有连接已关闭, 老的将退出,由新的替代运行,若这段时间连接仍未关闭,
//			新的高版本的 RCAServer 将退出
//
//			更早运行的 RCAServer 版本高, 简单, 新的低版本 RCAServer 直接退出.
//
//	返回值: TRUE	--- 此 RCAServer 实例将可以继续运行
//			FALSE	--- 此 RCAServer 实例必须退出
//
BOOL WINAPI CanGoon( DWORD * result )
{

	// 

	BOOL bAlreadyRun		= FALSE;
	DWORD dwWaitResult;
	g_hRunningControlSemaphore = 
		CreateSemaphore( NULL, 2, 2, RCA_RUNNING_CONTROL_SEMAPHORE_NAME	);

	if( !g_hRunningControlSemaphore )
		return FALSE;

	if( GetLastError() == ERROR_ALREADY_EXISTS )	// 信标对象已经存在, 将试图找 
	{												// RCA SERVER 主窗口, 并进行版本更新

		dwWaitResult = WaitForSingleObject( g_hRunningControlSemaphore, 500 );
		if( dwWaitResult == WAIT_TIMEOUT )
		{
			
			SAFE_CLOSE_HANDLE( g_hRunningControlSemaphore );
			return FALSE;
		}

		bAlreadyRun = TRUE;

		HWND oldRCAMainWnd = FindWindow( SERVER_WINDOW_CLASSNAME, 
										 SERVER_WINDOW_CAPTIONNAME);
		if( !oldRCAMainWnd ) // 如果找不到,先休眠 2 秒, 再次试图查找窗口
			Sleep(2000);

		oldRCAMainWnd = FindWindow( SERVER_WINDOW_CLASSNAME, 
									SERVER_WINDOW_CAPTIONNAME );
		if( !oldRCAMainWnd ) // 如果还找不到,返回 FALSE,必须退出,信标对象无法准确定位
			return FALSE;

		PostMessage( oldRCAMainWnd, WM_VERSIONUPDATE, 
					 CURRENT_VERSION, GetCurrentThreadId() );

		MSG msg;
		int count = 4; // 循环 4 次
		while( count ) // 等待正在工作的 RCA 回递版本更新的消息
		{
			Sleep( 500 );  // 
			if( PeekMessage( &msg, NULL, WM_VERSIONUPDATE, WM_VERSIONUPDATE, PM_REMOVE ) )
			{
				DWORD iCmp = msg.wParam;	// wParam 为版本比较结果信息
				WORD oldVersion = LOWORD(msg.lParam);	// lParam 的低字为正在工作的 RCA 版本

				// 正在工作的RCA 是否可以退出, 假如正在工作的 RCA 版本低,
				// 但有连接在工作中,则为 FALSE,即无法退出
				BOOL bOldRCARunning = (BOOL)HIWORD(msg.lParam); 


				
				if( iCmp == VERSION_LOW )  // 本版本低, 必须退出
				{
					ReleaseSemaphore( g_hRunningControlSemaphore , 1, NULL );
					SAFE_CLOSE_HANDLE( g_hRunningControlSemaphore );

					return FALSE;

				} else if( iCmp == VERSION_EQUAL ) // 正在工作的版本与本版本相同,也退出
				{
					ReleaseSemaphore( g_hRunningControlSemaphore, 1, NULL );
					SAFE_CLOSE_HANDLE( g_hRunningControlSemaphore );
					return FALSE;

				} else if( iCmp == VERSION_HIGH ) // 本版本高,可以开始更新
				{
					BOOL bOldRCAExit = FALSE;

					count = 4;
					while( count )
					{
						Sleep( 500 ); 
						if( PeekMessage( &msg, NULL, WM_OLDVERSIONEXIT, WM_OLDVERSIONEXIT, PM_REMOVE ) )
						{
							bOldRCAExit = TRUE;
							break;
						} else 
							count-- ;
					}
					if( bOldRCAExit == FALSE ) // 虽然正在工作的版本低,但无法退出(有连接等)
					{
						ReleaseSemaphore( g_hRunningControlSemaphore, 1, NULL );
						SAFE_CLOSE_HANDLE( g_hRunningControlSemaphore );
						return FALSE;
					}
					break; // 跳出版本更新的消息通信循环
				}
				
			} else
				count --;

		}

	}

	WNDCLASSEX wcex;
	wcex.cbClsExtra		= 0;
	wcex.cbSize			= sizeof( wcex );
	wcex.cbWndExtra		= 0;
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW );
	wcex.hCursor		= LoadCursor( NULL, IDC_ARROW );
	wcex.hIcon			= g_hBig;
	wcex.hIconSm		= g_hSmall;
	wcex.hInstance		= g_hInstance;
	wcex.lpfnWndProc	= MainWndProc;
	wcex.lpszClassName	= SERVER_WINDOW_CLASSNAME;
	wcex.lpszMenuName	= NULL;
	wcex.style			= CS_HREDRAW | CS_VREDRAW;

	if( !RegisterClassEx( &wcex ) )
	{
		RCAUninit();
		return -1;
	}

	g_hWnd = CreateWindow( SERVER_WINDOW_CLASSNAME, SERVER_WINDOW_CAPTIONNAME,
			WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 
			CW_USEDEFAULT, 400, 300,
			NULL, NULL, g_hInstance, NULL );

	if( g_hWnd == NULL )
	{
		RCAUninit();
		return -1;
	}

	ShowWindow( g_hWnd, SW_HIDE);
	UpdateWindow( g_hWnd );

	
	return TRUE;
}
 /*		// 接收请求头
		while ( nLeft > 0 )
		{
			ret = recv( sockRemote, &(headBuffer[i]), nLeft, 0 );
			if( ret == SOCKET_ERROR )
			{
				if( WSAGetLastError() != WSAEWOULDBLOCK )
				{
					bRecv = FALSE;
					break;
				}

			} 
			else 
			{

				nLeft -= ret;
				i += ret;
				continue;
			}

			DWORD dw = WaitForSingleObject( hEvent, INFINITE );
			WSANETWORKEVENTS netEvents;

			ret = WSAEnumNetworkEvents( sockRemote, hEvent, &netEvents );
			if( ret != 0 )
			{
				DEBUGOUTPUT1( WSAERRORSTRING );
				bRecv = FALSE;
				break;
			}

			if( netEvents.lNetworkEvents & FD_READ )
			{
				if( netEvents.iErrorCode[FD_READ_BIT] != 0 )
				{
					DEBUGOUTPUT1( WSAERRORSTRING );
					bRecv = FALSE;
					break;
				
				} else
					continue;
			}
			if( netEvents.lNetworkEvents & FD_CLOSE )
			{
				bRecv = FALSE;
				break;
			}
		} // recv while
	*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -