ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
August 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
32 participants
304 discussions
Start a n
N
ew thread
01/01: [NTOSKRNL] Fix a nullptr dereference in IopStartDevice
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b2b1c054e4dad11fe6775…
commit b2b1c054e4dad11fe6775d10f35d65c68422e3b4 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Aug 5 22:14:44 2018 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Mon Aug 6 20:51:21 2018 +0200 [NTOSKRNL] Fix a nullptr dereference in IopStartDevice --- ntoskrnl/io/pnpmgr/pnpmgr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 62ad7a253f..e4cb7db6d6 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -786,7 +786,7 @@ IopStartDevice( { NTSTATUS Status; HANDLE InstanceHandle = NULL, ControlHandle = NULL; - UNICODE_STRING KeyName; + UNICODE_STRING KeyName, ValueString; OBJECT_ATTRIBUTES ObjectAttributes; if (DeviceNode->Flags & DNF_DISABLED) @@ -817,7 +817,10 @@ IopStartDevice( goto ByeBye; RtlInitUnicodeString(&KeyName, L"ActiveService"); - Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length + sizeof(UNICODE_NULL)); + ValueString = DeviceNode->ServiceName; + if (!ValueString.Buffer) + RtlInitUnicodeString(&ValueString, L""); + Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, ValueString.Buffer, ValueString.Length + sizeof(UNICODE_NULL)); // } ByeBye:
6 years, 4 months
1
0
0
0
02/02: [WINLOGON] Hack-fix for CORE-14877 ; see commit bcec1fd6.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=10c5bfb8feac6b37348e1…
commit 10c5bfb8feac6b37348e19a8dc3b33d967a7264a Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Mon Aug 6 17:30:21 2018 +0200 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Mon Aug 6 17:38:00 2018 +0200 [WINLOGON] Hack-fix for CORE-14877 ; see commit bcec1fd6. --- base/system/winlogon/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/system/winlogon/setup.c b/base/system/winlogon/setup.c index f5ef367318..af76e2a950 100644 --- a/base/system/winlogon/setup.c +++ b/base/system/winlogon/setup.c @@ -141,7 +141,7 @@ RunSetupThreadProc( CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); - SwitchDesktop(WLSession->WinlogonDesktop); + // SwitchDesktop(WLSession->WinlogonDesktop); TRACE ("RunSetup() done\n");
6 years, 4 months
1
0
0
0
01/02: [WINLOGON][MSGINA] Fix typo.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=40000a1716632cfbcf4f4…
commit 40000a1716632cfbcf4f40715be21570c8a90126 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Mon Aug 6 17:29:34 2018 +0200 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Mon Aug 6 17:37:38 2018 +0200 [WINLOGON][MSGINA] Fix typo. --- base/system/winlogon/sas.c | 2 +- dll/win32/msgina/gui.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base/system/winlogon/sas.c b/base/system/winlogon/sas.c index 0189953cff..e56ba639e7 100644 --- a/base/system/winlogon/sas.c +++ b/base/system/winlogon/sas.c @@ -586,7 +586,7 @@ HandleLogon( Session->hProfileInfo = ProfileInfo.hProfile; - /* Logon has successed. Play sound. */ + /* Logon has succeeded. Play sound. */ PlayLogonSound(Session); ret = TRUE; diff --git a/dll/win32/msgina/gui.c b/dll/win32/msgina/gui.c index d148088db3..a2466e8c47 100644 --- a/dll/win32/msgina/gui.c +++ b/dll/win32/msgina/gui.c @@ -53,7 +53,7 @@ SetWelcomeText(HWND hWnd) TRACE("SetWelcomeText(%p)\n", hWnd); - /* Get the path of userinit */ + /* Open the Winlogon key */ rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0,
6 years, 4 months
1
0
0
0
01/01: [SYSSETUP] SetupStartService: Wait until the service is running
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8f911f21b8eb8178a0d09…
commit 8f911f21b8eb8178a0d09ec5fdf8eb664cf0733f Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Sun Aug 5 20:02:22 2018 +0200 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Sun Aug 5 20:02:22 2018 +0200 [SYSSETUP] SetupStartService: Wait until the service is running --- dll/win32/syssetup/install.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/dll/win32/syssetup/install.c b/dll/win32/syssetup/install.c index 63fa4a28e9..e9b5745def 100644 --- a/dll/win32/syssetup/install.c +++ b/dll/win32/syssetup/install.c @@ -1508,7 +1508,9 @@ SetupStartService( { SC_HANDLE hManager = NULL; SC_HANDLE hService = NULL; + SERVICE_STATUS ServiceStatus; DWORD dwError = ERROR_SUCCESS; + DWORD dwRetries = 0; hManager = OpenSCManagerW(NULL, NULL, @@ -1521,7 +1523,7 @@ SetupStartService( hService = OpenServiceW(hManager, lpServiceName, - SERVICE_START); + SERVICE_START | (bWait) ? SERVICE_QUERY_STATUS : 0); if (hService == NULL) { dwError = GetLastError(); @@ -1531,7 +1533,27 @@ SetupStartService( if (!StartService(hService, 0, NULL)) { dwError = GetLastError(); - goto done; + if (dwError != ERROR_SERVICE_ALREADY_RUNNING) + goto done; + + if (bWait) + { + for (;;) + { + if (!QueryServiceStatus(hService, &ServiceStatus)) + break; + + if (ServiceStatus.dwCurrentState != SERVICE_START_PENDING) + break; + + if (dwRetries == 30) + break; + + dwRetries++; + + Sleep(5000); + } + } } done:
6 years, 4 months
1
0
0
0
01/01: [ADVAPI32] Add parameter checks to LogonUserExW and initialize the token handle.
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5ebcc6cdc1dff92055398…
commit 5ebcc6cdc1dff92055398b10af7ab74e8ae4eb31 Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Sun Aug 5 16:16:53 2018 +0200 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Sun Aug 5 16:16:53 2018 +0200 [ADVAPI32] Add parameter checks to LogonUserExW and initialize the token handle. --- dll/win32/advapi32/misc/logon.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/dll/win32/advapi32/misc/logon.c b/dll/win32/advapi32/misc/logon.c index 88be6e5f39..f4e3f851df 100644 --- a/dll/win32/advapi32/misc/logon.c +++ b/dll/win32/advapi32/misc/logon.c @@ -469,7 +469,21 @@ LogonUserExW( NTSTATUS SubStatus = STATUS_SUCCESS; NTSTATUS Status; - *phToken = NULL; + if ((ppProfileBuffer != NULL && pdwProfileLength == NULL) || + (ppProfileBuffer == NULL && pdwProfileLength != NULL)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (ppProfileBuffer != NULL && pdwProfileLength != NULL) + { + *ppProfileBuffer = NULL; + *pdwProfileLength = 0; + } + + if (phToken != NULL) + *phToken = NULL; switch (dwLogonType) { @@ -654,9 +668,10 @@ LogonUserExW( TRACE("TokenHandle: %p\n", TokenHandle); } - *phToken = TokenHandle; + if (phToken != NULL) + *phToken = TokenHandle; - /* FIXME: return ppLogonSid, ppProfileBuffer, pdwProfileLength and pQuotaLimits */ + /* FIXME: return ppLogonSid and pQuotaLimits */ done: if (ProfileBuffer != NULL)
6 years, 4 months
1
0
0
0
02/02: [NETAPI32] Implement I_NetServerSetServiceBits()
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b4040ea74036e16e360aa…
commit b4040ea74036e16e360aaa942bddf0355fb3e887 Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Sun Aug 5 15:57:03 2018 +0200 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Sun Aug 5 15:57:03 2018 +0200 [NETAPI32] Implement I_NetServerSetServiceBits() --- dll/win32/netapi32/netapi32.spec | 2 +- dll/win32/netapi32/srvsvc.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/dll/win32/netapi32/netapi32.spec b/dll/win32/netapi32/netapi32.spec index 99131f6364..333d1405b2 100644 --- a/dll/win32/netapi32/netapi32.spec +++ b/dll/win32/netapi32/netapi32.spec @@ -93,7 +93,7 @@ @ stub I_NetServerPasswordSet2 @ stub I_NetServerPasswordSet @ stub I_NetServerReqChallenge -@ stub I_NetServerSetServiceBits +@ stdcall I_NetServerSetServiceBits(wstr wstr long long) @ stub I_NetServerSetServiceBitsEx @ stub I_NetServerTrustPasswordsGet @ stub I_NetlogonComputeClientDigest diff --git a/dll/win32/netapi32/srvsvc.c b/dll/win32/netapi32/srvsvc.c index 7103e4aa58..680082da20 100644 --- a/dll/win32/netapi32/srvsvc.c +++ b/dll/win32/netapi32/srvsvc.c @@ -424,6 +424,36 @@ NetServerSetInfo( } +NET_API_STATUS +WINAPI +I_NetServerSetServiceBits( + _In_ LPWSTR servername, + _In_ LPWSTR transport, + _In_ DWORD servicebits, + _In_ DWORD updateimmediately) +{ + NET_API_STATUS status; + + TRACE("I_NetServerSetServiceBits(%s %s 0x%lx %lu)\n", + debugstr_w(servername), debugstr_w(transport), servicebits, updateimmediately); + + RpcTryExcept + { + status = NetrServerSetServiceBits(servername, + transport, + servicebits, + updateimmediately); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return status; +} + + NET_API_STATUS WINAPI NetServerTransportAdd(
6 years, 4 months
1
0
0
0
01/02: [NETAPI32] Add annotations and move NetUseGetInfo to a better location.
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=89f6e701d4b079ec90d02…
commit 89f6e701d4b079ec90d02a6e89466fd8e7346b7e Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Sun Aug 5 15:36:48 2018 +0200 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Sun Aug 5 15:36:48 2018 +0200 [NETAPI32] Add annotations and move NetUseGetInfo to a better location. --- dll/win32/netapi32/wksta_new.c | 192 ++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/dll/win32/netapi32/wksta_new.c b/dll/win32/netapi32/wksta_new.c index 7bda9e690d..8cb6157d94 100644 --- a/dll/win32/netapi32/wksta_new.c +++ b/dll/win32/netapi32/wksta_new.c @@ -244,23 +244,23 @@ NetEnumerateComputerNames( NET_API_STATUS WINAPI NetGetJoinInformation( - LPCWSTR Server, - LPWSTR *Name, - PNETSETUP_JOIN_STATUS type) + _In_ LPCWSTR lpServer, + _Out_ LPWSTR *lpNameBuffer, + _Out_ PNETSETUP_JOIN_STATUS BufferType) { NET_API_STATUS status; - TRACE("NetGetJoinInformation(%s %p %p)\n", debugstr_w(Server), - Name, type); + TRACE("NetGetJoinInformation(%s %p %p)\n", + debugstr_w(lpServer), lpNameBuffer, BufferType); - if (Name == NULL || type == NULL) + if (lpNameBuffer == NULL || BufferType == NULL) return ERROR_INVALID_PARAMETER; RpcTryExcept { - status = NetrGetJoinInformation((LPWSTR)Server, - Name, - type); + status = NetrGetJoinInformation((LPWSTR)lpServer, + lpNameBuffer, + BufferType); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -518,10 +518,10 @@ NetUnjoinDomain( NET_API_STATUS WINAPI NetUseAdd( - LMSTR UncServerName, - DWORD Level, - LPBYTE Buf, - LPDWORD ParmError) + _In_ LMSTR UncServerName, + _In_ DWORD Level, + _In_ LPBYTE Buf, + _Out_ LPDWORD ParmError) { NET_API_STATUS status; @@ -548,9 +548,9 @@ NetUseAdd( NET_API_STATUS WINAPI NetUseDel( - LMSTR UncServerName, - LMSTR UseName, - DWORD ForceCond) + _In_ LMSTR UncServerName, + _In_ LMSTR UseName, + _In_ DWORD ForceCond) { NET_API_STATUS status; @@ -576,13 +576,13 @@ NetUseDel( NET_API_STATUS WINAPI NetUseEnum( - LMSTR UncServerName, - DWORD Level, - LPBYTE *BufPtr, - DWORD PreferedMaximumSize, - LPDWORD EntriesRead, - LPDWORD TotalEntries, - LPDWORD ResumeHandle) + _In_ LMSTR UncServerName, + _In_ DWORD Level, + _Out_ LPBYTE *BufPtr, + _In_ DWORD PreferedMaximumSize, + _Out_ LPDWORD EntriesRead, + _Out_ LPDWORD TotalEntries, + _Inout_ LPDWORD ResumeHandle) { USE_ENUM_STRUCT UseEnumInfo; USE_INFO_0_CONTAINER Container0; @@ -658,33 +658,25 @@ NetUseEnum( NET_API_STATUS WINAPI -NetValidateName( - _In_ LPCWSTR lpServer, - _In_ LPCWSTR lpName, - _In_ LPCWSTR lpAccount, - _In_ LPCWSTR lpPassword, - _In_ NETSETUP_NAME_TYPE NameType) +NetUseGetInfo( + _In_ LMSTR UncServerName, + _In_ LMSTR UseName, + _In_ DWORD Level, + _Out_ LPBYTE *BufPtr) { - PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword; - handle_t BindingHandle; NET_API_STATUS status; - TRACE("NetValidateName(%s %s %s %s %u)\n", - debugstr_w(lpServer), debugstr_w(lpName), debugstr_w(lpAccount), - debugstr_w(lpPassword), NameType); + TRACE("NetUseGetInfo(%s, %s, %d, %p)\n", debugstr_w(UncServerName), + debugstr_w(UseName), Level, BufPtr); - /* FIXME */ - BindingHandle = NULL; - EncryptedPassword = NULL; + *BufPtr = NULL; RpcTryExcept { - status = NetrValidateName2(BindingHandle, - (PWSTR)lpServer, - (PWSTR)lpName, - (PWSTR)lpAccount, - EncryptedPassword, - NameType); + status = NetrUseGetInfo(UncServerName, + UseName, + Level, + (LPUSE_INFO)BufPtr); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -698,25 +690,33 @@ NetValidateName( NET_API_STATUS WINAPI -NetUseGetInfo( - LMSTR UncServerName, - LMSTR UseName, - DWORD Level, - LPBYTE *BufPtr) +NetValidateName( + _In_ LPCWSTR lpServer, + _In_ LPCWSTR lpName, + _In_ LPCWSTR lpAccount, + _In_ LPCWSTR lpPassword, + _In_ NETSETUP_NAME_TYPE NameType) { + PJOINPR_ENCRYPTED_USER_PASSWORD EncryptedPassword; + handle_t BindingHandle; NET_API_STATUS status; - TRACE("NetUseGetInfo(%s, %s, %d, %p)\n", debugstr_w(UncServerName), - debugstr_w(UseName), Level, BufPtr); + TRACE("NetValidateName(%s %s %s %s %u)\n", + debugstr_w(lpServer), debugstr_w(lpName), debugstr_w(lpAccount), + debugstr_w(lpPassword), NameType); - *BufPtr = NULL; + /* FIXME */ + BindingHandle = NULL; + EncryptedPassword = NULL; RpcTryExcept { - status = NetrUseGetInfo(UncServerName, - UseName, - Level, - (LPUSE_INFO)BufPtr); + status = NetrValidateName2(BindingHandle, + (PWSTR)lpServer, + (PWSTR)lpName, + (PWSTR)lpAccount, + EncryptedPassword, + NameType); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { @@ -732,14 +732,14 @@ NetUseGetInfo( NET_API_STATUS WINAPI NetWkstaGetInfo( - LPWSTR servername, - DWORD level, - LPBYTE *bufptr) + _In_ LPWSTR servername, + _In_ DWORD level, + _Out_ LPBYTE *bufptr) { NET_API_STATUS status; - TRACE("NetWkstaGetInfo(%s, %d, %p)\n", debugstr_w(servername), - level, bufptr); + TRACE("NetWkstaGetInfo(%s, %d, %p)\n", + debugstr_w(servername), level, bufptr); if (bufptr == NULL) return ERROR_INVALID_PARAMETER; @@ -766,15 +766,15 @@ NetWkstaGetInfo( NET_API_STATUS WINAPI NetWkstaSetInfo( - LPWSTR servername, - DWORD level, - LPBYTE buffer, - LPDWORD parm_err) + _In_ LPWSTR servername, + _In_ DWORD level, + _In_ LPBYTE buffer, + _Out_ LPDWORD parm_err) { NET_API_STATUS status; - TRACE("NetWkstaSetInfo(%s, %d, %p, %p)\n", debugstr_w(servername), - level, buffer, parm_err); + TRACE("NetWkstaSetInfo(%s, %d, %p, %p)\n", + debugstr_w(servername), level, buffer, parm_err); RpcTryExcept { @@ -796,10 +796,10 @@ NetWkstaSetInfo( NET_API_STATUS WINAPI NetWkstaTransportAdd( - LPWSTR servername, - DWORD level, - LPBYTE buf, - LPDWORD parm_err) + _In_opt_ LPWSTR servername, + _In_ DWORD level, + _In_ LPBYTE buf, + _Out_ LPDWORD parm_err) { NET_API_STATUS status; @@ -826,9 +826,9 @@ NetWkstaTransportAdd( NET_API_STATUS WINAPI NetWkstaTransportDel( - LPWSTR servername, - LPWSTR transportname, - DWORD ucond) + _In_opt_ LPWSTR servername, + _In_ LPWSTR transportname, + _In_ DWORD ucond) { NET_API_STATUS status; @@ -855,13 +855,13 @@ NetWkstaTransportDel( NET_API_STATUS WINAPI NetWkstaTransportEnum( - LPWSTR servername, - DWORD level, - LPBYTE *bufptr, - DWORD prefmaxlen, - LPDWORD entriesread, - LPDWORD totalentries, - LPDWORD resumehandle) + _In_opt_ LPWSTR servername, + _In_ DWORD level, + _Out_ LPBYTE *bufptr, + _In_ DWORD prefmaxlen, + _Out_ LPDWORD entriesread, + _Out_ LPDWORD totalentries, + _Inout_ LPDWORD resumehandle) { WKSTA_TRANSPORT_ENUM_STRUCT TransportEnumInfo; WKSTA_TRANSPORT_INFO_0_CONTAINER Container0; @@ -914,13 +914,13 @@ NetWkstaTransportEnum( NET_API_STATUS WINAPI NetWkstaUserEnum( - LPWSTR servername, - DWORD level, - LPBYTE *bufptr, - DWORD prefmaxlen, - LPDWORD entriesread, - LPDWORD totalentries, - LPDWORD resumehandle) + _In_ LPWSTR servername, + _In_ DWORD level, + _Out_ LPBYTE *bufptr, + _In_ DWORD prefmaxlen, + _Out_ LPDWORD entriesread, + _Out_ LPDWORD totalentries, + _Inout_ LPDWORD resumehandle) { WKSTA_USER_ENUM_STRUCT UserEnumInfo; WKSTA_USER_INFO_0_CONTAINER Container0; @@ -986,13 +986,13 @@ NET_API_STATUS WINAPI NetWkstaUserGetInfo( LPWSTR reserved, - DWORD level, - PBYTE *bufptr) + _In_ DWORD level, + _Out_ PBYTE *bufptr) { NET_API_STATUS status; - TRACE("NetWkstaUserGetInfo(%s, %d, %p)\n", debugstr_w(reserved), - level, bufptr); + TRACE("NetWkstaUserGetInfo(%s, %d, %p)\n", + debugstr_w(reserved), level, bufptr); if (reserved != NULL) return ERROR_INVALID_PARAMETER; @@ -1020,14 +1020,14 @@ NET_API_STATUS WINAPI NetWkstaUserSetInfo( LPWSTR reserved, - DWORD level, - LPBYTE buf, - LPDWORD parm_err) + _In_ DWORD level, + _In_ LPBYTE buf, + _Out_ LPDWORD parm_err) { NET_API_STATUS status; - TRACE("NetWkstaSetInfo(%s, %d, %p, %p)\n", debugstr_w(reserved), - level, buf, parm_err); + TRACE("NetWkstaSetInfo(%s, %d, %p, %p)\n", + debugstr_w(reserved), level, buf, parm_err); if (reserved != NULL) return ERROR_INVALID_PARAMETER;
6 years, 4 months
1
0
0
0
01/01: [SRVSVC] Set and retrieve service bits and rename unknown functions
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0a5ccac599028abc3f4da…
commit 0a5ccac599028abc3f4da2c9e41521118a8c7c6b Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Sun Aug 5 15:04:01 2018 +0200 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Sun Aug 5 15:05:19 2018 +0200 [SRVSVC] Set and retrieve service bits and rename unknown functions - Service bits are set by NetrServerSetServiceBits and can be retrieved by NetrServerGetInfo. - The real name of function 42 is NetrServerSetServiceBitsEx and the real name of function 47 is NetrDfsSetServerInfo. --- base/services/srvsvc/precomp.h | 4 ++++ base/services/srvsvc/rpcserver.c | 35 +++++++++++++++++++++++++---------- base/services/srvsvc/srvsvc.c | 3 +++ sdk/include/reactos/idl/srvsvc.idl | 18 ++++++++++++------ 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/base/services/srvsvc/precomp.h b/base/services/srvsvc/precomp.h index a0fbcbc4bd..6da24c6e0f 100644 --- a/base/services/srvsvc/precomp.h +++ b/base/services/srvsvc/precomp.h @@ -15,6 +15,10 @@ #include <wine/debug.h> + +extern DWORD dwServiceBits; + + DWORD WINAPI RpcThreadRoutine( diff --git a/base/services/srvsvc/rpcserver.c b/base/services/srvsvc/rpcserver.c index d1d9f3dc3d..214bf0bfd6 100644 --- a/base/services/srvsvc/rpcserver.c +++ b/base/services/srvsvc/rpcserver.c @@ -394,7 +394,7 @@ NetrServerGetInfo( pServerInfo->ServerInfo101.sv101_version_major = VersionInfo.dwMajorVersion; pServerInfo->ServerInfo101.sv101_version_minor = VersionInfo.dwMinorVersion; - pServerInfo->ServerInfo101.sv101_type = SV_TYPE_NT; /* FIXME */ + pServerInfo->ServerInfo101.sv101_type = dwServiceBits | SV_TYPE_NT; pServerInfo->ServerInfo101.sv101_comment = NULL; /* FIXME */ *InfoStruct = pServerInfo; @@ -413,7 +413,7 @@ NetrServerGetInfo( pServerInfo->ServerInfo102.sv102_version_major = VersionInfo.dwMajorVersion; pServerInfo->ServerInfo102.sv102_version_minor = VersionInfo.dwMinorVersion; - pServerInfo->ServerInfo102.sv102_type = SV_TYPE_NT; + pServerInfo->ServerInfo102.sv102_type = dwServiceBits | SV_TYPE_NT; pServerInfo->ServerInfo102.sv102_comment = NULL; /* FIXME */ pServerInfo->ServerInfo102.sv102_users = 0; /* FIXME */ @@ -619,8 +619,15 @@ NetrServerSetServiceBits( DWORD ServiceBits, DWORD UpdateImmediately) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + FIXME("NetrServerSetServiceBits(%p %s %lx %lu)\n", + ServerName, debugstr_w(Transport), ServiceBits, UpdateImmediately); + + /* FIXME: Support Transport */ + /* FIXME: Support UpdateImmdiately */ + + dwServiceBits = ServiceBits; + + return NERR_Success; } @@ -798,12 +805,19 @@ NetrServerTransportAddEx( } -/* Function 42 */ -void +/* Function 42 - Not used on wire */ +NET_API_STATUS __stdcall -Opnum42NotUsedOnWire(void) +NetrServerSetServiceBitsEx( + SRVSVC_HANDLE ServerName, + WCHAR *EmulatedServer, + WCHAR *Transport, + DWORD ServiceBitsOfInterest, + DWORD ServiceBits, + DWORD UpdateImmediately) { UNIMPLEMENTED; + return ERROR_CALL_NOT_IMPLEMENTED; } @@ -863,12 +877,13 @@ NetrDfsSetLocalVolumeState( } -/* Function 47 */ -void +/* Function 47 - Not used on wire */ +NET_API_STATUS __stdcall -Opnum47NotUsedOnWire(void) +NetrDfsSetServerInfo(void) { UNIMPLEMENTED; + return ERROR_CALL_NOT_IMPLEMENTED; } diff --git a/base/services/srvsvc/srvsvc.c b/base/services/srvsvc/srvsvc.c index 5182987d50..1c3710547b 100644 --- a/base/services/srvsvc/srvsvc.c +++ b/base/services/srvsvc/srvsvc.c @@ -37,6 +37,9 @@ static WCHAR ServiceName[] = L"Lanmanserver"; static SERVICE_STATUS_HANDLE ServiceStatusHandle; static SERVICE_STATUS ServiceStatus; +DWORD dwServiceBits = 0; + + /* FUNCTIONS *****************************************************************/ static VOID diff --git a/sdk/include/reactos/idl/srvsvc.idl b/sdk/include/reactos/idl/srvsvc.idl index eea19b18ea..4a80140f44 100644 --- a/sdk/include/reactos/idl/srvsvc.idl +++ b/sdk/include/reactos/idl/srvsvc.idl @@ -1388,10 +1388,16 @@ interface srvsvc [in] DWORD Level, [in, switch_is(Level)] LPTRANSPORT_INFO Buffer); - // This method not used on the wire - void + /* Function 42 - Not used on wire */ + NET_API_STATUS __stdcall - Opnum42NotUsedOnWire(void); + NetrServerSetServiceBitsEx( + [in, string, unique] SRVSVC_HANDLE ServerName, + [in, string, unique] WCHAR *EmulatedServer, + [in, string, unique] WCHAR *Transport, + [in] DWORD ServiceBitsOfInterest, + [in] DWORD ServiceBits, + [in] DWORD UpdateImmediately); NET_API_STATUS __stdcall @@ -1425,10 +1431,10 @@ interface srvsvc [in, string] WCHAR *Prefix, [in] unsigned long State); - // This method not used on the wire - void + /* Function 47 - Not used on wire */ + NET_API_STATUS __stdcall - Opnum47NotUsedOnWire(void); + NetrDfsSetServerInfo(void); NET_API_STATUS __stdcall
6 years, 4 months
1
0
0
0
01/01: [SHELL32] Fix handling of multiple parameters in the 'Run' dialog (#665)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bfcbda227f99c1b59e8ed…
commit bfcbda227f99c1b59e8ed71f5e0f59f793d496a1 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sun Aug 5 20:39:17 2018 +0900 Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Aug 5 13:39:17 2018 +0200 [SHELL32] Fix handling of multiple parameters in the 'Run' dialog (#665) The "Run" dialog failed when multiple parameters wee specified. We use instead a newly-created ShellExecCmdLine() helper function to fix the problem (as found via API-tracing on Windows). Note that ShellExecCmdLine() starts to be exported with Vista+. - Implement ShellExecCmdLine() function in shell32. - Add URL support. - Fix RunDlgProc function in shell32. - Add a testcase for ShellExecCmdLine() function. CORE-14790 --- dll/win32/shell32/dialogs/dialogs.cpp | 25 +- dll/win32/shell32/shlexec.cpp | 180 +++++++ modules/rostests/apitests/shell32/CMakeLists.txt | 1 + .../rostests/apitests/shell32/ShellExecCmdLine.cpp | 582 +++++++++++++++++++++ modules/rostests/apitests/shell32/testlist.c | 2 + sdk/include/reactos/undocshell.h | 15 + 6 files changed, 790 insertions(+), 15 deletions(-) diff --git a/dll/win32/shell32/dialogs/dialogs.cpp b/dll/win32/shell32/dialogs/dialogs.cpp index 168b066e28..77c1bdf5cc 100644 --- a/dll/win32/shell32/dialogs/dialogs.cpp +++ b/dll/win32/shell32/dialogs/dialogs.cpp @@ -527,7 +527,6 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA HWND htxt = GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH); INT ic; WCHAR *psz, *parent = NULL; - SHELLEXECUTEINFOW sei; NMRUNFILEDLGW nmrfd; ic = GetWindowTextLengthW(htxt); @@ -537,9 +536,6 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA return TRUE; } - ZeroMemory(&sei, sizeof(sei)); - sei.cbSize = sizeof(sei); - /* * Allocate a new MRU entry, we need to add two characters * for the terminating "\\1" part, then the NULL character. @@ -552,10 +548,7 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA } GetWindowTextW(htxt, psz, ic + 1); - - sei.hwnd = hwnd; - sei.nShow = SW_SHOWNORMAL; - sei.lpFile = psz; + StrTrimW(psz, L" \t"); /* * The precedence is the following: first the user-given @@ -563,12 +556,13 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA * directory is computed if the RFF_CALCDIRECTORY is set, * otherwise no current directory is defined. */ + LPCWSTR pszStartDir; if (prfdp->lpstrDirectory) - sei.lpDirectory = prfdp->lpstrDirectory; + pszStartDir = prfdp->lpstrDirectory; else if (prfdp->uFlags & RFF_CALCDIRECTORY) - sei.lpDirectory = parent = RunDlg_GetParentDir(sei.lpFile); + pszStartDir = parent = RunDlg_GetParentDir(psz); else - sei.lpDirectory = NULL; + pszStartDir = NULL; /* Hide the dialog for now on, we will show it up in case of retry */ ShowWindow(hwnd, SW_HIDE); @@ -585,9 +579,9 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA nmrfd.hdr.code = RFN_VALIDATE; nmrfd.hdr.hwndFrom = hwnd; nmrfd.hdr.idFrom = 0; - nmrfd.lpFile = sei.lpFile; - nmrfd.lpDirectory = sei.lpDirectory; - nmrfd.nShow = sei.nShow; + nmrfd.lpFile = psz; + nmrfd.lpDirectory = pszStartDir; + nmrfd.nShow = SW_SHOWNORMAL; lRet = SendMessageW(prfdp->hwndOwner, WM_NOTIFY, 0, (LPARAM)&nmrfd.hdr); @@ -598,7 +592,8 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA break; case RF_OK: - if (ShellExecuteExW(&sei)) + if (SUCCEEDED(ShellExecCmdLine(hwnd, psz, pszStartDir, SW_SHOWNORMAL, NULL, + SECL_ALLOW_NONEXE))) { /* Call again GetWindowText in case the contents of the edit box has changed? */ GetWindowTextW(htxt, psz, ic + 1); diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 478a3c20b4..55b3d051fe 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -21,11 +21,13 @@ */ #include "precomp.h" +#include <undocshell.h> WINE_DEFAULT_DEBUG_CHANNEL(exec); static const WCHAR wszOpen[] = L"open"; static const WCHAR wszExe[] = L".exe"; +static const WCHAR wszCom[] = L".com"; #define SEE_MASK_CLASSALL (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY) @@ -2322,3 +2324,181 @@ OpenAs_RunDLLA(HWND hwnd, HINSTANCE hinst, LPCSTR cmdline, int cmdshow) OpenAs_RunDLLW(hwnd, hinst, pszCmdLineW, cmdshow); SHFree(pszCmdLineW); } + +/*************************************************************************/ + +static LPCWSTR +SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0) +{ + LPCWSTR pch; + size_t ich = 0; + if (*psz == L'"') + { + // 1st argument is quoted. the string in quotes is quoted 1st argument. + // [pch] --> [pszArg0+ich] + for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch) + { + if (*pch == L'"' && pch[1] == L'"') + { + // doubled double quotations found! + pszArg0[ich] = L'"'; + } + else if (*pch == L'"') + { + // single double quotation found! + ++pch; + break; + } + else + { + // otherwise + pszArg0[ich] = *pch; + } + } + } + else + { + // 1st argument is unquoted. non-space sequence is 1st argument. + // [pch] --> [pszArg0+ich] + for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch) + { + pszArg0[ich] = *pch; + } + } + pszArg0[ich] = 0; + + // skip space + while (iswspace(*pch)) + ++pch; + + return pch; +} + +HRESULT WINAPI ShellExecCmdLine( + HWND hwnd, + LPCWSTR pwszCommand, + LPCWSTR pwszStartDir, + int nShow, + LPVOID pUnused, + DWORD dwSeclFlags) +{ + SHELLEXECUTEINFOW info; + DWORD dwSize, dwError, dwType, dwFlags = SEE_MASK_DOENVSUBST | SEE_MASK_NOASYNC; + LPCWSTR pszVerb = NULL; + WCHAR szFile[MAX_PATH], szFile2[MAX_PATH]; + HRESULT hr; + LPCWSTR pchParams; + LPWSTR lpCommand = NULL; + + if (pwszCommand == NULL) + RaiseException(EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, + 1, (ULONG_PTR*)pwszCommand); + + __SHCloneStrW(&lpCommand, pwszCommand); + StrTrimW(lpCommand, L" \t"); + + if (dwSeclFlags & SECL_NO_UI) + dwFlags |= SEE_MASK_FLAG_NO_UI; + if (dwSeclFlags & SECL_LOG_USAGE) + dwFlags |= SEE_MASK_FLAG_LOG_USAGE; + if (dwSeclFlags & SECL_USE_IDLIST) + dwFlags |= SEE_MASK_INVOKEIDLIST; + + if (dwSeclFlags & SECL_RUNAS) + { + dwSize = 0; + hr = AssocQueryStringW(0, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize); + if (SUCCEEDED(hr) && dwSize != 0) + { + pszVerb = L"runas"; + } + } + + if (UrlIsFileUrlW(lpCommand)) + { + StringCchCopyW(szFile, _countof(szFile), lpCommand); + pchParams = NULL; + } + else + { + pchParams = SplitParams(lpCommand, szFile, _countof(szFile)); + if (SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, szFile, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, szFile, wszCom, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, szFile, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, szFile, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, szFile, wszCom, _countof(szFile2), szFile2, NULL)) + { + StringCchCopyW(szFile, _countof(szFile), szFile2); + pchParams = NULL; + } + else if (SearchPathW(NULL, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, lpCommand, wszCom, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, lpCommand, wszCom, _countof(szFile2), szFile2, NULL)) + { + StringCchCopyW(szFile, _countof(szFile), szFile2); + pchParams = NULL; + } + + if (!(dwSeclFlags & SECL_ALLOW_NONEXE)) + { + if (!GetBinaryTypeW(szFile, &dwType)) + { + SHFree(lpCommand); + + if (!(dwSeclFlags & SECL_NO_UI)) + { + WCHAR szText[128 + MAX_PATH], szFormat[128]; + LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); + StringCchPrintfW(szText, _countof(szText), szFormat, szFile); + MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); + } + return CO_E_APPNOTFOUND; + } + } + else + { + if (GetFileAttributesW(szFile) == INVALID_FILE_ATTRIBUTES) + { + SHFree(lpCommand); + + if (!(dwSeclFlags & SECL_NO_UI)) + { + WCHAR szText[128 + MAX_PATH], szFormat[128]; + LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); + StringCchPrintfW(szText, _countof(szText), szFormat, szFile); + MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); + } + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + } + } + } + + ZeroMemory(&info, sizeof(info)); + info.cbSize = sizeof(info); + info.fMask = dwFlags; + info.hwnd = hwnd; + info.lpVerb = pszVerb; + info.lpFile = szFile; + info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL; + info.lpDirectory = pwszStartDir; + info.nShow = nShow; + if (ShellExecuteExW(&info)) + { + if (info.lpIDList) + CoTaskMemFree(info.lpIDList); + + SHFree(lpCommand); + + return S_OK; + } + + dwError = GetLastError(); + + SHFree(lpCommand); + + return HRESULT_FROM_WIN32(dwError); +} diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt b/modules/rostests/apitests/shell32/CMakeLists.txt index 545d2cc26e..8201a6f12e 100644 --- a/modules/rostests/apitests/shell32/CMakeLists.txt +++ b/modules/rostests/apitests/shell32/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND SOURCE PathResolve.cpp SHCreateFileExtractIconW.cpp SHParseDisplayName.cpp + ShellExecCmdLine.cpp ShellExecuteEx.cpp ShellState.cpp menu.cpp diff --git a/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp b/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp new file mode 100644 index 0000000000..c540321a65 --- /dev/null +++ b/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp @@ -0,0 +1,582 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for ShellExecCmdLine + * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> + */ +#include "shelltest.h" +#include <shlwapi.h> +#include <strsafe.h> + +#define NDEBUG +#include <debug.h> +#include <stdio.h> + +//#define ShellExecCmdLine ShellExecCmdLine + +#ifndef SECL_NO_UI + #define SECL_NO_UI 0x2 + #define SECL_LOG_USAGE 0x8 + #define SECL_USE_IDLIST 0x10 + #define SECL_ALLOW_NONEXE 0x20 + #define SECL_RUNAS 0x40 +#endif + +#ifdef ShellExecCmdLine + +#define shell32_hInstance GetModuleHandle(NULL) +#define IDS_FILE_NOT_FOUND (-1) + +static const WCHAR wszOpen[] = L"open"; +static const WCHAR wszExe[] = L".exe"; +static const WCHAR wszCom[] = L".com"; + +static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source) +{ + *target = (WCHAR *)SHAlloc((lstrlenW(source) + 1) * sizeof(WCHAR) ); + lstrcpyW(*target, source); +} + +static LPCWSTR +SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0) +{ + LPCWSTR pch; + size_t ich = 0; + if (*psz == L'"') + { + // 1st argument is quoted. the string in quotes is quoted 1st argument. + // [pch] --> [pszArg0+ich] + for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch) + { + if (*pch == L'"' && pch[1] == L'"') + { + // doubled double quotations found! + pszArg0[ich] = L'"'; + } + else if (*pch == L'"') + { + // single double quotation found! + ++pch; + break; + } + else + { + // otherwise + pszArg0[ich] = *pch; + } + } + } + else + { + // 1st argument is unquoted. non-space sequence is 1st argument. + // [pch] --> [pszArg0+ich] + for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch) + { + pszArg0[ich] = *pch; + } + } + pszArg0[ich] = 0; + + // skip space + while (iswspace(*pch)) + ++pch; + + return pch; +} + +HRESULT WINAPI ShellExecCmdLine( + HWND hwnd, + LPCWSTR pwszCommand, + LPCWSTR pwszStartDir, + int nShow, + LPVOID pUnused, + DWORD dwSeclFlags) +{ + SHELLEXECUTEINFOW info; + DWORD dwSize, dwError, dwType, dwFlags = SEE_MASK_DOENVSUBST | SEE_MASK_NOASYNC; + LPCWSTR pszVerb = NULL; + WCHAR szFile[MAX_PATH], szFile2[MAX_PATH]; + HRESULT hr; + LPCWSTR pchParams; + LPWSTR lpCommand = NULL; + + if (pwszCommand == NULL) + RaiseException(EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, + 1, (ULONG_PTR*)pwszCommand); + + __SHCloneStrW(&lpCommand, pwszCommand); + StrTrimW(lpCommand, L" \t"); + + if (dwSeclFlags & SECL_NO_UI) + dwFlags |= SEE_MASK_FLAG_NO_UI; + if (dwSeclFlags & SECL_LOG_USAGE) + dwFlags |= SEE_MASK_FLAG_LOG_USAGE; + if (dwSeclFlags & SECL_USE_IDLIST) + dwFlags |= SEE_MASK_INVOKEIDLIST; + + if (dwSeclFlags & SECL_RUNAS) + { + dwSize = 0; + hr = AssocQueryStringW(0, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize); + if (SUCCEEDED(hr) && dwSize != 0) + { + pszVerb = L"runas"; + } + } + + if (UrlIsFileUrlW(lpCommand)) + { + StringCchCopyW(szFile, _countof(szFile), lpCommand); + pchParams = NULL; + } + else + { + pchParams = SplitParams(lpCommand, szFile, _countof(szFile)); + if (SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, szFile, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, szFile, wszCom, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, szFile, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, szFile, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, szFile, wszCom, _countof(szFile2), szFile2, NULL)) + { + StringCchCopyW(szFile, _countof(szFile), szFile2); + pchParams = NULL; + } + else if (SearchPathW(NULL, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(NULL, lpCommand, wszCom, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || + SearchPathW(pwszStartDir, lpCommand, wszCom, _countof(szFile2), szFile2, NULL)) + { + StringCchCopyW(szFile, _countof(szFile), szFile2); + pchParams = NULL; + } + + if (!(dwSeclFlags & SECL_ALLOW_NONEXE)) + { + if (!GetBinaryTypeW(szFile, &dwType)) + { + SHFree(lpCommand); + + if (!(dwSeclFlags & SECL_NO_UI)) + { + WCHAR szText[128 + MAX_PATH], szFormat[128]; + LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); + StringCchPrintfW(szText, _countof(szText), szFormat, szFile); + MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); + } + return CO_E_APPNOTFOUND; + } + } + else + { + if (GetFileAttributesW(szFile) == INVALID_FILE_ATTRIBUTES) + { + SHFree(lpCommand); + + if (!(dwSeclFlags & SECL_NO_UI)) + { + WCHAR szText[128 + MAX_PATH], szFormat[128]; + LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); + StringCchPrintfW(szText, _countof(szText), szFormat, szFile); + MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); + } + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + } + } + } + + ZeroMemory(&info, sizeof(info)); + info.cbSize = sizeof(info); + info.fMask = dwFlags; + info.hwnd = hwnd; + info.lpVerb = pszVerb; + info.lpFile = szFile; + info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL; + info.lpDirectory = pwszStartDir; + info.nShow = nShow; + if (ShellExecuteExW(&info)) + { + if (info.lpIDList) + CoTaskMemFree(info.lpIDList); + + SHFree(lpCommand); + + return S_OK; + } + + dwError = GetLastError(); + + SHFree(lpCommand); + + return HRESULT_FROM_WIN32(dwError); +} +#else + typedef HRESULT (WINAPI *SHELLEXECCMDLINE)(HWND, LPCWSTR, LPCWSTR, INT, LPVOID, DWORD); + SHELLEXECCMDLINE g_pShellExecCmdLine = NULL; +#endif + +typedef struct TEST_ENTRY +{ + INT lineno; + HRESULT hr; + BOOL bAllowNonExe; + LPCWSTR pwszWindowClass; + LPCWSTR pwszCommand; + LPCWSTR pwszStartDir; +} TEST_ENTRY; + +static const char s_testfile1[] = "Test File.txt"; +static const char s_testfile2[] = "Test File.bat"; +static char s_notepad[] = "notepad.exe"; + +static const TEST_ENTRY s_entries[] = +{ + // NULL + { __LINE__, (HRESULT)0xDEADFACE, FALSE, NULL, NULL, NULL }, + { __LINE__, (HRESULT)0xDEADFACE, FALSE, NULL, NULL, L"." }, + { __LINE__, (HRESULT)0xDEADFACE, FALSE, NULL, NULL, L"system32" }, + { __LINE__, (HRESULT)0xDEADFACE, FALSE, NULL, NULL, L"C:\\Program Files" }, + { __LINE__, (HRESULT)0xDEADFACE, TRUE, NULL, NULL, NULL }, + { __LINE__, (HRESULT)0xDEADFACE, TRUE, NULL, NULL, L"." }, + { __LINE__, (HRESULT)0xDEADFACE, TRUE, NULL, NULL, L"system32" }, + { __LINE__, (HRESULT)0xDEADFACE, TRUE, NULL, NULL, L"C:\\Program Files" }, + // notepad + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad", L"." }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad", L"system32" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad", L"C:\\Program Files" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad \"Test File.txt\"", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad \"Test File.txt\"", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad", L"system32" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad", L"C:\\Program Files" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad \"Test File.txt\"", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad \"Test File.txt\"", L"." }, + // notepad.exe + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad.exe", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad.exe", L"." }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad.exe", L"system32" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad.exe", L"C:\\Program Files" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad.exe \"Test File.txt\"", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"notepad.exe \"Test File.txt\"", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad.exe", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad.exe", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad.exe", L"system32" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad.exe", L"C:\\Program Files" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad.exe \"Test File.txt\"", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"notepad.exe \"Test File.txt\"", L"." }, + // C:\notepad.exe + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"C:\\notepad.exe", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"C:\\notepad.exe", L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"C:\\notepad.exe", L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"C:\\notepad.exe", L"C:\\Program Files" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"C:\\notepad.exe \"Test File.txt\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"C:\\notepad.exe \"Test File.txt\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"C:\\notepad.exe", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"C:\\notepad.exe", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"C:\\notepad.exe", L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"C:\\notepad.exe", L"C:\\Program Files" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"C:\\notepad.exe \"Test File.txt\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"C:\\notepad.exe \"Test File.txt\"", L"." }, + // "notepad" + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad\"", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad\"", L"." }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad\"", L"system32" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad\"", L"C:\\Program Files" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad\" \"Test File.txt\"", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad\" \"Test File.txt\"", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad\"", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad\"", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad\"", L"system32" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad\"", L"C:\\Program Files" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad\" \"Test File.txt\"", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad\" \"Test File.txt\"", L"." }, + // "notepad.exe" + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad.exe\"", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad.exe\"", L"." }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad.exe\"", L"system32" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad.exe\"", L"C:\\Program Files" }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad.exe\" \"Test File.txt\"", NULL }, + { __LINE__, S_OK, FALSE, L"Notepad", L"\"notepad.exe\" \"Test File.txt\"", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad.exe\"", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad.exe\"", L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad.exe\"", L"system32" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad.exe\"", L"C:\\Program Files" }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad.exe\" \"Test File.txt\"", NULL }, + { __LINE__, S_OK, TRUE, L"Notepad", L"\"notepad.exe\" \"Test File.txt\"", L"." }, + // test program.exe + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"test program.exe", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"test program.exe", L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"test program.exe", L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"test program.exe", L"C:\\Program Files" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"test program.exe \"Test File.txt\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"test program.exe \"Test File.txt\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"test program.exe", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"test program.exe", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"test program.exe", L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"test program.exe", L"C:\\Program Files" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"test program.exe \"Test File.txt\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"test program.exe \"Test File.txt\"", L"." }, + // "test program" + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program\"", L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program\"", L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program\"", L"C:\\Program Files" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program\" \"Test File.txt\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program\" \"Test File.txt\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program\"", L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program\"", L"C:\\Program Files" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program\" \"Test File.txt\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program\" \"Test File.txt\"", L"." }, + // "test program.exe" + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program.exe\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program.exe\"", L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program.exe\"", L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program.exe\"", L"C:\\Program Files" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program.exe\" \"Test File.txt\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"test program.exe\" \"Test File.txt\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program.exe\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program.exe\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program.exe\"", L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program.exe\"", L"C:\\Program Files" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program.exe\" \"Test File.txt\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"test program.exe\" \"Test File.txt\"", L"." }, + // invalid program + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"invalid program", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"invalid program", L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"invalid program", L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"invalid program", L"C:\\Program Files" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"invalid program \"Test File.txt\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"invalid program \"Test File.txt\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"invalid program", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"invalid program", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"invalid program", L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"invalid program", L"C:\\Program Files" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"invalid program \"Test File.txt\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"invalid program \"Test File.txt\"", L"." }, + // \"invalid program.exe\" + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"invalid program.exe\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"invalid program.exe\"", L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"invalid program.exe\"", L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"invalid program.exe\"", L"C:\\Program Files" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"invalid program.exe\" \"Test File.txt\"", NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", L"\"invalid program.exe\" \"Test File.txt\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"invalid program.exe\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"invalid program.exe\"", L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"invalid program.exe\"", L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"invalid program.exe\"", L"C:\\Program Files" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"invalid program.exe\" \"Test File.txt\"", NULL }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", L"\"invalid program.exe\" \"Test File.txt\"", L"." }, +}; + +static void DoEntry(const TEST_ENTRY *pEntry) +{ + HRESULT hr; + DWORD dwSeclFlags; + + if (pEntry->bAllowNonExe) + dwSeclFlags = SECL_NO_UI | SECL_ALLOW_NONEXE; + else + dwSeclFlags = SECL_NO_UI; + + _SEH2_TRY + { +#ifdef ShellExecCmdLine + hr = ShellExecCmdLine(NULL, pEntry->pwszCommand, pEntry->pwszStartDir, + SW_SHOWNORMAL, NULL, dwSeclFlags); +#else + hr = (*g_pShellExecCmdLine)(NULL, pEntry->pwszCommand, pEntry->pwszStartDir, + SW_SHOWNORMAL, NULL, dwSeclFlags); +#endif + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + hr = 0xDEADFACE; + } + _SEH2_END; + + ok(hr == pEntry->hr, "Line %d: hr expected 0x%lX, was 0x%lX\n", pEntry->lineno, pEntry->hr, hr); + +#define RETRY_COUNT 5 +#define RETRY_INTERVAL 250 + if (SUCCEEDED(hr) && pEntry->pwszWindowClass) + { + BOOL bFound = FALSE; + Sleep(RETRY_INTERVAL / 2); + for (int i = 0; i < RETRY_COUNT; ++i) + { + HWND hwnd = FindWindowW(pEntry->pwszWindowClass, NULL); + if (hwnd) + { + bFound = TRUE; + SendMessage(hwnd, WM_CLOSE, 0, 0); + break; + } + Sleep(RETRY_INTERVAL); + } + ok(bFound, "Line %d: The window not found\n", pEntry->lineno); + } +#undef RETRY_COUNT +#undef RETRY_INTERVAL +} + +START_TEST(ShellExecCmdLine) +{ + using namespace std; + +#ifndef ShellExecCmdLine + HMODULE hShell32 = GetModuleHandleA("shell32"); + g_pShellExecCmdLine = (SHELLEXECCMDLINE)GetProcAddress(hShell32, (LPCSTR)(INT_PTR)265); + if (!g_pShellExecCmdLine) + { + skip("ShellExecCmdLine is not found\n"); + return; + } +#endif + + // s_testfile1 + FILE *fp = fopen(s_testfile1, "wb"); + ok(fp != NULL, "failed to create a test file\n"); + fclose(fp); + + // s_testfile2 + fp = fopen(s_testfile2, "wb"); + ok(fp != NULL, "failed to create a test file\n"); + if (fp) + { + fprintf(fp, "echo OK\n"); + } + fclose(fp); + + for (size_t i = 0; i < _countof(s_entries); ++i) + { + DoEntry(&s_entries[i]); + } + + WCHAR buf0[MAX_PATH]; + WCHAR buf1[MAX_PATH]; + WCHAR buf2[MAX_PATH]; + TEST_ENTRY additionals[] = + { + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf0, NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf0, L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf0, L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf1, NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf1, L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf1, L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf2, NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf2, L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, L"Notepad", buf2, L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf0, NULL }, // FIXME + { __LINE__, S_OK, TRUE, L"Notepad", buf0, L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf0, L"system32" }, // FIXME + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf1, NULL }, // FIXME + { __LINE__, S_OK, TRUE, L"Notepad", buf1, L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", buf1, L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, L"Notepad", buf2, NULL }, // FIXME + { __LINE__, S_OK, TRUE, L"Notepad", buf2, L"." }, + { __LINE__, S_OK, TRUE, L"Notepad", buf2, L"system32" }, + }; + + wsprintfW(buf0, L"%hs", s_testfile1); + wsprintfW(buf1, L"\"%hs\"", s_testfile1); + wsprintfW(buf2, L"\"%hs\" \"Test File.txt\"", s_testfile1); + for (size_t i = 0; i < _countof(additionals); ++i) + { + DoEntry(&additionals[i]); + } + + TEST_ENTRY additionals2[] = + { + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf0, NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf0, L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf0, L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf1, NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf1, L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf1, L"system32" }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf2, NULL }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf2, L"." }, + { __LINE__, CO_E_APPNOTFOUND, FALSE, NULL, buf2, L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf0, NULL }, // FIXME + { __LINE__, S_OK, TRUE, NULL, buf0, L"." }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf0, L"system32" }, // FIXME + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf1, NULL }, // FIXME + { __LINE__, S_OK, TRUE, NULL, buf1, L"." }, + { __LINE__, S_OK, TRUE, NULL, buf1, L"system32" }, + { __LINE__, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), TRUE, NULL, buf2, NULL }, // FIXME + { __LINE__, S_OK, TRUE, NULL, buf2, L"." }, + { __LINE__, S_OK, TRUE, NULL, buf2, L"system32" }, + }; + + wsprintfW(buf0, L"%hs", s_testfile2); + wsprintfW(buf1, L"\"%hs\"", s_testfile2); + wsprintfW(buf2, L"\"%hs\" \"Test File.txt\"", s_testfile2); + for (size_t i = 0; i < _countof(additionals2); ++i) + { + DoEntry(&additionals2[i]); + } + + char path[MAX_PATH]; + ok((INT_PTR)FindExecutableA("notepad.exe", NULL, s_notepad) >= 32, "FindExecutableA failed\n"); + ok(GetModuleFileNameA(NULL, path, _countof(path)), "GetModuleFileNameA failed\n"); + char *pch = strrchr(path, '\\'); + + if (pch == NULL) + { + skip("pch == NULL\n"); + } + else + { + // create "My Directory" + strcpy(pch, "\\My Directory"); + if (GetFileAttributesA(path) == INVALID_FILE_ATTRIBUTES) + ok(CreateDirectoryA(path, NULL), "CreateDirectoryA failed\n"); + + // create "My Directory\\Notepad.exe" as clone of Notepad.exe + strcpy(pch, "\\My Directory\\Notepad.exe"); + ok(CopyFileA(s_notepad, path, FALSE), "CopyFileA failed\n"); + + wsprintfW(buf0, L"%hs", path); + wsprintfW(buf1, L"\"%hs\"", path); + wsprintfW(buf2, L"\"%hs\" \"Test File.txt\"", path); + TEST_ENTRY additionals3[] = + { + { __LINE__, S_OK, FALSE, NULL, buf0, NULL }, + { __LINE__, S_OK, FALSE, NULL, buf0, L"." }, + { __LINE__, S_OK, FALSE, NULL, buf0, L"system32" }, + { __LINE__, S_OK, FALSE, NULL, buf1, NULL }, + { __LINE__, S_OK, FALSE, NULL, buf1, L"." }, + { __LINE__, S_OK, FALSE, NULL, buf1, L"system32" }, + { __LINE__, S_OK, FALSE, NULL, buf2, NULL }, + { __LINE__, S_OK, FALSE, NULL, buf2, L"." }, + { __LINE__, S_OK, FALSE, NULL, buf2, L"system32" }, + { __LINE__, S_OK, TRUE, NULL, buf0, NULL }, + { __LINE__, S_OK, TRUE, NULL, buf0, L"." }, + { __LINE__, S_OK, TRUE, NULL, buf0, L"system32" }, + { __LINE__, S_OK, TRUE, NULL, buf1, NULL }, + { __LINE__, S_OK, TRUE, NULL, buf1, L"." }, + { __LINE__, S_OK, TRUE, NULL, buf1, L"system32" }, + { __LINE__, S_OK, TRUE, NULL, buf2, NULL }, + { __LINE__, S_OK, TRUE, NULL, buf2, L"." }, + { __LINE__, S_OK, TRUE, NULL, buf2, L"system32" }, + }; + for (size_t i = 0; i < _countof(additionals3); ++i) + { + DoEntry(&additionals3[i]); + } + + DeleteFileA(path); + + strcpy(pch, "\\My Directory"); + RemoveDirectory(path); + } + + // clean up + ok(DeleteFileA(s_testfile1), "failed to delete the test file\n"); + ok(DeleteFileA(s_testfile2), "failed to delete the test file\n"); +} diff --git a/modules/rostests/apitests/shell32/testlist.c b/modules/rostests/apitests/shell32/testlist.c index b2e1b78876..1b5339ea5e 100644 --- a/modules/rostests/apitests/shell32/testlist.c +++ b/modules/rostests/apitests/shell32/testlist.c @@ -15,6 +15,7 @@ extern void func_menu(void); extern void func_OpenAs_RunDLL(void); extern void func_PathResolve(void); extern void func_SHCreateFileExtractIconW(void); +extern void func_ShellExecCmdLine(void); extern void func_ShellExecuteEx(void); extern void func_ShellState(void); extern void func_SHParseDisplayName(void); @@ -33,6 +34,7 @@ const struct test winetest_testlist[] = { "OpenAs_RunDLL", func_OpenAs_RunDLL }, { "PathResolve", func_PathResolve }, { "SHCreateFileExtractIconW", func_SHCreateFileExtractIconW }, + { "ShellExecCmdLine", func_ShellExecCmdLine }, { "ShellExecuteEx", func_ShellExecuteEx }, { "ShellState", func_ShellState }, { "SHParseDisplayName", func_SHParseDisplayName }, diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index 24d6e82f55..c2a0b37c6b 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -546,6 +546,21 @@ WORD WINAPI ArrangeWindows( WORD cKids, CONST HWND * lpKids); +/* Flags for ShellExecCmdLine */ +#define SECL_NO_UI 0x2 +#define SECL_LOG_USAGE 0x8 +#define SECL_USE_IDLIST 0x10 +#define SECL_ALLOW_NONEXE 0x20 +#define SECL_RUNAS 0x40 + +HRESULT WINAPI ShellExecCmdLine( + HWND hwnd, + LPCWSTR pwszCommand, + LPCWSTR pwszStartDir, + int nShow, + LPVOID pUnused, + DWORD dwSeclFlags); + /* RegisterShellHook types */ #define RSH_DEREGISTER 0 #define RSH_REGISTER 1
6 years, 4 months
1
0
0
0
01/01: [MSCONFIG] Fix buffer overflow when handling long service command lines.
by Thomas Faber
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ff63ef3c55b8279600845…
commit ff63ef3c55b82796008453d049bc50df80b4c4a6 Author: Thomas Faber <thomas.faber(a)reactos.org> AuthorDate: Sun Aug 5 12:57:25 2018 +0200 Commit: Thomas Faber <thomas.faber(a)reactos.org> CommitDate: Sun Aug 5 12:58:35 2018 +0200 [MSCONFIG] Fix buffer overflow when handling long service command lines. --- base/applications/msconfig/srvpage.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/base/applications/msconfig/srvpage.c b/base/applications/msconfig/srvpage.c index 4acdf2523e..044a512bab 100644 --- a/base/applications/msconfig/srvpage.c +++ b/base/applications/msconfig/srvpage.c @@ -233,14 +233,23 @@ GetServices ( void ) } } - memset(&FileName, 0, MAX_PATH); - if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\""))) + if (pServiceConfig->lpBinaryPathName[0] != _T('"')) { - _tcsncpy(FileName, pServiceConfig->lpBinaryPathName, _tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")) ); + /* Assume everything before the first space is the binary path */ + /* FIXME: This is a reasonable heuristic but some + * services use unquoted paths with spaces */ + StringCchCopyN(FileName, + _countof(FileName), + pServiceConfig->lpBinaryPathName, + _tcscspn(pServiceConfig->lpBinaryPathName, _T(" "))); } else { - _tcscpy(FileName, pServiceConfig->lpBinaryPathName); + /* Binary path is inside the quotes */ + StringCchCopyN(FileName, + _countof(FileName), + pServiceConfig->lpBinaryPathName + 1, + _tcscspn(pServiceConfig->lpBinaryPathName + 1, _T("\""))); } HeapFree(GetProcessHeap(), 0, pServiceConfig);
6 years, 4 months
1
0
0
0
← Newer
1
...
24
25
26
27
28
29
30
31
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Results per page:
10
25
50
100
200