返 回
本文发表在:成都教育学院学报1999年1期
在DOS中改变Win95长名文件后磁盘冗余空间的回收
成都教育学院 傅叔平
Recovering of Spilth Space in Disk after Changing the File with long name in DOS
Shuping Fu Chengdu College of Education
摘 要:在DOS环境下对具有Windows 95的长文件名的文件进行删除、改名、拷贝或移动等操作后,原来的长文件名的目录项占据的存储空间将成为永不可用的冗余空间,本文讨论了收回这些冗余空间的方法。
关键词:长文件名,目录项,冗余空间
一.问题的提出
Windows 95支持的长文件名突破了MS-DOS长久以来的“8.3”规则的限制,给用户带来了很大的方便,这是一个不小的进步。但由于MS-DOS不能处理Windows 95的长文件名,所以如果不慎在MS-DOS环境中删除、改名、拷贝或移动了具有Windows 95长文件名的文件,则会在磁盘上留下永远不可使用的冗余空间。这些空间是原来长文件名占用的地方。如何回收这些冗余空间,这是本文要讨论的问题。
二.长名文件与短名文件在存储结构上的异同
要讨论这个问题,首先要弄清的是Windows 95长名文件与MS-DOS“8.3”规则的短名文件在存储结构上异同。为了兼容,Windows 95与MS-DOS的磁盘文件的存储格式要尽可能地保持一致,因此,Windows 95没有改变MS-DOS原有的磁盘格式,它只是利用了MS-DOS的多个目录项来存储它的长文件名。下面分别简述之:
1.MS-DOS的目录项结构
每个目录项固定为32个字节:
00H~07H 文件名(首字节若为E5H则表示文件已删除)
08H~0AH 扩展名
0BH 属性
0CH~15H 保留
16H~17H 时间
18H~19H 日期
1AH~1BH 文件内容起始簇号
其中,0BH属性字节的有效值如下:
02H 隐含文件
04H 系统文件
08H 卷标
10H 子目录
20H 归档位,当文件已完成写操作并已正确关闭时,该位被置为1。
2.Windows 95的长名文件的目录项结构
我们知道,Windows 95的长文件名都有一个与之对应的、符合MS-DOS“8.3”规则的短文件名,这个短文件名有一个与MS-DOS文件完全一样的目录项,以供MS-DOS或DOS环境的程序访问对应的文件。
Windows 95的长文件名则是用额外的多个MS-DOS的目录项来存储的。那么又怎样才能使MS-DOS不会将这些存储长文件名的目录项误认为是一般文件的目录项呢?原来,当上述MS-DOS的目录项的00H字节不为E5H且属性字节(0BH)中的值为0FH时,MS-DOS会认为此目录项已被使用但不是正常的文件目录,因而不会访问该目录项。Windows 95正是利用了这一点,将存储长文件名的目录项中的属性字节(0BH)填为0FH,以此来 “骗过”MS-DOS。存储长文件名的目录项的结构如下:
00H 序号(表明是存储长文件名的第几个目录项,最后一个序号加上40H)
01H~0AH 文件名(每个字符占两个字节)
0BH 属性(恒为0FH)
0CH 类型
0DH 校验
0EH~1AH 文件名(续)
1BH 恒为0
1CH~1FH 文件名(续)
下面来作一个实验:将一张1.44MB的软磁盘格式化,先在MS-DOS6.22中存储一个短名文件,名为:ABC.TXT;再在Windows 95中存储一个长名文件,名为:ABCDEFGHIJKLMNOPQRSTUVWXYZ.TXT。用Debug程序将相关的目录项读出来:
-L 7000:0000 0 13 2(A盘13H~14H扇区读入内存——目录项是从相对13H扇区开始的)
-D 7000:0000 009F
7000:0000 41 42 43 20 20 20 20 20-54 58 54 20 00 00 00 00 ABC TXT ....
7000:0010 00 00 00 00 00 00 36 47-8E 24 02 00 1A 00 00 00 ......6G.$......
7000:0020 43 2E 00 54 00 58 00 54-00 00 00 0F 00 27 FF FF C..T.X.T.....'..
7000:0030 FF FF FF FF FF FF FF FF-FF FF 00 00 FF FF FF FF ................
7000:0040 02 4E 00 4F 00 50 00 51-00 52 00 0F 00 27 53 00 .N.O.P.Q.R...'S.
7000:0050 54 00 55 00 56 00 57 00-58 00 00 00 59 00 5A 00 T.U.V.W.X...Y.Z.
7000:0060 01 41 00 42 00 43 00 44-00 45 00 0F 00 27 46 00 .A.B.C.D.E...'F.
7000:0070 47 00 48 00 49 00 4A 00-4B 00 00 00 4C 00 4D 00 G.H.I.J.K...L.M.
7000:0080 41 42 43 44 45 46 7E 31-54 58 54 20 00 C2 47 50 ABCDEF~1TXT ..GP
7000:0090 8E 24 8E 24 00 00 47 50-8E 24 03 00 0B 00 00 00 .$.$..GP.$......
其中,第一个目录项(00H~31H)是短名文件ABC.TXT的目录项。第4~2个目录项是长文件名ABCDEFGHIJKLMNOPQRSTUVWXYZ.TXT占用的目录项,序号(每个目录项的首字节60H、40H和20H的值)分别为01H、02H和43H,这三个目录项的属性字节(相对位置0BH)的值均为0FH。第5个目录项(08H~9FH)是由长文件名ABCDEFGHIJKLMNOPQRSTUVWXYZ.TXT转换而来的与MS-DOS兼容的短文件名ABCDEF~1.TXT的目录项,它与文件ABC.TXT的目录项的结构完全相同。
三.在MS-DOS环境中改变长名文件的后果
在MS-DOS中改变(删除、、改名、拷贝或移动)文件时,系统只按DOS的算法搜索和处理目录项。例如,若删除上述的文件ABCDEF~1.TXT,则只有第5个目录项的首字节被写为E5H,表明该目录已释放;而长文件名占用的目录项未作任何改变。结果如下:
-L 7000:0000 0 13 2
-D 7000:0000 9F
7000:0000 41 42 43 20 20 20 20 20-54 58 54 20 00 00 00 00 ABC TXT ....
7000:0010 00 00 00 00 00 00 36 47-8E 24 02 00 1A 00 00 00 ......6G.$......
7000:0020 43 2E 00 54 00 58 00 54-00 00 00 0F 00 27 FF FF C..T.X.T.....'..
7000:0030 FF FF FF FF FF FF FF FF-FF FF 00 00 FF FF FF FF ................
7000:0040 02 4E 00 4F 00 50 00 51-00 52 00 0F 00 27 53 00 .N.O.P.Q.R...'S.
7000:0050 54 00 55 00 56 00 57 00-58 00 00 00 59 00 5A 00 T.U.V.W.X...Y.Z.
7000:0060 01 41 00 42 00 43 00 44-00 45 00 0F 00 27 46 00 .A.B.C.D.E...'F.
7000:0070 47 00 48 00 49 00 4A 00-4B 00 00 00 4C 00 4D 00 G.H.I.J.K...L.M.
7000:0080 E5 42 43 44 45 46 7E 31-54 58 54 20 00 C2 47 50 .BCDEF~1TXT ..GP
7000:0090 8E 24 8E 24 00 00 47 50-8E 24 03 00 0B 00 00 00 .$.$..GP.$......
这样一来,原来存储长文件的(属性字节为0FH的)目录项再也不能使用,成为磁盘上的冗余空间。往磁盘上再存一个文件XYZ.TXT后的目录项结果如下:
-L 7000:0000 0 13 2
-D 7000:0000 009F
7000:0000 41 42 43 20 20 20 20 20-54 58 54 20 00 00 00 00 ABC TXT ....
7000:0010 00 00 00 00 00 00 36 47-8E 24 02 00 1A 00 00 00 ......6G.$......
7000:0020 43 2E 00 54 00 58 00 54-00 00 00 0F 00 27 FF FF C..T.X.T.....'..
7000:0030 FF FF FF FF FF FF FF FF-FF FF 00 00 FF FF FF FF ................
7000:0040 02 4E 00 4F 00 50 00 51-00 52 00 0F 00 27 53 00 .N.O.P.Q.R...'S.
7000:0050 54 00 55 00 56 00 57 00-58 00 00 00 59 00 5A 00 T.U.V.W.X...Y.Z.
7000:0060 01 41 00 42 00 43 00 44-00 45 00 0F 00 27 46 00 .A.B.C.D.E...'F.
7000:0070 47 00 48 00 49 00 4A 00-4B 00 00 00 4C 00 4D 00 G.H.I.J.K...L.M.
7000:0080 58 59 5A 20 20 20 20 20-54 58 54 20 00 00 00 00 XYZ TXT ....
7000:0090 00 00 00 00 00 00 4E 53-8E 24 03 00 06 00 00 00 ......NS.$......
可以看到,XYZ.TXT用的是第5个目录项(80H~9FH),它不能使用已被删除的长文件名原来所占用的第2~4个目录项(20H~7FH)。
四.回收长文件名遗留的磁盘冗余空间的方法
综上所述,我们只要按MS-DOS的算法,将每个冗余的目录项的首字填上E5H,系统就知道该目录项已被释放,以后再有文件需要存储时,这些目录项所占用的空间就可重新使用了。在Debug中操作如下:
-L 7000:0000 0 13 2
-E 7000:0020 E5
-E 7000:0040 E5
-E 7000:0060 E5
下面是操作结果:
-D 7000:0000 009F
7000:0000 41 42 43 20 20 20 20 20-54 58 54 20 00 00 00 00 ABC TXT ....
7000:0010 00 00 00 00 00 00 36 47-8E 24 02 00 1A 00 00 00 ......6G.$......
7000:0020 E5 2E 00 54 00 58 00 54-00 00 00 0F 00 27 FF FF ...T.X.T.....'..
7000:0030 FF FF FF FF FF FF FF FF-FF FF 00 00 FF FF FF FF ................
7000:0040 E5 4E 00 4F 00 50 00 51-00 52 00 0F 00 27 53 00 .N.O.P.Q.R...'S.
7000:0050 54 00 55 00 56 00 57 00-58 00 00 00 59 00 5A 00 T.U.V.W.X...Y.Z.
7000:0060 E5 41 00 42 00 43 00 44-00 45 00 0F 00 27 46 00 .A.B.C.D.E...'F.
7000:0070 47 00 48 00 49 00 4A 00-4B 00 00 00 4C 00 4D 00 G.H.I.J.K...L.M.
7000:0080 58 59 5A 20 20 20 20 20-54 58 54 20 00 00 00 00 XYZ TXT ....
7000:0090 00 00 00 00 00 00 4E 53-8E 24 03 00 06 00 00 00 ......NS.$......
把目录项内容写回磁盘:
-W 7000:0000 0 13 2
-Q
现在,继续我们的实验。在MS-DOS环境中再往该磁盘上存储一个文件123.TXT后,读入目录项的内容:
-L 7000:0000 0 13 2
-D 7000:0000 009F
7000:0000 41 42 43 20 20 20 20 20-54 58 54 20 00 00 00 00 ABC TXT ....
7000:0010 00 00 00 00 00 00 36 47-8E 24 02 00 1A 00 00 00 ......6G.$......
7000:0020 31 32 33 20 20 20 20 20-54 58 54 20 00 9C 0D 83 123 TXT ....
7000:0030 94 24 94 24 00 00 0B 83-94 24 04 00 06 00 00 00 .$.$.....$......
7000:0040 E5 4E 00 4F 00 50 00 51-00 52 00 0F 00 27 53 00 .N.O.P.Q.R...'S.
7000:0050 54 00 55 00 56 00 57 00-58 00 00 00 59 00 5A 00 T.U.V.W.X...Y.Z.
7000:0060 E5 41 00 42 00 43 00 44-00 45 00 0F 00 27 46 00 .A.B.C.D.E...'F.
7000:0070 47 00 48 00 49 00 4A 00-4B 00 00 00 4C 00 4D 00 G.H.I.J.K...L.M.
7000:0080 58 59 5A 20 20 20 20 20-54 58 54 20 00 00 00 00 XYZ TXT ....
7000:0090 00 00 00 00 00 00 4E 53-8E 24 03 00 06 00 00 00 ......NS.$......
我们看到,原来长文件名用过的第二个目录项(20H~3FH字节)已为文件123.TXT所用。
如果磁盘以后只MS-DOS环境中使用,则长文件名已成多余。根据以上原理,可用下面的C程序回收所有长文件名占用的冗余空间(为省篇幅,这里假定磁盘为A盘,其根目录下未建子目录):
// Recover spilth disk space
#include
#include
#include
#define StartSector 0x13 // Started sector of dir-item
#define DirItemLength 14 // Number of dir-item
#define BufferSize 14*512
#define Drive 0 // Drive A
#define Attribution 0x0b
int main(void)
{
int i;
unsigned char buf[BufferSize];
if(absread(Drive, DirItemLength, StartSector, &buf)!=0)
{
perror("Read Disk Error !");
exit(1);
}
printf("\nRead OK !\n");
for(i=0;i<BufferSize;i+=0x20)
if(buf[i+Attribution]==0x0f)
buf[i]=0xe5;
if(abswrite(Drive, DirItemLength, StartSector, &buf)!=0)
{
perror("Write Disk Error !");
exit(1);
}
else
printf("Write OK !\n");
return(0);
}
注:本文所作实验的环境为:Intel MMX 166, 48MB 内存, PWindows 95, MS-DOS 6.22。C程序在Borland C++ 3.1中通过。
返 回