Release 941030
[wine] / misc / shell.c
1 /*
2  *                              Shell Library Functions
3  */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include "prototypes.h"
9 #include "windows.h"
10 #include "shell.h"
11 #include "stddebug.h"
12 /* #define DEBUG_REG */
13 /* #undef  DEBUG_REG */
14 #include "debug.h"
15
16
17 LPKEYSTRUCT     lphRootKey = NULL;
18
19 DECLARE_HANDLE(HDROP);
20
21 extern HINSTANCE hSysRes;
22
23 /*************************************************************************
24  *                              RegOpenKey              [SHELL.1]
25  */
26 LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
27 {
28         LPKEYSTRUCT     lpKey = lphRootKey;
29         LPSTR           ptr;
30         char            str[128];
31
32         dprintf_reg(stddeb, "RegOpenKey(%04X, %08X='%s', %08X)\n",
33                                                 hKey, lpSubKey, lpSubKey, lphKey);
34         if (lpKey == NULL) return ERROR_BADKEY;
35         if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
36         if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
37         if (hKey != HKEY_CLASSES_ROOT) {
38                 dprintf_reg(stddeb,"RegOpenKey // specific key = %04X !\n", hKey);
39                 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
40                 }
41         while ( (ptr = strchr(lpSubKey, '\\')) != NULL ) {
42                 strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey);
43                 str[(LONG)ptr - (LONG)lpSubKey] = '\0';
44                 lpSubKey = ptr + 1;
45                 dprintf_reg(stddeb,"RegOpenKey // next level '%s' !\n", str);
46                 while(TRUE) {
47                         dprintf_reg(stddeb,"RegOpenKey // '%s' <-> '%s' !\n", str, lpKey->lpSubKey);
48                         if (lpKey->lpSubKey != NULL && lpKey->lpSubKey[0] != '\0' &&
49                                 strcmp(lpKey->lpSubKey, str) == 0) {
50                                 lpKey = lpKey->lpSubLvl;
51                                 if (lpKey == NULL) {
52                                         printf("RegOpenKey // can't find subkey '%s' !\n", str);
53                                         return ERROR_BADKEY;
54                                         }
55                                 break;
56                                 }
57                         if (lpKey->lpNextKey == NULL) {
58                                 printf("RegOpenKey // can't find subkey '%s' !\n", str);
59                                 return ERROR_BADKEY;
60                                 }
61                         lpKey = lpKey->lpNextKey;
62                         }
63                 }
64         while(TRUE) {
65                 if (lpKey->lpSubKey != NULL && 
66                         strcmp(lpKey->lpSubKey, lpSubKey) == 0) break;
67                 if (lpKey->lpNextKey == NULL) {
68                         printf("RegOpenKey // can't find subkey '%s' !\n", str);
69                         return ERROR_BADKEY;
70                         }
71                 lpKey = lpKey->lpNextKey;
72                 }
73         *lphKey = lpKey->hKey;
74         dprintf_reg(stddeb,"RegOpenKey // return hKey=%04X !\n", lpKey->hKey);
75         return ERROR_SUCCESS;
76 }
77
78
79 /*************************************************************************
80  *                              RegCreateKey            [SHELL.2]
81  */
82 LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
83 {
84         HKEY            hNewKey;
85         LPKEYSTRUCT     lpNewKey;
86         LPKEYSTRUCT     lpKey = lphRootKey;
87         LPKEYSTRUCT     lpPrevKey;
88         LONG            dwRet;
89         LPSTR           ptr;
90         char            str[128];
91         dprintf_reg(stddeb, "RegCreateKey(%04X, '%s', %08X)\n", hKey, lpSubKey, lphKey);
92         if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
93         if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
94         if (hKey != HKEY_CLASSES_ROOT) {
95                 dprintf_reg(stddeb,"RegCreateKey // specific key = %04X !\n", hKey);
96                 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
97                 }
98         while ( (ptr = strchr(lpSubKey, '\\')) != NULL ) {
99                 strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey);
100                 str[(LONG)ptr - (LONG)lpSubKey] = '\0';
101                 lpSubKey = ptr + 1;
102                 dprintf_reg(stddeb,"RegCreateKey // next level '%s' !\n", str);
103                 lpPrevKey = lpKey;
104                 while(TRUE) {
105                         dprintf_reg(stddeb,"RegCreateKey // '%s' <-> '%s' !\n", str, lpKey->lpSubKey);
106                         if (lpKey->lpSubKey != NULL &&
107                                 strcmp(lpKey->lpSubKey, str) == 0) {
108                                 if (lpKey->lpSubLvl == NULL) {
109                                         dprintf_reg(stddeb,"RegCreateKey // '%s' found !\n", str);
110                                         if ( (ptr = strchr(lpSubKey, '\\')) != NULL ) {
111                                                 strncpy(str, lpSubKey, (LONG)ptr - (LONG)lpSubKey);
112                                                 str[(LONG)ptr - (LONG)lpSubKey] = '\0';
113                                                 lpSubKey = ptr + 1;
114                                                 }
115                                         else
116                                                 strcpy(str, lpSubKey);
117                                         dwRet = RegCreateKey(lpKey->hKey, str, &hNewKey);
118                                         if (dwRet != ERROR_SUCCESS) {
119                                                 printf("RegCreateKey // can't create subkey '%s' !\n", str);
120                                                 return dwRet;
121                                                 }
122                                         lpKey->lpSubLvl = (LPKEYSTRUCT)GlobalLock(hNewKey);
123                                         }
124                                 lpKey = lpKey->lpSubLvl;
125                                 break;
126                                 }
127                         if (lpKey->lpNextKey == NULL) {
128                                 dwRet = RegCreateKey(lpPrevKey->hKey, str, &hNewKey);
129                                 if (dwRet != ERROR_SUCCESS) {
130                                         printf("RegCreateKey // can't create subkey '%s' !\n", str);
131                                         return dwRet;
132                                         }
133                                 lpKey = (LPKEYSTRUCT)GlobalLock(hNewKey);
134                                 break;
135                                 }
136                         lpKey = lpKey->lpNextKey;
137                         }
138                 }
139         hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT));
140         lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
141         if (lpNewKey == NULL) {
142                 printf("RegCreateKey // Can't alloc new key !\n");
143                 return ERROR_OUTOFMEMORY;
144                 }
145         if (lphRootKey == NULL) {
146                 lphRootKey = lpNewKey;
147                 lpNewKey->lpPrevKey = NULL;
148                 }
149         else {
150                 lpKey->lpNextKey = lpNewKey;
151                 lpNewKey->lpPrevKey = lpKey;
152                 }
153         lpNewKey->hKey = hNewKey;
154         lpNewKey->lpSubKey = malloc(strlen(lpSubKey) + 1);
155         if (lpNewKey->lpSubKey == NULL) {
156                 printf("RegCreateKey // Can't alloc key string !\n");
157                 return ERROR_OUTOFMEMORY;
158                 }
159         strcpy(lpNewKey->lpSubKey, lpSubKey);
160         lpNewKey->dwType = 0;
161         lpNewKey->lpValue = NULL;
162         lpNewKey->lpNextKey = NULL;
163         lpNewKey->lpSubLvl = NULL;
164         *lphKey = hNewKey;
165         dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%04X !\n", lpSubKey, hNewKey);
166         return ERROR_SUCCESS;
167 }
168
169
170 /*************************************************************************
171  *                              RegCloseKey             [SHELL.3]
172  */
173 LONG RegCloseKey(HKEY hKey)
174 {
175         dprintf_reg(stdnimp, "EMPTY STUB !!! RegCloseKey(%04X);\n", hKey);
176         return ERROR_INVALID_PARAMETER;
177 }
178
179
180 /*************************************************************************
181  *                              RegDeleteKey            [SHELL.4]
182  */
183 LONG RegDeleteKey(HKEY hKey, LPCSTR lpSubKey)
184 {
185         dprintf_reg(stdnimp, "EMPTY STUB !!! RegDeleteKey(%04X, '%s');\n", 
186                                                                                                 hKey, lpSubKey);
187         return ERROR_INVALID_PARAMETER;
188 }
189
190
191 /*************************************************************************
192  *                              RegSetValue             [SHELL.5]
193  */
194 LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType, 
195                                         LPCSTR lpVal, DWORD dwIgnored)
196 {
197         HKEY            hRetKey;
198         LPKEYSTRUCT     lpKey;
199         LONG            dwRet;
200         dprintf_reg(stddeb, "RegSetValue(%04X, '%s', %08X, '%s', %08X);\n",
201                                                 hKey, lpSubKey, dwType, lpVal, dwIgnored);
202         if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
203         if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
204         if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
205                 dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
206                 if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
207                         fprintf(stderr, "RegSetValue // key creation error %04X !\n", dwRet);
208                         return dwRet;
209                         }
210                 }
211         lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
212         if (lpKey == NULL) return ERROR_BADKEY;
213         if (lpKey->lpValue != NULL) free(lpKey->lpValue);
214         lpKey->lpValue = malloc(strlen(lpVal) + 1);
215         strcpy(lpKey->lpValue, lpVal);
216         dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpVal);
217         return ERROR_SUCCESS;
218 }
219
220
221 /*************************************************************************
222  *                              RegQueryValue           [SHELL.6]
223  */
224 LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb)
225 {
226         HKEY            hRetKey;
227         LPKEYSTRUCT     lpKey;
228         LONG            dwRet;
229         int                     size;
230         dprintf_reg(stddeb, "RegQueryValue(%04X, '%s', %08X, %08X);\n",
231                                                         hKey, lpSubKey, lpVal, lpcb);
232         if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
233         if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
234         if (lpcb == NULL) return ERROR_INVALID_PARAMETER;
235         if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
236                 fprintf(stderr, "RegQueryValue // key not found !\n");
237                 return dwRet;
238                 }
239         lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
240         if (lpKey == NULL) return ERROR_BADKEY;
241         if (lpKey->lpValue != NULL) {
242                 size = min(strlen(lpKey->lpValue), *lpcb);
243                 strncpy(lpVal, lpKey->lpValue, size);
244                 *lpcb = (LONG)size;
245                 }
246         else {
247                 lpVal[0] = '\0';
248                 *lpcb = (LONG)0;
249                 }
250         dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal);
251         return ERROR_SUCCESS;
252 }
253
254
255 /*************************************************************************
256  *                              RegEnumKey              [SHELL.7]
257  */
258 LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize)
259 {
260         dprintf_reg(stdnimp, "RegEnumKey : Empty Stub !!!\n");
261         return ERROR_INVALID_PARAMETER;
262 }
263
264 /*************************************************************************
265  *                              DragAcceptFiles         [SHELL.9]
266  */
267 void DragAcceptFiles(HWND hWnd, BOOL b)
268 {
269         dprintf_reg(stdnimp, "DragAcceptFiles : Empty Stub !!!\n");
270 }
271
272
273 /*************************************************************************
274  *                              DragQueryFile           [SHELL.11]
275  */
276 void DragQueryFile(HDROP h, UINT u, LPSTR u2, UINT u3)
277 {
278         dprintf_reg(stdnimp, "DragQueryFile : Empty Stub !!!\n");
279
280 }
281
282
283 /*************************************************************************
284  *                              DragFinish              [SHELL.12]
285  */
286 void DragFinish(HDROP h)
287 {
288         dprintf_reg(stdnimp, "DragFinish : Empty Stub !!!\n");
289
290 }
291
292
293 /*************************************************************************
294  *                              DragQueryPoint          [SHELL.13]
295  */
296 BOOL DragQueryPoint(HDROP h, POINT FAR *p)
297 {
298         dprintf_reg(stdnimp, "DragQueryPoinyt : Empty Stub !!!\n");
299         return FALSE;
300 }
301
302
303 /*************************************************************************
304  *                              ShellExecute            [SHELL.20]
305  */
306 HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int iShowCmd)
307 {
308         dprintf_reg(stdnimp, "ShellExecute // hWnd=%04X\n", hWnd);
309         dprintf_reg(stdnimp, "ShellExecute // lpOperation='%s'\n", lpOperation);
310         dprintf_reg(stdnimp, "ShellExecute // lpFile='%s'\n", lpFile);
311         dprintf_reg(stdnimp, "ShellExecute // lpParameters='%s'\n", lpParameters);
312         dprintf_reg(stdnimp, "ShellExecute // lpDirectory='%s'\n", lpDirectory);
313         dprintf_reg(stdnimp, "ShellExecute // iShowCmd=%04X\n", iShowCmd);
314         return 2; /* file not found */
315 }
316
317
318 /*************************************************************************
319  *                              FindExecutable          [SHELL.21]
320  */
321 HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
322 {
323         dprintf_reg(stdnimp, "FindExecutable : Empty Stub !!!\n");
324
325 }
326
327 char AppName[256], AppMisc[256];
328 INT AboutDlgProc(HWND hWnd, WORD msg, WORD wParam, LONG lParam);
329
330 /*************************************************************************
331  *                              ShellAbout              [SHELL.22]
332  */
333 INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
334 {
335 /*      fprintf(stderr, "ShellAbout ! (%s, %s)\n", szApp, szOtherStuff);*/
336
337         if (szApp)
338                 strcpy(AppName, szApp);
339         else
340                 *AppName = 0;
341
342         if (szOtherStuff)
343                 strcpy(AppMisc, szOtherStuff);
344         else
345                 *AppMisc = 0;
346
347         return DialogBox(hSysRes, "SHELL_ABOUT_MSGBOX", hWnd, (WNDPROC)AboutDlgProc);
348 }
349
350
351 /*************************************************************************
352  *                              AboutDlgProc            [SHELL.33]
353  */
354 INT AboutDlgProc(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
355 {
356         char temp[256];
357
358         switch(msg) {
359         case WM_INITDIALOG:
360                 sprintf(temp, "About %s", AppName);
361                 SetWindowText(hWnd, temp);
362                 SetDlgItemText(hWnd, 100, AppMisc);
363                 break;
364
365         case WM_COMMAND:
366                 switch (wParam) {
367                 case IDOK:
368                         EndDialog(hWnd, TRUE);
369                         return TRUE;
370                 }
371         }
372         return FALSE;
373 }
374
375 /*************************************************************************
376  *                              ExtractIcon             [SHELL.34]
377  */
378 HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
379 {
380         int             count;
381         HICON   hIcon = 0;
382         HINSTANCE hInst2 = hInst;
383         dprintf_reg(stddeb, "ExtractIcon(%04X, '%s', %d\n", 
384                         hInst, lpszExeFileName, nIconIndex);
385         if (lpszExeFileName != NULL) {
386                 hInst2 = LoadLibrary(lpszExeFileName);
387                 }
388         if (hInst2 != 0 && nIconIndex == (UINT)-1) {
389                 count = GetRsrcCount(hInst2, NE_RSCTYPE_GROUP_ICON);
390                 dprintf_reg(stddeb, "ExtractIcon // '%s' has %d icons !\n", lpszExeFileName, count);
391                 return (HICON)count;
392                 }
393         if (hInst2 != hInst && hInst2 != 0) {
394                 FreeLibrary(hInst2);
395                 }
396         return hIcon;
397 }
398
399
400 /*************************************************************************
401  *                              ExtractAssociatedIcon   [SHELL.36]
402  */
403 HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
404 {
405         dprintf_reg(stdnimp, "ExtractAssociatedIcon : Empty Stub !!!\n");
406 }
407
408 /*************************************************************************
409  *                              RegisterShellHook       [SHELL.102]
410  */
411 int RegisterShellHook(void *ptr) 
412 {
413         dprintf_reg(stdnimp, "RegisterShellHook : Empty Stub !!!\n");
414         return 0;
415 }
416
417
418 /*************************************************************************
419  *                              ShellHookProc           [SHELL.103]
420  */
421 int ShellHookProc(void) 
422 {
423         dprintf_reg(stdnimp, "ShellHookProc : Empty Stub !!!\n");
424 }