mirror of https://github.com/microsoft/WSL
Compare commits
15 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
c5fd672847 | |
|
|
d0609393e4 | |
|
|
1e3ef15f6d | |
|
|
f02f8ef91c | |
|
|
d48d374c8c | |
|
|
c6ac7433b1 | |
|
|
e24df7e0d1 | |
|
|
180d811099 | |
|
|
9ed5c130f4 | |
|
|
b4c0ced6b8 | |
|
|
f1e20b21c9 | |
|
|
7f8422654e | |
|
|
00b76b1d4b | |
|
|
8c166d7383 | |
|
|
19f06f9f51 |
|
|
@ -66,12 +66,30 @@ Build parameters:
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
### Unit Tests (Windows Only - TAEF Framework)
|
### Unit Tests (Windows Only - TAEF Framework)
|
||||||
|
|
||||||
|
**CRITICAL: ALWAYS build the ENTIRE project before running tests:**
|
||||||
|
```powershell
|
||||||
|
# Build everything first - this is required!
|
||||||
|
cmake --build . -- -m
|
||||||
|
|
||||||
|
# Then run tests
|
||||||
|
bin\<platform>\<target>\test.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why full build is required:**
|
||||||
|
- Tests depend on multiple components (libwsl.dll, wsltests.dll, wslservice.exe, etc.)
|
||||||
|
- Partial builds (e.g., only `configfile` or `wsltests`) will cause test failures
|
||||||
|
- Changed components must be built together to ensure compatibility
|
||||||
|
- **DO NOT skip the full build step even if only one file changed**
|
||||||
|
|
||||||
|
Test execution:
|
||||||
- Run all tests: `bin\<platform>\<target>\test.bat`
|
- Run all tests: `bin\<platform>\<target>\test.bat`
|
||||||
- **NEVER CANCEL: Full test suite takes 30-60 minutes. Set timeout to 90+ minutes.**
|
- **NEVER CANCEL: Full test suite takes 30-60 minutes. Set timeout to 90+ minutes.**
|
||||||
- Run subset: `bin\<platform>\<target>\test.bat /name:*UnitTest*`
|
- Run subset: `bin\<platform>\<target>\test.bat /name:*UnitTest*`
|
||||||
- Run specific test: `bin\<platform>\<target>\test.bat /name:<class>::<test>`
|
- Run specific test: `bin\<platform>\<target>\test.bat /name:<class>::<test>`
|
||||||
- WSL1 tests: Add `-Version 1` flag
|
- WSL1 tests: Add `-Version 1` flag
|
||||||
- Fast mode (after first run): Add `-f` flag (requires `wsl --set-default test_distro`)
|
- Fast mode (after first run): Add `-f` flag (requires `wsl --set-default test_distro`)
|
||||||
|
- **Requires Administrator privileges** - test.bat will fail without admin rights
|
||||||
|
|
||||||
Test debugging:
|
Test debugging:
|
||||||
- Wait for debugger: `/waitfordebugger`
|
- Wait for debugger: `/waitfordebugger`
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,7 @@ stages:
|
||||||
Move-Item -Path "bin\x64\cloudtest" -Destination "$(ob_outputDirectory)\testbin\x64\cloudtest"
|
Move-Item -Path "bin\x64\cloudtest" -Destination "$(ob_outputDirectory)\testbin\x64\cloudtest"
|
||||||
Move-Item -Path "tools\test\test-setup.ps1" -Destination "$(ob_outputDirectory)\testbin\test-setup.ps1"
|
Move-Item -Path "tools\test\test-setup.ps1" -Destination "$(ob_outputDirectory)\testbin\test-setup.ps1"
|
||||||
Move-Item -Path "tools\test\CloudTest-Setup.bat" -Destination "$(ob_outputDirectory)\testbin\CloudTest-Setup.bat"
|
Move-Item -Path "tools\test\CloudTest-Setup.bat" -Destination "$(ob_outputDirectory)\testbin\CloudTest-Setup.bat"
|
||||||
Move-Item -Path "tools\wsl.wprp" -Destination "$(ob_outputDirectory)\testbin\wsl.wprp"
|
Move-Item -Path "diagnostics\wsl.wprp" -Destination "$(ob_outputDirectory)\testbin\wsl.wprp"
|
||||||
Move-Item -Path "test\linux\unit_tests" -Destination "$(ob_outputDirectory)\testbin\unit_tests"
|
Move-Item -Path "test\linux\unit_tests" -Destination "$(ob_outputDirectory)\testbin\unit_tests"
|
||||||
|
|
||||||
Move-Item -Path bundle\release\* -Destination $(ob_outputDirectory)\bundle
|
Move-Item -Path bundle\release\* -Destination $(ob_outputDirectory)\bundle
|
||||||
|
|
|
||||||
153
NOTICE.txt
153
NOTICE.txt
|
|
@ -643,6 +643,159 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||||
Microsoft.NETCore.App.Runtime.win-arm64 10.0.0 - MIT
|
Microsoft.NETCore.App.Runtime.win-arm64 10.0.0 - MIT
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2021
|
||||||
|
Copyright (c) Six Labors
|
||||||
|
(c) Microsoft Corporation
|
||||||
|
Copyright (c) 2022 FormatJS
|
||||||
|
Copyright (c) Andrew Arnott
|
||||||
|
Copyright 2019 LLVM Project
|
||||||
|
Copyright (c) 1998 Microsoft
|
||||||
|
Copyright 2018 Daniel Lemire
|
||||||
|
Copyright (c) .NET Foundation
|
||||||
|
Copyright 1995-2022 Mark Adler
|
||||||
|
Copyright 1995-2024 Mark Adler
|
||||||
|
Copyright (c) 2011, Google Inc.
|
||||||
|
Copyright (c) 2020 Dan Shechter
|
||||||
|
(c) 1997-2005 Sean Eron Anderson
|
||||||
|
Copyright (c) 2015 Andrew Gallant
|
||||||
|
Copyright (c) 2022, Wojciech Mula
|
||||||
|
Copyright (c) 2017 Yoshifumi Kawai
|
||||||
|
Copyright (c) 2022, Geoff Langdale
|
||||||
|
Copyright (c) 2005-2020 Rich Felker
|
||||||
|
Copyright (c) 2012-2021 Yann Collet
|
||||||
|
Copyright (c) Microsoft Corporation
|
||||||
|
Copyright (c) 2007 James Newton-King
|
||||||
|
Copyright (c) 1991-2024 Unicode, Inc.
|
||||||
|
Copyright (c) 2013-2017, Alfred Klomp
|
||||||
|
Copyright (c) 2018 Nemanja Mijailovic
|
||||||
|
Copyright 2012 the V8 project authors
|
||||||
|
Copyright (c) 1999 Lucent Technologies
|
||||||
|
Copyright (c) 2008-2016, Wojciech Mula
|
||||||
|
Copyright (c) 2011-2020 Microsoft Corp
|
||||||
|
Copyright (c) 2015-2017, Wojciech Mula
|
||||||
|
Copyright (c) 2015-2018, Wojciech Mula
|
||||||
|
Copyright (c) 2005-2007, Nick Galbreath
|
||||||
|
Copyright (c) 2015 The Chromium Authors
|
||||||
|
Copyright (c) 2018 Alexander Chermyanin
|
||||||
|
Copyright (c) The Internet Society 1997
|
||||||
|
Copyright (c) 2004-2006 Intel Corporation
|
||||||
|
Copyright (c) 2011-2015 Intel Corporation
|
||||||
|
Copyright (c) 2013-2017, Milosz Krajewski
|
||||||
|
Copyright (c) 2016-2017, Matthieu Darbois
|
||||||
|
Copyright (c) The Internet Society (2003)
|
||||||
|
Copyright (c) .NET Foundation Contributors
|
||||||
|
(c) 1995-2024 Jean-loup Gailly and Mark Adler
|
||||||
|
Copyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>
|
||||||
|
Copyright (c) .NET Foundation and Contributors
|
||||||
|
Copyright (c) 2012 - present, Victor Zverovich
|
||||||
|
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
|
||||||
|
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
|
||||||
|
Copyright (c) 2019 Microsoft Corporation, Daan Leijen
|
||||||
|
Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||||
|
Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
|
||||||
|
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
|
||||||
|
Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
|
||||||
|
Copyright 1995-2024 Jean-loup Gailly and Mark Adler Qkkbal
|
||||||
|
Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
||||||
|
Portions (c) International Organization for Standardization 1986
|
||||||
|
Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
|
||||||
|
Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
|
||||||
|
Copyright (c) 1980, 1986, 1993 The Regents of the University of California
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
|
||||||
|
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) .NET Foundation and Contributors
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
|
Microsoft.NETCore.App.Runtime.win-x64 10.0.0 - MIT
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2021
|
||||||
|
Copyright (c) Six Labors
|
||||||
|
(c) Microsoft Corporation
|
||||||
|
Copyright (c) 2022 FormatJS
|
||||||
|
Copyright (c) Andrew Arnott
|
||||||
|
Copyright 2019 LLVM Project
|
||||||
|
Copyright (c) 1998 Microsoft
|
||||||
|
Copyright 2018 Daniel Lemire
|
||||||
|
Copyright (c) .NET Foundation
|
||||||
|
Copyright 1995-2022 Mark Adler
|
||||||
|
Copyright 1995-2024 Mark Adler
|
||||||
|
Copyright (c) 2011, Google Inc.
|
||||||
|
Copyright (c) 2020 Dan Shechter
|
||||||
|
(c) 1997-2005 Sean Eron Anderson
|
||||||
|
Copyright (c) 2015 Andrew Gallant
|
||||||
|
Copyright (c) 2022, Wojciech Mula
|
||||||
|
Copyright (c) 2017 Yoshifumi Kawai
|
||||||
|
Copyright (c) 2022, Geoff Langdale
|
||||||
|
Copyright (c) 2005-2020 Rich Felker
|
||||||
|
Copyright (c) 2012-2021 Yann Collet
|
||||||
|
Copyright (c) Microsoft Corporation
|
||||||
|
Copyright (c) 2007 James Newton-King
|
||||||
|
Copyright (c) 1991-2024 Unicode, Inc.
|
||||||
|
Copyright (c) 2013-2017, Alfred Klomp
|
||||||
|
Copyright (c) 2018 Nemanja Mijailovic
|
||||||
|
Copyright 2012 the V8 project authors
|
||||||
|
Copyright (c) 1999 Lucent Technologies
|
||||||
|
Copyright (c) 2008-2016, Wojciech Mula
|
||||||
|
Copyright (c) 2011-2020 Microsoft Corp
|
||||||
|
Copyright (c) 2015-2017, Wojciech Mula
|
||||||
|
Copyright (c) 2015-2018, Wojciech Mula
|
||||||
|
Copyright (c) 2005-2007, Nick Galbreath
|
||||||
|
Copyright (c) 2015 The Chromium Authors
|
||||||
|
Copyright (c) 2018 Alexander Chermyanin
|
||||||
|
Copyright (c) The Internet Society 1997
|
||||||
|
Copyright (c) 2004-2006 Intel Corporation
|
||||||
|
Copyright (c) 2011-2015 Intel Corporation
|
||||||
|
Copyright (c) 2013-2017, Milosz Krajewski
|
||||||
|
Copyright (c) 2016-2017, Matthieu Darbois
|
||||||
|
Copyright (c) The Internet Society (2003)
|
||||||
|
Copyright (c) .NET Foundation Contributors
|
||||||
|
(c) 1995-2024 Jean-loup Gailly and Mark Adler
|
||||||
|
Copyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>
|
||||||
|
Copyright (c) .NET Foundation and Contributors
|
||||||
|
Copyright (c) 2012 - present, Victor Zverovich
|
||||||
|
Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
|
||||||
|
Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
|
||||||
|
Copyright (c) 2019 Microsoft Corporation, Daan Leijen
|
||||||
|
Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||||
|
Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
|
||||||
|
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
|
||||||
|
Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
|
||||||
|
Copyright 1995-2024 Jean-loup Gailly and Mark Adler Qkkbal
|
||||||
|
Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
||||||
|
Portions (c) International Organization for Standardization 1986
|
||||||
|
Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
|
||||||
|
Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
|
||||||
|
Copyright (c) 1980, 1986, 1993 The Regents of the University of California
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
|
||||||
|
Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
|
||||||
|
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ message(STATUS "Loading user configuration")
|
||||||
# file(CREATE_LINK "${MSRDC_SOURCE_DIR}/${TARGET_PLATFORM}/rdpnanoTransport.dll" "${WSL_DEV_BINARY_PATH}/rdpnanoTransport.dll" SYMBOLIC)
|
# file(CREATE_LINK "${MSRDC_SOURCE_DIR}/${TARGET_PLATFORM}/rdpnanoTransport.dll" "${WSL_DEV_BINARY_PATH}/rdpnanoTransport.dll" SYMBOLIC)
|
||||||
# file(CREATE_LINK "${MSRDC_SOURCE_DIR}/${TARGET_PLATFORM}/RdpWinStlHelper.dll" "${WSL_DEV_BINARY_PATH}/RdpWinStlHelper.dll" SYMBOLIC)
|
# file(CREATE_LINK "${MSRDC_SOURCE_DIR}/${TARGET_PLATFORM}/RdpWinStlHelper.dll" "${WSL_DEV_BINARY_PATH}/RdpWinStlHelper.dll" SYMBOLIC)
|
||||||
# file(CREATE_LINK "${MSAL_SOURCE_DIR}/${TARGET_PLATFORM}/msal.wsl.proxy.exe" "${WSL_DEV_BINARY_PATH}/msal.wsl.proxy.exe" SYMBOLIC)
|
# file(CREATE_LINK "${MSAL_SOURCE_DIR}/${TARGET_PLATFORM}/msal.wsl.proxy.exe" "${WSL_DEV_BINARY_PATH}/msal.wsl.proxy.exe" SYMBOLIC)
|
||||||
# file(CREATE_LINK "${BIN}/wsldevicehost.dll" "${WSL_DEV_BINARY_PATH}/wsldevicehost.exe" SYMBOLIC)
|
# file(CREATE_LINK "${BIN}/wsldevicehost.dll" "${WSL_DEV_BINARY_PATH}/wsldevicehost.dll" SYMBOLIC)
|
||||||
# file(CREATE_LINK "${DIRECT3D_SOURCE_DIR}/lib/${TARGET_PLATFORM}" "${WSL_DEV_BINARY_PATH}/lib" SYMBOLIC)
|
# file(CREATE_LINK "${DIRECT3D_SOURCE_DIR}/lib/${TARGET_PLATFORM}" "${WSL_DEV_BINARY_PATH}/lib" SYMBOLIC)
|
||||||
|
|
||||||
# foreach(LANG ${SUPPORTED_LANGS})
|
# foreach(LANG ${SUPPORTED_LANGS})
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
<EventProvider Id="wsl_devicehost" Name="9d6c7b9e-2581-4d8a-b8c5-b90b4a17094a"/>
|
<EventProvider Id="wsl_devicehost" Name="9d6c7b9e-2581-4d8a-b8c5-b90b4a17094a"/>
|
||||||
<EventProvider Id="wslclient" Name="8cbb7724-7223-5d6f-8137-564dac45104d"/>
|
<EventProvider Id="wslclient" Name="8cbb7724-7223-5d6f-8137-564dac45104d"/>
|
||||||
<EventProvider Id="wslapi" Name="beb94edf-1a7b-5058-0696-ff9e6b1798d1"/>
|
<EventProvider Id="wslapi" Name="beb94edf-1a7b-5058-0696-ff9e6b1798d1"/>
|
||||||
|
<EventProvider Id="vfpext" Name="9F2660EA-CFE7-428F-9850-AECA612619B0" />
|
||||||
<EventProvider Id="vm_chipset" Name="de9ba731-7f33-4f44-98c9-6cac856b9f83"/>
|
<EventProvider Id="vm_chipset" Name="de9ba731-7f33-4f44-98c9-6cac856b9f83"/>
|
||||||
<EventProvider Id="vmcompute_dll" Name="AF7FD3A7-B248-460C-A9F5-FEC39EF8468C"/>
|
<EventProvider Id="vmcompute_dll" Name="AF7FD3A7-B248-460C-A9F5-FEC39EF8468C"/>
|
||||||
<EventProvider Id="vmcompute" Name="17103E3F-3C6E-4677-BB17-3B267EB5BE57"/>
|
<EventProvider Id="vmcompute" Name="17103E3F-3C6E-4677-BB17-3B267EB5BE57"/>
|
||||||
|
|
@ -19,7 +20,7 @@
|
||||||
<EventProvider Id="vmwp" Name="51DDFA29-D5C8-4803-BE4B-2ECB715570FE"/>
|
<EventProvider Id="vmwp" Name="51DDFA29-D5C8-4803-BE4B-2ECB715570FE"/>
|
||||||
<EventProvider Id="9p" Name="e13c8d52-b153-571f-78c5-1d4098af2a1e"/>
|
<EventProvider Id="9p" Name="e13c8d52-b153-571f-78c5-1d4098af2a1e"/>
|
||||||
<EventProvider Id="9p_errors" Name="06C601B3-6957-4F8C-A15F-74875B24429D" />
|
<EventProvider Id="9p_errors" Name="06C601B3-6957-4F8C-A15F-74875B24429D" />
|
||||||
<EventProvider Id="p9rdr" Name="bb1d36f0-e0e0-48cc-9493-fef0e3d0b28c" />
|
<EventProvider Id="p9rdr" Name="bb1d36f0-e0e0-48cc-9493-fef0e3d0b28c" NonPagedMemory="true" Strict="true"/>
|
||||||
<EventProvider Id="mup" Name="20c46239-d059-4214-a11e-7d6769cbe020" />
|
<EventProvider Id="mup" Name="20c46239-d059-4214-a11e-7d6769cbe020" />
|
||||||
<EventProvider Id="rfsmon" Name="51734B23-5B7E-4892-BA8E-45BC110B735C" />
|
<EventProvider Id="rfsmon" Name="51734B23-5B7E-4892-BA8E-45BC110B735C" />
|
||||||
<EventProvider Id="hyperv_storage" Name="c7ad62c6-5c99-5a1b-bbc4-0821ae5b765e" />
|
<EventProvider Id="hyperv_storage" Name="c7ad62c6-5c99-5a1b-bbc4-0821ae5b765e" />
|
||||||
|
|
@ -115,6 +116,7 @@
|
||||||
<EventProviderId Value="wsl_devicehost"/>
|
<EventProviderId Value="wsl_devicehost"/>
|
||||||
<EventProviderId Value="wslclient"/>
|
<EventProviderId Value="wslclient"/>
|
||||||
<EventProviderId Value="wslapi"/>
|
<EventProviderId Value="wslapi"/>
|
||||||
|
<EventProviderId Value="vfpext"/>
|
||||||
<EventProviderId Value="vm_chipset"/>
|
<EventProviderId Value="vm_chipset"/>
|
||||||
<EventProviderId Value="vmcompute_dll"/>
|
<EventProviderId Value="vmcompute_dll"/>
|
||||||
<EventProviderId Value="vmcompute"/>
|
<EventProviderId Value="vmcompute"/>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Může být nutné restartovat systém, aby se změny projevily.</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Změna velikosti disku se nezdařila.</value>
|
<value>Změna velikosti disku se nezdařila.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Cestu se nepodařilo přeložit.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Nebyla nalezena žádná hodnota.</value>
|
<value>Nebyla nalezena žádná hodnota.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -1060,7 +1057,7 @@ Návrat k sítím NAT.</value>
|
||||||
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
|
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessagePassVhdFlag" xml:space="preserve">
|
<data name="MessagePassVhdFlag" xml:space="preserve">
|
||||||
<value>This looks like a VHD file. Use --vhd to import a VHD instead of a tar.</value>
|
<value>Vypadá to jako soubor VHD. K importu virtuálního pevného disku místo tar použijte --vhd </value>
|
||||||
<comment>{Locked="--vhd "}Command line arguments, file names and string inserts should not be translated</comment>
|
<comment>{Locked="--vhd "}Command line arguments, file names and string inserts should not be translated</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageDistroStoreInstallFailed" xml:space="preserve">
|
<data name="MessageDistroStoreInstallFailed" xml:space="preserve">
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Systemet skal muligvis genstartes, så ændringerne kan træde i kraft.</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Diskens størrelsen kunne ikke tilpasses.</value>
|
<value>Diskens størrelsen kunne ikke tilpasses.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Det mislykkedes at oversætte stien.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Der blev ikke fundet nogen værdi.</value>
|
<value>Der blev ikke fundet nogen værdi.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -736,9 +736,6 @@ Das System muss möglicherweise neu gestartet werden, damit die Änderungen wirk
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Fehler beim Ändern der Größe des Datenträgers.</value>
|
<value>Fehler beim Ändern der Größe des Datenträgers.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Fehler beim Übersetzen des Pfads.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Kein Wert gefunden.</value>
|
<value>Kein Wert gefunden.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ The system may need to be restarted so the changes can take effect.</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Failed to resize disk.</value>
|
<value>Failed to resize disk.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Failed to translate path.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>No value found.</value>
|
<value>No value found.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ The system may need to be restarted so the changes can take effect.</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Failed to resize disk.</value>
|
<value>Failed to resize disk.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Failed to translate path.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>No value found.</value>
|
<value>No value found.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -736,9 +736,6 @@ Es posible que sea necesario reiniciar el sistema para que los cambios surtan ef
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Error al cambiar el tamaño del disco.</value>
|
<value>Error al cambiar el tamaño del disco.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>No se pudo traducir la ruta de acceso.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>No se encontró ningún valor.</value>
|
<value>No se encontró ningún valor.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Järjestelmä on ehkä käynnistettävä uudelleen, jotta muutokset tulevat voim
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Levyn koon muuttaminen epäonnistui.</value>
|
<value>Levyn koon muuttaminen epäonnistui.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Polun kääntäminen epäonnistui.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Arvoa ei löytynyt.</value>
|
<value>Arvoa ei löytynyt.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -737,9 +737,6 @@ Le système devra peut-être être redémarré pour que les modifications prenne
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Échec de redimensionnement de disque.</value>
|
<value>Échec de redimensionnement de disque.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Échec de la traduction du chemin d’accès.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Valeur non trouvée.</value>
|
<value>Valeur non trouvée.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Lehet, hogy újra kell indítani a rendszert, hogy a módosítások érvénybe l
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Nem sikerült a lemez átméretezése.</value>
|
<value>Nem sikerült a lemez átméretezése.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Az útvonal fordítása nem sikerült.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Nem található érték.</value>
|
<value>Nem található érték.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -736,9 +736,6 @@ Potrebbe essere necessario riavviare il sistema per rendere effettive le modific
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Non è possibile ridimensionare il disco.</value>
|
<value>Non è possibile ridimensionare il disco.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Non è stato possibile tradurre il percorso.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Nessun valore trovato.</value>
|
<value>Nessun valore trovato.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -736,9 +736,6 @@ Windows バージョン: {}</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>ディスクのサイズを変更できませんでした。</value>
|
<value>ディスクのサイズを変更できませんでした。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>パスを変換できませんでした。</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>値が見つかりません。</value>
|
<value>値が見つかりません。</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -736,9 +736,6 @@ Windows 버전: {}</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>디스크 크기를 조정하지 못했습니다.</value>
|
<value>디스크 크기를 조정하지 못했습니다.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>경로를 변환하지 못했습니다.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>값을 찾을 수 없습니다.</value>
|
<value>값을 찾을 수 없습니다.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Systemet må kanskje startes på nytt slik at endringene kan tre i kraft.</value
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Kan ikke endre størrelsen på disken.</value>
|
<value>Kan ikke endre størrelsen på disken.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Kan ikke oversette banen.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Finner ingen verdi.</value>
|
<value>Finner ingen verdi.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Het systeem moet mogelijk opnieuw worden opgestart, zodat de wijzigingen van kra
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Kan het formaat van de schijf niet wijzigen.</value>
|
<value>Kan het formaat van de schijf niet wijzigen.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Kan pad niet vertalen.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Geen waarde gevonden.</value>
|
<value>Geen waarde gevonden.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Może być konieczne ponowne uruchomienie systemu, aby zmiany zostały wprowadzo
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Nie można zmienić rozmiaru dysku.</value>
|
<value>Nie można zmienić rozmiaru dysku.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Nie można przetłumaczyć ścieżki.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Nie znaleziono wartości.</value>
|
<value>Nie znaleziono wartości.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -1060,7 +1057,7 @@ Powrót do sieci NAT.</value>
|
||||||
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
|
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessagePassVhdFlag" xml:space="preserve">
|
<data name="MessagePassVhdFlag" xml:space="preserve">
|
||||||
<value>This looks like a VHD file. Use --vhd to import a VHD instead of a tar.</value>
|
<value>Wygląda to na plik VHD. Użyj polecenia --vhd aby zaimportować plik VHD zamiast tar.</value>
|
||||||
<comment>{Locked="--vhd "}Command line arguments, file names and string inserts should not be translated</comment>
|
<comment>{Locked="--vhd "}Command line arguments, file names and string inserts should not be translated</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageDistroStoreInstallFailed" xml:space="preserve">
|
<data name="MessageDistroStoreInstallFailed" xml:space="preserve">
|
||||||
|
|
|
||||||
|
|
@ -737,9 +737,6 @@ Talvez seja necessário reiniciar o sistema para que as alterações entrem em v
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Falha ao redimensionar o disco.</value>
|
<value>Falha ao redimensionar o disco.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Falha ao converter o caminho.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Nenhum valor encontrado.</value>
|
<value>Nenhum valor encontrado.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ O sistema poderá ter de ser reiniciado para que as alterações possam ter efei
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Falha ao redimensionar o disco.</value>
|
<value>Falha ao redimensionar o disco.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Falha ao traduzir caminho.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Não foi encontrado nenhum valor.</value>
|
<value>Não foi encontrado nenhum valor.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -737,9 +737,6 @@
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Не удалось изменить размер диска.</value>
|
<value>Не удалось изменить размер диска.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Не удалось преобразовать путь.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Значение не найдено.</value>
|
<value>Значение не найдено.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Systemet kan behöva startas om så att ändringarna kan börja gälla.</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Det gick inte att ändra storlek på disken.</value>
|
<value>Det gick inte att ändra storlek på disken.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Det gick inte att översätta sökvägen.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Inget värde hittades.</value>
|
<value>Inget värde hittades.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -730,9 +730,6 @@ Değişikliklerin etkili olması için sistemin yeniden başlatılması gerekebi
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>Disk yeniden boyutlandırılamadı.</value>
|
<value>Disk yeniden boyutlandırılamadı.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>Yol çevrilemedi.</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>Değer bulunamadı.</value>
|
<value>Değer bulunamadı.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -736,9 +736,6 @@ Windows: {}</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>未能重设磁盘大小。</value>
|
<value>未能重设磁盘大小。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>无法转换路径。</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>找不到值。</value>
|
<value>找不到值。</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -736,9 +736,6 @@ Windows 版本: {}</value>
|
||||||
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
<data name="MessageFailedToResizeDisk" xml:space="preserve">
|
||||||
<value>無法調整磁碟。</value>
|
<value>無法調整磁碟。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageFailedToTranslatePath" xml:space="preserve">
|
|
||||||
<value>無法翻譯路徑。</value>
|
|
||||||
</data>
|
|
||||||
<data name="MessageNoValueFound" xml:space="preserve">
|
<data name="MessageNoValueFound" xml:space="preserve">
|
||||||
<value>找不到任何值。</value>
|
<value>找不到任何值。</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@
|
||||||
<!-- WslDeviceHost_VirtioFs (admin) -->
|
<!-- WslDeviceHost_VirtioFs (admin) -->
|
||||||
<RegistryKey Root="HKCR" Key="CLSID\{7e6ad219-d1b3-42d5-b8ee-d96324e64ff6}">
|
<RegistryKey Root="HKCR" Key="CLSID\{7e6ad219-d1b3-42d5-b8ee-d96324e64ff6}">
|
||||||
<RegistryValue Value="WslDeviceHost_VirtioFs_Admin" Type="string"/>
|
<RegistryValue Value="WslDeviceHost_VirtioFs_Admin" Type="string"/>
|
||||||
<RegistryValue Name="AppId" Value="{7F82AD86-755B-4870-86B1-D2E68DFE8A49}" Type="string"/>
|
<RegistryValue Name="AppId" Value="{17696EAC-9568-4CF5-BB8C-82515AAD6C09}" Type="string"/>
|
||||||
|
|
||||||
<RegistryKey Key="InProcServer32">
|
<RegistryKey Key="InProcServer32">
|
||||||
<RegistryValue Value="[INSTALLDIR]wsldevicehost.dll" Type="string"/>
|
<RegistryValue Value="[INSTALLDIR]wsldevicehost.dll" Type="string"/>
|
||||||
|
|
@ -191,15 +191,6 @@
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
|
||||||
<RegistryKey Root="HKCR" Key="AppID\{7F82AD86-755B-4870-86B1-D2E68DFE8A49}">
|
|
||||||
<RegistryValue Name="DllSurrogate" Value="" Type="string"/>
|
|
||||||
<RegistryValue Name="AppIDFlags" Value="2048" Type="integer"/><!--0x800-->
|
|
||||||
|
|
||||||
<!-- O:BAG:BAD:(A;;CCDCSW;;;AU)(A;;CCDCSW;;;PS)(A;;CCDCSW;;;SY) -->
|
|
||||||
<RegistryValue Name="AccessPermission" Value="01000480580000006800000000000000140000000200440003000000000014000B00000001010000000000050B000000000014000B00000001010000000000050A000000000014000B0000000101000000000005120000000102000000000005200000002002000001020000000000052000000020020000" Type="binary" />
|
|
||||||
<RegistryValue Name="LaunchPermission" Value="01000480580000006800000000000000140000000200440003000000000014000B00000001010000000000050B000000000014000B00000001010000000000050A000000000014000B0000000101000000000005120000000102000000000005200000002002000001020000000000052000000020020000" Type="binary" />
|
|
||||||
</RegistryKey>
|
|
||||||
|
|
||||||
<!-- WslDeviceHost_VirtioFs -->
|
<!-- WslDeviceHost_VirtioFs -->
|
||||||
<RegistryKey Root="HKCR" Key="CLSID\{60285AE6-AAF3-4456-B444-A6C2D0DEDA38}">
|
<RegistryKey Root="HKCR" Key="CLSID\{60285AE6-AAF3-4456-B444-A6C2D0DEDA38}">
|
||||||
<RegistryValue Value="WslDeviceHost_VirtioFs" Type="string" />
|
<RegistryValue Value="WslDeviceHost_VirtioFs" Type="string" />
|
||||||
|
|
|
||||||
|
|
@ -690,7 +690,7 @@ try
|
||||||
}
|
}
|
||||||
|
|
||||||
Common->Environment.AddVariable("DBUS_SESSION_BUS_ADDRESS", std::format("unix:path=/run/user/{}/bus", PasswordEntry->pw_uid));
|
Common->Environment.AddVariable("DBUS_SESSION_BUS_ADDRESS", std::format("unix:path=/run/user/{}/bus", PasswordEntry->pw_uid));
|
||||||
Common->Environment.AddVariable(XDG_RUNTIME_DIR_ENV, std::format("/run/user/{}/", PasswordEntry->pw_uid));
|
Common->Environment.AddVariable(XDG_RUNTIME_DIR_ENV, std::format("/run/user/{}", PasswordEntry->pw_uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
|
#include <linux/sock_diag.h>
|
||||||
|
#include <linux/inet_diag.h>
|
||||||
#include <lxwil.h>
|
#include <lxwil.h>
|
||||||
#include <linux/if_tun.h>
|
#include <linux/if_tun.h>
|
||||||
|
|
||||||
|
|
@ -21,6 +23,8 @@
|
||||||
#include "SecCompDispatcher.h"
|
#include "SecCompDispatcher.h"
|
||||||
#include "seccomp_defs.h"
|
#include "seccomp_defs.h"
|
||||||
#include "CommandLine.h"
|
#include "CommandLine.h"
|
||||||
|
#include "NetlinkChannel.h"
|
||||||
|
#include "NetlinkTransactionError.h"
|
||||||
|
|
||||||
#define TCP_LISTEN 10
|
#define TCP_LISTEN 10
|
||||||
|
|
||||||
|
|
@ -145,80 +149,60 @@ void ListenThread(sockaddr_vm hvSocketAddress, int listenSocket)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<sockaddr_storage> ParseTcpFile(int family, FILE* file)
|
std::vector<sockaddr_storage> QueryListeningSockets(NetlinkChannel& channel)
|
||||||
{
|
{
|
||||||
char* line = nullptr;
|
|
||||||
auto freeLine = wil::scope_exit([&line]() { free(line); });
|
|
||||||
|
|
||||||
// Skip the first line which contains a header.
|
|
||||||
size_t lineLength = 0;
|
|
||||||
auto bytesRead = getline(&line, &lineLength, file);
|
|
||||||
THROW_LAST_ERROR_IF(bytesRead < 0);
|
|
||||||
|
|
||||||
// Each line contains information about TCP sockets on the system, the fields
|
|
||||||
// we are interested are for sockets that are or have been listening:
|
|
||||||
// 1: Socket address and port number
|
|
||||||
// 3: Socket status
|
|
||||||
std::vector<sockaddr_storage> sockets{};
|
std::vector<sockaddr_storage> sockets{};
|
||||||
while ((bytesRead = getline(&line, &lineLength, file)) != -1)
|
try
|
||||||
{
|
{
|
||||||
sockaddr_storage sock{};
|
inet_diag_req_v2 message{};
|
||||||
int index = 0;
|
message.sdiag_protocol = IPPROTO_TCP;
|
||||||
int status = 0;
|
message.idiag_states = (1 << TCP_LISTEN);
|
||||||
for (char *sp, *field = strtok_r(line, " \n", &sp); field != nullptr; field = strtok_r(NULL, " \n", &sp))
|
|
||||||
|
auto onMessage = [&](const NetlinkResponse& response) {
|
||||||
|
for (const auto& e : response.Messages<inet_diag_msg>(SOCK_DIAG_BY_FAMILY))
|
||||||
|
{
|
||||||
|
const auto* payload = e.Payload();
|
||||||
|
sockaddr_storage sock{};
|
||||||
|
|
||||||
|
if (payload->idiag_family == AF_INET)
|
||||||
|
{
|
||||||
|
auto* ipv4 = reinterpret_cast<sockaddr_in*>(&sock);
|
||||||
|
ipv4->sin_family = AF_INET;
|
||||||
|
ipv4->sin_addr.s_addr = payload->id.idiag_src[0];
|
||||||
|
ipv4->sin_port = payload->id.idiag_sport;
|
||||||
|
}
|
||||||
|
else if (payload->idiag_family == AF_INET6)
|
||||||
|
{
|
||||||
|
auto* ipv6 = reinterpret_cast<sockaddr_in6*>(&sock);
|
||||||
|
ipv6->sin6_family = AF_INET6;
|
||||||
|
static_assert(sizeof(ipv6->sin6_addr.s6_addr32) == sizeof(payload->id.idiag_src));
|
||||||
|
memcpy(ipv6->sin6_addr.s6_addr32, payload->id.idiag_src, sizeof(ipv6->sin6_addr.s6_addr32));
|
||||||
|
ipv6->sin6_port = payload->id.idiag_sport;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockets.emplace_back(sock);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Query IPv4 listening sockets.
|
||||||
{
|
{
|
||||||
if (index == 1)
|
message.sdiag_family = AF_INET;
|
||||||
{
|
auto transaction = channel.CreateTransaction(message, SOCK_DIAG_BY_FAMILY, NLM_F_DUMP);
|
||||||
int port;
|
transaction.Execute(onMessage);
|
||||||
const char* portString = strchr(field, ':');
|
|
||||||
if (portString == nullptr)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
portString += 1;
|
|
||||||
port = static_cast<int>(strtol(portString, nullptr, 16));
|
|
||||||
if (port == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (family == AF_INET)
|
|
||||||
{
|
|
||||||
sockaddr_in ipv4Sock{};
|
|
||||||
ipv4Sock.sin_family = family;
|
|
||||||
ipv4Sock.sin_addr.s_addr = strtol(field, nullptr, 16);
|
|
||||||
ipv4Sock.sin_port = port;
|
|
||||||
memcpy(&sock, &ipv4Sock, sizeof(ipv4Sock));
|
|
||||||
}
|
|
||||||
else if (family == AF_INET6)
|
|
||||||
{
|
|
||||||
sockaddr_in6 ipv6Sock{};
|
|
||||||
ipv6Sock.sin6_family = family;
|
|
||||||
ipv6Sock.sin6_port = port;
|
|
||||||
for (int part = 0; part < 4; ++part)
|
|
||||||
{
|
|
||||||
char next[5];
|
|
||||||
next[4] = 0;
|
|
||||||
memcpy(next, field + part * 4, 4);
|
|
||||||
ipv6Sock.sin6_addr.__in6_union.__s6_addr32[part] = strtol(next, nullptr, 16);
|
|
||||||
}
|
|
||||||
memcpy(&sock, &ipv6Sock, sizeof(ipv6Sock));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (index == 3)
|
|
||||||
{
|
|
||||||
status = static_cast<int>(strtol(field, nullptr, 16));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
index += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status == TCP_LISTEN) && (sock.ss_family != 0))
|
// Query IPv6 listening sockets.
|
||||||
{
|
{
|
||||||
sockets.emplace_back(sock);
|
message.sdiag_family = AF_INET6;
|
||||||
|
auto transaction = channel.CreateTransaction(message, SOCK_DIAG_BY_FAMILY, NLM_F_DUMP);
|
||||||
|
transaction.Execute(onMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (const NetlinkTransactionError& e)
|
||||||
|
{
|
||||||
|
// Log but don't fail - network state might be temporarily unavailable
|
||||||
|
LOG_ERROR("Failed to query listening sockets via sock_diag: {}", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
return sockets;
|
return sockets;
|
||||||
}
|
}
|
||||||
|
|
@ -246,12 +230,12 @@ LX_GNS_PORT_LISTENER_RELAY SockToRelayMessage(const sockaddr_storage& sock)
|
||||||
{
|
{
|
||||||
auto ipv4 = reinterpret_cast<const sockaddr_in*>(&sock);
|
auto ipv4 = reinterpret_cast<const sockaddr_in*>(&sock);
|
||||||
message.Address[0] = ipv4->sin_addr.s_addr;
|
message.Address[0] = ipv4->sin_addr.s_addr;
|
||||||
message.Port = ipv4->sin_port;
|
message.Port = ntohs(ipv4->sin_port);
|
||||||
}
|
}
|
||||||
else if (sock.ss_family == AF_INET6)
|
else if (sock.ss_family == AF_INET6)
|
||||||
{
|
{
|
||||||
auto ipv6 = reinterpret_cast<const sockaddr_in6*>(&sock);
|
auto ipv6 = reinterpret_cast<const sockaddr_in6*>(&sock);
|
||||||
message.Port = ipv6->sin6_port;
|
message.Port = ntohs(ipv6->sin6_port);
|
||||||
memcpy(message.Address, ipv6->sin6_addr.__in6_union.__s6_addr, sizeof(message.Address));
|
memcpy(message.Address, ipv6->sin6_addr.__in6_union.__s6_addr, sizeof(message.Address));
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
|
|
@ -296,53 +280,23 @@ bool IsSameSockAddr(const sockaddr_storage& left, const sockaddr_storage& right)
|
||||||
{
|
{
|
||||||
auto leftIpv6 = reinterpret_cast<const sockaddr_in6*>(&left);
|
auto leftIpv6 = reinterpret_cast<const sockaddr_in6*>(&left);
|
||||||
auto rightIpv6 = reinterpret_cast<const sockaddr_in6*>(&right);
|
auto rightIpv6 = reinterpret_cast<const sockaddr_in6*>(&right);
|
||||||
if (leftIpv6->sin6_port != rightIpv6->sin6_port)
|
return (leftIpv6->sin6_port == rightIpv6->sin6_port && memcmp(&leftIpv6->sin6_addr, &rightIpv6->sin6_addr, sizeof(in6_addr)) == 0);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int part = 0; part < 4; ++part)
|
|
||||||
{
|
|
||||||
if (leftIpv6->sin6_addr.__in6_union.__s6_addr32[part] != rightIpv6->sin6_addr.__in6_union.__s6_addr32[part])
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FATAL_ERROR("Unrecognized socket family {}", left.ss_family);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FATAL_ERROR("Unrecognized socket family {}", left.ss_family);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start looking for ports bound to localhost or wildcard.
|
// Monitor listening TCP sockets using sock_diag netlink interface.
|
||||||
int ScanProcNetTCP(wsl::shared::SocketChannel& channel)
|
int MonitorListeningSockets(wsl::shared::SocketChannel& channel)
|
||||||
{
|
{
|
||||||
// Periodically scan procfs for listening TCP sockets.
|
NetlinkChannel netlinkChannel(SOCK_RAW, NETLINK_SOCK_DIAG);
|
||||||
std::vector<sockaddr_storage> relays{};
|
std::vector<sockaddr_storage> relays{};
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
std::vector<sockaddr_storage> sockets;
|
auto sockets = QueryListeningSockets(netlinkChannel);
|
||||||
wil::unique_file tcp4File{fopen("/proc/net/tcp", "r")};
|
|
||||||
if (tcp4File)
|
|
||||||
{
|
|
||||||
sockets = ParseTcpFile(AF_INET, tcp4File.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
wil::unique_file tcp6File{fopen("/proc/net/tcp6", "r")};
|
|
||||||
if (tcp6File)
|
|
||||||
{
|
|
||||||
auto ipv6Sockets = ParseTcpFile(AF_INET6, tcp6File.get());
|
|
||||||
sockets.insert(sockets.end(), ipv6Sockets.begin(), ipv6Sockets.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tcp4File && !tcp6File)
|
|
||||||
{
|
|
||||||
LOG_ERROR("Failed to open /proc/net/tcp and /proc/net/tcp6, closing port relay");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop any relays that no longer match listening ports.
|
// Stop any relays that no longer match listening ports.
|
||||||
std::erase_if(relays, [&](const auto& entry) {
|
std::erase_if(relays, [&](const auto& entry) {
|
||||||
|
|
@ -386,9 +340,7 @@ int ScanProcNetTCP(wsl::shared::SocketChannel& channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep before scanning again.
|
// Sleep before scanning again.
|
||||||
//
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
// TODO: Investigate using EBPF notifications instead of a sleep.
|
|
||||||
sleep(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -432,7 +384,7 @@ try
|
||||||
|
|
||||||
if (ScanForPorts)
|
if (ScanForPorts)
|
||||||
{
|
{
|
||||||
return ScanProcNetTCP(channel);
|
return MonitorListeningSockets(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -2884,14 +2884,16 @@ Return Value:
|
||||||
std::string TranslatedPath = WslPathTranslate(Path, 0, Mode);
|
std::string TranslatedPath = WslPathTranslate(Path, 0, Mode);
|
||||||
if (TranslatedPath.empty())
|
if (TranslatedPath.empty())
|
||||||
{
|
{
|
||||||
|
auto WarningMessage = wsl::shared::Localization::MessageFailedToTranslate(Path);
|
||||||
if (wil::ScopedWarningsCollector::CanCollectWarning())
|
if (wil::ScopedWarningsCollector::CanCollectWarning())
|
||||||
{
|
{
|
||||||
EMIT_USER_WARNING(wsl::shared::Localization::MessageFailedToTranslate(Path));
|
EMIT_USER_WARNING(std::move(WarningMessage));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR("Failed to translate {}", Path);
|
LOG_WARNING("{}", WarningMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ Return Value:
|
||||||
auto translatedPath = WslPathTranslate(value.data(), TRANSLATE_FLAG_ABSOLUTE, TRANSLATE_MODE_UNIX);
|
auto translatedPath = WslPathTranslate(value.data(), TRANSLATE_FLAG_ABSOLUTE, TRANSLATE_MODE_UNIX);
|
||||||
if (translatedPath.empty())
|
if (translatedPath.empty())
|
||||||
{
|
{
|
||||||
std::cerr << Localization::MessageFailedToTranslatePath() << "\n";
|
std::cerr << Localization::MessageFailedToTranslate(value.data()) << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,6 @@ int ParseConfigFile(std::vector<ConfigKey>& keys, FILE* file, int flags, const w
|
||||||
{
|
{
|
||||||
wint_t ch = 0;
|
wint_t ch = 0;
|
||||||
unsigned long line = 0;
|
unsigned long line = 0;
|
||||||
size_t newKeyValueInsertPos = 0;
|
|
||||||
bool trailingComment = false;
|
bool trailingComment = false;
|
||||||
bool inQuote = false;
|
bool inQuote = false;
|
||||||
size_t trimmedLength = 0;
|
size_t trimmedLength = 0;
|
||||||
|
|
@ -328,8 +327,6 @@ NewLine:
|
||||||
|
|
||||||
if (trailingComment)
|
if (trailingComment)
|
||||||
{
|
{
|
||||||
// Subtract 1 to account for ch being '\n' or WEOF.
|
|
||||||
newKeyValueInsertPos = configFileOutput.length() - 1;
|
|
||||||
trailingComment = false;
|
trailingComment = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -390,6 +387,37 @@ NewLine:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
|
// We're about to parse a new section. If we have an unwritten key-value
|
||||||
|
// and the current section matches, write it now before moving to the new section.
|
||||||
|
if (updateConfigFile && !outputKeyValueUpdated && !removeKey && sectionLength > 0)
|
||||||
|
{
|
||||||
|
const auto& outputConfigKey = outputKey.value();
|
||||||
|
if (outputConfigKey.Matches(key.c_str(), sectionLength))
|
||||||
|
{
|
||||||
|
const auto& keyNames = outputConfigKey.GetNames();
|
||||||
|
// Config key without name.
|
||||||
|
FAIL_FAST_IF(keyNames.empty());
|
||||||
|
const auto keyNameUtf8 = keyNames.front();
|
||||||
|
const auto keyName = wsl::shared::string::MultiByteToWide(keyNameUtf8);
|
||||||
|
const auto sectionKeySeparatorPos = keyName.find('.');
|
||||||
|
// Config key without separated section/key name
|
||||||
|
FAIL_FAST_IF(sectionKeySeparatorPos == std::string_view::npos);
|
||||||
|
// Config key without section name
|
||||||
|
FAIL_FAST_IF(sectionKeySeparatorPos == 0);
|
||||||
|
// Config key without key name
|
||||||
|
FAIL_FAST_IF(sectionKeySeparatorPos == (keyName.length() - 1));
|
||||||
|
|
||||||
|
// Remove any trailing newlines before inserting the new key-value
|
||||||
|
while (!configFileOutput.empty() && configFileOutput.back() == L'\n')
|
||||||
|
{
|
||||||
|
configFileOutput.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto keyValue = std::format(L"\n{}={}\n\n", keyName.substr(sectionKeySeparatorPos + 1), outputKey.value().GetValue());
|
||||||
|
configFileOutput += keyValue;
|
||||||
|
outputKeyValueUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
goto ParseSection;
|
goto ParseSection;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -418,30 +446,6 @@ NewLine:
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseSection:
|
ParseSection:
|
||||||
if (updateConfigFile && !outputKeyValueUpdated && !removeKey && sectionLength > 0)
|
|
||||||
{
|
|
||||||
const auto& outputConfigKey = outputKey.value();
|
|
||||||
if (outputConfigKey.Matches(key.c_str(), sectionLength))
|
|
||||||
{
|
|
||||||
const auto& keyNames = outputConfigKey.GetNames();
|
|
||||||
// Config key without name.
|
|
||||||
FAIL_FAST_IF(keyNames.empty());
|
|
||||||
const auto keyNameUtf8 = keyNames.front();
|
|
||||||
const auto keyName = wsl::shared::string::MultiByteToWide(keyNameUtf8);
|
|
||||||
const auto sectionKeySeparatorPos = keyName.find('.');
|
|
||||||
// Config key without separated section/key name
|
|
||||||
FAIL_FAST_IF(sectionKeySeparatorPos == std::string_view::npos);
|
|
||||||
// Config key without section name
|
|
||||||
FAIL_FAST_IF(sectionKeySeparatorPos == 0);
|
|
||||||
// Config key without key name
|
|
||||||
FAIL_FAST_IF(sectionKeySeparatorPos == (keyName.length() - 1));
|
|
||||||
|
|
||||||
auto keyValue = std::format(L"\n{}={}", keyName.substr(sectionKeySeparatorPos + 1), outputKey.value().GetValue());
|
|
||||||
configFileOutput.insert(newKeyValueInsertPos, keyValue);
|
|
||||||
outputKeyValueUpdated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse [section] ([ is already parsed)
|
// parse [section] ([ is already parsed)
|
||||||
if (updateConfigFile)
|
if (updateConfigFile)
|
||||||
{
|
{
|
||||||
|
|
@ -796,7 +800,6 @@ ValueDone:
|
||||||
// Trim any trailing space.
|
// Trim any trailing space.
|
||||||
value.resize(trimmedLength);
|
value.resize(trimmedLength);
|
||||||
SetConfig(keys, key.c_str(), value.c_str(), flags & CFG_DEBUG, filePath, line);
|
SetConfig(keys, key.c_str(), value.c_str(), flags & CFG_DEBUG, filePath, line);
|
||||||
newKeyValueInsertPos = configFileOutput.length();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto NewLine;
|
goto NewLine;
|
||||||
|
|
|
||||||
|
|
@ -92,11 +92,6 @@ void SubProcess::SetFlags(DWORD Flag)
|
||||||
WI_SetAllFlags(m_flags, Flag);
|
WI_SetAllFlags(m_flags, Flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubProcess::SetDesktop(LPCWSTR Desktop)
|
|
||||||
{
|
|
||||||
m_desktop = Desktop;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SubProcess::SetToken(HANDLE Token)
|
void SubProcess::SetToken(HANDLE Token)
|
||||||
{
|
{
|
||||||
m_token = Token;
|
m_token = Token;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ public:
|
||||||
void InheritHandle(HANDLE Handle);
|
void InheritHandle(HANDLE Handle);
|
||||||
void SetEnvironment(LPVOID Environment);
|
void SetEnvironment(LPVOID Environment);
|
||||||
void SetWorkingDirectory(LPCWSTR Directory);
|
void SetWorkingDirectory(LPCWSTR Directory);
|
||||||
void SetDesktop(LPCWSTR Desktop);
|
|
||||||
void SetToken(HANDLE Token);
|
void SetToken(HANDLE Token);
|
||||||
void SetShowWindow(WORD Show);
|
void SetShowWindow(WORD Show);
|
||||||
void SetFlags(DWORD Flag);
|
void SetFlags(DWORD Flag);
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,6 @@ CreateProcessResult CreateProcess(_In_ CreateProcessParsed* Parsed, _In_ HANDLE
|
||||||
wsl::windows::common::helpers::SetHandleInheritable(StdErr);
|
wsl::windows::common::helpers::SetHandleInheritable(StdErr);
|
||||||
|
|
||||||
wsl::windows::common::SubProcess process(Parsed->ApplicationName.c_str(), Parsed->CommandLine(), CREATE_UNICODE_ENVIRONMENT);
|
wsl::windows::common::SubProcess process(Parsed->ApplicationName.c_str(), Parsed->CommandLine(), CREATE_UNICODE_ENVIRONMENT);
|
||||||
process.SetDesktop(L"winsta0\\default");
|
|
||||||
|
|
||||||
CreateProcessResult Result{};
|
CreateProcessResult Result{};
|
||||||
if (Parsed->CreatePseudoconsole)
|
if (Parsed->CreatePseudoconsole)
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ try
|
||||||
</binding>
|
</binding>
|
||||||
</visual>
|
</visual>
|
||||||
<actions>
|
<actions>
|
||||||
<action arguments='--{}' content='{}'/>
|
<action arguments='{}' content='{}'/>
|
||||||
<action arguments='--{}' content='{}'/>
|
<action arguments='{}' content='{}'/>
|
||||||
</actions>
|
</actions>
|
||||||
</toast>)",
|
</toast>)",
|
||||||
Localization::MessageNewWslVersionAvailable(Localization::Options::DontImpersonate),
|
Localization::MessageNewWslVersionAvailable(Localization::Options::DontImpersonate),
|
||||||
|
|
@ -118,8 +118,8 @@ try
|
||||||
</binding>
|
</binding>
|
||||||
</visual>
|
</visual>
|
||||||
<actions>
|
<actions>
|
||||||
<action arguments='--{} {}' content='{}'/>
|
<action arguments='{} {}' content='{}'/>
|
||||||
<action arguments='--{} {}' content="{}"/>
|
<action arguments='{} {}' content="{}"/>
|
||||||
</actions>
|
</actions>
|
||||||
</toast>)",
|
</toast>)",
|
||||||
Localization::MessagePerformanceTip(Localization::Options::DontImpersonate),
|
Localization::MessagePerformanceTip(Localization::Options::DontImpersonate),
|
||||||
|
|
@ -151,7 +151,7 @@ try
|
||||||
</binding>
|
</binding>
|
||||||
</visual>
|
</visual>
|
||||||
<actions>
|
<actions>
|
||||||
<action arguments='--{}' content='{}'/>
|
<action arguments='{}' content='{}'/>
|
||||||
</actions>
|
</actions>
|
||||||
</toast>)",
|
</toast>)",
|
||||||
Localization::MessageWarningDuringStartup(),
|
Localization::MessageWarningDuringStartup(),
|
||||||
|
|
@ -176,7 +176,7 @@ try
|
||||||
</binding>
|
</binding>
|
||||||
</visual>
|
</visual>
|
||||||
<actions>
|
<actions>
|
||||||
<action arguments='--{}' content='{}'/>
|
<action arguments='{}' content='{}'/>
|
||||||
</actions>
|
</actions>
|
||||||
</toast>)",
|
</toast>)",
|
||||||
Localization::MessageMissingOptionalComponents(),
|
Localization::MessageMissingOptionalComponents(),
|
||||||
|
|
|
||||||
|
|
@ -33,5 +33,5 @@ LPCWSTR const handle_option = L"--handle";
|
||||||
LPCWSTR const event_option = L"--event";
|
LPCWSTR const event_option = L"--event";
|
||||||
LPCWSTR const parent_option = L"--parent";
|
LPCWSTR const parent_option = L"--parent";
|
||||||
LPCWSTR const vm_id_option = L"--vm-id";
|
LPCWSTR const vm_id_option = L"--vm-id";
|
||||||
LPCWSTR const embedding_option = L"--Embedding";
|
LPCWSTR const embedding_option = L"-Embedding";
|
||||||
} // namespace wslhost
|
} // namespace wslhost
|
||||||
|
|
@ -2172,13 +2172,22 @@ HRESULT LxssUserSessionImpl::Shutdown(_In_ bool PreventNewInstances, ShutdownBeh
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LxssUserSessionImpl::TelemetryWorker(_In_ wil::unique_socket&& socket, _In_ bool drvFsNotifications) const
|
void LxssUserSessionImpl::TelemetryWorker(_In_ wil::unique_socket&& socket) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wsl::windows::common::wslutil::SetThreadDescription(L"Telemetry");
|
wsl::windows::common::wslutil::SetThreadDescription(L"Telemetry");
|
||||||
|
|
||||||
wsl::shared::SocketChannel channel(std::move(socket), "Telemetry", m_vmTerminating.get());
|
wsl::shared::SocketChannel channel(std::move(socket), "Telemetry", m_vmTerminating.get());
|
||||||
|
|
||||||
|
// Check if drvfs notifications are enabled for the user.
|
||||||
|
bool drvFsNotifications{};
|
||||||
|
{
|
||||||
|
auto impersonate = wil::impersonate_token(m_userToken.get());
|
||||||
|
const auto lxssKey = wsl::windows::common::registry::OpenLxssUserKey();
|
||||||
|
drvFsNotifications =
|
||||||
|
wsl::windows::common::registry::ReadDword(lxssKey.get(), LXSS_NOTIFICATIONS_KEY, LXSS_NOTIFICATION_DRVFS_PERF_DISABLED, 0) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Aggregate information about what is running inside the VM. This is logged
|
// Aggregate information about what is running inside the VM. This is logged
|
||||||
// periodically because logging each event individually would be too noisy.
|
// periodically because logging each event individually would be too noisy.
|
||||||
for (;;)
|
for (;;)
|
||||||
|
|
@ -2852,17 +2861,9 @@ void LxssUserSessionImpl::_CreateVm()
|
||||||
// If the telemetry is enabled, launch the telemetry agent inside the VM.
|
// If the telemetry is enabled, launch the telemetry agent inside the VM.
|
||||||
if (m_utilityVm->GetConfig().EnableTelemetry && TraceLoggingProviderEnabled(g_hTraceLoggingProvider, WINEVENT_LEVEL_INFO, 0))
|
if (m_utilityVm->GetConfig().EnableTelemetry && TraceLoggingProviderEnabled(g_hTraceLoggingProvider, WINEVENT_LEVEL_INFO, 0))
|
||||||
{
|
{
|
||||||
bool drvFsNotifications = false;
|
|
||||||
{
|
|
||||||
auto impersonate = wil::impersonate_token(m_userToken.get());
|
|
||||||
const auto lxssKey = wsl::windows::common::registry::OpenLxssUserKey();
|
|
||||||
drvFsNotifications = wsl::windows::common::registry::ReadDword(
|
|
||||||
lxssKey.get(), LXSS_NOTIFICATIONS_KEY, LXSS_NOTIFICATION_DRVFS_PERF_DISABLED, 0) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPCSTR Arguments[] = {LX_INIT_TELEMETRY_AGENT, nullptr};
|
LPCSTR Arguments[] = {LX_INIT_TELEMETRY_AGENT, nullptr};
|
||||||
auto socket = m_utilityVm->CreateRootNamespaceProcess(LX_INIT_PATH, Arguments);
|
auto socket = m_utilityVm->CreateRootNamespaceProcess(LX_INIT_PATH, Arguments);
|
||||||
m_telemetryThread = std::thread(&LxssUserSessionImpl::TelemetryWorker, this, std::move(socket), drvFsNotifications);
|
m_telemetryThread = std::thread(&LxssUserSessionImpl::TelemetryWorker, this, std::move(socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pluginManager.OnVmStarted(&m_session, &userSettings);
|
m_pluginManager.OnVmStarted(&m_session, &userSettings);
|
||||||
|
|
|
||||||
|
|
@ -503,7 +503,7 @@ public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Worker thread for logging telemetry about processes running inside of WSL.
|
/// Worker thread for logging telemetry about processes running inside of WSL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void TelemetryWorker(_In_ wil::unique_socket&& socket, _In_ bool drvFsNotifications) const;
|
void TelemetryWorker(_In_ wil::unique_socket&& socket) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Terminates a distribution by it's client identifier.
|
/// Terminates a distribution by it's client identifier.
|
||||||
|
|
|
||||||
|
|
@ -1793,8 +1793,10 @@ void WslCoreVm::InitializeGuest()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_guestDeviceManager->AddSharedMemoryDevice(
|
// Use the appropriate virtiofs class ID based on m_userToken elevation.
|
||||||
VIRTIO_FS_CLASS_ID, L"wslg", L"wslg", WSLG_SHARED_MEMORY_SIZE_MB, m_userToken.get());
|
const bool admin = wsl::windows::common::security::IsTokenElevated(m_userToken.get());
|
||||||
|
const GUID classId = admin ? VIRTIO_FS_ADMIN_CLASS_ID : VIRTIO_FS_CLASS_ID;
|
||||||
|
m_guestDeviceManager->AddSharedMemoryDevice(classId, L"wslg", L"wslg", WSLG_SHARED_MEMORY_SIZE_MB, m_userToken.get());
|
||||||
m_sharedMemoryRoot = std::format(L"WSL\\{}\\wslg", m_machineId);
|
m_sharedMemoryRoot = std::format(L"WSL\\{}\\wslg", m_machineId);
|
||||||
}
|
}
|
||||||
CATCH_LOG()
|
CATCH_LOG()
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,7 @@ public:
|
||||||
// Log telemetry when a WSL notification is activated, used to determine user engagement for notifications
|
// Log telemetry when a WSL notification is activated, used to determine user engagement for notifications
|
||||||
WSL_LOG_TELEMETRY("NotificationActivate", PDT_ProductAndServicePerformance, TraceLoggingValue(invokedArgs, "Arguments"));
|
WSL_LOG_TELEMETRY("NotificationActivate", PDT_ProductAndServicePerformance, TraceLoggingValue(invokedArgs, "Arguments"));
|
||||||
|
|
||||||
// Prepend the executable name to the arguments so getopt can be used to parse the arguments.
|
ArgumentParser parser(invokedArgs, wslhost::binary_name, 0);
|
||||||
auto commandLine = wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle());
|
|
||||||
commandLine += L" ";
|
|
||||||
commandLine += invokedArgs;
|
|
||||||
|
|
||||||
ArgumentParser parser(GetCommandLineW(), wslhost::binary_name);
|
|
||||||
parser.AddArgument(
|
parser.AddArgument(
|
||||||
[]() {
|
[]() {
|
||||||
std::wstring path;
|
std::wstring path;
|
||||||
|
|
|
||||||
|
|
@ -461,7 +461,7 @@ extern "C" UINT __stdcall CleanMsixState(MSIHANDLE install)
|
||||||
const std::map<LPCWSTR, LPCWSTR> keys{
|
const std::map<LPCWSTR, LPCWSTR> keys{
|
||||||
{L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application", L"WSL"},
|
{L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application", L"WSL"},
|
||||||
{L"SOFTWARE\\Classes\\CLSID", L"{7e6ad219-d1b3-42d5-b8ee-d96324e64ff6}"},
|
{L"SOFTWARE\\Classes\\CLSID", L"{7e6ad219-d1b3-42d5-b8ee-d96324e64ff6}"},
|
||||||
{L"SOFTWARE\\Classes\\AppID", L"{7F82AD86-755B-4870-86B1-D2E68DFE8A49}"},
|
{L"SOFTWARE\\Classes\\AppID", L"{17696EAC-9568-4CF5-BB8C-82515AAD6C09}"},
|
||||||
{L"SOFTWARE\\Microsoft\\Terminal Server Client", L"Default"},
|
{L"SOFTWARE\\Microsoft\\Terminal Server Client", L"Default"},
|
||||||
{L"SOFTWARE\\Microsoft\\Terminal Server Client\\Default", L"OptionalAddIns"},
|
{L"SOFTWARE\\Microsoft\\Terminal Server Client\\Default", L"OptionalAddIns"},
|
||||||
{L"SOFTWARE\\Microsoft\\Terminal Server Client\\Default\\OptionalAddIns", L"WSLDVC_PACKAGE"}};
|
{L"SOFTWARE\\Microsoft\\Terminal Server Client\\Default\\OptionalAddIns", L"WSLDVC_PACKAGE"}};
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,13 @@ Return Value:
|
||||||
LxtCheckResult(LxtCheckWslPathTranslation("C:/Foo/bar", "/mnt/c/Foo/bar", true));
|
LxtCheckResult(LxtCheckWslPathTranslation("C:/Foo/bar", "/mnt/c/Foo/bar", true));
|
||||||
LxtCheckResult(LxtCheckWslPathTranslation("foo", "foo", true));
|
LxtCheckResult(LxtCheckWslPathTranslation("foo", "foo", true));
|
||||||
LxtCheckResult(LxtCheckWslPathTranslation("foo\\", "foo/", true));
|
LxtCheckResult(LxtCheckWslPathTranslation("foo\\", "foo/", true));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation("C:\\Program Files\\Git", "/mnt/c/Program Files/Git", true));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation("C:\\Program Files\\PowerShell\\7", "/mnt/c/Program Files/PowerShell/7", true));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation("C:\\Program Files (x86)\\Common Files", "/mnt/c/Program Files (x86)/Common Files", true));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation(
|
||||||
|
"C:\\Users\\Test User\\AppData\\Local\\Programs\\Microsoft VS Code\\bin",
|
||||||
|
"/mnt/c/Users/Test User/AppData/Local/Programs/Microsoft VS Code/bin",
|
||||||
|
true));
|
||||||
|
|
||||||
ErrorExit:
|
ErrorExit:
|
||||||
return Result;
|
return Result;
|
||||||
|
|
@ -241,6 +248,13 @@ Return Value:
|
||||||
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/Users", "C:\\Users", false));
|
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/Users", "C:\\Users", false));
|
||||||
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/Users/", "C:\\Users\\", false));
|
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/Users/", "C:\\Users\\", false));
|
||||||
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/DOESNOTEXIST/", "C:\\DOESNOTEXIST\\", false));
|
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/DOESNOTEXIST/", "C:\\DOESNOTEXIST\\", false));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/Program Files/Git", "C:\\Program Files\\Git", false));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/Program Files/PowerShell/7", "C:\\Program Files\\PowerShell\\7", false));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation("/mnt/c/Program Files (x86)/Common Files", "C:\\Program Files (x86)\\Common Files", false));
|
||||||
|
LxtCheckResult(LxtCheckWslPathTranslation(
|
||||||
|
"/mnt/c/Users/Test User/AppData/Local/Programs/Microsoft VS Code/bin",
|
||||||
|
"C:\\Users\\Test User\\AppData\\Local\\Programs\\Microsoft VS Code\\bin",
|
||||||
|
false));
|
||||||
|
|
||||||
ErrorExit:
|
ErrorExit:
|
||||||
return Result;
|
return Result;
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ public:
|
||||||
SKIP_TEST_ARM64();
|
SKIP_TEST_ARM64();
|
||||||
|
|
||||||
TerminateDistribution();
|
TerminateDistribution();
|
||||||
WslKeepAlive keelAlive;
|
WslKeepAlive keepAlive;
|
||||||
|
|
||||||
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT, Mode);
|
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT, Mode);
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +288,7 @@ public:
|
||||||
SKIP_TEST_ARM64();
|
SKIP_TEST_ARM64();
|
||||||
|
|
||||||
TerminateDistribution();
|
TerminateDistribution();
|
||||||
WslKeepAlive keelAlive;
|
WslKeepAlive keepAlive;
|
||||||
|
|
||||||
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, Mode);
|
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, Mode);
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +302,7 @@ public:
|
||||||
TerminateDistribution();
|
TerminateDistribution();
|
||||||
|
|
||||||
const auto nonElevatedToken = GetNonElevatedToken();
|
const auto nonElevatedToken = GetNonElevatedToken();
|
||||||
WslKeepAlive keelAlive(nonElevatedToken.get());
|
WslKeepAlive keepAlive(nonElevatedToken.get());
|
||||||
|
|
||||||
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT, Mode);
|
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT, Mode);
|
||||||
}
|
}
|
||||||
|
|
@ -316,11 +316,37 @@ public:
|
||||||
TerminateDistribution();
|
TerminateDistribution();
|
||||||
|
|
||||||
const auto nonElevatedToken = GetNonElevatedToken();
|
const auto nonElevatedToken = GetNonElevatedToken();
|
||||||
WslKeepAlive keelAlive(nonElevatedToken.get());
|
WslKeepAlive keepAlive(nonElevatedToken.get());
|
||||||
|
|
||||||
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, Mode);
|
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DrvfsMountElevatedSystemDistroEnabled(DrvFsMode Mode)
|
||||||
|
{
|
||||||
|
WSL2_TEST_ONLY();
|
||||||
|
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
|
||||||
|
SKIP_TEST_ARM64();
|
||||||
|
|
||||||
|
WslConfigChange config(LxssGenerateTestConfig({.guiApplications = true, .drvFsMode = Mode}));
|
||||||
|
WslKeepAlive keepAlive;
|
||||||
|
|
||||||
|
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT, Mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrvfsMountNonElevatedSystemDistroEnabled(DrvFsMode Mode)
|
||||||
|
{
|
||||||
|
WSL2_TEST_ONLY();
|
||||||
|
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
|
||||||
|
SKIP_TEST_ARM64();
|
||||||
|
|
||||||
|
WslConfigChange config(LxssGenerateTestConfig({.guiApplications = true, .drvFsMode = Mode}));
|
||||||
|
|
||||||
|
const auto nonElevatedToken = GetNonElevatedToken();
|
||||||
|
WslKeepAlive keepAlive(nonElevatedToken.get());
|
||||||
|
|
||||||
|
ValidateDrvfsMounts(CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT, Mode);
|
||||||
|
}
|
||||||
|
|
||||||
static void XattrDrvFs(DrvFsMode Mode)
|
static void XattrDrvFs(DrvFsMode Mode)
|
||||||
{
|
{
|
||||||
SKIP_TEST_ARM64();
|
SKIP_TEST_ARM64();
|
||||||
|
|
@ -946,6 +972,31 @@ private:
|
||||||
|
|
||||||
const auto nonElevatedToken = GetNonElevatedToken();
|
const auto nonElevatedToken = GetNonElevatedToken();
|
||||||
validate(nonElevatedType, nonElevatedToken.get());
|
validate(nonElevatedType, nonElevatedToken.get());
|
||||||
|
|
||||||
|
// Elevated token should be able to create files at the root of the drive (/mnt/c)
|
||||||
|
{
|
||||||
|
const auto commandLine =
|
||||||
|
LxssGenerateWslCommandLine(L"touch /mnt/c/elevated_test_file.tmp && rm /mnt/c/elevated_test_file.tmp");
|
||||||
|
|
||||||
|
wsl::windows::common::SubProcess process(nullptr, commandLine.c_str(), CreateProcessFlags);
|
||||||
|
process.SetToken(nullptr);
|
||||||
|
process.SetShowWindow(SW_HIDE);
|
||||||
|
|
||||||
|
const auto output = process.RunAndCaptureOutput();
|
||||||
|
VERIFY_ARE_EQUAL(0, output.ExitCode, L"Elevated token should be able to create files at /mnt/c");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-elevated token should NOT be able to create files at the root of the drive (/mnt/c)
|
||||||
|
{
|
||||||
|
const auto commandLine = LxssGenerateWslCommandLine(L"touch /mnt/c/nonelevated_test_file.tmp");
|
||||||
|
|
||||||
|
wsl::windows::common::SubProcess process(nullptr, commandLine.c_str(), CreateProcessFlags);
|
||||||
|
process.SetToken(nonElevatedToken.get());
|
||||||
|
process.SetShowWindow(SW_HIDE);
|
||||||
|
|
||||||
|
const auto output = process.RunAndCaptureOutput();
|
||||||
|
VERIFY_ARE_NOT_EQUAL(0, output.ExitCode, L"Non-elevated token should NOT be able to create files at /mnt/c (C:\\)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID VerifyDrvFsSymlink(const std::wstring& Path, const std::wstring& ExpectedTarget, bool Directory)
|
static VOID VerifyDrvFsSymlink(const std::wstring& Path, const std::wstring& ExpectedTarget, bool Directory)
|
||||||
|
|
@ -1198,6 +1249,18 @@ class WSL1 : public DrvFsTests
|
||||||
WSL2_TEST_ONLY(); \
|
WSL2_TEST_ONLY(); \
|
||||||
DrvFsTests::DrvfsMountNonElevatedDifferentConsole(DrvFsMode::##_mode##); \
|
DrvFsTests::DrvfsMountNonElevatedDifferentConsole(DrvFsMode::##_mode##); \
|
||||||
} \
|
} \
|
||||||
|
\
|
||||||
|
TEST_METHOD(DrvfsMountElevatedSystemDistroEnabled) \
|
||||||
|
{ \
|
||||||
|
WSL2_TEST_ONLY(); \
|
||||||
|
DrvFsTests::DrvfsMountElevatedSystemDistroEnabled(DrvFsMode::##_mode##); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
TEST_METHOD(DrvfsMountNonElevatedSystemDistroEnabled) \
|
||||||
|
{ \
|
||||||
|
WSL2_TEST_ONLY(); \
|
||||||
|
DrvFsTests::DrvfsMountNonElevatedSystemDistroEnabled(DrvFsMode::##_mode##); \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
TEST_METHOD(XattrDrvFs) \
|
TEST_METHOD(XattrDrvFs) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,7 @@ class NetworkTests
|
||||||
WSL_TEST_CLASS(NetworkTests)
|
WSL_TEST_CLASS(NetworkTests)
|
||||||
|
|
||||||
friend class MirroredTests;
|
friend class MirroredTests;
|
||||||
|
friend class BridgedTests;
|
||||||
friend class VirtioProxyTests;
|
friend class VirtioProxyTests;
|
||||||
|
|
||||||
static std::wstring SockaddrToString(const SOCKADDR_INET* sockAddr)
|
static std::wstring SockaddrToString(const SOCKADDR_INET* sockAddr)
|
||||||
|
|
@ -790,6 +791,51 @@ class NetworkTests
|
||||||
VERIFY_IS_TRUE(!out.empty());
|
VERIFY_IS_TRUE(!out.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void VerifyDnsResolutionBasic()
|
||||||
|
{
|
||||||
|
// Verify basic DNS resolution using getent
|
||||||
|
auto [out, _] = LxsstuLaunchWslAndCaptureOutput(L"getent ahosts bing.com", 0);
|
||||||
|
VERIFY_IS_TRUE(!out.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VerifyDnsResolutionDig()
|
||||||
|
{
|
||||||
|
if (HostHasInternetConnectivity(AF_INET))
|
||||||
|
{
|
||||||
|
// Test A record resolution (IPv4) with both UDP and TCP
|
||||||
|
VerifyDigDnsResolution(L"dig +short +time=5 A bing.com");
|
||||||
|
VerifyDigDnsResolution(L"dig +tcp +short +time=5 A bing.com");
|
||||||
|
|
||||||
|
// Test reverse DNS lookup
|
||||||
|
VerifyDigDnsResolution(L"dig +short +time=5 -x 8.8.8.8");
|
||||||
|
VerifyDigDnsResolution(L"dig +tcp +short +time=5 -x 8.8.8.8");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogSkipped("Host does not have IPv4 internet connectivity. Skipping IPv4 DNS tests.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HostHasInternetConnectivity(AF_INET6))
|
||||||
|
{
|
||||||
|
// Test AAAA record resolution (IPv6) with both UDP and TCP
|
||||||
|
VerifyDigDnsResolution(L"dig +short +time=5 AAAA bing.com");
|
||||||
|
VerifyDigDnsResolution(L"dig +tcp +short +time=5 AAAA bing.com");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogSkipped("Host does not have IPv6 internet connectivity. Skipping IPv6 DNS tests.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VerifyDnsResolutionRecordTypes()
|
||||||
|
{
|
||||||
|
// Test various DNS record types
|
||||||
|
VerifyDigDnsResolution(L"dig +short +time=5 MX bing.com");
|
||||||
|
VerifyDigDnsResolution(L"dig +short +time=5 NS bing.com");
|
||||||
|
VerifyDigDnsResolution(L"dig +short +time=5 TXT bing.com");
|
||||||
|
VerifyDigDnsResolution(L"dig +short +time=5 SOA bing.com");
|
||||||
|
}
|
||||||
|
|
||||||
static void VerifyDnsQueries()
|
static void VerifyDnsQueries()
|
||||||
{
|
{
|
||||||
// query for A/IPv4 records
|
// query for A/IPv4 records
|
||||||
|
|
@ -1006,6 +1052,27 @@ class NetworkTests
|
||||||
VERIFY_ARE_EQUAL(expected, out.c_str());
|
VERIFY_ARE_EQUAL(expected, out.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionBasic)
|
||||||
|
{
|
||||||
|
WSL2_TEST_ONLY();
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionBasic();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionDig)
|
||||||
|
{
|
||||||
|
WSL2_TEST_ONLY();
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionDig();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionRecordTypes)
|
||||||
|
{
|
||||||
|
WSL2_TEST_ONLY();
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionRecordTypes();
|
||||||
|
}
|
||||||
|
|
||||||
static void ClearHttpProxySettings(bool userScope)
|
static void ClearHttpProxySettings(bool userScope)
|
||||||
{
|
{
|
||||||
auto command = L"Set-WinhttpProxy -SettingScope Machine -Proxy \\\"\\\"";
|
auto command = L"Set-WinhttpProxy -SettingScope Machine -Proxy \\\"\\\"";
|
||||||
|
|
@ -2095,20 +2162,23 @@ class NetworkTests
|
||||||
VerifyNotBoundLoopback(port, false);
|
VerifyNotBoundLoopback(port, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ValidateLocalhostRelayTraffic(bool ipv6)
|
static void ValidateLocalhostRelayTraffic(ADDRESS_FAMILY addressFamily)
|
||||||
{
|
{
|
||||||
|
THROW_HR_IF(E_INVALIDARG, addressFamily != AF_INET && addressFamily != AF_INET6);
|
||||||
|
|
||||||
// Bind a port in the guest.
|
// Bind a port in the guest.
|
||||||
auto [guestProcess, read] = BindGuestPort(ipv6 ? L"TCP6-LISTEN:1234,bind=::1" : L"TCP4-LISTEN:1234,bind=127.0.0.1", true);
|
auto [guestProcess, read] =
|
||||||
|
BindGuestPort(addressFamily == AF_INET6 ? L"TCP6-LISTEN:1234,bind=::1" : L"TCP4-LISTEN:1234,bind=127.0.0.1", true);
|
||||||
|
|
||||||
// Connect to the port via the localhost relay
|
// Connect to the port via the localhost relay
|
||||||
wil::unique_socket hostSocket;
|
wil::unique_socket hostSocket;
|
||||||
SOCKADDR_INET addr{};
|
SOCKADDR_INET addr{};
|
||||||
addr.si_family = ipv6 ? AF_INET6 : AF_INET;
|
addr.si_family = addressFamily;
|
||||||
INETADDR_SETLOOPBACK((PSOCKADDR)&addr);
|
INETADDR_SETLOOPBACK((PSOCKADDR)&addr);
|
||||||
SS_PORT(&addr) = htons(1234);
|
SS_PORT(&addr) = htons(1234);
|
||||||
|
|
||||||
auto pred = [&]() {
|
auto pred = [&]() {
|
||||||
hostSocket.reset(socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
hostSocket.reset(socket(addressFamily, SOCK_STREAM, IPPROTO_TCP));
|
||||||
THROW_HR_IF(E_ABORT, !hostSocket);
|
THROW_HR_IF(E_ABORT, !hostSocket);
|
||||||
THROW_HR_IF(E_FAIL, connect(hostSocket.get(), reinterpret_cast<SOCKADDR*>(&addr), sizeof(addr)) == SOCKET_ERROR);
|
THROW_HR_IF(E_FAIL, connect(hostSocket.get(), reinterpret_cast<SOCKADDR*>(&addr), sizeof(addr)) == SOCKET_ERROR);
|
||||||
};
|
};
|
||||||
|
|
@ -2149,8 +2219,8 @@ class NetworkTests
|
||||||
WSL2_TEST_ONLY();
|
WSL2_TEST_ONLY();
|
||||||
WslKeepAlive keepAlive;
|
WslKeepAlive keepAlive;
|
||||||
|
|
||||||
ValidateLocalhostRelayTraffic(false);
|
ValidateLocalhostRelayTraffic(AF_INET);
|
||||||
ValidateLocalhostRelayTraffic(true);
|
ValidateLocalhostRelayTraffic(AF_INET6);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(NatLocalhostRelayNoIpv6)
|
TEST_METHOD(NatLocalhostRelayNoIpv6)
|
||||||
|
|
@ -2161,7 +2231,7 @@ class NetworkTests
|
||||||
WslKeepAlive keepAlive;
|
WslKeepAlive keepAlive;
|
||||||
|
|
||||||
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"test -f /proc/net/tcp6"), 1L);
|
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"test -f /proc/net/tcp6"), 1L);
|
||||||
ValidateLocalhostRelayTraffic(false);
|
ValidateLocalhostRelayTraffic(AF_INET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TestNonRootNamespaceEphemeralBind()
|
static void TestNonRootNamespaceEphemeralBind()
|
||||||
|
|
@ -4299,6 +4369,36 @@ class MirroredTests
|
||||||
|
|
||||||
VERIFY_IS_FALSE(Watchdog.IsExpired());
|
VERIFY_IS_FALSE(Watchdog.IsExpired());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionBasic)
|
||||||
|
{
|
||||||
|
MIRRORED_NETWORKING_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::Mirrored}));
|
||||||
|
WaitForMirroredStateInLinux();
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionBasic();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionDig)
|
||||||
|
{
|
||||||
|
MIRRORED_NETWORKING_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::Mirrored}));
|
||||||
|
WaitForMirroredStateInLinux();
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionDig();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionRecordTypes)
|
||||||
|
{
|
||||||
|
MIRRORED_NETWORKING_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::Mirrored}));
|
||||||
|
WaitForMirroredStateInLinux();
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionRecordTypes();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BridgedTests
|
class BridgedTests
|
||||||
|
|
@ -4413,6 +4513,8 @@ class VirtioProxyTests
|
||||||
{
|
{
|
||||||
VIRTIOPROXY_TEST_ONLY();
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
// Verify that we have a working connection
|
// Verify that we have a working connection
|
||||||
NetworkTests::GuestClient(L"tcp-connect:bing.com:80");
|
NetworkTests::GuestClient(L"tcp-connect:bing.com:80");
|
||||||
}
|
}
|
||||||
|
|
@ -4421,6 +4523,8 @@ class VirtioProxyTests
|
||||||
{
|
{
|
||||||
VIRTIOPROXY_TEST_ONLY();
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
if (!NetworkTests::HostHasInternetConnectivity(AF_INET))
|
if (!NetworkTests::HostHasInternetConnectivity(AF_INET))
|
||||||
{
|
{
|
||||||
LogSkipped("Host does not have IPv4 internet connectivity. Skipping...");
|
LogSkipped("Host does not have IPv4 internet connectivity. Skipping...");
|
||||||
|
|
@ -4434,6 +4538,8 @@ class VirtioProxyTests
|
||||||
{
|
{
|
||||||
VIRTIOPROXY_TEST_ONLY();
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
if (!NetworkTests::HostHasInternetConnectivity(AF_INET6))
|
if (!NetworkTests::HostHasInternetConnectivity(AF_INET6))
|
||||||
{
|
{
|
||||||
LogSkipped("Host does not have IPv6 internet connectivity. Skipping...");
|
LogSkipped("Host does not have IPv6 internet connectivity. Skipping...");
|
||||||
|
|
@ -4447,6 +4553,8 @@ class VirtioProxyTests
|
||||||
{
|
{
|
||||||
VIRTIOPROXY_TEST_ONLY();
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
const auto state = NetworkTests::GetInterfaceState(L"eth0");
|
const auto state = NetworkTests::GetInterfaceState(L"eth0");
|
||||||
VERIFY_IS_FALSE(state.V4Addresses.empty());
|
VERIFY_IS_FALSE(state.V4Addresses.empty());
|
||||||
VERIFY_IS_TRUE(state.Gateway.has_value());
|
VERIFY_IS_TRUE(state.Gateway.has_value());
|
||||||
|
|
@ -4461,6 +4569,8 @@ class VirtioProxyTests
|
||||||
{
|
{
|
||||||
VIRTIOPROXY_TEST_ONLY();
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
// Make sure the VM doesn't time out
|
// Make sure the VM doesn't time out
|
||||||
WslKeepAlive keepAlive;
|
WslKeepAlive keepAlive;
|
||||||
|
|
||||||
|
|
@ -4488,6 +4598,67 @@ class VirtioProxyTests
|
||||||
VERIFY_IS_TRUE(bound);
|
VERIFY_IS_TRUE(bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(LoopbackGuestToHost)
|
||||||
|
{
|
||||||
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
|
// Verify guest can connect to host on loopback (TCP only, UDP not supported)
|
||||||
|
NetworkTests::VerifyLoopbackGuestToHost(L"127.0.0.1", IPPROTO_TCP);
|
||||||
|
NetworkTests::VerifyLoopbackGuestToHost(L"0.0.0.0", IPPROTO_TCP);
|
||||||
|
// TODO: enable when v6 loopback is supported
|
||||||
|
// NetworkTests::VerifyLoopbackGuestToHost(L"::1", IPPROTO_TCP);
|
||||||
|
// NetworkTests::VerifyLoopbackGuestToHost(L"::", IPPROTO_TCP);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(UdpBindDoesNotPreventTcpBind)
|
||||||
|
{
|
||||||
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
|
auto tcpPort = NetworkTests::BindGuestPort(L"TCP4-LISTEN:1234", true);
|
||||||
|
auto udpPort = NetworkTests::BindGuestPort(L"UDP4-LISTEN:1234", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(HostUdpBindDoesNotPreventGuestTcpBind)
|
||||||
|
{
|
||||||
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
|
auto udpPort = NetworkTests::BindHostPort(2345, SOCK_DGRAM, IPPROTO_UDP, true);
|
||||||
|
auto tcpPort = NetworkTests::BindGuestPort(L"TCP4-LISTEN:2345", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionBasic)
|
||||||
|
{
|
||||||
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionBasic();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionDig)
|
||||||
|
{
|
||||||
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionDig();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(DnsResolutionRecordTypes)
|
||||||
|
{
|
||||||
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
||||||
|
m_config->Update(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
|
||||||
|
|
||||||
|
NetworkTests::VerifyDnsResolutionRecordTypes();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_METHOD(HttpProxySimple)
|
TEST_METHOD(HttpProxySimple)
|
||||||
{
|
{
|
||||||
VIRTIOPROXY_TEST_ONLY();
|
VIRTIOPROXY_TEST_ONLY();
|
||||||
|
|
|
||||||
|
|
@ -262,5 +262,39 @@ class SimpleTests
|
||||||
std::transform(upperCaseGuidStringWide.begin(), upperCaseGuidStringWide.end(), upperCaseGuidStringWide.begin(), toupper);
|
std::transform(upperCaseGuidStringWide.begin(), upperCaseGuidStringWide.end(), upperCaseGuidStringWide.begin(), toupper);
|
||||||
VERIFY_ARE_EQUAL(upperCaseGuidStringWide, wsl::shared::string::GuidToString<wchar_t>(guid, wsl::shared::string::GuidToStringFlags::Uppercase));
|
VERIFY_ARE_EQUAL(upperCaseGuidStringWide, wsl::shared::string::GuidToString<wchar_t>(guid, wsl::shared::string::GuidToStringFlags::Uppercase));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(WindowsPathWithSpaces)
|
||||||
|
{
|
||||||
|
wil::unique_environstrings_ptr originalPath;
|
||||||
|
const DWORD pathLength = GetEnvironmentVariableW(L"PATH", nullptr, 0);
|
||||||
|
if (pathLength > 0)
|
||||||
|
{
|
||||||
|
originalPath.reset(static_cast<PWSTR>(HeapAlloc(GetProcessHeap(), 0, pathLength * sizeof(wchar_t))));
|
||||||
|
THROW_LAST_ERROR_IF_NULL(originalPath.get());
|
||||||
|
THROW_LAST_ERROR_IF(GetEnvironmentVariableW(L"PATH", originalPath.get(), pathLength) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cleanup = wil::scope_exit([&]() {
|
||||||
|
if (originalPath)
|
||||||
|
{
|
||||||
|
THROW_LAST_ERROR_IF(!SetEnvironmentVariableW(L"PATH", originalPath.get()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const wchar_t* testPath =
|
||||||
|
L"C:\\Program Files\\Git\\cmd;"
|
||||||
|
L"C:\\Program Files\\PowerShell\\7;"
|
||||||
|
L"C:\\Program Files (x86)\\Common Files;"
|
||||||
|
L"C:\\Users\\Test User\\AppData\\Local\\Programs\\Microsoft VS Code\\bin";
|
||||||
|
|
||||||
|
THROW_LAST_ERROR_IF(!SetEnvironmentVariableW(L"PATH", testPath));
|
||||||
|
|
||||||
|
auto [output, _] = LxsstuLaunchWslAndCaptureOutput(L"echo $PATH");
|
||||||
|
|
||||||
|
VERIFY_IS_TRUE(output.find(L"/mnt/c/Program Files/Git/cmd") != std::wstring::npos);
|
||||||
|
VERIFY_IS_TRUE(output.find(L"/mnt/c/Program Files/PowerShell/7") != std::wstring::npos);
|
||||||
|
VERIFY_IS_TRUE(output.find(L"/mnt/c/Program Files (x86)/Common Files") != std::wstring::npos);
|
||||||
|
VERIFY_IS_TRUE(output.find(L"/mnt/c/Users/Test User/AppData/Local/Programs/Microsoft VS Code/bin") != std::wstring::npos);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace SimpleTests
|
} // namespace SimpleTests
|
||||||
|
|
@ -268,8 +268,12 @@ class UnitTests
|
||||||
{
|
{
|
||||||
validateUserSession();
|
validateUserSession();
|
||||||
|
|
||||||
auto [out, err] = LxsstuLaunchWslAndCaptureOutput(std::format(L"echo $DISPLAY", LXSST_TEST_USERNAME));
|
auto [out, err] = LxsstuLaunchWslAndCaptureOutput(std::format(L"--user {} echo $DISPLAY", LXSST_TEST_USERNAME));
|
||||||
VERIFY_ARE_EQUAL(out, L"\n");
|
VERIFY_ARE_EQUAL(out, L"\n");
|
||||||
|
|
||||||
|
// N.B. The XDG_RUNTIME_DIR variable is always set by init even if gui apps are disabled.
|
||||||
|
std::tie(out, err) = LxsstuLaunchWslAndCaptureOutput(std::format(L"--user {} echo $XDG_RUNTIME_DIR", LXSST_TEST_USERNAME));
|
||||||
|
VERIFY_ARE_EQUAL(out, std::format(L"/run/user/{}\n", TestUid));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate user sessions state with gui apps enabled.
|
// Validate user sessions state with gui apps enabled.
|
||||||
|
|
@ -277,8 +281,11 @@ class UnitTests
|
||||||
WslConfigChange config(LxssGenerateTestConfig({.guiApplications = true}));
|
WslConfigChange config(LxssGenerateTestConfig({.guiApplications = true}));
|
||||||
|
|
||||||
validateUserSession();
|
validateUserSession();
|
||||||
auto [out, err] = LxsstuLaunchWslAndCaptureOutput(std::format(L"echo $DISPLAY", LXSST_TEST_USERNAME));
|
auto [out, err] = LxsstuLaunchWslAndCaptureOutput(std::format(L"--user {} echo $DISPLAY", LXSST_TEST_USERNAME));
|
||||||
VERIFY_ARE_EQUAL(out, L":0\n");
|
VERIFY_ARE_EQUAL(out, L":0\n");
|
||||||
|
|
||||||
|
std::tie(out, err) = LxsstuLaunchWslAndCaptureOutput(std::format(L"--user {} echo $XDG_RUNTIME_DIR", LXSST_TEST_USERNAME));
|
||||||
|
VERIFY_ARE_EQUAL(out, std::format(L"/run/user/{}\n", TestUid));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a 'broken' /run/user and validate that the warning is correctly displayed.
|
// Create a 'broken' /run/user and validate that the warning is correctly displayed.
|
||||||
|
|
@ -2312,7 +2319,7 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
|
||||||
const std::vector<LPCWSTR> serviceKeys{
|
const std::vector<LPCWSTR> serviceKeys{
|
||||||
L"SOFTWARE\\Microsoft\\Terminal Server Client\\Default\\OptionalAddIns\\WSLDVC_PACKAGE",
|
L"SOFTWARE\\Microsoft\\Terminal Server Client\\Default\\OptionalAddIns\\WSLDVC_PACKAGE",
|
||||||
L"SOFTWARE\\Classes\\CLSID\\{7e6ad219-d1b3-42d5-b8ee-d96324e64ff6}",
|
L"SOFTWARE\\Classes\\CLSID\\{7e6ad219-d1b3-42d5-b8ee-d96324e64ff6}",
|
||||||
L"SOFTWARE\\Classes\\AppID\\{7F82AD86-755B-4870-86B1-D2E68DFE8A49}"};
|
L"SOFTWARE\\Classes\\AppID\\{17696EAC-9568-4CF5-BB8C-82515AAD6C09}"};
|
||||||
|
|
||||||
for (const auto* keyName : serviceKeys)
|
for (const auto* keyName : serviceKeys)
|
||||||
{
|
{
|
||||||
|
|
@ -3517,6 +3524,208 @@ localhostForwarding=true
|
||||||
configRead.close();
|
configRead.close();
|
||||||
VERIFY_ARE_EQUAL(customWslConfigContentActual, customWslConfigContentExpected);
|
VERIFY_ARE_EQUAL(customWslConfigContentActual, customWslConfigContentExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regression test for GitHub issue #12671:
|
||||||
|
// Ensure that section headers always appear BEFORE their key-value pairs.
|
||||||
|
// Bug: WSL Settings GUI was writing keys before the section header, causing "Unknown key" errors.
|
||||||
|
{
|
||||||
|
std::wstring bugScenarioConfig =
|
||||||
|
LR"([wsl2]
|
||||||
|
[experimental]
|
||||||
|
[wsl2]
|
||||||
|
)";
|
||||||
|
WslConfigChange config{bugScenarioConfig.c_str()};
|
||||||
|
|
||||||
|
wslConfig = createWslConfig(apiWslConfigFilePath);
|
||||||
|
VERIFY_IS_NOT_NULL(wslConfig);
|
||||||
|
auto cleanupWslConfig = wil::scope_exit([&] { freeWslConfig(wslConfig); });
|
||||||
|
|
||||||
|
// Write memory setting - this should NOT appear before the first [wsl2]
|
||||||
|
WslConfigSetting memorySetting{};
|
||||||
|
memorySetting.ConfigEntry = WslConfigEntry::MemorySizeBytes;
|
||||||
|
memorySetting.UInt64Value = 17825792000ULL; // Value from bug report
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(setWslConfigSetting(wslConfig, memorySetting), ERROR_SUCCESS);
|
||||||
|
|
||||||
|
// Read and verify
|
||||||
|
std::wifstream configRead(apiWslConfigFilePath);
|
||||||
|
std::wstring fileContent{std::istreambuf_iterator<wchar_t>(configRead), {}};
|
||||||
|
configRead.close();
|
||||||
|
|
||||||
|
// Find FIRST occurrence of [wsl2] and memory=
|
||||||
|
auto firstWsl2Pos = fileContent.find(L"[wsl2]");
|
||||||
|
auto memoryPos = fileContent.find(L"memory=");
|
||||||
|
|
||||||
|
VERIFY_ARE_NOT_EQUAL(firstWsl2Pos, std::wstring::npos);
|
||||||
|
VERIFY_ARE_NOT_EQUAL(memoryPos, std::wstring::npos);
|
||||||
|
|
||||||
|
// The critical assertion: memory= must NOT appear before [wsl2]
|
||||||
|
VERIFY_IS_TRUE(firstWsl2Pos < memoryPos);
|
||||||
|
|
||||||
|
// Additional check: memory should appear after the first [wsl2], not after line 1
|
||||||
|
auto firstLineEnd = fileContent.find(L'\n');
|
||||||
|
VERIFY_IS_TRUE(memoryPos > firstLineEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test: Empty file - should create proper [wsl2] section structure
|
||||||
|
{
|
||||||
|
std::wofstream emptyConfig(apiWslConfigFilePath, std::ios::trunc);
|
||||||
|
emptyConfig.close();
|
||||||
|
|
||||||
|
wslConfig = createWslConfig(apiWslConfigFilePath);
|
||||||
|
VERIFY_IS_NOT_NULL(wslConfig);
|
||||||
|
auto cleanupWslConfig = wil::scope_exit([&] { freeWslConfig(wslConfig); });
|
||||||
|
|
||||||
|
WslConfigSetting memorySetting{};
|
||||||
|
memorySetting.ConfigEntry = WslConfigEntry::MemorySizeBytes;
|
||||||
|
memorySetting.UInt64Value = 4294967296ULL; // 4GB
|
||||||
|
VERIFY_ARE_EQUAL(setWslConfigSetting(wslConfig, memorySetting), ERROR_SUCCESS);
|
||||||
|
|
||||||
|
std::wifstream configRead(apiWslConfigFilePath);
|
||||||
|
std::wstring fileContent{std::istreambuf_iterator<wchar_t>(configRead), {}};
|
||||||
|
configRead.close();
|
||||||
|
|
||||||
|
// Should create [wsl2] section and add memory key
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"[wsl2]") != std::wstring::npos);
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"memory=") != std::wstring::npos);
|
||||||
|
// Verify [wsl2] comes before memory=
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"[wsl2]") < fileContent.find(L"memory="));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test: Multiple same-section instances - should update first occurrence
|
||||||
|
{
|
||||||
|
std::wofstream configFile(apiWslConfigFilePath, std::ios::trunc);
|
||||||
|
configFile << L"[wsl2]\n";
|
||||||
|
configFile << L"processors=4\n";
|
||||||
|
configFile << L"\n";
|
||||||
|
configFile << L"[experimental]\n";
|
||||||
|
configFile << L"autoProxy=true\n";
|
||||||
|
configFile << L"\n";
|
||||||
|
configFile << L"[wsl2]\n"; // Second [wsl2] section
|
||||||
|
configFile << L"swap=0\n";
|
||||||
|
configFile.close();
|
||||||
|
|
||||||
|
wslConfig = createWslConfig(apiWslConfigFilePath);
|
||||||
|
VERIFY_IS_NOT_NULL(wslConfig);
|
||||||
|
auto cleanupWslConfig = wil::scope_exit([&] { freeWslConfig(wslConfig); });
|
||||||
|
|
||||||
|
WslConfigSetting memorySetting{};
|
||||||
|
memorySetting.ConfigEntry = WslConfigEntry::MemorySizeBytes;
|
||||||
|
memorySetting.UInt64Value = 8589934592ULL; // 8GB
|
||||||
|
VERIFY_ARE_EQUAL(setWslConfigSetting(wslConfig, memorySetting), ERROR_SUCCESS);
|
||||||
|
|
||||||
|
std::wifstream configRead(apiWslConfigFilePath);
|
||||||
|
std::wstring fileContent{std::istreambuf_iterator<wchar_t>(configRead), {}};
|
||||||
|
configRead.close();
|
||||||
|
|
||||||
|
// Find first and second [wsl2]
|
||||||
|
auto firstWsl2 = fileContent.find(L"[wsl2]");
|
||||||
|
auto secondWsl2 = fileContent.find(L"[wsl2]", firstWsl2 + 1);
|
||||||
|
auto memoryPos = fileContent.find(L"memory=");
|
||||||
|
|
||||||
|
VERIFY_ARE_NOT_EQUAL(firstWsl2, std::wstring::npos);
|
||||||
|
VERIFY_ARE_NOT_EQUAL(secondWsl2, std::wstring::npos);
|
||||||
|
VERIFY_ARE_NOT_EQUAL(memoryPos, std::wstring::npos);
|
||||||
|
|
||||||
|
// Memory should be added to FIRST [wsl2] section, not second
|
||||||
|
VERIFY_IS_TRUE(memoryPos > firstWsl2);
|
||||||
|
VERIFY_IS_TRUE(memoryPos < secondWsl2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test: EOF without trailing newline
|
||||||
|
{
|
||||||
|
std::wofstream configFile(apiWslConfigFilePath, std::ios::trunc);
|
||||||
|
configFile << L"[wsl2]\n";
|
||||||
|
configFile << L"processors=2"; // No trailing newline
|
||||||
|
configFile.close();
|
||||||
|
|
||||||
|
wslConfig = createWslConfig(apiWslConfigFilePath);
|
||||||
|
VERIFY_IS_NOT_NULL(wslConfig);
|
||||||
|
auto cleanupWslConfig = wil::scope_exit([&] { freeWslConfig(wslConfig); });
|
||||||
|
|
||||||
|
WslConfigSetting memorySetting{};
|
||||||
|
memorySetting.ConfigEntry = WslConfigEntry::MemorySizeBytes;
|
||||||
|
memorySetting.UInt64Value = 3221225472ULL; // 3GB
|
||||||
|
VERIFY_ARE_EQUAL(setWslConfigSetting(wslConfig, memorySetting), ERROR_SUCCESS);
|
||||||
|
|
||||||
|
std::wifstream configRead(apiWslConfigFilePath);
|
||||||
|
std::wstring fileContent{std::istreambuf_iterator<wchar_t>(configRead), {}};
|
||||||
|
configRead.close();
|
||||||
|
|
||||||
|
// Should properly append memory key even without trailing newline on last line
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"processors=2") != std::wstring::npos);
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"memory=") != std::wstring::npos);
|
||||||
|
|
||||||
|
// Verify both keys are in the same section
|
||||||
|
auto wsl2Pos = fileContent.find(L"[wsl2]");
|
||||||
|
auto processorsPos = fileContent.find(L"processors=2");
|
||||||
|
auto memoryPos = fileContent.find(L"memory=");
|
||||||
|
VERIFY_IS_TRUE(wsl2Pos < processorsPos);
|
||||||
|
VERIFY_IS_TRUE(wsl2Pos < memoryPos);
|
||||||
|
|
||||||
|
// Memory should come after processors in the same section
|
||||||
|
VERIFY_IS_TRUE(processorsPos < memoryPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test: Empty section followed by another section
|
||||||
|
{
|
||||||
|
std::wofstream configFile(apiWslConfigFilePath, std::ios::trunc);
|
||||||
|
configFile << L"[wsl2]\n";
|
||||||
|
configFile << L"[experimental]\n";
|
||||||
|
configFile << L"autoProxy=true\n";
|
||||||
|
configFile.close();
|
||||||
|
|
||||||
|
wslConfig = createWslConfig(apiWslConfigFilePath);
|
||||||
|
VERIFY_IS_NOT_NULL(wslConfig);
|
||||||
|
auto cleanupWslConfig = wil::scope_exit([&] { freeWslConfig(wslConfig); });
|
||||||
|
|
||||||
|
WslConfigSetting memorySetting{};
|
||||||
|
memorySetting.ConfigEntry = WslConfigEntry::MemorySizeBytes;
|
||||||
|
memorySetting.UInt64Value = 5368709120ULL; // 5GB
|
||||||
|
VERIFY_ARE_EQUAL(setWslConfigSetting(wslConfig, memorySetting), ERROR_SUCCESS);
|
||||||
|
|
||||||
|
std::wifstream configRead(apiWslConfigFilePath);
|
||||||
|
std::wstring fileContent{std::istreambuf_iterator<wchar_t>(configRead), {}};
|
||||||
|
configRead.close();
|
||||||
|
|
||||||
|
// Should insert memory into empty [wsl2] section before [experimental]
|
||||||
|
auto wsl2Pos = fileContent.find(L"[wsl2]");
|
||||||
|
auto memoryPos = fileContent.find(L"memory=");
|
||||||
|
auto experimentalPos = fileContent.find(L"[experimental]");
|
||||||
|
|
||||||
|
VERIFY_ARE_NOT_EQUAL(wsl2Pos, std::wstring::npos);
|
||||||
|
VERIFY_ARE_NOT_EQUAL(memoryPos, std::wstring::npos);
|
||||||
|
VERIFY_ARE_NOT_EQUAL(experimentalPos, std::wstring::npos);
|
||||||
|
|
||||||
|
// Order should be: [wsl2], memory=, [experimental]
|
||||||
|
VERIFY_IS_TRUE(wsl2Pos < memoryPos);
|
||||||
|
VERIFY_IS_TRUE(memoryPos < experimentalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test: Section header at EOF with no content
|
||||||
|
{
|
||||||
|
std::wofstream configFile(apiWslConfigFilePath, std::ios::trunc);
|
||||||
|
configFile << L"[wsl2]"; // Section at EOF, no newline, no content
|
||||||
|
configFile.close();
|
||||||
|
|
||||||
|
wslConfig = createWslConfig(apiWslConfigFilePath);
|
||||||
|
VERIFY_IS_NOT_NULL(wslConfig);
|
||||||
|
auto cleanupWslConfig = wil::scope_exit([&] { freeWslConfig(wslConfig); });
|
||||||
|
|
||||||
|
WslConfigSetting memorySetting{};
|
||||||
|
memorySetting.ConfigEntry = WslConfigEntry::MemorySizeBytes;
|
||||||
|
memorySetting.UInt64Value = 6442450944ULL; // 6GB
|
||||||
|
VERIFY_ARE_EQUAL(setWslConfigSetting(wslConfig, memorySetting), ERROR_SUCCESS);
|
||||||
|
|
||||||
|
std::wifstream configRead(apiWslConfigFilePath);
|
||||||
|
std::wstring fileContent{std::istreambuf_iterator<wchar_t>(configRead), {}};
|
||||||
|
configRead.close();
|
||||||
|
|
||||||
|
// Should properly add key to section at EOF
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"[wsl2]") != std::wstring::npos);
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"memory=") != std::wstring::npos);
|
||||||
|
VERIFY_IS_TRUE(fileContent.find(L"[wsl2]") < fileContent.find(L"memory="));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(LaunchWslSettingsFromProtocol)
|
TEST_METHOD(LaunchWslSettingsFromProtocol)
|
||||||
|
|
|
||||||
|
|
@ -71,23 +71,41 @@ if ($Package) {
|
||||||
try {
|
try {
|
||||||
if ($AllowUnsigned)
|
if ($AllowUnsigned)
|
||||||
{
|
{
|
||||||
# unfortunately -AllowUnsigned isn't supported on vb so we need to manually import the certificate and trust it.
|
# Try to add with -AllowUnsigned first (supported in newer PowerShell)
|
||||||
(Get-AuthenticodeSignature $Package).SignerCertificate | Export-Certificate -FilePath private-wsl.cert | Out-Null
|
try {
|
||||||
try
|
Add-AppxPackage $Package -AllowUnsigned -ErrorAction Stop
|
||||||
{
|
|
||||||
Import-Certificate -FilePath .\private-wsl.cert -CertStoreLocation Cert:\LocalMachine\Root | Out-Null
|
|
||||||
}
|
}
|
||||||
finally
|
catch {
|
||||||
{
|
# Fallback: manually import the certificate and trust it
|
||||||
Remove-Item -Path .\private-wsl.cert
|
Write-Host "Attempting to import package certificate..."
|
||||||
|
$signature = Get-AuthenticodeSignature -LiteralPath $Package
|
||||||
|
if (-not $signature.SignerCertificate) {
|
||||||
|
Write-Error "Package is not signed or has no certificate. Cannot import certificate."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$cert = $signature.SignerCertificate
|
||||||
|
$certPath = Join-Path $env:TEMP "wsl-package-cert.cer"
|
||||||
|
try {
|
||||||
|
$cert | Export-Certificate -FilePath $certPath | Out-Null
|
||||||
|
Import-Certificate -FilePath $certPath -CertStoreLocation Cert:\LocalMachine\Root | Out-Null
|
||||||
|
Write-Host "Certificate imported successfully. Retrying package installation..."
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Remove-Item -Path $certPath -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
# Retry installation after importing certificate
|
||||||
|
Add-AppxPackage $Package -ErrorAction Stop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
Add-AppxPackage $Package
|
Add-AppxPackage $Package -ErrorAction Stop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Host $_
|
Write-Host "Error installing package: $_"
|
||||||
Get-AppPackageLog -All
|
Get-AppPackageLog | Select-Object -First 64 | Format-List
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<WindowsPerformanceRecorder Version="1">
|
|
||||||
<Profiles>
|
|
||||||
<EventCollector Id="Collector" Name="Collector">
|
|
||||||
<BufferSize Value="256"/>
|
|
||||||
<Buffers Value="1024"/>
|
|
||||||
</EventCollector>
|
|
||||||
|
|
||||||
<EventProvider Id="lxcore_kernel" Name="0CD1C309-0878-4515-83DB-749843B3F5C9"/>
|
|
||||||
<EventProvider Id="lxcore_user" Name="D90B9468-67F0-5B3B-42CC-82AC81FFD960"/>
|
|
||||||
<EventProvider Id="lxcore_service" Name="B99CDB5A-039C-5046-E672-1A0DE0A40211"/>
|
|
||||||
<EventProvider Id="vm_chipset" Name="de9ba731-7f33-4f44-98c9-6cac856b9f83"/>
|
|
||||||
<EventProvider Id="vmcompute_dll" Name="AF7FD3A7-B248-460C-A9F5-FEC39EF8468C"/>
|
|
||||||
<EventProvider Id="vmcompute" Name="17103E3F-3C6E-4677-BB17-3B267EB5BE57"/>
|
|
||||||
<EventProvider Id="vmmm" Name="6066F867-7CA1-4418-85FD-36E3F9C0600C"/>
|
|
||||||
<EventProvider Id="vmwp" Name="51DDFA29-D5C8-4803-BE4B-2ECB715570FE"/>
|
|
||||||
<EventProvider Id="9p" Name="e13c8d52-b153-571f-78c5-1d4098af2a1e"/>
|
|
||||||
<EventProvider Id="p9rdr" Name="bb1d36f0-e0e0-48cc-9493-fef0e3d0b28c" NonPagedMemory="true" Strict="true"/>
|
|
||||||
<EventProvider Id="mup" Name="20c46239-d059-4214-a11e-7d6769cbe020" />
|
|
||||||
<EventProvider Id="rfsmon" Name="51734B23-5B7E-4892-BA8E-45BC110B735C" />
|
|
||||||
<EventProvider Id="hyperv_storage" Name="c7ad62c6-5c99-5a1b-bbc4-0821ae5b765e" />
|
|
||||||
<EventProvider Id="hns" Name="0c885e0d-6eb6-476c-a048-2457eed3a5c1" />
|
|
||||||
<EventProvider Id="wsl_devicehost" Name="9d6c7b9e-2581-4d8a-b8c5-b90b4a17094a"/>
|
|
||||||
<EventProvider Id="vfpext" Name="9F2660EA-CFE7-428F-9850-AECA612619B0" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.AppDownload" Name="0BBE6221-EF09-4A3F-82EE-BE00DBB6A98A" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.Datastore" Name="42C60CEA-0FE7-4541-A86B-9E11F95BD9BF" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.PhoneProvisioner" Name="B876B1FC-C7F1-443E-9012-86677F7DE580" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Mobile.Provisioning.PPOEM" Name="7EDBED09-1FF7-4FEE-B8C3-5DB694420830" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.API" Name="82ADD491-01D7-4B85-9EAD-192C3CAACA23" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.CSP" Name="16E12400-A2D8-44B7-9479-004568EC7819" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Engine" Name="A6A847B7-4429-49AA-BBA6-2AD8C191AC8C" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Handlers" Name="0383D92C-2337-4F25-A0B5-A51767F04746" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Migration" Name="A0AF985E-83F9-4E1A-B658-338DCFE27893" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Operations" Name="7F99598F-B2C1-4371-9911-63DEE13B9EB1" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Platform" Name="B1F30020-8BC3-4888-BB1B-4DD681F24209" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Plugin.Engine" Name="55239D60-0EB6-495B-874E-15DE5D5F9A70" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.Plugin.RemovableMedia" Name="B55883E6-6C45-45C2-AB9D-800BB7B66B13" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.ProvTool" Name="2BF4B6BA-556E-4D05-8534-CAFEDF19FED8" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.CommandCsp" Name="00BB69FC-60BC-4502-9438-25608F375CCB" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.Provisioning.ProvLaunch" Name="08FACCFA-125D-4ED6-B0B7-B4A1A912E693" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.EMPS.Enrollment" Name="E74EFD1A-B62D-4B83-AB00-66F4A166A2D3" />
|
|
||||||
<EventProvider Id="EventProvider_Microsoft.Windows.EnterpriseManagement.Enrollment" Name="F9E3B648-9AF1-4DC3-9A8E-BF42C0FBCE9A" />
|
|
||||||
|
|
||||||
<Profile
|
|
||||||
Id="WSL.Verbose.File"
|
|
||||||
Name="WSL"
|
|
||||||
Description="Traces for all WSL components"
|
|
||||||
LoggingMode="File"
|
|
||||||
DetailLevel="Verbose"
|
|
||||||
>
|
|
||||||
<Collectors>
|
|
||||||
<EventCollectorId Value="Collector">
|
|
||||||
<EventProviders>
|
|
||||||
<EventProviderId Value="lxcore_kernel"/>
|
|
||||||
<EventProviderId Value="lxcore_user"/>
|
|
||||||
<EventProviderId Value="lxcore_service"/>
|
|
||||||
<EventProviderId Value="vm_chipset"/>
|
|
||||||
<EventProviderId Value="vmcompute_dll"/>
|
|
||||||
<EventProviderId Value="vmcompute"/>
|
|
||||||
<EventProviderId Value="vmmm"/>
|
|
||||||
<EventProviderId Value="vmwp"/>
|
|
||||||
<EventProviderId Value="9p"/>
|
|
||||||
<EventProviderId Value="p9rdr"/>
|
|
||||||
<EventProviderId Value="mup"/>
|
|
||||||
<EventProviderId Value="rfsmon"/>
|
|
||||||
<EventProviderId Value="hyperv_storage"/>
|
|
||||||
<EventProviderId Value="hns"/>
|
|
||||||
<EventProviderId Value="wsl_devicehost"/>
|
|
||||||
<EventProviderId Value="vfpext"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.AppDownload"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.Datastore"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.PhoneProvisioner"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Mobile.Provisioning.PPOEM"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.CSP"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Engine"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Migration"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Platform"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Operations"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Plugin.Engine"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Plugin.RemovableMedia"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.ProvTool"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.Operations"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.CommandCsp"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.Provisioning.ProvLaunch"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.EMPS.Enrollment"/>
|
|
||||||
<EventProviderId Value="EventProvider_Microsoft.Windows.EnterpriseManagement.Enrollment"/>
|
|
||||||
</EventProviders>
|
|
||||||
</EventCollectorId>
|
|
||||||
</Collectors>
|
|
||||||
</Profile>
|
|
||||||
</Profiles>
|
|
||||||
</WindowsPerformanceRecorder>
|
|
||||||
Loading…
Reference in New Issue