Release 960331
[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 <ctype.h>
9 #include "windows.h"
10 #include "shell.h"
11 #include "module.h"
12 #include "neexe.h"
13 #include "resource.h"
14 #include "dlgs.h"
15 #include "win.h"
16 #include "stddebug.h"
17 #include "debug.h"
18 #include "xmalloc.h"
19
20 /*************************************************************************
21  *                              DragAcceptFiles         [SHELL.9]
22  */
23 void DragAcceptFiles(HWND hWnd, BOOL b)
24 {
25     /* flips WS_EX_ACCEPTFILES bit according to the value of b */
26     dprintf_reg(stddeb,"DragAcceptFiles(%04x, %u) old exStyle %08lx\n",
27                 hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE));
28
29     SetWindowLong(hWnd,GWL_EXSTYLE,
30                   GetWindowLong(hWnd,GWL_EXSTYLE) | b*(LONG)WS_EX_ACCEPTFILES);
31 }
32
33
34 /*************************************************************************
35  *                              DragQueryFile           [SHELL.11]
36  */
37 UINT DragQueryFile(HDROP hDrop, WORD wFile, LPSTR lpszFile, WORD wLength)
38 {
39     /* hDrop is a global memory block allocated with GMEM_SHARE 
40      * with DROPFILESTRUCT as a header and filenames following
41      * it, zero length filename is in the end */       
42     
43     LPDROPFILESTRUCT lpDropFileStruct;
44     LPSTR lpCurrent;
45     WORD  i;
46     
47     dprintf_reg(stddeb,"DragQueryFile(%04x, %i, %p, %u)\n",
48                 hDrop,wFile,lpszFile,wLength);
49     
50     lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); 
51     if(!lpDropFileStruct)
52     {
53         dprintf_reg(stddeb,"DragQueryFile: unable to lock handle!\n");
54         return 0;
55     } 
56     lpCurrent = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
57     
58     i = 0;
59     while (i++ < wFile)
60     {
61         while (*lpCurrent++);  /* skip filename */
62         if (!*lpCurrent) 
63             return (wFile == 0xFFFF) ? i : 0;  
64     }
65     
66     i = strlen(lpCurrent); 
67     if (!lpszFile) return i+1;   /* needed buffer size */
68     
69     i = (wLength > i) ? i : wLength-1;
70     strncpy(lpszFile, lpCurrent, i);
71     lpszFile[i] = '\0';
72     
73     GlobalUnlock(hDrop);
74     return i;
75 }
76
77
78 /*************************************************************************
79  *                              DragFinish              [SHELL.12]
80  */
81 void DragFinish(HDROP h)
82 {
83     GlobalFree((HGLOBAL)h);
84 }
85
86
87 /*************************************************************************
88  *                              DragQueryPoint          [SHELL.13]
89  */
90 BOOL DragQueryPoint(HDROP hDrop, POINT FAR *p)
91 {
92     LPDROPFILESTRUCT lpDropFileStruct;  
93     BOOL             bRet;
94
95     lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
96
97     memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT));
98     bRet = lpDropFileStruct->fInNonClientArea;
99
100     GlobalUnlock(hDrop);
101     return bRet;
102 }
103
104
105 /*************************************************************************
106  *                              ShellExecute            [SHELL.20]
107  */
108 HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
109 {
110     char cmd[400];
111     char *p,*x;
112     long len;
113     char subclass[200];
114     /* OK. We are supposed to lookup the program associated with lpFile,
115      * then to execute it using that program. If lpFile is a program,
116      * we have to pass the parameters. If an instance is already running,
117      * we might have to send DDE commands.
118      */
119     dprintf_exec(stddeb, "ShellExecute(%04x,'%s','%s','%s','%s',%x)\n",
120                 hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
121                 lpParameters ? lpParameters : "<null>", 
122                 lpDirectory ? lpDirectory : "<null>", iShowCmd);
123     if (lpFile==NULL) return 0; /* should not happen */
124     if (lpOperation==NULL) /* default is open */
125       lpOperation="open";
126     p=strrchr(lpFile,'.');
127     if (p!=NULL) {
128       x=p; /* the suffixes in the register database are lowercased */
129       while (*x) {*x=tolower(*x);x++;}
130     }
131     if (p==NULL || !strcmp(p,".exe")) {
132       p=".exe";
133       if (lpParameters) {
134         sprintf(cmd,"%s %s",lpFile,lpParameters);
135       } else {
136         strcpy(cmd,lpFile);
137       }
138     } else {
139       len=200;
140       if (RegQueryValue((HKEY)HKEY_CLASSES_ROOT,p,subclass,&len)==SHELL_ERROR_SUCCESS) {
141         if (len>20)
142           fprintf(stddeb,"ShellExecute:subclass with len %ld? (%s), please report.\n",len,subclass);
143         subclass[len]='\0';
144         strcat(subclass,"\\shell\\");
145         strcat(subclass,lpOperation);
146         strcat(subclass,"\\command");
147         dprintf_exec(stddeb,"ShellExecute:looking for %s.\n",subclass);
148         len=400;
149         if (RegQueryValue((HKEY)HKEY_CLASSES_ROOT,subclass,cmd,&len)==SHELL_ERROR_SUCCESS) {
150           char *t;
151           dprintf_exec(stddeb,"ShellExecute:...got %s\n",cmd);
152           cmd[len]='\0';
153           t=strstr(cmd,"%1");
154           if (t==NULL) {
155             strcat(cmd," ");
156             strcat(cmd,lpFile);
157           } else {
158             char *s;
159             s=xmalloc(len+strlen(lpFile)+10);
160             strncpy(s,cmd,t-cmd);
161             s[t-cmd]='\0';
162             strcat(s,lpFile);
163             strcat(s,t+2);
164             strcpy(cmd,s);
165             free(s);
166           }
167           /* does this use %x magic too? */
168           if (lpParameters) {
169             strcat(cmd," ");
170             strcat(cmd,lpParameters);
171           }
172         } else {
173           fprintf(stddeb,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass,lpOperation,p);
174           return (HINSTANCE)14; /* unknown type */
175         }
176       } else {
177         fprintf(stddeb,"ShellExecute: No operation found for \"%s\" suffix.\n",p);
178         return (HINSTANCE)14; /* file not found */
179       }
180     }
181     dprintf_exec(stddeb,"ShellExecute:starting %s\n",cmd);
182     return WinExec(cmd,iShowCmd);
183 }
184
185
186 /*************************************************************************
187  *                              FindExecutable          [SHELL.21]
188  */
189 HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
190 {
191         fprintf(stdnimp, "FindExecutable : Empty Stub !!!\n");
192         return 0;
193 }
194
195 static char AppName[128], AppMisc[906];
196
197 /*************************************************************************
198  *                              AboutDlgProc            [SHELL.33]
199  */
200 LRESULT AboutDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
201 {
202   char Template[512], AppTitle[512];
203  
204   switch(msg) {
205    case WM_INITDIALOG:
206 #ifdef WINELIB32
207     SendDlgItemMessage(hWnd,stc1,STM_SETICON,lParam,0);
208 #else
209     SendDlgItemMessage(hWnd,stc1,STM_SETICON,LOWORD(lParam),0);
210 #endif
211     GetWindowText(hWnd, Template, 511);
212     sprintf(AppTitle, Template, AppName);
213     SetWindowText(hWnd, AppTitle);
214     SetWindowText(GetDlgItem(hWnd,100), AppMisc);
215     return 1;
216     
217    case WM_COMMAND:
218     switch (wParam) {
219      case IDOK:
220       EndDialog(hWnd, TRUE);
221       return TRUE;
222     }
223     break;
224   }
225   return FALSE;
226 }
227
228 /*************************************************************************
229  *                              ShellAbout              [SHELL.22]
230  */
231 INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
232 {
233     HANDLE handle;
234     BOOL bRet;
235
236     if (szApp) strncpy(AppName, szApp, sizeof(AppName));
237     else *AppName = 0;
238     AppName[sizeof(AppName)-1]=0;
239
240     if (szOtherStuff) strncpy(AppMisc, szOtherStuff, sizeof(AppMisc));
241     else *AppMisc = 0;
242     AppMisc[sizeof(AppMisc)-1]=0;
243
244     if (!hIcon) hIcon = LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON));
245     handle = SYSRES_LoadResource( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX );
246     if (!handle) return FALSE;
247     bRet = DialogBoxIndirectParam( WIN_GetWindowInstance( hWnd ),
248                                    handle, hWnd,
249                                    MODULE_GetWndProcEntry16("AboutDlgProc"), 
250                                    (LONG)hIcon );
251     SYSRES_FreeResource( handle );
252     return bRet;
253 }
254
255 /*************************************************************************
256  *                              ExtractIcon             [SHELL.34]
257  */
258 HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
259 {
260         HICON   hIcon = 0;
261         HINSTANCE hInst2 = hInst;
262         dprintf_reg(stddeb, "ExtractIcon(%04x, '%s', %d\n", 
263                         hInst, lpszExeFileName, nIconIndex);
264         return 0;
265         if (lpszExeFileName != NULL) {
266                 hInst2 = LoadModule(lpszExeFileName,(LPVOID)-1);
267         }
268         if (hInst2 != 0 && nIconIndex == (UINT)-1) {
269 #if 0
270                 count = GetRsrcCount(hInst2, NE_RSCTYPE_GROUP_ICON);
271                 dprintf_reg(stddeb, "ExtractIcon // '%s' has %d icons !\n", lpszExeFileName, count);
272                 return (HICON)count;
273 #endif
274         }
275         if (hInst2 != hInst && hInst2 != 0) {
276                 FreeLibrary(hInst2);
277         }
278         return hIcon;
279 }
280
281
282 /*************************************************************************
283  *                              ExtractAssociatedIcon   [SHELL.36]
284  */
285 HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
286 {
287     dprintf_reg(stdnimp, "ExtractAssociatedIcon : Empty Stub !!!\n");
288     return 0;
289 }
290
291 /*************************************************************************
292  *              DoEnvironmentSubst      [SHELL.37]
293  */
294 DWORD DoEnvironmentSubst(LPSTR str,WORD len)
295 {
296     dprintf_reg(stdnimp, "DoEnvironmentSubst(%s,%x): Empty Stub !!!\n",str,len);
297     return 0;
298 }
299
300 /*************************************************************************
301  *                              RegisterShellHook       [SHELL.102]
302  */
303 int RegisterShellHook(void *ptr) 
304 {
305         dprintf_reg(stdnimp, "RegisterShellHook : Empty Stub !!!\n");
306         return 0;
307 }
308
309
310 /*************************************************************************
311  *                              ShellHookProc           [SHELL.103]
312  */
313 int ShellHookProc(void) 
314 {
315         dprintf_reg(stdnimp, "ShellHookProc : Empty Stub !!!\n");
316         return 0;
317 }