Author: dgorbachev Date: Sun Feb 7 20:52:10 2010 New Revision: 45490
URL: http://svn.reactos.org/svn/reactos?rev=45490&view=rev Log: Fix formatting.
Modified: trunk/reactos/base/setup/usetup/cabinet.c
Modified: trunk/reactos/base/setup/usetup/cabinet.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/cabinet.c... ============================================================================== --- trunk/reactos/base/setup/usetup/cabinet.c [iso-8859-1] (original) +++ trunk/reactos/base/setup/usetup/cabinet.c [iso-8859-1] Sun Feb 7 20:52:10 2010 @@ -20,19 +20,19 @@ #define SEEK_END 2 #endif
-typedef struct __DOSTIME -{ - WORD Second:5; - WORD Minute:6; - WORD Hour:5; +typedef struct _DOSTIME +{ + WORD Second:5; + WORD Minute:6; + WORD Hour:5; } DOSTIME, *PDOSTIME;
-typedef struct __DOSDATE -{ - WORD Day:5; - WORD Month:4; - WORD Year:5; +typedef struct _DOSDATE +{ + 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 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 @@ return RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, nSize); }
- void __cdecl free(void* _ptr) { RtlFreeHeap(ProcessHeap, 0, _ptr); @@ -93,11 +92,6 @@
/* RAW codec */
-ULONG -RawCodecUncompress(PVOID OutputBuffer, - PVOID InputBuffer, - PLONG InputLength, - PLONG OutputLength) /* * FUNCTION: Uncompresses data in a buffer * ARGUMENTS: @@ -108,21 +102,20 @@ * OutputLength = Length of output buffer before, amount filled after * Negative to indicate that this is not the end of the block */ -{ - LONG In = abs(*InputLength), Out = abs(*OutputLength); - memcpy(OutputBuffer, InputBuffer, In < Out ? In : Out); - *InputLength = *OutputLength = In < Out ? In : Out; - return CS_SUCCESS; -} - +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; +}
/* MSZIP codec */
-ULONG -MSZipCodecUncompress(PVOID OutputBuffer, - PVOID InputBuffer, - PLONG InputLength, - PLONG OutputLength) /* * FUNCTION: Uncompresses data in a buffer * ARGUMENTS: @@ -133,140 +126,146 @@ * OutputLength = Length of output buffer before, amount filled after * Negative to indicate that this is not the end of the block */ -{ - 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); - - 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); - - /* 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; - } - - 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; -} - - +ULONG +MSZipCodecUncompress(PVOID OutputBuffer, + PVOID InputBuffer, + PLONG InputLength, + PLONG OutputLength) +{ + 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; + + 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); + + /* 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; + } + + 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) -{ - return (voidpf)RtlAllocateHeap (ProcessHeap, 0, items * size); -} - -void MSZipFree (voidpf opaque, voidpf address) -{ - RtlFreeHeap(ProcessHeap, 0, address); +voidpf +MSZipAlloc(voidpf opaque, uInt items, uInt size) +{ + return (voidpf)RtlAllocateHeap(ProcessHeap, 0, items * size); +} + +void +MSZipFree(voidpf opaque, voidpf address) +{ + RtlFreeHeap(ProcessHeap, 0, address); }
static BOOL -ConvertSystemTimeToFileTime( - CONST SYSTEMTIME * lpSystemTime, - LPFILETIME lpFileTime) -{ - 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; - - if (RtlTimeFieldsToTime(&TimeFields, &liTime)) - { - lpFileTime->dwLowDateTime = liTime.u.LowPart; - lpFileTime->dwHighDateTime = liTime.u.HighPart; - return TRUE; - } - return FALSE; -} - +ConvertSystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, + LPFILETIME lpFileTime) +{ + 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; + + if (RtlTimeFieldsToTime(&TimeFields, &liTime)) + { + lpFileTime->dwLowDateTime = liTime.u.LowPart; + lpFileTime->dwHighDateTime = liTime.u.HighPart; + return TRUE; + } + + return FALSE; +}
static BOOL -ConvertDosDateTimeToFileTime( - WORD wFatDate, - WORD wFatTime, - LPFILETIME lpFileTime) -{ - PDOSTIME pdtime = (PDOSTIME) &wFatTime; - PDOSDATE pddate = (PDOSDATE) &wFatDate; - SYSTEMTIME SystemTime; - - if (lpFileTime == NULL) - return FALSE; - - 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; - - ConvertSystemTimeToFileTime(&SystemTime,lpFileTime); - - return TRUE; -} - - -static PWCHAR -GetFileName(PWCHAR Path) +ConvertDosDateTimeToFileTime(WORD wFatDate, + WORD wFatTime, + LPFILETIME lpFileTime) +{ + PDOSTIME pdtime = (PDOSTIME)&wFatTime; + PDOSDATE pddate = (PDOSDATE)&wFatDate; + SYSTEMTIME SystemTime; + + if (lpFileTime == NULL) + return FALSE; + + 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; + + ConvertSystemTimeToFileTime(&SystemTime, lpFileTime); + + return TRUE; +} + /* * FUNCTION: Returns a pointer to file name * ARGUMENTS: @@ -274,43 +273,45 @@ * RETURNS: * Pointer to filename */ -{ - ULONG i, j; - - j = i = 0; - - while (Path [i++]) - { - if (Path[i - 1] == L'\') j = i; - } - return Path + j; -} - - -static VOID -RemoveFileName(PWCHAR Path) +static PWCHAR +GetFileName(PWCHAR Path) +{ + ULONG i, j; + + j = i = 0; + + while (Path[i++]) + { + if (Path[i - 1] == L'\') + j = i; + } + + return Path + j; +} + /* * FUNCTION: Removes a file name from a path * ARGUMENTS: * Path = Pointer to string with path */ -{ - PWCHAR FileName; - DWORD 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; -} - - -static BOOL -SetAttributesOnFile(PCFFILE File, HANDLE hFile) +static VOID +RemoveFileName(PWCHAR Path) +{ + PWCHAR FileName; + DWORD 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; +} + /* * FUNCTION: Sets attributes on a file * ARGUMENTS: @@ -318,113 +319,110 @@ * RETURNS: * Status of operation */ -{ - 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_HIDDEN) - Attributes |= FILE_ATTRIBUTE_HIDDEN; - - 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_ARCHIVE) - Attributes |= FILE_ATTRIBUTE_ARCHIVE; - - NtStatus = NtQueryInformationFile(hFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(NtStatus)) - { - DPRINT("NtQueryInformationFile() failed (%x).\n", NtStatus); - } - else - { - FileBasic.FileAttributes = Attributes; - - NtStatus = NtSetInformationFile(hFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(NtStatus)) - { - DPRINT("NtSetInformationFile() failed (%x).\n", NtStatus); - } - } - - return NT_SUCCESS(NtStatus); -} - -static ULONG -CloseCabinet(VOID) +static BOOL +SetAttributesOnFile(PCFFILE File, + HANDLE hFile) +{ + 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_HIDDEN) + Attributes |= FILE_ATTRIBUTE_HIDDEN; + + 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_ARCHIVE) + Attributes |= FILE_ATTRIBUTE_ARCHIVE; + + NtStatus = NtQueryInformationFile(hFile, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(NtStatus)) + { + DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus); + } + else + { + FileBasic.FileAttributes = Attributes; + + NtStatus = NtSetInformationFile(hFile, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(NtStatus)) + { + DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus); + } + } + + return NT_SUCCESS(NtStatus); +} + /* * FUNCTION: Closes the current cabinet * RETURNS: * Status of operation */ -{ - if (FileBuffer) - { - NtUnmapViewOfSection( NtCurrentProcess(), FileBuffer ); - NtClose( FileSectionHandle ); - NtClose( FileHandle ); - FileBuffer = NULL; - } - - return 0; -} - - +static ULONG +CloseCabinet(VOID) +{ + if (FileBuffer) + { + NtUnmapViewOfSection(NtCurrentProcess(), FileBuffer); + NtClose(FileSectionHandle); + NtClose(FileHandle); + FileBuffer = NULL; + } + + return 0; +} + +/* + * FUNCTION: Initialize archiver + */ VOID CabinetInitialize(VOID) -/* - * FUNCTION: Initialize archiver - */ -{ - ZStream.zalloc = MSZipAlloc; - ZStream.zfree = MSZipFree; - ZStream.opaque = (voidpf)0; - - FileOpen = FALSE; - wcscpy(DestPath, L""); - - CodecId = CAB_CODEC_RAW; - CodecSelected = TRUE; - - FolderUncompSize = 0; - BytesLeftInBlock = 0; - CabinetReserved = 0; - FolderReserved = 0; - DataReserved = 0; - CabinetReservedArea = NULL; - LastFileOffset = 0; -} - - +{ + ZStream.zalloc = MSZipAlloc; + ZStream.zfree = MSZipFree; + ZStream.opaque = (voidpf)0; + + FileOpen = FALSE; + wcscpy(DestPath, L""); + + CodecId = CAB_CODEC_RAW; + CodecSelected = TRUE; + + FolderUncompSize = 0; + BytesLeftInBlock = 0; + CabinetReserved = 0; + FolderReserved = 0; + DataReserved = 0; + CabinetReservedArea = NULL; + LastFileOffset = 0; +} + +/* + * FUNCTION: Cleanup archiver + */ VOID CabinetCleanup(VOID) -/* - * FUNCTION: Cleanup archiver - */ -{ - CabinetClose(); -} - - -BOOL -CabinetNormalizePath(PWCHAR Path, - ULONG Length) +{ + CabinetClose(); +} + /* * FUNCTION: Normalizes a path * ARGUMENTS: @@ -433,254 +431,256 @@ * RETURNS: * TRUE if there was enough room in Path, or FALSE */ -{ - ULONG n; - BOOL OK = TRUE; - - if ((n = wcslen(Path)) && - (Path[n - 1] != L'\') && - (OK = ((n + 1) < Length))) - { - Path[n] = L'\'; - Path[n + 1] = 0; - } - return OK; -} - - -PWCHAR -CabinetGetCabinetName() +BOOL +CabinetNormalizePath(PWCHAR Path, + ULONG Length) +{ + ULONG n; + BOOL Ok; + + n = wcslen(Path); + Ok = (n + 1) < Length; + + if (n != 0 && Path[n - 1] != L'\' && Ok) + { + Path[n] = L'\'; + Path[n + 1] = 0; + } + + return Ok; +} + /* * FUNCTION: Returns pointer to cabinet file name * RETURNS: * Pointer to string with name of cabinet */ -{ - return CabinetName; -} - - -VOID -CabinetSetCabinetName(PWCHAR FileName) +PWCHAR +CabinetGetCabinetName(VOID) +{ + return CabinetName; +} + /* * FUNCTION: Sets cabinet file name * ARGUMENTS: * FileName = Pointer to string with name of cabinet */ -{ - wcscpy(CabinetName, FileName); -} - - VOID -CabinetSetDestinationPath(PWCHAR DestinationPath) +CabinetSetCabinetName(PWCHAR FileName) +{ + wcscpy(CabinetName, FileName); +} + /* * FUNCTION: Sets destination path * ARGUMENTS: * DestinationPath = Pointer to string with name of destination path */ -{ - wcscpy(DestPath, DestinationPath); - if (wcslen(DestPath) > 0) - CabinetNormalizePath(DestPath, MAX_PATH); -} - - -PWCHAR -CabinetGetDestinationPath() +VOID +CabinetSetDestinationPath(PWCHAR DestinationPath) +{ + wcscpy(DestPath, DestinationPath); + + if (wcslen(DestPath) > 0) + CabinetNormalizePath(DestPath, MAX_PATH); +} + /* * FUNCTION: Returns destination path * RETURNS: * Pointer to string with name of destination path */ -{ - return DestPath; -} - - -ULONG -CabinetOpen(VOID) +PWCHAR +CabinetGetDestinationPath(VOID) +{ + return DestPath; +} + /* * FUNCTION: Opens a cabinet file * RETURNS: * Status of operation */ -{ - PUCHAR Buffer; - UNICODE_STRING ustring; - ANSI_STRING astring; - - if (!FileOpen) - { - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING FileName; - NTSTATUS NtStatus; - ULONG Size; - - RtlInitUnicodeString(&FileName, - CabinetName); - - 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)) - { - 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; - - /* 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) +ULONG +CabinetOpen(VOID) +{ + PUCHAR Buffer; + UNICODE_STRING ustring; + ANSI_STRING astring; + + if (!FileOpen) + { + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING FileName; + NTSTATUS NtStatus; + ULONG Size; + + RtlInitUnicodeString(&FileName, CabinetName); + + 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)) + { + 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; + + /* 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) - { - /* 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; - } - else - { - wcscpy(CabinetPrev, L""); - wcscpy(DiskPrev, L""); - } - - 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; - - /* 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 - { - wcscpy(CabinetNext, L""); - wcscpy(DiskNext, L""); - } - CabinetFolders = (PCFFOLDER)Buffer; - } - DPRINT( "CabinetOpen returning SUCCESS\n" ); - return CAB_STATUS_SUCCESS; -} - - + 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; + + /* 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 + { + wcscpy(CabinetPrev, L""); + wcscpy(DiskPrev, L""); + } + + 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; + + /* 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 + { + wcscpy(CabinetNext, L""); + wcscpy(DiskNext, L""); + } + CabinetFolders = (PCFFOLDER)Buffer; + } + + DPRINT("CabinetOpen returning SUCCESS\n"); + return CAB_STATUS_SUCCESS; +} + +/* + * FUNCTION: Closes the cabinet file + */ VOID CabinetClose(VOID) -/* - * FUNCTION: Closes the cabinet file - */ -{ - if (FileOpen) - { - CloseCabinet(); - - FileOpen = FALSE; - } -} - - -ULONG -CabinetFindFirst(PWCHAR FileName, - PCAB_SEARCH Search) +{ + if (FileOpen) + { + CloseCabinet(); + FileOpen = FALSE; + } +} + /* * FUNCTION: Finds the first file in the cabinet that matches a search criteria * ARGUMENTS: @@ -689,17 +689,17 @@ * RETURNS: * Status of operation */ -{ - 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) +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); +} + /* * FUNCTION: Finds next file in the cabinet that matches a search criteria * ARGUMENTS: @@ -707,99 +707,116 @@ * RETURNS: * Status of operation */ -{ - ULONG Status; - PCFFILE Prev; - ANSI_STRING AnsiString; - UNICODE_STRING UnicodeString; - WCHAR FileName[MAX_PATH] = {L'\0'}; - - 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(); - - 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() -{ - return (int)RtlValidateHeap(ProcessHeap, 0, 0); -} - -ULONG CabinetExtractFile( PCAB_SEARCH Search ) +ULONG +CabinetFindNext(PCAB_SEARCH Search) +{ + ULONG Status; + PCFFILE Prev; + ANSI_STRING AnsiString; + UNICODE_STRING UnicodeString; + WCHAR FileName[MAX_PATH]; + + if (wcscmp(Search->Cabinet, CabinetName) != 0) + { + /* restart search of cabinet has changed since last find */ + Search->File = 0; + } + + if (!Search->File) + { + /* starting new search or cabinet */ + Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); + Search->Index = 0; + Prev = 0; + } + else + Prev = Search->File; + + 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; + } + } + } + + /* 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(); + + 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; +} + +#if 0 +int +Validate() +{ + return (int)RtlValidateHeap(ProcessHeap, 0, 0); +} +#endif + /* * FUNCTION: Extracts a file from the cabinet * ARGUMENTS: @@ -807,309 +824,339 @@ * RETURNS * Status of operation */ -{ - 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) - { - 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)) +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]; + + 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) + { + 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)) { - 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 - { - 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); - } - } - - 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 - 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) - { - 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); - - return Status; -} - - -VOID -CabinetSelectCodec(ULONG Id) + 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); + } + } + + 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; +} + /* * FUNCTION: Selects codec engine to use * ARGUMENTS: * Id = Codec identifier */ -{ - if (CodecSelected) - { - if (Id == CodecId) - return; - - CodecSelected = FALSE; - } - - switch (Id) - { - case CAB_CODEC_RAW: - CodecUncompress = RawCodecUncompress; - break; - case CAB_CODEC_MSZIP: - CodecUncompress = MSZipCodecUncompress; - break; - default: - return; - } - - CodecId = Id; - CodecSelected = TRUE; -} - - VOID -CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, - PCABINET_EXTRACT Extract, - PCABINET_DISK_CHANGE DiskChange) +CabinetSelectCodec(ULONG Id) +{ + if (CodecSelected) + { + if (Id == CodecId) + return; + + CodecSelected = FALSE; + } + + switch (Id) + { + case CAB_CODEC_RAW: + CodecUncompress = RawCodecUncompress; + break; + case CAB_CODEC_MSZIP: + CodecUncompress = MSZipCodecUncompress; + break; + default: + return; + } + + CodecId = Id; + CodecSelected = TRUE; +} + /* * FUNCTION: Set event handlers * ARGUMENTS: @@ -1117,33 +1164,38 @@ * Extract = Handler called when a file is to be extracted * DiskChange = Handler called when changing the disk */ -{ - OverwriteHandler = Overwrite; - ExtractHandler = Extract; - DiskChangeHandler = DiskChange; -} - - +VOID +CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, + PCABINET_EXTRACT Extract, + PCABINET_DISK_CHANGE DiskChange) +{ + OverwriteHandler = Overwrite; + ExtractHandler = Extract; + DiskChangeHandler = DiskChange; +} + +/* + * FUNCTION: Get pointer to cabinet reserved area. NULL if none + */ PVOID CabinetGetCabinetReservedArea(PULONG Size) -/* - * FUNCTION: Get pointer to cabinet reserved area. NULL if none - */ -{ - if (CabinetReservedArea != NULL) - { - if (Size != NULL) - { - *Size = CabinetReserved; - } - return CabinetReservedArea; - } - else - { - if (Size != NULL) - { - *Size = 0; - } - return NULL; - } -} +{ + if (CabinetReservedArea != NULL) + { + if (Size != NULL) + { + *Size = CabinetReserved; + } + + return CabinetReservedArea; + } + else + { + if (Size != NULL) + { + *Size = 0; + } + + return NULL; + } +}