Commit | Line | Data |
b4ad57f4 |
1 | #include <windows.h> |
2 | |
3 | #include "EXTERN.h" |
4 | #include "perl.h" |
5 | #include "XSUB.h" |
6 | |
7 | #define SE_SHUTDOWN_NAMEA "SeShutdownPrivilege" |
8 | #define SE_SHUTDOWN_NAMEW L"SeShutdownPrivilege" |
9 | |
10 | typedef BOOL (WINAPI *PFNSHGetSpecialFolderPath)(HWND, char*, int, BOOL); |
11 | typedef HRESULT (WINAPI *PFNSHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR); |
12 | #ifndef CSIDL_FLAG_CREATE |
13 | # define CSIDL_FLAG_CREATE 0x8000 |
14 | #endif |
15 | |
16 | XS(w32_ExpandEnvironmentStrings) |
17 | { |
18 | dXSARGS; |
19 | char *lpSource; |
20 | BYTE buffer[4096]; |
21 | DWORD dwDataLen; |
22 | STRLEN n_a; |
23 | |
24 | if (items != 1) |
25 | croak("usage: Win32::ExpandEnvironmentStrings($String);\n"); |
26 | |
27 | lpSource = (char *)SvPV(ST(0), n_a); |
28 | |
29 | if (USING_WIDE()) { |
30 | WCHAR wSource[MAX_PATH+1]; |
31 | WCHAR wbuffer[4096]; |
32 | A2WHELPER(lpSource, wSource, sizeof(wSource)); |
33 | dwDataLen = ExpandEnvironmentStringsW(wSource, wbuffer, sizeof(wbuffer)/2); |
34 | W2AHELPER(wbuffer, buffer, sizeof(buffer)); |
35 | } |
36 | else |
37 | dwDataLen = ExpandEnvironmentStringsA(lpSource, (char*)buffer, sizeof(buffer)); |
38 | |
39 | XSRETURN_PV((char*)buffer); |
40 | } |
41 | |
42 | XS(w32_IsAdminUser) |
43 | { |
44 | dXSARGS; |
45 | HINSTANCE hAdvApi32; |
46 | BOOL (__stdcall *pfnOpenThreadToken)(HANDLE hThr, DWORD dwDesiredAccess, |
47 | BOOL bOpenAsSelf, PHANDLE phTok); |
48 | BOOL (__stdcall *pfnOpenProcessToken)(HANDLE hProc, DWORD dwDesiredAccess, |
49 | PHANDLE phTok); |
50 | BOOL (__stdcall *pfnGetTokenInformation)(HANDLE hTok, |
51 | TOKEN_INFORMATION_CLASS TokenInformationClass, |
52 | LPVOID lpTokInfo, DWORD dwTokInfoLen, |
53 | PDWORD pdwRetLen); |
54 | BOOL (__stdcall *pfnAllocateAndInitializeSid)( |
55 | PSID_IDENTIFIER_AUTHORITY pIdAuth, |
56 | BYTE nSubAuthCount, DWORD dwSubAuth0, |
57 | DWORD dwSubAuth1, DWORD dwSubAuth2, |
58 | DWORD dwSubAuth3, DWORD dwSubAuth4, |
59 | DWORD dwSubAuth5, DWORD dwSubAuth6, |
60 | DWORD dwSubAuth7, PSID pSid); |
61 | BOOL (__stdcall *pfnEqualSid)(PSID pSid1, PSID pSid2); |
62 | PVOID (__stdcall *pfnFreeSid)(PSID pSid); |
63 | HANDLE hTok; |
64 | DWORD dwTokInfoLen; |
65 | TOKEN_GROUPS *lpTokInfo; |
66 | SID_IDENTIFIER_AUTHORITY NtAuth = SECURITY_NT_AUTHORITY; |
67 | PSID pAdminSid; |
68 | int iRetVal; |
69 | unsigned int i; |
70 | OSVERSIONINFO osver; |
71 | |
72 | if (items) |
73 | croak("usage: Win32::IsAdminUser()"); |
74 | |
75 | /* There is no concept of "Administrator" user accounts on Win9x systems, |
76 | so just return true. */ |
77 | memset(&osver, 0, sizeof(OSVERSIONINFO)); |
78 | osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
79 | GetVersionEx(&osver); |
80 | if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) |
81 | XSRETURN_YES; |
82 | |
83 | hAdvApi32 = LoadLibrary("advapi32.dll"); |
84 | if (!hAdvApi32) { |
85 | warn("Cannot load advapi32.dll library"); |
86 | XSRETURN_UNDEF; |
87 | } |
88 | |
89 | pfnOpenThreadToken = (BOOL (__stdcall *)(HANDLE, DWORD, BOOL, PHANDLE)) |
90 | GetProcAddress(hAdvApi32, "OpenThreadToken"); |
91 | pfnOpenProcessToken = (BOOL (__stdcall *)(HANDLE, DWORD, PHANDLE)) |
92 | GetProcAddress(hAdvApi32, "OpenProcessToken"); |
93 | pfnGetTokenInformation = (BOOL (__stdcall *)(HANDLE, |
94 | TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD)) |
95 | GetProcAddress(hAdvApi32, "GetTokenInformation"); |
96 | pfnAllocateAndInitializeSid = (BOOL (__stdcall *)( |
97 | PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, |
98 | DWORD, DWORD, DWORD, PSID)) |
99 | GetProcAddress(hAdvApi32, "AllocateAndInitializeSid"); |
100 | pfnEqualSid = (BOOL (__stdcall *)(PSID, PSID)) |
101 | GetProcAddress(hAdvApi32, "EqualSid"); |
102 | pfnFreeSid = (PVOID (__stdcall *)(PSID)) |
103 | GetProcAddress(hAdvApi32, "FreeSid"); |
104 | |
105 | if (!(pfnOpenThreadToken && pfnOpenProcessToken && |
106 | pfnGetTokenInformation && pfnAllocateAndInitializeSid && |
107 | pfnEqualSid && pfnFreeSid)) |
108 | { |
109 | warn("Cannot load functions from advapi32.dll library"); |
110 | FreeLibrary(hAdvApi32); |
111 | XSRETURN_UNDEF; |
112 | } |
113 | |
114 | if (!pfnOpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hTok)) { |
115 | if (!pfnOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hTok)) { |
116 | warn("Cannot open thread token or process token"); |
117 | FreeLibrary(hAdvApi32); |
118 | XSRETURN_UNDEF; |
119 | } |
120 | } |
121 | |
122 | pfnGetTokenInformation(hTok, TokenGroups, NULL, 0, &dwTokInfoLen); |
123 | if (!New(1, lpTokInfo, dwTokInfoLen, TOKEN_GROUPS)) { |
124 | warn("Cannot allocate token information structure"); |
125 | CloseHandle(hTok); |
126 | FreeLibrary(hAdvApi32); |
127 | XSRETURN_UNDEF; |
128 | } |
129 | |
130 | if (!pfnGetTokenInformation(hTok, TokenGroups, lpTokInfo, dwTokInfoLen, |
131 | &dwTokInfoLen)) |
132 | { |
133 | warn("Cannot get token information"); |
134 | Safefree(lpTokInfo); |
135 | CloseHandle(hTok); |
136 | FreeLibrary(hAdvApi32); |
137 | XSRETURN_UNDEF; |
138 | } |
139 | |
140 | if (!pfnAllocateAndInitializeSid(&NtAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, |
141 | DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid)) |
142 | { |
143 | warn("Cannot allocate administrators' SID"); |
144 | Safefree(lpTokInfo); |
145 | CloseHandle(hTok); |
146 | FreeLibrary(hAdvApi32); |
147 | XSRETURN_UNDEF; |
148 | } |
149 | |
150 | iRetVal = 0; |
151 | for (i = 0; i < lpTokInfo->GroupCount; ++i) { |
152 | if (pfnEqualSid(lpTokInfo->Groups[i].Sid, pAdminSid)) { |
153 | iRetVal = 1; |
154 | break; |
155 | } |
156 | } |
157 | |
158 | pfnFreeSid(pAdminSid); |
159 | Safefree(lpTokInfo); |
160 | CloseHandle(hTok); |
161 | FreeLibrary(hAdvApi32); |
162 | |
163 | EXTEND(SP, 1); |
164 | ST(0) = sv_2mortal(newSViv(iRetVal)); |
165 | XSRETURN(1); |
166 | } |
167 | |
168 | XS(w32_LookupAccountName) |
169 | { |
170 | dXSARGS; |
171 | char SID[400]; |
172 | DWORD SIDLen; |
173 | SID_NAME_USE snu; |
174 | char Domain[256]; |
175 | DWORD DomLen; |
176 | STRLEN n_a; |
177 | BOOL bResult; |
178 | |
179 | if (items != 5) |
180 | croak("usage: Win32::LookupAccountName($system, $account, $domain, " |
181 | "$sid, $sidtype);\n"); |
182 | |
183 | SIDLen = sizeof(SID); |
184 | DomLen = sizeof(Domain); |
185 | |
186 | if (USING_WIDE()) { |
187 | WCHAR wSID[sizeof(SID)]; |
188 | WCHAR wDomain[sizeof(Domain)]; |
189 | WCHAR wSystem[MAX_PATH+1]; |
190 | WCHAR wAccount[MAX_PATH+1]; |
191 | A2WHELPER(SvPV(ST(0),n_a), wSystem, sizeof(wSystem)); |
192 | A2WHELPER(SvPV(ST(1),n_a), wAccount, sizeof(wAccount)); |
193 | bResult = LookupAccountNameW(wSystem, /* System */ |
194 | wAccount, /* Account name */ |
195 | &wSID, /* SID structure */ |
196 | &SIDLen, /* Size of SID buffer */ |
197 | wDomain, /* Domain buffer */ |
198 | &DomLen, /* Domain buffer size */ |
199 | &snu); /* SID name type */ |
200 | if (bResult) { |
201 | W2AHELPER(wSID, SID, SIDLen); |
202 | W2AHELPER(wDomain, Domain, DomLen); |
203 | } |
204 | } |
205 | else |
206 | bResult = LookupAccountNameA(SvPV(ST(0),n_a), /* System */ |
207 | SvPV(ST(1),n_a), /* Account name */ |
208 | &SID, /* SID structure */ |
209 | &SIDLen, /* Size of SID buffer */ |
210 | Domain, /* Domain buffer */ |
211 | &DomLen, /* Domain buffer size */ |
212 | &snu); /* SID name type */ |
213 | if (bResult) { |
214 | sv_setpv(ST(2), Domain); |
215 | sv_setpvn(ST(3), SID, SIDLen); |
216 | sv_setiv(ST(4), snu); |
217 | XSRETURN_YES; |
218 | } |
219 | else { |
220 | GetLastError(); |
221 | XSRETURN_NO; |
222 | } |
223 | } /* NTLookupAccountName */ |
224 | |
225 | |
226 | XS(w32_LookupAccountSID) |
227 | { |
228 | dXSARGS; |
229 | PSID sid; |
230 | char Account[256]; |
231 | DWORD AcctLen = sizeof(Account); |
232 | char Domain[256]; |
233 | DWORD DomLen = sizeof(Domain); |
234 | SID_NAME_USE snu; |
235 | long retval; |
236 | STRLEN n_a; |
237 | BOOL bResult; |
238 | |
239 | if (items != 5) |
240 | croak("usage: Win32::LookupAccountSID($system, $sid, $account, $domain, $sidtype);\n"); |
241 | |
242 | sid = SvPV(ST(1), n_a); |
243 | if (IsValidSid(sid)) { |
244 | if (USING_WIDE()) { |
245 | WCHAR wSID[sizeof(SID)]; |
246 | WCHAR wDomain[sizeof(Domain)]; |
247 | WCHAR wSystem[MAX_PATH+1]; |
248 | WCHAR wAccount[sizeof(Account)]; |
249 | A2WHELPER(SvPV(ST(0),n_a), wSystem, sizeof(wSystem)); |
250 | |
251 | bResult = LookupAccountSidW(wSystem, /* System */ |
252 | sid, /* SID structure */ |
253 | wAccount, /* Account name buffer */ |
254 | &AcctLen, /* name buffer length */ |
255 | wDomain, /* Domain buffer */ |
256 | &DomLen, /* Domain buffer length */ |
257 | &snu); /* SID name type */ |
258 | if (bResult) { |
259 | W2AHELPER(wAccount, Account, AcctLen); |
260 | W2AHELPER(wDomain, Domain, DomLen); |
261 | } |
262 | } |
263 | else |
264 | bResult = LookupAccountSidA(SvPV(ST(0),n_a), /* System */ |
265 | sid, /* SID structure */ |
266 | Account, /* Account name buffer */ |
267 | &AcctLen, /* name buffer length */ |
268 | Domain, /* Domain buffer */ |
269 | &DomLen, /* Domain buffer length */ |
270 | &snu); /* SID name type */ |
271 | if (bResult) { |
272 | sv_setpv(ST(2), Account); |
273 | sv_setpv(ST(3), Domain); |
274 | sv_setiv(ST(4), (IV)snu); |
275 | XSRETURN_YES; |
276 | } |
277 | else { |
278 | GetLastError(); |
279 | XSRETURN_NO; |
280 | } |
281 | } |
282 | else { |
283 | GetLastError(); |
284 | XSRETURN_NO; |
285 | } |
286 | } /* NTLookupAccountSID */ |
287 | |
288 | XS(w32_InitiateSystemShutdown) |
289 | { |
290 | dXSARGS; |
291 | HANDLE hToken; /* handle to process token */ |
292 | TOKEN_PRIVILEGES tkp; /* pointer to token structure */ |
293 | BOOL bRet; |
294 | WCHAR wbuffer[MAX_PATH+1]; |
295 | char *machineName, *message; |
296 | STRLEN n_a; |
297 | |
298 | if (items != 5) |
299 | croak("usage: Win32::InitiateSystemShutdown($machineName, $message, " |
300 | "$timeOut, $forceClose, $reboot);\n"); |
301 | |
302 | machineName = SvPV(ST(0), n_a); |
303 | if (USING_WIDE()) { |
304 | A2WHELPER(machineName, wbuffer, sizeof(wbuffer)); |
305 | } |
306 | |
307 | if (OpenProcessToken(GetCurrentProcess(), |
308 | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, |
309 | &hToken)) |
310 | { |
311 | if (USING_WIDE()) |
312 | LookupPrivilegeValueW(wbuffer, |
313 | SE_SHUTDOWN_NAMEW, |
314 | &tkp.Privileges[0].Luid); |
315 | else |
316 | LookupPrivilegeValueA(machineName, |
317 | SE_SHUTDOWN_NAMEA, |
318 | &tkp.Privileges[0].Luid); |
319 | |
320 | tkp.PrivilegeCount = 1; /* only setting one */ |
321 | tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
322 | |
323 | /* Get shutdown privilege for this process. */ |
324 | AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, |
325 | (PTOKEN_PRIVILEGES)NULL, 0); |
326 | } |
327 | |
328 | message = SvPV(ST(1), n_a); |
329 | if (USING_WIDE()) { |
330 | WCHAR* pWBuf; |
331 | int length = strlen(message)+1; |
332 | New(0, pWBuf, length, WCHAR); |
333 | A2WHELPER(message, pWBuf, length*sizeof(WCHAR)); |
334 | bRet = InitiateSystemShutdownW(wbuffer, pWBuf, |
335 | SvIV(ST(2)), SvIV(ST(3)), SvIV(ST(4))); |
336 | Safefree(pWBuf); |
337 | } |
338 | else |
339 | bRet = InitiateSystemShutdownA(machineName, message, |
340 | SvIV(ST(2)), SvIV(ST(3)), SvIV(ST(4))); |
341 | |
342 | /* Disable shutdown privilege. */ |
343 | tkp.Privileges[0].Attributes = 0; |
344 | AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, |
345 | (PTOKEN_PRIVILEGES)NULL, 0); |
346 | CloseHandle(hToken); |
347 | XSRETURN_IV(bRet); |
348 | } |
349 | |
350 | XS(w32_AbortSystemShutdown) |
351 | { |
352 | dXSARGS; |
353 | HANDLE hToken; /* handle to process token */ |
354 | TOKEN_PRIVILEGES tkp; /* pointer to token structure */ |
355 | BOOL bRet; |
356 | char *machineName; |
357 | STRLEN n_a; |
358 | WCHAR wbuffer[MAX_PATH+1]; |
359 | |
360 | if (items != 1) |
361 | croak("usage: Win32::AbortSystemShutdown($machineName);\n"); |
362 | |
363 | machineName = SvPV(ST(0), n_a); |
364 | if (USING_WIDE()) { |
365 | A2WHELPER(machineName, wbuffer, sizeof(wbuffer)); |
366 | } |
367 | |
368 | if (OpenProcessToken(GetCurrentProcess(), |
369 | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, |
370 | &hToken)) |
371 | { |
372 | if (USING_WIDE()) |
373 | LookupPrivilegeValueW(wbuffer, |
374 | SE_SHUTDOWN_NAMEW, |
375 | &tkp.Privileges[0].Luid); |
376 | else |
377 | LookupPrivilegeValueA(machineName, |
378 | SE_SHUTDOWN_NAMEA, |
379 | &tkp.Privileges[0].Luid); |
380 | |
381 | tkp.PrivilegeCount = 1; /* only setting one */ |
382 | tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
383 | |
384 | /* Get shutdown privilege for this process. */ |
385 | AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, |
386 | (PTOKEN_PRIVILEGES)NULL, 0); |
387 | } |
388 | |
389 | if (USING_WIDE()) { |
390 | bRet = AbortSystemShutdownW(wbuffer); |
391 | } |
392 | else |
393 | bRet = AbortSystemShutdownA(machineName); |
394 | |
395 | /* Disable shutdown privilege. */ |
396 | tkp.Privileges[0].Attributes = 0; |
397 | AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, |
398 | (PTOKEN_PRIVILEGES)NULL, 0); |
399 | CloseHandle(hToken); |
400 | XSRETURN_IV(bRet); |
401 | } |
402 | |
403 | |
404 | XS(w32_MsgBox) |
405 | { |
406 | dXSARGS; |
407 | char *msg; |
408 | char *title = "Perl"; |
409 | DWORD flags = MB_ICONEXCLAMATION; |
410 | STRLEN n_a; |
411 | I32 result; |
412 | |
413 | if (items < 1 || items > 3) |
414 | croak("usage: Win32::MsgBox($message [, $flags [, $title]]);\n"); |
415 | |
416 | msg = SvPV(ST(0), n_a); |
417 | if (items > 1) { |
418 | flags = SvIV(ST(1)); |
419 | if (items > 2) |
420 | title = SvPV(ST(2), n_a); |
421 | } |
422 | if (USING_WIDE()) { |
423 | WCHAR* pMsg; |
424 | WCHAR* pTitle; |
425 | int length; |
426 | length = strlen(msg)+1; |
427 | New(0, pMsg, length, WCHAR); |
428 | A2WHELPER(msg, pMsg, length*sizeof(WCHAR)); |
429 | length = strlen(title)+1; |
430 | New(0, pTitle, length, WCHAR); |
431 | A2WHELPER(title, pTitle, length*sizeof(WCHAR)); |
432 | result = MessageBoxW(GetActiveWindow(), pMsg, pTitle, flags); |
433 | Safefree(pMsg); |
434 | Safefree(pTitle); |
435 | } |
436 | else |
437 | result = MessageBoxA(GetActiveWindow(), msg, title, flags); |
438 | |
439 | XSRETURN_IV(result); |
440 | } |
441 | |
442 | XS(w32_LoadLibrary) |
443 | { |
444 | dXSARGS; |
445 | STRLEN n_a; |
446 | HANDLE hHandle; |
447 | char* lpName; |
448 | |
449 | if (items != 1) |
450 | croak("usage: Win32::LoadLibrary($libname)\n"); |
451 | lpName = (char *)SvPV(ST(0),n_a); |
452 | if (USING_WIDE()) { |
453 | WCHAR wbuffer[MAX_PATH+1]; |
454 | A2WHELPER(lpName, wbuffer, sizeof(wbuffer)); |
455 | hHandle = LoadLibraryW(wbuffer); |
456 | } |
457 | else |
458 | hHandle = LoadLibraryA(lpName); |
459 | XSRETURN_IV((long)hHandle); |
460 | } |
461 | |
462 | XS(w32_FreeLibrary) |
463 | { |
464 | dXSARGS; |
465 | if (items != 1) |
466 | croak("usage: Win32::FreeLibrary($handle)\n"); |
467 | if (FreeLibrary((HINSTANCE) SvIV(ST(0)))) { |
468 | XSRETURN_YES; |
469 | } |
470 | XSRETURN_NO; |
471 | } |
472 | |
473 | XS(w32_GetProcAddress) |
474 | { |
475 | dXSARGS; |
476 | STRLEN n_a; |
477 | if (items != 2) |
478 | croak("usage: Win32::GetProcAddress($hinstance, $procname)\n"); |
479 | XSRETURN_IV((long)GetProcAddress((HINSTANCE)SvIV(ST(0)), SvPV(ST(1), n_a))); |
480 | } |
481 | |
482 | XS(w32_RegisterServer) |
483 | { |
484 | dXSARGS; |
485 | BOOL result = FALSE; |
486 | HINSTANCE hnd; |
487 | FARPROC func; |
488 | STRLEN n_a; |
489 | char* lpName; |
490 | |
491 | if (items != 1) |
492 | croak("usage: Win32::RegisterServer($libname)\n"); |
493 | |
494 | lpName = SvPV(ST(0),n_a); |
495 | if (USING_WIDE()) { |
496 | WCHAR wbuffer[MAX_PATH+1]; |
497 | A2WHELPER(lpName, wbuffer, sizeof(wbuffer)); |
498 | hnd = LoadLibraryW(wbuffer); |
499 | } |
500 | else |
501 | hnd = LoadLibraryA(lpName); |
502 | |
503 | if (hnd) { |
504 | func = GetProcAddress(hnd, "DllRegisterServer"); |
505 | if (func && func() == 0) |
506 | result = TRUE; |
507 | FreeLibrary(hnd); |
508 | } |
509 | if (result) |
510 | XSRETURN_YES; |
511 | else |
512 | XSRETURN_NO; |
513 | } |
514 | |
515 | XS(w32_UnregisterServer) |
516 | { |
517 | dXSARGS; |
518 | BOOL result = FALSE; |
519 | HINSTANCE hnd; |
520 | FARPROC func; |
521 | STRLEN n_a; |
522 | char* lpName; |
523 | |
524 | if (items != 1) |
525 | croak("usage: Win32::UnregisterServer($libname)\n"); |
526 | |
527 | lpName = SvPV(ST(0),n_a); |
528 | if (USING_WIDE()) { |
529 | WCHAR wbuffer[MAX_PATH+1]; |
530 | A2WHELPER(lpName, wbuffer, sizeof(wbuffer)); |
531 | hnd = LoadLibraryW(wbuffer); |
532 | } |
533 | else |
534 | hnd = LoadLibraryA(lpName); |
535 | |
536 | if (hnd) { |
537 | func = GetProcAddress(hnd, "DllUnregisterServer"); |
538 | if (func && func() == 0) |
539 | result = TRUE; |
540 | FreeLibrary(hnd); |
541 | } |
542 | if (result) |
543 | XSRETURN_YES; |
544 | else |
545 | XSRETURN_NO; |
546 | } |
547 | |
548 | /* XXX rather bogus */ |
549 | XS(w32_GetArchName) |
550 | { |
551 | dXSARGS; |
552 | XSRETURN_PV(getenv("PROCESSOR_ARCHITECTURE")); |
553 | } |
554 | |
555 | XS(w32_GetChipName) |
556 | { |
557 | dXSARGS; |
558 | SYSTEM_INFO sysinfo; |
559 | |
560 | Zero(&sysinfo,1,SYSTEM_INFO); |
561 | GetSystemInfo(&sysinfo); |
562 | /* XXX docs say dwProcessorType is deprecated on NT */ |
563 | XSRETURN_IV(sysinfo.dwProcessorType); |
564 | } |
565 | |
566 | XS(w32_GuidGen) |
567 | { |
568 | dXSARGS; |
569 | GUID guid; |
570 | char szGUID[50] = {'\0'}; |
571 | HRESULT hr = CoCreateGuid(&guid); |
572 | |
573 | if (SUCCEEDED(hr)) { |
574 | LPOLESTR pStr = NULL; |
575 | StringFromCLSID(&guid, &pStr); |
576 | WideCharToMultiByte(CP_ACP, 0, pStr, wcslen(pStr), szGUID, |
577 | sizeof(szGUID), NULL, NULL); |
578 | |
579 | XSRETURN_PV(szGUID); |
580 | } |
581 | else |
582 | XSRETURN_UNDEF; |
583 | } |
584 | |
585 | XS(w32_GetFolderPath) |
586 | { |
587 | dXSARGS; |
588 | char path[MAX_PATH+1]; |
589 | int folder; |
590 | int create = 0; |
591 | HMODULE module; |
592 | |
593 | if (items != 1 && items != 2) |
594 | croak("usage: Win32::GetFolderPath($csidl [, $create])\n"); |
595 | |
596 | folder = SvIV(ST(0)); |
597 | if (items == 2) |
598 | create = SvTRUE(ST(1)) ? CSIDL_FLAG_CREATE : 0; |
599 | |
600 | /* We are not bothering with USING_WIDE() anymore, |
601 | * because this is not how Unicode works with Perl. |
602 | * Nobody seems to use "perl -C" anyways. |
603 | */ |
604 | module = LoadLibrary("shfolder.dll"); |
605 | if (module) { |
606 | PFNSHGetFolderPath pfn; |
607 | pfn = (PFNSHGetFolderPath)GetProcAddress(module, "SHGetFolderPathA"); |
608 | if (pfn && SUCCEEDED(pfn(NULL, folder|create, NULL, 0, path))) { |
609 | FreeLibrary(module); |
610 | XSRETURN_PV(path); |
611 | } |
612 | FreeLibrary(module); |
613 | } |
614 | |
615 | module = LoadLibrary("shell32.dll"); |
616 | if (module) { |
617 | PFNSHGetSpecialFolderPath pfn; |
618 | pfn = (PFNSHGetSpecialFolderPath) |
619 | GetProcAddress(module, "SHGetSpecialFolderPathA"); |
620 | if (pfn && pfn(NULL, path, folder, !!create)) { |
621 | FreeLibrary(module); |
622 | XSRETURN_PV(path); |
623 | } |
624 | FreeLibrary(module); |
625 | } |
626 | XSRETURN_UNDEF; |
627 | } |
628 | |
629 | XS(boot_Win32) |
630 | { |
631 | dXSARGS; |
632 | char *file = __FILE__; |
633 | |
634 | newXS("Win32::LookupAccountName", w32_LookupAccountName, file); |
635 | newXS("Win32::LookupAccountSID", w32_LookupAccountSID, file); |
636 | newXS("Win32::InitiateSystemShutdown", w32_InitiateSystemShutdown, file); |
637 | newXS("Win32::AbortSystemShutdown", w32_AbortSystemShutdown, file); |
638 | newXS("Win32::ExpandEnvironmentStrings", w32_ExpandEnvironmentStrings, file); |
639 | newXS("Win32::MsgBox", w32_MsgBox, file); |
640 | newXS("Win32::LoadLibrary", w32_LoadLibrary, file); |
641 | newXS("Win32::FreeLibrary", w32_FreeLibrary, file); |
642 | newXS("Win32::GetProcAddress", w32_GetProcAddress, file); |
643 | newXS("Win32::RegisterServer", w32_RegisterServer, file); |
644 | newXS("Win32::UnregisterServer", w32_UnregisterServer, file); |
645 | newXS("Win32::GetArchName", w32_GetArchName, file); |
646 | newXS("Win32::GetChipName", w32_GetChipName, file); |
647 | newXS("Win32::GuidGen", w32_GuidGen, file); |
648 | newXS("Win32::GetFolderPath", w32_GetFolderPath, file); |
649 | newXS("Win32::IsAdminUser", w32_IsAdminUser, file); |
650 | |
651 | XSRETURN_YES; |
652 | } |