Example #1
0
        public TimingsEditor(MainWindow parent, SharedDisposable <RegistryKey> monitorKey, bool isCopy, string encodedMonitor, byte[] encodedGlasses)
        {
            InitializeComponent();
            listWaveforms.DataSource = defaultGlassesCmds;

            this.parent       = parent;
            this.monitorKey   = monitorKey;
            this.previousName = isCopy ? null : encodedMonitor;

            if (encodedMonitor != null)
            {
                this.textDisplayTimings.Text = encodedMonitor;
            }
            if (encodedGlasses != null)
            {
                this.textGlassesTimings.Text = StructureExtensions.ByteArrayToString(encodedGlasses);
            }

            if (encodedMonitor != null)
            {
                btnDecode_Click(btnDecodeDisplayTimings, null);
            }
            if (encodedGlasses != null)
            {
                btnDecode_Click(btnDecodeGlassesTimings, null);
            }

            UpdateListBoxButtons();
            UpdateSliderParams();
        }
Example #2
0
 private void btnDecode_Click(object sender, EventArgs e)
 {
     if (sender == btnDecodeDisplayTimings)
     {
         try
         {
             var timings = MonitorTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(textDisplayTimings.Text));
             ApplyMonitorTimings(timings);
         }
         catch (Exception ex)
         {
             MessageBox.Show(ex.Message, "Error parsing encoded display timings");
             return;
         }
     }
     else if (sender == btnDecodeGlassesTimings)
     {
         try
         {
             var timings = GlassesTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(textGlassesTimings.Text));
             ApplyGlassesTimings(timings);
         }
         catch (Exception ex)
         {
             MessageBox.Show(ex.Message, "Error parsing encoded glasses timings");
             return;
         }
     }
 }
Example #3
0
 private void btnEncode_Click(object sender, EventArgs e)
 {
     if (sender == btnEncodeDisplayTimings)
     {
         var timings = GetMonitorTimings();
         textDisplayTimings.Text = StructureExtensions.ByteArrayToString(timings.ToByteArray());
     }
     else if (sender == btnEncodeGlassesTimings)
     {
         var timings = GetGlassesTimings();
         textGlassesTimings.Text = StructureExtensions.ByteArrayToString(timings.ToByteArray());
     }
 }
Example #4
0
        public static GlassesTimings CreateFromByteArray(byte[] bytes)
        {
            var timingsStr     = new GlassesTimings();
            var requiredLength = Marshal.SizeOf(timingsStr);

            if (bytes.Length != requiredLength)
            {
                throw new ArgumentException(String.Format("Encoded glasses timing parameters must be {0} bytes long: {1}",
                                                          requiredLength, StructureExtensions.ByteArrayToString(bytes)));
            }

            timingsStr = StructureExtensions.ToStructure <GlassesTimings>(bytes);
            return(timingsStr);
        }
Example #5
0
        public override string ToString()
        {
            try
            {
                var timings   = MonitorTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(encodedName));
                var frequency = (decimal)(timings.frequency) / 100;
                var refresh   = (frequency * 1000000) / (timings.hor.total * timings.ver.total);
                refresh = Math.Round(refresh * 1000) / 1000;

                return(String.Format("{0}x{1} ({2}x{3}) @ {4}Hz ({5}MHz)", timings.hor.visible, timings.ver.visible,
                                     timings.hor.total, timings.ver.total,
                                     refresh, frequency));
            }
            catch (Exception)
            {
                return("ERROR:" + encodedName);
            }
        }
Example #6
0
        private bool ApplyChangesAndNotify()
        {
            try
            {
                var monitorTimings = StructureExtensions.ByteArrayToString(GetMonitorTimings().ToByteArray());
                var glassesTimings = GetGlassesTimings().ToByteArray();

                if (previousName == null || !previousName.Equals(monitorTimings, StringComparison.OrdinalIgnoreCase))
                {
                    if (monitorKey.Value.GetValue(monitorTimings) != null)
                    {
                        var dlgRes = MessageBox.Show("This monitor timing already exists. Do you wish to overwrite it?",
                                                     "Overwrite monitor timing?", MessageBoxButtons.YesNo);
                        if (dlgRes != DialogResult.Yes)
                        {
                            return(false);
                        }
                    }
                }

                monitorKey.Value.SetValue(monitorTimings, glassesTimings, RegistryValueKind.Binary);
                if (previousName != null && !previousName.Equals(monitorTimings, StringComparison.OrdinalIgnoreCase))
                {
                    monitorKey.Value.DeleteValue(previousName, false);
                }

                parent.TimingChangedCallback(previousName, monitorTimings);
                previousName = monitorTimings;
                return(true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error writing new values to registry");
                return(false);
            }
        }
Example #7
0
 public byte[] ToByteArray()
 {
     return(StructureExtensions.ToByteArray(this));
 }
Example #8
0
        private void btnPatchNvStRes_Click(object sender, EventArgs e)
        {
            if (monitorSubKey == null)
            {
                return;
            }

            var currMonitorName = monitorSubKey.Value.Name.Split('\\').Last().Trim();

            byte[] monitorIdentBytes = MonitorNameToEdidIdentifier(currMonitorName);
            if (monitorIdentBytes == null)
            {
                MessageBox.Show("Monitor name must be in the format ABC_HHHH where ABC are letters and HHHH is a hex-encoded uint16", "Invalid monitor name");
                return;
            }

            MonitorTimings[] monTimings = null;
            int actualLen  = 0;
            int invalidLen = 0;

            try
            {
                var valueNames = monitorSubKey.Value.GetValueNames();
                monTimings = new MonitorTimings[valueNames.Length];
                foreach (var monVal in valueNames)
                {
                    try
                    {
                        monTimings[actualLen++] = MonitorTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(monVal));
                    }
                    catch (Exception)
                    {
                        invalidLen++;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error reading monitor key values");
                return;
            }

            if (monTimings == null)
            {
                return;
            }
            else if (actualLen > 6)
            {
                MessageBox.Show("nvstres.dll supports a maximum of 6 timings per monitor", "Too many monitor timings");
                return;
            }

            if (invalidLen > 0)
            {
                var res = MessageBox.Show(actualLen.ToString() + " invalid monitor timings will be skipped. Continue?", "Invalid timings found", MessageBoxButtons.YesNo);
                if (res != DialogResult.Yes)
                {
                    return;
                }
            }

            byte[]       resData       = null;
            const ushort RESOURCE_NAME = 8;
            const ushort RESOURCE_TYPE = 10;
            const ushort RESOURCE_LANG = 0;

            int numFilesPatched = 0;

            string[] defaultFilenames = { "nvstres", "nvstres64" };
            foreach (string defaultFilename in defaultFilenames)
            {
                string theFileName = null;
                using (var dlg = new OpenFileDialog())
                {
                    dlg.FileName         = defaultFilename;
                    dlg.DefaultExt       = ".dll";
                    dlg.Filter           = "DLL files (.dll)|*.dll";
                    dlg.InitialDirectory = GetNvidia3DVisionFolder();
                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        theFileName = dlg.FileName;
                    }
                }

                if (theFileName == null)
                {
                    return;
                }

                if (resData == null)
                {
                    try
                    {
                        resData = ResourceManager.GetResourceFromExecutable(theFileName, (IntPtr)RESOURCE_NAME, (IntPtr)RESOURCE_TYPE);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Error reading resource");
                        continue;
                    }

                    if (resData == null)
                    {
                        MessageBox.Show("No timings resource in " + theFileName, "Error finding resource");
                        continue;
                    }

                    var currTimings = new ResourceMonitorTimings();
                    var oneSize     = Marshal.SizeOf(currTimings);
                    var numEntries  = resData.Length / oneSize;
                    if (oneSize * numEntries != resData.Length)
                    {
                        MessageBox.Show(String.Format("Timings resource has uneven length of {0} expected {1}", resData.Length, oneSize * numEntries), "Error parsing resource");
                        continue;
                    }

                    int foundIdx     = -1;
                    int firstFreeIdx = -1;
                    var allTimings   = new ResourceMonitorTimings[numEntries];
                    for (int i = 0; i < numEntries; i++)
                    {
                        var entryData = resData.Skip(i * oneSize).Take(oneSize).ToArray();
                        allTimings[i] = entryData.ToStructure <ResourceMonitorTimings>();
                        if (currMonitorName.Equals(allTimings[i].GetMonitorName(), StringComparison.OrdinalIgnoreCase))
                        {
                            foundIdx = i;
                        }
                        else if (firstFreeIdx < 0 && allTimings[i].IsEmpty())
                        {
                            firstFreeIdx = i;
                        }
                    }

                    if (foundIdx < 0 && firstFreeIdx < 0)
                    {
                        MessageBox.Show(String.Format("Timings for monitor {0} not found and the resource is full!", currMonitorName), "Cannot add to resource");
                        continue;
                    }

                    var existingTimings = allTimings.ElementAtOrDefault(foundIdx);
                    var newTimings      = new ResourceMonitorTimings();
                    newTimings.timings   = new ResourceTiming[actualLen];
                    newTimings.vendorId  = BitConverter.ToUInt16(monitorIdentBytes, 0);
                    newTimings.productId = BitConverter.ToUInt16(monitorIdentBytes, 2);
                    for (int i = 0; i < actualLen; i++)
                    {
                        newTimings.timings[i] = ResourceTiming.FromMonitorTimings(monTimings[i]);
                        if (existingTimings.timings != null)
                        {
                            newTimings.timings[i].horFlags = existingTimings.timings[0].horFlags;
                            newTimings.timings[i].verFlags = existingTimings.timings[0].verFlags;
                        }
                    }
                    Array.Sort(newTimings.timings, 0, actualLen, new FunctionalComparer <ResourceTiming>(
                                   (x, y) => (x.refreshRateHz == y.refreshRateHz) ? (x.freq10sKhz.CompareTo(y.freq10sKhz)) : (x.refreshRateHz.CompareTo(y.refreshRateHz))
                                   ));

                    using (var dlg = new TimingReview(currMonitorName, existingTimings.timings, newTimings.timings))
                    {
                        var dlgRes = dlg.ShowDialog();
                        if (dlgRes != DialogResult.OK)
                        {
                            return;
                        }

                        newTimings.timings = dlg.GetNewTimings();
                        Array.Resize(ref newTimings.timings, 6);
                    }

                    int copyIdx = (foundIdx < 0) ? firstFreeIdx : foundIdx;
                    Array.Copy(StructureExtensions.ToByteArray(newTimings), 0, resData, oneSize * copyIdx, oneSize);
                }

                IntPtr resHandle    = IntPtr.Zero;
                bool   resUpdatedOk = false;
                try
                {
                    resHandle    = ResourceManager.BeginUpdateResource(theFileName, false);
                    resUpdatedOk = ResourceManager.UpdateResourceWithBytes(resHandle, (IntPtr)RESOURCE_TYPE, (IntPtr)RESOURCE_NAME, RESOURCE_LANG, resData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error updating resource");
                    continue;
                }
                finally
                {
                    if (resHandle != IntPtr.Zero)
                    {
                        var resFinishedOk = ResourceManager.EndUpdateResource(resHandle, !resUpdatedOk);
                        if (resUpdatedOk)
                        {
                            resUpdatedOk = resFinishedOk;
                        }
                    }
                }
                if (resUpdatedOk == false)
                {
                    MessageBox.Show("Error updating resource in " + theFileName, "Error updating resource");
                    continue;
                }
                else
                {
                    MessageBox.Show("Applied changes to " + theFileName, "Finished updating resource");
                    numFilesPatched++;
                }
            }

            if (numFilesPatched > 0)
            {
                MessageBox.Show(numFilesPatched.ToString() + " files have been patched.\nYou will likely need to REBOOT for any changes to take effect", "Done with patching");
            }
        }
Example #9
0
        static byte[] MonitorNameToEdidIdentifier(string monitorName)
        {
            UInt16 monitorVendorShort  = 0;
            UInt16 monitorProductShort = 0;

            char[] nameSplitChars = { '_' };
            var    nameParts      = monitorName.Split(nameSplitChars);

            if (nameParts.Length != 2)
            {
                return(null);
            }
            else
            {
                var vendorStr  = nameParts[0];
                var productStr = nameParts[1];
                if (vendorStr.Length != 3 || productStr.Length != 4)
                {
                    return(null);
                }

                int vendorInt = 0;
                foreach (var c in vendorStr)
                {
                    if (!char.IsLetter(c))
                    {
                        return(null);
                    }

                    vendorInt  |= char.ToUpper(c) - '@';
                    vendorInt <<= 5;
                }
                foreach (var c in productStr)
                {
                    if (char.IsDigit(c) || (c >= 'A' && c <= 'F'))
                    {
                        continue;
                    }
                    else
                    {
                        return(null);
                    }
                }

                vendorInt        >>= 5;
                monitorVendorShort = (UInt16)((vendorInt & 0x00FFU) << 8 | (vendorInt & 0xFF00U) >> 8);

                try
                {
                    monitorProductShort = BitConverter.ToUInt16(StructureExtensions.StringToByteArrayFastest(productStr), 0);
                    monitorProductShort = (UInt16)((monitorProductShort & 0x00FFU) << 8 | (monitorProductShort & 0xFF00U) >> 8);
                }
                catch (Exception)
                {
                    return(null);
                }
            }

            byte[] outputArr = new byte[sizeof(UInt16) + sizeof(UInt16)];
            Array.Copy(BitConverter.GetBytes(monitorVendorShort), 0, outputArr, 0, sizeof(UInt16));
            Array.Copy(BitConverter.GetBytes(monitorProductShort), 0, outputArr, sizeof(UInt16), sizeof(UInt16));

            return(outputArr);
        }