/** * @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; }
/** * @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; }