/** *Datawestoreforeachserver
*/ struct wts_server
{ struct wts_obj *info_obj; // Object to get session notifications struct xrdp_chan_session_state session_state; // session state
};
staticstruct wts_server wts_current_server;
/* helper functions used by WTSxxx API - do not invoke directly */ staticint
can_send(int sck, int millis, int restart); staticint
can_recv(int sck, int millis, int restart); staticint
mysend(int sck, constvoid *adata, int bytes); staticint
myrecv(int sck, void *adata, int bytes); staticint
mypeek(int sck, void *adata, int bytes);
staticvoid
free_wts(struct wts_obj *wts)
{ if (wts != NULL)
{ if (wts->fd >= 0)
{
close(wts->fd);
}
free(wts);
}
}
/* *Opensahandletotheserverendofaspecifiedvirtualchannel * *@paramSessionId-currentsessionID;*must*beWTS_CURRENT_SESSION *@parampVirtualName-virtualchannelnamewhenusingSVC *-nameofendpointlistenerwhenusingDVC *@paramflags-typeofchannelandchannelpriorityifDVC *@paramprivate_chan-If!=0,thisisaprivatechanneldefined *inchannel_defs.h *@param[out]errcode-Indicationfortheuserofapossible *error.Cannotbedefaulted.Isonlysetonerror. * *@returnavalidpointeronsuccess,NULLonerror
******************************************************************************/ staticvoid *
VirtualChannelOpen(unsignedint SessionId, constchar *pVirtualName, unsignedint flags, unsignedint private_chan, enum wts_errcode *errcode)
{ struct wts_obj *wts; int bytes; unsignedlong long1; struct sockaddr_un s; // Pad the connect data out to a larger size to allow for // changes to struct xrdp_chan_connect union
{ char pad[XRDPAPI_CONNECT_PDU_LEN]; struct xrdp_chan_connect connect_data;
} cd = {0};
uint32_t connect_result; int lerrno;
if (SessionId != WTS_CURRENT_SESSION)
{
LOG(LOG_LEVEL_ERROR, "WTSVirtualChannelOpenEx: bad SessionId");
*errcode = WTS_E_BAD_SESSION_ID; return0;
}
/*****************************************************************************/ staticint
mysend(int sck, constvoid *adata, int bytes)
{ int sent; int error; constchar *data;
data = (constchar *) adata;
sent = 0; while (sent < bytes)
{ if (can_send(sck, 100, 0))
{
error = send(sck, data + sent, bytes - sent, MSG_NOSIGNAL); if (error < 1)
{ return -1;
}
sent += error;
}
} return sent;
}
/*****************************************************************************/ staticint
myrecv(int sck, void *adata, int bytes)
{ int recd; int error; char *data;
do
{
status = poll(&pollfd, 1, millis);
} while (status < 0 && errno == EINTR && restart);
if (status > 0)
{ if ((pollfd.revents & POLLOUT) != 0)
{
rv = 1;
}
}
return rv;
}
/*****************************************************************************/ staticint
can_recv(int sck, int millis, int restart)
{ int rv = 0; struct pollfd pollfd; int status;
pollfd.fd = sck;
pollfd.events = POLLIN;
pollfd.revents = 0; do
{
status = poll(&pollfd, 1, millis);
} while (status < 0 && errno == EINTR && restart);
if (status > 0)
{ if ((pollfd.revents & (POLLIN | POLLHUP)) != 0)
{
rv = 1;
}
}
if (hServer != WTS_CURRENT_SERVER_HANDLE)
{
LOG(LOG_LEVEL_ERROR, "WTSQuerySessionInformationA: bad hServer");
*errcode = WTS_E_BAD_SERVER;
} elseif (SessionId != WTS_CURRENT_SESSION)
{
LOG(LOG_LEVEL_ERROR, "WTSQuerySessionInformationA: bad SessionId");
*errcode = WTS_E_BAD_SESSION_ID;
} elseif (WTSInfoClass != WTSConnectState)
{
LOG(LOG_LEVEL_ERROR, "WTSQuerySessionInformationA: unsupported WTSInfoClass");
*errcode = WTS_E_BAD_INFO_CLASS;
} else
{
rv = 1; // Assume success if (wts_current_server.info_obj == NULL)
{ // We don't have a current connection for server state events. // Set one up to update our cached values, then tear it down again. int fd;
/*****************************************************************************/ int
WTSGetDispatchMessage(void *cbdata, WNDPROC wndproc, LRESULT *lResult)
{
LRESULT result = 0; struct xrdp_chan_session_state new_state;
/* get response */ if (wts_current_server.info_obj == NULL)
{
LOG(LOG_LEVEL_ERROR, "WTSGetDispatchMessage: No notification channel was opened");
} elseif (!can_recv(wts_current_server.info_obj->fd, 0, 1))
{ // No message available - nothing to log
} elseif (mypeek(wts_current_server.info_obj->fd,
&new_state, sizeof(new_state)) != sizeof(new_state))
{
LOG(LOG_LEVEL_ERROR, "WTSGetDispatchMessage: An incomplete message was received");
} else
{ /* We've peeked a message. Find a SINGLE difference with our *ownstate,updateourstate,andissueacallback.Ifthere *aremoredifferences,theapplicationwillcallusbackand *wecanprocessthenextone.Whenallthedifferencesare *accountedfor,wecanclearthemessagefromthequeue,and
* the fd will no longer be readable */
UINT msgno = 0; // 0 means 'no message'
WPARAM wParam = 0;
LPARAM lParam = 0; // Look for a single difference in the state we have, and the // current state from the server struct xrdp_chan_session_state *curr_state;
curr_state = &wts_current_server.session_state;
// If we found a difference, activate the callback if (msgno != 0)
{
*lResult = wndproc(cbdata, msgno, wParam, lParam);
result = 1;
}
// If we've exhausted all the differences between the old and // the new state, purge the message from the queue if (curr_state->is_connected == new_state.is_connected && /* Add further checks here in the future */ 1)
{ /* Sanity check on the fd */ if (wts_current_server.info_obj->fd >= 0)
{
(void)myrecv(wts_current_server.info_obj->fd,
&new_state, sizeof(new_state));
}
}
}
return result;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-07-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.