Форум: "Начинающим";
Текущий архив: 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