?
Solved

Detecting number Interactive Users works in Xp but not Win2k

Posted on 2006-05-23
3
Medium Priority
?
1,131 Views
Last Modified: 2013-11-20
Hi,
Detecting number Interactive Users works in Xp but not Win2k. See code below. Is there a more reliable way in C++? Note in win2k If you logged in and the service runs this code it counts the users ok, but when you log out it seems to think the user is still logged in. In Xp it works fine.

Regards
Colin

int GetActiveUsers(void)
{
  PLUID sessions;
  ULONG count;
  NTSTATUS retval;
  int i;
  int ActiveUsers = 0;

  retval = LsaEnumerateLogonSessions(&count, &sessions);

  if (retval != 0)
  {
     //wprintf (L"LsaEnumerate failed %lu\n",   LsaNtStatusToWinError(retval));
            ActiveUsers = -1;
  }
  else
  {
      //wprintf (L"Enumerate sessions received %lu sessions.\n", count);
      // Process the array of session LUIDs...
      for (i =0;i < (int) count; i++)
      {
            ActiveUsers += GetSessionData (&sessions[i]);
      }
  }

  // Free the array of session LUIDs allocated by the LSA.
  LsaFreeReturnBuffer(sessions);
 return ActiveUsers;

}

int GetSessionData(PLUID session)
{
      PSECURITY_LOGON_SESSION_DATA sessionData = NULL;
      NTSTATUS retval;
      WCHAR buffer[256];
      WCHAR *usBuffer;
      int usLength;
      int ActiveUserCount = 0;

       // Check for a valid session.
      if (!session )
      {
            //wprintf(L"Error - Invalid logon session identifier.\n");
      }
      else
      {
            // Get the session information.
            retval = LsaGetLogonSessionData (session, &sessionData);
            if (retval != 0)
            {
                  // An error occurred. Tell the world.
                  //wprintf (L"LsaGetLogonSessionData failed %lu \n",   LsaNtStatusToWinError(retval));
                  // If session information was returned, free it.
            }
            else
            {

                  if (sessionData)
                  {

                        if (sessionData->LogonType == Interactive)
                        {
                              ++ActiveUserCount ;
                              if (sessionData->UserName.Buffer != NULL)
                              {
                                    // Get the user name.
                                    usBuffer = (sessionData->UserName).Buffer;
                                    usLength = (sessionData->UserName).Length;
                                    CString Username(usBuffer);
                                    std::clog << "User Logged On " << Username << endl;
                              }

                              //wprintf(L"interactively ");
                        }
                        sessionData->LogonType = Network;
//                        memset(sessionData,0,sizeof(SECURITY_LOGON_SESSION_DATA));
                  }
            }
      }

      if (sessionData != NULL)
      {
            // Free the memory returned by the LSA.
            LsaFreeReturnBuffer(sessionData);
      }
    return ActiveUserCount;
}
0
Comment
Question by:ace_ghostwind
3 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 16744374
Does the code from http://www.sysinternals.com/Files/PsLoggedOnSource.zip also produce different results?
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16744462
Detecting and enumerating logon sessions on NT3.x, NT4, W2K,WXP, W2K3Server :

http://www.codeproject.com/system/logonsessions.asp <=====

-MAHESH
0
 

Author Comment

by:ace_ghostwind
ID: 16751254
I did this in the end which works fine

int ProfileUsersLoggedIn( void )
{

      int                loggedOn = 0;
    TCHAR            subKeyName[MAX_PATH];
    DWORD            subKeyNameSize, index;
    FILETIME      lastWriteTime;
    HKEY            usersKey;
      BYTE            subAuthorityCount;
    DWORD            authorityVal, revision;
    DWORD            subAuthorityVal[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
   
    //
    // Use RegConnectRegistry so that we work with remote computers
    //

      if( RegOpenKey( HKEY_USERS, NULL, &usersKey ) != ERROR_SUCCESS )
      {
            std::clog << "ProfileUsersLoggedIn Error opening HKEY_USERS" << std::endl;
            loggedOn = 50;
      }
      else
      {
            //
            // 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( stricmp( subKeyName, ".default" ) &&
                        !strstr( subKeyName, "Classes")) {

                        //
                        // Convert the textual SID into a binary SID
                        //
                        subAuthorityCount= sscanf(  subKeyName, "S-%d-%x-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu",
                                                                  &revision, &authorityVal,
                                                                  &subAuthorityVal[0],
                                                                  &subAuthorityVal[1],
                                                                  &subAuthorityVal[2],
                                                                  &subAuthorityVal[3],
                                                                  &subAuthorityVal[4],
                                                                  &subAuthorityVal[5],
                                                                  &subAuthorityVal[6],
                                                                  &subAuthorityVal[7] );

                        if( subAuthorityCount >= 3 )
                        {

                              if (strnicmp("S-1-5-21",subKeyName,8) == 0)
                              {
                                    ++loggedOn;
                                    std::clog << "ProfileUsersLoggedIn Logged on locally " << subKeyName << std::endl;
                              }
                        }
                  }
                  subKeyNameSize = sizeof( subKeyName );
                  index++;
            }
            RegCloseKey( usersKey );
      }

      if( loggedOn == 0  )
      {
            std::clog << "ProfileUsersLoggedIn No one is logged on locally" << std::endl;
      }

      return loggedOn;
}
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Suggested Courses

840 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