| version 1.1, 2004/01/09 04:36:02 | version 1.10, 2004/01/22 04:59:48 | 
| Line 1 | Line 1 | 
 |  | #include        "compiler.h" | 
 |  |  | 
 |  | #if defined(SUPPORT_HOSTDRV) | 
 |  |  | 
 | /* | /* | 
 | ゲストOS(DOS)からホストOS(Win)にアクセスするの〜 | ゲストOS(DOS)からホストOS(Win)にアクセスするの〜 | 
| Line 6 | Line 9 | 
 | 更に、手抜き版だし(マテ | 更に、手抜き版だし(マテ | 
 | */ | */ | 
 |  |  | 
 | #include        "compiler.h" |  | 
 | #include        "dosio.h" | #include        "dosio.h" | 
 | #include        "cpucore.h" | #include        "cpucore.h" | 
 | #include        "pccore.h" | #include        "pccore.h" | 
 |  | #include        "iocore.h" | 
 | #include        "hostdrv.h" | #include        "hostdrv.h" | 
 | #include        "hostdrvs.h" | #include        "hostdrvs.h" | 
 | #include        "hostdrv.tbl" | #include        "hostdrv.tbl" | 
 |  |  | 
 |  |  | 
| #if 1 | #define IS_PERMITWRITE          (np2cfg.hdrvacc & HDFMODE_WRITE) | 
| #define IS_PERMITWRITE          0 | #define IS_PERMITDELETE         (np2cfg.hdrvacc & HDFMODE_DELETE) | 
| #else |  | 
| #define IS_PERMITWRITE          np2oscfg.hostdrv_permitwrite |  | 
| #endif |  | 
|  |  | 
| #define ROOTPATH                        "\\\\HOSTDRV\\" |  | 
| #define ROOTPATH_SIZE           (sizeof(ROOTPATH) - 1) |  | 
 |  |  | 
| static const HDRVDIR hdd_volume = {"_HOSTDRIVE_", 0, 0x08}; | #define ROOTPATH_NAME           "\\\\HOSTDRV\\" | 
| static const HDRVDIR hdd_owner  = {".          ", 0, 0x10}; | #define ROOTPATH_SIZE           (sizeof(ROOTPATH_NAME) - 1) | 
| static const HDRVDIR hdd_parent = {"..         ", 0, 0x10}; |  | 
 |  |  | 
 |  | static const char ROOTPATH[ROOTPATH_SIZE + 1] = ROOTPATH_NAME; | 
 |  | static const HDRVDIR hdd_volume = {"_HOSTDRIVE_", 0, 0, 0, 0x08, {0}, {0}}; | 
 |  | static const HDRVDIR hdd_owner  = {".          ", 0, 0, 0, 0x10, {0}, {0}}; | 
 |  | static const HDRVDIR hdd_parent = {"..         ", 0, 0, 0, 0x10, {0}, {0}}; | 
 |  |  | 
 | //      see int2159-BX0000 | //      see int2159-BX0000 | 
 | enum { | enum { | 
| Line 69  static void fetch_if4dos(void) { | Line 69  static void fetch_if4dos(void) { | 
 | off = i286_memoryread_w(IF4DOSPTR_ADDR); | off = i286_memoryread_w(IF4DOSPTR_ADDR); | 
 | seg = i286_memoryread_w(IF4DOSPTR_ADDR + 2); | seg = i286_memoryread_w(IF4DOSPTR_ADDR + 2); | 
 | i286_memstr_read(seg, off, &if4dos, sizeof(if4dos)); | i286_memstr_read(seg, off, &if4dos, sizeof(if4dos)); | 
| hostdrv.drive_no = if4dos.drive_no; | hostdrv.stat.drive_no = if4dos.drive_no; | 
| hostdrv.dosver_major = if4dos.dosver_major; | hostdrv.stat.dosver_major = if4dos.dosver_major; | 
| hostdrv.dosver_minor = if4dos.dosver_minor; | hostdrv.stat.dosver_minor = if4dos.dosver_minor; | 
| hostdrv.sda_off = LOADINTELWORD(if4dos.sda_off); | hostdrv.stat.sda_off = LOADINTELWORD(if4dos.sda_off); | 
| hostdrv.sda_seg = LOADINTELWORD(if4dos.sda_seg); | hostdrv.stat.sda_seg = LOADINTELWORD(if4dos.sda_seg); | 
|  |  | 
| TRACEOUT(("hostdrv.drive_no = %d", if4dos.drive_no)); | TRACEOUT(("hostdrv:drive_no = %d", if4dos.drive_no)); | 
| TRACEOUT(("hostdrv.dosver = %d.%.2d", if4dos.dosver_major, if4dos.dosver_minor)); | TRACEOUT(("hostdrv:dosver = %d.%.2d", if4dos.dosver_major, if4dos.dosver_minor)); | 
| TRACEOUT(("hostdrv.sda = %.4x:%.4x", hostdrv.sda_seg, hostdrv.sda_off)); | TRACEOUT(("hostdrv.sda = %.4x:%.4x", hostdrv.stat.sda_seg, hostdrv.stat.sda_off)); | 
 | } | } | 
 |  |  | 
 |  |  | 
| Line 97  static void fetch_sda_currcds(SDACDS sc) | Line 97  static void fetch_sda_currcds(SDACDS sc) | 
 | REG16   off; | REG16   off; | 
 | REG16   seg; | REG16   seg; | 
 |  |  | 
| if (hostdrv.dosver_major == 3) { | if (hostdrv.stat.dosver_major == 3) { | 
| i286_memstr_read(hostdrv.sda_seg, hostdrv.sda_off, | i286_memstr_read(hostdrv.stat.sda_seg, hostdrv.stat.sda_off, | 
 | &sc->ver3.sda, sizeof(sc->ver3.sda)); | &sc->ver3.sda, sizeof(sc->ver3.sda)); | 
 | off = LOADINTELWORD(sc->ver3.sda.cdsptr.off); | off = LOADINTELWORD(sc->ver3.sda.cdsptr.off); | 
 | seg = LOADINTELWORD(sc->ver3.sda.cdsptr.seg); | seg = LOADINTELWORD(sc->ver3.sda.cdsptr.seg); | 
 | i286_memstr_read(seg, off, &sc->ver3.cds, sizeof(sc->ver3.cds)); | i286_memstr_read(seg, off, &sc->ver3.cds, sizeof(sc->ver3.cds)); | 
 | } | } | 
 | else { | else { | 
| i286_memstr_read(hostdrv.sda_seg, hostdrv.sda_off, | i286_memstr_read(hostdrv.stat.sda_seg, hostdrv.stat.sda_off, | 
 | &sc->ver4.sda, sizeof(sc->ver4.sda)); | &sc->ver4.sda, sizeof(sc->ver4.sda)); | 
 | off = LOADINTELWORD(sc->ver4.sda.cdsptr.off); | off = LOADINTELWORD(sc->ver4.sda.cdsptr.off); | 
 | seg = LOADINTELWORD(sc->ver4.sda.cdsptr.seg); | seg = LOADINTELWORD(sc->ver4.sda.cdsptr.seg); | 
| Line 118  static void store_sda_currcds(SDACDS sc) | Line 118  static void store_sda_currcds(SDACDS sc) | 
 | REG16   off; | REG16   off; | 
 | REG16   seg; | REG16   seg; | 
 |  |  | 
| if (hostdrv.dosver_major == 3) { | if (hostdrv.stat.dosver_major == 3) { | 
| i286_memstr_write(hostdrv.sda_seg, hostdrv.sda_off, | i286_memstr_write(hostdrv.stat.sda_seg, hostdrv.stat.sda_off, | 
 | &sc->ver3.sda, sizeof(sc->ver3.sda)); | &sc->ver3.sda, sizeof(sc->ver3.sda)); | 
 | off = LOADINTELWORD(sc->ver3.sda.cdsptr.off); | off = LOADINTELWORD(sc->ver3.sda.cdsptr.off); | 
 | seg = LOADINTELWORD(sc->ver3.sda.cdsptr.seg); | seg = LOADINTELWORD(sc->ver3.sda.cdsptr.seg); | 
 | i286_memstr_write(seg, off, &sc->ver3.cds, sizeof(sc->ver3.cds)); | i286_memstr_write(seg, off, &sc->ver3.cds, sizeof(sc->ver3.cds)); | 
 | } | } | 
 | else { | else { | 
| i286_memstr_write(hostdrv.sda_seg, hostdrv.sda_off, | i286_memstr_write(hostdrv.stat.sda_seg, hostdrv.stat.sda_off, | 
 | &sc->ver4.sda, sizeof(sc->ver4.sda)); | &sc->ver4.sda, sizeof(sc->ver4.sda)); | 
 | off = LOADINTELWORD(sc->ver4.sda.cdsptr.off); | off = LOADINTELWORD(sc->ver4.sda.cdsptr.off); | 
 | seg = LOADINTELWORD(sc->ver4.sda.cdsptr.seg); | seg = LOADINTELWORD(sc->ver4.sda.cdsptr.seg); | 
| Line 162  static void store_srch(INTRST is) { | Line 162  static void store_srch(INTRST is) { | 
 |  |  | 
 | // SDA内のSRCHRECにセット | // SDA内のSRCHRECにセット | 
 | srchrec = is->srchrec_ptr; | srchrec = is->srchrec_ptr; | 
| srchrec->drive_no = 0xc0 | hostdrv.drive_no; | srchrec->drive_no = 0xc0 | hostdrv.stat.drive_no; | 
 | CopyMemory(srchrec->srch_mask, is->fcbname_ptr, 11); | CopyMemory(srchrec->srch_mask, is->fcbname_ptr, 11); | 
 | srchrec->attr_mask = *is->srch_attr_ptr; | srchrec->attr_mask = *is->srch_attr_ptr; | 
 | STOREINTELWORD(srchrec->dir_entry_no, ((UINT16)-1)); | STOREINTELWORD(srchrec->dir_entry_no, ((UINT16)-1)); | 
| Line 173  static void store_dir(INTRST is, const H | Line 173  static void store_dir(INTRST is, const H | 
 |  |  | 
 | DIRREC  dirrec; | DIRREC  dirrec; | 
 | UINT8   attr; | UINT8   attr; | 
 |  | UINT16  reg; | 
 |  |  | 
 | // SDA内のDIRRECにセット | // SDA内のDIRRECにセット | 
 | dirrec = is->dirrec_ptr; | dirrec = is->dirrec_ptr; | 
| Line 182  static void store_dir(INTRST is, const H | Line 183  static void store_dir(INTRST is, const H | 
 | attr |= 0x01; | attr |= 0x01; | 
 | } | } | 
 | dirrec->file_attr = attr; | dirrec->file_attr = attr; | 
| STOREINTELDWORD(dirrec->file_time, 0);          // di->datetime | reg = 0; | 
| STOREINTELDWORD(dirrec->start_sector, ((UINT32)-1)); | if (di->caps & FLICAPS_TIME) { | 
|  | reg |= (di->time.hour & 0x1f) << 11; | 
|  | reg |= (di->time.minute & 0x3f) << 5; | 
|  | reg |= (di->time.second & 0x3e) >> 1; | 
|  | } | 
|  | STOREINTELWORD(dirrec->file_time, reg); | 
|  | reg = 0; | 
|  | if (di->caps & FLICAPS_DATE) { | 
|  | reg |= ((di->date.year - 1980) & 0x7f) << 9; | 
|  | reg |= (di->date.month & 0x0f) << 5; | 
|  | reg |= di->date.day & 0x1f; | 
|  | } | 
|  | STOREINTELWORD(dirrec->file_date, reg); | 
|  | STOREINTELWORD(dirrec->start_sector, ((UINT16)-1)); | 
 | STOREINTELDWORD(dirrec->file_size, di->size); | STOREINTELDWORD(dirrec->file_size, di->size); | 
 | } | } | 
 |  |  | 
 | static void fill_sft(INTRST is, SFTREC sft, UINT num, HDRVDIR *di) { | static void fill_sft(INTRST is, SFTREC sft, UINT num, HDRVDIR *di) { | 
 |  |  | 
 | UINT8   attr; | UINT8   attr; | 
 |  | UINT16  reg; | 
 |  |  | 
 | attr = di->attr; | attr = di->attr; | 
 | if (!IS_PERMITWRITE) { | if (!IS_PERMITWRITE) { | 
| Line 197  static void fill_sft(INTRST is, SFTREC s | Line 212  static void fill_sft(INTRST is, SFTREC s | 
 | } | } | 
 | sft->file_attr = attr; | sft->file_attr = attr; | 
 | STOREINTELWORD(sft->start_sector, (UINT16)num); | STOREINTELWORD(sft->start_sector, (UINT16)num); | 
| STOREINTELDWORD(sft->file_time, 0);                                     // di->datetime |  | 
|  | reg = 0; | 
|  | if (di->caps & FLICAPS_TIME) { | 
|  | reg |= (di->time.hour & 0x1f) << 11; | 
|  | reg |= (di->time.minute & 0x3f) << 5; | 
|  | reg |= (di->time.second & 0x3e) >> 1; | 
|  | } | 
|  | STOREINTELWORD(sft->file_time, reg); | 
|  | reg = 0; | 
|  | if (di->caps & FLICAPS_DATE) { | 
|  | reg |= ((di->date.year - 1980) & 0x7f) << 9; | 
|  | reg |= (di->date.month & 0x0f) << 5; | 
|  | reg |= di->date.day & 0x1f; | 
|  | } | 
|  | STOREINTELWORD(sft->file_date, reg); | 
 | STOREINTELDWORD(sft->file_size, di->size); | STOREINTELDWORD(sft->file_size, di->size); | 
 | STOREINTELWORD(sft->dir_sector, (UINT16)-1); | STOREINTELWORD(sft->dir_sector, (UINT16)-1); | 
 | sft->dir_entry_no = (UINT8)-1; | sft->dir_entry_no = (UINT8)-1; | 
 | CopyMemory(sft->file_name, is->fcbname_ptr, 11); | CopyMemory(sft->file_name, is->fcbname_ptr, 11); | 
 |  | TRACEOUT(("open -> size %d", di->size)); | 
 | } | } | 
 |  |  | 
 | static void init_sft(SFTREC sft) { | static void init_sft(SFTREC sft) { | 
| Line 212  static void init_sft(SFTREC sft) { | Line 242  static void init_sft(SFTREC sft) { | 
 | else { | else { | 
 | sft->open_mode[0] &= 0x0f; | sft->open_mode[0] &= 0x0f; | 
 | } | } | 
| sft->dev_info_word[0] = (BYTE)(0x40 | hostdrv.drive_no); | sft->dev_info_word[0] = (BYTE)(0x40 | hostdrv.stat.drive_no); | 
 | sft->dev_info_word[1] = 0x80; | sft->dev_info_word[1] = 0x80; | 
 | STOREINTELDWORD(sft->dev_drvr_ptr, 0); | STOREINTELDWORD(sft->dev_drvr_ptr, 0); | 
 | STOREINTELDWORD(sft->file_pos, 0); | STOREINTELDWORD(sft->file_pos, 0); | 
| Line 255  static void setup_ptrs(INTRST is, SDACDS | Line 285  static void setup_ptrs(INTRST is, SDACDS | 
 | char    *rootpath; | char    *rootpath; | 
 | int             off; | int             off; | 
 |  |  | 
| if (hostdrv.dosver_major == 3) { | if (hostdrv.stat.dosver_major == 3) { | 
 | is->fcbname_ptr = sc->ver3.sda.fcb_name; | is->fcbname_ptr = sc->ver3.sda.fcb_name; | 
 | is->filename_ptr = sc->ver3.sda.file_name + ROOTPATH_SIZE - 1; | is->filename_ptr = sc->ver3.sda.file_name + ROOTPATH_SIZE - 1; | 
 | is->fcbname_ptr_2 = sc->ver3.sda.fcb_name_2; | is->fcbname_ptr_2 = sc->ver3.sda.fcb_name_2; | 
| Line 292  static void setup_ptrs(INTRST is, SDACDS | Line 322  static void setup_ptrs(INTRST is, SDACDS | 
 | } | } | 
 |  |  | 
 |  |  | 
| static BOOL read_data(UINT num, UINT32 pos, UINT size, | static BOOL pathishostdrv(INTRST is, SDACDS sc) { | 
| UINT16 seg, UINT16 off) { |  | 
|  | fetch_sda_currcds(sc); | 
|  | setup_ptrs(is, sc); | 
|  |  | 
|  | if (memcmp(is->root_path, ROOTPATH, ROOTPATH_SIZE)) { | 
|  | CPU_FLAG &= ~Z_FLAG;    // chain | 
|  | return(FAILURE); | 
|  | } | 
|  | if (is->is_chardev) { | 
|  | fail(is, ERR_ACCESSDENIED); | 
|  | return(FAILURE); | 
|  | } | 
|  | return(SUCCESS); | 
|  | } | 
|  |  | 
|  |  | 
|  | static BOOL read_data(UINT num, UINT32 pos, UINT size, UINT seg, UINT off) { | 
 |  |  | 
 | HDRVFILE        hdf; | HDRVFILE        hdf; | 
 | FILEH           fh; | FILEH           fh; | 
| BYTE            work[256]; | BYTE            work[1024]; | 
 | UINT            r; | UINT            r; | 
 |  |  | 
 | hdf = (HDRVFILE)listarray_getitem(hostdrv.fhdl, num); | hdf = (HDRVFILE)listarray_getitem(hostdrv.fhdl, num); | 
| Line 320  static BOOL read_data(UINT num, UINT32 p | Line 366  static BOOL read_data(UINT num, UINT32 p | 
 | return(SUCCESS); | return(SUCCESS); | 
 | } | } | 
 |  |  | 
 |  | static BOOL write_data(UINT num, UINT32 pos, UINT size, UINT seg, UINT off) { | 
 |  |  | 
 |  | HDRVFILE        hdf; | 
 |  | FILEH           fh; | 
 |  | BYTE            work[1024]; | 
 |  | UINT            r; | 
 |  |  | 
 |  | hdf = (HDRVFILE)listarray_getitem(hostdrv.fhdl, num); | 
 |  | if (hdf == NULL) { | 
 |  | return(FAILURE); | 
 |  | } | 
 |  | fh = (FILEH)hdf->hdl; | 
 |  | if (file_seek(fh, (long)pos, FSEEK_SET) != (long)pos) { | 
 |  | return(FAILURE); | 
 |  | } | 
 |  | if (!size) { | 
 |  | file_write(fh, work, 0); | 
 |  | } | 
 |  | else { | 
 |  | do { | 
 |  | r = min(size, sizeof(work)); | 
 |  | i286_memstr_read(seg, off, work, r); | 
 |  | if (file_write(fh, work, r) != r) { | 
 |  | return(FAILURE); | 
 |  | } | 
 |  | off += r; | 
 |  | size -= r; | 
 |  | } while(size); | 
 |  | } | 
 |  | return(SUCCESS); | 
 |  | } | 
 |  |  | 
 |  |  | 
 | static BOOL find_file1(INTRST is, const HDRVDIR *di) { | static BOOL find_file1(INTRST is, const HDRVDIR *di) { | 
 |  |  | 
| Line 348  const HDRVDIR *di; | Line 426  const HDRVDIR *di; | 
 | store_srch(is); | store_srch(is); | 
 |  |  | 
 | ret = FAILURE; | ret = FAILURE; | 
| pos = hostdrv.flistpos; | pos = hostdrv.stat.flistpos; | 
 | do { | do { | 
 | if (pos == 0) { | if (pos == 0) { | 
 | di = &hdd_owner; | di = &hdd_owner; | 
| Line 359  const HDRVDIR *di; | Line 437  const HDRVDIR *di; | 
 | else { | else { | 
 | hdl = listarray_getitem(hostdrv.flist, pos - 2); | hdl = listarray_getitem(hostdrv.flist, pos - 2); | 
 | if (hdl == NULL) { | if (hdl == NULL) { | 
 |  | listarray_destroy(hostdrv.flist); | 
 |  | hostdrv.flist = NULL; | 
 | break; | break; | 
 | } | } | 
 | di = &hdl->di; | di = &hdl->di; | 
| Line 366  const HDRVDIR *di; | Line 446  const HDRVDIR *di; | 
 | pos++; | pos++; | 
 | ret = find_file1(is, di); | ret = find_file1(is, di); | 
 | } while(ret != SUCCESS); | } while(ret != SUCCESS); | 
| hostdrv.flistpos = pos; | hostdrv.stat.flistpos = pos; | 
 | return(ret); | return(ret); | 
 | } | } | 
 |  |  | 
| Line 388  static void change_currdir(INTRST intrst | Line 468  static void change_currdir(INTRST intrst | 
 | char            *ptr; | char            *ptr; | 
 | HDRVPATH        hdp; | HDRVPATH        hdp; | 
 |  |  | 
| fetch_sda_currcds(&sc); | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
| setup_ptrs(intrst, &sc); |  | 
|  |  | 
| if (strncmp(intrst->root_path, ROOTPATH, ROOTPATH_SIZE) != 0) { |  | 
| CPU_FLAG &= ~Z_FLAG;    // chain |  | 
| return; |  | 
| } |  | 
| if (intrst->is_chardev) { |  | 
| fail(intrst, ERR_ACCESSDENIED); |  | 
 | return; | return; | 
 | } | } | 
 |  |  | 
 | ptr = intrst->filename_ptr; | ptr = intrst->filename_ptr; | 
 |  | TRACEOUT(("change_currdir %s", intrst->filename_ptr)); | 
 | if (ptr[0] == '\0') {                                                   // るーと | if (ptr[0] == '\0') {                                                   // るーと | 
 | strcpy(intrst->filename_ptr, "\\"); | strcpy(intrst->filename_ptr, "\\"); | 
 | strcpy(intrst->current_path, intrst->filename_ptr); | strcpy(intrst->current_path, intrst->filename_ptr); | 
| Line 408  static void change_currdir(INTRST intrst | Line 481  static void change_currdir(INTRST intrst | 
 | succeed(intrst); | succeed(intrst); | 
 | return; | return; | 
 | } | } | 
| if ((is_wildcards(intrst->fcbname_ptr) != FALSE) || | if ((strlen(intrst->filename_ptr) >= (67 - ROOTPATH_SIZE)) || | 
|  | (is_wildcards(intrst->fcbname_ptr) != FALSE) || | 
 | (hostdrvs_getrealpath(&hdp, ptr) != SUCCESS) || | (hostdrvs_getrealpath(&hdp, ptr) != SUCCESS) || | 
 | (hdp.di.fcbname[0] == ' ') || (!(hdp.di.attr & 0x10))) { | (hdp.di.fcbname[0] == ' ') || (!(hdp.di.attr & 0x10))) { | 
 | fail(intrst, ERR_PATHNOTFOUND); | fail(intrst, ERR_PATHNOTFOUND); | 
| Line 432  static void close_file(INTRST intrst) { | Line 506  static void close_file(INTRST intrst) { | 
 | fetch_sft(intrst, &sft); | fetch_sft(intrst, &sft); | 
 | setup_ptrs(intrst, &sc); | setup_ptrs(intrst, &sc); | 
 |  |  | 
| if ((sft.dev_info_word[0] & 0x3f) != hostdrv.drive_no) { | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
 | CPU_FLAG &= ~Z_FLAG;    // chain | CPU_FLAG &= ~Z_FLAG;    // chain | 
 | return; | return; | 
 | } | } | 
| Line 464  static void commit_file(INTRST intrst) { | Line 538  static void commit_file(INTRST intrst) { | 
 | fetch_sda_currcds(&sc); | fetch_sda_currcds(&sc); | 
 | fetch_sft(intrst, &sft); | fetch_sft(intrst, &sft); | 
 |  |  | 
| if ((sft.dev_info_word[0] & 0x3f) != hostdrv.drive_no) { | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
 | CPU_FLAG &= ~Z_FLAG;    // chain | CPU_FLAG &= ~Z_FLAG;    // chain | 
 | return; | return; | 
 | } | } | 
| Line 486  static void read_file(INTRST intrst) { | Line 560  static void read_file(INTRST intrst) { | 
 | fetch_sft(intrst, &sft); | fetch_sft(intrst, &sft); | 
 | setup_ptrs(intrst, &sc); | setup_ptrs(intrst, &sc); | 
 |  |  | 
| if ((sft.dev_info_word[0] & 0x3f) != hostdrv.drive_no) { | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
 | CPU_FLAG &= ~Z_FLAG;    // chain | CPU_FLAG &= ~Z_FLAG;    // chain | 
 | return; | return; | 
 | } | } | 
| Line 512  static void read_file(INTRST intrst) { | Line 586  static void read_file(INTRST intrst) { | 
 | fail(intrst, ERR_READFAULT); | fail(intrst, ERR_READFAULT); | 
 | return; | return; | 
 | } | } | 
 |  |  | 
 | file_pos += cx; | file_pos += cx; | 
 | STOREINTELDWORD(sft.file_pos, file_pos); | STOREINTELDWORD(sft.file_pos, file_pos); | 
 |  |  | 
 | store_sft(intrst, &sft); | store_sft(intrst, &sft); | 
| store_sda_currcds(&sc); | //      store_sda_currcds(&sc);                                         // ver0.74 Yui / sdaは変更無し | 
|  | succeed(intrst); | 
|  | } | 
|  |  | 
|  | /* 09 */ | 
|  | static void write_file(INTRST intrst) { | 
|  |  | 
|  | _SDACDS         sc; | 
|  | _SFTREC         sft; | 
|  | UINT16          cx; | 
|  | UINT            file_size; | 
|  | UINT32          file_pos; | 
|  |  | 
|  | fetch_sda_currcds(&sc); | 
|  | fetch_sft(intrst, &sft); | 
|  | setup_ptrs(intrst, &sc); | 
|  |  | 
|  | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
|  | CPU_FLAG &= ~Z_FLAG;    // chain | 
|  | return; | 
|  | } | 
|  |  | 
|  | if ((!IS_PERMITWRITE) || | 
|  | (!(sft.open_mode[0] & 3))) {    // read only | 
|  | fail(intrst, ERR_ACCESSDENIED); | 
|  | return; | 
|  | } | 
|  |  | 
|  | cx = LOADINTELWORD(intrst->r.w.cx); | 
|  | file_size = LOADINTELDWORD(sft.file_size); | 
|  | file_pos = LOADINTELDWORD(sft.file_pos); | 
|  | if (write_data(LOADINTELWORD(sft.start_sector), file_pos, cx, | 
|  | LOADINTELWORD(sc.ver3.sda.current_dta.seg), | 
|  | LOADINTELWORD(sc.ver3.sda.current_dta.off)) != SUCCESS) { | 
|  | fail(intrst, ERR_WRITEFAULT); | 
|  | return; | 
|  | } | 
|  | if (cx) { | 
|  | file_pos += cx; | 
|  | if (file_size < file_pos) { | 
|  | file_size = file_pos; | 
|  | } | 
|  | } | 
|  | else { | 
|  | file_size = file_pos; | 
|  | } | 
|  |  | 
|  | STOREINTELDWORD(sft.file_size, file_size); | 
|  | STOREINTELDWORD(sft.file_pos, file_pos); | 
|  | store_sft(intrst, &sft); | 
 | succeed(intrst); | succeed(intrst); | 
 | } | } | 
 |  |  | 
| Line 529  static void lock_file(INTRST intrst) { | Line 653  static void lock_file(INTRST intrst) { | 
 | fetch_sda_currcds(&sc); | fetch_sda_currcds(&sc); | 
 | fetch_sft(intrst, &sft); | fetch_sft(intrst, &sft); | 
 |  |  | 
| if ((sft.dev_info_word[0] & 0x3f) != hostdrv.drive_no) { | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
 | CPU_FLAG &= ~Z_FLAG;    // chain | CPU_FLAG &= ~Z_FLAG;    // chain | 
 | return; | return; | 
 | } | } | 
| Line 546  static void unlock_file(INTRST intrst) { | Line 670  static void unlock_file(INTRST intrst) { | 
 | fetch_sda_currcds(&sc); | fetch_sda_currcds(&sc); | 
 | fetch_sft(intrst, &sft); | fetch_sft(intrst, &sft); | 
 |  |  | 
| if ((sft.dev_info_word[0] & 0x3f) != hostdrv.drive_no) { | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
 | CPU_FLAG &= ~Z_FLAG;    // chain | CPU_FLAG &= ~Z_FLAG;    // chain | 
 | return; | return; | 
 | } | } | 
| Line 554  static void unlock_file(INTRST intrst) { | Line 678  static void unlock_file(INTRST intrst) { | 
 | TRACEOUT(("hostdrv: unlock_file")); | TRACEOUT(("hostdrv: unlock_file")); | 
 | } | } | 
 |  |  | 
| /* 0F */ | /* 0E */ | 
| static void get_fileattr(INTRST intrst) { | static void set_fileattr(INTRST intrst) { | 
 |  |  | 
 | _SDACDS         sc; | _SDACDS         sc; | 
 | HDRVPATH        hdp; | HDRVPATH        hdp; | 
| UINT16          ax; | REG16           attr; | 
|  |  | 
| fetch_sda_currcds(&sc); |  | 
| setup_ptrs(intrst, &sc); |  | 
 |  |  | 
| if (strncmp(intrst->root_path, ROOTPATH, ROOTPATH_SIZE) != 0) { | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
| CPU_FLAG &= ~Z_FLAG;    // chain |  | 
 | return; | return; | 
 | } | } | 
| if (intrst->is_chardev) { | if ((is_wildcards(intrst->fcbname_ptr)) || | 
|  | (hostdrvs_getrealpath(&hdp, intrst->filename_ptr) != SUCCESS)) { | 
|  | fail(intrst, ERR_FILENOTFOUND); | 
|  | return; | 
|  | } | 
|  | if (!IS_PERMITWRITE) { | 
 | fail(intrst, ERR_ACCESSDENIED); | fail(intrst, ERR_ACCESSDENIED); | 
 | return; | return; | 
 | } | } | 
 |  | attr = i286_memword_read(CPU_SS, CPU_BP + sizeof(IF4INTR)) & 0x37; | 
 |  |  | 
 |  | // 成功したことにする... | 
 |  | succeed(intrst); | 
 |  | } | 
 |  |  | 
 |  | /* 0F */ | 
 |  | static void get_fileattr(INTRST intrst) { | 
 |  |  | 
 |  | _SDACDS         sc; | 
 |  | HDRVPATH        hdp; | 
 |  | UINT16          ax; | 
 |  |  | 
 |  | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
 |  | return; | 
 |  | } | 
 |  |  | 
 |  | TRACEOUT(("get_fileattr: ->%s", intrst->fcbname_ptr)); | 
 | if ((is_wildcards(intrst->fcbname_ptr)) || | if ((is_wildcards(intrst->fcbname_ptr)) || | 
 | (hostdrvs_getrealpath(&hdp, intrst->filename_ptr) != SUCCESS)) { | (hostdrvs_getrealpath(&hdp, intrst->filename_ptr) != SUCCESS)) { | 
 | fail(intrst, ERR_FILENOTFOUND); | fail(intrst, ERR_FILENOTFOUND); | 
 | return; | return; | 
 | } | } | 
 |  | TRACEOUT(("get_fileattr: %s - %x", hdp.path, hdp.di.attr)); | 
 | ax = hdp.di.attr & 0x37; | ax = hdp.di.attr & 0x37; | 
 | if (!IS_PERMITWRITE) { | if (!IS_PERMITWRITE) { | 
 | ax |= 0x01; | ax |= 0x01; | 
| Line 585  static void get_fileattr(INTRST intrst) | Line 729  static void get_fileattr(INTRST intrst) | 
 | STOREINTELWORD(intrst->r.w.ax, ax); | STOREINTELWORD(intrst->r.w.ax, ax); | 
 | } | } | 
 |  |  | 
 |  | /* 11 */ | 
 |  | static void rename_file(INTRST intrst) { | 
 |  |  | 
 |  | _SDACDS         sc; | 
 |  | HDRVPATH        hdp1; | 
 |  | HDRVPATH        hdp2; | 
 |  |  | 
 |  | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
 |  | return; | 
 |  | } | 
 |  |  | 
 |  | // ワイルドカードくるんで要修正… | 
 |  | if ((hostdrvs_getrealpath(&hdp1, intrst->filename_ptr) != SUCCESS) || | 
 |  | (hostdrvs_getrealpath(&hdp2, intrst->filename_ptr_2) != SUCCESS)) { | 
 |  | fail(intrst, ERR_PATHNOTFOUND); | 
 |  | return; | 
 |  | } | 
 |  | TRACEOUT(("rename_file %s to %s - failed", hdp1.path, hdp2.path)); | 
 |  | fail(intrst, ERR_ACCESSDENIED); | 
 |  | } | 
 |  |  | 
 |  | /* 13 */ | 
 |  | static void delete_file(INTRST intrst) { | 
 |  |  | 
 |  | _SDACDS         sc; | 
 |  | HDRVPATH        hdp; | 
 |  |  | 
 |  | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
 |  | return; | 
 |  | } | 
 |  |  | 
 |  | // ワイルドカードくるんで要修正… | 
 |  | if ((hostdrvs_getrealpath(&hdp, intrst->filename_ptr) != SUCCESS) || | 
 |  | (hdp.di.attr & 0x10)) { | 
 |  | fail(intrst, ERR_PATHNOTFOUND); | 
 |  | return; | 
 |  | } | 
 |  | TRACEOUT(("delete_file %s - failed", hdp.path)); | 
 |  | fail(intrst, ERR_ACCESSDENIED); | 
 |  | } | 
 |  |  | 
 | /* 16 */ | /* 16 */ | 
 | static void open_file(INTRST intrst) { | static void open_file(INTRST intrst) { | 
 |  |  | 
 | _SDACDS         sc; | _SDACDS         sc; | 
 | _SFTREC         sft; | _SFTREC         sft; | 
 | HDRVPATH        hdp; | HDRVPATH        hdp; | 
| HDRVFILE        hdf; | UINT            mode; | 
 | FILEH           fh; | FILEH           fh; | 
 |  | HDRVFILE        hdf; | 
 |  |  | 
| fetch_sda_currcds(&sc); | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
| fetch_sft(intrst, &sft); |  | 
| setup_ptrs(intrst, &sc); |  | 
|  |  | 
| if (strncmp(intrst->root_path, ROOTPATH, ROOTPATH_SIZE) != 0) { |  | 
| CPU_FLAG &= ~Z_FLAG;    // chain |  | 
| return; |  | 
| } |  | 
| if (intrst->is_chardev) { |  | 
| fail(intrst, ERR_ACCESSDENIED); |  | 
 | return; | return; | 
 | } | } | 
 |  | //      fetch_sft(intrst, &sft); | 
 |  | ZeroMemory(&sft, sizeof(sft)); | 
 |  |  | 
 | if ((is_wildcards(intrst->fcbname_ptr)) || | if ((is_wildcards(intrst->fcbname_ptr)) || | 
 | (hostdrvs_getrealpath(&hdp, intrst->filename_ptr) != SUCCESS) || | (hostdrvs_getrealpath(&hdp, intrst->filename_ptr) != SUCCESS) || | 
 | (hdp.di.attr & 0x10)) { | (hdp.di.attr & 0x10)) { | 
| Line 616  static void open_file(INTRST intrst) { | Line 796  static void open_file(INTRST intrst) { | 
 | hdp.path, sft.open_mode[0] & 7)); | hdp.path, sft.open_mode[0] & 7)); | 
 | switch(sft.open_mode[0] & 7) { | switch(sft.open_mode[0] & 7) { | 
 | case 1: // write only | case 1: // write only | 
 |  | mode = HDFMODE_WRITE; | 
 |  | break; | 
 |  |  | 
 | case 2: // read/write | case 2: // read/write | 
| if (!IS_PERMITWRITE) { | mode = HDFMODE_READ | HDFMODE_WRITE; | 
| fail(intrst, ERR_ACCESSDENIED); |  | 
| return; |  | 
| } |  | 
 | break; | break; | 
 |  |  | 
 |  | default: | 
 |  | mode = HDFMODE_READ; | 
 |  | break; | 
 |  | } | 
 |  |  | 
 |  | if (mode & HDFMODE_WRITE) { | 
 |  | if (!IS_PERMITWRITE) { | 
 |  | fail(intrst, ERR_ACCESSDENIED); | 
 |  | return; | 
 |  | } | 
 |  | fh = file_open(hdp.path); | 
 |  | } | 
 |  | else { | 
 |  | fh = file_open_rb(hdp.path); | 
 |  | } | 
 |  | if (fh == FILEH_INVALID) { | 
 |  | TRACEOUT(("file open error!")); | 
 |  | fail(intrst, ERR_PATHNOTFOUND); | 
 |  | return; | 
 | } | } | 
 |  |  | 
 | hdf = hostdrvs_fhdlsea(hostdrv.fhdl); | hdf = hostdrvs_fhdlsea(hostdrv.fhdl); | 
 | if (hdf == NULL) { | if (hdf == NULL) { | 
 |  | file_close(fh); | 
 | fail(intrst, ERR_PATHNOTFOUND); | fail(intrst, ERR_PATHNOTFOUND); | 
 | return; | return; | 
 | } | } | 
| fh = file_open_rb(hdp.path); |  | 
| if (fh == FILEH_INVALID) { | hdf->hdl = (long)fh; | 
| TRACEOUT(("file open error!")); | hdf->mode = mode; | 
|  | file_cpyname(hdf->path, hdp.path, sizeof(hdf->path)); | 
|  |  | 
|  | fill_sft(intrst, &sft, listarray_getpos(hostdrv.fhdl, hdf), &hdp.di); | 
|  | init_sft(&sft); | 
|  |  | 
|  | store_sft(intrst, &sft); | 
|  | store_sda_currcds(&sc); | 
|  | succeed(intrst); | 
|  | } | 
|  |  | 
|  | /* 17 */ | 
|  | static void create_file(INTRST intrst) { | 
|  |  | 
|  | _SDACDS         sc; | 
|  | _SFTREC         sft; | 
|  | HDRVPATH        hdp; | 
|  | HDRVFILE        hdf; | 
|  | FILEH           fh; | 
|  |  | 
|  | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
|  | return; | 
|  | } | 
|  | fetch_sft(intrst, &sft); | 
|  |  | 
|  | if ((is_wildcards(intrst->fcbname_ptr)) || | 
|  | (hostdrvs_newrealpath(&hdp, intrst->filename_ptr) != SUCCESS) || | 
|  | (hdp.di.attr & 0x10)) { | 
|  | fail(intrst, ERR_PATHNOTFOUND); | 
|  | return; | 
|  | } | 
|  | TRACEOUT(("create_file: %s -> %s %d", intrst->filename_ptr, | 
|  | hdp.path, sft.open_mode[0] & 7)); | 
|  |  | 
|  | if (!IS_PERMITWRITE) { | 
|  | fail(intrst, ERR_ACCESSDENIED); | 
|  | return; | 
|  | } | 
|  |  | 
|  | hdf = hostdrvs_fhdlsea(hostdrv.fhdl); | 
|  | if (hdf == NULL) { | 
 | fail(intrst, ERR_PATHNOTFOUND); | fail(intrst, ERR_PATHNOTFOUND); | 
 | return; | return; | 
 | } | } | 
 |  | fh = file_create(hdp.path); | 
 |  | if (fh == FILEH_INVALID) { | 
 |  | TRACEOUT(("file create error!")); | 
 |  | fail(intrst, ERR_ACCESSDENIED); | 
 |  | return; | 
 |  | } | 
 | hdf->hdl = (long)fh; | hdf->hdl = (long)fh; | 
| hdf->mode = 0; | hdf->mode = HDFMODE_READ | HDFMODE_WRITE; | 
 | file_cpyname(hdf->path, hdp.path, sizeof(hdf->path)); | file_cpyname(hdf->path, hdp.path, sizeof(hdf->path)); | 
 |  |  | 
 | fill_sft(intrst, &sft, listarray_getpos(hostdrv.fhdl, hdf), &hdp.di); | fill_sft(intrst, &sft, listarray_getpos(hostdrv.fhdl, hdf), &hdp.di); | 
| Line 656  static void find_first(INTRST intrst) { | Line 904  static void find_first(INTRST intrst) { | 
 | flist = hostdrv.flist; | flist = hostdrv.flist; | 
 | if (flist) { | if (flist) { | 
 | hostdrv.flist = NULL; | hostdrv.flist = NULL; | 
| hostdrv.flistpos = 0; | hostdrv.stat.flistpos = 0; | 
 | listarray_destroy(flist); | listarray_destroy(flist); | 
 | } | } | 
 |  |  | 
| fetch_sda_currcds(&sc); | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
| setup_ptrs(intrst, &sc); |  | 
|  |  | 
| if (strncmp(intrst->root_path, ROOTPATH, ROOTPATH_SIZE) != 0) { |  | 
| CPU_FLAG &= ~Z_FLAG;    // chain |  | 
| return; |  | 
| } |  | 
| if (intrst->is_chardev) { |  | 
| fail(intrst, ERR_ACCESSDENIED); |  | 
 | return; | return; | 
 | } | } | 
 |  |  | 
| Line 684  static void find_first(INTRST intrst) { | Line 924  static void find_first(INTRST intrst) { | 
 | } | } | 
 | TRACEOUT(("find_first %s -> %s", intrst->current_path, hdp.path)); | TRACEOUT(("find_first %s -> %s", intrst->current_path, hdp.path)); | 
 | hostdrv.flist = hostdrvs_getpathlist(hdp.path); | hostdrv.flist = hostdrvs_getpathlist(hdp.path); | 
| hostdrv.flistpos = 0; | hostdrv.stat.flistpos = 0; | 
 | if (find_file(intrst) != SUCCESS) { | if (find_file(intrst) != SUCCESS) { | 
 | fail(intrst, ERR_PATHNOTFOUND); | fail(intrst, ERR_PATHNOTFOUND); | 
 | return; | return; | 
| Line 699  static void find_next(INTRST intrst) { | Line 939  static void find_next(INTRST intrst) { | 
 |  |  | 
 | _SDACDS         sc; | _SDACDS         sc; | 
 | SRCHREC         srchrec; | SRCHREC         srchrec; | 
 | //      char            *curpath; |  | 
 |  |  | 
 | fetch_sda_currcds(&sc); | fetch_sda_currcds(&sc); | 
 | setup_ptrs(intrst, &sc); | setup_ptrs(intrst, &sc); | 
 |  |  | 
 | srchrec = intrst->srchrec_ptr; | srchrec = intrst->srchrec_ptr; | 
 | if ((!(srchrec->drive_no & 0x40)) || | if ((!(srchrec->drive_no & 0x40)) || | 
| ((srchrec->drive_no & 0x1f) != hostdrv.drive_no)) { | ((srchrec->drive_no & 0x1f) != hostdrv.stat.drive_no)) { | 
 | CPU_FLAG &= ~Z_FLAG;    // chain | CPU_FLAG &= ~Z_FLAG;    // chain | 
 | return; | return; | 
 | } | } | 
 | //      curpath = intrst->current_path; |  | 
 | if (find_file(intrst) != SUCCESS) { | if (find_file(intrst) != SUCCESS) { | 
 | fail(intrst, ERR_NOMOREFILES); | fail(intrst, ERR_NOMOREFILES); | 
 | return; | return; | 
| Line 719  static void find_next(INTRST intrst) { | Line 957  static void find_next(INTRST intrst) { | 
 | succeed(intrst); | succeed(intrst); | 
 | } | } | 
 |  |  | 
 |  | #if 1 | 
 |  | /* 1E */ | 
 |  | static void do_redir(INTRST intrst) { | 
 |  |  | 
 |  | _SDACDS         sc; | 
 |  | REG16           mode; | 
 |  | REG16           bx; | 
 |  | char            tmp[4]; | 
 |  |  | 
 |  | TRACEOUT(("do_redir")); | 
 |  | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
 |  | return; | 
 |  | } | 
 |  | mode = i286_memword_read(CPU_SS, CPU_BP + sizeof(IF4INTR)); | 
 |  | TRACEOUT(("do_redir: %.4x", mode)); | 
 |  | switch(mode) { | 
 |  | case 0x5f02: | 
 |  | bx = LOADINTELWORD(intrst->r.w.bx); | 
 |  | if (bx) { | 
 |  | fail(intrst, 0x12); | 
 |  | return; | 
 |  | } | 
 |  | i286_memword_write(CPU_DS, CPU_BX + 2, 4); | 
 |  | i286_memword_write(CPU_DS, CPU_BX + 4, 1); | 
 |  | //                      STOREINTELWORD(intrst->r.w.bx, 4); | 
 |  | //                      STOREINTELWORD(intrst->r.w.cx, 1); | 
 |  | tmp[0] = (char)('A' + hostdrv.stat.drive_no); | 
 |  | tmp[1] = ':'; | 
 |  | tmp[2] = '\0'; | 
 |  | i286_memstr_write(LOADINTELWORD(intrst->r.w.ds), | 
 |  | LOADINTELWORD(intrst->r.w.si), tmp, 3); | 
 |  | i286_memstr_write(LOADINTELWORD(intrst->r.w.es), | 
 |  | LOADINTELWORD(intrst->r.w.di), | 
 |  | ROOTPATH, ROOTPATH_SIZE + 1); | 
 |  | break; | 
 |  |  | 
 |  | default: | 
 |  | CPU_FLAG &= ~Z_FLAG;    // chain | 
 |  | return; | 
 |  | } | 
 |  | succeed(intrst); | 
 |  | } | 
 |  | #endif | 
 |  |  | 
 |  | /* 21 */ | 
 |  | // dos4以降呼ばれることはあんまない・・・ | 
 |  | static void seek_fromend(INTRST intrst) { | 
 |  |  | 
 |  | _SDACDS         sc; | 
 |  | _SFTREC         sft; | 
 |  | UINT16          reg; | 
 |  | UINT32          pos; | 
 |  | UINT            file_size; | 
 |  |  | 
 |  | fetch_sda_currcds(&sc); | 
 |  | fetch_sft(intrst, &sft); | 
 |  |  | 
 |  | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
 |  | CPU_FLAG &= ~Z_FLAG;    // chain | 
 |  | return; | 
 |  | } | 
 |  | reg = LOADINTELWORD(intrst->r.w.cx); | 
 |  | pos = reg << 16; | 
 |  | reg = LOADINTELWORD(intrst->r.w.dx); | 
 |  | pos += reg; | 
 |  | file_size = LOADINTELDWORD(sft.file_size); | 
 |  | if (pos > file_size) { | 
 |  | pos = file_size; | 
 |  | } | 
 |  | reg = (UINT16)(pos >> 16); | 
 |  | STOREINTELWORD(intrst->r.w.dx, reg); | 
 |  | reg = (UINT16)pos; | 
 |  | STOREINTELWORD(intrst->r.w.ax, reg); | 
 |  | pos = file_size - pos; | 
 |  | STOREINTELDWORD(sft.file_pos, pos); | 
 |  |  | 
 |  | store_sft(intrst, &sft); | 
 |  | intrst->r.b.flag_l &= ~C_FLAG; | 
 |  | } | 
 |  |  | 
 |  | /* 2D */ | 
 |  | static void unknownfunc_2d(INTRST intrst) { | 
 |  |  | 
 |  | _SDACDS         sc; | 
 |  | _SFTREC         sft; | 
 |  |  | 
 |  | fetch_sda_currcds(&sc); | 
 |  | fetch_sft(intrst, &sft); | 
 |  | if ((sft.dev_info_word[0] & 0x3f) != hostdrv.stat.drive_no) { | 
 |  | CPU_FLAG &= ~Z_FLAG;    // chain | 
 |  | return; | 
 |  | } | 
 |  | #if 1 | 
 |  | TRACEOUT(("unknownfunc_2d")); | 
 |  | #else | 
 |  | intr_regs.flags &= ~C_FLAG; | 
 |  | intr_regs.ax = 2; | 
 |  | #endif | 
 |  | } | 
 |  |  | 
 |  | /* 2E */ | 
 |  | // for dos4+ | 
 |  | static void ext_openfile(INTRST intrst) { | 
 |  |  | 
 |  | _SDACDS         sc; | 
 |  | _SFTREC         sft; | 
 |  | HDRVPATH        hdp; | 
 |  | UINT            mode; | 
 |  | BOOL            create; | 
 |  | REG16           act; | 
 |  | REG16           cx; | 
 |  | FILEH           fh; | 
 |  | HDRVFILE        hdf; | 
 |  |  | 
 |  | if (pathishostdrv(intrst, &sc) != SUCCESS) { | 
 |  | return; | 
 |  | } | 
 |  | fetch_sft(intrst, &sft); | 
 |  |  | 
 |  | // ファイルを探しに〜 | 
 |  | if ((is_wildcards(intrst->fcbname_ptr)) || | 
 |  | (hostdrvs_newrealpath(&hdp, intrst->filename_ptr) != SUCCESS) || | 
 |  | (hdp.di.attr & 0x10)) { | 
 |  | fail(intrst, ERR_PATHNOTFOUND); | 
 |  | return; | 
 |  | } | 
 |  |  | 
 |  | sft.open_mode[0] = sc.ver4.sda.mode_2E[0] & 0x7f; | 
 |  | sft.open_mode[1] = sc.ver4.sda.mode_2E[1] & 0x00; | 
 |  | act     = LOADINTELWORD(sc.ver4.sda.action_2E); | 
 |  |  | 
 |  | switch(sft.open_mode[0] & 7) { | 
 |  | case 1: // write only | 
 |  | mode = HDFMODE_WRITE; | 
 |  | break; | 
 |  |  | 
 |  | case 2: // read/write | 
 |  | mode = HDFMODE_READ | HDFMODE_WRITE; | 
 |  | break; | 
 |  |  | 
 |  | default: | 
 |  | mode = HDFMODE_READ; | 
 |  | break; | 
 |  | } | 
 |  |  | 
 |  | create = FALSE; | 
 |  | if (hdp.di.exist) {                                     // ファイルが存在 | 
 |  | switch(act & 3) { | 
 |  | case 1: | 
 |  | cx = 1; | 
 |  | break; | 
 |  |  | 
 |  | case 2: | 
 |  | create = TRUE; | 
 |  | cx = 3; | 
 |  | break; | 
 |  |  | 
 |  | default: | 
 |  | fail(intrst, ERR_ACCESSDENIED); | 
 |  | return; | 
 |  | } | 
 |  | } | 
 |  | else {                                                          // 新規ファイル | 
 |  | if (act & 0x10) { | 
 |  | create = TRUE; | 
 |  | cx = 2; | 
 |  | } | 
 |  | else { | 
 |  | fail(intrst, ERR_PATHNOTFOUND); | 
 |  | return; | 
 |  | } | 
 |  | } | 
 |  |  | 
 |  | if (create) { | 
 |  | if (!IS_PERMITWRITE) { | 
 |  | fail(intrst, ERR_ACCESSDENIED); | 
 |  | return; | 
 |  | } | 
 |  | fh = file_create(hdp.path); | 
 |  | } | 
 |  | else if (mode & HDFMODE_WRITE) { | 
 |  | if (!IS_PERMITWRITE) { | 
 |  | fail(intrst, ERR_ACCESSDENIED); | 
 |  | return; | 
 |  | } | 
 |  | fh = file_open(hdp.path); | 
 |  | } | 
 |  | else { | 
 |  | fh = file_open_rb(hdp.path); | 
 |  | } | 
 |  | if (fh == FILEH_INVALID) { | 
 |  | TRACEOUT(("file open error!")); | 
 |  | fail(intrst, ERR_PATHNOTFOUND); | 
 |  | return; | 
 |  | } | 
 |  |  | 
 |  | hdf = hostdrvs_fhdlsea(hostdrv.fhdl); | 
 |  | if (hdf == NULL) { | 
 |  | file_close(fh); | 
 |  | fail(intrst, ERR_PATHNOTFOUND); | 
 |  | return; | 
 |  | } | 
 |  |  | 
 |  | hdf->hdl = (long)fh; | 
 |  | hdf->mode = mode; | 
 |  | file_cpyname(hdf->path, hdp.path, sizeof(hdf->path)); | 
 |  |  | 
 |  | STOREINTELWORD(intrst->r.w.cx, cx); | 
 |  | fill_sft(intrst, &sft, listarray_getpos(hostdrv.fhdl, hdf), &hdp.di); | 
 |  | init_sft(&sft); | 
 |  | store_sft(intrst, &sft); | 
 |  |  | 
 |  | store_sda_currcds(&sc); | 
 |  | succeed(intrst); | 
 |  | } | 
 |  |  | 
 |  |  | 
 | // ---- | // ---- | 
 |  |  | 
| Line 734  static const HDINTRFN intr_func[] = { | Line 1188  static const HDINTRFN intr_func[] = { | 
 | close_file,                     /* 06 */ | close_file,                     /* 06 */ | 
 | commit_file,            /* 07 */ | commit_file,            /* 07 */ | 
 | read_file,                      /* 08 */ | read_file,                      /* 08 */ | 
| NULL,   //      write_file,                     /* 09 */ | write_file,                     /* 09 */ | 
 | lock_file,                      /* 0A */ | lock_file,                      /* 0A */ | 
 | unlock_file,            /* 0B */ | unlock_file,            /* 0B */ | 
 | NULL,   //      get_diskspace,          /* 0C */ | NULL,   //      get_diskspace,          /* 0C */ | 
 | NULL, | NULL, | 
| NULL,   //      set_fileattr,           /* 0E */ | set_fileattr,           /* 0E */ | 
 | get_fileattr,           /* 0F */ | get_fileattr,           /* 0F */ | 
 | NULL, | NULL, | 
| NULL,   //      rename_file,            /* 11 */ | rename_file,            /* 11 */ | 
 | NULL, | NULL, | 
| NULL,   //      delete_file,            /* 13 */ | delete_file,            /* 13 */ | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
 | open_file,                      /* 16 */ | open_file,                      /* 16 */ | 
| NULL,   //      create_file,            /* 17 */ | create_file,            /* 17 */ | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
 | find_first,                     /* 1B */ | find_first,                     /* 1B */ | 
 | find_next,                      /* 1C */ | find_next,                      /* 1C */ | 
 | NULL, | NULL, | 
 |  | do_redir, | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
| NULL, | seek_fromend,           /* 21 */ | 
| NULL,   //      seek_fromend,           /* 21 */ |  | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
| Line 770  static const HDINTRFN intr_func[] = { | Line 1224  static const HDINTRFN intr_func[] = { | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
 | NULL, | NULL, | 
| NULL,   //      unknownfunc_2d,         /* 2D */ | unknownfunc_2d,         /* 2D */ | 
| NULL,   //      ext_openfile            /* 2E */ | ext_openfile            /* 2E */ | 
 | }; | }; | 
 |  |  | 
 |  |  | 
| Line 804  void hostdrv_reset(void) { | Line 1258  void hostdrv_reset(void) { | 
 |  |  | 
 | // ---- for np2sysp | // ---- for np2sysp | 
 |  |  | 
| BOOL hostdrv_mount(void) { | void hostdrv_mount(const void *arg1, long arg2) { | 
 |  |  | 
| if ((np2cfg.hdrvroot[0] == '\0') || (hostdrv.is_mount)) { | if ((np2cfg.hdrvroot[0] == '\0') || (hostdrv.stat.is_mount)) { | 
| return(FAILURE); | np2sysp_outstr("ng", 0); | 
 | } | } | 
| hostdrv.is_mount = TRUE; | hostdrv.stat.is_mount = TRUE; | 
 | fetch_if4dos(); | fetch_if4dos(); | 
| return(SUCCESS); | np2sysp_outstr("ok", 0); | 
|  | (void)arg1; | 
|  | (void)arg2; | 
 | } | } | 
 |  |  | 
| void hostdrv_unmount(void) { | void hostdrv_unmount(const void *arg1, long arg2) { | 
 |  |  | 
| if (hostdrv.is_mount) { | if (hostdrv.stat.is_mount) { | 
 | hostdrv_reset(); | hostdrv_reset(); | 
 | } | } | 
 |  | (void)arg1; | 
 |  | (void)arg2; | 
 | } | } | 
 |  |  | 
| void hostdrv_intr(void) { | void hostdrv_intr(const void *arg1, long arg2) { | 
 |  |  | 
 | _INTRST intrst; | _INTRST intrst; | 
 |  |  | 
| Line 829  void hostdrv_intr(void) { | Line 1287  void hostdrv_intr(void) { | 
 | intrst.is_chardev = (CPU_FLAG & C_FLAG) == 0; | intrst.is_chardev = (CPU_FLAG & C_FLAG) == 0; | 
 | CPU_FLAG &= ~(C_FLAG | Z_FLAG);                         // not fcb / chain | CPU_FLAG &= ~(C_FLAG | Z_FLAG);                         // not fcb / chain | 
 |  |  | 
| if (!hostdrv.is_mount) { | if (!hostdrv.stat.is_mount) { | 
 | return; | return; | 
 | } | } | 
 |  |  | 
 | fetch_intr_regs(&intrst); | fetch_intr_regs(&intrst); | 
 |  |  | 
| //      TRACEOUT(("hostdrv: AL=%.2x", intrst.r.b.al)); | TRACEOUT(("hostdrv: AL=%.2x", intrst.r.b.al)); | 
 |  |  | 
 | if ((intrst.r.b.al >= sizeof(intr_func) / sizeof(HDINTRFN)) || | if ((intrst.r.b.al >= sizeof(intr_func) / sizeof(HDINTRFN)) || | 
 | (intr_func[intrst.r.b.al] == NULL)) { | (intr_func[intrst.r.b.al] == NULL)) { | 
| Line 846  void hostdrv_intr(void) { | Line 1304  void hostdrv_intr(void) { | 
 | (*intr_func[intrst.r.b.al])(&intrst); | (*intr_func[intrst.r.b.al])(&intrst); | 
 |  |  | 
 | store_intr_regs(&intrst); | store_intr_regs(&intrst); | 
 |  |  | 
 |  | (void)arg1; | 
 |  | (void)arg2; | 
 |  | } | 
 |  |  | 
 |  |  | 
 |  | // ---- for statsave | 
 |  |  | 
 |  | typedef struct { | 
 |  | UINT    stat; | 
 |  | UINT    files; | 
 |  | UINT    flists; | 
 |  | } SFHDRV; | 
 |  |  | 
 |  | static BOOL fhdl_wr(void *vpItem, void *vpArg) { | 
 |  |  | 
 |  | char    *p; | 
 |  | UINT    len; | 
 |  |  | 
 |  | p = ((HDRVFILE)vpItem)->path; | 
 |  | len = strlen(p); | 
 |  | statflag_write((STFLAGH)vpArg, &len, sizeof(len)); | 
 |  | if (len) { | 
 |  | if (len < sizeof(MAX_PATH)) { | 
 |  | ZeroMemory(p + len, sizeof(MAX_PATH) - len); | 
 |  | } | 
 |  | statflag_write((STFLAGH)vpArg, vpItem, sizeof(_HDRVFILE)); | 
 |  | } | 
 |  | return(FALSE); | 
 |  | } | 
 |  |  | 
 |  | static BOOL flist_wr(void *vpItem, void *vpArg) { | 
 |  |  | 
 |  | char    *p; | 
 |  | int             len; | 
 |  |  | 
 |  | p = ((HDRVLST)vpItem)->realname; | 
 |  | len = strlen(p); | 
 |  | if (len < sizeof(MAX_PATH)) { | 
 |  | ZeroMemory(p + len, sizeof(MAX_PATH) - len); | 
 |  | } | 
 |  | statflag_write((STFLAGH)vpArg, vpItem, sizeof(_HDRVLST)); | 
 |  | return(FALSE); | 
 | } | } | 
 |  |  | 
 |  | int hostdrv_sfsave(STFLAGH sfh, const SFENTRY *tbl) { | 
 |  |  | 
 |  | SFHDRV  sfhdrv; | 
 |  | int             ret; | 
 |  |  | 
 |  | if (!hostdrv.stat.is_mount) { | 
 |  | return(STATFLAG_SUCCESS); | 
 |  | } | 
 |  | sfhdrv.stat = sizeof(hostdrv.stat); | 
 |  | sfhdrv.files = listarray_getitems(hostdrv.fhdl); | 
 |  | sfhdrv.flists = listarray_getitems(hostdrv.flist); | 
 |  | ret = statflag_write(sfh, &sfhdrv, sizeof(sfhdrv)); | 
 |  | ret |= statflag_write(sfh, &hostdrv.stat, sizeof(hostdrv.stat)); | 
 |  | listarray_enum(hostdrv.fhdl, fhdl_wr, sfh); | 
 |  | listarray_enum(hostdrv.flist, flist_wr, sfh); | 
 |  | (void)tbl; | 
 |  | return(ret); | 
 |  | } | 
 |  |  | 
 |  | int hostdrv_sfload(STFLAGH sfh, const SFENTRY *tbl) { | 
 |  |  | 
 |  | SFHDRV          sfhdrv; | 
 |  | int                     ret; | 
 |  | UINT            i; | 
 |  | UINT            len; | 
 |  | HDRVFILE        hdf; | 
 |  | FILEH           fh; | 
 |  | HDRVLST         hdl; | 
 |  |  | 
 |  | listarray_clr(hostdrv.fhdl); | 
 |  | listarray_clr(hostdrv.flist); | 
 |  |  | 
 |  | ret = statflag_read(sfh, &sfhdrv, sizeof(sfhdrv)); | 
 |  | if (sfhdrv.stat != sizeof(hostdrv.stat)) { | 
 |  | return(STATFLAG_FAILURE); | 
 |  | } | 
 |  | ret |= statflag_read(sfh, &hostdrv.stat, sizeof(hostdrv.stat)); | 
 |  | for (i=0; i<sfhdrv.files; i++) { | 
 |  | hdf = (HDRVFILE)listarray_append(hostdrv.fhdl, NULL); | 
 |  | if (hdf == NULL) { | 
 |  | return(STATFLAG_FAILURE); | 
 |  | } | 
 |  | ret |= statflag_read(sfh, &len, sizeof(len)); | 
 |  | if (len) { | 
 |  | ret |= statflag_read(sfh, hdf, sizeof(_HDRVFILE)); | 
 |  | if (hdf->mode & HDFMODE_WRITE) { | 
 |  | fh = file_open(hdf->path); | 
 |  | } | 
 |  | else { | 
 |  | fh = file_open_rb(hdf->path); | 
 |  | } | 
 |  | hdf->hdl = (long)fh; | 
 |  | } | 
 |  | } | 
 |  | for (i=0; i<sfhdrv.flists; i++) { | 
 |  | hdl = (HDRVLST)listarray_append(hostdrv.flist, NULL); | 
 |  | if (hdl == NULL) { | 
 |  | return(STATFLAG_FAILURE); | 
 |  | } | 
 |  | ret |= statflag_read(sfh, hdl, sizeof(_HDRVLST)); | 
 |  | } | 
 |  | (void)tbl; | 
 |  | return(ret); | 
 |  | } | 
 |  | #endif | 
 |  |  |