![]() |
udefrag.dll 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 "../../include/ntndk.h" 00028 00029 #include "../../include/udefrag.h" 00030 #include "../zenwinx/zenwinx.h" 00031 00032 #define DbgCheckInitEvent(f) { \ 00033 if(!init_event){ \ 00034 DebugPrint(f " call without initialization!"); \ 00035 return (-1); \ 00036 } \ 00037 } 00038 00039 struct kernel_start_parameters { 00040 char *volume_name; 00041 UDEFRAG_JOB_TYPE job_type; 00042 int cluster_map_size; 00043 int cmd_status; 00044 BOOL done_flag; 00045 }; 00046 00047 /* global variables */ 00048 HANDLE init_event = NULL; 00049 char result_msg[4096]; /* buffer for the default formatted result message */ 00050 extern int refresh_interval; 00051 extern ULONGLONG time_limit; 00052 void udefrag_reload_settings(void); 00053 00054 #ifndef STATIC_LIB 00055 00058 BOOL WINAPI DllMain(HANDLE hinstDLL,DWORD dwReason,LPVOID lpvReserved) 00059 { 00060 return 1; 00061 } 00062 #endif 00063 00071 void __stdcall udefrag_monolithic_native_app_init(void) 00072 { 00073 zenwinx_native_init(); 00074 udefrag_kernel_native_init(); 00075 } 00076 00085 void __stdcall udefrag_monolithic_native_app_unload(void) 00086 { 00087 udefrag_kernel_native_unload(); 00088 zenwinx_native_unload(); 00089 } 00090 00095 int __stdcall udefrag_init(void) 00096 { 00097 int error_code; 00098 00099 /* only a single instance of the program ! */ 00100 error_code = winx_create_event(L"\\udefrag_init",SynchronizationEvent,&init_event); 00101 if(error_code < 0){ 00102 if(error_code == STATUS_OBJECT_NAME_COLLISION) return UDEFRAG_ALREADY_RUNNING; 00103 return (-1); 00104 } 00105 00106 /* enable neccessary privileges */ 00107 /*(void)winx_enable_privilege(SE_MANAGE_VOLUME_PRIVILEGE); */ 00108 (void)winx_enable_privilege(SE_SHUTDOWN_PRIVILEGE); /* required by GUI client */ 00109 return 0; 00110 } 00111 00116 int __stdcall udefrag_unload(void) 00117 { 00118 NtCloseSafe(init_event); 00119 return 0; 00120 } 00121 00129 DWORD WINAPI engine_start(LPVOID p) 00130 { 00131 struct kernel_start_parameters *pksp; 00132 00133 pksp = (struct kernel_start_parameters *)p; 00134 pksp->cmd_status = udefrag_kernel_start(pksp->volume_name,pksp->job_type,pksp->cluster_map_size); 00135 pksp->done_flag = TRUE; 00136 winx_exit_thread(); /* 8k/12k memory leak here? */ 00137 return 0; 00138 } 00139 00152 int __stdcall udefrag_start(char *volume_name, UDEFRAG_JOB_TYPE job_type, int cluster_map_size, STATUPDATEPROC sproc) 00153 { 00154 struct kernel_start_parameters ksp; 00155 ULONGLONG t = 0; 00156 int use_limit = 0; 00157 00158 DbgCheckInitEvent("udefrag_start"); 00159 00160 /* reload time_limit and refresh_interval variables */ 00161 udefrag_reload_settings(); 00162 00163 /* initialize kernel_start_parameters structure */ 00164 ksp.volume_name = volume_name; 00165 ksp.job_type = job_type; 00166 ksp.cluster_map_size = cluster_map_size; 00167 ksp.cmd_status = 0; 00168 ksp.done_flag = FALSE; 00169 00170 /* create a separate thread for the command processing */ 00171 if(winx_create_thread(engine_start,(PVOID)&ksp,NULL) < 0){ 00172 //winx_printf("\nFUCKED!\n\n"); 00173 return (-1); 00174 } 00175 00176 /* 00177 * Call specified callback 00178 * every refresh_interval milliseconds. 00179 */ 00180 if(time_limit){ 00181 use_limit = 1; 00182 t = time_limit * 1000; 00183 } 00184 do { 00185 winx_sleep(refresh_interval); 00186 if(sproc) sproc(FALSE); 00187 if(use_limit){ 00188 if(t <= refresh_interval){ 00189 DebugPrint("Time limit exceeded!\n"); 00190 (void)udefrag_stop(); 00191 } else { 00192 t -= refresh_interval; 00193 } 00194 } 00195 } while(!ksp.done_flag); 00196 if(sproc) sproc(TRUE); 00197 00198 if(ksp.cmd_status < 0) 00199 DebugPrint("udefrag_start(%s,%u,%u,0x%p) failed!\n", 00200 volume_name,job_type,cluster_map_size,sproc); 00201 return ksp.cmd_status; 00202 } 00203 00208 int __stdcall udefrag_stop(void) 00209 { 00210 DbgCheckInitEvent("udefrag_stop"); 00211 if(udefrag_kernel_stop() >= 0) return 0; 00212 DebugPrint("Stop request failed!"); 00213 return (-1); 00214 } 00215 00224 int __stdcall udefrag_get_progress(STATISTIC *pstat, double *percentage) 00225 { 00226 double x, y; 00227 00228 DbgCheckInitEvent("udefrag_get_progress"); 00229 00230 if(udefrag_kernel_get_statistic(pstat,NULL,0) < 0){ 00231 DebugPrint("Statistical data unavailable!"); 00232 return (-1); 00233 } 00234 00235 if(percentage){ /* calculate percentage only if we have such request */ 00236 /* FIXME: do it more accurate */ 00237 x = (double)(LONGLONG)pstat->processed_clusters; 00238 y = (double)(LONGLONG)pstat->clusters_to_process; 00239 if(y == 0) *percentage = 0.00; 00240 else *percentage = (x / y) * 100.00; 00241 } 00242 return 0; 00243 } 00244 00252 int __stdcall udefrag_get_map(char *buffer,int size) 00253 { 00254 DbgCheckInitEvent("udefrag_get_map"); 00255 00256 if(udefrag_kernel_get_statistic(NULL,buffer,(long)size) < 0){ 00257 DebugPrint("Cluster map unavailable!"); 00258 return (-1); 00259 } 00260 return 0; 00261 } 00262 00273 char * __stdcall udefrag_get_default_formatted_results(STATISTIC *pstat) 00274 { 00275 char total_space[68]; 00276 char free_space[68]; 00277 double p; 00278 unsigned int ip; 00279 00280 (void)winx_fbsize(pstat->total_space,2,total_space,sizeof(total_space)); 00281 (void)winx_fbsize(pstat->free_space,2,free_space,sizeof(free_space)); 00282 if(pstat->filecounter == 0) p = 0.00; 00283 else p = (double)(pstat->fragmcounter)/((double)(pstat->filecounter)); 00284 ip = (unsigned int)(p * 100.00); 00285 if(ip < 100) ip = 100; /* fix round off error */ 00286 (void)_snprintf(result_msg,sizeof(result_msg) - 1, 00287 "Volume information:\r\n\r\n" 00288 " Volume size = %s\r\n" 00289 " Free space = %s\r\n\r\n" 00290 " Total number of files = %u\r\n" 00291 " Number of fragmented files = %u\r\n" 00292 " Fragments per file = %u.%02u\r\n\r\n", 00293 total_space, 00294 free_space, 00295 pstat->filecounter, 00296 pstat->fragmfilecounter, 00297 ip / 100, ip % 100 00298 ); 00299 result_msg[sizeof(result_msg) - 1] = 0; 00300 return result_msg; 00301 } 00302 00310 char * __stdcall udefrag_get_error_description(int error_code) 00311 { 00312 switch(error_code){ 00313 case UDEFRAG_UNKNOWN_ERROR: 00314 return "Some unknown internal bug or some\n" 00315 "rarely arising error has been encountered."; 00316 case UDEFRAG_ALREADY_RUNNING: 00317 return "You can run only one instance of UltraDefrag!"; 00318 case UDEFRAG_W2K_4KB_CLUSTERS: 00319 return "NTFS volumes with cluster size greater than 4 kb\n" 00320 "cannot be defragmented on Windows 2000."; 00321 case UDEFRAG_NO_MEM: 00322 return "Not enough memory."; 00323 case UDEFRAG_CDROM: 00324 return "It is impossible to defragment CDROM drive."; 00325 case UDEFRAG_REMOTE: 00326 return "It is impossible to defragment remote volume."; 00327 case UDEFRAG_ASSIGNED_BY_SUBST: 00328 return "It is impossible to defragment volumes\n" 00329 "assigned by \'subst\' command."; 00330 case UDEFRAG_REMOVABLE: 00331 return "You are trying to defragment removable volume.\n" 00332 "If the volume type was wrong identified, send\n" 00333 "a bug report to the author, please."; 00334 } 00335 return ""; 00336 } 00337