본문 바로가기
컴퓨터/자작 프로그램

원격 접속해서 컴퓨터 끄기

by adnoctum 2013. 1. 12.




   윈도우즈에서 원격 접속을 할 경우 접속당한 컴퓨터를 끄는 코드를 살펴 보자. 최종 사용자는 이 곳에 올려 놓는 exe 파일을 사용하면 끌 수 있다. 사용할 때, 접속이 끊기는데 끌 것이냐고 계속 묻는데 그럴 때마다 OK 를 누르면 꺼진다. 




현재 시간과 사용자가 선택한 시간이 동일하면 꺼지거나 재부팅을 하게 된다. source code 는 Visual C++ 6.0 으로 작성되어 있으며, project file 을 이 곳에 올려 둔다 - 이것은 이 프로그램이 악성 프로그램은 아니라는 것을 보여주기 위함이기도 하다, ㅋ. 



코드가 한 50여 줄 정도밖에 안되는 아주아주 간단한 프로그램이다. 공개할 목적으로 만든 건 아니고, 내가 필요해서 한 십여분 정도 뚝딱거려 만들어서 꽤 자주 사용하다가 생각이 나서 이 곳에 올려 두는 바이다. 그럴 정도도 아니겠지만 이 코드의 수정/베포는 당연히 자유이며 이 곳에 굳이 그것을 말할 필요도 없다. 오히려, 내가 GUI 에 전혀 신경쓰지 않은 이것을 누군가가 좀 보기 좋게(?, ㅋㅋ) 바꾸길 바라는 바이다. 


위 용도로 어떤 다른 프로그램이 있는지는 잘 모르겠다. 내가 만들 수 있는 것은 찾기보다 그냥 만드는 것이 더 내 마음에 쏙 들게 할 수 있어서 찾아보기 보다 위처럼 간단한 건 일단 만들어 사용해서..., >,<""


주요한 source 는 다음이다. 


int CTimerView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	_hour.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST 
				| CBS_AUTOHSCROLL , CRect(100,100,160,300),this,1010);
	_minute.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST 
				   | CBS_AUTOHSCROLL, CRect(200,100,260,300),this,1010);
	_chkReboot.Create("Reboot",WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 
					  CRect(300,100,400,120),this,1020);
 
	TCHAR temp[10] = "";
	for(int i = 0; i<60; i++){
		itoa(i,temp,10);
		if(i<24){
			_hour.AddString(temp);
		}
		_minute.AddString(temp);
	}
 
	SetTimer(1,1000,NULL);
 
	
	return 0;
}
 
void CTimerView::OnTimer(UINT nIDEvent) 
{
 
	CTime t = CTime::GetCurrentTime();
	CClientDC dc(this);
 
	CString str = t.Format("%H시 %M분 %S초");
	dc.TextOut(110,130,str);
 
	int Hour = _hour.GetCurSel();
	int Minute = _minute.GetCurSel();
 
	if( Hour == t.GetHour() && Minute == t.GetMinute()){
		KillTimer(1000);
		HANDLE hToken; 
		TOKEN_PRIVILEGES tkp; 
		
		// Get a token for this process. 	
		OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
			&hToken);
 
		// Get the LUID for the shutdown privilege. 	
		LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid); 
		
		tkp.PrivilegeCount = 1;  // one privilege to set    
		tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
		
		// Get the shutdown privilege for this process. 	
		AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 
		
 
		if(_chkReboot.GetCheck() == 1){
			if(ExitWindowsEx(EWX_REBOOT,0)==0){
				if(ExitWindowsEx(EWX_REBOOT|EWX_FORCE,0) ==0){
					ExitWindowsEx(EWX_REBOOT|0x00000010,0);
				}
			}
		}
		else{
			if(ExitWindowsEx(EWX_POWEROFF,0)==0){
				if(ExitWindowsEx(EWX_POWEROFF|EWX_FORCE,0)==0){
					ExitWindowsEx(EWX_POWEROFF|0x00000010,0);
				}
			}
		}
	}
	
	CView::OnTimer(nIDEvent);
}



자세한 내용은 MSDN 을 찾아 볼 것을 추천한다. 나도 MSDN 보고 끄적거린 것일 뿐이니까. (저 주석을 내가 쓴 건지 아닌지도 좀 아리까리 하다, 영어랑 한글을 주석에 섞어 써서...)