Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

CConnOptions.cxx 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This 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. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #include <vncviewer/CConnOptions.h>
  19. #include <rfb/Configuration.h>
  20. #include <rfb/encodings.h>
  21. #include <rfb/LogWriter.h>
  22. #include <rfb/ScaleFilters.h>
  23. #include <rfb_win32/MsgBox.h>
  24. #include <rfb_win32/Registry.h>
  25. #include <rfb/SecurityClient.h>
  26. #include <rdr/HexInStream.h>
  27. #include <rdr/HexOutStream.h>
  28. #include <stdlib.h>
  29. using namespace rfb;
  30. using namespace rfb::win32;
  31. static StringParameter passwordFile("PasswordFile",
  32. "Password file for VNC authentication", "");
  33. // - Settings stored in the registry & in .vnc files, by Save Defaults and
  34. // Save Configuration respectively.
  35. static BoolParameter useLocalCursor("UseLocalCursor", "Render the mouse cursor locally", true);
  36. static BoolParameter useDesktopResize("UseDesktopResize", "Support dynamic desktop resizing", true);
  37. static BoolParameter fullColour("FullColor",
  38. "Use full color", true);
  39. static AliasParameter fullColourAlias("FullColour", "Alias for FullColor", &fullColour);
  40. static IntParameter lowColourLevel("LowColorLevel",
  41. "Color level to use on slow connections. "
  42. "0 = Very Low (8 colors), 1 = Low (64 colors), 2 = Medium (256 colors)",
  43. 2);
  44. static AliasParameter lowColourLevelAlias("LowColourLevel", "Alias for LowColorLevel", &lowColourLevel);
  45. static BoolParameter fullScreen("FullScreen",
  46. "Use the whole display to show the remote desktop."
  47. "(Press F8 to access the viewer menu)",
  48. false);
  49. static StringParameter preferredEncoding("PreferredEncoding",
  50. "Preferred encoding to use (Tight, ZRLE, Hextile or"
  51. " Raw)", "Tight");
  52. static BoolParameter autoSelect("AutoSelect",
  53. "Auto select pixel format and encoding. "
  54. "Default if PreferredEncoding and FullColor are not specified.",
  55. true);
  56. static BoolParameter sharedConnection("Shared",
  57. "Allow existing connections to the server to continue."
  58. "(Default is to disconnect all other clients)",
  59. false);
  60. StringParameter desktopSize("DesktopSize",
  61. "Reconfigure desktop size on the server on "
  62. "connect (if possible)", "");
  63. static BoolParameter sendPtrEvents("SendPointerEvents",
  64. "Send pointer (mouse) events to the server.", true);
  65. static BoolParameter sendKeyEvents("SendKeyEvents",
  66. "Send key presses (and releases) to the server.", true);
  67. static BoolParameter clientCutText("ClientCutText",
  68. "Send clipboard changes to the server.", true);
  69. static BoolParameter serverCutText("ServerCutText",
  70. "Accept clipboard changes from the server.", true);
  71. static BoolParameter disableWinKeys("DisableWinKeys",
  72. "Pass special Windows keys directly to the server.", true);
  73. static BoolParameter protocol3_3("Protocol3.3",
  74. "Only use protocol version 3.3", false);
  75. static IntParameter ptrEventInterval("PointerEventInterval",
  76. "The interval to delay between sending one pointer event "
  77. "and the next.", 0);
  78. static BoolParameter emulate3("Emulate3",
  79. "Emulate middle mouse button when left and right buttons "
  80. "are used simulatenously.", false);
  81. static BoolParameter acceptBell("AcceptBell",
  82. "Produce a system beep when requested to by the server.",
  83. true);
  84. static BoolParameter showToolbar("ShowToolbar", "Show toolbar by default.", true);
  85. static StringParameter monitor("Monitor", "The monitor to open the VNC Viewer window on, if available.", "");
  86. static StringParameter menuKey("MenuKey", "The key which brings up the popup menu", "F8");
  87. static BoolParameter autoReconnect("AutoReconnect", "Offer to reconnect to the remote server if the connection"
  88. "is dropped because an error occurs.", true);
  89. static BoolParameter customCompressLevel("CustomCompressLevel",
  90. "Use custom compression level. "
  91. "Default if CompressLevel is specified.", false);
  92. static IntParameter compressLevel("CompressLevel",
  93. "Use specified compression level"
  94. "0 = Low, 9 = High",
  95. 6);
  96. static BoolParameter noJpeg("NoJPEG",
  97. "Disable lossy JPEG compression in Tight encoding.",
  98. false);
  99. static IntParameter qualityLevel("QualityLevel",
  100. "JPEG quality level. "
  101. "0 = Low, 9 = High",
  102. 8);
  103. static BoolParameter autoScaling("AutoScaling",
  104. "Auto rescale local copy of the remote desktop to the client window.",
  105. false);
  106. static IntParameter scale("Scale",
  107. "Scale local copy of the remote desktop, in percent",
  108. 100);
  109. CConnOptions::CConnOptions()
  110. : useLocalCursor (::useLocalCursor),
  111. useDesktopResize(::useDesktopResize),
  112. fullScreen(::fullScreen),
  113. fullColour(::fullColour),
  114. lowColourLevel(::lowColourLevel),
  115. preferredEncoding(encodingTight),
  116. autoSelect(::autoSelect),
  117. shared(::sharedConnection),
  118. desktopSize(::desktopSize.getData()),
  119. sendPtrEvents(::sendPtrEvents),
  120. sendKeyEvents(::sendKeyEvents),
  121. showToolbar(::showToolbar),
  122. clientCutText(::clientCutText),
  123. serverCutText(::serverCutText),
  124. disableWinKeys(::disableWinKeys),
  125. emulate3(::emulate3),
  126. pointerEventInterval(ptrEventInterval),
  127. protocol3_3(::protocol3_3),
  128. acceptBell(::acceptBell),
  129. autoScaling(::autoScaling),
  130. scale(::scale),
  131. monitor(::monitor.getData()),
  132. autoReconnect(::autoReconnect),
  133. customCompressLevel(::customCompressLevel),
  134. compressLevel(::compressLevel),
  135. noJpeg(::noJpeg),
  136. qualityLevel(::qualityLevel),
  137. passwordFile(::passwordFile.getData())
  138. {
  139. char *sectypes;
  140. if (autoSelect) {
  141. preferredEncoding = encodingTight;
  142. } else {
  143. CharArray encodingName(::preferredEncoding.getData());
  144. preferredEncoding = encodingNum(encodingName.buf);
  145. }
  146. setMenuKey(CharArray(::menuKey.getData()).buf);
  147. if (!::autoSelect.hasBeenSet()) {
  148. // Default to AutoSelect=0 if -PreferredEncoding or -FullColor is used
  149. autoSelect = (!::preferredEncoding.hasBeenSet()
  150. && !::fullColour.hasBeenSet()
  151. && !::fullColourAlias.hasBeenSet());
  152. }
  153. if (!::customCompressLevel.hasBeenSet()) {
  154. // Default to CustomCompressLevel=1 if CompressLevel is used.
  155. customCompressLevel = ::compressLevel.hasBeenSet();
  156. }
  157. sectypes = SecurityClient::secTypes.getDefaultStr();
  158. secTypes = parseSecTypes(sectypes);
  159. delete [] sectypes;
  160. }
  161. void CConnOptions::readFromFile(const char* filename) {
  162. FILE* f = fopen(filename, "r");
  163. if (!f)
  164. throw rdr::Exception("Failed to read configuration file");
  165. try {
  166. char line[4096];
  167. CharArray section;
  168. CharArray hostTmp;
  169. int portTmp = 0;
  170. while (!feof(f)) {
  171. // Read the next line
  172. if (!fgets(line, sizeof(line), f)) {
  173. if (feof(f))
  174. break;
  175. throw rdr::SystemException("fgets", ferror(f));
  176. }
  177. int len=strlen(line);
  178. if (line[len-1] == '\n') {
  179. line[len-1] = 0;
  180. len--;
  181. }
  182. // Process the line
  183. if (line[0] == ';') {
  184. // Comment
  185. } else if (line[0] == '[') {
  186. // Entering a new section
  187. if (!strSplit(&line[1], ']', &section.buf, 0))
  188. throw rdr::Exception("bad Section");
  189. } else {
  190. // Reading an option
  191. CharArray name;
  192. CharArray value;
  193. if (!strSplit(line, '=', &name.buf, &value.buf))
  194. throw rdr::Exception("bad Name/Value pair");
  195. if (stricmp(section.buf, "Connection") == 0) {
  196. if (stricmp(name.buf, "Host") == 0) {
  197. hostTmp.replaceBuf(value.takeBuf());
  198. } else if (stricmp(name.buf, "Port") == 0) {
  199. portTmp = atoi(value.buf);
  200. } else if (stricmp(name.buf, "UserName") == 0) {
  201. userName.replaceBuf(value.takeBuf());
  202. } else if (stricmp(name.buf, "Password") == 0) {
  203. ObfuscatedPasswd obfPwd;
  204. rdr::HexInStream::hexStrToBin(value.buf, (char**)&obfPwd.buf, &obfPwd.length);
  205. PlainPasswd passwd(obfPwd);
  206. password.replaceBuf(passwd.takeBuf());
  207. }
  208. } else if (stricmp(section.buf, "Options") == 0) {
  209. // V4 options
  210. if (stricmp(name.buf, "UseLocalCursor") == 0) {
  211. useLocalCursor = atoi(value.buf);
  212. } else if (stricmp(name.buf, "UseDesktopResize") == 0) {
  213. useDesktopResize = atoi(value.buf);
  214. } else if (stricmp(name.buf, "FullScreen") == 0) {
  215. fullScreen = atoi(value.buf);
  216. } else if (stricmp(name.buf, "FullColour") == 0) {
  217. fullColour = atoi(value.buf);
  218. } else if (stricmp(name.buf, "LowColourLevel") == 0) {
  219. lowColourLevel = atoi(value.buf);
  220. } else if (stricmp(name.buf, "PreferredEncoding") == 0) {
  221. preferredEncoding = encodingNum(value.buf);
  222. } else if ((stricmp(name.buf, "AutoDetect") == 0) ||
  223. (stricmp(name.buf, "AutoSelect") == 0)) {
  224. autoSelect = atoi(value.buf);
  225. } else if (stricmp(name.buf, "Shared") == 0) {
  226. shared = atoi(value.buf);
  227. } else if (stricmp(name.buf, "SendPtrEvents") == 0) {
  228. sendPtrEvents = atoi(value.buf);
  229. } else if (stricmp(name.buf, "SendKeyEvents") == 0) {
  230. sendKeyEvents = atoi(value.buf);
  231. } else if (stricmp(name.buf, "SendCutText") == 0) {
  232. clientCutText = atoi(value.buf);
  233. } else if (stricmp(name.buf, "AcceptCutText") == 0) {
  234. serverCutText = atoi(value.buf);
  235. } else if (stricmp(name.buf, "DisableWinKeys") == 0) {
  236. disableWinKeys = atoi(value.buf);
  237. } else if (stricmp(name.buf, "AcceptBell") == 0) {
  238. acceptBell = atoi(value.buf);
  239. } else if (stricmp(name.buf, "Emulate3") == 0) {
  240. emulate3 = atoi(value.buf);
  241. } else if (stricmp(name.buf, "ShowToolbar") == 0) {
  242. showToolbar = atoi(value.buf);
  243. } else if (stricmp(name.buf, "PointerEventInterval") == 0) {
  244. pointerEventInterval = atoi(value.buf);
  245. } else if (stricmp(name.buf, "Monitor") == 0) {
  246. monitor.replaceBuf(value.takeBuf());
  247. } else if (stricmp(name.buf, "MenuKey") == 0) {
  248. setMenuKey(value.buf);
  249. } else if (stricmp(name.buf, "AutoReconnect") == 0) {
  250. autoReconnect = atoi(value.buf);
  251. } else if (stricmp(name.buf, "CustomCompressLevel") == 0) {
  252. customCompressLevel = atoi(value.buf);
  253. } else if (stricmp(name.buf, "CompressLevel") == 0) {
  254. compressLevel = atoi(value.buf);
  255. } else if (stricmp(name.buf, "NoJPEG") == 0) {
  256. noJpeg = atoi(value.buf);
  257. } else if (stricmp(name.buf, "QualityLevel") == 0) {
  258. qualityLevel = atoi(value.buf);
  259. // Legacy options
  260. } else if (stricmp(name.buf, "Preferred_Encoding") == 0) {
  261. preferredEncoding = atoi(value.buf);
  262. } else if (stricmp(name.buf, "8bit") == 0) {
  263. fullColour = !atoi(value.buf);
  264. } else if (stricmp(name.buf, "FullScreen") == 0) {
  265. fullScreen = atoi(value.buf);
  266. } else if (stricmp(name.buf, "ViewOnly") == 0) {
  267. sendPtrEvents = sendKeyEvents = !atoi(value.buf);
  268. } else if (stricmp(name.buf, "DisableClipboard") == 0) {
  269. clientCutText = serverCutText = !atoi(value.buf);
  270. } else if (stricmp(name.buf, "AutoScaling") == 0) {
  271. autoScaling = atoi(value.buf);
  272. } else if (stricmp(name.buf, "Scale") == 0) {
  273. scale = atoi(value.buf);
  274. } else if (stricmp(name.buf, "SecurityTypes") == 0) {
  275. secTypes = parseSecTypes(value.buf);
  276. }
  277. }
  278. }
  279. }
  280. fclose(f); f=0;
  281. // Process the Host and Port
  282. if (hostTmp.buf) {
  283. int hostLen = strlen(hostTmp.buf) + 2 + 17;
  284. host.replaceBuf(new char[hostLen]);
  285. strCopy(host.buf, hostTmp.buf, hostLen);
  286. if (portTmp) {
  287. strncat(host.buf, "::", hostLen-1);
  288. char tmp[16];
  289. sprintf(tmp, "%d", portTmp);
  290. strncat(host.buf, tmp, hostLen-1);
  291. }
  292. }
  293. // If AutoSelect is enabled then override the preferred encoding
  294. if (autoSelect)
  295. preferredEncoding = encodingZRLE;
  296. setConfigFileName(filename);
  297. } catch (rdr::Exception&) {
  298. if (f) fclose(f);
  299. throw;
  300. }
  301. }
  302. void CConnOptions::writeToFile(const char* filename) {
  303. FILE* f = fopen(filename, "w");
  304. if (!f)
  305. throw rdr::Exception("Failed to write configuration file");
  306. try {
  307. // - Split server into host and port and save
  308. fprintf(f, "[Connection]\n");
  309. fprintf(f, "Host=%s\n", host.buf);
  310. if (userName.buf)
  311. fprintf(f, "UserName=%s\n", userName.buf);
  312. if (password.buf) {
  313. // - Warn the user before saving the password
  314. if (MsgBox(0, _T("Do you want to include the VNC Password in this configuration file?\n")
  315. _T("Storing the password is more convenient but poses a security risk."),
  316. MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING) == IDYES) {
  317. ObfuscatedPasswd obfPwd(password);
  318. CharArray obfuscatedHex(rdr::HexOutStream::binToHexStr(obfPwd.buf, obfPwd.length));
  319. fprintf(f, "Password=%s\n", obfuscatedHex.buf);
  320. }
  321. }
  322. // - Save the other options
  323. fprintf(f, "[Options]\n");
  324. fprintf(f, "UseLocalCursor=%d\n", (int)useLocalCursor);
  325. fprintf(f, "UseDesktopResize=%d\n", (int)useDesktopResize);
  326. fprintf(f, "FullScreen=%d\n", (int)fullScreen);
  327. fprintf(f, "FullColour=%d\n", (int)fullColour);
  328. fprintf(f, "LowColourLevel=%d\n", lowColourLevel);
  329. fprintf(f, "PreferredEncoding=%s\n", encodingName(preferredEncoding));
  330. fprintf(f, "AutoSelect=%d\n", (int)autoSelect);
  331. fprintf(f, "Shared=%d\n", (int)shared);
  332. fprintf(f, "SendPtrEvents=%d\n", (int)sendPtrEvents);
  333. fprintf(f, "SendKeyEvents=%d\n", (int)sendKeyEvents);
  334. fprintf(f, "SendCutText=%d\n", (int)clientCutText);
  335. fprintf(f, "AcceptCutText=%d\n", (int)serverCutText);
  336. fprintf(f, "DisableWinKeys=%d\n", (int)disableWinKeys);
  337. fprintf(f, "AcceptBell=%d\n", (int)acceptBell);
  338. fprintf(f, "Emulate3=%d\n", (int)emulate3);
  339. fprintf(f, "ShowToolbar=%d\n", (int)showToolbar);
  340. fprintf(f, "PointerEventInterval=%d\n", pointerEventInterval);
  341. if (monitor.buf)
  342. fprintf(f, "Monitor=%s\n", monitor.buf);
  343. fprintf(f, "MenuKey=%s\n", CharArray(menuKeyName()).buf);
  344. fprintf(f, "AutoReconnect=%d\n", (int)autoReconnect);
  345. fprintf(f, "CustomCompressLevel=%d\n", customCompressLevel);
  346. fprintf(f, "CompressLevel=%d\n", compressLevel);
  347. fprintf(f, "NoJPEG=%d\n", noJpeg);
  348. fprintf(f, "QualityLevel=%d\n", qualityLevel);
  349. fprintf(f, "AutoScaling=%d\n", (int)autoScaling);
  350. fprintf(f, "Scale=%d\n", scale);
  351. fprintf(f, "SecurityTypes=");
  352. std::list<rdr::U32>::iterator i;
  353. for (i = secTypes.begin(); i != secTypes.end(); i++)
  354. fprintf(f, "%s,", secTypeName(*i));
  355. fprintf(f, "\n");
  356. fclose(f); f=0;
  357. setConfigFileName(filename);
  358. } catch (rdr::Exception&) {
  359. if (f) fclose(f);
  360. throw;
  361. }
  362. }
  363. void CConnOptions::writeDefaults() {
  364. RegKey key;
  365. key.createKey(HKEY_CURRENT_USER, _T("Software\\TigerVNC\\VNCviewer4"));
  366. key.setBool(_T("UseLocalCursor"), useLocalCursor);
  367. key.setBool(_T("UseDesktopResize"), useDesktopResize);
  368. key.setBool(_T("FullScreen"), fullScreen);
  369. key.setBool(_T("FullColour"), fullColour);
  370. key.setInt(_T("LowColourLevel"), lowColourLevel);
  371. key.setString(_T("PreferredEncoding"), TStr(encodingName(preferredEncoding)));
  372. key.setBool(_T("AutoSelect"), autoSelect);
  373. key.setBool(_T("Shared"), shared);
  374. key.setBool(_T("SendPointerEvents"), sendPtrEvents);
  375. key.setBool(_T("SendKeyEvents"), sendKeyEvents);
  376. key.setBool(_T("ClientCutText"), clientCutText);
  377. key.setBool(_T("ServerCutText"), serverCutText);
  378. key.setBool(_T("DisableWinKeys"), disableWinKeys);
  379. key.setBool(_T("Protocol3.3"), protocol3_3);
  380. key.setBool(_T("AcceptBell"), acceptBell);
  381. key.setBool(_T("ShowToolbar"), showToolbar);
  382. key.setBool(_T("Emulate3"), emulate3);
  383. key.setInt(_T("PointerEventInterval"), pointerEventInterval);
  384. if (monitor.buf)
  385. key.setString(_T("Monitor"), TStr(monitor.buf));
  386. key.setString(_T("MenuKey"), TCharArray(menuKeyName()).buf);
  387. key.setBool(_T("AutoReconnect"), autoReconnect);
  388. key.setInt(_T("CustomCompressLevel"), customCompressLevel);
  389. key.setInt(_T("CompressLevel"), compressLevel);
  390. key.setInt(_T("NoJPEG"), noJpeg);
  391. key.setInt(_T("QualityLevel"), qualityLevel);
  392. key.setBool(_T("AutoScaling"), autoScaling);
  393. key.setInt(_T("Scale"), scale);
  394. }
  395. void CConnOptions::setUserName(const char* user) {userName.replaceBuf(strDup(user));}
  396. void CConnOptions::setPassword(const char* pwd) {password.replaceBuf(strDup(pwd));}
  397. void CConnOptions::setConfigFileName(const char* cfn) {configFileName.replaceBuf(strDup(cfn));}
  398. void CConnOptions::setHost(const char* h) {host.replaceBuf(strDup(h));}
  399. void CConnOptions::setMonitor(const char* m) {monitor.replaceBuf(strDup(m));}
  400. void CConnOptions::setMenuKey(const char* keyName) {
  401. if (!keyName[0]) {
  402. menuKey = 0;
  403. } else {
  404. menuKey = VK_F8;
  405. if (keyName[0] == 'F') {
  406. UINT fKey = atoi(&keyName[1]);
  407. if (fKey >= 1 && fKey <= 12)
  408. menuKey = fKey-1 + VK_F1;
  409. }
  410. }
  411. }
  412. char* CConnOptions::menuKeyName() {
  413. int fNum = (menuKey-VK_F1)+1;
  414. if (fNum<1 || fNum>12)
  415. return strDup("");
  416. CharArray menuKeyStr(4);
  417. sprintf(menuKeyStr.buf, "F%d", fNum);
  418. return menuKeyStr.takeBuf();
  419. }
  420. CConnOptions& CConnOptions::operator=(const CConnOptions& o) {
  421. useLocalCursor = o.useLocalCursor;
  422. useDesktopResize = o.useDesktopResize;
  423. fullScreen = o.fullScreen;
  424. fullColour = o.fullColour;
  425. lowColourLevel = o.lowColourLevel;
  426. preferredEncoding = o.preferredEncoding;
  427. autoSelect = o.autoSelect;
  428. shared = o.shared;
  429. sendPtrEvents = o.sendPtrEvents;
  430. sendKeyEvents = o.sendKeyEvents;
  431. clientCutText = o.clientCutText;
  432. serverCutText = o.serverCutText;
  433. disableWinKeys = o.disableWinKeys;
  434. emulate3 = o.emulate3;
  435. pointerEventInterval = o.pointerEventInterval;
  436. protocol3_3 = o.protocol3_3;
  437. acceptBell = o.acceptBell;
  438. showToolbar = o.showToolbar;
  439. setUserName(o.userName.buf);
  440. setPassword(o.password.buf);
  441. setConfigFileName(o.configFileName.buf);
  442. setHost(o.host.buf);
  443. setMonitor(o.monitor.buf);
  444. menuKey = o.menuKey;
  445. autoReconnect = o.autoReconnect;
  446. customCompressLevel = o.customCompressLevel;
  447. compressLevel = o.compressLevel;
  448. noJpeg = o.noJpeg;
  449. qualityLevel = o.qualityLevel;
  450. autoScaling = o.autoScaling;
  451. scale = o.scale;
  452. secTypes = o.secTypes;
  453. return *this;
  454. }