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 |