Blog Home  Sign In RSS 2.0 Atom 1.0 CDF  

  def Softwaremaker() :
         return "William Tay", "<Challenging Conventions />"

  knownType_Serialize, about = Softwaremaker()

 Monday, January 31, 2005

If there is one guy who can do it, it is sure to be Mr Brains-and-Brawns...

You are a devil, Casey.

Monday, January 31, 2005 12:42:35 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, January 29, 2005

    This guy is killing me. Another excellent post from him here on how to extact a RSA Public Key from a Signed Assembly.

    Nice work, William.

    Saturday, January 29, 2005 1:47:59 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • Time and time again, I have heard many companies and people talk about how they want to adopt XML Services and (W3C) SOAP so that they can be seen moving with the times embracing Service Orientated Architectures.

    I have always stressed that it is a lot lot more than that. Just because all your applications can emit out SOAP and angle brackets and your consuming applications can "Add Web Reference" doesnt mean your business is in the realms of Service-Orientation.

    This article here puts it very nicely. It is a lot more than what most people think and it takes a longer time to understand and embrace it fully. It is very much in the business processes and very importantly, the understanding of it...and this takes a tremendous mindset change in the business thinking and culture.

    I took the liberty to quote a few snippets out:

    • "Some of the enterprises that are deftly moving toward a service-oriented architecture to exploit the potential of Web services are confronting challenges technology can't always conquer. Users say Web services still suffer from a lack of clear metadata definitions and the need for sometimes significant IT cultural changes. "
    • "Trimble learned that even using Web services, it isn't possible for the company to "gracefully and quickly" integrate systems gained in several acquisitions over the past couple of years because of the metadata problems, Denis said. "There's too much fluidity around data objects, [and] we fall back into our own nomenclature and begin to define business objects," he said. "Customer definitions are the most complex challenges for us. We support very different businesses. Our customers are major accounts, channels and end users, so it is difficult to have a one-size-fits-all definition." Until industry standards for metadata management mature, the company must tackle the metadata issues outside the SOA project, he said "
    • "But as the project has moved forward, it has been slowed by the lack of standard metadata definitions, which define and describe applications' data, "
    • "Learning noted that the migration to Web services required some cultural changes along the way, such as getting customers to change their mind-set about the way they use the system."
    • "Denis said that the company must create its own process for managing the disparate ERP systems' metadata because of a lack of tools that can automate the operation. The complex ERP network includes packages from SAP AG, Oracle Corp. and Siebel Systems Inc., some of which were gained via acquisitions."
    Saturday, January 29, 2005 8:52:29 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • Finally, after months of waiting, Microsoft's Enterprise Library is available for download. This is essentially Avanade's famous ACA.NET version 4 which now has a official Microsoft alignment.
    Saturday, January 29, 2005 12:59:58 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Friday, January 28, 2005

    Some of the folks in the Spore DotNet Usergroup got together one night to run a practical project. The idea behind the link is to build a bridge to access Visual SourceSafe over the internet. It was built successfully with the help of SCCBridge.

    Incidentally, SCCBridge relies heavily on SOAP and DIME for its purpose and it is therefore no surprise that Web Services Enhancements (WSE) 2.0 was heavily involved in use here.

    "Both the server and the client are written in C# in Microsoft Visual Studio .NET. In the project is used library SharpZipLib created by Mike Krueger (for more info see ). The algorithm for text files comparing was taken from The Code Porject site, and was written by Shankar Pratap."

    Friday, January 28, 2005 3:28:07 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • This has been floating around for some time BUT MSFT Corp has released an official statement here

    Since XQuery is expected to reach W3C recommendation only in 2006, it won't be shipped in the upcoming .NET Framework 2.0

    I guess people like me will have to live with XSLT and XPATH for now.

    Friday, January 28, 2005 12:02:47 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Wednesday, January 26, 2005

    Finally, this is done. Read the cover story here.

    Even though I usually dont advocate the use of SOAP to transfer large BLOBS of binary bits (I tend to think that there are slightly better ways of transferring files and/or attachments), I do believe that there will be more and more calls for uses for it and that is why I think this is an important specification which is way better than W3C's SwA or MSFT Corp's/IETF's  DIME (Can you say Security ?). The latter, incidentally, is being implemented by Web Services Enhancements (WSE) 1 and 2.

    Of course, since DIME is being superseded by MTOM, I am really looking forward (hopefully) to the implementations of it in WSE 3.0

    Wednesday, January 26, 2005 9:16:26 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • Got this inkling feeling that these ASCII Character code tables will come in handy one day...

    DEC HEX ASCII   KEY                 DEC HEX ASCII
    0 00 NUL Null CTRL-@   32 20 SPACE
    1 01 SOH Start of header CTRL-A   33 21 !
    2 02 STX Start of text CTRL-B   34 22 "
    3 03 ETX End of text CTRL-C   35 23 #
    4 04 EOT End of transmission CTRL-D   36 24 $
    5 05 ENQ Enquiry CTRL-E   37 25 %
    6 06 ACK Acknowledge CTRL-F   38 26 &
    7 07 BEL Bell CTRL-G   39 27 '
    8 08 BS Backspace CTRL-H   40 28 (
    9 09 HT Horizontal tab CTRL-I   41 29 )
    10 0A LF Line Feed CTRL-J   42 2A *
    11 0B VT Vertical tab CTRL-K   43 2B +
    12 0C FF Form feed CTRL-L   44 2C ,
    13 0D CR Carriage return CTRL-M   45 2D -
    14 0E SO Shift out CTRL-N   46 2E .
    15 0F SI Shift in CTRL-O   47 2F /
    16 10 DLE Data link escape CTRL-P   48 30 0
    17 11 XON, DC1 XON, Device control 1 CTRL-Q   49 31 1
    18 12 DC2 Device control 2 CTRL-R   50 32 2
    19 13 XOFF, DC3 XOFF, Device control 3 CTRL-S   51 33 3
    20 14 DC4 Device control 4 CTRL-T   52 34 4
    21 15 NAK Negative acknowledge CTRL-U   53 35 5
    22 16 SYN Synchronous idle CTRL-V   54 36 6
    23 17 ETB End of text buffer CTRL-W   55 37 7
    24 18 CAN Cancel CTRL-X   56 38 8
    25 19 EM End of medium CTRL-Y   57 39 9
    26 1A SUB Substitute CTRL-Z   58 3A :
    27 1B ESC Escape CTRL-[   59 3B ;
    28 1C FS File separator CTRL-\   60 3C <
    29 1D GS Group separator CTRL-]   61 3D =
    30 1E RS Record separator CTRL-^   62 3E >
    31 1F US Unit Separator CTRL-_   63 3F ?


    DEC HEX ASCII                 DEC HEX ASCII
    64 40 @   96 60 `
    65 41 A   97 61 a
    66 42 B   98 62 b
    67 43 C   99 63 c
    68 44 D   100 64 d
    69 45 E   101 65 e
    70 46 F   102 66 f
    71 47 G   103 67 g
    72 48 H   104 68 h
    73 49 I   105 69 i
    74 4A J   106 6A j
    75 4B K   107 6B k
    76 4C L   108 6C l
    77 4D M   109 6D m
    78 4E N   110 6E n
    79 4F O   111 6F o
    80 50 P   112 70 p
    81 51 Q   113 71 q
    82 52 R   114 72 r
    83 53 S   115 73 s
    84 54 T   116 74 t
    85 55 U   117 75 u
    86 56 V   118 76 v
    87 57 W   119 77 w
    88 58 X   120 78 x
    89 59 Y   121 79 y
    90 5A Z   122 7A z
    91 5B [   123 7B {
    92 5C \   124 7C |
    93 5D ]   125 7D }
    94 5E ^   126 7E ~
    95 5F _   127 7F DELETE

    6Bit-ASCII Table Conversion

    Value Char   Value Char   Value Char   Value Char
    0 A   16 Q   32 g   48 w
    1 B   17 R   33 h   49 x
    2 C   18 S   34 i   50 y
    3 D   19 T   35 j   51 z
    4 E   20 U   36 k   52 0
    5 F   21 V   37 l   53 1
    6 G   22 W   38 m   54 2
    7 H   23 X   39 n   55 3
    8 I   24 Y   40 o   56 4
    9 J   25 Z   41 p   57 5
    10 K   26 a   42 q   58 6
    11 L   27 b   43 r   59 7
    12 M   28 c   44 s   60 8
    13 N   29 d   45 t   61 9
    14 O   30 e   46 u   62 +
    15 P   31 f   47 v   63 /

    Wednesday, January 26, 2005 8:55:30 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Tuesday, January 25, 2005

    William Stacey has outdone himself again. He has blogged on how to create SecurityContextTokens without X509 Certs.

    He has beaten me to it. As I have said in a comment to his blog:

    ...I knew something like that would be very useful and there are tons of requests out there for the use of SCT without X.509 because of cost issues or the server admin doesnt want to install them for whatever reasons.

    I was on my way to implementing it, then I took some time off to look at the specifications for the exchange of entropy values, then I got derailed by some work committments and after that I just got lost...

    It is so good for you to come up with this. It is excellent. I would have to try it and feedback. Many people will thank you for it.

    Julie, if you are reading this, hopefully this will help solve a problem of yours that is way loooong overdue.

    Tuesday, January 25, 2005 11:26:20 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Thursday, January 20, 2005

    If you can see this correctly, then Julie Lerman's BLInk still works with this version of dasBlog 1.7.5016.0

    Posted from BLInk !

    Wednesday, January 19, 2005 10:56:15 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Wednesday, January 19, 2005

    If you are reading this, I am already successfully migrated to dasBlog 1.7.5016.0. There are so many wonderful enhancements to this version. I especially love the Anti-Spam features of it via the Captcha image Comment Post and the ReferralSpam blacklist.

    Incidentally, I had written up an article on DevX before on "Spoof-Proofing your Logins" here. Do check it out.

    Thanks Mr Computer Zen, Scott Hanselman for the excellent contributions to this project.

    Trust me, I wasted no time in drawing up the referral blacklist. The much-desired feature of allowing the author to draft up a blog post first before publishing it (IsPublic = true) is also here now.

    Wednesday, January 19, 2005 1:19:53 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • I recently extended a chat program written in Web Services Enhancements (WSE) 2.0 utililizing the TCP transport protocol. I wanted it to run over the internet now. This was prompted by some members of our Singapore Professional DotNet Usergroup who wanted to implement a mini Pub-Sub (aka WS-Eventing) project using the tcp protocol.

    They had indicated that they had some trouble binding the FQDN specified for the URI in the EndpointReference to a local network interface. If this cannot be resolved, the binding will fail.

    At the most basic level, the EndpointReference.Address is both the name of the target and its location. For example, [http://localhost/SomeService] can be used as a name and a transport address. WSE 2.0 comes with an extended model to allow a single named service to be hosted on multiple transport addresses. This can also be useful if we want to apply a single corporate policy on them.

    This is where EndpointReference.Via comes in. It allows you to host a well-known service that can only be accessible via different transports such as the soap.tcp protocol of WSE 2.0 and others.

    For example, my well-known service is hosted at soap.tcp:// (or soap.tcp://, if you dont have a DNS tagged to it). This is the public FQDN address of the service. For the broadband cable and ADSL users of dynamic IPs, this address may be the address of your home network router.

    Now, your WSE 2.0 application has a SOAP Receiver object that allows your application to listen for SOAP requests coming in on WSE2-custom defined transports. Once you define your own address on your own listening machine such as soap.tcp://, you would now have 2 URIs:

    Public Facing: soap.tcp://
    Private Internal: soap.tcp://

    The Public Facing well-known URI becomes the EndpointReference.Address while the transport address mechanism becomes the EndpointReference.Via

    In other words, soap.tcp:// will listen for any messages that is sent to soap.tcp:// (the address element in the WS-Addressing headers). Put it in another way, the custom soap.tcp transport will only accept messages sent to soap.tcp:// if they arrive via the internal address:

    The Via address is not in the message itself, only the well-known URI is. Based on the network address the message is being received on, the custom soap.tcp transport mechanism will know how use both well-known and private URIs to dispatch the message to the registered and configured-properly SOAP Receiver.

        EndpointReference EPR = new EndpointReference
        (new Address(new Uri("soap.tcp://")),

        new Via(new Uri("soap.tcp://")));

        SoapReceivers.Add(EPR, yourOwnSoapReceiver);

    The last step you need to take is to be able to forward all requests going to the well-known URI (soap.tcp:// to your local machine with the internal IP

    This is not something you can do in WSE 2.0 or in your machine. This has to be done at your broadband or cable router. You just have to forward requests coming in to your Public port:2088 to the Private port:2088 of machine (Note that these ports doesnt have to be the same number at all)

    Of course, the huge assumption is that you have control over the port routing and forwarding of your broadband or cable router (which may be rather tricky if you are within a corporate or organizational boundary) BUT technically, you will be able to carry out a p-2-p SOAP message chat or even do a Pub/Sub model approach with your own implementation of the “Notification” and “Solicit-Response” message-exchange patterns over the internet using the custom soap.tcp protocol of WSE 2.0

    [Author Note] What do ya know ? I just found that that Hervey has got an even better post on the EndpointReference.Via of WSE 2.0 here.

    Wednesday, January 19, 2005 1:47:59 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Sunday, January 16, 2005

    dasBlog 1.7 is works in the brewing with tons of excellent new features, especially with the Anti-Spam comments and referrals blacklist features, contributions from Mr Computer Zen himself, Scott Hanselman.

    I have noticed that many of the blog authors of and have turned off their comments API. I, myself, have turned off my own referral email notification API because I have been receiving up to 50 SPAM referrals a single day through emails.

    This will be, indeed, a welcome relief. Thanks Omar Shahine, Scott Hanselman and the other contributing authors of dasBlog 1.7.

    [AuthorNote] Done...Migrated...

    Sunday, January 16, 2005 9:26:13 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Thursday, January 13, 2005

    One of the great minds whose blog I keep track of is Werner Vogels. I have been keeping track of his blog since he was teaching in Cornell and then he moved on to the Director of Research of Amazon and now this, to become the CTO of Amazon !!! Ultra-Cool, Mr Distributed Computing !

    Congratulations, Werner.

    I wonder if this means we could see the scary vision of Googlezon in 2008 ?
    If you dont know what I mean, check this out...

    Thursday, January 13, 2005 10:09:20 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • William Stacy has a new blog in MSN Spaces and he blogged about a topic that has spurned from recent activities in the WSE newsgroups.

    It is about the security and the use of username tokens in the real world, specifically when it relates to passwords being stored as hash in the user database.

    William proposes a method here to solve the issue of how to authenticate username tokens embedded in _WS-Security Specs_ security headers.

    In my own opinion, his case represents a very major common representation of how passwords are stored in the database. They are mostly and SHOULD be hased. To add another realm of security, SALT is used. However, I dont really agree that his method may prove to more secure. In fact, I think it gives a somewhat false sense of security (and William, please correct me if I am wrong anywhere).

    1)   By using your verifier as a matching mechanism to gain authentication, then this verifier (SALT Hash and all) effectively becomes a password. If Mallet steals the hash from the user database, nothing prevents him/her from writing a client that sends the hash and thus he would authenticate successfully. This is exactly what the hash scheme is trying to avoid in the first place.

    If used this way, the hash is no safer than storing the passwords in clear text in the database...which ultimately means that the weakest link is still the security of the Username Database which must be protected at all costs.

    In other words, this must be made known clearly so that it doesnt preach a false sense of security that people think that this scheme NOT only protects their cleartext password BUT also their SOAP calls as well.

    This post here explains real well on my thoughts as well.

    2)   SALT should be a completely random value and should be algorithmically introduced to further obfuscate the one-way hash. In your approach, it seems that the SALT is tied very much to your username (am I wrong ?). This doesnt help much because I dont need to guess your publicly-available username, there are only a handful of hashing algorithms out there and you are NOT passing any SALT into your PasswordDeriveBytes constructor. In fact, the only saving grace is the iteration count which basically sets the number of iterations for the operation. Is that enough ? I believe it may serve well for some smaller-scale simpler systems BUT I dont know how it sits well with some of the security policies of bigger enterprises.

    IMHO, I think the current username tokens as defined by WS-Security doesnt fit very well into most EXISTING user databases which store passwords as hashes which may or may not be SALTED. I dont think there is a clean way to do this in WSE without using or representing the hashes as passwords. However, I am still thinking about this issue and will blog more about it later if (not when) I reach enlightenment.

    Your approach, however, does allow passwords to remain as they are in the EXISTING user databases. The only obstacle you require is a change in the schema of that table, which requires management approval and buy-in and usually triggers off many other related procedures, and that in my experience, is sometimes harder than finding the password from a hash.

    [Author Note]: This topic has got nothing to do with the security of username tokens as I have blogged about earlier here. This is all about the authentication of username tokens with the stored credentials in the user databases.

    Wednesday, January 12, 2005 11:09:54 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Wednesday, January 12, 2005

    After installing Web Services Enhancements (WSE) 2.0 SP2, the most natural thing for me to do is to run my previous WSE 2.0 SP1 projects and see if it works with the new assembly.

    Most of it still do run <phew>. A couple of them (specifically the SOAP Routing ones) did NOT run as intended. A further drilldown into the code revealed that the ExtendedSecurity doesnt serialize properly if you are planning to send another set of Security Headers to the next SOAP node...In fact, it doesnt get serialized at all.

    ...Obviously, this next node cannot be the ultimate soap receiver as target service cannot process 2 security headers as specified in the _WS-Security Specs_. You can refer to my previous discussions with HerveyW here and here.

    So, if your next node is another SOAP Router and you need a different set of Security Headers for the next node to process, this is how to do it with the ExtendedSecurity function in SP2:

    You need to add a Security Utility Timestamp into the Security Header in order for the ExtendedSecurity function to serialize a new set of Security Headers properly.

    Dim t As Utility.Timestamp = AnotherSecurityHeaderBlock.Timestamp

    Thereafter, when you call the ExtendedSecurity function and add this new Security Header block, the serialization will take place.

    In SP1, it is NOT necessarily for you to add this timestamp.

    The WSE team has confirmed this as a workaround to this minor bug.

    Wednesday, January 12, 2005 10:38:07 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, January 08, 2005

    I have recently installed SP2 of Web Services Enhancements (WSE) 2.0 over my previous installed version of SP1.

    From my first views of it, it seems that I would uninstall it and re-install the older copy of SP1 again. This has got nothing to do with SP2 itself BUT the WSE SOAP tracing utility that I used before with SP1 doesnt work with SP2.

    I have been using Mike Taulty's WSE 2.0 Tracing Utility for some time now and I have nothing BUT the best things to say about it. It really helps in my demos that I have done for the past year, including the very successful ones I have done in MS TechED Asia 2004. However, it doesnt work in this new SP2 version of WSE 2.0

    To trace the WSE SOAP trails in SP2, I switched over to Simon Guest's Trace Tool. Although it works well due to the difference in how they captured their traces, I dont really like Simon's WSE 2.0 Trace Tool. Sorry, Simon. Love all your interoperability works and presentations plus all the efforts you have done revolving around interoperability, just not this tool.

    Let me explain briefly what their differences are (performing my own dissection):

    Mike's WSE Tracing Utility, I believe, works based on filters and streams. It needs some configuration to set this utility up so that its own trace filters can intercept the (W3C) SOAP messages. It then outputs and writes the captured traces into its console and present it via log message style. I believe it does so using the System.IO.Stream classes. I dont even have to turn on the diagnostic properties of WSE 2.0. Very ingenious, to say the least.

    Simon's WSE Trace Tool works slightly differently. There is zero configuration on this Trace Tool. Only thing you need to do is to turn on the diagnostic properties of WSE 2.0. It works by reading the diagnostic files that are churned by WSE 2.0. Therefore, it can only output the results after the code has run. It uses either a Timer or a FileSystemWatcher basis to capture any new writes to the diagnostic files. Therefore, it is NOT as real-time as I would like it to be.

    Therefore, from the looks of it, Simon's WSE Trace Tool seems to offer the best chance in terms of integration with the new WSE 2.0 releases. However, it is just NOT as friendly and intuitive as I like it to be.

    Mike's WSE Tracing Utility also offers a quick one-glance understanding of what is the output and input of the traces are. With Simon, it doesnt. I have to figure out and remember the upper pane is the output trace while the lower pane belongs to the input trace.

    And the main thing to me separating those two is that I dont have to turn on the diagnostic properties of WSE 2.0 for Mike's tracing utility. If I turn that on, I have to remember to turn it off once I move it into a production system as the diagnostic files are kept, “logging style”, and it does bloat. What is worse, every write into it appends an entire brand new SOAP message into it and we all know how verbose SOAP can get, with all the new WS SOAP headings and such...and as the file gets bigger, the writes will take longer and it will directly impact on the run-time performance of the entire application.

    It doesnt take much to google'd and newsgroup'd the web and you will find that some of the initial hiccups of WSE 2.0 is with regards to the run-time performance of it as the longer it runs. Turning off the diagnostic properties solves this issue right away.

    Another thing that I dislike about these diagnostic files is that I cannot delete them right away. IIS has a timing lock on them and only when I reset IIS, then I can delete them. Although it is not directly linked to Simon's Trace Tool, I can only delete them from the console after I reset IIS which means a toggling of windows. It is still a disadvantage to Simon's way of capturing the traces. Since Mike uses a stream, there is no file lock to speak of. The only persistant traces are in his console, not in the files, which makes it much more efficient and cleaner.

    Simon's trace tool also has a pesky bug that frustrates me. You have to pick a project folder for him to scan for the trace files. Most times, we have many project folders in a solution directory (for example, SOAP Routing Projects). Therefore, it doesnt work well if I want to capture the trace diagnostics of all projects of a solution. Even if I set the solution folder to be the project folder, it doesnt seem to scan and pick out all the trace files found in all the project folders of the the root folder. It seems, to me, to only display the trace files found in the last-scanned project folder. . This has a big impact on the aesthetics, especially when I am doing WSE 2.0 demos to a large audience, which I do, quite a fair bit.

    Mike's trace utility, again, got into my good books for this. Because his is based on a stream approach, all “configured-properly” projects of the same solution will be written to the console and displayed very nicely and logically so that anyone can view and understand it right away.

    Lastly, there is something about Mike's trace utility that generates the trace outputs as the WSE 2.0 code runs on the fly that always...and I mean always, gets the WOW out of the audience and that to me, is the single most important factor that makes me swear by his trace utility anytime, anyday...

    So, Mike, if you are reading this, this is a call for your action to fix the issues so it can work with WSE 2.0 SP2 as thousands of people like me are waiting and will Thank you for it. Even more so, many more people in the audiences will Thank you for it too as well because it does help them understand WSE 2.0 and all its related WS SOAP headings a little bit better.

    [Author Note: Mike has graciously fixed the Trace Utility so that it works with WSE 2.0 SP2 now. It can be downloaded from his blog here.]

    Friday, January 07, 2005 10:42:21 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Thursday, January 06, 2005

    I so agree with Mike Gilbert for his post on this...

    Wednesday, January 05, 2005 10:16:39 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Monday, January 03, 2005

    A very interesting blog about Why Microsoft can blow off with C# and an even more amazing response after that.

    Sunday, January 02, 2005 9:25:14 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions