![]() |
UltraDefrag Engine Architecture - Reference Manual - Guides |
|
00001 /* 00002 * UltraDefrag - powerful defragmentation tool for Windows NT. 00003 * Copyright (c) 2007-2010 by Dmitri Arkhangelski (dmitriar@gmail.com). 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00027 #include "globals.h" 00028 00034 int OpenVolume(char *volume_name) 00035 { 00036 char path[64]; 00037 char flags[2]; 00038 #define FLAG 'r' 00039 00040 CloseVolume(); 00041 (void)_snprintf(path,64,"\\??\\%s:",volume_name); 00042 path[63] = 0; 00043 #if FLAG != 'r' 00044 #error Volume must be opened for read access! 00045 #endif 00046 flags[0] = FLAG; flags[1] = 0; 00047 fVolume = winx_fopen(path,flags); 00048 if(!fVolume){ 00049 DebugPrint("Cannot open volume %s!\n",path); 00050 return (-1); 00051 } 00052 return 0; 00053 } 00054 00059 void FlushAllFileBuffers(char *volume_name) 00060 { 00061 char path[64]; 00062 WINX_FILE *f; 00063 00064 (void)_snprintf(path,64,"\\??\\%s:",volume_name); 00065 path[63] = 0; 00066 00067 f = winx_fopen(path,"r+"); 00068 if(f){ 00069 (void)winx_fflush(f); 00070 winx_fclose(f); 00071 } 00072 } 00073 00079 int GetDriveGeometry(char *volume_name) 00080 { 00081 char path[64]; 00082 char flags[2]; 00083 WINX_FILE *fRoot; 00084 #define FLAG 'r' 00085 00086 FILE_FS_SIZE_INFORMATION *pFileFsSize; 00087 IO_STATUS_BLOCK iosb; 00088 NTSTATUS status; 00089 ULONGLONG bpc; /* bytes per cluster */ 00090 00091 /* reset geometry related variables */ 00092 bytes_per_cluster = 0; 00093 bytes_per_sector = 0; 00094 sectors_per_cluster = 0; 00095 Stat.total_space = 0; 00096 Stat.free_space = 0; 00097 clusters_total = 0; 00098 clusters_per_256k = 0; 00099 00100 /* get drive geometry */ 00101 (void)_snprintf(path,64,"\\??\\%s:\\",volume_name); 00102 path[63] = 0; 00103 #if FLAG != 'r' 00104 #error Root directory must be opened for read access! 00105 #endif 00106 flags[0] = FLAG; flags[1] = 0; 00107 fRoot = winx_fopen(path,flags); 00108 if(!fRoot){ 00109 DebugPrint("Cannot open the root directory %s!\n",path); 00110 return (-1); 00111 } 00112 00113 pFileFsSize = winx_heap_alloc(sizeof(FILE_FS_SIZE_INFORMATION)); 00114 if(!pFileFsSize){ 00115 winx_fclose(fRoot); 00116 DebugPrint("udefrag-kernel.dll GetDriveGeometry(): no enough memory!"); 00117 out_of_memory_condition_counter ++; 00118 return UDEFRAG_NO_MEM; 00119 } 00120 00121 /* get logical geometry */ 00122 RtlZeroMemory(pFileFsSize,sizeof(FILE_FS_SIZE_INFORMATION)); 00123 status = NtQueryVolumeInformationFile(winx_fileno(fRoot),&iosb,pFileFsSize, 00124 sizeof(FILE_FS_SIZE_INFORMATION),FileFsSizeInformation); 00125 winx_fclose(fRoot); 00126 if(status != STATUS_SUCCESS){ 00127 winx_heap_free(pFileFsSize); 00128 DebugPrintEx(status,"FileFsSizeInformation() request failed for %s",path); 00129 return (-1); 00130 } 00131 00132 bpc = pFileFsSize->SectorsPerAllocationUnit * pFileFsSize->BytesPerSector; 00133 sectors_per_cluster = pFileFsSize->SectorsPerAllocationUnit; 00134 bytes_per_cluster = bpc; 00135 bytes_per_sector = pFileFsSize->BytesPerSector; 00136 Stat.total_space = pFileFsSize->TotalAllocationUnits.QuadPart * bpc; 00137 Stat.free_space = pFileFsSize->AvailableAllocationUnits.QuadPart * bpc; 00138 clusters_total = (ULONGLONG)(pFileFsSize->TotalAllocationUnits.QuadPart); 00139 if(bytes_per_cluster) clusters_per_256k = _256K / bytes_per_cluster; 00140 DebugPrint("Total clusters: %I64u\n",clusters_total); 00141 DebugPrint("Cluster size: %I64u\n",bytes_per_cluster); 00142 if(!clusters_per_256k){ 00143 DebugPrint("Clusters are larger than 256 kbytes!\n"); 00144 clusters_per_256k ++; 00145 } 00146 00147 /* validate geometry */ 00148 if(!clusters_total || !bytes_per_cluster){ 00149 winx_heap_free(pFileFsSize); 00150 DebugPrint("Wrong volume geometry!"); 00151 return (-1); 00152 } 00153 winx_heap_free(pFileFsSize); 00154 return 0; 00155 } 00156 00160 void CloseVolume(void) 00161 { 00162 winx_fclose(fVolume); 00163 fVolume = NULL; 00164 } 00165