2 * Shell Library Functions
12 #include "selectors.h"
22 LPKEYSTRUCT lphRootKey = NULL,lphTopKey = NULL;
24 static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]";
26 /*************************************************************************
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");
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");
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 /* FIXME: the loading and saving of the registry database is rather messy.
64 * bad input (while reading) may crash wine.
67 _DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs)
71 lpKey=lpTKey->lpSubLvl;
74 for (i=0;i<tabs;i++) fprintf(f,"\t");
75 /* implement different dwTypes ... */
77 fprintf(f,"%s=%s\n",lpKey->lpSubKey,lpKey->lpValue);
79 fprintf(f,"%s\n",lpKey->lpSubKey);
82 _DumpLevel(f,lpKey,tabs+1);
83 lpKey=lpKey->lpNextKey;
88 _SaveKey(HKEY hKey,char *where)
95 perror("registry-fopen");
98 switch ((DWORD)hKey) {
99 case HKEY_CLASSES_ROOT:
104 _DumpLevel(f,lpKey,0);
109 SHELL_SaveRegistry(void)
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");
121 _LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf)
126 LPKEYSTRUCT lpNewKey;
129 if (NULL==fgets(buf,BUFSIZE,f)) {
133 for (i=0;buf[i]=='\t';i++) /*empty*/;
135 if (NULL!=(t=strchr(s,'\n'))) *t='\0';
136 if (NULL!=(t=strchr(s,'\r'))) *t='\0';
138 if (i<tabsexp) return;
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,'='))) {
152 lpNewKey->dwType = REG_SZ;
153 lpNewKey->lpSubKey = xstrdup(s);
154 lpNewKey->lpValue = xstrdup(t);
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*/;
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,'='))) {
177 lpNewKey->dwType = REG_SZ;
178 lpNewKey->lpSubKey = xstrdup(s);
179 lpNewKey->lpValue = xstrdup(t);
181 lpNewKey->dwType = REG_SZ;
182 lpNewKey->lpSubKey = xstrdup(s);
189 _LoadKey(HKEY hKey,char *from)
193 char buf[BUFSIZE]; /* FIXME: long enough? */
197 dprintf_reg(stddeb,"fopen-registry-read");
200 switch ((DWORD)hKey) {
201 case HKEY_CLASSES_ROOT:
206 _LoadLevel(f,lpKey,-1,buf);
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;
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) {
229 lpKey = lphTopKey; break;
230 case HKEY_CLASSES_ROOT: /* == 1 */
233 lpKey = lphRootKey; break;
235 dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", (DWORD)hKey);
236 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
238 if (lpSubKey == NULL || !*lpSubKey) {
240 return SHELL_ERROR_SUCCESS;
243 ptr = strchr(lpSubKey,'\\');
244 if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
245 strncpy(str,lpSubKey,ptr-lpSubKey);
246 str[ptr-lpSubKey] = 0;
248 if (*lpSubKey) lpSubKey++;
250 lpNextKey = lpKey->lpSubLvl;
251 while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
253 if (lpKey) lpNextKey = lpKey->lpNextKey;
256 dprintf_reg(stddeb,"RegOpenKey: key %s not found!\n",str);
257 return SHELL_ERROR_BADKEY;
260 *lphKey = lpKey->hKey;
261 return SHELL_ERROR_SUCCESS;
265 /*************************************************************************
266 * RegCreateKey [SHELL.2]
268 LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, LPHKEY lphKey)
271 LPKEYSTRUCT lpNewKey;
273 LPKEYSTRUCT lpPrevKey;
277 dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", (DWORD)hKey, lpSubKey, lphKey);
278 if (lphKey == NULL) return SHELL_ERROR_INVALID_PARAMETER;
279 switch((DWORD)hKey) {
281 lpKey = lphTopKey; break;
282 case HKEY_CLASSES_ROOT: /* == 1 */
285 lpKey = lphRootKey; break;
287 dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", (DWORD)hKey);
288 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
290 if (lpSubKey == NULL || !*lpSubKey) {
292 return SHELL_ERROR_SUCCESS;
295 dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey);
296 ptr = strchr(lpSubKey,'\\');
297 if (!ptr) ptr = lpSubKey + strlen(lpSubKey);
298 strncpy(str,lpSubKey,ptr-lpSubKey);
299 str[ptr-lpSubKey] = 0;
301 if (*lpSubKey) lpSubKey++;
304 lpKey = lpKey->lpSubLvl;
305 while(lpKey != NULL && strcmp(lpKey->lpSubKey, str) != 0) {
306 lpKey = lpKey->lpNextKey;
309 hNewKey = GlobalAlloc(GMEM_MOVEABLE, sizeof(KEYSTRUCT));
310 lpNewKey = (LPKEYSTRUCT) GlobalLock(hNewKey);
311 if (lpNewKey == NULL) {
312 printf("RegCreateKey // Can't alloc new key !\n");
313 return SHELL_ERROR_OUTOFMEMORY;
315 lpNewKey->hKey = hNewKey;
316 lpNewKey->lpSubKey = malloc(strlen(str) + 1);
317 if (lpNewKey->lpSubKey == NULL) {
318 printf("RegCreateKey // Can't alloc key string !\n");
319 return SHELL_ERROR_OUTOFMEMORY;
321 strcpy(lpNewKey->lpSubKey, str);
322 lpNewKey->lpNextKey = lpPrevKey->lpSubLvl;
323 lpNewKey->lpPrevKey = NULL;
324 lpPrevKey->lpSubLvl = lpNewKey;
326 lpNewKey->dwType = 0;
327 lpNewKey->lpValue = NULL;
328 lpNewKey->lpSubLvl = NULL;
330 dprintf_reg(stddeb,"RegCreateKey // successful '%s' key=%08lX !\n", str, (DWORD)hNewKey);
333 *lphKey = lpKey->hKey;
334 dprintf_reg(stddeb,"RegCreateKey // found '%s', key=%08lX\n", str, (DWORD)*lphKey);
337 return SHELL_ERROR_SUCCESS;
341 /*************************************************************************
342 * RegCloseKey [SHELL.3]
344 LONG RegCloseKey(HKEY hKey)
346 dprintf_reg(stdnimp, "EMPTY STUB !!! RegCloseKey(%08lX);\n", (DWORD)hKey);
347 return SHELL_ERROR_SUCCESS;
351 /*************************************************************************
352 * RegDeleteKey [SHELL.4]
354 LONG RegDeleteKey(HKEY hKey, LPCSTR lpSubKey)
356 dprintf_reg(stdnimp, "EMPTY STUB !!! RegDeleteKey(%08lX, '%s');\n",
357 (DWORD)hKey, lpSubKey);
358 return SHELL_ERROR_SUCCESS;
362 /*************************************************************************
363 * RegSetValue [SHELL.5]
365 LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType,
366 LPCSTR lpVal, DWORD dwIgnored)
371 dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n",
372 (DWORD)hKey, lpSubKey, dwType, lpVal, dwIgnored);
373 /*if (lpSubKey == NULL) return SHELL_ERROR_INVALID_PARAMETER;*/
374 if (lpVal == NULL) return SHELL_ERROR_INVALID_PARAMETER;
375 if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) {
376 dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
377 if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) {
378 fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet);
382 lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
383 if (lpKey == NULL) return SHELL_ERROR_BADKEY;
384 if (lpKey->lpValue != NULL) free(lpKey->lpValue);
385 lpKey->lpValue = xmalloc(strlen(lpVal) + 1);
386 strcpy(lpKey->lpValue, lpVal);
387 dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpKey->lpValue);
388 return SHELL_ERROR_SUCCESS;
392 /*************************************************************************
393 * RegQueryValue [SHELL.6]
395 LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LPLONG lpcb)
401 dprintf_reg(stddeb, "RegQueryValue(%08lX, '%s', %p, %p);\n",
402 (DWORD)hKey, lpSubKey, lpVal, lpcb);
403 /*if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;*/
404 if (lpVal == NULL) return SHELL_ERROR_INVALID_PARAMETER;
405 if (lpcb == NULL) return SHELL_ERROR_INVALID_PARAMETER;
406 if (!*lpcb) return SHELL_ERROR_INVALID_PARAMETER;
408 if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != SHELL_ERROR_SUCCESS) {
409 fprintf(stderr, "RegQueryValue // key not found !\n");
412 lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
413 if (lpKey == NULL) return SHELL_ERROR_BADKEY;
414 if (lpKey->lpValue != NULL) {
415 if ((size = strlen(lpKey->lpValue)+1) > *lpcb){
416 strncpy(lpVal,lpKey->lpValue,*lpcb-1);
419 strcpy(lpVal,lpKey->lpValue);
426 dprintf_reg(stddeb,"RegQueryValue // return '%s' !\n", lpVal);
427 return SHELL_ERROR_SUCCESS;
431 /*************************************************************************
432 * RegEnumKey [SHELL.7]
434 LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize)
439 dprintf_reg(stddeb, "RegEnumKey(%08lX, %ld)\n", (DWORD)hKey, dwSubKey);
440 if (lpBuf == NULL) return SHELL_ERROR_INVALID_PARAMETER;
441 switch((DWORD)hKey) {
443 lpKey = lphTopKey; break;
444 case HKEY_CLASSES_ROOT: /* == 1 */
447 lpKey = lphRootKey; break;
449 dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", (DWORD)hKey);
450 lpKey = (LPKEYSTRUCT)GlobalLock(hKey);
452 lpKey = lpKey->lpSubLvl;
453 while(lpKey != NULL){
455 len = MIN(dwSize-1,strlen(lpKey->lpSubKey));
456 strncpy(lpBuf,lpKey->lpSubKey,len);
458 dprintf_reg(stddeb, "RegEnumKey: found %s\n",lpBuf);
459 return SHELL_ERROR_SUCCESS;
462 lpKey = lpKey->lpNextKey;
464 dprintf_reg(stddeb, "RegEnumKey: key not found!\n");
465 return SHELL_ERROR_INVALID_PARAMETER;
469 /*************************************************************************
470 * DragAcceptFiles [SHELL.9]
472 void DragAcceptFiles(HWND hWnd, BOOL b)
474 /* flips WS_EX_ACCEPTFILES bit according to the value of b */
475 dprintf_reg(stddeb,"DragAcceptFiles(%04x, %u) old exStyle %08lx\n",
476 hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE));
478 SetWindowLong(hWnd,GWL_EXSTYLE,
479 GetWindowLong(hWnd,GWL_EXSTYLE) | b*(LONG)WS_EX_ACCEPTFILES);
483 /*************************************************************************
484 * DragQueryFile [SHELL.11]
486 UINT DragQueryFile(HDROP hDrop, WORD wFile, LPSTR lpszFile, WORD wLength)
488 /* hDrop is a global memory block allocated with GMEM_SHARE
489 * with DROPFILESTRUCT as a header and filenames following
490 * it, zero length filename is in the end */
492 LPDROPFILESTRUCT lpDropFileStruct;
496 dprintf_reg(stddeb,"DragQueryFile(%04x, %i, %p, %u)\n",
497 hDrop,wFile,lpszFile,wLength);
499 lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
500 if(!lpDropFileStruct)
502 dprintf_reg(stddeb,"DragQueryFile: unable to lock handle!\n");
505 lpCurrent = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
510 while (*lpCurrent++); /* skip filename */
512 return (wFile == 0xFFFF) ? i : 0;
515 i = strlen(lpCurrent);
516 if (!lpszFile) return i+1; /* needed buffer size */
518 i = (wLength > i) ? i : wLength-1;
519 strncpy(lpszFile, lpCurrent, i);
527 /*************************************************************************
528 * DragFinish [SHELL.12]
530 void DragFinish(HDROP h)
532 GlobalFree((HGLOBAL)h);
536 /*************************************************************************
537 * DragQueryPoint [SHELL.13]
539 BOOL DragQueryPoint(HDROP hDrop, POINT FAR *p)
541 LPDROPFILESTRUCT lpDropFileStruct;
544 lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
546 memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT));
547 bRet = lpDropFileStruct->fInNonClientArea;
554 /*************************************************************************
555 * ShellExecute [SHELL.20]
557 HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
563 /* OK. We are supposed to lookup the program associated with lpFile,
564 * then to execute it using that program. If lpFile is a program,
565 * we have to pass the parameters. If an instance is already running,
566 * we might have to send DDE commands.
568 dprintf_exec(stddeb, "ShellExecute(%04x,'%s','%s','%s','%s',%x)\n",
569 hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
570 lpParameters ? lpParameters : "<null>",
571 lpDirectory ? lpDirectory : "<null>", iShowCmd);
572 if (lpFile==NULL) return 0; /* should not happen */
573 if (lpOperation==NULL) /* default is open */
575 p=strrchr(lpFile,'.');
577 x=p; /* the suffixes in the register database are lowercased */
578 while (*x) {*x=tolower(*x);x++;}
580 if (p==NULL || !strcmp(p,".exe")) {
583 sprintf(cmd,"%s %s",lpFile,lpParameters);
589 if (RegQueryValue((HKEY)HKEY_CLASSES_ROOT,p,subclass,&len)==SHELL_ERROR_SUCCESS) {
591 fprintf(stddeb,"ShellExecute:subclass with len %ld? (%s), please report.\n",len,subclass);
593 strcat(subclass,"\\shell\\");
594 strcat(subclass,lpOperation);
595 strcat(subclass,"\\command");
596 dprintf_exec(stddeb,"ShellExecute:looking for %s.\n",subclass);
598 if (RegQueryValue((HKEY)HKEY_CLASSES_ROOT,subclass,cmd,&len)==SHELL_ERROR_SUCCESS) {
600 dprintf_exec(stddeb,"ShellExecute:...got %s\n",cmd);
608 s=xmalloc(len+strlen(lpFile)+10);
609 strncpy(s,cmd,t-cmd);
616 /* does this use %x magic too? */
619 strcat(cmd,lpParameters);
622 fprintf(stddeb,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass,lpOperation,p);
623 return (HINSTANCE)14; /* unknown type */
626 fprintf(stddeb,"ShellExecute: No operation found for \"%s\" suffix.\n",p);
627 return (HINSTANCE)14; /* file not found */
630 dprintf_exec(stddeb,"ShellExecute:starting %s\n",cmd);
631 return WinExec(cmd,iShowCmd);
635 /*************************************************************************
636 * FindExecutable [SHELL.21]
638 HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
640 fprintf(stdnimp, "FindExecutable : Empty Stub !!!\n");
644 static char AppName[128], AppMisc[906];
646 /*************************************************************************
647 * AboutDlgProc [SHELL.33]
649 LRESULT AboutDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
651 char Template[512], AppTitle[512];
656 SendDlgItemMessage(hWnd,stc1,STM_SETICON,lParam,0);
658 SendDlgItemMessage(hWnd,stc1,STM_SETICON,LOWORD(lParam),0);
660 GetWindowText(hWnd, Template, 511);
661 sprintf(AppTitle, Template, AppName);
662 SetWindowText(hWnd, AppTitle);
663 SetWindowText(GetDlgItem(hWnd,100), AppMisc);
669 EndDialog(hWnd, TRUE);
677 /*************************************************************************
678 * ShellAbout [SHELL.22]
680 INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
684 DWORD WineProc,Win16Proc,Win32Proc;
685 static int initialized=0;
687 if (szApp) strncpy(AppName, szApp, sizeof(AppName));
689 AppName[sizeof(AppName)-1]=0;
691 if (szOtherStuff) strncpy(AppMisc, szOtherStuff, sizeof(AppMisc));
693 AppMisc[sizeof(AppMisc)-1]=0;
695 if (!hIcon) hIcon = LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON));
699 WineProc=(DWORD)AboutDlgProc;
700 Win16Proc=(DWORD)GetWndProcEntry16("AboutDlgProc");
701 Win32Proc=(DWORD)RELAY32_GetEntryPoint(RELAY32_GetBuiltinDLL("WINPROCS32"),
703 ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc);
707 handle = SYSRES_LoadResource( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX );
708 if (!handle) return FALSE;
709 bRet = DialogBoxIndirectParam( WIN_GetWindowInstance( hWnd ),
711 GetWndProcEntry16("AboutDlgProc"),
713 SYSRES_FreeResource( handle );
717 /*************************************************************************
718 * ExtractIcon [SHELL.34]
720 HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
723 HINSTANCE hInst2 = hInst;
724 dprintf_reg(stddeb, "ExtractIcon(%04x, '%s', %d\n",
725 hInst, lpszExeFileName, nIconIndex);
727 if (lpszExeFileName != NULL) {
728 hInst2 = LoadModule(lpszExeFileName,(LPVOID)-1);
730 if (hInst2 != 0 && nIconIndex == (UINT)-1) {
732 count = GetRsrcCount(hInst2, NE_RSCTYPE_GROUP_ICON);
733 dprintf_reg(stddeb, "ExtractIcon // '%s' has %d icons !\n", lpszExeFileName, count);
737 if (hInst2 != hInst && hInst2 != 0) {
744 /*************************************************************************
745 * ExtractAssociatedIcon [SHELL.36]
747 HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
749 dprintf_reg(stdnimp, "ExtractAssociatedIcon : Empty Stub !!!\n");
753 /*************************************************************************
754 * DoEnvironmentSubst [SHELL.37]
756 DWORD DoEnvironmentSubst(LPSTR str,WORD len)
758 dprintf_reg(stdnimp, "DoEnvironmentSubst(%s,%x): Empty Stub !!!\n",str,len);
762 /*************************************************************************
763 * RegisterShellHook [SHELL.102]
765 int RegisterShellHook(void *ptr)
767 dprintf_reg(stdnimp, "RegisterShellHook : Empty Stub !!!\n");
772 /*************************************************************************
773 * ShellHookProc [SHELL.103]
775 int ShellHookProc(void)
777 dprintf_reg(stdnimp, "ShellHookProc : Empty Stub !!!\n");