Im using the code below to get the appdata folder. Normally it works, but if I start the same process though a service using a similar way to this I get the error 0x80070005
which means Access Denied
.
HRESULT result;
if ((result = SHGetKnownFolderPath(
FOLDERID_RoamingAppData,
NULL,
NULL,
&appdate)) != S_OK)
{
std::cout << result << std::endl
return false;
}
The function that creates the process is
if (!CreateProcessAsUser(
token,
executablePath,
executableName,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
0,
&startupInfo,
&processInformation))
{
SHOW_SERVICE_ERROR;
}
I have not found anything related to this in the internet. Can anyone help?
your error that you not pass lpEnvironment
parameter to CreateProcess
call.
lpEnvironment [in, optional]
A pointer to the environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process.
as result child process uses the environment of the calling process. what effect this give to FOLDERID_RoamingAppData
? during resolve FOLDERID_RoamingAppData
- we usually got %USERPROFILE%\AppData\Roaming
- and final result will be depend from value of %USERPROFILE%
. in your case - it will be inherited from service (LocalSystem
) and will be look like C:\WINDOWS\system32\config\systemprofile
- so final path must look like C:\WINDOWS\system32\config\systemprofile\AppData\Roaming
. before return this path to caller - system check are path exist - call GetFileAttributes
. and here it fail (due security permission) - last error - 5 - ERROR_ACCESS_DENIED
. and api final return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)
which is 80070005
.
conclusion - in call CreateProcessAsUser
use pointer to environment block returned by CreateEnvironmentBlock
. and free this block later by DestroyEnvironmentBlock
. also not forget CREATE_UNICODE_ENVIRONMENT
flag in call CreateProcessAsUser
also your error can easy be reproduced in local (not elevated) process by next code:
SetEnvironmentVariableW(L"USERPROFILE", L"C:\\WINDOWS\\system32\\config\\systemprofile");
PWSTR appdate;
HRESULT result;
if ((result = SHGetKnownFolderPath(
FOLDERID_RoamingAppData,
NULL,
NULL,
&appdate)) == S_OK)
{
CoTaskMemFree(appdate);
}
if we will be set invalid path in USERPROFILE
- we got 80070003
error - HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)
User contributions licensed under CC BY-SA 3.0