#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