Pessoal estou trabalhndo montando um dll que é acessada atraves de JNI para modificar o volume do windows pra isso montei primeiramente um executavel apartir de um exemplo do msdn que funcionou blz consegui aumentar baixar e “mutar” o volume do win.
Quando adptei a minha dll para adicionar as assinaturas do JNI e acessar atraves de uma pequena main apareceram os erros.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
//
//
// EndpointVolumeChanger.cpp : Endpoint Volume Changing sample application.
//
#include "stdafx.h"
#include "volumeJNI.h"
#include <functiondiscoverykeys.h>
#include "EndpointVolume.h"
bool ShowHelp;
bool UseConsoleDevice;
bool UseCommunicationsDevice;
bool UseMultimediaDevice;
bool VolumeUp;
bool VolumeDown;
bool ToggleMute;
int VolumeValue = -1;
bool isDefaultDevice;
IAudioEndpointVolume *endpointVolume;
int result = 0;
wchar_t *OutputEndpoint;
LPWSTR GetDeviceName(IMMDeviceCollection *DeviceCollection, UINT DeviceIndex)
{
IMMDevice *device;
LPWSTR deviceId;
HRESULT hr;
hr = DeviceCollection->Item(DeviceIndex, &device);
if (FAILED(hr))
{
printf("Unable to get device %d: %x\n", DeviceIndex, hr);
return NULL;
}
hr = device->GetId(&deviceId);
if (FAILED(hr))
{
printf("Unable to get device %d id: %x\n", DeviceIndex, hr);
return NULL;
}
IPropertyStore *propertyStore;
hr = device->OpenPropertyStore(STGM_READ, &propertyStore);
SafeRelease(&device);
if (FAILED(hr))
{
printf("Unable to open device %d property store: %x\n", DeviceIndex, hr);
return NULL;
}
PROPVARIANT friendlyName;
PropVariantInit(&friendlyName);
hr = propertyStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
SafeRelease(&propertyStore);
if (FAILED(hr))
{
printf("Unable to retrieve friendly name for device %d : %x\n", DeviceIndex, hr);
return NULL;
}
wchar_t deviceName[128];
hr = StringCbPrintf(deviceName, sizeof(deviceName), L"%s (%s)", friendlyName.vt != VT_LPWSTR ? L"Unknown" : friendlyName.pwszVal, deviceId);
if (FAILED(hr))
{
printf("Unable to format friendly name for device %d : %x\n", DeviceIndex, hr);
return NULL;
}
PropVariantClear(&friendlyName);
CoTaskMemFree(deviceId);
wchar_t *returnValue = _wcsdup(deviceName);
if (returnValue == NULL)
{
printf("Unable to allocate buffer for return\n");
return NULL;
}
return returnValue;
}
bool PickDevice(IMMDevice **DeviceToUse, bool *IsDefaultDevice, ERole *DefaultDeviceRole)
{
HRESULT hr;
bool retValue = true;
IMMDeviceEnumerator *deviceEnumerator = NULL;
IMMDeviceCollection *deviceCollection = NULL;
*IsDefaultDevice = false; // Assume we're not using the default device.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&deviceEnumerator));
if (FAILED(hr))
{
printf("Unable to instantiate device enumerator: %x\n", hr);
retValue = false;
goto Exit;
}
IMMDevice *device = NULL;
//
// First off, if none of the console switches was specified, use the console device.
//
if (!UseConsoleDevice && !UseCommunicationsDevice && !UseMultimediaDevice && OutputEndpoint == NULL)
{
//
// The user didn't specify an output device, prompt the user for a device and use that.
//
hr = deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &deviceCollection);
if (FAILED(hr))
{
printf("Unable to retrieve device collection: %x\n", hr);
retValue = false;
goto Exit;
}
// printf("Select an output device:\n");
// printf(" 0: Default Console Device\n");
// printf(" 1: Default Communications Device\n");
// printf(" 2: Default Multimedia Device\n");
UINT deviceCount;
hr = deviceCollection->GetCount(&deviceCount);
if (FAILED(hr))
{
printf("Unable to get device collection length: %x\n", hr);
retValue = false;
goto Exit;
}
for (UINT i = 0 ; i < deviceCount ; i += 1)
{
LPWSTR deviceName;
deviceName = GetDeviceName(deviceCollection, i);
if (deviceName == NULL)
{
retValue = false;
goto Exit;
}
printf(" %d: %S\n", i + 3, deviceName);
free(deviceName);
}
wchar_t choice[10];
// _getws_s(choice); // Note: Using the safe CRT version of _getws.
long deviceIndex;
wchar_t *endPointer;
deviceIndex = 0;//= wcstoul(choice, &endPointer, 0);
if (deviceIndex == 0 && endPointer == choice)
{
printf("unrecognized device index: %S\n", choice);
retValue = false;
goto Exit;
}
switch (deviceIndex)
{
case 0:
UseConsoleDevice = 1;
break;
case 1:
UseCommunicationsDevice = 1;
break;
case 2:
UseMultimediaDevice = 1;
break;
default:
hr = deviceCollection->Item(deviceIndex - 3, &device);
if (FAILED(hr))
{
printf("Unable to retrieve device %d: %x\n", deviceIndex - 3, hr);
retValue = false;
goto Exit;
}
break;
}
}
else if (OutputEndpoint != NULL)
{
hr = deviceEnumerator->GetDevice(OutputEndpoint, &device);
if (FAILED(hr))
{
printf("Unable to get endpoint for endpoint %S: %x\n", OutputEndpoint, hr);
retValue = false;
goto Exit;
}
}
if (device == NULL)
{
ERole deviceRole = eConsole; // Assume we're using the console role.
if (UseConsoleDevice)
{
deviceRole = eConsole;
}
else if (UseCommunicationsDevice)
{
deviceRole = eCommunications;
}
else if (UseMultimediaDevice)
{
deviceRole = eMultimedia;
}
hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, deviceRole, &device);
if (FAILED(hr))
{
printf("Unable to get default device for role %d: %x\n", deviceRole, hr);
retValue = false;
goto Exit;
}
*IsDefaultDevice = true;
*DefaultDeviceRole = deviceRole;
}
*DeviceToUse = device;
retValue = true;
Exit:
SafeRelease(&deviceCollection);
SafeRelease(&deviceEnumerator);
return retValue;
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
int result = 0;
bool isDefaultDevice;
IMMDevice *device = NULL;
ERole role;
HRESULT hr;
IMMDeviceEnumerator *deviceEnumerator = NULL;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr))
{
printf("Unable to initialize COM: %x\n", hr);
result = hr;
}
if (!PickDevice(&device, &isDefaultDevice, &role))
{
printf("no pickdevice \n");
result = -1;
}
hr = device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, reinterpret_cast<void **>(&endpointVolume));
if (FAILED(hr))
{
printf("Unable to activate endpoint volume on output device: %x\n", hr);
result = -1;
printf("1 if ");
goto Exit;
}//Apartir daqui começa a escolher as funções para
printf(" 7");
BOOL currentMute;
printf(" 8");
hr = endpointVolume->GetMute(¤tMute);
printf(" 9");
if (FAILED(hr))
{
printf(" 10");
printf("Unable to retrieve current mute state: %x\n", hr);
printf(" 11");
result = -1;
printf(" 12");
// goto Exit;
}
//
// Since we're not reacting to volume changes, we don't care about the event context.
//
printf(" 13");
hr = endpointVolume->SetMute(currentMute ? FALSE : TRUE, NULL);
printf(" 14");
UINT currentStep, stepCount;
hr = endpointVolume->GetVolumeStepInfo(¤tStep, &stepCount);
if (FAILED(hr))
{
printf("Unable to get current volume step: %x\n", hr);
result = -1;
printf(" 2 if ");
goto Exit;
}
float currentVolume;
hr = endpointVolume->GetMasterVolumeLevelScalar(¤tVolume);
if (FAILED(hr))
{
printf("Unable to get current volume step: %x\n", hr);
result = -1;
printf(" 3 if ");
goto Exit;
}
hr = endpointVolume->GetMute(¤tMute);
if (FAILED(hr))
{
printf("Unable to get current volume step: %x\n", hr);
result = -1;
printf(" 4 if ");
goto Exit;
}
printf("Current master volume: %f. Step %d of step range 0-%d.\nEndpoint Mute: %S\n", currentVolume, currentStep, stepCount, currentMute ? L"Muted" : L"Unmuted");
Exit:
return 0;
}
JNIEXPORT void JNICALL Java_VolumeJNI_volumeUp
(JNIEnv *, jobject){
HRESULT hr;
hr = endpointVolume->VolumeStepUp(NULL);
if (FAILED(hr))
{
printf("Unable to increase volume: %x\n", hr);
result = -1;
//goto Exit;
}
if (hr == S_FALSE)
{
printf("Volume is already at the maximum\n");
}
}
JNIEXPORT void JNICALL Java_VolumeJNI_volumeDown
(JNIEnv *, jobject){
HRESULT hr;
//
// Since we're not reacting to volume changes, we don't care about the event context.
//
hr = endpointVolume->VolumeStepDown(NULL);
if (FAILED(hr))
{
printf("Unable to decrease volume: %x\n", hr);
result = -1;
// goto Exit;
}
if (hr == S_FALSE)
{
printf("Volume is already at the minimum\n");
}
}
JNIEXPORT void JNICALL Java_VolumeJNI_toggleMute
(JNIEnv *, jobject){
printf(" 6");
HRESULT hr;
printf(" 7");
BOOL currentMute;
printf(" 8");
hr = endpointVolume->GetMute(¤tMute);
printf(" 9");
if (FAILED(hr))
{
printf(" 10");
printf("Unable to retrieve current mute state: %x\n", hr);
printf(" 11");
result = -1;
printf(" 12");
// goto Exit;
}
//
// Since we're not reacting to volume changes, we don't care about the event context.
//
printf(" 13");
hr = endpointVolume->SetMute(currentMute ? FALSE : TRUE, NULL);
printf(" 14");
}
ERRO:
3: Alto-falantes (SoundMAX Integrated Digital High Definition Audio) ({0.0.0.00000000}.{78b90aea-7be4-4276-ac0e-7700c8fda986})
7 8 9 13 14Current master volume: 0.520000. Step 26 of step range 0-51.
Endpoint Mute: Unmuted
ERRROOO /n 7 8 9 13 14Current master volume: 0.520000. Step 26 of step range 0-51.
Endpoint Mute: Muted
ERRROOO /njava.lang.UnsatisfiedLinkError: C:\Users\0810850\Desktop\dlls\VolumeJNI.dll: Uma rotina de inicialização da biblioteca de vínculo dinâmico (DLL) falhou
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at VolumeJNI.<clinit>(VolumeJNI.java:8)
Como nao e possivel debuggar a dll coloquei varios printf para saber onde o codigo quebrava. alguem Podeira me ajudar??