/* * Shell basics * * 1998 Marcus Meissner * 1998 Juergen Schmied (jsch) * */ #include #include #include "wine/winuser16.h" #include "winerror.h" #include "heap.h" #include "resource.h" #include "dlgs.h" #include "ldt.h" #include "sysmetrics.h" #include "debugtools.h" #include "winreg.h" #include "authors.h" #include "winversion.h" #include "shellapi.h" #include "pidl.h" #include "shlobj.h" #include "shell32_main.h" #include "shlguid.h" #include "wine/undocshell.h" DECLARE_DEBUG_CHANNEL(exec) DECLARE_DEBUG_CHANNEL(shell) /************************************************************************* * CommandLineToArgvW [SHELL32.7] */ LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs) { LPWSTR *argv,s,t; int i; TRACE_(shell)("\n"); /* to get writeable copy */ cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline); s=cmdline;i=0; while (*s) { /* space */ if (*s==0x0020) { i++; s++; while (*s && *s==0x0020) s++; continue; } s++; } argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) ); s=t=cmdline; i=0; while (*s) { if (*s==0x0020) { *s=0; argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t ); *s=0x0020; while (*s && *s==0x0020) s++; if (*s) t=s+1; else t=s; continue; } s++; } if (*t) argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t ); HeapFree( GetProcessHeap(), 0, cmdline ); argv[i]=NULL; *numargs=i; return argv; } /************************************************************************* * Control_RunDLL [SHELL32.12] * * Wild speculation in the following! * * http://premium.microsoft.com/msdn/library/techart/msdn193.htm */ void WINAPI Control_RunDLL( HWND hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 ) { FIXME_(shell)("(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code, debugstr_a(cmd), arg4); } /************************************************************************* * SHGetFileInfoA [SHELL32.254] */ DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes, SHFILEINFOA *psfi, UINT sizeofpsfi, UINT flags ) { CHAR szTemp[MAX_PATH]; LPPIDLDATA pData; LPITEMIDLIST pPidlTemp = NULL; DWORD ret=0, dwfa = dwFileAttributes; TRACE_(shell)("(%s,0x%lx,%p,0x%x,0x%x)\n", path,dwFileAttributes,psfi,sizeofpsfi,flags); /* translate the pidl to a path*/ if (flags & SHGFI_PIDL) { pPidlTemp = (LPCITEMIDLIST)path; SHGetPathFromIDListA (pPidlTemp, szTemp); TRACE_(shell)("pidl=%p is %s\n", path, szTemp); } else { strcpy(szTemp,path); TRACE_(shell)("path=%s\n", szTemp); } if (flags & SHGFI_ATTRIBUTES) { if (flags & SHGFI_PIDL) { /* * We have to test for the desktop folder first because ILGetDataPointer returns * NULL on the desktop folder. */ if (_ILIsDesktop((LPCITEMIDLIST)path)) { psfi->dwAttributes = 0xb0000154; ret = TRUE; } else { pData = _ILGetDataPointer((LPCITEMIDLIST)path); switch (pData->type) { case PT_DESKTOP: psfi->dwAttributes = 0xb0000154; case PT_MYCOMP: psfi->dwAttributes = 0xb0000154; case PT_SPECIAL: psfi->dwAttributes = 0xa0000000; case PT_DRIVE: psfi->dwAttributes = 0xf0000144; case PT_FOLDER: psfi->dwAttributes = 0xe0000177; case PT_VALUE: psfi->dwAttributes = 0x40000177; } ret=TRUE; } } else { if (! (flags & SHGFI_USEFILEATTRIBUTES)) dwfa = GetFileAttributesA (szTemp); psfi->dwAttributes = SFGAO_FILESYSTEM; if (dwfa == FILE_ATTRIBUTE_DIRECTORY) psfi->dwAttributes |= SFGAO_FOLDER | SFGAO_HASSUBFOLDER; ret=TRUE; } WARN_(shell)("file attributes, semi-stub\n"); } if (flags & SHGFI_DISPLAYNAME) { if (flags & SHGFI_PIDL) { _ILSimpleGetText(ILFindLastID(pPidlTemp), psfi->szDisplayName, MAX_PATH); } else { lstrcpynA(psfi->szDisplayName,PathFindFilenameA(path), MAX_PATH); } TRACE_(shell)("displayname=%s\n", psfi->szDisplayName); ret=TRUE; } if (flags & SHGFI_TYPENAME) { FIXME_(shell)("get the file type, stub\n"); strcpy(psfi->szTypeName,"FIXME: Type"); ret=TRUE; } if (flags & SHGFI_ICONLOCATION) { FIXME_(shell)("location of icon, stub\n"); strcpy(psfi->szDisplayName,""); ret=TRUE; } if (flags & SHGFI_EXETYPE) FIXME_(shell)("type of executable, stub\n"); if (flags & SHGFI_LINKOVERLAY) FIXME_(shell)("set icon to link, stub\n"); if (flags & SHGFI_OPENICON) FIXME_(shell)("set to open icon, stub\n"); if (flags & SHGFI_SELECTED) FIXME_(shell)("set icon to selected, stub\n"); if (flags & SHGFI_SHELLICONSIZE) FIXME_(shell)("set icon to shell size, stub\n"); if (flags & SHGFI_USEFILEATTRIBUTES) FIXME_(shell)("use the dwFileAttributes, stub\n"); if (flags & (SHGFI_UNKNOWN1 | SHGFI_UNKNOWN2 | SHGFI_UNKNOWN3)) FIXME_(shell)("unknown attribute!\n"); if (flags & SHGFI_ICON) { FIXME_(shell)("icon handle\n"); if (flags & SHGFI_SMALLICON) { TRACE_(shell)("set to small icon\n"); psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL); ret = (DWORD) ShellSmallIconList; } else { TRACE_(shell)("set to big icon\n"); psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL); ret = (DWORD) ShellBigIconList; } } if (flags & SHGFI_SYSICONINDEX) { IShellFolder * sf; if (!pPidlTemp) { pPidlTemp = ILCreateFromPathA (szTemp); } if (SUCCEEDED (SHGetDesktopFolder (&sf))) { psfi->iIcon = SHMapPIDLToSystemImageListIndex (sf, pPidlTemp, 0); IShellFolder_Release(sf); } TRACE_(shell)("-- SYSICONINDEX %i\n", psfi->iIcon); if (flags & SHGFI_SMALLICON) { TRACE_(shell)("set to small icon\n"); ret = (DWORD) ShellSmallIconList; } else { TRACE_(shell)("set to big icon\n"); ret = (DWORD) ShellBigIconList; } } return ret; } /************************************************************************* * SHGetFileInfoW [SHELL32.255] */ DWORD WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags ) { FIXME_(shell)("(%s,0x%lx,%p,0x%x,0x%x)\n", debugstr_w(path),dwFileAttributes,psfi,sizeofpsfi,flags); return 0; } /************************************************************************* * ExtractIconA [SHELL32.133] */ HICON WINAPI ExtractIconA( HINSTANCE hInstance, LPCSTR lpszExeFileName, UINT nIconIndex ) { HGLOBAL16 handle = InternalExtractIcon16(hInstance,lpszExeFileName,nIconIndex, 1); TRACE_(shell)("\n"); if( handle ) { HICON16* ptr = (HICON16*)GlobalLock16(handle); HICON16 hIcon = *ptr; GlobalFree16(handle); return hIcon; } return 0; } /************************************************************************* * ExtractIconW [SHELL32.180] */ HICON WINAPI ExtractIconW( HINSTANCE hInstance, LPCWSTR lpszExeFileName, UINT nIconIndex ) { LPSTR exefn; HICON ret; TRACE_(shell)("\n"); exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName); ret = ExtractIconA(hInstance,exefn,nIconIndex); HeapFree(GetProcessHeap(),0,exefn); return ret; } /************************************************************************* * FindExecutableA [SHELL32.184] */ HINSTANCE WINAPI FindExecutableA( LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult ) { HINSTANCE retval=31; /* default - 'No association was found' */ char old_dir[1024]; TRACE_(shell)("File %s, Dir %s\n", (lpFile != NULL?lpFile:"-"), (lpDirectory != NULL?lpDirectory:"-")); lpResult[0]='\0'; /* Start off with an empty return string */ /* trap NULL parameters on entry */ if (( lpFile == NULL ) || ( lpResult == NULL )) { /* FIXME - should throw a warning, perhaps! */ return 2; /* File not found. Close enough, I guess. */ } if (lpDirectory) { GetCurrentDirectoryA( sizeof(old_dir), old_dir ); SetCurrentDirectoryA( lpDirectory ); } retval = SHELL_FindExecutable( lpFile, "open", lpResult ); TRACE_(shell)("returning %s\n", lpResult); if (lpDirectory) SetCurrentDirectoryA( old_dir ); return retval; } /************************************************************************* * FindExecutableW [SHELL32.219] */ HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult) { FIXME_(shell)("(%p,%p,%p): stub\n", lpFile, lpDirectory, lpResult); return 31; /* default - 'No association was found' */ } typedef struct { LPCSTR szApp; LPCSTR szOtherStuff; HICON hIcon; } ABOUT_INFO; #define IDC_STATIC_TEXT 100 #define IDC_LISTBOX 99 #define IDC_WINE_TEXT 98 #define DROP_FIELD_TOP (-15) #define DROP_FIELD_HEIGHT 15 extern HICON hIconTitleFont; static BOOL __get_dropline( HWND hWnd, LPRECT lprect ) { HWND hWndCtl = GetDlgItem(hWnd, IDC_WINE_TEXT); if( hWndCtl ) { GetWindowRect( hWndCtl, lprect ); MapWindowPoints( 0, hWnd, (LPPOINT)lprect, 2 ); lprect->bottom = (lprect->top += DROP_FIELD_TOP); return TRUE; } return FALSE; } /************************************************************************* * SHAppBarMessage32 [SHELL32.207] */ UINT WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data) { FIXME_(shell)("(0x%08lx,%p hwnd=0x%08x): stub\n", msg, data, data->hWnd); switch (msg) { case ABM_GETSTATE: return ABS_ALWAYSONTOP | ABS_AUTOHIDE; case ABM_GETTASKBARPOS: /* fake a taskbar on the bottom of the desktop */ { RECT rec; GetWindowRect(GetDesktopWindow(), &rec); rec.left = 0; rec.top = rec.bottom - 2; } return TRUE; case ABM_ACTIVATE: case ABM_GETAUTOHIDEBAR: case ABM_NEW: case ABM_QUERYPOS: case ABM_REMOVE: case ABM_SETAUTOHIDEBAR: case ABM_SETPOS: case ABM_WINDOWPOSCHANGED: return FALSE; } return 0; } /************************************************************************* * SHHelpShortcuts_RunDLL [SHELL32.224] * */ DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4) { FIXME_(exec)("(%lx, %lx, %lx, %lx) empty stub!\n", dwArg1, dwArg2, dwArg3, dwArg4); return 0; } /************************************************************************* * SHLoadInProc [SHELL32.225] * */ DWORD WINAPI SHLoadInProc (DWORD dwArg1) { FIXME_(shell)("(%lx) empty stub!\n", dwArg1); return 0; } /************************************************************************* * ShellExecuteA [SHELL32.245] */ HINSTANCE WINAPI ShellExecuteA( HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd ) { TRACE_(shell)("\n"); return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters, lpDirectory, iShowCmd ); } /************************************************************************* * ShellExecuteW [SHELL32.294] * from shellapi.h * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd); */ HINSTANCE WINAPI ShellExecuteW( HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd) { FIXME_(shell)(": stub\n"); return 0; } /************************************************************************* * AboutDlgProc32 (internal) */ BOOL WINAPI AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { HWND hWndCtl; char Template[512], AppTitle[512]; TRACE_(shell)("\n"); switch(msg) { case WM_INITDIALOG: { ABOUT_INFO *info = (ABOUT_INFO *)lParam; if (info) { const char* const *pstr = SHELL_People; SendDlgItemMessageA(hWnd, stc1, STM_SETICON,info->hIcon, 0); GetWindowTextA( hWnd, Template, sizeof(Template) ); sprintf( AppTitle, Template, info->szApp ); SetWindowTextA( hWnd, AppTitle ); SetWindowTextA( GetDlgItem(hWnd, IDC_STATIC_TEXT), info->szOtherStuff ); hWndCtl = GetDlgItem(hWnd, IDC_LISTBOX); SendMessageA( hWndCtl, WM_SETREDRAW, 0, 0 ); SendMessageA( hWndCtl, WM_SETFONT, hIconTitleFont, 0 ); while (*pstr) { SendMessageA( hWndCtl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)*pstr ); pstr++; } SendMessageA( hWndCtl, WM_SETREDRAW, 1, 0 ); } } return 1; case WM_PAINT: { RECT rect; PAINTSTRUCT ps; HDC hDC = BeginPaint( hWnd, &ps ); if( __get_dropline( hWnd, &rect ) ) { SelectObject( hDC, GetStockObject( BLACK_PEN ) ); MoveToEx( hDC, rect.left, rect.top, NULL ); LineTo( hDC, rect.right, rect.bottom ); } EndPaint( hWnd, &ps ); } break; case WM_LBTRACKPOINT: hWndCtl = GetDlgItem(hWnd, IDC_LISTBOX); if( (INT16)GetKeyState16( VK_CONTROL ) < 0 ) { if( DragDetect( hWndCtl, *((LPPOINT)&lParam) ) ) { INT idx = SendMessageA( hWndCtl, LB_GETCURSEL, 0, 0 ); if( idx != -1 ) { INT length = SendMessageA( hWndCtl, LB_GETTEXTLEN, (WPARAM)idx, 0 ); HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 ); char* pstr = (char*)GlobalLock16( hMemObj ); if( pstr ) { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) ); SendMessageA( hWndCtl, LB_GETTEXT, (WPARAM)idx, (LPARAM)pstr ); SendMessageA( hWndCtl, LB_DELETESTRING, (WPARAM)idx, 0 ); UpdateWindow( hWndCtl ); if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) ) SendMessageA( hWndCtl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)pstr ); } if( hMemObj ) GlobalFree16( hMemObj ); } } } break; case WM_QUERYDROPOBJECT: if( wParam == 0 ) { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA ) { RECT rect; if( __get_dropline( hWnd, &rect ) ) { POINT pt; pt.x=lpDragInfo->pt.x; pt.x=lpDragInfo->pt.y; rect.bottom += DROP_FIELD_HEIGHT; if( PtInRect( &rect, pt ) ) { SetWindowLongA( hWnd, DWL_MSGRESULT, 1 ); return TRUE; } } } } break; case WM_DROPOBJECT: if( wParam == hWnd ) { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam); if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList ) { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) ); if( pstr ) { static char __appendix_str[] = " with"; hWndCtl = GetDlgItem( hWnd, IDC_WINE_TEXT ); SendMessageA( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template ); if( !lstrncmpA( Template, "WINE", 4 ) ) SetWindowTextA( GetDlgItem(hWnd, IDC_STATIC_TEXT), Template ); else { char* pch = Template + strlen(Template) - strlen(__appendix_str); *pch = '\0'; SendMessageA( GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING, (WPARAM)-1, (LPARAM)Template ); } lstrcpyA( Template, pstr ); lstrcatA( Template, __appendix_str ); SetWindowTextA( hWndCtl, Template ); SetWindowLongA( hWnd, DWL_MSGRESULT, 1 ); return TRUE; } } } break; case WM_COMMAND: if (wParam == IDOK) { EndDialog(hWnd, TRUE); return TRUE; } break; } return 0; } /************************************************************************* * ShellAboutA [SHELL32.243] */ BOOL WINAPI ShellAboutA( HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon ) { ABOUT_INFO info; HRSRC hRes; LPVOID template; TRACE_(shell)("\n"); if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA))) return FALSE; if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes))) return FALSE; info.szApp = szApp; info.szOtherStuff = szOtherStuff; info.hIcon = hIcon; if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); return DialogBoxIndirectParamA( GetWindowLongA( hWnd, GWL_HINSTANCE ), template, hWnd, AboutDlgProc, (LPARAM)&info ); } /************************************************************************* * ShellAboutW [SHELL32.244] */ BOOL WINAPI ShellAboutW( HWND hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, HICON hIcon ) { BOOL ret; ABOUT_INFO info; HRSRC hRes; LPVOID template; TRACE_(shell)("\n"); if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA))) return FALSE; if(!(template = (LPVOID)LoadResource(shell32_hInstance, hRes))) return FALSE; info.szApp = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp ); info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff ); info.hIcon = hIcon; if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) ); ret = DialogBoxIndirectParamA( GetWindowLongA( hWnd, GWL_HINSTANCE ), template, hWnd, AboutDlgProc, (LPARAM)&info ); HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp ); HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff ); return ret; } /************************************************************************* * Shell_NotifyIcon [SHELL32.296] * FIXME * This function is supposed to deal with the systray. * Any ideas on how this is to be implimented? */ BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATAA pnid ) { TRACE_(shell)("\n"); return FALSE; } /************************************************************************* * Shell_NotifyIcon [SHELL32.297] * FIXME * This function is supposed to deal with the systray. * Any ideas on how this is to be implimented? */ BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid ) { TRACE_(shell)("\n"); return FALSE; } /************************************************************************* * FreeIconList */ void WINAPI FreeIconList( DWORD dw ) { FIXME_(shell)("(%lx): stub\n",dw); } /*********************************************************************** * DllGetVersion [COMCTL32.25] * * Retrieves version information of the 'SHELL32.DLL' * * PARAMS * pdvi [O] pointer to version information structure. * * RETURNS * Success: S_OK * Failure: E_INVALIDARG * * NOTES * Returns version of a shell32.dll from IE4.01 SP1. */ HRESULT WINAPI SHELL32_DllGetVersion (DLLVERSIONINFO *pdvi) { if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) { WARN_(shell)("wrong DLLVERSIONINFO size from app"); return E_INVALIDARG; } pdvi->dwMajorVersion = 4; pdvi->dwMinorVersion = 72; pdvi->dwBuildNumber = 3110; pdvi->dwPlatformID = 1; TRACE_(shell)("%lu.%lu.%lu.%lu\n", pdvi->dwMajorVersion, pdvi->dwMinorVersion, pdvi->dwBuildNumber, pdvi->dwPlatformID); return S_OK; } /************************************************************************* * global variables of the shell32.dll * all are once per process * */ void (WINAPI* pDLLInitComctl)(LPVOID); INT (WINAPI* pImageList_AddIcon) (HIMAGELIST himl, HICON hIcon); INT (WINAPI* pImageList_ReplaceIcon) (HIMAGELIST, INT, HICON); HIMAGELIST (WINAPI * pImageList_Create) (INT,INT,UINT,INT,INT); BOOL (WINAPI* pImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle); HICON (WINAPI * pImageList_GetIcon) (HIMAGELIST, INT, UINT); INT (WINAPI* pImageList_GetImageCount)(HIMAGELIST); COLORREF (WINAPI *pImageList_SetBkColor)(HIMAGELIST, COLORREF); LPVOID (WINAPI* pCOMCTL32_Alloc) (INT); BOOL (WINAPI* pCOMCTL32_Free) (LPVOID); HDPA (WINAPI* pDPA_Create) (INT); INT (WINAPI* pDPA_InsertPtr) (const HDPA, INT, LPVOID); BOOL (WINAPI* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM); LPVOID (WINAPI* pDPA_GetPtr) (const HDPA, INT); BOOL (WINAPI* pDPA_Destroy) (const HDPA); INT (WINAPI *pDPA_Search) (const HDPA, LPVOID, INT, PFNDPACOMPARE, LPARAM, UINT); LPVOID (WINAPI *pDPA_DeletePtr) (const HDPA hdpa, INT i); /* user32 */ HICON (WINAPI *pLookupIconIdFromDirectoryEx)(LPBYTE dir, BOOL bIcon, INT width, INT height, UINT cFlag); HICON (WINAPI *pCreateIconFromResourceEx)(LPBYTE bits,UINT cbSize, BOOL bIcon, DWORD dwVersion, INT width, INT height,UINT cFlag); static BOOL bShell32IsInitialized = 0; static HINSTANCE hComctl32; static INT shell32_RefCount = 0; INT shell32_ObjCount = 0; HINSTANCE shell32_hInstance; HIMAGELIST ShellSmallIconList = 0; HIMAGELIST ShellBigIconList = 0; HDPA sic_hdpa = 0; /************************************************************************* * SHELL32 LibMain * */ BOOL WINAPI Shell32LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { HMODULE hUser32; TRACE_(shell)("0x%x 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad); shell32_hInstance = hinstDLL; switch (fdwReason) { case DLL_PROCESS_ATTACH: if (!bShell32IsInitialized) { hComctl32 = LoadLibraryA("COMCTL32.DLL"); hUser32 = GetModuleHandleA("USER32"); if (hComctl32 && hUser32) { pDLLInitComctl=(void*)GetProcAddress(hComctl32,"InitCommonControlsEx"); if (pDLLInitComctl) { pDLLInitComctl(NULL); } pImageList_Create=(void*)GetProcAddress(hComctl32,"ImageList_Create"); pImageList_AddIcon=(void*)GetProcAddress(hComctl32,"ImageList_AddIcon"); pImageList_ReplaceIcon=(void*)GetProcAddress(hComctl32,"ImageList_ReplaceIcon"); pImageList_GetIcon=(void*)GetProcAddress(hComctl32,"ImageList_GetIcon"); pImageList_GetImageCount=(void*)GetProcAddress(hComctl32,"ImageList_GetImageCount"); pImageList_Draw=(void*)GetProcAddress(hComctl32,"ImageList_Draw"); pImageList_SetBkColor=(void*)GetProcAddress(hComctl32,"ImageList_SetBkColor"); /* imports by ordinal, pray that it works*/ pCOMCTL32_Alloc=(void*)GetProcAddress(hComctl32, (LPCSTR)71L); pCOMCTL32_Free=(void*)GetProcAddress(hComctl32, (LPCSTR)73L); pDPA_Create=(void*)GetProcAddress(hComctl32, (LPCSTR)328L); pDPA_Destroy=(void*)GetProcAddress(hComctl32, (LPCSTR)329L); pDPA_GetPtr=(void*)GetProcAddress(hComctl32, (LPCSTR)332L); pDPA_InsertPtr=(void*)GetProcAddress(hComctl32, (LPCSTR)334L); pDPA_DeletePtr=(void*)GetProcAddress(hComctl32, (LPCSTR)336L); pDPA_Sort=(void*)GetProcAddress(hComctl32, (LPCSTR)338L); pDPA_Search=(void*)GetProcAddress(hComctl32, (LPCSTR)339L); /* user32 */ pLookupIconIdFromDirectoryEx=(void*)GetProcAddress(hUser32,"LookupIconIdFromDirectoryEx"); pCreateIconFromResourceEx=(void*)GetProcAddress(hUser32,"CreateIconFromResourceEx"); } else { ERR_(shell)("P A N I C SHELL32 loading failed\n"); return FALSE; } SIC_Initialize(); bShell32IsInitialized = TRUE; } shell32_RefCount++; break; case DLL_THREAD_ATTACH: shell32_RefCount++; break; case DLL_THREAD_DETACH: shell32_RefCount--; break; case DLL_PROCESS_DETACH: shell32_RefCount--; if ( !shell32_RefCount ) { bShell32IsInitialized = FALSE; if (pdesktopfolder) { IShellFolder_Release(pdesktopfolder); pdesktopfolder = NULL; } SIC_Destroy(); FreeLibrary(hComctl32); /* this one is here to check if AddRef/Release is balanced */ if (shell32_ObjCount) { WARN_(shell)("leaving with %u objects left (memory leak)\n", shell32_ObjCount); } } TRACE_(shell)("refcount=%u objcount=%u \n", shell32_RefCount, shell32_ObjCount); break; } return TRUE; }