I've taken over maintenance of a Windows Service that was written many years ago.
My first task is to get the service running on Windows 7.
WinDbg shows that the service is erroring out on a call to GetAddressByName. (GetAddressByName returns 0 and the service shuts down.)
According to MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/ms738517%28v=vs.85%29.aspx), GetAddressByName is not available for use with Winsock v. 2.
Does the above mean that GetAddressByName will not work with Windows 7? (Does Winsock 1.x work on Windows 7?)
(Any recommendations for a function to use instead of GetAddressByName? )
I'm looking to see if anyone else has done this before.
Alternatively (GetAddressByName is supported on Win 7), any suggestions for debugging a call to GetAddressByName that's returning 0?
Best regards,
Mitch
GetAddressByName() is a legacy function from WinSock 1.x. It was removed in WinSock 2.0. Apps using WinSock 2.x should use getaddrinfo(), if not gethostbyname() (which is still available).
In any case, the documentation for GetAddressByName() says:
If the function succeeds, the return value is the number of CSADDR_INFO data structures written to the buffer pointed to by lpCsaddrBuffer.
If the function fails, the return value is SOCKET_ERROR( –1). To get extended error information, call GetLastError
Since GetAddressByName() is returning 0, it is succeeding but no addresses are being returned. Make sure the service code is handling that fact and not trying to access invalid buffer data.
Related
WSAStartup() can be called multiple times in a single process, as long as the requested version is supported by the WinSock dll and that calls to WSAStartup() and WSACleanup() are balanced.
In addition to that, Multiple sockets using different WinSock versions is allowed.
(see this post: Is it possible to tell if WSAStartup has been called in a process?)
In that case, how do these different WinSock versions coexist?
For example, what if I request the use of a specific WinSock version for my application, and my application also loads a third party dll that happens to request the use a different version? What version gets used, and when?
It says in the MS doc -
An application can call WSAStartup more than once if it needs to
obtain the WSADATA structure information more than once. On each such
call, the application can specify any version number supported by the
Winsock DLL.
The last sentence implies, that those subsequent calls don't actually request a different winsock version, just getting the existing one that's saved in wsadata.
If you wanted to change the winsock version in the middle of the program, I suppose you could call WSACleanup (as many times as needed), and "start fresh" with a new WSAStartup
Windows 7 introduced "Power Availability Requests". This feature allows applications to notify the OS that they require the display or whole system and therefore power management should be temporarily inhibited. The feature is documented here:
https://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/AvailabilityRequests.docx
The availability requests feature uses an object model and provides the functions PowerCreateRequest(), PowerSetRequest() and PowerClearRequest() to create requests, activate them and ultimately remove them. This functionality is very similar to the older SetThreadExecutionState() API available in Windows 2000 but allows multiple requests to be create per-thread and improves potential diagnostics by requiring each request to have a reason string.
The OS supplied POWERCFG.EXE utility can enumerate the current outstanding requests using the command:
POWERCFG -REQUESTS
Microsoft do not document how to enumerate requests with Windows API.
The CallNtPowerInformation() function in the SDK has been updated to support a new information level called "GetPowerRequestList". This looks very much like it could be the required API but is not documented.
Please does anyone know how to call CallNtPowerInformation(GetPowerRequestList..)?
Jim
Late answer, but, I found that it was easier to call this other function instead (since CallNtPowerInformation(GetPowerRequestList, ...) returned a not supported error):
PowerInformationWithPrivileges(GetPowerRequestList, 0, 0, bufout, 16384);
Function signature seemed to be the same, and you might have to define it and GetProcAddress from powrprof.dll yourself depending on what libs you have available.
Output format seemed to be a binary blob. If I had to guess, it's a list of int64's (even in 32-bit apps), first entry is # entries (call it x), next x entries are offsets in the blob for the real entries, which themselves are some kind of variable length blob/struct, probably correlating to each PowerRequest and/or type of request. Not complete info, but that should get other people started if they're serious about trying to make this work.
You need admin to call this function (you also need admin to call powercfg /requests, so this isn't too much of a surprise, though perhaps a shortcoming depending on your use case).
Put on your wayback hats...
I have to use DDE (sorry, absolutely no choice in this) to communicate with an industrial control system. The control system is the DDE server and runs on the same Windows 7 PC as my DDE client. The client uses MfcDDE as it's interface which in turn makes calls to the DdeClientTransaction() functions.
The DDE advise operations work as expected after calling MfcDDE to establish them with DdeClientTransaction(XTYP_ADVSTART). All data points of interest are successfully read through the advice mechanism.
Unfortunately, attempts to write data through the DdeClientTransaction(XTYP_POKE) function fails. Within my client, DdeGetLastError() returns DMLERR_INVALIDPARAMETER (16390 0x4006). Interestingly, DDESpy (yes, I am that desparate) is reporting DMLERR_POSTMSG_FAILED (16396 0x400C).
The client worked in its initial NT implementation, but rebuilt and running under Win7, the XTYPE_POKE is failing. I've contemplated both security and threading as possibilities.
I've been unsuccessful finding a pointing gun for DDE security changes between NT and Win7.
If it matters, the DdeClientTransaction() call is being made in a thread started with WinMain() calling through to AfxWinMain() and CDialog::DoModal() to get to client's functional code.
Thanks for any help you can provide...
Confirmed that DdeClientTransaction(XTYP_POKE) can only be called on the same thread upon which DdeInitialize() was called. The restriction may actually be the same thread upon which DdeConnect() was called, but my money is on the DdeInitialize() since the returned DDEIdInst is passed to DdeConnect(). I could be wrong.
Thanks for letting me work through this with you guys... :)
I made a GUI application that must run in my DELL server to send queries for 24 hours.
In case where the application is stopped by random users, or whatever it is, I created a service program that detects when it stops running, and executes it again.
The problem is, in service, FindWindow() doesn't properly work (always returns nullptr) because Microsoft changed its OS service policies since XP. And my service program has no way to find if the program is on the process list or not.
I found some solutions on the internet, which is to "allow service to interact with desktop on service panel" but since it was a long time ago so doesn't quite fit into the current OS version.
Should I use IPC instead? or any other ways to fix?
I believe that there has got to be a way to do this, because executing a process from service is also possible by using CreateProcessAsUser().
Any advice will be truly appreciated.
Thanks in advance.
So I did what Remy Lebeau suggessted for me, and it properly works in Windows 7, and 2008.
Here's how I went step by step.
Create a named mutex in the global namespace in the GUI application.
::CreateMutex(nullptr, false, L"Global\\MyMutex");
Check periodically if the mutex has disappeared or not
by using CreateMutex(), and do not forget to take care of the reference count to the handle.
HANDLE hDetector = ::CreateMutex(nullptr, false, L"Global\\MyMutex");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// The GUI application is still running.
// ...
::CloseHandle(hDetector);
}
else
{
// The GUI application is not running.
// ...
::CloseHandle(hDetector);
}
See it work.
I have developed a driver for Windows XP which is able to monitor the execution of processes.
A callback function receives the notifications using standard WDK API (PsSetCreateProcessNotifyRoutine).
The driver then decides if the process should be authorized or not; if not, it must block its execution/kill it.
What is the cleanest way to intercept execution that way? I do not mind if it is not documented, but I would rather not resort to hooking, if possible.
Ok, according to this document:
http://download.microsoft.com/download/4/4/b/44bb7147-f058-4002-9ab2-ed22870e3fe9/Kernal%20Data%20and%20Filtering%20Support%20for%20Windows%20Server%202008.doc
I need to install a minifilter for IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION and check for PageProtection == PAGE_EXECUTE.
PsSetCreateProcessNotifyRoutineEx (Vista+) will allow you to cause the process-creation operation to fail by changing the CreateInfo->CreationStatus member to an NTSTATUS error code.