📄 win32.c
字号:
{ p_env->access_mode = str_to_access_mode_win32(value); if (p_env->access_mode == _AM_ASPI && !p_env->b_aspi_init) return init_aspi(p_env) ? 1 : -3; else if (p_env->access_mode == _AM_IOCTL && !p_env->b_ioctl_init) return init_win32ioctl(p_env) ? 1 : -3; else return -4; return 0; } else return -1; return 0;}/*! Read and cache the CD's Track Table of Contents and track info. Return true if successful or false if an error.*/static boolread_toc_win32 (void *p_user_data) { _img_private_t *p_env = p_user_data; bool ret; if( p_env->hASPI ) { ret = read_toc_aspi( p_env ); } else { ret = read_toc_win32ioctl( p_env ); } if (ret) p_env->gen.toc_init = true ; return true;}/*! Eject media. Return 1 if successful, 0 otherwise. */static int _cdio_eject_media (void *user_data) {#ifdef _XBOX return -1;#else _img_private_t *env = user_data; MCI_OPEN_PARMS op; MCI_STATUS_PARMS st; DWORD i_flags; char psz_drive[4]; int ret; memset( &op, 0, sizeof(MCI_OPEN_PARMS) ); op.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_CD_AUDIO; strcpy( psz_drive, "X:" ); psz_drive[0] = env->gen.source_name[0]; op.lpstrElementName = psz_drive; /* Set the flags for the device type */ i_flags = MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT | MCI_OPEN_SHAREABLE; if( _cdio_mciSendCommand( 0, MCI_OPEN, i_flags, &op ) ) { st.dwItem = MCI_STATUS_READY; /* Eject disc */ ret = _cdio_mciSendCommand( op.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0 ) != 0; /* Release access to the device */ _cdio_mciSendCommand( op.wDeviceID, MCI_CLOSE, MCI_WAIT, 0 ); } else ret = 0; return ret;#endif}/*! Return the value associated with the key "arg".*/static const char *_get_arg_win32 (void *user_data, const char key[]){ _img_private_t *env = user_data; if (!strcmp (key, "source")) { return env->gen.source_name; } else if (!strcmp (key, "access-mode")) { if (env->hASPI) return "ASPI"; else return "ioctl"; } return NULL;}/*! Return the media catalog number MCN. Note: string is malloc'd so caller should free() then returned string when done with it. */static char *_cdio_get_mcn (const void *p_user_data) { const _img_private_t *p_env = p_user_data; if( p_env->hASPI ) { return scsi_mmc_get_mcn( p_env->gen.cdio ); } else { return get_mcn_win32ioctl(p_env); }}/*! Get format of track. */static track_format_t_cdio_get_track_format(void *p_obj, track_t i_track) { _img_private_t *p_env = p_obj; if ( !p_env ) return TRACK_FORMAT_ERROR; if (!p_env->gen.toc_init) read_toc_win32 (p_env) ; if ( i_track < p_env->gen.i_first_track || i_track >= p_env->gen.i_tracks + p_env->gen.i_first_track ) return TRACK_FORMAT_ERROR; if( p_env->hASPI ) { return get_track_format_aspi(p_env, i_track); } else { return get_track_format_win32ioctl(p_env, i_track); }}/*! Return true if we have XA data (green, mode2 form1) or XA data (green, mode2 form2). That is track begins: sync - header - subheader 12 4 - 8 FIXME: there's gotta be a better design for this and get_track_format?*/static bool_cdio_get_track_green(void *obj, track_t i_track) { _img_private_t *p_env = obj; switch (_cdio_get_track_format(p_env, i_track)) { case TRACK_FORMAT_XA: return true; case TRACK_FORMAT_ERROR: case TRACK_FORMAT_CDI: case TRACK_FORMAT_AUDIO: return false; case TRACK_FORMAT_DATA: if (_AM_ASPI == p_env->access_mode ) return ((p_env->tocent[i_track-p_env->gen.i_first_track].Control & 8) != 0); default: break; } /* FIXME: Dunno if this is the right way, but it's what I was using in cd-info for a while. */ return ((p_env->tocent[i_track-p_env->gen.i_first_track].Control & 2) != 0);}/*! Return the starting MSF (minutes/secs/frames) for track number i_tracks in obj. Track numbers start at 1. The "leadout" track is specified either by using i_tracks LEADOUT_TRACK or the total tracks+1. False is returned if there is no track entry.*/static bool_cdio_get_track_msf(void *p_user_data, track_t i_tracks, msf_t *msf){ _img_private_t *p_env = p_user_data; if (NULL == msf) return false; if (!p_env->gen.toc_init) read_toc_win32 (p_env) ; if (i_tracks == CDIO_CDROM_LEADOUT_TRACK) i_tracks = p_env->gen.i_tracks+1; if (i_tracks > p_env->gen.i_tracks+1 || i_tracks == 0) { return false; } else { cdio_lsn_to_msf(p_env->tocent[i_tracks-1].start_lsn, msf); return true; }}#endif /* HAVE_WIN32_CDROM *//*! Return an array of strings giving possible CD devices. */char **cdio_get_devices_win32 (void){#ifndef HAVE_WIN32_CDROM return NULL;#else char **drives = NULL; unsigned int num_drives=0; char drive_letter; /* Scan the system for CD-ROM drives. */#if FINISHED /* Now check the currently mounted CD drives */ if (NULL != (ret_drive = cdio_check_mounts("/etc/mtab"))) { cdio_add_device_list(&drives, drive, &num_drives); } /* Finally check possible mountable drives in /etc/fstab */ if (NULL != (ret_drive = cdio_check_mounts("/etc/fstab"))) { cdio_add_device_list(&drives, drive, &num_drives); }#endif /* Scan the system for CD-ROM drives. Not always 100% reliable, so use the USE_MNTENT code above first. */ for (drive_letter='A'; drive_letter <= 'Z'; drive_letter++) { const char *drive_str=is_cdrom_win32(drive_letter); if (drive_str != NULL) { cdio_add_device_list(&drives, drive_str, &num_drives); } } cdio_add_device_list(&drives, NULL, &num_drives); return drives;#endif /*HAVE_WIN32_CDROM*/}/*! Return a string containing the default CD device if none is specified. if CdIo is NULL (we haven't initialized a specific device driver), then find a suitable one and return the default device for that. NULL is returned if we couldn't get a default device.*/char *cdio_get_default_device_win32(void){#ifdef HAVE_WIN32_CDROM char drive_letter; for (drive_letter='A'; drive_letter <= 'Z'; drive_letter++) { const char *drive_str=is_cdrom_win32(drive_letter); if (drive_str != NULL) { return strdup(drive_str); } }#endif return NULL;}/*! Return true if source_name could be a device containing a CD-ROM.*/boolcdio_is_device_win32(const char *source_name){ unsigned int len; if (NULL == source_name) return false; len = strlen(source_name);#ifdef HAVE_WIN32_CDROM if ((len == 2) && isalpha(source_name[0]) && (source_name[len-1] == ':')) return true; if ( ! WIN_NT ) return false; /* Test to see if of form: \\.\x: */ return ( (len == 6) && source_name[0] == '\\' && source_name[1] == '\\' && source_name[2] == '.' && source_name[3] == '\\' && isalpha(source_name[len-2]) && (source_name[len-1] == ':') );#else return false;#endif}/*! Initialization routine. This is the only thing that doesn't get called via a function pointer. In fact *we* are the ones to set that up. */CdIo *cdio_open_win32 (const char *psz_source_name){#ifdef HAVE_WIN32_CDROM if ( WIN_NT ) { return cdio_open_am_win32(psz_source_name, "ioctl"); } else { return cdio_open_am_win32(psz_source_name, "ASPI"); }#else return NULL;#endif /* HAVE_WIN32_CDROM */}/*! Initialization routine. This is the only thing that doesn't get called via a function pointer. In fact *we* are the ones to set that up. */CdIo *cdio_open_am_win32 (const char *psz_orig_source, const char *psz_access_mode){#ifdef HAVE_WIN32_CDROM CdIo *ret; _img_private_t *_data; char *psz_source; cdio_funcs _funcs; memset( &_funcs, 0, sizeof(_funcs) ); _funcs.eject_media = _cdio_eject_media; _funcs.free = _free_win32; _funcs.get_arg = _get_arg_win32; _funcs.get_cdtext = get_cdtext_generic; _funcs.get_default_device = cdio_get_default_device_win32; _funcs.get_devices = cdio_get_devices_win32; _funcs.get_discmode = get_discmode_win32; _funcs.get_drive_cap = scsi_mmc_get_drive_cap_generic; _funcs.get_first_track_num= get_first_track_num_generic; _funcs.get_hwinfo = NULL; _funcs.get_mcn = _cdio_get_mcn; _funcs.get_num_tracks = get_num_tracks_generic; _funcs.get_track_format = _cdio_get_track_format; _funcs.get_track_green = _cdio_get_track_green; _funcs.get_track_lba = NULL; /* This could be implemented if need be. */ _funcs.get_track_msf = _cdio_get_track_msf; _funcs.lseek = NULL; _funcs.read = NULL; _funcs.read_audio_sectors = _cdio_read_audio_sectors; _funcs.read_mode1_sector = _cdio_read_mode1_sector; _funcs.read_mode1_sectors = _cdio_read_mode1_sectors; _funcs.read_mode2_sector = _cdio_read_mode2_sector; _funcs.read_mode2_sectors = _cdio_read_mode2_sectors; _funcs.read_toc = &read_toc_win32; _funcs.run_scsi_mmc_cmd = &run_scsi_cmd_win32; _funcs.set_arg = set_arg_win32; _funcs.stat_size = stat_size_win32; _data = _cdio_malloc (sizeof (_img_private_t)); _data->access_mode = str_to_access_mode_win32(psz_access_mode); _data->gen.init = false; _data->gen.fd = -1; if (NULL == psz_orig_source) { psz_source=cdio_get_default_device_win32(); if (NULL == psz_source) return NULL; set_arg_win32(_data, "source", psz_source); free(psz_source); } else { if (cdio_is_device_win32(psz_orig_source)) set_arg_win32(_data, "source", psz_orig_source); else { /* The below would be okay if all device drivers worked this way. */#if 0 cdio_info ("source %s is a not a device", psz_orig_source);#endif return NULL; } } ret = cdio_new ((void *)_data, &_funcs); if (ret == NULL) return NULL; if (_cdio_init_win32(_data)) return ret; else { _free_win32 (_data); return NULL; } #else return NULL;#endif /* HAVE_WIN32_CDROM */}boolcdio_have_win32 (void){#ifdef HAVE_WIN32_CDROM return true;#else return false;#endif /* HAVE_WIN32_CDROM */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -