How to io_control of boost library socket with customized command - boost-asio

I' trying to make an identical function to "ioctl" in c++ style using boost library.
Here is my "c" style code:
int sockfd;
char * id;
struct iwreq wreq;
memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
exit(1);
}
printf("Socket opened successfully \n");
id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;
if (ioctl(sockfd, SIOCGIWESSID, &wreq)) {
fprintf(stderr, "Get ESSID ioctl failed \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description : %s\n",strerror(errno));
exit(2);
}
printf("IOCTL Successfull\n");
printf("ESSID is %s\n", wreq.u.essid.pointer);
I found some relevant example, but I'm not clear how to use it correctly. example
Main function:
boost::asio::ip::udp::socket socket(io_service);
struct iwreq wreq
memset(&wreq, 0, sizeof(struct iwreq));
sprintf(wreq.ifr_name, IW_INTERFACE);
id = malloc(IW_ESSID_MAX_SIZE+1);
wreq.u.essid.pointer = id;
boost::asio::detail::io_control::myCommand command;
command.set(&wreq);
boost::system::error_code ec;
socket.io_control(command, ec);
if (ec)
{
// An error occurred.
}
Custom command:
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/asio/detail/socket_types.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
namespace io_control {
// I/O control command for getting number of bytes available.
class myCommand
{
public:
// Default constructor.
myCommand()
: value_(0)
{
}
// Get the name of the IO control command.
int name() const
{
return static_cast<int>(SIOCGIWESSID);
}
// Set the value of the I/O control command.
void set(struct iwreq* value)
{
value_ = static_cast<detail::ioctl_arg_type>(value);
}
// Get the current value of the I/O control command.
std::size_t get() const
{
return static_cast<struct iwreq*>(value_);
}
// Get the address of the command data.
detail::ioctl_arg_type* data()
{
return &value_;
}
// Get the address of the command data.
const detail::ioctl_arg_type* data() const
{
return &value_;
}
private:
detail::ioctl_arg_type value_;
};
} // namespace io_control
} // namespace detail
} // namespace asio
} // namespace boost
However, the code does not work.
If you have any example code or solution, please let me know.
Thank you.

Related

Port not bound SystemC (E112)

I am trying to implement a producer (master) speaking to a memory element (slave) through the memory controller (which implements the interface simple_mem_interface).
Note: Some functions details and include statements are not fully mentioned in the code attached.
Searching for bugs in the code.
Adding debugging tools to find the fault in Write Enable Port.
binding.cpp
int sc_main(int argc, char* argv[])
{
sc_signal<unsigned int> d_out,d_in,address_d;
sc_signal<bool> wen, ren, ack;
sc_clock ClkFast("ClkFast", 100, SC_NS);
sc_clock ClkSlow("ClkSlow", 50, SC_NS);
Memory_Controller Controller1 ("Controller");
d_out = Controller1.data_mem_read;
ren.write(Controller1.REN);
ack.write(Controller1.ack);
d_in.write(Controller1.data_write);
address_d.write(Controller1.address);
wen.write(Controller1.WEN);
producer P1("Producer");
P1.out(Controller1);
P1.Clk(ClkFast);
Memory_module MEM("Memory");
MEM.Wen(wen);
MEM.Ren(ren);
MEM.ack(ack);
MEM.Clock(ClkSlow);
MEM.data_in(d_in);
MEM.data_out(d_out);
MEM.address(address_d);
sc_start(5000, SC_NS);
return 0;
Memory_controller.h
#define MEM_SIZE 100
#include <interface_func.h>
class Memory_Controller : public sc_module, public simple_mem_if
{
public:
// Ports
sc_in <unsigned int> data_mem_read{ "Data_Read_from_Memory" };
sc_out<bool> REN { "Read_Enable" };
sc_out<bool> WEN { "Write_Enable" };
sc_out <bool> ack{ "ACK_Bool" };
sc_out<unsigned int> address{ "Memory_Address" }, data_write{
"Data_Written_to_Memory" };
// constructor
Memory_Controller(sc_module_name nm) : sc_module(nm)
{ // Creating a 2 dimentional array holding adresses and data
WEN.write(false);
REN.write(false);
ack.write(false);
}
~Memory_Controller() //destructor
{
}
bool Write(unsigned int address_i, unsigned int datum) // blocking write
{
WEN.write(true);
REN.write(false);
data_write.write(datum);
address.write(address_i);
if (ack == true)
return true;
else
return false;
}
bool Read(unsigned int address_i, unsigned int& datum_i) // blocking read
{
WEN.write(false);
REN.write(true);
datum_i=data_mem_read;
address.write(address_i);
if (ack == true)
return true;
else
return false;
}
void register_port(sc_port_base& port, const char* if_typename)
{
cout << "binding " << port.name() << " to "
<< "interface: " << if_typename << endl;
}
};
Memory.h
#define MEM_SIZE 100
#include "interface_func.h"
class Memory_module : public sc_module
{
public:
sc_in<bool> Wen,Ren;
sc_in <unsigned int> address, data_in ;
sc_in<bool> Clock;
sc_out <unsigned int> data_out;
sc_out <bool> ack;
bool fileinput = false;
ifstream myfile;
unsigned int item [MEM_SIZE];
Memory_module()
{
}
void Write() // blocking write
{
while (true)
{
wait();
if (Wen==true)
{
if (address >= MEM_SIZE || address < 0)
{
ack=false;
}
else
{
item[address]=data_in;
ack=true;
}
}
}
}
void Read() // blocking read
{
while (true)
{
wait();
if (Ren)
{
if (address >= MEM_SIZE || address < 0)
ack=false;
else
{
data_out.write(item[address]);
ack=true;
}
}
}
}
SC_CTOR(Memory_module)
{
SC_THREAD(Read);
sensitive << Clock.pos();
SC_THREAD(Write);
sensitive << Clock.pos();
}
};
interface_func.h
class simple_mem_if : virtual public sc_interface
{
public:
virtual bool Write(unsigned int addr, unsigned int data) = 0;
virtual bool Read(unsigned int addr, unsigned int& data) = 0;
};
After debugging the SystemC binder.cpp code, the following error arises:
(E112) get interface failed: port is not bound : port 'Controller.Write_Enable' (sc_out)
You cannot drive your unconnected ports in the Memory_Controller constructor. If you want to explicitly drive these ports during startup, move these calls to a start_of_simulation callback:
Memory_Controller(sc_module_name nm) : sc_module(nm)
{}
void start_of_simulation()
{
WEN.write(false);
REN.write(false);
ack.write(false);
}

How to get type of object when using ole automation (C++)

I'm using the autowrap function to interact with VBA and now I get the control using item method as below.
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_INT;
x.intVal = index;
wchar_t method[] = L"Item";
hr = AutoWrap(DISPATCH_METHOD, &result, pControls, method,1,x);
pObject = result.pdispVal;
I can get the name of the control item using this code below:
VARIANT result;
VariantInit(&result);
wchar_t method[] = L"Name";
hr = AutoWrap(DISPATCH_PROPERTYGET, &result, pObject, method, 0);
QString name=QString::fromWCharArray(result.bstrVal);
But I can't seem to find a property to get the type of object (textbox, commandbutton and etc). In VBA, there is a TypeName() function to get the type. So how can I actually do it in OLE automation autowrap function? Thanks.
Here is an example... could be optimized with a function to check the result and throw/catch an exception, but it is what it is.
#include <windows.h>
#include <atlbase.h>
#include <comdef.h>
#include <stdio.h>
int main(int argc, TCHAR* argv[])
{
class CComInit
{
public:
CComInit()
{
CoInitialize(NULL);
}
~CComInit()
{
CoUninitialize();
}
} _init;
IDispatchPtr lpDisp;
HRESULT hr = lpDisp.CreateInstance(L"Scripting.FileSystemObject");
if (FAILED(hr))
{
_com_error err(hr);
printf("Error %s\n", err.ErrorMessage());
return 0;
}
ITypeInfoPtr lpTypeInfo;
hr = lpDisp->GetTypeInfo(0, 0, &lpTypeInfo);
if (FAILED(hr))
{
_com_error err(hr);
printf("Error %s\n", err.ErrorMessage());
return 0;
}
CComBSTR ccbName, ccbDocString;
hr = lpTypeInfo->GetDocumentation(-1, &ccbName, &ccbDocString, NULL, NULL) ;
if (FAILED(hr))
{
_com_error err(hr);
printf("Error %s\n", err.ErrorMessage());
return 0;
}
printf("Type name: %S\n", ccbName.m_str);
printf("Doc: %S\n", ccbDocString.m_str);
return 0;
}

create my own resource types (tf.resource)

My current code:
// For Eigen::ThreadPoolDevice.
#define EIGEN_USE_THREADS 1
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/resource_mgr.h"
#include "tensorflow/core/framework/resource_op_kernel.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/platform/mutex.h"
#include "tensorflow/core/platform/types.h"
using namespace tensorflow;
REGISTER_OP("ArrayContainerCreate")
.Attr("T: type")
.Attr("container: string = ''")
.Attr("shared_name: string = ''")
.Output("resource: resource")
.SetIsStateful()
.SetShapeFn(shape_inference::ScalarShape)
.Doc(R"doc(Array container, random index access)doc");
REGISTER_OP("ArrayContainerGetSize")
.Input("handle: resource")
.Output("out: int32")
.SetShapeFn(shape_inference::ScalarShape)
;
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/resource_mgr.h
struct ArrayContainer : public ResourceBase {
ArrayContainer(const DataType& dtype) : dtype_(dtype) {}
string DebugString() override { return "ArrayContainer"; }
int64 MemoryUsed() const override { return 0; };
mutex mu_;
const DataType dtype_;
int32 get_size() {
mutex_lock l(mu_);
return (int32) 42;
}
};
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/resource_op_kernel.h
class ArrayContainerCreateOp : public ResourceOpKernel<ArrayContainer> {
public:
explicit ArrayContainerCreateOp(OpKernelConstruction* context) : ResourceOpKernel(context) {
OP_REQUIRES_OK(context, context->GetAttr("T", &dtype_));
}
private:
virtual bool IsCancellable() const { return false; }
virtual void Cancel() {}
Status CreateResource(ArrayContainer** ret) override EXCLUSIVE_LOCKS_REQUIRED(mu_) {
*ret = new ArrayContainer(dtype_);
if(*ret == nullptr)
return errors::ResourceExhausted("Failed to allocate");
return Status::OK();
}
Status VerifyResource(ArrayContainer* ar) override {
if(ar->dtype_ != dtype_)
return errors::InvalidArgument("Data type mismatch: expected ", DataTypeString(dtype_),
" but got ", DataTypeString(ar->dtype_), ".");
return Status::OK();
}
DataType dtype_;
};
REGISTER_KERNEL_BUILDER(Name("ArrayContainerCreate").Device(DEVICE_CPU), ArrayContainerCreateOp);
class ArrayContainerGetSizeOp : public OpKernel {
public:
using OpKernel::OpKernel;
void Compute(OpKernelContext* context) override {
ArrayContainer* ar;
OP_REQUIRES_OK(context, GetResourceFromContext(context, "handle", &ar));
core::ScopedUnref unref(ar);
int32 size = ar->get_size();
Tensor* tensor_size = nullptr;
OP_REQUIRES_OK(context, context->allocate_output(0, TensorShape({}), &tensor_size));
tensor_size->flat<int32>().setConstant(size);
}
};
REGISTER_KERNEL_BUILDER(Name("ArrayContainerGetSize").Device(DEVICE_CPU), ArrayContainerGetSizeOp);
I compile that. Note that I first got some undefined symbol: _ZN6google8protobuf8internal26fixed_address_empty_stringE error but I resolved that by adding these additional compiler flags:
from google.protobuf.pyext import _message as msg
lib = msg.__file__
extra_compiler_flags = [
"-Xlinker", "-rpath", "-Xlinker", os.path.dirname(lib),
"-L", os.path.dirname(lib), "-l", ":" + os.path.basename(lib)]
I read about that here.
Then I load that as a module via tf.load_op_library.
Then, I have this Python code:
handle = mod.array_container_create(T=tf.int32)
size = mod.array_container_get_size(handle=handle)
When I try to evaluate size, I get the error:
InvalidArgumentError (see above for traceback): Trying to access resource located in device 14ArrayContainer from device /job:localhost/replica:0/task:0/cpu:0
[[Node: ArrayContainerGetSize = ArrayContainerGetSize[_device="/job:localhost/replica:0/task:0/cpu:0"](array_container)]]
The device name (14ArrayContainer) somehow seem to be messed up. Why is that? What is the problem with the code?
For some more testing, I added this additional code in the ArrayContainerCreateOp:
ResourceHandle rhandle = MakeResourceHandle<ArrayContainer>(context, cinfo_.container(), cinfo_.name());
printf("created. device: %s\n", rhandle.device().c_str());
printf("container: %s\n", rhandle.container().c_str());
printf("name: %s\n", rhandle.name().c_str());
printf("actual device: %s\n", context->device()->attributes().name().c_str());
printf("actual name: %s\n", cinfo_.name().c_str());
This gives me the output:
created. device: 14ArrayContainer
container: 14ArrayContainer
name: 14ArrayContainer
actual device: /job:localhost/replica:0/task:0/cpu:0
actual name: _2_array_container
So clearly, there is some of the problem.
This looks like something is messed up with the protobuf? Maybe I am linking the wrong lib? But I have not found which lib to link instead.
(I also posted an issue about this here.)
That is upstream bug 10950, which should be fixed in TensorFlow 1.2.2.

Calling methods and receiving signals using low-level APIs

I am trying to call the method ReadLocalBdAddrReq and receive its signal ReadLocalBdAddrCfm on dbus using the dbus low level APIs.
I have written the following code with the help of some forum posts and a dbus tutorial.
The thing is, I am not able to receive the signals back. The code is incomplete at some places as I didn't know what should be done.
So please help me so that I can receive the signals for the methods called.
Here the code I have written. Please correct any mistakes I've made.
#include <stdlib.h>
#include <stdio.h>
#include <dbus/dbus.h>
#define OBJ_PATH "/bt/cm"
static dbus_bool_t add_watch(DBusWatch *watch, void *data)
{
if (!dbus_watch_get_enabled(watch))
return TRUE;
int fd = dbus_watch_get_unix_fd(watch);
unsigned int flags = dbus_watch_get_flags(watch);
int f = 0;;
if (flags & DBUS_WATCH_READABLE) {
f |= DBUS_WATCH_READABLE;
printf("Readable\n");
}
if (flags & DBUS_WATCH_WRITABLE) {
printf("Writeable\n");
f |= DBUS_WATCH_WRITABLE;
}
/* this should not be here */
if (dbus_watch_handle(watch, f) == FALSE)
printf("dbus_watch_handle() failed\n");
return TRUE;
}
static void remove_watch(DBusWatch *watch, void *data)
{
printf("In remove watch with fd = [%d]\n",dbus_watch_get_unix_fd(watch));
}
static void toggel_watch(DBusWatch *watch, void *data)
{
printf("In toggel watch\n");
/*
if (dbus_watch_get_enabled(watch))
add_watch(watch, data);
else
remove_watch(watch, data);
*/
}
/* timeout functions */
static dbus_bool_t add_time(DBusTimeout *timeout, void *data)
{
/* Incomplete */
printf("In add_time\n");
if (!dbus_timeout_get_enabled(timeout))
return TRUE;
//dbus_timeout_handle(timeout);
return 0;
}
static void remove_time(DBusTimeout *timeout, void *data)
{
/* Incomplete */
printf("In remove_time\n");
}
static void toggel_time(DBusTimeout *timeout, void *data)
{
/* Incomplete */
printf("In toggel_time\n");
/*
if (dbus_timeout_get_enabled(timeout))
add_timeout(timeout, data);
else
remove_timeout(timeout, data);
*/
}
/* message filter -- handlers to run on all incoming messages*/
static DBusHandlerResult filter (DBusConnection *connection, DBusMessage *message, void *user_data)
{
printf("In filter\n");
char *deviceaddr;
if (dbus_message_is_signal(message, "com.bluegiga.v2.bt.cm", "ReadLocalBdAddrCfm")) {
printf("Signal received is ReadLocalBdAddrCfm\n");
if ((dbus_message_get_args(message,NULL,DBUS_TYPE_STRING, &deviceaddr,DBUS_TYPE_INVALID) == FALSE))
{
printf("Could not get the arguments from the message received\n");
return -2;
}
printf("Got Signal and device address is [%s]\n", deviceaddr);
}
return 0;
}
/* dispatch function-- simply save an indication that messages should be dispatched later, when the main loop is re-entered*/
static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_status, void *data)
{
printf("In dispatch_status\n");
if (new_status == DBUS_DISPATCH_DATA_REMAINS)
{
printf("new dbus dispatch status: DBUS_DISPATCH_DATA_REMAINS [%d]",new_status);
}
}
/* unregister function */
void unregister_func(DBusConnection *connection, void *user_data)
{
}
/* message function - Called when a message is sent to a registered object path. */
static DBusHandlerResult message_func(DBusConnection *connection, DBusMessage *message, void *data)
{
printf("Message [%s] is sent to [%s] from interface [%s] on path [%s] \n",dbus_message_get_member(message),dbus_message_get_destination(message),
dbus_message_get_interface(message),dbus_message_get_path(message)); return 0;
}
DBusObjectPathVTable table = {
.unregister_function = unregister_func,
.message_function = message_func,
};
int main(void) {
DBusMessage* msg;
DBusMessageIter args;
DBusConnection* conn;
DBusError err;
DBusPendingCall* pending;
int ret;
//unsigned int level;
char* appHandle = NULL;
//int *context;
int msg_serial;
int open;
char *deviceaddr;
dbus_error_init(&err);
// connect to the system bus and check for errors
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
exit(1);
}
if (!dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggel_watch, NULL, NULL))
{
printf("Error in dbus_set_watch_functions\n");
dbus_connection_unref(conn);
return -1;
}
/* These functions are responsible for making the application's main loop aware of timeouts */
if (!dbus_connection_set_timeout_functions(conn, add_time, remove_time, toggel_time, NULL, NULL))
{
printf("Error in dbus_set_timeout_functions\n");
dbus_connection_unref(conn);
return -1;
}
/* Used to register the handler functions run on incoming messages*/
if (!dbus_connection_add_filter(conn, filter, NULL, NULL))
{
printf("Error in adding filter\n");
dbus_connection_unref(conn);
return -1;
}
/* Filter added for incoming messages */
/* Set a function to be invoked when the dispatch status changes */
dbus_connection_set_dispatch_status_function(conn, dispatch_status, NULL ,NULL);
/* Register a handler for messages sent to a given path */
if(!dbus_connection_register_object_path(conn, OBJ_PATH, &table, NULL))
{
printf("Error in registering object\n");
return -1;
}
/* sending messages to the outgoing queue */
msg = dbus_message_new_method_call("com.bluegiga.v2.bt.cm", // target for the method call
OBJ_PATH, // object to call on
"com.bluegiga.v2.bt.cm", // interface to call on
"ReadLocalBdAddrReq"); // method name
if (NULL == msg) {
fprintf(stderr, "Message Null\n");
exit(1);
}
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT16,&appHandle)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
fprintf(stderr, "Sending the connections\n");
// send message and get a handle for a reply
if (!dbus_connection_send (conn, msg, &msg_serial)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
fprintf(stderr, "Connection sent and the msg serial is %d\n",msg_serial);
/* Message sent over */
/* not sure whether this should be here or above watch */
while (dbus_connection_get_dispatch_status(conn) == DBUS_DISPATCH_DATA_REMAINS)
{
//printf("Entered in dispatch\n");
/* Processes any incoming data. will call the filters registered by add_filer*/
dbus_connection_dispatch(conn);
}
return 0;
}
After I run this program it has the following output:
Readable
Sending the connections
Connection sent and the msg serial is
2(DBUS_MESSAGE_TYPE_METHOD_RETURN)
If the connection was sent to the object path then message_func should have been called correctly, but it never is called. Have I made any mistake in sending the method call?
You are missing the event loop which is otherwise available by default if you choose to go with one of the bindings. When you get a call to add_watch, libdbus expects that the application will attach an IO handler to it. The IOHandler added by application will watch for an activity on the fd (filedescriptor) queried for the watch. Whenever there is an activity on that file descriptor, the IOHandler will trigger a callback with appropriate flags that you need to convert to DBUS flags before calling dbus_watch_handle.
Suggest that you use glib if you don't know how to use event loops. I am able to get it if I use libUV or libEV as low footprint event loop.

Controlling the volume of other applications

I am trying to make an app that controls the volume of another process using the Windows 7 Audio API.
What I'm looking for is the ISimpleAudioVolume for the session used by the other process.
I have tried using the IAudioSessionEnumerator but it will only give me the IAudioSessionControl2 of the session. Using the IAudioSessionControl I have managed to receive notifications when I change the volume through sndvol but not change it myself.
I have also tried using GetSimpleAudioVolume() from IAudioSessionManager but it will only give me sessions within the current process.
How do you do it? It should be possible since sndvol is doing this.
Here is an example of muting another process using Core Audio API.
#include <windows.h>
#include <iostream>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <Audiopolicy.h>
#include <comdef.h>
#include <comip.h>
#define CHECK_HR(hr) \
if(FAILED(hr)) { \
std::cout << "error" << std::endl; \
return 0; \
}
_COM_SMARTPTR_TYPEDEF(IMMDevice, __uuidof(IMMDevice));
_COM_SMARTPTR_TYPEDEF(IMMDeviceEnumerator, __uuidof(IMMDeviceEnumerator));
_COM_SMARTPTR_TYPEDEF(IAudioSessionManager2, __uuidof(IAudioSessionManager2));
_COM_SMARTPTR_TYPEDEF(IAudioSessionManager2, __uuidof(IAudioSessionManager2));
_COM_SMARTPTR_TYPEDEF(IAudioSessionEnumerator, __uuidof(IAudioSessionEnumerator));
_COM_SMARTPTR_TYPEDEF(IAudioSessionControl2, __uuidof(IAudioSessionControl2));
_COM_SMARTPTR_TYPEDEF(IAudioSessionControl, __uuidof(IAudioSessionControl));
_COM_SMARTPTR_TYPEDEF(ISimpleAudioVolume, __uuidof(ISimpleAudioVolume));
IAudioSessionManager2Ptr CreateSessionManager()
{
HRESULT hr = S_OK;
IMMDevicePtr pDevice;
IMMDeviceEnumeratorPtr pEnumerator;
IAudioSessionManager2Ptr pSessionManager;
// Create the device enumerator.
CHECK_HR(hr = CoCreateInstance(
__uuidof(MMDeviceEnumerator),
NULL, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator),
(void**)&pEnumerator));
// Get the default audio device.
CHECK_HR(hr = pEnumerator->GetDefaultAudioEndpoint(
eRender, eConsole, &pDevice));
// Get the session manager.
CHECK_HR(hr = pDevice->Activate(
__uuidof(IAudioSessionManager2), CLSCTX_ALL,
NULL, (void**)&pSessionManager));
return pSessionManager;
}
bool MuteProcess(DWORD processId) {
IAudioSessionManager2Ptr mgr = CreateSessionManager();
if (!mgr) {
return false;
}
IAudioSessionEnumeratorPtr enumerator;
if (SUCCEEDED(mgr->GetSessionEnumerator(&enumerator))) {
int sessionCount;
if (SUCCEEDED(enumerator->GetCount(&sessionCount))) {
for (int i = 0; i < sessionCount; i++) {
IAudioSessionControlPtr control;
if (SUCCEEDED(enumerator->GetSession(i, &control))) {
IAudioSessionControl2Ptr control2;
if (SUCCEEDED(control->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&control2))) {
DWORD foundProcessId;
if (SUCCEEDED(control2->GetProcessId(&foundProcessId))) {
if (foundProcessId == processId) {
ISimpleAudioVolumePtr volume;
if (SUCCEEDED(control2->QueryInterface(_uuidof(ISimpleAudioVolume), (void**)&volume))) {
if (SUCCEEDED(volume->SetMute(TRUE, 0))) {
return true;
}
}
}
}
}
}
}
}
}
return false;
}
int _tmain(int argc, _TCHAR* argv[]){
CoInitialize(NULL);
DWORD processId = 11944;
MuteProcess(processId);
return 0;
}
There is an MSDN forum question and Blog Post about this very question. Hope this helps.
According to Larry Osterman
"There is no publicly documented mechanism for doing what you're trying to do."