Packet *genExecuteAck(Packet *execute_serv){ /*wrap into packet*/ Packet *execute_ack; execute_ack = (Packet *)malloc(sizeof(Packet)); //Packet with Register_Service type Data snprintf(execute_ack->sender_id, sizeof(execute_ack->sender_id), "%s", execute_serv->receiver_id); snprintf(execute_ack->receiver_id, sizeof(execute_ack->receiver_id), "%s", execute_serv->sender_id); snprintf(execute_ack->packet_type, sizeof(execute_ack->packet_type), "%s", "110"); //ack packet snprintf(execute_ack->Data.version_number, sizeof(execute_ack->Data.version_number), "%s", execute_serv->Data.version_number); snprintf(execute_ack->Data.program_name, sizeof(execute_ack->Data.program_name), "%s", execute_serv->Data.program_name); snprintf(execute_ack->Data.procedure_name, sizeof(execute_ack->Data.procedure_name), "%s", execute_serv->Data.procedure_name); execute_ack->Data.data_is_file_or_dir = execute_serv->Data.data_is_file_or_dir; execute_ack->Data.transaction_id = execute_serv->Data.transaction_id ; execute_ack->Data.end_flag = execute_serv->Data.end_flag; execute_ack->Data.seq = execute_serv->Data.seq + 1; /*checksum*/ snprintf(execute_ack->PacketChecksum, sizeof(execute_ack->PacketChecksum), "%d", chksum_crc32(((unsigned char*) execute_ack) , sizeof(*execute_ack))); return execute_ack; }
/*generate minigoogle reply, put result directory into reply packet*/ Packet_Seq *genMapReduceReply(OptionsStruct *result_options, char *client_ip, char *server_ip, char *trans_id){ Packet execReply; //execReply = (Packet *)malloc(sizeof(Packet)); snprintf(execReply.sender_id, sizeof(execReply.sender_id), "%s", server_ip); snprintf(execReply.receiver_id, sizeof(execReply.receiver_id), "%s", client_ip); snprintf(execReply.packet_type, sizeof(execReply.packet_type), "%s", "101"); // execute reply type snprintf(execReply.Data.program_name, sizeof(execReply.Data.program_name), "%s", result_options->option1); snprintf(execReply.Data.version_number, sizeof(execReply.Data.version_number), "%s", result_options->option2); snprintf(execReply.Data.procedure_name, sizeof(execReply.Data.procedure_name), "%s", result_options->option3); snprintf(execReply.Data.res_data.data_str, sizeof(execReply.Data.res_data.data_str), "%s", result_options->option4); srand(time(NULL)); execReply.Data.transaction_id = rand(); // share the same transaction_id in the seq /*store the transcation id, in case there are multiple secquence in the link*/ snprintf(trans_id, 32, "%d", execReply.Data.transaction_id); execReply.Data.end_flag = 1; // only one packet send execReply.Data.seq = 0; execReply.Data.respons_type = 2; // here is str (2) /*checksum*/ snprintf(execReply.PacketChecksum, sizeof(execReply.PacketChecksum), "%d", chksum_crc32((unsigned char*) &execReply, sizeof(execReply))); /*enqueue the packet*/ appendListSeq(executeResultSeq, execReply); return executeResultSeq; }
void conf_save_as_default() { log_info("CONF_SAVE", "Default settings saved"); /* Generate checksum */ config.checksum = chksum_crc32((unsigned char *) &config, sizeof(config) - sizeof(uint32_t)); /* Save to default file */ conf_save("/boot/default.cnf"); }
cpu_reset_cause_t __attribute__((weak)) cpu_read_reset_cause(void) { //printf("CAUSE %p, CRC %p\r\n", &cpu_reset_cause, &cpu_reset_cause_crc); //printf("CAUSE %u, CRC %u\r\n", cpu_reset_cause, cpu_reset_cause_crc); unsigned int cause = cpu_reset_cause; if (chksum_crc32((unsigned char *) &cause, sizeof(unsigned int)) == cpu_reset_cause_crc) { cpu_reset_cause = 0; return cause; } return CPU_RESET_NONE; }
void conf_restore() { /* Restore */ int ret = conf_load("/boot/default.cnf"); /* Check checksum */ if ((ret < 0) || (config.checksum != chksum_crc32((unsigned char *) &config, sizeof(config) - sizeof(uint32_t)))) { log_info("CONF_RUN_COMPILED", ""); /* Restore compile-time configuration */ memcpy((void *)&config, (void *) &config_compiled, sizeof(conf_t)); } else { log_info("CONF_RUN_STORED", ""); } }
static uint32_t stun_get_fingerprint(stun_hdr_t *pkt) { uint32_t crc; uint16_t mlen; unsigned char tdata[128]; ENTER; mlen = ntohs(pkt->mlen) + sizeof(stun_hdr_t); x_memset(tdata, 0, sizeof(tdata)); x_memcpy(tdata, pkt, mlen - 8); crc = chksum_crc32(tdata, mlen - 8); EXIT; return crc; }
static int conf_store_verify_checksum(char * fpbuf, unsigned int bufsize) { if (fpbuf == NULL) return -1; if (bufsize < sizeof(uint32_t)) return -1; uint32_t fpcrc_read, fpcrc_calc; memcpy(&fpcrc_read, &fpbuf[bufsize - sizeof(fpcrc_read)], sizeof(fpcrc_read)); fpcrc_calc = chksum_crc32((unsigned char *)fpbuf, bufsize - sizeof(fpcrc_calc)); if (fpcrc_read != fpcrc_calc) return -1; return 0; }
int conf_save(char * path) { int ret = -1; /* Open file */ FILE * fpfp = fopen(path, "w+"); if (fpfp == NULL) { log_error("CONF_SAVE", "Open fail %s", path); goto out; } /* Save magic */ ret = conf_store_write_magic(fpfp); if (ret < 0) { log_error("CONF_SAVE", "Magic write fail %s", path); goto out_close; } /* Generate config checksum */ config.checksum = chksum_crc32((unsigned char *) &config, sizeof(config) - sizeof(uint32_t)); /* Save config */ CONF_WRITE_FIELD(fpfp, config); /* Save checksum */ ret = conf_store_write_checksum(fpfp); if (ret < 0) { log_error("CONF_SAVE", "CRC write fail"); goto out_close; } ret = 0; out_close: fclose(fpfp); out: return ret; }
static int conf_store_write_checksum(FILE * fpfp) { /* Get current file position */ long int size = ftell(fpfp); if (size < 0) { log_error("CONF_SAVE", "Ftell error %ld", size); return -1; } /* Allocate buffer */ char * fpbuf = pvPortMalloc(size); if (fpbuf == NULL) { log_error("CONF_SAVE", "Malloc fail %ld", size); return -1; } /* Rewind file and read into buffer */ rewind(fpfp); if (fread(fpbuf, 1, size, fpfp) != (size_t) size) { log_error("CONF_SAVE", "Read fail %ld", size); vPortFree(fpbuf); return -1; } /* Calculate checksum */ uint32_t fpcrc = chksum_crc32((unsigned char *)fpbuf, size); /* Write to file */ if (fwrite(&fpcrc, 1, sizeof(fpcrc), fpfp) != sizeof(fpcrc)) { log_error("CONF_SAVE", "Write fail"); vPortFree(fpbuf); return -1; } vPortFree(fpbuf); return 0; }
int conf_load(char * path) { int ret = -1; int offset = 0; /* Open file */ FILE * fpfp = fopen(path, "r"); if (fpfp == NULL) goto out; log_info("CONF_LOAD", "Using %s", path); /* Read size */ struct stat st; if (stat(path, &st) != 0) { log_error("CONF_LOAD", "Failed to stat %s", path); goto out_close; } unsigned int size = st.st_size; char * fpbuf = pvPortMalloc(size); if (fpbuf == NULL) { log_error("CONF_LOAD", "Malloc fail %u", size); goto out_free; } if (fread(fpbuf, 1, size, fpfp) != size) { log_error("CONF_LOAD", "Read fail %u %s", size, path); goto out_free; } /* Verify magic */ ret = conf_store_verify_magic(fpbuf, &offset, size); if (ret < 0) { log_error("CONF_LOAD", "%s invalid", path); goto out_free; } /* Verify file checksum */ ret = conf_store_verify_checksum(fpbuf, size); if (ret < 0) { log_error("CONF_LOAD", "%s invalid crc", path); goto out_free; } /* Load config */ CONF_READ_FIELD(fpbuf, config, &offset); /* Verify config checksum */ if (config.checksum != chksum_crc32((unsigned char *) &config, sizeof(config) - sizeof(uint32_t))) { log_error("CONF_LOAD", "%s invalid conf crc", path); goto out_free; } /* Okay we got this far, config is good */ ret = 0; out_free: vPortFree(fpbuf); out_close: fclose(fpfp); out: return ret; }
HVNC VNCCreateServer(HVNC_INITIALIZE *lpVNCInit) { if (!bHVNCInit) return -1; HVNC hVNC=1; EnterCriticalSection(&csHVNC); { HVNC_HANDLE *lpHandle=NULL; DWORD dwHash=chksum_crc32((byte*)lpVNCInit->szDeskName,lstrlenA(lpVNCInit->szDeskName)); if (!lpHandles) lpHandle=lpHandles=(HVNC_HANDLE*)MemAlloc(sizeof(HVNC_HANDLE)); else { lpHandle=lpHandles; HVNC_HANDLE *lpPrev; while (lpHandle) { if (lpHandle->lpServer->Names.dwHash == dwHash) { LeaveCriticalSection(&csHVNC); return -1; } lpPrev=lpHandle; lpHandle=lpHandle->lpNext; } lpHandle=lpPrev->lpNext=(HVNC_HANDLE*)MemAlloc(sizeof(HVNC_HANDLE)); lpHandle->lpPrev=lpPrev; hVNC=lpPrev->hHandle+1; } PHVNC lpServer=lpHandle->lpServer=(PHVNC)VirtualAlloc(NULL,sizeof(HVNCS),MEM_COMMIT,PAGE_READWRITE); lpHandle->hHandle=hVNC; InitializeCriticalSection(&lpServer->ThreadsInfo.csThreads); InitializeCriticalSection(&lpServer->WndWatcherInfo.csWndsList); lpServer->EventsInfo.dwSleep=50; lstrcpyA(lpServer->DeskInfo.szDeskName,lpVNCInit->szDeskName); lpServer->DeskInfo.dwFlags=lpVNCInit->dwFlags; #ifdef _HVNC_WEBCAM if (!memcmp(lpVNCInit->szDeskName,"#webcam",sizeof("#webcam")-1)) { lpServer->DeskInfo.bWebCam=true; lpServer->DeskInfo.dwFlags|=HVNC_WEB_CAM; if (!InitWebCam(lpServer)) { LeaveCriticalSection(&csHVNC); VNCCloseHandle(lpHandle->hHandle); return -1; } } else #endif { HDESK hInputDesktop=OpenInputDesktop(0,FALSE,DESKTOP_READOBJECTS); if (hInputDesktop) { char szInputDesktopName[100]; GetUserObjectInformationA(hInputDesktop,UOI_NAME,szInputDesktopName,sizeof(szInputDesktopName),NULL); if (!lstrcmpiA(szInputDesktopName,lpVNCInit->szDeskName)) { lpServer->DeskInfo.bInputDesktop=true; lpServer->DeskInfo.dwFlags|=HVNC_INPUT_DESKTOP; } CloseDesktop(hInputDesktop); } if (lpServer->DeskInfo.dwFlags & HVNC_SCREEN_SIZE_DETERMINED) { if ((!lpVNCInit->bBitsPerPixel) || (!lpVNCInit->dwHeight) || (!lpVNCInit->dwWidth)) { LeaveCriticalSection(&csHVNC); VNCCloseHandle(lpHandle->hHandle); return -1; } SetScreenSize(lpServer,lpVNCInit->dwHeight,lpVNCInit->dwWidth,lpVNCInit->bBitsPerPixel); } } lpServer->Names.dwHash=dwHash; InitGlobalDataNames(lpServer); if (!InitGlobalData(lpServer)) { LeaveCriticalSection(&csHVNC); VNCCloseHandle(lpHandle->hHandle); return -1; } lpServer->lpClientGoneHook=lpVNCInit->lpClientGoneHook; lpServer->lpNewClientHook=lpVNCInit->lpNewClientHook; if (!(lpServer->DeskInfo.dwFlags & HVNC_NO_INJECTS)) { lstrcpyA(lpServer->lpGlobalVNCData->szDeskName,lpServer->DeskInfo.szDeskName); lpServer->lpGlobalVNCData->dwDeskFlags=lpVNCInit->dwFlags; WaitForSingleObject(hHandlesMutex,INFINITE); for (int i=0; i < HVNC_MAX_HANDLES; i++) { if (!lpHandlesMapping[i]) { lpHandlesMapping[i]=lpServer->Names.dwHash; break; } } ReleaseMutex(hHandlesMutex); } } LeaveCriticalSection(&csHVNC); return hVNC; }
void __attribute__((weak)) cpu_set_reset_cause(cpu_reset_cause_t cause) { cpu_reset_cause = cause; cpu_reset_cause_crc = chksum_crc32((unsigned char *) &cpu_reset_cause, sizeof(unsigned int)); //printf("CAUSE %p, CRC %p\r\n", &cpu_reset_cause, &cpu_reset_cause_crc); //printf("CAUSE %u, CRC %u\r\n", cpu_reset_cause, cpu_reset_cause_crc); }
/* Load mi4 firmware from a hidden disk partition */ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo, unsigned int buffer_size, bool disable_rebuild) { struct mi4header_t mi4header; struct ppmi_header_t ppmi_header; unsigned long sum; /* Read header to find out how long the mi4 file is. */ storage_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET, PPMI_SECTORS, &ppmi_header); /* The first four characters at 0x80000 (sector 1024) should be PPMI*/ if( memcmp(ppmi_header.magic, "PPMI", 4) ) return EFILE_NOT_FOUND; printf("BL mi4 size: %x", ppmi_header.length); /* Read mi4 header of the OF */ storage_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS + (ppmi_header.length/512), MI4_HEADER_SECTORS, &mi4header); /* We don't support encrypted mi4 files yet */ if( (mi4header.plaintext) != (mi4header.mi4size-MI4_HEADER_SIZE)) return EINVALID_FORMAT; /* MI4 file size */ printf("OF mi4 size: %x", mi4header.mi4size); if ((mi4header.mi4size-MI4_HEADER_SIZE) > buffer_size) return EFILE_TOO_BIG; /* CRC32 */ printf("CRC32: %x", mi4header.crc32); /* Rockbox model id */ printf("Model id: %.4s", mi4header.model); /* Read binary type (RBOS, RBBL) */ printf("Binary type: %.4s", mi4header.type); /* Load firmware */ storage_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS + (ppmi_header.length/512) + MI4_HEADER_SECTORS, (mi4header.mi4size-MI4_HEADER_SIZE)/512, buf); /* Check CRC32 to see if we have a valid file */ sum = chksum_crc32 (buf,mi4header.mi4size-MI4_HEADER_SIZE); printf("Calculated CRC32: %x", sum); if(sum != mi4header.crc32) return EBAD_CHKSUM; #ifdef SANSA_E200 if (disable_rebuild) { char block[512]; printf("Disabling database rebuild"); storage_read_sectors(pinfo->start + 0x3c08, 1, block); block[0xe1] = 0; storage_write_sectors(pinfo->start + 0x3c08, 1, block); } #else (void) disable_rebuild; #endif return mi4header.mi4size-MI4_HEADER_SIZE; }
/*----------------------------------------------------------------------------*/ void writeChecksum(uint8_t* buff, uint32_t current_offset) { uint32_t checksum = chksum_crc32(buff,current_offset); copyData(buff, current_offset, (uint8_t* )&checksum, int32_len); }
static void try_boot(void) { FILE * fp; /* Pointer to start of memory */ void * dst = (void *) 0x50000000; /* _Maximum_ size of image is 1MB */ int size = 0xC0000 - 1; /* Check for a boot config */ fp = fopen("/boot/boot.conf", "r"); if (!fp) goto out; printf("Found /boot/boot.conf\r\n"); char image[100], cs[20], boot_cnt[8]; /* Read image path */ fgets(image, 100, fp); image[strlen(image)-1] = '\0'; printf("Image %s\r\n", image); /* Read checksum */ fgets(cs, 20, fp); cs[strlen(cs)-1] = '\0'; unsigned int checksum; sscanf(cs, "%x", &checksum); printf("Checksum %#x\r\n", checksum); /* Read boot count */ fgets(boot_cnt, 8, fp); boot_cnt[strlen(boot_cnt)-1] = '\0'; unsigned int boot_count; sscanf(boot_cnt, "%u", &boot_count); printf("Boot count: %u\r\n", boot_count); fclose(fp); /* If boot count is > 0 */ if (boot_count > 0) { /* decrement boot_count by one and write back to file */ /* decrement boot_count by one and write back to file */ boot_count--; fp = fopen("/boot/boot.conf", "w"); fprintf(fp, "%s\n", image); fprintf(fp, "%s\n", cs); if (!fprintf(fp, "%u\n", boot_count)) { fclose(fp); goto out; } fclose(fp); } else { goto out; } if (lzo_is_lzop_image(image)) { printf("Image is LZO compressed - decompressing\r\n"); /* Decompress image into memory */ if((size = lzo_decompress_image(image, dst, size)) < 0) { printf("Failed to decompress image\r\n"); goto out; } } else { /* Open image */ fp = fopen(image, "r"); if (!fp) { printf("Failed to open file %s\r\n", image); goto out; } /* Read image size */ struct stat st; if (stat(image, &st) != 0) { printf("Failed to stat image file\r\n"); fclose(fp); goto out; } size = st.st_size; /* Copy image */ printf("Copying %u bytes to %p\r\n", size, dst); int r; if ((r = fread(dst, 1, size, fp)) != size) { printf("Failed to copy %u bytes\r\n", size); fclose(fp); goto out; } } /* Checking checksum */ unsigned int checksum_ram = chksum_crc32((unsigned char *) dst, size); printf("Checksum RAM: 0x%x, boot.conf: 0x%x\r\n", checksum_ram, checksum); if (checksum_ram != checksum) goto out; /* Jump to address */ printf("Jumping to addr %p\r\n", dst); void (*jump) (void) = (void *) dst; jump(); out: return; }
/*for server, generate execute reply*/ Packet_Seq *genExecuteReply(OptionsStruct *result_options, char *client_ip, char *server_ip, char *trans_id){ char result_file[32]; memset(result_file, 0, sizeof(result_file)); strcpy(result_file, "../"); strcat(result_file, EXECUTE_RESULT_FILE); /*generate result sequence*/ FILE *out_fp; char *line = NULL; size_t len = 0; ssize_t read; if ((out_fp = fopen(result_file,"r")) < 0){ char logmsg[128]; snprintf(logmsg, sizeof(logmsg), "readfile: Failed to open file: %s\n", result_file); logging(LOGFILE, logmsg); //return result_seq; return executeResultSeq; //return -1; } Packet execReply; //execReply = (Packet *)malloc(sizeof(Packet)); snprintf(execReply.sender_id, sizeof(execReply.sender_id), "%s", server_ip); snprintf(execReply.receiver_id, sizeof(execReply.receiver_id), "%s", client_ip); snprintf(execReply.packet_type, sizeof(execReply.packet_type), "%s", "101"); // execute reply type snprintf(execReply.Data.program_name, sizeof(execReply.Data.program_name), "%s", result_options->option1); snprintf(execReply.Data.version_number, sizeof(execReply.Data.version_number), "%s", result_options->option2); snprintf(execReply.Data.procedure_name, sizeof(execReply.Data.procedure_name), "%s", result_options->option3); srand(time(NULL)); execReply.Data.transaction_id = rand(); // share the same transaction_id in the seq /*store the transcation id, in case there are multiple secquence in the link*/ snprintf(trans_id, 32, "%d", execReply.Data.transaction_id); execReply.Data.end_flag = 0; // default is 0 execReply.Data.respons_type = 0; // default is int (0) int lineIndex = 0; int arrayIndex = 0; int nPerLine = 0; // the number of integers per line int pktSeq = 0; // start from 0 int isEOF = 0; //read the end of the file int start_n = 0; //prevent data_int over flow, control the convert size in str2IntArray int data_int_full = 0; //packet data_int is full, ready to enqueue char line_no_n[10240]; //the length per line while ((read = getline(&line, &len, out_fp)) != -1 || isEOF == 0) { snprintf(line_no_n, strlen(line), "%s", line); /*provide the chance to create packet if is end of file*/ if(read == -1){ execReply.Data.end_flag = 1; isEOF = 1; } /* add split integers into temp int array*/ nPerLine = str2IntArray(execReply.Data.res_data.data_int, INTMTU, arrayIndex, line_no_n, start_n); if(arrayIndex + nPerLine > INTMTU){ start_n = INTMTU - arrayIndex; // next start index for line arrayIndex = 0; // start from begining for data_int data_int_full = 1; if(out_fp){ fseek(out_fp, -read-1, SEEK_CUR); // seek backward 30 bytes from the current pos } } else if(arrayIndex + nPerLine == INTMTU){ if (nPerLine != 0) start_n = 0; // reset line start index arrayIndex = 0; // start from begining for data_int data_int_full = 1; } else{ if (nPerLine != 0){ arrayIndex = arrayIndex + nPerLine - start_n; start_n = 0; // reset line start index } data_int_full = 0; //reset full flag } /* create packet if: * a. is end of file, or * b. the execReply.Data.res_data.data_int is full */ if(isEOF == 1 || data_int_full == 1){ execReply.Data.seq = pktSeq ++; /*checksum*/ snprintf(execReply.PacketChecksum, sizeof(execReply.PacketChecksum), "%d", chksum_crc32((unsigned char*) &execReply, sizeof(execReply))); /*enqueue the packet*/ appendListSeq(executeResultSeq, execReply); //appendListSeq(result_seq, execReply); /*reset the index, for the next packet*/ arrayIndex = 0; } /*read the parameter 1 dimension length*/ if(lineIndex == 0){ execReply.Data.respons_dimension = nPerLine; execReply.Data.res_dimen1_len = execReply.Data.res_data.data_int[arrayIndex-2]; execReply.Data.res_dimen2_len = execReply.Data.res_data.data_int[arrayIndex-1]; } lineIndex++; } unlinkFile(result_file); //return 0; int fcerr; if(out_fp){ if( (fcerr = fclose(out_fp)) != 0 ){ char logmsg[128]; snprintf(logmsg, sizeof(logmsg), "closefile: Failed to close file: %s. Error <%d>.\n", result_file, fcerr); logging(LOGFILE, logmsg); } } return executeResultSeq; //return result_seq; }
u_int32_t ath_net80211_aow_chksum_crc32 (unsigned char *block, unsigned int length) { return chksum_crc32(block, length); }
void* main(void) { int i; int btn; int num_partitions; int crc32; char sector[512]; struct partinfo pinfo; system_init(); kernel_init(); lcd_init(); font_init(); button_init(); i2c_init(); backlight_hw_on(); lcd_set_foreground(LCD_WHITE); lcd_set_background(LCD_BLACK); lcd_clear_display(); btn = button_read_device(); verbose = true; lcd_setfont(FONT_SYSFIXED); printf("Rockbox e200R installer"); printf("Version: %s", rbversion); printf(MODEL_NAME); printf(""); i=storage_init(); filesystem_init(); num_partitions = disk_mount_all(); if (num_partitions<=0) { error(EDISK, num_partitions, true); } disk_partinfo(1, &pinfo); #if 0 /* not needed in release builds */ printf("--- Partition info ---"); printf("start: %x", pinfo.start); printf("size: %x", pinfo.size); printf("type: %x", pinfo.type); printf("reading: %x", (START_SECTOR_OF_ROM + ROMSECTOR_TO_HACK)*512); #endif storage_read_sectors(pinfo.start + START_SECTOR_OF_ROM + ROMSECTOR_TO_HACK, 1 , sector); crc32 = chksum_crc32 (sector, 512); #if 0 /* not needed in release builds */ printf("--- Hack Status ---"); printf("Sector checksum: %x", crc32); #endif if (crc32 == PATCHED_CRC32) { /* Bootloader already patched */ printf("Already unlocked"); printf("Proceed to Step 2"); } else if ((crc32 == KNOWN_CRC32) && !memcmp(§or[HACK_OFFSET], knownBytes, sizeof(knownBytes)/sizeof(*knownBytes))) { /* E200R bootloader detected - patch it */ memcpy(§or[HACK_OFFSET], changedBytes, sizeof(changedBytes)/sizeof(*changedBytes)); storage_write_sectors( pinfo.start + START_SECTOR_OF_ROM + ROMSECTOR_TO_HACK, 1 , sector); printf("Firmware unlocked"); printf("Proceed to Step 2"); } else if (is_e200(crc32)) { printf("Vanilla E200 detected!"); printf("Please install using"); printf("Sansapatcher"); } else { printf("Unknown bootloader"); printf("Rockbox installer cannot"); printf("continue"); } /* Turn button lights off */ GPIOG_OUTPUT_VAL &=~0x80; printf(""); if (button_hold()) printf("Release Hold and"); printf("Press any key to shutdown"); while(button_read_device() == BUTTON_NONE); power_off(); return NULL; }