无忧启动论坛

标题: grub4dos 外部命令 wenv [2010-10-17 ] [打印本页]

作者: chenall    时间: 2010-2-2 16:10
标题: grub4dos 外部命令 wenv [2010-10-17 ]
[功能说明]

在GRUB4DOS还没有支持变量之前可以暂时代替着使用变量的功能

最新版本下载地址

http://grubutils.googlecode.com

[使用方法]

注:变量名不能超过8个字符.
变量值不能超过512个字符
最多保存64个变量.
2010-10-06
1.添加四个比较符 ==,<>,>=,<=
例子:
wenv ${a}==abc && echo ${a} 等于 abc
wenv ${c} == 0x20 && echo ${c} = 0x20

2.支持按数字比较
例,以下都会返回真.
001 == 1 或 0x20 == 32
3.修正前面WENV SET XXX=
如果XXX变量不存在时会设置变量的BUG.

2010-10-05
   1.添加字符串处理功能,和linux shell类似.
      1).${VAR:x:y}  从x开始提取y个字符,如果x为负数则从倒数x个开始提取.
      
      以下提取的内容都不包含STRING字符串.
      2).${VAR#STRING}        提取STRING字符串后面的内容,从左往右第一个位置开始.
      3).${VAR##STRING} 提取STRING字符串后面的内容,从右往左第一个位置开始.
      4).${VAR%STRING}        提取STRING字符串前面的内容,从右往左第一个位置开始.
      5).${VAR%%STRING}        提取STRING字符串前面的内容,从左往右第一个位置开始.

2010-06-23
1.修正zhaohj 提到的一个BUG
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=159851&page=20#pid1984131
2.所有参数不区分大小写.(变量有)

2010-06-20
1.重写部份代码,优化效率,不再使用虚拟内存盘存放.而是直接使用内存地址0×40000(最多占用0×8200字节)
2.添加read命令,可以从指定文件中读取一序列命令执行(用于动态执行)
3.内置ECHO命令,使用wenv run ECHO时直接调用内置的echo功能显示.


2010-02-04
1.对run命令增强了一下

现在的run可以连续运行多条内部命令

命令与命令之前使用以下字符隔开
]]]  无条件执行
]]&  当前一条命令返回真时执行后面的语句.否则直接返回
]]|  当前一条命令返回假时执行后面的语句.否则直接返回.


2010-02-03
1.优化代码(替换变量的代码).
2.wenv run 允许使用*ADDR来获取指定内存的字符串(具体看后面的截图).
除了截图的方法外,还可以动态执行命令.
比如
write (md)0x300+1 map --status\0
wenv run *0x60000


嘿嘿,这就是之前想要的的动态执行命令效果.

注:读取内存是碰到\0(0x0)结束的,所以在写命令的时候后面最好再加\0.


2010-02-02
1.整合CALC功能并支持变量.命令格式 calc
wenv calc 表达式(同CALC命令).
唯一的区别是 = 前面如果是一个非数字字符串,则会把计算结果设为变量
例子
以下都会设置一个变量a
wenv calc a=*0x60000+1
wenv calc a=*0x60000

wenv calc a=${a} + 1 或 wenv calc a= ${a} ++
注:暂时还不能直接 wenv calc a++,以后会考虑支持.
2.全面支持变量.

wenv set a=1
a=1
wenv set b=${a}
b=1
wenv calc c=${a}+${b}
c=2












[ 本帖最后由 chenall 于 2010-10-17 09:55 编辑 ]

20100202160541204.png (16.12 KB, 下载次数: 474)

20100202160541204.png

20101009222005254.png (10.11 KB, 下载次数: 370)

20101009222005254.png

20101014083916635.png (11.6 KB, 下载次数: 343)

复杂的变量嵌套

复杂的变量嵌套

20101013181254251.png (1.21 KB, 下载次数: 391)

for的例子

for的例子

20101013175906648.png (1.48 KB, 下载次数: 346)

20101013175906648.png

作者: chenall    时间: 2010-2-2 16:16
原理很简单.
读取其中一个扇区作为变量名的存放位置.

目前使用第65个扇区放变量名.

然后根据这个变量名所在的位置(以8个字节对齐)读取/写入 对应扇区的值 获取/设置 变量.


                    WENV 使用说明 (readme)
                    
                    chenall 整理于 2010-10-12
WENV 是一个基于GRUB4DOS的程序,可以用它来增强GRUB4DOS的脚本能力,来现一些不可思议的功能。
WENV 最初只支持简单变量和运行GRUB4DOS命令。到了现在已经支持各式各样的处理。
可以把让它当成是GRUB4DOS的增强形SHELL,方便各位grub4dos fans编写高效强大的菜单。
在这里要感谢无论启动论坛上众多朋友的支持,如果没有你们,WENV还只是一个小玩具。
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=159851
取之于网络,共享于网络。
本说明文件来源于无忧论坛zhaohj提供的README.TXT,我经过修改整理而成。
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=159851&page=46#pid2056205
如有发现错误,请通知我,谢谢。
WENV目前支持的命令列表(wenv-commands):
    SET         设置/修改/新增/删除变量
    GET         显示变量/判断变是是否存在
    FOR         类似于CMD的FOR命令,具体见后面介绍
    CALL        执行一个GRUB4DOS内部命令
    CALC        简易计算器(没有优先级从左往右计算,不支持括号)
    ECHO        在屏幕上显示信息
    READ        分析一个文件并执行里面的命令(必须是WENV支持的命令),并且支持参数。
    CHECK       判断/检测相当于if命令,后面可以跟WENV-COMMAND(当判断的返回值为真时执行)
两个内置变量:
?_WENV          保存上一次wenv call运行的返回值
?_GET           保存上一次wenv get variable变量的长度
一:SET 设置/修改/新增/删除变量
   
    1.WENV SET [variable=[string]]
    variable  指定环境变量名,区分大小写 (目前最多允许用户定义60个变量)
              不超过8个字符.可以使用字母(a-z/A-Z)、数字(0-9)、下划线(_)。不可以使用数字开头。
    string    指定要指派给变量的一系列字符串。不能超过512字节。
   
    无等号时显示指定名称的所有变量的值。
    SET P
   
    会显示所有以字母 P 打头的变量
   
    2.等号后面可以跟"$U,"或"$L,"
        $U,全转变为大写;
        $L,全转变为小写;
   
        例子: WENV SET a=$U,aBcDeF  得到 a=ABCDEF
    3.关键字 $input,来获取从键盘输入的字符。
        例子:获取从键盘输入的字符串,并转换为大写赋值给srspath
        WENV set srspath=$u,$input,please input SRS driver path:
   
    4.一些组合例子:
        WENV SET variable=$U,string
        WENV SET variable=$U,$input,Prompt
        
二、 GET 显示变量/判断变是是否存在
    GET 命令可以显示指定的变量,并设置?_GET为该变量的字符串长度。
   
    WENV get xxx
    返回变量xxx的值的字符串长度.
   
    注: 如果变量不存在会返回一个失败的值0,可以用于判断变量是否存在
    如: 当变量abc不存在时显示字符串"Variable abc not defined"
        wenv get abc || echo Variable abc not defined
三、FOR 类拟于CMD的for
   比较强大的一个命令,可以分析字符串,文本文件。
   语法:
      FOR /L %variable IN (start,step,end) DO wenv-command
      该集表示以增量形式从开始到结束的一个数字序列。因此,(1,1,5)将产生序列
      1 2 3 4 5,(5,-1,1)将产生序列(5 4 3 2 1)
      
      FOR /F ["options"] %variable IN ( file ) DO wenv-command
      FOR /F ["options"] %variable IN ("string") DO wenv-command
   如果有 usebackq 选项:
      FOR /F ["options"] %variable IN (`string`) DO wenv-command
      options
       eol=c           - 指一个行注释字符的结尾(就一个)
       delims=xxx      - 指分隔符集。这个替换了空格和跳格键的
                         默认分隔符集。
       tokens=x,y,m-n  - 指每行的哪一个符号被传递到每个迭代
                         的 for 本身。这会导致额外变量名称的分配。m-n
                         格式为一个范围。通过 nth 符号指定 mth。
       usebackq        - 反向引号
      
     几个例子 分析myfile.txt的每一行,使用";"作为注释符,使用","分隔字符串,显示每行的第二和第三个字符串
      FOR /F "eol=; tokens=2,3 delims=," %i in ( myfile.txt ) do echo %i %j
      
      显示从1-10的数字
      FOR /L %i in (1,1,10) do echo %i
      
      以下语句会显示 1 2 3 6
      FOR /f "tokens=1-3,6" %i in ("1 2 3 4 5 6 7 8 9 0") do echo %i %j %k %l
      
      可以参考CMD的for命令帮助说明.
四、CALL 命令
    WENV call grub4dos-builtincmd
    CALL 命令用于执行GRUB4DOS内部命令,使得可以动态执行一些GRUB4DOS的命令.
   
    可以使用变量或*ADDR$代替命令的任意部份。
    例子:
   
    wenv set a=(hd0)
    wenv call map ${a} (hd1)
    扩展了变量${a} 相当于执行map (hd0) (hd1)
    wenv call write (fd0)/aa.txt *0x60000$
    这个会扩展*0x60000$,把从内存地址0X60000处的字符复制到命令行
   
    如果内存地址0x60000处有字符串abcdef
   
    那扩展后就是write (fd0)/aa.txt abcdef
    甚至还可以直接 wenv call ${mycmd}
    会扩展变量mycmd,如果它是一个GRUB4DOS内部命令,则会得到执行,否则返回失败值。
    call 可以连续运行多条内部命令,命令与命令之间使用以下字符隔开
    ]]]  无条件执行
    ]]&  当前一条命令返回真时执行后面的语句.否则直接返回
    ]]|  当前一条命令返回假时执行后面的语句.否则直接返回.
五、calc 命令 用于grub4dos的简单计算,从左到右计算,不支持优先级
    WENV calc [[VAR |
  • INTEGER]=]
  • INTEGER OPERATOR [
  • INTEGER]
       
        calc 命令可以直接操作内存中的数据,请使用*ADDR的形式。
        =前面如果是一个非数字字符串,则会把计算结果赋值给变量;
        OPERATOR:包含+、-、*、/、&(与)、|(或)、^(位异或)、>>、<<
        *INTEGER表示内存地址的值;
        如:
        WENV calc a=*60000+1        表示把内存地址0x60000的值再加1赋值给变量a
        WENV calc a=1<<10           左移10位,即2的10次方,等于1024
        WENV calc a=b++             a=b,b=b+1
        WENV calc a=++b             b=b+1,a=b
        WENV calc a=b--             a=b,b=b-1
        WENV calc a=--b             b=b-1,a=b
        WENV calc a++               变量a的值加1;
       
        注:calc可以对变量进行计算,但一般情况下请使用如下的例子获得更快的运算速度。
        wenv calc a=${b}+${c}
        以上的例子不会对变量b和c进行修改。
       
        wenv calc a=${b}+c++
        这个例子会修改变量c的值
    六、echo 命令
        WENV ECHO strings
       
        用于显示一个字符串,支持\x转义符。比如\n是一个回车。
    七、READ 命令
        WENV READ wenv-bat-file parameters
       
        用于执行一个WENV的批处理文件,该批处理文件里面必须是 wenv-commands。
        忽略以冒号":"开头的行。
       
        在批处理中可以使用参数$0-$9
        其中: $0 代表批处理文件自身。$1-$9 分别代表第一个参数到第九个参数。
       
        参数之间使用空格分隔。
       
        一个例子:
        wenv.bat文件内容如下
        echo $0
        echo $1
        echo $2
        使用命令WENV READ /wenv.bat abcd 12345
        将会在屏幕上显示如下内容
        /wenv.bat
        abcd
        12345
    八:CHECK 判断命令相当于IF命令
        1.WENV check string1 compare-op string2 wenv-command
       
        比较符号可以使用其中一个: ==、<>、>=、<=
       
        where compare-op may be one of:
        == – equal
        <> – not equal
        <= – less than or equal
        >= – greater than or equal
        注: 注意比较时,后面的字符串忽略小写对比.
        如:
        abc==ABC 值为真
        aBc==abc 值为假
        abc==aBc 值为真.
        只要前面部分某个字符是大写,后面部分对应的一定要大写才能匹配
    其它说明:
        1、要使用命令序列,可以把要执行的命令放在()之内,使用" ; "分隔每个命令。
           格式: (wenv-command1 ; wenv-command2 ; wenv-command3)
           应用的例子:
       
                      wenv (set a=1 ; set b=2 ; set c=3)
                      wenv for /l %i in (1,1,5) do (set a=%i ; echo %i)
       2、从内存中复制字符串 *ADDR$
          说明:程序执行时会从内存地址ADDR处复制一个字符串替换命令行的*ADDR$
          例子:显示内存地址0x60000处的字符串信息
          wenv echo *0x60000$
          执行时先复制内存0x60000处的字符串到命令行替换后再执行。

    通用字符串处理(以下方法可以应用于任何地方)
       
       1: ${VAR:X:Y}
        提取第X个字符后面的Y个字符,如果X为负数则从倒数第X个开始提取Y长度的字符;
        如果Y的值为空则提取第X个字符后面的所有有字符;
        如果Y的值为负数,则去掉倒数Y个字符;
        WENV set a=ABCDabcd1234
        WENV set b=${a:4:4}     得到b=abcd
        WENV set b=${a:-8:4}    得到b=abcd
        WENV set b=${a:4:-4}    得到b=abcd
        WENV set b=${a:-8:-4}   得到b=abcd
       
       2: ${VAR#STRING} 删除STRING前面的字符.
        WENV set a=ABCD;abcd;1234
        WENV set b=${a#;}       得到b=abcd;1234
       
       3: ${VAR##STRING} 删除STRING前面的字符,贪婪模式
        WENV set a=ABCD;abcd;1234
        WENV set b=${a##;}      得到b=1234
       
       4: ${VAR%STRING} 删除STRING后面的字符.
        WENV set a=ABCD;abcd;1234
        WENV set b=${a%;}       得到b=ABCD;abcd
       
       5: ${VAR%%STRING} 删除STRING后面的字符,贪婪模式
        WENV set a=ABCD;abcd;1234
        WENV set b=${a%%;}       得到b=ABCD
       6: 支持嵌套变量。
       像下面的例子:
        wenv echo ${${${a:0:1}:0:1}}
    一些应用举例:
            1)根据提示从键盘输入,全转为大写后保存给srspath变量
            WENV set srspath=$u,$input,please input SRS driver path:
            2)设置变量a,并把值全转为大写
            WENV set a=ABCDabcd1234
            WENV set a=$u,${a}
            得到a=ABCDABCD1234
            3)清除某个变量
            WENV set a=        =后为空,清除变量a
            4)清除某些字符开头的所有变量
            WENV reset a*      清除a开头的所有变量
            WENV reset sr*     清除sr开头的所有变量
            5)清除所有变量
            WENV reset
            6)显示所有变量信息(不包括内置变量)
            WENV set
            7)显示所有以prefix开头的变量
            WENV set prefix
    wenv call 的例子:
        如:
        WENV set imgpath=/SRS_f6/srs_f6.IMG
        WENV set imgpath=$u,${imgpath}
        WENV call map --mem ${imgpath} (fd0)
        map --hook
        可以动态执行命令,如:
        write (md)0x300+1 map --status\0
        WENV call *0x60000$
       
    wenv check 的例子:
        如:WENV set a=abc
            WENV check ${a}==abc && echo ${a}=abc
            WENV calc a=123
            WENV check ${a}==123 && echo ${a}=123
            WENV check ${a}<=150 check ${a}>=100 && echo ${a}>=100.and.${a}<=150
        上面实现了IF语句功能.

    [ 本帖最后由 chenall 于 2010-10-14 08:41 编辑 ]
    作者: sratlf    时间: 2010-2-2 16:19
    和编程越来越像了啊   支持了
    作者: pseudo    时间: 2010-2-2 16:45
    强!

    wenv set oem_srs=右边
    右边能否包含变量

    能否用变量值
    作四则运算符
    作||、&&
    作者: chenall    时间: 2010-2-2 16:46
    目前没有考虑到这些,汗....
    作者: NicTense    时间: 2010-2-2 17:10
    这个不像calc只是处理2个数值了

    如果要支持运算,那就要象dos的set那样考虑多种情况了,包括字符串和数值运算,还要考虑变量嵌套,就比较复杂了

    不过如果只是支持数值双目运算,就可以借助calc写地址

    这里的set只要增加一个前置识别符*,当*开头时,读入地址值
    作者: chenall    时间: 2010-2-2 17:33
    因为GRUB4DOS目前只允许同时有一个外部命令在运行,所以是没有办法通过这个来调用calc的

    wenv set aaa=右边

    这个右边的变量自动扩展倒是比较容易.

    运算就比较麻烦了.

    写这个命令是因为像CPSE/0PE 还有zhhsh 的F6模块, 等使用了不同地址的SRS文件名但其实内容是可以通用的.

    这样在合盘时就可以使用同一个SRS驱动了.

    ^_^..

    运算目前还是通过CALC就基本可以满足了.

    [ 本帖最后由 chenall 于 2010-2-2 17:34 编辑 ]
    作者: chenall    时间: 2010-2-2 20:03
    准备把CALC的功能整合进来.
    这样就可以支持简单的计算功能了.

    计算功能加上变量 再加上GOTO
    可以做一个简单的循环了.^_^


    明天再弄了.

    [ 本帖最后由 chenall 于 2010-2-2 20:06 编辑 ]
    作者: NicTense    时间: 2010-2-2 20:54
    呵呵,新版本的话
    如果
    fallback 0
    .....
    goto 0
    就算goto文件没有,效果也是一样的,就是要提前fallback而已

    如果再加上一个for,就差不多完工了
    已经接近于basic了

    for还是得靠你了,我纯粹是试试编着玩的,c都忘光了,就算编好我都不敢用了

    [ 本帖最后由 NicTense 于 2010-2-2 20:56 编辑 ]
    作者: NicTense    时间: 2010-2-3 00:27
    wenv run COMMAND 后面的参数能不能加上对前置符*的支持啊
    跟calc一样,当前置符*被指定时,视为内存地址并从该地址取值

    这样能解决很多原来解决不了的问题
    作者: chenall    时间: 2010-2-3 00:50
    可以加,但是可能会有冲突,

    像cat 命令也有*内存地址的.

    还有一点.
    关于命令执行时*取的内存地址如果是数值,到底应该转换成字符型数据还是使用原来的数据呢?
    作者: chenall    时间: 2010-2-3 01:15
    下班之前再更新一下..整合calc命令和更全面的变量支持.

    见顶楼..
    作者: NicTense    时间: 2010-2-3 01:30
    原帖由 chenall 于 2010-2-3 00:50 发表
    可以加,但是可能会有冲突,

    像cat 命令也有*内存地址的.

    还有一点.
    关于命令执行时*取的内存地址如果是数值,到底应该转换成字符型数据还是使用原来的数据呢?



    cat命令有*吗,我看readme和help都没找到cat有*号的说明啊
    如果确实有 *号的冲突问题,解决方法也很简单
    前置*,读内存,前置**,则不读内存,把 *内存地址 作为字符串参数

    执行时取数值还是原来的数据,这个要看你打算做到什么程度

    如果不打算支持字符串的运算,仅支持数值双目运算,那我建议内存也只读数值

    如果是打算支持字符串的各种相关操作,那么最好就得能判断内存指向的是一个数值,还是字符串
    即允许该内存地址是一个字符串的入口指针

    [ 本帖最后由 NicTense 于 2010-2-3 01:45 编辑 ]
    作者: chenall    时间: 2010-2-3 01:34
    附上一个例子,根据当前系统的硬盘数量依次后移..

    map (hd0) (hd1)
    map (hd1) (hd2)
    ....

    wenv init
    default 0
    timeout 5

    title 0
    #获取当前硬盘数量(旧的方法)
    #清除0x60000的值
    #write 0x60000 0
    #dd if=(md) of=(md) bs=1 count=1 skip=0x475 seek=0x60000
    #设置变量到hd 最大硬盘号码
    #wenv calc hd=*0x60000 + 0x7F
    #获取当前硬盘数量(新的方法)
    wenv calc hd=*0x475 & 0xff
    wenv calc hd=${hd} + 0x7f
    #转到菜单1
    goto 1

    title 1
    ##不用解释了以,当前硬盘号+1 作为目的映射磁盘.
    wenv calc hd1=${hd}++
    ##....执行map命令.
    wenv run map (${hd}) (${hd1})
    ##如果计算后硬盘号 <> 0x7f 就继续...否则循环结束.硬盘编号是从0x80开始的.
    checkrange 0x7F wenv calc hd=${hd}-- || goto 2
    map --status
    map --hook
    pause

    另外,目前变量保存的数值是16进制的,下次改成用10进制的.10进制的使用比较方便.

    [ 本帖最后由 chenall 于 2010-2-3 17:29 编辑 ]
    作者: chenall    时间: 2010-2-3 01:39
    标题: 回复 #13 NicTense 的帖子
    这个得再讨论一下.看要用什么方式比较好.

    个人认为.
    对于wenv run command
    出现的内存地址应该是指向一个字符串的地址...
    作者: NicTense    时间: 2010-2-3 02:00
    标题: 回复 #15 chenall 的帖子
    也行的
    这样凡是需要读内存数值的就通过wenv calc 实现

    wenv calc a=*0x829c >> 16
    然后 ${a}就代表当前分区了,再用变量代入 wenv run就行

    有wenv calc之后,wenv run支不支持读地址已经不是那么重要了
    作者: chenall    时间: 2010-2-3 02:47
    #14后面的goto 2应该是goto 1.我写错了。
    作者: zhaohj    时间: 2010-2-3 11:26
    wenv帮助信息写一下,现在还没有集成。
    作者: zhaohj    时间: 2010-2-3 11:42
    wenv使用了一个虚拟磁盘(25)存放
    那么,wenv uninit后相当于
    map --unmap 25
    map --rehook
    了吗?
    作者: NicTense    时间: 2010-2-3 12:19
    原帖由 chenall 于 2010-2-3 01:34 发表
    #清除0x60000的值
    write 0x60000 0
    #获取当前硬盘数量
    dd if=(md) of=(md) bs=1 count=1 skip=0x475 seek=0x60000


    既然是新命令的例子,就不要用dd和write了

    calc *0x60000=*0x475 & 0xff


    问题解决了,也不用清除
    作者: chenall    时间: 2010-2-3 17:42
    OK,更新了...

    基本搞定...

    我认为这是GRUB4DOS的一个利器..嘿嘿.
    作者: chenall    时间: 2010-2-4 00:01
    对run命令增强了一下

    现在的run可以连续运行多条内部命令

    命令与命令之前使用以下字符隔开
    ]]]  无条件执行
    ]]&  当前一条命令返回真时执行后面的语句.否则直接返回
    ]]|  当前一条命令返回假时执行后面的语句.否则直接返回.

    比grub4dos原来的&& ||更强大了.

    只可惜不能调用外部命令.

    ....

    [ 本帖最后由 chenall 于 2010-2-4 00:04 编辑 ]

    wenv.zip

    6.02 KB, 下载次数: 129, 下载积分: 无忧币 -2


    作者: NicTense    时间: 2010-2-4 00:19
    这几个符号看上去好不习惯啊,是不是考虑换一下
    例如

    ]&
    ]&&
    ]||
    作者: chenall    时间: 2010-2-4 00:48
    因为编程的方便,也保证这些符号比较少用到.

    前面两个字符是固定的用于定位.(也可以设置为其它任意两个字符,只要这两字符基本上不会连续出现在命令行中就好了.)

    改天我再想办法看能不能增强一下GRUB4DOS原来的&& || 让它可以连续运行多个命令.

    这样子这个命令就可以不用了.

    [ 本帖最后由 chenall 于 2010-2-4 00:49 编辑 ]
    作者: NicTense    时间: 2010-2-4 00:56
    标题: 回复 #24 chenall 的帖子
    相比来说,直接增强grub4dos的&& ||命令更好
    我一直觉得那个&& ||用起来好痛苦
    无数行判断条件一样的 checkrange

    另外就是看看能不能把 calc和goto 变成内部函数,这两个的代码都很小的
    但是很常用,也很实用

    另外就是 calc的表达式是不是用这个更准确呢


    一个就够了,最后一项貌似也是加中括号的

    calc *0x60000 ++

    [ 本帖最后由 NicTense 于 2010-2-4 01:04 编辑 ]
    作者: chenall    时间: 2010-2-4 01:47
    允许连续执行多个命令的grldr测试

    目前只改了命令行的.只能在命令行下测试.

    grldr.rar

    112.42 KB, 下载次数: 120, 下载积分: 无忧币 -2


    作者: NicTense    时间: 2010-2-4 03:07
    标题: 回复 #26 chenall 的帖子
    root (fd0)
    checkrange 0x80 read 0x82a0 && uuid (hd0,0) || uuid (fd0) && ls /

    结果只出来read的结果,跟原来的版本一样

    我的语法有错吗
    作者: chenall    时间: 2010-2-4 09:34
    因为checkrange返回假。后面的当然不能执行了
    作者: zhaohj    时间: 2010-2-4 09:53
    C大,新版本1.23的grldr有一个小毛病,在菜单中选择菜单项的时候,
    default 1
    timeout 10
    title 0
    ....
    如果第一次用“向上箭头”选择菜单项,下方会一直出现时间倒计时,用“向下箭头”选择就不会出现时间倒计时。这是一个BUG

    另感觉新版grldr比较占用内存,ZZHSH的SRS_F6,128M内存都无法进入“user menu",望有空C大查查原因。
    作者: NicTense    时间: 2010-2-4 09:55
    标题: 回复 #28 chenall 的帖子
    不是相当于  if 条件 命令 else 命令 吗
    如果是应该会执行 || 后面的才对啊

    你的意思是改造之后,只能连续执行命令,当第一个不执行,则后面的都不会执行吗
    作者: zhaohj    时间: 2010-2-4 10:17
    原帖由 NicTense 于 2010-2-4 09:55 发表
    不是相当于  if 条件 命令 else 命令 吗
    如果是应该会执行 || 后面的才对啊

    你的意思是改造之后,只能连续执行命令,当第一个不执行,则后面的都不会执行吗


    && 前面是真时执行后面的命令
    ||  前面是假时执行后面的命令

    既然是连续执行命令,当某个不执行时,则后面的都不会执行

    [ 本帖最后由 zhaohj 于 2010-2-4 10:21 编辑 ]
    作者: NicTense    时间: 2010-2-4 10:30
    标题: 回复 #31 zhaohj 的帖子
    我还以为是 if ...else...

    这样要实现if...else...至少还是要2个一样的 checkrange
    作者: pseudo    时间: 2010-2-4 11:57
    如果
    允许嵌套||和&&,并可加括号表示优先级
    http://bbs.znpc.net/viewthread.php?tid=5842&page=1&fromuid=14511#pid43913

    则if else可通过加括号实现。

    可能要通过堆栈之类的机制来支持这种括号嵌套。

    1、变量
    2、(嵌套)||和&&
    3、goto
    是构成程序结构的基本要素。1、3目前差不多了,2最好再加强一下,更方便些。

    [ 本帖最后由 pseudo 于 2010-2-4 12:09 编辑 ]
    作者: chenall    时间: 2010-2-4 12:01
    实现if else在内部命令可能比较麻烦。

    外部命令可以考虑写一个if命令来实现。
    作者: netwinxp    时间: 2010-2-4 12:04
    既然有那么多要求,那我觉得你直接用C语言编一个类似BASIC的解释器(BASIC解释器比较容易实现)得了:)
    作者: NicTense    时间: 2010-2-4 12:13
    标题: 回复 #35 netwinxp 的帖子
    两回事啊,c大是用极小的代码换来grub质的飞跃

    现在做的事情是由针对性的,而不是编译器那种具通用性的东西啊
    作者: chenall    时间: 2010-2-4 12:15
    呵呵,N版说的是。

    一些比较简单的实用的功能可以考虑实现,比较复杂的就没有必要了。
    作者: pseudo    时间: 2010-2-4 12:18
    原帖由 netwinxp 于 2010-2-4 12:04 发表
    既然有那么多要求,那我觉得你直接用C语言编一个类似BASIC的解释器(BASIC解释器比较容易实现)得了:)

    版主所言极是
    chenall兄可以考虑做一个特别的外部命令,其作用是命令解释器,类似Pro*C、SQLJ。
    作者: NicTense    时间: 2010-2-4 12:23
    标题: 回复 #34 chenall 的帖子
    哦,我明白了,我弄错了一个东西
    && || 并不是 checkrange 的符号,是grub本身的符号

    算了,可以连续执行已经比原来好很多了

    if的外部命令,感觉跟 checkrange有点同质化,等于一个增强版的checkrange
    作者: chenall    时间: 2010-2-4 12:25
    原帖由 pseudo 于 2010-2-4 12:18 发表

    版主所言极是
    chenall兄可以考虑做一个特别的外部命令,其作用是命令解释器,类似Pro*C、SQLJ。


    汗。。。

    这些可不是一个简单的工程。。

    我的C也是刚起步,以我目前的情况根本不可能。。

    (我学习,是需要用到什么东西就去学什么。所以我学的很乱,甚至还有一些很基础的东西我都没有接触过。)


    其实pseudo也可以自己考虑编写一些外部程序。。
    作者: NicTense    时间: 2010-2-4 12:42
    这样子行不行

    当条件为false时,找到并执行其后面的第一个||跟着的命令,而其前面的所有命令将被跳过
    同样的
    当条件为true时,找到并执行其后面的第一个&&跟着的命令,其前面的所有命令同样被跳过

    执行完该命令后,继续按以上原则找到并执行下一条命令,直到命令行完毕

    也不用括号了,还是顺序关系,改造起来应该不太难
    这样就可以实现 if else了,虽然嵌套规则上有点不同
    作者: chenall    时间: 2010-2-4 17:14
    这样改造会很混乱...


    还不如再写一个if命令更简单.

    类似c语言那样

    if (表达式) 命令1 else 命令2
    作者: chenall    时间: 2010-2-4 18:48
    我想这样的grldr应该基本能够满足像
    if xxx else之类的要求了

    虽然效果不是很理想..但是勉强可以用.

    新增加了一个 ! 符号必须配合&& ||使用.

    前面的语句执行出错时就跳到!后面执行

    例子
    当echo外部命令存在,echo1不存在
    以下命令
    echo aa && echo bb || echo cc ! echo dd

    先执行
    echo aa 成功
    后面的符号是&&
    继续执行echo bb 成功
    后顺的符号是 ||
    所以echo cc不执行.直接跳到echo dd

    又如下
    echo1 aa && echo bb && echo cc ! echo dd

    echo1 aa执行失败,后面的符号是&&所以后面的语句不会执行直接跳到!后面!
    执行echo dd


    当然了这样和 真正的 if 命令还是相差很远.

    [ 本帖最后由 chenall 于 2010-2-27 19:02 编辑 ]
    作者: NicTense    时间: 2010-2-4 21:22
    看上去还不错,换了个符号,可以避免意外错误导致的||乱转

    这样 if 命令可以不要了,应该够用了

    我试试有没有bug再来报告
    作者: chenall    时间: 2010-2-4 23:06
    原帖由 zhaohj 于 2010-2-4 09:53 发表
    C大,新版本1.23的grldr有一个小毛病,在菜单中选择菜单项的时候,
    default 1
    timeout 10
    title 0
    ....
    如果第一次用“向上箭头”选择菜单项,下方会一直出现时间倒计时,用“向下箭头”选择就不会出现时间 ...



    我自己试了一下没有发现这个问题..

    另外"128M内存都无法进入“user menu",

    单单这条信息无法确定是GRLDR的问题..
    作者: NicTense    时间: 2010-2-5 03:47
    测试了一下,基本上没什么问题,可以用了,就是逻辑上跟if else不太一样,用的时候注意就是了

    title u盘启动后的从本地硬盘启动菜单
    checkrange 0x80 read 0x8280 && rootnoverify (hd1) ! rootnoverify (hd0)
    chainloader +1

    就是如果当条件为真时不需要执行任何东西,当条件为假时要执行一串命令,就只能

    条件 || 命令1 && 命令2 ...
    或者
    条件 && ! 命令1 && 命令2...

    而不能

    条件 ! 命令1 && 命令2

    也就是 ! 之前至少要有一个 && 或者 ||  否则就会出错

    这个也无可厚非,就像 if else 可以没有else 但是不能没有if

    所以结论就是这个方案基本上应该够用了
    作者: zhaohj    时间: 2010-2-5 09:47
    2.4版测试通过,发个完整版吧!
    C大有没有考虑把几个新开发的常用命令也集成进去,我们收藏一下!
    作者: NicTense    时间: 2010-2-5 10:16
    标题: 回复 #47 zhaohj 的帖子
    呵呵,我觉得 calc 和 goto 比较适合内置,因为用到的地方特别多,而且代码小,也就增加2k多
    作者: chenall    时间: 2010-2-5 18:23
    http://grub4dos-chenall.googleco ... 4.5a-2010-02-05.zip

    内置了calc命令的版本,有空试下看有没有什么BUG.

    另外给fallback命令加了一个参数 --go 相当于goto功能.(未公开参数,不对使用这个功能的后果负责)
    例子.
    fallback --go 2

    还有一点.因为fallback命令的返回值为真.
    以下句语是合法的,并且会执行echo bb语句.
    fallback --go 2 && echo bb

    还有 && ||的改进(同样属未公开,所以不对使用这个功能的后果负责)

    以上两个功能使用起来比较混乱,所以不公开.自己小心就是.

    [ 本帖最后由 chenall 于 2010-2-5 18:29 编辑 ]
    作者: NicTense    时间: 2010-2-5 19:11
    标题: 回复 #49 chenall 的帖子
    hoho,听起来有点害怕,我豁出去了。。。

    如果给fallback加参数的话
    按grub4dos的传统习惯,这个参数貌似应该是  --force

    个人觉得有calc和goto,这个grub在功能上应该算是完满了,
    剩下的像ghostid,fat,wenv这些应该外置就可以了
    毕竟都属于比较个性化的功能
    就是如果有可能的话,多几个人帮忙找bug,然后做一个新的稳定版本
    作者: chenall    时间: 2010-2-5 19:44
    嘿嘿,即然是未公开的就不用讲究那么多了.

    用--go代表马上跳转也挺直观的..


    另外
    现在的calc 允许多个从左到右的计算.(相对之前的版本只是加了两行代码而已,就顺便支持一下了,也比较方便,)

    注:这个是没有优先级的,只是依次从左边算到右边.

    例子
    calc 1+2+3+4+5+6+7+8+9+10
    calc *0x60000 = *0x8284 >> 8 & 0xff

    还有以下也是合法的,一个++代表+1
    calc 1++++++++++++
    作者: zhaohj    时间: 2010-2-6 13:25
    fallback 2 与fallback --go 2不是一样的吗?为何要加这个参数?
    作者: chenall    时间: 2010-2-6 18:20
    呵呵,不公开的命令参数..
    懂得用的就用,不懂的就不要乱用了...

    具体可以看下前面的贴子.
    作者: NicTense    时间: 2010-2-6 20:12
    哈哈,这个是grub的彩蛋

    对了,c大,echo,这个你最开始的例子是不是也考虑内置了

    这个功能也很实用的,1行代码

    下个版本考虑一下吧
    作者: chenall    时间: 2010-2-6 20:28
    echo没有必要吧,目前的PAUSE命令就可以实现同样的功能.
    作者: NicTense    时间: 2010-2-6 21:54
    呵呵,区别就是,pause会暂停
    作者: chenall    时间: 2010-2-6 22:18
    pause --wait=0
    不暂停的
    作者: NicTense    时间: 2010-2-6 22:22
    好吧,我错了。。。

    对了,我在看那些不常用的命令,有个问题

    module 和 modulenounzip

    这两个命令是用来装载什么文件的

    我没弄懂这两个命令和kernel的区别

    还有 outline 是干吗用的,我找了老半天也没找到这个资料,什么是字符轮廓模式?

    [ 本帖最后由 NicTense 于 2010-2-7 01:50 编辑 ]
    作者: NicTense    时间: 2010-2-7 01:43
    哈哈,新版本很不错

    修正部分usb-zip启动后root为(fd0,0)的问题

    checkrange 0 read 0x8280 && checkrange 0 calc 0=*0x8208 >> 16 && root (fd0) && calc *0x8208 | 0xff0000

    从本地硬盘启动
    checkrange 0x80 read 0x8280 && rootnoverify (hd1) ! rootnoverify (hd0)
    chainloader +1

    [ 本帖最后由 NicTense 于 2010-2-7 03:22 编辑 ]
    作者: 不点    时间: 2010-2-7 06:52
    module 和 modulenounzip

    当 kernel 加载了一个内核后,内核也可能需要某些模块,这时候就可以用上述两条命令了。很少用到。

    outline 是图形模式下显示字符笔画的边框。在图形模式下,如果 splashimage 的颜色与字符颜色很接近,则字符就不能看清。有了 outline,给字符加上轮廓,就可以看清字符了。outline 对文本模式不起作用。
    作者: NicTense    时间: 2010-2-7 11:35
    标题: 回复 #60 不点 的帖子
    谢谢不点
    我从来不用图形模式,怪不得我怎么试都没试出outline on 之后有什么区别

    关于module
    是不是就是说,载入 kernel 模块后
    如果该引导系统还要求载入其他模块,除了initrd初始化内存模块,其他模块则必须通过module 或 modulenounzip载入
    作者: pseudo    时间: 2010-2-7 12:32
    标题: 回复 #59 NicTense 的帖子
    手头有(fd0,0 )的环境吗?
    这种环境下0PE(1220以后版本)能否直接启动?
    作者: NicTense    时间: 2010-2-7 12:36
    标题: 回复 #62 pseudo 的帖子
    被我格式化成usb-fdd了
    貌似我测试的结果,grub4dos无法处理(fd0,0)的情况,会导致mount分区错误
    只要在内置菜单最开始加上这行
    checkrange 0 read 0x8280 && checkrange 0 calc 0=*0x8208 >> 16 && root (fd0) && calc *0x8208 | 0xff0000
    问题就解决了

    这个跟0pe应该没什么关系
    因为如果不修改以上内存值,则root分区和(bd)都是不可读的,u盘上任何文件包括menu.lst都无效,0pe也不例外


    但是我目前不确定的是

    在我的电脑上 grub4dos将启动设备定位为 (fd0,0)但是又无法mount分区,必须重新定位为(fd0)才能工作

    这种情况对grub4dos来说,不知道是通性,还是特例

    我不知道在其他电脑上,grub4dos是否能处理(fd0,0),反正在我的电脑上是不行的

    [ 本帖最后由 NicTense 于 2010-2-7 12:40 编辑 ]
    作者: chenall    时间: 2010-2-7 22:39
    可以试试以下的方法解决

    checkrange 0 read 0x8280 && root (fd0) || calc *0x829c=0xffff

    检测当前root设备是否为(fd0).如果是的话再检测(fd0)是否可以访问,
    如果不行就修改为(fd0,0)
    作者: pseudo    时间: 2010-2-7 23:02
    回复 #63 NicTense 的帖子

    还是想知道(fd0,0 )环境下0pe的情况,执行到哪句出问题。
    如果卡在无参数root处(只为显示调试信息),可删掉该行(0pe的grldr内置菜单用fbinsttool编辑),应该就可以启动了。

    回复 #64 chenall 的帖子

    &&、||现在可以连用、嵌套了? 跟]]&等有何区别?
    作者: NicTense    时间: 2010-2-7 23:14
    标题: 回复 #65 pseudo 的帖子
    其实不用测试的,你看菜单就知道在哪行,反正如果不加上面那行的话,读任何文件都会出错
    root也会出错,返回false,但是不会影响继续执行下面的语句
    用find是可以的,因为会重新定位root,但是find我不喜欢的原因是经常定位到硬盘去了(有同样目录同样文件的情况下)

    && ||是内部符号,]]&是外部命令的wenv的符号
    && ||的逻辑关系是,先从第一个顺序判断,当值与后面的符号相符时,则继续执行,否则,跳到后面的第一个!处继续执行
    作者: chenall    时间: 2010-2-7 23:19
    标题: 回复 #65 pseudo 的帖子
    这个新版未公开的功能

    具体可以参考NicTense 的解释.还有本贴前几页也有相关的介绍.

    另外calc也是新版的内部命令.
    作者: NicTense    时间: 2010-2-7 23:20
    原帖由 chenall 于 2010-2-7 22:39 发表
    可以试试以下的方法解决

    checkrange 0 read 0x8280 && root (fd0) || calc *0x829c=0xffff

    检测当前root设备是否为(fd0).如果是的话再检测(fd0)是否可以访问,
    如果不行就修改为(fd0,0)



    这个方法如果像我那种情况就不能完美解决

    root (fd0) 返回正,但是(bd)依然是(fd0,0),所以凡是用到(bd)的就会出错,比如

    command的默认路径

    我现在就是不知道有没有一些u盘是必须(fd0,0)才能读取,而(fd0)则不行的
    作者: chenall    时间: 2010-2-7 23:29
    我CSPE里面就把CSPE所在文件夹设置为bd了

    首先菜单前面用一句root (bd)
    检测完以后再修改(bd)为当前root
    calc *0x8280=*0x82A0
    calc *0x8208=*0x829C

    这样不管后面的命令用到多少find --set-root
    都可以通过(bd)/cspe/xxx
    来访问文件,省去了来回转换root的麻烦.
    作者: pseudo    时间: 2010-2-7 23:52
    标题: 回复 #66 NicTense 的帖子
    ls ()/grldr会出错?
    作者: NicTense    时间: 2010-2-7 23:55
    原帖由 pseudo 于 2010-2-7 23:52 发表
    ls ()/grldr会出错?


    当然,()=(fd0,0),会显示无法mount当前分区的
    作者: NicTense    时间: 2010-2-9 03:56
    我将另外一个u盘格式化为usb-zip,这次更厉害
    启动需要大概5分钟才能进入grub引导界面
    进去后我看了一下
    (bd)和(root)被定位为 (fd0,3)
    由于zip格式天生异丙,唯一的一个分区是占用mbr中第4个分区项的
    就是不知道为什么同样是zip,同样是写的第4项,之前那个就是 (fd0,0),而这个是 (fd0,3)

    不过被认作(fd0,0)和(fd0,3)的后果相差很大
    前者不影响引导到grub的速度,所以只须改写2个内存值就可以解决问题
    而后者,到执行内置菜单第一行程序的时候就需要5分钟
    改写内存值的命令行也要等5分钟才会被执行到。。。太郁闷了
    我明天试试把 分区表的值改一下,把第4项复制到第1项看看怎么样
    作者: chenall    时间: 2010-2-9 13:15
    嘿嘿,还是弃用ZIP格式吧,能HDD就用HDD
    速度快,兼容性也比较好.
    作者: NicTense    时间: 2010-2-9 15:27
    标题: 回复 #73 chenall 的帖子
    hdd的确是最好的,唯一的问题是默认情况下会占用第一硬盘位置,但这个对grub4dos来说不是问题,而且pe也有盘符整理程序

    但是问题是,稍微老一点点的电脑,(3年以前的)很多都不支持hdd的

    这种情况下,fdd也比zip强,特别是对grub4dos来说

    看样子grub4dos对zip的容错处理非常差

    不过zip有一个优势

    就是既有可能被支持fdd的认作fdd,也有可能被支持hdd的认作hdd

    只要能支持u盘启动的电脑,无论支持哪种格式,基本上都能检测到zip格式的u盘
    剩下的问题就是能不能成功启动了

    所以如果能找到zip被认出后却不能成功启动出错的原因所在,并解决了这个问题的话
    zip格式是最有希望能在最多电脑上都能启动的格式
    作者: chenall    时间: 2010-2-9 17:33
    OK,更新了,修正了当内存低于128MB时不能运行的问题.
    作者: NicTense    时间: 2010-2-9 22:27
    被忽悠了
    我知道usb-zip出错的根本原因了
    在启动初期,即执行内置菜单之前
    grub4dos读到的是启动扇区的0扇区
    然后在这里会卡上5分钟
    但是从执行内置菜单开始
    则会跳过前32个扇区,也就是(fd0)+1实际上是 (fd0)+32
    然后就会卡死,如果这个时候把u盘拔出
    再插入,则(fd0)的前32个扇区彻底被忽略
    这时只要修正(bd)和root区就可以正常读写

    而且我在两个电脑(一个海尔a10和一个微型u100)都是一样的结果
    用bootice格式化的usb-zip

    试了usboot格式化的usb-zip,区别就是bootice的zip格式是标准的zip格式,仅有一个分区位于最后一个分区项
    而usboot则是设在第一个分区项,所以会有(fd0,3)和(fd0,0)的区别
    但无论哪个,结果都是悲剧

    算了,我放弃usb-zip了。。。。

    [ 本帖最后由 NicTense 于 2010-2-9 22:48 编辑 ]
    作者: NicTense    时间: 2010-2-9 23:04
    对了,有个问题想确认一下
    find的查找顺序是 优先从(bd)查找,还是按设备号的顺序查找

    还有就是,是不是所有版本(不点和chenall的版本)都是统一的查找顺序的?
    作者: kook213    时间: 2010-3-8 17:08
    原帖由 chenall 于 2010-2-4 18:48 发表
    我想这样的grldr应该基本能够满足像
    if xxx else之类的要求了

    虽然效果不是很理想..但是勉强可以用.

    新增加了一个 ! 符号必须配合&& ||使用.

    前面的语句执行出错时就跳到!后面执行

    例子
    当echo外 ...


    学到了,又
    作者: hhh333    时间: 2010-5-9 21:03
    时空不好进,在此反馈一个bug,可能与这个主题无关,但用最新版0503的splashimage出错,错误表现

         出错语句:splashimage /BOOT/GRUB/BACK.XPM.GZ。

    1、当调用文件位于NTFS分区时出现,运行至此屏幕左上出现一个横线光标,但并未死机,且可“摸黑”进菜单项。
    2、将文件解开,但NTFS分区形式不变,可以进入。
    3、文件不变,但将磁盘格为FAT32,故障消失。
    4、其他位于光盘上时也无问题。
    作者: chenall    时间: 2010-5-9 22:33
    哪个版本可以,哪个版本不行?

    还是哪版本以后全部不行?
    作者: hhh333    时间: 2010-5-10 09:21
    标题: 回复 #80 chenall 的帖子
    刚才将手头有的版本都测试了一下,090331发布的0.44及其以后的到100503均不行,前面的版本未测试。
    把我的图传一个给你吧: BACK.XPM.GZ (2.23 KB, 下载次数: 104)

    这个应该是一个重要而明显的bug,以前难道没人碰到?应该是将g4d安装到NTFS时且使用压缩格式的背景时出现。应该不是我测试的问题,开始是bootmgr->grldr.mbr->grldr,后面又用ntldr->grldr,故障依旧。看过此帖的网友都可试一下。

    [ 本帖最后由 hhh333 于 2010-5-10 09:49 编辑 ]
    作者: wofeiyingme    时间: 2010-5-10 09:34
    哦...謝謝LZ分享 用上了額 哈哈 感恩~
    作者: pseudo    时间: 2010-5-10 10:32
    @hhh333
    换个背景图试试?换个压缩后体积6K以上的。
    作者: zhaohj    时间: 2010-5-10 11:08
    有个地方不理解,请大大解释一下:
    0x800开始的8个扇区(4kb)存放的是内置菜单

    动态执行命令
    write (md)0x300+1 map --status\0
    wenv run *0x60000
    上面的0x300怎么理解?测试结果是正确的。
    作者: 不点    时间: 2010-5-10 11:47
    @zhaohj:

    0x300 是扇区序号。物理地址就是 0x300 * 0x200 = 0x60000 了。

    @all

    back.xpm.gz 文件有个对应的 8.3 格式的短文件名 backxp~1.gz,这个打开却是正常的。估计问题出在 NTFS 驱动程序内部。chenall 看看能否解决,实在不行,请 bean 来解决。

    注意,在 grub 命令行之下,可以比较 FAT32 之下的和 NTFS 之下的内容相同的文件:

    cmp (hd0,0)/back.xpm.gz (hd0,7)/back.xpm.gz

    还可以用

    cat --length=120 (hd0,0)/back.xpm.gz
    cat --length=120 (hd0,7)/back.xpm.gz

    来比较两个文件开头的差别。
    作者: zhaohj    时间: 2010-5-10 14:18
    谢谢不点!
    write写入设备时(此处是(md))以是扇区序号来表示的,如果是整个设备,表示整个设备的全部扇区。


    做了两个IMG,一个fat,一个ntfs(启用压缩),没发现差异

    [ 本帖最后由 zhaohj 于 2010-5-10 14:37 编辑 ]

    Snap1.jpg (93.41 KB, 下载次数: 311)

    Snap1.jpg

    作者: zhaohj    时间: 2010-5-10 14:53
    在虚拟机硬盘上也未见差异

    [ 本帖最后由 zhaohj 于 2010-5-10 15:02 编辑 ]

    Snap2.jpg (104.57 KB, 下载次数: 328)

    Snap2.jpg

    Snap3.jpg (171.01 KB, 下载次数: 334)

    Snap3.jpg

    作者: hhh333    时间: 2010-5-10 15:07
    标题: 回复 #83 pseudo 的帖子
    确实与兄弟推测的一样,换了个41KB的压缩文件,故障消失!

    [ 本帖最后由 hhh333 于 2010-5-10 15:09 编辑 ]
    作者: zhaohj    时间: 2010-5-10 15:17
    发现一个问题,在NTFS上第一次读会读不出这个文件。可能这就是问题所在。我在真实机器上测试也是如此。
    这个问题在虚拟机上可以重现!

    而FAT上就不会出现这个问题。

    [ 本帖最后由 zhaohj 于 2010-5-10 15:38 编辑 ]

    Snap1.jpg (129.04 KB, 下载次数: 333)

    Snap1.jpg

    作者: zhaohj    时间: 2010-5-10 15:54
    进一步测试,find没问题,是不是gz有问题?

    Snap1.jpg (90.53 KB, 下载次数: 328)

    Snap1.jpg

    作者: zhaohj    时间: 2010-5-10 16:32
    再次测试,只要在FAT分区上读过文件,NTFS上就没问题了。

    Snap1.jpg (63.05 KB, 下载次数: 275)

    Snap1.jpg

    Snap2.jpg (80.44 KB, 下载次数: 287)

    Snap2.jpg

    Snap3.jpg (38.64 KB, 下载次数: 296)

    Snap3.jpg

    作者: chenall    时间: 2010-5-10 16:50
    文件太小?NTFS不支持这么小的文件。

    记得好像目前的NTFS代码访问小于4KB的文件经常会出问题的说。
    作者: zhaohj    时间: 2010-5-10 17:04
    是的,大于4KB没有问题。这是否也是BUG?
    作者: xianglang    时间: 2010-5-10 17:16
    我在上网本和笔记本上,使用我的那个压缩3KB的背景图,会花屏,但是如果不压缩的话,却很正常——我的分区也是NTFS格式的。由此看来,可能与GZIP压缩有关啊。G4D的版本,从今年开始的都是一样,之前的版本没试过。
    作者: zhaohj    时间: 2010-5-10 17:30
    不是压缩问题,是文件太小的原因。如果不压缩小于4KB也一样(不过不压缩至少背景图片肯定超过4KB)。
    作者: chenall    时间: 2010-5-10 17:33
    以前很早就会有这样的问题了吧,具体要问一下bean。

    记得NTFS分区上小于4KB的文件用GRUB4DOS访问偶尔是会出问题的。
    作者: sgw888    时间: 2010-5-10 17:37
    我在虚拟机测试的时候,CAT 是可以正常显示内容的. 第一次可以正常读出啊.
    之前测试的时候,总也读不出. 读多少次也是0. 虚拟机,DISKGEN3创建的NTFS. 然后,DOS下NTFS4DOS,拷贝的文件,从真实机拷到虚拟机.  这儿有几个问题,一,NTFS是DISKGEN创建的,第二,DOS下拷贝的,使用了NTFS4DOS,而且是从真实机又转到虚拟机的.  使用的是 8.3短文件名.

    后来,在PE下,格式化了一下NTFS的盘,从真实机重新拷贝了一下文件. 格式化之前,打开原来拷贝的文件也没发现什么问题,可以正常解压缩的.
    再试的时候,就正常了.
    作者: hhh333    时间: 2010-5-10 17:51
    原帖由 chenall 于 2010-5-10 17:33 发表
    以前很早就会有这样的问题了吧,具体要问一下bean。

    记得NTFS分区上小于4KB的文件用GRUB4DOS访问偶尔是会出问题的。


    就我测试的情况来看,应该较早或者是从一开始就有这个问题,可能要仔细看NTFS读写的代码才能找出来。应该算一个隐藏得较深的BUG吧。 

    [ 本帖最后由 hhh333 于 2010-5-10 17:52 编辑 ]
    作者: hhh333    时间: 2010-5-10 20:07
    在没找到错误所在时,我只能将图稍微做大一点了,不过这总是个安全隐患。
    作者: 不点    时间: 2010-5-10 21:35
    hhh333 因为做出了重大发现,而被授予国家重大诺贝尔科学发现金质奖章。

    chenall 你得把这个 bug 解决了。实在解决不了,再求助于 bean。

    这次难度系数,向上翻腾8周半,向下翻腾5周半,转体960度。

    ---------------

    根据大家的研究,初步感觉,问题与 gz 无关。那么可能是 ntfs 下小文件访问时容易出现的问题。

    因此就要注意, NTFS 支持模块代码中,究竟什么地方与此有关?读小文件的过程,与读大文件的过程有何区别?

    只要找到差别,就缩小了范围,再加上一些调试代码,也就比较容易找到问题的根源了。




    欢迎光临 无忧启动论坛 (http://wuyou.net./) Powered by Discuz! X3.3