2 * Shell Library Functions
21 #include "cursoricon.h"
22 #include "interfaces.h"
23 #include "sysmetrics.h"
28 static const char * const SHELL_People
[] =
45 "Niels de Carpentier",
51 "Frans van Dorsselaer",
102 "Philippe De Muyter",
115 "Bernhard Rosenkraenzer",
116 "Johannes Ruscheinski",
118 "Constantine Sapuntzakis",
126 "Yngvi Sigurjonsson",
141 "Gregory Trubetskoy",
153 "Karl Guenter Wuensch",
156 "Nikita V. Youshchenko",
159 "Luiz Otavio L. Zorzella",
164 /* .ICO file ICONDIR definitions */
170 BYTE bWidth
; /* Width, in pixels, of the image */
171 BYTE bHeight
; /* Height, in pixels, of the image */
172 BYTE bColorCount
; /* Number of colors in image (0 if >=8bpp) */
173 BYTE bReserved
; /* Reserved ( must be 0) */
174 WORD wPlanes
; /* Color Planes */
175 WORD wBitCount
; /* Bits per pixel */
176 DWORD dwBytesInRes
; /* How many bytes in this resource? */
177 DWORD dwImageOffset
; /* Where in the file is this image? */
178 } icoICONDIRENTRY
, *LPicoICONDIRENTRY
;
182 WORD idReserved
; /* Reserved (must be 0) */
183 WORD idType
; /* Resource Type (1 for icons) */
184 WORD idCount
; /* How many images? */
185 icoICONDIRENTRY idEntries
[1]; /* An entry for each image (idCount of 'em) */
186 } icoICONDIR
, *LPicoICONDIR
;
190 static const char* lpstrMsgWndCreated
= "OTHERWINDOWCREATED";
191 static const char* lpstrMsgWndDestroyed
= "OTHERWINDOWDESTROYED";
192 static const char* lpstrMsgShellActivate
= "ACTIVATESHELLWINDOW";
194 static HWND16 SHELL_hWnd
= 0;
195 static HHOOK SHELL_hHook
= 0;
196 static UINT16 uMsgWndCreated
= 0;
197 static UINT16 uMsgWndDestroyed
= 0;
198 static UINT16 uMsgShellActivate
= 0;
200 /*************************************************************************
201 * DragAcceptFiles [SHELL.9]
203 void WINAPI
DragAcceptFiles(HWND16 hWnd
, BOOL16 b
)
205 WND
* wnd
= WIN_FindWndPtr(hWnd
);
208 wnd
->dwExStyle
= b
? wnd
->dwExStyle
| WS_EX_ACCEPTFILES
209 : wnd
->dwExStyle
& ~WS_EX_ACCEPTFILES
;
213 /*************************************************************************
214 * DragQueryFile [SHELL.11]
216 UINT16 WINAPI
DragQueryFile(HDROP16 hDrop
, WORD wFile
, LPSTR lpszFile
,
219 /* hDrop is a global memory block allocated with GMEM_SHARE
220 * with DROPFILESTRUCT as a header and filenames following
221 * it, zero length filename is in the end */
223 LPDROPFILESTRUCT lpDropFileStruct
;
227 TRACE(reg
,"(%04x, %i, %p, %u)\n",
228 hDrop
,wFile
,lpszFile
,wLength
);
230 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
231 if(!lpDropFileStruct
) return 0;
233 lpCurrent
= (LPSTR
) lpDropFileStruct
+ lpDropFileStruct
->wSize
;
238 while (*lpCurrent
++); /* skip filename */
240 return (wFile
== 0xFFFF) ? i
: 0;
243 i
= strlen(lpCurrent
);
244 if (!lpszFile
) return i
+1; /* needed buffer size */
246 i
= (wLength
> i
) ? i
: wLength
-1;
247 strncpy(lpszFile
, lpCurrent
, i
);
250 GlobalUnlock16(hDrop
);
255 /*************************************************************************
256 * DragFinish [SHELL.12]
258 void WINAPI
DragFinish(HDROP16 h
)
260 GlobalFree16((HGLOBAL16
)h
);
264 /*************************************************************************
265 * DragQueryPoint [SHELL.13]
267 BOOL16 WINAPI
DragQueryPoint(HDROP16 hDrop
, POINT16
*p
)
269 LPDROPFILESTRUCT lpDropFileStruct
;
272 lpDropFileStruct
= (LPDROPFILESTRUCT
) GlobalLock16(hDrop
);
274 memcpy(p
,&lpDropFileStruct
->ptMousePos
,sizeof(POINT16
));
275 bRet
= lpDropFileStruct
->fInNonClientArea
;
277 GlobalUnlock16(hDrop
);
281 /*************************************************************************
282 * SHELL_FindExecutable
283 * Utility for code sharing between FindExecutable and ShellExecute
285 static HINSTANCE32
SHELL_FindExecutable( LPCSTR lpFile
,
289 char *extension
= NULL
; /* pointer to file extension */
290 char tmpext
[5]; /* local copy to mung as we please */
291 char filetype
[256]; /* registry name for this filetype */
292 LONG filetypelen
=256; /* length of above */
293 char command
[256]; /* command from registry */
294 LONG commandlen
=256; /* This is the most DOS can handle :) */
295 char buffer
[256]; /* Used to GetProfileString */
296 HINSTANCE32 retval
=31; /* default - 'No association was found' */
297 char *tok
; /* token pointer */
298 int i
; /* random counter */
299 char xlpFile
[256]; /* result of SearchPath */
302 (lpFile
!= NULL
?lpFile
:"-") );
303 lpResult
[0]='\0'; /* Start off with an empty return string */
305 /* trap NULL parameters on entry */
306 if (( lpFile
== NULL
) || ( lpResult
== NULL
) || ( lpOperation
== NULL
))
308 /* FIXME - should throw a warning, perhaps! */
309 return 2; /* File not found. Close enough, I guess. */
312 if (SearchPath32A( NULL
, lpFile
,".exe",sizeof(xlpFile
),xlpFile
,NULL
))
315 /* First thing we need is the file's extension */
316 extension
= strrchr( xlpFile
, '.' ); /* Assume last "." is the one; */
317 /* File->Run in progman uses */
319 if ((extension
== NULL
) || (extension
== &xlpFile
[strlen(xlpFile
)]))
321 return 31; /* no association */
324 /* Make local copy & lowercase it for reg & 'programs=' lookup */
325 lstrcpyn32A( tmpext
, extension
, 5 );
326 CharLower32A( tmpext
);
327 TRACE(exec
, "%s file\n", tmpext
);
329 /* Three places to check: */
330 /* 1. win.ini, [windows], programs (NB no leading '.') */
331 /* 2. Registry, HKEY_CLASS_ROOT\<filetype>\shell\open\command */
332 /* 3. win.ini, [extensions], extension (NB no leading '.' */
333 /* All I know of the order is that registry is checked before */
334 /* extensions; however, it'd make sense to check the programs */
335 /* section first, so that's what happens here. */
337 /* See if it's a program - if GetProfileString fails, we skip this
338 * section. Actually, if GetProfileString fails, we've probably
339 * got a lot more to worry about than running a program... */
340 if ( GetProfileString32A("windows", "programs", "exe pif bat com",
341 buffer
, sizeof(buffer
)) > 0 )
343 for (i
=0;i
<strlen(buffer
); i
++) buffer
[i
]=tolower(buffer
[i
]);
345 tok
= strtok(buffer
, " \t"); /* ? */
348 if (strcmp(tok
, &tmpext
[1])==0) /* have to skip the leading "." */
350 strcpy(lpResult
, xlpFile
);
351 /* Need to perhaps check that the file has a path
353 TRACE(exec
, "found %s\n",
357 /* Greater than 32 to indicate success FIXME According to the
358 * docs, I should be returning a handle for the
359 * executable. Does this mean I'm supposed to open the
360 * executable file or something? More RTFM, I guess... */
362 tok
=strtok(NULL
, " \t");
367 if (RegQueryValue16( (HKEY
)HKEY_CLASSES_ROOT
, tmpext
, filetype
,
368 &filetypelen
) == SHELL_ERROR_SUCCESS
)
370 filetype
[filetypelen
]='\0';
371 TRACE(exec
, "File type: %s\n",
374 /* Looking for ...buffer\shell\lpOperation\command */
375 strcat( filetype
, "\\shell\\" );
376 strcat( filetype
, lpOperation
);
377 strcat( filetype
, "\\command" );
379 if (RegQueryValue16( (HKEY
)HKEY_CLASSES_ROOT
, filetype
, command
,
380 &commandlen
) == SHELL_ERROR_SUCCESS
)
382 /* Is there a replace() function anywhere? */
383 command
[commandlen
]='\0';
384 strcpy( lpResult
, command
);
385 tok
=strstr( lpResult
, "%1" );
388 tok
[0]='\0'; /* truncate string at the percent */
389 strcat( lpResult
, xlpFile
); /* what if no dir in xlpFile? */
390 tok
=strstr( command
, "%1" );
391 if ((tok
!=NULL
) && (strlen(tok
)>2))
393 strcat( lpResult
, &tok
[2] );
396 retval
=33; /* FIXME see above */
399 else /* Check win.ini */
401 /* Toss the leading dot */
403 if ( GetProfileString32A( "extensions", extension
, "", command
,
404 sizeof(command
)) > 0)
406 if (strlen(command
)!=0)
408 strcpy( lpResult
, command
);
409 tok
=strstr( lpResult
, "^" ); /* should be ^.extension? */
413 strcat( lpResult
, xlpFile
); /* what if no dir in xlpFile? */
414 tok
=strstr( command
, "^" ); /* see above */
415 if ((tok
!= NULL
) && (strlen(tok
)>5))
417 strcat( lpResult
, &tok
[5]);
420 retval
=33; /* FIXME - see above */
425 TRACE(exec
, "returning %s\n", lpResult
);
429 /*************************************************************************
430 * ShellExecute16 [SHELL.20]
432 HINSTANCE16 WINAPI
ShellExecute16( HWND16 hWnd
, LPCSTR lpOperation
,
433 LPCSTR lpFile
, LPCSTR lpParameters
,
434 LPCSTR lpDirectory
, INT16 iShowCmd
)
436 HINSTANCE16 retval
=31;
440 TRACE(exec
, "(%04x,'%s','%s','%s','%s',%x)\n",
441 hWnd
, lpOperation
? lpOperation
:"<null>", lpFile
? lpFile
:"<null>",
442 lpParameters
? lpParameters
: "<null>",
443 lpDirectory
? lpDirectory
: "<null>", iShowCmd
);
445 if (lpFile
==NULL
) return 0; /* should not happen */
446 if (lpOperation
==NULL
) /* default is open */
451 GetCurrentDirectory32A( sizeof(old_dir
), old_dir
);
452 SetCurrentDirectory32A( lpDirectory
);
455 retval
= SHELL_FindExecutable( lpFile
, lpOperation
, cmd
);
457 if (retval
> 32) /* Found */
462 strcat(cmd
,lpParameters
);
465 TRACE(exec
,"starting %s\n",cmd
);
466 retval
= WinExec32( cmd
, iShowCmd
);
468 if (lpDirectory
) SetCurrentDirectory32A( old_dir
);
473 /*************************************************************************
474 * ShellExecute32A (SHELL32.245)
476 HINSTANCE32 WINAPI
ShellExecute32A( HWND32 hWnd
, LPCSTR lpOperation
,
477 LPCSTR lpFile
, LPCSTR lpParameters
,
478 LPCSTR lpDirectory
, INT32 iShowCmd
)
480 return ShellExecute16( hWnd
, lpOperation
, lpFile
, lpParameters
,
481 lpDirectory
, iShowCmd
);
485 /*************************************************************************
486 * FindExecutable16 (SHELL.21)
488 HINSTANCE16 WINAPI
FindExecutable16( LPCSTR lpFile
, LPCSTR lpDirectory
,
491 return (HINSTANCE16
)FindExecutable32A( lpFile
, lpDirectory
, lpResult
);
494 /*************************************************************************
495 * FindExecutable32A (SHELL32.184)
497 HINSTANCE32 WINAPI
FindExecutable32A( LPCSTR lpFile
, LPCSTR lpDirectory
,
500 HINSTANCE32 retval
=31; /* default - 'No association was found' */
503 TRACE(exec
, "File %s, Dir %s\n",
504 (lpFile
!= NULL
?lpFile
:"-"),
505 (lpDirectory
!= NULL
?lpDirectory
:"-"));
507 lpResult
[0]='\0'; /* Start off with an empty return string */
509 /* trap NULL parameters on entry */
510 if (( lpFile
== NULL
) || ( lpResult
== NULL
))
512 /* FIXME - should throw a warning, perhaps! */
513 return 2; /* File not found. Close enough, I guess. */
518 GetCurrentDirectory32A( sizeof(old_dir
), old_dir
);
519 SetCurrentDirectory32A( lpDirectory
);
522 retval
= SHELL_FindExecutable( lpFile
, "open", lpResult
);
524 TRACE(exec
, "returning %s\n", lpResult
);
525 if (lpDirectory
) SetCurrentDirectory32A( old_dir
);
536 #define IDC_STATIC_TEXT 100
537 #define IDC_LISTBOX 99
538 #define IDC_WINE_TEXT 98
540 #define DROP_FIELD_TOP (-15)
541 #define DROP_FIELD_HEIGHT 15
543 extern HICON32 hIconTitleFont
;
545 static BOOL32
__get_dropline( HWND32 hWnd
, LPRECT32 lprect
)
547 HWND32 hWndCtl
= GetDlgItem32(hWnd
, IDC_WINE_TEXT
);
550 GetWindowRect32( hWndCtl
, lprect
);
551 MapWindowPoints32( 0, hWnd
, (LPPOINT32
)lprect
, 2 );
552 lprect
->bottom
= (lprect
->top
+= DROP_FIELD_TOP
);
558 /*************************************************************************
559 * AboutDlgProc32 (not an exported API function)
561 LRESULT WINAPI
AboutDlgProc32( HWND32 hWnd
, UINT32 msg
, WPARAM32 wParam
,
565 char Template
[512], AppTitle
[512];
571 ABOUT_INFO
*info
= (ABOUT_INFO
*)lParam
;
574 const char* const *pstr
= SHELL_People
;
575 SendDlgItemMessage32A(hWnd
, stc1
, STM_SETICON32
,info
->hIcon
, 0);
576 GetWindowText32A( hWnd
, Template
, sizeof(Template
) );
577 sprintf( AppTitle
, Template
, info
->szApp
);
578 SetWindowText32A( hWnd
, AppTitle
);
579 SetWindowText32A( GetDlgItem32(hWnd
, IDC_STATIC_TEXT
),
580 info
->szOtherStuff
);
581 hWndCtl
= GetDlgItem32(hWnd
, IDC_LISTBOX
);
582 SendMessage32A( hWndCtl
, WM_SETREDRAW
, 0, 0 );
583 SendMessage32A( hWndCtl
, WM_SETFONT
, hIconTitleFont
, 0 );
586 SendMessage32A( hWndCtl
, LB_ADDSTRING32
,
587 (WPARAM32
)-1, (LPARAM
)*pstr
);
590 SendMessage32A( hWndCtl
, WM_SETREDRAW
, 1, 0 );
599 HDC32 hDC
= BeginPaint32( hWnd
, &ps
);
601 if( __get_dropline( hWnd
, &rect
) )
602 GRAPH_DrawLines( hDC
, (LPPOINT32
)&rect
, 1, GetStockObject32( BLACK_PEN
) );
603 EndPaint32( hWnd
, &ps
);
607 case WM_LBTRACKPOINT
:
609 hWndCtl
= GetDlgItem32(hWnd
, IDC_LISTBOX
);
610 if( (INT16
)GetKeyState16( VK_CONTROL
) < 0 )
612 if( DragDetect32( hWndCtl
, *((LPPOINT32
)&lParam
) ) )
614 INT32 idx
= SendMessage32A( hWndCtl
, LB_GETCURSEL32
, 0, 0 );
617 INT32 length
= SendMessage32A( hWndCtl
, LB_GETTEXTLEN32
, (WPARAM32
)idx
, 0 );
618 HGLOBAL16 hMemObj
= GlobalAlloc16( GMEM_MOVEABLE
, length
+ 1 );
619 char* pstr
= (char*)GlobalLock16( hMemObj
);
623 HCURSOR16 hCursor
= LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT
) );
624 SendMessage32A( hWndCtl
, LB_GETTEXT32
, (WPARAM32
)idx
, (LPARAM
)pstr
);
625 SendMessage32A( hWndCtl
, LB_DELETESTRING32
, (WPARAM32
)idx
, 0 );
626 UpdateWindow32( hWndCtl
);
627 if( !DragObject16((HWND16
)hWnd
, (HWND16
)hWnd
, DRAGOBJ_DATA
, 0, (WORD
)hMemObj
, hCursor
) )
628 SendMessage32A( hWndCtl
, LB_ADDSTRING32
, (WPARAM32
)-1, (LPARAM
)pstr
);
630 if( hMemObj
) GlobalFree16( hMemObj
);
636 case WM_QUERYDROPOBJECT
:
639 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
640 if( lpDragInfo
&& lpDragInfo
->wFlags
== DRAGOBJ_DATA
)
643 if( __get_dropline( hWnd
, &rect
) )
645 POINT32 pt
= { lpDragInfo
->pt
.x
, lpDragInfo
->pt
.y
};
646 rect
.bottom
+= DROP_FIELD_HEIGHT
;
647 if( PtInRect32( &rect
, pt
) )
649 SetWindowLong32A( hWnd
, DWL_MSGRESULT
, 1 );
660 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
661 if( lpDragInfo
&& lpDragInfo
->wFlags
== DRAGOBJ_DATA
&& lpDragInfo
->hList
)
663 char* pstr
= (char*)GlobalLock16( (HGLOBAL16
)(lpDragInfo
->hList
) );
666 static char __appendix_str
[] = " with";
668 hWndCtl
= GetDlgItem32( hWnd
, IDC_WINE_TEXT
);
669 SendMessage32A( hWndCtl
, WM_GETTEXT
, 512, (LPARAM
)Template
);
670 if( !lstrncmp32A( Template
, "WINE", 4 ) )
671 SetWindowText32A( GetDlgItem32(hWnd
, IDC_STATIC_TEXT
), Template
);
674 char* pch
= Template
+ strlen(Template
) - strlen(__appendix_str
);
676 SendMessage32A( GetDlgItem32(hWnd
, IDC_LISTBOX
), LB_ADDSTRING32
,
677 (WPARAM32
)-1, (LPARAM
)Template
);
680 lstrcpy32A( Template
, pstr
);
681 lstrcat32A( Template
, __appendix_str
);
682 SetWindowText32A( hWndCtl
, Template
);
684 SetWindowLong32A( hWnd
, DWL_MSGRESULT
, 1 );
694 EndDialog32(hWnd
, TRUE
);
703 /*************************************************************************
704 * AboutDlgProc16 (SHELL.33)
706 LRESULT WINAPI
AboutDlgProc16( HWND16 hWnd
, UINT16 msg
, WPARAM16 wParam
,
709 return AboutDlgProc32( hWnd
, msg
, wParam
, lParam
);
713 /*************************************************************************
714 * ShellAbout16 (SHELL.22)
716 BOOL16 WINAPI
ShellAbout16( HWND16 hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
,
719 return ShellAbout32A( hWnd
, szApp
, szOtherStuff
, hIcon
);
722 /*************************************************************************
723 * ShellAbout32A (SHELL32.243)
725 BOOL32 WINAPI
ShellAbout32A( HWND32 hWnd
, LPCSTR szApp
, LPCSTR szOtherStuff
,
730 info
.szOtherStuff
= szOtherStuff
;
732 if (!hIcon
) info
.hIcon
= LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON
) );
733 return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd
),
734 SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX
),
735 hWnd
, AboutDlgProc32
, (LPARAM
)&info
);
739 /*************************************************************************
740 * ShellAbout32W (SHELL32.244)
742 BOOL32 WINAPI
ShellAbout32W( HWND32 hWnd
, LPCWSTR szApp
, LPCWSTR szOtherStuff
,
748 info
.szApp
= HEAP_strdupWtoA( GetProcessHeap(), 0, szApp
);
749 info
.szOtherStuff
= HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff
);
751 if (!hIcon
) info
.hIcon
= LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON
) );
752 ret
= DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd
),
753 SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX
),
754 hWnd
, AboutDlgProc32
, (LPARAM
)&info
);
755 HeapFree( GetProcessHeap(), 0, (LPSTR
)info
.szApp
);
756 HeapFree( GetProcessHeap(), 0, (LPSTR
)info
.szOtherStuff
);
760 /*************************************************************************
761 * Shell_NotifyIcon [SHELL32.249]
763 * This function is supposed to deal with the systray.
764 * Any ideas on how this is to be implimented?
766 BOOL32 WINAPI
Shell_NotifyIcon( DWORD dwMessage
,
767 PNOTIFYICONDATA pnid
)
772 /*************************************************************************
773 * Shell_NotifyIcon [SHELL32.240]
775 * This function is supposed to deal with the systray.
776 * Any ideas on how this is to be implimented?
778 BOOL32 WINAPI
Shell_NotifyIconA(DWORD dwMessage
,
779 PNOTIFYICONDATA pnid
)
784 /*************************************************************************
785 * SHELL_GetResourceTable
787 static DWORD
SHELL_GetResourceTable(HFILE32 hFile
,LPBYTE
*retptr
)
789 IMAGE_DOS_HEADER mz_header
;
794 _llseek32( hFile
, 0, SEEK_SET
);
795 if ( (_lread32(hFile
,&mz_header
,sizeof(mz_header
)) != sizeof(mz_header
)) ||
796 (mz_header
.e_magic
!= IMAGE_DOS_SIGNATURE
)
797 ) { /* .ICO file ? */
798 if (mz_header
.e_cblp
== 1) { /* ICONHEADER.idType, must be 1 */
799 *retptr
= (LPBYTE
)-1;
803 return 0; /* failed */
805 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
806 if (_lread32( hFile
, magic
, sizeof(magic
) ) != sizeof(magic
))
808 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
810 if (*(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
811 return IMAGE_NT_SIGNATURE
;
812 if (*(WORD
*)magic
== IMAGE_OS2_SIGNATURE
) {
813 IMAGE_OS2_HEADER ne_header
;
814 LPBYTE pTypeInfo
= (LPBYTE
)-1;
816 if (_lread32(hFile
,&ne_header
,sizeof(ne_header
))!=sizeof(ne_header
))
819 if (ne_header
.ne_magic
!= IMAGE_OS2_SIGNATURE
) return 0;
820 size
= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
821 if( size
> sizeof(NE_TYPEINFO
) )
823 pTypeInfo
= (BYTE
*)HeapAlloc( GetProcessHeap(), 0, size
);
825 _llseek32(hFile
, mz_header
.e_lfanew
+ne_header
.resource_tab_offset
, SEEK_SET
);
826 if( _lread32( hFile
, (char*)pTypeInfo
, size
) != size
) {
827 HeapFree( GetProcessHeap(), 0, pTypeInfo
);
833 return IMAGE_OS2_SIGNATURE
;
835 return 0; /* failed */
838 /*************************************************************************
841 static HGLOBAL16
SHELL_LoadResource(HINSTANCE16 hInst
, HFILE32 hFile
, NE_NAMEINFO
* pNInfo
, WORD sizeShift
)
844 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, (DWORD
)pNInfo
->length
<< sizeShift
);
846 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
848 _llseek32( hFile
, (DWORD
)pNInfo
->offset
<< sizeShift
, SEEK_SET
);
849 _lread32( hFile
, (char*)ptr
, pNInfo
->length
<< sizeShift
);
855 /*************************************************************************
858 static HGLOBAL16
ICO_LoadIcon(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIRENTRY lpiIDE
)
861 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, lpiIDE
->dwBytesInRes
);
863 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
865 _llseek32( hFile
, lpiIDE
->dwImageOffset
, SEEK_SET
);
866 _lread32( hFile
, (char*)ptr
, lpiIDE
->dwBytesInRes
);
872 /*************************************************************************
873 * ICO_GetIconDirectory
875 * Read .ico file and build phony ICONDIR struct for GetIconID
877 static HGLOBAL16
ICO_GetIconDirectory(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIR
* lplpiID
)
879 WORD id
[3]; /* idReserved, idType, idCount */
883 _llseek32( hFile
, 0, SEEK_SET
);
884 if( _lread32(hFile
,(char*)id
,sizeof(id
)) != sizeof(id
) ) return 0;
888 * - see http://www.microsoft.com/win32dev/ui/icons.htm
891 if( id
[0] || id
[1] != 1 || !id
[2] ) return 0;
893 i
= id
[2]*sizeof(icoICONDIRENTRY
) + sizeof(id
);
895 lpiID
= (LPicoICONDIR
)HeapAlloc( GetProcessHeap(), 0, i
);
897 if( _lread32(hFile
,(char*)lpiID
->idEntries
,i
) == i
)
899 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10,
900 id
[2]*sizeof(ICONDIRENTRY
) + sizeof(id
) );
903 CURSORICONDIR
* lpID
= (CURSORICONDIR
*)GlobalLock16( handle
);
904 lpID
->idReserved
= lpiID
->idReserved
= id
[0];
905 lpID
->idType
= lpiID
->idType
= id
[1];
906 lpID
->idCount
= lpiID
->idCount
= id
[2];
907 for( i
=0; i
< lpiID
->idCount
; i
++ )
909 memcpy((void*)(lpID
->idEntries
+ i
),
910 (void*)(lpiID
->idEntries
+ i
), sizeof(ICONDIRENTRY
) - 2);
911 lpID
->idEntries
[i
].icon
.wResId
= i
;
919 HeapFree( GetProcessHeap(), 0, lpiID
);
923 /*************************************************************************
924 * InternalExtractIcon [SHELL.39]
926 * This abortion is called directly by Progman
928 HGLOBAL16 WINAPI
InternalExtractIcon(HINSTANCE16 hInstance
,
929 LPCSTR lpszExeFileName
, UINT16 nIconIndex
,
933 HGLOBAL16
* RetPtr
= NULL
;
937 HFILE32 hFile
= OpenFile32( lpszExeFileName
, &ofs
, OF_READ
);
938 UINT16 iconDirCount
= 0,iconCount
= 0;
940 TRACE(reg
,"(%04x,file %s,start %d,extract %d\n",
941 hInstance
, lpszExeFileName
, nIconIndex
, n
);
943 if( hFile
== HFILE_ERROR32
|| !n
) return 0;
945 hRet
= GlobalAlloc16( GMEM_FIXED
| GMEM_ZEROINIT
, sizeof(HICON16
)*n
);
946 RetPtr
= (HICON16
*)GlobalLock16(hRet
);
948 *RetPtr
= (n
== 0xFFFF)? 0: 1; /* error return values */
950 sig
= SHELL_GetResourceTable(hFile
,&pData
);
952 if((sig
== IMAGE_OS2_SIGNATURE
)
953 || (sig
== 1)) /* .ICO file */
956 NE_TYPEINFO
* pTInfo
= (NE_TYPEINFO
*)(pData
+ 2);
957 NE_NAMEINFO
* pIconStorage
= NULL
;
958 NE_NAMEINFO
* pIconDir
= NULL
;
959 LPicoICONDIR lpiID
= NULL
;
961 if( pData
== (BYTE
*)-1 )
963 /* check for .ICO file */
965 hIcon
= ICO_GetIconDirectory(hInstance
, hFile
, &lpiID
);
966 if( hIcon
) { iconDirCount
= 1; iconCount
= lpiID
->idCount
; }
968 else while( pTInfo
->type_id
&& !(pIconStorage
&& pIconDir
) )
970 /* find icon directory and icon repository */
972 if( pTInfo
->type_id
== NE_RSCTYPE_GROUP_ICON
)
974 iconDirCount
= pTInfo
->count
;
975 pIconDir
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
976 TRACE(reg
,"\tfound directory - %i icon families\n", iconDirCount
);
978 if( pTInfo
->type_id
== NE_RSCTYPE_ICON
)
980 iconCount
= pTInfo
->count
;
981 pIconStorage
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
982 TRACE(reg
,"\ttotal icons - %i\n", iconCount
);
984 pTInfo
= (NE_TYPEINFO
*)((char*)(pTInfo
+1)+pTInfo
->count
*sizeof(NE_NAMEINFO
));
987 /* load resources and create icons */
989 if( (pIconStorage
&& pIconDir
) || lpiID
)
990 if( nIconIndex
== (UINT16
)-1 ) RetPtr
[0] = iconDirCount
;
991 else if( nIconIndex
< iconDirCount
)
995 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
997 for( i
= nIconIndex
; i
< nIconIndex
+ n
; i
++ )
999 /* .ICO files have only one icon directory */
1002 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconDir
+ i
,
1004 RetPtr
[i
-nIconIndex
] = GetIconID( hIcon
, 3 );
1005 GlobalFree16(hIcon
);
1008 for( icon
= nIconIndex
; icon
< nIconIndex
+ n
; icon
++ )
1012 hIcon
= ICO_LoadIcon( hInstance
, hFile
,
1013 lpiID
->idEntries
+ RetPtr
[icon
-nIconIndex
]);
1015 for( i
= 0; i
< iconCount
; i
++ )
1016 if( pIconStorage
[i
].id
== (RetPtr
[icon
-nIconIndex
] | 0x8000) )
1017 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconStorage
+ i
,
1021 RetPtr
[icon
-nIconIndex
] = LoadIconHandler( hIcon
, TRUE
);
1022 FarSetOwner( RetPtr
[icon
-nIconIndex
], GetExePtr(hInstance
) );
1025 RetPtr
[icon
-nIconIndex
] = 0;
1028 if( lpiID
) HeapFree( GetProcessHeap(), 0, lpiID
);
1029 else HeapFree( GetProcessHeap(), 0, pData
);
1031 if( sig
== IMAGE_NT_SIGNATURE
)
1033 LPBYTE peimage
,idata
,igdata
;
1034 LPIMAGE_DOS_HEADER dheader
;
1035 LPIMAGE_NT_HEADERS pe_header
;
1036 LPIMAGE_SECTION_HEADER pe_sections
;
1037 LPIMAGE_RESOURCE_DIRECTORY rootresdir
,iconresdir
,icongroupresdir
;
1038 LPIMAGE_RESOURCE_DATA_ENTRY idataent
,igdataent
;
1041 LPIMAGE_RESOURCE_DIRECTORY_ENTRY xresent
;
1042 CURSORICONDIR
**cids
;
1044 fmapping
= CreateFileMapping32A(hFile
,NULL
,PAGE_READONLY
|SEC_COMMIT
,0,0,NULL
);
1045 if (fmapping
== 0) { /* FIXME, INVALID_HANDLE_VALUE? */
1046 WARN(reg
,"failed to create filemap.\n");
1050 peimage
= MapViewOfFile(fmapping
,FILE_MAP_READ
,0,0,0);
1052 WARN(reg
,"failed to mmap filemap.\n");
1053 CloseHandle(fmapping
);
1057 dheader
= (LPIMAGE_DOS_HEADER
)peimage
;
1058 /* it is a pe header, SHELL_GetResourceTable checked that */
1059 pe_header
= (LPIMAGE_NT_HEADERS
)(peimage
+dheader
->e_lfanew
);
1060 /* probably makes problems with short PE headers... but I haven't seen
1063 pe_sections
= (LPIMAGE_SECTION_HEADER
)(((char*)pe_header
)+sizeof(*pe_header
));
1065 for (i
=0;i
<pe_header
->FileHeader
.NumberOfSections
;i
++) {
1066 if (pe_sections
[i
].Characteristics
& IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
1068 /* FIXME: doesn't work when the resources are not in a seperate section */
1069 if (pe_sections
[i
].VirtualAddress
== pe_header
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
].VirtualAddress
) {
1070 rootresdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((char*)peimage
+pe_sections
[i
].PointerToRawData
);
1076 WARN(reg
,"haven't found section for resource directory.\n");
1077 UnmapViewOfFile(peimage
);
1078 CloseHandle(fmapping
);
1082 icongroupresdir
= GetResDirEntryW(rootresdir
,RT_GROUP_ICON32W
,
1083 (DWORD
)rootresdir
,FALSE
);
1084 if (!icongroupresdir
) {
1085 WARN(reg
,"No Icongroupresourcedirectory!\n");
1086 UnmapViewOfFile(peimage
);
1087 CloseHandle(fmapping
);
1092 iconDirCount
= icongroupresdir
->NumberOfNamedEntries
+icongroupresdir
->NumberOfIdEntries
;
1093 if( nIconIndex
== (UINT16
)-1 ) {
1094 RetPtr
[0] = iconDirCount
;
1095 UnmapViewOfFile(peimage
);
1096 CloseHandle(fmapping
);
1101 if (nIconIndex
>= iconDirCount
) {
1102 WARN(reg
,"nIconIndex %d is larger than iconDirCount %d\n",
1103 nIconIndex
,iconDirCount
);
1104 UnmapViewOfFile(peimage
);
1105 CloseHandle(fmapping
);
1110 cids
= (CURSORICONDIR
**)HeapAlloc(GetProcessHeap(),0,n
*sizeof(CURSORICONDIR
*));
1112 /* caller just wanted the number of entries */
1114 xresent
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)(icongroupresdir
+1);
1115 /* assure we don't get too much ... */
1116 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
1118 /* starting from specified index ... */
1119 xresent
= xresent
+nIconIndex
;
1121 for (i
=0;i
<n
;i
++,xresent
++) {
1123 LPIMAGE_RESOURCE_DIRECTORY resdir
;
1125 /* go down this resource entry, name */
1126 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((DWORD
)rootresdir
+(xresent
->u2
.s
.OffsetToDirectory
));
1127 /* default language (0) */
1128 resdir
= GetResDirEntryW(resdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1129 igdataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)resdir
;
1131 /* lookup address in mapped image for virtual address */
1133 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1134 if (igdataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1136 if (igdataent
->OffsetToData
+igdataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1138 igdata
= peimage
+(igdataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1141 WARN(reg
,"no matching real address for icongroup!\n");
1142 UnmapViewOfFile(peimage
);
1143 CloseHandle(fmapping
);
1148 cid
= (CURSORICONDIR
*)igdata
;
1150 RetPtr
[i
] = LookupIconIdFromDirectoryEx32(igdata
,TRUE
,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1152 iconresdir
=GetResDirEntryW(rootresdir
,RT_ICON32W
,
1153 (DWORD
)rootresdir
,FALSE
);
1155 WARN(reg
,"No Iconresourcedirectory!\n");
1156 UnmapViewOfFile(peimage
);
1157 CloseHandle(fmapping
);
1162 LPIMAGE_RESOURCE_DIRECTORY xresdir
;
1164 xresdir
= GetResDirEntryW(iconresdir
,(LPWSTR
)RetPtr
[i
],(DWORD
)rootresdir
,FALSE
);
1165 xresdir
= GetResDirEntryW(xresdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1167 idataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)xresdir
;
1170 /* map virtual to address in image */
1171 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1172 if (idataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1174 if (idataent
->OffsetToData
+idataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1176 idata
= peimage
+(idataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1179 WARN(reg
,"no matching real address found for icondata!\n");
1183 RetPtr
[i
] = CreateIconFromResourceEx32(idata
,idataent
->Size
,TRUE
,0x00030000,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1185 UnmapViewOfFile(peimage
);
1186 CloseHandle(fmapping
);
1191 /* return array with icon handles */
1196 /*************************************************************************
1197 * ExtractIcon16 (SHELL.34)
1199 HICON16 WINAPI
ExtractIcon16( HINSTANCE16 hInstance
, LPCSTR lpszExeFileName
,
1202 return ExtractIcon32A( hInstance
, lpszExeFileName
, nIconIndex
);
1206 /*************************************************************************
1207 * ExtractIcon32A (SHELL32.133)
1209 HICON32 WINAPI
ExtractIcon32A( HINSTANCE32 hInstance
, LPCSTR lpszExeFileName
,
1212 HGLOBAL16 handle
= InternalExtractIcon(hInstance
,lpszExeFileName
,nIconIndex
, 1);
1216 HICON16
* ptr
= (HICON16
*)GlobalLock16(handle
);
1217 HICON16 hIcon
= *ptr
;
1219 GlobalFree16(handle
);
1225 /*************************************************************************
1226 * ExtractIcon32W (SHELL32.180)
1228 HICON32 WINAPI
ExtractIcon32W( HINSTANCE32 hInstance
, LPCWSTR lpszExeFileName
,
1231 LPSTR exefn
= HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName
);
1232 HICON32 ret
= ExtractIcon32A(hInstance
,exefn
,nIconIndex
);
1234 HeapFree(GetProcessHeap(),0,exefn
);
1239 /*************************************************************************
1240 * ExtractAssociatedIcon [SHELL.36]
1242 * Return icon for given file (either from file itself or from associated
1243 * executable) and patch parameters if needed.
1245 HICON32 WINAPI
ExtractAssociatedIcon32A(HINSTANCE32 hInst
,LPSTR lpIconPath
,
1248 return ExtractAssociatedIcon16(hInst
,lpIconPath
,lpiIcon
);
1251 HICON16 WINAPI
ExtractAssociatedIcon16(HINSTANCE16 hInst
,LPSTR lpIconPath
,
1254 HICON16 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1259 if( hIcon
== 1 ) /* no icons found in given file */
1261 char tempPath
[0x80];
1262 UINT16 uRet
= FindExecutable16(lpIconPath
,NULL
,tempPath
);
1264 if( uRet
> 32 && tempPath
[0] )
1266 strcpy(lpIconPath
,tempPath
);
1267 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1269 if( hIcon
> 2 ) return hIcon
;
1275 *lpiIcon
= 2; /* MSDOS icon - we found .exe but no icons in it */
1277 *lpiIcon
= 6; /* generic icon - found nothing */
1279 GetModuleFileName16(hInst
, lpIconPath
, 0x80);
1280 hIcon
= LoadIcon16( hInst
, MAKEINTRESOURCE16(*lpiIcon
));
1286 /*************************************************************************
1287 * FindEnvironmentString [SHELL.38]
1289 * Returns a pointer into the DOS environment... Ugh.
1291 LPSTR
SHELL_FindString(LPSTR lpEnv
, LPCSTR entry
)
1293 UINT16 l
= strlen(entry
);
1294 for( ; *lpEnv
; lpEnv
+=strlen(lpEnv
)+1 )
1296 if( lstrncmpi32A(lpEnv
, entry
, l
) ) continue;
1299 return (lpEnv
+ l
); /* empty entry */
1300 else if ( *(lpEnv
+l
)== '=' )
1301 return (lpEnv
+ l
+ 1);
1306 SEGPTR WINAPI
FindEnvironmentString(LPSTR str
)
1308 SEGPTR spEnv
= GetDOSEnvironment();
1309 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(spEnv
);
1311 LPSTR lpString
= (spEnv
)?SHELL_FindString(lpEnv
, str
):NULL
;
1313 if( lpString
) /* offset should be small enough */
1314 return spEnv
+ (lpString
- lpEnv
);
1316 return (SEGPTR
)NULL
;
1319 /*************************************************************************
1320 * DoEnvironmentSubst [SHELL.37]
1322 * Replace %KEYWORD% in the str with the value of variable KEYWORD
1323 * from "DOS" environment.
1325 DWORD WINAPI
DoEnvironmentSubst(LPSTR str
,WORD length
)
1327 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(GetDOSEnvironment());
1328 LPSTR lpBuffer
= (LPSTR
)HeapAlloc( GetProcessHeap(), 0, length
);
1330 LPSTR lpbstr
= lpBuffer
;
1332 CharToOem32A(str
,str
);
1334 TRACE(reg
,"accept %s\n", str
);
1336 while( *lpstr
&& lpbstr
- lpBuffer
< length
)
1338 LPSTR lpend
= lpstr
;
1342 do { lpend
++; } while( *lpend
&& *lpend
!= '%' );
1343 if( *lpend
== '%' && lpend
- lpstr
> 1 ) /* found key */
1347 lpKey
= SHELL_FindString(lpEnv
, lpstr
+1);
1348 if( lpKey
) /* found key value */
1350 int l
= strlen(lpKey
);
1352 if( l
> length
- (lpbstr
- lpBuffer
) - 1 )
1354 WARN(reg
,"Env subst aborted - string too short\n");
1358 strcpy(lpbstr
, lpKey
);
1365 else break; /* back off and whine */
1370 *lpbstr
++ = *lpstr
++;
1374 if( lpstr
- str
== strlen(str
) )
1376 strncpy(str
, lpBuffer
, length
);
1382 TRACE(reg
," return %s\n", str
);
1384 OemToChar32A(str
,str
);
1385 HeapFree( GetProcessHeap(), 0, lpBuffer
);
1387 /* Return str length in the LOWORD
1388 * and 1 in HIWORD if subst was successful.
1390 return (DWORD
)MAKELONG(strlen(str
), length
);
1393 /*************************************************************************
1394 * ShellHookProc [SHELL.103]
1395 * System-wide WH_SHELL hook.
1397 LRESULT WINAPI
ShellHookProc(INT16 code
, WPARAM16 wParam
, LPARAM lParam
)
1399 TRACE(reg
,"%i, %04x, %08x\n", code
, wParam
,
1401 if( SHELL_hHook
&& SHELL_hWnd
)
1406 case HSHELL_WINDOWCREATED
: uMsg
= uMsgWndCreated
; break;
1407 case HSHELL_WINDOWDESTROYED
: uMsg
= uMsgWndDestroyed
; break;
1408 case HSHELL_ACTIVATESHELLWINDOW
: uMsg
= uMsgShellActivate
;
1410 PostMessage16( SHELL_hWnd
, uMsg
, wParam
, 0 );
1412 return CallNextHookEx16( WH_SHELL
, code
, wParam
, 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 FIXME(shell
,"(%s,0x%08lx,%p,%d,0x%08x): stub\n",
1464 path
,dwFileAttributes
,psfi
,sizeofpsfi
,flags
);
1468 /*************************************************************************
1469 * SHAppBarMessage32 [SHELL32.207]
1471 UINT32 WINAPI
SHAppBarMessage32(DWORD msg
, PAPPBARDATA data
)
1473 FIXME(shell
,"(0x%08lx,%p): stub\n", msg
, data
);
1477 case ABM_GETAUTOHIDEBAR
:
1479 case ABM_GETTASKBARPOS
:
1483 case ABM_SETAUTOHIDEBAR
:
1485 case ABM_WINDOWPOSCHANGED
:
1492 /*************************************************************************
1493 * CommandLineToArgvW [SHELL32.7]
1495 LPWSTR
* WINAPI
CommandLineToArgvW(LPWSTR cmdline
,LPDWORD numargs
)
1500 /* to get writeable copy */
1501 cmdline
= HEAP_strdupW( GetProcessHeap(), 0, cmdline
);
1508 while (*s
&& *s
==0x0020)
1514 argv
=(LPWSTR
*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR
)*(i
+1) );
1520 argv
[i
++]=HEAP_strdupW( GetProcessHeap(), 0, t
);
1522 while (*s
&& *s
==0x0020)
1533 argv
[i
++]=(LPWSTR
)HEAP_strdupW( GetProcessHeap(), 0, t
);
1534 HeapFree( GetProcessHeap(), 0, cmdline
);
1540 /*************************************************************************
1541 * Control_RunDLL [SHELL32.12]
1543 * Wild speculation in the following!
1545 * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
1548 void WINAPI
Control_RunDLL (HWND32 hwnd
, LPCVOID code
, LPCSTR cmd
, DWORD arg4
)
1550 TRACE(exec
, "(%08x, %p, \"%s\", %08lx)\n",
1551 hwnd
, code
? code
: "(null)", cmd
? cmd
: "(null)", arg4
);
1554 /*************************************************************************
1557 void WINAPI
FreeIconList( DWORD dw
)
1559 FIXME(reg
, "empty stub\n" );
1562 /*************************************************************************
1563 * SHELL32_DllGetClassObject [SHELL32.14]
1565 * http://premium.microsoft.com/msdn/library/sdkdoc/api2_48fo.htm
1567 DWORD WINAPI
SHELL32_DllGetClassObject(REFCLSID rclsid
,REFIID iid
,LPVOID
*ppv
)
1569 char xclsid
[50],xiid
[50];
1570 HRESULT hres
= E_OUTOFMEMORY
;
1573 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
1574 WINE_StringFromCLSID((LPCLSID
)iid
,xiid
);
1575 TRACE(shell
,"(%s,%s,%p)\n",xclsid
,xiid
,ppv
);
1578 /* SDK example code looks like this:
1580 HRESULT hres = E_OUTOFMEMORY;
1583 CClassFactory *pClassFactory = new CClassFactory(rclsid);
1585 if (pClassFactory) {
1586 hRes = pClassFactory->QueryInterface(riid,ppv);
1587 pClassFactory->Release();
1591 * The magic of the whole stuff is still unclear to me, so just hack together
1595 if (!memcmp(rclsid
,&CLSID_ShellDesktop
,sizeof(CLSID_ShellDesktop
))) {
1596 TRACE(shell
," requested CLSID_ShellDesktop, creating it.\n");
1597 *ppv
= IShellFolder_Constructor();
1598 FIXME(shell
,"Initialize this folder to be the shell desktop folder\n");
1602 FIXME(shell
, " -> clsid not found. returning E_OUTOFMEMORY.\n");
1606 /*************************************************************************
1607 * SHGetDesktopFolder [SHELL32.216]
1608 * returns the interface to the shell desktop folder.
1610 * [SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
1611 * CLSID_ShellDesktop.
1613 * CoCreateInstance(CLSID_Desktop, NULL,
1614 * CLSCTX_INPROC, IID_IShellFolder, &pshf);
1616 * So what we are doing is currently wrong....
1618 DWORD WINAPI
SHGetDesktopFolder(LPSHELLFOLDER
*shellfolder
) {
1619 *shellfolder
= IShellFolder_Constructor();
1623 /*************************************************************************
1624 * SHGetMalloc [SHELL32.220]
1625 * returns the interface to shell malloc.
1627 * [SDK header win95/shlobj.h:
1628 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
1630 * What we are currently doing is not very wrong, since we always use the same
1631 * heap (ProcessHeap).
1633 DWORD WINAPI
SHGetMalloc(LPMALLOC32
*lpmal
) {
1634 TRACE(shell
,"(%p)\n", lpmal
);
1635 return CoGetMalloc32(0,lpmal
);
1638 /*************************************************************************
1639 * SHGetSpecialFolderLocation [SHELL32.223]
1640 * returns the PIDL of a special folder
1642 * nFolder is a CSIDL_xxxxx.
1644 HRESULT WINAPI
SHGetSpecialFolderLocation(HWND32 hwndOwner
, INT32 nFolder
, LPITEMIDLIST
* ppidl
) {
1645 FIXME(shell
,"(%04x,%d,%p),stub!\n", hwndOwner
,nFolder
,ppidl
);
1646 *ppidl
= (LPITEMIDLIST
)HeapAlloc(GetProcessHeap(),0,2*sizeof(ITEMIDLIST
));
1647 FIXME(shell
, "we return only the empty ITEMIDLIST currently.\n");
1648 (*ppidl
)->mkid
.cb
= 0;
1652 /*************************************************************************
1653 * SHGetPathFromIDList [SHELL32.221]
1654 * returns the path from a passed PIDL.
1656 BOOL32 WINAPI
SHGetPathFromIDList(LPCITEMIDLIST pidl
,LPSTR pszPath
) {
1657 FIXME(shell
,"(%p,%p),stub!\n",pidl
,pszPath
);
1658 lstrcpy32A(pszPath
,"E:\\"); /* FIXME */