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
2025
March
February
January
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
February 2025
----- 2025 -----
March 2025
February 2025
January 2025
----- 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
17 participants
79 discussions
Start a n
N
ew thread
[reactos] 01/01: [SHIMGVW] Update Portuguese (pt-PT) translation (#7688)
by Jose Carlos Jesus
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a07a35d0f6139e759a59c…
commit a07a35d0f6139e759a59c6fe645a8912472d4516 Author: Jose Carlos Jesus <zecarlos1957(a)hotmail.com> AuthorDate: Mon Feb 3 11:59:22 2025 +0000 Commit: GitHub <noreply(a)github.com> CommitDate: Mon Feb 3 12:59:22 2025 +0100 [SHIMGVW] Update Portuguese (pt-PT) translation (#7688) And add file header. --- dll/win32/shimgvw/lang/pt-PT.rc | 46 +++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/dll/win32/shimgvw/lang/pt-PT.rc b/dll/win32/shimgvw/lang/pt-PT.rc index d51396c5018..c224cd5f3ba 100644 --- a/dll/win32/shimgvw/lang/pt-PT.rc +++ b/dll/win32/shimgvw/lang/pt-PT.rc @@ -1,6 +1,8 @@ -/* Portuguese Language resource file - * - * Traduzido por: Jose Carlos Jesus 17-01-2020 zecarlos1957(a)hotmail.com +/* + * PROJECT: ReactOS Picture and Fax Viewer + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) + * PURPOSE: Portuguese (Portugal) resource file + * TRANSLATOR: Copyright 2019-2025 Jose Carlos Jesus <zecarlos1957(a)hotmail.com> */ LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL @@ -9,34 +11,34 @@ STRINGTABLE BEGIN IDS_APPTITLE "Visualizador de imagens e faxes do ReactOS" IDS_SETASDESKBG "Definir como plano de fundo da área de trabalho" - IDS_NOPREVIEW "No preview available." - IDS_PREVIEW "Pre-visualizar" + IDS_NOPREVIEW "Nenhuma pré-visualização disponível." + IDS_PREVIEW "Pré-visualizar" /* Tooltips */ IDS_TOOLTIP_NEXT_PIC "Próxima imagem" IDS_TOOLTIP_PREV_PIC "Imagem anterior" - IDS_TOOLTIP_BEST_FIT "Best fit to window (Ctrl+B)" - IDS_TOOLTIP_REAL_SIZE "Actual size (Ctrl+A)" - IDS_TOOLTIP_SLIDE_SHOW "Start slideshow (F11)" + IDS_TOOLTIP_BEST_FIT "Melhor ajuste à janela(Ctrl+B)" + IDS_TOOLTIP_REAL_SIZE "Tamanho actual (Ctrl+A)" + IDS_TOOLTIP_SLIDE_SHOW "Iniciar apresentação de diapositivos (F11)" IDS_TOOLTIP_ZOOM_IN "Zoom (+)" IDS_TOOLTIP_ZOOM_OUT "Zoom (-)" - IDS_TOOLTIP_ROT_CLOCKW "Girar no sentido dos ponteiros do relógio(Ctrl+K)" - IDS_TOOLTIP_ROT_COUNCW "Girar no sentido anti-horário (Ctrl+L)" - IDS_TOOLTIP_ROT_CWSAVE "Rotate Clockwise and Save (Lossy)" - IDS_TOOLTIP_ROT_CCWSAVE "Rotate Counterclockwise and Save (Lossy)" - IDS_TOOLTIP_DELETE "Delete (DEL)" + IDS_TOOLTIP_ROT_CLOCKW "Girar no sentido dos ponteiros do relógio (Ctrl+K)" + IDS_TOOLTIP_ROT_COUNCW "Girar no sentido contrário aos ponteiros do relógio (Ctrl+L)" + IDS_TOOLTIP_ROT_CWSAVE "Girar no sentido dos ponteiros do relógio e guardar (com perdas)" + IDS_TOOLTIP_ROT_CCWSAVE "Girar no sentido contrário aos ponteiros do relógio e guardar (com perdas)" + IDS_TOOLTIP_DELETE "Eliminar (DEL)" IDS_TOOLTIP_PRINT "Imprimir (Ctrl+P)" IDS_TOOLTIP_SAVEAS "Guardar como... (Ctrl+S)" - IDS_TOOLTIP_MODIFY "Modify (Ctrl+E)" - IDS_TOOLTIP_HELP_TOC "Help topics (F1)" + IDS_TOOLTIP_MODIFY "Modificar (Ctrl+E)" + IDS_TOOLTIP_HELP_TOC "Tópicos da ajuda (F1)" END STRINGTABLE BEGIN - IDS_EMF_FILE "EMF Image" - IDS_GIF_FILE "GIF Image" - IDS_JPG_FILE "JPEG Image" - IDS_BMP_FILE "Bitmap Image" - IDS_PNG_FILE "PNG Image" - IDS_TIF_FILE "TIF Image" - IDS_WMF_FILE "WMF Image" + IDS_EMF_FILE "Imagem EMF" + IDS_GIF_FILE "Imagem GIF" + IDS_JPG_FILE "Imagem JPEG" + IDS_BMP_FILE "Imagem Bitmap" + IDS_PNG_FILE "Imagem PNG" + IDS_TIF_FILE "Imagem TIF" + IDS_WMF_FILE "Imagem WMF" END
4 weeks
1
0
0
0
[reactos] 01/01: [e1000][ne2000][pcnet][rtl8139] Add missing UpperRange and LowerRange values to network adapter inf files
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9c8ef7369fabdea8fd2d1…
commit 9c8ef7369fabdea8fd2d1da3e12de0e8e9d02c7e Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Mon Feb 3 01:15:10 2025 +0100 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Mon Feb 3 01:15:10 2025 +0100 [e1000][ne2000][pcnet][rtl8139] Add missing UpperRange and LowerRange values to network adapter inf files These values will be used for binding network adapters to protocol drivers. Right now we use hard-coded binding. --- drivers/network/dd/e1000/nete1000.inf | 6 ++++++ drivers/network/dd/ne2000/netne.inf | 3 +++ drivers/network/dd/pcnet/netamd.inf | 3 +++ drivers/network/dd/rtl8139/netrtl.inf | 6 ++++++ 4 files changed, 18 insertions(+) diff --git a/drivers/network/dd/e1000/nete1000.inf b/drivers/network/dd/e1000/nete1000.inf index 7ae4df0d4f1..2540412a129 100644 --- a/drivers/network/dd/e1000/nete1000.inf +++ b/drivers/network/dd/e1000/nete1000.inf @@ -61,11 +61,17 @@ DefaultDestDir = 12 [E1000_Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 5 ; PCIBus +AddReg = E1000_AddReg.NT CopyFiles = E1000_CopyFiles.NT [E1000_CopyFiles.NT] e1000.sys +[E1000_AddReg.NT] +HKR, Ndi, Service, 0, "e1000" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" + [E1000_Inst.ndi.NT.Services] AddService = e1000, 0x00000002, E1000_Service_Inst diff --git a/drivers/network/dd/ne2000/netne.inf b/drivers/network/dd/ne2000/netne.inf index 208e6c49a29..01a07793207 100644 --- a/drivers/network/dd/ne2000/netne.inf +++ b/drivers/network/dd/ne2000/netne.inf @@ -42,6 +42,9 @@ CopyFiles = NE2000_CopyFiles.NT [NE2000_AddReg.NT] HKR,,Port,0x00000000,"c100" HKR,,Irq,0x00000000,"B" +HKR, Ndi, Service, 0, "ne2000" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" [NE2000_CopyFiles.NT] ne2000.sys diff --git a/drivers/network/dd/pcnet/netamd.inf b/drivers/network/dd/pcnet/netamd.inf index 5792ffd58d3..0ac4fd6f7fe 100644 --- a/drivers/network/dd/pcnet/netamd.inf +++ b/drivers/network/dd/pcnet/netamd.inf @@ -39,6 +39,9 @@ HKR,,LED2,,"10000" HKR,,LED3,,"10000" HKR,,MPMODE,,"0" HKR,,TP,,"1" +HKR, Ndi, Service, 0, "PCNet" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" [PCNet_CopyFiles.NT] pcnet.sys diff --git a/drivers/network/dd/rtl8139/netrtl.inf b/drivers/network/dd/rtl8139/netrtl.inf index 461376d408d..5ffbe9283c0 100644 --- a/drivers/network/dd/rtl8139/netrtl.inf +++ b/drivers/network/dd/rtl8139/netrtl.inf @@ -43,11 +43,17 @@ DefaultDestDir = 12 [RTL8139_Inst.ndi.NT] Characteristics = 0x4 ; NCF_PHYSICAL BusType = 5 ; PCIBus +AddReg = RTL8139_AddReg.NT CopyFiles = RTL8139_CopyFiles.NT [RTL8139_CopyFiles.NT] rtl8139.sys +[RTL8139_AddReg.NT] +HKR, Ndi, Service, 0, "rtl8139" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" + [RTL8139_Inst.ndi.NT.Services] AddService = rtl8139, 0x00000002, RTL8139_Service_Inst
4 weeks, 1 day
1
0
0
0
[reactos] 03/03: [NTOS:IO] Rewrite OpenRegistryHandlesFromSymbolicLink Also add a new IopOpenOrCreateSymbolicLinkSubKeys routine, which does some work for it. CORE-17361
by Oleg Dubinskiy
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a8669e023ad50b4afb714…
commit a8669e023ad50b4afb714bf12002f2d5d22080ad Author: Oleg Dubinskiy <oleg.dubinskij2013(a)yandex.ua> AuthorDate: Fri Jan 21 21:05:03 2022 +0200 Commit: Oleg Dubinskiy <oleg.dubinskij30(a)gmail.com> CommitDate: Sun Feb 2 23:30:38 2025 +0100 [NTOS:IO] Rewrite OpenRegistryHandlesFromSymbolicLink Also add a new IopOpenOrCreateSymbolicLinkSubKeys routine, which does some work for it. CORE-17361 --- ntoskrnl/io/iomgr/deviface.c | 347 +++++++++++++++++++++++++++---------------- 1 file changed, 221 insertions(+), 126 deletions(-) diff --git a/ntoskrnl/io/iomgr/deviface.c b/ntoskrnl/io/iomgr/deviface.c index a5f20efb50a..5c3391f929b 100644 --- a/ntoskrnl/io/iomgr/deviface.c +++ b/ntoskrnl/io/iomgr/deviface.c @@ -287,187 +287,282 @@ IopSeparateSymbolicLink( return Status; } +/** + * @brief + * Retrieves a handles to the device and instance registry keys + * for the previously opened registry key handle of the specified symbolic link. + **/ static NTSTATUS -OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName, - IN ACCESS_MASK DesiredAccess, - IN OPTIONAL PHANDLE GuidKey, - IN OPTIONAL PHANDLE DeviceKey, - IN OPTIONAL PHANDLE InstanceKey) +IopOpenOrCreateSymbolicLinkSubKeys( + _Out_opt_ PHANDLE DeviceHandle, + _Out_opt_ PULONG DeviceDisposition, + _Out_opt_ PHANDLE InstanceHandle, + _Out_opt_ PULONG InstanceDisposition, + _In_ HANDLE ClassHandle, + _In_ PCUNICODE_STRING SymbolicLinkName, + _In_ ACCESS_MASK DesiredAccess, + _In_ BOOLEAN Create) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING BaseKeyU; - UNICODE_STRING GuidString, SubKeyName, ReferenceString; - PWCHAR StartPosition, EndPosition; - HANDLE ClassesKey; - PHANDLE GuidKeyRealP, DeviceKeyRealP, InstanceKeyRealP; - HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal; + UNICODE_STRING ReferenceString = {0}; + UNICODE_STRING SymbolicLink = {0}; + HANDLE DeviceKeyHandle, InstanceKeyHandle; + ULONG DeviceKeyDisposition, InstanceKeyDisposition; + BOOLEAN ReferenceStringPresent = FALSE; /* Assuming no ref string by default */ NTSTATUS Status; + USHORT i; - SubKeyName.Buffer = NULL; + DeviceKeyHandle = InstanceKeyHandle = NULL; - if (GuidKey != NULL) - GuidKeyRealP = GuidKey; - else - GuidKeyRealP = &GuidKeyReal; + /* Duplicate the symbolic link (we'll modify it later) */ + Status = RtlDuplicateUnicodeString(0, SymbolicLinkName, &SymbolicLink); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlDuplicateUnicodeString() failed, Status 0x%08lx\n", Status); + goto Quit; + } - if (DeviceKey != NULL) - DeviceKeyRealP = DeviceKey; - else - DeviceKeyRealP = &DeviceKeyReal; + /* Separate it into its constituents */ + Status = IopSeparateSymbolicLink(&SymbolicLink, + NULL, + NULL, + NULL, + &ReferenceString, + &ReferenceStringPresent, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to separate symbolic link %wZ, Status 0x%08lx\n", &SymbolicLink, Status); + goto Quit; + } - if (InstanceKey != NULL) - InstanceKeyRealP = InstanceKey; + /* Did we got a ref string? */ + if (ReferenceStringPresent) + { + /* Remove it from our symbolic link */ + SymbolicLink.MaximumLength = SymbolicLink.Length -= ReferenceString.Length; + + /* Replace the 1st backslash `\` character by '#' pound */ + ReferenceString.Buffer[0] = L'#'; + } else - InstanceKeyRealP = &InstanceKeyReal; + { + /* No ref string, initialize it with a single pound character '#' */ + RtlInitUnicodeString(&ReferenceString, L"#"); + } - *GuidKeyRealP = NULL; - *DeviceKeyRealP = NULL; - *InstanceKeyRealP = NULL; + /* Replace all '\' by '#' in symbolic link */ + for (i = 0; i < SymbolicLink.Length / sizeof(WCHAR); i++) + { + if (SymbolicLink.Buffer[i] == L'\\') + SymbolicLink.Buffer[i] = L'#'; + } - RtlInitUnicodeString(&BaseKeyU, BaseKeyString); + /* Fix prefix: '#??#' -> '##?#' */ + SymbolicLink.Buffer[1] = L'#'; + + DPRINT("Munged symbolic link is %wZ\n", &SymbolicLink); + + /* Try to open or create device interface keys */ + if (Create) + { + Status = IopCreateRegistryKeyEx(&DeviceKeyHandle, + ClassHandle, + &SymbolicLink, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS, + REG_OPTION_NON_VOLATILE, + &DeviceKeyDisposition); + } + else + { + Status = IopOpenRegistryKeyEx(&DeviceKeyHandle, + ClassHandle, + &SymbolicLink, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS); + } - /* Open the DeviceClasses key */ - InitializeObjectAttributes(&ObjectAttributes, - &BaseKeyU, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - NULL, - NULL); - Status = ZwOpenKey(&ClassesKey, - DesiredAccess | KEY_ENUMERATE_SUB_KEYS, - &ObjectAttributes); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open %wZ\n", &BaseKeyU); - goto cleanup; + DPRINT1("Failed to create or open %wZ, Status 0x%08lx\n", &SymbolicLink, Status); + goto Quit; } - StartPosition = wcschr(SymbolicLinkName->Buffer, L'{'); - EndPosition = wcschr(SymbolicLinkName->Buffer, L'}'); - if (!StartPosition || !EndPosition || StartPosition > EndPosition) + DPRINT("Munged reference string is %wZ\n", &ReferenceString); + + /* Try to open or create instance subkeys */ + if (Create) { - DPRINT1("Bad symbolic link: %wZ\n", SymbolicLinkName); - return STATUS_INVALID_PARAMETER_1; + Status = IopCreateRegistryKeyEx(&InstanceKeyHandle, + DeviceKeyHandle, + &ReferenceString, + DesiredAccess, + REG_OPTION_NON_VOLATILE, + &InstanceKeyDisposition); + } + else + { + Status = IopOpenRegistryKeyEx(&InstanceKeyHandle, + DeviceKeyHandle, + &ReferenceString, + DesiredAccess); } - GuidString.Buffer = StartPosition; - GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition); - InitializeObjectAttributes(&ObjectAttributes, - &GuidString, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - ClassesKey, - NULL); - Status = ZwCreateKey(GuidKeyRealP, - DesiredAccess | KEY_ENUMERATE_SUB_KEYS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); - ZwClose(ClassesKey); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open %wZ%wZ (%x)\n", &BaseKeyU, &GuidString, Status); - goto cleanup; + DPRINT1("Failed to create or open %wZ, Status 0x%08lx\n", &ReferenceString, Status); + goto Quit; } - SubKeyName.MaximumLength = SymbolicLinkName->Length + sizeof(WCHAR); - SubKeyName.Length = 0; - SubKeyName.Buffer = ExAllocatePool(PagedPool, SubKeyName.MaximumLength); - if (!SubKeyName.Buffer) + Status = STATUS_SUCCESS; + +Quit: + if (NT_SUCCESS(Status)) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; + if (DeviceHandle) + *DeviceHandle = DeviceKeyHandle; + else + ZwClose(DeviceKeyHandle); + + if (DeviceDisposition) + *DeviceDisposition = DeviceKeyDisposition; + + if (InstanceHandle) + *InstanceHandle = InstanceKeyHandle; + else + ZwClose(InstanceKeyHandle); + + if (InstanceDisposition) + *InstanceDisposition = InstanceKeyDisposition; } + else + { + if (InstanceKeyHandle) + ZwClose(InstanceKeyHandle); - RtlAppendUnicodeStringToString(&SubKeyName, - SymbolicLinkName); + if (Create) + ZwDeleteKey(DeviceKeyHandle); - SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL; + if (DeviceKeyHandle) + ZwClose(DeviceKeyHandle); + } - SubKeyName.Buffer[0] = L'#'; - SubKeyName.Buffer[1] = L'#'; - SubKeyName.Buffer[2] = L'?'; - SubKeyName.Buffer[3] = L'#'; + if (SymbolicLink.Buffer) + RtlFreeUnicodeString(&SymbolicLink); - ReferenceString.Buffer = wcsrchr(SubKeyName.Buffer, '\\'); - if (ReferenceString.Buffer != NULL) - { - ReferenceString.Buffer[0] = L'#'; + return Status; +} - SubKeyName.Length = (USHORT)((ULONG_PTR)(ReferenceString.Buffer) - (ULONG_PTR)SubKeyName.Buffer); - ReferenceString.Length = SymbolicLinkName->Length - SubKeyName.Length; +/** + * @brief + * Retrieves a handles to the GUID, device and instance registry keys + * for the specified symbolic link. + **/ +static +NTSTATUS +OpenRegistryHandlesFromSymbolicLink( + _In_ PCUNICODE_STRING SymbolicLinkName, + _In_ ACCESS_MASK DesiredAccess, + _Out_opt_ PHANDLE GuidKey, + _Out_opt_ PHANDLE DeviceKey, + _Out_opt_ PHANDLE InstanceKey) +{ + UNICODE_STRING BaseKeyU; + UNICODE_STRING GuidString; + HANDLE ClassesKey; + HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal; + NTSTATUS Status; + + ClassesKey = GuidKeyReal = DeviceKeyReal = InstanceKeyReal = NULL; + + RtlInitUnicodeString(&BaseKeyU, BaseKeyString); + + /* Separate symbolic link onto the parts */ + Status = IopSeparateSymbolicLink(SymbolicLinkName, + NULL, + NULL, + &GuidString, + NULL, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to parse symbolic link %wZ, Status 0x%08lx\n", + SymbolicLinkName, Status); + goto Quit; } - else + + /* Open the DeviceClasses key */ + Status = IopOpenRegistryKeyEx(&ClassesKey, + NULL, + &BaseKeyU, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS); + if (!NT_SUCCESS(Status)) { - RtlInitUnicodeString(&ReferenceString, L"#"); + DPRINT1("Failed to open %wZ, Status 0x%08lx\n", &BaseKeyU, Status); + goto Quit; } - InitializeObjectAttributes(&ObjectAttributes, - &SubKeyName, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - *GuidKeyRealP, - NULL); - Status = ZwCreateKey(DeviceKeyRealP, - DesiredAccess | KEY_ENUMERATE_SUB_KEYS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); + /* Open the GUID subkey */ + Status = IopOpenRegistryKeyEx(&GuidKeyReal, + ClassesKey, + &GuidString, + DesiredAccess | KEY_ENUMERATE_SUB_KEYS); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open %wZ%wZ\\%wZ Status %x\n", &BaseKeyU, &GuidString, &SubKeyName, Status); - goto cleanup; + DPRINT1("Failed to open %wZ%wZ, Status 0x%08lx\n", &BaseKeyU, &GuidString, Status); + goto Quit; } - InitializeObjectAttributes(&ObjectAttributes, - &ReferenceString, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - *DeviceKeyRealP, - NULL); - Status = ZwCreateKey(InstanceKeyRealP, - DesiredAccess, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); + /* Open the device and instance subkeys */ + Status = IopOpenOrCreateSymbolicLinkSubKeys(&DeviceKeyReal, + NULL, + &InstanceKeyReal, + NULL, + GuidKeyReal, + SymbolicLinkName, + DesiredAccess, + FALSE); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open %wZ%wZ\\%wZ%\\%wZ (%x)\n", &BaseKeyU, &GuidString, &SubKeyName, &ReferenceString, Status); - goto cleanup; + DPRINT1("Failed to open %wZ%wZ, Status 0x%08lx\n", &BaseKeyU, &GuidString, Status); + goto Quit; } Status = STATUS_SUCCESS; -cleanup: - if (SubKeyName.Buffer != NULL) - ExFreePool(SubKeyName.Buffer); - +Quit: if (NT_SUCCESS(Status)) { - if (!GuidKey) - ZwClose(*GuidKeyRealP); + if (GuidKey) + *GuidKey = GuidKeyReal; + else + ZwClose(GuidKeyReal); - if (!DeviceKey) - ZwClose(*DeviceKeyRealP); + if (DeviceKey) + *DeviceKey = DeviceKeyReal; + else + ZwClose(DeviceKeyReal); - if (!InstanceKey) - ZwClose(*InstanceKeyRealP); + if (InstanceKey) + *InstanceKey = InstanceKeyReal; + else + ZwClose(InstanceKeyReal); } else { - if (*GuidKeyRealP != NULL) - ZwClose(*GuidKeyRealP); + if (GuidKeyReal) + ZwClose(GuidKeyReal); - if (*DeviceKeyRealP != NULL) - ZwClose(*DeviceKeyRealP); + if (DeviceKeyReal) + ZwClose(DeviceKeyReal); - if (*InstanceKeyRealP != NULL) - ZwClose(*InstanceKeyRealP); + if (InstanceKeyReal) + ZwClose(InstanceKeyReal); } + if (ClassesKey) + ZwClose(ClassesKey); + return Status; }
4 weeks, 1 day
1
0
0
0
[reactos] 02/03: [NTOS:IO] Implement IoGetDeviceInterfaceAlias Required by XP/2003 audio stack to be loaded properly. CORE-17361
by Oleg Dubinskiy
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d617c8cf329960805eebf…
commit d617c8cf329960805eebff5d37907604e5d96db7 Author: Oleg Dubinskiy <oleg.dubinskij2013(a)yandex.ua> AuthorDate: Sun Apr 4 20:11:14 2021 +0300 Commit: Oleg Dubinskiy <oleg.dubinskij30(a)gmail.com> CommitDate: Sun Feb 2 23:30:38 2025 +0100 [NTOS:IO] Implement IoGetDeviceInterfaceAlias Required by XP/2003 audio stack to be loaded properly. CORE-17361 --- ntoskrnl/io/iomgr/deviface.c | 453 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 420 insertions(+), 33 deletions(-) diff --git a/ntoskrnl/io/iomgr/deviface.c b/ntoskrnl/io/iomgr/deviface.c index ed81e4407c4..a5f20efb50a 100644 --- a/ntoskrnl/io/iomgr/deviface.c +++ b/ntoskrnl/io/iomgr/deviface.c @@ -7,6 +7,7 @@ * PROGRAMMERS: Filip Navara (xnavara(a)volny.cz) * Matthew Brace (ismarc(a)austin.rr.com) * Hervé Poussineau (hpoussin(a)reactos.org) + * Oleg Dubinskiy (oleg.dubinskiy(a)reactos.org) */ /* INCLUDES ******************************************************************/ @@ -26,7 +27,265 @@ C_ASSERT(sizeof(L"{01234567-89ab-cdef-0123-456789abcdef}") == GUID_STRING_BYTES PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance); -static PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\"; +static PCWSTR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\"; + +/** + * @brief + * Creates a new symbolic link from the specified format of the prefix, device string, + * class GUID and reference string (if any). + * + * @param[in] DeviceString + * Device string, placed after prefix and before GUID, for example ACPI#PNP0501#1#. + * + * @param[in] GuidString + * Device interface class GUID represented by a string. Placed in curly brackets {}, + * after device string, should always be 38 characters long. For example, + * {01234567-89ab-cdef-0123-456789abcdef}. + * + * @param[in] ReferenceString + * Optional reference string, if any. Placed after GUID, at the end of symbolic link. + * Usually contains human-readable subdevice name or class GUID. + * + * @param[in] UserModePrefixFormat + * Specifies whether a new symbolic link should have either a kernel mode or user mode prefix. + * TRUE for user mode prefix, FALSE for kernel mode. + * + * @param[out] SymbolicLinkName + * Pointer to unicode string which receives created symbolic link. + * + * @return + * STATUS_SUCCESS in case of success, or an NTSTATUS error code otherwise. + **/ +static +NTSTATUS +IopBuildSymbolicLink( + _In_ PCUNICODE_STRING DeviceString, + _In_ PCUNICODE_STRING GuidString, + _In_opt_ PCUNICODE_STRING ReferenceString, + _In_ BOOLEAN UserModePrefixFormat, + _Out_ PUNICODE_STRING SymbolicLinkName) +{ + static const UNICODE_STRING KernelModePrefix = RTL_CONSTANT_STRING(L"\\??\\"); + static const UNICODE_STRING UserModePrefix = RTL_CONSTANT_STRING(L"\\\\?\\"); + static const UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\"); + UNICODE_STRING MungedDeviceString, SymbolicLink; + NTSTATUS Status; + ULONG Length; + USHORT i; + + /* Use a backslash if reference string is not specified */ + if (!ReferenceString) + ReferenceString = &PathSep; + + /* Duplicate the device string (to "munge" it) */ + Status = RtlDuplicateUnicodeString(0, DeviceString, &MungedDeviceString); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlDuplicateUnicodeString() failed, Status 0x%08lx\n", Status); + return Status; + } + + /* Replace all '\' by '#' in device string */ + for (i = 0; i < MungedDeviceString.Length / sizeof(WCHAR); i++) + { + if (MungedDeviceString.Buffer[i] == L'\\') + MungedDeviceString.Buffer[i] = L'#'; + } + + /* Calculate total length */ + Length = KernelModePrefix.Length // Same as UserModePrefix.Length + + MungedDeviceString.Length + + sizeof(L"#") + GuidString->Length + + ReferenceString->Length; + ASSERT(Length <= MAXUSHORT); + + /* Build up new symbolic link */ + SymbolicLink.Length = 0; + SymbolicLink.MaximumLength = Length; + SymbolicLink.Buffer = ExAllocatePoolWithTag(PagedPool, SymbolicLink.MaximumLength, TAG_IO); + if (!SymbolicLink.Buffer) + { + DPRINT1("ExAllocatePoolWithTag() failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = RtlUnicodeStringPrintf(&SymbolicLink, + L"%wZ%wZ#%wZ%wZ", + UserModePrefixFormat ? + &UserModePrefix : &KernelModePrefix, + &MungedDeviceString, + GuidString, + ReferenceString); + NT_VERIFY(NT_SUCCESS(Status)); + + DPRINT("New symbolic link is %wZ\n", &SymbolicLink); + + *SymbolicLinkName = SymbolicLink; + return STATUS_SUCCESS; +} + +/** + * @brief + * Parses the specified symbolic link onto the 4 parts: prefix, device string, + * class GUID and reference string. + * + * @param[in] SymbolicLinkName + * Pointer to a symbolic link string to parse. + * + * @param[out] PrefixString + * Receives prefix of symbolic link. Can be '\??\' for Kernel mode or '\\?\' for User mode. + * + * @param[out] MungedString + * Receives device string. For example, ##?#ACPI#PNP0501#1#. + * + * @param[out] GuidString + * Receives device interface class GUID string represented by device interface. + * For example, {01234567-89ab-cdef-0123-456789abcdef}. + * + * @param[out] ReferenceString + * Receives reference string, if any. Usually contains a human-readable + * subdevice name or class GUID. + * + * @param[out] ReferenceStringPresent + * Pointer to variable that indicates whether the reference string exists in symbolic link. + * TRUE if it does, FALSE otherwise. + * + * @param[out] InterfaceClassGuid + * Receives the interface class GUID to which specified symbolic link belongs to. + * + * @return + * STATUS_SUCCESS in case of success, or an NTSTATUS error code otherwise. + **/ +static +NTSTATUS +IopSeparateSymbolicLink( + _In_ PCUNICODE_STRING SymbolicLinkName, + _Out_opt_ PUNICODE_STRING PrefixString, + _Out_opt_ PUNICODE_STRING MungedString, + _Out_opt_ PUNICODE_STRING GuidString, + _Out_opt_ PUNICODE_STRING ReferenceString, + _Out_opt_ PBOOLEAN ReferenceStringPresent, + _Out_opt_ LPGUID InterfaceClassGuid) +{ + static const UNICODE_STRING KernelModePrefix = RTL_CONSTANT_STRING(L"\\??\\"); + static const UNICODE_STRING UserModePrefix = RTL_CONSTANT_STRING(L"\\\\?\\"); + UNICODE_STRING MungedStringReal, GuidStringReal, ReferenceStringReal; + UNICODE_STRING LinkNameNoPrefix; + USHORT i, ReferenceStringOffset; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("Symbolic link is %wZ\n", SymbolicLinkName); + + /* The symbolic link name looks like \??\ACPI#PNP0501#1#{GUID}\ReferenceString + * Make sure it starts with the expected prefix. */ + if (!RtlPrefixUnicodeString(&KernelModePrefix, SymbolicLinkName, FALSE) && + !RtlPrefixUnicodeString(&UserModePrefix, SymbolicLinkName, FALSE)) + { + DPRINT1("Invalid link name %wZ\n", SymbolicLinkName); + return STATUS_INVALID_PARAMETER; + } + + /* Sanity checks */ + ASSERT(KernelModePrefix.Length == UserModePrefix.Length); + ASSERT(SymbolicLinkName->Length >= KernelModePrefix.Length); + + /* Make a version without the prefix for further processing */ + LinkNameNoPrefix.Buffer = SymbolicLinkName->Buffer + KernelModePrefix.Length / sizeof(WCHAR); + LinkNameNoPrefix.Length = SymbolicLinkName->Length - KernelModePrefix.Length; + LinkNameNoPrefix.MaximumLength = LinkNameNoPrefix.Length; + + DPRINT("Symbolic link without prefix is %wZ\n", &LinkNameNoPrefix); + + /* Find the reference string, if any */ + for (i = 0; i < LinkNameNoPrefix.Length / sizeof(WCHAR); i++) + { + if (LinkNameNoPrefix.Buffer[i] == L'\\') + break; + } + ReferenceStringOffset = i * sizeof(WCHAR); + + /* The GUID is before the reference string or at the end */ + ASSERT(LinkNameNoPrefix.Length >= ReferenceStringOffset); + if (ReferenceStringOffset < GUID_STRING_BYTES + sizeof(WCHAR)) + { + DPRINT1("Invalid link name %wZ\n", SymbolicLinkName); + return STATUS_INVALID_PARAMETER; + } + + /* Get reference string (starts with \ after {GUID}) from link without prefix */ + ReferenceStringReal.Buffer = LinkNameNoPrefix.Buffer + ReferenceStringOffset / sizeof(WCHAR); + ReferenceStringReal.Length = LinkNameNoPrefix.Length - ReferenceStringOffset; + ReferenceStringReal.MaximumLength = ReferenceStringReal.Length; + + DPRINT("Reference string is %wZ\n", &ReferenceStringReal); + + /* Get GUID string (device class GUID in {} brackets) */ + GuidStringReal.Buffer = LinkNameNoPrefix.Buffer + (ReferenceStringOffset - GUID_STRING_BYTES) / sizeof(WCHAR); + GuidStringReal.Length = GUID_STRING_BYTES; + GuidStringReal.MaximumLength = GuidStringReal.Length; + + DPRINT("GUID string is %wZ\n", &GuidStringReal); + + /* Validate GUID string for: + * 1) {} brackets at the start and the end; + * 2) - separators in the appropriate places. */ + ASSERT(GuidStringReal.Buffer[0] == L'{'); + ASSERT(GuidStringReal.Buffer[GUID_STRING_CHARS - 1] == L'}'); + ASSERT(GuidStringReal.Buffer[9] == L'-'); + ASSERT(GuidStringReal.Buffer[14] == L'-'); + ASSERT(GuidStringReal.Buffer[19] == L'-'); + ASSERT(GuidStringReal.Buffer[24] == L'-'); + + if (MungedString) + { + /* Create a munged path string (looks like ACPI#PNP0501#1#) */ + MungedStringReal.Buffer = LinkNameNoPrefix.Buffer; + MungedStringReal.Length = LinkNameNoPrefix.Length - ReferenceStringReal.Length - GUID_STRING_BYTES - sizeof(WCHAR); + MungedStringReal.MaximumLength = MungedStringReal.Length; + + DPRINT("Munged string is %wZ\n", &MungedStringReal); + } + + /* Store received parts if the parameters are not null */ + if (PrefixString) + { + PrefixString->Buffer = SymbolicLinkName->Buffer; + PrefixString->Length = KernelModePrefix.Length; // Same as UserModePrefix.Length + PrefixString->MaximumLength = PrefixString->Length; + + DPRINT("Prefix string is %wZ\n", PrefixString); + } + + if (MungedString) + *MungedString = MungedStringReal; + + if (GuidString) + *GuidString = GuidStringReal; + + if (ReferenceString) + { + if (ReferenceStringReal.Length > sizeof(WCHAR)) + *ReferenceString = ReferenceStringReal; + else + RtlInitEmptyUnicodeString(ReferenceString, NULL, 0); + } + + if (ReferenceStringPresent) + *ReferenceStringPresent = ReferenceStringReal.Length > sizeof(WCHAR); + + if (InterfaceClassGuid) + { + /* Convert GUID string into a GUID and store it also */ + Status = RtlGUIDFromString(&GuidStringReal, InterfaceClassGuid); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlGUIDFromString() failed, Status 0x%08lx\n", Status); + } + } + + /* We're done */ + return Status; +} static NTSTATUS @@ -275,38 +534,6 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, return Status; } -/*++ - * @name IoGetDeviceInterfaceAlias - * @unimplemented - * - * Returns the alias device interface of the specified device interface - * instance, if the alias exists. - * Documented in WDK. - * - * @param SymbolicLinkName - * Pointer to a string which identifies the device interface instance - * - * @param AliasInterfaceClassGuid - * See WDK - * - * @param AliasSymbolicLinkName - * See WDK - * - * @return Three different NTSTATUS values in case of errors, and STATUS_SUCCESS - * otherwise (see WDK for details) - * - * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a system thread - * - *--*/ -NTSTATUS -NTAPI -IoGetDeviceInterfaceAlias(IN PUNICODE_STRING SymbolicLinkName, - IN CONST GUID *AliasInterfaceClassGuid, - OUT PUNICODE_STRING AliasSymbolicLinkName) -{ - return STATUS_NOT_IMPLEMENTED; -} - /*++ * @name IopOpenInterfaceKey * @@ -412,6 +639,166 @@ cleanup: return Status; } +/** + * @brief + * Returns the alias device interface of the specified device interface + * instance, if the alias exists. + * + * @param[in] SymbolicLinkName + * Pointer to a symbolic link string which identifies the device interface instance. + * + * @param[in] AliasInterfaceClassGuid + * Pointer to a device interface class GUID. + * + * @param[out] AliasSymbolicLinkName + * Pointer to unicode string which receives the alias symbolic link upon success. + * Must be freed with RtlFreeUnicodeString after using. + * + * @return NTSTATUS values in case of errors, STATUS_SUCCESS otherwise. + * + * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a system thread + **/ +NTSTATUS +NTAPI +IoGetDeviceInterfaceAlias( + _In_ PUNICODE_STRING SymbolicLinkName, + _In_ CONST GUID *AliasInterfaceClassGuid, + _Out_ PUNICODE_STRING AliasSymbolicLinkName) +{ + static const UNICODE_STRING UserModePrefix = RTL_CONSTANT_STRING(L"\\\\?\\"); + UNICODE_STRING AliasSymbolicLink = {0}; + UNICODE_STRING AliasGuidString = {0}; + UNICODE_STRING DeviceString = {0}; + UNICODE_STRING ReferenceString = {0}; + PKEY_VALUE_FULL_INFORMATION kvInfo; + HANDLE DeviceKey, AliasInstanceKey; + BOOLEAN UserModePrefixFormat; + BOOLEAN ReferenceStringPresent = FALSE; /* Assuming no ref string by default */ + PVOID Buffer; + NTSTATUS Status; + + DPRINT("IoGetDeviceInterfaceAlias(%wZ, 0x%p)\n", SymbolicLinkName, AliasInterfaceClassGuid); + + /* Sanity check */ + if (!SymbolicLinkName || !AliasInterfaceClassGuid) + { + DPRINT1("IoGetDeviceInterfaceAlias() invalid symbolic link or alias class GUID\n"); + return STATUS_INVALID_PARAMETER; + } + + /* Convert alias GUID to a string */ + Status = RtlStringFromGUID(AliasInterfaceClassGuid, &AliasGuidString); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlStringFromGUID() failed, Status 0x%08lx\n", Status); + goto Quit; + } + + DPRINT("Alias GUID is %wZ\n", &AliasGuidString); + + /* Get the device instance string of existing symbolic link */ + Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName, + KEY_QUERY_VALUE, + NULL, + &DeviceKey, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open device instance key for %wZ, Status 0x%08lx\n", SymbolicLinkName, Status); + goto Quit; + } + + Status = IopGetRegistryValue(DeviceKey, L"DeviceInstance", &kvInfo); + ZwClose(DeviceKey); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed get device instance value, Status 0x%08lx\n", Status); + goto Quit; + } + + if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0 || kvInfo->DataLength > MAXUSHORT) + { + DPRINT1("Wrong or empty instance value\n"); + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + + /* Convert received data to unicode string */ + Buffer = (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset); + PnpRegSzToString(Buffer, kvInfo->DataLength, &DeviceString.Length); + DeviceString.MaximumLength = DeviceString.Length; + DeviceString.Buffer = Buffer; + + /* + * Separate symbolic link into 4 parts: + * 1) prefix string (\??\ for kernel mode or \\?\ for user mode), + * 2) munged path string (like ##?#ACPI#PNP0501#1#{GUID}), + * 3) GUID string (the current GUID), + * 4) reference string (goes after GUID, starts with '\'). + * + * We need only reference string. + */ + Status = IopSeparateSymbolicLink(SymbolicLinkName, + NULL, + NULL, + NULL, + &ReferenceString, + &ReferenceStringPresent, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to separate symbolic link %wZ, Status 0x%08lx\n", SymbolicLinkName, Status); + goto Quit; + } + + DPRINT("Device string is '%wZ'\n", &DeviceString); + + /* Does symbolic link have kernel mode "\??\" or user mode "\\?\" prefix format? */ + UserModePrefixFormat = RtlPrefixUnicodeString(&UserModePrefix, SymbolicLinkName, FALSE); + + /* Build up new symbolic link with alias GUID */ + Status = IopBuildSymbolicLink(&DeviceString, + &AliasGuidString, + ReferenceStringPresent ? &ReferenceString : NULL, + UserModePrefixFormat, + &AliasSymbolicLink); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to build alias symbolic link, Status 0x%08lx\n", Status); + goto Quit; + } + + /* Make sure that alias symbolic link key exists in registry */ + Status = OpenRegistryHandlesFromSymbolicLink(&AliasSymbolicLink, + KEY_READ, + NULL, + NULL, + &AliasInstanceKey); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open alias symbolic link key, Status 0x%08lx\n", Status); + goto Quit; + } + ZwClose(AliasInstanceKey); + + /* We're done */ + DPRINT("IoGetDeviceInterfaceAlias(): alias symbolic link %wZ\n", &AliasSymbolicLink); + *AliasSymbolicLinkName = AliasSymbolicLink; + Status = STATUS_SUCCESS; + +Quit: + if (!NT_SUCCESS(Status)) + { + if (AliasSymbolicLink.Buffer) + RtlFreeUnicodeString(&AliasSymbolicLink); + } + + if (AliasGuidString.Buffer) + RtlFreeUnicodeString(&AliasGuidString); + + return Status; +} + /*++ * @name IoGetDeviceInterfaces * @implemented
4 weeks, 1 day
1
0
0
0
[reactos] 01/03: [KMTESTS:IO] Rewrite IoDeviceInterface kmtest Add new kernel-mode test for Device Interface functions, based on the patch by Mark Jansen. The previous one was buggy and crashed even on Windows. The new one doesn't fail, and works without bugs. Although there is missing one test case (for IoRegisterDeviceInterface). Also perhaps IoRegister/UnregisterPlugPlayNotification testcases should be keept, if they correspond to Device Interface functions. CORE-17361
by Oleg Dubinskiy
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6b2f00e70a08912601edb…
commit 6b2f00e70a08912601edbb3264e71bee5f49b8cf Author: Oleg Dubinskiy <oleg.dubinskij2013(a)yandex.ua> AuthorDate: Thu Apr 8 21:03:02 2021 +0300 Commit: Oleg Dubinskiy <oleg.dubinskij30(a)gmail.com> CommitDate: Sun Feb 2 23:30:38 2025 +0100 [KMTESTS:IO] Rewrite IoDeviceInterface kmtest Add new kernel-mode test for Device Interface functions, based on the patch by Mark Jansen. The previous one was buggy and crashed even on Windows. The new one doesn't fail, and works without bugs. Although there is missing one test case (for IoRegisterDeviceInterface). Also perhaps IoRegister/UnregisterPlugPlayNotification testcases should be keept, if they correspond to Device Interface functions. CORE-17361 --- .../rostests/kmtests/ntos_io/IoDeviceInterface.c | 374 ++++++++++----------- 1 file changed, 172 insertions(+), 202 deletions(-) diff --git a/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c b/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c index 58f15cb6c75..846c43901c6 100644 --- a/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c +++ b/modules/rostests/kmtests/ntos_io/IoDeviceInterface.c @@ -1,11 +1,14 @@ /* - * PROJECT: ReactOS kernel-mode tests - * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory - * PURPOSE: Kernel-Mode Test Suite Device Interface functions test - * PROGRAMMER: Filip Navara <xnavara(a)volny.cz> + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Test for Device Interface functions + * COPYRIGHT: Copyright 2011 Filip Navara <xnavara(a)volny.cz> + * Copyright 2011-2015 Thomas Faber <thomas.faber(a)reactos.org> + * Copyright 2021 Mark Jansen <mark.jansen(a)reactos.org> + * Copyright 2021-2024 Oleg Dubinskiy <oleg.dubinskiy(a)reactos.org> */ -/* TODO: what's with the prototypes at the top, what's with the if-ed out part? Doesn't process most results */ +/* TODO: Add IoRegisterDeviceInterface testcase */ #include <kmt_test.h> #include <poclass.h> @@ -13,113 +16,176 @@ #define NDEBUG #include <debug.h> -#if 0 -NTSTATUS -(NTAPI *IoGetDeviceInterfaces_Func)( - IN CONST GUID *InterfaceClassGuid, - IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, - IN ULONG Flags, - OUT PWSTR *SymbolicLinkList); - -NTSTATUS NTAPI -ReactOS_IoGetDeviceInterfaces( - IN CONST GUID *InterfaceClassGuid, - IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, - IN ULONG Flags, - OUT PWSTR *SymbolicLinkList); -#endif /* 0 */ - -static VOID DeviceInterfaceTest_Func() +/* Predefined GUIDs are required for IoGetDeviceInterfaceAlias and IoOpenDeviceInterfaceRegistryKey. + * Only they can provide the aliases and the needed subkeys, unlike manually declared test GUIDs. + * Since IoRegisterDeviceInterface testcase is missing, it is not possible to register the new device interface + * and get an alias/key handle of it using this test. */ +/* Invalid GUID */ +static const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +/* From our ks.h */ +static const GUID KSCATEGORY_BRIDGE = {0x085AFF00L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_CAPTURE = {0x65E8773DL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_COMMUNICATIONSTRANSFORM = {0xCF1DDA2CL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_DATACOMPRESSOR = {0x1E84C900L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_DATADECOMPRESSOR = {0x2721AE20L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_DATATRANSFORM = {0x2EB07EA0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_FILESYSTEM = {0x760FED5EL, 0x9357, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_INTERFACETRANSFORM = {0xCF1DDA2DL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_MEDIUMTRANSFORM = {0xCF1DDA2EL, 0x9743, 0x11D0, {0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_MIXER = {0xAD809C00L, 0x7B88, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +static const GUID KSCATEGORY_RENDER = {0x65E8773EL, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +static const GUID KSCATEGORY_SPLITTER = {0x0A4252A0L, 0x7E70, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; + +static const GUID* Types[] = { - NTSTATUS Status; - PWSTR SymbolicLinkList; - PWSTR SymbolicLinkListPtr; - GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}}; - - Status = IoGetDeviceInterfaces( - &Guid, - NULL, - 0, - &SymbolicLinkList); - - ok(NT_SUCCESS(Status), - "IoGetDeviceInterfaces failed with status 0x%X\n", - (unsigned int)Status); - if (!NT_SUCCESS(Status)) - { - return; - } - - DPRINT("IoGetDeviceInterfaces results:\n"); - for (SymbolicLinkListPtr = SymbolicLinkList; - SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0; - SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1) - { - DPRINT1("Symbolic Link: %S\n", SymbolicLinkListPtr); - } - -#if 0 - DPRINT("[PnP Test] Trying to get aliases\n"); - - for (SymbolicLinkListPtr = SymbolicLinkList; - SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0; - SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1) - { - UNICODE_STRING SymbolicLink; - UNICODE_STRING AliasSymbolicLink; - - SymbolicLink.Buffer = SymbolicLinkListPtr; - SymbolicLink.Length = SymbolicLink.MaximumLength = wcslen(SymbolicLinkListPtr); - RtlInitUnicodeString(&AliasSymbolicLink, NULL); - IoGetDeviceInterfaceAlias( - &SymbolicLink, - &AliasGuid, - &AliasSymbolicLink); - if (AliasSymbolicLink.Buffer != NULL) - { - DPRINT("[PnP Test] Original: %S\n", SymbolicLinkListPtr); - DPRINT("[PnP Test] Alias: %S\n", AliasSymbolicLink.Buffer); - } - } -#endif - - ExFreePool(SymbolicLinkList); + &GUID_NULL, + &KSCATEGORY_BRIDGE, + &KSCATEGORY_CAPTURE, + &KSCATEGORY_COMMUNICATIONSTRANSFORM, + &KSCATEGORY_DATACOMPRESSOR, + &KSCATEGORY_DATADECOMPRESSOR, + &KSCATEGORY_DATATRANSFORM, + &KSCATEGORY_FILESYSTEM, + &KSCATEGORY_INTERFACETRANSFORM, + &KSCATEGORY_MEDIUMTRANSFORM, + &KSCATEGORY_MIXER, + &KSCATEGORY_RENDER, + &KSCATEGORY_SPLITTER, +}; + +static +VOID +Test_IoOpenDeviceInterfaceRegistryKey( + _In_opt_ PCWSTR SymbolicLink) +{ + UNICODE_STRING KeyName, SymbolicLinkName; + HANDLE DeviceInterfaceKey; + NTSTATUS Status; + size_t n; + + RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink); + RtlInitUnicodeString(&KeyName, L"ReactOS_kmtest"); + + /* It's okay to call this from a user process's thread */ + Status = IoOpenDeviceInterfaceRegistryKey(&SymbolicLinkName, KEY_CREATE_SUB_KEY, &DeviceInterfaceKey); + + if (skip(NT_SUCCESS(Status), "IoOpenDeviceInterfaceRegistryKey() failed: 0x%lx\n", Status)) + return; + + trace("IoOpenDeviceInterfaceRegistryKey() success: 0x%p\n", DeviceInterfaceKey); + + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) + { + HANDLE DeviceInterfaceSubKey; + OBJECT_ATTRIBUTES ObjectAttributes; + + /* Try to create the non-volatile subkey to check whether the parent key is volatile */ + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + DeviceInterfaceKey, + NULL); + Status = ZwCreateKey(&DeviceInterfaceSubKey, + KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + + if (skip(NT_SUCCESS(Status), "ZwCreateKey() failed to create a subkey: %d 0x%lx\n", n, Status)) + continue; + + trace("ZwCreateKey(): successfully created subkey: %d 0x%p\n", n, DeviceInterfaceSubKey); + + ZwDeleteKey(DeviceInterfaceSubKey); + ZwClose(DeviceInterfaceSubKey); + } + + ZwClose(DeviceInterfaceKey); } static VOID -Test_IoRegisterDeviceInterface(VOID) +Test_IoGetDeviceInterfaceAlias( + _In_opt_ PCWSTR SymbolicLink) { - GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}}; - DEVICE_OBJECT DeviceObject; - EXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension; - DEVICE_NODE DeviceNode; UNICODE_STRING SymbolicLinkName; - NTSTATUS Status; + size_t n; + + RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink); + + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) + { + UNICODE_STRING AliasSymbolicLinkName; + NTSTATUS Status = IoGetDeviceInterfaceAlias(&SymbolicLinkName, Types[n], &AliasSymbolicLinkName); - RtlInitUnicodeString(&SymbolicLinkName, L""); + if (skip(NT_SUCCESS(Status), "IoGetDeviceInterfaceAlias(): fail: %d 0x%x\n", n, Status)) + continue; - // Prepare our surrogate of a Device Object - DeviceObject.DeviceObjectExtension = (PDEVOBJ_EXTENSION)&DeviceObjectExtension; + trace("IoGetDeviceInterfaceAlias(): success: %d %wZ\n", n, &AliasSymbolicLinkName); + + /* Test IoOpenDeviceInterfaceRegistryKey with alias symbolic link too */ + Test_IoOpenDeviceInterfaceRegistryKey(AliasSymbolicLinkName.Buffer); + + RtlFreeUnicodeString(&AliasSymbolicLinkName); + } +} - // 1. DeviceNode = NULL - DeviceObjectExtension.DeviceNode = NULL; - Status = IoRegisterDeviceInterface(&DeviceObject, &Guid, NULL, - &SymbolicLinkName); +static +VOID +Test_IoSetDeviceInterfaceState( + _In_opt_ PCWSTR SymbolicLink) +{ + UNICODE_STRING SymbolicLinkName; + size_t n; - ok(Status == STATUS_INVALID_DEVICE_REQUEST, - "IoRegisterDeviceInterface returned 0x%08lX\n", Status); + RtlInitUnicodeString(&SymbolicLinkName, SymbolicLink); - // 2. DeviceNode->InstancePath is of a null length - DeviceObjectExtension.DeviceNode = &DeviceNode; - DeviceNode.InstancePath.Length = 0; - Status = IoRegisterDeviceInterface(&DeviceObject, &Guid, NULL, - &SymbolicLinkName); + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) + { + NTSTATUS Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - ok(Status == STATUS_INVALID_DEVICE_REQUEST, - "IoRegisterDeviceInterface returned 0x%08lX\n", Status); + if (skip(NT_SUCCESS(Status), "IoSetDeviceInterfaceState(): failed to enable interface: %d 0x%x\n", n, Status)) + continue; - DeviceInterfaceTest_Func(); + trace("IoSetDeviceInterfaceState(): successfully enabled interface: %d %wZ\n", n, &SymbolicLinkName); + } +} + +static +VOID +Test_IoGetDeviceInterfaces( + _In_ const GUID* Guid) +{ + NTSTATUS Status; + PZZWSTR SymbolicLinkList; + PWSTR SymbolicLink; + UNICODE_STRING GuidString; + + Status = IoGetDeviceInterfaces(Guid, NULL, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &SymbolicLinkList); + + RtlStringFromGUID(Guid, &GuidString); + if (skip(NT_SUCCESS(Status), "IoGetDeviceInterfaces failed with status 0x%x for '%wZ'\n", Status, &GuidString)) + { + RtlFreeUnicodeString(&GuidString); + return; + } + + trace("IoGetDeviceInterfaces '%wZ' results:\n", &GuidString); + RtlFreeUnicodeString(&GuidString); + + for (SymbolicLink = SymbolicLinkList; + SymbolicLink[0] != UNICODE_NULL; + SymbolicLink += wcslen(SymbolicLink) + 1) + { + trace("Symbolic Link: %S\n", SymbolicLink); + Test_IoGetDeviceInterfaceAlias(SymbolicLink); + Test_IoOpenDeviceInterfaceRegistryKey(SymbolicLink); + Test_IoSetDeviceInterfaceState(SymbolicLink); + } + + ExFreePool(SymbolicLinkList); } static UCHAR NotificationContext; @@ -181,112 +247,16 @@ Test_IoRegisterPlugPlayNotification(VOID) } } -static -VOID -Test_IoSetDeviceInterface(VOID) +START_TEST(IoDeviceInterface) { - NTSTATUS Status; - UNICODE_STRING SymbolicLinkName; - PWCHAR Buffer; - ULONG BufferSize; - - /* Invalid prefix or GUID */ - KmtStartSeh() - Status = IoSetDeviceInterfaceState(NULL, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitEmptyUnicodeString(&SymbolicLinkName, NULL, 0); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\\\"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - - /* Valid prefix & GUID, invalid device node */ - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\\\?\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}\\"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - - /* Must not read past the buffer */ - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - BufferSize = SymbolicLinkName.Length; - Buffer = KmtAllocateGuarded(BufferSize); - if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize)) + size_t n; + for (n = 0; n < RTL_NUMBER_OF(Types); ++n) { - RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); - SymbolicLinkName.Buffer = Buffer; - SymbolicLinkName.MaximumLength = BufferSize; - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND); - KmtFreeGuarded(Buffer); + Test_IoGetDeviceInterfaces(Types[n]); } - - RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#aaaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}"); - BufferSize = SymbolicLinkName.Length; - Buffer = KmtAllocateGuarded(BufferSize); - if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize)) - { - RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize); - SymbolicLinkName.Buffer = Buffer; - SymbolicLinkName.MaximumLength = BufferSize; - KmtStartSeh() - Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - KmtEndSeh(STATUS_SUCCESS) - ok_eq_hex(Status, STATUS_INVALID_PARAMETER); - KmtFreeGuarded(Buffer); - } -} - -START_TEST(IoDeviceInterface) -{ - // FIXME: This test crashes in Windows - (void)Test_IoRegisterDeviceInterface; + /* Test the invalid case behaviour */ + Test_IoGetDeviceInterfaceAlias(NULL); + Test_IoOpenDeviceInterfaceRegistryKey(NULL); + Test_IoSetDeviceInterfaceState(NULL); Test_IoRegisterPlugPlayNotification(); - Test_IoSetDeviceInterface(); }
4 weeks, 1 day
1
0
0
0
[reactos] 03/03: [NTOS:KE/x86] Detect more KeFeatureBits
by Timo Kreuzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9b002025d45e36cccaa57…
commit 9b002025d45e36cccaa579e930c7aa8267c77c4d Author: Timo Kreuzer <timo.kreuzer(a)reactos.org> AuthorDate: Wed Jan 22 12:58:47 2025 +0200 Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org> CommitDate: Sat Feb 1 19:45:21 2025 +0200 [NTOS:KE/x86] Detect more KeFeatureBits --- ntoskrnl/include/internal/i386/ke.h | 8 ++++++++ ntoskrnl/ke/i386/cpu.c | 8 ++++++++ ntoskrnl/ke/i386/kiinit.c | 11 +++++++++++ 3 files changed, 27 insertions(+) diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index 596c58b418f..3d4675b30d8 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -22,6 +22,14 @@ extern "C" #define KD_BREAKPOINT_SIZE sizeof(UCHAR) #define KD_BREAKPOINT_VALUE 0xCC +/* CPUID 1 - ECX flags */ +#define X86_FEATURE_SSE3 0x00000001 +#define X86_FEATURE_SSSE3 0x00000200 +#define X86_FEATURE_SSE4_1 0x00080000 +#define X86_FEATURE_SSE4_2 0x00100000 +#define X86_FEATURE_XSAVE 0x04000000 +#define X86_FEATURE_RDRAND 0x40000000 + /* CPUID 1 - EDX flags */ #define X86_FEATURE_FPU 0x00000001 /* x87 FPU is present */ #define X86_FEATURE_VME 0x00000002 /* Virtual 8086 Extensions are present */ diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c index ab639340443..a5d4912db43 100644 --- a/ntoskrnl/ke/i386/cpu.c +++ b/ntoskrnl/ke/i386/cpu.c @@ -361,6 +361,14 @@ KiGetFeatureBits(VOID) break; } + /* Get some features from ECX */ + if (CpuInfo.Ecx & X86_FEATURE_SSE3) FeatureBits |= KF_SSE3; + if (CpuInfo.Ecx & X86_FEATURE_SSSE3) FeatureBits |= KF_SSSE3; + if (CpuInfo.Ecx & X86_FEATURE_SSE4_1) FeatureBits |= KF_SSE4_1; + if (CpuInfo.Ecx & X86_FEATURE_SSE4_2) FeatureBits |= KF_SSE4_2; + if (CpuInfo.Ecx & X86_FEATURE_XSAVE) FeatureBits |= KF_XSTATE; + if (CpuInfo.Ecx & X86_FEATURE_RDRAND) FeatureBits |= KF_RDRAND; + /* Set the current features */ CpuFeatures = CpuInfo.Edx; diff --git a/ntoskrnl/ke/i386/kiinit.c b/ntoskrnl/ke/i386/kiinit.c index 4d576e86f8a..671adad67c3 100644 --- a/ntoskrnl/ke/i386/kiinit.c +++ b/ntoskrnl/ke/i386/kiinit.c @@ -572,6 +572,17 @@ KiInitializeKernel(IN PKPROCESS InitProcess, (KeFeatureBits & KF_3DNOW) ? TRUE: FALSE; SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = (KeFeatureBits & KF_RDTSC) ? TRUE: FALSE; + SharedUserData->ProcessorFeatures[PF_RDRAND_INSTRUCTION_AVAILABLE] = + (KeFeatureBits & KF_RDRAND) ? TRUE : FALSE; + // Note: On x86 we lack support for saving/restoring SSE state + SharedUserData->ProcessorFeatures[PF_SSE3_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSE3) ? TRUE : FALSE; + SharedUserData->ProcessorFeatures[PF_SSSE3_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSSE3) ? TRUE : FALSE; + SharedUserData->ProcessorFeatures[PF_SSE4_1_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSE4_1) ? TRUE : FALSE; + SharedUserData->ProcessorFeatures[PF_SSE4_2_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_SSE4_2) ? TRUE : FALSE; /* Set up the thread-related fields in the PRCB */ Prcb->CurrentThread = InitThread;
1 month
1
0
0
0
[reactos] 02/03: [NTOS:KE/x64] Add detection of SSE 4.2
by Timo Kreuzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d09eb6f856c81c298b99e…
commit d09eb6f856c81c298b99eccf7721f0653d564823 Author: Timo Kreuzer <timo.kreuzer(a)reactos.org> AuthorDate: Mon Jun 3 10:16:07 2024 +0300 Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org> CommitDate: Sat Feb 1 19:45:21 2025 +0200 [NTOS:KE/x64] Add detection of SSE 4.2 --- ntoskrnl/ke/amd64/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ntoskrnl/ke/amd64/cpu.c b/ntoskrnl/ke/amd64/cpu.c index 90519e56181..4fe811aaa42 100644 --- a/ntoskrnl/ke/amd64/cpu.c +++ b/ntoskrnl/ke/amd64/cpu.c @@ -206,6 +206,7 @@ KiGetFeatureBits(VOID) if (VersionInfo.Ecx.Bits.SSSE3) FeatureBits |= KF_SSSE3; if (VersionInfo.Ecx.Bits.CMPXCHG16B) FeatureBits |= KF_CMPXCHG16B; if (VersionInfo.Ecx.Bits.SSE4_1) FeatureBits |= KF_SSE4_1; + if (VersionInfo.Ecx.Bits.SSE4_2) FeatureBits |= KF_SSE4_2; if (VersionInfo.Ecx.Bits.XSAVE) FeatureBits |= KF_XSTATE; if (VersionInfo.Ecx.Bits.RDRAND) FeatureBits |= KF_RDRAND;
1 month
1
0
0
0
[reactos] 01/03: [NTOS] Make KeFeatureBits 64 bit
by Timo Kreuzer
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=be3dde7698ec3b9bbad02…
commit be3dde7698ec3b9bbad020f970dd5ae39d6c2c79 Author: Timo Kreuzer <timo.kreuzer(a)reactos.org> AuthorDate: Sun Sep 29 21:55:20 2024 +0300 Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org> CommitDate: Sat Feb 1 19:45:21 2025 +0200 [NTOS] Make KeFeatureBits 64 bit --- ntoskrnl/ex/sysinfo.c | 8 +++++++- ntoskrnl/include/internal/i386/ke.h | 2 +- ntoskrnl/include/internal/ke.h | 2 +- ntoskrnl/ke/amd64/krnlinit.c | 2 +- ntoskrnl/ke/i386/cpu.c | 4 ++-- ntoskrnl/ke/i386/kiinit.c | 7 ++++--- ntoskrnl/ke/krnlinit.c | 2 +- sdk/include/ndk/amd64/ketypes.h | 3 +++ sdk/include/ndk/extypes.h | 4 ++++ sdk/include/ndk/i386/ketypes.h | 6 ++++++ 10 files changed, 30 insertions(+), 10 deletions(-) diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c index 75e3dd452fd..6c6547bf3b8 100644 --- a/ntoskrnl/ex/sysinfo.c +++ b/ntoskrnl/ex/sysinfo.c @@ -664,7 +664,13 @@ QSI_DEF(SystemProcessorInformation) #else Spi->MaximumProcessors = 0; #endif - Spi->ProcessorFeatureBits = KeFeatureBits; + + /* According to Geoff Chappell, on Win 8.1 x64 / Win 10 x86, where this + field is extended to 64 bits, it continues to produce only the low 32 + bits. For the full value, use SYSTEM_PROCESSOR_FEATURES_INFORMATION. + See
https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/pr…
+ */ + Spi->ProcessorFeatureBits = (ULONG)KeFeatureBits; DPRINT("Arch %u Level %u Rev 0x%x\n", Spi->ProcessorArchitecture, Spi->ProcessorLevel, Spi->ProcessorRevision); diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index 81194e91e0e..596c58b418f 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -462,7 +462,7 @@ NTAPI KiSetProcessorType(VOID); CODE_SEG("INIT") -ULONG +ULONG64 NTAPI KiGetFeatureBits(VOID); diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h index c5fcd5b8af3..5af00103476 100644 --- a/ntoskrnl/include/internal/ke.h +++ b/ntoskrnl/include/internal/ke.h @@ -103,7 +103,7 @@ extern BOOLEAN ExCmosClockIsSane; extern USHORT KeProcessorArchitecture; extern USHORT KeProcessorLevel; extern USHORT KeProcessorRevision; -extern ULONG KeFeatureBits; +extern ULONG64 KeFeatureBits; extern KNODE KiNode0; extern PKNODE KeNodeBlock[1]; extern UCHAR KeNumberNodes; diff --git a/ntoskrnl/ke/amd64/krnlinit.c b/ntoskrnl/ke/amd64/krnlinit.c index d7aea4db738..f580cacbba9 100644 --- a/ntoskrnl/ke/amd64/krnlinit.c +++ b/ntoskrnl/ke/amd64/krnlinit.c @@ -233,7 +233,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, ULONG i; /* Set boot-level flags */ - KeFeatureBits = Prcb->FeatureBits; + KeFeatureBits = Prcb->FeatureBits | (ULONG64)Prcb->FeatureBitsHigh << 32; /* Initialize 8/16 bit SList support */ RtlpUse16ByteSLists = (KeFeatureBits & KF_CMPXCHG16B) ? TRUE : FALSE; diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c index 598a21d9de1..ab639340443 100644 --- a/ntoskrnl/ke/i386/cpu.c +++ b/ntoskrnl/ke/i386/cpu.c @@ -209,13 +209,13 @@ KiSetProcessorType(VOID) } CODE_SEG("INIT") -ULONG +ULONG64 NTAPI KiGetFeatureBits(VOID) { PKPRCB Prcb = KeGetCurrentPrcb(); ULONG Vendor; - ULONG FeatureBits = KF_WORKING_PTE; + ULONG64 FeatureBits = KF_WORKING_PTE; CPU_INFO CpuInfo, DummyCpuInfo; UCHAR Ccr1; BOOLEAN ExtendedCPUID = TRUE; diff --git a/ntoskrnl/ke/i386/kiinit.c b/ntoskrnl/ke/i386/kiinit.c index e3ec9ed94bf..4d576e86f8a 100644 --- a/ntoskrnl/ke/i386/kiinit.c +++ b/ntoskrnl/ke/i386/kiinit.c @@ -384,7 +384,7 @@ KiVerifyCpuFeatures(PKPRCB Prcb) KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x386, 0, 0, 0); // 3. Finally, obtain CPU features. - ULONG FeatureBits = KiGetFeatureBits(); + ULONG64 FeatureBits = KiGetFeatureBits(); // 4. Verify it supports everything we need. if (!(FeatureBits & KF_RDTSC)) @@ -423,7 +423,8 @@ KiVerifyCpuFeatures(PKPRCB Prcb) } // 5. Save feature bits. - Prcb->FeatureBits = FeatureBits; + Prcb->FeatureBits = (ULONG)FeatureBits; + Prcb->FeatureBitsHigh = FeatureBits >> 32; } CODE_SEG("INIT") @@ -445,7 +446,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Set boot-level flags */ if (Number == 0) - KeFeatureBits = Prcb->FeatureBits; + KeFeatureBits = Prcb->FeatureBits | (ULONG64)Prcb->FeatureBitsHigh << 32; /* Set the default NX policy (opt-in) */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN; diff --git a/ntoskrnl/ke/krnlinit.c b/ntoskrnl/ke/krnlinit.c index 4ffdb0bd104..edb455abfc5 100644 --- a/ntoskrnl/ke/krnlinit.c +++ b/ntoskrnl/ke/krnlinit.c @@ -19,7 +19,7 @@ USHORT KeProcessorArchitecture; USHORT KeProcessorLevel; USHORT KeProcessorRevision; -ULONG KeFeatureBits; +ULONG64 KeFeatureBits; /* System call count */ ULONG KiServiceLimit = NUMBER_OF_SYSCALLS; diff --git a/sdk/include/ndk/amd64/ketypes.h b/sdk/include/ndk/amd64/ketypes.h index 08c94196db3..5d65d4a3508 100644 --- a/sdk/include/ndk/amd64/ketypes.h +++ b/sdk/include/ndk/amd64/ketypes.h @@ -939,8 +939,11 @@ typedef struct _KPRCB ULONG CacheCount; #endif #ifdef __REACTOS__ +#if (NTDDI_VERSION < NTDDI_WINBLUE) + // On Win 8.1+ the FeatureBits field is extended to 64 bits ULONG FeatureBitsHigh; #endif +#endif } KPRCB, *PKPRCB; // diff --git a/sdk/include/ndk/extypes.h b/sdk/include/ndk/extypes.h index 2b190f1ca30..251a7a0e6f2 100644 --- a/sdk/include/ndk/extypes.h +++ b/sdk/include/ndk/extypes.h @@ -761,7 +761,11 @@ typedef struct _SYSTEM_PROCESSOR_INFORMATION #else USHORT MaximumProcessors; #endif +#if (NTDDI_VERSION >= NTDDI_WIN10) || ((NTDDI_VERSION >= NTDDI_WINBLUE) && defined(_WIN64)) + ULONG64 ProcessorFeatureBits; +#else ULONG ProcessorFeatureBits; +#endif } SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION; // Class 2 diff --git a/sdk/include/ndk/i386/ketypes.h b/sdk/include/ndk/i386/ketypes.h index 757fd4e82d4..e97f243b6c0 100644 --- a/sdk/include/ndk/i386/ketypes.h +++ b/sdk/include/ndk/i386/ketypes.h @@ -781,6 +781,12 @@ typedef struct _KPRCB ULONG PackageProcessorSet; ULONG CoreProcessorSet; #endif +#ifdef __REACTOS__ +#if (NTDDI_VERSION < NTDDI_WIN10) + // On Win 10+ the FeatureBits field is extended to 64 bits + ULONG FeatureBitsHigh; +#endif +#endif } KPRCB, *PKPRCB; //
1 month
1
0
0
0
[reactos] 01/01: [SHELL32] CMenuBand must set ShowWindow value for InvokeCommand (#7695)
by Whindmar Saksit
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=77e4217919a2e5cf8b4fe…
commit 77e4217919a2e5cf8b4fef8db32e64678307e746 Author: Whindmar Saksit <whindsaks(a)proton.me> AuthorDate: Sat Feb 1 13:50:22 2025 +0100 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Feb 1 13:50:22 2025 +0100 [SHELL32] CMenuBand must set ShowWindow value for InvokeCommand (#7695) --- dll/win32/shell32/shellmenu/CMenuBand.cpp | 1 + dll/win32/shell32/shlexec.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dll/win32/shell32/shellmenu/CMenuBand.cpp b/dll/win32/shell32/shellmenu/CMenuBand.cpp index 486f745c6b0..36c58121984 100644 --- a/dll/win32/shell32/shellmenu/CMenuBand.cpp +++ b/dll/win32/shell32/shellmenu/CMenuBand.cpp @@ -865,6 +865,7 @@ HRESULT CMenuBand::_TrackContextMenu(IContextMenu * contextMenu, INT x, INT y) cmi.fMask |= CMIC_MASK_SHIFT_DOWN; if (GetKeyState(VK_CONTROL) < 0) cmi.fMask |= CMIC_MASK_CONTROL_DOWN; + cmi.nShow = SW_SHOW; hr = contextMenu->InvokeCommand(&cmi); TRACE("InvokeCommand returned hr=%08x\n", hr); } diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 9e3af71a27f..cf04d935742 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -1461,7 +1461,7 @@ static HRESULT shellex_run_context_menu_default(IShellExtInit *obj, memset(&ici, 0, sizeof ici); ici.cbSize = sizeof ici; - ici.fMask = CMIC_MASK_UNICODE | (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI)); + ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) | CMIC_MASK_UNICODE; ici.nShow = sei->nShow; ici.lpVerb = MAKEINTRESOURCEA(def); ici.hwnd = sei->hwnd; @@ -1794,7 +1794,7 @@ SHELL_InvokePidl( // Invoke a command CMINVOKECOMMANDINFO ici = { sizeof(ici) }; - ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI)); + ici.fMask = (sei->fMask & SEE_CMIC_COMMON_BASICFLAGS) & ~CMIC_MASK_UNICODE; // FIXME: Unicode? ici.nShow = sei->nShow; ici.hwnd = sei->hwnd; char szVerb[VERBKEY_CCHMAX];
1 month
1
0
0
0
← Newer
1
2
3
4
5
6
7
8
Older →
Jump to page:
1
2
3
4
5
6
7
8
Results per page:
10
25
50
100
200