Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
557 views
in Technique[技术] by (71.8m points)

c - Determine if process started from shortcut

Is it possible to determine if another process/window was started using a shortcut? The purpose being to then read that shortcut to obtain the startup settings: start-in folder, run as admin, etc. Maybe there is a way to find out the catalyst/caller of the program (User/Application w admin privileges/shortcut)?

I'm aware of using the Windows Driver Kit to determine it. Although this is rather tricky to develop in among other things.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is it possible to determine if another process/window was started using a shortcut?

Yes, but not easily.

As mentioned in an answer to a similar question, a process can find out if itself was started by a shortcut by calling GetStartupInfo() and checking for the STARTF_TITLEISLINKNAME flag. This is documented on MSDN:

GetStartupInfo function

Retrieves the contents of the STARTUPINFO structure that was specified when the calling process was created.

STARTUPINFO structure

dwFlags
A bitfield that determines whether certain STARTUPINFO members are used when the process creates a window. This member can be one or more of the following values.

...
STARTF_TITLEISLINKNAME
0x00000800
The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked to start this process. This is typically set by the shell when a .lnk file pointing to the launched application is invoked. Most applications will not need to set this value.

Once you have the path to the .lnk file, you can parse it using the IShellLink interface as needed (see Shell Links for more details).

Now, that being said, you cannot directly retrieve the STARTUPINFO structure of another process. However, you can retrieve it indirectly, by injecting code into the target process (using CreateRemoteThread() or SetWindowsHookEx()), and then have that code call GetStartupInfo() and communicate the desired information back to your process using an IPC mechanism of your choosing (WM_COPYDATA, named pipe, mailslot, socket, COM, RPC, etc).

Or, there is an unofficial way (subject to OS version) to get many of the same STARTUPINFO field values, including the .lnk filename, without injecting any code into the target process. Use NtQueryInformationProcess() to get a pointer to the target process's PEB1 structure, which has a ProcessParameters field that is a pointer to an RTL_USER_PROCESS_PARAMETERS1 structure, which has a WindowTitle field (amongst other fields that contain values from STARTUPINFO). You can use OpenProcess() to get a HANDLE to the target process (you can get the process ID of an HWND using GetWindowThreadProcessId()), and then use ReadProcessMemory() to read the contents of the PEB and RTL_USER_PROCESS_PARAMETERS structures as needed.

1: Most of the content of the PEB and RTL_USER_PROCESS_PARAMETERS structures are not documented by MSDN, but are documented on http://undocumented.ntinternals.net (here and here).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...