![]() |
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 #ifndef STATIC_LIB 00030 00033 BOOL WINAPI DllMain(HANDLE hinstDLL,DWORD dwReason,LPVOID lpvReserved) 00034 { 00035 if(dwReason == DLL_PROCESS_ATTACH) 00036 InitDriverResources(); 00037 else if(dwReason == DLL_PROCESS_DETACH) 00038 FreeDriverResources(); 00039 return 1; 00040 } 00041 #endif 00042 00048 void __stdcall udefrag_kernel_native_init(void) 00049 { 00050 InitDriverResources(); 00051 } 00052 00058 void __stdcall udefrag_kernel_native_unload(void) 00059 { 00060 FreeDriverResources(); 00061 } 00062 00070 int __stdcall udefrag_kernel_start(char *volume_name, UDEFRAG_JOB_TYPE job_type, int cluster_map_size) 00071 { 00072 char *action = "analyzing"; 00073 LARGE_INTEGER interval; 00074 NTSTATUS Status; 00075 int error_code = 0; 00076 00077 /* 0a. check for synchronization objects */ 00078 if(CheckForSynchObjects() < 0){ 00079 DebugPrint("Synchronization objects aren't available!"); 00080 return (-1); 00081 } 00082 /* 0b. synchronize with other requests */ 00083 interval.QuadPart = (-1); /* 100 nsec */ 00084 Status = NtWaitForSingleObject(hSynchEvent,FALSE,&interval); 00085 if(Status == STATUS_TIMEOUT || !NT_SUCCESS(Status)){ 00086 DebugPrint("Driver is busy because the previous request was not completed!\n"); 00087 return (-1); 00088 } 00089 00090 /* FIXME: stop request will fail when completes before this point :-) */ 00091 (void)NtClearEvent(hStopEvent); 00092 00093 /* 1. print header */ 00094 if(job_type == DEFRAG_JOB) action = "defragmenting"; 00095 if(job_type == OPTIMIZE_JOB) action = "optimizing"; 00096 DebugPrint("Start %s volume %s\n",action,volume_name); 00097 00098 /* reset out_of_memory_condition_counter */ 00099 out_of_memory_condition_counter = 0; 00100 00101 /* 2. allocate cluster map */ 00102 if(AllocateMap(cluster_map_size) < 0){ 00103 DebugPrint("Cannot allocate cluster map!"); 00104 error_code = UDEFRAG_NO_MEM; 00105 goto failure; 00106 } 00107 00108 /* 3. read options from environment variables */ 00109 InitializeOptions(); 00110 00111 /* 4. prepare for job */ 00112 (void)_strupr(volume_name); 00113 volume_letter = volume_name[0]; 00114 RemoveReportFromDisk(volume_name); 00115 if(job_type == OPTIMIZE_JOB) optimize_flag = TRUE; 00116 else optimize_flag = FALSE; 00117 JobType = job_type; 00118 00119 Stat.pass_number = 0; 00120 00121 /* 5. flush all file buffers */ 00122 /*DebugPrint("Flush all file buffers!\n"); 00123 FlushAllFileBuffers(volume_name);*/ 00124 00125 /* 6. analyse volume */ 00126 initial_analysis = TRUE; 00127 error_code = Analyze(volume_name); 00128 initial_analysis = FALSE; 00129 if(error_code < 0) goto failure; 00130 00131 /* 7. defragment/optimize volume */ 00132 if(job_type == ANALYSE_JOB) goto success; 00133 if(CheckForStopEvent()) goto success; 00134 /* 00135 * NTFS volumes with cluster size greater than 4 kb 00136 * cannot be defragmented on Windows 2000. 00137 * This is a well known limitation of Windows Defrag API. 00138 */ 00139 if(partition_type == NTFS_PARTITION && bytes_per_cluster > 4096 && w2k_system){ 00140 DebugPrint("Cannot defragment NTFS volumes with\n" 00141 "cluster size greater than 4 kb\n" 00142 "on Windows 2000 (read docs for details)."); 00143 error_code = UDEFRAG_W2K_4KB_CLUSTERS; 00144 goto failure; 00145 } 00146 if(job_type == DEFRAG_JOB) (void)Defragment(volume_name); 00147 else (void)Optimize(volume_name); 00148 00149 success: 00150 /* 8. save report */ 00151 (void)SaveReportToDisk(volume_name); 00152 00153 /* FreeMap(); - NEVER CALL IT HERE */ 00154 00155 DestroyLists(); 00156 CloseVolume(); 00157 Stat.pass_number = 0xffffffff; 00158 (void)NtSetEvent(hSynchEvent,NULL); 00159 (void)NtClearEvent(hStopEvent); 00160 if(out_of_memory_condition_counter){ 00161 DebugPrint("The out of memory condition has been occured %I64u times.\n", 00162 out_of_memory_condition_counter); 00163 DebugPrint("Therefore the disk defragmentation may be incomplete.\n"); 00164 } 00165 return 0; 00166 00167 failure: 00168 DestroyLists(); 00169 CloseVolume(); 00170 Stat.pass_number = 0xffffffff; 00171 (void)NtSetEvent(hSynchEvent,NULL); 00172 (void)NtClearEvent(hStopEvent); 00173 if(out_of_memory_condition_counter){ 00174 DebugPrint("The out of memory condition has been occured %I64u times.\n", 00175 out_of_memory_condition_counter); 00176 DebugPrint("Therefore the disk defragmentation may be incomplete.\n"); 00177 } 00178 return error_code; 00179 } 00180 00185 int __stdcall udefrag_kernel_stop(void) 00186 { 00187 DebugPrint("Stop\n"); 00188 if(CheckForSynchObjects() < 0){ 00189 DebugPrint("Synchronization objects aren't available!"); 00190 return (-1); 00191 } 00192 (void)NtSetEvent(hStopEvent,NULL); 00193 return 0; 00194 } 00195 00206 int __stdcall udefrag_kernel_get_statistic(STATISTIC *stat, char *map, int map_size) 00207 { 00208 DebugPrint2("Get Statistic\n"); 00209 if(stat) memcpy(stat,&Stat,sizeof(STATISTIC)); 00210 if(map){ 00211 if(GetMap(map,map_size) < 0) return (-1); 00212 } 00213 return 0; 00214 } 00215