Windows WTF



  • Just found this while reading the MSDN documentation on the IsThemeActive() function:


    Remarks:

    Do not call this function during DllMain or global objects contructors. This may cause invalid return values in Windows Vista and may cause Microsoft Windows XP to become unstable.


  • Lovely....

     

    So could this "instability" in XP indicate a security vulnerability?

    I mean cheking if a theme is active shouldn't destabilize the OS.

    Besides, if they know there's a problem with this function, why don't they fix it or put a sanity test at the beginning that senses this? 



  • In working with Infragistics 2006 Vol 3 for WinForms we've had instances where the Zune XP theme causes Infragistics to blow chunks, and more recently an XP machine with the Windows Classic theme and the Tulips background to blow up some specific Infragistics components.

     

    Maybe they're making that call?  :-{



  • I guess every system needs "the ultimate kill button"... Windows XP has IsThemeActive()...



  •  Well, DllMain is a bit special and there are some pretty restrictive rules about what can and cannot be done inside any DllMain.

     More info in the DllMain "Remarks" section, and there's even a white paper on this topic...

    (oh hi BTW, long time reader, first time poster) 



  • @Carnildo said:

    MSDN documentation
     

    Thanks for the link!



  • @MasterPlanSoftware said:

    @Carnildo said:

    MSDN documentation
     

    Thanks for the link!

    You're not familiar with MSDN, are you? They reorganize it at random, and every time they do, most of the links to it stop working. Your best bet is to do a Google search for "IsThemeActive site:msdn.microsoft.com".



  • @MasterPlanSoftware said:

    @Carnildo said:

    MSDN documentation
     

    Thanks for the link!

     

    [url=http://msdn.microsoft.com/en-us/library/bb759813(VS.85).aspx]you're welcome[/url] 



  • @Carnildo said:

    You're not familiar with MSDN, are you? They reorganize it at random, and every time they do, most of the links to it stop working.

    Obviously a huge problem since this thread will be up for many years and if the link stopped working at any point everyone would hate you.

     

    It's a bit WTFy that this causes system instability in XP and doesn't just crash your app.  There are all kinds of problems with dependencies in C++ static object constructors, though, so I'd imagine this is just an extension of that.  In general, you can't do a lot in global constructors without running into some problems and this function (and a few others I found in a similar vein) all return info on the current app's window properties which probably hasn't been set up before main is invoked.  It's well-documented and other than the problem with it causing "system instability" in XP, seems quite reasonable.  Still, if anyone has more of an idea about the why behind this (esp. the instability part) I'd love to hear it.  I'm not a Windows or C++ dev, so don't take my word as gospel.



  • @Carnildo said:

    @MasterPlanSoftware said:

    @Carnildo said:

    MSDN documentation
     

    Thanks for the link!

    You're not familiar with MSDN, are you? They reorganize it at random, and every time they do, most of the links to it stop working. Your best bet is to do a Google search for "IsThemeActive site:msdn.microsoft.com".

     

    Or... YOU could do it. Since you POSTED it.



  • Global objects in DLL are constructed in DllMain context, too, so that part is redundant.

    Because of restriction of what DllMain can call (answer: pretty much only kernel32.dll functions), such remark shuld be assumed for most other functions. It looks like some piece of soft actually called the function in question, causing system indigestion.

    About WinXP becoming unstable: I suspect some display driver could not handle it.



  • @morbiuswilters said:

    @Carnildo said:

    You're not familiar with MSDN, are you? They reorganize it at random, and every time they do, most of the links to it stop working.

    Obviously a huge problem since this thread will be up for many years and if the link stopped working at any point everyone would hate you.

    I don't like posting links if I can't be sure they'll still work tomorrow.



  • @Carnildo said:

    I don't like posting links if I can't be sure they'll still work tomorrow.

    This must be very hard for you since most of the Web is fairly dynamic and there's no guarantee a link will work in the future.  Look, MSDN isn't going to update tonight and they did it nobody would jump on your ass for posting a bum link.  If sentient cockroaches unearth your post in 3179 and the link doesn't work, they'll probabaly be smart enough to use Google or their sentient cockroach equivalent.  However, we are in the year now() and we are lazy and there is no reason to not provide a link.  Stop trying to pretend you had some strong moral conviction against posting a goddamn link and just admit you forgot.  Or better yet, stfu about it because the link has already been posted and nobody cares anyway.



  • @Carnildo said:

    I don't like posting links if I can't be sure they'll still work tomorrow.
     

    Here, I will help you out since you seem to be challenged by this seemingly simple task.

    MSDN article (Google.com first result)

    Cached article

    MSDN Article (currently)



  • @morbiuswilters said:

    and nobody cares anyway.
     

    Indeed, I thought it was a simple request.

    Really though, the OP is pretty mug worthy altogether.

     

    OMG! You can cause unpredictable behavior with bad codez!!!



  • Additionally in the DllMain docs, in order to make an initialization routine that is only called once, their suggestion is "the initialization routine can create a file with an ACL that restricts access, and each routine in the DLL would call the initialization routine if the file does not exist." Is there really no better way to do this? No say global variable you can create?



  • @Talchas said:

    Additionally in the DllMain docs, in order to make an initialization routine that is only called once, their suggestion is "the initialization routine can create a file with an ACL that restricts access, and each routine in the DLL would call the initialization routine if the file does not exist." Is there really no better way to do this? No say global variable you can create?

    In Unix one of the most common ways to create a mutex across processes is an exclusively-created file.  The file isn't usually written to disk but only cached in memory by the kernel.  Don't know what options are available under Windows, but I wouldn't be surprised if the idiom were the same there. 



  • @morbiuswilters said:

    an exclusively-created file
     

    No way! Globals!



  • @Talchas said:

    Additionally in the DllMain docs, in order to make an initialization routine that is only called once, their suggestion is "the initialization routine can create a file with an ACL that restricts access, and each routine in the DLL would call the initialization routine if the file does not exist." Is there really no better way to do this? No say global variable you can create?

    This is quite cumbersome approach and only makes sense if you want to uniquely initialize something systemwide, in which case it would be very unwise to do that in DllMain. The better way would be then to create a global named volatile object, which could be any kernel object, or volatile (non-persistent across reboot) registry key.

    Actually, DllMain is only called once with DLL_PROCESS_ATTACH code, and this call is serialized vs all other DllMain in the given process. You don't need any other means of serialization for that.



  • @MasterPlanSoftware said:

    No way! Globals!

    When is ammoQ going to wise up and finally ban you?  Maybe he's just not man enough to make that move, but I remember a German who was man enough...  He led the German people out of a major economic depression and towards world domination.  Some called him a murderer, others a hero.  Perhaps ammoQ is afraid he won't live up to the expectations his nationality has set, but I believe he will come through for us.  Amen.



  • @morbiuswilters said:

    Some called him a murdered
     

     @morbiuswilters said:

    his nationality have set

     



  • @morbiuswilters said:

    @Talchas said:

    Additionally in the DllMain docs, in order to make an initialization routine that is only called once, their suggestion is "the initialization routine can create a file with an ACL
    that restricts access, and each routine in the DLL would call the
    initialization routine if the file does not exist." Is there really no better way to do this? No say global variable you can create?

    In Unix one of the most common ways to create a mutex across processes is an exclusively-created file.

    That's nice because you aren't depending on a specific *nix's threading techniques. Windows, on the other hand, has a decent set of thread-related functions that have been available at least since Win98, so there should be no reason to use files for synchronization.



  • @Carnildo said:

    That's nice because you aren't depending on a specific *nix's threading techniques. Windows, on the other hand, has a decent set of thread-related functions that have been available at least since Win98, so there should be no reason to use files for synchronization.
     

    You are right. We are all wrong, and so is MS. Obviously no one knows what they are doing except you.

     

    Please guide us through the fog of ignorance!


  • @Carnildo said:

    That's nice because you aren't depending on a specific *nix's threading techniques. Windows, on the other hand, has a decent set of thread-related functions that have been available at least since Win98, so there should be no reason to use files for synchronization.

    Is this about threading or something else, though?  It seems to me like they would use a memory address available to all threads if that were the best solution, but since they suggest otherwise it seems that is not a possibility.  I mean, Microsoft doesn't hire absolute idiots to write their OS and I assume most of their employees are probably smarter than 99% of the people here, so there is probably a good reason for this.  It always surprises me that people excuse Unix idioms that initially seem bizarre because "it's tradition" but won't hold back to flame MS for some suggestion the company makes, without even understanding why (or at least posting an explanation for people like myself who are don't know).  My post was more to point out that it's not a huge WTF to use the filesystem to ensure mutual exclusion, but once again, I am not a Winders developer. 



  • @morbiuswilters said:

    ...
     

    Well done. I have lost my patience with the anti-MS trolling nature of this thread. No backup of any kind, just wild speculation that this is the end of the world.

     

    You are a better man than me.



  • @MasterPlanSoftware said:

    @Carnildo said:

    That's nice because you aren't depending on a specific *nix's threading techniques. Windows, on the other hand, has a decent set of thread-related functions that have been available at least since Win98, so there should be no reason to use files for synchronization.
     

    You are right. We are all wrong, and so is MS. Obviously no one knows what they are doing except you.

    Would you please not put words in my mouth?

    My point is that, in an ideal world, it would be possible to use Windows' threading primitives for coordination between threads: if you want something to be done only once, you use a mutex or other threading primitive to coordinate it, rather than creating a flag file on disk.



  • I distinctly remembering seeing CreateMutex() or something of the sort used in a single-instance example that shipped with VC++ 6. Granted, that was WinMain(), not DllMain(), but mutexes can't be implemented anywhere but kernel32... can they?!

    Much better than non-atomic disk operations, that's for sure.



  • @Carnildo said:

    Remarks:

    Do not call this function during DllMain or global objects contructors. This may cause invalid return values in Windows Vista and may cause Microsoft Windows XP to become unstable.

    What surprises me is that nobody picks up on the fact that calling a function in Vista makes XP unstable. Of course this is a faulty edit, but everyone here seems to think XP and Vista are the same thing, as apparently the editor of the docs did...



  • @TGV said:

    @Carnildo said:

    Remarks:



    Do not call this function during DllMain or global objects contructors. This may cause invalid return values in Windows Vista and may cause Microsoft Windows XP to become unstable.

    What surprises me is that nobody picks up on the fact that calling a function in Vista makes XP unstable. Of course this is a faulty edit, but everyone here seems to think XP and Vista are the same thing, as apparently the editor of the docs did...

    Aren't they all windows 2000?



  • @morbiuswilters said:

    When is ammoQ going to wise up and finally ban you?  Maybe he's just not man enough to make that move, but I remember a German who was man enough...  He led the German people out of a major economic depression and towards world domination.  Some called him a murderer, others a hero.  Perhaps ammoQ is afraid he won't live up to the expectations his nationality has set, but I believe he will come through for us.  Amen.

     

    Only Alex can ban people. Normal mods like me can moderate posts (edit, delete, lock). BTW, I'm not a German, but an Austrian. That other guy originated in Austria, too. 



  •  I like the time machne in Windows that allows you to modify a file 3 years before it is created

     

    [img]http://www.zweg.com/dump/photo/picwtf.png[/img]

     



  • @Summer.Glau said:

    I like the time machne in Windows that allows you to modify a file 3 years before it is created
    OMG it's Summer Glau.

    @River Tam said:

    The human body can be drained of blood in three seconds.
     



  • @Summer.Glau said:

    I like the time machne in Windows that allows you to modify a file 3 years before it is created
    That's not a WTF. The file you're looking at was last modified in 2004, and was copied or moved to it's current location in 2007, but it was not modified at that time. Thus the creation date is newer than last modified date.



  • The "and" doesn't work like that in this sentence. I read it as joining the two different possibilities, without the first one implying the second.



  • @Adriano said:

    The "and" doesn't work like that in this sentence. I read it as joining the two different possibilities, without the first one implying the second.
    What sentence?



  • @belgariontheking said:

    What sentence?
     

    The OP's quoted sentence about the bug's effects. And Adriano is right.



  • @teqman said:

    I distinctly remembering seeing CreateMutex() or something of the sort used in a single-instance example that shipped with VC++ 6. Granted, that was WinMain(), not DllMain(), but mutexes can't be implemented anywhere but kernel32... can they?!

    Much better than non-atomic disk operations, that's for sure.

    I don't think this has anything to do with threading, it's about controlling initialization order within a single thread.  Due to the way C++ behaves, it is almost impossible to determine the order that dependencies within a static object constructor will fire so you have to usually add the dependencies everywhere and use a flag (not mutex) to prevent the dependencies from being initialized more than once.  Mutexes are used to synchronize access to a resource by multiple processes or threads, so they are of no help here.  I'm going out on a limb here, but my guess is that the way C++ compilers arrange allocation and initialization of global variables makes it difficult to use them as flags.  For example, a global constructor that needs the variable could fire off before the variable is actually initialized.  There's probably a reasonable explanation for using lock files instead of flag variables.

     

    The disk operations that are commonly used on Unix are atmoic so I would assume the same applies to Windows which usually has more robust options for file access.



  • That's not a WTF. The file you're looking at was last modified in 2004, and was copied or moved to it's current location in 2007, but it was not modified at that time. Thus the creation date is newer than last modified date.
    Yes, i know *why* the creation date is newer than last modified date --  in June 2007 I replaced my secondary hard drive and then copied all the files from the old drive to the new drive.  But what if I want to know when a particular file was originally created?  If you change the creation date on a file every time it is copied or moved, you have rendered that information useless.  and that's TRWTF.



  • @Summer.Glau said:

    That's not a WTF. The file you're looking at was last modified in 2004, and was copied or moved to it's current location in 2007, but it was not modified at that time. Thus the creation date is newer than last modified date.
    Yes, i know *why* the creation date is newer than last modified date --  in June 2007 I replaced my secondary hard drive and then copied all the files from the old drive to the new drive.  But what if I want to know when a particular file was originally created?  If you change the creation date on a file every time it is copied or moved, you have rendered that information useless.  and that's TRWTF.

    At least you Winders users have a creation date for your files.  Us Unix folks just have to guess.

     

    Also: lern2quote 



  • @Summer.Glau said:

    But what if I want to know when a particular file was originally created?
     

    Welcome to Windows. 

    Maybe when MS gets done pleasing the 90+% of the market share, they will give you a call and ask what they can fix for you today.



  • @teqman said:

    Much better than non-atomic disk operations, that's for sure.

    On *nix, opening a file with O_CREAT|O_EXCL is an atomic operation that will succeed if the file doesn't exist, or return an error code if the file exists. I presume that since Windows supports the POSIX open() function with those flags, it's also an atomic operation on Windows.



  • @dlikhten said:

    I guess every system needs "the ultimate kill button"... Windows XP has IsThemeActive()...

     

    I think this feature is ingenious. I use it all the time because logging off takes too long.

     

    WindowsXP


  • @quarnel said:

    I think this feature is ingenious. I use it all the time because logging off takes too long.

    This is the best post in this thread.  Bonus points because it was posted by a n00b.  This one has potential, if only he can be turned to the dar good side.



  • Unfortunately I don't see anything in the CreateFile() documentation that states that it's atomic. Moreover, since temporary files are stored in your profile directory, it's very likely that the path you would use to create one is located on a network volume, and therefore CreateFile can't be atomic.



  • @teqman said:

    Unfortunately I don't see anything in the CreateFile() documentation that states that it's atomic. Moreover, since temporary files are stored in your profile directory, it's very likely that the path you would use to create one is located on a network volume, and therefore CreateFile can't be atomic.

    CREATE_NEW flag gives you atomicity guarantee. Even on a network volume. Otherwise it would be possible to create two files with the same name, and no filesystem worths its bits would allow that.

     


Log in to reply