Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
platform
active.directory
adsi
adsi.iis-admin
base
com_ole
complus_mts
component_svcs
database
directx
gdi
graphics_mm
internet.client
internet.server
internet.server.isapi-dev
localization
mapi
messaging
msi
mslayerforunicode
multimedia
networking
networking.ipv6
sdk_install
security
shell
telephony.tapi_2
telephony.tapi_3
telephony.tsp
telephony.wte
tools
ui
ui_shell
win_base_svcs
win16
  
 
date: Tue, 05 Aug 2008 09:27:34 -0700,    group: microsoft.public.platformsdk.shell        back       


Problems with CreatEnvironmentBlock in 64-bit Vista   
I hope this is the right forum for this.  If not, I'd appreciate a 
suggestion on where to post it.

CreateEnvironmentBlock appears to have a bug in 64-bit Vista. Because
of the bug, Protected Mode 32-bit iexplore will fail to launch fully
(including not show a window) if iexplore is launched using
CreateEnvironmentBlock + CreateProcessAsUser in a 32-bit service and
if ieuser is not already running.

Details:
When CreateEnvironmentBlock is called without inheriting environment
variables from the current process, the returned environment block is
missing the following environment variables: CommonProgramFiles(x86),
CommonProgramW6432, ProgramFiles(x86), ProgramW6432.  Then if iexplore
is launched using that environment block, iexplore is unable to launch
ieuser, probably because it cannot expand the path to ieuser found
under ieuser's classid ("%ProgramFiles(x86)%\Internet
Explorer\IEUser.exe").  Substituting a simple exe for iexplore, it is
easy to confirm that those missing environment variables are missing
within the iexplore process (and not added later, for example, inside
the CreateProcessAsUser call or inside the WoW 32-bit subsystem).  It
is also easy to confirm that those environment variables are present
when a process is launched from Windows Explorer (or, naturally, from
CreateProcess within a process launched from Windows Explorer).

Simplified sample code:
// build with UNICODE strings
// run from the explorer shell at medium integrity


// Paths are hard coded in the following two strings for simiplicity.

static const TCHAR missing_environment_variables[] =
   _T("CommonProgramFiles(x86)=C:\\Program Files (x86)\\Common Files\0")
   _T("CommonProgramW6432=C:\\Program Files\\Common Files\0")
   _T("ProgramFiles(x86)=C:\\Program Files (x86)\0")
   _T("ProgramW6432=C:\\Program Files\0\0");

static const TCHAR iexplore_command_line[] =
   _T("\"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe\" ")
   _T("http://www.nytimes.com/");


// Get size of a multi-string.  Include all 0 characters in the returned 
size.
int GetMultzStringSize(const WCHAR* string) {
  int length = 0;
  // Determine length to final two 0 characters.
  for(; L'\0' != string[length] || L'\0' != string[length+1]; length++) {
  }
  // Add two to include the final two 0 characters.
  return sizeof(WCHAR)*(length + 2);
}

void testCreateProcessAsUser() {
  // Get a token for the current user.
  HANDLE process_token = NULL;
  if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | 
TOKEN_QUERY,
                         &process_token))
   return;
  HANDLE user_token = NULL;
  BOOL token_duplicated = DuplicateTokenEx(process_token,
     TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | 
TOKEN_DUPLICATE,
     NULL, SecurityImpersonation, TokenPrimary, &user_token);
  CloseHandle(process_token);
  if (!token_duplicated || INVALID_HANDLE_VALUE == user_token)
   return;

  STARTUPINFO startup_info = {0};
  startup_info.cb = sizeof(startup_info);
  // Setting the desktop does not help.
  //startup_info.lpDesktop = _T("winsta0\\default");
  PROCESS_INFORMATION process_info;

  // Impersonating the user does not help.
//  bool impersonating_user = !!ImpersonateLoggedOnUser(user_token);

  // Create a key for storing experiment results.  Could not get results by
  // debugging remotely since debugger did not show the entirety of the
  // environment blocks.
  HKEY key;
  if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER,
                                     _T("SOFTWARE\\Google\\experiment"), 0,
                                     NULL, 0, KEY_ALL_ACCESS, NULL, 
&key, NULL))
    return;
  DWORD creation_flags(0);
  void* environment_block(NULL);
  BYTE* fixed_environment_block(NULL);
  if (CreateEnvironmentBlock(&environment_block, user_token, FALSE)) {
   creation_flags |= CREATE_UNICODE_ENVIRONMENT;

   int size = GetMultzStringSize((const WCHAR*)environment_block);
   // Write out contents of environment block.
   RegSetValueEx(key, _T("failing_environment"), 0, REG_MULTI_SZ,
                 reinterpret_cast<const BYTE *>(environment_block), size);

   // Subtract out the final 0 character.
   size -= sizeof(WCHAR);

   // Append missing environment variables to end
   fixed_environment_block =
       new BYTE[size + sizeof(missing_environment_variables)];
   memcpy(fixed_environment_block, environment_block, size);
   memcpy(fixed_environment_block + size, missing_environment_variables,
          sizeof(missing_environment_variables));
   size = GetMultzStringSize((const WCHAR*)fixed_environment_block);
   // Write out contents of fixed environment block.
   RegSetValueEx(key, _T("failing_environment_fixed"), 0, REG_MULTI_SZ,
                 reinterpret_cast<const BYTE 
*>(fixed_environment_block), size);
  }
  void* inherited_environment_block(NULL);
  CreateEnvironmentBlock(&inherited_environment_block, user_token, TRUE);
  if (inherited_environment_block) {
   int size = GetMultzStringSize((const WCHAR*)inherited_environment_block);
   // Write out contents of environment block that inherits from current
   // process.
   RegSetValueEx(key, _T("inherited_environment"), 0, REG_MULTI_SZ,
                 reinterpret_cast<const BYTE 
*>(inherited_environment_block),
                 size);
   DestroyEnvironmentBlock(inherited_environment_block);
  }
  LPTCH environment_strings = GetEnvironmentStrings();
  if (NULL != environment_strings) {
   int size = GetMultzStringSize((const WCHAR*)environment_strings);
   // Write out current environment.
   RegSetValueEx(key, _T("current_environment"), 0, REG_MULTI_SZ,
                 reinterpret_cast<const BYTE *>(environment_strings), size);
   FreeEnvironmentStrings(environment_strings);
  }
  TCHAR command_line[500];
  // For simplicity, use hard coded path to 32-bit iexplore.
  wcscpy(command_line, iexplore_command_line);
  // Launch iexplore using failing environment block.
  if (!CreateProcessAsUser(user_token, 0, command_line, 0, 0, FALSE,
                          creation_flags, environment_block, 0,
                          &startup_info, &process_info)) {
   DWORD last_error = GetLastError();
  } else {
   CloseHandle(process_info.hThread);
   CloseHandle(process_info.hProcess);
  }
  MessageBox(NULL, _T("Pause after failed iexplore launch"),
            _T("Test Impersonation"), MB_OK);
  // Launch iexplore using fixed environment block.
  if (!CreateProcessAsUser(user_token, 0, command_line, 0, 0, FALSE,
                          creation_flags, fixed_environment_block, 0,
                          &startup_info, &process_info)) {
   DWORD last_error = GetLastError();
  } else {
   CloseHandle(process_info.hThread);
   CloseHandle(process_info.hProcess);
  }

  if (environment_block)
   DestroyEnvironmentBlock(environment_block);

  delete [] fixed_environment_block;

//  if (impersonating_user)
//    RevertToSelf();

  RegCloseKey(key);

  CloseHandle(user_token);
}

int WINAPI _tWinMain(HINSTANCE instance, HINSTANCE, TCHAR* 
command_line_string,
                    int show) {
  MessageBox(NULL, _T("Pause before test\nBefore continuing, kill ieuser"),
            _T("Test Impersonation"), MB_OK);
  testCreateProcessAsUser();
  return 0;
}
date: Tue, 05 Aug 2008 09:27:34 -0700   author:   Albert Bodenhamer am

RE: Problems with CreatEnvironmentBlock in 64-bit Vista   
Good morning Albert. Welcome to Microsoft Newsgroup Support Service! My 
name is Jialiang Ge [MSFT]. It's my pleasure to work with you on this issue.

This is a quick note to let you know that I am building a Vista x64 
environment to test your code snippet. Before the env is set up, I queried 
the symptom in the product group's database that CreateEnvironmentBlock() 
fails to set %CommonProgramFiles(x86)% and %CommonProgramFiles(x86)% and 
%ProgramFiles(x86)% for 32bit application running in WOW64 of Windows 
Vista, and found a relevant bug report:

--- BRIEF DESCRIPTION  ---
Applications fail to run when SQL Agent is running in a 32bit environment 
and tries to launch the App on a x64 Vista system with SQL installed in WOW 
mode. It internally calls
CreateEnvironmentBlock(bInherit = FALSE)
and the app fails to launch as it is unable to locate ole32db.dll (and 
other dlls which have %CommonProgramFiles(x86)% in the path for the dll). 
Essentially, com applications fail because kernel32's load library function 
is unable to locate dlls since %CommonProgramFiles(x86)% is not defined in 
the environment

--- CAUSE ---
The problem indicates that kernel32's load library function is unable to 
locate dlls. This is because %CommonProgramFiles(x86)% and 
%ProgramFiles(x86)% are not defined for 32bit application running in WOW64. 
The root cause is: on a 64bit box, if an application (both 32bit and 64bit) 
created a 32-bit child without inherit:

CreateEnvironmentBlock(bInherit = FALSE)

the child's environment variables got changed a lot, including that it will 
lose %CommonProgramFiles(x86)% and %ProgramFiles(x86)%, and there are many 
other changes as well. To fix it, on x64, we need to add 
%CommonProgramFiles(x86)% and %ProgramFiles(x86)% back to 32bit child 
without inherit, that is, it will perform the same as when a parent creates 
a 32-bit child with inherit, and also the same as when a parent creates a 
64-bit child with and without inherit. The bug is at CreateEnviromentBlock, 
however, the product team currently does not have the plan to fix it in 
Vista though the fix has been checked into the next version of Windows.

Based on the above issue description, I assume that the possible 
resolutions in your code will be:

SOLUTION1. 
Set the hInherit parameter of CreateEnvironmentBlock to TRUE if this fits 
your product environment:
http://msdn.microsoft.com/en-us/library/bb762270(VS.85).aspx 
CreateEnvironmentBlock(&environment_block, user_token, TRUE))

SOLUTION2.
If the first solution is not helpful, you may want to try this one:

%CommonProgramFiles% and %ProgramFiles% environment variable (without (x86) 
version) are always pointing to right location, according to binary types 
(32bit or 64bit) and not depending on if it is inherited and not. Thus, we 
can use these environment variables to find the right path. Also, the 
application can add the environment variable %CommonProgramFiles(x86)% to 
the value of %CommonProgramFiles% to avoid hard-coding 
_T("CommonProgramFiles(x86)=C:\\Program Files (x86)\\Common Files\0").

These two points are my current assumption of the resolution. I need to 
prove them after I build up the environment. Albert, you may also want to 
test them on your side if my env cannot be set up timely.

Best Regards,
Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and 
suggestions about how we can improve the support we provide to you. Please 
feel free to let my manager know what you think of the level of service 
provided. You can send feedback directly to my manager at: 
msdnmg@microsoft.com. 

==================================================
Get notification to my posts through email? Please refer to 
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues 
where an initial response from the community or a Microsoft Support 
Engineer within 1 business day is acceptable. Please note that each follow 
up response may take approximately 2 business days as the support 
professional working with you may need further investigation to reach the 
most efficient resolution. The offering is not appropriate for situations 
that require urgent, real-time or phone-based interactions or complex 
project analysis and dump analysis issues. Issues of this nature are best 
handled working with a dedicated Microsoft Support Engineer by contacting 
Microsoft Customer Support Services (CSS) at 
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
date: Wed, 06 Aug 2008 05:37:53 GMT   author:   (Jialiang Ge [MSFT])

RE: Problems with CreatEnvironmentBlock in 64-bit Vista   
Hello Albert,

I've built up a Windows Vista x64 environment and tested your code snippet 
in it. Below is my analysis:

1. failing_environment

Test Result: 31items
Environment Variables like CommonProgramFiles(x86), CommonProgramW6432 are 
lost.

Cause
This is indeed a bug of CreateEnvironmentBlock(bInherit = FALSE). I've 
attached the detailed information of this issue to my last reply's "CAUSE" 
section. According to the product group's responses, it has been fixed in 
the next version of Windows. However, they currently do not have plan to 
check the fix into Vista.

2. current_environment

Test Result: 37 items
Because I tested your code in a Win32 console application. The current 
environment includes the variables like CommonProgramFiles(x86), 
CommonProgramW6432.

3. inherited_environment

Test Result: 37 items
The test result depends on the current environment. Because my current 
environment includes the variables like CommonProgramFiles(x86), 
CommonProgramW6432. They are not lost in the inherited_environment.

4. failing_environment_fixed

Test Result: 35 items
The result of failing_environment_fixed  is not as complete as 
current_environment. The fixed environment is enough to run IE smoothly.

==================

In conclusion, whether my solutions in the initial reply are helpful to you 
depends.

SOLUTION1. Set the hInherit parameter of CreateEnvironmentBlock to TRUE
It depends on the current environment of the process. If 
current_environment is complete, this solution is useful.

SOLUTION2. Add the environment variable %CommonProgramFiles(x86)% to the 
value of %CommonProgramFiles% to avoid hard-coding:

static const TCHAR missing_environment_variables[] =
   _T("CommonProgramFiles(x86)=C:\\Program Files (x86)\\Common Files\0")
   _T("CommonProgramW6432=C:\\Program Files\\Common Files\0")
   _T("ProgramFiles(x86)=C:\\Program Files (x86)\0")
   _T("ProgramW6432=C:\\Program Files\0\0");
 
Albert, what do you think about these solutions and my analysis of the 
issue? If you have any other concerns or questions, please DON'T hesitate 
to tell me.

And again, thank you very much for reporting this product issue to us.

Have a great day!

Regards, 
Jialiang Ge  (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and 
suggestions about how we can improve the support we provide to you. Please 
feel free to let my manager know what you think of the level of service 
provided. You can send feedback directly to my manager at: 
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
date: Thu, 07 Aug 2008 11:32:34 GMT   author:   (Jialiang Ge [MSFT])

RE: Problems with CreatEnvironmentBlock in 64-bit Vista   
Hello Albert,

It's been a few days since my last reply. I am writing to check the status 
of the issue on your side. Because this issue has been confirmed as a 
product issue, please feel free to contact Microsoft Customer Support 
Service if you have any other concerns about this issue. The support 
incident will be free of charge for this kind of product issue.

Have a great day!

Regards, 
Jialiang Ge  (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and 
suggestions about how we can improve the support we provide to you. Please 
feel free to let my manager know what you think of the level of service 
provided. You can send feedback directly to my manager at: 
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
date: Tue, 12 Aug 2008 08:30:47 GMT   author:   (Jialiang Ge [MSFT])

Re: Problems with CreatEnvironmentBlock in 64-bit Vista   
Hi Jialiang,

Sorry I didn't follow up on the thread earlier.  It's been a busy few 
days around here and it dropped off my plate.  I was expecting the 
nospam address to forward to my actual e-mail address when I got a response.

Thanks for investigating.  It's good to hear this is a real issue and 
not a bug on our end.

We've found a workaround.  It's a bit of a hack, but it should work 
reliably for us.  If it doesn't work out I'll open a support incident.

Thanks.

Jialiang Ge [MSFT] wrote:
> Hello Albert,
> 
> It's been a few days since my last reply. I am writing to check the status 
> of the issue on your side. Because this issue has been confirmed as a 
> product issue, please feel free to contact Microsoft Customer Support 
> Service if you have any other concerns about this issue. The support 
> incident will be free of charge for this kind of product issue.
> 
> Have a great day!
> 
> Regards, 
> Jialiang Ge  (jialge@online.microsoft.com, remove 'online.')
> Microsoft Online Community Support
> 
> =================================================
> Delighting our customers is our #1 priority. We welcome your comments and 
> suggestions about how we can improve the support we provide to you. Please 
> feel free to let my manager know what you think of the level of service 
> provided. You can send feedback directly to my manager at: 
> msdnmg@microsoft.com.
> 
> This posting is provided "AS IS" with no warranties, and confers no rights.
> =================================================
>
date: Thu, 14 Aug 2008 16:38:27 -0700   author:   Albert Bodenhamer am

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us