* Write a resource to the specified ELF binary handle */
| 404 | * Write a resource to the specified ELF binary handle |
| 405 | */ |
| 406 | int libr_write(libr_file *file_handle, char *resource_name, char *buffer, size_t size, libr_type_t type, libr_overwrite_t overwrite) |
| 407 | { |
| 408 | char header[9] = {'R', 'E', 'S', SPEC_VERSION}; |
| 409 | unsigned int header_size = 4; |
| 410 | libr_section *scn = NULL; |
| 411 | libr_data *data = NULL; |
| 412 | libr_intstatus ret; |
| 413 | |
| 414 | /* Ensure valid inputs */ |
| 415 | if(file_handle == NULL || resource_name == NULL || buffer == NULL) |
| 416 | PUBLIC_RETURN(LIBR_ERROR_INVALIDPARAMS, "Invalid parameters passed to function"); |
| 417 | if(file_handle->access != LIBR_READ_WRITE) |
| 418 | PUBLIC_RETURN(LIBR_ERROR_NOPERM, "Open handle with LIBR_READ_WRITE access"); |
| 419 | /* Get the section if it already exists */ |
| 420 | ret = find_section(file_handle, resource_name, &scn); |
| 421 | if(ret.status == LIBR_OK) |
| 422 | { |
| 423 | /* If the section exists (and overwrite is not specified) then fail */ |
| 424 | if(!overwrite) |
| 425 | PUBLIC_RETURN(LIBR_ERROR_OVERWRITE, "Section already exists, over-write not specified"); |
| 426 | /* Grab the existing data section for overwriting */ |
| 427 | if((data = get_data(file_handle, scn)) == NULL) |
| 428 | PUBLIC_RETURN(LIBR_ERROR_GETDATA, "Failed to obtain data of section"); |
| 429 | } |
| 430 | else if(ret.status == LIBR_ERROR_NOSECTION) |
| 431 | { |
| 432 | /* Create a new section named "resource_name" */ |
| 433 | if(add_section(file_handle, resource_name, &scn).status != LIBR_OK) |
| 434 | return false; /* error already set */ |
| 435 | /* Create a data segment to store the compressed image */ |
| 436 | if((data = new_data(file_handle, scn)) == NULL) |
| 437 | PUBLIC_RETURN(LIBR_ERROR_NEWDATA, "Failed to create data for section"); |
| 438 | } |
| 439 | else |
| 440 | return false; /* error already set */ |
| 441 | |
| 442 | header[header_size++] = (char) type; |
| 443 | switch(type) |
| 444 | { |
| 445 | case LIBR_UNCOMPRESSED: |
| 446 | /* Do nothing, just stick the data in */ |
| 447 | break; |
| 448 | case LIBR_COMPRESSED: |
| 449 | { |
| 450 | char *compressed_buffer = NULL, *uncompressed_buffer = buffer; |
| 451 | unsigned long compressed_size = 0, uncompressed_size = size; |
| 452 | uint32_t size_temp; |
| 453 | |
| 454 | /* Store the uncompressed size to the header */ |
| 455 | size_temp = uncompressed_size; |
| 456 | memcpy(&header[header_size], &size_temp, sizeof(uint32_t)); |
| 457 | header_size += sizeof(uint32_t); |
| 458 | /* Compress the data for storage */ |
| 459 | compressed_size = ceil((uncompressed_size+12)*1.1); |
| 460 | compressed_buffer = (char *) malloc(compressed_size); |
| 461 | if(compress((unsigned char *)compressed_buffer, &compressed_size, (unsigned char *)uncompressed_buffer, uncompressed_size) != Z_OK) |
| 462 | { |
| 463 | free(compressed_buffer); |
no test coverage detected