ReactOS  0.4.15-dev-1152-g6c94e4f
dfp.cxx
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS cabinet manager
4  * FILE: tools/cabman/dfp.cxx
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 (But not entirely compatible!)
10  * REVISIONS:
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
14  */
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include "cabman.h"
18 #include "dfp.h"
19 
20 /* CDFParser */
21 
23 /*
24  * FUNCTION: Default constructor
25  */
26 {
27  InfFileOnly = false;
28  DontGenerateInf = false;
29 
30  FileBuffer = NULL;
31  FileLoaded = false;
32  CurrentOffset = 0;
33  CurrentLine = 0;
34  CabinetCreated = false;
35  DiskCreated = false;
36  FolderCreated = false;
37  CabinetName = NULL;
38  DiskLabel = NULL;
39  MaxDiskSize = NULL;
40 
41  MaxDiskSizeAllSet = false;
42  CabinetNameTemplateSet = false;
43  DiskLabelTemplateSet = false;
44  InfFileNameSet = false;
45 
46  InfModeEnabled = false;
48 }
49 
51 /*
52  * FUNCTION: Default destructor
53  */
54 {
55  PCABINET_NAME CNPrev;
56  PCABINET_NAME CNNext;
57  PDISK_NUMBER DNPrev;
58  PDISK_NUMBER DNNext;
59 
60  if (FileBuffer)
62  CNNext = CabinetName;
63  while (CNNext != NULL)
64  {
65  CNPrev = CNNext->Next;
66  delete CNNext;
67  CNNext = CNPrev;
68  }
69  CNNext = DiskLabel;
70  while (CNNext != NULL)
71  {
72  CNPrev = CNNext->Next;
73  delete CNNext;
74  CNNext = CNPrev;
75  }
76  DNNext = MaxDiskSize;
77  while (DNNext != NULL)
78  {
79  DNPrev = DNNext->Next;
80  delete DNNext;
81  DNNext = DNPrev;
82  }
83 
84  if (InfFileHandle != NULL)
86 }
87 
88 void CDFParser::WriteInfLine(char* InfLine)
89 {
90  char buf[PATH_MAX];
91  char eolbuf[2];
92  const char* destpath;
93 
94  if (DontGenerateInf)
95  return;
96 
97  if (InfFileHandle == NULL)
98  {
99  if (!InfFileNameSet)
100  /* FIXME: Use cabinet name with extension .inf */
101  return;
102 
103  destpath = GetDestinationPath();
104  if (strlen(destpath) > 0)
105  {
106  strcpy(buf, destpath);
108  }
109  else
111 
112  /* Create .inf file, overwrite if it already exists */
113  InfFileHandle = fopen(buf, "wb");
114  if (InfFileHandle == NULL)
115  {
116  DPRINT(MID_TRACE, ("Error creating INF file.\n"));
117  return;
118  }
119  }
120 
121  if (fwrite(InfLine, strlen(InfLine), 1, InfFileHandle) < 1)
122  {
123  DPRINT(MID_TRACE, ("Error writing INF file.\n"));
124  return;
125  }
126 
127  eolbuf[0] = 0x0d;
128  eolbuf[1] = 0x0a;
129 
130  if (fwrite(eolbuf, sizeof(eolbuf), 1, InfFileHandle) < 1)
131  {
132  DPRINT(MID_TRACE, ("Error writing INF file.\n"));
133  return;
134  }
135 }
136 
137 
139 /*
140  * FUNCTION: Loads a directive file into memory
141  * ARGUMENTS:
142  * FileName = Pointer to name of directive file
143  * RETURNS:
144  * Status of operation
145  */
146 {
147  LONG FileSize;
148 
149  if (FileLoaded)
150  return CAB_STATUS_SUCCESS;
151 
152  /* Open the directive file */
153  FileHandle = fopen(FileName, "rb");
154  if (FileHandle == NULL)
155  {
156  return CAB_STATUS_CANNOT_OPEN;
157  }
158 
160  if (FileSize == -1)
161  {
163  return CAB_STATUS_CANNOT_OPEN;
164  }
165 
167 
168  FileBuffer = (char*)malloc(FileBufferSize);
169  if (!FileBuffer)
170  {
172  return CAB_STATUS_NOMEMORY;
173  }
174 
175  if ( fread(FileBuffer, FileBufferSize, 1, FileHandle) < 1 )
176  {
178  free(FileBuffer);
179  FileBuffer = NULL;
180  return CAB_STATUS_CANNOT_READ;
181  }
182 
184 
185  FileLoaded = true;
186 
187  DPRINT(MAX_TRACE, ("File (%u bytes)\n", (UINT)FileBufferSize));
188 
189  return CAB_STATUS_SUCCESS;
190 }
191 
192 
194 /*
195  * FUNCTION: Parses a loaded directive file
196  * RETURNS:
197  * Status of operation
198  */
199 {
200  bool Command;
201  ULONG Status;
202 
203  if (!FileLoaded)
204  return CAB_STATUS_NOFILE;
205 
206  while (ReadLine())
207  {
208  Command = false;
209 
210  if (InfModeEnabled)
211  {
212  bool WriteLine = true;
213  while (CurrentToken != TokenEnd)
214  {
215  switch (CurrentToken)
216  {
217  case TokenIdentifier:
218  if (Command)
219  {
220  /* Command */
222  if (Status == CAB_STATUS_FAILURE)
223  WriteLine = true;
224  else
225  if (!InfModeEnabled)
226  WriteLine = false;
227 
229  continue;
230  }
231  else
232  {
233  WriteLine = true;
235  continue;
236  }
237  break;
238 
239  case TokenSpace:
240  break;
241 
242  case TokenPeriod:
243  Command = true;
244  break;
245 
246  default:
247  WriteLine = true;
249  continue;
250  }
251  NextToken();
252  }
253  if (WriteLine)
255  }
256  else
257  {
258  while (CurrentToken != TokenEnd)
259  {
260  switch (CurrentToken)
261  {
262  case TokenInteger:
264  case TokenIdentifier:
265  case TokenString:
266  if (Command)
267  {
268  /* Command */
270 
271  if (Status == CAB_STATUS_FAILURE)
272  {
273  printf("ERROR: Directive file contains errors at line %u.\n", (UINT)CurrentLine);
274  DPRINT(MID_TRACE, ("Error while executing command.\n"));
275  }
276 
277  if (Status != CAB_STATUS_SUCCESS)
278  return Status;
279  }
280  else
281  {
282  /* File copy */
284 
285  if (Status != CAB_STATUS_SUCCESS)
286  {
287  printf("ERROR: Directive file contains errors at line %u.\n", (UINT)CurrentLine);
288  DPRINT(MID_TRACE, ("Error while copying file.\n"));
289  return Status;
290  }
291  }
292  break;
293 
294  case TokenSpace:
295  break;
296 
297  case TokenSemi:
299  continue;
300 
301  case TokenPeriod:
302  Command = true;
303  break;
304 
305  default:
306  printf("ERROR: Directive file contains errors at line %u.\n", (UINT)CurrentLine);
307  DPRINT(MID_TRACE, ("Token is (%u).\n", (UINT)CurrentToken));
308  return CAB_STATUS_SUCCESS;
309  }
310  NextToken();
311  }
312  }
313  }
314 
315  if (!InfFileOnly)
316  {
317  OnVerboseMessage("Writing cabinet. This may take a while...\n");
318 
319  if (DiskCreated)
320  {
321  Status = WriteDisk(false);
322  if (Status == CAB_STATUS_SUCCESS)
323  Status = CloseDisk();
324  if (Status != CAB_STATUS_SUCCESS)
325  {
326  DPRINT(MIN_TRACE, ("Cannot write disk (%u).\n", (UINT)Status));
327  return Status;
328  }
329  }
330 
331  if (CabinetCreated)
332  {
333  Status = CloseCabinet();
334  if (Status != CAB_STATUS_SUCCESS)
335  {
336  DPRINT(MIN_TRACE, ("Cannot close cabinet (%u).\n", (UINT)Status));
337  return Status;
338  }
339  }
340 
341  OnVerboseMessage("Done.\n");
342  }
343 
344  return CAB_STATUS_SUCCESS;
345 }
346 
347 
349 /*
350  * FUNCTION: Sets path where files in the .dff is assumed relative to
351  * ARGUMENTS:
352  * Path = Pointer to string with path
353  */
354 {
358 }
359 
360 
362 /*
363  * FUNCTION: Called when a disk needs a label
364  * ARGUMENTS:
365  * Number = Cabinet number that needs a label
366  * Label = Pointer to buffer to place label of disk
367  * RETURNS:
368  * true if a disk label was returned, false if not
369  */
370 {
371  char Buffer[20];
372  ULONG i;
373  int j;
374  char ch;
375 
376  Number += 1;
377 
378  DPRINT(MID_TRACE, ("Giving disk (%u) a label...\n", (UINT)Number));
379 
381  return true;
382 
384  {
385  j = 0;
386  strcpy(Label, "");
387  for (i = 0; i < strlen(DiskLabelTemplate); i++)
388  {
389  ch = DiskLabelTemplate[i];
390  if (ch == '*')
391  {
392  sprintf(Buffer, "%u", (UINT)Number);
393  strcat(Label, Buffer);
394  j += (LONG)strlen(Buffer);
395  }
396  else
397  {
398  Label[j] = ch;
399  j++;
400  }
401  Label[j] = '\0';
402  }
403 
404  DPRINT(MID_TRACE, ("Giving disk (%s) as a label...\n", Label));
405 
406  return true;
407  }
408  else
409  return false;
410 }
411 
412 
414 /*
415  * FUNCTION: Called when a cabinet needs a name
416  * ARGUMENTS:
417  * Number = Disk number that needs a name
418  * Name = Pointer to buffer to place name of cabinet
419  * RETURNS:
420  * true if a cabinet name was returned, false if not
421  */
422 {
423  char Buffer[PATH_MAX];
424  ULONG i;
425  int j;
426  char ch;
427 
428  Number += 1;
429 
430  DPRINT(MID_TRACE, ("Giving cabinet (%u) a name...\n", (UINT)Number));
431 
433  {
435  strcat(Name, Buffer);
436  return true;
437  }
438 
440  {
442  j = (LONG)strlen(Name);
443  for (i = 0; i < strlen(CabinetNameTemplate); i++)
444  {
445  ch = CabinetNameTemplate[i];
446  if (ch == '*')
447  {
448  sprintf(Buffer, "%u", (UINT)Number);
449  strcat(Name, Buffer);
450  j += (LONG)strlen(Buffer);
451  }
452  else
453  {
454  Name[j] = ch;
455  j++;
456  }
457  Name[j] = '\0';
458  }
459 
460  DPRINT(MID_TRACE, ("Giving cabinet (%s) as a name...\n", Name));
461  return true;
462  }
463  else
464  return false;
465 }
466 
467 
469 /*
470  * FUNCTION: Sets an entry in a list
471  * ARGUMENTS:
472  * List = Address of pointer to list
473  * Number = Disk number
474  * String = Pointer to string
475  * RETURNS:
476  * false if there was not enough free memory available
477  */
478 {
480 
481  CN = *List;
482  while (CN != NULL)
483  {
484  if (CN->DiskNumber == Number)
485  {
486  strcpy(CN->Name, String);
487  return true;
488  }
489  CN = CN->Next;
490  }
491 
492  CN = new CABINET_NAME;
493  if (!CN)
494  return false;
495 
496  CN->DiskNumber = Number;
497  strcpy(CN->Name, String);
498 
499  CN->Next = *List;
500  *List = CN;
501 
502  return true;
503 }
504 
505 
507 /*
508  * FUNCTION: Returns an entry in a list
509  * ARGUMENTS:
510  * List = Address of pointer to list
511  * Number = Disk number
512  * String = Address of buffer to copy string to
513  * RETURNS:
514  * false if there was not enough free memory available
515  */
516 {
518 
519  CN = *List;
520  while (CN != NULL)
521  {
522  if (CN->DiskNumber == Number)
523  {
524  strcpy(String, CN->Name);
525  return true;
526  }
527  CN = CN->Next;
528  }
529 
530  return false;
531 }
532 
533 
535 /*
536  * FUNCTION: Sets an entry in a list
537  * ARGUMENTS:
538  * List = Address of pointer to list
539  * Number = Disk number
540  * Value = Value to set
541  * RETURNS:
542  * false if there was not enough free memory available
543  */
544 {
545  PDISK_NUMBER DN;
546 
547  DN = *List;
548  while (DN != NULL)
549  {
550  if (DN->DiskNumber == Number)
551  {
552  DN->Number = Value;
553  return true;
554  }
555  DN = DN->Next;
556  }
557 
558  DN = new DISK_NUMBER;
559  if (!DN)
560  return false;
561 
562  DN->DiskNumber = Number;
563  DN->Number = Value;
564 
565  DN->Next = *List;
566  *List = DN;
567 
568  return true;
569 }
570 
571 
573 /*
574  * FUNCTION: Returns an entry in a list
575  * ARGUMENTS:
576  * List = Address of pointer to list
577  * Number = Disk number
578  * Value = Address of buffer to place value
579  * RETURNS:
580  * true if the entry was found
581  */
582 {
583  PDISK_NUMBER DN;
584 
585  DN = *List;
586  while (DN != NULL)
587  {
588  if (DN->DiskNumber == Number)
589  {
590  *Value = DN->Number;
591  return true;
592  }
593  DN = DN->Next;
594  }
595 
596  return false;
597 }
598 
599 
601 /*
602  * FUNCTION: Sets the label of a disk
603  * ARGUMENTS:
604  * Number = Disk number
605  * Label = Pointer to label of disk
606  * RETURNS:
607  * false if there was not enough free memory available
608  */
609 {
610  DPRINT(MID_TRACE, ("Setting label of disk (%u) to '%s'\n", (UINT)Number, Label));
611 
612  return SetDiskName(&DiskLabel, Number, Label);
613 }
614 
615 
616 void CDFParser::DoDiskLabelTemplate(char* Template)
617 /*
618  * FUNCTION: Sets a disk label template to use
619  * ARGUMENTS:
620  * Template = Pointer to disk label template
621  */
622 {
623  DPRINT(MID_TRACE, ("Setting disk label template to '%s'\n", Template));
624 
625  strcpy(DiskLabelTemplate, Template);
626  DiskLabelTemplateSet = true;
627 }
628 
629 
631 /*
632  * FUNCTION: Sets the name of a cabinet
633  * ARGUMENTS:
634  * Number = Disk number
635  * Name = Pointer to name of cabinet
636  * RETURNS:
637  * false if there was not enough free memory available
638  */
639 {
640  DPRINT(MID_TRACE, ("Setting name of cabinet (%u) to '%s'\n", (UINT)Number, Name));
641 
642  return SetDiskName(&CabinetName, Number, Name);
643 }
644 
645 
647 /*
648  * FUNCTION: Sets a cabinet name template to use
649  * ARGUMENTS:
650  * Template = Pointer to cabinet name template
651  */
652 {
653  DPRINT(MID_TRACE, ("Setting cabinet name template to '%s'\n", Template));
654 
655  strcpy(CabinetNameTemplate, Template);
656  CabinetNameTemplateSet = true;
657 }
658 
659 
661 /*
662  * FUNCTION: Sets the maximum disk size
663  * ARGUMENTS:
664  * NumberValid = true if disk number is valid
665  * Number = Disk number
666  * RETURNS:
667  * Status of operation
668  * NOTES:
669  * Standard sizes are 2.88M, 1.44M, 1.25M, 1.2M, 720K, 360K, and CDROM
670  */
671 {
672  ULONG A, B, Value;
673 
674  if (IsNextToken(TokenInteger, true))
675  {
676  A = CurrentInteger;
677 
678  if (IsNextToken(TokenPeriod, false))
679  {
680  if (!IsNextToken(TokenInteger, false))
681  return CAB_STATUS_FAILURE;
682 
683  B = CurrentInteger;
684 
685  }
686  else
687  B = 0;
688 
690  {
691  switch (CurrentString[0])
692  {
693  case 'K':
694  if (B != 0)
695  return CAB_STATUS_FAILURE;
696 
697  if (A == 720)
698  /* 720K disk */
699  Value = 730112;
700  else if (A == 360)
701  /* 360K disk */
702  Value = 362496;
703  else
704  return CAB_STATUS_FAILURE;
705  break;
706 
707  case 'M':
708  if (A == 1)
709  {
710  if (B == 44)
711  /* 1.44M disk */
712  Value = 1457664;
713  else if (B == 25)
714  /* 1.25M disk */
715  Value = 1300000; // FIXME: Value?
716  else if (B == 2)
717  /* 1.2M disk */
718  Value = 1213952;
719  else
720  return CAB_STATUS_FAILURE;
721  }
722  else if (A == 2)
723  {
724  if (B == 88)
725  /* 2.88M disk */
726  Value = 2915328;
727  else
728  return CAB_STATUS_FAILURE;
729  }
730  else
731  return CAB_STATUS_FAILURE;
732  break;
733 
734  default:
735  DPRINT(MID_TRACE, ("Bad suffix (%c)\n", CurrentString[0]));
736  return CAB_STATUS_FAILURE;
737  }
738  }
739  else
740  Value = A;
741  }
742  else
743  {
744  if ((CurrentToken != TokenString) &&
745  (strcasecmp(CurrentString, "CDROM") != 0))
746  return CAB_STATUS_FAILURE;
747  /* CDROM */
748  Value = 640*1024*1024; // FIXME: Correct size for CDROM?
749  }
750 
751  if (NumberValid)
754 
756  MaxDiskSizeAllSet = true;
757 
759 
760  return CAB_STATUS_SUCCESS;
761 }
762 
763 
765 /*
766  * FUNCTION: Sets filename of the generated .inf file
767  * ARGUMENTS:
768  * FileName = Pointer to .inf filename
769  */
770 {
771  DPRINT(MID_TRACE, ("Setting .inf filename to '%s'\n", FileName));
772 
774  InfFileNameSet = true;
775 }
776 
778 /*
779  * FUNCTION: Sets up parameters for a new disk
780  * RETURNS:
781  * Status of operation
782  */
783 {
784  ULONG Value;
785 
787  {
788  if (MaxDiskSizeAllSet)
790  else
791  Value = 0;
792  }
794 
795  return CAB_STATUS_SUCCESS;
796 }
797 
798 
800 /*
801  * FUNCTION: Performs a set variable command
802  * RETURNS:
803  * Status of operation
804  */
805 {
806  SETTYPE SetType;
807  bool NumberValid = false;
808  ULONG Number = 0;
809 
810  if (!IsNextToken(TokenIdentifier, true))
811  return CAB_STATUS_FAILURE;
812 
813  if (strcasecmp(CurrentString, "DiskLabel") == 0)
814  SetType = stDiskLabel;
815  else if (strcasecmp(CurrentString, "DiskLabelTemplate") == 0)
816  SetType = stDiskLabelTemplate;
817  else if (strcasecmp(CurrentString, "CabinetName") == 0)
818  SetType = stCabinetName;
819  else if (strcasecmp(CurrentString, "CabinetNameTemplate") == 0)
820  SetType = stCabinetNameTemplate;
821  else if (strcasecmp(CurrentString, "MaxDiskSize") == 0)
822  SetType = stMaxDiskSize;
823  else if (strcasecmp(CurrentString, "InfFileName") == 0)
824  SetType = stInfFileName;
825  else
826  return CAB_STATUS_FAILURE;
827 
828  if ((SetType == stDiskLabel) || (SetType == stCabinetName))
829  {
830  if (!IsNextToken(TokenInteger, false))
831  return CAB_STATUS_FAILURE;
833 
834  if (!IsNextToken(TokenEqual, true))
835  return CAB_STATUS_FAILURE;
836  }
837  else if (SetType == stMaxDiskSize)
838  {
839  if (IsNextToken(TokenInteger, false))
840  {
841  NumberValid = true;
843  }
844  else
845  {
846  NumberValid = false;
847  while (CurrentToken == TokenSpace)
848  NextToken();
849  if (CurrentToken != TokenEqual)
850  return CAB_STATUS_FAILURE;
851  }
852  }
853  else if (!IsNextToken(TokenEqual, true))
854  return CAB_STATUS_FAILURE;
855 
856  if (SetType != stMaxDiskSize)
857  {
858  if (!IsNextToken(TokenString, true))
859  return CAB_STATUS_FAILURE;
860  }
861 
862  switch (SetType)
863  {
864  case stDiskLabel:
866  DPRINT(MIN_TRACE, ("Not enough available free memory.\n"));
867  return CAB_STATUS_SUCCESS;
868 
869  case stCabinetName:
871  DPRINT(MIN_TRACE, ("Not enough available free memory.\n"));
872  return CAB_STATUS_SUCCESS;
873 
874  case stDiskLabelTemplate:
876  return CAB_STATUS_SUCCESS;
877 
880  return CAB_STATUS_SUCCESS;
881 
882  case stMaxDiskSize:
883  return DoMaxDiskSize(NumberValid, Number);
884 
885  case stInfFileName:
887  return CAB_STATUS_SUCCESS;
888 
889  default:
890  return CAB_STATUS_FAILURE;
891  }
892 }
893 
894 
896 /*
897  * FUNCTION: Performs a new disk|cabinet|folder command
898  * RETURNS:
899  * Status of operation
900  */
901 {
902  NEWTYPE NewType;
903  ULONG Status;
904 
905  if (!IsNextToken(TokenIdentifier, true))
906  return CAB_STATUS_FAILURE;
907 
908  if (strcasecmp(CurrentString, "Disk") == 0)
909  NewType = ntDisk;
910  else if (strcasecmp(CurrentString, "Cabinet") == 0)
911  NewType = ntCabinet;
912  else if (strcasecmp(CurrentString, "Folder") == 0)
913  NewType = ntFolder;
914  else
915  return CAB_STATUS_FAILURE;
916 
917  switch (NewType)
918  {
919  case ntDisk:
920  if (DiskCreated)
921  {
922  Status = WriteDisk(true);
923  if (Status == CAB_STATUS_SUCCESS)
924  Status = CloseDisk();
925  if (Status != CAB_STATUS_SUCCESS)
926  {
927  DPRINT(MIN_TRACE, ("Cannot write disk (%u).\n", (UINT)Status));
928  return CAB_STATUS_SUCCESS;
929  }
930  DiskCreated = false;
931  }
932 
933  Status = NewDisk();
934  if (Status != CAB_STATUS_SUCCESS)
935  {
936  DPRINT(MIN_TRACE, ("Cannot create disk (%u).\n", (UINT)Status));
937  return CAB_STATUS_SUCCESS;
938  }
939  DiskCreated = true;
940  SetupNewDisk();
941  return CAB_STATUS_SUCCESS;
942 
943  case ntCabinet:
944  if (DiskCreated)
945  {
946  Status = WriteDisk(true);
947  if (Status == CAB_STATUS_SUCCESS)
948  Status = CloseDisk();
949  if (Status != CAB_STATUS_SUCCESS)
950  {
951  DPRINT(MIN_TRACE, ("Cannot write disk (%u).\n", (UINT)Status));
952  return CAB_STATUS_SUCCESS;
953  }
954  DiskCreated = false;
955  }
956 
957  Status = NewCabinet();
958  if (Status != CAB_STATUS_SUCCESS)
959  {
960  DPRINT(MIN_TRACE, ("Cannot create cabinet (%u).\n", (UINT)Status));
961  return CAB_STATUS_SUCCESS;
962  }
963  DiskCreated = true;
964  SetupNewDisk();
965  return CAB_STATUS_SUCCESS;
966 
967  case ntFolder:
968  Status = NewFolder();
970  return CAB_STATUS_SUCCESS;
971 
972  default:
973  return CAB_STATUS_FAILURE;
974  }
975 }
976 
977 
979 /*
980  * FUNCTION: Begins inf mode
981  * RETURNS:
982  * Status of operation
983  */
984 {
985  InfModeEnabled = true;
986  return CAB_STATUS_SUCCESS;
987 }
988 
989 
991 /*
992  * FUNCTION: Begins inf mode
993  * RETURNS:
994  * Status of operation
995  */
996 {
997  InfModeEnabled = false;
998  return CAB_STATUS_SUCCESS;
999 }
1000 
1001 
1003 /*
1004  * FUNCTION: Performs a command
1005  * RETURNS:
1006  * Status of operation
1007  */
1008 {
1009  if (strcasecmp(CurrentString, "Set") == 0)
1010  return PerformSetCommand();
1011  if (strcasecmp(CurrentString, "New") == 0)
1012  return PerformNewCommand();
1013  if (strcasecmp(CurrentString, "InfBegin") == 0)
1014  return PerformInfBeginCommand();
1015  if (strcasecmp(CurrentString, "InfEnd") == 0)
1016  return PerformInfEndCommand();
1017 
1018  return CAB_STATUS_FAILURE;
1019 }
1020 
1021 
1023 /*
1024  * FUNCTION: Performs a file copy
1025  * RETURNS:
1026  * Status of operation
1027  */
1028 {
1029  ULONG Status;
1030  ULONG i, j;
1031  char ch;
1032  char SrcName[PATH_MAX];
1033  char DstName[PATH_MAX];
1034  char InfLine[PATH_MAX];
1035  char Options[128];
1036  char BaseFilename[PATH_MAX];
1037 
1038  *SrcName = '\0';
1039  *DstName = '\0';
1040  *Options = '\0';
1041 
1042  // source file
1043  i = CurrentChar;
1044  while ((i < LineLength) &&
1045  ((ch = Line[i]) != ' ') &&
1046  (ch != 0x09) &&
1047  (ch != ';'))
1048  {
1049  CurrentString[i] = ch;
1050  i++;
1051  }
1052  CurrentString[i] = '\0';
1054  CurrentChar = i + 1;
1055  strcpy(BaseFilename, CurrentString);
1056  strcat(SrcName, BaseFilename);
1057 
1058  // destination
1059  SkipSpaces();
1060 
1061  if (CurrentToken != TokenEnd)
1062  {
1063  j = (ULONG)strlen(CurrentString); i = 0;
1064  while ((CurrentChar + i < LineLength) &&
1065  ((ch = Line[CurrentChar + i]) != ' ') &&
1066  (ch != 0x09) &&
1067  (ch != ';'))
1068  {
1069  CurrentString[j + i] = ch;
1070  i++;
1071  }
1072  CurrentString[j + i] = '\0';
1074  CurrentChar += i + 1;
1075  strcpy(DstName, CurrentString);
1076  }
1077 
1078  // options (it may be empty)
1079  SkipSpaces ();
1080 
1081  if (CurrentToken != TokenEnd)
1082  {
1083  j = (ULONG)strlen(CurrentString); i = 0;
1084  while ((CurrentChar + i < LineLength) &&
1085  ((ch = Line[CurrentChar + i]) != ' ') &&
1086  (ch != 0x09) &&
1087  (ch != ';'))
1088  {
1089  CurrentString[j + i] = ch;
1090  i++;
1091  }
1092  CurrentString[j + i] = '\0';
1094  CurrentChar += i + 1;
1096  }
1097 
1098  if (!CabinetCreated)
1099  {
1100  DPRINT(MID_TRACE, ("Creating cabinet.\n"));
1101 
1102  Status = NewCabinet();
1103  if (Status != CAB_STATUS_SUCCESS)
1104  {
1105  DPRINT(MIN_TRACE, ("Cannot create cabinet (%u).\n", (UINT)Status));
1106  printf("ERROR: Cannot create cabinet.\n");
1107  return CAB_STATUS_FAILURE;
1108  }
1109  CabinetCreated = true;
1110 
1111  DPRINT(MID_TRACE, ("Creating disk.\n"));
1112 
1113  Status = NewDisk();
1114  if (Status != CAB_STATUS_SUCCESS)
1115  {
1116  DPRINT(MIN_TRACE, ("Cannot create disk (%u).\n", (UINT)Status));
1117  printf("ERROR: Cannot create disk.\n");
1118  return CAB_STATUS_FAILURE;
1119  }
1120  DiskCreated = true;
1121  SetupNewDisk();
1122  }
1123 
1124  DPRINT(MID_TRACE, ("Adding file: '%s' destination: '%s'.\n", SrcName, DstName));
1125 
1126  Status = AddFile(SrcName, std::string());
1128  {
1129  strcpy(SrcName, FileRelativePath.c_str());
1130  strcat(SrcName, BaseFilename);
1131  Status = AddFile(SrcName, std::string());
1132  }
1133  switch (Status)
1134  {
1135  case CAB_STATUS_SUCCESS:
1136  sprintf(InfLine, "%s=%s", GetFileName(SrcName).c_str(), DstName);
1137  WriteInfLine(InfLine);
1138  break;
1139 
1141  if (strstr(Options,"optional"))
1142  {
1144  printf("Optional file skipped (does not exist): %s.\n", SrcName);
1145  }
1146  else
1147  printf("ERROR: File not found: %s.\n", SrcName);
1148 
1149  break;
1150 
1151  case CAB_STATUS_NOMEMORY:
1152  printf("ERROR: Insufficient memory to add file: %s.\n", SrcName);
1153  break;
1154 
1155  default:
1156  printf("ERROR: Cannot add file: %s (%u).\n", SrcName, (UINT)Status);
1157  break;
1158  }
1159  return Status;
1160 }
1161 
1162 
1164 /*
1165  * FUNCTION: Skips any spaces in the current line
1166  */
1167 {
1168  NextToken();
1169  while (CurrentToken == TokenSpace)
1170  NextToken();
1171 }
1172 
1173 
1175 /*
1176  * FUNCTION: Checks if next token equals Token
1177  * ARGUMENTS:
1178  * Token = Token to compare with
1179  * SkipSp = true if spaces should be skipped
1180  * RETURNS:
1181  * false if next token is diffrent from Token
1182  */
1183 {
1184  if (NoSpaces)
1185  SkipSpaces();
1186  else
1187  NextToken();
1188  return (CurrentToken == Token);
1189 }
1190 
1191 
1193 /*
1194  * FUNCTION: Reads the next line into the line buffer
1195  * RETURNS:
1196  * true if there is a new line, false if not
1197  */
1198 {
1199  ULONG i, j;
1200  char ch;
1201 
1203  return false;
1204 
1205  i = 0;
1206  while (((j = CurrentOffset + i) < FileBufferSize) && (i < sizeof(Line) - 1) &&
1207  ((ch = FileBuffer[j]) != 0x0D && (ch = FileBuffer[j]) != 0x0A))
1208  {
1209  Line[i] = ch;
1210  i++;
1211  }
1212 
1213  Line[i] = '\0';
1214  LineLength = i;
1215 
1216  if ((FileBuffer[CurrentOffset + i] == 0x0D) && (FileBuffer[CurrentOffset + i + 1] == 0x0A))
1217  CurrentOffset++;
1218 
1219  CurrentOffset += i + 1;
1220 
1221  CurrentChar = 0;
1222 
1223  CurrentLine++;
1224 
1225  NextToken();
1226 
1227  return true;
1228 }
1229 
1230 
1232 /*
1233  * FUNCTION: Reads the next token from the current line
1234  */
1235 {
1236  ULONG i;
1237  char ch = ' ';
1238 
1239  if (CurrentChar >= LineLength)
1240  {
1242  return;
1243  }
1244 
1245  switch (Line[CurrentChar])
1246  {
1247  case ' ':
1248  case 0x09:
1250  break;
1251 
1252  case ';':
1254  break;
1255 
1256  case '=':
1258  break;
1259 
1260  case '.':
1262  break;
1263 
1264  case '\\':
1266  break;
1267 
1268  case '"':
1269  i = 0;
1270  while ((CurrentChar + i + 1 < LineLength) &&
1271  ((ch = Line[CurrentChar + i + 1]) != '"'))
1272  {
1273  CurrentString[i] = ch;
1274  i++;
1275  }
1276  CurrentString[i] = '\0';
1278  CurrentChar += i + 2;
1279  return;
1280 
1281  default:
1282  i = 0;
1283  while ((CurrentChar + i < LineLength) &&
1284  ((ch = Line[CurrentChar + i]) >= '0') && (ch <= '9'))
1285  {
1286  CurrentString[i] = ch;
1287  i++;
1288  }
1289  if (i > 0)
1290  {
1291  CurrentString[i] = '\0';
1294  CurrentChar += i;
1295  return;
1296  }
1297  i = 0;
1298  while (((CurrentChar + i < LineLength) &&
1299  (((ch = Line[CurrentChar + i]) >= 'a') && (ch <= 'z'))) ||
1300  ((ch >= 'A') && (ch <= 'Z')) || (ch == '_'))
1301  {
1302  CurrentString[i] = ch;
1303  i++;
1304  }
1305  if (i > 0)
1306  {
1307  CurrentString[i] = '\0';
1309  CurrentChar += i;
1310  return;
1311  }
1313  }
1314  CurrentChar++;
1315 }
1316 
1317 /* EOF */
ULONG DiskNumber
Definition: dfp.h:22
char InfFileName[256]
Definition: dfp.h:126
PCABINET_NAME CabinetName
Definition: dfp.h:122
Definition: dfp.h:56
void DoCabinetNameTemplate(char *Template)
Definition: dfp.cxx:646
virtual void OnVerboseMessage(const char *Message)
Definition: cabinet.cxx:1773
bool SetDiskNumber(PDISK_NUMBER *List, ULONG Number, ULONG Value)
Definition: dfp.cxx:534
ULONG PerformNewCommand()
Definition: dfp.cxx:895
ULONG PerformCommand()
Definition: dfp.cxx:1002
#define MID_TRACE
Definition: debug.h:15
bool GetDiskName(PCABINET_NAME *List, ULONG Number, char *String)
Definition: dfp.cxx:506
bool SetDiskName(PCABINET_NAME *List, ULONG Number, char *String)
Definition: dfp.cxx:468
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define strcasecmp
Definition: fake.h:9
ULONG CurrentOffset
Definition: dfp.h:105
bool FolderCreated
Definition: dfp.h:118
bool MaxDiskSizeAllSet
Definition: dfp.h:137
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG CloseCabinet()
Definition: cabinet.cxx:1477
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
ULONG NewCabinet()
Definition: cabinet.cxx:1057
DFP_TOKEN
Definition: dfp.h:26
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define CAB_STATUS_CANNOT_READ
Definition: cabinet.h:28
bool DontGenerateInf
Definition: dfp.h:71
ULONG CurrentInteger
Definition: dfp.h:112
struct _CABINET_NAME CABINET_NAME
#define free
Definition: debug_ros.c:5
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
Definition: dfp.h:55
void SetFileRelativePath(char *Path)
Definition: dfp.cxx:348
bool DoCabinetName(ULONG Number, char *Name)
Definition: dfp.cxx:630
static WCHAR String[]
Definition: stringtable.c:55
Definition: shell.h:41
bool InfFileNameSet
Definition: dfp.h:125
void WriteLine(char *pchLine, FILE *fileOut)
Definition: hpp.c:194
PDISK_NUMBER MaxDiskSize
Definition: dfp.h:136
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
enum OPTION_FLAGS Options
Definition: stats.c:44
ULONG SetupNewDisk()
Definition: dfp.cxx:777
IN UCHAR Value
Definition: halp.h:394
bool DiskLabelTemplateSet
Definition: dfp.h:130
void DoDiskLabelTemplate(char *Template)
Definition: dfp.cxx:616
bool IsNextToken(DFP_TOKEN Token, bool NoSpaces)
Definition: dfp.cxx:1174
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define A(row, col)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void NormalizePath(std::string &Path)
Definition: cabinet.cxx:179
ULONG CurrentLine
Definition: dfp.h:108
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
void WriteInfLine(char *InfLine)
Definition: dfp.cxx:88
DFP_TOKEN CurrentToken
Definition: dfp.h:111
bool CabinetCreated
Definition: dfp.h:116
SETTYPE
Definition: dfp.h:41
bool CabinetNameTemplateSet
Definition: dfp.h:123
long LONG
Definition: pedump.c:60
const char * GetDestinationPath()
Definition: cabinet.cxx:308
CDFParser()
Definition: dfp.cxx:22
void SetMaxDiskSize(ULONG Size)
Definition: cabinet.cxx:1720
ULONG FileBufferSize
Definition: dfp.h:104
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
smooth NULL
Definition: ftsmooth.c:416
ULONG Number
Definition: dfp.h:23
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
Definition: dfp.h:34
char CabinetNameTemplate[128]
Definition: dfp.h:124
FILE * FileHandle
Definition: dfp.h:102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
struct _DISK_NUMBER DISK_NUMBER
char DiskLabelTemplate[128]
Definition: dfp.h:131
ULONG DoMaxDiskSize(bool NumberValid, ULONG Number)
Definition: dfp.cxx:660
LIST_ENTRY List
Definition: psmgr.c:57
bool InfFileOnly
Definition: dfp.h:70
struct Command Command
virtual ~CDFParser()
Definition: dfp.cxx:50
ULONG MaxDiskSizeAll
Definition: dfp.h:138
ULONG CurrentChar
Definition: dfp.h:109
#define CAB_STATUS_FAILURE
Definition: cabinet.h:24
std::string FileRelativePath
Definition: dfp.h:72
#define PATH_MAX
Definition: types.h:280
void ConvertPath(std::string &Path)
Definition: cabinet.cxx:134
void NextToken()
Definition: dfp.cxx:1231
ULONG NewFolder()
Definition: cabinet.cxx:1152
ULONG Parse()
Definition: dfp.cxx:193
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ULONG PerformFileCopy()
Definition: dfp.cxx:1022
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: ncftp.h:79
ULONG PerformInfBeginCommand()
Definition: dfp.cxx:978
#define CN(I, J, K)
Definition: ttei1.cpp:12
Status
Definition: gdiplustypes.h:24
Definition: dfp.h:37
char CurrentString[256]
Definition: dfp.h:113
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
bool FileLoaded
Definition: dfp.h:101
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
bool ReadLine()
Definition: dfp.cxx:1192
char string[160]
Definition: util.h:11
bool InfModeEnabled
Definition: dfp.h:144
PRTL_UNICODE_STRING_BUFFER Path
char * FileBuffer
Definition: dfp.h:103
bool GetDiskNumber(PDISK_NUMBER *List, ULONG Number, PULONG Value)
Definition: dfp.cxx:572
#define MAX_TRACE
Definition: debug.h:16
NEWTYPE
Definition: dfp.h:52
Definition: dfp.h:32
unsigned int * PULONG
Definition: retypes.h:1
#define B(row, col)
unsigned int UINT
Definition: ndis.h:50
virtual bool OnDiskLabel(ULONG Number, char *Label) override
Definition: dfp.cxx:361
ULONG NewDisk()
Definition: cabinet.cxx:1128
Definition: dfp.h:54
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
void SkipSpaces()
Definition: dfp.cxx:1163
ULONG AddFile(const std::string &FileName, const std::string &TargetFolder)
Definition: cabinet.cxx:1515
ULONG PerformInfEndCommand()
Definition: dfp.cxx:990
bool DoDiskLabel(ULONG Number, char *Label)
Definition: dfp.cxx:600
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
PWCHAR Label
Definition: format.c:70
#define MIN_TRACE
Definition: debug.h:14
Definition: dfp.h:33
#define CAB_STATUS_CANNOT_OPEN
Definition: cabinet.h:26
#define malloc
Definition: debug_ros.c:4
ULONG LineLength
Definition: dfp.h:107
std::string GetFileName(const std::string &Path)
Definition: cabinet.cxx:158
ULONG Load(char *FileName)
Definition: dfp.cxx:138
struct _DISK_NUMBER * Next
Definition: dfp.h:21
void DoInfFileName(char *InfFileName)
Definition: dfp.cxx:764
bool DiskCreated
Definition: dfp.h:117
ULONG PerformSetCommand()
Definition: dfp.cxx:799
ULONG CloseDisk()
Definition: cabinet.cxx:1459
struct _CABINET_NAME * Next
Definition: dfp.h:14
ULONG GetCurrentDiskNumber()
Definition: cabinet.cxx:376
FILE * InfFileHandle
Definition: dfp.h:143
virtual bool OnCabinetName(ULONG Number, char *Name) override
Definition: dfp.cxx:413
#define CAB_STATUS_NOFILE
Definition: cabinet.h:32
LONG GetSizeOfFile(FILE *handle)
Definition: cabinet.h:50
ULONG WriteDisk(ULONG MoreDisks)
Definition: cabinet.cxx:1311
#define printf
Definition: config.h:203
PCABINET_NAME DiskLabel
Definition: dfp.h:129