22
22
23
23
#include < comdef.h>
24
24
#include < Lmcons.h>
25
+ #include < psapi.h>
26
+ #include < RestartManager.h>
25
27
#include < shlguid.h>
26
28
#include < shlobj.h>
27
29
#include < string>
@@ -43,6 +45,72 @@ static const char runPathC[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\C
43
45
44
46
namespace OCC {
45
47
48
+ QVector<Utility::ProcessInfosForOpenFile> Utility::queryProcessInfosKeepingFileOpen (const QString &filePath)
49
+ {
50
+ QVector<ProcessInfosForOpenFile> results;
51
+
52
+ DWORD restartManagerSession = 0 ;
53
+ WCHAR restartManagerSessionKey[CCH_RM_SESSION_KEY + 1 ] = {0 };
54
+ auto errorStatus = RmStartSession (&restartManagerSession, 0 , restartManagerSessionKey);
55
+ if (errorStatus != ERROR_SUCCESS) {
56
+ return results;
57
+ }
58
+
59
+ LPCWSTR files[] = {reinterpret_cast <LPCWSTR>(filePath.utf16 ())};
60
+ errorStatus = RmRegisterResources (restartManagerSession, 1 , files, 0 , NULL , 0 , NULL );
61
+ if (errorStatus != ERROR_SUCCESS) {
62
+ RmEndSession (restartManagerSession);
63
+ return results;
64
+ }
65
+
66
+ DWORD rebootReasons = 0 ;
67
+ UINT rmProcessInfosNeededCount = 0 ;
68
+ std::vector<RM_PROCESS_INFO> rmProcessInfos;
69
+ auto rmProcessInfosRequestedCount = static_cast <UINT>(rmProcessInfos.size ());
70
+ errorStatus = RmGetList (restartManagerSession, &rmProcessInfosNeededCount, &rmProcessInfosRequestedCount, rmProcessInfos.data (), &rebootReasons);
71
+
72
+ if (errorStatus == ERROR_MORE_DATA) {
73
+ rmProcessInfos.resize (rmProcessInfosNeededCount, {});
74
+ rmProcessInfosRequestedCount = static_cast <UINT>(rmProcessInfos.size ());
75
+ errorStatus = RmGetList (restartManagerSession, &rmProcessInfosNeededCount, &rmProcessInfosRequestedCount, rmProcessInfos.data (), &rebootReasons);
76
+ }
77
+
78
+ if (errorStatus != ERROR_SUCCESS || rmProcessInfos.empty ()) {
79
+ RmEndSession (restartManagerSession);
80
+ return results;
81
+ }
82
+
83
+ for (size_t i = 0 ; i < rmProcessInfos.size (); ++i) {
84
+ const auto processHandle = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE , rmProcessInfos[i].Process .dwProcessId );
85
+ if (!processHandle) {
86
+ continue ;
87
+ }
88
+
89
+ FILETIME ftCreate, ftExit, ftKernel, ftUser;
90
+
91
+ if (!GetProcessTimes (processHandle, &ftCreate, &ftExit, &ftKernel, &ftUser)
92
+ || CompareFileTime (&rmProcessInfos[i].Process .ProcessStartTime , &ftCreate) != 0 ) {
93
+ CloseHandle (processHandle);
94
+ continue ;
95
+ }
96
+
97
+ WCHAR processFullPath[MAX_PATH];
98
+ DWORD processFullPathLength = MAX_PATH;
99
+ if (QueryFullProcessImageNameW (processHandle, 0 , processFullPath, &processFullPathLength) && processFullPathLength <= MAX_PATH) {
100
+ const auto processFullPathString = QDir::fromNativeSeparators (QString::fromWCharArray (processFullPath));
101
+ const QFileInfo fileInfoForProcess (processFullPathString);
102
+ const auto processName = fileInfoForProcess.fileName ();
103
+ if (!processName.isEmpty ()) {
104
+ results.push_back (Utility::ProcessInfosForOpenFile{rmProcessInfos[i].Process .dwProcessId , processName});
105
+ }
106
+ }
107
+ CloseHandle (processHandle);
108
+ }
109
+ RmEndSession (restartManagerSession);
110
+
111
+ return results;
112
+ }
113
+
46
114
void Utility::setupFavLink (const QString &folder)
47
115
{
48
116
// First create a Desktop.ini so that the folder and favorite link show our application's icon.
0 commit comments