![]() |
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 FILTER in_filter = {NULL,NULL}; 00030 FILTER ex_filter = {NULL,NULL}; 00031 ULONGLONG sizelimit = 0; 00032 ULONGLONG fraglimit = 0; 00033 00034 void SetFilter(PFILTER pf,short *buffer); 00035 00039 void InitializeFilter(void) 00040 { 00041 char buf[64]; 00042 short *env_buffer; 00043 #define ENV_BUFFER_SIZE 8192 00044 00045 /* allocate memory */ 00046 env_buffer = winx_heap_alloc(ENV_BUFFER_SIZE * sizeof(short)); 00047 if(!env_buffer){ 00048 DebugPrint("Cannot allocate %u bytes for InitializeOptions()\n", 00049 ENV_BUFFER_SIZE * sizeof(short)); 00050 out_of_memory_condition_counter ++; 00051 return; 00052 } 00053 RtlZeroMemory(env_buffer,ENV_BUFFER_SIZE * sizeof(short)); 00054 00055 /* reset filter */ 00056 sizelimit = 0; fraglimit = 0; 00057 DestroyFilter(); 00058 00059 /* read program's filter options from environment variables */ 00060 if(winx_query_env_variable(L"UD_IN_FILTER",env_buffer,ENV_BUFFER_SIZE) >= 0){ 00061 DebugPrint("Include: %ws\n",env_buffer); 00062 SetFilter(&in_filter,env_buffer); 00063 } else { 00064 DebugPrint("Include: %ws\n",L""); 00065 } 00066 context_menu_handler = CheckForContextMenuHandler(); 00067 if(context_menu_handler) DebugPrint("Context menu handler?\n"); 00068 00069 if(winx_query_env_variable(L"UD_EX_FILTER",env_buffer,ENV_BUFFER_SIZE) >= 0){ 00070 DebugPrint("Exclude: %ws\n",env_buffer); 00071 SetFilter(&ex_filter,env_buffer); 00072 } else { 00073 DebugPrint("Exclude: %ws\n",L""); 00074 } 00075 00076 if(winx_query_env_variable(L"UD_SIZELIMIT",env_buffer,ENV_BUFFER_SIZE) >= 0){ 00077 (void)_snprintf(buf,sizeof(buf) - 1,"%ws",env_buffer); 00078 buf[sizeof(buf) - 1] = 0; 00079 (void)winx_dfbsize(buf,&sizelimit); 00080 } 00081 00082 if(winx_query_env_variable(L"UD_FRAGMENTS_THRESHOLD",env_buffer,ENV_BUFFER_SIZE) >= 0) 00083 fraglimit = (ULONGLONG)_wtol(env_buffer); 00084 00085 /* print filtering options */ 00086 DebugPrint("Sizelimit = %I64u\n",sizelimit); 00087 DebugPrint("Fragments threshold = %I64u\n",fraglimit); 00088 00089 /* free memory */ 00090 winx_heap_free(env_buffer); 00091 } 00092 00099 void SetFilter(PFILTER pf,short *buffer) 00100 { 00101 POFFSET poffset; 00102 int i; 00103 char ch; 00104 int length; 00105 00106 if(pf->buffer){ 00107 winx_heap_free((void *)pf->buffer); 00108 winx_list_destroy((list_entry **)pf->offsets); 00109 } 00110 pf->buffer = NULL; 00111 pf->offsets = NULL; 00112 00113 length = wcslen(buffer) + 1; 00114 if(length <= 1) return; 00115 00116 pf->buffer = winx_heap_alloc(length * sizeof(short)); 00117 if(!pf->buffer){ 00118 DebugPrint("Cannot allocate memory for pf->buffer in SetFilter()!\n"); 00119 out_of_memory_condition_counter ++; 00120 return; 00121 } 00122 00123 buffer[length - 1] = 0; 00124 (void)_wcslwr(buffer); 00125 00126 /* replace double quotes and semicolons with zeros */ 00127 poffset = (POFFSET)winx_list_insert_item((list_entry **)&pf->offsets,NULL,sizeof(OFFSET)); 00128 if(!poffset) return; 00129 if(length > 1 && buffer[0] == 0x0022) poffset->offset = 1; /* skip leading double quote */ 00130 else poffset->offset = 0; 00131 00132 for(i = 0; i < length - 1; i++){ 00133 if(buffer[i] == 0x0022) { buffer[i] = 0; continue; } /* replace all double quotes with zeros */ 00134 if(buffer[i] == 0x003b){ 00135 buffer[i] = 0; 00136 poffset = (POFFSET)winx_list_insert_item((list_entry **)&pf->offsets,NULL,sizeof(OFFSET)); 00137 if(!poffset) break; 00138 if(buffer[i + 1] == 0x0022) poffset->offset = i + 2; /* safe, because we always have null terminated buffer */ 00139 else poffset->offset = i + 1; 00140 } 00141 } 00142 00143 memcpy(pf->buffer,buffer,length * sizeof(short)); 00144 00145 DebugPrint("Filter strings:\n"); 00146 ch = (pf == &in_filter) ? '+' : '-'; 00147 for(poffset = pf->offsets; poffset != NULL; poffset = poffset->next_ptr){ 00148 DebugPrint(" %c %ws\n",ch,pf->buffer + poffset->offset); 00149 if(poffset->next_ptr == pf->offsets) break; 00150 } 00151 } 00152 00161 BOOLEAN IsStringInFilter(short *str,PFILTER pf) 00162 { 00163 POFFSET po; 00164 short *p; 00165 00166 for(po = pf->offsets; po != NULL; po = po->next_ptr){ 00167 p = pf->buffer + po->offset; 00168 if(p[0]){ if(wcsstr(str,p)) return TRUE; } 00169 if(po->next_ptr == pf->offsets) break; 00170 } 00171 return FALSE; 00172 } 00173 00180 BOOLEAN CheckForContextMenuHandler(void) 00181 { 00182 POFFSET po; 00183 short *p; 00184 00185 if(!in_filter.buffer) return FALSE; 00186 po = in_filter.offsets; 00187 if(!po) return FALSE; 00188 if(po->next_ptr != po) return FALSE; 00189 p = in_filter.buffer + po->offset; 00190 if(wcslen(p) < 3) return FALSE; 00191 if(p[1] != ':' || p[2] != '\\') return FALSE; 00192 return TRUE; 00193 } 00194 00198 void DestroyFilter(void) 00199 { 00200 if(in_filter.buffer){ 00201 winx_heap_free(in_filter.buffer); 00202 in_filter.buffer = NULL; 00203 } 00204 if(ex_filter.buffer){ 00205 winx_heap_free(ex_filter.buffer); 00206 ex_filter.buffer = NULL; 00207 } 00208 winx_list_destroy((list_entry **)&in_filter.offsets); 00209 winx_list_destroy((list_entry **)&ex_filter.offsets); 00210 } 00211 00212 /* 1. wcsstr(L"AGTENTLEPSE.SDFGSDFSDFSRG",L"AGTENTLEPSE"); x 1 mln. times = 63 ms 00213 2. empty cycle = 0 ms 00214 3. wcsistr(L"AGTENTLEPSE.SDFGSDFSDFSRG",L"AGTENTLEPSE"); x 1 mln. times = 340 ms 00215 4. wcsistr 2 kanji strings x 1 mln. times = 310 ms 00216 WCHAR s1[] = {0x30ea,0x30e0,0x30fc,0x30d0,0x30d6,0x30eb,0x30e1,0x30c7,0x30a3,0x30a2,0x306f,0x9664,0x5916,0}; 00217 WCHAR s2[] = {0x30ea,0x30e0,0x30fc,0x30d0,0x30d6,0x30eb,0x30e1,0x30c7,0x30a3,0x30a2,0x306f,0}; 00218 ULONGLONG t = _rdtsc(); 00219 for(i = 0; i < 1000000; i++) wcsistr(s1,s2);//wcsistr(L"AGTENTLEPSE.SDFGSDFSDFSRG",L"AGTENTLEPSE"); 00220 DbgPrint("AAAA %I64u ms\n",_rdtsc() - t); 00221 */ 00222 00226 wchar_t * __cdecl wcsistr(const wchar_t * wcs1,const wchar_t * wcs2) 00227 { 00228 wchar_t *cp = (wchar_t *)wcs1; 00229 wchar_t *s1, *s2; 00230 00231 if(wcs1 == NULL || wcs2 == NULL) return NULL; 00232 00233 while(*cp){ 00234 s1 = cp; 00235 s2 = (wchar_t *)wcs2; 00236 00237 while(*s1 && *s2 && !( towlower((int)(*s1)) - towlower((int)(*s2)) )){ s1++, s2++; } 00238 if(!*s2) return cp; 00239 cp++; 00240 } 00241 00242 return NULL; 00243 } 00244