Subversion Repositories SvarDOS

Rev

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

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