Re: [PATCH] Re: [perl #34650] perldoc -f my should perhaps mention BEGIN and END
[p5sagit/p5-mst-13.2.git] / win32 / ext / Win32 / Win32.xs
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 }