/* Copyright (C) 2019-2020 Logaev Maxim (turbocat2001), GPLv3 */ #include #include #include #include #include #include #include #include #include #include #define TRUE 1; #define FALSE 0; #define MAX_HASH_LEN 65 // Максимальная длина строки #define WINDOW_W 665 #define VERSION "%s - thashview 2.5" struct kolibri_system_colors sys_color_table; char hex[]={"abcdefABCDEF1234567890"}; //Для проверки вводимых символов char hash_str_md5[MAX_HASH_LEN]= "Click the 'MD5:' button to show the md5-checksum! "; //Вывод MD5 char hash_str_sha1[MAX_HASH_LEN]= "Click the 'SHA1:' button to show the sha1-checksum! "; //Вывод SHA1 char hash_str_sha256[MAX_HASH_LEN]="Click the 'SHA256:' button to show the sha256-checksum!"; //Вывод SHA256 char edit_box_buff[MAX_HASH_LEN]; // Буффер для ввода char *filename; // Имя обрабатываемого файла char *title; // Заголовок окна enum MYCOLORS // Цвета { GREEN = 0x00067D06, RED = 0x00FF0000, BLACK = 0x00000000, WHITE = 0xFFFFFFFF, GREY = 0x00DDD7CF }; unsigned int str_pos=0; // Позиция курсора при печати в строке ввода int md5_flag=0, sha1_flag=0, sha256_flag=0; // Флаги показывающие была ли уже рассчитана котрольная сумма в функции check_sum() int edit_box_text_color=BLACK; // Изначальный цвет текста в строке ввода enum MYKEYS // Коды клавиш { CTRL_V=22, BACKSPACE=8 }; enum BUTTONS // Кнопки в интрефейсе { BTN_QUIT=1, //Выход BTN_MD5 = 10, //Рассчитать md5-контрольную сумму BTN_SHA1 = 20, //Рассчитать sha1-контрольную сумму BTN_SHA256 = 30, //Рассчитать sha256-контрольную сумму BTN_COPY_MD5= 11, //Скопировать в буффер обмена BTN_COPY_SHA1= 21, BTN_COPY_SHA256=31, BTN_CMP=40, //Сравнить edit_box и контрольную сумму BTN_PASTE=50 //Вставить в edit_box(пока в разработке) }; void notify_show(char *text) { start_app("/sys/@notify", text); } void* safe_malloc(size_t size) // Безопасный malloc. Показывает уведомление об ошибке и закрывает программу если память не была выделена { void *p=malloc(size); if(p==NULL) { notify_show("'Memory allocation error!' -E"); exit(0); } else { return p; } } void global_var_init(unsigned int size) // Инициализируются глобальные массивы { filename=safe_malloc(size); title=safe_malloc(size+20); } /* Функции генерации контрольных сумм */ void md5_hash(FILE* input, BYTE* hash ) { int input_size; BYTE *temp_buffer; temp_buffer=safe_malloc(1024); MD5_CTX ctx; md5_init(&ctx); while((input_size = fread(temp_buffer, 1, 1024, input)) > 0){ md5_update(&ctx, temp_buffer, input_size); } md5_final(&ctx, hash); free(temp_buffer); } void sha1_hash(FILE* input, BYTE* hash ) { int input_size; BYTE *buffer; buffer=safe_malloc(1024); SHA1_CTX ctx; sha1_init(&ctx); while((input_size = fread(buffer, 1, 1024, input)) > 0){ sha1_update(&ctx, buffer, input_size); } sha1_final(&ctx, hash); free(buffer); } void sha256_hash(FILE* input, BYTE* hash ) { int input_size; BYTE *buffer; buffer=safe_malloc(1024); SHA256_CTX ctx; sha256_init(&ctx); while((input_size = fread(buffer, 1, 1024, input)) > 0){ sha256_update(&ctx, buffer, input_size); } sha256_final(&ctx, hash); free(buffer); } BYTE* check_sum(int alg) // Генерируем контрольные суммы используя один из алгоритмов { FILE* input_file; BYTE *hash; input_file=fopen(filename,"rb"); hash = safe_malloc(alg); switch (alg) { case MD5_BLOCK_SIZE : md5_hash(input_file, hash); md5_flag=1; break; case SHA1_BLOCK_SIZE : sha1_hash(input_file, hash); sha1_flag=1; break; case SHA256_BLOCK_SIZE : sha256_hash(input_file, hash); sha256_flag=1; break; } fclose(input_file); return hash; } void sprint_hash(BYTE *hash, char* hash_str, int hash_size) //Преобрауем двоичные данные из hash в строку hash_str { char block[3]; memset(hash_str, 0, MAX_HASH_LEN); // Очищаем строку для strcat for(int i=0; i0) { temp_buff=kol_clip_get(kol_clip_num()-1); memset(edit_box_buff,0,MAX_HASH_LEN); if(DATA(int, temp_buff,0)>0 && DATA(int,temp_buff,4)==TEXT && DATA(int,temp_buff,8)==CP866) { strncpy(edit_box_buff,temp_buff+12, MAX_HASH_LEN-1); str_pos=strlen(edit_box_buff); notify_show("'Pasted from clipboard!' -I"); edit_box_text_color=BLACK; user_free(temp_buff); } } } void copy_to_clipboard(char *text) // Копирлвать в буффер обмена { if(55!=strlen(text)) { char *temp_buffer=safe_malloc(MAX_HASH_LEN+12); memset(temp_buffer, 0, MAX_HASH_LEN); DATA(char,temp_buffer,4)=TEXT; DATA(char,temp_buffer,8)=CP866; strncpy(temp_buffer+12, text, MAX_HASH_LEN-1); kol_clip_set(strlen(text)+12, temp_buffer); notify_show("'Copied to clipboard!' -I"); free(temp_buffer); } } void print_pending_calc(char *str) // Выводим сообщение о том что контрольная суммма вычисляется. { strcpy(str, "Please wait! Calculating checksum... "); redraw_window(); } bool calc_and_cmp(char *hash_str_universal,int alg) // Вычисляем контрольную сумму и сравниваем с edit_box_buff. { print_pending_calc(hash_str_universal); sprint_hash(check_sum(alg),hash_str_universal, alg); return !strcmp(edit_box_buff, hash_str_universal); } bool hash_compare() // Главная функция для сравнения { int alg=strlen(edit_box_buff)/2; switch (alg) // Если вычисления ещё небыло { case MD5_BLOCK_SIZE: if(md5_flag) { return !strcmp(edit_box_buff,hash_str_md5); } else { return calc_and_cmp(hash_str_md5,alg); } break; case SHA1_BLOCK_SIZE: if(sha1_flag) { return !strcmp(edit_box_buff,hash_str_sha1); } else { return calc_and_cmp(hash_str_sha1,alg); } break; case SHA256_BLOCK_SIZE: if(sha256_flag) { return !strcmp(edit_box_buff,hash_str_sha256); } else { return calc_and_cmp(hash_str_sha256,alg); } break; default: return FALSE; break; } } void edit_box(oskey_t key) //Функция реализующая строку ввода { edit_box_text_color=BLACK; if(key.code==CTRL_V) // Если нажато Ctrl+V то вставить из буфера обмена { paste_to_edit_buffer(); } if(key.code==BACKSPACE && str_pos>0) // Если backspace то удалить последний символ { str_pos--; edit_box_buff[str_pos]='\0'; } else if(str_posstatus==SUCCESS) // Если файл выбран { global_var_init(strlen(dialog->openfile_path)); strcpy(filename, dialog->openfile_path); } else // Если файл не выбран { notify_show("'No file selected!' -E"); exit(0); } free(dialog); } else { global_var_init(strlen(argv[1])); strcpy(filename, argv[1]); } if(NULL==fopen(filename,"rb")) // Если файла нет или не открывается { notify_show("'File not found!' -E"); exit(0); } if(GetScreenSize()/65536