123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- /*
- * OleView (details.c)
- *
- * Copyright 2006 Piotr Caban
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
- #include "main.h"
- DETAILS details;
- static const WCHAR wszAppID[] = { 'A','p','p','I','D','\0' };
- static const WCHAR wszCLSID[] = { 'C','L','S','I','D','\0' };
- static const WCHAR wszProgID[] = { 'P','r','o','g','I','D','\0' };
- static const WCHAR wszProxyStubClsid32[] =
- { 'P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2','\0' };
- static const WCHAR wszTypeLib[] = { 'T','y','p','e','L','i','b','\0' };
- static void CreateRegRec(HKEY hKey, HTREEITEM parent, WCHAR *wszKeyName, BOOL addings)
- {
- int i=0, j, retEnum;
- HKEY hCurKey;
- DWORD lenName, lenData, valType;
- WCHAR wszName[MAX_LOAD_STRING];
- WCHAR wszData[MAX_LOAD_STRING];
- WCHAR wszTree[MAX_LOAD_STRING];
- const WCHAR wszBinary[] = { '%','0','2','X',' ','\0' };
- const WCHAR wszDots[] = { '.','.','.','\0' };
- const WCHAR wszFormat1[] = { '%','s',' ','[','%','s',']',' ','=',' ','%','s','\0' };
- const WCHAR wszFormat2[] = { '%','s',' ','=',' ','%','s','\0' };
- TVINSERTSTRUCTW tvis;
- HTREEITEM addPlace = parent;
- U(tvis).item.mask = TVIF_TEXT;
- U(tvis).item.cchTextMax = MAX_LOAD_STRING;
- U(tvis).item.pszText = wszTree;
- tvis.hInsertAfter = TVI_LAST;
- tvis.hParent = parent;
- while(TRUE)
- {
- lenName = ARRAY_SIZE(wszName);
- lenData = sizeof(wszData);
- retEnum = RegEnumValueW(hKey, i, wszName, &lenName,
- NULL, &valType, (LPBYTE)wszData, &lenData);
- if(retEnum != ERROR_SUCCESS)
- {
- if(!i && lstrlenW(wszKeyName) > 1)
- {
- U(tvis).item.pszText = wszKeyName;
- addPlace = TreeView_InsertItemW(details.hReg, &tvis);
- U(tvis).item.pszText = wszTree;
- }
- break;
- }
- if(valType == REG_BINARY)
- {
- WCHAR wszBuf[MAX_LOAD_STRING];
- for(j=0; j<MAX_LOAD_STRING/3-1; j++)
- wsprintfW(&wszBuf[3*j], wszBinary, (int)((unsigned char)wszData[j]));
- wszBuf[(lenData*3>=MAX_LOAD_STRING ? MAX_LOAD_STRING-1 : lenData*3)] = '\0';
- lstrcpyW(wszData, wszBuf);
- lstrcpyW(&wszData[MAX_LOAD_STRING-5], wszDots);
- }
- if(lenName) wsprintfW(wszTree, wszFormat1, wszKeyName, wszName, wszData);
- else wsprintfW(wszTree, wszFormat2, wszKeyName, wszData);
- addPlace = TreeView_InsertItemW(details.hReg, &tvis);
- if(addings && !memcmp(wszName, wszAppID, sizeof(WCHAR[6])))
- {
- lstrcpyW(wszTree, wszName);
- memmove(&wszData[6], wszData, sizeof(WCHAR[MAX_LOAD_STRING-6]));
- lstrcpyW(wszData, wszCLSID);
- wszData[5] = '\\';
- if(RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey) != ERROR_SUCCESS)
- {
- i++;
- continue;
- }
- tvis.hParent = TVI_ROOT;
- tvis.hParent = TreeView_InsertItemW(details.hReg, &tvis);
- lenName = sizeof(wszName);
- RegQueryValueW(hCurKey, NULL, wszName, (LONG *)&lenName);
- RegCloseKey(hCurKey);
- wsprintfW(wszTree, wszFormat2, &wszData[6], wszName);
- SendMessageW(details.hReg, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
- SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
- tvis.hParent = parent;
- }
- i++;
- }
- i=-1;
- while(TRUE)
- {
- i++;
- if(RegEnumKeyW(hKey, i, wszName, ARRAY_SIZE(wszName)) != ERROR_SUCCESS) break;
- if(RegOpenKeyW(hKey, wszName, &hCurKey) != ERROR_SUCCESS) continue;
- CreateRegRec(hCurKey, addPlace, wszName, addings);
- SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)addPlace);
- if(addings && !memcmp(wszName, wszProgID, sizeof(WCHAR[7])))
- {
- lenData = sizeof(wszData);
- RegQueryValueW(hCurKey, NULL, wszData, (LONG *)&lenData);
- RegCloseKey(hCurKey);
- if(RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey) != ERROR_SUCCESS)
- continue;
- CreateRegRec(hCurKey, TVI_ROOT, wszData, FALSE);
- }
- else if(addings && !memcmp(wszName, wszProxyStubClsid32, sizeof(WCHAR[17])))
- {
- lenData = sizeof(wszData);
- RegQueryValueW(hCurKey, NULL, wszData, (LONG *)&lenData);
- RegCloseKey(hCurKey);
- RegOpenKeyW(HKEY_CLASSES_ROOT, wszCLSID, &hCurKey);
- lenName = sizeof(wszName);
- RegQueryValueW(hCurKey, NULL, wszName, (LONG *)&lenName);
- tvis.hParent = TVI_ROOT;
- wsprintfW(wszTree, wszFormat2, wszCLSID, wszName);
- tvis.hParent = TreeView_InsertItemW(details.hReg, &tvis);
- RegCloseKey(hCurKey);
- memmove(&wszData[6], wszData, lenData);
- memcpy(wszData, wszCLSID, sizeof(WCHAR[6]));
- wszData[5] = '\\';
- RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey);
- CreateRegRec(hCurKey, tvis.hParent, &wszData[6], FALSE);
- SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
- tvis.hParent = parent;
- }
- else if(addings && !memcmp(wszName, wszTypeLib, sizeof(WCHAR[8])))
- {
- lenData = sizeof(wszData);
- RegQueryValueW(hCurKey, NULL, wszData, (LONG *)&lenData);
- RegCloseKey(hCurKey);
- RegOpenKeyW(HKEY_CLASSES_ROOT, wszTypeLib, &hCurKey);
- lenName = sizeof(wszName);
- RegQueryValueW(hCurKey, NULL, wszName, (LONG *)&lenName);
- tvis.hParent = TVI_ROOT;
- wsprintfW(wszTree, wszFormat2, wszTypeLib, wszName);
- tvis.hParent = TreeView_InsertItemW(details.hReg, &tvis);
- RegCloseKey(hCurKey);
- memmove(&wszData[8], wszData, lenData);
- memcpy(wszData, wszTypeLib, sizeof(WCHAR[8]));
- wszData[7] = '\\';
- RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey);
- CreateRegRec(hCurKey, tvis.hParent, &wszData[8], FALSE);
- SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
- tvis.hParent = parent;
- }
- RegCloseKey(hCurKey);
- }
- }
- static void CreateReg(WCHAR *buffer)
- {
- HKEY hKey;
- DWORD lenBuffer=-1, lastLenBuffer, lenTree;
- WCHAR *path;
- WCHAR wszTree[MAX_LOAD_STRING];
- TVINSERTSTRUCTW tvis;
- HTREEITEM addPlace = TVI_ROOT;
- U(tvis).item.mask = TVIF_TEXT;
- U(tvis).item.cchTextMax = MAX_LOAD_STRING;
- U(tvis).item.pszText = wszTree;
- tvis.hInsertAfter = TVI_LAST;
- tvis.hParent = TVI_ROOT;
- path = buffer;
- while(TRUE)
- {
- while(*path != '\\' && *path != '\0') path += 1;
- if(*path == '\\')
- {
- *path = '\0';
- if(RegOpenKeyW(HKEY_CLASSES_ROOT, buffer, &hKey) != ERROR_SUCCESS)
- return;
- lastLenBuffer = lenBuffer+1;
- lenBuffer = lstrlenW(buffer);
- *path = '\\';
- path += 1;
- lenTree = sizeof(wszTree);
- if(RegQueryValueW(hKey, NULL, wszTree, (LONG *)&lenTree) == ERROR_SUCCESS)
- {
- memmove(&wszTree[lenBuffer-lastLenBuffer+3], wszTree, lenTree);
- memcpy(wszTree, &buffer[lastLenBuffer],
- (lenBuffer - lastLenBuffer) * sizeof(WCHAR));
- if(lenTree == 1) wszTree[lenBuffer-lastLenBuffer] = '\0';
- else
- {
- wszTree[lenBuffer-lastLenBuffer] = ' ';
- wszTree[lenBuffer-lastLenBuffer+1] = '=';
- wszTree[lenBuffer-lastLenBuffer+2] = ' ';
- }
- addPlace = TreeView_InsertItemW(details.hReg, &tvis);
- }
- tvis.hParent = addPlace;
- RegCloseKey(hKey);
- }
- else break;
- }
- if(RegOpenKeyW(HKEY_CLASSES_ROOT, buffer, &hKey) != ERROR_SUCCESS) return;
- CreateRegRec(hKey, addPlace, &buffer[lenBuffer+1], TRUE);
- RegCloseKey(hKey);
- SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)addPlace);
- SendMessageW(details.hReg, TVM_ENSUREVISIBLE, 0, (LPARAM)addPlace);
- }
- void RefreshDetails(HTREEITEM item)
- {
- TVITEMW tvi;
- WCHAR wszBuf[MAX_LOAD_STRING];
- WCHAR wszStaticText[MAX_LOAD_STRING];
- const WCHAR wszFormat[] = { '%','s','\n','%','s','\0' };
- BOOL show;
- memset(&tvi, 0, sizeof(TVITEMW));
- memset(&wszStaticText, 0, sizeof(WCHAR[MAX_LOAD_STRING]));
- tvi.mask = TVIF_TEXT;
- tvi.hItem = item;
- tvi.pszText = wszBuf;
- tvi.cchTextMax = MAX_LOAD_STRING;
- SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
- if(tvi.lParam)
- wsprintfW(wszStaticText, wszFormat, tvi.pszText, ((ITEM_INFO *)tvi.lParam)->clsid);
- else lstrcpyW(wszStaticText, tvi.pszText);
- SetWindowTextW(details.hStatic, wszStaticText);
- SendMessageW(details.hTab, TCM_SETCURSEL, 0, 0);
- if(tvi.lParam && ((ITEM_INFO *)tvi.lParam)->cFlag & SHOWALL)
- {
- if(SendMessageW(details.hTab, TCM_GETITEMCOUNT, 0, 0) == 1)
- {
- TCITEMW tci;
- memset(&tci, 0, sizeof(TCITEMW));
- tci.mask = TCIF_TEXT;
- tci.pszText = wszBuf;
- tci.cchTextMax = ARRAY_SIZE(wszBuf);
- LoadStringW(globals.hMainInst, IDS_TAB_IMPL, wszBuf, ARRAY_SIZE(wszBuf));
- SendMessageW(details.hTab, TCM_INSERTITEMW, 1, (LPARAM)&tci);
- LoadStringW(globals.hMainInst, IDS_TAB_ACTIV, wszBuf, ARRAY_SIZE(wszBuf));
- SendMessageW(details.hTab, TCM_INSERTITEMW, 2, (LPARAM)&tci);
- }
- }
- else
- {
- SendMessageW(details.hTab, TCM_DELETEITEM, 2, 0);
- SendMessageW(details.hTab, TCM_DELETEITEM, 1, 0);
- }
- show = CreateRegPath(item, wszBuf, MAX_LOAD_STRING);
- ShowWindow(details.hTab, show ? SW_SHOW : SW_HIDE);
- /* FIXME Next line deals with TreeView_EnsureVisible bug */
- SendMessageW(details.hReg, TVM_ENSUREVISIBLE, 0,
- SendMessageW(details.hReg, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)TVI_ROOT));
- SendMessageW(details.hReg, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
- if(show) CreateReg(wszBuf);
- }
- static void CreateTabCtrl(HWND hWnd)
- {
- TCITEMW tci;
- WCHAR buffer[MAX_LOAD_STRING];
- memset(&tci, 0, sizeof(TCITEMW));
- tci.mask = TCIF_TEXT;
- tci.pszText = buffer;
- tci.cchTextMax = ARRAY_SIZE(buffer);
- details.hTab = CreateWindowW(WC_TABCONTROLW, NULL, WS_CHILD|WS_VISIBLE,
- 0, 0, 0, 0, hWnd, (HMENU)TAB_WINDOW, globals.hMainInst, NULL);
- ShowWindow(details.hTab, SW_HIDE);
- LoadStringW(globals.hMainInst, IDS_TAB_REG, buffer, ARRAY_SIZE(buffer));
- SendMessageW(details.hTab, TCM_INSERTITEMW, 0, (LPARAM)&tci);
- details.hReg = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, NULL,
- WS_CHILD|WS_VISIBLE|TVS_HASLINES,
- 0, 0, 0, 0, details.hTab, NULL, globals.hMainInst, NULL);
- }
- static LRESULT CALLBACK DetailsProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- int sel;
- switch(uMsg)
- {
- case WM_CREATE:
- {
- const WCHAR wszStatic[] = { 'S','t','a','t','i','c','\0' };
- details.hStatic = CreateWindowW(wszStatic, NULL, WS_CHILD|WS_VISIBLE,
- 0, 0, 0, 0, hWnd, NULL, globals.hMainInst, NULL);
- CreateTabCtrl(hWnd);
- }
- break;
- case WM_SIZE:
- MoveWindow(details.hStatic, 0, 0, LOWORD(lParam), 40, TRUE);
- MoveWindow(details.hTab, 3, 40, LOWORD(lParam)-6, HIWORD(lParam)-43, TRUE);
- MoveWindow(details.hReg, 10, 34, LOWORD(lParam)-26,
- HIWORD(lParam)-87, TRUE);
- break;
- case WM_NOTIFY:
- if((int)wParam != TAB_WINDOW) break;
- switch(((LPNMHDR)lParam)->code)
- {
- case TCN_SELCHANGE:
- ShowWindow(details.hReg, SW_HIDE);
- sel = SendMessageW(details.hTab, TCM_GETCURSEL, 0, 0);
- if(sel==0) ShowWindow(details.hReg, SW_SHOW);
- break;
- }
- break;
- default:
- return DefWindowProcW(hWnd, uMsg, wParam, lParam);
- }
- return 0;
- }
- HWND CreateDetailsWindow(HINSTANCE hInst)
- {
- WNDCLASSW wcd;
- const WCHAR wszDetailsClass[] = { 'D','E','T','A','I','L','S','\0' };
- memset(&wcd, 0, sizeof(WNDCLASSW));
- wcd.lpfnWndProc = DetailsProc;
- wcd.lpszClassName = wszDetailsClass;
- wcd.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcd.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
- if(!RegisterClassW(&wcd)) return NULL;
- globals.hDetails = CreateWindowExW(WS_EX_CLIENTEDGE, wszDetailsClass, NULL,
- WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, globals.hPaneWnd, NULL, hInst, NULL);
- return globals.hDetails;
- }
|