diff --git a/App.config b/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Form1.Designer.cs b/Form1.Designer.cs
new file mode 100644
index 0000000..c9db810
--- /dev/null
+++ b/Form1.Designer.cs
@@ -0,0 +1,196 @@
+namespace RockBoxPlaylistEditor
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.button1 = new System.Windows.Forms.Button();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.button2 = new System.Windows.Forms.Button();
+ this.dataGridView1 = new System.Windows.Forms.DataGridView();
+ this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
+ this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
+ this.button3 = new System.Windows.Forms.Button();
+ this.button4 = new System.Windows.Forms.Button();
+ this.button5 = new System.Windows.Forms.Button();
+ this.openFileDialog2 = new System.Windows.Forms.OpenFileDialog();
+ this.button6 = new System.Windows.Forms.Button();
+ this.label1 = new System.Windows.Forms.Label();
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
+ this.SuspendLayout();
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(121, 11);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(75, 23);
+ this.button1.TabIndex = 0;
+ this.button1.Text = "Browse";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // textBox1
+ //
+ this.textBox1.Location = new System.Drawing.Point(202, 11);
+ this.textBox1.Multiline = true;
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(240, 23);
+ this.textBox1.TabIndex = 1;
+ //
+ // button2
+ //
+ this.button2.Location = new System.Drawing.Point(713, 12);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(75, 23);
+ this.button2.TabIndex = 2;
+ this.button2.Text = "Eject";
+ this.button2.UseVisualStyleBackColor = true;
+ this.button2.Click += new System.EventHandler(this.button2_Click);
+ //
+ // dataGridView1
+ //
+ this.dataGridView1.AllowUserToAddRows = false;
+ this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
+ this.dataGridView1.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
+ this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+ this.Column1});
+ this.dataGridView1.Location = new System.Drawing.Point(0, 43);
+ this.dataGridView1.Name = "dataGridView1";
+ this.dataGridView1.Size = new System.Drawing.Size(799, 377);
+ this.dataGridView1.TabIndex = 3;
+ this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
+ //
+ // Column1
+ //
+ this.Column1.HeaderText = "Path";
+ this.Column1.Name = "Column1";
+ //
+ // openFileDialog1
+ //
+ this.openFileDialog1.FileName = "openFileDialog1";
+ //
+ // button3
+ //
+ this.button3.Location = new System.Drawing.Point(634, 426);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(75, 23);
+ this.button3.TabIndex = 4;
+ this.button3.Text = "Apply ";
+ this.button3.UseVisualStyleBackColor = true;
+ this.button3.Click += new System.EventHandler(this.button3_Click);
+ //
+ // button4
+ //
+ this.button4.Location = new System.Drawing.Point(715, 426);
+ this.button4.Name = "button4";
+ this.button4.Size = new System.Drawing.Size(75, 23);
+ this.button4.TabIndex = 5;
+ this.button4.Text = "Quit";
+ this.button4.UseVisualStyleBackColor = true;
+ this.button4.Click += new System.EventHandler(this.button4_Click);
+ //
+ // button5
+ //
+ this.button5.Location = new System.Drawing.Point(13, 425);
+ this.button5.Name = "button5";
+ this.button5.Size = new System.Drawing.Size(50, 23);
+ this.button5.TabIndex = 6;
+ this.button5.Text = "Add";
+ this.button5.UseVisualStyleBackColor = true;
+ this.button5.Click += new System.EventHandler(this.button5_Click);
+ //
+ // openFileDialog2
+ //
+ this.openFileDialog2.FileName = "openFileDialog1";
+ //
+ // button6
+ //
+ this.button6.Location = new System.Drawing.Point(69, 425);
+ this.button6.Name = "button6";
+ this.button6.Size = new System.Drawing.Size(63, 23);
+ this.button6.TabIndex = 7;
+ this.button6.Text = "Remove";
+ this.button6.UseVisualStyleBackColor = true;
+ this.button6.Click += new System.EventHandler(this.button6_Click);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(10, 16);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(105, 13);
+ this.label1.TabIndex = 8;
+ this.label1.Text = "Select your m3u8 file";
+ this.label1.Click += new System.EventHandler(this.label1_Click);
+ //
+ // Form1
+ //
+ this.AllowDrop = true;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(800, 454);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.button6);
+ this.Controls.Add(this.button5);
+ this.Controls.Add(this.button4);
+ this.Controls.Add(this.button3);
+ this.Controls.Add(this.dataGridView1);
+ this.Controls.Add(this.button2);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.button1);
+ this.Name = "Form1";
+ this.ShowIcon = false;
+ this.Text = "Rockbox Playlist Manager";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
+ this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form1_DragDrop);
+ this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form1_DragEnter);
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.DataGridView dataGridView1;
+ private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
+ private System.Windows.Forms.OpenFileDialog openFileDialog1;
+ private System.Windows.Forms.Button button3;
+ private System.Windows.Forms.Button button4;
+ private System.Windows.Forms.Button button5;
+ private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
+ private System.Windows.Forms.OpenFileDialog openFileDialog2;
+ private System.Windows.Forms.Button button6;
+ private System.Windows.Forms.Label label1;
+ }
+}
+
diff --git a/Form1.cs b/Form1.cs
new file mode 100644
index 0000000..d8bde4a
--- /dev/null
+++ b/Form1.cs
@@ -0,0 +1,303 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace RockBoxPlaylistEditor
+{
+
+ public partial class Form1 : Form
+ {
+
+ string path;
+ string path2;
+
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ private static extern IntPtr CreateFile(
+ string lpFileName,
+ uint dwDesiredAccess,
+ uint dwShareMode,
+ IntPtr SecurityAttributes,
+ uint dwCreationDisposition,
+ uint dwFlagsAndAttributes,
+ IntPtr hTemplateFile
+);
+
+ [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
+ private static extern bool DeviceIoControl(
+ IntPtr hDevice,
+ uint dwIoControlCode,
+ IntPtr lpInBuffer,
+ uint nInBufferSize,
+ IntPtr lpOutBuffer,
+ uint nOutBufferSize,
+ out uint lpBytesReturned,
+ IntPtr lpOverlapped
+ );
+
+ [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
+ private static extern bool DeviceIoControl(
+ IntPtr hDevice,
+ uint dwIoControlCode,
+ byte[] lpInBuffer,
+ uint nInBufferSize,
+ IntPtr lpOutBuffer,
+ uint nOutBufferSize,
+ out uint lpBytesReturned,
+ IntPtr lpOverlapped
+ );
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool CloseHandle(IntPtr hObject);
+
+ private IntPtr handle = IntPtr.Zero;
+
+ const uint GENERIC_READ = 0x80000000;
+ const uint GENERIC_WRITE = 0x40000000;
+ const int FILE_SHARE_READ = 0x1;
+ const int FILE_SHARE_WRITE = 0x2;
+ const int FSCTL_LOCK_VOLUME = 0x00090018;
+ const int FSCTL_DISMOUNT_VOLUME = 0x00090020;
+ const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
+ const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804;
+
+ ///
+ /// Constructor for the USBEject class
+ ///
+ /// This should be the drive letter. Format: F:/, C:/..
+
+ public IntPtr USBEject(string driveLetter)
+ {
+ string filename = @"\\.\" + driveLetter[0] + ":";
+ return CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero);
+ }
+
+ public bool Eject(IntPtr handle)
+ {
+ bool result = false;
+
+ if (LockVolume(handle) && DismountVolume(handle))
+ {
+ PreventRemovalOfVolume(handle, false);
+ result = AutoEjectVolume(handle);
+ }
+ CloseHandle(handle);
+ return result;
+ }
+
+ private bool LockVolume(IntPtr handle)
+ {
+ uint byteReturned;
+
+ for (int i = 0; i < 10; i++)
+ {
+ if (DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero))
+ {
+ System.Windows.Forms.MessageBox.Show("Eject completed!");
+ return true;
+ }
+ Thread.Sleep(500);
+ }
+ return false;
+ }
+
+ private bool PreventRemovalOfVolume(IntPtr handle, bool prevent)
+ {
+ byte[] buf = new byte[1];
+ uint retVal;
+
+ buf[0] = (prevent) ? (byte)1 : (byte)0;
+ return DeviceIoControl(handle, IOCTL_STORAGE_MEDIA_REMOVAL, buf, 1, IntPtr.Zero, 0, out retVal, IntPtr.Zero);
+ }
+
+ private bool DismountVolume(IntPtr handle)
+ {
+ uint byteReturned;
+ return DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
+ }
+
+ private bool AutoEjectVolume(IntPtr handle)
+ {
+ uint byteReturned;
+ return DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
+ }
+
+ private bool CloseVolume(IntPtr handle)
+ {
+ return CloseHandle(handle);
+ }
+
+
+ private void Form1_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ if (MessageBox.Show("Are you sure to exit?", "Confirmation", MessageBoxButtons.YesNo) == DialogResult.Yes)
+ {
+ //Environment.Exit(0);
+ e.Cancel = false;
+ }
+ else
+ {
+ // your Code for Changes or anything you want to allow user changes etc.
+ e.Cancel = true;
+ }
+ }
+
+ private void Form1_DragEnter(object sender, DragEventArgs e)
+ {
+ if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
+ }
+
+ private void Form1_DragDrop(object sender, DragEventArgs e)
+ {
+ string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
+ foreach (string file in files)
+ {
+ string meow = string.Join(string.Empty, file.Skip(2)).Replace("\\", "/");
+ this.dataGridView1.Rows.Add(meow);
+ }
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ OpenFileDialog dialog = new OpenFileDialog();
+ dialog.Filter = "playlist files (*.m3u8)|*.m3u8";
+ dialog.Title = "Load m3u8 playlist";
+
+ if (dialog.ShowDialog() == DialogResult.OK)
+ {
+ this.dataGridView1.Rows.Clear();
+
+
+ textBox1.Text = dialog.FileName;
+
+ path2 = dialog.FileName;
+
+ var fileStream = dialog.OpenFile();
+
+
+
+ using (StreamReader reader = new StreamReader(fileStream))
+ {
+ path = reader.ReadToEnd();
+ Console.WriteLine(path);
+
+ using (StringReader reader2 = new StringReader(path))
+ {
+ string line;
+ while ((line = reader2.ReadLine()) != null)
+ {
+ this.dataGridView1.Rows.Add(line);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ private void button2_Click(object sender, EventArgs e)
+ {
+ Eject(USBEject(textBox1.Text.Substring(0, 2)));
+ }
+
+ private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
+ {
+
+ }
+
+ private void button5_Click(object sender, EventArgs e)
+ {
+ OpenFileDialog dialog2 = new OpenFileDialog();
+ dialog2.Filter = "All files (*.*)|*.*";
+ dialog2.Title = "Load songs for playlist";
+ dialog2.Multiselect = true;
+
+ if (dialog2.ShowDialog() == DialogResult.OK)
+ {
+ var fileStream = dialog2.OpenFile();
+
+ string[] allFiles = dialog2.FileNames;
+
+ foreach (string file in allFiles)
+ {
+ string meow = string.Join(string.Empty, file.Skip(2)).Replace("\\", "/");
+ this.dataGridView1.Rows.Add(meow);
+ }
+ }
+ }
+
+ private void button3_Click(object sender, EventArgs e)
+ {
+
+ Console.WriteLine(this.dataGridView1.Rows.Count);
+
+ try
+ {
+ using (TextWriter tw = new StreamWriter(path2))
+ {
+ for (int i = 0; i < this.dataGridView1.Rows.Count; i++)
+ {
+ tw.WriteLine($"{dataGridView1.Rows[i].Cells[0].Value.ToString()}");
+ }
+ }
+
+ MessageBox.Show("Done!", "Data written successfully", MessageBoxButtons.OK, MessageBoxIcon.Information);
+
+ } catch (Exception asdf) {
+ MessageBox.Show(asdf.Message, "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ private void button4_Click(object sender, EventArgs e)
+ {
+ Application.Exit();
+ }
+
+ private void button6_Click(object sender, EventArgs e)
+ {
+ DeleteSelectedRows();
+ }
+
+ private void DeleteSelectedRows()
+ {
+ HashSet rowsToDelete = new HashSet();
+
+ // Collect all row indices that contain selected cells
+ foreach (DataGridViewCell selectedCell in dataGridView1.SelectedCells)
+ {
+ if (selectedCell.Selected)
+ {
+ rowsToDelete.Add(selectedCell.RowIndex);
+ }
+ }
+
+ // Remove rows starting from the highest index to avoid index shifting issues
+ List sortedRows = new List(rowsToDelete);
+ sortedRows.Sort((a, b) => b.CompareTo(a)); // Sort in descending order
+
+ foreach (int rowIndex in sortedRows)
+ {
+ dataGridView1.Rows.RemoveAt(rowIndex);
+ }
+ }
+
+ private void label1_Click(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/Form1.resx b/Form1.resx
new file mode 100644
index 0000000..737f308
--- /dev/null
+++ b/Form1.resx
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+ True
+
+
+ 33, 18
+
+
+ 200, 18
+
+
+ 339, 18
+
+
\ No newline at end of file
diff --git a/Program.cs b/Program.cs
new file mode 100644
index 0000000..26cd239
--- /dev/null
+++ b/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace RockBoxPlaylistEditor
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..bd27c95
--- /dev/null
+++ b/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RockBoxPlaylistEditor")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RockBoxPlaylistEditor")]
+[assembly: AssemblyCopyright("Copyright © 2024")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("cf66f8e5-ef01-46f0-b068-a647a26d2349")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..75fba94
--- /dev/null
+++ b/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace RockBoxPlaylistEditor.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RockBoxPlaylistEditor.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Properties/Resources.resx b/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..1961dc2
--- /dev/null
+++ b/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace RockBoxPlaylistEditor.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Properties/Settings.settings b/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/RockBoxPlaylistEditor.csproj b/RockBoxPlaylistEditor.csproj
new file mode 100644
index 0000000..27cb50d
--- /dev/null
+++ b/RockBoxPlaylistEditor.csproj
@@ -0,0 +1,103 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}
+ WinExe
+ RockBoxPlaylistEditor
+ RockBoxPlaylistEditor
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ true
+ bin\ARM64\Debug\
+ DEBUG;TRACE
+ full
+ ARM64
+ 7.3
+ prompt
+ true
+
+
+ bin\ARM64\Release\
+ TRACE
+ true
+ pdbonly
+ ARM64
+ 7.3
+ prompt
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RockBoxPlaylistEditor.sln b/RockBoxPlaylistEditor.sln
new file mode 100644
index 0000000..3ee02ce
--- /dev/null
+++ b/RockBoxPlaylistEditor.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34902.65
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RockBoxPlaylistEditor", "RockBoxPlaylistEditor.csproj", "{CF66F8E5-EF01-46F0-B068-A647A26D2349}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM64 = Debug|ARM64
+ Release|Any CPU = Release|Any CPU
+ Release|ARM64 = Release|ARM64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Debug|ARM64.Build.0 = Debug|ARM64
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {CF66F8E5-EF01-46F0-B068-A647A26D2349}.Release|ARM64.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {9A25F34D-29C7-43F9-AD27-B2B1C1988CA4}
+ EndGlobalSection
+EndGlobal