标题: DOS下如何编程来判断光驱已经装入?
[打印本页]
作者: wqqqing
时间: 2003-1-29 00:00
标题: DOS下如何编程来判断光驱已经装入?
如何在DOS下编写C或者汇编程序来判断光驱是否已经装入?
请高手指点,给个程序段落看看。
谢谢!!!
作者: Wengier
时间: 2003-1-29 00:00
好主意。
作者: qzxym
时间: 2003-1-30 00:00
简单极了,BASIC语言就能做到,原理就是判断Mscdex.exe是否已经运行即可。
作者: nre
时间: 2003-1-30 00:00
以下是引用qzxym在2003-1-30 22:40:16的发言:
简单极了,BASIC语言就能做到,原理就是判断Mscdex.exe是否已经运行即可。
说这种话有什么意义。 具体怎么实现?
作者: Wengier
时间: 2003-1-30 00:00
光判断MSCDEX是否加载了没用,而且还有其它的光驱扩展驱动程序,如SHSUCD等。
作者: Wengier
时间: 2003-1-31 00:00
刚才我对baobolz原来提到的那个FINDRAMD的源代码进行了一番改编,改编成为了FINDCD程序,可以查找光盘所在的盘符,并设置到环境变量CDROM中。它有两个明显的优点:
1:完全支持CLOAKING+MSCDEX,而网上的那个FINDCD.COM 1.02则不支持;
2:可以直接将光盘盘符设到变量CDROM中,操作非常方便,而不用判断任何ERRORLEVEL值。
我已将它传到论坛上来了,下载地址:
打开附件 链接已失效(管理员注 2009-4-28)
作者: mys
时间: 2003-2-6 00:00
非常好非常好,这样做启动盘就很方便了。
作者: Wengier
时间: 2003-2-6 00:00
我又对FINDCD做了一些增强,再次传上来:
打开附件 链接已失效(管理员注 2009-4-28)
注:它还修正了无光驱时会死机的BUG。
作者: nre
时间: 2003-2-7 00:00
标题: ~
同时上传原代码吧,有利于大家水平的提高。
作者: Wengier
时间: 2003-2-7 00:00
好吧,以下是此程序的部分源代码:
程序初始化部分(PASCAL源代码):
program findcd;
const
env: arrayof Char='CDROM=c:'; <- 准备环境变量
var
drvs: array of Char; <- 光驱字符列表
envp: PChar;
查找光驱子程序(汇编源代码):
procedure setdrv; assembler;
asm mov bx,0
mov ax,1500h
int 2fh <- 调用中断取得光驱状态
cmp bx,1 <- 检查光驱是否安装
jc @@m <- 若无,退出子程序
push bx
push ds
pop es
mov bx,offset drvs
mov ax,150Dh
int 2Fh
pop cx
@@l: add byte ptr ,'A'
inc bx
loop @@l
mov byte ptr ,0
@@m:
end;
添加环境变量子程序(汇编源代码,略);
主调用程序(PASCAL源代码):
begin
setdrv; <- 调用查找光驱子程序;
if ord(drvs)=0 then <- 若无光驱,显示“No CD-ROM found”;
WriteLn('No CD-ROM found.')
else begin
env:=drvs; <- 若存在光驱,将第一个光驱字母加入环境变量CDROM;
WriteLn(env); <- 在屏幕上显示“CDROM=x:”;
if not InsertEnvVar <- 调用添加环境变量子程序;
then WriteLn('Cannot set environment variable!'); <- 若无法加入环境变量,显示错误;
exit;
end;
end. <- 程序结束。
作者: pfox
时间: 2003-2-7 00:00
是否支持双光驱及三光驱?
作者: Wengier
时间: 2003-2-8 00:00
pfox:好主意,因此我刚才对FINDCD又进行了一番增强,在此下载:
打开附件 链接已失效(管理员注 2009-4-28)
此版本的特点是,“FINDCD n”(n是数字)将把CDROM环境变量设置为第n个光驱。若未指定n,则默认为第一个光驱(即n=1)。若n的值为0或非数字,则将CDROM值设置为光驱的数目。
假设现有E:、F:、G:盘三个光驱,那么运行“FINDCD”或“FINDCD 1”将得到“CDROM=E:”,运行“FINDCD 3”将得到“CDROM=G:”;若运行“FINDCD 0”将得到“CDROM=3”(即有三个光驱);若运行“FINDCD 4”将显示光驱找不到(因为只有三个光驱)。
作者: pfox
时间: 2003-2-8 00:00
Good!
Wengier,能否再增强一下,在不加参数运行FindCD后,
直接将第一个CDROM的盘符赋给CDROM环境变量,若存在
第二个、第三个CDROM盘符直接赋给CDROM1、CDROM2?
这样在启动盘里面就可以直接用cda.exe判断光驱里面是否
有盘及是否有存在的文件,若有就可以直接执行或调用。
作者: Wengier
时间: 2003-2-15 00:00
不如编写个批处理文件来做到,因为若运行FINDCD 0后%CDROM%的值为光驱数目,做个批处理循环并根据光驱数目将所有的光驱字符设置到%CDROM%变量中就可以了。
作者: Wengier
时间: 2003-2-15 00:00
我刚才编写了个简单的DOS批处理文件,可以通过上面的FINDCD程序方便地将CDROM1,CDROM2等依次设置为光驱盘符.程序如下:
@echo off
set n=0
:loop
set cdrom=
findcd %n% (即: 调用上面的FINDCD)
if %n%==0 set cdn=%cdrom%
if not %n%==0 set cdrom%n%=%cdrom%
if %n%#==%cdn%# goto end
count n (即: n=n+1)
goto loop
:end
set n=
set cdn=
set cdrom=
echo.
作者: pfox
时间: 2003-2-17 00:00
虽然麻烦了点,但是也是一个很不错的处理方法(我原来就是不想再用批处理进行转换)。
:)
作者: lydong
时间: 2003-2-20 00:00
能不能对 FINDCD 再做加强,以实现上述功能呢?这样可以省去一些麻烦.
作者: lydong
时间: 2003-2-20 00:00
运行FINDCD之后,用SET命令会出现几行乱码。是不是程序的问题?
作者: Wengier
时间: 2003-2-20 00:00
什么乱码?
作者: lydong
时间: 2003-2-21 00:00
运行FINDCN之前执行SET命令
-------------------------------------------------------------------------
E:\>set
TMP=C:\WINDOWS\TEMP
TEMP=C:\WINDOWS\TEMP
PROMPT=$p$g
winbootdir=C:\WINDOWS
PATH=C:\WINDOWS;C:\WINDOWS\COMMAND
COMSPEC=C:\WINDOWS\COMMAND.COM
windir=C:\WINDOWS
BLASTER=A220 I5 D1 T4
E:\>
---------------------------------------------------------------------------------------
运行FINDCN之后:
---------------------------------------------------------------------------------------
E:\恒昌电脑刻录光盘\dos2\FINDCD>findcd
CDROM=F:
E:\恒昌电脑刻录光盘\dos2\FINDCD>set
TMP=C:\WINDOWS\TEMP
TEMP=C:\WINDOWS\TEMP
PROMPT=$p$g
winbootdir=C:\WINDOWS
PATH=C:\WINDOWS;C:\WINDOWS\COMMAND
COMSPEC=C:\WINDOWS\COMMAND.COM
windir=C:\WINDOWS
BLASTER=A220 I5 D1 T4
CMDLINE=findcd
CDROM=F:
%u蟍??C
梃?3缷琚!??
9PSRW??
??緕媽D6墊4荄@
苿?
$荄D
E:\恒昌电脑刻录光盘\dos2\FINDCD>
---------------------------------------------------------------------------------------
作者: Wengier
时间: 2003-2-21 00:00
好吧,既然如此,我再次做了增强,增加了以下选项(注:一次最多只能输入一个选项):
/N:只在屏幕上显示,而不设置环境变量;
/Q:不在屏幕上显示,而只设置环境变量;
/?:帮助;
/S:全部设置模式(即pfox和lydong想要的效果)。例如,现有F与G盘两个光驱,运行FINDCD /S后的结果是:
CDROM=2
CDROM1=F:
CDROM2=G:
注:若运行正常的话,则ERRORLEVEL值为0,否则为1(无光驱)或2(无法设置环境变量)。
下载地址:
打开附件 链接已失效(管理员注 2009-4-28)
lydong:我倒从没有发现有乱码现象,无论是在纯DOS下还是在DOS窗口下都没有。
作者: lydong
时间: 2003-2-21 00:00
谢谢Wengier,你的FINDCD现在很好用了,而且没有乱码了。
作者: pfox
时间: 2003-2-22 00:00
呵呵,Wengier,在目前的findcd已经非常完善,但我还想再提一个,就是你既然用CDROM来存储Cdrom的个数,那么为什么不在无光驱的情况下直接把CDROM置为0?这样就可以不使用ERRORLEVEL来判断是否有光驱存在,而可以直接判断CDROM是否等于0来检测是否有光驱?不好意思!
作者: Wengier
时间: 2003-2-22 00:00
其实是这样的,如果光驱不存在,那么FINDCD在将ERRORLEVEL的值设为1的同时,将不会设置CDROM变量,因此,要判断是否有光驱其实很简单,即只需运行FINDCD后检查CDROM变量是否存在即可,例如:
FINDCD
IF %CDROM%#==# ECHO No CDROM!
或者,使用FINDCD 0的格式,若光驱不存在,CDROM变量的值将为0。
不过,如果您是指在无光驱的情况下运行FINDCD /S后CDROM变量的值应为0,那倒是个好主意。请问您是不是这个意思?
作者: pfox
时间: 2003-2-24 00:00
就是这个意思。:)
作者: Wengier
时间: 2003-2-24 00:00
作者: lydong
时间: 2003-4-7 00:00
Wengier :
我装了双光驱,我想在AUTOEXEC.BAT执行时显示第一个光驱盘符,但执行了FINDCD后显示的CDROM1却为最后一个光驱盘符.显示如下:
I:\>findcd /s
CDROM=2
CDROM1=L:
CDROM2=K:
I:\>
如果是在光驱数量不定的情况下判断第一个光驱盘符就有点困难了,除非是判断最后的光驱盘符.
但我觉得还是按顺序好一点,所以希望您能再改一下您的程序.
作者: Wengier
时间: 2003-4-7 00:00
如果是同一个光驱设备名(例如MSCD001)的话,顺序确实会反过来了,我去看看.不过如果是多个光驱设备名的话,则是按顺序来的.
作者: lydong
时间: 2003-4-7 00:00
能改过来吗?
作者: Wengier
时间: 2003-4-8 00:00
我重新去看了一下FINDCD源程序,可惜一是那些汇编代码改起来非常复杂(且INT2F中断的150D号功能返回的光驱盘符列表似乎本身就不完全是正顺序),二是我现在没有同一设备名的双光驱去测试(因为对于不同设备名的双光驱则是按顺序来的),没办法了~~
作者: lydong
时间: 2003-4-8 00:00
我装了虚拟光驱也一样,你可以装一个或两个虚拟光驱来测试.如果真的没办法,那也只能这样了.
作者: Wengier
时间: 2003-4-8 00:00
我看从中断那儿得到的那种顺序是改不了的,不过可以编一个附加的子程序,在输出前自动对盘符字母进行排序.
作者: lydong
时间: 2003-4-8 00:00
好吧
作者: Wengier
时间: 2003-4-9 00:00
OK,我刚才对FINDCD增加了字母表自动排序功能,下载地址:
打开附件 链接已失效(管理员注 2009-4-28)
作者: Wengier
时间: 2003-4-10 00:00
lydong觉得这个最新的FINDCD好用吗?还需要增加什么功能吗?
作者: Dark-Destroy
时间: 2003-4-11 00:00
Wengier版主,可以把FINDCD改用C寫嗎??因為PASCAL我只有學一點而已,不是很熟...謝謝版主
作者: Wengier
时间: 2003-4-11 00:00
改用C语言?那等于是重写一遍了.而且FINDCD是汇编+PASCAL程序的直接组合体,而汇编+C怎么直接组合我不太清楚.
作者: lydong
时间: 2003-4-12 00:00
哈,我很高兴,这个FINDCD编得很好,是用来查找光驱的,也不用太多其它功能了.谢谢!
作者: boyachang
时间: 2003-4-22 00:00
不知道能否给完整源代码,我想知道“添加环境变量子程序”这部分?
作者: Wengier
时间: 2003-4-23 00:00
“添加环境变量子程序”这部分汇编子程序不是我写的,内容如下:
function InsertEnvVar:Boolean; assembler;
asm mov es,
mov es,es:
mov ax,es:
dec ax
mov es,ax
mov dx,es:
shl dx,4
inc ax
mov es,ax
cld
xor di,di
xor ax,ax
mov cx,dx
@@l1: repne scasb
mov bx,di
dec cx
scasb
jnz @@l1
cmp word ptr es:,1
jnz @@no_ext
scasw
sub cx,2
repne scasb
jnz @@err
@@no_ext:
cmp cx,10
jl @@err
push ds
push es
pop ds
mov si,di
add di,10
mov cx,si
sub cx,bx
std
dec si
dec di
rep movsb
cld
pop ds
mov si,offset env
mov di,bx
mov cx,10
rep movsb
mov al,1
jmp @@e
@@err:
mov al,0
@@e:
end;
作者: boyachang
时间: 2003-4-23 00:00
谢谢
作者: boyachang
时间: 2003-4-25 00:00
PrefixSeg是不是等于42h啊,PSP?
我怎么没有试成功呢?不想再试了。
版主可否帮忙将它封装成一个汇编函数?
一个输入参数为设置字符串指针。
作者: Wengier
时间: 2003-4-26 00:00
那个function是拿来用的,具体我也不太清楚。
作者: boyachang
时间: 2003-4-27 00:00
终于改成功了,不过只是能用而已,不知道有没有什么潜在问题?
作者: lemonhall
时间: 2003-9-20 00:00
本帖被加入精华区
作者: 问题
时间: 2003-9-23 00:00
版主您好!
对您的编程技术我很佩服!
能把您这个汇编程序改成TC写法吗!
我先在这谢谢呢!
----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------
添加环境变量子程序”
function InsertEnvVar:Boolean; assembler;
asm mov es,
mov es,es:
mov ax,es:
dec ax
mov es,ax
mov dx,es:
shl dx,4
inc ax
mov es,ax
cld
xor di,di
xor ax,ax
mov cx,dx
@@l1: repne scasb
mov bx,di
dec cx
scasb
jnz @@l1
cmp word ptr es:,1
jnz @@no_ext
scasw
sub cx,2
repne scasb
jnz @@err
@@no_ext:
cmp cx,10
jl @@err
push ds
push es
pop ds
mov si,di
add di,10
mov cx,si
sub cx,bx
std
dec si
dec di
rep movsb
cld
pop ds
mov si,offset env
mov di,bx
mov cx,10
rep movsb
mov al,1
jmp @@e
@@err:
mov al,0
@@e:
end;
----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------