ReactOS 0.4.15-dev-7136-g77ab709
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 529 of file cabinet.c.

531{
532 CabinetClose(CabinetContext);
533}
VOID CabinetClose(IN OUT PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:801

Referenced by PrepareFileCopy(), and SetupExtractFile().

◆ CabinetClose()

VOID CabinetClose ( IN OUT PCABINET_CONTEXT  CabinetContext)

Definition at line 801 of file cabinet.c.

803{
804 if (!CabinetContext->FileOpen)
805 return;
806
807 CloseCabinet(CabinetContext);
808 CabinetContext->FileOpen = FALSE;
809}
static ULONG CloseCabinet(IN PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:483
#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 959 of file cabinet.c.

962{
963 ULONG Size; // remaining file bytes to decompress
964 ULONG CurrentOffset; // current uncompressed offset within the folder
965 PUCHAR CurrentBuffer; // current pointer to compressed data in the block
966 LONG RemainingBlock; // remaining comp data in the block
967 HANDLE DestFile;
968 HANDLE DestFileSection;
969 PVOID DestFileBuffer; // mapped view of dest file
970 PVOID CurrentDestBuffer; // pointer to the current position in the dest view
971 PCFDATA CFData; // current data block
973 FILETIME FileTime;
974 WCHAR DestName[MAX_PATH];
975 NTSTATUS NtStatus;
980 FILE_BASIC_INFORMATION FileBasic;
981 PCFFOLDER CurrentFolder;
982 LARGE_INTEGER MaxDestFileSize;
983 LONG InputLength, OutputLength;
984 SIZE_T StringLength;
985 char Chunk[512];
986
987 if (wcscmp(Search->Cabinet, CabinetContext->CabinetName) != 0)
988 {
989 /* the file is not in the current cabinet */
990 DPRINT("File is not in this cabinet (%S != %S)\n",
991 Search->Cabinet, CabinetContext->CabinetName);
992 return CAB_STATUS_NOFILE;
993 }
994
995 /* look up the folder that the file specifies */
996 if (Search->File->FolderIndex == 0xFFFD ||
997 Search->File->FolderIndex == 0xFFFF)
998 {
999 /* folder is continued from previous cabinet,
1000 that shouldn't happen here */
1001 return CAB_STATUS_NOFILE;
1002 }
1003 else if (Search->File->FolderIndex == 0xFFFE)
1004 {
1005 /* folder is the last in this cabinet and continues into next */
1006 CurrentFolder = &CabinetContext->CabinetFolders[CabinetContext->PCABHeader->FolderCount - 1];
1007 }
1008 else
1009 {
1010 /* folder is completely contained within this cabinet */
1011 CurrentFolder = &CabinetContext->CabinetFolders[Search->File->FolderIndex];
1012 }
1013
1014 switch (CurrentFolder->CompressionType & CAB_COMP_MASK)
1015 {
1016 case CAB_COMP_NONE:
1017 CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW);
1018 break;
1019 case CAB_COMP_MSZIP:
1020 CabinetSelectCodec(CabinetContext, CAB_CODEC_MSZIP);
1021 break;
1022 default:
1023 return CAB_STATUS_UNSUPPCOMP;
1024 }
1025
1026 DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n",
1027 (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize);
1028
1029 if (CabinetContext->CreateFileHandler)
1030 {
1031 /* Call create context */
1032 CurrentDestBuffer = CabinetContext->CreateFileHandler(CabinetContext, Search->File->FileSize);
1033 if (!CurrentDestBuffer)
1034 {
1035 DPRINT1("CreateFileHandler() failed\n");
1037 }
1038 }
1039 else
1040 {
1041 RtlInitAnsiString(&AnsiString, Search->File->FileName);
1042 wcscpy(DestName, CabinetContext->DestPath);
1043 StringLength = wcslen(DestName);
1044 UnicodeString.MaximumLength = sizeof(DestName) - (USHORT)StringLength * sizeof(WCHAR);
1045 UnicodeString.Buffer = DestName + StringLength;
1046 UnicodeString.Length = 0;
1048
1049 /* Create destination file, fail if it already exists */
1051
1055 NULL, NULL);
1056
1057 NtStatus = NtCreateFile(&DestFile,
1061 NULL,
1063 0,
1066 NULL, 0);
1067
1068 if (!NT_SUCCESS(NtStatus))
1069 {
1070 DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
1071
1072 /* If file exists, ask to overwrite file */
1073 if (CabinetContext->OverwriteHandler == NULL ||
1074 CabinetContext->OverwriteHandler(CabinetContext, Search->File, DestName))
1075 {
1076 /* Create destination file, overwrite if it already exists */
1077 NtStatus = NtCreateFile(&DestFile,
1081 NULL,
1083 0,
1086 NULL, 0);
1087
1088 if (!NT_SUCCESS(NtStatus))
1089 {
1090 DPRINT1("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
1092 }
1093 }
1094 else
1095 {
1096 DPRINT1("File (%S) exists\n", DestName);
1098 }
1099 }
1100
1101 MaxDestFileSize.QuadPart = Search->File->FileSize;
1102 NtStatus = NtCreateSection(&DestFileSection,
1104 0,
1105 &MaxDestFileSize,
1107 SEC_COMMIT,
1108 DestFile);
1109
1110 if (!NT_SUCCESS(NtStatus))
1111 {
1112 DPRINT1("NtCreateSection failed for %ls: %x\n", DestName, NtStatus);
1114 goto CloseDestFile;
1115 }
1116
1117 DestFileBuffer = 0;
1118 CabinetContext->DestFileSize = 0;
1119 NtStatus = NtMapViewOfSection(DestFileSection,
1121 &DestFileBuffer,
1122 0, 0, 0,
1123 &CabinetContext->DestFileSize,
1124 ViewUnmap,
1125 0,
1127
1128 if (!NT_SUCCESS(NtStatus))
1129 {
1130 DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
1132 goto CloseDestFileSection;
1133 }
1134
1135 CurrentDestBuffer = DestFileBuffer;
1136 if (!ConvertDosDateTimeToFileTime(Search->File->FileDate,
1137 Search->File->FileTime,
1138 &FileTime))
1139 {
1140 DPRINT1("DosDateTimeToFileTime() failed\n");
1142 goto UnmapDestFile;
1143 }
1144
1145 NtStatus = NtQueryInformationFile(DestFile,
1147 &FileBasic,
1148 sizeof(FILE_BASIC_INFORMATION),
1150 if (!NT_SUCCESS(NtStatus))
1151 {
1152 DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
1153 }
1154 else
1155 {
1156 memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME));
1157
1158 NtStatus = NtSetInformationFile(DestFile,
1160 &FileBasic,
1161 sizeof(FILE_BASIC_INFORMATION),
1163 if (!NT_SUCCESS(NtStatus))
1164 {
1165 DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
1166 }
1167 }
1168
1169 SetAttributesOnFile(Search->File, DestFile);
1170 }
1171
1172 /* Call extract event handler */
1173 if (CabinetContext->ExtractHandler != NULL)
1174 CabinetContext->ExtractHandler(CabinetContext, Search->File, DestName);
1175
1176 if (Search->CFData)
1177 CFData = Search->CFData;
1178 else
1179 CFData = (PCFDATA)(CabinetContext->CabinetFolders[Search->File->FolderIndex].DataOffset + CabinetContext->FileBuffer);
1180
1181 CurrentOffset = Search->Offset;
1182 while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset)
1183 {
1184 /* walk the data blocks until we reach
1185 the one containing the start of the file */
1186 CurrentOffset += CFData->UncompSize;
1187 CFData = (PCFDATA)((char *)(CFData + 1) + CabinetContext->DataReserved + CFData->CompSize);
1188 }
1189
1190 Search->CFData = CFData;
1191 Search->Offset = CurrentOffset;
1192
1193 /* now decompress and discard any data in
1194 the block before the start of the file */
1195
1196 /* start of comp data */
1197 CurrentBuffer = ((unsigned char *)(CFData + 1)) + CabinetContext->DataReserved;
1198 RemainingBlock = CFData->CompSize;
1199 InputLength = RemainingBlock;
1200
1201 while (CurrentOffset < Search->File->FileOffset)
1202 {
1203 /* compute remaining uncomp bytes to start
1204 of file, bounded by size of chunk */
1205 OutputLength = Search->File->FileOffset - CurrentOffset;
1206 if (OutputLength > (LONG)sizeof(Chunk))
1207 OutputLength = sizeof(Chunk);
1208
1209 /* negate to signal NOT end of block */
1210 OutputLength = -OutputLength;
1211
1212 CabinetContext->Codec->Uncompress(CabinetContext->Codec,
1213 Chunk,
1215 &InputLength,
1216 &OutputLength);
1217
1218 /* add the uncomp bytes extracted to current folder offset */
1219 CurrentOffset += OutputLength;
1220 /* add comp bytes consumed to CurrentBuffer */
1221 CurrentBuffer += InputLength;
1222 /* subtract bytes consumed from bytes remaining in block */
1223 RemainingBlock -= InputLength;
1224 /* neg for resume decompression of the same block */
1225 InputLength = -RemainingBlock;
1226 }
1227
1228 /* now CurrentBuffer points to the first comp byte
1229 of the file, so we can begin decompressing */
1230
1231 /* Size = remaining uncomp bytes of the file to decompress */
1232 Size = Search->File->FileSize;
1233 while (Size > 0)
1234 {
1235 OutputLength = Size;
1236 DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n",
1237 CurrentBuffer, RemainingBlock, Size);
1238
1239 Status = CabinetContext->Codec->Uncompress(CabinetContext->Codec,
1240 CurrentDestBuffer,
1242 &InputLength,
1243 &OutputLength);
1244 if (Status != CS_SUCCESS)
1245 {
1246 DPRINT("Cannot uncompress block\n");
1247 if (Status == CS_NOMEMORY)
1250 goto UnmapDestFile;
1251 }
1252
1253 /* advance dest buffer by bytes produced */
1254 CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength);
1255 /* advance src buffer by bytes consumed */
1256 CurrentBuffer += InputLength;
1257 /* reduce remaining file bytes by bytes produced */
1258 Size -= OutputLength;
1259 /* reduce remaining block size by bytes consumed */
1260 RemainingBlock -= InputLength;
1261 if (Size > 0 && RemainingBlock == 0)
1262 {
1263 /* used up this block, move on to the next */
1264 DPRINT("Out of block data\n");
1265 CFData = (PCFDATA)CurrentBuffer;
1266 RemainingBlock = CFData->CompSize;
1267 CurrentBuffer = (unsigned char *)(CFData + 1) + CabinetContext->DataReserved;
1268 InputLength = RemainingBlock;
1269 }
1270 }
1271
1273
1274UnmapDestFile:
1275 if (!CabinetContext->CreateFileHandler)
1276 NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);
1277
1278CloseDestFileSection:
1279 if (!CabinetContext->CreateFileHandler)
1280 NtClose(DestFileSection);
1281
1282CloseDestFile:
1283 if (!CabinetContext->CreateFileHandler)
1284 NtClose(DestFile);
1285
1286 return Status;
1287}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3848
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:3441
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:3622
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:427
static BOOL ConvertDosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, LPFILETIME lpFileTime)
Definition: cabinet.c:348
struct _CFDATA * PCFDATA
#define CAB_COMP_MASK
Definition: cabinet.c:51
#define CAB_COMP_NONE
Definition: cabinet.c:52
VOID CabinetSelectCodec(IN PCABINET_CONTEXT CabinetContext, IN ULONG Id)
Definition: cabinet.c:1295
#define CAB_COMP_MSZIP
Definition: cabinet.c:53
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:32
#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:71
USHORT CompSize
Definition: cabinet.c:129
USHORT UncompSize
Definition: cabinet.c:130
USHORT CompressionType
Definition: cabinet.c:108
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 820 of file cabinet.c.

824{
825 DPRINT("CabinetFindFirst(FileName = %S)\n", FileName);
826 wcsncpy(Search->Search, FileName, MAX_PATH);
827 wcsncpy(Search->Cabinet, CabinetContext->CabinetName, MAX_PATH);
828 Search->File = 0;
829 return CabinetFindNext(CabinetContext, Search);
830}
ULONG CabinetFindNext(IN PCABINET_CONTEXT CabinetContext, IN OUT PCAB_SEARCH Search)
Definition: cabinet.c:840
_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 840 of file cabinet.c.

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

Referenced by CabinetFindFirst(), and CabinetFindNextFileSequential().

◆ CabinetFindNextFileSequential()

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

Definition at line 933 of file cabinet.c.

937{
938 DPRINT("CabinetFindNextFileSequential(FileName = %S)\n", FileName);
939 wcsncpy(Search->Search, FileName, MAX_PATH);
940 return CabinetFindNext(CabinetContext, Search);
941}

Referenced by SetupExtractFile().

◆ CabinetGetCabinetName()

PCWSTR CabinetGetCabinetName ( IN PCABINET_CONTEXT  CabinetContext)

Definition at line 568 of file cabinet.c.

570{
571 return CabinetContext->CabinetName;
572}

Referenced by SetupExtractFile().

◆ CabinetGetCabinetReservedArea()

PVOID CabinetGetCabinetReservedArea ( IN PCABINET_CONTEXT  CabinetContext,
OUT PULONG  Size 
)

Definition at line 1357 of file cabinet.c.

1360{
1361 if (CabinetContext->CabinetReservedArea != NULL)
1362 {
1363 if (Size != NULL)
1364 {
1365 *Size = CabinetContext->CabinetReserved;
1366 }
1367
1368 return CabinetContext->CabinetReservedArea;
1369 }
1370 else
1371 {
1372 if (Size != NULL)
1373 {
1374 *Size = 0;
1375 }
1376
1377 return NULL;
1378 }
1379}

Referenced by PrepareFileCopy().

◆ CabinetGetDestinationPath()

PCWSTR CabinetGetDestinationPath ( IN PCABINET_CONTEXT  CabinetContext)

Definition at line 609 of file cabinet.c.

611{
612 return CabinetContext->DestPath;
613}

◆ CabinetInitialize()

VOID CabinetInitialize ( IN OUT PCABINET_CONTEXT  CabinetContext)

Definition at line 501 of file cabinet.c.

503{
504 RtlZeroMemory(CabinetContext, sizeof(*CabinetContext));
505
506 CabinetContext->FileOpen = FALSE;
507 wcscpy(CabinetContext->DestPath, L"");
508
509 CabinetContext->CodecSelected = FALSE;
510 CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW);
511
512 CabinetContext->OverwriteHandler = NULL;
513 CabinetContext->ExtractHandler = NULL;
514 CabinetContext->DiskChangeHandler = NULL;
515
516 CabinetContext->FolderUncompSize = 0;
517 CabinetContext->BytesLeftInBlock = 0;
518 CabinetContext->CabinetReserved = 0;
519 CabinetContext->FolderReserved = 0;
520 CabinetContext->DataReserved = 0;
521 CabinetContext->CabinetReservedArea = NULL;
522 CabinetContext->LastFileOffset = 0;
523}
#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 621 of file cabinet.c.

623{
626 ANSI_STRING astring;
627
631 USHORT StringLength;
632 NTSTATUS NtStatus;
633
634 if (CabinetContext->FileOpen)
635 {
636 /* Cabinet file already opened */
637 DPRINT("CabinetOpen returning SUCCESS\n");
638 return CAB_STATUS_SUCCESS;
639 }
640
641 RtlInitUnicodeString(&FileName, CabinetContext->CabinetName);
642
644 &FileName,
646 NULL, NULL);
647
648 NtStatus = NtOpenFile(&CabinetContext->FileHandle,
654
655 if (!NT_SUCCESS(NtStatus))
656 {
657 DPRINT1("Cannot open file (%S) (%x)\n", CabinetContext->CabinetName, NtStatus);
659 }
660
661 CabinetContext->FileOpen = TRUE;
662
663 NtStatus = NtCreateSection(&CabinetContext->FileSectionHandle,
665 0, 0,
668 CabinetContext->FileHandle);
669
670 if (!NT_SUCCESS(NtStatus))
671 {
672 DPRINT1("NtCreateSection failed for %ls: %x\n", CabinetContext->CabinetName, NtStatus);
673 return CAB_STATUS_NOMEMORY;
674 }
675
676 CabinetContext->FileBuffer = 0;
677 CabinetContext->FileSize = 0;
678
679 NtStatus = NtMapViewOfSection(CabinetContext->FileSectionHandle,
681 (PVOID*)&CabinetContext->FileBuffer,
682 0, 0, 0,
683 &CabinetContext->FileSize,
684 ViewUnmap,
685 0,
687
688 if (!NT_SUCCESS(NtStatus))
689 {
690 DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus);
691 return CAB_STATUS_NOMEMORY;
692 }
693
694 DPRINT("Cabinet file %S opened and mapped to %x\n",
695 CabinetContext->CabinetName, CabinetContext->FileBuffer);
696 CabinetContext->PCABHeader = (PCFHEADER)CabinetContext->FileBuffer;
697
698 /* Check header */
699 if (CabinetContext->FileSize <= sizeof(CFHEADER) ||
700 CabinetContext->PCABHeader->Signature != CAB_SIGNATURE ||
701 CabinetContext->PCABHeader->Version != CAB_VERSION ||
702 CabinetContext->PCABHeader->FolderCount == 0 ||
703 CabinetContext->PCABHeader->FileCount == 0 ||
704 CabinetContext->PCABHeader->FileTableOffset < sizeof(CFHEADER))
705 {
706 CloseCabinet(CabinetContext);
707 DPRINT1("File has invalid header\n");
709 }
710
711 Buffer = (PUCHAR)(CabinetContext->PCABHeader + 1);
712
713 /* Read/skip any reserved bytes */
714 if (CabinetContext->PCABHeader->Flags & CAB_FLAG_RESERVE)
715 {
716 CabinetContext->CabinetReserved = *(PUSHORT)Buffer;
717 Buffer += 2;
718 CabinetContext->FolderReserved = *Buffer;
719 Buffer++;
720 CabinetContext->DataReserved = *Buffer;
721 Buffer++;
722
723 if (CabinetContext->CabinetReserved > 0)
724 {
725 CabinetContext->CabinetReservedArea = Buffer;
726 Buffer += CabinetContext->CabinetReserved;
727 }
728 }
729
730 if (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASPREV)
731 {
732 /* The previous cabinet file is in
733 the same directory as the current */
734 wcscpy(CabinetContext->CabinetPrev, CabinetContext->CabinetName);
735 RemoveFileName(CabinetContext->CabinetPrev);
736 CabinetNormalizePath(CabinetContext->CabinetPrev, sizeof(CabinetContext->CabinetPrev));
737 RtlInitAnsiString(&astring, (LPSTR)Buffer);
738
739 /* Initialize ustring with the remaining buffer */
740 StringLength = (USHORT)wcslen(CabinetContext->CabinetPrev) * sizeof(WCHAR);
741 ustring.Buffer = CabinetContext->CabinetPrev + StringLength;
742 ustring.MaximumLength = sizeof(CabinetContext->CabinetPrev) - StringLength;
743 ustring.Length = 0;
745 Buffer += astring.Length + 1;
746
747 /* Read label of prev disk */
748 RtlInitAnsiString(&astring, (LPSTR)Buffer);
749 ustring.Length = 0;
750 ustring.Buffer = CabinetContext->DiskPrev;
751 ustring.MaximumLength = sizeof(CabinetContext->DiskPrev);
753 Buffer += astring.Length + 1;
754 }
755 else
756 {
757 wcscpy(CabinetContext->CabinetPrev, L"");
758 wcscpy(CabinetContext->DiskPrev, L"");
759 }
760
761 if (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASNEXT)
762 {
763 /* The next cabinet file is in
764 the same directory as the previous */
765 wcscpy(CabinetContext->CabinetNext, CabinetContext->CabinetName);
766 RemoveFileName(CabinetContext->CabinetNext);
767 CabinetNormalizePath(CabinetContext->CabinetNext, 256);
768 RtlInitAnsiString(&astring, (LPSTR)Buffer);
769
770 /* Initialize ustring with the remaining buffer */
771 StringLength = (USHORT)wcslen(CabinetContext->CabinetNext) * sizeof(WCHAR);
772 ustring.Buffer = CabinetContext->CabinetNext + StringLength;
773 ustring.MaximumLength = sizeof(CabinetContext->CabinetNext) - StringLength;
774 ustring.Length = 0;
776 Buffer += astring.Length + 1;
777
778 /* Read label of next disk */
779 RtlInitAnsiString(&astring, (LPSTR)Buffer);
780 ustring.Length = 0;
781 ustring.Buffer = CabinetContext->DiskNext;
782 ustring.MaximumLength = sizeof(CabinetContext->DiskNext);
784 Buffer += astring.Length + 1;
785 }
786 else
787 {
788 wcscpy(CabinetContext->CabinetNext, L"");
789 wcscpy(CabinetContext->DiskNext, L"");
790 }
791 CabinetContext->CabinetFolders = (PCFFOLDER)Buffer;
792
793 DPRINT("CabinetOpen returning SUCCESS\n");
794 return CAB_STATUS_SUCCESS;
795}
#define CAB_STATUS_CANNOT_OPEN
Definition: cabinet.h:26
struct _CFFOLDER * PCFFOLDER
struct _CFHEADER CFHEADER
#define CAB_VERSION
Definition: cabinet.c:48
#define CAB_SIGNATURE
Definition: cabinet.c:47
static BOOL CabinetNormalizePath(PWCHAR Path, ULONG Length)
Definition: cabinet.c:544
#define CAB_FLAG_HASNEXT
Definition: cabinet.c:58
#define CAB_FLAG_RESERVE
Definition: cabinet.c:59
#define CAB_FLAG_HASPREV
Definition: cabinet.c:57
struct _CFHEADER * PCFHEADER
static VOID RemoveFileName(PWCHAR Path)
Definition: cabinet.c:402
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 1295 of file cabinet.c.

1298{
1299 if (CabinetContext->CodecSelected)
1300 {
1301 if (Id == CabinetContext->CodecId)
1302 return;
1303
1304 CabinetContext->CodecSelected = FALSE;
1305 }
1306
1307 switch (Id)
1308 {
1309 case CAB_CODEC_RAW:
1310 {
1311 CabinetContext->Codec = &RawCodec;
1312 break;
1313 }
1314
1315 case CAB_CODEC_MSZIP:
1316 {
1317 CabinetContext->Codec = &MSZipCodec;
1318 CabinetContext->Codec->ZStream.zalloc = MSZipAlloc;
1319 CabinetContext->Codec->ZStream.zfree = MSZipFree;
1320 CabinetContext->Codec->ZStream.opaque = (voidpf)0;
1321 break;
1322 }
1323
1324 default:
1325 return;
1326 }
1327
1328 CabinetContext->CodecId = Id;
1329 CabinetContext->CodecSelected = TRUE;
1330}
DWORD Id
voidpf MSZipAlloc(voidpf opaque, uInt items, uInt size)
Definition: cabinet.c:311
static CAB_CODEC RawCodec
Definition: cabinet.c:205
void MSZipFree(voidpf opaque, voidpf address)
Definition: cabinet.c:317
static CAB_CODEC MSZipCodec
Definition: cabinet.c:302
void FAR * voidpf
Definition: zlib.h:42
z_stream ZStream
Definition: cabinet.c:172
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 580 of file cabinet.c.

583{
584 wcscpy(CabinetContext->CabinetName, FileName);
585}

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

◆ CabinetSetDestinationPath()

VOID CabinetSetDestinationPath ( IN PCABINET_CONTEXT  CabinetContext,
IN PCWSTR  DestinationPath 
)

Definition at line 593 of file cabinet.c.

596{
597 wcscpy(CabinetContext->DestPath, DestinationPath);
598
599 if (wcslen(CabinetContext->DestPath) > 0)
600 CabinetNormalizePath(CabinetContext->DestPath, MAX_PATH);
601}

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 1340 of file cabinet.c.

1346{
1347 CabinetContext->OverwriteHandler = Overwrite;
1348 CabinetContext->ExtractHandler = Extract;
1349 CabinetContext->DiskChangeHandler = DiskChange;
1350 CabinetContext->CreateFileHandler = CreateFile;
1351}
HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName)
Definition: cabinet_main.c:328
#define CreateFile
Definition: winbase.h:3684

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