Beispiel #1
0
/**
 * @brief Creates a directory tree.
 * @param[in] path the native path.
 * @return Zero for success,
 * negative value otherwise.
 */
int winx_create_path(wchar_t *path)
{
    /*wchar_t rootdir[] = L"\\??\\X:\\";*/
    winx_volume_information v;
    wchar_t *p;
    size_t n;
    
    if(path == NULL)
        return (-1);

    /* path must contain at least \??\X: */
    if(wcsstr(path,L"\\??\\") != path || wcschr(path,':') != (path + 5)){
        etrace("native path must be specified");
        return (-1);
    }

    n = wcslen(L"\\??\\X:\\");
    if(wcslen(path) <= n){
        /* check for volume existence */
        /*
        rootdir[4] = path[4];
        // may fail with access denied status
        return winx_create_directory(rootdir);
        */
        return winx_get_volume_information((char)path[4],&v);
    }
    
    /* skip \??\X:\ */
    p = path + n;
    
    /* create directory tree */
    while((p = wcschr(p,'\\'))){
        *p = 0;
        if(winx_create_directory(path) < 0){
            *p = '\\';
            etrace("cannot create %ws",path);
            return (-1);
        }
        *p = '\\';
        p ++;
    }
    
    /* create target directory */
    if(winx_create_directory(path) < 0){
        etrace("cannot create %ws",path);
        return (-1);
    }
    
    return 0;
}
Beispiel #2
0
/**
 * @brief Retrieves all information about the volume.
 * @return Zero for success, negative value otherwise.
 * @note Resets statistics and cluster map.
 */
int get_volume_information(udefrag_job_parameters *jp)
{
    char fs_name[MAX_FS_NAME_LENGTH + 1];
    int i;
    
    /* reset mft zone disposition */
    memset(&jp->mft_zone,0,sizeof(struct _mft_zone));

    /* reset v_info structure */
    memset(&jp->v_info,0,sizeof(winx_volume_information));
    
    /* reset statistics */
    jp->pi.files = 0;
    jp->pi.directories = 0;
    jp->pi.compressed = 0;
    jp->pi.fragmented = 0;
    jp->pi.fragments = 0;
    jp->pi.total_space = 0;
    jp->pi.free_space = 0;
    jp->pi.mft_size = 0;
    jp->pi.clusters_to_process = 0;
    jp->pi.processed_clusters = 0;
    
    jp->fs_type = FS_UNKNOWN;
    jp->is_fat = 0;
    
    /* reset file lists */
    destroy_lists(jp);
    
    /* update global variables holding drive geometry */
    if(winx_get_volume_information(jp->volume_letter,&jp->v_info) < 0)
        return (-1);
    
    /* don't touch dirty volumes */
    if(jp->v_info.is_dirty)
        return UDEFRAG_DIRTY_VOLUME;

    jp->pi.total_space = jp->v_info.total_bytes;
    jp->pi.free_space = jp->v_info.free_bytes;
    itrace("total clusters: %I64u",jp->v_info.total_clusters);
    jp->pi.used_clusters = jp->v_info.total_clusters - (jp->v_info.free_bytes / jp->v_info.bytes_per_cluster);
    itrace("used clusters : %I64u",jp->pi.used_clusters);
    itrace("cluster size: %I64u",jp->v_info.bytes_per_cluster);
    /* validate geometry */
    if(!jp->v_info.total_clusters || !jp->v_info.bytes_per_cluster){
        etrace("wrong volume geometry detected");
        return (-1);
    }
    adjust_move_at_once_parameter(jp);
    /* check partition type */
    itrace("%s partition detected",jp->v_info.fs_name);
    strncpy(fs_name,jp->v_info.fs_name,MAX_FS_NAME_LENGTH);
    fs_name[MAX_FS_NAME_LENGTH] = 0;
    _strupr(fs_name);
    for(i = 0; fs_types[i].name; i++){
        if(!strcmp(fs_name,fs_types[i].name)){
            jp->fs_type = fs_types[i].type;
            jp->is_fat = fs_types[i].is_fat;
            break;
        }
    }
    if(jp->fs_type == FS_UNKNOWN){
        etrace("file system type is not recognized");
        etrace("type independent routines will be used to defragment it");
    }
    
    jp->pi.clusters_to_process = jp->v_info.total_clusters;
    jp->pi.processed_clusters = 0;
    
    if(jp->udo.fragment_size_threshold){
        if(jp->udo.fragment_size_threshold <= jp->v_info.bytes_per_cluster){
            itrace("fragment size threshold is below the cluster size, so it will be ignored");
            jp->udo.fragment_size_threshold = 0;
        }
    }

    /* reset cluster map */
    reset_cluster_map(jp);
    return 0;
}