static HRESULT WINAPI MSTASK_ITaskScheduler_AddWorkItem(ITaskScheduler *iface, LPCWSTR name, IScheduledWorkItem *item) { static const WCHAR tasksW[] = { '\\','T','a','s','k','s','\\',0 }; static const WCHAR jobW[] = { '.','j','o','b',0 }; WCHAR task_name[MAX_PATH]; IPersistFile *pfile; HRESULT hr; TRACE("%p, %s, %p\n", iface, debugstr_w(name), item); if (strchrW(name, '.')) return E_INVALIDARG; GetWindowsDirectoryW(task_name, MAX_PATH); lstrcatW(task_name, tasksW); lstrcatW(task_name, name); lstrcatW(task_name, jobW); hr = IScheduledWorkItem_QueryInterface(item, &IID_IPersistFile, (void **)&pfile); if (hr == S_OK) { hr = IPersistFile_Save(pfile, task_name, TRUE); IPersistFile_Release(pfile); } return hr; }
VOID SetupCreateLink( _In_ PWSTR LinkFilePath, _In_ PWSTR FilePath, _In_ PWSTR FileParentDir ) { IShellLink* shellLinkPtr = NULL; IPersistFile* persistFilePtr = NULL; if (FAILED(CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, &shellLinkPtr))) goto CleanupExit; if (FAILED(IShellLinkW_QueryInterface(shellLinkPtr, &IID_IPersistFile, &persistFilePtr))) goto CleanupExit; // Load existing shell item if it exists... //IPersistFile_Load(persistFilePtr, LinkFilePath, STGM_READ) //IShellLinkW_SetDescription(shellLinkPtr, FileComment); IShellLinkW_SetWorkingDirectory(shellLinkPtr, FileParentDir); IShellLinkW_SetIconLocation(shellLinkPtr, FilePath, 0); // Set the shortcut target path... if (FAILED(IShellLinkW_SetPath(shellLinkPtr, FilePath))) goto CleanupExit; // Save the shortcut to the file system... IPersistFile_Save(persistFilePtr, LinkFilePath, TRUE); CleanupExit: if (persistFilePtr) IPersistFile_Release(persistFilePtr); if (shellLinkPtr) IShellLinkW_Release(shellLinkPtr); }
BOOLEAN CreateLink( _In_ PWSTR DestFilePath, _In_ PWSTR FilePath, _In_ PWSTR FileParentDir, _In_ PWSTR FileComment ) { IShellLink* shellLinkPtr = NULL; IPersistFile* persistFilePtr = NULL; BOOLEAN isSuccess = FALSE; __try { if (FAILED(CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, &shellLinkPtr))) __leave; if (FAILED(IShellLinkW_QueryInterface(shellLinkPtr, &IID_IPersistFile, &persistFilePtr))) __leave; // Load existing shell item if it exists... //if (SUCCEEDED(IPersistFile_Load(persistFilePtr, DestFilePath, STGM_READ))) //{ // IShellLinkW_Resolve(shellLinkPtr, NULL, 0); //} IShellLinkW_SetDescription(shellLinkPtr, FileComment); IShellLinkW_SetWorkingDirectory(shellLinkPtr, FileParentDir); IShellLinkW_SetIconLocation(shellLinkPtr, FilePath, 0); // Set the shortcut target path... if (FAILED(IShellLinkW_SetPath(shellLinkPtr, FilePath))) __leave; // Save the shortcut to the file system... if (FAILED(IPersistFile_Save(persistFilePtr, DestFilePath, TRUE))) __leave; isSuccess = TRUE; } __finally { if (persistFilePtr) { IPersistFile_Release(persistFilePtr); } if (shellLinkPtr) { IShellLinkW_Release(shellLinkPtr); } } return isSuccess; }
static HRESULT WINAPI WshShortcut_Save(IWshShortcut *iface) { WshShortcut *This = impl_from_IWshShortcut(iface); IPersistFile *file; HRESULT hr; TRACE("(%p)\n", This); IShellLinkW_QueryInterface(This->link, &IID_IPersistFile, (void**)&file); hr = IPersistFile_Save(file, This->path_link, TRUE); IPersistFile_Release(file); return hr; }
void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails) { HRESULT r; IShellLinkA *sl; IPersistFile *pf; r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkA, (LPVOID*)&sl); lok(r == S_OK, "no IID_IShellLinkA (0x%08x)\n", r); if (r != S_OK) return; if (desc->description) { r = IShellLinkA_SetDescription(sl, desc->description); lok(r == S_OK, "SetDescription failed (0x%08x)\n", r); } if (desc->workdir) { r = IShellLinkA_SetWorkingDirectory(sl, desc->workdir); lok(r == S_OK, "SetWorkingDirectory failed (0x%08x)\n", r); } if (desc->path) { r = IShellLinkA_SetPath(sl, desc->path); lok(SUCCEEDED(r), "SetPath failed (0x%08x)\n", r); } if (desc->pidl) { r = IShellLinkA_SetIDList(sl, desc->pidl); lok(r == S_OK, "SetIDList failed (0x%08x)\n", r); } if (desc->arguments) { r = IShellLinkA_SetArguments(sl, desc->arguments); lok(r == S_OK, "SetArguments failed (0x%08x)\n", r); } if (desc->showcmd) { r = IShellLinkA_SetShowCmd(sl, desc->showcmd); lok(r == S_OK, "SetShowCmd failed (0x%08x)\n", r); } if (desc->icon) { r = IShellLinkA_SetIconLocation(sl, desc->icon, desc->icon_id); lok(r == S_OK, "SetIconLocation failed (0x%08x)\n", r); } if (desc->hotkey) { r = IShellLinkA_SetHotkey(sl, desc->hotkey); lok(r == S_OK, "SetHotkey failed (0x%08x)\n", r); } r = IShellLinkA_QueryInterface(sl, &IID_IPersistFile, (void**)&pf); lok(r == S_OK, "no IID_IPersistFile (0x%08x)\n", r); if (r == S_OK) { LPOLESTR str; if (0) { /* crashes on XP */ IPersistFile_GetCurFile(pf, NULL); } /* test GetCurFile before ::Save */ str = (LPWSTR)0xdeadbeef; r = IPersistFile_GetCurFile(pf, &str); lok(r == S_FALSE || broken(r == S_OK), /* shell32 < 5.0 */ "got 0x%08x\n", r); lok(str == NULL, "got %p\n", str); r = IPersistFile_Save(pf, path, TRUE); if (save_fails) { todo_wine { lok(r == S_OK, "save failed (0x%08x)\n", r); } } else {
int main (int argc, char *argv[]) { char start_folder[MAX_PATH + 1]; int shortcuts_created = 0; int com_available = 1; char modname[MAX_PATH]; const char *prog_name; const char *emacs_path; char *p; int quiet = 0; HRESULT result; IShellLinkA *shortcut; /* If no args specified, use our location to set emacs_path. */ if (argc > 1 && (argv[1][0] == '/' || argv[1][0] == '-') && argv[1][1] == 'q') { quiet = 1; --argc; ++argv; } if (argc > 1) emacs_path = argv[1]; else { if (!GetModuleFileName (NULL, modname, MAX_PATH) || (p = strrchr (modname, '\\')) == NULL) { fprintf (stderr, "fatal error"); exit (1); } *p = 0; /* Set emacs_path to emacs_dir if we are in "%emacs_dir%\bin". */ if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0) { *p = 0; emacs_path = modname; } else { fprintf (stderr, "usage: addpm emacs_path\n"); exit (1); } /* Tell user what we are going to do. */ if (!quiet) { int result; char msg[ MAX_PATH ]; sprintf (msg, "Install Emacs at %s?\n", emacs_path); result = MessageBox (NULL, msg, "Install Emacs", MB_OKCANCEL | MB_ICONQUESTION); if (result != IDOK) { fprintf (stderr, "Install cancelled\n"); exit (1); } } } add_registry (emacs_path); prog_name = "runemacs.exe"; /* Try to install globally. */ if (!SUCCEEDED (CoInitialize (NULL)) || !SUCCEEDED (CoCreateInstance (&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkA, (void **) &shortcut))) { com_available = 0; } if (com_available && SHGetSpecialFolderPath (NULL, start_folder, CSIDL_COMMON_PROGRAMS, 0)) { if (strlen (start_folder) < (MAX_PATH - 20)) { strcat (start_folder, "\\Gnu Emacs"); if (CreateDirectory (start_folder, NULL) || GetLastError () == ERROR_ALREADY_EXISTS) { char full_emacs_path[MAX_PATH + 1]; IPersistFile *lnk; strcat (start_folder, "\\Emacs.lnk"); sprintf (full_emacs_path, "%s\\bin\\%s", emacs_path, prog_name); IShellLinkA_SetPath (shortcut, full_emacs_path); IShellLinkA_SetDescription (shortcut, "GNU Emacs"); result = IShellLinkA_QueryInterface (shortcut, &IID_IPersistFile, (void **) &lnk); if (SUCCEEDED (result)) { wchar_t unicode_path[MAX_PATH]; MultiByteToWideChar (CP_ACP, 0, start_folder, -1, unicode_path, MAX_PATH); if (SUCCEEDED (IPersistFile_Save (lnk, unicode_path, TRUE))) shortcuts_created = 1; IPersistFile_Release (lnk); } } } } if (!shortcuts_created && com_available && SHGetSpecialFolderPath (NULL, start_folder, CSIDL_PROGRAMS, 0)) { /* Ensure there is enough room for "...\GNU Emacs\Emacs.lnk". */ if (strlen (start_folder) < (MAX_PATH - 20)) { strcat (start_folder, "\\Gnu Emacs"); if (CreateDirectory (start_folder, NULL) || GetLastError () == ERROR_ALREADY_EXISTS) { char full_emacs_path[MAX_PATH + 1]; IPersistFile *lnk; strcat (start_folder, "\\Emacs.lnk"); sprintf (full_emacs_path, "%s\\bin\\%s", emacs_path, prog_name); IShellLinkA_SetPath (shortcut, full_emacs_path); IShellLinkA_SetDescription (shortcut, "GNU Emacs"); result = IShellLinkA_QueryInterface (shortcut, &IID_IPersistFile, (void **) &lnk); if (SUCCEEDED (result)) { wchar_t unicode_path[MAX_PATH]; MultiByteToWideChar (CP_ACP, 0, start_folder, -1, unicode_path, MAX_PATH); if (SUCCEEDED (IPersistFile_Save (lnk, unicode_path, TRUE))) shortcuts_created = 1; IPersistFile_Release (lnk); } } } } if (com_available) IShellLinkA_Release (shortcut); /* Need to call uninitialize, even if ComInitialize failed. */ CoUninitialize (); /* Fallback on old DDE method if the above failed. */ if (!shortcuts_created) { DWORD dde = 0; HCONV conversation; HSZ progman; char add_item[MAX_PATH*2 + 100]; DdeInitialize (&dde, (PFNCALLBACK) DdeCallback, APPCMD_CLIENTONLY, 0); progman = DdeCreateStringHandle (dde, "PROGMAN", CP_WINANSI); conversation = DdeConnect (dde, progman, progman, NULL); if (conversation) { DdeCommand ("[CreateGroup (\"Gnu Emacs\")]"); DdeCommand ("[ReplaceItem (Emacs)]"); sprintf (add_item, "[AddItem (\"%s\\bin\\%s\", Emacs)]", emacs_path, prog_name); DdeCommand (add_item); DdeDisconnect (conversation); } DdeFreeStringHandle (dde, progman); DdeUninitialize (dde); } return 0; }
static void test_ReadAndWriteProperties(void) { HRESULT hr; IUniformResourceLocatorA *urlA; IUniformResourceLocatorA *urlAFromFile; WCHAR fileNameW[MAX_PATH]; static const WCHAR shortcutW[] = {'t','e','s','t','s','h','o','r','t','c','u','t','.','u','r','l',0}; WCHAR iconPath[] = {'f','i','l','e',':','/','/','/','C',':','/','a','r','b','i','t','r','a','r','y','/','i','c','o','n','/','p','a','t','h',0}; int iconIndex = 7; char testurl[] = "http://some/bogus/url.html"; PROPSPEC ps[2]; ps[0].ulKind = PRSPEC_PROPID; U(ps[0]).propid = PID_IS_ICONFILE; ps[1].ulKind = PRSPEC_PROPID; U(ps[1]).propid = PID_IS_ICONINDEX; /* Make sure we have a valid temporary directory */ GetTempPathW(MAX_PATH, fileNameW); lstrcatW(fileNameW, shortcutW); hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUniformResourceLocatorA, (void**)&urlA); if (hr == S_OK) { IPersistFile *pf; IPropertyStorage *pPropStgWrite; IPropertySetStorage *pPropSetStg; PROPVARIANT pv[2]; /* We need to set a URL -- IPersistFile refuses to save without one. */ hr = urlA->lpVtbl->SetURL(urlA, testurl, 0); ok(hr == S_OK, "Failed to set a URL. hr=0x%x\n", hr); /* Write this shortcut out to a file so that we can test reading it in again. */ hr = urlA->lpVtbl->QueryInterface(urlA, &IID_IPersistFile, (void **) &pf); ok(hr == S_OK, "Failed to get the IPersistFile for writing. hr=0x%x\n", hr); hr = IPersistFile_Save(pf, fileNameW, TRUE); ok(hr == S_OK, "Failed to save via IPersistFile. hr=0x%x\n", hr); IPersistFile_Release(pf); pv[0].vt = VT_LPWSTR; U(pv[0]).pwszVal = (void *) iconPath; pv[1].vt = VT_I4; U(pv[1]).iVal = iconIndex; hr = urlA->lpVtbl->QueryInterface(urlA, &IID_IPropertySetStorage, (void **) &pPropSetStg); ok(hr == S_OK, "Unable to get an IPropertySetStorage, hr=0x%x\n", hr); hr = IPropertySetStorage_Open(pPropSetStg, &FMTID_Intshcut, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &pPropStgWrite); ok(hr == S_OK, "Unable to get an IPropertyStorage for writing, hr=0x%x\n", hr); hr = IPropertyStorage_WriteMultiple(pPropStgWrite, 2, ps, pv, 0); ok(hr == S_OK, "Unable to set properties, hr=0x%x\n", hr); hr = IPropertyStorage_Commit(pPropStgWrite, STGC_DEFAULT); ok(hr == S_OK, "Failed to commit properties, hr=0x%x\n", hr); pPropStgWrite->lpVtbl->Release(pPropStgWrite); urlA->lpVtbl->Release(urlA); IPropertySetStorage_Release(pPropSetStg); } else skip("could not create a CLSID_InternetShortcut for property tests, hr=0x%x\n", hr); hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUniformResourceLocatorA, (void**)&urlAFromFile); if (hr == S_OK) { IPropertySetStorage *pPropSetStg; IPropertyStorage *pPropStgRead; PROPVARIANT pvread[2]; IPersistFile *pf; LPSTR url = NULL; /* Now read that .url file back in. */ hr = urlAFromFile->lpVtbl->QueryInterface(urlAFromFile, &IID_IPersistFile, (void **) &pf); ok(hr == S_OK, "Failed to get the IPersistFile for reading. hr=0x%x\n", hr); hr = IPersistFile_Load(pf, fileNameW, 0); ok(hr == S_OK, "Failed to load via IPersistFile. hr=0x%x\n", hr); IPersistFile_Release(pf); hr = urlAFromFile->lpVtbl->GetURL(urlAFromFile, &url); ok(hr == S_OK, "Unable to get url from file, hr=0x%x\n", hr); ok(lstrcmp(url, testurl) == 0, "Wrong url read from file: %s\n",url); hr = urlAFromFile->lpVtbl->QueryInterface(urlAFromFile, &IID_IPropertySetStorage, (void **) &pPropSetStg); ok(hr == S_OK, "Unable to get an IPropertySetStorage, hr=0x%x\n", hr); hr = IPropertySetStorage_Open(pPropSetStg, &FMTID_Intshcut, STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStgRead); ok(hr == S_OK, "Unable to get an IPropertyStorage for reading, hr=0x%x\n", hr); hr = IPropertyStorage_ReadMultiple(pPropStgRead, 2, ps, pvread); ok(hr == S_OK, "Unable to read properties, hr=0x%x\n", hr); todo_wine /* Wine doesn't yet support setting properties after save */ { ok(U(pvread[1]).iVal == iconIndex, "Read wrong icon index: %d\n", U(pvread[1]).iVal); ok(lstrcmpW(U(pvread[0]).pwszVal, iconPath) == 0, "Wrong icon path read: %s\n", wine_dbgstr_w(U(pvread[0]).pwszVal)); } PropVariantClear(&pvread[0]); PropVariantClear(&pvread[1]); IPropertyStorage_Release(pPropStgRead); IPropertySetStorage_Release(pPropSetStg); urlAFromFile->lpVtbl->Release(urlAFromFile); DeleteFileW(fileNameW); }