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.

426 lines
11 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: install.cxx
  7. //
  8. // Contents: Routines for queries/install of application state in the DS.
  9. //
  10. // Functions:
  11. //
  12. // History: Feb-97 DKays Created
  13. // Nov-97 DebiM Changed for Beta2
  14. //
  15. //--------------------------------------------------------------------------
  16. #include "cstore.hxx"
  17. extern IClassAccess * gpClassAccess;
  18. //HRESULT InstallAppDetail( DWORD dwActFlags, APPDETAIL *pAppDetail );
  19. HRESULT DarwinPackageAssign( LPCWSTR pwszScript, BOOL InstallNow );
  20. void GetDefaultPlatform(CSPLATFORM *pPlatform);
  21. //+-------------------------------------------------------------------------
  22. //
  23. // CSGetClass
  24. //
  25. // Attempts to lookup and possibly install a class.
  26. //
  27. //--------------------------------------------------------------------------
  28. HRESULT CSGetClass(
  29. DWORD dwFlags,
  30. uCLSSPEC * pClassSpec,
  31. QUERYCONTEXT * pQueryContext,
  32. CLSID * pClsid,
  33. INSTALLINFO ** ppInstallInfo
  34. )
  35. {
  36. HRESULT hr;
  37. QUERYCONTEXT QueryContext;
  38. INSTALLINFO InstallInfo;
  39. *pClsid = CLSID_NULL;
  40. *ppInstallInfo = 0;
  41. if ( pQueryContext )
  42. {
  43. QueryContext = *pQueryContext;
  44. }
  45. else
  46. {
  47. QueryContext.dwContext = CLSCTX_ALL;
  48. GetDefaultPlatform( &QueryContext.Platform );
  49. QueryContext.Locale = GetThreadLocale();
  50. QueryContext.dwVersionHi = (DWORD) -1;
  51. QueryContext.dwVersionLo = (DWORD) -1;
  52. }
  53. if ( ! gpClassAccess )
  54. return CS_E_NO_CLASSSTORE;
  55. hr = gpClassAccess->GetAppInfo( pClassSpec, &QueryContext, &InstallInfo );
  56. if ( hr != S_OK )
  57. return hr;
  58. //
  59. // Only one package is returned.
  60. //
  61. #ifdef DARWIN_ENABLED
  62. if ( DrwFilePath == InstallInfo.PathType )
  63. {
  64. hr = DarwinPackageAssign( InstallInfo.pszScriptPath, FALSE );
  65. }
  66. else
  67. #endif
  68. {
  69. /*
  70. * The APPDETAIL contains a bunch of useless info that we're not
  71. * using. If you need this stuff, then you'll have to change
  72. * the InstallAppDetail routine to work correctly with per-user
  73. * registry.
  74. *
  75. if ( pPackageDetail->pAppDetail )
  76. {
  77. for ( DWORD i = 0; i < pPackageDetail->cApps; i++ )
  78. {
  79. hr = InstallAppDetail( pPackageDetail->dwActFlags,
  80. &pPackageDetail->pAppDetail[i] );
  81. if ( hr != S_OK )
  82. {
  83. FreePackageInfo( &Package );
  84. return hr;
  85. }
  86. }
  87. }
  88. */
  89. //
  90. // Return one of the ClassIDs. This is for IE use only.
  91. //
  92. if ( pClassSpec->tyspec != TYSPEC_CLSID )
  93. {
  94. if ( InstallInfo.pClsid )
  95. *pClsid = *(InstallInfo.pClsid);
  96. }
  97. /* following is not necessary with the simplification for beta2 - DebiM
  98. //
  99. // This information is processed here and does not need to be sent
  100. // to the client.
  101. //
  102. FreeAppDetail( pPackageDetail->pAppDetail );
  103. MIDL_user_free( pPackageDetail->pAppDetail );
  104. pPackageDetail->cApps = 0;
  105. pPackageDetail->pAppDetail = 0;
  106. if ( Package.cPackages > 1 )
  107. {
  108. *ppPackageDetail = (PACKAGEDETAIL *) MIDL_user_allocate( sizeof(PACKAGEDETAIL) );
  109. if ( *ppPackageDetail )
  110. {
  111. **ppPackageDetail = *pPackageDetail;
  112. Package.pPackageDetail[0] = Package.pPackageDetail[Package.cPackages - 1];
  113. }
  114. }
  115. else
  116. {
  117. *ppPackageDetail = pPackageDetail;
  118. Package.pPackageDetail = 0;
  119. }
  120. if ( *ppPackageDetail )
  121. Package.cPackages--;
  122. //End of Beta2 simplification
  123. */
  124. }
  125. *ppInstallInfo = (INSTALLINFO *) CoTaskMemAlloc (sizeof(INSTALLINFO));
  126. memcpy( *ppInstallInfo, &InstallInfo, sizeof(INSTALLINFO) );
  127. return hr;
  128. }
  129. /*
  130. //+---------------------------------------------------------------------------
  131. //
  132. // Function: InstallAppDetail
  133. //
  134. // Synopsis: Installs an APPDETAIL obtained from the class store.
  135. //
  136. //----------------------------------------------------------------------------
  137. HRESULT InstallAppDetail(
  138. DWORD dwActFlags//,
  139. //APPDETAIL *pAppDetail)
  140. {
  141. HRESULT hr = S_OK;
  142. DWORD status;
  143. WCHAR wszAppid[40];
  144. DWORD dwOptions;
  145. HKEY hkAppID;
  146. HKEY hkCLSID;
  147. DWORD Count;
  148. DWORD Type;
  149. DWORD Size;
  150. DWORD Length;
  151. DWORD Disp;
  152. if(!pAppDetail)
  153. return E_INVALIDARG;
  154. if(pAppDetail->AppID == GUID_NULL)
  155. return E_INVALIDARG;
  156. (void) wStringFromGUID2(
  157. pAppDetail->AppID,
  158. wszAppid,
  159. sizeof(wszAppid) );
  160. if(dwActFlags & ACTFLG_RunOnce)
  161. {
  162. dwOptions = REG_OPTION_VOLATILE;
  163. }
  164. else
  165. {
  166. dwOptions = REG_OPTION_NON_VOLATILE;
  167. }
  168. //
  169. //Register the APPID.
  170. //
  171. if(dwActFlags & ACTFLG_SystemWide)
  172. {
  173. status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  174. L"Software\\Classes\\AppID",
  175. 0,
  176. KEY_WRITE,
  177. &hkAppID);
  178. }
  179. else
  180. {
  181. status = RegOpenKeyEx(HKEY_CLASSES_ROOT,
  182. L"AppID",
  183. 0,
  184. KEY_WRITE,
  185. &hkAppID);
  186. }
  187. if(ERROR_SUCCESS == status)
  188. {
  189. HKEY hAppid;
  190. status = RegCreateKeyEx(
  191. hkAppID,
  192. wszAppid,
  193. 0,
  194. NULL,
  195. dwOptions,
  196. KEY_WRITE,
  197. NULL,
  198. &hAppid,
  199. &Disp );
  200. if(ERROR_SUCCESS == status)
  201. {
  202. WCHAR * pwszNames = 0;
  203. HKEY hkSettings;
  204. unsigned __int64 time;
  205. SYSTEMTIME systemTime;
  206. //
  207. //Write the last refresh time.
  208. //
  209. GetLocalTime(&systemTime);
  210. SystemTimeToFileTime(&systemTime, (FILETIME *)&time);
  211. status = RegSetValueEx(hAppid,
  212. L"LastRefresh",
  213. 0,
  214. REG_BINARY,
  215. (LPBYTE) &time,
  216. sizeof(time));
  217. //
  218. //Write the remote server name.
  219. //
  220. Size = 0;
  221. for ( Count = 0; Count < pAppDetail->cServers; Count++ )
  222. Size += (lstrlenW(pAppDetail->prgServerNames[Count]) + 1) * sizeof(WCHAR);
  223. if (pAppDetail->cServers == 1)
  224. {
  225. Type = REG_SZ;
  226. pwszNames = pAppDetail->prgServerNames[0];
  227. }
  228. else if (pAppDetail->cServers > 1)
  229. {
  230. Size += sizeof(WCHAR);
  231. pwszNames = (WCHAR *) alloca( Size );
  232. if(pwszNames != 0)
  233. {
  234. pwszNames[0] = 0;
  235. Length = 0;
  236. for ( Count = 0; Count < pAppDetail->cServers; Count++ )
  237. {
  238. lstrcpyW( &pwszNames[Length], pAppDetail->prgServerNames[Count] );
  239. Length += lstrlenW(pAppDetail->prgServerNames[Count]) + 1;
  240. }
  241. pwszNames[Length] = 0;
  242. Type = REG_MULTI_SZ;
  243. }
  244. else
  245. {
  246. hr = E_OUTOFMEMORY;
  247. }
  248. }
  249. if(pwszNames != NULL)
  250. {
  251. status = RegSetValueEx(hAppid,
  252. L"RemoteServerName",
  253. 0,
  254. Type,
  255. (PBYTE) pwszNames,
  256. Size );
  257. if(STATUS_SUCCESS != status)
  258. {
  259. hr = HRESULT_FROM_WIN32(status);
  260. }
  261. }
  262. RegCloseKey( hAppid );
  263. }
  264. else
  265. {
  266. hr = HRESULT_FROM_WIN32(status);
  267. }
  268. RegCloseKey(hkAppID);
  269. }
  270. else
  271. {
  272. hr = HRESULT_FROM_WIN32(status);
  273. }
  274. if(FAILED(hr))
  275. {
  276. return hr;
  277. }
  278. //
  279. // Add the APPID value to all of the CLSIDs.
  280. //
  281. if(dwActFlags & ACTFLG_SystemWide)
  282. {
  283. status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  284. L"Software\\Classes\\CLSID",
  285. 0,
  286. KEY_WRITE,
  287. &hkCLSID);
  288. }
  289. else
  290. {
  291. status = RegOpenKeyEx(HKEY_CLASSES_ROOT,
  292. L"CLSID",
  293. 0,
  294. KEY_WRITE,
  295. &hkCLSID);
  296. }
  297. if(STATUS_SUCCESS == status)
  298. {
  299. HKEY hClsid;
  300. WCHAR wszClsid[40];
  301. for ( Count = 0; Count < pAppDetail->cClasses; Count++ )
  302. {
  303. (void) wStringFromGUID2(
  304. pAppDetail->prgClsIdList[Count],
  305. wszClsid,
  306. sizeof(wszClsid) );
  307. status = RegCreateKeyEx(hkCLSID,
  308. wszClsid,
  309. 0,
  310. NULL,
  311. dwOptions,
  312. KEY_SET_VALUE,
  313. NULL,
  314. &hClsid,
  315. &Disp );
  316. if (STATUS_SUCCESS == status)
  317. {
  318. status = RegSetValueEx(hClsid,
  319. L"APPID",
  320. 0,
  321. REG_SZ,
  322. (PBYTE) wszAppid,
  323. GUIDSTR_MAX * sizeof(WCHAR) );
  324. if (status != STATUS_SUCCESS)
  325. {
  326. hr = HRESULT_FROM_WIN32(status);
  327. }
  328. RegCloseKey(hClsid);
  329. }
  330. else
  331. {
  332. hr = HRESULT_FROM_WIN32(status);
  333. }
  334. }
  335. RegCloseKey(hkCLSID);
  336. }
  337. else
  338. {
  339. hr = HRESULT_FROM_WIN32(status);
  340. }
  341. return hr;
  342. }
  343. */
  344. #ifdef DARWIN_ENABLED
  345. HRESULT
  346. DarwinPackageAssign(
  347. IN LPCWSTR pwszScript,
  348. IN BOOL InstallNow )
  349. {
  350. BOOL bStatus;
  351. HRESULT hr;
  352. hr = RpcImpersonateClient( NULL );
  353. if (hr != RPC_S_OK)
  354. return hr;
  355. bStatus = AssignApplication( pwszScript, InstallNow );
  356. RevertToSelf();
  357. if ( ! bStatus )
  358. return HRESULT_FROM_WIN32( GetLastError() );
  359. return S_OK;
  360. }
  361. #endif
  362. void
  363. GetDefaultPlatform(CSPLATFORM *pPlatform)
  364. {
  365. OSVERSIONINFO VersionInformation;
  366. VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  367. GetVersionEx(&VersionInformation);
  368. pPlatform->dwPlatformId = VersionInformation.dwPlatformId;
  369. pPlatform->dwVersionHi = VersionInformation.dwMajorVersion;
  370. pPlatform->dwVersionLo = VersionInformation.dwMinorVersion;
  371. pPlatform->dwProcessorArch = DEFAULT_ARCHITECTURE;
  372. }