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