📄 file.xs
字号:
/* Win32API/File.xs */#include "EXTERN.h"#include "perl.h"#include "XSUB.h"/*#include "patchlevel.h"*//* Uncomment the next line unless set "WRITE_PERL=>1" in Makefile.PL: */#define NEED_newCONSTSUB#include "ppport.h"#ifdef WORD# undef WORD#endif#define WIN32_LEAN_AND_MEAN /* Tell windows.h to skip much */#include <windows.h>#include <winioctl.h>/*CONSTS_DEFINED*/#ifndef INVALID_SET_FILE_POINTER# define INVALID_SET_FILE_POINTER ((DWORD)-1)#endif#define oDWORD DWORD#if (PERL_REVISION <= 5 && PERL_VERSION < 5) || defined(__CYGWIN__)# define win32_get_osfhandle _get_osfhandle# ifdef __CYGWIN__# define win32_open_osfhandle(handle,mode) \ (Perl_croak(aTHX_ "_open_osfhandle not implemented on Cygwin!"), -1)# else# define win32_open_osfhandle _open_osfhandle# endif# ifdef _get_osfhandle# undef _get_osfhandle /* stolen_get_osfhandle() isn't available here */# endif# ifdef _open_osfhandle# undef _open_osfhandle /* stolen_open_osfhandle() isn't available here */# endif#endif#ifndef XST_mUV# define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) )#endif#ifndef XSRETURN_UV# define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END#endif#ifndef DEBUGGING# define Debug(list) /*Nothing*/#else# define Debug(list) ErrPrintf list# include <stdarg.h> static void ErrPrintf( const char *sFmt, ... ) { va_list pAList; static char *sEnv= NULL; DWORD uErr= GetLastError(); if( NULL == sEnv ) { if( NULL == ( sEnv= getenv("DEBUG_WIN32API_FILE") ) ) sEnv= ""; } if( '\0' == *sEnv ) return; va_start( pAList, sFmt ); vfprintf( stderr, sFmt, pAList ); va_end( pAList ); SetLastError( uErr ); }#endif /* DEBUGGING */#include "buffers.h" /* Include this after DEBUGGING setup finished */static LONG uLastFileErr= 0;static voidSaveErr( BOOL bFailed ){ if( bFailed ) { uLastFileErr= GetLastError(); }}MODULE = Win32API::File PACKAGE = Win32API::FilePROTOTYPES: DISABLELONG_fileLastError( uError=0 ) DWORD uError CODE: if( 1 <= items ) { uLastFileErr= uError; } RETVAL= uLastFileErr; OUTPUT: RETVALBOOLCloseHandle( hObject ) HANDLE hObject CODE: RETVAL = CloseHandle( hObject ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLCopyFileA( sOldFileName, sNewFileName, bFailIfExists ) char * sOldFileName char * sNewFileName BOOL bFailIfExists CODE: RETVAL = CopyFileA( sOldFileName, sNewFileName, bFailIfExists ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLCopyFileW( swOldFileName, swNewFileName, bFailIfExists ) WCHAR * swOldFileName WCHAR * swNewFileName BOOL bFailIfExists CODE: RETVAL = CopyFileW( swOldFileName, swNewFileName, bFailIfExists ); SaveErr( !RETVAL ); OUTPUT: RETVALHANDLECreateFileA( sPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel ) char * sPath DWORD uAccess DWORD uShare void * pSecAttr DWORD uCreate DWORD uFlags HANDLE hModel CODE: RETVAL= CreateFileA( sPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel ); if( INVALID_HANDLE_VALUE == RETVAL ) { SaveErr( 1 ); XSRETURN_NO; } else if( 0 == RETVAL ) { XSRETURN_PV( "0 but true" ); } else { XSRETURN_UV( PTR2UV(RETVAL) ); }HANDLECreateFileW( swPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel ) WCHAR * swPath DWORD uAccess DWORD uShare void * pSecAttr DWORD uCreate DWORD uFlags HANDLE hModel CODE: RETVAL= CreateFileW( swPath, uAccess, uShare, pSecAttr, uCreate, uFlags, hModel ); if( INVALID_HANDLE_VALUE == RETVAL ) { SaveErr( 1 ); XSRETURN_NO; } else if( 0 == RETVAL ) { XSRETURN_PV( "0 but true" ); } else { XSRETURN_UV( PTR2UV(RETVAL) ); }BOOLDefineDosDeviceA( uFlags, sDosDeviceName, sTargetPath ) DWORD uFlags char * sDosDeviceName char * sTargetPath CODE: RETVAL = DefineDosDeviceA( uFlags, sDosDeviceName, sTargetPath ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLDefineDosDeviceW( uFlags, swDosDeviceName, swTargetPath ) DWORD uFlags WCHAR * swDosDeviceName WCHAR * swTargetPath CODE: RETVAL = DefineDosDeviceW( uFlags, swDosDeviceName, swTargetPath ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLDeleteFileA( sFileName ) char * sFileName CODE: RETVAL = DeleteFileA( sFileName ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLDeleteFileW( swFileName ) WCHAR * swFileName CODE: RETVAL = DeleteFileW( swFileName ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLDeviceIoControl( hDevice, uIoControlCode, pInBuf, lInBuf, opOutBuf, lOutBuf, olRetBytes, pOverlapped ) HANDLE hDevice DWORD uIoControlCode char * pInBuf DWORD lInBuf = init_buf_l($arg); char * opOutBuf = NO_INIT DWORD lOutBuf = init_buf_l($arg); oDWORD &olRetBytes void * pOverlapped CODE: if( NULL != pInBuf ) { if( 0 == lInBuf ) { lInBuf= SvCUR(ST(2)); } else if( SvCUR(ST(2)) < lInBuf ) { croak( "%s: pInBuf shorter than specified (%d < %d)", "Win32API::File::DeviceIoControl", SvCUR(ST(2)), lInBuf ); } } grow_buf_l( opOutBuf,ST(4),char *, lOutBuf,ST(5) ); RETVAL= DeviceIoControl( hDevice, uIoControlCode, pInBuf, lInBuf, opOutBuf, lOutBuf, &olRetBytes, pOverlapped ); SaveErr( !RETVAL ); OUTPUT: RETVAL opOutBuf trunc_buf_l( RETVAL, opOutBuf,ST(4), olRetBytes ); olRetBytesHANDLEFdGetOsFHandle( ivFd ) int ivFd CODE: RETVAL= (HANDLE) win32_get_osfhandle( ivFd ); SaveErr( INVALID_HANDLE_VALUE == RETVAL ); OUTPUT: RETVALDWORDGetDriveTypeA( sRootPath ) char * sRootPath CODE: RETVAL = GetDriveTypeA( sRootPath ); SaveErr( !RETVAL ); OUTPUT: RETVALDWORDGetDriveTypeW( swRootPath ) WCHAR * swRootPath CODE: RETVAL = GetDriveTypeW( swRootPath ); SaveErr( !RETVAL ); OUTPUT: RETVALDWORDGetFileAttributesA( sPath ) char * sPath CODE: RETVAL = GetFileAttributesA( sPath ); SaveErr( !RETVAL ); OUTPUT: RETVALDWORDGetFileAttributesW( swPath ) WCHAR * swPath CODE: RETVAL = GetFileAttributesW( swPath ); SaveErr( !RETVAL ); OUTPUT: RETVALDWORDGetFileType( hFile ) HANDLE hFile CODE: RETVAL = GetFileType( hFile ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLGetHandleInformation( hObject, ouFlags ) HANDLE hObject oDWORD * ouFlags CODE: RETVAL = GetHandleInformation( hObject, ouFlags ); SaveErr( !RETVAL ); OUTPUT: RETVAL ouFlagsDWORDGetLogicalDrives() CODE: RETVAL = GetLogicalDrives(); SaveErr( !RETVAL ); OUTPUT: RETVALDWORDGetLogicalDriveStringsA( lBufSize, osBuffer ) DWORD lBufSize = init_buf_l($arg); char * osBuffer = NO_INIT CODE: grow_buf_l( osBuffer,ST(1),char *, lBufSize,ST(0) ); RETVAL= GetLogicalDriveStringsA( lBufSize, osBuffer ); if( lBufSize < RETVAL && autosize(ST(0)) ) { lBufSize= RETVAL; grow_buf_l( osBuffer,ST(1),char *, lBufSize,ST(0) ); RETVAL= GetLogicalDriveStringsA( lBufSize, osBuffer ); } if( 0 == RETVAL || lBufSize < RETVAL ) { SaveErr( 1 ); } else { trunc_buf_l( 1, osBuffer,ST(1), RETVAL ); } OUTPUT: RETVAL osBuffer ;/* The code for this appears above. */DWORDGetLogicalDriveStringsW( lwBufSize, oswBuffer ) DWORD lwBufSize = init_buf_lw($arg); WCHAR * oswBuffer = NO_INIT CODE: grow_buf_lw( oswBuffer,ST(1), lwBufSize,ST(0) ); RETVAL= GetLogicalDriveStringsW( lwBufSize, oswBuffer ); if( lwBufSize < RETVAL && autosize(ST(0)) ) { lwBufSize= RETVAL; grow_buf_lw( oswBuffer,ST(1), lwBufSize,ST(0) ); RETVAL= GetLogicalDriveStringsW( lwBufSize, oswBuffer ); } if( 0 == RETVAL || lwBufSize < RETVAL ) { SaveErr( 1 ); } else { trunc_buf_lw( 1, oswBuffer,ST(1), RETVAL ); } OUTPUT: RETVAL oswBuffer ;/* The code for this appears above. */BOOLGetVolumeInformationA( sRootPath, osVolName, lVolName, ouSerialNum, ouMaxNameLen, ouFsFlags, osFsType, lFsType ) char * sRootPath char * osVolName = NO_INIT DWORD lVolName = init_buf_l($arg); oDWORD &ouSerialNum = optUV($arg); oDWORD &ouMaxNameLen = optUV($arg); oDWORD &ouFsFlags = optUV($arg); char * osFsType = NO_INIT DWORD lFsType = init_buf_l($arg); CODE: grow_buf_l( osVolName,ST(1),char *, lVolName,ST(2) ); grow_buf_l( osFsType,ST(6),char *, lFsType,ST(7) ); RETVAL= GetVolumeInformationA( sRootPath, osVolName, lVolName, &ouSerialNum, &ouMaxNameLen, &ouFsFlags, osFsType, lFsType ); SaveErr( !RETVAL ); OUTPUT: RETVAL osVolName trunc_buf_z( RETVAL, osVolName,ST(1) ); osFsType trunc_buf_z( RETVAL, osFsType,ST(6) ); ouSerialNum ouMaxNameLen ouFsFlagsBOOLGetVolumeInformationW( swRootPath, oswVolName, lwVolName, ouSerialNum, ouMaxNameLen, ouFsFlags, oswFsType, lwFsType ) WCHAR * swRootPath WCHAR * oswVolName = NO_INIT DWORD lwVolName = init_buf_lw($arg); oDWORD &ouSerialNum = optUV($arg); oDWORD &ouMaxNameLen = optUV($arg); oDWORD &ouFsFlags = optUV($arg); WCHAR * oswFsType = NO_INIT DWORD lwFsType = init_buf_lw($arg); CODE: grow_buf_lw( oswVolName,ST(1), lwVolName,ST(2) ); grow_buf_lw( oswFsType,ST(6), lwFsType,ST(7) ); RETVAL= GetVolumeInformationW( swRootPath, oswVolName, lwVolName, &ouSerialNum, &ouMaxNameLen, &ouFsFlags, oswFsType, lwFsType ); SaveErr( !RETVAL ); OUTPUT: RETVAL oswVolName trunc_buf_zw( RETVAL, oswVolName,ST(1) ); oswFsType trunc_buf_zw( RETVAL, oswFsType,ST(6) ); ouSerialNum ouMaxNameLen ouFsFlagsBOOLIsRecognizedPartition( ivPartitionType ) int ivPartitionType CODE: RETVAL = IsRecognizedPartition( ivPartitionType ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLIsContainerPartition( ivPartitionType ) int ivPartitionType CODE: RETVAL = IsContainerPartition( ivPartitionType ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLMoveFileA( sOldName, sNewName ) char * sOldName char * sNewName CODE: RETVAL = MoveFileA( sOldName, sNewName ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLMoveFileW( swOldName, swNewName ) WCHAR * swOldName WCHAR * swNewName CODE: RETVAL = MoveFileW( swOldName, swNewName ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLMoveFileExA( sOldName, sNewName, uFlags ) char * sOldName char * sNewName DWORD uFlags CODE: RETVAL = MoveFileExA( sOldName, sNewName, uFlags ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLMoveFileExW( swOldName, swNewName, uFlags ) WCHAR * swOldName WCHAR * swNewName DWORD uFlags CODE: RETVAL = MoveFileExW( swOldName, swNewName, uFlags ); SaveErr( !RETVAL ); OUTPUT: RETVALlongOsFHandleOpenFd( hOsFHandle, uMode ) long hOsFHandle DWORD uMode CODE: RETVAL= win32_open_osfhandle( hOsFHandle, uMode ); if( RETVAL < 0 ) { SaveErr( 1 ); XSRETURN_NO; } else if( 0 == RETVAL ) { XSRETURN_PV( "0 but true" ); } else { XSRETURN_IV( (IV) RETVAL ); }DWORDQueryDosDeviceA( sDeviceName, osTargetPath, lTargetBuf ) char * sDeviceName char * osTargetPath = NO_INIT DWORD lTargetBuf = init_buf_l($arg); CODE: grow_buf_l( osTargetPath,ST(1),char *, lTargetBuf,ST(2) ); RETVAL= QueryDosDeviceA( sDeviceName, osTargetPath, lTargetBuf ); SaveErr( 0 == RETVAL ); OUTPUT: RETVAL osTargetPath trunc_buf_l( 1, osTargetPath,ST(1), RETVAL );DWORDQueryDosDeviceW( swDeviceName, oswTargetPath, lwTargetBuf ) WCHAR * swDeviceName WCHAR * oswTargetPath = NO_INIT DWORD lwTargetBuf = init_buf_lw($arg); CODE: grow_buf_lw( oswTargetPath,ST(1), lwTargetBuf,ST(2) ); RETVAL= QueryDosDeviceW( swDeviceName, oswTargetPath, lwTargetBuf ); SaveErr( 0 == RETVAL ); OUTPUT: RETVAL oswTargetPath trunc_buf_lw( 1, oswTargetPath,ST(1), RETVAL );BOOLReadFile( hFile, opBuffer, lBytes, olBytesRead, pOverlapped ) HANDLE hFile BYTE * opBuffer = NO_INIT DWORD lBytes = init_buf_l($arg); oDWORD &olBytesRead void * pOverlapped CODE: grow_buf_l( opBuffer,ST(1),BYTE *, lBytes,ST(2) ); /* Don't read more bytes than asked for if buffer is already big: */ lBytes= init_buf_l(ST(2)); if( 0 == lBytes && autosize(ST(2)) ) { lBytes= SvLEN( ST(1) ) - 1; } RETVAL= ReadFile( hFile, opBuffer, lBytes, &olBytesRead, pOverlapped ); SaveErr( !RETVAL ); OUTPUT: RETVAL opBuffer trunc_buf_l( RETVAL, opBuffer,ST(1), olBytesRead ); olBytesReadBOOLGetOverlappedResult( hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait) HANDLE hFile LPOVERLAPPED lpOverlapped LPDWORD lpNumberOfBytesTransferred BOOL bWait CODE: RETVAL= GetOverlappedResult( hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait); SaveErr( !RETVAL ); OUTPUT: RETVAL lpOverlapped lpNumberOfBytesTransferredDWORDGetFileSize( hFile, lpFileSizeHigh ) HANDLE hFile LPDWORD lpFileSizeHigh CODE: RETVAL= GetFileSize( hFile, lpFileSizeHigh ); SaveErr( NO_ERROR != GetLastError() ); OUTPUT: RETVAL lpFileSizeHighUINTSetErrorMode( uNewMode ) UINT uNewModeLONGSetFilePointer( hFile, ivOffset, ioivOffsetHigh, uFromWhere ) HANDLE hFile LONG ivOffset LONG * ioivOffsetHigh DWORD uFromWhere CODE: RETVAL= SetFilePointer( hFile, ivOffset, ioivOffsetHigh, uFromWhere ); if( RETVAL == INVALID_SET_FILE_POINTER && (GetLastError() != NO_ERROR) ) { SaveErr( 1 ); XST_mNO(0); } else if( 0 == RETVAL ) { XST_mPV(0,"0 but true"); } else { XST_mIV(0,RETVAL); } OUTPUT: ioivOffsetHighBOOLSetHandleInformation( hObject, uMask, uFlags ) HANDLE hObject DWORD uMask DWORD uFlags CODE: RETVAL = SetHandleInformation( hObject, uMask, uFlags ); SaveErr( !RETVAL ); OUTPUT: RETVALBOOLWriteFile( hFile, pBuffer, lBytes, ouBytesWritten, pOverlapped ) HANDLE hFile BYTE * pBuffer DWORD lBytes = init_buf_l($arg); oDWORD &ouBytesWritten void * pOverlapped CODE: /* SvCUR(ST(1)) might "panic" if pBuffer isn't valid */ if( 0 == lBytes ) { lBytes= SvCUR(ST(1)); } else if( SvCUR(ST(1)) < lBytes ) { croak( "%s: pBuffer value too short (%d < %d)", "Win32API::File::WriteFile", SvCUR(ST(1)), lBytes ); } RETVAL= WriteFile( hFile, pBuffer, lBytes, &ouBytesWritten, pOverlapped ); SaveErr( !RETVAL ); OUTPUT: RETVAL ouBytesWritten
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -