Release 950918
[wine/testsucceed.git] / misc / shell.c
blob7588a5745b0fcc8765288f33e542675e65d7d34a
1 /*
2 * Shell Library Functions
3 */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <ctype.h>
9 #include "windows.h"
10 #include "shell.h"
11 #include "global.h"
12 #include "neexe.h"
13 #include "selectors.h"
14 #include "alias.h"
15 #include "relay32.h"
16 #include "../rc/sysres.h"
17 #include "dlgs.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 LPKEYSTRUCT lphRootKey = NULL,lphTopKey = NULL;
23 static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]";
25 /*************************************************************************
26 * SHELL_RegCheckForRoot() internal use only
28 static LONG SHELL_RegCheckForRoot()
30 HKEY hNewKey;
32 if (lphRootKey == NULL){
33 hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
34 lphRootKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
35 if (lphRootKey == NULL) {
36 printf("SHELL_RegCheckForRoot: Couldn't allocate root key!\n");
37 return ERROR_OUTOFMEMORY;
39 lphRootKey->hKey = 1;
40 lphRootKey->lpSubKey = RootKeyName;
41 lphRootKey->dwType = 0;
42 lphRootKey->lpValue = NULL;
43 lphRootKey->lpSubLvl = lphRootKey->lpNextKey = lphRootKey->lpPrevKey = NULL;
45 hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
46 lphTopKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
47 if (lphTopKey == NULL) {
48 printf("SHELL_RegCheckForRoot: Couldn't allocate top key!\n");
49 return ERROR_OUTOFMEMORY;
51 lphTopKey->hKey = 0;
52 lphTopKey->lpSubKey = TopKeyName;
53 lphTopKey->dwType = 0;
54 lphTopKey->lpValue = NULL;
55 lphTopKey->lpSubLvl = lphRootKey;
56 lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL;
58 dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n");
60 return ERROR_SUCCESS;
63 /*************************************************************************
64 * RegOpenKey [SHELL.1]
66 LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
68 LPKEYSTRUCT lpKey,lpNextKey;
69 LPCSTR ptr;
70 char str[128];
71 LONG dwRet;
73 dwRet = SHELL_RegCheckForRoot();
74 if (dwRet != ERROR_SUCCESS) return dwRet;
75 dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n",
76 hKey, lpSubKey, lpSubKey, lphKey);
77 if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
78 switch(hKey) {
79 case 0:
80 lpKey = lphTopKey; break;
81 case HKEY_CLASSES_ROOT: /* == 1 */
82 case 0x80000000:
83 lpKey = lphRootKey; break;
84 default:
85 dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey);
86 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
88 if (lpSubKey == NULL || !*lpSubKey) {
89 *lphKey = hKey;
90 return ERROR_SUCCESS;
92 while(*lpSubKey) {
93 ptr = strchr(lpSubKey,'\\');
94 if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
95 strncpy(str,lpSubKey,ptr-lpSubKey);
96 str[ptr-lpSubKey] = 0;
97 lpSubKey = ptr;
98 if (*lpSubKey) lpSubKey++;
100 lpNextKey = lpKey->lpSubLvl;
101 while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
102 lpKey = lpNextKey;
103 if (lpKey) lpNextKey = lpKey->lpNextKey;
105 if (lpKey == NULL) {
106 dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str);
107 return ERROR_BADKEY;
110 *lphKey = lpKey->hKey;
111 return ERROR_SUCCESS;
115 /*************************************************************************
116 * RegCreateKey [SHELL.2]
118 LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey)
120 HKEY hNewKey;
121 LPKEYSTRUCT lpNewKey;
122 LPKEYSTRUCT lpKey;
123 LPKEYSTRUCT lpPrevKey;
124 LONG dwRet;
125 LPCSTR ptr;
126 char str[128];
128 dwRet = SHELL_RegCheckForRoot();
129 if (dwRet != ERROR_SUCCESS) return dwRet;
130 dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", hKey, lpSubKey, lphKey);
131 if (lphKey == NULL) return ERROR_INVALID_PARAMETER;
132 switch(hKey) {
133 case 0:
134 lpKey = lphTopKey; break;
135 case HKEY_CLASSES_ROOT: /* == 1 */
136 case 0x80000000:
137 lpKey = lphRootKey; break;
138 default:
139 dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey);
140 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
142 if (lpSubKey == NULL || !*lpSubKey) {
143 *lphKey = hKey;
144 return ERROR_SUCCESS;
146 while (*lpSubKey) {
147 dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey);
148 ptr = strchr(lpSubKey,'\\');
149 if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
150 strncpy(str,lpSubKey,ptr-lpSubKey);
151 str[ptr-lpSubKey] = 0;
152 lpSubKey = ptr;
153 if (*lpSubKey) lpSubKey++;
155 lpPrevKey = lpKey;
156 lpKey = lpKey->lpSubLvl;
157 while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
158 lpKey = lpKey->lpNextKey;
160 if (lpKey == NULL) {
161 hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT));
162 lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
163 if (lpNewKey == NULL) {
164 printf("RegCreateKey // Can't alloc new key !\n");
165 return ERROR_OUTOFMEMORY;
167 lpNewKey->hKey = hNewKey;
168 lpNewKey->lpSubKey = malloc(strlen(str) + 1);
169 if (lpNewKey->lpSubKey == NULL) {
170 printf("RegCreateKey // Can't alloc key string !\n");
171 return ERROR_OUTOFMEMORY;
173 strcpy(lpNewKey->lpSubKey, str);
174 lpNewKey->lpNextKey = lpPrevKey->lpSubLvl;
175 lpNewKey->lpPrevKey = NULL;
176 lpPrevKey->lpSubLvl = lpNewKey;
178 lpNewKey->dwType = 0;
179 lpNewKey->lpValue = NULL;
180 lpNewKey->lpSubLvl = NULL;
181 *lphKey = hNewKey;
182 dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%08lX !\n", str, hNewKey);
183 lpKey = lpNewKey;
184 } else {
185 *lphKey = lpKey->hKey;
186 dprintf_reg(stddeb,"RegCreateKey // found '%s', key=%08lX\n", str, *lphKey);
189 return ERROR_SUCCESS;
193 /*************************************************************************
194 * RegCloseKey [SHELL.3]
196 LONG RegCloseKey(HKEY hKey)
198 dprintf_reg(stdnimp, "EMPTY STUB !!! RegCloseKey(%08lX);\n", hKey);
199 return ERROR_SUCCESS;
203 /*************************************************************************
204 * RegDeleteKey [SHELL.4]
206 LONG RegDeleteKey(HKEY hKey, LPCSTR lpSubKey)
208 dprintf_reg(stdnimp, "EMPTY STUB !!! RegDeleteKey(%08lX, '%s');\n",
209 hKey, lpSubKey);
210 return ERROR_SUCCESS;
214 /*************************************************************************
215 * RegSetValue [SHELL.5]
217 LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType,
218 LPCSTR lpVal, DWORD dwIgnored)
220 HKEY hRetKey;
221 LPKEYSTRUCT lpKey;
222 LONG dwRet;
223 dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n",
224 hKey, lpSubKey, dwType, lpVal, dwIgnored);
225 /*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
226 if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
227 if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
228 dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
229 if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
230 fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet);
231 return dwRet;
234 lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
235 if (lpKey == NULL) return ERROR_BADKEY;
236 if (lpKey->lpValue != NULL) free(lpKey->lpValue);
237 lpKey->lpValue = malloc(strlen(lpVal) + 1);
238 strcpy(lpKey->lpValue, lpVal);
239 dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpKey->lpValue);
240 return ERROR_SUCCESS;
244 /*************************************************************************
245 * RegQueryValue [SHELL.6]
247 LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb)
249 HKEY hRetKey;
250 LPKEYSTRUCT lpKey;
251 LONG dwRet;
252 int size;
253 dprintf_reg(stddeb, "RegQueryValue(%08lX, '%s', %p, %p);\n",
254 hKey, lpSubKey, lpVal, lpcb);
255 /*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
256 if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
257 if (lpcb == NULL) return ERROR_INVALID_PARAMETER;
258 if (!*lpcb) return ERROR_INVALID_PARAMETER;
260 if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
261 fprintf(stderr, "RegQueryValue // key not found !\n");
262 return dwRet;
264 lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
265 if (lpKey == NULL) return ERROR_BADKEY;
266 if (lpKey->lpValue != NULL) {
267 if ((size = strlen(lpKey->lpValue)+1) > *lpcb){
268 strncpy(lpVal,lpKey->lpValue,*lpcb-1);
269 lpVal[*lpcb-1] = 0;
270 } else {
271 strcpy(lpVal,lpKey->lpValue);
272 *lpcb = size;
274 } else {
275 *lpVal = 0;
276 *lpcb = (LONG)1;
278 dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal);
279 return ERROR_SUCCESS;
283 /*************************************************************************
284 * RegEnumKey [SHELL.7]
286 LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize)
288 LPKEYSTRUCT lpKey;
289 LONG dwRet;
290 LONG len;
292 dwRet = SHELL_RegCheckForRoot();
293 if (dwRet != ERROR_SUCCESS) return dwRet;
294 dprintf_reg(stddeb, "RegEnumKey(%08lX, %ld)\n", hKey, dwSubKey);
295 if (lpBuf == NULL) return ERROR_INVALID_PARAMETER;
296 switch(hKey) {
297 case 0:
298 lpKey = lphTopKey; break;
299 case HKEY_CLASSES_ROOT: /* == 1 */
300 case 0x80000000:
301 lpKey = lphRootKey; break;
302 default:
303 dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", hKey);
304 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
306 lpKey = lpKey->lpSubLvl;
307 while(lpKey != NULL){
308 if (!dwSubKey){
309 len = min(dwSize-1,strlen(lpKey->lpSubKey));
310 strncpy(lpBuf,lpKey->lpSubKey,len);
311 lpBuf[len] = 0;
312 dprintf_reg(stddeb, "RegEnumKey: found %s\n",lpBuf);
313 return ERROR_SUCCESS;
315 dwSubKey--;
316 lpKey = lpKey->lpNextKey;
318 dprintf_reg(stddeb, "RegEnumKey: key not found!\n");
319 return ERROR_INVALID_PARAMETER;
322 /*************************************************************************
323 * DragAcceptFiles [SHELL.9]
325 void DragAcceptFiles(HWND hWnd, BOOL b)
327 fprintf(stdnimp, "DragAcceptFiles : Empty Stub !!!\n");
331 /*************************************************************************
332 * DragQueryFile [SHELL.11]
334 void DragQueryFile(HDROP h, UINT u, LPSTR u2, UINT u3)
336 fprintf(stdnimp, "DragQueryFile : Empty Stub !!!\n");
341 /*************************************************************************
342 * DragFinish [SHELL.12]
344 void DragFinish(HDROP h)
346 fprintf(stdnimp, "DragFinish : Empty Stub !!!\n");
350 /*************************************************************************
351 * DragQueryPoint [SHELL.13]
353 BOOL DragQueryPoint(HDROP h, POINT FAR *p)
355 fprintf(stdnimp, "DragQueryPoint : Empty Stub !!!\n");
356 return FALSE;
360 /*************************************************************************
361 * ShellExecute [SHELL.20]
363 HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int iShowCmd)
365 char cmd[400];
366 char *p,*x;
367 long len;
368 char subclass[200];
369 /* OK. We are supposed to lookup the program associated with lpFile,
370 * then to execute it using that program. If lpFile is a program,
371 * we have to pass the parameters. If an instance is already running,
372 * we might have to send DDE commands.
374 dprintf_exec(stddeb, "ShellExecute(%4X,'%s','%s','%s','%s',%x)\n",
375 hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
376 lpParameters ? lpParameters : "<null>",
377 lpDirectory ? lpDirectory : "<null>", iShowCmd);
378 if (lpFile==NULL) return 0; /* should not happen */
379 if (lpOperation==NULL) /* default is open */
380 lpOperation="open";
381 p=strrchr(lpFile,'.');
382 if (p!=NULL) {
383 x=p; /* the suffixes in the register database are lowercased */
384 while (*x) {*x=tolower(*x);x++;}
386 if (p==NULL || !strcmp(p,".exe")) {
387 p=".exe";
388 if (lpParameters) {
389 sprintf(cmd,"%s %s",lpFile,lpParameters);
390 } else {
391 strcpy(cmd,lpFile);
393 } else {
394 len=200;
395 if (RegQueryValue(HKEY_CLASSES_ROOT,p,subclass,&len)==ERROR_SUCCESS) {
396 if (len>20)
397 fprintf(stddeb,"ShellExecute:subclass with len %ld? (%s), please report.\n",len,subclass);
398 subclass[len]='\0';
399 strcat(subclass,"\\shell\\");
400 strcat(subclass,lpOperation);
401 strcat(subclass,"\\command");
402 dprintf_exec(stddeb,"ShellExecute:looking for %s.\n",subclass);
403 len=400;
404 if (RegQueryValue(HKEY_CLASSES_ROOT,subclass,cmd,&len)==ERROR_SUCCESS) {
405 char *t;
406 dprintf_exec(stddeb,"ShellExecute:...got %s\n",cmd);
407 cmd[len]='\0';
408 t=strstr(cmd,"%1");
409 if (t==NULL) {
410 strcat(cmd," ");
411 strcat(cmd,lpFile);
412 } else {
413 char *s;
414 s=malloc(len+strlen(lpFile)+10);
415 strncpy(s,cmd,t-cmd);
416 strcat(s,lpFile);
417 strcat(s,t+2);
418 strcpy(cmd,s);
419 free(s);
421 /* does this use %x magic too? */
422 if (lpParameters) {
423 strcat(cmd," ");
424 strcat(cmd,lpParameters);
426 } else {
427 fprintf(stddeb,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass,lpOperation,p);
428 return 14; /* unknown type */
430 } else {
431 fprintf(stddeb,"ShellExecute: No operation found for \"%s\" suffix.\n",p);
432 return 14; /* file not found */
435 return WinExec(cmd,iShowCmd);
439 /*************************************************************************
440 * FindExecutable [SHELL.21]
442 HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
444 fprintf(stdnimp, "FindExecutable : Empty Stub !!!\n");
445 return 0;
448 static char AppName[512], AppMisc[512];
450 /*************************************************************************
451 * AboutDlgProc [SHELL.33]
453 INT AboutDlgProc(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
455 char Template[512], AppTitle[512];
457 switch(msg) {
458 case WM_INITDIALOG:
459 SendDlgItemMessage(hWnd,stc1,STM_SETICON,LOWORD(lParam),0);
460 GetWindowText(hWnd, Template, 511);
461 sprintf(AppTitle, Template, AppName);
462 SetWindowText(hWnd, AppTitle);
463 SetWindowText(GetDlgItem(hWnd,100), AppMisc);
464 return 1;
466 case WM_COMMAND:
467 switch (wParam) {
468 case IDOK:
469 EndDialog(hWnd, TRUE);
470 return TRUE;
472 break;
474 return FALSE;
477 /*************************************************************************
478 * ShellAbout [SHELL.22]
480 INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
482 HANDLE handle;
483 BOOL bRet;
484 DWORD WineProc,Win16Proc,Win32Proc;
485 static int initialized=0;
487 if (szApp) strcpy(AppName, szApp);
488 else *AppName = 0;
490 if (szOtherStuff) strcpy(AppMisc, szOtherStuff);
491 else *AppMisc = 0;
493 if (!hIcon) hIcon = LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON));
495 if(!initialized)
497 WineProc=(DWORD)AboutDlgProc;
498 Win16Proc=(DWORD)GetWndProcEntry16("AboutDlgProc");
499 Win32Proc=(DWORD)RELAY32_GetEntryPoint("WINPROCS32","AboutDlgProc",0);
500 ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc);
501 initialized=1;
504 handle = GLOBAL_CreateBlock( GMEM_FIXED,
505 sysres_DIALOG_SHELL_ABOUT_MSGBOX.bytes,
506 sysres_DIALOG_SHELL_ABOUT_MSGBOX.size,
507 GetCurrentPDB(), FALSE, FALSE,
508 TRUE, NULL );
509 if (!handle) return FALSE;
510 bRet = DialogBoxIndirectParam( GetWindowWord( hWnd, GWW_HINSTANCE ),
511 handle, hWnd,
512 GetWndProcEntry16("AboutDlgProc"), hIcon );
513 GLOBAL_FreeBlock( handle );
514 return bRet;
517 /*************************************************************************
518 * ExtractIcon [SHELL.34]
520 HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
522 HICON hIcon = 0;
523 HINSTANCE hInst2 = hInst;
524 dprintf_reg(stddeb, "ExtractIcon(%04X, '%s', %d\n",
525 hInst, lpszExeFileName, nIconIndex);
526 return 0;
527 if (lpszExeFileName != NULL) {
528 hInst2 = LoadModule(lpszExeFileName,(LPVOID)-1);
530 if (hInst2 != 0 && nIconIndex == (UINT)-1) {
531 #if 0
532 count = GetRsrcCount(hInst2, NE_RSCTYPE_GROUP_ICON);
533 dprintf_reg(stddeb, "ExtractIcon // '%s' has %d icons !\n", lpszExeFileName, count);
534 return (HICON)count;
535 #endif
537 if (hInst2 != hInst && hInst2 != 0) {
538 FreeLibrary(hInst2);
540 return hIcon;
544 /*************************************************************************
545 * ExtractAssociatedIcon [SHELL.36]
547 HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
549 dprintf_reg(stdnimp, "ExtractAssociatedIcon : Empty Stub !!!\n");
550 return 0;
553 /*************************************************************************
554 * DoEnvironmentSubst [SHELL.37]
556 DWORD DoEnvironmentSubst(LPSTR str,WORD len)
558 dprintf_reg(stdnimp, "DoEnvironmentSubst(%s,%x): Empyt Stub !!!\n",str,len);
559 return 0;
562 /*************************************************************************
563 * RegisterShellHook [SHELL.102]
565 int RegisterShellHook(void *ptr)
567 dprintf_reg(stdnimp, "RegisterShellHook : Empty Stub !!!\n");
568 return 0;
572 /*************************************************************************
573 * ShellHookProc [SHELL.103]
575 int ShellHookProc(void)
577 dprintf_reg(stdnimp, "ShellHookProc : Empty Stub !!!\n");
578 return 0;