2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS cabinet manager
4 * FILE: tools/cabman/dfp.cpp
5 * PURPOSE: Directive file parser
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * NOTES: The directive file format is similar to the
8 * directive file format used by Microsoft's MAKECAB
10 * CSH 21/03-2001 Created
11 * CSH 15/08-2003 Made it portable
20 #define GetSizeOfFile(handle) _GetSizeOfFile(handle)
21 static long _GetSizeOfFile(FILEHANDLE handle
)
23 unsigned long size
= GetFileSize(handle
, NULL
);
24 if (size
== INVALID_FILE_SIZE
)
30 #define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
31 static bool _ReadFileData(FILEHANDLE handle
, void* buffer
, unsigned long size
, unsigned long* bytesread
)
33 return ReadFile(handle
, buffer
, size
, bytesread
, NULL
);
36 #define GetSizeOfFile(handle) _GetSizeOfFile(handle)
37 static long _GetSizeOfFile(FILEHANDLE handle
)
40 fseek(handle
, 0, SEEK_END
);
42 fseek(handle
, 0, SEEK_SET
);
45 #define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
46 static bool _ReadFileData(FILEHANDLE handle
, void* buffer
, unsigned long size
, unsigned long* bytesread
)
48 *bytesread
= fread(buffer
, 1, size
, handle
);
49 return *bytesread
== size
;
55 CDFParser::CDFParser()
57 * FUNCTION: Default constructor
61 DontGenerateInf
= false;
67 CabinetCreated
= false;
69 FolderCreated
= false;
74 MaxDiskSizeAllSet
= false;
75 CabinetNameTemplateSet
= false;
76 DiskLabelTemplateSet
= false;
77 InfFileNameSet
= false;
79 InfModeEnabled
= false;
82 strcpy(FileRelativePath
, "");
85 CDFParser::~CDFParser()
87 * FUNCTION: Default destructor
96 FreeMemory(FileBuffer
);
98 while (CNNext
!= NULL
) {
99 CNPrev
= CNNext
->Next
;
104 while (CNNext
!= NULL
) {
105 CNPrev
= CNNext
->Next
;
109 DNNext
= MaxDiskSize
;
110 while (DNNext
!= NULL
) {
111 DNPrev
= DNNext
->Next
;
116 if (InfFileHandle
!= NULL
) {
117 CloseFile(InfFileHandle
);
121 void CDFParser::WriteInfLine(char* InfLine
)
127 unsigned long BytesWritten
;
130 if (DontGenerateInf
) {
134 if (InfFileHandle
== NULL
) {
135 if (!InfFileNameSet
) {
136 /* FIXME: Use cabinet name with extension .inf */
140 destpath
= GetDestinationPath();
141 if (strlen(destpath
) > 0) {
142 strcpy(buf
, destpath
);
143 strcat(buf
, InfFileName
);
145 strcpy(buf
, InfFileName
);
148 /* Create .inf file, overwrite if it already exists */
150 InfFileHandle
= CreateFile(buf
, // Create this file
151 GENERIC_WRITE
, // Open for writing
154 CREATE_ALWAYS
, // Create or overwrite
155 FILE_ATTRIBUTE_NORMAL
, // Normal file
156 NULL
); // No attribute template
157 if (InfFileHandle
== INVALID_HANDLE_VALUE
) {
158 DPRINT(MID_TRACE
, ("Error creating '%d'.\n", (unsigned int)GetLastError()));
162 InfFileHandle
= fopen(buf
, "wb");
163 if (InfFileHandle
== NULL
) {
164 DPRINT(MID_TRACE
, ("Error creating '%d'.\n", (unsigned int)errno
));
171 if (!WriteFile(InfFileHandle
, InfLine
, strlen(InfLine
), &BytesWritten
, NULL
)) {
172 DPRINT(MID_TRACE
, ("ERROR WRITING '%d'.\n", (unsigned int)GetLastError()));
176 if (fwrite(InfLine
, strlen(InfLine
), 1, InfFileHandle
) < 1)
184 if (!WriteFile(InfFileHandle
, eolbuf
, sizeof(eolbuf
), &BytesWritten
, NULL
)) {
185 DPRINT(MID_TRACE
, ("ERROR WRITING '%d'.\n", (unsigned int)GetLastError()));
189 if (fwrite(eolbuf
, 1, sizeof(eolbuf
), InfFileHandle
) < 1)
195 unsigned long CDFParser::Load(char* FileName
)
197 * FUNCTION: Loads a directive file into memory
199 * FileName = Pointer to name of directive file
201 * Status of operation
204 unsigned long BytesRead
;
208 return CAB_STATUS_SUCCESS
;
210 /* Create cabinet file, overwrite if it already exists */
212 FileHandle
= CreateFile(FileName
, // Create this file
213 GENERIC_READ
, // Open for reading
216 OPEN_EXISTING
, // Open the file
217 FILE_ATTRIBUTE_NORMAL
, // Normal file
218 NULL
); // No attribute template
219 if (FileHandle
== INVALID_HANDLE_VALUE
)
220 return CAB_STATUS_CANNOT_OPEN
;
222 FileHandle
= fopen(FileName
, "rb");
223 if (FileHandle
== NULL
) {
224 return CAB_STATUS_CANNOT_OPEN
;
228 FileSize
= GetSizeOfFile(FileHandle
);
229 if (FileSize
== -1) {
230 CloseFile(FileHandle
);
231 return CAB_STATUS_CANNOT_OPEN
;
234 FileBufferSize
= (unsigned long)FileSize
;
236 FileBuffer
= (char*)AllocateMemory(FileBufferSize
);
238 CloseFile(FileHandle
);
239 return CAB_STATUS_NOMEMORY
;
242 if (!ReadFileData(FileHandle
, FileBuffer
, FileBufferSize
, &BytesRead
)) {
243 CloseFile(FileHandle
);
244 FreeMemory(FileBuffer
);
246 return CAB_STATUS_CANNOT_READ
;
249 CloseFile(FileHandle
);
253 DPRINT(MAX_TRACE
, ("File (%lu bytes)\n", FileBufferSize
));
255 return CAB_STATUS_SUCCESS
;
259 unsigned long CDFParser::Parse()
261 * FUNCTION: Parses a loaded directive file
263 * Status of operation
267 unsigned long Status
;
270 return CAB_STATUS_NOFILE
;
275 if (InfModeEnabled
) {
276 bool WriteLine
= true;
277 while (CurrentToken
!= TokenEnd
) {
278 switch (CurrentToken
) {
279 case TokenIdentifier
:
282 Status
= PerformCommand();
283 if (Status
== CAB_STATUS_FAILURE
) {
286 if (!InfModeEnabled
) {
290 CurrentToken
= TokenEnd
;
294 CurrentToken
= TokenEnd
;
305 CurrentToken
= TokenEnd
;
314 while (CurrentToken
!= TokenEnd
) {
315 switch (CurrentToken
) {
317 sprintf(CurrentString
, "%lu", CurrentInteger
);
318 case TokenIdentifier
:
322 Status
= PerformCommand();
324 if (Status
== CAB_STATUS_FAILURE
) {
325 printf("Directive file contains errors at line %d.\n", (unsigned int)CurrentLine
);
326 DPRINT(MID_TRACE
, ("Error while executing command.\n"));
329 if (Status
!= CAB_STATUS_SUCCESS
)
333 Status
= PerformFileCopy();
335 if (Status
== CAB_STATUS_FAILURE
) {
336 printf("Directive file contains errors at line %d.\n", (unsigned int)CurrentLine
);
337 DPRINT(MID_TRACE
, ("Error while copying file.\n"));
340 if (Status
!= CAB_STATUS_SUCCESS
)
347 CurrentToken
= TokenEnd
;
353 printf("Directive file contains errors at line %d.\n", (unsigned int)CurrentLine
);
354 DPRINT(MID_TRACE
, ("Token is (%d).\n", (unsigned int)CurrentToken
));
355 return CAB_STATUS_SUCCESS
;
363 printf("\nWriting cabinet. This may take a while...\n\n");
366 Status
= WriteDisk(false);
367 if (Status
== CAB_STATUS_SUCCESS
)
368 Status
= CloseDisk();
369 if (Status
!= CAB_STATUS_SUCCESS
) {
370 DPRINT(MIN_TRACE
, ("Cannot write disk (%d).\n", (unsigned int)Status
));
375 if (CabinetCreated
) {
376 Status
= CloseCabinet();
377 if (Status
!= CAB_STATUS_SUCCESS
) {
378 DPRINT(MIN_TRACE
, ("Cannot close cabinet (%d).\n", (unsigned int)Status
));
386 return CAB_STATUS_SUCCESS
;
390 void CDFParser::SetFileRelativePath(char* Path
)
392 * FUNCTION: Sets path where files in the .dff is assumed relative to
394 * Path = Pointer to string with path
397 strcpy(FileRelativePath
, Path
);
398 ConvertPath(FileRelativePath
, false);
399 if (strlen(FileRelativePath
) > 0)
400 NormalizePath(FileRelativePath
, MAX_PATH
);
404 bool CDFParser::OnDiskLabel(unsigned long Number
, char* Label
)
406 * FUNCTION: Called when a disk needs a label
408 * Number = Cabinet number that needs a label
409 * Label = Pointer to buffer to place label of disk
411 * true if a disk label was returned, false if not
421 DPRINT(MID_TRACE
, ("Giving disk (%d) a label...\n", (unsigned int)Number
));
423 if (GetDiskName(&DiskLabel
, Number
, Label
))
426 if (DiskLabelTemplateSet
) {
429 for (i
= 0; i
< strlen(DiskLabelTemplate
); i
++) {
430 ch
= DiskLabelTemplate
[i
];
432 sprintf(Buffer
, "%lu", Number
);
433 strcat(Label
, Buffer
);
442 DPRINT(MID_TRACE
, ("Giving disk (%s) as a label...\n", Label
));
450 bool CDFParser::OnCabinetName(unsigned long Number
, char* Name
)
452 * FUNCTION: Called when a cabinet needs a name
454 * Number = Disk number that needs a name
455 * Name = Pointer to buffer to place name of cabinet
457 * true if a cabinet name was returned, false if not
460 char Buffer
[MAX_PATH
];
467 DPRINT(MID_TRACE
, ("Giving cabinet (%d) a name...\n", (unsigned int)Number
));
469 if (GetDiskName(&CabinetName
, Number
, Buffer
)) {
470 strcpy(Name
, GetDestinationPath());
471 strcat(Name
, Buffer
);
475 if (CabinetNameTemplateSet
) {
476 strcpy(Name
, GetDestinationPath());
478 for (i
= 0; i
< strlen(CabinetNameTemplate
); i
++) {
479 ch
= CabinetNameTemplate
[i
];
481 sprintf(Buffer
, "%lu", Number
);
482 strcat(Name
, Buffer
);
491 DPRINT(MID_TRACE
, ("Giving cabinet (%s) as a name...\n", Name
));
499 bool CDFParser::SetDiskName(PCABINET_NAME
*List
, unsigned long Number
, char* String
)
501 * FUNCTION: Sets an entry in a list
503 * List = Address of pointer to list
504 * Number = Disk number
505 * String = Pointer to string
507 * false if there was not enough free memory available
514 if (CN
->DiskNumber
== Number
) {
515 strcpy(CN
->Name
, String
);
521 CN
= (PCABINET_NAME
)AllocateMemory(sizeof(CABINET_NAME
));
525 CN
->DiskNumber
= Number
;
526 strcpy(CN
->Name
, String
);
535 bool CDFParser::GetDiskName(PCABINET_NAME
*List
, unsigned long Number
, char* String
)
537 * FUNCTION: Returns an entry in a list
539 * List = Address of pointer to list
540 * Number = Disk number
541 * String = Address of buffer to copy string to
543 * false if there was not enough free memory available
550 if (CN
->DiskNumber
== Number
) {
551 strcpy(String
, CN
->Name
);
561 bool CDFParser::SetDiskNumber(PDISK_NUMBER
*List
, unsigned long Number
, unsigned long Value
)
563 * FUNCTION: Sets an entry in a list
565 * List = Address of pointer to list
566 * Number = Disk number
567 * Value = Value to set
569 * false if there was not enough free memory available
576 if (DN
->DiskNumber
== Number
) {
583 DN
= (PDISK_NUMBER
)AllocateMemory(sizeof(DISK_NUMBER
));
587 DN
->DiskNumber
= Number
;
597 bool CDFParser::GetDiskNumber(PDISK_NUMBER
*List
, unsigned long Number
, unsigned long* Value
)
599 * FUNCTION: Returns an entry in a list
601 * List = Address of pointer to list
602 * Number = Disk number
603 * Value = Address of buffer to place value
605 * true if the entry was found
612 if (DN
->DiskNumber
== Number
) {
623 bool CDFParser::DoDiskLabel(unsigned long Number
, char* Label
)
625 * FUNCTION: Sets the label of a disk
627 * Number = Disk number
628 * Label = Pointer to label of disk
630 * false if there was not enough free memory available
633 DPRINT(MID_TRACE
, ("Setting label of disk (%d) to '%s'\n", (unsigned int)Number
, Label
));
635 return SetDiskName(&DiskLabel
, Number
, Label
);
639 void CDFParser::DoDiskLabelTemplate(char* Template
)
641 * FUNCTION: Sets a disk label template to use
643 * Template = Pointer to disk label template
646 DPRINT(MID_TRACE
, ("Setting disk label template to '%s'\n", Template
));
648 strcpy(DiskLabelTemplate
, Template
);
649 DiskLabelTemplateSet
= true;
653 bool CDFParser::DoCabinetName(unsigned long Number
, char* Name
)
655 * FUNCTION: Sets the name of a cabinet
657 * Number = Disk number
658 * Name = Pointer to name of cabinet
660 * false if there was not enough free memory available
663 DPRINT(MID_TRACE
, ("Setting name of cabinet (%d) to '%s'\n", (unsigned int)Number
, Name
));
665 return SetDiskName(&CabinetName
, Number
, Name
);
669 void CDFParser::DoCabinetNameTemplate(char* Template
)
671 * FUNCTION: Sets a cabinet name template to use
673 * Template = Pointer to cabinet name template
676 DPRINT(MID_TRACE
, ("Setting cabinet name template to '%s'\n", Template
));
678 strcpy(CabinetNameTemplate
, Template
);
679 CabinetNameTemplateSet
= true;
683 unsigned long CDFParser::DoMaxDiskSize(bool NumberValid
, unsigned long Number
)
685 * FUNCTION: Sets the maximum disk size
687 * NumberValid = true if disk number is valid
688 * Number = Disk number
690 * Status of operation
692 * Standard sizes are 2.88M, 1.44M, 1.25M, 1.2M, 720K, 360K, and CDROM
695 unsigned long A
, B
, Value
;
697 if (IsNextToken(TokenInteger
, true)) {
701 if (IsNextToken(TokenPeriod
, false)) {
702 if (!IsNextToken(TokenInteger
, false))
703 return CAB_STATUS_FAILURE
;
710 if (CurrentToken
== TokenIdentifier
) {
711 switch (CurrentString
[0]) {
714 return CAB_STATUS_FAILURE
;
723 return CAB_STATUS_FAILURE
;
732 Value
= 1300000; // FIXME: Value?
737 return CAB_STATUS_FAILURE
;
743 return CAB_STATUS_FAILURE
;
745 return CAB_STATUS_FAILURE
;
748 DPRINT(MID_TRACE
, ("Bad suffix (%c)\n", CurrentString
[0]));
749 return CAB_STATUS_FAILURE
;
754 if ((CurrentToken
!= TokenString
) &&
755 (strcasecmp(CurrentString
, "CDROM") != 0))
756 return CAB_STATUS_FAILURE
;
758 Value
= 640*1024*1024; // FIXME: Correct size for CDROM?
762 return (SetDiskNumber(&MaxDiskSize
, Number
, Value
)?
763 CAB_STATUS_SUCCESS
: CAB_STATUS_FAILURE
);
765 MaxDiskSizeAll
= Value
;
766 MaxDiskSizeAllSet
= true;
768 SetMaxDiskSize(Value
);
770 return CAB_STATUS_SUCCESS
;
774 void CDFParser::DoInfFileName(char* FileName
)
776 * FUNCTION: Sets filename of the generated .inf file
778 * FileName = Pointer to .inf filename
781 DPRINT(MID_TRACE
, ("Setting .inf filename to '%s'\n", FileName
));
783 strcpy(InfFileName
, FileName
);
784 InfFileNameSet
= true;
787 unsigned long CDFParser::SetupNewDisk()
789 * FUNCTION: Sets up parameters for a new disk
791 * Status of operation
796 if (!GetDiskNumber(&MaxDiskSize
, GetCurrentDiskNumber(), &Value
)) {
797 if (MaxDiskSizeAllSet
)
798 Value
= MaxDiskSizeAll
;
802 SetMaxDiskSize(Value
);
804 return CAB_STATUS_SUCCESS
;
808 unsigned long CDFParser::PerformSetCommand()
810 * FUNCTION: Performs a set variable command
812 * Status of operation
816 bool NumberValid
= false;
817 unsigned long Number
= 0;
819 if (!IsNextToken(TokenIdentifier
, true))
820 return CAB_STATUS_FAILURE
;
822 if (strcasecmp(CurrentString
, "DiskLabel") == 0)
823 SetType
= stDiskLabel
;
824 else if (strcasecmp(CurrentString
, "DiskLabelTemplate") == 0)
825 SetType
= stDiskLabelTemplate
;
826 else if (strcasecmp(CurrentString
, "CabinetName") == 0)
827 SetType
= stCabinetName
;
828 else if (strcasecmp(CurrentString
, "CabinetNameTemplate") == 0)
829 SetType
= stCabinetNameTemplate
;
830 else if (strcasecmp(CurrentString
, "MaxDiskSize") == 0)
831 SetType
= stMaxDiskSize
;
832 else if (strcasecmp(CurrentString
, "InfFileName") == 0)
833 SetType
= stInfFileName
;
835 return CAB_STATUS_FAILURE
;
837 if ((SetType
== stDiskLabel
) || (SetType
== stCabinetName
)) {
838 if (!IsNextToken(TokenInteger
, false))
839 return CAB_STATUS_FAILURE
;
840 Number
= CurrentInteger
;
842 if (!IsNextToken(TokenEqual
, true))
843 return CAB_STATUS_FAILURE
;
844 } else if (SetType
== stMaxDiskSize
) {
845 if (IsNextToken(TokenInteger
, false)) {
847 Number
= CurrentInteger
;
850 while (CurrentToken
== TokenSpace
)
852 if (CurrentToken
!= TokenEqual
)
853 return CAB_STATUS_FAILURE
;
855 } else if (!IsNextToken(TokenEqual
, true))
856 return CAB_STATUS_FAILURE
;
858 if (SetType
!= stMaxDiskSize
) {
859 if (!IsNextToken(TokenString
, true))
860 return CAB_STATUS_FAILURE
;
865 if (!DoDiskLabel(Number
, CurrentString
))
866 DPRINT(MIN_TRACE
, ("Not enough available free memory.\n"));
867 return CAB_STATUS_SUCCESS
;
869 if (!DoCabinetName(Number
, CurrentString
))
870 DPRINT(MIN_TRACE
, ("Not enough available free memory.\n"));
871 return CAB_STATUS_SUCCESS
;
872 case stDiskLabelTemplate
:
873 DoDiskLabelTemplate(CurrentString
);
874 return CAB_STATUS_SUCCESS
;
875 case stCabinetNameTemplate
:
876 DoCabinetNameTemplate(CurrentString
);
877 return CAB_STATUS_SUCCESS
;
879 return DoMaxDiskSize(NumberValid
, Number
);
881 DoInfFileName(CurrentString
);
882 return CAB_STATUS_SUCCESS
;
884 return CAB_STATUS_FAILURE
;
889 unsigned long CDFParser::PerformNewCommand()
891 * FUNCTION: Performs a new disk|cabinet|folder command
893 * Status of operation
897 unsigned long Status
;
899 if (!IsNextToken(TokenIdentifier
, true))
900 return CAB_STATUS_FAILURE
;
902 if (strcasecmp(CurrentString
, "Disk") == 0)
904 else if (strcasecmp(CurrentString
, "Cabinet") == 0)
906 else if (strcasecmp(CurrentString
, "Folder") == 0)
909 return CAB_STATUS_FAILURE
;
914 Status
= WriteDisk(true);
915 if (Status
== CAB_STATUS_SUCCESS
)
916 Status
= CloseDisk();
917 if (Status
!= CAB_STATUS_SUCCESS
) {
918 DPRINT(MIN_TRACE
, ("Cannot write disk (%d).\n", (unsigned int)Status
));
919 return CAB_STATUS_SUCCESS
;
925 if (Status
!= CAB_STATUS_SUCCESS
) {
926 DPRINT(MIN_TRACE
, ("Cannot create disk (%d).\n", (unsigned int)Status
));
927 return CAB_STATUS_SUCCESS
;
931 return CAB_STATUS_SUCCESS
;
934 Status
= WriteDisk(true);
935 if (Status
== CAB_STATUS_SUCCESS
)
936 Status
= CloseDisk();
937 if (Status
!= CAB_STATUS_SUCCESS
) {
938 DPRINT(MIN_TRACE
, ("Cannot write disk (%d).\n", (unsigned int)Status
));
939 return CAB_STATUS_SUCCESS
;
944 Status
= NewCabinet();
945 if (Status
!= CAB_STATUS_SUCCESS
) {
946 DPRINT(MIN_TRACE
, ("Cannot create cabinet (%d).\n", (unsigned int)Status
));
947 return CAB_STATUS_SUCCESS
;
951 return CAB_STATUS_SUCCESS
;
953 Status
= NewFolder();
954 ASSERT(Status
== CAB_STATUS_SUCCESS
);
955 return CAB_STATUS_SUCCESS
;
957 return CAB_STATUS_FAILURE
;
962 unsigned long CDFParser::PerformInfBeginCommand()
964 * FUNCTION: Begins inf mode
966 * Status of operation
969 InfModeEnabled
= true;
970 return CAB_STATUS_SUCCESS
;
974 unsigned long CDFParser::PerformInfEndCommand()
976 * FUNCTION: Begins inf mode
978 * Status of operation
981 InfModeEnabled
= false;
982 return CAB_STATUS_SUCCESS
;
986 unsigned long CDFParser::PerformCommand()
988 * FUNCTION: Performs a command
990 * Status of operation
993 if (strcasecmp(CurrentString
, "Set") == 0)
994 return PerformSetCommand();
995 if (strcasecmp(CurrentString
, "New") == 0)
996 return PerformNewCommand();
997 if (strcasecmp(CurrentString
, "InfBegin") == 0)
998 return PerformInfBeginCommand();
999 if (strcasecmp(CurrentString
, "InfEnd") == 0)
1000 return PerformInfEndCommand();
1002 return CAB_STATUS_FAILURE
;
1006 unsigned long CDFParser::PerformFileCopy()
1008 * FUNCTION: Performs a file copy
1010 * Status of operation
1013 unsigned long Status
;
1016 char SrcName
[MAX_PATH
];
1017 char DstName
[MAX_PATH
];
1018 char InfLine
[MAX_PATH
];
1019 char BaseFilename
[MAX_PATH
];
1021 strcpy(SrcName
, "");
1022 strcpy(DstName
, "");
1025 while ((i
< LineLength
) &&
1026 ((ch
= Line
[i
]) != ' ') &&
1029 CurrentString
[i
] = ch
;
1032 CurrentString
[i
] = '\0';
1033 CurrentToken
= TokenString
;
1034 CurrentChar
= i
+ 1;
1035 strcpy(BaseFilename
, CurrentString
);
1036 strcat(SrcName
, BaseFilename
);
1040 if (CurrentToken
!= TokenEnd
) {
1041 j
= strlen(CurrentString
); i
= 0;
1042 while ((CurrentChar
+ i
< LineLength
) &&
1043 ((ch
= Line
[CurrentChar
+ i
]) != ' ') &&
1046 CurrentString
[j
+ i
] = ch
;
1049 CurrentString
[j
+ i
] = '\0';
1050 CurrentToken
= TokenString
;
1051 CurrentChar
+= i
+ 1;
1052 strcpy(DstName
, CurrentString
);
1055 if (!CabinetCreated
) {
1057 DPRINT(MID_TRACE
, ("Creating cabinet.\n"));
1059 Status
= NewCabinet();
1060 if (Status
!= CAB_STATUS_SUCCESS
) {
1061 DPRINT(MIN_TRACE
, ("Cannot create cabinet (%d).\n", (unsigned int)Status
));
1062 printf("Cannot create cabinet.\n");
1063 return CAB_STATUS_FAILURE
;
1065 CabinetCreated
= true;
1067 DPRINT(MID_TRACE
, ("Creating disk.\n"));
1070 if (Status
!= CAB_STATUS_SUCCESS
) {
1071 DPRINT(MIN_TRACE
, ("Cannot create disk (%d).\n", (unsigned int)Status
));
1072 printf("Cannot create disk.\n");
1073 return CAB_STATUS_FAILURE
;
1079 DPRINT(MID_TRACE
, ("Adding file: '%s' destination: '%s'.\n", SrcName
, DstName
));
1081 sprintf(InfLine
, "%s=%s", GetFileName(SrcName
), DstName
);
1082 WriteInfLine(InfLine
);
1084 Status
= AddFile(SrcName
);
1085 if (Status
== CAB_STATUS_CANNOT_OPEN
) {
1086 strcpy(SrcName
, FileRelativePath
);
1087 strcat(SrcName
, BaseFilename
);
1088 Status
= AddFile(SrcName
);
1090 if (Status
!= CAB_STATUS_SUCCESS
) {
1091 if (Status
== CAB_STATUS_CANNOT_OPEN
)
1092 printf("File does not exist: %s.\n", SrcName
);
1093 else if (Status
== CAB_STATUS_NOMEMORY
)
1094 printf("Insufficient memory to add file: %s.\n", SrcName
);
1096 printf("Cannot add file: %s (%lu).\n", SrcName
, Status
);
1100 return CAB_STATUS_SUCCESS
;
1104 void CDFParser::SkipSpaces()
1106 * FUNCTION: Skips any spaces in the current line
1110 while (CurrentToken
== TokenSpace
)
1115 bool CDFParser::IsNextToken(DFP_TOKEN Token
, bool NoSpaces
)
1117 * FUNCTION: Checks if next token equals Token
1119 * Token = Token to compare with
1120 * SkipSp = true if spaces should be skipped
1122 * false if next token is diffrent from Token
1129 return (CurrentToken
== Token
);
1133 bool CDFParser::ReadLine()
1135 * FUNCTION: Reads the next line into the line buffer
1137 * true if there is a new line, false if not
1143 if (CurrentOffset
>= FileBufferSize
)
1147 while (((j
= CurrentOffset
+ i
) < FileBufferSize
) && (i
< 127) &&
1148 ((ch
= FileBuffer
[j
]) != 0x0D && (ch
= FileBuffer
[j
]) != 0x0A)) {
1156 if ((FileBuffer
[CurrentOffset
+ i
] == 0x0D) && (FileBuffer
[CurrentOffset
+ i
+ 1] == 0x0A))
1159 CurrentOffset
+= i
+ 1;
1171 void CDFParser::NextToken()
1173 * FUNCTION: Reads the next token from the current line
1179 if (CurrentChar
>= LineLength
) {
1180 CurrentToken
= TokenEnd
;
1184 switch (Line
[CurrentChar
]) {
1186 case 0x09: CurrentToken
= TokenSpace
;
1188 case ';': CurrentToken
= TokenSemi
;
1190 case '=': CurrentToken
= TokenEqual
;
1192 case '.': CurrentToken
= TokenPeriod
;
1194 case '\\': CurrentToken
= TokenBackslash
;
1198 while ((CurrentChar
+ i
+ 1 < LineLength
) &&
1199 ((ch
= Line
[CurrentChar
+ i
+ 1]) != '"')) {
1200 CurrentString
[i
] = ch
;
1203 CurrentString
[i
] = '\0';
1204 CurrentToken
= TokenString
;
1205 CurrentChar
+= i
+ 2;
1209 while ((CurrentChar
+ i
< LineLength
) &&
1210 ((ch
= Line
[CurrentChar
+ i
]) >= '0') && (ch
<= '9')) {
1211 CurrentString
[i
] = ch
;
1215 CurrentString
[i
] = '\0';
1216 CurrentInteger
= atoi((char*)CurrentString
);
1217 CurrentToken
= TokenInteger
;
1222 while (((CurrentChar
+ i
< LineLength
) &&
1223 (((ch
= Line
[CurrentChar
+ i
]) >= 'a') && (ch
<= 'z')) ||
1224 ((ch
>= 'A') && (ch
<= 'Z')) || (ch
== '_'))) {
1225 CurrentString
[i
] = ch
;
1229 CurrentString
[i
] = '\0';
1230 CurrentToken
= TokenIdentifier
;
1234 CurrentToken
= TokenEnd
;