@@ -17,6 +17,8 @@ Module Name:
1717#include "driver.h"
1818#include "EcCommunication.h"
1919#include "device.tmh"
20+ #define _USE_MATH_DEFINES
21+ #include <math.h>
2022
2123//
2224// This is the default report descriptor for the virtual Hid device returned
@@ -200,6 +202,81 @@ HID_DESCRIPTOR G_DefaultHidDescriptor = {
200202 }
201203};
202204
205+ NTSTATUS
206+ CalculateLampPositions (
207+ PDEVICE_CONTEXT DeviceContext ,
208+ UINT16 LampCount ,
209+ UINT8 LedArrangement
210+ )
211+ {
212+ UINT8 Layers = 0 ;
213+ double centerX = 40000.0 ;
214+ double centerY = 40000.0 ;
215+ double radius = 40000.0 ;
216+
217+ TraceInformation ("%!FUNC! LampCount: %d, LedArrangement: %d" , LampCount , LedArrangement );
218+
219+ if (LampCount == 0 ) {
220+ TraceError ("LampCount is 0" );
221+ return STATUS_INVALID_PARAMETER ;
222+ }
223+ if (LampCount > MAX_LAMPARRAY_LAMP_COUNT ) {
224+ TraceError ("LampCount %d over %d" , LampCount , MAX_LAMPARRAY_LAMP_COUNT );
225+ return STATUS_INVALID_PARAMETER ;
226+ }
227+
228+ switch (LedArrangement ) {
229+ // Circular, layers of 8
230+ case 0 :
231+ DeviceContext -> Width = 80000 ;
232+ DeviceContext -> Height = 80000 ;
233+ DeviceContext -> Depth = 2000 * (LampCount / 8 );
234+ // Place LampCount LEDs evenly spaced around a circle of radius 40000 (centered at 40000,40000) in layers of 8
235+ for (UINT8 i = 0 ; i < LampCount ; i ++ ) {
236+ double angle = (2.0 * M_PI * (i % 8 )) / 8 ;
237+ DeviceContext -> LampPositions [i ].x = (UINT32 )(centerX + radius * cos (angle ));
238+ DeviceContext -> LampPositions [i ].y = (UINT32 )(centerY + radius * sin (angle ));
239+ DeviceContext -> LampPositions [i ].z = 2000 * i ;
240+ }
241+ break ;
242+ // LEDs arranged in a circle single layer, even distance from each other
243+ case 1 :
244+ DeviceContext -> Width = 80000 ;
245+ DeviceContext -> Height = 80000 ;
246+ // Place LampCount LEDs evenly spaced around a circle of radius 40000 (centered at 40000,40000)
247+ for (UINT8 i = 0 ; i < LampCount ; i ++ ) {
248+ double angle = (2.0 * M_PI * i ) / LampCount ;
249+ DeviceContext -> LampPositions [i ].x = (UINT32 )(centerX + radius * cos (angle ));
250+ DeviceContext -> LampPositions [i ].y = (UINT32 )(centerY + radius * sin (angle ));
251+ }
252+ break ;
253+ // Linear, LED strip with 5mm distance
254+ case 2 :
255+ DeviceContext -> Width = LampCount * 5000 ;
256+ DeviceContext -> Height = 0 ;
257+ for (UINT8 i = 0 ; i <= LampCount ; i ++ ) {
258+ DeviceContext -> LampPositions [i ].x = i * 5000 ;
259+ DeviceContext -> LampPositions [i ].y = 0 ;
260+ }
261+ break ;
262+ // Square Matrix with 5mm distance
263+ case 3 :
264+ Layers = (UINT8 ) sqrt ((double ) LampCount );
265+ DeviceContext -> Width = Layers * 5000 ;
266+ DeviceContext -> Height = Layers * 5000 ;
267+ for (UINT8 i = 0 ; i <= LampCount ; i ++ ) {
268+ DeviceContext -> LampPositions [i ].x = (i % Layers ) * 5000 ;
269+ DeviceContext -> LampPositions [i ].y = (i / Layers ) * 5000 ;
270+ }
271+ break ;
272+ default :
273+ TraceError ("LedArrangement %d invalid." , LedArrangement );
274+ return STATUS_INVALID_PARAMETER ;
275+ }
276+
277+ return STATUS_SUCCESS ;
278+ }
279+
203280NTSTATUS
204281FrameworkArgbCreateDevice (
205282 _Inout_ PWDFDEVICE_INIT DeviceInit
@@ -227,6 +304,7 @@ Return Value:
227304 PHID_DEVICE_ATTRIBUTES hidAttributes ;
228305 WDFDEVICE device ;
229306 NTSTATUS status ;
307+ UINT8 LedArrangement ;
230308
231309 TraceInformation ("%!FUNC! Entry" );
232310
@@ -261,28 +339,35 @@ Return Value:
261339 deviceContext -> Device = device ;
262340 deviceContext -> CurrentLampId = 0 ;
263341 deviceContext -> AutonomousMode = TRUE;
264- // 8 LEDs in a circle
265- // z is 0 for all LEDs, they're all in the same plane
266- // Bottom LED
267- deviceContext -> LampPositions [0 ].x = 40000 ;
268- deviceContext -> LampPositions [0 ].y = 0 ;
269- deviceContext -> LampPositions [1 ].x = 60000 ;
270- deviceContext -> LampPositions [1 ].y = 20000 ;
271- // Right LED
272- deviceContext -> LampPositions [2 ].x = 80000 ;
273- deviceContext -> LampPositions [2 ].y = 40000 ;
274- deviceContext -> LampPositions [3 ].x = 60000 ;
275- deviceContext -> LampPositions [3 ].y = 60000 ;
276- // Top LED
277- deviceContext -> LampPositions [4 ].x = 40000 ;
278- deviceContext -> LampPositions [4 ].y = 80000 ;
279- deviceContext -> LampPositions [5 ].x = 20000 ;
280- deviceContext -> LampPositions [5 ].y = 60000 ;
281- // Left LED
282- deviceContext -> LampPositions [6 ].x = 0 ;
283- deviceContext -> LampPositions [6 ].y = 40000 ;
284- deviceContext -> LampPositions [7 ].x = 20000 ;
285- deviceContext -> LampPositions [7 ].y = 20000 ;
342+
343+ deviceContext -> LampCount = 0 ;
344+ deviceContext -> Width = 0 ;
345+ deviceContext -> Height = 0 ;
346+ deviceContext -> Depth = 2000 ;
347+ LedArrangement = 0 ;
348+ status = CheckRegistryForLedConfig (device );
349+ if (NT_SUCCESS (status )) {
350+ //
351+ // We need to read read descriptor from registry
352+ //
353+ status = ReadLedConfigFromRegistry (device , & deviceContext -> LampCount , & LedArrangement );
354+ if (!NT_SUCCESS (status )) {
355+ TraceError ("Failed to read LED config from registry\n" );
356+ }
357+ }
358+
359+ // Default 8 LED fan
360+ if (deviceContext -> LampCount == 0 ) {
361+ TraceError ("No lamps set, falling back to default" );
362+ deviceContext -> LampCount = 8 ;
363+ LedArrangement = 0 ;
364+ }
365+
366+ status = CalculateLampPositions (deviceContext , deviceContext -> LampCount , LedArrangement );
367+ if (!NT_SUCCESS (status )) {
368+ TraceError ("Failed to calulcate lamp positions\n" );
369+ deviceContext -> LampCount = 0 ;
370+ }
286371
287372 hidAttributes = & deviceContext -> HidDeviceAttributes ;
288373 RtlZeroMemory (hidAttributes , sizeof (HID_DEVICE_ATTRIBUTES ));
@@ -526,3 +611,127 @@ Return Value:
526611 status = RequestCopyFromBuffer (Request , string , stringSizeCb );
527612 return status ;
528613}
614+
615+ NTSTATUS
616+ CheckRegistryForLedConfig (
617+ WDFDEVICE Device
618+ )
619+ /*++
620+
621+ Routine Description:
622+
623+ Read "ReadFromRegistry" key value from device parameters in the registry.
624+
625+ Arguments:
626+
627+ device - pointer to a device object.
628+
629+ Return Value:
630+
631+ NT status code.
632+
633+ --*/
634+
635+ {
636+ WDFKEY hKey = NULL ;
637+ NTSTATUS status ;
638+ UNICODE_STRING valueName ;
639+ ULONG value ;
640+
641+ TraceInformation ("%!FUNC! Entry" );
642+ //
643+ // If this fails, AppVerifier shows an error
644+ // RegOpenKeyExW: Key (\REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\WUDFx02000) is denied 'READ_CONTROL KEY_QUERY_VALUE KEY_ENUMERATE_SUB_KEYS KEY_NOTIFY' access with error 0x2
645+ status = WdfDeviceOpenRegistryKey (Device ,
646+ PLUGPLAY_REGKEY_DEVICE ,
647+ KEY_READ ,
648+ WDF_NO_OBJECT_ATTRIBUTES ,
649+ & hKey );
650+ if (NT_SUCCESS (status )) {
651+ TraceInformation ("%!FUNC! Found driver Registry key" );
652+ RtlInitUnicodeString (& valueName , L"ReadFromRegistry" );
653+
654+ status = WdfRegistryQueryULong (hKey ,
655+ & valueName ,
656+ & value );
657+
658+ if (NT_SUCCESS (status )) {
659+ TraceInformation ("%!FUNC! ReadFromRegistry has value: %d" , value );
660+ if (value == 0 ) {
661+ status = STATUS_UNSUCCESSFUL ;
662+ }
663+ }
664+
665+ WdfRegistryClose (hKey );
666+ }
667+
668+ TraceInformation ("%!FUNC! Exiting with %!STATUS!" , status );
669+ return status ;
670+ }
671+
672+ NTSTATUS
673+ ReadLedConfigFromRegistry (
674+ WDFDEVICE Device ,
675+ UINT16 * LampCount ,
676+ UINT8 * LedArrangement
677+ )
678+ /*++
679+
680+ Routine Description:
681+
682+ Read LED config report descriptor from registry
683+
684+ Arguments:
685+
686+ device - pointer to a device object.
687+
688+ Return Value:
689+
690+ NT status code.
691+
692+ --*/
693+ {
694+ WDFKEY hKey = NULL ;
695+ NTSTATUS status ;
696+ UNICODE_STRING valueName ;
697+ PDEVICE_CONTEXT deviceContext ;
698+ ULONG value ;
699+
700+ TraceInformation ("%!FUNC! Entry" );
701+ deviceContext = GetDeviceContext (Device );
702+
703+ status = WdfDeviceOpenRegistryKey (Device ,
704+ PLUGPLAY_REGKEY_DEVICE ,
705+ KEY_READ ,
706+ WDF_NO_OBJECT_ATTRIBUTES ,
707+ & hKey );
708+
709+ if (!NT_SUCCESS (status )) {
710+ TraceError ("%!FUNC! Failed to find driver registry key" );
711+ return status ;
712+ }
713+
714+ RtlInitUnicodeString (& valueName , L"LedCount" );
715+ status = WdfRegistryQueryULong (hKey , & valueName , & value );
716+ if (!NT_SUCCESS (status )) {
717+ TraceError ("%!FUNC! Failed to WdfRegistryQueryULong LedCount: %!STATUS!" , status );
718+ WdfRegistryClose (hKey );
719+ return status ;
720+ }
721+ TraceInformation ("%!FUNC! LedCount has value: %d" , value );
722+ * LampCount = (UINT8 ) value ;
723+
724+ RtlInitUnicodeString (& valueName , L"LedArrangement" );
725+ status = WdfRegistryQueryULong (hKey , & valueName , & value );
726+ if (!NT_SUCCESS (status )) {
727+ TraceError ("%!FUNC! Failed to WdfRegistryQueryULong LedArrangement: %!STATUS!" , status );
728+ WdfRegistryClose (hKey );
729+ return status ;
730+ }
731+ TraceInformation ("%!FUNC! LedArrangement has value: %d" , value );
732+ * LedArrangement = (UINT8 ) value ;
733+
734+ WdfRegistryClose (hKey );
735+
736+ return status ;
737+ }
0 commit comments