2 * Shell Library Functions
4 * currently work in progress on SH* and SHELL32_DllGetClassObject functions
5 * <contact juergen.schmied@metronet.de 980624>
23 #include "cursoricon.h"
24 #include "interfaces.h"
25 #include "sysmetrics.h"
30 static const char * const SHELL_People
[] =
47 "Niels de Carpentier",
54 "Frans van Dorsselaer",
107 "Philippe De Muyter",
120 "Bernhard Rosenkraenzer",
121 "Johannes Ruscheinski",
123 "Constantine Sapuntzakis",
131 "Yngvi Sigurjonsson",
146 "Gregory Trubetskoy",
159 "Karl Guenter Wuensch",
162 "Nikita V. Youshchenko",
165 "Luiz Otavio L. Zorzella",
170 /* .ICO file ICONDIR definitions */
176 BYTE bWidth
; /* Width, in pixels, of the image */
177 BYTE bHeight
; /* Height, in pixels, of the image */
178 BYTE bColorCount
; /* Number of colors in image (0 if >=8bpp) */
179 BYTE bReserved
; /* Reserved ( must be 0) */
180 WORD wPlanes
; /* Color Planes */
181 WORD wBitCount
; /* Bits per pixel */
182 DWORD dwBytesInRes
; /* How many bytes in this resource? */
183 DWORD dwImageOffset
; /* Where in the file is this image? */
184 } icoICONDIRENTRY
, *LPicoICONDIRENTRY
;
188 WORD idReserved
; /* Reserved (must be 0) */
189 WORD idType
; /* Resource Type (1 for icons) */
190 WORD idCount
; /* How many images? */
191 icoICONDIRENTRY idEntries
[1]; /* An entry for each image (idCount of 'em) */
192 } icoICONDIR
, *LPicoICONDIR
;
196 static const char* lpstrMsgWndCreated
= "OTHERWINDOWCREATED";
197 static const char* lpstrMsgWndDestroyed
= "OTHERWINDOWDESTROYED";
198 static const char* lpstrMsgShellActivate
= "ACTIVATESHELLWINDOW";
200 static HWND16 SHELL_hWnd
= 0;
201 static HHOOK SHELL_hHook
= 0;
202 static UINT16 uMsgWndCreated
= 0;
203 static UINT16 uMsgWndDestroyed
= 0;
204 static UINT16 uMsgShellActivate
= 0;
206 /*************************************************************************
207 * DragAcceptFiles [SHELL.9]
209 void WINAPI
DragAcceptFiles(HWND16 hWnd
, BOOL16 b
)
211 WND
* wnd
= WIN_FindWndPtr(hWnd
);
214 wnd
->dwExStyle
= b
? wnd
->dwExStyle
| WS_EX_ACCEPTFILES
215 : wnd
->dwExStyle
& ~WS_EX_ACCEPTFILES
;
219 /*************************************************************************
220 * DragQueryFile [SHELL.11]
222 UINT16 WINAPI
DragQueryFile(HDROP16 hDrop
, WORD wFile
, LPSTR lpszFile
,
225 /* hDrop is a global memory block allocated with GMEM_SHARE
226 * with DROPFILESTRUCT as a header and filenames following
227 * it, zero length filename is in the end */
229 LPDROPFILESTRUCT lpDropFileStruct
;
233 TRACE(reg
,"(%04x, %i, %p, %u)\n",
234 hDrop
,wFile
,lpszFile
,wLength
);
236 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
237 if(!lpDropFileStruct
) return 0;
239 lpCurrent
= (LPSTR
) lpDropFileStruct
+ lpDropFileStruct
->wSize
;
244 while (*lpCurrent
++); /* skip filename */
246 return (wFile
== 0xFFFF) ? i
: 0;
249 i
= strlen(lpCurrent
);
250 if (!lpszFile
) return i
+1; /* needed buffer size */
252 i
= (wLength
> i
) ? i
: wLength
-1;
253 strncpy(lpszFile
, lpCurrent
, i
);
256 GlobalUnlock16(hDrop
);
261 /*************************************************************************
262 * DragFinish [SHELL.12]
264 void WINAPI
DragFinish(HDROP16 h
)
266 GlobalFree16((HGLOBAL16
)h
);
270 /*************************************************************************
271 * DragQueryPoint [SHELL.13]
273 BOOL16 WINAPI
DragQueryPoint(HDROP16 hDrop
, POINT16
*p
)
275 LPDROPFILESTRUCT lpDropFileStruct
;
278 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
280 memcpy(p
,&lpDropFileStruct
->ptMousePos
,sizeof(POINT16
));
281 bRet
= lpDropFileStruct
->fInNonClientArea
;
283 GlobalUnlock16(hDrop
);
287 /*************************************************************************
288 * SHELL_FindExecutable [Internal]
290 * Utility for code sharing between FindExecutable and ShellExecute
292 static HINSTANCE32
SHELL_FindExecutable( LPCSTR lpFile
,
296 char *extension
= NULL
; /* pointer to file extension */
297 char tmpext
[5]; /* local copy to mung as we please */
298 char filetype
[256]; /* registry name for this filetype */
299 LONG filetypelen
=256; /* length of above */
300 char command
[256]; /* command from registry */
301 LONG commandlen
=256; /* This is the most DOS can handle :) */
302 char buffer
[256]; /* Used to GetProfileString */
303 HINSTANCE32 retval
=31; /* default - 'No association was found' */
304 char *tok
; /* token pointer */
305 int i
; /* random counter */
306 char xlpFile
[256]; /* result of SearchPath */
308 TRACE(exec
, "%s\n", (lpFile
!= NULL
?lpFile
:"-") );
310 lpResult
[0]='\0'; /* Start off with an empty return string */
312 /* trap NULL parameters on entry */
313 if (( lpFile
== NULL
) || ( lpResult
== NULL
) || ( lpOperation
== NULL
))
315 WARN(exec
, "(lpFile=%s,lpResult=%s,lpOperation=%s): NULL parameter\n",
316 lpFile
, lpOperation
, lpResult
);
317 return 2; /* File not found. Close enough, I guess. */
320 if (SearchPath32A( NULL
, lpFile
,".exe",sizeof(xlpFile
),xlpFile
,NULL
))
322 TRACE(exec
, "SearchPath32A returned non-zero\n");
326 /* First thing we need is the file's extension */
327 extension
= strrchr( xlpFile
, '.' ); /* Assume last "." is the one; */
328 /* File->Run in progman uses */
330 TRACE(exec
, "xlpFile=%s,extension=%s\n", xlpFile
, extension
);
332 if ((extension
== NULL
) || (extension
== &xlpFile
[strlen(xlpFile
)]))
334 WARN(exec
, "Returning 31 - No association\n");
335 return 31; /* no association */
338 /* Make local copy & lowercase it for reg & 'programs=' lookup */
339 lstrcpyn32A( tmpext
, extension
, 5 );
340 CharLower32A( tmpext
);
341 TRACE(exec
, "%s file\n", tmpext
);
343 /* Three places to check: */
344 /* 1. win.ini, [windows], programs (NB no leading '.') */
345 /* 2. Registry, HKEY_CLASS_ROOT\<filetype>\shell\open\command */
346 /* 3. win.ini, [extensions], extension (NB no leading '.' */
347 /* All I know of the order is that registry is checked before */
348 /* extensions; however, it'd make sense to check the programs */
349 /* section first, so that's what happens here. */
351 /* See if it's a program - if GetProfileString fails, we skip this
352 * section. Actually, if GetProfileString fails, we've probably
353 * got a lot more to worry about than running a program... */
354 if ( GetProfileString32A("windows", "programs", "exe pif bat com",
355 buffer
, sizeof(buffer
)) > 0 )
357 for (i
=0;i
<strlen(buffer
); i
++) buffer
[i
]=tolower(buffer
[i
]);
359 tok
= strtok(buffer
, " \t"); /* ? */
362 if (strcmp(tok
, &tmpext
[1])==0) /* have to skip the leading "." */
364 strcpy(lpResult
, xlpFile
);
365 /* Need to perhaps check that the file has a path
367 TRACE(exec
, "found %s\n",
371 /* Greater than 32 to indicate success FIXME According to the
372 * docs, I should be returning a handle for the
373 * executable. Does this mean I'm supposed to open the
374 * executable file or something? More RTFM, I guess... */
376 tok
=strtok(NULL
, " \t");
381 if (RegQueryValue16( HKEY_CLASSES_ROOT
, tmpext
, filetype
,
382 &filetypelen
) == ERROR_SUCCESS
)
384 filetype
[filetypelen
]='\0';
385 TRACE(exec
, "File type: %s\n",
388 /* Looking for ...buffer\shell\lpOperation\command */
389 strcat( filetype
, "\\shell\\" );
390 strcat( filetype
, lpOperation
);
391 strcat( filetype
, "\\command" );
393 if (RegQueryValue16( HKEY_CLASSES_ROOT
, filetype
, command
,
394 &commandlen
) == ERROR_SUCCESS
)
396 /* Is there a replace() function anywhere? */
397 command
[commandlen
]='\0';
398 strcpy( lpResult
, command
);
399 tok
=strstr( lpResult
, "%1" );
402 tok
[0]='\0'; /* truncate string at the percent */
403 strcat( lpResult
, xlpFile
); /* what if no dir in xlpFile? */
404 tok
=strstr( command
, "%1" );
405 if ((tok
!=NULL
) && (strlen(tok
)>2))
407 strcat( lpResult
, &tok
[2] );
410 retval
=33; /* FIXME see above */
413 else /* Check win.ini */
415 /* Toss the leading dot */
417 if ( GetProfileString32A( "extensions", extension
, "", command
,
418 sizeof(command
)) > 0)
420 if (strlen(command
)!=0)
422 strcpy( lpResult
, command
);
423 tok
=strstr( lpResult
, "^" ); /* should be ^.extension? */
427 strcat( lpResult
, xlpFile
); /* what if no dir in xlpFile? */
428 tok
=strstr( command
, "^" ); /* see above */
429 if ((tok
!= NULL
) && (strlen(tok
)>5))
431 strcat( lpResult
, &tok
[5]);
434 retval
=33; /* FIXME - see above */
439 TRACE(exec
, "returning %s\n", lpResult
);
443 /*************************************************************************
444 * ShellExecute16 [SHELL.20]
446 HINSTANCE16 WINAPI
ShellExecute16( HWND16 hWnd
, LPCSTR lpOperation
,
447 LPCSTR lpFile
, LPCSTR lpParameters
,
448 LPCSTR lpDirectory
, INT16 iShowCmd
)
450 HINSTANCE16 retval
=31;
454 TRACE(exec
, "(%04x,'%s','%s','%s','%s',%x)\n",
455 hWnd
, lpOperation
? lpOperation
:"<null>", lpFile
? lpFile
:"<null>",
456 lpParameters
? lpParameters
: "<null>",
457 lpDirectory
? lpDirectory
: "<null>", iShowCmd
);
459 if (lpFile
==NULL
) return 0; /* should not happen */
460 if (lpOperation
==NULL
) /* default is open */
465 GetCurrentDirectory32A( sizeof(old_dir
), old_dir
);
466 SetCurrentDirectory32A( lpDirectory
);
469 retval
= SHELL_FindExecutable( lpFile
, lpOperation
, cmd
);
471 if (retval
> 32) /* Found */
476 strcat(cmd
,lpParameters
);
479 TRACE(exec
,"starting %s\n",cmd
);
480 retval
= WinExec32( cmd
, iShowCmd
);
482 if (lpDirectory
) SetCurrentDirectory32A( old_dir
);
487 /*************************************************************************
488 * ShellExecute32A (SHELL32.245)
490 HINSTANCE32 WINAPI
ShellExecute32A( HWND32 hWnd
, LPCSTR lpOperation
,
491 LPCSTR lpFile
, LPCSTR lpParameters
,
492 LPCSTR lpDirectory
, INT32 iShowCmd
)
494 return ShellExecute16( hWnd
, lpOperation
, lpFile
, lpParameters
,
495 lpDirectory
, iShowCmd
);
499 /*************************************************************************
500 * FindExecutable16 (SHELL.21)
502 HINSTANCE16 WINAPI
FindExecutable16( LPCSTR lpFile
, LPCSTR lpDirectory
,
505 return (HINSTANCE16
)FindExecutable32A( lpFile
, lpDirectory
, lpResult
);
508 /*************************************************************************
509 * FindExecutable32A (SHELL32.184)
511 HINSTANCE32 WINAPI
FindExecutable32A( LPCSTR lpFile
, LPCSTR lpDirectory
,
514 HINSTANCE32 retval
=31; /* default - 'No association was found' */
517 TRACE(exec
, "File %s, Dir %s\n",
518 (lpFile
!= NULL
?lpFile
:"-"),
519 (lpDirectory
!= NULL
?lpDirectory
:"-"));
521 lpResult
[0]='\0'; /* Start off with an empty return string */
523 /* trap NULL parameters on entry */
524 if (( lpFile
== NULL
) || ( lpResult
== NULL
))
526 /* FIXME - should throw a warning, perhaps! */
527 return 2; /* File not found. Close enough, I guess. */
532 GetCurrentDirectory32A( sizeof(old_dir
), old_dir
);
533 SetCurrentDirectory32A( lpDirectory
);
536 retval
= SHELL_FindExecutable( lpFile
, "open", lpResult
);
538 TRACE(exec
, "returning %s\n", lpResult
);
539 if (lpDirectory
) SetCurrentDirectory32A( old_dir
);
550 #define IDC_STATIC_TEXT 100
551 #define IDC_LISTBOX 99
552 #define IDC_WINE_TEXT 98
554 #define DROP_FIELD_TOP (-15)
555 #define DROP_FIELD_HEIGHT 15
557 extern HICON32 hIconTitleFont
;
559 static BOOL32
__get_dropline( HWND32 hWnd
, LPRECT32 lprect
)
561 HWND32 hWndCtl
= GetDlgItem32(hWnd
, IDC_WINE_TEXT
);
564 GetWindowRect32( hWndCtl
, lprect
);
565 MapWindowPoints32( 0, hWnd
, (LPPOINT32
)lprect
, 2 );
566 lprect
->bottom
= (lprect
->top
+= DROP_FIELD_TOP
);
572 /*************************************************************************
573 * AboutDlgProc32 (not an exported API function)
575 LRESULT WINAPI
AboutDlgProc32( HWND32 hWnd
, UINT32 msg
, WPARAM32 wParam
,
579 char Template
[512], AppTitle
[512];
585 ABOUT_INFO
*info
= (ABOUT_INFO
*)lParam
;
588 const char* const *pstr
= SHELL_People
;
589 SendDlgItemMessage32A(hWnd
, stc1
, STM_SETICON32
,info
->hIcon
, 0);
590 GetWindowText32A( hWnd
, Template
, sizeof(Template
) );
591 sprintf( AppTitle
, Template
, info
->szApp
);
592 SetWindowText32A( hWnd
, AppTitle
);
593 SetWindowText32A( GetDlgItem32(hWnd
, IDC_STATIC_TEXT
),
594 info
->szOtherStuff
);
595 hWndCtl
= GetDlgItem32(hWnd
, IDC_LISTBOX
);
596 SendMessage32A( hWndCtl
, WM_SETREDRAW
, 0, 0 );
597 SendMessage32A( hWndCtl
, WM_SETFONT
, hIconTitleFont
, 0 );
600 SendMessage32A( hWndCtl
, LB_ADDSTRING32
,
601 (WPARAM32
)-1, (LPARAM
)*pstr
);
604 SendMessage32A( hWndCtl
, WM_SETREDRAW
, 1, 0 );
613 HDC32 hDC
= BeginPaint32( hWnd
, &ps
);
615 if( __get_dropline( hWnd
, &rect
) )
616 GRAPH_DrawLines( hDC
, (LPPOINT32
)&rect
, 1, GetStockObject32( BLACK_PEN
) );
617 EndPaint32( hWnd
, &ps
);
621 case WM_LBTRACKPOINT
:
623 hWndCtl
= GetDlgItem32(hWnd
, IDC_LISTBOX
);
624 if( (INT16
)GetKeyState16( VK_CONTROL
) < 0 )
626 if( DragDetect32( hWndCtl
, *((LPPOINT32
)&lParam
) ) )
628 INT32 idx
= SendMessage32A( hWndCtl
, LB_GETCURSEL32
, 0, 0 );
631 INT32 length
= SendMessage32A( hWndCtl
, LB_GETTEXTLEN32
, (WPARAM32
)idx
, 0 );
632 HGLOBAL16 hMemObj
= GlobalAlloc16( GMEM_MOVEABLE
, length
+ 1 );
633 char* pstr
= (char*)GlobalLock16( hMemObj
);
637 HCURSOR16 hCursor
= LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT
) );
638 SendMessage32A( hWndCtl
, LB_GETTEXT32
, (WPARAM32
)idx
, (LPARAM
)pstr
);
639 SendMessage32A( hWndCtl
, LB_DELETESTRING32
, (WPARAM32
)idx
, 0 );
640 UpdateWindow32( hWndCtl
);
641 if( !DragObject16((HWND16
)hWnd
, (HWND16
)hWnd
, DRAGOBJ_DATA
, 0, (WORD
)hMemObj
, hCursor
) )
642 SendMessage32A( hWndCtl
, LB_ADDSTRING32
, (WPARAM32
)-1, (LPARAM
)pstr
);
644 if( hMemObj
) GlobalFree16( hMemObj
);
650 case WM_QUERYDROPOBJECT
:
653 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
654 if( lpDragInfo
&& lpDragInfo
->wFlags
== DRAGOBJ_DATA
)
657 if( __get_dropline( hWnd
, &rect
) )
659 POINT32 pt
= { lpDragInfo
->pt
.x
, lpDragInfo
->pt
.y
};
660 rect
.bottom
+= DROP_FIELD_HEIGHT
;
661 if( PtInRect32( &rect
, pt
) )
663 SetWindowLong32A( hWnd
, DWL_MSGRESULT
, 1 );
674 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
675 if( lpDragInfo
&& lpDragInfo
->wFlags
== DRAGOBJ_DATA
&& lpDragInfo
->hList
)
677 char* pstr
= (char*)GlobalLock16( (HGLOBAL16
)(lpDragInfo
->hList
) );
680 static char __appendix_str
[] = " with";
682 hWndCtl
= GetDlgItem32( hWnd
, IDC_WINE_TEXT
);
683 SendMessage32A( hWndCtl
, WM_GETTEXT
, 512, (LPARAM
)Template
);
684 if( !lstrncmp32A( Template
, "WINE", 4 ) )
685 SetWindowText32A( GetDlgItem32(hWnd
, IDC_STATIC_TEXT
), Template
);
688 char* pch
= Template
+ strlen(Template
) - strlen(__appendix_str
);
690 SendMessage32A( GetDlgItem32(hWnd
, IDC_LISTBOX
), LB_ADDSTRING32
,
691 (WPARAM32
)-1, (LPARAM
)Template
);
694 lstrcpy32A( Template
, pstr
);
695 lstrcat32A( Template
, __appendix_str
);
696 SetWindowText32A( hWndCtl
, Template
);
698 SetWindowLong32A( hWnd
, DWL_MSGRESULT
, 1 );
708 EndDialog32(hWnd
, TRUE
);
717 /*************************************************************************
718 * AboutDlgProc16 (SHELL.33)
720 LRESULT WINAPI
AboutDlgProc16( HWND16 hWnd
, UINT16 msg
, WPARAM16 wParam
,
723 return AboutDlgProc32( hWnd
, msg
, wParam
, lParam
);
727 /*************************************************************************
728 * ShellAbout16 (SHELL.22)
730 BOOL16 WINAPI
ShellAbout16( HWND16 hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
,
733 return ShellAbout32A( hWnd
, szApp
, szOtherStuff
, hIcon
);
736 /*************************************************************************
737 * ShellAbout32A (SHELL32.243)
739 BOOL32 WINAPI
ShellAbout32A( HWND32 hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
,
744 info
.szOtherStuff
= szOtherStuff
;
746 if (!hIcon
) info
.hIcon
= LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON
) );
747 return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd
),
748 SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX
),
749 hWnd
, AboutDlgProc32
, (LPARAM
)&info
);
753 /*************************************************************************
754 * ShellAbout32W (SHELL32.244)
756 BOOL32 WINAPI
ShellAbout32W( HWND32 hWnd
, LPCWSTR szApp
, LPCWSTR szOtherStuff
,
762 info
.szApp
= HEAP_strdupWtoA( GetProcessHeap(), 0, szApp
);
763 info
.szOtherStuff
= HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff
);
765 if (!hIcon
) info
.hIcon
= LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON
) );
766 ret
= DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd
),
767 SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX
),
768 hWnd
, AboutDlgProc32
, (LPARAM
)&info
);
769 HeapFree( GetProcessHeap(), 0, (LPSTR
)info
.szApp
);
770 HeapFree( GetProcessHeap(), 0, (LPSTR
)info
.szOtherStuff
);
774 /*************************************************************************
775 * Shell_NotifyIcon [SHELL32.249]
777 * This function is supposed to deal with the systray.
778 * Any ideas on how this is to be implimented?
780 BOOL32 WINAPI
Shell_NotifyIcon( DWORD dwMessage
,
781 PNOTIFYICONDATA pnid
)
786 /*************************************************************************
787 * Shell_NotifyIcon [SHELL32.240]
789 * This function is supposed to deal with the systray.
790 * Any ideas on how this is to be implimented?
792 BOOL32 WINAPI
Shell_NotifyIconA(DWORD dwMessage
,
793 PNOTIFYICONDATA pnid
)
798 /*************************************************************************
799 * SHELL_GetResourceTable
801 static DWORD
SHELL_GetResourceTable(HFILE32 hFile
,LPBYTE
*retptr
)
803 IMAGE_DOS_HEADER mz_header
;
808 _llseek32( hFile
, 0, SEEK_SET
);
809 if ( (_lread32(hFile
,&mz_header
,sizeof(mz_header
)) != sizeof(mz_header
)) ||
810 (mz_header
.e_magic
!= IMAGE_DOS_SIGNATURE
)
811 ) { /* .ICO file ? */
812 if (mz_header
.e_cblp
== 1) { /* ICONHEADER.idType, must be 1 */
813 *retptr
= (LPBYTE
)-1;
817 return 0; /* failed */
819 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
820 if (_lread32( hFile
, magic
, sizeof(magic
) ) != sizeof(magic
))
822 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
824 if (*(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
825 return IMAGE_NT_SIGNATURE
;
826 if (*(WORD
*)magic
== IMAGE_OS2_SIGNATURE
) {
827 IMAGE_OS2_HEADER ne_header
;
828 LPBYTE pTypeInfo
= (LPBYTE
)-1;
830 if (_lread32(hFile
,&ne_header
,sizeof(ne_header
))!=sizeof(ne_header
))
833 if (ne_header
.ne_magic
!= IMAGE_OS2_SIGNATURE
) return 0;
834 size
= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
835 if( size
> sizeof(NE_TYPEINFO
) )
837 pTypeInfo
= (BYTE
*)HeapAlloc( GetProcessHeap(), 0, size
);
839 _llseek32(hFile
, mz_header
.e_lfanew
+ne_header
.resource_tab_offset
, SEEK_SET
);
840 if( _lread32( hFile
, (char*)pTypeInfo
, size
) != size
) {
841 HeapFree( GetProcessHeap(), 0, pTypeInfo
);
847 return IMAGE_OS2_SIGNATURE
;
849 return 0; /* failed */
852 /*************************************************************************
855 static HGLOBAL16
SHELL_LoadResource(HINSTANCE16 hInst
, HFILE32 hFile
, NE_NAMEINFO
* pNInfo
, WORD sizeShift
)
858 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, (DWORD
)pNInfo
->length
<< sizeShift
);
860 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
862 _llseek32( hFile
, (DWORD
)pNInfo
->offset
<< sizeShift
, SEEK_SET
);
863 _lread32( hFile
, (char*)ptr
, pNInfo
->length
<< sizeShift
);
869 /*************************************************************************
872 static HGLOBAL16
ICO_LoadIcon(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIRENTRY lpiIDE
)
875 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, lpiIDE
->dwBytesInRes
);
877 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
879 _llseek32( hFile
, lpiIDE
->dwImageOffset
, SEEK_SET
);
880 _lread32( hFile
, (char*)ptr
, lpiIDE
->dwBytesInRes
);
886 /*************************************************************************
887 * ICO_GetIconDirectory
889 * Read .ico file and build phony ICONDIR struct for GetIconID
891 static HGLOBAL16
ICO_GetIconDirectory(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIR
* lplpiID
)
893 WORD id
[3]; /* idReserved, idType, idCount */
897 _llseek32( hFile
, 0, SEEK_SET
);
898 if( _lread32(hFile
,(char*)id
,sizeof(id
)) != sizeof(id
) ) return 0;
902 * - see http://www.microsoft.com/win32dev/ui/icons.htm
905 if( id
[0] || id
[1] != 1 || !id
[2] ) return 0;
907 i
= id
[2]*sizeof(icoICONDIRENTRY
) + sizeof(id
);
909 lpiID
= (LPicoICONDIR
)HeapAlloc( GetProcessHeap(), 0, i
);
911 if( _lread32(hFile
,(char*)lpiID
->idEntries
,i
) == i
)
913 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10,
914 id
[2]*sizeof(ICONDIRENTRY
) + sizeof(id
) );
917 CURSORICONDIR
* lpID
= (CURSORICONDIR
*)GlobalLock16( handle
);
918 lpID
->idReserved
= lpiID
->idReserved
= id
[0];
919 lpID
->idType
= lpiID
->idType
= id
[1];
920 lpID
->idCount
= lpiID
->idCount
= id
[2];
921 for( i
=0; i
< lpiID
->idCount
; i
++ )
923 memcpy((void*)(lpID
->idEntries
+ i
),
924 (void*)(lpiID
->idEntries
+ i
), sizeof(ICONDIRENTRY
) - 2);
925 lpID
->idEntries
[i
].icon
.wResId
= i
;
933 HeapFree( GetProcessHeap(), 0, lpiID
);
937 /*************************************************************************
938 * InternalExtractIcon [SHELL.39]
940 * This abortion is called directly by Progman
942 HGLOBAL16 WINAPI
InternalExtractIcon(HINSTANCE16 hInstance
,
943 LPCSTR lpszExeFileName
, UINT16 nIconIndex
,
947 HGLOBAL16
* RetPtr
= NULL
;
951 HFILE32 hFile
= OpenFile32( lpszExeFileName
, &ofs
, OF_READ
);
952 UINT16 iconDirCount
= 0,iconCount
= 0;
954 TRACE(reg
,"(%04x,file %s,start %d,extract %d\n",
955 hInstance
, lpszExeFileName
, nIconIndex
, n
);
957 if( hFile
== HFILE_ERROR32
|| !n
) return 0;
959 hRet
= GlobalAlloc16( GMEM_FIXED
| GMEM_ZEROINIT
, sizeof(HICON16
)*n
);
960 RetPtr
= (HICON16
*)GlobalLock16(hRet
);
962 *RetPtr
= (n
== 0xFFFF)? 0: 1; /* error return values */
964 sig
= SHELL_GetResourceTable(hFile
,&pData
);
966 if((sig
== IMAGE_OS2_SIGNATURE
)
967 || (sig
== 1)) /* .ICO file */
970 NE_TYPEINFO
* pTInfo
= (NE_TYPEINFO
*)(pData
+ 2);
971 NE_NAMEINFO
* pIconStorage
= NULL
;
972 NE_NAMEINFO
* pIconDir
= NULL
;
973 LPicoICONDIR lpiID
= NULL
;
975 if( pData
== (BYTE
*)-1 )
977 /* check for .ICO file */
979 hIcon
= ICO_GetIconDirectory(hInstance
, hFile
, &lpiID
);
980 if( hIcon
) { iconDirCount
= 1; iconCount
= lpiID
->idCount
; }
982 else while( pTInfo
->type_id
&& !(pIconStorage
&& pIconDir
) )
984 /* find icon directory and icon repository */
986 if( pTInfo
->type_id
== NE_RSCTYPE_GROUP_ICON
)
988 iconDirCount
= pTInfo
->count
;
989 pIconDir
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
990 TRACE(reg
,"\tfound directory - %i icon families\n", iconDirCount
);
992 if( pTInfo
->type_id
== NE_RSCTYPE_ICON
)
994 iconCount
= pTInfo
->count
;
995 pIconStorage
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
996 TRACE(reg
,"\ttotal icons - %i\n", iconCount
);
998 pTInfo
= (NE_TYPEINFO
*)((char*)(pTInfo
+1)+pTInfo
->count
*sizeof(NE_NAMEINFO
));
1001 /* load resources and create icons */
1003 if( (pIconStorage
&& pIconDir
) || lpiID
)
1004 if( nIconIndex
== (UINT16
)-1 ) RetPtr
[0] = iconDirCount
;
1005 else if( nIconIndex
< iconDirCount
)
1009 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
1011 for( i
= nIconIndex
; i
< nIconIndex
+ n
; i
++ )
1013 /* .ICO files have only one icon directory */
1016 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconDir
+ i
,
1018 RetPtr
[i
-nIconIndex
] = GetIconID( hIcon
, 3 );
1019 GlobalFree16(hIcon
);
1022 for( icon
= nIconIndex
; icon
< nIconIndex
+ n
; icon
++ )
1026 hIcon
= ICO_LoadIcon( hInstance
, hFile
,
1027 lpiID
->idEntries
+ RetPtr
[icon
-nIconIndex
]);
1029 for( i
= 0; i
< iconCount
; i
++ )
1030 if( pIconStorage
[i
].id
== (RetPtr
[icon
-nIconIndex
] | 0x8000) )
1031 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconStorage
+ i
,
1035 RetPtr
[icon
-nIconIndex
] = LoadIconHandler( hIcon
, TRUE
);
1036 FarSetOwner( RetPtr
[icon
-nIconIndex
], GetExePtr(hInstance
) );
1039 RetPtr
[icon
-nIconIndex
] = 0;
1042 if( lpiID
) HeapFree( GetProcessHeap(), 0, lpiID
);
1043 else HeapFree( GetProcessHeap(), 0, pData
);
1045 if( sig
== IMAGE_NT_SIGNATURE
)
1047 LPBYTE peimage
,idata
,igdata
;
1048 LPIMAGE_DOS_HEADER dheader
;
1049 LPIMAGE_NT_HEADERS pe_header
;
1050 LPIMAGE_SECTION_HEADER pe_sections
;
1051 LPIMAGE_RESOURCE_DIRECTORY rootresdir
,iconresdir
,icongroupresdir
;
1052 LPIMAGE_RESOURCE_DATA_ENTRY idataent
,igdataent
;
1055 LPIMAGE_RESOURCE_DIRECTORY_ENTRY xresent
;
1056 CURSORICONDIR
**cids
;
1058 fmapping
= CreateFileMapping32A(hFile
,NULL
,PAGE_READONLY
|SEC_COMMIT
,0,0,NULL
);
1059 if (fmapping
== 0) { /* FIXME, INVALID_HANDLE_VALUE? */
1060 WARN(reg
,"failed to create filemap.\n");
1064 peimage
= MapViewOfFile(fmapping
,FILE_MAP_READ
,0,0,0);
1066 WARN(reg
,"failed to mmap filemap.\n");
1067 CloseHandle(fmapping
);
1071 dheader
= (LPIMAGE_DOS_HEADER
)peimage
;
1072 /* it is a pe header, SHELL_GetResourceTable checked that */
1073 pe_header
= (LPIMAGE_NT_HEADERS
)(peimage
+dheader
->e_lfanew
);
1074 /* probably makes problems with short PE headers... but I haven't seen
1077 pe_sections
= (LPIMAGE_SECTION_HEADER
)(((char*)pe_header
)+sizeof(*pe_header
));
1079 for (i
=0;i
<pe_header
->FileHeader
.NumberOfSections
;i
++) {
1080 if (pe_sections
[i
].Characteristics
& IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
1082 /* FIXME: doesn't work when the resources are not in a seperate section */
1083 if (pe_sections
[i
].VirtualAddress
== pe_header
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
].VirtualAddress
) {
1084 rootresdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((char*)peimage
+pe_sections
[i
].PointerToRawData
);
1090 WARN(reg
,"haven't found section for resource directory.\n");
1091 UnmapViewOfFile(peimage
);
1092 CloseHandle(fmapping
);
1096 icongroupresdir
= GetResDirEntryW(rootresdir
,RT_GROUP_ICON32W
,
1097 (DWORD
)rootresdir
,FALSE
);
1098 if (!icongroupresdir
) {
1099 WARN(reg
,"No Icongroupresourcedirectory!\n");
1100 UnmapViewOfFile(peimage
);
1101 CloseHandle(fmapping
);
1106 iconDirCount
= icongroupresdir
->NumberOfNamedEntries
+icongroupresdir
->NumberOfIdEntries
;
1107 if( nIconIndex
== (UINT16
)-1 ) {
1108 RetPtr
[0] = iconDirCount
;
1109 UnmapViewOfFile(peimage
);
1110 CloseHandle(fmapping
);
1115 if (nIconIndex
>= iconDirCount
) {
1116 WARN(reg
,"nIconIndex %d is larger than iconDirCount %d\n",
1117 nIconIndex
,iconDirCount
);
1118 UnmapViewOfFile(peimage
);
1119 CloseHandle(fmapping
);
1124 cids
= (CURSORICONDIR
**)HeapAlloc(GetProcessHeap(),0,n
*sizeof(CURSORICONDIR
*));
1126 /* caller just wanted the number of entries */
1128 xresent
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)(icongroupresdir
+1);
1129 /* assure we don't get too much ... */
1130 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
1132 /* starting from specified index ... */
1133 xresent
= xresent
+nIconIndex
;
1135 for (i
=0;i
<n
;i
++,xresent
++) {
1137 LPIMAGE_RESOURCE_DIRECTORY resdir
;
1139 /* go down this resource entry, name */
1140 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((DWORD
)rootresdir
+(xresent
->u2
.s
.OffsetToDirectory
));
1141 /* default language (0) */
1142 resdir
= GetResDirEntryW(resdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1143 igdataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)resdir
;
1145 /* lookup address in mapped image for virtual address */
1147 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1148 if (igdataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1150 if (igdataent
->OffsetToData
+igdataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1152 igdata
= peimage
+(igdataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1155 WARN(reg
,"no matching real address for icongroup!\n");
1156 UnmapViewOfFile(peimage
);
1157 CloseHandle(fmapping
);
1162 cid
= (CURSORICONDIR
*)igdata
;
1164 RetPtr
[i
] = LookupIconIdFromDirectoryEx32(igdata
,TRUE
,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1166 iconresdir
=GetResDirEntryW(rootresdir
,RT_ICON32W
,
1167 (DWORD
)rootresdir
,FALSE
);
1169 WARN(reg
,"No Iconresourcedirectory!\n");
1170 UnmapViewOfFile(peimage
);
1171 CloseHandle(fmapping
);
1176 LPIMAGE_RESOURCE_DIRECTORY xresdir
;
1178 xresdir
= GetResDirEntryW(iconresdir
,(LPWSTR
)RetPtr
[i
],(DWORD
)rootresdir
,FALSE
);
1179 xresdir
= GetResDirEntryW(xresdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1181 idataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)xresdir
;
1184 /* map virtual to address in image */
1185 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1186 if (idataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1188 if (idataent
->OffsetToData
+idataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1190 idata
= peimage
+(idataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1193 WARN(reg
,"no matching real address found for icondata!\n");
1197 RetPtr
[i
] = CreateIconFromResourceEx32(idata
,idataent
->Size
,TRUE
,0x00030000,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1199 UnmapViewOfFile(peimage
);
1200 CloseHandle(fmapping
);
1205 /* return array with icon handles */
1210 /*************************************************************************
1211 * ExtractIcon16 (SHELL.34)
1213 HICON16 WINAPI
ExtractIcon16( HINSTANCE16 hInstance
, LPCSTR lpszExeFileName
,
1216 return ExtractIcon32A( hInstance
, lpszExeFileName
, nIconIndex
);
1220 /*************************************************************************
1221 * ExtractIcon32A (SHELL32.133)
1223 HICON32 WINAPI
ExtractIcon32A( HINSTANCE32 hInstance
, LPCSTR lpszExeFileName
,
1226 HGLOBAL16 handle
= InternalExtractIcon(hInstance
,lpszExeFileName
,nIconIndex
, 1);
1230 HICON16
* ptr
= (HICON16
*)GlobalLock16(handle
);
1231 HICON16 hIcon
= *ptr
;
1233 GlobalFree16(handle
);
1239 /*************************************************************************
1240 * ExtractIcon32W (SHELL32.180)
1242 HICON32 WINAPI
ExtractIcon32W( HINSTANCE32 hInstance
, LPCWSTR lpszExeFileName
,
1245 LPSTR exefn
= HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName
);
1246 HICON32 ret
= ExtractIcon32A(hInstance
,exefn
,nIconIndex
);
1248 HeapFree(GetProcessHeap(),0,exefn
);
1253 /*************************************************************************
1254 * ExtractAssociatedIcon [SHELL.36]
1256 * Return icon for given file (either from file itself or from associated
1257 * executable) and patch parameters if needed.
1259 HICON32 WINAPI
ExtractAssociatedIcon32A(HINSTANCE32 hInst
,LPSTR lpIconPath
,
1262 return ExtractAssociatedIcon16(hInst
,lpIconPath
,lpiIcon
);
1265 HICON16 WINAPI
ExtractAssociatedIcon16(HINSTANCE16 hInst
,LPSTR lpIconPath
,
1268 HICON16 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1273 if( hIcon
== 1 ) /* no icons found in given file */
1275 char tempPath
[0x80];
1276 UINT16 uRet
= FindExecutable16(lpIconPath
,NULL
,tempPath
);
1278 if( uRet
> 32 && tempPath
[0] )
1280 strcpy(lpIconPath
,tempPath
);
1281 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1283 if( hIcon
> 2 ) return hIcon
;
1289 *lpiIcon
= 2; /* MSDOS icon - we found .exe but no icons in it */
1291 *lpiIcon
= 6; /* generic icon - found nothing */
1293 GetModuleFileName16(hInst
, lpIconPath
, 0x80);
1294 hIcon
= LoadIcon16( hInst
, MAKEINTRESOURCE16(*lpiIcon
));
1300 /*************************************************************************
1301 * FindEnvironmentString [SHELL.38]
1303 * Returns a pointer into the DOS environment... Ugh.
1305 LPSTR
SHELL_FindString(LPSTR lpEnv
, LPCSTR entry
)
1307 UINT16 l
= strlen(entry
);
1308 for( ; *lpEnv
; lpEnv
+=strlen(lpEnv
)+1 )
1310 if( lstrncmpi32A(lpEnv
, entry
, l
) ) continue;
1313 return (lpEnv
+ l
); /* empty entry */
1314 else if ( *(lpEnv
+l
)== '=' )
1315 return (lpEnv
+ l
+ 1);
1320 SEGPTR WINAPI
FindEnvironmentString(LPSTR str
)
1322 SEGPTR spEnv
= GetDOSEnvironment();
1323 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(spEnv
);
1325 LPSTR lpString
= (spEnv
)?SHELL_FindString(lpEnv
, str
):NULL
;
1327 if( lpString
) /* offset should be small enough */
1328 return spEnv
+ (lpString
- lpEnv
);
1330 return (SEGPTR
)NULL
;
1333 /*************************************************************************
1334 * DoEnvironmentSubst [SHELL.37]
1336 * Replace %KEYWORD% in the str with the value of variable KEYWORD
1337 * from "DOS" environment.
1339 DWORD WINAPI
DoEnvironmentSubst(LPSTR str
,WORD length
)
1341 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(GetDOSEnvironment());
1342 LPSTR lpBuffer
= (LPSTR
)HeapAlloc( GetProcessHeap(), 0, length
);
1344 LPSTR lpbstr
= lpBuffer
;
1346 CharToOem32A(str
,str
);
1348 TRACE(reg
,"accept %s\n", str
);
1350 while( *lpstr
&& lpbstr
- lpBuffer
< length
)
1352 LPSTR lpend
= lpstr
;
1356 do { lpend
++; } while( *lpend
&& *lpend
!= '%' );
1357 if( *lpend
== '%' && lpend
- lpstr
> 1 ) /* found key */
1361 lpKey
= SHELL_FindString(lpEnv
, lpstr
+1);
1362 if( lpKey
) /* found key value */
1364 int l
= strlen(lpKey
);
1366 if( l
> length
- (lpbstr
- lpBuffer
) - 1 )
1368 WARN(reg
,"Env subst aborted - string too short\n");
1372 strcpy(lpbstr
, lpKey
);
1379 else break; /* back off and whine */
1384 *lpbstr
++ = *lpstr
++;
1388 if( lpstr
- str
== strlen(str
) )
1390 strncpy(str
, lpBuffer
, length
);
1396 TRACE(reg
," return %s\n", str
);
1398 OemToChar32A(str
,str
);
1399 HeapFree( GetProcessHeap(), 0, lpBuffer
);
1401 /* Return str length in the LOWORD
1402 * and 1 in HIWORD if subst was successful.
1404 return (DWORD
)MAKELONG(strlen(str
), length
);
1407 /*************************************************************************
1408 * ShellHookProc [SHELL.103]
1409 * System-wide WH_SHELL hook.
1411 LRESULT WINAPI
ShellHookProc(INT16 code
, WPARAM16 wParam
, LPARAM lParam
)
1413 TRACE(reg
,"%i, %04x, %08x\n", code
, wParam
,
1415 if( SHELL_hHook
&& SHELL_hWnd
)
1420 case HSHELL_WINDOWCREATED
: uMsg
= uMsgWndCreated
; break;
1421 case HSHELL_WINDOWDESTROYED
: uMsg
= uMsgWndDestroyed
; break;
1422 case HSHELL_ACTIVATESHELLWINDOW
: uMsg
= uMsgShellActivate
;
1424 PostMessage16( SHELL_hWnd
, uMsg
, wParam
, 0 );
1426 return CallNextHookEx16( WH_SHELL
, code
, wParam
, lParam
);
1429 /*************************************************************************
1430 * RegisterShellHook [SHELL.102]
1432 BOOL32 WINAPI
RegisterShellHook(HWND16 hWnd
, UINT16 uAction
)
1434 TRACE(reg
,"%04x [%u]\n", hWnd
, uAction
);
1438 case 2: /* register hWnd as a shell window */
1442 HMODULE16 hShell
= GetModuleHandle16( "SHELL" );
1444 SHELL_hHook
= SetWindowsHookEx16( WH_SHELL
, ShellHookProc
,
1448 uMsgWndCreated
= RegisterWindowMessage32A( lpstrMsgWndCreated
);
1449 uMsgWndDestroyed
= RegisterWindowMessage32A( lpstrMsgWndDestroyed
);
1450 uMsgShellActivate
= RegisterWindowMessage32A( lpstrMsgShellActivate
);
1452 else WARN(reg
, "unable to install ShellHookProc()!\n");
1455 if( SHELL_hHook
) return ((SHELL_hWnd
= hWnd
) != 0);
1460 WARN(reg
, "unknown code %i\n", uAction
);
1470 /*************************************************************************
1471 * SHGetFileInfoA [SHELL32.218]
1473 DWORD WINAPI
SHGetFileInfo32A(LPCSTR path
,DWORD dwFileAttributes
,
1474 SHFILEINFO32A
*psfi
, UINT32 sizeofpsfi
,
1477 FIXME(shell
,"(%s,0x%08lx,%p,%d,0x%08x): stub\n",
1478 path
,dwFileAttributes
,psfi
,sizeofpsfi
,flags
);
1482 /*************************************************************************
1483 * SHAppBarMessage32 [SHELL32.207]
1485 UINT32 WINAPI
SHAppBarMessage32(DWORD msg
, PAPPBARDATA data
)
1487 FIXME(shell
,"(0x%08lx,%p): stub\n", msg
, data
);
1491 case ABM_GETAUTOHIDEBAR
:
1493 case ABM_GETTASKBARPOS
:
1497 case ABM_SETAUTOHIDEBAR
:
1499 case ABM_WINDOWPOSCHANGED
:
1506 /*************************************************************************
1507 * CommandLineToArgvW [SHELL32.7]
1509 LPWSTR
* WINAPI
CommandLineToArgvW(LPWSTR cmdline
,LPDWORD numargs
)
1514 /* to get writeable copy */
1515 cmdline
= HEAP_strdupW( GetProcessHeap(), 0, cmdline
);
1522 while (*s
&& *s
==0x0020)
1528 argv
=(LPWSTR
*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR
)*(i
+1) );
1534 argv
[i
++]=HEAP_strdupW( GetProcessHeap(), 0, t
);
1536 while (*s
&& *s
==0x0020)
1547 argv
[i
++]=(LPWSTR
)HEAP_strdupW( GetProcessHeap(), 0, t
);
1548 HeapFree( GetProcessHeap(), 0, cmdline
);
1554 /*************************************************************************
1555 * Control_RunDLL [SHELL32.12]
1557 * Wild speculation in the following!
1559 * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
1562 void WINAPI
Control_RunDLL (HWND32 hwnd
, LPCVOID code
, LPCSTR cmd
, DWORD arg4
)
1564 TRACE(exec
, "(%08x, %p, \"%s\", %08lx)\n",
1565 hwnd
, code
? code
: "(null)", cmd
? cmd
: "(null)", arg4
);
1568 /*************************************************************************
1571 void WINAPI
FreeIconList( DWORD dw
)
1573 FIXME(reg
, "(%lx): stub\n",dw
);
1576 /*************************************************************************
1577 * SHELL32_DllGetClassObject [SHELL32.14]
1579 * http://premium.microsoft.com/msdn/library/sdkdoc/api2_48fo.htm
1581 DWORD WINAPI
SHELL32_DllGetClassObject(REFCLSID rclsid
,REFIID iid
,LPVOID
*ppv
)
1583 char xclsid
[50],xiid
[50];
1584 HRESULT hres
= E_OUTOFMEMORY
;
1587 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
1588 WINE_StringFromCLSID((LPCLSID
)iid
,xiid
);
1589 TRACE(shell
,"(%s,%s,%p)\n",xclsid
,xiid
,ppv
);
1592 /* SDK example code looks like this:
1594 HRESULT hres = E_OUTOFMEMORY;
1597 CClassFactory *pClassFactory = new CClassFactory(rclsid);
1599 if (pClassFactory) {
1600 hRes = pClassFactory->QueryInterface(riid,ppv);
1601 pClassFactory->Release();
1605 * The magic of the whole stuff is still unclear to me, so just hack together
1609 if (!memcmp(rclsid
,&CLSID_ShellDesktop
,sizeof(CLSID_ShellDesktop
)))
1610 { TRACE(shell
," requested CLSID_ShellDesktop, creating it.\n");
1611 *ppv
= IShellFolder_Constructor();
1612 /* FIXME(shell,"Initialize this folder to be the shell desktop folder\n")*/
1616 FIXME(shell
, "clsid(%s) not found, return CLASS_E_CLASSNOTAVAILABLE.\n",xclsid
);
1618 return CLASS_E_CLASSNOTAVAILABLE
;
1621 /*************************************************************************
1622 * SHGetDesktopFolder [SHELL32.216]
1623 * returns the interface to the shell desktop folder.
1625 * [SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
1626 * CLSID_ShellDesktop.
1628 * CoCreateInstance(CLSID_Desktop, NULL,
1629 * CLSCTX_INPROC, IID_IShellFolder, &pshf);
1631 * So what we are doing is currently wrong....
1633 DWORD WINAPI
SHGetDesktopFolder(LPSHELLFOLDER
*shellfolder
) {
1634 *shellfolder
= IShellFolder_Constructor();
1638 /*************************************************************************
1639 * SHGetMalloc [SHELL32.220]
1640 * returns the interface to shell malloc.
1642 * [SDK header win95/shlobj.h:
1643 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
1645 * What we are currently doing is not very wrong, since we always use the same
1646 * heap (ProcessHeap).
1648 DWORD WINAPI
SHGetMalloc(LPMALLOC32
*lpmal
) {
1649 TRACE(shell
,"(%p)\n", lpmal
);
1650 return CoGetMalloc32(0,lpmal
);
1653 /*************************************************************************
1654 * SHGetSpecialFolderLocation [SHELL32.223]
1655 * returns the PIDL of a special folder
1657 * nFolder is a CSIDL_xxxxx.
1659 HRESULT WINAPI
SHGetSpecialFolderLocation(HWND32 hwndOwner
, INT32 nFolder
, LPITEMIDLIST
* ppidl
)
1660 { FIXME(shell
,"(%04x,%d,%p),stub!\n", hwndOwner
,nFolder
,ppidl
);
1663 { case CSIDL_BITBUCKET
: TRACE (shell
,"looking for Recyceler\n");
1665 case CSIDL_CONTROLS
: TRACE (shell
,"looking for Control\n");
1667 case CSIDL_DESKTOP
: TRACE (shell
,"looking for Desktop\n");
1669 case CSIDL_DESKTOPDIRECTORY
: TRACE (shell
,"looking for DeskDir\n");
1671 case CSIDL_DRIVES
: TRACE (shell
,"looking for Drives\n");
1673 case CSIDL_FONTS
: TRACE (shell
,"looking for Fonts\n");
1675 case CSIDL_NETHOOD
: TRACE (shell
,"looking for Nethood\n");
1677 case CSIDL_NETWORK
: TRACE (shell
,"looking for Network\n");
1679 case CSIDL_PERSONAL
: TRACE (shell
,"looking for Personal\n");
1681 case CSIDL_PRINTERS
: TRACE (shell
,"looking for Printers\n");
1683 case CSIDL_PROGRAMS
: TRACE (shell
,"looking for Programms\n");
1685 case CSIDL_RECENT
: TRACE (shell
,"looking for Recent\n");
1687 case CSIDL_SENDTO
: TRACE (shell
,"looking for Sendto\n");
1689 case CSIDL_STARTMENU
: TRACE (shell
,"looking for Startmenu\n");
1691 case CSIDL_STARTUP
: TRACE (shell
,"looking for Startup\n");
1693 case CSIDL_TEMPLATES
: TRACE (shell
,"looking for Templates\n");
1695 default: ERR (shell
,"unknown CSIDL\n");
1699 *ppidl
= (LPITEMIDLIST
)HeapAlloc(GetProcessHeap(),0,sizeof(ITEMIDLIST
));
1700 (*ppidl
)->mkid
.cb
= 0; /*the first ITEMIDLIST*/
1702 FIXME(shell
, "return empty ITEMIDLIST only (pidl %p)\n",*ppidl
);
1707 /*************************************************************************
1708 * SHGetPathFromIDList [SHELL32.221]
1709 * returns the path from a passed PIDL.
1711 BOOL32 WINAPI
SHGetPathFromIDList(LPCITEMIDLIST pidl
,LPSTR pszPath
)
1712 { FIXME(shell
,"(pidl %p,%p),stub, returning E:\\\\ \n",pidl
,pszPath
);
1713 strcpy(pszPath
,"E:\\"); /* FIXME */
1717 /*************************************************************************
1718 * SHHelpShortcuts_RunDLL [SHELL32.224]
1723 SHHelpShortcuts_RunDLL (DWORD dwArg1
, DWORD dwArg2
, DWORD dwArg3
, DWORD dwArg4
)
1725 FIXME (exec
, "(%lx, %lx, %lx, %lx) empty stub!\n",
1726 dwArg1
, dwArg2
, dwArg3
, dwArg4
);
1732 /*************************************************************************
1733 * SHBrowseForFolderA [SHELL32.209]
1738 SHBrowseForFolder32A (LPBROWSEINFO32A lpbi
)
1740 FIXME (exec
, "(%lx) empty stub!\n", (DWORD
)lpbi
);
1741 FIXME (exec
, "(%s) empty stub!\n", lpbi
->lpszTitle
);