Subversion Repositories SvarDOS

Rev

Rev 399 | Rev 533 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 399 Rev 421
-
 
1
/* This file is part of the SvarCOM project and is published under the terms
-
 
2
 * of the MIT license.
-
 
3
 *
-
 
4
 * Copyright (C) 2021 Mateusz Viste
-
 
5
 *
-
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
-
 
7
 * copy of this software and associated documentation files (the "Software"),
-
 
8
 * to deal in the Software without restriction, including without limitation
-
 
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-
 
10
 * and/or sell copies of the Software, and to permit persons to whom the
-
 
11
 * Software is furnished to do so, subject to the following conditions:
-
 
12
 *
-
 
13
 * The above copyright notice and this permission notice shall be included in
-
 
14
 * all copies or substantial portions of the Software.
-
 
15
 *
-
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-
 
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-
 
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-
 
22
 * DEALINGS IN THE SOFTWARE.
-
 
23
 */
-
 
24
 
1
/*
25
/*
2
 * vol [drive:]
26
 * vol [drive:]
3
 */
27
 */
4
 
28
 
5
static void cmd_vol_internal(unsigned char drv, char *buff) {
29
static void cmd_vol_internal(unsigned char drv, char *buff) {
6
  unsigned short *buff16 = (void *)(buff);
30
  unsigned short *buff16 = (void *)(buff);
7
  unsigned short err = 0;
31
  unsigned short err = 0;
8
  struct DTA *dta = (void *)0x80; /* use the default DTA at location 80h in PSP */
32
  struct DTA *dta = (void *)0x80; /* use the default DTA at location 80h in PSP */
9
 
33
 
10
  outputnl("");  /* start with an empty line to mimic MS-DOS */
34
  outputnl("");  /* start with an empty line to mimic MS-DOS */
11
 
35
 
12
  /* look for volume label in root dir via a FindFirst call */
36
  /* look for volume label in root dir via a FindFirst call */
13
  sprintf(buff, "%c:\\????????.???", drv + 'A');
37
  sprintf(buff, "%c:\\????????.???", drv + 'A');
14
  _asm {
38
  _asm {
15
    push ax
39
    push ax
16
    push cx
40
    push cx
17
    push dx
41
    push dx
18
    mov [err], 0    /* preset errflag to zero */
42
    mov [err], 0    /* preset errflag to zero */
19
    mov ah, 0x4e  /* FindFirst */
43
    mov ah, 0x4e  /* FindFirst */
20
    mov dx, buff
44
    mov dx, buff
21
    mov cx, 0x08  /* match volume labels only */
45
    mov cx, 0x08  /* match volume labels only */
22
    int 0x21      /* dta filled or CF set on error */
46
    int 0x21      /* dta filled or CF set on error */
23
    jnc DONE
47
    jnc DONE
24
    mov [err], ax
48
    mov [err], ax
25
    DONE:
49
    DONE:
26
    pop dx
50
    pop dx
27
    pop cx
51
    pop cx
28
    pop ax
52
    pop ax
29
  }
53
  }
30
 
54
 
31
  if (err != 0) {
55
  if (err != 0) {
32
    sprintf(buff, "Volume in drive %c has no label", drv + 'A');
56
    sprintf(buff, "Volume in drive %c has no label", drv + 'A');
33
  } else {
57
  } else {
34
    /* if label > 8 chars then drop the dot (DRIVE_LA.BEL -> DRIVE_LABEL) */
58
    /* if label > 8 chars then drop the dot (DRIVE_LA.BEL -> DRIVE_LABEL) */
35
    if (strlen(dta->fname) > 8) memmove(dta->fname + 8, dta->fname + 9, 4);
59
    if (strlen(dta->fname) > 8) memmove(dta->fname + 8, dta->fname + 9, 4);
36
    sprintf(buff, "Volume in drive %c is %s", drv + 'A', dta->fname);
60
    sprintf(buff, "Volume in drive %c is %s", drv + 'A', dta->fname);
37
  }
61
  }
38
  outputnl(buff);
62
  outputnl(buff);
39
 
63
 
40
  /* try to fetch the disk's serial number (DOS 4+ internal call) */
64
  /* try to fetch the disk's serial number (DOS 4+ internal call) */
41
  err = 0;
65
  err = 0;
42
  _asm {
66
  _asm {
43
    push ax
67
    push ax
44
    push bx
68
    push bx
45
    push dx
69
    push dx
46
    mov ax, 0x6900
70
    mov ax, 0x6900
47
    mov bl, drv  /* A=1, B=2, etc */
71
    mov bl, drv  /* A=1, B=2, etc */
48
    inc bl       /* adjust BL to +1 since drv is 0-based (A=0, B=1, etc) */
72
    inc bl       /* adjust BL to +1 since drv is 0-based (A=0, B=1, etc) */
49
    xor bh, bh   /* "info level", must be 0 */
73
    xor bh, bh   /* "info level", must be 0 */
50
    mov dx, buff /* pointer to a location where a DiskInfo struct will be written */
74
    mov dx, buff /* pointer to a location where a DiskInfo struct will be written */
51
    int 0x21
75
    int 0x21
52
    jnc DONE
76
    jnc DONE
53
    mov [err], ax  /* err code */
77
    mov [err], ax  /* err code */
54
    DONE:
78
    DONE:
55
    pop dx
79
    pop dx
56
    pop bx
80
    pop bx
57
    pop ax
81
    pop ax
58
  }
82
  }
59
  /* Format of DiskInfo struct (source: RBIL)
83
  /* Format of DiskInfo struct (source: RBIL)
60
   Offset  Size    Description (Table 01766)
84
   Offset  Size    Description (Table 01766)
61
   00h     WORD    0000h (info level)
85
   00h     WORD    0000h (info level)
62
   02h     DWORD   disk serial number (binary)
86
   02h     DWORD   disk serial number (binary)
63
   06h  11 BYTEs   volume label or "NO NAME    " if none present
87
   06h  11 BYTEs   volume label or "NO NAME    " if none present
64
   11h   8 BYTEs   filesystem type */
88
   11h   8 BYTEs   filesystem type */
65
  if ((err == 0) && (buff16[1] | buff16[2])) {
89
  if ((err == 0) && (buff16[1] | buff16[2])) {
66
    sprintf(buff + 64, "Volume Serial Number is %04X-%04X", buff16[2], buff16[1]);
90
    sprintf(buff + 64, "Volume Serial Number is %04X-%04X", buff16[2], buff16[1]);
67
    outputnl(buff + 64);
91
    outputnl(buff + 64);
68
  }
92
  }
69
}
93
}
70
 
94
 
71
 
95
 
72
static int cmd_vol(struct cmd_funcparam *p) {
96
static int cmd_vol(struct cmd_funcparam *p) {
73
  char drv = 0;
97
  char drv = 0;
74
  char curdrv = 0;
98
  char curdrv = 0;
75
  unsigned short i;
99
  unsigned short i;
76
 
100
 
77
  if (cmd_ishlp(p)) {
101
  if (cmd_ishlp(p)) {
78
    outputnl("Displays the disk volume label and serial number, if they exist.");
102
    outputnl("Displays the disk volume label and serial number, if they exist.");
79
    outputnl("");
103
    outputnl("");
80
    outputnl("VOL [drive:]");
104
    outputnl("VOL [drive:]");
81
    return(-1);
105
    return(-1);
82
  }
106
  }
83
 
107
 
84
  for (i = 0; i < p->argc; i++) {
108
  for (i = 0; i < p->argc; i++) {
85
    if (p->argv[i][0] == '/') {
109
    if (p->argv[i][0] == '/') {
86
      outputnl("Invalid switch");
110
      outputnl("Invalid switch");
87
      return(-1);
111
      return(-1);
88
    }
112
    }
89
    if (drv != 0) {
113
    if (drv != 0) {
90
      outputnl("Too many parameters");
114
      outputnl("Too many parameters");
91
      return(-1);
115
      return(-1);
92
    }
116
    }
93
    if ((p->argv[i][0] == 0) || (p->argv[i][1] != ':') || (p->argv[i][2] != 0)) {
117
    if ((p->argv[i][0] == 0) || (p->argv[i][1] != ':') || (p->argv[i][2] != 0)) {
94
      outputnl("Invalid parameter format");
118
      outputnl("Invalid parameter format");
95
      return(-1);
119
      return(-1);
96
    }
120
    }
97
    drv = p->argv[i][0];
121
    drv = p->argv[i][0];
98
    /* convert drive letter to a value 1..x (1=A, 2=B, etc) */
122
    /* convert drive letter to a value 1..x (1=A, 2=B, etc) */
99
    if ((drv >= 'a') && (drv <= 'z')) {
123
    if ((drv >= 'a') && (drv <= 'z')) {
100
      drv -= 'a';
124
      drv -= 'a';
101
    } else {
125
    } else {
102
      drv -= 'A';
126
      drv -= 'A';
103
    }
127
    }
104
  }
128
  }
105
 
129
 
106
  /* fetch current drive */
130
  /* fetch current drive */
107
  _asm {
131
  _asm {
108
    push ax
132
    push ax
109
    mov ah, 0x19  /* query default (current) disk */
133
    mov ah, 0x19  /* query default (current) disk */
110
    int 0x21      /* drive in AL (0=A, 1=B, etc) */
134
    int 0x21      /* drive in AL (0=A, 1=B, etc) */
111
    mov [curdrv], al
135
    mov [curdrv], al
112
    pop ax
136
    pop ax
113
  }
137
  }
114
 
138
 
115
  /* if no drive specified, use the default one */
139
  /* if no drive specified, use the default one */
116
  if (drv == 0) {
140
  if (drv == 0) {
117
    drv = curdrv;
141
    drv = curdrv;
118
  } else if (!isdrivevalid(drv)) { /* is specified drive valid? */
142
  } else if (!isdrivevalid(drv)) { /* is specified drive valid? */
119
    outputnl("Invalid drive");
143
    outputnl("Invalid drive");
120
    return(-1);
144
    return(-1);
121
  }
145
  }
122
 
146
 
123
  cmd_vol_internal(drv, p->BUFFER);
147
  cmd_vol_internal(drv, p->BUFFER);
124
 
148
 
125
  return(-1);
149
  return(-1);
126
}
150
}
127
 
151