2 * Shell Library Functions
21 #include "cursoricon.h"
22 #include "interfaces.h"
23 #include "sysmetrics.h"
29 static const char * const SHELL_People
[] =
46 "Niels de Carpentier",
52 "Frans van Dorsselaer",
103 "Philippe De Muyter",
116 "Bernhard Rosenkraenzer",
117 "Johannes Ruscheinski",
119 "Constantine Sapuntzakis",
127 "Yngvi Sigurjonsson",
142 "Gregory Trubetskoy",
154 "Karl Guenter Wuensch",
157 "Nikita V. Youshchenko",
160 "Luiz Otavio L. Zorzella",
165 /* .ICO file ICONDIR definitions */
171 BYTE bWidth
; /* Width, in pixels, of the image */
172 BYTE bHeight
; /* Height, in pixels, of the image */
173 BYTE bColorCount
; /* Number of colors in image (0 if >=8bpp) */
174 BYTE bReserved
; /* Reserved ( must be 0) */
175 WORD wPlanes
; /* Color Planes */
176 WORD wBitCount
; /* Bits per pixel */
177 DWORD dwBytesInRes
; /* How many bytes in this resource? */
178 DWORD dwImageOffset
; /* Where in the file is this image? */
179 } icoICONDIRENTRY
, *LPicoICONDIRENTRY
;
183 WORD idReserved
; /* Reserved (must be 0) */
184 WORD idType
; /* Resource Type (1 for icons) */
185 WORD idCount
; /* How many images? */
186 icoICONDIRENTRY idEntries
[1]; /* An entry for each image (idCount of 'em) */
187 } icoICONDIR
, *LPicoICONDIR
;
191 static const char* lpstrMsgWndCreated
= "OTHERWINDOWCREATED";
192 static const char* lpstrMsgWndDestroyed
= "OTHERWINDOWDESTROYED";
193 static const char* lpstrMsgShellActivate
= "ACTIVATESHELLWINDOW";
195 static HWND16 SHELL_hWnd
= 0;
196 static HHOOK SHELL_hHook
= 0;
197 static UINT16 uMsgWndCreated
= 0;
198 static UINT16 uMsgWndDestroyed
= 0;
199 static UINT16 uMsgShellActivate
= 0;
201 /*************************************************************************
202 * DragAcceptFiles [SHELL.9]
204 void WINAPI
DragAcceptFiles(HWND16 hWnd
, BOOL16 b
)
206 WND
* wnd
= WIN_FindWndPtr(hWnd
);
209 wnd
->dwExStyle
= b
? wnd
->dwExStyle
| WS_EX_ACCEPTFILES
210 : wnd
->dwExStyle
& ~WS_EX_ACCEPTFILES
;
214 /*************************************************************************
215 * DragQueryFile [SHELL.11]
217 UINT16 WINAPI
DragQueryFile(HDROP16 hDrop
, WORD wFile
, LPSTR lpszFile
,
220 /* hDrop is a global memory block allocated with GMEM_SHARE
221 * with DROPFILESTRUCT as a header and filenames following
222 * it, zero length filename is in the end */
224 LPDROPFILESTRUCT lpDropFileStruct
;
228 TRACE(reg
,"(%04x, %i, %p, %u)\n",
229 hDrop
,wFile
,lpszFile
,wLength
);
231 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
232 if(!lpDropFileStruct
) return 0;
234 lpCurrent
= (LPSTR
) lpDropFileStruct
+ lpDropFileStruct
->wSize
;
239 while (*lpCurrent
++); /* skip filename */
241 return (wFile
== 0xFFFF) ? i
: 0;
244 i
= strlen(lpCurrent
);
245 if (!lpszFile
) return i
+1; /* needed buffer size */
247 i
= (wLength
> i
) ? i
: wLength
-1;
248 strncpy(lpszFile
, lpCurrent
, i
);
251 GlobalUnlock16(hDrop
);
256 /*************************************************************************
257 * DragFinish [SHELL.12]
259 void WINAPI
DragFinish(HDROP16 h
)
261 GlobalFree16((HGLOBAL16
)h
);
265 /*************************************************************************
266 * DragQueryPoint [SHELL.13]
268 BOOL16 WINAPI
DragQueryPoint(HDROP16 hDrop
, POINT16
*p
)
270 LPDROPFILESTRUCT lpDropFileStruct
;
273 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
275 memcpy(p
,&lpDropFileStruct
->ptMousePos
,sizeof(POINT16
));
276 bRet
= lpDropFileStruct
->fInNonClientArea
;
278 GlobalUnlock16(hDrop
);
282 /*************************************************************************
283 * SHELL_FindExecutable
284 * Utility for code sharing between FindExecutable and ShellExecute
286 static HINSTANCE32
SHELL_FindExecutable( LPCSTR lpFile
,
290 char *extension
= NULL
; /* pointer to file extension */
291 char tmpext
[5]; /* local copy to mung as we please */
292 char filetype
[256]; /* registry name for this filetype */
293 LONG filetypelen
=256; /* length of above */
294 char command
[256]; /* command from registry */
295 LONG commandlen
=256; /* This is the most DOS can handle :) */
296 char buffer
[256]; /* Used to GetProfileString */
297 HINSTANCE32 retval
=31; /* default - 'No association was found' */
298 char *tok
; /* token pointer */
299 int i
; /* random counter */
300 char xlpFile
[256]; /* result of SearchPath */
303 (lpFile
!= NULL
?lpFile
:"-") );
304 lpResult
[0]='\0'; /* Start off with an empty return string */
306 /* trap NULL parameters on entry */
307 if (( lpFile
== NULL
) || ( lpResult
== NULL
) || ( lpOperation
== NULL
))
309 /* FIXME - should throw a warning, perhaps! */
310 return 2; /* File not found. Close enough, I guess. */
313 if (SearchPath32A( NULL
, lpFile
,".exe",sizeof(xlpFile
),xlpFile
,NULL
))
316 /* First thing we need is the file's extension */
317 extension
= strrchr( xlpFile
, '.' ); /* Assume last "." is the one; */
318 /* File->Run in progman uses */
320 if ((extension
== NULL
) || (extension
== &xlpFile
[strlen(xlpFile
)]))
322 return 31; /* no association */
325 /* Make local copy & lowercase it for reg & 'programs=' lookup */
326 lstrcpyn32A( tmpext
, extension
, 5 );
327 CharLower32A( tmpext
);
328 TRACE(exec
, "%s file\n", tmpext
);
330 /* Three places to check: */
331 /* 1. win.ini, [windows], programs (NB no leading '.') */
332 /* 2. Registry, HKEY_CLASS_ROOT\<filetype>\shell\open\command */
333 /* 3. win.ini, [extensions], extension (NB no leading '.' */
334 /* All I know of the order is that registry is checked before */
335 /* extensions; however, it'd make sense to check the programs */
336 /* section first, so that's what happens here. */
338 /* See if it's a program - if GetProfileString fails, we skip this
339 * section. Actually, if GetProfileString fails, we've probably
340 * got a lot more to worry about than running a program... */
341 if ( GetProfileString32A("windows", "programs", "exe pif bat com",
342 buffer
, sizeof(buffer
)) > 0 )
344 for (i
=0;i
<strlen(buffer
); i
++) buffer
[i
]=tolower(buffer
[i
]);
346 tok
= strtok(buffer
, " \t"); /* ? */
349 if (strcmp(tok
, &tmpext
[1])==0) /* have to skip the leading "." */
351 strcpy(lpResult
, xlpFile
);
352 /* Need to perhaps check that the file has a path
354 TRACE(exec
, "found %s\n",
358 /* Greater than 32 to indicate success FIXME According to the
359 * docs, I should be returning a handle for the
360 * executable. Does this mean I'm supposed to open the
361 * executable file or something? More RTFM, I guess... */
363 tok
=strtok(NULL
, " \t");
368 if (RegQueryValue16( (HKEY
)HKEY_CLASSES_ROOT
, tmpext
, filetype
,
369 &filetypelen
) == SHELL_ERROR_SUCCESS
)
371 filetype
[filetypelen
]='\0';
372 TRACE(exec
, "File type: %s\n",
375 /* Looking for ...buffer\shell\lpOperation\command */
376 strcat( filetype
, "\\shell\\" );
377 strcat( filetype
, lpOperation
);
378 strcat( filetype
, "\\command" );
380 if (RegQueryValue16( (HKEY
)HKEY_CLASSES_ROOT
, filetype
, command
,
381 &commandlen
) == SHELL_ERROR_SUCCESS
)
383 /* Is there a replace() function anywhere? */
384 command
[commandlen
]='\0';
385 strcpy( lpResult
, command
);
386 tok
=strstr( lpResult
, "%1" );
389 tok
[0]='\0'; /* truncate string at the percent */
390 strcat( lpResult
, xlpFile
); /* what if no dir in xlpFile? */
391 tok
=strstr( command
, "%1" );
392 if ((tok
!=NULL
) && (strlen(tok
)>2))
394 strcat( lpResult
, &tok
[2] );
397 retval
=33; /* FIXME see above */
400 else /* Check win.ini */
402 /* Toss the leading dot */
404 if ( GetProfileString32A( "extensions", extension
, "", command
,
405 sizeof(command
)) > 0)
407 if (strlen(command
)!=0)
409 strcpy( lpResult
, command
);
410 tok
=strstr( lpResult
, "^" ); /* should be ^.extension? */
414 strcat( lpResult
, xlpFile
); /* what if no dir in xlpFile? */
415 tok
=strstr( command
, "^" ); /* see above */
416 if ((tok
!= NULL
) && (strlen(tok
)>5))
418 strcat( lpResult
, &tok
[5]);
421 retval
=33; /* FIXME - see above */
426 TRACE(exec
, "returning %s\n", lpResult
);
430 /*************************************************************************
431 * ShellExecute16 [SHELL.20]
433 HINSTANCE16 WINAPI
ShellExecute16( HWND16 hWnd
, LPCSTR lpOperation
,
434 LPCSTR lpFile
, LPCSTR lpParameters
,
435 LPCSTR lpDirectory
, INT16 iShowCmd
)
437 HINSTANCE16 retval
=31;
441 TRACE(exec
, "(%04x,'%s','%s','%s','%s',%x)\n",
442 hWnd
, lpOperation
? lpOperation
:"<null>", lpFile
? lpFile
:"<null>",
443 lpParameters
? lpParameters
: "<null>",
444 lpDirectory
? lpDirectory
: "<null>", iShowCmd
);
446 if (lpFile
==NULL
) return 0; /* should not happen */
447 if (lpOperation
==NULL
) /* default is open */
452 GetCurrentDirectory32A( sizeof(old_dir
), old_dir
);
453 SetCurrentDirectory32A( lpDirectory
);
456 retval
= SHELL_FindExecutable( lpFile
, lpOperation
, cmd
);
458 if (retval
> 32) /* Found */
463 strcat(cmd
,lpParameters
);
466 TRACE(exec
,"starting %s\n",cmd
);
467 retval
= WinExec32( cmd
, iShowCmd
);
469 if (lpDirectory
) SetCurrentDirectory32A( old_dir
);
474 /*************************************************************************
475 * ShellExecute32A (SHELL32.245)
477 HINSTANCE32 WINAPI
ShellExecute32A( HWND32 hWnd
, LPCSTR lpOperation
,
478 LPCSTR lpFile
, LPCSTR lpParameters
,
479 LPCSTR lpDirectory
, INT32 iShowCmd
)
481 return ShellExecute16( hWnd
, lpOperation
, lpFile
, lpParameters
,
482 lpDirectory
, iShowCmd
);
486 /*************************************************************************
487 * FindExecutable16 (SHELL.21)
489 HINSTANCE16 WINAPI
FindExecutable16( LPCSTR lpFile
, LPCSTR lpDirectory
,
492 return (HINSTANCE16
)FindExecutable32A( lpFile
, lpDirectory
, lpResult
);
495 /*************************************************************************
496 * FindExecutable32A (SHELL32.184)
498 HINSTANCE32 WINAPI
FindExecutable32A( LPCSTR lpFile
, LPCSTR lpDirectory
,
501 HINSTANCE32 retval
=31; /* default - 'No association was found' */
504 TRACE(exec
, "File %s, Dir %s\n",
505 (lpFile
!= NULL
?lpFile
:"-"),
506 (lpDirectory
!= NULL
?lpDirectory
:"-"));
508 lpResult
[0]='\0'; /* Start off with an empty return string */
510 /* trap NULL parameters on entry */
511 if (( lpFile
== NULL
) || ( lpResult
== NULL
))
513 /* FIXME - should throw a warning, perhaps! */
514 return 2; /* File not found. Close enough, I guess. */
519 GetCurrentDirectory32A( sizeof(old_dir
), old_dir
);
520 SetCurrentDirectory32A( lpDirectory
);
523 retval
= SHELL_FindExecutable( lpFile
, "open", lpResult
);
525 TRACE(exec
, "returning %s\n", lpResult
);
526 if (lpDirectory
) SetCurrentDirectory32A( old_dir
);
537 #define IDC_STATIC_TEXT 100
538 #define IDC_LISTBOX 99
539 #define IDC_WINE_TEXT 98
541 #define DROP_FIELD_TOP (-15)
542 #define DROP_FIELD_HEIGHT 15
544 extern HICON32 hIconTitleFont
;
546 static BOOL32
__get_dropline( HWND32 hWnd
, LPRECT32 lprect
)
548 HWND32 hWndCtl
= GetDlgItem32(hWnd
, IDC_WINE_TEXT
);
551 GetWindowRect32( hWndCtl
, lprect
);
552 MapWindowPoints32( 0, hWnd
, (LPPOINT32
)lprect
, 2 );
553 lprect
->bottom
= (lprect
->top
+= DROP_FIELD_TOP
);
559 /*************************************************************************
560 * AboutDlgProc32 (not an exported API function)
562 LRESULT WINAPI
AboutDlgProc32( HWND32 hWnd
, UINT32 msg
, WPARAM32 wParam
,
566 char Template
[512], AppTitle
[512];
572 ABOUT_INFO
*info
= (ABOUT_INFO
*)lParam
;
575 const char* const *pstr
= SHELL_People
;
576 SendDlgItemMessage32A(hWnd
, stc1
, STM_SETICON32
,info
->hIcon
, 0);
577 GetWindowText32A( hWnd
, Template
, sizeof(Template
) );
578 sprintf( AppTitle
, Template
, info
->szApp
);
579 SetWindowText32A( hWnd
, AppTitle
);
580 SetWindowText32A( GetDlgItem32(hWnd
, IDC_STATIC_TEXT
),
581 info
->szOtherStuff
);
582 hWndCtl
= GetDlgItem32(hWnd
, IDC_LISTBOX
);
583 SendMessage32A( hWndCtl
, WM_SETREDRAW
, 0, 0 );
584 SendMessage32A( hWndCtl
, WM_SETFONT
, hIconTitleFont
, 0 );
587 SendMessage32A( hWndCtl
, LB_ADDSTRING32
,
588 (WPARAM32
)-1, (LPARAM
)*pstr
);
591 SendMessage32A( hWndCtl
, WM_SETREDRAW
, 1, 0 );
600 HDC32 hDC
= BeginPaint32( hWnd
, &ps
);
602 if( __get_dropline( hWnd
, &rect
) )
603 GRAPH_DrawLines( hDC
, (LPPOINT32
)&rect
, 1, GetStockObject32( BLACK_PEN
) );
604 EndPaint32( hWnd
, &ps
);
608 case WM_LBTRACKPOINT
:
610 hWndCtl
= GetDlgItem32(hWnd
, IDC_LISTBOX
);
611 if( (INT16
)GetKeyState16( VK_CONTROL
) < 0 )
613 if( DragDetect32( hWndCtl
, *((LPPOINT32
)&lParam
) ) )
615 INT32 idx
= SendMessage32A( hWndCtl
, LB_GETCURSEL32
, 0, 0 );
618 INT32 length
= SendMessage32A( hWndCtl
, LB_GETTEXTLEN32
, (WPARAM32
)idx
, 0 );
619 HGLOBAL16 hMemObj
= GlobalAlloc16( GMEM_MOVEABLE
, length
+ 1 );
620 char* pstr
= (char*)GlobalLock16( hMemObj
);
624 HCURSOR16 hCursor
= LoadCursor16( 0, MAKEINTRESOURCE(OCR_DRAGOBJECT
) );
625 SendMessage32A( hWndCtl
, LB_GETTEXT32
, (WPARAM32
)idx
, (LPARAM
)pstr
);
626 SendMessage32A( hWndCtl
, LB_DELETESTRING32
, (WPARAM32
)idx
, 0 );
627 UpdateWindow32( hWndCtl
);
628 if( !DragObject16((HWND16
)hWnd
, (HWND16
)hWnd
, DRAGOBJ_DATA
, 0, (WORD
)hMemObj
, hCursor
) )
629 SendMessage32A( hWndCtl
, LB_ADDSTRING32
, (WPARAM32
)-1, (LPARAM
)pstr
);
631 if( hMemObj
) GlobalFree16( hMemObj
);
637 case WM_QUERYDROPOBJECT
:
640 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
641 if( lpDragInfo
&& lpDragInfo
->wFlags
== DRAGOBJ_DATA
)
644 if( __get_dropline( hWnd
, &rect
) )
646 POINT32 pt
= { lpDragInfo
->pt
.x
, lpDragInfo
->pt
.y
};
647 rect
.bottom
+= DROP_FIELD_HEIGHT
;
648 if( PtInRect32( &rect
, pt
) )
650 SetWindowLong32A( hWnd
, DWL_MSGRESULT
, 1 );
661 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
662 if( lpDragInfo
&& lpDragInfo
->wFlags
== DRAGOBJ_DATA
&& lpDragInfo
->hList
)
664 char* pstr
= (char*)GlobalLock16( (HGLOBAL16
)(lpDragInfo
->hList
) );
667 static char __appendix_str
[] = " with";
669 hWndCtl
= GetDlgItem32( hWnd
, IDC_WINE_TEXT
);
670 SendMessage32A( hWndCtl
, WM_GETTEXT
, 512, (LPARAM
)Template
);
671 if( !lstrncmp32A( Template
, "WINE", 4 ) )
672 SetWindowText32A( GetDlgItem32(hWnd
, IDC_STATIC_TEXT
), Template
);
675 char* pch
= Template
+ strlen(Template
) - strlen(__appendix_str
);
677 SendMessage32A( GetDlgItem32(hWnd
, IDC_LISTBOX
), LB_ADDSTRING32
,
678 (WPARAM32
)-1, (LPARAM
)Template
);
681 lstrcpy32A( Template
, pstr
);
682 lstrcat32A( Template
, __appendix_str
);
683 SetWindowText32A( hWndCtl
, Template
);
685 SetWindowLong32A( hWnd
, DWL_MSGRESULT
, 1 );
695 EndDialog32(hWnd
, TRUE
);
704 /*************************************************************************
705 * AboutDlgProc16 (SHELL.33)
707 LRESULT WINAPI
AboutDlgProc16( HWND16 hWnd
, UINT16 msg
, WPARAM16 wParam
,
710 return AboutDlgProc32( hWnd
, msg
, wParam
, lParam
);
714 /*************************************************************************
715 * ShellAbout16 (SHELL.22)
717 BOOL16 WINAPI
ShellAbout16( HWND16 hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
,
720 return ShellAbout32A( hWnd
, szApp
, szOtherStuff
, hIcon
);
723 /*************************************************************************
724 * ShellAbout32A (SHELL32.243)
726 BOOL32 WINAPI
ShellAbout32A( HWND32 hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
,
731 info
.szOtherStuff
= szOtherStuff
;
733 if (!hIcon
) info
.hIcon
= LoadIcon16( 0, MAKEINTRESOURCE(OIC_WINEICON
) );
734 return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd
),
735 SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX
),
736 hWnd
, AboutDlgProc32
, (LPARAM
)&info
);
740 /*************************************************************************
741 * ShellAbout32W (SHELL32.244)
743 BOOL32 WINAPI
ShellAbout32W( HWND32 hWnd
, LPCWSTR szApp
, LPCWSTR szOtherStuff
,
749 info
.szApp
= HEAP_strdupWtoA( GetProcessHeap(), 0, szApp
);
750 info
.szOtherStuff
= HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff
);
752 if (!hIcon
) info
.hIcon
= LoadIcon16( 0, MAKEINTRESOURCE(OIC_WINEICON
) );
753 ret
= DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd
),
754 SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX
),
755 hWnd
, AboutDlgProc32
, (LPARAM
)&info
);
756 HeapFree( GetProcessHeap(), 0, (LPSTR
)info
.szApp
);
757 HeapFree( GetProcessHeap(), 0, (LPSTR
)info
.szOtherStuff
);
761 /*************************************************************************
762 * Shell_NotifyIcon [SHELL32.249]
764 * This function is supposed to deal with the systray.
765 * Any ideas on how this is to be implimented?
767 BOOL32 WINAPI
Shell_NotifyIcon( DWORD dwMessage
,
768 PNOTIFYICONDATA pnid
)
773 /*************************************************************************
774 * Shell_NotifyIcon [SHELL32.240]
776 * This function is supposed to deal with the systray.
777 * Any ideas on how this is to be implimented?
779 BOOL32 WINAPI
Shell_NotifyIconA(DWORD dwMessage
,
780 PNOTIFYICONDATA pnid
)
785 /*************************************************************************
786 * SHELL_GetResourceTable
788 static DWORD
SHELL_GetResourceTable(HFILE32 hFile
,LPBYTE
*retptr
)
790 IMAGE_DOS_HEADER mz_header
;
795 _llseek32( hFile
, 0, SEEK_SET
);
796 if ( (_lread32(hFile
,&mz_header
,sizeof(mz_header
)) != sizeof(mz_header
)) ||
797 (mz_header
.e_magic
!= IMAGE_DOS_SIGNATURE
)
801 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
802 if (_lread32( hFile
, magic
, sizeof(magic
) ) != sizeof(magic
))
804 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
806 if (*(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
807 return IMAGE_NT_SIGNATURE
;
808 if (*(WORD
*)magic
== IMAGE_OS2_SIGNATURE
) {
809 IMAGE_OS2_HEADER ne_header
;
810 LPBYTE pTypeInfo
= (LPBYTE
)-1;
812 if (_lread32(hFile
,&ne_header
,sizeof(ne_header
))!=sizeof(ne_header
))
815 if (ne_header
.ne_magic
!= IMAGE_OS2_SIGNATURE
) return 0;
816 size
= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
817 if( size
> sizeof(NE_TYPEINFO
) )
819 pTypeInfo
= (BYTE
*)HeapAlloc( GetProcessHeap(), 0, size
);
821 _llseek32(hFile
, mz_header
.e_lfanew
+ne_header
.resource_tab_offset
, SEEK_SET
);
822 if( _lread32( hFile
, (char*)pTypeInfo
, size
) != size
) {
823 HeapFree( GetProcessHeap(), 0, pTypeInfo
);
830 *retptr
= (LPBYTE
)-1;
831 return IMAGE_OS2_SIGNATURE
; /* handles .ICO too */
835 /*************************************************************************
838 static HGLOBAL16
SHELL_LoadResource(HINSTANCE16 hInst
, HFILE32 hFile
, NE_NAMEINFO
* pNInfo
, WORD sizeShift
)
841 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, (DWORD
)pNInfo
->length
<< sizeShift
);
843 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
845 _llseek32( hFile
, (DWORD
)pNInfo
->offset
<< sizeShift
, SEEK_SET
);
846 _lread32( hFile
, (char*)ptr
, pNInfo
->length
<< sizeShift
);
852 /*************************************************************************
855 static HGLOBAL16
ICO_LoadIcon(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIRENTRY lpiIDE
)
858 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, lpiIDE
->dwBytesInRes
);
860 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
862 _llseek32( hFile
, lpiIDE
->dwImageOffset
, SEEK_SET
);
863 _lread32( hFile
, (char*)ptr
, lpiIDE
->dwBytesInRes
);
869 /*************************************************************************
870 * ICO_GetIconDirectory
872 * Read .ico file and build phony ICONDIR struct for GetIconID
874 static HGLOBAL16
ICO_GetIconDirectory(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIR
* lplpiID
)
876 WORD id
[3]; /* idReserved, idType, idCount */
880 _llseek32( hFile
, 0, SEEK_SET
);
881 if( _lread32(hFile
,(char*)id
,sizeof(id
)) != sizeof(id
) ) return 0;
885 * - see http://www.microsoft.com/win32dev/ui/icons.htm
888 if( id
[0] || id
[1] != 1 || !id
[2] ) return 0;
890 i
= id
[2]*sizeof(icoICONDIRENTRY
) + sizeof(id
);
892 lpiID
= (LPicoICONDIR
)HeapAlloc( GetProcessHeap(), 0, i
);
894 if( _lread32(hFile
,(char*)lpiID
->idEntries
,i
) == i
)
896 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10,
897 id
[2]*sizeof(ICONDIRENTRY
) + sizeof(id
) );
900 CURSORICONDIR
* lpID
= (CURSORICONDIR
*)GlobalLock16( handle
);
901 lpID
->idReserved
= lpiID
->idReserved
= id
[0];
902 lpID
->idType
= lpiID
->idType
= id
[1];
903 lpID
->idCount
= lpiID
->idCount
= id
[2];
904 for( i
=0; i
< lpiID
->idCount
; i
++ )
906 memcpy((void*)(lpID
->idEntries
+ i
),
907 (void*)(lpiID
->idEntries
+ i
), sizeof(ICONDIRENTRY
) - 2);
908 lpID
->idEntries
[i
].icon
.wResId
= i
;
916 HeapFree( GetProcessHeap(), 0, lpiID
);
920 /*************************************************************************
921 * InternalExtractIcon [SHELL.39]
923 * This abortion is called directly by Progman
925 HGLOBAL16 WINAPI
InternalExtractIcon(HINSTANCE16 hInstance
,
926 LPCSTR lpszExeFileName
, UINT16 nIconIndex
,
930 HGLOBAL16
* RetPtr
= NULL
;
934 HFILE32 hFile
= OpenFile32( lpszExeFileName
, &ofs
, OF_READ
);
935 UINT16 iconDirCount
= 0,iconCount
= 0;
937 TRACE(reg
,"(%04x,file %s,start %d,extract %d\n",
938 hInstance
, lpszExeFileName
, nIconIndex
, n
);
940 if( hFile
== HFILE_ERROR32
|| !n
) return 0;
942 hRet
= GlobalAlloc16( GMEM_FIXED
| GMEM_ZEROINIT
, sizeof(HICON16
)*n
);
943 RetPtr
= (HICON16
*)GlobalLock16(hRet
);
945 *RetPtr
= (n
== 0xFFFF)? 0: 1; /* error return values */
947 sig
= SHELL_GetResourceTable(hFile
,&pData
);
949 if(sig
== IMAGE_OS2_SIGNATURE
)
952 NE_TYPEINFO
* pTInfo
= (NE_TYPEINFO
*)(pData
+ 2);
953 NE_NAMEINFO
* pIconStorage
= NULL
;
954 NE_NAMEINFO
* pIconDir
= NULL
;
955 LPicoICONDIR lpiID
= NULL
;
957 if( pData
== (BYTE
*)-1 )
959 /* check for .ICO file */
961 hIcon
= ICO_GetIconDirectory(hInstance
, hFile
, &lpiID
);
962 if( hIcon
) { iconDirCount
= 1; iconCount
= lpiID
->idCount
; }
964 else while( pTInfo
->type_id
&& !(pIconStorage
&& pIconDir
) )
966 /* find icon directory and icon repository */
968 if( pTInfo
->type_id
== NE_RSCTYPE_GROUP_ICON
)
970 iconDirCount
= pTInfo
->count
;
971 pIconDir
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
972 TRACE(reg
,"\tfound directory - %i icon families\n", iconDirCount
);
974 if( pTInfo
->type_id
== NE_RSCTYPE_ICON
)
976 iconCount
= pTInfo
->count
;
977 pIconStorage
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
978 TRACE(reg
,"\ttotal icons - %i\n", iconCount
);
980 pTInfo
= (NE_TYPEINFO
*)((char*)(pTInfo
+1)+pTInfo
->count
*sizeof(NE_NAMEINFO
));
983 /* load resources and create icons */
985 if( (pIconStorage
&& pIconDir
) || lpiID
)
986 if( nIconIndex
== (UINT16
)-1 ) RetPtr
[0] = iconDirCount
;
987 else if( nIconIndex
< iconDirCount
)
991 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
993 for( i
= nIconIndex
; i
< nIconIndex
+ n
; i
++ )
995 /* .ICO files have only one icon directory */
998 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconDir
+ i
,
1000 RetPtr
[i
-nIconIndex
] = GetIconID( hIcon
, 3 );
1001 GlobalFree16(hIcon
);
1004 for( icon
= nIconIndex
; icon
< nIconIndex
+ n
; icon
++ )
1008 hIcon
= ICO_LoadIcon( hInstance
, hFile
,
1009 lpiID
->idEntries
+ RetPtr
[icon
-nIconIndex
]);
1011 for( i
= 0; i
< iconCount
; i
++ )
1012 if( pIconStorage
[i
].id
== (RetPtr
[icon
-nIconIndex
] | 0x8000) )
1013 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconStorage
+ i
,
1017 RetPtr
[icon
-nIconIndex
] = LoadIconHandler( hIcon
, TRUE
);
1018 FarSetOwner( RetPtr
[icon
-nIconIndex
], GetExePtr(hInstance
) );
1021 RetPtr
[icon
-nIconIndex
] = 0;
1024 if( lpiID
) HeapFree( GetProcessHeap(), 0, lpiID
);
1025 else HeapFree( GetProcessHeap(), 0, pData
);
1027 if( sig
== IMAGE_NT_SIGNATURE
)
1029 LPBYTE peimage
,idata
,igdata
;
1030 LPIMAGE_DOS_HEADER dheader
;
1031 LPIMAGE_NT_HEADERS pe_header
;
1032 LPIMAGE_SECTION_HEADER pe_sections
;
1033 LPIMAGE_RESOURCE_DIRECTORY rootresdir
,iconresdir
,icongroupresdir
;
1034 LPIMAGE_RESOURCE_DATA_ENTRY idataent
,igdataent
;
1037 LPIMAGE_RESOURCE_DIRECTORY_ENTRY xresent
;
1038 CURSORICONDIR
**cids
;
1040 fmapping
= CreateFileMapping32A(hFile
,NULL
,PAGE_READONLY
|SEC_COMMIT
,0,0,NULL
);
1041 if (fmapping
== 0) { /* FIXME, INVALID_HANDLE_VALUE? */
1042 WARN(reg
,"failed to create filemap.\n");
1046 peimage
= MapViewOfFile(fmapping
,FILE_MAP_READ
,0,0,0);
1048 WARN(reg
,"failed to mmap filemap.\n");
1049 CloseHandle(fmapping
);
1053 dheader
= (LPIMAGE_DOS_HEADER
)peimage
;
1054 /* it is a pe header, SHELL_GetResourceTable checked that */
1055 pe_header
= (LPIMAGE_NT_HEADERS
)(peimage
+dheader
->e_lfanew
);
1056 /* probably makes problems with short PE headers... but I haven't seen
1059 pe_sections
= (LPIMAGE_SECTION_HEADER
)(((char*)pe_header
)+sizeof(*pe_header
));
1061 for (i
=0;i
<pe_header
->FileHeader
.NumberOfSections
;i
++) {
1062 if (pe_sections
[i
].Characteristics
& IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
1064 /* FIXME: doesn't work when the resources are not in a seperate section */
1065 if (pe_sections
[i
].VirtualAddress
== pe_header
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
].VirtualAddress
) {
1066 rootresdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((char*)peimage
+pe_sections
[i
].PointerToRawData
);
1072 WARN(reg
,"haven't found section for resource directory.\n");
1073 UnmapViewOfFile(peimage
);
1074 CloseHandle(fmapping
);
1078 icongroupresdir
= GetResDirEntryW(rootresdir
,(LPWSTR
)RT_GROUP_ICON
,(DWORD
)rootresdir
,FALSE
);
1079 if (!icongroupresdir
) {
1080 WARN(reg
,"No Icongroupresourcedirectory!\n");
1081 UnmapViewOfFile(peimage
);
1082 CloseHandle(fmapping
);
1087 iconDirCount
= icongroupresdir
->NumberOfNamedEntries
+icongroupresdir
->NumberOfIdEntries
;
1088 if( nIconIndex
== (UINT16
)-1 ) {
1089 RetPtr
[0] = iconDirCount
;
1090 UnmapViewOfFile(peimage
);
1091 CloseHandle(fmapping
);
1096 if (nIconIndex
>= iconDirCount
) {
1097 WARN(reg
,"nIconIndex %d is larger than iconDirCount %d\n",
1098 nIconIndex
,iconDirCount
);
1099 UnmapViewOfFile(peimage
);
1100 CloseHandle(fmapping
);
1105 cids
= (CURSORICONDIR
**)HeapAlloc(GetProcessHeap(),0,n
*sizeof(CURSORICONDIR
*));
1107 /* caller just wanted the number of entries */
1109 xresent
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)(icongroupresdir
+1);
1110 /* assure we don't get too much ... */
1111 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
1113 /* starting from specified index ... */
1114 xresent
= xresent
+nIconIndex
;
1116 for (i
=0;i
<n
;i
++,xresent
++) {
1118 LPIMAGE_RESOURCE_DIRECTORY resdir
;
1120 /* go down this resource entry, name */
1121 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((DWORD
)rootresdir
+(xresent
->u2
.s
.OffsetToDirectory
));
1122 /* default language (0) */
1123 resdir
= GetResDirEntryW(resdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1124 igdataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)resdir
;
1126 /* lookup address in mapped image for virtual address */
1128 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1129 if (igdataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1131 if (igdataent
->OffsetToData
+igdataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1133 igdata
= peimage
+(igdataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1136 WARN(reg
,"no matching real address for icongroup!\n");
1137 UnmapViewOfFile(peimage
);
1138 CloseHandle(fmapping
);
1143 cid
= (CURSORICONDIR
*)igdata
;
1145 RetPtr
[i
] = LookupIconIdFromDirectoryEx32(igdata
,TRUE
,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1147 iconresdir
=GetResDirEntryW(rootresdir
,(LPWSTR
)RT_ICON
,(DWORD
)rootresdir
,FALSE
);
1149 WARN(reg
,"No Iconresourcedirectory!\n");
1150 UnmapViewOfFile(peimage
);
1151 CloseHandle(fmapping
);
1156 LPIMAGE_RESOURCE_DIRECTORY xresdir
;
1158 xresdir
= GetResDirEntryW(iconresdir
,(LPWSTR
)RetPtr
[i
],(DWORD
)rootresdir
,FALSE
);
1159 xresdir
= GetResDirEntryW(xresdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1161 idataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)xresdir
;
1164 /* map virtual to address in image */
1165 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1166 if (idataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1168 if (idataent
->OffsetToData
+idataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1170 idata
= peimage
+(idataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1173 WARN(reg
,"no matching real address found for icondata!\n");
1177 RetPtr
[i
] = CreateIconFromResourceEx32(idata
,idataent
->Size
,TRUE
,0x00030000,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1179 UnmapViewOfFile(peimage
);
1180 CloseHandle(fmapping
);
1185 /* return array with icon handles */
1190 /*************************************************************************
1191 * ExtractIcon16 (SHELL.34)
1193 HICON16 WINAPI
ExtractIcon16( HINSTANCE16 hInstance
, LPCSTR lpszExeFileName
,
1196 return ExtractIcon32A( hInstance
, lpszExeFileName
, nIconIndex
);
1200 /*************************************************************************
1201 * ExtractIcon32A (SHELL32.133)
1203 HICON32 WINAPI
ExtractIcon32A( HINSTANCE32 hInstance
, LPCSTR lpszExeFileName
,
1206 HGLOBAL16 handle
= InternalExtractIcon(hInstance
,lpszExeFileName
,nIconIndex
, 1);
1210 HICON16
* ptr
= (HICON16
*)GlobalLock16(handle
);
1211 HICON16 hIcon
= *ptr
;
1213 GlobalFree16(handle
);
1219 /*************************************************************************
1220 * ExtractIcon32W (SHELL32.180)
1222 HICON32 WINAPI
ExtractIcon32W( HINSTANCE32 hInstance
, LPCWSTR lpszExeFileName
,
1225 LPSTR exefn
= HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName
);
1226 HICON32 ret
= ExtractIcon32A(hInstance
,exefn
,nIconIndex
);
1228 HeapFree(GetProcessHeap(),0,exefn
);
1233 /*************************************************************************
1234 * ExtractAssociatedIcon [SHELL.36]
1236 * Return icon for given file (either from file itself or from associated
1237 * executable) and patch parameters if needed.
1239 HICON32 WINAPI
ExtractAssociatedIcon32A(HINSTANCE32 hInst
,LPSTR lpIconPath
,
1242 return ExtractAssociatedIcon16(hInst
,lpIconPath
,lpiIcon
);
1245 HICON16 WINAPI
ExtractAssociatedIcon16(HINSTANCE16 hInst
,LPSTR lpIconPath
,
1248 HICON16 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1253 if( hIcon
== 1 ) /* no icons found in given file */
1255 char tempPath
[0x80];
1256 UINT16 uRet
= FindExecutable16(lpIconPath
,NULL
,tempPath
);
1258 if( uRet
> 32 && tempPath
[0] )
1260 strcpy(lpIconPath
,tempPath
);
1261 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1263 if( hIcon
> 2 ) return hIcon
;
1269 *lpiIcon
= 2; /* MSDOS icon - we found .exe but no icons in it */
1271 *lpiIcon
= 6; /* generic icon - found nothing */
1273 GetModuleFileName16(hInst
, lpIconPath
, 0x80);
1274 hIcon
= LoadIcon16( hInst
, MAKEINTRESOURCE(*lpiIcon
));
1280 /*************************************************************************
1281 * FindEnvironmentString [SHELL.38]
1283 * Returns a pointer into the DOS environment... Ugh.
1285 LPSTR
SHELL_FindString(LPSTR lpEnv
, LPCSTR entry
)
1287 UINT16 l
= strlen(entry
);
1288 for( ; *lpEnv
; lpEnv
+=strlen(lpEnv
)+1 )
1290 if( lstrncmpi32A(lpEnv
, entry
, l
) ) continue;
1293 return (lpEnv
+ l
); /* empty entry */
1294 else if ( *(lpEnv
+l
)== '=' )
1295 return (lpEnv
+ l
+ 1);
1300 SEGPTR WINAPI
FindEnvironmentString(LPSTR str
)
1302 SEGPTR spEnv
= GetDOSEnvironment();
1303 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(spEnv
);
1305 LPSTR lpString
= (spEnv
)?SHELL_FindString(lpEnv
, str
):NULL
;
1307 if( lpString
) /* offset should be small enough */
1308 return spEnv
+ (lpString
- lpEnv
);
1310 return (SEGPTR
)NULL
;
1313 /*************************************************************************
1314 * DoEnvironmentSubst [SHELL.37]
1316 * Replace %KEYWORD% in the str with the value of variable KEYWORD
1317 * from "DOS" environment.
1319 DWORD WINAPI
DoEnvironmentSubst(LPSTR str
,WORD length
)
1321 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(GetDOSEnvironment());
1322 LPSTR lpBuffer
= (LPSTR
)HeapAlloc( GetProcessHeap(), 0, length
);
1324 LPSTR lpbstr
= lpBuffer
;
1326 CharToOem32A(str
,str
);
1328 TRACE(reg
,"accept %s\n", str
);
1330 while( *lpstr
&& lpbstr
- lpBuffer
< length
)
1332 LPSTR lpend
= lpstr
;
1336 do { lpend
++; } while( *lpend
&& *lpend
!= '%' );
1337 if( *lpend
== '%' && lpend
- lpstr
> 1 ) /* found key */
1341 lpKey
= SHELL_FindString(lpEnv
, lpstr
+1);
1342 if( lpKey
) /* found key value */
1344 int l
= strlen(lpKey
);
1346 if( l
> length
- (lpbstr
- lpBuffer
) - 1 )
1348 WARN(reg
,"Env subst aborted - string too short\n");
1352 strcpy(lpbstr
, lpKey
);
1359 else break; /* back off and whine */
1364 *lpbstr
++ = *lpstr
++;
1368 if( lpstr
- str
== strlen(str
) )
1370 strncpy(str
, lpBuffer
, length
);
1376 TRACE(reg
," return %s\n", str
);
1378 OemToChar32A(str
,str
);
1379 HeapFree( GetProcessHeap(), 0, lpBuffer
);
1381 /* Return str length in the LOWORD
1382 * and 1 in HIWORD if subst was successful.
1384 return (DWORD
)MAKELONG(strlen(str
), length
);
1387 /*************************************************************************
1388 * ShellHookProc [SHELL.103]
1389 * System-wide WH_SHELL hook.
1391 LRESULT WINAPI
ShellHookProc(INT16 code
, WPARAM16 wParam
, LPARAM lParam
)
1393 TRACE(reg
,"%i, %04x, %08x\n", code
, wParam
,
1395 if( SHELL_hHook
&& SHELL_hWnd
)
1400 case HSHELL_WINDOWCREATED
: uMsg
= uMsgWndCreated
; break;
1401 case HSHELL_WINDOWDESTROYED
: uMsg
= uMsgWndDestroyed
; break;
1402 case HSHELL_ACTIVATESHELLWINDOW
: uMsg
= uMsgShellActivate
;
1404 PostMessage16( SHELL_hWnd
, uMsg
, wParam
, 0 );
1406 return CallNextHookEx16( WH_SHELL
, code
, wParam
, lParam
);
1409 LRESULT WINAPI
FUNC004(INT16 code
, WPARAM16 wParam
, /*LPARAM*/WORD lParam
)
1411 FIXME(reg
,"(%d,%d,%d),STUB!\n",code
,wParam
,lParam
);
1412 return ShellHookProc(code
,wParam
,(DWORD
)lParam
);
1415 /*************************************************************************
1416 * RegisterShellHook [SHELL.102]
1418 BOOL32 WINAPI
RegisterShellHook(HWND16 hWnd
, UINT16 uAction
)
1420 TRACE(reg
,"%04x [%u]\n", hWnd
, uAction
);
1424 case 2: /* register hWnd as a shell window */
1428 HMODULE16 hShell
= GetModuleHandle16( "SHELL" );
1430 SHELL_hHook
= SetWindowsHookEx16( WH_SHELL
, ShellHookProc
,
1434 uMsgWndCreated
= RegisterWindowMessage32A( lpstrMsgWndCreated
);
1435 uMsgWndDestroyed
= RegisterWindowMessage32A( lpstrMsgWndDestroyed
);
1436 uMsgShellActivate
= RegisterWindowMessage32A( lpstrMsgShellActivate
);
1438 else WARN(reg
, "unable to install ShellHookProc()!\n");
1441 if( SHELL_hHook
) return ((SHELL_hWnd
= hWnd
) != 0);
1446 WARN(reg
, "unknown code %i\n", uAction
);
1456 /*************************************************************************
1457 * SHGetFileInfoA [SHELL32.218]
1459 DWORD WINAPI
SHGetFileInfo32A(LPCSTR path
,DWORD dwFileAttributes
,
1460 SHFILEINFO32A
*psfi
, UINT32 sizeofpsfi
,
1463 fprintf(stdnimp
,"SHGetFileInfo32A(%s,0x%08lx,%p,%d,0x%08x)\n",
1464 path
,dwFileAttributes
,psfi
,sizeofpsfi
,flags
1469 /*************************************************************************
1470 * SHAppBarMessage32 [SHELL32.207]
1472 UINT32 WINAPI
SHAppBarMessage32(DWORD msg
, PAPPBARDATA data
)
1474 fprintf(stdnimp
,"SHAppBarMessage32(0x%08lx,%p)\n", msg
, data
);
1478 case ABM_GETAUTOHIDEBAR
:
1480 case ABM_GETTASKBARPOS
:
1484 case ABM_SETAUTOHIDEBAR
:
1486 case ABM_WINDOWPOSCHANGED
:
1493 /*************************************************************************
1494 * CommandLineToArgvW [SHELL32.7]
1496 LPWSTR
* WINAPI
CommandLineToArgvW(LPWSTR cmdline
,LPDWORD numargs
)
1501 /* to get writeable copy */
1502 cmdline
= HEAP_strdupW( GetProcessHeap(), 0, cmdline
);
1509 while (*s
&& *s
==0x0020)
1515 argv
=(LPWSTR
*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR
)*(i
+1) );
1521 argv
[i
++]=HEAP_strdupW( GetProcessHeap(), 0, t
);
1523 while (*s
&& *s
==0x0020)
1534 argv
[i
++]=(LPWSTR
)HEAP_strdupW( GetProcessHeap(), 0, t
);
1535 HeapFree( GetProcessHeap(), 0, cmdline
);
1541 /*************************************************************************
1542 * Control_RunDLL [SHELL32.12]
1544 * Wild speculation in the following!
1546 * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
1549 void WINAPI
Control_RunDLL (HWND32 hwnd
, LPCVOID code
, LPCSTR cmd
, DWORD arg4
)
1551 TRACE(exec
, "(%08x, %p, \"%s\", %08lx)\n",
1552 hwnd
, code
? code
: "(null)",
1553 cmd
? cmd
: "(null)", arg4
);
1556 /*************************************************************************
1559 void WINAPI
FreeIconList( DWORD dw
)
1561 fprintf( stdnimp
, "FreeIconList: empty stub\n" );
1564 /*************************************************************************
1565 * SHELL32_DllGetClassObject [SHELL32.14]
1567 * http://premium.microsoft.com/msdn/library/sdkdoc/api2_48fo.htm
1569 DWORD WINAPI
SHELL32_DllGetClassObject(REFCLSID rclsid
,REFIID iid
,LPVOID
*ppv
)
1571 char xclsid
[50],xiid
[50];
1572 HRESULT hres
= E_OUTOFMEMORY
;
1575 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
1576 WINE_StringFromCLSID((LPCLSID
)iid
,xiid
);
1577 fprintf(stderr
,"SHELL32_DllGetClassObject(%s,%s,%p)\n",xclsid
,xiid
,ppv
);
1580 /* SDK example code looks like this:
1582 HRESULT hres = E_OUTOFMEMORY;
1585 CClassFactory *pClassFactory = new CClassFactory(rclsid);
1587 if (pClassFactory) {
1588 hRes = pClassFactory->QueryInterface(riid,ppv);
1589 pClassFactory->Release();
1593 * The magic of the whole stuff is still unclear to me, so just hack together
1597 if (!memcmp(rclsid
,&CLSID_ShellDesktop
,sizeof(CLSID_ShellDesktop
))) {
1598 fprintf(stderr
," requested CLSID_ShellDesktop, creating it.\n");
1599 *ppv
= IShellFolder_Constructor();
1600 /* FIXME: Initialize this folder to be the shell desktop folder */
1604 fprintf (stdnimp
, " -> clsid not found. returning E_OUTOFMEMORY.\n");
1608 /*************************************************************************
1609 * SHGetDesktopFolder [SHELL32.216]
1610 * returns the interface to the shell desktop folder.
1612 * [SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
1613 * CLSID_ShellDesktop.
1615 * CoCreateInstance(CLSID_Desktop, NULL,
1616 * CLSCTX_INPROC, IID_IShellFolder, &pshf);
1618 * So what we are doing is currently wrong....
1620 DWORD WINAPI
SHGetDesktopFolder(LPSHELLFOLDER
*shellfolder
) {
1621 *shellfolder
= IShellFolder_Constructor();
1625 /*************************************************************************
1626 * SHGetMalloc [SHELL32.220]
1627 * returns the interface to shell malloc.
1629 * [SDK header win95/shlobj.h:
1630 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
1632 * What we are currently doing is not very wrong, since we always use the same
1633 * heap (ProcessHeap).
1635 DWORD WINAPI
SHGetMalloc(LPMALLOC32
*lpmal
) {
1636 fprintf(stderr
,"SHGetMalloc()\n");
1637 return CoGetMalloc32(0,lpmal
);
1640 /*************************************************************************
1641 * SHGetSpecialFolderLocation [SHELL32.223]
1642 * returns the PIDL of a special folder
1644 * nFolder is a CSIDL_xxxxx.
1646 HRESULT WINAPI
SHGetSpecialFolderLocation(HWND32 hwndOwner
, INT32 nFolder
, LPITEMIDLIST
* ppidl
) {
1647 fprintf(stderr
,"SHGetSpecialFolderLocation(%04x,%d,%p),stub!\n",
1648 hwndOwner
,nFolder
,ppidl
1650 *ppidl
= (LPITEMIDLIST
)HeapAlloc(GetProcessHeap(),0,2*sizeof(ITEMIDLIST
));
1651 /* FIXME: we return only the empty ITEMIDLIST currently. */
1652 (*ppidl
)->mkid
.cb
= 0;
1656 /*************************************************************************
1657 * SHGetPathFromIDList [SHELL32.221]
1658 * returns the path from a passed PIDL.
1660 BOOL32 WINAPI
SHGetPathFromIDList(LPCITEMIDLIST pidl
,LPSTR pszPath
) {
1661 fprintf(stderr
,"SHGetPathFromIDList(%p,%p),stub!\n",pidl
,pszPath
);
1662 lstrcpy32A(pszPath
,"E:\\"); /* FIXME */