What is the problem with DLLs and the Registry? - windows

I was watching the WWDC 2009 Keynote and something someone said about Windows 7/Vista got me curious..
The speaker claimed that 7 was still a poor operating system because it still used the same technologies such as DLLs and the registry. How accurate are his claims and how different is OS X doing it? Even os x has dynamically loaded libraries right? I guess the Registry thing might have some weight..
Can anyone explain to me the differences in each OS' strategy?
I'm not trying to incite fanboys here or anything, I just want to know how both operating systems tackle problems in general..
Thanks,
kreb

Of course both operating systems have facilities for using DLLs (they're called dylibs or Frameworks on OS X depending on how they're packaged).dylibs are very much like DLLs--they are a dynamically linked library and as such there may be multiple versions of them floating around. Frameworks, on the other hand, are really a directory structure. They contain dynamically linked libraries (potentially multiple versions of them), resources, headers, documentation, etc. The dynamic linker on OS X automatically handles choosing the correct library version from the framework for each executable. The system appears to work better than Windows' DLL management which is, well, quite a mess still (of course, Windows' system is tied by legacy issues that Apple dropped when they moved to OS X). To be fair, Unix has had a solution to this problem for a long time, as well using symbolic links to link dylibs to their correct versioned implementation, allowing multiple installed versions.
There is no OS X equivalent of the Windows registry. This is good and bad. The good side is that it's much harder to corrupt an entire OS X system with a registry screw up. OS X instead stores configuration in many separate files, usually one or more per application, user, whatever. These files are generally a plist (an XML schema representing dictionaries, arrays, and primitive types) formatted file. The bad side is that, by retaining this Unix-y heritage, OS X doesn't have the same über-admin tools that can churn through the registry and do all sorts of crazy things.

DLLs
The major difference between OS X and Windows is that Windows historically tried to save space/memory by having everyone share code (i.e. you install one DLL, everyone can use it). Apple statically compiles (well, not really, but it may as well be) all of the non-system libraries into every application. Wastes disk space/memory, but makes app deployment way easier and no versioning issues.
Registry
OS X does have a registry, they're just flat files called plists, instead of a magic component that's mostly like a filesystem except where it's not. Apple's approach makes it easy to migrate settings from one machine to another, whereas Windows' approach is faster in-memory, and allows apps to easily "watch" a key without taking a big perf hit (i.e. one app changes a key and the other instantly knows about it).
In conclusion
The keynote presenter's full of it, 10.6 is mostly the same code as 10.5, which was mostly the same code as 10.4 et al, just like Win7 is mostly Vista, which is mostly Server '03, etc. There's far too much tested code in an operating system to throw it away every release, especially if you actually want your customers' apps to work.

DLL's are bad variations of libaries since they are unable to operate on their own, to use them a further wrapper executable is called(automatically), which adds unrequired overhead and makes it much harder to tell which libraries are actually in use. Another less important flaw, is the inability for systems to truely share a library.
*nix systems avoid this by having libraries exist on the top level running on their own or under a larger wrapper(like kde-init ), the libraries may be shared by any applications, meaning only a single copy of each library is required, and you may at any time kill a single library with ease as required.
The registry is a great idea, except for the fact that it is used for so much, almost anything you install will use the registry, and a corrupt registry and render your operating system almost completely useless until it's fixed.
This is avoided in *nix systems by having multiple different files for different content, drivers are refered to via Xorg's config file, installed applications will be written to their own database, and keys or identification will often be written into a directory, rather than a single all purpose file. This reduces the likely hood of a serious failure and means that at any time you can probably still repair the system. If Xorg becomes corrupt you just reconfigure it, if the installed applications database becomes corrupt you can repair or rebuild it, and should an applications individual settings directory become corrupt you need only reinstall one application(and most good commercial aps should have a way to repair this anyway)

Related

What is the difference between "binary install" and "compile and install from source"? Which is better?

I want to install a driver for Ros (robot operating system), and I have two options the binary install and the compile and install from source. I would like to know which installation is better, and what are the advantages and disadvantages of each one.
Source: AKA sourcecode, usually in some sort of tarball or zip file. This is RAW programming language code. You need some sort of compiler (javac for java, gcc for c++, etc.) to create the executable that your computer then runs.
Advantages:
You can see what the source code is which means....
You can edit the end result program to behave differently
Depending on what you're doing, when you compile, you could enable certain optimizations that will work on your machine and ONLY your machine (or one EXACTLY like it). For instance, for some sort of gfx rendering software, you could compile it to enable GPU support, which would increase the rendering speed.
You can create a version of an application for a different OS/Chipset (see Binary below)
Disadvantages:
You have to have your compiler installed
You need to manually install all required libraries, which frequently also need to be compiled (and THEIR libraries need to be installed, etc.) This can easily turn a quick 30-second command into a multi-hour project.
There are any number of things that could go wrong, and if you're not familiar with what the various errors mean, finding support online could be quite difficult.
Binary: This is the actual program that runs. This is the executable that gets created when you compile from source. They typically have all necessary libraries built into them, or install/deploy them as necessary (depending on how the application was written).
Advantages:
It's ready-to-run. If you have a binary designed for your processor and operating system, then chances are you can run the program and everything will work the first time.
Less configuration. You don't have to set up a whole bunch of configuration options to use the program; it just uses a generic default configuration.
If something goes wrong, it should be a little easier to find help online, since the binary is pre-compiled....other people may be using it, which means you are using the EXACT same program as them, not one optimized for your system.
Disadvantages:
You can't see/edit the source code, so you can't get optimizations, or tweak it for your specific application. Additionally, you don't really know what the program is going to do, so there could be nasty surprises waiting for you (this is why Antivirus is useful....although LESS necessary on a linux system).
Your system must be compatible with the Binary. For instance, you can't run a 64-bit application on a 32-bit operating system. You can't run an Intel binary for OS X on an older PowerPC-based G5 Mac.
In summary, which one is "better" is up to you. Only you can decide which one will be necessary for whatever it is you're trying to do. In most cases, using the binary is going to be just fine, and give you the least trouble. Sometimes, though, it is nice to have the source available, if only as documentation.

What do we need installations for?

This is a conceptual question and I hope it fits into Stackoverflow's question and answer style. I wonder what the concept of installing applications is good for. In my naive understanding of operating systems we do not need a registry and to use an application it should be enough to just copy the executable and files onto your drive and launch that.
Am a Windows user but also worked with Linux a bit and noticed that there are package managers instead of installers. But even those do more than just a copy instruction, I guess.
I do not think that all the installers exist only because the common user expects them out of steady habit. So what is the advantage of installers in contrast to developing applications which are designed to run out of a single folder and copy that over?
I would really like if someone could explain that concept.
Installing applications is a way to embed them in the OS. It's a kind of standard, you offer procedures like installing and uninstalling that should have the same functionalities for all applications (even "change" under Windows).
Countless times I've "installed" applications with a single shell script that came with them, and then had troubles removing such programs, having to look for single files. If the programmer uses the standard of the OS to make an executable that can be installed, that won't happen.
You can also easily view a list of the installed programs at any time.
Under Linux, additionally, if we're talking about a package manager, it is convenient for the user to have an easy way to download and install a program by just typing its name.
Last but not least, some applications are required to be installed and recognized by the OS (for example services in Windows).

What are the effects of the PE header "subsystem" field?

I have several questions about the PE "subsystem" field, which may overlap to some extent. To avoid spamming this place with each question separately, I thought I'd ask them together and then re-ask separately anything that doesn't get addressed. Hope this is OK...
I know that IMAGE_SUBSYSTEM_WINDOWS_CUI makes the OS "pre-attach" the process to a console, either of its parent process or creating a new console if necessary. IMAGE_SUBSYSTEM_WINDOWS_GUI doesn't do that.
Are there any other differences between these two in a modern version of Windows? Have there been more in the past?
What about the other values, are they used by Windows merely to reject an EXE, or do they cause Windows to emulate a different API? Is this "emulation" process extensible by end-users or is this hard-baked into the OS?
Yes, pre-attaching a console seems to be the only current difference. If memory serves, that wasn't so much the case with the 16-bit based versions of Windows though (95/98/SE/Me).
Older versions of NT accepted other values for the POSIX and OS/2 subsystems.
In theory, you might be able to write your own subsystem using the NT Native API. Although there's a fair amount of documentation around for that if you look, I'm not at all sure it's sufficient to this task. The Win32 subsystem has always had rather a "special" status anyway, and now that the other subsystems are gone, I'm not at all sure they've even tried to assure that other subsystems can be integrated. On NT 4 (for one example) I'd have said "difficult but almost certainly possible". On a current version of Windows, I'd say there's about even odds that some change to the kernel would prevent it from working -- and much lower than even odds that the currently-available documentation would be up to the task of anybody but MS implementing a subsystem.

Finding undocumented APIs in Windows

I was curious as to how does one go about finding undocumented APIs in Windows.
I know the risks involved in using them but this question is focused towards finding them and not whether to use them or not.
Use a tool to dump the export table from a shared library (for example, a .dll such as kernel32.dll). You'll see the named entry points and/or the ordinal entry points. Generally for windows the named entry points are unmangled (extern "C"). You will most likely need to do some peeking at the assembly code and derive the parameters (types, number, order, calling convention, etc) from the stack frame (if there is one) and register usage. If there is no stack frame it is a bit more difficult, but still doable. See the following links for references:
http://www.sf.org.cn/symbian/Tools/symbian_18245.html
http://msdn.microsoft.com/en-us/library/31d242h4.aspx
Check out tools such as dumpbin for investigating export sections.
There are also sites and books out there that try to keep an updated list of undocumented windows APIs:
The Undocumented Functions
A Primer of the Windows Architecture
How To Find Undocumented Constants Used by Windows API Functions
Undocumented Windows
Windows API
Edit:
These same principles work on a multitude of operating systems however, you will need to replace the tool you're using to dump the export table. For example, on Linux you could use nm to dump an object file and list its exports section (among other things). You could also use gdb to set breakpoints and step through the assembly code of an entry point to determine what the arguments should be.
IDA Pro is your best bet here, but please please double please don't actually use them for anything ever.
They're internal because they change; they can (and do) even change as a result of a Hotfix, so you're not even guaranteed your undocumented API will work for the specific OS version and Service Pack level you wrote it for. If you ship a product like that, you're living on borrowed time.
Everybody here so far is missing some substantial functionality that comprises hugely un-documented portions of the Windows OS RPC . RPC (think rpcrt4.dll, lsass.exe, csrss.exe, etc...) operations occur very frequently across all subsystems, via LPC ports or other interfaces, their functionality is buried in the mysticism incantations of various type/sub-type/struct-typedef's etc... which are substantially more difficult to debug, due to the asynchronous nature or the fact that they are destine for process's which if you were to debug via single stepping or what have you, you would find the entire system lockup due to blocking keyboard or other I/O from being passed ;)
ReactOS is probably the most expedient way to investigate undocumented API. They have a fairly mature kernel and other executive's built up. IDA is fairly time-intensive and it's unlikely you will find anything the ReactOS people have not already.
Here's a blurb from the linked page;
ReactOS® is a free, modern operating
system based on the design of Windows®
XP/2003. Written completely from
scratch, it aims to follow the
Windows® architecture designed by
Microsoft from the hardware level
right through to the application
level. This is not a Linux based
system, and shares none of the unix
architecture.
The main goal of the
ReactOS project is to provide an
operating system which is binary
compatible with Windows. This will
allow your Windows applications and
drivers to run as they would on your
Windows system. Additionally, the look
and feel of the Windows operating
system is used, such that people
accustomed to the familiar user
interface of Windows® would find using
ReactOS straightforward. The ultimate
goal of ReactOS is to allow you to
remove Windows® and install ReactOS
without the end user noticing the
change.
When I am investigating some rarely seen Windows construct, ReactOS is often the only credible reference.
Look at the system dlls and what functions they export. Every API function, whether documented or not, is exported in one of them (user, kernel, ...).
For user mode APIs you can open Kernel32.dll User32.dll Gdi32.dll, specially ntdll.dll in dependancy walker and find all the exported APIs. But you will not have the documentation offcourse.
Just found a good article on Native APIS by Mark Russinovich

Does a newly produced mac application need to support 10.4, and can I both support 10.4 and prepare for 64bit?

My company is in the process of rewriting our software from scratch, and I'm the one who is going to be doing most of the work in rewriting the Mac client (The core of our software is Windows based, and the Mac client communicates with it through a webservice).
This isn't a real heavy app, mainly does some background work tracking stuff and a UI component for the user to enter information.
I'm trying to decide how hard I should argue for dropping support for 10.4 and going with pure 10.5+/Obj-C 2.0 code.
My main motivations for this are:
It would be easier to code, I could use all the features of Obj-C 2.0 such as synthesized properties and fast enumeration.
It would give me access to several classes, and methods in existing classes, that don't exist in 10.4 (Just in mocking up a UI I've come across NSPathControl and NSTreeNode, both of which I would otherwise be very happy to use.
Preparing for the conversion to 64 bit coming in Snow Leopard. It seems like most of the techniques for preparing for the move to 64 bit (NSInteger, etc) are only available in 10.5+, and it would not be possible to use these if writing for 10.4.
The downside would of course be that we'd no longer be supporting an operating system that was only a year out of date.
My boss is himself supportive of this move, but of course has our customers to consider and doesn't want to cause any more issues for them than are justified. The director of support would like to support 10.4. I suspect the other execs will be marginally against it at first, just due to the not being able to support some customers thing. Everybody would be open to persuasion by a good argument from either side.
I'm trying to talk to some of the support people and get an idea of how many of our customers are actually still using 10.4, but I don't have that data yet.
Some kind of hybrid solution might be possible, such as rewriting parts of the old client to use the new webservice, or writing the client in 10.5 and backporting it to 10.4 if enough people made a fuss, but quite frankly those sound like they're likely to be even more trouble than giving up the 10.5 features and writing the code in 10.4 to begin with.
So I guess my questions are as follows:
Given the information above, do you think making a case for the adoption of 10.5+ only is the right thing to do? Do you have any suggestions as to how this might be presented positively to the rest of the company?
I don't know as much about the coming 64 bit transition as I'd like. Does anybody have any good references on what will be different, and do you think that supporting only 10.5+ would make this transition easier for us?
If it were I doing the update, I would target 10.5, especially since 10.6 is just around the corner and 10.5 did come out with a lot of great, new things (especially Objective-c 2.0). However, I think you really need to answer this question based on what you think your target customer group will be using. If they are slow to adopt new technology, it may be that you have to support 10.4 or risk losing a portion of your customer base.
On the other hand, you can actually target 10.4 and write using the 10.5 SDK. That way you can take advantage of all the preparations for 64-bit added to the SDK. You just have to ensure that you don't use any classes or features of the frameworks that didn't exist in 10.4. You can also do weak linking to the 10.5 frameworks and programatically decide whether you can use a new feature or not (while this is a bit of extra work up front, you can easily phase 10.4 support out of your code in the future and take full advantage of 10.5 improvements for users that actually are running 10.5).
There are a lot of blogs and write-ups about doing the cross-platform stuff out on the web. The other thing to keep in mind is that if you do target 10.4 make sure you have a 10.4 machine available to do a lot of testing (especially if you compile from the 10.5 SDK to take advantage of the 64-bit ready features). Also check the docks for any feature you may want to use from the 10.5 SDK. Many features were actually available in 10.4 but undocumented and the new documentation usually states which features you can safely use when deploying to 10.4
Do you need 64-bit? Unless your application is very CPU-intensive, it won't make any difference.
Tiger can run 64-bit applications, but without GUI. If you need 64-bit, you can create 64-bit CLI executable that does heavy lifting and provide 32-bit font-end for it (using NSTask and NSPipe).
You can also have separate .nib files for Leopard and Tiger:
-(id)init
{
BOOL tiger = floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4;
NSString nibname = (tiger ? #"WindowTiger" : #"WindowLeopard");
if (self = [super initWithWindowNibName:nibname])
…
You really need to find out what your customers are using, and the support person is probably best positioned to know, or the product manager. That said there's nothing wrong with making the technical arguments clear now even if 90%+ of your user base were pre-Leopard; that way the issues will be known (and hopefully understood) so you'll have more support as the environment does change.
I never wrote production code in Objective-C and its hard to keep up, but as far as i am aware NSInteger and friends are in 10.4, it's just that Cocoa isn't 64 bit in 10.4 whereas in 10.5 most of it is (so no more need for seperate 64bit worker process under a 32bit UI).
I don't know what your product is, or who your customers are, but from my experience, Mac users are early adopters (relatively speaking) I've never used an OS X version longer than two weeks before the next upgrade was out, and in my circle I am a late adopter. Ofcourse I'm not just a business Mac user and that may well make a big difference.
What makes 64bits a requirement in your code? There's not much of a reason to not compile a universal binary holding as many architectures as you wish you could have one binary run on G4, G5, IA32 and IA64 no problem, and have it be native on all of them. If you're just doing 64bits because you can there's no reason (that I can imagine) not to keep supporting 32bits, but if you want stuff like CoreAnimation you don't have much choice.
I don't think it's wrong to demand 10.5 for new development, but it wouldn't make much business sense to force a whole new OS on customers just to keep using your existing product. So if you can, stay compatible, maybe backport your new features/patches for a time. There is a good reason for forking in version control and this might be it.
edit-
Since I posted this I learned that I was wrong and NSInteger did not exist before 10.5. I think I assumed too much having used similar types (like NSDecimal) earlier.

Resources