Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/programs/oleview/details.c
4389 views
1
/*
2
* OleView (details.c)
3
*
4
* Copyright 2006 Piotr Caban
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include "main.h"
22
23
DETAILS details;
24
25
static void CreateRegRec(HKEY hKey, HTREEITEM parent, WCHAR *wszKeyName, BOOL addings)
26
{
27
int i=0, j, retEnum;
28
HKEY hCurKey;
29
DWORD lenName, lenData, valType;
30
WCHAR wszName[MAX_LOAD_STRING];
31
WCHAR wszData[MAX_LOAD_STRING];
32
WCHAR wszTree[MAX_LOAD_STRING];
33
TVINSERTSTRUCTW tvis;
34
HTREEITEM addPlace = parent;
35
36
tvis.item.mask = TVIF_TEXT;
37
tvis.item.cchTextMax = MAX_LOAD_STRING;
38
tvis.item.pszText = wszTree;
39
tvis.hInsertAfter = TVI_LAST;
40
tvis.hParent = parent;
41
42
while(TRUE)
43
{
44
lenName = ARRAY_SIZE(wszName);
45
lenData = sizeof(wszData);
46
47
retEnum = RegEnumValueW(hKey, i, wszName, &lenName,
48
NULL, &valType, (LPBYTE)wszData, &lenData);
49
50
if(retEnum != ERROR_SUCCESS)
51
{
52
if(!i && lstrlenW(wszKeyName) > 1)
53
{
54
tvis.item.pszText = wszKeyName;
55
addPlace = TreeView_InsertItemW(details.hReg, &tvis);
56
tvis.item.pszText = wszTree;
57
}
58
break;
59
}
60
61
if(valType == REG_BINARY)
62
{
63
WCHAR wszBuf[MAX_LOAD_STRING];
64
65
for(j=0; j<MAX_LOAD_STRING/3-1; j++)
66
wsprintfW(&wszBuf[3*j], L"%02X ", (int)((unsigned char)wszData[j]));
67
wszBuf[(lenData*3>=MAX_LOAD_STRING ? MAX_LOAD_STRING-1 : lenData*3)] = '\0';
68
lstrcpyW(wszData, wszBuf);
69
lstrcpyW(&wszData[MAX_LOAD_STRING-5], L"...");
70
}
71
72
if(lenName) wsprintfW(wszTree, L"%s [%s] = %s", wszKeyName, wszName, wszData);
73
else wsprintfW(wszTree, L"%s = %s", wszKeyName, wszData);
74
75
addPlace = TreeView_InsertItemW(details.hReg, &tvis);
76
77
if(addings && !wcscmp(wszName, L"AppID"))
78
{
79
lstrcpyW(wszTree, wszName);
80
memmove(&wszData[6], wszData, sizeof(WCHAR[MAX_LOAD_STRING-6]));
81
memcpy(wszData, L"CLSID\\",sizeof(WCHAR[6]));
82
83
if(RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey) != ERROR_SUCCESS)
84
{
85
i++;
86
continue;
87
}
88
89
tvis.hParent = TVI_ROOT;
90
tvis.hParent = TreeView_InsertItemW(details.hReg, &tvis);
91
92
lenName = sizeof(wszName);
93
RegQueryValueW(hCurKey, NULL, wszName, (LONG *)&lenName);
94
RegCloseKey(hCurKey);
95
96
wsprintfW(wszTree, L"%s = %s", &wszData[6], wszName);
97
98
SendMessageW(details.hReg, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
99
SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
100
101
tvis.hParent = parent;
102
}
103
i++;
104
}
105
106
i=-1;
107
108
while(TRUE)
109
{
110
i++;
111
112
if(RegEnumKeyW(hKey, i, wszName, ARRAY_SIZE(wszName)) != ERROR_SUCCESS) break;
113
114
if(RegOpenKeyW(hKey, wszName, &hCurKey) != ERROR_SUCCESS) continue;
115
116
CreateRegRec(hCurKey, addPlace, wszName, addings);
117
SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)addPlace);
118
119
if(addings && !wcscmp(wszName, L"ProgID"))
120
{
121
lenData = sizeof(wszData);
122
RegQueryValueW(hCurKey, NULL, wszData, (LONG *)&lenData);
123
RegCloseKey(hCurKey);
124
125
if(RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey) != ERROR_SUCCESS)
126
continue;
127
CreateRegRec(hCurKey, TVI_ROOT, wszData, FALSE);
128
}
129
else if(addings && !wcscmp(wszName, L"ProxyStubClsid32"))
130
{
131
lenData = sizeof(wszData);
132
133
RegQueryValueW(hCurKey, NULL, wszData, (LONG *)&lenData);
134
RegCloseKey(hCurKey);
135
136
RegOpenKeyW(HKEY_CLASSES_ROOT, L"CLSID", &hCurKey);
137
138
lenName = sizeof(wszName);
139
RegQueryValueW(hCurKey, NULL, wszName, (LONG *)&lenName);
140
141
tvis.hParent = TVI_ROOT;
142
wsprintfW(wszTree, L"CLSID = %s", wszName);
143
tvis.hParent = TreeView_InsertItemW(details.hReg, &tvis);
144
145
RegCloseKey(hCurKey);
146
147
memmove(&wszData[6], wszData, lenData);
148
memcpy(wszData, L"CLSID\\", sizeof(WCHAR[6]));
149
150
RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey);
151
152
CreateRegRec(hCurKey, tvis.hParent, &wszData[6], FALSE);
153
154
SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
155
tvis.hParent = parent;
156
}
157
else if(addings && !wcscmp(wszName, L"TypeLib"))
158
{
159
lenData = sizeof(wszData);
160
RegQueryValueW(hCurKey, NULL, wszData, (LONG *)&lenData);
161
RegCloseKey(hCurKey);
162
163
RegOpenKeyW(HKEY_CLASSES_ROOT, L"TypeLib", &hCurKey);
164
165
lenName = sizeof(wszName);
166
RegQueryValueW(hCurKey, NULL, wszName, (LONG *)&lenName);
167
168
tvis.hParent = TVI_ROOT;
169
wsprintfW(wszTree, L"TypeLib = %s", wszName);
170
tvis.hParent = TreeView_InsertItemW(details.hReg, &tvis);
171
172
RegCloseKey(hCurKey);
173
174
memmove(&wszData[8], wszData, lenData);
175
memcpy(wszData, L"TypeLib\\", sizeof(WCHAR[8]));
176
RegOpenKeyW(HKEY_CLASSES_ROOT, wszData, &hCurKey);
177
178
CreateRegRec(hCurKey, tvis.hParent, &wszData[8], FALSE);
179
180
SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)tvis.hParent);
181
tvis.hParent = parent;
182
}
183
RegCloseKey(hCurKey);
184
}
185
}
186
187
static void CreateReg(WCHAR *buffer)
188
{
189
HKEY hKey;
190
DWORD lenBuffer=-1, lastLenBuffer, lenTree;
191
WCHAR *path;
192
WCHAR wszTree[MAX_LOAD_STRING];
193
TVINSERTSTRUCTW tvis;
194
HTREEITEM addPlace = TVI_ROOT;
195
196
tvis.item.mask = TVIF_TEXT;
197
tvis.item.cchTextMax = MAX_LOAD_STRING;
198
tvis.item.pszText = wszTree;
199
tvis.hInsertAfter = TVI_LAST;
200
tvis.hParent = TVI_ROOT;
201
202
path = buffer;
203
while(TRUE)
204
{
205
while(*path != '\\' && *path != '\0') path += 1;
206
207
if(*path == '\\')
208
{
209
*path = '\0';
210
211
if(RegOpenKeyW(HKEY_CLASSES_ROOT, buffer, &hKey) != ERROR_SUCCESS)
212
return;
213
214
lastLenBuffer = lenBuffer+1;
215
lenBuffer = lstrlenW(buffer);
216
*path = '\\';
217
path += 1;
218
219
lenTree = sizeof(wszTree);
220
221
if(RegQueryValueW(hKey, NULL, wszTree, (LONG *)&lenTree) == ERROR_SUCCESS)
222
{
223
memmove(&wszTree[lenBuffer-lastLenBuffer+3], wszTree, lenTree);
224
memcpy(wszTree, &buffer[lastLenBuffer],
225
(lenBuffer - lastLenBuffer) * sizeof(WCHAR));
226
227
if(lenTree == 1) wszTree[lenBuffer-lastLenBuffer] = '\0';
228
else
229
{
230
wszTree[lenBuffer-lastLenBuffer] = ' ';
231
wszTree[lenBuffer-lastLenBuffer+1] = '=';
232
wszTree[lenBuffer-lastLenBuffer+2] = ' ';
233
}
234
235
addPlace = TreeView_InsertItemW(details.hReg, &tvis);
236
}
237
238
tvis.hParent = addPlace;
239
RegCloseKey(hKey);
240
}
241
else break;
242
}
243
244
if(RegOpenKeyW(HKEY_CLASSES_ROOT, buffer, &hKey) != ERROR_SUCCESS) return;
245
246
CreateRegRec(hKey, addPlace, &buffer[lenBuffer+1], TRUE);
247
248
RegCloseKey(hKey);
249
250
SendMessageW(details.hReg, TVM_EXPAND, TVE_EXPAND, (LPARAM)addPlace);
251
SendMessageW(details.hReg, TVM_ENSUREVISIBLE, 0, (LPARAM)addPlace);
252
}
253
254
void RefreshDetails(HTREEITEM item)
255
{
256
TVITEMW tvi;
257
WCHAR wszBuf[MAX_LOAD_STRING];
258
WCHAR wszStaticText[MAX_LOAD_STRING];
259
BOOL show;
260
261
memset(&tvi, 0, sizeof(TVITEMW));
262
memset(&wszStaticText, 0, sizeof(WCHAR[MAX_LOAD_STRING]));
263
tvi.mask = TVIF_TEXT;
264
tvi.hItem = item;
265
tvi.pszText = wszBuf;
266
tvi.cchTextMax = MAX_LOAD_STRING;
267
SendMessageW(globals.hTree, TVM_GETITEMW, 0, (LPARAM)&tvi);
268
269
if(tvi.lParam)
270
wsprintfW(wszStaticText, L"%s\n%s", tvi.pszText, ((ITEM_INFO *)tvi.lParam)->clsid);
271
else lstrcpyW(wszStaticText, tvi.pszText);
272
273
SetWindowTextW(details.hStatic, wszStaticText);
274
275
SendMessageW(details.hTab, TCM_SETCURSEL, 0, 0);
276
277
if(tvi.lParam && ((ITEM_INFO *)tvi.lParam)->cFlag & SHOWALL)
278
{
279
if(SendMessageW(details.hTab, TCM_GETITEMCOUNT, 0, 0) == 1)
280
{
281
TCITEMW tci;
282
memset(&tci, 0, sizeof(TCITEMW));
283
tci.mask = TCIF_TEXT;
284
tci.pszText = wszBuf;
285
tci.cchTextMax = ARRAY_SIZE(wszBuf);
286
287
LoadStringW(globals.hMainInst, IDS_TAB_IMPL, wszBuf, ARRAY_SIZE(wszBuf));
288
SendMessageW(details.hTab, TCM_INSERTITEMW, 1, (LPARAM)&tci);
289
290
LoadStringW(globals.hMainInst, IDS_TAB_ACTIV, wszBuf, ARRAY_SIZE(wszBuf));
291
SendMessageW(details.hTab, TCM_INSERTITEMW, 2, (LPARAM)&tci);
292
}
293
}
294
else
295
{
296
SendMessageW(details.hTab, TCM_DELETEITEM, 2, 0);
297
SendMessageW(details.hTab, TCM_DELETEITEM, 1, 0);
298
}
299
300
show = CreateRegPath(item, wszBuf, MAX_LOAD_STRING);
301
ShowWindow(details.hTab, show ? SW_SHOW : SW_HIDE);
302
303
/* FIXME Next line deals with TreeView_EnsureVisible bug */
304
SendMessageW(details.hReg, TVM_ENSUREVISIBLE, 0,
305
SendMessageW(details.hReg, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)TVI_ROOT));
306
SendMessageW(details.hReg, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
307
if(show) CreateReg(wszBuf);
308
}
309
310
static void CreateTabCtrl(HWND hWnd)
311
{
312
TCITEMW tci;
313
WCHAR buffer[MAX_LOAD_STRING];
314
315
memset(&tci, 0, sizeof(TCITEMW));
316
tci.mask = TCIF_TEXT;
317
tci.pszText = buffer;
318
tci.cchTextMax = ARRAY_SIZE(buffer);
319
320
details.hTab = CreateWindowW(WC_TABCONTROLW, NULL, WS_CHILD|WS_VISIBLE,
321
0, 0, 0, 0, hWnd, (HMENU)TAB_WINDOW, globals.hMainInst, NULL);
322
ShowWindow(details.hTab, SW_HIDE);
323
324
LoadStringW(globals.hMainInst, IDS_TAB_REG, buffer, ARRAY_SIZE(buffer));
325
SendMessageW(details.hTab, TCM_INSERTITEMW, 0, (LPARAM)&tci);
326
327
details.hReg = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, NULL,
328
WS_CHILD|WS_VISIBLE|TVS_HASLINES,
329
0, 0, 0, 0, details.hTab, NULL, globals.hMainInst, NULL);
330
}
331
332
static LRESULT CALLBACK DetailsProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
333
{
334
int sel;
335
336
switch(uMsg)
337
{
338
case WM_CREATE:
339
details.hStatic = CreateWindowW(L"Static", NULL, WS_CHILD|WS_VISIBLE,
340
0, 0, 0, 0, hWnd, NULL, globals.hMainInst, NULL);
341
CreateTabCtrl(hWnd);
342
break;
343
case WM_SIZE:
344
MoveWindow(details.hStatic, 0, 0, LOWORD(lParam), 40, TRUE);
345
MoveWindow(details.hTab, 3, 40, LOWORD(lParam)-6, HIWORD(lParam)-43, TRUE);
346
MoveWindow(details.hReg, 10, 34, LOWORD(lParam)-26,
347
HIWORD(lParam)-87, TRUE);
348
break;
349
case WM_NOTIFY:
350
if((int)wParam != TAB_WINDOW) break;
351
switch(((LPNMHDR)lParam)->code)
352
{
353
case TCN_SELCHANGE:
354
ShowWindow(details.hReg, SW_HIDE);
355
sel = SendMessageW(details.hTab, TCM_GETCURSEL, 0, 0);
356
357
if(sel==0) ShowWindow(details.hReg, SW_SHOW);
358
break;
359
}
360
break;
361
default:
362
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
363
}
364
return 0;
365
}
366
367
HWND CreateDetailsWindow(HINSTANCE hInst)
368
{
369
WNDCLASSW wcd;
370
371
memset(&wcd, 0, sizeof(WNDCLASSW));
372
wcd.lpfnWndProc = DetailsProc;
373
wcd.lpszClassName = L"DETAILS";
374
wcd.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
375
wcd.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
376
377
if(!RegisterClassW(&wcd)) return NULL;
378
379
globals.hDetails = CreateWindowExW(WS_EX_CLIENTEDGE, L"DETAILS", NULL,
380
WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, globals.hPaneWnd, NULL, hInst, NULL);
381
382
return globals.hDetails;
383
}
384
385