Friday, April 28, 2023

Multiple RDP Connections to Windows 10 or 11 machine

 Best way to make your Windows 10 accept multiple RDP connections or, in my case, allow a local and a remote session simultaneously:

http://www.federa.lt/multiple-rdp-sessions-in-windows-10/

I opted by doing the patch of termsvr.dll. Just one note about it:

Just look for this sequence of bytes 39 81 3C 06 00 00 and replace the following with the sequence B8 00 01 00 00 89 81 38 06 00 00 90 regardless of the Windows build  number and everything will just work.


Saturday, January 7, 2023

SystemBuilder da Squadra II - A missão (final)

Há mais de 15 anos, publiquei um post sobre o SystemBuilder da Squadra, aqui:

https://alexandrecmachado.blogspot.com/2007/11/systembuilder-da-squadra.html

Pessoalmente nunca usei o SystemBuilder e hoje, mais do que nunca, acho que foi uma péssima idéia quem usou. O SystemBuilder facilitou o desenvolvimento às custas de introduzir muitas coisas erradas no código e no sistema.

Bem, isto não vem ao caso aqui. 

Este post serve somente para ensinar como ficar livre da proteção que a Squadra colocou no SystemBuilder, coisa que qualquer um pode fazer seguindo alguns passos simples.

Por que estou fazendo isso? Bem, sou completamente a favor de se cobrar por um produto e serviço, e incluir proteção no software, para evitar pirataria. 

Mas sou contra a empresa simplesmente terminar com o suporte ao produto e deixar os usuários órfãos sem ter como continuar com o sistema. A Squadra não suporta mais o SystemBuilder e deveria ter liberado o código fonte do framework para que os usuários fizessem bom uso dele. Não o fez sabe-se lá porquê. Talvez ainda tenha algum usuário que ligue para lá desesperado e pague algumas centenas de reais para ter um novo serial key? Não faço idéia. Mas se é por causa disso, é uma estupidez sem tamanho.

Então vamos ao que interessa. Como eu disse no post anterior, a proteção contra execução não autorizada do SystemBuilder é coisa bem precária, com certeza feito por quem não entende de segurança de software.

Atenção: Este hack se aplica do SystemBuilder 3.2 (última versão lançada) para o Delphi 7 somente.

A primeira coisa é instalar um heditor hexadecimal, caso não tenha. Eu uso e aconselho o HxD. Baixe ele aqui:

https://mh-nexus.de/en/hxd/

Após instalado, procure no seu sistema onde o SystemBuilder está instalado pelo arquivo SqUtil.dcu.

Rode o HxD e abra o arquivo SqUtil.dcu. Você vai ver algo como isso:


Agora, vá ao menu Search (Procurar), selecione a aba Hex-values e cole esta sequência de caracteres lá:

55 8B EC B9

Veja a figura abaixo


O HxD vai encontra a sequência e marcá-la, como mostrado abaixo:


Agora vem o passo final. Coloque o cursor onde está 55 acima e edite o código diretamente. Substitua 55 8B EC por B0 01 C3


Após editado, vá no menu File e selecione Save, salvando as alterações. O HxD, se não me falha a memória, irá criar uma cópia do arquivo original e irá salvar o novo arquivo (alterado) com o mesmo nome.

Pronto. Você agora tem um SqUtil.dcu que contém código que irá sempre validar a instalação do SystemBuilder. Basta dar um build na aplicação e ela irá funcionar normalmente. Nunca mais a proteção do SystemBuilder irá se intrometer no seu caminho. 😀😀😀

Um detalhe: Como somente o DCU foi alterado, isto não muda o comportamento dos pacotes (packages) que são instalados no IDE do Delphi 7. 

Duas coisas que eu garanto aqui:

- Não existe nenhum código malicioso aí, e nem seria possível fazer algo assim com uma alteração de tão poucos bytes.

- Esta alteração não muda nada no funcionamento do SystemBuilder. Ela simplesmente faz um bypass na validação de proteção.

Em uma outra oportunidade eu irei explicar o que foi feito acima e porque uma alteração tão simples funciona tão bem.

Até a próxima! 










Tuesday, June 12, 2018

Erik Meijer on Agile

That's exactly what I think about Agile


Not that I think everything about Agile is bad. But the bad parts took over and what's left is not much better than nothing. Probably worse.

Friday, June 8, 2018

Delphi fix up mechanism


There are a few methods and functions in Classes.pas unit which take care of something that I call "fix up mechanism". Just search for "fixup" inside Classes.pas and you will find them. The fix up mechanism exists to "fix" (really?) references to other components which are owned by a different container, when they are created at runtime, loaded from a DFM resource.

So, let's say you have a ADOQuery1 contained in DataModule1. Then you have Form1 which contains DataSource1 which in turn references ADOQuery1 through DataSet property. This relationship could be set at runtime as:

Form1.DataSource1.DataSet := DataModule1.ADOQuery1;

However, most Delphi developers choose to set this relationship at design time, using Object Inspector. This has some advantages - it requires zero code - but also its disadvantages - it requires that some mechanism "fixes" this reference at runtime. So, when you create Form1 at runtime, it also creates/loads DataSource1. Inside the DFM file you will find that DataSource1.DataSet contains a reference to DataModule1.ADOQuery1 - referenced by name. But when the form loads from DFM, the Delphi runtime library doesn't know how to set this property. The form (a DFM resource at this stage) only contains a string (DataModule1.ADOQuery1) but RTL needs to find the actual object and set the reference accordingly. That's the fix up mechanism mission.

Most Delphi developers never worried about this (they probably don't even know about it) because (a) it works transparently and very well and (b) it doesn't have any effect on performance of most applications. When I say "most" I mean, desktop applications. It definitely may have some - important - influence on multi-threaded applications created with Delphi because it uses a global lock, implemented as a TMultiReaderExclusiveWriterSynchronizer. If your application contains, for instance, TDataModules loading from DFM resources this effect can be serious.

Let's say you have some server application (it might be a DataSnap server, COM+, WebBroker, whatever) which loads DataModules from DFM files. For example, WebModules *are* DataModules. If all objects contained in that DataModule reference other objects contained in the same DataModule, you are also safe. However, if one component references another component in another DataModule, the fix up mechanism will need to do its job and the nasty global lock will occur. 

If your application receives several requests at the same time and 2 or more requests require the creation of one instance of such DataModule, the first one will acquire the global lock and the second will have to wait until the fix up finishes (and unlocks the global list), so it can proceed and lock the fix up list again. There is another - more complicated - scenario where this global lock might create some deadlock situation if you also have other global locks (e.g. Critical Sections) being used at the same time.

So, my first recommendation is "never link objects owned by different containers at design time in a multi-threaded application". If you link them via code it will perform better and also save you from a possible deadlock which - believe me - is very very hard to find and almost impossible to reproduce in a controlled environment. As a bonus you will never have that nasty surprise when you find out - in production, of course - that your DataSource1 is not pointing to DataSet1 anymore because, God knows how, the DataSet property is blank (who never experienced that?)...
Link objects via code!! OnCreate event of Forms and DataModules are good places to put that linkage code.

Sometimes I know that it is hard to change the whole application. Your application is ready, tested and you don't want to risk such a core change now. That's fine. If your application is an IntraWeb application you can turn on our - still experimental - new feature which replaces the global fix up mechanism completely, with a new, much more scalable and thread-friendly one. To turn it on you should set TIWServerControllerBase.FixupPatchEnabled* to true, before starting your application. The best place to do it is in your .DPR file. Example:

begin
  TIWServerControllerBase.FixupPatchEnabled := True;
  TIWStart.Execute(True);
end.

That should do it. Have in mind that it might need some adjustments in your application but, in general, it should work in most cases.

Available in IntraWeb 15 only.




Thursday, June 7, 2018

Back to business

After a long long period of inactivity, I'm back to business. I'll publish some new stuff here, probably some IntraWeb related material as well.

Actually I have plans to create a brand new IntraWeb application to host some documentation about IntraWeb itself. It will contain new stuff and I intend to make a *really nice* IntraWeb application to handle it.


Wednesday, March 1, 2017

Delphi...


Back in 2013, Marco Cantu wrote this blog post:

http://blog.marcocantu.com/blog/strings_immutability_cow_ansistrings.html

Simon Kissel, a very active and respected member of the old Delphi community posted a comment which I find very relevant and I want to emphasize here. If you are interested in Simon's Delphi story, you can read his alternative (and controversial) Delphi roadmap, here:

http://delphiroadmap.untergrund.net

Marco also commented on Simon's roadmap, here:

http://blog.marcocantu.com/blog/alternative_delphi_roadmap.html

I don't recall all the details right now, but this roadmap did some very loud noise at that time... You can google for it and find lots of stuff....

Anyway, here is Simon's comment about Marco's take on string immutability, among other things (abominations) like, AnsiString removal/deprecation. I think Simon's comments are *more relevant than ever*.

Of Strings, Immutability, COW, and AnsiStrings

Excuse me, but you are not "adding features". You are breaking compatibility of 100% of all Object Pascal code existing today, without any benefit at all. The decision for 0-based strings would have needed be done 20 years ago. Today it's plain silly. Mutability, copy-on-write and the excellent string performance always has been one of the very few actual language advantages over pretty much all the competition. This is easy to learn, easy to remember, clean and nice, and produces fast code: s1 := s1 + ' ' + s2; This is hard to learn, hard to remember, dead ugly, and produces slow code: s1 := TStringBuilder.create(s1).append(' ').append(s2).ToString; Also, "help maintaing code on very old version of Delphi" - that's also completely off. Check the Delphi version survey. A large chunk of users still is using Delphi 7 - for example me, because I need Linux compatibility. Do you want to give them an incentive to finally move to your current offerings and pay you money, or do you want to give them an incentive to drop Delphi and move elsewhere? And: It is about time for Embarcadero that they are no longer the market leader in the Object Pascal field, which already is a niché due to how Delphi and the language got handled the recent years. There are other players, which have stopped copying most of the not-so-clever language extensions of the past years. If you make yourself incompatible with other Object Pascal compilers, you will no longer hurt the competition, you will only hurt yourself. It's a guarantee you'll never get back any users from FreePascal/Lazarus anymore. The "we want to attract new users by making our language look more modern"-stuff doesn't work either. You are a Delphi book author. You very well know that *all* of all available literature on Delphi and Object Pascal in the world teach Delphi Strings. Whoever is new to the language will learn something to then find out that you've broken it. This is a terrible new user experience. Long story short: In the great tradition of the recent years, what you guys do *simply does not make sense business-wise*. You are fractioning the ecosphere you live in. That's an insane strategy. You should revert it. And finally a rant about the implementation aspect: Delphi strings can be implemented in LLVM without any problems and with good performance. Others have done it. There is no technical reason for all this. Whoever is writing your NextGen compiler must either incompetent, lazy, underfunded or very new to the object pascal language. Sorry for the harsh words, but LLVM takes 90% of the work a compiler engineer has to do. If you fail on the remaing 10%, you should not be a compiler engineer.

Monday, January 25, 2016

My Delphi code on Bitbucket

Finally I started using Bitbucket as a repository to my personal projects. Some are free, like the MergeSort algorithm, and the FastStringReplace unit. Soon I'll publish one more project that I've been working on during the last month...

So here they are:

https://bitbucket.org/alex7691/delphi

Enjoy!