GetHostAddresses timeout - windows

When calling Dns.GetHostAddresses("an_hostname_that_does_not_exist"); on windows 10 I get a 30 seconds blocking call until getting an exception (when the hostname does not exist). On windows 2019 it is more in the 10 seconds range and on windows server 2012 it is less than 1 second.
Is there a way to configure the duration of the timeout when calling gethostbyname (mainly for Windows 2019) ?
NB : I can not change the call to Dns.GetHostAddresses but I can change any configuration on the client machine
NB : Dns.GetHostAddresses looks to ultimately resolve to the below call.
[DllImport("ws2_32.dll", CharSet = CharSet.Ansi, SetLastError = true, ThrowOnUnmappableChar = true, BestFitMapping = false)]
internal static extern IntPtr gethostbyname([In] string host);
NB : I found that but it looks to be for old windows version and I don't have anything in my registry : https://learn.microsoft.com/en-us/previous-versions//cc977482(v=technet.10)?redirectedfrom=MSDN

Related

Did SHOpenWithDialog API change in Windows 10?

I have a function which allows the user to edit a file, either with their default program, or choose a program using SHOpenFileDialog().
I'm calling it by PInvoke in C# (https://www.pinvoke.net/default.aspx/shell32/SHOpenWithDialog.html):
[DllImport("shell32.dll", EntryPoint = "SHOpenWithDialog", CharSet = CharSet.Unicode)]
private static extern int SHOpenWithDialog(IntPtr hWndParent, ref tagOPENASINFO oOAI);
I call it with flags OAIF_HIDE_REGISTRATION | OAIF_EXEC.
Under Windows 7, it returns 1 on success. Under Windows 10, it returns 0 on success. The documentation claims it returns S_OK, which is 0, but that page was created on 2018/12/05, so I don't know what the previous documentation for it said.
What is the correct way to check the return code? Should I be checking for either 0 or 1 return value? Or should I be checking the Environment.OSVersion and checking for different return codes based on the OS version? Can it ever returns 1 under Windows 10 as an error condition?

Embarcadero Rad Studio Firemonkey Indy POP3 IPv6 socket error 11004

I have the following problem. I use Embarcadero Rad Studio 10.1 Berlin Firemonkey. I want to connect to a POP3 server within an IPv6 network where IPv4 is not enabled and I get the socket error # 11004 error. My code is:
int port = 110;
pop3->Host = ...
pop3->Username = ...
pop3->Password = ..
pop3->AuthType = patUserPass;
pop3->IOHandler = iOHandlerStack;
iOHandlerStack->IPVersion = TIdIPVersion::Id_IPv6;
pop3->UseTLS = utNoTLSSupport;
pop3->Port = port;
iOHandlerStack->Port = port;
try
{
pop3->ConnectTimeout = 5000;
pop3->Connect();
int msgc = pop3->CheckMessages();
pop3->Disconnect();
ShowMessage("OK: " + IntToStr(msgc));
}
catch (Exception &exc)
{
ShowMessage(exc.Message);
}
If I use the application within an IPv4 network then after connecting the IPVersion property is set to Id_IPv4 automatically and there is no problem.
Interesting thing is that the following code works within IPv6 network:
IdTCPClient->IPVersion = TIdIPVersion::Id_IPv6;
IdTCPClient->Host = ...
IdTCPClient->Port = 80;
IdTCPClient->Connect();
IdTCPClient->Disconnect();
ShowMessage("OK");
Any suggestion?
You need to set the pop3->IPVersion property (which is inherited from TIdTCPClient) instead of the iOHandlerStack->IPVersion property directly.
Connect() overrides the IOHandler's IPVersion property value with the higher layer TIdTCPClient::IPVersion property value.
So, if you are leaving pop3->IPVersion to its default value of Id_IPv4, that would explain why you can't connect using IPv6. And why your TIdTCPClient example works.
Also, you don't need to set the iOHandlerStack->Port property manually, Connect() handles that as well.

InitiateShutdown fails with RPC_S_SERVER_UNAVAILABLE error for a remote computer

I'm trying to implement rebooting of a remote computer with InitiateShutdown API using the following code, but it fails with RPC_S_SERVER_UNAVAILABLE or 1722 error code:
//Process is running as administrator
//Select a remote machine to reboot:
//INFO: Tried it with and w/o two opening slashes.
LPCTSTR pServerName = L"192.168.42.105";
//Or use 127.0.0.1 if you don't have access to another machine on your network.
//This will attempt to reboot your local machine.
//In that case make sure to call shutdown /a /m \\127.0.0.1 to cancel it.
if(AdjustPrivilege(NULL, L"SeShutdownPrivilege", TRUE) &&
AdjustPrivilege(pServerName, L"SeRemoteShutdownPrivilege", TRUE))
{
int nErrorCode = ::InitiateShutdown(pServerName, NULL, 30,
SHUTDOWN_INSTALL_UPDATES | SHUTDOWN_RESTART, 0);
//Receive nErrorCode == 1722, or RPC_S_SERVER_UNAVAILABLE
}
BOOL AdjustPrivilege(LPCTSTR pStrMachine, LPCTSTR pPrivilegeName, BOOL bEnable)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
BOOL bRes = FALSE;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;
if(LookupPrivilegeValue(pStrMachine, pPrivilegeName, &tkp.Privileges[0].Luid))
{
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;
bRes = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
int nOSError = GetLastError();
if(bRes)
{
if(nOSError != ERROR_SUCCESS)
bRes = FALSE;
}
}
CloseHandle(hToken);
return bRes;
}
So to prepare for this code to run I do the following on this computer, which is Windows 7 Pro (as I would do for the Microsoft's shutdown tool):
Run the following "as administrator" to allow SMB access to the logged in user D1 on the 192.168.42.105 computer (per this answer):
NET USE \\192.168.42.105\IPC$ 1234 /USER:D1
Run the process with my code above "as administrator".
And then do the following on remote computer, or 192.168.42.105, that has Windows 7 Pro (per answer here with most upvotes):
Control Panel, Network and Sharing Center, Change Advanced Sharing settings
"Private" enable "Turn on File and Printer sharing"
Set the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
LocalAccountTokenFilterPolicy=dword:1
RUN secpol.msc, then go to Local Security Policy, Security Settings, Local Policies, User Rights Assignment. Add "Everyone" to "Force shutdown from a remote system". (Just remember to remove it after you're done testing!)
Note that the following shutdown command seems to work just fine to reboot the remote computer:
shutdown /r /m \\192.168.42.105 /t 30
What am I missing with my code?
EDIT:
OK. I will admit that I was merely interested in why InitiateShutdown doesn't seem to "want" to work with a remote server connection, while InitiateSystemShutdownEx or InitiateSystemShutdown had no issues at all. (Unfortunately the latter two did not have the dwShutdownFlags parameter, which I needed to pass the SHUTDOWN_INSTALL_UPDATES flag to, which caused my persistence...)
At this point I had no other way of finding out than dusting out a copy of WinDbg... I'm still trying to dig into it, but so far this is what I found...
(A) It turns out that InitiateSystemShutdownEx internally uses a totally different RPC call. W/o too many details, it initiates RPC binding with RpcStringBindingComposeW using the following parameters:
ObjUuid = NULL
ProtSeq = ncacn_np
NetworkAddr = \\192.168.42.105
EndPoint = \\PIPE\\InitShutdown
Options = NULL
or the following binding string:
ncacn_np:\\\\192.168.42.105[\\PIPE\\InitShutdown]
(B) While InitiateShutdown on the other hand uses the following binding parameters:
ObjUuid = 765294ba-60bc-48b8-92e9-89fd77769d91
ProtSeq = ncacn_ip_tcp
NetworkAddr = 192.168.42.105
EndPoint = NULL
Options = NULL
which it later translates into the following binding string:
ncacn_np:\\\\192.168.42.105[\\PIPE\\lsarpc]
that it uses to obtain the RPC handle that it passes to WsdrInitiateShutdown (that seems to have its own specification):
So as you see, the InitiateShutdown call is technically treated as Unknown RPC service (for the UUID {765294ba-60bc-48b8-92e9-89fd77769d91}), which later causes a whole bunch of credential checks between the server and the client:
which, honestly, I'm not sure I want to step into with a low-level debugger :)
At this stage I will say that I am not very well versed on "Local Security Authority" interface (or the \PIPE\lsarpc named pipe configuration.) So if anyone knows what configuration is missing on the server side to allow this RPC call to go through, I would appreciate if you could post your take on it?

Ping request : hide console window and differentiate "not responding" from response : no response

I'm making ping requests to all the server on my domain with Qt
I found inspiration here : how to check computer's state using Qt?
and did like this :
int exitCode = QProcess::execute("ping", QStringList() << "-n 1" << "hostname");
if (0 == exitCode) {
// it's alive
} else {
// it's dead
}
Its working (mostly)
But, here is two problem I can't find solution for :
When I launch, some ugly windows console show up for all the ping, how to hide them ?
Some server are known by the DNS but not working anymore : resulting in this message for a ping :
****************> ping oldserverNotWorkingAnymore
sending a 'ping' request for oldserverNotWorkingAnymore.mydomain [172.20.*.*] with 32 bytes of data
response from 172.20.*.* : Impossible to call host
response from 172.20.*.* : Impossible to call host
response from 172.20.*.* : Impossible to call host
response from 172.20.*.* : Impossible to call host
stat : send = 4, received = 4, lost = 0
which result in the program thinking the host exist while it's not
How to differentiate from a really working ping ?

Unable to connect to ftp server

I'm trying to connect to an ftp server through a powerbuilder application using windows api functions. I manage to connect to the ftp server through Internet Explorer (so I don't think it's a permission problem) but the application fails for some unknown reason.
String ls_Null, &
ls_id
Integer li_rc
li_rc = 1
IF Not InternetAutodial(AUTODIAL_FORCE_UNATTENDED, 0) THEN
f_write_to_err_log('IMPORT Unable To Connect Internet - Dialup')
li_rc = -1
ELSE
SetNull(ls_Null)
ls_id = "Care_Dsend"
al_internet_handle = InternetOpen(ls_id, INTERNET_OPEN_TYPE_DIRECT, ls_Null, ls_Null, 0)
IF al_internet_handle > 0 THEN
al_ftp_connect_handle = InternetConnect(al_internet_handle, is_ftp_url, il_ftp_port, is_ftp_user, is_ftp_password, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, al_ref)
END IF
END IF
Return li_rc
//al_internet_handle, al_ftp_connect_handle are by ref long parms
//al_ref is a by ref unsignedlong parm
//is_ftp_url, is_ftp_user, is_ftp_password are strings
//il_ftp_port is long
The function manages to return a handle from the InternetOpen api function, but returns 0 from the InternetConnect function.
Any ideas?
Ok, I found out what the problem was. I was missing ;Ansi at the end of my function declaration as in :
Function ulong InternetOpen (ref
string lpszAgent, ulong dwAccessType,
ref string lpszProxy, ref string
lpszProxyBypass, ulong dwFlags)
Library "WININET.DLL" Alias for
"InternetOpenA ;Ansi"
Can you post your Local External Functions or whatever you are using for InternetAutodial(), InternetOpen() etc? Those are not built-in functions (at least not in my Powerbuilder 11.2) and they don't look like PFC. Also, what version of Powerbuilder are you using.
Alternatively, you might want to look at these links:
Upload a file using FTP - Real's Powerbuilder HowTo (also uses a windows batch file)
Internet services example - PFC guide (uses PFC)

Resources