[MSTSC] Enable taking settings folder using SHGetFolderLocation instead of using...
[reactos.git] / reactos / base / applications / mstsc / settings.c
1
2 #include "precomp.h"
3
4 /* update NUM_SETTINGS in precomp.h */
5 LPWSTR lpSettings[NUM_SETTINGS] =
6 {
7 L"desktopwidth",
8 L"desktopheight",
9 L"session bpp",
10 L"full address",
11 L"username",
12 L"screen mode id",
13 };
14
15 VOID
16 SaveAllSettings(PINFO pInfo)
17 {
18 INT ret;
19 WCHAR szValue[MAXVALUE];
20
21 /* server */
22 if (GetDlgItemText(pInfo->hGeneralPage,
23 IDC_SERVERCOMBO,
24 szValue,
25 MAXVALUE))
26 {
27 SetStringToSettings(pInfo->pRdpSettings,
28 L"full address",
29 szValue);
30 }
31
32 /* resolution and fullscreen*/
33 ret = SendDlgItemMessage(pInfo->hDisplayPage,
34 IDC_GEOSLIDER,
35 TBM_GETPOS,
36 0,
37 0);
38 if (ret != -1)
39 {
40 SetIntegerToSettings(pInfo->pRdpSettings,
41 L"screen mode id",
42 (ret == SendDlgItemMessageW(pInfo->hDisplayPage, IDC_GEOSLIDER, TBM_GETRANGEMAX, 0, 0)) ? 2 : 1);
43 SetIntegerToSettings(pInfo->pRdpSettings,
44 L"desktopwidth",
45 pInfo->DisplayDeviceList->Resolutions[ret].dmPelsWidth);
46 SetIntegerToSettings(pInfo->pRdpSettings,
47 L"desktopheight",
48 pInfo->DisplayDeviceList->Resolutions[ret].dmPelsHeight);
49 }
50
51 /* bpp */
52 ret = SendDlgItemMessage(pInfo->hDisplayPage,
53 IDC_BPPCOMBO,
54 CB_GETCURSEL,
55 0,
56 0);
57 if (ret != CB_ERR)
58 {
59 ret = SendDlgItemMessage(pInfo->hDisplayPage,
60 IDC_BPPCOMBO,
61 CB_GETITEMDATA,
62 ret,
63 0);
64 if (ret != CB_ERR)
65 {
66 SetIntegerToSettings(pInfo->pRdpSettings,
67 L"session bpp",
68 ret);
69 }
70 }
71
72 /* user name */
73 if (GetDlgItemText(pInfo->hGeneralPage,
74 IDC_NAMEEDIT,
75 szValue,
76 MAXVALUE))
77 {
78 SetStringToSettings(pInfo->pRdpSettings,
79 L"username",
80 szValue);
81 }
82 }
83
84
85 BOOL
86 SetIntegerToSettings(PRDPSETTINGS pRdpSettings,
87 LPWSTR lpKey,
88 INT Value)
89 {
90 BOOL bRet = FALSE;
91
92 if (pRdpSettings)
93 {
94 INT i;
95
96 for (i = 0; i < pRdpSettings->NumSettings; i++)
97 {
98 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0)
99 {
100 if (pRdpSettings->pSettings[i].Type == 0)
101 pRdpSettings->pSettings[i].Type = L'i';
102
103 pRdpSettings->pSettings[i].Value.i = Value;
104 bRet = TRUE;
105 break;
106 }
107 }
108 }
109
110 return bRet;
111 }
112
113
114 BOOL
115 SetStringToSettings(PRDPSETTINGS pRdpSettings,
116 LPWSTR lpKey,
117 LPWSTR lpValue)
118 {
119 BOOL bRet = FALSE;
120
121 if (pRdpSettings)
122 {
123 INT i;
124
125 for (i = 0; i < pRdpSettings->NumSettings; i++)
126 {
127 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0)
128 {
129 if (pRdpSettings->pSettings[i].Type == 0)
130 pRdpSettings->pSettings[i].Type = L's';
131
132 wcscpy(pRdpSettings->pSettings[i].Value.s, lpValue);
133 bRet = TRUE;
134 break;
135 }
136 }
137 }
138
139 return bRet;
140 }
141
142
143 INT
144 GetIntegerFromSettings(PRDPSETTINGS pRdpSettings,
145 LPWSTR lpKey)
146 {
147 INT Value = -1;
148
149 if (pRdpSettings)
150 {
151 INT i;
152
153 for (i = 0; i < pRdpSettings->NumSettings; i++)
154 {
155 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0)
156 {
157 if (pRdpSettings->pSettings[i].Type == L'i')
158 {
159 Value = pRdpSettings->pSettings[i].Value.i;
160 break;
161 }
162 }
163 }
164 }
165
166 return Value;
167 }
168
169
170 LPWSTR
171 GetStringFromSettings(PRDPSETTINGS pRdpSettings,
172 LPWSTR lpKey)
173 {
174 LPWSTR lpValue = NULL;
175
176 if (pRdpSettings)
177 {
178 INT i;
179
180 for (i = 0; i < pRdpSettings->NumSettings; i++)
181 {
182 if (wcscmp(pRdpSettings->pSettings[i].Key, lpKey) == 0)
183 {
184 if (pRdpSettings->pSettings[i].Type == L's')
185 {
186 lpValue = pRdpSettings->pSettings[i].Value.s;
187 break;
188 }
189 }
190 }
191 }
192
193 return lpValue;
194 }
195
196
197 static BOOL
198 WriteRdpFile(HANDLE hFile,
199 PRDPSETTINGS pRdpSettings)
200 {
201 WCHAR line[MAXKEY + MAXVALUE + 4];
202 DWORD BytesToWrite, BytesWritten;
203 BOOL bRet;
204 INT i, k;
205
206 for (i = 0; i < pRdpSettings->NumSettings; i++)
207 {
208 /* only write out values in the lpSettings struct */
209 for (k = 0; k < NUM_SETTINGS; k++)
210 {
211 if (wcscmp(lpSettings[k], pRdpSettings->pSettings[i].Key) == 0)
212 {
213 if (pRdpSettings->pSettings[i].Type == L'i')
214 {
215 _snwprintf(line, MAXKEY + MAXVALUE + 4, L"%s:i:%d\r\n",
216 pRdpSettings->pSettings[i].Key,
217 pRdpSettings->pSettings[i].Value.i);
218 }
219 else
220 {
221 _snwprintf(line, MAXKEY + MAXVALUE + 4, L"%s:s:%s\r\n",
222 pRdpSettings->pSettings[i].Key,
223 pRdpSettings->pSettings[i].Value.s);
224 }
225
226 BytesToWrite = wcslen(line) * sizeof(WCHAR);
227
228 bRet = WriteFile(hFile,
229 line,
230 BytesToWrite,
231 &BytesWritten,
232 NULL);
233 if (!bRet || BytesWritten == 0)
234 return FALSE;
235 }
236 }
237 }
238
239 return TRUE;
240 }
241
242
243 static VOID
244 ParseSettings(PRDPSETTINGS pRdpSettings,
245 LPWSTR lpBuffer)
246 {
247 LPWSTR lpStr = lpBuffer;
248 WCHAR szSeps[] = L":\r\n";
249 WCHAR szNewline[] = L"\r\n";
250 LPWSTR lpToken;
251 BOOL bFound;
252 INT i;
253
254 /* move past unicode byte order */
255 if (lpStr[0] == 0xFEFF || lpStr[0] == 0xFFFE)
256 lpStr += 1;
257
258 lpToken = wcstok(lpStr, szSeps);
259 while (lpToken)
260 {
261 bFound = FALSE;
262
263 for (i = 0; i < pRdpSettings->NumSettings && !bFound; i++)
264 {
265 if (wcscmp(lpToken, pRdpSettings->pSettings[i].Key) == 0)
266 {
267 lpToken = wcstok(NULL, szSeps);
268 if (lpToken[0] == L'i')
269 {
270 pRdpSettings->pSettings[i].Type = lpToken[0];
271 lpToken = wcstok(NULL, szSeps);
272 if (lpToken != NULL)
273 pRdpSettings->pSettings[i].Value.i = _wtoi(lpToken);
274 }
275 else if (lpToken[0] == L's')
276 {
277 pRdpSettings->pSettings[i].Type = lpToken[0];
278 lpToken = wcstok(NULL, szNewline);
279 if (lpToken != NULL)
280 wcscpy(pRdpSettings->pSettings[i].Value.s, lpToken);
281 }
282 bFound = TRUE;
283 }
284 }
285
286 /* move past the type and value */
287 if (!bFound)
288 lpToken = wcstok(NULL, szNewline);
289
290 /* move to next key */
291 lpToken = wcstok(NULL, szSeps);
292 }
293 }
294
295
296 static LPWSTR
297 ReadRdpFile(HANDLE hFile)
298 {
299 LPWSTR lpBuffer = NULL;
300 DWORD BytesToRead, BytesRead;
301 BOOL bRes;
302
303 if (hFile)
304 {
305 BytesToRead = GetFileSize(hFile, NULL);
306 if (BytesToRead)
307 {
308 lpBuffer = HeapAlloc(GetProcessHeap(),
309 0,
310 BytesToRead + 2);
311 if (lpBuffer)
312 {
313 bRes = ReadFile(hFile,
314 lpBuffer,
315 BytesToRead,
316 &BytesRead,
317 NULL);
318 if (bRes)
319 {
320 lpBuffer[BytesRead / 2] = 0;
321 }
322 else
323 {
324 HeapFree(GetProcessHeap(),
325 0,
326 lpBuffer);
327
328 lpBuffer = NULL;
329 }
330 }
331 }
332 }
333
334 return lpBuffer;
335 }
336
337
338 static HANDLE
339 OpenRdpFile(LPWSTR path, BOOL bWrite)
340 {
341 HANDLE hFile = NULL;
342
343 if (path)
344 {
345 hFile = CreateFileW(path,
346 bWrite ? GENERIC_WRITE : GENERIC_READ,
347 0,
348 NULL,
349 bWrite ? CREATE_ALWAYS : OPEN_EXISTING,
350 FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN,
351 NULL);
352 }
353
354 return hFile;
355 }
356
357
358 static VOID
359 CloseRdpFile(HANDLE hFile)
360 {
361 if (hFile)
362 CloseHandle(hFile);
363 }
364
365
366 BOOL
367 SaveRdpSettingsToFile(LPWSTR lpFile,
368 PRDPSETTINGS pRdpSettings)
369 {
370 WCHAR pszPath[MAX_PATH];
371 HANDLE hFile;
372 BOOL bRet = FALSE;
373
374 /* use default file */
375 if (lpFile == NULL)
376 {
377 HRESULT hr;
378 LPITEMIDLIST lpidl= NULL;
379
380 hr = SHGetFolderLocation(NULL,
381 CSIDL_PERSONAL,
382 NULL,
383 0,
384 &lpidl);
385 if (hr == S_OK)
386 {
387 if (SHGetPathFromIDListW(lpidl, pszPath))
388 {
389 wcscat(pszPath, L"\\Default.rdp");
390 lpFile = pszPath;
391 CoTaskMemFree(lpidl);
392 }
393 }
394 }
395
396 if (lpFile)
397 {
398 hFile = OpenRdpFile(lpFile, TRUE);
399 if (hFile)
400 {
401 if (WriteRdpFile(hFile, pRdpSettings))
402 {
403 bRet = TRUE;
404 }
405
406 CloseRdpFile(hFile);
407 }
408 }
409
410 return bRet;
411 }
412
413
414 BOOL
415 LoadRdpSettingsFromFile(PRDPSETTINGS pRdpSettings,
416 LPWSTR lpFile)
417 {
418 WCHAR pszPath[MAX_PATH];
419 HANDLE hFile;
420 BOOL bRet = FALSE;
421
422 /* use default file */
423 if (lpFile == NULL)
424 {
425 HRESULT hr;
426 LPITEMIDLIST lpidl= NULL;
427
428 hr = SHGetFolderLocation(NULL,
429 CSIDL_PERSONAL,
430 NULL,
431 0,
432 &lpidl);
433 if (hr == S_OK)
434 {
435 if (SHGetPathFromIDListW(lpidl, pszPath))
436 {
437 wcscat(pszPath, L"\\Default.rdp");
438 lpFile = pszPath;
439 CoTaskMemFree(lpidl);
440 }
441 }
442 }
443
444 if (lpFile)
445 {
446 LPWSTR lpBuffer = NULL;
447
448 hFile = OpenRdpFile(lpFile, FALSE);
449 if (hFile)
450 {
451 lpBuffer = ReadRdpFile(hFile);
452 if (lpBuffer)
453 {
454 ParseSettings(pRdpSettings, lpBuffer);
455
456 HeapFree(GetProcessHeap(),
457 0,
458 lpBuffer);
459
460 bRet = TRUE;
461 }
462
463 CloseRdpFile(hFile);
464 }
465 }
466
467 return bRet;
468 }
469
470
471 BOOL
472 InitRdpSettings(PRDPSETTINGS pRdpSettings)
473 {
474 BOOL bRet = FALSE;
475
476 pRdpSettings->pSettings = HeapAlloc(GetProcessHeap(),
477 0,
478 sizeof(SETTINGS) * NUM_SETTINGS);
479 if (pRdpSettings->pSettings)
480 {
481 INT i;
482
483 for (i = 0; i < NUM_SETTINGS; i++)
484 {
485 wcscpy(pRdpSettings->pSettings[i].Key, lpSettings[i]);
486 pRdpSettings->pSettings[i].Type = (WCHAR)0;
487 pRdpSettings->pSettings[i].Value.i = 0;
488 }
489
490 pRdpSettings->NumSettings = NUM_SETTINGS;
491
492 bRet = TRUE;
493 }
494
495 return bRet;
496 }