Skip to content

Commit fb02e2f

Browse files
Merge pull request #4 from FrameworkComputer/led-config
Customize LED config by registry settings
2 parents cbbd202 + 844cf56 commit fb02e2f

File tree

9 files changed

+448
-44
lines changed

9 files changed

+448
-44
lines changed

FrameworkArgb/Device.c

Lines changed: 231 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
203280
NTSTATUS
204281
FrameworkArgbCreateDevice(
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 &apos;READ_CONTROL KEY_QUERY_VALUE KEY_ENUMERATE_SUB_KEYS KEY_NOTIFY&apos; 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+
}

FrameworkArgb/Device.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ DRIVER_INITIALIZE DriverEntry;
2828
EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd;
2929
EVT_WDF_TIMER EvtTimerFunc;
3030

31-
#define LAMPARRAY_LAMP_COUNT 8
32-
#define LAMPARRAY_WIDTH 80000 // 80mm
33-
#define LAMPARRAY_HEIGHT 80000 // 80mm
34-
#define LAMPARRAY_DEPTH 20000 // 20mm
31+
#define MAX_LAMPARRAY_LAMP_COUNT 256
32+
//#define LAMPARRAY_WIDTH 80000 // 80mm
33+
//#define LAMPARRAY_HEIGHT 80000 // 80mm
34+
//#define LAMPARRAY_DEPTH 20000 // 20mm
3535
#define LAMPARRAY_KIND 0x07 // LampArrayKindChassis
3636
#define LAMPARRAY_UPDATE_INTERVAL 100000 // 10ms
3737

@@ -48,10 +48,13 @@ typedef struct _DEVICE_CONTEXT
4848
HANDLE CrosEcHandle;
4949
UINT16 CurrentLampId;
5050
BOOLEAN AutonomousMode;
51-
Position LampPositions[LAMPARRAY_LAMP_COUNT];
51+
UINT16 LampCount;
52+
UINT32 Width;
53+
UINT32 Height;
54+
UINT32 Depth;
55+
Position LampPositions[MAX_LAMPARRAY_LAMP_COUNT];
5256
HID_DESCRIPTOR HidDescriptor;
5357
PHID_REPORT_DESCRIPTOR ReportDescriptor;
54-
BOOLEAN ReadReportDescFromRegistry;
5558
} DEVICE_CONTEXT, * PDEVICE_CONTEXT;
5659

5760
//
@@ -168,6 +171,17 @@ RequestGetHidXferPacket_ToWriteToDevice(
168171
_Out_ HID_XFER_PACKET* Packet
169172
);
170173

174+
NTSTATUS
175+
CheckRegistryForLedConfig(
176+
_In_ WDFDEVICE Device
177+
);
178+
179+
NTSTATUS
180+
ReadLedConfigFromRegistry(
181+
_In_ WDFDEVICE Device,
182+
_Out_ UINT16 *LampCount,
183+
_Out_ UINT8 *LedArrangement
184+
);
171185

172186
//
173187
// Misc definitions
@@ -182,16 +196,6 @@ RequestGetHidXferPacket_ToWriteToDevice(
182196
#define FWK_ARGB_HID_PID 0x0033
183197
#define FWK_ARGB_HID_VERSION 0x0100
184198

185-
//
186-
// Custom control codes are defined here. They are to be used for sideband
187-
// communication with the hid minidriver. These control codes are sent to
188-
// the hid minidriver using Hid_SetFeature() API to a custom collection
189-
// defined especially to handle such requests.
190-
//
191-
#define FWK_ARGB_CONTROL_CODE_SET_ATTRIBUTES 0x00
192-
#define FWK_ARGB_CONTROL_CODE_DUMMY1 0x01
193-
#define FWK_ARGB_CONTROL_CODE_DUMMY2 0x02
194-
195199
#define LAMP_ARRAY_ATTRIBUTES_REPORT_ID 0x01
196200
#define LAMP_ATTRIBUTES_REQUEST_REPORT_ID 0x02
197201
#define LAMP_ATTRIBUTES_RESPONSE_REPORT_ID 0x03

FrameworkArgb/Driver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Return Value:
6262
#endif
6363

6464
TraceInformation("%!FUNC! Entry");
65+
// TODO: Print Registry path
6566

6667
//
6768
// Register a cleanup callback so that we can call WPP_CLEANUP when
@@ -74,6 +75,9 @@ Return Value:
7475
FrameworkArgbEvtDeviceAdd
7576
);
7677

78+
// AppVerifier shows the following errors
79+
// Could not convert Key security descriptor &apos;\REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\FrameworkArgb&apos; to text due to error 0x8
80+
// RegOpenKeyExW: Key (\REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\FrameworkArgb\Parameters\Wdf) is denied &apos;READ_CONTROL KEY_QUERY_VALUE KEY_ENUMERATE_SUB_KEYS KEY_NOTIFY&apos; access with error 0x2
7781
status = WdfDriverCreate(DriverObject,
7882
RegistryPath,
7983
&attributes,

FrameworkArgb/FrameworkArgb.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
126126
</DriverSign>
127127
<Inf>
128-
<TimeStamp>0.0.0.1</TimeStamp>
128+
<TimeStamp>0.0.0.2</TimeStamp>
129129
</Inf>
130130
</ItemDefinitionGroup>
131131
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

0 commit comments

Comments
 (0)