This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
utf8.c: Fix warning category and subcategory conflicts
[perl5.git] / cpan / Win32API-File / File.xs
CommitLineData
00701878
SH
1/* Win32API/File.xs */
2
3#include "EXTERN.h"
4#include "perl.h"
5#include "XSUB.h"
6/*#include "patchlevel.h"*/
7
8/* Uncomment the next line unless set "WRITE_PERL=>1" in Makefile.PL: */
9#define NEED_newCONSTSUB
10#include "ppport.h"
11
12#ifdef WORD
13# undef WORD
14#endif
15
16#define WIN32_LEAN_AND_MEAN /* Tell windows.h to skip much */
17#include <windows.h>
18#include <winioctl.h>
19
20/*CONSTS_DEFINED*/
21
22#ifndef INVALID_SET_FILE_POINTER
23# define INVALID_SET_FILE_POINTER ((DWORD)-1)
24#endif
25
26#define oDWORD DWORD
27
28#if (PERL_REVISION <= 5 && PERL_VERSION < 5) || defined(__CYGWIN__)
29# define win32_get_osfhandle _get_osfhandle
30# ifdef __CYGWIN__
31# define win32_open_osfhandle(handle,mode) \
32 (Perl_croak(aTHX_ "_open_osfhandle not implemented on Cygwin!"), -1)
33# else
34# define win32_open_osfhandle _open_osfhandle
35# endif
36# ifdef _get_osfhandle
37# undef _get_osfhandle /* stolen_get_osfhandle() isn't available here */
38# endif
39# ifdef _open_osfhandle
40# undef _open_osfhandle /* stolen_open_osfhandle() isn't available here */
41# endif
42#endif
43
44#ifndef XST_mUV
45# define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) )
46#endif
47
48#ifndef XSRETURN_UV
49# define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END
50#endif
51
52#ifndef DEBUGGING
53# define Debug(list) /*Nothing*/
54#else
55# define Debug(list) ErrPrintf list
56# include <stdarg.h>
57 static void
58 ErrPrintf( const char *sFmt, ... )
59 {
60 va_list pAList;
61 static char *sEnv= NULL;
62 DWORD uErr= GetLastError();
63 if( NULL == sEnv ) {
64 if( NULL == ( sEnv= getenv("DEBUG_WIN32API_FILE") ) )
65 sEnv= "";
66 }
67 if( '\0' == *sEnv )
68 return;
69 va_start( pAList, sFmt );
70 vfprintf( stderr, sFmt, pAList );
71 va_end( pAList );
72 SetLastError( uErr );
73 }
74#endif /* DEBUGGING */
75
76
77#include "buffers.h" /* Include this after DEBUGGING setup finished */
78
79static LONG uLastFileErr= 0;
80
81static void
82SaveErr( BOOL bFailed )
83{
84 if( bFailed ) {
85 uLastFileErr= GetLastError();
86 }
87}
88
89MODULE = Win32API::File PACKAGE = Win32API::File
90
91PROTOTYPES: DISABLE
92
93
94LONG
95_fileLastError( uError=0 )
96 DWORD uError
97 CODE:
98 if( 1 <= items ) {
99 uLastFileErr= uError;
100 }
101 RETVAL= uLastFileErr;
102 OUTPUT:
103 RETVAL
104
105
106BOOL
107CloseHandle( hObject )
108 HANDLE hObject
109 CODE:
110 RETVAL = CloseHandle( hObject );
111 SaveErr( !RETVAL );
112 OUTPUT:
113 RETVAL
114
115
116BOOL
117CopyFileA( sOldFileName, sNewFileName, bFailIfExists )
118 char * sOldFileName
119 char * sNewFileName
120 BOOL bFailIfExists
121 CODE:
122 RETVAL = CopyFileA( sOldFileName, sNewFileName, bFailIfExists );
123 SaveErr( !RETVAL );
124 OUTPUT:
125 RETVAL
126
127
128BOOL
129CopyFileW( swOldFileName, swNewFileName, bFailIfExists )
130 WCHAR * swOldFileName
131 WCHAR * swNewFileName
132 BOOL bFailIfExists
133 CODE:
134 RETVAL = CopyFileW( swOldFileName, swNewFileName, bFailIfExists );
135 SaveErr( !RETVAL );
136 OUTPUT:
137 RETVAL
138
139
140HANDLE
141CreateFileA( sPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel )
142 char * sPath
143 DWORD uAccess
144 DWORD uShare
145 void * pSecAttr
146 DWORD uCreate
147 DWORD uFlags
148 HANDLE hModel
149 CODE:
150 RETVAL= CreateFileA( sPath, uAccess, uShare,
151 pSecAttr, uCreate, uFlags, hModel );
152 if( INVALID_HANDLE_VALUE == RETVAL ) {
153 SaveErr( 1 );
154 XSRETURN_NO;
155 } else if( 0 == RETVAL ) {
156 XSRETURN_PV( "0 but true" );
157 } else {
158 XSRETURN_UV( PTR2UV(RETVAL) );
159 }
160
161
162HANDLE
163CreateFileW( swPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel )
164 WCHAR * swPath
165 DWORD uAccess
166 DWORD uShare
167 void * pSecAttr
168 DWORD uCreate
169 DWORD uFlags
170 HANDLE hModel
171 CODE:
172 RETVAL= CreateFileW( swPath, uAccess, uShare,
173 pSecAttr, uCreate, uFlags, hModel );
174 if( INVALID_HANDLE_VALUE == RETVAL ) {
175 SaveErr( 1 );
176 XSRETURN_NO;
177 } else if( 0 == RETVAL ) {
178 XSRETURN_PV( "0 but true" );
179 } else {
180 XSRETURN_UV( PTR2UV(RETVAL) );
181 }
182
183
184BOOL
185DefineDosDeviceA( uFlags, sDosDeviceName, sTargetPath )
186 DWORD uFlags
187 char * sDosDeviceName
188 char * sTargetPath
189 CODE:
190 RETVAL = DefineDosDeviceA( uFlags, sDosDeviceName, sTargetPath );
191 SaveErr( !RETVAL );
192 OUTPUT:
193 RETVAL
194
195
196BOOL
197DefineDosDeviceW( uFlags, swDosDeviceName, swTargetPath )
198 DWORD uFlags
199 WCHAR * swDosDeviceName
200 WCHAR * swTargetPath
201 CODE:
202 RETVAL = DefineDosDeviceW( uFlags, swDosDeviceName, swTargetPath );
203 SaveErr( !RETVAL );
204 OUTPUT:
205 RETVAL
206
207
208BOOL
209DeleteFileA( sFileName )
210 char * sFileName
211 CODE:
212 RETVAL = DeleteFileA( sFileName );
213 SaveErr( !RETVAL );
214 OUTPUT:
215 RETVAL
216
217
218BOOL
219DeleteFileW( swFileName )
220 WCHAR * swFileName
221 CODE:
222 RETVAL = DeleteFileW( swFileName );
223 SaveErr( !RETVAL );
224 OUTPUT:
225 RETVAL
226
227
228BOOL
229DeviceIoControl( hDevice, uIoControlCode, pInBuf, lInBuf, opOutBuf, lOutBuf, olRetBytes, pOverlapped )
230 HANDLE hDevice
231 DWORD uIoControlCode
232 char * pInBuf
233 DWORD lInBuf = init_buf_l($arg);
234 char * opOutBuf = NO_INIT
235 DWORD lOutBuf = init_buf_l($arg);
236 oDWORD &olRetBytes
237 void * pOverlapped
238 CODE:
239 if( NULL != pInBuf ) {
240 if( 0 == lInBuf ) {
241 lInBuf= SvCUR(ST(2));
242 } else if( SvCUR(ST(2)) < lInBuf ) {
243 croak( "%s: pInBuf shorter than specified (%d < %d)",
244 "Win32API::File::DeviceIoControl", SvCUR(ST(2)), lInBuf );
245 }
246 }
247 grow_buf_l( opOutBuf,ST(4),char *, lOutBuf,ST(5) );
248 RETVAL= DeviceIoControl( hDevice, uIoControlCode, pInBuf, lInBuf,
249 opOutBuf, lOutBuf, &olRetBytes, pOverlapped );
250 SaveErr( !RETVAL );
251 OUTPUT:
252 RETVAL
253 opOutBuf trunc_buf_l( RETVAL, opOutBuf,ST(4), olRetBytes );
254 olRetBytes
255
256
257HANDLE
258FdGetOsFHandle( ivFd )
259 int ivFd
260 CODE:
261 RETVAL= (HANDLE) win32_get_osfhandle( ivFd );
262 SaveErr( INVALID_HANDLE_VALUE == RETVAL );
263 OUTPUT:
264 RETVAL
265
266
267DWORD
268GetDriveTypeA( sRootPath )
269 char * sRootPath
270 CODE:
271 RETVAL = GetDriveTypeA( sRootPath );
272 SaveErr( !RETVAL );
273 OUTPUT:
274 RETVAL
275
276
277DWORD
278GetDriveTypeW( swRootPath )
279 WCHAR * swRootPath
280 CODE:
281 RETVAL = GetDriveTypeW( swRootPath );
282 SaveErr( !RETVAL );
283 OUTPUT:
284 RETVAL
285
286
287DWORD
288GetFileAttributesA( sPath )
289 char * sPath
290 CODE:
291 RETVAL = GetFileAttributesA( sPath );
292 SaveErr( !RETVAL );
293 OUTPUT:
294 RETVAL
295
296
297DWORD
298GetFileAttributesW( swPath )
299 WCHAR * swPath
300 CODE:
301 RETVAL = GetFileAttributesW( swPath );
302 SaveErr( !RETVAL );
303 OUTPUT:
304 RETVAL
305
306
307DWORD
308GetFileType( hFile )
309 HANDLE hFile
310 CODE:
311 RETVAL = GetFileType( hFile );
312 SaveErr( !RETVAL );
313 OUTPUT:
314 RETVAL
315
316
317BOOL
318GetHandleInformation( hObject, ouFlags )
319 HANDLE hObject
320 oDWORD * ouFlags
321 CODE:
322 RETVAL = GetHandleInformation( hObject, ouFlags );
323 SaveErr( !RETVAL );
324 OUTPUT:
325 RETVAL
326 ouFlags
327
328
329DWORD
330GetLogicalDrives()
331 CODE:
332 RETVAL = GetLogicalDrives();
333 SaveErr( !RETVAL );
334 OUTPUT:
335 RETVAL
336
337
338DWORD
339GetLogicalDriveStringsA( lBufSize, osBuffer )
340 DWORD lBufSize = init_buf_l($arg);
341 char * osBuffer = NO_INIT
342 CODE:
343 grow_buf_l( osBuffer,ST(1),char *, lBufSize,ST(0) );
344 RETVAL= GetLogicalDriveStringsA( lBufSize, osBuffer );
345 if( lBufSize < RETVAL && autosize(ST(0)) ) {
346 lBufSize= RETVAL;
347 grow_buf_l( osBuffer,ST(1),char *, lBufSize,ST(0) );
348 RETVAL= GetLogicalDriveStringsA( lBufSize, osBuffer );
349 }
350 if( 0 == RETVAL || lBufSize < RETVAL ) {
351 SaveErr( 1 );
352 } else {
353 trunc_buf_l( 1, osBuffer,ST(1), RETVAL );
354 }
355 OUTPUT:
356 RETVAL
357 osBuffer ;/* The code for this appears above. */
358
359
360DWORD
361GetLogicalDriveStringsW( lwBufSize, oswBuffer )
362 DWORD lwBufSize = init_buf_lw($arg);
363 WCHAR * oswBuffer = NO_INIT
364 CODE:
365 grow_buf_lw( oswBuffer,ST(1), lwBufSize,ST(0) );
366 RETVAL= GetLogicalDriveStringsW( lwBufSize, oswBuffer );
367 if( lwBufSize < RETVAL && autosize(ST(0)) ) {
368 lwBufSize= RETVAL;
369 grow_buf_lw( oswBuffer,ST(1), lwBufSize,ST(0) );
370 RETVAL= GetLogicalDriveStringsW( lwBufSize, oswBuffer );
371 }
372 if( 0 == RETVAL || lwBufSize < RETVAL ) {
373 SaveErr( 1 );
374 } else {
375 trunc_buf_lw( 1, oswBuffer,ST(1), RETVAL );
376 }
377 OUTPUT:
378 RETVAL
379 oswBuffer ;/* The code for this appears above. */
380
381
382BOOL
383GetVolumeInformationA( sRootPath, osVolName, lVolName, ouSerialNum, ouMaxNameLen, ouFsFlags, osFsType, lFsType )
384 char * sRootPath
385 char * osVolName = NO_INIT
386 DWORD lVolName = init_buf_l($arg);
387 oDWORD &ouSerialNum = optUV($arg);
388 oDWORD &ouMaxNameLen = optUV($arg);
389 oDWORD &ouFsFlags = optUV($arg);
390 char * osFsType = NO_INIT
391 DWORD lFsType = init_buf_l($arg);
392 CODE:
393 grow_buf_l( osVolName,ST(1),char *, lVolName,ST(2) );
394 grow_buf_l( osFsType,ST(6),char *, lFsType,ST(7) );
395 RETVAL= GetVolumeInformationA( sRootPath, osVolName, lVolName,
396 &ouSerialNum, &ouMaxNameLen, &ouFsFlags, osFsType, lFsType );
397 SaveErr( !RETVAL );
398 OUTPUT:
399 RETVAL
400 osVolName trunc_buf_z( RETVAL, osVolName,ST(1) );
401 osFsType trunc_buf_z( RETVAL, osFsType,ST(6) );
402 ouSerialNum
403 ouMaxNameLen
404 ouFsFlags
405
406
407BOOL
408GetVolumeInformationW( swRootPath, oswVolName, lwVolName, ouSerialNum, ouMaxNameLen, ouFsFlags, oswFsType, lwFsType )
409 WCHAR * swRootPath
410 WCHAR * oswVolName = NO_INIT
411 DWORD lwVolName = init_buf_lw($arg);
412 oDWORD &ouSerialNum = optUV($arg);
413 oDWORD &ouMaxNameLen = optUV($arg);
414 oDWORD &ouFsFlags = optUV($arg);
415 WCHAR * oswFsType = NO_INIT
416 DWORD lwFsType = init_buf_lw($arg);
417 CODE:
418 grow_buf_lw( oswVolName,ST(1), lwVolName,ST(2) );
419 grow_buf_lw( oswFsType,ST(6), lwFsType,ST(7) );
420 RETVAL= GetVolumeInformationW( swRootPath, oswVolName, lwVolName,
421 &ouSerialNum, &ouMaxNameLen, &ouFsFlags, oswFsType, lwFsType );
422 SaveErr( !RETVAL );
423 OUTPUT:
424 RETVAL
425 oswVolName trunc_buf_zw( RETVAL, oswVolName,ST(1) );
426 oswFsType trunc_buf_zw( RETVAL, oswFsType,ST(6) );
427 ouSerialNum
428 ouMaxNameLen
429 ouFsFlags
430
431
432BOOL
433IsRecognizedPartition( ivPartitionType )
434 int ivPartitionType
435 CODE:
436 RETVAL = IsRecognizedPartition( ivPartitionType );
437 SaveErr( !RETVAL );
438 OUTPUT:
439 RETVAL
440
441
442BOOL
443IsContainerPartition( ivPartitionType )
444 int ivPartitionType
445 CODE:
446 RETVAL = IsContainerPartition( ivPartitionType );
447 SaveErr( !RETVAL );
448 OUTPUT:
449 RETVAL
450
451
452BOOL
453MoveFileA( sOldName, sNewName )
454 char * sOldName
455 char * sNewName
456 CODE:
457 RETVAL = MoveFileA( sOldName, sNewName );
458 SaveErr( !RETVAL );
459 OUTPUT:
460 RETVAL
461
462
463BOOL
464MoveFileW( swOldName, swNewName )
465 WCHAR * swOldName
466 WCHAR * swNewName
467 CODE:
468 RETVAL = MoveFileW( swOldName, swNewName );
469 SaveErr( !RETVAL );
470 OUTPUT:
471 RETVAL
472
473
474BOOL
475MoveFileExA( sOldName, sNewName, uFlags )
476 char * sOldName
477 char * sNewName
478 DWORD uFlags
479 CODE:
480 RETVAL = MoveFileExA( sOldName, sNewName, uFlags );
481 SaveErr( !RETVAL );
482 OUTPUT:
483 RETVAL
484
485
486BOOL
487MoveFileExW( swOldName, swNewName, uFlags )
488 WCHAR * swOldName
489 WCHAR * swNewName
490 DWORD uFlags
491 CODE:
492 RETVAL = MoveFileExW( swOldName, swNewName, uFlags );
493 SaveErr( !RETVAL );
494 OUTPUT:
495 RETVAL
496
497
498long
499OsFHandleOpenFd( hOsFHandle, uMode )
500 long hOsFHandle
501 DWORD uMode
502 CODE:
503 RETVAL= win32_open_osfhandle( hOsFHandle, uMode );
504 if( RETVAL < 0 ) {
505 SaveErr( 1 );
506 XSRETURN_NO;
507 } else if( 0 == RETVAL ) {
508 XSRETURN_PV( "0 but true" );
509 } else {
510 XSRETURN_IV( (IV) RETVAL );
511 }
512
513
514DWORD
515QueryDosDeviceA( sDeviceName, osTargetPath, lTargetBuf )
516 char * sDeviceName
517 char * osTargetPath = NO_INIT
518 DWORD lTargetBuf = init_buf_l($arg);
519 CODE:
520 grow_buf_l( osTargetPath,ST(1),char *, lTargetBuf,ST(2) );
521 RETVAL= QueryDosDeviceA( sDeviceName, osTargetPath, lTargetBuf );
522 SaveErr( 0 == RETVAL );
523 OUTPUT:
524 RETVAL
525 osTargetPath trunc_buf_l( 1, osTargetPath,ST(1), RETVAL );
526
527
528DWORD
529QueryDosDeviceW( swDeviceName, oswTargetPath, lwTargetBuf )
530 WCHAR * swDeviceName
531 WCHAR * oswTargetPath = NO_INIT
532 DWORD lwTargetBuf = init_buf_lw($arg);
533 CODE:
534 grow_buf_lw( oswTargetPath,ST(1), lwTargetBuf,ST(2) );
535 RETVAL= QueryDosDeviceW( swDeviceName, oswTargetPath, lwTargetBuf );
536 SaveErr( 0 == RETVAL );
537 OUTPUT:
538 RETVAL
539 oswTargetPath trunc_buf_lw( 1, oswTargetPath,ST(1), RETVAL );
540
541
542BOOL
543ReadFile( hFile, opBuffer, lBytes, olBytesRead, pOverlapped )
544 HANDLE hFile
545 BYTE * opBuffer = NO_INIT
546 DWORD lBytes = init_buf_l($arg);
547 oDWORD &olBytesRead
548 void * pOverlapped
549 CODE:
550 grow_buf_l( opBuffer,ST(1),BYTE *, lBytes,ST(2) );
551 /* Don't read more bytes than asked for if buffer is already big: */
552 lBytes= init_buf_l(ST(2));
553 if( 0 == lBytes && autosize(ST(2)) ) {
554 lBytes= SvLEN( ST(1) ) - 1;
555 }
556 RETVAL= ReadFile( hFile, opBuffer, lBytes, &olBytesRead, pOverlapped );
557 SaveErr( !RETVAL );
558 OUTPUT:
559 RETVAL
560 opBuffer trunc_buf_l( RETVAL, opBuffer,ST(1), olBytesRead );
561 olBytesRead
562
563
564BOOL
565GetOverlappedResult( hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait)
566 HANDLE hFile
567 LPOVERLAPPED lpOverlapped
568 LPDWORD lpNumberOfBytesTransferred
569 BOOL bWait
570 CODE:
571 RETVAL= GetOverlappedResult( hFile, lpOverlapped,
572 lpNumberOfBytesTransferred, bWait);
573 SaveErr( !RETVAL );
574 OUTPUT:
575 RETVAL
576 lpOverlapped
577 lpNumberOfBytesTransferred
578
579DWORD
580GetFileSize( hFile, lpFileSizeHigh )
581 HANDLE hFile
582 LPDWORD lpFileSizeHigh
583 CODE:
584 RETVAL= GetFileSize( hFile, lpFileSizeHigh );
585 SaveErr( NO_ERROR != GetLastError() );
586 OUTPUT:
587 RETVAL
588 lpFileSizeHigh
589
590UINT
591SetErrorMode( uNewMode )
592 UINT uNewMode
593
594
595LONG
596SetFilePointer( hFile, ivOffset, ioivOffsetHigh, uFromWhere )
597 HANDLE hFile
598 LONG ivOffset
599 LONG * ioivOffsetHigh
600 DWORD uFromWhere
601 CODE:
602 RETVAL= SetFilePointer( hFile, ivOffset, ioivOffsetHigh, uFromWhere );
603 if( RETVAL == INVALID_SET_FILE_POINTER && (GetLastError() != NO_ERROR) ) {
604 SaveErr( 1 );
605 XST_mNO(0);
606 } else if( 0 == RETVAL ) {
607 XST_mPV(0,"0 but true");
608 } else {
609 XST_mIV(0,RETVAL);
610 }
611 OUTPUT:
612 ioivOffsetHigh
613
614
615BOOL
616SetHandleInformation( hObject, uMask, uFlags )
617 HANDLE hObject
618 DWORD uMask
619 DWORD uFlags
620 CODE:
621 RETVAL = SetHandleInformation( hObject, uMask, uFlags );
622 SaveErr( !RETVAL );
623 OUTPUT:
624 RETVAL
625
626
627BOOL
628WriteFile( hFile, pBuffer, lBytes, ouBytesWritten, pOverlapped )
629 HANDLE hFile
630 BYTE * pBuffer
631 DWORD lBytes = init_buf_l($arg);
632 oDWORD &ouBytesWritten
633 void * pOverlapped
634 CODE:
635 /* SvCUR(ST(1)) might "panic" if pBuffer isn't valid */
636 if( 0 == lBytes ) {
637 lBytes= SvCUR(ST(1));
638 } else if( SvCUR(ST(1)) < lBytes ) {
639 croak( "%s: pBuffer value too short (%d < %d)",
640 "Win32API::File::WriteFile", SvCUR(ST(1)), lBytes );
641 }
642 RETVAL= WriteFile( hFile, pBuffer, lBytes,
643 &ouBytesWritten, pOverlapped );
644 SaveErr( !RETVAL );
645 OUTPUT:
646 RETVAL
647 ouBytesWritten
00f02a57
CBW
648
649void
650GetStdHandle(fd)
651 DWORD fd
652PPCODE:
653#ifdef _WIN64
654 XSRETURN_IV((DWORD_PTR)GetStdHandle(fd));
655#else
656 XSRETURN_IV((DWORD)GetStdHandle(fd));
657#endif
658
659void
660SetStdHandle(fd,handle)
661 DWORD fd
662 HANDLE handle
663PPCODE:
664 if (SetStdHandle(fd, handle))
665 XSRETURN_YES;
666 else
667 XSRETURN_NO;