ReactOS 0.4.16-dev-297-gc569aee
cabinet.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _CAB_SEARCH
 
struct  _CABINET_CONTEXT
 

Macros

#define CAB_STATUS_SUCCESS   0x00000000
 
#define CAB_STATUS_FAILURE   0x00000001
 
#define CAB_STATUS_NOMEMORY   0x00000002
 
#define CAB_STATUS_CANNOT_OPEN   0x00000003
 
#define CAB_STATUS_CANNOT_CREATE   0x00000004
 
#define CAB_STATUS_CANNOT_READ   0x00000005
 
#define CAB_STATUS_CANNOT_WRITE   0x00000006
 
#define CAB_STATUS_FILE_EXISTS   0x00000007
 
#define CAB_STATUS_INVALID_CAB   0x00000008
 
#define CAB_STATUS_NOFILE   0x00000009
 
#define CAB_STATUS_UNSUPPCOMP   0x0000000A
 
#define CS_SUCCESS   0x0000 /* All data consumed */
 
#define CS_NOMEMORY   0x0001 /* Not enough free memory */
 
#define CS_BADSTREAM   0x0002 /* Bad data stream */
 
#define CAB_CODEC_RAW   0x00
 
#define CAB_CODEC_LZX   0x01
 
#define CAB_CODEC_MSZIP   0x02
 

Typedefs

typedef struct _CFHEADERPCFHEADER
 
typedef struct _CFFOLDERPCFFOLDER
 
typedef struct _CFFILEPCFFILE
 
typedef struct _CFDATAPCFDATA
 
typedef struct _CAB_CODECPCAB_CODEC
 
typedef BOOL(* PCABINET_OVERWRITE) (IN struct _CABINET_CONTEXT *CabinetContext, IN PCFFILE File, IN PCWSTR FileName)
 
typedef VOID(* PCABINET_EXTRACT) (IN struct _CABINET_CONTEXT *CabinetContext, IN PCFFILE File, IN PCWSTR FileName)
 
typedef VOID(* PCABINET_DISK_CHANGE) (IN struct _CABINET_CONTEXT *CabinetContext, IN PCWSTR CabinetName, IN PCWSTR DiskLabel)
 
typedef PVOID(* PCABINET_CREATE_FILE) (IN struct _CABINET_CONTEXT *CabinetContext, IN ULONG FileSize)
 
typedef struct _CAB_SEARCH CAB_SEARCH
 
typedef struct _CAB_SEARCHPCAB_SEARCH
 
typedef struct _CABINET_CONTEXT CABINET_CONTEXT
 
typedef struct _CABINET_CONTEXTPCABINET_CONTEXT
 

Functions

VOID CabinetInitialize (IN OUT PCABINET_CONTEXT CabinetContext)
 
VOID CabinetCleanup (IN OUT PCABINET_CONTEXT CabinetContext)
 
PCWSTR CabinetGetCabinetName (IN PCABINET_CONTEXT CabinetContext)
 
VOID CabinetSetCabinetName (IN PCABINET_CONTEXT CabinetContext, IN PCWSTR FileName)
 
VOID CabinetSetDestinationPath (IN PCABINET_CONTEXT CabinetContext, IN PCWSTR DestinationPath)
 
PCWSTR CabinetGetDestinationPath (IN PCABINET_CONTEXT CabinetContext)
 
ULONG CabinetOpen (IN OUT PCABINET_CONTEXT CabinetContext)
 
VOID CabinetClose (IN OUT PCABINET_CONTEXT CabinetContext)
 
ULONG CabinetFindFirst (IN PCABINET_CONTEXT CabinetContext, IN PCWSTR FileName, IN OUT PCAB_SEARCH Search)
 
ULONG CabinetFindNext (IN PCABINET_CONTEXT CabinetContext, IN OUT PCAB_SEARCH Search)
 
ULONG CabinetFindNextFileSequential (IN PCABINET_CONTEXT CabinetContext, IN PCWSTR FileName, IN OUT PCAB_SEARCH Search)
 
ULONG CabinetExtractFile (IN PCABINET_CONTEXT CabinetContext, IN PCAB_SEARCH Search)
 
VOID CabinetSelectCodec (IN PCABINET_CONTEXT CabinetContext, IN ULONG Id)
 
VOID CabinetSetEventHandlers (IN PCABINET_CONTEXT CabinetContext, IN PCABINET_OVERWRITE Overwrite, IN PCABINET_EXTRACT Extract, IN PCABINET_DISK_CHANGE DiskChange, IN PCABINET_CREATE_FILE CreateFile)
 
PVOID CabinetGetCabinetReservedArea (IN PCABINET_CONTEXT CabinetContext, OUT PULONG Size)
 

Macro Definition Documentation

◆ CAB_CODEC_LZX

#define CAB_CODEC_LZX   0x01

Definition at line 47 of file cabinet.h.

◆ CAB_CODEC_MSZIP

#define CAB_CODEC_MSZIP   0x02

Definition at line 48 of file cabinet.h.

◆ CAB_CODEC_RAW

#define CAB_CODEC_RAW   0x00

Definition at line 46 of file cabinet.h.

◆ CAB_STATUS_CANNOT_CREATE

#define CAB_STATUS_CANNOT_CREATE   0x00000004

Definition at line 27 of file cabinet.h.

◆ CAB_STATUS_CANNOT_OPEN

#define CAB_STATUS_CANNOT_OPEN   0x00000003

Definition at line 26 of file cabinet.h.

◆ CAB_STATUS_CANNOT_READ

#define CAB_STATUS_CANNOT_READ   0x00000005

Definition at line 28 of file cabinet.h.

◆ CAB_STATUS_CANNOT_WRITE

#define CAB_STATUS_CANNOT_WRITE   0x00000006

Definition at line 29 of file cabinet.h.

◆ CAB_STATUS_FAILURE

#define CAB_STATUS_FAILURE   0x00000001

Definition at line 24 of file cabinet.h.

◆ CAB_STATUS_FILE_EXISTS

#define CAB_STATUS_FILE_EXISTS   0x00000007

Definition at line 30 of file cabinet.h.

◆ CAB_STATUS_INVALID_CAB

#define CAB_STATUS_INVALID_CAB   0x00000008

Definition at line 31 of file cabinet.h.

◆ CAB_STATUS_NOFILE

#define CAB_STATUS_NOFILE   0x00000009

Definition at line 32 of file cabinet.h.

◆ CAB_STATUS_NOMEMORY

#define CAB_STATUS_NOMEMORY   0x00000002

Definition at line 25 of file cabinet.h.

◆ CAB_STATUS_SUCCESS

#define CAB_STATUS_SUCCESS   0x00000000

Definition at line 23 of file cabinet.h.

◆ CAB_STATUS_UNSUPPCOMP

#define CAB_STATUS_UNSUPPCOMP   0x0000000A

Definition at line 33 of file cabinet.h.

◆ CS_BADSTREAM

#define CS_BADSTREAM   0x0002 /* Bad data stream */

Definition at line 43 of file cabinet.h.

◆ CS_NOMEMORY

#define CS_NOMEMORY   0x0001 /* Not enough free memory */

Definition at line 42 of file cabinet.h.

◆ CS_SUCCESS

#define CS_SUCCESS   0x0000 /* All data consumed */

Definition at line 41 of file cabinet.h.

Typedef Documentation

◆ CAB_SEARCH

◆ CABINET_CONTEXT

◆ PCAB_CODEC

Definition at line 38 of file cabinet.h.

◆ PCAB_SEARCH

◆ PCABINET_CONTEXT

◆ PCABINET_CREATE_FILE

typedef PVOID(* PCABINET_CREATE_FILE) (IN struct _CABINET_CONTEXT *CabinetContext, IN ULONG FileSize)

Definition at line 68 of file cabinet.h.

◆ PCABINET_DISK_CHANGE

typedef VOID(* PCABINET_DISK_CHANGE) (IN struct _CABINET_CONTEXT *CabinetContext, IN PCWSTR CabinetName, IN PCWSTR DiskLabel)

Definition at line 63 of file cabinet.h.

◆ PCABINET_EXTRACT

typedef VOID(* PCABINET_EXTRACT) (IN struct _CABINET_CONTEXT *CabinetContext, IN PCFFILE File, IN PCWSTR FileName)

Definition at line 58 of file cabinet.h.

◆ PCABINET_OVERWRITE

typedef BOOL(* PCABINET_OVERWRITE) (IN struct _CABINET_CONTEXT *CabinetContext, IN PCFFILE File, IN PCWSTR FileName)

Definition at line 53 of file cabinet.h.

◆ PCFDATA

Definition at line 15 of file cabinet.h.

◆ PCFFILE

Definition at line 14 of file cabinet.h.

◆ PCFFOLDER

Definition at line 13 of file cabinet.h.

◆ PCFHEADER

Definition at line 12 of file cabinet.h.

Function Documentation

◆ CabinetCleanup()

VOID CabinetCleanup ( IN OUT PCABINET_CONTEXT  CabinetContext)

Definition at line 535 of file cabinet.c.

537{
538 CabinetClose(CabinetContext);
539}
VOID CabinetClose(IN OUT PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:807

Referenced by PrepareFileCopy(), and SetupExtractFile().

◆ CabinetClose()

VOID CabinetClose ( IN OUT PCABINET_CONTEXT  CabinetContext)

Definition at line 807 of file cabinet.c.

809{
810 if (!CabinetContext->FileOpen)
811 return;
812
813 CloseCabinet(CabinetContext);
814 CabinetContext->FileOpen = FALSE;
815}
static ULONG CloseCabinet(IN PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:489
#define FALSE
Definition: types.h:117

Referenced by CabinetCleanup(), and SetConsoleOutputCP().

◆ CabinetExtractFile()

ULONG CabinetExtractFile ( IN PCABINET_CONTEXT  CabinetContext,
IN PCAB_SEARCH  Search 
)

Definition at line 965 of file cabinet.c.

968{
969 ULONG Size; // remaining file bytes to decompress
970 ULONG CurrentOffset; // current uncompressed offset within the folder
971 PUCHAR CurrentBuffer; // current pointer to compressed data in the block
972 LONG RemainingBlock; // remaining comp data in the block
973 HANDLE DestFile;
974 HANDLE DestFileSection;
975 PVOID DestFileBuffer; // mapped view of dest file
976 PVOID CurrentDestBuffer; // pointer to the current position in the dest view
977 PCFDATA CFData; // current data block
979 FILETIME FileTime;
980 WCHAR DestName[MAX_PATH];
981 NTSTATUS NtStatus;
986 FILE_BASIC_INFORMATION FileBasic;
987 PCFFOLDER CurrentFolder;
988 LARGE_INTEGER MaxDestFileSize;
989 LONG InputLength, OutputLength;
990 SIZE_T StringLength;
991 char Chunk[512];
992
993 if (wcscmp(Search->Cabinet, CabinetContext->CabinetName) != 0)
994 {
995 /* the file is not in the current cabinet */
996 DPRINT("File is not in this cabinet (%S != %S)\n",
997 Search->Cabinet, CabinetContext->CabinetName);
998 return CAB_STATUS_NOFILE;
999 }
1000
1001 /* look up the folder that the file specifies */
1002 if (Search->File->FolderIndex == 0xFFFD ||
1003 Search->File->FolderIndex == 0xFFFF)
1004 {
1005 /* folder is continued from previous cabinet,
1006 that shouldn't happen here */
1007 return CAB_STATUS_NOFILE;
1008 }
1009 else if (Search->File->FolderIndex == 0xFFFE)
1010 {
1011 /* folder is the last in this cabinet and continues into next */
1012 CurrentFolder = &CabinetContext->CabinetFolders[CabinetContext->PCABHeader->FolderCount - 1];
1013 }
1014 else
1015 {
1016 /* folder is completely contained within this cabinet */
1017 CurrentFolder = &CabinetContext->CabinetFolders[Search->File->FolderIndex];
1018 }
1019
1020 switch (CurrentFolder->CompressionType & CAB_COMP_MASK)
1021 {
1022 case CAB_COMP_NONE:
1023 CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW);
1024 break;
1025 case CAB_COMP_MSZIP:
1026 CabinetSelectCodec(CabinetContext, CAB_CODEC_MSZIP);
1027 break;
1028 default:
1029 return CAB_STATUS_UNSUPPCOMP;
1030 }
1031
1032 DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n",
1033 (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize);
1034
1035 if (CabinetContext->CreateFileHandler)
1036 {
1037 /* Call create context */
1038 CurrentDestBuffer = CabinetContext->CreateFileHandler(CabinetContext, Search->File->FileSize);
1039 if (!CurrentDestBuffer)
1040 {
1041 DPRINT1("CreateFileHandler() failed\n");
1043 }
1044 }
1045 else
1046 {
1047 RtlInitAnsiString(&AnsiString, Search->File->FileName);
1048 wcscpy(DestName, CabinetContext->DestPath);
1049 StringLength = wcslen(DestName);
1050 UnicodeString.MaximumLength = sizeof(DestName) - (USHORT)StringLength * sizeof(WCHAR);
1051 UnicodeString.Buffer = DestName + StringLength;
1052 UnicodeString.Length = 0;
1054
1055 /* Create destination file, fail if it already exists */
1057
1061 NULL, NULL);
1062
1063 NtStatus = NtCreateFile(&DestFile,
1067 NULL,
1069 0,
1072 NULL, 0);
1073
1074 if (!NT_SUCCESS(NtStatus))
1075 {
1076 DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
1077
1078 /* If file exists, ask to overwrite file */
1079 if (CabinetContext->OverwriteHandler == NULL ||
1080 CabinetContext->OverwriteHandler(CabinetContext, Search->File, DestName))
1081 {
1082 /* Create destination file, overwrite if it already exists */
1083 NtStatus = NtCreateFile(&DestFile,
1087 NULL,
1089 0,
1092 NULL, 0);
1093
1094 if (!NT_SUCCESS(NtStatus))
1095 {
1096 DPRINT1("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
1098 }
1099 }
1100 else
1101 {
1102 DPRINT1("File (%S) exists\n", DestName);
1104 }
1105 }
1106
1107 if (!ConvertDosDateTimeToFileTime(Search->File->FileDate,
1108 Search->File->FileTime,
1109 &FileTime))
1110 {
1111 DPRINT1("DosDateTimeToFileTime() failed\n");
1113 goto CloseDestFile;
1114 }
1115
1116 NtStatus = NtQueryInformationFile(DestFile,
1118 &FileBasic,
1119 sizeof(FILE_BASIC_INFORMATION),
1121 if (!NT_SUCCESS(NtStatus))
1122 {
1123 DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
1124 }
1125 else
1126 {
1127 memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME));
1128
1129 NtStatus = NtSetInformationFile(DestFile,
1131 &FileBasic,
1132 sizeof(FILE_BASIC_INFORMATION),
1134 if (!NT_SUCCESS(NtStatus))
1135 {
1136 DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
1137 }
1138 }
1139
1140 SetAttributesOnFile(Search->File, DestFile);
1141
1142 /* Nothing more to do for 0 sized files */
1143 if (Search->File->FileSize == 0)
1144 {
1146 goto CloseDestFile;
1147 }
1148
1149 MaxDestFileSize.QuadPart = Search->File->FileSize;
1150 NtStatus = NtCreateSection(&DestFileSection,
1152 0,
1153 &MaxDestFileSize,
1155 SEC_COMMIT,
1156 DestFile);
1157
1158 if (!NT_SUCCESS(NtStatus))
1159 {
1160 DPRINT1("NtCreateSection failed for %ls: %x\n", DestName, NtStatus);
1162 goto CloseDestFile;
1163 }
1164
1165 DestFileBuffer = 0;
1166 CabinetContext->DestFileSize = 0;
1167 NtStatus = NtMapViewOfSection(DestFileSection,
1169 &DestFileBuffer,
1170 0, 0, 0,
1171 &CabinetContext->DestFileSize,
1172 ViewUnmap,
1173 0,
1175
1176 if (!NT_SUCCESS(NtStatus))
1177 {
1178 DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
1180 goto CloseDestFileSection;
1181 }
1182
1183 CurrentDestBuffer = DestFileBuffer;
1184 }
1185
1186 /* Call extract event handler */
1187 if (CabinetContext->ExtractHandler != NULL)
1188 CabinetContext->ExtractHandler(CabinetContext, Search->File, DestName);
1189
1190 if (Search->CFData)
1191 CFData = Search->CFData;
1192 else
1193 CFData = (PCFDATA)(CabinetContext->CabinetFolders[Search->File->FolderIndex].DataOffset + CabinetContext->FileBuffer);
1194
1195 CurrentOffset = Search->Offset;
1196 while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset)
1197 {
1198 /* walk the data blocks until we reach
1199 the one containing the start of the file */
1200 CurrentOffset += CFData->UncompSize;
1201 CFData = (PCFDATA)((char *)(CFData + 1) + CabinetContext->DataReserved + CFData->CompSize);
1202 }
1203
1204 Search->CFData = CFData;
1205 Search->Offset = CurrentOffset;
1206
1207 /* now decompress and discard any data in
1208 the block before the start of the file */
1209
1210 /* start of comp data */
1211 CurrentBuffer = ((unsigned char *)(CFData + 1)) + CabinetContext->DataReserved;
1212 RemainingBlock = CFData->CompSize;
1213 InputLength = RemainingBlock;
1214
1215 while (CurrentOffset < Search->File->FileOffset)
1216 {
1217 /* compute remaining uncomp bytes to start
1218 of file, bounded by size of chunk */
1219 OutputLength = Search->File->FileOffset - CurrentOffset;
1220 if (OutputLength > (LONG)sizeof(Chunk))
1221 OutputLength = sizeof(Chunk);
1222
1223 /* negate to signal NOT end of block */
1224 OutputLength = -OutputLength;
1225
1226 CabinetContext->Codec->Uncompress(CabinetContext->Codec,
1227 Chunk,
1229 &InputLength,
1230 &OutputLength);
1231
1232 /* add the uncomp bytes extracted to current folder offset */
1233 CurrentOffset += OutputLength;
1234 /* add comp bytes consumed to CurrentBuffer */
1235 CurrentBuffer += InputLength;
1236 /* subtract bytes consumed from bytes remaining in block */
1237 RemainingBlock -= InputLength;
1238 /* neg for resume decompression of the same block */
1239 InputLength = -RemainingBlock;
1240 }
1241
1242 /* now CurrentBuffer points to the first comp byte
1243 of the file, so we can begin decompressing */
1244
1245 /* Size = remaining uncomp bytes of the file to decompress */
1246 Size = Search->File->FileSize;
1247 while (Size > 0)
1248 {
1249 OutputLength = Size;
1250 DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n",
1251 CurrentBuffer, RemainingBlock, Size);
1252
1253 Status = CabinetContext->Codec->Uncompress(CabinetContext->Codec,
1254 CurrentDestBuffer,
1256 &InputLength,
1257 &OutputLength);
1258 if (Status != CS_SUCCESS)
1259 {
1260 DPRINT("Cannot uncompress block\n");
1261 if (Status == CS_NOMEMORY)
1263 else
1265 goto UnmapDestFile;
1266 }
1267
1268 /* advance dest buffer by bytes produced */
1269 CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength);
1270 /* advance src buffer by bytes consumed */
1271 CurrentBuffer += InputLength;
1272 /* reduce remaining file bytes by bytes produced */
1273 Size -= OutputLength;
1274 /* reduce remaining block size by bytes consumed */
1275 RemainingBlock -= InputLength;
1276 if (Size > 0 && RemainingBlock == 0)
1277 {
1278 /* used up this block, move on to the next */
1279 DPRINT("Out of block data\n");
1280 CFData = (PCFDATA)CurrentBuffer;
1281 RemainingBlock = CFData->CompSize;
1282 CurrentBuffer = (unsigned char *)(CFData + 1) + CabinetContext->DataReserved;
1283 InputLength = RemainingBlock;
1284 }
1285 }
1286
1288
1289UnmapDestFile:
1290 if (!CabinetContext->CreateFileHandler)
1291 NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);
1292
1293CloseDestFileSection:
1294 if (!CabinetContext->CreateFileHandler)
1295 NtClose(DestFileSection);
1296
1297CloseDestFile:
1298 if (!CabinetContext->CreateFileHandler)
1299 NtClose(DestFile);
1300
1301 return Status;
1302}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3481
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:3074
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:3255
static ACPI_BUFFER CurrentBuffer
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define CAB_STATUS_NOFILE
Definition: cabinet.h:32
#define CAB_CODEC_MSZIP
Definition: cabinet.h:48
#define CAB_STATUS_UNSUPPCOMP
Definition: cabinet.h:33
#define CAB_STATUS_FILE_EXISTS
Definition: cabinet.h:30
#define CS_NOMEMORY
Definition: cabinet.h:42
#define CS_SUCCESS
Definition: cabinet.h:41
#define CAB_STATUS_NOMEMORY
Definition: cabinet.h:25
#define CAB_CODEC_RAW
Definition: cabinet.h:46
#define CAB_STATUS_CANNOT_CREATE
Definition: cabinet.h:27
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
#define CAB_STATUS_CANNOT_WRITE
Definition: cabinet.h:29
#define CAB_STATUS_INVALID_CAB
Definition: cabinet.h:31
static BOOL SetAttributesOnFile(PCFFILE File, HANDLE hFile)
Definition: cabinet.c:433
static BOOL ConvertDosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, LPFILETIME lpFileTime)
Definition: cabinet.c:354
struct _CFDATA * PCFDATA
#define CAB_COMP_MASK
Definition: cabinet.c:53
#define CAB_COMP_NONE
Definition: cabinet.c:54
VOID CabinetSelectCodec(IN PCABINET_CONTEXT CabinetContext, IN ULONG Id)
Definition: cabinet.c:1310
#define CAB_COMP_MSZIP
Definition: cabinet.c:55
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
Definition: File.h:16
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
@ AnsiString
Definition: dnslib.h:19
@ FileBasicInformation
Definition: from_kernel.h:65
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
unsigned int UINT
Definition: ndis.h:50
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SYNCHRONIZE
Definition: nt_native.h:61
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
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:3096
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
@ ViewUnmap
Definition: nt_native.h:1279
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
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)
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define DPRINT
Definition: sndvol32.h:73
USHORT CompSize
Definition: cabinet.c:131
USHORT UncompSize
Definition: cabinet.c:132
USHORT CompressionType
Definition: cabinet.c:110
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by SetConsoleOutputCP(), and SetupExtractFile().

◆ CabinetFindFirst()

ULONG CabinetFindFirst ( IN PCABINET_CONTEXT  CabinetContext,
IN PCWSTR  FileName,
IN OUT PCAB_SEARCH  Search 
)

Definition at line 826 of file cabinet.c.

830{
831 DPRINT("CabinetFindFirst(FileName = %S)\n", FileName);
832 wcsncpy(Search->Search, FileName, MAX_PATH);
833 wcsncpy(Search->Cabinet, CabinetContext->CabinetName, MAX_PATH);
834 Search->File = 0;
835 return CabinetFindNext(CabinetContext, Search);
836}
ULONG CabinetFindNext(IN PCABINET_CONTEXT CabinetContext, IN OUT PCAB_SEARCH Search)
Definition: cabinet.c:846
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)

Referenced by SetConsoleOutputCP(), and SetupExtractFile().

◆ CabinetFindNext()

ULONG CabinetFindNext ( IN PCABINET_CONTEXT  CabinetContext,
IN OUT PCAB_SEARCH  Search 
)

Definition at line 846 of file cabinet.c.

849{
850 PCFFILE Prev;
854
855 if (wcscmp(Search->Cabinet, CabinetContext->CabinetName) != 0)
856 {
857 /* restart search of cabinet has changed since last find */
858 Search->File = 0;
859 }
860
861 if (!Search->File)
862 {
863 /* starting new search or cabinet */
864 Search->File = (PCFFILE)(CabinetContext->FileBuffer + CabinetContext->PCABHeader->FileTableOffset);
865 Search->Index = 0;
866 Prev = 0;
867 }
868 else
869 Prev = Search->File;
870
871 while (TRUE)
872 {
873 /* look at each file in the archive and see if we found a match */
874 if (Search->File->FolderIndex == 0xFFFD ||
875 Search->File->FolderIndex == 0xFFFF)
876 {
877 /* skip files continued from previous cab */
878 DPRINT("Skipping file (%s): FileOffset (0x%X), "
879 "LastFileOffset (0x%X)\n", (char *)(Search->File + 1),
880 Search->File->FileOffset, CabinetContext->LastFileOffset);
881 }
882 else
883 {
884 // FIXME: check for match against search criteria
885 if (Search->File != Prev)
886 {
887 if (Prev == NULL || Search->File->FolderIndex != Prev->FolderIndex)
888 {
889 Search->CFData = NULL;
890 Search->Offset = 0;
891 }
892
893 /* don't match the file we started with */
894 if (wcscmp(Search->Search, L"*") == 0)
895 {
896 /* take any file */
897 break;
898 }
899 else
900 {
901 /* otherwise, try to match the exact file name */
902 RtlInitAnsiString(&AnsiString, Search->File->FileName);
903 UnicodeString.Buffer = FileName;
904 UnicodeString.Buffer[0] = 0;
905 UnicodeString.Length = 0;
906 UnicodeString.MaximumLength = sizeof(FileName);
908 if (wcscmp(Search->Search, UnicodeString.Buffer) == 0)
909 break;
910 }
911 }
912 }
913
914 /* if we make it here we found no match, so move to the next file */
915 Search->Index++;
916 if (Search->Index >= CabinetContext->PCABHeader->FileCount)
917 {
918 /* we have reached the end of this cabinet */
919 DPRINT("End of cabinet reached\n");
920 return CAB_STATUS_NOFILE;
921 }
922 else
923 Search->File = (PCFFILE)(strchr((char *)(Search->File + 1), 0) + 1);
924 }
925
926 DPRINT("Found file %s\n", Search->File->FileName);
927 return CAB_STATUS_SUCCESS;
928}
char * strchr(const char *String, int ch)
Definition: utclib.c:501
struct _CFFILE * PCFFILE
#define TRUE
Definition: types.h:120
struct _FileName FileName
Definition: fatprocs.h:897
#define L(x)
Definition: ntvdm.h:50
USHORT FolderIndex
Definition: cabinet.c:120

Referenced by CabinetFindFirst(), and CabinetFindNextFileSequential().

◆ CabinetFindNextFileSequential()

ULONG CabinetFindNextFileSequential ( IN PCABINET_CONTEXT  CabinetContext,
IN PCWSTR  FileName,
IN OUT PCAB_SEARCH  Search 
)

Definition at line 939 of file cabinet.c.

943{
944 DPRINT("CabinetFindNextFileSequential(FileName = %S)\n", FileName);
945 wcsncpy(Search->Search, FileName, MAX_PATH);
946 return CabinetFindNext(CabinetContext, Search);
947}

Referenced by SetupExtractFile().

◆ CabinetGetCabinetName()

PCWSTR CabinetGetCabinetName ( IN PCABINET_CONTEXT  CabinetContext)

Definition at line 574 of file cabinet.c.

576{
577 return CabinetContext->CabinetName;
578}

Referenced by SetupExtractFile().

◆ CabinetGetCabinetReservedArea()

PVOID CabinetGetCabinetReservedArea ( IN PCABINET_CONTEXT  CabinetContext,
OUT PULONG  Size 
)

Definition at line 1372 of file cabinet.c.

1375{
1376 if (CabinetContext->CabinetReservedArea != NULL)
1377 {
1378 if (Size != NULL)
1379 {
1380 *Size = CabinetContext->CabinetReserved;
1381 }
1382
1383 return CabinetContext->CabinetReservedArea;
1384 }
1385 else
1386 {
1387 if (Size != NULL)
1388 {
1389 *Size = 0;
1390 }
1391
1392 return NULL;
1393 }
1394}

Referenced by PrepareFileCopy().

◆ CabinetGetDestinationPath()

PCWSTR CabinetGetDestinationPath ( IN PCABINET_CONTEXT  CabinetContext)

Definition at line 615 of file cabinet.c.

617{
618 return CabinetContext->DestPath;
619}

◆ CabinetInitialize()

VOID CabinetInitialize ( IN OUT PCABINET_CONTEXT  CabinetContext)

Definition at line 507 of file cabinet.c.

509{
510 RtlZeroMemory(CabinetContext, sizeof(*CabinetContext));
511
512 CabinetContext->FileOpen = FALSE;
513 wcscpy(CabinetContext->DestPath, L"");
514
515 CabinetContext->CodecSelected = FALSE;
516 CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW);
517
518 CabinetContext->OverwriteHandler = NULL;
519 CabinetContext->ExtractHandler = NULL;
520 CabinetContext->DiskChangeHandler = NULL;
521
522 CabinetContext->FolderUncompSize = 0;
523 CabinetContext->BytesLeftInBlock = 0;
524 CabinetContext->CabinetReserved = 0;
525 CabinetContext->FolderReserved = 0;
526 CabinetContext->DataReserved = 0;
527 CabinetContext->CabinetReservedArea = NULL;
528 CabinetContext->LastFileOffset = 0;
529}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by PrepareFileCopy(), SetConsoleOutputCP(), and SetupExtractFile().

◆ CabinetOpen()

ULONG CabinetOpen ( IN OUT PCABINET_CONTEXT  CabinetContext)

Definition at line 627 of file cabinet.c.

629{
632 ANSI_STRING astring;
633
637 USHORT StringLength;
638 NTSTATUS NtStatus;
639
640 if (CabinetContext->FileOpen)
641 {
642 /* Cabinet file already opened */
643 DPRINT("CabinetOpen returning SUCCESS\n");
644 return CAB_STATUS_SUCCESS;
645 }
646
647 RtlInitUnicodeString(&FileName, CabinetContext->CabinetName);
648
650 &FileName,
652 NULL, NULL);
653
654 NtStatus = NtOpenFile(&CabinetContext->FileHandle,
660
661 if (!NT_SUCCESS(NtStatus))
662 {
663 DPRINT1("Cannot open file (%S) (%x)\n", CabinetContext->CabinetName, NtStatus);
665 }
666
667 CabinetContext->FileOpen = TRUE;
668
669 NtStatus = NtCreateSection(&CabinetContext->FileSectionHandle,
671 0, 0,
674 CabinetContext->FileHandle);
675
676 if (!NT_SUCCESS(NtStatus))
677 {
678 DPRINT1("NtCreateSection failed for %ls: %x\n", CabinetContext->CabinetName, NtStatus);
679 return CAB_STATUS_NOMEMORY;
680 }
681
682 CabinetContext->FileBuffer = 0;
683 CabinetContext->FileSize = 0;
684
685 NtStatus = NtMapViewOfSection(CabinetContext->FileSectionHandle,
687 (PVOID*)&CabinetContext->FileBuffer,
688 0, 0, 0,
689 &CabinetContext->FileSize,
690 ViewUnmap,
691 0,
693
694 if (!NT_SUCCESS(NtStatus))
695 {
696 DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
697 return CAB_STATUS_NOMEMORY;
698 }
699
700 DPRINT("Cabinet file %S opened and mapped to %x\n",
701 CabinetContext->CabinetName, CabinetContext->FileBuffer);
702 CabinetContext->PCABHeader = (PCFHEADER)CabinetContext->FileBuffer;
703
704 /* Check header */
705 if (CabinetContext->FileSize <= sizeof(CFHEADER) ||
706 CabinetContext->PCABHeader->Signature != CAB_SIGNATURE ||
707 CabinetContext->PCABHeader->Version != CAB_VERSION ||
708 CabinetContext->PCABHeader->FolderCount == 0 ||
709 CabinetContext->PCABHeader->FileCount == 0 ||
710 CabinetContext->PCABHeader->FileTableOffset < sizeof(CFHEADER))
711 {
712 CloseCabinet(CabinetContext);
713 DPRINT1("File has invalid header\n");
715 }
716
717 Buffer = (PUCHAR)(CabinetContext->PCABHeader + 1);
718
719 /* Read/skip any reserved bytes */
720 if (CabinetContext->PCABHeader->Flags & CAB_FLAG_RESERVE)
721 {
722 CabinetContext->CabinetReserved = *(PUSHORT)Buffer;
723 Buffer += 2;
724 CabinetContext->FolderReserved = *Buffer;
725 Buffer++;
726 CabinetContext->DataReserved = *Buffer;
727 Buffer++;
728
729 if (CabinetContext->CabinetReserved > 0)
730 {
731 CabinetContext->CabinetReservedArea = Buffer;
732 Buffer += CabinetContext->CabinetReserved;
733 }
734 }
735
736 if (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASPREV)
737 {
738 /* The previous cabinet file is in
739 the same directory as the current */
740 wcscpy(CabinetContext->CabinetPrev, CabinetContext->CabinetName);
741 RemoveFileName(CabinetContext->CabinetPrev);
742 CabinetNormalizePath(CabinetContext->CabinetPrev, sizeof(CabinetContext->CabinetPrev));
743 RtlInitAnsiString(&astring, (LPSTR)Buffer);
744
745 /* Initialize ustring with the remaining buffer */
746 StringLength = (USHORT)wcslen(CabinetContext->CabinetPrev) * sizeof(WCHAR);
747 ustring.Buffer = CabinetContext->CabinetPrev + StringLength;
748 ustring.MaximumLength = sizeof(CabinetContext->CabinetPrev) - StringLength;
749 ustring.Length = 0;
751 Buffer += astring.Length + 1;
752
753 /* Read label of prev disk */
754 RtlInitAnsiString(&astring, (LPSTR)Buffer);
755 ustring.Length = 0;
756 ustring.Buffer = CabinetContext->DiskPrev;
757 ustring.MaximumLength = sizeof(CabinetContext->DiskPrev);
759 Buffer += astring.Length + 1;
760 }
761 else
762 {
763 wcscpy(CabinetContext->CabinetPrev, L"");
764 wcscpy(CabinetContext->DiskPrev, L"");
765 }
766
767 if (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASNEXT)
768 {
769 /* The next cabinet file is in
770 the same directory as the previous */
771 wcscpy(CabinetContext->CabinetNext, CabinetContext->CabinetName);
772 RemoveFileName(CabinetContext->CabinetNext);
773 CabinetNormalizePath(CabinetContext->CabinetNext, 256);
774 RtlInitAnsiString(&astring, (LPSTR)Buffer);
775
776 /* Initialize ustring with the remaining buffer */
777 StringLength = (USHORT)wcslen(CabinetContext->CabinetNext) * sizeof(WCHAR);
778 ustring.Buffer = CabinetContext->CabinetNext + StringLength;
779 ustring.MaximumLength = sizeof(CabinetContext->CabinetNext) - StringLength;
780 ustring.Length = 0;
782 Buffer += astring.Length + 1;
783
784 /* Read label of next disk */
785 RtlInitAnsiString(&astring, (LPSTR)Buffer);
786 ustring.Length = 0;
787 ustring.Buffer = CabinetContext->DiskNext;
788 ustring.MaximumLength = sizeof(CabinetContext->DiskNext);
790 Buffer += astring.Length + 1;
791 }
792 else
793 {
794 wcscpy(CabinetContext->CabinetNext, L"");
795 wcscpy(CabinetContext->DiskNext, L"");
796 }
797 CabinetContext->CabinetFolders = (PCFFOLDER)Buffer;
798
799 DPRINT("CabinetOpen returning SUCCESS\n");
800 return CAB_STATUS_SUCCESS;
801}
#define CAB_STATUS_CANNOT_OPEN
Definition: cabinet.h:26
struct _CFFOLDER * PCFFOLDER
struct _CFHEADER CFHEADER
#define CAB_VERSION
Definition: cabinet.c:50
#define CAB_SIGNATURE
Definition: cabinet.c:49
static BOOL CabinetNormalizePath(PWCHAR Path, ULONG Length)
Definition: cabinet.c:550
#define CAB_FLAG_HASNEXT
Definition: cabinet.c:60
#define CAB_FLAG_RESERVE
Definition: cabinet.c:61
#define CAB_FLAG_HASPREV
Definition: cabinet.c:59
struct _CFHEADER * PCFHEADER
static VOID RemoveFileName(PWCHAR Path)
Definition: cabinet.c:408
Definition: bufpool.h:45
#define PAGE_READONLY
Definition: compat.h:138
#define FILE_SHARE_READ
Definition: compat.h:136
if(dx< 0)
Definition: linetemp.h:194
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:3952
Definition: fci.c:65
Definition: config.c:19
DWORD Length
Definition: config.c:20
DWORD MaximumLength
Definition: config.c:21
unsigned char * Buffer
Definition: config.c:22
uint16_t * PUSHORT
Definition: typedefs.h:56
char * LPSTR
Definition: xmlstorage.h:182

Referenced by PrepareFileCopy(), SetConsoleOutputCP(), and SetupExtractFile().

◆ CabinetSelectCodec()

VOID CabinetSelectCodec ( IN PCABINET_CONTEXT  CabinetContext,
IN ULONG  Id 
)

Definition at line 1310 of file cabinet.c.

1313{
1314 if (CabinetContext->CodecSelected)
1315 {
1316 if (Id == CabinetContext->CodecId)
1317 return;
1318
1319 CabinetContext->CodecSelected = FALSE;
1320 }
1321
1322 switch (Id)
1323 {
1324 case CAB_CODEC_RAW:
1325 {
1326 CabinetContext->Codec = &RawCodec;
1327 break;
1328 }
1329
1330 case CAB_CODEC_MSZIP:
1331 {
1332 CabinetContext->Codec = &MSZipCodec;
1333 CabinetContext->Codec->ZStream.zalloc = MSZipAlloc;
1334 CabinetContext->Codec->ZStream.zfree = MSZipFree;
1335 CabinetContext->Codec->ZStream.opaque = (voidpf)0;
1336 break;
1337 }
1338
1339 default:
1340 return;
1341 }
1342
1343 CabinetContext->CodecId = Id;
1344 CabinetContext->CodecSelected = TRUE;
1345}
DWORD Id
voidpf MSZipAlloc(voidpf opaque, uInt items, uInt size)
Definition: cabinet.c:317
static CAB_CODEC RawCodec
Definition: cabinet.c:211
void MSZipFree(voidpf opaque, voidpf address)
Definition: cabinet.c:323
static CAB_CODEC MSZipCodec
Definition: cabinet.c:308
void FAR * voidpf
Definition: zlib.h:42
z_stream ZStream
Definition: cabinet.c:178
alloc_func zalloc
Definition: zlib.h:70

Referenced by CabinetExtractFile(), and CabinetInitialize().

◆ CabinetSetCabinetName()

VOID CabinetSetCabinetName ( IN PCABINET_CONTEXT  CabinetContext,
IN PCWSTR  FileName 
)

Definition at line 586 of file cabinet.c.

589{
590 wcscpy(CabinetContext->CabinetName, FileName);
591}

Referenced by PrepareFileCopy(), SetConsoleOutputCP(), and SetupExtractFile().

◆ CabinetSetDestinationPath()

VOID CabinetSetDestinationPath ( IN PCABINET_CONTEXT  CabinetContext,
IN PCWSTR  DestinationPath 
)

Definition at line 599 of file cabinet.c.

602{
603 wcscpy(CabinetContext->DestPath, DestinationPath);
604
605 if (wcslen(CabinetContext->DestPath) > 0)
606 CabinetNormalizePath(CabinetContext->DestPath, MAX_PATH);
607}

Referenced by SetupExtractFile().

◆ CabinetSetEventHandlers()

VOID CabinetSetEventHandlers ( IN PCABINET_CONTEXT  CabinetContext,
IN PCABINET_OVERWRITE  Overwrite,
IN PCABINET_EXTRACT  Extract,
IN PCABINET_DISK_CHANGE  DiskChange,
IN PCABINET_CREATE_FILE  CreateFile 
)

Definition at line 1355 of file cabinet.c.

1361{
1362 CabinetContext->OverwriteHandler = Overwrite;
1363 CabinetContext->ExtractHandler = Extract;
1364 CabinetContext->DiskChangeHandler = DiskChange;
1365 CabinetContext->CreateFileHandler = CreateFile;
1366}
HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName)
Definition: cabinet_main.c:328
#define CreateFile
Definition: winbase.h:3774

Referenced by PrepareFileCopy(), SetConsoleOutputCP(), and SetupExtractFile().