Commit | Line | Data |
0a753a76 |
1 | /* |
2 | * "The Road goes ever on and on, down from the door where it began." |
3 | */ |
4 | |
5 | #ifdef __cplusplus |
6 | extern "C" { |
7 | #endif |
8 | |
9 | #include "EXTERN.h" |
10 | #include "perl.h" |
96e4d5b1 |
11 | #include "XSUB.h" |
0a753a76 |
12 | |
13 | #ifdef __cplusplus |
14 | } |
15 | # define EXTERN_C extern "C" |
16 | #else |
17 | # define EXTERN_C extern |
18 | #endif |
19 | |
20 | static void xs_init _((void)); |
21 | |
68dc0745 |
22 | __declspec(dllexport) int |
23 | RunPerl(int argc, char **argv, char **env, void *iosubsystem) |
0a753a76 |
24 | { |
68dc0745 |
25 | int exitstatus; |
26 | PerlInterpreter *my_perl; |
27 | void *pOldIOSubsystem; |
0a753a76 |
28 | |
68dc0745 |
29 | pOldIOSubsystem = SetIOSubSystem(iosubsystem); |
0a753a76 |
30 | |
31 | PERL_SYS_INIT(&argc,&argv); |
32 | |
33 | perl_init_i18nl10n(1); |
34 | |
68dc0745 |
35 | if (!(my_perl = perl_alloc())) |
36 | return (1); |
37 | perl_construct( my_perl ); |
38 | perl_destruct_level = 0; |
0a753a76 |
39 | |
40 | exitstatus = perl_parse( my_perl, xs_init, argc, argv, env); |
41 | if (!exitstatus) { |
42 | exitstatus = perl_run( my_perl ); |
43 | } |
44 | |
0a753a76 |
45 | perl_destruct( my_perl ); |
46 | perl_free( my_perl ); |
47 | |
48 | PERL_SYS_TERM(); |
49 | |
68dc0745 |
50 | SetIOSubSystem(pOldIOSubsystem); |
0a753a76 |
51 | |
68dc0745 |
52 | return (exitstatus); |
0a753a76 |
53 | } |
54 | |
0a753a76 |
55 | extern HANDLE PerlDllHandle; |
56 | |
68dc0745 |
57 | BOOL APIENTRY |
58 | DllMain(HANDLE hModule, /* DLL module handle */ |
59 | DWORD fdwReason, /* reason called */ |
60 | LPVOID lpvReserved) /* reserved */ |
0a753a76 |
61 | { |
68dc0745 |
62 | switch (fdwReason) { |
63 | /* The DLL is attaching to a process due to process |
64 | * initialization or a call to LoadLibrary. |
65 | */ |
66 | case DLL_PROCESS_ATTACH: |
67 | /* #define DEFAULT_BINMODE */ |
0a753a76 |
68 | #ifdef DEFAULT_BINMODE |
3e3baf6d |
69 | setmode( fileno( stdin ), O_BINARY ); |
70 | setmode( fileno( stdout ), O_BINARY ); |
71 | setmode( fileno( stderr ), O_BINARY ); |
72 | _fmode = O_BINARY; |
0a753a76 |
73 | #endif |
68dc0745 |
74 | PerlDllHandle = hModule; |
75 | break; |
0a753a76 |
76 | |
68dc0745 |
77 | /* The DLL is detaching from a process due to |
78 | * process termination or call to FreeLibrary. |
79 | */ |
80 | case DLL_PROCESS_DETACH: |
81 | break; |
0a753a76 |
82 | |
68dc0745 |
83 | /* The attached process creates a new thread. */ |
84 | case DLL_THREAD_ATTACH: |
85 | break; |
0a753a76 |
86 | |
68dc0745 |
87 | /* The thread of the attached process terminates. */ |
88 | case DLL_THREAD_DETACH: |
89 | break; |
0a753a76 |
90 | |
68dc0745 |
91 | default: |
92 | break; |
93 | } |
94 | return TRUE; |
0a753a76 |
95 | } |
8b10511d |
96 | |
97 | /* Register any extra external extensions */ |
98 | |
99 | char *staticlinkmodules[] = { |
100 | "DynaLoader", |
101 | NULL, |
102 | }; |
103 | |
104 | EXTERN_C void boot_DynaLoader _((CV* cv)); |
105 | |
106 | static |
7bac28a0 |
107 | XS(w32_GetCwd) |
8b10511d |
108 | { |
109 | dXSARGS; |
110 | SV *sv = sv_newmortal(); |
111 | /* Make one call with zero size - return value is required size */ |
112 | DWORD len = GetCurrentDirectory((DWORD)0,NULL); |
113 | SvUPGRADE(sv,SVt_PV); |
114 | SvGROW(sv,len); |
115 | SvCUR(sv) = GetCurrentDirectory((DWORD) SvLEN(sv), SvPVX(sv)); |
116 | /* |
117 | * If result != 0 |
118 | * then it worked, set PV valid, |
119 | * else leave it 'undef' |
120 | */ |
121 | if (SvCUR(sv)) |
122 | SvPOK_on(sv); |
123 | EXTEND(sp,1); |
124 | ST(0) = sv; |
125 | XSRETURN(1); |
126 | } |
127 | |
128 | static |
7bac28a0 |
129 | XS(w32_SetCwd) |
130 | { |
131 | dXSARGS; |
132 | if (items != 1) |
133 | croak("usage: Win32::SetCurrentDirectory($cwd)"); |
134 | if (SetCurrentDirectory(SvPV(ST(0),na))) |
135 | XSRETURN_YES; |
136 | |
137 | XSRETURN_NO; |
138 | } |
139 | |
140 | static |
141 | XS(w32_GetNextAvailDrive) |
142 | { |
143 | dXSARGS; |
144 | char ix = 'C'; |
145 | char root[] = "_:\\"; |
146 | while (ix <= 'Z') { |
147 | root[0] = ix++; |
148 | if (GetDriveType(root) == 1) { |
149 | root[2] = '\0'; |
150 | XSRETURN_PV(root); |
151 | } |
152 | } |
153 | XSRETURN_UNDEF; |
154 | } |
155 | |
156 | static |
8b10511d |
157 | XS(w32_GetLastError) |
158 | { |
7bac28a0 |
159 | dXSARGS; |
160 | XSRETURN_IV(GetLastError()); |
8b10511d |
161 | } |
162 | |
7bac28a0 |
163 | static |
164 | XS(w32_LoginName) |
165 | { |
166 | dXSARGS; |
167 | char name[256]; |
168 | DWORD size = sizeof(name); |
169 | if (GetUserName(name,&size)) { |
170 | /* size includes NULL */ |
171 | ST(0) = sv_2mortal(newSVpv(name,size-1)); |
172 | XSRETURN(1); |
173 | } |
174 | XSRETURN_UNDEF; |
175 | } |
176 | |
177 | static |
178 | XS(w32_NodeName) |
179 | { |
180 | dXSARGS; |
181 | char name[MAX_COMPUTERNAME_LENGTH+1]; |
182 | DWORD size = sizeof(name); |
183 | if (GetComputerName(name,&size)) { |
184 | /* size does NOT include NULL :-( */ |
185 | ST(0) = sv_2mortal(newSVpv(name,size)); |
186 | XSRETURN(1); |
187 | } |
188 | XSRETURN_UNDEF; |
189 | } |
190 | |
191 | |
192 | static |
193 | XS(w32_DomainName) |
194 | { |
195 | dXSARGS; |
196 | char name[256]; |
197 | DWORD size = sizeof(name); |
198 | if (GetUserName(name,&size)) { |
199 | char sid[1024]; |
200 | DWORD sidlen = sizeof(sid); |
201 | char dname[256]; |
202 | DWORD dnamelen = sizeof(dname); |
203 | SID_NAME_USE snu; |
204 | if (LookupAccountName(NULL, name, &sid, &sidlen, |
205 | dname, &dnamelen, &snu)) { |
206 | XSRETURN_PV(dname); /* all that for this */ |
207 | } |
208 | } |
209 | XSRETURN_UNDEF; |
210 | } |
211 | |
212 | static |
213 | XS(w32_FsType) |
214 | { |
215 | dXSARGS; |
216 | char fsname[256]; |
217 | DWORD flags, filecomplen; |
218 | if (GetVolumeInformation(NULL, NULL, 0, NULL, &filecomplen, |
219 | &flags, fsname, sizeof(fsname))) { |
220 | if (GIMME == G_ARRAY) { |
221 | XPUSHs(sv_2mortal(newSVpv(fsname,0))); |
222 | XPUSHs(sv_2mortal(newSViv(flags))); |
223 | XPUSHs(sv_2mortal(newSViv(filecomplen))); |
224 | PUTBACK; |
225 | return; |
226 | } |
227 | XSRETURN_PV(fsname); |
228 | } |
229 | XSRETURN_UNDEF; |
230 | } |
231 | |
232 | static |
233 | XS(w32_GetOSVersion) |
234 | { |
235 | dXSARGS; |
236 | OSVERSIONINFO osver; |
237 | |
238 | osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
239 | if (GetVersionEx(&osver)) { |
240 | XPUSHs(newSVpv(osver.szCSDVersion, 0)); |
241 | XPUSHs(newSViv(osver.dwMajorVersion)); |
242 | XPUSHs(newSViv(osver.dwMinorVersion)); |
243 | XPUSHs(newSViv(osver.dwBuildNumber)); |
244 | XPUSHs(newSViv(osver.dwPlatformId)); |
245 | PUTBACK; |
246 | return; |
247 | } |
248 | XSRETURN_UNDEF; |
249 | } |
250 | |
251 | static |
8b10511d |
252 | XS(w32_IsWinNT) |
253 | { |
7bac28a0 |
254 | dXSARGS; |
255 | XSRETURN_IV(IsWinNT()); |
8b10511d |
256 | } |
257 | |
7bac28a0 |
258 | static |
8b10511d |
259 | XS(w32_IsWin95) |
260 | { |
7bac28a0 |
261 | dXSARGS; |
262 | XSRETURN_IV(IsWin95()); |
263 | } |
264 | |
265 | static |
266 | XS(w32_FormatMessage) |
267 | { |
268 | dXSARGS; |
269 | DWORD source = 0; |
270 | char msgbuf[1024]; |
271 | |
272 | if (items != 1) |
273 | croak("usage: Win32::FormatMessage($errno)"); |
274 | |
275 | if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, |
276 | &source, SvIV(ST(0)), 0, |
277 | msgbuf, sizeof(msgbuf)-1, NULL)) |
278 | XSRETURN_PV(msgbuf); |
279 | |
280 | XSRETURN_UNDEF; |
281 | } |
282 | |
283 | static |
284 | XS(w32_Spawn) |
285 | { |
286 | dXSARGS; |
287 | char *cmd, *args; |
288 | PROCESS_INFORMATION stProcInfo; |
289 | STARTUPINFO stStartInfo; |
290 | BOOL bSuccess = FALSE; |
291 | |
292 | if(items != 3) |
293 | croak("usage: Win32::Spawn($cmdName, $args, $PID)"); |
294 | |
295 | cmd = SvPV(ST(0),na); |
296 | args = SvPV(ST(1), na); |
297 | |
298 | memset(&stStartInfo, 0, sizeof(stStartInfo)); /* Clear the block */ |
299 | stStartInfo.cb = sizeof(stStartInfo); /* Set the structure size */ |
300 | stStartInfo.dwFlags = STARTF_USESHOWWINDOW; /* Enable wShowWindow control */ |
301 | stStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; /* Start min (normal) */ |
302 | |
303 | if(CreateProcess( |
304 | cmd, /* Image path */ |
305 | args, /* Arguments for command line */ |
306 | NULL, /* Default process security */ |
307 | NULL, /* Default thread security */ |
308 | FALSE, /* Must be TRUE to use std handles */ |
309 | NORMAL_PRIORITY_CLASS, /* No special scheduling */ |
310 | NULL, /* Inherit our environment block */ |
311 | NULL, /* Inherit our currrent directory */ |
312 | &stStartInfo, /* -> Startup info */ |
313 | &stProcInfo)) /* <- Process info (if OK) */ |
314 | { |
315 | CloseHandle(stProcInfo.hThread);/* library source code does this. */ |
316 | sv_setiv(ST(2), stProcInfo.dwProcessId); |
317 | bSuccess = TRUE; |
318 | } |
319 | XSRETURN_IV(bSuccess); |
320 | } |
321 | |
322 | static |
323 | XS(w32_GetTickCount) |
324 | { |
325 | dXSARGS; |
326 | XSRETURN_IV(GetTickCount()); |
327 | } |
328 | |
329 | static |
330 | XS(w32_GetShortPathName) |
331 | { |
332 | dXSARGS; |
333 | SV *shortpath; |
334 | |
335 | if(items != 1) |
336 | croak("usage: Win32::GetShortPathName($longPathName)"); |
337 | |
338 | shortpath = sv_mortalcopy(ST(0)); |
339 | SvUPGRADE(shortpath, SVt_PV); |
340 | /* src == target is allowed */ |
341 | if (GetShortPathName(SvPVX(shortpath), SvPVX(shortpath), SvCUR(shortpath))) |
342 | ST(0) = shortpath; |
343 | else |
344 | ST(0) = &sv_undef; |
345 | XSRETURN(1); |
8b10511d |
346 | } |
347 | |
348 | static void |
349 | xs_init() |
350 | { |
351 | char *file = __FILE__; |
352 | dXSUB_SYS; |
353 | newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); |
7bac28a0 |
354 | |
355 | /* XXX should be removed after checking with Nick */ |
356 | newXS("Win32::GetCurrentDirectory", w32_GetCwd, file); |
357 | |
358 | /* these names are Activeware compatible */ |
359 | newXS("Win32::GetCwd", w32_GetCwd, file); |
360 | newXS("Win32::SetCwd", w32_SetCwd, file); |
361 | newXS("Win32::GetNextAvailDrive", w32_GetNextAvailDrive, file); |
8b10511d |
362 | newXS("Win32::GetLastError", w32_GetLastError, file); |
7bac28a0 |
363 | newXS("Win32::LoginName", w32_LoginName, file); |
364 | newXS("Win32::NodeName", w32_NodeName, file); |
365 | newXS("Win32::DomainName", w32_DomainName, file); |
366 | newXS("Win32::FsType", w32_FsType, file); |
367 | newXS("Win32::GetOSVersion", w32_GetOSVersion, file); |
8b10511d |
368 | newXS("Win32::IsWinNT", w32_IsWinNT, file); |
369 | newXS("Win32::IsWin95", w32_IsWin95, file); |
7bac28a0 |
370 | newXS("Win32::FormatMessage", w32_FormatMessage, file); |
371 | newXS("Win32::Spawn", w32_Spawn, file); |
372 | newXS("Win32::GetTickCount", w32_GetTickCount, file); |
373 | newXS("Win32::GetShortPathName", w32_GetShortPathName, file); |
374 | |
375 | /* XXX Bloat Alert! The following Activeware preloads really |
376 | * ought to be part of Win32::Sys::*, so they're not included |
377 | * here. |
378 | */ |
379 | /* LookupAccountName |
380 | * LookupAccountSID |
381 | * InitiateSystemShutdown |
382 | * AbortSystemShutdown |
383 | * ExpandEnvrironmentStrings |
384 | */ |
8b10511d |
385 | } |
386 | |