These stubs are used in the Chromium sandbox.
-- v5: userenv: Add stubs and reorder functions in alphabetical order.
From: Joshua Brest 36625023+JoshuaBrest@users.noreply.github.com
--- dlls/userenv/userenv.spec | 21 +++ dlls/userenv/userenv_main.c | 256 ++++++++++++++++++++---------------- 2 files changed, 163 insertions(+), 114 deletions(-)
diff --git a/dlls/userenv/userenv.spec b/dlls/userenv/userenv.spec index 6395bba1949..42fc30c2646 100644 --- a/dlls/userenv/userenv.spec +++ b/dlls/userenv/userenv.spec @@ -2,15 +2,28 @@
@ stdcall CreateAppContainerProfile(wstr wstr wstr ptr long ptr) @ stdcall CreateEnvironmentBlock(ptr ptr long) +# @ stub CreateProfile +@ stdcall DeleteAppContainerProfile(wstr) +# @ stub DeleteProfileA +# @ stub DeleteProfileW +@ stdcall DeriveAppContainerSidFromAppContainerName(wstr ptr) +# @ stub DeriveRestrictedAppContainerSidFromAppContainerSidAndRestrictedName @ stdcall DestroyEnvironmentBlock(ptr) @ stdcall EnterCriticalPolicySection(long) @ stdcall ExpandEnvironmentStringsForUserA(ptr str ptr long) @ stdcall ExpandEnvironmentStringsForUserW(ptr wstr ptr long) +# @ stub FreeGPOListA +# @ stub FreeGPOListW @ stdcall GetAllUsersProfileDirectoryA(ptr ptr) @ stdcall GetAllUsersProfileDirectoryW(ptr ptr) +@ stdcall GetAppContainerFolderPath(wstr ptr) +@ stdcall GetAppContainerRegistryLocation(long ptr) +# @ stub GetAppliedGPOListA @ stdcall GetAppliedGPOListW(long wstr ptr ptr ptr) @ stdcall GetDefaultUserProfileDirectoryA(ptr ptr) @ stdcall GetDefaultUserProfileDirectoryW(ptr ptr) +# @ stub GetGPOListA +# @ stub GetGPOListW @ stdcall GetProfilesDirectoryA(ptr ptr) @ stdcall GetProfilesDirectoryW(ptr ptr) @ stdcall GetProfileType(ptr) @@ -19,6 +32,14 @@ @ stdcall LeaveCriticalPolicySection(ptr) @ stdcall LoadUserProfileA(ptr ptr) @ stdcall LoadUserProfileW(ptr ptr) +# @ stub ProcessGroupPolicyCompleted +# @ stub ProcessGroupPolicyCompletedEx +# @ stub RefreshPolicy +# @ stub RefreshPolicyEx @ stdcall RegisterGPNotification(long long) +# @ stub RsopAccessCheckByType +# @ stub RsopFileAccessCheck +# @ stub RsopResetPolicySettingStatus +# @ stub RsopSetPolicySettingStatus @ stdcall UnloadUserProfile(ptr ptr) @ stdcall UnregisterGPNotification(long) diff --git a/dlls/userenv/userenv_main.c b/dlls/userenv/userenv_main.c index 2d9f245f1be..28b8a3a09a0 100644 --- a/dlls/userenv/userenv_main.c +++ b/dlls/userenv/userenv_main.c @@ -169,6 +169,17 @@ static void set_wow64_environment(WCHAR **env) RegCloseKey(hkey); }
+ +HRESULT WINAPI CreateAppContainerProfile(PCWSTR container_name, PCWSTR display_name, PCWSTR description, + SID_AND_ATTRIBUTES *capabilities, DWORD capability_count, + SID **container_sid) +{ + FIXME("(%s, %s, %s, %p, %ld, %p): stub\n", debugstr_w(container_name), debugstr_w(display_name), + debugstr_w(description), capabilities, capability_count, container_sid); + + return E_NOTIMPL; +} + BOOL WINAPI CreateEnvironmentBlock( LPVOID* lpEnvironment, HANDLE hToken, BOOL bInherit ) { @@ -333,6 +344,21 @@ BOOL WINAPI CreateEnvironmentBlock( LPVOID* lpEnvironment, return TRUE; }
+HRESULT WINAPI DeleteAppContainerProfile(PCWSTR pContainerName) +{ + FIXME("(%s): stub\n", debugstr_w(pContainerName)); + + /* S_OK is returned if the context and arguments aren't invalid */ + return S_OK; +} + +HRESULT WINAPI DeriveAppContainerSidFromAppContainerName( PCWSTR pContainerName, PSID *ppSid ) +{ + FIXME("(%s, %p): stub\n", debugstr_w(pContainerName), ppSid); + + return E_NOTIMPL; +} + BOOL WINAPI DestroyEnvironmentBlock(LPVOID lpEnvironment) { NTSTATUS r; @@ -344,6 +370,13 @@ BOOL WINAPI DestroyEnvironmentBlock(LPVOID lpEnvironment) return FALSE; }
+HANDLE WINAPI EnterCriticalPolicySection(BOOL bMachine) +{ + FIXME("(%x)\n", bMachine); + SetLastError(ERROR_ACCESS_DENIED); + return NULL; +} + BOOL WINAPI ExpandEnvironmentStringsForUserA( HANDLE hToken, LPCSTR lpSrc, LPSTR lpDest, DWORD dwSize ) { @@ -368,94 +401,47 @@ BOOL WINAPI ExpandEnvironmentStringsForUserW( HANDLE hToken, LPCWSTR lpSrc, return ret; }
-BOOL WINAPI GetDefaultUserProfileDirectoryA( LPSTR lpProfileDir, LPDWORD lpcchSize ) +BOOL WINAPI GetAllUsersProfileDirectoryA( LPSTR lpProfileDir, LPDWORD lpcchSize ) { - FIXME("%p %p\n", lpProfileDir, lpcchSize ); + FIXME("%p %p\n", lpProfileDir, lpcchSize); return FALSE; }
-BOOL WINAPI GetDefaultUserProfileDirectoryW( LPWSTR lpProfileDir, LPDWORD lpcchSize ) +BOOL WINAPI GetAllUsersProfileDirectoryW( LPWSTR lpProfileDir, LPDWORD lpcchSize ) { - FIXME("%p %p\n", lpProfileDir, lpcchSize ); + FIXME("%p %p\n", lpProfileDir, lpcchSize); return FALSE; }
-BOOL WINAPI GetUserProfileDirectoryA( HANDLE hToken, LPSTR lpProfileDir, - LPDWORD lpcchSize ) +HRESULT WINAPI GetAppContainerFolderPath( PCWSTR pSidStr, PWSTR *ppPath ) { - BOOL ret; - WCHAR *dirW = NULL; - - TRACE( "%p %p %p\n", hToken, lpProfileDir, lpcchSize ); - - if (!lpProfileDir || !lpcchSize) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - if (!(dirW = HeapAlloc( GetProcessHeap(), 0, *lpcchSize * sizeof(WCHAR) ))) - return FALSE; - - if ((ret = GetUserProfileDirectoryW( hToken, dirW, lpcchSize ))) - WideCharToMultiByte( CP_ACP, 0, dirW, *lpcchSize, lpProfileDir, *lpcchSize, NULL, NULL ); - - HeapFree( GetProcessHeap(), 0, dirW ); - return ret; + FIXME("(%s, %p): stub\n", debugstr_w(pSidStr), ppPath); + return E_NOTIMPL; }
-BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir, - LPDWORD lpcchSize ) +HRESULT WINAPI GetAppContainerRegistryLocation( REGSAM dwAccess, PHKEY pRegistryKey ) { - TOKEN_USER *t; - WCHAR *userW = NULL, *dirW = NULL; - DWORD len, dir_len, domain_len; - SID_NAME_USE use; - BOOL ret = FALSE; - - TRACE( "%p %p %p\n", hToken, lpProfileDir, lpcchSize ); - - if (!lpcchSize) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - len = 0; - GetTokenInformation( hToken, TokenUser, NULL, 0, &len ); - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE; - if (!(t = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE; - if (!GetTokenInformation( hToken, TokenUser, t, len, &len )) goto done; - - len = domain_len = 0; - LookupAccountSidW( NULL, t->User.Sid, NULL, &len, NULL, &domain_len, NULL ); - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; - if (!(userW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto done; - if (!LookupAccountSidW( NULL, t->User.Sid, userW, &len, NULL, &domain_len, &use )) goto done; + FIXME("(%lx, %p): stub\n", dwAccess, pRegistryKey); + return E_NOTIMPL; +}
- dir_len = 0; - GetProfilesDirectoryW( NULL, &dir_len ); - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; - if (!(dirW = HeapAlloc( GetProcessHeap(), 0, (dir_len + 1) * sizeof(WCHAR) ))) goto done; - if (!GetProfilesDirectoryW( dirW, &dir_len )) goto done; +DWORD WINAPI GetAppliedGPOListW( DWORD dwFlags, LPCWSTR pMachineName, PSID pSidUser, GUID *pGuidExtension, + PGROUP_POLICY_OBJECTW *ppGPOList ) +{ + FIXME("(%lx %s %p %s %p)\n", dwFlags, debugstr_w(pMachineName), pSidUser, debugstr_guid(pGuidExtension), ppGPOList); + return ERROR_ACCESS_DENIED; +}
- len += dir_len + 2; - if (*lpcchSize < len || !lpProfileDir) - { - SetLastError( ERROR_INSUFFICIENT_BUFFER ); - *lpcchSize = len; - goto done; - } - lstrcpyW( lpProfileDir, dirW ); - lstrcatW( lpProfileDir, L"\" ); - lstrcatW( lpProfileDir, userW ); - *lpcchSize = len; - ret = TRUE; +BOOL WINAPI GetDefaultUserProfileDirectoryA( LPSTR lpProfileDir, LPDWORD lpcchSize ) +{ + FIXME("%p %p\n", lpProfileDir, lpcchSize ); + return FALSE; +}
-done: - HeapFree( GetProcessHeap(), 0, t ); - HeapFree( GetProcessHeap(), 0, userW ); - HeapFree( GetProcessHeap(), 0, dirW ); - return ret; +BOOL WINAPI GetDefaultUserProfileDirectoryW( LPWSTR lpProfileDir, LPDWORD lpcchSize ) +{ + FIXME("%p %p\n", lpProfileDir, lpcchSize ); + return FALSE; }
static const char ProfileListA[] = "Software\Microsoft\Windows NT\CurrentVersion\ProfileList"; @@ -580,22 +566,94 @@ end: return ret; }
-BOOL WINAPI GetAllUsersProfileDirectoryA( LPSTR lpProfileDir, LPDWORD lpcchSize ) +BOOL WINAPI GetProfileType( DWORD *pdwFlags ) { - FIXME("%p %p\n", lpProfileDir, lpcchSize); - return FALSE; + FIXME("%p\n", pdwFlags ); + *pdwFlags = 0; + return TRUE; }
-BOOL WINAPI GetAllUsersProfileDirectoryW( LPWSTR lpProfileDir, LPDWORD lpcchSize ) +BOOL WINAPI GetUserProfileDirectoryA( HANDLE hToken, LPSTR lpProfileDir, + LPDWORD lpcchSize ) { - FIXME("%p %p\n", lpProfileDir, lpcchSize); - return FALSE; + BOOL ret; + WCHAR *dirW = NULL; + + TRACE( "%p %p %p\n", hToken, lpProfileDir, lpcchSize ); + + if (!lpProfileDir || !lpcchSize) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (!(dirW = HeapAlloc( GetProcessHeap(), 0, *lpcchSize * sizeof(WCHAR) ))) + return FALSE; + + if ((ret = GetUserProfileDirectoryW( hToken, dirW, lpcchSize ))) + WideCharToMultiByte( CP_ACP, 0, dirW, *lpcchSize, lpProfileDir, *lpcchSize, NULL, NULL ); + + HeapFree( GetProcessHeap(), 0, dirW ); + return ret; }
-BOOL WINAPI GetProfileType( DWORD *pdwFlags ) +BOOL WINAPI GetUserProfileDirectoryW( HANDLE hToken, LPWSTR lpProfileDir, + LPDWORD lpcchSize ) { - FIXME("%p\n", pdwFlags ); - *pdwFlags = 0; + TOKEN_USER *t; + WCHAR *userW = NULL, *dirW = NULL; + DWORD len, dir_len, domain_len; + SID_NAME_USE use; + BOOL ret = FALSE; + + TRACE( "%p %p %p\n", hToken, lpProfileDir, lpcchSize ); + + if (!lpcchSize) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + len = 0; + GetTokenInformation( hToken, TokenUser, NULL, 0, &len ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE; + if (!(t = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE; + if (!GetTokenInformation( hToken, TokenUser, t, len, &len )) goto done; + + len = domain_len = 0; + LookupAccountSidW( NULL, t->User.Sid, NULL, &len, NULL, &domain_len, NULL ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; + if (!(userW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto done; + if (!LookupAccountSidW( NULL, t->User.Sid, userW, &len, NULL, &domain_len, &use )) goto done; + + dir_len = 0; + GetProfilesDirectoryW( NULL, &dir_len ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; + if (!(dirW = HeapAlloc( GetProcessHeap(), 0, (dir_len + 1) * sizeof(WCHAR) ))) goto done; + if (!GetProfilesDirectoryW( dirW, &dir_len )) goto done; + + len += dir_len + 2; + if (*lpcchSize < len || !lpProfileDir) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + *lpcchSize = len; + goto done; + } + lstrcpyW( lpProfileDir, dirW ); + lstrcatW( lpProfileDir, L"\" ); + lstrcatW( lpProfileDir, userW ); + *lpcchSize = len; + ret = TRUE; + +done: + HeapFree( GetProcessHeap(), 0, t ); + HeapFree( GetProcessHeap(), 0, userW ); + HeapFree( GetProcessHeap(), 0, dirW ); + return ret; +} + +BOOL WINAPI LeaveCriticalPolicySection(HANDLE hSection) +{ + FIXME("(%p)\n", hSection); return TRUE; }
@@ -619,38 +677,18 @@ BOOL WINAPI RegisterGPNotification( HANDLE event, BOOL machine ) return TRUE; }
-BOOL WINAPI UnregisterGPNotification( HANDLE event ) -{ - FIXME("%p\n", event ); - return TRUE; -} - BOOL WINAPI UnloadUserProfile( HANDLE hToken, HANDLE hProfile ) { FIXME("(%p, %p): stub\n", hToken, hProfile); return FALSE; }
-HANDLE WINAPI EnterCriticalPolicySection(BOOL bMachine) -{ - FIXME("(%x)\n", bMachine); - SetLastError(ERROR_ACCESS_DENIED); - return NULL; -} - -BOOL WINAPI LeaveCriticalPolicySection(HANDLE hSection) +BOOL WINAPI UnregisterGPNotification( HANDLE event ) { - FIXME("(%p)\n", hSection); + FIXME("%p\n", event ); return TRUE; }
-DWORD WINAPI GetAppliedGPOListW(DWORD dwFlags, LPCWSTR pMachineName, PSID pSidUser, GUID *pGuidExtension, - PGROUP_POLICY_OBJECTW *ppGPOList) -{ - FIXME("(%lx %s %p %s %p)\n", dwFlags, debugstr_w(pMachineName), pSidUser, debugstr_guid(pGuidExtension), ppGPOList); - return ERROR_ACCESS_DENIED; -} - /****************************************************************************** * USERENV.138 * @@ -687,13 +725,3 @@ BOOL WINAPI USERENV_138( int csidl, LPCSTR lnk_dir, LPCSTR lnk_filename,
return FALSE; } - -HRESULT WINAPI CreateAppContainerProfile(PCWSTR container_name, PCWSTR display_name, PCWSTR description, - SID_AND_ATTRIBUTES *capabilities, DWORD capability_count, - SID **container_sid) -{ - FIXME("(%s, %s, %s, %p, %ld, %p): stub\n", debugstr_w(container_name), debugstr_w(display_name), - debugstr_w(description), capabilities, capability_count, container_sid); - - return E_NOTIMPL; -}
IMHO it's hard to see what's changed when you combine refactoring and new changes into a single commit. Not sure if we need to have functions ordered alphabetically to begin with.
Also, FWIW, chromium only seems to need DeriveAppContainerSidFromAppContainerName, the others aren't even called for me.
On Sun Nov 10 20:15:27 2024 +0000, Fabian Maurer wrote:
IMHO it's hard to see what's changed when you combine refactoring and new changes into a single commit. Not sure if we need to have functions ordered alphabetically to begin with. Also, FWIW, chromium only seems to need DeriveAppContainerSidFromAppContainerName, the others aren't even called for me.
None of the existing functions changed. Also:
![CleanShot 2024-11-10 at 12.14.56@2x.png](/uploads/0f4be52104ec4f5febbb72dc8a161702/CleanShot_2024-11-10_at_12.14.56_2x.png)
On Sun Nov 10 20:15:26 2024 +0000, Joshua Brest wrote:
None of the existing functions changed. Also: ![CleanShot 2024-11-10 at 12.14.56@2x.png](/uploads/0f4be52104ec4f5febbb72dc8a161702/CleanShot_2024-11-10_at_12.14.56_2x.png)
Just because they don't change, doesn't make reviewing easier.
Did you try running chromium and see it use that functions? Because it doesn't for me. There's a lot of code paths that don't get used on Wine.
On Mon Nov 11 18:43:50 2024 +0000, Fabian Maurer wrote:
Do you know of a program that needs that?
@DarkShadow44 Yes, as I said, chromium does. It would work if you had `DeriveAppContainerSidFromAppContainerName` implemented. If you do: `--enable-appcontainer`.
I am still testing with Capability SID hashing...
On Mon Nov 11 21:58:04 2024 +0000, Joshua Brest wrote:
@DarkShadow44 Yes, as I said, chromium does. It would work if you had `DeriveAppContainerSidFromAppContainerName` implemented. If you do: `--enable-appcontainer`. I am still testing with Capability SID hashing...
FWIW I've implemented that with tests here: https://gitlab.winehq.org/wine/wine/-/merge_requests/3747
On Mon Nov 11 22:22:53 2024 +0000, Paul Gofman wrote:
FWIW I've implemented that with tests here: https://gitlab.winehq.org/wine/wine/-/merge_requests/3747
While I don't know that it is actually needed for Chromium right now, it uses it if available but I haven't ever saw it actually failing due to this function being absent.
On Mon Nov 11 22:27:01 2024 +0000, Paul Gofman wrote:
While I don't know that it is actually needed for Chromium right now, it uses it if available but I haven't ever seen it actually failing due to this function being absent.
@gofman Thanks so much!! That is awesome!
Yes, you're right that it falls back if it's not available, but I would definitely like it as an option ;)
On Mon Nov 11 23:20:22 2024 +0000, Joshua Brest wrote:
@gofman Thanks so much!! That is awesome! Yes, you're right that it falls back if it's not available, but I would definitely like it as an option ;)
@gofman Why hasn't your MR been merged yet?