From de5865bcd6ce759fba2dde591fa3e517bb026d7f Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Sat, 7 Jul 2007 10:09:24 +0000 Subject: [PATCH] - fixes / improvements to regedit, see bug 2356 for details - patch by carlo bramix (carlo.bramix at libero it) - it should be noted that import_registry_file needs more work to support unicode files svn path=/trunk/; revision=27447 --- reactos/base/applications/regedit/childwnd.c | 29 +++- .../base/applications/regedit/lang/en-US.rc | 4 + .../base/applications/regedit/lang/it-IT.rc | 34 ++-- .../base/applications/regedit/lang/pt-PT.rc | 2 +- reactos/base/applications/regedit/listview.c | 163 ++++++++---------- reactos/base/applications/regedit/regproc.c | 20 ++- reactos/base/applications/regedit/security.c | 2 + 7 files changed, 139 insertions(+), 115 deletions(-) diff --git a/reactos/base/applications/regedit/childwnd.c b/reactos/base/applications/regedit/childwnd.c index 4e6b8161345..b880b4caae9 100644 --- a/reactos/base/applications/regedit/childwnd.c +++ b/reactos/base/applications/regedit/childwnd.c @@ -67,13 +67,18 @@ static void draw_splitbar(HWND hWnd, int x) static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy) { HDWP hdwp = BeginDeferWindowPos(2); - RECT rt; - SetRect(&rt, 0, 0, cx, cy); + RECT rt, rs; + SetRect(&rt, 0, 0, cx, cy); + cy = 0; + if (hStatusBar != NULL) { + GetWindowRect(hStatusBar, &rs); + cy = rs.bottom - rs.top + 8; + } cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2; DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left, 23, SWP_NOZORDER|SWP_NOACTIVATE); - DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + 25, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top - 30, SWP_NOZORDER|SWP_NOACTIVATE); - DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx , rt.top + 25, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + 25, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx , rt.top + 25, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); EndDeferWindowPos(hdwp); } @@ -276,6 +281,17 @@ LRESULT CALLBACK AddressBarProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar return CallWindowProc(oldwndproc, hwnd, uMsg, wParam, lParam); } +/* fix coords to top-left when SHIFT-F10 is pressed */ +void FixPointIfContext(POINTS *pt, HWND hWnd) +{ + if (pt->x == -1 && pt->y == -1) { + POINT p = { 0, 0 }; + ClientToScreen(hWnd, &p); + pt->x = (WORD)(p.x); + pt->y = (WORD)(p.y); + } +} + /******************************************************************************* * * FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG) @@ -527,6 +543,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa pt = MAKEPOINTS(lParam); cnt = ListView_GetSelectedCount(pChildWnd->hListWnd); i = ListView_GetNextItem(pChildWnd->hListWnd, -1, LVNI_FOCUSED | LVNI_SELECTED); + FixPointIfContext(&pt, pChildWnd->hListWnd); if(i == -1) { TrackPopupMenu(GetSubMenu(hPopupMenus, PM_NEW), TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL); @@ -566,7 +583,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa ScreenToClient(pChildWnd->hTreeWnd, &hti.pt); (void)TreeView_HitTest(pChildWnd->hTreeWnd, &hti); - if ((hti.flags & TVHT_ONITEM) != 0) + if ((hti.flags & TVHT_ONITEM) != 0 || (pt.x == -1 && pt.y == -1)) { hContextMenu = GetSubMenu(hPopupMenus, PM_TREECONTEXT); (void)TreeView_SelectItem(pChildWnd->hTreeWnd, hti.hItem); @@ -627,7 +644,7 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa s += _tcslen(s) + 1; } } - + FixPointIfContext(&pt, pChildWnd->hTreeWnd); TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, pChildWnd->hWnd, NULL); } } diff --git a/reactos/base/applications/regedit/lang/en-US.rc b/reactos/base/applications/regedit/lang/en-US.rc index e77a31437a9..e704114c0b2 100644 --- a/reactos/base/applications/regedit/lang/en-US.rc +++ b/reactos/base/applications/regedit/lang/en-US.rc @@ -135,6 +135,8 @@ BEGIN MENUITEM "&String Value", ID_EDIT_NEW_STRINGVALUE MENUITEM "&Binary Value", ID_EDIT_NEW_BINARYVALUE MENUITEM "&DWORD Value", ID_EDIT_NEW_DWORDVALUE + MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END END POPUP "" @@ -147,6 +149,8 @@ BEGIN MENUITEM "&String Value", ID_EDIT_NEW_STRINGVALUE MENUITEM "&Binary Value", ID_EDIT_NEW_BINARYVALUE MENUITEM "&DWORD Value", ID_EDIT_NEW_DWORDVALUE + MENUITEM "&Multi-String Value", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Expandable String Value", ID_EDIT_NEW_EXPANDABLESTRINGVALUE END MENUITEM "&Find", ID_EDIT_FIND MENUITEM SEPARATOR diff --git a/reactos/base/applications/regedit/lang/it-IT.rc b/reactos/base/applications/regedit/lang/it-IT.rc index e7ecbcd21ee..7f282c510fb 100644 --- a/reactos/base/applications/regedit/lang/it-IT.rc +++ b/reactos/base/applications/regedit/lang/it-IT.rc @@ -131,13 +131,17 @@ BEGIN END POPUP "" BEGIN - POPUP "&Nuova" + POPUP "&Nuovo" BEGIN MENUITEM "&Chiave", ID_EDIT_NEW_KEY MENUITEM SEPARATOR - MENUITEM "&Stringa", ID_EDIT_NEW_STRINGVALUE - MENUITEM "Valore &binario", ID_EDIT_NEW_BINARYVALUE - MENUITEM "Valore &DWORD", ID_EDIT_NEW_DWORDVALUE + MENUITEM "Valore &stringa", ID_EDIT_NEW_STRINGVALUE + MENUITEM "Valore &binario", ID_EDIT_NEW_BINARYVALUE + MENUITEM "Valore &DWORD", ID_EDIT_NEW_DWORDVALUE + MENUITEM "Valore &multi-stringa", ID_EDIT_NEW_MULTISTRINGVALUE + + MENUITEM "Valore stringa &espandibile", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + END END POPUP "" @@ -147,9 +151,13 @@ BEGIN BEGIN MENUITEM "&Chiave", ID_EDIT_NEW_KEY MENUITEM SEPARATOR - MENUITEM "&Stringa", ID_EDIT_NEW_STRINGVALUE - MENUITEM "Valore &binario", ID_EDIT_NEW_BINARYVALUE - MENUITEM "Valore &DWORD", ID_EDIT_NEW_DWORDVALUE + MENUITEM "Valore &stringa", ID_EDIT_NEW_STRINGVALUE + MENUITEM "Valore &binario", ID_EDIT_NEW_BINARYVALUE + MENUITEM "Valore &DWORD", ID_EDIT_NEW_DWORDVALUE + MENUITEM "Valore &multi-stringa", ID_EDIT_NEW_MULTISTRINGVALUE + + MENUITEM "Valore stringa &espandibile", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + END MENUITEM "&Trova", ID_EDIT_FIND MENUITEM SEPARATOR @@ -175,11 +183,11 @@ CAPTION "Edit String" FONT 8, "MS Shell Dlg" BEGIN LTEXT "Nome:",IDC_STATIC,5,5,119,8 - EDITTEXT IDC_VALUE_NAME,5,15,200,12, WS_BORDER | WS_TABSTOP | WS_DISABLED + EDITTEXT IDC_VALUE_NAME,5,15,239,12,ES_AUTOHSCROLL | ES_READONLY LTEXT "Dati:",IDC_STATIC,5,30,119,8 - EDITTEXT IDC_VALUE_DATA,5,40,200,12, WS_BORDER | WS_TABSTOP - DEFPUSHBUTTON "OK",IDOK,140,60,30,11,WS_GROUP - DEFPUSHBUTTON "Annulla",IDCANCEL,175,60,30,11,WS_GROUP + EDITTEXT IDC_VALUE_DATA,5,40,239,12 + DEFPUSHBUTTON "OK",IDOK,142,64,50,14,WS_GROUP + PUSHBUTTON "Annulla",IDCANCEL,196,64,50,14,WS_GROUP END IDD_EDIT_MULTI_STRING DIALOG 32, 24, 252, 174 @@ -191,7 +199,9 @@ BEGIN LTEXT "&Name:",IDC_STATIC,6,6,134,8 EDITTEXT IDC_VALUE_NAME,6,17,240,12,ES_AUTOHSCROLL | ES_READONLY LTEXT "&Dati:",IDC_STATIC,6,35,161,8 - EDITTEXT IDC_VALUE_DATA,6,46,240,102,ES_AUTOHSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL + EDITTEXT IDC_VALUE_DATA,6,46,240,102,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_VSCROLL DEFPUSHBUTTON "OK",IDOK,142,154,50,14 PUSHBUTTON "Annulla",IDCANCEL,196,154,50,14 END diff --git a/reactos/base/applications/regedit/lang/pt-PT.rc b/reactos/base/applications/regedit/lang/pt-PT.rc index dce104d1ccb..64909c06452 100644 --- a/reactos/base/applications/regedit/lang/pt-PT.rc +++ b/reactos/base/applications/regedit/lang/pt-PT.rc @@ -137,7 +137,7 @@ BEGIN LTEXT "Dados do valor:",IDC_STATIC,5,30,119,8 EDITTEXT IDC_VALUE_DATA,5,40,200,12, WS_BORDER | WS_TABSTOP DEFPUSHBUTTON "OK",IDOK,140,60,30,11,WS_GROUP - DEFPUSHBUTTON "Cancelar",IDCANCEL,175,60,30,11,WS_GROUP + PUSHBUTTON "Cancelar",IDCANCEL,175,60,30,11,WS_GROUP END /* diff --git a/reactos/base/applications/regedit/listview.c b/reactos/base/applications/regedit/listview.c index fcc0cb362b8..e4ffaece62f 100644 --- a/reactos/base/applications/regedit/listview.c +++ b/reactos/base/applications/regedit/listview.c @@ -42,52 +42,38 @@ typedef struct tagLINE_INFO static DWORD g_columnToSort = ~0UL; static BOOL g_invertSort = FALSE; -static LPTSTR g_valueName; #define MAX_LIST_COLUMNS (IDS_LIST_COLUMN_LAST - IDS_LIST_COLUMN_FIRST + 1) -static int default_column_widths[MAX_LIST_COLUMNS] = { 200, 175, 400 }; -static int column_alignment[MAX_LIST_COLUMNS] = { LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT }; +static const int default_column_widths[MAX_LIST_COLUMNS] = { 200, 175, 400 }; +static const int column_alignment[MAX_LIST_COLUMNS] = { LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT }; LPCTSTR GetValueName(HWND hwndLV, int iStartAt) { int item; - size_t len, maxLen; - LPTSTR newStr; LVITEM LVItem; PLINE_INFO lineinfo; - if (!g_valueName) g_valueName = HeapAlloc(GetProcessHeap(), 0, 1024); - if (!g_valueName) return NULL; - *g_valueName = 0; - maxLen = HeapSize(GetProcessHeap(), 0, g_valueName); - if (maxLen == -1) return NULL; - + /* + if a new item is inserted, then no allocation, + otherwise the heap block will be lost! + */ item = ListView_GetNextItem(hwndLV, iStartAt, LVNI_SELECTED); if (item == -1) return NULL; - LVItem.mask = LVIF_PARAM; + + /* + Should be always TRUE anyways + */ LVItem.iItem = item; - for(;;) - { - if(ListView_GetItem(hwndLV, &LVItem)) - { - lineinfo = (PLINE_INFO)LVItem.lParam; - if(!lineinfo->name) - { - *g_valueName = 0; - return g_valueName; - } - len = _tcslen(lineinfo->name); - if (len < maxLen - 1) break; - newStr = HeapReAlloc(GetProcessHeap(), 0, g_valueName, maxLen * 2); - if (!newStr) return NULL; - g_valueName = newStr; - maxLen *= 2; - } - else + LVItem.iSubItem = 0; + LVItem.mask = LVIF_PARAM; + if (ListView_GetItem(hwndLV, &LVItem) == FALSE) + return NULL; + + lineinfo = (PLINE_INFO)LVItem.lParam; + if (lineinfo == NULL) return NULL; - } - memcpy(g_valueName, lineinfo->name, sizeof(TCHAR) * (len + 1)); - return g_valueName; + + return lineinfo->name; } BOOL IsDefaultValue(HWND hwndLV, int i) @@ -110,11 +96,11 @@ BOOL IsDefaultValue(HWND hwndLV, int i) */ static void AddEntryToList(HWND hwndLV, LPTSTR Name, DWORD dwValType, void* ValBuf, DWORD dwCount, int Position, BOOL ValExists) { - LINE_INFO* linfo; + PLINE_INFO linfo; LVITEM item; int index; - linfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LINE_INFO) + dwCount); + linfo = (PLINE_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LINE_INFO) + dwCount); linfo->dwValType = dwValType; linfo->val_len = dwCount; if(dwCount > 0) @@ -402,69 +388,63 @@ BOOL ListWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result) g_pChildWnd->nFocusPanel = 0; break; case LVN_BEGINLABELEDIT: + Info = (NMLVDISPINFO*)lParam; + if(Info) { - PLINE_INFO lineinfo; - Info = (NMLVDISPINFO*)lParam; - if(Info) - { - lineinfo = (PLINE_INFO)Info->item.lParam; + PLINE_INFO lineinfo = (PLINE_INFO)Info->item.lParam; if(!lineinfo->name || !_tcscmp(lineinfo->name, _T(""))) { - *Result = TRUE; + *Result = TRUE; } else { - *Result = FALSE; + *Result = FALSE; } - } - else - *Result = TRUE; - return TRUE; } + else + *Result = TRUE; + return TRUE; case LVN_ENDLABELEDIT: + Info = (NMLVDISPINFO*)lParam; + if(Info && Info->item.pszText) { - PLINE_INFO lineinfo; - Info = (NMLVDISPINFO*)lParam; - if(Info && Info->item.pszText) - { - lineinfo = (PLINE_INFO)Info->item.lParam; + PLINE_INFO lineinfo = (PLINE_INFO)Info->item.lParam; if(!lineinfo->name || !_tcscmp(lineinfo->name, _T(""))) { - *Result = FALSE; + *Result = FALSE; } else { - //if((ret = RenameValue(lineinfo->name, Info->item.pszText)) != ERROR_SUCCESS) - { - TCHAR msg[128], caption[128]; + if(_tcslen(Info->item.pszText) == 0) + { + TCHAR msg[128], caption[128]; - LoadString(hInst, IDS_ERR_RENVAL_CAPTION, caption, sizeof(caption)/sizeof(TCHAR)); - if(_tcslen(Info->item.pszText) == 0) - { - LoadString(hInst, IDS_ERR_RENVAL_TOEMPTY, msg, sizeof(msg)/sizeof(TCHAR)); - MessageBox(0, msg, NULL, 0); - *Result = TRUE; - } - else - { - HKEY hKeyRoot; - LPCTSTR keyPath; - LONG lResult; - keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); - lResult = RegRenameValue(hKeyRoot, keyPath, Info->item.pszText, lineinfo->name); - if (lineinfo->name) - LocalFree(lineinfo->name); - lineinfo->name = _tcsdup(Info->item.pszText); - *Result = TRUE; - return (lResult == ERROR_SUCCESS); - } - } + LoadString(hInst, IDS_ERR_RENVAL_TOEMPTY, msg, sizeof(msg)/sizeof(TCHAR)); + LoadString(hInst, IDS_ERR_RENVAL_CAPTION, caption, sizeof(caption)/sizeof(TCHAR)); + MessageBox(0, msg, caption, 0); + *Result = TRUE; + } + else + { + HKEY hKeyRoot; + LPCTSTR keyPath; + LONG lResult; + + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); + lResult = RegRenameValue(hKeyRoot, keyPath, Info->item.pszText, lineinfo->name); + lineinfo->name = realloc(lineinfo->name, (_tcslen(Info->item.pszText)+1)*sizeof(TCHAR)); + if (lineinfo->name != NULL) + _tcscpy(lineinfo->name, Info->item.pszText); + + *Result = TRUE; + return (lResult == ERROR_SUCCESS); + } } - } - else - *Result = TRUE; - return TRUE; } + else + *Result = TRUE; + + return TRUE; } return FALSE; } @@ -493,13 +473,11 @@ fail: return NULL; } -void DestroyListView(HWND hwndLV) { +void DestroyListView(HWND hwndLV) +{ INT count, i; LVITEM item; - if (g_valueName) - HeapFree(GetProcessHeap(), 0, g_valueName); - count = ListView_GetItemCount(hwndLV); for (i = 0; i < count; i++) { item.mask = LVIF_PARAM; @@ -519,8 +497,6 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath) DWORD val_count; HKEY hNewKey; LONG errCode; - INT count, i; - LVITEM item; BOOL AddedDefault = FALSE; if (!hwndLV) return FALSE; @@ -528,14 +504,8 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath) (void)ListView_EditLabel(hwndLV, -1); SendMessage(hwndLV, WM_SETREDRAW, FALSE, 0); - count = ListView_GetItemCount(hwndLV); - for (i = 0; i < count; i++) { - item.mask = LVIF_PARAM; - item.iItem = i; - (void)ListView_GetItem(hwndLV, &item); - free(((LINE_INFO*)item.lParam)->name); - HeapFree(GetProcessHeap(), 0, (void*)item.lParam); - } + DestroyListView(hwndLV); + g_columnToSort = ~0UL; (void)ListView_DeleteAllItems(hwndLV); @@ -560,9 +530,12 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath) /* } */ /* dwValSize = max_val_size; */ while (RegEnumValue(hNewKey, dwIndex, ValName, &dwValNameLen, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) { + /* Remove unwanted path from key name */ + TCHAR *pLastBl = _tcsrchr(ValName, TEXT('\\')); + if (pLastBl != NULL) ++pLastBl; else pLastBl = ValName; /* Add a terminating 0 character. Usually this is only necessary for strings. */ ((TCHAR*)ValBuf)[dwValSize/sizeof(TCHAR)] = 0; - AddEntryToList(hwndLV, ValName, dwValType, ValBuf, dwValSize, -1, TRUE); + AddEntryToList(hwndLV, pLastBl, dwValType, ValBuf, dwValSize, -1, TRUE); dwValNameLen = max_val_name_len; dwValSize = max_val_size; dwValType = 0L; diff --git a/reactos/base/applications/regedit/regproc.c b/reactos/base/applications/regedit/regproc.c index 4201f4241e7..79427197bd6 100644 --- a/reactos/base/applications/regedit/regproc.c +++ b/reactos/base/applications/regedit/regproc.c @@ -696,6 +696,11 @@ void processSetValue(LPSTR line) line_idx++; val_name = line + line_idx; while (TRUE) { + /* check if the line is unterminated (otherwise it may loop forever!) */ + if (line[line_idx] == '\0') { + fprintf(stderr,"Warning! unrecognized line:\n%s\n", line); + return; + } else if (line[line_idx] == '\\') /* skip escaped character */ { line_idx += 2; @@ -1391,7 +1396,19 @@ BOOL import_registry_file(LPTSTR filename) FILE* reg_file = _tfopen(filename, _T("r")); if (reg_file) { - processRegLines(reg_file, doSetValue); + unsigned char ch1 = fgetc(reg_file); + unsigned char ch2 = fgetc(reg_file); + + /* detect UTF-16.LE or UTF-16.BE format */ + if ((ch1 == 0xff && ch2 == 0xfe) || + (ch1 == 0xfe && ch2 == 0xff)) { + /* TODO: implement support for UNICODE files! */ + } else { + /* restore read point to the first line */ + fseek(reg_file, 0L, SEEK_SET); + processRegLines(reg_file, doSetValue); + } + fclose(reg_file); return TRUE; } return FALSE; @@ -1850,3 +1867,4 @@ BOOL RegKeyGetName(LPTSTR pszDest, size_t iDestLength, HKEY hRootKey, LPCTSTR lp return TRUE; } + diff --git a/reactos/base/applications/regedit/security.c b/reactos/base/applications/regedit/security.c index 2d401129e9a..aab65bdcfc6 100644 --- a/reactos/base/applications/regedit/security.c +++ b/reactos/base/applications/regedit/security.c @@ -30,8 +30,10 @@ DEFINE_GUID(IID_IRegKeySecurity2, 0xc3ccfdb4, 0x6f88, 0x11d2, 0x00a3, 0xce,0x00, #endif /* FIXME: already defined in aclui.h - causing problems when compiling with MSVC/PSDK*/ +#ifndef _MSC_VER DEFINE_GUID(IID_IEffectivePermission, 0x3853dc76, 0x9f35, 0x407c, 0x0088, 0xa1,0xd1,0x93,0x44,0x36,0x5f,0xbc); DEFINE_GUID(IID_ISecurityObjectTypeInfo, 0xfc3066eb, 0x79ef, 0x444b, 0x0091, 0x11,0xd1,0x8a,0x75,0xeb,0xf2,0xfa); +#endif /****************************************************************************** Implementation of the IUnknown methods of CRegKeySecurity