/** * @brief Defines how many clusters to move at once in the move_file routine. * @details This algorithm has been suggested by Joachim Otahal: * http://sourceforge.net/projects/ultradefrag/forums/forum/709672/topic/4779581 */ void adjust_move_at_once_parameter(udefrag_job_parameters *jp) { ULONGLONG bytes_at_once; char buffer[32]; /* comply with "one half second to stop defragmentation" rule */ if(jp->v_info.device_capacity < _20G){ bytes_at_once = _256K; } else if(jp->v_info.device_capacity < _100G){ bytes_at_once = _4M; } else if(jp->v_info.device_capacity < _250G){ bytes_at_once = _8M; } else if(jp->v_info.device_capacity < _1T){ bytes_at_once = _16M; } else if(jp->v_info.device_capacity < _2T){ bytes_at_once = _32M; } else { bytes_at_once = _64M; } jp->clusters_at_once = bytes_at_once / jp->v_info.bytes_per_cluster; if(jp->clusters_at_once == 0) jp->clusters_at_once ++; winx_bytes_to_hr(bytes_at_once,0,buffer,sizeof(buffer)); itrace("the program will move %s (%I64u clusters) at once", buffer, jp->clusters_at_once); }
/** * @brief Retrieves free space layout. * @return Zero for success, negative value otherwise. */ static int get_free_space_layout(udefrag_job_parameters *jp) { char buffer[32]; jp->free_regions = winx_get_free_volume_regions(jp->volume_letter, WINX_GVR_ALLOW_PARTIAL_SCAN,process_free_region,(void *)jp); winx_bytes_to_hr(jp->v_info.free_bytes,2,buffer,sizeof(buffer)); itrace("free space amount : %s",buffer); itrace("free regions count: %u",jp->free_regions_count); /* let full disks to pass the analysis successfully */ if(jp->free_regions == NULL || jp->free_regions_count == 0) etrace("disk is full or some error has been encountered"); return 0; }
/** * @internal * @brief Retrieves the drive geometry. * @param[in] hRoot handle to the * root directory. * @param[out] pointer to the structure * receiving the drive geometry. * @return Zero for success, negative * value otherwise. */ static int get_drive_geometry(HANDLE hRoot,winx_volume_information *v) { FILE_FS_SIZE_INFORMATION ffs; IO_STATUS_BLOCK IoStatusBlock; NTSTATUS status; WINX_FILE *f; DISK_GEOMETRY dg; char buffer[32]; /* get drive geometry */ RtlZeroMemory(&ffs,sizeof(FILE_FS_SIZE_INFORMATION)); status = NtQueryVolumeInformationFile(hRoot,&IoStatusBlock,&ffs, sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation); if(!NT_SUCCESS(status)){ strace(status,"cannot get geometry of drive %c:",v->volume_letter); return (-1); } /* fill all geometry related fields of the output structure */ v->total_bytes = (ULONGLONG)ffs.TotalAllocationUnits.QuadPart * \ ffs.SectorsPerAllocationUnit * ffs.BytesPerSector; v->free_bytes = (ULONGLONG)ffs.AvailableAllocationUnits.QuadPart * \ ffs.SectorsPerAllocationUnit * ffs.BytesPerSector; v->total_clusters = (ULONGLONG)ffs.TotalAllocationUnits.QuadPart; v->bytes_per_cluster = ffs.SectorsPerAllocationUnit * ffs.BytesPerSector; v->sectors_per_cluster = ffs.SectorsPerAllocationUnit; v->bytes_per_sector = ffs.BytesPerSector; /* optional: get device capacity */ v->device_capacity = 0; f = winx_vopen(v->volume_letter); if(f != NULL){ if(winx_ioctl(f,IOCTL_DISK_GET_DRIVE_GEOMETRY, "get_drive_geometry: device geometry request",NULL,0, &dg,sizeof(dg),NULL) >= 0){ v->device_capacity = dg.Cylinders.QuadPart * \ dg.TracksPerCylinder * dg.SectorsPerTrack * dg.BytesPerSector; winx_bytes_to_hr(v->device_capacity,1,buffer,sizeof(buffer)); itrace("%c: device capacity = %s",v->volume_letter,buffer); } winx_fclose(f); } return 0; }