www.pudn.com > FTP¿Í»§¶Ë³ÌÐòµÄÔ´³ÌÐò.zip > Extra.h
// Copyright © 1999 Ziff-Davis, Inc.
// Written by Ignacio Alvarez
static BOOL CALLBACK EnumWProc(HWND hwnd, LPARAM lParam)
{
char CName[MAX_PATH];
BOOL* Visible = (BOOL*) lParam; // Casts lParam into a BOOL pointer
if(GetClassName(hwnd, CName, MAX_PATH))
if(!strcmp(CName, "BaseBar")) // Checks if the window is of class BaseBar
if(IsWindowVisible(hwnd)) // Checks if it's visible
{
*Visible = TRUE; // Sets Visible to TRUE, indicating it found a visible BaseBar window
return FALSE; // Returns FALSE to stop the enumeration
}
return TRUE;
}
// This is the CLSID of the Folder Pointers
static const char* guid = "{FA6C62A0-9FE5-11D2-9E61-444553540000}";
// This function returns TRUE if it's running in NT
static BOOL IsWinNT(void)
{
OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof(os);
GetVersionEx(&os);
return (os.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
// This Function returns TRUE if Internet Explorer 4 is installed
static BOOL IsIE4(void)
{
HKEY key;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ, &key);
RegOpenKeyEx(key, "Microsoft", 0, KEY_READ, &key);
RegOpenKeyEx(key, "Internet Explorer", 0, KEY_READ, &key);
char IEversion[MAX_PATH];
DWORD IEsize = MAX_PATH;
DWORD IEtype;
if(!RegQueryValueEx(key, "Version", 0, &IEtype, (unsigned char *)IEversion, &IEsize))
if(IEtype = REG_SZ)
if(IEversion[0] > '4') // Determines version of Internet Explorer, if it's higher than 4, the shortcut isn't going to be created
return FALSE;
RegCloseKey(key);
return TRUE;
}
// This Function returns TRUE if the folder is a FOLDER POINTER
static BOOL IsFolderPointer(const char* Folder)
{
char F[MAX_PATH], temp[MAX_PATH];
char* Ext = PathFindExtension(Folder); // Searches for an extension
if(*Ext == '.')
Ext++;
if(!stricmp(guid, Ext)) // Checks if the folder is of the form "Desktop.{FA6C62A0-9FE5-11D2-9E61-444553540000}"
return TRUE;
if(PathIsSystemFolder(Folder, 0)) // Checks if it is a System folder
{
wsprintf(F, "%s\\Desktop.ini", Folder);
GetPrivateProfileString(".ShellClassInfo", "CLSID", NULL, temp, MAX_PATH, F); // Tries to open the ini file and read ".ShellClassInfo"
return !strcmpi(temp, guid); // If the CLSIDs match, it returns TRUE
}
return FALSE;
}
// These static variables are used all through the program, they include the locations
// of several special Windows folders, and the DLL name in its short form
static char WinDir[MAX_PATH], SysDir[MAX_PATH], StartDir[MAX_PATH], dllName[MAX_PATH], dllPath[MAX_PATH];
// This function initializes the above variables
static void ReadFolders()
{
LPMALLOC ShellMalloc;
LPITEMIDLIST FolderID;
GetWindowsDirectory(WinDir, MAX_PATH); // Retrieves the location of the Windows directory and stores it in WinDir
GetSystemDirectory(SysDir, MAX_PATH); // Retrieves the location of the System directory and stores it in SysDir
SHGetMalloc(&ShellMalloc);
__try
{
SHGetSpecialFolderLocation(0, CSIDL_STARTMENU, &FolderID);
SHGetPathFromIDList(FolderID, StartDir); // Retrieves the location of the Start menu and stores it in StartDir
ShellMalloc->Free(FolderID);
}
__finally
{
ShellMalloc->Release();
}
char Path[MAX_PATH];
GetModuleFileName(_Module.m_hInst, Path, MAX_PATH); // Retrieves the filename of the DLL
GetShortPathName(Path, dllName, MAX_PATH); // Retrieves the short name of the DLL and stores it in dllName
strcpy(dllPath, dllName);
PathRemoveFileSpec(dllPath);
PathAddBackslash(dllPath);
}
// This function returns TRUE if the folder is located inside any Start Menu of any profile
static BOOL InStartMenu(const char* Folder)
{
char Path[MAX_PATH];
ReadFolders();
if(PathIsPrefix(StartDir, Folder)) // Checks if the Start Menu directory of the current profile, is a prefix of the folder path
return TRUE;
wsprintf(Path, "%s\\Profiles", WinDir);
if(strlen(Folder) > strlen(Path))
if(PathIsPrefix(Path, Folder)) // Checks if the folder is inside the Profiles directory
{
Folder += strlen(Path) + 1;
while((*Folder != 0) && (*Folder++ != '\\'));
if(PathIsPrefix("Start Menu", Folder)) // Checks if the folder is inside a Start Menu
return TRUE;
}
return FALSE;
}
// This function receives the name for a Folder Pointer and the PIDL of its target folder, and creates a new Folder Pointer
static void CreatePointer(const char* Folder, LPITEMIDLIST FolderID)
{
__try
{
IShellLink* psl;
LPPERSISTFILE ppf;
WCHAR Shortcut[MAX_PATH];
char Path[MAX_PATH], Path2[MAX_PATH];
int i = 2;
strcpy(Path, Folder);
while(PathFileExists(Path)) // loops until it finds an available folder name (i.e. Desktop, Desktop (2), Desktop (3))
wsprintf(Path,"%s (%d)", Folder, i++);
CoInitialize(NULL);
__try
{
CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl); // Instantiates the shortcut
psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
CreateDirectory(Path, NULL);// Creates the folder that is going to serve as the junction point for the Folder Pointer
wsprintf(Path2, "%s\\Desktop.ini", Path);
WritePrivateProfileString(".ShellClassInfo", "CLSID", guid, Path2); // Writes the ini file that tells Windows that this is a virtual folder
SetFileAttributes(Path, FILE_ATTRIBUTE_SYSTEM); // Sets the System attribute of the folder
wsprintf(Path2, "%s\\Folder.lnk", Path);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Path2, strlen(Path2) + 1, Shortcut, MAX_PATH);
psl->SetIDList(FolderID); // Sets the target location of the shortcut to the folder for which a Folder Pointer is being created
ppf->Save(Shortcut, TRUE); // Saves the shortcut
ppf->Release();
psl->Release();
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATH | SHCNF_FLUSH, Path, NULL);
}
__finally
{
CoUninitialize();
}
}
__except(1)
{
MessageBox(0, "Folder Pointer creation error.", NULL, MB_OK);
}
}
// This function is called externally by the New Folder Pointer command, using Rundll32
void CALLBACK NewPointer(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
__try
{
BROWSEINFO BrowseInfo;
LPMALLOC ShellMalloc;
LPITEMIDLIST FolderID;
char DisplayName[MAX_PATH], DisplayStr[MAX_PATH], Folder[MAX_PATH], Path[MAX_PATH];
strcpy(Folder, lpszCmdLine);
PathRemoveFileSpec(Folder);
if(!InStartMenu(Folder)) // Checks if the Folder is inside a Start Menu
MessageBox(hwnd, "You can only have Folder Pointers inside the Start Menu.", "Folder Pointers", MB_ICONERROR | MB_OK);
else
{
SHGetMalloc(&ShellMalloc);
__try
{
ZeroMemory(&BrowseInfo, sizeof(BrowseInfo));
BrowseInfo.lpszTitle = "Select the folder for which you want to create a Folder Pointer:";
BrowseInfo.pszDisplayName = DisplayName;
FolderID = SHBrowseForFolder(&BrowseInfo); // Displays the Browse for Folder dialog
if(FolderID)
{
int j = 0;
for(UINT i = 0; i < strlen(DisplayName); i++) // Looks for any illegal characters in the Folder Pointer name, and deletes them
if ((DisplayName[i] != '\\') &&
(DisplayName[i] != '/') &&
(DisplayName[i] != ':') &&
(DisplayName[i] != '*') &&
(DisplayName[i] != '?') &&
(DisplayName[i] != '"') &&
(DisplayName[i] != '<') &&
(DisplayName[i] != '>') &&
(DisplayName[i] != '|'))
DisplayStr[j++] = DisplayName[i];
DisplayStr[j] = 0;
wsprintf(Path, "%s\\%s", Folder, DisplayStr);
CreatePointer(Path, FolderID); // Calls CreatePointer, passing it the name of the Folder Pointer and a PIDL to the target folder
}
ShellMalloc->Free(FolderID);
}
__finally
{
ShellMalloc->Release();
}
}
}
__except(1)
{
MessageBox(hwnd, "New Folder Pointer error.", NULL, MB_OK);
}
}
// This function adds the Refresh Start Menu shortcut, and the Desktop Folder Pointer to the Start Menu
static void CreateIcons(BOOL FullInstall)
{
__try
{
IShellLink* psl;
LPPERSISTFILE ppf;
WCHAR Shortcut[MAX_PATH];
char Path[MAX_PATH], ShortcutPath[MAX_PATH], Desktop[MAX_PATH];
WORD HotKey;
ReadFolders(); // This function reads the location of several Windows folders and stores them in static variables
wsprintf(Desktop, "%s\\Desktop", StartDir); // Sets the location of the Desktop Folder Pointer inside the Start Menu
if(!IsFolderPointer(Desktop))
{
LPMALLOC ShellMalloc;
LPITEMIDLIST FolderID;
SHGetMalloc(&ShellMalloc);
__try
{
SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &FolderID); // Gets the PIDL of the Desktop folder
CreatePointer(Desktop, FolderID); // Creates the Desktop Folder Pointer
ShellMalloc->Free(FolderID);
}
__finally
{
ShellMalloc->Release();
}
}
if(IsIE4()) // Checks for Internet Explorer 4
{
CoInitialize(NULL);
__try
{
CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl); // Instantiates the shortcut
psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
wsprintf(Path, "%s\\Refresh Start Menu.lnk", StartDir); // Sets the name of the shortcut
strcpy(ShortcutPath, Path);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Path, strlen(Path) + 1, Shortcut, MAX_PATH);
if(IsWinNT())
strcpy(Path, SysDir);
else
strcpy(Path, WinDir);
strcat(Path, "\\RunDLL32.exe"); // Sets the target of the shortcut to Rundll32
psl->SetPath(Path);
HotKey = ((HOTKEYF_CONTROL | HOTKEYF_SHIFT) << 8) | (byte)'R'; // Set the default shortcut key to Ctrl + Shift + R
psl->SetHotkey(HotKey);
psl->SetIconLocation(dllName, 0); // Sets the icon to the green arrow located inside the DLL
wsprintf(Path, "%s,RefreshMenu", dllName);
psl->SetArguments(Path); // Sets the arguments to FPointer.dll,RefreshMenu
ppf->Save(Shortcut, TRUE); // Saves the shortcut
ppf->Release();
psl->Release();
SHChangeNotify(SHCNE_CREATE, SHCNF_PATH | SHCNF_FLUSH, ShortcutPath, NULL); // Notify the shell that the shortcut has been created
}
__finally
{
CoUninitialize();
}
}
char msg[MAX_PATH];
if(FullInstall) // Uses this message if it was a full install
strcpy(msg, "Folder Pointers has been successfully installed.");
else // Uses this message if only the Desktop Folder Pointer has been added to the Start Menu
strcpy(msg, "Default items installed.");
strcat(msg, "\n\nTo view the help file at any time, right-click the Start button and choose Help from the Folder Pointers submenu.\n\nYou can also view the help file now. Do you want to view the help file now?");
if(MessageBox(0, msg, "Folder Pointers", MB_ICONINFORMATION | MB_YESNO) == IDYES) // Asks the user if he wants to view the help file
{
wsprintf(Path, "%sFPointer.hlp", dllPath);
ShellExecute(0, "open", Path, NULL, NULL, SW_SHOWNORMAL); // Opens the help file
}
}
__except(1)
{
MessageBox(0, "Folder Pointers Installation error.", NULL, MB_OK);
}
}
// This function is called by the Setup program after it finishes copying the files
void CALLBACK Install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
__try
{
DllRegisterServer(); // Registers the DLL
CreateIcons(TRUE); // Calls CreateIcons passing it TRUE, indicating it is a full install
}
__except(1)
{
MessageBox(hwnd, "Folder Pointers Installation error.", NULL, MB_OK);
}
}
// This is a recursive function that searches the Start Menu for Folder Pointers and removes them
void SearchFolder(const char* Folder)
{
WIN32_FIND_DATA Info;
char F[MAX_PATH];
wsprintf(F, "%s\\*.*", Folder);
HANDLE hFind = FindFirstFile(F, &Info); // Looks for first file matching *.*
if(hFind != INVALID_HANDLE_VALUE)
{
do
{
if(Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // Checks to see if it is a folder
if(!(!strcmpi(Info.cFileName, ".") || !strcmpi(Info.cFileName, "..")))
{
wsprintf(F, "%s\\%s", Folder, Info.cFileName);
if(IsFolderPointer(F)) // Checks to see if it is a Folder Pointer
{
SetFileAttributes(F, FILE_ATTRIBUTE_NORMAL); // Removes the System attribute from the folder
wsprintf(F, "%s\\%s\\Folder.lnk", Folder, Info.cFileName);
DeleteFile(F); // Deletes the shortcut
wsprintf(F, "%s\\%s\\Desktop.ini", Folder, Info.cFileName);
DeleteFile(F); // Deletes the ini file
wsprintf(F, "%s\\%s", Folder, Info.cFileName);
RemoveDirectory(F); // Removes the empty folder
}
else // If it's not a Folder Pointer, it recursively calls itself to search the folder
SearchFolder(F);
}
}
while(FindNextFile(hFind, &Info)); // loop until there are no more files
FindClose(hFind);
}
}
// This function is called using Rundll32, when the user double-clicks the Folder
// Pointers name in the Add/Remove Programs applet in Control Panel
void CALLBACK Uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
__try
{
DllUnregisterServer();
char Path[MAX_PATH];
ReadFolders();
SearchFolder(StartDir); // Removes all Folder Pointers from the Start Menu
wsprintf(Path, "%s\\Profiles", WinDir);
SearchFolder(Path); // Removes all Folder Pointers from all Profiles
wsprintf(Path, "%s\\Refresh Start Menu.lnk", StartDir);
DeleteFile(Path); // Deletes the Refresh shortcut
SHChangeNotify(SHCNE_DELETE, SHCNF_PATH | SHCNF_FLUSH, Path, NULL);
wsprintf(Path, "%sFPointer.hlp", dllPath);
DeleteFile(Path); // Deletes the Help file and all its related files
wsprintf(Path, "%sFPointer.cnt", dllPath);
DeleteFile(Path);
wsprintf(Path, "%sFPointer.gid", dllPath);
DeleteFile(Path);
if(IsWinNT()) // If it's running in NT, it uses MoveFileEx to delete the DLL when Windows restarts
MoveFileEx(dllName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
else // Otherwise it uses WinInit.ini to delete the DLL when Windows restarts
WritePrivateProfileString("Rename", "NUL", dllName, "WinInit.ini");
MessageBox(hwnd, "The Folder Pointers library will be removed the next time you start Windows.", "Folder Pointers", MB_ICONINFORMATION | MB_OK);
}
__except(1)
{
MessageBox(hwnd, "Folder Pointers uninstall error.", NULL, MB_OK);
}
}
// This function is called by the Refresh Start Menu shortcut, using Rundll32
void CALLBACK RefreshMenu(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, NULL, NULL);
}
// This function calculates the size in bytes of a PIDL
static int sizeofPIDL(LPCITEMIDLIST pidl)
{
int i = 0;
LPBYTE pb = (LPBYTE) pidl;
if(pidl)
{
LPSHITEMID id;
id = (LPSHITEMID)pidl;
while(id->cb > 0)
{
i += id->cb;
pb += id->cb;
id = (LPSHITEMID) pb;
}
i += 2;
}
return i;
}