I'm developing a small service for Linux OS. And I had a problem. I can't access the display from my service, although I run it as a root user. If I transfer the same code to a console application, everything works fine. I have a suspicion that Linux services cannot work with Xorg. Is my suspicion correct? Can you advise me!
I apologize for not providing my code. Please take a look at my code.
namespace tasks::window {
using namespace storage::entities;
WindowTask::WindowTask(Poco::Logger &logger, sdk::events::AbstractCollector& events)
:Poco::Task("WindowTask"),
logger_(logger),
event_(events)
{
}
WindowTask::~WindowTask()
{
}
void WindowTask::runTask() {
while (!isCancelled()) {
auto wi = getWindowInfo();
std::cout<<"window name = "<< wi->name << std::endl;
std::cout<<"window pid = "<< wi->pid << std::endl;
// отправим dlp событие на сервер
dlp::events::WindowEventData eventData;
eventData.setTitle(wi->name);
eventData.setPid(wi->pid);
this->sendDlpEvent(eventData);
//задержка перед повторной отправкой события об активном окне пользователя
this->sleep(sleep_period_); // каждый некоторый промежуток времени повторить действия в цикле
}
}
Window WindowTask::getActiveWindow() {
Window activeWindow = None;
unsigned char* property = getProperty(::XDefaultRootWindow(xDisplay_), XA_WINDOW,
"_NET_ACTIVE_WINDOW");
if (property != nullptr)
{
activeWindow = *(reinterpret_cast<Window*>(property));
}
return activeWindow;
}
Poco::SharedPtr<WindowInfo> WindowTask::getWindowInfo() {
xDisplay_ = ::XOpenDisplay(NULL);
Window activeWindow = getActiveWindow();
if (activeWindow == None){
logger_.information("не удалось получить активное окно");
return nullptr;
}
unsigned char* netwmName = getProperty(activeWindow,
::XInternAtom(xDisplay_, "UTF8_STRING", False),
"_NET_WM_NAME");
if (netwmName == nullptr)
netwmName = getProperty(activeWindow,
::XInternAtom(xDisplay_, "UTF8_STRING", False),
"WM_NAME");
unsigned char* wmPid = getProperty(activeWindow,
AnyPropertyType,
"_NET_WM_PID");
::XCloseDisplay(xDisplay_);
if (netwmName != nullptr && wmPid != nullptr)
{
Poco::SharedPtr<WindowInfo> windowInfo = Poco::makeShared<WindowInfo>();
windowInfo->name = std::string((char*)netwmName);
unsigned long long_property = static_cast<unsigned long>(wmPid[0] + (wmPid[1] << 8) + (wmPid[2] << 16) +
(wmPid[3] << 24));
windowInfo->pid = (int)long_property;
return windowInfo;
}
return nullptr;
}
// метод получающий некоторое свойство окна
unsigned char* WindowTask::getProperty(Window xWindow, Atom xPropertyType, const char* propertyName){
Atom xProperty = ::XInternAtom(xDisplay_,propertyName,False);
if (xProperty == None)
{
logger_.information("не удалось получить следующее свойство окна - %s",propertyName);
return nullptr;
}
Atom xActualType = None;
int actualFormat = 0;
unsigned long itemsNumber = 0;
unsigned long RemainigBytes = 0;
unsigned char *pProperty = NULL;
const long maxPropertySize = 4096;
int result = ::XGetWindowProperty(xDisplay_,xWindow,xProperty,0,maxPropertySize/4,False,xPropertyType,
&xActualType,&actualFormat,&itemsNumber,&RemainigBytes,&pProperty);
if (result != Success) {
logger_.information("не удалось получить следующее свойство окна - %s",propertyName);
return nullptr;
}
return pProperty;
}
void WindowTask::sendDlpEvent(dlp::events::WindowEventData& eventData) {
auto event = std::make_shared<sdk::events::UserEvent>(TypeTaskString.at(TypeTask::ACTIVE_WINDOW));
event->setStatus("NOTIFY");
event->setAttack(sdk::events::Attack::BENIGN);
event->setLogin("test");
auto data_object = Poco::makeShared<Poco::JSON::Object>(Poco::JSON_PRESERVE_KEY_ORDER);
eventData.serialize(*data_object);
event->setData(std::move(data_object));
event_.push(std::move(event));
}
}
On this line of code my application crashes. I suspect that I was unable to receive the display:
unsigned char* property = getProperty(::XDefaultRootWindow(xDisplay_), XA_WINDOW,"_NET_ACTIVE_WINDOW");
my service and works with the current user. I just need to log in to the X server so that I can receive screenshots. I found some code that helped me get the xLib library working in my service. To do this, I write the following line in the code: setenv("XAUTHORITY", "/run/user/1000/.mutter-Xwaylandauth.AL7MK2", 1); I take the value of the variable from the console with the command echo $XAUTHORITY but how can I do this in code?? so that I don’t need to take information from the console and enter it manually.
Please tell me how to do this correctly in code? If we get the user id using the function getuid()
Or can anyone tell me how to log in to the X server knowing the user ID?