Rev 8785 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8542 | superturbo | 1 | /* Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv2 */ |
8430 | superturbo | 2 | |
8707 | turbocat | 3 | #include |
8073 | superturbo | 4 | #include |
8430 | superturbo | 5 | #include |
8073 | superturbo | 6 | #include |
7 | #include |
||
8373 | superturbo | 8 | #include |
9 | #include |
||
10 | #include |
||
8430 | superturbo | 11 | #include |
8466 | 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 |
||
8785 | turbocat | 18 | #define VERSION "%s - thashview 2.6.2" |
8466 | superturbo | 19 | #define EDIT_TEXT_SIZE 0x10000000 |
8707 | turbocat | 20 | #define DATA(type, addr, offset) *((type*)((uint8_t*)addr+offset)) |
8073 | superturbo | 21 | |
8707 | turbocat | 22 | ksys_colors_table_t sys_color_table; |
8073 | superturbo | 23 | |
8565 | superturbo | 24 | char hash_str_md5[MAX_HASH_LEN]= "Click the 'MD5:' button to show the md5-checksum!"; //Вывод MD5 |
25 | char hash_str_sha1[MAX_HASH_LEN]= "Click the 'SHA1:' button to show the sha1-checksum!"; //Вывод SHA1 |
||
8073 | superturbo | 26 | char hash_str_sha256[MAX_HASH_LEN]="Click the 'SHA256:' button to show the sha256-checksum!"; //Вывод SHA256 |
27 | char edit_box_buff[MAX_HASH_LEN]; // Буффер для ввода |
||
28 | char *filename; // Имя обрабатываемого файла |
||
29 | char *title; // Заголовок окна |
||
30 | |||
31 | enum MYCOLORS // Цвета |
||
32 | { |
||
8466 | superturbo | 33 | GREEN = 0x067D06 | EDIT_TEXT_SIZE, |
34 | RED = 0xFF0000 | EDIT_TEXT_SIZE, |
||
35 | BLACK = 0x000000 | EDIT_TEXT_SIZE, |
||
36 | WHITE = 0xFFFFFF, |
||
37 | GREY = 0x919191 |
||
8073 | superturbo | 38 | }; |
39 | |||
8466 | superturbo | 40 | edit_box hash_edit_box={WINDOW_W-140,10,121,WHITE,0,0,GREY,EDIT_TEXT_SIZE, MAX_HASH_LEN-1, edit_box_buff,NULL,ed_focus}; // Создаём структуру edit_box |
8073 | superturbo | 41 | int md5_flag=0, sha1_flag=0, sha256_flag=0; // Флаги показывающие была ли уже рассчитана котрольная сумма в функции check_sum() |
42 | |||
43 | enum BUTTONS // Кнопки в интрефейсе |
||
44 | { |
||
45 | BTN_QUIT=1, //Выход |
||
46 | BTN_MD5 = 10, //Рассчитать md5-контрольную сумму |
||
47 | BTN_SHA1 = 20, //Рассчитать sha1-контрольную сумму |
||
48 | BTN_SHA256 = 30, //Рассчитать sha256-контрольную сумму |
||
49 | BTN_COPY_MD5= 11, //Скопировать в буффер обмена |
||
50 | BTN_COPY_SHA1= 21, |
||
51 | BTN_COPY_SHA256=31, |
||
52 | BTN_CMP=40, //Сравнить edit_box и контрольную сумму |
||
53 | BTN_PASTE=50 //Вставить в edit_box(пока в разработке) |
||
54 | }; |
||
55 | |||
8373 | superturbo | 56 | void notify_show(char *text) |
57 | { |
||
8707 | turbocat | 58 | _ksys_exec("/sys/@notify", text); |
8373 | superturbo | 59 | } |
8073 | superturbo | 60 | |
61 | void* safe_malloc(size_t size) // Безопасный malloc. Показывает уведомление об ошибке и закрывает программу если память не была выделена |
||
62 | { |
||
63 | void *p=malloc(size); |
||
8565 | superturbo | 64 | if(p==NULL){ |
8073 | superturbo | 65 | notify_show("'Memory allocation error!' -E"); |
66 | exit(0); |
||
8565 | superturbo | 67 | }else{ |
8073 | superturbo | 68 | return p; |
69 | } |
||
70 | } |
||
71 | |||
72 | void global_var_init(unsigned int size) // Инициализируются глобальные массивы |
||
73 | { |
||
74 | filename=safe_malloc(size); |
||
75 | title=safe_malloc(size+20); |
||
76 | } |
||
77 | |||
78 | /* Функции генерации контрольных сумм */ |
||
79 | void md5_hash(FILE* input, BYTE* hash ) |
||
80 | { |
||
81 | int input_size; |
||
82 | BYTE *temp_buffer; |
||
83 | temp_buffer=safe_malloc(1024); |
||
84 | MD5_CTX ctx; |
||
85 | md5_init(&ctx); |
||
86 | while((input_size = fread(temp_buffer, 1, 1024, input)) > 0){ |
||
87 | md5_update(&ctx, temp_buffer, input_size); |
||
88 | } |
||
89 | md5_final(&ctx, hash); |
||
90 | free(temp_buffer); |
||
91 | } |
||
92 | |||
93 | void sha1_hash(FILE* input, BYTE* hash ) |
||
94 | { |
||
95 | int input_size; |
||
96 | BYTE *buffer; |
||
97 | buffer=safe_malloc(1024); |
||
98 | SHA1_CTX ctx; |
||
99 | sha1_init(&ctx); |
||
100 | while((input_size = fread(buffer, 1, 1024, input)) > 0){ |
||
101 | sha1_update(&ctx, buffer, input_size); |
||
102 | } |
||
103 | sha1_final(&ctx, hash); |
||
104 | free(buffer); |
||
105 | } |
||
106 | |||
107 | void sha256_hash(FILE* input, BYTE* hash ) |
||
108 | { |
||
109 | int input_size; |
||
110 | BYTE *buffer; |
||
111 | buffer=safe_malloc(1024); |
||
112 | SHA256_CTX ctx; |
||
113 | sha256_init(&ctx); |
||
114 | while((input_size = fread(buffer, 1, 1024, input)) > 0){ |
||
115 | sha256_update(&ctx, buffer, input_size); |
||
116 | } |
||
117 | sha256_final(&ctx, hash); |
||
118 | free(buffer); |
||
119 | } |
||
120 | |||
121 | |||
122 | BYTE* check_sum(int alg) // Генерируем контрольные суммы используя один из алгоритмов |
||
123 | { |
||
124 | FILE* input_file; |
||
125 | BYTE *hash; |
||
126 | input_file=fopen(filename,"rb"); |
||
127 | hash = safe_malloc(alg); |
||
128 | switch (alg) |
||
129 | { |
||
130 | case MD5_BLOCK_SIZE : |
||
131 | md5_hash(input_file, hash); |
||
132 | md5_flag=1; |
||
133 | break; |
||
134 | |||
135 | case SHA1_BLOCK_SIZE : |
||
136 | sha1_hash(input_file, hash); |
||
137 | sha1_flag=1; |
||
138 | break; |
||
139 | |||
140 | case SHA256_BLOCK_SIZE : |
||
141 | sha256_hash(input_file, hash); |
||
142 | sha256_flag=1; |
||
143 | break; |
||
144 | } |
||
145 | fclose(input_file); |
||
146 | return hash; |
||
147 | } |
||
148 | |||
149 | void sprint_hash(BYTE *hash, char* hash_str, int hash_size) //Преобрауем двоичные данные из hash в строку hash_str |
||
150 | { |
||
151 | char block[3]; |
||
152 | memset(hash_str, 0, MAX_HASH_LEN); // Очищаем строку для strcat |
||
153 | for(int i=0; i |
||
154 | { |
||
155 | sprintf(block,"%02x", hash[i]); |
||
156 | strcat(hash_str,block); |
||
157 | } |
||
158 | free(hash); |
||
159 | } |
||
160 | |||
161 | void redraw_window() //Рисуем окно |
||
162 | { |
||
163 | sprintf(title,VERSION, filename); // Устанавливаем заголовок окна |
||
8707 | turbocat | 164 | ksys_pos_t win_pos = _ksys_get_mouse_pos(KSYS_MOUSE_SCREEN_POS); // Получаем координаты курсора |
165 | _ksys_start_draw(); //Начинаем рисование интерфейса ) |
||
166 | _ksys_create_window(win_pos.x, win_pos.y, WINDOW_W, 150, title, sys_color_table.work_area, 0x14); // Создаём окно. |
||
8466 | superturbo | 167 | edit_box_draw(&hash_edit_box); // Рисуем edit_box |
8073 | superturbo | 168 | |
8707 | turbocat | 169 | _ksys_define_button(10, 30, 60, 20, BTN_MD5, GREEN); // Определяем кнопку md5 |
170 | _ksys_define_button(10, 60, 60, 20, BTN_SHA1, GREEN);// Определяем кнопку sha1 |
||
171 | _ksys_define_button(10, 90, 60, 20, BTN_SHA256, GREEN);// Определяем кнопку sha256 |
||
8073 | superturbo | 172 | |
8707 | turbocat | 173 | _ksys_draw_text("MD5:", 15, 34, 0, 0x90000000 | sys_color_table.work_button_text); // Пищем текст на кнопках |
174 | _ksys_draw_text("SHA1:", 15, 64, 0, 0x90000000 | sys_color_table.work_button_text); |
||
175 | _ksys_draw_text("SHA256:", 15,94, 0, 0x90000000 | sys_color_table.work_button_text); |
||
8073 | superturbo | 176 | |
8707 | turbocat | 177 | _ksys_draw_text(hash_str_md5, 80, 34, 0, 0x90000000 | sys_color_table.work_text); // Выводим контрольные суммы в окно |
178 | _ksys_draw_text(hash_str_sha1, 80, 64, 0, 0x90000000 | sys_color_table.work_text); |
||
179 | _ksys_draw_text(hash_str_sha256, 80, 94, 0, 0x90000000| sys_color_table.work_text); |
||
8073 | superturbo | 180 | |
8707 | turbocat | 181 | |
182 | _ksys_define_button(610, 30, 42, 20, BTN_COPY_MD5, sys_color_table.work_button); // Определяем кнопки для копирования |
||
8785 | turbocat | 183 | _ksys_define_button(610, 60, 42, 20, BTN_COPY_SHA1, sys_color_table.work_button); |
184 | _ksys_define_button(610, 90, 42, 20, BTN_COPY_SHA256, sys_color_table.work_button); |
||
8073 | superturbo | 185 | |
8707 | turbocat | 186 | _ksys_draw_text("Copy", 615, 34, 0, 0x90000000 | sys_color_table.work_button_text); // Пишем copy на всех кнопках для копирования |
187 | _ksys_draw_text("Copy", 615, 64, 0, 0x90000000 | sys_color_table.work_button_text); |
||
188 | _ksys_draw_text("Copy", 615, 94, 0, 0x90000000 | sys_color_table.work_button_text); |
||
8073 | superturbo | 189 | |
8707 | turbocat | 190 | _ksys_define_button(592, 120, 60, 20, BTN_CMP, GREEN); // Определяем кнопку для сравнения контольных сумм |
191 | _ksys_draw_text("Compare", 595, 124 , 0,0x90000000 | sys_color_table.work_button_text); // Пишем текс на кнопке. |
||
192 | _ksys_define_button(540, 120, 45, 20, BTN_PASTE, sys_color_table.work_button); //Кнопка для вставки (неработает) |
||
193 | _ksys_draw_text("Paste", 543, 124 , 0,0x90000000 | sys_color_table.work_button_text); // Текст paste на кнопке |
||
194 | _ksys_end_draw(); |
||
8073 | superturbo | 195 | } |
196 | |||
197 | void paste_to_edit_buffer() // Вставить из буффера обмена |
||
198 | { |
||
8250 | superturbo | 199 | char *temp_buff=NULL; |
8707 | turbocat | 200 | if(_ksys_clip_num()>0){ |
201 | temp_buff=_ksys_clip_get(_ksys_clip_num()-1); |
||
8250 | superturbo | 202 | memset(edit_box_buff,0,MAX_HASH_LEN); |
8707 | turbocat | 203 | if(DATA(int, temp_buff,0)>0 && DATA(int,temp_buff,4)==KSYS_CLIP_TEXT && DATA(int,temp_buff,8)==KSYS_CLIP_CP866){ |
8250 | superturbo | 204 | strncpy(edit_box_buff,temp_buff+12, MAX_HASH_LEN-1); |
8466 | superturbo | 205 | edit_box_set_text(&hash_edit_box,edit_box_buff); |
8250 | superturbo | 206 | notify_show("'Pasted from clipboard!' -I"); |
8466 | superturbo | 207 | hash_edit_box.text_color = BLACK; |
8707 | turbocat | 208 | free(temp_buff); |
8250 | superturbo | 209 | } |
8073 | superturbo | 210 | } |
211 | } |
||
212 | |||
8565 | superturbo | 213 | void copy_to_clipboard(char *text) // Копировать в буфер обмена |
8073 | superturbo | 214 | { |
8565 | superturbo | 215 | int text_hash_len = strlen(text)/2; |
216 | if(text_hash_len==MD5_BLOCK_SIZE || |
||
217 | text_hash_len==SHA1_BLOCK_SIZE || |
||
218 | text_hash_len==SHA256_BLOCK_SIZE) // Если текст является хэш-строкой |
||
8073 | superturbo | 219 | { |
8565 | superturbo | 220 | char *temp_buffer=safe_malloc(MAX_HASH_LEN+12); // Выделяем память для времнного буфера |
221 | memset(temp_buffer, 0, MAX_HASH_LEN); // Зануляем буфер |
||
8707 | turbocat | 222 | DATA(char,temp_buffer,4)=KSYS_CLIP_TEXT; // Устанавливаем TEXT для буфера(Смещение 4 байта) |
223 | DATA(char,temp_buffer,8)=KSYS_CLIP_CP866; // Устанавливаем кодировку CP866(Смещение 8 байт) |
||
8565 | superturbo | 224 | strncpy(temp_buffer+12, text, MAX_HASH_LEN-1); // Копируем данные из text во временный буфер(Смещение 12 байт) |
8707 | turbocat | 225 | _ksys_clip_set(strlen(text)+12, temp_buffer); // Выполняем системный вызов и перемещаем данные из временного буфера в буфер обмена |
8565 | superturbo | 226 | notify_show("'Copied to clipboard!' -I"); |
227 | free(temp_buffer); // Освобожаем временный буфер. |
||
8073 | superturbo | 228 | } |
229 | } |
||
230 | |||
231 | void print_pending_calc(char *str) // Выводим сообщение о том что контрольная суммма вычисляется. |
||
232 | { |
||
8565 | superturbo | 233 | strcpy(str, "Please wait! Calculating checksum..."); |
8073 | superturbo | 234 | redraw_window(); |
235 | } |
||
236 | |||
237 | bool calc_and_cmp(char *hash_str_universal,int alg) // Вычисляем контрольную сумму и сравниваем с edit_box_buff. |
||
238 | { |
||
239 | print_pending_calc(hash_str_universal); |
||
240 | sprint_hash(check_sum(alg),hash_str_universal, alg); |
||
241 | return !strcmp(edit_box_buff, hash_str_universal); |
||
242 | } |
||
243 | |||
244 | bool hash_compare() // Главная функция для сравнения |
||
245 | { |
||
246 | int alg=strlen(edit_box_buff)/2; |
||
8565 | superturbo | 247 | switch (alg){ // Если вычисления ещё небыло |
8073 | superturbo | 248 | case MD5_BLOCK_SIZE: |
8466 | superturbo | 249 | if(md5_flag){ |
8073 | superturbo | 250 | return !strcmp(edit_box_buff,hash_str_md5); |
8466 | superturbo | 251 | }else{ |
8073 | superturbo | 252 | return calc_and_cmp(hash_str_md5,alg); |
253 | } |
||
8565 | superturbo | 254 | break; |
8073 | superturbo | 255 | case SHA1_BLOCK_SIZE: |
8466 | superturbo | 256 | if(sha1_flag){ |
8073 | superturbo | 257 | return !strcmp(edit_box_buff,hash_str_sha1); |
8466 | superturbo | 258 | }else{ |
8073 | superturbo | 259 | return calc_and_cmp(hash_str_sha1,alg); |
260 | } |
||
8565 | superturbo | 261 | break; |
8073 | superturbo | 262 | case SHA256_BLOCK_SIZE: |
8466 | superturbo | 263 | if(sha256_flag){ |
8073 | superturbo | 264 | return !strcmp(edit_box_buff,hash_str_sha256); |
8466 | superturbo | 265 | }else{ |
8073 | superturbo | 266 | return calc_and_cmp(hash_str_sha256,alg); |
267 | } |
||
8565 | superturbo | 268 | break; |
8073 | superturbo | 269 | default: |
270 | return FALSE; |
||
8565 | superturbo | 271 | break; |
272 | } |
||
8073 | superturbo | 273 | } |
274 | |||
275 | int main(int argc, char** argv) |
||
276 | { |
||
8565 | superturbo | 277 | if(argc<2){ // Если аргументов нет, то запускаем диалог выбора фа |
8430 | superturbo | 278 | open_dialog* dialog = kolibri_new_open_dialog(OPEN,0, 0, 420, 320); |
279 | OpenDialog_init(dialog); |
||
280 | OpenDialog_start(dialog); |
||
8565 | superturbo | 281 | if(dialog->status==SUCCESS){ // Если файл выбран |
8430 | superturbo | 282 | global_var_init(strlen(dialog->openfile_path)); |
283 | strcpy(filename, dialog->openfile_path); |
||
8565 | superturbo | 284 | }else{ // Если файл не выбран |
8430 | superturbo | 285 | notify_show("'No file selected!' -E"); |
286 | exit(0); |
||
287 | } |
||
288 | free(dialog); |
||
8565 | superturbo | 289 | }else{ |
8430 | superturbo | 290 | global_var_init(strlen(argv[1])); |
291 | strcpy(filename, argv[1]); |
||
292 | } |
||
8073 | superturbo | 293 | |
8565 | superturbo | 294 | if(NULL==fopen(filename,"rb")){ // Если файла нет или не открывается |
8073 | superturbo | 295 | notify_show("'File not found!' -E"); |
296 | exit(0); |
||
297 | } |
||
8707 | turbocat | 298 | if(_ksys_screen_size().x |
8073 | superturbo | 299 | notify_show("'Low screen resolution! Program will not display correctrly!' -W"); |
300 | } |
||
301 | |||
8430 | superturbo | 302 | int gui_event; // Переменная для хранения события |
8073 | superturbo | 303 | uint32_t pressed_button = 0; // Код нажатой кнопки в окне |
304 | |||
8707 | turbocat | 305 | _ksys_get_system_colors(&sys_color_table); |
8466 | superturbo | 306 | hash_edit_box.shift_color=sys_color_table.work_button; |
307 | |||
8707 | turbocat | 308 | _ksys_set_event_mask(0xC0000027);// Устанавливаем маску событий |
8073 | superturbo | 309 | do // Цикл обработки событий |
310 | { |
||
8707 | turbocat | 311 | gui_event = _ksys_get_event(); // Получаем событие |
8565 | superturbo | 312 | switch(gui_event){ // Обрабатываем события |
8707 | turbocat | 313 | case KSYS_EVENT_NONE: |
8073 | superturbo | 314 | break; |
8707 | turbocat | 315 | case KSYS_EVENT_REDRAW: |
8565 | superturbo | 316 | redraw_window(); |
8073 | superturbo | 317 | break; |
8707 | turbocat | 318 | case KSYS_EVENT_MOUSE: |
8565 | superturbo | 319 | edit_box_mouse(&hash_edit_box); |
320 | break; |
||
8707 | turbocat | 321 | case KSYS_EVENT_KEY: |
8565 | superturbo | 322 | hash_edit_box.text_color = BLACK; |
9625 | turbocat | 323 | edit_box_key_safe(&hash_edit_box, _ksys_get_key()); |
8073 | superturbo | 324 | break; |
8707 | turbocat | 325 | case KSYS_EVENT_BUTTON: // Событие обработки кнопок |
326 | pressed_button = _ksys_get_button(); // Получение кода нажатой кнопки. |
||
8565 | superturbo | 327 | switch (pressed_button){ // Проверка какая кнопка была нажата |
328 | case BTN_MD5: |
||
329 | print_pending_calc(hash_str_md5); |
||
330 | sprint_hash(check_sum(MD5_BLOCK_SIZE),hash_str_md5, MD5_BLOCK_SIZE); |
||
331 | break; |
||
332 | case BTN_SHA1: |
||
333 | print_pending_calc(hash_str_sha1); |
||
334 | sprint_hash(check_sum(SHA1_BLOCK_SIZE),hash_str_sha1, SHA1_BLOCK_SIZE); |
||
335 | break; |
||
336 | case BTN_SHA256: |
||
337 | print_pending_calc(hash_str_sha256); |
||
338 | sprint_hash(check_sum(SHA256_BLOCK_SIZE),hash_str_sha256, SHA256_BLOCK_SIZE); |
||
339 | break; |
||
340 | case BTN_COPY_MD5: |
||
341 | copy_to_clipboard(hash_str_md5); |
||
342 | break; |
||
343 | case BTN_COPY_SHA1: |
||
344 | copy_to_clipboard(hash_str_sha1); |
||
345 | break; |
||
346 | case BTN_COPY_SHA256: |
||
347 | copy_to_clipboard(hash_str_sha256); |
||
348 | break; |
||
349 | case BTN_PASTE: |
||
350 | paste_to_edit_buffer(); |
||
351 | break; |
||
352 | case BTN_CMP: |
||
353 | if(hash_compare()){ |
||
354 | notify_show("'The checksum matches :)' -OK"); |
||
355 | hash_edit_box.text_color = GREEN; // Устанавливаем текст ввода зелёным если контрольная сумма совпадает |
||
356 | }else{ |
||
357 | notify_show("'The checksum does not match! :(' -W"); |
||
358 | hash_edit_box.text_color = RED; // Устанавливаем текст ввода красным если контрольная суммы не совпадает |
||
359 | } |
||
360 | break; |
||
361 | case BTN_QUIT: |
||
362 | exit(0); |
||
363 | break; |
||
8073 | superturbo | 364 | } |
365 | redraw_window(); |
||
8565 | superturbo | 366 | break; |
8073 | superturbo | 367 | } |
368 | }while(1); |
||
8785 | turbocat | 369 | return 0; |
8073 | superturbo | 370 | } |