4 * Copyright 1998 Marcus Meissner
5 * Copyright 1998 Juergen Schmied (jsch) * <juergen.schmied@metronet.de>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "shell32_version.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
33 AddCommasW(DWORD lValue
, LPWSTR lpNumber
)
35 WCHAR szValue
[MAX_PATH
], szSeparator
[8 + 1];
38 GetLocaleInfoW(LOCALE_USER_DEFAULT
,
41 _countof(szSeparator
));
43 numFormat
.NumDigits
= 0;
44 numFormat
.LeadingZero
= 0;
45 numFormat
.Grouping
= 3; // FIXME! Use GetLocaleInfoW with LOCALE_SGROUPING and interpret the result.
46 numFormat
.lpDecimalSep
= szSeparator
;
47 numFormat
.lpThousandSep
= szSeparator
;
48 numFormat
.NegativeOrder
= 0;
50 swprintf(szValue
, L
"%lu", lValue
);
52 if (GetNumberFormatW(LOCALE_USER_DEFAULT
,
62 wcscpy(lpNumber
, szValue
);
71 RegenerateUserEnvironment(LPVOID
*lpEnvironment
, BOOL bUpdateSelf
)
74 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ
| TOKEN_WRITE
, &hUserToken
))
77 BOOL bResult
= CreateEnvironmentBlock(lpEnvironment
, hUserToken
, TRUE
);
78 if (!bResult
|| !lpEnvironment
)
80 CloseHandle(hUserToken
);
86 LPWSTR pszz
= (LPWSTR
)*lpEnvironment
;
92 size_t cch
= wcslen(pszz
);
93 LPWSTR pchEqual
= wcschr(pszz
, L
'=');
96 CStringW
strName(pszz
, pchEqual
- pszz
);
97 SetEnvironmentVariableW(strName
, pchEqual
+ 1);
103 CloseHandle(hUserToken
);
108 /**************************************************************************
109 * Default ClassFactory types
111 typedef HRESULT (CALLBACK
*LPFNCREATEINSTANCE
)(IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
* ppvObject
);
112 HRESULT
IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI
, PLONG pcRefDll
, const IID
*riidInst
, IClassFactory
**theFactory
);
115 /**************************************************************************
116 * Default ClassFactory Implementation
118 * SHCreateDefClassObject
121 * Helper function for dlls without their own classfactory.
122 * A generic classfactory is returned.
123 * When the CreateInstance of the cf is called the callback is executed.
127 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
132 LPFNCREATEINSTANCE lpfnCI
;
134 LONG
*pcRefDll
; /* pointer to refcounter in external dll (ugrrr...) */
137 HRESULT
Initialize(LPFNCREATEINSTANCE lpfnCI
, PLONG pcRefDll
, const IID
*riidInstx
);
140 STDMETHOD(CreateInstance
)(IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
*ppvObject
) override
;
141 STDMETHOD(LockServer
)(BOOL fLock
) override
;
143 BEGIN_COM_MAP(IDefClFImpl
)
144 COM_INTERFACE_ENTRY_IID(IID_IClassFactory
, IClassFactory
)
148 IDefClFImpl::IDefClFImpl()
156 HRESULT
IDefClFImpl::Initialize(LPFNCREATEINSTANCE lpfnCIx
, PLONG pcRefDllx
, const IID
*riidInstx
)
159 riidInst
= riidInstx
;
160 pcRefDll
= pcRefDllx
;
163 InterlockedIncrement(pcRefDll
);
165 TRACE("(%p)%s\n", this, shdebugstr_guid(riidInst
));
169 /******************************************************************************
170 * IDefClF_fnCreateInstance
172 HRESULT WINAPI
IDefClFImpl::CreateInstance(IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
*ppvObject
)
174 TRACE("%p->(%p,%s,%p)\n", this, pUnkOuter
, shdebugstr_guid(&riid
), ppvObject
);
178 if (riidInst
== NULL
|| IsEqualCLSID(riid
, *riidInst
) || IsEqualCLSID(riid
, IID_IUnknown
))
180 return lpfnCI(pUnkOuter
, riid
, ppvObject
);
183 ERR("unknown IID requested %s\n", shdebugstr_guid(&riid
));
184 return E_NOINTERFACE
;
187 /******************************************************************************
188 * IDefClF_fnLockServer
190 HRESULT WINAPI
IDefClFImpl::LockServer(BOOL fLock
)
192 TRACE("%p->(0x%x), not implemented\n", this, fLock
);
196 /**************************************************************************
197 * IDefClF_fnConstructor
200 HRESULT
IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI
, PLONG pcRefDll
, const IID
*riidInst
, IClassFactory
**theFactory
)
202 return ShellObjectCreatorInit
<IDefClFImpl
>(lpfnCI
, pcRefDll
, riidInst
, IID_PPV_ARG(IClassFactory
, theFactory
));
205 /******************************************************************************
206 * SHCreateDefClassObject [SHELL32.70]
208 HRESULT WINAPI
SHCreateDefClassObject(
211 LPFNCREATEINSTANCE lpfnCI
, /* [in] create instance callback entry */
212 LPDWORD pcRefDll
, /* [in/out] ref count of the dll */
213 REFIID riidInst
) /* [in] optional interface to the instance */
218 TRACE("%s %p %p %p %s\n", shdebugstr_guid(&riid
), ppv
, lpfnCI
, pcRefDll
, shdebugstr_guid(&riidInst
));
220 if (!IsEqualCLSID(riid
, IID_IClassFactory
))
221 return E_NOINTERFACE
;
222 hResult
= IDefClF_fnConstructor(lpfnCI
, (PLONG
)pcRefDll
, &riidInst
, &pcf
);
229 /**************************************************************************
232 class CStartMenuDummy
:
233 public CComCoClass
<CStartMenuDummy
, &CLSID_StartMenu
>,
234 public CComObjectRootEx
<CComMultiThreadModelNoCS
>
238 virtual ~CStartMenuDummy();
241 DECLARE_REGISTRY_RESOURCEID(IDR_STARTMENU
)
246 static STDMETHODIMP
CreateInstance(void *pv
, REFIID riid
, LPVOID
*ppv
)
252 return CLASS_E_NOAGGREGATION
;
253 return RSHELL_CStartMenu_CreateInstance(riid
, ppv
);
258 /**************************************************************************
261 class CShell32Module
: public CComModule
266 CComCreatorCentralInstance
< ATL::CComObject
< CDrivesFolder
> >::Term();
267 CComCreatorCentralInstance
< ATL::CComObject
< CDesktopFolder
> >::Term();
273 BEGIN_OBJECT_MAP(ObjectMap
)
274 OBJECT_ENTRY(CLSID_ActiveDesktop
, CActiveDesktop
)
275 OBJECT_ENTRY(CLSID_ShellFSFolder
, CFSFolder
)
276 OBJECT_ENTRY(CLSID_MyComputer
, CDrivesFolder
)
277 OBJECT_ENTRY(CLSID_ShellDesktop
, CDesktopFolder
)
278 OBJECT_ENTRY(CLSID_ShellItem
, CShellItem
)
279 OBJECT_ENTRY(CLSID_ShellLink
, CShellLink
)
280 OBJECT_ENTRY(CLSID_Shell
, CShellDispatch
)
281 OBJECT_ENTRY(CLSID_DragDropHelper
, CDropTargetHelper
)
282 OBJECT_ENTRY(CLSID_ControlPanel
, CControlPanelFolder
)
283 OBJECT_ENTRY(CLSID_OpenControlPanel
, COpenControlPanel
)
284 OBJECT_ENTRY(CLSID_MyDocuments
, CMyDocsFolder
)
285 OBJECT_ENTRY(CLSID_NetworkPlaces
, CNetFolder
)
286 OBJECT_ENTRY(CLSID_FontsFolderShortcut
, CFontsFolder
)
287 OBJECT_ENTRY(CLSID_Printers
, CPrinterFolder
)
288 OBJECT_ENTRY(CLSID_AdminFolderShortcut
, CAdminToolsFolder
)
289 OBJECT_ENTRY(CLSID_ShellFldSetExt
, CFolderOptions
)
290 OBJECT_ENTRY(CLSID_RecycleBin
, CRecycleBin
)
291 OBJECT_ENTRY(CLSID_OpenWithMenu
, COpenWithMenu
)
292 OBJECT_ENTRY(CLSID_NewMenu
, CNewMenu
)
293 OBJECT_ENTRY(CLSID_SendToMenu
, CSendToMenu
)
294 OBJECT_ENTRY(CLSID_CopyAsPathMenu
, CCopyAsPathMenu
)
295 OBJECT_ENTRY(CLSID_CopyToMenu
, CCopyToMenu
)
296 OBJECT_ENTRY(CLSID_MoveToMenu
, CMoveToMenu
)
297 OBJECT_ENTRY(CLSID_StartMenu
, CStartMenuDummy
)
298 OBJECT_ENTRY(CLSID_MenuBandSite
, CMenuSite
)
299 OBJECT_ENTRY(CLSID_MenuBand
, CMenuBand
)
300 OBJECT_ENTRY(CLSID_MenuDeskBar
, CMenuDeskBar
)
301 OBJECT_ENTRY(CLSID_MergedFolder
, CMergedFolder
)
302 OBJECT_ENTRY(CLSID_ExeDropHandler
, CExeDropHandler
)
303 OBJECT_ENTRY(CLSID_QueryAssociations
, CQueryAssociations
)
304 OBJECT_ENTRY(CLSID_UserNotification
, CUserNotification
)
307 CShell32Module gModule
;
310 /***********************************************************************
311 * DllGetVersion [SHELL32.@]
313 * Retrieves version information of the 'SHELL32.DLL'
316 * pdvi [O] pointer to version information structure.
320 * Failure: E_INVALIDARG
323 * Returns version of a shell32.dll from IE4.01 SP1.
326 STDAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
328 /* FIXME: shouldn't these values come from the version resource? */
329 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO
) ||
330 pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
332 pdvi
->dwMajorVersion
= WINE_FILEVERSION_MAJOR
;
333 pdvi
->dwMinorVersion
= WINE_FILEVERSION_MINOR
;
334 pdvi
->dwBuildNumber
= WINE_FILEVERSION_BUILD
;
335 pdvi
->dwPlatformID
= WINE_FILEVERSION_PLATFORMID
;
336 if (pdvi
->cbSize
== sizeof(DLLVERSIONINFO2
))
338 DLLVERSIONINFO2
*pdvi2
= (DLLVERSIONINFO2
*)pdvi
;
341 pdvi2
->ullVersion
= MAKEDLLVERULL(WINE_FILEVERSION_MAJOR
,
342 WINE_FILEVERSION_MINOR
,
343 WINE_FILEVERSION_BUILD
,
344 WINE_FILEVERSION_PLATFORMID
);
346 TRACE("%u.%u.%u.%u\n",
347 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
348 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);
353 WARN("wrong DLLVERSIONINFO size from app\n");
358 /*************************************************************************
359 * global variables of the shell32.dll
360 * all are once per process
363 HINSTANCE shell32_hInstance
;
365 /*************************************************************************
369 * calling oleinitialize here breaks sone apps.
371 STDAPI_(BOOL
) DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID fImpLoad
)
373 TRACE("%p 0x%x %p\n", hInstance
, dwReason
, fImpLoad
);
374 if (dwReason
== DLL_PROCESS_ATTACH
)
376 shell32_hInstance
= hInstance
;
377 gModule
.Init(ObjectMap
, hInstance
, &LIBID_Shell32
);
379 DisableThreadLibraryCalls (hInstance
);
381 /* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
382 GetModuleFileNameW(hInstance
, swShell32Name
, MAX_PATH
);
383 swShell32Name
[MAX_PATH
- 1] = '\0';
385 /* Initialize comctl32 */
386 INITCOMMONCONTROLSEX InitCtrls
;
387 InitCtrls
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
388 InitCtrls
.dwICC
= ICC_WIN95_CLASSES
| ICC_DATE_CLASSES
| ICC_USEREX_CLASSES
;
389 InitCommonControlsEx(&InitCtrls
);
391 /* Bad idea, initialization in DllMain! */
392 InitChangeNotifications();
394 else if (dwReason
== DLL_PROCESS_DETACH
)
396 shell32_hInstance
= NULL
;
398 FreeChangeNotifications();
404 /***********************************************************************
405 * DllCanUnloadNow (SHELL32.@)
407 STDAPI
DllCanUnloadNow()
409 return gModule
.DllCanUnloadNow();
412 /*************************************************************************
413 * DllGetClassObject [SHELL32.@]
414 * SHDllGetClassObject [SHELL32.128]
416 STDAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
420 TRACE("CLSID:%s,IID:%s\n", shdebugstr_guid(&rclsid
), shdebugstr_guid(&riid
));
422 hResult
= gModule
.DllGetClassObject(rclsid
, riid
, ppv
);
423 TRACE("-- pointer to class factory: %p\n", *ppv
);
427 /***********************************************************************
428 * DllRegisterServer (SHELL32.@)
430 STDAPI
DllRegisterServer()
434 hr
= gModule
.DllRegisterServer(TRUE
);
438 hr
= gModule
.UpdateRegistryFromResource(IDR_FOLDEROPTIONS
, TRUE
, NULL
);
442 hr
= SHELL_RegisterShellFolders();
449 /***********************************************************************
450 * DllUnregisterServer (SHELL32.@)
452 STDAPI
DllUnregisterServer()
456 hr
= gModule
.DllUnregisterServer(TRUE
);
460 hr
= gModule
.UpdateRegistryFromResource(IDR_FOLDEROPTIONS
, FALSE
, NULL
);
467 /*************************************************************************
468 * DllInstall [SHELL32.@]
472 * BOOL bInstall - TRUE for install, FALSE for uninstall
473 * LPCWSTR pszCmdLine - command line (unused by shell32?)
476 HRESULT WINAPI
DllInstall(BOOL bInstall
, LPCWSTR cmdline
)
478 FIXME("%s %s: stub\n", bInstall
? "TRUE":"FALSE", debugstr_w(cmdline
));
479 return S_OK
; /* indicate success */