Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
dll.cpp
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 43k
Category:
Windows Kernel
Development Platform:
Visual C++
- /***************************************************************************
- * dll.c
- *
- * Standard DLL entry-point functions
- *
- ***************************************************************************/
- #include "shellprv.h"
- #include <ntverp.h>
- #include <advpub.h> // For REGINSTALL
- #include "fstreex.h"
- #include "ids.h"
- #ifdef WINNT
- #define INSTALL_WEBFOLDERS 1
- #include <msi.h> // For OfficeWebFolders_Install()
- void OfficeWebFolders_Install(void);
- #endif // WINNT
- extern "C" STDAPI_(void) Control_FillCache_RunDLL( HWND hwndStub, HINSTANCE hAppInstance, LPSTR pszCmdLine, int nCmdShow );
- // DllGetVersion - New for IE 4.0 shell integrated mode
- //
- // All we have to do is declare this puppy and CCDllGetVersion does the rest
- //
- DLLVER_DUALBINARY(VER_PRODUCTVERSION_DW, VER_PRODUCTBUILD_QFE);
- HRESULT CallRegInstall(LPCSTR szSection)
- {
- HRESULT hr = E_FAIL;
- HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
- if (hinstAdvPack)
- {
- REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
- if (pfnri)
- {
- char szShdocvwPath[MAX_PATH];
- STRENTRY seReg[] = {
- { "SHDOCVW_PATH", szShdocvwPath },
- #ifdef WINNT
- { "25", "%SystemRoot%" },
- { "11", "%SystemRoot%\system32" },
- #endif
- };
- STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
- // Get the location of shdocvw.dll
- #ifdef WINNT
- lstrcpyA(szShdocvwPath, "%SystemRoot%\system32");
- #else
- GetSystemDirectory(szShdocvwPath, SIZECHARS(szShdocvwPath));
- #endif
- PathAppendA(szShdocvwPath, "shdocvw.dll");
- hr = pfnri(g_hinst, szSection, &stReg);
- }
- // since we only do this from DllInstall() don't load and unload advpack over and over
- // FreeLibrary(hinstAdvPack);
- }
- return hr;
- }
- BOOL UnregisterTypeLibrary(const CLSID* piidLibrary)
- {
- TCHAR szScratch[GUIDSTR_MAX];
- HKEY hk;
- BOOL f = FALSE;
- // convert the libid into a string.
- //
- SHStringFromGUID(*piidLibrary, szScratch, ARRAYSIZE(szScratch));
- if (RegOpenKey(HKEY_CLASSES_ROOT, TEXT("TypeLib"), &hk) == ERROR_SUCCESS)
- {
- f = RegDeleteKey(hk, szScratch);
- RegCloseKey(hk);
- }
- return f;
- }
- HRESULT Shell32RegTypeLib(void)
- {
- TCHAR szPath[MAX_PATH];
- WCHAR wszPath[MAX_PATH];
- // Load and register our type library.
- //
- GetModuleFileName(HINST_THISDLL, szPath, ARRAYSIZE(szPath));
- SHTCharToUnicode(szPath, wszPath, ARRAYSIZE(wszPath));
- ITypeLib *pTypeLib;
- HRESULT hr = LoadTypeLib(wszPath, &pTypeLib);
- if (SUCCEEDED(hr))
- {
- // call the unregister type library as we had some old junk that
- // was registered by a previous version of OleAut32, which is now causing
- // the current version to not work on NT...
- UnregisterTypeLibrary(&LIBID_Shell32);
- hr = RegisterTypeLib(pTypeLib, wszPath, NULL);
- if (FAILED(hr))
- {
- TraceMsg(TF_WARNING, "SHELL32: RegisterTypeLib failed (%x)", hr);
- }
- pTypeLib->Release();
- }
- else
- {
- TraceMsg(TF_WARNING, "SHELL32: LoadTypeLib failed (%x)", hr);
- }
- return hr;
- }
- STDAPI CreateShowDesktopOnQuickLaunch()
- {
- // delete the "_Current Item" key used for tip rotation in welcome.exe on every upgrade
- HKEY hkey;
- if ( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\Microsoft\Windows NT\CurrentVersion\Setup\Welcome"), 0, MAXIMUM_ALLOWED, &hkey ) )
- {
- RegDeleteValue(hkey, TEXT("_Current Item"));
- RegCloseKey(hkey);
- }
- // create the "Show Desktop" icon in the quick launch tray
- TCHAR szPath[MAX_PATH];
- if ( SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, TRUE) )
- {
- TCHAR szQuickLaunch[MAX_PATH];
- LoadString(g_hinst, IDS_QUICKLAUNCH, szQuickLaunch, ARRAYSIZE(szQuickLaunch));
- if ( PathAppend( szPath, szQuickLaunch ) )
- {
- WritePrivateProfileSection( TEXT("Shell"), TEXT("Command=2IconFile=explorer.exe,3"), szPath );
- WritePrivateProfileSection( TEXT("Taskbar"), TEXT("Command=ToggleDesktop"), szPath );
- return S_OK;
- }
- }
- return E_FAIL;
- }
- STDAPI Favorites_Install(BOOL bInstall);
- STDAPI RecentDocs_Install(BOOL bInstall);
- STDAPI CDeskHtmlProp_RegUnReg(BOOL bInstall);
- #ifdef WINNT
- STDAPI_(BOOL) ApplyRegistrySecurity();
- #endif
- STDAPI_(void) FixPlusIcons();
- STDAPI_(void) CleanupFileSystem();
- #define KEEP_FAILURE(hrSum, hrLast) if (FAILED(hrLast)) hrSum = hrLast;
- STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
- {
- HRESULT hrTemp, hr = S_OK;
- // 99/05/03 vtan: If you're reading this section then you are considering
- // adding code to the registration/installation of shell32.dll. There are
- // now 3 schemes to accomplish this task:
- // 1. IE4UINIT.EXE
- // Check HKLMSoftwareMicrosoftActive SetupInstalled Components{89820200-ECBD-11cf-8B85-00AA005B4383}
- // This says that if there is a new version of IE5 to launch ie4uinit.exe.
- // You can add code to this executable if you wish. You need to enlist in
- // the setup project on \trangoslmadd using "ieenlist setup"
- // 2. REGSVR32.EXE /n /i:U shell32.dll
- // Check HKLMSoftwareMicrosoftActive SetupInstalled Components{89820200-ECBD-11cf-8B85-00AA005B4340}
- // This is executed using the same scheme as IE4UINIT.EXE except that the
- // executable used is regsvr32.exe with a command line passed to
- // shell32!DllInstall. Add your code in the section for "U" below.
- // If you put the code in the section which is NOT "U" then your
- // code is executed at GUI setup and any changes you make to HKCU
- // go into the default user (template). Be careful when putting
- // things here as winlogon.exe (or some other process) may put
- // your changes into a user profile unconditionally.
- // 3. HIVEUSD.INX
- // Checks NT build numbers and does command based on the previous build
- // number and the current build number only executing the changes between
- // the builds. If you wish to add something using this method, currently
- // you have to enlist in the setup project on \rastamanntwin using
- // "enlist -fgs \rastamanntwin -p setup". To find hiveusd.inx go to
- // ntprivatesetupinfwin4inf. Add the build number which the delta
- // is required and a command to launch %SystemRoot%System32shmgrate.exe
- // with one or two parameters. The first parameter tells what command to
- // execute. The second parameter is optional. shmgrate.exe then finds
- // shell32.dll and calls shell32!FirstUserLogon. Code here is for upgrading
- // HKCU user profiles from one NT build to another NT build.
- // Code is executed in the process context shmgrate.exe and is executed
- // at a time where no UI is possible. Always use HKLMSoftwareMicrosoft
- // Windows NTCurrentVersionImage File Execution OptionsDebugger with
- // "-d".
- // Schemes 1 and 2 work on either Win9x or WinNT but have the sometimes
- // unwanted side effect of ALWAYS getting executed on version upgrades.
- // Scheme 3 only gets executed on build number deltas. Because schemes 1
- // and 2 are always executed, if a user changes (or deletes) that setting
- // it will always get put back. Not so with scheme 3.
- // Ideally, the best solution is have an internal shell32 build number
- // delta scheme which determines the from build and the to build and does
- // a similar mechanism to what hiveusd.inx and shmgrate.exe do. This
- // would probably involve either a common installation function (such as
- // FirstUserLogon()) which is called differently from Win9x and WinNT or
- // common functions to do the upgrade and two entry points (such as
- // FirstUserLogonNT() and FirstUserLogonWin9X().
- if (bInstall)
- {
- #ifdef WINNT
- NT_PRODUCT_TYPE type = NtProductWinNt;
- RtlGetNtProductType(&type);
- #endif
- // "U" means it's the per user install call
- if (!StrCmpIW(pszCmdLine, L"U"))
- {
- // NOTE: Code in this segment get run during first login. We want first
- // login to be as quick as possible so try to minimize this section.
- // Put per-user install stuff here. Any HKCU registration
- // done here is suspect. (If you are setting defaults, do
- // so in HKLM and use the SHRegXXXUSValue functions.)
- // WARNING: we get called by the ie4unit.exe (ieunit.inf) scheme:
- // %11%shell32.dll,NI,U
- // this happens per user, to test this code "regsvr32 /n /i:U shell32.dll"
- #ifdef INSTALL_WEBFOLDERS
- // Install the Office WebFolders shell namespace extension per user.
- OfficeWebFolders_Install();
- #endif
- // do the work to Install/Uninstall the favorites directory shellext...
- hrTemp = Favorites_Install(bInstall);
- KEEP_FAILURE(hrTemp, hr);
- // do the work to Install/Uninstall the Recent Docs Folder
- hrTemp = RecentDocs_Install(bInstall);
- KEEP_FAILURE(hrTemp, hr);
- hrTemp = CreateShowDesktopOnQuickLaunch();
- KEEP_FAILURE(hrTemp, hr);
- // populate the control panel cache
- Control_FillCache_RunDLL(NULL, NULL, NULL, SW_HIDE);
- }
- else
- {
- // Delete any old registration entries, then add the new ones.
- // Keep ADVPACK.DLL loaded across multiple calls to RegInstall.
- // (The inf engine doesn't guarantee DelReg/AddReg order, that's
- // why we explicitly unreg and reg here.)
- //
- hrTemp = CallRegInstall("RegDll");
- KEEP_FAILURE(hrTemp, hr);
- #ifdef WINNT
- // I suppose we should call out NT-only registrations, just in case
- // we ever have to ship a win9x based shell again
- hrTemp = CallRegInstall("RegDllNT");
- KEEP_FAILURE(hrTemp, hr);
- // If we are on NT server, do additional stuff
- if (type != NtProductWinNt)
- {
- hrTemp = CallRegInstall("RegDllNTServer");
- KEEP_FAILURE(hrTemp, hr);
- }
- #endif
- // This is apparently the only way to get setup to remove all the registry backup
- // for old names no longer in use...
- hrTemp = CallRegInstall("CleanupOldRollback1");
- KEEP_FAILURE(hrTemp, hr);
- hrTemp = CallRegInstall("CleanupOldRollback2");
- KEEP_FAILURE(hrTemp, hr);
- // REVIEW (ToddB): Move this to DllRegisterServer.
- hrTemp = Shell32RegTypeLib();
- KEEP_FAILURE(hrTemp, hr);
- #ifdef WINNT
- ApplyRegistrySecurity();
- #endif
- FixPlusIcons();
- CleanupFileSystem();
- }
- }
- else
- {
- // We only need one unreg call since all our sections share
- // the same backup information
- hrTemp = CallRegInstall("UnregDll");
- KEEP_FAILURE(hrTemp, hr);
- UnregisterTypeLibrary(&LIBID_Shell32);
- }
- CDeskHtmlProp_RegUnReg(bInstall);
- return hr;
- }
- STDAPI DllRegisterServer(void)
- {
- // NT5 setup calls this so it is now safe to put code here.
- return S_OK;
- }
- STDAPI DllUnregisterServer(void)
- {
- return S_OK;
- }
- // Migration/Upgrade functions put here for want of a better place
- // See DllInstall() for an explanation of usage.
- BOOL Clone (LPCTSTR pszSourcePath, LPCTSTR pszTargetPath, LPCTSTR pszName)
- {
- TCHAR szSourcePath[MAX_PATH], szTargetPath[MAX_PATH];
- lstrcpy(szSourcePath, pszSourcePath);
- lstrcpy(szTargetPath, pszTargetPath);
- PathAppend(szSourcePath, pszName);
- PathAppend(szTargetPath, pszName);
- return(CopyFile(szSourcePath, szTargetPath, TRUE));
- }
- STDAPI CopySampleJPG (void)
- {
- TCHAR szCurrentUserMyPicturesPath[MAX_PATH],
- szDefaultUserMyPicturesPath[MAX_PATH];
- // Here's the logic for copying the "Sample.jpg" file on upgrade.
- // 1. Get the CSIDL_MYPICUTRES path by using shell32!SHGetFolderPath passing (HANDLE)-1
- // as the hToken meaning "Default User".
- // 2. Copy the file
- // mydocs!PerUserInit is invoked to setup the desktop.ini and do all the other work
- // required to make this correct.
- if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_MYPICTURES, NULL, SHGFP_TYPE_CURRENT, szCurrentUserMyPicturesPath)) &&
- SUCCEEDED(SHGetFolderPath(NULL, CSIDL_MYPICTURES, (HANDLE)-1, SHGFP_TYPE_CURRENT, szDefaultUserMyPicturesPath)))
- {
- TCHAR szMyDocsDLLPath[MAX_PATH];
- Clone(szDefaultUserMyPicturesPath, szCurrentUserMyPicturesPath, TEXT("Sample.jpg"));
- if (GetSystemDirectory(szMyDocsDLLPath, ARRAYSIZE(szMyDocsDLLPath)) != 0)
- {
- HINSTANCE hInstMyDocs;
- PathAppend(szMyDocsDLLPath, TEXT("mydocs.dll"));
- hInstMyDocs = LoadLibrary(szMyDocsDLLPath);
- if (hInstMyDocs != NULL)
- {
- typedef void (*PFNPerUserInit) (void);
- PFNPerUserInit pfnPerUserInit;
- pfnPerUserInit = (PFNPerUserInit)GetProcAddress(hInstMyDocs, "PerUserInit");
- if (pfnPerUserInit != NULL)
- pfnPerUserInit();
- FreeLibrary(hInstMyDocs);
- }
- }
- }
- return(S_OK);
- }
- void CopyRegistryValues (HKEY hKeyBaseSource, LPCTSTR pszSource, HKEY hKeyBaseTarget, LPCTSTR pszTarget)
- {
- DWORD dwDisposition, dwMaxValueNameSize, dwMaxValueDataSize;
- HKEY hKeySource, hKeyTarget;
- hKeySource = hKeyTarget = NULL;
- if ((ERROR_SUCCESS == RegOpenKeyEx(hKeyBaseSource,
- pszSource,
- 0,
- KEY_READ,
- &hKeySource)) &&
- (ERROR_SUCCESS == RegCreateKeyEx(hKeyBaseTarget,
- pszTarget,
- 0,
- TEXT(""),
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKeyTarget,
- &dwDisposition)) &&
- (ERROR_SUCCESS == RegQueryInfoKey(hKeySource,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- &dwMaxValueNameSize,
- &dwMaxValueDataSize,
- NULL,
- NULL)))
- {
- TCHAR *pszValueName;
- void *pValueData;
- pszValueName = reinterpret_cast<TCHAR*>(LocalAlloc(LMEM_FIXED, ++dwMaxValueNameSize * sizeof(TCHAR)));
- if (pszValueName != NULL)
- {
- pValueData = LocalAlloc(LMEM_FIXED, dwMaxValueDataSize);
- if (pValueData != NULL)
- {
- DWORD dwIndex, dwType, dwValueNameSize, dwValueDataSize;
- dwIndex = 0;
- dwValueNameSize = dwMaxValueNameSize;
- dwValueDataSize = dwMaxValueDataSize;
- while (ERROR_SUCCESS == RegEnumValue(hKeySource,
- dwIndex,
- pszValueName,
- &dwValueNameSize,
- NULL,
- &dwType,
- reinterpret_cast<LPBYTE>(pValueData),
- &dwValueDataSize))
- {
- RegSetValueEx(hKeyTarget,
- pszValueName,
- 0,
- dwType,
- reinterpret_cast<LPBYTE>(pValueData),
- dwValueDataSize);
- ++dwIndex;
- dwValueNameSize = dwMaxValueNameSize;
- dwValueDataSize = dwMaxValueDataSize;
- }
- LocalFree(pValueData);
- }
- LocalFree(pszValueName);
- }
- }
- }
- STDAPI MergeDesktopAndNormalStreams (void)
- {
- static const TCHAR scszBaseRegistryLocation[] = TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer");
- static const int sciMaximumStreams = 128;
- static const TCHAR sccOldMRUListBase = TEXT('a');
- // Upgrade from NT4 (classic shell) to Windows 2000 (integrated shell)
- // This involves TWO major changes and one minor change:
- // 1. Merging DesktopStreamMRU and StreamMRU
- // 2. Upgrading the MRUList to MRUListEx
- // 3. Leaving the old settings alone for the roaming user profile scenario
- // This also involves special casing the users desktop PIDL because this is
- // stored as an absolute path PIDL in DesktopStream and needs to be stored
- // in StreamsDesktop instead.
- // The conversion is performed in-situ and simultaneously.
- // 1. Open all the keys we are going to need to do the conversion.
- HKEY hKeyBase, hKeyDesktopStreamMRU, hKeyDesktopStreams, hKeyStreamMRU, hKeyStreams;
- hKeyBase = hKeyDesktopStreamMRU = hKeyDesktopStreams = hKeyStreamMRU = hKeyStreams = NULL;
- if ((ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
- scszBaseRegistryLocation,
- 0,
- KEY_ALL_ACCESS,
- &hKeyBase)) &&
- (ERROR_SUCCESS == RegOpenKeyEx(hKeyBase,
- TEXT("DesktopStreamMRU"),
- 0,
- KEY_ALL_ACCESS,
- &hKeyDesktopStreamMRU)) &&
- (ERROR_SUCCESS == RegOpenKeyEx(hKeyBase,
- TEXT("DesktopStreams"),
- 0,
- KEY_ALL_ACCESS,
- &hKeyDesktopStreams)) &&
- (ERROR_SUCCESS == RegOpenKeyEx(hKeyBase,
- TEXT("StreamMRU"),
- 0,
- KEY_ALL_ACCESS,
- &hKeyStreamMRU)) &&
- (ERROR_SUCCESS == RegOpenKeyEx(hKeyBase,
- TEXT("Streams"),
- 0,
- KEY_ALL_ACCESS,
- &hKeyStreams)) &&
- // 2. Determine whether this upgrade is needed at all. If the presence of
- // StreamMRUMRUListEx is detected then stop.
- (ERROR_SUCCESS != RegQueryValueEx(hKeyStreamMRU,
- TEXT("MRUListEx"),
- NULL,
- NULL,
- NULL,
- NULL)))
- {
- DWORD *pdwMRUListEx, *pdwMRUListExBase;
- pdwMRUListExBase = pdwMRUListEx = reinterpret_cast<DWORD*>(LocalAlloc(LPTR, sciMaximumStreams * sizeof(DWORD) * 2));
- if (pdwMRUListEx != NULL)
- {
- DWORD dwLastFreeSlot, dwMRUListSize, dwType;
- TCHAR *pszMRUList, szMRUList[sciMaximumStreams];
- // 3. Read the StreamMRUMRUList, iterate thru this list
- // and convert as we go.
- dwLastFreeSlot = 0;
- dwMRUListSize = sizeof(szMRUList);
- if (ERROR_SUCCESS == RegQueryValueEx(hKeyStreamMRU,
- TEXT("MRUList"),
- NULL,
- &dwType,
- reinterpret_cast<LPBYTE>(szMRUList),
- &dwMRUListSize))
- {
- pszMRUList = szMRUList;
- while (*pszMRUList != TEXT(''))
- {
- DWORD dwValueDataSize;
- TCHAR szValue[16];
- // Read the PIDL information based on the letter in
- // the MRUList.
- szValue[0] = *pszMRUList++;
- szValue[1] = TEXT('');
- if (ERROR_SUCCESS == RegQueryValueEx(hKeyStreamMRU,
- szValue,
- NULL,
- NULL,
- NULL,
- &dwValueDataSize))
- {
- DWORD dwValueType;
- void *pValueData;
- pValueData = LocalAlloc(LMEM_FIXED, dwValueDataSize);
- if ((pValueData != NULL) &&
- (ERROR_SUCCESS == RegQueryValueEx(hKeyStreamMRU,
- szValue,
- NULL,
- &dwValueType,
- reinterpret_cast<LPBYTE>(pValueData),
- &dwValueDataSize)))
- {
- // Allocate a new number in the MRUListEx for the PIDL.
- *pdwMRUListEx = szValue[0] - sccOldMRUListBase;
- wsprintf(szValue, TEXT("%d"), *pdwMRUListEx++);
- ++dwLastFreeSlot;
- RegSetValueEx(hKeyStreamMRU,
- szValue,
- NULL,
- dwValueType,
- reinterpret_cast<LPBYTE>(pValueData),
- dwValueDataSize);
- LocalFree(pValueData);
- }
- }
- }
- }
- // 4. Read the DesktopStreamMRUMRUList, iterate thru this
- // this and append to the new MRUListEx that is being
- // created as well as copying both the PIDL in DesktopStreamMRU
- // and the view information in DesktopStreams.
- dwMRUListSize = sizeof(szMRUList);
- if (ERROR_SUCCESS == RegQueryValueEx(hKeyDesktopStreamMRU,
- TEXT("MRUList"),
- NULL,
- &dwType,
- reinterpret_cast<LPBYTE>(szMRUList),
- &dwMRUListSize))
- {
- bool fConvertedEmptyPIDL;
- TCHAR szDesktopDirectoryPath[MAX_PATH];
- fConvertedEmptyPIDL = false;
- SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL, SHGFP_TYPE_CURRENT, szDesktopDirectoryPath);
- pszMRUList = szMRUList;
- while (*pszMRUList != TEXT(''))
- {
- DWORD dwValueDataSize;
- TCHAR szSource[16];
- // Read the PIDL information based on the letter in
- // the MRUList.
- szSource[0] = *pszMRUList++;
- szSource[1] = TEXT('');
- if (ERROR_SUCCESS == RegQueryValueEx(hKeyDesktopStreamMRU,
- szSource,
- NULL,
- NULL,
- NULL,
- &dwValueDataSize))
- {
- DWORD dwValueType;
- void *pValueData;
- pValueData = LocalAlloc(LMEM_FIXED, dwValueDataSize);
- if ((pValueData != NULL) &&
- (ERROR_SUCCESS == RegQueryValueEx(hKeyDesktopStreamMRU,
- szSource,
- NULL,
- &dwValueType,
- reinterpret_cast<LPBYTE>(pValueData),
- &dwValueDataSize)))
- {
- TCHAR szTarget[16], szStreamPath[MAX_PATH];
- if ((SHGetPathFromIDList(reinterpret_cast<LPCITEMIDLIST>(pValueData), szStreamPath) != 0) &&
- (0 == lstrcmpi(szStreamPath, szDesktopDirectoryPath)))
- {
- if (!fConvertedEmptyPIDL)
- {
- // 99/05/24 #343721 vtan: Prefer the desktop relative PIDL
- // (empty PIDL) when given a choice of two PIDLs that refer
- // to the desktop. The old absolute PIDL is from SP3 and
- // earlier days. The new relative PIDL is from SP4 and
- // later days. An upgraded SP3 -> SP4 -> SPx -> Windows
- // 2000 system will possibly have old absolute PIDLs.
- // Check for the empty PIDL. If this is encountered already
- // then don't process this stream.
- fConvertedEmptyPIDL = ILIsEmpty(reinterpret_cast<LPCITEMIDLIST>(pValueData));
- wsprintf(szSource, TEXT("%d"), szSource[0] - sccOldMRUListBase);
- CopyRegistryValues(hKeyDesktopStreams, szSource, hKeyStreams, TEXT("Desktop"));
- }
- }
- else
- {
- // Allocate a new number in the MRUListEx for the PIDL.
- *pdwMRUListEx++ = dwLastFreeSlot;
- wsprintf(szTarget, TEXT("%d"), dwLastFreeSlot++);
- if (ERROR_SUCCESS == RegSetValueEx(hKeyStreamMRU,
- szTarget,
- NULL,
- dwValueType,
- reinterpret_cast<LPBYTE>(pValueData),
- dwValueDataSize))
- {
- // Copy the view information from DesktopStreams to Streams
- wsprintf(szSource, TEXT("%d"), szSource[0] - sccOldMRUListBase);
- CopyRegistryValues(hKeyDesktopStreams, szSource, hKeyStreams, szTarget);
- }
- }
- LocalFree(pValueData);
- }
- }
- }
- }
- *pdwMRUListEx++ = static_cast<DWORD>(-1);
- RegSetValueEx(hKeyStreamMRU,
- TEXT("MRUListEx"),
- NULL,
- REG_BINARY,
- reinterpret_cast<LPCBYTE>(pdwMRUListExBase),
- ++dwLastFreeSlot * sizeof(DWORD));
- LocalFree(reinterpret_cast<HLOCAL>(pdwMRUListExBase));
- }
- }
- if (hKeyStreams != NULL)
- RegCloseKey(hKeyStreams);
- if (hKeyStreamMRU != NULL)
- RegCloseKey(hKeyStreamMRU);
- if (hKeyDesktopStreams != NULL)
- RegCloseKey(hKeyDesktopStreams);
- if (hKeyDesktopStreamMRU != NULL)
- RegCloseKey(hKeyDesktopStreamMRU);
- if (hKeyBase != NULL)
- RegCloseKey(hKeyBase);
- return(S_OK);
- }
- static const int s_ciMaximumNumericString = 32;
- int GetRegistryStringValueAsInteger (HKEY hKey, LPCTSTR pszValue, int iDefaultValue)
- {
- int iResult;
- DWORD dwType, dwStringSize;
- TCHAR szString[s_ciMaximumNumericString];
- dwStringSize = sizeof(szString);
- if (ERROR_SUCCESS == RegQueryValueEx(hKey,
- pszValue,
- NULL,
- &dwType,
- reinterpret_cast<LPBYTE>(szString),
- &dwStringSize) && (dwType == REG_SZ))
- {
- iResult = StrToInt(szString);
- }
- else
- {
- iResult = iDefaultValue;
- }
- return(iResult);
- }
- void SetRegistryIntegerAsStringValue (HKEY hKey, LPCTSTR pszValue, int iValue)
- {
- TCHAR szString[s_ciMaximumNumericString];
- wnsprintf(szString, ARRAYSIZE(szString), TEXT("%d"), iValue);
- TW32(RegSetValueEx(hKey,
- pszValue,
- 0,
- REG_SZ,
- reinterpret_cast<LPBYTE>(szString),
- (lstrlen(szString) + sizeof('')) * sizeof(TCHAR)));
- }
- STDAPI MoveAndAdjustIconMetrics (void)
- {
- // 99/06/06 #309198 vtan: The following comes from hiveusd.inx which is
- // where this functionality used to be executed. It used to consist of
- // simple registry deletion and addition. This doesn't work on upgrade
- // when the user has large icons (Shell Icon Size == 48).
- // In this case that metric must be moved and the new values adjusted
- // so that the metric is preserved should the user then decide to turn
- // off large icons.
- // To restore old functionality, remove the entry in hiveusd.inx at
- // build 1500 which is where this function is invoked and copy the
- // old text back in.
- /*
- HKR,"1508Hive2","Action",0x00010001,3
- HKR,"1508Hive2","KeyName",0000000000,"Control PanelDesktopWindowMetrics"
- HKR,"1508Hive2","Value",0000000000,"75"
- HKR,"1508Hive2","ValueName",0000000000,"IconSpacing"
- HKR,"1508Hive3","Action",0x00010001,3
- HKR,"1508Hive3","KeyName",0000000000,"Control PanelDesktopWindowMetrics"
- HKR,"1508Hive3","Value",0000000000,"1"
- HKR,"1508Hive3","ValueName",0000000000,"IconTitleWrap"
- */
- // Icon metric keys have moved from HKCUControl PanelDesktopIcon*
- // to HKCUControl PanelDesktopWindowMetricsIcon* but only 3 values
- // should be moved. These are "IconSpacing", "IconTitleWrap" and
- // "IconVerticalSpacing". This code is executed before the deletion
- // entry in hiveusd.inx so that it can get the values before they
- // are deleted. The addition section has been remove (it's above).
- static const TCHAR s_cszIconSpacing[] = TEXT("IconSpacing");
- static const TCHAR s_cszIconTitleWrap[] = TEXT("IconTitleWrap");
- static const TCHAR s_cszIconVerticalSpacing[] = TEXT("IconVerticalSpacing");
- static const int s_ciStandardOldIconSpacing = 75;
- static const int s_ciStandardNewIconSpacing = -1125;
- HKEY hKeyDesktop, hKeyWindowMetrics;
- hKeyDesktop = hKeyWindowMetrics = NULL;
- if ((ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
- TEXT("Control Panel\Desktop"),
- 0,
- KEY_ALL_ACCESS,
- &hKeyDesktop)) &&
- (ERROR_SUCCESS == RegOpenKeyEx(hKeyDesktop,
- TEXT("WindowMetrics"),
- 0,
- KEY_ALL_ACCESS,
- &hKeyWindowMetrics)))
- {
- int iIconSpacing, iIconTitleWrap, iIconVerticalSpacing;
- // 1. Read the values that we wish the move and adjust.
- iIconSpacing = GetRegistryStringValueAsInteger(hKeyDesktop, s_cszIconSpacing, s_ciStandardOldIconSpacing);
- iIconTitleWrap = GetRegistryStringValueAsInteger(hKeyDesktop, s_cszIconTitleWrap, 1);
- iIconVerticalSpacing = GetRegistryStringValueAsInteger(hKeyDesktop, s_cszIconVerticalSpacing, s_ciStandardOldIconSpacing);
- // 2. Perform the adjustment.
- iIconSpacing = s_ciStandardNewIconSpacing * iIconSpacing / s_ciStandardOldIconSpacing;
- iIconVerticalSpacing = s_ciStandardNewIconSpacing * iIconVerticalSpacing / s_ciStandardOldIconSpacing;
- // 3. Write the values back out in the new (moved) location.
- SetRegistryIntegerAsStringValue(hKeyWindowMetrics, s_cszIconSpacing, iIconSpacing);
- SetRegistryIntegerAsStringValue(hKeyWindowMetrics, s_cszIconTitleWrap, iIconTitleWrap);
- SetRegistryIntegerAsStringValue(hKeyWindowMetrics, s_cszIconVerticalSpacing, iIconVerticalSpacing);
- // 4. Let winlogon continue processing hiveusd.inx and delete the
- // old entries in the process. We already created the new entries
- // and that has been removed from hiveusd.inx.
- }
- if (hKeyWindowMetrics != NULL)
- TW32(RegCloseKey(hKeyWindowMetrics));
- if (hKeyDesktop != NULL)
- TW32(RegCloseKey(hKeyDesktop));
- return(S_OK);
- }
- extern "C" STDAPI FirstUserLogon (LPCSTR pcszCommand, LPCSTR pcszOptionalArguments)
- {
- enum
- {
- kCommandCopySampleJPG,
- kCommandMergeDesktopAndNormalStreams,
- kCommandMoveAndAdjustIconMetrics
- };
- typedef struct
- {
- LPCSTR pcszCommand;
- int iCommand;
- } tCommandElement;
- tCommandElement sCommands[] =
- {
- { "CopySampleJPG", kCommandCopySampleJPG },
- { "MergeDesktopAndNormalStreams", kCommandMergeDesktopAndNormalStreams },
- { "MoveAndAdjustIconMetrics", kCommandMoveAndAdjustIconMetrics },
- };
- HRESULT hResult;
- int i;
- // Match what shmgrate.exe passed us and execute the command.
- // Only use the optional argument if required. Note this is
- // done ANSI because the original command line is ANSI from
- // shmgrate.exe.
- for (i = 0; (i < ARRAYSIZE(sCommands)) && (lstrcmpA(pcszCommand, sCommands[i].pcszCommand) != 0); ++i)
- ;
- switch (sCommands[i].iCommand)
- {
- case kCommandCopySampleJPG:
- hResult = CopySampleJPG();
- break;
- case kCommandMergeDesktopAndNormalStreams:
- hResult = MergeDesktopAndNormalStreams();
- break;
- case kCommandMoveAndAdjustIconMetrics:
- hResult = MoveAndAdjustIconMetrics();
- break;
- default:
- hResult = E_FAIL;
- break;
- }
- return(hResult);
- }
- #ifdef INSTALL_WEBFOLDERS
- //
- // WebFolders namespace extension installation.
- // This is the code that initially installs the Office WebFolders
- // shell namespace extension on the computer. Code in shmgrate.exe
- // (see privatewindowsshellmigrate) performs per-user
- // web folders registration duties.
- //
- typedef UINT (WINAPI * PFNMSIINSTALLPRODUCT)(LPCTSTR, LPCTSTR);
- typedef INSTALLUILEVEL (WINAPI * PFNMSISETINTERNALUI)(INSTALLUILEVEL, HWND *);
- #define GETPROC(var, hmod, ptype, fn) ptype var = (ptype)GetProcAddress(hmod, fn)
- #define API_MSISETINTERNALUI "MsiSetInternalUI"
- #ifdef UNICODE
- # define API_MSIINSTALLPRODUCT "MsiInstallProductW"
- #else
- # define API_MSIINSTALLPRODUCT "MsiInstallProductA"
- #endif
- typedef struct _WEBFOLDER_INSTALL_RETRY_STRUCT {
- HMODULE hmod;
- PFNMSISETINTERNALUI pfnMsiSetInternalUI;
- PFNMSIINSTALLPRODUCT pfnMsiInstallProduct;
- } WEBFOLDER_INSTALL_RETRY_STRUCT;
- void WebFolder_Install_RetryThreadProc(WEBFOLDER_INSTALL_RETRY_STRUCT * pwirs)
- {
- ASSERT(pwirs);
- ASSERT(pwirs->hmod);
- ASSERT(pwirs->pfnMsiSetInternalUI);
- ASSERT(pwirs->pfnMsiInstallProduct);
- TCHAR szPath[MAX_PATH];
- UINT uRet = 0;
- INSTALLUILEVEL oldUILevel = pwirs->pfnMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
- do {
- GetSystemDirectory(szPath, ARRAYSIZE(szPath));
- PathAppend(szPath, TEXT("webfldrs.msi"));
- uRet = pwirs->pfnMsiInstallProduct(szPath, TEXT(""));
- } while (uRet == ERROR_INSTALL_ALREADY_RUNNING);
- pwirs->pfnMsiSetInternalUI(oldUILevel, NULL);
- DllRelease();
- FreeLibrary(pwirs->hmod);
- LocalFree(pwirs);
- }
- void OfficeWebFolders_Install(void)
- {
- HMODULE hmod = LoadLibrary(TEXT("msi.dll"));
- if (hmod)
- {
- BOOL bFreeLib = FALSE;
- GETPROC(pfnMsiSetInternalUI, hmod, PFNMSISETINTERNALUI, API_MSISETINTERNALUI);
- GETPROC(pfnMsiInstallProduct, hmod, PFNMSIINSTALLPRODUCT, API_MSIINSTALLPRODUCT);
- if (pfnMsiSetInternalUI && pfnMsiInstallProduct)
- {
- TCHAR szPath[MAX_PATH];
- GetSystemDirectory(szPath, ARRAYSIZE(szPath));
- PathAppend(szPath, TEXT("webfldrs.msi"));
- //
- // Use "silent" install mode. No UI.
- //
- INSTALLUILEVEL oldUILevel = pfnMsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
- //
- // Install the web folders MSI package.
- //
- if (pfnMsiInstallProduct(szPath, TEXT("")) == ERROR_INSTALL_ALREADY_RUNNING)
- {
- WEBFOLDER_INSTALL_RETRY_STRUCT * pwirs = (WEBFOLDER_INSTALL_RETRY_STRUCT *)LocalAlloc(LPTR, SIZEOF(WEBFOLDER_INSTALL_RETRY_STRUCT));
- if (pwirs)
- {
- DWORD thid; // Not used but we have to pass something in
- pwirs->hmod = hmod;
- pwirs->pfnMsiSetInternalUI = pfnMsiSetInternalUI;
- pwirs->pfnMsiInstallProduct = pfnMsiInstallProduct;
- DllAddRef();
- HANDLE hthreadWorker = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE)WebFolder_Install_RetryThreadProc,
- (LPVOID)pwirs, CREATE_SUSPENDED, &thid);
- if (hthreadWorker)
- {
- // Demote the priority so it doesn't interfere with the
- SetThreadPriority(hthreadWorker, THREAD_PRIORITY_BELOW_NORMAL);
- ResumeThread(hthreadWorker);
- bFreeLib = FALSE;
- }
- else
- {
- DllRelease();
- LocalFree(pwirs);
- }
- }
- }
- pfnMsiSetInternalUI(oldUILevel, NULL);
- }
- if (bFreeLib)
- FreeLibrary(hmod);
- }
- }
- #endif // INSTALL_WEBFOLDERS
- #ifdef WINNT
- // now is the time on sprockets when we lock down the registry
- STDAPI_(BOOL) ApplyRegistrySecurity()
- {
- BOOL fSuccess = FALSE; // assume failure
- SECURITY_DESCRIPTOR* psd;
- SHELL_USER_PERMISSION supEveryone;
- SHELL_USER_PERMISSION supSystem;
- SHELL_USER_PERMISSION supAdministrators;
- PSHELL_USER_PERMISSION aPerms[3] = {&supEveryone, &supSystem, &supAdministrators};
- // we want the "Everyone" to have read access
- supEveryone.susID = susEveryone;
- supEveryone.dwAccessType = ACCESS_ALLOWED_ACE_TYPE;
- supEveryone.dwAccessMask = KEY_READ;
- supEveryone.fInherit = TRUE;
- supEveryone.dwInheritMask = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
- supEveryone.dwInheritAccessMask = GENERIC_READ;
- // we want the "SYSTEM" to have full control
- supSystem.susID = susSystem;
- supSystem.dwAccessType = ACCESS_ALLOWED_ACE_TYPE;
- supSystem.dwAccessMask = KEY_ALL_ACCESS;
- supSystem.fInherit = TRUE;
- supSystem.dwInheritMask = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
- supSystem.dwInheritAccessMask = GENERIC_ALL;
- // we want the "Administrators" to have full control
- supAdministrators.susID = susAdministrators;
- supAdministrators.dwAccessType = ACCESS_ALLOWED_ACE_TYPE;
- supAdministrators.dwAccessMask = KEY_ALL_ACCESS;
- supAdministrators.fInherit = TRUE;
- supAdministrators.dwInheritMask = (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
- supAdministrators.dwInheritAccessMask = GENERIC_ALL;
- psd = GetShellSecurityDescriptor(aPerms, ARRAYSIZE(aPerms));
- if (psd)
- {
- HKEY hkLMBitBucket;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer\BitBucket"), 0, KEY_ALL_ACCESS, &hkLMBitBucket) == ERROR_SUCCESS)
- {
- if (RegSetKeySecurity(hkLMBitBucket, DACL_SECURITY_INFORMATION, psd) == ERROR_SUCCESS)
- {
- // victory is mine!
- fSuccess = TRUE;
- }
- RegCloseKey(hkLMBitBucket);
- }
- LocalFree(psd);
- }
- return fSuccess;
- }
- #endif // WINNT
- CComModule _Module;
- BEGIN_OBJECT_MAP(ObjectMap)
- // nothing in here, use clsobj.c class table instead
- END_OBJECT_MAP()
- // ATL DllMain, needed to support our ATL classes that depend on _Module
- // REVIEW: confirm that _Module is really needed
- STDAPI_(BOOL) ATL_DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
- {
- if (dwReason == DLL_PROCESS_ATTACH)
- {
- _Module.Init(ObjectMap, hInstance);
- }
- else if (dwReason == DLL_PROCESS_DETACH)
- {
- _Module.Term();
- }
- return TRUE; // ok
- }