7 #define SE_SHUTDOWN_NAMEA "SeShutdownPrivilege"
9 typedef BOOL (WINAPI *PFNSHGetSpecialFolderPath)(HWND, char*, int, BOOL);
10 typedef HRESULT (WINAPI *PFNSHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR);
11 typedef int (__stdcall *PFNDllRegisterServer)(void);
12 typedef int (__stdcall *PFNDllUnregisterServer)(void);
13 #ifndef CSIDL_FLAG_CREATE
14 # define CSIDL_FLAG_CREATE 0x8000
17 XS(w32_ExpandEnvironmentStrings)
23 croak("usage: Win32::ExpandEnvironmentStrings($String);\n");
25 ExpandEnvironmentStringsA(SvPV_nolen(ST(0)), (char*)buffer, sizeof(buffer));
26 XSRETURN_PV((char*)buffer);
33 BOOL (__stdcall *pfnOpenThreadToken)(HANDLE hThr, DWORD dwDesiredAccess,
34 BOOL bOpenAsSelf, PHANDLE phTok);
35 BOOL (__stdcall *pfnOpenProcessToken)(HANDLE hProc, DWORD dwDesiredAccess,
37 BOOL (__stdcall *pfnGetTokenInformation)(HANDLE hTok,
38 TOKEN_INFORMATION_CLASS TokenInformationClass,
39 LPVOID lpTokInfo, DWORD dwTokInfoLen,
41 BOOL (__stdcall *pfnAllocateAndInitializeSid)(
42 PSID_IDENTIFIER_AUTHORITY pIdAuth,
43 BYTE nSubAuthCount, DWORD dwSubAuth0,
44 DWORD dwSubAuth1, DWORD dwSubAuth2,
45 DWORD dwSubAuth3, DWORD dwSubAuth4,
46 DWORD dwSubAuth5, DWORD dwSubAuth6,
47 DWORD dwSubAuth7, PSID pSid);
48 BOOL (__stdcall *pfnEqualSid)(PSID pSid1, PSID pSid2);
49 PVOID (__stdcall *pfnFreeSid)(PSID pSid);
52 TOKEN_GROUPS *lpTokInfo;
53 SID_IDENTIFIER_AUTHORITY NtAuth = SECURITY_NT_AUTHORITY;
60 croak("usage: Win32::IsAdminUser()");
62 /* There is no concept of "Administrator" user accounts on Win9x systems,
63 so just return true. */
64 memset(&osver, 0, sizeof(OSVERSIONINFO));
65 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
67 if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
70 hAdvApi32 = LoadLibrary("advapi32.dll");
72 warn("Cannot load advapi32.dll library");
76 pfnOpenThreadToken = (BOOL (__stdcall *)(HANDLE, DWORD, BOOL, PHANDLE))
77 GetProcAddress(hAdvApi32, "OpenThreadToken");
78 pfnOpenProcessToken = (BOOL (__stdcall *)(HANDLE, DWORD, PHANDLE))
79 GetProcAddress(hAdvApi32, "OpenProcessToken");
80 pfnGetTokenInformation = (BOOL (__stdcall *)(HANDLE,
81 TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD))
82 GetProcAddress(hAdvApi32, "GetTokenInformation");
83 pfnAllocateAndInitializeSid = (BOOL (__stdcall *)(
84 PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD,
85 DWORD, DWORD, DWORD, PSID))
86 GetProcAddress(hAdvApi32, "AllocateAndInitializeSid");
87 pfnEqualSid = (BOOL (__stdcall *)(PSID, PSID))
88 GetProcAddress(hAdvApi32, "EqualSid");
89 pfnFreeSid = (PVOID (__stdcall *)(PSID))
90 GetProcAddress(hAdvApi32, "FreeSid");
92 if (!(pfnOpenThreadToken && pfnOpenProcessToken &&
93 pfnGetTokenInformation && pfnAllocateAndInitializeSid &&
94 pfnEqualSid && pfnFreeSid))
96 warn("Cannot load functions from advapi32.dll library");
97 FreeLibrary(hAdvApi32);
101 if (!pfnOpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hTok)) {
102 if (!pfnOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hTok)) {
103 warn("Cannot open thread token or process token");
104 FreeLibrary(hAdvApi32);
109 pfnGetTokenInformation(hTok, TokenGroups, NULL, 0, &dwTokInfoLen);
110 if (!New(1, lpTokInfo, dwTokInfoLen, TOKEN_GROUPS)) {
111 warn("Cannot allocate token information structure");
113 FreeLibrary(hAdvApi32);
117 if (!pfnGetTokenInformation(hTok, TokenGroups, lpTokInfo, dwTokInfoLen,
120 warn("Cannot get token information");
123 FreeLibrary(hAdvApi32);
127 if (!pfnAllocateAndInitializeSid(&NtAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
128 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid))
130 warn("Cannot allocate administrators' SID");
133 FreeLibrary(hAdvApi32);
138 for (i = 0; i < lpTokInfo->GroupCount; ++i) {
139 if (pfnEqualSid(lpTokInfo->Groups[i].Sid, pAdminSid)) {
145 pfnFreeSid(pAdminSid);
148 FreeLibrary(hAdvApi32);
151 ST(0) = sv_2mortal(newSViv(iRetVal));
155 XS(w32_LookupAccountName)
166 croak("usage: Win32::LookupAccountName($system, $account, $domain, "
167 "$sid, $sidtype);\n");
169 SIDLen = sizeof(SID);
170 DomLen = sizeof(Domain);
172 bResult = LookupAccountNameA(SvPV_nolen(ST(0)), /* System */
173 SvPV_nolen(ST(1)), /* Account name */
174 &SID, /* SID structure */
175 &SIDLen, /* Size of SID buffer */
176 Domain, /* Domain buffer */
177 &DomLen, /* Domain buffer size */
178 &snu); /* SID name type */
180 sv_setpv(ST(2), Domain);
181 sv_setpvn(ST(3), SID, SIDLen);
182 sv_setiv(ST(4), snu);
189 XS(w32_LookupAccountSID)
194 DWORD AcctLen = sizeof(Account);
196 DWORD DomLen = sizeof(Domain);
201 croak("usage: Win32::LookupAccountSID($system, $sid, $account, $domain, $sidtype);\n");
203 sid = SvPV_nolen(ST(1));
204 if (IsValidSid(sid)) {
205 bResult = LookupAccountSidA(SvPV_nolen(ST(0)), /* System */
206 sid, /* SID structure */
207 Account, /* Account name buffer */
208 &AcctLen, /* name buffer length */
209 Domain, /* Domain buffer */
210 &DomLen, /* Domain buffer length */
211 &snu); /* SID name type */
213 sv_setpv(ST(2), Account);
214 sv_setpv(ST(3), Domain);
215 sv_setiv(ST(4), (IV)snu);
222 XS(w32_InitiateSystemShutdown)
225 HANDLE hToken; /* handle to process token */
226 TOKEN_PRIVILEGES tkp; /* pointer to token structure */
228 char *machineName, *message;
231 croak("usage: Win32::InitiateSystemShutdown($machineName, $message, "
232 "$timeOut, $forceClose, $reboot);\n");
234 machineName = SvPV_nolen(ST(0));
236 if (OpenProcessToken(GetCurrentProcess(),
237 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
240 LookupPrivilegeValueA(machineName,
242 &tkp.Privileges[0].Luid);
244 tkp.PrivilegeCount = 1; /* only setting one */
245 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
247 /* Get shutdown privilege for this process. */
248 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
249 (PTOKEN_PRIVILEGES)NULL, 0);
252 message = SvPV_nolen(ST(1));
253 bRet = InitiateSystemShutdownA(machineName, message,
254 SvIV(ST(2)), SvIV(ST(3)), SvIV(ST(4)));
256 /* Disable shutdown privilege. */
257 tkp.Privileges[0].Attributes = 0;
258 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
259 (PTOKEN_PRIVILEGES)NULL, 0);
264 XS(w32_AbortSystemShutdown)
267 HANDLE hToken; /* handle to process token */
268 TOKEN_PRIVILEGES tkp; /* pointer to token structure */
273 croak("usage: Win32::AbortSystemShutdown($machineName);\n");
275 machineName = SvPV_nolen(ST(0));
277 if (OpenProcessToken(GetCurrentProcess(),
278 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
281 LookupPrivilegeValueA(machineName,
283 &tkp.Privileges[0].Luid);
285 tkp.PrivilegeCount = 1; /* only setting one */
286 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
288 /* Get shutdown privilege for this process. */
289 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
290 (PTOKEN_PRIVILEGES)NULL, 0);
293 bRet = AbortSystemShutdownA(machineName);
295 /* Disable shutdown privilege. */
296 tkp.Privileges[0].Attributes = 0;
297 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
298 (PTOKEN_PRIVILEGES)NULL, 0);
308 char *title = "Perl";
309 DWORD flags = MB_ICONEXCLAMATION;
312 if (items < 1 || items > 3)
313 croak("usage: Win32::MsgBox($message [, $flags [, $title]]);\n");
315 msg = SvPV_nolen(ST(0));
319 title = SvPV_nolen(ST(2));
321 result = MessageBoxA(GetActiveWindow(), msg, title, flags);
331 croak("usage: Win32::LoadLibrary($libname)\n");
332 hHandle = LoadLibraryA(SvPV_nolen(ST(0)));
333 XSRETURN_IV((long)hHandle);
341 croak("usage: Win32::FreeLibrary($handle)\n");
342 if (FreeLibrary(INT2PTR(HINSTANCE, SvIV(ST(0))))) {
348 XS(w32_GetProcAddress)
353 croak("usage: Win32::GetProcAddress($hinstance, $procname)\n");
354 XSRETURN_IV(PTR2IV(GetProcAddress(INT2PTR(HINSTANCE, SvIV(ST(0))), SvPV_nolen(ST(1)))));
357 XS(w32_RegisterServer)
364 croak("usage: Win32::RegisterServer($libname)\n");
366 hnd = LoadLibraryA(SvPV_nolen(ST(0)));
368 PFNDllRegisterServer func;
369 func = (PFNDllRegisterServer)GetProcAddress(hnd, "DllRegisterServer");
370 if (func && func() == 0)
374 ST(0) = boolSV(result);
378 XS(w32_UnregisterServer)
385 croak("usage: Win32::UnregisterServer($libname)\n");
387 hnd = LoadLibraryA(SvPV_nolen(ST(0)));
389 PFNDllUnregisterServer func;
390 func = (PFNDllUnregisterServer)GetProcAddress(hnd, "DllUnregisterServer");
391 if (func && func() == 0)
395 ST(0) = boolSV(result);
399 /* XXX rather bogus */
403 XSRETURN_PV(getenv("PROCESSOR_ARCHITECTURE"));
411 Zero(&sysinfo,1,SYSTEM_INFO);
412 GetSystemInfo(&sysinfo);
413 /* XXX docs say dwProcessorType is deprecated on NT */
414 XSRETURN_IV(sysinfo.dwProcessorType);
421 char szGUID[50] = {'\0'};
422 HRESULT hr = CoCreateGuid(&guid);
425 LPOLESTR pStr = NULL;
426 if (SUCCEEDED(StringFromCLSID(&guid, &pStr))) {
427 WideCharToMultiByte(CP_ACP, 0, pStr, wcslen(pStr), szGUID,
428 sizeof(szGUID), NULL, NULL);
436 XS(w32_GetFolderPath)
439 char path[MAX_PATH+1];
444 if (items != 1 && items != 2)
445 croak("usage: Win32::GetFolderPath($csidl [, $create])\n");
447 folder = SvIV(ST(0));
449 create = SvTRUE(ST(1)) ? CSIDL_FLAG_CREATE : 0;
451 module = LoadLibrary("shfolder.dll");
453 PFNSHGetFolderPath pfn;
454 pfn = (PFNSHGetFolderPath)GetProcAddress(module, "SHGetFolderPathA");
455 if (pfn && SUCCEEDED(pfn(NULL, folder|create, NULL, 0, path))) {
462 module = LoadLibrary("shell32.dll");
464 PFNSHGetSpecialFolderPath pfn;
465 pfn = (PFNSHGetSpecialFolderPath)
466 GetProcAddress(module, "SHGetSpecialFolderPathA");
467 if (pfn && pfn(NULL, path, folder, !!create)) {
476 XS(w32_GetFileVersion)
485 croak("usage: Win32::GetFileVersion($filename)\n");
487 filename = SvPV_nolen(ST(0));
488 size = GetFileVersionInfoSize(filename, &handle);
492 New(0, data, size, char);
496 if (GetFileVersionInfo(filename, handle, size, data)) {
497 VS_FIXEDFILEINFO *info;
499 if (VerQueryValue(data, "\\", (void**)&info, &len)) {
500 int dwValueMS1 = (info->dwFileVersionMS>>16);
501 int dwValueMS2 = (info->dwFileVersionMS&0xffff);
502 int dwValueLS1 = (info->dwFileVersionLS>>16);
503 int dwValueLS2 = (info->dwFileVersionLS&0xffff);
505 if (GIMME_V == G_ARRAY) {
507 XST_mIV(0, dwValueMS1);
508 XST_mIV(1, dwValueMS2);
509 XST_mIV(2, dwValueLS1);
510 XST_mIV(3, dwValueLS2);
515 sprintf(version, "%d.%d.%d.%d", dwValueMS1, dwValueMS2, dwValueLS1, dwValueLS2);
530 char *file = __FILE__;
532 newXS("Win32::LookupAccountName", w32_LookupAccountName, file);
533 newXS("Win32::LookupAccountSID", w32_LookupAccountSID, file);
534 newXS("Win32::InitiateSystemShutdown", w32_InitiateSystemShutdown, file);
535 newXS("Win32::AbortSystemShutdown", w32_AbortSystemShutdown, file);
536 newXS("Win32::ExpandEnvironmentStrings", w32_ExpandEnvironmentStrings, file);
537 newXS("Win32::MsgBox", w32_MsgBox, file);
538 newXS("Win32::LoadLibrary", w32_LoadLibrary, file);
539 newXS("Win32::FreeLibrary", w32_FreeLibrary, file);
540 newXS("Win32::GetProcAddress", w32_GetProcAddress, file);
541 newXS("Win32::RegisterServer", w32_RegisterServer, file);
542 newXS("Win32::UnregisterServer", w32_UnregisterServer, file);
543 newXS("Win32::GetArchName", w32_GetArchName, file);
544 newXS("Win32::GetChipName", w32_GetChipName, file);
545 newXS("Win32::GuidGen", w32_GuidGen, file);
546 newXS("Win32::GetFolderPath", w32_GetFolderPath, file);
547 newXS("Win32::IsAdminUser", w32_IsAdminUser, file);
548 newXS("Win32::GetFileVersion", w32_GetFileVersion, file);