1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
#ifndef DOSINT_H
#define DOSINT_H
// Internal DOS structures
// For documentation of these, better grab "Undocumented DOS" or similar book
// These are probably valid only on DOS >= 4
typedef _Packed struct dos_current_directory_structure {
char curr_path[67];
uint16_t flags;
uint32_t disk_blk;
void __far * info;
char pad1[11];
} DOSCDS;
STATIC_ASSERT(sizeof(DOSCDS) == 88);
enum dos_cds_flags {
DOS_CDS_FLAG_PHYSICAL = 0x4000,
DOS_CDS_FLAG_NETWORK = 0x8000
};
typedef _Packed struct dos_system_file_table_entry {
uint16_t num_handles;
uint16_t open_mode;
uint8_t attr;
uint16_t dev_info;
void __far *dpb;
uint16_t start_cluster;
uint16_t f_time;
uint16_t f_date;
uint32_t f_size;
uint32_t f_pos;
uint16_t last_rel_cluster;
uint16_t last_abs_cluster;
uint16_t dir_sector;
uint8_t dir_entry;
char filename[11];
} DOSSFT;
STATIC_ASSERT(sizeof(DOSSFT) == 43);
enum dos_sft_dev_flags {
DOS_SFT_FLAG_NETWORK = 0x8000,
DOS_SFT_FLAG_TIME_SET = 0x4000,
DOS_SFT_FLAG_CLEAN = 0x0040,
DOS_SFT_DRIVE_MASK = 0x001F
};
typedef _Packed struct dos_search_data_block {
uint8_t drive;
char search_templ[11];
uint8_t search_attr;
uint16_t dir_entry;
uint16_t par_clstr;
char pad1[4];
} DOSSDB;
STATIC_ASSERT(sizeof(DOSSDB) == 21);
enum dos_sdb_drive_flags {
DOS_SDB_DRIVE_FLAG_NETWORK = 0x80,
DOS_SDB_DRIVE_MASK = 0x1F
};
typedef _Packed struct dos_lock_params {
uint32_t start_offset;
uint32_t region_size;
} DOSLOCK;
typedef _Packed struct dos_direntry {
char filename[11];
uint8_t attr;
char pad1[10];
uint16_t f_time;
uint16_t f_date;
uint16_t start_cluster;
uint32_t f_size;
} DOSDIR;
STATIC_ASSERT(sizeof(DOSDIR) == 32);
typedef _Packed struct dos_swappable_area {
uint8_t criterr;
uint8_t indos;
uint8_t drive_num;
uint8_t lasterr_dum[9];
uint8_t __far *cur_dta;
uint16_t cur_psp;
uint8_t pad1[4];
uint8_t cur_drive;
uint8_t pad2[135];
char fn1[128];
char fn2[128];
DOSSDB sdb;
DOSDIR found_file;
DOSCDS drive_cdscopy;
uint8_t fcb_fn1[11];
uint8_t pad3[1];
uint8_t fcb_fn2[11];
uint8_t pad4[11];
uint8_t search_attr;
uint8_t open_mode;
uint8_t pad5[51];
DOSCDS __far *drive_cds;
uint8_t pad6[12];
uint16_t fn1_csoffset;
uint16_t fn2_csoffset;
uint8_t pad7[71];
uint16_t openex_act;
uint16_t openex_attr;
uint16_t openex_mode;
uint8_t pad8[29];
DOSSDB rename_srcfile;
DOSDIR rename_file;
} DOSSDA;
STATIC_ASSERT(offsetof(DOSSDA, cur_dta) == 0xC);
STATIC_ASSERT(offsetof(DOSSDA, cur_drive) == 0x16);
STATIC_ASSERT(offsetof(DOSSDA, fn1) == 0x9E);
STATIC_ASSERT(offsetof(DOSSDA, fn2) == 0x11E);
STATIC_ASSERT(offsetof(DOSSDA, sdb) == 0x19E);
STATIC_ASSERT(offsetof(DOSSDA, found_file) == 0x1B3);
STATIC_ASSERT(offsetof(DOSSDA, search_attr) == 0x24D);
STATIC_ASSERT(offsetof(DOSSDA, open_mode) == 0x24E);
STATIC_ASSERT(offsetof(DOSSDA, drive_cds) == 0x282);
STATIC_ASSERT(offsetof(DOSSDA, openex_act) == 0x2DD);
STATIC_ASSERT(offsetof(DOSSDA, openex_mode) == 0x2E1);
typedef _Packed struct dos_list_of_lists {
char pad1[22];
DOSCDS __far *cds;
char pad2[7];
uint8_t last_drive;
} DOSLOL;
typedef _Packed struct dos_nls_table {
uint8_t table_id;
void __far *table_data;
} NLSTABLE;
typedef _Packed struct file_char_table {
uint16_t size; // table size (not counting this word)
uint8_t unk1; // ??? (01h for MS-DOS 3.30-6.00)
uint8_t lowest; // lowest permissible character value for filename
uint8_t highest; // highest permissible character value for filename
uint8_t unk2; // ??? (00h for MS-DOS 3.30-6.00)
uint8_t first_x; // first excluded character in range \ all characters in this
uint8_t last_x; // last excluded character in range / range are illegal
uint8_t unk3; // ??? (02h for MS-DOS 3.30-6.00)
uint8_t n_illegal; // number of illegal (terminator) characters
uint8_t illegal[1]; // characters which terminate a filename: ."/\[]:|<>+=;,
} FCHAR;
static inline int drive_letter_to_index(char letter)
{
if (letter >= 'A' && letter <= 'Z') return letter - 'A';
else if (letter >= 'a' && letter <= 'z') return letter - 'a';
else return -1;
}
static inline char drive_index_to_letter(int index)
{
return 'A' + index;
}
static inline DOSSDA __far * dos_get_swappable_dos_area(void);
#pragma aux dos_get_swappable_dos_area = \
"push ds" \
"mov ax, 0x5D06" \
"int 0x21" \
"jnc success" \
"xor si, si" \
"mov es, si" \
"jmp end" \
"success: mov ax, ds" \
"mov es, ax" \
"end: pop ds" \
__value [es si] \
__modify [ax cx dx]
static inline DOSLOL __far * dos_get_list_of_lists(void);
#pragma aux dos_get_list_of_lists = \
"mov ax, 0x5200" \
"int 0x21" \
__value [es bx] \
__modify [ax]
static inline uint16_t dos_sft_decref(DOSSFT __far *sft);
#pragma aux dos_sft_decref = \
"mov ax, 0x1208" \
"int 0x2F" \
__parm [es di] \
__value [ax]
// Network redirector interface
enum DOS_REDIR_SUBFUNCTION {
DOS_FN_RMDIR = 0x01,
DOS_FN_MKDIR = 0x03,
DOS_FN_CHDIR = 0x05,
DOS_FN_CLOSE = 0x06,
DOS_FN_COMMIT = 0x07,
DOS_FN_READ = 0x08,
DOS_FN_WRITE = 0x09,
DOS_FN_LOCK = 0x0A,
DOS_FN_UNLOCK = 0x0B,
DOS_FN_GET_DISK_FREE = 0x0C,
DOS_FN_SET_FILE_ATTR = 0x0E,
DOS_FN_GET_FILE_ATTR = 0x0F,
DOS_FN_RENAME = 0x11,
DOS_FN_DELETE = 0x13,
DOS_FN_OPEN = 0x16,
DOS_FN_CREATE = 0x17,
DOS_FN_FIND_FIRST = 0x1B,
DOS_FN_FIND_NEXT = 0x1C,
DOS_FN_CLOSE_ALL = 0x1D,
DOS_FN_DO_REDIR = 0x1E,
DOS_FN_PRINTSETUP = 0x1F,
DOS_FN_FLUSH = 0x20,
DOS_FN_SEEK_END = 0x21,
DOS_FN_ATEXIT = 0x22,
DOS_FN_QUALIFY = 0x23,
DOS_FN_OPEN_EX = 0x2E
};
enum OPENEX_ACTIONS {
OPENEX_FAIL_IF_EXISTS = 0x00,
OPENEX_OPEN_IF_EXISTS = 0x01,
OPENEX_REPLACE_IF_EXISTS = 0x02,
OPENEX_FAIL_IF_NEW = 0x00,
OPENEX_CREATE_IF_NEW = 0x10,
};
enum OPENEX_MODE {
OPENEX_MODE_READ = 0,
OPENEX_MODE_WRITE = 1,
OPENEX_MODE_RDWR = 2,
OPENEX_MODE_MASK = 3,
OPENEX_SHARE_COMPAT = 0x00,
OPENEX_SHARE_DENYALL = 0x10,
OPENEX_SHARE_DENYWRITE = 0x20,
OPENEX_SHARE_DENYREAD = 0x30,
OPENEX_SHARE_DENYNONE = 0x40,
OPENEX_SHARE_MASK = 0x70,
};
enum OPENEX_RESULT {
OPENEX_FILE_OPENED = 1,
OPENEX_FILE_CREATED = 2,
OPENEX_FILE_REPLACED = 3,
};
#endif // DOSINT_H
|