Subversion Repositories Kolibri OS

Rev

Rev 8373 | Rev 8466 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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