Microsoft KB Archive/168877: Difference between revisions

From BetaArchive Wiki
(stage2)
 
m (Text replacement - "&" to "&")
 
(7 intermediate revisions by the same user not shown)
Line 7: Line 7:




-----
----


The information in this article applies to:<br />
The information in this article applies to:<br />
Line 17: Line 17:




-----
----


<br />
<br />
Line 31: Line 31:
== MORE INFORMATION ==
== MORE INFORMATION ==


For a process that did not originate from either the interactive logged-on user or from a service (Windows NT 4.0 only) to have access to its hive, the hive must be loaded programmatically. For example, the CreateProcessAsUser API does not automatically load the user's hive, so by default any references to HKEY_CURRENT_USER from the process would map to HKEY_USERS\.default instead of HKEY_USERS\&lt;user's sid&gt; if the hive is not already loaded.
For a process that did not originate from either the interactive logged-on user or from a service (Windows NT 4.0 only) to have access to its hive, the hive must be loaded programmatically. For example, the CreateProcessAsUser API does not automatically load the user's hive, so by default any references to HKEY_CURRENT_USER from the process would map to HKEY_USERS\.default instead of HKEY_USERS\<user's sid> if the hive is not already loaded.


=== Sample Code ===
=== Sample Code ===


The following sample code requires a user, password, and an executable. This sample assumes that the specified user has an existing hive. This means the user must have interactively logged on to the machine at least once. Based on the above information, the sample code loads the user's hive and then launches the .exe given to it by the user. To load a user's hive, the user running the sample code needs to be granted the &quot;Restore files and directories&quot; (SE_RESTORE_NAME) privilege. Once the executable has exited, the sample code unloads the user's hive. You can verify that the user's hive is loaded by using Regedt32.exe. Note that the sample code does not handle modifying the security on the interactive Windowstation and Desktop. You should specify a user account that belongs to the Administrator group to avoid the User32.dll initialization error. For additional information about granting a user access to the interactive Windowstation and Desktop, please click the article number below to view the article in the Microsoft Knowledge Base:
The following sample code requires a user, password, and an executable. This sample assumes that the specified user has an existing hive. This means the user must have interactively logged on to the machine at least once. Based on the above information, the sample code loads the user's hive and then launches the .exe given to it by the user. To load a user's hive, the user running the sample code needs to be granted the "Restore files and directories" (SE_RESTORE_NAME) privilege. Once the executable has exited, the sample code unloads the user's hive. You can verify that the user's hive is loaded by using Regedt32.exe. Note that the sample code does not handle modifying the security on the interactive Windowstation and Desktop. You should specify a user account that belongs to the Administrator group to avoid the User32.dll initialization error. For additional information about granting a user access to the interactive Windowstation and Desktop, please click the article number below to view the article in the Microsoft Knowledge Base:


<blockquote>[[../win32sdk/q165194.htm|Q165194]] INFO: CreateProcessAsUser, Windowstations, and Desktops</blockquote>
<blockquote>[[../165194|Q165194]] INFO: CreateProcessAsUser, Windowstations, and Desktops</blockquote>
Note that the information contained in the ProfileImagePath registry key has changed between Windows NT 3.51 and Windows NT 4.0. On Windows NT 3.51, this key value contained both the path and name of the hive for a user. On Windows NT 4.0, it only contains the path of the hive. Hives on Windows NT 4.0 are always named Ntuser.dat. These differences are handled in the sample code.
Note that the information contained in the ProfileImagePath registry key has changed between Windows NT 3.51 and Windows NT 4.0. On Windows NT 3.51, this key value contained both the path and name of the hive for a user. On Windows NT 4.0, it only contains the path of the hive. Hives on Windows NT 4.0 are always named Ntuser.dat. These differences are handled in the sample code.


Line 45: Line 45:
   #define RTN_ERROR 13
   #define RTN_ERROR 13


   #include &lt;windows.h&gt;
   #include <windows.h>
   #include &lt;stdio.h&gt;
   #include <stdio.h>
   #include &lt;tchar.h&gt;
   #include <tchar.h>


   BOOL ConvertSid(PSID pSid, LPTSTR pszSidText, LPDWORD dwBufferLen)
   BOOL ConvertSid(PSID pSid, LPTSTR pszSidText, LPDWORD dwBufferLen)
Line 79: Line 79:
       // If not large enough, indicate proper size and setlasterror
       // If not large enough, indicate proper size and setlasterror
       //  
       //  
       if (*dwBufferLen &lt; dwSidSize){
       if (*dwBufferLen < dwSidSize){
         *dwBufferLen = dwSidSize;
         *dwBufferLen = dwSidSize;
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
Line 88: Line 88:
       // prepare S-SID_REVISION-
       // prepare S-SID_REVISION-
       //  
       //  
       dwSidSize=wsprintf(pszSidText, TEXT(&quot;S-%lu-&quot;), dwSidRev );
       dwSidSize=wsprintf(pszSidText, TEXT("S-%lu-"), dwSidRev );


       //  
       //  
       // prepare SidIdentifierAuthority
       // prepare SidIdentifierAuthority
       //  
       //  
       if ( (psia-&gt;Value[0] != 0) || (psia-&gt;Value[1] != 0) ){
       if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ){
         dwSidSize+=wsprintf(pszSidText + lstrlen(pszSidText),
         dwSidSize+=wsprintf(pszSidText + lstrlen(pszSidText),
                             TEXT(&quot;0x%02hx%02hx%02hx%02hx%02hx%02hx&quot;),
                             TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                             (USHORT)psia-&gt;Value[0],
                             (USHORT)psia->Value[0],
                             (USHORT)psia-&gt;Value[1],
                             (USHORT)psia->Value[1],
                             (USHORT)psia-&gt;Value[2],
                             (USHORT)psia->Value[2],
                             (USHORT)psia-&gt;Value[3],
                             (USHORT)psia->Value[3],
                             (USHORT)psia-&gt;Value[4],
                             (USHORT)psia->Value[4],
                             (USHORT)psia-&gt;Value[5]);
                             (USHORT)psia->Value[5]);
       }
       }
       else{
       else{
         dwSidSize+=wsprintf(pszSidText + lstrlen(pszSidText),
         dwSidSize+=wsprintf(pszSidText + lstrlen(pszSidText),
                             TEXT(&quot;%lu&quot;),
                             TEXT("%lu"),
                             (ULONG)(psia-&gt;Value[5]      )  +
                             (ULONG)(psia->Value[5]      )  +
                             (ULONG)(psia-&gt;Value[4] &lt;&lt; 8)  +
                             (ULONG)(psia->Value[4] << 8)  +
                             (ULONG)(psia-&gt;Value[3] &lt;&lt; 16)  +
                             (ULONG)(psia->Value[3] << 16)  +
                             (ULONG)(psia-&gt;Value[2] &lt;&lt; 24)  );
                             (ULONG)(psia->Value[2] << 24)  );
       }
       }


Line 115: Line 115:
       // loop through SidSubAuthorities
       // loop through SidSubAuthorities
       //  
       //  
       for (dwCounter=0 ; dwCounter &lt; dwSubAuthorities ; dwCounter++){
       for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++){
         dwSidSize+=wsprintf(pszSidText + dwSidSize, TEXT(&quot;-%lu&quot;),
         dwSidSize+=wsprintf(pszSidText + dwSidSize, TEXT("-%lu"),
         *GetSidSubAuthority(pSid, dwCounter) );
         *GetSidSubAuthority(pSid, dwCounter) );
       }
       }
Line 130: Line 130:




       TCHAR        szRegKey[1024] = TEXT(&quot;SOFTWARE\\Microsoft\\&quot;);
       TCHAR        szRegKey[1024] = TEXT("SOFTWARE\\Microsoft\\");
       TCHAR        szTemp[256] = TEXT(&quot;&quot;);
       TCHAR        szTemp[256] = TEXT("");
       DWORD        dwSizeProfilePath = dwPathSize;
       DWORD        dwSizeProfilePath = dwPathSize;
       DWORD        dwType;
       DWORD        dwType;
Line 140: Line 140:
       // concat sid
       // concat sid
       //  
       //  
       lstrcat(szRegKey, TEXT(&quot;Windows NT\\CurrentVersion\\ProfileList\\&quot;));
       lstrcat(szRegKey, TEXT("Windows NT\\CurrentVersion\\ProfileList\\"));
       lstrcat(szRegKey, pszSid);
       lstrcat(szRegKey, pszSid);


Line 147: Line 147:
       //  
       //  
       lErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0,
       lErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0,
                                 KEY_READ, &amp;hKey);
                                 KEY_READ, &hKey);
       if (lErrorCode != ERROR_SUCCESS)
       if (lErrorCode != ERROR_SUCCESS)
         return FALSE;
         return FALSE;
Line 154: Line 154:
       // query the value
       // query the value
       //  
       //  
       lErrorCode = RegQueryValueEx(hKey, TEXT(&quot;ProfileImagePath&quot;), NULL,
       lErrorCode = RegQueryValueEx(hKey, TEXT("ProfileImagePath"), NULL,
                   &amp;dwType, (LPBYTE)pszProfilePath, &amp;dwSizeProfilePath);
                   &dwType, (LPBYTE)pszProfilePath, &dwSizeProfilePath);
       if (lErrorCode != ERROR_SUCCESS)
       if (lErrorCode != ERROR_SUCCESS)
         return FALSE;
         return FALSE;


       //  
       //  
       // fix profile path by replacing &quot;%SystemRoot%&quot; with the actual path
       // fix profile path by replacing "%SystemRoot%" with the actual path
       //  
       //  
       lstrcpy(szTemp, pszProfilePath);
       lstrcpy(szTemp, pszProfilePath);
Line 172: Line 172:
       // WinNT 3.51 it is a file
       // WinNT 3.51 it is a file
       //  
       //  
       if ((GetFileAttributes(pszProfilePath) &amp; FILE_ATTRIBUTE_DIRECTORY) ==
       if ((GetFileAttributes(pszProfilePath) & FILE_ATTRIBUTE_DIRECTORY) ==
                             FILE_ATTRIBUTE_DIRECTORY)
                             FILE_ATTRIBUTE_DIRECTORY)
         lstrcat(pszProfilePath, TEXT(&quot;\\ntuser.dat&quot;));
         lstrcat(pszProfilePath, TEXT("\\ntuser.dat"));


       //  
       //  
Line 197: Line 197:
       //  
       //  
       if (!OpenProcessToken(GetCurrentProcess(),
       if (!OpenProcessToken(GetCurrentProcess(),
           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &amp;hToken))
           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
         return FALSE;
         return FALSE;


Line 204: Line 204:
       //  
       //  
       if (!LookupPrivilegeValue(NULL, pszPrivilege,
       if (!LookupPrivilegeValue(NULL, pszPrivilege,
                                 &amp;tp.Privileges[0].Luid))
                                 &tp.Privileges[0].Luid))
         return FALSE;
         return FALSE;


Line 217: Line 217:
       // enable or disable the privilege
       // enable or disable the privilege
       //  
       //  
       if (!AdjustTokenPrivileges(hToken, FALSE, &amp;tp, 0,
       if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0,
                                 (PTOKEN_PRIVILEGES)NULL, 0))
                                 (PTOKEN_PRIVILEGES)NULL, 0))
         return FALSE;
         return FALSE;
Line 259: Line 259:
       //  
       //  
       if (!GetTokenInformation(hToken, tic, (LPVOID)ptu, dwTokenUserLength,
       if (!GetTokenInformation(hToken, tic, (LPVOID)ptu, dwTokenUserLength,
                               &amp;dwReturnLength)){
                               &dwReturnLength)){
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
             ptu = (TOKEN_USER *)HeapAlloc(GetProcessHeap(),
             ptu = (TOKEN_USER *)HeapAlloc(GetProcessHeap(),
Line 270: Line 270:


             if (!GetTokenInformation(hToken, tic, (LPVOID)ptu,
             if (!GetTokenInformation(hToken, tic, (LPVOID)ptu,
                               dwTokenUserLength, &amp;dwReturnLength))
                               dwTokenUserLength, &dwReturnLength))
               return FALSE;
               return FALSE;
         }
         }
Line 280: Line 280:
       // convert the sid to textural form
       // convert the sid to textural form
       //  
       //  
       if (!ConvertSid((ptu-&gt;User).Sid, pszSid, pdwBufferLen))
       if (!ConvertSid((ptu->User).Sid, pszSid, pdwBufferLen))
         return FALSE;;
         return FALSE;;


Line 305: Line 305:
         {
         {
         if (argc != 4){
         if (argc != 4){
             _tprintf(TEXT(&quot;Usage: [account name] [password] [exe]\n&quot;));
             _tprintf(TEXT("Usage: [account name] [password] [exe]\n"));
             return RTN_ERROR;
             return RTN_ERROR;
         }
         }
Line 311: Line 311:
         dwComputerLen = sizeof(szComputerName)/sizeof(TCHAR);
         dwComputerLen = sizeof(szComputerName)/sizeof(TCHAR);


         if (!GetComputerName(szComputerName, &amp;dwComputerLen))
         if (!GetComputerName(szComputerName, &dwComputerLen))
             __leave;
             __leave;


         if (!LogonUser(argv[1], szComputerName, argv[2],
         if (!LogonUser(argv[1], szComputerName, argv[2],
                         LOGON32_LOGON_INTERACTIVE,
                         LOGON32_LOGON_INTERACTIVE,
                         LOGON32_PROVIDER_DEFAULT, &amp;hToken))
                         LOGON32_PROVIDER_DEFAULT, &hToken))
             __leave;
             __leave;


Line 329: Line 329:
         // obtain the sid
         // obtain the sid
         //  
         //  
         if (!ObtainSid(hToken, szSid, &amp;dwBufferLen))
         if (!ObtainSid(hToken, szSid, &dwBufferLen))
             __leave;
             __leave;


Line 351: Line 351:
             __leave;
             __leave;


         ZeroMemory(&amp;si, sizeof(STARTUPINFO));
         ZeroMemory(&si, sizeof(STARTUPINFO));
         si.cb        = sizeof(STARTUPINFO);
         si.cb        = sizeof(STARTUPINFO);
         si.lpDesktop = TEXT(&quot;winsta0\\default&quot;);
         si.lpDesktop = TEXT("winsta0\\default");


         if (!CreateProcessAsUser(hToken, NULL, argv[3], NULL, NULL,
         if (!CreateProcessAsUser(hToken, NULL, argv[3], NULL, NULL,
               FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL,
               FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL,
               NULL, &amp;si, &amp;pi))
               NULL, &si, &pi))
             __leave;
             __leave;



Latest revision as of 12:29, 21 July 2020

HOWTO: Load a User's Hive Programmatically

Q168877



The information in this article applies to:


  • Microsoft Win32 Application Programming Interface (API), used with:
    • Microsoft Windows NT Server versions 3.51, 4.0
    • Microsoft Windows NT Workstation versions 3.51, 4.0





SUMMARY

By default, a user's hive is loaded for only the interactive user and services running from a user account (Windows NT 4.0 only). A user's hive contains specific registry information pertaining to the user's application settings, desktop, environment, network connections, and printers. The hive is loaded under the HKEY_USERS key. The name of the hive is based on the SECURITY IDENTIFIER (SID) of the user. A process refers to its hive via the HKEY_CURRENT_USER key. This key is a mapping to the user's hive under HKEY_USERS based upon the user's SID. If the user's hive is not loaded, the system maps references pertaining to HKEY_CURRENT_USER to HKEY_USER\.default. In addition, a process running in the LocalSystem security context references to HKEY_CURRENT_USER are also mapped to HKEY_USER\.default.



MORE INFORMATION

For a process that did not originate from either the interactive logged-on user or from a service (Windows NT 4.0 only) to have access to its hive, the hive must be loaded programmatically. For example, the CreateProcessAsUser API does not automatically load the user's hive, so by default any references to HKEY_CURRENT_USER from the process would map to HKEY_USERS\.default instead of HKEY_USERS\<user's sid> if the hive is not already loaded.

Sample Code

The following sample code requires a user, password, and an executable. This sample assumes that the specified user has an existing hive. This means the user must have interactively logged on to the machine at least once. Based on the above information, the sample code loads the user's hive and then launches the .exe given to it by the user. To load a user's hive, the user running the sample code needs to be granted the "Restore files and directories" (SE_RESTORE_NAME) privilege. Once the executable has exited, the sample code unloads the user's hive. You can verify that the user's hive is loaded by using Regedt32.exe. Note that the sample code does not handle modifying the security on the interactive Windowstation and Desktop. You should specify a user account that belongs to the Administrator group to avoid the User32.dll initialization error. For additional information about granting a user access to the interactive Windowstation and Desktop, please click the article number below to view the article in the Microsoft Knowledge Base:

Q165194 INFO: CreateProcessAsUser, Windowstations, and Desktops

Note that the information contained in the ProfileImagePath registry key has changed between Windows NT 3.51 and Windows NT 4.0. On Windows NT 3.51, this key value contained both the path and name of the hive for a user. On Windows NT 4.0, it only contains the path of the hive. Hives on Windows NT 4.0 are always named Ntuser.dat. These differences are handled in the sample code.

Libraries required: USER32.LIB
                    ADVAPI32.LIB 
   #define RTN_OK     0
   #define RTN_ERROR 13

   #include <windows.h>
   #include <stdio.h>
   #include <tchar.h>

   BOOL ConvertSid(PSID pSid, LPTSTR pszSidText, LPDWORD dwBufferLen)
   {

      PSID_IDENTIFIER_AUTHORITY psia;
      DWORD dwSubAuthorities;
      DWORD dwSidRev=SID_REVISION;
      DWORD dwCounter;
      DWORD dwSidSize;

      // 
      // test if SID passed in is valid
      // 
      if(!IsValidSid(pSid)) return FALSE;

      // obtain SidIdentifierAuthority
      psia=GetSidIdentifierAuthority(pSid);

      // obtain sidsubauthority count
      dwSubAuthorities=*GetSidSubAuthorityCount(pSid);

      // 
      // compute buffer length
      // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
      // 
      dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

      // 
      // check provided buffer length.
      // If not large enough, indicate proper size and setlasterror
      // 
      if (*dwBufferLen < dwSidSize){
         *dwBufferLen = dwSidSize;
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
         return FALSE;
      }

      // 
      // prepare S-SID_REVISION-
      // 
      dwSidSize=wsprintf(pszSidText, TEXT("S-%lu-"), dwSidRev );

      // 
      // prepare SidIdentifierAuthority
      // 
      if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ){
         dwSidSize+=wsprintf(pszSidText + lstrlen(pszSidText),
                             TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                             (USHORT)psia->Value[0],
                             (USHORT)psia->Value[1],
                             (USHORT)psia->Value[2],
                             (USHORT)psia->Value[3],
                             (USHORT)psia->Value[4],
                             (USHORT)psia->Value[5]);
      }
      else{
         dwSidSize+=wsprintf(pszSidText + lstrlen(pszSidText),
                             TEXT("%lu"),
                             (ULONG)(psia->Value[5]      )   +
                             (ULONG)(psia->Value[4] <<  8)   +
                             (ULONG)(psia->Value[3] << 16)   +
                             (ULONG)(psia->Value[2] << 24)   );
      }

      // 
      // loop through SidSubAuthorities
      // 
      for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++){
         dwSidSize+=wsprintf(pszSidText + dwSidSize, TEXT("-%lu"),
         *GetSidSubAuthority(pSid, dwCounter) );
      }

      return TRUE;

   }

   BOOL ObtainProfilePath(LPTSTR pszSid, LPTSTR pszProfilePath,
                          DWORD dwPathSize)

   {


      TCHAR         szRegKey[1024] = TEXT("SOFTWARE\\Microsoft\\");
      TCHAR         szTemp[256] = TEXT("");
      DWORD         dwSizeProfilePath = dwPathSize;
      DWORD         dwType;
      HKEY          hKey;
      LONG          lErrorCode;

      // 
      // concat sid
      // 
      lstrcat(szRegKey, TEXT("Windows NT\\CurrentVersion\\ProfileList\\"));
      lstrcat(szRegKey, pszSid);

      // 
      // find the hive in the registry
      // 
      lErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0,
                                KEY_READ, &hKey);
      if (lErrorCode != ERROR_SUCCESS)
         return FALSE;

      // 
      // query the value
      // 
      lErrorCode = RegQueryValueEx(hKey, TEXT("ProfileImagePath"), NULL,
                   &dwType, (LPBYTE)pszProfilePath, &dwSizeProfilePath);
      if (lErrorCode != ERROR_SUCCESS)
         return FALSE;

      // 
      // fix profile path by replacing "%SystemRoot%" with the actual path
      // 
      lstrcpy(szTemp, pszProfilePath);
      ZeroMemory(pszProfilePath, dwPathSize);
      if (!ExpandEnvironmentStrings(szTemp, pszProfilePath,dwPathSize))
         return FALSE;

      // 
      // determine if it is a file or directory, WinNT 4.0 it is a
      // directory
      // WinNT 3.51 it is a file
      // 
      if ((GetFileAttributes(pszProfilePath) & FILE_ATTRIBUTE_DIRECTORY) ==
                             FILE_ATTRIBUTE_DIRECTORY)
         lstrcat(pszProfilePath, TEXT("\\ntuser.dat"));

      // 
      // close the key
      // 
      lErrorCode = RegCloseKey(hKey);
      if (lErrorCode != ERROR_SUCCESS)
         return FALSE;

      return TRUE;

   }

   BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
   {

      HANDLE           hToken;
      TOKEN_PRIVILEGES tp;

      // 
      // obtain the processes token
      // 
      if (!OpenProcessToken(GetCurrentProcess(),
           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
         return FALSE;

      // 
      // get the luid
      // 
      if (!LookupPrivilegeValue(NULL, pszPrivilege,
                                &tp.Privileges[0].Luid))
         return FALSE;

      tp.PrivilegeCount = 1;

      if (bEnable)
         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
      else
         tp.Privileges[0].Attributes = 0;

      // 
      // enable or disable the privilege
      // 
      if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0,
                                (PTOKEN_PRIVILEGES)NULL, 0))
         return FALSE;

      if (!CloseHandle(hToken))
         return FALSE;

      return TRUE;

   }

   BOOL Hive(LPTSTR pszSid, LPTSTR pszProfilePath, BOOL bLoad)
   {

      LONG lErrorCode;

      if (bLoad){
         lErrorCode = RegLoadKey(HKEY_USERS, pszSid, pszProfilePath);
         if (lErrorCode != ERROR_SUCCESS)
            return FALSE;
      }
      else{
         lErrorCode = RegUnLoadKey(HKEY_USERS, pszSid);
         if (lErrorCode != ERROR_SUCCESS)
            return FALSE;
      }
      return TRUE;

   }

   BOOL ObtainSid(HANDLE hToken, LPTSTR pszSid, LPDWORD pdwBufferLen)
   {

      DWORD                   dwReturnLength     = 0;
      DWORD                   dwTokenUserLength  = 0;
      TOKEN_INFORMATION_CLASS tic                = TokenUser;
      TOKEN_USER              *ptu               = NULL;

      // 
      // query info in the token
      // 
      if (!GetTokenInformation(hToken, tic, (LPVOID)ptu, dwTokenUserLength,
                               &dwReturnLength)){
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
            ptu = (TOKEN_USER *)HeapAlloc(GetProcessHeap(),
                     HEAP_ZERO_MEMORY, dwReturnLength);
            if (ptu == NULL)
               return FALSE;

            dwTokenUserLength = dwReturnLength;
            dwReturnLength    = 0;

            if (!GetTokenInformation(hToken, tic, (LPVOID)ptu,
                              dwTokenUserLength, &dwReturnLength))
               return FALSE;
         }
         else
            return FALSE;
      }

      // 
      // convert the sid to textural form
      // 
      if (!ConvertSid((ptu->User).Sid, pszSid, pdwBufferLen))
         return FALSE;;

      if (!HeapFree(GetProcessHeap(), 0, (LPVOID)ptu))
         return FALSE;

      return TRUE;

   }

   int _tmain(int argc, TCHAR *argv[])
   {
      TCHAR               szComputerName[256];
      TCHAR               szProfilePath[256];
      TCHAR               szSid[256];
      DWORD               dwBufferLen;
      DWORD               dwComputerLen;
      HANDLE              hToken = NULL;
      int                 iSuccess = RTN_ERROR;
      PROCESS_INFORMATION pi;
      STARTUPINFO         si;

      __try
         {
         if (argc != 4){
            _tprintf(TEXT("Usage: [account name] [password] [exe]\n"));
            return RTN_ERROR;
         }

         dwComputerLen = sizeof(szComputerName)/sizeof(TCHAR);

         if (!GetComputerName(szComputerName, &dwComputerLen))
            __leave;

         if (!LogonUser(argv[1], szComputerName, argv[2],
                         LOGON32_LOGON_INTERACTIVE,
                         LOGON32_PROVIDER_DEFAULT, &hToken))
            __leave;

         // 
         // initialize buffers
         // 
         ZeroMemory(szSid, (sizeof(szSid)/sizeof(TCHAR)));
         ZeroMemory(szProfilePath, (sizeof(szProfilePath)/sizeof(TCHAR)));
         dwBufferLen = (sizeof(szSid)/sizeof(TCHAR));

         // 
         // obtain the sid
         // 
         if (!ObtainSid(hToken, szSid, &dwBufferLen))
            __leave;

         // 
         // obtain profile path
         // 
         if (!ObtainProfilePath(szSid, szProfilePath,
                                 (sizeof(szProfilePath)/sizeof(TCHAR))))
            __leave;

         // 
         // enable privilege
         // 
         if (!Privilege(SE_RESTORE_NAME, TRUE))
            __leave;

         // 
         // load the hive
         // 
         if (!Hive(szSid, szProfilePath, TRUE))
            __leave;

         ZeroMemory(&si, sizeof(STARTUPINFO));
         si.cb        = sizeof(STARTUPINFO);
         si.lpDesktop = TEXT("winsta0\\default");

         if (!CreateProcessAsUser(hToken, NULL, argv[3], NULL, NULL,
               FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL,
               NULL, &si, &pi))
            __leave;

         if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED)
            __leave;

         // 
         // unload the hive
         // 
         if (!Hive(szSid, szProfilePath, FALSE))
            __leave;

         // 
         // disable the privilege
         // 
         if (!Privilege(SE_RESTORE_NAME, FALSE))
            __leave;

         iSuccess = RTN_OK;
         }
      __finally
         {
         if (hToken != NULL)
            CloseHandle(hToken);

         if (pi.hProcess != NULL)
            CloseHandle(pi.hProcess);

         if (pi.hThread != NULL)
            CloseHandle(pi.hThread);
         }

      return iSuccess;

   } 



REFERENCES

For more information on registry hives, please refer to the Microsoft Windows NT Resource Kit, Vol 1.

Additional query words:

Keywords : _IK kbprogramming kbKernBase kbRegistry kbDSupport kbGrpDSKernBase
Issue type : kbhowto
Technology : kbAudDeveloper kbWin32sSearch kbWin32API


Last Reviewed: October 27, 2000
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.