Example #1
0
void
syscreate(void)
{
	char file[1024];
	int n;
	ulong mode, name, perm;

	name = getmem_w(reg.r[REGSP]+4);
	mode = getmem_w(reg.r[REGSP]+8);
	perm = getmem_w(reg.r[REGSP]+12);
	memio(file, name, sizeof(file), MemReadstring);
	if(sysdbg)
		itrace("create(0x%lux='%s', 0x%lux, 0x%lux)", name, file, mode, perm);
	
	n = create(file, mode, perm);
	if(n < 0)
		errstr(errbuf, sizeof errbuf);

	reg.r[REGRET] = n;
}
Example #2
0
void
sys_fstat(void)
{
	char buf[ODIRLEN];
	extern int _fstat(int, char*);	/* old system call */
	uint32_t edir;
	int n, fd;

	fd = getmem_w(reg.r[13]+4);
	edir = getmem_w(reg.r[13]+8);
	if(sysdbg)
		itrace("fstat(%d, 0x%lux)", fd, edir);

	n = _fstat(fd, buf);
	if(n < 0)
		errstr(errbuf, sizeof errbuf);
	else
		memio(buf, edir, ODIRLEN, MemWrite);

	reg.r[REGRET] = n;
}
Example #3
0
void
sysseek(void)
{
	int fd;
	uint32_t mode;
	uint32_t retp;
	int64_t v;

	retp = getmem_w(reg.r[13]+4);
	fd = getmem_w(reg.r[13]+8);
	v = getmem_v(reg.r[13]+16);
	mode = getmem_w(reg.r[13]+20);
	if(sysdbg)
		itrace("seek(%d, %lld, %d)", fd, v, mode);

	v = seek(fd, v, mode);
	if(v < 0)
		errstr(errbuf, sizeof errbuf);	

	putmem_v(retp, v);
}
Example #4
0
void
sysbind(void)
{ 
	uint32_t pname, pold, flags;
	char name[1024], old[1024];
	int n;

	pname = getmem_w(reg.r[13]+4);
	pold = getmem_w(reg.r[13]+8);
	flags = getmem_w(reg.r[13]+12);
	memio(name, pname, sizeof(name), MemReadstring);
	memio(old, pold, sizeof(old), MemReadstring);
	if(sysdbg)
		itrace("bind(0x%lux='%s', 0x%lux='%s', 0x%lux)", name, name, old, old, flags);

	n = bind(name, old, flags);
	if(n < 0)
		errstr(errbuf, sizeof errbuf);

	reg.r[REGRET] = n;
}
Example #5
0
void
sys_stat(void)
{
	char nambuf[1024];
	char buf[ODIRLEN];
	uint32_t edir, name;
	extern int _stat(char*, char*);	/* old system call */
	int n;

	name = getmem_w(reg.r[13]+4);
	edir = getmem_w(reg.r[13]+8);
	memio(nambuf, name, sizeof(nambuf), MemReadstring);
	if(sysdbg)
		itrace("stat(0x%lux='%s', 0x%lux)", name, nambuf, edir);

	n = _stat(nambuf, buf);
	if(n < 0)
		errstr(errbuf, sizeof errbuf);
	else
		memio(buf, edir, ODIRLEN, MemWrite);

	reg.r[REGRET] = n;
}
Example #6
0
/**
 * @brief Creates a named mutex.
 * @param[in] name the mutex name.
 * @param[out] phandle pointer to the mutex handle.
 * @return Zero for success, negative value otherwise.
 * @par Example:
 * @code
 * HANDLE h;
 * winx_create_mutex(L"\\BaseNamedObjects\\ultradefrag_mutex",&h);
 * @endcode
 */
int winx_create_mutex(wchar_t *name,HANDLE *phandle)
{
    UNICODE_STRING us;
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;

    DbgCheck2(name,phandle,-1);
    *phandle = NULL;

    RtlInitUnicodeString(&us,name);
    InitializeObjectAttributes(&oa,&us,0,NULL,NULL);
    status = NtCreateMutant(phandle,MUTEX_ALL_ACCESS,&oa,0);
    if(status == STATUS_OBJECT_NAME_COLLISION){
        itrace("%ws already exists",name);
        status = NtOpenMutant(phandle,MUTEX_ALL_ACCESS,&oa);
    }
    if(!NT_SUCCESS(status)){
        *phandle = NULL;
        strace(status,"cannot create/open %ws",name);
        return (-1);
    }
    return 0;
}
Example #7
0
void
syswrite(vlong offset)
{
	int fd;
	ulong size, a;
	char *buf;
	int n;

	fd = getmem_w(reg.r[REGSP]+4);
	a = getmem_w(reg.r[REGSP]+8);
	size = getmem_w(reg.r[REGSP]+12);

	Bflush(bioout);
	buf = memio(0, a, size, MemRead);
	n = pwrite(fd, buf, size, offset);
	if(n < 0)
		errstr(errbuf, sizeof errbuf);	
	if(sysdbg)
		itrace("write(%d, %lux, %d, 0xllx) = %d", fd, a, size, offset, n);
	free(buf);

	reg.r[REGRET] = n;
}
Example #8
0
static int save_lua_report(udefrag_job_parameters *jp)
{
    wchar_t *path = NULL;
    WINX_FILE *f;
    wchar_t *cn;
    wchar_t compname[MAX_COMPUTERNAME_LENGTH + 1];
    char utf8_compname[(MAX_COMPUTERNAME_LENGTH + 1) * 4];
    char buffer[512];
    struct prb_traverser t;
    winx_file_info *file;
    char *comment;
    char *status;
    int length;
    winx_time tm;
    
    /* should be enough for any path in UTF-8 encoding */
    #define MAX_UTF8_PATH_LENGTH (256 * 1024)
    char *utf8_path;
    
    utf8_path = winx_tmalloc(MAX_UTF8_PATH_LENGTH);
    if(utf8_path == NULL){
        mtrace();
        return (-1);
    }
    
    path = get_report_path(jp);
    if(path == NULL)
        return UDEFRAG_NO_MEM;
    
    f = winx_fbopen(path,"w",RSB_SIZE);
    if(f == NULL){
        f = winx_fopen(path,"w");
        if(f == NULL){
            winx_free(path);
            winx_free(utf8_path);
            return (-1);
        }
    }

    /* print header */
    cn = winx_getenv(L"COMPUTERNAME");
    if(cn){
        wcsncpy(compname,cn,MAX_COMPUTERNAME_LENGTH + 1);
        compname[MAX_COMPUTERNAME_LENGTH] = 0;
        winx_free(cn);
    } else {
        wcscpy(compname,L"nil");
    }
    winx_to_utf8(utf8_compname,sizeof(utf8_compname),compname);
    memset(&tm,0,sizeof(winx_time));
    (void)winx_get_local_time(&tm);
    (void)_snprintf(buffer,sizeof(buffer),
        "-- UltraDefrag report for disk %c:\r\n\r\n"
        "format_version = 7\r\n\r\n"
        "volume_letter = \"%c\"\r\n"
        "computer_name = \"%hs\"\r\n\r\n"
        "current_time = {\r\n"
        "\tyear = %04i,\r\n"
        "\tmonth = %02i,\r\n"
        "\tday = %02i,\r\n"
        "\thour = %02i,\r\n"
        "\tmin = %02i,\r\n"
        "\tsec = %02i,\r\n"
        "\tisdst = false\r\n"
        "}\r\n\r\n"
        "files = {\r\n",
        jp->volume_letter, jp->volume_letter,utf8_compname,
        (int)tm.year,(int)tm.month,(int)tm.day,
        (int)tm.hour,(int)tm.minute,(int)tm.second
        );
    buffer[sizeof(buffer) - 1] = 0;
    (void)winx_fwrite(buffer,1,strlen(buffer),f);
    
    /* print body */
    prb_t_init(&t,jp->fragmented_files);
    file = prb_t_first(&t,jp->fragmented_files);
    while(file){
        if(is_directory(file))
            comment = "[DIR]";
        else if(is_compressed(file))
            comment = "[CMP]";
        else
            comment = " - ";
        
        /*
        * On change of status strings don't forget
        * also to adjust write_file_status routine
        * in udreportcnv.lua file.
        */
        if(is_locked(file))
            status = "locked";
        else if(is_moving_failed(file))
            status = "move failed";
        else if(is_in_improper_state(file))
            status = "invalid";
        else
            status = " - ";
        
        (void)_snprintf(buffer, sizeof(buffer),
            "\t{fragments = %u,"
            "size = %I64u,"
            "comment = \"%s\","
            "status = \"%s\","
            "path = \"",
            (UINT)file->disp.fragments,
            file->disp.clusters * jp->v_info.bytes_per_cluster,
            comment,
            status
            );
        buffer[sizeof(buffer) - 1] = 0;
        (void)winx_fwrite(buffer,1,strlen(buffer),f);

        if(file->path != NULL){
            /* skip \??\ sequence in the beginning of the path */
            length = (int)wcslen(file->path);
            if(length > 4){
                convert_to_utf8_path(utf8_path,MAX_UTF8_PATH_LENGTH,file->path + 4);
            } else {
                convert_to_utf8_path(utf8_path,MAX_UTF8_PATH_LENGTH,file->path);
            }
            (void)winx_fwrite(utf8_path,1,strlen(utf8_path),f);
        }

        (void)strcpy(buffer,"\"},\r\n");
        (void)winx_fwrite(buffer,1,strlen(buffer),f);

        file = prb_t_next(&t);
    }
    
    /* print footer */
    (void)strcpy(buffer,"}\r\n");
    (void)winx_fwrite(buffer,1,strlen(buffer),f);

    itrace("report saved to %ws",path);
    winx_fclose(f);
    winx_free(path);
    winx_free(utf8_path);
    return 0;
}
Example #9
0
/**
 * @brief Initializes main window.
 */
MainFrame::MainFrame()
    :wxFrame(NULL,wxID_ANY,wxT("UltraDefrag"))
{
    g_mainFrame = this;
    m_vList = NULL;
    m_cMap = NULL;
    m_currentJob = NULL;
    m_busy = false;
    m_paused = false;

    // set main window icon
    SetIcons(wxICON(appicon));

    // read configuration
    ReadAppConfiguration();
    ProcessCommandEvent(ID_ReadUserPreferences);

    // set main window title
    wxString *instdir = new wxString();
    //genBTC re-arranged the below, A LOT.
    wxStandardPaths stdpaths;
    wxFileName exepath(stdpaths.GetExecutablePath());
    wxString cd = exepath.GetPath();
    if((wxGetEnv(wxT("UD_INSTALL_DIR"),instdir))&&(cd.CmpNoCase(*instdir) == 0)) {
        itrace("current directory matches installation location, so it isn't portable");
        itrace("installation location: %ls",instdir->wc_str());
        m_title = new wxString(wxT(VERSIONINTITLE));
    } else {
        itrace("current directory differs from installation location, so it is portable");
        itrace("current directory: %ls",cd.wc_str());
        wxSetEnv(wxT("UD_IS_PORTABLE"),wxT("1"));
        m_title = new wxString(wxT(VERSIONINTITLE_PORTABLE));
    }
    //genBTC re-arranged the above, A LOT.
    ProcessCommandEvent(ID_SetWindowTitle);
    delete instdir;

    // set main window size and position
    SetSize(m_width,m_height);
    if(!m_saved){
        CenterOnScreen();
        GetPosition(&m_x,&m_y);
    }
    Move(m_x,m_y);
    if(m_maximized) Maximize(true);

    SetMinSize(wxSize(DPI(MAIN_WINDOW_MIN_WIDTH),DPI(MAIN_WINDOW_MIN_HEIGHT)));

    // create menu, tool and status bars
    InitMenu(); InitToolbar(); InitStatusBar();

	//make sizer1 to hold the the tabbed "notebook". And make the notebook
	wxBoxSizer* bSizer1;
	bSizer1 = new wxBoxSizer( wxVERTICAL );
	m_notebook1 = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );

	//make a panel inside the notebook to hold the m_splitter
	m_panel1 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );

    // create list of volumes and cluster map (with splitter as parent)
    m_splitter = new wxSplitterWindow(m_panel1,wxID_ANY, wxDefaultPosition,wxDefaultSize, 
                                      wxSP_3D | wxCLIP_CHILDREN);
    m_splitter->SetMinimumPaneSize(DPI(MIN_PANEL_HEIGHT));

    m_vList = new DrivesList(m_splitter,wxLC_REPORT | wxLC_NO_SORT_HEADER | 
                             wxLC_HRULES | wxLC_VRULES | wxBORDER_NONE);

    m_cMap = new ClusterMap(m_splitter);

    m_splitter->SplitHorizontally(m_vList,m_cMap);

    int height = GetClientSize().GetHeight();
    int maxPanelHeight = height - DPI(MIN_PANEL_HEIGHT) - m_splitter->GetSashSize();
    if(m_separatorPosition < DPI(MIN_PANEL_HEIGHT)) m_separatorPosition = DPI(MIN_PANEL_HEIGHT);
    else if(m_separatorPosition > maxPanelHeight) m_separatorPosition = maxPanelHeight;
    m_splitter->SetSashPosition(m_separatorPosition);

    // update frame layout so we'll be able to initialize
    // list of volumes and cluster map properly
    wxSizeEvent evt(wxSize(m_width,m_height));
    ProcessEvent(evt); m_splitter->UpdateSize();

    InitVolList();
    m_vList->SetFocus();

    // populate list of volumes
    m_listThread = new ListThread();

    //make sizer2 to Fit the splitter, and initialize it.
	wxBoxSizer* bSizer2;
	bSizer2 = new wxBoxSizer( wxVERTICAL );
	bSizer2->Add( m_splitter, 1, wxEXPAND, 1 );
	m_panel1->SetSizer( bSizer2 );

	//Finish Tab1 - Add the Panel1(Splitter+sizer2) to the notebook.
	m_notebook1->AddPage( m_panel1, wxT("Drives"), false );

	//make a 2nd panel inside the notebook to hold the 2nd page(a grid)
	m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );

    m_filesList = new FilesList(m_panel2,wxLC_REPORT /* | wxLC_SINGLE_SEL  | wxLC_NO_SORT_HEADER*/ \
                                        | wxLC_VIRTUAL | wxLC_HRULES | wxLC_VRULES | wxBORDER_NONE);
    InitFilesList();

	//make sizer3 to Fit the page2list, and initialize it.
	wxBoxSizer* bSizer3;
	bSizer3 = new wxBoxSizer( wxVERTICAL );
	bSizer3->Add( m_filesList, 1, wxEXPAND, 1 );
	m_panel2->SetSizer( bSizer3 );
    bSizer3->Fit( m_panel2 );

	//Finish Tab 2 - Add the Panel2(page2list+sizer3) to the notebook.
	m_notebook1->AddPage( m_panel2, wxT("Files"), false );

    //Finish Notebook & initialize
	bSizer1->Add( m_notebook1, 1, wxEXPAND, 1 );
	this->SetSizer( bSizer1 );

    // check the boot time defragmenter presence
    wxFileName btdFile(wxT("%SystemRoot%\\system32\\defrag_native.exe"));
    btdFile.Normalize();
    bool btd = btdFile.FileExists();
    m_menuBar->FindItem(ID_BootEnable)->Enable(btd);
    m_menuBar->FindItem(ID_BootScript)->Enable(btd);
    m_toolBar->EnableTool(ID_BootEnable,btd);
    m_toolBar->EnableTool(ID_BootScript,btd);
    if(btd && ::winx_bootex_check(L"defrag_native") > 0){
        m_menuBar->FindItem(ID_BootEnable)->Check(true);
        m_toolBar->ToggleTool(ID_BootEnable,true);
        m_btdEnabled = true;
    } else {
        m_btdEnabled = false;
    }

    // launch threads for time consuming operations
    m_btdThread = btd ? new BtdThread() : NULL;
    m_configThread = new ConfigThread();
    m_crashInfoThread = new CrashInfoThread();

    wxConfigBase *cfg = wxConfigBase::Get();
    int ulevel = (int)cfg->Read(wxT("/Upgrade/Level"),1);
    wxMenuItem *item = m_menuBar->FindItem(ID_HelpUpgradeNone + ulevel);
    if(item) item->Check();

    m_upgradeThread = new UpgradeThread(ulevel);

    // set system tray icon
    m_systemTrayIcon = new SystemTrayIcon();
    if(!m_systemTrayIcon->IsOk()){
        etrace("system tray icon initialization failed");
        wxSetEnv(wxT("UD_MINIMIZE_TO_SYSTEM_TRAY"),wxT("0"));
    }
    SetSystemTrayIcon(wxT("tray"),wxT("UltraDefrag"));

    // set localized text
    ProcessCommandEvent(ID_LocaleChange + g_locale->GetLanguage());

    // allow disk processing
    m_jobThread = new JobThread();

    //create query thread to perform queries without blocking the GUI
    //(sort of like jobs) - may not be good to have both possibly running at once.
    //Create Query Tab, Tab #3.
    InitQueryMenu();
    
    UD_DisableTool(ID_Stop);    //change stop icon to be not always enabled.
}
Example #10
0
/**
 * @brief find_files helper.
 * @note Optimized for speed.
 */
static int filter(winx_file_info *f,void *user_defined_data)
{
    udefrag_job_parameters *jp = (udefrag_job_parameters *)user_defined_data;
    int length;
    
    /* START OF AUX CODE */
    
    /* skip entries with empty path, as well as their children */
    if(f->path == NULL) goto skip_file_and_children;
    if(f->path[0] == 0) goto skip_file_and_children;
    
    /*
    * Remove trailing dot from the root
    * directory path, otherwise we'll not
    * be able to defragment it.
    */
    length = (int)wcslen(f->path);
    if(length >= 2){
        if(f->path[length - 1] == '.' && f->path[length - 2] == '\\'){
            itrace("root directory detected, its trailing dot will be removed");
            f->path[length - 1] = 0;
        }
    }
    
    /* skip resident streams */
    if(f->disp.fragments == 0)
        goto skip_file;
    
    /* show debugging information about interesting cases */
    /* comment it out after testing to speed things up */
    /*
    if(is_sparse(f))
        dtrace("sparse file found: %ws",f->path);
    if(is_reparse_point(f))
        dtrace("reparse point found: %ws",f->path);
    if(winx_wcsistr(f->path,L"$BITMAP"))
        dtrace("bitmap found: %ws",f->path);
    if(winx_wcsistr(f->path,L"$ATTRIBUTE_LIST"))
        dtrace("attribute list found: %ws",f->path);
    */
    
    /* START OF FILTERING */
    
    /* skip files with invalid map */
    if(f->disp.blockmap == NULL)
        goto skip_file;

    /* skip temporary files */
    if(is_temporary(f))
        goto skip_file;

    /* filter files by their sizes */
    if(exclude_by_size(f,jp))
        goto skip_file;

    /* filter files by their number of fragments */
    if(exclude_by_fragments(f,jp))
        goto skip_file;

    /* filter files by their fragment sizes */
    if(exclude_by_fragment_size(f,jp))
        goto skip_file;
    
    /* filter files by their paths */
    if(exclude_by_path(f,jp)){
        /*
        * Don't skip children however since 
        * their paths may match patterns.
        */
        goto skip_file;
    }
    
    goto accept_file;

skip_file:
    f->user_defined_flags |= UD_FILE_EXCLUDED;
    
accept_file:
    /* count everything in context menu handler to avoid ambiguity */
    if(jp->udo.job_flags & UD_JOB_CONTEXT_MENU_HANDLER){
        if(jp->udo.cut_filter.count){
            if(winx_patcmp(f->path + 0x4,&jp->udo.cut_filter))
                update_progress_counters(f,jp);
        } else {
            update_progress_counters(f,jp);
        }
    }
    return 0;

skip_file_and_children:
    f->user_defined_flags |= UD_FILE_EXCLUDED;
    return 1;
}
Example #11
0
/**
 * @brief Retrieves all information about the volume.
 * @return Zero for success, negative value otherwise.
 * @note Resets statistics and cluster map.
 */
int get_volume_information(udefrag_job_parameters *jp)
{
    char fs_name[MAX_FS_NAME_LENGTH + 1];
    int i;
    
    /* reset mft zone disposition */
    memset(&jp->mft_zone,0,sizeof(struct _mft_zone));

    /* reset v_info structure */
    memset(&jp->v_info,0,sizeof(winx_volume_information));
    
    /* reset statistics */
    jp->pi.files = 0;
    jp->pi.directories = 0;
    jp->pi.compressed = 0;
    jp->pi.fragmented = 0;
    jp->pi.fragments = 0;
    jp->pi.total_space = 0;
    jp->pi.free_space = 0;
    jp->pi.mft_size = 0;
    jp->pi.clusters_to_process = 0;
    jp->pi.processed_clusters = 0;
    
    jp->fs_type = FS_UNKNOWN;
    jp->is_fat = 0;
    
    /* reset file lists */
    destroy_lists(jp);
    
    /* update global variables holding drive geometry */
    if(winx_get_volume_information(jp->volume_letter,&jp->v_info) < 0)
        return (-1);
    
    /* don't touch dirty volumes */
    if(jp->v_info.is_dirty)
        return UDEFRAG_DIRTY_VOLUME;

    jp->pi.total_space = jp->v_info.total_bytes;
    jp->pi.free_space = jp->v_info.free_bytes;
    itrace("total clusters: %I64u",jp->v_info.total_clusters);
    jp->pi.used_clusters = jp->v_info.total_clusters - (jp->v_info.free_bytes / jp->v_info.bytes_per_cluster);
    itrace("used clusters : %I64u",jp->pi.used_clusters);
    itrace("cluster size: %I64u",jp->v_info.bytes_per_cluster);
    /* validate geometry */
    if(!jp->v_info.total_clusters || !jp->v_info.bytes_per_cluster){
        etrace("wrong volume geometry detected");
        return (-1);
    }
    adjust_move_at_once_parameter(jp);
    /* check partition type */
    itrace("%s partition detected",jp->v_info.fs_name);
    strncpy(fs_name,jp->v_info.fs_name,MAX_FS_NAME_LENGTH);
    fs_name[MAX_FS_NAME_LENGTH] = 0;
    _strupr(fs_name);
    for(i = 0; fs_types[i].name; i++){
        if(!strcmp(fs_name,fs_types[i].name)){
            jp->fs_type = fs_types[i].type;
            jp->is_fat = fs_types[i].is_fat;
            break;
        }
    }
    if(jp->fs_type == FS_UNKNOWN){
        etrace("file system type is not recognized");
        etrace("type independent routines will be used to defragment it");
    }
    
    jp->pi.clusters_to_process = jp->v_info.total_clusters;
    jp->pi.processed_clusters = 0;
    
    if(jp->udo.fragment_size_threshold){
        if(jp->udo.fragment_size_threshold <= jp->v_info.bytes_per_cluster){
            itrace("fragment size threshold is below the cluster size, so it will be ignored");
            jp->udo.fragment_size_threshold = 0;
        }
    }

    /* reset cluster map */
    reset_cluster_map(jp);
    return 0;
}