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.

452 lines
14 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1997.
  5. //
  6. // File: script.cpp
  7. //
  8. // Contents: Functions for working with Darwin files, both packages,
  9. // transforms and scripts.
  10. //
  11. // Classes:
  12. //
  13. // Functions: BuildScriptAndGetActInfo
  14. //
  15. // History: 1-14-1998 stevebl Created
  16. //
  17. //---------------------------------------------------------------------------
  18. #include "precomp.hxx"
  19. #define REG_TEMP L"temporary key created by ADE"
  20. HRESULT GetShellExtensions(HKEY hkey, PACKAGEDETAIL &pd);
  21. HRESULT GetCLSIDs(HKEY hkey, PACKAGEDETAIL &pd);
  22. HRESULT GetIIDs(HKEY hkey, PACKAGEDETAIL &pd);
  23. HRESULT GetTLBs(HKEY hkey, PACKAGEDETAIL &pd);
  24. //+--------------------------------------------------------------------------
  25. //
  26. // Function: RegDeleteTree
  27. //
  28. // Synopsis: deletes a registry key and all of its children
  29. //
  30. // Arguments: [hKey] - handle to the key's parent
  31. // [szSubKey] - name of the key to be deleted
  32. //
  33. // Returns: ERROR_SUCCESS
  34. //
  35. // History: 1-14-1998 stevebl Moved from old project
  36. //
  37. //---------------------------------------------------------------------------
  38. LONG RegDeleteTree(HKEY hKey, TCHAR * szSubKey)
  39. {
  40. HKEY hKeyNew;
  41. LONG lResult = RegOpenKey(hKey, szSubKey, &hKeyNew);
  42. if (lResult != ERROR_SUCCESS)
  43. {
  44. return lResult;
  45. }
  46. TCHAR szName[256];
  47. while (ERROR_SUCCESS == RegEnumKey(hKeyNew, 0, szName, 256))
  48. {
  49. RegDeleteTree(hKeyNew, szName);
  50. }
  51. RegCloseKey(hKeyNew);
  52. return RegDeleteKey(hKey, szSubKey);
  53. }
  54. //+--------------------------------------------------------------------------
  55. //
  56. // Function: BuildScriptAndGetActInfo
  57. //
  58. // Synopsis: Builds the script file and fills in the ACTINFO structure
  59. // member in the PACKAGEDETAIL structure.
  60. //
  61. // Arguments: [szScriptRoot] - [in] the subdirectory that the script file
  62. // should be place in.
  63. // [pd] - [in/out] package detail structure - see
  64. // notes for complete list of fields that
  65. // should be filled in and the list of fields
  66. // that are set on return
  67. //
  68. // Returns: S_OK - success
  69. // <other> - error
  70. //
  71. // Modifies: all fields under pd.pActInfo (only on success)
  72. // also modifies pd.pInstallInfo->cScriptLen
  73. //
  74. // History: 1-14-1998 stevebl Created
  75. //
  76. // Notes: On input:
  77. // pd.cSources must be >= 1.
  78. // pd.pszSourceList[] contains the MSI package and the list of
  79. // (if any) transforms to be applied.
  80. // pd.pPlatformInfo should be completely filled in (only one
  81. // locale).
  82. // pd.pInstallInfo->pszScriptFile contains the name of the
  83. // script file to be generated.
  84. //
  85. // On output:
  86. // The script file will be generated under the appropriate name
  87. // and in the appropriate directory.
  88. // pd.pActInfo will be completely filled in.
  89. //
  90. //---------------------------------------------------------------------------
  91. HRESULT BuildScriptAndGetActInfo(CString szScriptRoot, PACKAGEDETAIL & pd)
  92. {
  93. CHourglass hourglass;
  94. HRESULT hr;
  95. UINT uMsiStatus;
  96. LONG error;
  97. int i;
  98. CString szScriptPath = szScriptRoot;
  99. szScriptPath += L"\\";
  100. szScriptPath += pd.pInstallInfo->pszScriptPath;
  101. CString szTransformList = L"";
  102. for (i = 1; i < pd.cSources; i++)
  103. {
  104. if (i < 1)
  105. {
  106. szTransformList += L";";
  107. }
  108. szTransformList += pd.pszSourceList[i];
  109. }
  110. // disable MSI ui
  111. MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
  112. // build the script file
  113. uMsiStatus = MsiAdvertiseProduct(pd.pszSourceList[0],
  114. szScriptPath,
  115. szTransformList,
  116. LANGIDFROMLCID(pd.pPlatformInfo->prgLocale[0]));
  117. if (uMsiStatus)
  118. {
  119. // an error occured
  120. return HRESULT_FROM_WIN32((long)uMsiStatus);
  121. }
  122. // get script file length
  123. HANDLE hFile = CreateFile(szScriptPath,
  124. GENERIC_READ,
  125. 0,
  126. 0,
  127. OPEN_EXISTING,
  128. FILE_ATTRIBUTE_NORMAL,
  129. 0);
  130. if (hFile != INVALID_HANDLE_VALUE)
  131. {
  132. pd.pInstallInfo->cScriptLen = GetFileSize(hFile, NULL);
  133. CloseHandle(hFile);
  134. }
  135. //
  136. // dump everyting into the registry
  137. //
  138. // nuke old temporary registry key just to be safe:
  139. RegDeleteTree(HKEY_CLASSES_ROOT, REG_TEMP);
  140. // create temporary registry key
  141. DWORD dwDisp;
  142. HKEY hkey;
  143. error = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  144. REG_TEMP,
  145. 0,
  146. L"REG_SZ",
  147. REG_OPTION_NON_VOLATILE,
  148. KEY_ALL_ACCESS,
  149. 0,
  150. &hkey,
  151. &dwDisp);
  152. hr = HRESULT_FROM_WIN32(error);
  153. if (SUCCEEDED(hr))
  154. {
  155. uMsiStatus = MsiProcessAdvertiseScript(szScriptPath,
  156. 0,
  157. hkey,
  158. FALSE,
  159. FALSE);
  160. hr = HRESULT_FROM_WIN32(uMsiStatus);
  161. if (SUCCEEDED(hr))
  162. {
  163. // fill in the ActInfo
  164. GetShellExtensions(hkey, pd);
  165. GetCLSIDs(hkey, pd);
  166. GetIIDs(hkey, pd);
  167. GetTLBs(hkey, pd);
  168. }
  169. RegCloseKey(hkey);
  170. RegDeleteTree(HKEY_CLASSES_ROOT, REG_TEMP);
  171. }
  172. return hr;
  173. }
  174. //+--------------------------------------------------------------------------
  175. //
  176. // Function: GetShellExtensions
  177. //
  178. // Synopsis: fills the shell extension part of the PACKAGEDETAIL structure
  179. //
  180. // Arguments: [hkey] - key containing the registry info
  181. // [pd] - PACKAGEDETAIL structure
  182. //
  183. // History: 1-15-1998 stevebl Created
  184. //
  185. //---------------------------------------------------------------------------
  186. HRESULT GetShellExtensions(HKEY hkey, PACKAGEDETAIL &pd)
  187. {
  188. std::vector<CString> v;
  189. TCHAR szName[256];
  190. LONG lResult;
  191. UINT n = 0;
  192. while (ERROR_SUCCESS == RegEnumKey(hkey, n++, szName, 256))
  193. {
  194. if (szName[0] == L'.')
  195. {
  196. v.push_back(szName);
  197. }
  198. }
  199. n = v.size();
  200. pd.pActInfo->cShellFileExt = n;
  201. if (n > 0)
  202. {
  203. pd.pActInfo->prgShellFileExt = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n);
  204. pd.pActInfo->prgPriority = (UINT *) OLEALLOC(sizeof(UINT) * n);
  205. while (n--)
  206. {
  207. CString &sz = v[n];
  208. sz.MakeLower();
  209. OLESAFE_COPYSTRING(pd.pActInfo->prgShellFileExt[n], sz);
  210. pd.pActInfo->prgPriority[n] = 0;
  211. }
  212. }
  213. return S_OK;
  214. }
  215. //+--------------------------------------------------------------------------
  216. //
  217. // Function: GetCLSIDs
  218. //
  219. // Synopsis: fills the CLSID part of the PACKAGEDETAIL structure
  220. //
  221. // Arguments: [hkey] - key containing the registry info
  222. // [pd] - PACKAGEDETAIL structure
  223. //
  224. // History: 1-15-1998 stevebl Created
  225. //
  226. //---------------------------------------------------------------------------
  227. HRESULT GetCLSIDs(HKEY hkey, PACKAGEDETAIL &pd)
  228. {
  229. HRESULT hr;
  230. LONG lResult;
  231. HKEY hkeyNew;
  232. lResult = RegOpenKey(hkey, L"CLSID", &hkeyNew);
  233. if (lResult == ERROR_SUCCESS)
  234. {
  235. // Find all the CLSID entries and add them to our vector
  236. UINT n = 0;
  237. std::vector<CLASSDETAIL> v;
  238. TCHAR szName[256];
  239. while (ERROR_SUCCESS == RegEnumKey(hkeyNew, n++, szName, 256))
  240. {
  241. CLASSDETAIL cd;
  242. memset(&cd, 0, sizeof(CLASSDETAIL));
  243. hr = CLSIDFromString(szName, &cd.Clsid);
  244. if (SUCCEEDED(hr))
  245. {
  246. HKEY hkeyCLSID;
  247. lResult = RegOpenKey(hkeyNew, szName, &hkeyCLSID);
  248. if (ERROR_SUCCESS == lResult)
  249. {
  250. HKEY hkeySub;
  251. DWORD dw;
  252. lResult = RegOpenKey(hkeyCLSID, L"TreatAs", &hkeySub);
  253. if (ERROR_SUCCESS == lResult)
  254. {
  255. dw = 256 * sizeof(TCHAR);
  256. lResult = RegQueryValueEx(hkeySub, L"", 0, NULL, (LPBYTE) szName, &dw);
  257. if (ERROR_SUCCESS == lResult)
  258. {
  259. CLSIDFromString(szName, &cd.TreatAs);
  260. }
  261. RegCloseKey(hkeySub);
  262. }
  263. TCHAR szProgID[256];
  264. szProgID[0] = 0;
  265. TCHAR szVersionIndependentProgID[256];
  266. szVersionIndependentProgID[0] = 0;
  267. lResult = RegOpenKey(hkeyCLSID, L"ProgID", &hkeySub);
  268. if (ERROR_SUCCESS == lResult)
  269. {
  270. dw = 256 * sizeof(TCHAR);
  271. RegQueryValueEx(hkeySub, L"", 0, NULL, (LPBYTE) szProgID, &dw);
  272. RegCloseKey(hkeySub);
  273. }
  274. lResult = RegOpenKey(hkeyCLSID, L"VersionIndependentProgID", &hkeySub);
  275. if (ERROR_SUCCESS == lResult)
  276. {
  277. dw = 256 * sizeof(TCHAR);
  278. RegQueryValueEx(hkeySub, L"", 0, NULL, (LPBYTE) szVersionIndependentProgID, &dw);
  279. RegCloseKey(hkeySub);
  280. }
  281. DWORD cProgId = 0;
  282. if (szProgID[0])
  283. {
  284. cProgId++;
  285. }
  286. if (szVersionIndependentProgID[0])
  287. {
  288. cProgId++;
  289. }
  290. if (cProgId > 0)
  291. {
  292. cd.cProgId = cProgId;
  293. cd.prgProgId = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * cProgId);
  294. cProgId = 0;
  295. if (szProgID[0])
  296. {
  297. OLESAFE_COPYSTRING(cd.prgProgId[cProgId], szProgID);
  298. cProgId++;
  299. }
  300. if (szVersionIndependentProgID[0])
  301. {
  302. OLESAFE_COPYSTRING(cd.prgProgId[cProgId], szVersionIndependentProgID);
  303. }
  304. }
  305. RegCloseKey(hkeyCLSID);
  306. }
  307. v.push_back(cd);
  308. }
  309. }
  310. RegCloseKey(hkeyNew);
  311. // create the list of CLASSDETAIL structures
  312. n = v.size();
  313. pd.pActInfo->cClasses = n;
  314. if (n > 0)
  315. {
  316. pd.pActInfo->pClasses = (CLASSDETAIL *) OLEALLOC(sizeof(CLASSDETAIL) * n);
  317. while (n--)
  318. {
  319. pd.pActInfo->pClasses[n] = v[n];
  320. }
  321. }
  322. }
  323. return S_OK;
  324. }
  325. //+--------------------------------------------------------------------------
  326. //
  327. // Function: GetIIDs
  328. //
  329. // Synopsis: fills in the Interface section of the PACKAGEDETAIL structure
  330. //
  331. // Arguments: [hkey] - key containing the registry info
  332. // [pd] - PACKAGEDETAIL structure
  333. //
  334. // History: 1-15-1998 stevebl Created
  335. //
  336. //---------------------------------------------------------------------------
  337. HRESULT GetIIDs(HKEY hkey, PACKAGEDETAIL &pd)
  338. {
  339. HRESULT hr;
  340. LONG lResult;
  341. HKEY hkeyNew;
  342. lResult = RegOpenKey(hkey, L"Interface", &hkeyNew);
  343. if (lResult == ERROR_SUCCESS)
  344. {
  345. // Find all the IID entries and add them to our vector
  346. UINT n = 0;
  347. std::vector<GUID> v;
  348. TCHAR szName[256];
  349. while (ERROR_SUCCESS == RegEnumKey(hkeyNew, n++, szName, 256))
  350. {
  351. GUID g;
  352. hr = CLSIDFromString(szName, &g);
  353. if (SUCCEEDED(hr))
  354. {
  355. v.push_back(g);
  356. }
  357. }
  358. RegCloseKey(hkeyNew);
  359. // create the list
  360. n = v.size();
  361. pd.pActInfo->cInterfaces = n;
  362. if (n > 0)
  363. {
  364. pd.pActInfo->prgInterfaceId = (IID *) OLEALLOC(sizeof(IID) * n);
  365. while (n--)
  366. {
  367. pd.pActInfo->prgInterfaceId[n] = v[n];
  368. }
  369. }
  370. }
  371. return S_OK;
  372. }
  373. //+--------------------------------------------------------------------------
  374. //
  375. // Function: GetTLBs
  376. //
  377. // Synopsis: fills in the type library section of the PACKAGEDETAIL struct
  378. //
  379. // Arguments: [hkey] - key containing the registry info
  380. // [pd] - PACKAGEDETAIL structure
  381. //
  382. // History: 1-15-1998 stevebl Created
  383. //
  384. //---------------------------------------------------------------------------
  385. HRESULT GetTLBs(HKEY hkey, PACKAGEDETAIL &pd)
  386. {
  387. HRESULT hr;
  388. LONG lResult;
  389. HKEY hkeyNew;
  390. lResult = RegOpenKey(hkey, L"TypeLib", &hkeyNew);
  391. if (lResult == ERROR_SUCCESS)
  392. {
  393. // Find all the TLB entries and add them to our vector
  394. UINT n = 0;
  395. std::vector<GUID> v;
  396. TCHAR szName[256];
  397. while (ERROR_SUCCESS == RegEnumKey(hkeyNew, n++, szName, 256))
  398. {
  399. GUID g;
  400. hr = CLSIDFromString(szName, &g);
  401. if (SUCCEEDED(hr))
  402. {
  403. v.push_back(g);
  404. }
  405. }
  406. RegCloseKey(hkeyNew);
  407. // create the list
  408. n = v.size();
  409. pd.pActInfo->cTypeLib = n;
  410. if (n > 0)
  411. {
  412. pd.pActInfo->prgTlbId = (GUID *) OLEALLOC(sizeof(GUID) * n);
  413. while (n--)
  414. {
  415. pd.pActInfo->prgTlbId[n] = v[n];
  416. }
  417. }
  418. }
  419. return S_OK;
  420. }