RIP Alan Kalameja

I saw in the March 8 edition of the TenLinks Daily newsletter that Alan Kalameja passed away at age 55. Condolences to his family. Alan hired me to write test questions for an AutoCAD certification exam in the early ’90s (I don’t recall which version, but probably either R12 or R13). That was one of my first real contracting jobs. Although it wasn’t very glamorous, it made me feel important, and undoubtedly helped focus my fledgling consulting business on AutoCAD. Thanks, Alan, for giving me that opportunity.

March 9, 2010 · 1 min · Owen Wengerd

Automatic LISP Loading

There are a myriad of ways to load AutoLISP applications in AutoCAD, including acaddoc.lsp, an .mnl file, the Startup Suite, and manually by various means. For application developers wishing to deploy their applications to others, all of these methods have drawbacks. The ideal solution should be easy to implement in an installation program, require minimal or zero changes to the user’s AutoCAD configuration, work the same way across all versions of AutoCAD, and easily undone when the application is uninstalled. ...

December 24, 2009 · 3 min · Owen Wengerd

ArxDbg Utility

ArxDbg is the name of a sample project that has been included with the ObjectARX SDK for many years. It’s primary purpose is to demonstrate how to use the ObjectARX API, but it is a complete free-standing utility in its own right. ObjectARX programmers often use this utility during development for testing and exercising their application code, but it can be useful to anybody, not just programmers. ...

September 23, 2009 · 1 min · Owen Wengerd

AutoCAD Missing Language Pack Drawing File Corruption

I’ve been chasing a drawing corruption problem on behalf of a customer. The problem manifests itself by causing a “Missing Language Pack” dialog to display when the drawing is opened (but only in Windows XP with no language packs installed – my Vista installation apparently has all the language packs installed). Installing the language packs “fixes” the problem, in that the drawing files open without error. However, the real problem is that some drawing objects were corrupted in memory, and corrupt data was subsequently written to the .dwg file. My customer thinks the corruption might be linked to a virus that they were infected with (and have since eliminated). I have a copy of the virus for testing, but I have not been able to catch it in the act of corrupting an open drawing file. Therefore, I cannot conclusively link the virus with the corruption. So, I need your help. Have you recently noticed a “Missing Language Pack” dialog appearing in drawing files that have opened fine in the past? Has your virus scanner recently detected an AutoCAD related virus? If you have, please send me an email describing your situation and AutoCAD versions involved. I would like to determine conclusively whether the virus is causing drawing file corruption, and if so, whether the corruption is always in the same location of the drawing file. [Update: Autodesk has released a technical document with information about the virus. See also Shaan Hurley’s blog post.]

August 3, 2009 · 2 min · Owen Wengerd

Disable InfoCenter in AutoCAD 2010

[Update: See Disable AutoCAD InfoCenter] In case you missed it, Tony Tanzillo has posted instructions for disabling the InfoCenter in AutoCAD 2010. AutoCAD 2010 starts faster when the InfoCenter is disabled. To make it easy, I’ve created an AutoLISP file that defines commands named DisableInfoCenter and EnableInfoCenter: ...

March 30, 2009 · 1 min · Owen Wengerd

ObjectARX 2010: Dealing With Missing Exports

In the new ObjectARX 2010 SDK, Autodesk has added some new virtual member functions that are not exported as they should be. For example, the AcGiFaceData class has had two new virtual functions added for setting and getting the face transparency: class AcGiFaceData: public AcRxObject { //[… deleted for brevity] ACDB_PORT virtual AcDbObjectId materials() const; ACDB_PORT virtual AcGiMapper mappers() const virtual void setTransparency(const AcCmTransparency transparency); virtual AcCmTransparency transparency() const private: AcGiImpFaceData mpAcGiImpFaceData; }; As you can see, whoever added the new functions neglected to prefix them with the ACDB_PORT macro. ACDB_PORT evaluates to __declspec(export), which tells the compiler to export the function. Since the macro is missing, the new functions are not exported from acdb18.dll. Since these are virtual functions, you won’t have any problems calling them through a pointer to an AcGiFaceData object that was constructed by AutoCAD. The problem arises when you derive a class from AcGiFaceData. Since the functions are not exported, the linker has no way of resolving their address for creating the virtual function table of your derived class. This results in linker errors: acrxEntryPoint.obj : error LNK2001: unresolved external symbol “public: virtual void __thiscall AcGiFaceData::setTransparency(class AcCmTransparency const )” (?setTransparency@AcGiFaceData@@UAEXPBVAcCmTransparency@@@Z) acrxEntryPoint.obj : error LNK2001: unresolved external symbol “public: virtual class AcCmTransparency * __thiscall AcGiFaceData::transparency(void)const " (?transparency@AcGiFaceData@@UBEPAVAcCmTransparency@@XZ)Following is an example that results in these errors: class AcGiFaceDataEx: public AcGiFaceData { public: AcGiFaceDataEx() {} ~AcGiFaceDataEx() {} } Test; The only solution is to provide an implementation of the missing functions. In this case, it could be accomplished by something like this: class AcGiFaceDataEx: public AcGiFaceData { AcCmTransparency mpTransparency; public: AcGiFaceDataEx() : mpTransparency( NULL ) {} ~AcGiFaceDataEx() { delete mpTransparency; } virtual void setTransparency(const AcCmTransparency transparency) { delete mpTransparency; mpTransparency = (transparency? new AcCmTransparency( transparency ) : NULL); } virtual AcCmTransparency transparency() const { return mpTransparency; } } Test;This will fix the linker errors, but there is no guarantee that it will work as intended. AutoCAD might access its internal transparency value directly without calling through the member functions, which means it would never “see” the transparency set through the replacement member functions. Furthermore, the addition of the new pointer member changes the size of the class, which causes AcGiFaceDataEx arrays to have a different memory footprint than AcGiFaceData arrays. Lastly, what if Autodesk fixes the problem in a future AutoCAD service pack? The ideal solution should not change the size of the class. It should check at runtime whether the function is exported, then use the exported function if it exists. That way, code that is written now will use the exported function if and when it becomes available in a future version of AutoCAD. When the function is not exported, an alternate implementation must be provided. This is not an unusual scenario, and the solution I present for the specific case of AcGiFaceData can be adapted to the more general problem. In the AcGiFaceData case, the missing functions are virtual functions. Knowing this, it is possible to use a trick to get the address of the real function. In the code below, the function getAcGiFaceData_vtable() constructs a temporary AcGiFaceData object, from which it extracts a pointer to the object’s virtual function table. The virtual function table is just an array of function pointers, so the address of the desired function can be obtained by indexing into the virtual function table. The question is, how far? By counting virtual functions and data members starting from the top of the class hierarchy: in this case, 6 virtual functions in AcRxObject plus 16 virtual functions in AcGiFaceData = 22. Note that obtaining a function pointer this way relies on Visual C++ implementation details, but this is safe to do since all ObjectARX modules must be compiled in Visual C++. Following is my solution to the missing AcGiFaceData functions: #pragma warning(push) #pragma warning(disable: 4608) template < typename Src, typename Dest > Dest force_cast( Src src ) { union _convertor { Dest d; Src s; _convertor() : d(0), s(0) {} } convertor; convertor.s = src; return convertor.d; } #pragma warning(pop) static FARPROC getAcGiFaceData_vtable() { static FARPROC rfVTable = (FARPROC**)&AcGiFaceData(); return (rfVTable? rfVTable : NULL); } void AcGiFaceData::setTransparency( const AcCmTransparency transparency ) { typedef void (AcGiFaceData::F_setTransparency)( const AcCmTransparency ); static F_setTransparency pfSetTransparency = force_cast< FARPROC, F_setTransparency >(GetProcAddress( GetModuleHandleA( “acdb18.dll”), “?setTransparency@AcGiFaceData@@UEAAXPEBVAcCmTransparency@@@Z” )); if( !pfSetTransparency ) { static FARPROC rfVTable = getAcGiFaceData_vtable(); if( rfVTable ) pfSetTransparency = force_cast< FARPROC, F_setTransparency >( rfVTable[22] ); } if( pfSetTransparency ) (this->pfSetTransparency)( transparency ); } AcCmTransparency AcGiFaceData::transparency() const { typedef AcCmTransparency (AcGiFaceData::F_transparency)() const; static F_transparency pfTransparency = force_cast< FARPROC, F_transparency >(GetProcAddress( GetModuleHandleA( “acdb18.dll”), “?transparency@AcGiFaceData@@UEBAPEAVAcCmTransparency@@XZ” )); if( !pfTransparency ) { static FARPROC rfVTable = getAcGiFaceData_vtable(); if( rfVTable ) pfTransparency = force_cast< FARPROC, F_transparency >( rfVTable[23] ); } if( pfTransparency ) return (this->*pfTransparency)(); return NULL; }

March 28, 2009 · 4 min · Owen Wengerd

What's New in the AutoCAD 2010 EULA

Everyone else is discussing all the cool new features in AutoCAD 2010, so I decided to have a look at what’s new in the EULA (End User License Agreement). I compared the AutoCAD 2010 EULA for US/Canada to the AutoCAD 2009 EULA. I won’t divulge the process I used to automate the comparison, because the odds are pretty good that I violated the EULA somewhere along the way, and I want plausible deniability. The first change I noticed is that the AutoCAD 2010 EULA contains more shouting. The 2009 EULA started out in a fairly mellow mixed case with a few shouts thrown in for effect, but the 2010 EULA dispenses with the lower case and launches right into a multi-paragraph avalanche of screaming block letters. Apparently nobody was listening, so they turned up the volume. Substantively, there are a number of very interesting changes. The following was added to the preamble: SOFTWARE OBTAINED FROM THIRD PARTIES THAT HAVE NOT BEEN AUTHORIZED OR ALLOWED BY AUTODESK, DIRECTLY OR INDIRECTLY, TO SUPPLY SOFTWARE IS LIKELY TO HAVE BEEN MADE AVAILABLE IN VIOLATION OF AUTODESK’S RIGHTS. IN SUCH AN EVENT, AUTODESK IS NOT OBLIGATED TO ISSUE AN ACTIVATION CODE OR OTHERWISE PERMIT YOU TO INSTALL OR USE THE SOFTWARE. Next time you’re eyeing that used copy of AutoCAD 2010 on eBay, be warned that Autodesk is not obligated to permit you to install or use the software. They don’t come right out and say that they won’t allow it, so maybe they won’t mind – but then what’s the point of including this clause? Tim Vernor won’t be very happy about this change. Moving along, I see that they added a definition for “Uninstall”, defining it as “to destroy or remove”. The definition of “User Documentation” was very slightly changed from “…after You acquire or Install the Software…” to “…when or after You acquire or Install the Software…”. Incidentally, did you know that Autodesk considers an AutoCAD reseller’s invoice to be “user documentation”? Rounding out changes in definitions is a change in the definition of “You”. Yes, Autodesk has redefined “You” whether “you” like it or not. I could go on and on about small wording changes, and while it would be interesting to contemplate why each change was made (and how many scheming lawyers it took to do it), we’d risk missing the forest for the trees. Section 2.1, “License Grant”, contains ominous new language. The following has been added: You may Access the application programming interfaces that may be included with or in the Software or otherwise available from Autodesk for use with the Software (“API’s”) to develop programs, modules, components or functionality that (i) are compatible with and are used and/or interfaced with the Software and (ii) contribute significant value-added functionality or enhancements to the Software (“API Modules”) provided You may Install and Access such API Modules solely on Computers where a licensed copy of the Software is also installed and further provided such Installation and Access is solely in connection with Your Installation and Access of the Software and solely for Your internal business needs. You may not redistribute all or any portion of an API Module. Read that again. That’s right, you may not write any “programs, modules, components, or functionality” unless they “contribute significant value-added functionality or enhancements” to AutoCAD. Furthermore, if you do manage to write a program that adds significant functionality, you may not redistribute all or any part of it. What are those guys smoking out there in California? Finally at the end of section 2.1, they changed “No license is granted under the terms of this Agreement if You did not lawfully acquire the Software” to “No license is granted under the terms of this Agreement if You did not lawfully acquire the Software from Autodesk or from a third party who has been permitted or authorized by Autodesk either directly or indirectly to supply the Software”. Take that Tim Vernor! In another nod to the Vernor case, section 2.3, “Upgrades”, adds a new requirement to “destroy all Autodesk Materials relating to the Previous Version or, upon request by Autodesk, return all such Autodesk Materials relating to the Previous Version to Autodesk or the company from which they were acquired”. This is important language that could persuade a court to view an AutoCAD purchase as a license instead of a sale, thereby giving Autodesk the power to control the secondary market. Interestingly, section 2.4, “Crossgrades”, requires that the previous software be uninstalled within 60 days, but has no requirement that it be destroyed. However, new language in section 2.7, “Termination”, which requires the software to be destroyed “upon termination of the license grant or this Agreement”, apparently covers both cases. A funny change in section 3.2.3, “Transfers”, appears to close a loophole. The AutoCAD 2009 EULA disallowed transfers to “any other person”; the AutoCAD 2010 EULA disallows transfers to “any other person or legal entity”. Considering a license transfer? Make sure it’s to an illegal entity! Section 4, “ALL RIGHTS RESERVED”, was rewritten. The rewrite introduced a grammatical error (“and You have not other rights”), but otherwise I don’t see that much changed. It still ends with the now familiar directive that “The Software and User Documentation are licensed, not sold." Finally, the infamous “audit clause” has been revised. Not the way you may have hoped, I’m sad to report. Luckily the change was a minor one that doesn’t make the clause any more overbearing than it already was. Isn’t change wonderful?

March 25, 2009 · 5 min · Owen Wengerd

Software Licensing: A Case For Reform

I want to consider software licensing practices in general, but with the specific facts and history in the Vernor vs. Autodesk lawsuit as a backdrop. In the Vernor case, Tim Vernor purchased several boxes of AutoCAD software, and never even read, let alone agreed to, the terms of the license agreement inside the box. When Vernor listed the AutoCAD software for sale on Ebay, Autodesk sent Ebay a notice that claimed Vernor’s auction violated Autodesk’s copyright. In order to benefit from the safe harbor provisions of the Digital Millennium Copyright Act (DMCA), Ebay was obligated to remove the auctions. Vernor responded by filing a lawsuit accusing Autodesk of making false copyright violation claims. Additional facts have since come to light. For one, we’ve learned that the AutoCAD software that Vernor purchased had been previously upgraded to a newer version. Vernor did not know this when he purchased the software; and in any case, it’s not clear that this fact has any bearing on the outcome of the suit. Given this set of facts, let’s analyze the Vernor case not from a purely legal perspective, but from a more abstract “moral” perspective. After all, society is the ultimate arbitrator of what is wrong and what is right with respect to our laws. We ultimately determine whether laws are fair by whether we follow them willingly (and whether we put pressure on our legislatures to change them). Steve Johnson opines that Autodesk is morally right in the Vernor case, because the software Vernor purchased was “tainted” due to having been upgraded by the original owner. In Steve’s view… [see Steve’s comment below where he chides me for ascribing this view to him - O.W.] Presumably, one who holds this view sees Vernor’s original purchase as akin to someone purchasing stolen goods. With stolen goods, the law (and hopefully our moral compass) recognizes that the purchaser of the stolen goods has no legal right to them. Autodesk offered the original owner a discounted price for a newer version of AutoCAD in exchange for a promise to destroy the older version. The original owner reneged on its promise to destroy the old version, and sold it to an unwitting buyer instead. It follows that both Autodesk and Tim Vernor were treated unfairly by the company that sold the AutoCAD software to Vernor. Despite the company’s history of using pirated software, Autodesk gave them the benefit of the doubt when selling them a discounted upgrade. Vernor, by all accounts, had no idea and no way of knowing that the software he purchased had been previously upgraded. This is a recipe for disaster. Unfortunately, this sort of disaster is all too common. In many cases, software users simply don’t read license agreements. If they do read license agreements, they don’t understand them. After all, most of us are not lawyers, and we can’t reasonably be expected to hire a lawyer to evaluate the license agreements of every software product we use. How then can we be expected to follow them exactly and without fail? Consider that it’s entirely possible that the company from which Vernor bought his AutoCAD software had no idea that they had agreed to destroy the upgraded AutoCAD software. At least from a moral perspective, we can have some sympathy for the company if they honestly had no idea they were violating any agreements when they sold the software to Vernor. Could Autodesk have required the upgraded AutoCAD software to be returned, or required certification by an independent “software recycler” that it had been destroyed? Sure they could have. In fact, such requirements did exist in the early days of software license agreements. Had Autodesk done so, the Vernor court would probably have concluded that AutoCAD was licensed, not sold. Why even require the old version to be destroyed when upgrading? If we stop using the old version, why shouldn’t we be allowed to sell it at market value? Doesn’t recycling old software make just as much sense as recycling old tires? We have been conditioned to believe that discounted upgrades are good for us, but are they really? Would we accept a legal regime under which tire manufacturers could force us to destroy our old tires as part of the new tire purchase agreement? Oh, you say, that comparison isn’t valid because tires eventually wear out of their own accord, whereas old software continues working forever! First of all, old software doesn’t continue working forever. How many people still use VisiCalc? Furthermore, what would this line of reasoning conclude about potential tires of the future that last forever? We’d have to start licensing tires instead of purchasing them! What would happen if software vendors could not legally prevent “used” software from being resold on the open market, no matter how it was purchased or upgraded? For one, it would increase competition, because new versions of software would be competing not only against software from other vendors, but also against older versions of itself. In a world where software is priced based on what the market will bear, the net effect would be lower prices and higher quality (not to mention less frequent “upgrades”) for all software. I think the Vernor case is just one example illustrating how the current software licensing system has sprung a leak, and is in need of repair. Can it be patched, or does it need to be replaced? Can the bleeding be stopped at the ankle, or should it be stopped it at the neck? This is a classical case of the Petcock Problem. Software industry advocates like the Business Software Alliance (BSA) proclaim that the solution is educating consumers. Education may be important, but I think that “educating consumers” should not be left to an industry alliance. I have some ideas about how the system can be reformed, but I think we have to start by recognizing that there’s a problem.

March 1, 2009 · 5 min · Owen Wengerd

AECOPEN Utility

James Maeding of Hunsaker & Associates contacted me recently about an irritating problem that his users have with the AECOPEN command in Land Desktop. The AECOPEN command replaces the core AutoCAD OPEN command in AEC verticals. The problem they have is that AECOPEN displays an initial project dialog that requires users to press a [Browse] button to open the file browser dialog. Since they want to browse for a file every time they use the AECOPEN command, James wondered if I could create some code to automatically “press” the Browse button every time the AECOPEN command is issued. I whipped up a little utility for AutoCAD 2007-2009 based products to do what James wanted, and it is now available on my freebies page as AecAutoOpen.zip. When the ARX module is loaded, AECOPEN behaves as if the user had immediately pressed the [Browse] button on the project dialog. If the [Ctrl] key is pressed, AECOPEN reverts to its original behavior. Why not just use the built in OPEN command instead? The AECOPEN command has some important side effects, according to James.

January 24, 2009 · 1 min · Owen Wengerd

Missing Menu Madness

One of my many complaints about about the CUI system introduced in AutoCAD 2006 is that it's not very friendly to third party developers. In my opinion, it's not very friendly to end users either, but I digress... One example of the unfriendly CUI is the case where a third party application installs a partial menu. In the pre-CUI days, adding a partial menu was an easy way to add an application specific menu to AutoCAD without making any changes to the end user's existing menu files. If the application was later uninstalled, the uninstall script could remove its menu and clean up the registry, leaving no trace behind. CUI breaks that scenario. ...

December 22, 2008 · 2 min · Owen Wengerd

Design File Locking and Snake Oil Security

The increased sharing of electronic CAD data (ala BIM) holds a lot of promise, but it also exposes companies and individuals to additional liability and risk. This additional risk is coming into focus more and more as actual cases of costly legal battles confront engineers and architects. The June 2008 AUGI wishlist results contain “Design File Locking” as the top wish by a substantial margin, and Shaan Hurley lists it as number 3 in the AU 2008 AutoCAD wish list. Clearly, interest in file and IP security has been growing steadily. As demand for IP security grows, there are sure to be snake oil security vendors trying to cash in on it. I received a spam email a few days ago from SafeNet, Inc. promising “a cost-effective and easy to integrate solution that provides reliable and effective security through the use of digital signatures.” Whenever I see such statements with a long string of buzzwords, my snake oil alarm goes on alert. Digital signatures are for authentication and establishing trust – they cannot and do not provide “reliable and effective security”, although I suppose they could be used by a system that does. In the last year or two, a number of companies have claimed to market software that “secures” AutoCAD DWG files. When I see such a claim, it invariably refers to software that creates an anonymous unequally scaled MINSERT entity. These can be created or “exploded” with a few lines of AutoLISP code. Frequently these companies claim to “encrypt” the drawing, which may sound sexy, but is an outright lie. If this is a level of “security” that meets your needs, at least use one of the many free versions posted throughout the internet (DETER.VLX from DotSoft is one I know of). There are solutions, but they always require changes in the workflow process that involve difficult tradeoffs and careful evaluation of what is technically feasible and practical versus the costs of implementing the changes. There is no such thing as installing a single piece of software to instantly solve the problem. If you are looking for ways to protect intellectual property in your drawing files, don’t be fooled by snake oil security vendors. Disclaimer: One of my hats is the president of CADLock, Inc., makers of CADVault for AutoCAD.

December 6, 2008 · 2 min · Owen Wengerd

Update vs. Service Pack

Of course I’m talking about Autodesk’s newly reinvented nomenclature for bug fixes. Once upon a time they were known as bug fixes, then service packs, and now “updates”. Is the Autodesk marketing department running amok? The subtle spin is certainly a sign of the times, but I wonder if the change in terminology comes about for another reason as well. Autodesk promises “features extensions” to subscription customers. They have had difficulty delivering such extensions on a consistent basis. One of the reasons, I suspect, is that developers of extensions encounter the same brick walls that third party developers battle all the time: AutoCAD bugs, of course; but also incomplete APIs and feature limitations. It’s possible that updates not only fix bugs, but also fill gaps so that extension developers can get their extensions working. Then again, the change in terminology might be part of a new fad. My wife, who is an engineer working in the automotive industry, informs me that they no longer issue drawing revisions in her company. Instead, they now issue “updates”. I wonder how long it will be before auto mechanics stop repairing cars and start updating them instead.

September 27, 2008 · 1 min · Owen Wengerd