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 #ifndef CSIDL_FLAG_CREATE
12 # define CSIDL_FLAG_CREATE 0x8000
15 XS(w32_ExpandEnvironmentStrings)
21 croak("usage: Win32::ExpandEnvironmentStrings($String);\n");
23 ExpandEnvironmentStringsA(SvPV_nolen(ST(0)), (char*)buffer, sizeof(buffer));
24 XSRETURN_PV((char*)buffer);
31 BOOL (__stdcall *pfnOpenThreadToken)(HANDLE hThr, DWORD dwDesiredAccess,
32 BOOL bOpenAsSelf, PHANDLE phTok);
33 BOOL (__stdcall *pfnOpenProcessToken)(HANDLE hProc, DWORD dwDesiredAccess,
35 BOOL (__stdcall *pfnGetTokenInformation)(HANDLE hTok,
36 TOKEN_INFORMATION_CLASS TokenInformationClass,
37 LPVOID lpTokInfo, DWORD dwTokInfoLen,
39 BOOL (__stdcall *pfnAllocateAndInitializeSid)(
40 PSID_IDENTIFIER_AUTHORITY pIdAuth,
41 BYTE nSubAuthCount, DWORD dwSubAuth0,
42 DWORD dwSubAuth1, DWORD dwSubAuth2,
43 DWORD dwSubAuth3, DWORD dwSubAuth4,
44 DWORD dwSubAuth5, DWORD dwSubAuth6,
45 DWORD dwSubAuth7, PSID pSid);
46 BOOL (__stdcall *pfnEqualSid)(PSID pSid1, PSID pSid2);
47 PVOID (__stdcall *pfnFreeSid)(PSID pSid);
50 TOKEN_GROUPS *lpTokInfo;
51 SID_IDENTIFIER_AUTHORITY NtAuth = SECURITY_NT_AUTHORITY;
58 croak("usage: Win32::IsAdminUser()");
60 /* There is no concept of "Administrator" user accounts on Win9x systems,
61 so just return true. */
62 memset(&osver, 0, sizeof(OSVERSIONINFO));
63 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
65 if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
68 hAdvApi32 = LoadLibrary("advapi32.dll");
70 warn("Cannot load advapi32.dll library");
74 pfnOpenThreadToken = (BOOL (__stdcall *)(HANDLE, DWORD, BOOL, PHANDLE))
75 GetProcAddress(hAdvApi32, "OpenThreadToken");
76 pfnOpenProcessToken = (BOOL (__stdcall *)(HANDLE, DWORD, PHANDLE))
77 GetProcAddress(hAdvApi32, "OpenProcessToken");
78 pfnGetTokenInformation = (BOOL (__stdcall *)(HANDLE,
79 TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD))
80 GetProcAddress(hAdvApi32, "GetTokenInformation");
81 pfnAllocateAndInitializeSid = (BOOL (__stdcall *)(
82 PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD,
83 DWORD, DWORD, DWORD, PSID))
84 GetProcAddress(hAdvApi32, "AllocateAndInitializeSid");
85 pfnEqualSid = (BOOL (__stdcall *)(PSID, PSID))
86 GetProcAddress(hAdvApi32, "EqualSid");
87 pfnFreeSid = (PVOID (__stdcall *)(PSID))
88 GetProcAddress(hAdvApi32, "FreeSid");
90 if (!(pfnOpenThreadToken && pfnOpenProcessToken &&
91 pfnGetTokenInformation && pfnAllocateAndInitializeSid &&
92 pfnEqualSid && pfnFreeSid))
94 warn("Cannot load functions from advapi32.dll library");
95 FreeLibrary(hAdvApi32);
99 if (!pfnOpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hTok)) {
100 if (!pfnOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hTok)) {
101 warn("Cannot open thread token or process token");
102 FreeLibrary(hAdvApi32);
107 pfnGetTokenInformation(hTok, TokenGroups, NULL, 0, &dwTokInfoLen);
108 if (!New(1, lpTokInfo, dwTokInfoLen, TOKEN_GROUPS)) {
109 warn("Cannot allocate token information structure");
111 FreeLibrary(hAdvApi32);
115 if (!pfnGetTokenInformation(hTok, TokenGroups, lpTokInfo, dwTokInfoLen,
118 warn("Cannot get token information");
121 FreeLibrary(hAdvApi32);
125 if (!pfnAllocateAndInitializeSid(&NtAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
126 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid))
128 warn("Cannot allocate administrators' SID");
131 FreeLibrary(hAdvApi32);
136 for (i = 0; i < lpTokInfo->GroupCount; ++i) {
137 if (pfnEqualSid(lpTokInfo->Groups[i].Sid, pAdminSid)) {
143 pfnFreeSid(pAdminSid);
146 FreeLibrary(hAdvApi32);
149 ST(0) = sv_2mortal(newSViv(iRetVal));
153 XS(w32_LookupAccountName)
164 croak("usage: Win32::LookupAccountName($system, $account, $domain, "
165 "$sid, $sidtype);\n");
167 SIDLen = sizeof(SID);
168 DomLen = sizeof(Domain);
170 bResult = LookupAccountNameA(SvPV_nolen(ST(0)), /* System */
171 SvPV_nolen(ST(1)), /* Account name */
172 &SID, /* SID structure */
173 &SIDLen, /* Size of SID buffer */
174 Domain, /* Domain buffer */
175 &DomLen, /* Domain buffer size */
176 &snu); /* SID name type */
178 sv_setpv(ST(2), Domain);
179 sv_setpvn(ST(3), SID, SIDLen);
180 sv_setiv(ST(4), snu);
187 XS(w32_LookupAccountSID)
192 DWORD AcctLen = sizeof(Account);
194 DWORD DomLen = sizeof(Domain);
199 croak("usage: Win32::LookupAccountSID($system, $sid, $account, $domain, $sidtype);\n");
201 sid = SvPV_nolen(ST(1));
202 if (IsValidSid(sid)) {
203 bResult = LookupAccountSidA(SvPV_nolen(ST(0)), /* System */
204 sid, /* SID structure */
205 Account, /* Account name buffer */
206 &AcctLen, /* name buffer length */
207 Domain, /* Domain buffer */
208 &DomLen, /* Domain buffer length */
209 &snu); /* SID name type */
211 sv_setpv(ST(2), Account);
212 sv_setpv(ST(3), Domain);
213 sv_setiv(ST(4), (IV)snu);
220 XS(w32_InitiateSystemShutdown)
223 HANDLE hToken; /* handle to process token */
224 TOKEN_PRIVILEGES tkp; /* pointer to token structure */
226 char *machineName, *message;
229 croak("usage: Win32::InitiateSystemShutdown($machineName, $message, "
230 "$timeOut, $forceClose, $reboot);\n");
232 machineName = SvPV_nolen(ST(0));
234 if (OpenProcessToken(GetCurrentProcess(),
235 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
238 LookupPrivilegeValueA(machineName,
240 &tkp.Privileges[0].Luid);
242 tkp.PrivilegeCount = 1; /* only setting one */
243 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
245 /* Get shutdown privilege for this process. */
246 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
247 (PTOKEN_PRIVILEGES)NULL, 0);
250 message = SvPV_nolen(ST(1));
251 bRet = InitiateSystemShutdownA(machineName, message,
252 SvIV(ST(2)), SvIV(ST(3)), SvIV(ST(4)));
254 /* Disable shutdown privilege. */
255 tkp.Privileges[0].Attributes = 0;
256 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
257 (PTOKEN_PRIVILEGES)NULL, 0);
262 XS(w32_AbortSystemShutdown)
265 HANDLE hToken; /* handle to process token */
266 TOKEN_PRIVILEGES tkp; /* pointer to token structure */
271 croak("usage: Win32::AbortSystemShutdown($machineName);\n");
273 machineName = SvPV_nolen(ST(0));
275 if (OpenProcessToken(GetCurrentProcess(),
276 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
279 LookupPrivilegeValueA(machineName,
281 &tkp.Privileges[0].Luid);
283 tkp.PrivilegeCount = 1; /* only setting one */
284 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
286 /* Get shutdown privilege for this process. */
287 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
288 (PTOKEN_PRIVILEGES)NULL, 0);
291 bRet = AbortSystemShutdownA(machineName);
293 /* Disable shutdown privilege. */
294 tkp.Privileges[0].Attributes = 0;
295 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
296 (PTOKEN_PRIVILEGES)NULL, 0);
306 char *title = "Perl";
307 DWORD flags = MB_ICONEXCLAMATION;
310 if (items < 1 || items > 3)
311 croak("usage: Win32::MsgBox($message [, $flags [, $title]]);\n");
313 msg = SvPV_nolen(ST(0));
317 title = SvPV_nolen(ST(2));
319 result = MessageBoxA(GetActiveWindow(), msg, title, flags);
329 croak("usage: Win32::LoadLibrary($libname)\n");
330 hHandle = LoadLibraryA(SvPV_nolen(ST(0)));
331 XSRETURN_IV((long)hHandle);
339 croak("usage: Win32::FreeLibrary($handle)\n");
340 if (FreeLibrary(INT2PTR(HINSTANCE, SvIV(ST(0))))) {
346 XS(w32_GetProcAddress)
351 croak("usage: Win32::GetProcAddress($hinstance, $procname)\n");
352 XSRETURN_IV(PTR2IV(GetProcAddress(INT2PTR(HINSTANCE, SvIV(ST(0))), SvPV_nolen(ST(1)))));
355 XS(w32_RegisterServer)
363 croak("usage: Win32::RegisterServer($libname)\n");
365 hnd = LoadLibraryA(SvPV_nolen(ST(0)));
367 func = GetProcAddress(hnd, "DllRegisterServer");
368 if (func && func() == 0)
372 ST(0) = boolSV(result);
376 XS(w32_UnregisterServer)
384 croak("usage: Win32::UnregisterServer($libname)\n");
386 hnd = LoadLibraryA(SvPV_nolen(ST(0)));
388 func = GetProcAddress(hnd, "DllUnregisterServer");
389 if (func && func() == 0)
393 ST(0) = boolSV(result);
397 /* XXX rather bogus */
401 XSRETURN_PV(getenv("PROCESSOR_ARCHITECTURE"));
409 Zero(&sysinfo,1,SYSTEM_INFO);
410 GetSystemInfo(&sysinfo);
411 /* XXX docs say dwProcessorType is deprecated on NT */
412 XSRETURN_IV(sysinfo.dwProcessorType);
419 char szGUID[50] = {'\0'};
420 HRESULT hr = CoCreateGuid(&guid);
423 LPOLESTR pStr = NULL;
424 if (SUCCEEDED(StringFromCLSID(&guid, &pStr))) {
425 WideCharToMultiByte(CP_ACP, 0, pStr, wcslen(pStr), szGUID,
426 sizeof(szGUID), NULL, NULL);
434 XS(w32_GetFolderPath)
437 char path[MAX_PATH+1];
442 if (items != 1 && items != 2)
443 croak("usage: Win32::GetFolderPath($csidl [, $create])\n");
445 folder = SvIV(ST(0));
447 create = SvTRUE(ST(1)) ? CSIDL_FLAG_CREATE : 0;
449 module = LoadLibrary("shfolder.dll");
451 PFNSHGetFolderPath pfn;
452 pfn = (PFNSHGetFolderPath)GetProcAddress(module, "SHGetFolderPathA");
453 if (pfn && SUCCEEDED(pfn(NULL, folder|create, NULL, 0, path))) {
460 module = LoadLibrary("shell32.dll");
462 PFNSHGetSpecialFolderPath pfn;
463 pfn = (PFNSHGetSpecialFolderPath)
464 GetProcAddress(module, "SHGetSpecialFolderPathA");
465 if (pfn && pfn(NULL, path, folder, !!create)) {
474 XS(w32_GetFileVersion)
483 croak("usage: Win32::GetFileVersion($filename)\n");
485 filename = SvPV_nolen(ST(0));
486 size = GetFileVersionInfoSize(filename, &handle);
490 New(0, data, size, char);
494 if (GetFileVersionInfo(filename, handle, size, data)) {
495 VS_FIXEDFILEINFO *info;
497 if (VerQueryValue(data, "\\", (void**)&info, &len)) {
498 int dwValueMS1 = (info->dwFileVersionMS>>16);
499 int dwValueMS2 = (info->dwFileVersionMS&0xffff);
500 int dwValueLS1 = (info->dwFileVersionLS>>16);
501 int dwValueLS2 = (info->dwFileVersionLS&0xffff);
503 if (GIMME_V == G_ARRAY) {
505 XST_mIV(0, dwValueMS1);
506 XST_mIV(1, dwValueMS2);
507 XST_mIV(2, dwValueLS1);
508 XST_mIV(3, dwValueLS2);
513 sprintf(version, "%d.%d.%d.%d", dwValueMS1, dwValueMS2, dwValueLS1, dwValueLS2);
528 char *file = __FILE__;
530 newXS("Win32::LookupAccountName", w32_LookupAccountName, file);
531 newXS("Win32::LookupAccountSID", w32_LookupAccountSID, file);
532 newXS("Win32::InitiateSystemShutdown", w32_InitiateSystemShutdown, file);
533 newXS("Win32::AbortSystemShutdown", w32_AbortSystemShutdown, file);
534 newXS("Win32::ExpandEnvironmentStrings", w32_ExpandEnvironmentStrings, file);
535 newXS("Win32::MsgBox", w32_MsgBox, file);
536 newXS("Win32::LoadLibrary", w32_LoadLibrary, file);
537 newXS("Win32::FreeLibrary", w32_FreeLibrary, file);
538 newXS("Win32::GetProcAddress", w32_GetProcAddress, file);
539 newXS("Win32::RegisterServer", w32_RegisterServer, file);
540 newXS("Win32::UnregisterServer", w32_UnregisterServer, file);
541 newXS("Win32::GetArchName", w32_GetArchName, file);
542 newXS("Win32::GetChipName", w32_GetChipName, file);
543 newXS("Win32::GuidGen", w32_GuidGen, file);
544 newXS("Win32::GetFolderPath", w32_GetFolderPath, file);
545 newXS("Win32::IsAdminUser", w32_IsAdminUser, file);
546 newXS("Win32::GetFileVersion", w32_GetFileVersion, file);