Subversion Repositories Kolibri OS

Rev

Rev 8250 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8073 superturbo 1
/*Автор: Логаев Максим(turbocat2001) */
2
#include 
3
#include 
4
#include "kos32sys.h"
5
#include "notify.h"
6
#include 
7
#include 
8
#include "algorithms/md5.h"
9
#include "algorithms/sha1.h"
10
#include "algorithms/sha256.h"
11
 
12
#define TRUE 1;
13
#define FALSE 0;
14
#define MAX_HASH_LEN 65 // Максимальная длина строки
15
#define WINDOW_W 665
16
#define VERSION "%s - thashview 2.2"
17
 
18
typedef unsigned char bool;
19
struct kolibri_system_colors sys_color_table;
20
 
21
char hex[]={"abcdefABCDEF1234567890"}; //Для проверки вводимых символов
22
char hash_str_md5[MAX_HASH_LEN]=   "Click the 'MD5:' button to show the md5-checksum!      "; //Вывод MD5
23
char hash_str_sha1[MAX_HASH_LEN]=  "Click the 'SHA1:' button to show the sha1-checksum!    "; //Вывод SHA1
24
char hash_str_sha256[MAX_HASH_LEN]="Click the 'SHA256:' button to show the sha256-checksum!"; //Вывод SHA256
25
char edit_box_buff[MAX_HASH_LEN]; // Буффер для ввода
26
char *filename; // Имя обрабатываемого файла
27
char *title; // Заголовок окна
28
 
29
enum MYCOLORS // Цвета
30
{
31
    GREEN = 0x00067D06,
32
    RED   = 0x00FF0000,
33
    BLACK = 0x00000000,
34
    WHITE = 0xFFFFFFFF,
35
    GREY  = 0x00DDD7CF
36
};
37
 
38
 
39
unsigned int str_pos=0; // Позиция курсора при печати в строке ввода
40
int md5_flag=0, sha1_flag=0, sha256_flag=0; // Флаги показывающие была ли уже рассчитана котрольная сумма в функции check_sum()
41
int edit_box_text_color=BLACK; // Изначальный цвет текста в строке ввода
42
 
43
enum MYKEYS // Коды клавиш
44
{
45
    CTRL_V=22,
46
    BACKSPACE=8
47
};
48
 
49
enum BUTTONS // Кнопки в интрефейсе
50
{
51
    BTN_QUIT=1,        //Выход
52
    BTN_MD5 = 10,      //Рассчитать md5-контрольную сумму
53
    BTN_SHA1 = 20,     //Рассчитать sha1-контрольную сумму
54
    BTN_SHA256 = 30,   //Рассчитать sha256-контрольную сумму
55
    BTN_COPY_MD5= 11,  //Скопировать в буффер обмена
56
    BTN_COPY_SHA1= 21,
57
    BTN_COPY_SHA256=31,
58
    BTN_CMP=40,        //Сравнить edit_box и контрольную сумму
59
    BTN_PASTE=50       //Вставить в edit_box(пока в разработке)
60
};
61
 
62
 
63
 
64
void* safe_malloc(size_t size) // Безопасный malloc. Показывает уведомление об ошибке и закрывает программу если память не была выделена
65
{
66
    void *p=malloc(size);
67
    if(p==NULL)
68
    {
69
       notify_show("'Memory allocation error!' -E");
70
       exit(0);
71
    }
72
    else
73
    {
74
        return p;
75
    }
76
}
77
 
78
void global_var_init(unsigned int size)  // Инициализируются глобальные массивы
79
{
80
  filename=safe_malloc(size);
81
  title=safe_malloc(size+20);
82
}
83
 
84
/* Функции генерации контрольных сумм */
85
void md5_hash(FILE* input, BYTE* hash )
86
{
87
    int input_size;
88
    BYTE *temp_buffer;
89
    temp_buffer=safe_malloc(1024);
90
    MD5_CTX ctx;
91
    md5_init(&ctx);
92
    while((input_size = fread(temp_buffer, 1, 1024, input)) > 0){
93
                md5_update(&ctx, temp_buffer, input_size);
94
    }
95
    md5_final(&ctx, hash);
96
    free(temp_buffer);
97
}
98
 
99
void sha1_hash(FILE* input, BYTE* hash )
100
{
101
    int input_size;
102
    BYTE *buffer;
103
    buffer=safe_malloc(1024);
104
    SHA1_CTX ctx;
105
    sha1_init(&ctx);
106
    while((input_size = fread(buffer, 1, 1024, input)) > 0){
107
                sha1_update(&ctx, buffer, input_size);
108
    }
109
    sha1_final(&ctx, hash);
110
    free(buffer);
111
}
112
 
113
void sha256_hash(FILE* input, BYTE* hash )
114
{
115
    int input_size;
116
    BYTE *buffer;
117
    buffer=safe_malloc(1024);
118
    SHA256_CTX ctx;
119
    sha256_init(&ctx);
120
    while((input_size = fread(buffer, 1, 1024, input)) > 0){
121
                sha256_update(&ctx, buffer, input_size);
122
    }
123
    sha256_final(&ctx, hash);
124
    free(buffer);
125
}
126
 
127
 
128
BYTE* check_sum(int alg) // Генерируем контрольные суммы используя один из алгоритмов
129
{
130
    FILE* input_file;
131
    BYTE *hash;
132
    input_file=fopen(filename,"rb");
133
    hash = safe_malloc(alg);
134
    switch (alg)
135
    {
136
        case MD5_BLOCK_SIZE :
137
            md5_hash(input_file, hash);
138
            md5_flag=1;
139
        break;
140
 
141
        case SHA1_BLOCK_SIZE :
142
            sha1_hash(input_file, hash);
143
            sha1_flag=1;
144
        break;
145
 
146
        case SHA256_BLOCK_SIZE :
147
            sha256_hash(input_file, hash);
148
            sha256_flag=1;
149
        break;
150
    }
151
    fclose(input_file);
152
    return hash;
153
}
154
 
155
void sprint_hash(BYTE *hash, char* hash_str, int hash_size) //Преобрауем двоичные данные из hash в строку hash_str
156
{
157
    char block[3];
158
    memset(hash_str, 0, MAX_HASH_LEN); // Очищаем строку для strcat
159
    for(int i=0; i
160
    {
161
        sprintf(block,"%02x", hash[i]);
162
        strcat(hash_str,block);
163
    }
164
    free(hash);
165
}
166
 
167
void redraw_window() //Рисуем окно
168
{
169
    pos_t win_pos = get_mouse_pos(0); //Получаем позицию курсора мыши.
170
    sprintf(title,VERSION, filename); // Устанавливаем заголовок окна
171
    begin_draw(); //Начинаем рисование интерфейса )
172
    sys_create_window(win_pos.x, win_pos.y, WINDOW_W, 150, title, GREY, 0x14); // Создаём окно.
173
 
174
    draw_bar(10, 121, 525,20, WHITE); // Создаём прямоугольник для поля ввода
175
    draw_text_sys(edit_box_buff,15, 125, 0, 0x90000000| edit_box_text_color); // Выводим текст из буффера ввода
176
    draw_text_sys("|",10+(8*str_pos),125,0,0x90000000 | sys_color_table.work_text);
177
 
178
    define_button((10 << 16) + 60, (30 << 16) + 20, BTN_MD5, GREEN); // Определяем кнопку md5
179
    define_button((10 << 16) + 60, (60 << 16) + 20, BTN_SHA1, GREEN);// Определяем кнопку sha1
180
    define_button((10 << 16) + 60, (90 << 16) + 20, BTN_SHA256, GREEN);// Определяем кнопку sha256
181
 
182
    draw_text_sys("MD5:", 15, 34, 0,   0x90000000 | sys_color_table.work_button_text); // Пищем текст на кнопках
183
    draw_text_sys("SHA1:", 15, 64, 0,  0x90000000 | sys_color_table.work_button_text);
184
    draw_text_sys("SHA256:", 15,94, 0, 0x90000000 | sys_color_table.work_button_text);
185
 
186
    draw_text_sys(hash_str_md5, 80, 34, 0, 0x90000000 | sys_color_table.work_text); // Выводим контрольные суммы в окно
187
    draw_text_sys(hash_str_sha1, 80, 64, 0, 0x90000000 | sys_color_table.work_text);
188
    draw_text_sys(hash_str_sha256, 80, 94, 0, 0x90000000| sys_color_table.work_text);
189
 
190
    define_button((610 << 16) + 42, (30 << 16) + 20, BTN_COPY_MD5, sys_color_table.work_button); // Определяем кнопки для копирования
191
    define_button((610<< 16) + 42, (60 << 16) + 20, BTN_COPY_SHA1, sys_color_table.work_button);
192
    define_button((610<< 16) + 42, (90 << 16) + 20, BTN_COPY_SHA256, sys_color_table.work_button);
193
 
194
    draw_text_sys("Copy", 615, 34, 0,   0x90000000 | sys_color_table.work_button_text); // Пишем copy на всех кнопках для копирования
195
    draw_text_sys("Copy", 615, 64, 0,  0x90000000 | sys_color_table.work_button_text);
196
    draw_text_sys("Copy", 615, 94, 0, 0x90000000 | sys_color_table.work_button_text);
197
 
198
    define_button((592<< 16) + 60, (120 << 16) + 20, BTN_CMP, GREEN); // Определяем кнопку для сравнения контольных сумм
199
    draw_text_sys("Compare", 595, 124 , 0,0x90000000 | sys_color_table.work_button_text); // Пишем текс на кнопке.
200
 
201
    define_button((540 << 16) + 45, (120 << 16) + 20, BTN_PASTE, sys_color_table.work_button); //Кнопка для вставки (неработает)
202
    draw_text_sys("Paste", 543, 124 , 0,0x90000000 | sys_color_table.work_button_text); // Текст paste на кнопке
203
    end_draw();
204
}
205
 
206
 
207
void paste_to_edit_buffer()    // Вставить из буффера обмена
208
{
209
    char *temp_buff;
210
    temp_buff=kol_clip_get(kol_clip_num()-1);
211
    memset(edit_box_buff,0,MAX_HASH_LEN);
212
    if(((int)*(temp_buff)>0) && ((int)*(temp_buff+4)==0) && ((int)*(temp_buff+8)==1))
213
    {
214
        strncpy(edit_box_buff,temp_buff+12, MAX_HASH_LEN-1);
215
        str_pos=strlen(edit_box_buff);
216
        notify_show("'Pasted from clipboard!' -I");
217
        edit_box_text_color=BLACK;
218
    }
219
    user_free(temp_buff);
220
}
221
 
222
 
223
void copy_to_clipboard(char *text) // Копирлвать в буффер обмена
224
{
225
    if(55!=strlen(text))
226
    {
227
        char *temp_buffer=safe_malloc(MAX_HASH_LEN+12);
228
        memset(temp_buffer, 0, MAX_HASH_LEN);
229
        *(temp_buffer+4)=0;
230
        *(temp_buffer+8)=1;
231
        strncpy(temp_buffer+12, text, MAX_HASH_LEN-1);
232
        kol_clip_set(strlen(text)+12, temp_buffer);
233
        notify_show("'Copied to clipboard!' -I");
234
        free(temp_buffer);
235
    }
236
}
237
 
238
void print_pending_calc(char *str) // Выводим сообщение о том что контрольная суммма вычисляется.
239
{
240
  strcpy(str, "Please wait! Calculating checksum...                   ");
241
  redraw_window();
242
}
243
 
244
bool calc_and_cmp(char *hash_str_universal,int alg) // Вычисляем контрольную сумму и сравниваем с edit_box_buff.
245
{
246
   print_pending_calc(hash_str_universal);
247
   sprint_hash(check_sum(alg),hash_str_universal, alg);
248
   return !strcmp(edit_box_buff, hash_str_universal);
249
}
250
 
251
bool hash_compare() // Главная функция для сравнения
252
{
253
   int alg=strlen(edit_box_buff)/2;
254
 
255
        switch (alg) // Если вычисления ещё небыло
256
        {
257
        case MD5_BLOCK_SIZE:
258
            if(md5_flag)
259
            {
260
                return !strcmp(edit_box_buff,hash_str_md5);
261
            }
262
            else
263
            {
264
                return calc_and_cmp(hash_str_md5,alg);
265
            }
266
        break;
267
 
268
        case SHA1_BLOCK_SIZE:
269
            if(sha1_flag)
270
            {
271
                return !strcmp(edit_box_buff,hash_str_sha1);
272
            }
273
            else
274
            {
275
                return calc_and_cmp(hash_str_sha1,alg);
276
            }
277
        break;
278
 
279
        case SHA256_BLOCK_SIZE:
280
 
281
            if(sha256_flag)
282
            {
283
                return !strcmp(edit_box_buff,hash_str_sha256);
284
            }
285
            else
286
            {
287
                return calc_and_cmp(hash_str_sha256,alg);
288
            }
289
        break;
290
 
291
        default:
292
            return FALSE;
293
        break;
294
        }
295
}
296
 
297
void edit_box(oskey_t key)      //Функция реализующая строку ввода
298
{
299
    edit_box_text_color=BLACK;
300
 
301
    if(key.code==CTRL_V) // Если нажато Ctrl+V то вставить из буфера обмена
302
    {
303
        paste_to_edit_buffer();
304
    }
305
    if(key.code==BACKSPACE && str_pos>0) // Если backspace то удалить последний символ
306
    {
307
        str_pos--;
308
        edit_box_buff[str_pos]='\0';
309
 
310
    }
311
    else if(str_pos
312
    {
313
        if(strchr(hex,key.code)!=NULL)
314
        {
315
           edit_box_buff[str_pos]=key.code;
316
           str_pos++;
317
        }
318
    }
319
}
320
 
321
int main(int argc, char** argv)
322
{
323
    // получаем имя файла
324
    if(argc<2) // Если аргументов нет то сообщаем об этом
325
    {
326
        notify_show("'No file selected!' -E");
327
        exit(0);
328
    }
329
 
330
    global_var_init(strlen(argv[1]));
331
    strcpy(filename, argv[1]);
332
 
333
    if(NULL==fopen(filename,"rb")) // Если файла нет или не открывается
334
    {
335
        notify_show("'File not found!' -E");
336
        exit(0);
337
    }
338
 
339
    if(GetScreenSize()/65536
340
    {
341
        notify_show("'Low screen resolution! Program will not display correctrly!' -W");
342
    }
343
 
344
    int gui_event; // Перемная для хранения события
345
    uint32_t pressed_button = 0; // Код нажатой кнопки в окне
346
 
347
    get_system_colors(&sys_color_table);
348
    set_event_mask(0xC0000027); // Устанавливаем маску событий
349
    do // Цикл обработки событий
350
    {
351
        gui_event = get_os_event(); // Получаем событие
352
        switch(gui_event) // Обрабатываем события
353
        {
354
        case KOLIBRI_EVENT_NONE:
355
            break;
356
        case KOLIBRI_EVENT_REDRAW:
357
            redraw_window();
358
            break;
359
        case KOLIBRI_EVENT_KEY:
360
            edit_box(get_key()); // Получаем нажатую клавишу и задействуем строку ввода
361
            redraw_window();
362
            break;
363
        case KOLIBRI_EVENT_BUTTON: // Событие обработки кнопок
364
            pressed_button = get_os_button(); // Получение кода нажатой кнопки.
365
            switch (pressed_button) // Проверка какая кнопка была нажата
366
            {
367
                case BTN_MD5:
368
                    print_pending_calc(hash_str_md5);
369
                    sprint_hash(check_sum(MD5_BLOCK_SIZE),hash_str_md5, MD5_BLOCK_SIZE);
370
                    redraw_window();
371
                break;
372
 
373
                case BTN_SHA1:
374
                    print_pending_calc(hash_str_sha1);
375
                    sprint_hash(check_sum(SHA1_BLOCK_SIZE),hash_str_sha1, SHA1_BLOCK_SIZE);
376
                    redraw_window();
377
                break;
378
 
379
                case BTN_SHA256:
380
                    print_pending_calc(hash_str_sha256);
381
                    sprint_hash(check_sum(SHA256_BLOCK_SIZE),hash_str_sha256, SHA256_BLOCK_SIZE);
382
                    redraw_window();
383
                break;
384
 
385
                case BTN_COPY_MD5:
386
                    redraw_window();
387
                    copy_to_clipboard(hash_str_md5);
388
                break;
389
 
390
                case BTN_COPY_SHA1:
391
                    redraw_window();
392
                    copy_to_clipboard(hash_str_sha1);
393
                break;
394
 
395
                case BTN_COPY_SHA256:
396
                    redraw_window();
397
                    copy_to_clipboard(hash_str_sha256);
398
                break;
399
 
400
                case BTN_PASTE:
401
                    paste_to_edit_buffer();
402
                    redraw_window();
403
                break;
404
 
405
                case BTN_CMP:
406
                if(hash_compare())
407
                {
408
                    notify_show("'The checksum matches :)' -OK");
409
                    edit_box_text_color=GREEN; // Устанавливаем текст ввода зелёным если контрольная сумма совпадает
410
                }
411
                else
412
                {
413
                    notify_show("'The checksum does not match! :(' -W");
414
                    edit_box_text_color=RED; // Устанавливаем текст ввода красным если контрольная суммы не совпадает
415
                }
416
                redraw_window();
417
                break;
418
 
419
                case BTN_QUIT:
420
                    exit(0);
421
                break;
422
            }
423
        }
424
    }while(1);
425
}