ReactOS 0.4.16-dev-109-gf4cb10f
registry.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Functions to read RunOnceEx registry.
5 * COPYRIGHT: Copyright 2021 He Yang <1160386205@qq.com>
6 */
7
8#include "iernonce.h"
9
11
13 _In_ DWORD iIndex,
14 _Out_ LPTSTR pszName,
15 _Inout_ LPDWORD pnNameLength)
16{
17 return RegEnumValueW(m_hKey, iIndex, pszName, pnNameLength,
18 NULL, NULL, NULL, NULL);
19}
20
22 _In_ const ATL::CStringW &Name,
23 _In_ const ATL::CStringW &Value) :
24 m_Value(Value), m_Name(Name)
25{ ; }
26
28 _In_ CRegKeyEx &hParentKey)
29{
30 return hParentKey.DeleteValue(m_Name) == ERROR_SUCCESS;
31}
32
34{
35 CStringW CommandLine;
36 if (wcsncmp(m_Value, L"||", 2) == 0)
37 {
38 // Remove the prefix.
39 CommandLine = (LPCWSTR)m_Value + 2;
40 }
41 else
42 {
43 CommandLine = m_Value;
44 }
45
46 // FIXME: SHEvaluateSystemCommandTemplate is not implemented
47 // using PathGetArgsW, PathRemoveArgsW as a workaround.
48 LPWSTR szCommandLine = CommandLine.GetBuffer();
49 LPCWSTR szParam = PathGetArgsW(szCommandLine);
50 PathRemoveArgsW(szCommandLine);
51
52 SHELLEXECUTEINFOW Info = { 0 };
53 Info.cbSize = sizeof(Info);
55 Info.lpFile = szCommandLine;
56 Info.lpParameters = szParam;
57 Info.nShow = SW_SHOWNORMAL;
58
60
61 CommandLine.ReleaseBuffer();
62
63 if (!bSuccess)
64 {
65 return FALSE;
66 }
67
68 if (Info.hProcess)
69 {
71 CloseHandle(Info.hProcess);
72 }
73
74 return TRUE;
75}
76
78 _In_ const void *a,
79 _In_ const void *b)
80{
81 return lstrcmpW(((RunOnceExEntry *)a)->m_Name,
82 ((RunOnceExEntry *)b)->m_Name);
83}
84
87 _In_ const CStringW &ValueName)
88{
89 DWORD dwType;
90 DWORD cbData;
91
92 // Query data size
93 if (hKey.QueryValue(ValueName, &dwType, NULL, &cbData) != ERROR_SUCCESS)
94 return FALSE;
95
96 // Validate its format and size.
97 if (dwType != REG_SZ)
98 return TRUE;
99
100 if (cbData % sizeof(WCHAR) != 0)
101 return FALSE;
102
104 LPWSTR szBuffer = Buffer.GetBuffer((cbData / sizeof(WCHAR)) + 1);
105
106 if (hKey.QueryValue(ValueName, &dwType, szBuffer, &cbData) != ERROR_SUCCESS)
107 {
108 Buffer.ReleaseBuffer();
109 return FALSE;
110 }
111 szBuffer[cbData / sizeof(WCHAR)] = L'\0';
112 Buffer.ReleaseBuffer();
113
114 CStringW ExpandStr;
115 DWORD dwcchExpand = ExpandEnvironmentStringsW(Buffer, NULL, 0);
116 ExpandEnvironmentStringsW(Buffer, ExpandStr.GetBuffer(dwcchExpand + 1), dwcchExpand);
117 ExpandStr.ReleaseBuffer();
118
119 if (ValueName.IsEmpty())
120 {
121 // The default value specifies the section title.
123 }
124 else
125 {
127 }
128
129 return TRUE;
130}
131
133 _In_ CRegKeyEx &hParentKey,
134 _In_ const CStringW &lpSubKeyName) :
135 m_SectionName(lpSubKeyName)
136{
138 DWORD dwValueNum;
139 DWORD dwMaxValueNameLen;
142
143 if (m_RegKey.Open(hParentKey, lpSubKeyName) != ERROR_SUCCESS)
144 return;
145
147 &dwValueNum, &dwMaxValueNameLen,
148 NULL, NULL, NULL);
149 if (Error != ERROR_SUCCESS)
150 return;
151
152 for (DWORD i = 0; i < dwValueNum; i++)
153 {
154 LPWSTR szValueName;
155 DWORD dwcchName = dwMaxValueNameLen + 1;
156
157 szValueName = ValueName.GetBuffer(dwMaxValueNameLen + 1);
158 Error = m_RegKey.EnumValueName(i, szValueName, &dwcchName);
159 ValueName.ReleaseBuffer();
160
161 if (Error != ERROR_SUCCESS)
162 {
163 // TODO: error handling
164 return;
165 }
166
168 return;
169 }
170
171 // Sort entries by name in string order.
174
176 return;
177}
178
179// Copy constructor, CSimpleArray needs it.
181 m_SectionName(Section.m_SectionName),
182 m_bSuccess(Section.m_bSuccess),
183 m_SectionTitle(Section.m_SectionTitle),
184 m_EntryList(Section.m_EntryList)
185{
186 m_RegKey.Attach(Section.m_RegKey);
187}
188
190 _In_ CRegKeyEx &hParentKey)
191{
192 m_RegKey.Close();
193 return hParentKey.RecurseDeleteKey(m_SectionName) == ERROR_SUCCESS;
194}
195
197{
198 return m_EntryList.GetSize();
199}
200
202 _Inout_ UINT& iCompleteCnt,
203 _In_ const UINT iTotalCnt)
204{
206
207 for (int i = 0; i < m_EntryList.GetSize(); i++)
208 {
209 m_EntryList[i].Delete(m_RegKey);
210 bSuccess &= m_EntryList[i].Exec();
211 iCompleteCnt++;
212 // TODO: the meaning of the third param is still unknown, seems it's always 0.
213 if (g_Callback)
214 g_Callback(iCompleteCnt, iTotalCnt, NULL);
215 }
216 return bSuccess;
217}
218
220 _In_ const void *a,
221 _In_ const void *b)
222{
223 return lstrcmpW(((RunOnceExSection *)a)->m_SectionName,
224 ((RunOnceExSection *)b)->m_SectionName);
225}
226
228{
230 DWORD dwSubKeyNum;
231 DWORD dwMaxSubKeyNameLen;
234
235 Error = m_RegKey.Open(BaseKey,
236 L"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\");
237 if (Error != ERROR_SUCCESS)
238 {
239 return;
240 }
241
242 ULONG cchTitle;
243 Error = m_RegKey.QueryStringValue(L"Title", NULL, &cchTitle);
244 if (Error == ERROR_SUCCESS)
245 {
246 Error = m_RegKey.QueryStringValue(L"Title", m_Title.GetBuffer(cchTitle + 1), &cchTitle);
247 m_Title.ReleaseBuffer();
248 if (Error != ERROR_SUCCESS)
249 return;
250 }
251
253 if (Error != ERROR_SUCCESS)
254 {
255 m_dwFlags = 0;
256 }
257
259 &dwSubKeyNum, &dwMaxSubKeyNameLen,
260 NULL, NULL, NULL, NULL, NULL, NULL);
261 if (Error != ERROR_SUCCESS)
262 return;
263
265
266 for (DWORD i = 0; i < dwSubKeyNum; i++)
267 {
268 LPWSTR szSubKeyName;
269 DWORD dwcchName = dwMaxSubKeyNameLen + 1;
270
271 szSubKeyName = SubKeyName.GetBuffer(dwMaxSubKeyNameLen + 1);
272 Error = m_RegKey.EnumKey(i, szSubKeyName, &dwcchName);
273 SubKeyName.ReleaseBuffer();
274
275 if (Error != ERROR_SUCCESS)
276 {
277 // TODO: error handling
278 return;
279 }
280
282 return;
283 }
284
285 // Sort sections by name in string order.
288
290 return;
291}
292
294{
296
297 UINT TotalCnt = 0;
298 UINT CompleteCnt = 0;
299 for (int i = 0; i < m_SectionList.GetSize(); i++)
300 {
301 TotalCnt += m_SectionList[i].GetEntryCnt();
302 }
303
304 // Execute items from registry one by one, and remove them.
305 for (int i = 0; i < m_SectionList.GetSize(); i++)
306 {
307 if (hwnd)
309
310 bSuccess &= m_SectionList[i].Exec(CompleteCnt, TotalCnt);
311 m_SectionList[i].CloseAndDelete(m_RegKey);
312 }
313
314 m_RegKey.DeleteValue(L"Title");
315 m_RegKey.DeleteValue(L"Flags");
316
317 // Notify the dialog all sections are handled.
318 if (hwnd)
320 return bSuccess;
321}
322
324{
325 if (bSilence ||
328 {
329 return Exec(NULL);
330 }
331 else
332 {
333 // The dialog is responsible to create a thread and execute.
334 ProgressDlg dlg(*this);
335 return dlg.RunDialogBox();
336 }
337}
338
341 _In_ const CStringW& SubKeyName)
342{
344 if (!Section.m_bSuccess)
345 {
346 return FALSE;
347 }
348
349 if (!Section.m_SectionTitle.IsEmpty())
350 {
352 }
353 m_SectionList.Add(Section);
354
355 // The copy constructor of RunOnceExSection didn't detach
356 // the m_RegKey while it's attached to the one in the array.
357 // So we have to detach it manually.
358 Section.m_RegKey.Detach();
359 return TRUE;
360}
BOOL Error
Definition: chkdsk.c:66
LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired=KEY_READ|KEY_WRITE) noexcept
Definition: atlbase.h:1173
LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG *pnChars) noexcept
Definition: atlbase.h:1240
HKEY m_hKey
Definition: atlbase.h:1115
LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD &dwValue) noexcept
Definition: atlbase.h:1217
HKEY Detach() noexcept
Definition: atlbase.h:1166
LONG Close() noexcept
Definition: atlbase.h:1156
LONG EnumKey(DWORD iIndex, LPTSTR pszName, LPDWORD pnNameLength, FILETIME *pftLastWriteTime=NULL) noexcept
Definition: atlbase.h:1421
LONG DeleteValue(LPCTSTR lpszValue) noexcept
Definition: atlbase.h:1401
void Attach(HKEY hKey) noexcept
Definition: atlbase.h:1151
int GetSize() const
Definition: atlsimpcoll.h:104
BOOL Add(const T &t)
Definition: atlsimpcoll.h:58
bool IsEmpty() const noexcept
Definition: atlsimpstr.h:394
Definition: bufpool.h:45
LONG EnumValueName(_In_ DWORD iIndex, _Out_ LPTSTR pszName, _Inout_ LPDWORD pnNameLength)
Definition: registry.cpp:12
BOOL RunDialogBox()
Definition: dialog.cpp:30
RunOnceExEntry(_In_ const ATL::CStringW &Name, _In_ const ATL::CStringW &Value)
Definition: registry.cpp:21
ATL::CStringW m_Value
Definition: registry.h:34
ATL::CStringW m_Name
Definition: registry.h:35
BOOL Delete(_In_ CRegKeyEx &hParentKey)
Definition: registry.cpp:27
BOOL Exec() const
Definition: registry.cpp:33
BOOL HandleSubKey(_In_ CRegKeyEx &hKey, _In_ const CStringW &SubKeyName)
Definition: registry.cpp:339
RunOnceExInstance(_In_ HKEY BaseKey)
Definition: registry.cpp:227
BOOL Run(_In_ BOOL bSilence)
Definition: registry.cpp:323
BOOL Exec(_In_opt_ HWND hwnd)
Definition: registry.cpp:293
CStringW m_Title
Definition: registry.h:99
CSimpleArray< RunOnceExSection > m_SectionList
Definition: registry.h:98
CRegKeyEx m_RegKey
Definition: registry.h:90
ATL::CStringW m_SectionTitle
Definition: registry.h:63
BOOL CloseAndDelete(_In_ CRegKeyEx &hParentKey)
Definition: registry.cpp:189
UINT GetEntryCnt() const
Definition: registry.cpp:196
CSimpleArray< RunOnceExEntry > m_EntryList
Definition: registry.h:64
BOOL HandleValue(_In_ CRegKeyEx &hKey, _In_ const CStringW &ValueName)
Definition: registry.cpp:85
RunOnceExSection(_In_ CRegKeyEx &hParentKey, _In_ const CStringW &lpSubKeyName)
Definition: registry.cpp:132
BOOL Exec(_Inout_ UINT &iCompleteCnt, _In_ const UINT iTotalCnt)
Definition: registry.cpp:201
ATL::CStringW m_SectionName
Definition: registry.h:54
CRegKeyEx m_RegKey
Definition: registry.h:55
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2830
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
#define CloseHandle
Definition: compat.h:739
#define WM_SETINDEX
Definition: dialog.h:18
#define FLAGS_NO_STAT_DIALOG
Definition: registry.h:16
int RunOnceExSectionCmp(_In_ const void *a, _In_ const void *b)
Definition: registry.cpp:219
int RunOnceExEntryCmp(_In_ const void *a, _In_ const void *b)
Definition: registry.cpp:77
RUNONCEEX_CALLBACK g_Callback
Definition: iernonce.cpp:11
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
Definition: path.c:779
LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
Definition: path.c:506
static BOOLEAN bSuccess
Definition: drive.cpp:477
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
RUNONCEEX_CALLBACK g_Callback
Definition: iernonce.cpp:11
VOID(CALLBACK * RUNONCEEX_CALLBACK)(_In_ UINT CompleteCnt, _In_ UINT TotalCnt, _In_ DWORD_PTR dwReserved)
Definition: iernonce_undoc.h:9
#define REG_SZ
Definition: layer.c:22
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
unsigned int UINT
Definition: ndis.h:50
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4725
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2424
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define SW_SHOWNORMAL
Definition: winuser.h:773
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
CHAR * LPTSTR
Definition: xmlstorage.h:192
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185