Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add new bluetooth module #147

Open
Gijsreyn wants to merge 21 commits intomicrosoft:main from
Gijsreyn:windows-setting-bluetooth
Open

Add new bluetooth module #147
Gijsreyn wants to merge 21 commits intomicrosoft:main from
Gijsreyn:windows-setting-bluetooth

Conversation

@Gijsreyn
Copy link
Contributor

@Gijsreyn Gijsreyn commented Jan 19, 2025
edited
Loading


This PR addresses starts to address issue #94. The following DSC resources are introduced:

  • USB
  • PenWindowsInk
  • Mouse
  • AutoPlay
  • PrinterAndScanner
  • MobileDevice
Microsoft Reviewers: Open in CodeFlow

Copy link
Contributor Author

Hi @denelon. I started working on this module with quite some hiccups. Despite the hiccups, working with the low-level APIs was an interesting learning curve, and I guess the engineers in your team will like it as well. I aimed to address the logoff/login for users when applying a DSC resource. There might only be 1 or 2 at the moment because it didn't have a clear function to call (it's in a TODO).

Unfortunately, I couldn't finish the Touchpad class. I already constructed the function with the C/C++ code, but somehow, I cannot get it to work. Hopefully, someone on the team can help me with it.

This comment has been minimized.

Copy link
Collaborator

@stephengillie stephengillie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Gijsreyn,

Apologies for experimenting with your module instead of one of my own. In reviewing your very well-formatted code, I kept seeing the code patterns stand out and wanted to express them in a more compact way. Please let me know what you think.

# TODO: There is no refresh win32_api, so users have to logout and login to see the changes.
}
}
#endregion Functions
Copy link
Collaborator

@stephengillie stephengillie Feb 5, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endregion Functions
#endregion Functions
#Region CommonFunctions
function Set-RegistryKey {
param(
$NewValue,
$RegistryPath,
$RegistryKey,
$KeyType = "DWORD"
)
if ($null -ne $NewValue) {
if (-not (DoesRegistryKeyPropertyExist -Path $RegistryPath -Name $RegistryKey)) {
New-ItemProperty -Path $RegistryPath -Name $RegistryKey -Value $NewValue -PropertyType $KeyType | Out-Null
}
Set-ItemProperty -Path $RegistryPath -Name $RegistryKey -Value $NewValue
}
}
function Get-RegistryKey {
param(
$RegistryPath,
$RegistryKey,
$KeyParameter,
$ReturnValue = 1
)
if (-not (DoesRegistryKeyPropertyExist -Path $RegistryPath -Name $RegistryKey)) {
return $true
} else {
$KeyValue = (Get-ItemProperty -Path $RegistryPath -Name $RegistryKey).$KeyName
return ($KeyValue -eq $ReturnValue)
}
}
#endregion CommonFunctions

Comment on lines +504 to +527
[void] Set() {
if (-not ($this.Test())) {
if ($null -ne $this.ConnectionNotifications) {
if (-not (DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty))) {
New-ItemProperty -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty) -Value ([int]$this.ConnectionNotifications) -PropertyType DWord | Out-Null
}
Set-ItemProperty -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty) -Value ([int]$this.ConnectionNotifications)
}

if ($null -ne $this.SlowChargingNotification) {
if (-not (DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty))) {
New-ItemProperty -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty) -Value ([int]$this.SlowChargingNotification) -PropertyType DWord | Out-Null
}
Set-ItemProperty -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty) -Value ([int]$this.SlowChargingNotification)
}

if ($null -ne $this.BatterySaver) {
if (-not (DoesRegistryKeyPropertyExist -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty))) {
New-ItemProperty -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty) -Value ([int]$this.BatterySaver) -PropertyType DWord | Out-Null
}
Set-ItemProperty -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty) -Value ([int]$this.BatterySaver)
}
}
}
Copy link
Collaborator

@stephengillie stephengillie Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[void] Set() {
if (-not ($this.Test())) {
if ($null -ne $this.ConnectionNotifications) {
if (-not (DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty))) {
New-ItemProperty -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty) -Value ([int]$this.ConnectionNotifications) -PropertyType DWord | Out-Null
}
Set-ItemProperty -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty) -Value ([int]$this.ConnectionNotifications)
}
if ($null -ne $this.SlowChargingNotification) {
if (-not (DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty))) {
New-ItemProperty -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty) -Value ([int]$this.SlowChargingNotification) -PropertyType DWord | Out-Null
}
Set-ItemProperty -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty) -Value ([int]$this.SlowChargingNotification)
}
if ($null -ne $this.BatterySaver) {
if (-not (DoesRegistryKeyPropertyExist -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty))) {
New-ItemProperty -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty) -Value ([int]$this.BatterySaver) -PropertyType DWord | Out-Null
}
Set-ItemProperty -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty) -Value ([int]$this.BatterySaver)
}
}
}
[void] Set() {
if (-not ($this.Test())) {
Set-RegistryKey -NewValue [int]$this.ConnectionNotifications -RegistryPath $global:USBShellPath -RegistryKey ([USB]::ConnectionNotificationsProperty)
Set-RegistryKey -NewValue [int]$this.SlowChargingNotification -RegistryPath $global:USBShellPath -RegistryKey ([USB]::SlowChargingNotificationProperty)
Set-RegistryKey -NewValue [int]$this.BatterySaver -RegistryPath $global:USBMachinePath -RegistryKey ([USB]::BatterySaverProperty)
}
}```

Comment on lines +529 to +557
#region USB helper functions
static [bool] GetConnectionNotificationStatus() {
if (-not(DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty))) {
return $true
} else {
$ConnectionNotificationsValue = (Get-ItemProperty -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty)).NotifyOnUsbErrors
return ($ConnectionNotificationsValue -eq 1)
}
}

static [bool] GetSlowChargingNotificationStatus() {
if (-not(DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty))) {
return $true
} else {
$SlowChargingNotificationValue = (Get-ItemProperty -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty)).NotifyOnWeakCharger
return ($SlowChargingNotificationValue -eq 1)
}
}

static [bool] GetBatterySaverStatus() {
if (-not(DoesRegistryKeyPropertyExist -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty))) {
return $false # It is not enabled by default if the registry key does not exist.
} else {
$BatterySaverValue = (Get-ItemProperty -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty)).AttemptRecoveryFromUsbPowerDrain
return ($BatterySaverValue -eq 1)
}
}
#endregion USB helper functions
}
Copy link
Collaborator

@stephengillie stephengillie Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#region USB helper functions
static [bool] GetConnectionNotificationStatus() {
if (-not(DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty))) {
return $true
} else {
$ConnectionNotificationsValue = (Get-ItemProperty -Path $global:USBShellPath -Name ([USB]::ConnectionNotificationsProperty)).NotifyOnUsbErrors
return ($ConnectionNotificationsValue -eq 1)
}
}
static [bool] GetSlowChargingNotificationStatus() {
if (-not(DoesRegistryKeyPropertyExist -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty))) {
return $true
} else {
$SlowChargingNotificationValue = (Get-ItemProperty -Path $global:USBShellPath -Name ([USB]::SlowChargingNotificationProperty)).NotifyOnWeakCharger
return ($SlowChargingNotificationValue -eq 1)
}
}
static [bool] GetBatterySaverStatus() {
if (-not(DoesRegistryKeyPropertyExist -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty))) {
return $false # It is not enabled by default if the registry key does not exist.
} else {
$BatterySaverValue = (Get-ItemProperty -Path $global:USBMachinePath -Name ([USB]::BatterySaverProperty)).AttemptRecoveryFromUsbPowerDrain
return ($BatterySaverValue -eq 1)
}
}
#endregion USB helper functions
}
}

Comment on lines +479 to +481
$currentState.ConnectionNotifications = [USB]::GetConnectionNotificationStatus()
$currentState.SlowChargingNotification = [USB]::GetSlowChargingNotificationStatus()
$currentState.BatterySaver = [USB]::GetBatterySaverStatus()
Copy link
Collaborator

@stephengillie stephengillie Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$currentState.ConnectionNotifications = [USB]::GetConnectionNotificationStatus()
$currentState.SlowChargingNotification = [USB]::GetSlowChargingNotificationStatus()
$currentState.BatterySaver = [USB]::GetBatterySaverStatus()
$currentState.ConnectionNotifications = Get-RegistryKey-RegistryPath $global:USBShellPath-RegistryKey ([USB]::ConnectionNotificationsProperty) -KeyParameter "NotifyOnUsbErrors"
$currentState.SlowChargingNotification = Get-RegistryKey-RegistryPath $global:USBShellPath-RegistryKey ([USB]::SlowChargingNotificationProperty) -KeyParameter "NotifyOnWeakCharger"
$currentState.BatterySaver = Get-RegistryKey-RegistryPath $global:USBMachinePath-RegistryKey ([USB]::BatterySaverProperty) -KeyParameter "AttemptRecoveryFromUsbPowerDrain"

Comment on lines +242 to +248
# TODO: Does not work, error code 87. See: https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
# TODO: Might also require checking if touchpad is present on machine, and if result can be captured as C++ acts different
$result = [Touchpad32Functions]::SystemParametersInfo(0x00AE, 0, [ref]$touchpad, 0) # SPI_GETTOUCHPADPARAMETERS
$err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($err -ne 0) {
throw [System.ComponentModel.Win32Exception]::new($err)
}
Copy link
Collaborator

@stephengillie stephengillie Feb 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...error code 87.

From the website:

ERROR_INVALID_PARAMETER: The parameter is incorrect.

On my laptop, which has a touchpad, I get code 203: The system could not find the environment option that was entered. I'm having difficulty finding documentation of the Touchpad32Functions assembly, which complicates troubleshooting.

I did locate another set of Touchpad settings, under HKCU:\Software\Microsoft\Windows\CurrentVersion\PrecisionTouchPad:

First, the enabled/disabled switch is in a subfolder:

PS C:\ManVal> Get-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\PrecisionTouchPad\Status\
Enabled : 1

And the rest of the settings are in the main folder:

PS C:\ManVal> Get-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\PrecisionTouchPad
AAPThreshold : 2
CursorSpeed : 10
ScrollDirection : 0
EnableEdgy : 4294967295
LeaveOnWithMouse : 0
PanEnabled : 4294967295
RightClickZoneEnabled : 0
TapAndDrag : 0
TapsEnabled : 4294967295
TwoFingerTapEnabled : 0
ZoomEnabled : 4294967295
HonorMouseAccelSetting : 0
FeedbackIntensity : 50
FeedbackEnabled : 4294967295
ThreeFingerSlideEnabled : 0
ThreeFingerTapEnabled : 0
FourFingerSlideEnabled : 0
FourFingerTapEnabled : 0
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\PrecisionTouchPad

Copy link
Contributor Author

Gijsreyn commented Feb 8, 2025

Hi @Gijsreyn,

Apologies for experimenting with your module instead of one of my own. In reviewing your very well-formatted code, I kept seeing the code patterns stand out and wanted to express them in a more compact way. Please let me know what you think.

Hey @stephengillie, thanks for hopping in. Yes, that's what I noticed as well, and I didn't really like it. There's so much overlap in each module, and Demitrius mentioned one sentence back about having the modules move toward the DSC community. That sentence remained with me.

Having said that, I had some time spent investigating the class-based development within the DSC community. It was a bit tough to get started, but I finally managed to get a mock setup, and I feel it's a way better approach with modularity included. I demoed this during the last community call as a sneak peek, and I intend to move most of the content that I have PRed here to that module.

image

Basically, the 010.SettingsBase.ps1 contains a class that can be inherited across (nearly) all settings unless they don't contain 0 or 1 values as DWORDS (still thinking about it to expand). Others can be more self-contained.

The repository is still private, but if you and @denelon want access to it, just give me a heads-up. I'm just letting you know that I'll not spend much time around this repository, and I guess most PRs can be abandoned.

Lastly, on the touchpad settings. Thanks for the deep dive and yes, I think I noticed these settings also. The thing is, you can change them in the registry, but the user would still have to log out and log back in. That's why I wanted to use the API to get the values and set it using that. Anyway, if you've someone internal who might be able to help out, that would be pretty cool :)

stephengillie reacted with heart emoji

Copy link
Collaborator

denelon commented Feb 10, 2025

@Gijsreyn one thing to note about my comment is that the "Microsoft" specific resources wouldn't be in scope to move to the DSC Community. Several folks have expressed concerns about digitally signed modules. In order for the Microsoft resources to be signed by Microsoft, they need to come from a Microsoft maintained project.

Copy link
Contributor Author

Gijsreyn commented Feb 10, 2025
edited
Loading

@Gijsreyn one thing to note about my comment is that the "Microsoft" specific resources wouldn't be in scope to move to the DSC Community. Several folks have expressed concerns about digitally signed modules. In order for the Microsoft resources to be signed by Microsoft, they need to come from a Microsoft maintained project.

Auch, then I'm feeling a bit stuck here, and I'm not sure how to contribute further. I guess that's about 70% to 80% of the modules here. The only ones that would probably participate are Python, Npm, etc. I still want to contribute and especially bring in some professionalization and standardization in here @denelon , as Stephen also mentioned. Yet, the approach is vague for me what the best way would be. I can hit up the sources that I've created for the community in this repository to get all the sweetness from the community in here if that's desirable. That only would require the pipeline to be adjusted.

Copy link
Collaborator

denelon commented Feb 13, 2025

Yes, and @AmelBawa-msft is looking at the pipelines so we can iterate a bit more quickly here.

Copy link
Contributor Author

@denelon Do note, when the module is built through Sampler, it also includes the DscResource.Base and DscResource.Common. Is that something we want to sign during packaging?

image

Copy link
Collaborator

denelon commented Feb 13, 2025

If it's coming out of the "build" from this project, it's likely we will need/want to sign.

Copy link
Contributor Author

Alright, I'll try to hit something up hopefully this weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

1 more reviewer

@stephengillie stephengillie stephengillie left review comments

Reviewers whose approvals may not affect merge requirements

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /