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; 
}