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
07/08: [USETUP] Sprinkle some INF_FreeData() calls to balance the INF_GetData() / INF_GetDataField() calls.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf2571de6e9c90f188070…
commit cf2571de6e9c90f18807053ef953a96f5b1e6141 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Wed Aug 9 20:24:24 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Oct 27 03:18:00 2018 +0200 [USETUP] Sprinkle some INF_FreeData() calls to balance the INF_GetData() / INF_GetDataField() calls. They currently do nothing, since the getter functions don't actually capture (copy) the strings but merely return pointers to read-only strings. But the calls are placed here for consistency, because if one day the getters' implementation is changed so that strings are captured, it would then be needed to free the allocated buffers. In addition, fix a buggy call to INF_GetData() -- should be instead INF_GetDataField() -- in AddSectionToCopyQueue(). svn path=/branches/setup_improvements/; revision=75516 --- base/setup/usetup/devinst.c | 99 +++++++++++++++++++++++++------------------- base/setup/usetup/settings.c | 29 +++++++++---- base/setup/usetup/usetup.c | 43 ++++++++++++++++++- 3 files changed, 119 insertions(+), 52 deletions(-) diff --git a/base/setup/usetup/devinst.c b/base/setup/usetup/devinst.c index bd9af3a357..dd867d3c9b 100644 --- a/base/setup/usetup/devinst.c +++ b/base/setup/usetup/devinst.c @@ -76,11 +76,17 @@ InstallDriver( && !SetupFindFirstLineW(hInf, L"InputDevicesSupport.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"Keyboard.Load", Driver, &Context)) { + INF_FreeData(ClassGuid); + INF_FreeData(Driver); return FALSE; } if (!INF_GetDataField(&Context, 1, &ImagePath)) + { + INF_FreeData(ClassGuid); + INF_FreeData(Driver); return FALSE; + } /* Prepare full driver path */ dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR); @@ -88,6 +94,9 @@ InstallDriver( if (!FullImagePath) { DPRINT1("RtlAllocateHeap() failed\n"); + INF_FreeData(ImagePath); + INF_FreeData(ClassGuid); + INF_FreeData(Driver); return FALSE; } RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength); @@ -103,6 +112,9 @@ InstallDriver( { DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status); RtlFreeHeap(ProcessHeap, 0, FullImagePath); + INF_FreeData(ImagePath); + INF_FreeData(ClassGuid); + INF_FreeData(Driver); return FALSE; } @@ -110,38 +122,38 @@ InstallDriver( if (Disposition == REG_CREATED_NEW_KEY) { dwValue = 0; - NtSetValueKey( - hService, - &ErrorControlU, - 0, - REG_DWORD, - &dwValue, - sizeof(dwValue)); + NtSetValueKey(hService, + &ErrorControlU, + 0, + REG_DWORD, + &dwValue, + sizeof(dwValue)); + dwValue = 0; - NtSetValueKey( - hService, - &StartU, - 0, - REG_DWORD, - &dwValue, - sizeof(dwValue)); + NtSetValueKey(hService, + &StartU, + 0, + REG_DWORD, + &dwValue, + sizeof(dwValue)); + dwValue = SERVICE_KERNEL_DRIVER; - NtSetValueKey( - hService, - &TypeU, - 0, - REG_DWORD, - &dwValue, - sizeof(dwValue)); + NtSetValueKey(hService, + &TypeU, + 0, + REG_DWORD, + &dwValue, + sizeof(dwValue)); } /* HACK: don't put any path in registry */ - NtSetValueKey( - hService, - &ImagePathU, - 0, - REG_SZ, - ImagePath, - (wcslen(ImagePath) + 1) * sizeof(WCHAR)); + NtSetValueKey(hService, + &ImagePathU, + 0, + REG_SZ, + ImagePath, + (wcslen(ImagePath) + 1) * sizeof(WCHAR)); + + INF_FreeData(ImagePath); if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0) { @@ -154,29 +166,32 @@ InstallDriver( (wcslen(keyboardClass) + 2) * sizeof(WCHAR)); } + INF_FreeData(ClassGuid); + /* Associate device with the service we just filled */ - Status = NtSetValueKey( - hDeviceKey, - &ServiceU, - 0, - REG_SZ, - Driver, - (wcslen(Driver) + 1) * sizeof(WCHAR)); + Status = NtSetValueKey(hDeviceKey, + &ServiceU, + 0, + REG_SZ, + Driver, + (wcslen(Driver) + 1) * sizeof(WCHAR)); if (NT_SUCCESS(Status)) { /* Restart the device, so it will use the driver we registered */ deviceInstalled = ResetDevice(DeviceId); } + INF_FreeData(Driver); + /* HACK: Update driver path */ - NtSetValueKey( - hService, - &ImagePathU, - 0, - REG_SZ, - FullImagePath, - (wcslen(FullImagePath) + 1) * sizeof(WCHAR)); + NtSetValueKey(hService, + &ImagePathU, + 0, + REG_SZ, + FullImagePath, + (wcslen(FullImagePath) + 1) * sizeof(WCHAR)); RtlFreeHeap(ProcessHeap, 0, FullImagePath); + NtClose(hService); return deviceInstalled; diff --git a/base/setup/usetup/settings.c b/base/setup/usetup/settings.c index 8aaa528b0e..64ccd9e709 100644 --- a/base/setup/usetup/settings.c +++ b/base/setup/usetup/settings.c @@ -324,6 +324,7 @@ CreateComputerTypeList( DPRINT("KeyValue: %S\n", KeyValue); if (wcsstr(ComputerIdentifier, KeyValue)) { + INF_FreeData(KeyValue); if (!INF_GetDataField(&Context, 0, &KeyName)) { /* FIXME: Handle error! */ @@ -333,7 +334,9 @@ CreateComputerTypeList( DPRINT("Computer key: %S\n", KeyName); wcscpy(ComputerKey, KeyName); + INF_FreeData(KeyName); } + INF_FreeData(KeyValue); } while (SetupFindNextLine(&Context, &Context)); List = CreateGenericList(); @@ -348,7 +351,7 @@ CreateComputerTypeList( do { - if (!INF_GetData (&Context, &KeyName, &KeyValue)) + if (!INF_GetData(&Context, &KeyName, &KeyValue)) { /* FIXME: Handle error! */ DPRINT("INF_GetData() failed\n"); @@ -364,10 +367,13 @@ CreateComputerTypeList( } wcscpy(UserData, KeyName); + INF_FreeData(KeyName); sprintf(Buffer, "%S", KeyValue); + INF_FreeData(KeyValue); + AppendGenericListEntry(List, Buffer, UserData, - _wcsicmp(KeyName, ComputerKey) ? FALSE : TRUE); + _wcsicmp(UserData, ComputerKey) ? FALSE : TRUE); } while (SetupFindNextLine(&Context, &Context)); return List; @@ -579,6 +585,7 @@ CreateDisplayDriverList( DPRINT("KeyValue: %S\n", KeyValue); if (wcsstr(DisplayIdentifier, KeyValue)) { + INF_FreeData(KeyValue); if (!INF_GetDataField(&Context, 0, &KeyName)) { /* FIXME: Handle error! */ @@ -588,7 +595,9 @@ CreateDisplayDriverList( DPRINT("Display key: %S\n", KeyName); wcscpy(DisplayKey, KeyName); + INF_FreeData(KeyName); } + INF_FreeData(KeyValue); } while (SetupFindNextLine(&Context, &Context)); List = CreateGenericList(); @@ -612,6 +621,7 @@ CreateDisplayDriverList( if (!INF_GetDataField(&Context, 1, &KeyValue)) { DPRINT1("INF_GetDataField() failed\n"); + INF_FreeData(KeyName); break; } @@ -622,16 +632,19 @@ CreateDisplayDriverList( { DPRINT1("RtlAllocateHeap() failed\n"); DestroyGenericList(List, TRUE); + INF_FreeData(KeyValue); + INF_FreeData(KeyName); return NULL; } wcscpy(UserData, KeyName); + INF_FreeData(KeyName); sprintf(Buffer, "%S", KeyValue); - AppendGenericListEntry(List, - Buffer, - UserData, - _wcsicmp(KeyName, DisplayKey) ? FALSE : TRUE); + INF_FreeData(KeyValue); + + AppendGenericListEntry(List, Buffer, UserData, + _wcsicmp(UserData, DisplayKey) ? FALSE : TRUE); } while (SetupFindNextLine(&Context, &Context)); #if 0 @@ -1061,7 +1074,7 @@ CreateLanguageList( } while (SetupFindNextLine(&Context, &Context)); /* Only one language available, make it the default one */ - if(uIndex == 1 && UserData != NULL) + if (uIndex == 1 && UserData != NULL) { DefaultLanguageIndex = 0; wcscpy(DefaultLanguage, UserData); @@ -1234,7 +1247,7 @@ SetGeoID( Status = NtOpenKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes); - if(!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); return FALSE; diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index d59a751e42..97da4d426a 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -3718,13 +3718,20 @@ AddSectionToCopyQueueCab(HINF InfFile, { /* FIXME: Handle error! */ DPRINT1("SetupFindFirstLine() failed\n"); + INF_FreeData(FileKeyName); + INF_FreeData(FileKeyValue); + INF_FreeData(TargetFileName); break; } + INF_FreeData(FileKeyValue); + if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) { /* FIXME: Handle error! */ DPRINT1("INF_GetData() failed\n"); + INF_FreeData(FileKeyName); + INF_FreeData(TargetFileName); break; } @@ -3739,6 +3746,10 @@ AddSectionToCopyQueueCab(HINF InfFile, /* FIXME: Handle error! */ DPRINT1("SetupQueueCopy() failed\n"); } + + INF_FreeData(FileKeyName); + INF_FreeData(TargetFileName); + INF_FreeData(DirKeyValue); } while (SetupFindNextLine(&FilesContext, &FilesContext)); return TRUE; @@ -3782,8 +3793,8 @@ AddSectionToCopyQueue(HINF InfFile, */ do { - /* Get source file name and target directory id */ - if (!INF_GetData(&FilesContext, &FileKeyName, &FileKeyValue)) + /* Get source file name */ + if (!INF_GetDataField(&FilesContext, 0, &FileKeyName)) { /* FIXME: Handle error! */ DPRINT1("INF_GetData() failed\n"); @@ -3795,6 +3806,7 @@ AddSectionToCopyQueue(HINF InfFile, { /* FIXME: Handle error! */ DPRINT1("INF_GetData() failed\n"); + INF_FreeData(FileKeyName); break; } @@ -3811,13 +3823,20 @@ AddSectionToCopyQueue(HINF InfFile, { /* FIXME: Handle error! */ DPRINT1("SetupFindFirstLine() failed\n"); + INF_FreeData(FileKeyName); + INF_FreeData(FileKeyValue); + INF_FreeData(TargetFileName); break; } + INF_FreeData(FileKeyValue); + if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) { /* FIXME: Handle error! */ DPRINT1("INF_GetData() failed\n"); + INF_FreeData(FileKeyName); + INF_FreeData(TargetFileName); break; } @@ -3863,6 +3882,10 @@ AddSectionToCopyQueue(HINF InfFile, /* FIXME: Handle error! */ DPRINT1("SetupQueueCopy() failed\n"); } + + INF_FreeData(FileKeyName); + INF_FreeData(TargetFileName); + INF_FreeData(DirKeyValue); } while (SetupFindNextLine(&FilesContext, &FilesContext)); return TRUE; @@ -3968,6 +3991,7 @@ PrepareCopyPageInfFile(HINF InfFile, Status = SetupCreateDirectory(PathBuffer); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) { + INF_FreeData(DirKeyValue); DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER); return FALSE; @@ -3986,11 +4010,14 @@ PrepareCopyPageInfFile(HINF InfFile, Status = SetupCreateDirectory(PathBuffer); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) { + INF_FreeData(DirKeyValue); DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER); return FALSE; } } + + INF_FreeData(DirKeyValue); } while (SetupFindNextLine(&DirContext, &DirContext)); return TRUE; @@ -4380,7 +4407,12 @@ DoUpdate: DPRINT("Action: %S File: %S Section %S\n", Action, File, Section); if (Action == NULL) + { + INF_FreeData(Action); + INF_FreeData(File); + INF_FreeData(Section); break; // Hackfix + } if (!_wcsicmp(Action, L"AddReg")) Delete = FALSE; @@ -4389,14 +4421,21 @@ DoUpdate: else { DPRINT1("Unrecognized registry INF action '%S'\n", Action); + INF_FreeData(Action); + INF_FreeData(File); + INF_FreeData(Section); continue; } + INF_FreeData(Action); + CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File); if (!ImportRegistryFile(SourcePath.Buffer, File, Section, LanguageId, Delete)) { DPRINT1("Importing %S failed\n", File); + INF_FreeData(File); + INF_FreeData(Section); MUIDisplayError(ERROR_IMPORT_HIVE, Ir, POPUP_WAIT_ENTER); goto Cleanup; }
6 years, 2 months
1
0
0
0
06/08: [USETUP] Comment out SetupQueueCopyWNew() declaration which is not used at all. Remove unnecessary casts in the INF_OpenBufferedFileA() call.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aa110db3ea93c7ebab489…
commit aa110db3ea93c7ebab4895fe74dd9884b3835b5b Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Tue Aug 8 14:07:17 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Oct 27 03:17:59 2018 +0200 [USETUP] Comment out SetupQueueCopyWNew() declaration which is not used at all. Remove unnecessary casts in the INF_OpenBufferedFileA() call. svn path=/branches/setup_improvements/; revision=75509 --- base/setup/usetup/filequeue.h | 4 +++- base/setup/usetup/usetup.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/base/setup/usetup/filequeue.h b/base/setup/usetup/filequeue.h index ebc05e282b..f43ef91462 100644 --- a/base/setup/usetup/filequeue.h +++ b/base/setup/usetup/filequeue.h @@ -60,7 +60,7 @@ typedef UINT (CALLBACK* PSP_FILE_CALLBACK_W)( typedef struct _COPYCONTEXT { LPCWSTR DestinationRootPath; /* Not owned by this structure */ - LPCWSTR InstallPath; /* Not owned by this structure */ + LPCWSTR InstallPath; /* Not owned by this structure */ ULONG TotalOperations; ULONG CompletedOperations; PPROGRESSBAR ProgressBar; @@ -78,6 +78,7 @@ WINAPI SetupCloseFileQueue( IN HSPFILEQ QueueHandle); +#if 0 // This is the API that is declared in setupapi.h and exported by setupapi.dll BOOL WINAPI SetupQueueCopyWNew( @@ -90,6 +91,7 @@ SetupQueueCopyWNew( IN PCWSTR TargetDirectory, IN PCWSTR TargetFileName, IN DWORD CopyStyle); +#endif BOOL SetupQueueCopy( diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index b34a7b762f..d59a751e42 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -4078,9 +4078,9 @@ PrepareCopyPage(PINPUT_RECORD Ir) return QUIT_PAGE; } - InfHandle = INF_OpenBufferedFileA((CHAR*) InfFileData, + InfHandle = INF_OpenBufferedFileA((PSTR)InfFileData, InfFileSize, - (const CHAR*) NULL, + NULL, INF_STYLE_WIN4, LanguageId, &ErrorLine);
6 years, 2 months
1
0
0
0
05/08: [SETUPLIB] Introduce defines for size units. [USETUP] Use them in the code.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9348fe1f7ef402cbeb178…
commit 9348fe1f7ef402cbeb1784852841dd98d1ff2681 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Tue Aug 8 14:05:20 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Oct 27 03:17:58 2018 +0200 [SETUPLIB] Introduce defines for size units. [USETUP] Use them in the code. svn path=/branches/setup_improvements/; revision=75508 --- base/setup/lib/setuplib.h | 12 ++++++++ base/setup/usetup/partlist.c | 26 ++++++++--------- base/setup/usetup/usetup.c | 66 ++++++++++++++++++++++---------------------- 3 files changed, 58 insertions(+), 46 deletions(-) diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h index 73b308ae4f..223a1ac6d5 100644 --- a/base/setup/lib/setuplib.h +++ b/base/setup/lib/setuplib.h @@ -7,6 +7,8 @@ #pragma once +/* INCLUDES *****************************************************************/ + /* Needed PSDK headers when using this library */ #if 0 @@ -37,4 +39,14 @@ extern HANDLE ProcessHeap; #include "regutil.h" #include "registry.h" + +/* DEFINES ******************************************************************/ + +#define KB ((ULONGLONG)1024) +#define MB (KB*KB) +#define GB (KB*KB*KB) +// #define TB (KB*KB*KB*KB) +// #define PB (KB*KB*KB*KB*KB) + + /* EOF */ diff --git a/base/setup/usetup/partlist.c b/base/setup/usetup/partlist.c index 5ae9edc88d..f403a976ce 100644 --- a/base/setup/usetup/partlist.c +++ b/base/setup/usetup/partlist.c @@ -292,21 +292,21 @@ PrintPartitionData( { PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (PartSize.QuadPart >= 10737418240) /* 10 GB */ + if (PartSize.QuadPart >= 10 * GB) /* 10 GB */ { - PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824); + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, GB); Unit = MUIGetString(STRING_GB); } else #endif - if (PartSize.QuadPart >= 10485760) /* 10 MB */ + if (PartSize.QuadPart >= 10 * MB) /* 10 MB */ { - PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576); + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, MB); Unit = MUIGetString(STRING_MB); } else { - PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024); + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, KB); Unit = MUIGetString(STRING_KB); } @@ -335,21 +335,21 @@ PrintPartitionData( PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (PartSize.QuadPart >= 10737418240) /* 10 GB */ + if (PartSize.QuadPart >= 10 * GB) /* 10 GB */ { - PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824); + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, GB); Unit = MUIGetString(STRING_GB); } else #endif - if (PartSize.QuadPart >= 10485760) /* 10 MB */ + if (PartSize.QuadPart >= 10 * MB) /* 10 MB */ { - PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576); + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, MB); Unit = MUIGetString(STRING_MB); } else { - PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024); + PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, KB); Unit = MUIGetString(STRING_KB); } @@ -442,14 +442,14 @@ PrintDiskData( coPos.Y = ListUi->Top + 1 + ListUi->Line; DiskSize.QuadPart = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; - if (DiskSize.QuadPart >= 10737418240) /* 10 GB */ + if (DiskSize.QuadPart >= 10 * GB) /* 10 GB */ { - DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1073741824); + DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, GB); Unit = MUIGetString(STRING_GB); } else { - DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1048576); + DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, MB); if (DiskSize.QuadPart == 0) DiskSize.QuadPart = 1; Unit = MUIGetString(STRING_MB); diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index d076a52475..b34a7b762f 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -1702,7 +1702,7 @@ IsDiskSizeValid(PPARTENTRY PartEntry) ULONGLONG size; size = PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector; - size = (size + 524288) / 1048576; /* in MBytes */ + size = (size + (512 * KB)) / MB; /* in MBytes */ if (size < RequiredPartitionDiskSpace) { @@ -2215,15 +2215,15 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2260,7 +2260,7 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB", - PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576); + PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / MB); #endif CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); @@ -2268,7 +2268,7 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; while (TRUE) { - MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576; /* in MBytes (rounded) */ + MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / MB; /* in MBytes (rounded) */ if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE; @@ -2312,7 +2312,7 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) else { /* Calculate the sector count from the size in MB */ - SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector; + SectorCount = PartSize * MB / DiskEntry->BytesPerSector; /* But never get larger than the unpartitioned disk space */ if (SectorCount > PartEntry->SectorCount.QuadPart) @@ -2374,15 +2374,15 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2419,7 +2419,7 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB", - PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576); + PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / MB); #endif CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); @@ -2427,7 +2427,7 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; while (TRUE) { - MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576; /* in MBytes (rounded) */ + MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / MB; /* in MBytes (rounded) */ if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE; @@ -2471,7 +2471,7 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) else { /* Calculate the sector count from the size in MB */ - SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector; + SectorCount = PartSize * MB / DiskEntry->BytesPerSector; /* But never get larger than the unpartitioned disk space */ if (SectorCount > PartEntry->SectorCount.QuadPart) @@ -2532,15 +2532,15 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2577,7 +2577,7 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB", - PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576); + PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / MB); #endif CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); @@ -2585,7 +2585,7 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; while (TRUE) { - MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576; /* in MBytes (rounded) */ + MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / MB; /* in MBytes (rounded) */ if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE; @@ -2629,7 +2629,7 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) else { /* Calculate the sector count from the size in MB */ - SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector; + SectorCount = PartSize * MB / DiskEntry->BytesPerSector; /* But never get larger than the unpartitioned disk space */ if (SectorCount > PartEntry->SectorCount.QuadPart) @@ -2730,21 +2730,21 @@ DeletePartitionPage(PINPUT_RECORD Ir) PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (PartSize >= 10737418240) /* 10 GB */ + if (PartSize >= 10 * GB) /* 10 GB */ { - PartSize = PartSize / 1073741824; + PartSize = PartSize / GB; Unit = MUIGetString(STRING_GB); } else #endif - if (PartSize >= 10485760) /* 10 MB */ + if (PartSize >= 10 * MB) /* 10 MB */ { - PartSize = PartSize / 1048576; + PartSize = PartSize / MB; Unit = MUIGetString(STRING_MB); } else { - PartSize = PartSize / 1024; + PartSize = PartSize / KB; Unit = MUIGetString(STRING_KB); } @@ -2771,15 +2771,15 @@ DeletePartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2980,27 +2980,27 @@ SelectFileSystemPage(PINPUT_RECORD Ir) /* Adjust disk size */ DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; DiskUnit = MUIGetString(STRING_GB); } else { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; DiskUnit = MUIGetString(STRING_MB); } /* Adjust partition size */ PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; - if (PartSize >= 10737418240) /* 10 GB */ + if (PartSize >= 10 * GB) /* 10 GB */ { - PartSize = PartSize / 1073741824; + PartSize = PartSize / GB; PartUnit = MUIGetString(STRING_GB); } else { - PartSize = PartSize / 1048576; + PartSize = PartSize / MB; PartUnit = MUIGetString(STRING_MB); }
6 years, 2 months
1
0
0
0
04/08: [SETUPLIB] IniCacheSave(): use the OBJ_CASE_INSENSITIVE flag.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a95581c4c2d376402d0d9…
commit a95581c4c2d376402d0d94956ca2efff820e59a9 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Tue Aug 8 13:54:23 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Oct 27 03:17:57 2018 +0200 [SETUPLIB] IniCacheSave(): use the OBJ_CASE_INSENSITIVE flag. svn path=/branches/setup_improvements/; revision=75507 --- base/setup/lib/inicache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/setup/lib/inicache.c b/base/setup/lib/inicache.c index de0d6f6d92..26e4bf34af 100644 --- a/base/setup/lib/inicache.c +++ b/base/setup/lib/inicache.c @@ -1055,7 +1055,7 @@ IniCacheSave( InitializeObjectAttributes(&ObjectAttributes, &Name, - 0, + OBJ_CASE_INSENSITIVE, NULL, NULL);
6 years, 2 months
1
0
0
0
03/08: [USETUP] Move SetDefaultPagefile() into settings.c and remove the now-empty registry.c/.h files.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7d0f6f02abac6b2d41630…
commit 7d0f6f02abac6b2d41630de5beafa0c03498c0e2 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Fri Jun 30 22:46:15 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Oct 27 03:17:41 2018 +0200 [USETUP] Move SetDefaultPagefile() into settings.c and remove the now-empty registry.c/.h files. svn path=/branches/setup_improvements/; revision=75250 --- base/setup/usetup/CMakeLists.txt | 1 - base/setup/usetup/registry.c | 70 ---------------------------------------- base/setup/usetup/registry.h | 33 ------------------- base/setup/usetup/settings.c | 46 ++++++++++++++++++++------ base/setup/usetup/settings.h | 6 +++- base/setup/usetup/usetup.h | 1 - 6 files changed, 41 insertions(+), 116 deletions(-) diff --git a/base/setup/usetup/CMakeLists.txt b/base/setup/usetup/CMakeLists.txt index 21d15544f4..66a22fcbb5 100644 --- a/base/setup/usetup/CMakeLists.txt +++ b/base/setup/usetup/CMakeLists.txt @@ -27,7 +27,6 @@ list(APPEND SOURCE mui.c partlist.c progress.c - registry.c settings.c usetup.c usetup.h) diff --git a/base/setup/usetup/registry.c b/base/setup/usetup/registry.c deleted file mode 100644 index f8e1d72fc8..0000000000 --- a/base/setup/usetup/registry.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * ReactOS kernel - * Copyright (C) 2003 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS text-mode setup - * FILE: base/setup/usetup/registry.c - * PURPOSE: Registry creation functions - * PROGRAMMER: - */ - -/* INCLUDES *****************************************************************/ - -#include "usetup.h" - -#define NDEBUG -#include <debug.h> - -/* FUNCTIONS ****************************************************************/ - -VOID -SetDefaultPagefile( - WCHAR Drive) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); - UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"PagingFiles"); - WCHAR ValueBuffer[] = L"?:\\pagefile.sys 0 0\0"; - HANDLE KeyHandle; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), - NULL); - Status = NtOpenKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - return; - - ValueBuffer[0] = Drive; - - NtSetValueKey(KeyHandle, - &ValueName, - 0, - REG_MULTI_SZ, - (PVOID)&ValueBuffer, - sizeof(ValueBuffer)); - - NtClose(KeyHandle); -} - -/* EOF */ diff --git a/base/setup/usetup/registry.h b/base/setup/usetup/registry.h deleted file mode 100644 index ef53b708ff..0000000000 --- a/base/setup/usetup/registry.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ReactOS kernel - * Copyright (C) 2003 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS text-mode setup - * FILE: base/setup/usetup/registry.h - * PURPOSE: Registry creation functions - * PROGRAMMER: - */ - -#pragma once - -VOID -SetDefaultPagefile( - WCHAR Drive); - -/* EOF */ diff --git a/base/setup/usetup/settings.c b/base/setup/usetup/settings.c index d358f85e39..8aaa528b0e 100644 --- a/base/setup/usetup/settings.c +++ b/base/setup/usetup/settings.c @@ -179,7 +179,6 @@ cleanup: return ret; } - static BOOLEAN GetComputerIdentifier( @@ -374,7 +373,6 @@ CreateComputerTypeList( return List; } - static BOOLEAN GetDisplayIdentifier( @@ -541,7 +539,6 @@ GetDisplayIdentifier( return FALSE; } - PGENERIC_LIST CreateDisplayDriverList( HINF InfFile) @@ -670,7 +667,6 @@ ProcessComputerFiles( return TRUE; } - BOOLEAN ProcessDisplayRegistry( HINF InfFile, @@ -829,7 +825,6 @@ ProcessDisplayRegistry( return TRUE; } - BOOLEAN ProcessLocaleRegistry( PGENERIC_LIST List) @@ -991,14 +986,12 @@ CreateKeyboardDriverList( return List; } - ULONG GetDefaultLanguageIndex(VOID) { return DefaultLanguageIndex; } - PGENERIC_LIST CreateLanguageList( HINF InfFile, @@ -1077,7 +1070,6 @@ CreateLanguageList( return List; } - PGENERIC_LIST CreateKeyboardLayoutList( HINF InfFile, @@ -1214,7 +1206,6 @@ ProcessKeyboardLayoutRegistry( return TRUE; } - #if 0 BOOLEAN ProcessKeyboardLayoutFiles( @@ -1224,7 +1215,6 @@ ProcessKeyboardLayoutFiles( } #endif - BOOLEAN SetGeoID( PWCHAR Id) @@ -1267,4 +1257,40 @@ SetGeoID( return TRUE; } + +BOOLEAN +SetDefaultPagefile( + WCHAR Drive) +{ + NTSTATUS Status; + HANDLE KeyHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); + UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"PagingFiles"); + WCHAR ValueBuffer[] = L"?:\\pagefile.sys 0 0\0"; + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), + NULL); + Status = NtOpenKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + return FALSE; + + ValueBuffer[0] = Drive; + + NtSetValueKey(KeyHandle, + &ValueName, + 0, + REG_MULTI_SZ, + (PVOID)&ValueBuffer, + sizeof(ValueBuffer)); + + NtClose(KeyHandle); + return TRUE; +} + /* EOF */ diff --git a/base/setup/usetup/settings.h b/base/setup/usetup/settings.h index 1fce8f7735..3ecabd8e52 100644 --- a/base/setup/usetup/settings.h +++ b/base/setup/usetup/settings.h @@ -21,7 +21,7 @@ * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/settings.h * PURPOSE: Device settings support functions - * PROGRAMMER: + * PROGRAMMERS: Colin Finck */ #pragma once @@ -78,4 +78,8 @@ BOOLEAN SetGeoID( PWCHAR Id); +BOOLEAN +SetDefaultPagefile( + WCHAR Drive); + /* EOF */ diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h index ca7fed0671..2134fcdb8c 100644 --- a/base/setup/usetup/usetup.h +++ b/base/setup/usetup/usetup.h @@ -62,7 +62,6 @@ #include "inffile.h" #include "progress.h" #include "filequeue.h" -#include "registry.h" #include "fslist.h" #include "partlist.h" #include "cabinet.h"
6 years, 2 months
1
0
0
0
02/08: [USETUP] Move Setup[Delete|Copy|Move]File() from usetup code into the setuplib's filesup.c .
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2268b3d64512f93fdeb0a…
commit 2268b3d64512f93fdeb0a8c5e1591f9e85db879e Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Fri Jun 30 22:28:06 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Oct 27 03:17:29 2018 +0200 [USETUP] Move Setup[Delete|Copy|Move]File() from usetup code into the setuplib's filesup.c . Remove the commented-out IsValidPath() in that file, and remove as well the temporary prototypes in regutil.c . svn path=/branches/setup_improvements/; revision=75249 --- base/setup/lib/filesup.c | 457 ++++++++++++++++++++++++++++++++++++++++++++ base/setup/lib/filesup.h | 25 ++- base/setup/lib/regutil.c | 21 -- base/setup/usetup/filesup.c | 448 +------------------------------------------ base/setup/usetup/filesup.h | 35 +--- 5 files changed, 480 insertions(+), 506 deletions(-) diff --git a/base/setup/lib/filesup.c b/base/setup/lib/filesup.c index c6314c222e..03d1ad8003 100644 --- a/base/setup/lib/filesup.c +++ b/base/setup/lib/filesup.c @@ -12,8 +12,465 @@ #define NDEBUG #include <debug.h> + +// ACHTUNG! HAXX FIXME!! +#define _SEH2_TRY +#define _SEH2_LEAVE goto __SEH2_FINALLY__label; +#define _SEH2_FINALLY __SEH2_FINALLY__label: +#define _SEH2_END + + /* FUNCTIONS ****************************************************************/ +// TODO: Move SetupCreateDirectory later... + +NTSTATUS +SetupDeleteFile( + IN PCWSTR FileName, + IN BOOLEAN ForceDelete) // ForceDelete can be used to delete read-only files +{ + NTSTATUS Status; + UNICODE_STRING NtPathU; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + FILE_DISPOSITION_INFORMATION FileDispInfo; + BOOLEAN RetryOnce = FALSE; + + /* Open the directory name that was passed in */ + RtlInitUnicodeString(&NtPathU, FileName); + InitializeObjectAttributes(&ObjectAttributes, + &NtPathU, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + +Retry: // We go back there once if RetryOnce == TRUE + Status = NtOpenFile(&FileHandle, + DELETE | FILE_READ_ATTRIBUTES | + (RetryOnce ? FILE_WRITE_ATTRIBUTES : 0), + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile failed with Status 0x%08lx\n", Status); + return Status; + } + + if (RetryOnce) + { + FILE_BASIC_INFORMATION FileInformation; + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInformation, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile failed with Status 0x%08lx\n", Status); + NtClose(FileHandle); + return Status; + } + + FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInformation, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile failed with Status 0x%08lx\n", Status); + return Status; + } + } + + /* Ask for the file to be deleted */ + FileDispInfo.DeleteFile = TRUE; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileDispInfo, + sizeof(FILE_DISPOSITION_INFORMATION), + FileDispositionInformation); + NtClose(FileHandle); + + if (!NT_SUCCESS(Status)) + DPRINT1("Deletion of file '%S' failed, Status 0x%08lx\n", FileName, Status); + + // FIXME: Check the precise value of Status! + if (!NT_SUCCESS(Status) && ForceDelete && !RetryOnce) + { + /* Retry once */ + RetryOnce = TRUE; + goto Retry; + } + + /* Return result to the caller */ + return Status; +} + +NTSTATUS +SetupCopyFile( + IN PCWSTR SourceFileName, + IN PCWSTR DestinationFileName, + IN BOOLEAN FailIfExists) +{ + NTSTATUS Status; + UNICODE_STRING FileName; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandleSource; + HANDLE FileHandleDest; + IO_STATUS_BLOCK IoStatusBlock; + FILE_STANDARD_INFORMATION FileStandard; + FILE_BASIC_INFORMATION FileBasic; + ULONG RegionSize; + HANDLE SourceFileSection; + PVOID SourceFileMap = NULL; + SIZE_T SourceSectionSize = 0; + LARGE_INTEGER ByteOffset; + + RtlInitUnicodeString(&FileName, SourceFileName); + + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandleSource, + GENERIC_READ, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SEQUENTIAL_ONLY); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName); + goto done; + } + + Status = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock, + &FileStandard, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile failed: %x\n", Status); + goto closesrc; + } + + Status = NtQueryInformationFile(FileHandleSource, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile failed: %x\n", Status); + goto closesrc; + } + + Status = NtCreateSection(&SourceFileSection, + SECTION_MAP_READ, + NULL, + NULL, + PAGE_READONLY, + SEC_COMMIT, + FileHandleSource); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName); + goto closesrc; + } + + Status = NtMapViewOfSection(SourceFileSection, + NtCurrentProcess(), + &SourceFileMap, + 0, + 0, + NULL, + &SourceSectionSize, + ViewUnmap, + 0, + PAGE_READONLY); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName); + goto closesrcsec; + } + + RtlInitUnicodeString(&FileName, DestinationFileName); + + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtCreateFile(&FileHandleDest, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FileBasic.FileAttributes, // FILE_ATTRIBUTE_NORMAL, + 0, + FailIfExists ? FILE_CREATE : FILE_OVERWRITE_IF, + FILE_NO_INTERMEDIATE_BUFFERING | + FILE_SEQUENTIAL_ONLY | + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + /* + * Open may have failed because the file to overwrite + * is in readonly mode. + */ + if (Status == STATUS_ACCESS_DENIED) + { + FILE_BASIC_INFORMATION FileBasicInfo; + + /* Reattempt to open it with limited access */ + Status = NtCreateFile(&FileHandleDest, + FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NO_INTERMEDIATE_BUFFERING | + FILE_SEQUENTIAL_ONLY | + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + /* Fail for real if we cannot open it that way */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName); + goto unmapsrcsec; + } + + /* Zero our basic info, just to set attributes */ + RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo)); + /* Reset attributes to normal, no read-only */ + FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; + /* + * We basically don't care about whether it succeed: + * if it didn't, later open will fail. + */ + NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasicInfo, + sizeof(FileBasicInfo), FileBasicInformation); + + /* Close file */ + NtClose(FileHandleDest); + + /* And re-attempt overwrite */ + Status = NtCreateFile(&FileHandleDest, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_NO_INTERMEDIATE_BUFFERING | + FILE_SEQUENTIAL_ONLY | + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + } + + /* We failed */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName); + goto unmapsrcsec; + } + } + + RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart); + IoStatusBlock.Status = 0; + ByteOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandleDest, + NULL, + NULL, + NULL, + &IoStatusBlock, + SourceFileMap, + RegionSize, + &ByteOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", + Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize); + goto closedest; + } + + /* Copy file date/time from source file */ + Status = NtSetInformationFile(FileHandleDest, + &IoStatusBlock, + &FileBasic, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile failed: %x\n", Status); + goto closedest; + } + + /* Shorten the file back to its real size after completing the write */ + Status = NtSetInformationFile(FileHandleDest, + &IoStatusBlock, + &FileStandard.EndOfFile, + sizeof(FILE_END_OF_FILE_INFORMATION), + FileEndOfFileInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile failed: %x\n", Status); + } + +closedest: + NtClose(FileHandleDest); + +unmapsrcsec: + NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap); + +closesrcsec: + NtClose(SourceFileSection); + +closesrc: + NtClose(FileHandleSource); + +done: + return Status; +} + +/* + * Synchronized with its kernel32 counterpart, but we don't manage reparse points here. + */ +NTSTATUS +SetupMoveFile( + IN PCWSTR ExistingFileName, + IN PCWSTR NewFileName, + IN ULONG Flags) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + PFILE_RENAME_INFORMATION RenameInfo; + UNICODE_STRING NewPathU, ExistingPathU; + HANDLE SourceHandle = NULL; + BOOLEAN ReplaceIfExists; + + RtlInitUnicodeString(&ExistingPathU, ExistingFileName); + RtlInitUnicodeString(&NewPathU, NewFileName); + + _SEH2_TRY + { + ReplaceIfExists = !!(Flags & MOVEFILE_REPLACE_EXISTING); + + /* Unless we manage a proper opening, we'll attempt to reopen without reparse support */ + InitializeObjectAttributes(&ObjectAttributes, + &ExistingPathU, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + /* Attempt to open source file */ + Status = NtOpenFile(&SourceHandle, + FILE_READ_ATTRIBUTES | DELETE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_OPEN_FOR_BACKUP_INTENT | ((Flags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0)); + if (!NT_SUCCESS(Status)) + { + if (Status != STATUS_INVALID_PARAMETER) + { + _SEH2_LEAVE; + } + } + + /* At that point, we MUST have a source handle */ + ASSERT(SourceHandle); + + /* Allocate renaming buffer and fill it */ + RenameInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(FILE_RENAME_INFORMATION)); + if (RenameInfo == NULL) + { + Status = STATUS_NO_MEMORY; + _SEH2_LEAVE; + } + + RtlCopyMemory(&RenameInfo->FileName, NewPathU.Buffer, NewPathU.Length); + RenameInfo->ReplaceIfExists = ReplaceIfExists; + RenameInfo->RootDirectory = NULL; + RenameInfo->FileNameLength = NewPathU.Length; + + /* Attempt to rename the file */ + Status = NtSetInformationFile(SourceHandle, + &IoStatusBlock, + RenameInfo, + NewPathU.Length + sizeof(FILE_RENAME_INFORMATION), + FileRenameInformation); + RtlFreeHeap(RtlGetProcessHeap(), 0, RenameInfo); + if (NT_SUCCESS(Status)) + { + /* If it succeeded, all fine, quit */ + _SEH2_LEAVE; + } + /* + * If we failed for any other reason than not the same device, fail. + * If we failed because of different devices, only allow renaming + * if user allowed copy. + */ + if (Status != STATUS_NOT_SAME_DEVICE || !(Flags & MOVEFILE_COPY_ALLOWED)) + { + /* ReactOS hack! To be removed once all FSD have proper renaming support + * Just leave status to error and leave + */ + if (Status == STATUS_NOT_IMPLEMENTED) + { + DPRINT1("Forcing copy, renaming not supported by FSD\n"); + } + else + { + _SEH2_LEAVE; + } + } + + /* Close the source file */ + NtClose(SourceHandle); + SourceHandle = NULL; + + /* Perform the file copy */ + Status = SetupCopyFile(ExistingFileName, + NewFileName, + !ReplaceIfExists); + + /* If it succeeded, delete the source file */ + if (NT_SUCCESS(Status)) + { + /* Force-delete files even if read-only */ + SetupDeleteFile(ExistingFileName, TRUE); + } + } + _SEH2_FINALLY + { + if (SourceHandle) + NtClose(SourceHandle); + } + _SEH2_END; + + return Status; +} + NTSTATUS ConcatPathsV( IN OUT PWSTR PathBuffer, diff --git a/base/setup/lib/filesup.h b/base/setup/lib/filesup.h index abc1b1c58d..0b82069185 100644 --- a/base/setup/lib/filesup.h +++ b/base/setup/lib/filesup.h @@ -7,14 +7,31 @@ #pragma once -#if 0 +NTSTATUS +SetupDeleteFile( + IN PCWSTR FileName, + IN BOOLEAN ForceDelete); // ForceDelete can be used to delete read-only files -BOOLEAN -IsValidPath( - IN PCWSTR InstallDir); +NTSTATUS +SetupCopyFile( + IN PCWSTR SourceFileName, + IN PCWSTR DestinationFileName, + IN BOOLEAN FailIfExists); + +#ifndef _WINBASE_ + +#define MOVEFILE_REPLACE_EXISTING 1 +#define MOVEFILE_COPY_ALLOWED 2 +#define MOVEFILE_WRITE_THROUGH 8 #endif +NTSTATUS +SetupMoveFile( + IN PCWSTR ExistingFileName, + IN PCWSTR NewFileName, + IN ULONG Flags); + NTSTATUS ConcatPathsV( IN OUT PWSTR PathBuffer, diff --git a/base/setup/lib/regutil.c b/base/setup/lib/regutil.c index eebbac0feb..2ede224164 100644 --- a/base/setup/lib/regutil.c +++ b/base/setup/lib/regutil.c @@ -19,27 +19,6 @@ #define NDEBUG #include <debug.h> - -// HACK!! These functions should actually be moved in the setup lib! -// For the moment, see usetup/filesup.c (or .h) -#if 1 - -NTSTATUS -SetupCopyFile( - IN PCWSTR SourceFileName, - IN PCWSTR DestinationFileName, - IN BOOLEAN FailIfExists); - -#define MOVEFILE_REPLACE_EXISTING 1 - -NTSTATUS -SetupMoveFile( - IN PCWSTR ExistingFileName, - IN PCWSTR NewFileName, - IN ULONG Flags); - -#endif - /* FUNCTIONS ****************************************************************/ /* diff --git a/base/setup/usetup/filesup.c b/base/setup/usetup/filesup.c index 06d9d86344..261bfd9fa8 100644 --- a/base/setup/usetup/filesup.c +++ b/base/setup/usetup/filesup.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/filesup.c * PURPOSE: File support functions - * PROGRAMMER: Casper S. Hornstrup (chorns(a)users.sourceforge.net) + * PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net) */ /* INCLUDES *****************************************************************/ @@ -142,451 +142,6 @@ done: return Status; } -NTSTATUS -SetupDeleteFile( - IN PCWSTR FileName, - IN BOOLEAN ForceDelete) // ForceDelete can be used to delete read-only files -{ - NTSTATUS Status; - UNICODE_STRING NtPathU; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE FileHandle; - FILE_DISPOSITION_INFORMATION FileDispInfo; - BOOLEAN RetryOnce = FALSE; - - /* Open the directory name that was passed in */ - RtlInitUnicodeString(&NtPathU, FileName); - InitializeObjectAttributes(&ObjectAttributes, - &NtPathU, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - -Retry: // We go back there once if RetryOnce == TRUE - Status = NtOpenFile(&FileHandle, - DELETE | FILE_READ_ATTRIBUTES | - (RetryOnce ? FILE_WRITE_ATTRIBUTES : 0), - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - FILE_NON_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenFile failed with Status 0x%08lx\n", Status); - return Status; - } - - if (RetryOnce) - { - FILE_BASIC_INFORMATION FileInformation; - - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInformation, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryInformationFile failed with Status 0x%08lx\n", Status); - NtClose(FileHandle); - return Status; - } - - FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL; - Status = NtSetInformationFile(FileHandle, - &IoStatusBlock, - &FileInformation, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - NtClose(FileHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSetInformationFile failed with Status 0x%08lx\n", Status); - return Status; - } - } - - /* Ask for the file to be deleted */ - FileDispInfo.DeleteFile = TRUE; - Status = NtSetInformationFile(FileHandle, - &IoStatusBlock, - &FileDispInfo, - sizeof(FILE_DISPOSITION_INFORMATION), - FileDispositionInformation); - NtClose(FileHandle); - - if (!NT_SUCCESS(Status)) - DPRINT1("Deletion of file '%S' failed, Status 0x%08lx\n", FileName, Status); - - // FIXME: Check the precise value of Status! - if (!NT_SUCCESS(Status) && ForceDelete && !RetryOnce) - { - /* Retry once */ - RetryOnce = TRUE; - goto Retry; - } - - /* Return result to the caller */ - return Status; -} - -NTSTATUS -SetupCopyFile( - IN PCWSTR SourceFileName, - IN PCWSTR DestinationFileName, - IN BOOLEAN FailIfExists) -{ - NTSTATUS Status; - UNICODE_STRING FileName; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE FileHandleSource; - HANDLE FileHandleDest; - IO_STATUS_BLOCK IoStatusBlock; - FILE_STANDARD_INFORMATION FileStandard; - FILE_BASIC_INFORMATION FileBasic; - ULONG RegionSize; - HANDLE SourceFileSection; - PVOID SourceFileMap = NULL; - SIZE_T SourceSectionSize = 0; - LARGE_INTEGER ByteOffset; - - RtlInitUnicodeString(&FileName, SourceFileName); - - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenFile(&FileHandleSource, - GENERIC_READ, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ, - FILE_SEQUENTIAL_ONLY); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName); - goto done; - } - - Status = NtQueryInformationFile(FileHandleSource, - &IoStatusBlock, - &FileStandard, - sizeof(FILE_STANDARD_INFORMATION), - FileStandardInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryInformationFile failed: %x\n", Status); - goto closesrc; - } - - Status = NtQueryInformationFile(FileHandleSource, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryInformationFile failed: %x\n", Status); - goto closesrc; - } - - Status = NtCreateSection(&SourceFileSection, - SECTION_MAP_READ, - NULL, - NULL, - PAGE_READONLY, - SEC_COMMIT, - FileHandleSource); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName); - goto closesrc; - } - - Status = NtMapViewOfSection(SourceFileSection, - NtCurrentProcess(), - &SourceFileMap, - 0, - 0, - NULL, - &SourceSectionSize, - ViewUnmap, - 0, - PAGE_READONLY); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName); - goto closesrcsec; - } - - RtlInitUnicodeString(&FileName, DestinationFileName); - - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtCreateFile(&FileHandleDest, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FileBasic.FileAttributes, // FILE_ATTRIBUTE_NORMAL, - 0, - FailIfExists ? FILE_CREATE : FILE_OVERWRITE_IF, - FILE_NO_INTERMEDIATE_BUFFERING | - FILE_SEQUENTIAL_ONLY | - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - /* Open may have failed because the file to overwrite - * is in readonly mode - */ - if (Status == STATUS_ACCESS_DENIED) - { - FILE_BASIC_INFORMATION FileBasicInfo; - - /* Reattempt to open it with limited access */ - Status = NtCreateFile(&FileHandleDest, - FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OPEN, - FILE_NO_INTERMEDIATE_BUFFERING | - FILE_SEQUENTIAL_ONLY | - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - /* Fail for real if we cannot open it that way */ - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName); - goto unmapsrcsec; - } - - /* Zero our basic info, just to set attributes */ - RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo)); - /* Reset attributes to normal, no read-only */ - FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; - /* We basically don't care about whether it succeed: - * if it didn't, later open will fail - */ - NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasicInfo, - sizeof(FileBasicInfo), FileBasicInformation); - - /* Close file */ - NtClose(FileHandleDest); - - /* And re-attempt overwrite */ - Status = NtCreateFile(&FileHandleDest, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OVERWRITE_IF, - FILE_NO_INTERMEDIATE_BUFFERING | - FILE_SEQUENTIAL_ONLY | - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - } - - /* We failed */ - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName); - goto unmapsrcsec; - } - } - - RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart); - IoStatusBlock.Status = 0; - ByteOffset.QuadPart = 0ULL; - Status = NtWriteFile(FileHandleDest, - NULL, - NULL, - NULL, - &IoStatusBlock, - SourceFileMap, - RegionSize, - &ByteOffset, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", - Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize); - goto closedest; - } - - /* Copy file date/time from source file */ - Status = NtSetInformationFile(FileHandleDest, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSetInformationFile failed: %x\n", Status); - goto closedest; - } - - /* Shorten the file back to its real size after completing the write */ - Status = NtSetInformationFile(FileHandleDest, - &IoStatusBlock, - &FileStandard.EndOfFile, - sizeof(FILE_END_OF_FILE_INFORMATION), - FileEndOfFileInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSetInformationFile failed: %x\n", Status); - } - -closedest: - NtClose(FileHandleDest); - -unmapsrcsec: - NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap); - -closesrcsec: - NtClose(SourceFileSection); - -closesrc: - NtClose(FileHandleSource); - -done: - return Status; -} - -/* - * Synchronized with its kernel32 counterpart, but we don't manage reparse points here. - */ -NTSTATUS -SetupMoveFile( - IN PCWSTR ExistingFileName, - IN PCWSTR NewFileName, - IN ULONG Flags) -{ - NTSTATUS Status; - IO_STATUS_BLOCK IoStatusBlock; - OBJECT_ATTRIBUTES ObjectAttributes; - PFILE_RENAME_INFORMATION RenameInfo; - UNICODE_STRING NewPathU, ExistingPathU; - HANDLE SourceHandle = NULL; - BOOLEAN ReplaceIfExists; - - RtlInitUnicodeString(&ExistingPathU, ExistingFileName); - RtlInitUnicodeString(&NewPathU, NewFileName); - - _SEH2_TRY - { - ReplaceIfExists = !!(Flags & MOVEFILE_REPLACE_EXISTING); - - /* Unless we manage a proper opening, we'll attempt to reopen without reparse support */ - InitializeObjectAttributes(&ObjectAttributes, - &ExistingPathU, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - /* Attempt to open source file */ - Status = NtOpenFile(&SourceHandle, - FILE_READ_ATTRIBUTES | DELETE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - FILE_OPEN_FOR_BACKUP_INTENT | ((Flags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0)); - if (!NT_SUCCESS(Status)) - { - if (Status != STATUS_INVALID_PARAMETER) - { - _SEH2_LEAVE; - } - } - - /* At that point, we MUST have a source handle */ - ASSERT(SourceHandle); - - /* Allocate renaming buffer and fill it */ - RenameInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(FILE_RENAME_INFORMATION)); - if (RenameInfo == NULL) - { - Status = STATUS_NO_MEMORY; - _SEH2_LEAVE; - } - - RtlCopyMemory(&RenameInfo->FileName, NewPathU.Buffer, NewPathU.Length); - RenameInfo->ReplaceIfExists = ReplaceIfExists; - RenameInfo->RootDirectory = NULL; - RenameInfo->FileNameLength = NewPathU.Length; - - /* Attempt to rename the file */ - Status = NtSetInformationFile(SourceHandle, - &IoStatusBlock, - RenameInfo, - NewPathU.Length + sizeof(FILE_RENAME_INFORMATION), - FileRenameInformation); - RtlFreeHeap(RtlGetProcessHeap(), 0, RenameInfo); - if (NT_SUCCESS(Status)) - { - /* If it succeeded, all fine, quit */ - _SEH2_LEAVE; - } - /* - * If we failed for any other reason than not the same device, fail. - * If we failed because of different devices, only allow renaming - * if user allowed copy. - */ - if (Status != STATUS_NOT_SAME_DEVICE || !(Flags & MOVEFILE_COPY_ALLOWED)) - { - /* ReactOS hack! To be removed once all FSD have proper renaming support - * Just leave status to error and leave - */ - if (Status == STATUS_NOT_IMPLEMENTED) - { - DPRINT1("Forcing copy, renaming not supported by FSD\n"); - } - else - { - _SEH2_LEAVE; - } - } - - /* Close the source file */ - NtClose(SourceHandle); - SourceHandle = NULL; - - /* Perform the file copy */ - Status = SetupCopyFile(ExistingFileName, - NewFileName, - !ReplaceIfExists); - - /* If it succeeded, delete the source file */ - if (NT_SUCCESS(Status)) - { - /* Force-delete files even if read-only */ - SetupDeleteFile(ExistingFileName, TRUE); - } - } - _SEH2_FINALLY - { - if (SourceHandle) - NtClose(SourceHandle); - } - _SEH2_END; - - return Status; -} - NTSTATUS SetupExtractFile( PWCHAR CabinetFileName, @@ -665,7 +220,6 @@ SetupExtractFile( return STATUS_SUCCESS; } - BOOLEAN IsValidPath( IN PCWSTR InstallDir) diff --git a/base/setup/usetup/filesup.h b/base/setup/usetup/filesup.h index a8cc7940a7..884d384efa 100644 --- a/base/setup/usetup/filesup.h +++ b/base/setup/usetup/filesup.h @@ -3,7 +3,7 @@ * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/filesup.h * PURPOSE: File support functions - * PROGRAMMER: + * PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net) */ #pragma once @@ -12,45 +12,12 @@ NTSTATUS SetupCreateDirectory( PWCHAR DirectoryName); -NTSTATUS -SetupDeleteFile( - IN PCWSTR FileName, - IN BOOLEAN ForceDelete); // ForceDelete can be used to delete read-only files - -NTSTATUS -SetupCopyFile( - IN PCWSTR SourceFileName, - IN PCWSTR DestinationFileName, - IN BOOLEAN FailIfExists); - -#ifndef _WINBASE_ - -#define MOVEFILE_REPLACE_EXISTING 1 -#define MOVEFILE_COPY_ALLOWED 2 -#define MOVEFILE_WRITE_THROUGH 8 - -#endif - -// ACHTUNG! HAXX FIXME!! -#define _SEH2_TRY -#define _SEH2_LEAVE goto __SEH2_FINALLY__label; -#define _SEH2_FINALLY __SEH2_FINALLY__label: -#define _SEH2_END - - -NTSTATUS -SetupMoveFile( - IN PCWSTR ExistingFileName, - IN PCWSTR NewFileName, - IN ULONG Flags); - NTSTATUS SetupExtractFile( PWCHAR CabinetFileName, PWCHAR SourceFileName, PWCHAR DestinationFileName); - BOOLEAN IsValidPath( IN PCWSTR InstallDir);
6 years, 2 months
1
0
0
0
01/08: [USETUP][SETUPLIB] Split the registry helper code.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=60d9ea76d1252c80b85e8…
commit 60d9ea76d1252c80b85e8424e4a84081c20855b1 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Fri Jun 30 19:07:02 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Oct 27 03:16:47 2018 +0200 [USETUP][SETUPLIB] Split the registry helper code. Split the registry helper code into registry utility functions (create/mount/unmount/verify hives) and registry creation code (the rest: initializing the system hives) and move it in the setup library. svn path=/branches/setup_improvements/; revision=75247 [USETUP][SETUPLIB] Improve how the Setup* INF APIs are interfaced in the code. Define prototypes compatible (including their calling convention) with the ones defined by setupapi (.h/.dll) so that it can be possible to either use an internal implementation of these functions (via the INFLIB library) as currently being done, or using imported setupapi functions, as would be done by the future 1st-stage GUI installer. [SETUPLIB] Cleanup the registry.c file and use the infsupp.h header. svn path=/branches/setup_improvements/; revision=75345 svn path=/branches/setup_improvements/; revision=75346 [USETUP][SETUPLIB] Move some INF-related code from usetup to the setuplib. - Move the generic INF_GetDataField() and INF_GetData() helpers to setuplib, and rework them a bit so that they explicitly call setupapi functions (or implementations thereof when being used in usetup); - Rework the headers in accordance; - Fix compilation in lib/registry.c . - Fix compilation when these headers are used withing usetup (who doesn't use setupapi.dll) and "reactos" (the 1st-stage GUI installer that uses setupapi.dll). svn path=/branches/setup_improvements/; revision=75515 svn path=/branches/setup_improvements/; revision=75537 svn path=/branches/setup_improvements/; revision=75538 --- base/setup/lib/CMakeLists.txt | 3 + base/setup/lib/errorcode.h | 7 +- base/setup/lib/infsupp.c | 119 +++ base/setup/lib/infsupp.h | 164 ++++ base/setup/{usetup => lib}/registry.c | 489 +---------- base/setup/{usetup => lib}/registry.h | 21 +- base/setup/lib/regutil.c | 457 ++++++++++ base/setup/lib/regutil.h | 80 ++ base/setup/lib/setuplib.h | 2 + base/setup/usetup/inffile.c | 159 +++- base/setup/usetup/inffile.h | 84 +- base/setup/usetup/registry.c | 1475 +-------------------------------- base/setup/usetup/registry.h | 31 - base/setup/usetup/usetup.h | 1 - 14 files changed, 1023 insertions(+), 2069 deletions(-) diff --git a/base/setup/lib/CMakeLists.txt b/base/setup/lib/CMakeLists.txt index 819ecf34bd..c1164c809d 100644 --- a/base/setup/lib/CMakeLists.txt +++ b/base/setup/lib/CMakeLists.txt @@ -5,10 +5,13 @@ list(APPEND SOURCE filesup.c fsutil.c genlist.c + infsupp.c inicache.c ntverrsrc.c osdetect.c partlist.c + registry.c + regutil.c precomp.h) add_library(setuplib ${SOURCE}) diff --git a/base/setup/lib/errorcode.h b/base/setup/lib/errorcode.h index 963e137bcd..b440e4e8d3 100644 --- a/base/setup/lib/errorcode.h +++ b/base/setup/lib/errorcode.h @@ -7,7 +7,12 @@ #pragma once -typedef enum +/* setupapi.h defines ERROR_NOT_INSTALLED with another meaning */ +#ifdef ERROR_NOT_INSTALLED +#undef ERROR_NOT_INSTALLED +#endif + +typedef enum _ERROR_NUMBER { NOT_AN_ERROR = 0, // ERROR_SUCCESS, ERROR_NOT_INSTALLED, diff --git a/base/setup/lib/infsupp.c b/base/setup/lib/infsupp.c new file mode 100644 index 0000000000..265585712e --- /dev/null +++ b/base/setup/lib/infsupp.c @@ -0,0 +1,119 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Setup Library + * FILE: base/setup/lib/infsupp.c + * PURPOSE: Interfacing with Setup* API .inf files support functions + * PROGRAMMERS: Hervé Poussineau + * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) + */ + +/* INCLUDES *****************************************************************/ + +#include "precomp.h" +#include "infsupp.h" + +#define NDEBUG +#include <debug.h> + +/* HELPER FUNCTIONS **********************************************************/ + +BOOLEAN +INF_GetDataField( + IN PINFCONTEXT Context, + IN ULONG FieldIndex, + OUT PWCHAR *Data) +{ +#if 0 + + BOOL Success; + PWCHAR InfData; + DWORD dwSize; + + *Data = NULL; + + Success = SetupGetStringFieldW(Context, + FieldIndex, + NULL, + 0, + &dwSize); + if (!Success) + return FALSE; + + InfData = RtlAllocateHeap(ProcessHeap, 0, dwSize * sizeof(WCHAR)); + if (!InfData) + return FALSE; + + Success = SetupGetStringFieldW(Context, + FieldIndex, + InfData, + dwSize, + NULL); + if (!Success) + { + RtlFreeHeap(ProcessHeap, 0, InfData); + return FALSE; + } + + *Data = InfData; + return TRUE; + +#else + + *Data = (PWCHAR)pSetupGetField(Context, FieldIndex); + return !!*Data; + +#endif +} + +BOOLEAN +INF_GetData( + IN PINFCONTEXT Context, + OUT PWCHAR *Key, + OUT PWCHAR *Data) +{ + BOOL Success; + PWCHAR InfData[2] = {NULL, NULL}; + + if (Key) + *Key = NULL; + + if (Data) + *Data = NULL; + + /* + * Verify that the INF file has only one value field, in addition to its key name. + * Note that SetupGetFieldCount() does not count the key name as a field. + */ + if (SetupGetFieldCount(Context) != 1) + { + DPRINT1("SetupGetFieldCount != 1\n"); + return FALSE; + } + + if (Key) + { + Success = INF_GetDataField(Context, 0, &InfData[0]); + if (!Success) + return FALSE; + } + + if (Data) + { + Success = INF_GetDataField(Context, 1, &InfData[1]); + if (!Success) + { + INF_FreeData(InfData[0]); + return FALSE; + } + } + + if (Key) + *Key = InfData[0]; + + if (Data) + *Data = InfData[1]; + + return TRUE; +} + +/* EOF */ diff --git a/base/setup/lib/infsupp.h b/base/setup/lib/infsupp.h new file mode 100644 index 0000000000..677fb9af2a --- /dev/null +++ b/base/setup/lib/infsupp.h @@ -0,0 +1,164 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Setup Library + * FILE: base/setup/lib/infsupp.h + * PURPOSE: Interfacing with Setup* API .inf files support functions + * PROGRAMMER: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) + */ + +#pragma once + +/* Make setupapi.h to not define the API as exports to the DLL */ +#ifdef __REACTOS__ +#define _SETUPAPI_ +#endif + +// FIXME: Temporary measure until all the users of this header +// (usetup...) use or define SetupAPI-conforming APIs. +#if defined(_SETUPAPI_H_) || defined(_INC_SETUPAPI) + +#include <setupapi.h> + +#else + +typedef PVOID HINF; +typedef struct _INFCONTEXT +{ + HINF Inf; + HINF CurrentInf; + UINT Section; + UINT Line; +} INFCONTEXT, *PINFCONTEXT; + +// #define SetupCloseInfFile InfCloseFile +VOID +WINAPI +SetupCloseInfFile(HINF InfHandle); + +// #define SetupFindFirstLineW InfpFindFirstLineW +BOOL +WINAPI +SetupFindFirstLineW( + IN HINF InfHandle, + IN PCWSTR Section, + IN PCWSTR Key, + IN OUT PINFCONTEXT Context); + +// #define SetupFindNextLine InfFindNextLine +BOOL +WINAPI +SetupFindNextLine(PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut); + +// #define SetupGetFieldCount InfGetFieldCount +LONG +WINAPI +SetupGetFieldCount(PINFCONTEXT Context); + +// #define SetupGetBinaryField InfGetBinaryField +BOOL +WINAPI +SetupGetBinaryField(PINFCONTEXT Context, + ULONG FieldIndex, + PUCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + +// #define SetupGetIntField InfGetIntField +BOOL +WINAPI +SetupGetIntField(PINFCONTEXT Context, + ULONG FieldIndex, + INT *IntegerValue); // PINT + +// #define SetupGetMultiSzFieldW InfGetMultiSzField +BOOL +WINAPI +SetupGetMultiSzFieldW(PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + +// #define SetupGetStringFieldW InfGetStringField +BOOL +WINAPI +SetupGetStringFieldW(PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + +#endif + +/* Lower the MAX_INF_STRING_LENGTH value in order to avoid too much stack usage */ +#undef MAX_INF_STRING_LENGTH +#define MAX_INF_STRING_LENGTH 1024 // Still larger than in infcommon.h + +#ifndef INF_STYLE_WIN4 +#define INF_STYLE_WIN4 0x00000002 +#endif + +#if 0 +typedef PVOID HINF; +typedef struct _INFCONTEXT +{ + HINF Inf; + HINF CurrentInf; + UINT Section; + UINT Line; +} INFCONTEXT, *PINFCONTEXT; +#endif + +C_ASSERT(sizeof(INFCONTEXT) == 2 * sizeof(HINF) + 2 * sizeof(UINT)); + + +/* + * This function corresponds to an undocumented but exported SetupAPI function + * that exists since WinNT4 and is still present in Win10. + * The returned string pointer is a read-only pointer to a string in the + * maintained INF cache, and is always in UNICODE (on NT systems). + */ +PCWSTR +WINAPI +pSetupGetField(PINFCONTEXT Context, + ULONG FieldIndex); + +/* A version of SetupOpenInfFileW with support for a user-provided LCID */ +// #define SetupOpenInfFileExW InfpOpenInfFileW +HINF +WINAPI +SetupOpenInfFileExW( + IN PCWSTR FileName, + IN PCWSTR InfClass, + IN DWORD InfStyle, + IN LCID LocaleId, + OUT PUINT ErrorLine); + + +/* HELPER FUNCTIONS **********************************************************/ + +FORCEINLINE VOID +INF_FreeData(IN PWCHAR InfData) +{ +#if 0 + if (InfData) + RtlFreeHeap(ProcessHeap, 0, InfData); +#else + UNREFERENCED_PARAMETER(InfData); +#endif +} + +BOOLEAN +INF_GetDataField( + IN PINFCONTEXT Context, + IN ULONG FieldIndex, + OUT PWCHAR *Data); + +BOOLEAN +INF_GetData( + IN PINFCONTEXT Context, + OUT PWCHAR *Key, + OUT PWCHAR *Data); + +/* EOF */ diff --git a/base/setup/usetup/registry.c b/base/setup/lib/registry.c similarity index 70% copy from base/setup/usetup/registry.c copy to base/setup/lib/registry.c index 749835c3d7..e36e6a7c76 100644 --- a/base/setup/usetup/registry.c +++ b/base/setup/lib/registry.c @@ -18,15 +18,21 @@ */ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS text-mode setup - * FILE: base/setup/usetup/registry.c + * PROJECT: ReactOS Setup Library + * FILE: base/setup/lib/registry.c * PURPOSE: Registry creation functions - * PROGRAMMER: + * PROGRAMMERS: ... + * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) */ /* INCLUDES *****************************************************************/ -#include "usetup.h" +#include "precomp.h" +#include "filesup.h" +#include "infsupp.h" +#include "regutil.h" + +#include "registry.h" // HACK! #include <strsafe.h> @@ -34,6 +40,9 @@ #define NDEBUG #include <debug.h> + +// #ifdef __REACTOS__ +#if 1 // FIXME: Disable if setupapi.h is included in the code... #define FLG_ADDREG_BINVALUETYPE 0x00000001 #define FLG_ADDREG_NOCLOBBER 0x00000002 #define FLG_ADDREG_DELVAL 0x00000004 @@ -47,6 +56,7 @@ #define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE) #define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE) #define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE) +#endif #ifdef _M_IX86 #define Architecture L"x86" @@ -98,7 +108,7 @@ GetRootKeyByPredefKey( if (!IsPredefKey(KeyHandle)) return NULL; - if (GetPredefKeyIndex(KeyHandle) >= ARRAYSIZE(RootKeys)) + if (Index >= ARRAYSIZE(RootKeys)) return NULL; if (RootKeyMountPoint) @@ -406,115 +416,6 @@ do_reg_operation(HANDLE KeyHandle, return TRUE; } -/* - * This function is similar to the one in dlls/win32/advapi32/reg/reg.c - * TODO: I should review both of them very carefully, because they may need - * some adjustments in their NtCreateKey calls, especially for CreateOptions - * stuff etc... - */ -NTSTATUS -CreateNestedKey(PHANDLE KeyHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - ULONG CreateOptions) -{ - OBJECT_ATTRIBUTES LocalObjectAttributes; - UNICODE_STRING LocalKeyName; - ULONG Disposition; - NTSTATUS Status; - USHORT FullNameLength; - PWCHAR Ptr; - HANDLE LocalKeyHandle; - - Status = NtCreateKey(KeyHandle, - KEY_ALL_ACCESS, - ObjectAttributes, - 0, - NULL, - CreateOptions, - &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status); - if (Status != STATUS_OBJECT_NAME_NOT_FOUND) - { - if (!NT_SUCCESS(Status)) - DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", ObjectAttributes->ObjectName, Status); - - return Status; - } - - /* Copy object attributes */ - RtlCopyMemory(&LocalObjectAttributes, - ObjectAttributes, - sizeof(OBJECT_ATTRIBUTES)); - RtlCreateUnicodeString(&LocalKeyName, - ObjectAttributes->ObjectName->Buffer); - LocalObjectAttributes.ObjectName = &LocalKeyName; - FullNameLength = LocalKeyName.Length; - - /* Remove the last part of the key name and try to create the key again. */ - while (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - Ptr = wcsrchr(LocalKeyName.Buffer, '\\'); - if (Ptr == NULL || Ptr == LocalKeyName.Buffer) - { - Status = STATUS_UNSUCCESSFUL; - break; - } - *Ptr = (WCHAR)0; - LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR); - - Status = NtCreateKey(&LocalKeyHandle, - KEY_CREATE_SUB_KEY, - &LocalObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) - DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status); - } - - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&LocalKeyName); - return Status; - } - - /* Add removed parts of the key name and create them too. */ - while (TRUE) - { - if (LocalKeyName.Length == FullNameLength) - { - Status = STATUS_SUCCESS; - *KeyHandle = LocalKeyHandle; - break; - } - NtClose(LocalKeyHandle); - - LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\'; - LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR); - - Status = NtCreateKey(&LocalKeyHandle, - KEY_ALL_ACCESS, - &LocalObjectAttributes, - 0, - NULL, - CreateOptions, - &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status); - break; - } - } - - RtlFreeUnicodeString(&LocalKeyName); - - return Status; -} - /*********************************************************************** * registry_callback * @@ -539,7 +440,7 @@ registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete) if (!Ok) return TRUE; /* Don't fail if the section isn't present */ - for (;Ok; Ok = SetupFindNextLine (&Context, &Context)) + for (;Ok; Ok = SetupFindNextLine(&Context, &Context)) { /* get root */ if (!SetupGetStringFieldW(&Context, 1, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL)) @@ -615,22 +516,21 @@ registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete) return TRUE; } - BOOLEAN ImportRegistryFile( - PCWSTR SourcePath, - PWSTR Filename, - PWSTR Section, - LCID LocaleId, - BOOLEAN Delete) + IN PCWSTR SourcePath, + IN PCWSTR FileName, + IN PCWSTR Section, + IN LCID LocaleId, + IN BOOLEAN Delete) { - WCHAR FileNameBuffer[MAX_PATH]; HINF hInf; UINT ErrorLine; + WCHAR FileNameBuffer[MAX_PATH]; - /* Load inf file from install media. */ + /* Load the INF file from the installation media */ CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, - SourcePath, Filename); + SourcePath, FileName); hInf = SetupOpenInfFileExW(FileNameBuffer, NULL, @@ -639,7 +539,7 @@ ImportRegistryFile( &ErrorLine); if (hInf == INVALID_HANDLE_VALUE) { - DPRINT1("SetupOpenInfFile() failed\n"); + DPRINT1("SetupOpenInfFileEx() failed\n"); return FALSE; } @@ -647,7 +547,7 @@ ImportRegistryFile( if (!registry_callback(hInf, L"DelReg", FALSE)) { DPRINT1("registry_callback() failed\n"); - InfCloseFile(hInf); + SetupCloseInfFile(hInf); return FALSE; } #endif @@ -655,305 +555,21 @@ ImportRegistryFile( if (!registry_callback(hInf, L"AddReg", FALSE)) { DPRINT1("registry_callback() failed\n"); - InfCloseFile(hInf); + SetupCloseInfFile(hInf); return FALSE; } if (!registry_callback(hInf, L"AddReg.NT" Architecture, FALSE)) { DPRINT1("registry_callback() failed\n"); - InfCloseFile(hInf); - return FALSE; - } - - InfCloseFile(hInf); - return TRUE; -} - -/* - * Should be called under privileges - */ -static NTSTATUS -CreateRegistryFile( - IN PUNICODE_STRING InstallPath, - IN PCWSTR RegistryKey, - IN BOOLEAN IsHiveNew, - IN HANDLE ProtoKeyHandle -/* - IN PUCHAR Descriptor, - IN ULONG DescriptorLength -*/ - ) -{ - /* '.old' is for old valid hives, while '.brk' is for old broken hives */ - static PCWSTR Extensions[] = {L"old", L"brk"}; - - NTSTATUS Status; - HANDLE FileHandle; - UNICODE_STRING FileName; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - PCWSTR Extension; - WCHAR PathBuffer[MAX_PATH]; - WCHAR PathBuffer2[MAX_PATH]; - - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, - InstallPath->Buffer, L"System32\\config", RegistryKey); - - Extension = Extensions[IsHiveNew ? 0 : 1]; - - // - // FIXME: The best, actually, would be to rename (move) the existing - // System32\config\RegistryKey file to System32\config\RegistryKey.old, - // and if it already existed some System32\config\RegistryKey.old, we should - // first rename this one into System32\config\RegistryKey_N.old before - // performing the original rename. - // - - /* Check whether the registry hive file already existed, and if so, rename it */ - if (DoesFileExist(NULL, PathBuffer)) - { - // UINT i; - - DPRINT1("Registry hive '%S' already exists, rename it\n", PathBuffer); - - // i = 1; - /* Try first by just appending the '.old' extension */ - StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s", PathBuffer, Extension); -#if 0 - while (DoesFileExist(NULL, PathBuffer2)) - { - /* An old file already exists, increments its index, but not too much */ - if (i <= 0xFFFF) - { - /* Append '_N.old' extension */ - StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s_%lu.%s", PathBuffer, i, Extension); - ++i; - } - else - { - /* - * Too many old files exist, we will rename the file - * using the name of the oldest one. - */ - StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s", PathBuffer, Extension); - break; - } - } -#endif - - /* Now rename the file (force the move) */ - Status = SetupMoveFile(PathBuffer, PathBuffer2, MOVEFILE_REPLACE_EXISTING); - } - - /* Create the file */ - RtlInitUnicodeString(&FileName, PathBuffer); - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, // Could have been InstallPath, etc... - NULL); // Descriptor - - Status = NtCreateFile(&FileHandle, - FILE_GENERIC_WRITE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OVERWRITE_IF, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName, Status); - return Status; - } - - /* Save the selected hive into the file */ - Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName, Status); - } - - /* Close the file and return */ - NtClose(FileHandle); - return Status; -} - -static BOOLEAN -CmpLinkKeyToHive( - IN HANDLE RootLinkKeyHandle OPTIONAL, - IN PCWSTR LinkKeyName, - IN PCWSTR TargetKeyName) -{ - static UNICODE_STRING CmSymbolicLinkValueName = - RTL_CONSTANT_STRING(L"SymbolicLinkValue"); - - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - HANDLE TargetKeyHandle; - ULONG Disposition; - - /* Initialize the object attributes */ - RtlInitUnicodeString(&KeyName, LinkKeyName); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootLinkKeyHandle, - NULL); - - /* Create the link key */ - Status = NtCreateKey(&TargetKeyHandle, - KEY_SET_VALUE | KEY_CREATE_LINK, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CmpLinkKeyToHive: couldn't create %S, Status = 0x%08lx\n", - LinkKeyName, Status); - return FALSE; - } - - /* Check if the new key was actually created */ - if (Disposition != REG_CREATED_NEW_KEY) - { - DPRINT1("CmpLinkKeyToHive: %S already exists!\n", LinkKeyName); - NtClose(TargetKeyHandle); - return FALSE; - } - - /* Set the target key name as link target */ - RtlInitUnicodeString(&KeyName, TargetKeyName); - Status = NtSetValueKey(TargetKeyHandle, - &CmSymbolicLinkValueName, - 0, - REG_LINK, - KeyName.Buffer, - KeyName.Length); - - /* Close the link key handle */ - NtClose(TargetKeyHandle); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("CmpLinkKeyToHive: couldn't create symbolic link for %S, Status = 0x%08lx\n", - TargetKeyName, Status); + SetupCloseInfFile(hInf); return FALSE; } + SetupCloseInfFile(hInf); return TRUE; } -/* - * Should be called under privileges - */ -static NTSTATUS -ConnectRegistry( - IN HKEY RootKey OPTIONAL, - IN PCWSTR RegMountPoint, - // IN HANDLE RootDirectory OPTIONAL, - IN PUNICODE_STRING InstallPath, - IN PCWSTR RegistryKey -/* - IN PUCHAR Descriptor, - IN ULONG DescriptorLength -*/ - ) -{ - UNICODE_STRING KeyName, FileName; - OBJECT_ATTRIBUTES KeyObjectAttributes; - OBJECT_ATTRIBUTES FileObjectAttributes; - WCHAR PathBuffer[MAX_PATH]; - - RtlInitUnicodeString(&KeyName, RegMountPoint); - InitializeObjectAttributes(&KeyObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKey, - NULL); // Descriptor - - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, - InstallPath->Buffer, L"System32\\config", RegistryKey); - RtlInitUnicodeString(&FileName, PathBuffer); - InitializeObjectAttributes(&FileObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, // RootDirectory, - NULL); - - /* Mount the registry hive in the registry namespace */ - return NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes); -} - - -static NTSTATUS -VerifyRegistryHive( - // IN HKEY RootKey OPTIONAL, - // // IN HANDLE RootDirectory OPTIONAL, - IN PUNICODE_STRING InstallPath, - IN PCWSTR RegistryKey /* , - IN PCWSTR RegMountPoint */) -{ - NTSTATUS Status; - UNICODE_STRING KeyName; - OBJECT_ATTRIBUTES ObjectAttributes; - - /* Try to mount the specified registry hive */ - Status = ConnectRegistry(NULL, - L"\\Registry\\Machine\\USetup_VerifyHive", - InstallPath, - RegistryKey - /* NULL, 0 */); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey, Status); - } - - DPRINT1("VerifyRegistryHive: ConnectRegistry(%S) returns Status 0x%08lx\n", RegistryKey, Status); - - // - // TODO: Check the Status error codes: STATUS_SUCCESS, STATUS_REGISTRY_RECOVERED, - // STATUS_REGISTRY_HIVE_RECOVERED, STATUS_REGISTRY_CORRUPT, STATUS_REGISTRY_IO_FAILED, - // STATUS_NOT_REGISTRY_FILE, STATUS_CANNOT_LOAD_REGISTRY_FILE ; - //(STATUS_HIVE_UNLOADED) ; STATUS_SYSTEM_HIVE_TOO_LARGE - // - - if (Status == STATUS_REGISTRY_HIVE_RECOVERED) // NT_SUCCESS is still FALSE in this case! - DPRINT1("VerifyRegistryHive: Registry hive %S was recovered but some data may be lost (Status 0x%08lx)\n", RegistryKey, Status); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("VerifyRegistryHive: Registry hive %S is corrupted (Status 0x%08lx)\n", RegistryKey, Status); - return Status; - } - - if (Status == STATUS_REGISTRY_RECOVERED) - DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status 0x%08lx)\n", RegistryKey, Status); - - /* Unmount the hive */ - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\USetup_VerifyHive"); - Status = NtUnloadKey(&ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtUnloadKey(%S, %wZ) failed, Status 0x%08lx\n", RegistryKey, &KeyName, Status); - } - - return Status; -} - typedef enum _HIVE_UPDATE_STATE { @@ -1072,7 +688,6 @@ VerifyRegistryHives( return Status; } - NTSTATUS RegInitializeRegistry( IN PUNICODE_STRING InstallPath) @@ -1444,14 +1059,9 @@ RegCleanupRegistry( } else { - RtlInitUnicodeString(&KeyName, RegistryHives[i].HiveRegistryPath); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - // Status = NtUnloadKey(&ObjectAttributes); - Status = NtUnloadKey2(&ObjectAttributes, 1 /* REG_FORCE_UNLOAD */); + Status = DisconnectRegistry(NULL, + RegistryHives[i].HiveRegistryPath, + 1 /* REG_FORCE_UNLOAD */); DPRINT1("Unmounting '%S' %s\n", RegistryHives[i].HiveRegistryPath, NT_SUCCESS(Status) ? "succeeded" : "failed"); /* Switch the hive state to 'Update' */ @@ -1505,39 +1115,4 @@ RegCleanupRegistry( RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); } - -VOID -SetDefaultPagefile( - WCHAR Drive) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); - UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"PagingFiles"); - WCHAR ValueBuffer[] = L"?:\\pagefile.sys 0 0\0"; - HANDLE KeyHandle; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, - NULL); - Status = NtOpenKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - return; - - ValueBuffer[0] = Drive; - - NtSetValueKey(KeyHandle, - &ValueName, - 0, - REG_MULTI_SZ, - (PVOID)&ValueBuffer, - sizeof(ValueBuffer)); - - NtClose(KeyHandle); -} - /* EOF */ diff --git a/base/setup/usetup/registry.h b/base/setup/lib/registry.h similarity index 82% copy from base/setup/usetup/registry.h copy to base/setup/lib/registry.h index b48777a126..7bc8d8f7a0 100644 --- a/base/setup/usetup/registry.h +++ b/base/setup/lib/registry.h @@ -18,10 +18,11 @@ */ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS text-mode setup - * FILE: base/setup/usetup/registry.h + * PROJECT: ReactOS Setup Library + * FILE: base/setup/lib/registry.h * PURPOSE: Registry creation functions - * PROGRAMMER: + * PROGRAMMERS: ... + * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) */ #pragma once @@ -38,11 +39,11 @@ GetRootKeyByName( BOOLEAN ImportRegistryFile( - PCWSTR SourcePath, - PWSTR Filename, - PWSTR Section, - LCID LocaleId, - BOOLEAN Delete); + IN PCWSTR SourcePath, + IN PCWSTR FileName, + IN PCWSTR Section, + IN LCID LocaleId, + IN BOOLEAN Delete); NTSTATUS VerifyRegistryHives( @@ -57,8 +58,4 @@ VOID RegCleanupRegistry( IN PUNICODE_STRING InstallPath); -VOID -SetDefaultPagefile( - WCHAR Drive); - /* EOF */ diff --git a/base/setup/lib/regutil.c b/base/setup/lib/regutil.c new file mode 100644 index 0000000000..eebbac0feb --- /dev/null +++ b/base/setup/lib/regutil.c @@ -0,0 +1,457 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Setup Library + * FILE: base/setup/lib/regutil.c + * PURPOSE: Registry utility functions + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) + */ + +/* INCLUDES *****************************************************************/ + +#include "precomp.h" +#include "filesup.h" + +#include "regutil.h" + +// HACK! +#include <strsafe.h> + +#define NDEBUG +#include <debug.h> + + +// HACK!! These functions should actually be moved in the setup lib! +// For the moment, see usetup/filesup.c (or .h) +#if 1 + +NTSTATUS +SetupCopyFile( + IN PCWSTR SourceFileName, + IN PCWSTR DestinationFileName, + IN BOOLEAN FailIfExists); + +#define MOVEFILE_REPLACE_EXISTING 1 + +NTSTATUS +SetupMoveFile( + IN PCWSTR ExistingFileName, + IN PCWSTR NewFileName, + IN ULONG Flags); + +#endif + +/* FUNCTIONS ****************************************************************/ + +/* + * This function is similar to the one in dlls/win32/advapi32/reg/reg.c + * TODO: I should review both of them very carefully, because they may need + * some adjustments in their NtCreateKey calls, especially for CreateOptions + * stuff etc... + */ +NTSTATUS +CreateNestedKey(PHANDLE KeyHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + ULONG CreateOptions) +{ + OBJECT_ATTRIBUTES LocalObjectAttributes; + UNICODE_STRING LocalKeyName; + ULONG Disposition; + NTSTATUS Status; + USHORT FullNameLength; + PWCHAR Ptr; + HANDLE LocalKeyHandle; + + Status = NtCreateKey(KeyHandle, + KEY_ALL_ACCESS, + ObjectAttributes, + 0, + NULL, + CreateOptions, + &Disposition); + DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status); + if (Status != STATUS_OBJECT_NAME_NOT_FOUND) + { + if (!NT_SUCCESS(Status)) + DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", ObjectAttributes->ObjectName, Status); + + return Status; + } + + /* Copy object attributes */ + RtlCopyMemory(&LocalObjectAttributes, + ObjectAttributes, + sizeof(OBJECT_ATTRIBUTES)); + RtlCreateUnicodeString(&LocalKeyName, + ObjectAttributes->ObjectName->Buffer); + LocalObjectAttributes.ObjectName = &LocalKeyName; + FullNameLength = LocalKeyName.Length; + + /* Remove the last part of the key name and try to create the key again. */ + while (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + Ptr = wcsrchr(LocalKeyName.Buffer, '\\'); + if (Ptr == NULL || Ptr == LocalKeyName.Buffer) + { + Status = STATUS_UNSUCCESSFUL; + break; + } + *Ptr = (WCHAR)0; + LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR); + + Status = NtCreateKey(&LocalKeyHandle, + KEY_CREATE_SUB_KEY, + &LocalObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + &Disposition); + DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status); + } + + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString(&LocalKeyName); + return Status; + } + + /* Add removed parts of the key name and create them too. */ + while (TRUE) + { + if (LocalKeyName.Length == FullNameLength) + { + Status = STATUS_SUCCESS; + *KeyHandle = LocalKeyHandle; + break; + } + NtClose(LocalKeyHandle); + + LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\'; + LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR); + + Status = NtCreateKey(&LocalKeyHandle, + KEY_ALL_ACCESS, + &LocalObjectAttributes, + 0, + NULL, + CreateOptions, + &Disposition); + DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status); + break; + } + } + + RtlFreeUnicodeString(&LocalKeyName); + + return Status; +} + + +/* + * Should be called under SE_BACKUP_PRIVILEGE privilege + */ +NTSTATUS +CreateRegistryFile( + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey, + IN BOOLEAN IsHiveNew, + IN HANDLE ProtoKeyHandle +/* + IN PUCHAR Descriptor, + IN ULONG DescriptorLength +*/ + ) +{ + /* '.old' is for old valid hives, while '.brk' is for old broken hives */ + static PCWSTR Extensions[] = {L"old", L"brk"}; + + NTSTATUS Status; + HANDLE FileHandle; + UNICODE_STRING FileName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + PCWSTR Extension; + WCHAR PathBuffer[MAX_PATH]; + WCHAR PathBuffer2[MAX_PATH]; + + CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, + InstallPath->Buffer, L"System32\\config", RegistryKey); + + Extension = Extensions[IsHiveNew ? 0 : 1]; + + // + // FIXME: The best, actually, would be to rename (move) the existing + // System32\config\RegistryKey file to System32\config\RegistryKey.old, + // and if it already existed some System32\config\RegistryKey.old, we should + // first rename this one into System32\config\RegistryKey_N.old before + // performing the original rename. + // + + /* Check whether the registry hive file already existed, and if so, rename it */ + if (DoesFileExist(NULL, PathBuffer)) + { + // UINT i; + + DPRINT1("Registry hive '%S' already exists, rename it\n", PathBuffer); + + // i = 1; + /* Try first by just appending the '.old' extension */ + StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s", PathBuffer, Extension); +#if 0 + while (DoesFileExist(NULL, PathBuffer2)) + { + /* An old file already exists, increments its index, but not too much */ + if (i <= 0xFFFF) + { + /* Append '_N.old' extension */ + StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s_%lu.%s", PathBuffer, i, Extension); + ++i; + } + else + { + /* + * Too many old files exist, we will rename the file + * using the name of the oldest one. + */ + StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s", PathBuffer, Extension); + break; + } + } +#endif + + /* Now rename the file (force the move) */ + Status = SetupMoveFile(PathBuffer, PathBuffer2, MOVEFILE_REPLACE_EXISTING); + } + + /* Create the file */ + RtlInitUnicodeString(&FileName, PathBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, // Could have been InstallPath, etc... + NULL); // Descriptor + + Status = NtCreateFile(&FileHandle, + FILE_GENERIC_WRITE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName, Status); + return Status; + } + + /* Save the selected hive into the file */ + Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName, Status); + } + + /* Close the file and return */ + NtClose(FileHandle); + return Status; +} + +BOOLEAN +CmpLinkKeyToHive( + IN HANDLE RootLinkKeyHandle OPTIONAL, + IN PCWSTR LinkKeyName, + IN PCWSTR TargetKeyName) +{ + static UNICODE_STRING CmSymbolicLinkValueName = + RTL_CONSTANT_STRING(L"SymbolicLinkValue"); + + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE TargetKeyHandle; + ULONG Disposition; + + /* Initialize the object attributes */ + RtlInitUnicodeString(&KeyName, LinkKeyName); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootLinkKeyHandle, + NULL); + + /* Create the link key */ + Status = NtCreateKey(&TargetKeyHandle, + KEY_SET_VALUE | KEY_CREATE_LINK, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, + &Disposition); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmpLinkKeyToHive: couldn't create %S, Status = 0x%08lx\n", + LinkKeyName, Status); + return FALSE; + } + + /* Check if the new key was actually created */ + if (Disposition != REG_CREATED_NEW_KEY) + { + DPRINT1("CmpLinkKeyToHive: %S already exists!\n", LinkKeyName); + NtClose(TargetKeyHandle); + return FALSE; + } + + /* Set the target key name as link target */ + RtlInitUnicodeString(&KeyName, TargetKeyName); + Status = NtSetValueKey(TargetKeyHandle, + &CmSymbolicLinkValueName, + 0, + REG_LINK, + KeyName.Buffer, + KeyName.Length); + + /* Close the link key handle */ + NtClose(TargetKeyHandle); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmpLinkKeyToHive: couldn't create symbolic link for %S, Status = 0x%08lx\n", + TargetKeyName, Status); + return FALSE; + } + + return TRUE; +} + +/* + * Should be called under SE_RESTORE_PRIVILEGE privilege + */ +NTSTATUS +ConnectRegistry( + IN HKEY RootKey OPTIONAL, + IN PCWSTR RegMountPoint, + // IN HANDLE RootDirectory OPTIONAL, + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey +/* + IN PUCHAR Descriptor, + IN ULONG DescriptorLength +*/ + ) +{ + UNICODE_STRING KeyName, FileName; + OBJECT_ATTRIBUTES KeyObjectAttributes; + OBJECT_ATTRIBUTES FileObjectAttributes; + WCHAR PathBuffer[MAX_PATH]; + + RtlInitUnicodeString(&KeyName, RegMountPoint); + InitializeObjectAttributes(&KeyObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKey, + NULL); // Descriptor + + CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, + InstallPath->Buffer, L"System32\\config", RegistryKey); + RtlInitUnicodeString(&FileName, PathBuffer); + InitializeObjectAttributes(&FileObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, // RootDirectory, + NULL); + + /* Mount the registry hive in the registry namespace */ + return NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes); +} + +/* + * Should be called under SE_RESTORE_PRIVILEGE privilege + */ +NTSTATUS +DisconnectRegistry( + IN HKEY RootKey OPTIONAL, + IN PCWSTR RegMountPoint, + IN ULONG Flags) +{ + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + + RtlInitUnicodeString(&KeyName, RegMountPoint); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + RootKey, + NULL); + + // NOTE: NtUnloadKey == NtUnloadKey2 with Flags == 0. + return NtUnloadKey2(&ObjectAttributes, Flags); +} + +/* + * Should be called under SE_RESTORE_PRIVILEGE privilege + */ +NTSTATUS +VerifyRegistryHive( + // IN HKEY RootKey OPTIONAL, + // // IN HANDLE RootDirectory OPTIONAL, + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey /* , + IN PCWSTR RegMountPoint */) +{ + NTSTATUS Status; + + /* Try to mount the specified registry hive */ + Status = ConnectRegistry(NULL, + L"\\Registry\\Machine\\USetup_VerifyHive", + InstallPath, + RegistryKey + /* NULL, 0 */); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey, Status); + } + + DPRINT1("VerifyRegistryHive: ConnectRegistry(%S) returns Status 0x%08lx\n", RegistryKey, Status); + + // + // TODO: Check the Status error codes: STATUS_SUCCESS, STATUS_REGISTRY_RECOVERED, + // STATUS_REGISTRY_HIVE_RECOVERED, STATUS_REGISTRY_CORRUPT, STATUS_REGISTRY_IO_FAILED, + // STATUS_NOT_REGISTRY_FILE, STATUS_CANNOT_LOAD_REGISTRY_FILE ; + //(STATUS_HIVE_UNLOADED) ; STATUS_SYSTEM_HIVE_TOO_LARGE + // + + if (Status == STATUS_REGISTRY_HIVE_RECOVERED) // NT_SUCCESS is still FALSE in this case! + DPRINT1("VerifyRegistryHive: Registry hive %S was recovered but some data may be lost (Status 0x%08lx)\n", RegistryKey, Status); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("VerifyRegistryHive: Registry hive %S is corrupted (Status 0x%08lx)\n", RegistryKey, Status); + return Status; + } + + if (Status == STATUS_REGISTRY_RECOVERED) + DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status 0x%08lx)\n", RegistryKey, Status); + + /* Unmount the hive */ + Status = DisconnectRegistry(NULL, + L"\\Registry\\Machine\\USetup_VerifyHive", + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("DisconnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey, Status); + } + + return Status; +} + +/* EOF */ diff --git a/base/setup/lib/regutil.h b/base/setup/lib/regutil.h new file mode 100644 index 0000000000..2b2d6a12e1 --- /dev/null +++ b/base/setup/lib/regutil.h @@ -0,0 +1,80 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Setup Library + * FILE: base/setup/lib/regutil.h + * PURPOSE: Registry utility functions + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) + */ + +#pragma once + +/* + * This function is similar to the one in dlls/win32/advapi32/reg/reg.c + * TODO: I should review both of them very carefully, because they may need + * some adjustments in their NtCreateKey calls, especially for CreateOptions + * stuff etc... + */ +NTSTATUS +CreateNestedKey(PHANDLE KeyHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + ULONG CreateOptions); + +/* + * Should be called under SE_BACKUP_PRIVILEGE privilege + */ +NTSTATUS +CreateRegistryFile( + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey, + IN BOOLEAN IsHiveNew, + IN HANDLE ProtoKeyHandle +/* + IN PUCHAR Descriptor, + IN ULONG DescriptorLength +*/ + ); + +BOOLEAN +CmpLinkKeyToHive( + IN HANDLE RootLinkKeyHandle OPTIONAL, + IN PCWSTR LinkKeyName, + IN PCWSTR TargetKeyName); + +/* + * Should be called under SE_RESTORE_PRIVILEGE privilege + */ +NTSTATUS +ConnectRegistry( + IN HKEY RootKey OPTIONAL, + IN PCWSTR RegMountPoint, + // IN HANDLE RootDirectory OPTIONAL, + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey +/* + IN PUCHAR Descriptor, + IN ULONG DescriptorLength +*/ + ); + +/* + * Should be called under SE_RESTORE_PRIVILEGE privilege + */ +NTSTATUS +DisconnectRegistry( + IN HKEY RootKey OPTIONAL, + IN PCWSTR RegMountPoint, + IN ULONG Flags); + +/* + * Should be called under SE_RESTORE_PRIVILEGE privilege + */ +NTSTATUS +VerifyRegistryHive( + // IN HKEY RootKey OPTIONAL, + // // IN HANDLE RootDirectory OPTIONAL, + IN PUNICODE_STRING InstallPath, + IN PCWSTR RegistryKey /* , + IN PCWSTR RegMountPoint */); + +/* EOF */ diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h index bee6e9f87f..73b308ae4f 100644 --- a/base/setup/lib/setuplib.h +++ b/base/setup/lib/setuplib.h @@ -34,5 +34,7 @@ extern HANDLE ProcessHeap; #include "partlist.h" #include "arcname.h" #include "osdetect.h" +#include "regutil.h" +#include "registry.h" /* EOF */ diff --git a/base/setup/usetup/inffile.c b/base/setup/usetup/inffile.c index 10adbcf5c2..47edb34a58 100644 --- a/base/setup/usetup/inffile.c +++ b/base/setup/usetup/inffile.c @@ -21,7 +21,8 @@ * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/inffile.c * PURPOSE: .inf files support functions - * PROGRAMMER: Herv� Poussineau + * PROGRAMMERS: Herv� Poussineau + * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) */ /* INCLUDES ******************************************************************/ @@ -31,11 +32,23 @@ #define NDEBUG #include <debug.h> -/* FUNCTIONS *****************************************************************/ +/* SETUP* API COMPATIBILITY FUNCTIONS ****************************************/ +/* Functions from the INFLIB library */ + +extern VOID InfCloseFile(HINF InfHandle); +// #define SetupCloseInfFile InfCloseFile +VOID +WINAPI +SetupCloseInfFile(HINF InfHandle) +{ + InfCloseFile(InfHandle); +} + +// #define SetupFindFirstLineW InfpFindFirstLineW BOOL WINAPI -InfpFindFirstLineW( +SetupFindFirstLineW( IN HINF InfHandle, IN PCWSTR Section, IN PCWSTR Key, @@ -53,10 +66,128 @@ InfpFindFirstLineW( return TRUE; } +extern BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut); +// #define SetupFindNextLine InfFindNextLine +BOOL +WINAPI +SetupFindNextLine(PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut) +{ + return !!InfFindNextLine(ContextIn, ContextOut); +} + +extern LONG InfGetFieldCount(PINFCONTEXT Context); +// #define SetupGetFieldCount InfGetFieldCount +LONG +WINAPI +SetupGetFieldCount(PINFCONTEXT Context) +{ + return InfGetFieldCount(Context); +} + +/* + * This function corresponds to an undocumented but exported setupapi API + * that exists since WinNT4 and is still present in Win10. + * The returned string pointer is a read-only pointer to a string in the + * maintained INF cache, and is always in UNICODE (on NT systems). + */ +extern BOOLEAN InfGetDataField(PINFCONTEXT Context, + ULONG FieldIndex, + PWCHAR *Data); +PCWSTR +WINAPI +pSetupGetField(PINFCONTEXT Context, + ULONG FieldIndex) +{ + PWCHAR Data = NULL; + if (!InfGetDataField(Context, FieldIndex, &Data)) + return NULL; + return Data; +} + +extern BOOLEAN InfGetBinaryField(PINFCONTEXT Context, + ULONG FieldIndex, + PUCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); +// #define SetupGetBinaryField InfGetBinaryField +BOOL +WINAPI +SetupGetBinaryField(PINFCONTEXT Context, + ULONG FieldIndex, + PUCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + return !!InfGetBinaryField(Context, + FieldIndex, + ReturnBuffer, + ReturnBufferSize, + RequiredSize); +} +extern BOOLEAN InfGetIntField(PINFCONTEXT Context, + ULONG FieldIndex, + INT *IntegerValue); +// #define SetupGetIntField InfGetIntField +BOOL +WINAPI +SetupGetIntField(PINFCONTEXT Context, + ULONG FieldIndex, + INT *IntegerValue) // PINT +{ + return !!InfGetIntField(Context, FieldIndex, IntegerValue); +} + +extern BOOLEAN InfGetMultiSzField(PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); +// #define SetupGetMultiSzFieldW InfGetMultiSzField +BOOL +WINAPI +SetupGetMultiSzFieldW(PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + return !!InfGetMultiSzField(Context, + FieldIndex, + ReturnBuffer, + ReturnBufferSize, + RequiredSize); +} + +extern BOOLEAN InfGetStringField(PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); +// #define SetupGetStringFieldW InfGetStringField +BOOL +WINAPI +SetupGetStringFieldW(PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + return !!InfGetStringField(Context, + FieldIndex, + ReturnBuffer, + ReturnBufferSize, + RequiredSize); +} + + +/* SetupOpenInfFileW with support for a user-provided LCID */ +// #define SetupOpenInfFileExW InfpOpenInfFileW HINF WINAPI -InfpOpenInfFileW( +SetupOpenInfFileExW( IN PCWSTR FileName, IN PCWSTR InfClass, IN DWORD InfStyle, @@ -81,25 +212,7 @@ InfpOpenInfFileW( } -BOOLEAN -INF_GetData( - IN PINFCONTEXT Context, - OUT PWCHAR *Key, - OUT PWCHAR *Data) -{ - return InfGetData(Context, Key, Data); -} - - -BOOLEAN -INF_GetDataField( - IN PINFCONTEXT Context, - IN ULONG FieldIndex, - OUT PWCHAR *Data) -{ - return InfGetDataField(Context, FieldIndex, Data); -} - +/* HELPER FUNCTIONS **********************************************************/ HINF WINAPI INF_OpenBufferedFileA( diff --git a/base/setup/usetup/inffile.h b/base/setup/usetup/inffile.h index 610c9e23a3..90fb5e7d5f 100644 --- a/base/setup/usetup/inffile.h +++ b/base/setup/usetup/inffile.h @@ -21,88 +21,32 @@ * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/inffile.h * PURPOSE: .inf files support functions - * PROGRAMMER: Herv� Poussineau + * PROGRAMMERS: Herv� Poussineau + * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) */ #pragma once -#include <infcommon.h> +#ifdef __REACTOS__ -extern VOID InfSetHeap(PVOID Heap); -extern VOID InfCloseFile(HINF InfHandle); -extern BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn, - PINFCONTEXT ContextOut); -extern BOOLEAN InfGetBinaryField(PINFCONTEXT Context, - ULONG FieldIndex, - PUCHAR ReturnBuffer, - ULONG ReturnBufferSize, - PULONG RequiredSize); -extern BOOLEAN InfGetMultiSzField(PINFCONTEXT Context, - ULONG FieldIndex, - PWSTR ReturnBuffer, - ULONG ReturnBufferSize, - PULONG RequiredSize); -extern BOOLEAN InfGetStringField(PINFCONTEXT Context, - ULONG FieldIndex, - PWSTR ReturnBuffer, - ULONG ReturnBufferSize, - PULONG RequiredSize); - -#define SetupCloseInfFile InfCloseFile -#define SetupFindNextLine InfFindNextLine -#define SetupGetBinaryField InfGetBinaryField -#define SetupGetMultiSzFieldW InfGetMultiSzField -#define SetupGetStringFieldW InfGetStringField - - -#define SetupFindFirstLineW InfpFindFirstLineW -#define SetupGetFieldCount InfGetFieldCount -#define SetupGetIntField InfGetIntField +// HACK around the fact INFLIB unconditionally defines MAX_INF_STRING_LENGTH. +#undef MAX_INF_STRING_LENGTH -// SetupOpenInfFileW with support for a user-provided LCID -#define SetupOpenInfFileExW InfpOpenInfFileW +/* Functions from the INFLIB library */ +// #include <infcommon.h> +#include <infros.h> -#define INF_STYLE_WIN4 0x00000002 +#undef MAX_INF_STRING_LENGTH +#define MAX_INF_STRING_LENGTH 1024 -/* FIXME: this structure is the one used in inflib, not in setupapi - * Delete it once we don't use inflib anymore */ -typedef struct _INFCONTEXT -{ - HINF Inf; - HINF CurrentInf; - UINT Section; - UINT Line; -} INFCONTEXT; -C_ASSERT(sizeof(INFCONTEXT) == 2 * sizeof(PVOID) + 2 * sizeof(UINT)); +extern VOID InfSetHeap(PVOID Heap); -BOOL -WINAPI -InfpFindFirstLineW( - IN HINF InfHandle, - IN PCWSTR Section, - IN PCWSTR Key, - IN OUT PINFCONTEXT Context); +#endif /* __REACTOS__ */ -HINF -WINAPI -InfpOpenInfFileW( - IN PCWSTR FileName, - IN PCWSTR InfClass, - IN DWORD InfStyle, - IN LCID LocaleId, - OUT PUINT ErrorLine); +#include <../lib/infsupp.h> -BOOLEAN -INF_GetData( - IN PINFCONTEXT Context, - OUT PWCHAR *Key, - OUT PWCHAR *Data); -BOOLEAN -INF_GetDataField( - IN PINFCONTEXT Context, - IN ULONG FieldIndex, - OUT PWCHAR *Data); +/* HELPER FUNCTIONS **********************************************************/ HINF WINAPI INF_OpenBufferedFileA( diff --git a/base/setup/usetup/registry.c b/base/setup/usetup/registry.c index 749835c3d7..f8e1d72fc8 100644 --- a/base/setup/usetup/registry.c +++ b/base/setup/usetup/registry.c @@ -28,1484 +28,11 @@ #include "usetup.h" -// HACK! -#include <strsafe.h> - #define NDEBUG #include <debug.h> -#define FLG_ADDREG_BINVALUETYPE 0x00000001 -#define FLG_ADDREG_NOCLOBBER 0x00000002 -#define FLG_ADDREG_DELVAL 0x00000004 -#define FLG_ADDREG_APPEND 0x00000008 -#define FLG_ADDREG_KEYONLY 0x00000010 -#define FLG_ADDREG_OVERWRITEONLY 0x00000020 -#define FLG_ADDREG_TYPE_SZ 0x00000000 -#define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000 -#define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000 -#define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE) -#define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE) -#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE) -#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE) - -#ifdef _M_IX86 -#define Architecture L"x86" -#elif defined(_M_AMD64) -#define Architecture L"amd64" -#elif defined(_M_IA64) -#define Architecture L"ia64" -#elif defined(_M_ARM) -#define Architecture L"arm" -#elif defined(_M_PPC) -#define Architecture L"ppc" -#endif - /* FUNCTIONS ****************************************************************/ -#define REGISTRY_SETUP_MACHINE L"\\Registry\\Machine\\SYSTEM\\USetup_Machine\\" -#define REGISTRY_SETUP_USER L"\\Registry\\Machine\\SYSTEM\\USetup_User\\" - -typedef struct _ROOT_KEY -{ - PCWSTR Name; - PCWSTR MountPoint; - HANDLE Handle; -} ROOT_KEY, *PROOT_KEY; - -ROOT_KEY RootKeys[] = -{ - { L"HKCR", REGISTRY_SETUP_MACHINE L"SOFTWARE\\Classes\\", NULL }, /* "\\Registry\\Machine\\SOFTWARE\\Classes\\" */ // HKEY_CLASSES_ROOT - { L"HKCU", REGISTRY_SETUP_USER L".DEFAULT\\" , NULL }, /* "\\Registry\\User\\.DEFAULT\\" */ // HKEY_CURRENT_USER - { L"HKLM", REGISTRY_SETUP_MACHINE , NULL }, /* "\\Registry\\Machine\\" */ // HKEY_LOCAL_MACHINE - { L"HKU" , REGISTRY_SETUP_USER , NULL }, /* "\\Registry\\User\\" */ // HKEY_USERS -#if 0 - { L"HKR", NULL, NULL }, -#endif -}; - -#define IsPredefKey(HKey) \ - (((ULONG_PTR)(HKey) & 0xF0000000) == 0x80000000) - -#define GetPredefKeyIndex(HKey) \ - ((ULONG_PTR)(HKey) & 0x0FFFFFFF) - -HANDLE -GetRootKeyByPredefKey( - IN HANDLE KeyHandle, - OUT PCWSTR* RootKeyMountPoint OPTIONAL) -{ - ULONG_PTR Index = GetPredefKeyIndex(KeyHandle); - - if (!IsPredefKey(KeyHandle)) - return NULL; - if (GetPredefKeyIndex(KeyHandle) >= ARRAYSIZE(RootKeys)) - return NULL; - - if (RootKeyMountPoint) - *RootKeyMountPoint = RootKeys[Index].MountPoint; - return RootKeys[Index].Handle; -} - -HANDLE -GetRootKeyByName( - IN PCWSTR RootKeyName, - OUT PCWSTR* RootKeyMountPoint OPTIONAL) -{ - UCHAR i; - - for (i = 0; i < ARRAYSIZE(RootKeys); ++i) - { - if (!_wcsicmp(RootKeyName, RootKeys[i].Name)) - { - if (RootKeyMountPoint) - *RootKeyMountPoint = RootKeys[i].MountPoint; - return RootKeys[i].Handle; - } - } - - return NULL; -} - - -/*********************************************************************** - * append_multi_sz_value - * - * Append a multisz string to a multisz registry value. - */ -// NOTE: Synced with setupapi/install.c ; see also mkhive/reginf.c -#if 0 -static void -append_multi_sz_value (HANDLE hkey, - const WCHAR *value, - const WCHAR *strings, - DWORD str_size ) -{ - DWORD size, type, total; - WCHAR *buffer, *p; - - if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; - if (type != REG_MULTI_SZ) return; - - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size + str_size * sizeof(WCHAR) ))) return; - if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; - - /* compare each string against all the existing ones */ - total = size; - while (*strings) - { - int len = strlenW(strings) + 1; - - for (p = buffer; *p; p += strlenW(p) + 1) - if (!strcmpiW( p, strings )) break; - - if (!*p) /* not found, need to append it */ - { - memcpy( p, strings, len * sizeof(WCHAR) ); - p[len] = 0; - total += len; - } - strings += len; - } - if (total != size) - { - TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) ); - RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total ); - } - done: - HeapFree( GetProcessHeap(), 0, buffer ); -} -#endif - -/*********************************************************************** - * delete_multi_sz_value - * - * Remove a string from a multisz registry value. - */ -#if 0 -static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string ) -{ - DWORD size, type; - WCHAR *buffer, *src, *dst; - - if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; - if (type != REG_MULTI_SZ) return; - /* allocate double the size, one for value before and one for after */ - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return; - if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; - src = buffer; - dst = buffer + size; - while (*src) - { - int len = strlenW(src) + 1; - if (strcmpiW( src, string )) - { - memcpy( dst, src, len * sizeof(WCHAR) ); - dst += len; - } - src += len; - } - *dst++ = 0; - if (dst != buffer + 2*size) /* did we remove something? */ - { - TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) ); - RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, - (BYTE *)(buffer + size), dst - (buffer + size) ); - } - done: - HeapFree( GetProcessHeap(), 0, buffer ); -} -#endif - -/*********************************************************************** - * do_reg_operation - * - * Perform an add/delete registry operation depending on the flags. - */ -static BOOLEAN -do_reg_operation(HANDLE KeyHandle, - PUNICODE_STRING ValueName, - PINFCONTEXT Context, - ULONG Flags) -{ - WCHAR EmptyStr = 0; - ULONG Type; - ULONG Size; - - if (Flags & FLG_ADDREG_DELVAL) /* deletion */ - { -#if 0 - if (ValueName) - { - RegDeleteValueW( KeyHandle, ValueName ); - } - else - { - RegDeleteKeyW( KeyHandle, NULL ); - } -#endif - return TRUE; - } - - if (Flags & FLG_ADDREG_KEYONLY) - return TRUE; - -#if 0 - if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) - { - BOOL exists = !RegQueryValueExW( hkey, ValueName, NULL, NULL, NULL, NULL ); - if (exists && (flags & FLG_ADDREG_NOCLOBBER)) - return TRUE; - if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY)) - return TRUE; - } -#endif - - switch (Flags & FLG_ADDREG_TYPE_MASK) - { - case FLG_ADDREG_TYPE_SZ: - Type = REG_SZ; - break; - - case FLG_ADDREG_TYPE_MULTI_SZ: - Type = REG_MULTI_SZ; - break; - - case FLG_ADDREG_TYPE_EXPAND_SZ: - Type = REG_EXPAND_SZ; - break; - - case FLG_ADDREG_TYPE_BINARY: - Type = REG_BINARY; - break; - - case FLG_ADDREG_TYPE_DWORD: - Type = REG_DWORD; - break; - - case FLG_ADDREG_TYPE_NONE: - Type = REG_NONE; - break; - - default: - Type = Flags >> 16; - break; - } - - if (!(Flags & FLG_ADDREG_BINVALUETYPE) || - (Type == REG_DWORD && SetupGetFieldCount (Context) == 5)) - { - PWCHAR Str = NULL; - - if (Type == REG_MULTI_SZ) - { - if (!SetupGetMultiSzFieldW (Context, 5, NULL, 0, &Size)) - Size = 0; - - if (Size) - { - Str = (WCHAR*) RtlAllocateHeap(ProcessHeap, 0, Size * sizeof(WCHAR)); - if (Str == NULL) - return FALSE; - - SetupGetMultiSzFieldW (Context, 5, Str, Size, NULL); - } - - if (Flags & FLG_ADDREG_APPEND) - { - if (Str == NULL) - return TRUE; - - DPRINT1("append_multi_sz_value '%S' commented out, WHY??\n", ValueName); -// append_multi_sz_value( hkey, value, str, size ); - - RtlFreeHeap (ProcessHeap, 0, Str); - return TRUE; - } - /* else fall through to normal string handling */ - } - else - { - if (!SetupGetStringFieldW(Context, 5, NULL, 0, &Size)) - Size = 0; - - if (Size) - { - Str = (WCHAR*)RtlAllocateHeap(ProcessHeap, 0, Size * sizeof(WCHAR)); - if (Str == NULL) - return FALSE; - - SetupGetStringFieldW(Context, 5, Str, Size, NULL); - } - } - - if (Type == REG_DWORD) - { - ULONG dw = Str ? wcstoul (Str, NULL, 0) : 0; - - DPRINT("setting dword %wZ to %lx\n", ValueName, dw); - - NtSetValueKey (KeyHandle, - ValueName, - 0, - Type, - (PVOID)&dw, - sizeof(ULONG)); - } - else - { - DPRINT("setting value %wZ to %S\n", ValueName, Str); - - if (Str) - { - NtSetValueKey (KeyHandle, - ValueName, - 0, - Type, - (PVOID)Str, - Size * sizeof(WCHAR)); - } - else - { - NtSetValueKey (KeyHandle, - ValueName, - 0, - Type, - (PVOID)&EmptyStr, - sizeof(WCHAR)); - } - } - RtlFreeHeap (ProcessHeap, 0, Str); - } - else /* get the binary data */ - { - PUCHAR Data = NULL; - - if (!SetupGetBinaryField (Context, 5, NULL, 0, &Size)) - Size = 0; - - if (Size) - { - Data = (unsigned char*) RtlAllocateHeap(ProcessHeap, 0, Size); - if (Data == NULL) - return FALSE; - - DPRINT("setting binary data %wZ len %lu\n", ValueName, Size); - SetupGetBinaryField (Context, 5, Data, Size, NULL); - } - - NtSetValueKey (KeyHandle, - ValueName, - 0, - Type, - (PVOID)Data, - Size); - - RtlFreeHeap (ProcessHeap, 0, Data); - } - - return TRUE; -} - -/* - * This function is similar to the one in dlls/win32/advapi32/reg/reg.c - * TODO: I should review both of them very carefully, because they may need - * some adjustments in their NtCreateKey calls, especially for CreateOptions - * stuff etc... - */ -NTSTATUS -CreateNestedKey(PHANDLE KeyHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - ULONG CreateOptions) -{ - OBJECT_ATTRIBUTES LocalObjectAttributes; - UNICODE_STRING LocalKeyName; - ULONG Disposition; - NTSTATUS Status; - USHORT FullNameLength; - PWCHAR Ptr; - HANDLE LocalKeyHandle; - - Status = NtCreateKey(KeyHandle, - KEY_ALL_ACCESS, - ObjectAttributes, - 0, - NULL, - CreateOptions, - &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status); - if (Status != STATUS_OBJECT_NAME_NOT_FOUND) - { - if (!NT_SUCCESS(Status)) - DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", ObjectAttributes->ObjectName, Status); - - return Status; - } - - /* Copy object attributes */ - RtlCopyMemory(&LocalObjectAttributes, - ObjectAttributes, - sizeof(OBJECT_ATTRIBUTES)); - RtlCreateUnicodeString(&LocalKeyName, - ObjectAttributes->ObjectName->Buffer); - LocalObjectAttributes.ObjectName = &LocalKeyName; - FullNameLength = LocalKeyName.Length; - - /* Remove the last part of the key name and try to create the key again. */ - while (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - Ptr = wcsrchr(LocalKeyName.Buffer, '\\'); - if (Ptr == NULL || Ptr == LocalKeyName.Buffer) - { - Status = STATUS_UNSUCCESSFUL; - break; - } - *Ptr = (WCHAR)0; - LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR); - - Status = NtCreateKey(&LocalKeyHandle, - KEY_CREATE_SUB_KEY, - &LocalObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) - DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status); - } - - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&LocalKeyName); - return Status; - } - - /* Add removed parts of the key name and create them too. */ - while (TRUE) - { - if (LocalKeyName.Length == FullNameLength) - { - Status = STATUS_SUCCESS; - *KeyHandle = LocalKeyHandle; - break; - } - NtClose(LocalKeyHandle); - - LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\'; - LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR); - - Status = NtCreateKey(&LocalKeyHandle, - KEY_ALL_ACCESS, - &LocalObjectAttributes, - 0, - NULL, - CreateOptions, - &Disposition); - DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status); - break; - } - } - - RtlFreeUnicodeString(&LocalKeyName); - - return Status; -} - -/*********************************************************************** - * registry_callback - * - * Called once for each AddReg and DelReg entry in a given section. - */ -static BOOLEAN -registry_callback(HINF hInf, PCWSTR Section, BOOLEAN Delete) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING Name, Value; - PUNICODE_STRING ValuePtr; - UINT Flags; - WCHAR Buffer[MAX_INF_STRING_LENGTH]; - - INFCONTEXT Context; - PCWSTR RootKeyName; - HANDLE RootKeyHandle, KeyHandle; - BOOLEAN Ok; - - Ok = SetupFindFirstLineW(hInf, Section, NULL, &Context); - if (!Ok) - return TRUE; /* Don't fail if the section isn't present */ - - for (;Ok; Ok = SetupFindNextLine (&Context, &Context)) - { - /* get root */ - if (!SetupGetStringFieldW(&Context, 1, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL)) - continue; - RootKeyHandle = GetRootKeyByName(Buffer, &RootKeyName); - if (!RootKeyHandle) - continue; - - /* get key */ - if (!SetupGetStringFieldW(&Context, 2, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL)) - *Buffer = 0; - - DPRINT("KeyName: <%S\\%S>\n", RootKeyName, Buffer); - - /* get flags */ - if (!SetupGetIntField(&Context, 4, (PINT)&Flags)) - Flags = 0; - - DPRINT("Flags: %lx\n", Flags); - - RtlInitUnicodeString(&Name, Buffer); - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - RootKeyHandle, - NULL); - - if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) - { - Status = NtOpenKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &Name, Status); - continue; /* ignore if it doesn't exist */ - } - } - else - { - Status = CreateNestedKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - REG_OPTION_NON_VOLATILE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreateNestedKey(%wZ) failed (Status %lx)\n", &Name, Status); - continue; - } - } - - /* get value name */ - if (SetupGetStringFieldW(&Context, 3, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL)) - { - RtlInitUnicodeString(&Value, Buffer); - ValuePtr = &Value; - } - else - { - ValuePtr = NULL; - } - - /* and now do it */ - if (!do_reg_operation(KeyHandle, ValuePtr, &Context, Flags)) - { - NtClose(KeyHandle); - return FALSE; - } - - NtClose(KeyHandle); - } - - return TRUE; -} - - -BOOLEAN -ImportRegistryFile( - PCWSTR SourcePath, - PWSTR Filename, - PWSTR Section, - LCID LocaleId, - BOOLEAN Delete) -{ - WCHAR FileNameBuffer[MAX_PATH]; - HINF hInf; - UINT ErrorLine; - - /* Load inf file from install media. */ - CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, - SourcePath, Filename); - - hInf = SetupOpenInfFileExW(FileNameBuffer, - NULL, - INF_STYLE_WIN4, - LocaleId, - &ErrorLine); - if (hInf == INVALID_HANDLE_VALUE) - { - DPRINT1("SetupOpenInfFile() failed\n"); - return FALSE; - } - -#if 0 - if (!registry_callback(hInf, L"DelReg", FALSE)) - { - DPRINT1("registry_callback() failed\n"); - InfCloseFile(hInf); - return FALSE; - } -#endif - - if (!registry_callback(hInf, L"AddReg", FALSE)) - { - DPRINT1("registry_callback() failed\n"); - InfCloseFile(hInf); - return FALSE; - } - - if (!registry_callback(hInf, L"AddReg.NT" Architecture, FALSE)) - { - DPRINT1("registry_callback() failed\n"); - InfCloseFile(hInf); - return FALSE; - } - - InfCloseFile(hInf); - return TRUE; -} - -/* - * Should be called under privileges - */ -static NTSTATUS -CreateRegistryFile( - IN PUNICODE_STRING InstallPath, - IN PCWSTR RegistryKey, - IN BOOLEAN IsHiveNew, - IN HANDLE ProtoKeyHandle -/* - IN PUCHAR Descriptor, - IN ULONG DescriptorLength -*/ - ) -{ - /* '.old' is for old valid hives, while '.brk' is for old broken hives */ - static PCWSTR Extensions[] = {L"old", L"brk"}; - - NTSTATUS Status; - HANDLE FileHandle; - UNICODE_STRING FileName; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - PCWSTR Extension; - WCHAR PathBuffer[MAX_PATH]; - WCHAR PathBuffer2[MAX_PATH]; - - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, - InstallPath->Buffer, L"System32\\config", RegistryKey); - - Extension = Extensions[IsHiveNew ? 0 : 1]; - - // - // FIXME: The best, actually, would be to rename (move) the existing - // System32\config\RegistryKey file to System32\config\RegistryKey.old, - // and if it already existed some System32\config\RegistryKey.old, we should - // first rename this one into System32\config\RegistryKey_N.old before - // performing the original rename. - // - - /* Check whether the registry hive file already existed, and if so, rename it */ - if (DoesFileExist(NULL, PathBuffer)) - { - // UINT i; - - DPRINT1("Registry hive '%S' already exists, rename it\n", PathBuffer); - - // i = 1; - /* Try first by just appending the '.old' extension */ - StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s", PathBuffer, Extension); -#if 0 - while (DoesFileExist(NULL, PathBuffer2)) - { - /* An old file already exists, increments its index, but not too much */ - if (i <= 0xFFFF) - { - /* Append '_N.old' extension */ - StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s_%lu.%s", PathBuffer, i, Extension); - ++i; - } - else - { - /* - * Too many old files exist, we will rename the file - * using the name of the oldest one. - */ - StringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2), L"%s.%s", PathBuffer, Extension); - break; - } - } -#endif - - /* Now rename the file (force the move) */ - Status = SetupMoveFile(PathBuffer, PathBuffer2, MOVEFILE_REPLACE_EXISTING); - } - - /* Create the file */ - RtlInitUnicodeString(&FileName, PathBuffer); - InitializeObjectAttributes(&ObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, // Could have been InstallPath, etc... - NULL); // Descriptor - - Status = NtCreateFile(&FileHandle, - FILE_GENERIC_WRITE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OVERWRITE_IF, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName, Status); - return Status; - } - - /* Save the selected hive into the file */ - Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName, Status); - } - - /* Close the file and return */ - NtClose(FileHandle); - return Status; -} - -static BOOLEAN -CmpLinkKeyToHive( - IN HANDLE RootLinkKeyHandle OPTIONAL, - IN PCWSTR LinkKeyName, - IN PCWSTR TargetKeyName) -{ - static UNICODE_STRING CmSymbolicLinkValueName = - RTL_CONSTANT_STRING(L"SymbolicLinkValue"); - - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - HANDLE TargetKeyHandle; - ULONG Disposition; - - /* Initialize the object attributes */ - RtlInitUnicodeString(&KeyName, LinkKeyName); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootLinkKeyHandle, - NULL); - - /* Create the link key */ - Status = NtCreateKey(&TargetKeyHandle, - KEY_SET_VALUE | KEY_CREATE_LINK, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CmpLinkKeyToHive: couldn't create %S, Status = 0x%08lx\n", - LinkKeyName, Status); - return FALSE; - } - - /* Check if the new key was actually created */ - if (Disposition != REG_CREATED_NEW_KEY) - { - DPRINT1("CmpLinkKeyToHive: %S already exists!\n", LinkKeyName); - NtClose(TargetKeyHandle); - return FALSE; - } - - /* Set the target key name as link target */ - RtlInitUnicodeString(&KeyName, TargetKeyName); - Status = NtSetValueKey(TargetKeyHandle, - &CmSymbolicLinkValueName, - 0, - REG_LINK, - KeyName.Buffer, - KeyName.Length); - - /* Close the link key handle */ - NtClose(TargetKeyHandle); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("CmpLinkKeyToHive: couldn't create symbolic link for %S, Status = 0x%08lx\n", - TargetKeyName, Status); - return FALSE; - } - - return TRUE; -} - -/* - * Should be called under privileges - */ -static NTSTATUS -ConnectRegistry( - IN HKEY RootKey OPTIONAL, - IN PCWSTR RegMountPoint, - // IN HANDLE RootDirectory OPTIONAL, - IN PUNICODE_STRING InstallPath, - IN PCWSTR RegistryKey -/* - IN PUCHAR Descriptor, - IN ULONG DescriptorLength -*/ - ) -{ - UNICODE_STRING KeyName, FileName; - OBJECT_ATTRIBUTES KeyObjectAttributes; - OBJECT_ATTRIBUTES FileObjectAttributes; - WCHAR PathBuffer[MAX_PATH]; - - RtlInitUnicodeString(&KeyName, RegMountPoint); - InitializeObjectAttributes(&KeyObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKey, - NULL); // Descriptor - - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3, - InstallPath->Buffer, L"System32\\config", RegistryKey); - RtlInitUnicodeString(&FileName, PathBuffer); - InitializeObjectAttributes(&FileObjectAttributes, - &FileName, - OBJ_CASE_INSENSITIVE, - NULL, // RootDirectory, - NULL); - - /* Mount the registry hive in the registry namespace */ - return NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes); -} - - -static NTSTATUS -VerifyRegistryHive( - // IN HKEY RootKey OPTIONAL, - // // IN HANDLE RootDirectory OPTIONAL, - IN PUNICODE_STRING InstallPath, - IN PCWSTR RegistryKey /* , - IN PCWSTR RegMountPoint */) -{ - NTSTATUS Status; - UNICODE_STRING KeyName; - OBJECT_ATTRIBUTES ObjectAttributes; - - /* Try to mount the specified registry hive */ - Status = ConnectRegistry(NULL, - L"\\Registry\\Machine\\USetup_VerifyHive", - InstallPath, - RegistryKey - /* NULL, 0 */); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey, Status); - } - - DPRINT1("VerifyRegistryHive: ConnectRegistry(%S) returns Status 0x%08lx\n", RegistryKey, Status); - - // - // TODO: Check the Status error codes: STATUS_SUCCESS, STATUS_REGISTRY_RECOVERED, - // STATUS_REGISTRY_HIVE_RECOVERED, STATUS_REGISTRY_CORRUPT, STATUS_REGISTRY_IO_FAILED, - // STATUS_NOT_REGISTRY_FILE, STATUS_CANNOT_LOAD_REGISTRY_FILE ; - //(STATUS_HIVE_UNLOADED) ; STATUS_SYSTEM_HIVE_TOO_LARGE - // - - if (Status == STATUS_REGISTRY_HIVE_RECOVERED) // NT_SUCCESS is still FALSE in this case! - DPRINT1("VerifyRegistryHive: Registry hive %S was recovered but some data may be lost (Status 0x%08lx)\n", RegistryKey, Status); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("VerifyRegistryHive: Registry hive %S is corrupted (Status 0x%08lx)\n", RegistryKey, Status); - return Status; - } - - if (Status == STATUS_REGISTRY_RECOVERED) - DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status 0x%08lx)\n", RegistryKey, Status); - - /* Unmount the hive */ - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\USetup_VerifyHive"); - Status = NtUnloadKey(&ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtUnloadKey(%S, %wZ) failed, Status 0x%08lx\n", RegistryKey, &KeyName, Status); - } - - return Status; -} - - -typedef enum _HIVE_UPDATE_STATE -{ - Create, // Create a new hive file and save possibly existing old one with a .old extension. - Repair, // Re-create a new hive file and save possibly existing old one with a .brk extension. - Update // Hive update, do not need to be recreated. -} HIVE_UPDATE_STATE; - -typedef struct _HIVE_LIST_ENTRY -{ - PCWSTR HiveName; // HiveFileName; - PCWSTR HiveRegistryPath; // HiveRegMountPoint; - HANDLE PredefKeyHandle; - PCWSTR RegSymLink; - HIVE_UPDATE_STATE State; - // PUCHAR SecurityDescriptor; - // ULONG SecurityDescriptorLength; -} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY; - -#define NUMBER_OF_STANDARD_REGISTRY_HIVES 3 - -HIVE_LIST_ENTRY RegistryHives[/*NUMBER_OF_STANDARD_REGISTRY_HIVES*/] = -{ - { L"SYSTEM" , L"\\Registry\\Machine\\USetup_SYSTEM" , HKEY_LOCAL_MACHINE, L"SYSTEM" , Create /* , SystemSecurity , sizeof(SystemSecurity) */ }, - { L"SOFTWARE", L"\\Registry\\Machine\\USetup_SOFTWARE", HKEY_LOCAL_MACHINE, L"SOFTWARE", Create /* , SoftwareSecurity, sizeof(SoftwareSecurity) */ }, - { L"DEFAULT" , L"\\Registry\\User\\USetup_DEFAULT" , HKEY_USERS , L".DEFAULT", Create /* , SystemSecurity , sizeof(SystemSecurity) */ }, - -// { L"BCD" , L"\\Registry\\Machine\\USetup_BCD", HKEY_LOCAL_MACHINE, L"BCD00000000", Create /* , BcdSecurity , sizeof(BcdSecurity) */ }, -}; -C_ASSERT(_countof(RegistryHives) == NUMBER_OF_STANDARD_REGISTRY_HIVES); - -#define NUMBER_OF_SECURITY_REGISTRY_HIVES 2 - -/** These hives are created by LSASS during 2nd stage setup */ -HIVE_LIST_ENTRY SecurityRegistryHives[/*NUMBER_OF_SECURITY_REGISTRY_HIVES*/] = -{ - { L"SAM" , L"\\Registry\\Machine\\USetup_SAM" , HKEY_LOCAL_MACHINE, L"SAM" , Create /* , SystemSecurity , sizeof(SystemSecurity) */ }, - { L"SECURITY", L"\\Registry\\Machine\\USetup_SECURITY", HKEY_LOCAL_MACHINE, L"SECURITY", Create /* , NULL , 0 */ }, -}; -C_ASSERT(_countof(SecurityRegistryHives) == NUMBER_OF_SECURITY_REGISTRY_HIVES); - - -NTSTATUS -VerifyRegistryHives( - IN PUNICODE_STRING InstallPath, - OUT PBOOLEAN ShouldRepairRegistry) -{ - NTSTATUS Status; - BOOLEAN PrivilegeSet[2] = {FALSE, FALSE}; - UINT i; - - /* Suppose first the registry hives do not have to be fully recreated */ - *ShouldRepairRegistry = FALSE; - - /* Acquire restore privilege */ - Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[0]); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status); - /* Exit prematurely here.... */ - return Status; - } - - /* Acquire backup privilege */ - Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status); - RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); - /* Exit prematurely here.... */ - return Status; - } - - for (i = 0; i < ARRAYSIZE(RegistryHives); ++i) - { - Status = VerifyRegistryHive(InstallPath, RegistryHives[i].HiveName); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Registry hive '%S' needs repair!\n", RegistryHives[i].HiveName); - RegistryHives[i].State = Repair; - *ShouldRepairRegistry = TRUE; - } - else - { - RegistryHives[i].State = Update; - } - } - - /** These hives are created by LSASS during 2nd stage setup */ - for (i = 0; i < ARRAYSIZE(SecurityRegistryHives); ++i) - { - Status = VerifyRegistryHive(InstallPath, SecurityRegistryHives[i].HiveName); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Registry hive '%S' needs repair!\n", SecurityRegistryHives[i].HiveName); - SecurityRegistryHives[i].State = Repair; - /* - * Note that it's not the role of the 1st-stage installer to fix - * the security hives. This should be done at 2nd-stage installation - * by LSASS. - */ - } - else - { - SecurityRegistryHives[i].State = Update; - } - } - - /* Reset the status (we succeeded in checking all the hives) */ - Status = STATUS_SUCCESS; - - /* Remove restore and backup privileges */ - RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]); - RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); - - return Status; -} - - -NTSTATUS -RegInitializeRegistry( - IN PUNICODE_STRING InstallPath) -{ - NTSTATUS Status; - HANDLE KeyHandle; - UNICODE_STRING KeyName; - OBJECT_ATTRIBUTES ObjectAttributes; - BOOLEAN PrivilegeSet[2] = {FALSE, FALSE}; - ULONG Disposition; - UINT i; - - /* Acquire restore privilege */ - Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[0]); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status); - /* Exit prematurely here.... */ - return Status; - } - - /* Acquire backup privilege */ - Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status); - RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); - /* Exit prematurely here.... */ - return Status; - } - - /* - * Create the template proto-hive. - * - * Use a dummy root key name: - * - On 2k/XP/2k3, this is "$$$PROTO.HIV" - * - On Vista+, this is "CMI-CreateHive{guid}" - * See
https://github.com/libyal/winreg-kb/blob/master/documentation/Registry%20fi…
- * for more information. - */ - RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\$$$PROTO.HIV"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey() failed to create the proto-hive (Status %lx)\n", Status); - goto Quit; - } - NtFlushKey(KeyHandle); - - for (i = 0; i < ARRAYSIZE(RegistryHives); ++i) - { - if (RegistryHives[i].State != Create && RegistryHives[i].State != Repair) - continue; - - Status = CreateRegistryFile(InstallPath, - RegistryHives[i].HiveName, - RegistryHives[i].State != Repair, // RegistryHives[i].State == Create, - KeyHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreateRegistryFile(%S) failed, Status 0x%08lx\n", RegistryHives[i].HiveName, Status); - /* Exit prematurely here.... */ - /* That is now done, remove the proto-hive */ - NtDeleteKey(KeyHandle); - NtClose(KeyHandle); - goto Quit; - } - } - - /* That is now done, remove the proto-hive */ - NtDeleteKey(KeyHandle); - NtClose(KeyHandle); - - - /* - * Prepare the registry root keys. Since we cannot create real registry keys - * inside the master keys (\Registry, \Registry\Machine or \Registry\User), - * we need to perform some SymLink tricks instead. - */ - - /* Our offline HKLM '\Registry\Machine' is inside '\Registry\Machine\SYSTEM\USetup_Machine' */ - RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].MountPoint); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - KeyHandle = NULL; - Status = NtCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE, // FIXME! - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status); - // return Status; - } - RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle = KeyHandle; - - /* Our offline HKU '\Registry\User' is inside '\Registry\Machine\SYSTEM\USetup_User' */ - RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_USERS)].MountPoint); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - KeyHandle = NULL; - Status = NtCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE, // FIXME! - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status); - // return Status; - } - RootKeys[GetPredefKeyIndex(HKEY_USERS)].Handle = KeyHandle; - - - /* - * Now properly mount the offline hive files - */ - for (i = 0; i < ARRAYSIZE(RegistryHives); ++i) - { - // if (RegistryHives[i].State != Create && RegistryHives[i].State != Repair) - // continue; - - if (RegistryHives[i].State == Create || RegistryHives[i].State == Repair) - { - Status = ConnectRegistry(NULL, - RegistryHives[i].HiveRegistryPath, - InstallPath, - RegistryHives[i].HiveName - /* SystemSecurity, sizeof(SystemSecurity) */); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryHives[i].HiveName, Status); - } - - /* Create the registry symlink to this key */ - if (!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle, - RegistryHives[i].RegSymLink, - RegistryHives[i].HiveRegistryPath)) - { - DPRINT1("CmpLinkKeyToHive(%S) failed!\n", RegistryHives[i].HiveName); - } - } - else - { - /* Create *DUMMY* volatile hives just to make the update procedure working */ - - RtlInitUnicodeString(&KeyName, RegistryHives[i].RegSymLink); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle, - NULL); - KeyHandle = NULL; - Status = NtCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, // REG_OPTION_VOLATILE, // FIXME! - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey(%wZ) failed (Status 0x%08lx)\n", &KeyName, Status); - // return Status; - } - NtClose(KeyHandle); - } - } - - - /* HKCU is a handle to 'HKU\.DEFAULT' */ -#if 0 - RtlInitUnicodeString(&KeyName, L".DEFAULT"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKeys[GetPredefKeyIndex(HKEY_USERS)].Handle, - NULL); -#else - RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_CURRENT_USER)].MountPoint); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); -#endif - KeyHandle = NULL; - Status = NtOpenKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &KeyName, Status); - } - RootKeys[GetPredefKeyIndex(HKEY_CURRENT_USER)].Handle = KeyHandle; - - - /* HKCR is a handle to 'HKLM\Software\Classes' */ -#if 0 - RtlInitUnicodeString(&KeyName, L"Software\\Classes"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, - NULL); -#else - RtlInitUnicodeString(&KeyName, RootKeys[GetPredefKeyIndex(HKEY_CLASSES_ROOT)].MountPoint); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); -#endif - KeyHandle = NULL; - /* We use NtCreateKey instead of NtOpenKey because Software\Classes doesn't exist originally */ - Status = NtCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey(%wZ) failed (Status %lx)\n", &KeyName, Status); - } - else - { - DPRINT1("NtCreateKey() succeeded to %s the %wZ key (Status %lx)\n", - Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open", - &KeyName, Status); - } - RootKeys[GetPredefKeyIndex(HKEY_CLASSES_ROOT)].Handle = KeyHandle; - - - Status = STATUS_SUCCESS; - - - /* Create the 'HKLM\SYSTEM\ControlSet001' key */ - // REGISTRY_SETUP_MACHINE L"SYSTEM\\ControlSet001" - RtlInitUnicodeString(&KeyName, L"SYSTEM\\ControlSet001"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, - NULL); - Status = NtCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey() failed to create the ControlSet001 key (Status %lx)\n", Status); - // return Status; - } - else - { - DPRINT1("NtCreateKey() succeeded to %s the ControlSet001 key (Status %lx)\n", - Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open", - Status); - } - NtClose(KeyHandle); - - /* Create the 'HKLM\SYSTEM\CurrentControlSet' symlink */ - if (!CmpLinkKeyToHive(RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, - L"SYSTEM\\CurrentControlSet", - REGISTRY_SETUP_MACHINE L"SYSTEM\\ControlSet001")) - { - DPRINT1("CmpLinkKeyToHive(CurrentControlSet) failed!\n"); - } - - - Status = STATUS_SUCCESS; - - -Quit: - /* Remove restore and backup privileges */ - RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]); - RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); - - return Status; -} - -VOID -RegCleanupRegistry( - IN PUNICODE_STRING InstallPath) -{ - NTSTATUS Status; - HANDLE KeyHandle; - UNICODE_STRING KeyName; - OBJECT_ATTRIBUTES ObjectAttributes; - BOOLEAN PrivilegeSet[2] = {FALSE, FALSE}; - UINT i; - WCHAR SrcPath[MAX_PATH]; - WCHAR DstPath[MAX_PATH]; - - /* Acquire restore privilege */ - Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[0]); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status); - /* Exit prematurely here.... */ - return; - } - - /* Acquire backup privilege */ - Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status); - RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); - /* Exit prematurely here.... */ - return; - } - - /* - * Note that we don't need to explicitly remove the symlinks we have created - * since they are created volatile, inside registry keys that will be however - * removed explictly in the following. - */ - - for (i = 0; i < ARRAYSIZE(RegistryHives); ++i) - { - if (RegistryHives[i].State != Create && RegistryHives[i].State != Repair) - { - RtlInitUnicodeString(&KeyName, RegistryHives[i].RegSymLink); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - RootKeys[GetPredefKeyIndex(RegistryHives[i].PredefKeyHandle)].Handle, - NULL); - KeyHandle = NULL; - Status = NtOpenKey(&KeyHandle, - DELETE, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenKey(%wZ) failed, Status 0x%08lx\n", &KeyName, Status); - // return; - } - - NtDeleteKey(KeyHandle); - NtClose(KeyHandle); - } - else - { - RtlInitUnicodeString(&KeyName, RegistryHives[i].HiveRegistryPath); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - // Status = NtUnloadKey(&ObjectAttributes); - Status = NtUnloadKey2(&ObjectAttributes, 1 /* REG_FORCE_UNLOAD */); - DPRINT1("Unmounting '%S' %s\n", RegistryHives[i].HiveRegistryPath, NT_SUCCESS(Status) ? "succeeded" : "failed"); - - /* Switch the hive state to 'Update' */ - RegistryHives[i].State = Update; - } - } - - /* - * FIXME: Once force-unloading keys is correctly fixed, I'll fix - * this code that closes some of the registry keys that were opened - * inside the hives we've just unmounted above... - */ - - /* Remove the registry root keys */ - for (i = 0; i < ARRAYSIZE(RootKeys); ++i) - { - if (RootKeys[i].Handle) - { - /**/NtFlushKey(RootKeys[i].Handle);/**/ // FIXME: Why does it hang? Answer: because we have some problems in CMAPI! - NtDeleteKey(RootKeys[i].Handle); - NtClose(RootKeys[i].Handle); - RootKeys[i].Handle = NULL; - } - } - - // - // RegBackupRegistry() - // - /* Now backup the hives into .sav files */ - for (i = 0; i < ARRAYSIZE(RegistryHives); ++i) - { - if (RegistryHives[i].State != Create && RegistryHives[i].State != Repair) - continue; - - CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 3, - InstallPath->Buffer, L"System32\\config", RegistryHives[i].HiveName); - StringCchCopyW(DstPath, ARRAYSIZE(DstPath), SrcPath); - StringCchCatW(DstPath, ARRAYSIZE(DstPath), L".sav"); - - DPRINT1("Copy hive: %S ==> %S\n", SrcPath, DstPath); - Status = SetupCopyFile(SrcPath, DstPath, FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); - // return Status; - } - } - - /* Remove restore and backup privileges */ - RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]); - RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]); -} - - VOID SetDefaultPagefile( WCHAR Drive) @@ -1520,7 +47,7 @@ SetDefaultPagefile( InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, - RootKeys[GetPredefKeyIndex(HKEY_LOCAL_MACHINE)].Handle, + GetRootKeyByPredefKey(HKEY_LOCAL_MACHINE, NULL), NULL); Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, diff --git a/base/setup/usetup/registry.h b/base/setup/usetup/registry.h index b48777a126..ef53b708ff 100644 --- a/base/setup/usetup/registry.h +++ b/base/setup/usetup/registry.h @@ -26,37 +26,6 @@ #pragma once -HANDLE -GetRootKeyByPredefKey( - IN HANDLE KeyHandle, - OUT PCWSTR* RootKeyMountPoint OPTIONAL); - -HANDLE -GetRootKeyByName( - IN PCWSTR RootKeyName, - OUT PCWSTR* RootKeyMountPoint OPTIONAL); - -BOOLEAN -ImportRegistryFile( - PCWSTR SourcePath, - PWSTR Filename, - PWSTR Section, - LCID LocaleId, - BOOLEAN Delete); - -NTSTATUS -VerifyRegistryHives( - IN PUNICODE_STRING InstallPath, - OUT PBOOLEAN ShouldRepairRegistry); - -NTSTATUS -RegInitializeRegistry( - IN PUNICODE_STRING InstallPath); - -VOID -RegCleanupRegistry( - IN PUNICODE_STRING InstallPath); - VOID SetDefaultPagefile( WCHAR Drive); diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h index 6e95582ce7..ca7fed0671 100644 --- a/base/setup/usetup/usetup.h +++ b/base/setup/usetup/usetup.h @@ -61,7 +61,6 @@ #include "consup.h" #include "inffile.h" #include "progress.h" -#include "infros.h" #include "filequeue.h" #include "registry.h" #include "fslist.h"
6 years, 2 months
1
0
0
0
01/01: [WIN32SS][NTUSER] Sunken menu item (#981)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ed41bd71dd13ad68af40a…
commit ed41bd71dd13ad68af40a55b4b36549a834e7eaf Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Oct 27 04:20:09 2018 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Oct 27 04:20:09 2018 +0900 [WIN32SS][NTUSER] Sunken menu item (#981) CORE-15226 --- win32ss/user/ntuser/menu.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/win32ss/user/ntuser/menu.c b/win32ss/user/ntuser/menu.c index f4159030cc..dfab116bbc 100644 --- a/win32ss/user/ntuser/menu.c +++ b/win32ss/user/ntuser/menu.c @@ -1657,9 +1657,12 @@ static void FASTCALL MENU_DrawBitmapItem(HDC hdc, PITEM lpitem, const RECT *rect int h = rect->bottom - rect->top; int bmp_xoffset = 0; int left, top; + BOOL flat_menu; HBITMAP hbmToDraw = lpitem->hbmp; bmp = hbmToDraw; + UserSystemParametersInfo(SPI_GETFLATMENU, 0, &flat_menu, 0); + /* Check if there is a magic menu item associated with this item */ if (IS_MAGIC_BITMAP(hbmToDraw)) { @@ -1778,6 +1781,12 @@ static void FASTCALL MENU_DrawBitmapItem(HDC hdc, PITEM lpitem, const RECT *rect rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY; if ((lpitem->fState & MF_HILITE) && lpitem->hbmp) IntGdiSetBkColor(hdc, IntGetSysColor(COLOR_HIGHLIGHT)); + if (!flat_menu && + (lpitem->fState & (MF_HILITE | MF_GRAYED)) == MF_HILITE) + { + ++left; + ++top; + } NtGdiBitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop , 0, 0); IntGdiDeleteDC( hdcMem, FALSE ); } @@ -2325,10 +2334,15 @@ static void FASTCALL MENU_DrawMenuItem(PWND Wnd, PMENU Menu, PWND WndOwner, HDC } else { - if(menuBar) + if (menuBar) + { + FillRect(hdc, &rect, IntGetSysColorBrush(COLOR_MENU)); DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT); + } else + { FillRect(hdc, &rect, IntGetSysColorBrush(COLOR_HIGHLIGHT)); + } } } else @@ -2517,6 +2531,12 @@ static void FASTCALL MENU_DrawMenuItem(PWND Wnd, PMENU Menu, PWND WndOwner, HDC break; } + if (!flat_menu && + (lpitem->fState & (MF_HILITE | MF_GRAYED)) == MF_HILITE) + { + RECTL_vOffsetRect(&rect, +1, +1); + } + if(lpitem->fState & MF_GRAYED) { if (!(lpitem->fState & MF_HILITE) ) @@ -2558,6 +2578,12 @@ static void FASTCALL MENU_DrawMenuItem(PWND Wnd, PMENU Menu, PWND WndOwner, HDC DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat ); } + if (!flat_menu && + (lpitem->fState & (MF_HILITE | MF_GRAYED)) == MF_HILITE) + { + RECTL_vOffsetRect(&rect, -1, -1); + } + if (hfontOld) { NtGdiSelectFont (hdc, hfontOld);
6 years, 2 months
1
0
0
0
01/01: [CMAKE] Use configured include files to define the __RELFILE__ hack (#979)
by Jérôme Gardou
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=07bd6089ec96b068d92f4…
commit 07bd6089ec96b068d92f42e764cc7336a7de24a0 Author: Jérôme Gardou <zefklop(a)users.noreply.github.com> AuthorDate: Fri Oct 26 13:47:22 2018 +0200 Commit: GitHub <noreply(a)github.com> CommitDate: Fri Oct 26 13:47:22 2018 +0200 [CMAKE] Use configured include files to define the __RELFILE__ hack (#979) [CMAKE] Use configured include files to define the __RELFILE__ hack It's easier on the command line and the eyes looking at it --- CMakeLists.txt | 3 --- sdk/include/reactos/builddir.h.cmake | 7 +++++++ sdk/include/reactos/debug.h | 7 ++++++- sdk/include/reactos/version.cmake | 1 + sdk/include/reactos/wine/debug.h | 7 ++++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2e8b861ee..f79577f65d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,9 +57,6 @@ endif() include(sdk/cmake/compilerflags.cmake) add_definitions(-D__REACTOS__) -add_definitions(-DREACTOS_SOURCE_DIR="\\"${REACTOS_SOURCE_DIR}\\"") -add_definitions(-DREACTOS_BINARY_DIR="\\"${REACTOS_BINARY_DIR}\\"") -add_compile_flags(-D__RELFILE__="&__FILE__[sizeof REACTOS_SOURCE_DIR]") if(MSVC_IDE) add_compile_flags("/MP") diff --git a/sdk/include/reactos/builddir.h.cmake b/sdk/include/reactos/builddir.h.cmake new file mode 100644 index 0000000000..8bd5b44ac5 --- /dev/null +++ b/sdk/include/reactos/builddir.h.cmake @@ -0,0 +1,7 @@ +/* Do not edit - Machine generated */ +#pragma once + +#define REACTOS_SOURCE_DIR "@REACTOS_SOURCE_DIR@" +#define REACTOS_BINARY_DIR "@REACTOS_BINARY_DIR@" + +/* EOF */ diff --git a/sdk/include/reactos/debug.h b/sdk/include/reactos/debug.h index ab332fda18..f56090b65c 100644 --- a/sdk/include/reactos/debug.h +++ b/sdk/include/reactos/debug.h @@ -15,7 +15,12 @@ #pragma once #ifndef __RELFILE__ -#define __RELFILE__ __FILE__ +# ifdef __REACTOS__ +# include <reactos/builddir.h> +# define __RELFILE__ &__FILE__[sizeof(REACTOS_SOURCE_DIR)] +# else +# define __RELFILE__ __FILE__ +# endif #endif /* Define DbgPrint/DbgPrintEx/RtlAssert unless the NDK is used */ diff --git a/sdk/include/reactos/version.cmake b/sdk/include/reactos/version.cmake index 9314a56cfc..46a424728a 100644 --- a/sdk/include/reactos/version.cmake +++ b/sdk/include/reactos/version.cmake @@ -53,3 +53,4 @@ endif() configure_file(sdk/include/reactos/version.h.cmake ${REACTOS_BINARY_DIR}/sdk/include/reactos/version.h) configure_file(sdk/include/reactos/buildno.h.cmake ${REACTOS_BINARY_DIR}/sdk/include/reactos/buildno.h) +configure_file(sdk/include/reactos/builddir.h.cmake ${REACTOS_BINARY_DIR}/sdk/include/reactos/builddir.h) diff --git a/sdk/include/reactos/wine/debug.h b/sdk/include/reactos/wine/debug.h index 35aefc9852..23f402a13f 100644 --- a/sdk/include/reactos/wine/debug.h +++ b/sdk/include/reactos/wine/debug.h @@ -28,7 +28,12 @@ #endif #ifndef __RELFILE__ -#define __RELFILE__ __FILE__ +# ifdef __REACTOS__ +# include <reactos/builddir.h> +# define __RELFILE__ &__FILE__[sizeof(REACTOS_SOURCE_DIR)] +# else +# define __RELFILE__ __FILE__ +# endif #endif #ifdef __WINE_WINE_TEST_H
6 years, 2 months
1
0
0
0
01/01: [APITESTS][USER32] Add testcase for SwitchToThisWindow (#980)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3e00e7fb22fe98e32f6d9…
commit 3e00e7fb22fe98e32f6d93c34e1d1cf058146758 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Fri Oct 26 19:56:25 2018 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Fri Oct 26 19:56:25 2018 +0900 [APITESTS][USER32] Add testcase for SwitchToThisWindow (#980) Add an API test program for user32!SwitchToThisWindow function. JIRA issue: CORE-15165 --- modules/rostests/apitests/user32/CMakeLists.txt | 1 + .../rostests/apitests/user32/SwitchToThisWindow.c | 214 +++++++++++++++++++++ modules/rostests/apitests/user32/testlist.c | 2 + 3 files changed, 217 insertions(+) diff --git a/modules/rostests/apitests/user32/CMakeLists.txt b/modules/rostests/apitests/user32/CMakeLists.txt index 4d901a4c9d..0a82490574 100644 --- a/modules/rostests/apitests/user32/CMakeLists.txt +++ b/modules/rostests/apitests/user32/CMakeLists.txt @@ -36,6 +36,7 @@ list(APPEND SOURCE SetProp.c SetScrollInfo.c SetScrollRange.c + SwitchToThisWindow.c SystemParametersInfo.c TrackMouseEvent.c WndProc.c diff --git a/modules/rostests/apitests/user32/SwitchToThisWindow.c b/modules/rostests/apitests/user32/SwitchToThisWindow.c new file mode 100644 index 0000000000..e89bf11c47 --- /dev/null +++ b/modules/rostests/apitests/user32/SwitchToThisWindow.c @@ -0,0 +1,214 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for SwitchToThisWindow + * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> + */ + +#include "precomp.h" + +static const WCHAR s_szClassName[] = L"SwitchTest"; + +static BOOL s_bTracing = FALSE; + +static INT s_nWM_SYSCOMMAND_SC_RESTORE = 0; +static INT s_nWM_SYSCOMMAND_NOT_SC_RESTORE = 0; +static INT s_nWM_NCACTIVATE = 0; +static INT s_nWM_WINDOWPOSCHANGING = 0; +static INT s_nWM_ACTIVATE = 0; + +#define TIMER_INTERVAL 200 + +static void +DoMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_TIMER || !s_bTracing) + return; + + trace("uMsg:0x%04X, wParam:0x%08lX, lParam:0x%08lX\n", uMsg, (LONG)wParam, (LONG)lParam); + + if (uMsg == WM_SYSCOMMAND) + { + if (wParam == SC_RESTORE) + ++s_nWM_SYSCOMMAND_SC_RESTORE; + else + ++s_nWM_SYSCOMMAND_NOT_SC_RESTORE; + } + + if (uMsg == WM_NCACTIVATE) + ++s_nWM_NCACTIVATE; + + if (uMsg == WM_WINDOWPOSCHANGING) + ++s_nWM_WINDOWPOSCHANGING; + + if (uMsg == WM_ACTIVATE) + ++s_nWM_ACTIVATE; +} + +// WM_TIMER +static void +OnTimer(HWND hwnd, UINT id) +{ + KillTimer(hwnd, id); + switch (id) + { + // + // SwitchToThisWindow(TRUE) + // + case 0: // minimize + SetForegroundWindow(GetDesktopWindow()); + SetActiveWindow(GetDesktopWindow()); + ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n"); + ok(GetActiveWindow() == NULL, "GetActiveWindow() != NULL\n"); + ok(GetFocus() == NULL, "GetFocus() != NULL\n"); + CloseWindow(hwnd); // minimize + break; + case 1: // start tracing + ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n"); + ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n"); + ok(GetFocus() == NULL, "GetFocus() != NULL\n"); + s_nWM_SYSCOMMAND_SC_RESTORE = 0; + s_nWM_SYSCOMMAND_NOT_SC_RESTORE = 0; + s_nWM_NCACTIVATE = 0; + s_nWM_WINDOWPOSCHANGING = 0; + s_nWM_ACTIVATE = 0; + s_bTracing = TRUE; + SwitchToThisWindow(hwnd, TRUE); + trace("SwitchToThisWindow(TRUE): tracing...\n"); + break; + case 2: // tracing done + s_bTracing = FALSE; + trace("SwitchToThisWindow(TRUE): tracing done\n"); + ok(GetForegroundWindow() == hwnd, "GetForegroundWindow() != hwnd\n"); + ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n"); + ok(GetFocus() == hwnd, "GetFocus() != hwnd\n"); + ok(s_nWM_SYSCOMMAND_SC_RESTORE == 1, "WM_SYSCOMMAND SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_SC_RESTORE); + ok(!s_nWM_SYSCOMMAND_NOT_SC_RESTORE, "WM_SYSCOMMAND non-SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_NOT_SC_RESTORE); + ok(s_nWM_NCACTIVATE > 0, "WM_NCACTIVATE: not found\n"); + ok(s_nWM_WINDOWPOSCHANGING > 0, "WM_WINDOWPOSCHANGING: not found\n"); + ok(s_nWM_ACTIVATE > 0, "WM_ACTIVATE: not found\n"); + break; + // + // SwitchToThisWindow(FALSE) + // + case 3: // minimize + SetForegroundWindow(GetDesktopWindow()); + SetActiveWindow(GetDesktopWindow()); + ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n"); + ok(GetActiveWindow() == NULL, "GetActiveWindow() != NULL\n"); + ok(GetFocus() == NULL, "GetFocus() != NULL\n"); + CloseWindow(hwnd); // minimize + break; + case 4: // start tracing + ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n"); + ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n"); + ok(GetFocus() == NULL, "GetFocus() != NULL\n"); + s_nWM_SYSCOMMAND_SC_RESTORE = 0; + s_nWM_SYSCOMMAND_NOT_SC_RESTORE = 0; + s_nWM_NCACTIVATE = 0; + s_nWM_WINDOWPOSCHANGING = 0; + s_nWM_ACTIVATE = 0; + s_bTracing = TRUE; + SwitchToThisWindow(hwnd, FALSE); + trace("SwitchToThisWindow(FALSE): tracing...\n"); + break; + case 5: // tracing done + s_bTracing = FALSE; + trace("SwitchToThisWindow(FALSE): tracing done\n"); + ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n"); + ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n"); + ok(GetFocus() == NULL, "GetFocus() != NULL\n"); + ok(!s_nWM_SYSCOMMAND_SC_RESTORE, "WM_SYSCOMMAND SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_SC_RESTORE); + ok(!s_nWM_SYSCOMMAND_NOT_SC_RESTORE, "WM_SYSCOMMAND non-SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_NOT_SC_RESTORE); + ok(!s_nWM_NCACTIVATE, "WM_NCACTIVATE: %d\n", s_nWM_NCACTIVATE); + ok(!s_nWM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING: %d\n", s_nWM_WINDOWPOSCHANGING); + ok(!s_nWM_ACTIVATE, "WM_ACTIVATE: %d\n", s_nWM_ACTIVATE); + break; + default: // finish + DestroyWindow(hwnd); + return; + } + SetTimer(hwnd, id + 1, TIMER_INTERVAL, NULL); +} + +static LRESULT CALLBACK +WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + DoMessage(hwnd, uMsg, wParam, lParam); + switch (uMsg) + { + case WM_CREATE: + SetTimer(hwnd, 0, TIMER_INTERVAL, NULL); + break; + case WM_TIMER: + OnTimer(hwnd, (UINT)wParam); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + return 0; +} + +START_TEST(SwitchToThisWindow) +{ + WNDCLASSW wc; + HICON hIcon; + HCURSOR hCursor; + ATOM atom; + HWND hwnd; + MSG msg; + + hIcon = LoadIcon(NULL, IDI_APPLICATION); + ok(hIcon != NULL, "hIcon was NULL\n"); + hCursor = LoadCursor(NULL, IDC_ARROW); + ok(hCursor != NULL, "hCursor was NULL\n"); + + ZeroMemory(&wc, sizeof(wc)); + wc.lpfnWndProc = WindowProc; + wc.hInstance = GetModuleHandleW(NULL); + wc.hIcon = hIcon; + wc.hCursor = hCursor; + wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); + wc.lpszClassName = s_szClassName; + atom = RegisterClassW(&wc); + ok(atom != 0, "RegisterClassW failed\n"); + + if (!atom) + { + skip("atom is zero\n"); + DestroyIcon(hIcon); + DestroyCursor(hCursor); + return; + } + + hwnd = CreateWindowW(s_szClassName, L"SwitchToThisWindow", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, + NULL, NULL, GetModuleHandleW(NULL), NULL); + ok(hwnd != NULL, "CreateWindowW failed\n"); + trace("hwnd: %p\n", hwnd); + + if (!hwnd) + { + skip("hwnd is NULL\n"); + UnregisterClassW(s_szClassName, GetModuleHandleW(NULL)); + DestroyIcon(hIcon); + DestroyCursor(hCursor); + return; + } + + ShowWindow(hwnd, SW_SHOWNORMAL); + UpdateWindow(hwnd); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + UnregisterClassW(s_szClassName, GetModuleHandleW(NULL)); + DestroyIcon(hIcon); + DestroyCursor(hCursor); +} diff --git a/modules/rostests/apitests/user32/testlist.c b/modules/rostests/apitests/user32/testlist.c index 86a1bdbc84..1155a39aa8 100644 --- a/modules/rostests/apitests/user32/testlist.c +++ b/modules/rostests/apitests/user32/testlist.c @@ -38,6 +38,7 @@ extern void func_SetParent(void); extern void func_SetProp(void); extern void func_SetScrollInfo(void); extern void func_SetScrollRange(void); +extern void func_SwitchToThisWindow(void); extern void func_SystemParametersInfo(void); extern void func_TrackMouseEvent(void); extern void func_WndProc(void); @@ -80,6 +81,7 @@ const struct test winetest_testlist[] = { "SetProp", func_SetProp }, { "SetScrollInfo", func_SetScrollInfo }, { "SetScrollRange", func_SetScrollRange }, + { "SwitchToThisWindow", func_SwitchToThisWindow }, { "SystemParametersInfo", func_SystemParametersInfo }, { "TrackMouseEvent", func_TrackMouseEvent }, { "WndProc", func_WndProc },
6 years, 2 months
1
0
0
0
← Newer
1
...
9
10
11
12
13
14
15
...
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