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.

152 lines
5.2 KiB

  1. #include "stock.h"
  2. #pragma hdrstop
  3. //
  4. // Return root hkey and default client name. The caller is expected to
  5. // retrieve the command from hkey\default\shell\open\command.
  6. //
  7. STDAPI_(HKEY) _GetClientKeyAndDefaultW(LPCWSTR pwszClientType, LPWSTR pwszDefault, DWORD cchDefault)
  8. {
  9. HKEY hkClient = NULL;
  10. ASSERT(cchDefault); // This had better be a nonempty buffer
  11. // Borrow pwszDefault as a scratch buffer
  12. wnsprintfW(pwszDefault, cchDefault, L"SOFTWARE\\Clients\\%s", pwszClientType);
  13. if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszDefault, 0, KEY_READ, &hkClient))
  14. {
  15. DWORD dwSize = cchDefault * sizeof(*pwszDefault);
  16. pwszDefault[0] = 0; // in case of failure
  17. RegQueryValueExW(hkClient, NULL, NULL, NULL, (LPBYTE)pwszDefault, &dwSize);
  18. // If no default client, then fail
  19. if (!pwszDefault[0])
  20. {
  21. RegCloseKey(hkClient);
  22. hkClient = NULL;
  23. }
  24. } else if (StrCmpIW(pwszClientType, L"webbrowser") == 0)
  25. {
  26. // In theory, we could use
  27. // RegOpenKeyExW(HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &hkClient)
  28. // but that just returns HKEY_CLASSES_ROOT back anyway.
  29. hkClient = HKEY_CLASSES_ROOT;
  30. StrCpyNW(pwszDefault, L"http", cchDefault);
  31. }
  32. return hkClient;
  33. }
  34. // Gets the path to open the default Mail, News, etc Client.
  35. STDAPI SHGetDefaultClientOpenCommandW(LPCWSTR pwszClientType,
  36. LPWSTR pwszClientCommand, DWORD dwCch,
  37. OPTIONAL LPWSTR pwszClientParams, DWORD dwCchParams)
  38. {
  39. HRESULT hr = E_INVALIDARG;
  40. HKEY hkClient;
  41. WCHAR wszDefault[MAX_PATH];
  42. ASSERT(pwszClientCommand && dwCch);
  43. ASSERT(pwszClientParams == NULL || dwCchParams);
  44. hkClient = _GetClientKeyAndDefaultW(pwszClientType, wszDefault, ARRAYSIZE(wszDefault));
  45. if (hkClient)
  46. {
  47. // For the webbrowser client, do not pass any command line arguments
  48. // at all. This suppresses the "-nohome" flag that IE likes to throw
  49. // in there. Also, if we end up being forced to use the Protocol key,
  50. // then strip the args there, too.
  51. BOOL fStripArgs = hkClient == HKEY_CLASSES_ROOT;
  52. BOOL iRetry = 0;
  53. int cchDefault = lstrlenW(wszDefault);
  54. again:
  55. StrCatBuffW(wszDefault, L"\\shell\\open\\command", ARRAYSIZE(wszDefault));
  56. // convert characters to bytes
  57. DWORD cb = dwCch * (sizeof(WCHAR)/sizeof(BYTE));
  58. // the default value of this key is the actual command to run the app
  59. DWORD dwError;
  60. dwError = SHGetValueW(hkClient, wszDefault, NULL, NULL, (LPBYTE) pwszClientCommand, &cb);
  61. if (dwError == ERROR_FILE_NOT_FOUND && iRetry == 0 &&
  62. StrCmpICW(pwszClientType, L"mail") == 0)
  63. {
  64. // Sigh, Netscape doesn't register a shell\open\command; we have to
  65. // look in Protocols\mailto\shell\open\command instead.
  66. wszDefault[cchDefault] = L'\0';
  67. StrCatBuffW(wszDefault, L"\\Protocols\\mailto", ARRAYSIZE(wszDefault));
  68. fStripArgs = TRUE;
  69. iRetry++;
  70. goto again;
  71. }
  72. if (dwError == ERROR_SUCCESS)
  73. {
  74. // Sigh. Netscape forgets to quote its EXE name.
  75. PathProcessCommand(pwszClientCommand, pwszClientCommand, dwCch,
  76. PPCF_ADDQUOTES | PPCF_NODIRECTORIES | PPCF_LONGESTPOSSIBLE);
  77. if (pwszClientParams)
  78. {
  79. if (fStripArgs)
  80. {
  81. pwszClientParams[0] = 0;
  82. }
  83. else
  84. {
  85. StrCpyNW(pwszClientParams, PathGetArgsW(pwszClientCommand), dwCchParams);
  86. }
  87. }
  88. PathRemoveArgsW(pwszClientCommand);
  89. PathUnquoteSpaces(pwszClientCommand);
  90. // Bonus hack for Netscape! To read email you have to pass the
  91. // "-mail" command line option even though there is no indication
  92. // anywhere that this is the case.
  93. if (iRetry > 0 && pwszClientParams &&
  94. StrCmpIW(PathFindFileName(pwszClientCommand), L"netscape.exe") == 0)
  95. {
  96. StrCpyNW(pwszClientParams, L"-mail", dwCchParams);
  97. }
  98. hr = S_OK;
  99. }
  100. else
  101. {
  102. hr = HRESULT_FROM_WIN32(dwError);
  103. }
  104. // Do not RegCloseKey(HKEY_CLASSES_ROOT) or the world will end!
  105. if (hkClient != HKEY_CLASSES_ROOT)
  106. RegCloseKey(hkClient);
  107. }
  108. return hr;
  109. }
  110. // Gets the friendly name for the default Mail, News, etc Client.
  111. // Note that this doesn't work for Webbrowser.
  112. STDAPI SHGetDefaultClientNameW(LPCWSTR pwszClientType,
  113. LPWSTR pwszBuf, DWORD dwCch)
  114. {
  115. HRESULT hr = E_INVALIDARG;
  116. HKEY hkClient;
  117. WCHAR wszDefault[MAX_PATH];
  118. ASSERT(pwszBuf && dwCch);
  119. hkClient = _GetClientKeyAndDefaultW(pwszClientType, wszDefault, ARRAYSIZE(wszDefault));
  120. if (hkClient && hkClient != HKEY_CLASSES_ROOT)
  121. {
  122. LONG cbValue = dwCch * sizeof(TCHAR);
  123. if (RegQueryValueW(hkClient, wszDefault, pwszBuf, &cbValue) == ERROR_SUCCESS &&
  124. pwszBuf[0])
  125. {
  126. hr = S_OK;
  127. }
  128. RegCloseKey(hkClient);
  129. }
  130. return hr;
  131. }