A Microsoft platform for building and publishing apps for Windows devices.
IApplicationActivationManager race condition
IApplicationActivationManager::ActivateApplication() and related methods return a process ID (PID) as an out parameter. The process ID can then be used in a call to OpenProcess() to retrieve a process HANDLE so to gather any additional information or synchronize with the spawned process.
Unfortunately, testing on Windows 10 21H2 suggests that there's a race condition between retrieving the process ID from the ActivateApplication() methods and calling OpenProcess(). ApplicationActivationManager should really keep an open HANDLE to the spawned process, until disposed by the last call to Release(), to avoid such race condition.
Thank you,
Luca
Developer technologies | Universal Windows Platform (UWP)
Windows development | Windows API - Win32
-
-
-
RLWA32 • 52,571 Reputation points2022-07-26T21:27:40.207+00:00 So when OpenProcess fails what error code is returned by GetLastError? Is the same error code returned for each failure?
-
-
Viorel • 127K Reputation points2022-07-27T02:49:21.563+00:00 Does it succeed after several delays and trials?
-
Nico Zhu (Shanghai Wicresoft Co,.Ltd.) • 12,871 Reputation points2022-07-27T03:15:49.143+00:00 What's the first
dwDesiredAccessparameter you have used? -
lb90 • 1 Reputation point
2022-07-27T07:57:14.423+00:00 The access rights parameter is set to PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE
-
lb90 • 1 Reputation point
2022-07-27T07:57:52.907+00:00 No, it keeps failing with the same error code
-
Nico Zhu (Shanghai Wicresoft Co,.Ltd.) • 12,871 Reputation points2022-07-27T08:13:41.353+00:00 Do you develop UWP app?
-
Nico Zhu (Shanghai Wicresoft Co,.Ltd.) • 12,871 Reputation points2022-07-27T08:27:55.307+00:00 Can you try to set the flag as ALL ?
-
Castorix31 • 91,876 Reputation points2022-07-27T08:54:35.683+00:00 testing on Windows 10 21H2
It works normally for me on Windows 10 21H1...
-
lb90 • 1 Reputation point
2022-07-27T09:19:07.507+00:00 I am using this sample code for testing: https://gist.github.com/lb90/b994c72ad1f0f53cfdc0d3bbbbb76728. The Windows Calculator UserModelID may differ on your system, so you may need to get it using PowerShell:
PS C:\Users\lucab> Get-StartApps Calculator Name AppID ---- ----- Calculator Microsoft.WindowsCalculator_8wekyb3d8bbwe!AppCopy the AppID from the PowerShell output and paste it into the source file, replacing the value of the global aumid variable.
Now launch the test sample. Windows Calculator will show up. Close the Calculator app and then press any key on the command prompt.
-
lb90 • 1 Reputation point
2022-07-27T09:21:32.02+00:00 No, I use ApplicationActivationManager to launch third-party apps. I am currently testing with apps from MS, e.g. Camera, Calculator, etc.
-
lb90 • 1 Reputation point
2022-07-27T09:25:15.07+00:00 I have now tested with PROCESS_ALL_ACCESS, but it's still unsuccessfull
-
Castorix31 • 91,876 Reputation points2022-07-27T09:26:14.823+00:00 Close the Calculator app
If you close the app, it is normal that it fails...
(an the documented AUMIDs are the same on all OS)
-
RLWA32 • 52,571 Reputation points2022-07-27T09:39:20.063+00:00 Tested on Win 10 21H1 with PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE for calculator and paint. Works normally.
-
lb90 • 1 Reputation point
2022-07-27T09:39:47.107+00:00 Thanks Castorix! Yeah, but it's racy, because one cannot guarantee that OpenProcess will be executed on time.
-
Castorix31 • 91,876 Reputation points2022-07-27T09:44:14.527+00:00 But while the application is running, it will work, like for any running app
If you close the application, the PID does not exist anymore (it is like if you call OpenProcess with 123456...) -
lb90 • 1 Reputation point
2022-07-27T09:53:35.737+00:00 Yeah, though theoretically the application could end up opening a different process, as PIDs are reused (though I agree that it's unlikely). Maybe if someone suspends the process with task manager that could happen...
I am writing a library that launches the application and passes a HANDLE back to the library user, so it can do whatever it wants with that (e.g. be notified when the spawned process exits, etc.). If I get ERROR_INVALID_PARAMETER from OpenProcess, I have to pass back NULL to the caller, but then the caller doesn't know why it has a NULL handle.
Anyway I guess I can live with that, after all it's extremely unlikely to ever happen :)
-
lb90 • 1 Reputation point
2022-07-27T10:00:26.877+00:00 Yes, it mostly works, it's just racy. See the example above. The thing here is that the API is not well-defined unless the COM object keeps a HANDLE internally (but it doesn't)
-
RLWA32 • 52,571 Reputation points2022-07-27T10:44:39.487+00:00 How is the started app being terminated? Are you closing it?
-
-
RLWA32 • 52,571 Reputation points2022-07-27T11:45:11.417+00:00 Maybe I'm just old and slow but I couldn't close either Calculator or Paint fast enough to cause OpenProcess to fail. :)
-
Castorix31 • 91,876 Reputation points2022-07-27T12:02:35.377+00:00 Because he used a pause in the sample the OP posted ...
_wsystem(L"pause"); -
RLWA32 • 52,571 Reputation points2022-07-27T12:09:38.097+00:00 Because he used a pause in the sample the OP posted ...
Well that's hardly proof of a serious race condition. I suppose on a heavily loaded system its possible for the thread to be preempted between the time that the app is started and OpenProcess is called to allow for app closure during that window but it seems unlikely.
-
lb90 • 1 Reputation point
2022-07-27T12:39:17.607+00:00 Yeah, I agree, it's extremely unlikely to ever happen. I just find it a bit odd that it doesn't keep a ref internally till the next launch, but definitely not a problem by all practical means :)
Sign in to comment