Saturday, February 12, 2011

static const Member Value vs. Member enum : Which Method is Better & Why?

If you want to associate some constant value with a class, here are two ways to accomplish the same goal:

class Foo
{
public:
    static const size_t Life = 42;
};

class Bar
{
public:
    enum {Life = 42};
};

Syntactically and semantically they appear to be identical from the client's point of view:

size_t fooLife = Foo::Life;
size_t barLife = Bar::Life;

Is there any reason other than just pure style concerns why one would be preferable to another?

  • They're not identical:

    size_t *pLife1 = &Foo::Life;
    size_t *pLife2 = &Bar::Life;
    
    Konrad Rudolph : Essentially what I said, in less words. ;-)
    John Dibling : See, that's why I like Stack Overflow...
    jwfearn : Mike F, I assume that the scond line is supposed to generate a compile error. Perhaps you could add a comment stating that.
    Johannes Schaub - litb : yes, and you should change it to size_t const* pLife1
  • The enum hack used to be necessary because many compilers didn't support in-place initialization of the value. Since this is no longer an issue, go for the other option. Modern compilers are also capable of optimizing this constant so that no storage space is required for it.

    The only reason for not using the static const variant is if you want to forbid taking the address of the value: you can't take an address of an enum value while you can take the address of a constant (and this would prompt the compiler to reserve space for the value after all, but only if its address is really taken).

    Additionally, the taking of the address will yield a link-time error unless the constant is explicitly defined as well. Notice that it can still be initialized at the site of declaration:

    struct foo {
        static int const bar = 42; // Declaration, initialization.
    };
    
    int const foo::bar; // Definition.
    
    Richard Corden : Actually - your compiler shouldn't allocate any storage space for the constant. The standard explicitly states that only if the object is "used", ie. it's address needed, is the definition for the object required. And then the developer has to provide a definition explicitly!
    Richard Corden : If you take the address of a "static const" but don't define it, then it should result in a linker error.
    Konrad Rudolph : Richard, you're mixing intialization with definition here; you can well initialize the constant inline and define it separately. But you're right, I need to clarify my posting.
  • Well, if needed, you can take the address of a static const Member Value. You've have to declare a separate member variable of enum type to take the address of it.

  • One difference is that the enum defines a type that can be used as a method parameter, for example, to get better type checking. Both are treated as compile time constants by the compiler, so they should generate identical code.

  • Another third solution?

    One subtle difference is that the enum must be defined in the header, and visible for all. When you are avoiding dependencies, this is a pain. For example, in a PImpl, adding an enum is somewhat counter-productive:

    // MyPImpl.hpp
    
    class MyImpl ;
    
    class MyPimpl
    {
       public :
          enum { Life = 42 } ;
       private :
          MyImpl * myImpl ;
    }
    

    Another third solution would be a variation on the "const static" alternative proposed in the question: Declaring the variable in the header, but defining it in the source:

    // MyPImpl.hpp
    
    class MyImpl ;
    
    class MyPimpl
    {
       public :
          static const int Life ;
       private :
          MyImpl * myImpl ;
    }
    

    .

    // MyPImpl.cpp
    const int MyPImpl::Life = 42 ;
    

    Note that the value of MyPImpl::Life is hidden from the user of MyPImpl (who includes MyPImpl.hpp).

    This will enable the MyPimpl author to change the value of "Life" as needed, without needing the MyPImpl user to recompile, as is the overall aim of the PImpl.

    From paercebal
  • static const values are treated as r-values just like enum in 99% of code you'll see. That means there is never memory generated for them. The only advantage to using enums is they can't become l-values in that other 1%. The static const value has the advantage that it is type safe. You can also have static const float values.

    The compiler will make Foo::Life an l-value if it has memory associated with it. The primary way to do that is to take it's address. e.g. &Foo::Life;

    Using gcc there is another more subtle way!

    int foo = rand()? Foo::Life: Foo::Everthing;
    

    The compiler generated code uses the addresses of Life and Everthing. It compiles fine but will give a linker error about the missing addresses for Foo::Life and Foo::Everthing. This behavior is completely standard conforming, though obviously undesirable.

    Note, neither of these statements will generate the linker error.

    int foo = rand()? Foo::Life: Bar::Life;
    int bar = rand()? Foo::Life: Foo::Everthing + 0;
    

    Once you have a compiler conforming to the C++0x the correct code will be

    class Foo
    {
    public:
       constexpr size_t Life = 42;
    };
    

    This is guaranteed to always be an l-value, the best of both worlds.

    From caspin

Help Regarding Dynamic Proxy

I am seeing following exception when I try to use dynamic proxy

com.intellij.rt.execution.application.AppMain DynamicProxy.DynamicProxy Exception in thread "main" java.lang.IllegalArgumentException: interface Interfaces.IPerson is not visible from class loader at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353) at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581) at DynamicProxy.Creator.getProxy(Creator.java:18) at DynamicProxy.DynamicProxy.main(DynamicProxy.java:54) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

Any idea what I need to do to resolve it

  • When your DynamicProxy tries to do Class.forName(youInterfaceClass.getName()) the resulting java.lang.Class instance is different from the one you passed when you created the proxy. In other words you have two class objects with the same name and the proxy is not sure which one is the right one (doesn't matter whether they are the same).

    Usually, this happens when the interface you are trying to proxy is in a library loaded through two different classloaders (i.e. Tomcat's 'common' and 'application').

    If this doesn't help, please post more info on your application - especially if you are using any application server, Spring or OSGi.

    From ddimitrov

How to get the statistics existing on a column, if any?

I want to check in Transact SQL if a specific column in a table has statistics and if so to get them all.

  • This query should do it.
    I use it in a stored proc that browse the DB to find stats.
    Works in SQL Server 2005 and probably older version as well.

    SELECT S.NAME
    FROM   SYS.OBJECTS AS O
           INNER JOIN SYS.STATS AS S
             ON O.OBJECT_ID = S.OBJECT_ID
           INNER JOIN SYS.STATS_COLUMNS AS SC
             ON SC.OBJECT_ID = S.OBJECT_ID
                AND S.STATS_ID = SC.STATS_ID
    WHERE  (O.OBJECT_ID = OBJECT_ID('MyTable','local'))
           AND (O.TYPE IN ('U'))
           AND (INDEXPROPERTY(S.OBJECT_ID,S.NAME,'IsStatistics') = 1)  /* only stats */
           AND (COL_NAME(SC.OBJECT_ID,SC.COLUMN_ID) = 'MyColumn')
    
    From François

Can I use the standard C library in a Palm OS application?

The published code for Palm OS applications doesn't include standard headers, but instead uses Palm OS APIs for things like StrCopy and MemMove. Can I use standard headers and functions or do I need to convert my code to use the Palm OS versions?

  • It depends on the compiler and what version of the tools you're using. In general, if you can use Palm OS APIs, you'll probably work better on the platform, but both CodeWarrior and prc-tools had some library functions implemented.

    In CW for Palm OS V9, there's a pretty full version of the Metrowerks Standard Library (MSL). Most of MSL C++ is there giving you access to STL and other constructs. On the C front, you've got most of the standard C headers for memory management and string functions. However, it omits implementations for locales, math, signals, and standard I/O.

    To use the library, you need to make sure you link with the MSL C/C++ libraries. This can be set when you create your project in the wizard or added later by modifying the access paths and adding the appropriate static libraries for your targets.

    From Ben Combee
  • From a program size point of view its better to use the Palm OS API whenever possible, since that means you don't have to include the code from the library in the generated 'executable'. If you use functions from the compiler provided libraries the code of that functions will be added to each of your programs increasing their sizes.

    From rslite

.Net 2.0 ServiceController.GetServices()

I've got a website that has windows authentication enable on it. From a page in the website, the users have the ability to start a service that does some stuff with the database.

It works fine for me to start the service because I'm a local admin on the server. But I just had a user test it and they can't get the service started.

My question is:


Does anyone know of a way to get a list of services on a specified computer by name using a different windows account than the one they are currently logged in with?


I really don't want to add all the users that need to start the service into a windows group and set them all to a local admin on my IIS server.....

Here's some of the code I've got:

public static ServiceControllerStatus FindService()
        {
            ServiceControllerStatus status = ServiceControllerStatus.Stopped;

            try
            {
                string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
                ServiceController[] services = ServiceController.GetServices(machineName);
                string serviceName = ConfigurationManager.AppSettings["ServiceName"].ToLower();

                foreach (ServiceController service in services)
                {
                    if (service.ServiceName.ToLower() == serviceName)
                    {
                        status = service.Status;
                        break;
                    }
                }
            }
            catch(Exception ex)
            {
                status = ServiceControllerStatus.Stopped;
                SaveError(ex, "Utilities - FindService()");
            }

            return status;
        }

My exception comes from the second line in the try block. Here's the error:

System.InvalidOperationException: Cannot open Service Control Manager on computer 'server.domain.com'. This operation might require other privileges. ---> System.ComponentModel.Win32Exception: Access is denied --- End of inner exception stack trace --- at System.ServiceProcess.ServiceController.GetDataBaseHandleWithAccess(String machineName, Int32 serviceControlManaqerAccess) at System.ServiceProcess.ServiceController.GetServicesOfType(String machineName, Int32 serviceType) at TelemarketingWebSite.Utilities.StartService()

Thanks for the help/info

  • You can try using ASP.NET impersonation in your web.config file and specify a user account that has the appropriate permissions:

        <system.web>
           <identity impersonate="true" userName="Username" password="Password" />
        </system.web
    

    Take a look at this article on MSDN. I believe there are other options that do not require storing the password in the web.config file such as placing it in a registry key instead.

    This will cause the ASP.NET worker process to run under the context of the specified user instead of the user logged into the web application. However, this poses a security issue and I would strongly rethink your design. You may want to consider having the ASP.NET web page in turn fire off a request to some other process that actually controls the services, even another windows service or write the request to a database table that the windows service polls periodically.

    Miles : i have to have the windows username because I'm showing things in the website based on their windows login. I didn't want to have to make the user have an additional login.
    Rich : You can continue to use their windows account for authentication. I assume you are using integrated authentication in IIS and the ASP.NET authentication model. (). You can use both together and IIS will still negotiate the user credentials with no additional login.
    From Rich
  • Note: This doesn't address enumerating services as a different user, but given the broader description of what you're doing, I think it's a good answer.

    I think you can simplify this a lot, and possibly avoid part of the security problem, if you go directly to the service of interest. Instead of calling GetServices, try this:

    string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
    string serviceName = ConfigurationManager.AppSettings["ServiceName"];
    ServiceController service = new ServiceController( serviceName, machineName );
    return service.Status;
    

    This connects directly to the service of interest and bypasses the enumeration/search step. Therefore, it doesn't require the caller to have the SC_MANAGER_ENUMERATE_SERVICE right on the Service Control Manager (SCM), which remote users do not have by default. It does still require SC_MANAGER_CONNECT, but according to MSDN that should be granted to remote authenticated users.

    Once you have found the service of interest, you'll still need to be able to stop and start it, which your remote users probably don't have rights to do. However, it's possible to modify the security descriptor (DACL) on individual services, which would let you grant your remote users access to stop and start the service without requiring them to be local admins. This is done via the SetNamedSecurityInfo API function. The access rights you need to grant are SERVICE_START and SERVICE_STOP. Depending on exactly which groups these users belong to, you might also need to grant them GENERIC_READ. All of these rights are described in MSDN.

    Here is some C++ code that would perform this setup, assuming the users of interest are in the "Remote Service Controllers" group (which you would create) and the service name is "my-service-name". Note that if you wanted to grant access to a well-known group such as Users (not necessarily a good idea) rather than a group you created, you need to change TRUSTEE_IS_GROUP to TRUSTEE_IS_WELL_KNOWN_GROUP.

    The code has no error checking, which you would want to add. All three functions that can fail (Get/SetNamedSecurityInfo and SetEntriesInAcl) return 0 to indicate success.

    Another Note: You can also set a service's security descriptor using the SC tool, which can be found under %WINDIR%\System32, but that doesn't involve any programming.

    #include "windows.h"
    #include "accctrl.h"
    #include "aclapi.h"
    
    int main()
    {
     char serviceName[] = "my-service-name";
     char userGroup[] = "Remote Service Controllers";
    
     // retrieve the security info
     PACL pDacl = NULL;
     PSECURITY_DESCRIPTOR pDescriptor = NULL;
     GetNamedSecurityInfo( serviceName, SE_SERVICE,
      DACL_SECURITY_INFORMATION, NULL, NULL,
      &pDacl, NULL, &pDescriptor );
    
     // add an entry to allow the users to start and stop the service
     EXPLICIT_ACCESS access;
     ZeroMemory( &access, sizeof(access) );
     access.grfAccessMode = GRANT_ACCESS;
     access.grfAccessPermissions = SERVICE_START | SERVICE_STOP;
     access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
     access.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
     access.Trustee.ptstrName = userGroup;
     PACL pNewDacl;
     SetEntriesInAcl( 1, &access, pDacl, &pNewDacl );
    
     // write the changes back to the service
     SetNamedSecurityInfo( serviceName, SE_SERVICE,
      DACL_SECURITY_INFORMATION, NULL, NULL,
      pNewDacl, NULL );
    
     LocalFree( pNewDacl );
     LocalFree( pDescriptor );
    }
    

    This could also be done from C# using P/Invoke, but that's a bit more work.

    If you still specifically want to be able to enumerate services as these users, you need to grant them the SC_MANAGER_ENUMERATE_SERVICE right on the SCM. Unfortunately, according to MSDN, the SCM's security can only be modified on Windows Server 2003 sp1 or later.

    From Charlie
  • Thanks for that line of code Charlie. Here's what I ended up doing. I got the idea from this website: http://www.codeproject.com/KB/cs/svcmgr.aspx?display=Print

    I also had to add the account I'm accessing this as to the Power Users group on the server.

    public static ServiceControllerStatus FindService()
            {
                ServiceControllerStatus status = ServiceControllerStatus.Stopped;
        try
                {
                    string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
                    string serviceName = ConfigurationManager.AppSettings["ServiceName"].ToLower();
    
                    ImpersonationUtil.Impersonate();
    
                    ServiceController service = new ServiceController(serviceName, machineName);
                    status = service.Status;
                }
                catch(Exception ex)
                {
                    status = ServiceControllerStatus.Stopped;
                    SaveError(ex, "Utilities - FindService()");
                }
    
                return status;
            }
    

    And here's my other class with the ImpersonationUtil.Impersonate():

    public static class ImpersonationUtil
        {
            public static bool Impersonate()
            {
                string logon = ConfigurationManager.AppSettings["ImpersonationUserName"];
                string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
                string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
    
                IntPtr token = IntPtr.Zero;
                IntPtr tokenDuplicate = IntPtr.Zero;
                WindowsImpersonationContext impersonationContext = null;
    
                if (LogonUser(logon, domain, password, 2, 0, ref token) != 0)
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                        impersonationContext = new WindowsIdentity(tokenDuplicate).Impersonate();
                //
    
                return (impersonationContext != null);
            }
    
            [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
            public static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
    
            [DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
            public extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
        }
    
    Charlie : Cool, best of luck on that. I would be very careful to make sure that you properly revert the impersonation when you're done. To do that, you'll need to dispose the impersonation context returned from Impersonate. Failing to do that will leak the impersonation and cause problems down the road.
    Charlie : Just to be clear, if you don't revert the impersonation, that thread will continue to impersonate the specified account indefinitely. This is at best a likely cause of bugs, and at worst a security hole. Best to be careful with that.
    From Miles
  • I tried the code in a win-form but did not work !!!! it returns nothing!

    From Data-Base
  • thanks alot, this is perfect... worked straight away I only had to add the references correctly

What is the difference between Scrum and Extreme Programming?

A few years ago I have worked on a green field project where we did Extreme Programming. I also see a lot of people mention the Scrum methodology.

Could someone tell me the main differences between Scrum and XP?

  • I found this article gave a pretty accurate description: here

    From John Sibly
  • Scrum is a project management process, XP is a programming practice. Both are "agile" techniques and are often used together.

    Scrum outlines a process for identifying and cataloging work that needs to be done, prioritizing that work by communicating with the customer or customer representative, and implementing that work using iterative releases.

    When my team first started experimenting with Scrum I found the Implementing Scrum website to be helpful.

  • Scrum is one component of the Agile development methodology concerning the daily meeting held to discuss progress and XP is a different methodology stressing pair programming and test first development.

    From dl__
  • I've worked on both. Some of the main differences are that SCRUM focuses on the shorter more structured sprints, and prioritizes back log items. Some of the focuses of XP are more on paired programming, prioritizing the tasks, and more test driven development. Both work in iterations and both are flexible enough to handle a volatile changing project.

  • Scrum's main goal is to get estimations of how long development will take. XP is more about helping developers get things done as quickly and maintainably as possible.

Ordering numbers that are stored as strings in the database

I have a bunch of records in several tables in a database that have a "process number" field, that's basically a number, but I have to store it as a string both because of some legacy data that has stuff like "89a" as a number and some numbering system that requires that process numbers be represented as number/year.

The problem arises when I try to order the processes by number. I get stuff like:

  • 1
  • 10
  • 11
  • 12

And the other problem is when I need to add a new process. The new process' number should be the biggest existing number incremented by one, and for that I would need a way to order the existing records by number.

Any suggestions?

  • Maybe this will help.

    Essentially:

    SELECT process_order FROM your_table ORDER BY process_order + 0 ASC
    
  • Can you store the numbers as zero padded values? That is, 01, 10, 11, 12?

    Farinha : Hhmm, I guess so. That might be a solution...
    From Andrew
  • I would suggest to create a new numeric field used only for ordering and update it from a trigger.

    From Panos
  • You need to cast your field as you're selecting. I'm basing this syntax on MySQL - but the idea's the same:

    select * from table order by cast(field AS UNSIGNED);
    

    Of course UNSIGNED could be SIGNED if required.

    Farinha : That breaks when I have "numbers" like "62a" and "12/98", like I explained in the question.
    From Remy Sharp
  • Can you split the data into two fields?

    Store the 'process number' as an int and the 'process subtype' as a string.

    That way:

    • you can easily get the MAX processNumber - and increment it when you need to generate a new number
    • you can ORDER BY processNumber ASC, processSubtype ASC - to get the correct order, even if multiple records have the same base number with different years/letters appended
    • when you need the 'full' number you can just concatenate the two fields

    Would that do what you need?

  • Given that your process numbers don't seem to follow any fixed patterns (from your question and comments), can you construct/maintain a process number table that has two fields:

    create table process_ordering ( processNumber varchar(N), processOrder int )
    

    Then select all the process numbers from your tables and insert into the process number table. Set the ordering however you want based on the (varying) process number formats. Join on this table, order by processOrder and select all fields from the other table. Index this table on processNumber to make the join fast.

    select my_processes.*
    from my_processes
      inner join process_ordering on my_process.processNumber = process_ordering.processNumber
    order by process_ordering.processOrder
    
    From tvanfosson
  • It seems to me that you have two tasks here.

    • Convert the strings to numbers by legacy format/strip off the junk
    • Order the numbers

    If you have a practical way of introducing string-parsing regular expressions into your process (and your issue has enough volume to be worth the effort), then I'd

    • Create a reference table such as
    
    CREATE TABLE tblLegacyFormatRegularExpressionMaster(
        LegacyFormatId int,
        LegacyFormatName varchar(50),
        RegularExpression varchar(max)
    )
    
    • Then, with a way of invoking the regular expressions, such as the CLR integration in SQL Server 2005 and above (the .NET Common Language Runtime integration to allow calls to compiled .NET methods from within SQL Server as ordinary (Microsoft extended) T-SQL, then you should be able to solve your problem.

            • See
              http://www.codeproject.com/KB/string/SqlRegEx.aspx


    I apologize if this is way too much overhead for your problem at hand.

  • Suggestion:

    • Make your column a fixed width text (i.e. CHAR rather than VARCHAR).

    • Pad the existing values with enough leading zeros to fill each column and a trailing space(s) where the values do not end in 'a' (or whatever). • Add a CHECK constraint (or equivalent) to ensure new values conform to the pattern e.g. something like

    CHECK (process_number LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][ab ]')
    

    • In your insert/update stored procedures (or equivalent), pad any incoming values to fit the pattern.

    • Remove the leading/trailing zeros/spaces as appropriate when displaying the values to humans.

    Another advantage of this approach is that the incoming values '1', '01', '001', etc would all be considered to be the same value and could be covered by a simple unique constraint in the DBMS.

    BTW I like the idea of splitting the trailing 'a' (or whatever) into a separate column, however I got the impression the data element in question is an identifier and therefore would not be appropriate to split it.

    From onedaywhen

Preventing copy protection circumvention

Anyone visiting a torrent tracker is sure to find droves of "cracked" programs ranging from simple shareware to software suites costing thousands of dollars. It seems that as long as the program does not rely on a remote service (e.g. an MMORPG) that any built-in copy protection or user authentication is useless.

Is it effectively not possible to prevent a cracker from circumventing the copy protection? Why?

  • Copy-protection is like security -- it's impossible to achieve 100% perfection but you can add layers that make it successively more difficult to crack.

    Most applications have some point where they ask (themselves), "Is the license valid?" The hacker just needs to find that point and alter the compiled code to return "yes." Alternatively, crackers can use brute-force to try different license keys until one works. There's also social factors -- once one person buys the tool they might post a valid license code on the Internet.

    So, code obfuscation makes it more difficult (but not impossible) to find the code to alter. Digital signing of the binaries makes it more difficult to change the code, but still not impossible. Brute-force methods can be combated with long license codes with lots of error-correction bits. Social attacks can be mitigated by requiring a name, email, and phone number that is part of the license code itself. I've used that method to great effect.

    Good luck!

    Matthew Scharley : I'd argue that copy-protection isn't "like" security, it IS security on alot of levels. Some more ideas for making things harder is to throw a few exceptions around early, check for attached debugger AFTER this, and other fun things like that. In the end though, everything can be reversed with time.
    Tim Williscroft : We theorized back in the 90's that putting the customers credit card details in the software license would dissuade them for circulating it. What else does the seller know about the buyer that they really don't want anyone else to know? It's just escalating the conflict to taking hostages ( see my answer below)
    Jason Cohen : @Tim -- Nice point, depending on your customers. For example at Smart Bear 95% of our sales are through purchase orders, so that doesn't work. But I like it!
  • I think given enough time a would-be cracker can circumvent any copy-protection, even ones using callbacks to remote servers. All it takes is redirecting all outgoing traffic through a box that will filter those requests, and respond with the appropriate messages.

    On a long enough timeline, the survival rate of copy protection systems is 0. Everything is reverse-engineerable with enough time and knowledge.

    Perhaps you should focus on ways of making your software be more attractive with real, registered, uncracked versions. Superior customer service, perks for registration, etc. reward legitimate users.

    Jason Cohen : I like your reference to Fight Club. :-)
    Bob King : I was wondering if anyone would notice it ;-)
    From Bob King
  • Because it's a fixed defense against a thinking opponent.

    The military theorists beat this one to death how many millennia ago ?

    Yar : Which is why products that update usually do a security revamp on each revision.
  • Basically history has shown us the most you can buy with copy protection is a little time. Fundamentally since there is data you want someone to see one way, there is a way to get to that data. Since there is a way someone can exploit that way to get to the data.

    The only thing that any copy protection or encryption for that matter can do is make it very hard to get at something. If someone is motivated enough there is always the brute force way of getting around things.

    But more importantly, in the computer software space we have tons of tools that let us see how things are working, and once you get the method of how the copy protection works then its a very simple matter to get what you want.

    The other issue is that copy protection for the most part just frustrates your users who are paying for your software. Take a look at the open source model they don't bother and some folks are making a ton of money encouraging people to copy their software.

    Kelly French : Agreed. Since stand-alone games used to make the majority of their profit in the period just after the release date, it seemed that game companies were going to just keep upping the ante with the pirates. I thought online gaming would get rid of these types of measures but now the game companies are using similar technology to prevent online cheating. So, the cycle begins anew.
    From William
  • No, it's not really possible to prevent it. You can make it extremely difficult - some Starforce versions apparently accomplished that, at the expense of seriously pissing off a number of "users" (victims might be more accurate).

    Your code is running on their system and they can do whatever they want with it. Attach a debugger, modify memory, whatever. That's just how it is.

    Spore appears to be an elegant example of where draconian efforts in this direction have not only totally failed to prevent it from being shared around P2P networks etc, but has significantly harmed the image of the product and almost certainly the sales.

    Also worth noting that users may need to crack copy protection for their own use; I recall playing Diablo on my laptop some years back, which had no internal optical drive. So I dropped in a no-cd crack, and was then entertained for several hours on a long plane flight. Forcing that kind of check, and hence users to work around it is a misfeature of the stupidest kind.

    From Peter
  • }} Why?

    You can buy the most expensive safe in the world, and use it to to protect something. Once you give away the combination to open the safe, you have lost your security.

    The same is true for software, if you want people to use your product you must given them the ability to open the proverbial safe and access the contents, obfuscating the method to open the lock doesn't help. You have granted them the ability to open it.

    From Zoredache
  • You can either trust your customers/users, or you can waste inordinate amounts of time and resource trying to defeat them instead of providing the features they want to pay for.

    It just doesn't pay to bother. Really. If you don't protect your software, and it's good, undoubtedly someone will pirate it. The barrier will be low, of course. But the time you save from not bothering will be time you can invest in your product, marketing, customer relationships, etc., building your customer base for the long term.

    If you do spend the time on protecting your product instead of developing it, you'll definitely reduce piracy. But now your competitors may be able to develop features that you didn't have time for, and you may very well end up selling less, even in the short term.

    From Tanktalus
  • This is one occasion where quality software is a bad thing, because if no one whats your software then they will not spend time trying to crack it, on the other hand things like Adobe's Master Collection CS3, were available just days after release.

    So the moral of this story is if you don't want someone to steal your software there is one option: don't write anything worth stealing.

    Piotr Dobrogost : -1 for "This is one occasion where quality software is a bad thing".
    From Unkwntech
  • I think someone will come up with a dynamic AI way of defeating all the currently standard methods of copy protection; heck, I'd sure love to get paid to work on that problem. Once they get there then new methods will be developed, but it'll slow things down.

    The second best way for society to stop theft of software, is to penalize it heavily, and enforce the penalties.

    The best way is to reverse the moral decline, and thereby increase the level of integrity in society.

    Aaron Digulla : Please look up what influence the death penalty has on crimes: None. People don't break the law to piss you off, they are smart. Creating a law that 90% of the population will not follow will not get you anywhere.
    Piotr Dobrogost : @Aaron You missed "and enforce the penalties." part. +1 to make up for -1 (I guess from you). And go for a trip to Switzerland, please.
  • As others point out, you can easily end up frustrating real and legitimate users more than you frustrate the crooks. Always keep your paying users in mind when you develop a circumvention technique.

    If your software is wanted, you have no hope against the army of bored 17 year old's. :)

  • The difference between security and copy-protection is that with security, you are protecting an asset from an attacker while allowing access by an authorized user. With copy protection, the attacker and the authorized user are the same person. That makes perfect copy protection impossible.

    From KeithB
  • In the case of personal copying/non-commercial copyright infringement, the key factor would appear to be the relationship between the price of the item and the ease of copying it. You can increase the difficulty to copy it, but with diminishing returns as highlighted by some of the previous answers. The other tack to take would be to lower the price until even the effort to download it via bittorrent is more cumbersome than simply buying it.

    There are actually many successful examples where an author has found a sweet spot of pricing that has certainly resulted in a large profit for themselves. Trying to chase a 100% unauthorized copy prevention is a lost cause, you only need to get a large group of customers willing to pay instead of downloading illegaly. The very thing that makes pirating softweare inexpensive is also what makes it inexpensive to publish software.

  • "Trying to make bits uncopyable is like trying to make water not wet." -- Bruce Schneier

    Copy protection and other forms of digital restrictions management are inherently breakable, because it is not possible to make a stream of bits visible to a computer while simultaneously preventing that computer from copying them. It just can't be done.

    As others have pointed out, copy protection only serves to punish legitimate customers. I have no desire to play Spore, but if I did, I'd likely buy it but then install the cracked version because it's actually a better product for its lack of the system-damaging SecuROM or property-depriving activation scheme.

  • It is impossible to stop it without breaking your product. The proof:

    Given: The people you are trying to prevent from hacking/stealing will inevitably be much more technically sophisticated than a large portion of your market.
    Given: Your product will be used by some members of the public.
    Given: Using your product requires access to it's data on some level.

    Therefore, You have to released you encrypt-key/copy protection method/program data to the public in enough of a fashion that the data has been seen in it's useable/unencrypted form.
    Therefore, you have in some fashion made your data accessible to pirates.
    Therefore, your data will be more easily accessible to the hackers than your legitimate audience.
    Therefore, ANYTHING past the most simplistic protection method will end up treating your legitimate audience like pirates and alienating them

    Or in short, the way the end user sees it:
    Steal This Comic

  • A lost cause if ever I heard one... of course that doesn't mean you shouldn't try.

    Personally, I like Penny Arcade's take on it: "A Cyclical Argument With A Literal Strawman"alt text

  • There's an easy way, I'm amazed you haven't said so in the answers above. Move the copy protection to a secured area (understand your server in your secure lab). Your server will receive random number from clients (check that the number wasn't used before), encrypt some ever evolving binary code / computation results with clients' number and your private key and send it back. No hacker can circumvent this since they don't have access to your server code.

    What I'm describing is basically webservice other SSL, that's where most company goes nowadays.

    Cons: A competitor will develop an offline version of the same featured product during the time you finish your crypto code.

    From X-Ryl669

How secure are CGI based web apps?

A very well known major drawback of using CGI is poor webserver performance. But how secure are CGI (mainly C/C++) based applications? Are there any major security holes in CGI architecture built on C/C++?

I would like to know some real life implementations of CGI based web apps/web sites. One that I know of is javaranch.com.

  • CGI is no more insecure than any other WSAPI. It's all about what the program does with the code. All CGI does is set environment variables and handles off to the program.

  • The major security hole I would see anywhere, C/C++ included, would be not using a standard, open CGI library, not reading its documentation, and thinking you're secure anyway.

    • don't re-invent the wheel. Use a CGI library. Some languages have this built-in (PHP probably does), others have it included (Perl comes to mind), others need you to grab it from elsewhere (C/C++). Make sure you know what it is, and that you use it. Do not try to implement it yourself. If you have to ask about security, you, like me, are not qualified to write it.
    • Read the documentation. If you're using a well-established library, there will be documentation on security issues and what you can do to avoid them.
    • Do not ever assume you're secure. I'm quite sure I'm not secure, even though I've followed all the rules in the CGI library for Perl, and the rules in the database interface library, etc. But I still assume I'm not secure, and keep it on the forefront of my mind when doing anything there. Should I ever be an expert on security, maybe I'll change my assumption. Not sure yet.

    Security is always multi-faceted, and always incomplete. There are holes being found in all sorts of software all the time - software that may have been previously thought secure. And now we have many more best-practices for security than we did, say, 15 years ago. And we have SELinux for more security.

    Of course, the question is - do you have enough security for your app? Does a reasonable effort get you a reasonable level of security? Of course, that's why I don't use C/C++, but I use Perl instead. It takes a lot less effort to ensure I don't overwrite memory in Perl than it does in C++. That's a level of security right there with no actual work involved.

    From Tanktalus
  • Many sites are CGI based. Many PHP sites that are located on hosting are run in CGI mode - mod_php is hard to used in shared environment - no suid.

    In general, running as CGI has lower performance, but better for security - you have no access to webserver internals (as with mod_perl and mod_php) so using vulnerabilities is harder. If you use cgi-bin, you non-execute files are not visible (a common bug of PHP programmers is that they have libraries with extension like .inc so source is shown when this file is requested directly).

  • Perl's taint-checking mode provides a marvelous way to increase security.

    From skiphoppy

jQuery.ScrollTo / jQuery.SerialScroll Horizontal Scrolling

Hi,

I am looking to implement horizontal scrolling using jQuery.SerialScroll (based on jQuery.ScrollTo).

I currently have a continuous horizontal scrolling working with liScroll as I discuss in this post.

However, now I need discrete scrolling and I have SerialScroll working perfectly for vertical scrolling.

For some reason, if the 'axis' property is specified as 'x' nothing happens.

I can't even get the SerialScroll example for right to left scrolling to work.

I have HTML like this:

<div id="pane">
   <div>Item 1</div>
   <div>Item 2</div>
   <div>Item 3</div>
</div>

I have jQuery like this, that works when axis is 'y'

 jQuery(function($) {
      var $pane = $('#pane');
      $pane.serialScroll({
          items: 'div',
          next: $pane, // the container itself will get bound
          duration: 2100,
          force: true,
          axis: 'x',
          step: 1, //scroll 1 news each time
          event: 'showNext' //just a random event name
       });

       setInterval(function() {//scroll each 12 seconds
          $pane.trigger('showNext');
       }, 12000);
   });

Any ideas?

//Edit (answer accepted)

For those that come along, the accepted answer gets rid of the need for "serialScroll" (just need scrollTo). Heights weren't required. Be sure to change $('scroller') to something like $('mywrap') or $(target.parent().parent()). You can also set up automatic scrolling like this:

 var index = 2;

 setInterval(function() {//scroll each 5 seconds
 index = index > $('#news ul li').length ? 1 : index;
  sliderScroll($('#news ul li:nth-child(' + index + ')'));
  index ++;
 }, 5000);

replacing #news ul li to your appropriate selector.

  • I was recently working with scrollTo to implement a Coda-like slider wizard.

    Here's the steps I took:

    1. Set a containing div to the dimensions I wanted the slider to appear as. overflow:auto; helps for testing, but you'll probably want to use overflow:hidden in the end.
    2. Inside that place another div, make it big enough to hold all your elements horizontally.
    3. Float the panels. give them explicit dimensions.

    My CSS:

    .scroller{
      position: relative;
      overflow: hidden;
      height: 410px;
      width: 787px;}
      .modal-content{width: 3400px;}
        .modal-content div{float:left; width:728px; height: 405px; padding: 0 30px;}
    

    My JS:

    function sliderScroll(target){
      if(target.length <1)return false;
      $(".current").removeClass("current");
      target.addClass("current");
      $(".scroller").scrollTo(target,500,{axis:'x'});
      return false;
    }
    

    My HTML:

    <div class="scroller">
      <div class="modal-content">
         <div>...</div>
         ...
      </div>
    </div>
    
    Graphain : Great! - For those interested please see my edits in the question for some minor modifications.

What compels you to attend your local user group(s)?

So I'm in Des Moines, Iowa and we have a good number of user groups in our area considering our size. Ruby, .Net, Java, Agile, *nix, etc... Well, tonight a good number of us "leaders" of said user groups got together for a couple drinks and to talk about how we can work together to help make the "DeMo" (I keep seeing this on Twitter) user group scene better.

We came up with a number of rather good ideas, but I'm curious. What compels you to attend your local user group(s)? Dig deep here guys. Maybe it is the free pizza, or the give aways. But I'm more interested to know about things out side of the freebie stuff.

  • I've always found the professional networking to be completely invaluable. I got my current job because of the Denver Java Users Group and it was one of the best choices I've ever made.

  • I agree with Eric. I also enjoy seeing how others approach problems and what solutions they have in place. The reason is, if you're not a consultant, you work with the same set of individuals and it helps to bring fresh new ideas into the group.

  • Many people really have different reasons for attending, with many of them denying it but are really just after the food and schwags (of course I kid ^_^). But there are a few other things that interest me, particularly:

    • Professional networking (as Eric stated above)
    • Ability to find out what I've missed out on (if I'm not "drinking from the fire hose" on Google Reader because I was uber-busy)
    • Certificate of participation (some employers use UG participation as points towards merit)
    • Brownie points on resumes (if you are the speaker, that is)
    • Food and schwag (oops, mentioned that already)
    From Jon Limjap
  • I know of 3 different types of events around here for local user groups where each has its own pull:

    1) Presentations/Talks - Where someone comes in and talks for an hour or two on a subject to either introduce or advance the knowledge of a technology. So, an introduction Dependency Injection or Windows Workflow are a couple of examples. There are also what are called "deep dives" where the idea is to get really down into the topic and see various tips and tricks and try to improve how all of us develop software well. There are times where Microsoft will rent a movie theater screen for a day and have a series of 4 presentations about their latest technologies would be another example here. This can also include things like the Agile Project Leadership Network.

    2) Code camp - These are sooo cool, I love these where part of the idea is that people volunteer to show something off, and the work isn't canned. By canned I mean that the demonstration code is all prepared and we can't see how long it took to get the code to be that way, e.g. a dozen files of code that took a dozen hours to get from nothing to this state that in a demo may seem like this should just come out within a few hours which isn't realistic. Here they have taken a few rooms at a local university to do it. One blogger's view of one a couple of years ago.

    3) Open spaces - This was an awesome event that I really look forward to the next one. A bunch of other developers come together and self-organize discuss whatever we want in a sense. The discussions had were varied and in some cases the results weren't great, like how do we get others to take their off time and come to these things or other ways to volunteer our skills beyond open source projects. What was going on the first day link.

    Each of the last two occur on a weekend so it isn't during work hours. Sometimes the joy of seeing something new or a better way to do something can really be rewarding, in addition to the good networking opportunity where you'll never know where the people are that come to these things as the Open Spaces had a few people from other countries present which added a nice diversity dimension to things.

    Are there other local user group type events?

    From JB King
  • I really just like the idea of meeting people who are as excited about a certain topic as I am; it's exciting and inspiring. Especially since I live in a fairly small midwestern town, people with common interests in computer technologies will not be very abundant, so the social aspect is really appealing

  • A little different approach, but I can tell you what keeps me away... I've always been interested in going, but just don't make it to any of them.

    • Most of them seem to be in small towns an hour away, right after work, so I'd miss a significant portion of the meeting.
    • The rare one that meets here in the city seems to want to meet at night in a part of town I don't want to go to even during the day.
  • Because I get to see cool things like this (video - RFID deadbolt with embedded RFID tag. And I do mean embedded!)

    Of course, this is one of the few groups I make time for - I don't have time to attend every group I'd like to, but this one has a mix of interesting Make, software, etc so they're never boring.

    Try to understand what your users need, and provide it is the best advice I can give. Only you know your audience.

    From Adam Davis
  • I have been attending local JUG meetings for some time and based on that I would say:

    • Networking, this is important for me as I have recently relocated
    • Organizing the event itself can be fun
    • Free beer!

Python's __import__ doesn't work as expected

When using __import__ with a dotted name, something like: somepackage.somemodule, the module returned isn't somemodule, whatever is returned seems to be mostly empty! what's going on here?

  • From the python docs on __import__:

    __import__( name[, globals[, locals[, fromlist[, level]]]])
    

    ...

    When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned. This is done for compatibility with the bytecode generated for the different kinds of import statement; when using "import spam.ham.eggs", the top-level package spam must be placed in the importing namespace, but when using "from spam.ham import eggs", the spam.ham subpackage must be used to find the eggs variable. As a workaround for this behavior, use getattr() to extract the desired components. For example, you could define the following helper:

    def my_import(name):
        mod = __import__(name)
        components = name.split('.')
        for comp in components[1:]:
            mod = getattr(mod, comp)
        return mod
    

    To paraphrase:

    When you ask for somepackage.somemodule, __import__ returns somepackage.__init__.py, which is often empty.

    It will return somemodule if you provide fromlist (a list of the variable names inside somemodule you want, which are not actually returned)

    You can also, as I did, use the function they suggest.

    Note: I asked this question fully intending to answer it myself. There was a big bug in my code, and having misdiagnosed it, it took me a long time to figure it out, so I figured I'd help the SO community out and post the gotcha I ran into here.

    From dwestbrook
  • There is something that works as you want it to: twisted.python.reflect.namedAny:

    >>> from twisted.python.reflect import namedAny
    >>> namedAny("operator.eq")
    <built-in function eq>
    >>> namedAny("pysqlite2.dbapi2.connect")
    <built-in function connect>
    >>> namedAny("os")
    <module 'os' from '/usr/lib/python2.5/os.pyc'>
    
    dwestbrook : That's very useful, however I don't really have any other need for twisted in my program. Although, as the founder (!), you are probably more knowledgeable of the possibilities than me (never used it).
    From Glyph