Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.12.26;
Скачать: [xml.tar.bz2];

Вниз

проблемка с LsaGetLogonSessionData...   Найти похожие ветки 

 
istok   (2010-09-27 23:40) [0]

нижеприведенная программка является демкой определения времени старта сессии юзера.
всё бы хорошо, но в одном случае оно работает некорректно:
если искомая сессия является консольной сессией на сервере (windows server 2003), то почему-то вместо sessionData.Session=0 LsaGetLogonSessionData пишет другой номер сессии..

итак, вот код:

const
 WTS_CURRENT_SERVER_HANDLE = 0;

type
 PTOKEN_USER = ^TOKEN_USER;
 _TOKEN_USER = record
   User: TSidAndAttributes;
 end;
 TOKEN_USER = _TOKEN_USER;

 USHORT = word;
   
 _LSA_UNICODE_STRING = record
   Length: USHORT;
   MaximumLength: USHORT;
   Buffer: LPWSTR;
 end;
 LSA_UNICODE_STRING = _LSA_UNICODE_STRING;

 PLuid = ^LUID;
 _LUID = record
   LowPart: DWORD;
   HighPart: LongInt;
 end;
 LUID = _LUID;
 
 _SECURITY_LOGON_TYPE = (
   seltFiller0, seltFiller1,
   Interactive,
   Network,
   Batch,
   Service,
   Proxy,
   Unlock,
   NetworkCleartext,
   NewCredentials,
   RemoteInteractive,
   CachedInteractive,
   CachedRemoteInteractive);
 SECURITY_LOGON_TYPE = _SECURITY_LOGON_TYPE;

 PSECURITY_LOGON_SESSION_DATA = ^SECURITY_LOGON_SESSION_DATA;
 _SECURITY_LOGON_SESSION_DATA = record
   Size: ULONG;
   LogonId: LUID;
   UserName: LSA_UNICODE_STRING;
   LogonDomain: LSA_UNICODE_STRING;
   AuthenticationPackage: LSA_UNICODE_STRING;
   LogonType: SECURITY_LOGON_TYPE;
   Session: ULONG;
   Sid: PSID;
   LogonTime: LARGE_INTEGER;
   LogonServer: LSA_UNICODE_STRING;
   DnsDomainName: LSA_UNICODE_STRING;
   Upn: LSA_UNICODE_STRING;
 end;
 SECURITY_LOGON_SESSION_DATA = _SECURITY_LOGON_SESSION_DATA;

 _WTS_INFO_CLASS = (
   WTSInitialProgram,
   WTSApplicationName,
   WTSWorkingDirectory,
   WTSOEMId,
   WTSSessionId,
   WTSUserName,
   WTSWinStationName,
   WTSDomainName,
   WTSConnectState,
   WTSClientBuildNumber,
   WTSClientName,
   WTSClientDirectory,
   WTSClientProductId,
   WTSClientHardwareId,
   WTSClientAddress,
   WTSClientDisplay,
   WTSClientProtocolType);
 WTS_INFO_CLASS = _WTS_INFO_CLASS;

 _WTS_CONNECTSTATE_CLASS = (
   WTSActive, // User logged on to WinStation
   WTSConnected, // WinStation connected to client
   WTSConnectQuery, // In the process of connecting to client
   WTSShadow, // Shadowing another WinStation
   WTSDisconnected, // WinStation logged on without client
   WTSIdle, // Waiting for client to connect
   WTSListen, // WinStation is listening for connection
   WTSReset, // WinStation is being reset
   WTSDown, // WinStation is down due to error
   WTSInit); // WinStation in initialization
 WTS_CONNECTSTATE_CLASS = _WTS_CONNECTSTATE_CLASS;

 function LsaFreeReturnBuffer(Buffer: pointer): Integer; stdcall;

 function WTSGetActiveConsoleSessionId: DWORD; external "Kernel32.dll";

 function LsaGetLogonSessionData(LogonId: PLUID;
    var ppLogonSessionData: PSECURITY_LOGON_SESSION_DATA): LongInt; stdcall;
    external "Secur32.dll";

 function LsaNtStatusToWinError(Status: cardinal): ULONG; stdcall;
    external "Advapi32.dll";

 function LsaEnumerateLogonSessions(Count: PULONG; List: PLUID): LongInt;
    stdcall; external "Secur32.dll";

 function WTSQuerySessionInformationA(hServer: THandle; SessionId: DWORD;
    WTSInfoClass: WTS_INFO_CLASS; var pBuffer: Pointer;
    var pBytesReturned: DWORD): BOOL; stdcall; external "Wtsapi32.dll";

var
 Form1: TForm1;

implementation

uses DateUtils;

{$R *.dfm}

function LSAUnicodeStringToStr(const lsaStr : LSA_UNICODE_STRING) : string;
var
len : Integer;
begin
len := lsaStr.Length div sizeof (WideChar);
SetLength (result, len);
WideCharToMultiByte (CP_ACP, 0, lsaStr.Buffer, len,  PChar (result), len, Nil, Nil);
end;

function GMTToLocalTime(GMTTime: TDateTime): TDateTime;
var
 GMTST: Windows.TSystemTime;
 LocalST: Windows.TSystemTime;
begin
  SysUtils.DateTimeToSystemTime(GMTTime, GMTST);
  SysUtils.Win32Check(Windows.SystemTimeToTzSpecificLocalTime(nil, GMTST, LocalST));
  Result := SysUtils.SystemTimeToDateTime(LocalST);
end;

function LsaFreeReturnBuffer; external "secur32.dll" name "LsaFreeReturnBuffer";

function GetUserLogonTime(ASessionId: Integer): TDateTime;
var
  Count: cardinal;
  List: PLUID;
  sessionData: PSECURITY_LOGON_SESSION_DATA;
  i1: integer;
  SizeNeeded, SizeNeeded2: DWORD;
  OwnerName, DomainName: PChar;
  OwnerType: SID_NAME_USE;
  pBuffer: Pointer;
  pBytesreturned: DWord;
  ft: TFileTime;
  st: TSystemTime;
  dt: TDateTime;
begin
  result:= 0;  

  Form1.Memo1.Lines.Add("---- "+inttostr(ASessionId));

  i1:= lsaNtStatusToWinError(LsaEnumerateLogonSessions(@Count, @List));
  try
     if i1 = 0 then
     begin
         i1:= -1;
         if Count > 0 then
         begin  // Form1.Memo1.Lines.Add("Count > 0");
             repeat
               inc(i1);
               LsaGetLogonSessionData(List, sessionData);

               if ((sessionData.LogonType = Interactive) or (sessionData.LogonType = RemoteInteractive)) and (sessionData.Session = ASessionId) then
                 Form1.Memo1.Lines.Add("found");

                 ft.dwLowDateTime := sessionData.LogonTime.LowPart;
                 ft.dwHighDateTime := sessionData.LogonTime.HighPart;

                 FileTimeToSystemTime(ft, st);
                 dt := EncodeDateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

                 dt :=  GMTToLocalTime(dt);
                             
                 result := dt;

               Form1.Memo1.Lines.Add(format("i1=%d, user = %s, Count = %d, sessionData.LogonType=%d, sessionData.Session=%d, time = %s",
               [i1, LSAUnicodeStringToStr(sessionData.UserName), Count, integer(sessionData.LogonType), sessionData.Session,
               datetimetostr(result)]));

               inc(List);
               try
                   LSAFreeReturnBuffer(sessionData);
               except
               end;
           until (i1 = Count-1) {or (result <> 0)};
         end;
     end;
  finally
     LSAFreeReturnBuffer(List);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 ppLogonSessionData: PSECURITY_LOGON_SESSION_DATA;
 c: ULONG;
 l: PLUID;
begin
memo1.lines.add("GetCurrentSessionID = "+inttostr(GetCurrentSessionID));
memo1.lines.add(datetimetostr(GetUserLogonTime(GetCurrentSessionID)));
end;


 
istok   (2010-09-27 23:40) [1]

результат выполнения:

GetCurrentSessionID = 0
---- 0
i1=0, user = АНОНИМНЫЙ ВХОД, Count = 10, sessionData.LogonType=3, sessionData.Session=0, time = 23.09.2010 9:40:45
i1=1, user = NETWORK SERVICE, Count = 10, sessionData.LogonType=5, sessionData.Session=0, time = 23.09.2010 9:40:08
i1=2, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=3, time = 27.09.2010 23:20:03
i1=3, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=5, time = 27.09.2010 12:47:40
i1=4, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=7, time = 24.09.2010 17:06:02
i1=5, user = ademko, Count = 10, sessionData.LogonType=10, sessionData.Session=2, time = 23.09.2010 11:51:39
i1=6, user = ashestakov, Count = 10, sessionData.LogonType=10, sessionData.Session=1, time = 23.09.2010 9:41:44
i1=7, user = LOCAL SERVICE, Count = 10, sessionData.LogonType=5, sessionData.Session=5, time = 23.09.2010 9:40:08
i1=8, user = , Count = 10, sessionData.LogonType=0, sessionData.Session=0, time = 23.09.2010 9:40:08
i1=9, user = BELG-STUDENT$, Count = 10, sessionData.LogonType=0, sessionData.Session=0, time = 23.09.2010 9:40:08
23.09.2010 9:40:08

выделенная сессия является искомой, но почему-то её id возвращается как 3 а не 0.
вопрос - почему???

в других системах такая проблема пока больше не воспроизводилась.


 
istok   (2010-09-27 23:54) [2]

поправка: ровно такая же проблема воспроизвелась с консольной сессией на другом сервере.  с remote сессиями проблем нет.

в консольную сессию вхожу через mstsc.exe -admin из win7 (или /console из 2003ей) - может в этом дело? т.е. сессия консольная (нулевая), но удалённая..


 
Игорь Шевченко ©   (2010-09-28 00:11) [3]

Удаленная сессия не может быть нулевой.

"Первый сеанс входа на физической консоли компьютера считается нулевой сессией"


 
Eraser ©   (2010-09-28 00:23) [4]

> [3] Игорь Шевченко ©   (28.09.10 00:11)
> Удаленная сессия не может быть нулевой.

Еще как может.


 
istok   (2010-09-28 07:48) [5]

а как быть с тем, что вот эта функция возвращает 0 ? и в диспетчере задач в юзерах код сеанса тоже 0.


function GetCurrentSessionID: Integer;
// Getting the session id from the current process
type
 TProcessIdToSessionId = function(dwProcessId: DWORD; pSessionId: DWORD): BOOL; stdcall;
var
 ProcessIdToSessionId: TProcessIdToSessionId;
 hWTSapi32dll: THandle;
 Lib : THandle;
 pSessionId : DWord;
begin
 Result := 0;
 Lib := GetModuleHandle("kernel32");
 if Lib <> 0 then
 begin
   ProcessIdToSessionId := GetProcAddress(Lib, "ProcessIdToSessionId");
   if Assigned(ProcessIdToSessionId) then
   begin
     ProcessIdToSessionId(GetCurrentProcessId(), DWORD(@pSessionId));
     Result:= pSessionId;
   end;
 end;
end;


 
Anatoly Podgoretsky ©   (2010-09-28 08:52) [6]

Кто же будет читать эту портянку?


 
Eraser ©   (2010-09-29 02:25) [7]

> [5] istok   (28.09.10 07:48)

ну значит 0, а в чем проблема то не понятно?


 
han_malign   (2010-09-29 12:26) [8]


> но почему-то её id возвращается как 3 а не 0.

The WTSGetActiveConsoleSessionId function retrieves the Terminal Services session currently attached to the physical console. The physical console is the monitor, keyboard, and mouse. Note that it is not necessary that Terminal Services be running for this function to succeed.


> Удаленная сессия не может быть нулевой.
> "Первый сеанс входа на физической консоли компьютера считается нулевой сессией"

MSDN: Terminal Services Sessions
The console session on the Terminal Server is assigned the session ID 0.
- где тут physical?

KB: Q278845 (http://support.microsoft.com/kb/278845)
В Windows Server 2003 при использовании служб терминалов вы можете подключаться к сеансу консоли (сеанс 0) и одновременно открывать параллельный сеанс (если вы подключаетесь из сеанса не на консоли). Эта дополнительная функция позволит удаленно выполнять вход на сервер Windows Server 2003, на котором запущена служба терминалов, и подключаться к сеансу 0, как если бы вы физически находились за консолью компьютера. Этот сеанс можно также запускать параллельно, чтобы удаленный и локальный пользователи могли работать в одном сеансе.


 
Игорь Шевченко ©   (2010-09-29 13:11) [9]

han_malign   (29.09.10 12:26) [8]

Значит, надо сказать Соломону, чтобы исправил опечатку. Цитата оттуда, из "Внутреннего устройства Windows"


 
han_malign   (2010-09-29 13:36) [10]


> Значит, надо сказать Соломону

MSDN - Август 2006
Terminal Services: WTSQuerySessionInformation
...
Windows Server 2003 and Windows XP:  Session zero might not be attached to the physical console. This is because session zero can be attached to a remote session. Additionally, fast user switching is implemented using Terminal Services sessions. The first user to log on uses session zero, the next user to log on uses session one, and so on. To determine if your application is running on the physical console, call the WTSGetActiveConsoleSessionId function as follows:
(CurrentSessionId == WTSGetActiveConsoleSessionId ())

Windows 2000 Server and Windows 2000 Professional:  Session zero will be attached only to the physical console.

А начиная с Vista - нулевой сессии наглухо обломали доступ к физической консоли... В том числе, кажется, и разные хитрые манипуляции с модификацией жетона, олицетворением и т.п. ...



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.12.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.004 c
8-1208708462
NaRuTo
2008-04-20 20:21
2010.12.26
Полупрозрачность


2-1285738449
Temp User
2010-09-29 09:34
2010.12.26
Программно выделить секцию у хидера


2-1283250786
madmech
2010-08-31 14:33
2010.12.26
Проблема с рисованием на канве TDBGrid


2-1285857008
faiwer
2010-09-30 18:30
2010.12.26
Уничтожение объекта


2-1286211551
denissoft
2010-10-04 20:59
2010.12.26
где скачать пример memory path–ера!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский