2 * Shell Library Functions
13 #include "selectors.h"
16 #include "../rc/sysres.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()
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
;
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
;
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");
63 /*************************************************************************
64 * RegOpenKey [SHELL.1]
66 LONG
RegOpenKey(HKEY hKey
, LPCSTR lpSubKey
, HKEY FAR
*lphKey
)
68 LPKEYSTRUCT lpKey
,lpNextKey
;
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
;
80 lpKey
= lphTopKey
; break;
81 case HKEY_CLASSES_ROOT
: /* == 1 */
83 lpKey
= lphRootKey
; break;
85 dprintf_reg(stddeb
,"RegOpenKey // specific key = %08lX !\n", hKey
);
86 lpKey
= (LPKEYSTRUCT
)GlobalLock(hKey
);
88 if (lpSubKey
== NULL
|| !*lpSubKey
) {
93 ptr
= strchr(lpSubKey
,'\\');
94 if (!ptr
) ptr
= lpSubKey
+ strlen(lpSubKey
);
95 strncpy(str
,lpSubKey
,ptr
-lpSubKey
);
96 str
[ptr
-lpSubKey
] = 0;
98 if (*lpSubKey
) lpSubKey
++;
100 lpNextKey
= lpKey
->lpSubLvl
;
101 while(lpKey
!= NULL
&& strcmp(lpKey
->lpSubKey
, str
) != 0) {
103 if (lpKey
) lpNextKey
= lpKey
->lpNextKey
;
106 dprintf_reg(stddeb
,"RegOpenKey: key %s not found!\n",str
);
110 *lphKey
= lpKey
->hKey
;
111 return ERROR_SUCCESS
;
115 /*************************************************************************
116 * RegCreateKey [SHELL.2]
118 LONG
RegCreateKey(HKEY hKey
, LPCSTR lpSubKey
, HKEY FAR
*lphKey
)
121 LPKEYSTRUCT lpNewKey
;
123 LPKEYSTRUCT lpPrevKey
;
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
;
134 lpKey
= lphTopKey
; break;
135 case HKEY_CLASSES_ROOT
: /* == 1 */
137 lpKey
= lphRootKey
; break;
139 dprintf_reg(stddeb
,"RegCreateKey // specific key = %08lX !\n", hKey
);
140 lpKey
= (LPKEYSTRUCT
)GlobalLock(hKey
);
142 if (lpSubKey
== NULL
|| !*lpSubKey
) {
144 return ERROR_SUCCESS
;
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;
153 if (*lpSubKey
) lpSubKey
++;
156 lpKey
= lpKey
->lpSubLvl
;
157 while(lpKey
!= NULL
&& strcmp(lpKey
->lpSubKey
, str
) != 0) {
158 lpKey
= lpKey
->lpNextKey
;
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
;
182 dprintf_reg(stddeb
,"RegCreateKey // successful '%s' key=%08lX !\n", str
, hNewKey
);
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",
210 return ERROR_SUCCESS
;
214 /*************************************************************************
215 * RegSetValue [SHELL.5]
217 LONG
RegSetValue(HKEY hKey
, LPCSTR lpSubKey
, DWORD dwType
,
218 LPCSTR lpVal
, DWORD dwIgnored
)
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
);
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
)
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");
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);
271 strcpy(lpVal
,lpKey
->lpValue
);
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
)
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
;
298 lpKey
= lphTopKey
; break;
299 case HKEY_CLASSES_ROOT
: /* == 1 */
301 lpKey
= lphRootKey
; break;
303 dprintf_reg(stddeb
,"RegEnumKey // specific key = %08lX !\n", hKey
);
304 lpKey
= (LPKEYSTRUCT
)GlobalLock(hKey
);
306 lpKey
= lpKey
->lpSubLvl
;
307 while(lpKey
!= NULL
){
309 len
= min(dwSize
-1,strlen(lpKey
->lpSubKey
));
310 strncpy(lpBuf
,lpKey
->lpSubKey
,len
);
312 dprintf_reg(stddeb
, "RegEnumKey: found %s\n",lpBuf
);
313 return ERROR_SUCCESS
;
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");
360 /*************************************************************************
361 * ShellExecute [SHELL.20]
363 HINSTANCE
ShellExecute(HWND hWnd
, LPCSTR lpOperation
, LPCSTR lpFile
, LPCSTR lpParameters
, LPCSTR lpDirectory
, int iShowCmd
)
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 */
381 p
=strrchr(lpFile
,'.');
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")) {
389 sprintf(cmd
,"%s %s",lpFile
,lpParameters
);
395 if (RegQueryValue(HKEY_CLASSES_ROOT
,p
,subclass
,&len
)==ERROR_SUCCESS
) {
397 fprintf(stddeb
,"ShellExecute:subclass with len %ld? (%s), please report.\n",len
,subclass
);
399 strcat(subclass
,"\\shell\\");
400 strcat(subclass
,lpOperation
);
401 strcat(subclass
,"\\command");
402 dprintf_exec(stddeb
,"ShellExecute:looking for %s.\n",subclass
);
404 if (RegQueryValue(HKEY_CLASSES_ROOT
,subclass
,cmd
,&len
)==ERROR_SUCCESS
) {
406 dprintf_exec(stddeb
,"ShellExecute:...got %s\n",cmd
);
414 s
=malloc(len
+strlen(lpFile
)+10);
415 strncpy(s
,cmd
,t
-cmd
);
421 /* does this use %x magic too? */
424 strcat(cmd
,lpParameters
);
427 fprintf(stddeb
,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass
,lpOperation
,p
);
428 return 14; /* unknown type */
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");
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];
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
);
469 EndDialog(hWnd
, TRUE
);
477 /*************************************************************************
478 * ShellAbout [SHELL.22]
480 INT
ShellAbout(HWND hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
, HICON hIcon
)
484 DWORD WineProc
,Win16Proc
,Win32Proc
;
485 static int initialized
=0;
487 if (szApp
) strcpy(AppName
, szApp
);
490 if (szOtherStuff
) strcpy(AppMisc
, szOtherStuff
);
493 if (!hIcon
) hIcon
= LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON
));
497 WineProc
=(DWORD
)AboutDlgProc
;
498 Win16Proc
=(DWORD
)GetWndProcEntry16("AboutDlgProc");
499 Win32Proc
=(DWORD
)RELAY32_GetEntryPoint("WINPROCS32","AboutDlgProc",0);
500 ALIAS_RegisterAlias(WineProc
,Win16Proc
,Win32Proc
);
504 handle
= GLOBAL_CreateBlock( GMEM_FIXED
,
505 sysres_DIALOG_SHELL_ABOUT_MSGBOX
.bytes
,
506 sysres_DIALOG_SHELL_ABOUT_MSGBOX
.size
,
507 GetCurrentPDB(), FALSE
, FALSE
,
509 if (!handle
) return FALSE
;
510 bRet
= DialogBoxIndirectParam( GetWindowWord( hWnd
, GWW_HINSTANCE
),
512 GetWndProcEntry16("AboutDlgProc"), hIcon
);
513 GLOBAL_FreeBlock( handle
);
517 /*************************************************************************
518 * ExtractIcon [SHELL.34]
520 HICON
ExtractIcon(HINSTANCE hInst
, LPCSTR lpszExeFileName
, UINT nIconIndex
)
523 HINSTANCE hInst2
= hInst
;
524 dprintf_reg(stddeb
, "ExtractIcon(%04X, '%s', %d\n",
525 hInst
, lpszExeFileName
, nIconIndex
);
527 if (lpszExeFileName
!= NULL
) {
528 hInst2
= LoadModule(lpszExeFileName
,(LPVOID
)-1);
530 if (hInst2
!= 0 && nIconIndex
== (UINT
)-1) {
532 count
= GetRsrcCount(hInst2
, NE_RSCTYPE_GROUP_ICON
);
533 dprintf_reg(stddeb
, "ExtractIcon // '%s' has %d icons !\n", lpszExeFileName
, count
);
537 if (hInst2
!= hInst
&& hInst2
!= 0) {
544 /*************************************************************************
545 * ExtractAssociatedIcon [SHELL.36]
547 HICON
ExtractAssociatedIcon(HINSTANCE hInst
,LPSTR lpIconPath
, LPWORD lpiIcon
)
549 dprintf_reg(stdnimp
, "ExtractAssociatedIcon : Empty Stub !!!\n");
553 /*************************************************************************
554 * DoEnvironmentSubst [SHELL.37]
556 DWORD
DoEnvironmentSubst(LPSTR str
,WORD len
)
558 dprintf_reg(stdnimp
, "DoEnvironmentSubst(%s,%x): Empyt Stub !!!\n",str
,len
);
562 /*************************************************************************
563 * RegisterShellHook [SHELL.102]
565 int RegisterShellHook(void *ptr
)
567 dprintf_reg(stdnimp
, "RegisterShellHook : Empty Stub !!!\n");
572 /*************************************************************************
573 * ShellHookProc [SHELL.103]
575 int ShellHookProc(void)
577 dprintf_reg(stdnimp
, "ShellHookProc : Empty Stub !!!\n");