From 33a4dde3d168fc086b417578769a193cbb9662d9 Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Sun, 7 Feb 2010 19:52:10 +0000 Subject: [PATCH] Fix formatting. svn path=/trunk/; revision=45490 --- reactos/base/setup/usetup/cabinet.c | 1544 ++++++++++++++------------- 1 file changed, 798 insertions(+), 746 deletions(-) diff --git a/reactos/base/setup/usetup/cabinet.c b/reactos/base/setup/usetup/cabinet.c index c44521a541a..508b5c4a81d 100644 --- a/reactos/base/setup/usetup/cabinet.c +++ b/reactos/base/setup/usetup/cabinet.c @@ -20,19 +20,19 @@ #define SEEK_END 2 #endif -typedef struct __DOSTIME +typedef struct _DOSTIME { - WORD Second:5; - WORD Minute:6; - WORD Hour:5; + WORD Second:5; + WORD Minute:6; + WORD Hour:5; } DOSTIME, *PDOSTIME; -typedef struct __DOSDATE +typedef struct _DOSDATE { - WORD Day:5; - WORD Month:4; - WORD Year:5; + WORD Day:5; + WORD Month:4; + WORD Year:5; } DOSDATE, *PDOSDATE; static WCHAR CabinetName[256]; // Filename of current cabinet @@ -57,7 +57,7 @@ static ULONG DataReserved = 0; static ULONG CodecId; static PCABINET_CODEC_UNCOMPRESS CodecUncompress = NULL; static BOOL CodecSelected = FALSE; -static ULONG LastFileOffset = 0; // Uncompressed offset of last extracted file +static ULONG LastFileOffset = 0; // Uncompressed offset of last extracted file static PCABINET_OVERWRITE OverwriteHandler = NULL; static PCABINET_EXTRACT ExtractHandler = NULL; static PCABINET_DISK_CHANGE DiskChangeHandler = NULL; @@ -80,7 +80,6 @@ void* __cdecl malloc(size_t _size) return RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, nSize); } - void __cdecl free(void* _ptr) { RtlFreeHeap(ProcessHeap, 0, _ptr); @@ -93,11 +92,6 @@ void* __cdecl calloc(size_t _nmemb, size_t _size) /* RAW codec */ -ULONG -RawCodecUncompress(PVOID OutputBuffer, - PVOID InputBuffer, - PLONG InputLength, - PLONG OutputLength) /* * FUNCTION: Uncompresses data in a buffer * ARGUMENTS: @@ -108,21 +102,20 @@ RawCodecUncompress(PVOID OutputBuffer, * OutputLength = Length of output buffer before, amount filled after * Negative to indicate that this is not the end of the block */ +ULONG +RawCodecUncompress(PVOID OutputBuffer, + PVOID InputBuffer, + PLONG InputLength, + PLONG OutputLength) { - LONG In = abs(*InputLength), Out = abs(*OutputLength); - memcpy(OutputBuffer, InputBuffer, In < Out ? In : Out); - *InputLength = *OutputLength = In < Out ? In : Out; - return CS_SUCCESS; + LONG In = abs(*InputLength), Out = abs(*OutputLength); + memcpy(OutputBuffer, InputBuffer, In < Out ? In : Out); + *InputLength = *OutputLength = In < Out ? In : Out; + return CS_SUCCESS; } - /* MSZIP codec */ -ULONG -MSZipCodecUncompress(PVOID OutputBuffer, - PVOID InputBuffer, - PLONG InputLength, - PLONG OutputLength) /* * FUNCTION: Uncompresses data in a buffer * ARGUMENTS: @@ -133,140 +126,146 @@ MSZipCodecUncompress(PVOID OutputBuffer, * OutputLength = Length of output buffer before, amount filled after * Negative to indicate that this is not the end of the block */ +ULONG +MSZipCodecUncompress(PVOID OutputBuffer, + PVOID InputBuffer, + PLONG InputLength, + PLONG OutputLength) { - USHORT Magic; - INT Status; + USHORT Magic; + INT Status; - DPRINT("MSZipCodecUncompress( OutputBuffer = %x, InputBuffer = %x, InputLength = %d, OutputLength = %d.\n", OutputBuffer, InputBuffer, *InputLength, *OutputLength); - if( *InputLength > 0 ) - { - Magic = *((PUSHORT)InputBuffer); + DPRINT("MSZipCodecUncompress(OutputBuffer = %x, InputBuffer = %x, " + "InputLength = %d, OutputLength = %d)\n", OutputBuffer, + InputBuffer, *InputLength, *OutputLength); + if (*InputLength > 0) + { + Magic = *(PUSHORT)InputBuffer; - if (Magic != MSZIP_MAGIC) - { - DPRINT("Bad MSZIP block header magic (0x%X)\n", Magic); - return CS_BADSTREAM; - } + if (Magic != MSZIP_MAGIC) + { + DPRINT("Bad MSZIP block header magic (0x%X)\n", Magic); + return CS_BADSTREAM; + } - ZStream.next_in = ((PUCHAR)InputBuffer )+ 2; - ZStream.avail_in = *InputLength - 2; - ZStream.next_out = (PUCHAR)OutputBuffer; - ZStream.avail_out = abs(*OutputLength); + ZStream.next_in = (PUCHAR)InputBuffer + 2; + ZStream.avail_in = *InputLength - 2; + ZStream.next_out = (PUCHAR)OutputBuffer; + ZStream.avail_out = abs(*OutputLength); - /* WindowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - */ - Status = inflateInit2(&ZStream, -MAX_WBITS); - if (Status != Z_OK) - { - DPRINT("inflateInit2() returned (%d).\n", Status); - return CS_BADSTREAM; - } - ZStream.total_in = 2; - } - else { - ZStream.avail_in = -*InputLength; - ZStream.next_in = (PUCHAR)InputBuffer; - ZStream.next_out = (PUCHAR)OutputBuffer; - ZStream.avail_out = abs(*OutputLength); - ZStream.total_in = 0; - } - ZStream.total_out = 0; - Status = inflate(&ZStream, Z_SYNC_FLUSH ); - if (Status != Z_OK && Status != Z_STREAM_END) - { - DPRINT("inflate() returned (%d) (%s).\n", Status, ZStream.msg); - if (Status == Z_MEM_ERROR) - return CS_NOMEMORY; - return CS_BADSTREAM; - } + /* WindowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + */ + Status = inflateInit2(&ZStream, -MAX_WBITS); + if (Status != Z_OK) + { + DPRINT("inflateInit2() returned (%d)\n", Status); + return CS_BADSTREAM; + } + ZStream.total_in = 2; + } + else + { + ZStream.avail_in = -*InputLength; + ZStream.next_in = (PUCHAR)InputBuffer; + ZStream.next_out = (PUCHAR)OutputBuffer; + ZStream.avail_out = abs(*OutputLength); + ZStream.total_in = 0; + } - if( *OutputLength > 0 ) - { - Status = inflateEnd(&ZStream); - if (Status != Z_OK) - { - DPRINT("inflateEnd() returned (%d).\n", Status); - return CS_BADSTREAM; - } - } - *OutputLength = ZStream.total_out; - *InputLength = ZStream.total_in; - return CS_SUCCESS; + ZStream.total_out = 0; + Status = inflate(&ZStream, Z_SYNC_FLUSH); + if (Status != Z_OK && Status != Z_STREAM_END) + { + DPRINT("inflate() returned (%d) (%s)\n", Status, ZStream.msg); + if (Status == Z_MEM_ERROR) + return CS_NOMEMORY; + return CS_BADSTREAM; + } + + if (*OutputLength > 0) + { + Status = inflateEnd(&ZStream); + if (Status != Z_OK) + { + DPRINT("inflateEnd() returned (%d)\n", Status); + return CS_BADSTREAM; + } + } + + *OutputLength = ZStream.total_out; + *InputLength = ZStream.total_in; + + return CS_SUCCESS; } - - /* Memory functions */ -voidpf MSZipAlloc(voidpf opaque, uInt items, uInt size) +voidpf +MSZipAlloc(voidpf opaque, uInt items, uInt size) { - return (voidpf)RtlAllocateHeap (ProcessHeap, 0, items * size); + return (voidpf)RtlAllocateHeap(ProcessHeap, 0, items * size); } -void MSZipFree (voidpf opaque, voidpf address) +void +MSZipFree(voidpf opaque, voidpf address) { - RtlFreeHeap(ProcessHeap, 0, address); + RtlFreeHeap(ProcessHeap, 0, address); } static BOOL -ConvertSystemTimeToFileTime( - CONST SYSTEMTIME * lpSystemTime, - LPFILETIME lpFileTime) +ConvertSystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, + LPFILETIME lpFileTime) { - TIME_FIELDS TimeFields; - LARGE_INTEGER liTime; + TIME_FIELDS TimeFields; + LARGE_INTEGER liTime; - TimeFields.Year = lpSystemTime->wYear; - TimeFields.Month = lpSystemTime->wMonth; - TimeFields.Day = lpSystemTime->wDay; - TimeFields.Hour = lpSystemTime->wHour; - TimeFields.Minute = lpSystemTime->wMinute; - TimeFields.Second = lpSystemTime->wSecond; - TimeFields.Milliseconds = lpSystemTime->wMilliseconds; + TimeFields.Year = lpSystemTime->wYear; + TimeFields.Month = lpSystemTime->wMonth; + TimeFields.Day = lpSystemTime->wDay; + TimeFields.Hour = lpSystemTime->wHour; + TimeFields.Minute = lpSystemTime->wMinute; + TimeFields.Second = lpSystemTime->wSecond; + TimeFields.Milliseconds = lpSystemTime->wMilliseconds; - if (RtlTimeFieldsToTime(&TimeFields, &liTime)) + if (RtlTimeFieldsToTime(&TimeFields, &liTime)) { - lpFileTime->dwLowDateTime = liTime.u.LowPart; - lpFileTime->dwHighDateTime = liTime.u.HighPart; - return TRUE; + lpFileTime->dwLowDateTime = liTime.u.LowPart; + lpFileTime->dwHighDateTime = liTime.u.HighPart; + return TRUE; } - return FALSE; -} + return FALSE; +} static BOOL -ConvertDosDateTimeToFileTime( - WORD wFatDate, - WORD wFatTime, - LPFILETIME lpFileTime) +ConvertDosDateTimeToFileTime(WORD wFatDate, + WORD wFatTime, + LPFILETIME lpFileTime) { - PDOSTIME pdtime = (PDOSTIME) &wFatTime; - PDOSDATE pddate = (PDOSDATE) &wFatDate; - SYSTEMTIME SystemTime; + PDOSTIME pdtime = (PDOSTIME)&wFatTime; + PDOSDATE pddate = (PDOSDATE)&wFatDate; + SYSTEMTIME SystemTime; - if (lpFileTime == NULL) - return FALSE; + if (lpFileTime == NULL) + return FALSE; - SystemTime.wMilliseconds = 0; - SystemTime.wSecond = pdtime->Second; - SystemTime.wMinute = pdtime->Minute; - SystemTime.wHour = pdtime->Hour; + SystemTime.wMilliseconds = 0; + SystemTime.wSecond = pdtime->Second; + SystemTime.wMinute = pdtime->Minute; + SystemTime.wHour = pdtime->Hour; - SystemTime.wDay = pddate->Day; - SystemTime.wMonth = pddate->Month; - SystemTime.wYear = 1980 + pddate->Year; + SystemTime.wDay = pddate->Day; + SystemTime.wMonth = pddate->Month; + SystemTime.wYear = 1980 + pddate->Year; - ConvertSystemTimeToFileTime(&SystemTime,lpFileTime); + ConvertSystemTimeToFileTime(&SystemTime, lpFileTime); - return TRUE; + return TRUE; } - -static PWCHAR -GetFileName(PWCHAR Path) /* * FUNCTION: Returns a pointer to file name * ARGUMENTS: @@ -274,43 +273,45 @@ GetFileName(PWCHAR Path) * RETURNS: * Pointer to filename */ +static PWCHAR +GetFileName(PWCHAR Path) { - ULONG i, j; + ULONG i, j; - j = i = 0; + j = i = 0; - while (Path [i++]) + while (Path[i++]) { - if (Path[i - 1] == L'\\') j = i; + if (Path[i - 1] == L'\\') + j = i; } - return Path + j; + + return Path + j; } - -static VOID -RemoveFileName(PWCHAR Path) /* * FUNCTION: Removes a file name from a path * ARGUMENTS: * Path = Pointer to string with path */ +static VOID +RemoveFileName(PWCHAR Path) { - PWCHAR FileName; - DWORD i; + PWCHAR FileName; + DWORD i; - i = 0; - FileName = GetFileName(Path + i); + i = 0; + FileName = GetFileName(Path + i); - if ((FileName != (Path + i)) && (FileName [-1] == L'\\')) - FileName--; - if ((FileName == (Path + i)) && (FileName [0] == L'\\')) - FileName++; - FileName[0] = 0; + if (FileName != Path + i && FileName[-1] == L'\\') + FileName--; + + if (FileName == Path + i && FileName[0] == L'\\') + FileName++; + + FileName[0] = 0; } - -static BOOL -SetAttributesOnFile(PCFFILE File, HANDLE hFile) /* * FUNCTION: Sets attributes on a file * ARGUMENTS: @@ -318,113 +319,110 @@ SetAttributesOnFile(PCFFILE File, HANDLE hFile) * RETURNS: * Status of operation */ +static BOOL +SetAttributesOnFile(PCFFILE File, + HANDLE hFile) { - FILE_BASIC_INFORMATION FileBasic; - IO_STATUS_BLOCK IoStatusBlock; - NTSTATUS NtStatus; - ULONG Attributes = 0; + FILE_BASIC_INFORMATION FileBasic; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS NtStatus; + ULONG Attributes = 0; - if (File->Attributes & CAB_ATTRIB_READONLY) - Attributes |= FILE_ATTRIBUTE_READONLY; + if (File->Attributes & CAB_ATTRIB_READONLY) + Attributes |= FILE_ATTRIBUTE_READONLY; - if (File->Attributes & CAB_ATTRIB_HIDDEN) - Attributes |= FILE_ATTRIBUTE_HIDDEN; + if (File->Attributes & CAB_ATTRIB_HIDDEN) + Attributes |= FILE_ATTRIBUTE_HIDDEN; - if (File->Attributes & CAB_ATTRIB_SYSTEM) - Attributes |= FILE_ATTRIBUTE_SYSTEM; + if (File->Attributes & CAB_ATTRIB_SYSTEM) + Attributes |= FILE_ATTRIBUTE_SYSTEM; - if (File->Attributes & CAB_ATTRIB_DIRECTORY) - Attributes |= FILE_ATTRIBUTE_DIRECTORY; + if (File->Attributes & CAB_ATTRIB_DIRECTORY) + Attributes |= FILE_ATTRIBUTE_DIRECTORY; - if (File->Attributes & CAB_ATTRIB_ARCHIVE) - Attributes |= FILE_ATTRIBUTE_ARCHIVE; + if (File->Attributes & CAB_ATTRIB_ARCHIVE) + Attributes |= FILE_ATTRIBUTE_ARCHIVE; - NtStatus = NtQueryInformationFile(hFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(NtStatus)) + NtStatus = NtQueryInformationFile(hFile, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(NtStatus)) { - DPRINT("NtQueryInformationFile() failed (%x).\n", NtStatus); + DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus); } - else + else { - FileBasic.FileAttributes = Attributes; + FileBasic.FileAttributes = Attributes; - NtStatus = NtSetInformationFile(hFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(NtStatus)) + NtStatus = NtSetInformationFile(hFile, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(NtStatus)) { - DPRINT("NtSetInformationFile() failed (%x).\n", NtStatus); + DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus); } } - return NT_SUCCESS(NtStatus); + return NT_SUCCESS(NtStatus); } -static ULONG -CloseCabinet(VOID) /* * FUNCTION: Closes the current cabinet * RETURNS: * Status of operation */ +static ULONG +CloseCabinet(VOID) { - if (FileBuffer) + if (FileBuffer) { - NtUnmapViewOfSection( NtCurrentProcess(), FileBuffer ); - NtClose( FileSectionHandle ); - NtClose( FileHandle ); - FileBuffer = NULL; + NtUnmapViewOfSection(NtCurrentProcess(), FileBuffer); + NtClose(FileSectionHandle); + NtClose(FileHandle); + FileBuffer = NULL; } - return 0; + return 0; } - -VOID -CabinetInitialize(VOID) /* * FUNCTION: Initialize archiver */ +VOID +CabinetInitialize(VOID) { - ZStream.zalloc = MSZipAlloc; - ZStream.zfree = MSZipFree; - ZStream.opaque = (voidpf)0; + ZStream.zalloc = MSZipAlloc; + ZStream.zfree = MSZipFree; + ZStream.opaque = (voidpf)0; - FileOpen = FALSE; - wcscpy(DestPath, L""); + FileOpen = FALSE; + wcscpy(DestPath, L""); - CodecId = CAB_CODEC_RAW; - CodecSelected = TRUE; + CodecId = CAB_CODEC_RAW; + CodecSelected = TRUE; - FolderUncompSize = 0; - BytesLeftInBlock = 0; - CabinetReserved = 0; - FolderReserved = 0; - DataReserved = 0; - CabinetReservedArea = NULL; - LastFileOffset = 0; + FolderUncompSize = 0; + BytesLeftInBlock = 0; + CabinetReserved = 0; + FolderReserved = 0; + DataReserved = 0; + CabinetReservedArea = NULL; + LastFileOffset = 0; } - -VOID -CabinetCleanup(VOID) /* * FUNCTION: Cleanup archiver */ +VOID +CabinetCleanup(VOID) { - CabinetClose(); + CabinetClose(); } - -BOOL -CabinetNormalizePath(PWCHAR Path, - ULONG Length) /* * FUNCTION: Normalizes a path * ARGUMENTS: @@ -433,254 +431,256 @@ CabinetNormalizePath(PWCHAR Path, * RETURNS: * TRUE if there was enough room in Path, or FALSE */ +BOOL +CabinetNormalizePath(PWCHAR Path, + ULONG Length) { - ULONG n; - BOOL OK = TRUE; + ULONG n; + BOOL Ok; - if ((n = wcslen(Path)) && - (Path[n - 1] != L'\\') && - (OK = ((n + 1) < Length))) + n = wcslen(Path); + Ok = (n + 1) < Length; + + if (n != 0 && Path[n - 1] != L'\\' && Ok) { - Path[n] = L'\\'; - Path[n + 1] = 0; + Path[n] = L'\\'; + Path[n + 1] = 0; } - return OK; + + return Ok; } - -PWCHAR -CabinetGetCabinetName() /* * FUNCTION: Returns pointer to cabinet file name * RETURNS: * Pointer to string with name of cabinet */ +PWCHAR +CabinetGetCabinetName(VOID) { - return CabinetName; + return CabinetName; } - -VOID -CabinetSetCabinetName(PWCHAR FileName) /* * FUNCTION: Sets cabinet file name * ARGUMENTS: * FileName = Pointer to string with name of cabinet */ +VOID +CabinetSetCabinetName(PWCHAR FileName) { - wcscpy(CabinetName, FileName); + wcscpy(CabinetName, FileName); } - -VOID -CabinetSetDestinationPath(PWCHAR DestinationPath) /* * FUNCTION: Sets destination path * ARGUMENTS: * DestinationPath = Pointer to string with name of destination path */ +VOID +CabinetSetDestinationPath(PWCHAR DestinationPath) { - wcscpy(DestPath, DestinationPath); - if (wcslen(DestPath) > 0) - CabinetNormalizePath(DestPath, MAX_PATH); + wcscpy(DestPath, DestinationPath); + + if (wcslen(DestPath) > 0) + CabinetNormalizePath(DestPath, MAX_PATH); } - -PWCHAR -CabinetGetDestinationPath() /* * FUNCTION: Returns destination path * RETURNS: * Pointer to string with name of destination path */ +PWCHAR +CabinetGetDestinationPath(VOID) { - return DestPath; + return DestPath; } - -ULONG -CabinetOpen(VOID) /* * FUNCTION: Opens a cabinet file * RETURNS: * Status of operation */ +ULONG +CabinetOpen(VOID) { - PUCHAR Buffer; - UNICODE_STRING ustring; - ANSI_STRING astring; + PUCHAR Buffer; + UNICODE_STRING ustring; + ANSI_STRING astring; - if (!FileOpen) + if (!FileOpen) { - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING FileName; - NTSTATUS NtStatus; - ULONG Size; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING FileName; + NTSTATUS NtStatus; + ULONG Size; - RtlInitUnicodeString(&FileName, - CabinetName); + RtlInitUnicodeString(&FileName, CabinetName); - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, NULL); - NtStatus = NtOpenFile(&FileHandle, - GENERIC_READ | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(NtStatus)) + NtStatus = NtOpenFile(&FileHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); + + if (!NT_SUCCESS(NtStatus)) { - DPRINT("Cannot open file (%S) (%x).\n", CabinetName, NtStatus); - return CAB_STATUS_CANNOT_OPEN; + DPRINT("Cannot open file (%S) (%x)\n", CabinetName, NtStatus); + return CAB_STATUS_CANNOT_OPEN; } - FileOpen = TRUE; - NtStatus = NtCreateSection(&FileSectionHandle, - SECTION_ALL_ACCESS, - 0, - 0, - PAGE_READONLY, - SEC_COMMIT, - FileHandle); - if(!NT_SUCCESS(NtStatus)) - { - DPRINT("NtCreateSection failed: %x\n", NtStatus); - return CAB_STATUS_NOMEMORY; - } - FileBuffer = 0; - FileSize = 0; - NtStatus = NtMapViewOfSection(FileSectionHandle, - NtCurrentProcess(), - (PVOID *)&FileBuffer, - 0, - 0, - 0, - &FileSize, - ViewUnmap, - 0, - PAGE_READONLY); - if(!NT_SUCCESS(NtStatus)) - { - DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); - return CAB_STATUS_NOMEMORY; - } - DPRINT( "Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer ); - PCABHeader = (PCFHEADER)FileBuffer; + FileOpen = TRUE; - /* Check header */ - if(FileSize <= sizeof(CFHEADER) || - PCABHeader->Signature != CAB_SIGNATURE || - PCABHeader->Version != CAB_VERSION || - PCABHeader->FolderCount == 0 || - PCABHeader->FileCount == 0 || - PCABHeader->FileTableOffset < sizeof(CFHEADER)) - { - CloseCabinet(); - DPRINT("File has invalid header.\n"); - return CAB_STATUS_INVALID_CAB; - } + NtStatus = NtCreateSection(&FileSectionHandle, + SECTION_ALL_ACCESS, + 0, 0, + PAGE_READONLY, + SEC_COMMIT, + FileHandle); - Size = 0; - Buffer = (PUCHAR)(PCABHeader+1); - /* Read/skip any reserved bytes */ - if (PCABHeader->Flags & CAB_FLAG_RESERVE) + if (!NT_SUCCESS(NtStatus)) { - CabinetReserved = *(PUSHORT)Buffer; - Buffer += 2; - FolderReserved = *Buffer; - Buffer++; - DataReserved = *Buffer; - Buffer++; - if (CabinetReserved > 0) + DPRINT("NtCreateSection failed: %x\n", NtStatus); + return CAB_STATUS_NOMEMORY; + } + + FileBuffer = 0; + FileSize = 0; + + NtStatus = NtMapViewOfSection(FileSectionHandle, + NtCurrentProcess(), + (PVOID *)&FileBuffer, + 0, 0, 0, + &FileSize, + ViewUnmap, + 0, + PAGE_READONLY); + + if (!NT_SUCCESS(NtStatus)) + { + DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); + return CAB_STATUS_NOMEMORY; + } + + DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer); + PCABHeader = (PCFHEADER) FileBuffer; + + /* Check header */ + if (FileSize <= sizeof(CFHEADER) || + PCABHeader->Signature != CAB_SIGNATURE || + PCABHeader->Version != CAB_VERSION || + PCABHeader->FolderCount == 0 || + PCABHeader->FileCount == 0 || + PCABHeader->FileTableOffset < sizeof(CFHEADER)) + { + CloseCabinet(); + DPRINT("File has invalid header\n"); + return CAB_STATUS_INVALID_CAB; + } + + Size = 0; + Buffer = (PUCHAR)(PCABHeader + 1); + + /* Read/skip any reserved bytes */ + if (PCABHeader->Flags & CAB_FLAG_RESERVE) + { + CabinetReserved = *(PUSHORT)Buffer; + Buffer += 2; + FolderReserved = *Buffer; + Buffer++; + DataReserved = *Buffer; + Buffer++; + + if (CabinetReserved > 0) { - CabinetReservedArea = Buffer; - Buffer += CabinetReserved; + CabinetReservedArea = Buffer; + Buffer += CabinetReserved; } } - if (PCABHeader->Flags & CAB_FLAG_HASPREV) + if (PCABHeader->Flags & CAB_FLAG_HASPREV) { - /* The previous cabinet file is in the same directory as the current */ - wcscpy(CabinetPrev, CabinetName); - RemoveFileName(CabinetPrev); - CabinetNormalizePath(CabinetPrev, 256); - RtlInitAnsiString( &astring, (LPSTR)Buffer ); - ustring.Length = wcslen( CabinetPrev ); - ustring.Buffer = CabinetPrev + ustring.Length; - ustring.MaximumLength = sizeof( CabinetPrev ) - ustring.Length; - RtlAnsiStringToUnicodeString( &ustring, &astring, FALSE ); - Buffer += astring.Length + 1; + /* The previous cabinet file is in + the same directory as the current */ + wcscpy(CabinetPrev, CabinetName); + RemoveFileName(CabinetPrev); + CabinetNormalizePath(CabinetPrev, 256); + RtlInitAnsiString(&astring, (LPSTR)Buffer); + ustring.Length = wcslen(CabinetPrev); + ustring.Buffer = CabinetPrev + ustring.Length; + ustring.MaximumLength = sizeof(CabinetPrev) - ustring.Length; + RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); + Buffer += astring.Length + 1; - /* Read label of prev disk */ - RtlInitAnsiString( &astring, (LPSTR)Buffer ); - ustring.Length = 0; - ustring.Buffer = DiskPrev; - ustring.MaximumLength = sizeof( DiskPrev ); - RtlAnsiStringToUnicodeString( &ustring, &astring, FALSE ); - Buffer += astring.Length + 1; + /* Read label of prev disk */ + RtlInitAnsiString(&astring, (LPSTR)Buffer); + ustring.Length = 0; + ustring.Buffer = DiskPrev; + ustring.MaximumLength = sizeof(DiskPrev); + RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); + Buffer += astring.Length + 1; } - else + else { - wcscpy(CabinetPrev, L""); - wcscpy(DiskPrev, L""); + wcscpy(CabinetPrev, L""); + wcscpy(DiskPrev, L""); } - if (PCABHeader->Flags & CAB_FLAG_HASNEXT) + if (PCABHeader->Flags & CAB_FLAG_HASNEXT) { - /* The next cabinet file is in the same directory as the previous */ - wcscpy(CabinetNext, CabinetName); - RemoveFileName(CabinetNext); - CabinetNormalizePath(CabinetNext, 256); - RtlInitAnsiString( &astring, (LPSTR)Buffer ); - ustring.Length = wcslen( CabinetNext ); - ustring.Buffer = CabinetNext + ustring.Length; - ustring.MaximumLength = sizeof( CabinetNext ) - ustring.Length; - RtlAnsiStringToUnicodeString( &ustring, &astring, FALSE ); - Buffer += astring.Length + 1; + /* The next cabinet file is in + the same directory as the previous */ + wcscpy(CabinetNext, CabinetName); + RemoveFileName(CabinetNext); + CabinetNormalizePath(CabinetNext, 256); + RtlInitAnsiString(&astring, (LPSTR)Buffer); + ustring.Length = wcslen(CabinetNext); + ustring.Buffer = CabinetNext + ustring.Length; + ustring.MaximumLength = sizeof(CabinetNext) - ustring.Length; + RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); + Buffer += astring.Length + 1; - /* Read label of next disk */ - RtlInitAnsiString( &astring, (LPSTR)Buffer ); - ustring.Length = 0; - ustring.Buffer = DiskNext; - ustring.MaximumLength = sizeof( DiskNext ); - RtlAnsiStringToUnicodeString( &ustring, &astring, FALSE ); - Buffer += astring.Length + 1; + /* Read label of next disk */ + RtlInitAnsiString(&astring, (LPSTR)Buffer); + ustring.Length = 0; + ustring.Buffer = DiskNext; + ustring.MaximumLength = sizeof(DiskNext); + RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); + Buffer += astring.Length + 1; } - else + else { - wcscpy(CabinetNext, L""); - wcscpy(DiskNext, L""); + wcscpy(CabinetNext, L""); + wcscpy(DiskNext, L""); } - CabinetFolders = (PCFFOLDER)Buffer; + CabinetFolders = (PCFFOLDER)Buffer; } - DPRINT( "CabinetOpen returning SUCCESS\n" ); - return CAB_STATUS_SUCCESS; + + DPRINT("CabinetOpen returning SUCCESS\n"); + return CAB_STATUS_SUCCESS; } - -VOID -CabinetClose(VOID) /* * FUNCTION: Closes the cabinet file */ +VOID +CabinetClose(VOID) { - if (FileOpen) + if (FileOpen) { - CloseCabinet(); - - FileOpen = FALSE; + CloseCabinet(); + FileOpen = FALSE; } } - -ULONG -CabinetFindFirst(PWCHAR FileName, - PCAB_SEARCH Search) /* * FUNCTION: Finds the first file in the cabinet that matches a search criteria * ARGUMENTS: @@ -689,17 +689,17 @@ CabinetFindFirst(PWCHAR FileName, * RETURNS: * Status of operation */ +ULONG +CabinetFindFirst(PWCHAR FileName, + PCAB_SEARCH Search) { - DPRINT( "CabinetFindFirst( FileName = %S )\n", FileName ); - wcsncpy(Search->Search, FileName, MAX_PATH); - wcsncpy(Search->Cabinet, CabinetName, MAX_PATH); - Search->File = 0; - return CabinetFindNext(Search); + DPRINT("CabinetFindFirst( FileName = %S )\n", FileName); + wcsncpy(Search->Search, FileName, MAX_PATH); + wcsncpy(Search->Cabinet, CabinetName, MAX_PATH); + Search->File = 0; + return CabinetFindNext(Search); } - -ULONG -CabinetFindNext(PCAB_SEARCH Search) /* * FUNCTION: Finds next file in the cabinet that matches a search criteria * ARGUMENTS: @@ -707,99 +707,116 @@ CabinetFindNext(PCAB_SEARCH Search) * RETURNS: * Status of operation */ +ULONG +CabinetFindNext(PCAB_SEARCH Search) { - ULONG Status; - PCFFILE Prev; - ANSI_STRING AnsiString; - UNICODE_STRING UnicodeString; - WCHAR FileName[MAX_PATH] = {L'\0'}; + ULONG Status; + PCFFILE Prev; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + WCHAR FileName[MAX_PATH]; - if( wcscmp( Search->Cabinet, CabinetName ) != 0 ) - Search->File = 0; // restart search of cabinet has changed since last find - if( !Search->File ) - { - // starting new search or cabinet - Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); - Search->Index = 0; - Prev = 0; - } - else Prev = Search->File; - while(1) - { - // look at each file in the archive and see if we found a match - if( Search->File->FolderIndex == 0xFFFD || Search->File->FolderIndex == 0xFFFF ) - { - // skip files continued from previous cab - DPRINT("Skipping file (%s) FileOffset (0x%X) LastFileOffset (0x%X).\n", - (char *)(Search->File + 1), Search->File->FileOffset, LastFileOffset); - } - else { - // FIXME: check for match against search criteria - if( Search->File != Prev ) - { - // don't match the file we started with - if( wcscmp( Search->Search, L"*" ) == 0 ) - { - // take any file - break; - } - else { - // otherwise, try to match the exact file name - RtlInitAnsiString( &AnsiString, Search->File->FileName ); - UnicodeString.Buffer = FileName; - UnicodeString.Length = 0; - UnicodeString.MaximumLength = sizeof( FileName ); - RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, FALSE ); - if( wcscmp( Search->Search, UnicodeString.Buffer ) == 0 ) - break; - } - } - } - // if we make it here we found no match, so move to the next file - Search->Index++; - if( Search->Index >= PCABHeader->FileCount ) - { - // we have reached the end of this cabinet, try to open the next - DPRINT( "End of cabinet reached\n" ); - if (wcslen(DiskNext) > 0) - { - CloseCabinet(); + if (wcscmp(Search->Cabinet, CabinetName) != 0) + { + /* restart search of cabinet has changed since last find */ + Search->File = 0; + } - CabinetSetCabinetName(CabinetNext); - wcscpy( Search->Cabinet, CabinetName ); + if (!Search->File) + { + /* starting new search or cabinet */ + Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); + Search->Index = 0; + Prev = 0; + } + else + Prev = Search->File; - if (DiskChangeHandler != NULL) - { - DiskChangeHandler(CabinetNext, DiskNext); - } + while (TRUE) + { + /* look at each file in the archive and see if we found a match */ + if (Search->File->FolderIndex == 0xFFFD || + Search->File->FolderIndex == 0xFFFF) + { + /* skip files continued from previous cab */ + DPRINT("Skipping file (%s): FileOffset (0x%X), " + "LastFileOffset (0x%X)\n", (char *)(Search->File + 1), + Search->File->FileOffset, LastFileOffset); + } + else + { + // FIXME: check for match against search criteria + if (Search->File != Prev) + { + /* don't match the file we started with */ + if (wcscmp(Search->Search, L"*") == 0) + { + /* take any file */ + break; + } + else + { + /* otherwise, try to match the exact file name */ + RtlInitAnsiString(&AnsiString, Search->File->FileName); + UnicodeString.Buffer = FileName; + UnicodeString.Buffer[0] = 0; + UnicodeString.Length = 0; + UnicodeString.MaximumLength = sizeof(FileName); + RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); + if (wcscmp(Search->Search, UnicodeString.Buffer) == 0) + break; + } + } + } - Status = CabinetOpen(); - if (Status != CAB_STATUS_SUCCESS) - return Status; + /* if we make it here we found no match, so move to the next file */ + Search->Index++; + if (Search->Index >= PCABHeader->FileCount) + { + /* we have reached the end of this cabinet, try to open the next */ + DPRINT("End of cabinet reached\n"); + if (wcslen(DiskNext) > 0) + { + CloseCabinet(); - } - else - { - return CAB_STATUS_NOFILE; - } - // starting new search or cabinet - Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); - Search->Index = 0; - Prev = 0; - } - else Search->File = (PCFFILE)(strchr( (char *)(Search->File + 1), 0 ) + 1); - } - DPRINT( "Found file %s\n", Search->File->FileName ); - return CAB_STATUS_SUCCESS; + CabinetSetCabinetName(CabinetNext); + wcscpy(Search->Cabinet, CabinetName); + + if (DiskChangeHandler != NULL) + { + DiskChangeHandler(CabinetNext, DiskNext); + } + + Status = CabinetOpen(); + if (Status != CAB_STATUS_SUCCESS) + return Status; + } + else + { + return CAB_STATUS_NOFILE; + } + + /* starting new search or cabinet */ + Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); + Search->Index = 0; + Prev = 0; + } + else + Search->File = (PCFFILE)(strchr((char *)(Search->File + 1), 0) + 1); + } + + DPRINT("Found file %s\n", Search->File->FileName); + return CAB_STATUS_SUCCESS; } - -int Validate() +#if 0 +int +Validate() { - return (int)RtlValidateHeap(ProcessHeap, 0, 0); + return (int)RtlValidateHeap(ProcessHeap, 0, 0); } +#endif -ULONG CabinetExtractFile( PCAB_SEARCH Search ) /* * FUNCTION: Extracts a file from the cabinet * ARGUMENTS: @@ -807,309 +824,339 @@ ULONG CabinetExtractFile( PCAB_SEARCH Search ) * RETURNS * Status of operation */ +ULONG +CabinetExtractFile(PCAB_SEARCH Search) { - ULONG Size; // remaining file bytes to decompress - ULONG CurrentOffset; // current uncompressed offset within the folder - PUCHAR CurrentBuffer; // current pointer to compressed data in the block - LONG RemainingBlock; // remaining comp data in the block - HANDLE DestFile; - HANDLE DestFileSection; - PVOID DestFileBuffer; // mapped view of dest file - PVOID CurrentDestBuffer; // pointer to the current position in the dest view - PCFDATA CFData; // current data block - ULONG Status; - FILETIME FileTime; - WCHAR DestName[MAX_PATH]; - NTSTATUS NtStatus; - UNICODE_STRING UnicodeString; - ANSI_STRING AnsiString; - IO_STATUS_BLOCK IoStatusBlock; - OBJECT_ATTRIBUTES ObjectAttributes; - FILE_BASIC_INFORMATION FileBasic; - PCFFOLDER CurrentFolder; - LARGE_INTEGER MaxDestFileSize; - LONG InputLength, OutputLength; - char Junk[512]; + ULONG Size; // remaining file bytes to decompress + ULONG CurrentOffset; // current uncompressed offset within the folder + PUCHAR CurrentBuffer; // current pointer to compressed data in the block + LONG RemainingBlock; // remaining comp data in the block + HANDLE DestFile; + HANDLE DestFileSection; + PVOID DestFileBuffer; // mapped view of dest file + PVOID CurrentDestBuffer; // pointer to the current position in the dest view + PCFDATA CFData; // current data block + ULONG Status; + FILETIME FileTime; + WCHAR DestName[MAX_PATH]; + NTSTATUS NtStatus; + UNICODE_STRING UnicodeString; + ANSI_STRING AnsiString; + IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + FILE_BASIC_INFORMATION FileBasic; + PCFFOLDER CurrentFolder; + LARGE_INTEGER MaxDestFileSize; + LONG InputLength, OutputLength; + char Junk[512]; - if( wcscmp( Search->Cabinet, CabinetName ) != 0 ) - { - // the file is not in the current cabinet - DPRINT( "File is not in this cabinet ( %S != %S )\n", Search->Cabinet, CabinetName ); - return CAB_STATUS_NOFILE; - } - // look up the folder that the file specifies - if( Search->File->FolderIndex == 0xFFFD || Search->File->FolderIndex == 0xFFFF ) - { - // folder is continued from previous cabinet, that shouldn't happen here - return CAB_STATUS_NOFILE; - } - else if( Search->File->FolderIndex == 0xFFFE ) - { - // folder is the last in this cabinet and continues into next - CurrentFolder = &CabinetFolders[PCABHeader->FolderCount-1]; - } - else { - // folder is completely contained within this cabinet - CurrentFolder = &CabinetFolders[Search->File->FolderIndex]; - } - switch (CurrentFolder->CompressionType & CAB_COMP_MASK) + if (wcscmp(Search->Cabinet, CabinetName) != 0) { - case CAB_COMP_NONE: - CabinetSelectCodec(CAB_CODEC_RAW); - break; - case CAB_COMP_MSZIP: - CabinetSelectCodec(CAB_CODEC_MSZIP); - break; - default: - return CAB_STATUS_UNSUPPCOMP; + /* the file is not in the current cabinet */ + DPRINT("File is not in this cabinet (%S != %S)\n", + Search->Cabinet, CabinetName); + return CAB_STATUS_NOFILE; } - DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)).\n", - (UINT)Search->File->FileOffset, - (UINT)Search->File->FileSize); - RtlInitAnsiString( &AnsiString, Search->File->FileName ); - wcscpy( DestName, DestPath ); - UnicodeString.MaximumLength = sizeof( DestName ) - wcslen( DestName ); - UnicodeString.Buffer = DestName + wcslen( DestName ); - UnicodeString.Length = 0; - RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, FALSE ); - - /* Create destination file, fail if it already exists */ - RtlInitUnicodeString(&UnicodeString, - DestName); - - - InitializeObjectAttributes(&ObjectAttributes, - &UnicodeString, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - NtStatus = NtCreateFile(&DestFile, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_CREATE, - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - if (!NT_SUCCESS(NtStatus)) + /* look up the folder that the file specifies */ + if (Search->File->FolderIndex == 0xFFFD || + Search->File->FolderIndex == 0xFFFF) { - DPRINT("NtCreateFile() failed (%S) (%x).\n", DestName, NtStatus); + /* folder is continued from previous cabinet, + that shouldn't happen here */ + return CAB_STATUS_NOFILE; + } + else if (Search->File->FolderIndex == 0xFFFE) + { + /* folder is the last in this cabinet and continues into next */ + CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1]; + } + else + { + /* folder is completely contained within this cabinet */ + CurrentFolder = &CabinetFolders[Search->File->FolderIndex]; + } - /* If file exists, ask to overwrite file */ - if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName)) + switch (CurrentFolder->CompressionType & CAB_COMP_MASK) + { + case CAB_COMP_NONE: + CabinetSelectCodec(CAB_CODEC_RAW); + break; + case CAB_COMP_MSZIP: + CabinetSelectCodec(CAB_CODEC_MSZIP); + break; + default: + return CAB_STATUS_UNSUPPCOMP; + } + + DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n", + (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize); + + RtlInitAnsiString(&AnsiString, Search->File->FileName); + wcscpy(DestName, DestPath); + UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName); + UnicodeString.Buffer = DestName + wcslen(DestName); + UnicodeString.Length = 0; + RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); + + /* Create destination file, fail if it already exists */ + RtlInitUnicodeString(&UnicodeString, DestName); + + InitializeObjectAttributes(&ObjectAttributes, + &UnicodeString, + OBJ_CASE_INSENSITIVE, + NULL, NULL); + + NtStatus = NtCreateFile(&DestFile, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_CREATE, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, 0); + + if (!NT_SUCCESS(NtStatus)) + { + DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); + + /* If file exists, ask to overwrite file */ + if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName)) { - /* Create destination file, overwrite if it already exists */ - NtStatus = NtCreateFile(&DestFile, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OVERWRITE, - FILE_SYNCHRONOUS_IO_ALERT, - NULL, - 0); - if (!NT_SUCCESS(NtStatus)) + /* Create destination file, overwrite if it already exists */ + NtStatus = NtCreateFile(&DestFile, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE, + FILE_SYNCHRONOUS_IO_ALERT, + NULL, 0); + + if (!NT_SUCCESS(NtStatus)) { - DPRINT("NtCreateFile() failed 2 (%S) (%x).\n", DestName, NtStatus); - return CAB_STATUS_CANNOT_CREATE; + DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); + return CAB_STATUS_CANNOT_CREATE; } } - else + else { - DPRINT("File (%S) exists.\n", DestName); - return CAB_STATUS_FILE_EXISTS; - } - } - MaxDestFileSize.QuadPart = Search->File->FileSize; - NtStatus = NtCreateSection(&DestFileSection, - SECTION_ALL_ACCESS, - 0, - &MaxDestFileSize, - PAGE_READWRITE, - SEC_COMMIT, - DestFile); - if(!NT_SUCCESS(NtStatus)) - { - DPRINT("NtCreateSection failed: %x\n", NtStatus); - Status = CAB_STATUS_NOMEMORY; - goto CloseDestFile; - } - DestFileBuffer = 0; - DestFileSize = 0; - NtStatus = NtMapViewOfSection(DestFileSection, - NtCurrentProcess(), - &DestFileBuffer, - 0, - 0, - 0, - &DestFileSize, - ViewUnmap, - 0, - PAGE_READWRITE); - if(!NT_SUCCESS(NtStatus)) - { - DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); - Status = CAB_STATUS_NOMEMORY; - goto CloseDestFileSection; - } - CurrentDestBuffer = DestFileBuffer; - if (!ConvertDosDateTimeToFileTime(Search->File->FileDate, Search->File->FileTime, &FileTime)) - { - DPRINT("DosDateTimeToFileTime() failed.\n"); - Status = CAB_STATUS_CANNOT_WRITE; - goto UnmapDestFile; - } - - NtStatus = NtQueryInformationFile(DestFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(NtStatus)) - { - DPRINT("NtQueryInformationFile() failed (%x).\n", NtStatus); - } - else - { - memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME)); - - NtStatus = NtSetInformationFile(DestFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(NtStatus)) - { - DPRINT("NtSetInformationFile() failed (%x).\n", NtStatus); + DPRINT("File (%S) exists\n", DestName); + return CAB_STATUS_FILE_EXISTS; } } - SetAttributesOnFile(Search->File, DestFile); + MaxDestFileSize.QuadPart = Search->File->FileSize; + NtStatus = NtCreateSection(&DestFileSection, + SECTION_ALL_ACCESS, + 0, + &MaxDestFileSize, + PAGE_READWRITE, + SEC_COMMIT, + DestFile); - /* Call extract event handler */ - if (ExtractHandler != NULL) + if (!NT_SUCCESS(NtStatus)) { - ExtractHandler(Search->File, DestName); + DPRINT("NtCreateSection failed: %x\n", NtStatus); + Status = CAB_STATUS_NOMEMORY; + goto CloseDestFile; } - // find the starting block of the file - // start with the first data block of the folder - CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer); - CurrentOffset = 0; - while( CurrentOffset + CFData->UncompSize <= Search->File->FileOffset ) - { - // walk the data blocks until we reach the one containing the start of the file - CurrentOffset += CFData->UncompSize; - CFData = (PCFDATA)((char *)(CFData+1) + DataReserved + CFData->CompSize); - } - // now decompress and discard any data in the block before the start of the file - CurrentBuffer = ((unsigned char *)(CFData+1)) + DataReserved; // start of comp data - RemainingBlock = CFData->CompSize; - InputLength = RemainingBlock; - while( CurrentOffset < Search->File->FileOffset ) - { - // compute remaining uncomp bytes to start of file, bounded by sizeof junk - OutputLength = Search->File->FileOffset - CurrentOffset; - if( OutputLength > (LONG)sizeof( Junk ) ) - OutputLength = sizeof( Junk ); - OutputLength = -OutputLength; // negate to signal NOT end of block - CodecUncompress( Junk, - CurrentBuffer, - &InputLength, - &OutputLength ); - CurrentOffset += OutputLength; // add the uncomp bytes extracted to current folder offset - CurrentBuffer += InputLength; // add comp bytes consumed to CurrentBuffer - RemainingBlock -= InputLength; // subtract bytes consumed from bytes remaining in block - InputLength = -RemainingBlock; // neg for resume decompression of the same block - } - // now CurrentBuffer points to the first comp byte of the file, so we can begin decompressing - Size = Search->File->FileSize; // Size = remaining uncomp bytes of the file to decompress - while(Size > 0) + DestFileBuffer = 0; + DestFileSize = 0; + NtStatus = NtMapViewOfSection(DestFileSection, + NtCurrentProcess(), + &DestFileBuffer, + 0, 0, 0, + &DestFileSize, + ViewUnmap, + 0, + PAGE_READWRITE); + + if (!NT_SUCCESS(NtStatus)) { - OutputLength = Size; - DPRINT( "Decompressing block at %x with RemainingBlock = %d, Size = %d\n", CurrentBuffer, RemainingBlock, Size ); - Status = CodecUncompress(CurrentDestBuffer, - CurrentBuffer, - &InputLength, - &OutputLength); - if (Status != CS_SUCCESS) - { - DPRINT("Cannot uncompress block.\n"); - if(Status == CS_NOMEMORY) - Status = CAB_STATUS_NOMEMORY; - Status = CAB_STATUS_INVALID_CAB; - goto UnmapDestFile; - } - CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength); // advance dest buffer by bytes produced - CurrentBuffer += InputLength; // advance src buffer by bytes consumed - Size -= OutputLength; // reduce remaining file bytes by bytes produced - RemainingBlock -= InputLength; // reduce remaining block size by bytes consumed - if( RemainingBlock == 0 ) - { - // used up this block, move on to the next - DPRINT( "Out of block data\n" ); - CFData = (PCFDATA)CurrentBuffer; - RemainingBlock = CFData->CompSize; - CurrentBuffer = ((unsigned char *)(CFData+1) + DataReserved); - InputLength = RemainingBlock; - } - } - Status = CAB_STATUS_SUCCESS; - UnmapDestFile: - NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer); - CloseDestFileSection: - NtClose(DestFileSection); - CloseDestFile: - NtClose(DestFile); + DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); + Status = CAB_STATUS_NOMEMORY; + goto CloseDestFileSection; + } - return Status; + CurrentDestBuffer = DestFileBuffer; + if (!ConvertDosDateTimeToFileTime(Search->File->FileDate, + Search->File->FileTime, + &FileTime)) + { + DPRINT("DosDateTimeToFileTime() failed\n"); + Status = CAB_STATUS_CANNOT_WRITE; + goto UnmapDestFile; + } + + NtStatus = NtQueryInformationFile(DestFile, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(NtStatus)) + { + DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus); + } + else + { + memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME)); + + NtStatus = NtSetInformationFile(DestFile, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(NtStatus)) + { + DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus); + } + } + + SetAttributesOnFile(Search->File, DestFile); + + /* Call extract event handler */ + if (ExtractHandler != NULL) + { + ExtractHandler(Search->File, DestName); + } + + /* find the starting block of the file + start with the first data block of the folder */ + CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer); + CurrentOffset = 0; + while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset) + { + /* walk the data blocks until we reach + the one containing the start of the file */ + CurrentOffset += CFData->UncompSize; + CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize); + } + + /* now decompress and discard any data in + the block before the start of the file */ + + /* start of comp data */ + CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved; + RemainingBlock = CFData->CompSize; + InputLength = RemainingBlock; + + while (CurrentOffset < Search->File->FileOffset) + { + /* compute remaining uncomp bytes to start + of file, bounded by sizeof junk */ + OutputLength = Search->File->FileOffset - CurrentOffset; + if (OutputLength > (LONG)sizeof(Junk)) + OutputLength = sizeof (Junk); + + /* negate to signal NOT end of block */ + OutputLength = -OutputLength; + CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength); + /* add the uncomp bytes extracted to current folder offset */ + CurrentOffset += OutputLength; + /* add comp bytes consumed to CurrentBuffer */ + CurrentBuffer += InputLength; + /* subtract bytes consumed from bytes remaining in block */ + RemainingBlock -= InputLength; + /* neg for resume decompression of the same block */ + InputLength = -RemainingBlock; + } + + /* now CurrentBuffer points to the first comp byte + of the file, so we can begin decompressing */ + + /* Size = remaining uncomp bytes of the file to decompress */ + Size = Search->File->FileSize; + while (Size > 0) + { + OutputLength = Size; + DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n", + CurrentBuffer, RemainingBlock, Size); + + Status = CodecUncompress(CurrentDestBuffer, + CurrentBuffer, + &InputLength, + &OutputLength); + + if (Status != CS_SUCCESS) + { + DPRINT("Cannot uncompress block\n"); + if (Status == CS_NOMEMORY) + Status = CAB_STATUS_NOMEMORY; + Status = CAB_STATUS_INVALID_CAB; + goto UnmapDestFile; + } + + /* advance dest buffer by bytes produced */ + CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength); + /* advance src buffer by bytes consumed */ + CurrentBuffer += InputLength; + /* reduce remaining file bytes by bytes produced */ + Size -= OutputLength; + /* reduce remaining block size by bytes consumed */ + RemainingBlock -= InputLength; + if (RemainingBlock == 0) + { + /* used up this block, move on to the next */ + DPRINT("Out of block data\n"); + CFData = (PCFDATA)CurrentBuffer; + RemainingBlock = CFData->CompSize; + CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved; + InputLength = RemainingBlock; + } + } + + Status = CAB_STATUS_SUCCESS; + +UnmapDestFile: + NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer); + +CloseDestFileSection: + NtClose(DestFileSection); + +CloseDestFile: + NtClose(DestFile); + + return Status; } - -VOID -CabinetSelectCodec(ULONG Id) /* * FUNCTION: Selects codec engine to use * ARGUMENTS: * Id = Codec identifier */ +VOID +CabinetSelectCodec(ULONG Id) { - if (CodecSelected) + if (CodecSelected) { - if (Id == CodecId) - return; + if (Id == CodecId) + return; - CodecSelected = FALSE; + CodecSelected = FALSE; } - switch (Id) + switch (Id) { - case CAB_CODEC_RAW: - CodecUncompress = RawCodecUncompress; - break; - case CAB_CODEC_MSZIP: - CodecUncompress = MSZipCodecUncompress; - break; - default: - return; + case CAB_CODEC_RAW: + CodecUncompress = RawCodecUncompress; + break; + case CAB_CODEC_MSZIP: + CodecUncompress = MSZipCodecUncompress; + break; + default: + return; } - CodecId = Id; - CodecSelected = TRUE; + CodecId = Id; + CodecSelected = TRUE; } - -VOID -CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, - PCABINET_EXTRACT Extract, - PCABINET_DISK_CHANGE DiskChange) /* * FUNCTION: Set event handlers * ARGUMENTS: @@ -1117,33 +1164,38 @@ CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, * Extract = Handler called when a file is to be extracted * DiskChange = Handler called when changing the disk */ +VOID +CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, + PCABINET_EXTRACT Extract, + PCABINET_DISK_CHANGE DiskChange) { - OverwriteHandler = Overwrite; - ExtractHandler = Extract; - DiskChangeHandler = DiskChange; + OverwriteHandler = Overwrite; + ExtractHandler = Extract; + DiskChangeHandler = DiskChange; } - -PVOID -CabinetGetCabinetReservedArea(PULONG Size) /* * FUNCTION: Get pointer to cabinet reserved area. NULL if none */ +PVOID +CabinetGetCabinetReservedArea(PULONG Size) { - if (CabinetReservedArea != NULL) + if (CabinetReservedArea != NULL) { - if (Size != NULL) + if (Size != NULL) { - *Size = CabinetReserved; + *Size = CabinetReserved; } - return CabinetReservedArea; + + return CabinetReservedArea; } - else + else { - if (Size != NULL) + if (Size != NULL) { - *Size = 0; + *Size = 0; } - return NULL; + + return NULL; } }