ReactOS  0.4.15-dev-5137-g826bd41
COpenWithMenu.cpp
Go to the documentation of this file.
1 /*
2  * Open With Context Menu extension
3  *
4  * Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org>
5  * Copyright 2009 Andrew Hill
6  * Copyright 2012 Rafal Harabien
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include "precomp.h"
24 
26 
27 //
28 // [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system]
29 // "NoInternetOpenWith"=dword:00000001
30 //
31 
33 
35 {
36  public:
37  struct SApp
38  {
41  //WCHAR wszManufacturer[256];
42  WCHAR wszName[256];
47  };
48 
49  COpenWithList();
51 
52  BOOL Load();
53  SApp *Add(LPCWSTR pwszPath);
54  static BOOL SaveApp(SApp *pApp);
55  SApp *Find(LPCWSTR pwszFilename);
56  static LPCWSTR GetName(SApp *pApp);
57  static HICON GetIcon(SApp *pApp);
58  static BOOL Execute(SApp *pApp, LPCWSTR pwszFilePath);
59  static BOOL IsHidden(SApp *pApp);
60  inline BOOL IsNoOpen(VOID) { return m_bNoOpen; }
61  BOOL LoadRecommended(LPCWSTR pwszFilePath);
62  BOOL SetDefaultHandler(SApp *pApp, LPCWSTR pwszFilename);
63 
64  inline SApp *GetList() { return m_pApp; }
65  inline UINT GetCount() { return m_cApp; }
67 
68  private:
69  typedef struct _LANGANDCODEPAGE
70  {
74 
78 
79  SApp *AddInternal(LPCWSTR pwszFilename);
80  static BOOL LoadInfo(SApp *pApp);
81  static VOID GetPathFromCmd(LPWSTR pwszAppPath, LPCWSTR pwszCmd);
83  static HANDLE OpenMRUList(HKEY hKey);
89  static BOOL AddAppToMRUList(SApp *pApp, LPCWSTR pwszFilename);
90 
91  inline VOID SetRecommended(SApp *pApp)
92  {
93  if (!pApp->bRecommended)
95  pApp->bRecommended = TRUE;
96  }
97 };
98 
100  m_pApp(NULL), m_cApp(0), m_cRecommended(0), m_bNoOpen(FALSE) {}
101 
103 {
104  for (UINT i = 0; i < m_cApp; ++i)
105  if (m_pApp[i].hIcon)
107 
109 }
110 
112 {
113  HKEY hKey, hKeyApp;
114  WCHAR wszName[256], wszBuf[100];
115  DWORD i = 0, cchName, dwSize;
116  SApp *pApp;
117 
118  if (RegOpenKeyEx(HKEY_CLASSES_ROOT, L"Applications", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
119  {
120  ERR("RegOpenKeyEx HKCR\\Applications failed!\n");
121  return FALSE;
122  }
123 
124  while (TRUE)
125  {
126  cchName = _countof(wszName);
127  if (RegEnumKeyEx(hKey, i++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
128  break;
129 
130  pApp = AddInternal(wszName);
131 
132  if (pApp)
133  {
134  if (RegOpenKeyW(hKey, wszName, &hKeyApp) == ERROR_SUCCESS)
135  {
136  if ((RegQueryValueExW(hKeyApp, L"NoOpenWith", NULL, NULL, NULL, NULL) != ERROR_SUCCESS) &&
137  (RegQueryValueExW(hKeyApp, L"NoStartPage", NULL, NULL, NULL, NULL) != ERROR_SUCCESS))
138  {
139  StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s\\shell\\open\\command", wszName);
140  dwSize = sizeof(pApp->wszCmd);
141  if (RegGetValueW(hKey, wszBuf, L"", RRF_RT_REG_SZ, NULL, pApp->wszCmd, &dwSize) != ERROR_SUCCESS)
142  {
143  ERR("Failed to add app %ls\n", wszName);
144  pApp->bHidden = TRUE;
145  }
146  else
147  {
148  TRACE("App added %ls\n", pApp->wszCmd);
149  }
150  }
151  else
152  {
153  pApp->bHidden = TRUE;
154  }
155  RegCloseKey(hKeyApp);
156  }
157  else
158  {
159  pApp->bHidden = TRUE;
160  }
161  }
162  else
163  {
164  ERR("AddInternal failed\n");
165  }
166  }
167 
168  RegCloseKey(hKey);
169  return TRUE;
170 }
171 
173 {
174  SApp *pApp = AddInternal(PathFindFileNameW(pwszPath));
175 
176  if (pApp)
177  {
178  StringCbPrintfW(pApp->wszCmd, sizeof(pApp->wszCmd), L"\"%s\" \"%%1\"", pwszPath);
179  SaveApp(pApp);
180  }
181 
182  return pApp;
183 }
184 
186 {
187  WCHAR wszBuf[256];
188  HKEY hKey;
189 
190  StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Applications\\%s\\shell\\open\\command", pApp->wszFilename);
192  {
193  ERR("RegOpenKeyEx failed\n");
194  return FALSE;
195  }
196 
197  if (RegSetValueEx(hKey, L"", 0, REG_SZ, (PBYTE)pApp->wszCmd, (wcslen(pApp->wszCmd)+1)*sizeof(WCHAR)) != ERROR_SUCCESS)
198  ERR("Cannot add app to registry\n");
199 
200  RegCloseKey(hKey);
201  return TRUE;
202 }
203 
205 {
206  for (UINT i = 0; i < m_cApp; ++i)
207  if (wcsicmp(m_pApp[i].wszFilename, pwszFilename) == 0)
208  return &m_pApp[i];
209  return NULL;
210 }
211 
213 {
214  if (!pApp->wszName[0])
215  {
216  if (!LoadInfo(pApp))
217  {
218  WARN("Failed to load %ls info\n", pApp->wszFilename);
219  StringCbCopyW(pApp->wszName, sizeof(pApp->wszName), pApp->wszFilename);
220  }
221  }
222 
223  TRACE("%ls name: %ls\n", pApp->wszFilename, pApp->wszName);
224  return pApp->wszName;
225 }
226 
228 {
229  if (!pApp->hIcon)
230  {
231  WCHAR wszPath[MAX_PATH];
232 
233  GetPathFromCmd(wszPath, pApp->wszCmd);
234  ExtractIconExW(wszPath, 0, NULL, &pApp->hIcon, 1);
235  }
236 
237  TRACE("%ls icon: %p\n", pApp->wszFilename, pApp->hIcon);
238 
239  return pApp->hIcon;
240 }
241 
243 {
244  WCHAR wszBuf[256];
245  HKEY hKey;
246 
247  /* Add app to registry if it wasnt there before */
248  SaveApp(pApp);
249  if (!pApp->bMRUList)
250  AddAppToMRUList(pApp, pwszFilePath);
251 
252  /* Get a handle to the reg key */
253  StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Applications\\%s", pApp->wszFilename);
255  {
256  ERR("RegOpenKeyEx failed\n");
257  return FALSE;
258  }
259 
260  /* Let ShellExecuteExW do the work */
262  sei.nShow = SW_SHOWNORMAL;
263  sei.hkeyClass = hKey;
264  sei.lpFile = pwszFilePath;
265 
266  ShellExecuteExW(&sei);
267 
268  return TRUE;
269 }
270 
272 {
273  WCHAR wszBuf[100];
274  DWORD dwSize = 0;
275 
276  if (pApp->bHidden)
277  return pApp->bHidden;
278 
279  if (FAILED(StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Applications\\%s", pApp->wszFilename)))
280  {
281  ERR("insufficient buffer\n");
282  return FALSE;
283  }
284 
285  if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"NoOpenWith", RRF_RT_REG_SZ, NULL, NULL, &dwSize) != ERROR_SUCCESS)
286  return FALSE;
287 
288  pApp->bHidden = TRUE;
289  return TRUE;
290 }
291 
293 {
294  /* Check for duplicate */
295  SApp *pApp = Find(pwszFilename);
296  if (pApp)
297  return pApp;
298 
299  /* Create new item */
300  if (!m_pApp)
301  m_pApp = static_cast<SApp *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(m_pApp[0])));
302  else
303  m_pApp = static_cast<SApp *>(HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, m_pApp, (m_cApp + 1)*sizeof(m_pApp[0])));
304  if (!m_pApp)
305  {
306  ERR("Allocation failed\n");
307  return NULL;
308  }
309 
310  pApp = &m_pApp[m_cApp++];
311  wcscpy(pApp->wszFilename, pwszFilename);
312  return pApp;
313 }
314 
316 {
317  UINT cbSize, cchLen;
318  LPVOID pBuf;
319  WORD wLang = 0, wCode = 0;
320  LPLANGANDCODEPAGE lpLangCode;
321  WCHAR wszBuf[100];
322  WCHAR *pResult;
323  WCHAR wszPath[MAX_PATH];
324 
325  GetPathFromCmd(wszPath, pApp->wszCmd);
326  TRACE("LoadInfo %ls\n", wszPath);
327 
328  /* query version info size */
329  cbSize = GetFileVersionInfoSizeW(wszPath, NULL);
330  if (!cbSize)
331  {
332  ERR("GetFileVersionInfoSizeW %ls failed: %lu\n", wszPath, GetLastError());
333  return FALSE;
334  }
335 
336  /* allocate buffer */
337  pBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 200);
338  if (!pBuf)
339  {
340  ERR("HeapAlloc failed\n");
341  return FALSE;
342  }
343 
344  /* query version info */
345  if (!GetFileVersionInfoW(wszPath, 0, cbSize, pBuf))
346  {
347  ERR("GetFileVersionInfoW %ls failed: %lu\n", wszPath, GetLastError());
348  HeapFree(GetProcessHeap(), 0, pBuf);
349  return FALSE;
350  }
351 
352  /* query lang code */
353  if (VerQueryValueW(pBuf, L"VarFileInfo\\Translation", (LPVOID*)&lpLangCode, &cbSize))
354  {
355  /* FIXME: find language from current locale / if not available,
356  * default to english
357  * for now default to first available language
358  */
359  wLang = lpLangCode->lang;
360  wCode = lpLangCode->code;
361  }
362 
363  /* Query name */
364  swprintf(wszBuf, L"\\StringFileInfo\\%04x%04x\\FileDescription", wLang, wCode);
365  if (VerQueryValueW(pBuf, wszBuf, (LPVOID *)&pResult, &cchLen))
366  StringCchCopyNW(pApp->wszName, _countof(pApp->wszName), pResult, cchLen);
367  else
368  ERR("Cannot get app name\n");
369 
370  /* Query manufacturer */
371  /*swprintf(wszBuf, L"\\StringFileInfo\\%04x%04x\\CompanyName", wLang, wCode);
372 
373  if (VerQueryValueW(pBuf, wszBuf, (LPVOID *)&pResult, &cchLen))
374  StringCchCopyNW(pApp->wszManufacturer, _countof(pApp->wszManufacturer), pResult, cchLen);*/
375  HeapFree(GetProcessHeap(), 0, pBuf);
376  return TRUE;
377 }
378 
380 {
381  WCHAR wszBuf[MAX_PATH], *pwszDest = wszBuf;
382 
383  /* Remove arguments */
384  if (pwszCmd[0] == '"')
385  {
386  for(LPCWSTR pwszSrc = pwszCmd + 1; *pwszSrc && *pwszSrc != '"'; ++pwszSrc)
387  *(pwszDest++) = *pwszSrc;
388  }
389  else
390  {
391  for(LPCWSTR pwszSrc = pwszCmd; *pwszSrc && *pwszSrc != ' '; ++pwszSrc)
392  *(pwszDest++) = *pwszSrc;
393  }
394 
395  *pwszDest = 0;
396 
397  /* Expand evn vers and optionally search for path */
398  ExpandEnvironmentStrings(wszBuf, pwszAppPath, MAX_PATH);
399  if (!PathFileExists(pwszAppPath))
400  SearchPath(NULL, pwszAppPath, NULL, MAX_PATH, pwszAppPath, NULL);
401 }
402 
404 {
405  LPCWSTR pwszExt;
406 
407  pwszExt = PathFindExtensionW(pwszFilePath);
408  if (!pwszExt[0])
409  return FALSE;
410 
411  /* load programs directly associated from HKCU */
412  LoadRecommendedFromHKCU(pwszExt);
413 
414  /* load programs associated from HKCR\Extension */
415  LoadRecommendedFromHKCR(pwszExt);
416 
417  return TRUE;
418 }
419 
421 {
422  HKEY hSubkey, hSubkey2;
423  WCHAR wszProgId[256];
424  DWORD i = 0, cchProgId;
425 
426  if (RegOpenKeyExW(hKey, L"OpenWithProgIDs", 0, KEY_READ, &hSubkey) != ERROR_SUCCESS)
427  return FALSE;
428 
429  while (TRUE)
430  {
431  /* Enumerate values - value name is ProgId */
432  cchProgId = _countof(wszProgId);
433  if (RegEnumValue(hSubkey, i++, wszProgId, &cchProgId, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
434  break;
435 
436  /* If ProgId exists load it */
437  if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszProgId, 0, KEY_READ, &hSubkey2) == ERROR_SUCCESS)
438  {
439  LoadFromProgIdKey(hSubkey2, pwszExt);
440  RegCloseKey(hSubkey2);
441  }
442  }
443 
444  RegCloseKey(hSubkey);
445  return TRUE;
446 }
447 
449 {
450  MRUINFOW Info;
451 
452  /* Initialize mru list info */
453  Info.cbSize = sizeof(Info);
454  Info.uMax = 32;
455  Info.fFlags = MRU_STRING;
456  Info.hKey = hKey;
457  Info.lpszSubKey = L"OpenWithList";
458  Info.lpfnCompare = NULL;
459 
460  return CreateMRUListW(&Info);
461 }
462 
464 {
465  HANDLE hList;
466  int nItem, nCount, nResult;
467  WCHAR wszAppFilename[MAX_PATH];
468 
469  /* Open MRU list */
471  if (!hList)
472  {
473  TRACE("OpenMRUList failed\n");
474  return FALSE;
475  }
476 
477  /* Get list count */
478  nCount = EnumMRUListW(hList, -1, NULL, 0);
479 
480  for(nItem = 0; nItem < nCount; nItem++)
481  {
482  nResult = EnumMRUListW(hList, nItem, wszAppFilename, _countof(wszAppFilename));
483  if (nResult <= 0)
484  continue;
485 
486  /* Insert item */
487  SApp *pApp = Find(wszAppFilename);
488 
489  TRACE("Recommended app %ls: %p\n", wszAppFilename, pApp);
490  if (pApp)
491  {
492  pApp->bMRUList = TRUE;
493  SetRecommended(pApp);
494  }
495  }
496 
497  /* Free the MRU list */
499  return TRUE;
500 }
501 
503 {
504  WCHAR wszAppFilename[MAX_PATH];
505  HKEY hSubkey;
506  DWORD i = 0, cchAppFilename;
507 
508  if (RegOpenKeyExW(hKey, L"OpenWithList", 0, KEY_READ, &hSubkey) != ERROR_SUCCESS)
509  return FALSE;
510 
511  while (TRUE)
512  {
513  /* Enum registry keys - each of them is app name */
514  cchAppFilename = _countof(wszAppFilename);
515  if (RegEnumKeyExW(hSubkey, i++, wszAppFilename, &cchAppFilename, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
516  break;
517 
518  /* Set application as recommended */
519  SApp *pApp = Find(wszAppFilename);
520 
521  TRACE("Recommended app %ls: %p\n", wszAppFilename, pApp);
522  if (pApp)
523  SetRecommended(pApp);
524  }
525 
526  RegCloseKey(hSubkey);
527  return TRUE;
528 }
529 
531 {
532  WCHAR wszCmd[MAX_PATH], wszPath[MAX_PATH];
533  DWORD dwSize = 0;
534 
535  /* Check if NoOpen value exists */
537  {
538  /* Display warning dialog */
539  m_bNoOpen = TRUE;
540  }
541 
542  /* Check if there is a directly available execute key */
543  dwSize = sizeof(wszCmd);
544  if (RegGetValueW(hKey, L"shell\\open\\command", NULL, RRF_RT_REG_SZ, NULL, (PVOID)wszCmd, &dwSize) == ERROR_SUCCESS)
545  {
546  /* Erase extra arguments */
547  GetPathFromCmd(wszPath, wszCmd);
548 
549  /* Add application */
550  SApp *pApp = AddInternal(PathFindFileNameW(wszPath));
551  TRACE("Add app %ls: %p\n", wszPath, pApp);
552 
553  if (pApp)
554  {
555  StringCbCopyW(pApp->wszCmd, sizeof(pApp->wszCmd), wszCmd);
556  SetRecommended(pApp);
557  }
558  }
559 }
560 
562 {
563  HKEY hKey, hSubkey;
564  WCHAR wszBuf[MAX_PATH], wszBuf2[MAX_PATH];
565  DWORD dwSize;
566 
567  /* Check if extension exists */
569  {
570  /* Load items from SystemFileAssociations\Ext key */
571  StringCbPrintfW(wszBuf, sizeof(wszBuf), L"SystemFileAssociations\\%s", pwszExt);
573  return;
574  }
575 
576  /* Load programs referenced from HKCR\ProgId */
577  dwSize = sizeof(wszBuf);
578  if (RegGetValueW(hKey, NULL, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize) == ERROR_SUCCESS &&
579  RegOpenKeyExW(HKEY_CLASSES_ROOT, wszBuf, 0, KEY_READ, &hSubkey) == ERROR_SUCCESS)
580  {
581  LoadFromProgIdKey(hSubkey, pwszExt);
582  RegCloseKey(hSubkey);
583  }
584  else
585  LoadFromProgIdKey(hKey, pwszExt);
586 
587  /* Load items from HKCR\Ext\OpenWithList */
588  LoadAppList(hKey);
589 
590  /* Load items from HKCR\Ext\OpenWithProgIDs */
591  if (RegOpenKeyExW(hKey, L"OpenWithProgIDs", 0, KEY_READ, &hSubkey) == ERROR_SUCCESS)
592  {
593  LoadProgIdList(hSubkey, pwszExt);
594  RegCloseKey(hSubkey);
595  }
596 
597  /* Load additional items from referenced PerceivedType */
598  dwSize = sizeof(wszBuf);
599  if (RegGetValueW(hKey, NULL, L"PerceivedType", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize) == ERROR_SUCCESS)
600  {
601  StringCbPrintfW(wszBuf2, sizeof(wszBuf2), L"SystemFileAssociations\\%s", wszBuf);
602  if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszBuf2, 0, KEY_READ | KEY_WRITE, &hSubkey) == ERROR_SUCCESS)
603  {
604  /* Load from OpenWithList key */
605  LoadAppList(hSubkey);
606  RegCloseKey(hSubkey);
607  }
608  }
609 
610  /* Close the key */
611  RegCloseKey(hKey);
612 }
613 
615 {
616  WCHAR wszBuf[MAX_PATH];
617  HKEY hKey;
618 
619  StringCbPrintfW(wszBuf, sizeof(wszBuf),
620  L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%s",
621  pwszExt);
623  {
624  /* Load MRU and ProgId lists */
625  LoadMRUList(hKey);
626  LoadProgIdList(hKey, pwszExt);
627 
628  /* Handle "Aplication" value */
629  DWORD cbBuf = sizeof(wszBuf);
630  if (RegGetValueW(hKey, NULL, L"Application", RRF_RT_REG_SZ, NULL, wszBuf, &cbBuf) == ERROR_SUCCESS)
631  {
632  SApp *pApp = Find(wszBuf);
633  if (pApp)
634  SetRecommended(pApp);
635  }
636 
637  /* Close the key */
638  RegCloseKey(hKey);
639  }
640 }
641 
643 {
644  WCHAR wszBuf[100];
645  LPCWSTR pwszExt;
646  HKEY hKey;
647  HANDLE hList;
648 
649  /* Get file extension */
650  pwszExt = PathFindExtensionW(pwszFilename);
651  if (!pwszExt[0])
652  return FALSE;
653 
654  /* Build registry key */
655  if (FAILED(StringCbPrintfW(wszBuf, sizeof(wszBuf),
656  L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%s",
657  pwszExt)))
658  {
659  ERR("insufficient buffer\n");
660  return FALSE;
661  }
662 
663  /* Open base key for this file extension */
665  return FALSE;
666 
667  /* Open MRU list */
669  if (hList)
670  {
671  /* Insert the entry */
673 
674  /* Set MRU presence */
675  pApp->bMRUList = TRUE;
676 
677  /* Close MRU list */
679  }
680 
681  RegCloseKey(hKey);
682  return TRUE;
683 }
684 
686 {
687  HKEY hKey, hSrcKey, hDestKey;
688  WCHAR wszBuf[256];
689 
690  TRACE("SetDefaultHandler %ls %ls\n", pApp->wszFilename, pwszFilename);
691 
692  /* Extract file extension */
693  LPCWSTR pwszExt = PathFindExtensionW(pwszFilename);
694  if (!pwszExt[0] || !pwszExt[1])
695  return FALSE;
696 
697  /* Create file extension key */
699  {
700  ERR("Cannot open ext key\n");
701  return FALSE;
702  }
703 
704  DWORD dwSize = sizeof(wszBuf);
705  LONG lResult = RegGetValueW(hKey, NULL, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize);
706 
707  if (lResult == ERROR_FILE_NOT_FOUND)
708  {
709  /* A new entry was created or the default key is not set: set the prog key id */
710  StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s_auto_file", pwszExt + 1);
711  if (RegSetValueExW(hKey, L"", 0, REG_SZ, (const BYTE*)wszBuf, (wcslen(wszBuf) + 1) * sizeof(WCHAR)) != ERROR_SUCCESS)
712  {
713  RegCloseKey(hKey);
714  ERR("RegSetValueExW failed\n");
715  return FALSE;
716  }
717  }
718  else if (lResult != ERROR_SUCCESS)
719  {
720  RegCloseKey(hKey);
721  ERR("RegGetValueExW failed: 0x%08x\n", lResult);
722  return FALSE;
723  }
724 
725  /* Close file extension key */
726  RegCloseKey(hKey);
727 
728  /* Create prog id key */
730  {
731  ERR("RegCreateKeyExW failed\n");
732  return FALSE;
733  }
734 
735  /* Check if there already verbs existing for that app */
736  StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Applications\\%s\\shell", pApp->wszFilename);
737  if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszBuf, 0, KEY_READ, &hSrcKey) != ERROR_SUCCESS)
738  {
739  ERR("RegOpenKeyExW %ls failed\n", wszBuf);
740  RegCloseKey(hKey);
741  return FALSE;
742  }
743 
744  /* Open destination key */
745  if (RegCreateKeyExW(hKey, L"shell", 0, NULL, 0, KEY_WRITE, NULL, &hDestKey, NULL) != ERROR_SUCCESS)
746  {
747  ERR("RegCreateKeyExW failed\n");
748  RegCloseKey(hSrcKey);
749  RegCloseKey(hKey);
750  return FALSE;
751  }
752 
753  /* Copy static verbs from Classes\Applications key */
754  /* FIXME: SHCopyKey does not copy the security attributes of the keys */
755  LSTATUS Result = SHCopyKeyW(hSrcKey, NULL, hDestKey, 0);
756  RegCloseKey(hDestKey);
757  RegCloseKey(hSrcKey);
758  RegCloseKey(hKey);
759 
760  if (Result != ERROR_SUCCESS)
761  {
762  ERR("SHCopyKeyW failed\n");
763  return FALSE;
764  }
765 
766  return TRUE;
767 }
768 
770 {
771  public:
772  COpenWithDialog(const OPENASINFO *pInfo, COpenWithList *pAppList);
774  static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
776 
777  private:
778  VOID Init(HWND hwnd);
779  VOID AddApp(COpenWithList::SApp *pApp, BOOL bSelected);
780  VOID Browse();
781  VOID Accept();
784 
793 };
794 
796  m_pInfo(pInfo), m_pAppList(pAppList), m_hImgList(NULL), m_bNoOpen(FALSE)
797 {
798  if (!m_pAppList)
799  {
802  }
803  else
805 }
806 
808 {
810  delete m_pAppList;
811  if (m_hImgList)
813 }
814 
816 {
817  switch(Message)
818  {
819  case WM_INITDIALOG:
820  {
821  return TRUE;
822  }
823  case WM_CLOSE:
824  EndDialog(hwnd, IDNO);
825  break;
826  case WM_COMMAND:
827  switch(LOWORD(wParam))
828  {
829  case IDYES:
830  EndDialog(hwnd, IDYES);
831  break;
832  case IDNO:
833  EndDialog(hwnd, IDNO);
834  break;
835  }
836  break;
837  default:
838  return FALSE;
839  }
840  return TRUE;
841 }
842 
844 {
845  /* Only do the actual check if the file type has the 'NoOpen' flag. */
846  if (m_bNoOpen)
847  {
849 
850  if (dReturnValue == IDNO)
851  return TRUE;
852  else if (dReturnValue == -1)
853  {
854  ERR("IsNoOpen failed to load the dialog box.\n");
855  return TRUE;
856  }
857  }
858 
859  return FALSE;
860 }
861 
863 {
864  LPCWSTR pwszName = m_pAppList->GetName(pApp);
865  HICON hIcon = m_pAppList->GetIcon(pApp);
866 
867  TRACE("AddApp Cmd %ls Name %ls\n", pApp->wszCmd, pwszName);
868 
869  /* Add item to the list */
870  TVINSERTSTRUCT tvins;
871 
872  if (pApp->bRecommended)
873  tvins.hParent = tvins.hInsertAfter = m_hRecommend;
874  else
875  tvins.hParent = tvins.hInsertAfter = m_hOther;
876 
877  tvins.item.mask = TVIF_TEXT|TVIF_PARAM;
878  tvins.item.pszText = (LPWSTR)pwszName;
879  tvins.item.lParam = (LPARAM)pApp;
880 
881  if (hIcon)
882  {
883  tvins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
884  tvins.item.iImage = tvins.item.iSelectedImage = ImageList_AddIcon(m_hImgList, hIcon);
885  }
886 
888 
889  if (bSelected)
891 }
892 
894 {
895  WCHAR wszTitle[64];
896  WCHAR wszFilter[256];
897  WCHAR wszPath[MAX_PATH];
899 
900  /* Initialize OPENFILENAMEW structure */
901  ZeroMemory(&ofn, sizeof(OPENFILENAMEW));
902  ofn.lStructSize = sizeof(OPENFILENAMEW);
906  ofn.nMaxFile = (sizeof(wszPath) / sizeof(WCHAR));
907  ofn.lpstrFile = wszPath;
908  ofn.lpstrInitialDir = L"%programfiles%";
909 
910  /* Init title */
911  if (LoadStringW(shell32_hInstance, IDS_OPEN_WITH, wszTitle, sizeof(wszTitle) / sizeof(WCHAR)))
912  {
913  ofn.lpstrTitle = wszTitle;
914  ofn.nMaxFileTitle = wcslen(wszTitle);
915  }
916 
917  /* Init the filter string */
920  ZeroMemory(wszPath, sizeof(wszPath));
921 
922  /* Create OpenFile dialog */
923  if (!GetOpenFileNameW(&ofn))
924  return;
925 
926  /* Setup context for insert proc */
927  COpenWithList::SApp *pApp = m_pAppList->Add(wszPath);
928  AddApp(pApp, TRUE);
929 }
930 
932 {
933  TVITEM tvi;
934  tvi.hItem = TreeView_GetSelection(m_hTreeView);
935  if (!tvi.hItem)
936  return NULL;
937 
938  tvi.mask = TVIF_PARAM;
939  if (!TreeView_GetItem(m_hTreeView, &tvi))
940  return NULL;
941 
942  return (COpenWithList::SApp*)tvi.lParam;
943 }
944 
946 {
947  TRACE("COpenWithDialog::Init hwnd %p\n", hwnd);
948 
949  m_hDialog = hwnd;
951 
952  /* Handle register checkbox */
953  HWND hRegisterCheckbox = GetDlgItem(hwnd, 14003);
955  EnableWindow(hRegisterCheckbox, FALSE);
957  SendMessage(hRegisterCheckbox, BM_SETCHECK, BST_CHECKED, 0);
959  ShowWindow(hRegisterCheckbox, SW_HIDE);
960 
961  if (m_pInfo->pcszFile)
962  {
963  WCHAR wszBuf[MAX_PATH];
964  UINT cchBuf;
965 
966  /* Add filename to label */
967  cchBuf = GetDlgItemTextW(hwnd, 14001, wszBuf, _countof(wszBuf));
968  StringCchCopyW(wszBuf + cchBuf, _countof(wszBuf) - cchBuf, PathFindFileNameW(m_pInfo->pcszFile));
969  SetDlgItemTextW(hwnd, 14001, wszBuf);
970 
971  /* Load applications from registry */
972  m_pAppList->Load();
974 
975  /* Determine if the type of file can be opened directly from the shell */
976  if (m_pAppList->IsNoOpen() != FALSE)
977  m_bNoOpen = TRUE;
978 
979  /* Init treeview */
980  m_hTreeView = GetDlgItem(hwnd, 14002);
983 
984  /* If there are some recommendations add parent nodes: Recommended and Others */
985  UINT cRecommended = m_pAppList->GetRecommendedCount();
986  if (cRecommended > 0)
987  {
988  TVINSERTSTRUCT tvins;
989  HICON hFolderIcon;
990 
991  tvins.hParent = tvins.hInsertAfter = TVI_ROOT;
993  tvins.item.pszText = (LPWSTR)wszBuf;
994  tvins.item.state = tvins.item.stateMask = TVIS_EXPANDED;
996  tvins.item.iImage = tvins.item.iSelectedImage = ImageList_AddIcon(m_hImgList, hFolderIcon);
997 
1000 
1003  }
1004  else
1006 
1007  /* Add all applications */
1008  BOOL bNoAppSelected = TRUE;
1009  COpenWithList::SApp *pAppList = m_pAppList->GetList();
1010  for (UINT i = 0; i < m_pAppList->GetCount(); ++i)
1011  {
1012  if (!COpenWithList::IsHidden(&pAppList[i]))
1013  {
1014  if (bNoAppSelected && (pAppList[i].bRecommended || !cRecommended))
1015  {
1016  AddApp(&pAppList[i], TRUE);
1017  bNoAppSelected = FALSE;
1018  }
1019  else
1020  AddApp(&pAppList[i], FALSE);
1021  }
1022  }
1023  }
1024 }
1025 
1027 {
1029  if (pApp)
1030  {
1031  /* Set programm as default handler */
1032  if (SendDlgItemMessage(m_hDialog, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED)
1034 
1035  /* Execute program */
1036  if (m_pInfo->oaifInFlags & OAIF_EXEC)
1038 
1039  EndDialog(m_hDialog, 1);
1040  }
1041 }
1042 
1044 {
1045  COpenWithDialog *pThis = reinterpret_cast<COpenWithDialog *>(GetWindowLongPtr(hwndDlg, DWLP_USER));
1046 
1047  switch(uMsg)
1048  {
1049  case WM_INITDIALOG:
1050  {
1051  COpenWithDialog *pThis = reinterpret_cast<COpenWithDialog *>(lParam);
1052 
1053  pThis->Init(hwndDlg);
1054  return TRUE;
1055  }
1056  case WM_COMMAND:
1057  switch(LOWORD(wParam))
1058  {
1059  case 14004: /* browse */
1060  {
1061  pThis->Browse();
1062  return TRUE;
1063  }
1064  case IDOK: /* ok */
1065  {
1066  pThis->Accept();
1067  return TRUE;
1068  }
1069  case IDCANCEL: /* cancel */
1070  EndDialog(hwndDlg, 0);
1071  return TRUE;
1072  default:
1073  break;
1074  }
1075  break;
1076  case WM_NOTIFY:
1077  switch (((LPNMHDR)lParam)->code)
1078  {
1079  case TVN_SELCHANGED:
1080  EnableWindow(GetDlgItem(hwndDlg, IDOK), pThis->GetCurrentApp() ? TRUE : FALSE);
1081  break;
1082  case NM_DBLCLK:
1083  case NM_RETURN:
1084  pThis->Accept();
1085  break;
1086  }
1087  break;
1088  case WM_CLOSE:
1089  EndDialog(hwndDlg, 0);
1090  return TRUE;
1091  default:
1092  break;
1093  }
1094  return FALSE;
1095 }
1096 
1098 {
1099  m_idCmdFirst = 0;
1100  m_idCmdLast = 0;
1101  m_pAppList = new COpenWithList;
1102 }
1103 
1105 {
1106  TRACE("Destroying COpenWithMenu(%p)\n", this);
1107 
1108  if (m_hSubMenu)
1109  {
1110  INT Count, Index;
1111  MENUITEMINFOW mii;
1112 
1113  /* get item count */
1115  if (Count == -1)
1116  return;
1117 
1118  /* setup menuitem info */
1119  ZeroMemory(&mii, sizeof(mii));
1120  mii.cbSize = sizeof(mii);
1122 
1123  for(Index = 0; Index < Count; Index++)
1124  {
1125  if (GetMenuItemInfoW(m_hSubMenu, Index, TRUE, &mii))
1126  {
1127  if (mii.hbmpChecked)
1129  }
1130  }
1131  }
1132 
1133  if (m_pAppList)
1134  delete m_pAppList;
1135 }
1136 
1138 {
1139  HDC hdc, hdcScr;
1140  HBITMAP hbm, hbmOld;
1141  RECT rc;
1142 
1143  hdcScr = GetDC(NULL);
1144  hdc = CreateCompatibleDC(hdcScr);
1146  hbm = CreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
1147  ReleaseDC(NULL, hdcScr);
1148 
1149  hbmOld = (HBITMAP)SelectObject(hdc, hbm);
1150  FillRect(hdc, &rc, (HBRUSH)(COLOR_MENU + 1));
1151  if (!DrawIconEx(hdc, 0, 0, hIcon, rc.right, rc.bottom, 0, NULL, DI_NORMAL))
1152  ERR("DrawIcon failed: %x\n", GetLastError());
1153  SelectObject(hdc, hbmOld);
1154 
1155  DeleteDC(hdc);
1156 
1157  return hbm;
1158 }
1159 
1161 {
1162  MENUITEMINFOW mii;
1163  WCHAR wszBuf[128];
1164 
1165  ZeroMemory(&mii, sizeof(mii));
1166  mii.cbSize = sizeof(mii);
1167  mii.fMask = MIIM_TYPE | MIIM_ID;
1168  mii.fType = MFT_SEPARATOR;
1169  mii.wID = -1;
1170  InsertMenuItemW(m_hSubMenu, -1, TRUE, &mii);
1171 
1173  {
1174  ERR("Failed to load string\n");
1175  return;
1176  }
1177 
1178  mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
1179  mii.fType = MFT_STRING;
1180  mii.fState = MFS_ENABLED;
1181  mii.wID = m_idCmdLast;
1182  mii.dwTypeData = (LPWSTR)wszBuf;
1183  mii.cch = wcslen(wszBuf);
1184 
1185  InsertMenuItemW(m_hSubMenu, -1, TRUE, &mii);
1186 }
1187 
1189 {
1190  MENUITEMINFOW mii;
1191  LPCWSTR pwszName = m_pAppList->GetName((COpenWithList::SApp*)pApp);
1192 
1193  ZeroMemory(&mii, sizeof(mii));
1194  mii.cbSize = sizeof(mii);
1196  mii.fType = MFT_STRING;
1197  mii.fState = MFS_ENABLED;
1198  mii.wID = m_idCmdLast;
1199  mii.dwTypeData = (LPWSTR)pwszName;
1200  mii.cch = wcslen(mii.dwTypeData);
1201  mii.dwItemData = (ULONG_PTR)pApp;
1202 
1204  if (hIcon)
1205  {
1206  mii.fMask |= MIIM_CHECKMARKS;
1208  }
1209 
1210  if (InsertMenuItemW(m_hSubMenu, -1, TRUE, &mii))
1211  m_idCmdLast++;
1212 }
1213 
1215  HMENU hMenu,
1216  UINT indexMenu,
1217  UINT idCmdFirst,
1218  UINT idCmdLast,
1219  UINT uFlags)
1220 {
1221  TRACE("hMenu %p indexMenu %u idFirst %u idLast %u uFlags %u\n", hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
1222 
1223  INT DefaultPos = GetMenuDefaultItem(hMenu, TRUE, 0);
1224 
1225  WCHAR wszName[100];
1226  UINT NameId = (DefaultPos == -1 ? IDS_OPEN : IDS_OPEN_WITH);
1227  if (!LoadStringW(shell32_hInstance, NameId, wszName, _countof(wszName)))
1228  {
1229  ERR("Failed to load string\n");
1230  return E_FAIL;
1231  }
1232 
1233  /* Init first cmd id and submenu */
1234  m_idCmdFirst = m_idCmdLast = idCmdFirst;
1235  m_hSubMenu = NULL;
1236 
1237  /* If we are going to be default item, we shouldn't be submenu */
1238  if (DefaultPos != -1)
1239  {
1240  /* Load applications list */
1241  m_pAppList->Load();
1243 
1244  /* Create submenu only if there is more than one application and menu has a default item */
1245  if (m_pAppList->GetRecommendedCount() > 1)
1246  {
1248 
1249  for(UINT i = 0; i < m_pAppList->GetCount(); ++i)
1250  {
1251  COpenWithList::SApp *pApp = m_pAppList->GetList() + i;
1252  if (pApp->bRecommended)
1253  AddApp(pApp);
1254  }
1255 
1257  }
1258  }
1259 
1260  /* Insert menu item */
1261  MENUITEMINFOW mii;
1262  ZeroMemory(&mii, sizeof(mii));
1263  mii.cbSize = sizeof(mii);
1264  mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
1265  if (m_hSubMenu)
1266  {
1267  mii.fMask |= MIIM_SUBMENU;
1268  mii.hSubMenu = m_hSubMenu;
1269  mii.wID = -1;
1270  }
1271  else
1272  mii.wID = m_idCmdLast;
1273 
1274  mii.fType = MFT_STRING;
1275  mii.dwTypeData = (LPWSTR)wszName;
1276  mii.cch = wcslen(wszName);
1277 
1278  mii.fState = MFS_ENABLED;
1279  if (DefaultPos == -1)
1280  mii.fState |= MFS_DEFAULT;
1281 
1282  if (!InsertMenuItemW(hMenu, DefaultPos + 1, TRUE, &mii))
1283  return E_FAIL;
1284 
1286 }
1287 
1290 {
1291  HRESULT hr = E_FAIL;
1292 
1293  TRACE("This %p idFirst %u idLast %u idCmd %u\n", this, m_idCmdFirst, m_idCmdLast, m_idCmdFirst + LOWORD(lpici->lpVerb));
1294 
1295  if (HIWORD(lpici->lpVerb) == 0 && m_idCmdFirst + LOWORD(lpici->lpVerb) <= m_idCmdLast)
1296  {
1297  if (m_idCmdFirst + LOWORD(lpici->lpVerb) == m_idCmdLast)
1298  {
1299  OPENASINFO info;
1301 
1302  info.pcszFile = m_wszPath;
1303  info.oaifInFlags = OAIF_EXEC;
1304  if (pwszExt[0])
1306  info.pcszClass = NULL;
1307  hr = SHOpenWithDialog(lpici->hwnd, &info);
1308  }
1309  else
1310  {
1311  /* retrieve menu item info */
1312  MENUITEMINFOW mii;
1313  ZeroMemory(&mii, sizeof(mii));
1314  mii.cbSize = sizeof(mii);
1315  mii.fMask = MIIM_DATA | MIIM_FTYPE;
1316 
1317  if (GetMenuItemInfoW(m_hSubMenu, LOWORD(lpici->lpVerb), TRUE, &mii) && mii.dwItemData)
1318  {
1319  /* launch item with specified app */
1322  hr = S_OK;
1323  }
1324  }
1325  }
1326 
1327  return hr;
1328 }
1329 
1332  UINT* pwReserved, LPSTR pszName, UINT cchMax )
1333 {
1334  FIXME("%p %lu %u %p %p %u\n", this,
1335  idCmd, uType, pwReserved, pszName, cchMax );
1336 
1337  return E_NOTIMPL;
1338 }
1339 
1341  UINT uMsg,
1342  WPARAM wParam,
1343  LPARAM lParam)
1344 {
1345  TRACE("This %p uMsg %x\n", this, uMsg);
1346 
1347  return E_NOTIMPL;
1348 }
1349 
1352  IDataObject *pdtobj,
1353  HKEY hkeyProgID)
1354 {
1355  LPCITEMIDLIST pidlFolder2;
1356  LPCITEMIDLIST pidlChild;
1357 
1358  TRACE("This %p\n", this);
1359 
1360  if (pdtobj == NULL)
1361  return E_INVALIDARG;
1362 
1363  CDataObjectHIDA pida(pdtobj);
1364  if (FAILED(pida.hr()))
1365  {
1366  ERR("pdtobj->GetData failed with 0x%x\n", pida.hr());
1367  return pida.hr();
1368  }
1369 
1370  ASSERT(pida->cidl >= 1);
1371 
1372  pidlFolder2 = HIDA_GetPIDLFolder(pida);
1373  pidlChild = HIDA_GetPIDLItem(pida, 0);
1374 
1375  if (!_ILIsValue(pidlChild))
1376  {
1377  TRACE("pidl is not a file\n");
1378  return E_FAIL;
1379  }
1380 
1381  CComHeapPtr<ITEMIDLIST> pidl(ILCombine(pidlFolder2, pidlChild));
1382  if (!pidl)
1383  {
1384  ERR("no mem\n");
1385  return E_OUTOFMEMORY;
1386  }
1387 
1388  if (!SHGetPathFromIDListW(pidl, m_wszPath))
1389  {
1390  ERR("SHGetPathFromIDListW failed\n");
1391  return E_FAIL;
1392  }
1393 
1394  TRACE("szPath %s\n", debugstr_w(m_wszPath));
1395 
1397  if (PathIsExeW(pwszExt) || !_wcsicmp(pwszExt, L".lnk"))
1398  {
1399  TRACE("file is a executable or shortcut\n");
1400  return E_FAIL;
1401  }
1402 
1403  return S_OK;
1404 }
1405 
1408 {
1409  INT_PTR ret;
1410 
1411  TRACE("SHOpenWithDialog hwndParent %p poainfo %p\n", hwndParent, poainfo);
1412 
1414 
1415  if (poainfo->pcszClass == NULL && poainfo->pcszFile == NULL)
1416  return E_FAIL;
1417 
1418  COpenWithDialog pDialog(poainfo);
1419 
1420  if (pDialog.IsNoOpen(hwndParent))
1421  return S_OK;
1422 
1424  COpenWithDialog::DialogProc, (LPARAM)&pDialog);
1425 
1426  if (ret == (INT_PTR)-1)
1427  {
1428  ERR("Failed to create dialog: %u\n", GetLastError());
1429  return E_FAIL;
1430  }
1431 
1432  return S_OK;
1433 }
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1965
#define OFN_FILEMUSTEXIST
Definition: commdlg.h:106
VOID Init(HWND hwnd)
#define OFN_EXPLORER
Definition: commdlg.h:104
DWORD WINAPI SHCopyKeyW(HKEY hKeySrc, LPCWSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved)
Definition: reg.c:2261
#define MAKEINTRESOURCE
Definition: winuser.h:591
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
WCHAR m_wszPath[MAX_PATH]
Definition: COpenWithMenu.h:36
SApp * AddInternal(LPCWSTR pwszFilename)
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
static HICON
Definition: imagelist.c:84
UINT WINAPI GetDlgItemTextW(HWND hDlg, int nIDDlgItem, LPWSTR lpString, int nMaxCount)
Definition: dialog.c:2263
#define MFT_STRING
Definition: winuser.h:741
#define MIIM_FTYPE
Definition: winuser.h:724
BOOL LoadProgIdList(HKEY hKey, LPCWSTR pwszExt)
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
#define IDOK
Definition: winuser.h:824
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
HBITMAP hbmpChecked
Definition: winuser.h:3256
#define IMAGE_ICON
Definition: winuser.h:212
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
SApp * Add(LPCWSTR pwszPath)
#define ERROR_SUCCESS
Definition: deptool.c:10
COpenWithList::SApp * GetCurrentApp()
BOOL LoadAppList(HKEY hKey)
LPCWSTR pcszFile
Definition: shlobj.h:2532
HRESULT hr
Definition: shlfolder.c:183
#define IDYES
Definition: winuser.h:829
SApp * GetList()
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
VOID AddApp(PVOID pApp)
HDC WINAPI GetDC(_In_opt_ HWND)
HWND hwndOwner
Definition: commdlg.h:330
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define SW_HIDE
Definition: winuser.h:762
static WCHAR wszFilter[MAX_STRING_LEN *4+6 *3+5]
Definition: wordpad.c:72
WINE_DEFAULT_DEBUG_CHANNEL(shell)
HBITMAP IconToBitmap(HICON hIcon)
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define WARN(fmt,...)
Definition: debug.h:112
#define ExpandEnvironmentStrings
Definition: winbase.h:3635
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:699
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1294
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
static PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const *pida, SIZE_T i)
Definition: shellutils.h:554
#define SM_CXMENUCHECK
Definition: winuser.h:1025
HIMAGELIST m_hImgList
OPEN_AS_INFO_FLAGS oaifInFlags
Definition: shlobj.h:2534
OPENFILENAME ofn
Definition: main.cpp:37
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
#define RRF_RT_REG_SZ
Definition: driver.c:575
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1667
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
INT WINAPI AddMRUStringW(HANDLE hList, LPCWSTR lpszString)
#define IDD_OPEN_WITH
Definition: shresdef.h:489
LPWSTR dwTypeData
Definition: winuser.h:3259
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
UINT_PTR WPARAM
Definition: windef.h:207
static INT_PTR CALLBACK NoOpenDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
#define SendDlgItemMessage
Definition: winuser.h:5832
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3271
#define IDI_SHELL_PROGRAMS_FOLDER
Definition: shresdef.h:543
UINT uFlags
Definition: api.c:59
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
int32_t INT_PTR
Definition: typedefs.h:64
VOID LoadRecommendedFromHKCU(LPCWSTR pwszExt)
#define MFS_DEFAULT
Definition: winuser.h:743
char * LPSTR
Definition: xmlstorage.h:182
static BOOL AddAppToMRUList(SApp *pApp, LPCWSTR pwszFilename)
LONG right
Definition: windef.h:308
VOID SetRecommended(SApp *pApp)
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int32_t INT
Definition: typedefs.h:58
#define IDS_OPEN
Definition: resource.h:12
#define SetWindowLongPtr
Definition: treelist.c:70
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
WPARAM wParam
Definition: combotst.c:138
#define SEVERITY_SUCCESS
Definition: winerror.h:64
LPCWSTR pcszClass
Definition: shlobj.h:2533
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
#define SearchPath
Definition: winbase.h:3761
DWORD nMaxFile
Definition: commdlg.h:337
#define IDS_OPEN_WITH_RECOMMENDED
Definition: shresdef.h:189
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:928
#define ILC_COLOR32
Definition: commctrl.h:358
BOOL WINAPI SetDlgItemTextW(_In_ HWND, _In_ int, _In_ LPCWSTR)
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
static HICON GetIcon(SApp *pApp)
static VOID GetPathFromCmd(LPWSTR pwszAppPath, LPCWSTR pwszCmd)
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3412
#define DialogBox
Definition: winuser.h:5751
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2750
#define MIIM_SUBMENU
Definition: winuser.h:718
HANDLE WINAPI CreateMRUListW(const MRUINFOW *infoW)
#define L(x)
Definition: ntvdm.h:50
const OPENASINFO * m_pInfo
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
#define SM_CYMENUCHECK
Definition: winuser.h:1026
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define MFS_ENABLED
Definition: winuser.h:745
#define FALSE
Definition: types.h:117
#define IDS_OPEN_WITH_CHOOSE
Definition: shresdef.h:135
#define MIIM_STATE
Definition: winuser.h:716
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIcons)
Definition: iconcache.cpp:866
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3291
static struct _test_info info[]
Definition: SetCursorPos.c:19
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define debugstr_w
Definition: kernel32.h:32
struct COpenWithList::_LANGANDCODEPAGE * LPLANGANDCODEPAGE
BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn)
Definition: filedlg.c:4677
static LPCWSTR GetName(SApp *pApp)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define FIXME(fmt,...)
Definition: debug.h:111
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
#define IDS_OPEN_WITH_FILTER
Definition: shresdef.h:145
#define E_INVALIDARG
Definition: ddrawi.h:101
static HWND hwndParent
Definition: cryptui.c:300
#define COLOR_MENU
Definition: winuser.h:911
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
LONG_PTR LPARAM
Definition: windef.h:208
#define BM_GETCHECK
Definition: winuser.h:1908
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2343
BOOL SetDefaultHandler(SApp *pApp, LPCWSTR pwszFilename)
HINSTANCE hInstance
Definition: commdlg.h:331
virtual HRESULT STDMETHODCALLTYPE Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID)
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3447
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static BOOL SaveApp(SApp *pApp)
#define MIIM_ID
Definition: winuser.h:717
#define OFN_PATHMUSTEXIST
Definition: commdlg.h:117
COpenWithDialog(const OPENASINFO *pInfo, COpenWithList *pAppList)
#define KEY_WRITE
Definition: nt_native.h:1031
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4899
WCHAR wszFilename[MAX_PATH]
struct COpenWithList::_LANGANDCODEPAGE LANGANDCODEPAGE
int Count
Definition: noreturn.cpp:7
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
BOOL LoadRecommended(LPCWSTR pwszFilePath)
#define BM_SETCHECK
Definition: winuser.h:1911
#define TRACE(s)
Definition: solgame.cpp:4
#define TreeView_GetSelection(hwnd)
Definition: commctrl.h:3473
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
#define ASSERT(a)
Definition: mode.c:44
HRESULT WINAPI SHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:1997
static BOOL LoadInfo(SApp *pApp)
LONG HRESULT
Definition: typedefs.h:79
_In_ WDFCOLLECTION _In_ ULONG Index
LPCSTR lpstrInitialDir
Definition: commdlg.h:340
#define _countof(array)
Definition: sndvol32.h:68
#define TVN_SELCHANGED
Definition: commctrl.h:3735
#define WM_CLOSE
Definition: winuser.h:1611
#define MAX_PATH
Definition: compat.h:34
DWORD lStructSize
Definition: commdlg.h:329
#define WINAPI
Definition: msvc.h:6
unsigned short WORD
Definition: ntddk_ex.h:93
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:370
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
INT WINAPI ImageList_AddIcon(HIMAGELIST himl, HICON hIcon)
Definition: imagelist.c:540
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define IDS_OPEN_WITH_OTHER
Definition: shresdef.h:190
UINT cchMax
#define TVI_ROOT
Definition: commctrl.h:3368
#define MFT_SEPARATOR
Definition: winuser.h:739
CHAR Message[80]
Definition: alive.c:5
#define wcsicmp
Definition: compat.h:15
int ret
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
BOOL LoadMRUList(HKEY hKey)
struct tagOFNW OPENFILENAMEW
HDC hdc
Definition: main.c:9
#define MRU_STRING
#define DWLP_USER
Definition: winuser.h:866
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:611
#define MIIM_TYPE
Definition: winuser.h:720
BOOL _ILIsValue(LPCITEMIDLIST pidl)
Definition: pidl.c:1985
#define ILC_MASK
Definition: commctrl.h:351
#define DI_NORMAL
Definition: wingdi.h:72
#define MIIM_CHECKMARKS
Definition: winuser.h:719
INT WINAPI EnumMRUListW(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize)
static PCUIDLIST_ABSOLUTE HIDA_GetPIDLFolder(CIDA const *pida)
Definition: shellutils.h:549
#define WM_COMMAND
Definition: winuser.h:1730
Definition: inflate.c:139
int _cdecl swprintf(const WCHAR *,...)
#define RegEnumKeyEx
Definition: winreg.h:510
unsigned char BYTE
Definition: xxhash.c:193
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
#define TVIS_EXPANDED
Definition: commctrl.h:3284
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
#define TVITEM
Definition: commctrl.h:3365
#define ERR(fmt,...)
Definition: debug.h:110
static BOOL IsHidden(SApp *pApp)
HWND hList
Definition: livecd.c:10
#define NM_RETURN
Definition: commctrl.h:132
void WINAPI FreeMRUList(HANDLE hMRUList)
COpenWithList * m_pAppList
#define PathFileExists
Definition: shlwapi.h:899
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define S_OK
Definition: intsafe.h:52
#define RegOpenKeyEx
Definition: winreg.h:520
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define shell32_hInstance
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID AddChooseProgramItem()
#define NM_DBLCLK
Definition: commctrl.h:131
BOOL WINAPI DeleteDC(_In_ HDC)
LPSTR lpstrFile
Definition: commdlg.h:336
#define TVIF_TEXT
Definition: commctrl.h:3266
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
HICON hIcon
Definition: msconfig.c:44
FxAutoRegKey hKey
#define IDS_OPEN_WITH
Definition: shresdef.h:134
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3481
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
#define HeapReAlloc
Definition: compat.h:593
WCHAR wszCmd[MAX_PATH]
#define E_NOTIMPL
Definition: ddrawi.h:99
HTREEITEM m_hRecommend
#define TVINSERTSTRUCT
Definition: commctrl.h:3402
#define TVIF_IMAGE
Definition: commctrl.h:3267
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
LPCSTR lpstrFilter
Definition: commdlg.h:332
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
VOID LoadFromProgIdKey(HKEY hKey, LPCWSTR pwszExt)
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL IsNoOpen(VOID)
static HANDLE OpenMRUList(HKEY hKey)
struct _SHELLEXECUTEINFOW SHELLEXECUTEINFOW
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define BST_CHECKED
Definition: winuser.h:197
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:845
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:846
LPCSTR lpstrTitle
Definition: commdlg.h:341
#define TVSIL_NORMAL
Definition: commctrl.h:3443
#define SendMessage
Definition: winuser.h:5833
COpenWithList * m_pAppList
Definition: COpenWithMenu.h:38
#define HIWORD(l)
Definition: typedefs.h:247
UINT GetRecommendedCount()
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
SApp * Find(LPCWSTR pwszFilename)
LONG bottom
Definition: windef.h:309
#define TVIF_STATE
Definition: commctrl.h:3269
#define ULONG_PTR
Definition: config.h:101
#define LoadImage
Definition: winuser.h:5805
HBITMAP hbmpUnchecked
Definition: winuser.h:3257
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
static HBITMAP
Definition: button.c:44
VOID WINAPI InitCommonControls(void)
Definition: commctrl.c:863
#define TVIF_PARAM
Definition: commctrl.h:3268
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
#define IDNO
Definition: winuser.h:830
static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define GetWindowLongPtr
Definition: treelist.c:73
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDCANCEL
Definition: winuser.h:825
#define MIIM_DATA
Definition: winuser.h:721
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
VOID LoadRecommendedFromHKCR(LPCWSTR pwszExt)
#define EXTERN_C
Definition: basetyps.h:12
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
BOOL IsNoOpen(HWND hwnd)
ULONG_PTR dwItemData
Definition: winuser.h:3258
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
BYTE * PBYTE
Definition: pedump.c:66
#define WM_INITDIALOG
Definition: winuser.h:1729
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:594
#define RegEnumValue
Definition: winreg.h:511
VOID AddApp(COpenWithList::SApp *pApp, BOOL bSelected)
#define RegCloseKey(hKey)
Definition: registry.h:47
#define RegSetValueEx
Definition: winreg.h:533
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define RegCreateKeyEx
Definition: winreg.h:501
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3490
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define WM_NOTIFY
Definition: richedit.h:61
static BOOL Execute(SApp *pApp, LPCWSTR pwszFilePath)
#define IDD_NOOPEN
Definition: shresdef.h:492
DWORD nMaxFileTitle
Definition: commdlg.h:339
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1049
DWORD Flags
Definition: commdlg.h:342
#define REG_SZ
Definition: layer.c:22