/* delete the disk device for a given drive */ static void delete_dos_device( struct dos_drive *drive ) { list_remove( &drive->entry ); if (drive->mount) delete_mount_point( drive->mount ); release_volume( drive->volume ); RtlFreeHeap( GetProcessHeap(), 0, drive ); }
/* create a new disk volume */ NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point, enum device_type type, const GUID *guid ) { struct volume *volume; NTSTATUS status = STATUS_SUCCESS; TRACE( "adding %s device %s mount %s type %u uuid %s\n", debugstr_a(udi), debugstr_a(device), debugstr_a(mount_point), type, debugstr_guid(guid) ); EnterCriticalSection( &device_section ); LIST_FOR_EACH_ENTRY( volume, &volumes_list, struct volume, entry ) if (volume->udi && !strcmp( udi, volume->udi )) { grab_volume( volume ); goto found; } /* udi not found, search for a non-dynamic volume */ if ((volume = find_matching_volume( udi, device, mount_point, type ))) set_volume_udi( volume, udi ); else status = create_volume( udi, type, &volume ); found: if (!status) status = set_volume_info( volume, NULL, device, mount_point, type, guid ); if (volume) release_volume( volume ); LeaveCriticalSection( &device_section ); return status; }
bool DCR::do_unload() { if (dev->must_unload()) { Dmsg1(100, "must_unload release %s\n", dev->print_name()); release_volume(); } return false; }
/* create devices for mapped drives */ static void create_drive_devices(void) { char *path, *p, *link, *device; struct dos_drive *drive; struct volume *volume; unsigned int i; HKEY drives_key; enum device_type drive_type; WCHAR driveW[] = {'a',':',0}; if (!(path = get_dosdevices_path( &p ))) return; if (RegOpenKeyW( HKEY_LOCAL_MACHINE, drives_keyW, &drives_key )) drives_key = 0; for (i = 0; i < MAX_DOS_DRIVES; i++) { p[0] = 'a' + i; p[2] = 0; if (!(link = read_symlink( path ))) continue; p[2] = ':'; device = read_symlink( path ); drive_type = i < 2 ? DEVICE_FLOPPY : DEVICE_HARDDISK_VOL; if (drives_key) { WCHAR buffer[32]; DWORD j, type, size = sizeof(buffer); driveW[0] = 'a' + i; if (!RegQueryValueExW( drives_key, driveW, NULL, &type, (BYTE *)buffer, &size ) && type == REG_SZ) { for (j = 0; j < sizeof(drive_types)/sizeof(drive_types[0]); j++) if (drive_types[j][0] && !strcmpiW( buffer, drive_types[j] )) { drive_type = j; break; } if (drive_type == DEVICE_FLOPPY && i >= 2) drive_type = DEVICE_HARDDISK; } } volume = find_matching_volume( NULL, device, link, drive_type ); if (!create_dos_device( volume, NULL, i, drive_type, &drive )) { /* don't reset uuid if we used an existing volume */ const GUID *guid = volume ? NULL : get_default_uuid(i); set_volume_info( drive->volume, drive, device, link, drive_type, guid ); } else { RtlFreeHeap( GetProcessHeap(), 0, link ); RtlFreeHeap( GetProcessHeap(), 0, device ); } if (volume) release_volume( volume ); } RegCloseKey( drives_key ); RtlFreeHeap( GetProcessHeap(), 0, path ); }
/* set the volume udi */ static void set_volume_udi( struct volume *volume, const char *udi ) { if (udi) { assert( !volume->udi ); /* having a udi means the HAL side holds an extra reference */ if ((volume->udi = strdupA( udi ))) grab_volume( volume ); } else if (volume->udi) { RtlFreeHeap( GetProcessHeap(), 0, volume->udi ); volume->udi = NULL; release_volume( volume ); } }
/* change the drive letter or volume for an existing drive */ static void set_drive_info( struct dos_drive *drive, int letter, struct volume *volume ) { if (drive->drive != letter) { if (drive->mount) delete_mount_point( drive->mount ); drive->mount = NULL; drive->drive = letter; } if (drive->volume != volume) { if (drive->mount) delete_mount_point( drive->mount ); drive->mount = NULL; grab_volume( volume ); release_volume( drive->volume ); drive->volume = volume; } }
/* * Insanity check * * Check to see if the tape position as defined by the OS is * the same as our concept. If it is not, * it means the user has probably manually rewound the tape. * Note, we check only if num_writers == 0, but this code will * also work fine for any number of writers. If num_writers > 0, * we probably should cancel all jobs using this device, or * perhaps even abort the SD, or at a minimum, mark the tape * in error. Another strategy with num_writers == 0, would be * to rewind the tape and do a new eod() request. */ bool DCR::is_tape_position_ok() { if (dev->is_tape() && dev->num_writers == 0) { int32_t file = dev->get_os_tape_file(); if (file >= 0 && file != (int32_t)dev->get_file()) { Jmsg(jcr, M_ERROR, 0, _("Invalid tape position on volume \"%s\"" " on device %s. Expected %d, got %d\n"), dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file); /* * If the current file is greater than zero, it means we probably * have some bad count of EOF marks, so mark tape in error. Otherwise * the operator might have moved the tape, so we just release it * and try again. */ if (file > 0) { mark_volume_in_error(); } release_volume(); return false; } } return true; }