/* ZLock by Levak 13/02/12 */ #include #include "libndls.h" #define MAXLEN 10 #define QUOTE_X(t)#t #define QUOTE(t)QUOTE_X(t) static char *title = "ZLock says"; static char *errorUninst = "ZLock Manager is not installed yet."; static char *successUninst = "ZLock successfuly deleted config file !"; static char *welcome1Msg = "Hi, welcome to ZLock !\nThis program lets you protect your TI-Nspire with a digit code password !\nPRESS ENTER TO CONTINUE\nLevak"; static char *welcome2Msg = "We are going to configure ZLock.\nLet's enter a password of maximum " QUOTE(MAXLEN) " characters.\nPRESS ENTER TO CONTINUE"; static char *welcome3Msg = "Congratulations !\nZLock is now set up, test it !\nTip : you can put ZLock in ndless/startup/ so that it will protect your TI-Nspire on startup !\n\nVisit http://tiplanet.org/ for more TI-Nspire programs !"; static char *welcomeCanceled = "Setup Canceled."; static char *confirmUninst = "Do you really want to uninstall ZLock ?"; static char *yes = "Yes"; static char *no = "No"; static char *wrongPass = "Wrong Password, try again.\nAttempts remaining : 0"; static char *floodAttempt = "Flood Attempt detected.\nWait 10 seconds to try again."; #define lock_width 12 #define lock_height 12 static unsigned char lock[lock_width][lock_height] = { {15,15,15,0,0,0,0,0,0,15,15,15}, {15,15,0,0,7,7,7,7,0,0,15,15}, {15,15,0,12,15,15,15,15,12,0,15,15}, {15,15,0,12,15,15,15,15,12,0,15,15}, {15,0,0,0,0,0,0,0,0,0,0,15}, {15,0,7,12,15,15,15,15,12,7,0,15}, {15,0,7,12,15,15,15,15,12,7,0,15}, {15,0,7,12,15,0,0,15,12,7,0,15}, {15,0,7,12,15,0,0,15,12,7,0,15}, {15,0,7,12,15,15,15,15,12,7,0,15}, {15,0,7,12,7,7,7,7,12,7,0,15}, {15,15,15,15,15,15,15,15,15,15,15,15} }; static unsigned short* p_timer = (unsigned short*) 0x90090000; static unsigned short last_timer = 0; static unsigned int* p_contrast = (unsigned int*) 0x900F0020; static unsigned int contrast; static unsigned int timeout = 5; /* in seconds */ /* From particles by ExtendeD, mdified */ inline void setPixel(int x, int y, int r, int g, int b) { if(lcd_isincolor()) { /* Inverted color for CX since it is ugly and sharpen */ unsigned short* p = (unsigned short*)(SCREEN_BASE_ADDRESS + (x << 1) + (y << 9) + (y << 7)); *p = ((255-r) >> 3) | (((255-g) >> 2) << 5) | (((255-b) >> 3) << 11); } else { unsigned char* p = (unsigned char*)(SCREEN_BASE_ADDRESS + ((x >> 1) + (y << 7) + (y << 5))); *p = (x & 1) ? ((*p & 0xF0) | r) : ((*p & 0x0F) | (r << 4)); } } void clrscr(void) { if(lcd_isincolor()) memset(SCREEN_BASE_ADDRESS, 0x00, SCREEN_BYTES_SIZE); else memset(SCREEN_BASE_ADDRESS, 0xFF, SCREEN_BYTES_SIZE); } /* End of particles */ void drawLock(void) { unsigned int i, j; for(i = 0; i < lock_width; i ++) for(j = 0; j < lock_height; j ++){ unsigned char v = lock[j][i] * 16; setPixel(i, j, v, v, v); } } void fillCircle(int x, int y, int r) { int i, j; for(i = -r; i < r; ++i) for(j = -r; j < r; ++j) { int v = i*i + j*j - r*r; if(v < 0 && v > -40 ) setPixel(x+i, y+j, 255, 255, 255); else if(v < 0) setPixel(x+i, y+j, 0, 0, 0); } } void fillRect(int x1, int y1, int x2, int y2) { int i, j; for(i = x1; i < x2; ++i) for(j = y1; j < y2; ++j) setPixel(i, j, 255, 255, 255); } void drawRect(int x1, int y1, int x2, int y2) { int i, j; int margin = 2; for(i = x1; i < x2; ++i) for(j = y1; j < y2; ++j) if(i < x1 + margin || i > x2 - margin || j < y1 + margin || j > y2 - margin) setPixel(i, j, 0, 0, 0); } /* Non-bloking fadeDown of the backlight */ BOOL fadeDown(void) { printf("%x fadeDown\n", *p_contrast); return (is_cx && --*p_contrast > 0x100) || (!is_cx && --*p_contrast > 0x6B); } /* Non-bloking fadeUp of the backlight */ BOOL fadeUp(void) { printf("%x fadeUp\n", *p_contrast); return (is_cx && ++*p_contrast < contrast) || (!is_cx && ++*p_contrast < contrast); } /* Blocking fadeOut of the backlight */ void fadeOut(int ms) { while(fadeDown()) sleep(ms); } /* Blocking fadeIn of the backlight */ void fadeIn(int ms) { while(fadeUp()) sleep(ms); } char request_char(void) { char key = 0; BOOL idle_mode = FALSE; last_timer = *p_timer; /* reset timer */ wait_no_key_pressed(); while (key == 0) { while(!any_key_pressed()) { /* if timer has expired, bright down the screen */ if(!idle_mode && *p_timer >= last_timer + timeout) { idle_mode = !fadeDown(); sleep(50); } else if(idle_mode) { sleep(500); } } idle_mode = FALSE; *p_contrast = contrast; /* Release contrast */ if(isKeyPressed(KEY_NSPIRE_0)) key = '0'; if(isKeyPressed(KEY_NSPIRE_1)) key = '1'; if(isKeyPressed(KEY_NSPIRE_2)) key = '2'; if(isKeyPressed(KEY_NSPIRE_3)) key = '3'; if(isKeyPressed(KEY_NSPIRE_4)) key = '4'; if(isKeyPressed(KEY_NSPIRE_5)) key = '5'; if(isKeyPressed(KEY_NSPIRE_6)) key = '6'; if(isKeyPressed(KEY_NSPIRE_7)) key = '7'; if(isKeyPressed(KEY_NSPIRE_8)) key = '8'; if(isKeyPressed(KEY_NSPIRE_9)) key = '9'; if(isKeyPressed(KEY_NSPIRE_A)) key = 'A'; if(isKeyPressed(KEY_NSPIRE_B)) key = 'B'; if(isKeyPressed(KEY_NSPIRE_C)) key = 'C'; if(isKeyPressed(KEY_NSPIRE_D)) key = 'D'; if(isKeyPressed(KEY_NSPIRE_E)) key = 'E'; if(isKeyPressed(KEY_NSPIRE_F)) key = 'F'; if(isKeyPressed(KEY_NSPIRE_G)) key = 'G'; if(isKeyPressed(KEY_NSPIRE_H)) key = 'H'; if(isKeyPressed(KEY_NSPIRE_I)) key = 'I'; if(isKeyPressed(KEY_NSPIRE_J)) key = 'J'; if(isKeyPressed(KEY_NSPIRE_K)) key = 'K'; if(isKeyPressed(KEY_NSPIRE_L)) key = 'L'; if(isKeyPressed(KEY_NSPIRE_M)) key = 'M'; if(isKeyPressed(KEY_NSPIRE_N)) key = 'N'; if(isKeyPressed(KEY_NSPIRE_O)) key = 'O'; if(isKeyPressed(KEY_NSPIRE_P)) key = 'P'; if(isKeyPressed(KEY_NSPIRE_Q)) key = 'Q'; if(isKeyPressed(KEY_NSPIRE_R)) key = 'R'; if(isKeyPressed(KEY_NSPIRE_S)) key = 'S'; if(isKeyPressed(KEY_NSPIRE_T)) key = 'T'; if(isKeyPressed(KEY_NSPIRE_U)) key = 'U'; if(isKeyPressed(KEY_NSPIRE_V)) key = 'V'; if(isKeyPressed(KEY_NSPIRE_W)) key = 'W'; if(isKeyPressed(KEY_NSPIRE_X)) key = 'X'; if(isKeyPressed(KEY_NSPIRE_Y)) key = 'Y'; if(isKeyPressed(KEY_NSPIRE_Z)) key = 'Z'; if(isKeyPressed(KEY_NSPIRE_ESC)) key = 1; if(isKeyPressed(KEY_NSPIRE_DEL)) key = 2; if(isKeyPressed(KEY_NSPIRE_ENTER)) key = 3; wait_no_key_pressed(); last_timer = *p_timer; /* reset timer */ } return key; } int request_pwd(char *password, int maxlen, BOOL init) { int len = 0; char key = 0; int i; int r = 10; int offset = 10; int size = (2*r + offset)/2; for(i = 0; i < maxlen; ++i) password[i] = 0; /* Main Loop */ while (len < maxlen && key != 3){ /* Enterkey */ if(init) drawRect(150 - maxlen*size + offset, 220-1.5*r, 150 + maxlen*size + offset, 220+1.5*r); fillRect(150 - maxlen*size + offset+2, 220-1.5*r+2, 150 + maxlen*size + offset-2, 220+1.5*r-2); drawLock(); for(i = 0; i < len; ++i) fillCircle(140 - (2*i - len)*size + offset/2, 220, r); key = request_char(); if (key >= '0' && key <= '9' || key >= 'A' && key <= 'Z') password[len++] = key; else if (key == 2 && len > 0) /* Backspace */ password[--len] = 0; else if (key == 1) /* Esc key */ return 1; } return 0; } void zlock(char* config_path) { /* Extra screen buffer */ char *sbuffer = malloc(SCREEN_BYTES_SIZE); memcpy(sbuffer, SCREEN_BASE_ADDRESS, SCREEN_BYTES_SIZE); char password[MAXLEN+1]; password[MAXLEN] = 0; contrast = *p_contrast; /* Save user contrast */ FILE *config; /* Contains password */ config = fopen (config_path, "r"); if (config != NULL) { char realpass[MAXLEN+1]; int i; for(i = 0; i < MAXLEN; ++i) realpass[i] = 0; fread(realpass, sizeof(char), MAXLEN, config); fclose(config); int attempts = 0; fadeOut(20); clrscr(); drawLock(); fadeIn(20); while((request_pwd(password, MAXLEN, FALSE) != 0 || strcmp(password, realpass)) && !(++attempts > 2)) { /* If password doesn't match or if attempt number exceds 3 */ wrongPass[strlen(wrongPass)-1] = '0' + (3 - attempts); sleep(2000); show_msgbox(title, wrongPass); clrscr(); drawLock(); } if(attempts < 3) { fadeOut(10); memcpy(SCREEN_BASE_ADDRESS, sbuffer, SCREEN_BYTES_SIZE); fadeIn(10); puts("ok"); } else { show_msgbox(title, floodAttempt); clrscr(); drawLock(); sleep(10000); zlock(config_path); } } else if(!nl_isstartup()) { /* Welcome, First use */ show_msgbox(title, welcome1Msg); /* Saving password */ show_msgbox(title, welcome2Msg); fadeOut(20); clrscr(); fadeIn(20); if(request_pwd(password, MAXLEN, TRUE) == 0) { fadeOut(20); memcpy(SCREEN_BASE_ADDRESS, sbuffer, SCREEN_BYTES_SIZE); fadeIn(20); config = fopen (config_path, "w"); fputs (password, config); fclose (config); show_msgbox(title, welcome3Msg); } else { /* Canceled setup */ fadeOut(20); memcpy(SCREEN_BASE_ADDRESS, sbuffer, SCREEN_BYTES_SIZE); fadeIn(20); show_msgbox(title, welcomeCanceled); } } /* Restore user defined contrast */ *p_contrast = contrast; free(sbuffer); } int main(int argc, char* argv[]) { if(argc < 1) return 0; char *config_path = "/documents/config.zlock"; int len = strlen(argv[0]); char path[len]; strcpy(path, argv[0]); char *p = strrchr(path, '/'); char self_name[len - ((p) ? p - path + 1: 0) + 1]; strcpy(self_name, (p) ? p + 1: path); if(strcmp(self_name, "uninstall.tns") == 0) { if (show_msgbox_2b(title, confirmUninst, yes, no) == 2) return 0; if(remove(config_path) == 0) show_msgbox(title, successUninst); else show_msgbox(title, errorUninst); return 0; } if (is_cx) lcd_incolor(); zlock(config_path); wait_no_key_pressed(); return 0; }