// size by default = -1 /////////////////////////////////////////////////////////////////////////////// void stream_file_read(R_STREAM_FILE *stream_file, int size, char *res) { int pn_start, off_start, pn_end, off_end; if (size == -1) { char *pdata = (char *) malloc(stream_file->pages_amount * stream_file->page_size); if (pdata) { GET_PAGE(pn_start, off_start, stream_file->pos, stream_file->page_size); (void)off_end; // hack to remove unused warning stream_file_read_pages (stream_file, 0, stream_file->pages_amount, pdata); stream_file->pos = stream_file->end; memcpy (res, pdata + off_start, stream_file->end - off_start); free (pdata); } } else { GET_PAGE(pn_start, off_start, stream_file->pos, stream_file->page_size); GET_PAGE(pn_end, off_end, stream_file->pos + size, stream_file->page_size); (void)off_end; // hack to remove unused warning char *pdata = (char *) calloc(stream_file->page_size * (pn_end + 1 - pn_start), 1); if (pdata) { stream_file_read_pages(stream_file, pn_start, pn_end + 1, pdata); stream_file->pos += size; memcpy(res, pdata + off_start, size); free (pdata); } } }
size_t vm_getphypage(int n,size_t vp){ vp=GET_PAGE(vp); if(vp<VM_KERNEL)return vp; size_t i1=vp/0x8000000000; vp-=i1*0x8000000000; size_t i2=vp/0x40000000; vp-=i2*0x40000000; size_t i3=vp/0x200000; vp-=i3*0x200000; size_t i4=vp/0x1000; u64 *p=vi[n].pagetable; if(p==NULL){ return 0; } p=(u64*)GET_PAGE(p[i1]); if(p==NULL){ return 0; } p=(u64*)GET_PAGE(p[i2]); if(p==NULL){ return 0; } p=(u64*)GET_PAGE(p[i3]); if(p==NULL){ return 0; } p=(u64*)GET_PAGE(p[i4]); return (size_t)p; }
bool callhook::research(){ void* pEntry; void* pEnd; pEntry = GET_PAGE((unsigned long)pEntryFunc-SEARCH_RANG); pEnd = GET_PAGE((unsigned long)pEntryFunc+SEARCH_RANG); if( !pFunInfo )return false; void* pf = ScreechFunctionEntry( pEntry,pEnd,pFunInfo->code,pFunInfo->mask ); if( pf ){ void* pold = pEntryFunc; pEntryFunc = (char*)pf-pFunInfo->off; if( check() ){ #ifdef _OUT printf("callhook::research(\"%s\") PASS %X\n",pFunInfo->name,pEntryFunc); #endif return true; } pEntryFunc = pold; } #ifdef _OUT printf("callhook::research(\"%s\") FALSE\n",pFunInfo->name); #endif return false; }
void callhook::jmp_clear(){ int i; DWORD op; VirtualProtect( GET_PAGE(pEntryFunc),PAGE_SIZE,PAGE_EXECUTE_READWRITE,&op ); for( i = 0;i < 8;i++ ) ((unsigned char*)pEntryFunc)[i] = ((unsigned char*)pEntryCode)[i]; VirtualProtect( GET_PAGE(pEntryFunc),PAGE_SIZE,PAGE_EXECUTE_READ,&op ); }
void callhook::jmp_setup( void* pNewFunc ){ int i; DWORD op; VirtualProtect( GET_PAGE(pEntryFunc),PAGE_SIZE,PAGE_EXECUTE_READWRITE,&op ); //保存以前的代码 for( i = 0;i < 8;i++ ) ((unsigned char*)pEntryCode)[i] = ((unsigned char*)pEntryFunc)[i]; //加入jmp pNuwFunc的硬编码 ((unsigned char*)pEntryFunc)[0] = 0xe9; //jmp *(void**)((char*)pEntryFunc+1) = (void*)((char*)pNewFunc-(char*)pEntryFunc-5); VirtualProtect( GET_PAGE(pEntryFunc),PAGE_SIZE,PAGE_EXECUTE_READ,&op ); }
int vm_rawmap(int n,size_t vp,size_t pp){ vp=GET_PAGE(vp); if(vp<VM_KERNEL)return 0; pp=GET_PAGE(pp); size_t i1=vp/0x8000000000; vp-=i1*0x8000000000; size_t i2=vp/0x40000000; vp-=i2*0x40000000; size_t i3=vp/0x200000; vp-=i3*0x200000; size_t i4=vp/0x1000; if(vi[n].pagetable==NULL){ vi[n].pagetable=pmm_alloc(); if(vi[n].pagetable==NULL)return 0; memset(vi[n].pagetable,0,4096); } u64 *p=(u64*)GET_PAGE(vi[n].pagetable[i1]),*q; if(p==NULL){ p=vi[n].pagetable[i1]=pmm_alloc(); if(p==NULL)return 0; vi[n].pagetable[i1]|=3; memset(p,0,4096); } if((u64*)p[i2]==NULL){ q=p[i2]=pmm_alloc(); if(q==NULL)return 0; p[i2]|=3; p=q; memset(p,0,4096); }else{ p=GET_PAGE(p[i2]); } if((u64*)p[i3]==NULL){ q=p[i3]=pmm_alloc(); if(q==NULL)return 0; p[i3]|=3; p=q; memset(p,0,4096); }else{ p=GET_PAGE(p[i3]); } p[i4]=pp|3; return 1; }
int check_address(int addr) { /* If beyond the number of pages */ if( num_pages <= GET_PAGE(addr) ) { printf("%s: Fault! Invalid Page Reference (%d)!\n", current_ref, GET_PAGE(addr)); return -1; } /* If offset is larger than a page */ if( PAGE_SIZE <= GET_OFFSET(addr) ) { printf("%s: Fault! Invalid Offset (%d)!\n", current_ref, GET_OFFSET(addr)); return -1; } return 0; }
/* * Adds a destructor to a block. */ dip_status VMAddDtor( imp_image_handle *ii, virt_mem start, void ( *dtor )( imp_image_handle *ii, void *user ), void *user ) { unsigned dir_idx; unsigned pg_idx; virt_page *pg; /* locate the block. */ dir_idx = GET_DIR( start ); if( ii->virt[dir_idx] != NULL ) { pg_idx = GET_PAGE( start ); pg = ii->virt[dir_idx][pg_idx]; if( pg != NULL ) { /* create a new dtor node and link it in */ vm_dtor *node = DCAlloc( sizeof( *node ) ); if( node != NULL ) { node->user = user; node->dtor = dtor; node->next = pg->block->first_dtor; pg->block->first_dtor = node; return( DS_OK ); } return( DS_ERR | DS_NO_MEM ); } } return( DS_ERR | DS_FAIL ); }
void InitDynamicHook(){ DWORD op,op2; //lua在注册一个函数的时候有个个表, //大概类似与funs={{"CastSpellByName",CastSpellByName},...} //这里我直接改动这个表中的地址,因为它位于.data段,和变量在一个数据段 //wow并不校验这些变量的初值 PDWORD pf; hookType = 3; pf = pdwCastSpellByName; VirtualProtect( GET_PAGE(pf),PAGE_SIZE,PAGE_EXECUTE_READWRITE,&op ); CastSpellByName = (t_lua)(*pf); *pf = (DWORD)lua_MyCastSpellByName; VirtualProtect( GET_PAGE(pf),PAGE_SIZE,op,&op2 ); //在调用一个lua函数的时候wow要检查他是不是出了wow的.text段范围 //而wow的调用检查函数使用一个范围来标记.text的范围 //[pdwCallCheckerLow,pdwCallCheckerLow+4]中存放这些范围 //不能设置成0,0xffffffff,检查函数会比较这个值是否为0 pf = pdwCallCheckerLow; VirtualProtect( GET_PAGE(pf),PAGE_SIZE,PAGE_EXECUTE_READWRITE,&op ); *pf = 1; pf++; *pf = 0xffffffff; VirtualProtect( GET_PAGE(pf),PAGE_SIZE,op,&op2 ); //设置绘制挂钩,这个数据处于.rdata段 VirtualProtect( GET_PAGE(pdwSwapBuff),PAGE_SIZE,PAGE_EXECUTE_READWRITE,&op ); pSwapBuff = (t_SwapBuff)(*pdwSwapBuff); *pdwSwapBuff = (DWORD)MySwapBuff; VirtualProtect( GET_PAGE(pdwSwapBuff),PAGE_SIZE,op,&op2 ); //这里子类化wow窗口,重新定位winproc DWORD tid; CreateThread(NULL,0,subClassProc,0,0,&tid); }
int find_page_table_entry(addr_t address, int index, page_table_leaf_t **page_entry) { /* * Simulate time needed to bring in page table from RAM */ nanosleep(&ACCESS_TIME_RAM, NULL); /* * Single level page table */ *page_entry = &(sys_proc_table[index].page_table->pages[GET_PAGE(address)]); return 0; }
int vmm_init_raw(int n){ size_t p,i; for((p=(size_t)get_phy_kernel_start()),(i=0); p<(size_t)get_phy_kernel_end(); (p+=4096),(i+=4096)){ if(!vm_rawmap(n,VM_KERNEL_CODE+i,p)){ return 0; } } if(n==0)vmm_initphy(); else{ for(i=0;i<VM_KERNEL/0x8000000000;i++) vi[n].pagetable[i]=GET_PAGE(vi[0].pagetable[i])|3; } processor_info *pi=pmm_alloc(); if(pi==NULL)return 0; if(!vm_rawmap(n,MP_PROCESSOR_INFO,pi))return 0; pi->n=n; return 1; }
void vm_unmap(int n,size_t vp){ vp=GET_PAGE(vp); if(vp<VM_KERNEL)return 0; size_t i1=vp/0x8000000000; vp-=i1*0x8000000000; size_t i2=vp/0x40000000; vp-=i2*0x40000000; size_t i3=vp/0x200000; vp-=i3*0x200000; size_t i4=vp/0x1000; int i; if(vi[n].pagetable!=NULL){ u64 *p1=(u64*)GET_PAGE(vi[n].pagetable[i1]); if(p1!=NULL){ u64 *p2=(u64*)GET_PAGE(p1[i2]); if(p2!=NULL){ u64 *p3=(u64*)GET_PAGE(p2[i3]); if(p3!=NULL){ p3[i4]=NULL; for(i=0;i<4096/8;i++){ if(GET_PAGE(p3[i])!=NULL){ invlpaging(); return; } } p2[i3]=NULL; pmm_free(p3); for(i=0;i<4096/8;i++){ if(GET_PAGE(p2[i])!=NULL){ invlpaging(); return; } } p1[i2]=NULL; invlpaging(); pmm_free(p2); } } } } }
/* * FDDI card reset */ static void card_start(struct s_smc *smc) { int i ; #ifdef PCI u_char rev_id ; u_short word; #endif smt_stop_watchdog(smc) ; #ifdef PCI /* * make sure no transfer activity is pending */ outpw(FM_A(FM_MDREG1),FM_MINIT) ; outp(ADDR(B0_CTRL), CTRL_HPI_SET) ; hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ; /* * now reset everything */ outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */ i = (int) inp(ADDR(B0_CTRL)) ; /* do dummy read */ SK_UNUSED(i) ; /* Make LINT happy. */ outp(ADDR(B0_CTRL), CTRL_RST_CLR) ; /* * Reset all bits in the PCI STATUS register */ outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */ word = inpw(PCI_C(PCI_STATUS)) ; outpw(PCI_C(PCI_STATUS), word | PCI_ERRBITS) ; outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */ /* * Release the reset of all the State machines * Release Master_Reset * Release HPI_SM_Reset */ outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ; /* * determine the adapter type * Note: Do it here, because some drivers may call card_start() once * at very first before any other initialization functions is * executed. */ rev_id = inp(PCI_C(PCI_REV_ID)) ; if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) { smc->hw.hw_is_64bit = TRUE ; } else { smc->hw.hw_is_64bit = FALSE ; } /* * Watermark initialization */ if (!smc->hw.hw_is_64bit) { outpd(ADDR(B4_R1_F), RX_WATERMARK) ; outpd(ADDR(B5_XA_F), TX_WATERMARK) ; outpd(ADDR(B5_XS_F), TX_WATERMARK) ; } outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* clear the reset chips */ outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ; /* ye LED on */ /* init the timer value for the watch dog 2,5 minutes */ outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ; /* initialize the ISR mask */ smc->hw.is_imask = ISR_MASK ; smc->hw.hw_state = STOPPED ; #endif GET_PAGE(0) ; /* necessary for BOOT */ }
void stream_file_get_size(R_STREAM_FILE *stream_file, int *data_size) { int pn_start = 0, off_start = 0; GET_PAGE(pn_start, off_start, stream_file->pos, stream_file->page_size); (void)pn_start; // hack for remove unused warning *data_size = stream_file->end - off_start; }
void CFinishedPage::Start() { if ( m_pBuilder ) delete m_pBuilder; m_pBuilder = new CTorrentBuilder(); GET_PAGE( COutputPage, pOutput ); m_pBuilder->SetOutputFile( pOutput->m_sFolder + '\\' + pOutput->m_sName ); if ( pOutput->m_bAutoPieces ) m_pBuilder->SetPieceSize( -1 ); else m_pBuilder->SetPieceSize( pOutput->m_nPieceIndex ); m_pBuilder->Enable( pOutput->m_bSHA1, pOutput->m_bED2K, pOutput->m_bMD5 ); GET_PAGE( CTrackerPage, pTracker ); m_pBuilder->AddTrackerURL( pTracker->m_sTracker ); m_pBuilder->AddTrackerURL2( pTracker->m_sTracker2 ); GET_PAGE( CCommentPage, pComment ); m_pBuilder->SetComment( pComment->m_sComment ); GET_PAGE( CWelcomePage, pWelcome ); if ( pWelcome->m_nType == 0 ) { GET_PAGE( CSinglePage, pSingle ); m_pBuilder->AddFile( pSingle->m_sFileName ); } else if ( pWelcome->m_nType == 1 ) { GET_PAGE( CPackagePage, pPackage ); for ( int nFile = 0 ; nFile < pPackage->m_wndList.GetItemCount() ; nFile++ ) { m_pBuilder->AddFile( pPackage->m_wndList.GetItemText( nFile, 0 ) ); } } else { GET_PAGE( CExpertPage, pExpert ); for ( int nFile = 0 ; nFile < pExpert->m_wndList.GetItemCount() ; nFile++ ) { m_pBuilder->AddFile( pExpert->m_wndList.GetItemText( nFile, 0 ) ); } } m_pBuilder->Start(); SetTimer( 1, 200, NULL ); PostMessage( WM_TIMER, 1 ); m_wndDone1.ShowWindow( SW_HIDE ); m_wndDone2.ShowWindow( SW_HIDE ); m_wndTorrentName.ShowWindow( SW_HIDE ); m_wndTorrentCopy.ShowWindow( SW_HIDE ); m_wndTorrentOpen.ShowWindow( SW_HIDE ); m_wndTorrentSeed.ShowWindow( SW_HIDE ); m_wndAbort.ShowWindow( SW_SHOW ); m_wndSpeedMessage.ShowWindow( SW_SHOW ); m_wndSpeedSlow.ShowWindow( SW_SHOW ); m_wndSpeedFast.ShowWindow( SW_SHOW ); m_wndSpeed.ShowWindow( SW_SHOW ); m_wndProgress.SetPos( 0 ); m_wndProgress.SetRange( 0, 1 ); SetWizardButtons( PSWIZB_DISABLEDFINISH ); }
/********************** ************************/ int main(int argc,char *argv[]) { int n_pages = 0; //int n_frames = 0; ram_info_t ram_info;// ram_info.n_frames = 0;// ram_info.algorithm = NULL;// int n_cache = 0; int n_tlb = 0; char *access_file = NULL; FILE *access_fd = NULL; addr_t virtual_addr = 0; addr_t physical_addr; pid_t pid = 0; char mode; /* * Parse arguments */ if( 0 != parse_args(argc, argv, &access_file, &n_pages, &ram_info.n_frames, &n_cache, &n_tlb, &ram_info.algorithm) ) {// return -1; } /* * Setup data structures */ srand(time(NULL)); current_ref = (char *)malloc(sizeof(char) * MAX_LINE); clear_stats(); stats.cache_size = n_cache; stats.tlb_size = n_tlb; stats.num_pages = n_pages; stats.num_frames = ram_info.n_frames;// printf("Allocating resources...\n"); allocate_cache(n_cache); allocate_tlb(n_tlb); allocate_page_table(n_pages); allocate_page_directory(n_pages); //allocate_ram(n_frames); allocate_ram(ram_info); /* * Open the file that we are going to read */ if( NULL == (access_fd = fopen(access_file, "r") ) ) { fprintf(stderr, "Error: Unable to open the access file <%s>\n", access_file); return -1; } /* * Read page requests from the file */ gettimeofday(&stats.start, NULL); while(0 == feof(access_fd) ) { /* Read one line */ current_ref[0] = '\0'; if( NULL == fgets(current_ref, MAX_LINE, access_fd) ) { break; } /* Strip off the newline */ if( '\n' == current_ref[strlen(current_ref)-1] ) { current_ref[strlen(current_ref)-1] = '\0'; } extract_args(current_ref, &pid, &mode, &virtual_addr); /* * Memory management operations to access the page */ if(VERBOSE){ printf("-----------------------------------------------------------\n"); printf("%s: Process %*d \t Access [Page %4d, Offset %#05x] (%#010x)\n", current_ref, MAX_PID_LEN, pid, GET_PAGE(virtual_addr), GET_OFFSET(virtual_addr), virtual_addr); } access_page(pid, mode, virtual_addr, &physical_addr); if(VERBOSE){ printf("%s: Process %*d \t Access [Page %4d, Offset %#05x] (%#010x) --> (%#010x) [Frame %4d, Offset %#05x]\n", current_ref, MAX_PID_LEN, pid, GET_PAGE(virtual_addr), GET_OFFSET(virtual_addr), virtual_addr, physical_addr, GET_FRAME(physical_addr), GET_OFFSET(physical_addr)); } } gettimeofday(&stats.end, NULL); display_stats(); /* * Cleanup */ fclose(access_fd); if( NULL != current_ref ) { free(current_ref); current_ref = NULL; } free_ram(); free_page_dir(); free_tlb(); free_cache(); return 0; }
void *VMBlock( imp_image_handle *iih, virt_mem start, size_t len ) { unsigned dir_idx; unsigned pg_idx; unsigned tmp_idx; unsigned i; unsigned j; unsigned num_pages; virt_mem pg_start; virt_page *pg; virt_page *zero; loaded_block *block; dir_idx = GET_DIR( start ); if( iih->virt[dir_idx] == NULL ) { if( !InitPageDir( iih, dir_idx ) ) { return( NULL ); } } pg_idx = GET_PAGE( start ); len += start % VM_PAGE_SIZE; pg_start = start & ~(virt_mem)(VM_PAGE_SIZE - 1); pg = iih->virt[dir_idx][pg_idx]; if( pg == NULL || ( pg->block->len - pg->offset ) < len ) { /* unloaded previously loaded block */ if( pg != NULL ) { tmp_idx = dir_idx; /* find first page of the block */ i = pg_idx; for( ;; ) { iih->virt[tmp_idx][i] = NULL; if( pg->offset == 0 ) break; if( i == 0 ) { --tmp_idx; i = DIR_SIZE; } --i; --pg; } DCFree( pg ); } num_pages = BLOCK_FACTOR( len, VM_PAGE_SIZE ); pg = DCAlloc( num_pages * ( sizeof( *pg ) + VM_PAGE_SIZE ) + sizeof( loaded_block ) - 1 ); if( pg == NULL ) { DCStatus( DS_ERR | DS_NO_MEM ); return( NULL ); } /* set up new page table entries */ block = (loaded_block *)&pg[num_pages]; tmp_idx = dir_idx; for( j = pg_idx, i = 0; i < num_pages; ++j, ++i ) { pg[i].block = block; pg[i].offset = i * VM_PAGE_SIZE; if( j >= DIR_SIZE ) { ++tmp_idx; j = 0; } if( iih->virt[tmp_idx] == NULL ) { if( !InitPageDir( iih, tmp_idx ) ) { /* unwind the setup already done */ num_pages = i; for( i = 0; i < num_pages; ++i, ++pg_idx ) { if( pg_idx >= DIR_SIZE ) { ++dir_idx; pg_idx = 0; } iih->virt[dir_idx][pg_idx] = NULL; } DCFree( pg ); return( NULL ); } } if( iih->virt[tmp_idx][j] != NULL ) { /* We just ran into another allocated block, so we have to kill all the pages mapped in by it. We know that if the page pointer is non-NULL, it will be offset==0 since KillPages will clean out the others. */ KillPages( iih, tmp_idx, j ); } iih->virt[tmp_idx][j] = &pg[i]; } /* read in new block */ len = num_pages * VM_PAGE_SIZE; block->len = len; pg_start += iih->bias; if( DCSeek( iih->sym_fp, pg_start, DIG_ORG ) ) { DCStatus( DS_ERR | DS_FSEEK_FAILED ); return( NULL ); } /* last block might be a short read */ if( DCRead( iih->sym_fp, pg->block->data, len ) == DIG_RW_ERROR ) { DCStatus( DS_ERR | DS_FREAD_FAILED ); return( NULL ); } pg = iih->virt[dir_idx][pg_idx]; } ++TimeStamp; if( TimeStamp == 0 ) { /* deal with wrap-around */ for( iih = ImageList; iih != NULL; iih = iih->next_image ) { if( iih->virt != NULL ) { for( i = iih->vm_dir_num; i-- > 0; ) { if( iih->virt[i] != NULL ) { for( j = DIR_SIZE; j-- > 0; ) { zero = iih->virt[i][j]; if( zero != NULL ) { zero->block->time_stamp = 0; } } } } } } ++TimeStamp; } pg->block->time_stamp = TimeStamp; return( &pg->block->data[(start & (VM_PAGE_SIZE - 1)) + pg->offset] ); }
void CFinishedPage::OnTimer(UINT_PTR nIDEvent) { BOOL bFinished = FALSE; if ( nIDEvent == 2 ) { KillTimer( 2 ); Start(); return; } if ( m_pBuilder != NULL ) { CString str1, str2; DWORD nPos, nLen; if ( m_pBuilder->GetTotalProgress( nPos, nLen ) ) { m_wndProgress.SetRange32( 0, nLen ); // m_wndProgress.SetRange( 0, nLen ); m_wndProgress.SetPos( nPos ); } if ( m_pBuilder->GetCurrentFile( str1 ) ) { m_wndFileName.GetWindowText( str2 ); if ( str1 != str2 ) m_wndFileName.SetWindowText( str1 ); } if ( m_pBuilder->IsRunning() ) return; bFinished = m_pBuilder->IsFinished(); str1.Empty(); m_pBuilder->GetMessageString( str1 ); m_wndFileName.SetWindowText( str1 ); m_pBuilder->Stop(); delete m_pBuilder; m_pBuilder = NULL; } KillTimer( 1 ); m_wndAbort.ShowWindow( SW_HIDE ); m_wndSpeedMessage.ShowWindow( SW_HIDE ); m_wndSpeedSlow.ShowWindow( SW_HIDE ); m_wndSpeedFast.ShowWindow( SW_HIDE ); m_wndSpeed.ShowWindow( SW_HIDE ); GET_PAGE( COutputPage, pOutput ); m_wndTorrentName.SetWindowText( pOutput->m_sFolder + '\\' + pOutput->m_sName ); if ( bFinished ) { m_wndDone1.ShowWindow( SW_SHOW ); m_wndTorrentName.ShowWindow( SW_SHOW ); m_wndTorrentCopy.ShowWindow( SW_SHOW ); m_wndTorrentOpen.ShowWindow( SW_SHOW ); m_wndTorrentSeed.ShowWindow( SW_SHOW ); } else { m_wndProgress.SetPos( 0 ); } m_wndDone2.ShowWindow( SW_SHOW ); // GetSheet()->GetDlgItem( 2 )->EnableWindow( FALSE ); SetWizardButtons( PSWIZB_BACK | PSWIZB_FINISH ); }
BOOL COutputPage::OnSetActive() { SetWizardButtons( PSWIZB_BACK | PSWIZB_NEXT ); GET_PAGE( CWelcomePage, pWelcome ); if ( pWelcome->m_nType == 0 ) { GET_PAGE( CSinglePage, pSingle ); CString strFile = pSingle->m_sFileName; if ( LPCTSTR pszSlash = _tcsrchr( strFile, '\\' ) ) { m_sName = pszSlash + 1; m_sName += _T(".torrent"); if ( m_sFolder.IsEmpty() ) m_sFolder = strFile.Left( (int)( pszSlash - strFile ) ); } } else { GET_PAGE( CPackagePage, pPackage ); CString sName = pPackage->m_wndList.GetItemText( 0, 0 ); // Get same part of first and last files int nCount = pPackage->m_wndList.GetItemCount(); if ( nCount > 1 ) { CString sName2 = pPackage->m_wndList.GetItemText( nCount - 1, 0 ); LPCTSTR pszName1 = sName; LPCTSTR pszName2 = sName2; for ( int i = 0; *pszName1 && *pszName2; ++pszName1, ++pszName2, ++i ) { if ( *pszName1 != *pszName2 ) { sName = sName.Left( i + 1 ); break; } } } // Use parent folder name as torrent name int nSlash = sName.ReverseFind( _T('\\') ); if ( nSlash != -1 ) { sName = sName.Left( nSlash ); nSlash = sName.ReverseFind( _T('\\') ); if ( nSlash != -1 ) { m_sName = sName.Mid( nSlash + 1 ) + _T(".torrent"); } } if ( m_sFolder.IsEmpty() ) m_sFolder = theApp.GetProfileString( _T("Folders"), _T("Last") ); if ( ! m_sFolder.IsEmpty() && m_sName.IsEmpty() ) { m_sName = PathFindFileName( m_sFolder ); m_sName += _T(".torrent"); } } if ( ! theApp.m_sCommandLineDestination.IsEmpty() ) { m_sFolder = theApp.m_sCommandLineDestination; theApp.m_sCommandLineDestination.Empty(); Next(); } UpdateData( FALSE ); return CWizardPage::OnSetActive(); }