Subversion Repositories userdetect2

Rev

Rev 82 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 82 Rev 98
1
(******************************************************************************)
1
(******************************************************************************)
2
(* SPGetSid - Retrieve the current user's SID in text format                  *)
2
(* SPGetSid - Retrieve the current user's SID in text format                  *)
3
(*                                                                            *)
3
(*                                                                            *)
4
(* Copyright (c) 2004 Shorter Path Software                                   *)
4
(* Copyright (c) 2004 Shorter Path Software                                   *)
5
(* http://www.shorterpath.com                                                 *)
5
(* http://www.shorterpath.com                                                 *)
6
(******************************************************************************)
6
(******************************************************************************)
7
 
7
 
8
            (*** Modified and extended by ViaThinkSoft ***)
8
            (*** Modified and extended by ViaThinkSoft ***)
9
 
9
 
10
{
10
{
11
  SID is a data structure of variable length that identifies user, group,
11
  SID is a data structure of variable length that identifies user, group,
12
  and computer accounts.
12
  and computer accounts.
13
  Every account on a network is issued a unique SID when the account is first created.
13
  Every account on a network is issued a unique SID when the account is first created.
14
  Internal processes in Windows refer to an account's SID
14
  Internal processes in Windows refer to an account's SID
15
  rather than the account's user or group name.
15
  rather than the account's user or group name.
16
}
16
}
17
 
17
 
18
 
18
 
19
unit SPGetSid;
19
unit SPGetSid;
20
 
20
 
21
interface
21
interface
22
 
22
 
23
uses
23
uses
24
  Windows, SysUtils;
24
  Windows, SysUtils;
25
 
25
 
26
function GetCurrentUserSid: string;
26
function GetCurrentUserSid: string;
27
function GetComputerSID: string;
27
function GetComputerSID: string;
28
 
28
 
29
implementation
29
implementation
30
 
30
 
31
const
31
const
32
  HEAP_ZERO_MEMORY = $00000008;
32
  HEAP_ZERO_MEMORY = $00000008;
33
  SID_REVISION     = 1; // Current revision level
33
  SID_REVISION     = 1; // Current revision level
34
 
34
 
35
type
35
type
36
  PTokenUser = ^TTokenUser;
36
  PTokenUser = ^TTokenUser;
37
  TTokenUser = packed record
37
  TTokenUser = packed record
38
    User: TSidAndAttributes;
38
    User: TSidAndAttributes;
39
  end;
39
  end;
40
 
40
 
41
function ConvertSid(Sid: PSID; pszSidText: PChar; var dwBufferLen: DWORD): BOOL;
41
function ConvertSid(Sid: PSID; pszSidText: PChar; var dwBufferLen: DWORD): BOOL;
42
var
42
var
43
  psia: PSIDIdentifierAuthority;
43
  psia: PSIDIdentifierAuthority;
44
  dwSubAuthorities: DWORD;
44
  dwSubAuthorities: DWORD;
45
  dwSidRev: DWORD;
45
  dwSidRev: DWORD;
46
  dwCounter: DWORD;
46
  dwCounter: DWORD;
47
  dwSidSize: DWORD;
47
  dwSidSize: DWORD;
48
begin
48
begin
49
  Result := False;
49
  Result := False;
50
 
50
 
51
  dwSidRev := SID_REVISION;
51
  dwSidRev := SID_REVISION;
52
 
52
 
53
  if not IsValidSid(Sid) then Exit;
53
  if not IsValidSid(Sid) then Exit;
54
 
54
 
55
  psia := GetSidIdentifierAuthority(Sid);
55
  psia := GetSidIdentifierAuthority(Sid);
56
 
56
 
57
  dwSubAuthorities := GetSidSubAuthorityCount(Sid)^;
57
  dwSubAuthorities := GetSidSubAuthorityCount(Sid)^;
58
 
58
 
59
  dwSidSize := (15 + 12 + (12 * dwSubAuthorities) + 1) * SizeOf(Char);
59
  dwSidSize := (15 + 12 + (12 * dwSubAuthorities) + 1) * SizeOf(Char);
60
 
60
 
61
  if (dwBufferLen < dwSidSize) then
61
  if (dwBufferLen < dwSidSize) then
62
  begin
62
  begin
63
    dwBufferLen := dwSidSize;
63
    dwBufferLen := dwSidSize;
64
    SetLastError(ERROR_INSUFFICIENT_BUFFER);
64
    SetLastError(ERROR_INSUFFICIENT_BUFFER);
65
    Exit;
65
    Exit;
66
  end;
66
  end;
67
 
67
 
68
  StrFmt(pszSidText, 'S-%u-', [dwSidRev]);
68
  StrFmt(pszSidText, 'S-%u-', [dwSidRev]);
69
 
69
 
70
  if (psia.Value[0] <> 0) or (psia.Value[1] <> 0) then
70
  if (psia.Value[0] <> 0) or (psia.Value[1] <> 0) then
71
    StrFmt(pszSidText + StrLen(pszSidText),
71
    StrFmt(pszSidText + StrLen(pszSidText),
72
      '0x%.2x%.2x%.2x%.2x%.2x%.2x',
72
      '0x%.2x%.2x%.2x%.2x%.2x%.2x',
73
      [psia.Value[0], psia.Value[1], psia.Value[2],
73
      [psia.Value[0], psia.Value[1], psia.Value[2],
74
      psia.Value[3], psia.Value[4], psia.Value[5]])
74
      psia.Value[3], psia.Value[4], psia.Value[5]])
75
  else
75
  else
76
    StrFmt(pszSidText + StrLen(pszSidText),
76
    StrFmt(pszSidText + StrLen(pszSidText),
77
      '%u',
77
      '%u',
78
      [DWORD(psia.Value[5]) +
78
      [DWORD(psia.Value[5]) +
79
      DWORD(psia.Value[4] shl 8) +
79
      DWORD(psia.Value[4] shl 8) +
80
      DWORD(psia.Value[3] shl 16) +
80
      DWORD(psia.Value[3] shl 16) +
81
      DWORD(psia.Value[2] shl 24)]);
81
      DWORD(psia.Value[2] shl 24)]);
82
 
82
 
83
  dwSidSize := StrLen(pszSidText);
83
  dwSidSize := StrLen(pszSidText);
84
 
84
 
85
  for dwCounter := 0 to dwSubAuthorities - 1 do
85
  for dwCounter := 0 to dwSubAuthorities - 1 do
86
  begin
86
  begin
87
    StrFmt(pszSidText + dwSidSize, '-%u',
87
    StrFmt(pszSidText + dwSidSize, '-%u',
88
      [GetSidSubAuthority(Sid, dwCounter)^]);
88
      [GetSidSubAuthority(Sid, dwCounter)^]);
89
    dwSidSize := StrLen(pszSidText);
89
    dwSidSize := StrLen(pszSidText);
90
  end;
90
  end;
91
 
91
 
92
  Result := True;
92
  Result := True;
93
end;
93
end;
94
 
94
 
95
function ObtainTextSid(hToken: THandle; pszSid: PChar; var dwBufferLen: DWORD): BOOL;
95
function ObtainTextSid(hToken: THandle; pszSid: PChar; var dwBufferLen: DWORD): BOOL;
96
var
96
var
97
  dwReturnLength: DWORD;
97
  dwReturnLength: DWORD;
98
  dwTokenUserLength: DWORD;
98
  dwTokenUserLength: DWORD;
99
  tic: TTokenInformationClass;
99
  tic: TTokenInformationClass;
100
  ptu: Pointer;
100
  ptu: Pointer;
101
begin
101
begin
102
  Result := False;
102
  Result := False;
103
  dwReturnLength := 0;
103
  dwReturnLength := 0;
104
  dwTokenUserLength := 0;
104
  dwTokenUserLength := 0;
105
  tic := TokenUser;
105
  tic := TokenUser;
106
  ptu := nil;
106
  ptu := nil;
107
 
107
 
108
  if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
108
  if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
109
    dwReturnLength) then
109
    dwReturnLength) then
110
  begin
110
  begin
111
    if GetLastError = ERROR_INSUFFICIENT_BUFFER then
111
    if GetLastError = ERROR_INSUFFICIENT_BUFFER then
112
    begin
112
    begin
113
      ptu := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwReturnLength);
113
      ptu := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwReturnLength);
114
      if ptu = nil then Exit;
114
      if ptu = nil then Exit;
115
      dwTokenUserLength := dwReturnLength;
115
      dwTokenUserLength := dwReturnLength;
116
      dwReturnLength    := 0;
116
      dwReturnLength    := 0;
117
 
117
 
118
      if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
118
      if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
119
        dwReturnLength) then Exit;
119
        dwReturnLength) then Exit;
120
    end
120
    end
121
    else
121
    else
122
      Exit;
122
      Exit;
123
  end;
123
  end;
124
 
124
 
125
  if not ConvertSid((PTokenUser(ptu).User).Sid, pszSid, dwBufferLen) then Exit;
125
  if not ConvertSid((PTokenUser(ptu).User).Sid, pszSid, dwBufferLen) then Exit;
126
 
126
 
127
  if not HeapFree(GetProcessHeap, 0, ptu) then Exit;
127
  if not HeapFree(GetProcessHeap, 0, ptu) then Exit;
128
 
128
 
129
  Result := True;
129
  Result := True;
130
end;
130
end;
131
 
131
 
132
function GetCurrentUserSid: string;
132
function GetCurrentUserSid: string;
133
var
133
var
134
  hAccessToken: THandle;
134
  hAccessToken: THandle;
135
  bSuccess: BOOL;
135
  bSuccess: BOOL;
136
  dwBufferLen: DWORD;
136
  dwBufferLen: DWORD;
137
  szSid: array[0..MAX_PATH] of Char;
137
  szSid: array[0..MAX_PATH] of Char;
138
begin
138
begin
139
  Result := '';
139
  Result := '';
140
 
140
 
141
  bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
141
  bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
142
    hAccessToken);
142
    hAccessToken);
143
  if not bSuccess then
143
  if not bSuccess then
144
  begin
144
  begin
145
    if GetLastError = ERROR_NO_TOKEN then
145
    if GetLastError = ERROR_NO_TOKEN then
146
      bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
146
      bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
147
        hAccessToken);
147
        hAccessToken);
148
  end;
148
  end;
149
  if bSuccess then
149
  if bSuccess then
150
  begin
150
  begin
151
    ZeroMemory(@szSid, SizeOf(szSid));
151
    ZeroMemory(@szSid, SizeOf(szSid));
152
    dwBufferLen := SizeOf(szSid);
152
    dwBufferLen := SizeOf(szSid);
153
 
153
 
154
    if ObtainTextSid(hAccessToken, szSid, dwBufferLen) then
154
    if ObtainTextSid(hAccessToken, szSid, dwBufferLen) then
155
      Result := szSid;
155
      Result := szSid;
156
    CloseHandle(hAccessToken);
156
    CloseHandle(hAccessToken);
157
  end;
157
  end;
158
end;
158
end;
159
 
159
 
160
// --- Section added by ViaThinkSoft ---
160
// --- Section added by ViaThinkSoft ---
161
 
161
 
162
function SIDToString(ASID: PSID): string;
162
function SIDToString(ASID: PSID): string;
163
 
163
 
164
  function _FallBack: string;
164
  function _FallBack: string;
165
  var
165
  var
166
    StringSid : PChar;
166
    StringSid : PChar;
167
    len: DWORD;
167
    len: DWORD;
168
  begin
168
  begin
169
    len := MAX_PATH;
169
    len := MAX_PATH;
170
    StringSid := AllocMem(MAX_PATH);
170
    StringSid := AllocMem(MAX_PATH);
171
    ConvertSid(ASID, StringSid, len);
171
    ConvertSid(ASID, StringSid, len);
172
    Result := string(StringSid);
172
    Result := string(StringSid);
173
    FreeMem(StringSid);
173
    FreeMem(StringSid);
174
  end;
174
  end;
175
 
175
 
176
type
176
type
177
  TFuncConvertSidToStringSid = function(Sid: PSID; out StringSid: PChar): BOOL; stdcall;
177
  TFuncConvertSidToStringSid = function(Sid: PSID; out StringSid: PChar): BOOL; stdcall;
178
var
178
var
179
  dllHandle: Cardinal;
179
  dllHandle: HMODULE;
180
  fConvertSidToStringSid: TFuncConvertSidToStringSid;
180
  fConvertSidToStringSid: TFuncConvertSidToStringSid;
181
  StringSid : PChar;
181
  StringSid : PChar;
182
begin
182
begin
183
  dllHandle := LoadLibrary(advapi32);
183
  dllHandle := LoadLibrary(advapi32);
184
  if dllHandle = 0 then
184
  if dllHandle = 0 then
185
  begin
185
  begin
186
    result := _FallBack;
186
    result := _FallBack;
187
    Exit;
187
    Exit;
188
  end;
188
  end;
189
  try
189
  try
190
    @fConvertSidToStringSid := GetProcAddress(dllHandle, {$IFDEF UNICODE}'ConvertSidToStringSidW'{$ELSE}'ConvertSidToStringSidA'{$ENDIF});
190
    @fConvertSidToStringSid := GetProcAddress(dllHandle, {$IFDEF UNICODE}'ConvertSidToStringSidW'{$ELSE}'ConvertSidToStringSidA'{$ENDIF});
191
    if not Assigned(fConvertSidToStringSid) then
191
    if not Assigned(fConvertSidToStringSid) then
192
    begin
192
    begin
193
      result := _FallBack;
193
      result := _FallBack;
194
      Exit;
194
      Exit;
195
    end;
195
    end;
196
 
196
 
197
    fConvertSidToStringSid(ASID, StringSid);
197
    fConvertSidToStringSid(ASID, StringSid);
198
    Result := string(StringSid);
198
    Result := string(StringSid);
199
    LocalFree(HLocal(StringSid)); // added by ViaThinkSoft
199
    LocalFree(HLocal(StringSid)); // added by ViaThinkSoft
200
  finally
200
  finally
201
    FreeLibrary(dllHandle);
201
    FreeLibrary(dllHandle);
202
  end;
202
  end;
203
end;
203
end;
204
 
204
 
205
function GetComputerName: string;
205
function GetComputerName: string;
206
// Source: http://www.delphi-treff.de/tipps-tricks/netzwerkinternet/netzwerkeigenschaften/computernamen-des-eigenen-rechners-ermitteln/
206
// Source: http://www.delphi-treff.de/tipps-tricks/netzwerkinternet/netzwerkeigenschaften/computernamen-des-eigenen-rechners-ermitteln/
207
var
207
var
208
  Len: DWORD;
208
  Len: DWORD;
209
begin
209
begin
210
  Len := MAX_COMPUTERNAME_LENGTH+1;
210
  Len := MAX_COMPUTERNAME_LENGTH+1;
211
  SetLength(Result,Len);
211
  SetLength(Result,Len);
212
  if Windows.GetComputerName(PChar(Result), Len) then
212
  if Windows.GetComputerName(PChar(Result), Len) then
213
    SetLength(Result,Len)
213
    SetLength(Result,Len)
214
  else
214
  else
215
    RaiseLastOSError;
215
    RaiseLastOSError;
216
end;
216
end;
217
 
217
 
218
function GetComputerSID: string;
218
function GetComputerSID: string;
219
// Source: http://stackoverflow.com/a/7643383
219
// Source: http://stackoverflow.com/a/7643383
220
var
220
var
221
  Sid: PSID;
221
  Sid: PSID;
222
  cbSid: DWORD;
222
  cbSid: DWORD;
223
  cbReferencedDomainName : DWORD;
223
  cbReferencedDomainName : DWORD;
224
  ReferencedDomainName: string;
224
  ReferencedDomainName: string;
225
  peUse: SID_NAME_USE;
225
  peUse: SID_NAME_USE;
226
  Success: BOOL;
226
  Success: BOOL;
227
  lpSystemName : string;
227
  lpSystemName : string;
228
  lpAccountName: string;
228
  lpAccountName: string;
229
begin
229
begin
230
  result := '';
230
  result := '';
231
  Sid:=nil;
231
  Sid:=nil;
232
  try
232
  try
233
    lpSystemName:='';
233
    lpSystemName:='';
234
    lpAccountName:=GetComputerName;
234
    lpAccountName:=GetComputerName;
235
 
235
 
236
    cbSid := 0;
236
    cbSid := 0;
237
    cbReferencedDomainName := 0;
237
    cbReferencedDomainName := 0;
238
    // First call to LookupAccountName to get the buffer sizes.
238
    // First call to LookupAccountName to get the buffer sizes.
239
    Success := LookupAccountName(PChar(lpSystemName), PChar(lpAccountName), nil, cbSid, nil, cbReferencedDomainName, peUse);
239
    Success := LookupAccountName(PChar(lpSystemName), PChar(lpAccountName), nil, cbSid, nil, cbReferencedDomainName, peUse);
240
    if (not Success) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
240
    if (not Success) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
241
    begin
241
    begin
242
      SetLength(ReferencedDomainName, cbReferencedDomainName);
242
      SetLength(ReferencedDomainName, cbReferencedDomainName);
243
      Sid := AllocMem(cbSid);
243
      Sid := AllocMem(cbSid);
244
      // Second call to LookupAccountName to get the SID.
244
      // Second call to LookupAccountName to get the SID.
245
      Success := LookupAccountName(PChar(lpSystemName), PChar(lpAccountName), Sid, cbSid, PChar(ReferencedDomainName), cbReferencedDomainName, peUse);
245
      Success := LookupAccountName(PChar(lpSystemName), PChar(lpAccountName), Sid, cbSid, PChar(ReferencedDomainName), cbReferencedDomainName, peUse);
246
      if not Success then
246
      if not Success then
247
      begin
247
      begin
248
        FreeMem(Sid);
248
        FreeMem(Sid);
249
        Sid := nil;
249
        Sid := nil;
250
        RaiseLastOSError;
250
        RaiseLastOSError;
251
      end
251
      end
252
      else
252
      else
253
        Result := SIDToString(Sid);
253
        Result := SIDToString(Sid);
254
    end
254
    end
255
    else
255
    else
256
      RaiseLastOSError;
256
      RaiseLastOSError;
257
  finally
257
  finally
258
    if Assigned(Sid) then
258
    if Assigned(Sid) then
259
      FreeMem(Sid);
259
      FreeMem(Sid);
260
  end;
260
  end;
261
end;
261
end;
262
 
262
 
263
end.
263
end.
264
 
264