1
1
#define WIN32_LEAN_AND_MEAN
2
+ #define _WIN32_WINNT 0x0500
2
3
#include <wchar.h>
3
4
#include <wctype.h>
4
5
#include <windows.h>
5
6
#include <shlobj.h>
6
7
#include <wchar.h>
8
+ #include <userenv.h>
9
+ #include <lm.h>
7
10
8
11
#define PERL_NO_GET_CONTEXT
9
12
#include "EXTERN.h"
22
25
23
26
#define GETPROC (fn ) pfn##fn = (PFN##fn)GetProcAddress(module, #fn)
24
27
25
- typedef BOOL (WINAPI * PFNSHGetSpecialFolderPathW )(HWND , WCHAR * , int , BOOL );
26
- typedef HRESULT (WINAPI * PFNSHGetFolderPathW )(HWND , int , HANDLE , DWORD , LPWSTR );
27
- typedef BOOL (WINAPI * PFNCreateEnvironmentBlock )(void * * , HANDLE , BOOL );
28
- typedef BOOL (WINAPI * PFNDestroyEnvironmentBlock )(void * );
29
28
typedef int (__stdcall * PFNDllRegisterServer )(void );
30
29
typedef int (__stdcall * PFNDllUnregisterServer )(void );
31
- typedef DWORD (__stdcall * PFNNetApiBufferFree )(void * );
32
- typedef DWORD (__stdcall * PFNNetWkstaGetInfo )(LPWSTR , DWORD , void * );
33
-
34
- typedef BOOL (__stdcall * PFNOpenProcessToken )(HANDLE , DWORD , HANDLE * );
35
- typedef BOOL (__stdcall * PFNOpenThreadToken )(HANDLE , DWORD , BOOL , HANDLE * );
36
- typedef BOOL (__stdcall * PFNGetTokenInformation )(HANDLE , TOKEN_INFORMATION_CLASS , void * , DWORD , DWORD * );
37
- typedef BOOL (__stdcall * PFNAllocateAndInitializeSid )(PSID_IDENTIFIER_AUTHORITY , BYTE , DWORD , DWORD ,
38
- DWORD , DWORD , DWORD , DWORD , DWORD , DWORD , PSID * );
39
- typedef BOOL (__stdcall * PFNEqualSid )(PSID , PSID );
40
- typedef void * (__stdcall * PFNFreeSid )(PSID );
41
30
typedef BOOL (__stdcall * PFNIsUserAnAdmin )(void );
42
31
typedef BOOL (WINAPI * PFNGetProductInfo )(DWORD , DWORD , DWORD , DWORD , DWORD * );
43
32
typedef void (WINAPI * PFNGetNativeSystemInfo )(LPSYSTEM_INFO lpSystemInfo );
@@ -188,55 +177,33 @@ get_unicode_env(pTHX_ const WCHAR *name)
188
177
SV * sv = NULL ;
189
178
void * env ;
190
179
HANDLE token ;
191
- HMODULE module ;
192
- PFNOpenProcessToken pfnOpenProcessToken ;
193
180
194
181
/* Get security token for the current process owner */
195
- module = LoadLibrary ("advapi32.dll" );
196
- if (!module )
197
- return NULL ;
198
-
199
- GETPROC (OpenProcessToken );
200
-
201
- if (pfnOpenProcessToken == NULL ||
202
- !pfnOpenProcessToken (GetCurrentProcess (), TOKEN_QUERY | TOKEN_DUPLICATE , & token ))
182
+ if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY | TOKEN_DUPLICATE , & token ))
203
183
{
204
- FreeLibrary (module );
205
184
return NULL ;
206
185
}
207
- FreeLibrary (module );
208
186
209
187
/* Create a Unicode environment block for this process */
210
- module = LoadLibrary ("userenv.dll" );
211
- if (module ) {
212
- PFNCreateEnvironmentBlock pfnCreateEnvironmentBlock ;
213
- PFNDestroyEnvironmentBlock pfnDestroyEnvironmentBlock ;
214
-
215
- GETPROC (CreateEnvironmentBlock );
216
- GETPROC (DestroyEnvironmentBlock );
217
-
218
- if (pfnCreateEnvironmentBlock && pfnDestroyEnvironmentBlock &&
219
- pfnCreateEnvironmentBlock (& env , token , FALSE))
220
- {
221
- size_t name_len = wcslen (name );
222
- WCHAR * entry = (WCHAR * )env ;
223
- while (* entry ) {
224
- size_t i ;
225
- size_t entry_len = wcslen (entry );
226
- BOOL equal = (entry_len > name_len ) && (entry [name_len ] == '=' );
227
-
228
- for (i = 0 ; equal && i < name_len ; ++ i )
229
- equal = (towupper (entry [i ]) == towupper (name [i ]));
230
-
231
- if (equal ) {
232
- sv = wstr_to_sv (aTHX_ entry + name_len + 1 );
233
- break ;
234
- }
235
- entry += entry_len + 1 ;
188
+ if (CreateEnvironmentBlock (& env , token , FALSE))
189
+ {
190
+ size_t name_len = wcslen (name );
191
+ WCHAR * entry = (WCHAR * )env ;
192
+ while (* entry ) {
193
+ size_t i ;
194
+ size_t entry_len = wcslen (entry );
195
+ BOOL equal = (entry_len > name_len ) && (entry [name_len ] == '=' );
196
+
197
+ for (i = 0 ; equal && i < name_len ; ++ i )
198
+ equal = (towupper (entry [i ]) == towupper (name [i ]));
199
+
200
+ if (equal ) {
201
+ sv = wstr_to_sv (aTHX_ entry + name_len + 1 );
202
+ break ;
236
203
}
237
- pfnDestroyEnvironmentBlock ( env ) ;
204
+ entry += entry_len + 1 ;
238
205
}
239
- FreeLibrary ( module );
206
+ DestroyEnvironmentBlock ( env );
240
207
}
241
208
CloseHandle (token );
242
209
return sv ;
@@ -367,12 +334,6 @@ XS(w32_IsAdminUser)
367
334
dXSARGS ;
368
335
HMODULE module ;
369
336
PFNIsUserAnAdmin pfnIsUserAnAdmin ;
370
- PFNOpenThreadToken pfnOpenThreadToken ;
371
- PFNOpenProcessToken pfnOpenProcessToken ;
372
- PFNGetTokenInformation pfnGetTokenInformation ;
373
- PFNAllocateAndInitializeSid pfnAllocateAndInitializeSid ;
374
- PFNEqualSid pfnEqualSid ;
375
- PFNFreeSid pfnFreeSid ;
376
337
HANDLE hTok ;
377
338
DWORD dwTokInfoLen ;
378
339
TOKEN_GROUPS * lpTokInfo ;
@@ -388,88 +349,57 @@ XS(w32_IsAdminUser)
388
349
* if the process is running with elevated privileges and not just when the
389
350
* process owner is a member of the "Administrators" group.
390
351
*/
391
- module = LoadLibrary ("shell32.dll" );
392
- if (module ) {
393
- GETPROC (IsUserAnAdmin );
394
- if (pfnIsUserAnAdmin ) {
395
- EXTEND (SP , 1 );
396
- ST (0 ) = sv_2mortal (newSViv (pfnIsUserAnAdmin () ? 1 : 0 ));
397
- FreeLibrary (module );
398
- XSRETURN (1 );
399
- }
400
- FreeLibrary (module );
401
- }
402
-
403
- module = LoadLibrary ("advapi32.dll" );
404
- if (!module ) {
405
- warn ("Cannot load advapi32.dll library" );
406
- XSRETURN_UNDEF ;
407
- }
408
-
409
- GETPROC (OpenThreadToken );
410
- GETPROC (OpenProcessToken );
411
- GETPROC (GetTokenInformation );
412
- GETPROC (AllocateAndInitializeSid );
413
- GETPROC (EqualSid );
414
- GETPROC (FreeSid );
415
-
416
- if (!(pfnOpenThreadToken && pfnOpenProcessToken &&
417
- pfnGetTokenInformation && pfnAllocateAndInitializeSid &&
418
- pfnEqualSid && pfnFreeSid ))
419
- {
420
- warn ("Cannot load functions from advapi32.dll library" );
421
- FreeLibrary (module );
422
- XSRETURN_UNDEF ;
352
+ module = GetModuleHandleA ("shell32.dll" );
353
+ GETPROC (IsUserAnAdmin );
354
+ if (pfnIsUserAnAdmin ) {
355
+ EXTEND (SP , 1 );
356
+ ST (0 ) = sv_2mortal (newSViv (pfnIsUserAnAdmin () ? 1 : 0 ));
357
+ XSRETURN (1 );
423
358
}
424
359
425
- if (!pfnOpenThreadToken (GetCurrentThread (), TOKEN_QUERY , FALSE, & hTok )) {
426
- if (!pfnOpenProcessToken (GetCurrentProcess (), TOKEN_QUERY , & hTok )) {
360
+ if (!OpenThreadToken (GetCurrentThread (), TOKEN_QUERY , FALSE, & hTok )) {
361
+ if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY , & hTok )) {
427
362
warn ("Cannot open thread token or process token" );
428
- FreeLibrary (module );
429
363
XSRETURN_UNDEF ;
430
364
}
431
365
}
432
366
433
- pfnGetTokenInformation (hTok , TokenGroups , NULL , 0 , & dwTokInfoLen );
367
+ GetTokenInformation (hTok , TokenGroups , NULL , 0 , & dwTokInfoLen );
434
368
if (!New (1 , lpTokInfo , dwTokInfoLen , TOKEN_GROUPS )) {
435
369
warn ("Cannot allocate token information structure" );
436
370
CloseHandle (hTok );
437
- FreeLibrary (module );
438
371
XSRETURN_UNDEF ;
439
372
}
440
373
441
- if (!pfnGetTokenInformation (hTok , TokenGroups , lpTokInfo , dwTokInfoLen ,
374
+ if (!GetTokenInformation (hTok , TokenGroups , lpTokInfo , dwTokInfoLen ,
442
375
& dwTokInfoLen ))
443
376
{
444
377
warn ("Cannot get token information" );
445
378
Safefree (lpTokInfo );
446
379
CloseHandle (hTok );
447
- FreeLibrary (module );
448
380
XSRETURN_UNDEF ;
449
381
}
450
382
451
- if (!pfnAllocateAndInitializeSid (& NtAuth , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
383
+ if (!AllocateAndInitializeSid (& NtAuth , 2 , SECURITY_BUILTIN_DOMAIN_RID ,
452
384
DOMAIN_ALIAS_RID_ADMINS , 0 , 0 , 0 , 0 , 0 , 0 , & pAdminSid ))
453
385
{
454
386
warn ("Cannot allocate administrators' SID" );
455
387
Safefree (lpTokInfo );
456
388
CloseHandle (hTok );
457
- FreeLibrary (module );
458
389
XSRETURN_UNDEF ;
459
390
}
460
391
461
392
iRetVal = 0 ;
462
393
for (i = 0 ; i < lpTokInfo -> GroupCount ; ++ i ) {
463
- if (pfnEqualSid (lpTokInfo -> Groups [i ].Sid , pAdminSid )) {
394
+ if (EqualSid (lpTokInfo -> Groups [i ].Sid , pAdminSid )) {
464
395
iRetVal = 1 ;
465
396
break ;
466
397
}
467
398
}
468
399
469
- pfnFreeSid (pAdminSid );
400
+ FreeSid (pAdminSid );
470
401
Safefree (lpTokInfo );
471
402
CloseHandle (hTok );
472
- FreeLibrary (module );
473
403
474
404
EXTEND (SP , 1 );
475
405
ST (0 ) = sv_2mortal (newSViv (iRetVal ));
@@ -790,7 +720,6 @@ XS(w32_GetFolderPath)
790
720
WCHAR wpath [MAX_PATH + 1 ];
791
721
int folder ;
792
722
int create = 0 ;
793
- HMODULE module ;
794
723
795
724
if (items != 1 && items != 2 )
796
725
croak ("usage: Win32::GetFolderPath($csidl [, $create])\n" );
@@ -799,28 +728,14 @@ XS(w32_GetFolderPath)
799
728
if (items == 2 )
800
729
create = SvTRUE (ST (1 )) ? CSIDL_FLAG_CREATE : 0 ;
801
730
802
- module = LoadLibrary ("shfolder.dll" );
803
- if (module ) {
804
- PFNSHGetFolderPathW pfnw ;
805
- pfnw = (PFNSHGetFolderPathW )GetProcAddress (module , "SHGetFolderPathW" );
806
- if (pfnw && SUCCEEDED (pfnw (NULL , folder |create , NULL , 0 , wpath ))) {
807
- FreeLibrary (module );
808
- ST (0 ) = wstr_to_ansipath (aTHX_ wpath );
809
- XSRETURN (1 );
810
- }
811
- FreeLibrary (module );
731
+ if (SUCCEEDED (SHGetFolderPathW (NULL , folder |create , NULL , 0 , wpath ))) {
732
+ ST (0 ) = wstr_to_ansipath (aTHX_ wpath );
733
+ XSRETURN (1 );
812
734
}
813
735
814
- module = LoadLibrary ("shell32.dll" );
815
- if (module ) {
816
- PFNSHGetSpecialFolderPathW pfnw ;
817
- pfnw = (PFNSHGetSpecialFolderPathW )GetProcAddress (module , "SHGetSpecialFolderPathW" );
818
- if (pfnw && pfnw (NULL , wpath , folder , !!create )) {
819
- FreeLibrary (module );
820
- ST (0 ) = wstr_to_ansipath (aTHX_ wpath );
821
- XSRETURN (1 );
822
- }
823
- FreeLibrary (module );
736
+ if (SHGetSpecialFolderPathW (NULL , wpath , folder , !!create )) {
737
+ ST (0 ) = wstr_to_ansipath (aTHX_ wpath );
738
+ XSRETURN (1 );
824
739
}
825
740
826
741
/* SHGetFolderPathW() and SHGetSpecialFolderPathW() may fail on older
@@ -1119,65 +1034,31 @@ XS(w32_NodeName)
1119
1034
XS (w32_DomainName )
1120
1035
{
1121
1036
dXSARGS ;
1122
- HMODULE module = LoadLibrary ("netapi32.dll" );
1123
- PFNNetApiBufferFree pfnNetApiBufferFree = NULL ;
1124
- PFNNetWkstaGetInfo pfnNetWkstaGetInfo = NULL ;
1037
+ char dname [256 ];
1038
+ DWORD dnamelen = sizeof (dname );
1039
+ WKSTA_INFO_100 * pwi ;
1040
+ DWORD retval ;
1125
1041
1126
1042
if (items )
1127
1043
Perl_croak (aTHX_ "usage: Win32::DomainName()" );
1128
- if (module ) {
1129
- GETPROC (NetApiBufferFree );
1130
- GETPROC (NetWkstaGetInfo );
1131
- }
1044
+
1132
1045
EXTEND (SP ,1 );
1133
- if (module && pfnNetWkstaGetInfo && pfnNetApiBufferFree ) {
1134
- /* this way is more reliable, in case user has a local account. */
1135
- char dname [256 ];
1136
- DWORD dnamelen = sizeof (dname );
1137
- struct {
1138
- DWORD wki100_platform_id ;
1139
- LPWSTR wki100_computername ;
1140
- LPWSTR wki100_langroup ;
1141
- DWORD wki100_ver_major ;
1142
- DWORD wki100_ver_minor ;
1143
- } * pwi ;
1144
- DWORD retval ;
1145
- retval = pfnNetWkstaGetInfo (NULL , 100 , & pwi );
1146
- /* NERR_Success *is* 0*/
1147
- if (retval == 0 ) {
1148
- if (pwi -> wki100_langroup && * (pwi -> wki100_langroup )) {
1149
- WideCharToMultiByte (CP_ACP , 0 , pwi -> wki100_langroup ,
1150
- -1 , (LPSTR )dname , dnamelen , NULL , NULL );
1151
- }
1152
- else {
1153
- WideCharToMultiByte (CP_ACP , 0 , pwi -> wki100_computername ,
1154
- -1 , (LPSTR )dname , dnamelen , NULL , NULL );
1155
- }
1156
- pfnNetApiBufferFree (pwi );
1157
- FreeLibrary (module );
1158
- XSRETURN_PV (dname );
1159
- }
1160
- FreeLibrary (module );
1161
- SetLastError (retval );
1162
- }
1163
- else {
1164
- /* Win95 doesn't have NetWksta*(), so do it the old way */
1165
- char name [256 ];
1166
- DWORD size = sizeof (name );
1167
- if (module )
1168
- FreeLibrary (module );
1169
- if (GetUserName (name ,& size )) {
1170
- char sid [ONE_K_BUFSIZE ];
1171
- DWORD sidlen = sizeof (sid );
1172
- char dname [256 ];
1173
- DWORD dnamelen = sizeof (dname );
1174
- SID_NAME_USE snu ;
1175
- if (LookupAccountName (NULL , name , (PSID )& sid , & sidlen ,
1176
- dname , & dnamelen , & snu )) {
1177
- XSRETURN_PV (dname ); /* all that for this */
1178
- }
1179
- }
1046
+
1047
+ retval = NetWkstaGetInfo (NULL , 100 , (LPBYTE * )& pwi );
1048
+ /* NERR_Success *is* 0*/
1049
+ if (retval == 0 ) {
1050
+ if (pwi -> wki100_langroup && * (pwi -> wki100_langroup )) {
1051
+ WideCharToMultiByte (CP_ACP , 0 , pwi -> wki100_langroup ,
1052
+ -1 , (LPSTR )dname , dnamelen , NULL , NULL );
1053
+ }
1054
+ else {
1055
+ WideCharToMultiByte (CP_ACP , 0 , pwi -> wki100_computername ,
1056
+ -1 , (LPSTR )dname , dnamelen , NULL , NULL );
1057
+ }
1058
+ NetApiBufferFree (pwi );
1059
+ XSRETURN_PV (dname );
1180
1060
}
1061
+ SetLastError (retval );
1181
1062
XSRETURN_UNDEF ;
1182
1063
}
1183
1064
0 commit comments