요즘 바빠서 연습삼아서 간단한 코딩을 해봤다.


 이미 있는 파일 방식이라서 별 어려움도 없을 뿐더러. 딱히 제대로 사용이 될 것 같지만, 단일 파일의 길이를 알아봐야 되는 일이 있을 것이다.


 단일 파일의 길이를 알아야 되는 것은 파일을 읽었을때, 메모리 초과를 일어날 수 도 있고, 다양한 이유가 있을 것이다.


 파일의 길이를 알아 내는 것은 간단한 함수를 사용하면 된다.


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
31
32
33
#include <stdio.h>
#include <stdlib.h>
 
long getFileSize(FILE*);
 
int main()
{
    FILE *filePoint = NULL;
    long fileSize = 0;
 
    if((filePoint=fopen("./test.txt","r"))==NULL)
    {
        printf("Error : File Not Files");
        return -1;
    }
 
    fileSize = getFileSize(filePoint);
 
    printf("File Size : %d", fileSize);
 
    return 0;
}
 
long getFileSize(FILE *filePoint)
{
    long fileSize = 0;
    fseek(filePoint, 0L, SEEK_END);
    fileSize = ftell(filePoint);
    fclose(filePoint);
 
    return fileSize;
}
 
cs


 fileSize라는 것으로 파일의 길이를 얻을 수 있다.


 여기서 사용하는 함수는 2가지인데, 첫번째는 fseek이다.


 fseek라는 것은 파일을 읽는 포인터의 위치를 개발자가 자기 원하는 형태로 바꾸는 것이다.


 단일 파일의 길이를 알아내는 방법은 간단하게 파일의 끝으로 파일 포인트를 보낸 다음에, 그 위치를 읽으면 된다.


 그래서 단일 파일에서 파일 끝으로 보내는 방법으로


 fseek(filePoint, 0L, SEEK_END); 을 사용한다.


 이 후에 ftell을 사용한다.


 ftell은 파일 포인터 위치의 값을 반환해주는 함수이다.


 fseek(filePoint, 0L, SEEK_END);을 한 후에라면, 파일 포인터의 위치의 값이 파일의 끝을 되게 된다. 그래서 ftell은 파일의 끝이 출력되어 파일의 최대 크기가 받아 지게 된다.


 하지만, 이건 잘 쓰일 일이 없다.


 이유는 sys/stat.h을 사용하면, 이상없이 사용이 가능하기 때문이다.


 stat 구조체에서 파일의 크기를 가지고 있기 때문에, 굳이 단일 파일을 열어서 관리할 필요가 없다는 것이다.


 하지만, 단일 파일의 크기를 이용해서 쓰거나 읽어 들이는 용도로는 쓸만 한 것 같다.

Posted by JunkMam
,

C언어 키 눌음 처리.

연습 2016. 7. 11. 00:00

 키 눌음 처리 이벤트로 하는 방법과 kbhit() 함수를 사용하는 방법. GetAsyncKeyState()을 이용하는 방법이 있다.


 이벤트는 앞써 설명한 방법으로 WM_KEYDOWN과 WM_KEYUP등을 이용한 방법이다.


 kbhit()은 키보드에 입력을 받았는지 확인하는 방식으로 다음과 같이 사용이 가능하다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <conio.h>
 
int main()
{
    int key;
 
    if(kbhit() != 0)
    {
        key = getch();
    }
 
    return 0;
}
cs


 GetAsyncKeyState()는 윈도우스에서 키가 눌러졌는지 확인 하는 것으로, 위에 설명한 방식은 다중 키 입력을 받을 수 없다. 하지만, 이 함수를 사용한다면, 다중으로 다운을 받을 수 있게 된다.


 

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
#include <stdio.h>
#include <stdlib.h>
 
#include <windows.h>
 
int main(int argc, char** argv)
{
    while(1)
    {
        if(GetAsyncKeyState(VK_UP)!=0)
        {
            printf("Key Down : UP\n");
        }
        if(GetAsyncKeyState(0x41)!=0)
        {
            printf("Key Down : A\n");
        }
        if(GetAsyncKeyState(0x1B)!=0)
        {
            break;
        }
    }
    return 0;
}
 
cs


Posted by JunkMam
,

 포토샾이나 드림위버를 이용해서 작업을 하다가 TEMP파일에 임시 파일이 들어가는 걸 확인 했다.


 그런데, 포토샾이라는 표시를 위해서 'PhotoShop tmpxxxxx' 이런식으로 파일이 생성 되는걸 확인 했다.


 TEMP 파일을 생성하는걸 보니, 파일명을 따로 정의 내리는게 없어 보였다.


 TEMP 파일 생성의 함수를 사용하는게 아니라면, 파일을 새로 원하는 형태로 만들었다. 라는 판단에 시스템 변수의 값을 출력하는 방법을 찾아 보았다.


 원본


 찾아보니, 다음과 같은 블로그에서 설명이 되어 있었다.


 시스템 변수를 찾는 방법으로 #include <stdio.h>에 정의 되어져 있는 getenv()라는 함수를 사용하거나 환경변수 envp을 이용해서 변수를 찾는 방법을 사용했다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
//#include <stdlib.h>
 
 
int main(int argc, char* argv[], char* envp[]) {
  char *s;
 
  // 지정한 특정 환경변수만 출력
  s = getenv("PATH");
 
  if (s != NULL)
    printf("%s\n", s);
  else
    fputs("그런 환경 변수가 없습니다\n", stderr);
 
  // 모든 환경변수 출력 (envp 이용하여)
  for (int i = 0; envp[i] != NULL; i++)
    printf("%s\n", envp[i]);
 
  return 0;
}
 
cs


 이렇게 해서 환경변수를 출력할 수 있으며, getenv을 이용해서 원하는 변수를 받을 수 있으니, 이걸 이용해서 TEMP 파일을 생성 할 수도 있을 것 같다.


 하지만, C언어의 tmpfile을 이용하는게 더 나을 것 같다.

Posted by JunkMam
,

 최근에 LEA관련된 암호 방식이 있다는 걸 확인해서(필자는 DVD에 보관하길 원하는데, 혹시 모르는 안전을 위해서도 있고... 이것 저것 신기한 것 같아서) 연습삼아 만든걸 올린다.


 LEA는 최근 우리나라 KISA가 만든 경량화된 대칭키 암호 방식을 뜻한다.


 대칭키 암호는 단일 암호키를 가지고 암호/복호화를 하기 때문에 키를 알면 누구든지 암호/복호를 할 수 있는 단점을 가지고 있지만, 반대로 간단한 암호 방식으로 알고 있다.


 대표적인 암호로 AES가 있는데, LEA는 여기에 있는 AES의 속도 보다 1.5~2배 빠르다. 라고 나와있다.(실제로 나온 과 비교해보니 빠르다.)


 그래서 이걸 library을 다운받아서 적용시키는 작업을 해보았다.



 -소스-

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdio.h>
#include <stdlib.h>
 
#include "include/lea/config.h"
#include "include/lea/lea.h"
 
#define ENC {2323534323123050894203424518223}
 
unsigned char mk[16= ENC;
 
unsigned int mk_len = 16;
 
unsigned char ctr_enc[16= ENC;
 
unsigned char pyn_buffer[16];
//unsigned int pyn_buffer_len = 16;
 
unsigned char cyp_buffer[16];
//unsigned int cyp_buffer_len = 16;
 
int main()
{
    size_t M = 0;
 
    LEA_KEY key;
 
    FILE *fip = NULL;
    FILE *fop = NULL;
 
    fip = fopen64("test","rb");
    fop = fopen64("test.LEA_CTR","wb");
 
    lea_set_key(&key, mk, mk_len);
 
    while((M=fread(pyn_buffer, sizeof(char), sizeof(pyn_buffer), fip))!=NULL)
    {
        lea_ctr_enc(cyp_buffer, pyn_buffer, M, ctr_enc, &key);
        //lea_ctr_dec(cyp_buffer, pyn_buffer,M,ctr_enc,&key);
        if (fwrite(cyp_buffer, sizeof(char), M, fop) == 0)
        {
            fclose(fip);
            fclose(fop);
            _unlink(fop); // 에러난 파일 지우고 종료
            return -1;
        }
        //lea_ctr_enc(cyp_buffer, pyn_buffer, pyn_buffer_len, ctr_enc, &key);
        //fwrite(cyp_buffer, cyp_buffer_len, 1, fop);
 
    }
 
    fclose(fip);
    fclose(fop);
 
    return 0;
}
 
cs



 일단, 위에 소개한 앱과 다른 점은 모드가 다르다.


 위에 소개한 앱의 암호 방법은 ECB방식이다. 이 방식은 암호키와 평문을 사용하는데, 딱 1:1로 처리하기 때문에 암호문이 단조로워 질수도 있다는 점이다.


 실제로도 이미지(RAW)파일을 암호화 시키니깐, 색은 없지만, 형태는 보여져서 대략적인 그림을 알 수 있는 특징을 가졌다.

 이것은 반대로 말하면, 반복적인 평문일 경우엔 뚫리기 쉬워진다는 뜻이 된다.(암호문의 반복 패턴을 이용해서 암호키를 유추할 수 있으며, 이 유추된 키를 이용해서 다른 암호문들을 다 풀기 시작하면, 평문이 금방 나오게 된다는 점이다.)


 그래서 나는 CRT 방식이 라이브러리로 적용이 되어 줘서 이 방법을 사용하였다.


 이 방법은 CRT라는 암호키 외의 정보를 가지고 있어야되며, 이것과 다른 암호문을 만들때 변형 시켜서 사용하기 때문에 단조로운 형태를 취해지지 않는다는 특징을 가지게 된다.


 실제로도 RAW파일을 이용해서 만드니 이게 어떤 형태의 파일인지 정확하게 알기 어려웠다.


 다음은 RAW파일을 억지로 BMP파일로 바꾼것과 LEA_ECB로 암호화된 파일을 억지로 BMP으로 바꾼 것. LEA_CRT로 암호화된 파일을 억지로 BMP으로 바꾼 것이다.


 억지로 바꾸기 위해서 MSPAINT을 이용해서 24bit그림 파일로 바꾸었고(RAW파일의 대상은 내 휴대폰이다.) 수정할때 사용한 에디터는 HxD이다.


 

LEA_ECB 방식으로 암호화한 결과를 BMP으로 바꾼 것.


LEA_CRT로 암호화 한걸 BMP으로 바꾼 것.


원본



 RAW파일을 강제로 가지고와서 그려지게 했기 때문에 조금 깨지게 되어 있지만, LEA_ECB로 해서 만들어진 것과 비교한다면, 약간의 잔상이 원본과 유사한 부분이 있어 보임을 알 수 있다.


 파일을 암호화 하는 것 중에 하나는 랜섬웨어 같은 나쁜 용도로 사용되는게 아니라 원래는 내 파일을 혹은 내 문서/내 메세지를 원하지 않는 사람(해커)에게서 지키기 위해서 사용하는 방식이다.


 LEA방식과 AES 방식을 비교해보면, LEA 방식이 확실이 빠름을 느낄 수 있었다.

 이걸 이용해서 개인 파일을 해커에게 지키거나 하는 방법도 생각해보는 것도 좋을 것 같다.


 사실, 국가 보호법에서 사람의 휴대폰을 볼 수 있다. 이런 식의 이야기가 있기도 하고, 내 개인 적인 정보를 DVD에 기록하기 전에 한번이라도 적용 시킬 수 있는 내 개인적인 장치를 만들고 싶기도 했다.


 LEA는 최근에 내왔지만, 기사에선 LEA가 암호화에서 3~5위 안에 들어간 방식이라는 말을 들었기 때문에 빠르게 암호화를 원한다면, 한번 제작해보는 것도 좋을 것 같다.


 사실 라이브러리를 적용시킨 사례가 적은 것도 있는 것 같다.


 여기서 CRT는 사용자(개발자) 마음대로 적용 시켜도 되는데, 저렇게 고정 시켜서 적용 시켜도 되는지는 모르겠다.

 라이브러리 사용법은 적혀 있지만, 예제가 적은 점이...



 참고로 Block암호화 방식이기 때문에 늘어나는 것도 줄어 드는 것도 없다. A라는 용량의 파일을 암호화 하면, A라는 용량으로 1:1크기의 암호다.


 큰 용량일때, 압축이 가능하다. 라면, 압축시키고 암호화 시켜야된다.(아니면, 분할시켜서 보내던가...)

 그렇지 않고, 암호한 후에 압축하면 효율성이 거의 0%이다.

Posted by JunkMam
,

Win32 Text 출력.

연습 2015. 12. 1. 12:51
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif
 
#include <tchar.h>
#include <windows.h>
 
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");
char strTitle[]="Text";
 
int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
 
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);
 
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) WHITE_BRUSH;
    //wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
 
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           _T("Code::Blocks Template Windows App"),       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
 
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
 
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 00))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }
 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}
 
 
/*  This function is called by the Windows function DispatchMessage()  */
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    RECT rc;
    PAINTSTRUCT ps;
 
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        case WM_PAINT :
            hdc=BeginPaint(hwnd,&ps);
            TextOut(hdc,10,10,strTitle, 4);
            EndPaint(hwnd,&ps);
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
 
    return 0;
}
 
 
cs


 이 방법에서 수정 및 처리가 필요할 것이다.

 윗 방법을 처리하는 방법을 생각하여 만든다면, Wini32형 Hexa Code Editor을 만들 수 있지 않을까 생각이 든다.

Posted by JunkMam
,

 WindowProcedure의 함수는 GUI에서 작동되는 함수이다.


 기본적으로 While로 계속 작동 하도록 만들어 져있다.


 이것은 매세지를 받아서 처리하는 함수이다.



 이걸 연결하는 방법으로 Windows Class에 설정이 되게 된다.


    /* The Window structure */

    wincl.hInstance = hThisInstance;

    wincl.lpszClassName = szClassName;

    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */

    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */

    wincl.cbSize = sizeof (WNDCLASSEX);


    /* Use default icon and mouse-pointer */

    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);

    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);

    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);

    wincl.lpszMenuName = NULL;                 /* No menu */

    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */

    wincl.cbWndExtra = 0;                      /* structure or the window instance */

    /* Use Windows's default colour as the background of the window */

    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;


 이렇게 설정이 된다.


 여기서 wincl.lpfnWndProc에서 설정이 함수를 설정이 된다.

 이걸로, 기본적으로 WIndows의 GUI의 메세지를 받아서 처리할 수 있게 한다.


 메세지는 운영체제에서 큐 자료형에서 받아들이는 것으로 사용자가 행동을 취하는 것을 받아들이는 매개체라고 보면 된다.


 예을 들어서 사용자가 마우스를 움직이면, 움직였다는 메세지가 생성되고, 그것을 프로그램이 받아들여서 사용하는 것이다.


     /* Run the message loop. It will run until GetMessage() returns 0 */

    while (GetMessage (&messages, NULL, 0, 0))

    {

        /* Translate virtual-key messages into character messages */

        TranslateMessage(&messages);

        /* Send message to WindowProcedure */

        DispatchMessage(&messages);

    }


 이걸 이용해서 프로그램이 항상 메세지를 받아들이도록하고, 만약, 종료 메세지가 들어오게 되면, 꺼지게 되게 하는 것은 WindowProcedure에 설정하여 종료 및 기타 이벤트를 사용할 수 있게한다.


'연습' 카테고리의 다른 글

Android Youtube API 사용하기 - 0. 라이브러리에 추가하기 -  (0) 2015.12.02
Win32 Text 출력.  (0) 2015.12.01
Win32 API 기본  (0) 2015.11.29
GCC 전처리 출력.  (0) 2015.11.28
GCC에서의 Inline ASM  (0) 2015.11.27
Posted by JunkMam
,

Win32 API 기본

연습 2015. 11. 29. 00:00

 Win32는 Windows가 제작한 32Bit 환경에서 작동하는 GUI용 라이브러리이다.


 과거 Windows가 dos에 작동되는 버전인 1.0과 2.0쯤에는 WIn16(Windows 16Bit용)이 존재하고, 그 다음 Windows 32bit가 작성되기 시작했다고 한다.


 Win32 API에서 대부분 윈도우에서 GUI의 프로그램은 다 작성된다고 보면 된다.


 기본적으로 Win32 API의 대표적으로 내보내는 방법을 기록하고자 한다.


 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif
 
#include <tchar.h>
#include <windows.h>
 
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");
 
int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
 
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);
 
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
 
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           _T("Code::Blocks Template Windows App"),       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
 
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
 
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 00))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }
 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}
 
 
/*  This function is called by the Windows function DispatchMessage()  */
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
 
    return 0;
}
 
 
cs


 이렇게해서 간단한 GUI을 출력할 수 있다.

 윗 소스는 CodeBlocks을 이용한

'연습' 카테고리의 다른 글

Win32 Text 출력.  (0) 2015.12.01
Win32 API의 기본 구성 설명.  (0) 2015.11.30
GCC 전처리 출력.  (0) 2015.11.28
GCC에서의 Inline ASM  (0) 2015.11.27
Hello World를 어셈블리어로 변환한 결과.  (0) 2015.11.26
Posted by JunkMam
,

 간단한 프로그램 만드는 방법으로 파일 입출력으로 자기 자신을 복사하는 프로그램을 만들고자한다.


 그냥 공부용으로 자기 자신을 복사하는 프로그램을 만들려고 한 것이다.


 방법은 엄청 복잡하지 않다.

 그냥 파일 입출력으로 자기 자신을 복사하는 프로그램을 만들려고한다.

 우리가 쉽게 배우는 fopen이나, fread, fwrite등을 이용할 것이다.


 fopen은 자기 자신을 열게 만들고, 자기 클론이 될 파일을 생성하고, 그 파일을 복사하는 형태를 취하게 할 것이다.


 간단하게 말해서 파일 복사 방식을 사용할 것이다.


 소스는 다음과 같다.


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
31
32
#include <stdio.h>
#include <stdlib.h>
 
#include <string.h>
 
#include <windows.h>
 
int main(int argc, char** argv)
{
    FILE *me = NULL;
    FILE *clone = NULL;
 
    char names[255= {0,};
    char buffer[1024= {0,};
 
    int read = 0;
 
    strcpy(names,argv[0]);
    strcat(names,".exe");
 
    me = fopen(argv[0],"rb");
    clone = fopen(names,"wb");
 
    while(read = fread(buffer,sizeof(char),1024,me)){
        fwrite(buffer,sizeof(char),read,clone);
    }
 
    printf("Hello world!\n");
    return 0;
}
 
 
cs


 간단하게 구현되어 있는 방법으로, 여기서 알아야 될 것은 main의 매개 변수이다.


 main의 매개 변수는 argc와 argv인데,

 argc는 해당 파일에서 명령을 입력하는 총 갯수를 뜻하고, argv는 그 명령의 내용을 뜻한다.


 즉, 명령 프로토콜(CMD)에서 명령이 main의 매개변수가 된다.


 예을 들어서

 clone.exe -A Next


 이렇게 입력을 했다면,

 argc는 3이라는 값을 가지게 되고, argv는 각각 "clone.exe" "-A" "Next" 을 가지게 된다.


 argv[0]는 정확하게는 실행시키는 파일의 최대 경로를 가지게 되어 있는게 맞다.


 자기 자신을 복사하는 프로그램은 딱히 쓸 일은 없지만, 파일 입출력과 argv을 이용해서 자기 자신을 복사할 수 있음을 알려주기 위해서 작성한 글이다.

Posted by JunkMam
,

 이번에 사용하는건 간단한 키보드 입력 인식 및 처리 방법이다.

 Hexa Code Editor를 TUI 형태로 처리 하기 위해서 getch()을 이용했다.[각주:1]


 윗 방법은 conio.h로 콘솔 입출력에서 수정하는 방법이다.

 Windows.h에서는 또 다른 방법으로 처리하는 방법이 있다.


 이것의 예로는 GetKeyboardState 혹은 GetAsyncKeyState을 이용해서 처리한다.[각주:2]

 이 방법은 가상 키 처리이기 때문에, 콘솔 입출력이 아닌, Windows에서 제공하는 방법을 사용하면 된다.


 콘솔로 처리하고 싶어서, 일단, 콘솔 입출력으로 구현했다.


 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <stdlib.h>
 
#include <windows.h>
#include <conio.h>
 
int main()
{
    COORD coord;
 
    char keys = 0;
 
    int a = 1;
 
    short x=0,y=0;
 
    while(a){
        keys=getch();
        switch(keys){
        case 'a':
        case 'A':
            if(x>0) x=x-1;
            break;
        case 'd':
        case 'D' :
            if(x<10) x=x+1;
            break;
        case 's':
        case 'S':
            if(y<10) y=y+1;
            break;
        case 'w':
        case 'W':
            if(y>0) y=y-1;
            break;
        case 'c':
        case 'C':
            a=0;
            break;
        default:
            break;
        }
        coord.X=x;
        coord.Y=y;
 
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
 
        printf("W");
    }
 
    coord.X = 0;
    coord.Y = 11;
 
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
 
    printf("Hello world!\n");
 
    return 0;
}
 
 
cs


 다른 방법으로 앞서 설명한, 가상 키를 입력 받아서 처리하는 방법을 사용해도 된다.


 윗 방법에다가 Hexa Code Editor의 출력 부분을 설정하면, 완성하면, TUI형태의 편집기가 완성된다.

Posted by JunkMam
,

 Windows에서 사용되는 DOS 커서 설정하는 것은 꼭 Hexa Code Editor을 만들기 위해서 사용되는 방법이 아니다.


 단, 이걸 이용해서 DOS의 커서를 설정해야지만이 TUI을 제작할 수 있기 때문에 기록하는 것이다.


 DOS의 커서를 설정하는데 사용되는 함수는 setConsoleCursorPosition[각주:1]이라는 함수이다.


 이 함수를 이용하면, 만들어지고, 어셈블리어를 설정하면, 또다른 방법으로 TUI을 설정할 수 있다.(이것은 나중에 찾아봐야겠다.)


 예제)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
 
#include <windows.h>
 
int main()
{
    COORD coord;
 
    coord.X = 10;
    coord.Y = 20;
 
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
 
    printf("Hello world!\n");
    
    return 0;
}
 
 
cs


 여기서 COORD[각주:2]라는 구조체가 필요하게 된다.

 여기서 coord라는 녀석은 콘솔의 X, Y의 값을 저장하는 구조체가 있다.

 GetStdHandle()[각주:3]은 콘솔의 핸들러를 받아서 처리하는 것이다.

 STD_OUTPUT_HANDLE이라는 것은 기본적으로 설정되어 있는 핸들이다.


 여기 핸들의 정보는 각주를 참조하는게 좋을 것으로 생각한다.

Posted by JunkMam
,