![]() |
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 00029 /* 00030 * Micro Edition generates text reports only, 00031 * all other editions - both reports. 00032 */ 00033 00034 /* function prototypes */ 00035 static void RemoveLuaReportFromDisk(char *volume_name); 00036 static void RemoveTextReportFromDisk(char *volume_name); 00037 static void RemoveHtmlReportFromDisk(char *volume_name); 00038 static BOOLEAN SaveLuaReportToDisk(char *volume_name); 00039 static void WriteLuaReportBody(WINX_FILE *f,BOOLEAN is_filtered); 00040 static BOOLEAN SaveTextReportToDisk(char *volume_name); 00041 static void WriteTextReportBody(WINX_FILE *f,BOOLEAN is_filtered); 00042 00043 static BOOLEAN SaveReportToDiskInternal(char *volume_name); 00044 00045 static int InitializeReportSavingBuffer(void); 00046 static void DestroyReportSavingBuffer(void); 00047 static size_t WriteToReportSavingBuffer(const void *buffer,size_t size,size_t count,WINX_FILE *f); 00048 00053 void RemoveReportFromDisk(char *volume_name) 00054 { 00055 RemoveTextReportFromDisk(volume_name); 00056 RemoveLuaReportFromDisk(volume_name); 00057 RemoveHtmlReportFromDisk(volume_name); 00058 } 00059 00060 static void RemoveLuaReportFromDisk(char *volume_name) 00061 { 00062 char path[64]; 00063 00064 (void)_snprintf(path,64,"\\??\\%s:\\fraglist.luar",volume_name); 00065 path[63] = 0; 00066 (void)winx_delete_file(path); 00067 } 00068 00069 static void RemoveTextReportFromDisk(char *volume_name) 00070 { 00071 char path[64]; 00072 00073 (void)_snprintf(path,64,"\\??\\%s:\\fraglist.txt",volume_name); 00074 path[63] = 0; 00075 (void)winx_delete_file(path); 00076 } 00077 00078 static void RemoveHtmlReportFromDisk(char *volume_name) 00079 { 00080 char path[64]; 00081 00082 (void)_snprintf(path,64,"\\??\\%s:\\fraglist.htm",volume_name); 00083 path[63] = 0; 00084 (void)winx_delete_file(path); 00085 00086 (void)_snprintf(path,64,"\\??\\%s:\\fraglist.html",volume_name); 00087 path[63] = 0; 00088 (void)winx_delete_file(path); 00089 } 00090 00095 BOOLEAN SaveReportToDisk(char *volume_name) 00096 { 00097 ULONGLONG tm, time; 00098 BOOLEAN result; 00099 00100 DebugPrint("SaveReportToDisk() started...\n"); 00101 tm = _rdtsc(); 00102 00103 result = SaveReportToDiskInternal(volume_name); 00104 00105 time = _rdtsc() - tm; 00106 DebugPrint("SaveReportToDisk() completed in %I64u ms.\n",time); 00107 return result; 00108 } 00109 00110 static BOOLEAN SaveReportToDiskInternal(char *volume_name) 00111 { 00112 if(!SaveTextReportToDisk(volume_name)) return FALSE; 00113 #ifdef MICRO_EDITION 00114 return TRUE; 00115 #else 00116 return SaveLuaReportToDisk(volume_name); 00117 #endif 00118 } 00119 00120 #ifndef MICRO_EDITION 00121 00126 static BOOLEAN SaveLuaReportToDisk(char *volume_name) 00127 { 00128 char buffer[512]; 00129 char path[64]; 00130 WINX_FILE *f; 00131 00132 if(disable_reports) return TRUE; 00133 00134 (void)_snprintf(path,64,"\\??\\%s:\\fraglist.luar",volume_name); 00135 path[63] = 0; 00136 f = winx_fopen(path,"w"); 00137 if(f == NULL){ 00138 DebugPrint("Cannot create %s file!\n",path); 00139 return FALSE; 00140 } 00141 00142 InitializeReportSavingBuffer(); 00143 00144 (void)_snprintf(buffer,sizeof(buffer), 00145 "-- UltraDefrag report for volume %s:\r\n\r\n" 00146 "format_version = 2\r\n\r\n" 00147 "volume_letter = \"%s\"\r\n\r\n" 00148 "files = {\r\n", 00149 volume_name, volume_name 00150 ); 00151 buffer[sizeof(buffer) - 1] = 0; /* to be sure that the buffer is terminated by zero */ 00152 (void)WriteToReportSavingBuffer(buffer,1,strlen(buffer),f); 00153 00154 WriteLuaReportBody(f,FALSE); 00155 //WriteLuaReportBody(f,TRUE); 00156 00157 (void)strcpy(buffer,"}\r\n"); 00158 (void)WriteToReportSavingBuffer(buffer,1,strlen(buffer),f); 00159 00160 DestroyReportSavingBuffer(); 00161 00162 winx_fclose(f); 00163 00164 DebugPrint("Report saved to %s\n",path); 00165 return TRUE; 00166 } 00167 00168 static void WriteLuaReportBody(WINX_FILE *f,BOOLEAN is_filtered) 00169 { 00170 char buffer[256]; 00171 PFRAGMENTED pf; 00172 char *comment; 00173 int i, offset, name_length; 00174 00175 pf = fragmfileslist; if(!pf) return; 00176 do { 00177 if(pf->pfn->is_filtered != is_filtered) 00178 goto next_item; 00179 if(pf->pfn->is_dir) comment = "[DIR]"; 00180 else if(pf->pfn->is_overlimit) comment = "[OVR]"; 00181 else if(pf->pfn->is_compressed) comment = "[CMP]"; 00182 else comment = " - "; 00183 (void)_snprintf(buffer, sizeof(buffer), 00184 "\t{fragments = %u,size = %I64u,filtered = %u," 00185 "comment = \"%s\",uname = {", 00186 (UINT)pf->pfn->n_fragments, 00187 pf->pfn->clusters_total * bytes_per_cluster, 00188 (UINT)(pf->pfn->is_filtered & 0x1), 00189 comment 00190 ); 00191 buffer[sizeof(buffer) - 1] = 0; /* to be sure that the buffer is terminated by zero */ 00192 (void)WriteToReportSavingBuffer(buffer,1,strlen(buffer),f); 00193 00194 /* skip \??\ sequence in the beginning of the path */ 00195 name_length = pf->pfn->name.Length / sizeof(short); 00196 if(name_length > 4) offset = 4; else offset = 0; 00197 00198 for(i = offset; i < name_length; i++){ 00199 (void)_snprintf(buffer,sizeof(buffer),"%u,",(unsigned int)pf->pfn->name.Buffer[i]); 00200 buffer[sizeof(buffer) - 1] = 0; /* to be sure that the buffer is terminated by zero */ 00201 (void)WriteToReportSavingBuffer(buffer,1,strlen(buffer),f); 00202 } 00203 00204 (void)strcpy(buffer,"}},\r\n"); 00205 (void)WriteToReportSavingBuffer(buffer,1,strlen(buffer),f); 00206 next_item: 00207 pf = pf->next_ptr; 00208 } while(pf != fragmfileslist); 00209 } 00210 00211 #endif /* MICRO_EDITION */ 00212 00217 static BOOLEAN SaveTextReportToDisk(char *volume_name) 00218 { 00219 char path[64]; 00220 WINX_FILE *f; 00221 short buffer[256]; 00222 int length = sizeof(buffer) / sizeof(short); 00223 00224 if(disable_reports) return TRUE; 00225 00226 (void)_snprintf(path,64,"\\??\\%s:\\fraglist.txt",volume_name); 00227 path[63] = 0; 00228 f = winx_fopen(path,"w"); 00229 if(f == NULL){ 00230 DebugPrint("Cannot create %s file!\n",path); 00231 return FALSE; 00232 } 00233 00234 InitializeReportSavingBuffer(); 00235 00236 wcscpy(buffer,L";---------------------------------------------------------------------------------------------\r\n"); 00237 (void)WriteToReportSavingBuffer(buffer,sizeof(short),wcslen(buffer),f); 00238 00239 (void)_snwprintf(buffer,length,L"; Fragmented files on %hs:\r\n;\r\n",volume_name); 00240 buffer[length - 1] = 0; 00241 (void)WriteToReportSavingBuffer(buffer,sizeof(short),wcslen(buffer),f); 00242 00243 (void)_snwprintf(buffer,length,L"; Fragments%21hs%9hs Filename\r\n","Filesize","Comment"); 00244 buffer[length - 1] = 0; 00245 (void)WriteToReportSavingBuffer(buffer,sizeof(short),wcslen(buffer),f); 00246 00247 wcscpy(buffer,L";---------------------------------------------------------------------------------------------\r\n"); 00248 (void)WriteToReportSavingBuffer(buffer,sizeof(short),wcslen(buffer),f); 00249 00250 WriteTextReportBody(f,FALSE); 00251 //WriteTextReportBody(f,TRUE); 00252 00253 DestroyReportSavingBuffer(); 00254 00255 winx_fclose(f); 00256 00257 DebugPrint("Report saved to %s\n",path); 00258 return TRUE; 00259 } 00260 00261 static void WriteTextReportBody(WINX_FILE *f,BOOLEAN is_filtered) 00262 { 00263 PFRAGMENTED pf; 00264 short buffer[256]; 00265 int length = sizeof(buffer) / sizeof(short); 00266 char *comment; 00267 int offset; 00268 00269 pf = fragmfileslist; if(!pf) return; 00270 do { 00271 if(pf->pfn->is_filtered != is_filtered) 00272 goto next_item; 00273 if(pf->pfn->is_dir) comment = "[DIR]"; 00274 else if(pf->pfn->is_overlimit) comment = "[OVR]"; 00275 else if(pf->pfn->is_compressed) comment = "[CMP]"; 00276 else comment = " - "; 00277 00278 (void)_snwprintf(buffer,length,L"\r\n%11u%21I64u%9hs ", 00279 (UINT)pf->pfn->n_fragments, 00280 pf->pfn->clusters_total * bytes_per_cluster, 00281 comment); 00282 buffer[length - 1] = 0; 00283 (void)WriteToReportSavingBuffer(buffer,sizeof(short),wcslen(buffer),f); 00284 00285 /* skip \??\ sequence in the beginning of the path */ 00286 if(pf->pfn->name.Length > 0x8) offset = 0x8; 00287 else offset = 0x0; 00288 (void)WriteToReportSavingBuffer((char *)pf->pfn->name.Buffer + offset,1,pf->pfn->name.Length - offset,f); 00289 00290 next_item: 00291 pf = pf->next_ptr; 00292 } while(pf != fragmfileslist); 00293 } 00294 00295 /* ------------------------------------------------------------------------- */ 00296 /* this code speeds up the report saving */ 00297 /* ------------------------------------------------------------------------- */ 00298 00302 #define RSB_SIZE (512 * 1024) 00303 00307 char *rsb = NULL; 00308 00313 unsigned int offset = 0; 00314 00318 WINX_FILE *f_report = NULL; 00319 00325 static int InitializeReportSavingBuffer(void) 00326 { 00327 rsb = winx_virtual_alloc(RSB_SIZE); 00328 if(!rsb){ 00329 DebugPrint("Cannot allocate %u bytes of memory for the report saving buffer!\n",RSB_SIZE); 00330 DebugPrint("Slower report saving algorithm will be used.\n"); 00331 return (-1); 00332 } 00333 RtlZeroMemory(rsb,RSB_SIZE); 00334 offset = 0; 00335 f_report = NULL; 00336 return 0; 00337 } 00338 00343 static void DestroyReportSavingBuffer(void) 00344 { 00345 if(offset && f_report) winx_fwrite(rsb,1,offset,f_report); 00346 if(rsb) winx_virtual_free(rsb,RSB_SIZE); 00347 offset = 0; 00348 f_report = NULL; 00349 } 00350 00355 static size_t WriteToReportSavingBuffer(const void *buffer,size_t size,size_t count,WINX_FILE *f) 00356 { 00357 size_t bytes; 00358 size_t result; 00359 00360 if(rsb == NULL) return winx_fwrite(buffer,size,count,f); 00361 00362 bytes = size * count; 00363 if(bytes > RSB_SIZE){ 00364 DebugPrint("WriteToReportSavingBuffer(): attempt to write %u bytes failed!\n",(UINT)bytes); 00365 return 0; 00366 } 00367 00368 f_report = f; 00369 result = count; 00370 00371 if(bytes > (RSB_SIZE - offset)){ 00372 winx_fwrite(rsb,1,offset,f); 00373 offset = 0; 00374 } 00375 memcpy(rsb + offset,buffer,bytes); 00376 offset += bytes; 00377 if(offset >= RSB_SIZE){ 00378 result = winx_fwrite(rsb,1,RSB_SIZE,f); 00379 offset = 0; 00380 } 00381 return result; 00382 } 00383