[differences between cumulative patch application and perl5.004_01]
[p5sagit/p5-mst-13.2.git] / win32 / perllib.c
CommitLineData
0a753a76 1/*
2 * "The Road goes ever on and on, down from the door where it began."
3 */
4
5#ifdef __cplusplus
6extern "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
20static void xs_init _((void));
21
68dc0745 22__declspec(dllexport) int
23RunPerl(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 55extern HANDLE PerlDllHandle;
56
68dc0745 57BOOL APIENTRY
58DllMain(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
99char *staticlinkmodules[] = {
100 "DynaLoader",
101 NULL,
102};
103
104EXTERN_C void boot_DynaLoader _((CV* cv));
105
106static
7bac28a0 107XS(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
128static
7bac28a0 129XS(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
140static
141XS(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
156static
8b10511d 157XS(w32_GetLastError)
158{
7bac28a0 159 dXSARGS;
160 XSRETURN_IV(GetLastError());
8b10511d 161}
162
7bac28a0 163static
164XS(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
177static
178XS(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
192static
193XS(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
212static
213XS(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
232static
233XS(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
251static
8b10511d 252XS(w32_IsWinNT)
253{
7bac28a0 254 dXSARGS;
255 XSRETURN_IV(IsWinNT());
8b10511d 256}
257
7bac28a0 258static
8b10511d 259XS(w32_IsWin95)
260{
7bac28a0 261 dXSARGS;
262 XSRETURN_IV(IsWin95());
263}
264
265static
266XS(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
283static
284XS(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
322static
323XS(w32_GetTickCount)
324{
325 dXSARGS;
326 XSRETURN_IV(GetTickCount());
327}
328
329static
330XS(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
348static void
349xs_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