WordPress 2.0 Theme competion SLAMMED with entries

Justin innocently thought he would have a little competion to allow bloggers to compete with their WordPress 2.0 themes

Now in the last day his email box was flooded with entries.  A total of 188 themes were submitted!  Now the poor guy is left with no, if he ever had one, life for the next 6 months as he reviews these themes!

Ya gotta giggle: http://kcyap.com/competition/?p=24

Actually it makes me want to start a WordPress 3.0 them competition site right now. Then we’ll have a chance at having something organized by the time WordPress 3 is released in a few years!

Hiding an EXE or Virus inside a TXT file or JPG.

AKA: Alternate Data Streams – An introduction…

One of the members of a technical forum to which I belong had a virus detected in a dll that he could not find anywhere on his computer.  In the end, it was discovered that the file was embedded as Alternate Data Stream (ADS) attached to his System32 directory.  The full path to the file was something simlar to c:\windows\system32:dhht.dll.

I was not familiar with using streams in this manner; so I looked it up.  In short, any file or directory on an NTFS drive can any number of files piggy-backed onto it without affecting its reported file size.  These files remain intact through normal file copying and renaming actions as long as the file remains on an NTFS drive (or compatible archiver).

I’d never come across this before and thought I would share.
Summary/Demo….    (adjust paths as necessary)

  1. Create a directory off the root called test
    From the command prompt in your test directory type:
       [DOS]Echo a>test.txt[/DOS]
       That will create a nice 3 byte text file.
  2. Now type:
       [DOS]type c:\Windows\system32\notepad.exe>test.txt:notepad.exe[/DOS]
  3. Get another directory listing and notice that the size of test.txt remains 3 bytes though an additional ~70kb has been added to it.  The time has changed but that could be set back.
  4. Now, from the command prompt in your test directory, execute the hidden stream:
       [DOS]start \test\test.txt:Notepad.exe[/DOS]
       (You must use include the path to test.txt)

You are now running an exe that was hidden in 3 byte text file!
As far as Windows is concerned, that file takes up only enough space for three characters.  Yet it’s got this hidden back end on it.  That txt file could be taking up any amount of space.  Perhaps it is storing 5 gigs of pictures in it.  Who knows?
Windows supplies no tools to display this.  The zip file referenced in this article, includes an exe that does. 
The Task Manager shows the running proces in different ways depending upon your Windows version.  In SP2, the executable is listed as test.txt:Notepad.exe. However, in earlier versions of windows, only the host file is listed.  So, if you’d embeded Notepad.exe in calc.exe, calc.exe would be in the task list even though you’d be running Notepad.  Nifty huh?
Of course, you’ll have to find a transport/archiver that supports these streams, if you want to distribute them.  Outlook and WinZip do not seem to do so.
Apparently ADS are there for backwards compatibility with a Macintosh file system (HFS), but I’m not sure why we’d want/need that…  Some Windows apps use it for other things.  For example when you download an exe file through IE, MS helpfully edits the file for you and attaches an ADS that stores the Zone under which the file was downloaded.  As a result you are NEVER getting the same file that was on the internet.  Developers should be aware of this when they deploy software via a website. 

In short, while Alternative Data Streams do add some flexibility to the operating system, the incomplete implementation of the feature makes ADS more of an avenue for abuse than a feature.

Common mistake: Don’t rely on exception handling.

Steve Trefethen, Senior R&D Engineer Delphi/C#Builder for the Borland Software Corporation had an EXCELLENT post on his BLog. It emphasizes the cost of a mistake that I always see in example code on the web and in WordPress plug-ins as far as that goes.

Here’s the law that is always broken: “If you know an error is likely to occur in your code, check for that condition first.  DO NOT rely on exception handling detect it.”

This applies whether you are waiting for file access to fail  or an SQL insert statement to come back with an error.  Check to see if the condtion (or record) exists and then have your program handle it correctly.

Generic exception handling should only be used when you cannot predict or test for the condition. 

Newer versions (5+) of MySQL have a clause for inserts called ON DUPLICATE KEY.  Many MySQL programmers are starting to rely on it, but it too has a cost.  Even a single call that runs two insert queries with exception handling thrown in there is almost always going to be slower than checking for the record first and chosing what to do based upon the result of the read only select.  The ONLY reason I see for that call to exist is if it locks the database as it is running and therefore you KNOW the has not changed after your Select query is run. So it does have its application.

 Maybe this article will help others come around: 

BDS 2006, slow compile times and the cost of exceptions

While browsing the newsgroups I ran into a thread where a user had commented that BDS 2006 compiled his application incredibly slowly. A while ago I’d had a discussion with Mark Edington our resident performance maverick about this issue and it turns out that it’s a good reminder of the cost of raising an exception or in this case lots of them.

Since Mark debugged this issue he kindly provided me with a short write up of the specifc problem, it’s solution and a workaround.

Mark write:
In BDS 2006 in Delphi a performance issue arises when compiling projects in the IDE when the source files in the project are marked as read-only on disk. The more files in the project the more significant the delay. The problem only affects projects that have read-only source files. The root of the problem, is a callback procedure which is called by the compiler when compiling in the IDE. The callback is designed to open the file and return an IStream interface:

 


function OpenOSFile(const Name: string): IStream;
begin
  { try opening existing file so that read/write operations are
    possible }
  Result := nil;
  if FileExists(Name) then
  begin
    try
      Result := TOSFileStream.Create(Name, fmOpenReadWrite or 
        fmShareDenyNone);
    except
      on EFOpenError do
        Result := TOSFileStream.Create(Name, fmOpenRead or 
          fmShareDenyWrite);
    end;
  end;
end;

Notice the try/except block, since there is no parameter to the function that specifies what access rights to use when opening the file, the procedure tries to be accommodating and provide read/write access first and if that fails it resorts to to opening the file as read-only. Unfortunately, as written, it introduces a serious performance penalty for anything other than small projects. Interestingly enough, the performance issue isn’t from the fact that it takes 2 attempts to get a read-only file opened, it is actually caused by the exception that is raised when the first (read/write) TOSFileStream.Create call fails.

In the test case that was submitted for diagnosing this problem the RaiseException procedure (which is a Windows API call), was accounting for nearly 40% of the total compile time. Under a profiler it took nearly 50 seconds to execute that procedure about 1100 times. That works out to around 45 milliseconds per call which may not sound like that much, but when executed 1100+ times it adds up.

The solution was very straightforward: Rewrite the routine and remove the exception based fallback algorithm. The new version looks like this:


function OpenOSFile(const Name: string): IStream;
var
  Code: Integer;
begin
  Result := nil;
  Code := GetFileAttributes(PChar(Name));
  if (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0) then
  begin
    if (FILE_ATTRIBUTE_READONLY and Code = 0) then
      Result := TOSFileStream.Create(Name, fmOpenReadWrite or
fmShareDenyNone)
    else
      Result := TOSFileStream.Create(Name, fmOpenRead or
fmShareDenyWrite);
  end;
end;

This version first checks to make sure the file is not marked as read-only before attempting to open it as read/write. The FileExists call that was replaced in the original version of the procedure is actually implemented using GetFileAttributes anyway, so there was no extra overhead introduced to make the check.

The moral of the story is avoid writing code that raises exceptions as part of the normal course of program execution. Exceptions are horrifically expensive to raise and handle and should be reserved for the truly “exceptional” events. If you have a medium to large Delphi project that has files marked as read-only the workaround for this issue is to mark them as read/write until this fix is made publicly available.

posted on Monday, February 27, 2006 3:51 PM

Graphics programming in Delphi

This was a brief introduction to Graphics programming that I wrote a few years back… The concepts are all good even if the links are not.  🙂  Many of the resources for Delphi graphics programming were disappearing even then.  So this article is now the only place to get some of these examples…

http://www.TheCodeCave.com/Queeg/GraphicsProgramming/index.htm

Brian Layman on .Net Programming

I’ve used this twice now.  So I’ll add it here.

Some PHP zealot stated that because PHP could be used in conjunction with AJAX, .NET was dead.  I should have just let him go, but he was being so arrogant that he could only be some 14 year old sitting in his parents house spouting “wisdom” for the masses despite his bragging of being a VB programmer with 20 years of experience.  And frankly I don’t see much difference between a 14 year old living with his parents and a Visual Basic programmer with 20 years of experience (so sorry ;p).

So, here is my response and more importantly my explanation of what .NET programming is and isn’t:

“[..] Microsoft is spouting that Win32 is dead not that .NET is dead.  While I agree that is not correct (Win32 is far from dead), it is not because .NET is going to leave the scene any time in the next 20 years.  .NET
programming is the only manner of programming MS’s new compilers allow. Really .NET isn’t a language at all.  It is a standard that can be used by any programming language to get your code into a third neutral language that will run on any platform. Basically you don’t compile into machine code anymore.  That way all of the tricks the hacker uses are eliminated.  No more reading areas of memory that don’t belong to you.  No more expanding your strings with binary code to put stuff where it doesn’t belong.  [No more grabbing initialized memory and accidentally getting the contents of an email that was just sent out.] The second level of compiling ensures none of that exists in the new final machine code.  Then the OS (Vienna?) will not allow anything that is not .NET compliant to run.

So, you write something in C or Delphi in a way that conforms to the .Net standard.  That compiler translates your code into a Common Intermediate Language that will be compiled again in a by a Common Language Runtime (CLR) to run on specific platforms (OSs).  MS’s .Net framework, the only.net “platform” that we have right now, is just the transition path to allow us to start writing applications now that will compatible with their future OS’s.  It’s a pretty smart plan really.  We are a long time away from having a OS that only supports programs written under the .NET specs (2009?), but MS is starting to make those programs the only type that can be written.”  

[continuing] 

And in that fashion Microsoft ensures their new OS standard will be adopted even when drop backwards compatibility to Windows Server 200x and Windows Vista and Windows XP by saying that their OS will  no longer allow 16 bit and Win32 bit programs to run.  The fact that no major programming languages, other than Delphi 2006, support Win32 programming ensures that by 2009 most apps that are less than 5 years old will be .NET and run on MS Vienna without a problem and MS can say that they have achieved 95% compatibility.  They have found a way achieve forward compatibility with an operating system half a decade into the future.

I have to say that is somewhat impressive. They definately do some things right.  Just don’t get me started about feature level de-activation in Windows Vista.

There are problems there. For instance, I changed some hardware in my computer. Outlook deactivated itself and required I put in the original disk to get it to work. Fine. I did that and ti was working again. But just now it deactivated itself again, because it suddenly decided I must be a thief. I’m connecting via Remote Desktop and some bug must have led it to determine that my hardware had changed again.  I AM VPNING IN HOW CAN I INSERT THE CD???? IT IS ON MY DESK AT HOME!!!! AAAGGHHH! I guess you take the good with the bad…

*UPDATE: AND NOW IT’S HAPPENED TWICE!!! but that’s for another post….

A command line method to reattach to networks

This routine does the same thing as the Windows Network Repair function, but from the command prompt.  Now why is this important? Well, it is VERY important when you have effected network changes, or physically had someone detach the computer from one network and attach it to another.  When this is done, the computer has to know to forget everything it knew about the old network and learn what it can from the new network.  Double clicking on a short cut to this batch file can take care of that and it is much simpler than leading someone through the steps to get to the network repair option.

Concepts Demonstrated: Network manipulation
Concepts Demonstrated: Quiet Parameter

      ::@Echo off ::************************************************************************* :: This Batch file performs the rough equivelant of a Windows XP SP1  :: Network Connection Repair. :: :: Usage: ::   NetworkRepair      <-- Prompts for permission & repairs all networks ::   NetworkRepair [ConnectionName]     <-- Prompts & repairs one network ::   NetworkRepair Quiet    <-- Does Not Prompt (Quiet is Case Sensitive) ::   NetworkRepair Quiet [ConnectionName]    <-- Repairs only one network :: :: A Windows Network Connection Repair (Right click on the Local Area  :: Connection and choose Repair) performs a series of commands that allows :: a computer to rebuild a its connection to the network.  The commands :: that are invoked by Repair are included below in their command-line :: equivalents.  The only current  difference is that the Repair process :: first checks whether DHCP is enabled and then, if enabled, it issues a :: broadcast renew to refresh the IP address.   This will cause the  :: computer to accept a lease from *any* DHCP server that is on the network.  :: You cannot do that from the command line.  In contrast, a unicast renew :: (as done through ipconfig /renew) will only renew the existing lease :: from the currently used DHCP server.  I've  tried to work around that :: difference calling ipconfig /release.  Hopefully, putting the :: ipconfig /renew further down in the batch file will cause a broadcast :: request for a new IP address.  I do not know if that will happen or not.  :: In any case, this would only affect the behavior of the repair if your :: network has multiple DHCP servers. :: :: In addition, a normal repair is performed for one connection at a time. :: This batch file will repair all network connections unless you specify :: the mask to use for finding the correct networks. Like so: ::   NetworkRepair Wi*         <-- Repair any connection that has its name ::                                 starting with "Wi" ::   NetworkRepair Quiet *Con* <-- Quietly repair all connections with, ::                                 "Con" anywhere in the name.  Examples ::                                 include "Local Area Connection 1" or ::                                         "Local Area Connection 2":: ::   NetworkRepair quiet       <-- Repair all networks named "quiet" :: :: :: Author - Brian Layman :: Created - 5/29/2003 :: Last Modified - 7/27/2005 :: :: License - If this helps you - Great! Use it, modify it share it. :: :: Indemnity - You're playing with network settings and clearing caches. ::    That means that if your settings are messed up on this computer or any ::    of your network servers or routers, running this batch may cause it to ::    see even fewer network resources from this computer.  This batch file  ::    makes the computer forget everything it ever knew about the way the  ::    network was working before.  When it asks the routers and servers for new ::    information, that information must be correct for your problem to go away. ::    ::    Use this batch file at your own risk.  I'm only calling built-in Windows ::    commands, but if a typo or service pack change affects what this routine ::    does, it is not my fault.  In fact, you should just stop right now and ::    not run this file.  For if it causes blue smoke to be emitted from your ::    network card, if it resets your home site to HowToKillMyBoss.com, or if ::    it makes your sister break up with her lawyer boyfriend and start dating ::    a caver, it is not my fault.  (Actually that last one might be an ::    improvement, but it is still not my fault.) :: :: Uses - This routine allows you to automate switching from one network ::    connection to another simply by double-clicking a link on the desktop. ::    It may also be useful in performing quick repairs of network connections ::    rather than guiding your relative/friend/spouse through the process over ::    the phone. :: :: Donations - If this batch file really helps you out, feel free to make a $5 ::    (US) donation via Paypal to Brian@TheCodeCave.com or just send a Thank ::    You via email to that address and include your country of origin. :: :: MD5 - The correct MD5 is available at: ::                     http://www.The-WildWest.com/Queeg/NetworkRepair :: :: Enjoy! :: ::*************************************************************************  :: ************************************************************************* :Quiet Check ::  Check for the Quiet password. :: ************************************************************************* :: Put a bracket around the %1 to trap for empty values and to allow the :: string comparison to work if [%1] == [Quiet] GOTO :TheWorks :: *************************************************************************  :: ************************************************************************* :TheWarning ::  ::  Display some info about the program and also allow several ways to ::  abort an accidental launch. :: :: ************************************************************************* Echo. Echo This batch file will reset your network connection.   Echo. Echo. By running it you're playing with network settings and clearing caches. Echo. That means that if your settings are messed up on this computer or any Echo. of your network servers or routers, running this batch may cause it to Echo. see even fewer network resources from this computer.  This batch file Echo. makes the computer forget everything it ever knew about the way the network Echo. was working before.  When it asks the routers and servers for new Echo. information, that information must be correct for your problem to go away. Echo. Echo. Use this batch file at your own risk.  I'm only calling built-in Windows Echo. commands, but if a typo or service pack change affects what this routine Echo. does, it is not my fault.  In fact, you should just stop right now and Echo. not run this file.  For if it causes blue smoke to be emitted from your Echo. network card, if it resets your home site to HowToKillMyBoss.com, or if Echo. it makes your sister break up with her lawyer boyfriend and start dating Echo. a caver, it is not my fault.  (Actually that last one might be an Echo. improvement, but it is still not my fault.) Echo.  @pause  :: ************************************************************************* :TheWorks :: ::  Let the fun begin! :: :: ************************************************************************* if NOT [%1] == [Quiet] Echo. if NOT [%1] == [Quiet] Echo * Release the DHCP lease - NOT PART OF REPAIR if NOT [%1] == [Quiet] ipconfig /release %1 if [%1] == [Quiet] ipconfig /release %2 if NOT [%1] == [Quiet] Echo. if NOT [%1] == [Quiet] Echo * Flush the ARP cache arp -d *  if NOT [%1] == [Quiet] Echo. if NOT [%1] == [Quiet] Echo * Flush the NetBIOS cache nbtstat -R  if NOT [%1] == [Quiet] Echo. if NOT [%1] == [Quiet] Echo * Flush the DNS cache ipconfig /flushdns  if NOT [%1] == [Quiet] Echo. if NOT [%1] == [Quiet] Echo * Request a new the DHCP lease - NOT PART OF REPAIR if NOT [%1] == [Quiet] ipconfig /renew %1 if [%1] == [Quiet] ipconfig /renew %2  if NOT [%1] == [Quiet] Echo. if NOT [%1] == [Quiet] Echo * Re-register with WINS nbtstat -RR  if NOT [%1] == [Quiet] Echo. if NOT [%1] == [Quiet] Echo * Re-registers with DNS ipconfig /registerdns  if [%1] == [Quiet] CLS  :: ************************************************************************* :TheEnd :: ::  So long and thanks for all the fish! :: :: ************************************************************************* 

Demonstration: Manipulating the Clipboard in Delphi

Here’s a quick demonstration of how easy programming is in Delphi.

This small app allows you to copy text and past it again right away with it converted to proper case or upper case.  This was written for a ZTree user that had a bunch of files that he wanted t rename to partially uppercase.  There was no way to pick out the part of the name he wanted in upper case. So I wrote this routine to allow him to highlight part of the text, hit copy and then hit paste.  And viola, he it would be fixed.

So in Delphi, how do you access the clip board? Well, it couldn’t be simpler.  Just add the clipbrd unit to your uses statement like this:

[delphi]uses Clipbrd;[/delphi]

Then you can read and write to the clipboard  as text like this:

[delphi]A := Clipboard.AsText;
Clipboard.AsText := A + ‘BC’;[/delphi]

Of course it is best to check that you are dealing with text befor you try to get the information back from the clipboard.  That can be done like this:

[delphi]if (Clipboard.HasFormat(CF_TEXT)) then DoIt;[/delphi]

See! It is THAT straight forward.  If you want to see what  other clipboard formats there are, just highlight CF_TEXT in Delphi and hit F1 and you’ll get a full list.

Value Meaning
CF_TEXT Text with a CR-LF combination at the end of each line. A null character identifies the end of the text.
CF_BITMAP A Windows bitmap graphic.
CF_METAFILEPICT A Windows metafile graphic.
CF_PICTURE An object of type TPicture.
CF_COMPONENT Any persistent object.

So the instructions to create a full app are quite simple:
In Delphi, create a new app. In the Object Inspector, Name the main form frmCBFix, change the Border style to bsToolWindow, and change the form style to fsStayOnTop

Place a TEdit on the form and name it editCorrected text, clearing the default text value.

Add Clipbrd to the uses.

Put a TTimer on the form and double click the timer event in the Object Inspector.

Paste the following code into the unit replacing the automatic generated Timer1Timer procedure:

[delphi]{******************************************************************************
ProperCase
Converts a string to proper case by capitalizing each letter after a space or
punctuation. The only common punctuation not used is the apostrophe/single
quote. This avoids changing don’t to Don’T, but will sentences quoted
inside single quotes will not have their first letter capitalized.
******************************************************************************}
function ProperCase(aSrcStr: String): String;
var
Len, Index: integer;
begin
aSrcStr := Lowercase(aSrcStr);
Len := Length(aSrcStr);
aSrcStr[1] := UpperCase(string(aSrcStr[1]))[1];
for Index := 1 to Len – 1
do begin
if (aSrcStr[Index] in [‘ ‘,’$’,'”‘,'(‘,’)’,’`’,’!’,’?’,’<','!','>‘,’#’,’=’,’+’,’:’,’,’,’/’,’.’,’&’,’-‘,'{‘,’}’,'[‘,’]’,’|’])
then aSrcStr[Index + 1] := UpperCase(String(aSrcStr[Index + 1]))[1];
end;
Result := aSrcStr;
end;

{******************************************************************************
Timer1Timer
Fires periodically (orignally every 250ms), checks the clip board for text,
if it has changed, convert it to proper case and put the result in the
clipboard and the edit control.
******************************************************************************}
procedure TfrmCBFix.Timer1Timer(Sender: TObject);
begin // Timer1Timer
if Clipboard.HasFormat(CF_TEXT)
then begin
if (editCorrectedText.Text <> Clipboard.AsText)
then begin
editCorrectedText.Text := ProperCase(Clipboard.AsText);
Clipboard.AsText := editCorrectedText.Text;
end;
end;
end; // Timer1Timer [/delphi]
And you’re done!

Here are the files for this project:
http://www.TheCodeCave.com/downloads/delphi/CBFixerUpper.exe
http://www.TheCodeCave.com/downloads/delphi/CBFixerUpper.dpr
http://www.TheCodeCave.com/downloads/delphi/u_CBFix.dfm
http://www.TheCodeCave.com/downloads/delphi/u_CBFix.pas

The WordPress 2.0 theme competition ends today

Today is the last day for submissions.  I hope this means there are pleanty of good themes coming out soon.  Now that I know a little about this, I realize that this competition is being done the right way.  In reality, appearance, which to the new WordPress user seems to all there is to themes, is MUCH less important than the underpinnings and design of the theme.  In this competion, prizes are being given for How the theme was written and what features it includes.  In stead of, or perhaps in addition to, the theme appearance.  See here: http://kcyap.com/competition/?p=3

Display the program that will run when type a name at the cmd prompt

You can also find this file here: http://www.the-wildwest.com/Queeg/Batches/SearchPath.bat

:: ************************************************************************* ::  SearchPath.Bat                                               10/31/2005 ::  Written by Brian Layman (AKA Capt. Queeg) ::  Visit him at http://www.thecodecave.com/ ::  ::  A batch written to display the program that would be run when ::  a filename is typed at the command prompt.  Just a demo for ::  Hartmut at http://www.ztw3.com/forum/forum.cgi ::  ::  Usage: SearchPath ProgramName[.EXT] ::  ::  History: ::     10/31/2005 - BL - Created ::     11/01/2005 - BL - Removed Temp File Usage ::     02/28/2006 - BL - Changed my URL ::  :: ************************************************************************* @echo Off :: All this is boiled down to one subroutine that sets a variable of the :: same name. call :SearchedFilePath %1 :: If no program is found, say so. if "%SearchedFilePath%"=="" echo There is no matching program in the search path :: If a program was found, echo its name. if NOT "%SearchedFilePath%"=="" echo %SearchedFilePath% :: Clear out our temp variable set SearchedFilePath= :: Quit GOTO :EOF :: ************************************************************************* :: ************************************************************************* ::  Support procedures :: ::  These routines are called with a CALL directive and the GOTO :EOF ::  terminates that CALL but does not terminate the entire running of the ::  batch file. :: ************************************************************************* :: ************************************************************************* :SearchedFilePath ::  Returns the full path to a passed file in the searchpath :: ::  Returns blank if not found. :: :: ************************************************************************* : set SearchedFilePath=    :: Set the default value to blank.   set SearchedFilePath=   :: If there is no extension handle it   if "%~x1"=="" Call :SearchWithExtensions %1&GOTO :EOF   :: There is no extension, is it blank?   if "%1"=="" GOTO :EOF   :: So, we have an extension.  That means we can do a simple search.   :: %~dp$PATH:1 automatically searches the path for us.  It is a   :: variable set by the Call command.   set  SearchedFilePath=%~dp$PATH:1%1   if "%SearchedFilePath%"=="%1" set SearchedFilePath=&GOTO :EOF   GOTO :EOF :: ************************************************************************* :: ************************************************************************* :SearchWithExtensions ::  Iterates the extensions gathered from the PATHEXT environment ::  and searches until the file is found. :: ::  Returns blank if not found. :: :: *************************************************************************     :: Initialize a counter for looking at multiple search results in one line     set cnt=0     :SearchLoop       :: Break out after 20  checks.       :: If you might have more than 20 extensions, increase this value.       :: If you could find out how many periods there are in the temp file, you could optimize this.       if "%cnt%"=="20" GOTO :SearchLoopCleanup       set /A cnt=%cnt%+1       :: Continually search the single line file returning each sequential search result and recursively pass it to the       :: SearchedFilePath routine.  When we ask for a token # that doesn't exist and blank is returned, abort out.       for /F "tokens=%cnt% delims=.;" %%C in ("%PATHEXT%") do call :SearchedFilePath %1.%%C       if "%SearchedFilePath%"== "" GOTO :SearchLoop         :SearchLoopCleanup       :: Clear our Temp variable       set cnt=   GOTO :EOF :: *************************************************************************

 

Borland Dies.

By now every Delphi programmer knows about this.  But for all others, here you go:

Borland has release the first version of Delphi, since Delphi 5 in 1999ish, that has been truely worth the upgrade price.  Delphi 2006 (D9) pretty much guarantees the success of the company by being the ONLY compiler fill a niche (Win32 development) that MS’s move to dot .net created.  Only ONE of the new MS compilers will allow you to write a Win32 bit app (VC++ still allows it but VB, VC#, VJ# etc do not  Thanks Liviu! ) Delphi is IT for the next 7-10 years while Win32 apps will still be allowed (basically for the life span of Windows XP and Vista).

Having such a high quality tool that practically guaranteed sales in a totally open vertical market, left Borland’s newest poker-playing-turn-around-guy, Tod Nielsen – the newest in a string of CEOs dedicated to the destruction of Borland – no choice but to kill the company by dropping all code development tools 100 days after he took the job.

“We’re still all about development, but less about the creation of code,” Nielsen said.  – HUH??????

The interesting thing is that the Delphi community user base is SO frustrated with the management decisions of the last 7 years that they have thrown up their arms and said “Fine. Do it. And good riddance.” 

 Read the details:

http://www.eweek.com/article2/0%2C1895%2C1922016%2C00.asp

 

Addendum – I just found out that in the fall of 2005 a Borland stock holder (the largest?) had offered Borland 125 million for their language suites.  Borland turned him down out of hand.  Now a few months later, they’ve begun to think “hmmm, that was a lot of green!  Let’s do it!”  Of course now that they are the ones wanting to make the deal, not the buyers, they’ll be lucky to get 2/3 the original offer.   Which I should be happy with I guess.  It means the people buying the IDE products will have all the more money to invest in them… 

Oh and if you are a news group reader, David “I” has been out on the groups lately trying to restore confidence in the product.

I still can’t beleive they’ve done this after such a succesful production release. But I guess you always clean your car just before you sell it, too.