2c8995a5f84dde2641f836249da7d2aa851b9e50
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 * Colin Finck <mail@colinfinck.de>
8 * NOTES: The directive file format is similar to the
9 * directive file format used by Microsoft's MAKECAB
11 * CSH 21/03-2001 Created
12 * CSH 15/08-2003 Made it portable
13 * CF 04/05-2007 Made it compatible with 64-bit operating systems
22 #define GetSizeOfFile(handle) _GetSizeOfFile(handle)
23 static LONG
_GetSizeOfFile(FILEHANDLE handle
)
25 ULONG size
= GetFileSize(handle
, NULL
);
26 if (size
== INVALID_FILE_SIZE
)
31 #define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
32 static BOOL
_ReadFileData(FILEHANDLE handle
, void* buffer
, ULONG size
, PULONG bytesread
)
34 return ReadFile(handle
, buffer
, size
, (LPDWORD
)bytesread
, NULL
);
37 #define GetSizeOfFile(handle) _GetSizeOfFile(handle)
38 static LONG
_GetSizeOfFile(FILEHANDLE handle
)
41 fseek(handle
, 0, SEEK_END
);
43 fseek(handle
, 0, SEEK_SET
);
46 #define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
47 static bool _ReadFileData(FILEHANDLE handle
, void* buffer
, ULONG size
, PULONG bytesread
)
49 *bytesread
= fread(buffer
, 1, size
, handle
);
50 return *bytesread
== size
;
56 CDFParser::CDFParser()
58 * FUNCTION: Default constructor
62 DontGenerateInf
= false;
68 CabinetCreated
= false;
70 FolderCreated
= false;
75 MaxDiskSizeAllSet
= false;
76 CabinetNameTemplateSet
= false;
77 DiskLabelTemplateSet
= false;
78 InfFileNameSet
= false;
80 InfModeEnabled
= false;
83 strcpy(FileRelativePath
, "");
86 CDFParser::~CDFParser()
88 * FUNCTION: Default destructor
97 FreeMemory(FileBuffer
);
99 while (CNNext
!= NULL
)
101 CNPrev
= CNNext
->Next
;
106 while (CNNext
!= NULL
)
108 CNPrev
= CNNext
->Next
;
112 DNNext
= MaxDiskSize
;
113 while (DNNext
!= NULL
)
115 DNPrev
= DNNext
->Next
;
120 if (InfFileHandle
!= NULL
)
121 CloseFile(InfFileHandle
);
124 void CDFParser::WriteInfLine(char* InfLine
)
136 if (InfFileHandle
== NULL
)
139 /* FIXME: Use cabinet name with extension .inf */
142 destpath
= GetDestinationPath();
143 if (strlen(destpath
) > 0)
145 strcpy(buf
, destpath
);
146 strcat(buf
, InfFileName
);
149 strcpy(buf
, InfFileName
);
151 /* Create .inf file, overwrite if it already exists */
153 InfFileHandle
= CreateFile(buf
, // Create this file
154 GENERIC_WRITE
, // Open for writing
157 CREATE_ALWAYS
, // Create or overwrite
158 FILE_ATTRIBUTE_NORMAL
, // Normal file
159 NULL
); // No attribute template
160 if (InfFileHandle
== INVALID_HANDLE_VALUE
)
162 DPRINT(MID_TRACE
, ("Error creating '%u'.\n", (UINT
)GetLastError()));
166 InfFileHandle
= fopen(buf
, "wb");
167 if (InfFileHandle
== NULL
)
169 DPRINT(MID_TRACE
, ("Error creating '%i'.\n", errno
));
176 if (!WriteFile(InfFileHandle
, InfLine
, (DWORD
)strlen(InfLine
), (LPDWORD
)&BytesWritten
, NULL
))
178 DPRINT(MID_TRACE
, ("ERROR WRITING '%u'.\n", (UINT
)GetLastError()));
182 if (fwrite(InfLine
, strlen(InfLine
), 1, InfFileHandle
) < 1)
190 if (!WriteFile(InfFileHandle
, eolbuf
, sizeof(eolbuf
), (LPDWORD
)&BytesWritten
, NULL
))
192 DPRINT(MID_TRACE
, ("ERROR WRITING '%u'.\n", (UINT
)GetLastError()));
196 if (fwrite(eolbuf
, 1, sizeof(eolbuf
), InfFileHandle
) < 1)
202 ULONG
CDFParser::Load(char* FileName
)
204 * FUNCTION: Loads a directive file into memory
206 * FileName = Pointer to name of directive file
208 * Status of operation
215 return CAB_STATUS_SUCCESS
;
217 /* Create cabinet file, overwrite if it already exists */
219 FileHandle
= CreateFile(FileName
, // Create this file
220 GENERIC_READ
, // Open for reading
223 OPEN_EXISTING
, // Open the file
224 FILE_ATTRIBUTE_NORMAL
, // Normal file
225 NULL
); // No attribute template
226 if (FileHandle
== INVALID_HANDLE_VALUE
)
227 return CAB_STATUS_CANNOT_OPEN
;
229 FileHandle
= fopen(FileName
, "rb");
230 if (FileHandle
== NULL
)
231 return CAB_STATUS_CANNOT_OPEN
;
234 FileSize
= GetSizeOfFile(FileHandle
);
237 CloseFile(FileHandle
);
238 return CAB_STATUS_CANNOT_OPEN
;
241 FileBufferSize
= (ULONG
)FileSize
;
243 FileBuffer
= (char*)AllocateMemory(FileBufferSize
);
246 CloseFile(FileHandle
);
247 return CAB_STATUS_NOMEMORY
;
250 if (!ReadFileData(FileHandle
, FileBuffer
, FileBufferSize
, &BytesRead
))
252 CloseFile(FileHandle
);
253 FreeMemory(FileBuffer
);
255 return CAB_STATUS_CANNOT_READ
;
258 CloseFile(FileHandle
);
262 DPRINT(MAX_TRACE
, ("File (%u bytes)\n", (UINT
)FileBufferSize
));
264 return CAB_STATUS_SUCCESS
;
268 ULONG
CDFParser::Parse()
270 * FUNCTION: Parses a loaded directive file
272 * Status of operation
279 return CAB_STATUS_NOFILE
;
287 bool WriteLine
= true;
288 while (CurrentToken
!= TokenEnd
)
290 switch (CurrentToken
)
292 case TokenIdentifier
:
296 Status
= PerformCommand();
297 if (Status
== CAB_STATUS_FAILURE
)
303 CurrentToken
= TokenEnd
;
309 CurrentToken
= TokenEnd
;
323 CurrentToken
= TokenEnd
;
333 while (CurrentToken
!= TokenEnd
)
335 switch (CurrentToken
)
338 sprintf(CurrentString
, "%u", (UINT
)CurrentInteger
);
339 case TokenIdentifier
:
344 Status
= PerformCommand();
346 if (Status
== CAB_STATUS_FAILURE
)
348 printf("Directive file contains errors at line %u.\n", (UINT
)CurrentLine
);
349 DPRINT(MID_TRACE
, ("Error while executing command.\n"));
352 if (Status
!= CAB_STATUS_SUCCESS
)
358 Status
= PerformFileCopy();
360 if (Status
!= CAB_STATUS_SUCCESS
)
362 printf("Directive file contains errors at line %u.\n", (UINT
)CurrentLine
);
363 DPRINT(MID_TRACE
, ("Error while copying file.\n"));
366 if (Status
!= CAB_STATUS_SUCCESS
)
375 CurrentToken
= TokenEnd
;
383 printf("Directive file contains errors at line %u.\n", (UINT
)CurrentLine
);
384 DPRINT(MID_TRACE
, ("Token is (%u).\n", (UINT
)CurrentToken
));
385 return CAB_STATUS_SUCCESS
;
394 printf("\nWriting cabinet. This may take a while...\n\n");
398 Status
= WriteDisk(false);
399 if (Status
== CAB_STATUS_SUCCESS
)
400 Status
= CloseDisk();
401 if (Status
!= CAB_STATUS_SUCCESS
)
403 DPRINT(MIN_TRACE
, ("Cannot write disk (%u).\n", (UINT
)Status
));
410 Status
= CloseCabinet();
411 if (Status
!= CAB_STATUS_SUCCESS
)
413 DPRINT(MIN_TRACE
, ("Cannot close cabinet (%u).\n", (UINT
)Status
));
421 return CAB_STATUS_SUCCESS
;
425 void CDFParser::SetFileRelativePath(char* Path
)
427 * FUNCTION: Sets path where files in the .dff is assumed relative to
429 * Path = Pointer to string with path
432 strcpy(FileRelativePath
, Path
);
433 ConvertPath(FileRelativePath
, false);
434 if (strlen(FileRelativePath
) > 0)
435 NormalizePath(FileRelativePath
, MAX_PATH
);
439 bool CDFParser::OnDiskLabel(ULONG Number
, char* Label
)
441 * FUNCTION: Called when a disk needs a label
443 * Number = Cabinet number that needs a label
444 * Label = Pointer to buffer to place label of disk
446 * true if a disk label was returned, false if not
456 DPRINT(MID_TRACE
, ("Giving disk (%u) a label...\n", (UINT
)Number
));
458 if (GetDiskName(&DiskLabel
, Number
, Label
))
461 if (DiskLabelTemplateSet
)
465 for (i
= 0; i
< strlen(DiskLabelTemplate
); i
++)
467 ch
= DiskLabelTemplate
[i
];
470 sprintf(Buffer
, "%u", (UINT
)Number
);
471 strcat(Label
, Buffer
);
472 j
+= (LONG
)strlen(Buffer
);
482 DPRINT(MID_TRACE
, ("Giving disk (%s) as a label...\n", Label
));
491 bool CDFParser::OnCabinetName(ULONG Number
, char* Name
)
493 * FUNCTION: Called when a cabinet needs a name
495 * Number = Disk number that needs a name
496 * Name = Pointer to buffer to place name of cabinet
498 * true if a cabinet name was returned, false if not
501 char Buffer
[MAX_PATH
];
508 DPRINT(MID_TRACE
, ("Giving cabinet (%u) a name...\n", (UINT
)Number
));
510 if (GetDiskName(&CabinetName
, Number
, Buffer
))
512 strcpy(Name
, GetDestinationPath());
513 strcat(Name
, Buffer
);
517 if (CabinetNameTemplateSet
)
519 strcpy(Name
, GetDestinationPath());
520 j
= (LONG
)strlen(Name
);
521 for (i
= 0; i
< strlen(CabinetNameTemplate
); i
++)
523 ch
= CabinetNameTemplate
[i
];
526 sprintf(Buffer
, "%u", (UINT
)Number
);
527 strcat(Name
, Buffer
);
528 j
+= (LONG
)strlen(Buffer
);
538 DPRINT(MID_TRACE
, ("Giving cabinet (%s) as a name...\n", Name
));
546 bool CDFParser::SetDiskName(PCABINET_NAME
*List
, ULONG Number
, char* String
)
548 * FUNCTION: Sets an entry in a list
550 * List = Address of pointer to list
551 * Number = Disk number
552 * String = Pointer to string
554 * false if there was not enough free memory available
562 if (CN
->DiskNumber
== Number
)
564 strcpy(CN
->Name
, String
);
570 CN
= (PCABINET_NAME
)AllocateMemory(sizeof(CABINET_NAME
));
574 CN
->DiskNumber
= Number
;
575 strcpy(CN
->Name
, String
);
584 bool CDFParser::GetDiskName(PCABINET_NAME
*List
, ULONG Number
, char* String
)
586 * FUNCTION: Returns an entry in a list
588 * List = Address of pointer to list
589 * Number = Disk number
590 * String = Address of buffer to copy string to
592 * false if there was not enough free memory available
600 if (CN
->DiskNumber
== Number
)
602 strcpy(String
, CN
->Name
);
612 bool CDFParser::SetDiskNumber(PDISK_NUMBER
*List
, ULONG Number
, ULONG Value
)
614 * FUNCTION: Sets an entry in a list
616 * List = Address of pointer to list
617 * Number = Disk number
618 * Value = Value to set
620 * false if there was not enough free memory available
628 if (DN
->DiskNumber
== Number
)
636 DN
= (PDISK_NUMBER
)AllocateMemory(sizeof(DISK_NUMBER
));
640 DN
->DiskNumber
= Number
;
650 bool CDFParser::GetDiskNumber(PDISK_NUMBER
*List
, ULONG Number
, PULONG Value
)
652 * FUNCTION: Returns an entry in a list
654 * List = Address of pointer to list
655 * Number = Disk number
656 * Value = Address of buffer to place value
658 * true if the entry was found
666 if (DN
->DiskNumber
== Number
)
678 bool CDFParser::DoDiskLabel(ULONG Number
, char* Label
)
680 * FUNCTION: Sets the label of a disk
682 * Number = Disk number
683 * Label = Pointer to label of disk
685 * false if there was not enough free memory available
688 DPRINT(MID_TRACE
, ("Setting label of disk (%u) to '%s'\n", (UINT
)Number
, Label
));
690 return SetDiskName(&DiskLabel
, Number
, Label
);
694 void CDFParser::DoDiskLabelTemplate(char* Template
)
696 * FUNCTION: Sets a disk label template to use
698 * Template = Pointer to disk label template
701 DPRINT(MID_TRACE
, ("Setting disk label template to '%s'\n", Template
));
703 strcpy(DiskLabelTemplate
, Template
);
704 DiskLabelTemplateSet
= true;
708 bool CDFParser::DoCabinetName(ULONG Number
, char* Name
)
710 * FUNCTION: Sets the name of a cabinet
712 * Number = Disk number
713 * Name = Pointer to name of cabinet
715 * false if there was not enough free memory available
718 DPRINT(MID_TRACE
, ("Setting name of cabinet (%u) to '%s'\n", (UINT
)Number
, Name
));
720 return SetDiskName(&CabinetName
, Number
, Name
);
724 void CDFParser::DoCabinetNameTemplate(char* Template
)
726 * FUNCTION: Sets a cabinet name template to use
728 * Template = Pointer to cabinet name template
731 DPRINT(MID_TRACE
, ("Setting cabinet name template to '%s'\n", Template
));
733 strcpy(CabinetNameTemplate
, Template
);
734 CabinetNameTemplateSet
= true;
738 ULONG
CDFParser::DoMaxDiskSize(bool NumberValid
, ULONG Number
)
740 * FUNCTION: Sets the maximum disk size
742 * NumberValid = true if disk number is valid
743 * Number = Disk number
745 * Status of operation
747 * Standard sizes are 2.88M, 1.44M, 1.25M, 1.2M, 720K, 360K, and CDROM
752 if (IsNextToken(TokenInteger
, true))
756 if (IsNextToken(TokenPeriod
, false))
758 if (!IsNextToken(TokenInteger
, false))
759 return CAB_STATUS_FAILURE
;
767 if (CurrentToken
== TokenIdentifier
)
769 switch (CurrentString
[0])
773 return CAB_STATUS_FAILURE
;
782 return CAB_STATUS_FAILURE
;
793 Value
= 1300000; // FIXME: Value?
798 return CAB_STATUS_FAILURE
;
806 return CAB_STATUS_FAILURE
;
809 return CAB_STATUS_FAILURE
;
813 DPRINT(MID_TRACE
, ("Bad suffix (%c)\n", CurrentString
[0]));
814 return CAB_STATUS_FAILURE
;
822 if ((CurrentToken
!= TokenString
) &&
823 (strcasecmp(CurrentString
, "CDROM") != 0))
824 return CAB_STATUS_FAILURE
;
826 Value
= 640*1024*1024; // FIXME: Correct size for CDROM?
830 return (SetDiskNumber(&MaxDiskSize
, Number
, Value
)?
831 CAB_STATUS_SUCCESS
: CAB_STATUS_FAILURE
);
833 MaxDiskSizeAll
= Value
;
834 MaxDiskSizeAllSet
= true;
836 SetMaxDiskSize(Value
);
838 return CAB_STATUS_SUCCESS
;
842 void CDFParser::DoInfFileName(char* FileName
)
844 * FUNCTION: Sets filename of the generated .inf file
846 * FileName = Pointer to .inf filename
849 DPRINT(MID_TRACE
, ("Setting .inf filename to '%s'\n", FileName
));
851 strcpy(InfFileName
, FileName
);
852 InfFileNameSet
= true;
855 ULONG
CDFParser::SetupNewDisk()
857 * FUNCTION: Sets up parameters for a new disk
859 * Status of operation
864 if (!GetDiskNumber(&MaxDiskSize
, GetCurrentDiskNumber(), &Value
))
866 if (MaxDiskSizeAllSet
)
867 Value
= MaxDiskSizeAll
;
871 SetMaxDiskSize(Value
);
873 return CAB_STATUS_SUCCESS
;
877 ULONG
CDFParser::PerformSetCommand()
879 * FUNCTION: Performs a set variable command
881 * Status of operation
885 bool NumberValid
= false;
888 if (!IsNextToken(TokenIdentifier
, true))
889 return CAB_STATUS_FAILURE
;
891 if (strcasecmp(CurrentString
, "DiskLabel") == 0)
892 SetType
= stDiskLabel
;
893 else if (strcasecmp(CurrentString
, "DiskLabelTemplate") == 0)
894 SetType
= stDiskLabelTemplate
;
895 else if (strcasecmp(CurrentString
, "CabinetName") == 0)
896 SetType
= stCabinetName
;
897 else if (strcasecmp(CurrentString
, "CabinetNameTemplate") == 0)
898 SetType
= stCabinetNameTemplate
;
899 else if (strcasecmp(CurrentString
, "MaxDiskSize") == 0)
900 SetType
= stMaxDiskSize
;
901 else if (strcasecmp(CurrentString
, "InfFileName") == 0)
902 SetType
= stInfFileName
;
904 return CAB_STATUS_FAILURE
;
906 if ((SetType
== stDiskLabel
) || (SetType
== stCabinetName
))
908 if (!IsNextToken(TokenInteger
, false))
909 return CAB_STATUS_FAILURE
;
910 Number
= CurrentInteger
;
912 if (!IsNextToken(TokenEqual
, true))
913 return CAB_STATUS_FAILURE
;
915 else if (SetType
== stMaxDiskSize
)
917 if (IsNextToken(TokenInteger
, false))
920 Number
= CurrentInteger
;
925 while (CurrentToken
== TokenSpace
)
927 if (CurrentToken
!= TokenEqual
)
928 return CAB_STATUS_FAILURE
;
931 else if (!IsNextToken(TokenEqual
, true))
932 return CAB_STATUS_FAILURE
;
934 if (SetType
!= stMaxDiskSize
)
936 if (!IsNextToken(TokenString
, true))
937 return CAB_STATUS_FAILURE
;
943 if (!DoDiskLabel(Number
, CurrentString
))
944 DPRINT(MIN_TRACE
, ("Not enough available free memory.\n"));
945 return CAB_STATUS_SUCCESS
;
948 if (!DoCabinetName(Number
, CurrentString
))
949 DPRINT(MIN_TRACE
, ("Not enough available free memory.\n"));
950 return CAB_STATUS_SUCCESS
;
952 case stDiskLabelTemplate
:
953 DoDiskLabelTemplate(CurrentString
);
954 return CAB_STATUS_SUCCESS
;
956 case stCabinetNameTemplate
:
957 DoCabinetNameTemplate(CurrentString
);
958 return CAB_STATUS_SUCCESS
;
961 return DoMaxDiskSize(NumberValid
, Number
);
964 DoInfFileName(CurrentString
);
965 return CAB_STATUS_SUCCESS
;
968 return CAB_STATUS_FAILURE
;
973 ULONG
CDFParser::PerformNewCommand()
975 * FUNCTION: Performs a new disk|cabinet|folder command
977 * Status of operation
983 if (!IsNextToken(TokenIdentifier
, true))
984 return CAB_STATUS_FAILURE
;
986 if (strcasecmp(CurrentString
, "Disk") == 0)
988 else if (strcasecmp(CurrentString
, "Cabinet") == 0)
990 else if (strcasecmp(CurrentString
, "Folder") == 0)
993 return CAB_STATUS_FAILURE
;
1000 Status
= WriteDisk(true);
1001 if (Status
== CAB_STATUS_SUCCESS
)
1002 Status
= CloseDisk();
1003 if (Status
!= CAB_STATUS_SUCCESS
)
1005 DPRINT(MIN_TRACE
, ("Cannot write disk (%u).\n", (UINT
)Status
));
1006 return CAB_STATUS_SUCCESS
;
1008 DiskCreated
= false;
1012 if (Status
!= CAB_STATUS_SUCCESS
)
1014 DPRINT(MIN_TRACE
, ("Cannot create disk (%u).\n", (UINT
)Status
));
1015 return CAB_STATUS_SUCCESS
;
1019 return CAB_STATUS_SUCCESS
;
1024 Status
= WriteDisk(true);
1025 if (Status
== CAB_STATUS_SUCCESS
)
1026 Status
= CloseDisk();
1027 if (Status
!= CAB_STATUS_SUCCESS
)
1029 DPRINT(MIN_TRACE
, ("Cannot write disk (%u).\n", (UINT
)Status
));
1030 return CAB_STATUS_SUCCESS
;
1032 DiskCreated
= false;
1035 Status
= NewCabinet();
1036 if (Status
!= CAB_STATUS_SUCCESS
)
1038 DPRINT(MIN_TRACE
, ("Cannot create cabinet (%u).\n", (UINT
)Status
));
1039 return CAB_STATUS_SUCCESS
;
1043 return CAB_STATUS_SUCCESS
;
1046 Status
= NewFolder();
1047 ASSERT(Status
== CAB_STATUS_SUCCESS
);
1048 return CAB_STATUS_SUCCESS
;
1051 return CAB_STATUS_FAILURE
;
1056 ULONG
CDFParser::PerformInfBeginCommand()
1058 * FUNCTION: Begins inf mode
1060 * Status of operation
1063 InfModeEnabled
= true;
1064 return CAB_STATUS_SUCCESS
;
1068 ULONG
CDFParser::PerformInfEndCommand()
1070 * FUNCTION: Begins inf mode
1072 * Status of operation
1075 InfModeEnabled
= false;
1076 return CAB_STATUS_SUCCESS
;
1080 ULONG
CDFParser::PerformCommand()
1082 * FUNCTION: Performs a command
1084 * Status of operation
1087 if (strcasecmp(CurrentString
, "Set") == 0)
1088 return PerformSetCommand();
1089 if (strcasecmp(CurrentString
, "New") == 0)
1090 return PerformNewCommand();
1091 if (strcasecmp(CurrentString
, "InfBegin") == 0)
1092 return PerformInfBeginCommand();
1093 if (strcasecmp(CurrentString
, "InfEnd") == 0)
1094 return PerformInfEndCommand();
1096 return CAB_STATUS_FAILURE
;
1100 ULONG
CDFParser::PerformFileCopy()
1102 * FUNCTION: Performs a file copy
1104 * Status of operation
1110 char SrcName
[MAX_PATH
];
1111 char DstName
[MAX_PATH
];
1112 char InfLine
[MAX_PATH
];
1114 char BaseFilename
[MAX_PATH
];
1122 while ((i
< LineLength
) &&
1123 ((ch
= Line
[i
]) != ' ') &&
1127 CurrentString
[i
] = ch
;
1130 CurrentString
[i
] = '\0';
1131 CurrentToken
= TokenString
;
1132 CurrentChar
= i
+ 1;
1133 strcpy(BaseFilename
, CurrentString
);
1134 strcat(SrcName
, BaseFilename
);
1139 if (CurrentToken
!= TokenEnd
)
1141 j
= (ULONG
)strlen(CurrentString
); i
= 0;
1142 while ((CurrentChar
+ i
< LineLength
) &&
1143 ((ch
= Line
[CurrentChar
+ i
]) != ' ') &&
1147 CurrentString
[j
+ i
] = ch
;
1150 CurrentString
[j
+ i
] = '\0';
1151 CurrentToken
= TokenString
;
1152 CurrentChar
+= i
+ 1;
1153 strcpy(DstName
, CurrentString
);
1156 // options (it may be empty)
1159 if (CurrentToken
!= TokenEnd
)
1161 j
= (ULONG
)strlen(CurrentString
); i
= 0;
1162 while ((CurrentChar
+ i
< LineLength
) &&
1163 ((ch
= Line
[CurrentChar
+ i
]) != ' ') &&
1167 CurrentString
[j
+ i
] = ch
;
1170 CurrentString
[j
+ i
] = '\0';
1171 CurrentToken
= TokenString
;
1172 CurrentChar
+= i
+ 1;
1173 strcpy(Options
, CurrentString
);
1176 if (!CabinetCreated
)
1178 DPRINT(MID_TRACE
, ("Creating cabinet.\n"));
1180 Status
= NewCabinet();
1181 if (Status
!= CAB_STATUS_SUCCESS
)
1183 DPRINT(MIN_TRACE
, ("Cannot create cabinet (%u).\n", (UINT
)Status
));
1184 printf("Cannot create cabinet.\n");
1185 return CAB_STATUS_FAILURE
;
1187 CabinetCreated
= true;
1189 DPRINT(MID_TRACE
, ("Creating disk.\n"));
1192 if (Status
!= CAB_STATUS_SUCCESS
)
1194 DPRINT(MIN_TRACE
, ("Cannot create disk (%u).\n", (UINT
)Status
));
1195 printf("Cannot create disk.\n");
1196 return CAB_STATUS_FAILURE
;
1202 DPRINT(MID_TRACE
, ("Adding file: '%s' destination: '%s'.\n", SrcName
, DstName
));
1204 Status
= AddFile(SrcName
);
1205 if (Status
== CAB_STATUS_CANNOT_OPEN
)
1207 strcpy(SrcName
, FileRelativePath
);
1208 strcat(SrcName
, BaseFilename
);
1209 Status
= AddFile(SrcName
);
1213 case CAB_STATUS_SUCCESS
:
1214 sprintf(InfLine
, "%s=%s", GetFileName(SrcName
), DstName
);
1215 WriteInfLine(InfLine
);
1218 case CAB_STATUS_CANNOT_OPEN
:
1219 if (strstr(Options
,"optional"))
1221 Status
= CAB_STATUS_SUCCESS
;
1222 printf("Optional file does not exist: %s.\n", SrcName
);
1225 printf("File does not exist: %s.\n", SrcName
);
1229 case CAB_STATUS_NOMEMORY
:
1230 printf("Insufficient memory to add file: %s.\n", SrcName
);
1234 printf("Cannot add file: %s (%u).\n", SrcName
, (UINT
)Status
);
1241 void CDFParser::SkipSpaces()
1243 * FUNCTION: Skips any spaces in the current line
1247 while (CurrentToken
== TokenSpace
)
1252 bool CDFParser::IsNextToken(DFP_TOKEN Token
, bool NoSpaces
)
1254 * FUNCTION: Checks if next token equals Token
1256 * Token = Token to compare with
1257 * SkipSp = true if spaces should be skipped
1259 * false if next token is diffrent from Token
1266 return (CurrentToken
== Token
);
1270 bool CDFParser::ReadLine()
1272 * FUNCTION: Reads the next line into the line buffer
1274 * true if there is a new line, false if not
1280 if (CurrentOffset
>= FileBufferSize
)
1284 while (((j
= CurrentOffset
+ i
) < FileBufferSize
) && (i
< 127) &&
1285 ((ch
= FileBuffer
[j
]) != 0x0D && (ch
= FileBuffer
[j
]) != 0x0A))
1294 if ((FileBuffer
[CurrentOffset
+ i
] == 0x0D) && (FileBuffer
[CurrentOffset
+ i
+ 1] == 0x0A))
1297 CurrentOffset
+= i
+ 1;
1309 void CDFParser::NextToken()
1311 * FUNCTION: Reads the next token from the current line
1317 if (CurrentChar
>= LineLength
)
1319 CurrentToken
= TokenEnd
;
1323 switch (Line
[CurrentChar
])
1327 CurrentToken
= TokenSpace
;
1331 CurrentToken
= TokenSemi
;
1335 CurrentToken
= TokenEqual
;
1339 CurrentToken
= TokenPeriod
;
1343 CurrentToken
= TokenBackslash
;
1348 while ((CurrentChar
+ i
+ 1 < LineLength
) &&
1349 ((ch
= Line
[CurrentChar
+ i
+ 1]) != '"'))
1351 CurrentString
[i
] = ch
;
1354 CurrentString
[i
] = '\0';
1355 CurrentToken
= TokenString
;
1356 CurrentChar
+= i
+ 2;
1361 while ((CurrentChar
+ i
< LineLength
) &&
1362 ((ch
= Line
[CurrentChar
+ i
]) >= '0') && (ch
<= '9'))
1364 CurrentString
[i
] = ch
;
1369 CurrentString
[i
] = '\0';
1370 CurrentInteger
= atoi(CurrentString
);
1371 CurrentToken
= TokenInteger
;
1376 while ((CurrentChar
+ i
< LineLength
) &&
1377 (((ch
= Line
[CurrentChar
+ i
]) >= 'a') && (ch
<= 'z')) ||
1378 ((ch
>= 'A') && (ch
<= 'Z')) || (ch
== '_'))
1380 CurrentString
[i
] = ch
;
1385 CurrentString
[i
] = '\0';
1386 CurrentToken
= TokenIdentifier
;
1390 CurrentToken
= TokenEnd
;