// _ReadInfoTableEnd bool ResourceFile::_ReadInfoTableEnd(const void* data, int32 dataSize) { bool hasTableEnd = true; if ((uint32)dataSize < kResourceInfoSeparatorSize) throw Exception("Info table is too short."); if ((uint32)dataSize < kResourceInfoTableEndSize) hasTableEnd = false; if (hasTableEnd) { const resource_info_table_end* tableEnd = (const resource_info_table_end*) skip_bytes(data, dataSize - kResourceInfoTableEndSize); if (_GetInt32(tableEnd->rite_terminator) != 0) hasTableEnd = false; if (hasTableEnd) { dataSize -= kResourceInfoTableEndSize; // checksum uint32 checkSum = calculate_checksum(data, dataSize); uint32 fileCheckSum = _GetUInt32(tableEnd->rite_check_sum); if (checkSum != fileCheckSum) { throw Exception("Invalid resource info table check sum: In " "file: %lx, calculated: %lx.", fileCheckSum, checkSum); } } } if (!hasTableEnd) Warnings::AddCurrentWarning("resource info table has no check sum."); return hasTableEnd; }
DEC_errCode data_decode(uint8_t stream[]) { #if DEBUG > 1 printf("Entering data_decode\n"); #endif int i = 0; uint8_t checksum_1 = 0; uint8_t checksum_2 = 0; uint8_t length = stream[LENGTH_INDEX]; uint8_t sender = stream[SENDER_ID_INDEX]; //check first bit is 0x99 if(stream[STARTBYTE_INDEX] != 0x99) { //unknown package !!! return DEC_ERR_START_BYTE; } calculate_checksum(stream,&checksum_1,&checksum_2); //checksum1 is voorlaatste byte, checksum2 is last byte if(checksum_1 != stream[length-2] || checksum_2 != stream[length-1]) { return DEC_ERR_CHECKSUM; } return data_to_struct(sender, stream, length); }
int add_timestamp(uint8_t buffer[]){ #if DEBUG > 1 printf("Entering add_timestamp\n"); #endif int length_original=buffer[1],i,j; uint8_t checksum_1,checksum_2; int new_length=length_original+16; //timeval is 16 bytes struct timeval tv_8; //beaglebones timestamp is 8 byte, server timestamp is 16 byte :-( TimestampBeagle timestampBeagle; //get localtime gettimeofday(&tv_8, NULL); //convert beaglebone 8 byte timeval to 16 byte timeval for server, if this is server this does not change anything timestampBeagle.tv.tv_sec=(uint64_t)tv_8.tv_sec; timestampBeagle.tv.tv_usec=(uint64_t)tv_8.tv_usec; //update message length buffer[LENGTH_INDEX]=new_length; //add timestamp to buffer memcpy(&(buffer[length_original-2]),(void *)×tampBeagle.tv,sizeof(timestampBeagle.tv)); //overwrite previous checksums (-2) //recalculate checksum calculate_checksum(buffer,&checksum_1,&checksum_2); buffer[new_length-2]=checksum_1; buffer[new_length-1]=checksum_2; return new_length; }
inline void transmit(void) { // Power up radio. RADIO_POWER_PORT |= _BV(RADIO_POWER_PIN); DDRB |= _BV(TX_PIN); _delay_ms(0.1); manchester_union.manchester_packet.checksum = calculate_checksum(&manchester_union.manchester_packet); // Transmit preamble for (int i = 4; i > 0; i--) { transmit_byte(0xFF); } transmit_byte(0x7F); // Transmit data int len = sizeof(manchester_union); for (int i = 0; i < len; i++) { char b = manchester_union.manchester_data[i]; transmit_byte(b); } // Generate one final transition TX_PORT ^= (char)_BV(TX_PIN); _delay_ms(HALF_BIT_DELAY_TIME_MILLIS); // Then disable the transmitter RADIO_POWER_PORT &= ~_BV(RADIO_POWER_PIN); // And tri-state the TX pin DDRB &= (char)~_BV(TX_PIN); TX_PORT &= (char)~_BV(TX_PIN); }
void build_ustar_header_from_file(FILE_HEADER* header, char* filename) { struct stat buffer; errno = 0; if(stat(filename, &buffer) == 0 && errno == 0) { clean_up_header(header); get_prefix_and_name(filename, header->name, header->prefix); get_file_mode(header->mode, buffer.st_mode); get_id(header->uid, buffer.st_uid); get_id(header->gid, buffer.st_gid); get_size(header->size, buffer.st_size); get_modification_time(header->mtime, buffer.st_mtime); get_file_type(header->typeflag, buffer.st_mode); strcpy(header->magic, "ustar "); strcpy(header->version, " \0"); get_username(header->uname, buffer.st_uid); get_groupname(header->gname, buffer.st_gid); get_device_numbers(header->devmajor, header->devminor, buffer.st_dev); calculate_checksum(header); } else fprintf(stderr, "%s '%s': %s\n", STAT_FAILURE_ERR, filename, strerror(errno)); }
/** * Used to process a data frame that has just been uploaded. */ void block_uploaded(struct rx_frame* rx) { uint32_t mem_addr; uint32_t checksum, actual_checksum; if (rx->length >= MEMORY_RECORD_SIZE) { /* Copy the record from the radio packet. Skip the header and memory address */ memcpy(record, rx->data+5, MEMORY_RECORD_SIZE); /* Calculate the checksum */ actual_checksum = calculate_checksum(record); /* Read the checksum */ checksum = get_checksum(record); if (checksum == actual_checksum) { /* Extract the memory address */ mem_addr = get_memory_address_from_rx(rx); /* Acknowledge the frame */ send_upload_ack(rx->source_address, mem_addr, checksum); /* Write the record out to memory */ put_sample(record); console_puts("Radio Upload Frame OK\n"); } else { console_puts("Radio Upload Frame Checksum Error!\n"); console_printf("Frame: %04x\nCalc: %04x\n", checksum, actual_checksum); } } else { console_puts("Radio Upload Frame too short!\n"); } }
/* release all lower object references & free the file info structure */ static int wrapfs_file_release(struct inode *inode, struct file *file) { struct file *lower_file; #ifdef EXTRA_CREDIT int CHKSUM_SIZE =0; char *algo = kmalloc(sizeof(char)*10,GFP_KERNEL); int *algo_len = kmalloc(sizeof(int)*1,GFP_KERNEL); char *getchkbuf = kmalloc(sizeof(char)*32,GFP_KERNEL); #else char *getchkbuf = kmalloc(sizeof(char)*CHKSUM_SIZE,GFP_KERNEL); #endif char *has_integrity = kmalloc(sizeof(char)*1,GFP_KERNEL); int rc; lower_file = wrapfs_lower_file(file); if (lower_file) { if(lower_file->f_mode == O_RDONLY) goto out_release; else if(!S_ISDIR(lower_file->f_path.dentry->d_inode->i_mode)&& wrapfs_get_write_dirty(inode) == WRITE_DIRTY_BIT) { #ifdef EXTRA_CREDIT CHKSUM_SIZE = get_default_chksum_size(lower_file->f_path.dentry,algo,algo_len); #endif if(!has_integrity || !getchkbuf) { rc = -ENOMEM; goto out_release; } spin_lock(&inode->i_lock); wrapfs_set_write_dirty(inode,READ_DIRTY_BIT); spin_unlock(&inode->i_lock); if(vfs_getxattr(lower_file->f_path.dentry,XATTR_HAS_INTEGRITY,has_integrity,1)>0) { if(!memcmp(has_integrity,"1",1)) { calculate_checksum(lower_file,getchkbuf,CHKSUM_SIZE); rc = vfs_setxattr(lower_file->f_path.dentry,XATTR_INTEGRITY_VAL,getchkbuf,CHKSUM_SIZE,XATTR_CREATE); if(rc == -EEXIST) rc = vfs_setxattr(lower_file->f_path.dentry,XATTR_INTEGRITY_VAL,getchkbuf,CHKSUM_SIZE,XATTR_REPLACE); } } } out_release: wrapfs_set_lower_file(file, NULL); fput(lower_file); } kfree(WRAPFS_F(file)); kfree(getchkbuf); kfree(has_integrity); #ifdef EXTRA_CREDIT kfree(algo); kfree(algo_len); #endif return 0; }
/** * \param procedure procedure ID * \param data unpacked message data * \param len data length * * Creates SysEx message then sends it. This function uses folowing global variables: device_id, family_id and product_id. **/ void send_message(gint procedure, gchar *data, gint len) { GString *msg = g_string_new_len("\xF0" /* SysEx status byte */ "\x00\x00\x10", /* Manufacturer ID */ 4); g_string_append_printf(msg, "%c%c%c" /* device, family, product ID */ "%c", /* procedure */ device_id, family_id, product_id, procedure); if (len > 0) { GString *tmp = pack_data(data, len); g_string_append_len(msg, tmp->str, tmp->len); g_string_free(tmp, TRUE); } g_string_append_printf(msg, "%c\xF7", calculate_checksum(&msg->str[1], msg->len - 1)); debug_msg(DEBUG_VERBOSE, "Sending %s len %d", get_message_name(procedure), len); send_data(msg->str, msg->len); g_string_free(msg, TRUE); }
bool ProviderWithChecksum::saveDocument(const UString &path, UString contents) { if (inner->saveDocument(path, contents)) { this->contents[path.str()] = calculate_checksum(contents.str()).str(); return true; } return false; }
///////////////////////////// Message receiving ///////////////////////////// Message * receive_message() { radio.read(rx_buffer, MESSAGE_LENGTH); Message *m = (Message *) rx_buffer; if (calculate_checksum(m) != (get_checksum(m))) { Serial.println("WARNING: Checksum differs from expected value."); m->message_id = ERROR; } return m; }
int config_write(void){ uint8_t sum, xor; config.checksum = config.checkxor = 0; calculate_checksum(config, &sum, &xor); config.checksum = sum; config.checkxor = xor; sc_user_eeprom_write_block(0, (u08*)&config, sizeof(config)); return 0; }
static void write_header (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr) { /* Update the checksum */ hdr->checksum = calculate_checksum (hdr); /* Write the header back into the a.out file */ lseek (file, 0, 0); if (write (file, hdr, sizeof (*hdr)) != sizeof (*hdr)) { perror ("Couldn't write header to a.out file"); exit (1); } lseek (file, hdr->aux_header_location, 0); if (write (file, auxhdr, sizeof (*auxhdr)) != sizeof (*auxhdr)) { perror ("Couldn't write auxiliary header to a.out file"); exit (1); } }
int process_block(FILE *fp, int block_size) { int kBlock = block_size; char c[kBlock]; int checksum = -1; int i; for (i = 0; i < block_size && !feof(fp); i++) { c[i] = fgetc(fp); } if (i == block_size) { checksum = calculate_checksum(c, block_size); } return checksum; }
int opendcp_request_encoded_file(opendcp_t *opendcp, char *file) { int connection; char md5[40]; char *checksum; message_t message; connection = create_connection(opendcp->remote.host, opendcp->remote.port); if (connection < 0 ) { return OPENDCP_ERROR; } /* send file request */ snprintf(message.header, sizeof(message.header), ":action=%s:file=%s:length=0", "encoded_file_request", file); message.data = NULL; message.data_length = 0; send_message(connection, &message); /* receive file */ receive_message(connection, &message); get_parameter(message.header, strlen(message.header), "md5", md5, sizeof(md5)); if (write_file("foo.tif", message.data, message.data_length)) { printf("File write error"); free(message.data); return 1; } if (message.data) { free(message.data); } close(connection); //checksum = malloc(sizeof(MD5_DIGEST_LENGTH*2) + 1); checksum = calculate_checksum("foo.tif"); if (strcmp(checksum, md5)) { printf("checksum mismatch\n"); free(checksum); return 1; } free(checksum); return 0; }
void config_read(void){ uint8_t sum, xor; uint8_t insum, inxor; sc_user_eeprom_read_block(0, (uint8_t*)&config, sizeof(config)); insum = config.checksum; inxor = config.checkxor; config.checksum = config.checkxor = 0; calculate_checksum(config, &sum, &xor); if( (insum != sum) || (inxor != xor) ){ mpptng_fatal_error(UNSWMPPTNG_ERROR_EEPROM); } }
int strip_timestamp(uint8_t buffer[]){ #if DEBUG > 1 printf("Entering strip_timestamp\n"); #endif int length=buffer[LENGTH_INDEX],i,j; uint8_t checksum_1,checksum_2; int new_length=length-16; //timeval is 16 bytes //update message length buffer[LENGTH_INDEX]=new_length; //recalculate checksum calculate_checksum(buffer,&checksum_1,&checksum_2); buffer[new_length-2]=checksum_1; buffer[new_length-1]=checksum_2; return new_length; }
// Process any messages waiting to be transmitted int transmit_messages() { while (!message_queue.empty()) { char *packet_string = message_queue.front(); packet_string[PACKETSTRINGCHECKSUM] = calculate_checksum(packet_string); write_comm(packet_string); if (debug_toggle) { output_string << "[DEBUG MESSAGE] Transmitted Packet - " << packet_string << "\n"; write_to_output(output_string.str()); output_string.str(std::string()); } delete packet_string; message_queue.pop(); } return 0; }
void main() { int i=0; char mymac[6]={0x74,0xf7,0x26,0x00,0x00,0x01}; unsigned char data[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x04,0x74,0xf7,0x26,0x00,0x00,0x01,0x65,0x00,0x00,0x0a,0x05,0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x09}; bowler4_header bh; for (i=0; i<sizeof(bowler4_header); i++) bh.bytes[i]=0; bh.fields.version=0x04; bh.fields.affect=setPriority(5,setState(setAsync(bh.fields.affect))); bh.fields.payloadLength=10; bh.fields.payloadType=0; set_mac_address(mymac,&bh); calculate_checksum(&bh); printf("Verify?\t%d\n",verify_checksum(&bh)); printf("Verify?\t%d\n",verify_checksum(&bh)); printf("%X\n",check_mac_address(mymac,&bh) ); printHeader(bh); V4MicroParser_state parser; parser.state=align; parser.macaddr=&mymac; fifoInit(&parser.fifo); fifoPrint(&parser.fifo); for (i=0; i<sizeof(data); i++){ fifoPush(&parser.fifo,data[i]); int delta=parser.fifo.inPointer; printf("Pushing:\t%i\n",i); /*fifoPrint(&parser.fifo);*/ runParserSM(&parser); if (parser.fifo.inPointer!=delta) {printf("\nNew Contents of FIFO:");fifoPrint(&parser.fifo);} printf("===================\n"); } /* fifoPull(&fifo,15); */ /* fifoPrint(&fifo); */ }
int read_fifo_store_data(int fifo_fd, int storage_fd, unsigned char* buf, size_t length) { fprintf(stderr, "Child process %i has entered read_fifo_store_data\n", getpid() ); int bytes_read; while(1){ if ( (bytes_read = read(fifo_fd, buf, length)) != length) //reading from fifo_device { fprintf(stderr, "Error: couldn't read from fifo_dev correctly; bytes_read = %d\n", bytes_read); } // now store the data in buf to a file calculate_checksum(); read_channels(); determineError(pass_fail); write(storage_fd, buf, bytes_read); fprintf(stderr, "Child read from fifo. \n"); } close(storage_fd); close(fifo_fd); return 0; }
DEC_errCode data_encode(uint8_t message[],long unsigned int message_length,uint8_t encoded_data[],int sender_id,int message_id) { #if DEBUG > 1 printf("Entering data_encode\n"); #endif int i = 0,j; uint8_t checksum_1 = 0; uint8_t checksum_2 = 0; uint8_t length = message_length+6+16; //message length + 6 info bytes + 16 timestamp bytes timeval timestamp; TimestampBeagle timestampBeagle; encoded_data[STARTBYTE_INDEX] = 0x99; encoded_data[LENGTH_INDEX] = length; encoded_data[SENDER_ID_INDEX] = sender_id; // sender id of server encoded_data[MESSAGE_ID_INDEX] = message_id; // message id //add message memcpy(&(encoded_data[MESSAGE_START_INDEX]),(void *)message,message_length); //get localtime gettimeofday(×tamp, NULL); //convert beaglebone 8 byte timeval to 16 byte timeval for server, if this is server this does not change anything timestampBeagle.tv.tv_sec=(uint64_t)timestamp.tv_sec; timestampBeagle.tv.tv_usec=(uint64_t)timestamp.tv_usec; //add timestamp to buffer memcpy(&(encoded_data[message_length+4]),(void *)×tampBeagle.tv,sizeof(timestampBeagle.tv)); calculate_checksum(encoded_data,&checksum_1,&checksum_2); encoded_data[length-2] = checksum_1; encoded_data[length-1] = checksum_2; return DEC_ERR_NONE; }
bool ProviderWithChecksum::readDocument(const UString &path, UString &result) { if (inner->readDocument(path, result)) { auto sha1Sum = calculate_checksum(result.str()); auto expectedSha1Sum = contents[path.str()]; if (expectedSha1Sum != "") { if (sha1Sum != expectedSha1Sum) { LogWarning("File \"%s\" has incorrect checksum \"%s\", expected \"%s\"", path.cStr(), sha1Sum.cStr(), expectedSha1Sum.c_str()); } } else { LogInfo("Skipping missing checksum for file \"%s\"", path.cStr()); } return true; } return false; }
int main(void) { int rcvid; msg_buf_t msg; int status; int checksum; name_attach_t* attach; setvbuf (stdout, NULL, _IOLBF, 0); //set IO to stdout to be line buffered attach = name_attach(NULL, SERVER_NAME, 0);//PUT CODE HERE to attach a name if(NULL == attach) { //was there an error creating the channel? perror("name_attach()"); //look up the errno code and print exit(EXIT_FAILURE); } while(1) { rcvid = MsgReceive(attach->chid, &msg, sizeof msg, NULL);//PUT CODE HERE to receive msg from client, store the receive id in rcvid if(rcvid == -1) { //was there an error receiving msg? perror("MsgReceive"); //look up errno code and print continue; //try receiving another msg } else if(rcvid == 0) { printf("received pulse, code = %d\n", msg.pulse.code); continue; } printf("received msg: %s\n", msg.cksum.string_to_cksum); checksum = calculate_checksum(msg.cksum.string_to_cksum); status = MsgReply(rcvid, EOK, &checksum, sizeof checksum);//PUT CODE HERE TO reply to client with checksum, store the return status in status if(-1 == status) { perror("MsgReply"); } } return 0; }
xbee_tx_packet::xbee_tx_packet(uint8_t *pMessage, uint8_t pSize, uint16_t pDstAddress){ m_message = 0; m_messageSize = 0; m_rfDataSize = pSize; m_packetData.m_length = TX_LEN_CALC_CONST + pSize; m_packetData.m_api = 0x01; m_packetData.m_frameId = 0x01; m_packetData.m_dstAddress = pDstAddress; m_packetData.m_options = 0x00; uint8_t checksum = 0x00; m_packetData.m_rfData = new uint8_t[pSize]; if (m_packetData.m_rfData){ printf("Debug: allocated %d bytes for m_rfData.\n",pSize); }else{ printf("Debug: could not allocate memory for m_rfData.\n"); } memcpy(m_packetData.m_rfData,pMessage,pSize); // calculate checksum checksum = calculate_checksum(); // allocating memory for m_message.. m_messageSize = m_packetData.m_length+TX_MSG_SIZE_CONST; m_message = new uint8_t[m_messageSize]; if(m_message){ printf("Debug: allocated %d bytes for m_message.\n",m_messageSize); }else{ printf("Debug: could not allocate memory for m_message.\n"); } // constructing packet uint8_t tmpLenHigh = convert_to_uint8(m_packetData.m_length,RETURN_HIGH); uint8_t tmpLenLow = convert_to_uint8(m_packetData.m_length,RETURN_LOW); uint8_t tmpDstAddrHigh = convert_to_uint8(m_packetData.m_dstAddress,RETURN_HIGH); uint8_t tmpDstAddrLow = convert_to_uint8(m_packetData.m_dstAddress,RETURN_LOW); /* cleanup with constants and/or enum (check manual) */ m_message[0] = 0x7E; // start delim m_message[1] = tmpLenHigh; // length low/high m_message[2] = tmpLenLow; m_message[3] = m_packetData.m_api; m_message[4] = m_packetData.m_frameId; m_message[5] = tmpDstAddrHigh; // dst address low/high m_message[6] = tmpDstAddrLow; m_message[7] = m_packetData.m_options; for (int i = 0; i < m_rfDataSize; i++){ m_message[8+i] = m_packetData.m_rfData[i]; } m_message[m_messageSize-1] = checksum; m_packet.m_data = m_message; m_packet.m_size = m_messageSize; //for (int i = 0; i < m_messageSize; i++){ // printf("%02X ",m_message[i]); //} }
static void oeth_rx(void) { volatile oeth_regs *regs; regs = (oeth_regs *)(OETH_REG_BASE); volatile oeth_bd *rx_bdp; int pkt_len, i; int bad = 0; rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM; /* Find RX buffers marked as having received data */ for(i = 0; i < OETH_RXBD_NUM; i++) { bad=0; /* Looking for buffer descriptors marked not empty */ if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Check status for errors. */ report(i); report(rx_bdp[i].len_status); if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) { bad = 1; report(0xbaad0001); } if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) { bad = 1; report(0xbaad0002); } if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) { bad = 1; report(0xbaad0003); } if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) { bad = 1; report(0xbaad0004); } if (rx_bdp[i].len_status & OETH_RX_BD_MISS) { report(0xbaad0005); } if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) { bad = 1; report(0xbaad0006); } if (bad) { rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; //exit(0xbaaaaaad); continue; } else { /* * Process the incoming frame. */ pkt_len = rx_bdp[i].len_status >> 16; // Do a bit of work - ie. copy it, process it memcpy(CHECKSUM_BUFFER, rx_bdp[i].addr, pkt_len); report(0xc4eccccc); report(calculate_checksum(CHECKSUM_BUFFER, pkt_len)); /* finish up */ rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */ rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */ rx_done++; report(rx_done); } } }
bool DFInstanceLinux::find_running_copy(bool connect_anyway) { // find PID of DF TRACE << "attempting to find running copy of DF by executable name"; QProcess *proc = new QProcess(this); QStringList args; args << "dwarfort.exe"; // 0.31.04 and earlier args << "Dwarf_Fortress"; // 0.31.05+ proc->start("pidof", args); proc->waitForFinished(1000); if (proc->exitCode() == 0) { //found it QByteArray out = proc->readAllStandardOutput(); QStringList str_pids = QString(out).split(" "); str_pids.sort(); if(str_pids.count() > 1){ m_pid = QInputDialog::getItem(0, tr("Warning"),tr("Multiple Dwarf Fortress processes found, please choose the process to use."),str_pids,str_pids.count()-1,false).toInt(); }else{ m_pid = str_pids.at(0).toInt(); } m_memory_file.setFileName(QString("/proc/%1/mem").arg(m_pid)); TRACE << "USING PID:" << m_pid; } else { QMessageBox::warning(0, tr("Warning"), tr("Unable to locate a running copy of Dwarf " "Fortress, are you sure it's running?")); LOGW << "can't find running copy"; m_is_ok = false; return m_is_ok; } m_inject_addr = unsigned(-1); m_alloc_start = 0; m_alloc_end = 0; map_virtual_memory(); //qDebug() << "LOWEST ADDR:" << hex << lowest_addr; //DUMP LIST OF MEMORY RANGES /* QPair<uint, uint> tmp_pair; foreach(tmp_pair, m_regions) { LOGD << "RANGE start:" << hex << tmp_pair.first << "end:" << tmp_pair.second; }*/ VIRTADDR m_base_addr = read_addr(m_lowest_address + 0x18); LOGD << "base_addr:" << m_base_addr << "HEX" << hex << m_base_addr; m_is_ok = m_base_addr > 0; uint checksum = calculate_checksum(); LOGD << "DF's checksum is" << hexify(checksum); if (m_is_ok) { m_layout = get_memory_layout(hexify(checksum).toLower(), !connect_anyway); } //Get dwarf fortress directory m_df_dir = QDir(QFileInfo(QString("/proc/%1/cwd").arg(m_pid)).symLinkTarget()); LOGI << "Dwarf fortress path:" << m_df_dir.absolutePath(); return m_is_ok || connect_anyway; }
void cmd_loop() { while(1) { /* Wait for a command */ while(ub.command == NULL) { } esp_command_req_t *command = ub.command; ub.command = NULL; /* provide easy access for 32-bit data words */ uint32_t *data_words = (uint32_t *)command->data_buf; /* Send command response header */ esp_command_response_t resp = { .resp = 1, .op_ret = command->op, .len_ret = 0, /* esptool.py ignores this value */ .value = 0, }; /* ESP_READ_REG is the only command that needs to write into the 'resp' structure before we send it back. */ if (command->op == ESP_READ_REG && command->data_len == 4) { resp.value = REG_READ(data_words[0]); } /* Send the command response. */ SLIP_send_frame_delimiter(); SLIP_send_frame_data_buf(&resp, sizeof(esp_command_response_t)); if(command->data_len > MAX_WRITE_BLOCK+16) { SLIP_send_frame_data(ESP_BAD_DATA_LEN); SLIP_send_frame_data(0xEE); SLIP_send_frame_delimiter(); continue; } /* ... some commands will insert in-frame response data between here and when we send the end of the frame */ esp_command_error error = ESP_CMD_NOT_IMPLEMENTED; int status = 0; /* First stage of command processing - before sending error/status */ switch (command->op) { case ESP_ERASE_FLASH: error = verify_data_len(command, 0) || SPIEraseChip(); break; case ESP_ERASE_REGION: /* Params for ERASE_REGION are addr, len */ error = verify_data_len(command, 8) || handle_flash_erase(data_words[0], data_words[1]); break; case ESP_SET_BAUD: /* ESP_SET_BAUD sends two args, we ignore the second one */ error = verify_data_len(command, 8); /* actual baud setting happens after we send the reply */ break; case ESP_READ_FLASH: error = verify_data_len(command, 16); /* actual data is sent after we send the reply */ break; case ESP_FLASH_VERIFY_MD5: /* unsure why the MD5 command has 4 params but we only pass 2 of them, but this is in ESP32 ROM so we can't mess with it. */ error = verify_data_len(command, 16) || handle_flash_get_md5sum(data_words[0], data_words[1]); break; case ESP_FLASH_BEGIN: /* parameters (interpreted differently to ROM flasher): 0 - erase_size (used as total size to write) 1 - num_blocks (ignored) 2 - block_size (should be MAX_WRITE_BLOCK, relies on num_blocks * block_size >= erase_size) 3 - offset (used as-is) */ if (command->data_len == 16 && data_words[2] != MAX_WRITE_BLOCK) { error = ESP_BAD_BLOCKSIZE; } else { error = verify_data_len(command, 16) || handle_flash_begin(data_words[0], data_words[3]); } break; case ESP_FLASH_DEFLATED_BEGIN: /* parameters: 0 - uncompressed size 1 - num_blocks (based on compressed size) 2 - block_size (should be MAX_WRITE_BLOCK, total bytes over serial = num_blocks * block_size) 3 - offset (used as-is) */ if (command->data_len == 16 && data_words[2] != MAX_WRITE_BLOCK) { error = ESP_BAD_BLOCKSIZE; } else { error = verify_data_len(command, 16) || handle_flash_deflated_begin(data_words[0], data_words[1] * data_words[2], data_words[3]); } break; case ESP_FLASH_DATA: case ESP_FLASH_DEFLATED_DATA: /* ACK DATA commands immediately, then process them a few lines down, allowing next command to buffer */ if(is_in_flash_mode()) { error = get_flash_error(); int payload_len = command->data_len - 16; if (data_words[0] != payload_len) { /* First byte of data payload header is length (repeated) as a word */ error = ESP_BAD_DATA_LEN; } uint8_t data_checksum = calculate_checksum(command->data_buf + 16, payload_len); if (data_checksum != command->checksum) { error = ESP_BAD_DATA_CHECKSUM; } } else { error = ESP_NOT_IN_FLASH_MODE; } break; case ESP_FLASH_END: case ESP_FLASH_DEFLATED_END: error = handle_flash_end(); break; case ESP_SPI_SET_PARAMS: /* data params: fl_id, total_size, block_size, sector_Size, page_size, status_mask */ error = verify_data_len(command, 24) || handle_spi_set_params(data_words, &status); break; case ESP_SPI_ATTACH: /* parameter is 'hspi mode' (0, 1 or a pin mask for ESP32. Ignored on ESP8266.) */ error = verify_data_len(command, 4) || handle_spi_attach(data_words[0]); break; case ESP_WRITE_REG: /* params are addr, value, mask (ignored), delay_us (ignored) */ error = verify_data_len(command, 16); if (error == ESP_OK) { REG_WRITE(data_words[0], data_words[1]); } break; case ESP_READ_REG: /* actual READ_REG operation happens higher up */ error = verify_data_len(command, 4); break; case ESP_MEM_BEGIN: error = verify_data_len(command, 16) || handle_mem_begin(data_words[0], data_words[3]); break; case ESP_MEM_DATA: error = handle_mem_data(command->data_buf + 16, command->data_len - 16); break; case ESP_MEM_END: error = verify_data_len(command, 8) || handle_mem_finish(); break; case ESP_RUN_USER_CODE: /* Returning from here will run user code, ie standard boot process This command does not send a response. */ return; } SLIP_send_frame_data(error); SLIP_send_frame_data(status); SLIP_send_frame_delimiter(); /* Some commands need to do things after after sending this response */ if (error == ESP_OK) { switch(command->op) { case ESP_SET_BAUD: ets_delay_us(10000); uart_div_modify(0, baud_rate_to_divider(data_words[0])); ets_delay_us(1000); break; case ESP_READ_FLASH: /* args are: offset, length, block_size, max_in_flight */ handle_flash_read(data_words[0], data_words[1], data_words[2], data_words[3]); break; case ESP_FLASH_DATA: /* drop into flashing mode, discard 16 byte payload header */ handle_flash_data(command->data_buf + 16, command->data_len - 16); break; case ESP_FLASH_DEFLATED_DATA: handle_flash_deflated_data(command->data_buf + 16, command->data_len - 16); break; case ESP_FLASH_DEFLATED_END: case ESP_FLASH_END: /* passing 0 as parameter for ESP_FLASH_END means reboot now */ if (data_words[0] == 0) { /* Flush the FLASH_END response before rebooting */ #ifdef ESP32 uart_tx_flush(0); #endif ets_delay_us(10000); software_reset(); } break; case ESP_MEM_END: if (data_words[1] != 0) { void (*entrypoint_fn)(void) = (void (*))data_words[1]; /* this is a little different from the ROM loader, which exits the loader routine and _then_ calls this function. But for our purposes so far, having a bit of extra stuff on the stack doesn't really matter. */ entrypoint_fn(); } break; } } } } extern uint32_t _bss_start; extern uint32_t _bss_end; void __attribute__((used)) stub_main(); #ifdef ESP8266 __asm__ ( ".global stub_main_8266\n" ".literal_position\n" ".align 4\n" "stub_main_8266:\n" /* ESP8266 wrapper for "stub_main()" manipulates the return address in * a0, so 'return' from here runs user code. * * After setting a0, we jump directly to stub_main_inner() which is a * normal C function * * Adapted from similar approach used by Cesanta Software for ESP8266 * flasher stub. * */ "movi a0, 0x400010a8;" "j stub_main;"); #endif /* This function is called from stub_main, with return address reset to point to user code. */ void stub_main() { const uint32_t greeting = 0x4941484f; /* OHAI */ /* this points to stub_main now, clear for next boot */ ets_set_user_start(0); /* zero bss */ for(uint32_t *p = &_bss_start; p < &_bss_end; p++) { *p = 0; } SLIP_send(&greeting, 4); /* All UART reads come via uart_isr */ ub.reading_buf = ub.buf_a; ets_isr_attach(ETS_UART0_INUM, uart_isr, NULL); SET_PERI_REG_MASK(UART_INT_ENA(0), UART_RX_INTS); ets_isr_unmask(1 << ETS_UART0_INUM); /* Configure default SPI flash functionality. Can be overriden later by esptool.py. */ #ifdef ESP8266 SelectSpiFunction(); #else uint32_t spiconfig = ets_efuse_get_spiconfig(); uint32_t strapping = REG_READ(GPIO_STRAP_REG); /* If GPIO1 (U0TXD) is pulled low and no other boot mode is set in efuse, assume HSPI flash mode (same as normal boot) */ if (spiconfig == 0 && (strapping & 0x1c) == 0x08) { spiconfig = 1; /* HSPI flash mode */ } spi_flash_attach(spiconfig, 0); #endif SPIParamCfg(0, 16*1024*1024, FLASH_BLOCK_SIZE, FLASH_SECTOR_SIZE, FLASH_PAGE_SIZE, FLASH_STATUS_MASK); cmd_loop(); /* if cmd_loop returns, it's due to ESP_RUN_USER_CODE command. */ return; }
static int wrapfs_open(struct inode *inode, struct file *file) { int err = 0; struct file *lower_file = NULL; struct path lower_path; #ifdef EXTRA_CREDIT int CHKSUM_SIZE =0; char *algo = kmalloc(sizeof(char)*10,GFP_KERNEL); int *algo_len = kmalloc(sizeof(char)*1,GFP_KERNEL); char *chkbuf = kmalloc(sizeof(char)*32,GFP_KERNEL); char *getchkbuf = kmalloc(sizeof(char)*32,GFP_KERNEL); #else char *chkbuf = kmalloc(sizeof(char)*CHKSUM_SIZE,GFP_KERNEL); char *getchkbuf = kmalloc(sizeof(char)*CHKSUM_SIZE,GFP_KERNEL); #endif char *has_integrity = kmalloc(sizeof(char)*1,GFP_KERNEL); int rc = 0; if(!chkbuf || !has_integrity || !getchkbuf) { err = -ENOMEM; goto out_err; } /* don't open unhashed/deleted files */ if (d_unhashed(file->f_path.dentry)) { err = -ENOENT; goto out_err; } file->private_data = kzalloc(sizeof(struct wrapfs_file_info), GFP_KERNEL); if (!WRAPFS_F(file)) { err = -ENOMEM; goto out_err; } /* open lower object and link wrapfs's file struct to lower's */ wrapfs_get_lower_path(file->f_path.dentry, &lower_path); lower_file = dentry_open(lower_path.dentry, lower_path.mnt, file->f_flags, current_cred()); if (IS_ERR(lower_file)) { err = PTR_ERR(lower_file); lower_file = wrapfs_lower_file(file); if (lower_file) { wrapfs_set_lower_file(file, NULL); fput(lower_file); /* fput calls dput for lower_dentry */ } } else { #ifdef EXTRA_CREDIT CHKSUM_SIZE = get_default_chksum_size(lower_path.dentry,algo,algo_len); #endif rc = vfs_getxattr(lower_path.dentry,XATTR_HAS_INTEGRITY,has_integrity,1); if(rc > 0 && !S_ISDIR(lower_path.dentry->d_inode->i_mode)) { wrapfs_set_lower_file(file,lower_file); if(lower_file->f_mode == O_TRUNC) wrapfs_set_write_dirty(inode,WRITE_DIRTY_BIT); if(!memcmp(has_integrity,"1",1) && wrapfs_get_write_dirty(inode)!=WRITE_DIRTY_BIT && rc ==1) { if(vfs_getxattr(lower_path.dentry,XATTR_INTEGRITY_VAL,chkbuf,CHKSUM_SIZE)>0) { //mutex_lock(&lower_path.dentry->d_inode->i_mutex); calculate_checksum(lower_file,getchkbuf,CHKSUM_SIZE); if(memcmp(chkbuf,getchkbuf,CHKSUM_SIZE)) { printk("Integrity mismatch\n"); err = -EPERM; wrapfs_set_lower_file(file,NULL); fput(lower_file); } //mutex_unlock(&lower_path.dentry->d_inode->i_mutex); } } else if(!memcmp(has_integrity,"0",1) && rc ==1) { if(vfs_getxattr(lower_path.dentry,XATTR_INTEGRITY_VAL,chkbuf,CHKSUM_SIZE)>0) { err = -EIO; wrapfs_set_lower_file(file,NULL); fput(lower_file); } else wrapfs_set_lower_file(file,lower_file); } else { printk("File corrupted.Unexpected value for has_integrity attribute\n"); err = -EPERM; wrapfs_set_lower_file(file,NULL); fput(lower_file); } } else if(vfs_getxattr(lower_path.dentry,XATTR_HAS_INTEGRITY,has_integrity,1)<=0 && vfs_getxattr(lower_path.dentry,XATTR_INTEGRITY_VAL,chkbuf,CHKSUM_SIZE)>0) { err = -EIO; wrapfs_set_lower_file(file,NULL); fput(lower_file); } else { wrapfs_set_lower_file(file, lower_file); } } if (err) kfree(WRAPFS_F(file)); else fsstack_copy_attr_all(inode, wrapfs_lower_inode(inode)); out_err: kfree(chkbuf); kfree(getchkbuf); kfree(has_integrity); #ifdef EXTRA_CREDIT kfree(algo); kfree(algo_len); #endif return err; }
int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, const size_t filecount, const char * files[], int * offset, const char verbosity){ if (fd < 0){ return -1; } if (!archive || *archive){ return -1; } if (filecount && !files){ return -1; } // add new data struct tar_t ** tar = archive; // current entry char buf[512]; // one block buffer for(unsigned int i = 0; i < filecount; i++){ *tar = malloc(sizeof(struct tar_t)); // stat file if (format_tar_data(*tar, files[i], verbosity) < 0){ WRITE_ERROR(stderr, "Error: Failed to stat %s\n", files[i]); } if (!i){ *archive = *tar; // store first address } (*tar) -> begin = *offset; // write different data depending on file type if ((*tar) -> type == DIRECTORY){ // save parent directory name (source will change) const size_t len = strlen((*tar) -> name); char * parent = calloc(len + 1, sizeof(char)); strncpy(parent, (*tar) -> name, len); // add a '/' character to the end if ((len < 99) && ((*tar) -> name[len - 1] != '/')){ (*tar) -> name[len] = '/'; (*tar) -> name[len + 1] = '\0'; calculate_checksum((*tar)); } V_PRINT(stdout, "%s\n", (*tar) -> name); // write metadata to (*tar) file if (write_size(fd, (*tar) -> block, 512) != 512){ WRITE_ERROR(stderr, "Error: Failed to write metadata to archive\n"); } // go through directory DIR * d = opendir(parent); if (!d){ WRITE_ERROR(stderr, "Error: Cannot read directory %s\n", parent); } struct dirent * dir; while ((dir = readdir(d))){ // if not special directories . and .. const size_t sublen = strlen(dir -> d_name); if (strncmp(dir -> d_name, ".", sublen) && strncmp(dir -> d_name, "..", sublen)){ char * path = calloc(len + sublen + 2, sizeof(char)); sprintf(path, "%s/%s", parent, dir -> d_name); // recursively write each subdirectory if (write_entries(fd, &((*tar) -> next), head, 1, (const char **) &path, offset, verbosity) < 0){ WRITE_ERROR(stderr, "Error: Recurse error\n"); } // go to end of new data while ((*tar) -> next){ tar = &((*tar) -> next); } free(path); } } free(parent); closedir(d); } else{ // if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS) || ((*tar) -> type == SYMLINK) || ((*tar) -> type == CHAR) || ((*tar) -> type == BLOCK) || ((*tar) -> type == FIFO)){ V_PRINT(stdout, "%s\n", (*tar) -> name); char tarred = 0; // whether or not the file has already been put into the archive if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS) || ((*tar) -> type == SYMLINK)){ struct tar_t * found = exists(*head, files[i], 1); tarred = (found != (*tar)); // if file has already been included, modify the header if (tarred){ // change type to hard link (*tar) -> type = HARDLINK; // change link name to (*tar)red file name (both are the same) strncpy((*tar) -> link_name, (*tar) -> name, 100); // change size to 0 strncpy((*tar) -> size, "00000000000", 11); // recalculate checksum calculate_checksum((*tar)); } } // write metadata to (*tar) file if (write_size(fd, (*tar) -> block, 512) != 512){ WRITE_ERROR(stderr, "Error: Failed to write metadata to archive\n"); } if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS)){ // if the file isn't already in the tar file, copy the contents in if (!tarred){ int f = open((*tar) -> name, O_RDONLY); if (f < 0){ WRITE_ERROR(stderr, "Error: Could not open %s\n", files[i]); } int r = 0; while ((r = read_size(f, buf, 512)) > 0){ if (write_size(fd, buf, r) != r){ RC_ERROR(stderr, "Error: Could not write to archive: %s\n", strerror(rc)); } } close(f); } } // pad data to fill block const unsigned int size = oct2uint((*tar) -> size, 11); const unsigned int pad = 512 - size % 512; if (pad != 512){ for(unsigned int j = 0; j < pad; j++){ if (write_size(fd, "\0", 1) != 1){ WRITE_ERROR(stderr, "Error: Could not write padding data\n"); } } *offset += pad; } *offset += size; tar = &((*tar) -> next); } // add metadata size *offset += 512; } return 0; }
int format_tar_data(struct tar_t * entry, const char * filename, const char verbosity){ if (!entry){ return -1; } struct stat st; if (lstat(filename, &st)){ RC_ERROR(stderr, "Error: Cannot stat %s: %s\n", filename, strerror(rc)); return -1; } // remove relative path int move = 0; if (!strncmp(filename, "/", 1)){ move = 1; } else if (!strncmp(filename, "./", 2)){ move = 2; } else if (!strncmp(filename, "../", 3)){ move = 3; } // start putting in new data memset(entry, 0, sizeof(struct tar_t)); strncpy(entry -> original_name, filename, 100); strncpy(entry -> name, filename + move, 100); sprintf(entry -> mode, "%07o", st.st_mode & 0777); sprintf(entry -> uid, "%07o", st.st_uid); sprintf(entry -> gid, "%07o", st.st_gid); sprintf(entry -> size, "%011o", (int) st.st_size); sprintf(entry -> mtime, "%011o", (int) st.st_mtime); strncpy(entry -> group, "None", 4); // default value memcpy(entry -> ustar, "ustar\00000", 8); // official value? // figure out filename type switch (st.st_mode & S_IFMT) { case S_IFREG: entry -> type = NORMAL; break; case S_IFLNK: entry -> type = SYMLINK; // file size is 0, but will print link size strncpy(entry -> size, "00000000000", 11); // get link name if (readlink(filename, entry -> link_name, 100) < 0){ RC_ERROR(stderr, "Error: Could not read link %s: %s\n", filename, strerror(rc)); } break; case S_IFCHR: entry -> type = CHAR; // get character device major and minor values sprintf(entry -> major, "%08o", major(st.st_dev)); sprintf(entry -> minor, "%08o", minor(st.st_dev)); break; case S_IFBLK: entry -> type = BLOCK; // get block device major and minor values sprintf(entry -> major, "%08o", major(st.st_dev)); sprintf(entry -> minor, "%08o", minor(st.st_dev)); break; case S_IFDIR: entry -> type = DIRECTORY; break; case S_IFIFO: entry -> type = FIFO; break; case S_IFSOCK: entry -> type = -1; V_PRINT(stderr, "Error: Cannot tar socket\n"); return -1; break; default: entry -> type = -1; V_PRINT(stderr, "Error: Unknown filetype\n"); return -1; break; } // get username if (getlogin_r(entry -> owner, 32)){ RC_ERROR(stderr, "Warning: Unable to get username: %s\n", strerror(rc)); } // get group name struct group * grp = getgrgid(st.st_gid); if (grp){ strncpy(entry -> group, grp -> gr_name, 100); } // get the checksum calculate_checksum(entry); return 0; }
// WriteResources uint32 ResourceFile::WriteResources(void* buffer, uint32 bufferSize) { // calculate sizes and offsets // header uint32 size = kResourcesHeaderSize; // index section uint32 indexSectionOffset = size; uint32 indexSectionSize = kResourceIndexSectionHeaderSize + fResourceCount * kResourceIndexEntrySize; indexSectionSize = align_value(indexSectionSize, kResourceIndexSectionAlignment); size += indexSectionSize; // unknown section uint32 unknownSectionOffset = size; uint32 unknownSectionSize = kUnknownResourceSectionSize; size += unknownSectionSize; // data uint32 dataOffset = size; uint32 dataSize = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); dataSize += item->GetSize(); } size += dataSize; // info table uint32 infoTableOffset = size; uint32 infoTableSize = 0; type_code type = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); if (i == 0 || type != item->GetType()) { if (i != 0) infoTableSize += kResourceInfoSeparatorSize; type = item->GetType(); infoTableSize += kMinResourceInfoBlockSize; } else infoTableSize += kMinResourceInfoSize; uint32 nameLen = strlen(item->GetName()); if (nameLen != 0) infoTableSize += nameLen + 1; } infoTableSize += kResourceInfoSeparatorSize + kResourceInfoTableEndSize; size += infoTableSize; // check whether the buffer is large enough if (!buffer) throw Exception("Supplied buffer is NULL."); if (bufferSize < size) throw Exception("Supplied buffer is too small."); // write... void* data = buffer; // header resources_header* resourcesHeader = (resources_header*)data; resourcesHeader->rh_resources_magic = kResourcesHeaderMagic; resourcesHeader->rh_resource_count = fResourceCount; resourcesHeader->rh_index_section_offset = indexSectionOffset; resourcesHeader->rh_admin_section_size = indexSectionOffset + indexSectionSize; for (int32 i = 0; i < 13; i++) resourcesHeader->rh_pad[i] = 0; // index section // header data = skip_bytes(buffer, indexSectionOffset); resource_index_section_header* indexHeader = (resource_index_section_header*)data; indexHeader->rish_index_section_offset = indexSectionOffset; indexHeader->rish_index_section_size = indexSectionSize; indexHeader->rish_unknown_section_offset = unknownSectionOffset; indexHeader->rish_unknown_section_size = unknownSectionSize; indexHeader->rish_info_table_offset = infoTableOffset; indexHeader->rish_info_table_size = infoTableSize; fill_pattern(buffer, &indexHeader->rish_unused_data1, 1); fill_pattern(buffer, indexHeader->rish_unused_data2, 25); fill_pattern(buffer, &indexHeader->rish_unused_data3, 1); // index table data = skip_bytes(data, kResourceIndexSectionHeaderSize); resource_index_entry* entry = (resource_index_entry*)data; uint32 entryOffset = dataOffset; for (int32 i = 0; i < fResourceCount; i++, entry++) { ResourceItem* item = ItemAt(i); uint32 entrySize = item->GetSize(); entry->rie_offset = entryOffset; entry->rie_size = entrySize; entry->rie_pad = 0; entryOffset += entrySize; } // padding + unknown section data = skip_bytes(buffer, dataOffset); fill_pattern(buffer, entry, data); // data for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); status_t error = item->LoadData(fFile); if (error != B_OK) throw Exception(error, "Error loading resource data."); uint32 entrySize = item->GetSize(); memcpy(data, item->GetData(), entrySize); data = skip_bytes(data, entrySize); } // info table data = skip_bytes(buffer, infoTableOffset); type = 0; for (int32 i = 0; i < fResourceCount; i++) { ResourceItem* item = ItemAt(i); resource_info* info = NULL; if (i == 0 || type != item->GetType()) { if (i != 0) { resource_info_separator* separator = (resource_info_separator*)data; separator->ris_value1 = 0xffffffff; separator->ris_value2 = 0xffffffff; data = skip_bytes(data, kResourceInfoSeparatorSize); } type = item->GetType(); resource_info_block* infoBlock = (resource_info_block*)data; infoBlock->rib_type = type; info = infoBlock->rib_info; } else info = (resource_info*)data; // info info->ri_id = item->GetID(); info->ri_index = i + 1; info->ri_name_size = 0; data = info->ri_name; uint32 nameLen = strlen(item->GetName()); if (nameLen != 0) { memcpy(info->ri_name, item->GetName(), nameLen + 1); data = skip_bytes(data, nameLen + 1); info->ri_name_size = nameLen + 1; } } // separator resource_info_separator* separator = (resource_info_separator*)data; separator->ris_value1 = 0xffffffff; separator->ris_value2 = 0xffffffff; // table end data = skip_bytes(data, kResourceInfoSeparatorSize); resource_info_table_end* tableEnd = (resource_info_table_end*)data; void* infoTable = skip_bytes(buffer, infoTableOffset); tableEnd->rite_check_sum = calculate_checksum(infoTable, infoTableSize - kResourceInfoTableEndSize); tableEnd->rite_terminator = 0; // final check data = skip_bytes(data, kResourceInfoTableEndSize); uint32 bytesWritten = (char*)data - (char*)buffer; if (bytesWritten != size) { throw Exception("Bad boy error: Wrote %lu bytes, though supposed to " "write %lu bytes.", bytesWritten, size); } return size; }