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