2 * Shell Library Functions
21 extern HANDLE
CURSORICON_LoadHandler( HANDLE
, HINSTANCE
, BOOL
);
22 extern WORD
GetIconID( HANDLE hResource
, DWORD resType
);
24 /*************************************************************************
25 * DragAcceptFiles [SHELL.9]
27 void DragAcceptFiles(HWND hWnd
, BOOL b
)
29 WND
* wnd
= WIN_FindWndPtr(hWnd
);
32 wnd
->dwExStyle
= b
? wnd
->dwExStyle
| WS_EX_ACCEPTFILES
33 : wnd
->dwExStyle
& ~WS_EX_ACCEPTFILES
;
37 /*************************************************************************
38 * DragQueryFile [SHELL.11]
40 UINT
DragQueryFile(HDROP hDrop
, WORD wFile
, LPSTR lpszFile
, WORD wLength
)
42 /* hDrop is a global memory block allocated with GMEM_SHARE
43 * with DROPFILESTRUCT as a header and filenames following
44 * it, zero length filename is in the end */
46 LPDROPFILESTRUCT lpDropFileStruct
;
50 dprintf_reg(stddeb
,"DragQueryFile(%04x, %i, %p, %u)\n",
51 hDrop
,wFile
,lpszFile
,wLength
);
53 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
56 dprintf_reg(stddeb
,"DragQueryFile: unable to lock handle!\n");
59 lpCurrent
= (LPSTR
) lpDropFileStruct
+ lpDropFileStruct
->wSize
;
64 while (*lpCurrent
++); /* skip filename */
66 return (wFile
== 0xFFFF) ? i
: 0;
69 i
= strlen(lpCurrent
);
70 if (!lpszFile
) return i
+1; /* needed buffer size */
72 i
= (wLength
> i
) ? i
: wLength
-1;
73 strncpy(lpszFile
, lpCurrent
, i
);
76 GlobalUnlock16(hDrop
);
81 /*************************************************************************
82 * DragFinish [SHELL.12]
84 void DragFinish(HDROP h
)
86 GlobalFree16((HGLOBAL16
)h
);
90 /*************************************************************************
91 * DragQueryPoint [SHELL.13]
93 BOOL
DragQueryPoint(HDROP hDrop
, POINT
*p
)
95 LPDROPFILESTRUCT lpDropFileStruct
;
98 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
100 memcpy(p
,&lpDropFileStruct
->ptMousePos
,sizeof(POINT
));
101 bRet
= lpDropFileStruct
->fInNonClientArea
;
103 GlobalUnlock16(hDrop
);
108 /*************************************************************************
109 * ShellExecute [SHELL.20]
111 HINSTANCE
ShellExecute(HWND hWnd
, LPCSTR lpOperation
, LPCSTR lpFile
, LPSTR lpParameters
, LPCSTR lpDirectory
, INT iShowCmd
)
118 /* OK. We are supposed to lookup the program associated with lpFile,
119 * then to execute it using that program. If lpFile is a program,
120 * we have to pass the parameters. If an instance is already running,
121 * we might have to send DDE commands.
123 * FIXME: Should also look up WIN.INI [Extensions] section?
126 dprintf_exec(stddeb
, "ShellExecute(%04x,'%s','%s','%s','%s',%x)\n",
127 hWnd
, lpOperation
? lpOperation
:"<null>", lpFile
? lpFile
:"<null>",
128 lpParameters
? lpParameters
: "<null>",
129 lpDirectory
? lpDirectory
: "<null>", iShowCmd
);
131 if (lpFile
==NULL
) return 0; /* should not happen */
132 if (lpOperation
==NULL
) /* default is open */
134 p
=strrchr(lpFile
,'.');
136 x
=p
; /* the suffixes in the register database are lowercased */
137 while (*x
) {*x
=tolower(*x
);x
++;}
139 if (p
==NULL
|| !strcmp(p
,".exe")) {
142 sprintf(cmd
,"%s %s",lpFile
,lpParameters
);
148 if (RegQueryValue((HKEY
)HKEY_CLASSES_ROOT
,p
,subclass
,&len
)==SHELL_ERROR_SUCCESS
) {
150 fprintf(stddeb
,"ShellExecute:subclass with len %ld? (%s), please report.\n",len
,subclass
);
152 strcat(subclass
,"\\shell\\");
153 strcat(subclass
,lpOperation
);
154 strcat(subclass
,"\\command");
155 dprintf_exec(stddeb
,"ShellExecute:looking for %s.\n",subclass
);
157 if (RegQueryValue((HKEY
)HKEY_CLASSES_ROOT
,subclass
,cmd
,&len
)==SHELL_ERROR_SUCCESS
) {
159 dprintf_exec(stddeb
,"ShellExecute:...got %s\n",cmd
);
167 s
=xmalloc(len
+strlen(lpFile
)+10);
168 strncpy(s
,cmd
,t
-cmd
);
175 /* does this use %x magic too? */
178 strcat(cmd
,lpParameters
);
181 fprintf(stddeb
,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass
,lpOperation
,p
);
182 return (HINSTANCE
)31; /* unknown type */
185 fprintf(stddeb
,"ShellExecute: No operation found for \"%s\" suffix.\n",p
);
186 return (HINSTANCE
)31; /* file not found */
189 dprintf_exec(stddeb
,"ShellExecute:starting %s\n",cmd
);
190 return WinExec(cmd
,iShowCmd
);
194 /*************************************************************************
195 * FindExecutable [SHELL.21]
197 HINSTANCE
FindExecutable(LPCSTR lpFile
, LPCSTR lpDirectory
, LPSTR lpResult
)
199 fprintf(stdnimp
, "FindExecutable: someone has to fix me and this is YOUR turn! :-)\n");
202 return 31; /* no association */
205 static char AppName
[128], AppMisc
[1536];
207 /*************************************************************************
208 * AboutDlgProc [SHELL.33]
210 LRESULT
AboutDlgProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
212 char Template
[512], AppTitle
[512];
217 SendDlgItemMessage(hWnd
,stc1
,STM_SETICON
,lParam
,0);
219 SendDlgItemMessage(hWnd
,stc1
,STM_SETICON
,LOWORD(lParam
),0);
221 GetWindowText(hWnd
, Template
, 511);
222 sprintf(AppTitle
, Template
, AppName
);
223 SetWindowText(hWnd
, AppTitle
);
224 SetWindowText(GetDlgItem(hWnd
,100), AppMisc
);
230 EndDialog(hWnd
, TRUE
);
238 /*************************************************************************
239 * ShellAbout [SHELL.22]
241 INT
ShellAbout(HWND hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
, HICON hIcon
)
246 if (szApp
) strncpy(AppName
, szApp
, sizeof(AppName
));
248 AppName
[sizeof(AppName
)-1]=0;
250 if (szOtherStuff
) strncpy(AppMisc
, szOtherStuff
, sizeof(AppMisc
));
252 AppMisc
[sizeof(AppMisc
)-1]=0;
254 if (!hIcon
) hIcon
= LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON
));
255 handle
= SYSRES_LoadResource( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX
);
256 if (!handle
) return FALSE
;
257 bRet
= DialogBoxIndirectParam( WIN_GetWindowInstance( hWnd
),
259 MODULE_GetWndProcEntry16("AboutDlgProc"),
261 SYSRES_FreeResource( handle
);
265 /*************************************************************************
266 * SHELL_GetResourceTable
268 * FIXME: Implement GetPEResourceTable in w32sys.c and call it here.
270 BYTE
* SHELL_GetResourceTable(HFILE hFile
)
272 struct mz_header_s mz_header
;
273 struct ne_header_s ne_header
;
276 _llseek( hFile
, 0, SEEK_SET
);
277 if ((FILE_Read(hFile
,&mz_header
,sizeof(mz_header
)) != sizeof(mz_header
)) ||
278 (mz_header
.mz_magic
!= MZ_SIGNATURE
)) return (BYTE
*)-1;
280 _llseek( hFile
, mz_header
.ne_offset
, SEEK_SET
);
281 if (FILE_Read( hFile
, &ne_header
, sizeof(ne_header
) ) != sizeof(ne_header
))
284 if (ne_header
.ne_magic
== PE_SIGNATURE
)
285 { fprintf(stdnimp
,"Win32 FIXME: file %s line %i\n", __FILE__
, __LINE__
);
288 if (ne_header
.ne_magic
!= NE_SIGNATURE
) return NULL
;
290 size
= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
292 if( size
> sizeof(NE_TYPEINFO
) )
294 BYTE
* pTypeInfo
= (BYTE
*)xmalloc(size
);
296 if( !pTypeInfo
) return NULL
;
298 _llseek(hFile
, mz_header
.ne_offset
+ne_header
.resource_tab_offset
, SEEK_SET
);
299 if( FILE_Read( hFile
, (char*)pTypeInfo
, size
) != size
)
300 { free(pTypeInfo
); return NULL
; }
308 /*************************************************************************
311 HANDLE
SHELL_LoadResource(HINSTANCE hInst
, HFILE hFile
, NE_NAMEINFO
* pNInfo
, WORD sizeShift
)
314 HANDLE handle
= DirectResAlloc( hInst
, 0x10, (DWORD
)pNInfo
->length
<< sizeShift
);
316 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
318 _llseek( hFile
, (DWORD
)pNInfo
->offset
<< sizeShift
, SEEK_SET
);
319 FILE_Read( hFile
, (char*)ptr
, pNInfo
->length
<< sizeShift
);
325 /*************************************************************************
326 * InternalExtractIcon [SHELL.39]
328 * This abortion is called directly by Progman
330 HICON
InternalExtractIcon(HINSTANCE hInstance
, LPCSTR lpszExeFileName
, UINT nIconIndex
, WORD n
)
333 HICON
* RetPtr
= NULL
;
336 HFILE hFile
= OpenFile( lpszExeFileName
, &ofs
, OF_READ
);
338 dprintf_reg(stddeb
, "InternalExtractIcon(%04x, file '%s', start from %d, extract %d\n",
339 hInstance
, lpszExeFileName
, nIconIndex
, n
);
341 if( hFile
== HFILE_ERROR
|| !n
) return 0;
343 hRet
= GlobalAlloc16( GMEM_FIXED
, sizeof(HICON
)*n
);
344 RetPtr
= (HICON
*)GlobalLock16(hRet
);
346 *RetPtr
= (n
== 0xFFFF)? 0: 1; /* error return values */
348 pData
= SHELL_GetResourceTable(hFile
);
350 if( pData
== (BYTE
*)-1 )
352 /* FIXME: possible .ICO file */
354 fprintf(stddeb
,"InternalExtractIcon: cannot handle file %s\n", lpszExeFileName
);
356 else /* got resource table */
358 UINT iconDirCount
= 0;
360 NE_TYPEINFO
* pTInfo
= (NE_TYPEINFO
*)(pData
+ 2);
361 NE_NAMEINFO
* pIconStorage
= NULL
;
362 NE_NAMEINFO
* pIconDir
= NULL
;
364 /* find icon directory and icon repository */
366 while( pTInfo
->type_id
&& !(pIconStorage
&& pIconDir
) )
368 if( pTInfo
->type_id
== NE_RSCTYPE_GROUP_ICON
)
370 iconDirCount
= pTInfo
->count
;
371 pIconDir
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
372 dprintf_reg(stddeb
,"\tfound directory - %i icon families\n", iconDirCount
);
374 if( pTInfo
->type_id
== NE_RSCTYPE_ICON
)
376 iconCount
= pTInfo
->count
;
377 pIconStorage
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
378 dprintf_reg(stddeb
,"\ttotal icons - %i\n", iconCount
);
380 pTInfo
= (NE_TYPEINFO
*)((char*)(pTInfo
+1)+pTInfo
->count
*sizeof(NE_NAMEINFO
));
383 /* load resources and create icons */
385 if( pIconStorage
&& pIconDir
)
387 if( nIconIndex
== (UINT
)-1 ) RetPtr
[0] = iconDirCount
;
388 else if( nIconIndex
< iconDirCount
)
393 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
395 for( i
= nIconIndex
; i
< nIconIndex
+ n
; i
++ )
397 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconDir
+ (i
- nIconIndex
),
399 RetPtr
[i
-nIconIndex
] = GetIconID( hIcon
, 3 );
403 for( icon
= nIconIndex
; icon
< nIconIndex
+ n
; icon
++ )
406 for( i
= 0; i
< iconCount
; i
++ )
407 if( pIconStorage
[i
].id
== (RetPtr
[icon
-nIconIndex
] | 0x8000) )
408 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconStorage
+ i
,
410 RetPtr
[icon
-nIconIndex
] = (hIcon
)?CURSORICON_LoadHandler( hIcon
, hInstance
, FALSE
):0;
418 /* return array with icon handles */
423 /*************************************************************************
424 * ExtractIcon [SHELL.34]
426 HICON
ExtractIcon(HINSTANCE hInstance
, LPCSTR lpszExeFileName
, WORD nIconIndex
)
428 HANDLE handle
= InternalExtractIcon(hInstance
,lpszExeFileName
,nIconIndex
, 1);
432 HICON
* ptr
= (HICON
*)GlobalLock16(handle
);
435 GlobalFree16(handle
);
441 /*************************************************************************
442 * ExtractAssociatedIcon [SHELL.36]
444 HICON
ExtractAssociatedIcon(HINSTANCE hInst
,LPSTR lpIconPath
, LPWORD lpiIcon
)
446 HICON hIcon
= ExtractIcon(hInst
, lpIconPath
, *lpiIcon
);
448 /* MAKEINTRESOURCE(2) seems to be "default" icon according to Progman
450 * For data files it probably should call FindExecutable and load
451 * icon from there. As of now FindExecutable is empty stub.
454 if( hIcon
< 2 ) hIcon
= LoadIcon( hInst
, MAKEINTRESOURCE(2));
459 /*************************************************************************
460 * FindEnvironmentString [SHELL.38]
462 * Returns a pointer into the DOS environment... Ugh.
464 LPSTR
SHELL_FindString(LPSTR lpEnv
, LPCSTR entry
)
466 UINT l
= strlen(entry
);
467 for( ; *lpEnv
; lpEnv
+=strlen(lpEnv
)+1 )
469 if( strncasecmp(lpEnv
, entry
, l
) ) continue;
472 return (lpEnv
+ l
); /* empty entry */
473 else if ( *(lpEnv
+l
)== '=' )
474 return (lpEnv
+ l
+ 1);
479 SEGPTR
FindEnvironmentString(LPSTR str
)
481 SEGPTR spEnv
= GetDOSEnvironment();
482 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(spEnv
);
484 LPSTR lpString
= (spEnv
)?SHELL_FindString(lpEnv
, str
):NULL
;
486 if( lpString
) /* offset should be small enough */
487 return spEnv
+ (lpString
- lpEnv
);
492 /*************************************************************************
493 * DoEnvironmentSubst [SHELL.37]
495 * Replace %KEYWORD% in the str with the value of variable KEYWORD
496 * from "DOS" environment.
498 DWORD
DoEnvironmentSubst(LPSTR str
,WORD length
)
500 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(GetDOSEnvironment());
501 LPSTR lpBuffer
= (LPSTR
)xmalloc(length
);
503 LPSTR lpbstr
= lpBuffer
;
507 dprintf_reg(stddeb
,"DoEnvSubst: accept %s", str
);
509 while( *lpstr
&& lpbstr
- lpBuffer
< length
)
515 do { lpend
++; } while( *lpend
&& *lpend
!= '%' );
516 if( *lpend
== '%' && lpend
- lpstr
> 1 ) /* found key */
520 lpKey
= SHELL_FindString(lpEnv
, lpstr
+1);
521 if( lpKey
) /* found key value */
523 int l
= strlen(lpKey
);
525 if( l
> length
- (lpbstr
- lpBuffer
) - 1 )
527 fprintf(stdnimp
,"File %s, line %i: Env subst aborted - string too short\n",
532 strcpy(lpbstr
, lpKey
);
539 else break; /* back off and whine */
544 *lpbstr
++ = *lpstr
++;
548 if( lpstr
- str
== strlen(str
) )
550 strncpy(str
, lpBuffer
, length
);
556 dprintf_reg(stddeb
," return %s\n", str
);
561 /* Return str length in the LOWORD
562 * and 1 in HIWORD if subst was successful.
564 return (DWORD
)MAKELONG(strlen(str
), length
);
567 /*************************************************************************
568 * RegisterShellHook [SHELL.102]
570 int RegisterShellHook(void *ptr
)
572 dprintf_reg(stdnimp
, "RegisterShellHook : Empty Stub !!!\n");
577 /*************************************************************************
578 * ShellHookProc [SHELL.103]
580 int ShellHookProc(void)
582 dprintf_reg(stdnimp
, "ShellHookProc : Empty Stub !!!\n");