Release 960225
[wine.git] / misc / shell.c
blob8e4b9f7e18746c778c269dd28fa7fb631b6874b0
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 "neexe.h"
12 #include "selectors.h"
13 #include "alias.h"
14 #include "relay32.h"
15 #include "resource.h"
16 #include "dlgs.h"
17 #include "win.h"
18 #include "stddebug.h"
19 #include "debug.h"
20 #include "xmalloc.h"
22 LPKEYSTRUCT lphRootKey = NULL,lphTopKey = NULL;
24 static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]";
26 /*************************************************************************
27 * SHELL_Init()
29 BOOL SHELL_Init()
31 HKEY hNewKey;
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 FALSE;
39 lphRootKey->hKey = (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 FALSE;
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 TRUE;
63 /* FIXME: the loading and saving of the registry database is rather messy.
64 * bad input (while reading) may crash wine.
66 void
67 _DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs)
69 LPKEYSTRUCT lpKey;
71 lpKey=lpTKey->lpSubLvl;
72 while (lpKey) {
73 int i;
74 for (i=0;i<tabs;i++) fprintf(f,"\t");
75 /* implement different dwTypes ... */
76 if (lpKey->lpValue)
77 fprintf(f,"%s=%s\n",lpKey->lpSubKey,lpKey->lpValue);
78 else
79 fprintf(f,"%s\n",lpKey->lpSubKey);
81 if (lpKey->lpSubLvl)
82 _DumpLevel(f,lpKey,tabs+1);
83 lpKey=lpKey->lpNextKey;
87 static void
88 _SaveKey(HKEY hKey,char *where)
90 FILE *f;
91 LPKEYSTRUCT lpKey;
93 f=fopen(where,"w");
94 if (f==NULL) {
95 perror("registry-fopen");
96 return;
98 switch ((DWORD)hKey) {
99 case HKEY_CLASSES_ROOT:
100 lpKey=lphRootKey;
101 break;
102 default:return;
104 _DumpLevel(f,lpKey,0);
105 fclose(f);
108 void
109 SHELL_SaveRegistry(void)
111 /* FIXME:
112 * -implement win95 additional keytypes here
113 * (HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER or whatever)
114 * -choose better filename(s)
116 _SaveKey((HKEY)HKEY_CLASSES_ROOT,"/tmp/winereg");
119 #define BUFSIZE 256
120 void
121 _LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf)
123 int i;
124 char *s,*t;
125 HKEY hNewKey;
126 LPKEYSTRUCT lpNewKey;
128 while (1) {
129 if (NULL==fgets(buf,BUFSIZE,f)) {
130 buf[0]=0;
131 return;
133 for (i=0;buf[i]=='\t';i++) /*empty*/;
134 s=buf+i;
135 if (NULL!=(t=strchr(s,'\n'))) *t='\0';
136 if (NULL!=(t=strchr(s,'\r'))) *t='\0';
138 if (i<tabsexp) return;
140 if (i>tabsexp) {
141 hNewKey=GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
142 lpNewKey=lpKey->lpSubLvl=(LPKEYSTRUCT)GlobalLock(hNewKey);
143 lpNewKey->hKey = hNewKey;
144 lpNewKey->dwType = 0;
145 lpNewKey->lpSubKey = NULL;
146 lpNewKey->lpValue = NULL;
147 lpNewKey->lpSubLvl = NULL;
148 lpNewKey->lpNextKey = NULL;
149 lpNewKey->lpPrevKey = NULL;
150 if (NULL!=(t=strchr(s,'='))) {
151 *t='\0';t++;
152 lpNewKey->dwType = REG_SZ;
153 lpNewKey->lpSubKey = xstrdup(s);
154 lpNewKey->lpValue = xstrdup(t);
155 } else {
156 lpNewKey->dwType = REG_SZ;
157 lpNewKey->lpSubKey = xstrdup(s);
159 _LoadLevel(f,lpNewKey,tabsexp+1,buf);
161 for (i=0;buf[i]=='\t';i++) /*empty*/;
162 s=buf+i;
163 if (i<tabsexp) return;
164 if (buf[0]=='\0') break; /* marks end of file */
165 /* we have a buf now. even when returning from _LoadLevel */
166 hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT));
167 lpNewKey = lpKey->lpNextKey=(LPKEYSTRUCT)GlobalLock(hNewKey);
168 lpNewKey->lpPrevKey = lpKey;
169 lpNewKey->hKey = hNewKey;
170 lpNewKey->dwType = 0;
171 lpNewKey->lpSubKey = NULL;
172 lpNewKey->lpValue = NULL;
173 lpNewKey->lpSubLvl = NULL;
174 lpNewKey->lpNextKey = NULL;
175 if (NULL!=(t=strchr(s,'='))) {
176 *t='\0';t++;
177 lpNewKey->dwType = REG_SZ;
178 lpNewKey->lpSubKey = xstrdup(s);
179 lpNewKey->lpValue = xstrdup(t);
180 } else {
181 lpNewKey->dwType = REG_SZ;
182 lpNewKey->lpSubKey = xstrdup(s);
184 lpKey=lpNewKey;
188 void
189 _LoadKey(HKEY hKey,char *from)
191 FILE *f;
192 LPKEYSTRUCT lpKey;
193 char buf[BUFSIZE]; /* FIXME: long enough? */
195 f=fopen(from,"r");
196 if (f==NULL) {
197 perror("fopen-registry-read");
198 return;
200 switch ((DWORD)hKey) {
201 case HKEY_CLASSES_ROOT:
202 lpKey=lphRootKey;
203 break;
204 default:return;
206 _LoadLevel(f,lpKey,-1,buf);
209 void
210 SHELL_LoadRegistry(void)
212 _LoadKey((HKEY)HKEY_CLASSES_ROOT,"/tmp/winereg");
215 /*************************************************************************
216 * RegOpenKey [SHELL.1]
218 LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, LPHKEY lphKey)
220 LPKEYSTRUCT lpKey,lpNextKey;
221 LPCSTR ptr;
222 char str[128];
224 dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n",
225 (DWORD)hKey, lpSubKey, lpSubKey, lphKey);
226 if (lphKey == NULL) return SHELL_ERROR_INVALID_PARAMETER;
227 switch((DWORD)hKey) {
228 case 0:
229 lpKey = lphTopKey; break;
230 case HKEY_CLASSES_ROOT: /* == 1 */
231 case 0x80000000:
232 lpKey = lphRootKey; break;
233 default:
234 dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", (DWORD)hKey);
235 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
237 if (lpSubKey == NULL || !*lpSubKey) {
238 *lphKey = hKey;
239 return SHELL_ERROR_SUCCESS;
241 while(*lpSubKey) {
242 ptr = strchr(lpSubKey,'\\');
243 if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
244 strncpy(str,lpSubKey,ptr-lpSubKey);
245 str[ptr-lpSubKey] = 0;
246 lpSubKey = ptr;
247 if (*lpSubKey) lpSubKey++;
249 lpNextKey = lpKey->lpSubLvl;
250 while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
251 lpKey = lpNextKey;
252 if (lpKey) lpNextKey = lpKey->lpNextKey;
254 if (lpKey == NULL) {
255 dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str);
256 return SHELL_ERROR_BADKEY;
259 *lphKey = lpKey->hKey;
260 return SHELL_ERROR_SUCCESS;
264 /*************************************************************************
265 * RegCreateKey [SHELL.2]
267 LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, LPHKEY lphKey)
269 HKEY hNewKey;
270 LPKEYSTRUCT lpNewKey;
271 LPKEYSTRUCT lpKey;
272 LPKEYSTRUCT lpPrevKey;
273 LPCSTR ptr;
274 char str[128];
276 dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", (DWORD)hKey, lpSubKey, lphKey);
277 if (lphKey == NULL) return SHELL_ERROR_INVALID_PARAMETER;
278 switch((DWORD)hKey) {
279 case 0:
280 lpKey = lphTopKey; break;
281 case HKEY_CLASSES_ROOT: /* == 1 */
282 case 0x80000000:
283 case 0x80000001:
284 lpKey = lphRootKey; break;
285 default:
286 dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", (DWORD)hKey);
287 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
289 if (lpSubKey == NULL || !*lpSubKey) {
290 *lphKey = hKey;
291 return SHELL_ERROR_SUCCESS;
293 while (*lpSubKey) {
294 dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey);
295 ptr = strchr(lpSubKey,'\\');
296 if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
297 strncpy(str,lpSubKey,ptr-lpSubKey);
298 str[ptr-lpSubKey] = 0;
299 lpSubKey = ptr;
300 if (*lpSubKey) lpSubKey++;
302 lpPrevKey = lpKey;
303 lpKey = lpKey->lpSubLvl;
304 while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
305 lpKey = lpKey->lpNextKey;
307 if (lpKey == NULL) {
308 hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT));
309 lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
310 if (lpNewKey == NULL) {
311 printf("RegCreateKey // Can't alloc new key !\n");
312 return SHELL_ERROR_OUTOFMEMORY;
314 lpNewKey->hKey = hNewKey;
315 lpNewKey->lpSubKey = malloc(strlen(str) + 1);
316 if (lpNewKey->lpSubKey == NULL) {
317 printf("RegCreateKey // Can't alloc key string !\n");
318 return SHELL_ERROR_OUTOFMEMORY;
320 strcpy(lpNewKey->lpSubKey, str);
321 lpNewKey->lpNextKey = lpPrevKey->lpSubLvl;
322 lpNewKey->lpPrevKey = NULL;
323 lpPrevKey->lpSubLvl = lpNewKey;
325 lpNewKey->dwType = 0;
326 lpNewKey->lpValue = NULL;
327 lpNewKey->lpSubLvl = NULL;
328 *lphKey = hNewKey;
329 dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%08lX !\n", str, (DWORD)hNewKey);
330 lpKey = lpNewKey;
331 } else {
332 *lphKey = lpKey->hKey;
333 dprintf_reg(stddeb,"RegCreateKey // found '%s', key=%08lX\n", str, (DWORD)*lphKey);
336 return SHELL_ERROR_SUCCESS;
340 /*************************************************************************
341 * RegCloseKey [SHELL.3]
343 LONG RegCloseKey(HKEY hKey)
345 dprintf_reg(stdnimp, "EMPTY STUB !!! RegCloseKey(%08lX);\n", (DWORD)hKey);
346 return SHELL_ERROR_SUCCESS;
350 /*************************************************************************
351 * RegDeleteKey [SHELL.4]
353 LONG RegDeleteKey(HKEY hKey, LPCSTR lpSubKey)
355 dprintf_reg(stdnimp, "EMPTY STUB !!! RegDeleteKey(%08lX, '%s');\n",
356 (DWORD)hKey, lpSubKey);
357 return SHELL_ERROR_SUCCESS;
361 /*************************************************************************
362 * RegSetValue [SHELL.5]
364 LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType,
365 LPCSTR lpVal, DWORD dwIgnored)
367 HKEY hRetKey;
368 LPKEYSTRUCT lpKey;
369 LONG dwRet;
370 dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n",
371 (DWORD)hKey, lpSubKey, dwType, lpVal, dwIgnored);
372 /*if (lpSubKey == NULL) return SHELL_ERROR_INVALID_PARAMETER;*/
373 if (lpVal == NULL) return SHELL_ERROR_INVALID_PARAMETER;
374 if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) {
375 dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
376 if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) {
377 fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet);
378 return dwRet;
381 lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
382 if (lpKey == NULL) return SHELL_ERROR_BADKEY;
383 if (lpKey->lpValue != NULL) free(lpKey->lpValue);
384 lpKey->lpValue = xmalloc(strlen(lpVal) + 1);
385 strcpy(lpKey->lpValue, lpVal);
386 dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpKey->lpValue);
387 return SHELL_ERROR_SUCCESS;
391 /*************************************************************************
392 * RegQueryValue [SHELL.6]
394 LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LPLONG lpcb)
396 HKEY hRetKey;
397 LPKEYSTRUCT lpKey;
398 LONG dwRet;
399 int size;
400 dprintf_reg(stddeb, "RegQueryValue(%08lX, '%s', %p, %p);\n",
401 (DWORD)hKey, lpSubKey, lpVal, lpcb);
402 /*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
403 if (lpVal == NULL) return SHELL_ERROR_INVALID_PARAMETER;
404 if (lpcb == NULL) return SHELL_ERROR_INVALID_PARAMETER;
405 if (!*lpcb) return SHELL_ERROR_INVALID_PARAMETER;
407 if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) {
408 fprintf(stderr, "RegQueryValue // key not found !\n");
409 return dwRet;
411 lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
412 if (lpKey == NULL) return SHELL_ERROR_BADKEY;
413 if (lpKey->lpValue != NULL) {
414 if ((size = strlen(lpKey->lpValue)+1) > *lpcb){
415 strncpy(lpVal,lpKey->lpValue,*lpcb-1);
416 lpVal[*lpcb-1] = 0;
417 } else {
418 strcpy(lpVal,lpKey->lpValue);
419 *lpcb = size;
421 } else {
422 *lpVal = 0;
423 *lpcb = (LONG)1;
425 dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal);
426 return SHELL_ERROR_SUCCESS;
430 /*************************************************************************
431 * RegEnumKey [SHELL.7]
433 LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize)
435 LPKEYSTRUCT lpKey;
436 LONG len;
438 dprintf_reg(stddeb, "RegEnumKey(%08lX, %ld)\n", (DWORD)hKey, dwSubKey);
439 if (lpBuf == NULL) return SHELL_ERROR_INVALID_PARAMETER;
440 switch((DWORD)hKey) {
441 case 0:
442 lpKey = lphTopKey; break;
443 case HKEY_CLASSES_ROOT: /* == 1 */
444 case 0x80000000:
445 lpKey = lphRootKey; break;
446 default:
447 dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", (DWORD)hKey);
448 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
450 lpKey = lpKey->lpSubLvl;
451 while(lpKey != NULL){
452 if (!dwSubKey){
453 len = MIN(dwSize-1,strlen(lpKey->lpSubKey));
454 strncpy(lpBuf,lpKey->lpSubKey,len);
455 lpBuf[len] = 0;
456 dprintf_reg(stddeb, "RegEnumKey: found %s\n",lpBuf);
457 return SHELL_ERROR_SUCCESS;
459 dwSubKey--;
460 lpKey = lpKey->lpNextKey;
462 dprintf_reg(stddeb, "RegEnumKey: key not found!\n");
463 return SHELL_ERROR_INVALID_PARAMETER;
467 /*************************************************************************
468 * DragAcceptFiles [SHELL.9]
470 void DragAcceptFiles(HWND hWnd, BOOL b)
472 /* flips WS_EX_ACCEPTFILES bit according to the value of b */
473 dprintf_reg(stddeb,"DragAcceptFiles("NPFMT", %u) old exStyle %08lx\n",
474 hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE));
476 SetWindowLong(hWnd,GWL_EXSTYLE,
477 GetWindowLong(hWnd,GWL_EXSTYLE) | b*(LONG)WS_EX_ACCEPTFILES);
481 /*************************************************************************
482 * DragQueryFile [SHELL.11]
484 UINT DragQueryFile(HDROP hDrop, WORD wFile, LPSTR lpszFile, WORD wLength)
486 /* hDrop is a global memory block allocated with GMEM_SHARE
487 * with DROPFILESTRUCT as a header and filenames following
488 * it, zero length filename is in the end */
490 LPDROPFILESTRUCT lpDropFileStruct;
491 LPSTR lpCurrent;
492 WORD i;
494 dprintf_reg(stddeb,"DragQueryFile("NPFMT", %i, %p, %u)\n",
495 hDrop,wFile,lpszFile,wLength);
497 lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
498 if(!lpDropFileStruct)
500 dprintf_reg(stddeb,"DragQueryFile: unable to lock handle!\n");
501 return 0;
503 lpCurrent = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
505 i = 0;
506 while (i++ < wFile)
508 while (*lpCurrent++); /* skip filename */
509 if (!*lpCurrent)
510 return (wFile == 0xFFFF) ? i : 0;
513 i = strlen(lpCurrent);
514 if (!lpszFile) return i+1; /* needed buffer size */
516 i = (wLength > i) ? i : wLength-1;
517 strncpy(lpszFile, lpCurrent, i);
518 lpszFile[i] = '\0';
520 GlobalUnlock(hDrop);
521 return i;
525 /*************************************************************************
526 * DragFinish [SHELL.12]
528 void DragFinish(HDROP h)
530 GlobalFree((HGLOBAL)h);
534 /*************************************************************************
535 * DragQueryPoint [SHELL.13]
537 BOOL DragQueryPoint(HDROP hDrop, POINT FAR *p)
539 LPDROPFILESTRUCT lpDropFileStruct;
540 BOOL bRet;
542 lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
544 memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT));
545 bRet = lpDropFileStruct->fInNonClientArea;
547 GlobalUnlock(hDrop);
548 return bRet;
552 /*************************************************************************
553 * ShellExecute [SHELL.20]
555 HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
557 char cmd[400];
558 char *p,*x;
559 long len;
560 char subclass[200];
561 /* OK. We are supposed to lookup the program associated with lpFile,
562 * then to execute it using that program. If lpFile is a program,
563 * we have to pass the parameters. If an instance is already running,
564 * we might have to send DDE commands.
566 dprintf_exec(stddeb, "ShellExecute("NPFMT",'%s','%s','%s','%s',%x)\n",
567 hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
568 lpParameters ? lpParameters : "<null>",
569 lpDirectory ? lpDirectory : "<null>", iShowCmd);
570 if (lpFile==NULL) return 0; /* should not happen */
571 if (lpOperation==NULL) /* default is open */
572 lpOperation="open";
573 p=strrchr(lpFile,'.');
574 if (p!=NULL) {
575 x=p; /* the suffixes in the register database are lowercased */
576 while (*x) {*x=tolower(*x);x++;}
578 if (p==NULL || !strcmp(p,".exe")) {
579 p=".exe";
580 if (lpParameters) {
581 sprintf(cmd,"%s %s",lpFile,lpParameters);
582 } else {
583 strcpy(cmd,lpFile);
585 } else {
586 len=200;
587 if (RegQueryValue((HKEY)HKEY_CLASSES_ROOT,p,subclass,&len)==SHELL_ERROR_SUCCESS) {
588 if (len>20)
589 fprintf(stddeb,"ShellExecute:subclass with len %ld? (%s), please report.\n",len,subclass);
590 subclass[len]='\0';
591 strcat(subclass,"\\shell\\");
592 strcat(subclass,lpOperation);
593 strcat(subclass,"\\command");
594 dprintf_exec(stddeb,"ShellExecute:looking for %s.\n",subclass);
595 len=400;
596 if (RegQueryValue((HKEY)HKEY_CLASSES_ROOT,subclass,cmd,&len)==SHELL_ERROR_SUCCESS) {
597 char *t;
598 dprintf_exec(stddeb,"ShellExecute:...got %s\n",cmd);
599 cmd[len]='\0';
600 t=strstr(cmd,"%1");
601 if (t==NULL) {
602 strcat(cmd," ");
603 strcat(cmd,lpFile);
604 } else {
605 char *s;
606 s=xmalloc(len+strlen(lpFile)+10);
607 strncpy(s,cmd,t-cmd);
608 s[t-cmd]='\0';
609 strcat(s,lpFile);
610 strcat(s,t+2);
611 strcpy(cmd,s);
612 free(s);
614 /* does this use %x magic too? */
615 if (lpParameters) {
616 strcat(cmd," ");
617 strcat(cmd,lpParameters);
619 } else {
620 fprintf(stddeb,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass,lpOperation,p);
621 return (HINSTANCE)14; /* unknown type */
623 } else {
624 fprintf(stddeb,"ShellExecute: No operation found for \"%s\" suffix.\n",p);
625 return (HINSTANCE)14; /* file not found */
628 dprintf_exec(stddeb,"ShellExecute:starting %s\n",cmd);
629 return WinExec(cmd,iShowCmd);
633 /*************************************************************************
634 * FindExecutable [SHELL.21]
636 HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
638 fprintf(stdnimp, "FindExecutable : Empty Stub !!!\n");
639 return 0;
642 static char AppName[128], AppMisc[906];
644 /*************************************************************************
645 * AboutDlgProc [SHELL.33]
647 LRESULT AboutDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
649 char Template[512], AppTitle[512];
651 switch(msg) {
652 case WM_INITDIALOG:
653 #ifdef WINELIB32
654 SendDlgItemMessage(hWnd,stc1,STM_SETICON,lParam,0);
655 #else
656 SendDlgItemMessage(hWnd,stc1,STM_SETICON,LOWORD(lParam),0);
657 #endif
658 GetWindowText(hWnd, Template, 511);
659 sprintf(AppTitle, Template, AppName);
660 SetWindowText(hWnd, AppTitle);
661 SetWindowText(GetDlgItem(hWnd,100), AppMisc);
662 return 1;
664 case WM_COMMAND:
665 switch (wParam) {
666 case IDOK:
667 EndDialog(hWnd, TRUE);
668 return TRUE;
670 break;
672 return FALSE;
675 /*************************************************************************
676 * ShellAbout [SHELL.22]
678 INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
680 HANDLE handle;
681 BOOL bRet;
682 DWORD WineProc,Win16Proc,Win32Proc;
683 static int initialized=0;
685 if (szApp) strncpy(AppName, szApp, sizeof(AppName));
686 else *AppName = 0;
687 AppName[sizeof(AppName)-1]=0;
689 if (szOtherStuff) strncpy(AppMisc, szOtherStuff, sizeof(AppMisc));
690 else *AppMisc = 0;
691 AppMisc[sizeof(AppMisc)-1]=0;
693 if (!hIcon) hIcon = LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON));
695 if(!initialized)
697 WineProc=(DWORD)AboutDlgProc;
698 Win16Proc=(DWORD)GetWndProcEntry16("AboutDlgProc");
699 Win32Proc=(DWORD)RELAY32_GetEntryPoint(RELAY32_GetBuiltinDLL("WINPROCS32"),
700 "AboutDlgProc",0);
701 ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc);
702 initialized=1;
705 handle = SYSRES_LoadResource( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX );
706 if (!handle) return FALSE;
707 bRet = DialogBoxIndirectParam( WIN_GetWindowInstance( hWnd ),
708 handle, hWnd,
709 GetWndProcEntry16("AboutDlgProc"),
710 (LONG)hIcon );
711 SYSRES_FreeResource( handle );
712 return bRet;
715 /*************************************************************************
716 * ExtractIcon [SHELL.34]
718 HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
720 HICON hIcon = 0;
721 HINSTANCE hInst2 = hInst;
722 dprintf_reg(stddeb, "ExtractIcon("NPFMT", '%s', %d\n",
723 hInst, lpszExeFileName, nIconIndex);
724 return 0;
725 if (lpszExeFileName != NULL) {
726 hInst2 = LoadModule(lpszExeFileName,(LPVOID)-1);
728 if (hInst2 != 0 && nIconIndex == (UINT)-1) {
729 #if 0
730 count = GetRsrcCount(hInst2, NE_RSCTYPE_GROUP_ICON);
731 dprintf_reg(stddeb, "ExtractIcon // '%s' has %d icons !\n", lpszExeFileName, count);
732 return (HICON)count;
733 #endif
735 if (hInst2 != hInst && hInst2 != 0) {
736 FreeLibrary(hInst2);
738 return hIcon;
742 /*************************************************************************
743 * ExtractAssociatedIcon [SHELL.36]
745 HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
747 dprintf_reg(stdnimp, "ExtractAssociatedIcon : Empty Stub !!!\n");
748 return 0;
751 /*************************************************************************
752 * DoEnvironmentSubst [SHELL.37]
754 DWORD DoEnvironmentSubst(LPSTR str,WORD len)
756 dprintf_reg(stdnimp, "DoEnvironmentSubst(%s,%x): Empty Stub !!!\n",str,len);
757 return 0;
760 /*************************************************************************
761 * RegisterShellHook [SHELL.102]
763 int RegisterShellHook(void *ptr)
765 dprintf_reg(stdnimp, "RegisterShellHook : Empty Stub !!!\n");
766 return 0;
770 /*************************************************************************
771 * ShellHookProc [SHELL.103]
773 int ShellHookProc(void)
775 dprintf_reg(stdnimp, "ShellHookProc : Empty Stub !!!\n");
776 return 0;