0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU General
0007: * Public License Version 2 only ("GPL") or the Common Development and Distribution
0008: * License("CDDL") (collectively, the "License"). You may not use this file except in
0009: * compliance with the License. You can obtain a copy of the License at
0010: * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
0011: * License for the specific language governing permissions and limitations under the
0012: * License. When distributing the software, include this License Header Notice in
0013: * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun
0014: * designates this particular file as subject to the "Classpath" exception as
0015: * provided by Sun in the GPL Version 2 section of the License file that
0016: * accompanied this code. If applicable, add the following below the License Header,
0017: * with the fields enclosed by brackets [] replaced by your own identifying
0018: * information: "Portions Copyrighted [year] [name of copyright owner]"
0019: *
0020: * Contributor(s):
0021: *
0022: * The Original Software is NetBeans. The Initial Developer of the Original Software
0023: * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
0024: * Rights Reserved.
0025: *
0026: * If you wish your version of this file to be governed by only the CDDL or only the
0027: * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
0028: * this software in this distribution under the [CDDL or GPL Version 2] license." If
0029: * you do not indicate a single choice of license, a recipient has the option to
0030: * distribute your version of this file under either the CDDL, the GPL Version 2 or
0031: * to extend the choice of license to its licensees as provided above. However, if
0032: * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
0033: * the option applies only if the new code is made subject to such option by the
0034: * copyright holder.
0035: */
0036:
0037: package org.netbeans.installer.utils.system;
0038:
0039: import java.io.File;
0040: import java.io.IOException;
0041: import java.io.InputStream;
0042: import java.util.Arrays;
0043: import java.util.LinkedList;
0044: import java.util.List;
0045: import java.util.Properties;
0046: import java.util.regex.Pattern;
0047: import org.netbeans.installer.utils.StringUtils;
0048: import org.netbeans.installer.utils.helper.EnvironmentScope;
0049: import org.netbeans.installer.utils.helper.ErrorLevel;
0050: import org.netbeans.installer.utils.ErrorManager;
0051: import org.netbeans.installer.utils.FileUtils;
0052: import org.netbeans.installer.utils.LogManager;
0053: import org.netbeans.installer.utils.ResourceUtils;
0054: import org.netbeans.installer.utils.system.shortcut.FileShortcut;
0055: import org.netbeans.installer.utils.system.shortcut.InternetShortcut;
0056: import org.netbeans.installer.utils.system.shortcut.LocationType;
0057: import org.netbeans.installer.utils.system.shortcut.Shortcut;
0058: import org.netbeans.installer.utils.SystemUtils;
0059: import org.netbeans.installer.utils.exceptions.NativeException;
0060: import org.netbeans.installer.utils.helper.ApplicationDescriptor;
0061: import org.netbeans.installer.utils.system.windows.SystemApplication;
0062: import org.netbeans.installer.utils.system.windows.FileExtension;
0063: import org.netbeans.installer.utils.system.windows.WindowsRegistry;
0064: import org.netbeans.installer.utils.helper.FilesList;
0065: import org.netbeans.installer.utils.system.launchers.Launcher;
0066: import org.netbeans.installer.utils.progress.Progress;
0067: import org.netbeans.installer.utils.system.cleaner.OnExitCleanerHandler;
0068: import org.netbeans.installer.utils.system.cleaner.ProcessOnExitCleanerHandler;
0069: import static org.netbeans.installer.utils.StringUtils.*;
0070: import static org.netbeans.installer.utils.system.windows.WindowsRegistry.*;
0071:
0072: /**
0073: *
0074: * @author Dmitry Lipin
0075: * @author Kirill Sorokin
0076: */
0077: public class WindowsNativeUtils extends NativeUtils {
0078: /////////////////////////////////////////////////////////////////////////////////
0079: // Constants
0080: public static final String LIBRARY_PATH_X86 = NATIVE_JNILIB_RESOURCE_SUFFIX
0081: + "windows/windows-x86.dll"; //NOI18N
0082: public static final String LIBRARY_PATH_X64 = NATIVE_JNILIB_RESOURCE_SUFFIX
0083: + "windows/windows-x64.dll"; //NOI18N
0084:
0085: private static final String CLEANER_RESOURCE = NATIVE_CLEANER_RESOURCE_SUFFIX
0086: + "windows/" + "cleaner.exe";
0087:
0088: private static final String CLEANER_FILENAME = "nbi-cleaner.exe";
0089:
0090: public static final String UNINSTALL_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
0091:
0092: public static final String DISPLAY_NAME = "DisplayName";
0093: public static final String DISPLAY_ICON = "DisplayIcon";
0094: public static final String UNINSTALL_STRING = "UninstallString";
0095: public static final String MODIFY_STRING = "ModifyPath";
0096: public static final String NO_MODIFY = "NoModify";
0097: public static final String NO_REPAIR = "NoRepair";
0098: public static final String INSTALL_LOCATION = "InstallLocation";
0099:
0100: private static final String NBI_UID_PREFIX = "nbi-";
0101: private static final String UID_SEPARATOR = "-";
0102:
0103: private static final int MIN_UID_INDEX = 1;
0104: private static final int MAX_UID_INDEX = 100;
0105:
0106: private static final String SHELL_FOLDERS_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
0107:
0108: public static final String CURRENT_USER_ENVIRONMENT_KEY = "Environment";
0109: public static final String ALL_USERS_ENVIRONMENT_KEY = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
0110:
0111: private static final String RUNONCE_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
0112: private static final String RUNONCE_DELETE_VALUE_NAME = "NBI Temporary Files Delete";
0113:
0114: private static final String EXT_PREFIX = "NBI.";
0115: private static final String EXT_SUFFIX = "";
0116:
0117: private static final String SEP = SEPARATOR;
0118:
0119: ///////////////////////////////////////////////////////////////////////////
0120: // File Association Constants
0121: private static final String PERCEIVED_TYPE_VALUE_NAME = "PerceivedType";
0122: private static final String CONTENT_TYPE_VALUE_NAME = "Content Type";
0123: private static final String DEFAULT_ICON_KEY_NAME = "DefaultIcon";
0124: private static final String SHELL_OPEN_COMMAND = SEP + "shell"
0125: + SEP + "open" + SEP + "command";
0126: private static final String CONTENT_TYPE_KEY = "MIME" + SEP
0127: + "Database" + SEP + "Content Type";
0128: private static final String APPLICATIONS_KEY_NAME = "Applications";
0129: private static final String FRIENDLYAPPNAME_VALUE_NAME = "FriendlyAppName";
0130: private static final String APPLICATION_VALUE_NAME = "Application";
0131: private static final String OPEN_WITH_LIST_KEY_NAME = "OpenWithList";
0132: private static final String EXTENSION_VALUE_NAME = "Extension";
0133: public static final String DEFAULT_OPEN_COMMAND = "\"%1\"";
0134:
0135: private static final String CURRENT_USER_FILE_EXT_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts";
0136: private static final String CURRENT_USER_MUI_CACHE_KEY = "Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache";
0137: private static final String OPEN_WITH_PROGIDS_KEY_NAME = "OpenWithProgids";
0138: private static final String MRULIST_VALUE_NAME = "MRUList";
0139: private static final String MRU_VALUES = "abcdefghijklmnopqrstuvwxyz";
0140:
0141: // properties for file associations
0142: private static final String CREATED = "created";
0143: private static final String EXT_PERCEIVEDTYPE_PROPERTY = "perceivedType";
0144: private static final String EXT_CONTENTTYPE_PROPERTY = "contentType";
0145: private static final String EXT_LONGEXT_PROPERTY = "longExt";
0146: private static final String EXT_DESCRIPTION_PROPERTY = "description";
0147: private static final String EXT_ICON_PROPERTY = "defaultIcon";
0148: private static final String EXT_HKCRSHELL_OPEN_COMMAND_PROPERTY = "hkcrShellOpenCommand";
0149: private static final String EXT_HKCU_DEFAULTAPP_PROPERTY = "hkcuDefaultApp";
0150: private static final String EXT_HKCU_FILEXT_PROPERTY = "hkcuFileExt";
0151: private static final String EXT_HKCR_APPLICATIONS_PROPERTY = "hkcrApplications";
0152: private static final String EXT_HKCR_OPENWITHPROGIDS_PROPERTY = "hkcrOpenWithProgids";
0153: private static final String EXT_HKCR_OPENWITHLIST_PROPERTY = "hkcrOpenWithList";
0154: private static final String EXT_HKCU_MUICACHE_PROPERTY = "hkcuMuiCache";
0155: private static final String EXT_HKCU_OPENWITHPROGIDS_PROPERTY = "hkcuOpenWithProgids";
0156: private static final String EXT_HKCU_OPENWITHLIST_PROPERTY = "hkcuOpenWithList";
0157:
0158: private static final String CURRENT_USER_CLASSES = "Software\\Classes\\";
0159: private int clSection;
0160: private String clKey;
0161: private int uninstallSection;
0162:
0163: private boolean isUserAdminSet;
0164: private boolean isUserAdmin;
0165:
0166: //////////////////////////////////////////////////////////////////////////
0167: // file access
0168: // windows API constants
0169: private static final int FILE_READ_DATA = 0;
0170: private static final int FILE_LIST_DIRECTORY = 0;
0171: private static final int FILE_WRITE_DATA = 1;
0172: private static final int FILE_ADD_FILE = 1;
0173: private static final int FILE_APPEND_DATA = 4;
0174: private static final int FILE_ADD_SUBDIRECTORY = 4;
0175: private static final int FILE_READ_EA = 8;
0176: private static final int FILE_WRITE_EA = 16;
0177: private static final int FILE_EXECUTE = 32;
0178: private static final int FILE_TRAVERSE = 32;
0179: private static final int FILE_DELETE_CHILD = 64;
0180: private static final int FILE_READ_ATTRIBUTES = 128;
0181: private static final int FILE_WRITE_ATTRIBUTES = 256;
0182: private static final int FILE_DELETE = 65536;
0183:
0184: //////////////////////////////////////////////////////////////////////////
0185:
0186: private static final WindowsRegistry registry = new WindowsRegistry();
0187:
0188: private static final String[] FORBIDDEN_DELETING_FILES_WINDOWS = {
0189: System.getenv("ProgramFiles"), System.getenv("SystemRoot"),
0190: System.getenv("USERPROFILE"),
0191: System.getenv("SystemDrive") + File.separator };
0192: /////////////////////////////////////////////////////////////////////////////////
0193: // Instance
0194: private File defaultApplicationsLocation;
0195:
0196: // constructor //////////////////////////////////////////////////////////////////
0197: WindowsNativeUtils() {
0198: if (SystemUtils.isCurrentJava64Bit()) {
0199: loadNativeLibrary(LIBRARY_PATH_X64);
0200: } else {
0201: loadNativeLibrary(LIBRARY_PATH_X86);
0202: }
0203: //initializeForbiddenFiles(FORBIDDEN_DELETING_FILES_WINDOWS);
0204: initializeForbiddenFiles();
0205: initializeRegistryKeys();
0206: }
0207:
0208: private void initializeRegistryKeys() {
0209: boolean result = false;
0210: try {
0211: result = isCurrentUserAdmin();
0212: } catch (NativeException ex) {
0213: LogManager.log(ex);
0214: }
0215:
0216: try {
0217: clSection = registry.canModifyKey(HKCR, "") ? HKCR : HKCU;
0218: clKey = (result) ? EMPTY_STRING : CURRENT_USER_CLASSES;
0219: uninstallSection = registry.canModifyKey(HKLM,
0220: UNINSTALL_KEY) ? HKLM : HKCU;
0221: } catch (NativeException ex) {
0222: LogManager.log(ex);
0223: clSection = HKCU;
0224: clKey = CURRENT_USER_CLASSES;
0225: uninstallSection = HKCU;
0226: }
0227: }
0228:
0229: // parent implementation ////////////////////////////////////////////////////////
0230: public boolean isCurrentUserAdmin() throws NativeException {
0231: if (isUserAdminSet) {
0232: return isUserAdmin;
0233: }
0234: boolean result = isCurrentUserAdmin0();
0235: isUserAdmin = result;
0236: isUserAdminSet = true;
0237: return result;
0238:
0239: }
0240:
0241: protected OnExitCleanerHandler newDeleteOnExitCleanerHandler() {
0242: return new WindowsProcessOnExitCleanerHandler(CLEANER_FILENAME);
0243: }
0244:
0245: public File getDefaultApplicationsLocation() throws NativeException {
0246: if (defaultApplicationsLocation == null) {
0247: defaultApplicationsLocation = SystemUtils
0248: .getUserHomeDirectory();
0249:
0250: final String path = SystemUtils
0251: .getEnvironmentVariable("ProgramFiles");
0252:
0253: if (path != null) {
0254: defaultApplicationsLocation = new File(path)
0255: .getAbsoluteFile();
0256: } else {
0257: ErrorManager
0258: .notify(ErrorLevel.DEBUG,
0259: "Value of the environment variable ProgramFiles is not set");
0260: }
0261: }
0262:
0263: return defaultApplicationsLocation;
0264: }
0265:
0266: public long getFreeSpace(File file) throws NativeException {
0267: if ((file == null) || !isPathValid(file.getPath())) {
0268: return 0;
0269: } else {
0270: return getFreeSpace0(file.getPath());
0271: }
0272: }
0273:
0274: public boolean isUNCPath(String path) {
0275: // for windows UNC is smth like \\servername\folder...
0276: return path.matches("^\\\\\\\\.+(\\\\|/).+");
0277: }
0278:
0279: @Override
0280: public File getRoot(final File file) {
0281: if (isUNCPath(file.getPath())) {
0282: // tmp = server\folder;
0283: File parent = file;
0284: File previous = null;
0285: File can;
0286: try {
0287: while (parent.getParentFile() != null) {
0288: can = parent.getCanonicalFile();
0289: previous = parent;
0290: parent = parent.getParentFile();
0291: }
0292:
0293: } catch (IOException e) {
0294: // this occurs when file path is equal the server name : \\server
0295: // then go to finally and return previous file
0296: } finally {
0297: return previous;
0298: }
0299: } else {
0300: return super .getRoot(file);
0301: }
0302: }
0303:
0304: public boolean isPathValid(String path) {
0305: // there is a max length limitation
0306: if (path.length() > 256) {
0307: return false;
0308: }
0309:
0310: // the path should be absolute, i.e. should start with "<Drive>:\"
0311: if (!path.matches("^[A-Z,a-z]:\\\\.*")) {
0312: // the path can be also in UNC form
0313: if (!isUNCPath(path)) {
0314: return false;
0315: }
0316: }
0317:
0318: String[] parts = path.split("\\\\");
0319:
0320: for (int i = 1; i < parts.length; i++) {
0321: if (Pattern.compile("[\\/:*\\?\"<>|]").matcher(parts[i])
0322: .find()) {
0323: return false;
0324: }
0325: if (parts[i].startsWith(" ") || parts[i].startsWith("\t")
0326: || parts[i].endsWith(" ")
0327: || parts[i].endsWith("\t")) {
0328: return false;
0329: }
0330: }
0331:
0332: return true;
0333: }
0334:
0335: public File getShortcutLocation(Shortcut shortcut,
0336: LocationType locationType) throws NativeException {
0337: String path = shortcut.getRelativePath();
0338: if (path == null) {
0339: path = "";
0340: }
0341:
0342: String fileName = shortcut.getName();
0343: if (shortcut instanceof FileShortcut) {
0344: fileName += ".lnk";
0345: } else if (shortcut instanceof InternetShortcut) {
0346: fileName += ".url";
0347: }
0348:
0349: final String allUsersRootPath = SystemUtils
0350: .getEnvironmentVariable("allusersprofile");
0351:
0352: switch (locationType) {
0353: case CURRENT_USER_DESKTOP:
0354: String userDesktop = registry.getStringValue(HKCU,
0355: SHELL_FOLDERS_KEY, "Desktop", false);
0356: if (userDesktop == null) {
0357: userDesktop = SystemUtils.getUserHomeDirectory()
0358: + File.separator + "Desktop";
0359: }
0360:
0361: return new File(userDesktop, fileName);
0362:
0363: case ALL_USERS_DESKTOP:
0364: String commonDesktop = registry.getStringValue(HKLM,
0365: SHELL_FOLDERS_KEY, "Common Desktop", false);
0366: if (commonDesktop == null) {
0367: commonDesktop = allUsersRootPath + File.separator
0368: + "Desktop";
0369: }
0370:
0371: return new File(commonDesktop, fileName);
0372:
0373: case CURRENT_USER_START_MENU:
0374: String userStartMenu = registry.getStringValue(HKCU,
0375: SHELL_FOLDERS_KEY, "Programs", false);
0376: if (userStartMenu == null) {
0377: userStartMenu = SystemUtils.getUserHomeDirectory()
0378: + File.separator + "Start Menu"
0379: + File.separator + "Programs";
0380: }
0381:
0382: return new File(userStartMenu, path + File.separator
0383: + fileName);
0384:
0385: case ALL_USERS_START_MENU:
0386: String commonStartMenu = registry.getStringValue(HKLM,
0387: SHELL_FOLDERS_KEY, "Common Programs", false);
0388: if (commonStartMenu == null) {
0389: commonStartMenu = SystemUtils.getUserHomeDirectory()
0390: + File.separator + "Start Menu"
0391: + File.separator + "Programs";
0392: }
0393:
0394: return new File(commonStartMenu, path + File.separator
0395: + fileName);
0396: }
0397:
0398: return null;
0399: }
0400:
0401: protected void createURLShortcut(InternetShortcut shortcut)
0402: throws NativeException {
0403: try {
0404: List<String> lines = new LinkedList<String>();
0405: lines.add("[InternetShortcut]");
0406: lines.add("URL=" + shortcut.getURL());
0407: lines.add("IconFile=" + shortcut.getIconPath());
0408: lines.add("IconIndex=" + shortcut.getIconIndex());
0409: lines.add("HotKey=0");
0410: lines.add("IDList=");
0411: lines.add(SystemUtils.getLineSeparator());
0412: FileUtils.writeStringList(new File(shortcut.getPath()),
0413: lines);
0414: } catch (IOException ex) {
0415: throw new NativeException("Can`t create URL shortcut", ex);
0416: }
0417: }
0418:
0419: public File createShortcut(Shortcut shortcut,
0420: LocationType locationType) throws NativeException {
0421: File shortcutFile = getShortcutLocation(shortcut, locationType);
0422:
0423: shortcut.setPath(shortcutFile.getAbsolutePath());
0424: if (shortcut instanceof FileShortcut) {
0425: createShortcut0((FileShortcut) shortcut);
0426: } else if (shortcut instanceof InternetShortcut) {
0427: createURLShortcut((InternetShortcut) shortcut);
0428: }
0429:
0430: return shortcutFile;
0431: }
0432:
0433: public void removeShortcut(Shortcut shortcut,
0434: LocationType locationType, boolean cleanupParents)
0435: throws NativeException {
0436: File shortcutFile = getShortcutLocation(shortcut, locationType);
0437:
0438: try {
0439: FileUtils.deleteFile(shortcutFile);
0440:
0441: if (cleanupParents) {
0442: switch (locationType) {
0443: case CURRENT_USER_START_MENU:
0444: case ALL_USERS_START_MENU:
0445: FileUtils.deleteEmptyParents(shortcutFile);
0446: break;
0447: default:
0448: break;
0449: }
0450: }
0451: } catch (IOException e) {
0452: LogManager.log("Can`t remove shortcut", e);
0453: }
0454: }
0455:
0456: public FilesList addComponentToSystemInstallManager(
0457: ApplicationDescriptor descriptor) throws NativeException {
0458: final FilesList list = new FilesList();
0459:
0460: // create 'uninstaller' and 'modifier'
0461: Launcher modifyLauncher = null;
0462: Launcher uninstallLauncher = null;
0463: try {
0464: if (descriptor.getModifyCommand() != null) {
0465: modifyLauncher = createUninstaller(descriptor, false,
0466: new Progress());
0467: list.add(modifyLauncher.getOutputFile());
0468: }
0469: if (descriptor.getUninstallCommand() != null) {
0470: uninstallLauncher = createUninstaller(descriptor, true,
0471: new Progress());
0472: list.add(uninstallLauncher.getOutputFile());
0473: }
0474: } catch (IOException e) {
0475: throw new NativeException("Can`t create uninstaller", e);
0476: }
0477:
0478: //add to add/remove programs
0479:
0480: LogManager
0481: .log("adding new Add or Remove Programs entry with id ["
0482: + descriptor.getUid() + "]");
0483:
0484: final String uid = getVacantUninstallUid(descriptor.getUid());
0485: final String key = UNINSTALL_KEY + WindowsRegistry.SEPARATOR
0486: + uid;
0487:
0488: registry.createKey(uninstallSection, key);
0489:
0490: if (descriptor.getDisplayName() != null) {
0491: LogManager.log("Set '" + DISPLAY_NAME + "' = ["
0492: + descriptor.getDisplayName() + "]");
0493:
0494: registry.setStringValue(uninstallSection, key,
0495: DISPLAY_NAME, descriptor.getDisplayName(), false);
0496: }
0497: if (descriptor.getIcon() != null) {
0498: LogManager.log("Set '" + DISPLAY_ICON + "' = ["
0499: + descriptor.getIcon() + "]");
0500:
0501: registry.setStringValue(uninstallSection, key,
0502: DISPLAY_ICON, descriptor.getIcon(), false);
0503: }
0504: if (descriptor.getInstallPath() != null) {
0505: LogManager.log("Set '" + INSTALL_LOCATION + "' = ["
0506: + descriptor.getInstallPath() + "]");
0507:
0508: registry.setStringValue(uninstallSection, key,
0509: INSTALL_LOCATION, descriptor.getInstallPath(),
0510: false);
0511: }
0512:
0513: if (descriptor.getModifyCommand() != null) {
0514: LogManager.log("Set '" + NO_REPAIR + "' = [" + 1 + "]");
0515: registry.set32BitValue(uninstallSection, key, NO_REPAIR, 1);
0516:
0517: final String command = QUOTE
0518: + asString(modifyLauncher.getExecutionCommand(),
0519: QUOTE + SPACE + QUOTE) + QUOTE;
0520:
0521: LogManager.log("Set '" + MODIFY_STRING + "' = [" + command
0522: + "]");
0523: registry.setStringValue(uninstallSection, key,
0524: MODIFY_STRING, command, false);
0525: } else {
0526: LogManager.log("Set '" + NO_MODIFY + "' = [" + 1 + "]");
0527: registry.set32BitValue(uninstallSection, key, NO_MODIFY, 1);
0528: }
0529:
0530: if (descriptor.getUninstallCommand() != null) {
0531: final String command = QUOTE
0532: + asString(uninstallLauncher.getExecutionCommand(),
0533: QUOTE + SPACE + QUOTE) + QUOTE;
0534:
0535: LogManager.log("Set '" + UNINSTALL_STRING + "' = ["
0536: + command + "]");
0537: registry.setStringValue(uninstallSection, key,
0538: UNINSTALL_STRING, command, false);
0539: }
0540:
0541: registry.setAdditionalValues(uninstallSection, key, descriptor
0542: .getParameters());
0543: return list;
0544: }
0545:
0546: public void removeComponentFromSystemInstallManager(
0547: ApplicationDescriptor descriptor) throws NativeException {
0548: String properUid = getProperUninstallUid(descriptor.getUid(),
0549: descriptor.getInstallPath());
0550:
0551: if (properUid != null) {
0552: registry.deleteKey(uninstallSection, UNINSTALL_KEY,
0553: properUid);
0554: }
0555: }
0556:
0557: public String getEnvironmentVariable(String name,
0558: EnvironmentScope scope, boolean expand)
0559: throws NativeException {
0560: String value = null;
0561:
0562: if ((scope != null) && (name != null)) {
0563: if (scope == EnvironmentScope.PROCESS) {
0564: value = System.getenv(name);
0565: } else {
0566: String rootKey = null;
0567: int section = 0;
0568: if (scope == EnvironmentScope.CURRENT_USER) {
0569: rootKey = CURRENT_USER_ENVIRONMENT_KEY;
0570: section = HKCU;
0571: }
0572: if (scope == EnvironmentScope.ALL_USERS) {
0573: rootKey = ALL_USERS_ENVIRONMENT_KEY;
0574: section = HKLM;
0575: }
0576:
0577: if (registry.keyExists(section, rootKey)) {
0578: if (registry.valueExists(section, rootKey, name)) {
0579: value = registry.getStringValue(section,
0580: rootKey, name, expand);
0581: } else {
0582: LogManager.log(ErrorLevel.DEBUG,
0583: "Environment variable " + name
0584: + " doesn`t exist.");
0585: }
0586: } else {
0587: LogManager
0588: .log(ErrorLevel.DEBUG,
0589: "Root environment key doesn`t exist. Can`t get environment variable");
0590: }
0591: }
0592: }
0593:
0594: return value;
0595: }
0596:
0597: public void setEnvironmentVariable(String name, String value,
0598: EnvironmentScope scope, boolean expand)
0599: throws NativeException {
0600: if ((name != null) && (scope != null)) {
0601: if (scope == EnvironmentScope.PROCESS) {
0602: SystemUtils.getEnvironment().put(name, value);
0603: } else {
0604: String rootKey = null;
0605: int section = 0;
0606: if (scope == EnvironmentScope.CURRENT_USER) {
0607: rootKey = CURRENT_USER_ENVIRONMENT_KEY;
0608: section = HKCU;
0609: }
0610: if (scope == EnvironmentScope.ALL_USERS) {
0611: rootKey = ALL_USERS_ENVIRONMENT_KEY;
0612: section = HKLM;
0613: }
0614:
0615: if (registry.keyExists(section, rootKey)) {
0616: registry.setStringValue(section, rootKey, name,
0617: value, expand);
0618: notifyEnvironmentChanged0();
0619: } else {
0620: LogManager.log(ErrorLevel.WARNING,
0621: "Root envonment key doesn`t exist. "
0622: + "Can`t set environment variable");
0623: }
0624: }
0625: }
0626: }
0627:
0628: public List<File> findIrrelevantFiles(File parent)
0629: throws IOException {
0630: List<File> files = new LinkedList<File>();
0631:
0632: if (parent.exists()) {
0633: if (parent.isDirectory()) {
0634: for (File child : parent.listFiles()) {
0635: files.addAll(findIrrelevantFiles(child));
0636: }
0637: } else {
0638: // name based analysis
0639: File child = parent;
0640: String name = child.getName();
0641: String[] unixExtensions = { ".sh", ".so", ".dylib" };
0642: for (String ext : unixExtensions) {
0643: if (name.endsWith(ext)) {
0644: files.add(child);
0645: break;
0646: }
0647: }
0648:
0649: // contents based analysis
0650: // Switched off due to Issue 97995
0651: // This analysis can be switched back only after the serious invesigation
0652: // The main additional check should be done based on the name
0653: // If it contains any extenstion (except .sh) then check is failed anyway
0654: // E.G: GlassFish\imq\lib\props\broker\default.properties
0655: /*
0656: String line = FileUtils.readFirstLine(child);
0657: if (line != null) {
0658: if (line.startsWith("#!/bin/sh")) { // shell script
0659: files.add(child);
0660: continue;
0661: }
0662: }
0663: */
0664: }
0665: }
0666:
0667: return files;
0668: }
0669:
0670: public List<File> findExecutableFiles(File parent)
0671: throws IOException {
0672: List<File> files = new LinkedList<File>();
0673:
0674: if (parent.exists()) {
0675: if (parent.isDirectory()) {
0676: File[] children = parent.listFiles();
0677: for (File child : children) {
0678: files.addAll(findIrrelevantFiles(child));
0679: }
0680: } else {
0681: // name based analysis
0682: File child = parent;
0683: String name = child.getName();
0684: String[] windowsExecutableExtensions = { ".exe",
0685: ".com", ".bat", ".cmd", ".vbs", ".vbe", ".js",
0686: ".jse", ".wsf", ".wsh" };
0687: for (String ext : windowsExecutableExtensions) {
0688: if (name.endsWith(ext)) {
0689: files.add(child);
0690: break;
0691: }
0692: }
0693: }
0694: }
0695: return files;
0696: }
0697:
0698: public void correctFilesPermissions(File parent) {
0699: // does nothing, as there is no such thing as execute permissions
0700: }
0701:
0702: public void setPermissions(final File file, final int mode,
0703: final int change) throws IOException {
0704: // does nothing
0705: }
0706:
0707: public int getPermissions(final File file) throws IOException {
0708: return 0;
0709: }
0710:
0711: public List<File> getFileSystemRoots() throws IOException {
0712: return Arrays.asList(File.listRoots());
0713: }
0714:
0715: // windows-specific operations //////////////////////////////////////////////////
0716: public WindowsRegistry getWindowsRegistry() {
0717: return registry;
0718: }
0719:
0720: public void deleteFileOnReboot(File file) throws NativeException {
0721: String path = file.getAbsolutePath();
0722:
0723: if (isCurrentUserAdmin()) {
0724: deleteFileOnReboot0(path);
0725: } else {
0726: // just in case...
0727: if (!registry.keyExists(HKCU, RUNONCE_KEY)) {
0728: registry.createKey(HKCU, RUNONCE_KEY);
0729: }
0730:
0731: // find an appropriate name, which does not exist
0732: String name = RUNONCE_DELETE_VALUE_NAME;
0733: for (int i = 0; registry.valueExists(HKCU, RUNONCE_KEY,
0734: name); i++) {
0735: name = RUNONCE_DELETE_VALUE_NAME + UID_SEPARATOR + i;
0736: }
0737:
0738: // set the value
0739: String command = "cmd /q /c del /F /Q \"" + path + "\"";
0740: registry.setStringValue(HKCU, RUNONCE_KEY, name, command);
0741: }
0742: }
0743:
0744: // private //////////////////////////////////////////////////////////////////////
0745: private String getVacantUninstallUid(final String baseUid)
0746: throws NativeException {
0747: String vacantUid = baseUid;
0748:
0749: String key = UNINSTALL_KEY + WindowsRegistry.SEPARATOR
0750: + vacantUid;
0751: if (registry.keyExists(uninstallSection, key)) {
0752: for (int index = MIN_UID_INDEX; index < MAX_UID_INDEX; index++) {
0753: vacantUid = baseUid + UID_SEPARATOR + index;
0754: key = UNINSTALL_KEY + WindowsRegistry.SEPARATOR
0755: + vacantUid;
0756:
0757: if (!registry.keyExists(uninstallSection, key)) {
0758: return vacantUid;
0759: }
0760: }
0761: return null;
0762: } else {
0763: return vacantUid;
0764: }
0765: }
0766:
0767: private String getProperUninstallUid(final String baseUid,
0768: final String installLocation) throws NativeException {
0769: String properUid = baseUid;
0770:
0771: String key = UNINSTALL_KEY + WindowsRegistry.SEPARATOR
0772: + properUid;
0773: if (registry.keyExists(uninstallSection, key)
0774: && registry.getStringValue(uninstallSection, key,
0775: INSTALL_LOCATION).equals(installLocation)) {
0776: return properUid;
0777: } else {
0778: for (int index = MIN_UID_INDEX; index < MAX_UID_INDEX; index++) {
0779: properUid = baseUid + UID_SEPARATOR + index;
0780: key = UNINSTALL_KEY + WindowsRegistry.SEPARATOR
0781: + properUid;
0782:
0783: if (registry.keyExists(uninstallSection, key)
0784: && registry.getStringValue(uninstallSection,
0785: key, INSTALL_LOCATION).equals(
0786: installLocation)) {
0787: return properUid;
0788: }
0789: }
0790: return null;
0791: }
0792: }
0793:
0794: public boolean checkFileAccess(File file, boolean isReadNotModify)
0795: throws NativeException {
0796: int result = 0;
0797: try {
0798: int accessLevel = 0;
0799: if (isReadNotModify) {
0800: accessLevel = FILE_READ_DATA | FILE_LIST_DIRECTORY;
0801: } else {
0802: accessLevel = FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY
0803: | FILE_APPEND_DATA | FILE_WRITE_DATA;
0804: }
0805: result = checkAccessTokenAccessLevel0(file.getPath(),
0806: accessLevel);
0807: } catch (UnsatisfiedLinkError e) {
0808: throw new NativeException("Cannot access native method", e);
0809: }
0810: return (result == 1);
0811: }
0812:
0813: public synchronized void setFileAssociation(FileExtension ext,
0814: SystemApplication app, Properties props)
0815: throws NativeException {
0816: if (ext == null && isEmpty(ext.getName())) {
0817: return;
0818: }
0819: notifyAssociationChanged();
0820: FileExtensionKey feExt = new FileExtensionKey(ext,
0821: getLongExtensionName(ext));
0822: setExtensionDetails(feExt, props);
0823:
0824: if (app != null && !isEmpty(app.getLocation())) {
0825: SystemApplicationKey appExt = new SystemApplicationKey(app,
0826: getApplicationKey(app));
0827: registerApplication(appExt, feExt, props);
0828: changeDefaultApplication(appExt, feExt, props);
0829: addToOpenWithList(appExt, feExt, props);
0830: }
0831: notifyAssociationChanged();
0832: }
0833:
0834: public synchronized void removeFileAssociation(FileExtension ext,
0835: SystemApplication app, Properties props)
0836: throws NativeException {
0837:
0838: if (ext == null && isEmpty(ext.getName())) {
0839: return;
0840: }
0841: notifyAssociationChanged();
0842: String prefix = EXTENSION_VALUE_NAME + ext.getDotName();
0843: if (props.getProperty(prefix) != null) {
0844: //extension was created
0845: if (registry.valueExists(clSection, clKey
0846: + ext.getDotName(), EMPTY_STRING)) {
0847: String extKey = registry.getStringValue(clSection,
0848: clKey + ext.getDotName(), EMPTY_STRING);
0849: FileExtensionKey feExt = new FileExtensionKey(ext,
0850: extKey);
0851: String appKey = getApplicationKey(app);
0852: SystemApplicationKey sap = new SystemApplicationKey(
0853: app, appKey);
0854:
0855: removeFromOpenWithList(sap, feExt, props);
0856: rollbackDefaultApplication(sap, feExt, props);
0857: unregisterApplication(sap, feExt, props);
0858: clearExtensionDetails(sap, feExt, props);
0859: }
0860: }
0861: notifyAssociationChanged();
0862: }
0863:
0864: private void setExtensionDetails(FileExtensionKey ext,
0865: Properties props) throws NativeException {
0866: String name = ext.getDotName();
0867: String extKey = ext.getKey();
0868: // create key HKEY_CLASSES_ROOT\.EXTENSION
0869: if (!registry.keyExists(clSection, clKey + name)) {
0870: registry.createKey(clSection, clKey + name);
0871: setExtProperty(props, name, CREATED);
0872: }
0873:
0874: // Set perceived and content time if necessary
0875: if (ext.getPerceivedType() != null) {
0876: if (!registry.valueExists(clSection, clKey + name,
0877: PERCEIVED_TYPE_VALUE_NAME)) {
0878: registry.setStringValue(clSection, clKey + name,
0879: PERCEIVED_TYPE_VALUE_NAME, ext
0880: .getPerceivedType().toString());
0881: setExtProperty(props, name, EXT_PERCEIVEDTYPE_PROPERTY,
0882: CREATED);
0883: }
0884: }
0885: if (!isEmpty(ext.getMimeType())) {
0886: registry.setStringValue(clSection, clKey + name,
0887: CONTENT_TYPE_VALUE_NAME, ext.getMimeType());
0888: if (!registry.keyExists(clSection,
0889: clKey + CONTENT_TYPE_KEY, ext.getMimeType())) {
0890: registry.createKey(clSection, clKey + CONTENT_TYPE_KEY,
0891: ext.getMimeType());
0892: registry.setStringValue(clSection, clKey
0893: + CONTENT_TYPE_KEY + SEP + ext.getMimeType(),
0894: EXTENSION_VALUE_NAME, name);
0895: setExtProperty(props, name, EXT_CONTENTTYPE_PROPERTY,
0896: CREATED);
0897: }
0898: }
0899: // make connection with HKEY_CLASSES_ROOT\.EXTENSION
0900: registry.setStringValue(clSection, clKey + name, EMPTY_STRING,
0901: extKey);
0902:
0903: // create key HKEY_CLASSES_ROOT\EXT_PREFIX_EXTENSION_EXT_SUFFIX
0904: if (!registry.keyExists(clSection, clKey + extKey)) {
0905: registry.createKey(clSection, clKey + extKey);
0906: setExtProperty(props, name, EXT_LONGEXT_PROPERTY, CREATED);
0907: }
0908:
0909: // Set extension description and icon if necessary
0910: if (!isEmpty(ext.getDescription())) {
0911: if (registry.valueExists(clSection, clKey + extKey,
0912: EMPTY_STRING)) {
0913: setExtProperty(props, name, EXT_DESCRIPTION_PROPERTY,
0914: registry.getStringValue(clSection, clKey
0915: + extKey, EMPTY_STRING));
0916: }
0917: registry.setStringValue(clSection, clKey + extKey,
0918: EMPTY_STRING, ext.getDescription());
0919:
0920: }
0921: if (!isEmpty(ext.getIcon())) {
0922: if (!registry.keyExists(clSection, clKey + extKey,
0923: DEFAULT_ICON_KEY_NAME)) {
0924: registry.createKey(clSection, clKey + extKey,
0925: DEFAULT_ICON_KEY_NAME);
0926: registry.setStringValue(clSection, clKey + extKey + SEP
0927: + DEFAULT_ICON_KEY_NAME, EMPTY_STRING, ext
0928: .getIcon());
0929: setExtProperty(props, name, EXT_ICON_PROPERTY, CREATED);
0930: }
0931: }
0932:
0933: //create current user extension key in HKCU\CURRENT_USER_FILE_EXT_KEY
0934: if (!registry.keyExists(HKCU, CURRENT_USER_FILE_EXT_KEY, name)) {
0935: registry.createKey(HKCU, CURRENT_USER_FILE_EXT_KEY, name);
0936: setExtProperty(props, name, EXT_HKCU_FILEXT_PROPERTY,
0937: CREATED);
0938: }
0939: }
0940:
0941: private void clearExtensionDetails(SystemApplicationKey app,
0942: FileExtensionKey fe, Properties props)
0943: throws NativeException {
0944: String name = fe.getDotName();
0945: String extKey = fe.getKey();
0946: String property;
0947: property = getExtProperty(props, name, EXT_HKCU_FILEXT_PROPERTY);
0948: if (property != null) {
0949: if (registry.keyExists(HKCU, CURRENT_USER_FILE_EXT_KEY
0950: + SEP + name)) {
0951: if (registry.keyExists(HKCU, CURRENT_USER_FILE_EXT_KEY
0952: + SEP + name, OPEN_WITH_LIST_KEY_NAME)) {
0953: registry.deleteKey(HKCU, CURRENT_USER_FILE_EXT_KEY
0954: + SEP + name, OPEN_WITH_LIST_KEY_NAME);
0955: }
0956: if (registry.keyExists(HKCU, CURRENT_USER_FILE_EXT_KEY
0957: + SEP + name, OPEN_WITH_PROGIDS_KEY_NAME)) {
0958: registry.deleteKey(HKCU, CURRENT_USER_FILE_EXT_KEY
0959: + SEP + name, OPEN_WITH_PROGIDS_KEY_NAME);
0960: }
0961: if (registry.getSubKeys(HKCU, CURRENT_USER_FILE_EXT_KEY
0962: + SEP + name).length == 0) {
0963: registry.deleteKey(HKCU, CURRENT_USER_FILE_EXT_KEY,
0964: name);
0965: }
0966: }
0967: }
0968:
0969: property = getExtProperty(props, name, EXT_DESCRIPTION_PROPERTY);
0970: if (property != null) {
0971: //restore description
0972: registry.setStringValue(clSection, clKey + extKey,
0973: EMPTY_STRING, property);
0974: }
0975:
0976: property = getExtProperty(props, name, EXT_ICON_PROPERTY);
0977: if (property != null) {
0978: if (registry.keyExists(clSection, clKey + extKey + SEP
0979: + DEFAULT_ICON_KEY_NAME)) {
0980: registry.deleteKey(clSection, clKey + extKey + SEP
0981: + DEFAULT_ICON_KEY_NAME);
0982: }
0983: }
0984:
0985: property = getExtProperty(props, name, EXT_LONGEXT_PROPERTY);
0986: if (property != null) {
0987: if (registry.getSubKeys(clSection, clKey + extKey).length == 0) {
0988: registry.deleteKey(clSection, clKey + extKey);
0989: }
0990: }
0991:
0992: property = getExtProperty(props, name, EXT_CONTENTTYPE_PROPERTY);
0993: if (property != null) {
0994: if (registry.getSubKeys(clSection, clKey + CONTENT_TYPE_KEY
0995: + SEP + fe.getMimeType()).length == 0) {
0996: registry.deleteKey(clSection, clKey + CONTENT_TYPE_KEY,
0997: fe.getMimeType());
0998: }
0999: }
1000: property = getExtProperty(props, name,
1001: EXT_PERCEIVEDTYPE_PROPERTY);
1002: if (property != null) {
1003: registry.deleteValue(clSection, clKey + name,
1004: PERCEIVED_TYPE_VALUE_NAME);
1005: }
1006:
1007: property = getExtProperty(props, name);
1008: if (property != null) {
1009: if (registry.keyExists(clSection, clKey + name)
1010: && registry.getSubKeys(clSection, clKey + name).length == 0) {
1011: registry.deleteKey(clSection, clKey + name);
1012: }
1013: }
1014: }
1015:
1016: private void changeDefaultApplication(SystemApplicationKey app,
1017: FileExtensionKey fe, Properties props)
1018: throws NativeException {
1019: if (app.isUseByDefault()) {
1020: String name = fe.getDotName();
1021: String extKey = fe.getKey();
1022: String appLocation = app.getLocation();
1023: String appKey = app.getKey();
1024: String command = app.getCommand();
1025:
1026: if (!registry.keyExists(clSection, clKey + extKey
1027: + SHELL_OPEN_COMMAND)) {
1028: registry.createKey(clSection, clKey + extKey
1029: + SHELL_OPEN_COMMAND);
1030: registry.setStringValue(clSection, clKey + extKey
1031: + SHELL_OPEN_COMMAND, EMPTY_STRING,
1032: constructCommand(app));
1033: setExtProperty(props, name,
1034: EXT_HKCRSHELL_OPEN_COMMAND_PROPERTY, CREATED);
1035: }
1036:
1037: //change current user 'default-app' for this extension
1038: String s = null;
1039: if (registry.valueExists(HKCU, CURRENT_USER_FILE_EXT_KEY
1040: + SEP + name, APPLICATION_VALUE_NAME)) {
1041: s = registry.getStringValue(HKCU,
1042: CURRENT_USER_FILE_EXT_KEY + SEP + name,
1043: APPLICATION_VALUE_NAME);
1044: }
1045:
1046: registry.setStringValue(HKCU, CURRENT_USER_FILE_EXT_KEY
1047: + SEP + name, APPLICATION_VALUE_NAME, appKey);
1048: if (s != null) {
1049: setExtProperty(props, name,
1050: EXT_HKCU_DEFAULTAPP_PROPERTY, s);
1051: }
1052:
1053: }
1054: }
1055:
1056: private void rollbackDefaultApplication(SystemApplicationKey app,
1057: FileExtensionKey fe, Properties props)
1058: throws NativeException {
1059: String property;
1060: if (app.isUseByDefault()) {
1061: String name = fe.getDotName();
1062: String extKey = fe.getKey();
1063: String appLocation = app.getLocation();
1064: String appKey = app.getKey();
1065: String command = app.getCommand();
1066: property = getExtProperty(props, name,
1067: EXT_HKCRSHELL_OPEN_COMMAND_PROPERTY);
1068: if (property != null) {
1069: String s = SHELL_OPEN_COMMAND;
1070: registry.deleteKey(clSection, clKey + extKey + s); // delete command
1071: s = s.substring(0, s.lastIndexOf(SEP));
1072: registry.deleteKey(clSection, clKey + extKey + s); // delete open
1073: s = s.substring(0, s.lastIndexOf(SEP)); //
1074: registry.deleteKey(clSection, clKey + extKey + s); // delete shell
1075: }
1076: property = getExtProperty(props, name, DOT
1077: + EXT_HKCU_DEFAULTAPP_PROPERTY);
1078:
1079: if (registry.keyExists(HKCU, CURRENT_USER_FILE_EXT_KEY
1080: + SEP + name)) {
1081: if (property != null) {
1082: registry.setStringValue(HKCU,
1083: CURRENT_USER_FILE_EXT_KEY + SEP + name,
1084: APPLICATION_VALUE_NAME, property);
1085: } else {
1086: registry.deleteValue(HKCU,
1087: CURRENT_USER_FILE_EXT_KEY + SEP + name,
1088: APPLICATION_VALUE_NAME);
1089: }
1090: }
1091: }
1092: }
1093:
1094: private void addToOpenWithList(SystemApplicationKey app,
1095: FileExtensionKey ext, Properties props)
1096: throws NativeException {
1097: String name = ext.getDotName();
1098: String extKey = ext.getKey();
1099: String appName = app.getKey();
1100: if (app.isAddOpenWithList()) {
1101: if (!isEmpty(name) && !isEmpty(extKey) && !isEmpty(appName)) {
1102: if (!registry.keyExists(clSection, clKey + name + SEP
1103: + OPEN_WITH_LIST_KEY_NAME, appName)) {
1104: registry.createKey(clSection, clKey + name + SEP
1105: + OPEN_WITH_LIST_KEY_NAME, appName);
1106: setExtProperty(props, name,
1107: EXT_HKCR_OPENWITHLIST_PROPERTY, CREATED);
1108: }
1109: addCurrentUserOpenWithList(name, extKey, appName, props);
1110:
1111: if (!registry.keyExists(clSection, clKey + name + SEP
1112: + OPEN_WITH_PROGIDS_KEY_NAME)) {
1113: registry.createKey(clSection, clKey + name + SEP
1114: + OPEN_WITH_PROGIDS_KEY_NAME);
1115: setExtProperty(props, name,
1116: EXT_HKCR_OPENWITHPROGIDS_PROPERTY, CREATED);
1117: }
1118: registry.setNoneValue(clSection, clKey + name + SEP
1119: + OPEN_WITH_PROGIDS_KEY_NAME, extKey);
1120: addCurrentUserOpenWithProgids(name, extKey, appName,
1121: props);
1122: }
1123: }
1124: }
1125:
1126: private void removeFromOpenWithList(SystemApplicationKey app,
1127: FileExtensionKey ext, Properties props)
1128: throws NativeException {
1129: String property;
1130: String name = ext.getDotName();
1131: String extKey = ext.getKey();
1132: String appName = app.getKey();
1133: property = getExtProperty(props, name,
1134: EXT_HKCR_OPENWITHLIST_PROPERTY);
1135: if (property != null) {
1136: if (registry.keyExists(clSection, clKey + name + SEP
1137: + OPEN_WITH_LIST_KEY_NAME, appName)) {
1138: registry.deleteKey(clSection, clKey + name + SEP
1139: + OPEN_WITH_LIST_KEY_NAME, appName);
1140: }
1141: if (registry.keyExists(clSection, clKey + name + SEP
1142: + OPEN_WITH_LIST_KEY_NAME)) {
1143: if (registry.getSubKeys(clSection, clKey + name + SEP
1144: + OPEN_WITH_LIST_KEY_NAME).length == 0) {
1145: registry.deleteKey(clSection, clKey + name + SEP
1146: + OPEN_WITH_LIST_KEY_NAME);
1147: }
1148: }
1149: }
1150: property = getExtProperty(props, name,
1151: EXT_HKCR_OPENWITHPROGIDS_PROPERTY);
1152: if (property != null) {
1153: if (registry.keyExists(clSection, clKey + name + SEP
1154: + OPEN_WITH_PROGIDS_KEY_NAME)) {
1155: if (registry.valueExists(clSection, clKey + name + SEP
1156: + OPEN_WITH_PROGIDS_KEY_NAME, extKey)) {
1157: registry.deleteValue(clSection, clKey + name + SEP
1158: + OPEN_WITH_PROGIDS_KEY_NAME, extKey);
1159: }
1160: if (registry.keyEmpty(clSection, clKey + name + SEP
1161: + OPEN_WITH_PROGIDS_KEY_NAME)) {
1162: registry.deleteKey(clSection, clKey + name + SEP
1163: + OPEN_WITH_PROGIDS_KEY_NAME);
1164: }
1165: }
1166: }
1167: String cuExtKey = CURRENT_USER_FILE_EXT_KEY + SEP + name;
1168: property = getExtProperty(props, name,
1169: EXT_HKCU_OPENWITHPROGIDS_PROPERTY);
1170: if (property != null) {
1171: if (registry.keyExists(HKCU, cuExtKey,
1172: OPEN_WITH_PROGIDS_KEY_NAME)) {
1173: if (registry.valueExists(HKCU, cuExtKey + SEP
1174: + OPEN_WITH_PROGIDS_KEY_NAME, ext.getKey())) {
1175: registry.deleteValue(HKCU, cuExtKey + SEP
1176: + OPEN_WITH_PROGIDS_KEY_NAME, ext.getKey());
1177: }
1178: }
1179: }
1180: property = getExtProperty(props, name,
1181: EXT_HKCU_OPENWITHLIST_PROPERTY);
1182: if (property != null
1183: && registry.keyExists(HKCU, cuExtKey,
1184: OPEN_WITH_LIST_KEY_NAME)) {
1185: for (int i = 0; i < MRU_VALUES.length(); i++) {
1186: String ch = MRU_VALUES.substring(i, i + 1);
1187: if (registry.valueExists(HKCU, cuExtKey + SEP
1188: + OPEN_WITH_LIST_KEY_NAME, ch)
1189: && registry.getStringValue(
1190: HKCU,
1191: cuExtKey + SEP
1192: + OPEN_WITH_LIST_KEY_NAME, ch)
1193: .equals(appName)) {
1194:
1195: registry.deleteValue(HKCU, cuExtKey + SEP
1196: + OPEN_WITH_LIST_KEY_NAME, ch);
1197: if (registry.valueExists(HKCU, cuExtKey + SEP
1198: + OPEN_WITH_LIST_KEY_NAME,
1199: MRULIST_VALUE_NAME)) {
1200: String mru = registry.getStringValue(HKCU,
1201: cuExtKey + SEP
1202: + OPEN_WITH_LIST_KEY_NAME,
1203: MRULIST_VALUE_NAME);
1204: mru = mru.replace(ch, EMPTY_STRING);
1205: if (mru.equals(EMPTY_STRING)) {
1206: registry.deleteValue(HKCU, cuExtKey + SEP
1207: + OPEN_WITH_LIST_KEY_NAME,
1208: MRULIST_VALUE_NAME);
1209: } else {
1210: registry.setStringValue(HKCU, cuExtKey
1211: + SEP + OPEN_WITH_LIST_KEY_NAME,
1212: MRULIST_VALUE_NAME, mru);
1213: }
1214: }
1215: break;
1216: }
1217: }
1218: if (registry.keyEmpty(HKCU, cuExtKey + SEP
1219: + OPEN_WITH_LIST_KEY_NAME)) {
1220: registry.deleteKey(HKCU, cuExtKey,
1221: OPEN_WITH_LIST_KEY_NAME);
1222: }
1223: }
1224: }
1225:
1226: private void addCurrentUserOpenWithList(String name, String extKey,
1227: String appName, Properties props) throws NativeException {
1228: boolean found = false;
1229: String freeValue = MRU_VALUES.substring(0, 1);//=a
1230: String cuExtKey = CURRENT_USER_FILE_EXT_KEY + SEP + name;
1231:
1232: if (!registry
1233: .keyExists(HKCU, cuExtKey, OPEN_WITH_LIST_KEY_NAME)) {
1234: registry.createKey(HKCU, cuExtKey, OPEN_WITH_LIST_KEY_NAME);
1235: } else {
1236: freeValue = null;
1237: for (int i = 0; i < MRU_VALUES.length(); i++) {
1238: String s = MRU_VALUES.substring(i, i + 1);
1239:
1240: if (registry.valueExists(HKCU, cuExtKey + SEP
1241: + OPEN_WITH_LIST_KEY_NAME, s)) {
1242:
1243: String app = registry.getStringValue(HKCU, cuExtKey
1244: + SEP + OPEN_WITH_LIST_KEY_NAME, s);
1245: if (app.equals(appName)) {
1246: found = true;
1247: }
1248: } else if (freeValue == null) {
1249: freeValue = s;
1250: }
1251: }
1252: }
1253: if (!found) {
1254: registry.setStringValue(HKCU, cuExtKey + SEP
1255: + OPEN_WITH_LIST_KEY_NAME, freeValue, appName);
1256: setExtProperty(props, name, EXT_HKCU_OPENWITHLIST_PROPERTY,
1257: CREATED);
1258:
1259: String mru = freeValue;
1260: if (registry.valueExists(HKCU, cuExtKey + SEP
1261: + OPEN_WITH_LIST_KEY_NAME, MRULIST_VALUE_NAME)) {
1262:
1263: mru = mru
1264: + registry.getStringValue(HKCU, cuExtKey + SEP
1265: + OPEN_WITH_LIST_KEY_NAME,
1266: MRULIST_VALUE_NAME);
1267: }
1268: registry.setStringValue(HKCU, cuExtKey + SEP
1269: + OPEN_WITH_LIST_KEY_NAME, MRULIST_VALUE_NAME, mru);
1270: }
1271: }
1272:
1273: private void addCurrentUserOpenWithProgids(String name,
1274: String extKey, String appName, Properties props)
1275: throws NativeException {
1276: String cuExtKey = CURRENT_USER_FILE_EXT_KEY + SEP + name;
1277:
1278: if (!registry.keyExists(HKCU, cuExtKey,
1279: OPEN_WITH_PROGIDS_KEY_NAME)) {
1280: registry.createKey(HKCU, cuExtKey,
1281: OPEN_WITH_PROGIDS_KEY_NAME);
1282:
1283: } else {
1284: String[] values = registry.getValueNames(HKCU, cuExtKey
1285: + SEP + OPEN_WITH_PROGIDS_KEY_NAME);
1286: for (String value : values) {
1287: if (value.equals(appName)) {
1288: return;
1289: }
1290: }
1291: }
1292:
1293: registry.setNoneValue(HKCU, cuExtKey + SEP
1294: + OPEN_WITH_PROGIDS_KEY_NAME, extKey);
1295: setExtProperty(props, name, EXT_HKCU_OPENWITHPROGIDS_PROPERTY,
1296: CREATED);
1297: }
1298:
1299: private void registerApplication(SystemApplicationKey app,
1300: FileExtensionKey key, Properties props)
1301: throws NativeException {
1302: String appLocation = app.getLocation();
1303: String appKey = app.getKey();
1304: String appFriendlyName = app.getFriendlyName();
1305: String command = app.getCommand();
1306: String name = key.getDotName();
1307: if (!registry.keyExists(clSection, clKey
1308: + APPLICATIONS_KEY_NAME, appKey)) {
1309: registry.createKey(clSection,
1310: clKey + APPLICATIONS_KEY_NAME, appKey);
1311: setExtProperty(props, name, EXT_HKCR_APPLICATIONS_PROPERTY,
1312: CREATED);
1313: if (!isEmpty(appFriendlyName)) {
1314: registry.setStringValue(clSection, clKey
1315: + APPLICATIONS_KEY_NAME + SEP + appKey,
1316: FRIENDLYAPPNAME_VALUE_NAME, appFriendlyName);
1317: if (registry
1318: .keyExists(HKCU, CURRENT_USER_MUI_CACHE_KEY)) {
1319: String s = CREATED;
1320: if (registry.valueExists(HKCU,
1321: CURRENT_USER_MUI_CACHE_KEY, appLocation)) {
1322: s = registry
1323: .getStringValue(HKCU,
1324: CURRENT_USER_MUI_CACHE_KEY,
1325: appLocation);
1326: }
1327: registry.setStringValue(HKCU,
1328: CURRENT_USER_MUI_CACHE_KEY, appLocation,
1329: appFriendlyName);
1330: setExtProperty(props, name,
1331: EXT_HKCU_MUICACHE_PROPERTY, s);
1332: }
1333: }
1334: //set application`s 'open' command
1335: registry.createKey(clSection, clKey + APPLICATIONS_KEY_NAME
1336: + SEP + appKey + SHELL_OPEN_COMMAND);
1337: registry.setStringValue(clSection, clKey
1338: + APPLICATIONS_KEY_NAME + SEP + appKey
1339: + SHELL_OPEN_COMMAND, EMPTY_STRING,
1340: constructCommand(app));
1341: }
1342: }
1343:
1344: private void unregisterApplication(SystemApplicationKey app,
1345: FileExtensionKey key, Properties props)
1346: throws NativeException {
1347: String name = key.getDotName();
1348: String property = getExtProperty(props, name,
1349: EXT_HKCR_APPLICATIONS_PROPERTY);
1350: if (property != null) {
1351: String appKey = app.getKey();
1352: if (registry.keyExists(clSection, clKey
1353: + APPLICATIONS_KEY_NAME, appKey)) {
1354: String[] openCommandKey = SHELL_OPEN_COMMAND.split(SEP
1355: + SEP);
1356: for (int i = openCommandKey.length - 1; i >= 0; i--) {
1357: String str = EMPTY_STRING;
1358: for (int j = i - 1; j >= 0; j--) {
1359: str = str + SEP + openCommandKey[i - j];
1360: }
1361: if (registry.keyExists(clSection, clKey
1362: + APPLICATIONS_KEY_NAME + SEP + appKey
1363: + str)) {
1364: if (registry.getSubKeys(clSection, clKey
1365: + APPLICATIONS_KEY_NAME + SEP + appKey
1366: + str).length == 0) {
1367: registry.deleteKey(clSection, clKey
1368: + APPLICATIONS_KEY_NAME + SEP
1369: + appKey + str);
1370: }
1371: }
1372: }
1373: }
1374: }
1375: property = getExtProperty(props, name,
1376: EXT_HKCU_MUICACHE_PROPERTY);
1377: if (property != null) {
1378: if (registry.valueExists(HKCU, CURRENT_USER_MUI_CACHE_KEY,
1379: app.getLocation())) {
1380: if (property.equals(CREATED)) {
1381: registry.deleteValue(HKCU,
1382: CURRENT_USER_MUI_CACHE_KEY, app
1383: .getLocation());
1384: } else {
1385: registry.setStringValue(HKCU,
1386: CURRENT_USER_MUI_CACHE_KEY, app
1387: .getLocation(), property);
1388: }
1389: }
1390: }
1391: }
1392:
1393: private String getApplicationKey(SystemApplication app)
1394: throws NativeException {
1395: String appName = new File(app.getLocation()).getName();
1396: String appKey = appName;
1397: int index = 1;
1398: while (registry.keyExists(clSection, clKey
1399: + APPLICATIONS_KEY_NAME, appKey)) {
1400: if (registry.keyExists(clSection, clKey
1401: + APPLICATIONS_KEY_NAME + SEP + appKey
1402: + SHELL_OPEN_COMMAND)) {
1403: String command = registry.getStringValue(clSection,
1404: clKey + APPLICATIONS_KEY_NAME + SEP + appKey
1405: + SHELL_OPEN_COMMAND, EMPTY_STRING);
1406: if (command.equals(constructCommand(app))) {
1407: break;
1408: }
1409: }
1410: appKey = appName + DOT + (index++);
1411: }
1412: return appKey;
1413: }
1414:
1415: private String getLongExtensionName(FileExtension ext)
1416: throws NativeException {
1417: String dotname = ext.getDotName();
1418: String name = ext.getName();
1419: String key = null;
1420: if (registry.keyExists(clSection, clKey + dotname)) {
1421: key = registry.getStringValue(clSection, clKey + dotname,
1422: EMPTY_STRING);
1423: }
1424: if (isEmpty(key) || !registry.keyExists(clSection, clKey + key)) {
1425: int index = 1;
1426: do {
1427: key = EXT_PREFIX + name + EXT_SUFFIX + DOT + (index++);
1428: } while (registry.keyExists(clSection, clKey + key));
1429: }
1430: return key;
1431: }
1432:
1433: private String constructCommand(SystemApplication app) {
1434: String command = app.getCommand();
1435: if (command == null) {
1436: command = DEFAULT_OPEN_COMMAND;
1437: }
1438: return ("\"" + app.getLocation() + "\"" + SPACE + command);
1439: }
1440:
1441: private boolean isEmpty(String str) {
1442: return (str == null || str.equals(EMPTY_STRING));
1443: }
1444:
1445: private void notifyAssociationChanged() throws NativeException {
1446: notifyAssociationChanged0();
1447: }
1448:
1449: private class WindowsProcessOnExitCleanerHandler extends
1450: ProcessOnExitCleanerHandler {
1451: public WindowsProcessOnExitCleanerHandler(
1452: String cleanerDefaultFileName) {
1453: super (cleanerDefaultFileName);
1454: }
1455:
1456: protected void writeCleaner(File cleanerFile)
1457: throws IOException {
1458: InputStream is = ResourceUtils
1459: .getResource(CLEANER_RESOURCE);
1460: FileUtils.writeFile(cleanerFile, is);
1461: is.close();
1462: }
1463:
1464: protected void writeCleaningFileList(File listFile,
1465: List<String> files) throws IOException {
1466: FileUtils.writeStringList(listFile, files, "UNICODE");
1467: }
1468:
1469: @Override
1470: public void run() {
1471: init();
1472: if (runningCommand != null) {
1473: try {
1474: String command = "";
1475: for (int i = 0; i < runningCommand.size(); i++) {
1476: if (i != 0) {
1477: command += StringUtils.SPACE;
1478: }
1479: command += StringUtils.QUOTE
1480: + runningCommand.get(i)
1481: + StringUtils.QUOTE;
1482: }
1483: createProcessWithoutHandles0(command);
1484: } catch (NativeException e) {
1485: LogManager.log(e);
1486: }
1487: }
1488: }
1489: }
1490:
1491: private class FileExtensionKey extends FileExtension {
1492: private String key;
1493:
1494: public FileExtensionKey(FileExtension fe, String key) {
1495: super (fe);
1496: this .key = key;
1497: }
1498:
1499: public String getKey() {
1500: return key;
1501: }
1502: }
1503:
1504: private class SystemApplicationKey extends SystemApplication {
1505: private String key;
1506:
1507: public SystemApplicationKey(SystemApplication sapp,
1508: String extKey) {
1509: super (sapp);
1510: key = extKey;
1511: }
1512:
1513: public String getKey() {
1514: return key;
1515: }
1516: }
1517:
1518: private String getExtProperty(Properties props, String name) {
1519: return props.getProperty(EXTENSION_VALUE_NAME + name);
1520: }
1521:
1522: private String getExtProperty(Properties props, String name,
1523: String prop) {
1524: return props.getProperty(EXTENSION_VALUE_NAME + name + DOT
1525: + prop);
1526: }
1527:
1528: private void setExtProperty(Properties props, String name,
1529: String value) {
1530: props.setProperty(EXTENSION_VALUE_NAME + name, value);
1531: }
1532:
1533: private void setExtProperty(Properties props, String name,
1534: String prop, String value) {
1535: props.setProperty(EXTENSION_VALUE_NAME + name + DOT + prop,
1536: value);
1537: }
1538:
1539: // native declarations //////////////////////////////////////////////////////////
1540: private native boolean isCurrentUserAdmin0();
1541:
1542: private native long getFreeSpace0(String string);
1543:
1544: private native void createShortcut0(FileShortcut shortcut);
1545:
1546: private native void createProcessWithoutHandles0(String command)
1547: throws NativeException;
1548:
1549: private native void deleteFileOnReboot0(String file);
1550:
1551: private native void notifyAssociationChanged0();
1552:
1553: private native int checkAccessTokenAccessLevel0(String path,
1554: int desiredLevel) throws NativeException;
1555:
1556: private native int notifyEnvironmentChanged0()
1557: throws NativeException;
1558: }
|