I have a Windows service that may change the timeout on the logon screensaver in Windows (as described here.) To do that I change the following registry key to the timeout in seconds:
HKEY_USERS\.DEFAULT\Control Panel\Desktop\ScreenSaveTimeOut
The issue is that how do I make OS "read" or refresh the actual screensaver timeout after a change in the registry key above?
My practice shows that it is refreshed (for sure) only when I reboot the system, but in my case I need it to be applied without the reboot.
EDIT_1: After suggestion below I tried, as it seems to me, all possible combinations of the flags for the following:
DWORD bsmInfo1 = BSM_ALLDESKTOPS;
DWORD dwFlgs = BSF_FORCEIFHUNG | BSF_IGNORECURRENTTASK | BSF_NOTIMEOUTIFNOTHUNG | BSF_SENDNOTIFYMESSAGE;
int nbsm1 = ::BroadcastSystemMessage(dwFlgs, &bsmInfo1, WM_SETTINGCHANGE, 0, (LPARAM)L"Windows");
DWORD bsmInfo2 = BSM_ALLDESKTOPS;
int nbsm2 = ::BroadcastSystemMessage(dwFlgs, &bsmInfo2, WM_SETTINGCHANGE, 0, (LPARAM)L"WindowsThemeElement");
to no avail :( I receive 1 as a result from both calls but it has no effect.
I was able to resolve this.-.-.
If your service is running in the same session as the logon screensaver then you can call SystemParametersInfo with the SPI_SETSCREENSAVETIMEOUT flag.
SystemParametersInfo broadcasts the WM_SETTINGCHANGE message to all top level windows to indicate that a parameter has changed. If your code isn't running in the correct session then you could use BroadcastSystemMessage with the BSM_ALLDESKTOPS flag to deliver the WM_SETTINGCHANGE message. However, this does require the SE_TCB_NAME privilege, so your code would have to be running as SYSTEM.
I haven't actually tried this cross-session, so I can't guarantee that it works.
Related
my project using QTcpSocket and the function setSocketDescriptor(). The code is very normal
QTcpSocket *socket = new QTcpSocket();
socket->setSocketDescriptor(this->m_socketDescriptor);
This coding worked fine most of the time until I ran a performance testing on Windows Server 2016, the crash occurred. I debugging with the crash dump, here is the log
0000004f`ad1ff4e0 : ucrtbase!abort+0x4e
00000000`6ed19790 : Qt5Core!qt_logging_to_console+0x15a
000001b7`79015508 : Qt5Core!QMessageLogger::fatal+0x6d
0000004f`ad1ff0f0 : Qt5Core!QEventDispatcherWin32::installMessageHook+0xc0
00000000`00000000 : Qt5Core!QEventDispatcherWin32::createInternalHwnd+0xf3
000001b7`785b0000 : Qt5Core!QEventDispatcherWin32::registerSocketNotifier+0x13e
000001b7`7ad57580 : Qt5Core!QSocketNotifier::QSocketNotifier+0xf9
00000000`00000001 : Qt5Network!QLocalSocket::socketDescriptor+0x4cf7
00000000`00000000 : Qt5Network!QAbstractSocket::setSocketDescriptor+0x256
In the stderr log, I see those logs
CreateWindow() for QEventDispatcherWin32 internal window failed (Not enough storage is available to process this command.)
Qt: INTERNAL ERROR: failed to install GetMessage hook: 8, Not enough storage is available to process this command.
Here is the function, where the code was stopped on the Qt codebase
void QEventDispatcherWin32::installMessageHook()
{
Q_D(QEventDispatcherWin32);
if (d->getMessageHook)
return;
// setup GetMessage hook needed to drive our posted events
d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
if (Q_UNLIKELY(!d->getMessageHook)) {
int errorCode = GetLastError();
qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
errorCode, qPrintable(qt_error_string(errorCode)));
}
}
I did research and the error Not enough storage is available to process this command. maybe the OS (Windows) does not have enough resources to process this function (SetWindowsHookEx) and failed to create a hook, and then Qt fire a fatal signal, finally my app is killed.
I tested this on Windows Server 2019, the app is working fine, no crashes appear.
I just want to know more about the meaning of the error message (stderr) cause I don't really know what is "Not enough storage"? I think it is maybe the limit or bug of the Windows Server 2016? If yes, is there any way to overcome this issue on Windows Server 2016?
The error ‘Not enough storage is available to process this command’ usually occurs in Windows servers when the registry value is set incorrectly or after a recent reset or reinstallations, the configurations are not set correctly.
Below is verified procedure for this issue:
Click on Start > Run > regedit & press Enter
Find this key name HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters
Locate IRPStackSize
If this value does not exist Right Click on Parameters key and Click on New > Dword Value and type in IRPStackSize under the name.
The name of the value must be exactly (combination of uppercase and lowercase letters) the same as what I have above.
Right Click on the IRPStackSize and click on Modify
Select Decimal enter a value higher than 15(Maximum Value is 50 decimal) and Click Ok
You can close the registry editor and restart your computer.
Reference
After researching for a few days I finally can configure the Windows Server 2016 setting (registry) to prevent the crash.
So basically it is a limitation of the OS itself, it is called desktop heap limitation.
https://learn.microsoft.com/en-us/troubleshoot/windows-server/performance/desktop-heap-limitation-out-of-memory
(The funny thing is the error message is Not enough storage is available to process this command but the real problem came to desktop heap limitation. )
So for the solution, flowing the steps in this link: https://learn.microsoft.com/en-us/troubleshoot/system-center/orchestrator/increase-maximum-number-concurrent-policy-instances
I increased the 3rd parameter of SharedSection to 2048 and it fix the issue.
Summary steps:
Desktop Heap for the non-interactive desktops is identified by the third parameter of the SharedSection= segment of the following registry value:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows
The default data for this registry value will look something like the following:
%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16
The value to be entered into the Third Parameter of the SharedSection= segment should be based on the calculation of:
(number of desired concurrent policies) * 10 = (third parameter value)
Example: If it's desired to have 200 concurrent policy instances, then 200 * 10 = 2000, rounding up to a nice memory number gives you 2048as the third parameter resulting in the following update to be made to the registry value:
SharedSection=1024,3072,2048
I am trying to replicate a real time application on a windows computer to be able to debug and make changes easier, but I ran into issue with Delayed Ack. I have already disabled nagle and confirmed that it improve the speed a bit. When sending a lots of small packets, window doesn't ACK right away and delay it by 200 ms. Doing more research about it, I came across this. Problem with changing the registry value is that, it will affect the whole system rather than just the application that I am working with. Is there anyway to disable delayed ACK on window system like TCP_QUICKACK from linux using setsockopt? I tried hard coding 12, but got WSAEINVAL from WSAGetLastError.
I saw some dev on github that mentioned to use SIO_TCP_SET_ACK_FREQUENCY but I didn't see any example on how to actually use it.
So I tried doing below
#define SIO_TCP_SET_ACK_FREQUENCY _WSAIOW(IOC_VENDOR,23)
result = WSAIoctl(sock, SIO_TCP_SET_ACK_FREQUENCY, 0, 0, info, sizeof(info), &bytes, 0, 0);
and I got WSAEFAULT as an error code. Please help!
I've seen several references online that TCP_QUICKACK may actually be supported by Winsock via setsockopt() (opt 12), even though it is NOT documented, or officially confirmed anywhere.
But, regarding your actual question, your use of SIO_TCP_SET_ACK_FREQUENCY is failing because you are not providing any input buffer to WSAIoctl() to set the actual frequency value. Try something like this:
int freq = 1; // can be 1..255, default is 2
result = WSAIoctl(sock, SIO_TCP_SET_ACK_FREQUENCY, &freq, sizeof(freq), NULL, 0, &bytes, NULL, NULL);
Note that SIO_TCP_SET_ACK_FREQUENCY is available in Windows 7 / Server 2008 R2 and later.
I register a Bonjour service using
DNSServiceRegister(&dnssref, 0, 0, "Fortune Server on my-PC", "_trollfortune._tcp", 0, 0, bigEndianPort, 0, 0, 0, 0);
I then browse for it using
DNSServiceBrowse(&dnssref, 0, 0, "_trollfortune._tcp", 0, bonjourBrowseReplyCallback, this);
My callback function is called twice, with the same serviceName, regType and replyDomain, only the interfaceIndex is different, the first time it's 20, the second time it is 10000010. if_indextoname() returns ethernet_12 for both.
At the same time, Bonjour Browser (a tool I found on the Internet) shows my service listed only once.
Am I calling DNSServiceBrowse with wrong parameters?
I found the problem in my case.
The problem started after installing VMware. It created some virtual network interfaces. After disabling those interfaces the browser only showed one result.
But I think the problem is not related to the browsing. I think the problem is with the flag kDNSServiceInterfaceIndexAny (0 - 3rd parameter) send to the function DNSServiceBrowse maybe you need to set the interface to a fixed value instead of 0.
I found out that there is a command-line tool called dns-sd that ships with Bonjour, and you can register/browse services with it.
I registered a service using
dns-sd -R "Fortune Server on my-PC" _trollfortune._tcp local 1234
and browsing for it with the command
dns-sd -B _trollfortune._tcp
gives me the following output:
Browsing for _trollfortune._tcp
Timestamp A/R Flags if Domain Service Type Instance Name
19:48:23.674 Add 3 20 local. _trollfortune._tcp. Fortune Server on my-PC
19:48:23.674 Add 2 10000010 local. _trollfortune._tcp. Fortune Server on my-PC
Since the standard tool that comes with Bonjour lists the service twice, I guess this is the normal behavior.
I have an application (native C++, Windows), that cannot be run simultaneously on one machine. The behavior that I want to implement is this: on the attempt to run second instance of the application the first one stops running.
To do so I want to use WinApi function BroadcastSystemMessage() something like an example below.
When the application start it sends:
BroadcastSystemMessage(BSF_POSTMESSAGE, &dwRecepients, 0x666, 0, 0);
But, when I run my application in debug mode it doesn't hit
case 0x666:
int iClose = 0 + 1;
break;
when I start another instance. The other messages are nandled correctly (WM_KEYDOWN, WM_ACTIVATE and others).
What I'm I doing wrong?
In order to broadcast a custom message you need to create an id for it with the RegisterWindowMessage function, for example:
UINT msg666 = RegisterWindowMessage(L"custom_devil_message");
and use it both in the sending and receiving code:
// sending code
BroadcastSystemMessage(BSF_POSTMESSAGE, &dwRecepients, msg666, 0, 0);
// receiving code
case msg666:
int iClose = 0 + 1;
break;
Remember that messages do not work for console applications.
The solution began to work after I changed the type of the message to WM_APPCOMMAND + 10. Anyway, it didn't help, because BroadcastSystemMessage() doesn't broadcast messages to tabs in a browser, which is my case. Also, I couldn't find the range of message types that are allowed to be sent with BroadcastSystemMessage().
I have a Windows service which starts another application using CreateProcess. Thus, the application runs with SYSTEM privileges. This application calls LsaEnumerateLogonSessions, which returns the error code 8 (Not enough storage is available to process this command.). The service and the application are run under Windows 7 x64.
ULONG luLogonSessionCount = 0;
LUID *pLogonSessionList = NULL;
NTSTATUS lNtStatus = LsaEnumerateLogonSessions(
&luLogonSessionCount, &pLogonSessionList );
LsaNtStatusToWinError( lNtStatus ) returns 8. Does anyone know the cause of this?
Thanks in advance!
Most services nowadays run under a service account, for security reasons. Check that your service has adequate permissions. What is the actual NTSTATUS result?