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, MAKEINTRESOURCE(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, MAKEINTRESOURCE(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, MAKEINTRESOURCE(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
)
800 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
801 if (_lread32( hFile
, magic
, sizeof(magic
) ) != sizeof(magic
))
803 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
805 if (*(DWORD
*)magic
== IMAGE_NT_SIGNATURE
)
806 return IMAGE_NT_SIGNATURE
;
807 if (*(WORD
*)magic
== IMAGE_OS2_SIGNATURE
) {
808 IMAGE_OS2_HEADER ne_header
;
809 LPBYTE pTypeInfo
= (LPBYTE
)-1;
811 if (_lread32(hFile
,&ne_header
,sizeof(ne_header
))!=sizeof(ne_header
))
814 if (ne_header
.ne_magic
!= IMAGE_OS2_SIGNATURE
) return 0;
815 size
= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
816 if( size
> sizeof(NE_TYPEINFO
) )
818 pTypeInfo
= (BYTE
*)HeapAlloc( GetProcessHeap(), 0, size
);
820 _llseek32(hFile
, mz_header
.e_lfanew
+ne_header
.resource_tab_offset
, SEEK_SET
);
821 if( _lread32( hFile
, (char*)pTypeInfo
, size
) != size
) {
822 HeapFree( GetProcessHeap(), 0, pTypeInfo
);
829 *retptr
= (LPBYTE
)-1;
830 return IMAGE_OS2_SIGNATURE
; /* handles .ICO too */
834 /*************************************************************************
837 static HGLOBAL16
SHELL_LoadResource(HINSTANCE16 hInst
, HFILE32 hFile
, NE_NAMEINFO
* pNInfo
, WORD sizeShift
)
840 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, (DWORD
)pNInfo
->length
<< sizeShift
);
842 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
844 _llseek32( hFile
, (DWORD
)pNInfo
->offset
<< sizeShift
, SEEK_SET
);
845 _lread32( hFile
, (char*)ptr
, pNInfo
->length
<< sizeShift
);
851 /*************************************************************************
854 static HGLOBAL16
ICO_LoadIcon(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIRENTRY lpiIDE
)
857 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10, lpiIDE
->dwBytesInRes
);
859 if( (ptr
= (BYTE
*)GlobalLock16( handle
)) )
861 _llseek32( hFile
, lpiIDE
->dwImageOffset
, SEEK_SET
);
862 _lread32( hFile
, (char*)ptr
, lpiIDE
->dwBytesInRes
);
868 /*************************************************************************
869 * ICO_GetIconDirectory
871 * Read .ico file and build phony ICONDIR struct for GetIconID
873 static HGLOBAL16
ICO_GetIconDirectory(HINSTANCE16 hInst
, HFILE32 hFile
, LPicoICONDIR
* lplpiID
)
875 WORD id
[3]; /* idReserved, idType, idCount */
879 _llseek32( hFile
, 0, SEEK_SET
);
880 if( _lread32(hFile
,(char*)id
,sizeof(id
)) != sizeof(id
) ) return 0;
884 * - see http://www.microsoft.com/win32dev/ui/icons.htm
887 if( id
[0] || id
[1] != 1 || !id
[2] ) return 0;
889 i
= id
[2]*sizeof(icoICONDIRENTRY
) + sizeof(id
);
891 lpiID
= (LPicoICONDIR
)HeapAlloc( GetProcessHeap(), 0, i
);
893 if( _lread32(hFile
,(char*)lpiID
->idEntries
,i
) == i
)
895 HGLOBAL16 handle
= DirectResAlloc( hInst
, 0x10,
896 id
[2]*sizeof(ICONDIRENTRY
) + sizeof(id
) );
899 CURSORICONDIR
* lpID
= (CURSORICONDIR
*)GlobalLock16( handle
);
900 lpID
->idReserved
= lpiID
->idReserved
= id
[0];
901 lpID
->idType
= lpiID
->idType
= id
[1];
902 lpID
->idCount
= lpiID
->idCount
= id
[2];
903 for( i
=0; i
< lpiID
->idCount
; i
++ )
905 memcpy((void*)(lpID
->idEntries
+ i
),
906 (void*)(lpiID
->idEntries
+ i
), sizeof(ICONDIRENTRY
) - 2);
907 lpID
->idEntries
[i
].icon
.wResId
= i
;
915 HeapFree( GetProcessHeap(), 0, lpiID
);
919 /*************************************************************************
920 * InternalExtractIcon [SHELL.39]
922 * This abortion is called directly by Progman
924 HGLOBAL16 WINAPI
InternalExtractIcon(HINSTANCE16 hInstance
,
925 LPCSTR lpszExeFileName
, UINT16 nIconIndex
,
929 HGLOBAL16
* RetPtr
= NULL
;
933 HFILE32 hFile
= OpenFile32( lpszExeFileName
, &ofs
, OF_READ
);
934 UINT16 iconDirCount
= 0,iconCount
= 0;
936 TRACE(reg
,"(%04x,file %s,start %d,extract %d\n",
937 hInstance
, lpszExeFileName
, nIconIndex
, n
);
939 if( hFile
== HFILE_ERROR32
|| !n
) return 0;
941 hRet
= GlobalAlloc16( GMEM_FIXED
| GMEM_ZEROINIT
, sizeof(HICON16
)*n
);
942 RetPtr
= (HICON16
*)GlobalLock16(hRet
);
944 *RetPtr
= (n
== 0xFFFF)? 0: 1; /* error return values */
946 sig
= SHELL_GetResourceTable(hFile
,&pData
);
948 if(sig
== IMAGE_OS2_SIGNATURE
)
951 NE_TYPEINFO
* pTInfo
= (NE_TYPEINFO
*)(pData
+ 2);
952 NE_NAMEINFO
* pIconStorage
= NULL
;
953 NE_NAMEINFO
* pIconDir
= NULL
;
954 LPicoICONDIR lpiID
= NULL
;
956 if( pData
== (BYTE
*)-1 )
958 /* check for .ICO file */
960 hIcon
= ICO_GetIconDirectory(hInstance
, hFile
, &lpiID
);
961 if( hIcon
) { iconDirCount
= 1; iconCount
= lpiID
->idCount
; }
963 else while( pTInfo
->type_id
&& !(pIconStorage
&& pIconDir
) )
965 /* find icon directory and icon repository */
967 if( pTInfo
->type_id
== NE_RSCTYPE_GROUP_ICON
)
969 iconDirCount
= pTInfo
->count
;
970 pIconDir
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
971 TRACE(reg
,"\tfound directory - %i icon families\n", iconDirCount
);
973 if( pTInfo
->type_id
== NE_RSCTYPE_ICON
)
975 iconCount
= pTInfo
->count
;
976 pIconStorage
= ((NE_NAMEINFO
*)(pTInfo
+ 1));
977 TRACE(reg
,"\ttotal icons - %i\n", iconCount
);
979 pTInfo
= (NE_TYPEINFO
*)((char*)(pTInfo
+1)+pTInfo
->count
*sizeof(NE_NAMEINFO
));
982 /* load resources and create icons */
984 if( (pIconStorage
&& pIconDir
) || lpiID
)
985 if( nIconIndex
== (UINT16
)-1 ) RetPtr
[0] = iconDirCount
;
986 else if( nIconIndex
< iconDirCount
)
990 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
992 for( i
= nIconIndex
; i
< nIconIndex
+ n
; i
++ )
994 /* .ICO files have only one icon directory */
997 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconDir
+ i
,
999 RetPtr
[i
-nIconIndex
] = GetIconID( hIcon
, 3 );
1000 GlobalFree16(hIcon
);
1003 for( icon
= nIconIndex
; icon
< nIconIndex
+ n
; icon
++ )
1007 hIcon
= ICO_LoadIcon( hInstance
, hFile
,
1008 lpiID
->idEntries
+ RetPtr
[icon
-nIconIndex
]);
1010 for( i
= 0; i
< iconCount
; i
++ )
1011 if( pIconStorage
[i
].id
== (RetPtr
[icon
-nIconIndex
] | 0x8000) )
1012 hIcon
= SHELL_LoadResource( hInstance
, hFile
, pIconStorage
+ i
,
1016 RetPtr
[icon
-nIconIndex
] = LoadIconHandler( hIcon
, TRUE
);
1017 FarSetOwner( RetPtr
[icon
-nIconIndex
], GetExePtr(hInstance
) );
1020 RetPtr
[icon
-nIconIndex
] = 0;
1023 if( lpiID
) HeapFree( GetProcessHeap(), 0, lpiID
);
1024 else HeapFree( GetProcessHeap(), 0, pData
);
1026 if( sig
== IMAGE_NT_SIGNATURE
)
1028 LPBYTE peimage
,idata
,igdata
;
1029 LPIMAGE_DOS_HEADER dheader
;
1030 LPIMAGE_NT_HEADERS pe_header
;
1031 LPIMAGE_SECTION_HEADER pe_sections
;
1032 LPIMAGE_RESOURCE_DIRECTORY rootresdir
,iconresdir
,icongroupresdir
;
1033 LPIMAGE_RESOURCE_DATA_ENTRY idataent
,igdataent
;
1036 LPIMAGE_RESOURCE_DIRECTORY_ENTRY xresent
;
1037 CURSORICONDIR
**cids
;
1039 fmapping
= CreateFileMapping32A(hFile
,NULL
,PAGE_READONLY
|SEC_COMMIT
,0,0,NULL
);
1040 if (fmapping
== 0) { /* FIXME, INVALID_HANDLE_VALUE? */
1041 WARN(reg
,"failed to create filemap.\n");
1045 peimage
= MapViewOfFile(fmapping
,FILE_MAP_READ
,0,0,0);
1047 WARN(reg
,"failed to mmap filemap.\n");
1048 CloseHandle(fmapping
);
1052 dheader
= (LPIMAGE_DOS_HEADER
)peimage
;
1053 /* it is a pe header, SHELL_GetResourceTable checked that */
1054 pe_header
= (LPIMAGE_NT_HEADERS
)(peimage
+dheader
->e_lfanew
);
1055 /* probably makes problems with short PE headers... but I haven't seen
1058 pe_sections
= (LPIMAGE_SECTION_HEADER
)(((char*)pe_header
)+sizeof(*pe_header
));
1060 for (i
=0;i
<pe_header
->FileHeader
.NumberOfSections
;i
++) {
1061 if (pe_sections
[i
].Characteristics
& IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
1063 /* FIXME: doesn't work when the resources are not in a seperate section */
1064 if (pe_sections
[i
].VirtualAddress
== pe_header
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_RESOURCE
].VirtualAddress
) {
1065 rootresdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((char*)peimage
+pe_sections
[i
].PointerToRawData
);
1071 WARN(reg
,"haven't found section for resource directory.\n");
1072 UnmapViewOfFile(peimage
);
1073 CloseHandle(fmapping
);
1077 icongroupresdir
= GetResDirEntryW(rootresdir
,(LPWSTR
)RT_GROUP_ICON
,(DWORD
)rootresdir
,FALSE
);
1078 if (!icongroupresdir
) {
1079 WARN(reg
,"No Icongroupresourcedirectory!\n");
1080 UnmapViewOfFile(peimage
);
1081 CloseHandle(fmapping
);
1086 iconDirCount
= icongroupresdir
->NumberOfNamedEntries
+icongroupresdir
->NumberOfIdEntries
;
1087 if( nIconIndex
== (UINT16
)-1 ) {
1088 RetPtr
[0] = iconDirCount
;
1089 UnmapViewOfFile(peimage
);
1090 CloseHandle(fmapping
);
1095 if (nIconIndex
>= iconDirCount
) {
1096 WARN(reg
,"nIconIndex %d is larger than iconDirCount %d\n",
1097 nIconIndex
,iconDirCount
);
1098 UnmapViewOfFile(peimage
);
1099 CloseHandle(fmapping
);
1104 cids
= (CURSORICONDIR
**)HeapAlloc(GetProcessHeap(),0,n
*sizeof(CURSORICONDIR
*));
1106 /* caller just wanted the number of entries */
1108 xresent
= (LPIMAGE_RESOURCE_DIRECTORY_ENTRY
)(icongroupresdir
+1);
1109 /* assure we don't get too much ... */
1110 if( n
> iconDirCount
- nIconIndex
) n
= iconDirCount
- nIconIndex
;
1112 /* starting from specified index ... */
1113 xresent
= xresent
+nIconIndex
;
1115 for (i
=0;i
<n
;i
++,xresent
++) {
1117 LPIMAGE_RESOURCE_DIRECTORY resdir
;
1119 /* go down this resource entry, name */
1120 resdir
= (LPIMAGE_RESOURCE_DIRECTORY
)((DWORD
)rootresdir
+(xresent
->u2
.s
.OffsetToDirectory
));
1121 /* default language (0) */
1122 resdir
= GetResDirEntryW(resdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1123 igdataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)resdir
;
1125 /* lookup address in mapped image for virtual address */
1127 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1128 if (igdataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1130 if (igdataent
->OffsetToData
+igdataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1132 igdata
= peimage
+(igdataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1135 WARN(reg
,"no matching real address for icongroup!\n");
1136 UnmapViewOfFile(peimage
);
1137 CloseHandle(fmapping
);
1142 cid
= (CURSORICONDIR
*)igdata
;
1144 RetPtr
[i
] = LookupIconIdFromDirectoryEx32(igdata
,TRUE
,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1146 iconresdir
=GetResDirEntryW(rootresdir
,(LPWSTR
)RT_ICON
,(DWORD
)rootresdir
,FALSE
);
1148 WARN(reg
,"No Iconresourcedirectory!\n");
1149 UnmapViewOfFile(peimage
);
1150 CloseHandle(fmapping
);
1155 LPIMAGE_RESOURCE_DIRECTORY xresdir
;
1157 xresdir
= GetResDirEntryW(iconresdir
,(LPWSTR
)RetPtr
[i
],(DWORD
)rootresdir
,FALSE
);
1158 xresdir
= GetResDirEntryW(xresdir
,(LPWSTR
)0,(DWORD
)rootresdir
,TRUE
);
1160 idataent
= (LPIMAGE_RESOURCE_DATA_ENTRY
)xresdir
;
1163 /* map virtual to address in image */
1164 for (j
=0;j
<pe_header
->FileHeader
.NumberOfSections
;j
++) {
1165 if (idataent
->OffsetToData
< pe_sections
[j
].VirtualAddress
)
1167 if (idataent
->OffsetToData
+idataent
->Size
> pe_sections
[j
].VirtualAddress
+pe_sections
[j
].SizeOfRawData
)
1169 idata
= peimage
+(idataent
->OffsetToData
-pe_sections
[j
].VirtualAddress
+pe_sections
[j
].PointerToRawData
);
1172 WARN(reg
,"no matching real address found for icondata!\n");
1176 RetPtr
[i
] = CreateIconFromResourceEx32(idata
,idataent
->Size
,TRUE
,0x00030000,SYSMETRICS_CXICON
,SYSMETRICS_CYICON
,0);
1178 UnmapViewOfFile(peimage
);
1179 CloseHandle(fmapping
);
1184 /* return array with icon handles */
1189 /*************************************************************************
1190 * ExtractIcon16 (SHELL.34)
1192 HICON16 WINAPI
ExtractIcon16( HINSTANCE16 hInstance
, LPCSTR lpszExeFileName
,
1195 return ExtractIcon32A( hInstance
, lpszExeFileName
, nIconIndex
);
1199 /*************************************************************************
1200 * ExtractIcon32A (SHELL32.133)
1202 HICON32 WINAPI
ExtractIcon32A( HINSTANCE32 hInstance
, LPCSTR lpszExeFileName
,
1205 HGLOBAL16 handle
= InternalExtractIcon(hInstance
,lpszExeFileName
,nIconIndex
, 1);
1209 HICON16
* ptr
= (HICON16
*)GlobalLock16(handle
);
1210 HICON16 hIcon
= *ptr
;
1212 GlobalFree16(handle
);
1218 /*************************************************************************
1219 * ExtractIcon32W (SHELL32.180)
1221 HICON32 WINAPI
ExtractIcon32W( HINSTANCE32 hInstance
, LPCWSTR lpszExeFileName
,
1224 LPSTR exefn
= HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName
);
1225 HICON32 ret
= ExtractIcon32A(hInstance
,exefn
,nIconIndex
);
1227 HeapFree(GetProcessHeap(),0,exefn
);
1232 /*************************************************************************
1233 * ExtractAssociatedIcon [SHELL.36]
1235 * Return icon for given file (either from file itself or from associated
1236 * executable) and patch parameters if needed.
1238 HICON32 WINAPI
ExtractAssociatedIcon32A(HINSTANCE32 hInst
,LPSTR lpIconPath
,
1241 return ExtractAssociatedIcon16(hInst
,lpIconPath
,lpiIcon
);
1244 HICON16 WINAPI
ExtractAssociatedIcon16(HINSTANCE16 hInst
,LPSTR lpIconPath
,
1247 HICON16 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1252 if( hIcon
== 1 ) /* no icons found in given file */
1254 char tempPath
[0x80];
1255 UINT16 uRet
= FindExecutable16(lpIconPath
,NULL
,tempPath
);
1257 if( uRet
> 32 && tempPath
[0] )
1259 strcpy(lpIconPath
,tempPath
);
1260 hIcon
= ExtractIcon16(hInst
, lpIconPath
, *lpiIcon
);
1262 if( hIcon
> 2 ) return hIcon
;
1268 *lpiIcon
= 2; /* MSDOS icon - we found .exe but no icons in it */
1270 *lpiIcon
= 6; /* generic icon - found nothing */
1272 GetModuleFileName16(hInst
, lpIconPath
, 0x80);
1273 hIcon
= LoadIcon16( hInst
, MAKEINTRESOURCE(*lpiIcon
));
1279 /*************************************************************************
1280 * FindEnvironmentString [SHELL.38]
1282 * Returns a pointer into the DOS environment... Ugh.
1284 LPSTR
SHELL_FindString(LPSTR lpEnv
, LPCSTR entry
)
1286 UINT16 l
= strlen(entry
);
1287 for( ; *lpEnv
; lpEnv
+=strlen(lpEnv
)+1 )
1289 if( lstrncmpi32A(lpEnv
, entry
, l
) ) continue;
1292 return (lpEnv
+ l
); /* empty entry */
1293 else if ( *(lpEnv
+l
)== '=' )
1294 return (lpEnv
+ l
+ 1);
1299 SEGPTR WINAPI
FindEnvironmentString(LPSTR str
)
1301 SEGPTR spEnv
= GetDOSEnvironment();
1302 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(spEnv
);
1304 LPSTR lpString
= (spEnv
)?SHELL_FindString(lpEnv
, str
):NULL
;
1306 if( lpString
) /* offset should be small enough */
1307 return spEnv
+ (lpString
- lpEnv
);
1309 return (SEGPTR
)NULL
;
1312 /*************************************************************************
1313 * DoEnvironmentSubst [SHELL.37]
1315 * Replace %KEYWORD% in the str with the value of variable KEYWORD
1316 * from "DOS" environment.
1318 DWORD WINAPI
DoEnvironmentSubst(LPSTR str
,WORD length
)
1320 LPSTR lpEnv
= (LPSTR
)PTR_SEG_TO_LIN(GetDOSEnvironment());
1321 LPSTR lpBuffer
= (LPSTR
)HeapAlloc( GetProcessHeap(), 0, length
);
1323 LPSTR lpbstr
= lpBuffer
;
1325 CharToOem32A(str
,str
);
1327 TRACE(reg
,"accept %s\n", str
);
1329 while( *lpstr
&& lpbstr
- lpBuffer
< length
)
1331 LPSTR lpend
= lpstr
;
1335 do { lpend
++; } while( *lpend
&& *lpend
!= '%' );
1336 if( *lpend
== '%' && lpend
- lpstr
> 1 ) /* found key */
1340 lpKey
= SHELL_FindString(lpEnv
, lpstr
+1);
1341 if( lpKey
) /* found key value */
1343 int l
= strlen(lpKey
);
1345 if( l
> length
- (lpbstr
- lpBuffer
) - 1 )
1347 WARN(reg
,"Env subst aborted - string too short\n");
1351 strcpy(lpbstr
, lpKey
);
1358 else break; /* back off and whine */
1363 *lpbstr
++ = *lpstr
++;
1367 if( lpstr
- str
== strlen(str
) )
1369 strncpy(str
, lpBuffer
, length
);
1375 TRACE(reg
," return %s\n", str
);
1377 OemToChar32A(str
,str
);
1378 HeapFree( GetProcessHeap(), 0, lpBuffer
);
1380 /* Return str length in the LOWORD
1381 * and 1 in HIWORD if subst was successful.
1383 return (DWORD
)MAKELONG(strlen(str
), length
);
1386 /*************************************************************************
1387 * ShellHookProc [SHELL.103]
1388 * System-wide WH_SHELL hook.
1390 LRESULT WINAPI
ShellHookProc(INT16 code
, WPARAM16 wParam
, LPARAM lParam
)
1392 TRACE(reg
,"%i, %04x, %08x\n", code
, wParam
,
1394 if( SHELL_hHook
&& SHELL_hWnd
)
1399 case HSHELL_WINDOWCREATED
: uMsg
= uMsgWndCreated
; break;
1400 case HSHELL_WINDOWDESTROYED
: uMsg
= uMsgWndDestroyed
; break;
1401 case HSHELL_ACTIVATESHELLWINDOW
: uMsg
= uMsgShellActivate
;
1403 PostMessage16( SHELL_hWnd
, uMsg
, wParam
, 0 );
1405 return CallNextHookEx16( WH_SHELL
, code
, wParam
, lParam
);
1408 /*************************************************************************
1409 * RegisterShellHook [SHELL.102]
1411 BOOL32 WINAPI
RegisterShellHook(HWND16 hWnd
, UINT16 uAction
)
1413 TRACE(reg
,"%04x [%u]\n", hWnd
, uAction
);
1417 case 2: /* register hWnd as a shell window */
1421 HMODULE16 hShell
= GetModuleHandle16( "SHELL" );
1423 SHELL_hHook
= SetWindowsHookEx16( WH_SHELL
, ShellHookProc
,
1427 uMsgWndCreated
= RegisterWindowMessage32A( lpstrMsgWndCreated
);
1428 uMsgWndDestroyed
= RegisterWindowMessage32A( lpstrMsgWndDestroyed
);
1429 uMsgShellActivate
= RegisterWindowMessage32A( lpstrMsgShellActivate
);
1431 else WARN(reg
, "unable to install ShellHookProc()!\n");
1434 if( SHELL_hHook
) return ((SHELL_hWnd
= hWnd
) != 0);
1439 WARN(reg
, "unknown code %i\n", uAction
);
1449 /*************************************************************************
1450 * SHGetFileInfoA [SHELL32.218]
1452 DWORD WINAPI
SHGetFileInfo32A(LPCSTR path
,DWORD dwFileAttributes
,
1453 SHFILEINFO32A
*psfi
, UINT32 sizeofpsfi
,
1456 FIXME(shell
,"(%s,0x%08lx,%p,%d,0x%08x): stub\n",
1457 path
,dwFileAttributes
,psfi
,sizeofpsfi
,flags
);
1461 /*************************************************************************
1462 * SHAppBarMessage32 [SHELL32.207]
1464 UINT32 WINAPI
SHAppBarMessage32(DWORD msg
, PAPPBARDATA data
)
1466 FIXME(shell
,"(0x%08lx,%p): stub\n", msg
, data
);
1470 case ABM_GETAUTOHIDEBAR
:
1472 case ABM_GETTASKBARPOS
:
1476 case ABM_SETAUTOHIDEBAR
:
1478 case ABM_WINDOWPOSCHANGED
:
1485 /*************************************************************************
1486 * CommandLineToArgvW [SHELL32.7]
1488 LPWSTR
* WINAPI
CommandLineToArgvW(LPWSTR cmdline
,LPDWORD numargs
)
1493 /* to get writeable copy */
1494 cmdline
= HEAP_strdupW( GetProcessHeap(), 0, cmdline
);
1501 while (*s
&& *s
==0x0020)
1507 argv
=(LPWSTR
*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR
)*(i
+1) );
1513 argv
[i
++]=HEAP_strdupW( GetProcessHeap(), 0, t
);
1515 while (*s
&& *s
==0x0020)
1526 argv
[i
++]=(LPWSTR
)HEAP_strdupW( GetProcessHeap(), 0, t
);
1527 HeapFree( GetProcessHeap(), 0, cmdline
);
1533 /*************************************************************************
1534 * Control_RunDLL [SHELL32.12]
1536 * Wild speculation in the following!
1538 * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
1541 void WINAPI
Control_RunDLL (HWND32 hwnd
, LPCVOID code
, LPCSTR cmd
, DWORD arg4
)
1543 TRACE(exec
, "(%08x, %p, \"%s\", %08lx)\n",
1544 hwnd
, code
? code
: "(null)", cmd
? cmd
: "(null)", arg4
);
1547 /*************************************************************************
1550 void WINAPI
FreeIconList( DWORD dw
)
1552 FIXME(reg
, "empty stub\n" );
1555 /*************************************************************************
1556 * SHELL32_DllGetClassObject [SHELL32.14]
1558 * http://premium.microsoft.com/msdn/library/sdkdoc/api2_48fo.htm
1560 DWORD WINAPI
SHELL32_DllGetClassObject(REFCLSID rclsid
,REFIID iid
,LPVOID
*ppv
)
1562 char xclsid
[50],xiid
[50];
1563 HRESULT hres
= E_OUTOFMEMORY
;
1566 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
1567 WINE_StringFromCLSID((LPCLSID
)iid
,xiid
);
1568 TRACE(shell
,"(%s,%s,%p)\n",xclsid
,xiid
,ppv
);
1571 /* SDK example code looks like this:
1573 HRESULT hres = E_OUTOFMEMORY;
1576 CClassFactory *pClassFactory = new CClassFactory(rclsid);
1578 if (pClassFactory) {
1579 hRes = pClassFactory->QueryInterface(riid,ppv);
1580 pClassFactory->Release();
1584 * The magic of the whole stuff is still unclear to me, so just hack together
1588 if (!memcmp(rclsid
,&CLSID_ShellDesktop
,sizeof(CLSID_ShellDesktop
))) {
1589 TRACE(shell
," requested CLSID_ShellDesktop, creating it.\n");
1590 *ppv
= IShellFolder_Constructor();
1591 FIXME(shell
,"Initialize this folder to be the shell desktop folder\n");
1595 FIXME(shell
, " -> clsid not found. returning E_OUTOFMEMORY.\n");
1599 /*************************************************************************
1600 * SHGetDesktopFolder [SHELL32.216]
1601 * returns the interface to the shell desktop folder.
1603 * [SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
1604 * CLSID_ShellDesktop.
1606 * CoCreateInstance(CLSID_Desktop, NULL,
1607 * CLSCTX_INPROC, IID_IShellFolder, &pshf);
1609 * So what we are doing is currently wrong....
1611 DWORD WINAPI
SHGetDesktopFolder(LPSHELLFOLDER
*shellfolder
) {
1612 *shellfolder
= IShellFolder_Constructor();
1616 /*************************************************************************
1617 * SHGetMalloc [SHELL32.220]
1618 * returns the interface to shell malloc.
1620 * [SDK header win95/shlobj.h:
1621 * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
1623 * What we are currently doing is not very wrong, since we always use the same
1624 * heap (ProcessHeap).
1626 DWORD WINAPI
SHGetMalloc(LPMALLOC32
*lpmal
) {
1627 TRACE(shell
,"(%p)\n", lpmal
);
1628 return CoGetMalloc32(0,lpmal
);
1631 /*************************************************************************
1632 * SHGetSpecialFolderLocation [SHELL32.223]
1633 * returns the PIDL of a special folder
1635 * nFolder is a CSIDL_xxxxx.
1637 HRESULT WINAPI
SHGetSpecialFolderLocation(HWND32 hwndOwner
, INT32 nFolder
, LPITEMIDLIST
* ppidl
) {
1638 FIXME(shell
,"(%04x,%d,%p),stub!\n", hwndOwner
,nFolder
,ppidl
);
1639 *ppidl
= (LPITEMIDLIST
)HeapAlloc(GetProcessHeap(),0,2*sizeof(ITEMIDLIST
));
1640 FIXME(shell
, "we return only the empty ITEMIDLIST currently.\n");
1641 (*ppidl
)->mkid
.cb
= 0;
1645 /*************************************************************************
1646 * SHGetPathFromIDList [SHELL32.221]
1647 * returns the path from a passed PIDL.
1649 BOOL32 WINAPI
SHGetPathFromIDList(LPCITEMIDLIST pidl
,LPSTR pszPath
) {
1650 FIXME(shell
,"(%p,%p),stub!\n",pidl
,pszPath
);
1651 lstrcpy32A(pszPath
,"E:\\"); /* FIXME */