/* Copyright (C) 2019-2021 Logaev Maxim (turbocat2001), GPLv2 */ #include <sys/ksys.h> #include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> #include <cryptal/md5.h> #include <cryptal/sha1.h> #include <cryptal/sha256.h> #include <clayer/dialog.h> #include <clayer/boxlib.h> #define TRUE 1; #define FALSE 0; #define MAX_HASH_LEN 65 // Œ ªá¨¬ «ì ï ¤«¨ áâப¨ #define WINDOW_W 665 #define VERSION "%s - thashview 2.6.2" #define EDIT_TEXT_SIZE 0x10000000 #define DATA(type, addr, offset) *((type*)((uint8_t*)addr+offset)) ksys_colors_table_t sys_color_table; 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 = 0x067D06 | EDIT_TEXT_SIZE, RED = 0xFF0000 | EDIT_TEXT_SIZE, BLACK = 0x000000 | EDIT_TEXT_SIZE, WHITE = 0xFFFFFF, GREY = 0x919191 }; 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 int md5_flag=0, sha1_flag=0, sha256_flag=0; // ”« £¨ ¯®ª §ë¢ î騥 ¡ë« «¨ 㦥 à ááç¨â ª®â஫ì ï á㬬 ¢ äãªæ¨¨ check_sum() 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) { _ksys_exec("/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; i<hash_size; i++) { sprintf(block,"%02x", hash[i]); strcat(hash_str,block); } free(hash); } void redraw_window() //¨á㥬 ®ª® { sprintf(title,VERSION, filename); // “áâ ¢«¨¢ ¥¬ § £®«®¢®ª ®ª ksys_pos_t win_pos = _ksys_get_mouse_pos(KSYS_MOUSE_SCREEN_POS); // ®«ãç ¥¬ ª®®à¤¨ âë ªãàá®à _ksys_start_draw(); // ç¨ ¥¬ à¨á®¢ ¨¥ ¨â¥à䥩á ) _ksys_create_window(win_pos.x, win_pos.y, WINDOW_W, 150, title, sys_color_table.work_area, 0x14); // ‘®§¤ ñ¬ ®ª®. edit_box_draw(&hash_edit_box); // ¨á㥬 edit_box _ksys_define_button(10, 30, 60, 20, BTN_MD5, GREEN); // Ž¯à¥¤¥«ï¥¬ ª®¯ªã md5 _ksys_define_button(10, 60, 60, 20, BTN_SHA1, GREEN);// Ž¯à¥¤¥«ï¥¬ ª®¯ªã sha1 _ksys_define_button(10, 90, 60, 20, BTN_SHA256, GREEN);// Ž¯à¥¤¥«ï¥¬ ª®¯ªã sha256 _ksys_draw_text("MD5:", 15, 34, 0, 0x90000000 | sys_color_table.work_button_text); // ¨é¥¬ ⥪áâ ª®¯ª å _ksys_draw_text("SHA1:", 15, 64, 0, 0x90000000 | sys_color_table.work_button_text); _ksys_draw_text("SHA256:", 15,94, 0, 0x90000000 | sys_color_table.work_button_text); _ksys_draw_text(hash_str_md5, 80, 34, 0, 0x90000000 | sys_color_table.work_text); // ‚뢮¤¨¬ ª®â஫ìë¥ áã¬¬ë ¢ ®ª® _ksys_draw_text(hash_str_sha1, 80, 64, 0, 0x90000000 | sys_color_table.work_text); _ksys_draw_text(hash_str_sha256, 80, 94, 0, 0x90000000| sys_color_table.work_text); _ksys_define_button(610, 30, 42, 20, BTN_COPY_MD5, sys_color_table.work_button); // Ž¯à¥¤¥«ï¥¬ ª®¯ª¨ ¤«ï ª®¯¨à®¢ ¨ï _ksys_define_button(610, 60, 42, 20, BTN_COPY_SHA1, sys_color_table.work_button); _ksys_define_button(610, 90, 42, 20, BTN_COPY_SHA256, sys_color_table.work_button); _ksys_draw_text("Copy", 615, 34, 0, 0x90000000 | sys_color_table.work_button_text); // ¨è¥¬ copy ¢á¥å ª®¯ª å ¤«ï ª®¯¨à®¢ ¨ï _ksys_draw_text("Copy", 615, 64, 0, 0x90000000 | sys_color_table.work_button_text); _ksys_draw_text("Copy", 615, 94, 0, 0x90000000 | sys_color_table.work_button_text); _ksys_define_button(592, 120, 60, 20, BTN_CMP, GREEN); // Ž¯à¥¤¥«ï¥¬ ª®¯ªã ¤«ï áà ¢¥¨ï ª®â®«ìëå á㬬 _ksys_draw_text("Compare", 595, 124 , 0,0x90000000 | sys_color_table.work_button_text); // ¨è¥¬ â¥ªá ª®¯ª¥. _ksys_define_button(540, 120, 45, 20, BTN_PASTE, sys_color_table.work_button); //Š®¯ª ¤«ï ¢áâ ¢ª¨ (¥à ¡®â ¥â) _ksys_draw_text("Paste", 543, 124 , 0,0x90000000 | sys_color_table.work_button_text); // ’¥ªáâ paste ª®¯ª¥ _ksys_end_draw(); } void paste_to_edit_buffer() // ‚áâ ¢¨âì ¨§ ¡ãää¥à ®¡¬¥ { char *temp_buff=NULL; if(_ksys_clip_num()>0){ temp_buff=_ksys_clip_get(_ksys_clip_num()-1); memset(edit_box_buff,0,MAX_HASH_LEN); if(DATA(int, temp_buff,0)>0 && DATA(int,temp_buff,4)==KSYS_CLIP_TEXT && DATA(int,temp_buff,8)==KSYS_CLIP_CP866){ strncpy(edit_box_buff,temp_buff+12, MAX_HASH_LEN-1); edit_box_set_text(&hash_edit_box,edit_box_buff); notify_show("'Pasted from clipboard!' -I"); hash_edit_box.text_color = BLACK; free(temp_buff); } } } void copy_to_clipboard(char *text) // Š®¯¨à®¢ âì ¢ ¡ãä¥à ®¡¬¥ { int text_hash_len = strlen(text)/2; if(text_hash_len==MD5_BLOCK_SIZE || text_hash_len==SHA1_BLOCK_SIZE || text_hash_len==SHA256_BLOCK_SIZE) // …᫨ ⥪áâ ï¥âáï åíè-áâப®© { char *temp_buffer=safe_malloc(MAX_HASH_LEN+12); // ‚뤥«ï¥¬ ¯ ¬ïâì ¤«ï ¢à¥¬®£® ¡ãä¥à memset(temp_buffer, 0, MAX_HASH_LEN); // ‡ ã«ï¥¬ ¡ãä¥à DATA(char,temp_buffer,4)=KSYS_CLIP_TEXT; // “áâ ¢«¨¢ ¥¬ TEXT ¤«ï ¡ãä¥à (‘¬¥é¥¨¥ 4 ¡ ©â ) DATA(char,temp_buffer,8)=KSYS_CLIP_CP866; // “áâ ¢«¨¢ ¥¬ ª®¤¨à®¢ªã CP866(‘¬¥é¥¨¥ 8 ¡ ©â) strncpy(temp_buffer+12, text, MAX_HASH_LEN-1); // Š®¯¨à㥬 ¤ ë¥ ¨§ text ¢® ¢à¥¬¥ë© ¡ãä¥à(‘¬¥é¥¨¥ 12 ¡ ©â) _ksys_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; } } int main(int argc, char** argv) { kolibri_boxlib_init(); // ‡ £à㦠¥¬ boxlib if(argc<2){ // …᫨ à£ã¬¥â®¢ ¥â, â® § ¯ã᪠¥¬ ¤¨ «®£ ¢ë¡®à ä kolibri_dialog_init(); // § £à㦠¥¬ proc_lib(libdialog) open_dialog* dialog = kolibri_new_open_dialog(OPEN,0, 0, 420, 320); OpenDialog_init(dialog); OpenDialog_start(dialog); if(dialog->status==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(_ksys_screen_size().x<WINDOW_W){ notify_show("'Low screen resolution! Program will not display correctrly!' -W"); } int gui_event; // ¥à¥¬¥ ï ¤«ï åà ¥¨ï ᮡëâ¨ï uint32_t pressed_button = 0; // Š®¤ ¦ ⮩ ª®¯ª¨ ¢ ®ª¥ _ksys_get_system_colors(&sys_color_table); hash_edit_box.shift_color=sys_color_table.work_button; _ksys_set_event_mask(0xC0000027);// “áâ ¢«¨¢ ¥¬ ¬ áªã ᮡë⨩ do // –¨ª« ®¡à ¡®âª¨ ᮡë⨩ { gui_event = _ksys_get_event(); // ®«ãç ¥¬ ᮡë⨥ switch(gui_event){ // Ž¡à ¡ âë¢ ¥¬ ᮡëâ¨ï case KSYS_EVENT_NONE: break; case KSYS_EVENT_REDRAW: redraw_window(); break; case KSYS_EVENT_MOUSE: edit_box_mouse(&hash_edit_box); break; case KSYS_EVENT_KEY: hash_edit_box.text_color = BLACK; edit_box_key(&hash_edit_box, _ksys_get_key().val); break; case KSYS_EVENT_BUTTON: // ‘®¡ë⨥ ®¡à ¡®âª¨ ª®¯®ª pressed_button = _ksys_get_button(); // ®«ã票¥ ª®¤ ¦ ⮩ ª®¯ª¨. switch (pressed_button){ // ஢¥àª ª ª ï ª®¯ª ¡ë« ¦ â case BTN_MD5: print_pending_calc(hash_str_md5); sprint_hash(check_sum(MD5_BLOCK_SIZE),hash_str_md5, MD5_BLOCK_SIZE); break; case BTN_SHA1: print_pending_calc(hash_str_sha1); sprint_hash(check_sum(SHA1_BLOCK_SIZE),hash_str_sha1, SHA1_BLOCK_SIZE); break; case BTN_SHA256: print_pending_calc(hash_str_sha256); sprint_hash(check_sum(SHA256_BLOCK_SIZE),hash_str_sha256, SHA256_BLOCK_SIZE); break; case BTN_COPY_MD5: copy_to_clipboard(hash_str_md5); break; case BTN_COPY_SHA1: copy_to_clipboard(hash_str_sha1); break; case BTN_COPY_SHA256: copy_to_clipboard(hash_str_sha256); break; case BTN_PASTE: paste_to_edit_buffer(); break; case BTN_CMP: if(hash_compare()){ notify_show("'The checksum matches :)' -OK"); hash_edit_box.text_color = GREEN; // “áâ ¢«¨¢ ¥¬ ⥪áâ ¢¢®¤ §¥«ñë¬ ¥á«¨ ª®â஫ì ï á㬬 ᮢ¯ ¤ ¥â }else{ notify_show("'The checksum does not match! :(' -W"); hash_edit_box.text_color = RED; // “áâ ¢«¨¢ ¥¬ ⥪áâ ¢¢®¤ ªà áë¬ ¥á«¨ ª®â஫ì ï áã¬¬ë ¥ ᮢ¯ ¤ ¥â } break; case BTN_QUIT: exit(0); break; } redraw_window(); break; } }while(1); return 0; }