From 1d64c3e166b7f9a5e44bc531425b3d4efc1edba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Tue, 25 Jun 2013 19:44:24 +0200 Subject: [PATCH] Issue #160 binaryData export from commandline fix Issue #123 SWF Context menu integration (Windows) --- trunk/src/com/jpexs/decompiler/flash/SWF.java | 8 +- .../com/jpexs/decompiler/flash/TagNode.java | 4 +- .../com/jpexs/decompiler/flash/abc/ABC.java | 9 +- .../com/jpexs/decompiler/flash/gui/Main.java | 272 +++-- .../jpexs/decompiler/flash/gui/MainFrame.java | 39 +- .../gui/jna/platform/win32/Advapi32.java | 844 +++++++++++++++ .../gui/jna/platform/win32/Advapi32Util.java | 982 ++++++++++++++++++ .../jna/platform/win32/BaseTSD.java | 2 +- .../jna/platform/win32/Kernel32.java | 24 +- .../jna/platform/win32/SHELLEXECUTEINFO.java | 10 +- .../jna/platform/win32/Shell32.java | 2 +- .../jna/platform/win32/W32Errors.java | 4 +- .../jna/platform/win32/Win32Exception.java | 75 ++ .../jna/platform/win32/WinBase.java | 4 +- .../jna/platform/win32/WinDef.java | 6 +- .../jna/platform/win32/WinError.java | 4 +- .../jna/platform/win32/WinNT.java | 2 +- .../jna/platform/win32/WinReg.java | 4 +- .../jna/platform/win32/WinUser.java | 22 +- .../flash/gui/player/FlashPlayerPanel.java | 12 +- 20 files changed, 2196 insertions(+), 133 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32.java create mode 100644 trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32Util.java rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/BaseTSD.java (94%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/Kernel32.java (78%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/SHELLEXECUTEINFO.java (68%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/Shell32.java (93%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/W32Errors.java (92%) create mode 100644 trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Win32Exception.java rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/WinBase.java (97%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/WinDef.java (94%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/WinError.java (99%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/WinNT.java (99%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/WinReg.java (91%) rename trunk/src/com/jpexs/decompiler/flash/gui/{player => }/jna/platform/win32/WinUser.java (93%) diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index b1a93789b..40ef11ebd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -490,7 +490,7 @@ public class SWF { public List exportActionScript(String outdir, boolean isPcode, boolean paralel) throws Exception { boolean asV3Found = false; - List ret=new ArrayList<>(); + List ret = new ArrayList<>(); final EventListener evl = new EventListener() { @Override public void handleEvent(String event, Object data) { @@ -954,7 +954,7 @@ public class SWF { } } } - if(file!=null){ + if (file != null) { ret.add(file); } } @@ -1130,7 +1130,7 @@ public class SWF { } public static List exportBinaryData(String outdir, List tags) throws IOException { - List ret=new ArrayList<>(); + List ret = new ArrayList<>(); if (tags.isEmpty()) { return ret; } @@ -1143,7 +1143,7 @@ public class SWF { if (t instanceof CharacterTag) { characterID = ((CharacterTag) t).getCharacterID(); } - File file=new File(outdir + File.separator + characterID + ".bin"); + File file = new File(outdir + File.separator + characterID + ".bin"); try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(((DefineBinaryDataTag) t).binaryData); } diff --git a/trunk/src/com/jpexs/decompiler/flash/TagNode.java b/trunk/src/com/jpexs/decompiler/flash/TagNode.java index 1c703f35c..ce1ca1e47 100644 --- a/trunk/src/com/jpexs/decompiler/flash/TagNode.java +++ b/trunk/src/com/jpexs/decompiler/flash/TagNode.java @@ -233,7 +233,7 @@ public class TagNode { public static List exportNodeAS(List nodeList, String outdir, boolean isPcode, EventListener ev) { File dir = new File(outdir); - List ret=new ArrayList<>(); + List ret = new ArrayList<>(); if (!outdir.endsWith(File.separator)) { outdir = outdir + File.separator; } @@ -259,7 +259,7 @@ public class TagNode { } try { String f = outdir + name + ".as"; - File file=new File(f); + File file = new File(f); if (ev != null) { ev.handleEvent("export", "Exporting " + f + " ..."); } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java index 624235529..775438768 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -686,7 +686,6 @@ public class ABC { this.paralel = paralel; } - @Override public File call() throws Exception { try { @@ -701,7 +700,7 @@ public class ABC { } } - public List export(String directory, boolean pcode, List abcList, String abcStr, boolean paralel) throws IOException { + public List export(String directory, boolean pcode, List abcList, String abcStr, boolean paralel) throws IOException { ExecutorService executor = Executors.newFixedThreadPool(20); List> futureResults = new ArrayList<>(); AtomicInteger cnt = new AtomicInteger(1); @@ -712,8 +711,8 @@ public class ABC { futureResults.add(future); } } - - List ret=new ArrayList<>(); + + List ret = new ArrayList<>(); for (int f = 0; f < futureResults.size(); f++) { try { ret.add(futureResults.get(f).get()); @@ -721,7 +720,7 @@ public class ABC { Logger.getLogger(Traits.class.getName()).log(Level.SEVERE, "Error during ABC export", ex); } } - + try { executor.shutdown(); executor.awaitTermination(30, TimeUnit.MINUTES); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index be951c073..e4ca08711 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -22,9 +22,17 @@ import com.jpexs.decompiler.flash.PercentListener; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.Version; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.Advapi32Util; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.Kernel32; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.SHELLEXECUTEINFO; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.Shell32; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinReg; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinUser; import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame; import com.jpexs.decompiler.flash.helpers.Helper; +import com.sun.jna.Platform; +import com.sun.jna.WString; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -32,9 +40,11 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.*; import java.net.Socket; +import java.net.URLDecoder; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Properties; import java.util.logging.ConsoleHandler; @@ -420,6 +430,18 @@ public class Main { System.out.println("java -jar ffdec.jar -decompress myfiledec.swf myfile.swf"); } + private static void offerAssociation() { + boolean offered = (Boolean) Configuration.getConfig("offeredAssociation", Boolean.FALSE); + if (!offered) { + if (Platform.isWindows()) { + if ((!isAssociated()) && JOptionPane.showConfirmDialog(null, "Do you want to add FFDec to context menu of SWF files?\n(Can be changed later from main menu)", "Context menu", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) { + associate(true); + } + } + } + Configuration.setConfig("offeredAssociation", Boolean.TRUE); + } + /** * @param args the command line arguments */ @@ -438,9 +460,14 @@ public class Main { initLogging(Configuration.debugMode); if (args.length < pos + 1) { autoCheckForUpdates(); + offerAssociation(); showModeFrame(); } else { - if (args[pos].equals("-proxy")) { + if (args[pos].equals("-unassociate")) { + associate(false); + } else if (args[pos].equals("-associate")) { + associate(true); + } else if (args[pos].equals("-proxy")) { int port = 55555; for (int i = pos; i < args.length; i++) { if (args[i].startsWith("-P")) { @@ -461,35 +488,24 @@ public class Main { if (args.length < pos + 4) { badArguments(); } - String exportFormat = args[pos + 1]; - if (!exportFormat.toLowerCase().equals("as")) { - if (!exportFormat.toLowerCase().equals("pcode")) { - if (!exportFormat.toLowerCase().equals("image")) { - if (!exportFormat.toLowerCase().equals("shape")) { - if (!exportFormat.toLowerCase().equals("movie")) { - if (!exportFormat.toLowerCase().equals("sound")) { - if (!exportFormat.toLowerCase().equals("binaryData")) { - if (!exportFormat.toLowerCase().equals("text")) { - if (!exportFormat.toLowerCase().equals("textplain")) { - if (!exportFormat.toLowerCase().equals("all")) { - if (!exportFormat.toLowerCase().equals("fla")) { - if (!exportFormat.toLowerCase().equals("xfl")) { - System.err.println("Invalid export format:" + exportFormat); - badArguments(); - } - } - - } - - } - } - - } - } - } - } - } - } + String validExportFormats[] = new String[]{ + "as", + "pcode", + "image", + "shape", + "movie", + "sound", + "binarydata", + "text", + "textplain", + "all", + "fla", + "xfl" + }; + String exportFormat = args[pos + 1].toLowerCase(); + if (!Arrays.asList(validExportFormats).contains(exportFormat)) { + System.err.println("Invalid export format:" + exportFormat); + badArguments(); } File outDir = new File(args[pos + 2]); File inFile = new File(args[pos + 3]); @@ -510,60 +526,74 @@ public class Main { } } }); - if (exportFormat.equals("all")) { - System.out.println("Exporting images..."); - exfile.exportImages(outDir.getAbsolutePath() + File.separator + "images"); - System.out.println("Exporting shapes..."); - exfile.exportShapes(outDir.getAbsolutePath() + File.separator + "shapes"); - System.out.println("Exporting scripts..."); - exfile.exportActionScript(outDir.getAbsolutePath() + File.separator + "scripts", false, (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); - System.out.println("Exporting movies..."); - exfile.exportMovies(outDir.getAbsolutePath() + File.separator + "movies"); - System.out.println("Exporting sounds..."); - exfile.exportSounds(outDir.getAbsolutePath() + File.separator + "sounds", true, true); - System.out.println("Exporting binaryData..."); - exfile.exportBinaryData(outDir.getAbsolutePath() + File.separator + "binaryData"); - System.out.println("Exporting texts..."); - exfile.exportTexts(outDir.getAbsolutePath() + File.separator + "texts", true); - exportOK = true; - } else if (exportFormat.equals("image")) { - exfile.exportImages(outDir.getAbsolutePath()); - exportOK = true; - } else if (exportFormat.equals("shape")) { - exfile.exportShapes(outDir.getAbsolutePath()); - exportOK = true; - } else if (exportFormat.equals("as") || exportFormat.equals("pcode")) { - if ((pos + 5 < args.length) && (args[pos + 4].equals("-selectas3class"))) { + + switch (exportFormat) { + case "all": + System.out.println("Exporting images..."); + exfile.exportImages(outDir.getAbsolutePath() + File.separator + "images"); + System.out.println("Exporting shapes..."); + exfile.exportShapes(outDir.getAbsolutePath() + File.separator + "shapes"); + System.out.println("Exporting scripts..."); + exfile.exportActionScript(outDir.getAbsolutePath() + File.separator + "scripts", false, (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); + System.out.println("Exporting movies..."); + exfile.exportMovies(outDir.getAbsolutePath() + File.separator + "movies"); + System.out.println("Exporting sounds..."); + exfile.exportSounds(outDir.getAbsolutePath() + File.separator + "sounds", true, true); + System.out.println("Exporting binaryData..."); + exfile.exportBinaryData(outDir.getAbsolutePath() + File.separator + "binaryData"); + System.out.println("Exporting texts..."); + exfile.exportTexts(outDir.getAbsolutePath() + File.separator + "texts", true); exportOK = true; - for (int i = pos + 5; i < args.length; i++) { - exportOK = exportOK && exfile.exportAS3Class(args[i], outDir.getAbsolutePath(), exportFormat.equals("pcode"), (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); + break; + case "image": + exfile.exportImages(outDir.getAbsolutePath()); + exportOK = true; + break; + case "shape": + exfile.exportShapes(outDir.getAbsolutePath()); + exportOK = true; + break; + case "as": + case "pcode": + if ((pos + 5 < args.length) && (args[pos + 4].equals("-selectas3class"))) { + exportOK = true; + for (int i = pos + 5; i < args.length; i++) { + exportOK = exportOK && exfile.exportAS3Class(args[i], outDir.getAbsolutePath(), exportFormat.equals("pcode"), (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); + } + } else { + exportOK = !exfile.exportActionScript(outDir.getAbsolutePath(), exportFormat.equals("pcode"), (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)).isEmpty(); } - } else { - exportOK = !exfile.exportActionScript(outDir.getAbsolutePath(), exportFormat.equals("pcode"), (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)).isEmpty(); - } - } else if (exportFormat.equals("movie")) { - exfile.exportMovies(outDir.getAbsolutePath()); - exportOK = true; - } else if (exportFormat.equals("sound")) { - exfile.exportSounds(outDir.getAbsolutePath(), true, true); - exportOK = true; - } else if (exportFormat.equals("binaryData")) { - exfile.exportBinaryData(outDir.getAbsolutePath()); - exportOK = true; - } else if (exportFormat.equals("text")) { - exfile.exportTexts(outDir.getAbsolutePath(), true); - exportOK = true; - } else if (exportFormat.equals("textplain")) { - exfile.exportTexts(outDir.getAbsolutePath(), false); - exportOK = true; - } else if (exportFormat.equals("fla")) { - exfile.exportFla(outDir.getAbsolutePath(), inFile.getName(), applicationName, applicationVerName, version, (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); - exportOK = true; - } else if (exportFormat.equals("xfl")) { - exfile.exportXfl(outDir.getAbsolutePath(), inFile.getName(), applicationName, applicationVerName, version, (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); - exportOK = true; - } else { - exportOK = false; + break; + case "movie": + exfile.exportMovies(outDir.getAbsolutePath()); + exportOK = true; + break; + case "sound": + exfile.exportSounds(outDir.getAbsolutePath(), true, true); + exportOK = true; + break; + case "binarydata": + exfile.exportBinaryData(outDir.getAbsolutePath()); + exportOK = true; + break; + case "text": + exfile.exportTexts(outDir.getAbsolutePath(), true); + exportOK = true; + break; + case "textplain": + exfile.exportTexts(outDir.getAbsolutePath(), false); + exportOK = true; + break; + case "fla": + exfile.exportFla(outDir.getAbsolutePath(), inFile.getName(), applicationName, applicationVerName, version, (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); + exportOK = true; + break; + case "xfl": + exfile.exportXfl(outDir.getAbsolutePath(), inFile.getName(), applicationName, applicationVerName, version, (Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); + exportOK = true; + break; + default: + exportOK = false; } } catch (Exception ex) { exportOK = false; @@ -618,6 +648,7 @@ public class Main { System.exit(0); } else if (args.length == pos + 1) { autoCheckForUpdates(); + offerAssociation(); openFile(args[pos]); } else { badArguments(); @@ -936,4 +967,81 @@ public class Main { private static String getConfigFile() { return getFFDecHome() + CONFIG_NAME; } + + public static boolean isAssociated() { + if (!Advapi32Util.registryKeyExists(WinReg.HKEY_CLASSES_ROOT, ".swf")) { + return false; + } + String clsName = Advapi32Util.registryGetStringValue(WinReg.HKEY_CLASSES_ROOT, ".swf", ""); + if (clsName == null) { + return false; + } + return Advapi32Util.registryKeyExists(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec"); + } + + public static String getAppDir() { + String appDir = ""; + try { + appDir = new File(URLDecoder.decode(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8")).getParentFile().getAbsolutePath(); + } catch (UnsupportedEncodingException ex) { + Logger.getLogger(FlashPlayerPanel.class.getName()).log(Level.SEVERE, null, ex); + } + if (!appDir.endsWith("\\")) { + appDir += "\\"; + } + return appDir; + } + + public static boolean associate(boolean value) { + if (value == isAssociated()) { + return true; + } + + String appDir = getAppDir(); + + try { + if (!Advapi32Util.registryKeyExists(WinReg.HKEY_CLASSES_ROOT, ".swf")) { + Advapi32Util.registryCreateKey(WinReg.HKEY_CLASSES_ROOT, ".swf"); + Advapi32Util.registrySetStringValue(WinReg.HKEY_CLASSES_ROOT, ".swf", "", "ShockwaveFlash.ShockwaveFlash"); + } + + String clsName = Advapi32Util.registryGetStringValue(WinReg.HKEY_CLASSES_ROOT, ".swf", ""); + if (!Advapi32Util.registryKeyExists(WinReg.HKEY_CLASSES_ROOT, clsName)) { + Advapi32Util.registryCreateKey(WinReg.HKEY_CLASSES_ROOT, clsName); + Advapi32Util.registrySetStringValue(WinReg.HKEY_CLASSES_ROOT, clsName, "", "Flash Movie"); + } + + if (!Advapi32Util.registryKeyExists(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell")) { + Advapi32Util.registryCreateKey(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell"); + } + + boolean exists = Advapi32Util.registryKeyExists(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec"); + + //String shellName = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\" + clsName + "\\shell\\ffdec", ""); + if ((!exists) && value) { + Advapi32Util.registryCreateKey(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec"); + Advapi32Util.registrySetStringValue(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec", "", "Open with FFDec"); + Advapi32Util.registryCreateKey(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec\\command"); + Advapi32Util.registrySetStringValue(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec\\command", "", "\"" + appDir + "ffdec.exe\" \"%1\""); + return true; + } + if (exists && (!value)) { //unassociate + Advapi32Util.registryDeleteKey(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec\\command"); + Advapi32Util.registryDeleteKey(WinReg.HKEY_CLASSES_ROOT, clsName + "\\shell\\ffdec"); + return true; + } + } catch (Exception ex) { + //Updating registry failed, try elevating rights + SHELLEXECUTEINFO sei = new SHELLEXECUTEINFO(); + sei.fMask = 0x00000040; + sei.lpVerb = new WString("runas"); + sei.lpFile = new WString(appDir + "ffdec.exe"); + sei.lpParameters = new WString(value ? "-associate" : "-unassociate"); + sei.nShow = WinUser.SW_NORMAL; + Shell32.INSTANCE.ShellExecuteEx(sei); + //Wait till exit + Kernel32.INSTANCE.WaitForSingleObject(sei.hProcess, 1000 * 60 * 60 * 24 /*1 day max*/); + } + return false; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index c4f715b75..36bc3e4b2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.abc.gui.TreeElement; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import com.jpexs.decompiler.flash.action.gui.ActionPanel; +import static com.jpexs.decompiler.flash.gui.Main.isAssociated; import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel; import com.jpexs.decompiler.flash.helpers.Helper; import com.jpexs.decompiler.flash.tags.ABCContainerTag; @@ -89,6 +90,7 @@ import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.TEXTRECORD; +import com.sun.jna.Platform; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; @@ -126,6 +128,8 @@ import java.util.HashMap; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.BoxLayout; @@ -212,6 +216,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi private JPanel imageButtonsPanel; private JCheckBoxMenuItem miInternalViewer; private JCheckBoxMenuItem miParallelSpeedUp; + private JCheckBoxMenuItem miAssociate; public void setPercent(int percent) { progressBar.setValue(percent); @@ -335,7 +340,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi autoDeobfuscateMenuItem.addActionListener(this); autoDeobfuscateMenuItem.setActionCommand("AUTODEOBFUSCATE"); - menuDeobfuscation.add(autoDeobfuscateMenuItem); + JCheckBoxMenuItem miSubLimiter = new JCheckBoxMenuItem("Enable sub limiter"); miSubLimiter.setActionCommand("SUBLIMITER"); miSubLimiter.addActionListener(this); @@ -406,13 +411,12 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } miInternalViewer.setActionCommand("INTERNALVIEWERSWITCH"); miInternalViewer.addActionListener(this); - menuTools.add(miInternalViewer); miParallelSpeedUp = new JCheckBoxMenuItem("Parallel SpeedUp"); miParallelSpeedUp.setSelected((Boolean) Configuration.getConfig("paralelSpeedUp", Boolean.TRUE)); miParallelSpeedUp.setActionCommand("PARALLELSPEEDUP"); miParallelSpeedUp.addActionListener(this); - menuTools.add(miParallelSpeedUp); + menuTools.add(miProxy); @@ -427,6 +431,21 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } menuBar.add(menuTools); + JMenu menuSettings = new JMenu("Settings"); + menuSettings.add(autoDeobfuscateMenuItem); + menuSettings.add(miInternalViewer); + menuSettings.add(miParallelSpeedUp); + + + miAssociate = new JCheckBoxMenuItem("Add FFDec to SWF files context menu"); + miAssociate.setActionCommand("ASSOCIATE"); + miAssociate.addActionListener(this); + miAssociate.setState(isAssociated()); + if (Platform.isWindows()) { + menuSettings.add(miAssociate); + } + + menuBar.add(menuSettings); JMenu menuHelp = new JMenu("Help"); JMenuItem miAbout = new JMenuItem("About..."); miAbout.setIcon(View.getIcon("about16")); @@ -1441,6 +1460,20 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi @Override public void actionPerformed(ActionEvent e) { switch (e.getActionCommand()) { + case "ASSOCIATE": + if (miAssociate.getState() == Main.isAssociated()) { + return; + } + Main.associate(miAssociate.getState()); + + //Update checkbox menuitem accordingly (User can cancel rights elevation) + new Timer().schedule(new TimerTask() { + @Override + public void run() { + miAssociate.setState(Main.isAssociated()); + } + }, 500); //It takes some time registry change to apply + break; case "GOTODOCUMENTCLASS": String documentClass = null; loopdc: diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32.java new file mode 100644 index 000000000..3c8230f6c --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32.java @@ -0,0 +1,844 @@ +/* + * Copyright (C) 2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui.jna.platform.win32; + +/** + * + * @author JPEXS + */ +/* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLEByReference; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinReg.HKEY; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinReg.HKEYByReference; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +/** + * Advapi32.dll Interface. + * + * @author dblock[at]dblock.org + */ +public interface Advapi32 extends StdCallLibrary { + + Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", + Advapi32.class, W32APIOptions.UNICODE_OPTIONS); + + /** + * Retrieves the name of the user associated with the current thread. + * http://msdn.microsoft.com/en-us/library/ms724432(VS.85).aspx + * + * @param buffer Buffer to receive the user's logon name. + * @param len On input, the size of the buffer, on output the number of + * characters copied into the buffer, including the terminating null + * character. + * @return True if succeeded. + */ + public boolean GetUserNameW(char[] buffer, IntByReference len); + + /** + * The LogonUser function attempts to log a user on to the local computer. + * The local computer is the computer from which LogonUser was called. You + * cannot use LogonUser to log on to a remote computer. You specify the user + * with a user name and domain, and authenticate the user with a plaintext + * password. If the function succeeds, you receive a handle to a token that + * represents the logged-on user. You can then use this token handle to + * impersonate the specified user or, in most cases, to create a process + * that runs in the context of the specified user. + * + * @param lpszUsername A pointer to a null-terminated string that specifies + * the name of the user. This is the name of the user account to log on to. + * If you use the user principal name (UPN) format, user@DNS_domain_name, + * the lpszDomain parameter must be NULL. + * @param lpszDomain A pointer to a null-terminated string that specifies + * the name of the domain or server whose account database contains the + * lpszUsername account. If this parameter is NULL, the user name must be + * specified in UPN format. If this parameter is ".", the function validates + * the account using only the local account database. + * @param lpszPassword A pointer to a null-terminated string that specifies + * the plaintext password for the user account specified by lpszUsername. + * @param logonType The type of logon operation to perform. + * @param logonProvider Specifies the logon provider. + * @param phToken A pointer to a handle variable that receives a handle to a + * token that represents the specified user. + * @return If the function succeeds, the function returns nonzero. If the + * function fails, it returns zero. To get extended error information, call + * GetLastError. + */ + public boolean LogonUser( + String lpszUsername, + String lpszDomain, + String lpszPassword, + int logonType, + int logonProvider, + HANDLEByReference phToken); + + /** + * The OpenThreadToken function opens the access token associated with a + * thread. + * + * @param ThreadHandle Handle to the thread whose access token is opened. + * @param DesiredAccess Specifies an access mask that specifies the + * requested types of access to the access token. These requested access + * types are reconciled against the token's discretionary access control + * list (DACL) to determine which accesses are granted or denied. + * @param OpenAsSelf Indicates whether the access check is to be made + * against the security context of the thread calling the OpenThreadToken + * function or against the security context of the process for the calling + * thread. + * @param TokenHandle Pointer to a variable that receives the handle to the + * newly opened access token. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean OpenThreadToken( + HANDLE ThreadHandle, + int DesiredAccess, + boolean OpenAsSelf, + HANDLEByReference TokenHandle); + + /** + * The OpenProcessToken function opens the access token associated with a + * process. + * + * @param ProcessHandle Handle to the process whose access token is opened. + * The process must have the PROCESS_QUERY_INFORMATION access permission. + * @param DesiredAccess Specifies an access mask that specifies the + * requested types of access to the access token. These requested access + * types are compared with the discretionary access control list (DACL) of + * the token to determine which accesses are granted or denied. + * @param TokenHandle Pointer to a handle that identifies the newly opened + * access token when the function returns. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean OpenProcessToken( + HANDLE ProcessHandle, + int DesiredAccess, + HANDLEByReference TokenHandle); + + /** + * The DuplicateToken function creates a new access token that duplicates + * one already in existence. + * + * @param ExistingTokenHandle Handle to an access token opened with + * TOKEN_DUPLICATE access. + * @param ImpersonationLevel Specifies a SECURITY_IMPERSONATION_LEVEL + * enumerated type that supplies the impersonation level of the new token. + * @param DuplicateTokenHandle Pointer to a variable that receives a handle + * to the duplicate token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY + * access to the new token. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean DuplicateToken( + HANDLE ExistingTokenHandle, + int ImpersonationLevel, + HANDLEByReference DuplicateTokenHandle); + + /** + * The DuplicateTokenEx function creates a new access token that duplicates + * an existing token. This function can create either a primary token or an + * impersonation token. + * + * @param hExistingToken A handle to an access token opened with + * TOKEN_DUPLICATE access. + * @param dwDesiredAccess Specifies the requested access rights for the new + * token. + * @param lpTokenAttributes A pointer to a SECURITY_ATTRIBUTES structure + * that specifies a security descriptor for the new token and determines + * whether child processes can inherit the token. + * @param ImpersonationLevel Specifies a value from the + * SECURITY_IMPERSONATION_LEVEL enumeration that indicates the impersonation + * level of the new token. + * @param TokenType Specifies one of the following values from the + * TOKEN_TYPE enumeration. + * @param phNewToken A pointer to a HANDLE variable that receives the new + * token. + * @return If the function succeeds, the function returns a nonzero value. + * If the function fails, it returns zero. To get extended error + * information, call GetLastError. + */ + public boolean DuplicateTokenEx( + HANDLE hExistingToken, + int dwDesiredAccess, + WinBase.SECURITY_ATTRIBUTES lpTokenAttributes, + int ImpersonationLevel, + int TokenType, + HANDLEByReference phNewToken); + + /** + * Retrieves a specified type of information about an access token. The + * calling process must have appropriate access rights to obtain the + * information. + * + * @param tokenHandle Handle to an access token from which information is + * retrieved. If TokenInformationClass specifies TokenSource, the handle + * must have TOKEN_QUERY_SOURCE access. For all other TokenInformationClass + * values, the handle must have TOKEN_QUERY access. + * @param tokenInformationClass Specifies a value from the + * TOKEN_INFORMATION_CLASS enumerated type to identify the type of + * information the function retrieves. + * @param tokenInformation Pointer to a buffer the function fills with the + * requested information. The structure put into this buffer depends upon + * the type of information specified by the TokenInformationClass parameter. + * @param tokenInformationLength Specifies the size, in bytes, of the buffer + * pointed to by the TokenInformation parameter. If TokenInformation is + * NULL, this parameter must be zero. + * @param returnLength Pointer to a variable that receives the number of + * bytes needed for the buffer pointed to by the TokenInformation parameter. + * If this value is larger than the value specified in the + * TokenInformationLength parameter, the function fails and stores no data + * in the buffer. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean GetTokenInformation( + HANDLE tokenHandle, + int tokenInformationClass, + Structure tokenInformation, + int tokenInformationLength, + IntByReference returnLength); + + /** + * The ImpersonateLoggedOnUser function lets the calling thread impersonate + * the security context of a logged-on user. The user is represented by a + * token handle. + * + * @param hToken Handle to a primary or impersonation access token that + * represents a logged-on user. This can be a token handle returned by a + * call to LogonUser, CreateRestrictedToken, DuplicateToken, + * DuplicateTokenEx, OpenProcessToken, or OpenThreadToken functions. If + * hToken is a primary token, it must have TOKEN_QUERY and TOKEN_DUPLICATE + * access. If hToken is an impersonation token, it must have TOKEN_QUERY and + * TOKEN_IMPERSONATE access. + * @return If the function succeeds, the return value is nonzero. + */ + public boolean ImpersonateLoggedOnUser(HANDLE hToken); + + /** + * The ImpersonateSelf function obtains an access token that impersonates + * the security context of the calling process. The token is assigned to the + * calling thread. + * + * @param ImpersonationLevel Specifies a SECURITY_IMPERSONATION_LEVEL + * enumerated type that supplies the impersonation level of the new token. + * @return If the function succeeds, the return value is nonzero. + */ + public boolean ImpersonateSelf(int ImpersonationLevel); + + /** + * The RevertToSelf function terminates the impersonation of a client + * application. + * + * @return If the function succeeds, the return value is nonzero. + */ + public boolean RevertToSelf(); + + /** + * The RegOpenKeyEx function opens the specified registry key. Note that key + * names are not case sensitive. + * + * @param hKey Handle to an open key. + * @param lpSubKey Pointer to a null-terminated string containing the name + * of the subkey to open. + * @param ulOptions Reserved; must be zero. + * @param samDesired Access mask that specifies the desired access rights to + * the key. The function fails if the security descriptor of the key does + * not permit the requested access for the calling process. + * @param phkResult Pointer to a variable that receives a handle to the + * opened key. If the key is not one of the predefined registry keys, call + * the RegCloseKey function after you have finished using the handle. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegOpenKeyEx(HKEY hKey, String lpSubKey, int ulOptions, int samDesired, + HKEYByReference phkResult); + + /** + * The RegQueryValueEx function retrieves the type and data for a specified + * value name associated with an open registry key. + * + * @param hKey Handle to an open key. The key must have been opened with the + * KEY_QUERY_VALUE access right. + * @param lpValueName Pointer to a null-terminated string containing the + * name of the value to query. If lpValueName is NULL or an empty string, + * "", the function retrieves the type and data for the key's unnamed or + * default value, if any. + * @param lpReserved Reserved; must be NULL. + * @param lpType Pointer to a variable that receives a code indicating the + * type of data stored in the specified value. + * @param lpData Pointer to a buffer that receives the value's data. This + * parameter can be NULL if the data is not required. If the data is a + * string, the function checks for a terminating null character. If one is + * not found, the string is stored with a null terminator if the buffer is + * large enough to accommodate the extra character. Otherwise, the string is + * stored as is. + * @param lpcbData Pointer to a variable that specifies the size of the + * buffer pointed to by the lpData parameter, in bytes. When the function + * returns, this variable contains the size of the data copied to lpData. + * The lpcbData parameter can be NULL only if lpData is NULL. If the data + * has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, this size includes + * any terminating null character or characters. If the buffer specified by + * lpData parameter is not large enough to hold the data, the function + * returns ERROR_MORE_DATA and stores the required buffer size in the + * variable pointed to by lpcbData. In this case, the contents of the lpData + * buffer are undefined. If lpData is NULL, and lpcbData is non-NULL, the + * function returns ERROR_SUCCESS and stores the size of the data, in bytes, + * in the variable pointed to by lpcbData. This enables an application to + * determine the best way to allocate a buffer for the value's data. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + IntByReference lpType, char[] lpData, IntByReference lpcbData); + + public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + IntByReference lpType, byte[] lpData, IntByReference lpcbData); + + public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + IntByReference lpType, IntByReference lpData, IntByReference lpcbData); + + public int RegQueryValueEx(HKEY hKey, String lpValueName, int lpReserved, + IntByReference lpType, Pointer lpData, IntByReference lpcbData); + + /** + * The RegCloseKey function releases a handle to the specified registry key. + * + * @param hKey Handle to the open key to be closed. The handle must have + * been opened by the RegCreateKeyEx, RegOpenKeyEx, or RegConnectRegistry + * function. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegCloseKey(HKEY hKey); + + /** + * The RegDeleteValue function removes a named value from the specified + * registry key. Note that value names are not case sensitive. + * + * @param hKey Handle to an open key. The key must have been opened with the + * KEY_SET_VALUE access right. + * @param lpValueName Pointer to a null-terminated string that names the + * value to remove. If this parameter is NULL or an empty string, the value + * set by the RegSetValue function is removed. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegDeleteValue(HKEY hKey, String lpValueName); + + /** + * The RegSetValueEx function sets the data and type of a specified value + * under a registry key. + * + * @param hKey Handle to an open key. The key must have been opened with the + * KEY_SET_VALUE access right. + * @param lpValueName Pointer to a string containing the name of the value + * to set. If a value with this name is not already present in the key, the + * function adds it to the key. If lpValueName is NULL or an empty string, + * "", the function sets the type and data for the key's unnamed or default + * value. + * @param Reserved Reserved; must be zero. + * @param dwType Type of data pointed to by the lpData parameter. + * @param lpData Pointer to a buffer containing the data to be stored with + * the specified value name. + * @param cbData Size of the information pointed to by the lpData parameter, + * in bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, + * cbData must include the size of the terminating null character or + * characters. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved, int dwType, + char[] lpData, int cbData); + + public int RegSetValueEx(HKEY hKey, String lpValueName, int Reserved, int dwType, + byte[] lpData, int cbData); + + /** + * + * @param hKey + * @param lpSubKey + * @param Reserved + * @param lpClass + * @param dwOptions + * @param samDesired + * @param lpSecurityAttributes + * @param phkResult + * @param lpdwDisposition + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegCreateKeyEx(HKEY hKey, String lpSubKey, int Reserved, String lpClass, + int dwOptions, int samDesired, SECURITY_ATTRIBUTES lpSecurityAttributes, + HKEYByReference phkResult, IntByReference lpdwDisposition); + + /** + * + * @param hKey + * @param name + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegDeleteKey(HKEY hKey, String name); + + /** + * The RegEnumKeyEx function enumerates subkeys of the specified open + * registry key. The function retrieves information about one subkey each + * time it is called. + * + * @param hKey Handle to an open key. The key must have been opened with the + * KEY_ENUMERATE_SUB_KEYS access right. + * @param dwIndex Index of the subkey to retrieve. This parameter should be + * zero for the first call to the RegEnumKeyEx function and then incremented + * for subsequent calls. Because subkeys are not ordered, any new subkey + * will have an arbitrary index. This means that the function may return + * subkeys in any order. + * @param lpName Pointer to a buffer that receives the name of the subkey, + * including the terminating null character. The function copies only the + * name of the subkey, not the full key hierarchy, to the buffer. + * @param lpcName Pointer to a variable that specifies the size of the + * buffer specified by the lpName parameter, in TCHARs. This size should + * include the terminating null character. When the function returns, the + * variable pointed to by lpcName contains the number of characters stored + * in the buffer. The count returned does not include the terminating null + * character. + * @param reserved Reserved; must be NULL. + * @param lpClass Pointer to a buffer that receives the null-terminated + * class string of the enumerated subkey. This parameter can be NULL. + * @param lpcClass Pointer to a variable that specifies the size of the + * buffer specified by the lpClass parameter, in TCHARs. The size should + * include the terminating null character. When the function returns, + * lpcClass contains the number of characters stored in the buffer. The + * count returned does not include the terminating null character. This + * parameter can be NULL only if lpClass is NULL. + * @param lpftLastWriteTime Pointer to a variable that receives the time at + * which the enumerated subkey was last written. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegEnumKeyEx(HKEY hKey, int dwIndex, char[] lpName, IntByReference lpcName, + IntByReference reserved, char[] lpClass, IntByReference lpcClass, + WinBase.FILETIME lpftLastWriteTime); + + /** + * The RegEnumValue function enumerates the values for the specified open + * registry key. The function copies one indexed value name and data block + * for the key each time it is called. + * + * @param hKey Handle to an open key. The key must have been opened with the + * KEY_QUERY_VALUE access right. + * @param dwIndex Index of the value to be retrieved. This parameter should + * be zero for the first call to the RegEnumValue function and then be + * incremented for subsequent calls. Because values are not ordered, any new + * value will have an arbitrary index. This means that the function may + * return values in any order. + * @param lpValueName Pointer to a buffer that receives the name of the + * value, including the terminating null character. + * @param lpcchValueName Pointer to a variable that specifies the size of + * the buffer pointed to by the lpValueName parameter, in TCHARs. This size + * should include the terminating null character. When the function returns, + * the variable pointed to by lpcValueName contains the number of characters + * stored in the buffer. The count returned does not include the terminating + * null character. + * @param reserved Reserved; must be NULL. + * @param lpType Pointer to a variable that receives a code indicating the + * type of data stored in the specified value. + * @param lpData Pointer to a buffer that receives the data for the value + * entry. This parameter can be NULL if the data is not required. + * @param lpcbData Pointer to a variable that specifies the size of the + * buffer pointed to by the lpData parameter, in bytes. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegEnumValue(HKEY hKey, int dwIndex, char[] lpValueName, + IntByReference lpcchValueName, IntByReference reserved, + IntByReference lpType, byte[] lpData, IntByReference lpcbData); + + /** + * The RegQueryInfoKey function retrieves information about the specified + * registry key. + * + * @param hKey A handle to an open key. The key must have been opened with + * the KEY_QUERY_VALUE access right. + * @param lpClass A pointer to a buffer that receives the null-terminated + * class string of the key. This parameter can be ignored. This parameter + * can be NULL. + * @param lpcClass A pointer to a variable that specifies the size of the + * buffer pointed to by the lpClass parameter, in characters. + * @param lpReserved Reserved; must be NULL. + * @param lpcSubKeys A pointer to a variable that receives the number of + * subkeys that are contained by the specified key. This parameter can be + * NULL. + * @param lpcMaxSubKeyLen A pointer to a variable that receives the size of + * the key's subkey with the longest name, in characters, not including the + * terminating null character. This parameter can be NULL. + * @param lpcMaxClassLen A pointer to a variable that receives the size of + * the longest string that specifies a subkey class, in characters. The + * count returned does not include the terminating null character. This + * parameter can be NULL. + * @param lpcValues A pointer to a variable that receives the number of + * values that are associated with the key. This parameter can be NULL. + * @param lpcMaxValueNameLen A pointer to a variable that receives the size + * of the key's longest value name, in characters. The size does not include + * the terminating null character. This parameter can be NULL. + * @param lpcMaxValueLen A pointer to a variable that receives the size of + * the longest data component among the key's values, in bytes. This + * parameter can be NULL. + * @param lpcbSecurityDescriptor A pointer to a variable that receives the + * size of the key's security descriptor, in bytes. This parameter can be + * NULL. + * @param lpftLastWriteTime A pointer to a FILETIME structure that receives + * the last write time. This parameter can be NULL. + * @return If the function succeeds, the return value is ERROR_SUCCESS. If + * the function fails, the return value is a nonzero error code defined in + * Winerror.h. + */ + public int RegQueryInfoKey(HKEY hKey, char[] lpClass, + IntByReference lpcClass, IntByReference lpReserved, + IntByReference lpcSubKeys, IntByReference lpcMaxSubKeyLen, + IntByReference lpcMaxClassLen, IntByReference lpcValues, + IntByReference lpcMaxValueNameLen, IntByReference lpcMaxValueLen, + IntByReference lpcbSecurityDescriptor, + WinBase.FILETIME lpftLastWriteTime); + + /** + * Retrieves a registered handle to the specified event log. + * + * @param lpUNCServerName The Universal Naming Convention (UNC) name of the + * remote server on which this operation is to be performed. If this + * parameter is NULL, the local computer is used. + * @param lpSourceName The name of the event source whose handle is to be + * retrieved. The source name must be a subkey of a log under the Eventlog + * registry key. However, the Security log is for system use only. + * @return If the function succeeds, the return value is a handle to the + * event log. If the function fails, the return value is NULL. To get + * extended error information, call GetLastError. The function returns + * ERROR_ACCESS_DENIED if lpSourceName specifies the Security event log. + */ + public HANDLE RegisterEventSource(String lpUNCServerName, String lpSourceName); + + /** + * Closes the specified event log. + * + * @param hEventLog A handle to the event log. The RegisterEventSource + * function returns this handle. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean DeregisterEventSource(HANDLE hEventLog); + + /** + * Opens a handle to the specified event log. + * + * @param lpUNCServerName The Universal Naming Convention (UNC) name of the + * remote server on which the event log is to be opened. If this parameter + * is NULL, the local computer is used. + * @param lpSourceName The name of the log. If you specify a custom log and + * it cannot be found, the event logging service opens the Application log; + * however, there will be no associated message or category string file. + * @return If the function succeeds, the return value is the handle to an + * event log. If the function fails, the return value is NULL. To get + * extended error information, call GetLastError. + */ + public HANDLE OpenEventLog(String lpUNCServerName, String lpSourceName); + + /** + * Closes the specified event log. + * + * @param hEventLog A handle to the event log to be closed. The OpenEventLog + * or OpenBackupEventLog function returns this handle. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean CloseEventLog(HANDLE hEventLog); + + /** + * Retrieves the number of records in the specified event log. + * + * @param hEventLog A handle to the open event log. The OpenEventLog or + * OpenBackupEventLog function returns this handle. + * @param NumberOfRecords A pointer to a variable that receives the number + * of records in the specified event log. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean GetNumberOfEventLogRecords(HANDLE hEventLog, IntByReference NumberOfRecords); + + /** + * Clears the specified event log, and optionally saves the current copy of + * the log to a backup file. + * + * @param hEventLog A handle to the event log to be cleared. The + * OpenEventLog function returns this handle. + * @param lpBackupFileName The absolute or relative path of the backup file. + * If this file already exists, the function fails. If the lpBackupFileName + * parameter is NULL, the event log is not backed up. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. The ClearEventLog function can fail if + * the event log is empty or the backup file already exists. + */ + public boolean ClearEventLog(HANDLE hEventLog, String lpBackupFileName); + + /** + * Saves the specified event log to a backup file. The function does not + * clear the event log. + * + * @param hEventLog A handle to the open event log. The OpenEventLog + * function returns this handle. + * @param lpBackupFileName The absolute or relative path of the backup file. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean BackupEventLog(HANDLE hEventLog, String lpBackupFileName); + + /** + * Opens a handle to a backup event log created by the BackupEventLog + * function. + * + * @param lpUNCServerName The Universal Naming Convention (UNC) name of the + * remote server on which this operation is to be performed. If this + * parameter is NULL, the local computer is used. + * @param lpFileName The full path of the backup file. + * @return If the function succeeds, the return value is a handle to the + * backup event log. If the function fails, the return value is NULL. To get + * extended error information, call GetLastError. + */ + public HANDLE OpenBackupEventLog(String lpUNCServerName, String lpFileName); + + /** + * Reads the specified number of entries from the specified event log. The + * function can be used to read log entries in chronological or reverse + * chronological order. + * + * @param hEventLog A handle to the event log to be read. The OpenEventLog + * function returns this handle. + * @param dwReadFlags Use the following flag values to indicate how to read + * the log file. + * @param dwRecordOffset The record number of the log-entry at which the + * read operation should start. This parameter is ignored unless dwReadFlags + * includes the EVENTLOG_SEEK_READ flag. + * @param lpBuffer An application-allocated buffer that will receive one or + * more EVENTLOGRECORD structures. This parameter cannot be NULL, even if + * the nNumberOfBytesToRead parameter is zero. The maximum size of this + * buffer is 0x7ffff bytes. + * @param nNumberOfBytesToRead The size of the lpBuffer buffer, in bytes. + * This function will read as many log entries as will fit in the buffer; + * the function will not return partial entries. + * @param pnBytesRead A pointer to a variable that receives the number of + * bytes read by the function. + * @param pnMinNumberOfBytesNeeded A pointer to a variable that receives the + * required size of the lpBuffer buffer. This value is valid only this + * function returns zero and GetLastError returns ERROR_INSUFFICIENT_BUFFER. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean ReadEventLog(HANDLE hEventLog, int dwReadFlags, int dwRecordOffset, + Pointer lpBuffer, int nNumberOfBytesToRead, IntByReference pnBytesRead, + IntByReference pnMinNumberOfBytesNeeded); + + /** + * The GetOldestEventLogRecord function retrieves the absolute record number + * of the oldest record in the specified event log. + * + * @param hEventLog Handle to the open event log. This handle is returned by + * the OpenEventLog or OpenBackupEventLog function. + * @param OldestRecord Pointer to a variable that receives the absolute + * record number of the oldest record in the specified event log. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean GetOldestEventLogRecord(HANDLE hEventLog, IntByReference OldestRecord); + + /** + * Creates a new process and its primary thread. The new process runs in the + * security context of the user represented by the specified token. + * + * Typically, the process that calls the CreateProcessAsUser function must + * have the SE_INCREASE_QUOTA_NAME privilege and may require the + * SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable. If + * this function fails with ERROR_PRIVILEGE_NOT_HELD (1314), use the + * CreateProcessWithLogonW function instead. CreateProcessWithLogonW + * requires no special privileges, but the specified user account must be + * allowed to log on interactively. Generally, it is best to use + * CreateProcessWithLogonW to create a process with alternate credentials. + * + * @param hToken A handle to the primary token that represents a user. + * @param lpApplicationName The name of the module to be executed. + * @param lpCommandLine The command line to be executed. + * @param lpProcessAttributes A pointer to a SECURITY_ATTRIBUTES structure + * that specifies a security descriptor for the new process object and + * determines whether child processes can inherit the returned handle to the + * process. + * @param lpThreadAttributes A pointer to a SECURITY_ATTRIBUTES structure + * that specifies a security descriptor for the new thread object and + * determines whether child processes can inherit the returned handle to the + * thread. + * @param bInheritHandles If this parameter is TRUE, each inheritable handle + * in the calling process is inherited by the new process. If the parameter + * is FALSE, the handles are not inherited. Note that inherited handles have + * the same value and access rights as the original handles. + * @param dwCreationFlags The flags that control the priority class and the + * creation of the process. For a list of values, see Process Creation + * Flags. + * @param lpEnvironment A pointer to an environment block for the new + * process. If this parameter is NULL, the new process uses the environment + * of the calling process. + * + * An environment block consists of a null-terminated block of + * null-terminated strings. Each string is in the following form: + * name=value\0 + * @param lpCurrentDirectory The full path to the current directory for the + * process. The string can also specify a UNC path. + * @param lpStartupInfo A pointer to a STARTUPINFO or STARTUPINFOEX + * structure. + * @param lpProcessInformation A pointer to a PROCESS_INFORMATION structure + * that receives identification information about the new process. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean CreateProcessAsUser( + HANDLE hToken, + String lpApplicationName, + String lpCommandLine, + SECURITY_ATTRIBUTES lpProcessAttributes, + SECURITY_ATTRIBUTES lpThreadAttributes, + boolean bInheritHandles, + int dwCreationFlags, + String lpEnvironment, + String lpCurrentDirectory, + WinBase.STARTUPINFO lpStartupInfo, + WinBase.PROCESS_INFORMATION lpProcessInformation); + + /** + * The AdjustTokenPrivileges function enables or disables privileges in the + * specified access token. Enabling or disabling privileges in an access + * token requires TOKEN_ADJUST_PRIVILEGES access. + * + * @param TokenHandle A handle to the access token that contains the + * privileges to be modified. + * @param DisableAllPrivileges Specifies whether the function disables all + * of the token's privileges. + * @param NewState A pointer to a TOKEN_PRIVILEGES structure that specifies + * an array of privileges and their attributes. + * @param BufferLength Specifies the size, in bytes, of the buffer pointed + * to by the PreviousState parameter. This parameter can be zero if the + * PreviousState parameter is NULL. + * @param PreviousState A pointer to a buffer that the function fills with a + * TOKEN_PRIVILEGES structure that contains the previous state of any + * privileges that the function modifies. + * @param ReturnLength A pointer to a variable that receives the required + * size, in bytes, of the buffer pointed to by the PreviousState parameter. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean AdjustTokenPrivileges( + HANDLE TokenHandle, + boolean DisableAllPrivileges, + WinNT.TOKEN_PRIVILEGES NewState, + int BufferLength, + WinNT.TOKEN_PRIVILEGES PreviousState, + IntByReference ReturnLength); + + /** + * The LookupPrivilegeName function retrieves the name that corresponds to + * the privilege represented on a specific system by a specified locally + * unique identifier (LUID). + * + * @param lpSystemName A pointer to a null-terminated string that specifies + * the name of the system on which the privilege name is retrieved. If a + * null string is specified, the function attempts to find the privilege + * name on the local system. + * @param lpLuid A pointer to the LUID by which the privilege is known on + * the target system. + * @param lpName A pointer to a buffer that receives a null-terminated + * string that represents the privilege name. For example, this string could + * be "SeSecurityPrivilege". + * @param cchName A pointer to a variable that specifies the size, in a + * TCHAR value, of the lpName buffer. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean LookupPrivilegeName( + String lpSystemName, + WinNT.LUID lpLuid, + char[] lpName, + IntByReference cchName); + + /** + * The LookupPrivilegeValue function retrieves the locally unique identifier + * (LUID) used on a specified system to locally represent the specified + * privilege name. + * + * @param lpSystemName A pointer to a null-terminated string that specifies + * the name of the system on which the privilege name is retrieved. If a + * null string is specified, the function attempts to find the privilege + * name on the local system. + * @param lpName A pointer to a null-terminated string that specifies the + * name of the privilege, as defined in the Winnt.h header file. For + * example, this parameter could specify the constant, SE_SECURITY_NAME, or + * its corresponding string, "SeSecurityPrivilege". + * @param lpLuid A pointer to a variable that receives the LUID by which the + * privilege is known on the system specified by the lpSystemName parameter. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call GetLastError. + */ + public boolean LookupPrivilegeValue( + String lpSystemName, + String lpName, + WinNT.LUID lpLuid); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32Util.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32Util.java new file mode 100644 index 000000000..7b334ddb3 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Advapi32Util.java @@ -0,0 +1,982 @@ +/* + * Copyright (C) 2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui.jna.platform.win32; + +/** + * + * @author JPEXS + */ +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.EVENTLOGRECORD; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinReg.HKEY; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinReg.HKEYByReference; +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.IntByReference; +import java.util.ArrayList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +/** + * Advapi32 utility API. + * + * @author dblock[at]dblock.org + */ +public abstract class Advapi32Util { + + /** + * An account. + */ + public static class Account { + + /** + * Account name. + */ + public String name; + /** + * Account domain. + */ + public String domain; + /** + * Account SID. + */ + public byte[] sid; + /** + * String representation of the account SID. + */ + public String sidString; + /** + * Account type, one of SID_NAME_USE. + */ + public int accountType; + /** + * Fully qualified account name. + */ + public String fqn; + } + + /** + * Checks whether a registry key exists. + * + * @param root HKEY_LOCAL_MACHINE, etc. + * @param key Path to the registry key. + * @return True if the key exists. + */ + public static boolean registryKeyExists(HKEY root, String key) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ, phkKey); + switch (rc) { + case W32Errors.ERROR_SUCCESS: + Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + return true; + case W32Errors.ERROR_FILE_NOT_FOUND: + return false; + default: + throw new Win32Exception(rc); + } + } + + /** + * Checks whether a registry value exists. + * + * @param root HKEY_LOCAL_MACHINE, etc. + * @param key Registry key path. + * @param value Value name. + * @return True if the value exists. + */ + public static boolean registryValueExists(HKEY root, String key, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ, phkKey); + try { + switch (rc) { + case W32Errors.ERROR_SUCCESS: + break; + case W32Errors.ERROR_FILE_NOT_FOUND: + return false; + default: + throw new Win32Exception(rc); + } + IntByReference lpcbData = new IntByReference(); + IntByReference lpType = new IntByReference(); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData); + switch (rc) { + case W32Errors.ERROR_SUCCESS: + case W32Errors.ERROR_INSUFFICIENT_BUFFER: + return true; + case W32Errors.ERROR_FILE_NOT_FOUND: + return false; + default: + throw new Win32Exception(rc); + } + } finally { + if (phkKey.getValue() != WinBase.INVALID_HANDLE_VALUE) { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + } + + /** + * Get a registry REG_SZ value. + * + * @param root Root key. + * @param key Registry path. + * @param value Name of the value to retrieve. + * @return String value. + */ + public static String registryGetStringValue(HKEY root, String key, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + IntByReference lpcbData = new IntByReference(); + IntByReference lpType = new IntByReference(); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + if (lpType.getValue() != WinNT.REG_SZ) { + throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ"); + } + char[] data = new char[lpcbData.getValue()]; + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, data, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + return Native.toString(data); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Get a registry REG_EXPAND_SZ value. + * + * @param root Root key. + * @param key Registry path. + * @param value Name of the value to retrieve. + * @return String value. + */ + public static String registryGetExpandableStringValue(HKEY root, String key, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + IntByReference lpcbData = new IntByReference(); + IntByReference lpType = new IntByReference(); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + if (lpType.getValue() != WinNT.REG_EXPAND_SZ) { + throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ"); + } + char[] data = new char[lpcbData.getValue()]; + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, data, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + return Native.toString(data); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Get a registry REG_MULTI_SZ value. + * + * @param root Root key. + * @param key Registry path. + * @param value Name of the value to retrieve. + * @return String value. + */ + public static String[] registryGetStringArray(HKEY root, String key, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + IntByReference lpcbData = new IntByReference(); + IntByReference lpType = new IntByReference(); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + if (lpType.getValue() != WinNT.REG_MULTI_SZ) { + throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ"); + } + Memory data = new Memory(lpcbData.getValue()); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, data, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + ArrayList result = new ArrayList<>(); + int offset = 0; + while (offset < data.size()) { + String s = data.getString(offset, true); + offset += s.length() * Native.WCHAR_SIZE; + offset += Native.WCHAR_SIZE; + result.add(s); + } + return result.toArray(new String[0]); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Get a registry REG_BINARY value. + * + * @param root Root key. + * @param key Registry path. + * @param value Name of the value to retrieve. + * @return String value. + */ + public static byte[] registryGetBinaryValue(HKEY root, String key, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + IntByReference lpcbData = new IntByReference(); + IntByReference lpType = new IntByReference(); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + if (lpType.getValue() != WinNT.REG_BINARY) { + throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_BINARY"); + } + byte[] data = new byte[lpcbData.getValue()]; + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, data, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + return data; + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Get a registry DWORD value. + * + * @param root Root key. + * @param key Registry key path. + * @param value Name of the value to retrieve. + * @return Integer value. + */ + public static int registryGetIntValue(HKEY root, String key, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, key, 0, WinNT.KEY_READ, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + IntByReference lpcbData = new IntByReference(); + IntByReference lpType = new IntByReference(); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, (char[]) null, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + if (lpType.getValue() != WinNT.REG_DWORD) { + throw new RuntimeException("Unexpected registry type " + lpType.getValue() + ", expected REG_SZ"); + } + IntByReference data = new IntByReference(); + rc = Advapi32.INSTANCE.RegQueryValueEx( + phkKey.getValue(), value, 0, lpType, data, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) { + throw new Win32Exception(rc); + } + return data.getValue(); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Create a registry key. + * + * @param hKey Parent key. + * @param keyName Key name. + * @return True if the key was created, false otherwise. + */ + public static boolean registryCreateKey(HKEY hKey, String keyName) { + HKEYByReference phkResult = new HKEYByReference(); + IntByReference lpdwDisposition = new IntByReference(); + int rc = Advapi32.INSTANCE.RegCreateKeyEx(hKey, keyName, 0, null, WinNT.REG_OPTION_NON_VOLATILE, + WinNT.KEY_READ, null, phkResult, lpdwDisposition); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + rc = Advapi32.INSTANCE.RegCloseKey(phkResult.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + return WinNT.REG_CREATED_NEW_KEY == lpdwDisposition.getValue(); + } + + /** + * Create a registry key. + * + * @param root Root key. + * @param parentPath Path to an existing registry key. + * @param keyName Key name. + * @return True if the key was created, false otherwise. + */ + public static boolean registryCreateKey(HKEY root, String parentPath, String keyName) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, parentPath, 0, WinNT.KEY_CREATE_SUB_KEY, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + return registryCreateKey(phkKey.getValue(), keyName); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Set an integer value in registry. + * + * @param hKey Parent key. + * @param name Value name. + * @param value Value to write to registry. + */ + public static void registrySetIntValue(HKEY hKey, String name, int value) { + byte[] data = new byte[4]; + data[0] = (byte) (value & 0xff); + data[1] = (byte) ((value >> 8) & 0xff); + data[2] = (byte) ((value >> 16) & 0xff); + data[3] = (byte) ((value >> 24) & 0xff); + int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_DWORD, data, 4); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + + /** + * Set an integer value in registry. + * + * @param root Root key. + * @param keyPath Path to an existing registry key. + * @param name Value name. + * @param value Value to write to registry. + */ + public static void registrySetIntValue(HKEY root, String keyPath, String name, int value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + registrySetIntValue(phkKey.getValue(), name, value); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Set a string value in registry. + * + * @param hKey Parent key. + * @param name Value name. + * @param value Value to write to registry. + */ + public static void registrySetStringValue(HKEY hKey, String name, String value) { + char[] data = Native.toCharArray(value); + int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_SZ, + data, data.length * Native.WCHAR_SIZE); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + + /** + * Set a string value in registry. + * + * @param root Root key. + * @param keyPath Path to an existing registry key. + * @param name Value name. + * @param value Value to write to registry. + */ + public static void registrySetStringValue(HKEY root, String keyPath, String name, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + registrySetStringValue(phkKey.getValue(), name, value); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Set an expandable string value in registry. + * + * @param hKey Parent key. + * @param name Value name. + * @param value Value to write to registry. + */ + public static void registrySetExpandableStringValue(HKEY hKey, String name, String value) { + char[] data = Native.toCharArray(value); + int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_EXPAND_SZ, + data, data.length * Native.WCHAR_SIZE); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + + /** + * Set a string value in registry. + * + * @param root Root key. + * @param keyPath Path to an existing registry key. + * @param name Value name. + * @param value Value to write to registry. + */ + public static void registrySetExpandableStringValue(HKEY root, String keyPath, String name, String value) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + registrySetExpandableStringValue(phkKey.getValue(), name, value); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Set a string array value in registry. + * + * @param hKey Parent key. + * @param name Name. + * @param arr Array of strings to write to registry. + */ + public static void registrySetStringArray(HKEY hKey, String name, String[] arr) { + int size = 0; + for (String s : arr) { + size += s.length() * Native.WCHAR_SIZE; + size += Native.WCHAR_SIZE; + } + + int offset = 0; + Memory data = new Memory(size); + for (String s : arr) { + data.setString(offset, s, true); + offset += s.length() * Native.WCHAR_SIZE; + offset += Native.WCHAR_SIZE; + } + + int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_MULTI_SZ, + data.getByteArray(0, size), size); + + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + + /** + * Set a string array value in registry. + * + * @param root Root key. + * @param keyPath Path to an existing registry key. + * @param name Value name. + * @param arr Array of strings to write to registry. + */ + public static void registrySetStringArray(HKEY root, String keyPath, String name, String[] arr) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + registrySetStringArray(phkKey.getValue(), name, arr); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Set a binary value in registry. + * + * @param hKey Parent key. + * @param name Value name. + * @param data Data to write to registry. + */ + public static void registrySetBinaryValue(HKEY hKey, String name, byte[] data) { + int rc = Advapi32.INSTANCE.RegSetValueEx(hKey, name, 0, WinNT.REG_BINARY, data, data.length); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + + /** + * Set a binary value in registry. + * + * @param root Root key. + * @param keyPath Path to an existing registry key. + * @param name Value name. + * @param data Data to write to registry. + */ + public static void registrySetBinaryValue(HKEY root, String keyPath, String name, byte[] data) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + registrySetBinaryValue(phkKey.getValue(), name, data); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Delete a registry key. + * + * @param hKey Parent key. + * @param keyName Name of the key to delete. + */ + public static void registryDeleteKey(HKEY hKey, String keyName) { + int rc = Advapi32.INSTANCE.RegDeleteKey(hKey, keyName); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + + /** + * Delete a registry key. + * + * @param root Root key. + * @param keyPath Path to an existing registry key. + * @param keyName Name of the key to delete. + */ + public static void registryDeleteKey(HKEY root, String keyPath, String keyName) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + registryDeleteKey(phkKey.getValue(), keyName); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Delete a registry value. + * + * @param hKey Parent key. + * @param valueName Name of the value to delete. + */ + public static void registryDeleteValue(HKEY hKey, String valueName) { + int rc = Advapi32.INSTANCE.RegDeleteValue(hKey, valueName); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + + /** + * Delete a registry value. + * + * @param root Root key. + * @param keyPath Path to an existing registry key. + * @param valueName Name of the value to delete. + */ + public static void registryDeleteValue(HKEY root, String keyPath, String valueName) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + registryDeleteValue(phkKey.getValue(), valueName); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Get names of the registry key's sub-keys. + * + * @param hKey Registry key. + * @return Array of registry key names. + */ + public static String[] registryGetKeys(HKEY hKey) { + IntByReference lpcSubKeys = new IntByReference(); + IntByReference lpcMaxSubKeyLen = new IntByReference(); + int rc = Advapi32.INSTANCE.RegQueryInfoKey(hKey, null, null, null, + lpcSubKeys, lpcMaxSubKeyLen, null, null, null, null, null, null); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + ArrayList keys = new ArrayList<>(lpcSubKeys.getValue()); + char[] name = new char[lpcMaxSubKeyLen.getValue() + 1]; + for (int i = 0; i < lpcSubKeys.getValue(); i++) { + IntByReference lpcchValueName = new IntByReference(lpcMaxSubKeyLen.getValue() + 1); + rc = Advapi32.INSTANCE.RegEnumKeyEx(hKey, i, name, lpcchValueName, + null, null, null, null); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + keys.add(Native.toString(name)); + } + return keys.toArray(new String[0]); + } + + /** + * Get names of the registry key's sub-keys. + * + * @param root Root key. + * @param keyPath Path to a registry key. + * @return Array of registry key names. + */ + public static String[] registryGetKeys(HKEY root, String keyPath) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + return registryGetKeys(phkKey.getValue()); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Get a table of registry values. + * + * @param hKey Registry key. + * @return Table of values. + */ + public static TreeMap registryGetValues(HKEY hKey) { + IntByReference lpcValues = new IntByReference(); + IntByReference lpcMaxValueNameLen = new IntByReference(); + IntByReference lpcMaxValueLen = new IntByReference(); + int rc = Advapi32.INSTANCE.RegQueryInfoKey(hKey, null, null, null, null, + null, null, lpcValues, lpcMaxValueNameLen, lpcMaxValueLen, null, null); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + TreeMap keyValues = new TreeMap<>(); + char[] name = new char[lpcMaxValueNameLen.getValue() + 1]; + byte[] data = new byte[lpcMaxValueLen.getValue()]; + for (int i = 0; i < lpcValues.getValue(); i++) { + IntByReference lpcchValueName = new IntByReference(lpcMaxValueNameLen.getValue() + 1); + IntByReference lpcbData = new IntByReference(lpcMaxValueLen.getValue()); + IntByReference lpType = new IntByReference(); + rc = Advapi32.INSTANCE.RegEnumValue(hKey, i, name, lpcchValueName, null, + lpType, data, lpcbData); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + + String nameString = Native.toString(name); + + Memory byteData = new Memory(lpcbData.getValue()); + byteData.write(0, data, 0, lpcbData.getValue()); + + switch (lpType.getValue()) { + case WinNT.REG_DWORD: { + keyValues.put(nameString, byteData.getInt(0)); + break; + } + case WinNT.REG_SZ: + case WinNT.REG_EXPAND_SZ: { + keyValues.put(nameString, byteData.getString(0, true)); + break; + } + case WinNT.REG_BINARY: { + keyValues.put(nameString, byteData.getByteArray(0, lpcbData.getValue())); + break; + } + case WinNT.REG_MULTI_SZ: { + Memory stringData = new Memory(lpcbData.getValue()); + stringData.write(0, data, 0, lpcbData.getValue()); + ArrayList result = new ArrayList<>(); + int offset = 0; + while (offset < stringData.size()) { + String s = stringData.getString(offset, true); + offset += s.length() * Native.WCHAR_SIZE; + offset += Native.WCHAR_SIZE; + result.add(s); + } + keyValues.put(nameString, result.toArray(new String[0])); + break; + } + default: + throw new RuntimeException("Unsupported type: " + lpType.getValue()); + } + } + return keyValues; + } + + /** + * Get a table of registry values. + * + * @param root Registry root. + * @param keyPath Regitry key path. + * @return Table of values. + */ + public static TreeMap registryGetValues(HKEY root, String keyPath) { + HKEYByReference phkKey = new HKEYByReference(); + int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ, phkKey); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + try { + return registryGetValues(phkKey.getValue()); + } finally { + rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue()); + if (rc != W32Errors.ERROR_SUCCESS) { + throw new Win32Exception(rc); + } + } + } + + /** + * Converts a map of environment variables to an environment block suitable + * for {@link Advapi32#CreateProcessAsUser}. This environment block consists + * of null-terminated blocks of null-terminated strings. Each string is in + * the following form: name=value\0 + * + * @param environment Environment variables + * @return A environment block + */ + public static String getEnvironmentBlock(Map environment) { + StringBuffer out = new StringBuffer(); + for (Entry entry : environment.entrySet()) { + if (entry.getValue() != null) { + out.append(entry.getKey() + "=" + entry.getValue() + "\0"); + } + } + return out.toString() + "\0"; + } + + /** + * Event log types. + */ + public static enum EventLogType { + + Error, + Warning, + Informational, + AuditSuccess, + AuditFailure + } + + /** + * An event log record. + */ + public static class EventLogRecord { + + private EVENTLOGRECORD _record = null; + private String _source; + private byte[] _data; + private String[] _strings; + + /** + * Raw record data. + * + * @return EVENTLOGRECORD. + */ + public EVENTLOGRECORD getRecord() { + return _record; + } + + /** + * Event Id. + * + * @return Integer. + */ + public int getEventId() { + return _record.EventID.intValue(); + } + + /** + * Event source. + * + * @return String. + */ + public String getSource() { + return _source; + } + + /** + * Status code for the facility, part of the Event ID. + * + * @return Status code. + */ + public int getStatusCode() { + return _record.EventID.intValue() & 0xFFFF; + } + + /** + * Record number of the record. This value can be used with the + * EVENTLOG_SEEK_READ flag in the ReadEventLog function to begin reading + * at a specified record. + * + * @return Integer. + */ + public int getRecordNumber() { + return _record.RecordNumber.intValue(); + } + + /** + * Record length, with data. + * + * @return Number of bytes in the record including data. + */ + public int getLength() { + return _record.Length.intValue(); + } + + /** + * Strings associated with this event. + * + * @return Array of strings or null. + */ + public String[] getStrings() { + return _strings; + } + + /** + * Event log type. + * + * @return Event log type. + */ + public EventLogType getType() { + switch (_record.EventType.intValue()) { + case WinNT.EVENTLOG_SUCCESS: + case WinNT.EVENTLOG_INFORMATION_TYPE: + return EventLogType.Informational; + case WinNT.EVENTLOG_AUDIT_FAILURE: + return EventLogType.AuditFailure; + case WinNT.EVENTLOG_AUDIT_SUCCESS: + return EventLogType.AuditSuccess; + case WinNT.EVENTLOG_ERROR_TYPE: + return EventLogType.Error; + case WinNT.EVENTLOG_WARNING_TYPE: + return EventLogType.Warning; + default: + throw new RuntimeException("Invalid type: " + _record.EventType.intValue()); + } + } + + /** + * Raw data associated with the record. + * + * @return Array of bytes or null. + */ + public byte[] getData() { + return _data; + } + + public EventLogRecord(Pointer pevlr) { + _record = new EVENTLOGRECORD(pevlr); + _source = pevlr.getString(_record.size(), true); + // data + if (_record.DataLength.intValue() > 0) { + _data = pevlr.getByteArray(_record.DataOffset.intValue(), + _record.DataLength.intValue()); + } + // strings + if (_record.NumStrings.intValue() > 0) { + ArrayList strings = new ArrayList<>(); + int count = _record.NumStrings.intValue(); + long offset = _record.StringOffset.intValue(); + while (count > 0) { + String s = pevlr.getString(offset, true); + strings.add(s); + offset += s.length() * Native.WCHAR_SIZE; + offset += Native.WCHAR_SIZE; + count--; + } + _strings = strings.toArray(new String[0]); + } + } + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/BaseTSD.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/BaseTSD.java similarity index 94% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/BaseTSD.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/BaseTSD.java index 1a3211208..c7f2c3b01 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/BaseTSD.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/BaseTSD.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; import com.sun.jna.IntegerType; import com.sun.jna.Pointer; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/Kernel32.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Kernel32.java similarity index 78% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/Kernel32.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Kernel32.java index f2bd938fa..4fd2e90bd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/Kernel32.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Kernel32.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; import com.sun.jna.Native; import com.sun.jna.ptr.IntByReference; @@ -139,4 +139,26 @@ public interface Kernel32 extends WinNT { // __in HANDLE hNamedPipe // ); boolean DisconnectNamedPipe(HANDLE hNamedPipe); + + /** + * Waits until the specified object is in the signaled state or the time-out + * interval elapses. To enter an alertable wait state, use the + * WaitForSingleObjectEx function. To wait for multiple objects, use the + * WaitForMultipleObjects. + * + * @param hHandle A handle to the object. For a list of the object types + * whose handles can be specified, see the following Remarks section. If + * this handle is closed while the wait is still pending, the function's + * behavior is undefined. The handle must have the SYNCHRONIZE access right. + * For more information, see Standard Access Rights. + * @param dwMilliseconds The time-out interval, in milliseconds. If a + * nonzero value is specified, the function waits until the object is + * signaled or the interval elapses. If dwMilliseconds is zero, the function + * does not enter a wait state if the object is not signaled; it always + * returns immediately. If dwMilliseconds is INFINITE, the function will + * return only when the object is signaled. + * @return If the function succeeds, the return value indicates the event + * that caused the function to return. + */ + int WaitForSingleObject(HANDLE hHandle, int dwMilliseconds); } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/SHELLEXECUTEINFO.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/SHELLEXECUTEINFO.java similarity index 68% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/SHELLEXECUTEINFO.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/SHELLEXECUTEINFO.java index 76c4d00ba..2f06a8846 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/SHELLEXECUTEINFO.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/SHELLEXECUTEINFO.java @@ -1,9 +1,9 @@ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.HINSTANCE; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.HWND; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HANDLE; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinReg.HKEY; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.HINSTANCE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.HWND; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinReg.HKEY; import com.sun.jna.Pointer; import com.sun.jna.Structure; import com.sun.jna.WString; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/Shell32.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Shell32.java similarity index 93% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/Shell32.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Shell32.java index c861c47c4..fce08e85d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/Shell32.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Shell32.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; import com.sun.jna.Native; import com.sun.jna.win32.StdCallLibrary; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/W32Errors.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/W32Errors.java similarity index 92% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/W32Errors.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/W32Errors.java index 5632a8015..458339a45 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/W32Errors.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/W32Errors.java @@ -10,9 +10,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HRESULT; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HRESULT; // TODO: Auto-generated Javadoc /** diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Win32Exception.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Win32Exception.java new file mode 100644 index 000000000..7d17a6bec --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/Win32Exception.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui.jna.platform.win32; + +/** + * + * @author JPEXS + */ +/* Copyright (c) 2010 Daniel Doubrovkine, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HRESULT; + +/** + * Win32 exception. + * + * @author dblock[at]dblock[dot]org + */ +public class Win32Exception extends RuntimeException { + + private static final long serialVersionUID = 1L; + private HRESULT _hr; + + /** + * Returns the error code of the error. + * + * @return Error code. + */ + public HRESULT getHR() { + return _hr; + } + + /** + * New Win32 exception from HRESULT. + * + * @param hr HRESULT + */ + public Win32Exception(HRESULT hr) { + //super(Kernel32Util.formatMessageFromHR(hr)); + _hr = hr; + } + + /** + * New Win32 exception from an error code, usually obtained from + * GetLastError. + * + * @param code Error code. + */ + public Win32Exception(int code) { + this(W32Errors.HRESULT_FROM_WIN32(code)); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinBase.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinBase.java similarity index 97% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinBase.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinBase.java index c99a4752a..49f2542b2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinBase.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinBase.java @@ -10,9 +10,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HANDLE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.Platform; import com.sun.jna.Pointer; import com.sun.jna.Structure; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinDef.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinDef.java similarity index 94% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinDef.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinDef.java index 1250bc6f0..0d535208d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinDef.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinDef.java @@ -10,10 +10,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.BaseTSD.LONG_PTR; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HANDLE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.BaseTSD.LONG_PTR; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.IntegerType; import com.sun.jna.Pointer; import com.sun.jna.Structure; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinError.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinError.java similarity index 99% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinError.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinError.java index af97a0f6f..fb9f22e93 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinError.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinError.java @@ -10,9 +10,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HRESULT; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HRESULT; /** * Error code definitions for the Win32 API functions. Ported from Windows SDK diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinNT.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinNT.java similarity index 99% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinNT.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinNT.java index 935820f26..c84777cac 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinNT.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinNT.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; import com.sun.jna.FromNativeContext; import com.sun.jna.Memory; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinReg.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinReg.java similarity index 91% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinReg.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinReg.java index 2d45847cf..3e3bdcce1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinReg.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinReg.java @@ -10,9 +10,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HANDLE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.Pointer; import com.sun.jna.ptr.ByReference; import com.sun.jna.win32.StdCallLibrary; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinUser.java b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinUser.java similarity index 93% rename from trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinUser.java rename to trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinUser.java index 2c2aef8d6..8fde2d436 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/jna/platform/win32/WinUser.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/jna/platform/win32/WinUser.java @@ -10,18 +10,18 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU * Lesser General Public License for more details. */ -package com.jpexs.decompiler.flash.gui.player.jna.platform.win32; +package com.jpexs.decompiler.flash.gui.jna.platform.win32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.BaseTSD.ULONG_PTR; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.HBRUSH; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.HCURSOR; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.HICON; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.HINSTANCE; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.HWND; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.LPARAM; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.LRESULT; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef.WPARAM; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HANDLE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.BaseTSD.ULONG_PTR; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.HBRUSH; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.HCURSOR; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.HICON; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.HINSTANCE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.HWND; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.LPARAM; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.LRESULT; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef.WPARAM; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.Callback; import com.sun.jna.Pointer; import com.sun.jna.Structure; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index 78027d1e1..ad8d36b15 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -2,12 +2,12 @@ package com.jpexs.decompiler.flash.gui.player; import com.jpexs.decompiler.flash.gui.FlashUnsupportedException; import com.jpexs.decompiler.flash.gui.Main; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.Kernel32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.SHELLEXECUTEINFO; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.Shell32; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinDef; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinNT.HANDLE; -import com.jpexs.decompiler.flash.gui.player.jna.platform.win32.WinUser; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.Kernel32; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.SHELLEXECUTEINFO; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.Shell32; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinDef; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinNT.HANDLE; +import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinUser; import com.sun.jna.Native; import com.sun.jna.Platform; import com.sun.jna.WString;