无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 257|回复: 13
打印 上一主题 下一主题

[讨论] 一些 PECMD 封装函数和调用 WinApi 示例代码

  [复制链接]
跳转到指定楼层
1#
发表于 昨天 19:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Bluebells 于 2026-1-17 21:39 编辑

一些实用的(?) PECMD 示例代码分享给大家参考参考
代码质量可能不太好, 一些术语描述可能有误, 因为本人没啥编程基础, 希望大家谅解

EFI 变量设置封装函数
简单的 Ini 文本文件读写封装函数
获取目标驱动器的磁盘号和分区号
判断当前安全启动状态
获取系统版本号
获取计算机名和当前登录用户名
脱机注册表封装函数
2#
 楼主| 发表于 昨天 19:20 | 只看该作者
  1.     ;IniRead 有五个参数, 第一个参数为目标 .ini 完整文件名, 第二个参数为节名, 第三个参数为键名, 第四个参数为默认值, 第五个参数为存放读取的值的变量
  2.     ;当无法读取目标键的值时, 其返回值(第五个参数变量值)将为默认值(第四个参数定义的值)
  3.     _SUB IniRead
  4.     TEAM ENVI &FileName=%~1| ENVI &SectionName=%~2| ENVI &KeyName=%~3| ENVI &DefValue=%~4
  5.     FIND %&FileName%=,EXIT _SUB
  6.     FIND %&SectionName%=,EXIT _SUB
  7.     FIND %&KeyName%=,EXIT _SUB
  8.     FIND %&DefValue%=,EXIT _SUB
  9.     CALL $--qd --ret:&ret Kernel32.dll,GetPrivateProfileStringW,$%&SectionName%,$%&KeyName%,$%&DefValue%,0,0,$%&FileName%
  10.     TEAM CALC #&CC = %&ret% + 1| CALC #&nSize = %&CC% * 2
  11.     SET$ &ValueName=*%&nSize% 0
  12.     CALL $--qd --ret:&ret Kernel32.dll,GetPrivateProfileStringW,$%&SectionName%,$%&KeyName%,$%&DefValue%,*&ValueName,#%&CC%,$%&FileName%
  13.     ENVI-ret %~5=%&ValueName%
  14.     _END

  15.     ;IniWrite 有四个参数, 第一个参数为目标 .ini 完整文件名, 第二个参数为节名, 第三个参数为键名, 第四个参数为值名, 第五个参数为返回值(若返回零则写入失败)
  16.     ;其中第四个和第五个参数为可选, 当第四个参数留空时, 将移除目标键的值
  17.     _SUB IniWrite
  18.     TEAM ENVI &FileName=%~1| ENVI &SectionName=%~2| ENVI &KeyName=%~3| ENVI &ValueName=%~4
  19.     FIND %&FileName%=,EXIT _SUB
  20.     FIND %&SectionName%=,EXIT _SUB
  21.     FIND %&KeyName%=,EXIT _SUB
  22.     CALL $--qd --ret:&ret Kernel32.dll,WritePrivateProfileStringW,$%&SectionName%,$%&KeyName%,$%&ValueName%,$%&FileName%
  23.     ENVI-ret %~5=%&ret%
  24.     _END
复制代码
PS: mdyblog 老大的 PECMD 的示例代码(readini.wcs)中有读取 Ini 文本文件的封装代码段, 不过挺复杂的


回复

使用道具 举报

3#
 楼主| 发表于 昨天 19:23 | 只看该作者
  1. ;只有一个输入参数和两个输出参数
  2. ;输入参数为路径, 支持驱动器号(盘符), 路径命名空间(\\?\HarddiskVolumeX, \\?\HarddiskX\PartitionX 等)
  3. ;第一个输出参数为设备号, 第二个输出参数为分区号
  4. _SUB GetDevicePartNum
  5.     SET &drv=%~1
  6.     ENVI-ret %~2=
  7.     ENVI-ret %~3=
  8.     SET &prefix=\\?\
  9.     SET &gr=
  10.     LSTR aStr1=4,%drv%
  11.     LSTR aStr2=7,%drv%
  12.     FIND $%aStr1%=\\?\,SET &prefix=
  13.     FIND $%aStr2%=\Device,SET &gr=GLOBALROOT
  14.    
  15.     SET &FILE_ANY_ACCESS=0x00000000
  16.     SET &OPEN_EXISTING=3
  17.     SET &IOCTL_STORAGE_GET_DEVICE_NUMBER=0x2D1080
  18.     SET$# &udtQuery=*4 0 *4 0 *4 0
  19.     ENVI$# &&cbBytesReturned=*8 0
  20.     CALL $--qd --ret:&&h Kernel32.dll,CreateFileW,$%prefix%%gr%%drv%,#0,#%FILE_ANY_ACCESS%,#0,#%OPEN_EXISTING%,#0,#0
  21.     IFEX #%h%=-1, EXIT
  22.     CALL $--qd --ret:&&ret Kernel32.dll,DeviceIoControl,#%h%,#%IOCTL_STORAGE_GET_DEVICE_NUMBER%,#0,#0,*&udtQuery,#12,*&cbBytesReturned,#0 //待处理
  23.     CALL $--qd --ret:&&ret Kernel32.dll,CloseHandle,#%h%
  24.     ENVI?int &udtQuery=&&DeviceNum:4
  25.     ENVI?int &udtQuery=&&PartNum:8
  26.     ENVI-ret %~2=%&DeviceNum%
  27.     ENVI-ret %~3=%&PartNum%
  28. _END

  29. GetDevicePartNum C: &1 &2
  30. GetDevicePartNum \\?\HarddiskVolume2 &3 &4
  31. MESS 设备(磁盘)号: %1%\n分区号: %2%\n\n设备(磁盘)号: %3%\n分区号: %4%
复制代码



回复

使用道具 举报

4#
发表于 昨天 19:30 | 只看该作者
了解
回复

使用道具 举报

5#
发表于 昨天 19:32 | 只看该作者
学习一下
回复

使用道具 举报

6#
发表于 昨天 19:47 来自手机 | 只看该作者
强贴留名
回复

使用道具 举报

7#
发表于 昨天 19:54 | 只看该作者
了解一下。
回复

使用道具 举报

8#
 楼主| 发表于 昨天 20:09 | 只看该作者
  1. ;此封装函数有三个参数, 第一个参数用于存放返回的操作系统主要版本号, 第二个参数用于存放返回的操作系统次要版本号, 第三个参数用于存放返回的操作系统内部版本号
  2. _SUB RtlGetVersion
  3.     SET$# &VersionInformation=*4 0 *4 0 *4 0 *4 0 *4 0 *256 0
  4.     SET-long &VersionInformation=276
  5.     CALL $--qd --ret:&ret ntdll.dll,RtlGetVersion,*&VersionInformation
  6.     IFEX #%&ret%<>0,EXIT
  7.     TEAM ENVI?int &VersionInformation=&MajorVersion:4| ENVI?int &VersionInformation=&MinorVersion:8| ENVI?int &VersionInformation=&BuildNumber:12
  8.     ENVI-ret %~1=%MajorVersion%
  9.     ENVI-ret %~2=%MinorVersion%
  10.     ENVI-ret %~3=%BuildNumber%
  11. _END

  12. ;参数同上
  13. _SUB GetNTVersion
  14.     TEAM SET-long &pMajorVersion=| SET-long &pMinorVersion=| SET-long &pBuildNumber=
  15.     CALL $--qd --ret:&ret ntdll.dll,RtlGetNtVersionNumbers,*&pMajorVersion,*&pMinorVersion,*&pBuildNumber
  16.     IFEX #%&ret%=0,EXIT
  17.     TEAM ENVI?int &pMajorVersion=&MajorVersion| ENVI?int &pMinorVersion=&MinorVersion| ENVI?int &pBuildNumber=&BuildNumber
  18.     CALC #&BuildNumber = %&BuildNumber% & 0xFFFF
  19.     ENVI-ret %~1=%MajorVersion%
  20.     ENVI-ret %~2=%MinorVersion%
  21.     ENVI-ret %~3=%BuildNumber%
  22. _END
复制代码
PS: RtlGetNtVersionNumbers 为非公开函数, 且支持系统版本范围为 NT5.1+; 感谢 wintoflash 老大帮忙处理获取正确的 BuildNumber 值


回复

使用道具 举报

9#
发表于 昨天 20:19 | 只看该作者
技术贴 支持
回复

使用道具 举报

10#
 楼主| 发表于 昨天 20:27 | 只看该作者
  1. ;获取计算机名称, 仅一个参数, 用于存放返回的计算机名称
  2. _SUB GetComputerName
  3.     SET$# &nSize=*4 0
  4.     CALL $--qd --ret:&ret Kernel32.dll,GetComputerNameW,*,*&nSize
  5.     ENVI?int &nSize=&BufferSize
  6.     IFEX $%&BufferSize%=0,EXIT _SUB
  7.     SET$ &lpBuffer=*%&BufferSize% 0
  8.     CALL $--qd --ret:&&ret Kernel32.dll,GetComputerNameW,*&lpBuffer,*&nSize
  9.     IFEX $%&ret%=0,EXIT _SUB
  10.     ENVI-ret %~1=%&lpBuffer%
  11. _END

  12. ;获取系统当前登录用户名, 仅一个参数, 用于存放返回的当前登录用户名
  13. _SUB GetUserName
  14.     ENVI-ret %~1=
  15.     SET$# &pcbBuffer=*4 0
  16.     CALL $--qd --ret:&ret Advapi32.dll,GetUserNameW,*,*&pcbBuffer
  17.     ENVI?int &pcbBuffer=&BufferSize
  18.     IFEX $%&BufferSize%=0,EXIT _SUB
  19.     SET$ &lpBuffer=*%&BufferSize% 0
  20.     CALL $--qd --ret:&ret Advapi32.dll,GetUserNameW,*&lpBuffer,*&pcbBuffer
  21.     IFEX $%&ret%=0,EXIT _SUB
  22.     ENVI-ret %~1=%&lpBuffer%
  23. _END

  24. ;调用示例
  25. CALL GetComputerName &ComputerName
  26. CALL GetUserName &UserName
  27. MESS 计算机名称: %&ComputerName%\n\n用户名: %&UserName%
复制代码

回复

使用道具 举报

11#
发表于 昨天 21:05 | 只看该作者
感谢分享!
回复

使用道具 举报

12#
发表于 昨天 21:22 | 只看该作者
谢谢分享
回复

使用道具 举报

13#
发表于 昨天 22:48 | 只看该作者
支持原创
回复

使用道具 举报

14#
发表于 12 小时前 | 只看该作者
学习一下。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2026-1-18 13:16

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表