Write a daemon on Windows (8) Get the process path
To protect a process, you need to know that the process is not there. We assume that there will only be one instance of the process to be guarded (and this is most of the case).
I'm going to walk through all the processes on the system, and then determine if the process exists by determining whether their path is consistent with the process being guarded.
Traversal process everyone knows to use the CreateToolhelp32Snapshot series API, but they finally get the process EXE name, not the full path, if you can only rely on the name to achieve the purpose, but sometimes still have to take the full path, this will be more reliable.
So the question is, how to get to the full path of the process?
First came the Getmodulefilenameex. Most of the time, we can use this function to get the full path of the process, and this function is available on all platforms, but have you ever noticed such a passage:
(MSDN documentation from VS2008)
This function is defective. In addition to this problem, there is a problem: If you are 32 process to get a full path of a 64-bit process, there may also be errors, specifically, I wrote a very early post http://blog.csdn.net/mkdym/article/details/8688597.
Of course, Microsoft also said, you can also use Getprocessimagefilename and queryfullprocessimagename two functions ah.
So then, Getprocessimagefilename. This function does not exist Getmodulefilenameex two problems, but it does not support Windows2000, of course, if you do not need to support Windows2000 this antique, you do not have to ignore this shortcoming. However, it has other problems:
1. This guy returns a kernel name, like \device\harddisk0\partition1\winnt\system32\ctype.nls. Kernel name I'm not afraid, we use Querydosdevice Reverse acquisition: First use Querydosdevice to obtain the drive name and the kernel name of all the disk corresponding relationship, and then the newly acquired kernel name to replace the previous part of the. You have to search the Internet, it is all this way.
Think this is over? See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217 (v=vs.85). aspx for dynamic disk issues, This question I mention: in the case of dynamic disk, the drive link will have two layers, this you can see from the WinObj, and Querydosdevice can only get to the first layer, Getprocessimagefilename return is the second layer! I'll take a walk! After a search on the internet, many people give the answer is repeatedly called Querydosdevice on the results, I can only for these people, oh, maybe their computer is more special, querydosdevice can use that way.
On the issue of dynamic disk, you can also see the csdn I gave above the post, that is I found the process of the problem.
What to do? Later forgot to see in that forum, with the kernel function ntquerysymboliclinkobject can do querydosdevice the same thing, after the experiment, this function can be repeated on the results of the call, can get to the bottom of the kernel name. Well, this problem is solved.
Of course, the normal machine will not have dynamic disks.
2. When you look at the "dynamic Disk" issue on the MSDN page, you should be aware that this function will return a short path name, so let's take note. Convert each returned path to a growth path name, whether it is a short path name (I don't know if it is a short path name, or not). While I was testing it, it returned a long path name.
Here is also a point, I gave the process to take a snapshot, the moment the drive is determined, so there is no need to get each process path at the time to get all the name of the drive, only need to be in the beginning of the loop to prepare these names, and then traverse the time directly to use.
Well, using this API is such a hassle.
Finally we say queryfullprocessimagename. This function is all good, is the platform requirements too high, it is vista and above Ah, so can only be used.
Finally I get the path of the process is this: if there is a queryfullprocessimagename function, use this function, no word first on the Getmodulefilenameex, If Getmodulefilenameex goes wrong, then getprocessimagefilename. Put the most troublesome in the end.
Class name Cprocesspathquery.
When you look at the code, you may notice that I use a For loop when I'm dealing with it because I don't know how long the process path is, and if the error code says that the buffer is not enough, I'll try again, but I can't retry indefinitely, there's a limit.
After the process path is fetched, because it is possible that getprocessimagefilename gets it, it is a kernel name that needs to be converted, and the transformation class is cdospathconverter.
The process traversal class is cprocessscanner, and you can see that I put a cdospathconverter instance in it, initialized along with the initialization of the traversal class.
When traversing a process, it is important to note that there are several types of special processes that we do not get to the path, or that it is meaningless to get their paths, and you can see the comments of the cprocesspathquery.
One thing to note, be sure to mention the right, otherwise there will be a lot of process because we have insufficient authority and query failed.
Source: Https://git.oschina.net/mkdym/DaemonSvc.git (Master) && Https://github.com/mkdym/DaemonSvc.git (for lifting).
Thursday, November 19, 2015
Write a daemon on Windows (8) Get the process path