Skip to content

Commit

Permalink
SSD sensors, monitoring update.
Browse files Browse the repository at this point in the history
  • Loading branch information
T-Troll committed Sep 6, 2022
1 parent 0243301 commit 2e0319b
Show file tree
Hide file tree
Showing 28 changed files with 466 additions and 502 deletions.
5 changes: 5 additions & 0 deletions AlienFX-SDK/AlienFX_SDK.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlienFX_SDK_noACPI", "Alien
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alienfan-low", "..\alienfan-tools\alienfan-SDK\alienfan-low\alienfan-low.vcxproj", "{CC889C0D-369A-46F0-87B2-956DA96DDEFD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{71195927-9D2B-4898-96B8-4DB3296FA5C2}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
CheckDevices\CheckDevices.vcxitems*{685645dc-a6fb-47c6-a1bb-deed0d1b465c}*SharedItemsImports = 4
Expand Down
251 changes: 117 additions & 134 deletions AlienFX-SDK/AlienFX_SDK/AlienFX_SDK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,104 +148,92 @@ namespace AlienFX_SDK {
//Use this method for general devices, vid = 0 for any vid, pid = -1 for any pid. Do not use at the same time!
int Functions::AlienFXInitialize(int vid, int pidd) {
GUID guid;
bool flag = false;
bool flag = true;
pid = -1;
DWORD dw = 0;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData{ sizeof(SP_DEVICE_INTERFACE_DATA) };

HidD_GetHidGuid(&guid);
HDEVINFO hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE) {
return pid;
}
unsigned int dw = 0;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData{sizeof(SP_DEVICE_INTERFACE_DATA)};

while (!flag) {
if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, dw, &deviceInterfaceData)) {
flag = true;
continue;
}
dw++;
DWORD dwRequiredSize = 0;
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &dwRequiredSize, NULL)) {
continue;
}
if (hDevInfo != INVALID_HANDLE_VALUE) {
while (flag && SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, dw, &deviceInterfaceData)) {
dw++;
DWORD dwRequiredSize = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &dwRequiredSize, NULL);

std::unique_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA> deviceInterfaceDetailData((SP_DEVICE_INTERFACE_DETAIL_DATA*)new char[dwRequiredSize]);
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, deviceInterfaceDetailData.get(), dwRequiredSize, NULL, NULL)) {
if ((devHandle = CreateFile(deviceInterfaceDetailData->DevicePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL)) != INVALID_HANDLE_VALUE) {
std::unique_ptr<HIDD_ATTRIBUTES> attributes(new HIDD_ATTRIBUTES);
attributes->Size = sizeof(HIDD_ATTRIBUTES);
if (HidD_GetAttributes(devHandle, attributes.get())) {
if (((!vid || attributes->VendorID == vid) && (pidd == -1 || attributes->ProductID == pidd))) {
// Check API version...
PHIDP_PREPARSED_DATA prep_caps;
HIDP_CAPS caps;
HidD_GetPreparsedData(devHandle, &prep_caps);
HidP_GetCaps(prep_caps, &caps);
HidD_FreePreparsedData(prep_caps);

std::unique_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA> deviceInterfaceDetailData((SP_DEVICE_INTERFACE_DETAIL_DATA *)new char[dwRequiredSize]);
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, deviceInterfaceDetailData.get(), dwRequiredSize, NULL, NULL)) {
string devicePath = deviceInterfaceDetailData->DevicePath;
devHandle = CreateFile(devicePath.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);

if (devHandle != INVALID_HANDLE_VALUE) {
std::unique_ptr<HIDD_ATTRIBUTES> attributes(new HIDD_ATTRIBUTES);
attributes->Size = sizeof(HIDD_ATTRIBUTES);
if (HidD_GetAttributes(devHandle, attributes.get())) {
if (((!vid || attributes->VendorID == vid) && (pidd == -1 || attributes->ProductID == pidd))) {
// Check API version...
PHIDP_PREPARSED_DATA prep_caps;
HIDP_CAPS caps;
HidD_GetPreparsedData(devHandle, &prep_caps);
HidP_GetCaps(prep_caps, &caps);
HidD_FreePreparsedData(prep_caps);

if (caps.OutputReportByteLength || caps.Usage == 0xcc) {

// Yes, now so easy...
length = caps.OutputReportByteLength;
reportID = 0;
switch (caps.OutputReportByteLength) {
case 0:
length = caps.FeatureReportByteLength;
version = API_L_V5;
reportID = 0xcc;
break;
case 8:
version = API_L_V1;
reportID = 2;
break;
case 9:
version = API_L_V2;
reportID = 2;
break;
case 12:
version = API_L_V3;
reportID = 2;
break;
case 34:
version = API_L_V4;
break;
case 65:
switch (attributes->VendorID) {
case 0x0424: case 0x187c:
version = API_L_V6;
// device init
//PrepareAndSend(COMMV6.colorReset, sizeof(COMMV6.colorReset));
if (caps.OutputReportByteLength || caps.Usage == 0xcc) {
length = caps.OutputReportByteLength;
reportID = 0;
switch (caps.OutputReportByteLength) {
case 0:
length = caps.FeatureReportByteLength;
version = API_L_V5;
reportID = 0xcc;
break;
case 0x0461:
version = API_L_V7;
case 8:
version = API_L_V1;
reportID = 2;
break;
case 0x04f2:
version = API_L_V8;
reportID = 0xe;
case 9:
version = API_L_V2;
reportID = 2;
break;
case 12:
version = API_L_V3;
reportID = 2;
break;
case 34:
version = API_L_V4;
break;
case 65:
switch (attributes->VendorID) {
case 0x0424: case 0x187c:
version = API_L_V6;
// device init
PrepareAndSend(COMMV6.colorReset, sizeof(COMMV6.colorReset));
break;
case 0x0461:
version = API_L_V7;
break;
case 0x04f2:
version = API_L_V8;
reportID = 0xe;
break;
}
break;
//default: length = caps.OutputReportByteLength;
}
break;
//default: length = caps.OutputReportByteLength;
}

this->vid = attributes->VendorID;
pid = attributes->ProductID;
flag = true;
this->vid = attributes->VendorID;
pid = attributes->ProductID;
flag = false;
}
}
}
if (flag)
CloseHandle(devHandle);
}
if (!flag)
CloseHandle(devHandle);
}
deviceInterfaceDetailData.release();
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return pid;
}

Expand Down Expand Up @@ -285,7 +273,7 @@ namespace AlienFX_SDK {
bool result = false;
switch (version) {
case API_L_V6:
result = PrepareAndSend(COMMV6.colorReset, sizeof(COMMV6.colorReset));
//result = PrepareAndSend(COMMV6.colorReset, sizeof(COMMV6.colorReset));
break;
case API_L_V5:
{
Expand Down Expand Up @@ -503,6 +491,18 @@ namespace AlienFX_SDK {
if (save)
break;
byte bPos = 5, cnt = 1;
// set indicators second light
// vector<byte> indi;
//for (auto nc = act->begin(); nc != act->end(); nc++)
// switch (nc->index) {
// case 0x19: case 0x28: case 0xb3:
// indi.push_back(nc->index);
// }
//if (indi.size()) {
// SetMultiLights(&indi, { 0,0,255 });
// SetColor(0, { 0 });
//}

PrepareAndSend(COMMV8.readyToColor, sizeof(COMMV8.readyToColor), { {2,(byte)act->size()} });
for (auto nc = act->begin(); nc != act->end(); nc++)
if (bPos < length) {
Expand Down Expand Up @@ -541,13 +541,6 @@ namespace AlienFX_SDK {
mods.push_back({ 4, cnt });
val = PrepareAndSend(COMMV8.colorSet, sizeof(COMMV8.colorSet), &mods);
}
// now set indicators second light
//for (auto nc = act->begin(); nc != act->end(); nc++)
// switch (nc->index) {
// case 0x19: case 0x28: case 0xb3:
// SetColor(nc->index, { nc->act[0].b, nc->act[0].g, nc->act[0].r });
// }

} break;
case API_L_V7:
{
Expand Down Expand Up @@ -1141,65 +1134,55 @@ namespace AlienFX_SDK {
vector<pair<WORD, WORD>> Mappings::AlienFXEnumDevices() {
vector<pair<WORD, WORD>> pids;
GUID guid;
bool flag = false;
HANDLE tdevHandle;

HidD_GetHidGuid(&guid);
HDEVINFO hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE) {
return pids;
}
unsigned int dw = 0;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;

while (!flag) {
if (hDevInfo != INVALID_HANDLE_VALUE) {
DWORD dw = 0;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, dw, &deviceInterfaceData)) {
flag = true;
continue;
}
dw++;
DWORD dwRequiredSize = 0;
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &dwRequiredSize, NULL)) {
continue;
}
std::unique_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA> deviceInterfaceDetailData((SP_DEVICE_INTERFACE_DETAIL_DATA *)new char[dwRequiredSize]);
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, deviceInterfaceDetailData.get(), dwRequiredSize, NULL, NULL)) {
string devicePath = deviceInterfaceDetailData->DevicePath;
tdevHandle = CreateFile(devicePath.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

if (tdevHandle != INVALID_HANDLE_VALUE) {
std::unique_ptr<HIDD_ATTRIBUTES> attributes(new HIDD_ATTRIBUTES);
attributes->Size = sizeof(HIDD_ATTRIBUTES);
if (HidD_GetAttributes(tdevHandle, attributes.get())) {
for (unsigned i = 0; i < NUM_VIDS; i++) {
if (attributes->VendorID == vids[i]) {
PHIDP_PREPARSED_DATA prep_caps;
HIDP_CAPS caps;
HidD_GetPreparsedData(tdevHandle, &prep_caps);
HidP_GetCaps(prep_caps, &caps);
HidD_FreePreparsedData(prep_caps);

if (caps.OutputReportByteLength || caps.Usage == 0xcc) {
while (SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, dw, &deviceInterfaceData)) {
dw++;
DWORD dwRequiredSize = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &dwRequiredSize, NULL);
std::unique_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA> deviceInterfaceDetailData((SP_DEVICE_INTERFACE_DETAIL_DATA*)new char[dwRequiredSize]);
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, deviceInterfaceDetailData.get(), dwRequiredSize, NULL, NULL)) {
if ((tdevHandle = CreateFile(deviceInterfaceDetailData->DevicePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) {
std::unique_ptr<HIDD_ATTRIBUTES> attributes(new HIDD_ATTRIBUTES);
attributes->Size = sizeof(HIDD_ATTRIBUTES);
if (HidD_GetAttributes(tdevHandle, attributes.get())) {
for (unsigned i = 0; i < NUM_VIDS; i++) {
if (attributes->VendorID == vids[i]) {
PHIDP_PREPARSED_DATA prep_caps;
HIDP_CAPS caps;
HidD_GetPreparsedData(tdevHandle, &prep_caps);
HidP_GetCaps(prep_caps, &caps);
HidD_FreePreparsedData(prep_caps);

if (caps.OutputReportByteLength || caps.Usage == 0xcc) {
#ifdef _DEBUG
char buff[2048];
sprintf_s(buff, 2047, "Scan: VID: %#x, PID: %#x, Version: %d, Length: %d\n",
attributes->VendorID, attributes->ProductID, attributes->VersionNumber, attributes->Size);
OutputDebugString(buff);
printf("%s", buff);
char buff[2048];
sprintf_s(buff, 2047, "Scan: VID: %#x, PID: %#x, Version: %d, Length: %d\n",
attributes->VendorID, attributes->ProductID, attributes->VersionNumber, attributes->Size);
OutputDebugString(buff);
printf("%s", buff);
#endif
pids.push_back({attributes->VendorID,attributes->ProductID});
break;
pids.push_back({ attributes->VendorID,attributes->ProductID });
break;
}
}
}
}
CloseHandle(tdevHandle);
}
CloseHandle(tdevHandle);
}
deviceInterfaceDetailData.release();
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return pids;
}

Expand Down
19 changes: 13 additions & 6 deletions AlienFX-SDK/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@
Better AlienFX/LightFX SDK than Dell official's one without any limitations.

Dell official SDK does a very terrible job if you want to change LED color in quick succession. Their official SDK comes with 3 seconds delay and behaves pretty weird in general.
This SDK not only fixes up its issue and performs better but is written from scratch by reverse engineerig USB protocol. It sends byte data directly to USB which then changes zones color. This also removes the dependency from their Command Center software and works irrespective of settings set in stock software. In other words, you can finally achieve Rainbow effect across all LED's like it was intended without any lag. This SDK also lets you change color of zones that are not possible with official SDK such as Macro keys, power button etc.
This SDK not only fixes up its issue and performs better but is written from scratch by reverse engineering USB protocol. It sends byte data directly to USB which then changes zones color. This also removes the dependency from their Command Center software and works irrespective of settings set in stock software. In other words, you can finally achieve Rainbow effect across all LED's like it was intended without any lag. This SDK also lets you change color of zones that are not possible with official SDK such as Macro keys, power button etc.

Please checkout Sample App for reference.

**Currently tested on AW13/R2, AW13/R3, AWM14x, AW15R2/R3, AW17R3/R4, AWm15/R1-R4, AWm17/R1, Dell G5/G7, AWAurora/R7, but should work at any alienware laptop or desktop.**
### Supported devices:

Any Alienware/Dell G-series hardware with RGB lights from 2010 to 2022. Including mouses, keyboards, monitors.
Read more details about supported devices and models [here](https://github.com/T-Troll/alienfx-tools/wiki/Supported-and-tested-devices-list)

### Supported device API versions:
- ACPI-controlled lights - 3 lights, 8 bit/color (v0) - using this API require low-level ACPI driver and library from [Alienfan](https://github.com/T-Troll/alienfan-tools) project.

- ACPI-controlled lights - 3 lights, 8 bit/color (v0) - using this API require AlienFan-SDK library from [AlienFX-Tools](https://github.com/T-Troll/alienfx-tools) project.
- 9 bytes 8 bit/color, reportID 2 control (v1)
- 9 bytes 4 bit/color, reportID 2 control (v2)
- 12 bytes 8 bit/color, reportID 2 control (v3)
- 34 bytes 8 bit/color, reportID 0 control (v4)
- 64 bytes 8 bit/color, featureID 0xcc control (v5)
- 65 bytes 8 bit/color, interrupt control (v6)
- 65 bytes 8 bit/color, featureID control (v7)
- 65 bytes 8 bit/color, Interrupt control (v8)

Some notebooks have 2 devices - APIv4 (for logo, power button, etc) and APIv5 for keyboard.

Expand All @@ -25,8 +32,8 @@ Some notebooks have 2 devices - APIv4 (for logo, power button, etc) and APIv5 fo
- Change multiply lights color
- Change light hardware effect (except APIv5)
- Change multiply lights hardware effects (except APIv5)
- Hardware-backed global light off/on/dim (dim is software for APIv0-v3 and should be done by application)
- Global hardware light effects (APIv5)
- Hardware-backed global light off/on/dim (dim is software for APIv0-v3 and v6 and should be done by application)
- Global hardware light effects (APIv5, v8)

### Initialization
```C++
Expand Down Expand Up @@ -71,7 +78,7 @@ AlienFX_SDK::Functions::SetColor(6, 25, 114, 245);
AlienFX_SDK::Functions::UpdateColors();
```
### Test app
After buildng, you can find simple probe app `AlienFXDeviceTester` - it shows information about device found into the system. If device supported, it reveals SDK type and version.
After building, you can find simple probe app `AlienFXDeviceTester` - it shows information about device found into the system. If device supported, it reveals SDK type and version.
### Projects using this SDK
Expand Down
Loading

0 comments on commit 2e0319b

Please sign in to comment.