无忧启动论坛

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

grub4dos 外部命令 wenv [2010-10-17 ]

  [复制链接]
571#
 楼主| 发表于 2010-10-19 00:02:03 | 只看该作者
原帖由 tuxw 于 2010-10-18 23:59 发表
if (*p_buff == *sub && memcmp(p_buff,sub,isub) == 0)
{
        strcpyn(str,rep,irep); // 这里溢出的话,后面检查长度是没用的
        str += irep;
        p_buff += isub;
        istr += irep; ...



哦,这里倒没有注意.
回复

使用道具 举报

572#
 楼主| 发表于 2010-10-19 00:05:27 | 只看该作者
原帖由 zhaohj 于 2010-10-18 23:57 发表
溢出有已经碰到过了,不知现在的限制条件是什么?一行小于511字符?


一条命令扩展之后的字符最好不要超过510.

当然可以在程序中加大缓存,目前命令行的缓存是512.
回复

使用道具 举报

573#
 楼主| 发表于 2010-10-19 00:15:05 | 只看该作者
OK,感谢tuxw.

已经修改重新上传,已经下载的麻烦重新下载.
回复

使用道具 举报

574#
发表于 2010-10-19 12:49:45 | 只看该作者
for /f ()中的文件名不支持路径,使用usebackq也无效。
如wenv for /f "eol=; tokens=1-2 delims==;" %i in ( (fd0)/TXTSETUP.SIF ) do ...
回复

使用道具 举报

575#
发表于 2010-10-19 13:19:33 | 只看该作者
做了个比较通用的txtsetup.sif转srsid.txt程式:
for /f第一次计算srsid.txt需要的文件大小
debug off
command --set-path=(bd)/GRUB/
map --mem /SRS_F6/F6.GZ (fd0)
map --hook
fat copy /SRS_F6/TXTSETUP.SIF (fd0)/
wenv calc p=6
wenv for /f "eol=; tokens=1-2 delims==;" %i in ( (fd0)/TXTSETUP.SIF ) do (set a=%i ; set a1=$${a:4} ; set a2=%j ; set b=$${a:0:3} ; check $${b}==PCI calc p=$${p}+$${a1,?}+$${a2,?}+8 ; check $${b}==[ha call kernel)
wenv calc *0x8290=${p}
fat mkfile size=* (fd0)/SRSID.TXT
write --offset=0 (fd0)/SRSID.TXT PCI$\r\n
wenv calc p=6
wenv for /f "eol=; tokens=1-2 delims==;" %i in ( (fd0)/TXTSETUP.SIF ) do (set a=%i ; set a1=$${a:4} ; set a2=%j ; set b=$${a:0:3} ; check $${b}==PCI call write --offset=$${p} (fd0)/SRSID.TXT $PCI\\$${a1}=$${a2}\r\n ; check $${b}==PCI calc p=$${p}+$${a1,?}+$${a2,?}+8 ; check $${b}==[ha call kernel)

[ 本帖最后由 zhaohj 于 2010-10-20 08:32 编辑 ]

Snap1.jpg (77.71 KB, 下载次数: 100)

Snap1.jpg
回复

使用道具 举报

576#
 楼主| 发表于 2010-10-19 16:32:54 | 只看该作者
原帖由 zhaohj 于 2010-10-19 12:49 发表
for /f ()中的文件名不支持路径,使用usebackq也无效。
如wenv for /f "eol=; tokens=1-2 delims==;" %i in ( (fd0)/TXTSETUP.SIF ) do ...


嗯,这是一个bug,稍后修正.
回复

使用道具 举报

577#
 楼主| 发表于 2010-10-19 18:22:44 | 只看该作者
已经修正.顺便添加
${VARIABLE,?}
取变量长度的功能,如果变量不存在得到的是0.
这样设计主要是为了方便以后扩展.

另外有两个彩蛋,比较少用的功能,有兴趣的可以研究一下源码.我在NTBOOT里面有用过.

[ 本帖最后由 chenall 于 2010-10-19 18:26 编辑 ]
回复

使用道具 举报

578#
发表于 2010-10-20 08:34:40 | 只看该作者
支持路径的文件名,for测试已经正常。
增加${var,?}取变量长度的功能,使程式更加简单明了。#575已使用新功能。
回复

使用道具 举报

579#
发表于 2010-10-20 17:34:48 | 只看该作者
7-Zip,它能够将文件夹或文件压缩成TAR格式,再将TAR文件压缩成GZIP,就实现了在Windows下把文件夹或文件打包成tar.gz格式压缩文件的目的。
问题:
怎样把这样的tar.gz解压到目标盘?
回复

使用道具 举报

580#
发表于 2010-10-20 20:27:56 | 只看该作者
@zhaohj:
1.用cmd批处理?还是用grub4dos命令?
2.解压释放出tar文件?还是原始未压缩的文件(夹)?
3.一次性压缩成gzip不更好?何必两重压缩?

[ 本帖最后由 zxw 于 2010-10-20 20:31 编辑 ]
回复

使用道具 举报

581#
发表于 2010-10-20 22:08:34 | 只看该作者
用grub4dos命令。
解压释放出原始未压缩的文件。windows下可以直接释放TAR.GZ
一次性不可能把文件夹压缩成gz吧?gzip没有压缩文件夹的功能吧。
回复

使用道具 举报

582#
发表于 2010-10-20 22:25:55 | 只看该作者
哦,是我考虑不周。文件夹的处理看来要chenall出手。
回复

使用道具 举报

583#
发表于 2010-10-20 22:40:09 | 只看该作者
linux下可以方便处理TAR.GZ,看来得把TAR命令移植过来。

如果把驱动打包成IMG.GZ,使用又不便。

[ 本帖最后由 zhaohj 于 2010-10-21 07:47 编辑 ]
回复

使用道具 举报

584#
发表于 2010-10-22 15:13:24 | 只看该作者
如果zhaohj大有时间弄出一个SRS_F6 grub4dos版,我现在上高中,没有什么时间好好修改成grub4dos版本

缺少部分功能先不用管,先弄出一个模板

ps:现在高中生活很不容易啊~
回复

使用道具 举报

585#
发表于 2010-10-22 16:42:40 | 只看该作者
现在的难点在驱动包,要么不打包放在SRS\OEM\、SRS\SRS1\、SRS\SRS2\等目录下,要么打包成IMG的格式。
不打包的好处是:可以按顺序搜索,先检查OEM,如果ID匹配就使用OEM;不匹配再检查SRS1驱动包,如果ID匹配就使用SRS1;...
如果按顺序全找不到,给出提示,并返回主菜单。
PXE启动的情况,优先使用PXE上的。但PXE无法find,只好规定只查找上面3个目录下。
另一种是手动输入路径的方式,如输入/srs/intel,这里intel是目录。

目前对OEM的处理没有很好的方法,下面是先把TXTSETUP.OEM转化为SRSID.TXT的程式:
debug off
command --set-path=(bd)/GRUB/
map --mem /SRS_F6/F6.GZ (fd0)
map --hook
fat copy /SRS_F6/TXTSETUP.OEM (fd0)/
wenv reset
wenv calc p=6
wenv for /f "eol=# tokens=1-3 delims==," %i in ( (fd0)/TXTSETUP.OEM ) do (set a=%i ; set b=%j ; set c=%k ; check $${a}==id calc p=$${p}+$${b,?}+$${c,?}+4)
wenv calc *0x8290=${p}
fat mkfile size=* (fd0)/SRSID.TXT
write --offset=0 (fd0)/SRSID.TXT PCI$\r\n
wenv calc p=6
wenv for /f "eol=# tokens=1-3 delims==," %i in ( (fd0)/TXTSETUP.OEM ) do (set a=%i ; set b=%j ; set c=%k ; check $${a}==id call write --offset=$${p} (fd0)/SRSID.TXT $PCI\\$${b:4}=$${c}\r\n ; check $${a}==id calc p=$${p}+$${b,?}+$${c,?}+4)

-----------------
另:FAT命令目前不支持通匹符*,这对OEM驱动的文件拷贝造成了麻烦(特别是PXE)。TXTSETUP.OEM的改造(编辑)也相对比较复杂。

[ 本帖最后由 zhaohj 于 2010-10-24 11:33 编辑 ]
回复

使用道具 举报

586#
发表于 2010-10-22 20:33:57 | 只看该作者

回复 #585 zhaohj 的帖子

做得挺好嘛,我们可以通过分析TXTSETUP.OEM 来获取要复制的文件
回复

使用道具 举报

587#
发表于 2010-10-23 15:25:29 | 只看该作者
wenv for /f  ["option"]能不能加个locate=string
wenv for /f  [locate=string] ["option"]
如果这一行匹配或这一行前面部分匹配,就从第一个匹配的string字符后面开始定位。

这个功能用处很大,对类的提取就很方便了。

[ 本帖最后由 zhaohj 于 2010-10-23 16:22 编辑 ]
回复

使用道具 举报

588#
发表于 2010-10-23 15:43:14 | 只看该作者
不知下面是否是BUG:
一个文本srsid.txt
id = "PCI\VEN_1000&DEV_0622", "symmpi"
id = "PCI\VEN_1000&DEV_0624", "symmpi"
id = "PCI\VEN_1000&DEV_0628", "symmpi"
id = "PCI\VEN_1000&DEV_0030", "symmpi"
-----------
wenv for /f "tokens=1-2 delims=," %i in ( /SRSID.TXT ) do (set a=%i ; set b=%j ; echo $${a} ; echo $${b})
上面‘,’作为分隔符就会出错
--------------
wenv for /f "tokens=1-2 delims==" %i in ( /SRSID.TXT ) do (set a=%i ; set b=%j ; echo $${a} ; echo $${b})
上面‘=’作为分隔符就正常;”tokens=1-3 delims==,"也正常。
-------------
这说明这行中如果有‘=’字符,等号一定要作为分隔符。这是否BUG?

可以这样测试,从一个文本读行,写入另一个文本,取消#开头的行
wenv for /f "eol=#" %i in ...
如果文本行中有‘=’字符,这行肯定写不全。

[ 本帖最后由 zhaohj 于 2010-10-23 15:57 编辑 ]
回复

使用道具 举报

589#
发表于 2010-10-23 22:33:32 | 只看该作者
这次动作相当大,除了FOR命令完全没动外(因为我自己不会使用FOR命令, zhaohj的问题还得chenall来解决),其它大部分模块进行了重写,加了比较完整的缓存溢出检查,基础函数都加强了安全处理,程序现在应该比较健壮了。但改动较大,很难保证不引入新的BUG,大家帮忙测试下。
2010-10-23
    打印超长变量时,省略号后添加实际长度
    修复设置变量最长只能到507的BUG
    重写变量/地址替换函数, 递归改为循环, 修复缓存溢出BUG
    变量嵌套完善,如 ${VAR:${s}:-${l}}
    支持 *$ 混合嵌套,如 ${*${addr}$}
    *ADDR 跟 *ADDR$ 一样可以用在任何地方

2010-10-22
    计算结果可以选择64位或32位, 16进制或10进制(二个开关切换)
    添加了两个开关
        USE_INT64   切换 *ADDR 读写时结果为64位或32位
        USE_HEX     *ADDR 打转换为字符串时用16进制或10进制
                    加引号用在 CHECK 命令中时会有不同的结果
    开关中为?的位不改变当前开关状态, 不需要写全部的开关状态位
    比如需要将算结果改为32位,只须
        WENV switch ?0,这样第一位开关不受影响,第二位为0

2010-10-21
    SWITCH 取消了两个试验性开关,只留下 ECHO_LN
    取变量长度同步chenall新版方法 ${VAR,?}
    (取消 ?_GET,这个功能时间不长,不用考虑兼容性)


在“程序菜单”保存和恢复当前设备很常见的方法
calc *0x60000=*0x82A0
calc *0x82A0=*0x60000
这个用法是有潜在问题的,因为它操作的是64位,0x82A4可能被意外修改

比如
calc *0x82A0=*0x8280
calc *0x829C=*0x8208
用引导设备恢复当前设备,看起来很完美,但这个用法很可能导致重启,0x82A0被覆盖了。
当然可以将上两行换个顺序来解决,但仍有未知的4个字节被意外覆盖,只是不会马上表现出问题来。

现在可以这样:
WENV call write 0x82A0=*0x8280  # *ADDR 现在可以用在 call 命令中
WENV call write 0x829C=*0x8208  # 利用write只能写入32位特性防止多写

WENV switch ?0  #计算结果改为32位
WENV calc *0x82A0=*0x8280
WENV calc *0x829C=*0x8208
WENV switch ?1  #恢复默认的64位

64位32位,16进制10进制示例


混合嵌套示例


超长变量显示


wenv-tuxw-2010-10-23.zip (35.45 KB, 下载次数: 16)

[ 本帖最后由 tuxw 于 2010-10-23 23:28 编辑 ]
回复

使用道具 举报

590#
 楼主| 发表于 2010-10-24 01:09:06 | 只看该作者
原帖由 zhaohj 于 2010-10-23 15:43 发表
不知下面是否是BUG:
一个文本srsid.txt
id = "PCI\VEN_1000&DEV_0622", "symmpi"
id = "PCI\VEN_1000&DEV_0624", "symmpi"
id = "PCI\VEN_1000&DEV_0628", "symmpi"
id = "PCI\VEN_1000&DEV_0030", "symmp ...



是因为引号的原因,你把引号去掉就正常了.目前是自动去除字符串的首尾引号和空格的.

这样得到%i = id = "PCI\VEN_1000&DEV_0030
%j = symmpi

在使用;连续执行时,引号是需要配对的..所以到后面的SET A=就出错了...

这样一来就出现了这个问题.

解决方法,使用WENV READ的方法来替换需要连续执行的命令.

目前的命令序列并不完善.建议还是用WENV READ比较安全.
回复

使用道具 举报

591#
发表于 2010-10-24 02:09:01 | 只看该作者
原帖由 chenall 于 2010-10-24 01:09 发表



是因为引号的原因,你把引号去掉就正常了.目前是自动去除字符串的首尾引号和空格的.

这样得到%i = id = "PCI\VEN_1000&DEV_0030
%j = symmpi

在使用;连续执行时,引号是需要配对的..所以到后面的SET ...


知道了原因,就比较好办了
加了个开关 DEL_QUOTE,切换引号是否当特殊字符剪掉
目前这个开关仅测试FOR,不影响CHECK命令

用下面的命令
WENV switch ???0
WENV /F "tokens=1-2 delims=," %i in ( /SRSID.TXT ) do (set a=%i ; set b=%j ; switch 0 ; echo $${a}-- ; switch 1 ; echo $${b})
WENV switch ???1



wenv-tuxw-2010-10-24.zip (35.03 KB, 下载次数: 21)


这样改一下比较好
WENV (switch ???0 ; reset a ; reset b)
WENV for ...
WENV (reset a ; reset b ; switch ???1)

因为 for 前后对引号的处理不一样,临时变量 a,b 中有可能含有引号,后续对 a,b 的操作有可能不正常,所以在 for 前后将它清掉,完全当成“临时”变量。

[ 本帖最后由 tuxw 于 2010-10-24 03:05 编辑 ]
回复

使用道具 举报

592#
发表于 2010-10-24 08:40:44 | 只看该作者
那现在switch  1 1 1 1 应该是默认值了。
                   |  |  |  |__引号处理,默认去掉前后引导
                   |  |  |__*ADDR 转字符串时用16进制或10进制,默认16进制
                   |  |__ 内存值时选择64位或32位,默认64位计算
                   |__ECHO自动换行,默认自动换行


-------------
wenv switch 建议在debug off状态下也能显示

[ 本帖最后由 zhaohj 于 2010-10-24 11:01 编辑 ]
回复

使用道具 举报

593#
发表于 2010-10-24 10:28:49 | 只看该作者
四个开关的顺序是:换行,64位,16进制,删除引号。WENV switch ???0表示前3个开关不变,第4个关掉(?为不改变状态)。WENV switch 0第1个关掉,其它不变。在debug on时,每次执行switch命令后都会显示当前的开关状态。

[ 本帖最后由 tuxw 于 2010-10-24 10:41 编辑 ]
回复

使用道具 举报

594#
发表于 2010-10-24 11:09:41 | 只看该作者
wenv switch 0(echo命令序列之间不换行)的写法很容易误解,还是写成
wenv switch 0???
数值是从个位开始的,所以wenv switch 0应该等同于wenv switch ???0。
回复

使用道具 举报

595#
发表于 2010-10-24 11:36:33 | 只看该作者
#585楼,原来正常,使用tuxw的24号版本,没通过,变量p的值不会变化。这里p值是计算写入文件的偏移长度。
switch使用默认。

请tuxw测试一下。

[ 本帖最后由 zhaohj 于 2010-10-24 12:39 编辑 ]
回复

使用道具 举报

596#
发表于 2010-10-24 13:08:47 | 只看该作者
原帖由 zhaohj 于 2010-10-24 08:40 发表
...wenv switch 建议在debug off状态下也能显示
...


这个是响应chenall的建议,将大部分信息放到debug on 状态了,现在只有除错信息外,提示性输出全在debug on状态了。我后来实际测试发现这样比较好,在菜单中执行的时候实际上关心输出,特别是在 read <FILE> 时,有输出的话屏幕比较乱。

原帖由 zhaohj 于 2010-10-24 11:09 发表
wenv switch 0(echo命令序列之间不换行)的写法很容易误解,还是写成
wenv switch 0???
数值是从个位开始的,所以wenv switch 0应该等同于wenv switch ???0。


switch 后面跟的是一个开关状态排列的字符串(不要将它想成数值就可以),从左到右每个字符对应一个开关。可以正好4个字符,也可以多于4个(只取前4个判断),也可以少于4个(只判断给出的字符数)
? 是保持,0 是关,1或其它是开
switch ab0d 等于 switch 1101
switch 0??? 这样写也可以,等价于 switch 0

原帖由 zhaohj 于 2010-10-24 11:36 发表
#585楼,原来正常,使用tuxw的24号版本,没通过,变量p的值不会变化。这里p值是计算写入文件的偏移长度。
switch使用默认。

我不大会用for命令,而且你正在做的这个驱动的事也不太懂,所以找问题要麻烦点。

wenv calc p=6
wenv for /f "eol=# tokens=1-3 delims==," %i in ( (fd0)/TXTSETUP.OEM ) do (set a=%i ; set b=%j ; set c=%k ; check $${a}==id calc p=$${p}+$${b,?}+$${c,?}+4)

命令中的 id 是哪里来的,实际使用的时候是个数字是吧?
我试了下面两条命令是正常的
WENV calc p=6
WENV (set a=8 ; set b=abc ; set c=123 ; check $${a}==8 calc p=$${p}+$${b,?}+$${c,?}+4)

p值不变,首先检查下 check 命令结果是否正常。
注意check命令如果一方是字符串,另一方是数字,则进制形式会有影响,可以 switch ??0 为10进制试试

刚发了个问题,WENV calc p=... 命令中 p 和 = 间不能有空格。试了下原版是正常的,这个是我修改带来的BUG,下面已修复。

wenv-tuxw-2010-10-24.zip (35.07 KB, 下载次数: 15)
回复

使用道具 举报

597#
发表于 2010-10-24 13:44:59 | 只看该作者
测试了一下,这个版本触动了哪个开关,在debug off下全显示了,不过这样调试还真不错,找到了问题所在

[ 本帖最后由 zhaohj 于 2010-10-24 13:48 编辑 ]

Snap1.jpg (72.98 KB, 下载次数: 81)

Snap1.jpg
回复

使用道具 举报

598#
发表于 2010-10-24 13:55:02 | 只看该作者
这个是我将 check 命令比较时的两个对象显示临时打开了,用来判断 check 命令的对象是否正常。

WENV calc p=6 这句根据开关状态p值有可能是6可也能是0x6。可以在之前用  switch ??0 确认为10进制。

但数制形式在计算命令中应该是没有影响的,计算结果均应正常。

[ 本帖最后由 tuxw 于 2010-10-24 14:06 编辑 ]
回复

使用道具 举报

599#
发表于 2010-10-24 14:06:30 | 只看该作者
计算结果有问题,看下面,5次循环

Snap2.jpg (40.14 KB, 下载次数: 89)

Snap2.jpg
回复

使用道具 举报

600#
发表于 2010-10-24 14:31:34 | 只看该作者
知道原因了,do (calc p=$${p}+$${a,?} ....

在for里第一次将 $${p} 都替换为29了,再次循环时它直接用29来代替,而不是再去读 $${p},所以只计算了一次。

为了适应*$混合的变量嵌套,我重写了替换函数,但不会用for命令,所以for里没有做相应的更改。我要先熟悉下for命令再来修复这个BUG。

[ 本帖最后由 tuxw 于 2010-10-24 14:34 编辑 ]
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-11-23 15:04

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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