1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - tools - buryarg.TWL
3 File: buryarg.c
4
5 Copyright 2008-2009 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2009-06-17#$
14 $Rev: 10762 $
15 $Author: mizutani_nakaba $
16 *---------------------------------------------------------------------------*/
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <sys/fcntl.h>
22 #include <sys/stat.h>
23 #include <getopt.h>
24
25 #include <nitro_win32.h>
26
27 //---- Error code
28 #define ERROR_OVER_AREA 0
29 #define ERROR_NO_FILE 1
30 #define ERROR_CANNOT_OPEN_FILE 2
31 #define ERROR_CANNOT_OPEN_REP_FILE 3
32 #define ERROR_MARK_NOT_FOUND 4
33 #define ERROR_BAD_MARK_POSITION 5
34 #define ERROR_BAD_ARGUMENT_SIZE 6
35 #define ERROR_UNKNOWN_OPTION 7
36 #define ERROR_OUTFILE_NOT_SPECIFIED 8
37 #define ERROR_REPLACEMENTFILE_NOT_SPECIFIED 9
38 #define ERROR_REPLACEMENTFILE_TOO_BIG 10
39 #define ERROR_ILLEGAL_OPTIONS 11
40 #define ERROR_FILE_ERROR 12
41 #define ERROR_NLF_FILE_SPECIFIED 13
42 #define ERROR_NOT_TWL_SRL 14
43 #define ERROR_ILLEGAL_TLF_FILE 15
44
45 //---- Version
46 #define VERSION_STRING " 1.2 Copyright 2008 Nintendo. All right reserved."
47 // Version 1.2: Changed argument data position to same position as buryarg
48 // Version 1.1: Fixed bug on --stdout option
49 // Version 1.0: Applied for TWL
50
51 //---- Output default added string
52 #define ADDED_OUTPUT_NAME ".argAdded"
53
54 //---- Output for stdout
55 const char gNameForStdout[] = "-";
56
57 //---- Argument buffer identification string
58 const char gArgIdString[] = OS_ARGUMENT_ID_STRING;
59
60 //---- Input bin file
61 #define FILE_NAME_MAX_SIZE 1024
62 FILE *gInputFile;
63 char gInputFileNameString[FILE_NAME_MAX_SIZE];
64 BOOL gIsInputFileOpened = FALSE;
65
66 //---- Output file
67 FILE *gOutputFile;
68 char gOutputFileNameString[FILE_NAME_MAX_SIZE];
69 char *gOutputFileName = NULL;
70 BOOL gIsOutputFileOpened = FALSE;
71
72 //---- Replacement file
73 FILE *gReplacementFile;
74 char *gReplacementFileName = NULL;
75 BOOL gIsReplacementFileOpened = FALSE;
76
77 //---- TLF file
78 FILE *gTlfFile;
79 char *gTlfFileName = NULL;
80 BOOL gIsTlfFileOpened = FALSE;
81 char gTlfDirectoryNameString[FILE_NAME_MAX_SIZE];
82
83 //---- Argument buffer for replacement
84 #define ARGUMENT_BUF_SIZE 0x10000
85 char gArgString[ARGUMENT_BUF_SIZE];
86 int gArgStringSize;
87 int gArgStringIndex = 0;
88
89 //---- Mode
90 BOOL gQuietMode = FALSE;
91 BOOL gVerboseMode = FALSE;
92 BOOL gReplacementMode = TRUE;
93 BOOL gDebugMode = FALSE;
94 BOOL gTlfInputMode = FALSE;
95 BOOL gStdoutMode = FALSE;
96
97 //---- Declaration of prototype
98 void analyzeTlfFile(void);
99 void closeFiles(void);
100
101 //================================================================================
102 // Message display
103 //================================================================================
104 /*---------------------------------------------------------------------------*
105 Name: displayMessage
106
107 Description: Displays message.
108
109 Arguments: message: Message array
110
111 Returns: None.
112 *---------------------------------------------------------------------------*/
displayMessage(char * message[])113 void displayMessage(char *message[])
114 {
115 int n;
116 //---- Show help messages
117 for (n = 0; message[n]; n++)
118 {
119 printf(message[n]);
120 }
121 }
122
123
124 /*---------------------------------------------------------------------------*
125 Name: displayUsage
126
127 Description: Displays how to use.
128
129 Arguments: None.
130
131 Returns: None.
132 *---------------------------------------------------------------------------*/
displayUsage(void)133 void displayUsage(void)
134 {
135 char *usageString[] = {
136 "Usage: buryarg.TWL [OPTION]... <TWL srl filename> [argument]...\n",
137 "Bury argument strings to TWL srl file.",
138 "\n",
139 "Options:\n",
140 " --version : Show version.\n",
141 " -h, --help : Show this help.\n",
142 " -q, --quiet : Quiet mode.\n",
143 " -v, --verbose : Verbose mode.\n",
144 " -r, --remain : Remain original file.\n",
145 " -o, --output=FILE : Output file (default: srcfile.argAdded)\n",
146 " if \"-\" is specified, output to stdout.\n",
147 " --stdout : Mean '-o-' .\n",
148 " -f, --file=FILE : Specify replacement buffer data.\n",
149 " This is used instead of data from arguments.\n",
150 " -d, --debug : Debug mode. Show replacement buffer.\n",
151 0
152 };
153
154 displayMessage(usageString);
155 }
156
157 /*---------------------------------------------------------------------------*
158 Name: displayVersion
159
160 Description: Displays version.
161
162 Arguments: None.
163
164 Returns: None.
165 *---------------------------------------------------------------------------*/
displayVersion(void)166 void displayVersion(void)
167 {
168 printf("buryarg %s\n", VERSION_STRING);
169 }
170
171 /*---------------------------------------------------------------------------*
172 Name: displayError
173
174 Description: Displays error
175
176 Arguments: errorNumber: Error number
177
178 Returns: None.
179 *---------------------------------------------------------------------------*/
displayError(int errorNumber)180 void displayError(int errorNumber)
181 {
182 fprintf(stderr, "Error: buryarg: ");
183
184 switch (errorNumber)
185 {
186 case ERROR_OVER_AREA:
187 fprintf(stderr, "arguments too long.\n");
188 break;
189
190 case ERROR_NO_FILE:
191 fprintf(stderr, "cannot open binary file.\n");
192 break;
193
194 case ERROR_CANNOT_OPEN_FILE:
195 fprintf(stderr, "cannot open output file.\n");
196 break;
197
198 case ERROR_CANNOT_OPEN_REP_FILE:
199 fprintf(stderr, "cannot open replacement file.\n");
200 break;
201
202 case ERROR_MARK_NOT_FOUND:
203 fprintf(stderr, "cannot replace because bin file has no argument id string.\n");
204 break;
205
206 case ERROR_BAD_MARK_POSITION:
207 fprintf(stderr, "bad argument mark position.\n");
208 break;
209
210 case ERROR_BAD_ARGUMENT_SIZE:
211 fprintf(stderr, "bad argument size.\n");
212 break;
213
214 case ERROR_UNKNOWN_OPTION:
215 fprintf(stderr, "unknown option or invalid usage. try --help.\n");
216 break;
217
218 case ERROR_OUTFILE_NOT_SPECIFIED:
219 fprintf(stderr, "output file is not specified.\n");
220 break;
221
222 case ERROR_REPLACEMENTFILE_NOT_SPECIFIED:
223 fprintf(stderr, "replacement file is not specified.\n");
224 break;
225
226 case ERROR_REPLACEMENTFILE_TOO_BIG:
227 fprintf(stderr, "replacement file is too big.\n");
228 break;
229
230 case ERROR_ILLEGAL_OPTIONS:
231 fprintf(stderr, "specified illegal option set.\n");
232 break;
233
234 case ERROR_FILE_ERROR:
235 fprintf(stderr, "error occurred in renaming file.\n");
236 break;
237
238 case ERROR_NLF_FILE_SPECIFIED:
239 fprintf(stderr, "cannot access to nlf file.\n");
240 break;
241
242 case ERROR_NOT_TWL_SRL:
243 fprintf(stderr, "ROM is not for TWL.\n");
244 break;
245
246 case ERROR_ILLEGAL_TLF_FILE:
247 fprintf(stderr, "illegal tlf file.\n");
248 break;
249
250 default:
251 fprintf(stderr, "unknown error (%d).\n", errorNumber);
252 break;
253 }
254
255 closeFiles();
256 exit(2);
257 }
258
259
260 //================================================================================
261 // Display for debug
262 //================================================================================
263 //---- For debug
264 // Display buffer
displayBuffer(void)265 void displayBuffer(void)
266 {
267 const int showSize = 256;
268 int n;
269
270 for (n = 0; n < showSize; n++)
271 {
272 int k = n % 16;
273 int c;
274
275 if (k == 0)
276 {
277 printf("%4x ", n);
278 }
279
280 c = (int)gArgString[n];
281
282 if (0x20 <= c && c <= 0x7f)
283 {
284 printf("%c ", gArgString[n]);
285 }
286 else if (c == 0)
287 {
288 printf(". ");
289 }
290 else
291 {
292 printf("- ");
293 }
294
295 if (k == 15)
296 {
297 printf("\n");
298 }
299 }
300 }
301
302
303 //================================================================================
304 // Parse filename
305 //================================================================================
306 /*---------------------------------------------------------------------------*
307 Name: getTailFileName
308
309 Description: Searches for tail pointer of filename.
310 Example: If d:/aaa/bbb.srl was input, outputs bbb.srl.
311
312 Arguments: fileName: Filename
313
314 Returns: Tail pointer of original string.
315 *---------------------------------------------------------------------------*/
getTailFileName(const char * fileName)316 const char *getTailFileName(const char *fileName)
317 {
318 const char *p = fileName;
319 const char *tailPtr = p;
320
321 while (*p)
322 {
323 if (*p == '\\' || *p == '/' || *p == ':')
324 {
325 tailPtr = (p + 1);
326 }
327
328 p++;
329 }
330
331 return tailPtr;
332 }
333
334 //================================================================================
335 // Option parse and buffer creation
336 //================================================================================
337 /*---------------------------------------------------------------------------*
338 Name: checkOverBuffer
339
340 Description: Checks if buffer is over.
341 (If error occurred, never return.)
342
343 Arguments: None.
344
345 Returns: None.
346 *---------------------------------------------------------------------------*/
checkOverBuffer(void)347 void checkOverBuffer(void)
348 {
349 if (gArgStringIndex >= ARGUMENT_BUF_SIZE)
350 {
351 displayError(ERROR_OVER_AREA);
352 }
353 }
354
355 /*---------------------------------------------------------------------------*
356 Name: addString
357
358 Description: Adds string to TWL argument string area.
359
360 Arguments: str: String to add
361
362 Returns: None.
363 *---------------------------------------------------------------------------*/
addString(const char * str)364 void addString(const char *str)
365 {
366 const char *p = str;
367
368 if (!str)
369 {
370 printf("internal error: tend to add NULL string.\n");
371 exit(2);
372 }
373
374 while (*p)
375 {
376 checkOverBuffer();
377 gArgString[gArgStringIndex++] = *p++;
378 }
379
380 checkOverBuffer();
381 gArgString[gArgStringIndex++] = '\0';
382 }
383
384 /*---------------------------------------------------------------------------*
385 Name: checkTwlHeader
386
387 Description: Checks if the specified ROM is for TWL.
388
389 Arguments: None.
390
391 Returns: None.
392 *---------------------------------------------------------------------------*/
393 #define ROM_TYPE_OFS 12
checkTwlHeader(void)394 void checkTwlHeader(void)
395 {
396 const int readSize=32;
397 char romHeader[readSize];
398 int romType;
399
400 fseek(gTlfFile, 0, SEEK_SET);
401 size_t size = fread(romHeader, 1, readSize, gTlfFile);
402
403 romType = (int)romHeader[ ROM_TYPE_OFS ];
404
405 if (size != readSize || !(romType & 0x2) )
406 {
407 displayError(ERROR_NOT_TWL_SRL);
408 }
409 }
410
411 /*---------------------------------------------------------------------------*
412 Name: parseOption
413
414 Description: Parses the option line.
415
416 Arguments: argc: Argument count
417 argv: Argument vector
418
419 Returns: Result. Less than 0 if error.
420 *---------------------------------------------------------------------------*/
parseOption(int argc,char * argv[])421 void parseOption(int argc, char *argv[])
422 {
423 int n;
424 BOOL helpFlag = FALSE;
425
426 int c;
427
428 struct option optionInfo[] = {
429 {"help", no_argument, NULL, 'h'},
430 {"quiet", no_argument, NULL, 'q'},
431 {"verbose", no_argument, NULL, 'v'},
432 {"replacement", no_argument, NULL, 'r'},
433 {"version", no_argument, NULL, 'a'},
434 {"debug", no_argument, NULL, 'd'},
435 {"output", required_argument, 0, 'o'},
436 {"stdout", no_argument, NULL, 'O'},
437 {"file", required_argument, 0, 'f'},
438 {NULL, 0, 0, 0}
439 };
440 int optionIndex;
441
442 //---- Suppress error string of getopt_long()
443 opterr = 0;
444
445 while (1)
446 {
447 c = getopt_long(argc, argv, "+hqvrdo:f:", &optionInfo[0], &optionIndex);
448
449 //printf("optind=%d optopt=%d %x(%c) \n", optind, optopt, c,c );
450
451 if (c == -1)
452 {
453 break;
454 }
455
456 switch (c)
457 {
458 case 'h':
459 helpFlag = TRUE;
460 break;
461 case 'q':
462 gQuietMode = TRUE;
463 break;
464 case 'v':
465 gVerboseMode = TRUE;
466 break;
467 case 'r':
468 gReplacementMode = FALSE;
469 break;
470 case 'd':
471 gDebugMode = TRUE;
472 break;
473 case 'a':
474 displayVersion();
475 exit(1);
476 break;
477 case 'o':
478 gOutputFileName = (*optarg == '=') ? optarg + 1 : optarg;
479 if (!*gOutputFileName)
480 {
481 displayError(ERROR_OUTFILE_NOT_SPECIFIED);
482 }
483 gReplacementMode = FALSE;
484 break;
485 case 'O':
486 gOutputFileName = (char *)gNameForStdout;
487 gReplacementMode = FALSE;
488 break;
489 case 'f':
490 gReplacementFileName = (*optarg == '=') ? optarg + 1 : optarg;
491 if (!*gReplacementFileName)
492 {
493 displayError(ERROR_REPLACEMENTFILE_NOT_SPECIFIED);
494 }
495 break;
496 default:
497 displayError(ERROR_UNKNOWN_OPTION);
498 }
499 }
500
501 //---- No specified bin file or "-h" of "--help" to display usage
502 if (helpFlag || argc <= optind)
503 {
504 displayUsage();
505 exit(1);
506 }
507
508 //---- Input filename
509 strncpy(gInputFileNameString, argv[optind], FILE_NAME_MAX_SIZE);
510
511 //---- Check if TLF file
512 if ((gTlfFile = fopen(gInputFileNameString, "rb")) == NULL)
513 {
514 displayError(ERROR_NO_FILE);
515 }
516 gIsTlfFileOpened = TRUE;
517
518 //---- Check NLF and TLF ID string
519 {
520 char idString[4];
521 size_t size = fread(idString, 1, 4, gTlfFile);
522 if (size == 4 && !strncmp(idString, (char *)"#NLF", 4))
523 {
524 displayError(ERROR_NLF_FILE_SPECIFIED);
525 }
526
527 if (size == 4 && !strncmp(idString, (char *)"#TLF", 4))
528 {
529 gTlfFileName = argv[optind];
530
531 //---- Determine input filename
532 analyzeTlfFile();
533 }
534 }
535
536 //---- Check if TWL header
537 if (gTlfFileName == NULL)
538 {
539 checkTwlHeader();
540 }
541
542 //---- Close file
543 fclose(gTlfFile);
544 gIsTlfFileOpened = FALSE;
545
546 //---- Add string to replacement buffer
547 for (n = optind; n < argc; n++)
548 {
549 if (n == optind)
550 {
551 if (!gTlfFileName)
552 {
553 addString(getTailFileName(argv[n]));
554 }
555 }
556 else
557 {
558 addString(argv[n]);
559 }
560 }
561
562 //---- End mark
563 checkOverBuffer();
564 gArgString[gArgStringIndex++] = '\0';
565 }
566
567 //================================================================================
568 // File operations
569 //================================================================================
570 /*---------------------------------------------------------------------------*
571 Name: analyzeTlfFile
572
573 Description: Analyzes TLF file.
574
575 Arguments: None.
576
577 Returns: None.
578 *---------------------------------------------------------------------------*/
analyzeTlfFile(void)579 void analyzeTlfFile(void)
580 {
581 char lineBuffer[1024];
582 BOOL isFound_T = FALSE;
583 BOOL isFound_9 = FALSE;
584
585 fseek(gTlfFile, 0, SEEK_SET);
586
587 //---- Analyze
588 while (fgets(lineBuffer, 1024, gTlfFile))
589 {
590 if (!strncmp(lineBuffer, "T,", 2))
591 {
592 char *sp = &lineBuffer[0];
593 char *dp = &gTlfDirectoryNameString[0];
594
595 while (*sp++ != '\"')
596 {
597 }
598 while (*sp != '\"')
599 {
600 *dp++ = *sp++;
601 }
602 *dp = '\0';
603
604 isFound_T = TRUE;
605 }
606
607 if (!strncmp(lineBuffer, "9,", 2) && isFound_T)
608 {
609 char *sp = &lineBuffer[0];
610 char *dp = &gInputFileNameString[0];
611 int count=0;
612
613 while (*sp && count <=2)
614 {
615 if (*sp++ == '\"')
616 {
617 count++;
618 }
619 }
620 while (*sp != '\"')
621 {
622 *dp++ = *sp++;
623 }
624 *dp = '\0';
625
626 //---- Set argv[0]
627 addString(getTailFileName(gInputFileNameString));
628
629 isFound_9 = TRUE;
630 }
631 }
632
633 //---- Check if found filename
634 if (!isFound_9)
635 {
636 displayError(ERROR_ILLEGAL_TLF_FILE);
637 }
638 }
639
640 /*---------------------------------------------------------------------------*
641 Name: openFiles
642
643 Description: Opens original file and output file.
644
645 Arguments: None.
646
647 Returns: None.
648 *---------------------------------------------------------------------------*/
openFiles(void)649 void openFiles(void)
650 {
651 //---- Replacement file
652 if (gReplacementFileName)
653 {
654 if (gVerboseMode)
655 {
656 printf("replacement file : %s\n", gReplacementFileName);
657 }
658 if ((gReplacementFile = fopen(gReplacementFileName, "rb")) == NULL)
659 {
660 displayError(ERROR_CANNOT_OPEN_REP_FILE);
661 }
662 gIsReplacementFileOpened = TRUE;
663
664 //---- Replace buffer
665 {
666 int n;
667 int c;
668
669 if (gVerboseMode)
670 {
671 struct stat repFileStat;
672 stat(gReplacementFileName, &repFileStat);
673 printf("replacement file size is 0x%x byte (%d byte).\n", (int)repFileStat.st_size,
674 (int)repFileStat.st_size);
675 }
676
677 //---- Clear buffer
678 for (n = 0; n < ARGUMENT_BUF_SIZE; n++)
679 {
680 gArgString[n] = 0;
681 }
682
683 //---- Get replacement strings
684 n = 0;
685 while (n < ARGUMENT_BUF_SIZE && (c = fgetc(gReplacementFile)) != EOF)
686 {
687 gArgString[n] = c;
688 n++;
689 }
690 fclose(gReplacementFile);
691 gIsReplacementFileOpened = FALSE;
692
693 //---- Check over buffer
694 if (c != EOF)
695 {
696 //displayError( ERROR_REPLACEMENTFILE_TOO_BIG );
697 if (!gQuietMode)
698 {
699 printf("warning: replacement file is bigger than required size.");
700 }
701 }
702 }
703 }
704
705 //---- Do not overwrite original file
706 if (!gReplacementMode)
707 {
708 //---- Written filename
709 if (gOutputFileName)
710 {
711 strncpy(gOutputFileNameString, gOutputFileName, FILE_NAME_MAX_SIZE);
712 }
713 else
714 {
715 strcat(gOutputFileNameString, gInputFileNameString);
716 strncat(gOutputFileNameString, ADDED_OUTPUT_NAME, FILE_NAME_MAX_SIZE);
717 }
718
719 //---- Check if stdout specified
720 if (!strncmp(gOutputFileNameString, "-", 1))
721 {
722 gStdoutMode = TRUE;
723 }
724
725 //---- Output file
726 if (gVerboseMode)
727 {
728 if (gStdoutMode)
729 {
730 printf("destination : stdout\n");
731 }
732 else
733 {
734 printf("destination bin file: %s\n", gOutputFileNameString);
735 }
736 }
737 if (gStdoutMode)
738 {
739 gOutputFile = stdout;
740
741 //---- Set stdout to binary mode
742 _setmode(_fileno(gOutputFile), O_BINARY);
743 }
744 else
745 {
746 if ((gOutputFile = fopen(gOutputFileNameString, "wb")) == NULL)
747 {
748 displayError(ERROR_CANNOT_OPEN_FILE);
749 }
750 gIsOutputFileOpened = TRUE;
751 }
752 }
753
754 //---- Input file
755 if (gTlfFileName)
756 {
757 if (gVerboseMode)
758 {
759 printf("tlf current directory is %s\n", gTlfDirectoryNameString);
760 }
761 //---- Change current directory
762 if (chdir(gTlfDirectoryNameString) != 0)
763 {
764 displayError(ERROR_ILLEGAL_TLF_FILE);
765 }
766 }
767
768
769 if (gVerboseMode)
770 {
771 printf("original bin file : %s\n", gInputFileNameString);
772 }
773 if ((gInputFile = fopen(gInputFileNameString, (gReplacementMode) ? "rb+" : "rb")) == NULL)
774 {
775 displayError(ERROR_NO_FILE);
776 }
777 gIsInputFileOpened = TRUE;
778 }
779
780 /*---------------------------------------------------------------------------*
781 Name: closeFiles
782
783 Description: Closes files.
784
785 Arguments: None.
786
787 Returns: None.
788 *---------------------------------------------------------------------------*/
closeFiles(void)789 void closeFiles(void)
790 {
791 if (gStdoutMode)
792 {
793 //---- Flush stdout
794 fflush(stdout);
795
796 //---- Set stdout to text mode
797 _setmode(_fileno(gOutputFile), O_TEXT);
798 }
799
800 if (gIsInputFileOpened)
801 {
802 fclose(gInputFile);
803 gIsInputFileOpened = FALSE;
804 }
805 if (gIsOutputFileOpened)
806 {
807 fclose(gOutputFile);
808 gIsOutputFileOpened = FALSE;
809 }
810 if (gIsReplacementFileOpened)
811 {
812 fclose(gReplacementFile);
813 gIsReplacementFileOpened = FALSE;
814 }
815 if (gIsTlfFileOpened)
816 {
817 fclose(gTlfFile);
818 gIsTlfFileOpened = FALSE;
819 }
820 }
821
822 //================================================================================
823 // Replace buffer
824 //================================================================================
replaceToSpecifiedString(void)825 void replaceToSpecifiedString(void)
826 {
827 BOOL isFindMark = FALSE;
828 int markIndex = 0;
829 long bufPosition;
830 int n;
831 int inputChar;
832
833 const int markLength = strlen(gArgIdString);
834
835 //---- Search argument identification string in bin file
836 while (1)
837 {
838 if ((inputChar = fgetc(gInputFile)) == EOF)
839 {
840 break;
841 }
842
843 if (inputChar == gArgIdString[markIndex])
844 {
845 markIndex++;
846 if (markIndex == markLength)
847 {
848 long topPosition = ftell(gInputFile) - markLength;
849 bufPosition = topPosition + OS_ARGUMENT_ID_STRING_BUFFER_SIZE + sizeof(u16);
850
851 if (gVerboseMode)
852 {
853 printf("found argument identification string at 0x%x byte from top.\n",
854 (int)topPosition);
855 }
856 isFindMark = TRUE;
857 break;
858 }
859 }
860 else
861 {
862 if (markIndex > 0)
863 {
864 markIndex = 0;
865 if (inputChar == gArgIdString[0])
866 {
867 markIndex++;
868 }
869 }
870 }
871 }
872
873 //---- Check if mark not found
874 if (!isFindMark)
875 {
876 displayError(ERROR_MARK_NOT_FOUND);
877 }
878
879 //---- Position check
880 if (bufPosition < 0)
881 {
882 displayError(ERROR_BAD_MARK_POSITION);
883 }
884
885 //---- Get buffer size
886 fseek(gInputFile, bufPosition - sizeof(u16), SEEK_SET);
887 gArgStringSize = (int)(fgetc(gInputFile) + (fgetc(gInputFile) << 8));
888
889 if (gVerboseMode)
890 {
891 printf("buffer size = 0x%x byte\n", gArgStringSize);
892 }
893
894 if (gArgStringSize < 0 || gArgStringSize > ARGUMENT_BUF_SIZE)
895 {
896 displayError(ERROR_BAD_ARGUMENT_SIZE);
897 }
898
899 //---- Put forced endmark to replace buffer
900 gArgString[gArgStringSize - 2] = '\0';
901 gArgString[gArgStringSize - 1] = '\0';
902
903 //---- Replacement
904 if (gReplacementMode)
905 {
906 fseek(gInputFile, bufPosition, SEEK_SET);
907 for (n = 0; n < gArgStringSize; n++)
908 {
909 fputc(gArgString[n], gInputFile);
910 }
911
912 if (gVerboseMode)
913 {
914 printf("replaced 0x%x byte.\n", (int)gArgStringSize);
915 }
916 }
917 else
918 {
919 fseek(gInputFile, 0, SEEK_SET);
920 n = 0;
921 while ((inputChar = fgetc(gInputFile)) != EOF)
922 {
923 if (bufPosition <= n && n < bufPosition + gArgStringSize)
924 {
925 fputc(gArgString[n - bufPosition], gOutputFile);
926 }
927 else
928 {
929 fputc(inputChar, gOutputFile);
930 }
931
932 n++;
933 }
934
935 if (gVerboseMode)
936 {
937 printf("output 0x%x byte (%d byte).\n", n, n);
938 }
939 }
940 }
941
942 //================================================================================
943 // Main routine
944 //================================================================================
945 /*---------------------------------------------------------------------------*
946 Name: Main
947
948 Description: Main proc.
949
950 Arguments: argc: Argument count
951 argv: Argument vector
952
953 Returns: ---
954 *---------------------------------------------------------------------------*/
main(int argc,char * argv[])955 int main(int argc, char *argv[])
956 {
957 //---- Option parsing
958 parseOption(argc, argv);
959
960 //---- File open
961 openFiles();
962
963 //---- Buffer internal display (for debugging)
964 if (gDebugMode)
965 {
966 displayBuffer();
967 }
968
969 //---- Replacement processing
970 replaceToSpecifiedString();
971
972 //---- File close
973 closeFiles();
974
975 //---- End
976 if (!gQuietMode)
977 {
978 printf("Success.\n");
979 }
980 return 0;
981 }
982