A site devoted to discussing techniques that promote quality and ethical practices in software development.

Tuesday, December 22, 2009

Delusional plan

Stephen Conroy is not renown for making any intelligent contribution to Australian society and definitely not renown for possessing a great deal of knowledge on anything - including Intenet, Digital Media, and now traffic management. His latest delusional contribution to his vast collection of bloopers (mind you tax payers funded bloopers) is:
he was confident that placing speed humps every 100 metres on all Australian freeways would protect children - reducing accidents by 100 percent with a "negligible" impact on traffic congestion and travel times. The plan was supported by traffic management trials which had only been conducted in suburban back streets.
Anyone with a shred of intelligence will immediately asked why would children, or to matter any human or animals, be allowed onto a freeways. All freeway entrances have big signs declaring what are permitted to go onto a freeway. 

Is Conroy deluded into thinking freeways are synonymous with suburban back streets?

Is he confused with children inside a car in an accident that could harm them? May be he should ban cars carrying children to use freeway. Or banning children riding in a car at all. That will definitely reduced children injured in car accident by 100%. Banning thing is a widely practice by our authoritarian politicians who lack communication and persuasive skill. This is equally a stupid idea and may be that is Conroy's plan B. Who knows and I will not be the only one surprise if it turned out to be.

Sunday, December 20, 2009

Wrong assumption and big blunder

This would be funny if not deadly serious. How can a company producing military drones can be so stupid:
The problem was uncovered in July 2009, when the US military found files of intercepted drone video feeds on the laptop of a captured militant, intelligence and defense officials told the Journal.

They discovered "days and days and hours and hours of proof," an unnamed source said.

"It is part of their kits now."

Some of the most detailed examples of drone intercepts have been uncovered in Iraq, but the same technique is known to have been employed in Afghanistan and could easily be used in other areas where US drones operate.

The US government has known about the flaw since the 1990s, but assumed its adversaries would not be able to take advantage of it, the Journal said.

Adding encryption to a decade-old system requires upgrading several components of the system linking drones to ground control.

One of the developers of SkyGrabber, which is made by Russian company SkySoftware, told the Journal he had no idea the program could be used to intercept drone feeds
Even your mobile phone has more security and encryption from the handset to the base station than something meant to perform the task stealthily. It is just arrogant and stupid to assume your adversaries is dumb. I am wondering who is dumber now.

Friday, December 18, 2009

Applied equally to software

Software development tools and languages are progressively automated with heavy layers of encapsulation in the guise of freeing the developers from needing to know the underlying principle. This heavy layer of automation is fine until problem strikes and that is when people's knowledge of its underlying principle is needed to dig oneself out of the problem. I am not anti-encapsulation or things like that but I am a strong advocate of the importance to dig deeper to learn the principle behind a framework or class library so that one knows precisely what is underneath.

The situation has many similarity to this pilot's encounter with an automated plane:
The irony, she said, is that the more advanced the automated system, the more crucial the contribution of the human operator becomes to the successful operation of the system. Bainbridge also discusses the paradoxes of automation, the main one being that the more reliable the automation, the less the human operator may be able to contribute to that success. Consequently, operators are increasingly left out of the loop, at least until something unexpected happens. Then the operators need to get involved quickly and flawlessly, says Raja Parasuraman, professor of psychology at George Mason University in Fairfax, Va., who has been studying the issue of increasingly reliable automation and how that affects human performance, and therefore overall system performance.

”There will always be a set of circumstances that was not expected, that the automation either was not designed to handle or other things that just cannot be predicted,” explains Parasuraman. So as system reliability approaches—but doesn’t quite reach—100 percent, ”the more difficult it is to detect the error and recover from it,” he says.
And when the human operator can’t detect the system’s error, the consequences can be tragic.

Thursday, December 10, 2009

Pouring cold water on 'hacked' Climate Research Unit's E-Mail

I am skeptical that the recent publication of the collection of e-mail exchanges between scientists in the Climate Research Unit is the work of a hacker. My skepticism is now supported by a forensic analysis by a Unix System Administrator.
The only reasonable explanation for the archive being in this state is that the FOI Officer at the University was practising due diligence. The UEA was collecting data that couldn't be sheltered and they created FOIA2009.zip.

It is most likely that the FOI Officer at the University put it on an anonymous ftp server or that it resided on a shared folder that many people had access to and some curious individual looked at it.

If as some say, this was a targeted crack, then the cracker would have had to have back-doors and access to every machine at UEA and not just the CRU. It simply isn't reasonable for the FOI Officer to have kept the collection on a CRU system where CRU people had access, but rather used a UEA system.

Occam's razor concludes that "the simplest explanation or strategy tends to be the best one". The simplest explanation in this case is that someone at UEA found it and released it to the wild and the release of FOIA2009.zip wasn't because of some hacker, but because of a leak from UEA by a person with scruples.
 It is most likely an inside job.

E-Voting system opened for public scruntiny

Ed Felton's effort has finally paid dividend and Sequoia has opened up their Frontier e-voting system source code that is still in development for public scrutiny.
Yesterday, Sequoia made good on this promise and you can now pull the source code they've made available from their Subversion repository here:
They should be applauded to ensure full confidence in their product. I just wish many companies, particularly those producing ERP and critical software, are that inclined.

What is of great interest to me is the fact that this system is developed using MS .Net Framework V2/3.5 and the projects are developed using C# in VS2008.

A quick scan of the projects revealed some issues:
1) The solution failed to be self-contained. In other words, the solution should contains all the third party supporting DLLs and then projects needing it are then referring them in relative path. In this way, the source control and solution will contain everything a developer would need when the solution is checked the solution out. Perhaps they are not included in the public code because of licensing issues.

2) Many classes should be marked static but are not. There are signs showing the code may have been migrated from .Net 1.x, which does not have static class. For example, the Contract class in Core solution.

3) Projects have not turned on Code Analysis. May be they do not use Visual Studio Team System.

4) The System.Data.IDataReader that is returned by Sequoia.EMS.Core.DataServices.BaseDataService or Sequoia.Ems.Data.Custom.BaseEntrySet does not appear to have been disposed after entries are added in Sequoia.Ems.Data.Custom.BaseEntrySet.Load(). IDataReader is derived from IDisposable.

5) Good to see the use of the Workflow engine.

6) Use of NUnit is evidence in the code but does not appear to be widespread usage of the Unit Test or TDD.

7) It is also using Microsoft Enterprise Library but it appears that it is using its own implementation to do logging.

8) Some project for example, the Core, is set to use .Net 2.0 but it contains references to .Net 3.5 specifics namely System.Xml.Linq. Very strange. Just wondering if it is in the process of upgrading all project to .Net 3.5. There are currently 10 projects in .Net 2 and 12 in .Net 3.5. Altogether there are 22 projects.

9) Personally I am not too keen on the way the Core project is organized. Essentially Core is a project containing 34 files which are grouped into pseudo-sub-projects using solution folders. This kind of design can encourage tight coupling because each sub-project's internal artifacts are available to each other. May be that is their intention. Preliminary review does not support this.

This kind of organization also makes partitioning the module to be managed by several developers difficult. It is most unfortunate that VS2008 does not support netmodule in the IDE otherwise, partitioning Core into several netmodules is a better organization.

Wednesday, December 2, 2009

Treat String containing '\0' with care

Recently I had to decode a sequence of octets representing the UCS2 of some data and the sequence contained the C-Style string's null terminator. The sequence of octets were represented in C# as Byte[] naturally and Encoding.Unicode.GetString() was used to decode the sequence into a Unicode string.

The decoding process did not trim off the terminating '\0'. So it produced a Unicode string like this "Hello World\0".

During testing, several interesting things were discovered that could have significant impact on your code and the validity of your Unit Tests:
1) If you write out the string to console like this:
String s = "Hello World\0"; 
Console.WriteLine( "This is the Unicode String = '{0}'", s );

Your output will not contain the trailing '.

2) If you use write out several lines like this:
String s = "Hello World\0"; 
Console.WriteLine( "This is the Unicode String = '{0}'", s );
Console.WriteLine( "See anything strange?" );

It will produce a line like this:
This is the Unicode String = 'Hello WorldSee anything strange?

The Console.WriteLine() removes the ending ' and the newline.

3) Make sure you use the correct version of String.Compare() and use the correct comparison type as specified by the StringComparison enumeration:
String s0 = "Hello World"; 
String s1 = s0 + "\0";

Assert.IsFale( s0.EndsWith( "\0" ); // Just to check 
Assert.IsTrue( s1.EndsWith( "\0" ); // Just to check
Assert.IsTrue( s0.Equals( s1 )==false ); 
Assert.IsTrue( String.Compare( s1, s0 )!=0 );     // Fail but should Pass
Assert.IsTrue( String.Compare( s1, s0, false )!=0 ); // Fail but should Pass
Assert.IsTrue( String.Compare( s1, s0, StringComparison.Ordinal )!=0 );
Assert.IsTrue( String.Compare( s1, s0, 
   StringComparison.InvariantCulture )!=0 ); // Fail but should Pass

The lines in red are incorrectly processed.

Be careful when using NUnit's Assert.AreEqual(). In version 2.4.x, the AreEqual() incorrectly handles this case resulting in passing the comparison. This mistake has been fixed in ver 2.5. MSTest's AreEqual() correctly handles this case.

This illustrates the need to exercise care when comparing strings.

Monday, November 23, 2009

Good for the Industry

More of this will be good for the IT industry.

Friday, November 20, 2009

Feeling a bit cloudy

Unless you have not touched the Internet in the past year or so, you would no doubt be bombarded by the latest hype called Cloud Computing while the poster boys of yesterday B2B, B2C, E-Commerce are conspicuously ignored. Surprisingly, those advocates seem to imply Cloud only applies to those modern often rehashed applications.

According to those definitions in here and here, no one can argument that the good IMAP, whose RFC was ratified before the word Cloud Computing was ever conned, does not fit the definition of a Cloud computing application.

Since GMail is now supporting both POP3, which I have been using ever since I used e-mail, and IMAP, I have decided to give this cloud application a try to see what kind of adjustment I had to made or what other problem I can see.

Of course, I am not quite ready to give up my Desktop e-mail client and I am using Thunderbird as the IMAP client. Here are the main issues:

How could I take my mail from GMail to another ISP

In the past, when I switch ISP, I simply change the e-mail client's POP3 servers addresses to my ISP and to tell my friends to switch addresses. Since I am using an e-mail redirection service, I did not have to bother my friends and associates. My e-mail storage is the central repository of all my e-mail correspondence from various ISPs over the years. As long as I have a sound back up policy to adhere to, I do not lose them.

However, with the IMAP, the messages are located on the IMAP server and I cannot take the collection from say the GMail IMAP and give that to XYZ's IMAP and from there to accumulate e-mail sent to XYZ's server. Perhaps it is peculiar to GMail, I don't even have the control on when a file is actually deleted.

I guess this is not uncommon to many person's concern with using Cloud Computing. How can I retrieve the data that ultimately belonging to the user of the Cloud application when that association is broken?

I cannot find anyway to pick up all my e-mail from GMail IMAP and transplant that to another ISP's IMAP. Or could that ever be possible with IMAP technology? The best I could do is to employ a offline e-mail archive program.

How do I read/compose/search my e-mail when I am disconnected

The next annoying issue with IMAP is like Web Mail and you may as well embedded the browser in a Desktop application and calling that a 'IMAP' client. No Internet means no ability to browse through your mails or prepare the responses.

Yes, you can set up your e-mail client to operate in offline mode and when that happens it will download the messages to your client program.

It is not a matter if it can be done but how well it works in practice.

If your WiFi is suddenly cut or you have flown across to the other side of the world without a Wireless Internet service, it is a bit discomforting to know that you should have pressed that button to download all your IMAP messages before losing connectivity. Perhaps Thunderbird cannot do that process automatically.

As said, you may as well work totally with Web Mail via your browser. I guess in all these Cloud Computing, it is all predicated on having connectivity. If that is lost, you may as well be tapping on a piece of slat. It is just a modern version of the good old dumb terminals with the same kind of problems that technology bring.

In the end, I opted to switch back to the trusted POP3. The IMAP was supposed to be more efficient but from my experiments, it seems a lot more wasteful; when I clicked on different folder, the client contacted the server for information.

Wednesday, November 18, 2009

Annoying-ware from Microsoft's MSDN

Lately, Microsoft's MSDN web site has adopted similar tactic used by those inconsiderate Adware sites demanding you take some action or else it continues to annoy the hell out of you.

Here is what I mean:

You can see this is if you navigate to the MSDN library site. The 'Switch View' pop up is so annoying, anti-social, inconsiderate and so intrusive that is actually worse than many adware sites.

Look at how inconsiderate Microsoft has placed that pop up.It covers up the down button of the scroll bar. It is designed purely to annoy the user in much the same way as they designed the Vista UAC.

The idea of that pop up is to annoy you until you give in to switch to "Script Free". Hardly a good tactic to encourage feedback from user; you definitely get some negative ones from me. The following picture shows that even Microsoft cannot handle a machine running with 120DPI:

The 'Script free' option is half disappeared. Is this another annoying strategy employed by Microsoft?

Well done, Microsoft, you have succeeded in annoying your users and earn the same dubious title of that bestowed on Malware/Adware sites.

Tuesday, November 10, 2009

What does a decrease by a negative amount mean?

Recently I caused some share movement by amalgamating several holdings into one. As a result of my action, I received notification from the registry describing the movement.

But I am puzzled by this: under the column marked 'Decrease', it has a negative amount. To my mathematical mind, I would have thought a decrease (negative of increase) of a negative (double negative) would produce a positive number. Like calling a C++ function like this:

int Dec( int &var, int amount )
     return var -= (amount);

So if you have this:
int x = 100;
int y = Dec( x, -10 );
assert( x+10, y ); // as any logic will tell you.

If the registry intends on using negative amount to indicate reductions, it should display that figure in the 'Increase' column and the sum would come out right. Perhaps the company has not gotten around to amalgamate the 'Increase' and 'Decrease' columns into one 'Movement' column.

Thursday, November 5, 2009

Imporantce to knows what is behind the facade

A well written essay argues
there is still a need for "old-fashioned gumption" — a need to retain some mastery over tools we rely on and to explore others' potential.
... "it can be very disempowering because people aren't really understanding what's going on in their business".
Of course, the most common tools in our business and personal lives have user-friendly interfaces, enabling the least tech-savvy to use them. An unfortunate side-effect of this, Mr Gelme says, is that "general users of technology have no idea about how an appliance really works, which means they may not know how to use it most effectively or repair it".
He adds: "Hiding the internal operation with an intuitive interface is compounded by the manufacturer's natural tendencies to protect their product from competitors and to increase sales by ensuring broken appliances have to be replaced, not repaired." This is achieved mainly through proprietary software.
Far too many developers lack the understanding of the mechanics behind the tools they use. Many relies on the tools as an escape from learning the fundamentals. As a consequence, they are at loss when problem occurs, which according to Murphy's law will inevitably occur.

AvgTrayMainWnd in AVG 9.0.698 - What kind of customers help from AVG?

Out of the blue, I had this task bar button with AVG icon appearing and clicking on it reviewed the "AvgTrayMainWnd". OK, that is a bit unusual. It would not close even when the Close menu was there and enabled. Hence it fits my definition of annoying-ware. To there developer, please disable the sysmenu's Close item if you intend on showing it on task bar. 

Anyway Google reviewed several people have sought help from the AVG Official forum. My search in the forum revealed 8 messages. Since I had the same problem, I opened a few of these submissions to see what was the official view on this. The experience showed what a waste of Internet, time and energy. This is the typical robotic response:
"Just carry out a forum search on AvgTrayMainWnd & you'll see that users are being contacted by AVG Technologies." from the moderator.

Some time the manager's response is equally unhelpful:
"you will be soon contacted by AVG techsupport for some information."

What is the secrecy of this issue, which is obviously AVG's? Why not post an explanation or even a work around? If your forum cannot help your user, don't post this kind of unhelpful remark.

How does AVG know people have seen this annoying-ware appearing "that users are being contacted by AVG Technologies."? Perhaps, you should instruct user to file a bug report so that AVG could contact them. For those who have been contacted as claimed by AVG, would you mind sending me the highly secret response that they could not even disclose on their forum?

Here is my work around:
1) Download pskill.exe to say C:\Windows\system32 or a directory in the path.
2) Copy the following line to a batch file called KillAvgTrayWnd.cmd or anything you like but make sure it ends with cmd.
@Echo off
pushd "c:\program files\avg\avg9"
pskill avgtray & avgtray.exe
3) Put this batch file anywhere you like, on the desktop for example.

If you have installed AVG9 to somewhere else, change the directory in the pushd command.

When that annoying button appears, just execute the batch file which terminates that annoying-ware taking that stubborn window with it and then restarts the monitor.

Alternately, just uninstall it and use another free anti-virus program with a more helpful forum.

Wednesday, October 21, 2009

Fingerprinting to prove ID online

I hope they will not introduce fingerprinting recognition system as described here as I have yet to encounter one that worked reliability on me - from immigration to notebook. This part is true:
"The public is sending an important message to governments and the private sector that they are willing and ready to use sophisticated technology in order to protect themselves against these types of threats."

But that does not mean systems out there are "sophisticated". I am willing to be their beta tester anytime.

Difference between expert programmer and novice

Very succinctly put:
An expert can tell a non-expert to check for such conditions, and with those specifications, the non-expert can probably code them, but only the expert anticipates them. Just like driving, what makes a good programmer is not only the ability to solve the problems that occur, but the ability to foresee (and avoid) problems that haven't occurred yet. Unfortunately, experts learn how to do that by making mistakes. It's a sad commentary on the human condition. Each generation acquires expertise primarily by repeating the mistakes of the past generations. To paraphrase Neils Bohr, "An expert is someone who has made all the possible mistakes in a very narrow field."

But when you're riding in a car with a novice driver, you'll probably appreciate P. J. Plauger's version more, "My definition of an expert in any field is a person who knows enough about what's really going on to be scared."
Unfortunately, many novice developers or ones that have just acquired a taste of a new technology immediately delude into writing something only an expert is capable. It does not matter if it is just to store data in a file as illustrated by the example used. Or using COM, C++ framework such as ATL/STL, .Net or Java.

Many development managers lacking the experience and expertise fail to distinguish between act of stupidity and stroke of an expert, thus concur blindly allowing novice to use their product as the training ground, often leading to failure to exploit opportunities and creating laughable products.

Often these managers confuse the expert's time and effort to "foresee (and avoid) problems that haven't occurred yet" as being a case of gold plating and then wondering why they are having recurring problems, lack of respect and trust from their customers, and complaints.

Tuesday, October 20, 2009

Tools to help you to make your code secure

Microsoft has released two tools BinScope and MiniFuss.
these tools to show you how easy it is to use them to improve the security of your software. BinScope Binary Analyzer is a Microsoft verification tool that analyzes binaries on a project-wide level to ensure that they have been built in compliance with the requirements and recommendations of the Microsoft Security Development Lifecycle (SDL). At Microsoft, use of BinScope is a requirement of the Verification Phase of the SDL.
The best way to learn them is to start from this article.

Sunday, October 18, 2009

Does NBN guarantees high adoption of Internet?

Is it a futile exercise to equate speed of Internet with high adoption? This is a question recently asked in US when confronted with this issue. According the newspaper article:

And maybe that won’t change, no matter how many social workers knock at their doors, and no matter how many years pass after Internet service has come to be accepted by their neighbors as a utility as essential as water and electricity. South Korea’s experience as a broadband pioneer is suggestive. The task force looked at 22 countries with broadband plans, seeking best practices that were well suited to the United States, and South Korea’s broadband initiative was of particular interest.

In 1999, South Korea began to help low-income and elderly households get PCs and become connected, and the outcome could be described as quite successful: “Today, 83 percent of households in Korea have adopted broadband access,” the report says. But one can also look at the remaining 17 percent and wonder what has prevented those households from getting online, despite the strenuous efforts of a government that has been a world leader in the broadband race.
A worthy lesson for promoter of NBN (National Broadband Network).

Friday, October 16, 2009

Amateurs at work

This is funny. Looks like someone does not even the basic physics.
Unfortunately Siemens trains draw more power than they're getting and they've been unable to move, so other trains can't get through to move all those people

Saturday, October 10, 2009

I just love this quote...

Some times ago, I by accident came across this quote by a Poet Janet Minor:
"I have a spelling checker
It came with my PC;
It plainly marks four my revue
Mistakes I cannot sea.
I've run this poem threw it,
I'm sure your pleased too no,
Its letter perfect in its weigh,
My checker tolled me sew.
I frequently come across code that resembles something like this passage; all syntactically correct but full of runtime error.

Saturday, September 26, 2009

Toxic bosses

According to Human Synergistics' report, toxic boss
encouraged staff to ''fit the mould'' at the cost of new ideas.

''This compliance approach to management crushes any spark of creativity or innovation,'' he said.

''Quite frankly, to encourage conformity in the current climate is business suicide.''

Sounds familiar indeed. How to recognise a toxic management or manager? Here are some of the signs

Moody, aggressive, unpredictable, incompetent, always blaming other people. A compulsive liar with a Jekyll and Hyde nature, the individual, male or female, is always charming and plausible when management are around.

Toxic bosses and toxic managers prevent staff doing their jobs and prevent employees fulfilling their duties. They thrive in a toxic work environment. Unpredictable moods, conflicting demands, inconsistent orders, random decision-making, inability to plan strategically, inability and unwillingness to communicate and co-operate, obstructive ... the list goes on. If management suddenly appoint a toxic boss as your manager, you'll realise that toxic shock syndrome is not just a female condition. If you've got a toxic manager, your problems have just begun. And they won't get better.

Spot on and very true observation.

Sunday, September 20, 2009

Is Chrome Browser that crash hot?

Lately, the Internet is raving about the Chrome Browser from Google. While there are some features that I like and are better than Firefox and IE, it has problem in handling basic layouts.

This is the portion of a normal page on a small screen Fujitsu P1510 running with 120DPI settings when viewed by IE6:

The same port of the same page is rendered by Firefox v3.5.3 and captured as follows:

Notice the graph has been incorrectly laid out covering part of the text. Below is the same portion rendered on Google Chrome
Chrome suffers the same layout problem as in Firefox. So far the only browser that handles this basic layout correctly is the 'ancient' IE6 browser, despise so much hot-air being pumped into the Net about Chrome's JavaScript superiority.

Is it just pure hype? The figures don't lie.

Wednesday, September 16, 2009

Hunting Trojan/Virus experience

Several days ago, I was asked to deal with a Virus/Trojan infection situation.

The machine has AVG8 installed but seemed to be unable to protect the Trojan attack. I know with the right kind of anti-Trojan/Malware programs in hand one can make light works in eliminating them. Or could it?

This blog message is not so much about which Anti-Virus program is better than the other but is a collection of experience gained from hunting down a number of Trojans. It also contains description on how best to protect oneself from being infected and secured practices that were actually put to test in slaying the Trojan.

It is most unfortunate that different anti-virus program uses different name for the same Trojan and Virus. I am using Avira and it has identified the Trojans I am confronting as TR/Dldr.FraudLoad.fmb and TR/Crypt.ZPack.Gen. Others like AVG8 calls them SHeurs.BDEF. These are classified as downloader and in particular the FraudLoad is a fake anti-virus often called Scareware that causes the infection.

Below are some of records of my experience and lessons learned.

Always use offline Anti-Virus download link instead

Many Anti-virus program has now switched over to downloading a small stub download program and with which then downloads the remaining components. Do not use this stub program if you want to inoculate the infected machine offering it some protection because this kind of program requires a connection to the Internet, see the attack description below.

Thankfully AVG8 has offer a offline download link which allows one to download the full version.

TR/Crypt.ZPACK.Gen spreading infection mechanism

This trojan utilises the Microsoft's provided AutoRun mechanism to spread the infections to other machine. This is how it is done:
  • A process located in C:\Recycler\<SID>\WmiPrvse.exe launched and attached to Explorer.exe is responsible for spreading, where <SID> represents the SID of the user.
  • The Trojan creates an entry in HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon!Taskman=C:\Recycler\<SID>\WmiPrvse.exe and the trojan causes Explorer.exe to query this registry entry periodically. You should remove this as Taskman is not a valid Microsoft Windows entry.
  • When Windows senses a new USB device is plugged into the machine, this evil process will create a fake \Recycler on the USB drive even when it is formatted with FAT/FAT3 partition.
  • It is also structurally incorrect designed to hide the malicious code using a well known folder name and to fool people.
  • It then copies the malicious code called Explorer.exe to the fake recycler folder.
  • It creates an autorun.inf file on the root directory that contains instruction to launch the malicious code with the help of Microsoft's Autorun support when it is inserted into another machine, thus completing the spread.
  • No doubt this Explorer.exe will contain code to load it into some less obvious location to burrow into that machine to infect it.
I have always thought of disabling autorun permanently is sufficient to protect oneself. This is proven to be half correct.

Disabling autorun on a machine only disabling the launching mechanism that was used by malicious code to infect the machine. It does not prevent the malicious code already entrenched in an infected machine from infecting a USB drive making it the unwitting carrier of the malicious spreading code. Therefore it is so important not to plug a USB drive into any machine that
  1. You do not know if it has autorun enabled
  2. If the USB Drive carries the attacking code.
If you do not know, hold down the shift key while inserting the USB Drive into the machine and maintain holding it for a minute or two. This is will stop Windows from executing the instructions in the autorun.inf file.

Afterward make sure you scan it on a machine that has autorun disabled to ensure that it is not a carrier.

After seeing this and examining the content of the autorun.inf, it is certainly dicing with danger in leaving autorun enabled on all drives; it must therefore be disabled.

This is the content of the fake Recycler folder captured on the USB drive I was using it (a different USB drive from the tools carrier) to retrieve data from the infected machine.

Volume in drive K has no label.
Volume Serial Number is AE6B-BD53

Directory of k:\recycler

11/09/2009 06:05 PM <DIR> .
11/09/2009 06:05 PM <DIR> ..
12/09/2009 11:55 AM 64 Desktop.ini
12/09/2009 11:56 AM 106,496 explorer.exe
2 File(s) 106,560 bytes
2 Dir(s) 112,531,456 bytes free

Use a write-protected medium to carry tools

My practice is always to use a USB Drive that has hardware write-protection mechanism to transport tools to analyze the infected machine preventing malicious code from subverting the tools. When that is not available, I frequently use a SD-Card which always has the hardware lock mechanism to protect my tools and hosted it in a SD-Card reader like this.

The above observation proves that a write-protected USB drive is a must have device in carrying out investigation.

Furthermore, it is highly desirable to have tools that
  • do not have to installed into the target machine.
  • runs from a write-protected device
  • run as command-line utility as they can then be chained into one submission.
  • Do not need the access of the Internet during installation.
Sadly not one anti-virus scanner meeting the above stringent requirement. The Panda Command line scanner one comes near, except that it needs to write to the device. Avira also has one but to get the full benefit one needs to supply the licence key to it.

What does TR/Dldr.FraudLoad.fmb do?

The purpose of this trojan is to download malicious payload and is believe to belong to a class of software called Scareware to allow it to gain a foothold of the machine. It monitors if the machine is connected to the Internet and if not it becomes dormant. Hence I exploited this behavior to study this program and to defeat it. This is a record of its evil doings:
  • Downloads the payload, called windows_update[1].exe into the temporary internet file directory. The numeral inside the bracket may be different.
  • It creates a copy of itself in the %Temp% directory with a file name of this format [0-9][0-9][0-9]\.exe, e.g. 126.exe, and these numbers are randomly generated.
  • It then launches this program, say the 126.exe, to begin the attack.
  • The program then checks to see if system set up is in progress by examining the HKLM\System\SystemSetipInProgress registry value.
  • It also seems to have scan of which IE patches have been applied.
  • It also check for the presence of other fake anti-Virus programs such as AntiVirusXP, RealAV, AVR.
  • It also disable the ability for the user to launch the Task Manager from the task bar by setting this HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System!DisableTaskMgr=1. Hence to study this trojan you have to launch the TaskManager before connecting the machine to the Internet.
  • It creates the following named values NoSetActiveDesktop, NoChangingWallpaper, NoActiveDesktopChange intending on controlling the desktop in this registry key: HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer.
  • It copies itself as winupdate.exe to C:\Windows\System32. I have managed to disrupt this trojan's progress by using a custom built program that hold a file of this name opened with deny share access attribute before the machine is connected to the Internet and maintaining that hold during the attack. It failed to copy the attacking code to this directory.
  • It then creates the following registry entry intended on launching this malicious code when the machine is restarted: HKLM\Software\Microsoft\Windows\CurrentVersion\Run!WinUpdate.exe=C:\Windows\System32\WinUpdate.exe.
  • The program with the 3-digit name, like 126.exe, then launches winupdate.exe and drops out of the scene. The Trojan do not attempt to delete the instance of this file with a 3-digit name in the %Temp% directory, not very smart.
  • Winupdate.exe then register the malicious COM component called C:\Windows\System32\WinHelper.dll by calling Regsvr32 /s.
  • It also looks for C:\Windows\System32\AdvancedVirusRemover\PAVRM.EXE, a well known fake anti-virus program that is in fact a virus.
  • Winupdate.exe, then launches fake warning of malicious code detected and advising user to press the balloon to download protection code, which is nothing more than a ploy.
  • It also attempts to shut down CMD instances but failed to take care of Command.com instance, which I exploited this mistake to regain control.
  • It also attempts to block launching of other GUI applications until this winupdate.exe is terminated.
  • It also then creates a file with 2-digit name, like 41.exe, of 0 byte in C:\Windows\System32 whose purpose remains unknown.
  • Winupdate.exe remains running to disrupt the desktop and one can only regain control of it by terminating this process. PsKill is the ideal tool to do this.

Are these two Trojans related?

On the infected machine, AVG8 did not seem to offer any protection at all. There are even signs that they subverted Spybot Search & Destroy because their scanning and TeaTimer.exe offering only token protection. My observations of the operations of these Trojan were made while they were in operations showing little effect in detecting these key files containing malicious code.

I suspect these trojans are either related or utilizing one single malicious process to attack the machine. They seemed to be using C:\Recycler\<SID>\WmiPrvse.exe as a main source of maintaining control and attack. Because it is controlled and held opened by Explorer.exe it cannot be terminated easily.

The way I eliminated this process is to use DOS command chaining technique as follows:
pushd C:\Recycler\<SID> & j:\PsKill Explorer & del /A:S wmiprvse.exe
where <SID> represents the SID of the user. This sequence of commands does the following:
  • Change the directory to where wmiprvse.exe is located
  • Terminate the Explorer process that is holding onto the wmiprvse.exe process
  • Delete the malicious code which is marked as a system file called WmiPrvse.exe.
Bear in mind that when I submitted these command, the process WinUpdate.exe was not running and it was not connected to the Internet.

Once this malicious code is removed and terminated, the system becomes normal and reinstallation of AV is possible allowing them to do the job to get rid of files such as WinHelper.dll and other relatively less stubborn malware lurking around.

Dangerous & foolish not using LUA

My experience in this involvement further vindicates my view that people not using LUA is really asking for trouble. It also reinforces my view that it is dangerous leaving Autorun enabled.

Sure one can rely on Anti-Virus to protect oneself but can it be all that effective? What about the window of opportunity available to exploit code that is not yet protected by Anti-Virus when your machine's operating system's security defense shield is turned off?

As reported above, all those exploits they used are so simply and effectively blocked by not running in administrator's account. That's the defense shield, if allowed to operate, will block the above exploit without even the aid of anti-virus program.

Sure, it can still disable the task manager from being invoked but it could not succeed in planting anything more malicious in system folders and registry keys. All it can do is to inconvenient you that dirty deed could easily be removed.

It is impossible to determine if the ACLs of the system files and registry areas have been tempered with prior to the infection or as a result of the attack. A detail scan using AccessChk of the vital areas show that it is impossible to switch the just rescued machine to operate effectively in LUA mode without a full reinstallation. That part of security appears to have been irreversibly damaged.

Monday, September 14, 2009

Allowing Non-Administrators to receive update notification - in XP SP3 or Home

In XP Prof SP2, there is an option that you can set using GPEdit.msc to allow non-Administrators account to receive update notification. This is an extremely useful features in the following set up:
1) The machine is set up to run in LUA and
2) You have changed the Windows Automatic Updates from automatic mode to "Notify me but don't automatically download and install them" option.

In XP Prof SP3, this option is removed from the GPEdit template and hence one cannot set that with the policy editor. What a pity!

To allow non-Administrators to receive update notification in that environment, you need to do registry editing to defined the following registry key and named value:

This should allow non-administrators account to receive update notification. They can select which to install but often that requires a reboot.

Thursday, September 10, 2009

Bosses return to 1950s management style

This management style produces:
"We have too many workplaces which are toxic, by toxic I mean people aren't valued.

"Every organisation says 'people are our greatest asset' - my immediate response to that is then why do most organisations treat their employees like liabilities?"

I did not think it was a 'return to 1950s management style' as it seemed to be the modus operandi of the company I once worked for even before the Global Financial Crisis as it exhibits this trait:

They're also micromanaging and bossing their staff around, rather than engaging with them, she says.

"It sends a signal to employees that 'I don't trust you can do the job without being closely supervised', it equates not seeking input from anybody below senior executive level," she says.

Terrible UI in this Thunderbird feature

While Thunderbird (ver has Junk filter that allegedly using Bayesian technique, its operations are not as robust as others, particularly in the failure to explain why a message is classified as spam.

The other most annoying feature is represented by this dialog box with total neglect of good user interface design:
Now any normal users, other than the developer who wrote this, will instinctively press the 'Clear log' button to clear the log being shown. Not really! This is not how it is supposed to work.

You have to first select the log content, such as Ctrl-A, and then press the 'Clear log' button. I am puzzled why that button is enabled when no content is selected? Doing so with guide the user to use this properly.

As for the content of the log, it is as useful as saying nothing! I would like to see a spam rating much like that presented by SpamBayes.

Thursday, August 20, 2009

Is application of McCabe Complexity just another length reduction technique?

I was reading a book by Tom Demarco [1] that has made some comments about McCabe Cyclomatic Complexity [2] that I believe indicate he has misread the theory and showing off his lack of knowledge in this area. He said this:
... But when you let it guide you to produce alternate designs with lower values, you almost always end up dividing the modules into smaller ones. Now that is a pretty sensible thing to do in general, but it is not really a complexity reduction technique. It's a length reduction technique. You could do the same thing with a much simple metric, like line of code: If a module has too many lines divide it up. V(G) is, most of all, a length metric. Longer modules have higher V(G). If you factor out the hidden effect of length, V(G) is relatively meaningless.
Before I discuss many incorrect assertions in the above paragraph, Tom DeMarco also made the following remark:
... Tom McCabe's Cyclomatic Complexity - also called V(G) for some reason now forgotten.
Well sorry DeMarco, it has not been forgotten. For DeMarco's information V(G) is a standard notation used in Graph theory [3] and it stands for vertices of G. It is not a notation invented by McCabe. In fact, possibly the lack of familiarity with this notation and the graph theory explain why DeMarco makes such a rash and incorrect observation and from these mistakes one can safely assume he has not even used McCabe Complexity metric in even toy projects.

Let's consider his assertion: "It's a length reduction technique. You could do the same thing with a much simple metric, like line of code". Could you? What is better to start this debate than by stating Tom McCabe's expression of V(G) [2]:
V(G) = e - n + p
e = number of edges in a graph
n = number of vertices
p = number of connected components.
A graph is not about the number of assignment, line of expressions or function calls but it is made up of branching and logical expressions that causes transitions from one block of code to another, thus the edges. Where is line of code in the above expression, Tom DeMarco?

The following block of code gives some idea of complexity & LOC:

public static Int32 f1( Int32 a, Int32 b, Int32 c, Int32 d, Int32 e )
Int32 t = a;

t = a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + 3;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
t = t + a + 2 * b + c + d;
return t;
Which contains 23 statements, thus LOC=23, but according to McCabe, it only yields a CC=1. It does not matter how complex or how simple is the expression on the right hand side of the assignment it remains a CC=1. It could be all repeatedly initializing t to say 0 or it could be a very complicate polynomial expression of any length involving the function arguments CC remains 1 while LOC can increases to very large number.

No matter how Tom DeMarco slices and dices the above block, even down to functions with one line, thus LOC=1, CC is still 1. Hence this invalidates his wild claim.

Now consider this block containing 4 statements, thus LOC=4:

public static Int32 f2( Int32 a, Int32 b, Int32 c, Int32 d, Int32 e )
if( (a == b && (c != 5 || d != 6 ) ) ||
(c == e && (e == 2 * a && c > b && d == 3 * a ) ) )
return 23;
return 0;
Which yields a CC=9.

If Tom DeMarco's assertion that "You could do the same thing with a much simple metric, like line of code" is right, then the first block of code is more complex than the second, according to DeMarco. Clearly that is not true! It does not take much brain power to scan through say 23 initialization statements but to come up with an idea of what is doing in the second block takes a bit of comprehension.

In general, the technique to reduce CC is to make the code more readable to human as machine could not careless by rewriting the logical or control expressions using meaningful function names so that instead of just stating the logical expression in its raw form, the function names help the reader to read the meaning of the expression. It is kind of like literate programming. Or one could use this to make your code more readable and to reduce the CC.

To prove this point and to show that CC and LOC are unrelated, let's refactor the function f2() above in accordance to the recommendation to produce f3() as follows:

public static Int32 f3( Int32 a, Int32 b, Int32 c, Int32 d, Int32 e )
bool danger = ( a == b && ( c != 5 || d != 6 ) );
bool risky = (e == 2 * a);
bool makesLotOfMoney = (c > b && d == 3 * a);
if ( danger ||
( c == e && ( risky && makesLotOfMoney ) ) )
return 23;
return 0;
This function has a LOC=7 and increase from 4 but a reduction of CC from 9 to 6. In according to DeMarco's claim, I have in fact increases the complexity read LOC. This simple experiment clearly refutes DeMarco's unsubstantiated wild claims and his remarks should be discarded.

The above demonstration clearly shows the lack of relationship between LOC and CC. As a result, we can safely discard DeMarco's assertion as being without foundation.

I have great respect for many of his other writings and therefore I am shocked by so many false statements in just one paragraph of this book [1].

[1] "Why does software cost so much? And other puzzles of the information age" Tom DeMarco, Dorset House Publishing 1995

[2] "A Complexity Measure" by Thomas J. McCabe, IEEE Trans. Software Engineering, Vol SE-2, No. 4, Dec 1976, pp 308-320.

[3] "Discrete Mathematics, 2nd Edition", K.A. Ross and C.R.B. Wright, Chapter 8, Prentice-Hall International Editions, 1988

Monday, August 17, 2009

How to register a TLB?

During one conversation, the topic of how to register a TLB in com deployment came up and in the past, I used a less widely publicized program called RegTLIB.exe and from memory, it was installed into my machine as part of Word upgrade or Service Pack or something like that.

Since then, I have lost this program. It is rare to simply distribute the TLB and normally it is better to be embedded into a DLL, a kind of resource only DLL, to leverage the packaged registration script so that user can use the well known system tool Regsvr32.exe to register the TLB.

You can still distribute the TLIB for development but you do not register it unless you use importlib statement in your COM's IDL to import a foreign type library. There is a caveat between importlib and #import statement in developing your COM IDL and it is this:
Note that the imported library, as well as the generated library, must be distributed with the application so that it is available at run time.
The emphasis is on the last four words - available at run time. Failure to do that will cause a run time error. If you are not sure, use OleView to examine your DLL or TLB to see if it uses importlib and how it is used.

Anyway for those that have used importlib to import typelib rather than importlib of a DLL containing the type library, you therefore have to register the type library using a not very commonly available tool. Hence if you are developing COM component, even if you are publishing common interfaces, put the tlb inside the DLL and makes life easy for everyone. While importlib of a DLL does not require you to register the imported type library, you still have to register the imported DLL using RegSvr32. The difference is basically which tool you use to make the type library available at run time - RegTlib or Regsvr32.

In those situations you must register the type library, a lifeline is being offered by .Net framework 2. Go to "%windir%\Microsoft.net\framework\v2.0.50727" and you will find a program called RegTLibv12.exe. Do not expect to find too much information on how to drive this program and MSDN site is devoid of anything even though it has been mentioned several times in Aaron Stebner's blog.

Experimentations with this program tells me this:
* To register MyComStuff.tlb do this:
RegTlibV12 MyComStuff.tlb
* To unregister MyComStuff.tlb do this:
RegTlib -u MyComStuff.tlb
* This program, while distributed with .Net Framework 2, does not use any supporting DLL in the "%windir%\Microsoft.net\framework\v2.0.50727" directory and hence you can safely use it on a machine without .Net 2. Besides, it is a native code program.

Monday, August 10, 2009

WSJ trying to annoy readers the dumb way.

I have been collecting RSS feed from my WSJ subscription using the following location:

Randomly, WSJ returns articles that really annoy their readers. For example this article appears black over most of the text like this:
Don't dispair, WSJ is not all that smart. To read this, simply type Ctrl-A to select all the text and there you are:
If you do not want to do Ctrl-A, simply delete "public/b" from the URL and you can read it again.

I have no idea why WSJ is doing this kind of stupid thing just to annoy people, could it be Rupert Murdoch, owner of WSJ, is experimenting with different way to annoy people into paying for his online information?

Tuesday, August 4, 2009

Do software systems age analogously to humans?

Having worked in software industries for a long time, this question, posted in an introduction to a paper by the noted and respected Computer Scientist, David Parnas, in a book seems kind of obvious to me and no doubt to many practitioners. However, there are software companies that still hold this belief of "Design once last forever" philosophy and need not change at all. They are also unfortunately pursuers of this illusive Silver Bullet that another noted and respected scientist, Fredrick Brooks, has warned. They naturally do not believe software can age.

Having worked in such a nescient organisation, I am interested to read what Parnas has to say when I come across his paper "Software Aging". There are specifics that I believe worth mentioning here.

One of the good ways to slow down or even to deal with changes, is to design to cater for changes using well-known design principles. In his research and experience, sadly "I do not see much software that is well designed from this point of view" and he gave some of the reasons why:
... The principle is simple; applying it properly requires a lot of thoughts about the application and the environment. The textbooks do not make that clear.

Many programmers are impatient with such considerations; they are so eager to get the first version working or to meet some imminent deadline, that they do not take the time to design for change. Management is so concerned with the next deadline (and so eager to get to a higher position) that future maintenance costs don't have top priority.

Designs that result from a careful application of information hiding are quite different from the "natural" designs that are the result of most programmers' intuitive work.....

Programmers tend to confuse design principles with languages.... Even worse, they think that one has applied the techniques, if one has used such a language. [Sadly, in my professional experience many managers are the big champions of this (mis)belief creating massive software problems and wastes.]

Many people who are doing software development, do not have an education appropriate to the job.
Italics text are my comments.

One of the topic that he commented on that I share passionately that is often not done in Software Industry as compared with others, such as other forms of engineering and medicines is the topic of reviews despite its effectiveness supported by abundance of well publicized materials. Robert Glass even proclaims that it is "being a breakthrough as anything we have". Parnas said
it is quite astonishing to see how often commercial programs are produced without adequate reviews. There are many reasons for this:
  • Many programmers have no professional training in software at all. Some are engineers from other fields; some are "fallen scientists" who learned programming incidentally while getting education... In many of those areas, the concept of preparing and holding a design review is nonexistent.
  • Even among those that have Computer Science degrees many have had an education that neglected such professional concerns as the need for design documentation and reviews....
  • Many practitioners (and many researchers) do not know how to provide readable precise documentation of a design, as distinct from an implementation. No precise description, other than the detailed code, is available for review. Design reviews early in a project, when they would do the most good, are often reduced to chat sessions....
  • Much of software is often produced as a cottage industry, where there are no people who could serve as a qualified reviewers ....
  • Software is often produced under time pressure that misleads the designers into thinking that they have no time for proper reviews.
  • Many programmers regard programming as an "art" and resent the idea that anyone could or should review the work that they have done.
I also share Parnas' concern that "it is common to hear a programmer saying that the code is its own documentation; even highly respected language researchers take this position, arguing that if you use their language, the structure will be explicit and obvious"

My argument with proponent of this view is that code does not document a design; it merely documents an implementation of a design decision. There are plenty of materials a designer has discarded that are vitally important to the maintenance of the implementation but are not and cannot be translated to code. For example, technologies or algorithms that a designer has considered by discarded and for what reasons are not found in code and cannot be for practical reasons. Design decisions why it is done this way and not another are not found in code; in fact, lack of supplemental information that we called documentation one could be misled from reading code. They cannot be deduced from code no matter what language one uses or how clever one uses the language construct to aid documentation.

Parnas went on to say "Even if we take all reasonable preventive measures, and do so religiously, aging is inevitable." and in that paper he offers many practical advices to deal with software aging, including "start taking documentation more seriously".

Daniel M. Hoffman and David M. Weisss, "Software Fundmentals - Collected Papers by David L. Parnas" 2001. Chapter 29 "Software Aging"

Robert L. Glass, "Facts and Fallacies of Software Engineering", page 104

Sunday, August 2, 2009

Customers/Consumers of electronic services always considered last

Recent report of the way Amazon resolving an essentially business transaction with its supplier just simply highlights the power of supplier of electronic services over customers or consumers that this kind of unfettered power is not permitted in other forms of service provision.

Why should something rendered as 1-and-0 be allowed to be treated any differently from something tangible? If it is tangible, Amazon will be prosecuted for break-and-entering and thief. But when it is delivered in 1-and-0's, it escapes scot free. Why is this be allowed or difference exist? Apple is a master in this kind of kind of practices.

This kind of attitude - it is better to get the customers to foot the bill for the provider's problems or mistakes - is wide spread in software world and it is time the license should be written to provide a more level playing field, subjecting to commercial software to public scrutiny is a start.

Thursday, July 30, 2009

Cross AppDomain WinForm implementation

In a .Net solution, one often finds the use of plug-in pattern to support extensibility. This design pattern is so prevalent that the BCL team even provides its own add in architecture, supported by a number of namespaces prefixed by System.AddIn in Fx3.5 and is known as the Add-in pipeline.

One of the reasons for supporting Add-in loaded into a separate AppDomain is to allow the container to constrain the add-in with some form of security policy. Another reason, is to be able to unload all the assemblies used by the Add-in and to recover resources if it is being loaded into a separate AppDomain.

When these add-ins are just computational devices then one needs not take too much special care in programming them other than to ensure that the class is remotable across AppDomain. This generally means that it should derive from System.MarshalByRefObject.

However, if these add-ins are UI-rich devices using say System.Windows.Forms.Form, then one needs to take special precaution in programming them as Form object is not always marshal-safe.

This blog is to concentrate on this very issue - how to write UI-rich assemblies using WinForm that can live in a separate AppDomain?

What is the problem? Isn't a System.Windows.Forms.Form is a System.Windows.Forms.Control, which is in turns derived from System.MarshalByRefObject, and hence it should be able to marshal across Domain boundary? While all these are true but it does not necessary follow that a Form can be marshaled across a domain boundary.

In a private correspondence with Microsoft, this is their comment on this issue:
Windows Forms only supports isolating top-level windows via app domains. It does not support parent-child relationships across domains. Many people have assumed that because Control ultimately derives from MarshalByRefObject that it can successfully be remoted; this is not true. Certain interfaces on a control can be remoted across domains, but the control’s API itself does not support remoting. When you see exceptions stating that the object cannot be remoted because it isn’t serializable, what you’re seeing is that someone has tried to cast the remote proxy to Control.

If you scan the internet you will frequently encounter question asking why they have SerializationException when they try to remote WinForm across AppDomain.

Therefore, just because a Control supports MarshalByRefObject, you should not simply pass a Control across AppDomain. Sometimes this 'works' but it may not works all the time.

What is the recommended way?

According to Microsoft, you should always create an interface to allow you to operate the remoted WinForm from one app domain rather than casting the object obtained from AppDomain.CreateInstanceAndUnwrap() to a Form object. From the above statement, it is clear from Microsoft that it is this casting into WinForm, that is causing the exception.

Here is a sample code from Microsoft to illustrate this concept:

public partial class Form1 : Form, IDialog
public Form1()

private void button1_Click(object sender, EventArgs e)
AppDomain d = AppDomain.CreateDomain("Second Domain");

IDialog dialog = (IDialog)d.CreateInstanceAndUnwrap(typeof(Form1).Assembly.FullName,


public interface IDialog
DialogResult ShowDialog();

The idea is not to cast to WinForm as shown in the above highlighted line.

If you need to pass one's Form from one app domain to another so that it can establish the parent-and-child or owner-owned relationship, you need to, according to Microsoft:

Generally I would stay way from passing Windows Forms object across domains unless you know what the other side of the domain is doing with the form or control. The ShowDialog API requires an IWin32Window to provide the handle (that’s what the parameter type for owner is setup to be). You can implement this with your own marshal by ref object and have it return the form’s Handle property.

The above statement was clarified further with Microsoft and the recommendation is to create a carrier class which is derived from System.MarshalByRefObject and that it implements IWin32Window interface. Thus allowing the Control.Handle to be marshaled across the AppDomain.

The rationale according to Microsoft is to prevent any chance that Form.ShowDialog() may use some intelligent to detect if the given IWin32Window belongs a Control object, which is not marshal-safe across App Domain.

Furthermore, it is not recommended just to marshal a Control object's IWin32Window across App Domain as Control contains things not marshal-safe.

As a caveat: Control.FromHandle() cannot be used in another App Domain to regenerate a IWin32Window or Control from the Handle, which is a IntPtr.

The reason is that, according to Microsoft, Control.FromHandle() relies on static data, which is per-Domain specific. Hence when you pass a Handle, IntPtr, from one domain to another, when Control.FromHandle() is called by the recipient domain, it will produce a null reference object.

How to pass establish owner-relationship across AppDomain for Modeless form?

The above discussion is to handle modal form across AppDomain. But how to implement modeless form that lives in a separate AppDomain?

When a form has an owner (only top level form, ie System.Windows.Forms.Form.TopLevel == true, can have owner), it affects the z-order in relation to the owner. The owned form is always shown above the owner form.

If you simple want a Top level window, you do not have to define the owner.

If you want to define owner-owned form relationship, the technique discussed above cannot be used directly. This is because System.Windows.Forms.Form.Owner is of type System.Windows.Forms.Form and given the fact that Form is not safe to be marshaled across AppDomain, you need a different technique to establish the owner-owned relationship.

According to Microsoft's advice, you have to resort to using P/Invoke to get the job done. In according to the recommendation in previous section you continue to marhal an object that implements IWin32Window across the AppDomain. So you use this class to carry the owner's Handle across the AppDomain.

To establish the owner-owned relationship, you use the Win32 API, SetWindowLong() or SetWindowLongPtr(), for Win64.

Below is the C# code to establish the owner-owned relationship:

public sealed class OwnerWindowHelper
private OwnerWindowHelper() {}

[ DllImport( "user32.dll", EntryPoint="SetWindowLongA", SetLastError=true ) ]

private static extern IntPtr SetWindowLongPtr(HandleRef hWnd, int nIndex, HandleRef data);
const int GWLP_HWNDPARENT = -8;

public static void SetupOwnerWindow( HandleRef hwndOwner, HandleRef hwndOwned )
IntPtr result = IntPtr.Zero;
result = SetWindowLongPtr( hwndOwned, GWLP_HWNDPARENT, hwndOwner );
if( result == IntPtr.Zero )
int err = Marshal.GetLastWin32Error();

if( err != 0 )
throw new InvalidOperationException
( "Failed to establish owner-owned relation." );

That's it. If you doubt that one has to use P/Invoke to get the job done, try to have a look at the IL code in System.Windows.Forms.Form.Owner and trace the logic and you will arrive at similar conclusion.

Saturday, June 27, 2009

Is it eBay or eBait?

The online auction site, eBay, is becoming more like eBait to both buyers or sellers of goods. Despite eBay's best effort to stamp out frauds, the customers are still being fleeced and to fend for themselves. Shame.

Friday, June 26, 2009

Arrogance to the (Apple) core

This report on the release of Apple's iPhone shows Apple's arrogance to the core. I wouldn't be bothered - it is just a phone and my $50 makes as good phone call as something that holds the owner hostage.

Wednesday, June 24, 2009

Microsoft Security Essentials - is it worth the hassle?

Microsoft has released a beta version "free" Anti-virus suite to replace their defunct OneCare program. I am puzzled why Microsoft demands so much from user:
Interested users should note that installing MSE requires that the would-be user's system passes Microsoft's Windows Genuine Advantage anti-piracy tool, which checks to make sure it is being installed on a licensed version of Windows. Would-be users also will need to register for or already have a free Windows Live (or Hotmail) account in order to download the program.
Just to get a beta version! Doesn't Microsoft know that you can get free AVG, Avira and Avast without any question asked and installed in pirated or genuine Windows alike? All of them have well established credentials.

So I guess this MSE is just another waste of time, kind of like IE7/8 and better dismissed without wasting your time.

Monday, May 18, 2009

Why would some company want to project having a blurred vision?

I have seen companies wanting to project themselves as having clear vision but have not heard of one wanting to advertise itself as having a blurred vision until I was shown the one.

See for yourself. Below is a company's propaganda poster, doctored to hide the company name & logo saving it from embarrassment. I was told it was plastered all over the hallway prominently.

Perhaps, there is some truth in that poster!

Thursday, May 14, 2009

Commercial software subjected to public scrutiny

Bruce Schneier reports a court case in which the accuracy or quality of the embedded software in an alcohol breathalyzer is being questioned in a court case and the court decides to subject the software in question to an independent proper assessment, i.e. a proper code review, despite protests naturally from the vendor.

For people interested in seeing a professionally compiled thorough code review can read the full report and a separate deeper analysis report. Both reports are very educational, particularly the second one.

When I am digging through this report, which I do not recommend people to print out the full 57 pages, it reminds me of the similarity in the quality (or lack of) in an Australian-made ERP software. To be honest, the ERP software is far worse by a large margin.

For example, it is not uncommon in the Australian-made ERP software to have far higher density of code exceeding the CC of 105, admittedly, though inexcusably, the ERP software has more LOC. I have personally seen CC higher than 150-200 after discounting the accuracy of the metric measuring tool.

Another issue identified by this review that is wide spread in this Australian-made ERP software is the frivolous and gratuitous use of global variables; this was caused by lack of training in good software practices, lack of reviews and aided by the development tool. In fact so wide spread that it was used as an excuse to avoid an architectural design correction exercise. In the company's view, it is much cheaper to let their poor users to foot the bill of their frivolous resources wastage, the result of its architectural flaws and ignorance, by paying much higher hardware costs.

Public review of commercial and proprietary software should be a normal public quality assurance process to safe-guard the welling being of the software consumers; it is similar to safety rating of cars or electrical appliances. Such public review would have unearthed the glaring mistakes committed by this Australian-made ERP system allowing the users to seek compensation.

Currently, the playing field is severely tilled towards the producers, as reported, allowing them to discharge all responsibilities and to take all rewards.

Companies have often invoked the commercial-in-confidence or proprietary IP excuses to escape such scrutiny. But this report stated in court that
Base One found that the code consists mostly of general algorithms arranged in a manner to implement the breath testing sequence. "That is, the code is not really unique or proprietary."
I doubt there are too many genuinely proprietary IP stuff in many today's commercial software. The more well established they are, the less they are and many are just a quilt of widely publicised algorithms poorly implemented to meet the so-called commercial dead lines.

In my opinion as a developers with over 20 years of experience, I believe those hiding being the veil of proprietary secrecy are too afraid to be caught using unsafe practices, not using industry best practices and ignorance of their mistakes in their own coding; the Alcotest did not even realise that they have committed buffer overruns and including others surprises in the published findings.

The review report attempts to nail down the reasons for the high CC has this to say:
source code appears to have evolved over numerous transitions and versioning, which is responsible for cyclomatic complexity.
While this is a likely cause, and is in agreement with my experience in the Australian-made ERP software, it only indicates both companies have a very poor software maintenance process. Most likely it is based on code-and-fix with little regards to refactoring during a bug fix phase.

The review findings and my own personal experience in this industry indicate that bad software practices are more universal with no geographical boundaries.

Saturday, May 9, 2009

Showcasing the genuine ones in financial hard time

Justin Brown decided to showcase those companies that stand by their staff in financial hard time by creating a web site. Well done.
"At the moment the world is all doom and gloom, recession, credit crunching and downsizing. This site gives you a chance to gloat that your business has not fallen victim to short-sightedness, that even through bad times you value your staff enough to keep them for when times are good."
Most companies only give lip-service when they tout that they value staff as assets but tough times sort out the sheep from the goats causing them to reveal their true selves.

Mincom, Pacific Brands and Vision Australia need not apply.

Sunday, May 3, 2009

Designing API - Bad API can really hurts

An article titled "API Design Matters" is a must read article for any one in charge of designing API and has this to say:
Good APIs are a joy to use. They work without friction and almost disappear from sight: the right call for a particular job is available at just the right time, can be found and memorized easily, is well documented, has an interface that is intuitive to use, and deals correctly with boundary conditions.

So, why are there so many bad APIs around? The prime reason is that, for every way to design an API correctly, there are usually dozens of ways to design it incorrectly. Simply put, it is very easy to create a bad API and rather difficult to create a good one. Even minor and quite innocent design flaws have a tendency to get magnified out of all proportion because APIs are provided once, but are called many times. If a design flaw results in awkward or inefficient code, the resulting problems show up at every point the API is called.
The article went on to provide a list of guidelines. It also offers the following top advice:
APIs should be designed from the perspective of the caller. When a programmer is given the job of creating an API, he or she is usually immediately in problem-solving mode: What data structures and algorithms do I need for the job, and what input and output parameters are necessary to get it done? It's all downhill from there: the implementer is focused on solving the problem, and the concerns of the caller are quickly forgotten.
This alternative definition requires the implementer to think about the problem in terms of the caller.
This recommendation is not dissimilar to the advice "Your users is not you" or another saying is "there are more users than developers".

The best way to deal with this as alluded in the article is to use TDD (Test Driven Design) to combat this. Let the customer, as suggested by the paper, to write the Unit Test code.

A good API reads correctly and sensibly in the user's code and not in the implementer code. Far too many 'designer' starts the API design from an implementation point of view concerning too earlier with the implementation details, which can lead to a break down in abstraction. APIs are the visible interfaces to these abstractions.

In component technologies that heavily relying on interfaces, it is important the consultants or designers begin the process on the interface.

Using UML diagram is a good starting point as you can quickly play out the scenario to see the effect. At the same time it can document the requirements (Activity/Use case diagrams), how it is to be used (sequence diagrams), or error states (State Diagrams). Then at a later stage, have executable documentation in the form of Unit Test code.

The second most import point in my mind is to strive for 'miminalist' approach:
The fewer types, functions, and parameters an API uses, the easier it is to learn, remember, and use correctly. This minimalism is important. Many APIs end up as a kitchen sink of convenience functions that can be composed of other, more fundamental functions.
This topic was given a detail treatment by Scott Meyers, "When it comes to encapsulation, sometimes less is more.". Or the YAGNI principle.

I once worked for a company that prides itself in designing kitchen-sink API, regardless if it is COM or pure C-style interface. Methods are thrown into any place it can stash regardless if they make sense. Management only interested in getting things out quickly and applying bums-on-seats resource allocation algorithm and the result speaks voluminously of the foolishness of this myopic style, for a long time.

The article touches on the issue confronting the immutability, a term not used by alluded to, which can cause "
crud that, eventually, does more damage than the good it ever did by remaining backward compatible.". When that happens, it is better to start again!

The paper correctly lays blame on education, particularly many developers are not interested or have the patience and time to learn the art and are only interested in getting something 'working' in the IDE. Experience is also overlooked when selecting someone to the task, as identified by the paper.

The example the author used to illustrate a bad API design touches on a topic that .Net/Java should have considered. The author complains about the destruction of the input parameter when using the Select() method and the API method was not dutifully documented.

In C++, you have const member function and const parameters to allow compiler to catch any misuse and to tell user of the consequence of calling the method. But this is sadly not available in .Net/Java. While you have out and ref qualifier but they serve a different purpose.

In .Net/Java, one cannot be sure what would happen to a parameter when you make a call; the method could change the state of the object, as illustrated in the example, it could take a copy of the data (cloning it), or it could hold onto the reference of the object. The latter allows the holding object to change the state of an object it has a reference to and that changes can then be reflected in some other part which has also holds a reference to this object.

All these unknowns require explicit documentation that not too many developers read and can make the API harder to use. My advice is if in doubt, use the "Learning Test" test pattern, which also has an effect of detecting changes in API's behaviour over time.

CLR does not have any support to make sure a method does not alter the state of an object; VB has a language-level construct but it is just a smoke and mirror.

On the topic of cloneable, this can be a double-edged sword. In defense of .Net, the general recommendation is not to implement ICloneable. One such problem is what if an inner class does not support ICloneable and the other is that the caller has no idea if a deep or shallow copy is used. In many way this is the flip side of C++ in which copying an object is a natural behavior.

"Test-Driven Development - by Example" by Kent Beck, Addison Wesley, 2004, Chapter 26, "Learning Test"

Blog Archive