//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997 - 1997. // // File: shlink.cxx // // Contents: Utility stuff for shell links // // History: 10-Sep-97 dlee Created mostly from IIS setup code // //-------------------------------------------------------------------------- #include "pch.cxx" #pragma hdrstop #include #include #include BOOL DoesFileExist(LPCTSTR szFile) { return (GetFileAttributes(szFile) != 0xFFFFFFFF); } BOOL IsDirEmpty( WCHAR const * pwcDir ) { WIN32_FIND_DATA FindData; HANDLE hFind; BOOL bFindFile = TRUE; BOOL fReturn = TRUE; WCHAR awc[ MAX_PATH ]; unsigned cwc = wcslen( pwcDir ) + 4; if ( cwc >= MAX_PATH ) return TRUE; wcscpy( awc, pwcDir ); wcscat( awc, L"\\*.*" ); hFind = FindFirstFile( awc, &FindData ); while((INVALID_HANDLE_VALUE != hFind) && bFindFile) { if(*(FindData.cFileName) != _T('.')) { fReturn = FALSE; break; } //find the next file bFindFile = FindNextFile(hFind, &FindData); } FindClose (hFind ); return fReturn; } //IsDirEmpty //+------------------------------------------------------------------------- // // Function: CreateShellDirectoryTree // // Synopsis: Creates as many directories as is necessary // // Arguments: pwc -- the directory to create // // Returns: Win32 Error Code // // Notes: Directories are created up to the last backslash // // History: 8-Jan-97 dlee Created // //-------------------------------------------------------------------------- DWORD CreateShellDirectoryTree( WCHAR const *pwcIn ) { WCHAR awc[MAX_PATH]; WCHAR * pwc = awc; if ( wcslen( pwcIn ) >= ( MAX_PATH - 5 ) ) return ERROR_INVALID_PARAMETER; wcscpy( pwc, pwcIn ); unsigned cwc = wcslen( pwc ); if ( (cwc > 0) && (cwc < ((sizeof awc / sizeof WCHAR) - 1)) && (pwc[cwc-1] != L'\\') ) { wcscat( pwc, L"\\" ); } WCHAR *pwcStart = pwc; if ( *pwc == L'\\' && *(pwc+1) == L'\\' ) { pwc += 2; // get past machine name while ( *pwc && *pwc != '\\' ) pwc++; // get past slash if ( *pwc ) pwc++; // get past share name while ( *pwc && *pwc != '\\' ) pwc++; } else if ( *(pwc+1) == L':' ) pwc += 2; // get to the first directory name while ( *pwc == L'\\' ) pwc++; while ( *pwc ) { if ( *pwc == L'\\' ) { *pwc = 0; if (! CreateDirectory( pwcStart, 0 ) ) { DWORD dw = GetLastError(); if ( ERROR_ALREADY_EXISTS != dw ) return dw; } *pwc = L'\\'; } pwc++; } return NO_ERROR; } //CreateShellDirectoryTree HRESULT MyCreateLink(LPCTSTR lpszProgram, LPCTSTR lpszArgs, LPCTSTR lpszLink, LPCTSTR lpszDir, LPCTSTR lpszIconPath, int iIconIndex) { HRESULT hres; IShellLink* pShellLink; //CoInitialize must be called before this // Get a pointer to the IShellLink interface. hres = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&pShellLink ); if (SUCCEEDED(hres)) { IPersistFile* pPersistFile; // Set the path to the shortcut target, and add the description. pShellLink->SetPath(lpszProgram); pShellLink->SetArguments(lpszArgs); pShellLink->SetWorkingDirectory(lpszDir); pShellLink->SetIconLocation(lpszIconPath, iIconIndex); // Query IShellLink for the IPersistFile interface for saving the // shortcut in persistent storage. hres = pShellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&pPersistFile); if (SUCCEEDED(hres)) { WCHAR wsz[MAX_PATH]; lstrcpyn(wsz, lpszLink, sizeof wsz / sizeof WCHAR); // Save the link by calling IPersistFile::Save. hres = pPersistFile->Save(wsz, TRUE); pPersistFile->Release(); } pShellLink->Release(); } else { isDebugOut(( "createlink can't create instance: 0x%x\n", hres )); isDebugOut(( "!!!likely some k2 partner component left OLE " "initialized in an incompatible state!!!\n" )); } return hres; } BOOL MyDeleteLink(LPTSTR lpszShortcut) { // // Don't try to delete what doesn't exist // if ( !DoesFileExist( lpszShortcut ) ) { isDebugOut(( "deletelink: '%ws' doesn't exist\n", lpszShortcut )); return TRUE; } TCHAR szFile[_MAX_PATH]; SHFILEOPSTRUCT fos; ZeroMemory(szFile, sizeof(szFile)); lstrcpyn(szFile, lpszShortcut, sizeof szFile / sizeof TCHAR); ZeroMemory(&fos, sizeof(fos)); fos.hwnd = NULL; fos.wFunc = FO_DELETE; fos.pFrom = szFile; fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION; SHFileOperation(&fos); return TRUE; } void AddShellLink( WCHAR const * pwcGroupPath, WCHAR const * pwcName, WCHAR const * pwcProgram, WCHAR const * pwcArgs ) { if ( !DoesFileExist( pwcGroupPath ) ) { CreateShellDirectoryTree( pwcGroupPath ); SHChangeNotify( SHCNE_MKDIR, SHCNF_PATH, pwcGroupPath, 0 ); } unsigned cwc = wcslen( pwcGroupPath ) + 1 + wcslen( pwcName ) + wcslen( L".lnk" ); if ( cwc >= MAX_PATH ) return; WCHAR awcPath[ MAX_PATH ]; wcscpy( awcPath, pwcGroupPath ); wcscat( awcPath, L"\\" ); wcscat( awcPath, pwcName ); wcscat( awcPath, L".lnk" ); MyCreateLink( pwcProgram, pwcArgs, awcPath, 0, 0, 0 ); } //AddShellLink void DeleteShellLink( WCHAR const * pwcGroupPath, WCHAR const * pwcName ) { unsigned cwc = wcslen( pwcGroupPath ) + 1 + wcslen( pwcName ) + wcslen( L".lnk" ); if ( cwc >= MAX_PATH ) return; WCHAR awcPath[ MAX_PATH ]; wcscpy( awcPath, pwcGroupPath ); wcscat( awcPath, L"\\" ); wcscat( awcPath, pwcName ); wcscat( awcPath, L".lnk" ); MyDeleteLink( awcPath ); if ( IsDirEmpty( pwcGroupPath ) ) { RemoveDirectory( pwcGroupPath ); SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, pwcGroupPath, 0); } } //DeleteShellLink