블로그 이미지
랜달프

calendar

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

Notice

    2009. 3. 18. 19:20 Programming/C programming

    우리가 흔히 리눅스에서

    rdate -s time.bora.net

    이라는 명령어로 시간을 맞춘다

    즉,     time.bora.net   이라는 타임 서버에서 프로토콜에 맞춰 값을 가져온 후 시스템에 적용 하는 것이다.
    다음은 RFC 868 문서를 보고 만든 것인데 time.bora.net 서버에서 시간을 가져와 출력하는 코드이다.
    #ifdef _WIN32
    #include 
    #else
    #include 
    #include 
    #include 
    #include 
    #endif
    
    #include 
    #include 
    
    
    std::time_t getTime()
    {
    #ifdef _WIN32
    	WSADATA wsaData;
    #endif
    
    	int hSocket;
    	sockaddr_in servAddr;
    	std::time_t	sBuffer;
    	struct hostent* s_HostEntry;    
    	int strLen;
    	
    #ifdef _WIN32
    	if( WSAStartup(MAKEWORD(1,1),&wsaData) != 0 )
    	{
    		std::cout << "Startup Error" << std::endl;
    		return -1;
    	}
    #endif
    
    	hSocket = socket(PF_INET, SOCK_STREAM, 0);
    	
    	if( -1 == hSocket )
    	{
    		std::cout << "Socket Create Error" << std::endl;
    		return -1;
    	}
    
    	memset(&servAddr, 0, sizeof(servAddr));
    	servAddr.sin_family = AF_INET;
    	servAddr.sin_port = htons(37);
    
    	s_HostEntry = gethostbyname("time.bora.net");
    	memcpy((void *)(&servAddr.sin_addr), (void *)(s_HostEntry->h_addr), sizeof(servAddr.sin_addr));
    
    	if ( -1 == connect(hSocket, (sockaddr*)&servAddr, sizeof(servAddr)) )
    	{
    		return -1;
    	}
    
    	strLen = recv(hSocket, (char*)&sBuffer, sizeof(sBuffer), 0);
    	
    
    	if( -1 == strLen )
    	{
    		return -1;
    	}
    
    	sBuffer = ntohl(sBuffer) - 2208988800l;
    
    #ifdef _WIN32
    	closesocket(hSocket);
    	WSACleanup();
    #else
    	close(hSocket);
    #endif
    
    	return sBuffer;
    }
    
    int main()
    {
    	std::time_t currentTime;
    	std::tm* ts;
    	char str_time[80];
    
    	currentTime = getTime();
    	ts = localtime(¤tTime);      // 시스템에 적용된 시간대로 tm 구조체에 저장  (대한민국 표준시 GMT +09:00 )
    	//ts = gmtime(¤tTime);     // GMT  
    
    	strftime(str_time, 80, "%Y년 %m월 %d일 %H:%M:%S  %Z", ts);  // tm 구조체를 문자열로 저장
    
    	std::cout << str_time << std::endl;
    	
    	return 0;
    }
    
    struct tm 구조체
    #include 
    struct tm {
    
    	int tm_sec;   /* 초 */
    	int tm_min;   /* 분 */
    	int tm_hour;  /* 시 (0--23) */
    	int tm_mday;  /* 일 (1--31) */
    	int tm_mon;   /* 월 (0--11) */
    	int tm_year;  /* 년 (+ 1900) */
    	int tm_wday;  /* 요일 (0--6; 일요일 = 0) */
    	int tm_yday;  /* 올해 몇번째 날 (0--365) */
    	int tm_isdst; /* 서머타임 여부 */
    
    };
    

    실행 화면

    posted by 랜달프
    2009. 3. 18. 19:09 Programming/C programming


    RFC 868

    Network Working Group
    Request for Comments: 868

    J. Postel - ISI
    K. Harrenstien - SRI
    May 1983


    Time Protocol

    This RFC specifies a standard for the ARPA Internet community. Hosts on the ARPA Internet that choose to implement a Time Protocol are expected to adopt and implement this standard.
    This protocol provides a site-independent, machine readable date and time. The Time service sends back to the originating source the time in seconds since midnight on January first 1900.
    One motivation arises from the fact that not all systems have a date/time clock, and all are subject to occasional human or machine error. The use of time-servers makes it possible to quickly confirm or correct a system's idea of the time, by making a brief poll of several independent sites on the network.
    This protocol may be used either above the Transmission Control Protocol (TCP) or above the User Datagram Protocol (UDP).
    When used via TCP the time service works as follows:


    S: Listen on port 37 (45 octal).
    U: Connect to port 37.
    S: Send the time as a 32 bit binary number.
    U: Receive the time.
    U: Close the connection.
    S: Close the connection.


    The server listens for a connection on port 37. When the connection is established, the server returns a 32-bit time value and closes the connection. If the server is unable to determine the time at its site, it should either refuse the connection or close it without sending anything.

    When used via UDP the time service works as follows:


    S: Listen on port 37 (45 octal).
    U: Send an empty datagram to port 37.
    S: Receive the empty datagram.
    S: Send a datagram containing the time as a 32 bit binary number.
    U: Receive the time datagram.


    The server listens for a datagram on port 37. When a datagram arrives, the server returns a datagram containing the 32-bit time value. If the server is unable to determine the time at its site, it should discard the arriving datagram and make no reply.

    The Time

    The time is the number of seconds since 00:00 (midnight) 1 January 1900 GMT, such that the time 1 is 12:00:01 am on 1 January 1900 GMT; this base will serve until the year 2036.

    For example:

    the time

    2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT,

    2,398,291,200 corresponds to 00:00 1 Jan 1976 GMT,

    2,524,521,600 corresponds to 00:00 1 Jan 1980 GMT,
     
    2,629,584,000 corresponds to 00:00 1 May 1983 GMT,

    and

    -1,297,728,000 corresponds to 00:00 17 Nov 1858 GMT.

    posted by 랜달프
    VS2005 로 컴파일된 프로그램을 다른 PC에서 실행하였을때

    응용 프로그램 구성이 올바르지 않기 때문에 이 응용프로그램을 시작하지 못했습니다.
    이 문제를 해결하려면 응용 프로그램을 다시 설치하십시오

    이와 같은 경고가 뜨면서 실행이 안되는 경우가 있다

    이럴 경우 실행이 안되는 PC에 컴파일 했던 컴파일러에 맞는 재배포 가능 패키지를 설치해 주면 된다

    다운로드 링크

    1. Microsoft .NET Framework 버전 2.0 재배포 가능 패키지(x86)
    2. Microsoft Visual C++ 2005 재배포 가능 패키지(x86)
    3. Microsoft Visual C++ 2008 재배포 가능 패키지(x86)
    4. Microsoft Visual C++ 2008 SP1 재배포 가능 패키지(x86)
    5. Microsoft .NET Framework 3.5 서비스 팩 1
    posted by 랜달프
    2009. 3. 10. 15:07 Programming/Linux Programming
    파일의 상태 얻기
    #include 
    #include 
    #include 
    
    int stat(const char *file_name, struct stat *buf);
    int fstat(int filedes, struct stat *buf);
    int lstat(const char *file_name, struct stat *buf);
    

    파일의 상태는 다음과 같은 구조체에 저장
    struct stat
    {
    	dev_t         st_dev;      /* device */
    	ino_t         st_ino;      /* inode */
    	mode_t        st_mode;     /* protection */
    	nlink_t       st_nlink;    /* number of hard links */
    	uid_t         st_uid;      /* user ID of owner */
    	gid_t         st_gid;      /* group ID of owner */
    	dev_t         st_rdev;     /* device type (if inode device) */
    	off_t         st_size;     /* total size, in bytes */
    	unsigned long st_blksize;  /* blocksize for filesystem I/O */
    	unsigned long st_blocks;   /* number of blocks allocated */
    	time_t        st_atime;    /* time of last access */
    	time_t        st_mtime;    /* time of last modification */
    	time_t        st_ctime;    /* time of last change */
    };
    

    아래 POSIX 매크로는 파일 타입을 확인하는 것이다:
    S_ISLNK(m)  is it a symbolic link?
    S_ISREG(m)  regular file?
    S_ISDIR(m)  directory?
    S_ISCHR(m)  character device?
    S_ISBLK(m)  block device?
    S_ISFIFO(m) fifo?
    S_ISSOCK(m) socket?
    

    디렉토리 정보를 저장할 구조체 ( entry = readdir(dp) )
    #include 
    struct dirent
    {
    	long d_ino;                 /* inode number */
    	off_t d_off;                /* offset to this dirent */
    	unsigned short d_reclen;    /* length of this d_name */
    	char d_name[NAME_MAX+1];   /* file name (null-terminated) */
    }
    

    실수하기 쉬운 부분(주의사항)
    chdir() 함수를 이용하여 현재 작업 디렉토리를 유지해줘야 한다.
    그렇지 않으면 원하지 않은 결과(디렉토리를 파일로, 파일을 디렉토리로 인식)가 나올수도 있으니 유의하자.
    int remove_dir(std::string path)
    {
    	DIR* dp = NULL;
    	struct dirent* entry = NULL;
    	struct stat buf;
    	
    	if( ( dp = opendir(path.c_str())) == NULL  )
    	{
    		return -1;
    	}
    	
    	while( (entry = readdir(dp)) != NULL )
    	{
    		chdir(path.c_str());
    		lstat(entry->d_name, &buf);
    		
    		if( S_ISDIR(buf.st_mode) )
    		{
    			if( 0 == strcmp( entry->d_name , ".") || 0 == strcmp( entry->d_name, "..") )
    			continue;
    		
    			remove_dir(entry->d_name);
    		}
    		else if( S_ISREG(buf.st_mode) )
    		{
    			if(0 != remove(entry->d_name))
    			{
    				return -1;
    			}
    		}
    	}
    	
    	chdir("..");
    	
    	if(0 != remove(path.c_str()))
    	{
    		return -1;
    	}
    	
    	closedir(dp);
    	
    	return 0;
    }
    posted by 랜달프

    Iphlpapi.h  헤더 파일을 include 하고 컴파일 하면 에러가 난다.

    이 문제의 해결 방법은

    1. Microsoft SDK 설치한다.

    2. Visual Studio 의 Tools -> Options 의 Directory(도구->옵션->프로젝트 및 솔루션->VC++ 디렉터리 설정에서 Microsoft SDK 의 Lib 와 Include 폴더를 설정 해 준다.
    C:\Program Files\Microsoft Platform SDK\Lib
    C:\Program Files\Microsoft Platform SDK\Include

    3. Project -> Setting의 Link (프로젝트 -> 속성 -> 구성 속성 -> 링커 -> 입력 -> 추가 종속성) 에 Iphlpapi.lib 추가

    4. 컴파일



    Microsoft SDK 다운로드 :

    1. Windows SDK for Windows Server 2008 and .NET Framework 3.5


    2. Visual Studio 2008 SDK Version 1.0

    posted by 랜달프
    HWND   AllocateHWnd(HINSTANCE hInstance, WNDPROC WndMethod);
    void   DeallocateHWnd(HWND hWnd);
    
    HWND TDownloader :: AllocateHWnd(HINSTANCE hInstance, WNDPROC WndMethod)
    {
    	char sClassName[5];
    
    	sprintf(sClassName, "%d", GetTickCount());
    
    	HWND hWndResult;
    
    	WNDCLASS WndClass;
    
    	WndClass.cbClsExtra = 0;
    	WndClass.cbWndExtra = 0;
    	WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	WndClass.hInstance = hInstance;
    	WndClass.lpfnWndProc = WndMethod;
    	WndClass.lpszClassName = sClassName;
    	WndClass.lpszMenuName = NULL;
    	WndClass.style = CS_HREDRAW | CS_VREDRAW;
    	RegisterClass(&WndClass);
    
    
    	hWndResult = CreateWindowEx(
    					WS_EX_TOOLWINDOW,
    					sClassName,
    					"",
    					WS_POPUP,
    					0,
    					0,
    					0,
    					0,
    					0,
    					0,
    					hInstance,
    					NULL);
    
    
    	if (!hWndResult)
    	{
    		int ErrorCode = GetLastError();
    		ASSERT(0);
    	}
    
    	SetWindowLong(hWndResult, GWL_WNDPROC, (LONG)WndMethod);
    
    	return hWndResult;
    
    }
    
    void TDownloader :: DeallocateHWnd(HWND hWnd)
    {
    	DestroyWindow(hWnd);
    }
    
    
    
    출처 : http://cpueblo.com/programming/api/contents/177.html

    posted by 랜달프
    // WinMain
    #ifndef _DEBUG
    	ShowWindow(hWnd,SW_HIDE);
    #else
    	ShowWindow(hWnd,nCmdShow);
    #endif
    
    
    // WndProc
    #ifndef
    	_DEBUGMoveWindow(hWnd, 0, 0, 0, 0, FALSE);
    #endif
    
    posted by 랜달프

    //////////////////////////////////////////////////////////////////////////////////////////////////
    DLL 부분


    #include <windows.h>

    #pragma data_seg(".kbdata")
    HINSTANCE hModule=NULL;
    HHOOK hKeyHook=NULL;
    HWND g_hWnd=NULL;
    #pragma data_seg()
    #pragma comment (linker, "/SECTION:.kbdata,RWS")

    LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {

     if (nCode>=0)
     {

      SendMessage(g_hWnd,WM_USER+1,wParam,lParam);

     }

     if( wParam == VK_SNAPSHOT )
     {

      OpenClipboard(NULL);
      EmptyClipboard();
      CloseClipboard();

      MessageBoxA(0, "Print Screen 사용 금지", "경고", NULL);
      return true;

     }

     return CallNextHookEx(hKeyHook,nCode,wParam,lParam);

    }


    extern "C" __declspec(dllexport) void InstallHook(HWND hWnd)
    {

     g_hWnd=hWnd;
     hKeyHook=SetWindowsHookEx(WH_KEYBOARD,KeyHookProc,hModule,NULL);

    }

     

    extern "C" __declspec(dllexport) void UninstallHook()
    {

     UnhookWindowsHookEx(hKeyHook);

    }

     

    BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpRes)
    {

     switch (fdwReason)
     {

     case DLL_PROCESS_ATTACH:
        hModule=hInst;
        break;
     case DLL_PROCESS_DETACH:
        break;

     }

     return TRUE;

    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    코드 부분

    #include <MMSystem.h>

    extern "C" __declspec(dllexport) void InstallHook(HWND);
    extern "C" __declspec(dllexport) void UninstallHook();
    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

    ........

    LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
    {

     HDC hdc;
     PAINTSTRUCT ps;
     static int count;
     
     switch(iMessage)
     {

     case WM_CREATE:

      InstallHook(hWnd);
      return 0;

     case WM_USER+1:

      wsprintf(Mes2,"입력된 키:%d, lParam : %x ",wParam,lParam);
      InvalidateRect(hWnd,NULL,TRUE);
      return 0;

     case WM_PAINT:

      hdc=BeginPaint(hWnd, &ps);
      TextOut(hdc,10,10,Mes,lstrlen(Mes));
      TextOut(hdc,10,30,Mes2,lstrlen(Mes2));
      EndPaint(hWnd, &ps);
      return 0;

     
     case WM_DESTROY:

      UninstallHook();
      PostQuitMessage(0);
      return 0;

     }

     return(DefWindowProc(hWnd,iMessage,wParam,lParam));

    }

    posted by 랜달프


    프린트 스크린을 막아보자..
    프린트 스크린은 WM_KEYDOWN이나 다른 이벤트가 떨어지지 않는다..
    단지.. WM_KEYUP이벤트가 발생할 때 VK_SNAPSHOT키로 값이 넘어온다..
    프린트 스크린 키를 눌렀다면 이미 클립보드에 이미지가 들어간 것이다..
    그렇기 때문에 프린트 스크린이 눌리게 되면 키 이벤트를 잡아내고 그 시점에서 클립보드를 지워버리면 된다..

    BOOL CKET_TopFrameDlg::PreTranslateMessage(MSG* pMsg)
    {
     //이렇게는 안된다..왜냐면 이미 KEYDOWN에서 클립보드에 복사가 되었기때문에..
     //if (pMsg->message == WM_KEYUP && pMsg->wParam == VK_SNAPSHOT)
     // return TRUE;


     //  1.  프린트 스크린 키 이벤트를 잡아내고 그 시점에 클립보드를 지워버린다..
     //  print screen, ctrl+print screen은 막기..
     if (pMsg->message == WM_KEYUP && pMsg->wParam == VK_SNAPSHOT)
     {
         ::OpenClipboard(NULL);
         ::EmptyClipboard();
         ::CloseClipboard();
     }
     //  2.  alt+print+screen 막기..
     if (GetKeyState(VK_MENU)&& pMsg->wParam == VK_SNAPSHOT)
     {
         ::OpenClipboard(NULL);
         ::EmptyClipboard();
         ::CloseClipboard();
     }

     return CDialog::PreTranslateMessage(pMsg);
    }

    posted by 랜달프
    HANDLE hndl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    DWORD dwsma = GetLastError();
    DWORD dwExitCode = 0;
    PROCESSENTRY32 procEntry={0};
    procEntry.dwSize = sizeof( PROCESSENTRY32 );
    Process32First(hndl,&procEntry);
    do {
    if(NULL != strstr(strlwr(procEntry.szExeFile), strlwr("processName")))
    {
    HANDLE hHandle;
    hHandle = ::OpenProcess(PROCESS_ALL_ACCESS,0,procEntry.th32ProcessID);
    ::GetExitCodeProcess(hHandle,&dwExitCode);
    ::TerminateProcess(hHandle,dwExitCode);
    cout << "killed Process : " << procEntry.szExeFile << " " << procEntry.th32ProcessID << endl;
    break;
    }
    }while(Process32Next(hndl,&procEntry));
    posted by 랜달프
    prev 1 2 3 4 next