Seite 1 von 1

Namen des Benutzer der momentan am System angemeldet ist.

Verfasst: 06.07.2010 09:43
von jpd
dank der Remote Desktop Services API ist möglich der zurzeit angemeldeter benutzer auszuwerten, dafür verwende ich in diesen beispiel die funktion WTSQuerySessionInformation.

In diesen beispiel wird auch die zugehörige SID des benutzer ausgewertet.

getestet auf Win 2000 Server/XP/Win7/2003.

Ciao
jpd

Code: Alles auswählen

; coded by jpd, july 2010

#WTS_CURRENT_SERVER_HANDLE = 0
#WTS_CURRENT_SESSION = -1

Enumeration ;WTS_INFO_CLASS
  #WTSInitialProgram=0
  #WTSApplicationName
  #WTSWorkingDirectory
  #WTSOEMId
  #WTSSessionId
  #WTSUserName
  #WTSWinStationName
  #WTSDomainName
  #WTSConnectState
  #WTSClientBuildNumber
  #wtsclientname
  #WTSClientDirectory
  #WTSClientProductId
  #WTSClientHardwareId
  #WTSClientAddress
  #WTSClientDisplay
  #WTSClientProtocolType
EndEnumeration

Prototype WTSQuerySessionInformation(hServer.l,SessionId.l,WtsInfoClass.l,ppBuffer.l,pBytesReturned.l)
Global  WTSQuerySessionInformation.WTSQuerySessionInformation
Prototype WTSFreeMemory(lpBuffer.l)
Global  WTSFreeMemory.WTSFreeMemory

Prototype ConvertSidToStringSid(SidS.l,pSid.l) 
Global ConvertSidToStringSid.ConvertSidToStringSid


Procedure LoadWTSAPI() 
  Protected Result 

  Result = OpenLibrary(#PB_Any, "wtsapi32.dll") 
  If Result 
    
    WTSFreeMemory=GetFunction(Result, "WTSFreeMemory")
    CompilerIf #PB_Compiler_Unicode
      WTSQuerySessionInformation = GetFunction(Result, "WTSQuerySessionInformationW") 
    CompilerElse
      WTSQuerySessionInformation = GetFunction(Result, "WTSQuerySessionInformationA") 
    CompilerEndIf
    
    If WTSQuerySessionInformation = 0 
      CloseLibrary(Result) 
      Result = 0 
    EndIf      
  EndIf 
  
  ProcedureReturn Result 
  
EndProcedure 
Procedure LoadADVApi() 
  Protected Result 
 
  Result = OpenLibrary(#PB_Any, "advapi32.dll") 
  If Result 
     
    
    CompilerIf #PB_Compiler_Unicode
    ConvertSidToStringSid    = GetFunction(Result, "ConvertSidToStringSidW") 
    CompilerElse
    ConvertSidToStringSid     = GetFunction(Result, "ConvertSidToStringSidA")
    CompilerEndIf
     If ConvertSidToStringSid = 0 
        CloseLibrary(Result) 
        Result = 0 
      EndIf      
  EndIf 

  ProcedureReturn Result 
EndProcedure 


Procedure.s CurrentSessionUserName()
  
  Protected pBytesReturnedaddress.l
  Protected UnameLength
  Protected Username.s
  Protected DomainName.s
  *username=AllocateMemory(256)
  *domainname=AllocateMemory(256)
  WTSQuery= WTSQuerySessionInformation(#WTS_CURRENT_SERVER_HANDLE,#WTS_CURRENT_SESSION , #WTSUserName ,@*Username, @pBytesReturnedaddress)
  UnameLength=MemoryStringLength(*Username)
  Username=PeekS(*Username,UnameLength)
  WTSFreeMemory(*Username)
  WTSQuery= WTSQuerySessionInformation(#WTS_CURRENT_SERVER_HANDLE,#WTS_CURRENT_SESSION , #WTSDomainName,@*domainname, @pBytesReturnedaddress)
  UnameLength=MemoryStringLength(*domainname)
  DomainName=PeekS(*domainname,UnameLength)
  WTSFreeMemory(*domainname)
  
  If DomainName <> ""
    ProcedureReturn DomainName+"\"+Username 
  Else
    ProcedureReturn Username
  EndIf
  
EndProcedure



Procedure.s  UserNametoStringSID(UserName.s)
  
  Protected SIDString.s
  *username = AllocateMemory(256)
  PokeS(*username, UserName)
  rc.l = LookupAccountName_(#Null, *username, #Null, @sidbuflen, *domainname, @dnbuflen, @sidtype)
  *domainname = AllocateMemory(dnbuflen)
  *sid = AllocateMemory(sidbuflen)
  rc = LookupAccountName_(#Null, *username, *sid, @sidbuflen, *domainname, @dnbuflen, @sidtype)
  If IsValidSid_(*sid)
    libAV=LoadADVApi() 
    If libAV
      *psid=AllocateMemory(256)
      ConvertSidToStringSid(*sid,@*psid)
      lu=MemoryStringLength(*psid)
      SIDString=PeekS(*psid,lu)
      LocalFree_(*psid)
    EndIf
  Else
    SIDString="<INVALID SID>"
  EndIf  
  FreeMemory(*username)
  FreeMemory(*domainname)
  FreeMemory(*sid)
  CloseLibrary(libAV)
  ProcedureReturn SIDString

EndProcedure

libWTS=LoadWTSAPI()
If libWTS
  Debug "loaded"
  UName.s=CurrentSessionUserName()
  SID.s=UserNametoStringSID(UName)
  CloseLibrary(libWTS)
  MessageRequester("UserName & SID",UName +#CRLF$+SID)
Else  
  Debug "libWTS not loaded"
EndIf

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 06.07.2010 18:20
von hjbremer
sehr schön und funktioniert wunderbar

aber was kann ich mit dieser langen Zahl anfangen ?

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 06.07.2010 23:49
von jpd
Hallo Hjbremer,

beschreiben ist nicht meine stärke.. ich versuche es einfach.
Die SID wird von Windows zur Identifikation von Benutzern und Gruppen verwendet.

wenn wir die registry einstellungen für den angemeldeten benutzer ändern möchten
dann können wir mit der SID den bereich HKEY_USERS\"SID" ansprechen und dort die änderungen ausführen.
diese werden eins zu eins in HKEY_CURRENT_USER übernommen und viceversa.

wenn wir änderungen in bereich HKEY_CURRENT_USER für den benutzer vornehmen möchten und diese mit andere benutzer als der zur zeit angemeldet ist (z.b. admin) dann wird das problematisch.

mit diesen beispiel wird immer der angemeldeter benutzer ermittelt und die entsprechende SID egal in welcher kontext die werkzeuge auf der machine ausgeführt werden.

hoffe ist verständlich genug, wenn nicht dann frag einfach erneut :-)
ich werde es dann nochmal versuchen (Nein!!)

Ciao
jpd

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 07.07.2010 13:24
von bobobo
ömm . .wenn man die CLSID nicht braucht reicht es auch so, oder?

Code: Alles auswählen

If ExamineEnvironmentVariables()
  While NextEnvironmentVariable()
    If FindString(EnvironmentVariableName(),"LOGONSERVER",0)
      out.s=EnvironmentVariableValue()+"\"
    EndIf
    If FindString(EnvironmentVariableName(),"USERNAME",0)
      out.s+EnvironmentVariableValue()
    EndIf
  Wend
EndIf
Debug out

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 07.07.2010 13:55
von jpd
Hallo bobobo,

wenn du dein beispiel kompilierst und als runas ausführst und dieser benutzer nicht gleich den angemeldten benutzer ist , dann wird dein beispiel nicht die informationen des angemeldeten benutzer anzeigen sondern der "runas" user.

Shardik hat hier das ganze demonstriert und was gebastelt.
http://www.purebasic.fr/german/viewtopi ... 57#p276057

ich wollte eigentlich wissen wie man das über API lösen kann.

Ciao
jpd

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 07.07.2010 15:39
von bobobo
ok

und wie ist das, wenn sich mehrere gleichzeitig am system angemeldet haben ?
Das ist bei den Servern ja wohl üblich .

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 07.07.2010 16:00
von jpd
z.b. über eine RDP sitzung ,

user A ist angemeldet (bekommt eine eigene SessionID) und in der gleiche " Session" wird mein beispiel ausgeführt als RunAs mit user B ,
dann werden die Info's von User A gelifert.

Das geschiet auch wenn user A das beispiel ausführt.

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 07.07.2010 16:05
von bobobo
das war ir schon klar ..

ich wollte eigentlich, dass dein programm alle angemeldeten user anzeigt.
aber vermutlich ist das eine andere baustelle.

Re: Namen des Benutzer der momentan am System angemeldet ist

Verfasst: 07.07.2010 16:18
von jpd
ok,

das kann (glaube ich) über WTSEnumerateSessionsEx

ermittelt werden.

Da bin ich drann, werde dann auch ein beispiel posten.
Ciao
jpd