Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*Автор: Логаев Максим(turbocat2001) */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "kos32sys.h"
  5. #include "notify.h"
  6. #include <string.h>
  7. #include <stdarg.h>
  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<hash_size; 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<MAX_HASH_LEN-1) // Ограничение длины ввода
  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<WINDOW_W)
  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. }
  426.