1/*    Win32CORE.c
2 *
3 *    Copyright (C) 2007 by Larry Wall and others
4 *
5 *    You may distribute under the terms of either the GNU General Public
6 *    License or the Artistic License, as specified in the README file.
7 *
8 */
9
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12
13#if defined(__CYGWIN__) && !defined(USEIMPORTLIB)
14  #undef WIN32
15#endif
16#define PERL_NO_GET_CONTEXT
17#include "EXTERN.h"
18#if defined(__CYGWIN__) && !defined(USEIMPORTLIB)
19  #define EXTCONST extern const
20#endif
21#include "perl.h"
22#include "XSUB.h"
23
24
25XS(w32_CORE_all){
26    /* I'd use dSAVE_ERRNO() here, but it doesn't save the Win32 error code
27     * under cygwin, if that changes this code should change to use that.
28     */
29    int saved_errno = errno;
30    DWORD err = GetLastError();
31    /* capture the XSANY value before Perl_load_module, the CV's any member will
32     * be overwritten by Perl_load_module and subsequent newXSes or pure perl
33     * subs
34     */
35    const char *function  = (const char *) XSANY.any_ptr;
36    Perl_load_module(aTHX_ PERL_LOADMOD_NOIMPORT, newSVpvs("Win32"), newSVnv(0.27));
37    SetLastError(err);
38    errno = saved_errno;
39    /* mark and SP from caller are passed through unchanged */
40    call_pv(function, GIMME_V);
41}
42
43#ifdef __cplusplus
44extern "C"
45#endif
46XS_EXTERNAL(boot_Win32CORE)
47{
48    /* This function only exists because writemain.SH, lib/ExtUtils/Embed.pm
49     * and win32/buildext.pl will all generate references to it.  The function
50     * should never be called though, as Win32CORE.pm doesn't use DynaLoader.
51     */
52    PERL_UNUSED_ARG(cv);
53}
54
55EXTERN_C
56#if !defined(__CYGWIN__) || defined(USEIMPORTLIB)
57__declspec(dllexport)
58#endif
59void
60init_Win32CORE(pTHX)
61{
62    /* This function is called from init_os_extras().  The Perl interpreter
63     * is not yet fully initialized, so don't do anything fancy in here.
64     */
65
66    static const struct {
67        char Win32__GetCwd [sizeof("Win32::GetCwd")];
68        char Win32__SetCwd [sizeof("Win32::SetCwd")];
69        char Win32__GetNextAvailDrive [sizeof("Win32::GetNextAvailDrive")];
70        char Win32__GetLastError [sizeof("Win32::GetLastError")];
71        char Win32__SetLastError [sizeof("Win32::SetLastError")];
72        char Win32__LoginName [sizeof("Win32::LoginName")];
73        char Win32__NodeName [sizeof("Win32::NodeName")];
74        char Win32__DomainName [sizeof("Win32::DomainName")];
75        char Win32__FsType [sizeof("Win32::FsType")];
76        char Win32__GetOSVersion [sizeof("Win32::GetOSVersion")];
77        char Win32__IsWinNT [sizeof("Win32::IsWinNT")];
78        char Win32__IsWin95 [sizeof("Win32::IsWin95")];
79        char Win32__FormatMessage [sizeof("Win32::FormatMessage")];
80        char Win32__Spawn [sizeof("Win32::Spawn")];
81        char Win32__GetTickCount [sizeof("Win32::GetTickCount")];
82        char Win32__GetShortPathName [sizeof("Win32::GetShortPathName")];
83        char Win32__GetFullPathName [sizeof("Win32::GetFullPathName")];
84        char Win32__GetLongPathName [sizeof("Win32::GetLongPathName")];
85        char Win32__CopyFile [sizeof("Win32::CopyFile")];
86        char Win32__Sleep [sizeof("Win32::Sleep")];
87    } fnname_table = {
88        "Win32::GetCwd",
89        "Win32::SetCwd",
90        "Win32::GetNextAvailDrive",
91        "Win32::GetLastError",
92        "Win32::SetLastError",
93        "Win32::LoginName",
94        "Win32::NodeName",
95        "Win32::DomainName",
96        "Win32::FsType",
97        "Win32::GetOSVersion",
98        "Win32::IsWinNT",
99        "Win32::IsWin95",
100        "Win32::FormatMessage",
101        "Win32::Spawn",
102        "Win32::GetTickCount",
103        "Win32::GetShortPathName",
104        "Win32::GetFullPathName",
105        "Win32::GetLongPathName",
106        "Win32::CopyFile",
107        "Win32::Sleep"
108    };
109
110    static const unsigned char fnname_lens [] = {
111        sizeof("Win32::GetCwd"),
112        sizeof("Win32::SetCwd"),
113        sizeof("Win32::GetNextAvailDrive"),
114        sizeof("Win32::GetLastError"),
115        sizeof("Win32::SetLastError"),
116        sizeof("Win32::LoginName"),
117        sizeof("Win32::NodeName"),
118        sizeof("Win32::DomainName"),
119        sizeof("Win32::FsType"),
120        sizeof("Win32::GetOSVersion"),
121        sizeof("Win32::IsWinNT"),
122        sizeof("Win32::IsWin95"),
123        sizeof("Win32::FormatMessage"),
124        sizeof("Win32::Spawn"),
125        sizeof("Win32::GetTickCount"),
126        sizeof("Win32::GetShortPathName"),
127        sizeof("Win32::GetFullPathName"),
128        sizeof("Win32::GetLongPathName"),
129        sizeof("Win32::CopyFile"),
130        sizeof("Win32::Sleep")
131    };
132    const unsigned char * len = (const unsigned char *)&fnname_lens;
133    const char * function = (char *)&fnname_table;
134    while (function < (char *)&fnname_table + sizeof(fnname_table)) {
135        const char * const file = __FILE__;
136        CV * const cv = newXS(function, w32_CORE_all, file);
137        XSANY.any_ptr = (void *)function;
138        function += *len++;
139    }
140
141
142    /* Don't forward Win32::SetChildShowWindow().  It accesses the internal variable
143     * w32_showwindow in thread_intern and is therefore not implemented in Win32.xs.
144     */
145    /* newXS("Win32::SetChildShowWindow", w32_SetChildShowWindow, file); */
146}
147