4
5
WSL is the Windows Subsystem for Linux - a compatibility layer for running Linux binary executables natively on Windows. This repository contains the core Windows components that enable WSL functionality.
6
7
-## Working Effectively
7
+## Coding Conventions
8
+
9
+### Naming
10
+
11
+- **Classes/Structs**: `PascalCase` (e.g., `ConsoleProgressBar`, `DeviceHostProxy`)
12
+- **Functions/Methods**: `PascalCase()` (e.g., `GetFamilyName()`, `MultiByteToWide()`)
13
+- **Member variables**: `m_camelCase` (e.g., `m_isOutputConsole`, `m_outputHandle`)
14
+- **Local variables**: `camelCase` (e.g., `distroGuidString`, `asyncResponse`)
15
+- **Constants**: `c_camelCase` with `constexpr` (e.g., `constexpr size_t c_progressBarWidth = 58;`)
16
+- **Namespaces**: lowercase with `::` nesting (e.g., `wsl::windows::common::registry`)
17
+- **Enums**: `PascalCaseValue` (e.g., `LxssDistributionStateInstalled`)
18
+- **Windows types**: Keep as-is (`LPCWSTR`, `HRESULT`, `DWORD`, `ULONG`, `GUID`)
19
+
20
+### Error Handling
21
+
22
+Use WIL (Windows Implementation Libraries) macros — **never** bare `if (FAILED(hr))`:
23
+- `THROW_IF_FAILED(hr)` — throw on HRESULT failure
24
+- `THROW_HR_IF(hr, condition)` — conditional throw
25
+- `THROW_HR_IF_MSG(hr, condition, fmt, ...)` — conditional throw with message
26
+- `THROW_IF_NULL_ALLOC(ptr)` — throw on null allocation
27
+- `THROW_LAST_ERROR_IF(condition)` — throw last Win32 error
28
+- `RETURN_IF_FAILED(hr)` — return HRESULT on failure (no throw)
29
+- `RETURN_LAST_ERROR_IF_EXPECTED(condition)` — expected failure path
30
+- `LOG_IF_FAILED(hr)` — log but don't throw
31
+- `CATCH_LOG()` — catch and log exceptions
32
+
33
+For user-facing errors, set a localized message before throwing:
34
+```cpp
35
+THROW_HR_WITH_USER_ERROR(E_INVALIDARG, Localization::MessageConfigInvalidBoolean(name, value));
36
+```
37
+
38
+At API boundaries (COM interfaces), return `HRESULT` with out params. Internal code throws exceptions.
39
+
40
+### Memory Management and RAII
41
+
42
+Use WIL smart pointers — **never** raw `CloseHandle()` or manual cleanup:
43
+- `wil::unique_handle` — kernel handles
44
+- `wil::com_ptr<T>` — COM objects
45
+- `wil::unique_hfile` — file handles
46
+- `wil::unique_hkey` — registry keys
47
+- `wil::unique_event` — events
48
+- `wil::unique_hlocal_string` — HLOCAL strings
49
+- `wil::unique_cotaskmem_string` — CoTaskMem strings
50
+
51
+For non-standard resource types, use `wil::unique_any<Type, Deleter, Fn>`.
52
+
53
+For cleanup scopes, use `wil::scope_exit`:
54
+```cpp
55
+auto cleanup = wil::scope_exit([&] { registry::DeleteKey(LxssKey, guid.c_str()); });
56
+// ... work ...
57
+cleanup.release(); // dismiss on success
58
+```
59
+
60
+### Synchronization
61
+
62
+Use `wil::srwlock` (Slim Reader/Writer locks) with SAL annotations:
63
+```cpp
64
+mutable wil::srwlock m_lock;
65
+_Guarded_by_(m_lock) std::vector<Entry> m_entries;
66
+```
67
+
68
+### Strings
69
+
70
+- `std::wstring` / `std::wstring_view` are dominant throughout the codebase
71
+- Use `MultiByteToWide()` / `WideToMultiByte()` from `stringshared.h` for conversions
72
+- Use `std::format()` for formatting (the repo defines `std::formatter<std::wstring, char>` for wide-to-narrow support)
73
+- The `STRING_TO_WIDE_STRING()` macro handles compile-time conversion
74
+
75
+### Copy/Move Semantics
76
+
77
+Use macros from `defs.h` to declare copy/move behavior:
78
+```cpp
79
+NON_COPYABLE(MyClass);
80
+NON_MOVABLE(MyClass);
81
+DEFAULT_MOVABLE(MyClass);
82
+```
83
+
84
+### Headers
85
+
86
+- Use `#pragma once` (no traditional `#ifndef` include guards)
87
+- In Windows C++ components, every `.cpp` file must start with `#include "precomp.h"`
88
+- Linux-side code (`src/linux/`) does not use precompiled headers
89
+- Use `.h` for C-compatible headers, `.hpp` for C++-only headers
90
+- Include order is enforced by `.clang-format` (precomp first, then system, then project)
91
+
92
+### Copyright Headers
93
+
94
+Use this single-line format for new files:
95
+```cpp
96
+// Copyright (C) Microsoft Corporation. All rights reserved.
97
+```
98
+
99
+Some older files use the block format (`/*++ Copyright (c) Microsoft. All rights reserved. ... --*/`). Match the surrounding files in the same directory when editing.
100
+
101
+### Localization
102
+
103
+- Use `wsl::shared::Localization::MessageXxx()` static methods for user-facing strings
104
+- Use `EMIT_USER_WARNING(Localization::MessageXxx(...))` for non-fatal config warnings
105
+- All new user-facing strings must have entries in `localization/strings/en-US/Resources.resw`
106
+- In Resources.resw comments, use `{Locked="..."}` to prevent translation of `.wslconfig` property key names
107
+
108
+### Telemetry and Logging
109
+
110
+- `WSL_LOG(Name, ...)` — standard trace event
111
+- `WSL_LOG_DEBUG(Name, ...)` — debug-only (compiled out in release via `if constexpr`)
112
+- `WSL_LOG_TELEMETRY(Name, Tag, ...)` — metrics with privacy tag and version info
113
+- Provider: `g_hTraceLoggingProvider`, initialized via `WslTraceLoggingInitialize()`
114
+
115
+### Platform Conditionals
116
+
117
+Prefer `constexpr` checks over `#ifdef` where possible:
118
+```cpp
119
+if constexpr (wsl::shared::Debug) { /* debug-only code */ }
120
+if constexpr (wsl::shared::Arm64) { /* ARM64-specific code */ }
121
+```
122
+
123
+For compiler-specific code, use `#ifdef _MSC_VER` (Windows) / `#ifdef __GNUC__` (Linux).
124
+
125
+### Formatting
126
+
127
+Enforced by `.clang-format`:
128
+- 130 character column limit
129
+- 4-space indentation, no tabs
130
+- Allman-style braces (opening brace on new line for classes, functions, structs, control statements)
131
+- Left-aligned pointers (`int* ptr`, not `int *ptr`)
132
+- `InsertBraces: true` — all control statements must have braces
133
+
134
+### IDL / COM Conventions
135
+
136
+When modifying service interfaces (`src/windows/service/inc/`):
137
+- Interface attributes on separate lines: `[uuid(...), pointer_default(unique), object]`
138
+- String params: `[in, unique] LPCWSTR` with `[string]` for marshaled strings
139
+- Handle params: `[in, system_handle(sh_file)] HANDLE`
140
+- User-facing errors: pass `[in, out] LXSS_ERROR_INFO* Error`
141
+- **Adding methods to an existing interface is an ABI break** — create a new versioned interface with a new IID
142
+- Custom error codes: `WSL_E_xxx` via `MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSL_E_BASE + N)`
143
+
144
+### Config File (.wslconfig) Conventions
145
+
146
+When adding settings to `src/shared/configfile/`:
147
+- Format is `.gitconfig`-style INI: `[section]`, `key = value`, `#` comments, `\` line continuation
148
+- Use the `ConfigKey` template class for type-safe parsing
149
+- Supported types: `bool`, `int` (hex/octal), `std::string`, `std::wstring`, `MemoryString`, `MacAddress`, enum maps
150
+- Report invalid values with `EMIT_USER_WARNING(Localization::MessageConfigXxx(...))`
151
+- New settings require a corresponding localization string in Resources.resw
152
+
153
+## Repository Navigation
154
+
155
+### Key Directories
156
+- `src/windows/` — Main Windows WSL service components
157
+- `src/linux/` — Linux-side WSL components
158
+- `src/shared/` — Shared code between Windows and Linux
159
+- `test/windows/` — Windows-based tests (TAEF framework)
160
+- `test/linux/unit_tests/` — Linux unit test suite
161
+- `doc/` — Documentation source (MkDocs)
162
+- `tools/` — Build and deployment scripts
163
+- `distributions/` — Distribution validation and metadata
164
+- `localization/` — Localized string resources
165
+
166
+### Namespace → Directory Map
167
+
168
+| Namespace | Location |
169
+|---|---|
170
+| `wsl::shared::` | `src/shared/` |
171
+| `wsl::windows::common::` | `src/windows/common/` |
172
+| `wsl::windows::service::` | `src/windows/service/exe/` |
173
+| `wsl::core::` | `src/windows/service/exe/` |
174
+| `wsl::core::networking::` | `src/windows/common/` + `src/windows/service/exe/` |
175
+| `wsl::linux::` | `src/linux/init/` |
176
+
177
+### Key Files
178
+- `src/shared/inc/defs.h` — Shared platform definitions (NON_COPYABLE, Debug, Arm64, etc.)
179
+- `src/shared/inc/stringshared.h` — String conversion utilities
180
+- `src/windows/common/WslTelemetry.h` — Telemetry macros
181
+- `src/windows/common/ExecutionContext.h` — Error context and user-facing error macros
182
+- `src/windows/service/inc/wslservice.idl` — Main service COM interface definitions
183
+- `src/windows/service/inc/wslc.idl` — Container COM interface definitions
184
+- `src/windows/inc/WslPluginApi.h` — Plugin API header
185
+- `src/shared/configfile/configfile.h` — Config file parser
186
+- `.clang-format` — Code formatting rules (130 col, 4-space indent, Allman braces)
187
+
188
+## Building and Deploying
189
190
### Critical Platform Requirements
191
- **Full builds ONLY work on Windows** with Visual Studio and Windows SDK 26100
11
-- **DO NOT attempt to build the main WSL components on Linux** - they require Windows-specific APIs, MSBuild, and Visual Studio toolchain
192
+- **DO NOT attempt to build the main WSL components on Linux** — they require Windows-specific APIs, MSBuild, and Visual Studio toolchain
193
- Many validation and development tasks CAN be performed on Linux (documentation, formatting, Python validation scripts)
194
14
-### Windows Build Requirements (Required for Full Development)
195
+### Windows Build Requirements
196
- CMake >= 3.25 (`winget install Kitware.CMake`)
197
- Visual Studio with these components:
17
- - Windows SDK 26100
198
+ - Windows SDK 26100
199
- MSBuild
200
- Universal Windows platform support for v143 build tools (X64 and ARM64)
201
- MSVC v143 - VS 2022 C++ ARM64 build tools (Latest + Spectre) (X64 and ARM64)
210
1. Clone the repository
211
2. Generate Visual Studio solution: `cmake .`
212
3. Build: `cmake --build . -- -m` OR open `wsl.sln` in Visual Studio
32
-4. **NEVER CANCEL: Build takes 20-45 minutes on typical hardware. Set timeout to 60+ minutes.**
213
214
Build parameters:
35
-- `cmake . -A arm64` - Build for ARM64
36
-- `cmake . -DCMAKE_BUILD_TYPE=Release` - Release build
37
-- `cmake . -DBUILD_BUNDLE=TRUE` - Build bundle msix package (requires ARM64 built first)
215
+- `cmake . -A arm64` — Build for ARM64
216
+- `cmake . -DCMAKE_BUILD_TYPE=Release` — Release build
217
+- `cmake . -DBUILD_BUNDLE=TRUE` — Build bundle MSIX package (requires ARM64 built first)
218
39
-### Deploying WSL (Windows Only)
219
+### Deploying WSL (Windows Only)
220
- Install MSI: `bin\<platform>\<target>\wsl.msi`
221
- OR use script: `powershell tools\deploy\deploy-to-host.ps1`
222
- For Hyper-V VM: `powershell tools\deploy\deploy-to-vm.ps1 -VmName <vm> -Username <user> -Password <pass>`
223
44
-## Cross-Platform Development Tasks
45
-
46
-### Documentation (Works on Linux/Windows)
47
-- Install tools: `pip install mkdocs-mermaid2-plugin mkdocs --break-system-packages`
48
-- Build docs: `mkdocs build -f doc/mkdocs.yml`
49
-- **Build time: ~0.5 seconds. Set timeout to 5+ minutes for safety.**
50
-- Output location: `doc/site/`
51
-- **Note**: May show warnings about mermaid CDN access on restricted networks
224
+## Testing
225
53
-### Code Formatting and Validation (Works on Linux/Windows)
54
-- Format check: `clang-format --dry-run --style=file <files>`
55
-- Apply formatting: `clang-format -i --style=file <files>`
56
-- Format all source: `powershell formatsource.ps1` (available at repo root after running `cmake .`)
57
-- Validate copyright headers: `python3 tools/devops/validate-copyright-headers.py`
58
- - **Note**: Will report missing headers in generated/dependency files (_deps/), which is expected
59
-- Validate localization: `python3 tools/devops/validate-localization.py`
60
- - **Note**: Only works after Windows build (requires localization/strings/en-us/Resources.resw)
226
+### Writing Tests (TAEF Framework)
227
62
-### Distribution Validation (Limited on Linux)
63
-- Validate distribution info: `python3 distributions/validate.py distributions/DistributionInfo.json`
64
-- **Note**: May fail on Linux due to network restrictions accessing distribution URLs
228
+Tests use TAEF. See `.github/copilot/test.md` for detailed patterns and macros.
229
66
-## Testing
230
+Key points:
231
+- Use `WSL_TEST_CLASS(Name)` — not raw `BEGIN_TEST_CLASS`
232
+- Use `VERIFY_*` macros for assertions (`VERIFY_ARE_EQUAL`, `VERIFY_IS_TRUE`, etc.)
233
+- Skip macros: `WSL1_TEST_ONLY()`, `WSL2_TEST_ONLY()`, `SKIP_TEST_ARM64()`
234
+- Test infrastructure is in `test/windows/Common.h`
235
68
-### Unit Tests (Windows Only - TAEF Framework)
236
+### Running Tests (Windows Only)
237
238
**CRITICAL: ALWAYS build the ENTIRE project before running tests:**
239
```powershell
72
-# Build everything first - this is required!
240
cmake --build . -- -m
74
-
75
-# Then run tests
241
bin\<platform>\<target>\test.bat
242
```
243
244
**Why full build is required:**
245
- Tests depend on multiple components (libwsl.dll, wsltests.dll, wslservice.exe, etc.)
81
-- Partial builds (e.g., only `configfile` or `wsltests`) will cause test failures
82
-- Changed components must be built together to ensure compatibility
246
+- Partial builds will cause test failures
247
- **DO NOT skip the full build step even if only one file changed**
248
249
Test execution:
250
- Run all tests: `bin\<platform>\<target>\test.bat`
87
-- **NEVER CANCEL: Full test suite takes 30-60 minutes. Set timeout to 90+ minutes.**
251
- Run subset: `bin\<platform>\<target>\test.bat /name:*UnitTest*`
252
- Run specific test: `bin\<platform>\<target>\test.bat /name:<class>::<test>`
253
- WSL1 tests: Add `-Version 1` flag
254
- Fast mode (after first run): Add `-f` flag (requires `wsl --set-default test_distro`)
92
-- **Requires Administrator privileges** - test.bat will fail without admin rights
255
+- **Requires Administrator privileges**
256
257
Test debugging:
258
- Wait for debugger: `/waitfordebugger`
264
- Build script: `test/linux/unit_tests/build_tests.sh`
265
- **Note**: Requires specific Linux build environment setup not covered in main build process
266
104
-## Validation Scenarios
267
+## Cross-Platform Validation Tasks
268
106
-### Always Test These After Changes:
107
-1. **Documentation Build**: Run `mkdocs build -f doc/mkdocs.yml` and verify no errors
108
-2. **Code Formatting**: Run `clang-format --dry-run --style=file` on changed files
109
-3. **Windows Build** (if on Windows): Full cmake build cycle
110
-4. **Distribution Validation**: Run Python validation scripts on any distribution changes
269
+### Documentation (Works on Linux/Windows)
270
+- Install tools: `pip install mkdocs-mermaid2-plugin mkdocs --break-system-packages`
271
+- Build docs: `mkdocs build -f doc/mkdocs.yml`
272
+- Output location: `doc/site/`
273
+- **Note**: May show warnings about mermaid CDN access on restricted networks
274
112
-### Manual Validation Requirements
113
-- **Windows builds**: Install MSI and test basic WSL functionality (`wsl --version`, `wsl -l`)
114
-- **Documentation changes**: Review generated HTML in `doc/site/`
115
-- **Distribution changes**: Test with actual WSL distribution installation
275
+### Code Formatting and Validation
276
+- Format all source (Windows, requires `cmake .` first): `.\FormatSource.ps1`
277
+- Format check (Linux/cross-platform): `clang-format --dry-run --style=file <files>`
278
+- Validate copyright headers: `python3 tools/devops/validate-copyright-headers.py`
279
+ - **Note**: Will report missing headers in generated/dependency files (`_deps/`), which is expected
280
+- Validate localization: `python3 tools/devops/validate-localization.py`
281
+ - **Note**: Only works after Windows build (requires `localization/strings/en-US/Resources.resw`)
282
117
-## Repository Navigation
283
+### Distribution Validation (Limited on Linux)
284
+- Validate distribution info: `python3 distributions/validate.py distributions/DistributionInfo.json`
285
+- **Note**: May fail on Linux due to network restrictions accessing distribution URLs
286
119
-### Key Directories
120
-- `src/windows/` - Main Windows WSL service components
121
-- `src/linux/` - Linux-side WSL components
122
-- `src/shared/` - Shared code between Windows and Linux
123
-- `test/windows/` - Windows-based tests (TAEF framework)
124
-- `test/linux/unit_tests/` - Linux unit test suite
125
-- `doc/` - Documentation source (MkDocs)
126
-- `tools/` - Build and deployment scripts
127
-- `distributions/` - Distribution validation and metadata
287
+### Pre-commit Checklist
288
+Always run before committing:
289
+1. `.\FormatSource.ps1` to verify formatting on changed C++ files
290
+2. `python3 tools/devops/validate-copyright-headers.py` (ignore `_deps/` warnings)
291
+3. `mkdocs build -f doc/mkdocs.yml` if documentation changed
292
+4. Full Windows build if core components changed
293
129
-### Key Files
130
-- `CMakeLists.txt` - Main build configuration
131
-- `doc/docs/dev-loop.md` - Developer build instructions
132
-- `test/README.md` - Testing framework documentation
133
-- `CONTRIBUTING.md` - Contribution guidelines
134
-- `.clang-format` - Code formatting rules
135
-- `UserConfig.cmake.sample` - Optional build customizations
294
+**Note**: The `.gitignore` properly excludes build artifacts (`*.sln`, `*.dll`, `*.pdb`, `obj/`, `bin/`, etc.) — do not commit these files.
295
137
-### Frequently Used Commands (Platform-Specific)
296
+## Frequently Used Commands
297
139
-#### Windows Development:
140
-```bash
298
+### Windows Development
299
+```powershell
300
# Initial setup
301
cmake .
143
-cmake --build . -- -m # 20-45 minutes, NEVER CANCEL
302
+cmake --build . -- -m
303
145
-# Deploy and test
304
+# Deploy and test
305
powershell tools\deploy\deploy-to-host.ps1
306
wsl --version
307
308
# Run tests
150
-bin\x64\debug\test.bat # 30-60 minutes, NEVER CANCEL
309
+bin\x64\debug\test.bat
310
```
311
153
-#### Cross-Platform Validation:
154
-```bash
155
-# Documentation (0.5 seconds)
312
+### Cross-Platform Validation
313
+```powershell
314
+# Documentation
315
mkdocs build -f doc/mkdocs.yml
316
158
-# Code formatting
159
-find src -name "*.cpp" -o -name "*.h" | xargs clang-format --dry-run --style=file
317
+# Code formatting (Windows)
318
+.\FormatSource.ps1
319
320
# Copyright header validation (reports expected issues in _deps/)
321
python3 tools/devops/validate-copyright-headers.py
330
```powershell
331
# Collect traces
332
wpr -start diagnostics\wsl.wprp -filemode
174
-# [reproduce issue]
333
+# [reproduce issue]
334
wpr -stop logs.ETL
335
336
# Available profiles:
353
```
354
355
### Common Debugging Commands
197
-- Debug shell: `wsl --debug-shell`
356
+- Debug shell: `wsl --debug-shell`
357
- Collect WSL logs: `powershell diagnostics\collect-wsl-logs.ps1`
358
- Network logs: `powershell diagnostics\collect-wsl-logs.ps1 -LogProfile networking`
359
201
-## Critical Timing and Timeout Guidelines
360
+## Timing and Timeout Guidelines
361
203
-**NEVER CANCEL these operations - always wait for completion:**
362
+**NEVER CANCEL these operations — always wait for completion:**
363
205
-- **Full Windows build**: 20-45 minutes (set timeout: 60+ minutes)
206
-- **Full test suite**: 30-60 minutes (set timeout: 90+ minutes)
207
-- **Unit test subset**: 5-15 minutes (set timeout: 30+ minutes)
208
-- **Documentation build**: ~0.5 seconds (set timeout: 5+ minutes)
209
-- **Distribution validation**: 2-5 minutes (set timeout: 15+ minutes)
364
+| Operation | Typical Duration | Minimum Timeout |
365
+|---|---|---|
366
+| Full Windows build | 20-45 minutes | 60+ minutes |
367
+| Full test suite | 30-60 minutes | 90+ minutes |
368
+| Unit test subset | 5-15 minutes | 30+ minutes |
369
+| Documentation build | ~0.5 seconds | 5+ minutes |
370
+| Distribution validation | 2-5 minutes | 15+ minutes |
371
372
## CI/CD Integration
373
374
### GitHub Actions
214
-- **distributions.yml**: Validates distribution metadata (Linux)
215
-- **documentation.yml**: Builds and deploys docs (Linux)
216
-- **modern-distributions.yml**: Tests modern distribution support
217
-
218
-### Pre-commit Validation
219
-Always run before committing:
220
-1. `clang-format --dry-run --style=file` on changed C++ files
221
-2. `python3 tools/devops/validate-copyright-headers.py` (ignore _deps/ warnings)
222
-3. `mkdocs build -f doc/mkdocs.yml` if documentation changed
223
-4. Full Windows build if core components changed
224
-
225
-**Note**: The `.gitignore` file properly excludes build artifacts (*.sln, *.dll, *.pdb, obj/, bin/, etc.) - do not commit these files.
375
+- **distributions.yml** — Validates distribution metadata (Linux)
376
+- **documentation.yml** — Builds and deploys docs (Linux)
377
+- **modern-distributions.yml** — Tests modern distribution support
378
379
## Development Environment Setup
380
385
4. Clone repository
386
5. Run `cmake .` to generate solution
387
236
-### Linux (Documentation/Validation Only)
388
+### Linux (Documentation/Validation Only)
389
1. Install Python 3.8+
238
-2. Install clang-format
239
-3. Install docs tools: `pip install mkdocs-mermaid2-plugin mkdocs`
240
-4. Clone repository
241
-5. Run validation commands as needed
390
+2. Install docs tools: `pip install mkdocs-mermaid2-plugin mkdocs`
391
+3. Clone repository
392
+4. Run validation commands as needed
393
394
Remember: **This is a Windows-focused project**. While some tasks can be performed on Linux, full WSL development requires Windows with Visual Studio.
\ No newline at end of file