Click here to Skip to main content
6,594,932 members and growing! (15,346 online)
Email Password   helpLost your password?
General Programming » Bugs & Workarounds » VS.NET IDE Issues     Intermediate License: The Code Project Open License (CPOL)

dbgfix: An add-in to properly launch IE during ASP.NET debugging when running VS7 under alternate credentials

By Rama Krishna Vavilala

This add-in launches IE properly during ASP.NET debugging when running VS7 under alternate credentials.
VC7Win2K, WinXP, Visual Studio, ATL, Dev
Posted:16 Apr 2003
Views:44,889
Bookmarked:20 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
8 votes for this article.
Popularity: 3.87 Rating: 4.29 out of 5
2 votes, 25.0%
1

2
1 vote, 12.5%
3

4
5 votes, 62.5%
5

Introduction

Normally I log on to my machine as a normal non-admin user. In order to debug ASP.NET applications, one needs to be a member of the administrators group. So I need to launch VS.NET as local administrator. Things work out pretty good except that there is an annoying problem that, when I start debugging of the web application, Internet Explorer does not appear, so I have to launch Internet Explorer separately.

I wrote a small macro which handled the IDE events and launched Internet Explorer when debugging started. The only problem with this solution was that, while debugging there were two ASP.NET sessions running simultaneously and single stepping through the code became confusing (as happens with debugging multithreaded applications). The fact that there were two simultaneous sessions indicated that VS did launch IE. Viewing list of processes did indicate that there was an extra IE instance.

SessView

Why was IE main window not visible? Using the SessView tool by Keith Brown indicated that the invisible IE was launched in a separate non-interactive window station. Each window created in the Windows NT based operating systems belongs to a window station. Only one window station named winsta0 is interactive. Windows that belong to this window station can interact with the user. Window stations can be allocated to a process by the parent process through the CreateProcess function call. The 9th parameter of CreateProcess is of type STARTUPINFO. STARTUPINFO has a parameter called lpDesktop which specifies the name of the window station (and desktop) allocated to the process. Here is how it works:-

  1. If lpDesktop is NULL the newly created process inherits the window station of the calling process.
  2. If lpDestop is an empty string, system allocates the process a unique window station based on the logon session ID of the newly created process. The string is of the form Service-0xX-XXX$.
  3. Otherwise system uses the name of the window station provided in lpDesktop.

All evidences from SessView pointed out that lpDestop parameter passed to CreateProcess when launching IE from VS.NET, was an empty string. So a simple fix would be to intercept CreateProcess calls from within the context of the devenv process and modify this parameter.

Detours

Detours library from Microsoft research is my favorite for API interception. API interception is greatly simplified using Detours. I recommend everyone to have a look at the source and the documentation of this library. Detours works by changing the first few processor instructions at the start of the actual API, to invoke the interceptor function or the Detour. The interceptor function can call the real function with actual instructions if needed. The only problem remaining was to inject some code in the devnev process. The easiest way to do that was to write a VS add-in. The add-in can use the Detours library to intercept CreateProcess calls.

The add-in

I named the add-in dbgfix. There are two solutions and two projects included with the source code. dbgfix2003.sln is for VS.NET 2003 users and dbgfix.sln is for VS.NET 2002 users.

To use the add-in directly :-

  1. Extract the source zip files.
  2. Register the add-in by calling RegSvr32 dbgfix.dll

If you choose to build the source, the add-in gets registered in the post build step. Here is what the add-in code does in brief:-

  1. In the OnConnection event the add-in uses Detours library to hook CreateProcessW and CreateProcessA APIs. This is done only if VS.NET is running under the credentials of the primary interactive user - the user who logged on to the machine from the logon screen.
  2. In the OnDisconnection event the add-in cleans up by removing the hooks on CreateProcessW and CreateProcessA APIs.

OnConnection

Lets examine the code of the OnConnection method of the add-in.

  1. Find whether VS.NET is running as primary interactive user. For each window station, system associates a user. The SID of the user can be obtained by calling GetUserObjectInformation on the window station handle of winsta0.
    //Winsta0 is associated with the primary interactive user
    
    HWINSTA hwinsta = OpenWindowStation(TEXT("winsta0"), 
                               FALSE, WINSTA_READATTRIBUTES);
    
    //Get the sid associated with winsta0
    
    DWORD dwLength = 0;
    
    if (!GetUserObjectInformation(hwinsta, UOI_USER_SID, 
                                       NULL, 0, &dwLength))
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            AtlThrowLastWin32();
    }
    
    CAutoVectorPtr<BYTE> spSid(new BYTE[dwLength]);
    
    if (spSid == NULL)
        AtlThrow(E_OUTOFMEMORY);
    
    if (!GetUserObjectInformation(hwinsta, UOI_USER_SID, 
                                spSid, dwLength, &dwLength))
        AtlThrowLastWin32();
  2. The next step is to find the logon sid of the user who launched devenv. This can be obtained from the process token.
    //Get the sid associated with the process token
    
    CAccessToken token;
    
    if (!token.GetProcessToken(TOKEN_QUERY))
        AtlThrowLastWin32();
    
    CSid sidLogon;
    
    if (!token.GetLogonSid(&sidLogon))
        AtlThrowLastWin32();
    
    m_bRunningAsPrimary = (sidLogon == *(SID*)((BYTE*)spSid));
  3. Finally if the logon sid of the user is different from the sid associated with the user of winsta0, we call into Detours library.
    if (!m_bRunningAsPrimary)
    {
        //This means that devnv is running in a different user 
    
        //account than the primary interactive user
    
        DetourFunctionWithTrampoline((PBYTE)Real_CreateProcessW, 
                                      (PBYTE)CreateProcessW_Detour);
        DetourFunctionWithTrampoline((PBYTE)Real_CreateProcessA, 
                                      (PBYTE)CreateProcessA_Detour);
    }

    The first DetourFunctionWithTrampoline call modifies the first few instructions at the address of the CreateProcessWand invoke the function CreateProcessW_Detour. The actual CreateProcess function can still be called using the Real_CreateProcessW. For a complete discussion on how Detours work, refer the Detour web site. Here is how the CreateProcessW_Detour function looks like.

    BOOL WINAPI CreateProcessW_Detour(LPCWSTR lpApplicationName, 
       LPWSTR  lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, 
       LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles, 
       DWORD dwCreationFlags, LPVOID lpEnvironment, 
       LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, 
       LPPROCESS_INFORMATION lpProcessInformation)
    {
       if (lpStartupInfo->lpDesktop != NULL)
       {
           //Check for empty string
    
           if (*lpStartupInfo->lpDesktop == 0)
               lpStartupInfo->lpDesktop = NULL;
       }
    
       return Real_CreateProcessW(lpApplicationName, lpCommandLine, 
              lpProcessAttributes, lpThreadAttributes, 
              bInheritHandles, dwCreationFlags, 
              lpEnvironment, lpCurrentDirectory, 
              lpStartupInfo, lpProcessInformation);
    }

    Basically if the lpDesktop is an empty string, it is converted to NULL before calling the real CreateProcessW. This makes the invoked process to inherit the same window station as VS.NET, essentially fixing the problem.

Conclusion

This simple add-in resolves the problem with launching of IE. Thanks to Microsoft research for providing the source of Detours library. Please note that only detours.lib and detours.h is included with the source of this article. If you are interested in the full source of Detours, you can download it from the Detours web site.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rama Krishna Vavilala


Member

Occupation: Architect
Location: United States United States

Other popular Bugs & Workarounds articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 6 of 6 (Total in Forum: 6) (Refresh)FirstPrevNext
GeneralCan you help me with Detours intercepting a COM method? Pinmemberehaerim9:17 16 Oct '07  
GeneralIt works! (nearly) Pinmembernapisan200212:43 2 Aug '05  
GeneralDoes it work? Pinmemberclau310714:05 30 Nov '04  
GeneralRe: Detours is _NOT_ for commercial use... PinmemberRama Krishna6:20 11 Dec '03  
GeneralIE Still Invisible Problem PinmemberSteveC8810:43 13 Oct '03  
Generalerrors , PinmemberStoney Tian18:23 27 Jun '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 16 Apr 2003
Editor: Smitha Vijayan
Copyright 2003 by Rama Krishna Vavilala
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project