diff --git a/sdk/Windows/Helpers.cpp b/sdk/Windows/Helpers.cpp index 1fb8021..0700b11 100644 --- a/sdk/Windows/Helpers.cpp +++ b/sdk/Windows/Helpers.cpp @@ -202,6 +202,22 @@ double SMX::GetMonotonicTime() return iTime / 10000000.0; } +void SMX::GenerateRandom(void *pOut, int iSize) +{ + // These calls shouldn't fail. + HCRYPTPROV cryptProv; + if(!CryptAcquireContext(&cryptProv, nullptr, + L"Microsoft Base Cryptographic Provider v1.0", + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + throw exception("CryptAcquireContext error"); + + if(!CryptGenRandom(cryptProv, iSize, (BYTE *) pOut)) + throw exception("CryptGenRandom error"); + + if(!CryptReleaseContext(cryptProv, 0)) + throw exception("CryptReleaseContext error"); +} + const char *SMX::CreateError(string error) { // Store the string in a static so it doesn't get deallocated. diff --git a/sdk/Windows/Helpers.h b/sdk/Windows/Helpers.h index b9b90f8..8b5dddf 100644 --- a/sdk/Windows/Helpers.h +++ b/sdk/Windows/Helpers.h @@ -26,6 +26,7 @@ string BinaryToHex(const void *pData_, int iNumBytes); string BinaryToHex(const string &sString); bool GetRandomBytes(void *pData, int iBytes); double GetMonotonicTime(); +void GenerateRandom(void *pOut, int iSize); // Create a char* string that will be valid until the next call to CreateError. // This is used to return error messages to the caller. diff --git a/sdk/Windows/SMX.cpp b/sdk/Windows/SMX.cpp index 4df2ac9..a943199 100644 --- a/sdk/Windows/SMX.cpp +++ b/sdk/Windows/SMX.cpp @@ -99,5 +99,6 @@ SMX_API void SMX_SetLights2(const char *lightData, int lightDataSize) SMX_API void SMX_ReenableAutoLights() { SMXManager::g_pSMX->ReenableAutoLights(); } SMX_API const char *SMX_Version() { return SMX_BUILD_VERSION; } -// This isn't exposed in the public API, since this is only used internally. +// These aren't exposed in the public API, since they're only used internally. SMX_API void SMX_SetOnlySendLightsOnChange(bool value) { SMXManager::g_pSMX->SetOnlySendLightsOnChange(value); } +SMX_API void SMX_SetSerialNumbers() { SMXManager::g_pSMX->SetSerialNumbers(); } diff --git a/sdk/Windows/SMXManager.cpp b/sdk/Windows/SMXManager.cpp index d39388e..952996d 100644 --- a/sdk/Windows/SMXManager.cpp +++ b/sdk/Windows/SMXManager.cpp @@ -581,6 +581,29 @@ void SMX::SMXManager::UpdatePanelTestMode() m_pDevices[iPad]->SendCommandLocked(ssprintf("t %c\n", m_PanelTestMode)); } +// Assign a serial number to master controllers if one isn't already assigned. This +// will have no effect if a serial is already set. +// +// We just assign a random number. The serial number will be used as the USB serial +// number, and can be queried in SMXInfo. +void SMX::SMXManager::SetSerialNumbers() +{ + g_Lock.AssertNotLockedByCurrentThread(); + LockMutex L(g_Lock); + + m_aPendingLightsCommands.clear(); + for(int iPad = 0; iPad < 2; ++iPad) + { + string sData = "s"; + uint8_t serial[16]; + SMX::GenerateRandom(serial, sizeof(serial)); + sData.append((char *) serial, sizeof(serial)); + sData.append(1, '\n'); + + m_pDevices[iPad]->SendCommandLocked(sData); + } +} + void SMX::SMXManager::RunInHelperThread(function func) { m_UserCallbackThread.RunInThread(func); diff --git a/sdk/Windows/SMXManager.h b/sdk/Windows/SMXManager.h index cf64fe0..9154061 100644 --- a/sdk/Windows/SMXManager.h +++ b/sdk/Windows/SMXManager.h @@ -46,6 +46,7 @@ public: void SetLights(const string sLights[2]); void ReenableAutoLights(); void SetPanelTestMode(PanelTestMode mode); + void SetSerialNumbers(); void SetOnlySendLightsOnChange(bool value) { m_bOnlySendLightsOnChange = value; } // Run a function in the user callback thread.