#include <stdio.h>
#include <shlobj.h>
#include <shlwapi.h>
bool __fastcall CreateShortCut(LPWSTR pwzShortCutFileName, LPCITEMIDLIST pidl,
LPTSTR pszWorkingDirectory, WORD wHotKey, int iCmdShow);
int short_cut_startup(char *connection_name, LPWSTR link_name);
LPITEMIDLIST GetNextItemID(LPCITEMIDLIST pidl);
UINT GetSize(LPCITEMIDLIST pidl);
LPITEMIDLIST Append(LPCITEMIDLIST pidlBase, LPCITEMIDLIST pidlAdd);
LPMALLOC pMalloc;
int main(void)
{
if(short_cut_startup("demo", L"demo - connection.lnk"))
printf("Success!\n");
else printf("Can't create shortcut!\n");
return 0;
}
/* Main function which creating shortcut on desktop */
int short_cut_startup(char *connection_name, LPWSTR link_name)
{
LPITEMIDLIST pidConnections = NULL;
LPITEMIDLIST pidlItems = NULL;
LPITEMIDLIST pidlDesk = NULL;
IShellFolder *psfFirstFolder = NULL;
IShellFolder *psfDeskTop = NULL;
IShellFolder *pConnections = NULL;
LPENUMIDLIST ppenum = NULL;
ULONG celtFetched;
HRESULT hr;
STRRET str_curr_connection_name;
TCHAR curr_connection_name[MAX_PATH] = ""; /* Connection point name */
TCHAR desktop_path[MAX_PATH]=""; /* Path to desktop */
TCHAR full_link_name[MAX_PATH]=""; /* Full shortcut name */
LPITEMIDLIST full_pid; /* Full shortcut pid */
CoInitialize( NULL );
/* Allocating memory for Namespace objects */
hr = SHGetMalloc(&pMalloc);
hr = SHGetFolderLocation(NULL, CSIDL_CONNECTIONS, NULL, NULL, &pidConnections);
/* Get full path to desktop */
SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktop_path);
hr = SHGetDesktopFolder(&psfDeskTop);
hr = psfDeskTop->BindToObject(pidConnections, NULL, IID_IShellFolder, (LPVOID *) &pConnections);
hr = pConnections->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &ppenum);
/* Loop for searching our connection */
while(hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1)
{
pConnections->GetDisplayNameOf(pidlItems, SHGDN_INFOLDER, &str_curr_connection_name);
StrRetToBuf(&str_curr_connection_name, pidlItems, curr_connection_name, MAX_PATH);
if(!strcmp(curr_connection_name,connection_name))
goto found;
}
printf("Connection not found in \"Network connections\" folder.\n");
return 0;
found:
/* Append PIDLs */
full_pid=Append(pidConnections,pidlItems);
SetCurrentDirectory(desktop_path);
if(!CreateShortCut(link_name, full_pid, "C:\\windows", 0, SW_SHOWNORMAL))
return 0;
ppenum->Release();
pMalloc->Free(pidlItems);
pMalloc->Free(pidConnections);
pMalloc->Release();
pConnections->Release();
CoUninitialize();
return 1;
}
bool __fastcall CreateShortCut(LPWSTR pwzShortCutFileName, LPCITEMIDLIST pidl,
LPTSTR pszWorkingDirectory, WORD wHotKey, int iCmdShow)
{
IShellLink * pSL;
IPersistFile * pPF;
HRESULT hRes;
hRes = CoCreateInstance(CLSID_ShellLink, 0,CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID *)&pSL);
if( SUCCEEDED(hRes) )
{
hRes=pSL->SetIDList(pidl);
if(SUCCEEDED(hRes))
{
hRes = pSL->SetHotkey(wHotKey);
if( SUCCEEDED(hRes) )
{
hRes = pSL->SetShowCmd(iCmdShow);
if( SUCCEEDED(hRes) )
{
hRes = pSL->QueryInterface(IID_IPersistFile,(LPVOID *)&pPF);
if( SUCCEEDED(hRes) )
{
hRes = pPF->Save(pwzShortCutFileName,TRUE);
pPF->Release();
}
}
}
}
pSL->Release();
}
return SUCCEEDED(hRes);
}
/******************************************************************************/
/* Functions copied from http://msdn.microsoft.com */
LPITEMIDLIST GetNextItemID(LPCITEMIDLIST pidl)
{
// Check for valid pidl.
if(pidl == NULL)
return NULL;
// Get the size of the specified item identifier.
int cb = pidl->mkid.cb;
// If the size is zero, it is the end of the list.
if (cb == 0)
return NULL;
// Add cb to pidl (casting to increment by bytes).
pidl = (LPITEMIDLIST) (((LPBYTE) pidl) + cb);
// Return NULL if it is null-terminating, or a pidl otherwise.
return (pidl->mkid.cb == 0) ? NULL : (LPITEMIDLIST) pidl;
}
/* Get size of PIDL */
UINT GetSize(LPCITEMIDLIST pidl)
{
UINT cbTotal = 0;
if (pidl)
{
cbTotal += sizeof(pidl->mkid.cb); // Terminating null character
while (pidl)
{
cbTotal += pidl->mkid.cb;
pidl = GetNextItemID(pidl);
}
}
return cbTotal;
}
/* Appending PIDLs */
LPITEMIDLIST Append(LPCITEMIDLIST pidlBase, LPCITEMIDLIST pidlAdd)
{
if(pidlBase == NULL)
return NULL;
if(pidlAdd == NULL)
return (LPITEMIDLIST)pidlBase;
LPITEMIDLIST pidlNew;
UINT cb1 = GetSize(pidlBase) - sizeof(pidlBase->mkid.cb);
UINT cb2 = GetSize(pidlAdd);
pidlNew = (LPITEMIDLIST)pMalloc->Alloc(cb1 + cb2);
if (pidlNew)
{
CopyMemory(pidlNew, pidlBase, cb1);
CopyMemory(((LPSTR)pidlNew) + cb1, pidlAdd, cb2);
}
return pidlNew;
}