Guest User

Untitled

a guest
Sep 25th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.71 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2012, Muhammad Sumyandityo Noor
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * - Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  16. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  18. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  19. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  21. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  22. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  23. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  24. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. *
  26. */
  27.  
  28. // For reading Electronic Arts' .big files archives
  29.  
  30.  
  31. #include <stdio.h>
  32. #include <sys/stat.h>
  33. #include <fcntl.h>
  34. #include <unistd.h>
  35. #include <sys/mman.h>
  36. #include <string.h>
  37. #include <stdint.h>
  38.  
  39. // Per File Entry Headers
  40. struct big_entry_file_header {
  41. uint32_t offset; // big-endian
  42. uint32_t size; // big-endian
  43. };
  44.  
  45. // Archive header
  46. struct big_header {
  47. char ident[4];
  48. uint32_t archive_size; // little-endian
  49. uint32_t number_of_files; // big-endian
  50. uint32_t first_file_offset; // big-endian
  51. };
  52.  
  53. // Endian Check
  54. enum
  55. {
  56. O32_LITTLE_ENDIAN = 0x03020100ul,
  57. O32_BIG_ENDIAN = 0x00010203ul,
  58. O32_PDP_ENDIAN = 0x01000302ul
  59. };
  60.  
  61. static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order =
  62. { { 0, 1, 2, 3 } };
  63.  
  64. #define O32_HOST_ORDER (o32_host_order.value)
  65.  
  66.  
  67. // byte swap 32-bit
  68. static unsigned int inline
  69. swapped( unsigned int num ) {
  70. return ((num>>24)&0xff) | // move byte 3 to byte 0
  71. ((num<<8)&0xff0000) | // move byte 1 to byte 2
  72. ((num>>8)&0xff00) | // move byte 2 to byte 1
  73. ((num<<24)&0xff000000); // byte 0 to byte 3
  74. }
  75.  
  76. // convert big endian to native endian
  77. static unsigned int inline
  78. big2native( unsigned int num ) {
  79. if (O32_HOST_ORDER == O32_LITTLE_ENDIAN) {
  80. return swapped(num);
  81. }
  82. else {
  83. return num;
  84. }
  85. }
  86.  
  87. // convert little endian to native endian
  88. static unsigned int inline
  89. little2native(unsigned int num) {
  90. if (O32_HOST_ORDER == O32_BIG_ENDIAN) {
  91. return swapped(num);
  92. }
  93. else {
  94. return num;
  95. }
  96. }
  97.  
  98. int main( int argc, char **argv ) {
  99. // file stat
  100. struct stat sb;
  101. // file length
  102. off_t len;
  103. // mapped memory address
  104. char *p;
  105.  
  106. // file handle
  107. int fd;
  108.  
  109. // archive header address
  110. struct big_header *ph;
  111.  
  112. // hard coded [sorry, just for test !^_^]
  113.  
  114. fd = open("/Applications/Command & Conquer Generals/Generals Data"
  115. "/Terrain.big", O_RDONLY);
  116.  
  117. if (fstat(fd, &sb) == -1) {
  118. perror("fstat");
  119. return 1;
  120. }
  121.  
  122. if (!S_ISREG(sb.st_mode)) {
  123. fprintf (stderr, "%s is not a file\n", "Invalid Big File");
  124. return 1;
  125. }
  126.  
  127. p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
  128.  
  129. ph = (struct big_header*) p;
  130.  
  131. printf("Size of File : ");
  132.  
  133. if (little2native(ph->archive_size) >= 1024*1024) {
  134. float s = little2native(ph->archive_size) / (1024.0f * 1024.0f);
  135. printf("%.2f MB", s);
  136. }
  137. else if (little2native(ph->archive_size) >= 1024) {
  138. float s = little2native(ph->archive_size) / 1024.0f;
  139. printf("%.2f KB", s);
  140. }
  141. else {
  142. printf("%ul bytes", little2native(ph->archive_size));
  143. }
  144. printf("\n");
  145. printf("Number of Files : %u\n", big2native(ph->number_of_files));
  146. printf("First File Offset : 0x%x\n", big2native(ph->first_file_offset));
  147.  
  148. char *f = p + sizeof(struct big_header);
  149. char *d = f;
  150. int i;
  151.  
  152. for (i = 0; i < big2native(ph->number_of_files); ++i) {
  153. struct big_entry_file_header *eh = (struct big_entry_file_header*)d;
  154. d += sizeof(struct big_entry_file_header);
  155. printf("%s - ", d);
  156. while (*d != '\0') {
  157. ++d;
  158. }
  159. ++d;
  160.  
  161. printf("Size %u, Offset 0x%x\n", big2native(eh->size),
  162. big2native(eh->offset));
  163. }
  164.  
  165. close(fd);
  166. munmap(p, sb.st_size);
  167.  
  168. return 0;
  169. }
Add Comment
Please, Sign In to add comment