ReactOS  0.4.10-dev-348-gbcec1fd
cabinet.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS text-mode setup
4  * FILE: base/setup/usetup/cabinet.c
5  * PURPOSE: Cabinet routines
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * REVISIONS:
8  * CSH 15/08-2003 Created
9  */
10 
11 #include "usetup.h"
12 
13 #define Z_SOLO
14 #include <zlib.h>
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 #define SEEK_BEGIN 0
20 #define SEEK_CURRENT 1
21 #ifndef SEEK_END
22 #define SEEK_END 2
23 #endif
24 
25 typedef struct _DOSTIME
26 {
30 } DOSTIME, *PDOSTIME;
31 
32 
33 typedef struct _DOSDATE
34 {
35  WORD Day:5;
38 } DOSDATE, *PDOSDATE;
39 
40 static WCHAR CabinetName[256]; // Filename of current cabinet
41 static WCHAR CabinetPrev[256]; // Filename of previous cabinet
42 static WCHAR DiskPrev[256]; // Label of cabinet in file CabinetPrev
43 static WCHAR CabinetNext[256]; // Filename of next cabinet
44 static WCHAR DiskNext[256]; // Label of cabinet in file CabinetNext
45 static ULONG FolderUncompSize = 0; // Uncompressed size of folder
46 static ULONG BytesLeftInBlock = 0; // Number of bytes left in current block
53 static BOOL FileOpen = FALSE;
57 static ULONG FolderReserved = 0;
58 static ULONG DataReserved = 0;
59 static ULONG CodecId;
62 static ULONG LastFileOffset = 0; // Uncompressed offset of last extracted file
68 
69 
70 /* Needed by zlib, but we don't want the dependency on msvcrt.dll */
71 void *__cdecl
72 malloc(size_t size)
73 {
75 }
76 
77 void __cdecl
78 free(void *ptr)
79 {
80  RtlFreeHeap(ProcessHeap, 0, ptr);
81 }
82 
83 void *__cdecl
84 calloc(size_t nmemb, size_t size)
85 {
86  return (void *)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, nmemb * size);
87 }
88 
89 /* RAW codec */
90 
91 /*
92  * FUNCTION: Uncompresses data in a buffer
93  * ARGUMENTS:
94  * OutputBuffer = Pointer to buffer to place uncompressed data
95  * InputBuffer = Pointer to buffer with data to be uncompressed
96  * InputLength = Length of input buffer before, and amount consumed after
97  * Negative to indicate that this is not the start of a new block
98  * OutputLength = Length of output buffer before, amount filled after
99  * Negative to indicate that this is not the end of the block
100  */
101 ULONG
104  PLONG InputLength,
105  PLONG OutputLength)
106 {
107  LONG Len = min(abs(*InputLength), abs(*OutputLength));
108 
109  memcpy(OutputBuffer, InputBuffer, Len);
110  *InputLength = *OutputLength = Len;
111 
112  return CS_SUCCESS;
113 }
114 
115 /* MSZIP codec */
116 
117 /*
118  * FUNCTION: Uncompresses data in a buffer
119  * ARGUMENTS:
120  * OutputBuffer = Pointer to buffer to place uncompressed data
121  * InputBuffer = Pointer to buffer with data to be uncompressed
122  * InputLength = Length of input buffer before, and amount consumed after
123  * Negative to indicate that this is not the start of a new block
124  * OutputLength = Length of output buffer before, amount filled after
125  * Negative to indicate that this is not the end of the block
126  */
127 ULONG
130  PLONG InputLength,
131  PLONG OutputLength)
132 {
133  USHORT Magic;
134  INT Status;
135 
136  DPRINT("MSZipCodecUncompress(OutputBuffer = %x, InputBuffer = %x, "
137  "InputLength = %d, OutputLength = %d)\n", OutputBuffer,
138  InputBuffer, *InputLength, *OutputLength);
139  if (*InputLength > 0)
140  {
141  Magic = *(PUSHORT)InputBuffer;
142 
143  if (Magic != MSZIP_MAGIC)
144  {
145  DPRINT("Bad MSZIP block header magic (0x%X)\n", Magic);
146  return CS_BADSTREAM;
147  }
148 
149  ZStream.next_in = (PUCHAR)InputBuffer + 2;
150  ZStream.avail_in = *InputLength - 2;
151  ZStream.next_out = (PUCHAR)OutputBuffer;
152  ZStream.avail_out = abs(*OutputLength);
153 
154  /* WindowBits is passed < 0 to tell that there is no zlib header.
155  * Note that in this case inflate *requires* an extra "dummy" byte
156  * after the compressed stream in order to complete decompression and
157  * return Z_STREAM_END.
158  */
159  Status = inflateInit2(&ZStream, -MAX_WBITS);
160  if (Status != Z_OK)
161  {
162  DPRINT("inflateInit2() returned (%d)\n", Status);
163  return CS_BADSTREAM;
164  }
165  ZStream.total_in = 2;
166  }
167  else
168  {
169  ZStream.avail_in = -*InputLength;
170  ZStream.next_in = (PUCHAR)InputBuffer;
171  ZStream.next_out = (PUCHAR)OutputBuffer;
172  ZStream.avail_out = abs(*OutputLength);
173  ZStream.total_in = 0;
174  }
175 
176  ZStream.total_out = 0;
177  Status = inflate(&ZStream, Z_SYNC_FLUSH);
178  if (Status != Z_OK && Status != Z_STREAM_END)
179  {
180  DPRINT("inflate() returned (%d) (%s)\n", Status, ZStream.msg);
181  if (Status == Z_MEM_ERROR)
182  return CS_NOMEMORY;
183  return CS_BADSTREAM;
184  }
185 
186  if (*OutputLength > 0)
187  {
188  Status = inflateEnd(&ZStream);
189  if (Status != Z_OK)
190  {
191  DPRINT("inflateEnd() returned (%d)\n", Status);
192  return CS_BADSTREAM;
193  }
194  }
195 
196  *OutputLength = ZStream.total_out;
197  *InputLength = ZStream.total_in;
198 
199  return CS_SUCCESS;
200 }
201 
202 /* Memory functions */
203 
204 voidpf
206 {
207  return (voidpf)RtlAllocateHeap(ProcessHeap, 0, items * size);
208 }
209 
210 void
212 {
213  RtlFreeHeap(ProcessHeap, 0, address);
214 }
215 
216 static BOOL
218  LPFILETIME lpFileTime)
219 {
221  LARGE_INTEGER liTime;
222 
223  TimeFields.Year = lpSystemTime->wYear;
224  TimeFields.Month = lpSystemTime->wMonth;
225  TimeFields.Day = lpSystemTime->wDay;
226  TimeFields.Hour = lpSystemTime->wHour;
227  TimeFields.Minute = lpSystemTime->wMinute;
228  TimeFields.Second = lpSystemTime->wSecond;
229  TimeFields.Milliseconds = lpSystemTime->wMilliseconds;
230 
231  if (RtlTimeFieldsToTime(&TimeFields, &liTime))
232  {
233  lpFileTime->dwLowDateTime = liTime.u.LowPart;
234  lpFileTime->dwHighDateTime = liTime.u.HighPart;
235  return TRUE;
236  }
237 
238  return FALSE;
239 }
240 
241 static BOOL
243  WORD wFatTime,
244  LPFILETIME lpFileTime)
245 {
246  PDOSTIME pdtime = (PDOSTIME)&wFatTime;
247  PDOSDATE pddate = (PDOSDATE)&wFatDate;
248  SYSTEMTIME SystemTime;
249 
250  if (lpFileTime == NULL)
251  return FALSE;
252 
253  SystemTime.wMilliseconds = 0;
254  SystemTime.wSecond = pdtime->Second;
255  SystemTime.wMinute = pdtime->Minute;
256  SystemTime.wHour = pdtime->Hour;
257 
258  SystemTime.wDay = pddate->Day;
259  SystemTime.wMonth = pddate->Month;
260  SystemTime.wYear = 1980 + pddate->Year;
261 
262  ConvertSystemTimeToFileTime(&SystemTime, lpFileTime);
263 
264  return TRUE;
265 }
266 
267 /*
268  * FUNCTION: Returns a pointer to file name
269  * ARGUMENTS:
270  * Path = Pointer to string with pathname
271  * RETURNS:
272  * Pointer to filename
273  */
274 static PWCHAR
276 {
277  ULONG i, j;
278 
279  j = i = 0;
280 
281  while (Path[i++])
282  {
283  if (Path[i - 1] == L'\\')
284  j = i;
285  }
286 
287  return Path + j;
288 }
289 
290 /*
291  * FUNCTION: Removes a file name from a path
292  * ARGUMENTS:
293  * Path = Pointer to string with path
294  */
295 static VOID
297 {
299  DWORD i;
300 
301  i = 0;
302  FileName = GetFileName(Path + i);
303 
304  if (FileName != Path + i && FileName[-1] == L'\\')
305  FileName--;
306 
307  if (FileName == Path + i && FileName[0] == L'\\')
308  FileName++;
309 
310  FileName[0] = 0;
311 }
312 
313 /*
314  * FUNCTION: Sets attributes on a file
315  * ARGUMENTS:
316  * File = Pointer to CFFILE node for file
317  * RETURNS:
318  * Status of operation
319  */
320 static BOOL
322  HANDLE hFile)
323 {
324  FILE_BASIC_INFORMATION FileBasic;
326  NTSTATUS NtStatus;
327  ULONG Attributes = 0;
328 
329  if (File->Attributes & CAB_ATTRIB_READONLY)
330  Attributes |= FILE_ATTRIBUTE_READONLY;
331 
332  if (File->Attributes & CAB_ATTRIB_HIDDEN)
333  Attributes |= FILE_ATTRIBUTE_HIDDEN;
334 
335  if (File->Attributes & CAB_ATTRIB_SYSTEM)
336  Attributes |= FILE_ATTRIBUTE_SYSTEM;
337 
338  if (File->Attributes & CAB_ATTRIB_DIRECTORY)
339  Attributes |= FILE_ATTRIBUTE_DIRECTORY;
340 
341  if (File->Attributes & CAB_ATTRIB_ARCHIVE)
342  Attributes |= FILE_ATTRIBUTE_ARCHIVE;
343 
344  NtStatus = NtQueryInformationFile(hFile,
345  &IoStatusBlock,
346  &FileBasic,
347  sizeof(FILE_BASIC_INFORMATION),
349  if (!NT_SUCCESS(NtStatus))
350  {
351  DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
352  }
353  else
354  {
355  FileBasic.FileAttributes = Attributes;
356 
357  NtStatus = NtSetInformationFile(hFile,
358  &IoStatusBlock,
359  &FileBasic,
360  sizeof(FILE_BASIC_INFORMATION),
362  if (!NT_SUCCESS(NtStatus))
363  {
364  DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
365  }
366  }
367 
368  return NT_SUCCESS(NtStatus);
369 }
370 
371 /*
372  * FUNCTION: Closes the current cabinet
373  * RETURNS:
374  * Status of operation
375  */
376 static ULONG
378 {
379  if (FileBuffer)
380  {
384  FileBuffer = NULL;
385  }
386 
387  return 0;
388 }
389 
390 /*
391  * FUNCTION: Initialize archiver
392  */
393 VOID
395 {
396  ZStream.zalloc = MSZipAlloc;
397  ZStream.zfree = MSZipFree;
398  ZStream.opaque = (voidpf)0;
399 
400  FileOpen = FALSE;
401  wcscpy(DestPath, L"");
402 
405 
406  FolderUncompSize = 0;
407  BytesLeftInBlock = 0;
408  CabinetReserved = 0;
409  FolderReserved = 0;
410  DataReserved = 0;
412  LastFileOffset = 0;
413 }
414 
415 /*
416  * FUNCTION: Cleanup archiver
417  */
418 VOID
420 {
421  CabinetClose();
422 }
423 
424 /*
425  * FUNCTION: Normalizes a path
426  * ARGUMENTS:
427  * Path = Pointer to string with pathname
428  * Length = Number of characters in Path
429  * RETURNS:
430  * TRUE if there was enough room in Path, or FALSE
431  */
432 BOOL
434  ULONG Length)
435 {
436  ULONG n;
437  BOOL Ok;
438 
439  n = wcslen(Path);
440  Ok = (n + 1) < Length;
441 
442  if (n != 0 && Path[n - 1] != L'\\' && Ok)
443  {
444  Path[n] = L'\\';
445  Path[n + 1] = 0;
446  }
447 
448  return Ok;
449 }
450 
451 /*
452  * FUNCTION: Returns pointer to cabinet file name
453  * RETURNS:
454  * Pointer to string with name of cabinet
455  */
456 PWCHAR
458 {
459  return CabinetName;
460 }
461 
462 /*
463  * FUNCTION: Sets cabinet file name
464  * ARGUMENTS:
465  * FileName = Pointer to string with name of cabinet
466  */
467 VOID
469 {
470  wcscpy(CabinetName, FileName);
471 }
472 
473 /*
474  * FUNCTION: Sets destination path
475  * ARGUMENTS:
476  * DestinationPath = Pointer to string with name of destination path
477  */
478 VOID
480 {
481  wcscpy(DestPath, DestinationPath);
482 
483  if (wcslen(DestPath) > 0)
485 }
486 
487 /*
488  * FUNCTION: Returns destination path
489  * RETURNS:
490  * Pointer to string with name of destination path
491  */
492 PWCHAR
494 {
495  return DestPath;
496 }
497 
498 /*
499  * FUNCTION: Opens a cabinet file
500  * RETURNS:
501  * Status of operation
502  */
503 ULONG
505 {
506  PUCHAR Buffer;
508  ANSI_STRING astring;
509 
510  if (!FileOpen)
511  {
515  NTSTATUS NtStatus;
516 
517  RtlInitUnicodeString(&FileName, CabinetName);
518 
519  InitializeObjectAttributes(&ObjectAttributes,
520  &FileName,
522  NULL, NULL);
523 
524  NtStatus = NtOpenFile(&FileHandle,
526  &ObjectAttributes,
527  &IoStatusBlock,
530 
531  if (!NT_SUCCESS(NtStatus))
532  {
533  DPRINT1("Cannot open file (%S) (%x)\n", CabinetName, NtStatus);
534  return CAB_STATUS_CANNOT_OPEN;
535  }
536 
537  FileOpen = TRUE;
538 
541  0, 0,
543  SEC_COMMIT,
544  FileHandle);
545 
546  if (!NT_SUCCESS(NtStatus))
547  {
548  DPRINT1("NtCreateSection failed for %ls: %x\n", CabinetName, NtStatus);
549  return CAB_STATUS_NOMEMORY;
550  }
551 
552  FileBuffer = 0;
553  FileSize = 0;
554 
557  (PVOID *)&FileBuffer,
558  0, 0, 0,
559  &FileSize,
560  ViewUnmap,
561  0,
562  PAGE_READONLY);
563 
564  if (!NT_SUCCESS(NtStatus))
565  {
566  DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
567  return CAB_STATUS_NOMEMORY;
568  }
569 
570  DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer);
571  PCABHeader = (PCFHEADER) FileBuffer;
572 
573  /* Check header */
574  if (FileSize <= sizeof(CFHEADER) ||
575  PCABHeader->Signature != CAB_SIGNATURE ||
576  PCABHeader->Version != CAB_VERSION ||
577  PCABHeader->FolderCount == 0 ||
578  PCABHeader->FileCount == 0 ||
579  PCABHeader->FileTableOffset < sizeof(CFHEADER))
580  {
581  CloseCabinet();
582  DPRINT1("File has invalid header\n");
583  return CAB_STATUS_INVALID_CAB;
584  }
585 
586  Buffer = (PUCHAR)(PCABHeader + 1);
587 
588  /* Read/skip any reserved bytes */
589  if (PCABHeader->Flags & CAB_FLAG_RESERVE)
590  {
591  CabinetReserved = *(PUSHORT)Buffer;
592  Buffer += 2;
594  Buffer++;
595  DataReserved = *Buffer;
596  Buffer++;
597 
598  if (CabinetReserved > 0)
599  {
601  Buffer += CabinetReserved;
602  }
603  }
604 
605  if (PCABHeader->Flags & CAB_FLAG_HASPREV)
606  {
607  /* The previous cabinet file is in
608  the same directory as the current */
612  RtlInitAnsiString(&astring, (LPSTR)Buffer);
613  ustring.Length = wcslen(CabinetPrev);
614  ustring.Buffer = CabinetPrev + ustring.Length;
615  ustring.MaximumLength = sizeof(CabinetPrev) - ustring.Length;
616  RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
617  Buffer += astring.Length + 1;
618 
619  /* Read label of prev disk */
620  RtlInitAnsiString(&astring, (LPSTR)Buffer);
621  ustring.Length = 0;
622  ustring.Buffer = DiskPrev;
623  ustring.MaximumLength = sizeof(DiskPrev);
624  RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
625  Buffer += astring.Length + 1;
626  }
627  else
628  {
629  wcscpy(CabinetPrev, L"");
630  wcscpy(DiskPrev, L"");
631  }
632 
633  if (PCABHeader->Flags & CAB_FLAG_HASNEXT)
634  {
635  /* The next cabinet file is in
636  the same directory as the previous */
640  RtlInitAnsiString(&astring, (LPSTR)Buffer);
641  ustring.Length = wcslen(CabinetNext);
642  ustring.Buffer = CabinetNext + ustring.Length;
643  ustring.MaximumLength = sizeof(CabinetNext) - ustring.Length;
644  RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
645  Buffer += astring.Length + 1;
646 
647  /* Read label of next disk */
648  RtlInitAnsiString(&astring, (LPSTR)Buffer);
649  ustring.Length = 0;
650  ustring.Buffer = DiskNext;
651  ustring.MaximumLength = sizeof(DiskNext);
652  RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
653  Buffer += astring.Length + 1;
654  }
655  else
656  {
657  wcscpy(CabinetNext, L"");
658  wcscpy(DiskNext, L"");
659  }
660  CabinetFolders = (PCFFOLDER)Buffer;
661  }
662 
663  DPRINT("CabinetOpen returning SUCCESS\n");
664  return CAB_STATUS_SUCCESS;
665 }
666 
667 /*
668  * FUNCTION: Closes the cabinet file
669  */
670 VOID
672 {
673  if (FileOpen)
674  {
675  CloseCabinet();
676  FileOpen = FALSE;
677  }
678 }
679 
680 /*
681  * FUNCTION: Finds the first file in the cabinet that matches a search criteria
682  * ARGUMENTS:
683  * FileName = Pointer to search criteria
684  * Search = Pointer to search structure
685  * RETURNS:
686  * Status of operation
687  */
688 ULONG
691 {
692  DPRINT("CabinetFindFirst( FileName = %S )\n", FileName);
693  wcsncpy(Search->Search, FileName, MAX_PATH);
694  wcsncpy(Search->Cabinet, CabinetName, MAX_PATH);
695  Search->File = 0;
696  return CabinetFindNext(Search);
697 }
698 
699 /*
700  * FUNCTION: Finds the next file in the cabinet that matches a search criteria
701  * ARGUMENTS:
702  * FileName = Pointer to search criteria
703  * Search = Pointer to search structure
704  * RETURNS:
705  * Status of operation
706  */
707 ULONG
710 {
711  DPRINT("CabinetFindNextFileSequential( FileName = %S )\n", FileName);
712  wcsncpy(Search->Search, FileName, MAX_PATH);
713  return CabinetFindNext(Search);
714 }
715 
716 /*
717  * FUNCTION: Finds next file in the cabinet that matches a search criteria
718  * ARGUMENTS:
719  * Search = Pointer to search structure
720  * RETURNS:
721  * Status of operation
722  */
723 ULONG
725 {
726  PCFFILE Prev;
730 
731  if (wcscmp(Search->Cabinet, CabinetName) != 0)
732  {
733  /* restart search of cabinet has changed since last find */
734  Search->File = 0;
735  }
736 
737  if (!Search->File)
738  {
739  /* starting new search or cabinet */
740  Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset);
741  Search->Index = 0;
742  Prev = 0;
743  }
744  else
745  Prev = Search->File;
746 
747  while (TRUE)
748  {
749  /* look at each file in the archive and see if we found a match */
750  if (Search->File->FolderIndex == 0xFFFD ||
751  Search->File->FolderIndex == 0xFFFF)
752  {
753  /* skip files continued from previous cab */
754  DPRINT("Skipping file (%s): FileOffset (0x%X), "
755  "LastFileOffset (0x%X)\n", (char *)(Search->File + 1),
756  Search->File->FileOffset, LastFileOffset);
757  }
758  else
759  {
760  // FIXME: check for match against search criteria
761  if (Search->File != Prev)
762  {
763  if (Prev == NULL || Search->File->FolderIndex != Prev->FolderIndex)
764  {
765  Search->CFData = NULL;
766  Search->Offset = 0;
767  }
768 
769  /* don't match the file we started with */
770  if (wcscmp(Search->Search, L"*") == 0)
771  {
772  /* take any file */
773  break;
774  }
775  else
776  {
777  /* otherwise, try to match the exact file name */
778  RtlInitAnsiString(&AnsiString, Search->File->FileName);
779  UnicodeString.Buffer = FileName;
780  UnicodeString.Buffer[0] = 0;
781  UnicodeString.Length = 0;
782  UnicodeString.MaximumLength = sizeof(FileName);
783  RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
784  if (wcscmp(Search->Search, UnicodeString.Buffer) == 0)
785  break;
786  }
787  }
788  }
789 
790  /* if we make it here we found no match, so move to the next file */
791  Search->Index++;
792  if (Search->Index >= PCABHeader->FileCount)
793  {
794  /* we have reached the end of this cabinet */
795  DPRINT("End of cabinet reached\n");
796  return CAB_STATUS_NOFILE;
797  }
798  else
799  Search->File = (PCFFILE)(strchr((char *)(Search->File + 1), 0) + 1);
800  }
801 
802  DPRINT("Found file %s\n", Search->File->FileName);
803  return CAB_STATUS_SUCCESS;
804 }
805 
806 #if 0
807 int
808 Validate(VOID)
809 {
810  return (int)RtlValidateHeap(ProcessHeap, 0, 0);
811 }
812 #endif
813 
814 /*
815  * FUNCTION: Extracts a file from the cabinet
816  * ARGUMENTS:
817  * Search = Pointer to PCAB_SEARCH structure used to locate the file
818  * RETURNS
819  * Status of operation
820  */
821 ULONG
823 {
824  ULONG Size; // remaining file bytes to decompress
825  ULONG CurrentOffset; // current uncompressed offset within the folder
826  PUCHAR CurrentBuffer; // current pointer to compressed data in the block
827  LONG RemainingBlock; // remaining comp data in the block
828  HANDLE DestFile;
829  HANDLE DestFileSection;
830  PVOID DestFileBuffer; // mapped view of dest file
831  PVOID CurrentDestBuffer; // pointer to the current position in the dest view
832  PCFDATA CFData; // current data block
833  ULONG Status;
834  FILETIME FileTime;
835  WCHAR DestName[MAX_PATH];
836  NTSTATUS NtStatus;
841  FILE_BASIC_INFORMATION FileBasic;
842  PCFFOLDER CurrentFolder;
843  LARGE_INTEGER MaxDestFileSize;
844  LONG InputLength, OutputLength;
845  char Junk[512];
846 
847  if (wcscmp(Search->Cabinet, CabinetName) != 0)
848  {
849  /* the file is not in the current cabinet */
850  DPRINT("File is not in this cabinet (%S != %S)\n",
851  Search->Cabinet, CabinetName);
852  return CAB_STATUS_NOFILE;
853  }
854 
855  /* look up the folder that the file specifies */
856  if (Search->File->FolderIndex == 0xFFFD ||
857  Search->File->FolderIndex == 0xFFFF)
858  {
859  /* folder is continued from previous cabinet,
860  that shouldn't happen here */
861  return CAB_STATUS_NOFILE;
862  }
863  else if (Search->File->FolderIndex == 0xFFFE)
864  {
865  /* folder is the last in this cabinet and continues into next */
866  CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1];
867  }
868  else
869  {
870  /* folder is completely contained within this cabinet */
871  CurrentFolder = &CabinetFolders[Search->File->FolderIndex];
872  }
873 
874  switch (CurrentFolder->CompressionType & CAB_COMP_MASK)
875  {
876  case CAB_COMP_NONE:
878  break;
879  case CAB_COMP_MSZIP:
881  break;
882  default:
883  return CAB_STATUS_UNSUPPCOMP;
884  }
885 
886  DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n",
887  (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize);
888 
889  RtlInitAnsiString(&AnsiString, Search->File->FileName);
890  wcscpy(DestName, DestPath);
891  UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR);
892  UnicodeString.Buffer = DestName + wcslen(DestName);
893  UnicodeString.Length = 0;
894  RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
895 
896  /* Create destination file, fail if it already exists */
897  RtlInitUnicodeString(&UnicodeString, DestName);
898 
899  InitializeObjectAttributes(&ObjectAttributes,
900  &UnicodeString,
902  NULL, NULL);
903 
904  NtStatus = NtCreateFile(&DestFile,
906  &ObjectAttributes,
907  &IoStatusBlock,
908  NULL,
910  0,
911  FILE_CREATE,
913  NULL, 0);
914 
915  if (!NT_SUCCESS(NtStatus))
916  {
917  DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
918 
919  /* If file exists, ask to overwrite file */
920  if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName))
921  {
922  /* Create destination file, overwrite if it already exists */
923  NtStatus = NtCreateFile(&DestFile,
925  &ObjectAttributes,
926  &IoStatusBlock,
927  NULL,
929  0,
932  NULL, 0);
933 
934  if (!NT_SUCCESS(NtStatus))
935  {
936  DPRINT1("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
938  }
939  }
940  else
941  {
942  DPRINT1("File (%S) exists\n", DestName);
943  return CAB_STATUS_FILE_EXISTS;
944  }
945  }
946 
947  MaxDestFileSize.QuadPart = Search->File->FileSize;
948  NtStatus = NtCreateSection(&DestFileSection,
950  0,
951  &MaxDestFileSize,
953  SEC_COMMIT,
954  DestFile);
955 
956  if (!NT_SUCCESS(NtStatus))
957  {
958  DPRINT1("NtCreateSection failed for %ls, %x\n", DestName, NtStatus);
959  Status = CAB_STATUS_NOMEMORY;
960  goto CloseDestFile;
961  }
962 
963  DestFileBuffer = 0;
964  DestFileSize = 0;
965  NtStatus = NtMapViewOfSection(DestFileSection,
967  &DestFileBuffer,
968  0, 0, 0,
969  &DestFileSize,
970  ViewUnmap,
971  0,
973 
974  if (!NT_SUCCESS(NtStatus))
975  {
976  DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
977  Status = CAB_STATUS_NOMEMORY;
978  goto CloseDestFileSection;
979  }
980 
981  CurrentDestBuffer = DestFileBuffer;
983  Search->File->FileTime,
984  &FileTime))
985  {
986  DPRINT1("DosDateTimeToFileTime() failed\n");
987  Status = CAB_STATUS_CANNOT_WRITE;
988  goto UnmapDestFile;
989  }
990 
991  NtStatus = NtQueryInformationFile(DestFile,
992  &IoStatusBlock,
993  &FileBasic,
994  sizeof(FILE_BASIC_INFORMATION),
996  if (!NT_SUCCESS(NtStatus))
997  {
998  DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
999  }
1000  else
1001  {
1002  memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME));
1003 
1004  NtStatus = NtSetInformationFile(DestFile,
1005  &IoStatusBlock,
1006  &FileBasic,
1007  sizeof(FILE_BASIC_INFORMATION),
1009  if (!NT_SUCCESS(NtStatus))
1010  {
1011  DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
1012  }
1013  }
1014 
1015  SetAttributesOnFile(Search->File, DestFile);
1016 
1017  /* Call extract event handler */
1018  if (ExtractHandler != NULL)
1019  {
1020  ExtractHandler(Search->File, DestName);
1021  }
1022 
1023  if (Search->CFData)
1024  CFData = Search->CFData;
1025  else
1026  CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer);
1027 
1028  CurrentOffset = Search->Offset;
1029  while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset)
1030  {
1031  /* walk the data blocks until we reach
1032  the one containing the start of the file */
1033  CurrentOffset += CFData->UncompSize;
1034  CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize);
1035  }
1036 
1037  Search->CFData = CFData;
1038  Search->Offset = CurrentOffset;
1039 
1040  /* now decompress and discard any data in
1041  the block before the start of the file */
1042 
1043  /* start of comp data */
1044  CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved;
1045  RemainingBlock = CFData->CompSize;
1046  InputLength = RemainingBlock;
1047 
1048  while (CurrentOffset < Search->File->FileOffset)
1049  {
1050  /* compute remaining uncomp bytes to start
1051  of file, bounded by sizeof junk */
1052  OutputLength = Search->File->FileOffset - CurrentOffset;
1053  if (OutputLength > (LONG)sizeof(Junk))
1054  OutputLength = sizeof (Junk);
1055 
1056  /* negate to signal NOT end of block */
1057  OutputLength = -OutputLength;
1058  CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength);
1059  /* add the uncomp bytes extracted to current folder offset */
1060  CurrentOffset += OutputLength;
1061  /* add comp bytes consumed to CurrentBuffer */
1062  CurrentBuffer += InputLength;
1063  /* subtract bytes consumed from bytes remaining in block */
1064  RemainingBlock -= InputLength;
1065  /* neg for resume decompression of the same block */
1066  InputLength = -RemainingBlock;
1067  }
1068 
1069  /* now CurrentBuffer points to the first comp byte
1070  of the file, so we can begin decompressing */
1071 
1072  /* Size = remaining uncomp bytes of the file to decompress */
1073  Size = Search->File->FileSize;
1074  while (Size > 0)
1075  {
1076  OutputLength = Size;
1077  DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n",
1078  CurrentBuffer, RemainingBlock, Size);
1079 
1080  Status = CodecUncompress(CurrentDestBuffer,
1081  CurrentBuffer,
1082  &InputLength,
1083  &OutputLength);
1084 
1085  if (Status != CS_SUCCESS)
1086  {
1087  DPRINT("Cannot uncompress block\n");
1088  if (Status == CS_NOMEMORY)
1089  Status = CAB_STATUS_NOMEMORY;
1090  Status = CAB_STATUS_INVALID_CAB;
1091  goto UnmapDestFile;
1092  }
1093 
1094  /* advance dest buffer by bytes produced */
1095  CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength);
1096  /* advance src buffer by bytes consumed */
1097  CurrentBuffer += InputLength;
1098  /* reduce remaining file bytes by bytes produced */
1099  Size -= OutputLength;
1100  /* reduce remaining block size by bytes consumed */
1101  RemainingBlock -= InputLength;
1102  if (Size > 0 && RemainingBlock == 0)
1103  {
1104  /* used up this block, move on to the next */
1105  DPRINT("Out of block data\n");
1106  CFData = (PCFDATA)CurrentBuffer;
1107  RemainingBlock = CFData->CompSize;
1108  CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved;
1109  InputLength = RemainingBlock;
1110  }
1111  }
1112 
1113  Status = CAB_STATUS_SUCCESS;
1114 
1115 UnmapDestFile:
1116  NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);
1117 
1118 CloseDestFileSection:
1119  NtClose(DestFileSection);
1120 
1121 CloseDestFile:
1122  NtClose(DestFile);
1123 
1124  return Status;
1125 }
1126 
1127 /*
1128  * FUNCTION: Selects codec engine to use
1129  * ARGUMENTS:
1130  * Id = Codec identifier
1131  */
1132 VOID
1134 {
1135  if (CodecSelected)
1136  {
1137  if (Id == CodecId)
1138  return;
1139 
1140  CodecSelected = FALSE;
1141  }
1142 
1143  switch (Id)
1144  {
1145  case CAB_CODEC_RAW:
1147  break;
1148  case CAB_CODEC_MSZIP:
1150  break;
1151  default:
1152  return;
1153  }
1154 
1155  CodecId = Id;
1156  CodecSelected = TRUE;
1157 }
1158 
1159 /*
1160  * FUNCTION: Set event handlers
1161  * ARGUMENTS:
1162  * Overwrite = Handler called when a file is to be overwritten
1163  * Extract = Handler called when a file is to be extracted
1164  * DiskChange = Handler called when changing the disk
1165  */
1166 VOID
1169  PCABINET_DISK_CHANGE DiskChange)
1170 {
1171  OverwriteHandler = Overwrite;
1173  DiskChangeHandler = DiskChange;
1174 }
1175 
1176 /*
1177  * FUNCTION: Get pointer to cabinet reserved area. NULL if none
1178  */
1179 PVOID
1181 {
1182  if (CabinetReservedArea != NULL)
1183  {
1184  if (Size != NULL)
1185  {
1186  *Size = CabinetReserved;
1187  }
1188 
1189  return CabinetReservedArea;
1190  }
1191  else
1192  {
1193  if (Size != NULL)
1194  {
1195  *Size = 0;
1196  }
1197 
1198  return NULL;
1199  }
1200 }
DWORD *typedef PVOID
Definition: winlogon.h:52
VOID CabinetSetDestinationPath(PWCHAR DestinationPath)
Definition: cabinet.c:479
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG CabinetFindNextFileSequential(PWCHAR FileName, PCAB_SEARCH Search)
Definition: cabinet.c:708
#define abs(i)
Definition: fconv.c:206
ULONG MSZipCodecUncompress(PVOID OutputBuffer, PVOID InputBuffer, PLONG InputLength, PLONG OutputLength)
Definition: cabinet.c:128
#define CAB_COMP_NONE
Definition: cabinet.h:18
#define CAB_STATUS_CANNOT_WRITE
Definition: cabinet.h:125
VOID(* PCABINET_EXTRACT)(PCFFILE File, PWCHAR FileName)
Definition: cabinet.h:160
static ULONG CodecId
Definition: cabinet.c:59
WORD Month
Definition: cabinet.c:36
#define CAB_COMP_MASK
Definition: cabinet.h:17
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
unsigned short WORD
Definition: ntddk_ex.h:93
#define CAB_ATTRIB_SYSTEM
Definition: cabinet.h:29
WCHAR Search[MAX_PATH]
Definition: cabinet.h:107
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3778
#define TRUE
Definition: types.h:120
void __cdecl free(void *ptr)
Definition: cabinet.c:78
WORD CompSize
Definition: cabinet.h:98
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
WCHAR Cabinet[MAX_PATH]
Definition: cabinet.h:108
VOID CabinetInitialize(VOID)
Definition: cabinet.c:394
WORD FileDate
Definition: cabinet.h:87
static BOOL ConvertSystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime)
Definition: cabinet.c:217
static ULONG DataReserved
Definition: cabinet.c:58
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3369
static SIZE_T DestFileSize
Definition: cabinet.c:51
#define __cdecl
Definition: accygwin.h:79
ULONG(* PCABINET_CODEC_UNCOMPRESS)(PVOID OutputBuffer, PVOID InputBuffer, PLONG InputLength, PLONG OutputLength)
Definition: cabinet.h:135
static PVOID CabinetReservedArea
Definition: cabinet.c:67
static PWCHAR GetFileName(PWCHAR Path)
Definition: cabinet.c:275
USHORT MaximumLength
Definition: env_spec_w32.h:370
WORD wMonth
Definition: winbase.h:871
#define CAB_STATUS_UNSUPPCOMP
Definition: cabinet.h:129
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
WORD UncompSize
Definition: cabinet.h:99
static SIZE_T FileSize
Definition: cabinet.c:52
WORD Year
Definition: cabinet.c:37
unsigned char * PUCHAR
Definition: retypes.h:3
#define CAB_ATTRIB_HIDDEN
Definition: cabinet.h:28
int ZEXPORT inflateEnd(z_streamp strm)
Definition: inflate.c:1277
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define FILE_CREATE
Definition: from_kernel.h:55
uInt avail_in
Definition: zlib.h:88
BOOL(* PCABINET_OVERWRITE)(PCFFILE File, PWCHAR FileName)
Definition: cabinet.h:157
static UNICODE_STRING DestinationPath
Definition: usetup.c:89
WORD Version
Definition: cabinet.h:52
WORD Second
Definition: cabinet.c:27
static BOOL ConvertDosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, LPFILETIME lpFileTime)
Definition: cabinet.c:242
HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName)
Definition: cabinet_main.c:328
ULONG Offset
Definition: cabinet.h:112
#define FILE_OVERWRITE
Definition: from_kernel.h:57
WORD FileTime
Definition: cabinet.h:88
struct _DOSDATE * PDOSDATE
#define CAB_FLAG_RESERVE
Definition: cabinet.h:25
#define CS_NOMEMORY
Definition: cabinet.h:143
WORD Minute
Definition: cabinet.c:28
ULONG Signature
Definition: cabinet.h:46
uint16_t * PWCHAR
Definition: typedefs.h:54
char * LPSTR
Definition: xmlstorage.h:182
#define WCHAR
Definition: msvc.h:43
static PUCHAR FileBuffer
Definition: cabinet.c:50
static PCABINET_CODEC_UNCOMPRESS CodecUncompress
Definition: cabinet.c:60
int32_t INT
Definition: typedefs.h:56
DWORD DWORD
Definition: winlogon.h:75
VOID CabinetClose(VOID)
Definition: cabinet.c:671
CHAR InputBuffer[80]
Definition: conmgr.c:33
#define FILE_SHARE_READ
Definition: compat.h:125
PWCHAR CabinetGetCabinetName(VOID)
Definition: cabinet.c:457
DWORD Id
#define Z_STREAM_END
Definition: zlib.h:178
struct _DOSTIME * PDOSTIME
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:63
static WCHAR DiskPrev[256]
Definition: cabinet.c:42
void *__cdecl malloc(size_t size)
Definition: cabinet.c:72
GLuint n
Definition: s_context.h:57
NTSYSAPI BOOLEAN WINAPI RtlValidateHeap(HANDLE, ULONG, LPCVOID)
ULONG RawCodecUncompress(PVOID OutputBuffer, PVOID InputBuffer, PLONG InputLength, PLONG OutputLength)
Definition: cabinet.c:102
static WCHAR DestPath[MAX_PATH]
Definition: cabinet.c:47
voidpf opaque
Definition: zlib.h:100
DWORD dwHighDateTime
Definition: mapidefs.h:66
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
WORD wYear
Definition: winbase.h:870
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
free_func zfree
Definition: zlib.h:99
#define SEC_COMMIT
Definition: mmtypes.h:99
struct _CFHEADER * PCFHEADER
#define FALSE
Definition: types.h:117
WORD Attributes
Definition: cabinet.h:89
static PCABINET_EXTRACT ExtractHandler
Definition: cabinet.c:64
static BOOL FileOpen
Definition: cabinet.c:53
long LONG
Definition: pedump.c:60
static PCFFOLDER CabinetFolders
Definition: cabinet.c:55
WORD Hour
Definition: cabinet.c:29
#define GENERIC_WRITE
Definition: nt_native.h:90
WORD FileCount
Definition: cabinet.h:54
VOID CabinetSelectCodec(ULONG Id)
Definition: cabinet.c:1133
#define Z_OK
Definition: zlib.h:177
#define CAB_FLAG_HASPREV
Definition: cabinet.h:23
static PVOID ptr
Definition: dispmode.c:27
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3550
WORD wMinute
Definition: winbase.h:875
struct _CFDATA * PCFDATA
smooth NULL
Definition: ftsmooth.c:416
#define CAB_VERSION
Definition: cabinet.h:14
struct _DOSDATE DOSDATE
#define CAB_STATUS_CANNOT_OPEN
Definition: cabinet.h:122
BOOL CabinetNormalizePath(PWCHAR Path, ULONG Length)
Definition: cabinet.c:433
WORD CompressionType
Definition: cabinet.h:75
void DPRINT(...)
Definition: polytest.cpp:61
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
USHORT Milliseconds
Definition: env_spec_w32.h:717
static BOOL SetAttributesOnFile(PCFFILE File, HANDLE hFile)
Definition: cabinet.c:321
WORD FolderCount
Definition: cabinet.h:53
#define CS_SUCCESS
Definition: cabinet.h:142
#define CONST
Definition: compiler.h:170
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
UINTN Size
Definition: acefiex.h:555
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
struct _CFFILE * PCFFILE
static PCABINET_DISK_CHANGE DiskChangeHandler
Definition: cabinet.c:65
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3508
static BOOL CodecSelected
Definition: cabinet.c:61
PWCHAR CabinetGetDestinationPath(VOID)
Definition: cabinet.c:493
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
LONG NTSTATUS
Definition: precomp.h:26
z_const char * msg
Definition: zlib.h:95
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
uLong total_in
Definition: zlib.h:89
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
static VOID RemoveFileName(PWCHAR Path)
Definition: cabinet.c:296
#define MAX_PATH
Definition: compat.h:26
alloc_func zalloc
Definition: zlib.h:98
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
unsigned short * PUSHORT
Definition: retypes.h:2
#define inflateInit2(strm, windowBits)
Definition: zlib.h:1800
static WCHAR CabinetName[256]
Definition: cabinet.c:40
GLuint address
Definition: glext.h:9393
#define Len
Definition: deflate.h:82
void *__cdecl calloc(size_t nmemb, size_t size)
Definition: cabinet.c:84
struct _CFHEADER CFHEADER
UINTN VOID * Buffer
Definition: acefiex.h:370
int ZEXPORT inflate(z_streamp strm, int flush)
Definition: inflate.c:622
static ULONG FolderReserved
Definition: cabinet.c:57
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3392
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
WORD wSecond
Definition: winbase.h:876
static PCFHEADER PCABHeader
Definition: cabinet.c:54
WORD wMilliseconds
Definition: winbase.h:877
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
PVOID CabinetGetCabinetReservedArea(PULONG Size)
Definition: cabinet.c:1180
#define Z_SYNC_FLUSH
Definition: zlib.h:170
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
struct _DOSTIME DOSTIME
static const WCHAR L[]
Definition: oid.c:1087
VOID UINTN Length
Definition: acefiex.h:744
static WCHAR DiskNext[256]
Definition: cabinet.c:44
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:121
static WCHAR CabinetNext[256]
Definition: cabinet.c:43
#define CAB_STATUS_FILE_EXISTS
Definition: cabinet.h:126
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GENERIC_READ
Definition: compat.h:124
ULONG FileOffset
Definition: cabinet.h:85
static PCABINET_OVERWRITE OverwriteHandler
Definition: cabinet.c:63
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define SYNCHRONIZE
Definition: nt_native.h:61
_In_ HANDLE hFile
Definition: mswsock.h:90
WORD Flags
Definition: cabinet.h:55
static WCHAR CabinetPrev[256]
Definition: cabinet.c:41
VOID(* PCABINET_DISK_CHANGE)(PWCHAR CabinetName, PWCHAR DiskLabel)
Definition: cabinet.h:163
#define CAB_CODEC_RAW
Definition: cabinet.h:147
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
uLong total_out
Definition: zlib.h:93
void MSZipFree(voidpf opaque, voidpf address)
Definition: cabinet.c:211
#define CAB_COMP_MSZIP
Definition: cabinet.h:19
static HANDLE FileHandle
Definition: cabinet.c:48
WORD wDay
Definition: winbase.h:873
ULONG_PTR SIZE_T
Definition: typedefs.h:78
struct _CFFOLDER * PCFFOLDER
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
Byte FAR * voidpf
Definition: zconf.h:413
struct _FileName FileName
Definition: fatprocs.h:884
#define CAB_ATTRIB_READONLY
Definition: cabinet.h:27
DWORD *typedef HANDLE
Definition: winlogon.h:52
USHORT Index
Definition: cabinet.h:109
#define CAB_SIGNATURE
Definition: cabinet.h:13
ULONG CabinetFindFirst(PWCHAR FileName, PCAB_SEARCH Search)
Definition: cabinet.c:689
PRTL_UNICODE_STRING_BUFFER Path
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:127
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
#define CAB_ATTRIB_DIRECTORY
Definition: cabinet.h:31
unsigned short USHORT
Definition: pedump.c:61
ULONG CabinetOpen(VOID)
Definition: cabinet.c:504
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:119
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
VOID CabinetCleanup(VOID)
Definition: cabinet.c:419
#define CAB_STATUS_NOFILE
Definition: cabinet.h:128
CHAR FileName[ANYSIZE_ARRAY]
Definition: cabinet.h:90
WORD wHour
Definition: winbase.h:874
static PVOID CurrentBuffer
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
VOID CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, PCABINET_EXTRACT Extract, PCABINET_DISK_CHANGE DiskChange)
Definition: cabinet.c:1167
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
unsigned int * PULONG
Definition: retypes.h:1
Definition: crypt.h:94
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define PAGE_READONLY
Definition: compat.h:127
uInt avail_out
Definition: zlib.h:92
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
z_const Bytef * next_in
Definition: zlib.h:87
Definition: fci.c:65
WORD FolderIndex
Definition: cabinet.h:86
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define DPRINT1
Definition: precomp.h:8
PCFFILE File
Definition: cabinet.h:110
WORD Day
Definition: cabinet.c:35
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
static z_stream ZStream
Definition: cabinet.c:66
voidpf MSZipAlloc(voidpf opaque, uInt items, uInt size)
Definition: cabinet.c:205
#define CS_BADSTREAM
Definition: cabinet.h:144
#define CAB_ATTRIB_ARCHIVE
Definition: cabinet.h:32
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG FileSize
Definition: cabinet.h:84
Definition: File.h:15
#define MSZIP_MAGIC
Definition: cabinet.h:151
ULONG FileTableOffset
Definition: cabinet.h:50
Bytef * next_out
Definition: zlib.h:91
struct _LARGE_INTEGER::@2135 u
BOOLEAN RtlTimeFieldsToTime(IN PTIME_FIELDS TimeFields, IN PLARGE_INTEGER Time)
static PTIME_FIELDS TimeFields
Definition: time.c:104
static TCHAR * items[]
Definition: page1.c:45
signed int * PLONG
Definition: retypes.h:5
#define MAX_WBITS
Definition: zconf.h:270
static CAB_SEARCH Search
Definition: filesup.c:20
VOID CabinetSetCabinetName(PWCHAR FileName)
Definition: cabinet.c:468
#define CAB_STATUS_CANNOT_CREATE
Definition: cabinet.h:123
static ULONG CloseCabinet(VOID)
Definition: cabinet.c:377
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG CabinetFindNext(PCAB_SEARCH Search)
Definition: cabinet.c:724
ULONG CabinetExtractFile(PCAB_SEARCH Search)
Definition: cabinet.c:822
PCFDATA CFData
Definition: cabinet.h:111
#define Z_MEM_ERROR
Definition: zlib.h:183
static ULONG BytesLeftInBlock
Definition: cabinet.c:46
DWORD dwLowDateTime
Definition: mapidefs.h:65
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:2854
struct _ACPI_EFI_FILE_HANDLE CHAR16 UINT64 UINT64 Attributes
Definition: acefiex.h:335
unsigned int uInt
Definition: zconf.h:393
LONGLONG QuadPart
Definition: typedefs.h:112
static ULONG LastFileOffset
Definition: cabinet.c:62
static ULONG CabinetReserved
Definition: cabinet.c:56
#define CAB_FLAG_HASNEXT
Definition: cabinet.h:24
static HANDLE FileSectionHandle
Definition: cabinet.c:49
ULONG DataOffset
Definition: cabinet.h:73
#define CAB_CODEC_MSZIP
Definition: cabinet.h:149
#define PAGE_READWRITE
Definition: nt_native.h:1304
static ULONG FolderUncompSize
Definition: cabinet.c:45