6 /*#include "patchlevel.h"*/
8 /* Uncomment the next line unless set "WRITE_PERL=>1" in Makefile.PL: */
9 #define NEED_newCONSTSUB
16 #define WIN32_LEAN_AND_MEAN /* Tell windows.h to skip much */
22 #ifndef INVALID_SET_FILE_POINTER
23 # define INVALID_SET_FILE_POINTER ((DWORD)-1)
28 #if (PERL_REVISION <= 5 && PERL_VERSION < 5) || defined(__CYGWIN__)
29 # define win32_get_osfhandle _get_osfhandle
31 # define win32_open_osfhandle(handle,mode) \
32 (Perl_croak(aTHX_ "_open_osfhandle not implemented on Cygwin!"), -1)
34 # define win32_open_osfhandle _open_osfhandle
36 # ifdef _get_osfhandle
37 # undef _get_osfhandle /* stolen_get_osfhandle() isn't available here */
39 # ifdef _open_osfhandle
40 # undef _open_osfhandle /* stolen_open_osfhandle() isn't available here */
45 # define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) )
49 # define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END
53 # define Debug(list) /*Nothing*/
55 # define Debug(list) ErrPrintf list
58 ErrPrintf( const char *sFmt, ... )
61 static char *sEnv= NULL;
62 DWORD uErr= GetLastError();
64 if( NULL == ( sEnv= getenv("DEBUG_WIN32API_FILE") ) )
69 va_start( pAList, sFmt );
70 vfprintf( stderr, sFmt, pAList );
74 #endif /* DEBUGGING */
77 #include "buffers.h" /* Include this after DEBUGGING setup finished */
79 static LONG uLastFileErr= 0;
82 SaveErr( BOOL bFailed )
85 uLastFileErr= GetLastError();
89 MODULE = Win32API::File PACKAGE = Win32API::File
95 _fileLastError( uError=0 )
101 RETVAL= uLastFileErr;
107 CloseHandle( hObject )
110 RETVAL = CloseHandle( hObject );
117 CopyFileA( sOldFileName, sNewFileName, bFailIfExists )
122 RETVAL = CopyFileA( sOldFileName, sNewFileName, bFailIfExists );
129 CopyFileW( swOldFileName, swNewFileName, bFailIfExists )
130 WCHAR * swOldFileName
131 WCHAR * swNewFileName
134 RETVAL = CopyFileW( swOldFileName, swNewFileName, bFailIfExists );
141 CreateFileA( sPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel )
150 RETVAL= CreateFileA( sPath, uAccess, uShare,
151 pSecAttr, uCreate, uFlags, hModel );
152 if( INVALID_HANDLE_VALUE == RETVAL ) {
155 } else if( 0 == RETVAL ) {
156 XSRETURN_PV( "0 but true" );
158 XSRETURN_UV( PTR2UV(RETVAL) );
163 CreateFileW( swPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel )
172 RETVAL= CreateFileW( swPath, uAccess, uShare,
173 pSecAttr, uCreate, uFlags, hModel );
174 if( INVALID_HANDLE_VALUE == RETVAL ) {
177 } else if( 0 == RETVAL ) {
178 XSRETURN_PV( "0 but true" );
180 XSRETURN_UV( PTR2UV(RETVAL) );
185 DefineDosDeviceA( uFlags, sDosDeviceName, sTargetPath )
187 char * sDosDeviceName
190 RETVAL = DefineDosDeviceA( uFlags, sDosDeviceName, sTargetPath );
197 DefineDosDeviceW( uFlags, swDosDeviceName, swTargetPath )
199 WCHAR * swDosDeviceName
202 RETVAL = DefineDosDeviceW( uFlags, swDosDeviceName, swTargetPath );
209 DeleteFileA( sFileName )
212 RETVAL = DeleteFileA( sFileName );
219 DeleteFileW( swFileName )
222 RETVAL = DeleteFileW( swFileName );
229 DeviceIoControl( hDevice, uIoControlCode, pInBuf, lInBuf, opOutBuf, lOutBuf, olRetBytes, pOverlapped )
233 DWORD lInBuf = init_buf_l($arg);
234 char * opOutBuf = NO_INIT
235 DWORD lOutBuf = init_buf_l($arg);
239 if( NULL != pInBuf ) {
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 );
247 grow_buf_l( opOutBuf,ST(4),char *, lOutBuf,ST(5) );
248 RETVAL= DeviceIoControl( hDevice, uIoControlCode, pInBuf, lInBuf,
249 opOutBuf, lOutBuf, &olRetBytes, pOverlapped );
253 opOutBuf trunc_buf_l( RETVAL, opOutBuf,ST(4), olRetBytes );
258 FdGetOsFHandle( ivFd )
261 RETVAL= (HANDLE) win32_get_osfhandle( ivFd );
262 SaveErr( INVALID_HANDLE_VALUE == RETVAL );
268 GetDriveTypeA( sRootPath )
271 RETVAL = GetDriveTypeA( sRootPath );
278 GetDriveTypeW( swRootPath )
281 RETVAL = GetDriveTypeW( swRootPath );
288 GetFileAttributesA( sPath )
291 RETVAL = GetFileAttributesA( sPath );
298 GetFileAttributesW( swPath )
301 RETVAL = GetFileAttributesW( swPath );
311 RETVAL = GetFileType( hFile );
318 GetHandleInformation( hObject, ouFlags )
322 RETVAL = GetHandleInformation( hObject, ouFlags );
332 RETVAL = GetLogicalDrives();
339 GetLogicalDriveStringsA( lBufSize, osBuffer )
340 DWORD lBufSize = init_buf_l($arg);
341 char * osBuffer = NO_INIT
343 grow_buf_l( osBuffer,ST(1),char *, lBufSize,ST(0) );
344 RETVAL= GetLogicalDriveStringsA( lBufSize, osBuffer );
345 if( lBufSize < RETVAL && autosize(ST(0)) ) {
347 grow_buf_l( osBuffer,ST(1),char *, lBufSize,ST(0) );
348 RETVAL= GetLogicalDriveStringsA( lBufSize, osBuffer );
350 if( 0 == RETVAL || lBufSize < RETVAL ) {
353 trunc_buf_l( 1, osBuffer,ST(1), RETVAL );
357 osBuffer ;/* The code for this appears above. */
361 GetLogicalDriveStringsW( lwBufSize, oswBuffer )
362 DWORD lwBufSize = init_buf_lw($arg);
363 WCHAR * oswBuffer = NO_INIT
365 grow_buf_lw( oswBuffer,ST(1), lwBufSize,ST(0) );
366 RETVAL= GetLogicalDriveStringsW( lwBufSize, oswBuffer );
367 if( lwBufSize < RETVAL && autosize(ST(0)) ) {
369 grow_buf_lw( oswBuffer,ST(1), lwBufSize,ST(0) );
370 RETVAL= GetLogicalDriveStringsW( lwBufSize, oswBuffer );
372 if( 0 == RETVAL || lwBufSize < RETVAL ) {
375 trunc_buf_lw( 1, oswBuffer,ST(1), RETVAL );
379 oswBuffer ;/* The code for this appears above. */
383 GetVolumeInformationA( sRootPath, osVolName, lVolName, ouSerialNum, ouMaxNameLen, ouFsFlags, osFsType, lFsType )
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);
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 );
400 osVolName trunc_buf_z( RETVAL, osVolName,ST(1) );
401 osFsType trunc_buf_z( RETVAL, osFsType,ST(6) );
408 GetVolumeInformationW( swRootPath, oswVolName, lwVolName, ouSerialNum, ouMaxNameLen, ouFsFlags, oswFsType, lwFsType )
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);
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 );
425 oswVolName trunc_buf_zw( RETVAL, oswVolName,ST(1) );
426 oswFsType trunc_buf_zw( RETVAL, oswFsType,ST(6) );
433 IsRecognizedPartition( ivPartitionType )
436 RETVAL = IsRecognizedPartition( ivPartitionType );
443 IsContainerPartition( ivPartitionType )
446 RETVAL = IsContainerPartition( ivPartitionType );
453 MoveFileA( sOldName, sNewName )
457 RETVAL = MoveFileA( sOldName, sNewName );
464 MoveFileW( swOldName, swNewName )
468 RETVAL = MoveFileW( swOldName, swNewName );
475 MoveFileExA( sOldName, sNewName, uFlags )
480 RETVAL = MoveFileExA( sOldName, sNewName, uFlags );
487 MoveFileExW( swOldName, swNewName, uFlags )
492 RETVAL = MoveFileExW( swOldName, swNewName, uFlags );
499 OsFHandleOpenFd( hOsFHandle, uMode )
503 RETVAL= win32_open_osfhandle( hOsFHandle, uMode );
507 } else if( 0 == RETVAL ) {
508 XSRETURN_PV( "0 but true" );
510 XSRETURN_IV( (IV) RETVAL );
515 QueryDosDeviceA( sDeviceName, osTargetPath, lTargetBuf )
517 char * osTargetPath = NO_INIT
518 DWORD lTargetBuf = init_buf_l($arg);
520 grow_buf_l( osTargetPath,ST(1),char *, lTargetBuf,ST(2) );
521 RETVAL= QueryDosDeviceA( sDeviceName, osTargetPath, lTargetBuf );
522 SaveErr( 0 == RETVAL );
525 osTargetPath trunc_buf_l( 1, osTargetPath,ST(1), RETVAL );
529 QueryDosDeviceW( swDeviceName, oswTargetPath, lwTargetBuf )
531 WCHAR * oswTargetPath = NO_INIT
532 DWORD lwTargetBuf = init_buf_lw($arg);
534 grow_buf_lw( oswTargetPath,ST(1), lwTargetBuf,ST(2) );
535 RETVAL= QueryDosDeviceW( swDeviceName, oswTargetPath, lwTargetBuf );
536 SaveErr( 0 == RETVAL );
539 oswTargetPath trunc_buf_lw( 1, oswTargetPath,ST(1), RETVAL );
543 ReadFile( hFile, opBuffer, lBytes, olBytesRead, pOverlapped )
545 BYTE * opBuffer = NO_INIT
546 DWORD lBytes = init_buf_l($arg);
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;
556 RETVAL= ReadFile( hFile, opBuffer, lBytes, &olBytesRead, pOverlapped );
560 opBuffer trunc_buf_l( RETVAL, opBuffer,ST(1), olBytesRead );
565 GetOverlappedResult( hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait)
567 LPOVERLAPPED lpOverlapped
568 LPDWORD lpNumberOfBytesTransferred
571 RETVAL= GetOverlappedResult( hFile, lpOverlapped,
572 lpNumberOfBytesTransferred, bWait);
577 lpNumberOfBytesTransferred
580 GetFileSize( hFile, lpFileSizeHigh )
582 LPDWORD lpFileSizeHigh
584 RETVAL= GetFileSize( hFile, lpFileSizeHigh );
585 SaveErr( NO_ERROR != GetLastError() );
591 SetErrorMode( uNewMode )
596 SetFilePointer( hFile, ivOffset, ioivOffsetHigh, uFromWhere )
599 LONG * ioivOffsetHigh
602 RETVAL= SetFilePointer( hFile, ivOffset, ioivOffsetHigh, uFromWhere );
603 if( RETVAL == INVALID_SET_FILE_POINTER && (GetLastError() != NO_ERROR) ) {
606 } else if( 0 == RETVAL ) {
607 XST_mPV(0,"0 but true");
616 SetHandleInformation( hObject, uMask, uFlags )
621 RETVAL = SetHandleInformation( hObject, uMask, uFlags );
628 WriteFile( hFile, pBuffer, lBytes, ouBytesWritten, pOverlapped )
631 DWORD lBytes = init_buf_l($arg);
632 oDWORD &ouBytesWritten
635 /* SvCUR(ST(1)) might "panic" if pBuffer isn't valid */
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 );
642 RETVAL= WriteFile( hFile, pBuffer, lBytes,
643 &ouBytesWritten, pOverlapped );