diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/core/Bundle_ja.properties index 3a281e4bc3..ae67dfca3b 100644 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle_ja.properties @@ -8,7 +8,7 @@ OpenIDE-Module-Long-Description=\ \u8A73\u7D30\u306F\u4E0B\u8A18\u3092\u3054\u89A7\u4E0B\u3055\u3044\u3002http\://www.sleuthkit.org/autopsy/ OpenIDE-Module-Name=Autopsy-\u30B3\u30A2 OpenIDE-Module-Short-Description=Autopsy\u30B3\u30A2\u30E2\u30B8\u30E5\u30FC\u30EB -org_sleuthkit_autopsy_core_update_center=http\://sleuthkit.org/autopsy/updates.xml +org_sleuthkit_autopsy_core_update_center=http\://sleuthkit.org/autopsy/updates_ja.xml Services/AutoupdateType/org_sleuthkit_autopsy_core_update_center.settings=Autopsy\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u30BB\u30F3\u30BF\u30FC Installer.errorInitJavafx.msg=JavaFX\u521D\u671F\u5316\u30A8\u30E9\u30FC Installer.errorInitJavafx.details=\u4E00\u90E8\u306E\u6A5F\u80FD\u304C\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u6B63\u3057\u3044JRE\u304C\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u3066\u3044\u308B\u306E\u3092\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\uFF08Oracle JRE > 1.7.10\uFF09 \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties index d111a9c60a..1abf4708f9 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle_ja.properties @@ -1,134 +1,124 @@ -CTL_DataContentAction=\u30c7\u30fc\u30bf\u30b3\u30f3\u30c6\u30f3\u30c4 +CTL_DataContentAction=\u30C7\u30FC\u30BF\u30B3\u30F3\u30C6\u30F3\u30C4 OptionsCategory_Name_General=Autopsy -OptionsCategory_Keywords_General=Autopsy\u30aa\u30d7\u30b7\u30e7\u30f3 -CTL_CustomAboutAction=Autopsy\u306b\u3064\u3044\u3066 -CTL_DataContentTopComponent=\u30c7\u30fc\u30bf\u30b3\u30f3\u30c6\u30f3\u30c4 -HINT_DataContentTopComponent=\u3053\u308c\u306f\u30c7\u30fc\u30bf\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u3059 -HINT_NodeTableTopComponent=\u3053\u308c\u306f\u30c7\u30fc\u30bf\u7d50\u679c\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u3059 -OpenIDE-Module-Name=\u4e3b\u8981\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8 -DataContentViewerHex.pageLabel.text_1=\u30da\u30fc\u30b8\uff1a +OptionsCategory_Keywords_General=Autopsy\u30AA\u30D7\u30B7\u30E7\u30F3 +CTL_CustomAboutAction=Autopsy\u306B\u3064\u3044\u3066 +CTL_DataContentTopComponent=\u30C7\u30FC\u30BF\u30B3\u30F3\u30C6\u30F3\u30C4 +HINT_DataContentTopComponent=\u3053\u308C\u306F\u30C7\u30FC\u30BF\u30B3\u30F3\u30C6\u30F3\u30C4\u306E\u30A6\u30A3\u30F3\u30C9\u30A6\u3067\u3059 +HINT_NodeTableTopComponent=\u3053\u308C\u306F\u30C7\u30FC\u30BF\u7D50\u679C\u306E\u30A6\u30A3\u30F3\u30C9\u30A6\u3067\u3059 +OpenIDE-Module-Name=\u4E3B\u8981\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8 +DataContentViewerHex.pageLabel.text_1=\u30DA\u30FC\u30B8\uFF1A DataContentViewerHex.currentPageLabel.text_1=1 DataContentViewerHex.totalPageLabel.text_1=100 -DataContentViewerString.pageLabel.text_1=\u30da\u30fc\u30b8\uff1a +DataContentViewerString.pageLabel.text_1=\u30DA\u30FC\u30B8\uFF1A DataContentViewerString.currentPageLabel.text_1=1 DataContentViewerString.totalPageLabel.text_1=100 -DataContentViewerHex.pageLabel2.text=\u30da\u30fc\u30b8 -DataContentViewerString.pageLabel2.text=\u30da\u30fc\u30b8 -Format_OperatingSystem_Value={0} \u30d0\u30fc\u30b8\u30e7\u30f3 {1} \u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3 {2} +DataContentViewerHex.pageLabel2.text=\u30DA\u30FC\u30B8 +DataContentViewerString.pageLabel2.text=\u30DA\u30FC\u30B8 +Format_OperatingSystem_Value={0} \u30D0\u30FC\u30B8\u30E7\u30F3 {1} \u30A2\u30FC\u30AD\u30C6\u30AF\u30C1\u30E3 {2} URL_ON_IMG=http\://www.sleuthkit.org/ -LBL_Close=\u9589\u3058\u308b -DataContentViewerString.copyMenuItem.text=\u30b3\u30d4\u30fc -DataContentViewerHex.copyMenuItem.text=\u30b3\u30d4\u30fc -DataContentViewerString.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e -DataContentViewerHex.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e +LBL_Close=\u9589\u3058\u308B +DataContentViewerString.copyMenuItem.text=\u30B3\u30D4\u30FC +DataContentViewerHex.copyMenuItem.text=\u30B3\u30D4\u30FC +DataContentViewerString.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E +DataContentViewerHex.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E DataContentViewerArtifact.totalPageLabel.text=100 -DataContentViewerArtifact.pageLabel2.text=\u7d50\u679c +DataContentViewerArtifact.pageLabel2.text=\u7D50\u679C DataContentViewerArtifact.currentPageLabel.text=1 -DataContentViewerArtifact.copyMenuItem.text=\u30b3\u30d4\u30fc -DataContentViewerArtifact.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e -DataContentViewerArtifact.pageLabel.text=\u7d50\u679c\uff1a +DataContentViewerArtifact.copyMenuItem.text=\u30B3\u30D4\u30FC +DataContentViewerArtifact.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629E +DataContentViewerArtifact.pageLabel.text=\u7D50\u679C\uFF1A AdvancedConfigurationDialog.applyButton.text=OK -DataContentViewerString.goToPageLabel.text=\u4e0b\u8a18\u306e\u30da\u30fc\u30b8\u3078\u79fb\u52d5\uff1a -DataContentViewerHex.goToPageLabel.text=\u4e0b\u8a18\u306e\u30da\u30fc\u30b8\u3078\u79fb\u52d5\uff1a -DataContentViewerString.languageLabel.text=\u30b9\u30af\u30ea\u30d7\u30c8\uff1a -DataContentViewerString.languageCombo.toolTipText=\u30d0\u30a4\u30ca\u30ea\u30b9\u30c8\u30ea\u30f3\u30b0\u306e\u51e6\u7406\uff08\u62bd\u51fa\u304a\u3088\u3073\u30c7\u30b3\u30fc\u30c9\uff09\u306b\u4f7f\u7528\u3059\u308b\u8a00\u8a9e -DataResultViewerThumbnail.pageLabel.text=\u30da\u30fc\u30b8\uff1a -DataResultViewerThumbnail.pagesLabel.text=\u30da\u30fc\u30b8\uff1a -DataResultViewerThumbnail.imagesLabel.text=\u30a4\u30e1\u30fc\u30b8\uff1a +DataContentViewerString.goToPageLabel.text=\u4E0B\u8A18\u306E\u30DA\u30FC\u30B8\u3078\u79FB\u52D5\uFF1A +DataContentViewerHex.goToPageLabel.text=\u4E0B\u8A18\u306E\u30DA\u30FC\u30B8\u3078\u79FB\u52D5\uFF1A +DataContentViewerString.languageLabel.text=\u30B9\u30AF\u30EA\u30D7\u30C8\uFF1A +DataContentViewerString.languageCombo.toolTipText=\u30D0\u30A4\u30CA\u30EA\u30B9\u30C8\u30EA\u30F3\u30B0\u306E\u51E6\u7406\uFF08\u62BD\u51FA\u304A\u3088\u3073\u30C7\u30B3\u30FC\u30C9\uFF09\u306B\u4F7F\u7528\u3059\u308B\u8A00\u8A9E +DataResultViewerThumbnail.pageLabel.text=\u30DA\u30FC\u30B8\uFF1A +DataResultViewerThumbnail.pagesLabel.text=\u30DA\u30FC\u30B8\uFF1A +DataResultViewerThumbnail.imagesLabel.text=\u30A4\u30E1\u30FC\u30B8\uFF1A DataResultViewerThumbnail.imagesRangeLabel.text=- DataResultViewerThumbnail.pageNumLabel.text=- -DataResultViewerThumbnail.goToPageLabel.text=\u4e0b\u8a18\u306e\u30da\u30fc\u30b8\u306b\u79fb\u52d5\uff1a -AdvancedConfigurationDialog.cancelButton.text=\u30ad\u30e3\u30f3\u30bb\u30eb -DataResultPanel.directoryTablePath.text=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30d1\u30b9 +DataResultViewerThumbnail.goToPageLabel.text=\u4E0B\u8A18\u306E\u30DA\u30FC\u30B8\u306B\u79FB\u52D5\uFF1A +AdvancedConfigurationDialog.cancelButton.text=\u30AD\u30E3\u30F3\u30BB\u30EB +DataResultPanel.directoryTablePath.text=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u30D1\u30B9 DataResultPanel.numberMatchLabel.text=0 -DataResultPanel.matchLabel.text=\u7d50\u679c -MediaViewVideoPanel.pauseButton.text=\u25ba +DataResultPanel.matchLabel.text=\u7D50\u679C +MediaViewVideoPanel.pauseButton.text=\u25BA MediaViewVideoPanel.progressLabel.text=00\:00 -MediaViewVideoPanel.infoLabel.text=\u60c5\u5831 -DataContentViewerArtifact.waitText=\u30c7\u30fc\u30bf\u3092\u53d6\u8fbc\u307f\u304a\u3088\u3073\u6e96\u5099\u4e2d\u3002\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u4e0b\u3055\u3044\u2026 -DataContentViewerArtifact.errorText=\u7d50\u679c\u306e\u53d6\u8fbc\u307f\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f -DataContentViewerArtifact.title=\u7d50\u679c -DataContentViewerArtifact.toolTip=\u30d5\u30a1\u30a4\u30eb\u306b\u95a2\u9023\u3059\u308b\u7d50\u679c\u3092\u8868\u793a\u3057\u307e\u3059 -DataContentViewerHex.goToPageTextField.msgDlg=\uff11\u304b\u3089 {0}\u306e\u9593\u306e\u6709\u52b9\u306a\u30da\u30fc\u30b8\u6570\u3092\u5165\u529b\u3057\u3066\u4e0b\u3055\u3044 -DataContentViewerHex.goToPageTextField.err=\u7121\u52b9\u306a\u30da\u30fc\u30b8\u6570 -DataContentViewerHex.setDataView.errorText=\uff08\u30aa\u30d5\u30bb\u30c3\u30c8{0}-{1}\u306f\u8aad\u307f\u53d6\u308c\u307e\u305b\u3093\u3067\u3057\u305f\uff09 +MediaViewVideoPanel.infoLabel.text=\u60C5\u5831 +DataContentViewerArtifact.waitText=\u30C7\u30FC\u30BF\u3092\u53D6\u8FBC\u307F\u304A\u3088\u3073\u6E96\u5099\u4E2D\u3002\u3057\u3070\u3089\u304F\u304A\u5F85\u3061\u4E0B\u3055\u3044\u2026 +DataContentViewerArtifact.errorText=\u7D50\u679C\u306E\u53D6\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F +DataContentViewerArtifact.title=\u7D50\u679C +DataContentViewerArtifact.toolTip=\u30D5\u30A1\u30A4\u30EB\u306B\u95A2\u9023\u3059\u308B\u7D50\u679C\u3092\u8868\u793A\u3057\u307E\u3059 +DataContentViewerHex.goToPageTextField.msgDlg=\uFF11\u304B\u3089 {0}\u306E\u9593\u306E\u6709\u52B9\u306A\u30DA\u30FC\u30B8\u6570\u3092\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044 +DataContentViewerHex.goToPageTextField.err=\u7121\u52B9\u306A\u30DA\u30FC\u30B8\u6570 +DataContentViewerHex.setDataView.errorText=\uFF08\u30AA\u30D5\u30BB\u30C3\u30C8{0}-{1}\u306F\u8AAD\u307F\u53D6\u308C\u307E\u305B\u3093\u3067\u3057\u305F\uFF09 DataContentViewerHex.title=HEX -DataContentViewerHex.toolTip=\u30d0\u30a4\u30ca\u30ea\u30b3\u30f3\u30c6\u30f3\u30c4\u3092HEX\u30d5\u30a1\u30a4\u30eb\u3068\u3057\u3066\u8868\u793a\u3057\u3001ASCII\u3068\u3057\u3066\u8868\u793a\u3067\u304d\u308b\u30d0\u30a4\u30c8\u306f\u53f3\u5074\u306b\u8868\u793a\u3057\u307e\u3059\u3002 -DataContentViewerMedia.title=\u30e1\u30c7\u30a3\u30a2 -DataContentViewerMedia.toolTip=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u308b\u30de\u30eb\u30c1\u30e1\u30c7\u30a3\u30a2\u30d5\u30a1\u30a4\u30eb\uff08\u30a4\u30e1\u30fc\u30b8\u3001\u30d3\u30c7\u30aa\u3001\u30aa\u30fc\u30c7\u30a3\u30aa\uff09\u3092\u8868\u793a\u3057\u307e\u3059\u3002 -DataContentViewerString.goToPageTextField.msgDlg=\uff11\u304b\u3089{0}\u306e\u9593\u306e\u6709\u52b9\u306a\u30da\u30fc\u30b8\u6570\u3092\u5165\u529b\u3057\u3066\u4e0b\u3055\u3044 -DataContentViewerString.goToPageTextField.err=\u7121\u52b9\u306a\u30da\u30fc\u30b8\u6570 -DataContentViewerString.setDataView.errorText=\uff08\u30aa\u30d5\u30bb\u30c3\u30c8{0}-{1}\u306f\u8aad\u307f\u53d6\u308c\u307e\u305b\u3093\u3067\u3057\u305f\uff09 -DataContentViewerString.title=\u30b9\u30c8\u30ea\u30f3\u30b0 -DataContentViewerString.toolTip=\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u62bd\u51fa\u3055\u308c\u305fASCII\u304a\u3088\u3073\u30e6\u30cb\u30b3\u30fc\u30c9\u306e\u30b9\u30c8\u30ea\u30f3\u30b0\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002 -DataResultPanel.dummyNodeDisplayName=\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u2026 -DataResultViewerTable.firstColLbl=\u540d\u524d -DataResultViewerTable.illegalArgExc.noChildFromParent=\u6307\u5b9a\u3055\u308c\u305f\u30da\u30a2\u30ec\u30f3\u30c8\u304b\u3089\u30c1\u30e3\u30a4\u30eb\u30c9\u30ce\u30fc\u30c9\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 -DataResultViewerTable.illegalArgExc.childWithoutPropertySet=\u30c1\u30e3\u30a4\u30eb\u30c9\u30ce\u30fc\u30c9\u306f\u901a\u5e38\u306ePropertySet\u3092\u6301\u3063\u3066\u3044\u307e\u305b\u3093\u3002 -DataResultViewerTable.title=\u30c6\u30fc\u30d6\u30eb -DataResultViewerTable.dummyNodeDisplayName=\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u2026 -DataResultViewerThumbnail.title=\u30b5\u30e0\u30cd\u30a4\u30eb -DataResultViewerThumbnail.goToPageTextField.msgDlg=\uff11\u304b\u3089{0}\u306e\u9593\u306e\u6709\u52b9\u306a\u30da\u30fc\u30b8\u6570\u3092\u5165\u529b\u3057\u3066\u4e0b\u3055\u3044 -DataResultViewerThumbnail.goToPageTextField.err=\u7121\u52b9\u306a\u30da\u30fc\u30b8\u6570 -DataResultViewerThumbnail.genThumbs=\u30b5\u30e0\u30cd\u30a4\u30eb\u3092\u4f5c\u6210\u4e2d\u2026 -DataResultViewerThumbnail.pageNumbers.curOfTotal={0}\uff0f{1}\u3064\u76ee -FXVideoPanel.mediaPane.infoLabel=\u524a\u9664\u3055\u308c\u305f\u30d3\u30c7\u30aa\u306e\u518d\u751f\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u5916\u90e8\u30d7\u30ec\u30fc\u30e4\u30fc\u3092\u4f7f\u7528\u3057\u3066\u4e0b\u3055\u3044\u3002 -FXVideoPanel.progress.bufferingFile={0}\u3092\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0 -FXVideoPanel.progressLabel.buffering=\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u4e2d\u2026 -FXVideoPanel.media.unsupportedFormat=\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3067\u3059\u3002 -GeneralOptionsPanelController.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc -GeneralOptionsPanelController.moduleErr.msg=GeneralOptionsPanelController\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3067\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002 -GstVideoPanel.cannotProcFile.err=\u30e1\u30c7\u30a4\u30a2\u30d7\u30ec\u30fc\u30e4\u30fc\u304c\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u51e6\u7406\u3067\u304d\u307e\u305b\u3093\u3002 -GstVideoPanel.initGst.gstException.msg=\u30aa\u30fc\u30c7\u30a3\u30aa\uff0f\u30d3\u30c7\u30aa\u306e\u518d\u751f\u304a\u3088\u3073\u30d5\u30ec\u30fc\u30e0\u306e\u62bd\u51fa\u306b\u4f7f\u7528\u3059\u308bGStreamer\u306e\u521d\u671f\u5316\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u30d3\u30c7\u30aa\u304a\u3088\u3073\u30aa\u30fc\u30c7\u30a3\u30aa\u518d\u751f\u304c\u7121\u52b9\u5316\u3055\u308c\u307e\u3059\u3002 -GstVideoPanel.initGst.otherException.msg=\u30aa\u30fc\u30c7\u30a3\u30aa\uff0f\u30d3\u30c7\u30aa\u306e\u518d\u751f\u304a\u3088\u3073\u30d5\u30ec\u30fc\u30e0\u306e\u62bd\u51fa\u306b\u4f7f\u7528\u3059\u308bGStreamer\u306e\u521d\u671f\u5316\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u30d3\u30c7\u30aa\u304a\u3088\u3073\u30aa\u30fc\u30c7\u30a3\u30aa\u518d\u751f\u304c\u7121\u52b9\u5316\u3055\u308c\u307e\u3059\u3002 -GstVideoPanel.setupVideo.infoLabel.text=\u524a\u9664\u3055\u308c\u305f\u30d3\u30c7\u30aa\u306e\u518d\u751f\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u5916\u90e8\u30d7\u30ec\u30fc\u30e4\u30fc\u3092\u4f7f\u7528\u3057\u3066\u4e0b\u3055\u3044\u3002 -GstVideoPanel.exception.problemFile.msg=\u30d5\u30a1\u30a4\u30eb({0})\u304b\u3089\u306f\u30d5\u30ec\u30fc\u30e0\u3092\u62bd\u51fa\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 -GstVideoPanel.exception.problemPlay.msg=\u30d3\u30c7\u30aa\u30d5\u30a1\u30a4\u30eb\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u9577\u3055\u3092\u78ba\u8a8d\u4e2d\u306b\u518d\u751f\u3092\u3057\u3088\u3046\u3068\u3057\u305f\u969b\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -LBL_Description=
\n \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\uff1a {0} ({9})
Sleuth Kit\u30d0\u30fc\u30b8\u30e7\u30f3\uff1a {7}
Netbeans RCP\u30d3\u30eb\u30c9\: {8}
Java\: {1}; {2}
\u30b7\u30b9\u30c6\u30e0\uff1a {3}; {4}; {5}
\u30e6\u30fc\u30b6\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u540d {6}
-LBL_Copyright=
Autopsy™\u306fSleuth Kit™\u3084\u305d\u306e\u4ed6\u30c4\u30fc\u30eb\u3092\u57fa\u306b\u3057\u305f\u30c7\u30b8\u30bf\u30eb\u30fb\u30d5\u30a9\u30ec\u30f3\u30b8\u30c3\u30af\u30fb\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0\u3067\u3059\u3002

Copyright © 2003-2013. \u8a73\u7d30\u306f\u4e0b\u8a18\u3092\u3054\u89a7\u4e0b\u3055\u3044\u3002 http\://www.sleuthkit.org.
-GstVideoPanel.exception.problemPause.msg=\u30d3\u30c7\u30aa\u30d5\u30a1\u30a4\u30eb\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u9577\u3055\u3092\u78ba\u8a8d\u4e2d\u306b\u4e00\u6642\u505c\u6b62\u3092\u3057\u3088\u3046\u3068\u3057\u305f\u969b\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -GstVideoPanel.exception.problemPauseCaptFrame.msg=\u30d3\u30c7\u30aa\u30d5\u30a1\u30a4\u30eb\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u30d5\u30ec\u30fc\u30e0\u306e\u62bd\u51fa\u4e2d\u306b\u4e00\u6642\u505c\u6b62\u3092\u3057\u3088\u3046\u3068\u3057\u305f\u969b\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -GstVideoPanel.exception.problemPlayCaptFrame.msg=\u30d3\u30c7\u30aa\u30d5\u30a1\u30a4\u30eb\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u30d5\u30ec\u30fc\u30e0\u306e\u62bd\u51fa\u4e2d\u306b\u518d\u751f\u3057\u3088\u3046\u3068\u3057\u305f\u969b\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -GstVideoPanel.exception.problemStopCaptFrame.msg=\u30d3\u30c7\u30aa\u30d5\u30a1\u30a4\u30eb\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u30d5\u30ec\u30fc\u30e0\u306e\u62bd\u51fa\u4e2d\u306b\u505c\u6b62\u3057\u3088\u3046\u3068\u3057\u305f\u969b\u306b\u554f\u984c\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 -GstVideoPanel.progress.buffering=\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u4e2d\u2026 -GstVideoPanel.progressLabel.bufferingErr=\u30d5\u30a1\u30a4\u30eb\u306e\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u30a8\u30e9\u30fc -MediaViewImagePanel.imgFileTooLarge.msg=\u30a4\u30e1\u30fc\u30b8\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\uff08\u5927\u304d\u3059\u304e\u3067\u3059\uff09\uff1a {0} -ProductInformationPanel.verbLoggingEnabled.text=Verbose\u30ed\u30b0\u304c\u6709\u52b9\u3067\u3059 -ProductInformationPanel.propertyUnknown.text=\u4e0d\u660e +DataContentViewerHex.toolTip=\u30D0\u30A4\u30CA\u30EA\u30B3\u30F3\u30C6\u30F3\u30C4\u3092HEX\u30D5\u30A1\u30A4\u30EB\u3068\u3057\u3066\u8868\u793A\u3057\u3001ASCII\u3068\u3057\u3066\u8868\u793A\u3067\u304D\u308B\u30D0\u30A4\u30C8\u306F\u53F3\u5074\u306B\u8868\u793A\u3057\u307E\u3059\u3002 +DataContentViewerMedia.title=\u30E1\u30C7\u30A3\u30A2 +DataContentViewerMedia.toolTip=\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u30DE\u30EB\u30C1\u30E1\u30C7\u30A3\u30A2\u30D5\u30A1\u30A4\u30EB\uFF08\u30A4\u30E1\u30FC\u30B8\u3001\u30D3\u30C7\u30AA\u3001\u30AA\u30FC\u30C7\u30A3\u30AA\uFF09\u3092\u8868\u793A\u3057\u307E\u3059\u3002 +DataContentViewerString.goToPageTextField.msgDlg=\uFF11\u304B\u3089{0}\u306E\u9593\u306E\u6709\u52B9\u306A\u30DA\u30FC\u30B8\u6570\u3092\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044 +DataContentViewerString.goToPageTextField.err=\u7121\u52B9\u306A\u30DA\u30FC\u30B8\u6570 +DataContentViewerString.setDataView.errorText=\uFF08\u30AA\u30D5\u30BB\u30C3\u30C8{0}-{1}\u306F\u8AAD\u307F\u53D6\u308C\u307E\u305B\u3093\u3067\u3057\u305F\uFF09 +DataContentViewerString.title=\u30B9\u30C8\u30EA\u30F3\u30B0 +DataContentViewerString.toolTip=\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u62BD\u51FA\u3055\u308C\u305FASCII\u304A\u3088\u3073\u30E6\u30CB\u30B3\u30FC\u30C9\u306E\u30B9\u30C8\u30EA\u30F3\u30B0\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002 +DataResultPanel.dummyNodeDisplayName=\u3057\u3070\u3089\u304F\u304A\u5F85\u3061\u304F\u3060\u3055\u3044\u2026 +DataResultViewerTable.firstColLbl=\u540D\u524D +DataResultViewerTable.illegalArgExc.noChildFromParent=\u6307\u5B9A\u3055\u308C\u305F\u30DA\u30A2\u30EC\u30F3\u30C8\u304B\u3089\u30C1\u30E3\u30A4\u30EB\u30C9\u30CE\u30FC\u30C9\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002 +DataResultViewerTable.illegalArgExc.childWithoutPropertySet=\u30C1\u30E3\u30A4\u30EB\u30C9\u30CE\u30FC\u30C9\u306F\u901A\u5E38\u306EPropertySet\u3092\u6301\u3063\u3066\u3044\u307E\u305B\u3093\u3002 +DataResultViewerTable.title=\u30C6\u30FC\u30D6\u30EB +DataResultViewerTable.dummyNodeDisplayName=\u3057\u3070\u3089\u304F\u304A\u5F85\u3061\u304F\u3060\u3055\u3044\u2026 +DataResultViewerThumbnail.title=\u30B5\u30E0\u30CD\u30A4\u30EB +DataResultViewerThumbnail.goToPageTextField.msgDlg=\uFF11\u304B\u3089{0}\u306E\u9593\u306E\u6709\u52B9\u306A\u30DA\u30FC\u30B8\u6570\u3092\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044 +DataResultViewerThumbnail.goToPageTextField.err=\u7121\u52B9\u306A\u30DA\u30FC\u30B8\u6570 +DataResultViewerThumbnail.genThumbs=\u30B5\u30E0\u30CD\u30A4\u30EB\u3092\u4F5C\u6210\u4E2D\u2026 +DataResultViewerThumbnail.pageNumbers.curOfTotal={0}\uFF0F{1}\u3064\u76EE +FXVideoPanel.mediaPane.infoLabel=\u524A\u9664\u3055\u308C\u305F\u30D3\u30C7\u30AA\u306E\u518D\u751F\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u5916\u90E8\u30D7\u30EC\u30FC\u30E4\u30FC\u3092\u4F7F\u7528\u3057\u3066\u4E0B\u3055\u3044\u3002 +FXVideoPanel.progress.bufferingFile={0}\u3092\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0 +FXVideoPanel.progressLabel.buffering=\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u4E2D\u2026 +FXVideoPanel.media.unsupportedFormat=\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3067\u3059\u3002 +GeneralOptionsPanelController.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC +GeneralOptionsPanelController.moduleErr.msg=GeneralOptionsPanelController\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3067\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u4E0D\u5B8C\u5168\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002 +GstVideoPanel.cannotProcFile.err=\u30E1\u30C7\u30A4\u30A2\u30D7\u30EC\u30FC\u30E4\u30FC\u304C\u3053\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u51E6\u7406\u3067\u304D\u307E\u305B\u3093\u3002 +GstVideoPanel.initGst.gstException.msg=\u30AA\u30FC\u30C7\u30A3\u30AA\uFF0F\u30D3\u30C7\u30AA\u306E\u518D\u751F\u304A\u3088\u3073\u30D5\u30EC\u30FC\u30E0\u306E\u62BD\u51FA\u306B\u4F7F\u7528\u3059\u308BGStreamer\u306E\u521D\u671F\u5316\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30D3\u30C7\u30AA\u304A\u3088\u3073\u30AA\u30FC\u30C7\u30A3\u30AA\u518D\u751F\u304C\u7121\u52B9\u5316\u3055\u308C\u307E\u3059\u3002 +GstVideoPanel.initGst.otherException.msg=\u30AA\u30FC\u30C7\u30A3\u30AA\uFF0F\u30D3\u30C7\u30AA\u306E\u518D\u751F\u304A\u3088\u3073\u30D5\u30EC\u30FC\u30E0\u306E\u62BD\u51FA\u306B\u4F7F\u7528\u3059\u308BGStreamer\u306E\u521D\u671F\u5316\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30D3\u30C7\u30AA\u304A\u3088\u3073\u30AA\u30FC\u30C7\u30A3\u30AA\u518D\u751F\u304C\u7121\u52B9\u5316\u3055\u308C\u307E\u3059\u3002 +GstVideoPanel.setupVideo.infoLabel.text=\u524A\u9664\u3055\u308C\u305F\u30D3\u30C7\u30AA\u306E\u518D\u751F\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u5916\u90E8\u30D7\u30EC\u30FC\u30E4\u30FC\u3092\u4F7F\u7528\u3057\u3066\u4E0B\u3055\u3044\u3002 +GstVideoPanel.exception.problemFile.msg=\u30D5\u30A1\u30A4\u30EB({0})\u304B\u3089\u306F\u30D5\u30EC\u30FC\u30E0\u3092\u62BD\u51FA\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002 +GstVideoPanel.exception.problemPlay.msg=\u30D3\u30C7\u30AA\u30D5\u30A1\u30A4\u30EB\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u9577\u3055\u3092\u78BA\u8A8D\u4E2D\u306B\u518D\u751F\u3092\u3057\u3088\u3046\u3068\u3057\u305F\u969B\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 +LBL_Description=
\n \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\uFF1A {0} ({9})
Sleuth Kit\u30D0\u30FC\u30B8\u30E7\u30F3\uFF1A {7}
Netbeans RCP\u30D3\u30EB\u30C9\: {8}
Java\: {1}; {2}
\u30B7\u30B9\u30C6\u30E0\uFF1A {3}; {4}; {5}
\u30E6\u30FC\u30B6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u540D {6}
+LBL_Copyright=
Autopsy™\u306FSleuth Kit™\u3084\u305D\u306E\u4ED6\u30C4\u30FC\u30EB\u3092\u57FA\u306B\u3057\u305F\u30C7\u30B8\u30BF\u30EB\u30FB\u30D5\u30A9\u30EC\u30F3\u30B8\u30C3\u30AF\u30FB\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u3067\u3059\u3002

Copyright © 2003-2013. \u8A73\u7D30\u306F\u4E0B\u8A18\u3092\u3054\u89A7\u4E0B\u3055\u3044\u3002 http\://www.sleuthkit.org.
+GstVideoPanel.exception.problemPause.msg=\u30D3\u30C7\u30AA\u30D5\u30A1\u30A4\u30EB\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u9577\u3055\u3092\u78BA\u8A8D\u4E2D\u306B\u4E00\u6642\u505C\u6B62\u3092\u3057\u3088\u3046\u3068\u3057\u305F\u969B\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 +GstVideoPanel.exception.problemPauseCaptFrame.msg=\u30D3\u30C7\u30AA\u30D5\u30A1\u30A4\u30EB\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30D5\u30EC\u30FC\u30E0\u306E\u62BD\u51FA\u4E2D\u306B\u4E00\u6642\u505C\u6B62\u3092\u3057\u3088\u3046\u3068\u3057\u305F\u969B\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 +GstVideoPanel.exception.problemPlayCaptFrame.msg=\u30D3\u30C7\u30AA\u30D5\u30A1\u30A4\u30EB\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30D5\u30EC\u30FC\u30E0\u306E\u62BD\u51FA\u4E2D\u306B\u518D\u751F\u3057\u3088\u3046\u3068\u3057\u305F\u969B\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 +GstVideoPanel.exception.problemStopCaptFrame.msg=\u30D3\u30C7\u30AA\u30D5\u30A1\u30A4\u30EB\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30D5\u30EC\u30FC\u30E0\u306E\u62BD\u51FA\u4E2D\u306B\u505C\u6B62\u3057\u3088\u3046\u3068\u3057\u305F\u969B\u306B\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 +GstVideoPanel.progress.buffering=\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u4E2D\u2026 +GstVideoPanel.progressLabel.bufferingErr=\u30D5\u30A1\u30A4\u30EB\u306E\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u30A8\u30E9\u30FC +MediaViewImagePanel.imgFileTooLarge.msg=\u30A4\u30E1\u30FC\u30B8\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u5927\u304D\u3059\u304E\u3067\u3059\uFF09\uFF1A {0} +ProductInformationPanel.verbLoggingEnabled.text=Verbose\u30ED\u30B0\u304C\u6709\u52B9\u3067\u3059 +ProductInformationPanel.propertyUnknown.text=\u4E0D\u660E ProductInformationPanel.getVMValue.text={0} {1} -TableFilterNode.displayName.text=\u540d\u524d +TableFilterNode.displayName.text=\u540D\u524D DataContentViewerHex.ofLabel.text_1=of DataContentViewerString.ofLabel.text_1=of DataContentViewerArtifact.ofLabel.text=of -DataContentViewerString.setDataView.errorNoText=\uff08\u30aa\u30d5\u30bb\u30c3\u30c8{0}-{1}\u306b\u306f\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u305b\u3093\uff09 -DataResultViewerThumbnail.comboBox.smallThumbnails=\u30b5\u30e0\u30cd\u30a4\u30eb\uff08\u5c0f\uff09 -DataResultViewerThumbnail.comboBox.mediumThumbnails=\u30b5\u30e0\u30cd\u30a4\u30eb\uff08\u4e2d\uff09 -DataResultViewerThumbnail.comboBox.largeThumbnails=\u30b5\u30e0\u30cd\u30a4\u30eb\uff08\u5927\uff09 -DataResultViewerThumbnail.switchPage.done.errMsg=\u30b5\u30e0\u30cd\u30a4\u30eb\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0} -FXVideoPanel.pauseButton.infoLabel.playbackErr=\u518d\u751f\u30a8\u30e9\u30fc\u3002 -GstVideoPanel.progress.infoLabel.updateErr=\u30d3\u30c7\u30aa\u30d7\u30ed\u30b0\u30ec\u30b9\u306e\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\uff1a {0} -GstVideoPanel.ExtractMedia.progress.buffering={0}\u3092\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u4e2d -AboutWindowPanel.actVerboseLogging.text=Verbose\u30ed\u30b0\u3092\u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8 -AutopsyOptionsPanel.jLabel4.text=\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u306b\u4f7f\u7528\u3059\u308b\u30b9\u30ec\u30c3\u30c9\u6570\uff1a - -AutopsyOptionsPanel.viewsHideKnownCB.text=\u30d3\u30e5\u30fc\u304b\u3089\u9078\u629e\u3057\u3066\u3044\u308b\u5834\u5408 - -AutopsyOptionsPanel.dataSourcesHideKnownCB.text=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u30a8\u30ea\u30a2\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\uff09 - -AutopsyOptionsPanel.jLabel3.text=\u65e2\u77e5\u30d5\u30a1\u30a4\u30eb\uff08NIST NSRL\u5185\u306e\uff09\u3092\u4e0b\u8a18\u306b\u96a0\u3059\uff1a - -AutopsyOptionsPanel.useBestViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u306fHEX\u304b\u3089\u30e1\u30c7\u30a3\u30a2\u306b\u5909\u66f4\u3059\u308b\u3002 - -AutopsyOptionsPanel.useBestViewerRB.text=\u6700\u3082\u5c02\u9580\u7684\u306a\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u306b\u5909\u66f4 - -AutopsyOptionsPanel.useGMTTimeRB.text=GMT\u3092\u4f7f\u7528 - -AutopsyOptionsPanel.useLocalTimeRB.text=\u30ed\u30fc\u30ab\u30eb\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u4f7f\u7528 - -AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText=\u4f8b\u3048\u3070\u3001JPEG\u304c\u9078\u629e\u3055\u308c\u305f\u5834\u5408\u306b\u305d\u306e\u307e\u307eHEX\u30d3\u30e5\u30fc\u3092\u4f7f\u7528\u3002 - -AutopsyOptionsPanel.keepCurrentViewerRB.text=\u305d\u306e\u307e\u307e\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u30d3\u30e5\u30fc\u30a2\u3092\u4f7f\u7528 - -AutopsyOptionsPanel.jLabel1.text=\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3059\u308b\u5834\u5408\uff1a - -AutopsyOptionsPanel.jLabel2.text=\u30a2\u30a4\u30c6\u30e0\u3092\u8868\u793a\u3059\u308b\u5834\u5408\uff1a +DataContentViewerString.setDataView.errorNoText=\uFF08\u30AA\u30D5\u30BB\u30C3\u30C8{0}-{1}\u306B\u306F\u30C6\u30AD\u30B9\u30C8\u304C\u3042\u308A\u307E\u305B\u3093\uFF09 +DataResultViewerThumbnail.comboBox.smallThumbnails=\u30B5\u30E0\u30CD\u30A4\u30EB\uFF08\u5C0F\uFF09 +DataResultViewerThumbnail.comboBox.mediumThumbnails=\u30B5\u30E0\u30CD\u30A4\u30EB\uFF08\u4E2D\uFF09 +DataResultViewerThumbnail.comboBox.largeThumbnails=\u30B5\u30E0\u30CD\u30A4\u30EB\uFF08\u5927\uFF09 +DataResultViewerThumbnail.switchPage.done.errMsg=\u30B5\u30E0\u30CD\u30A4\u30EB\u4F5C\u6210\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF1A {0} +FXVideoPanel.pauseButton.infoLabel.playbackErr=\u518D\u751F\u30A8\u30E9\u30FC\u3002 +GstVideoPanel.progress.infoLabel.updateErr=\u30D3\u30C7\u30AA\u30D7\u30ED\u30B0\u30EC\u30B9\u306E\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF1A {0} +GstVideoPanel.ExtractMedia.progress.buffering={0}\u3092\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u4E2D +AboutWindowPanel.actVerboseLogging.text=Verbose\u30ED\u30B0\u3092\u30A2\u30AF\u30C6\u30A3\u30D9\u30FC\u30C8 +AutopsyOptionsPanel.jLabel4.text=\u30D5\u30A1\u30A4\u30EB\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u306B\u4F7F\u7528\u3059\u308B\u30B9\u30EC\u30C3\u30C9\u6570\uFF1A +AutopsyOptionsPanel.viewsHideKnownCB.text=\u30D3\u30E5\u30FC\u304B\u3089\u9078\u629E\u3057\u3066\u3044\u308B\u5834\u5408 +AutopsyOptionsPanel.dataSourcesHideKnownCB.text=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u30A8\u30EA\u30A2\uFF08\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u968E\u5C64\uFF09 +AutopsyOptionsPanel.jLabel3.text=\u65E2\u77E5\u30D5\u30A1\u30A4\u30EB\uFF08NIST NSRL\u5185\u306E\uFF09\u3092\u4E0B\u8A18\u306B\u96A0\u3059\uFF1A +AutopsyOptionsPanel.useBestViewerRB.toolTipText=\u4F8B\u3048\u3070\u3001JPEG\u304C\u9078\u629E\u3055\u308C\u305F\u5834\u5408\u306B\u306FHEX\u304B\u3089\u30E1\u30C7\u30A3\u30A2\u306B\u5909\u66F4\u3059\u308B\u3002 +AutopsyOptionsPanel.useBestViewerRB.text=\u6700\u3082\u5C02\u9580\u7684\u306A\u30D5\u30A1\u30A4\u30EB\u30D3\u30E5\u30FC\u30A2\u306B\u5909\u66F4 +AutopsyOptionsPanel.useGMTTimeRB.text=GMT\u3092\u4F7F\u7528 +AutopsyOptionsPanel.useLocalTimeRB.text=\u30ED\u30FC\u30AB\u30EB\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3\u3092\u4F7F\u7528 +AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText=\u4F8B\u3048\u3070\u3001JPEG\u304C\u9078\u629E\u3055\u308C\u305F\u5834\u5408\u306B\u305D\u306E\u307E\u307EHEX\u30D3\u30E5\u30FC\u3092\u4F7F\u7528\u3002 +AutopsyOptionsPanel.keepCurrentViewerRB.text=\u305D\u306E\u307E\u307E\u540C\u3058\u30D5\u30A1\u30A4\u30EB\u30D3\u30E5\u30FC\u30A2\u3092\u4F7F\u7528 +AutopsyOptionsPanel.jLabel1.text=\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E\u3059\u308B\u5834\u5408\uFF1A +AutopsyOptionsPanel.jLabel2.text=\u30A2\u30A4\u30C6\u30E0\u3092\u8868\u793A\u3059\u308B\u5834\u5408\uFF1A +AutopsyOptionsPanel.restartRequiredLabel.text=\u6709\u52B9\u306B\u3059\u308B\u306B\u306F\u518D\u8D77\u52D5\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties index 556487b1bb..b42121efea 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties @@ -52,10 +52,8 @@ IngestMonitor.mgrErrMsg.lowDiskSpace.msg=Stopping ingest due to low disk space o Ensure the Case drive has at least 1GB free space and restart ingest. IngestJobConfigurationPanel.advancedButton.text=Advanced IngestJobConfigurationPanel.advancedButton.actionCommand=Advanced -IngestScheduler.DataSourceScheduler.toString.size=DataSourceQueue, size\: IngestManager.StartIngestJobsTask.run.displayName=Queueing ingest tasks IngestManager.StartIngestJobsTask.run.cancelling={0} (Cancelling...) -IngestManager.StartIngestJobsTask.run.catchException.msg=An error occurred while starting ingest. Results may only be partial IngestMessagePanel.sortByComboBox.model.time=Time IngestMessagePanel.sortByComboBox.model.priority=Priority IngestMessagesToolbar.customizeButton.toolTipText=Ingest Messages @@ -69,8 +67,6 @@ IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList=Errors\: \ IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle=Ingest Failure IngestJobConfigurator.createModuleSettingsFolderForContext.exception.msg=Failed to create ingest module settings folder, cannot save settings. IngestJobConfigurator.createModuleSettingsFolderForContext.exception.title=Ingest Job Initialization Failure -IngestJobConfigurator.loadJobSettings.usermsg.text=Failed to load saved ingest job settings for {0} module, using defaults. -IngestJobConfigurator.loadJobSettings.usermsg.title=Ingest Job Settings IngestJobConfigurator.saveJobSettings.usermsg=Failed to save ingest job settings for {0} module. IngestJobConfigurator.saveJobSettings.usermsg.title=Ingest Job Settings IngestJobConfigurationPanel.descriptionLabel.text= diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties index da2cdc2783..f50e8f219e 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle_ja.properties @@ -13,7 +13,6 @@ IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText=\u524A\u9664\u305 IngestManager.moduleErr=\u30E2\u30B8\u30E5\u30FC\u30EB\u30A8\u30E9\u30FC IngestManager.moduleErr.errListenToUpdates.msg=Ingest Manager\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3092\u78BA\u8A8D\u4E2D\u306B\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u30A8\u30E9\u30FC\u3092\u8D77\u3053\u3057\u307E\u3057\u305F\u3002\u3069\u306E\u30E2\u30B8\u30E5\u30FC\u30EB\u304B\u30ED\u30B0\u3067\u78BA\u8A8D\u3057\u3066\u4E0B\u3055\u3044\u3002\u4E00\u90E8\u306E\u30C7\u30FC\u30BF\u304C\u4E0D\u5B8C\u5168\u304B\u3082\u3057\u308C\u307E\u305B\u3093\u3002 IngestManager.StartIngestJobsTask.run.cancelling={0}\uFF08\u30AD\u30E3\u30F3\u30BB\u30EB\u4E2D\u2026\uFF09 -IngestManager.StartIngestJobsTask.run.catchException.msg=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u306E\u958B\u59CB\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u7D50\u679C\u304C\u4E00\u90E8\u306E\u3082\u306E IngestManager.StartIngestJobsTask.run.displayName=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30BF\u30B9\u30AF\u3092\u30AD\u30E5\u30FC\u30A4\u30F3\u30B0 IngestMessage.exception.srcSubjDetailsDataNotNull.msg=\u30BD\u30FC\u30B9\u3001\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u3001\u8A73\u7D30\u304A\u3088\u3073\u30C7\u30FC\u30BF\u306F\u30CC\u30EB\u3067\u3042\u3063\u3066\u306F\u3044\u3051\u307E\u305B\u3093 IngestMessage.exception.srcSubjNotNull.msg=\u30BD\u30FC\u30B9\u304A\u3088\u3073\u30B5\u30D6\u30B8\u30A7\u30AF\u30C8\u306F\u30CC\u30EB\u3067\u3042\u3063\u3066\u306F\u3044\u3051\u307E\u305B\u3093 @@ -54,7 +53,6 @@ IngestMessageTopComponent.msgDlg.ingestRpt.text=\u30A4\u30F3\u30B8\u30A7\u30B9\u IngestMonitor.mgrErrMsg.lowDiskSpace.msg=\u30C7\u30A3\u30B9\u30AF{0}\u306E\u30C7\u30A3\u30B9\u30AF\u9818\u57DF\u4E0D\u8DB3\u306E\u305F\u3081\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u4E2D\u6B62\u3057\u307E\u3059\u3002\ \u30B1\u30FC\u30B9\u30C9\u30E9\u30A4\u30D6\u306B\u6700\u4F4E1GB\u306E\u7A7A\u304D\u9818\u57DF\u304C\u3042\u308B\u306E\u3092\u78BA\u8A8D\u3057\u3001\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u3092\u518D\u30B9\u30BF\u30FC\u30C8\u3057\u3066\u4E0B\u3055\u3044\u3002 IngestMonitor.mgrErrMsg.lowDiskSpace.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u304C\u4E2D\u6B62\u3055\u308C\u307E\u3057\u305F\u30FC{0}\u306E\u30C7\u30A3\u30B9\u30AF\u9818\u57DF\u4E0D\u8DB3 -IngestScheduler.DataSourceScheduler.toString.size=DataSourceQueue, \u30B5\u30A4\u30BA\uFF1A OpenIDE-Module-Name=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8 IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList=\u30A8\u30E9\u30FC\uFF1A\ \ @@ -64,7 +62,6 @@ IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution=\u5931\u6557\u3057\ IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u5931\u6557 IngestJobConfigurator.createModuleSettingsFolderForContext.exception.msg=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30E2\u30B8\u30E5\u30FC\u30EB\u8A2D\u5B9A\u30D5\u30A9\u30EB\u30C0\u306E\u4F5C\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u8A2D\u5B9A\u3092\u4FDD\u5B58\u3067\u304D\u307E\u305B\u3093\u3002 IngestJobConfigurator.createModuleSettingsFolderForContext.exception.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u521D\u671F\u5316\u306E\u5931\u6557 -IngestJobConfigurator.loadJobSettings.usermsg.text={0}\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u4FDD\u5B58\u3055\u308C\u305F\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A\u306E\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002 -IngestJobConfigurator.loadJobSettings.usermsg.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A IngestJobConfigurator.saveJobSettings.usermsg={0}\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002 -IngestJobConfigurator.saveJobSettings.usermsg.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A \ No newline at end of file +IngestJobConfigurator.saveJobSettings.usermsg.title=\u30A4\u30F3\u30B8\u30A7\u30B9\u30C8\u30B8\u30E7\u30D6\u8A2D\u5B9A +IngestJob.progress.dataSourceIngest.initialDisplayName={0}\u3092\u89E3\u6790\u4E2D \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java index c3411f88da..0e254e51a6 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestPipeline.java @@ -33,37 +33,28 @@ import org.sleuthkit.datamodel.Content; final class DataSourceIngestPipeline { private final IngestJobContext context; - private final List moduleTemplates; private List modules = new ArrayList<>(); DataSourceIngestPipeline(IngestJobContext context, List moduleTemplates) { this.context = context; - this.moduleTemplates = moduleTemplates; - } - List startUp() { - List errors = new ArrayList<>(); - // Create an ingest module instance from each ingest module template - // that has an ingest module factory capable of making data source - // ingest modules. Map the module class names to the module instance - // to allow the modules to be put in the sequence indicated by the - // ingest pipelines configuration. + // Create an ingest module instance from each data source ingest module + // template. Put the modules in a map of module class names to module + // instances to facilitate loading the modules into the pipeline in the + // sequence indicated by the ordered list of module class names that + // will be obtained from the data source ingest pipeline configuration. Map modulesByClass = new HashMap<>(); for (IngestModuleTemplate template : moduleTemplates) { if (template.isDataSourceIngestModuleTemplate()) { DataSourceIngestModuleDecorator module = new DataSourceIngestModuleDecorator(template.createDataSourceIngestModule(), template.getModuleName()); - try { - module.startUp(context); - modulesByClass.put(module.getClassName(), module); - } catch (Exception ex) { - errors.add(new IngestModuleError(module.getDisplayName(), ex)); - } + modulesByClass.put(module.getClassName(), module); } } - // Establish the module sequence of the core ingest modules - // indicated by the ingest pipeline configuration, adding any - // additional modules found in the global lookup to the end of the - // pipeline in arbitrary order. + + // Add the ingest modules to the pipeline in the order indicated by the + // data source ingest pipeline configuration, adding any additional + // modules found in the global lookup, but not mentioned in the + // configuration, to the end of the pipeline in arbitrary order. List pipelineConfig = IngestPipelinesConfiguration.getInstance().getDataSourceIngestPipelineConfig(); for (String moduleClassName : pipelineConfig) { if (modulesByClass.containsKey(moduleClassName)) { @@ -73,12 +64,27 @@ final class DataSourceIngestPipeline { for (DataSourceIngestModuleDecorator module : modulesByClass.values()) { modules.add(module); } + } + + boolean isEmpty() { + return modules.isEmpty(); + } + + List startUp() { + List errors = new ArrayList<>(); + for (DataSourceIngestModuleDecorator module : modules) { + try { + module.startUp(context); + } catch (Exception ex) { + errors.add(new IngestModuleError(module.getDisplayName(), ex)); + } + } return errors; } List process(Content dataSource, ProgressHandle progress) { List errors = new ArrayList<>(); - for (DataSourceIngestModuleDecorator module : this.modules) { + for (DataSourceIngestModuleDecorator module : modules) { try { progress.setDisplayName(NbBundle.getMessage(this.getClass(), "IngestJob.progress.dataSourceIngest.displayName", diff --git a/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestTaskScheduler.java b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestTaskScheduler.java new file mode 100755 index 0000000000..2acc58a5a1 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestTaskScheduler.java @@ -0,0 +1,72 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2012-2014 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.ingest; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.sleuthkit.datamodel.Content; + +final class DataSourceIngestTaskScheduler implements IngestTaskQueue { + + private static final DataSourceIngestTaskScheduler instance = new DataSourceIngestTaskScheduler(); + private final List tasks = new ArrayList<>(); // Guarded by this + private final LinkedBlockingQueue tasksQueue = new LinkedBlockingQueue<>(); + + static DataSourceIngestTaskScheduler getInstance() { + return instance; + } + + private DataSourceIngestTaskScheduler() { + } + + synchronized void scheduleTask(IngestJob job, Content dataSource) throws InterruptedException { + DataSourceIngestTask task = new DataSourceIngestTask(job, dataSource); + tasks.add(task); + try { + // Should not block, queue is (theoretically) unbounded. + tasksQueue.put(task); + } catch (InterruptedException ex) { + tasks.remove(task); + Logger.getLogger(DataSourceIngestTaskScheduler.class.getName()).log(Level.FINE, "Interruption of unexpected block on tasks queue", ex); //NON-NLS + throw ex; + } + } + + @Override + public IngestTask getNextTask() throws InterruptedException { + return tasksQueue.take(); + } + + synchronized void notifyTaskCompleted(DataSourceIngestTask task) { + tasks.remove(task); + } + + synchronized boolean hasIncompleteTasksForIngestJob(IngestJob job) { + long jobId = job.getId(); + for (DataSourceIngestTask task : tasks) { + if (task.getIngestJob().getId() == jobId) { + return true; + } + } + return false; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/ingest/FileIngestPipeline.java b/Core/src/org/sleuthkit/autopsy/ingest/FileIngestPipeline.java index f9715fdb3f..59570a3347 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/FileIngestPipeline.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/FileIngestPipeline.java @@ -31,37 +31,28 @@ import org.sleuthkit.datamodel.AbstractFile; final class FileIngestPipeline { private final IngestJobContext context; - private final List moduleTemplates; private List modules = new ArrayList<>(); FileIngestPipeline(IngestJobContext context, List moduleTemplates) { this.context = context; - this.moduleTemplates = moduleTemplates; - } - List startUp() { - List errors = new ArrayList<>(); - // Create an ingest module instance from each ingest module template - // that has an ingest module factory capable of making data source - // ingest modules. Map the module class names to the module instance - // to allow the modules to be put in the sequence indicated by the - // ingest pipelines configuration. + // Create an ingest module instance from each file ingest module + // template. Put the modules in a map of module class names to module + // instances to facilitate loading the modules into the pipeline in the + // sequence indicated by the ordered list of module class names that + // will be obtained from the file ingest pipeline configuration. Map modulesByClass = new HashMap<>(); for (IngestModuleTemplate template : moduleTemplates) { if (template.isFileIngestModuleTemplate()) { FileIngestModuleDecorator module = new FileIngestModuleDecorator(template.createFileIngestModule(), template.getModuleName()); - try { - module.startUp(context); - modulesByClass.put(module.getClassName(), module); - } catch (Exception ex) { - errors.add(new IngestModuleError(module.getDisplayName(), ex)); - } + modulesByClass.put(module.getClassName(), module); } } - // Establish the module sequence of the core ingest modules - // indicated by the ingest pipeline configuration, adding any - // additional modules found in the global lookup to the end of the - // pipeline in arbitrary order. + + // Add the ingest modules to the pipeline in the order indicated by the + // data source ingest pipeline configuration, adding any additional + // modules found in the global lookup, but not mentioned in the + // configuration, to the end of the pipeline in arbitrary order. List pipelineConfig = IngestPipelinesConfiguration.getInstance().getFileIngestPipelineConfig(); for (String moduleClassName : pipelineConfig) { if (modulesByClass.containsKey(moduleClassName)) { @@ -71,12 +62,27 @@ final class FileIngestPipeline { for (FileIngestModuleDecorator module : modulesByClass.values()) { modules.add(module); } + } + + boolean isEmpty() { + return modules.isEmpty(); + } + + List startUp() { + List errors = new ArrayList<>(); + for (FileIngestModuleDecorator module : modules) { + try { + module.startUp(context); + } catch (Exception ex) { + errors.add(new IngestModuleError(module.getDisplayName(), ex)); + } + } return errors; } List process(AbstractFile file) { List errors = new ArrayList<>(); - for (FileIngestModuleDecorator module : this.modules) { + for (FileIngestModuleDecorator module : modules) { try { module.process(file); } catch (Exception ex) { @@ -95,7 +101,7 @@ final class FileIngestPipeline { List shutDown() { List errors = new ArrayList<>(); - for (FileIngestModuleDecorator module : this.modules) { + for (FileIngestModuleDecorator module : modules) { try { module.shutDown(); } catch (Exception ex) { @@ -105,7 +111,7 @@ final class FileIngestPipeline { return errors; } - private static class FileIngestModuleDecorator implements FileIngestModule { + private static final class FileIngestModuleDecorator implements FileIngestModule { private final FileIngestModule module; private final String displayName; diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java b/Core/src/org/sleuthkit/autopsy/ingest/FileIngestTaskScheduler.java similarity index 61% rename from Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java rename to Core/src/org/sleuthkit/autopsy/ingest/FileIngestTaskScheduler.java index 2225efc617..4727f30ebc 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestScheduler.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/FileIngestTaskScheduler.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.ingest; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; -import java.util.Iterator; import java.util.List; import java.util.TreeSet; import java.util.concurrent.LinkedBlockingQueue; @@ -36,59 +35,45 @@ import org.sleuthkit.datamodel.FileSystem; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; -final class IngestScheduler { +final class FileIngestTaskScheduler implements IngestTaskQueue { - private static final IngestScheduler instance = new IngestScheduler(); - private static final Logger logger = Logger.getLogger(IngestScheduler.class.getName()); + private static final FileIngestTaskScheduler instance = new FileIngestTaskScheduler(); + private static final Logger logger = Logger.getLogger(FileIngestTaskScheduler.class.getName()); private static final int FAT_NTFS_FLAGS = TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT12.getValue() | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT16.getValue() | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_FAT32.getValue() | TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS.getValue(); - private final LinkedBlockingQueue dataSourceTasks = new LinkedBlockingQueue<>(); - private final TreeSet rootDirectoryTasks = new TreeSet<>(new RootDirectoryTaskComparator()); // Guarded by this - private final List directoryTasks = new ArrayList<>(); // Guarded by this - private final LinkedBlockingQueue fileTasks = new LinkedBlockingQueue<>(); // Guarded by this - private final List dataSourceTasksInProgress = new ArrayList<>(); // Guarded by this - private final List fileTasksInProgress = new ArrayList<>(); // Guarded by this - private final DataSourceIngestTaskQueue dataSourceTaskDispenser = new DataSourceIngestTaskQueue(); - private final FileIngestTaskQueue fileTaskDispenser = new FileIngestTaskQueue(); + private final List fileTasks = new ArrayList<>(); // Guarded by this + private final TreeSet rootDirectoryTasksQueue = new TreeSet<>(new RootDirectoryTaskComparator()); // Guarded by this + private final List directoryTasksQueue = new ArrayList<>(); // Guarded by this + private final LinkedBlockingQueue fileTasksQueue = new LinkedBlockingQueue<>(); - static IngestScheduler getInstance() { + static FileIngestTaskScheduler getInstance() { return instance; } - private IngestScheduler() { + private FileIngestTaskScheduler() { } - synchronized void addTasksForIngestJob(IngestJob job, Content dataSource) throws InterruptedException { - // Enqueue a data source ingest task for the data source. - DataSourceIngestTask task = new DataSourceIngestTask(job, dataSource); - try { - dataSourceTasks.put(task); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - logger.log(Level.FINE, "Task scheduling for ingest job interrupted", ex); //NON-NLS - return; - } - + boolean tryScheduleTasks(IngestJob job, Content dataSource) throws InterruptedException { // Get the top level files of the data source. Collection rootObjects = dataSource.accept(new GetRootDirectoryVisitor()); - List toptLevelFiles = new ArrayList<>(); + List topLevelFiles = new ArrayList<>(); if (rootObjects.isEmpty() && dataSource instanceof AbstractFile) { // The data source is itself a file. - toptLevelFiles.add((AbstractFile) dataSource); + topLevelFiles.add((AbstractFile) dataSource); } else { for (AbstractFile root : rootObjects) { List children; try { children = root.getChildren(); if (children.isEmpty()) { - // Add the root object itself, it could be an unallocated space - // file, or a child of a volume or an image. - toptLevelFiles.add(root); + // Add the root object itself, it could be an unallocated + // space file, or a child of a volume or an image. + topLevelFiles.add(root); } else { // The root object is a file system root directory, get // the files within it. for (Content child : children) { if (child instanceof AbstractFile) { - toptLevelFiles.add((AbstractFile) child); + topLevelFiles.add((AbstractFile) child); } } } @@ -98,87 +83,60 @@ final class IngestScheduler { } } - // Enqueue file ingest tasks for the top level files. - for (AbstractFile firstLevelFile : toptLevelFiles) { + // Try to enqueue file ingest tasks for the top level files. + for (AbstractFile firstLevelFile : topLevelFiles) { FileIngestTask fileTask = new FileIngestTask(job, firstLevelFile); - if (shouldEnqueueFileTask(fileTask)) { - rootDirectoryTasks.add(fileTask); + if (shouldEnqueueTask(fileTask)) { + synchronized (this) { + rootDirectoryTasksQueue.add(fileTask); + } } } - - updateFileTaskQueues(); + updateTaskQueues(); + + return !fileTasks.isEmpty(); } - void addFileTaskToIngestJob(IngestJob job, AbstractFile file) { + void scheduleTask(IngestJob job, AbstractFile file) throws InterruptedException { FileIngestTask task = new FileIngestTask(job, file); - if (shouldEnqueueFileTask(task)) { - try { - fileTasks.put(task); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - logger.log(Level.FINE, "Task scheduling for ingest job interrupted", ex); //NON-NLS - } + if (shouldEnqueueTask(task)) { + // Direct to file tasks queue, no need to update root directory or + // directory tasks queues. + enqueueFileTask(task); } } - synchronized void removeTasksForIngestJob(long ingestJobId) { - // Remove all tasks for this ingest job that are not in progress. - Iterator fileTasksIterator = fileTasks.iterator(); - while (fileTasksIterator.hasNext()) { - if (fileTasksIterator.next().getIngestJob().getId() == ingestJobId) { - fileTasksIterator.remove(); - } - } - Iterator directoryTasksIterator = directoryTasks.iterator(); - while (directoryTasksIterator.hasNext()) { - if (directoryTasksIterator.next().getIngestJob().getId() == ingestJobId) { - directoryTasksIterator.remove(); - } - } - Iterator rootDirectoryTasksIterator = rootDirectoryTasks.iterator(); - while (rootDirectoryTasksIterator.hasNext()) { - if (rootDirectoryTasksIterator.next().getIngestJob().getId() == ingestJobId) { - rootDirectoryTasksIterator.remove(); - } - } - Iterator dataSourceTasksIterator = dataSourceTasks.iterator(); - while (dataSourceTasksIterator.hasNext()) { - if (dataSourceTasksIterator.next().getIngestJob().getId() == ingestJobId) { - dataSourceTasksIterator.remove(); - } - } + @Override + public IngestTask getNextTask() throws InterruptedException { + FileIngestTask task = fileTasksQueue.take(); + updateTaskQueues(); + return task; } - private synchronized void updateFileTaskQueues() throws InterruptedException { + private synchronized void updateTaskQueues() throws InterruptedException { // we loop because we could have a directory that has all files // that do not get enqueued while (true) { // There are files in the queue, we're done - if (fileTasks.isEmpty() == false) { + if (fileTasksQueue.isEmpty() == false) { return; } // fill in the directory queue if it is empty. - if (this.directoryTasks.isEmpty()) { + if (this.directoryTasksQueue.isEmpty()) { // bail out if root is also empty -- we are done - if (rootDirectoryTasks.isEmpty()) { + if (rootDirectoryTasksQueue.isEmpty()) { return; } - FileIngestTask rootTask = rootDirectoryTasks.pollFirst(); - directoryTasks.add(rootTask); + FileIngestTask rootTask = rootDirectoryTasksQueue.pollFirst(); + directoryTasksQueue.add(rootTask); } //pop and push AbstractFile directory children if any //add the popped and its leaf children onto cur file list - FileIngestTask parentTask = directoryTasks.remove(directoryTasks.size() - 1); + FileIngestTask parentTask = directoryTasksQueue.remove(directoryTasksQueue.size() - 1); final AbstractFile parentFile = parentTask.getFile(); // add itself to the file list - if (shouldEnqueueFileTask(parentTask)) { - try { - fileTasks.put(parentTask); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - logger.log(Level.FINE, "Task scheduling for ingest job interrupted", ex); //NON-NLS - return; - } + if (shouldEnqueueTask(parentTask)) { + enqueueFileTask(parentTask); } // add its children to the file and directory lists try { @@ -188,15 +146,9 @@ final class IngestScheduler { AbstractFile childFile = (AbstractFile) c; FileIngestTask childTask = new FileIngestTask(parentTask.getIngestJob(), childFile); if (childFile.hasChildren()) { - directoryTasks.add(childTask); - } else if (shouldEnqueueFileTask(childTask)) { - try { - fileTasks.put(childTask); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - logger.log(Level.FINE, "Task scheduling for ingest job interrupted", ex); //NON-NLS - return; - } + directoryTasksQueue.add(childTask); + } else if (shouldEnqueueTask(childTask)) { + enqueueFileTask(childTask); } } } @@ -206,7 +158,7 @@ final class IngestScheduler { } } - private static boolean shouldEnqueueFileTask(final FileIngestTask processTask) { + private static boolean shouldEnqueueTask(final FileIngestTask processTask) { final AbstractFile aFile = processTask.getFile(); //if it's unalloc file, skip if so scheduled if (processTask.getIngestJob().shouldProcessUnallocatedSpace() == false && aFile.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) { @@ -251,55 +203,35 @@ final class IngestScheduler { return true; } - IngestTaskQueue getDataSourceIngestTaskQueue() { - return dataSourceTaskDispenser; + private synchronized void enqueueFileTask(FileIngestTask task) throws InterruptedException { + fileTasks.add(task); + try { + // Should not block, queue is (theoretically) unbounded. + fileTasksQueue.put(task); + } catch (InterruptedException ex) { + fileTasks.remove(task); + Logger.getLogger(DataSourceIngestTaskScheduler.class.getName()).log(Level.FINE, "Interruption of unexpected block on tasks queue", ex); //NON-NLS + throw ex; + } } - IngestTaskQueue getFileIngestTaskQueue() { - return fileTaskDispenser; + synchronized void notifyTaskCompleted(FileIngestTask task) { + fileTasks.remove(task); } - synchronized void notifyDataSourceIngestTaskCompleted(DataSourceIngestTask task) { - dataSourceTasksInProgress.remove(task); - } - - synchronized void notifyFileIngestTaskCompleted(FileIngestTask task) { - fileTasksInProgress.remove(task); - } - - synchronized boolean hasDataSourceIngestTaskForIngestJob(IngestJob job) { + synchronized boolean hasIncompleteTasksForIngestJob(IngestJob job) { long jobId = job.getId(); - for (IngestTask task : dataSourceTasksInProgress) { + for (IngestTask task : fileTasks) { if (task.getIngestJob().getId() == jobId) { return true; } } - for (DataSourceIngestTask task : dataSourceTasks) { + for (FileIngestTask task : directoryTasksQueue) { if (task.getIngestJob().getId() == jobId) { return true; } } - return false; - } - - synchronized boolean hasFileIngestTaskForIngestJob(IngestJob job) { - long jobId = job.getId(); - for (IngestTask task : fileTasksInProgress) { - if (task.getIngestJob().getId() == jobId) { - return true; - } - } - for (FileIngestTask task : fileTasks) { - if (task.getIngestJob().getId() == jobId) { - return true; - } - } - for (FileIngestTask task : directoryTasks) { - if (task.getIngestJob().getId() == jobId) { - return true; - } - } - for (FileIngestTask task : rootDirectoryTasks) { + for (FileIngestTask task : rootDirectoryTasksQueue) { if (task.getIngestJob().getId() == jobId) { return true; } @@ -402,29 +334,4 @@ final class IngestScheduler { } } } - - private class DataSourceIngestTaskQueue implements IngestTaskQueue { - - @Override - public IngestTask getNextTask() throws InterruptedException { - DataSourceIngestTask task = dataSourceTasks.take(); - synchronized (this) { - dataSourceTasksInProgress.add(task); - } - return task; - } - } - - private class FileIngestTaskQueue implements IngestTaskQueue { - - @Override - public IngestTask getNextTask() throws InterruptedException { - FileIngestTask task = fileTasks.take(); - synchronized (this) { - fileTasksInProgress.add(task); - } - updateFileTaskQueues(); - return task; - } - } } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJob.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJob.java index 616059a28d..e3d7a9d081 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestJob.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJob.java @@ -37,10 +37,10 @@ final class IngestJob { private static final Logger logger = Logger.getLogger(IngestManager.class.getName()); private static final AtomicLong nextIngestJobId = new AtomicLong(0L); private static final ConcurrentHashMap ingestJobsById = new ConcurrentHashMap<>(); - private static final IngestScheduler taskScheduler = IngestScheduler.getInstance(); + private static final DataSourceIngestTaskScheduler dataSourceTaskScheduler = DataSourceIngestTaskScheduler.getInstance(); + private static final FileIngestTaskScheduler fileTaskScheduler = FileIngestTaskScheduler.getInstance(); private final long id; private final Content dataSource; - private final List ingestModuleTemplates; private final boolean processUnallocatedSpace; private final LinkedBlockingQueue fileIngestPipelines = new LinkedBlockingQueue<>(); private long estimatedFilesToProcess = 0L; // Guarded by this @@ -62,26 +62,24 @@ final class IngestJob { * @throws InterruptedException */ static List startIngestJob(Content dataSource, List ingestModuleTemplates, boolean processUnallocatedSpace) throws InterruptedException { + List errors = new ArrayList<>(); long jobId = nextIngestJobId.incrementAndGet(); - IngestJob job = new IngestJob(jobId, dataSource, ingestModuleTemplates, processUnallocatedSpace); - ingestJobsById.put(jobId, job); - List errors = job.start(); - if (errors.isEmpty()) { - IngestManager.getInstance().fireIngestJobStarted(jobId); - taskScheduler.addTasksForIngestJob(job, dataSource); - } else { - ingestJobsById.remove(jobId); + IngestJob job = new IngestJob(jobId, dataSource, processUnallocatedSpace); + job.createIngestPipelines(ingestModuleTemplates); + if (job.hasNonEmptyPipeline()) { + ingestJobsById.put(jobId, job); + errors = job.start(); + if (errors.isEmpty()) { + IngestManager.getInstance().fireIngestJobStarted(jobId); + } else { + ingestJobsById.remove(jobId); + } } return errors; } static boolean ingestJobsAreRunning() { - for (IngestJob job : ingestJobsById.values()) { - if (!job.isCancelled()) { - return true; - } - } - return false; + return !ingestJobsById.isEmpty(); } static void cancelAllIngestJobs() { @@ -90,10 +88,9 @@ final class IngestJob { } } - IngestJob(long id, Content dataSource, List ingestModuleTemplates, boolean processUnallocatedSpace) { + IngestJob(long id, Content dataSource, boolean processUnallocatedSpace) { this.id = id; this.dataSource = dataSource; - this.ingestModuleTemplates = ingestModuleTemplates; this.processUnallocatedSpace = processUnallocatedSpace; } @@ -105,33 +102,56 @@ final class IngestJob { return processUnallocatedSpace; } + private void createIngestPipelines(List ingestModuleTemplates) throws InterruptedException { + IngestJobContext context = new IngestJobContext(this); + dataSourceIngestPipeline = new DataSourceIngestPipeline(context, ingestModuleTemplates); + int numberOfPipelines = IngestManager.getInstance().getNumberOfFileIngestThreads(); + for (int i = 0; i < numberOfPipelines; ++i) { + fileIngestPipelines.put(new FileIngestPipeline(context, ingestModuleTemplates)); + } + } + + private boolean hasNonEmptyPipeline() { + if (dataSourceIngestPipeline.isEmpty() && fileIngestPipelines.peek().isEmpty()) { + return false; + } + return true; + } + private List start() throws InterruptedException { List errors = startUpIngestPipelines(); if (errors.isEmpty()) { - startFileIngestProgressBar(); - startDataSourceIngestProgressBar(); + if (!dataSourceIngestPipeline.isEmpty()) { + // Start the data source ingest progress bar before scheduling the + // data source task to make sure the progress bar will be available + // as soon as the task begins to be processed. + startDataSourceIngestProgressBar(); + dataSourceTaskScheduler.scheduleTask(this, dataSource); + } + + if (!fileIngestPipelines.peek().isEmpty()) { + // Start the file ingest progress bar before scheduling the file + // ingest tasks to make sure the progress bar will be available + // as soon as the tasks begin to be processed. + startFileIngestProgressBar(); + if (!fileTaskScheduler.tryScheduleTasks(this, dataSource)) { + fileIngestProgress.finish(); + } + } } return errors; } private List startUpIngestPipelines() throws InterruptedException { - IngestJobContext context = new IngestJobContext(this); - - dataSourceIngestPipeline = new DataSourceIngestPipeline(context, ingestModuleTemplates); List errors = new ArrayList<>(); errors.addAll(dataSourceIngestPipeline.startUp()); - - int numberOfPipelines = IngestManager.getInstance().getNumberOfFileIngestThreads(); - for (int i = 0; i < numberOfPipelines; ++i) { - FileIngestPipeline pipeline = new FileIngestPipeline(context, ingestModuleTemplates); + for (FileIngestPipeline pipeline : fileIngestPipelines) { errors.addAll(pipeline.startUp()); - fileIngestPipelines.put(pipeline); if (!errors.isEmpty()) { // No need to accumulate presumably redundant errors. break; } } - logIngestModuleErrors(errors); return errors; } @@ -185,17 +205,12 @@ final class IngestJob { if (!errors.isEmpty()) { logIngestModuleErrors(errors); } - } else { - taskScheduler.removeTasksForIngestJob(id); } - taskScheduler.notifyDataSourceIngestTaskCompleted(task); + dataSourceTaskScheduler.notifyTaskCompleted(task); + dataSourceIngestProgress.finish(); - if (!taskScheduler.hasDataSourceIngestTaskForIngestJob(this)) { - finishProgressBar(dataSourceIngestProgress); - if (!taskScheduler.hasFileIngestTaskForIngestJob(this)) { - finishProgressBar(fileIngestProgress); - finish(); - } + if (!fileTaskScheduler.hasIncompleteTasksForIngestJob(this)) { + finish(); } } @@ -217,39 +232,31 @@ final class IngestJob { if (!errors.isEmpty()) { logIngestModuleErrors(errors); } - } else { - taskScheduler.removeTasksForIngestJob(id); } - taskScheduler.notifyFileIngestTaskCompleted(task); + fileTaskScheduler.notifyTaskCompleted(task); - if (!taskScheduler.hasFileIngestTaskForIngestJob(this)) { - finishProgressBar(fileIngestProgress); - if (!taskScheduler.hasDataSourceIngestTaskForIngestJob(this)) { - finishProgressBar(dataSourceIngestProgress); + if (!fileTaskScheduler.hasIncompleteTasksForIngestJob(this)) { + List errors = new ArrayList<>(); + while (!fileIngestPipelines.isEmpty()) { + FileIngestPipeline pipeline = fileIngestPipelines.poll(); + errors.addAll(pipeline.shutDown()); + } + if (!errors.isEmpty()) { + logIngestModuleErrors(errors); + } + fileIngestProgress.finish(); + if (!dataSourceTaskScheduler.hasIncompleteTasksForIngestJob(this)) { finish(); } } } - private synchronized void finishProgressBar(ProgressHandle progress) { - if (progress != null) { - progress.finish(); - progress = null; - } - } - private void finish() { - List errors = new ArrayList<>(); - while (!fileIngestPipelines.isEmpty()) { - FileIngestPipeline pipeline = fileIngestPipelines.poll(); - errors.addAll(pipeline.shutDown()); - } - if (!errors.isEmpty()) { - logIngestModuleErrors(errors); - } ingestJobsById.remove(id); if (!isCancelled()) { IngestManager.getInstance().fireIngestJobCompleted(id); + } else { + IngestManager.getInstance().fireIngestJobCancelled(id); } } @@ -265,8 +272,5 @@ final class IngestJob { private void cancel() { cancelled = true; - finishProgressBar(dataSourceIngestProgress); - finishProgressBar(fileIngestProgress); - IngestManager.getInstance().fireIngestJobCancelled(id); } } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobContext.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobContext.java index 030a878351..b23077856d 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobContext.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobContext.java @@ -19,6 +19,8 @@ package org.sleuthkit.autopsy.ingest; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.sleuthkit.datamodel.AbstractFile; /** @@ -60,7 +62,15 @@ public final class IngestJobContext { */ public void addFiles(List files) { for (AbstractFile file : files) { - IngestScheduler.getInstance().addFileTaskToIngestJob(ingestJob, file); + try { + FileIngestTaskScheduler.getInstance().scheduleTask(ingestJob, file); + } catch (InterruptedException ex) { + // Ultimately, this method is called by ingest task execution + // threads running ingest module code. Handle the unexpected + // interrupt here rather + Thread.currentThread().interrupt(); + Logger.getLogger(IngestJobContext.class.getName()).log(Level.SEVERE, "File task scheduling unexpectedly interrupted", ex); //NON-NLS + } } } } diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java index 7284b6933f..b1bfa68af4 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -52,7 +52,6 @@ public class IngestManager { private static final IngestManager instance = new IngestManager(); private final PropertyChangeSupport ingestJobEventPublisher = new PropertyChangeSupport(IngestManager.class); private final PropertyChangeSupport ingestModuleEventPublisher = new PropertyChangeSupport(IngestManager.class); - private final IngestScheduler scheduler = IngestScheduler.getInstance(); private final IngestMonitor ingestMonitor = new IngestMonitor(); private final ExecutorService startIngestJobsThreadPool = Executors.newSingleThreadExecutor(); private final ExecutorService dataSourceIngestThreadPool = Executors.newSingleThreadExecutor(); @@ -125,7 +124,7 @@ public class IngestManager { */ private void startDataSourceIngestThread() { long threadId = nextThreadId.incrementAndGet(); - Future handle = dataSourceIngestThreadPool.submit(new ExecuteIngestTasksThread(scheduler.getDataSourceIngestTaskQueue())); + Future handle = dataSourceIngestThreadPool.submit(new ExecuteIngestTasksThread(DataSourceIngestTaskScheduler.getInstance())); dataSourceIngestThreads.put(threadId, handle); } @@ -135,7 +134,7 @@ public class IngestManager { */ private void startFileIngestThread() { long threadId = nextThreadId.incrementAndGet(); - Future handle = fileIngestThreadPool.submit(new ExecuteIngestTasksThread(scheduler.getFileIngestTaskQueue())); + Future handle = fileIngestThreadPool.submit(new ExecuteIngestTasksThread(FileIngestTaskScheduler.getInstance())); fileIngestThreads.put(threadId, handle); } diff --git a/Core/updates_ja.xml b/Core/updates_ja.xml new file mode 100644 index 0000000000..7517fd6abc --- /dev/null +++ b/Core/updates_ja.xml @@ -0,0 +1,16 @@ + + + + + + Autopsy バージョン 3.0.10 は下記からダウンロードできます。http://www.sleuthkit.org/autopsy/. + + + + diff --git a/docs/doxygen/modIngest.dox b/docs/doxygen/modIngest.dox index 347d9c9a5a..fbae2a2a1c 100644 --- a/docs/doxygen/modIngest.dox +++ b/docs/doxygen/modIngest.dox @@ -17,11 +17,11 @@ The difference between these two types of modules is that data-source-level modu - Your module should be a data-source-level ingest module if it only needs to retrieve and analyze a small subset of the files present in a data source and it can find those files based on data in the database (such as file names). For example, a Windows registry analysis module that only processes -registry hive files should be implemented as a data-source-level ingest module because there are only a few registry hives and we can find them by name. +registry hive files should be implemented as a data-source-level ingest module because there are only a few registry hives and you can find them by name. - Your module should be a file-level ingest module if it analyzes most or all of the files from a data source, one file at a time. If you cannot rely on finding a file based on its name, it will need to be a file-level ingest module. For example, a hash look up module might process every file system file by looking up its hash in one or -more known file and known bad files hash sets (hash databases). +more known files and known bad files hash sets (hash databases). As you will learn a little later in this guide, it is possible to package a data-source-level ingest module and a file-level ingest module together. You @@ -39,11 +39,11 @@ ingest modules. \section ingest_modules_lifecycle Ingest Module Life Cycle -Before we dive into the details of creating a module, it is important to understand the life cycle of the module. Note that this life cycle is much different for Autopsy 3.1 modules than it was for Autopsy 3.0. This section only talks about 3.1 modules. +Before we dive into the details of creating a module, it is important to understand the life cycle of the module. Note that this life cycle is much different for Autopsy 3.1 modules compared to Autopsy 3.0 modules. This section only talks about 3.1 modules. You will need to implement at least 2 interfaces to make an ingest module: --# A factory class that will be created when Autopsy starts and will provide configuration panels to Autopsy and create instances of the ingest modules. --# An ingest module class that will be instantiated by the factory when the ingest modules are run. A new instance of this will be created for each thread. +-# A factory class that will be created when Autopsy starts and will provide configuration panels to Autopsy and will create instances of your ingest module. +-# An ingest module class that will be instantiated by the factory when the ingest modules are run. A new instance of this will class be created for each ingest thread. Here is an example sequence of events. Details will be provided below. -# User launches Autopsy and it looks for classes that implement the org.sleuthkit.autopsy.ingest.IngestModuleFactory interface. @@ -52,7 +52,7 @@ Here is an example sequence of events. Details will be provided below. -# Autopsy presents the list of available ingest modules to the user and uses the utility methods from FooIngestModuleFactory class to get the module's name, description, and configuration panels. -# User enables your module (and others). -# Autopsy uses FooIngestModuleFactory to create two instances of FooIngestModule (Autopsy is using two threads to process the files). --# Autopsy starts up the module, calls its process method, and shuts it down when all of the data is analyzed. +-# Autopsy starts up the module and calls its process method. @@ -73,7 +73,7 @@ Our basic factory will use the adapter. -# Create a class either manually or using the NetBeans wizards. Edit the class to extend org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter. NetBeans will likely complain that you have not implemented the necessary methods and you can use its "hints" to automatically generate stubs for them. -# Use the documentation for the org.sleuthkit.autopsy.ingest.IngestModuleFactory interface for details on what each method needs to do. You can also refer to org.sleuthkit.autopsy.examples.SampleIngestModuleFactory as an example. --# Add NetBeans annotations so that the module is found at run time: +-# Add a NetBeans ServiceProvider annotation so that the factory is found at run time: \code @ServiceProvider(service = IngestModuleFactory.class) \endcode @@ -83,7 +83,7 @@ API module to the NetBeans module that contains your ingest module. At this point, you should be able to compile your NetBeans module and run it. When you add a data source, you should see the module in the list of ingest modules. If you don't see it, double check that you extend -correct class and added the service provider annotation. +the correct class and added the service provider annotation. @@ -92,27 +92,18 @@ correct class and added the service provider annotation. Data source and file ingest modules have similar APIs. The main difference is what data gets passed to the methods. Let's first cover the common concepts. -Both modules implement the org.sleuthkit.autopsy.ingest.IngestModule interface, which defines two methods to allocate and free resources: +Both modules implement the org.sleuthkit.autopsy.ingest.IngestModule interface, which defines a module initialization method: - org.sleuthkit.autopsy.ingest.IngestModule.startUp() -- org.sleuthkit.autopsy.ingest.IngestModule.shutDown() -Use the previous links to get the details of each method. The ingest modules will also have to implement a process() -method that will get passed in either a DataSource or a File. - -This section outlines the basic idea of modules and the org.sleuthkit.autopsy.ingest.IngestModule documentation should -be referred to for more details. - -- startUp() will be called before any data is analyzed to initialize and allocate resources, process() will then be called with data to analyze, and then shutDown() will be called to free resources and send ingest messages (see \ref ingest_modules_making_results). -- Any setup procedures that could fail should be done in startUp() so that it can throw an exception and cause the ingest job to stop and notify the user. -- startUp(), process(), and shutDown() will be called from a single thread. So, basic modules do not need to worry about thread safety if they allocate resources for each instance of the module. If the module wants to share resources between instances, then it is responsible for synchronizing the the shared resource. See org.sleuthkit.autopsy.examples.SampleFileIngestModule as an example that shares resources. +Use the previous links to get the details of this method. The ingest modules have to implement a process() +method that will get passed in either a data source or a file. A file ingest module will also have to implement a shutDown() method. +- startUp() will be called before any data is analyzed to initialize and allocate resources. Any setup procedures that could fail should be done in startUp() so that it can throw an exception and cause the ingest job to stop and notify the user. +- shutDown() will be called on file ingest modules after all of the files have been analyzed. +- startUp(), process(), and shutDown() will be called from a single thread. So, basic modules do not need to worry about thread safety if they allocate resources for each instance of the module. However, if the module wants to share resources between instances, then it is responsible for synchronizing the the shared resource. See org.sleuthkit.autopsy.examples.SampleFileIngestModule as an example that shares resources. The org.sleuthkit.autopsy.ingest.DataSourceIngestModule and org.sleuthkit.autopsy.ingest.FileIngestModule interfaces both extend org.sleuthkit.autopsy.ingest.IngestModule. -For your convenience, an ingest module that does not require -initialization and/or clean up may extend the abstract -org.sleuthkit.autopsy.ingest.IngestModuleAdapter class to get default -"do nothing" implementations of these methods. \subsection ingest_modules_implementing_datasourceingestmodule Creating a Data Source Ingest Module @@ -120,8 +111,7 @@ To create a data source ingest module: -# Make a new Java class either manually or using the NetBeans wizards. -# Make the class implement -org.sleuthkit.autopsy.ingest.DataSourceIngestModule and optionally make it -extend org.sleuthkit.autopsy.ingest.IngestModuleAdapter. +org.sleuthkit.autopsy.ingest.DataSourceIngestModule. -# The NetBeans IDE will complain that you have not implemented one or more of the required methods. You can use its "hints" to automatically generate stubs for the missing methods. Use this page and the @@ -137,9 +127,9 @@ org.sleuthkit.autopsy.ingest.DataSourceIngestModule interface: - org.sleuthkit.autopsy.ingest.DataSourceIngestModule.process() The process() method is where all of the work of a data source ingest module is -done. It will be called exactly once between startUp() and shutDown(). The +done. It will be called exactly once. The process() method receives a reference to an org.sleuthkit.datamodel.Content object -and an org.sleuthkit.autopsy.ingest.DataSourceIngestModuleStatusHelper object. +and an org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress object. The former is a representation of the data source. The latter should be used by the module instance to be a good citizen within Autopsy as it does its potentially long-running processing. @@ -171,8 +161,7 @@ To create a file ingest module: -# Make a new Java class either manually or using the NetBeans wizards. -# Make the class implement -org.sleuthkit.autopsy.ingest.FileIngestModule and optionally make it -extend org.sleuthkit.autopsy.ingest.IngestModuleAdapter. +org.sleuthkit.autopsy.ingest.FileIngestModule. -# The NetBeans IDE will complain that you have not implemented one or more of the required methods. You can use its "hints" to automatically generate stubs for the missing methods. Use this page and the @@ -182,10 +171,11 @@ each method needs to do. Or you can copy the code from org.sleuthkit.autopsy.examples.SampleFileIngestModule and use it as a template for your module. -All file ingest modules must implement the single method defined by the +All file ingest modules must implement the two methods defined by the org.sleuthkit.autopsy.ingest.FileIngestModule interface: - org.sleuthkit.autopsy.ingest.FileIngestModule.process() +- org.sleuthkit.autopsy.ingest.FileIngestModule.shutDown() The process() method is where all of the work of a file ingest module is done. It will be called repeatedly between startUp() and shutDown(), once for @@ -385,7 +375,7 @@ IngestModuleAbstract.getName() | IngestModuleFactory.getModuleName() | IngestModuleAbstract.getDescription() | IngestModuleFactory.getModuleDescription() | IngestModuleAbstract.getVersion() | IngestModuleFactory.getModuleVersion() | IngestModuleAbstract.hasBackgroundJobsRunning | N/A | -IngestModuleAbstract.complete() | IngestModule.shutDown() | +IngestModuleAbstract.complete() | IngestModule.shutDown() for file ingest modules; data source ingest modules should do anything they did in complete() at the end of the process() method | IngestModuleAbstract.hasAdvancedConfiguration() | IngestModuleFactory.hasGlobalSettingsPanel() | IngestModuleAbstract.getAdvancedConfiguration() | IngestModuleFactory.getGlobalSettingsPanel() | IngestModuleAbstract.saveAdvancedConfiguration() | IngestModuleGlobalSetttingsPanel.saveSettings() | @@ -402,7 +392,7 @@ N/A | IngestModuleFactory.createFileIngestModule() | Notes: - IngestModuleFactory.getModuleName() should delegate to a static class method that can also be called by ingest module instances. -- Autopsy passes a flag to IngestModule.shutDown() indicating whether the ingest +- The IngestJobContext object passed to startUp() can be queried to determine whether the ingest job completed or was cancelled. - The global settings panel (formerly "advanced") for a module must implement IngestModuleGlobalSettingsPanel which extends JPanel. Global settings are those