Advertisement
Guest User

Untitled

a guest
Apr 19th, 2015
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. /*
  2. * This code only supports Little endian machine.
  3. */
  4. #include <errno.h>
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. #define PSF_MAGIC 0x46535000
  11.  
  12. enum {
  13. SFO_DATATYPE_UTF8 = 0x0204,
  14. SFO_DATATYPE_INT32 = 0x0404
  15. };
  16.  
  17. enum {
  18. SFO_ENT_ATTRIBUTE,
  19. SFO_ENT_BOOTABLE,
  20. SFO_ENT_CATEGORY,
  21. SFO_ENT_PARENTAL_LEVEL,
  22. SFO_ENT_TITLE,
  23. SFO_ENT_TITLE_ID,
  24. SFO_ENT_VERSION
  25. };
  26.  
  27. struct sfoHdr {
  28. uint32_t magic;
  29. uint32_t ver;
  30. uint32_t keyOffset;
  31. uint32_t dataOffset;
  32. uint32_t num;
  33. };
  34.  
  35. struct sfoEnt {
  36. uint16_t keyOffset;
  37. uint16_t dataType;
  38. uint32_t dataSize;
  39. uint32_t dataMaxSize;
  40. uint32_t dataOffset;
  41. };
  42.  
  43. struct outKeys_t {
  44. char attr[sizeof("ATTRIBUTE")];
  45. char bootable[sizeof("BOOTABLE")];
  46. char category[sizeof("CATEGORY")];
  47. char pl[sizeof("PARENTAL_LEVEL")];
  48. char title[sizeof("TITLE")];
  49. char titleId[sizeof("TITLE_ID")];
  50. char ver[sizeof("VERSION")];
  51. char pad[2];
  52. };
  53.  
  54. static const struct outKeys_t outKeys = {
  55. .attr = "ATTRIBUTE",
  56. .bootable = "BOOTABLE",
  57. .category = "CATEGORY",
  58. .pl = "PARENTAL_LEVEL",
  59. .title = "TITLE",
  60. .titleId = "TITLE_ID",
  61. .ver = "VERSION"
  62. };
  63.  
  64. struct outData_t {
  65. int32_t attr;
  66. int32_t bootable;
  67. char category[4];
  68. int32_t pl;
  69. char title[128];
  70. char titleId[16];
  71. char ver[8];
  72. };
  73.  
  74. static struct outData_t outData = {
  75. .attr = 3,
  76. .bootable = 1,
  77. .category = "PE"
  78. };
  79.  
  80. static struct sfoEnt outEnt[] = {
  81. [SFO_ENT_ATTRIBUTE] = {
  82. .keyOffset = offsetof(struct outKeys_t, attr),
  83. .dataType = SFO_DATATYPE_INT32,
  84. .dataSize = sizeof(outData.attr),
  85. .dataMaxSize = sizeof(outData.attr),
  86. .dataOffset = offsetof(struct outData_t, attr)
  87. },
  88. [SFO_ENT_BOOTABLE] = {
  89. .keyOffset = offsetof(struct outKeys_t, bootable),
  90. .dataType = SFO_DATATYPE_INT32,
  91. .dataSize = sizeof(outData.bootable),
  92. .dataMaxSize = sizeof(outData.bootable),
  93. .dataOffset = offsetof(struct outData_t, bootable)
  94. },
  95. [SFO_ENT_CATEGORY] = {
  96. .keyOffset = offsetof(struct outKeys_t, category),
  97. .dataType = SFO_DATATYPE_UTF8,
  98. .dataSize = 3,
  99. .dataMaxSize = sizeof(outData.category),
  100. .dataOffset = offsetof(struct outData_t, category)
  101. },
  102. [SFO_ENT_PARENTAL_LEVEL] = {
  103. .keyOffset = offsetof(struct outKeys_t, pl),
  104. .dataType = SFO_DATATYPE_INT32,
  105. .dataSize = sizeof(outData.pl),
  106. .dataMaxSize = sizeof(outData.pl),
  107. .dataOffset = offsetof(struct outData_t, pl)
  108. },
  109. [SFO_ENT_TITLE] = {
  110. .keyOffset = offsetof(struct outKeys_t, title),
  111. .dataType = SFO_DATATYPE_UTF8,
  112. .dataMaxSize = sizeof(outData.title),
  113. .dataOffset = offsetof(struct outData_t, title)
  114. },
  115. [SFO_ENT_TITLE_ID] = {
  116. .keyOffset = offsetof(struct outKeys_t, titleId),
  117. .dataType = SFO_DATATYPE_UTF8,
  118. .dataMaxSize = sizeof(outData.titleId),
  119. .dataOffset = offsetof(struct outData_t, titleId)
  120. },
  121. [SFO_ENT_VERSION] = {
  122. .keyOffset = offsetof(struct outKeys_t, ver),
  123. .dataType = SFO_DATATYPE_UTF8,
  124. .dataMaxSize = sizeof(outData.ver),
  125. .dataOffset = offsetof(struct outData_t, ver)
  126. }
  127. };
  128.  
  129. static const struct sfoHdr outHdr = {
  130. .magic = PSF_MAGIC,
  131. .ver = 0x0101,
  132. .keyOffset = sizeof(outHdr) + sizeof(outEnt),
  133. .dataOffset = sizeof(outHdr) + sizeof(outEnt) + sizeof(outKeys),
  134. .num = sizeof(outEnt) / sizeof(struct sfoEnt)
  135. };
  136.  
  137. int main(int argc, char *argv[])
  138. {
  139. struct sfoHdr hdr;
  140. struct sfoEnt ent;
  141. uint32_t *dataSize;
  142. size_t size;
  143. FILE *fp;
  144. char key[15];
  145. long offset;
  146. void *p;
  147.  
  148. if (argc != 3) {
  149. printf("Usage: %s <INPUT.SFO> <OUTPUT.SFO>\n", argv[0]);
  150. return EINVAL;
  151. }
  152.  
  153. fp = fopen(argv[1], "rb");
  154. if (fp < 0) {
  155. perror(argv[1]);
  156. return errno;
  157. }
  158.  
  159. if (fread(&hdr, sizeof(hdr), 1, fp) <= 0) {
  160. perror(argv[1]);
  161. return errno;
  162. }
  163.  
  164. if (hdr.magic != PSF_MAGIC) {
  165. printf("%s: Invalid Magic\n", argv[1]);
  166. return EILSEQ;
  167. }
  168.  
  169. for (offset = sizeof(hdr);
  170. offset < sizeof(hdr) + sizeof(ent) * hdr.num;
  171. offset += sizeof(ent))
  172. {
  173. if (fseek(fp, offset, SEEK_SET)) {
  174. perror(argv[1]);
  175. return errno;
  176. }
  177.  
  178. if (fread(&ent, sizeof(ent), 1, fp) <= 0) {
  179. perror(argv[1]);
  180. return errno;
  181. }
  182.  
  183. if (fseek(fp, hdr.keyOffset + ent.keyOffset, SEEK_SET)) {
  184. perror(argv[1]);
  185. return errno;
  186. }
  187.  
  188. if (fread(key, sizeof(key), 1, fp) <= 0) {
  189. perror(argv[1]);
  190. return errno;
  191. }
  192.  
  193. if (!strcmp(key, "DISC_ID")) {
  194. p = outData.titleId;
  195. size = sizeof(outData.titleId);
  196. dataSize = &outEnt[SFO_ENT_TITLE_ID].dataSize;
  197. } else if (!strcmp(key, "DISC_VERSION")) {
  198. p = outData.ver;
  199. size = sizeof(outData.ver);
  200. dataSize = &outEnt[SFO_ENT_VERSION].dataSize;
  201. } else if (!strcmp(key, "TITLE")) {
  202. p = outData.title;
  203. size = sizeof(outData.title);
  204. dataSize = &outEnt[SFO_ENT_TITLE].dataSize;
  205. } else
  206. continue;
  207.  
  208. if (fseek(fp, hdr.dataOffset + ent.dataOffset, SEEK_SET)) {
  209. perror(argv[1]);
  210. return errno;
  211. }
  212.  
  213. if (fread(p, size, 1, fp) <= 0) {
  214. perror(argv[1]);
  215. return errno;
  216. }
  217.  
  218. *dataSize = strlen(p);
  219. if (*dataSize > size) {
  220. printf("%s: %s is too long\n", argv[1], key);
  221. return EILSEQ;
  222. }
  223. }
  224.  
  225. if (fclose(fp))
  226. perror(argv[1]);
  227.  
  228. fp = fopen(argv[2], "w");
  229. if (fp < 0) {
  230. perror(argv[2]);
  231. return errno;
  232. }
  233.  
  234. if (fwrite(&outHdr, sizeof(outHdr), 1, fp) != 1) {
  235. perror(argv[2]);
  236. return errno;
  237. }
  238. if (fwrite(&outEnt, sizeof(outEnt), 1, fp) != 1) {
  239. perror(argv[2]);
  240. return errno;
  241. }
  242. if (fwrite(&outKeys, sizeof(outKeys), 1, fp) != 1) {
  243. perror(argv[2]);
  244. return errno;
  245. }
  246. if (fwrite(&outData, sizeof(outData), 1, fp) != 1) {
  247. perror(argv[2]);
  248. return errno;
  249. }
  250.  
  251. if (fclose(fp)) {
  252. perror(argv[2]);
  253. return errno;
  254. }
  255.  
  256. return 0;
  257. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement