Solved

Remote Registry Operations - Reading Mapped Drives on Remote Machine

Posted on 2004-04-23
5
851 Views
Last Modified: 2007-12-19
This is very similar to the question I posed yeaterday, but unlike yesterday's problem, this should be pretty easy.

To recap, I guess I cannot enumerate persistently mapped drives for a particular user using the registry (possibly through any means). In discussing this with a number of LAN Managers woh are trialing this, they have requested that I code it assuming the user whose data is to be backed up is logged on, i.e. I would be able to access their drives through HKCU.

To accomplish this, I pretty much ported over some code I have used numerous times for similar operations. For some reason that I cannot figure out, it doesn't work. I'll post the code below in a second, but to briefly explain it, following my call to RegConnectRegistry (which works) I place a call to RegOpenKeyEx, which returns a #2, and when I look that up it translates to ERROR_FILE_NOT_FOUND. The code may not look now look as it once did because I have been playing around with changing the parameters.

If anyone has any ideas, I would greatly appreciate them.

Thanks,
Jeff
*************************************************************
BOOL CFileBackupDlg::getMappings(CString strComputer)
{
      HKEY                        hKey;
      HKEY                        hSubKey;
      HKEY                        hTmpKey;
      FILE                        *fp;
      TCHAR                        szTemp[MAX_PATH];
      DWORD                        dwcSubKeys = 0;
      DWORD                        dwcValues = 0;
      DWORD                        dwcMaxSubKeyName = 0;
      DWORD                        dwcMaxValueName = 0;
      DWORD                        dwcMaxValueData = 0;
      DWORD                        dwSubKeyIndex = 0;            
      DWORD                        dwValueIndex = 0;
      DWORD                        dwBytes;
      DWORD                        dwType = 0;
      DWORD                        cchClassName = MAX_PATH;
      CString                        csBuf;
      char                        strMsg[MAX_PATH];
      char                        szBuffer[MAX_PATH];
      char                        lpArray[MAX_PATH];
      char                        lpszValueData[1024];
      char                        lpszSubKeyName[MAX_PATH];
      char                        lpName[MAX_PATH];
      char                        szLogFile[MAX_PATH];
      const unsigned int      BUF_SIZE = 1024;

      GetEnvironmentVariable ("TEMP", szTemp, sizeof (szTemp));
      lstrcpy (szLogFile, szTemp);
      lstrcat (szLogFile, "\\fileBackup.log");
      fp = fopen (szLogFile, "a+");
      fprintf (fp, "Mapped drives detected for: %s\n", strComputer);

      lstrcpy (lpName, "\\\\");
      lstrcat (lpName, strComputer);

      LONG lReturn = RegConnectRegistry (lpName, HKEY_CURRENT_USER, &hKey);
      if (lReturn != ERROR_SUCCESS)
      {
            CString            buf("Error reading drive mapping information on: ");
            buf += strComputer;
            MessageBox (buf, "Error Reading Drive Mapping Info", MB_OK | MB_ICONEXCLAMATION);
            fprintf (fp, "%s\n", buf);
            fclose (fp);
            return FALSE;
      }
      else
      {
            lReturn = RegOpenKeyEx (hKey,
                        "Network",
                        0,
                        KEY_QUERY_VALUE,
                        &hSubKey);
            if (lReturn == ERROR_SUCCESS)
            {
                  RegQueryInfoKey( hSubKey,
                              szBuffer,
                              &cchClassName,
                              NULL,
                              &dwcSubKeys,
                              &dwcMaxSubKeyName,
                              NULL,
                              &dwcValues,
                              &dwcMaxValueName,
                              &dwcMaxValueData,
                              NULL,
                              NULL );
                  if ( dwcValues != 0 || dwcSubKeys != 0 )
                  {
                        int nCount = 0;
                        do
                        {
                              DWORD dwcSubKeyName = dwcMaxSubKeyName + 1;

                              // Get data about the sub key.
                              lReturn = RegEnumKeyEx( hSubKey, dwSubKeyIndex, lpszSubKeyName,
                                   &dwcSubKeyName, NULL, NULL, NULL, NULL );
                              if ( lReturn == ERROR_SUCCESS )
                              {
                                    //create full subkey name to open
                                    lstrcpy (lpArray, "Network\\");
                                    lstrcat (lpArray, lpszSubKeyName);
                                    
                                    lReturn = RegOpenKeyEx(HKEY_CURRENT_USER,
                                                lpArray,
                                                0,
                                                KEY_ALL_ACCESS,
                                                &hTmpKey);

                                    if (lReturn == ERROR_SUCCESS)
                                    {
                                          dwBytes = BUF_SIZE;
                                          lReturn = RegQueryValueEx (hTmpKey,
                                                TEXT ("RemotePath"),
                                                NULL,
                                                &dwType,
                                                (unsigned char*)lpszValueData,
                                                &dwBytes);
                                          if ( lReturn == ERROR_SUCCESS )
                                          {
                                                fprintf (fp, "%\tDrive map letter: %s\n", lpszSubKeyName);
                                                fprintf (fp, "%\tDrive map path: %s\n", lpszValueData);
                                                wsprintf (strMsg, "Drive detected...drive letter = %s ", lpszSubKeyName);
                                                lstrcat (strMsg, "\n");
                                                wsprintf (strMsg, "Drive detected...drive path = %s ", lpszValueData);

                                          }
                                    }
                                    SetDlgItemText (IDC_STATUS, strMsg);
                                    RegCloseKey (hTmpKey);
                              }
                              dwSubKeyIndex++;
                              nCount++;
                        }while ( lReturn == ERROR_SUCCESS );
                  }
                  RegCloseKey (hSubKey);
            }
            else
                  return FALSE;
      }
      RegCloseKey (hKey);
      fclose (fp);
      return TRUE;
0
Comment
Question by:jpetter
  • 4
5 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
The problem is that you are trying to remotely connect to HKEY_CURRENT_USER - the docs explicitly state that

-------------------------------------------->8------------------------------

hKey
Specifies the one of the following predefined registry handles on the remote computer.
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA, if the remote computer is running Windows NT
Windows 95 and Windows 98: HKEY_DYN_DATA, if the remote computer is running Windows 95 or Windows 98
Windows 95 and Windows 98: HKEY_CURRENT_CONFIG, if the remote computer is running Windows 95 or Windows 98

You cannot specify the HKEY_CLASSES_ROOT or HKEY_CURRENT_USER value for this parameter.

-------------------------------------------->8------------------------------


You need to connect to 'HKEY_USERS' and read the information from there.

0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
BTW, there might be more than one user logged on to a machine - check the source code at http://www.sysinternals.com/files/PsLoggedonSrc.zip on how to enumerate through the HKEY_USERS entries.
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
Comment Utility
BTW, here's the relevant code from the samle (UNICODE):

    //
    // Use RegConnectRegistry so that we work with remote computers
    //
      if( ServerName ) {
            
            wprintf(L"Connecting to Registry of %s...", ServerName );
            fflush( stdout );

            if( RegConnectRegistry( ServerName, HKEY_USERS, &usersKey ) != ERROR_SUCCESS) {
       
                  wprintf(L"\r                                                      \r");
                  wprintf( L"Error opening HKEY_USERS for %s\n", ServerName );
                  return;
            }
            wprintf(L"\r                                                      \r");

      } else {

            if( RegOpenKey( HKEY_USERS, NULL, &usersKey ) != ERROR_SUCCESS ) {

                  wprintf( errorMessage, L"Error opening HKEY_USERS" );
                  PrintWin32Error( errorMessage, GetLastError() );
                  return;
            }
      }
   
    //
    // Enumerate keys under HKEY_USERS
    //
    index = 0;
    subKeyNameSize = sizeof( subKeyName );
    while( RegEnumKeyEx( usersKey, index, subKeyName, &subKeyNameSize,
                         NULL, NULL, NULL, &lastWriteTime ) == ERROR_SUCCESS ) {

        //
        // Ignore the default subkey and win2K user class subkeys
        //
        if( wcsicmp( subKeyName, L".default" ) &&
                  !wcsstr( subKeyName, L"Classes")) {

             wchar_t networkName [ MAX_PATH];

             wsprintf ( networkName,L"%s\\Network", subKeyName);

         lReturn = RegOpenKeyEx (usersKey,
                    networkName,
                    0,
                    KEY_QUERY_VALUE,
                    &hSubKey);

         if (lReturn == ERROR_SUCCESS) {

                  // gather information

             }

            }

        index++;
    }
0
 

Author Comment

by:jpetter
Comment Utility
I was wondering if that may be a problem, because if I manually (through regedt32) access a registry remotely those keys are not available. However, as per the February 2003 Platform SDK, when using RegConnectRegistry the hKey can be either a predefined registry handle or HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_PERFORMANCE_DATA
HKEY_USERS

I believe you, but cannot confirm it with the documentation I have. Thanks (again)
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
HKEY_CURRENT_USER does not make sense for a remote connection - think of it, this key is only a sybolic link to one of the entries under HKEY_USERS. From 'Inside Windows 2000":

HKEY_CURRENT_USER
The HKCU root key contains data regarding the preferences and software configuration of the locally logged-on user. It points to the currently logged-on user's user profile, located on the hard disk at \Documents and Settings\<username>\Ntuser.dat. (See the section "Registry Internals" later in this chapter to find out how root keys are mapped to files on the hard disk.) Whenever a user profile is loaded (such as at logon time or when a service process runs under the context of a specific username), HKCU is created as a link to the user's key under HKEY_USERS
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now