Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

273 lines
6.4 KiB

//+-------------------------------------------------------------------------
//
// 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 <tchar.h>
#include <shlobj.h>
#include <oleguid.h>
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