When hardware is failing, it can cause a number of symptoms. The most likely is a Blue Screen of Death, but lesser symptoms can just as easily appear. To get a better idea of how apparently unrelated programs can be affected by hardware, consider the operating system model:
User Software > Kernel > Hardware Abstraction Layer > Hardware
Any program that wants to interact with literally any resource, even the CPU or RAM, has to cooperate with the kernel, which in turn depends on the HAL to translate the various physical signals to and from the hardware into logical signals to and from the kernel.
The kernel has certain restrictions in place to "guarantee" stability, such as the limited ability to be re-entrant, thread safety, resource limitations, and so on. Particularly, most hardware does not have the concept of being shared; this is abstracted at a higher level through the HAL or kernel drivers.
If you remember from the days of modems, only one program at a time could use the modem, such as dialer. The Internet got around this by producing a common stack-- all programs wanting to access the Internet did so through a common stack, and that one stack had exclusive control of the hardware. The stack produced multiplexing to share this one resource.
Even today, sound cards, disk drives, video cards, and so on can't be shared physically. The signals would get confused, and chaos would ensue. The HAL does a pretty good job of tricking users into thinking there's actually more than one thing going on at a time. There's still a physical bottleneck that is place, but we typically don't notice it when hardware is working the way its intended to.
But, to get to the core of the problem, if the HAL has a problem communicating with a device, it can become blocked while it attempts to resend or reread the data over and over again. The HAL is also typically not multithreaded, so it can only handle one request at a time (per driver chain).
If the disk driver is locked up try to read a bad drive, for example, any other program that tries to make a similar API call will be in the queue behind the blocked call, resulting in that program potentially hanging. Multi-threaded programs wouldn't have this problem, because the UI could remain responsive while the drive was locked up. Unfortunately, most programs are not multithreaded.
Many programs in Windows basically go into a loop, like this:
while(GetMessage(&msg, hWnd, NULL, NULL)) {
DispatchMessage(&msg);
}
As you might guess, there's only one thread. Once it tries to read from a drive that's hung, it can't recover until the drive eventually times out. If it doesn't, that program is at the mercy of the OS's API. Even if it were multi-threaded, though, the drive-reading thread would become locked, although the UI thread would be able to detect this and recover/abort.
To compound the issue, many API calls, such as those that allocate memory, open drives or files, etc, are all blocking calls. They cause the current thread to wait indefinitely (unless it requests a specific timeout value) until the OS can complete the request or aborts it due to a timeout. Most programs don't assume that the OS will take very long, and so never specify a timeout. Those programs will never recover if the drive doesn't respond.
For a program that "never accesses the failing drive," it doesn't necessarily have to. All it needs to do is call a function that's currently blocked by the bad drive. For example, if OpenFile was called on the bad DVD drive, then other file requests might become hung until the DVD drive times out, even if they were only reading from the system drive.
Maybe the program calls GetOpenFileName, which shows an OS-rendered dialog that assumes control of the thread until it returns. That window lists all drives on the system by enumerating the list of drives. If the API is hung on a bad drive, the end result is the same: the dialog box is frozen, freezing the entire application, waiting for this drive to become available/free.