Fix a warning.
[reactos.git] / reactos / subsys / system / regedit / edit.c
1 /*
2 * Registry editing UI functions.
3 *
4 * Copyright (C) 2003 Dimitrie O. Paun
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
22
23 #include <windows.h>
24 #include <tchar.h>
25 #include <commctrl.h>
26 #include <commdlg.h>
27 #include <cderr.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <shellapi.h>
31 #include <ctype.h>
32
33 #include "main.h"
34 #include "regproc.h"
35 #include "resource.h"
36 #include "hexedit.h"
37
38
39 typedef enum _EDIT_MODE
40 {
41 EDIT_MODE_DEC,
42 EDIT_MODE_HEX
43 } EDIT_MODE;
44
45
46 static const TCHAR* editValueName;
47 static TCHAR* stringValueData;
48 static PVOID binValueData;
49 static DWORD dwordValueData;
50 static DWORD valueDataLen;
51 static EDIT_MODE dwordEditMode = EDIT_MODE_HEX;
52
53
54 void error(HWND hwnd, INT resId, ...)
55 {
56 va_list ap;
57 TCHAR title[256];
58 TCHAR errfmt[1024];
59 TCHAR errstr[1024];
60 HINSTANCE hInstance;
61
62 hInstance = GetModuleHandle(0);
63
64 if (!LoadString(hInstance, IDS_ERROR, title, COUNT_OF(title)))
65 _tcscpy(title, _T("Error"));
66
67 if (!LoadString(hInstance, resId, errfmt, COUNT_OF(errfmt)))
68 _tcscpy(errfmt, _T("Unknown error string!"));
69
70 va_start(ap, resId);
71 _vsntprintf(errstr, COUNT_OF(errstr), errfmt, ap);
72 va_end(ap);
73
74 MessageBox(hwnd, errstr, title, MB_OK | MB_ICONERROR);
75 }
76
77 void warning(HWND hwnd, INT resId, ...)
78 {
79 va_list ap;
80 TCHAR title[256];
81 TCHAR errfmt[1024];
82 TCHAR errstr[1024];
83 HINSTANCE hInstance;
84
85 hInstance = GetModuleHandle(0);
86
87 if (!LoadString(hInstance, IDS_WARNING, title, COUNT_OF(title)))
88 _tcscpy(title, _T("Warning"));
89
90 if (!LoadString(hInstance, resId, errfmt, COUNT_OF(errfmt)))
91 _tcscpy(errfmt, _T("Unknown error string!"));
92
93 va_start(ap, resId);
94 _vsntprintf(errstr, COUNT_OF(errstr), errfmt, ap);
95 va_end(ap);
96
97 MessageBox(hwnd, errstr, title, MB_OK | MB_ICONSTOP);
98 }
99
100 INT_PTR CALLBACK modify_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
101 {
102 TCHAR* valueData;
103 HWND hwndValue;
104 int len;
105
106 switch(uMsg) {
107 case WM_INITDIALOG:
108 if(editValueName && _tcscmp(editValueName, _T("")))
109 {
110 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
111 }
112 else
113 {
114 TCHAR buffer[255];
115 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
116 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
117 }
118 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, stringValueData);
119 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
120 return FALSE;
121 case WM_COMMAND:
122 switch (LOWORD(wParam))
123 {
124 case IDOK:
125 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
126 {
127 if ((len = GetWindowTextLength(hwndValue)))
128 {
129 if (stringValueData)
130 {
131 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(TCHAR))))
132 {
133 stringValueData = valueData;
134 if (!GetWindowText(hwndValue, stringValueData, len + 1))
135 *stringValueData = 0;
136 }
137 }
138 else
139 {
140 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR))))
141 {
142 stringValueData = valueData;
143 if (!GetWindowText(hwndValue, stringValueData, len + 1))
144 *stringValueData = 0;
145 }
146 }
147 }
148 else
149 {
150 if (stringValueData)
151 *stringValueData = 0;
152 }
153 }
154 EndDialog(hwndDlg, IDOK);
155 break;
156 case IDCANCEL:
157 EndDialog(hwndDlg, IDCANCEL);
158 return TRUE;
159 }
160 }
161 return FALSE;
162 }
163
164
165 INT_PTR CALLBACK modify_multi_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
166 {
167 TCHAR* valueData;
168 HWND hwndValue;
169 int len;
170
171 switch(uMsg) {
172 case WM_INITDIALOG:
173 if(editValueName && _tcscmp(editValueName, _T("")))
174 {
175 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
176 }
177 else
178 {
179 TCHAR buffer[255];
180 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
181 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
182 }
183 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, stringValueData);
184 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
185 return FALSE;
186 case WM_COMMAND:
187 switch (LOWORD(wParam))
188 {
189 case IDOK:
190 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
191 {
192 if ((len = GetWindowTextLength(hwndValue)))
193 {
194 if (stringValueData)
195 {
196 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(TCHAR))))
197 {
198 stringValueData = valueData;
199 if (!GetWindowText(hwndValue, stringValueData, len + 1))
200 *stringValueData = 0;
201 }
202 }
203 else
204 {
205 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR))))
206 {
207 stringValueData = valueData;
208 if (!GetWindowText(hwndValue, stringValueData, len + 1))
209 *stringValueData = 0;
210 }
211 }
212 }
213 else
214 {
215 if (stringValueData)
216 *stringValueData = 0;
217 }
218 }
219 EndDialog(hwndDlg, IDOK);
220 break;
221 case IDCANCEL:
222 EndDialog(hwndDlg, IDCANCEL);
223 return TRUE;
224 }
225 }
226 return FALSE;
227 }
228
229
230 LRESULT CALLBACK DwordEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
231 {
232 WNDPROC oldwndproc;
233
234 oldwndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWL_USERDATA);
235
236 switch (uMsg)
237 {
238 case WM_CHAR:
239 if (dwordEditMode == EDIT_MODE_DEC)
240 {
241 if (isdigit(wParam & 0xff))
242 {
243 break;
244 }
245 else
246 {
247 return 0;
248 }
249 }
250 else if (dwordEditMode == EDIT_MODE_HEX)
251 {
252 if (isxdigit(wParam & 0xff))
253 {
254 break;
255 }
256 else
257 {
258 return 0;
259 }
260 }
261 else
262 {
263 break;
264 }
265 }
266
267 return CallWindowProc(oldwndproc, hwnd, uMsg, wParam, lParam);
268 }
269
270
271 INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
272 {
273 WNDPROC oldproc;
274 HWND hwndValue;
275 int len;
276 TCHAR ValueString[32];
277 LPTSTR Remainder;
278 DWORD Base;
279 DWORD Value = 0;
280
281 switch(uMsg) {
282 case WM_INITDIALOG:
283 dwordEditMode = EDIT_MODE_HEX;
284
285 /* subclass the edit control */
286 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
287 oldproc = (WNDPROC)GetWindowLongPtr(hwndValue, GWL_WNDPROC);
288 SetWindowLongPtr(hwndValue, GWL_USERDATA, (DWORD_PTR)oldproc);
289 SetWindowLongPtr(hwndValue, GWL_WNDPROC, (DWORD_PTR)DwordEditSubclassProc);
290
291 if(editValueName && _tcscmp(editValueName, _T("")))
292 {
293 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
294 }
295 else
296 {
297 TCHAR buffer[255];
298 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
299 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
300 }
301 CheckRadioButton (hwndDlg, IDC_FORMAT_HEX, IDC_FORMAT_DEC, IDC_FORMAT_HEX);
302 _stprintf (ValueString, _T("%lx"), dwordValueData);
303 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, ValueString);
304 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
305 return FALSE;
306
307 case WM_COMMAND:
308 switch (LOWORD(wParam))
309 {
310 case IDC_FORMAT_HEX:
311 if (HIWORD(wParam) == BN_CLICKED && dwordEditMode == EDIT_MODE_DEC)
312 {
313 dwordEditMode = EDIT_MODE_HEX;
314 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
315 {
316 if ((len = GetWindowTextLength(hwndValue)))
317 {
318 if (GetWindowText(hwndValue, ValueString, 32))
319 {
320 Value = _tcstoul (ValueString, &Remainder, 10);
321 }
322 }
323 }
324 _stprintf (ValueString, _T("%lx"), Value);
325 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, ValueString);
326 return TRUE;
327 }
328 break;
329
330 case IDC_FORMAT_DEC:
331 if (HIWORD(wParam) == BN_CLICKED && dwordEditMode == EDIT_MODE_HEX)
332 {
333 dwordEditMode = EDIT_MODE_DEC;
334 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
335 {
336 if ((len = GetWindowTextLength(hwndValue)))
337 {
338 if (GetWindowText(hwndValue, ValueString, 32))
339 {
340 Value = _tcstoul (ValueString, &Remainder, 16);
341 }
342 }
343 }
344 _stprintf (ValueString, _T("%lu"), Value);
345 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, ValueString);
346 return TRUE;
347 }
348 break;
349
350 case IDOK:
351 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
352 {
353 if ((len = GetWindowTextLength(hwndValue)))
354 {
355 if (!GetWindowText(hwndValue, ValueString, 32))
356 {
357 EndDialog(hwndDlg, IDCANCEL);
358 return TRUE;
359 }
360
361 Base = (dwordEditMode == EDIT_MODE_HEX) ? 16 : 10;
362 dwordValueData = _tcstoul (ValueString, &Remainder, Base);
363 }
364 else
365 {
366 EndDialog(hwndDlg, IDCANCEL);
367 return TRUE;
368 }
369 }
370 EndDialog(hwndDlg, IDOK);
371 return TRUE;
372
373 case IDCANCEL:
374 EndDialog(hwndDlg, IDCANCEL);
375 return TRUE;
376 }
377 }
378 return FALSE;
379 }
380
381
382 INT_PTR CALLBACK modify_binary_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
383 {
384 HWND hwndValue;
385 int len;
386
387 switch(uMsg) {
388 case WM_INITDIALOG:
389 if(editValueName && _tcscmp(editValueName, _T("")))
390 {
391 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
392 }
393 else
394 {
395 TCHAR buffer[255];
396 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
397 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
398 }
399 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
400 HexEdit_LoadBuffer(hwndValue, binValueData, valueDataLen);
401 /* reset the hex edit control's font */
402 SendMessage(hwndValue, WM_SETFONT, 0, 0);
403 SetFocus(hwndValue);
404 return FALSE;
405 case WM_COMMAND:
406 switch (LOWORD(wParam))
407 {
408 case IDOK:
409 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
410 {
411 len = HexEdit_GetBufferSize(hwndValue);
412 if (len != valueDataLen && len > 0)
413 {
414 binValueData = HeapReAlloc(GetProcessHeap(), 0, binValueData, len);
415 }
416 if (len > 0)
417 {
418 HexEdit_CopyBuffer(hwndValue, binValueData, len);
419 }
420 valueDataLen = len;
421 }
422 EndDialog(hwndDlg, IDOK);
423 break;
424 case IDCANCEL:
425 EndDialog(hwndDlg, IDCANCEL);
426 return TRUE;
427 }
428 }
429 return FALSE;
430 }
431
432
433 BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName, BOOL EditBin)
434 {
435 DWORD type;
436 LONG lRet;
437 BOOL result = FALSE;
438
439 if (!hKey)
440 return FALSE;
441
442 editValueName = valueName;
443
444 lRet = RegQueryValueEx(hKey, valueName, 0, &type, 0, &valueDataLen);
445 if (lRet != ERROR_SUCCESS && (!_tcscmp(valueName, _T("")) || valueName == NULL))
446 {
447 lRet = ERROR_SUCCESS; /* Allow editing of (Default) values which don't exist */
448 type = REG_SZ;
449 valueDataLen = 0;
450 stringValueData = NULL;
451 binValueData = NULL;
452 }
453
454 if (lRet != ERROR_SUCCESS)
455 {
456 error(hwnd, IDS_BAD_VALUE, valueName);
457 goto done;
458 }
459
460 if (EditBin == FALSE && ((type == REG_SZ) || (type == REG_EXPAND_SZ)))
461 {
462 if (valueDataLen > 0)
463 {
464 if (!(stringValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
465 {
466 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
467 goto done;
468 }
469 lRet = RegQueryValueEx(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
470 if (lRet != ERROR_SUCCESS)
471 {
472 error(hwnd, IDS_BAD_VALUE, valueName);
473 goto done;
474 }
475 }
476 else
477 {
478 stringValueData = NULL;
479 }
480
481 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_STRING), hwnd, modify_string_dlgproc) == IDOK)
482 {
483 if (stringValueData)
484 {
485 lRet = RegSetValueEx(hKey, valueName, 0, type, (LPBYTE)stringValueData, (_tcslen(stringValueData) + 1) * sizeof(TCHAR));
486 }
487 else
488 {
489 lRet = RegSetValueEx(hKey, valueName, 0, type, NULL, 0);
490 }
491 if (lRet == ERROR_SUCCESS)
492 result = TRUE;
493 }
494 }
495 else if (EditBin == FALSE && type == REG_MULTI_SZ)
496 {
497 if (valueDataLen > 0)
498 {
499 DWORD llen, listlen, nl_len;
500 LPTSTR src, lines = NULL;
501
502 if (!(stringValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
503 {
504 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
505 goto done;
506 }
507 lRet = RegQueryValueEx(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
508 if (lRet != ERROR_SUCCESS)
509 {
510 error(hwnd, IDS_BAD_VALUE, valueName);
511 goto done;
512 }
513
514 /* convert \0 to \r\n */
515 src = stringValueData;
516 nl_len = _tcslen(_T("\r\n")) * sizeof(TCHAR);
517 listlen = sizeof(TCHAR);
518 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, listlen + sizeof(TCHAR));
519 while(*src != _T('\0'))
520 {
521 llen = _tcslen(src);
522 if(llen == 0)
523 break;
524 listlen += (llen * sizeof(TCHAR)) + nl_len;
525 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, listlen);
526 _tcscat(lines, src);
527 _tcscat(lines, _T("\r\n"));
528 src += llen + 1;
529 }
530 HeapFree(GetProcessHeap(), 0, stringValueData);
531 stringValueData = lines;
532 }
533 else
534 {
535 stringValueData = NULL;
536 }
537
538 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_MULTI_STRING), hwnd, modify_multi_string_dlgproc) == IDOK)
539 {
540 if (stringValueData)
541 {
542 /* convert \r\n to \0 */
543 BOOL EmptyLines = FALSE;
544 LPTSTR src, lines, nl;
545 DWORD linechars, buflen, c_nl, dest;
546
547 src = stringValueData;
548 buflen = sizeof(TCHAR);
549 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buflen + sizeof(TCHAR));
550 c_nl = _tcslen(_T("\r\n"));
551 dest = 0;
552 while(*src != _T('\0'))
553 {
554 if((nl = _tcsstr(src, _T("\r\n"))))
555 {
556 linechars = nl - src;
557 if(nl == src)
558 {
559 EmptyLines = TRUE;
560 src = nl + c_nl;
561 continue;
562 }
563 }
564 else
565 {
566 linechars = _tcslen(src);
567 }
568 if(linechars > 0)
569 {
570 buflen += ((linechars + 1) * sizeof(TCHAR));
571 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, buflen);
572 memcpy((lines + dest), src, linechars * sizeof(TCHAR));
573 dest += linechars;
574 lines[dest++] = _T('\0');
575 }
576 else
577 {
578 EmptyLines = TRUE;
579 }
580 src += linechars + (nl != NULL ? c_nl : 0);
581 }
582 lines[++dest] = _T('\0');
583
584 if(EmptyLines)
585 {
586 warning(hwnd, IDS_MULTI_SZ_EMPTY_STRING);
587 }
588
589 lRet = RegSetValueEx(hKey, valueName, 0, type, (LPBYTE)lines, buflen);
590 HeapFree(GetProcessHeap(), 0, lines);
591 }
592 else
593 {
594 lRet = RegSetValueEx(hKey, valueName, 0, type, NULL, 0);
595 }
596 if (lRet == ERROR_SUCCESS)
597 result = TRUE;
598 }
599 }
600 else if (EditBin == FALSE && type == REG_DWORD)
601 {
602 lRet = RegQueryValueEx(hKey, valueName, 0, 0, (LPBYTE)&dwordValueData, &valueDataLen);
603 if (lRet != ERROR_SUCCESS)
604 {
605 error(hwnd, IDS_BAD_VALUE, valueName);
606 goto done;
607 }
608
609 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_DWORD), hwnd, modify_dword_dlgproc) == IDOK)
610 {
611 lRet = RegSetValueEx(hKey, valueName, 0, type, (LPBYTE)&dwordValueData, sizeof(DWORD));
612 if (lRet == ERROR_SUCCESS)
613 result = TRUE;
614 }
615 }
616 else if (EditBin == TRUE || type == REG_NONE || type == REG_BINARY)
617 {
618 #ifndef UNICODE
619 LPWSTR u_valuename;
620 int len_vname = lstrlen(valueName);
621
622 if(len_vname > 0)
623 {
624 if(!(u_valuename = HeapAlloc(GetProcessHeap(), 0, (len_vname + 1) * sizeof(WCHAR))))
625 {
626 error(hwnd, IDS_TOO_BIG_VALUE, len_vname);
627 goto done;
628 }
629 /* convert the ansi value name to an unicode string */
630 MultiByteToWideChar(CP_ACP, 0, valueName, -1, u_valuename, len_vname + 1);
631 valueDataLen *= sizeof(WCHAR);
632 }
633 else
634 u_valuename = L"";
635 #endif
636 if(valueDataLen > 0)
637 {
638 if(!(binValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
639 {
640 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
641 goto done;
642 }
643
644 /* force to use the unicode version, so editing strings in binary mode is correct */
645 lRet = RegQueryValueExW(hKey,
646 #ifndef UNICODE
647 u_valuename,
648 #else
649 valueName,
650 #endif
651 0, 0, (LPBYTE)binValueData, &valueDataLen);
652 if (lRet != ERROR_SUCCESS)
653 {
654 HeapFree(GetProcessHeap(), 0, binValueData);
655 #ifndef UNICODE
656 if(len_vname > 0)
657 HeapFree(GetProcessHeap(), 0, u_valuename);
658 #endif
659 error(hwnd, IDS_BAD_VALUE, valueName);
660 goto done;
661 }
662 }
663 else
664 {
665 binValueData = NULL;
666 }
667
668 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_BIN_DATA), hwnd, modify_binary_dlgproc) == IDOK)
669 {
670 /* force to use the unicode version, so editing strings in binary mode is correct */
671 lRet = RegSetValueExW(hKey,
672 #ifndef UNICODE
673 u_valuename,
674 #else
675 valueName,
676 #endif
677 0, type, (LPBYTE)binValueData, valueDataLen);
678 if (lRet == ERROR_SUCCESS)
679 result = TRUE;
680 }
681 if(binValueData != NULL)
682 HeapFree(GetProcessHeap(), 0, binValueData);
683 #ifndef UNICODE
684 if(len_vname > 0)
685 HeapFree(GetProcessHeap(), 0, u_valuename);
686 #endif
687 }
688 else
689 {
690 error(hwnd, IDS_UNSUPPORTED_TYPE, type);
691 }
692
693 done:
694 if (stringValueData)
695 HeapFree(GetProcessHeap(), 0, stringValueData);
696 stringValueData = NULL;
697
698 return result;
699 }