5 #define PERL_NO_GET_CONTEXT
11 # define countof(array) (sizeof (array) / sizeof (*(array)))
14 #define SE_SHUTDOWN_NAMEA "SeShutdownPrivilege"
16 #ifndef WC_NO_BEST_FIT_CHARS
17 # define WC_NO_BEST_FIT_CHARS 0x00000400
20 #define GETPROC(fn) pfn##fn = (PFN##fn)GetProcAddress(module, #fn)
22 typedef BOOL (WINAPI *PFNSHGetSpecialFolderPathA)(HWND, char*, int, BOOL);
23 typedef BOOL (WINAPI *PFNSHGetSpecialFolderPathW)(HWND, WCHAR*, int, BOOL);
24 typedef HRESULT (WINAPI *PFNSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPTSTR);
25 typedef HRESULT (WINAPI *PFNSHGetFolderPathW)(HWND, int, HANDLE, DWORD, LPWSTR);
26 typedef BOOL (WINAPI *PFNCreateEnvironmentBlock)(void**, HANDLE, BOOL);
27 typedef BOOL (WINAPI *PFNDestroyEnvironmentBlock)(void*);
28 typedef int (__stdcall *PFNDllRegisterServer)(void);
29 typedef int (__stdcall *PFNDllUnregisterServer)(void);
30 typedef DWORD (__stdcall *PFNNetApiBufferFree)(void*);
31 typedef DWORD (__stdcall *PFNNetWkstaGetInfo)(LPWSTR, DWORD, void*);
33 typedef BOOL (__stdcall *PFNOpenProcessToken)(HANDLE, DWORD, HANDLE*);
34 typedef BOOL (__stdcall *PFNOpenThreadToken)(HANDLE, DWORD, BOOL, HANDLE*);
35 typedef BOOL (__stdcall *PFNGetTokenInformation)(HANDLE, TOKEN_INFORMATION_CLASS, void*, DWORD, DWORD*);
36 typedef BOOL (__stdcall *PFNAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD,
37 DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*);
38 typedef BOOL (__stdcall *PFNEqualSid)(PSID, PSID);
39 typedef void* (__stdcall *PFNFreeSid)(PSID);
40 typedef BOOL (__stdcall *PFNIsUserAnAdmin)(void);
41 typedef BOOL (WINAPI *PFNGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD*);
42 typedef void (WINAPI *PFNGetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
45 # define CSIDL_MYMUSIC 0x000D
48 # define CSIDL_MYVIDEO 0x000E
50 #ifndef CSIDL_LOCAL_APPDATA
51 # define CSIDL_LOCAL_APPDATA 0x001C
53 #ifndef CSIDL_COMMON_FAVORITES
54 # define CSIDL_COMMON_FAVORITES 0x001F
56 #ifndef CSIDL_INTERNET_CACHE
57 # define CSIDL_INTERNET_CACHE 0x0020
60 # define CSIDL_COOKIES 0x0021
63 # define CSIDL_HISTORY 0x0022
65 #ifndef CSIDL_COMMON_APPDATA
66 # define CSIDL_COMMON_APPDATA 0x0023
69 # define CSIDL_WINDOWS 0x0024
71 #ifndef CSIDL_PROGRAM_FILES
72 # define CSIDL_PROGRAM_FILES 0x0026
74 #ifndef CSIDL_MYPICTURES
75 # define CSIDL_MYPICTURES 0x0027
78 # define CSIDL_PROFILE 0x0028
80 #ifndef CSIDL_PROGRAM_FILES_COMMON
81 # define CSIDL_PROGRAM_FILES_COMMON 0x002B
83 #ifndef CSIDL_COMMON_TEMPLATES
84 # define CSIDL_COMMON_TEMPLATES 0x002D
86 #ifndef CSIDL_COMMON_DOCUMENTS
87 # define CSIDL_COMMON_DOCUMENTS 0x002E
89 #ifndef CSIDL_COMMON_ADMINTOOLS
90 # define CSIDL_COMMON_ADMINTOOLS 0x002F
92 #ifndef CSIDL_ADMINTOOLS
93 # define CSIDL_ADMINTOOLS 0x0030
95 #ifndef CSIDL_COMMON_MUSIC
96 # define CSIDL_COMMON_MUSIC 0x0035
98 #ifndef CSIDL_COMMON_PICTURES
99 # define CSIDL_COMMON_PICTURES 0x0036
101 #ifndef CSIDL_COMMON_VIDEO
102 # define CSIDL_COMMON_VIDEO 0x0037
104 #ifndef CSIDL_CDBURN_AREA
105 # define CSIDL_CDBURN_AREA 0x003B
107 #ifndef CSIDL_FLAG_CREATE
108 # define CSIDL_FLAG_CREATE 0x8000
111 /* Use explicit struct definition because wSuiteMask and
112 * wProductType are not defined in the VC++ 6.0 headers.
113 * WORD type has been replaced by unsigned short because
114 * WORD is already used by Perl itself.
117 DWORD dwOSVersionInfoSize;
118 DWORD dwMajorVersion;
119 DWORD dwMinorVersion;
122 CHAR szCSDVersion[128];
123 unsigned short wServicePackMajor;
124 unsigned short wServicePackMinor;
125 unsigned short wSuiteMask;
128 } g_osver = {0, 0, 0, 0, 0, "", 0, 0, 0, 0, 0};
129 BOOL g_osver_ex = TRUE;
131 #define ONE_K_BUFSIZE 1024
136 return (g_osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
142 return (g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT);
148 return (g_osver.dwMajorVersion > 4);
151 /* Convert SV to wide character string. The return value must be
152 * freed using Safefree().
155 sv_to_wstr(pTHX_ SV *sv)
160 char *str = SvPV(sv, len);
161 UINT cp = SvUTF8(sv) ? CP_UTF8 : CP_ACP;
163 wlen = MultiByteToWideChar(cp, 0, str, (int)(len+1), NULL, 0);
164 New(0, wstr, wlen, WCHAR);
165 MultiByteToWideChar(cp, 0, str, (int)(len+1), wstr, wlen);
170 /* Convert wide character string to mortal SV. Use UTF8 encoding
171 * if the string cannot be represented in the system codepage.
174 wstr_to_sv(pTHX_ WCHAR *wstr)
176 int wlen = (int)wcslen(wstr)+1;
177 BOOL use_default = FALSE;
178 int len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wstr, wlen, NULL, 0, NULL, NULL);
179 SV *sv = sv_2mortal(newSV(len));
181 len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wstr, wlen, SvPVX(sv), len, NULL, &use_default);
183 len = WideCharToMultiByte(CP_UTF8, 0, wstr, wlen, NULL, 0, NULL, NULL);
185 len = WideCharToMultiByte(CP_UTF8, 0, wstr, wlen, SvPVX(sv), len, NULL, NULL);
188 /* Shouldn't really ever fail since we ask for the required length first, but who knows... */
191 SvCUR_set(sv, len-1);
196 /* Retrieve a variable from the Unicode environment in a mortal SV.
198 * Recreates the Unicode environment because a bug in earlier Perl versions
199 * overwrites it with the ANSI version, which contains replacement
200 * characters for the characters not in the ANSI codepage.
203 get_unicode_env(pTHX_ WCHAR *name)
209 PFNOpenProcessToken pfnOpenProcessToken;
211 /* Get security token for the current process owner */
212 module = LoadLibrary("advapi32.dll");
216 GETPROC(OpenProcessToken);
218 if (pfnOpenProcessToken == NULL ||
219 !pfnOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &token))
226 /* Create a Unicode environment block for this process */
227 module = LoadLibrary("userenv.dll");
229 PFNCreateEnvironmentBlock pfnCreateEnvironmentBlock;
230 PFNDestroyEnvironmentBlock pfnDestroyEnvironmentBlock;
232 GETPROC(CreateEnvironmentBlock);
233 GETPROC(DestroyEnvironmentBlock);
235 if (pfnCreateEnvironmentBlock && pfnDestroyEnvironmentBlock &&
236 pfnCreateEnvironmentBlock(&env, token, FALSE))
238 size_t name_len = wcslen(name);
242 size_t entry_len = wcslen(entry);
243 BOOL equal = (entry_len > name_len) && (entry[name_len] == '=');
245 for (i=0; equal && i < name_len; ++i)
246 equal = (towupper(entry[i]) == towupper(name[i]));
249 sv = wstr_to_sv(aTHX_ entry+name_len+1);
252 entry += entry_len+1;
254 pfnDestroyEnvironmentBlock(env);
262 /* Define both an ANSI and a Wide version of win32_longpath */
265 #define WIN32_FIND_DATA_T WIN32_FIND_DATAA
266 #define FN_FINDFIRSTFILE FindFirstFileA
267 #define FN_STRLEN strlen
268 #define FN_STRCPY strcpy
269 #define LONGPATH my_longpathA
270 #include "longpath.inc"
273 #define WIN32_FIND_DATA_T WIN32_FIND_DATAW
274 #define FN_FINDFIRSTFILE FindFirstFileW
275 #define FN_STRLEN wcslen
276 #define FN_STRCPY wcscpy
277 #define LONGPATH my_longpathW
278 #include "longpath.inc"
280 /* The my_ansipath() function takes a Unicode filename and converts it
281 * into the current Windows codepage. If some characters cannot be mapped,
282 * then it will convert the short name instead.
284 * The buffer to the ansi pathname must be freed with Safefree() when it
285 * it no longer needed.
287 * The argument to my_ansipath() must exist before this function is
288 * called; otherwise there is no way to determine the short path name.
290 * Ideas for future refinement:
291 * - Only convert those segments of the path that are not in the current
292 * codepage, but leave the other segments in their long form.
293 * - If the resulting name is longer than MAX_PATH, start converting
294 * additional path segments into short names until the full name
295 * is shorter than MAX_PATH. Shorten the filename part last!
298 /* This is a modified version of core Perl win32/win32.c(win32_ansipath).
299 * It uses New() etc. instead of win32_malloc().
303 my_ansipath(const WCHAR *widename)
306 BOOL use_default = FALSE;
307 int widelen = (int)wcslen(widename)+1;
308 int len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, widename, widelen,
309 NULL, 0, NULL, NULL);
310 New(0, name, len, char);
311 WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, widename, widelen,
312 name, len, NULL, &use_default);
314 DWORD shortlen = GetShortPathNameW(widename, NULL, 0);
317 New(0, shortname, shortlen, WCHAR);
318 shortlen = GetShortPathNameW(widename, shortname, shortlen)+1;
320 len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, shortname, shortlen,
321 NULL, 0, NULL, NULL);
322 Renew(name, len, char);
323 WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, shortname, shortlen,
324 name, len, NULL, NULL);
331 /* Convert wide character path to ANSI path and return as mortal SV. */
333 wstr_to_ansipath(pTHX_ WCHAR *wstr)
335 char *ansi = my_ansipath(wstr);
336 SV *sv = sv_2mortal(newSVpvn(ansi, strlen(ansi)));
350 WCHAR filename[MAX_PATH+1];
351 GetCurrentDirectoryW(MAX_PATH+1, filename);
352 ptr = my_ansipath(filename);
355 char filename[MAX_PATH+1];
356 GetCurrentDirectoryA(MAX_PATH+1, filename);
357 New(0, ptr, strlen(filename)+1, char);
358 strcpy(ptr, filename);
364 free_childdir(char *d)
377 free_childenv(void *d)
381 # define PerlDir_mapA(dir) (dir)
385 XS(w32_ExpandEnvironmentStrings)
390 croak("usage: Win32::ExpandEnvironmentStrings($String);\n");
393 WCHAR value[31*1024];
394 WCHAR *source = sv_to_wstr(aTHX_ ST(0));
395 ExpandEnvironmentStringsW(source, value, countof(value)-1);
396 ST(0) = wstr_to_sv(aTHX_ value);
402 ExpandEnvironmentStringsA(SvPV_nolen(ST(0)), value, countof(value)-2);
411 PFNIsUserAnAdmin pfnIsUserAnAdmin;
412 PFNOpenThreadToken pfnOpenThreadToken;
413 PFNOpenProcessToken pfnOpenProcessToken;
414 PFNGetTokenInformation pfnGetTokenInformation;
415 PFNAllocateAndInitializeSid pfnAllocateAndInitializeSid;
416 PFNEqualSid pfnEqualSid;
417 PFNFreeSid pfnFreeSid;
420 TOKEN_GROUPS *lpTokInfo;
421 SID_IDENTIFIER_AUTHORITY NtAuth = SECURITY_NT_AUTHORITY;
427 croak("usage: Win32::IsAdminUser()");
429 /* There is no concept of "Administrator" user accounts on Win9x systems,
430 so just return true. */
434 /* Use IsUserAnAdmin() when available. On Vista this will only return TRUE
435 * if the process is running with elevated privileges and not just when the
436 * process owner is a member of the "Administrators" group.
438 module = LoadLibrary("shell32.dll");
440 GETPROC(IsUserAnAdmin);
441 if (pfnIsUserAnAdmin) {
443 ST(0) = sv_2mortal(newSViv(pfnIsUserAnAdmin() ? 1 : 0));
450 module = LoadLibrary("advapi32.dll");
452 warn("Cannot load advapi32.dll library");
456 GETPROC(OpenThreadToken);
457 GETPROC(OpenProcessToken);
458 GETPROC(GetTokenInformation);
459 GETPROC(AllocateAndInitializeSid);
463 if (!(pfnOpenThreadToken && pfnOpenProcessToken &&
464 pfnGetTokenInformation && pfnAllocateAndInitializeSid &&
465 pfnEqualSid && pfnFreeSid))
467 warn("Cannot load functions from advapi32.dll library");
472 if (!pfnOpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hTok)) {
473 if (!pfnOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hTok)) {
474 warn("Cannot open thread token or process token");
480 pfnGetTokenInformation(hTok, TokenGroups, NULL, 0, &dwTokInfoLen);
481 if (!New(1, lpTokInfo, dwTokInfoLen, TOKEN_GROUPS)) {
482 warn("Cannot allocate token information structure");
488 if (!pfnGetTokenInformation(hTok, TokenGroups, lpTokInfo, dwTokInfoLen,
491 warn("Cannot get token information");
498 if (!pfnAllocateAndInitializeSid(&NtAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
499 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid))
501 warn("Cannot allocate administrators' SID");
509 for (i = 0; i < lpTokInfo->GroupCount; ++i) {
510 if (pfnEqualSid(lpTokInfo->Groups[i].Sid, pAdminSid)) {
516 pfnFreeSid(pAdminSid);
522 ST(0) = sv_2mortal(newSViv(iRetVal));
526 XS(w32_LookupAccountName)
537 croak("usage: Win32::LookupAccountName($system, $account, $domain, "
538 "$sid, $sidtype);\n");
540 SIDLen = sizeof(SID);
541 DomLen = sizeof(Domain);
543 bResult = LookupAccountNameA(SvPV_nolen(ST(0)), /* System */
544 SvPV_nolen(ST(1)), /* Account name */
545 &SID, /* SID structure */
546 &SIDLen, /* Size of SID buffer */
547 Domain, /* Domain buffer */
548 &DomLen, /* Domain buffer size */
549 &snu); /* SID name type */
551 sv_setpv(ST(2), Domain);
552 sv_setpvn(ST(3), SID, SIDLen);
553 sv_setiv(ST(4), snu);
560 XS(w32_LookupAccountSID)
565 DWORD AcctLen = sizeof(Account);
567 DWORD DomLen = sizeof(Domain);
572 croak("usage: Win32::LookupAccountSID($system, $sid, $account, $domain, $sidtype);\n");
574 sid = SvPV_nolen(ST(1));
575 if (IsValidSid(sid)) {
576 bResult = LookupAccountSidA(SvPV_nolen(ST(0)), /* System */
577 sid, /* SID structure */
578 Account, /* Account name buffer */
579 &AcctLen, /* name buffer length */
580 Domain, /* Domain buffer */
581 &DomLen, /* Domain buffer length */
582 &snu); /* SID name type */
584 sv_setpv(ST(2), Account);
585 sv_setpv(ST(3), Domain);
586 sv_setiv(ST(4), (IV)snu);
593 XS(w32_InitiateSystemShutdown)
596 HANDLE hToken; /* handle to process token */
597 TOKEN_PRIVILEGES tkp; /* pointer to token structure */
599 char *machineName, *message;
602 croak("usage: Win32::InitiateSystemShutdown($machineName, $message, "
603 "$timeOut, $forceClose, $reboot);\n");
605 machineName = SvPV_nolen(ST(0));
607 if (OpenProcessToken(GetCurrentProcess(),
608 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
611 LookupPrivilegeValueA(machineName,
613 &tkp.Privileges[0].Luid);
615 tkp.PrivilegeCount = 1; /* only setting one */
616 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
618 /* Get shutdown privilege for this process. */
619 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
620 (PTOKEN_PRIVILEGES)NULL, 0);
623 message = SvPV_nolen(ST(1));
624 bRet = InitiateSystemShutdownA(machineName, message, (DWORD)SvIV(ST(2)),
625 (BOOL)SvIV(ST(3)), (BOOL)SvIV(ST(4)));
627 /* Disable shutdown privilege. */
628 tkp.Privileges[0].Attributes = 0;
629 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
630 (PTOKEN_PRIVILEGES)NULL, 0);
635 XS(w32_AbortSystemShutdown)
638 HANDLE hToken; /* handle to process token */
639 TOKEN_PRIVILEGES tkp; /* pointer to token structure */
644 croak("usage: Win32::AbortSystemShutdown($machineName);\n");
646 machineName = SvPV_nolen(ST(0));
648 if (OpenProcessToken(GetCurrentProcess(),
649 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
652 LookupPrivilegeValueA(machineName,
654 &tkp.Privileges[0].Luid);
656 tkp.PrivilegeCount = 1; /* only setting one */
657 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
659 /* Get shutdown privilege for this process. */
660 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
661 (PTOKEN_PRIVILEGES)NULL, 0);
664 bRet = AbortSystemShutdownA(machineName);
666 /* Disable shutdown privilege. */
667 tkp.Privileges[0].Attributes = 0;
668 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
669 (PTOKEN_PRIVILEGES)NULL, 0);
678 DWORD flags = MB_ICONEXCLAMATION;
681 if (items < 1 || items > 3)
682 croak("usage: Win32::MsgBox($message [, $flags [, $title]]);\n");
685 flags = (DWORD)SvIV(ST(1));
689 WCHAR *msg = sv_to_wstr(aTHX_ ST(0));
691 title = sv_to_wstr(aTHX_ ST(2));
692 result = MessageBoxW(GetActiveWindow(), msg, title ? title : L"Perl", flags);
698 char *title = "Perl";
699 char *msg = SvPV_nolen(ST(0));
701 title = SvPV_nolen(ST(2));
702 result = MessageBoxA(GetActiveWindow(), msg, title, flags);
713 croak("usage: Win32::LoadLibrary($libname)\n");
714 hHandle = LoadLibraryA(SvPV_nolen(ST(0)));
716 XSRETURN_IV((DWORD_PTR)hHandle);
718 XSRETURN_IV((DWORD)hHandle);
727 croak("usage: Win32::FreeLibrary($handle)\n");
728 if (FreeLibrary(INT2PTR(HINSTANCE, SvIV(ST(0))))) {
734 XS(w32_GetProcAddress)
739 croak("usage: Win32::GetProcAddress($hinstance, $procname)\n");
740 XSRETURN_IV(PTR2IV(GetProcAddress(INT2PTR(HINSTANCE, SvIV(ST(0))), SvPV_nolen(ST(1)))));
743 XS(w32_RegisterServer)
750 croak("usage: Win32::RegisterServer($libname)\n");
752 module = LoadLibraryA(SvPV_nolen(ST(0)));
754 PFNDllRegisterServer pfnDllRegisterServer;
755 GETPROC(DllRegisterServer);
756 if (pfnDllRegisterServer && pfnDllRegisterServer() == 0)
760 ST(0) = boolSV(result);
764 XS(w32_UnregisterServer)
771 croak("usage: Win32::UnregisterServer($libname)\n");
773 module = LoadLibraryA(SvPV_nolen(ST(0)));
775 PFNDllUnregisterServer pfnDllUnregisterServer;
776 GETPROC(DllUnregisterServer);
777 if (pfnDllUnregisterServer && pfnDllUnregisterServer() == 0)
781 ST(0) = boolSV(result);
785 /* XXX rather bogus */
789 XSRETURN_PV(getenv("PROCESSOR_ARCHITECTURE"));
797 PFNGetNativeSystemInfo pfnGetNativeSystemInfo;
799 Zero(&sysinfo,1,SYSTEM_INFO);
800 module = GetModuleHandle("kernel32.dll");
801 GETPROC(GetNativeSystemInfo);
802 if (pfnGetNativeSystemInfo)
803 pfnGetNativeSystemInfo(&sysinfo);
805 GetSystemInfo(&sysinfo);
807 /* XXX docs say dwProcessorType is deprecated on NT */
808 XSRETURN_IV(sysinfo.dwProcessorType);
815 char szGUID[50] = {'\0'};
816 HRESULT hr = CoCreateGuid(&guid);
819 LPOLESTR pStr = NULL;
820 if (SUCCEEDED(StringFromCLSID(&guid, &pStr))) {
821 WideCharToMultiByte(CP_ACP, 0, pStr, (int)wcslen(pStr), szGUID,
822 sizeof(szGUID), NULL, NULL);
830 XS(w32_GetFolderPath)
833 char path[MAX_PATH+1];
834 WCHAR wpath[MAX_PATH+1];
839 if (items != 1 && items != 2)
840 croak("usage: Win32::GetFolderPath($csidl [, $create])\n");
842 folder = (int)SvIV(ST(0));
844 create = SvTRUE(ST(1)) ? CSIDL_FLAG_CREATE : 0;
846 module = LoadLibrary("shfolder.dll");
848 PFNSHGetFolderPathA pfna;
850 PFNSHGetFolderPathW pfnw;
851 pfnw = (PFNSHGetFolderPathW)GetProcAddress(module, "SHGetFolderPathW");
852 if (pfnw && SUCCEEDED(pfnw(NULL, folder|create, NULL, 0, wpath))) {
854 ST(0) = wstr_to_ansipath(aTHX_ wpath);
858 pfna = (PFNSHGetFolderPathA)GetProcAddress(module, "SHGetFolderPathA");
859 if (pfna && SUCCEEDED(pfna(NULL, folder|create, NULL, 0, path))) {
866 module = LoadLibrary("shell32.dll");
868 PFNSHGetSpecialFolderPathA pfna;
870 PFNSHGetSpecialFolderPathW pfnw;
871 pfnw = (PFNSHGetSpecialFolderPathW)GetProcAddress(module, "SHGetSpecialFolderPathW");
872 if (pfnw && pfnw(NULL, wpath, folder, !!create)) {
874 ST(0) = wstr_to_ansipath(aTHX_ wpath);
878 pfna = (PFNSHGetSpecialFolderPathA)GetProcAddress(module, "SHGetSpecialFolderPathA");
879 if (pfna && pfna(NULL, path, folder, !!create)) {
886 /* SHGetFolderPathW() and SHGetSpecialFolderPathW() may fail on older
887 * Perl versions that have replaced the Unicode environment with an
888 * ANSI version. Let's go spelunking in the registry now...
893 HKEY root = HKEY_CURRENT_USER;
897 case CSIDL_ADMINTOOLS: name = L"Administrative Tools"; break;
898 case CSIDL_APPDATA: name = L"AppData"; break;
899 case CSIDL_CDBURN_AREA: name = L"CD Burning"; break;
900 case CSIDL_COOKIES: name = L"Cookies"; break;
902 case CSIDL_DESKTOPDIRECTORY: name = L"Desktop"; break;
903 case CSIDL_FAVORITES: name = L"Favorites"; break;
904 case CSIDL_FONTS: name = L"Fonts"; break;
905 case CSIDL_HISTORY: name = L"History"; break;
906 case CSIDL_INTERNET_CACHE: name = L"Cache"; break;
907 case CSIDL_LOCAL_APPDATA: name = L"Local AppData"; break;
908 case CSIDL_MYMUSIC: name = L"My Music"; break;
909 case CSIDL_MYPICTURES: name = L"My Pictures"; break;
910 case CSIDL_MYVIDEO: name = L"My Video"; break;
911 case CSIDL_NETHOOD: name = L"NetHood"; break;
912 case CSIDL_PERSONAL: name = L"Personal"; break;
913 case CSIDL_PRINTHOOD: name = L"PrintHood"; break;
914 case CSIDL_PROGRAMS: name = L"Programs"; break;
915 case CSIDL_RECENT: name = L"Recent"; break;
916 case CSIDL_SENDTO: name = L"SendTo"; break;
917 case CSIDL_STARTMENU: name = L"Start Menu"; break;
918 case CSIDL_STARTUP: name = L"Startup"; break;
919 case CSIDL_TEMPLATES: name = L"Templates"; break;
920 /* XXX L"Local Settings" */
924 root = HKEY_LOCAL_MACHINE;
926 case CSIDL_COMMON_ADMINTOOLS: name = L"Common Administrative Tools"; break;
927 case CSIDL_COMMON_APPDATA: name = L"Common AppData"; break;
928 case CSIDL_COMMON_DESKTOPDIRECTORY: name = L"Common Desktop"; break;
929 case CSIDL_COMMON_DOCUMENTS: name = L"Common Documents"; break;
930 case CSIDL_COMMON_FAVORITES: name = L"Common Favorites"; break;
931 case CSIDL_COMMON_PROGRAMS: name = L"Common Programs"; break;
932 case CSIDL_COMMON_STARTMENU: name = L"Common Start Menu"; break;
933 case CSIDL_COMMON_STARTUP: name = L"Common Startup"; break;
934 case CSIDL_COMMON_TEMPLATES: name = L"Common Templates"; break;
935 case CSIDL_COMMON_MUSIC: name = L"CommonMusic"; break;
936 case CSIDL_COMMON_PICTURES: name = L"CommonPictures"; break;
937 case CSIDL_COMMON_VIDEO: name = L"CommonVideo"; break;
941 * case CSIDL_SYSTEM # GetSystemDirectory()
942 * case CSIDL_RESOURCES # %windir%\Resources\, For theme and other windows resources.
943 * case CSIDL_RESOURCES_LOCALIZED # %windir%\Resources\<LangID>, for theme and other windows specific resources.
946 #define SHELL_FOLDERS "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
948 if (name && RegOpenKeyEx(root, SHELL_FOLDERS, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) {
949 WCHAR data[MAX_PATH+1];
950 DWORD cb = sizeof(data)-sizeof(WCHAR);
951 DWORD type = REG_NONE;
952 long rc = RegQueryValueExW(hkey, name, NULL, &type, (BYTE*)&data, &cb);
954 if (rc == ERROR_SUCCESS && type == REG_SZ && cb > sizeof(WCHAR) && data[0]) {
955 /* Make sure the string is properly terminated */
956 data[cb/sizeof(WCHAR)] = '\0';
957 ST(0) = wstr_to_ansipath(aTHX_ data);
964 /* Unders some circumstances the registry entries seem to have a null string
965 * as their value even when the directory already exists. The environment
966 * variables do get set though, so try re-create a Unicode environment and
967 * check if they are there.
971 case CSIDL_APPDATA: sv = get_unicode_env(aTHX_ L"APPDATA"); break;
972 case CSIDL_PROFILE: sv = get_unicode_env(aTHX_ L"USERPROFILE"); break;
973 case CSIDL_PROGRAM_FILES: sv = get_unicode_env(aTHX_ L"ProgramFiles"); break;
974 case CSIDL_PROGRAM_FILES_COMMON: sv = get_unicode_env(aTHX_ L"CommonProgramFiles"); break;
975 case CSIDL_WINDOWS: sv = get_unicode_env(aTHX_ L"SystemRoot"); break;
986 XS(w32_GetFileVersion)
995 croak("usage: Win32::GetFileVersion($filename)\n");
997 filename = SvPV_nolen(ST(0));
998 size = GetFileVersionInfoSize(filename, &handle);
1002 New(0, data, size, char);
1006 if (GetFileVersionInfo(filename, handle, size, data)) {
1007 VS_FIXEDFILEINFO *info;
1009 if (VerQueryValue(data, "\\", (void**)&info, &len)) {
1010 int dwValueMS1 = (info->dwFileVersionMS>>16);
1011 int dwValueMS2 = (info->dwFileVersionMS&0xffff);
1012 int dwValueLS1 = (info->dwFileVersionLS>>16);
1013 int dwValueLS2 = (info->dwFileVersionLS&0xffff);
1015 if (GIMME_V == G_ARRAY) {
1017 XST_mIV(0, dwValueMS1);
1018 XST_mIV(1, dwValueMS2);
1019 XST_mIV(2, dwValueLS1);
1020 XST_mIV(3, dwValueLS2);
1025 sprintf(version, "%d.%d.%d.%d", dwValueMS1, dwValueMS2, dwValueLS1, dwValueLS2);
1026 XST_mPV(0, version);
1038 XS(w32_SetChildShowWindow)
1040 /* This function doesn't do anything useful for cygwin. In the
1041 * MSWin32 case it modifies w32_showwindow, which is used by
1042 * win32_spawnvp(). Since w32_showwindow is an internal variable
1043 * inside the thread_intern structure, the MSWin32 implementation
1044 * lives in win32/win32.c in the core Perl distribution.
1054 /* Make the host for current directory */
1055 char* ptr = PerlEnv_get_childdir();
1058 * then it worked, set PV valid,
1059 * else return 'undef'
1062 SV *sv = sv_newmortal();
1064 PerlEnv_free_childdir(ptr);
1066 #ifndef INCOMPLETE_TAINTS
1081 Perl_croak(aTHX_ "usage: Win32::SetCwd($cwd)");
1083 if (IsWin2000() && SvUTF8(ST(0))) {
1084 WCHAR *wide = sv_to_wstr(aTHX_ ST(0));
1085 char *ansi = my_ansipath(wide);
1086 int rc = PerlDir_chdir(ansi);
1093 if (!PerlDir_chdir(SvPV_nolen(ST(0))))
1100 XS(w32_GetNextAvailDrive)
1104 char root[] = "_:\\";
1109 if (GetDriveType(root) == 1) {
1117 XS(w32_GetLastError)
1121 XSRETURN_IV(GetLastError());
1124 XS(w32_SetLastError)
1128 Perl_croak(aTHX_ "usage: Win32::SetLastError($error)");
1129 SetLastError((DWORD)SvIV(ST(0)));
1139 DWORD size = countof(name);
1140 if (GetUserNameW(name, &size)) {
1141 ST(0) = wstr_to_sv(aTHX_ name);
1147 DWORD size = countof(name);
1148 if (GetUserNameA(name, &size)) {
1149 /* size includes NULL */
1150 ST(0) = sv_2mortal(newSVpvn(name, size-1));
1160 char name[MAX_COMPUTERNAME_LENGTH+1];
1161 DWORD size = sizeof(name);
1163 if (GetComputerName(name,&size)) {
1164 /* size does NOT include NULL :-( */
1165 ST(0) = sv_2mortal(newSVpvn(name,size));
1175 HMODULE module = LoadLibrary("netapi32.dll");
1176 PFNNetApiBufferFree pfnNetApiBufferFree;
1177 PFNNetWkstaGetInfo pfnNetWkstaGetInfo;
1180 GETPROC(NetApiBufferFree);
1181 GETPROC(NetWkstaGetInfo);
1184 if (module && pfnNetWkstaGetInfo && pfnNetApiBufferFree) {
1185 /* this way is more reliable, in case user has a local account. */
1187 DWORD dnamelen = sizeof(dname);
1189 DWORD wki100_platform_id;
1190 LPWSTR wki100_computername;
1191 LPWSTR wki100_langroup;
1192 DWORD wki100_ver_major;
1193 DWORD wki100_ver_minor;
1196 retval = pfnNetWkstaGetInfo(NULL, 100, &pwi);
1197 /* NERR_Success *is* 0*/
1199 if (pwi->wki100_langroup && *(pwi->wki100_langroup)) {
1200 WideCharToMultiByte(CP_ACP, 0, pwi->wki100_langroup,
1201 -1, (LPSTR)dname, dnamelen, NULL, NULL);
1204 WideCharToMultiByte(CP_ACP, 0, pwi->wki100_computername,
1205 -1, (LPSTR)dname, dnamelen, NULL, NULL);
1207 pfnNetApiBufferFree(pwi);
1208 FreeLibrary(module);
1211 FreeLibrary(module);
1212 SetLastError(retval);
1215 /* Win95 doesn't have NetWksta*(), so do it the old way */
1217 DWORD size = sizeof(name);
1219 FreeLibrary(module);
1220 if (GetUserName(name,&size)) {
1221 char sid[ONE_K_BUFSIZE];
1222 DWORD sidlen = sizeof(sid);
1224 DWORD dnamelen = sizeof(dname);
1226 if (LookupAccountName(NULL, name, (PSID)&sid, &sidlen,
1227 dname, &dnamelen, &snu)) {
1228 XSRETURN_PV(dname); /* all that for this */
1239 DWORD flags, filecomplen;
1240 if (GetVolumeInformation(NULL, NULL, 0, NULL, &filecomplen,
1241 &flags, fsname, sizeof(fsname))) {
1242 if (GIMME_V == G_ARRAY) {
1243 XPUSHs(sv_2mortal(newSVpvn(fsname,strlen(fsname))));
1244 XPUSHs(sv_2mortal(newSViv(flags)));
1245 XPUSHs(sv_2mortal(newSViv(filecomplen)));
1250 XSRETURN_PV(fsname);
1255 XS(w32_GetOSVersion)
1259 if (GIMME_V == G_SCALAR) {
1260 XSRETURN_IV(g_osver.dwPlatformId);
1262 XPUSHs(sv_2mortal(newSVpvn(g_osver.szCSDVersion, strlen(g_osver.szCSDVersion))));
1264 XPUSHs(sv_2mortal(newSViv(g_osver.dwMajorVersion)));
1265 XPUSHs(sv_2mortal(newSViv(g_osver.dwMinorVersion)));
1266 XPUSHs(sv_2mortal(newSViv(g_osver.dwBuildNumber)));
1267 XPUSHs(sv_2mortal(newSViv(g_osver.dwPlatformId)));
1269 XPUSHs(sv_2mortal(newSViv(g_osver.wServicePackMajor)));
1270 XPUSHs(sv_2mortal(newSViv(g_osver.wServicePackMinor)));
1271 XPUSHs(sv_2mortal(newSViv(g_osver.wSuiteMask)));
1272 XPUSHs(sv_2mortal(newSViv(g_osver.wProductType)));
1281 XSRETURN_IV(IsWinNT());
1288 XSRETURN_IV(IsWin95());
1291 XS(w32_FormatMessage)
1295 char msgbuf[ONE_K_BUFSIZE];
1298 Perl_croak(aTHX_ "usage: Win32::FormatMessage($errno)");
1300 if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
1301 &source, (DWORD)SvIV(ST(0)), 0,
1302 msgbuf, sizeof(msgbuf)-1, NULL))
1304 XSRETURN_PV(msgbuf);
1316 PROCESS_INFORMATION stProcInfo;
1317 STARTUPINFO stStartInfo;
1318 BOOL bSuccess = FALSE;
1321 Perl_croak(aTHX_ "usage: Win32::Spawn($cmdName, $args, $PID)");
1323 cmd = SvPV_nolen(ST(0));
1324 args = SvPV_nolen(ST(1));
1326 env = PerlEnv_get_childenv();
1327 dir = PerlEnv_get_childdir();
1329 memset(&stStartInfo, 0, sizeof(stStartInfo)); /* Clear the block */
1330 stStartInfo.cb = sizeof(stStartInfo); /* Set the structure size */
1331 stStartInfo.dwFlags = STARTF_USESHOWWINDOW; /* Enable wShowWindow control */
1332 stStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; /* Start min (normal) */
1335 cmd, /* Image path */
1336 args, /* Arguments for command line */
1337 NULL, /* Default process security */
1338 NULL, /* Default thread security */
1339 FALSE, /* Must be TRUE to use std handles */
1340 NORMAL_PRIORITY_CLASS, /* No special scheduling */
1341 env, /* Inherit our environment block */
1342 dir, /* Inherit our currrent directory */
1343 &stStartInfo, /* -> Startup info */
1344 &stProcInfo)) /* <- Process info (if OK) */
1346 int pid = (int)stProcInfo.dwProcessId;
1347 if (IsWin95() && pid < 0)
1349 sv_setiv(ST(2), pid);
1350 CloseHandle(stProcInfo.hThread);/* library source code does this. */
1353 PerlEnv_free_childenv(env);
1354 PerlEnv_free_childdir(dir);
1355 XSRETURN_IV(bSuccess);
1358 XS(w32_GetTickCount)
1361 DWORD msec = GetTickCount();
1368 XS(w32_GetShortPathName)
1375 Perl_croak(aTHX_ "usage: Win32::GetShortPathName($longPathName)");
1378 WCHAR wshort[MAX_PATH+1];
1379 WCHAR *wlong = sv_to_wstr(aTHX_ ST(0));
1380 len = GetShortPathNameW(wlong, wshort, countof(wshort));
1382 if (len && len < sizeof(wshort)) {
1383 ST(0) = wstr_to_sv(aTHX_ wshort);
1389 shortpath = sv_mortalcopy(ST(0));
1390 SvUPGRADE(shortpath, SVt_PV);
1391 if (!SvPVX(shortpath) || !SvLEN(shortpath))
1394 /* src == target is allowed */
1396 len = GetShortPathName(SvPVX(shortpath),
1398 (DWORD)SvLEN(shortpath));
1399 } while (len >= SvLEN(shortpath) && sv_grow(shortpath,len+1));
1401 SvCUR_set(shortpath,len);
1402 *SvEND(shortpath) = '\0';
1409 XS(w32_GetFullPathName)
1415 /* The code below relies on the fact that PerlDir_mapX() returns an
1416 * absolute path, which is only true under PERL_IMPLICIT_SYS when
1417 * we use the virtualization code from win32/vdir.h.
1418 * Without it PerlDir_mapX() is a no-op and we need to use the same
1419 * code as we use for Cygwin.
1421 #if __CYGWIN__ || !defined(PERL_IMPLICIT_SYS)
1422 char buffer[2*MAX_PATH];
1426 Perl_croak(aTHX_ "usage: Win32::GetFullPathName($filename)");
1428 #if __CYGWIN__ || !defined(PERL_IMPLICIT_SYS)
1430 WCHAR *filename = sv_to_wstr(aTHX_ ST(0));
1431 WCHAR full[2*MAX_PATH];
1432 DWORD len = GetFullPathNameW(filename, countof(full), full, NULL);
1434 if (len == 0 || len >= countof(full))
1436 ansi = fullname = my_ansipath(full);
1439 DWORD len = GetFullPathNameA(SvPV_nolen(ST(0)), countof(buffer), buffer, NULL);
1440 if (len == 0 || len >= countof(buffer))
1445 /* Don't use my_ansipath() unless the $filename argument is in Unicode.
1446 * If the relative path doesn't exist, GetShortPathName() will fail and
1447 * my_ansipath() will use the long name with replacement characters.
1448 * In that case we will be better off using PerlDir_mapA(), which
1449 * already uses the ANSI name of the current directory.
1451 * XXX The one missing case is where we could downgrade $filename
1452 * XXX from UTF8 into the current codepage.
1454 if (IsWin2000() && SvUTF8(ST(0))) {
1455 WCHAR *filename = sv_to_wstr(aTHX_ ST(0));
1456 WCHAR *mappedname = PerlDir_mapW(filename);
1458 ansi = fullname = my_ansipath(mappedname);
1461 fullname = PerlDir_mapA(SvPV_nolen(ST(0)));
1463 # if PERL_VERSION < 8
1465 /* PerlDir_mapX() in Perl 5.6 used to return forward slashes */
1466 char *str = fullname;
1476 /* GetFullPathName() on Windows NT drops trailing backslash */
1477 if (g_osver.dwMajorVersion == 4 && *fullname) {
1479 char *pv = SvPV(ST(0), len);
1480 char *lastchar = fullname + strlen(fullname) - 1;
1481 /* If ST(0) ends with a slash, but fullname doesn't ... */
1482 if (len && (pv[len-1] == '/' || pv[len-1] == '\\') && *lastchar != '\\') {
1483 /* fullname is the MAX_PATH+1 sized buffer returned from PerlDir_mapA()
1484 * or the 2*MAX_PATH sized local buffer in the __CYGWIN__ case.
1486 if (lastchar - fullname < MAX_PATH - 1)
1487 strcpy(lastchar+1, "\\");
1491 if (GIMME_V == G_ARRAY) {
1492 char *filepart = strrchr(fullname, '\\');
1496 XST_mPV(1, ++filepart);
1504 XST_mPV(0, fullname);
1511 XS(w32_GetLongPathName)
1516 Perl_croak(aTHX_ "usage: Win32::GetLongPathName($pathname)");
1519 WCHAR *wstr = sv_to_wstr(aTHX_ ST(0));
1520 WCHAR wide_path[MAX_PATH+1];
1523 if (wcslen(wstr) < countof(wide_path)) {
1524 wcscpy(wide_path, wstr);
1525 long_path = my_longpathW(wide_path);
1528 ST(0) = wstr_to_sv(aTHX_ long_path);
1536 char tmpbuf[MAX_PATH+1];
1541 pathstr = SvPV(path,len);
1542 if (len < sizeof(tmpbuf)) {
1543 strcpy(tmpbuf, pathstr);
1544 pathstr = my_longpathA(tmpbuf);
1546 ST(0) = sv_2mortal(newSVpvn(pathstr, strlen(pathstr)));
1554 XS(w32_GetANSIPathName)
1560 Perl_croak(aTHX_ "usage: Win32::GetANSIPathName($pathname)");
1562 wide_path = sv_to_wstr(aTHX_ ST(0));
1563 ST(0) = wstr_to_ansipath(aTHX_ wide_path);
1564 Safefree(wide_path);
1572 Perl_croak(aTHX_ "usage: Win32::Sleep($milliseconds)");
1573 Sleep((DWORD)SvIV(ST(0)));
1581 char *pszSourceFile;
1582 char szSourceFile[MAX_PATH+1];
1585 Perl_croak(aTHX_ "usage: Win32::CopyFile($from, $to, $overwrite)");
1587 pszSourceFile = PerlDir_mapA(SvPV_nolen(ST(0)));
1588 if (strlen(pszSourceFile) < sizeof(szSourceFile)) {
1589 strcpy(szSourceFile, pszSourceFile);
1590 bResult = CopyFileA(szSourceFile, PerlDir_mapA(SvPV_nolen(ST(1))), !SvTRUE(ST(2)));
1597 XS(w32_OutputDebugString)
1601 Perl_croak(aTHX_ "usage: Win32::OutputDebugString($string)");
1603 if (SvUTF8(ST(0))) {
1604 WCHAR *str = sv_to_wstr(aTHX_ ST(0));
1605 OutputDebugStringW(str);
1609 OutputDebugStringA(SvPV_nolen(ST(0)));
1614 XS(w32_GetCurrentProcessId)
1618 XSRETURN_IV(GetCurrentProcessId());
1621 XS(w32_GetCurrentThreadId)
1625 XSRETURN_IV(GetCurrentThreadId());
1628 XS(w32_CreateDirectory)
1634 Perl_croak(aTHX_ "usage: Win32::CreateDirectory($dir)");
1636 if (IsWin2000() && SvUTF8(ST(0))) {
1637 WCHAR *dir = sv_to_wstr(aTHX_ ST(0));
1638 result = CreateDirectoryW(dir, NULL);
1642 result = CreateDirectoryA(SvPV_nolen(ST(0)), NULL);
1645 ST(0) = boolSV(result);
1655 Perl_croak(aTHX_ "usage: Win32::CreateFile($file)");
1657 if (IsWin2000() && SvUTF8(ST(0))) {
1658 WCHAR *file = sv_to_wstr(aTHX_ ST(0));
1659 handle = CreateFileW(file, GENERIC_WRITE, FILE_SHARE_WRITE,
1660 NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
1664 handle = CreateFileA(SvPV_nolen(ST(0)), GENERIC_WRITE, FILE_SHARE_WRITE,
1665 NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
1668 if (handle != INVALID_HANDLE_VALUE)
1669 CloseHandle(handle);
1671 ST(0) = boolSV(handle != INVALID_HANDLE_VALUE);
1675 XS(w32_GetSystemMetrics)
1680 Perl_croak(aTHX_ "usage: Win32::GetSystemMetrics($index)");
1682 XSRETURN_IV(GetSystemMetrics((int)SvIV(ST(0))));
1685 XS(w32_GetProductInfo)
1690 PFNGetProductInfo pfnGetProductInfo;
1693 Perl_croak(aTHX_ "usage: Win32::GetProductInfo($major,$minor,$spmajor,$spminor)");
1695 module = GetModuleHandle("kernel32.dll");
1696 GETPROC(GetProductInfo);
1697 if (pfnGetProductInfo &&
1698 pfnGetProductInfo((DWORD)SvIV(ST(0)), (DWORD)SvIV(ST(1)),
1699 (DWORD)SvIV(ST(2)), (DWORD)SvIV(ST(3)), &type))
1704 /* PRODUCT_UNDEFINED */
1712 XSRETURN_IV(GetACP());
1715 XS(w32_GetConsoleCP)
1719 XSRETURN_IV(GetConsoleCP());
1722 XS(w32_GetConsoleOutputCP)
1726 XSRETURN_IV(GetConsoleOutputCP());
1733 XSRETURN_IV(GetOEMCP());
1736 XS(w32_SetConsoleCP)
1741 Perl_croak(aTHX_ "usage: Win32::SetConsoleCP($id)");
1743 XSRETURN_IV(SetConsoleCP((int)SvIV(ST(0))));
1746 XS(w32_SetConsoleOutputCP)
1751 Perl_croak(aTHX_ "usage: Win32::SetConsoleOutputCP($id)");
1753 XSRETURN_IV(SetConsoleOutputCP((int)SvIV(ST(0))));
1756 MODULE = Win32 PACKAGE = Win32
1762 char *file = __FILE__;
1764 if (g_osver.dwOSVersionInfoSize == 0) {
1765 g_osver.dwOSVersionInfoSize = sizeof(g_osver);
1766 if (!GetVersionExA((OSVERSIONINFOA*)&g_osver)) {
1768 g_osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
1769 GetVersionExA((OSVERSIONINFOA*)&g_osver);
1773 newXS("Win32::LookupAccountName", w32_LookupAccountName, file);
1774 newXS("Win32::LookupAccountSID", w32_LookupAccountSID, file);
1775 newXS("Win32::InitiateSystemShutdown", w32_InitiateSystemShutdown, file);
1776 newXS("Win32::AbortSystemShutdown", w32_AbortSystemShutdown, file);
1777 newXS("Win32::ExpandEnvironmentStrings", w32_ExpandEnvironmentStrings, file);
1778 newXS("Win32::MsgBox", w32_MsgBox, file);
1779 newXS("Win32::LoadLibrary", w32_LoadLibrary, file);
1780 newXS("Win32::FreeLibrary", w32_FreeLibrary, file);
1781 newXS("Win32::GetProcAddress", w32_GetProcAddress, file);
1782 newXS("Win32::RegisterServer", w32_RegisterServer, file);
1783 newXS("Win32::UnregisterServer", w32_UnregisterServer, file);
1784 newXS("Win32::GetArchName", w32_GetArchName, file);
1785 newXS("Win32::GetChipName", w32_GetChipName, file);
1786 newXS("Win32::GuidGen", w32_GuidGen, file);
1787 newXS("Win32::GetFolderPath", w32_GetFolderPath, file);
1788 newXS("Win32::IsAdminUser", w32_IsAdminUser, file);
1789 newXS("Win32::GetFileVersion", w32_GetFileVersion, file);
1791 newXS("Win32::GetCwd", w32_GetCwd, file);
1792 newXS("Win32::SetCwd", w32_SetCwd, file);
1793 newXS("Win32::GetNextAvailDrive", w32_GetNextAvailDrive, file);
1794 newXS("Win32::GetLastError", w32_GetLastError, file);
1795 newXS("Win32::SetLastError", w32_SetLastError, file);
1796 newXS("Win32::LoginName", w32_LoginName, file);
1797 newXS("Win32::NodeName", w32_NodeName, file);
1798 newXS("Win32::DomainName", w32_DomainName, file);
1799 newXS("Win32::FsType", w32_FsType, file);
1800 newXS("Win32::GetOSVersion", w32_GetOSVersion, file);
1801 newXS("Win32::IsWinNT", w32_IsWinNT, file);
1802 newXS("Win32::IsWin95", w32_IsWin95, file);
1803 newXS("Win32::FormatMessage", w32_FormatMessage, file);
1804 newXS("Win32::Spawn", w32_Spawn, file);
1805 newXS("Win32::GetTickCount", w32_GetTickCount, file);
1806 newXS("Win32::GetShortPathName", w32_GetShortPathName, file);
1807 newXS("Win32::GetFullPathName", w32_GetFullPathName, file);
1808 newXS("Win32::GetLongPathName", w32_GetLongPathName, file);
1809 newXS("Win32::GetANSIPathName", w32_GetANSIPathName, file);
1810 newXS("Win32::CopyFile", w32_CopyFile, file);
1811 newXS("Win32::Sleep", w32_Sleep, file);
1812 newXS("Win32::OutputDebugString", w32_OutputDebugString, file);
1813 newXS("Win32::GetCurrentProcessId", w32_GetCurrentProcessId, file);
1814 newXS("Win32::GetCurrentThreadId", w32_GetCurrentThreadId, file);
1815 newXS("Win32::CreateDirectory", w32_CreateDirectory, file);
1816 newXS("Win32::CreateFile", w32_CreateFile, file);
1817 newXS("Win32::GetSystemMetrics", w32_GetSystemMetrics, file);
1818 newXS("Win32::GetProductInfo", w32_GetProductInfo, file);
1819 newXS("Win32::GetACP", w32_GetACP, file);
1820 newXS("Win32::GetConsoleCP", w32_GetConsoleCP, file);
1821 newXS("Win32::GetConsoleOutputCP", w32_GetConsoleOutputCP, file);
1822 newXS("Win32::GetOEMCP", w32_GetOEMCP, file);
1823 newXS("Win32::SetConsoleCP", w32_SetConsoleCP, file);
1824 newXS("Win32::SetConsoleOutputCP", w32_SetConsoleOutputCP, file);
1826 newXS("Win32::SetChildShowWindow", w32_SetChildShowWindow, file);