Leaked source code of windows server 2003
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.

436 lines
12 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1999 **
  4. //*********************************************************************
  5. //
  6. // EULA.CPP - Header for the implementation of CEula
  7. //
  8. // HISTORY:
  9. //
  10. // 1/27/99 a-jaswed Created.
  11. //
  12. #include "precomp.h"
  13. #include "msobmain.h"
  14. #include "eula.h"
  15. #include "appdefs.h"
  16. #include "dispids.h"
  17. #include "resource.h"
  18. #define REG_VAL_EULA L"Eula"
  19. #define EULA_FILE_NAME L"EULA.TXT"
  20. DISPATCHLIST EulaExternalInterface[] =
  21. {
  22. {L"get_EULAAcceptance", DISPID_EULA_GET_ACCEPTED },
  23. {L"set_EULAAcceptance", DISPID_EULA_SET_ACCEPTED },
  24. {L"ValidateEULA", DISPID_EULA_VALIDATEEULA }
  25. };
  26. /////////////////////////////////////////////////////////////
  27. // CEula::CEula
  28. CEula::CEula(HINSTANCE hInstance)
  29. {
  30. WCHAR szKeyName[] = REG_KEY_OOBE_TEMP,
  31. szBuffer[16] = L"\0";
  32. HKEY hKey = NULL;
  33. DWORD cb = sizeof(szBuffer),
  34. dwType;
  35. // Init member vars
  36. m_cRef = 0;
  37. m_hInstance = hInstance;
  38. // Retreive the state from the registry.
  39. //
  40. m_bAccepted = ( ( RegOpenKey(HKEY_LOCAL_MACHINE, szKeyName, &hKey) == ERROR_SUCCESS ) &&
  41. ( RegQueryValueEx(hKey, REG_VAL_EULA, NULL, &dwType, (LPBYTE) szBuffer, &cb) == ERROR_SUCCESS ) &&
  42. ( cb > 0 ) &&
  43. ( dwType == REG_SZ ) &&
  44. ( szBuffer[0] == L'1' ) &&
  45. ( szBuffer[1] == L'\0' ) );
  46. if ( hKey )
  47. RegCloseKey(hKey);
  48. // Preconfigured EULA for direct OEM scenario
  49. //
  50. WCHAR szEulaValue[MAX_PATH] = L"\0";
  51. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  52. NOEULA_REGKEY,
  53. 0,
  54. KEY_READ,
  55. &hKey) == ERROR_SUCCESS)
  56. {
  57. DWORD cb, dwType;
  58. cb = sizeof(szEulaValue);
  59. if (ERROR_SUCCESS == RegQueryValueEx(hKey, REG_VAL_NOEULA, NULL, &dwType, (LPBYTE) szEulaValue, &cb))
  60. {
  61. if(lstrcmp(szEulaValue, OOBE_SKIP_EULA_VAL) == 0)
  62. {
  63. set_EULAAcceptance(TRUE);
  64. createLicenseHtm();
  65. }
  66. }
  67. RegCloseKey(hKey);
  68. }
  69. }
  70. /////////////////////////////////////////////////////////////
  71. // CEula::~CEula
  72. CEula::~CEula()
  73. {
  74. MYASSERT(m_cRef == 0);
  75. }
  76. ////////////////////////////////////////////////
  77. ////////////////////////////////////////////////
  78. //// GET / SET :: EULAAcceptance
  79. ////
  80. HRESULT CEula::set_EULAAcceptance(BOOL bVal)
  81. {
  82. WCHAR szKeyName[] = REG_KEY_OOBE_TEMP;
  83. HKEY hKey;
  84. m_bAccepted = bVal;
  85. // Save the state of the EULA acceptance.
  86. //
  87. if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS )
  88. {
  89. if ( bVal )
  90. RegSetValueEx(hKey, REG_VAL_EULA, 0, REG_SZ, (LPBYTE) L"1", BYTES_REQUIRED_BY_SZ(L"1"));
  91. else
  92. RegDeleteValue(hKey, REG_VAL_EULA);
  93. RegFlushKey(hKey);
  94. RegCloseKey(hKey);
  95. }
  96. return S_OK;
  97. }
  98. HRESULT CEula::get_EULAAcceptance(BOOL* pbVal)
  99. {
  100. *pbVal = m_bAccepted;
  101. return S_OK;
  102. }
  103. HRESULT CEula::GetValidEulaFilename(BSTR* bstrVal)
  104. {
  105. WCHAR szEulaPath[MAX_PATH]= L"\0";
  106. BOOL bValid = FALSE;
  107. *bstrVal = NULL;
  108. #if 0
  109. if (SetupGetValidEulaFilename(EULA_FILE_NAME, szEulaPath))
  110. {
  111. *bstrVal = SysAllocString(szEulaPath);
  112. }
  113. else
  114. {
  115. *bstrVal = NULL;
  116. }
  117. #else
  118. // BUGBUG: Temporary hack until SetupGetValidEulaFilename is implemented.
  119. #define EULA_FILENAME L"EULA.TXT"
  120. if (0 != GetSystemDirectory(szEulaPath, MAX_PATH))
  121. {
  122. if (MAX_PATH >
  123. lstrlen(szEulaPath) + lstrlen(EULA_FILENAME) + lstrlen(L"\\")
  124. )
  125. {
  126. lstrcat(szEulaPath, L"\\");
  127. lstrcat(szEulaPath, EULA_FILENAME);
  128. *bstrVal = SysAllocString(szEulaPath);
  129. }
  130. }
  131. #endif // 0
  132. return (NULL != *bstrVal) ? S_OK : E_FAIL;
  133. }
  134. HRESULT CEula::createLicenseHtm()
  135. {
  136. // Get the handle of the HTML Application file stored in this .dll's resources.
  137. HRSRC hRes = 0;
  138. HGLOBAL hGlobalMem = 0;
  139. WCHAR szDir [MAX_PATH] = L"\0";
  140. int nLen = 0, i = 0;
  141. LPVOID pBytes = 0;
  142. BSTR bstrEulaPath = NULL;
  143. WCHAR szEulaPath[MAX_PATH] = L"\0";
  144. WCHAR* szIn = NULL;
  145. if ( !( hRes = FindResource( m_hInstance, L"LICENSE_RESOURCE.HTM", RT_HTML ) ) )
  146. {
  147. return E_FAIL;
  148. }
  149. // Look for at least a few bytes of script, or something is wrong.
  150. nLen = SizeofResource( m_hInstance, hRes );
  151. if ( ( hGlobalMem = LoadResource( m_hInstance, hRes ) ) == NULL )
  152. {
  153. return E_FAIL;
  154. }
  155. // Get a pointer to the bytes.
  156. if ( ( pBytes = (LPBYTE)LockResource( hGlobalMem )) == NULL )
  157. {
  158. return E_FAIL;
  159. }
  160. GetValidEulaFilename(&bstrEulaPath);
  161. GetOOBEPath(szDir);
  162. // Replace backslash with forwardslash for Jscript
  163. szIn = szDir;
  164. for ( i = 0; i < lstrlen(szDir); i++) { if (szIn[i] == L'\\') szIn[i] = L'/'; }
  165. lstrcpy(szEulaPath, bstrEulaPath);
  166. szIn = szEulaPath;
  167. for ( i = 0; i < lstrlen(szDir); i++) { if (szIn[i] == L'\\') szIn[i] = L'/'; }
  168. // Create "This software is licensed.htm in the windows desktop"
  169. HANDLE hfile = INVALID_HANDLE_VALUE;
  170. DWORD cbRet = 0;
  171. WCHAR szDesktop[MAX_PATH*2];
  172. GetDesktopDirectory(szDesktop);
  173. lstrcat(szDesktop, L"\\");
  174. WCHAR szTitle [MAX_PATH] = L"\0";
  175. LoadString(m_hInstance, IDS_SFTW_IS_LICENSED, szTitle, sizeof(szTitle)/sizeof(szTitle[0]));
  176. lstrcat(szDesktop, szTitle);
  177. hfile = CreateFile(szDesktop, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  178. if (hfile != INVALID_HANDLE_VALUE)
  179. {
  180. WCHAR *szCurr = (LPWSTR)pBytes;
  181. WCHAR *szOrig = (LPWSTR)pBytes;
  182. WCHAR *szDest = NULL;
  183. // BUGBUG: Search and replace the %s with Eula and Window's path. This
  184. // should be done with messages.
  185. while(NULL != (szDest = wcschr( szCurr, L'%' )))
  186. {
  187. if (szDest+1)
  188. {
  189. if (L's' == *(szDest+1))
  190. break;
  191. }
  192. szCurr = szDest+1;
  193. }
  194. WriteFile(hfile, szOrig, (DWORD)(szDest - szOrig), (LPDWORD)&cbRet, NULL);
  195. nLen -= cbRet;
  196. WriteFile(hfile, szDir, BYTES_REQUIRED_BY_SZ(szDir), (LPDWORD)&cbRet, NULL);
  197. szCurr = szDest + 2;
  198. szOrig = szCurr;
  199. while(NULL != (szDest = wcschr( szCurr, L'%' )))
  200. {
  201. if (szDest+1)
  202. {
  203. if (L's' == *(szDest+1))
  204. break;
  205. }
  206. szCurr = szDest+1;
  207. }
  208. WriteFile(hfile, szOrig, (DWORD)(szDest - szOrig), (LPDWORD)&cbRet, NULL);
  209. nLen -= cbRet;
  210. WriteFile(hfile, szEulaPath, BYTES_REQUIRED_BY_SZ(szEulaPath), (LPDWORD)&cbRet, NULL);
  211. szCurr = szDest + 2;
  212. szOrig = szCurr;
  213. // Need to substract 4 for the %s characters
  214. WriteFile(hfile, szOrig, nLen - 4, (LPDWORD)&cbRet, NULL);
  215. CloseHandle(hfile);
  216. }
  217. FreeResource(hGlobalMem);
  218. return S_OK;
  219. }
  220. /////////////////////////////////////////////////////////////
  221. /////////////////////////////////////////////////////////////
  222. /////////////////////////////////////////////////////////////
  223. /////// IUnknown implementation
  224. ///////
  225. ///////
  226. /////////////////////////////////////////////////////////////
  227. // CEula::QueryInterface
  228. STDMETHODIMP CEula::QueryInterface(REFIID riid, LPVOID* ppvObj)
  229. {
  230. // must set out pointer parameters to NULL
  231. *ppvObj = NULL;
  232. if ( riid == IID_IUnknown)
  233. {
  234. AddRef();
  235. *ppvObj = (IUnknown*)this;
  236. return ResultFromScode(S_OK);
  237. }
  238. if (riid == IID_IDispatch)
  239. {
  240. AddRef();
  241. *ppvObj = (IDispatch*)this;
  242. return ResultFromScode(S_OK);
  243. }
  244. // Not a supported interface
  245. return ResultFromScode(E_NOINTERFACE);
  246. }
  247. /////////////////////////////////////////////////////////////
  248. // CEula::AddRef
  249. STDMETHODIMP_(ULONG) CEula::AddRef()
  250. {
  251. return ++m_cRef;
  252. }
  253. /////////////////////////////////////////////////////////////
  254. // CEula::Release
  255. STDMETHODIMP_(ULONG) CEula::Release()
  256. {
  257. return --m_cRef;
  258. }
  259. /////////////////////////////////////////////////////////////
  260. /////////////////////////////////////////////////////////////
  261. /////////////////////////////////////////////////////////////
  262. /////// IDispatch implementation
  263. ///////
  264. ///////
  265. /////////////////////////////////////////////////////////////
  266. // CEula::GetTypeInfo
  267. STDMETHODIMP CEula::GetTypeInfo(UINT, LCID, ITypeInfo**)
  268. {
  269. return E_NOTIMPL;
  270. }
  271. /////////////////////////////////////////////////////////////
  272. // CEula::GetTypeInfoCount
  273. STDMETHODIMP CEula::GetTypeInfoCount(UINT* pcInfo)
  274. {
  275. return E_NOTIMPL;
  276. }
  277. /////////////////////////////////////////////////////////////
  278. // CEula::GetIDsOfNames
  279. STDMETHODIMP CEula::GetIDsOfNames(REFIID riid,
  280. OLECHAR** rgszNames,
  281. UINT cNames,
  282. LCID lcid,
  283. DISPID* rgDispId)
  284. {
  285. HRESULT hr = DISP_E_UNKNOWNNAME;
  286. rgDispId[0] = DISPID_UNKNOWN;
  287. for (int iX = 0; iX < sizeof(EulaExternalInterface)/sizeof(DISPATCHLIST); iX ++)
  288. {
  289. if(lstrcmp(EulaExternalInterface[iX].szName, rgszNames[0]) == 0)
  290. {
  291. rgDispId[0] = EulaExternalInterface[iX].dwDispID;
  292. hr = NOERROR;
  293. break;
  294. }
  295. }
  296. // Set the disid's for the parameters
  297. if (cNames > 1)
  298. {
  299. // Set a DISPID for function parameters
  300. for (UINT i = 1; i < cNames ; i++)
  301. rgDispId[i] = DISPID_UNKNOWN;
  302. }
  303. return hr;
  304. }
  305. /////////////////////////////////////////////////////////////
  306. // CEula::Invoke
  307. HRESULT CEula::Invoke
  308. (
  309. DISPID dispidMember,
  310. REFIID riid,
  311. LCID lcid,
  312. WORD wFlags,
  313. DISPPARAMS* pdispparams,
  314. VARIANT* pvarResult,
  315. EXCEPINFO* pexcepinfo,
  316. UINT* puArgErr
  317. )
  318. {
  319. HRESULT hr = S_OK;
  320. switch(dispidMember)
  321. {
  322. case DISPID_EULA_GET_ACCEPTED:
  323. {
  324. TRACE(L"DISPID_EULA_GET_ACCEPTED\n");
  325. if(pvarResult)
  326. {
  327. VariantInit(pvarResult);
  328. V_VT(pvarResult) = VT_BOOL;
  329. get_EULAAcceptance((BOOL*)&(pvarResult->boolVal));
  330. }
  331. break;
  332. }
  333. case DISPID_EULA_SET_ACCEPTED:
  334. {
  335. TRACE(L"DISPID_EULA_SET_ACCEPTED\n");
  336. if(pdispparams && &pdispparams[0].rgvarg[0])
  337. set_EULAAcceptance(pdispparams[0].rgvarg[0].boolVal);
  338. break;
  339. }
  340. case DISPID_EULA_VALIDATEEULA:
  341. {
  342. TRACE(L"DISPID_EULA_VALIDATEEULA\n");
  343. if(pvarResult)
  344. {
  345. VariantInit(pvarResult);
  346. V_VT(pvarResult) = VT_BSTR;
  347. GetValidEulaFilename(&(pvarResult->bstrVal));
  348. }
  349. break;
  350. }
  351. default:
  352. {
  353. hr = DISP_E_MEMBERNOTFOUND;
  354. break;
  355. }
  356. }
  357. return hr;
  358. }