ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
October 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
21 participants
354 discussions
Start a n
N
ew thread
05/18: [FLTMGR] Stub FltCreateFileEx()
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5fc37876d8e0739a4423b…
commit 5fc37876d8e0739a4423b7612521b007e65dd575 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sun Oct 28 10:26:37 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Mon Oct 29 23:56:39 2018 +0100 [FLTMGR] Stub FltCreateFileEx() --- drivers/filters/fltmgr/Object.c | 36 +++++++++++++++++++++++++++++++++++- drivers/filters/fltmgr/fltmgr.spec | 2 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/filters/fltmgr/Object.c b/drivers/filters/fltmgr/Object.c index 9597738a3d..413b85fce3 100644 --- a/drivers/filters/fltmgr/Object.c +++ b/drivers/filters/fltmgr/Object.c @@ -134,6 +134,40 @@ FltReleasePushLock(_Inout_ _Requires_lock_held_(*_Curr_) _Releases_lock_(*_Curr_ KeLeaveCriticalRegion(); } +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +FLTAPI +FltClose(_In_ HANDLE FileHandle) +{ + PAGED_CODE(); + + return ZwClose(FileHandle); +} + +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +FLTAPI +FltCreateFileEx(_In_ PFLT_FILTER Filter, + _In_opt_ PFLT_INSTANCE Instance, + _Out_ PHANDLE FileHandle, + _Outptr_opt_ PFILE_OBJECT *FileObject, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_opt_ PLARGE_INTEGER AllocationSize, + _In_ ULONG FileAttributes, + _In_ ULONG ShareAccess, + _In_ ULONG CreateDisposition, + _In_ ULONG CreateOptions, + _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, + _In_ ULONG EaLength, + _In_ ULONG Flags) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + /* INTERNAL FUNCTIONS ******************************************************/ @@ -269,4 +303,4 @@ FltpObjectPointerDereference(_In_ PFLT_OBJECT Object) // Cleanup FLT_ASSERT(FALSE); } -} \ No newline at end of file +} diff --git a/drivers/filters/fltmgr/fltmgr.spec b/drivers/filters/fltmgr/fltmgr.spec index af40f77ff4..51ad071a44 100644 --- a/drivers/filters/fltmgr/fltmgr.spec +++ b/drivers/filters/fltmgr/fltmgr.spec @@ -13,4 +13,6 @@ @ stdcall FltEnumerateVolumes(ptr ptr long ptr) @ stdcall FltGetFileNameInformationUnsafe(ptr ptr long ptr) @ stdcall FltCloseClientPort(ptr ptr) + @ stdcall FltClose(ptr) + @ stdcall FltCreateFileEx(ptr ptr ptr ptr long ptr ptr ptr long long long long ptr long long)
6 years, 1 month
1
0
0
0
04/18: [FLTMGR] Export FltCloseClientPort()
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b9c6debe303f78f285f44…
commit b9c6debe303f78f285f44ced2feda10e3a25e0bd Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sun Oct 28 09:35:17 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Mon Oct 29 23:56:39 2018 +0100 [FLTMGR] Export FltCloseClientPort() --- drivers/filters/fltmgr/fltmgr.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/filters/fltmgr/fltmgr.spec b/drivers/filters/fltmgr/fltmgr.spec index 07063fa1bb..af40f77ff4 100644 --- a/drivers/filters/fltmgr/fltmgr.spec +++ b/drivers/filters/fltmgr/fltmgr.spec @@ -12,4 +12,5 @@ @ stdcall FltSendMessage(ptr ptr ptr long ptr ptr ptr) @ stdcall FltEnumerateVolumes(ptr ptr long ptr) @ stdcall FltGetFileNameInformationUnsafe(ptr ptr long ptr) + @ stdcall FltCloseClientPort(ptr ptr)
6 years, 1 month
1
0
0
0
03/18: [FLTMGR] Stub FltGetFileNameInformationUnsafe()
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4c1d7026f63b2c51e9e11…
commit 4c1d7026f63b2c51e9e112c3e250acf3e28c8670 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sun Oct 28 09:34:39 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Mon Oct 29 23:56:39 2018 +0100 [FLTMGR] Stub FltGetFileNameInformationUnsafe() --- drivers/filters/fltmgr/Misc.c | 17 ++++++++++++++++- drivers/filters/fltmgr/fltmgr.spec | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/filters/fltmgr/Misc.c b/drivers/filters/fltmgr/Misc.c index 8643c48882..c2516af136 100644 --- a/drivers/filters/fltmgr/Misc.c +++ b/drivers/filters/fltmgr/Misc.c @@ -53,4 +53,19 @@ FltGetDiskDeviceObject( UNREFERENCED_PARAMETER(Volume); UNREFERENCED_PARAMETER(DiskDeviceObject); return 0; -} \ No newline at end of file +} + +NTSTATUS +FLTAPI +FltGetFileNameInformationUnsafe( + _In_ PFILE_OBJECT FileObject, + _In_opt_ PFLT_INSTANCE Instance, + _In_ FLT_FILE_NAME_OPTIONS NameOptions, + _Outptr_ PFLT_FILE_NAME_INFORMATION *FileNameInformation) +{ + UNREFERENCED_PARAMETER(FileObject); + UNREFERENCED_PARAMETER(Instance); + UNREFERENCED_PARAMETER(NameOptions); + *FileNameInformation = NULL; + return 0; +} diff --git a/drivers/filters/fltmgr/fltmgr.spec b/drivers/filters/fltmgr/fltmgr.spec index 916d742ac6..07063fa1bb 100644 --- a/drivers/filters/fltmgr/fltmgr.spec +++ b/drivers/filters/fltmgr/fltmgr.spec @@ -11,4 +11,5 @@ @ stdcall FltObjectDereference(ptr) @ stdcall FltSendMessage(ptr ptr ptr long ptr ptr ptr) @ stdcall FltEnumerateVolumes(ptr ptr long ptr) + @ stdcall FltGetFileNameInformationUnsafe(ptr ptr long ptr)
6 years, 1 month
1
0
0
0
02/18: [FLTMGR] Implement FltEnumerateVolumes()
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=92dca372783529d8361f7…
commit 92dca372783529d8361f7a3c035d2dfd6a7e5bae Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sun Oct 28 09:26:12 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Mon Oct 29 23:56:39 2018 +0100 [FLTMGR] Implement FltEnumerateVolumes() --- drivers/filters/fltmgr/Volume.c | 75 +++++++++++++++++++++++++++++++++++++- drivers/filters/fltmgr/fltmgr.spec | 1 + 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/drivers/filters/fltmgr/Volume.c b/drivers/filters/fltmgr/Volume.c index 6a854f76a6..d4c21bb999 100644 --- a/drivers/filters/fltmgr/Volume.c +++ b/drivers/filters/fltmgr/Volume.c @@ -107,4 +107,77 @@ FltGetVolumeProperties( } -/* INTERNAL FUNCTIONS ******************************************************/ \ No newline at end of file +NTSTATUS +FLTAPI +FltEnumerateVolumes( + _In_ PFLT_FILTER Filter, + _Out_writes_to_opt_(VolumeListSize,*NumberVolumesReturned) PFLT_VOLUME *VolumeList, + _In_ ULONG VolumeListSize, + _Out_ PULONG NumberVolumesReturned) +{ + ULONG i; + PFLTP_FRAME Frame; + PFLT_VOLUME Volume; + PLIST_ENTRY ListEntry; + ULONG NumberOfVolumes = 0; + NTSTATUS Status = STATUS_SUCCESS; + + PAGED_CODE(); + + Frame = Filter->Frame; + + /* Lock the attached volumes list */ + KeEnterCriticalRegion(); + ExAcquireResourceSharedLite(&Frame->AttachedVolumes.rLock, TRUE); + + /* If it's not empty */ + if (!IsListEmpty(&Frame->AttachedVolumes.rList)) + { + /* Browse every entry */ + for (ListEntry = Frame->AttachedVolumes.rList.Flink; + ListEntry != &Frame->AttachedVolumes.rList; + ListEntry = ListEntry->Flink) + { + /* Get the volume */ + Volume = CONTAINING_RECORD(ListEntry, FLT_VOLUME, Base.PrimaryLink); + + /* If there's still room in the output buffer */ + if (NumberOfVolumes < VolumeListSize) + { + /* Reference the volume and return it */ + FltObjectReference(Volume); + VolumeList[NumberOfVolumes] = Volume; + } + + /* We returned one more volume */ + ++NumberOfVolumes; + } + } + + /* Release the list */ + ExReleaseResourceLite(&Frame->AttachedVolumes.rLock); + KeLeaveCriticalRegion(); + + /* If we want to return more volumes than we can */ + if (NumberOfVolumes > VolumeListSize) + { + /* We will clear output */ + for (i = 0; i < VolumeListSize; ++i) + { + FltObjectDereference(VolumeList[i]); + VolumeList[i] = NULL; + } + + /* And set failure status */ + Status = STATUS_BUFFER_TOO_SMALL; + } + + /* Always return the max amount of volumes we want to return */ + *NumberVolumesReturned = NumberOfVolumes; + + /* Done */ + return Status; +} + + +/* INTERNAL FUNCTIONS ******************************************************/ diff --git a/drivers/filters/fltmgr/fltmgr.spec b/drivers/filters/fltmgr/fltmgr.spec index e3c88de91d..916d742ac6 100644 --- a/drivers/filters/fltmgr/fltmgr.spec +++ b/drivers/filters/fltmgr/fltmgr.spec @@ -10,4 +10,5 @@ @ stdcall FltGetVolumeProperties(ptr ptr long ptr) @ stdcall FltObjectDereference(ptr) @ stdcall FltSendMessage(ptr ptr ptr long ptr ptr ptr) + @ stdcall FltEnumerateVolumes(ptr ptr long ptr)
6 years, 1 month
1
0
0
0
01/18: [FLTMGR] Export FltObjectDereference() and FltSendMessage()
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5bdd806fb9fdb6d8ddf09…
commit 5bdd806fb9fdb6d8ddf092cb9ccc1a8953f4acc3 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sun Oct 28 09:10:40 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Mon Oct 29 23:56:39 2018 +0100 [FLTMGR] Export FltObjectDereference() and FltSendMessage() --- drivers/filters/fltmgr/fltmgr.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/filters/fltmgr/fltmgr.spec b/drivers/filters/fltmgr/fltmgr.spec index c7094eb9cf..e3c88de91d 100644 --- a/drivers/filters/fltmgr/fltmgr.spec +++ b/drivers/filters/fltmgr/fltmgr.spec @@ -8,4 +8,6 @@ @ stdcall FltFreeSecurityDescriptor(ptr) @ stdcall FltGetDiskDeviceObject(ptr ptr) @ stdcall FltGetVolumeProperties(ptr ptr long ptr) + @ stdcall FltObjectDereference(ptr) + @ stdcall FltSendMessage(ptr ptr ptr long ptr ptr ptr)
6 years, 1 month
1
0
0
0
01/01: [USETUP] Refactor the cabinet handling code to place all the global state variables into a CABINET_CONTEXT structure.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9169e881aa1ed3e7f8ac6…
commit 9169e881aa1ed3e7f8ac66af78203123daf6b3c9 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Mon Aug 14 17:11:50 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 28 23:57:06 2018 +0100 [USETUP] Refactor the cabinet handling code to place all the global state variables into a CABINET_CONTEXT structure. Place also all the private cabinet definitions into the .c, keeping into the header file only the "public" structures and function prototypes. --- base/setup/usetup/cabinet.c | 774 +++++++++++++++++++++++++----------------- base/setup/usetup/cabinet.h | 272 +++++++-------- base/setup/usetup/filequeue.c | 16 + base/setup/usetup/usetup.c | 13 + 4 files changed, 630 insertions(+), 445 deletions(-) diff --git a/base/setup/usetup/cabinet.c b/base/setup/usetup/cabinet.c index f6bc22b485..7e8450ca42 100644 --- a/base/setup/usetup/cabinet.c +++ b/base/setup/usetup/cabinet.c @@ -16,6 +16,11 @@ #define NDEBUG #include <debug.h> + +/* DEFINITIONS **************************************************************/ + +/* File management definitions */ + #define SEEK_BEGIN 0 #define SEEK_CURRENT 1 #ifndef SEEK_END @@ -29,7 +34,6 @@ typedef struct _DOSTIME WORD Hour:5; } DOSTIME, *PDOSTIME; - typedef struct _DOSDATE { WORD Day:5; @@ -37,37 +41,102 @@ typedef struct _DOSDATE WORD Year:5; } DOSDATE, *PDOSDATE; -static WCHAR CabinetName[256]; // Filename of current cabinet -static WCHAR CabinetPrev[256]; // Filename of previous cabinet -static WCHAR DiskPrev[256]; // Label of cabinet in file CabinetPrev -static WCHAR CabinetNext[256]; // Filename of next cabinet -static WCHAR DiskNext[256]; // Label of cabinet in file CabinetNext -static ULONG FolderUncompSize = 0; // Uncompressed size of folder -static ULONG BytesLeftInBlock = 0; // Number of bytes left in current block -static WCHAR DestPath[MAX_PATH]; -static HANDLE FileHandle; -static HANDLE FileSectionHandle; -static PUCHAR FileBuffer; -static SIZE_T DestFileSize; -static SIZE_T FileSize; -static BOOL FileOpen = FALSE; -static PCFHEADER PCABHeader; -static PCFFOLDER CabinetFolders; -static ULONG CabinetReserved = 0; -static ULONG FolderReserved = 0; -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 PCABINET_OVERWRITE OverwriteHandler = NULL; -static PCABINET_EXTRACT ExtractHandler = NULL; -static PCABINET_DISK_CHANGE DiskChangeHandler = NULL; -static z_stream ZStream; -static PVOID CabinetReservedArea = NULL; - - -/* Needed by zlib, but we don't want the dependency on msvcrt.dll */ + +/* Cabinet constants */ + +#define CAB_SIGNATURE 0x4643534D // "MSCF" +#define CAB_VERSION 0x0103 +#define CAB_BLOCKSIZE 32768 + +#define CAB_COMP_MASK 0x00FF +#define CAB_COMP_NONE 0x0000 +#define CAB_COMP_MSZIP 0x0001 +#define CAB_COMP_QUANTUM 0x0002 +#define CAB_COMP_LZX 0x0003 + +#define CAB_FLAG_HASPREV 0x0001 +#define CAB_FLAG_HASNEXT 0x0002 +#define CAB_FLAG_RESERVE 0x0004 + +#define CAB_ATTRIB_READONLY 0x0001 +#define CAB_ATTRIB_HIDDEN 0x0002 +#define CAB_ATTRIB_SYSTEM 0x0004 +#define CAB_ATTRIB_VOLUME 0x0008 +#define CAB_ATTRIB_DIRECTORY 0x0010 +#define CAB_ATTRIB_ARCHIVE 0x0020 +#define CAB_ATTRIB_EXECUTE 0x0040 +#define CAB_ATTRIB_UTF_NAME 0x0080 + +#define CAB_FILE_MAX_FOLDER 0xFFFC +#define CAB_FILE_CONTINUED 0xFFFD +#define CAB_FILE_SPLIT 0xFFFE +#define CAB_FILE_PREV_NEXT 0xFFFF + + +/* Cabinet structures */ + +typedef struct _CFHEADER +{ + ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE) + ULONG Reserved1; // Reserved field + ULONG CabinetSize; // Cabinet file size + ULONG Reserved2; // Reserved field + ULONG FileTableOffset; // Offset of first CFFILE + ULONG Reserved3; // Reserved field + USHORT Version; // Cabinet version (CAB_VERSION) + USHORT FolderCount; // Number of folders + USHORT FileCount; // Number of files + USHORT Flags; // Cabinet flags (CAB_FLAG_*) + USHORT SetID; // Cabinet set id + USHORT CabinetNumber; // Zero-based cabinet number +/* Optional fields (depends on Flags) + USHORT CabinetResSize // Per-cabinet reserved area size + CHAR FolderResSize // Per-folder reserved area size + CHAR FileResSize // Per-file reserved area size + CHAR CabinetReserved[] // Per-cabinet reserved area + CHAR CabinetPrev[] // Name of previous cabinet file + CHAR DiskPrev[] // Name of previous disk + CHAR CabinetNext[] // Name of next cabinet file + CHAR DiskNext[] // Name of next disk + */ +} CFHEADER, *PCFHEADER; + +typedef struct _CFFOLDER +{ + ULONG DataOffset; // Absolute offset of first CFDATA block in this folder + USHORT DataBlockCount; // Number of CFDATA blocks in this folder in this cabinet + USHORT CompressionType; // Type of compression used for all CFDATA blocks in this folder +/* Optional fields (depends on Flags) + CHAR FolderReserved[] // Per-folder reserved area + */ +} CFFOLDER, *PCFFOLDER; + +typedef struct _CFFILE +{ + ULONG FileSize; // Uncompressed file size in bytes + ULONG FileOffset; // Uncompressed offset of file in the folder + USHORT FolderIndex; // Index number of the folder that contains this file + USHORT FileDate; // File date stamp, as used by DOS + USHORT FileTime; // File time stamp, as used by DOS + USHORT Attributes; // File attributes (CAB_ATTRIB_*) + CHAR FileName[ANYSIZE_ARRAY]; + /* After this is the NULL terminated filename */ +} CFFILE, *PCFFILE; + +typedef struct _CFDATA +{ + ULONG Checksum; // Checksum of CFDATA entry + USHORT CompSize; // Number of compressed bytes in this block + USHORT UncompSize; // Number of uncompressed bytes in this block +/* Optional fields (depends on Flags) + CHAR DataReserved[] // Per-datablock reserved area + */ +} CFDATA, *PCFDATA; + + +/* FUNCTIONS ****************************************************************/ + +/* Needed by zlib, but we don't want the dependency on the CRT */ void *__cdecl malloc(size_t size) { @@ -86,6 +155,25 @@ calloc(size_t nmemb, size_t size) return (void *)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, nmemb * size); } + +/* Codecs */ + +/* Uncompresses a data block */ +typedef ULONG (*PCABINET_CODEC_UNCOMPRESS)( + IN struct _CAB_CODEC* Codec, + OUT PVOID OutputBuffer, + IN PVOID InputBuffer, + IN OUT PLONG InputLength, + IN OUT PLONG OutputLength); + +typedef struct _CAB_CODEC +{ + PCABINET_CODEC_UNCOMPRESS Uncompress; + z_stream ZStream; + // Other CODEC-related structures +} CAB_CODEC, *PCAB_CODEC; + + /* RAW codec */ /* @@ -99,10 +187,12 @@ calloc(size_t nmemb, size_t size) * Negative to indicate that this is not the end of the block */ ULONG -RawCodecUncompress(PVOID OutputBuffer, - PVOID InputBuffer, - PLONG InputLength, - PLONG OutputLength) +RawCodecUncompress( + IN OUT PCAB_CODEC Codec, + OUT PVOID OutputBuffer, + IN PVOID InputBuffer, + IN OUT PLONG InputLength, + IN OUT PLONG OutputLength) { LONG Len = min(abs(*InputLength), abs(*OutputLength)); @@ -112,8 +202,15 @@ RawCodecUncompress(PVOID OutputBuffer, return CS_SUCCESS; } +static CAB_CODEC RawCodec = +{ + RawCodecUncompress, {0} +}; + /* MSZIP codec */ +#define MSZIP_MAGIC 0x4B43 + /* * FUNCTION: Uncompresses data in a buffer * ARGUMENTS: @@ -125,10 +222,12 @@ RawCodecUncompress(PVOID OutputBuffer, * Negative to indicate that this is not the end of the block */ ULONG -MSZipCodecUncompress(PVOID OutputBuffer, - PVOID InputBuffer, - PLONG InputLength, - PLONG OutputLength) +MSZipCodecUncompress( + IN OUT PCAB_CODEC Codec, + OUT PVOID OutputBuffer, + IN PVOID InputBuffer, + IN OUT PLONG InputLength, + IN OUT PLONG OutputLength) { USHORT Magic; INT Status; @@ -136,6 +235,7 @@ MSZipCodecUncompress(PVOID OutputBuffer, DPRINT("MSZipCodecUncompress(OutputBuffer = %x, InputBuffer = %x, " "InputLength = %d, OutputLength = %d)\n", OutputBuffer, InputBuffer, *InputLength, *OutputLength); + if (*InputLength > 0) { Magic = *(PUSHORT)InputBuffer; @@ -146,38 +246,38 @@ MSZipCodecUncompress(PVOID OutputBuffer, return CS_BADSTREAM; } - ZStream.next_in = (PUCHAR)InputBuffer + 2; - ZStream.avail_in = *InputLength - 2; - ZStream.next_out = (PUCHAR)OutputBuffer; - ZStream.avail_out = abs(*OutputLength); + Codec->ZStream.next_in = (PUCHAR)InputBuffer + 2; + Codec->ZStream.avail_in = *InputLength - 2; + Codec->ZStream.next_out = (PUCHAR)OutputBuffer; + Codec->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); + Status = inflateInit2(&Codec->ZStream, -MAX_WBITS); if (Status != Z_OK) { DPRINT("inflateInit2() returned (%d)\n", Status); return CS_BADSTREAM; } - ZStream.total_in = 2; + Codec->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; + Codec->ZStream.avail_in = -*InputLength; + Codec->ZStream.next_in = (PUCHAR)InputBuffer; + Codec->ZStream.next_out = (PUCHAR)OutputBuffer; + Codec->ZStream.avail_out = abs(*OutputLength); + Codec->ZStream.total_in = 0; } - ZStream.total_out = 0; - Status = inflate(&ZStream, Z_SYNC_FLUSH); + Codec->ZStream.total_out = 0; + Status = inflate(&Codec->ZStream, Z_SYNC_FLUSH); if (Status != Z_OK && Status != Z_STREAM_END) { - DPRINT("inflate() returned (%d) (%s)\n", Status, ZStream.msg); + DPRINT("inflate() returned (%d) (%s)\n", Status, Codec->ZStream.msg); if (Status == Z_MEM_ERROR) return CS_NOMEMORY; return CS_BADSTREAM; @@ -185,7 +285,7 @@ MSZipCodecUncompress(PVOID OutputBuffer, if (*OutputLength > 0) { - Status = inflateEnd(&ZStream); + Status = inflateEnd(&Codec->ZStream); if (Status != Z_OK) { DPRINT("inflateEnd() returned (%d)\n", Status); @@ -193,12 +293,18 @@ MSZipCodecUncompress(PVOID OutputBuffer, } } - *OutputLength = ZStream.total_out; - *InputLength = ZStream.total_in; + *InputLength = Codec->ZStream.total_in; + *OutputLength = Codec->ZStream.total_out; return CS_SUCCESS; } +static CAB_CODEC MSZipCodec = +{ + MSZipCodecUncompress, {0} +}; + + /* Memory functions */ voidpf @@ -374,14 +480,15 @@ SetAttributesOnFile(PCFFILE File, * Status of operation */ static ULONG -CloseCabinet(VOID) +CloseCabinet( + IN PCABINET_CONTEXT CabinetContext) { - if (FileBuffer) + if (CabinetContext->FileBuffer) { - NtUnmapViewOfSection(NtCurrentProcess(), FileBuffer); - NtClose(FileSectionHandle); - NtClose(FileHandle); - FileBuffer = NULL; + NtUnmapViewOfSection(NtCurrentProcess(), CabinetContext->FileBuffer); + NtClose(CabinetContext->FileSectionHandle); + NtClose(CabinetContext->FileHandle); + CabinetContext->FileBuffer = NULL; } return 0; @@ -391,34 +498,38 @@ CloseCabinet(VOID) * FUNCTION: Initialize archiver */ VOID -CabinetInitialize(VOID) +CabinetInitialize( + IN OUT PCABINET_CONTEXT CabinetContext) { - 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; + RtlZeroMemory(CabinetContext, sizeof(*CabinetContext)); + + CabinetContext->FileOpen = FALSE; + wcscpy(CabinetContext->DestPath, L""); + + CabinetContext->CodecSelected = FALSE; + CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW); + + CabinetContext->OverwriteHandler = NULL; + CabinetContext->ExtractHandler = NULL; + CabinetContext->DiskChangeHandler = NULL; + + CabinetContext->FolderUncompSize = 0; + CabinetContext->BytesLeftInBlock = 0; + CabinetContext->CabinetReserved = 0; + CabinetContext->FolderReserved = 0; + CabinetContext->DataReserved = 0; + CabinetContext->CabinetReservedArea = NULL; + CabinetContext->LastFileOffset = 0; } /* * FUNCTION: Cleanup archiver */ VOID -CabinetCleanup(VOID) +CabinetCleanup( + IN OUT PCABINET_CONTEXT CabinetContext) { - CabinetClose(); + CabinetClose(CabinetContext); } /* @@ -429,7 +540,7 @@ CabinetCleanup(VOID) * RETURNS: * TRUE if there was enough room in Path, or FALSE */ -BOOL +static BOOL CabinetNormalizePath(PWCHAR Path, ULONG Length) { @@ -453,10 +564,11 @@ CabinetNormalizePath(PWCHAR Path, * RETURNS: * Pointer to string with name of cabinet */ -PWCHAR -CabinetGetCabinetName(VOID) +PCWSTR +CabinetGetCabinetName( + IN PCABINET_CONTEXT CabinetContext) { - return CabinetName; + return CabinetContext->CabinetName; } /* @@ -465,9 +577,11 @@ CabinetGetCabinetName(VOID) * FileName = Pointer to string with name of cabinet */ VOID -CabinetSetCabinetName(PWCHAR FileName) +CabinetSetCabinetName( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR FileName) { - wcscpy(CabinetName, FileName); + wcscpy(CabinetContext->CabinetName, FileName); } /* @@ -476,12 +590,14 @@ CabinetSetCabinetName(PWCHAR FileName) * DestinationPath = Pointer to string with name of destination path */ VOID -CabinetSetDestinationPath(PWCHAR DestinationPath) +CabinetSetDestinationPath( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR DestinationPath) { - wcscpy(DestPath, DestinationPath); + wcscpy(CabinetContext->DestPath, DestinationPath); - if (wcslen(DestPath) > 0) - CabinetNormalizePath(DestPath, MAX_PATH); + if (wcslen(CabinetContext->DestPath) > 0) + CabinetNormalizePath(CabinetContext->DestPath, MAX_PATH); } /* @@ -489,10 +605,11 @@ CabinetSetDestinationPath(PWCHAR DestinationPath) * RETURNS: * Pointer to string with name of destination path */ -PWCHAR -CabinetGetDestinationPath(VOID) +PCWSTR +CabinetGetDestinationPath( + IN PCABINET_CONTEXT CabinetContext) { - return DestPath; + return CabinetContext->DestPath; } /* @@ -501,164 +618,170 @@ CabinetGetDestinationPath(VOID) * Status of operation */ ULONG -CabinetOpen(VOID) +CabinetOpen( + IN OUT PCABINET_CONTEXT CabinetContext) { PUCHAR Buffer; UNICODE_STRING ustring; ANSI_STRING astring; - if (!FileOpen) - { - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - UNICODE_STRING FileName; - NTSTATUS NtStatus; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING FileName; + NTSTATUS NtStatus; - RtlInitUnicodeString(&FileName, CabinetName); + if (CabinetContext->FileOpen) + { + /* Cabinet file already opened */ + DPRINT("CabinetOpen returning SUCCESS\n"); + return CAB_STATUS_SUCCESS; + } - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, NULL); + RtlInitUnicodeString(&FileName, CabinetContext->CabinetName); - NtStatus = NtOpenFile(&FileHandle, - GENERIC_READ | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ, - FILE_SYNCHRONOUS_IO_NONALERT); + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, NULL); - if (!NT_SUCCESS(NtStatus)) - { - DPRINT1("Cannot open file (%S) (%x)\n", CabinetName, NtStatus); - return CAB_STATUS_CANNOT_OPEN; - } + NtStatus = NtOpenFile(&CabinetContext->FileHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); - FileOpen = TRUE; + if (!NT_SUCCESS(NtStatus)) + { + DPRINT1("Cannot open file (%S) (%x)\n", CabinetContext->CabinetName, NtStatus); + return CAB_STATUS_CANNOT_OPEN; + } - NtStatus = NtCreateSection(&FileSectionHandle, - SECTION_ALL_ACCESS, - 0, 0, - PAGE_READONLY, - SEC_COMMIT, - FileHandle); + CabinetContext->FileOpen = TRUE; - if (!NT_SUCCESS(NtStatus)) - { - DPRINT1("NtCreateSection failed for %ls: %x\n", CabinetName, NtStatus); - return CAB_STATUS_NOMEMORY; - } + NtStatus = NtCreateSection(&CabinetContext->FileSectionHandle, + SECTION_ALL_ACCESS, + 0, 0, + PAGE_READONLY, + SEC_COMMIT, + CabinetContext->FileHandle); - FileBuffer = 0; - FileSize = 0; + if (!NT_SUCCESS(NtStatus)) + { + DPRINT1("NtCreateSection failed for %ls: %x\n", CabinetContext->CabinetName, NtStatus); + return CAB_STATUS_NOMEMORY; + } - NtStatus = NtMapViewOfSection(FileSectionHandle, - NtCurrentProcess(), - (PVOID *)&FileBuffer, - 0, 0, 0, - &FileSize, - ViewUnmap, - 0, - PAGE_READONLY); + CabinetContext->FileBuffer = 0; + CabinetContext->FileSize = 0; - if (!NT_SUCCESS(NtStatus)) - { - DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus); - return CAB_STATUS_NOMEMORY; - } + NtStatus = NtMapViewOfSection(CabinetContext->FileSectionHandle, + NtCurrentProcess(), + (PVOID*)&CabinetContext->FileBuffer, + 0, 0, 0, + &CabinetContext->FileSize, + ViewUnmap, + 0, + PAGE_READONLY); - DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer); - PCABHeader = (PCFHEADER) FileBuffer; + if (!NT_SUCCESS(NtStatus)) + { + DPRINT1("NtMapViewOfSection failed: %x\n", NtStatus); + return CAB_STATUS_NOMEMORY; + } - /* 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(); - DPRINT1("File has invalid header\n"); - return CAB_STATUS_INVALID_CAB; - } + DPRINT("Cabinet file %S opened and mapped to %x\n", + CabinetContext->CabinetName, CabinetContext->FileBuffer); + CabinetContext->PCABHeader = (PCFHEADER)CabinetContext->FileBuffer; + + /* Check header */ + if (CabinetContext->FileSize <= sizeof(CFHEADER) || + CabinetContext->PCABHeader->Signature != CAB_SIGNATURE || + CabinetContext->PCABHeader->Version != CAB_VERSION || + CabinetContext->PCABHeader->FolderCount == 0 || + CabinetContext->PCABHeader->FileCount == 0 || + CabinetContext->PCABHeader->FileTableOffset < sizeof(CFHEADER)) + { + CloseCabinet(CabinetContext); + DPRINT1("File has invalid header\n"); + return CAB_STATUS_INVALID_CAB; + } - Buffer = (PUCHAR)(PCABHeader + 1); + Buffer = (PUCHAR)(CabinetContext->PCABHeader + 1); - /* Read/skip any reserved bytes */ - if (PCABHeader->Flags & CAB_FLAG_RESERVE) + /* Read/skip any reserved bytes */ + if (CabinetContext->PCABHeader->Flags & CAB_FLAG_RESERVE) + { + CabinetContext->CabinetReserved = *(PUSHORT)Buffer; + Buffer += 2; + CabinetContext->FolderReserved = *Buffer; + Buffer++; + CabinetContext->DataReserved = *Buffer; + Buffer++; + + if (CabinetContext->CabinetReserved > 0) { - CabinetReserved = *(PUSHORT)Buffer; - Buffer += 2; - FolderReserved = *Buffer; - Buffer++; - DataReserved = *Buffer; - Buffer++; - - if (CabinetReserved > 0) - { - CabinetReservedArea = Buffer; - Buffer += CabinetReserved; - } + CabinetContext->CabinetReservedArea = Buffer; + Buffer += CabinetContext->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 (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASPREV) + { + /* The previous cabinet file is in + the same directory as the current */ + wcscpy(CabinetContext->CabinetPrev, CabinetContext->CabinetName); + RemoveFileName(CabinetContext->CabinetPrev); + CabinetNormalizePath(CabinetContext->CabinetPrev, 256); + RtlInitAnsiString(&astring, (LPSTR)Buffer); + ustring.Length = wcslen(CabinetContext->CabinetPrev); + ustring.Buffer = CabinetContext->CabinetPrev + ustring.Length; + ustring.MaximumLength = sizeof(CabinetContext->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 = CabinetContext->DiskPrev; + ustring.MaximumLength = sizeof(CabinetContext->DiskPrev); + RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); + Buffer += astring.Length + 1; + } + else + { + wcscpy(CabinetContext->CabinetPrev, L""); + wcscpy(CabinetContext->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; + if (CabinetContext->PCABHeader->Flags & CAB_FLAG_HASNEXT) + { + /* The next cabinet file is in + the same directory as the previous */ + wcscpy(CabinetContext->CabinetNext, CabinetContext->CabinetName); + RemoveFileName(CabinetContext->CabinetNext); + CabinetNormalizePath(CabinetContext->CabinetNext, 256); + RtlInitAnsiString(&astring, (LPSTR)Buffer); + ustring.Length = wcslen(CabinetContext->CabinetNext); + ustring.Buffer = CabinetContext->CabinetNext + ustring.Length; + ustring.MaximumLength = sizeof(CabinetContext->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 = CabinetContext->DiskNext; + ustring.MaximumLength = sizeof(CabinetContext->DiskNext); + RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); + Buffer += astring.Length + 1; + } + else + { + wcscpy(CabinetContext->CabinetNext, L""); + wcscpy(CabinetContext->DiskNext, L""); } + CabinetContext->CabinetFolders = (PCFFOLDER)Buffer; DPRINT("CabinetOpen returning SUCCESS\n"); return CAB_STATUS_SUCCESS; @@ -668,13 +791,14 @@ CabinetOpen(VOID) * FUNCTION: Closes the cabinet file */ VOID -CabinetClose(VOID) +CabinetClose( + IN OUT PCABINET_CONTEXT CabinetContext) { - if (FileOpen) - { - CloseCabinet(); - FileOpen = FALSE; - } + if (!CabinetContext->FileOpen) + return; + + CloseCabinet(CabinetContext); + CabinetContext->FileOpen = FALSE; } /* @@ -686,31 +810,16 @@ CabinetClose(VOID) * Status of operation */ ULONG -CabinetFindFirst(PWCHAR FileName, - PCAB_SEARCH Search) +CabinetFindFirst( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR FileName, + IN OUT PCAB_SEARCH Search) { - DPRINT("CabinetFindFirst( FileName = %S )\n", FileName); + DPRINT("CabinetFindFirst(FileName = %S)\n", FileName); wcsncpy(Search->Search, FileName, MAX_PATH); - wcsncpy(Search->Cabinet, CabinetName, MAX_PATH); + wcsncpy(Search->Cabinet, CabinetContext->CabinetName, MAX_PATH); Search->File = 0; - return CabinetFindNext(Search); -} - -/* - * FUNCTION: Finds the next file in the cabinet that matches a search criteria - * ARGUMENTS: - * FileName = Pointer to search criteria - * Search = Pointer to search structure - * RETURNS: - * Status of operation - */ -ULONG -CabinetFindNextFileSequential(PWCHAR FileName, - PCAB_SEARCH Search) -{ - DPRINT("CabinetFindNextFileSequential( FileName = %S )\n", FileName); - wcsncpy(Search->Search, FileName, MAX_PATH); - return CabinetFindNext(Search); + return CabinetFindNext(CabinetContext, Search); } /* @@ -721,14 +830,16 @@ CabinetFindNextFileSequential(PWCHAR FileName, * Status of operation */ ULONG -CabinetFindNext(PCAB_SEARCH Search) +CabinetFindNext( + IN PCABINET_CONTEXT CabinetContext, + IN OUT PCAB_SEARCH Search) { PCFFILE Prev; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; WCHAR FileName[MAX_PATH]; - if (wcscmp(Search->Cabinet, CabinetName) != 0) + if (wcscmp(Search->Cabinet, CabinetContext->CabinetName) != 0) { /* restart search of cabinet has changed since last find */ Search->File = 0; @@ -737,7 +848,7 @@ CabinetFindNext(PCAB_SEARCH Search) if (!Search->File) { /* starting new search or cabinet */ - Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); + Search->File = (PCFFILE)(CabinetContext->FileBuffer + CabinetContext->PCABHeader->FileTableOffset); Search->Index = 0; Prev = 0; } @@ -753,7 +864,7 @@ CabinetFindNext(PCAB_SEARCH Search) /* 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); + Search->File->FileOffset, CabinetContext->LastFileOffset); } else { @@ -789,7 +900,7 @@ CabinetFindNext(PCAB_SEARCH Search) /* if we make it here we found no match, so move to the next file */ Search->Index++; - if (Search->Index >= PCABHeader->FileCount) + if (Search->Index >= CabinetContext->PCABHeader->FileCount) { /* we have reached the end of this cabinet */ DPRINT("End of cabinet reached\n"); @@ -803,6 +914,25 @@ CabinetFindNext(PCAB_SEARCH Search) return CAB_STATUS_SUCCESS; } +/* + * FUNCTION: Finds the next file in the cabinet that matches a search criteria + * ARGUMENTS: + * FileName = Pointer to search criteria + * Search = Pointer to search structure + * RETURNS: + * Status of operation + */ +ULONG +CabinetFindNextFileSequential( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR FileName, + IN OUT PCAB_SEARCH Search) +{ + DPRINT("CabinetFindNextFileSequential(FileName = %S)\n", FileName); + wcsncpy(Search->Search, FileName, MAX_PATH); + return CabinetFindNext(CabinetContext, Search); +} + #if 0 int Validate(VOID) @@ -819,7 +949,9 @@ Validate(VOID) * Status of operation */ ULONG -CabinetExtractFile(PCAB_SEARCH Search) +CabinetExtractFile( + IN PCABINET_CONTEXT CabinetContext, + IN PCAB_SEARCH Search) { ULONG Size; // remaining file bytes to decompress ULONG CurrentOffset; // current uncompressed offset within the folder @@ -842,13 +974,13 @@ CabinetExtractFile(PCAB_SEARCH Search) PCFFOLDER CurrentFolder; LARGE_INTEGER MaxDestFileSize; LONG InputLength, OutputLength; - char Junk[512]; + char Chunk[512]; - if (wcscmp(Search->Cabinet, CabinetName) != 0) + if (wcscmp(Search->Cabinet, CabinetContext->CabinetName) != 0) { /* the file is not in the current cabinet */ DPRINT("File is not in this cabinet (%S != %S)\n", - Search->Cabinet, CabinetName); + Search->Cabinet, CabinetContext->CabinetName); return CAB_STATUS_NOFILE; } @@ -863,21 +995,21 @@ CabinetExtractFile(PCAB_SEARCH Search) else if (Search->File->FolderIndex == 0xFFFE) { /* folder is the last in this cabinet and continues into next */ - CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1]; + CurrentFolder = &CabinetContext->CabinetFolders[CabinetContext->PCABHeader->FolderCount - 1]; } else { /* folder is completely contained within this cabinet */ - CurrentFolder = &CabinetFolders[Search->File->FolderIndex]; + CurrentFolder = &CabinetContext->CabinetFolders[Search->File->FolderIndex]; } switch (CurrentFolder->CompressionType & CAB_COMP_MASK) { case CAB_COMP_NONE: - CabinetSelectCodec(CAB_CODEC_RAW); + CabinetSelectCodec(CabinetContext, CAB_CODEC_RAW); break; case CAB_COMP_MSZIP: - CabinetSelectCodec(CAB_CODEC_MSZIP); + CabinetSelectCodec(CabinetContext, CAB_CODEC_MSZIP); break; default: return CAB_STATUS_UNSUPPCOMP; @@ -887,7 +1019,7 @@ CabinetExtractFile(PCAB_SEARCH Search) (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize); RtlInitAnsiString(&AnsiString, Search->File->FileName); - wcscpy(DestName, DestPath); + wcscpy(DestName, CabinetContext->DestPath); UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR); UnicodeString.Buffer = DestName + wcslen(DestName); UnicodeString.Length = 0; @@ -917,7 +1049,8 @@ CabinetExtractFile(PCAB_SEARCH Search) DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); /* If file exists, ask to overwrite file */ - if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName)) + if (CabinetContext->OverwriteHandler == NULL || + CabinetContext->OverwriteHandler(CabinetContext, Search->File, DestName)) { /* Create destination file, overwrite if it already exists */ NtStatus = NtCreateFile(&DestFile, @@ -955,18 +1088,18 @@ CabinetExtractFile(PCAB_SEARCH Search) if (!NT_SUCCESS(NtStatus)) { - DPRINT1("NtCreateSection failed for %ls, %x\n", DestName, NtStatus); + DPRINT1("NtCreateSection failed for %ls: %x\n", DestName, NtStatus); Status = CAB_STATUS_NOMEMORY; goto CloseDestFile; } DestFileBuffer = 0; - DestFileSize = 0; + CabinetContext->DestFileSize = 0; NtStatus = NtMapViewOfSection(DestFileSection, NtCurrentProcess(), &DestFileBuffer, 0, 0, 0, - &DestFileSize, + &CabinetContext->DestFileSize, ViewUnmap, 0, PAGE_READWRITE); @@ -1015,15 +1148,13 @@ CabinetExtractFile(PCAB_SEARCH Search) SetAttributesOnFile(Search->File, DestFile); /* Call extract event handler */ - if (ExtractHandler != NULL) - { - ExtractHandler(Search->File, DestName); - } + if (CabinetContext->ExtractHandler != NULL) + CabinetContext->ExtractHandler(CabinetContext, Search->File, DestName); if (Search->CFData) CFData = Search->CFData; else - CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer); + CFData = (PCFDATA)(CabinetContext->CabinetFolders[Search->File->FolderIndex].DataOffset + CabinetContext->FileBuffer); CurrentOffset = Search->Offset; while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset) @@ -1031,7 +1162,7 @@ CabinetExtractFile(PCAB_SEARCH Search) /* 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); + CFData = (PCFDATA)((char *)(CFData + 1) + CabinetContext->DataReserved + CFData->CompSize); } Search->CFData = CFData; @@ -1041,21 +1172,27 @@ CabinetExtractFile(PCAB_SEARCH Search) the block before the start of the file */ /* start of comp data */ - CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved; + CurrentBuffer = ((unsigned char *)(CFData + 1)) + CabinetContext->DataReserved; RemainingBlock = CFData->CompSize; InputLength = RemainingBlock; while (CurrentOffset < Search->File->FileOffset) { /* compute remaining uncomp bytes to start - of file, bounded by sizeof junk */ + of file, bounded by size of chunk */ OutputLength = Search->File->FileOffset - CurrentOffset; - if (OutputLength > (LONG)sizeof(Junk)) - OutputLength = sizeof (Junk); + if (OutputLength > (LONG)sizeof(Chunk)) + OutputLength = sizeof(Chunk); /* negate to signal NOT end of block */ OutputLength = -OutputLength; - CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength); + + CabinetContext->Codec->Uncompress(CabinetContext->Codec, + Chunk, + CurrentBuffer, + &InputLength, + &OutputLength); + /* add the uncomp bytes extracted to current folder offset */ CurrentOffset += OutputLength; /* add comp bytes consumed to CurrentBuffer */ @@ -1077,11 +1214,11 @@ CabinetExtractFile(PCAB_SEARCH Search) DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n", CurrentBuffer, RemainingBlock, Size); - Status = CodecUncompress(CurrentDestBuffer, - CurrentBuffer, - &InputLength, - &OutputLength); - + Status = CabinetContext->Codec->Uncompress(CabinetContext->Codec, + CurrentDestBuffer, + CurrentBuffer, + &InputLength, + &OutputLength); if (Status != CS_SUCCESS) { DPRINT("Cannot uncompress block\n"); @@ -1105,7 +1242,7 @@ CabinetExtractFile(PCAB_SEARCH Search) DPRINT("Out of block data\n"); CFData = (PCFDATA)CurrentBuffer; RemainingBlock = CFData->CompSize; - CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved; + CurrentBuffer = (unsigned char *)(CFData + 1) + CabinetContext->DataReserved; InputLength = RemainingBlock; } } @@ -1130,30 +1267,41 @@ CloseDestFile: * Id = Codec identifier */ VOID -CabinetSelectCodec(ULONG Id) +CabinetSelectCodec( + IN PCABINET_CONTEXT CabinetContext, + IN ULONG Id) { - if (CodecSelected) + if (CabinetContext->CodecSelected) { - if (Id == CodecId) + if (Id == CabinetContext->CodecId) return; - CodecSelected = FALSE; + CabinetContext->CodecSelected = FALSE; } switch (Id) { case CAB_CODEC_RAW: - CodecUncompress = RawCodecUncompress; + { + CabinetContext->Codec = &RawCodec; break; + } + case CAB_CODEC_MSZIP: - CodecUncompress = MSZipCodecUncompress; + { + CabinetContext->Codec = &MSZipCodec; + CabinetContext->Codec->ZStream.zalloc = MSZipAlloc; + CabinetContext->Codec->ZStream.zfree = MSZipFree; + CabinetContext->Codec->ZStream.opaque = (voidpf)0; break; + } + default: return; } - CodecId = Id; - CodecSelected = TRUE; + CabinetContext->CodecId = Id; + CabinetContext->CodecSelected = TRUE; } /* @@ -1164,29 +1312,33 @@ CabinetSelectCodec(ULONG Id) * DiskChange = Handler called when changing the disk */ VOID -CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, - PCABINET_EXTRACT Extract, - PCABINET_DISK_CHANGE DiskChange) +CabinetSetEventHandlers( + IN PCABINET_CONTEXT CabinetContext, + IN PCABINET_OVERWRITE Overwrite, + IN PCABINET_EXTRACT Extract, + IN PCABINET_DISK_CHANGE DiskChange) { - OverwriteHandler = Overwrite; - ExtractHandler = Extract; - DiskChangeHandler = DiskChange; + CabinetContext->OverwriteHandler = Overwrite; + CabinetContext->ExtractHandler = Extract; + CabinetContext->DiskChangeHandler = DiskChange; } /* * FUNCTION: Get pointer to cabinet reserved area. NULL if none */ PVOID -CabinetGetCabinetReservedArea(PULONG Size) +CabinetGetCabinetReservedArea( + IN PCABINET_CONTEXT CabinetContext, + OUT PULONG Size) { - if (CabinetReservedArea != NULL) + if (CabinetContext->CabinetReservedArea != NULL) { if (Size != NULL) { - *Size = CabinetReserved; + *Size = CabinetContext->CabinetReserved; } - return CabinetReservedArea; + return CabinetContext->CabinetReservedArea; } else { diff --git a/base/setup/usetup/cabinet.h b/base/setup/usetup/cabinet.h index 82392687d7..4dfd36e750 100644 --- a/base/setup/usetup/cabinet.h +++ b/base/setup/usetup/cabinet.h @@ -6,111 +6,15 @@ */ #pragma once -#include <string.h> - -/* Cabinet constants */ - -#define CAB_SIGNATURE 0x4643534D // "MSCF" -#define CAB_VERSION 0x0103 -#define CAB_BLOCKSIZE 32768 - -#define CAB_COMP_MASK 0x00FF -#define CAB_COMP_NONE 0x0000 -#define CAB_COMP_MSZIP 0x0001 -#define CAB_COMP_QUANTUM 0x0002 -#define CAB_COMP_LZX 0x0003 - -#define CAB_FLAG_HASPREV 0x0001 -#define CAB_FLAG_HASNEXT 0x0002 -#define CAB_FLAG_RESERVE 0x0004 - -#define CAB_ATTRIB_READONLY 0x0001 -#define CAB_ATTRIB_HIDDEN 0x0002 -#define CAB_ATTRIB_SYSTEM 0x0004 -#define CAB_ATTRIB_VOLUME 0x0008 -#define CAB_ATTRIB_DIRECTORY 0x0010 -#define CAB_ATTRIB_ARCHIVE 0x0020 -#define CAB_ATTRIB_EXECUTE 0x0040 -#define CAB_ATTRIB_UTF_NAME 0x0080 - -#define CAB_FILE_MAX_FOLDER 0xFFFC -#define CAB_FILE_CONTINUED 0xFFFD -#define CAB_FILE_SPLIT 0xFFFE -#define CAB_FILE_PREV_NEXT 0xFFFF - - /* Cabinet structures */ -typedef struct _CFHEADER -{ - ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE) - ULONG Reserved1; // Reserved field - ULONG CabinetSize; // Cabinet file size - ULONG Reserved2; // Reserved field - ULONG FileTableOffset; // Offset of first CFFILE - ULONG Reserved3; // Reserved field - WORD Version; // Cabinet version (CAB_VERSION) - WORD FolderCount; // Number of folders - WORD FileCount; // Number of files - WORD Flags; // Cabinet flags (CAB_FLAG_*) - WORD SetID; // Cabinet set id - WORD CabinetNumber; // Zero-based cabinet number -/* Optional fields (depends on Flags) - WORD CabinetResSize // Per-cabinet reserved area size - CHAR FolderResSize // Per-folder reserved area size - CHAR FileResSize // Per-file reserved area size - CHAR CabinetReserved[] // Per-cabinet reserved area - CHAR CabinetPrev[] // Name of previous cabinet file - CHAR DiskPrev[] // Name of previous disk - CHAR CabinetNext[] // Name of next cabinet file - CHAR DiskNext[] // Name of next disk - */ -} CFHEADER, *PCFHEADER; - - -typedef struct _CFFOLDER -{ - ULONG DataOffset; // Absolute offset of first CFDATA block in this folder - WORD DataBlockCount; // Number of CFDATA blocks in this folder in this cabinet - WORD CompressionType; // Type of compression used for all CFDATA blocks in this folder -/* Optional fields (depends on Flags) - CHAR FolderReserved[] // Per-folder reserved area - */ -} CFFOLDER, *PCFFOLDER; - - -typedef struct _CFFILE -{ - ULONG FileSize; // Uncompressed file size in bytes - ULONG FileOffset; // Uncompressed offset of file in the folder - WORD FolderIndex; // Index number of the folder that contains this file - WORD FileDate; // File date stamp, as used by DOS - WORD FileTime; // File time stamp, as used by DOS - WORD Attributes; // File attributes (CAB_ATTRIB_*) - CHAR FileName[ANYSIZE_ARRAY]; - /* After this is the NULL terminated filename */ -} CFFILE, *PCFFILE; - - -typedef struct _CFDATA -{ - ULONG Checksum; // Checksum of CFDATA entry - WORD CompSize; // Number of compressed bytes in this block - WORD UncompSize; // Number of uncompressed bytes in this block -/* Optional fields (depends on Flags) - CHAR DataReserved[] // Per-datablock reserved area - */ -} CFDATA, *PCFDATA; +// Shadow types, implementation-specific +typedef struct _CFHEADER *PCFHEADER; +typedef struct _CFFOLDER *PCFFOLDER; +typedef struct _CFFILE *PCFFILE; +typedef struct _CFDATA *PCFDATA; -typedef struct _CAB_SEARCH -{ - WCHAR Search[MAX_PATH]; // Search criteria - WCHAR Cabinet[MAX_PATH]; - USHORT Index; - PCFFILE File; // Pointer to current CFFILE - PCFDATA CFData; - ULONG Offset; -} CAB_SEARCH, *PCAB_SEARCH; +struct _CABINET_CONTEXT; /* Constants */ @@ -131,12 +35,7 @@ typedef struct _CAB_SEARCH /* Codecs */ -/* Uncompresses a data block */ -typedef ULONG (*PCABINET_CODEC_UNCOMPRESS)(PVOID OutputBuffer, - PVOID InputBuffer, - PLONG InputLength, - PLONG OutputLength); - +typedef struct _CAB_CODEC *PCAB_CODEC; /* Codec status codes */ #define CS_SUCCESS 0x0000 /* All data consumed */ @@ -148,62 +47,167 @@ typedef ULONG (*PCABINET_CODEC_UNCOMPRESS)(PVOID OutputBuffer, #define CAB_CODEC_LZX 0x01 #define CAB_CODEC_MSZIP 0x02 -#define MSZIP_MAGIC 0x4B43 +/* Event handler prototypes */ +typedef BOOL (*PCABINET_OVERWRITE)( + IN struct _CABINET_CONTEXT* CabinetContext, + IN PCFFILE File, + IN PCWSTR FileName); -/* Event handler prototypes */ +typedef VOID (*PCABINET_EXTRACT)( + IN struct _CABINET_CONTEXT* CabinetContext, + IN PCFFILE File, + IN PCWSTR FileName); -typedef BOOL (*PCABINET_OVERWRITE)(PCFFILE File, - PWCHAR FileName); +typedef VOID (*PCABINET_DISK_CHANGE)( + IN struct _CABINET_CONTEXT* CabinetContext, + IN PCWSTR CabinetName, + IN PCWSTR DiskLabel); -typedef VOID (*PCABINET_EXTRACT)(PCFFILE File, - PWCHAR FileName); -typedef VOID (*PCABINET_DISK_CHANGE)(PWCHAR CabinetName, - PWCHAR DiskLabel); +/* Classes */ +typedef struct _CAB_SEARCH +{ + WCHAR Search[MAX_PATH]; // Search criteria + WCHAR Cabinet[MAX_PATH]; + USHORT Index; + PCFFILE File; // Pointer to current CFFILE + PCFDATA CFData; + ULONG Offset; +} CAB_SEARCH, *PCAB_SEARCH; +typedef struct _CABINET_CONTEXT +{ + WCHAR CabinetName[256]; // Filename of current cabinet + WCHAR CabinetPrev[256]; // Filename of previous cabinet + WCHAR DiskPrev[256]; // Label of cabinet in file CabinetPrev + WCHAR CabinetNext[256]; // Filename of next cabinet + WCHAR DiskNext[256]; // Label of cabinet in file CabinetNext + ULONG FolderUncompSize; // Uncompressed size of folder + ULONG BytesLeftInBlock; // Number of bytes left in current block + WCHAR DestPath[MAX_PATH]; + HANDLE FileHandle; + HANDLE FileSectionHandle; + PUCHAR FileBuffer; + SIZE_T DestFileSize; + SIZE_T FileSize; + BOOL FileOpen; + PCFHEADER PCABHeader; + PCFFOLDER CabinetFolders; + ULONG CabinetReserved; + ULONG FolderReserved; + ULONG DataReserved; + PCAB_CODEC Codec; + ULONG CodecId; + BOOL CodecSelected; + ULONG LastFileOffset; // Uncompressed offset of last extracted file + PCABINET_OVERWRITE OverwriteHandler; + PCABINET_EXTRACT ExtractHandler; + PCABINET_DISK_CHANGE DiskChangeHandler; + PVOID CabinetReservedArea; +} CABINET_CONTEXT, *PCABINET_CONTEXT; -/* Classes */ /* Default constructor */ -VOID CabinetInitialize(VOID); +VOID +CabinetInitialize( + IN OUT PCABINET_CONTEXT CabinetContext); + /* Default destructor */ -VOID CabinetCleanup(VOID); +VOID +CabinetCleanup( + IN OUT PCABINET_CONTEXT CabinetContext); + +#if 0 /* Returns a pointer to the filename part of a fully qualified filename */ PWCHAR CabinetGetFileName(PWCHAR Path); /* Removes a filename from a fully qualified filename */ VOID CabinetRemoveFileName(PWCHAR Path); /* Normalizes a path */ BOOL CabinetNormalizePath(PWCHAR Path, ULONG Length); +#endif + /* Returns name of cabinet file */ -PWCHAR CabinetGetCabinetName(VOID); +PCWSTR +CabinetGetCabinetName( + IN PCABINET_CONTEXT CabinetContext); + /* Sets the name of the cabinet file */ -VOID CabinetSetCabinetName(PWCHAR FileName); +VOID +CabinetSetCabinetName( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR FileName); + /* Sets destination path for extracted files */ -VOID CabinetSetDestinationPath(PWCHAR DestinationPath); +VOID +CabinetSetDestinationPath( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR DestinationPath); + /* Returns destination path */ -PWCHAR CabinetGetDestinationPath(VOID); +PCWSTR +CabinetGetDestinationPath( + IN PCABINET_CONTEXT CabinetContext); + +#if 0 /* Returns zero-based current disk number */ ULONG CabinetGetCurrentDiskNumber(VOID); +#endif + /* Opens the current cabinet file */ -ULONG CabinetOpen(VOID); +ULONG +CabinetOpen( + IN OUT PCABINET_CONTEXT CabinetContext); + /* Closes the current open cabinet file */ -VOID CabinetClose(VOID); +VOID +CabinetClose( + IN OUT PCABINET_CONTEXT CabinetContext); + /* Locates the first file in the current cabinet file that matches a search criteria */ -ULONG CabinetFindFirst(PWCHAR FileName, PCAB_SEARCH Search); +ULONG +CabinetFindFirst( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR FileName, + IN OUT PCAB_SEARCH Search); + /* Locates the next file that matches the current search criteria */ -ULONG CabinetFindNext(PCAB_SEARCH Search); +ULONG +CabinetFindNext( + IN PCABINET_CONTEXT CabinetContext, + IN OUT PCAB_SEARCH Search); + /* Locates the next file in the current cabinet file sequentially */ -ULONG CabinetFindNextFileSequential(PWCHAR FileName, PCAB_SEARCH Search); +ULONG +CabinetFindNextFileSequential( + IN PCABINET_CONTEXT CabinetContext, + IN PCWSTR FileName, + IN OUT PCAB_SEARCH Search); + /* Extracts a file from the current cabinet file */ -ULONG CabinetExtractFile(PCAB_SEARCH Search); +ULONG +CabinetExtractFile( + IN PCABINET_CONTEXT CabinetContext, + IN PCAB_SEARCH Search); + /* Select codec engine to use */ -VOID CabinetSelectCodec(ULONG Id); +VOID +CabinetSelectCodec( + IN PCABINET_CONTEXT CabinetContext, + IN ULONG Id); + /* Set event handlers */ -VOID CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite, - PCABINET_EXTRACT Extract, - PCABINET_DISK_CHANGE DiskChange); +VOID +CabinetSetEventHandlers( + IN PCABINET_CONTEXT CabinetContext, + IN PCABINET_OVERWRITE Overwrite, + IN PCABINET_EXTRACT Extract, + IN PCABINET_DISK_CHANGE DiskChange); + /* Get pointer to cabinet reserved area. NULL if none */ -PVOID CabinetGetCabinetReservedArea(PULONG Size); +PVOID +CabinetGetCabinetReservedArea( + IN PCABINET_CONTEXT CabinetContext, + OUT PULONG Size); diff --git a/base/setup/usetup/filequeue.c b/base/setup/usetup/filequeue.c index b49e56e9ba..bb1f71218c 100644 --- a/base/setup/usetup/filequeue.c +++ b/base/setup/usetup/filequeue.c @@ -60,6 +60,22 @@ static BOOLEAN HasCurrentCabinet = FALSE; static WCHAR CurrentCabinetName[MAX_PATH]; static CAB_SEARCH Search; +// HACK: Temporary compatibility code. +#if 1 + static CABINET_CONTEXT CabinetContext; + #define CabinetInitialize() (CabinetInitialize(&CabinetContext)) + #define CabinetSetEventHandlers(a,b,c) (CabinetSetEventHandlers(&CabinetContext,(a),(b),(c))) + #define CabinetSetCabinetName(a) (CabinetSetCabinetName(&CabinetContext,(a))) + #define CabinetOpen() (CabinetOpen(&CabinetContext)) + #define CabinetGetCabinetName() (CabinetGetCabinetName(&CabinetContext)) + #define CabinetGetCabinetReservedArea(a) (CabinetGetCabinetReservedArea(&CabinetContext,(a))) + #define CabinetFindNextFileSequential(a,b) (CabinetFindNextFileSequential(&CabinetContext,(a),(b))) + #define CabinetFindFirst(a,b) (CabinetFindFirst(&CabinetContext,(a),(b))) + #define CabinetSetDestinationPath(a) (CabinetSetDestinationPath(&CabinetContext,(a))) + #define CabinetExtractFile(a) (CabinetExtractFile(&CabinetContext,(a))) + #define CabinetCleanup() (CabinetCleanup(&CabinetContext)) +#endif + NTSTATUS SetupExtractFile( PWCHAR CabinetFileName, diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index b544e207b3..edd98fd654 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -69,6 +69,19 @@ static PNTOS_INSTALLATION CurrentInstallation = NULL; static PGENERIC_LIST NtOsInstallsList = NULL; +// HACK: Temporary compatibility code. +#if 1 + static CABINET_CONTEXT CabinetContext; + #define CabinetInitialize() (CabinetInitialize(&CabinetContext)) + #define CabinetSetEventHandlers(a,b,c) (CabinetSetEventHandlers(&CabinetContext,(a),(b),(c))) + #define CabinetSetCabinetName(a) (CabinetSetCabinetName(&CabinetContext,(a))) + #define CabinetOpen() (CabinetOpen(&CabinetContext)) + #define CabinetGetCabinetName() (CabinetGetCabinetName(&CabinetContext)) + #define CabinetGetCabinetReservedArea(a) (CabinetGetCabinetReservedArea(&CabinetContext,(a))) + #define CabinetCleanup() (CabinetCleanup(&CabinetContext)) +#endif + + /* FUNCTIONS ****************************************************************/ static VOID
6 years, 1 month
1
0
0
0
02/02: [SETUPLIB][REACTOS][USETUP] Re-organize the setup state variables and some helpers.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1a173dfdb2dd25288a1f3…
commit 1a173dfdb2dd25288a1f396848ee01583d8dadd4 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Fri Jan 5 02:51:51 2018 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 28 23:40:28 2018 +0100 [SETUPLIB][REACTOS][USETUP] Re-organize the setup state variables and some helpers. - Move a great deal of global variables into the USETUP_DATA structure (the SetupInf, the SetupFileQueue, the generic lists...). - Place the common setup initialization code into an InitializeSetup() routine, and the cleanup code into FinishSetup(). - Implement the setup-code part support for the TXTSETUP.SIF setup source path override variables "SetupSourceDevice" and "SetupSourcePath" (see CORE-9023); support for them in SETUPLDR will be added later. --- base/setup/lib/setuplib.c | 227 +++++++++++++++++++++++++++++++++++-- base/setup/lib/setuplib.h | 41 ++++++- base/setup/reactos/drivepage.c | 2 +- base/setup/reactos/reactos.c | 75 +++++-------- base/setup/reactos/reactos.h | 22 ++-- base/setup/usetup/usetup.c | 248 +++++++++++++---------------------------- 6 files changed, 365 insertions(+), 250 deletions(-) diff --git a/base/setup/lib/setuplib.c b/base/setup/lib/setuplib.c index 5bd9fa4f03..cb48fd3fa3 100644 --- a/base/setup/lib/setuplib.c +++ b/base/setup/lib/setuplib.c @@ -500,7 +500,6 @@ InitPaths: ERROR_NUMBER LoadSetupInf( - OUT HINF* SetupInf, IN OUT PUSETUP_DATA pSetupData) { INFCONTEXT Context; @@ -514,17 +513,18 @@ LoadSetupInf( DPRINT("SetupInf path: '%S'\n", FileNameBuffer); - *SetupInf = SetupOpenInfFileExW(FileNameBuffer, - NULL, - /* INF_STYLE_WIN4 | */ INF_STYLE_OLDNT, - pSetupData->LanguageId, - &ErrorLine); + pSetupData->SetupInf = + SetupOpenInfFileExW(FileNameBuffer, + NULL, + /* INF_STYLE_WIN4 | */ INF_STYLE_OLDNT, + pSetupData->LanguageId, + &ErrorLine); - if (*SetupInf == INVALID_HANDLE_VALUE) + if (pSetupData->SetupInf == INVALID_HANDLE_VALUE) return ERROR_LOAD_TXTSETUPSIF; /* Open 'Version' section */ - if (!SetupFindFirstLineW(*SetupInf, L"Version", L"Signature", &Context)) + if (!SetupFindFirstLineW(pSetupData->SetupInf, L"Version", L"Signature", &Context)) return ERROR_CORRUPT_TXTSETUPSIF; /* Get pointer 'Signature' key */ @@ -541,7 +541,7 @@ LoadSetupInf( INF_FreeData(Value); /* Open 'DiskSpaceRequirements' section */ - if (!SetupFindFirstLineW(*SetupInf, L"DiskSpaceRequirements", L"FreeSysPartDiskSpace", &Context)) + if (!SetupFindFirstLineW(pSetupData->SetupInf, L"DiskSpaceRequirements", L"FreeSysPartDiskSpace", &Context)) return ERROR_CORRUPT_TXTSETUPSIF; pSetupData->RequiredPartitionDiskSpace = ~0; @@ -553,12 +553,48 @@ LoadSetupInf( pSetupData->RequiredPartitionDiskSpace = (ULONG)IntValue; // - // TODO: Support "SetupSourceDevice" and "SetupSourcePath" in txtsetup.sif + // Support "SetupSourceDevice" and "SetupSourcePath" in txtsetup.sif // See CORE-9023 + // Support for that should also be added in setupldr. // + /* Update the Setup Source paths */ + if (SetupFindFirstLineW(pSetupData->SetupInf, L"SetupData", L"SetupSourceDevice", &Context)) + { + /* + * Get optional pointer 'SetupSourceDevice' key, its presence + * will dictate whether we also need 'SetupSourcePath'. + */ + if (INF_GetData(&Context, NULL, &Value)) + { + /* Free the old source root path string and create the new one */ + RtlFreeUnicodeString(&pSetupData->SourceRootPath); + RtlCreateUnicodeString(&pSetupData->SourceRootPath, Value); + INF_FreeData(Value); + + if (!SetupFindFirstLineW(pSetupData->SetupInf, L"SetupData", L"SetupSourcePath", &Context)) + { + /* The 'SetupSourcePath' value is mandatory! */ + return ERROR_CORRUPT_TXTSETUPSIF; + } + + /* Get pointer 'SetupSourcePath' key */ + if (!INF_GetData(&Context, NULL, &Value)) + { + /* The 'SetupSourcePath' value is mandatory! */ + return ERROR_CORRUPT_TXTSETUPSIF; + } + + /* Free the old source path string and create the new one */ + RtlFreeUnicodeString(&pSetupData->SourceRootDir); + RtlCreateUnicodeString(&pSetupData->SourceRootDir, Value); + INF_FreeData(Value); + } + } + /* Search for 'DefaultPath' in the 'SetupData' section */ - if (SetupFindFirstLineW(*SetupInf, L"SetupData", L"DefaultPath", &Context)) + pSetupData->InstallationDirectory[0] = 0; + if (SetupFindFirstLineW(pSetupData->SetupInf, L"SetupData", L"DefaultPath", &Context)) { /* Get pointer 'DefaultPath' key */ if (!INF_GetData(&Context, NULL, &Value)) @@ -574,6 +610,175 @@ LoadSetupInf( return ERROR_SUCCESS; } +NTSTATUS +InitDestinationPaths( + IN OUT PUSETUP_DATA pSetupData, + IN PCWSTR InstallationDir, + IN PDISKENTRY DiskEntry, // FIXME: HACK! + IN PPARTENTRY PartEntry) // FIXME: HACK! +{ + WCHAR PathBuffer[MAX_PATH]; + + // + // TODO: Check return status values of the functions! + // + + /* Create 'pSetupData->DestinationRootPath' string */ + RtlFreeUnicodeString(&pSetupData->DestinationRootPath); + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\\Device\\Harddisk%lu\\Partition%lu\\", + DiskEntry->DiskNumber, + PartEntry->PartitionNumber); + RtlCreateUnicodeString(&pSetupData->DestinationRootPath, PathBuffer); + DPRINT("DestinationRootPath: %wZ\n", &pSetupData->DestinationRootPath); + +/** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/ + /* Create 'pSetupData->DestinationArcPath' */ + RtlFreeUnicodeString(&pSetupData->DestinationArcPath); + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\", + DiskEntry->BiosDiskNumber, + PartEntry->PartitionNumber); + ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallationDir); + RtlCreateUnicodeString(&pSetupData->DestinationArcPath, PathBuffer); + +/** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/ + /* Create 'pSetupData->DestinationPath' string */ + RtlFreeUnicodeString(&pSetupData->DestinationPath); + CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, + pSetupData->DestinationRootPath.Buffer, InstallationDir); + RtlCreateUnicodeString(&pSetupData->DestinationPath, PathBuffer); + +/** Equivalent of 'NTOS_INSTALLATION::PathComponent' **/ + // FIXME: This is only temporary!! Must be removed later! + /***/RtlCreateUnicodeString(&pSetupData->InstallPath, InstallationDir);/***/ + + return STATUS_SUCCESS; +} + +// NTSTATUS +ERROR_NUMBER +InitializeSetup( + IN OUT PUSETUP_DATA pSetupData, + IN ULONG InitPhase) +{ + if (InitPhase == 0) + { + RtlZeroMemory(pSetupData, sizeof(*pSetupData)); + + // pSetupData->ComputerList = NULL; + // pSetupData->DisplayList = NULL; + // pSetupData->KeyboardList = NULL; + // pSetupData->LayoutList = NULL; + // pSetupData->LanguageList = NULL; + + /* Initialize global unicode strings */ + RtlInitUnicodeString(&pSetupData->SourcePath, NULL); + RtlInitUnicodeString(&pSetupData->SourceRootPath, NULL); + RtlInitUnicodeString(&pSetupData->SourceRootDir, NULL); + RtlInitUnicodeString(&pSetupData->DestinationArcPath, NULL); + RtlInitUnicodeString(&pSetupData->DestinationPath, NULL); + RtlInitUnicodeString(&pSetupData->DestinationRootPath, NULL); + RtlInitUnicodeString(&pSetupData->SystemRootPath, NULL); + + // FIXME: This is only temporary!! Must be removed later! + /***/RtlInitUnicodeString(&pSetupData->InstallPath, NULL);/***/ + + // + // TODO: Load and start SetupDD, and ask it for the information + // + + return ERROR_SUCCESS; + } + else + if (InitPhase == 1) + { + ERROR_NUMBER Error; + NTSTATUS Status; + + /* Get the source path and source root path */ + // + // NOTE: Sometimes the source path may not be in SystemRoot !! + // (and this is the case when using the 1st-stage GUI setup!) + // + Status = GetSourcePaths(&pSetupData->SourcePath, + &pSetupData->SourceRootPath, + &pSetupData->SourceRootDir); + if (!NT_SUCCESS(Status)) + { + DPRINT1("GetSourcePaths() failed (Status 0x%08lx)", Status); + return ERROR_NO_SOURCE_DRIVE; + } + /* + * Example of output: + * SourcePath: '\Device\CdRom0\I386' + * SourceRootPath: '\Device\CdRom0' + * SourceRootDir: '\I386' + */ + DPRINT1("SourcePath (1): '%wZ'\n", &pSetupData->SourcePath); + DPRINT1("SourceRootPath (1): '%wZ'\n", &pSetupData->SourceRootPath); + DPRINT1("SourceRootDir (1): '%wZ'\n", &pSetupData->SourceRootDir); + + /* Load 'txtsetup.sif' from the installation media */ + Error = LoadSetupInf(pSetupData); + if (Error != ERROR_SUCCESS) + { + DPRINT1("LoadSetupInf() failed (Error 0x%lx)", Error); + return Error; + } + DPRINT1("SourcePath (2): '%wZ'\n", &pSetupData->SourcePath); + DPRINT1("SourceRootPath (2): '%wZ'\n", &pSetupData->SourceRootPath); + DPRINT1("SourceRootDir (2): '%wZ'\n", &pSetupData->SourceRootDir); + + return ERROR_SUCCESS; + } + + return ERROR_SUCCESS; +} + +VOID +FinishSetup( + IN OUT PUSETUP_DATA pSetupData) +{ + /* Destroy the computer settings list */ + if (pSetupData->ComputerList != NULL) + { + DestroyGenericList(pSetupData->ComputerList, TRUE); + pSetupData->ComputerList = NULL; + } + + /* Destroy the display settings list */ + if (pSetupData->DisplayList != NULL) + { + DestroyGenericList(pSetupData->DisplayList, TRUE); + pSetupData->DisplayList = NULL; + } + + /* Destroy the keyboard settings list */ + if (pSetupData->KeyboardList != NULL) + { + DestroyGenericList(pSetupData->KeyboardList, TRUE); + pSetupData->KeyboardList = NULL; + } + + /* Destroy the keyboard layout list */ + if (pSetupData->LayoutList != NULL) + { + DestroyGenericList(pSetupData->LayoutList, TRUE); + pSetupData->LayoutList = NULL; + } + + /* Destroy the languages list */ + if (pSetupData->LanguageList != NULL) + { + DestroyGenericList(pSetupData->LanguageList, FALSE); + pSetupData->LanguageList = NULL; + } + + /* Close the Setup INF */ + SetupCloseInfFile(pSetupData->SetupInf); +} + /* * SIDEEFFECTS * Calls RegInitializeRegistry diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h index 46c42f72a7..a885d6d09d 100644 --- a/base/setup/lib/setuplib.h +++ b/base/setup/lib/setuplib.h @@ -55,8 +55,16 @@ extern HANDLE ProcessHeap; /* TYPEDEFS *****************************************************************/ +struct _USETUP_DATA; + typedef struct _USETUP_DATA { +/* Setup INFs *****/ + HINF SetupInf; + +/* Installation *****/ + PVOID SetupFileQueue; // HSPFILEQ + /* SOURCE Paths *****/ UNICODE_STRING SourceRootPath; UNICODE_STRING SourceRootDir; @@ -79,17 +87,28 @@ typedef struct _USETUP_DATA UNICODE_STRING SystemRootPath; /* Path to the installation directory inside the ReactOS boot partition */ - UNICODE_STRING DestinationPath; /** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/ UNICODE_STRING DestinationArcPath; /** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/ + UNICODE_STRING DestinationPath; /** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/ UNICODE_STRING DestinationRootPath; + // FIXME: This is only temporary!! Must be removed later! + UNICODE_STRING InstallPath; + LONG DestinationDiskNumber; LONG DestinationPartitionNumber; - LONG MBRInstallType; + LONG MBRInstallType; LONG FormatPartition; LONG AutoPartition; +/* Settings lists *****/ + PGENERIC_LIST ComputerList; + PGENERIC_LIST DisplayList; + PGENERIC_LIST KeyboardList; + PGENERIC_LIST LayoutList; + PGENERIC_LIST LanguageList; + +/* Other stuff *****/ WCHAR LocaleID[9]; LANGID LanguageId; @@ -119,7 +138,23 @@ GetSourcePaths( ERROR_NUMBER LoadSetupInf( - OUT HINF* SetupInf, + IN OUT PUSETUP_DATA pSetupData); + +NTSTATUS +InitDestinationPaths( + IN OUT PUSETUP_DATA pSetupData, + IN PCWSTR InstallationDir, + IN PDISKENTRY DiskEntry, // FIXME: HACK! + IN PPARTENTRY PartEntry); // FIXME: HACK! + +// NTSTATUS +ERROR_NUMBER +InitializeSetup( + IN OUT PUSETUP_DATA pSetupData, + IN ULONG InitPhase); + +VOID +FinishSetup( IN OUT PUSETUP_DATA pSetupData); diff --git a/base/setup/reactos/drivepage.c b/base/setup/reactos/drivepage.c index b8bc07f3ce..b58557cf1e 100644 --- a/base/setup/reactos/drivepage.c +++ b/base/setup/reactos/drivepage.c @@ -70,7 +70,7 @@ MoreOptDlgProc(HWND hwndDlg, case IDOK: SendMessage(GetDlgItem(hwndDlg, IDC_PATH), WM_GETTEXT, - (WPARAM)sizeof(pSetupData->USetupData.InstallationDirectory) / sizeof(TCHAR), + (WPARAM)ARRAYSIZE(pSetupData->USetupData.InstallationDirectory), (LPARAM)pSetupData->USetupData.InstallationDirectory); EndDialog(hwndDlg, IDOK); diff --git a/base/setup/reactos/reactos.c b/base/setup/reactos/reactos.c index 7bc0581b9c..261d5b2d4b 100644 --- a/base/setup/reactos/reactos.c +++ b/base/setup/reactos/reactos.c @@ -555,16 +555,16 @@ DeviceDlgProc( SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData); hList = GetDlgItem(hwndDlg, IDC_COMPUTER); - InitGenericComboList(hList, pSetupData->ComputerList, GetSettingDescription); + InitGenericComboList(hList, pSetupData->USetupData.ComputerList, GetSettingDescription); hList = GetDlgItem(hwndDlg, IDC_DISPLAY); - InitGenericComboList(hList, pSetupData->DisplayList, GetSettingDescription); + InitGenericComboList(hList, pSetupData->USetupData.DisplayList, GetSettingDescription); hList = GetDlgItem(hwndDlg, IDC_KEYBOARD); - InitGenericComboList(hList, pSetupData->KeyboardList, GetSettingDescription); + InitGenericComboList(hList, pSetupData->USetupData.KeyboardList, GetSettingDescription); // hList = GetDlgItem(hwndDlg, IDC_KEYBOARD_LAYOUT); - // InitGenericComboList(hList, pSetupData->LayoutList, GetSettingDescription); + // InitGenericComboList(hList, pSetupData->USetupData.LayoutList, GetSettingDescription); break; } @@ -808,11 +808,11 @@ BOOL LoadSetupData( /* Load the hardware, language and keyboard layout lists */ - pSetupData->ComputerList = CreateComputerTypeList(pSetupData->SetupInf); - pSetupData->DisplayList = CreateDisplayDriverList(pSetupData->SetupInf); - pSetupData->KeyboardList = CreateKeyboardDriverList(pSetupData->SetupInf); + pSetupData->USetupData.ComputerList = CreateComputerTypeList(pSetupData->USetupData.SetupInf); + pSetupData->USetupData.DisplayList = CreateDisplayDriverList(pSetupData->USetupData.SetupInf); + pSetupData->USetupData.KeyboardList = CreateKeyboardDriverList(pSetupData->USetupData.SetupInf); - pSetupData->LanguageList = CreateLanguageList(pSetupData->SetupInf, pSetupData->DefaultLanguage); + pSetupData->USetupData.LanguageList = CreateLanguageList(pSetupData->USetupData.SetupInf, pSetupData->DefaultLanguage); pSetupData->PartitionList = CreatePartitionList(); @@ -826,7 +826,7 @@ BOOL LoadSetupData( wcscpy(pSetupData->DefaultLanguage, pSetupData->USetupData.LocaleID); pSetupData->USetupData.LanguageId = (LANGID)(wcstol(pSetupData->SelectedLanguageId, NULL, 16) & 0xFFFF); - pSetupData->LayoutList = CreateKeyboardLayoutList(pSetupData->SetupInf, pSetupData->SelectedLanguageId, pSetupData->DefaultKBLayout); + pSetupData->USetupData.LayoutList = CreateKeyboardLayoutList(pSetupData->USetupData.SetupInf, pSetupData->SelectedLanguageId, pSetupData->DefaultKBLayout); #if 0 // get default for keyboard and language @@ -834,7 +834,7 @@ BOOL LoadSetupData( pSetupData->DefaultLang = -1; // TODO: get defaults from underlaying running system - if (SetupFindFirstLine(pSetupData->SetupInf, _T("NLS"), _T("DefaultLayout"), &InfContext)) + if (SetupFindFirstLine(pSetupData->USetupData.SetupInf, _T("NLS"), _T("DefaultLayout"), &InfContext)) { SetupGetStringField(&InfContext, 1, tmp, ARRAYSIZE(tmp), &LineLength); for (Count = 0; Count < pSetupData->KbLayoutCount; Count++) @@ -847,7 +847,7 @@ BOOL LoadSetupData( } } - if (SetupFindFirstLine(pSetupData->SetupInf, _T("NLS"), _T("DefaultLanguage"), &InfContext)) + if (SetupFindFirstLine(pSetupData->USetupData.SetupInf, _T("NLS"), _T("DefaultLanguage"), &InfContext)) { SetupGetStringField(&InfContext, 1, tmp, ARRAYSIZE(tmp), &LineLength); for (Count = 0; Count < pSetupData->LangCount; Count++) @@ -948,7 +948,6 @@ _tWinMain(HINSTANCE hInst, LPTSTR lpszCmdLine, int nCmdShow) { - NTSTATUS Status; ULONG Error; INITCOMMONCONTROLSEX iccx; PROPSHEETHEADER psh; @@ -958,41 +957,23 @@ _tWinMain(HINSTANCE hInst, ProcessHeap = GetProcessHeap(); - /* Initialize global unicode strings */ - RtlInitUnicodeString(&SetupData.USetupData.SourcePath, NULL); - RtlInitUnicodeString(&SetupData.USetupData.SourceRootPath, NULL); - RtlInitUnicodeString(&SetupData.USetupData.SourceRootDir, NULL); - // RtlInitUnicodeString(&InstallPath, NULL); - RtlInitUnicodeString(&SetupData.USetupData.DestinationPath, NULL); - RtlInitUnicodeString(&SetupData.USetupData.DestinationArcPath, NULL); - RtlInitUnicodeString(&SetupData.USetupData.DestinationRootPath, NULL); - RtlInitUnicodeString(&SetupData.USetupData.SystemRootPath, NULL); - - /* Get the source path and source root path */ - // - // NOTE: Sometimes the source path may not be in SystemRoot !! - // (and this is the case when using the 1st-stage GUI setup!) - // - Status = GetSourcePaths(&SetupData.USetupData.SourcePath, - &SetupData.USetupData.SourceRootPath, - &SetupData.USetupData.SourceRootDir); - if (!NT_SUCCESS(Status)) - { - DPRINT1("GetSourcePaths() failed (Status 0x%08lx)", Status); - // MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER); - MessageBoxW(NULL, L"GetSourcePaths failed!", L"Error", MB_ICONERROR); - goto Quit; - } - DPRINT1("SourcePath: '%wZ'\n", &SetupData.USetupData.SourcePath); - DPRINT1("SourceRootPath: '%wZ'\n", &SetupData.USetupData.SourceRootPath); - DPRINT1("SourceRootDir: '%wZ'\n", &SetupData.USetupData.SourceRootDir); + /* Initialize Setup, phase 0 */ + InitializeSetup(&SetupData.USetupData, 0); - /* Load 'txtsetup.sif' from the installation media */ - Error = LoadSetupInf(&SetupData.SetupInf, &SetupData.USetupData); + /* Initialize Setup, phase 1 */ + Error = InitializeSetup(&SetupData.USetupData, 1); if (Error != ERROR_SUCCESS) { - // MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER); - DisplayError(NULL, IDS_CAPTION, IDS_NO_TXTSETUP_SIF); + // + // TODO: Write an error mapper (much like the MUIDisplayError of USETUP) + // + if (Error == ERROR_NO_SOURCE_DRIVE) + MessageBoxW(NULL, L"GetSourcePaths failed!", L"Error", MB_ICONERROR); + else if (Error == ERROR_LOAD_TXTSETUPSIF) + DisplayError(NULL, IDS_CAPTION, IDS_NO_TXTSETUP_SIF); + else // FIXME!! + MessageBoxW(NULL, L"Unknown error!", L"Error", MB_ICONERROR); + goto Quit; } @@ -1003,7 +984,7 @@ _tWinMain(HINSTANCE hInst, SetupData.hInstance = hInst; CheckUnattendedSetup(&SetupData.USetupData); - SetupData.bUnattend = IsUnattendedSetup; + SetupData.bUnattend = IsUnattendedSetup; // FIXME :-) /* Cache commonly-used strings */ LoadStringW(hInst, IDS_ABORTSETUP, SetupData.szAbortMessage, ARRAYSIZE(SetupData.szAbortMessage)); @@ -1124,9 +1105,9 @@ _tWinMain(HINSTANCE hInst, if (SetupData.hTitleFont) DeleteObject(SetupData.hTitleFont); - SetupCloseInfFile(SetupData.SetupInf); - Quit: + /* Setup has finished */ + FinishSetup(&SetupData.USetupData); #if 0 // NOTE: Disabled for testing purposes only! EnablePrivilege(SE_SHUTDOWN_NAME, TRUE); diff --git a/base/setup/reactos/reactos.h b/base/setup/reactos/reactos.h index 760b62708a..508d9652c0 100644 --- a/base/setup/reactos/reactos.h +++ b/base/setup/reactos/reactos.h @@ -55,7 +55,6 @@ /* Setup library headers */ // #include <reactos/rosioctl.h> #include <../lib/setuplib.h> -// #include "errorcode.h" #if 0 typedef struct _KBLAYOUT @@ -79,7 +78,13 @@ typedef struct _SETUPDATA TCHAR szAbortTitle[64]; USETUP_DATA USetupData; - HINF SetupInf; + + BOOLEAN RepairUpdateFlag; // flag for update/repair an installed reactos + + PPARTLIST PartitionList; + PNTOS_INSTALLATION CurrentInstallation; + PGENERIC_LIST NtOsInstallsList; + /* Settings */ LONG DestPartSize; // if partition doesn't exist, size of partition @@ -92,9 +97,6 @@ typedef struct _SETUPDATA LONG SelectedDisplay; // selected display type (table index) LONG SelectedKeyboard; // selected keyboard type (table index) - BOOLEAN RepairUpdateFlag; // flag for update/repair an installed reactos - - /* txtsetup.sif data */ // LONG DefaultLang; // default language (table index) // LONG DefaultKBLayout; // default keyboard layout (table index) @@ -102,16 +104,6 @@ typedef struct _SETUPDATA WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList - PGENERIC_LIST ComputerList; - PGENERIC_LIST DisplayList; - PGENERIC_LIST KeyboardList; - PGENERIC_LIST LayoutList; - PGENERIC_LIST LanguageList; - - PPARTLIST PartitionList; - PNTOS_INSTALLATION CurrentInstallation; - PGENERIC_LIST NtOsInstallsList; - } SETUPDATA, *PSETUPDATA; extern HANDLE ProcessHeap; diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 1461528b88..b544e207b3 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -40,15 +40,9 @@ /* GLOBALS & LOCALS *********************************************************/ HANDLE ProcessHeap; - BOOLEAN IsUnattendedSetup = FALSE; -static USETUP_DATA USetupData; -/* - * NOTE: Technically only used for the COPYCONTEXT InstallPath member - * for the filequeue functionality. - */ -static UNICODE_STRING InstallPath; +static USETUP_DATA USetupData; // FIXME: Is it really useful?? Just used for SetDefaultPagefile... static WCHAR DestinationDriveLetter; @@ -71,19 +65,9 @@ static FORMATMACHINESTATE FormatState = Start; /*****************************************************/ -static HINF SetupInf; - -static HSPFILEQ SetupFileQueue = NULL; - static PNTOS_INSTALLATION CurrentInstallation = NULL; static PGENERIC_LIST NtOsInstallsList = NULL; -static PGENERIC_LIST ComputerList = NULL; -static PGENERIC_LIST DisplayList = NULL; -static PGENERIC_LIST KeyboardList = NULL; -static PGENERIC_LIST LayoutList = NULL; -static PGENERIC_LIST LanguageList = NULL; - /* FUNCTIONS ****************************************************************/ @@ -404,10 +388,10 @@ UpdateKBLayout(VOID) pszNewLayout = MUIDefaultKeyboardLayout(SelectedLanguageId); - if (LayoutList == NULL) + if (USetupData.LayoutList == NULL) { - LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout); - if (LayoutList == NULL) + USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout); + if (USetupData.LayoutList == NULL) { /* FIXME: Handle error! */ return; @@ -417,12 +401,12 @@ UpdateKBLayout(VOID) /* Search for default layout (if provided) */ if (pszNewLayout != NULL) { - for (ListEntry = GetFirstListEntry(LayoutList); ListEntry; + for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry; ListEntry = GetNextListEntry(ListEntry)) { if (!wcscmp(pszNewLayout, ((PGENENTRY)GetListEntryData(ListEntry))->Id)) { - SetCurrentListEntry(LayoutList, ListEntry); + SetCurrentListEntry(USetupData.LayoutList, ListEntry); break; } } @@ -491,10 +475,10 @@ LanguagePage(PINPUT_RECORD Ir) BOOL RefreshPage = FALSE; /* Initialize the computer settings list */ - if (LanguageList == NULL) + if (USetupData.LanguageList == NULL) { - LanguageList = CreateLanguageList(SetupInf, DefaultLanguage); - if (LanguageList == NULL) + USetupData.LanguageList = CreateLanguageList(USetupData.SetupInf, DefaultLanguage); + if (USetupData.LanguageList == NULL) { PopupError("Setup failed to initialize available translations", NULL, NULL, POPUP_WAIT_NONE); return WELCOME_PAGE; @@ -512,13 +496,13 @@ LanguagePage(PINPUT_RECORD Ir) * If there is no language or just a single one in the list, * skip the language selection process altogether. */ - if (GetNumberOfListEntries(LanguageList) <= 1) + if (GetNumberOfListEntries(USetupData.LanguageList) <= 1) { USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); return WELCOME_PAGE; } - InitGenericListUi(&ListUi, LanguageList, GetSettingDescription); + InitGenericListUi(&ListUi, USetupData.LanguageList, GetSettingDescription); DrawGenericList(&ListUi, 2, 18, xScreen - 3, @@ -566,10 +550,10 @@ LanguagePage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - ASSERT(GetNumberOfListEntries(LanguageList) >= 1); + ASSERT(GetNumberOfListEntries(USetupData.LanguageList) >= 1); SelectedLanguageId = - ((PGENENTRY)GetListEntryData(GetCurrentListEntry(LanguageList)))->Id; + ((PGENENTRY)GetListEntryData(GetCurrentListEntry(USetupData.LanguageList)))->Id; USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); @@ -592,10 +576,10 @@ LanguagePage(PINPUT_RECORD Ir) if (RefreshPage) { - ASSERT(GetNumberOfListEntries(LanguageList) >= 1); + ASSERT(GetNumberOfListEntries(USetupData.LanguageList) >= 1); NewLanguageId = - ((PGENENTRY)GetListEntryData(GetCurrentListEntry(LanguageList)))->Id; + ((PGENENTRY)GetListEntryData(GetCurrentListEntry(USetupData.LanguageList)))->Id; if (wcscmp(SelectedLanguageId, NewLanguageId)) { @@ -632,7 +616,7 @@ LanguagePage(PINPUT_RECORD Ir) * Init USetupData.SourcePath * Init USetupData.SourceRootPath * Init USetupData.SourceRootDir - * Init SetupInf + * Init USetupData.SetupInf * Init USetupData.RequiredPartitionDiskSpace * Init IsUnattendedSetup * If unattended, init *List and sets the Codepage @@ -645,29 +629,14 @@ LanguagePage(PINPUT_RECORD Ir) static PAGE_NUMBER SetupStartPage(PINPUT_RECORD Ir) { - NTSTATUS Status; ULONG Error; PGENERIC_LIST_ENTRY ListEntry; PCWSTR LocaleId; CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); - /* Get the source path and source root path */ - Status = GetSourcePaths(&USetupData.SourcePath, - &USetupData.SourceRootPath, - &USetupData.SourceRootDir); - if (!NT_SUCCESS(Status)) - { - CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status); - MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - DPRINT1("SourcePath: '%wZ'\n", &USetupData.SourcePath); - DPRINT1("SourceRootPath: '%wZ'\n", &USetupData.SourceRootPath); - DPRINT1("SourceRootDir: '%wZ'\n", &USetupData.SourceRootDir); - - /* Load 'txtsetup.sif' from the installation media */ - Error = LoadSetupInf(&SetupInf, &USetupData); + /* Initialize Setup, phase 1 */ + Error = InitializeSetup(&USetupData, 1); if (Error != ERROR_SUCCESS) { MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER); @@ -688,41 +657,41 @@ SetupStartPage(PINPUT_RECORD Ir) // TODO: Read options from inf /* Load the hardware, language and keyboard layout lists */ - ComputerList = CreateComputerTypeList(SetupInf); - DisplayList = CreateDisplayDriverList(SetupInf); - KeyboardList = CreateKeyboardDriverList(SetupInf); + USetupData.ComputerList = CreateComputerTypeList(USetupData.SetupInf); + USetupData.DisplayList = CreateDisplayDriverList(USetupData.SetupInf); + USetupData.KeyboardList = CreateKeyboardDriverList(USetupData.SetupInf); - LanguageList = CreateLanguageList(SetupInf, DefaultLanguage); + USetupData.LanguageList = CreateLanguageList(USetupData.SetupInf, DefaultLanguage); /* new part */ SelectedLanguageId = DefaultLanguage; wcscpy(DefaultLanguage, USetupData.LocaleID); USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); - LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout); + USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout); /* first we hack LanguageList */ - for (ListEntry = GetFirstListEntry(LanguageList); ListEntry; + for (ListEntry = GetFirstListEntry(USetupData.LanguageList); ListEntry; ListEntry = GetNextListEntry(ListEntry)) { LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id; if (!wcsicmp(USetupData.LocaleID, LocaleId)) { DPRINT("found %S in LanguageList\n", LocaleId); - SetCurrentListEntry(LanguageList, ListEntry); + SetCurrentListEntry(USetupData.LanguageList, ListEntry); break; } } /* now LayoutList */ - for (ListEntry = GetFirstListEntry(LayoutList); ListEntry; + for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry; ListEntry = GetNextListEntry(ListEntry)) { LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id; if (!wcsicmp(USetupData.LocaleID, LocaleId)) { DPRINT("found %S in LayoutList\n", LocaleId); - SetCurrentListEntry(LayoutList, ListEntry); + SetCurrentListEntry(USetupData.LayoutList, ListEntry); break; } } @@ -1131,10 +1100,10 @@ OemDriverPage(PINPUT_RECORD Ir) * QuitPage * * SIDEEFFECTS - * Init ComputerList - * Init DisplayList - * Init KeyboardList - * Init LayoutList + * Init USetupData.ComputerList + * Init USetupData.DisplayList + * Init USetupData.KeyboardList + * Init USetupData.LayoutList * * RETURNS * Number of the next page. @@ -1145,10 +1114,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) static ULONG Line = 16; /* Initialize the computer settings list */ - if (ComputerList == NULL) + if (USetupData.ComputerList == NULL) { - ComputerList = CreateComputerTypeList(SetupInf); - if (ComputerList == NULL) + USetupData.ComputerList = CreateComputerTypeList(USetupData.SetupInf); + if (USetupData.ComputerList == NULL) { MUIDisplayError(ERROR_LOAD_COMPUTER, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; @@ -1156,10 +1125,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) } /* Initialize the display settings list */ - if (DisplayList == NULL) + if (USetupData.DisplayList == NULL) { - DisplayList = CreateDisplayDriverList(SetupInf); - if (DisplayList == NULL) + USetupData.DisplayList = CreateDisplayDriverList(USetupData.SetupInf); + if (USetupData.DisplayList == NULL) { MUIDisplayError(ERROR_LOAD_DISPLAY, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; @@ -1167,10 +1136,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) } /* Initialize the keyboard settings list */ - if (KeyboardList == NULL) + if (USetupData.KeyboardList == NULL) { - KeyboardList = CreateKeyboardDriverList(SetupInf); - if (KeyboardList == NULL) + USetupData.KeyboardList = CreateKeyboardDriverList(USetupData.SetupInf); + if (USetupData.KeyboardList == NULL) { MUIDisplayError(ERROR_LOAD_KEYBOARD, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; @@ -1178,10 +1147,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) } /* Initialize the keyboard layout list */ - if (LayoutList == NULL) + if (USetupData.LayoutList == NULL) { - LayoutList = CreateKeyboardLayoutList(SetupInf, SelectedLanguageId, DefaultKBLayout); - if (LayoutList == NULL) + USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout); + if (USetupData.LayoutList == NULL) { /* FIXME: report error */ MUIDisplayError(ERROR_LOAD_KBLAYOUT, Ir, POPUP_WAIT_ENTER); @@ -1197,10 +1166,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) MUIDisplayPage(DEVICE_SETTINGS_PAGE); - DrawGenericListCurrentItem(ComputerList, GetSettingDescription, 25, 11); - DrawGenericListCurrentItem(DisplayList , GetSettingDescription, 25, 12); - DrawGenericListCurrentItem(KeyboardList, GetSettingDescription, 25, 13); - DrawGenericListCurrentItem(LayoutList , GetSettingDescription, 25, 14); + DrawGenericListCurrentItem(USetupData.ComputerList, GetSettingDescription, 25, 11); + DrawGenericListCurrentItem(USetupData.DisplayList , GetSettingDescription, 25, 12); + DrawGenericListCurrentItem(USetupData.KeyboardList, GetSettingDescription, 25, 13); + DrawGenericListCurrentItem(USetupData.LayoutList , GetSettingDescription, 25, 14); CONSOLE_InvertTextXY(24, Line, 48, 1); @@ -1343,7 +1312,7 @@ ComputerSettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(COMPUTER_SETTINGS_PAGE); - InitGenericListUi(&ListUi, ComputerList, GetSettingDescription); + InitGenericListUi(&ListUi, USetupData.ComputerList, GetSettingDescription); DrawGenericList(&ListUi, 2, 18, xScreen - 3, @@ -1369,7 +1338,7 @@ DisplaySettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(DISPLAY_SETTINGS_PAGE); - InitGenericListUi(&ListUi, DisplayList, GetSettingDescription); + InitGenericListUi(&ListUi, USetupData.DisplayList, GetSettingDescription); DrawGenericList(&ListUi, 2, 18, xScreen - 3, @@ -1395,7 +1364,7 @@ KeyboardSettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(KEYBOARD_SETTINGS_PAGE); - InitGenericListUi(&ListUi, KeyboardList, GetSettingDescription); + InitGenericListUi(&ListUi, USetupData.KeyboardList, GetSettingDescription); DrawGenericList(&ListUi, 2, 18, xScreen - 3, @@ -1421,7 +1390,7 @@ LayoutSettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(LAYOUT_SETTINGS_PAGE); - InitGenericListUi(&ListUi, LayoutList, GetSettingDescription); + InitGenericListUi(&ListUi, USetupData.LayoutList, GetSettingDescription); DrawGenericList(&ListUi, 2, 18, xScreen - 3, @@ -3224,38 +3193,11 @@ BuildInstallPaths(PWSTR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEntry) { - WCHAR PathBuffer[MAX_PATH]; + NTSTATUS Status; -/** Equivalent of 'NTOS_INSTALLATION::PathComponent' **/ - /* Create 'InstallPath' string */ - RtlFreeUnicodeString(&InstallPath); - RtlCreateUnicodeString(&InstallPath, InstallDir); - - /* Create 'USetupData.DestinationRootPath' string */ - RtlFreeUnicodeString(&USetupData.DestinationRootPath); - RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), - L"\\Device\\Harddisk%lu\\Partition%lu\\", - DiskEntry->DiskNumber, - PartEntry->PartitionNumber); - RtlCreateUnicodeString(&USetupData.DestinationRootPath, PathBuffer); - DPRINT("DestinationRootPath: %wZ\n", &USetupData.DestinationRootPath); - -/** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/ - /* Create 'USetupData.DestinationPath' string */ - RtlFreeUnicodeString(&USetupData.DestinationPath); - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - USetupData.DestinationRootPath.Buffer, InstallDir); - RtlCreateUnicodeString(&USetupData.DestinationPath, PathBuffer); - -/** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/ - /* Create 'USetupData.DestinationArcPath' */ - RtlFreeUnicodeString(&USetupData.DestinationArcPath); - RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), - L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\", - DiskEntry->BiosDiskNumber, - PartEntry->PartitionNumber); - ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallDir); - RtlCreateUnicodeString(&USetupData.DestinationArcPath, PathBuffer); + Status = InitDestinationPaths(&USetupData, InstallDir, DiskEntry, PartEntry); + // TODO: Check Status + UNREFERENCED_PARAMETER(Status); /* Initialize DestinationDriveLetter */ DestinationDriveLetter = (WCHAR)PartEntry->DriveLetter; @@ -3594,7 +3536,7 @@ AddSectionToCopyQueueCab(HINF InfFile, break; } - if (!SetupQueueCopy(SetupFileQueue, + if (!SetupQueueCopy(USetupData.SetupFileQueue, SourceCabinet, USetupData.SourceRootPath.Buffer, USetupData.SourceRootDir.Buffer, @@ -3728,7 +3670,7 @@ AddSectionToCopyQueue(HINF InfFile, DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName); } - if (!SetupQueueCopy(SetupFileQueue, + if (!SetupQueueCopy(USetupData.SetupFileQueue, SourceCabinet, USetupData.SourceRootPath.Buffer, CompleteOrigDirName, @@ -3767,7 +3709,7 @@ PrepareCopyPageInfFile(HINF InfFile, /* Add specific files depending of computer type */ if (SourceCabinet == NULL) { - if (!ProcessComputerFiles(InfFile, ComputerList, &AdditionalSectionName)) + if (!ProcessComputerFiles(InfFile, USetupData.ComputerList, &AdditionalSectionName)) return FALSE; if (AdditionalSectionName) @@ -3905,21 +3847,21 @@ PrepareCopyPage(PINPUT_RECORD Ir) MUIDisplayPage(PREPARE_COPY_PAGE); /* Create the file queue */ - SetupFileQueue = SetupOpenFileQueue(); - if (SetupFileQueue == NULL) + USetupData.SetupFileQueue = SetupOpenFileQueue(); + if (USetupData.SetupFileQueue == NULL) { MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } - if (!PrepareCopyPageInfFile(SetupInf, NULL, Ir)) + if (!PrepareCopyPageInfFile(USetupData.SetupInf, NULL, Ir)) { /* FIXME: show an error dialog */ return QUIT_PAGE; } /* Search for the 'Cabinets' section */ - if (!SetupFindFirstLineW(SetupInf, L"Cabinets", NULL, &CabinetsContext)) + if (!SetupFindFirstLineW(USetupData.SetupInf, L"Cabinets", NULL, &CabinetsContext)) { return FILE_COPY_PAGE; } @@ -4078,7 +4020,7 @@ FileCopyPage(PINPUT_RECORD Ir) /* Create context for the copy process */ CopyContext.DestinationRootPath = USetupData.DestinationRootPath.Buffer; - CopyContext.InstallPath = InstallPath.Buffer; + CopyContext.InstallPath = USetupData.InstallPath.Buffer; CopyContext.TotalOperations = 0; CopyContext.CompletedOperations = 0; @@ -4128,12 +4070,12 @@ FileCopyPage(PINPUT_RECORD Ir) /* Do the file copying */ SetupCommitFileQueueW(NULL, - SetupFileQueue, + USetupData.SetupFileQueue, FileCopyCallback, &CopyContext); /* If we get here, we're done, so cleanup the queue and progress bar */ - SetupCloseFileQueue(SetupFileQueue); + SetupCloseFileQueue(USetupData.SetupFileQueue); DestroyProgressBar(CopyContext.ProgressBar); DestroyProgressBar(CopyContext.MemoryBars[0]); DestroyProgressBar(CopyContext.MemoryBars[1]); @@ -4199,15 +4141,15 @@ RegistryPage(PINPUT_RECORD Ir) MUIDisplayPage(REGISTRY_PAGE); - Error = UpdateRegistry(SetupInf, + Error = UpdateRegistry(USetupData.SetupInf, &USetupData, RepairUpdateFlag, PartitionList, DestinationDriveLetter, SelectedLanguageId, - DisplayList, - LayoutList, - LanguageList, + USetupData.DisplayList, + USetupData.LayoutList, + USetupData.LanguageList, RegistryStatus); if (Error != ERROR_SUCCESS) { @@ -4794,6 +4736,7 @@ QuitPage(PINPUT_RECORD Ir) DestroyPartitionList(PartitionList); PartitionList = NULL; } + TempPartition = NULL; FormatState = Start; @@ -4804,41 +4747,6 @@ QuitPage(PINPUT_RECORD Ir) FileSystemList = NULL; } - /* Destroy the computer settings list */ - if (ComputerList != NULL) - { - DestroyGenericList(ComputerList, TRUE); - ComputerList = NULL; - } - - /* Destroy the display settings list */ - if (DisplayList != NULL) - { - DestroyGenericList(DisplayList, TRUE); - DisplayList = NULL; - } - - /* Destroy the keyboard settings list */ - if (KeyboardList != NULL) - { - DestroyGenericList(KeyboardList, TRUE); - KeyboardList = NULL; - } - - /* Destroy the keyboard layout list */ - if (LayoutList != NULL) - { - DestroyGenericList(LayoutList, TRUE); - LayoutList = NULL; - } - - /* Destroy the languages list */ - if (LanguageList != NULL) - { - DestroyGenericList(LanguageList, FALSE); - LanguageList = NULL; - } - CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2)); /* Wait for maximum 15 seconds or an ENTER key before quitting */ @@ -4920,7 +4828,7 @@ RunUSetup(VOID) 0, 0, PnpEventThread, - &SetupInf, + &USetupData.SetupInf, &hPnpThread, NULL); if (!NT_SUCCESS(Status)) @@ -4936,15 +4844,8 @@ RunUSetup(VOID) return STATUS_APP_INIT_FAILURE; } - /* Initialize global unicode strings */ - RtlInitUnicodeString(&USetupData.SourcePath, NULL); - RtlInitUnicodeString(&USetupData.SourceRootPath, NULL); - RtlInitUnicodeString(&USetupData.SourceRootDir, NULL); - RtlInitUnicodeString(&InstallPath, NULL); - RtlInitUnicodeString(&USetupData.DestinationPath, NULL); - RtlInitUnicodeString(&USetupData.DestinationArcPath, NULL); - RtlInitUnicodeString(&USetupData.DestinationRootPath, NULL); - RtlInitUnicodeString(&USetupData.SystemRootPath, NULL); + /* Initialize Setup, phase 0 */ + InitializeSetup(&USetupData, 0); /* Hide the cursor */ CONSOLE_SetCursorType(TRUE, FALSE); @@ -5109,7 +5010,8 @@ RunUSetup(VOID) } } - SetupCloseInfFile(SetupInf); + /* Setup has finished */ + FinishSetup(&USetupData); if (Page == RECOVERY_PAGE) RecoveryConsole();
6 years, 1 month
1
0
0
0
01/02: [SETUPLIB] Silence noisy DPRINTs.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9016b5f3efc8fd3378112…
commit 9016b5f3efc8fd3378112e818cacb78cb8cf7ea9 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sun Oct 28 23:33:29 2018 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 28 23:40:26 2018 +0100 [SETUPLIB] Silence noisy DPRINTs. --- base/setup/lib/bootsup.c | 18 +++---- base/setup/lib/utils/bldrsup.c | 12 ++--- base/setup/lib/utils/osdetect.c | 106 +++++++++++++++++++++------------------- 3 files changed, 70 insertions(+), 66 deletions(-) diff --git a/base/setup/lib/bootsup.c b/base/setup/lib/bootsup.c index 3059d0c884..1caf02f951 100644 --- a/base/setup/lib/bootsup.c +++ b/base/setup/lib/bootsup.c @@ -356,10 +356,10 @@ EnumerateReactOSEntries( RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { /* This is not a ReactOS entry */ - // DPRINT1(" An installation '%S' of unsupported type '%S'\n", - // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); - DPRINT1(" An installation '%S' of unsupported type %lu\n", - BootEntry->FriendlyName, BootEntry->OsOptionsLength); + // DPRINT(" An installation '%S' of unsupported type '%S'\n", + // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); + DPRINT(" An installation '%S' of unsupported type %lu\n", + BootEntry->FriendlyName, BootEntry->OsOptionsLength); /* Continue the enumeration */ goto SkipThisEntry; } @@ -388,12 +388,12 @@ EnumerateReactOSEntries( } } - DPRINT1(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", - BootEntry->FriendlyName, Options->OsLoadPath); - // DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n", - // BootEntry->FriendlyName, Options->OsLoadPath); + DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", + BootEntry->FriendlyName, Options->OsLoadPath); + // DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n", + // BootEntry->FriendlyName, Options->OsLoadPath); - DPRINT1("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath); + DPRINT("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath); Data->UseExistingEntry = TRUE; RtlStringCchCopyW(Data->OsName, ARRAYSIZE(Data->OsName), BootEntry->FriendlyName); diff --git a/base/setup/lib/utils/bldrsup.c b/base/setup/lib/utils/bldrsup.c index a2978a0f25..09c59945b7 100644 --- a/base/setup/lib/utils/bldrsup.c +++ b/base/setup/lib/utils/bldrsup.c @@ -156,18 +156,18 @@ FindBootStore( // By handle if (DoesFileExist(PartitionDirectoryHandle, LoaderExecutable)) { /* A loader was found, stop there */ - DPRINT1("Found loader executable '%S'\n", LoaderExecutable); + DPRINT("Found loader executable '%S'\n", LoaderExecutable); break; } /* The loader does not exist, continue with another one */ - DPRINT1("Loader executable '%S' does not exist, continue with another one...\n", LoaderExecutable); + DPRINT("Loader executable '%S' does not exist, continue with another one...\n", LoaderExecutable); LoaderExecutable += wcslen(LoaderExecutable) + 1; } if (!*LoaderExecutable) { /* No loader was found */ - DPRINT1("No loader executable was found\n"); + DPRINT("No loader executable was found\n"); return STATUS_NOT_FOUND; } @@ -1308,7 +1308,7 @@ FreeLdrEnumerateBootEntries( InstallName = Buffer; } - DPRINT1("Boot entry '%S' in OS section '%S'\n", InstallName, SectionName); + DPRINT("Boot entry '%S' in OS section '%S'\n", InstallName, SectionName); BootEntry->Version = FreeLdr; BootEntry->BootEntryKey = MAKESTRKEY(SectionName); @@ -1337,7 +1337,7 @@ FreeLdrEnumerateBootEntries( /* BootType is Windows2003 */ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; - DPRINT1("This is a '%S' boot entry\n", KeyData); + DPRINT("This is a '%S' boot entry\n", KeyData); BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); RtlCopyMemory(Options->Signature, @@ -1368,7 +1368,7 @@ FreeLdrEnumerateBootEntries( /* BootType is BootSector */ PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions; - DPRINT1("This is a '%S' boot entry\n", KeyData); + DPRINT("This is a '%S' boot entry\n", KeyData); BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS); RtlCopyMemory(Options->Signature, diff --git a/base/setup/lib/utils/osdetect.c b/base/setup/lib/utils/osdetect.c index e654312c48..ed5e1f5805 100644 --- a/base/setup/lib/utils/osdetect.c +++ b/base/setup/lib/utils/osdetect.c @@ -96,10 +96,10 @@ EnumerateInstallations( RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { /* This is not a ReactOS entry */ - // DPRINT1(" An installation '%S' of unsupported type '%S'\n", - // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); - DPRINT1(" An installation '%S' of unsupported type %lu\n", - BootEntry->FriendlyName, BootEntry->OsOptionsLength); + // DPRINT(" An installation '%S' of unsupported type '%S'\n", + // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); + DPRINT(" An installation '%S' of unsupported type %lu\n", + BootEntry->FriendlyName, BootEntry->OsOptionsLength); /* Continue the enumeration */ return STATUS_SUCCESS; } @@ -113,10 +113,10 @@ EnumerateInstallations( return STATUS_SUCCESS; } - DPRINT1(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", - BootEntry->FriendlyName, Options->OsLoadPath); - // DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n", - // BootEntry->FriendlyName, Options->OsLoadPath); + DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", + BootEntry->FriendlyName, Options->OsLoadPath); + // DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n", + // BootEntry->FriendlyName, Options->OsLoadPath); // TODO: Normalize the ARC path. @@ -127,8 +127,8 @@ EnumerateInstallations( NtOsInstall = FindExistingNTOSInstall(Data->List, Options->OsLoadPath, NULL); if (NtOsInstall) { - DPRINT1(" An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n", - NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemArcPath); + DPRINT(" An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n", + NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemArcPath); /* Continue the enumeration */ return STATUS_SUCCESS; } @@ -146,8 +146,8 @@ EnumerateInstallations( return STATUS_SUCCESS; } - DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", - Options->OsLoadPath, &SystemRootPath); + DPRINT("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", + Options->OsLoadPath, &SystemRootPath); /* * Check whether we already have an installation with this NT path. @@ -162,7 +162,7 @@ EnumerateInstallations( return STATUS_SUCCESS; } - DPRINT1("EnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath); + DPRINT("EnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath); /* Check if this is a valid NTOS installation; stop there if it isn't one */ RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer, sizeof(VendorNameBuffer)); @@ -172,14 +172,14 @@ EnumerateInstallations( return STATUS_SUCCESS; } - DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", - Options->OsLoadPath, &SystemRootPath); + DPRINT("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", + Options->OsLoadPath, &SystemRootPath); /* From the NT path, compute the disk, partition and path components */ if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent)) { - DPRINT1("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n", - &SystemRootPath, DiskNumber, PartitionNumber, PathComponent); + DPRINT("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n", + &SystemRootPath, DiskNumber, PartitionNumber, PathComponent); /* Retrieve the corresponding disk and partition */ if (!GetDiskOrPartition(Data->PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry)) @@ -307,7 +307,7 @@ CheckForValidPEAndVendor( if (NT_SUCCESS(Status) /*&& pvData*/) { /* BufLen includes the NULL terminator count */ - DPRINT1("Found version vendor: \"%S\" for file '%S'\n", pvData, PathNameToFile); + DPRINT("Found version vendor: \"%S\" for file '%S'\n", pvData, PathNameToFile); RtlStringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength, pvData, BufLen * sizeof(WCHAR)); @@ -318,7 +318,7 @@ CheckForValidPEAndVendor( } if (!NT_SUCCESS(Status)) - DPRINT1("No version vendor found for file '%S'\n", PathNameToFile); + DPRINT("No version vendor found for file '%S'\n", PathNameToFile); UnmapCloseFile: /* Finally, unmap and close the file */ @@ -417,7 +417,7 @@ IsValidNTOSInstallationByHandle( if (Success) { /* We have found a correct vendor combination */ - DPRINT1("IsValidNTOSInstallation: We've got an NTOS installation from %S !\n", KnownVendors[i]); + DPRINT("IsValidNTOSInstallation: We've got an NTOS installation from %S !\n", KnownVendors[i]); break; } } @@ -445,7 +445,7 @@ IsValidNTOSInstallationByHandle( if (!!FindSubStrI(LocalVendorName.Buffer, KnownVendors[i])) { /* We have found a correct vendor combination */ - DPRINT1("IsValidNTOSInstallation: The user-mode DLL '%S' is from %S\n", PathName, KnownVendors[i]); + DPRINT("IsValidNTOSInstallation: The user-mode DLL '%S' is from %S\n", PathName, KnownVendors[i]); break; } } @@ -498,6 +498,7 @@ IsValidNTOSInstallation( return Success; } +#ifndef NDEBUG static VOID DumpNTOSInstalls( IN PGENERIC_LIST List) @@ -506,22 +507,23 @@ DumpNTOSInstalls( PNTOS_INSTALLATION NtOsInstall; ULONG NtOsInstallsCount = GetNumberOfListEntries(List); - DPRINT1("There %s %d installation%s detected:\n", - NtOsInstallsCount >= 2 ? "are" : "is", - NtOsInstallsCount, - NtOsInstallsCount >= 2 ? "s" : ""); + DPRINT("There %s %d installation%s detected:\n", + NtOsInstallsCount >= 2 ? "are" : "is", + NtOsInstallsCount, + NtOsInstallsCount >= 2 ? "s" : ""); for (Entry = GetFirstListEntry(List); Entry; Entry = GetNextListEntry(Entry)) { NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry); - DPRINT1(" On disk #%d, partition #%d: Installation \"%S\" in SystemRoot '%wZ'\n", - NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, - NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath); + DPRINT(" On disk #%d, partition #%d: Installation \"%S\" in SystemRoot '%wZ'\n", + NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, + NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath); } - DPRINT1("Done.\n"); + DPRINT("Done.\n"); } +#endif static PNTOS_INSTALLATION FindExistingNTOSInstall( @@ -661,7 +663,7 @@ FindNTOSInstallations( L"\\Device\\Harddisk%lu\\Partition%lu\\", DiskNumber, PartitionNumber); RtlInitUnicodeString(&PartitionRootPath, PathBuffer); - DPRINT1("FindNTOSInstallations: PartitionRootPath: '%wZ'\n", &PartitionRootPath); + DPRINT("FindNTOSInstallations: PartitionRootPath: '%wZ'\n", &PartitionRootPath); /* Open the partition */ InitializeObjectAttributes(&ObjectAttributes, @@ -691,14 +693,14 @@ FindNTOSInstallations( if (!NT_SUCCESS(Status)) { /* The loader does not exist, continue with another one */ - DPRINT1("Loader type '%d' does not exist, or an error happened (Status 0x%08lx), continue with another one...\n", - Type, Status); + DPRINT("Loader type '%d' does not exist, or an error happened (Status 0x%08lx), continue with another one...\n", + Type, Status); continue; } /* The loader exists, try to enumerate its boot entries */ - DPRINT1("Analyse the OS installations for loader type '%d' in disk #%d, partition #%d\n", - Type, DiskNumber, PartitionNumber); + DPRINT("Analyze the OS installations for loader type '%d' in disk #%d, partition #%d\n", + Type, DiskNumber, PartitionNumber); Status = OpenBootStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type, FALSE); if (!NT_SUCCESS(Status)) @@ -750,7 +752,7 @@ CreateNTOSInstallationsList( DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); Entry = Entry->Flink; - DPRINT1("Disk #%d\n", DiskEntry->DiskNumber); + DPRINT("Disk #%d\n", DiskEntry->DiskNumber); /* ... and for each disk, loop each available partition */ @@ -763,14 +765,14 @@ CreateNTOSInstallationsList( ASSERT(PartEntry->DiskEntry == DiskEntry); - DPRINT1(" Primary Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n", - PartEntry->PartitionNumber, PartEntry->PartitionIndex, - PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE", - PartEntry->IsPartitioned ? "TRUE" : "FALSE", - PartEntry->New ? "Yes" : "No", - PartEntry->AutoCreate ? "Yes" : "No", - PartEntry->FormatState, - ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!"); + DPRINT(" Primary Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n", + PartEntry->PartitionNumber, PartEntry->PartitionIndex, + PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE", + PartEntry->IsPartitioned ? "TRUE" : "FALSE", + PartEntry->New ? "Yes" : "No", + PartEntry->AutoCreate ? "Yes" : "No", + PartEntry->FormatState, + ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!"); if (ShouldICheckThisPartition(PartEntry)) FindNTOSInstallations(List, PartList, PartEntry); @@ -785,22 +787,24 @@ CreateNTOSInstallationsList( ASSERT(PartEntry->DiskEntry == DiskEntry); - DPRINT1(" Logical Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n", - PartEntry->PartitionNumber, PartEntry->PartitionIndex, - PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE", - PartEntry->IsPartitioned ? "TRUE" : "FALSE", - PartEntry->New ? "Yes" : "No", - PartEntry->AutoCreate ? "Yes" : "No", - PartEntry->FormatState, - ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!"); + DPRINT(" Logical Partition #%d, index %d - Type 0x%02x, IsLogical = %s, IsPartitioned = %s, IsNew = %s, AutoCreate = %s, FormatState = %lu -- Should I check it? %s\n", + PartEntry->PartitionNumber, PartEntry->PartitionIndex, + PartEntry->PartitionType, PartEntry->LogicalPartition ? "TRUE" : "FALSE", + PartEntry->IsPartitioned ? "TRUE" : "FALSE", + PartEntry->New ? "Yes" : "No", + PartEntry->AutoCreate ? "Yes" : "No", + PartEntry->FormatState, + ShouldICheckThisPartition(PartEntry) ? "YES!" : "NO!"); if (ShouldICheckThisPartition(PartEntry)) FindNTOSInstallations(List, PartList, PartEntry); } } +#ifndef NDEBUG /**** Debugging: List all the collected installations ****/ DumpNTOSInstalls(List); +#endif return List; }
6 years, 1 month
1
0
0
0
01/01: [KMTESTS:CC] Introduce a macro to test public BCB
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3d68c016640c58a49d9e6…
commit 3d68c016640c58a49d9e660de47c57f35a01f7c9 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sun Oct 28 22:37:59 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Sun Oct 28 22:37:59 2018 +0100 [KMTESTS:CC] Introduce a macro to test public BCB For now, it's local, but it may be moved to some header to be shared between tests. --- modules/rostests/kmtests/ntos_cc/CcPinRead_drv.c | 29 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/modules/rostests/kmtests/ntos_cc/CcPinRead_drv.c b/modules/rostests/kmtests/ntos_cc/CcPinRead_drv.c index 369d105742..c242f442a2 100644 --- a/modules/rostests/kmtests/ntos_cc/CcPinRead_drv.c +++ b/modules/rostests/kmtests/ntos_cc/CcPinRead_drv.c @@ -144,6 +144,15 @@ MapAndLockUserBuffer( return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); } +#define ok_bcb(B, L, O) \ +{ \ + PPUBLIC_BCB public_bcb = (B); \ + ok(public_bcb->NodeTypeCode == 0x2FD, "Not a BCB: %x\n", public_bcb->NodeTypeCode); \ + ok(public_bcb->NodeByteSize == 0, "Invalid size: %d\n", public_bcb->NodeByteSize); \ + ok_eq_ulong(public_bcb->MappedLength, (L)); \ + ok_eq_longlong(public_bcb->MappedFileOffset.QuadPart, (O)); \ +} + static VOID NTAPI @@ -172,7 +181,7 @@ PinInAnotherThread(IN PVOID Context) if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, 12288, Offset.QuadPart); ok_eq_pointer(Bcb, TestContext->Bcb); ok_eq_pointer(Buffer, TestContext->Buffer); @@ -185,7 +194,7 @@ PinInAnotherThread(IN PVOID Context) if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, 12288, Offset.QuadPart); ok_eq_pointer(Bcb, TestContext->Bcb); ok_eq_pointer(Buffer, TestContext->Buffer); @@ -198,7 +207,7 @@ PinInAnotherThread(IN PVOID Context) if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, 12288, Offset.QuadPart); ok_eq_pointer(Bcb, TestContext->Bcb); ok_eq_pointer(Buffer, TestContext->Buffer); @@ -226,7 +235,7 @@ PinInAnotherThread(IN PVOID Context) if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, 12288, 4096); ok_eq_pointer(Bcb, TestContext->Bcb); ok_eq_pointer(Buffer, (PVOID)((ULONG_PTR)TestContext->Buffer + 0x500)); @@ -239,7 +248,7 @@ PinInAnotherThread(IN PVOID Context) if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, 12288, 4096); ok_eq_pointer(Bcb, TestContext->Bcb); ok_eq_pointer(Buffer, (PVOID)((ULONG_PTR)TestContext->Buffer + 0x500)); @@ -252,7 +261,7 @@ PinInAnotherThread(IN PVOID Context) if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, 12288, 4096); ok_eq_pointer(Bcb, TestContext->Bcb); ok_eq_pointer(Buffer, (PVOID)((ULONG_PTR)TestContext->Buffer + 0x500)); @@ -393,7 +402,7 @@ PerformTest( if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, ((4 - TestId) * 4096), Offset.QuadPart); ok_eq_ulong(Buffer[(0x3000 - TestId * 0x1000) / sizeof(ULONG)], 0xDEADBABE); CcUnpinData(Bcb); @@ -427,7 +436,7 @@ PerformTest( { PKTHREAD ThreadHandle; - ok(*(PUSHORT)TestContext->Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)TestContext->Bcb); + ok_bcb(TestContext->Bcb, 12288, Offset.QuadPart); #ifdef _X86_ /* FIXME: Should be fixed, will fail under certains conditions */ @@ -460,7 +469,7 @@ PerformTest( { PKTHREAD ThreadHandle; - ok(*(PUSHORT)TestContext->Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)TestContext->Bcb); + ok_bcb(TestContext->Bcb, 12288, Offset.QuadPart); TestContext->Length = FileSizes.FileSize.QuadPart - Offset.QuadPart; ThreadHandle = KmtStartThread(PinInAnotherThreadExclusive, TestContext); @@ -482,7 +491,7 @@ PerformTest( if (!skip(Ret == TRUE, "CcPinRead failed\n")) { - ok(*(PUSHORT)Bcb == 0x2FD, "Not a BCB: %x\n", *(PUSHORT)Bcb); + ok_bcb(Bcb, 12288, Offset.QuadPart); ok_eq_ulong(Buffer[0x2000 / sizeof(ULONG)], 0); CcUnpinData(Bcb);
6 years, 1 month
1
0
0
0
01/01: [NTOSKRNL] Fix refcounting for BCBs
by Pierre Schweitzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf7969fbfaa3ff637dd57…
commit cf7969fbfaa3ff637dd57ad64743ee9d216f8d58 Author: Pierre Schweitzer <pierre(a)reactos.org> AuthorDate: Sun Oct 28 20:48:01 2018 +0100 Commit: Pierre Schweitzer <pierre(a)reactos.org> CommitDate: Sun Oct 28 20:48:01 2018 +0100 [NTOSKRNL] Fix refcounting for BCBs Now, we make sure that we update ref count and BCB list membership with the BCB lock held, in a row. This will avoid race conditions where the BCB was removed from the list, then referenced again, leading to inconsistencies in memory and crashes later on. This could notably be triggered while building ReactOS on ReactOS (one would call this a regression). CORE-15235 --- ntoskrnl/cc/pin.c | 120 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 49 deletions(-) diff --git a/ntoskrnl/cc/pin.c b/ntoskrnl/cc/pin.c index dc7427427e..775b105a2f 100644 --- a/ntoskrnl/cc/pin.c +++ b/ntoskrnl/cc/pin.c @@ -152,6 +152,38 @@ CcpMapData( return TRUE; } +static +VOID +CcpDereferenceBcb( + IN PROS_SHARED_CACHE_MAP SharedCacheMap, + IN PINTERNAL_BCB Bcb) +{ + ULONG RefCount; + KIRQL OldIrql; + + KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql); + RefCount = --Bcb->RefCount; + if (RefCount == 0) + { + RemoveEntryList(&Bcb->BcbEntry); + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + + ASSERT(Bcb->PinCount == 0); + CcRosReleaseVacb(SharedCacheMap, + Bcb->Vacb, + TRUE, + Bcb->Dirty, + FALSE); + + ExDeleteResourceLite(&Bcb->Lock); + ExFreeToNPagedLookasideList(&iBcbLookasideList, Bcb); + } + else + { + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + } +} + static PVOID CcpGetAppropriateBcb( @@ -191,12 +223,13 @@ CcpGetAppropriateBcb( /* Yes, and we've lost */ if (DupBcb != NULL) { + /* We will return that BCB */ + ++DupBcb->RefCount; Result = TRUE; + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); if (ToPin) { - DupBcb->PinCount++; - if (BooleanFlagOn(PinFlags, PIN_EXCLUSIVE)) { Result = ExAcquireResourceExclusiveLite(&iBcb->Lock, BooleanFlagOn(PinFlags, PIN_WAIT)); @@ -206,24 +239,25 @@ CcpGetAppropriateBcb( Result = ExAcquireSharedStarveExclusive(&iBcb->Lock, BooleanFlagOn(PinFlags, PIN_WAIT)); } - if (!Result) + if (Result) + { + DupBcb->PinCount++; + } + else { - DupBcb->PinCount--; + CcpDereferenceBcb(SharedCacheMap, DupBcb); DupBcb = NULL; } } - if (Result) + if (DupBcb != NULL) { - /* We'll return that BCB */ - ++DupBcb->RefCount; + /* Delete the loser */ + CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE); + ExDeleteResourceLite(&iBcb->Lock); + ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); } - /* Delete the loser */ - CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE); - ExDeleteResourceLite(&iBcb->Lock); - ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); - /* Return the winner - no need to update buffer address, it's * relative to the VACB, which is unchanged. */ @@ -249,8 +283,8 @@ CcpGetAppropriateBcb( } InsertTailList(&SharedCacheMap->BcbList, &iBcb->BcbEntry); + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); } - KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); return iBcb; } @@ -273,11 +307,11 @@ CcpPinData( KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql); NewBcb = CcpFindBcb(SharedCacheMap, FileOffset, Length, TRUE); - KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); if (NewBcb != NULL) { - NewBcb->PinCount++; + ++NewBcb->RefCount; + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); if (BooleanFlagOn(Flags, PIN_EXCLUSIVE)) { @@ -290,11 +324,12 @@ CcpPinData( if (!Result) { - NewBcb->PinCount--; + CcpDereferenceBcb(SharedCacheMap, NewBcb); + NewBcb = NULL; } else { - NewBcb->RefCount++; + NewBcb->PinCount++; *Bcb = NewBcb; *Buffer = (PUCHAR)NewBcb->Vacb->BaseAddress + FileOffset->QuadPart % VACB_MAPPING_GRANULARITY; } @@ -303,6 +338,8 @@ CcpPinData( } else { + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + if (BooleanFlagOn(Flags, PIN_IF_BCB)) { return FALSE; @@ -374,10 +411,11 @@ CcMapData ( KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql); iBcb = CcpFindBcb(SharedCacheMap, FileOffset, Length, FALSE); - KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); if (iBcb == NULL) { + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + Ret = CcpMapData(SharedCacheMap, FileOffset, Length, Flags, &Vacb, pBuffer); if (Ret) { @@ -396,6 +434,8 @@ CcMapData ( else { ++iBcb->RefCount; + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + *pBcb = iBcb; *pBuffer = (PUCHAR)iBcb->Vacb->BaseAddress + FileOffset->QuadPart % VACB_MAPPING_GRANULARITY; Ret = TRUE; @@ -564,6 +604,7 @@ CcUnpinDataForThread ( IN ERESOURCE_THREAD ResourceThreadId) { PINTERNAL_BCB iBcb = Bcb; + PROS_SHARED_CACHE_MAP SharedCacheMap; CCTRACE(CC_API_DEBUG, "Bcb=%p ResourceThreadId=%lu\n", Bcb, ResourceThreadId); @@ -573,29 +614,8 @@ CcUnpinDataForThread ( iBcb->PinCount--; } - if (--iBcb->RefCount == 0) - { - KIRQL OldIrql; - PROS_SHARED_CACHE_MAP SharedCacheMap; - - ASSERT(iBcb->PinCount == 0); - SharedCacheMap = iBcb->Vacb->SharedCacheMap; - CcRosReleaseVacb(SharedCacheMap, - iBcb->Vacb, - TRUE, - iBcb->Dirty, - FALSE); - - KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql); - if (!IsListEmpty(&iBcb->BcbEntry)) - { - RemoveEntryList(&iBcb->BcbEntry); - } - KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); - - ExDeleteResourceLite(&iBcb->Lock); - ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); - } + SharedCacheMap = iBcb->Vacb->SharedCacheMap; + CcpDereferenceBcb(SharedCacheMap, iBcb); } /* @@ -629,9 +649,15 @@ CcUnpinRepinnedBcb ( CCTRACE(CC_API_DEBUG, "Bcb=%p WriteThrough=%d\n", Bcb, WriteThrough); + SharedCacheMap = iBcb->Vacb->SharedCacheMap; IoStatus->Status = STATUS_SUCCESS; + + KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql); if (--iBcb->RefCount == 0) { + RemoveEntryList(&iBcb->BcbEntry); + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + IoStatus->Information = 0; if (WriteThrough) { @@ -656,21 +682,17 @@ CcUnpinRepinnedBcb ( ASSERT(iBcb->PinCount == 0); } - SharedCacheMap = iBcb->Vacb->SharedCacheMap; CcRosReleaseVacb(iBcb->Vacb->SharedCacheMap, iBcb->Vacb, TRUE, iBcb->Dirty, FALSE); - KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql); - if (!IsListEmpty(&iBcb->BcbEntry)) - { - RemoveEntryList(&iBcb->BcbEntry); - } - KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); - ExDeleteResourceLite(&iBcb->Lock); ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); } + else + { + KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql); + } }
6 years, 1 month
1
0
0
0
← Newer
1
2
3
4
5
6
...
36
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Results per page:
10
25
50
100
200