Win32API::File - 对文件/目录的 Win32 系统 API 调用进行低级访问。
use Win32API::File 0.08 qw( :ALL );
MoveFile( $Source, $Destination )
or die "Can't move $Source to $Destination: ",fileLastError(),"\n";
MoveFileEx( $Source, $Destination, MOVEFILE_REPLACE_EXISTING() )
or die "Can't move $Source to $Destination: ",fileLastError(),"\n";
[...]
它提供了对处理文件和目录的 Win32 系统 API 调用的相当低级的访问。
要将 NULL 作为指向可选缓冲区的指针传递,请传递一个空列表引用,[]。
除了对 API 调用和相关常量的原始访问之外,此模块还处理智能缓冲区分配和返回值的转换。
所有函数,除非另有说明,在成功时返回真值,在失败时返回假值,并在失败时设置 $^E。
警告:这是新代码,请自行承担风险使用。
此版本的 Win32API::File 可以像 IO::File 对象一样使用
my $file = Win32API::File->new("+> foo");
binmode $file;
print $file "hello there\n";
seek $file, 0, 0;
my $line = <$file>;
$file->close;
它还支持通过 win32 句柄(例如,来自 createFile())进行绑定
tie FILE, 'Win32API::File', $win32_handle;
print FILE "...";
它尚未经过广泛测试,并且缓冲 I/O 尚未实现。
默认情况下不导出任何内容。可以使用以下标签导出大量符号:":Func"、":FuncA"、":FuncW"、":Misc"、":DDD_"、":DRIVE_"、":FILE_"、":FILE_ATTRIBUTE_"、":FILE_FLAG_"、":FILE_SHARE_"、":FILE_TYPE_"、":FS_"、":FSCTL_"、":HANDLE_FLAG_"、":IOCTL_STORAGE_"、":IOCTL_DISK_"、":GENERIC_"、":MEDIA_TYPE"、":MOVEFILE_"、":SECURITY_"、":SEM_" 和 ":PARTITION_"。
":Func"基本函数名称:attrLetsToBits、createFile、fileConstant、fileLastError、getLogicalDrives、setFilePointer、getFileSize、CloseHandle、CopyFile、CreateFile、DefineDosDevice、DeleteFile、DeviceIoControl、FdGetOsFHandle、GetDriveType、GetFileAttributes、GetFileSize、GetFileType、GetHandleInformation、GetLogicalDrives、GetLogicalDriveStrings、GetOsFHandle、GetOverlappedResult、GetVolumeInformation、IsContainerPartition、IsRecognizedPartition、MoveFile、MoveFileEx、OsFHandleOpen、OsFHandleOpenFd、QueryDosDevice、ReadFile、SetErrorMode、SetFilePointer、SetHandleInformation 和 WriteFile。
$uBits= attrLetsToBits( $sAttributeLetters )将文件属性字母字符串转换为具有相应位设置的无符号值。$sAttributeLetters 应包含来自 "achorst" 的零个或多个字母。
$hObject= createFile( $sPath )$hObject= createFile( $sPath, $rvhvOptions )$hObject= createFile( $sPath, $svAccess )$hObject= createFile( $sPath, $svAccess, $rvhvOptions )这是一个 Perl 友好的 CreateFile 包装器。
如果失败,$hObject 将被设置为假值,regLastError() 和 $^E 将被设置为失败原因。否则,$hObject 将被设置为 Win32 本地文件句柄,它始终为真值 [在句柄值为 0 的不可能情况下返回 "0 but true"]。
$sPath 是要打开的文件(或设备等)的路径。有关 $sPath 的可能特殊值的更多信息,请参阅 CreateFile。
$svAccess 可以是一个包含位掩码的数字,表示您想要的特定类型的文件访问权限。有关这些值的更多信息,请参阅 CreateFile 的 $uAccess 参数。
更可能的是,$svAccess 是一个字符串,描述您想要的通用访问类型以及可能使用的文件创建选项。在这种情况下,$svAccess 应该包含来自 "qrw" [所需访问权限] 的零个或多个字符,来自 "ktn" 和 "ce" 的每个字符零个或一个字符,以及可选的空格。这些字母分别代表“查询访问权限”、“读取访问权限”、“写入访问权限”、“如果存在则保留”、“如果存在则截断”、“仅新文件”、“如果不存在则创建”和“仅现有文件”。大小写被忽略。
您可以将 "?" 传递给 $svAccess 以显示一条错误消息,总结其可能的值。这在使用 Perl 调试器进行即时编程时非常方便。
Win32API::File::createFile: $svAccess can use the following:
One or more of the following:
q -- Query access (same as 0)
r -- Read access (GENERIC_READ)
w -- Write access (GENERIC_WRITE)
At most one of the following:
k -- Keep if exists
t -- Truncate if exists
n -- New file only (fail if file already exists)
At most one of the following:
c -- Create if doesn't exist
e -- Existing file only (fail if doesn't exist)
'' is the same as 'q k e'
'r' is the same as 'r k e'
'w' is the same as 'w t c'
'rw' is the same as 'rw k c'
'rt' or 'rn' implies 'c'.
Or $access can be numeric.
$svAccess 被设计为“按我的意思做”,因此您可以跳过其余的解释,除非您对复杂的细节感兴趣。请注意,如果您想要对设备进行写入访问权限,则需要指定 "k" [以及可能 "e",如 "w ke" 或 "rw ke"],因为 Win32 建议在打开设备时使用 OPEN_EXISTING。
"q"代表“查询访问权限”。这实际上是一个无操作,因为您在打开文件时始终拥有查询访问权限。您可以指定 "q" 来记录您计划查询文件(或设备等)。当您不想要读取或写入访问权限时,这尤其有用,因为像 "q" 或 "q ke" 这样的东西可能比仅仅 "" 或 "ke" 更容易理解。
"r"代表“读取访问”。在传递给CreateFile的$uAccess中设置GENERIC_READ位。如果$svAccess参数缺失[或为undef且$rvhvOptions未指定"Access"选项],则这是默认访问权限。
"w"代表“写入访问”。在传递给CreateFile的$uAccess中设置GENERIC_WRITE位。
"k"代表“如果存在则保留”。如果请求的文件存在,则打开它。这是默认行为,除非已请求GENERIC_WRITE访问权限但未请求GENERIC_READ访问权限。与"t"和"n"对比。
"t"代表“如果存在则截断”。如果请求的文件存在,则将其截断为零长度,然后打开它。这是默认行为,如果已请求GENERIC_WRITE访问权限但未请求GENERIC_READ访问权限。与"k"和"n"对比。
"n"代表“仅限新文件”。如果请求的文件存在,则不会打开它,并且createFile调用失败。与"k"和"t"对比。不能与"e"一起使用。
"c"代表“如果不存在则创建”。如果请求的文件不存在,则创建它,然后打开它。这是默认行为,如果已请求GENERIC_WRITE访问权限或指定了"t"或"n"。与"e"对比。
"e"代表“仅限现有文件”。如果请求的文件不存在,则不会打开任何内容,并且createFile调用失败。这是默认行为,除非已请求GENERIC_WRITE访问权限或指定了"t"或"n"。与"c"对比。不能与"n"一起使用。
来自"ktn"和"ce"的字符组合在一起以确定传递给CreateFile的$uCreate的值[除非被$rvhvOptions覆盖]
$svShare 控制文件共享方式,即其他进程在打开文件时是否可以对文件进行读、写和/或删除操作。$svShare 通常是一个包含零个或多个来自 "rwd" 的字符的字符串,但也可以是数值位掩码。
"r" 设置 FILE_SHARE_READ 位,允许其他进程读取文件。"w" 设置 FILE_SHARE_WRITE 位,允许其他进程写入文件。"d" 设置 FILE_SHARE_DELETE 位,允许其他进程删除文件 [在 Windows 95 下被忽略]。
$svShare 的默认值为 "rw",它提供与使用常规 perl open() 相同的共享方式。
如果另一个进程当前对文件具有读、写和/或删除访问权限,而您不允许这种级别的共享,那么您的 createFile 调用将失败。如果您请求读、写和/或删除访问权限,而另一个进程已经打开了文件,但没有允许这种级别的共享,那么您的 createFile 调用将失败。一旦您打开了文件,如果另一个进程尝试以读、写和/或删除访问权限打开它,而您不允许这种级别的共享,那么该进程将无法打开文件。
$rvhvOptions 是一个哈希的引用,其中任何键都必须来自列表 qw( Access Create Share Attributes Flags Security Model )。值的含义取决于键名,如下所述。$rvhvOptions 中的任何选项值都会覆盖 $svAccess 和 $svShare 中的设置(如果冲突)。
$uFlags 是一个无符号值,它包含任何 FILE_FLAG_* 或 FILE_ATTRIBUTE_* 位。通过 Attributes 选项设置的任何 FILE_ATTRIBUTE_* 位将与这些位进行逻辑或运算。默认值为 0。
如果打开命名管道的客户端,则还可以指定 SECURITY_SQOS_PRESENT 以及其他 SECURITY_* 常量之一,以指定要使用的安全质量服务。
一个包含零个或多个字符的字符串,这些字符来自 "achorst" [有关更多信息,请参阅 attrLetsToBits],这些字符将转换为 FILE_ATTRIBUTE_* 位,并设置在传递给 CreateFile 的 $uFlags 参数中。
$pSecurityAttributes 应包含一个打包到字符串或 [] [默认值] 中的 SECURITY_ATTRIBUTES 结构。
$hModelFile 应包含一个使用 GENERIC_READ 访问权限打开的句柄,该句柄指向模型文件,从中复制文件属性和扩展属性。或者 $hModelFile 可以是 0 [默认值]。
$sAccess 应包含一个包含零个或多个字符的字符串,这些字符来自 "qrw",指定所需的访问类型:"query" 或 0,"read" 或 GENERIC_READ [默认值],或 "write" 或 GENERIC_WRITE。
$uAccess 应包含一个无符号值,其中设置了位以指示所需的访问类型。GENERIC_READ 是默认值。
$sCreate 应该是一个字符串,包含来自 "ktn" 的零个或一个字符,以及来自 "ce" 的零个或一个字符。这些分别代表 "如果存在则保留"、"如果存在则截断"、"仅新文件"、"如果不存在则创建" 和 "仅现有文件"。这些将被转换为 $uCreate 值。
$uCreate 应该为 OPEN_ALWAYS、OPEN_EXISTING、TRUNCATE_EXISTING、CREATE_ALWAYS 或 CREATE_NEW 之一。
$sShare 应该是一个字符串,包含来自 "rwd" 的零个或多个字符,这些字符将被转换为 $uShare 值。"rw" 是默认值。
$uShare 应该是一个无符号值,其中设置了以下一个或多个位:FILE_SHARE_READ、FILE_SHARE_WRITE 和 FILE_SHARE_DELETE。FILE_SHARE_READ|FILE_SHARE_WRITE 是默认值。
示例
$hFlop= createFile( "//./A:", "r", "r" )
or die "Can't prevent others from writing to floppy: $^E\n";
$hDisk= createFile( "//./C:", "rw ke", "" )
or die "Can't get exclusive access to C: $^E\n";
$hDisk= createFile( $sFilePath, "ke",
{ Access=>FILE_READ_ATTRIBUTES } )
or die "Can't read attributes of $sFilePath: $^E\n";
$hTemp= createFile( "$ENV{Temp}/temp.$$", "wn", "",
{ Attributes=>"hst", Flags=>FILE_FLAG_DELETE_ON_CLOSE() } )
or die "Can't create temporary file, temp.$$: $^E\n";
@roots= getLogicalDrives()返回当前定义的所有逻辑驱动器的根目录路径。这包括所有类型的驱动器盘符,例如软盘、CD-ROM、硬盘和网络共享。在配置较差的计算机上,典型的返回值将是 ("A:\\","C:\\")。
CloseHandle( $hObject )关闭 Win32 本地句柄,例如通过 CreateFile 打开的句柄。与大多数例程一样,如果成功则返回真值,如果失败则返回假值 [并设置 $^E 和 regLastError()]。
CopyFile( $sOldFileName, $sNewFileName, $bFailIfExists )$sOldFileName 是要复制的文件的路径。$sNewFileName 是要将文件复制到的路径。请注意,您 **不能** 只在 $sNewFileName 中指定目录路径,以使用相同的文件名将文件复制到该目录。
如果 $bFailIfExists 为真,并且 $sNewFileName 是指向已存在的文件的路径,则 CopyFile 将失败。如果 $bFailIfExists 为假,则如果 $sNewFileName 文件已存在,则 $sOldFileNmae 文件的副本将覆盖 $sNewFileName 文件。
与大多数例程一样,如果成功则返回真值,如果失败则返回假值 [并设置 $^E 和 regLastError()]。
如果失败,$hObject 将被设置为假值,$^E 和 fileLastError() 将被设置为失败的原因。否则,$hObject 将被设置为一个 Win32 本地文件句柄,该句柄始终为真值 [在句柄值为 0 的不可能情况下返回 "0 但为真"]。
$sPath 是要打开的文件 [或设备等] 的路径。
$sPath 可以使用 "/" 或 "\\" 作为路径分隔符,甚至可以混合使用两者。在我们的示例中,我们通常只使用 "/",因为使用 "\\" 通常更难阅读。
在 Windows NT 下,$sPath 可以以 "//?/" 开头,以允许使用超过 MAX_PATH 的路径 [对于 UNC 路径,将开头的 "//" 替换为 "//?/UNC/",例如 "//?/UNC/Server/Share/Dir/File.Ext"]。
$sPath 可以以 "//./" 开头,表示路径的其余部分是“DOS 设备”的名称。您可以使用 QueryDosDevice 列出所有当前的 DOS 设备,并可以使用 DefineDosDevice 添加或删除它们。如果您从 CPAN 获取此模块的源代码分发版,那么它包含一个示例脚本 ex/ListDevs.plx,该脚本将列出所有当前的 DOS 设备及其“本地”定义。再次注意,这在 Win95 或 Win98 下不起作用。
最常见的此类 DOS 设备包括
"//./PhysicalDrive0"您的整个第一个硬盘。在 Windows 95 下不起作用。这允许您读取或写入硬盘的原始扇区,并使用 DeviceIoControl 对硬盘执行各种查询和操作。写入原始扇区和某些其他操作可能会严重损坏您的文件或计算机的功能。
将此锁定为独占访问 [通过为 $uShare 指定 0] 不会阻止访问磁盘上的分区或其文件系统。因此,其他进程仍然可以访问分区内的任何原始扇区,并可以像往常一样使用磁盘上的文件系统。
"//./C:"您的 C: 分区。在 Windows 95 下不起作用。这允许您读取或写入该分区的原始扇区,并使用 DeviceIoControl 对分区执行各种查询和操作。写入原始扇区和某些其他操作可能会严重损坏您的文件或计算机的功能。
锁定此分区以供独占访问不会阻止访问分区所在的物理驱动器,因此其他进程仍然可以通过这种方式访问原始扇区。锁定此分区以供独占访问**确实**会阻止其他进程打开相同的原始分区,并且**确实**会阻止访问其上的文件系统。它甚至会阻止当前进程访问该分区上的文件系统。
"//./A:"原始软盘。在 Windows 95 下不起作用。这允许您读取或写入软盘的原始扇区,并使用DeviceIoControl对软盘或驱动器执行各种查询和操作。
锁定此分区以供独占访问会阻止对软盘的所有访问。
"//./PIPE/PipeName"一个命名管道,通过CreateNamedPipe创建。
$uAccess是一个无符号值,其位设置指示所需的访问类型。通常是0 ["查询"访问]、GENERIC_READ、GENERIC_WRITE、GENERIC_READ|GENERIC_WRITE或GENERIC_ALL。可以指定更具体的访问类型,例如FILE_APPEND_DATA或FILE_READ_EA。
$uShare控制如何共享文件,即当我们打开文件时,其他进程是否可以对文件进行读、写和/或删除访问。$uShare是一个无符号值,其位设置了以下一个或多个位:FILE_SHARE_READ、FILE_SHARE_WRITE和FILE_SHARE_DELETE。
如果另一个进程当前对文件具有读、写和/或删除访问权限,而您不允许这种级别的共享,那么您对CreateFile的调用将失败。如果您请求读、写和/或删除访问权限,而另一个进程已经打开了文件,但没有允许这种级别的共享,那么您对createFile的调用将失败。一旦您打开了文件,如果另一个进程尝试以读、写和/或删除访问权限打开它,而您不允许这种级别的共享,那么该进程将不被允许打开文件。
$pSecAttr应为[] [对于NULL] 或一个打包到字符串中的SECURITY_ATTRIBUTES数据结构。例如,如果$pSecDesc包含一个打包到字符串中的SECURITY_DESCRIPTOR结构,可能是通过
RegGetKeySecurity( $key, 4, $pSecDesc, 1024 );
那么您可以通过以下方式设置$pSecAttr
$pSecAttr= pack( "L P i", 12, $pSecDesc, $bInheritHandle );
$uCreate 可以是以下值之一:OPEN_ALWAYS、OPEN_EXISTING、TRUNCATE_EXISTING、CREATE_ALWAYS 和 CREATE_NEW。
$uFlags 是一个无符号值,其中设置了零个或多个位,表示与文件关联的属性 [FILE_ATTRIBUTE_* 值] 或特殊选项 [FILE_FLAG_* 值]。
如果打开命名管道的客户端,则还可以将 $uFlags 设置为包含 SECURITY_SQOS_PRESENT 以及其他 SECURITY_* 常量之一,以指定要使用的安全质量服务。
$hModel 为 0 [或 [],两者都表示 NULL] 或使用 GENERIC_READ 访问权限打开的 Win32 本机句柄,指向模型文件,如果创建新文件,则将从该模型文件复制文件属性和扩展属性。
示例
$hFlop= CreateFile( "//./A:", GENERIC_READ(),
FILE_SHARE_READ(), [], OPEN_EXISTING(), 0, [] )
or die "Can't prevent others from writing to floppy: $^E\n";
$hDisk= CreateFile( $sFilePath, FILE_READ_ATTRIBUTES(),
FILE_SHARE_READ()|FILE_SHARE_WRITE(), [], OPEN_EXISTING(), 0, [] )
or die "Can't read attributes of $sFilePath: $^E\n";
$hTemp= CreateFile( "$ENV{Temp}/temp.$$", GENERIC_WRITE(), 0,
CREATE_NEW(), FILE_FLAG_DELETE_ON_CLOSE()|attrLetsToBits("hst"), [] )
or die "Can't create temporary file, temp.$$: $^E\n";
DefineDosDevice( $uFlags, $sDosDeviceName, $sTargetPath )定义新的 DOS 设备,覆盖当前 DOS 设备的定义,或删除 DOS 设备的定义。与大多数例程一样,如果成功则返回真值,如果失败则返回假值 [并设置 $^E 和 regLastError()]。
$sDosDeviceName 是我们要为其添加或删除定义的 DOS 设备的名称。
$uFlags 是一个无符号值,其中设置了以下一个或多个位
DDD_RAW_TARGET_PATH表示 $sTargetPath 将是原始 Windows NT 对象名称。这通常意味着 $sTargetPath 以 "\\Device\\" 开头。请注意,在原始目标路径名称中不能使用 "/" 代替 "\\"。
DDD_REMOVE_DEFINITION请求删除定义。如果 $sTargetPath 为 [] [表示 NULL],则删除为 $sDosDeviceName 添加的最新定义。否则,删除与 $sTargetPath 匹配的最新添加的定义。
如果删除了最后一个定义,则也会删除 DOS 设备名称。
DDD_EXACT_MATCH_ON_REMOVE删除定义时,此位会导致每个$sTargetPath在搜索最近添加的匹配项时与完整长度的定义进行比较。如果未设置此位,则$sTargetPath只需要匹配定义的前缀。
$sTargetPath是您希望添加或删除的 DOS 设备的特定定义。对于DDD_RAW_TARGET_PATH,这些通常以"\\Device\\"开头。如果未设置DDD_RAW_TARGET_PATH位,则$sTargetPath只是一个指向某个文件或目录的普通路径,提供subst命令的功能。
DeleteFile( $sFileName )删除指定的文件。与 Perl 的unlink相比,DeleteFile的优点是不删除只读文件。对于某些版本的 Perl,unlink在删除文件之前会静默地调用chmod,无论它是否需要,因此您通过将其标记为只读来保护的文件并不总是受到 Perl 的unlink的保护。
与大多数例程一样,如果成功则返回真值,如果失败则返回假值 [并设置 $^E 和 regLastError()]。
DeviceIoControl( $hDevice, $uIoControlCode, $pInBuf, $lInBuf, $opOutBuf, $lOutBuf, $olRetBytes, $pOverlapped )请求对 I/O [输入/输出] 设备执行特殊操作,例如弹出磁带或格式化磁盘。与大多数例程一样,如果成功则返回真值,如果失败则返回假值 [并设置$^E和regLastError()]。
$hDevice是 Win32 本地文件句柄,指向设备 [来自CreateFile的返回值]。
$uIoControlCode是一个无符号值 [一个IOCTL_*或FSCTL_*常量],指示要执行的查询类型或其他操作。
$pInBuf为[] [对于NULL] 或将数据结构打包到字符串中。数据结构的类型取决于$uIoControlCode值。$lInBuf为0或$pInBuf中结构的长度。如果$pInBuf不是[]且$lInBuf为0,则$lInBuf将自动为您设置为length($pInBuf)。
$opOutBuf为[] [对于NULL] 或将设置为包含返回的数据结构,打包到字符串中。$lOutBuf指示在$opOutBuf中为DeviceIoControl存储数据结构分配多少空间。如果$lOutBuf是一个数字,并且$opOutBuf已经为其分配了一个大于$lOutBuf字节的缓冲区,那么这个更大的缓冲区大小将被传递给DeviceIoControl。但是,您可以通过在$lOutBuf前面添加一个"="来强制将特定缓冲区大小传递给DeviceIoControl。
$olRetBytes为[]或是一个标量,用于接收写入$opOutBuf的字节数。即使$olRetBytes为[],一个指向DWORD [而不是NULL] 的有效指针也会传递给DeviceIoControl。在这种情况下,[]只是意味着您不关心可能写入$olRetBytes的值,这通常是这种情况,因为您通常可以使用length($opOutBuf)代替。
$pOverlapped 是 [] 或者是一个打包成字符串的 OVERLAPPED 结构体。这只有在 $hDevice 以 FILE_FLAG_OVERLAPPED 标志打开时才有用。
$hNativeHandle= FdGetOsFHandle( $ivFd )FdGetOsFHandle 只是简单地调用 _get_osfhandle()。它被重命名以更好地融入该模块的其余函数名称,特别是为了将其与 GetOsFHandle 区分开来。它接受一个整数文件描述符(来自 Perl 的 fileno),并返回与该文件描述符关联的 Win32 本地文件句柄,如果 $ivFd 不是一个打开的文件描述符,则返回 INVALID_HANDLE_VALUE。
当您调用 Perl 的 open 来设置一个 Perl 文件句柄(如 STDOUT)时,Perl 会调用 C 的 fopen 来设置一个 stdio FILE *。C 的 fopen 会调用类似于 Unix 的 open 的东西,即 Win32 的 _sopen,来获取一个整数文件描述符(其中 0 用于 STDIN,1 用于 STDOUT,等等)。Win32 的 _sopen 会调用 CreateFile 来设置一个 HANDLE,一个 Win32 本地文件句柄。因此,每个 Perl 文件句柄(如 STDOUT)都与一个整数文件描述符相关联,您可以通过 fileno 获取该文件描述符。并且,在 Win32 下,每个文件描述符都与一个 Win32 本地文件句柄相关联。FdGetOsFHandle 允许您访问它。
如果 FdGetOsFHandle 失败,$hNativeHandle 将被设置为 INVALID_HANDLE_VALUE(并且 lastFileError() 和 $^E 被设置)。另请参阅 GetOsFHandle,它提供了一个更友好的接口。
$value= fileConstant( $sConstantName )获取常量的值。如果 $sConstantName 不是该模块支持的常量的名称,则返回 undef。从不设置 $! 或 $^E。
此函数很少使用,因为您通常会通过将常量名称列在 use Win32API::File 语句中,并将常量名称导入到您的包中来获取常量的值,然后在您的代码中简单地使用常量名称(可能后面跟着 ())。此函数对于验证不在 Perl 代码中的常量名称很有用,例如,在提示用户输入常量名称之后。
$svError= fileLastError();fileLastError( $uError );返回该模块中的例程遇到的最后一个错误。它与 $^E 相同,只是它不会被除该模块中的例程以外的任何东西更改。理想情况下,您可以直接使用 $^E,但当前版本的 Perl 通常会在您有机会检查它之前覆盖 $^E,而非常旧版本的 Perl 在 Win32 下并不真正支持 $^E。
与 $^E 一样,在数值上下文中,fileLastError() 返回数值错误值,而在字符串上下文中,它返回错误的文本描述(实际上,它返回一个包含这两个值的 Perl 标量,因此 $x= fileLastError() 会导致 $x 在字符串和数值上下文中给出不同的值)。
最后一个形式设置了将来调用 fileLastError() 返回的错误,不应经常使用。$uError 必须是一个数值错误代码。还返回 $uError 的双值版本。
$uDriveType= GetDriveType( $sRootPath )接受一个字符串,该字符串给出文件系统根目录的路径 [称为“驱动器”,因为每个文件系统都分配了一个“驱动器号”],并返回一个无符号值,指示文件系统所在的驱动器类型。返回值应为以下之一:
$uAttrs = GetFileAttributes( $sPath )接受一个路径字符串,并返回一个带有属性标志的无符号值。如果失败,它将返回 INVALID_FILE_ATTRIBUTES,否则它可以是以下一个或多个值:
FILE_ATTRIBUTE_ARCHIVE文件或目录是存档文件或目录。应用程序使用此属性来标记要备份或删除的文件。
FILE_ATTRIBUTE_COMPRESSED文件或目录已压缩。对于文件,这意味着文件中的所有数据都已压缩。对于目录,这意味着压缩是新创建的文件和子目录的默认设置。
FILE_ATTRIBUTE_DEVICE保留;不要使用。
FILE_ATTRIBUTE_DIRECTORY句柄标识一个目录。
FILE_ATTRIBUTE_ENCRYPTED文件或目录已加密。对于文件,这意味着文件中的所有数据流都已加密。对于目录,这意味着加密是新创建的文件和子目录的默认设置。
FILE_ATTRIBUTE_HIDDEN文件或目录已隐藏。它不包含在普通目录列表中。
FILE_ATTRIBUTE_NORMAL该文件或目录没有设置其他属性。此属性仅在单独使用时有效。
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED该文件不会被内容索引服务索引。
FILE_ATTRIBUTE_OFFLINE该文件的数据不可立即使用。此属性表示文件数据已物理移动到脱机存储。此属性由远程存储(分层存储管理软件)使用。应用程序不应随意更改此属性。
FILE_ATTRIBUTE_READONLY该文件或目录为只读。应用程序可以读取文件,但不能写入或删除它。对于目录,应用程序不能删除它。
FILE_ATTRIBUTE_REPARSE_POINT该文件或目录具有关联的重解析点。
FILE_ATTRIBUTE_SPARSE_FILE该文件是稀疏文件。
FILE_ATTRIBUTE_SYSTEM该文件或目录是操作系统的一部分,或专供操作系统使用。
FILE_ATTRIBUTE_TEMPORARY该文件用于临时存储。如果可用足够的缓存内存,文件系统将避免将数据写回大容量存储,因为应用程序通常在句柄关闭后不久就会删除临时文件。在这种情况下,系统可以完全避免写入数据。否则,数据将在句柄关闭后写入。
$uFileType= GetFileType( $hFile )接受一个 Win32 本地文件句柄,并返回一个 FILE_TYPE_* 常量,指示在该句柄上打开的文件类型。
$size= getFileSize( $hFile )这是对 GetFileSize(下面)API 调用的 Perl 友好包装器。
它接受一个 Win32 本地文件句柄,并返回以字节为单位的大小。由于大小可以是 64 位值,因此在非 64 位整数 Perl 中,返回的值将是 Math::BigInt 类型的对象。
$iSizeLow= GetFileSize($win32Handle, $iSizeHigh)返回由 $win32Handle 指向的文件的大小,如果 $iSizeHigh 不为 [],则可以选择将高阶 32 位存储到 $iSizeHigh 中。如果 $iSizeHigh 为 [],则非零值表示成功。否则,如果失败,返回值将为 0xffffffff,并且 fileLastError() 将不为 NO_ERROR。
$bRetval= GetOverlappedResult( $win32Handle, $pOverlapped, $numBytesTransferred, $bWait )用于 Win32 中的异步 IO,以获取挂起 IO 操作的结果,例如当文件操作返回 ERROR_IO_PENDING 时。如果失败,则返回一个假值。$overlapped 结构和 $numBytesTransferred 将使用操作结果进行修改。
就创建 $pOverlapped 结构而言,您目前只能自己完成。
有关更多信息,请参阅 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getoverlappedresult.asp。
$uDriveBits= GetLogicalDrives()返回一个无符号值,其中每个位对应一个当前定义的驱动器字母。如果“A:”当前是一个有效的驱动器字母,则$uDriveBits中的1位将被设置。如果“B:”有效,则2位将被设置。如果“Z:”有效,则2**26 [0x4000000] 位将被设置。
$olOutLength= GetLogicalDriveStrings( $lBufSize, $osBuffer )对于每个当前定义的驱动器字母,都会构造一个以'\0'结尾的字符串,表示其文件系统根目录的路径。所有这些字符串都被连接成一个更大的字符串,并添加一个额外的'\0'作为结尾。这个更大的字符串将返回到$osBuffer中。请注意,这包括已定义但没有文件系统的驱动器字母,例如分配给未格式化分区的驱动器字母。
$lBufSize是分配给存储此字符串列表的缓冲区的尺寸。26*4+1始终足够,通常应该使用。
$osBuffer是一个标量,将被设置为包含构造的字符串。
$olOutLength是实际写入$osBuffer的字节数,但也可以使用length($osBuffer)来确定此值。
例如,在一台配置较差的计算机上,
GetLogicalDriveStrings( 4*26+1, $osBuffer );
可能会将$osBuffer设置为 9 个字符的字符串 "A:\\\0C:\\\0\0"。
GetHandleInformation( $hObject, $ouFlags )检索与 Win32 本地文件句柄或对象句柄关联的标志。
$hObject是一个打开的 Win32 本地文件句柄或一个打开的 Win32 本地句柄,指向其他类型的对象。
$ouFlags将被设置为一个无符号值,其中设置了HANDLE_FLAG_INHERIT和HANDLE_FLAG_PROTECT_FROM_CLOSE中的一个或多个位。有关这些位的含义,请参见":HANDLE_FLAG_"导出类。
$hNativeHandle= GetOsFHandle( FILE )接受一个 Perl 文件句柄 [例如 STDIN],并返回与其关联的 Win32 本地文件句柄。有关 Win32 本地文件句柄的更多信息,请参见 FdGetOsFHandle。
$hNativeHandle 被设置为一个假值 [并且 lastFileError() 和 $^E 被设置] 如果 GetOsFHandle 失败。GetOsFHandle 在句柄值为 0 的不可能(?)情况下返回 "0 但为真"。
GetVolumeInformation( $sRootPath, $osVolName, $lVolName, $ouSerialNum, $ouMaxNameLen, $ouFsFlags, $osFsType, $lFsType )获取有关文件系统卷的信息,如果成功则返回真值。如果失败,则返回假值并设置 fileLastError() 和 $^E。
$sRootPath 是一个字符串,指定文件系统根目录的路径,例如 "C:/"。
$osVolName 是一个标量,将被设置为表示卷名称的字符串,也称为文件系统标签。$lVolName 是为 $osVolName 缓冲区分配的字节数 [有关更多信息,请参见 "缓冲区大小"]。
$ouSerialNum 为 [] [表示 NULL] 或将被设置为卷序列号的数值。
$ouMaxNameLen 为 [] [表示 NULL] 或将被设置为文件系统中允许的文件名或目录名的最大长度。
$osFsType 是一个标量,将被设置为表示文件系统类型的字符串,例如 "FAT" 或 "NTFS"。$lFsType 是为 $osFsType 缓冲区分配的字节数 [有关更多信息,请参见 "缓冲区大小"]。
$ouFsFlags 为 [] [表示 NULL] 或将被设置为一个无符号整数,其中设置的位表示文件系统的属性
FS_CASE_IS_PRESERVED文件系统保留文件名的大小写 [通常为真]。也就是说,它不会更改文件名的大小写,例如强制它们为大写或小写。
FS_CASE_SENSITIVE文件系统支持不忽略文件名大小写的能力 [但可能会忽略您使用它的方式的大小写]。也就是说,文件系统有能力强制您准确地获取文件的名称大小写才能打开它。对于 "NTFS" 文件系统来说,这是真的,即使文件名中的大小写通常仍然被忽略。
FS_UNICODE_STORED_ON_DISK文件系统保留文件名中的 Unicode [对于 "NTFS" 为真]。
FS_PERSISTENT_ACLS文件系统支持在文件上设置访问控制列表 [对于“NTFS”为真]。
FS_FILE_COMPRESSION文件系统支持按文件压缩 [对于“NTFS”为真]。
FS_VOL_IS_COMPRESSED整个文件系统被压缩,例如通过“DoubleSpace”。
IsRecognizedPartition( $ivPartitionType )接受分区类型并返回该分区类型是否在 Win32 下支持。$ivPartitonType 是一个整数值,来自硬盘 DOS 兼容分区表的操作系统字节 [即,基于 x86 的 Win32 的分区表,而不是例如与 Alpha 处理器一起使用的分区表]。例如,PARTITION_INFORMATION 结构的 PartitionType 成员。
$ivPartitionType 的常见值包括 PARTITION_FAT_12==1、PARTITION_FAT_16==4、PARTITION_EXTENDED==5、PARTITION_FAT32==0xB。
IsContainerPartition( $ivPartitionType )接受分区类型并返回该分区是否为 Win32 下支持的“容器”分区,即,它是否为可以包含“逻辑”分区的“扩展”分区。$ivPartitonType 与 IsRecognizedPartition 相同。
MoveFile( $sOldName, $sNewName )重命名文件或目录。$sOldName 是要重命名的现有文件或目录的名称。$sNewName 是要赋予文件或目录的新名称。如果移动成功,则返回真值。如果失败,则返回假值并将 fileLastErorr() 和 $^E 设置为失败的原因。
文件可以在文件系统之间“重命名”,并且文件内容和某些属性将被移动。目录只能在一个文件系统内重命名。如果已经存在名为 $sNewName 的文件或目录,则 MoveFile 将失败。
MoveFileEx( $sOldName, $sNewName, $uFlags )重命名文件或目录。$sOldName 是要重命名的现有文件或目录的名称。$sNewName 是要赋予文件或目录的新名称。如果移动成功,则返回真值。如果失败,则返回假值并将 fileLastErorr() 和 $^E 设置为失败的原因。
$uFlags 是一个无符号值,其中设置了以下一个或多个位
MOVEFILE_REPLACE_EXISTING如果设置了此位,并且名为 $sNewName 的文件 [但不是目录] 已经存在,那么它将被 $sOldName 替换。如果未设置此位,则 MoveFileEx 将失败,而不是替换现有的 $sNewName。
MOVEFILE_COPY_ALLOWED允许在文件系统之间移动文件(但不包括目录),方法是将$sOldName文件数据和一些属性复制到$sNewName,然后删除$sOldName。如果此位未设置(或如果$sOldName表示目录)并且$sNewName引用与$sOldName不同的文件系统,则MoveFileEx将失败。
MOVEFILE_DELAY_UNTIL_REBOOT进行初步验证,然后在注册表中添加一个条目,以便在下次启动此操作系统副本时执行重命名(或删除)操作(在任何自动文件系统检查完成后立即执行)。Windows 95 不支持此功能。
当设置此位时,$sNewName可以是[](表示NULL),表示在下次启动时应删除$sOldName,而不是重命名。
同时设置MOVEFILE_COPY_ALLOWED和MOVEFILE_DELAY_UNTIL_REBOOT位将导致MoveFileEx失败。
MOVEFILE_WRITE_THROUGH确保MoveFileEx在操作完成并刷新到磁盘之前不会返回。Windows 95 不支持此功能。仅影响文件重命名到另一个文件系统,在复制操作结束时强制缓冲区刷新。
OsFHandleOpen( FILE, $hNativeHandle, $sMode )基于已打开的 Win32 本地文件句柄打开 Perl 文件句柄(类似于 C 的fdopen() 对文件描述符的操作)。如果打开操作成功,则返回真值。如果失败,则返回假值并将$!(以及可能fileLastError() 和$^E)设置为失败的原因。
FILE 是一个 Perl 文件句柄(以任何支持的形式,裸字、字符串、类型全局变量或对类型全局变量的引用),将被打开。如果FILE 已经打开,它将在重新打开之前自动关闭。
$hNativeHandle 是一个已打开的 Win32 本地文件句柄,可能是CreateFile 或createFile 的返回值。
$sMode 是一个由 "rwatb" 中的零个或多个字母组成的字符串。这些字母被转换为 O_RDONLY ["r"]、O_WRONLY ["w"]、O_RDWR ["rw"]、O_APPEND ["a"]、O_TEXT ["t"] 和 O_BINARY ["b"] 标志的组合 [参见 Fcntl 模块],并传递给 OsFHandleOpenFd。目前只有 O_APPEND 和 O_TEXT 有意义。
此外,$sMode 中的 "r" 和/或 "w" 用于决定如何将文件描述符转换为 Perl 文件句柄,即使这似乎没有区别。以下其中一种方法将被使用
open( FILE, "<&=".$ivFd ) # "r" w/o "w"
open( FILE, ">&=".$ivFd ) # "w" w/o "r"
open( FILE, "+<&=".$ivFd ) # both "r" and "w"
OsFHandleOpen 最终调用 Win32 特定的 C 函数 _open_osfhandle() 或 Perl 的“改进”版本,称为 win32_open_osfhandle()。在 Perl5.005 之前,调用 C 的 _open_osfhandle(),如果 GetFileType($hNativeHandle) 返回 FILE_TYPE_UNKNOWN,则会失败。对于 Perl5.005 及更高版本,OsFHandleOpen 从 Perl DLL 调用 win32_open_osfhandle(),它没有此限制。
$ivFD= OsFHandleOpenFd( $hNativeHandle, $uMode )基于已打开的 Win32 本地文件句柄 $hNativeHandle 打开文件描述符 [$ivFD]。这只是调用 Win32 特定的 C 函数 _open_osfhandle() 或 Perl 的“改进”版本,称为 win32_open_osfhandle()。在 Perl5.005 之前以及在 Cygwin Perl 中,调用 C 的 _open_osfhandle(),如果 GetFileType($hNativeHandle) 返回 FILE_TYPE_UNKNOWN,则会失败。对于 Perl5.005 及更高版本,OsFHandleOpenFd 从 Perl DLL 调用 win32_open_osfhandle(),它没有此限制。
$uMode 是 Fcntl 模块导出的零个或多个 O_* 常量的逻辑组合。目前只有 O_APPEND 和 O_TEXT 有意义。
如果打开操作成功,$ivFD 将为非负值。对于失败,将返回 -1,并且 $! [以及可能 fileLastError() 和 $^E] 将设置为失败的原因。
$olTargetLen= QueryDosDevice( $sDosDeviceName, $osTargetPath, $lTargetBuf )查找给定“DOS”设备名称的定义,返回活动的 Windows NT 本地设备名称以及任何当前处于休眠状态的定义。
$sDosDeviceName 是我们要查找其定义的“DOS”设备的名称。例如,"C:"、"COM1" 或 "PhysicalDrive0"。如果 $sDosDeviceName 为 [] [表示 NULL],则返回所有 DOS 设备名称的列表。
$osTargetPath 将被分配一个包含定义列表的字符串。每个定义都以 '\0' 结尾,并被连接到字符串中,最新的定义排在最前面,整个字符串的末尾有一个额外的 '\0' [请参阅 GetLogicalDriveStrings 以了解此格式的示例]。
$lTargetBuf 是为 $osTargetPath 分配的缓冲区的大小(以字节为单位)。有关更多信息,请参阅 "缓冲区大小"。
$olTargetLen 设置为写入 $osTargetPath 的字节数,但您也可以使用 length($osTargetPath) 来确定此值。
如果失败,则返回 0,并将 fileLastError() 和 $^E 设置为失败的原因。
ReadFile( $hFile, $opBuffer, $lBytes, $olBytesRead, $pOverlapped )从文件或类似文件的设备中读取字节。如果读取操作成功,则返回真值。如果失败,则返回假值,并将 fileLastError() 和 $^E 设置为失败的原因。
$hFile 是一个 Win32 本地文件句柄,它已打开到要从中读取的文件或设备。
$opBuffer 将被设置为包含已读取字节的字符串。
$lBytes 是您要读取的字节数。$opBuffer 会自动初始化为具有足够大的缓冲区来容纳这些字节。与其他缓冲区大小不同,$lBytes 不需要在前面加上 "=" 来防止将更大的值传递给底层的 Win32 ReadFile API。但是,即使启用了 Perl 警告,也会静默忽略前导 "="。
如果 $olBytesRead 不为 [],则它将被设置为实际读取的字节数,尽管也可以使用 length($opBuffer) 来确定此值。
$pOverlapped 是 [] 或者是一个打包成字符串的 OVERLAPPED 结构体。这只有在 $hFile 以 FILE_FLAG_OVERLAPPED 标志打开时才有效。
$uOldMode= SetErrorMode( $uNewMode )设置控制系统错误处理的模式 **并** 返回之前的模式值。$uOldMode 和 $uNewMode 都将设置以下一个或多个位
SEM_FAILCRITICALERRORS如果设置,则表示当遇到严重错误时,触发该错误的调用会立即失败。通常此位未设置,这意味着严重错误会导致出现一个对话框,通知桌面用户某个应用程序触发了严重错误。该对话框允许桌面用户决定是否将严重错误返回给进程,忽略它,或者重试有问题的操作。
这会影响 CreateFile 和 GetVolumeInformation 调用。
设置此位有助于检查软盘驱动器中是否有软盘。
SEM_NOALIGNMENTFAULTEXCEPT如果设置,这会导致内存访问对齐错误以对进程不可见的方式自动修复。此标志在基于 x86 的 Windows NT 版本上被忽略。此标志在 Windows 95 上不受支持。
SEM_NOGPFAULTERRORBOX如果设置,一般保护错误不会生成对话框,而是可以通过异常处理程序由进程处理。此位不应由不知道如何处理此类错误的程序设置。
SEM_NOOPENFILEERRORBOX如果设置,则当尝试继续从已打开的文件(通常在可移动介质上,如软盘)中读取或写入时发现文件不再可用,调用将立即失败。通常此位未设置,这意味着会出现一个对话框,通知桌面用户某个应用程序遇到了此问题。该对话框允许桌面用户决定是否将失败返回给进程,忽略它,或者重试有问题的操作。
这会影响 ReadFile 和 WriteFile 调用。
$uNewPos = setFilePointer( $hFile, $ivOffset, $uFromWhere )这是一个 Perl 友好的 SetFilePointer API 包装器(如下)。$ivOffset 可以是 64 位整数或 Math::BigInt 对象,如果您的 Perl 没有 64 位整数。返回值是新的偏移量,同样将是 64 位整数或 Math::BigInt 对象。
$uNewPos = SetFilePointer( $hFile, $ivOffset, $ioivOffsetHigh, $uFromWhere )seek() 的原生 Win32 版本。SetFilePointer 设置文件中的位置,下一个读或写操作将从此位置开始。
$hFile 是一个 Win32 原生文件句柄。
$uFromWhere 可以是 FILE_BEGIN、FILE_CURRENT 或 FILE_END,分别表示新文件位置是相对于文件开头、当前文件指针或文件结尾指定的。
$ivOffset 是 [如果 $ioivOffsetHigh 是 []] 相对于 $uFromWhere 指定的位置的偏移量 [以字节为单位]。如果 $ioivOffsetHigh 不是 [],则 $ivOffset 将被转换为无符号值,用作偏移量的低 4 个字节。
$ioivOffsetHigh 可以是 [] [表示 NULL],表示您只指定了 4 字节的偏移量,并且结果文件位置将为 0xFFFFFFFE 或更小 [略小于 4GB]。否则,$ioivOfffsetHigh 从偏移量的高 4 个字节 [带符号] 开始,并被设置为结果文件位置的 [无符号] 高 4 个字节。
底层的 SetFilePointer 返回 0xFFFFFFFF 表示失败,但如果 $ioivOffsetHigh 不为空,则还需要检查 $^E 来确定 0xFFFFFFFF 是否表示错误。Win32API::File::SetFilePointer 会为您执行此检查,并且仅当底层 SetFilePointer 失败时才返回 false 值。因此,如果您将文件指针设置为文件开头 [或任何低 4 字节为 0 的位置],则 $uNewPos 将设置为 "0 but true"。
因此,如果 seek 操作成功,则返回值为 true。如果失败,则返回 false 值,并将 fileLastError() 和 $^E 设置为失败的原因。
SetHandleInformation( $hObject, $uMask, $uFlags )设置与 Win32 本地文件句柄或对象句柄关联的标志。如果操作成功,则返回 true 值。如果失败,则返回 false 值,并将 fileLastError() 和 $^E 设置为失败的原因。
$hObject是一个打开的 Win32 本地文件句柄或一个打开的 Win32 本地句柄,指向其他类型的对象。
$uMask 是一个无符号值,其中设置了 HANDLE_FLAG_INHERIT 和 HANDLE_FLAG_PROTECT_FROM_CLOSE 中的一个或多个位。只有在 $uMask 中设置的位才会被 SetHandleInformation 修改。
$uFlags 是一个无符号值,其中设置了 HANDLE_FLAG_INHERIT 和 HANDLE_FLAG_PROTECT_FROM_CLOSE 中的零个或多个位。对于 $uMask 中设置的每个位,句柄标志中的对应位将设置为 $uFlags 中对应位的的值。
如果 $uOldFlags 是调用 SetHandleInformation 之前句柄标志的值,则之后句柄标志的值将为
( $uOldFlags & ~$uMask ) | ( $uFlags & $uMask )
[至少在 HANDLE_FLAG_INHERIT 和 HANDLE_FLAG_PROTECT_FROM_CLOSE 位方面是如此。]
请参阅 ":HANDLE_FLAG_" 导出类以了解这些位的含义。
WriteFile( $hFile, $pBuffer, $lBytes, $ouBytesWritten, $pOverlapped )将字节写入文件或类似文件的设备。如果操作成功,则返回 true 值。如果失败,则返回 false 值,并将 fileLastError() 和 $^E 设置为失败的原因。
$hFile 是一个 Win32 本地文件句柄,它已经打开到要写入的文件或设备。
$pBuffer 是一个包含要写入字节的字符串。
$lBytes 是您想要写入的字节数。如果 $pBuffer 的长度小于 $lBytes,WriteFile 会报错。您可以将 $lBytes 设置为 0 来写入 length($pBuffer) 个字节。在 $lBytes 前面加一个 "=" 会被静默忽略,即使启用了 Perl 警告也是如此。
$ouBytesWritten 将被设置为实际写入的字节数,除非您将其指定为 []。
$pOverlapped 为 [] 或是一个打包成字符串的 OVERLAPPED 结构。这只有在 $hFile 以 FILE_FLAG_OVERLAPPED 标志打开时才有用。
":FuncA"ASCII 特定的函数。每个函数都与没有尾部 "A" 的版本相同。
CopyFileA
CreateFileA
DefineDosDeviceA
DeleteFileA
GetDriveTypeA
GetFileAttributesA
GetLogicalDriveStringsA
GetVolumeInformationA
MoveFileA
MoveFileExA
QueryDosDeviceA
":FuncW"宽字符特定的 (Unicode) 函数。每个函数都与没有尾部 "W" 的版本相同,除了字符串预期为 Unicode,并且某些长度以 WCHAR 的数量而不是字节的数量来衡量,如下所示。
CopyFileW( $swOldFileName, $swNewFileName, $bFailIfExists )$swOldFileName 和 $swNewFileName 是 Unicode 字符串。
$swPath 是 Unicode。
DefineDosDeviceW( $uFlags, $swDosDeviceName, $swTargetPath )$swDosDeviceName 和 $swTargetPath 是 Unicode。
DeleteFileW( $swFileName )$swFileName 是 Unicode。
$uDriveType= GetDriveTypeW( $swRootPath )$swRootPath 是 Unicode。
$uAttrs= GetFileAttributesW( $swPath )$swPath 是 Unicode。
$olwOutLength= GetLogicalDriveStringsW( $lwBufSize, $oswBuffer )Unicode 存储在 $oswBuffer 中。$lwBufSize 和 $olwOutLength 以 WCHAR 的数量来衡量。
GetVolumeInformationW( $swRootPath, $oswVolName, $lwVolName, $ouSerialNum, $ouMaxNameLen, $ouFsFlags, $oswFsType, $lwFsType )$swRootPath 是 Unicode,Unicode 写入 $oswVolName 和 $oswFsType。$lwVolName 和 $lwFsType 以 WCHAR 数量衡量。
MoveFileW( $swOldName, $swNewName )$swOldName 和 $swNewName 是 Unicode。
MoveFileExW( $swOldName, $swNewName, $uFlags )$swOldName 和 $swNewName 是 Unicode。
$olwTargetLen= QueryDosDeviceW( $swDeviceName, $oswTargetPath, $lwTargetBuf )$swDeviceName 是 Unicode,Unicode 写入 $oswTargetPath。$lwTargetBuf 和 $olwTargetLen 以 WCHAR 数量衡量。
":Misc"杂项常量。用于 CreateFile 的 $uCreate 参数或 SetFilePointer 的 $uFromWhere 参数。加上 INVALID_HANDLE_VALUE,通常不需要检查,因为大多数例程将其转换为假值。
CREATE_ALWAYS CREATE_NEW OPEN_ALWAYS
OPEN_EXISTING TRUNCATE_EXISTING INVALID_HANDLE_VALUE
FILE_BEGIN FILE_CURRENT FILE_END
":DDD_"DefineDosDevice 的 $uFlags 参数的常量。
DDD_EXACT_MATCH_ON_REMOVE
DDD_RAW_TARGET_PATH
DDD_REMOVE_DEFINITION
":DRIVE_"GetDriveType 返回的常量。
DRIVE_UNKNOWN DRIVE_NO_ROOT_DIR DRIVE_REMOVABLE
DRIVE_FIXED DRIVE_REMOTE DRIVE_CDROM
DRIVE_RAMDISK
":FILE_"可以通过 CreateFile 的 $uAccess 参数请求的特定类型的文件访问。
FILE_READ_DATA FILE_LIST_DIRECTORY
FILE_WRITE_DATA FILE_ADD_FILE
FILE_APPEND_DATA FILE_ADD_SUBDIRECTORY
FILE_CREATE_PIPE_INSTANCE FILE_READ_EA
FILE_WRITE_EA FILE_EXECUTE
FILE_TRAVERSE FILE_DELETE_CHILD
FILE_READ_ATTRIBUTES FILE_WRITE_ATTRIBUTES
FILE_ALL_ACCESS FILE_GENERIC_READ
FILE_GENERIC_WRITE FILE_GENERIC_EXECUTE )],
":FILE_ATTRIBUTE_"文件属性常量。由 attrLetsToBits 返回,并在 CreateFile 的 $uFlags 参数中使用。
FILE_ATTRIBUTE_ARCHIVE FILE_ATTRIBUTE_COMPRESSED
FILE_ATTRIBUTE_HIDDEN FILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_OFFLINE FILE_ATTRIBUTE_READONLY
FILE_ATTRIBUTE_SYSTEM FILE_ATTRIBUTE_TEMPORARY
此外,GetFileAttributes 可以返回这些常量(或在发生错误时返回 INVALID_FILE_ATTRIBUTES)。
FILE_ATTRIBUTE_DEVICE FILE_ATTRIBUTE_DIRECTORY
FILE_ATTRIBUTE_ENCRYPTED FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
FILE_ATTRIBUTE_REPARSE_POINT FILE_ATTRIBUTE_SPARSE_FILE
":FILE_FLAG_"文件选项标志常量。用于 CreateFile 的 $uFlags 参数。
FILE_FLAG_BACKUP_SEMANTICS FILE_FLAG_DELETE_ON_CLOSE
FILE_FLAG_NO_BUFFERING FILE_FLAG_OVERLAPPED
FILE_FLAG_POSIX_SEMANTICS FILE_FLAG_RANDOM_ACCESS
FILE_FLAG_SEQUENTIAL_SCAN FILE_FLAG_WRITE_THROUGH
FILE_FLAG_OPEN_REPARSE_POINT
":FILE_SHARE_"文件共享常量。在 CreateFile 的 $uShare 参数中使用。
FILE_SHARE_DELETE FILE_SHARE_READ FILE_SHARE_WRITE
":FILE_TYPE_"文件类型常量。由 GetFileType 返回。
FILE_TYPE_CHAR FILE_TYPE_DISK
FILE_TYPE_PIPE FILE_TYPE_UNKNOWN
":FS_"文件系统特性常量。放置在 GetVolumeInformation 的 $ouFsFlags 参数中。
FS_CASE_IS_PRESERVED FS_CASE_SENSITIVE
FS_UNICODE_STORED_ON_DISK FS_PERSISTENT_ACLS
FS_FILE_COMPRESSION FS_VOL_IS_COMPRESSED
":HANDLE_FLAG_"修改对象句柄行为的标志位,通过 GetHandleInformation 和 SetHandleInformation 访问。
":IOCTL_STORAGE_"通用存储设备的 I/O 控制操作。在 DeviceIoControl 的 $uIoControlCode 参数中使用。包括 IOCTL_STORAGE_CHECK_VERIFY、IOCTL_STORAGE_MEDIA_REMOVAL、IOCTL_STORAGE_EJECT_MEDIA、IOCTL_STORAGE_LOAD_MEDIA、IOCTL_STORAGE_RESERVE、IOCTL_STORAGE_RELEASE、IOCTL_STORAGE_FIND_NEW_DEVICES 和 IOCTL_STORAGE_GET_MEDIA_TYPES。
IOCTL_STORAGE_CHECK_VERIFY验证设备的媒体是否可访问。$pInBuf 和 $opOutBuf 都应为 []。如果 DeviceIoControl 返回真值,则媒体当前可访问。
IOCTL_STORAGE_MEDIA_REMOVAL允许锁定或解锁设备的媒体。$opOutBuf 应为 []。$pInBuf 应为 PREVENT_MEDIA_REMOVAL 数据结构,它只是一个包含布尔值的整数。
$pInBuf= pack( "i", $bPreventMediaRemoval );
IOCTL_STORAGE_EJECT_MEDIA请求设备弹出媒体。$pInBuf 和 $opOutBuf 都应为 []。
IOCTL_STORAGE_LOAD_MEDIA请求设备加载媒体。$pInBuf 和 $opOutBuf 都应为 []。
IOCTL_STORAGE_RESERVE请求保留设备。$pInBuf 和 $opOutBuf 都应为 []。
IOCTL_STORAGE_RELEASE释放之前的设备预留。$pInBuf 和 $opOutBuf 都应该是 []。
IOCTL_STORAGE_FIND_NEW_DEVICES未找到有关此 IOCTL 操作的文档。
IOCTL_STORAGE_GET_MEDIA_TYPES请求有关设备支持的媒体类型的信息。$pInBuf 应该是 []。$opOutBuf 将被设置为包含一个 DISK_GEOMETRY 数据结构的向量,可以通过以下方式解码:
# Calculate the number of DISK_GEOMETRY structures returned:
my $cStructs= length($opOutBuf)/(4+4+4+4+4+4);
my @fields= unpack( "L l I L L L" x $cStructs, $opOutBuf )
my( @ucCylsLow, @ivcCylsHigh, @uMediaType, @uTracksPerCyl,
@uSectsPerTrack, @uBytesPerSect )= ();
while( @fields ) {
push( @ucCylsLow, unshift @fields );
push( @ivcCylsHigh, unshift @fields );
push( @uMediaType, unshift @fields );
push( @uTracksPerCyl, unshift @fields );
push( @uSectsPerTrack, unshift @fields );
push( @uBytesPerSect, unshift @fields );
}
对于第 $i 种支持的媒体类型,以下变量将包含以下数据。
":IOCTL_DISK_"磁盘设备的 I/O 控制操作。在 DeviceIoControl 的 $uIoControlCode 参数中使用。大多数这些操作用于物理驱动器设备,例如 "//./PhysicalDrive0"。但是,IOCTL_DISK_GET_PARTITION_INFO 和 IOCTL_DISK_SET_PARTITION_INFO 应该只用于单分区设备,例如 "//./C:"。此外,IOCTL_DISK_GET_MEDIA_TYPES 被记录为已被取代,但在用于软盘设备(如 "//./A:")时仍然有用。
包括 IOCTL_DISK_FORMAT_TRACKS、IOCTL_DISK_FORMAT_TRACKS_EX、IOCTL_DISK_GET_DRIVE_GEOMETRY、IOCTL_DISK_GET_DRIVE_LAYOUT、IOCTL_DISK_GET_MEDIA_TYPES、IOCTL_DISK_GET_PARTITION_INFO、IOCTL_DISK_HISTOGRAM_DATA、IOCTL_DISK_HISTOGRAM_RESET、IOCTL_DISK_HISTOGRAM_STRUCTURE、IOCTL_DISK_IS_WRITABLE、IOCTL_DISK_LOGGING、IOCTL_DISK_PERFORMANCE、IOCTL_DISK_REASSIGN_BLOCKS、IOCTL_DISK_REQUEST_DATA、IOCTL_DISK_REQUEST_STRUCTURE、IOCTL_DISK_SET_DRIVE_LAYOUT、IOCTL_DISK_SET_PARTITION_INFO 和 IOCTL_DISK_VERIFY。
IOCTL_DISK_GET_DRIVE_GEOMETRY请求有关磁盘大小和几何形状的信息。$pInBuf 应该是 []。$opOutBuf 将被设置为一个 DISK_GEOMETRY 数据结构,可以通过以下方式解码:
( $ucCylsLow, $ivcCylsHigh, $uMediaType, $uTracksPerCyl,
$uSectsPerTrack, $uBytesPerSect )= unpack( "L l I L L L", $opOutBuf );
IOCTL_DISK_GET_PARTITION_INFO请求有关分区大小和几何形状的信息。$pInBuf 应为 []。$opOutBuf 将被设置为 PARTITION_INFORMATION 数据结构,可以通过以下方式解码
( $uStartLow, $ivStartHigh, $ucHiddenSects, $uPartitionSeqNumber,
$uPartitionType, $bActive, $bRecognized, $bToRewrite )=
unpack( "L l L L C c c c", $opOutBuf );
$uStartLow 和 $ivStartHigh分区的起始偏移量的低位和高位 [分别] 4 个字节,以字节为单位。
$ucHiddenSects此分区的“隐藏”扇区数。实际上,这是在此分区之前找到的扇区数,即起始偏移量 [如 $uStartLow 和 $ivStartHigh 中找到的] 除以每个扇区的字节数。
$uPartitionSeqNumber此分区的序列号。分区从 1 开始编号 [“分区 0”表示整个磁盘]。有时此字段可能为 0,您需要从磁盘上多少个分区位于其前面来推断分区序列号。
$uPartitionType分区的类型。有关已知类型的列表,请参阅 ":PARTITION_" 导出类。另请参阅 IsRecognizedPartition 和 IsContainerPartition。
$bActive活动 [引导] 分区为 1,否则为 0。
$bRecognized此类型的分区是否在 Win32 下受支持。
$bToRewrite是否更新此分区信息。此字段不用于 IOCTL_DISK_GET_PARTITION_INFO。对于 IOCTL_DISK_SET_DRIVE_LAYOUT,您必须将此字段设置为真值,以表示您希望更改、添加或删除的任何分区。
IOCTL_DISK_SET_PARTITION_INFO更改分区的类型。$opOutBuf 应该为 []。$pInBuf 应该是一个 SET_PARTITION_INFORMATION 数据结构,它只是一个包含新分区类型的单个字节 [参见 ":PARTITION_" 导出类以获取已知类型的列表]
$pInBuf= pack( "C", $uPartitionType );
IOCTL_DISK_GET_DRIVE_LAYOUT请求有关磁盘布局的信息。$pInBuf 应该为 []。$opOutBuf 将被设置为包含 DRIVE_LAYOUT_INFORMATION 结构,包括多个 PARTITION_INFORMATION 结构
my( $cPartitions, $uDiskSignature )= unpack( "L L", $opOutBuf );
my @fields= unpack( "x8" . ( "L l L L C c c c" x $cPartitions ),
$opOutBuf );
my( @uStartLow, @ivStartHigh, @ucHiddenSects,
@uPartitionSeqNumber, @uPartitionType, @bActive,
@bRecognized, @bToRewrite )= ();
for( 1..$cPartition ) {
push( @uStartLow, unshift @fields );
push( @ivStartHigh, unshift @fields );
push( @ucHiddenSects, unshift @fields );
push( @uPartitionSeqNumber, unshift @fields );
push( @uPartitionType, unshift @fields );
push( @bActive, unshift @fields );
push( @bRecognized, unshift @fields );
push( @bToRewrite, unshift @fields );
}
$cPartitions如果磁盘上的分区数量。
$uDiskSignature是磁盘签名,由磁盘管理员 [WinDisk.exe] 分配的唯一号码,用于标识磁盘。这允许该磁盘上的分区的驱动器号保持不变,即使磁盘的 SCSI 目标 ID 发生更改。
有关这些字段的剩余信息,请参见 IOCTL_DISK_GET_PARTITION_INFORMATION。
IOCTL_DISK_GET_MEDIA_TYPES应该被 IOCTL_STORAGE_GET_MEDIA_TYPES 取代,但对于确定给定软盘驱动器可以产生的软盘格式类型仍然有用。有关示例,请参见 ex/FormatFloppy.plx。
IOCTL_DISK_SET_DRIVE_LAYOUT更改磁盘的分区布局。$pOutBuf 应该为 []。$pInBuf 应该是一个 DISK_LAYOUT_INFORMATION 数据结构,包括多个 PARTITION_INFORMATION 数据结构。
# Already set: $cPartitions, $uDiskSignature, @uStartLow, @ivStartHigh,
# @ucHiddenSects, @uPartitionSeqNumber, @uPartitionType, @bActive,
# @bRecognized, and @bToRewrite.
my( @fields, $prtn )= ();
for $prtn ( 1..$cPartition ) {
push( @fields, $uStartLow[$prtn-1], $ivStartHigh[$prtn-1],
$ucHiddenSects[$prtn-1], $uPartitionSeqNumber[$prtn-1],
$uPartitionType[$prtn-1], $bActive[$prtn-1],
$bRecognized[$prtn-1], $bToRewrite[$prtn-1] );
}
$pInBuf= pack( "L L" . ( "L l L L C c c c" x $cPartitions ),
$cPartitions, $uDiskSignature, @fields );
要删除分区,请将所有字段清零,除了 $bToRewrite,它应该设置为 1。要添加分区,请递增 $cPartitions 并将新分区的相关信息添加到数组中,确保将 1 插入 @bToRewrite。
有关字段的描述,请参见 IOCTL_DISK_GET_DRIVE_LAYOUT 和 IOCTL_DISK_GET_PARITITON_INFORMATION。
IOCTL_DISK_VERIFY对磁盘 [部分] 执行逻辑格式化。$opOutBuf 应该为 []。$pInBuf 应该包含一个 VERIFY_INFORMATION 数据结构
$pInBuf= pack( "L l L",
$uStartOffsetLow, $ivStartOffsetHigh, $uLength );
IOCTL_DISK_FORMAT_TRACKS格式化磁盘上的一个磁道范围。$opOutBuf 应该为 []。$pInBuf 应该包含一个 FORMAT_PARAMETERS 数据结构
$pInBuf= pack( "L L L L L", $uMediaType,
$uStartCyl, $uEndCyl, $uStartHead, $uEndHead );
$uMediaType 是要格式化的介质类型。主要用于指定格式化软盘时使用的密度。有关更多信息,请参见 ":MEDIA_TYPE" 导出类。
其余字段指定要格式化的磁道范围的起始和结束柱面以及磁头。
IOCTL_DISK_REASSIGN_BLOCKS将磁盘块列表重新分配到磁盘的备用块池。$opOutBuf 应该为 []。$pInBuf 应该是一个 REASSIGN_BLOCKS 数据结构
$pInBuf= pack( "S S L*", 0, $cBlocks, @uBlockNumbers );
IOCTL_DISK_PERFORMANCE请求有关磁盘性能的信息。$pInBuf 应该为 []。$opOutBuf 将被设置为包含一个 DISK_PERFORMANCE 数据结构
my( $ucBytesReadLow, $ivcBytesReadHigh,
$ucBytesWrittenLow, $ivcBytesWrittenHigh,
$uReadTimeLow, $ivReadTimeHigh,
$uWriteTimeLow, $ivWriteTimeHigh,
$ucReads, $ucWrites, $uQueueDepth )=
unpack( "L l L l L l L l L L L", $opOutBuf );
IOCTL_DISK_IS_WRITABLE未找到有关此 IOCTL 操作的文档。
IOCTL_DISK_LOGGING控制磁盘日志记录。没有找到有关此 IOCTL 操作的文档。它使用 DISK_LOGGING 数据结构
开始将每个磁盘请求记录在磁盘设备驱动程序内部的缓冲区中,该缓冲区的大小为 $uLogBufferSize
$pInBuf= pack( "C L L", 0, 0, $uLogBufferSize );
停止记录每个磁盘请求
$pInBuf= pack( "C L L", 1, 0, 0 );
将内部日志复制到提供的缓冲区中
$pLogBuffer= ' ' x $uLogBufferSize
$pInBuf= pack( "C P L", 2, $pLogBuffer, $uLogBufferSize );
( $uByteOffsetLow[$i], $ivByteOffsetHigh[$i],
$uStartTimeLow[$i], $ivStartTimeHigh[$i],
$uEndTimeLog[$i], $ivEndTimeHigh[$i],
$hVirtualAddress[$i], $ucBytes[$i],
$uDeviceNumber[$i], $bWasReading[$i] )=
unpack( "x".(8+8+8+4+4+1+1+2)." L l L l L l L L C c x2", $pLogBuffer );
将统计信息分组到基于请求大小的 bin 中。
$pInBuf= pack( "C P L", 3, $pUnknown, $uUnknownSize );
IOCTL_DISK_FORMAT_TRACKS_EX此 IOCTL 没有包含文档。
IOCTL_DISK_HISTOGRAM_STRUCTURE此 IOCTL 没有包含文档。
IOCTL_DISK_HISTOGRAM_DATA此 IOCTL 没有包含文档。
IOCTL_DISK_HISTOGRAM_RESET此 IOCTL 没有包含文档。
IOCTL_DISK_REQUEST_STRUCTURE未找到有关此 IOCTL 操作的文档。
IOCTL_DISK_REQUEST_DATA未找到有关此 IOCTL 操作的文档。
":FSCTL_"文件系统控制操作。在DeviceIoControl函数的$uIoControlCode参数中使用。
包括FSCTL_SET_REPARSE_POINT、FSCTL_GET_REPARSE_POINT、FSCTL_DELETE_REPARSE_POINT。
":GENERIC_"指定通用访问权限的常量,这些权限不特定于一种类型的对象。
GENERIC_ALL GENERIC_EXECUTE
GENERIC_READ GENERIC_WRITE
":MEDIA_TYPE"设备可以支持的不同媒体类别。在DISK_GEOMETRY结构的$uMediaType字段中使用。
Unknown格式未知。
F5_1Pt2_5125.25"软盘,1.2MB [实际上为1,200KB] 总空间,512字节/扇区。
F3_1Pt44_5123.5"软盘,1.44MB [实际上为1,440KB] 总空间,512字节/扇区。
F3_2Pt88_5123.5"软盘,2.88MB [实际上为2,880KB] 总空间,512字节/扇区。
F3_20Pt8_5123.5"软盘,20.8MB 总空间,512字节/扇区。
F3_720_5123.5"软盘,720KB 总空间,512字节/扇区。
F5_360_5125.25"软盘,360KB 总空间,512字节/扇区。
F5_320_5125.25"软盘,320KB 总空间,512字节/扇区。
F5_320_10245.25"软盘,320KB 总空间,1024字节/扇区。
F5_180_5125.25"软盘,180KB 总空间,512字节/扇区。
F5_160_5125.25 英寸软盘,总容量 160KB,每扇区 512 字节。
RemovableMedia除软盘以外的其他可移动介质。
FixedMedia固定硬盘。
F3_120M_5123.5 英寸软盘,总容量 120MB。
":MOVEFILE_"用于 MoveFileEx 函数的 $uFlags 参数中的常量。
MOVEFILE_COPY_ALLOWED MOVEFILE_DELAY_UNTIL_REBOOT
MOVEFILE_REPLACE_EXISTING MOVEFILE_WRITE_THROUGH
":SECURITY_"在打开命名管道客户端时,可以在 CreateFile 函数的 $uFlags 参数中使用的安全质量服务值。
SECURITY_ANONYMOUS SECURITY_CONTEXT_TRACKING
SECURITY_DELEGATION SECURITY_EFFECTIVE_ONLY
SECURITY_IDENTIFICATION SECURITY_IMPERSONATION
SECURITY_SQOS_PRESENT
":SEM_"与 SetErrorMode 函数一起使用的常量。
SEM_FAILCRITICALERRORS SEM_NOGPFAULTERRORBOX
SEM_NOALIGNMENTFAULTEXCEPT SEM_NOOPENFILEERRORBOX
":PARTITION_"描述分区类型的常量。
PARTITION_ENTRY_UNUSED PARTITION_FAT_12
PARTITION_XENIX_1 PARTITION_XENIX_2
PARTITION_FAT_16 PARTITION_EXTENDED
PARTITION_HUGE PARTITION_IFS
PARTITION_FAT32 PARTITION_FAT32_XINT13
PARTITION_XINT13 PARTITION_XINT13_EXTENDED
PARTITION_PREP PARTITION_UNIX
VALID_NTFT PARTITION_NTFT
":STD_HANDLE_"用于 GetStdHandle 和 SetStdHandle 函数的常量。
STD_ERROR_HANDLE
STD_INPUT_HANDLE
STD_OUTPUT_HANDLE
":ALL"以上所有。
目前尚无已知问题。
Tye McQueen,tye@metronet.com,http://perlmonks.org/?node=tye。
金字塔。