How to control master mixer volume in windows 7 using mixer api? - c++

In windows XP, it is quite easy to control master volume of a mixer device by setting volume of destination line using mixer api.It can be easily tested by sdk sample application provided by Microsoft.But in case of windows 7 whenever I open a mixer device in my application it shows it as new volume application and I am able to control only volume of my application.Not able to control complete sound of system.Can anyone suggest me how to control complete sound of speaker which will affect sound of all running application.
How can I change speakers volume using my application in windows 7 ?

I believe that the method you're looking for is SetMasterVolumeLevelScalar.
A short example in C (sorry for the lpVtbls):
BOOL AddMasterVolumeLevelScalar(float fMasterVolumeAdd)
{
IMMDeviceEnumerator *deviceEnumerator = NULL;
IMMDevice *defaultDevice = NULL;
IAudioEndpointVolume *endpointVolume = NULL;
HRESULT hr;
float fMasterVolume;
BOOL bSuccess = FALSE;
hr = CoCreateInstance(&XIID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &XIID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator);
if(SUCCEEDED(hr))
{
hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice);
if(SUCCEEDED(hr))
{
hr = defaultDevice->lpVtbl->Activate(defaultDevice, &XIID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
if(SUCCEEDED(hr))
{
if(SUCCEEDED(endpointVolume->lpVtbl->GetMasterVolumeLevelScalar(endpointVolume, &fMasterVolume)))
{
fMasterVolume += fMasterVolumeAdd;
if(fMasterVolume < 0.0)
fMasterVolume = 0.0;
else if(fMasterVolume > 1.0)
fMasterVolume = 1.0;
if(SUCCEEDED(endpointVolume->lpVtbl->SetMasterVolumeLevelScalar(endpointVolume, fMasterVolume, NULL)))
bSuccess = TRUE;
}
endpointVolume->lpVtbl->Release(endpointVolume);
}
defaultDevice->lpVtbl->Release(defaultDevice);
}
deviceEnumerator->lpVtbl->Release(deviceEnumerator);
}
return bSuccess;
}
In case the GUIDs are not defined:
const static GUID XIID_IMMDeviceEnumerator = { 0xA95664D2, 0x9614, 0x4F35, { 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6 } };
const static GUID XIID_MMDeviceEnumerator = { 0xBCDE0395, 0xE52F, 0x467C, { 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E } };
const static GUID XIID_IAudioEndpointVolume = { 0x5CDF2C82, 0x841E, 0x4546, { 0x97, 0x22, 0x0C, 0xF7, 0x40, 0x78, 0x22, 0x9A } };

Related

How to get the VP9 decoder from a C++ program on Hololens 2?

I am implementing a VP9 hardware decoder that will run on PC and Hololens 2.
When I try to load the "MSVP9DEC.dll", it works well on PC but the DLL is not found on Hololens.
I have installed the VP9 Video Extensions on the device.
Here the snipped code. The "assert(DecoderDll)" fails on Hololens:
HRESULT CreateCOMObjectFromDll(HMODULE dll,
const CLSID& clsid,
const IID& iid,
void** object);
void CreateVP9Decoder()
{
#if PLATFORM_HOLOLENS
HMODULE DecoderDll = ::LoadPackagedLibrary(L"MSVP9DEC.dll", 0ul);
#else
HMODULE DecoderDll = ::LoadLibrary(L"MSVP9DEC.dll");
#endif
assert(DecoderDll);
const GUID CLSID_VpxDecoder = { 0xE3AAF548, 0xC9A4, 0x4C6E, {0x23, 0x4D, 0x5A, 0xDA, 0x37, 0x4B, 0x00, 0x00 } };
Microsoft::WRL::ComPtr<IMFTransform> VP9Decoder;
HRESULT hr = CreateCOMObjectFromDll(DecoderDll, CLSID_VpxDecoder,
IID_PPV_ARGS(&VP9Decoder));
assert(SUCCEEDED(hr));
//...
}
__pragma(warning(push))
__pragma(warning(disable: 4191))
//#See: https://chromium.googlesource.com/chromium/src/+/master/media/gpu/windows/dxva_video_decode_accelerator_win.cc
HRESULT CreateCOMObjectFromDll(HMODULE dll,
const CLSID& clsid,
const IID& iid,
void** object) {
if (!dll || !object)
return E_INVALIDARG;
using GetClassObject =
HRESULT(WINAPI*)(const CLSID& clsid, const IID& iid, void** object);
GetClassObject get_class_object = reinterpret_cast<GetClassObject>(
GetProcAddress(dll, "DllGetClassObject"));
assert(get_class_object);
TComPtr<IClassFactory> factory;
HRESULT hr = get_class_object(clsid, IID_PPV_ARGS(&factory));
assert(SUCCEEDED(hr));
hr = factory->CreateInstance(NULL, iid, object);
return hr;
}
__pragma(warning(pop))
Thank you!
const GUID CLSID_VpxDecoder = { 0xE3AAF548, 0xC9A4, 0x4C6E, {0x23, 0x4D, 0x5A, 0xDA, 0x37, 0x4B, 0x00, 0x00 } };
IMFTransform* VP9Decoder;
MULTI_QI qi[1];
memset(qi, 0, sizeof(qi));
qi[0].pIID = &IID_PPV_ARGS(&VP9Decoder);
HRESULT hr = CoCreateInstanceFromApp(CLSID_VpxDecoder, NULL, CLSCTX_INPROC_SERVER, NULL, _countof(qi), qi);

Disable Aeroshake minimize by GPO

I'm trying to disable Aeroshake minimize mouse gesture only. Asked a question How to disable Aero Shake minimize only on Windows 7 but no answers. So I continued digging and found another solution by updating user Group Policy.
void aeroshake(DWORD action)
{
HRESULT hr;
IGroupPolicyObject* pLGPO;
HKEY machine_key, dsrkey;
LSTATUS sdf, ds, rStatus;
GUID RegistryId = REGISTRY_EXTENSION_GUID;
GUID ThisAdminToolGuid =
/*{ CLSID_PolicySnapinUser/* */
{
0x0F6B957E,
0x509E,
0x11D1,
{ 0xA7, 0xCC, 0x00, 0x00, 0xF8, 0x75, 0x71, 0xE3 }
};
const IID my_IID_IGroupPolicyObject =
{ 0xea502723, 0xa23d, 0x11d1,{ 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
const IID my_CLSID_GroupPolicyObject =
{ 0xea502722, 0xa23d, 0x11d1,{ 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
GUID ext_guid = REGISTRY_EXTENSION_GUID;
// This next one can be any GUID you want
GUID snap_guid = { 0x3d271cfc, 0x2bc6, 0x4ac2,{ 0xb6, 0x33, 0x3b, 0xdf, 0xf5, 0xbd, 0xab, 0x2a } };
// Create an instance of the IGroupPolicyObject class
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CoCreateInstance(my_CLSID_GroupPolicyObject, NULL, CLSCTX_INPROC_SERVER,
my_IID_IGroupPolicyObject, (LPVOID*)&pLGPO);
// We need the machine LGPO (if C++, no need to go through the lpVtbl table)
hr = pLGPO->OpenLocalMachineGPO(GPO_OPEN_LOAD_REGISTRY);
if (hr != S_OK) {
goto release;
}
hr = pLGPO->GetRegistryKey(GPO_SECTION_USER, &machine_key);
if (hr != S_OK) {
goto close;
}
// create key for disable Aeroshake minimise
sdf = RegCreateKeyEx(machine_key, TEXT("Software\\Policies\\Microsoft\\Windows\\Desktop\\NoWindowMinimizingShortcuts"),
0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, NULL, &dsrkey, NULL);
// Create the value
ds = RegSetKeyValue(dsrkey, NULL, TEXT("NoWindowMinimizingShortcuts"), REG_DWORD, &action, sizeof(action));
RegCloseKey(dsrkey);
// Apply policy and free resources
pLGPO->Save( TRUE, TRUE, &ext_guid, &snap_guid);
rStatus = RegCloseKey(machine_key);
// Write the GPO back to the directory
hr = pLGPO->Save(
FALSE,
TRUE,
&RegistryId,
&ThisAdminToolGuid);
close:
RegCloseKey(machine_key);
release:
pLGPO->Release();
}
This looks like a proper way but I have problem with OpenLocalMachineGPO it always returns E_ACCESSDENIED. Can that be sorted w/o need to run as Admin. Also when the code run as Admin it still doesn't change the required policy.
E_ACCESSDENIED means no access, of course you need enough permissions to modify the GPO.
In addition, The key value NoWindowMinimizingShortcuts is under the Sub Key Software\\Policies\\Microsoft\\Windows\\Explorer
sdf = RegCreateKeyEx(machine_key, TEXT("Software\\Policies\\Microsoft\\Windows\\Explorer"),
0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, NULL, &dsrkey, NULL);
You'll need to reboot or at least log off, then log in to take effect.(Even you modify in GPO directly)
Then the changes will be updated to HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer:
NoWindowMinimizingShortcuts = 0x00000001
Of course, you can also modify this key directly.(need to create it first if you don't have one)
void aeroshake(DWORD action)
{
// create key for disable Aeroshake minimise
HKEY hKeyRoot, dsrkey;
LSTATUS sdf = RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Policies\\Microsoft\\Windows"), &hKeyRoot);
sdf = RegCreateKey(hKeyRoot, TEXT("Explorer"), &dsrkey);
// Create the value
sdf = RegSetKeyValue(dsrkey, NULL, TEXT("NoWindowMinimizingShortcuts"), REG_DWORD, &action, sizeof(action));
RegCloseKey(dsrkey);
}

Windows: How to control the adaptive brightness?

I want to control(On/Off) the adaptive brightness like the Power Options
Enable adaptive brightness:
by API in Win 10. I guess the API is included in the Power Management Functions: https://msdn.microsoft.com/en-us/library/windows/desktop/aa373163(v=vs.85).aspx
But I cannot find the function... May someone provide me some suggestions or directions. Thanks a lot!
I found the solution by myself, and I share the way to everyone who needs!
GUID *guidScheme;
bool bResult = false;
byte enableFunction= 0x1; //Set 0x0 to disable
bResult = PowerGetActiveScheme(NULL, &guidScheme);
if (bResult != ERROR_SUCCESS){
//error message
}
GUID guidSubVideo = { 0x7516b95f, 0xf776, 0x4464, 0x8c, 0x53, 0x06, 0x16, 0x7f, 0x40, 0xcc, 0x99 };
GUID guidAdaptBright = { 0xfbd9aa66, 0x9553, 0x4097, 0xba, 0x44, 0xed, 0x6e, 0x9d, 0x65, 0xea, 0xb8 };
bResult = PowerWriteDCValueIndex(NULL, guidScheme, &guidSubVideo, &guidAdaptBright, enableFunction);
if (bResult != ERROR_SUCCESS){
//error message
}

Why CoCreateInstance can't create an instance of my component?

I am learning COM through the book "Inside COM" of Dale Rogerson. I try to register my component in the registry and then through this info create an instance of my component in the code of my client. But I see ::FormatMessage function writes this: Class not registered. So, ::CoCreateInstance can't create an instance of my component.
My REG-file:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\CLSID\{68584B56-9224-4DCC-AD35-1070CC9B8FDE}]
#="bush_component_01"
[HKEY_CLASSES_ROOT\CLSID\{68584B56-9224-4DCC-AD35-1070CC9B8FDE}\InprocServer32]
#="D:\\projects\\com_sandbox_solution_01\\Debug\\bush_component_01.dll"
[HKEY_CLASSES_ROOT\CLSID\{EB4BFC91-6A6E-43D1-B4CD-7A5DF24DB8D8}]
#="IID_IX"
[HKEY_CLASSES_ROOT\CLSID\{EB4BFC91-6A6E-43D1-B4CD-7A5DF24DB8D8}\InprocServer32]
#="D:\\projects\\com_sandbox_solution_01\\Debug\\bush_component_01.dll"
Piece of code of my client:
...
// GUID of my DLL (it registered in registry (look at my REG-code above))
// {68584B56-9224-4DCC-AD35-1070CC9B8FDE}
static const CLSID CLSID_component_01 =
{ 0x68584b56, 0x9224, 0x4dcc, { 0xad, 0x35, 0x10, 0x70, 0xcc, 0x9b, 0x8f, 0xde } };
// GUID of my some interface (it registered in registry (look at my REG-code above))
// {EB4BFC91-6A6E-43D1-B4CD-7A5DF24DB8D8}
static const IID IID_IX =
{ 0xeb4bfc91, 0x6a6e, 0x43d1, { 0xb4, 0xcd, 0x7a, 0x5d, 0xf2, 0x4d, 0xb8, 0xd8 } };
...
// Code of my client:
::CoInitialize(nullptr);
IUnknown* comp = nullptr;
HRESULT hcri = ::CoCreateInstance(CLSID_component_01, nullptr,
CLSCTX_INPROC_SERVER, IID_IX, (void**)&comp);
if (FAILED(hcri)){
void* msg = nullptr;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr, hcri, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0,
nullptr);
trace("***** TRACE *****");
trace((LPTSTR)msg);
trace("****************");
keep_window_open();
return 1;
}
// But ::FormatMessage function writes this: Class not registered
Why does it happen?
In 64-bit Windows 32-bit applications should use Wow6432Node registry subkey (in terms of 64-bit regedit).
Unfortunately 32-bit book does not cover that.

Invalid Algorithm Specified CryptoAPI

I am trying to decrypt something using 128BIT AES Decryption. When i attempt to calling CryptDecrypt i get an Error stating "Invalid Algorithm Specified". I get the same problem when using the library posted here: http://www.codeproject.com/KB/security/WinAES.aspx
What can cause this error?
I am using CryptoAPI along on vista64bit with visual studio 2008. I checked in the registry and the AES library is there...
EDIT
BYTE*& encryptedData /* get data length */
HCRYPTPROV cryptoHandle = NULL;
HCRYPTKEY aesKeyHandle = NULL;
hr = InitWinCrypt(cryptoHandle);
if(FAILED(hr))
{
return hr;
}
AesKeyOffering aesKey = { {PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_AES_128}, 16, { 0xFF, 0x00, 0xFF, 0x1C, 0x1D, 0x1E, 0x03, 0x04, 0x05, 0x0F, 0x20, 0x21, 0xAD, 0xAF, 0xA4, 0x04 }};
if(CryptImportKey(cryptoHandle, (CONST BYTE*)&aesKey, sizeof(AesKeyOffering), NULL, 0, &aesKeyHandle) == FALSE)
{
// DO error
return HRESULT_FROM_WIN32(GetLastError());
}
if(CryptSetKeyParam(aesKeyHandle, KP_IV, { 0xFF, 0x00, 0xFF, 0x1C, 0x1D, 0x1E, 0x03, 0x04, 0x05, 0x0F, 0x20, 0x21, 0xAD, 0xAF, 0xA4, 0x04 } , 0) == FALSE)
{
return HRESULT_FROM_WIN32(GetLastError());
}
BYTE blah2 = CRYPT_MODE_CBC;
// set block mode
if(CryptSetKeyParam(aesKeyHandle, KP_MODE, &blah2, 0) == FALSE)
{
//
return HRESULT_FROM_WIN32(GetLastError());
}
DWORD lol = dataLength / 16 + 1;
DWORD lol2 = lol * 16;
if(CryptDecrypt(aesKeyHandle, 0, TRUE, 0, encryptedData, &lol2) == FALSE)
{
return HRESULT_FROM_WIN32(GetLastError());
}
InitWinCrypt function
if(!CryptAcquireContextW(&cryptoHandle, NULL, L"Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
{
if(!CryptAcquireContextW(&cryptoHandle, NULL, L"Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, 0))
{
return HRESULT_FROM_WIN32(GetLastError());
}
else
{
return S_OK;
}
}
return S_OK;
AesOffering struct:
struct AesKeyOffering
{
BLOBHEADER m_Header;
DWORD m_KeyLength;
BYTE Key[16];
};
EDIT2
After rebooting my computer, and remvoing the CBC chunk. I am now getting Bad Data Errors. The data decrypts fine in C#. But i need to do this using wincrypt.
Are you passing cryptoHandle by reference to InitWithCrypt? If not, your code
if(!CryptAcquireContextW(&cryptoHandle, ...
would only modify InitWinCrypt's copy of cryptoHandle.
EDIT: Given that it does, try getting rid of the CryptSetKeyParam call which sets CRYPT_MODE_CBC