RtlGetAssemblyStorageRoot() error 문제

간만에 생존신고를 위한 따끈따끈한 포스팅입니다.~ ㅋㅋ


SXS: Unable to resolve storage root for assembly directory x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83 in 2 tries
SXS: RtlGetAssemblyStorageRoot() unable to resolve storage map entry. Status = 0xc0150004
SXS: Unable to resolve storage root for assembly directory x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83 in 2 tries
SXS: RtlGetAssemblyStorageRoot() unable to resolve storage map entry. Status = 0xc0150004
SXS: Unable to resolve storage root for assembly directory x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83 in 2 tries
SXS: RtlGetAssemblyStorageRoot() unable to resolve storage map entry. Status = 0xc0150004


CreateProcessAsUser() 같은 함수를 사용할때 생성된 프로세스가 제대로 동작못하는 경우가 있습니다. 
저도 이 문제때문에 엄청 삽질을 했는데요. 
처음엔 manifest 가 잘 못되어그런것인지 바이너리가 잘 못되었는지 의심했습니다.
그러나 답은 간단한 곳에 있었습니다. 
환경변수 설정이 잘 못된것이었죠. 
SYSTEM_ROOT 환경변수가 해당 프로세스에 제대로 설정되지 않아서 발생했던 문제였던겁니다.

CreateEnvironmentBlock() 함수를 이용해서 환경변수를 설정해 줘야 합니다.
또한가지 주의할 점은 CREATE_UNICODE_ENVIRONMENT 플래그를 반드시 포함해 줘야 한다는 거죠. :-)
코드 나갑니다 ~ 참고만 하시길 :-)





BOOL
CreateProcessAsUserWrapperW(
IN PCWSTR UserId,
IN PCWSTR Password,
IN PCWSTR CommandLine,
IN PCWSTR CurrentDirectory,
IN BOOL Wait
)
{
_ASSERTE(NULL != UserId);
_ASSERTE(NULL != Password);
_ASSERTE(NULL != CommandLine);
if(NULL==UserId || NULL==Password||NULL==CommandLine) return FALSE;

PROCESS_INFORMATION pi = {0};
STARTUPINFOW si = {0};
PWSTR cmd=(PWSTR) malloc( (wcslen(CommandLine) + 1) * sizeof(WCHAR) );
if (NULL == cmd)
{
DBG_OP1 "[ERR ]", "insufficient memory for CommandLine" DBG_END
return FALSE;
}
SmrtPtr<PWSTR> spCmd(cmd);

RtlZeroMemory(cmd, (wcslen(CommandLine) + 1) * sizeof(WCHAR));
RtlCopyMemory(cmd, CommandLine, wcslen(CommandLine));

// user login
//
HANDLE hToken=NULL;
if (!LogonUserW(
UserId,
NULL,
Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken))
{
DBG_OP1
"[ERR ]", "LogonUserW(id=%ws) failed, error=0x%08x",
UserId, GetLastError()
DBG_END

return FALSE;
}
SmrtHandle shToken(hToken);



// 사용자, 시스템의 환경변수를 로드
// CreateProcessAsUser() 의 파라미터로 넘어가는 경우 반드시 CREATE_UNICODE_ENVIRONMENT
// 플래그를 설정해야 한다.
//
LPVOID lpvEnv=NULL;
if (TRUE != CreateEnvironmentBlock(
&lpvEnv,
hToken,
TRUE))
{
DBG_OP1
"[ERR ]", "CreateEnvironmentBlock() failed, error=0x%08x", GetLastError()
DBG_END

return FALSE;
}
SmrtEnvironmentBlock seEnv(lpvEnv);


DWORD CreationFlag = CREATE_UNICODE_ENVIRONMENT; // 꼭!!! 설정해 줘야 됌!~
si.cb = sizeof(si);
if(TRUE != CreateProcessAsUser(
hToken,
NULL,
cmd,
NULL,
NULL,
FALSE,
CreationFlag,
lpvEnv,
CurrentDirectory,
&si,
&pi
))
{
DBG_OP1
"[ERR ]", "CreateProcessAsUser() failed, error=0x%08x",
GetLastError()
DBG_END
return FALSE;
}

if (TRUE == Wait)
{
WaitForSingleObject(pi.hProcess, INFINITE);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

return TRUE;
}




덧글

댓글 입력 영역