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.

248 lines
8.3 KiB

  1. #include <stdafx.h>
  2. #include "misc.h"
  3. #define HTTPS_URL_SCHEME L"https://"
  4. #define HTTPS_URL_SCHEME_CCH (ARRAYSIZE(HTTPS_URL_SCHEME) - 1)
  5. // wininet reg key
  6. #define WININET_REG_LOC L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\passport"
  7. #define WININET_NEXUS_API "ForceNexusLookupExW"
  8. #define PASSPORT_MAX_URL 1024
  9. typedef BOOL (STDAPICALLTYPE *PFNFORCENEXUSLOOKUPEXW) (
  10. IN BOOL fForce,
  11. IN PWSTR pwszRegUrl, // user supplied buffer ...
  12. IN OUT PDWORD pdwRegUrlLen, // ... and length (will be updated to actual length
  13. // on successful return)
  14. IN PWSTR pwszDARealm, // user supplied buffer ...
  15. IN OUT PDWORD pdwDARealmLen // ... and length (will be updated to actual length
  16. // on successful return)
  17. );
  18. // Misc functions
  19. HRESULT PassportGetURL(PCWSTR pszName, PWSTR pszBuf, PDWORD pdwBufLen);
  20. VOID PassportForceNexusRepopulate();
  21. class CPassportClientServices :
  22. public CObjectSafety,
  23. public CImpIDispatch,
  24. public IPassportClientServices
  25. {
  26. public:
  27. CPassportClientServices() :
  28. CImpIDispatch(LIBID_Shell32, 1, 0, IID_IPassportClientServices),
  29. _cRef(1) {}
  30. // IUnknown
  31. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj);
  32. STDMETHOD_(ULONG,AddRef)(void);
  33. STDMETHOD_(ULONG,Release)(void);
  34. // IDispatch
  35. STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
  36. { return E_NOTIMPL; }
  37. STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
  38. { return CImpIDispatch::GetTypeInfo(iTInfo, lcid, ppTInfo); }
  39. STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
  40. { return CImpIDispatch::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId); }
  41. STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
  42. { return CImpIDispatch::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); }
  43. // IPassportClientServices
  44. STDMETHOD(MemberExists)(BSTR bstrUser, BSTR bstrPassword, VARIANT_BOOL* pvfExists);
  45. private:
  46. long _cRef;
  47. };
  48. STDAPI CPassportClientServices_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi)
  49. {
  50. CPassportClientServices *pPCS = new CPassportClientServices();
  51. if (!pPCS)
  52. return E_OUTOFMEMORY;
  53. HRESULT hr = pPCS->QueryInterface(IID_PPV_ARG(IUnknown, ppunk));
  54. pPCS->Release();
  55. return hr;
  56. }
  57. ULONG CPassportClientServices::AddRef()
  58. {
  59. return InterlockedIncrement(&_cRef);
  60. }
  61. ULONG CPassportClientServices::Release()
  62. {
  63. if (InterlockedDecrement(&_cRef))
  64. return _cRef;
  65. delete this;
  66. return 0;
  67. }
  68. HRESULT CPassportClientServices::QueryInterface(REFIID riid, void **ppv)
  69. {
  70. static const QITAB qit[] =
  71. {
  72. QITABENT(CPassportClientServices, IObjectSafety), // IID_IObjectSafety
  73. QITABENT(CPassportClientServices, IDispatch), // IID_IDispatch
  74. QITABENT(CPassportClientServices, IPassportClientServices), // IID_IPassportClientServices
  75. {0, 0 },
  76. };
  77. return QISearch(this, qit, riid, ppv);
  78. }
  79. // DONT_USE_HTTPS - Uncomment this #define to turn off secure sending of information - for debugging purposes only
  80. HRESULT CPassportClientServices::MemberExists(BSTR bstrUser, BSTR bstrPassword, VARIANT_BOOL* pvfExists)
  81. {
  82. *pvfExists = VARIANT_FALSE;
  83. WCHAR szURL[PASSPORT_MAX_URL];
  84. DWORD cch = PASSPORT_MAX_URL;
  85. HRESULT hr = PassportGetURL(PASSPORTURL_LOGON, szURL, &cch);
  86. if (SUCCEEDED(hr))
  87. {
  88. PBYTE lpBuffer = NULL;
  89. if (0 == StrCmpNI(szURL, HTTPS_URL_SCHEME, HTTPS_URL_SCHEME_CCH))
  90. {
  91. PWSTR pszServer = szURL + HTTPS_URL_SCHEME_CCH;
  92. // NULL terminate
  93. PWSTR psz = wcschr(pszServer, L'/');
  94. if (psz)
  95. {
  96. *psz = L'\0';
  97. }
  98. HINTERNET hInternet = InternetOpen(L"Shell Registration",
  99. INTERNET_OPEN_TYPE_PRECONFIG,
  100. NULL,
  101. NULL,
  102. 0);
  103. if (hInternet)
  104. {
  105. HINTERNET hConnection = InternetConnectW(hInternet,
  106. pszServer,
  107. INTERNET_DEFAULT_HTTPS_PORT,
  108. bstrUser,
  109. bstrPassword,
  110. INTERNET_SERVICE_HTTP,
  111. 0,
  112. 0);
  113. if (psz)
  114. {
  115. *psz = L'/';
  116. }
  117. if (hConnection)
  118. {
  119. // set username/pwd
  120. // send the GET request
  121. HINTERNET hRequest = HttpOpenRequest(hConnection,
  122. NULL,
  123. psz,
  124. L"HTTP/1.1",
  125. NULL,
  126. NULL,
  127. INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_SECURE,
  128. 0);
  129. if (hRequest)
  130. {
  131. if (HttpSendRequest(hRequest, NULL, 0, NULL, 0))
  132. {
  133. DWORD dwStatus, dwLength = sizeof(dwStatus);
  134. if (HttpQueryInfo(hRequest,
  135. HTTP_QUERY_STATUS_CODE |
  136. HTTP_QUERY_FLAG_NUMBER,
  137. &dwStatus,
  138. &dwLength,
  139. NULL))
  140. {
  141. // if 200, member is there ...
  142. if (dwStatus == 200)
  143. {
  144. *pvfExists = VARIANT_TRUE;
  145. }
  146. }
  147. }
  148. InternetCloseHandle(hRequest);
  149. }
  150. InternetCloseHandle(hConnection);
  151. }
  152. InternetCloseHandle(hInternet);
  153. }
  154. }
  155. }
  156. return S_OK;
  157. }
  158. //
  159. // read registry for the desired URL
  160. //
  161. HRESULT _PassportGetURLFromHKey(HKEY hkey, PCWSTR pszName, PWSTR pszBuf, PDWORD pdwBufLen)
  162. {
  163. HRESULT hr = E_FAIL;
  164. HKEY hk;
  165. LONG lErr = RegOpenKeyExW(hkey,
  166. WININET_REG_LOC,
  167. 0,
  168. KEY_READ,
  169. &hk);
  170. if (!lErr)
  171. {
  172. DWORD type;
  173. lErr = RegQueryValueExW(hk,
  174. pszName,
  175. 0,
  176. &type,
  177. (PBYTE)pszBuf,
  178. pdwBufLen);
  179. if ((!lErr) &&
  180. (L'\0' != *pszBuf))
  181. {
  182. hr = S_OK;
  183. }
  184. RegCloseKey(hk);
  185. }
  186. return hr;
  187. }
  188. HRESULT PassportGetURL(PCWSTR pszName, PWSTR pszBuf, PDWORD pdwBufLen)
  189. {
  190. PassportForceNexusRepopulate();
  191. HRESULT hr = _PassportGetURLFromHKey(HKEY_LOCAL_MACHINE, pszName, pszBuf, pdwBufLen);
  192. if (FAILED(hr))
  193. {
  194. hr = _PassportGetURLFromHKey(HKEY_CURRENT_USER, pszName, pszBuf, pdwBufLen);
  195. }
  196. return hr;
  197. }
  198. //
  199. // populate nexus values
  200. //
  201. // #define USE_PRIVATE_WININET
  202. VOID PassportForceNexusRepopulate()
  203. {
  204. #ifdef USE_PRIVATE_WININET
  205. HMODULE hm = LoadLibraryA(".\\wininet.dll");
  206. #else
  207. HMODULE hm = LoadLibraryA("wininet.dll");
  208. #endif
  209. if (hm)
  210. {
  211. PFNFORCENEXUSLOOKUPEXW pfnForceNexusLookupExW = (PFNFORCENEXUSLOOKUPEXW) GetProcAddress(hm, WININET_NEXUS_API);
  212. if (pfnForceNexusLookupExW)
  213. {
  214. pfnForceNexusLookupExW(TRUE, NULL, 0, NULL, 0);
  215. }
  216. FreeLibrary(hm);
  217. }
  218. }