//+-------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1994 - 1997. // // File: script.cpp // // Contents: Functions for working with Darwin files, both packages, // transforms and scripts. // // Classes: // // Functions: BuildScriptAndGetActInfo // // History: 1-14-1998 stevebl Created // //--------------------------------------------------------------------------- #include "precomp.hxx" #define REG_TEMP L"temporary key created by ADE" HRESULT GetShellExtensions(HKEY hkey, PACKAGEDETAIL &pd); HRESULT GetCLSIDs(HKEY hkey, PACKAGEDETAIL &pd); HRESULT GetIIDs(HKEY hkey, PACKAGEDETAIL &pd); HRESULT GetTLBs(HKEY hkey, PACKAGEDETAIL &pd); //+-------------------------------------------------------------------------- // // Function: RegDeleteTree // // Synopsis: deletes a registry key and all of its children // // Arguments: [hKey] - handle to the key's parent // [szSubKey] - name of the key to be deleted // // Returns: ERROR_SUCCESS // // History: 1-14-1998 stevebl Moved from old project // //--------------------------------------------------------------------------- LONG RegDeleteTree(HKEY hKey, TCHAR * szSubKey) { HKEY hKeyNew; LONG lResult = RegOpenKey(hKey, szSubKey, &hKeyNew); if (lResult != ERROR_SUCCESS) { return lResult; } TCHAR szName[256]; while (ERROR_SUCCESS == RegEnumKey(hKeyNew, 0, szName, 256)) { RegDeleteTree(hKeyNew, szName); } RegCloseKey(hKeyNew); return RegDeleteKey(hKey, szSubKey); } //+-------------------------------------------------------------------------- // // Function: BuildScriptAndGetActInfo // // Synopsis: Builds the script file and fills in the ACTINFO structure // member in the PACKAGEDETAIL structure. // // Arguments: [szScriptRoot] - [in] the subdirectory that the script file // should be place in. // [pd] - [in/out] package detail structure - see // notes for complete list of fields that // should be filled in and the list of fields // that are set on return // // Returns: S_OK - success // - error // // Modifies: all fields under pd.pActInfo (only on success) // also modifies pd.pInstallInfo->cScriptLen // // History: 1-14-1998 stevebl Created // // Notes: On input: // pd.cSources must be >= 1. // pd.pszSourceList[] contains the MSI package and the list of // (if any) transforms to be applied. // pd.pPlatformInfo should be completely filled in (only one // locale). // pd.pInstallInfo->pszScriptFile contains the name of the // script file to be generated. // // On output: // The script file will be generated under the appropriate name // and in the appropriate directory. // pd.pActInfo will be completely filled in. // //--------------------------------------------------------------------------- HRESULT BuildScriptAndGetActInfo(CString szScriptRoot, PACKAGEDETAIL & pd) { CHourglass hourglass; HRESULT hr; UINT uMsiStatus; LONG error; int i; CString szScriptPath = szScriptRoot; szScriptPath += L"\\"; szScriptPath += pd.pInstallInfo->pszScriptPath; CString szTransformList = L""; for (i = 1; i < pd.cSources; i++) { if (i < 1) { szTransformList += L";"; } szTransformList += pd.pszSourceList[i]; } // disable MSI ui MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); // build the script file uMsiStatus = MsiAdvertiseProduct(pd.pszSourceList[0], szScriptPath, szTransformList, LANGIDFROMLCID(pd.pPlatformInfo->prgLocale[0])); if (uMsiStatus) { // an error occured return HRESULT_FROM_WIN32((long)uMsiStatus); } // get script file length HANDLE hFile = CreateFile(szScriptPath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile != INVALID_HANDLE_VALUE) { pd.pInstallInfo->cScriptLen = GetFileSize(hFile, NULL); CloseHandle(hFile); } // // dump everyting into the registry // // nuke old temporary registry key just to be safe: RegDeleteTree(HKEY_CLASSES_ROOT, REG_TEMP); // create temporary registry key DWORD dwDisp; HKEY hkey; error = RegCreateKeyEx(HKEY_CLASSES_ROOT, REG_TEMP, 0, L"REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hkey, &dwDisp); hr = HRESULT_FROM_WIN32(error); if (SUCCEEDED(hr)) { uMsiStatus = MsiProcessAdvertiseScript(szScriptPath, 0, hkey, FALSE, FALSE); hr = HRESULT_FROM_WIN32(uMsiStatus); if (SUCCEEDED(hr)) { // fill in the ActInfo GetShellExtensions(hkey, pd); GetCLSIDs(hkey, pd); GetIIDs(hkey, pd); GetTLBs(hkey, pd); } RegCloseKey(hkey); RegDeleteTree(HKEY_CLASSES_ROOT, REG_TEMP); } return hr; } //+-------------------------------------------------------------------------- // // Function: GetShellExtensions // // Synopsis: fills the shell extension part of the PACKAGEDETAIL structure // // Arguments: [hkey] - key containing the registry info // [pd] - PACKAGEDETAIL structure // // History: 1-15-1998 stevebl Created // //--------------------------------------------------------------------------- HRESULT GetShellExtensions(HKEY hkey, PACKAGEDETAIL &pd) { std::vector v; TCHAR szName[256]; LONG lResult; UINT n = 0; while (ERROR_SUCCESS == RegEnumKey(hkey, n++, szName, 256)) { if (szName[0] == L'.') { v.push_back(szName); } } n = v.size(); pd.pActInfo->cShellFileExt = n; if (n > 0) { pd.pActInfo->prgShellFileExt = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n); pd.pActInfo->prgPriority = (UINT *) OLEALLOC(sizeof(UINT) * n); while (n--) { CString &sz = v[n]; sz.MakeLower(); OLESAFE_COPYSTRING(pd.pActInfo->prgShellFileExt[n], sz); pd.pActInfo->prgPriority[n] = 0; } } return S_OK; } //+-------------------------------------------------------------------------- // // Function: GetCLSIDs // // Synopsis: fills the CLSID part of the PACKAGEDETAIL structure // // Arguments: [hkey] - key containing the registry info // [pd] - PACKAGEDETAIL structure // // History: 1-15-1998 stevebl Created // //--------------------------------------------------------------------------- HRESULT GetCLSIDs(HKEY hkey, PACKAGEDETAIL &pd) { HRESULT hr; LONG lResult; HKEY hkeyNew; lResult = RegOpenKey(hkey, L"CLSID", &hkeyNew); if (lResult == ERROR_SUCCESS) { // Find all the CLSID entries and add them to our vector UINT n = 0; std::vector v; TCHAR szName[256]; while (ERROR_SUCCESS == RegEnumKey(hkeyNew, n++, szName, 256)) { CLASSDETAIL cd; memset(&cd, 0, sizeof(CLASSDETAIL)); hr = CLSIDFromString(szName, &cd.Clsid); if (SUCCEEDED(hr)) { HKEY hkeyCLSID; lResult = RegOpenKey(hkeyNew, szName, &hkeyCLSID); if (ERROR_SUCCESS == lResult) { HKEY hkeySub; DWORD dw; lResult = RegOpenKey(hkeyCLSID, L"TreatAs", &hkeySub); if (ERROR_SUCCESS == lResult) { dw = 256 * sizeof(TCHAR); lResult = RegQueryValueEx(hkeySub, L"", 0, NULL, (LPBYTE) szName, &dw); if (ERROR_SUCCESS == lResult) { CLSIDFromString(szName, &cd.TreatAs); } RegCloseKey(hkeySub); } TCHAR szProgID[256]; szProgID[0] = 0; TCHAR szVersionIndependentProgID[256]; szVersionIndependentProgID[0] = 0; lResult = RegOpenKey(hkeyCLSID, L"ProgID", &hkeySub); if (ERROR_SUCCESS == lResult) { dw = 256 * sizeof(TCHAR); RegQueryValueEx(hkeySub, L"", 0, NULL, (LPBYTE) szProgID, &dw); RegCloseKey(hkeySub); } lResult = RegOpenKey(hkeyCLSID, L"VersionIndependentProgID", &hkeySub); if (ERROR_SUCCESS == lResult) { dw = 256 * sizeof(TCHAR); RegQueryValueEx(hkeySub, L"", 0, NULL, (LPBYTE) szVersionIndependentProgID, &dw); RegCloseKey(hkeySub); } DWORD cProgId = 0; if (szProgID[0]) { cProgId++; } if (szVersionIndependentProgID[0]) { cProgId++; } if (cProgId > 0) { cd.cProgId = cProgId; cd.prgProgId = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * cProgId); cProgId = 0; if (szProgID[0]) { OLESAFE_COPYSTRING(cd.prgProgId[cProgId], szProgID); cProgId++; } if (szVersionIndependentProgID[0]) { OLESAFE_COPYSTRING(cd.prgProgId[cProgId], szVersionIndependentProgID); } } RegCloseKey(hkeyCLSID); } v.push_back(cd); } } RegCloseKey(hkeyNew); // create the list of CLASSDETAIL structures n = v.size(); pd.pActInfo->cClasses = n; if (n > 0) { pd.pActInfo->pClasses = (CLASSDETAIL *) OLEALLOC(sizeof(CLASSDETAIL) * n); while (n--) { pd.pActInfo->pClasses[n] = v[n]; } } } return S_OK; } //+-------------------------------------------------------------------------- // // Function: GetIIDs // // Synopsis: fills in the Interface section of the PACKAGEDETAIL structure // // Arguments: [hkey] - key containing the registry info // [pd] - PACKAGEDETAIL structure // // History: 1-15-1998 stevebl Created // //--------------------------------------------------------------------------- HRESULT GetIIDs(HKEY hkey, PACKAGEDETAIL &pd) { HRESULT hr; LONG lResult; HKEY hkeyNew; lResult = RegOpenKey(hkey, L"Interface", &hkeyNew); if (lResult == ERROR_SUCCESS) { // Find all the IID entries and add them to our vector UINT n = 0; std::vector v; TCHAR szName[256]; while (ERROR_SUCCESS == RegEnumKey(hkeyNew, n++, szName, 256)) { GUID g; hr = CLSIDFromString(szName, &g); if (SUCCEEDED(hr)) { v.push_back(g); } } RegCloseKey(hkeyNew); // create the list n = v.size(); pd.pActInfo->cInterfaces = n; if (n > 0) { pd.pActInfo->prgInterfaceId = (IID *) OLEALLOC(sizeof(IID) * n); while (n--) { pd.pActInfo->prgInterfaceId[n] = v[n]; } } } return S_OK; } //+-------------------------------------------------------------------------- // // Function: GetTLBs // // Synopsis: fills in the type library section of the PACKAGEDETAIL struct // // Arguments: [hkey] - key containing the registry info // [pd] - PACKAGEDETAIL structure // // History: 1-15-1998 stevebl Created // //--------------------------------------------------------------------------- HRESULT GetTLBs(HKEY hkey, PACKAGEDETAIL &pd) { HRESULT hr; LONG lResult; HKEY hkeyNew; lResult = RegOpenKey(hkey, L"TypeLib", &hkeyNew); if (lResult == ERROR_SUCCESS) { // Find all the TLB entries and add them to our vector UINT n = 0; std::vector v; TCHAR szName[256]; while (ERROR_SUCCESS == RegEnumKey(hkeyNew, n++, szName, 256)) { GUID g; hr = CLSIDFromString(szName, &g); if (SUCCEEDED(hr)) { v.push_back(g); } } RegCloseKey(hkeyNew); // create the list n = v.size(); pd.pActInfo->cTypeLib = n; if (n > 0) { pd.pActInfo->prgTlbId = (GUID *) OLEALLOC(sizeof(GUID) * n); while (n--) { pd.pActInfo->prgTlbId[n] = v[n]; } } } return S_OK; }