Cleanup of existing code, basic implementation of play/stop/resume
states.
Added: trunk/reactos/lib/wdmaud/README.TXT
Modified: trunk/reactos/lib/wdmaud/control.c
Modified: trunk/reactos/lib/wdmaud/devices.c
Modified: trunk/reactos/lib/wdmaud/kernel.c
Modified: trunk/reactos/lib/wdmaud/memtrack.c
Added: trunk/reactos/lib/wdmaud/midi.c
Modified: trunk/reactos/lib/wdmaud/threads.c
Modified: trunk/reactos/lib/wdmaud/user.c
Added: trunk/reactos/lib/wdmaud/wave.c
Deleted: trunk/reactos/lib/wdmaud/wavehdr.c
Modified: trunk/reactos/lib/wdmaud/wdmaud.h
Modified: trunk/reactos/lib/wdmaud/wdmaud.xml
_____
Added: trunk/reactos/lib/wdmaud/README.TXT
--- trunk/reactos/lib/wdmaud/README.TXT 2005-12-07 18:33:12 UTC (rev
19953)
+++ trunk/reactos/lib/wdmaud/README.TXT 2005-12-07 18:37:49 UTC (rev
19954)
@@ -0,0 +1,97 @@
+User-mode Multimedia Driver for WDM Audio
+-----------------------------------------
+
+USAGE
+-----
+This is a "drop-in" replacement for the Windows XP wdmaud.drv
component. To
+make use of it, you'll need to disable system file protection somehow
(easy
+way is to rename all *.cab files in the sub-folders of
C:\WINDOWS\DRIVER CACHE
+to something else, then delete or rename WDMAUD.DRV in both
C:\WINDOWS\SYSTEM32
+and C:\WINDOWS\SYSTEM32\DLLCACHE.)
+
+Now put the ReactOS wdmaud.drv in C:\WINDOWS\SYSTEM32. At some point,
you'll
+be asked to insert the Windows CD as some files are missing - cancel
this and
+choose "yes" when asked if you're sure. This is due to the system file
+protection not being able to have its own way.
+
+That should be all there is to it.
+
+
+IMPLEMENTATION/DEVELOPMENT NOTES
+--------------------------------
+The style of driver used here dates back to the days of Windows 3.1.
Not much
+has changed - the NT 4 Sound Blaster driver exported the same functions
and
+supported the same message codes as the traditional Windows 3.1
user-mode
+drivers did.
+
+But in XP, something strange happens with WDMAUD (which is why you
can't just
+put this next to the existing WDMAUD under a different name!)
+
+It appears that WINMM.DLL treats WDMAUD.DRV differently to other
drivers.
+
+Here's a summary of how things work differently:
+
+1) It seems DRV_ENABLE and DRV_DISABLE are the only important
messages
+ processed by DriverProc. These open and close the kernel-mode
+ driver.
+
+2) Each message handling function (aside from DriverProc) receives
a
+ DRVM_INIT message after the driver has been opened. The second
+ parameter of this is a pointer to a string containing a device
+ path (\\?\... format.) Returning zero seems to be the accepted
+ thing to do, in any case.
+
+ The purpose of this function (in our case) is to allow
WDMAUD.DRV
+ to let WDMAUD.SYS know which device we want to play with.
+
+ Presumably, this is called when new devices are added to the
system,
+ as well. I don't know if this is called once per hardware
device...
+
+3) xxxx_GETNUMDEVS now has extra data passed to it! The first
+ parameter is a device path string - which will have been passed
+ to DRVM_INIT previously.
+
+4) xxxx_GETDEVCAPS is a bit hazardous. The old set of parameters
were:
+ 1 - Pointer to a capabilities structure (eg: WAVEOUTCAPS)
+ 2 - Size of the above structure
+
+ But now, the parameters are:
+ 1 - Pointer to a MDEVCAPSEX struct (which points to a regular
+ capabilities structure)
+ 2 - Device path string
+
+ So anything expecting the second parameter to be a size (for
copying
+ memory maybe) is in for a bit of a surprise there!
+
+The reason for the above changes is Plug and Play. It seems that the
extra
+functionality was added in Windows 98 (possibly 95 as well) to make it
+possible to hot-swap winmm-supported devices without requiring a
restart of
+whatever applications are using the devices.
+
+That's the theory, at least.
+
+
+TODO
+----
+Our WINMM.DLL will need hacking to make sure it can take into account
the
+preferential treatment given to WDMAUD.DRV
+
+I'm not sure if it'll work with it yet as there seems to be some
accomodation
+for the PnP DRVM_INIT and DRVM_EXIT messages, but whether or not winmm
will
+function correctly with this WDMAUD.DRV replacement is something that
remains
+to be seen.
+
+
+THANKS
+------
+Thanks to everyone who has encouraged me to continue developing the
audio
+system for ReactOS.
+
+In particular, I'd like to thank Alex Ionescu for the many hours of
assistance
+he has given me in figuring out how things are done.
+
+
+-
+
+Andrew Greenwood
+andrew.greenwood AT silverblade DOT co DOT uk
Property changes on: trunk/reactos/lib/wdmaud/README.TXT
___________________________________________________________________
Name: svn:executable
+ *
Name: eol-style
+ native
Property changes on: trunk/reactos/lib/wdmaud/TODO
___________________________________________________________________
Name: eol-style
+ native
Property changes on: trunk/reactos/lib/wdmaud/callbacks.c
___________________________________________________________________
Name: eol-style
+ native
_____
Modified: trunk/reactos/lib/wdmaud/control.c
--- trunk/reactos/lib/wdmaud/control.c 2005-12-07 18:33:12 UTC (rev
19953)
+++ trunk/reactos/lib/wdmaud/control.c 2005-12-07 18:37:49 UTC (rev
19954)
@@ -13,8 +13,13 @@
#include "wdmaud.h"
/*
- TODO:
- Make these work for the other device types!
+ StartDevice
+
+ Creates a completion thread for a device, sets the "is_running"
member
+ of the device state to "true", and tells the kernel device to start
+ processing audio/MIDI data.
+
+ Wave devices always start paused.
*/
MMRESULT StartDevice(PWDMAUD_DEVICE_INFO device)
@@ -25,21 +30,165 @@
result = ValidateDeviceInfoAndState(device);
if ( result != MMSYSERR_NOERROR )
+ {
+ DPRINT1("Device info/state not valid\n");
return result;
+ }
- ioctl_code = device == WDMAUD_WAVE_IN ? IOCTL_WDMAUD_WAVE_IN_START
:
- device == WDMAUD_WAVE_OUT ?
IOCTL_WDMAUD_WAVE_OUT_START :
- 0x0000;
+ ioctl_code =
+ IsWaveInDeviceType(device->type) ? IOCTL_WDMAUD_WAVE_IN_START
:
+ IsWaveOutDeviceType(device->type) ? IOCTL_WDMAUD_WAVE_OUT_START
:
+ IsMidiInDeviceType(device->type) ? IOCTL_WDMAUD_MIDI_IN_START
:
+ 0x0000;
ASSERT( ioctl_code );
+
+ result = CreateCompletionThread(device);
+
+ if ( MM_FAILURE( result ) )
+ {
+ DPRINT1("Failed to create completion thread\n");
+ return result;
+ }
+
+ device->state->is_running = TRUE;
+
+ result = CallKernelDevice(device, ioctl_code, 0, 0);
+
+ if ( MM_FAILURE( result ) )
+ {
+ DPRINT1("Audio could not be started\n");
+ return result;
+ }
+
+ if ( ! IsWaveDeviceType(device->type) )
+ device->state->is_paused = FALSE;
+
+ return result;
}
MMRESULT StopDevice(PWDMAUD_DEVICE_INFO device)
{
+ MMRESULT result;
+ DWORD ioctl_code;
+
+ result = ValidateDeviceInfoAndState(device);
+
+ if ( result != MMSYSERR_NOERROR )
+ {
+ DPRINT1("Device info/state not valid\n");
+ return result;
+ }
+
+ ioctl_code =
+ IsWaveInDeviceType(device->type) ? IOCTL_WDMAUD_WAVE_IN_STOP :
+ IsWaveOutDeviceType(device->type) ? IOCTL_WDMAUD_WAVE_OUT_STOP
:
+ IsMidiInDeviceType(device->type) ? IOCTL_WDMAUD_MIDI_IN_STOP :
+ 0x0000;
+
+ ASSERT( ioctl_code );
+
+ if ( IsMidiInDeviceType(device->type) )
+ {
+ EnterCriticalSection(device->state->device_queue_guard);
+
+ if ( ! device->state->is_running )
+ {
+ /* TODO: Free the MIDI data queue */
+ }
+ else
+ {
+ device->state->is_running = FALSE;
+ }
+
+ LeaveCriticalSection(device->state->device_queue_guard);
+ }
+ else /* wave device */
+ {
+ device->state->is_paused = TRUE;
+ }
+
+ result = CallKernelDevice(device, ioctl_code, 0, 0);
+
+ if ( MM_FAILURE( result ) )
+ {
+ DPRINT1("Audio could not be stopped\n");
+ return result;
+ }
+
+ if ( IsWaveDeviceType(device-type) )
+ {
+ device->state->is_paused = TRUE;
+ }
+ else /* MIDI Device */
+ {
+ /* TODO: Destroy completion thread etc. */
+ }
+
+ return result;
}
-MMRESULT PauseDevice(PWDMAUD_DEVICE_INFO device)
+MMRESULT ResetDevice(PWDMAUD_DEVICE_INFO device)
{
+ MMRESULT result;
+ DWORD ioctl_code;
+
+ result = ValidateDeviceInfoAndState(device);
+
+ if ( result != MMSYSERR_NOERROR )
+ {
+ DPRINT1("Device info/state not valid\n");
+ return result;
+ }
+
+ ioctl_code =
+ IsWaveInDeviceType(device->type) ? IOCTL_WDMAUD_WAVE_IN_RESET
:
+ IsWaveOutDeviceType(device->type) ? IOCTL_WDMAUD_WAVE_OUT_RESET
:
+ IsMidiInDeviceType(device->type) ? IOCTL_WDMAUD_MIDI_IN_RESET
:
+ 0x0000;
+
+ ASSERT( ioctl_code );
+
+ if ( IsMidiInDeviceType(device->type) )
+ {
+ EnterCriticalSection(device->state->device_queue_guard);
+
+ if ( ! device->state->is_running )
+ {
+ /* TODO: Free the MIDI data queue */
+ }
+ else
+ {
+ device->state->is_running = FALSE;
+ }
+
+ LeaveCriticalSection(device->state->device_queue_guard);
+ }
+
+ result = CallKernelDevice(device, ioctl_code, 0, 0);
+
+ if ( MM_FAILURE( result ) )
+ {
+ DPRINT1("Audio could not be reset\n");
+ return result;
+ }
+
+ if ( IsWaveDeviceType(device->type) )
+ {
+ if ( IsWaveInDeviceType(device->type) )
+ device->state->is_paused = TRUE;
+ else if ( IsWaveOutDeviceType(device->type) )
+ device->state->is_paused = FALSE;
+
+ /* TODO: Destroy completion thread + check ret val */
+ }
+ else /* MIDI input device */
+ {
+ /* TODO: Destroy completion thread + check ret val */
+ /* TODO - more stuff */
+ }
+
+ return result;
}
MMRESULT StopDeviceLooping(PWDMAUD_DEVICE_INFO device)
Property changes on: trunk/reactos/lib/wdmaud/control.c
___________________________________________________________________
Name: eol-style
+ native
_____
Modified: trunk/reactos/lib/wdmaud/devices.c
--- trunk/reactos/lib/wdmaud/devices.c 2005-12-07 18:33:12 UTC (rev
19953)
+++ trunk/reactos/lib/wdmaud/devices.c 2005-12-07 18:37:49 UTC (rev
19954)
@@ -17,9 +17,15 @@
const char WDMAUD_DEVICE_INFO_SIG[4] = "WADI";
const char WDMAUD_DEVICE_STATE_SIG[4] = "WADS";
-const char WDMAUD_NULL_SIGNATURE[4] = {0,0,0,0};
+/*
+ IsValidDevicePath
+
+ Just checks to see if the string containing the path to the device
path
+ (object) is a valid, readable string.
+*/
+
BOOL IsValidDevicePath(WCHAR* path)
{
if (IsBadReadPtr(path, 1)) /* TODO: Replace with flags */
@@ -33,43 +39,93 @@
return TRUE;
}
-MMRESULT ValidateDeviceInfo(PWDMAUD_DEVICE_INFO device_info)
+/*
+ ValidateDeviceData
+
+ Checks that the memory pointed at by the device data pointer is
writable,
+ and that it has a valid signature.
+
+ If the "state" member isn't NULL, the state structure is also
validated
+ in the same way. If the "require_state" parameter is TRUE and the
"state"
+ member is NULL, an error code is returned. Otherwise the "state"
member
+ isn't validated and no error occurs.
+*/
+
+MMRESULT ValidateDeviceData(
+ PWDMAUD_DEVICE_INFO device,
+ BOOL require_state
+)
{
- if ( IsBadWritePtr(device_info, sizeof(WDMAUD_DEVICE_INFO)) )
+ if ( IsBadWritePtr(device, sizeof(WDMAUD_DEVICE_INFO)) )
+ {
+ DPRINT1("Device data structure not writable\n");
return MMSYSERR_INVALPARAM;
+ }
- if ( *device_info->signature != *WDMAUD_DEVICE_INFO_SIG )
+ if ( strncmp(device->signature, WDMAUD_DEVICE_INFO_SIG, 4) != 0 )
+ {
+ DPRINT1("Device signature is invalid\n");
return MMSYSERR_INVALPARAM;
+ }
- return MMSYSERR_NOERROR;
-}
+ if ( ! IsValidDeviceType(device->type) )
+ {
+ DPRINT1("Invalid device type\n");
+ return MMSYSERR_INVALPARAM;
+ }
-MMRESULT ValidateDeviceState(PWDMAUD_DEVICE_STATE state)
-{
- if ( IsBadWritePtr(state, sizeof(WDMAUD_DEVICE_INFO)) )
+ if ( device->id > 100 )
+ {
+ DPRINT1("Device ID is out of range\n");
return MMSYSERR_INVALPARAM;
+ }
- if ( *state->signature != *WDMAUD_DEVICE_STATE_SIG )
+ /* Now we validate the device state (if present) */
+
+ if ( device->state )
+ {
+ if ( IsBadWritePtr(device->state, sizeof(WDMAUD_DEVICE_INFO)) )
+ {
+ DPRINT1("Device state structure not writable\n");
+ return MMSYSERR_INVALPARAM;
+ }
+
+ if ( strncmp(device->state->signature,
+ WDMAUD_DEVICE_STATE_SIG,
+ 4) != 0 )
+ {
+ DPRINT1("Device state signature is invalid\n");
+ return MMSYSERR_INVALPARAM;
+ }
+
+ /* TODO: Validate state events */
+ }
+ else if ( require_state )
+ {
return MMSYSERR_INVALPARAM;
+ }
return MMSYSERR_NOERROR;
}
+
/*
ValidateDeviceStateEvents should be used in conjunction with the
standard
- state validation routine.
-*/
+ state validation routine (NOT on its own!)
+ FIXME: The tests are wrong
+*/
+/*
MMRESULT ValidateDeviceStateEvents(PWDMAUD_DEVICE_STATE state)
{
- if ( ( (DWORD) state->exit_thread_event == 0x00000000 ) &&
+ if ( ( (DWORD) state->exit_thread_event != 0x00000000 ) &&
( (DWORD) state->exit_thread_event != 0x48484848 ) )
{
DPRINT1("Bad exit thread event\n");
return MMSYSERR_INVALPARAM;
}
- if ( ( (DWORD) state->queue_event == 0x00000000 ) &&
+ if ( ( (DWORD) state->queue_event != 0x00000000 ) &&
( (DWORD) state->queue_event != 0x42424242 ) &&
( (DWORD) state->queue_event != 0x43434343 ) )
{
@@ -79,28 +135,32 @@
return MMSYSERR_NOERROR;
}
+*/
-MMRESULT ValidateDeviceInfoAndState(PWDMAUD_DEVICE_INFO device_info)
-{
- MMRESULT result;
+/*
+ CreateDeviceData
- result = ValidateDeviceInfo(device_info);
+ This is a glorified memory allocation routine, which acts as a
primitive
+ constructor for a device data structure.
- if ( result != MMSYSERR_NOERROR )
- return result;
+ It validates the device path given, allocates memory for both the
device
+ data and the device state data, copies the signatures over and sets
the
+ device type accordingly.
- result = ValidateDeviceState(device_info->state);
+ In some cases, a state structure isn't required, so the creation of
one can
+ be avoided by passing FALSE for the "with_state" parameter.
+*/
- if ( result != MMSYSERR_NOERROR )
- return result;
-
- return MMSYSERR_NOERROR;
-}
-
-PWDMAUD_DEVICE_INFO CreateDeviceData(CHAR device_type, WCHAR*
device_path)
+PWDMAUD_DEVICE_INFO
+CreateDeviceData(
+ CHAR device_type,
+ DWORD device_id,
+ WCHAR* device_path,
+ BOOL with_state
+)
{
- HANDLE heap = 0;
- PWDMAUD_DEVICE_INFO device_data = 0;
+ BOOL success = FALSE;
+ PWDMAUD_DEVICE_INFO device = 0;
int path_size = 0;
DPRINT("Creating device data for device type %d\n", (int)
device_type);
@@ -115,121 +175,119 @@
path_size = (lstrlen(device_path) + 1) * sizeof(WCHAR);
/* DPRINT("Size of path is %d\n", (int) path_size); */
- heap = GetProcessHeap();
-
- if ( ! heap )
- {
- DPRINT1("Couldn't get the process heap (error %d)\n",
- (int) GetLastError());
- goto cleanup;
- }
-
- DPRINT("Allocating %d bytes\n",
+ DPRINT("Allocating %d bytes for device data\n",
path_size + sizeof(WDMAUD_DEVICE_INFO));
-/*
- device_data = (PWDMAUD_DEVICE_INFO) HeapAlloc(heap,
- HEAP_ZERO_MEMORY,
- path_size +
sizeof(WDMAUD_DEVICE_INFO));
-*/
- device_data = (PWDMAUD_DEVICE_INFO)
+ device = (PWDMAUD_DEVICE_INFO)
AllocMem(path_size + sizeof(WDMAUD_DEVICE_INFO));
- if ( ! device_data )
+ if ( ! device )
{
DPRINT1("Unable to allocate memory for device data (error
%d)\n",
(int) GetLastError());
goto cleanup;
}
- DPRINT("Copying signature\n");
- memcpy(device_data->signature, WDMAUD_DEVICE_INFO_SIG, 4);
+ /* Copy the signature and device path */
+ memcpy(device->signature, WDMAUD_DEVICE_INFO_SIG, 4);
+ lstrcpy(device->path, device_path);
- DPRINT("Copying path (0x%x)\n", (int)device_path);
- lstrcpy(device_data->path, device_path);
+ /* Initialize these common members */
+ device->id = device_id;
+ device->type = device_type;
- device_data->type = device_type;
+ if ( with_state )
+ {
+ /* Allocate device state structure */
+ device->state = AllocMem(sizeof(WDMAUD_DEVICE_STATE));
+ if ( ! device->state )
+ {
+ DPRINT1("Couldn't allocate memory for device state (error
%d)\n",
+ (int) GetLastError());
+ goto cleanup;
+ }
+
+ /* Copy the signature */
+ memcpy(device->state->signature, WDMAUD_DEVICE_STATE_SIG, 4);
+ }
+
+ success = TRUE;
+
cleanup :
{
- /* No cleanup needed (no failures possible after allocation.)
*/
- DPRINT("Performing cleanup\n");
+ if ( ! success )
+ {
+ if ( device )
+ {
+ if ( device->state )
+ {
+ ZeroMemory(device->state->signature, 4);
+ FreeMem(device->state);
+ }
- return device_data;
+ ZeroMemory(device->signature, 4);
+ FreeMem(device);
+ }
+ }
+
+ return (success ? device : NULL);
}
}
+
/*
- CloneDeviceData
+ DeleteDeviceData
- This isn't all that great... Maybe some macros would be better:
- BEGIN_CLONING_STRUCT(source, target)
- CLONE_MEMBER(member)
- END_CLONING_STRUCT()
+ Blanks out the device and device state structures, and frees the
memory
+ associated with the structures.
- The main problem is that sometimes we'll want to copy more than
- the data presented here. I guess we could blindly copy EVERYTHING
- but that'd be excessive.
+ TODO: Free critical sections / events if set?
*/
-PWDMAUD_DEVICE_INFO CloneDeviceData(PWDMAUD_DEVICE_INFO original)
+void DeleteDeviceData(PWDMAUD_DEVICE_INFO device_data)
{
- PWDMAUD_DEVICE_INFO clone = NULL;
+ DPRINT("Deleting device data\n");
- if ( ValidateDeviceInfo(original) != MMSYSERR_NOERROR)
- {
- DPRINT1("Original device data was invalid\n");
- return NULL;
- }
+ ASSERT( device_data );
- /* This will set the type and path, so we can forget about those */
- clone = CreateDeviceData(original->type, original->path);
+ /* We don't really care if the structure is valid or not */
+ if ( ! device_data )
+ return;
- if ( ! clone )
+ if ( device_data->state )
{
- DPRINT1("Clone creation failed\n");
- return NULL;
- }
+ /* We DON'T want these to be set - should we clean up? */
+ ASSERT ( ! device_data->state->device_queue_guard );
+ ASSERT ( ! device_data->state->queue_event );
+ ASSERT ( ! device_data->state->exit_thread_event );
- clone->id = original->id;
- clone->wave_handle = original->wave_handle; /* ok? */
+ /* Insert a cow (not sure if this is right or not) */
+ device_data->state->sample_size = 0xDEADBEEF;
- /* TODO: Maybe we should copy some more? */
+ /* Overwrite the structure with zeroes and free it */
+ ZeroMemory(device_data->state, sizeof(WDMAUD_DEVICE_STATE));
+ FreeMem(device_data->state);
+ }
- return clone;
+ /* Overwrite the structure with zeroes and free it */
+ ZeroMemory(device_data, sizeof(WDMAUD_DEVICE_INFO));
+ FreeMem(device_data);
}
-void DeleteDeviceData(PWDMAUD_DEVICE_INFO device_data)
-{
- HANDLE heap;
+/*
+ ModifyDevicePresence
- ASSERT( device_data );
+ Use this to add or remove devices in the kernel-mode driver. If the
+ "adding" parameter is TRUE, the device is added, otherwise it is
removed.
- /* Erase the signature to prevent any possible future mishaps */
- *device_data->signature = *WDMAUD_NULL_SIGNATURE;
+ "device_type" is WDMAUD_WAVE_IN, WDMAUD_WAVE_OUT, etc...
- heap = GetProcessHeap();
+ "device_path" specifies the NT object path of the device.
- if ( ! heap )
- {
- DPRINT1("Couldn't get the process heap (error %d)\n",
- (int) GetLastError());
- goto exit;
- }
+ (I'm not sure what happens to devices that are added but never
removed.)
+*/
- FreeMem(device_data);
- /*
- {
- DPRINT1("Couldn't free device data memory (error %d)\n",
- (int) GetLastError());
- }
- */
-
- exit :
- /* We just return */
- return;
-}
-
MMRESULT ModifyDevicePresence(
CHAR device_type,
WCHAR* device_path,
@@ -249,7 +307,7 @@
ASSERT( IsValidDeviceType(device_type) );
ASSERT( device_path );
- device_data = CreateDeviceData(device_type, device_path);
+ device_data = CreateDeviceData(device_type, 0, device_path, FALSE);
if ( ! device_data )
{
@@ -292,6 +350,16 @@
}
}
+/*
+ GetDeviceCount
+
+ Pretty straightforward - pass the device type (WDMAUD_WAVE_IN, ...)
and
+ a topology device (NT object path) to obtain the number of devices
+ present in that topology of that particular type.
+
+ The topology path is supplied to us by winmm.
+*/
+
DWORD GetDeviceCount(CHAR device_type, WCHAR* topology_path)
{
PWDMAUD_DEVICE_INFO device_data;
@@ -299,7 +367,7 @@
DPRINT("Topology path %S\n", topology_path);
- device_data = CreateDeviceData(device_type, topology_path);
+ device_data = CreateDeviceData(device_type, 0, topology_path,
FALSE);
if (! device_data)
{
@@ -339,7 +407,8 @@
This uses a different structure to the traditional documentation,
because
we handle plug and play devices.
- Much sleep was lost over implementing this.
+ Much sleep was lost over implementing this. I got the ID and type
+ parameters the wrong way round!
*/
MMRESULT GetDeviceCapabilities(
@@ -363,7 +432,7 @@
DPRINT("Going to have to query the kernel-mode part\n");
- device = CreateDeviceData(device_type, device_path);
+ device = CreateDeviceData(device_type, device_id, device_path,
FALSE);
if ( ! device )
{
@@ -372,8 +441,9 @@
goto cleanup;
}
- device->id = device_id;
- device->with_critical_section = FALSE;
+ /* These are not needed as they're already initialized */
+ ASSERT( device_id == device->id );
+ ASSERT( ! device->with_critical_section );
*(LPWORD)caps->pCaps = (WORD) 0x43;
@@ -400,305 +470,224 @@
}
}
-MMRESULT TryOpenDevice(
+
+/*
+ OpenDeviceViaKernel
+
+ Internal function to rub the kernel mode part of wdmaud the right
way
+ so it opens a device on our behalf.
+*/
+
+MMRESULT
+OpenDeviceViaKernel(
PWDMAUD_DEVICE_INFO device,
LPWAVEFORMATEX format
)
{
- if ( device->id > 0x64 ) /* FIXME */
- {
- DPRINT1("device->id > 0x64 ! ???\n");
- return MMSYSERR_BADDEVICEID; /* OK? */
- }
+ DWORD format_struct_len = 0;
- /* We'll only have a format set for wave devices */
- if ( format )
+ DPRINT("Opening device via kernel\n");
+
+ if ( format->wFormatTag == 1 ) /* FIXME */
{
- if ( format->wFormatTag == 1 )
- {
- DWORD sample_size;
+ /* Standard PCM format */
+ DWORD sample_size;
- DPRINT("Standard (PCM) format\n");
- sample_size = format->nChannels * format->wBitsPerSample;
- device->state->sample_size = sample_size;
+ DPRINT("Standard (PCM) format\n");
- if ( CallKernelDevice(device,
- IOCTL_WDMAUD_OPEN_DEVICE,
- 0x10,
- (DWORD)format)
- != MMSYSERR_NOERROR )
- {
- DPRINT("Call failed\n");
- /* FIXME */
- return MMSYSERR_NOTSUPPORTED; /* WAVERR_BADFORMAT? */
- }
- }
- else
- {
- /* FIXME */
- DPRINT("Non-PCM format\n");
- return MMSYSERR_NOTSUPPORTED;
- }
+ sample_size = format->nChannels * format->wBitsPerSample;
+
+ device->state->sample_size = sample_size;
+
+ format_struct_len = 16; /* FIXME */
}
+ else
+ {
+ /* Non-standard format */
+ return MMSYSERR_NOTSUPPORTED; /* TODO */
+ }
- /* If we got this far without error, the format is supported! */
- return MMSYSERR_NOERROR;
+ return CallKernelDevice(device,
+ IOCTL_WDMAUD_OPEN_DEVICE,
+ format_struct_len,
+ (DWORD)format);
}
-MMRESULT OpenWaveDevice(
+
+/* MOVEME */
+LPCRITICAL_SECTION CreateCriticalSection()
+{
+ LPCRITICAL_SECTION cs;
+
+ cs = AllocMem(sizeof(CRITICAL_SECTION));
+
+ if ( ! cs )
+ return NULL;
+
+ InitializeCriticalSection(cs);
+
+ return cs;
+}
+
+
+/*
+ OpenDevice
+
+ A generic "open device" function, which makes use of the above
function
+ once parameters have been checked. This is capable of handling both
+ MIDI and wave devices, which is an improvement over the previous
+ implementation (which had a lot of duplicate functionality.)
+*/
+
+MMRESULT
+OpenDevice(
CHAR device_type,
DWORD device_id,
- LPWAVEOPENDESC open_details,
+ LPVOID open_descriptor,
DWORD flags,
- DWORD user_data
+ PWDMAUD_DEVICE_INFO* user_data
)
{
- HANDLE heap = 0;
- PWDMAUD_DEVICE_INFO device = NULL;
- WCHAR* device_path = NULL;
MMRESULT result = MMSYSERR_ERROR;
+ WCHAR* device_path;
+ PWDMAUD_DEVICE_INFO device;
+ LPWAVEFORMATEX format;
- /* ASSERT(open_details); */
+ /* As we support both types */
+ LPWAVEOPENDESC wave_opendesc = (LPWAVEOPENDESC) open_descriptor;
+ LPMIDIOPENDESC midi_opendesc = (LPMIDIOPENDESC) open_descriptor;
- heap = GetProcessHeap();
+ /* FIXME: Does this just apply to wave, or MIDI also? */
+ if ( device_id > 100 )
+ return MMSYSERR_BADDEVICEID;
- if ( ! heap )
- {
- DPRINT1("Couldn't get the process heap (error %d)\n",
- (int) GetLastError());
- result = MMSYSERR_ERROR;
- goto cleanup;
- }
+ /* Copy the appropriate dnDevNode value */
+ if ( IsWaveDeviceType(device_type) )
+ device_path = (WCHAR*) wave_opendesc->dnDevNode;
+ else if ( IsMidiDeviceType(device_type) )
+ device_path = (WCHAR*) midi_opendesc->dnDevNode;
+ else
+ return MMSYSERR_INVALPARAM;
- DPRINT("OpenDevice called\n");
+ device = CreateDeviceData(device_type, device_id, device_path,
TRUE);
- device_path = (WCHAR*) open_details->dnDevNode;
- device = CreateDeviceData(device_type, device_path);
-
if ( ! device )
{
- DPRINT1("Couldn't create device data\n");
+ DPRINT1("Couldn't allocate memory for device data\n");
result = MMSYSERR_NOMEM;
goto cleanup;
}
- DPRINT("Allocated device data, allocating device state\n");
-
- device->state = HeapAlloc(heap,
- HEAP_ZERO_MEMORY,
- sizeof(WDMAUD_DEVICE_STATE));
-
- if ( ! device->state )
- {
- DPRINT1("Couldn't allocate memory for device state (error
%d)\n",
- (int) GetLastError());
- result = MMSYSERR_NOMEM;
- goto cleanup;
- }
-
- /* FIXME: ok here ? */
- device->type = device_type;
- device->id = device_id;
device->flags = flags;
- if ( flags & WAVE_FORMAT_QUERY )
+ if ( ( IsWaveDeviceType(device->type) ) &&
+ ( device->flags & WAVE_FORMAT_QUERY ) )
{
- DPRINT("Do I support this format? Hmm...\n");
+ result = OpenDeviceViaKernel(device, wave_opendesc->lpFormat);
- result = TryOpenDevice(device, open_details->lpFormat);
-
if ( result != MMSYSERR_NOERROR )
{
- DPRINT("Format not supported\n");
- goto cleanup;
+ DPRINT1("Format not supported (mmsys error %d)\n", (int)
result);
+ result = WAVERR_BADFORMAT;
}
-
- DPRINT("Yes, I do support this format!\n");
- }
- else
- {
-
- DPRINT("You actually want me to open the device, huh?\n");
-
- /* Allocate memory for the "queue" critical section */
-
- device->state->queue_critical_section =
- HeapAlloc(heap, HEAP_ZERO_MEMORY,
sizeof(CRITICAL_SECTION));
-
- if ( ! device->state->queue_critical_section )
+ else
{
- DPRINT1("Couldn't allocate memory for queue critical
section (error %d)\n",
- (int) GetLastError());
- result = MMSYSERR_NOMEM;
- goto cleanup;
+ DPRINT("Format supported\n");
+ result = MMSYSERR_NOERROR;
}
- /* Initialize the critical section */
-
InitializeCriticalSection(device->state->queue_critical_section);
+ goto cleanup;
+ }
- /* We need these so we can contact the client later */
- device->client_instance = open_details->dwInstance;
- device->client_callback = open_details->dwCallback;
+ device->state->device_queue_guard = CreateCriticalSection();
- /* Reset state */
- device->state->open_descriptor = NULL;
- device->state->unknown_24 = 0;
+ if ( ! device->state->device_queue_guard )
+ {
+ DPRINT1("Couldn't create queue cs\n");
+ result = MMSYSERR_NOMEM;
+ goto cleanup;
+ }
- device->state->is_running = FALSE;
- device->state->is_paused =
- device->type == WDMAUD_WAVE_IN ? TRUE : FALSE;
+ /* Set up the callbacks */
+ device->client_instance = IsWaveDeviceType(device->type)
+ ? wave_opendesc->dwInstance
+ : midi_opendesc->dwInstance;
[truncated at 1000 lines; 2515 more skipped]
print more detailed information for the status codes (only the simple
ones)
Modified: trunk/reactos/lib/devmgr/En.rc
Modified: trunk/reactos/lib/devmgr/advprop.c
Modified: trunk/reactos/lib/devmgr/devprblm.c
Modified: trunk/reactos/lib/devmgr/misc.c
Modified: trunk/reactos/lib/devmgr/resource.h
_____
Modified: trunk/reactos/lib/devmgr/En.rc
--- trunk/reactos/lib/devmgr/En.rc 2005-12-07 13:09:01 UTC (rev
19946)
+++ trunk/reactos/lib/devmgr/En.rc 2005-12-07 15:30:00 UTC (rev
19947)
@@ -12,6 +12,7 @@
IDS_UNKNOWN "Unknown"
IDS_LOCATIONSTR "Location %1!u! (%2)"
IDS_DEVCODE " (Code %1!u!)"
+ IDS_DEVCODE2 " (Code %2!u!)"
IDS_ENABLEDEVICE "Use this device (enable)"
IDS_DISABLEDEVICE "Do not use this device (disable)"
IDS_UNKNOWNDEVICE "Unknown device"
@@ -20,59 +21,74 @@
IDS_TROUBLESHOOTDEV "&Troubleshoot..."
IDS_ENABLEDEV "E&nable Device"
IDS_REINSTALLDRV "Re&install Driver"
+ IDS_PROPERTIES "P&roperties"
+ IDS_UPDATEDRV "U&pdate Driver..."
+ IDS_REBOOT "Restart &Computer..."
END
+/* error messages, source: http://www.z123.org/techsupport/medm.htm */
STRINGTABLE
BEGIN
IDS_DEV_NO_PROBLEM "This device is working properly."
- IDS_DEV_NOT_CONFIGURED "CM_PROB_NOT_CONFIGURED"
- IDS_DEV_OUT_OF_MEMORY "CM_PROB_DEVLOADER_FAILED"
- IDS_DEV_ENTRY_IS_WRONG_TYPE "CM_PROB_ENTRY_IS_WRONG_TYPE"
- IDS_DEV_LACKED_ARBITRATOR "CM_PROB_LACKED_ARBITRATOR"
- IDS_DEV_BOOT_CONFIG_CONFLICT "CM_PROB_BOOT_CONFIG_CONFLICT"
- IDS_DEV_FAILED_FILTER "CM_PROB_FAILED_FILTER"
- IDS_DEV_DEVLOADER_NOT_FOUND "CM_PROB_DEVLOADER_NOT_FOUND"
- IDS_DEV_INVALID_DATA "CM_PROB_INVALID_DATA"
- IDS_DEV_FAILED_START "CM_PROB_FAILED_START"
- IDS_DEV_LIAR "CM_PROB_LIAR"
- IDS_DEV_NORMAL_CONFLICT "CM_PROB_NORMAL_CONFLICT"
- IDS_DEV_NOT_VERIFIED "CM_PROB_NOT_VERIFIED"
- IDS_DEV_NEED_RESTART "CM_PROB_NEED_RESTART"
- IDS_DEV_REENUMERATION "CM_PROB_REENUMERATION"
- IDS_DEV_PARTIAL_LOG_CONF "CM_PROB_PARTIAL_LOG_CONF"
- IDS_DEV_UNKNOWN_RESOURCE "CM_PROB_UNKNOWN_RESOURCE"
- IDS_DEV_REINSTALL "CM_PROB_REINSTALL"
- IDS_DEV_REGISTRY "CM_PROB_REGISTRY"
- IDS_DEV_WILL_BE_REMOVED "CM_PROB_WILL_BE_REMOVED"
- IDS_DEV_DISABLED "CM_PROB_DISABLED"
- IDS_DEV_DEVLOADER_NOT_READY "CM_PROB_DEVLOADER_NOT_READY"
- IDS_DEV_DEVICE_NOT_THERE "CM_PROB_DEVICE_NOT_THERE"
- IDS_DEV_MOVED "CM_PROB_MOVED"
- IDS_DEV_TOO_EARLY "CM_PROB_TOO_EARLY"
- IDS_DEV_NO_VALID_LOG_CONF "CM_PROB_NO_VALID_LOG_CONF"
- IDS_DEV_FAILED_INSTALL "CM_PROB_FAILED_INSTALL"
- IDS_DEV_HARDWARE_DISABLED "CM_PROB_HARDWARE_DISABLED"
- IDS_DEV_CANT_SHARE_IRQ "CM_PROB_CANT_SHARE_IRQ"
- IDS_DEV_FAILED_ADD "CM_PROB_FAILED_ADD"
- IDS_DEV_DISABLED_SERVICE "CM_PROB_DISABLED_SERVICE"
- IDS_DEV_TRANSLATION_FAILED "CM_PROB_TRANSLATION_FAILED"
- IDS_DEV_NO_SOFTCONFIG "CM_PROB_NO_SOFTCONFIG"
- IDS_DEV_BIOS_TABLE "CM_PROB_BIOS_TABLE"
- IDS_DEV_IRQ_TRANSLATION_FAILED "CM_PROB_IRQ_TRANSLATION_FAILED"
- IDS_DEV_FAILED_DRIVER_ENTRY "CM_PROB_FAILED_DRIVER_ENTRY"
- IDS_DEV_DRIVER_FAILED_PRIOR_UNLOAD
"CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD"
- IDS_DEV_DRIVER_FAILED_LOAD "CM_PROB_DRIVER_FAILED_LOAD"
- IDS_DEV_DRIVER_SERVICE_KEY_INVALID
"CM_PROB_DRIVER_SERVICE_KEY_INVALID"
- IDS_DEV_LEGACY_SERVICE_NO_DEVICES
"CM_PROB_LEGACY_SERVICE_NO_DEVICES"
- IDS_DEV_DUPLICATE_DEVICE "CM_PROB_DUPLICATE_DEVICE"
- IDS_DEV_FAILED_POST_START "CM_PROB_FAILED_POST_START"
- IDS_DEV_HALTED "CM_PROB_HALTED"
- IDS_DEV_PHANTOM "CM_PROB_PHANTOM"
- IDS_DEV_SYSTEM_SHUTDOWN "CM_PROB_SYSTEM_SHUTDOWN"
- IDS_DEV_HELD_FOR_EJECT "CM_PROB_HELD_FOR_EJECT"
- IDS_DEV_DRIVER_BLOCKED "CM_PROB_DRIVER_BLOCKED"
- IDS_DEV_REGISTRY_TOO_LARGE "CM_PROB_REGISTRY_TOO_LARGE"
- IDS_DEV_SETPROPERTIES_FAILED "CM_PROB_SETPROPERTIES_FAILED"
+ IDS_DEV_NOT_CONFIGURED "This device is not configured correctly."
+ IDS_DEV_DEVLOADER_FAILED "ReactOS could not load the driver for
this device because the computer is reporting two $1 bus types."
+ IDS_DEV_DEVLOADER_FAILED2 "The $1 device loader(s) for this device
could not load the device driver."
+ IDS_DEV_OUT_OF_MEMORY "The driver for this device may be bad, or
your system may be running low on memory or other resources."
+ IDS_DEV_ENTRY_IS_WRONG_TYPE "This device is not working properly
because one of its drivers may be bad, or your registry may be bad."
+ IDS_DEV_LACKED_ARBITRATOR "The driver for this device requested a
resource that ReactOS does not know how to handle."
+ IDS_DEV_BOOT_CONFIG_CONFLICT "Another device is using the resources
this device needs."
+ IDS_DEV_FAILED_FILTER "The drivers for this device need to be
reinstalled."
+ IDS_DEV_DEVLOADER_NOT_FOUND "This device is not working properly
because ReactOS cannot load the file $1 that loads the drivers for the
device."
+ IDS_DEV_DEVLOADER_NOT_FOUND2 "This device is not working properly
because the file $1 that loads the drivers for this device is bad."
+ IDS_DEV_DEVLOADER_NOT_FOUND3 "Device failure: Try changing the
driver for this device. If that doesn\'t work, see your hardware
documentation."
+ IDS_DEV_INVALID_DATA "This device is not working properly because
the BIOS in your computer is reporting the resources for the device
incorrectly."
+ IDS_DEV_INVALID_DATA2 "This device is not working properly because
the BIOS in the device is reporting the resources for the device
incorrectly. "
+ IDS_DEV_FAILED_START "This device is either not present, not
working properly, or does not have all the drivers installed."
+ IDS_DEV_LIAR "ReactOS stopped responding while attempting to start
this device, and therefore will never attempt to start this device
again."
+ IDS_DEV_NORMAL_CONFLICT "This device cannot find any free $1
resources to use."
+ IDS_DEV_NOT_VERIFIED "This device is either not present, not
working properly, or does not have all the drivers installed."
+ IDS_DEV_NEED_RESTART "This device cannot work properly until you
restart your computer."
+ IDS_DEV_REENUMERATION "This device is causing a resource conflict."
+ IDS_DEV_PARTIAL_LOG_CONF "Windows could not identify all the
resources this device uses."
+ IDS_DEV_UNKNOWN_RESOURCE "The driver information file $1 is telling
this child device to use a resource that the parent device does not have
or recognize."
+ IDS_DEV_REINSTALL "The drivers for this device need to be
reinstalled."
+ IDS_DEV_REGISTRY "Your registry may be bad."
+ IDS_DEV_WILL_BE_REMOVED "ReactOS is removing this device."
+ IDS_DEV_DISABLED "This device is not started."
+ IDS_DEV_DISABLED2 "This device is disabled."
+ IDS_DEV_DEVLOADER_NOT_READY "The loaders for this device cannot
load the required drivers."
+ IDS_DEV_DEVLOADER_NOT_READY2 "This display adapter is functioning
correctly."
+ IDS_DEV_DEVLOADER_NOT_READY3 "The loaders for this device cannot
load the required drivers."
+ IDS_DEV_DEVICE_NOT_THERE "This device is either not present, not
working properly, or does not have all the drivers installed."
+ IDS_DEV_MOVED "ReactOS is in the process of setting up this
device."
+ IDS_DEV_TOO_EARLY "ReactOS is in the process of setting up this
device."
+ IDS_DEV_NO_VALID_LOG_CONF "ReactOS can\'t specify the resources for
this device."
+ IDS_DEV_FAILED_INSTALL "The drivers for this device are not
installed."
+ IDS_DEV_HARDWARE_DISABLED "This device is disabled because the BIOS
for the device did not give it any resources."
+ IDS_DEV_CANT_SHARE_IRQ "This device is using an Interrupt Request
(IRQ) resource that is in use by another device and cannot be shared. "\
+ "You must change the conflicting setting or
remove the real-mode driver causing the conflict."
+ IDS_DEV_FAILED_ADD "This device is not working properly because $1
is not working properly."
+ IDS_DEV_DISABLED_SERVICE "ReactOS cannot install the drivers for
this device because it cannot access the drive or network location that
has the setup files on it."
+ IDS_DEV_TRANSLATION_FAILED "This device isn\'t responding to its
driver."
+ IDS_DEV_NO_SOFTCONFIG "ReactOS cannot determine the settings for
this device. Consult the documentation that came with this device and
use the Resource tab to set the configuration."
+ IDS_DEV_BIOS_TABLE "Your computer\'s system firmware does not
include enough information to properly configure and use this device. "\
+ "To use this device, contact your computer
manufacturer to obtain a firmware or BIOS update."
+ IDS_DEV_IRQ_TRANSLATION_FAILED "This device is requesting a PCI
interrupt but is configured for an ISA interrupt (or vice versa). "\
+ "Please use the computer\'s system
setup program to reconfigure the interrupt for this device."
+ IDS_DEV_FAILED_DRIVER_ENTRY "ReactOS cannot initialize the device
driver for this hardware."
+ IDS_DEV_DRIVER_FAILED_PRIOR_UNLOAD "ReactOS cannot load the device
driver for this hardware because a previous instance of the device
driver is still in memory."
+ IDS_DEV_DRIVER_FAILED_LOAD "ReactOS cannot load the device driver
for this hardware. The driver may be corrupted or missing."
+ IDS_DEV_DRIVER_SERVICE_KEY_INVALID "ReactOS cannot access this
hardware because its service key information in the registry is missing
or recorded incorrectly."
+ IDS_DEV_LEGACY_SERVICE_NO_DEVICES "ReactOS successfully loaded the
device driver for this hardware but cannot find the hardware device."
+ IDS_DEV_DUPLICATE_DEVICE "ReactOS cannot load the device driver for
this hardware because there is a duplicate device already running in the
system."
+ IDS_DEV_FAILED_POST_START "ReactOS has stopped this device because
it has reported problems."
+ IDS_DEV_HALTED "An application or service has shut down this
hardware device."
+ IDS_DEV_PHANTOM "Currently, this hardware device is not connected
to the computer."
+ IDS_DEV_SYSTEM_SHUTDOWN "ReactOS cannot gain access to this
hardware device because the operating system is in the process of
shutting down."
+ IDS_DEV_HELD_FOR_EJECT "ReactOS cannot use this hardware device
because it has been prepared for \"safe removal\", but it has not been
removed from the computer"
+ IDS_DEV_DRIVER_BLOCKED "The software for this device has been
blocked from starting because it is known to have problems with ReactOS.
Contact the hardware vendor for a new driver."
+ IDS_DEV_REGISTRY_TOO_LARGE "ReactOS cannot start new hardware
devices because the system hive is too large (exceeds the Registry Size
Limit)."
+ IDS_DEV_SETPROPERTIES_FAILED "ReactOS wasn\'t able to change the
settings of this device."
END
IDD_HARDWARE DIALOG DISCARDABLE 0, 0, 300, 400
_____
Modified: trunk/reactos/lib/devmgr/advprop.c
--- trunk/reactos/lib/devmgr/advprop.c 2005-12-07 13:09:01 UTC (rev
19946)
+++ trunk/reactos/lib/devmgr/advprop.c 2005-12-07 15:30:00 UTC (rev
19947)
@@ -166,7 +166,7 @@
{
BOOL Ret = FALSE;
- if (dap->DeviceUsageChanged && dap->IsAdmin)
+ if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable)
{
UINT SelectedUsageAction;
BOOL NeedReboot = FALSE;
@@ -237,7 +237,7 @@
CONFIGRET cr;
ULONG Status, ProblemNumber;
UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV;
- BOOL bFlag;
+ BOOL bFlag, bDevActionAvailable = TRUE;
DWORD i;
HDEVINFO DeviceInfoSet = NULL;
PSP_DEVINFO_DATA DeviceInfoData = NULL;
@@ -478,8 +478,6 @@
/* set the device troubleshoot button text and disable it if
necessary */
hDevProbBtn = GetDlgItem(hwndDlg,
IDC_DEVPROBLEM);
- EnableWindow(hDevProbBtn,
- dap->IsAdmin);
cr = CM_Get_DevNode_Status_Ex(&Status,
&ProblemNumber,
DeviceInfoData->DevInst,
@@ -489,13 +487,106 @@
{
switch (ProblemNumber)
{
- case CM_PROB_DISABLED:
- TroubleShootStrId = IDS_ENABLEDEV;
+ case CM_PROB_DEVLOADER_FAILED:
+ {
+ /* FIXME - only if it's not a root bus devloader,
+ disable the button otherwise */
+ TroubleShootStrId = IDS_UPDATEDRV;
break;
+ }
+ case CM_PROB_OUT_OF_MEMORY:
+ case CM_PROB_ENTRY_IS_WRONG_TYPE:
+ case CM_PROB_LACKED_ARBITRATOR:
+ case CM_PROB_FAILED_START:
+ case CM_PROB_LIAR:
+ case CM_PROB_UNKNOWN_RESOURCE:
+ {
+ TroubleShootStrId = IDS_UPDATEDRV;
+ break;
+ }
+
+ case CM_PROB_BOOT_CONFIG_CONFLICT:
+ case CM_PROB_NORMAL_CONFLICT:
+ case CM_PROB_REENUMERATION:
+ {
+ /* FIXME - Troubleshoot conflict */
+ break;
+ }
+
+ case CM_PROB_FAILED_FILTER:
+ case CM_PROB_REINSTALL:
case CM_PROB_FAILED_INSTALL:
+ {
TroubleShootStrId = IDS_REINSTALLDRV;
break;
+ }
+
+ case CM_PROB_DEVLOADER_NOT_FOUND:
+ {
+ /* FIXME - 4 cases:
+ 1) if it's a missing system devloader:
+ - disable the button (Reinstall Driver)
+ 2) if it's not a system devloader but still missing:
+ - Reinstall Driver
+ 3) if it's not a system devloader but the file can
be found:
+ - Update Driver
+ 4) if it's a missing or empty software key
+ - Update Driver
+ */
+ break;
+ }
+
+ case CM_PROB_INVALID_DATA:
+ case CM_PROB_PARTIAL_LOG_CONF:
+ case CM_PROB_NO_VALID_LOG_CONF:
+ case CM_PROB_HARDWARE_DISABLED:
+ case CM_PROB_CANT_SHARE_IRQ:
+ case CM_PROB_TRANSLATION_FAILED:
+ case CM_PROB_SYSTEM_SHUTDOWN:
+ case CM_PROB_PHANTOM:
+ bDevActionAvailable = FALSE;
+ break;
+
+ case CM_PROB_NOT_VERIFIED:
+ case CM_PROB_DEVICE_NOT_THERE:
+ /* FIXME - search hardware */
+ break;
+
+ case CM_PROB_NEED_RESTART:
+ case CM_PROB_WILL_BE_REMOVED:
+ case CM_PROB_MOVED:
+ case CM_PROB_TOO_EARLY:
+ case CM_PROB_DISABLED_SERVICE:
+ TroubleShootStrId = IDS_REBOOT;
+ break;
+
+ case CM_PROB_REGISTRY:
+ /* FIXME - check registry? */
+ break;
+
+ case CM_PROB_DISABLED:
+ /* if device was disabled by the user: */
+ TroubleShootStrId = IDS_ENABLEDEV;
+ /* FIXME - otherwise disable button because the device
was
+ disabled by the system*/
+ break;
+
+ case CM_PROB_DEVLOADER_NOT_READY:
+ /* FIXME - if it's a graphics adapter:
+ - if it's a a secondary adapter and the main
adapter
+ couldn't be found
+ - disable button
+ - else
+ - Properties
+ - else
+ - Update driver
+ */
+ break;
+
+ case CM_PROB_FAILED_ADD:
+ TroubleShootStrId = IDS_PROPERTIES;
+ break;
}
}
@@ -507,6 +598,8 @@
SetWindowText(hDevProbBtn,
dap->szTemp);
}
+ EnableWindow(hDevProbBtn,
+ dap->IsAdmin && bDevActionAvailable);
/* check if the device can be enabled/disabled */
hDevUsage = GetDlgItem(hwndDlg,
_____
Modified: trunk/reactos/lib/devmgr/devprblm.c
--- trunk/reactos/lib/devmgr/devprblm.c 2005-12-07 13:09:01 UTC (rev
19946)
+++ trunk/reactos/lib/devmgr/devprblm.c 2005-12-07 15:30:00 UTC (rev
19947)
@@ -50,18 +50,123 @@
{
switch (ProblemNumber)
{
- case CM_PROB_DISABLED:
+ case CM_PROB_DEVLOADER_FAILED:
{
- /* FIXME - display the "Enable Device" wizard */
+ /* FIXME - only if it's not a root bus devloader */
+ /* FIXME - display the update driver wizard */
break;
}
+ case CM_PROB_OUT_OF_MEMORY:
+ case CM_PROB_ENTRY_IS_WRONG_TYPE:
+ case CM_PROB_LACKED_ARBITRATOR:
+ case CM_PROB_FAILED_START:
+ case CM_PROB_LIAR:
+ case CM_PROB_UNKNOWN_RESOURCE:
+ {
+ /* FIXME - display the update driver wizard */
+ break;
+ }
+
+ case CM_PROB_BOOT_CONFIG_CONFLICT:
+ case CM_PROB_NORMAL_CONFLICT:
+ case CM_PROB_REENUMERATION:
+ {
+ /* FIXME - display the conflict wizard */
+ break;
+ }
+
+ case CM_PROB_FAILED_FILTER:
+ case CM_PROB_REINSTALL:
case CM_PROB_FAILED_INSTALL:
{
- /* FIXME - display the driver installation wizard */
+ /* FIXME - display the driver (re)installation wizard
*/
break;
}
+ case CM_PROB_DEVLOADER_NOT_FOUND:
+ {
+ /* FIXME - 4 cases:
+ 1) if it's a missing system devloader:
+ - fail
+ 2) if it's not a system devloader but still missing:
+ - display the driver reinstallation wizard
+ 3) if it's not a system devloader but the file can
be found:
+ - display the update driver wizard
+ 4) if it's a missing or empty software key
+ - display the update driver wizard
+ */
+ break;
+ }
+
+ case CM_PROB_INVALID_DATA:
+ case CM_PROB_PARTIAL_LOG_CONF:
+ case CM_PROB_NO_VALID_LOG_CONF:
+ case CM_PROB_HARDWARE_DISABLED:
+ case CM_PROB_CANT_SHARE_IRQ:
+ case CM_PROB_TRANSLATION_FAILED:
+ case CM_PROB_SYSTEM_SHUTDOWN:
+ case CM_PROB_PHANTOM:
+ /* FIXME - do nothing */
+ break;
+
+ case CM_PROB_NOT_VERIFIED:
+ case CM_PROB_DEVICE_NOT_THERE:
+ /* FIXME - display search hardware wizard */
+ break;
+
+ case CM_PROB_NEED_RESTART:
+ case CM_PROB_WILL_BE_REMOVED:
+ case CM_PROB_MOVED:
+ case CM_PROB_TOO_EARLY:
+ case CM_PROB_DISABLED_SERVICE:
+ /* FIXME - reboot computer */
+ break;
+
+ case CM_PROB_REGISTRY:
+ /* FIXME - check registry */
+ break;
+
+ case CM_PROB_DISABLED:
+ {
+ /* FIXME - if device was disabled by user display the
"Enable Device" wizard,
+ otherwise Troubleshoot because the device
was disabled by the system */
+ break;
+ }
+
+ case CM_PROB_DEVLOADER_NOT_READY:
+ {
+ /* FIXME - if it's a graphics adapter:
+ - if it's a a secondary adapter and the main
adapter
+ couldn't be found
+ - do nothing or default action
+ - else
+ - display the Properties
+ - else
+ - Update driver
+ */
+ break;
+ }
+
+ case CM_PROB_FAILED_ADD:
+ {
+ /* FIXME - display the properties of the sub-device */
+ break;
+ }
+
+ case CM_PROB_NO_SOFTCONFIG:
+ case CM_PROB_IRQ_TRANSLATION_FAILED:
+ case CM_PROB_FAILED_DRIVER_ENTRY:
+ case CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD:
+ case CM_PROB_DRIVER_FAILED_LOAD:
+ case CM_PROB_DRIVER_SERVICE_KEY_INVALID:
+ case CM_PROB_LEGACY_SERVICE_NO_DEVICES:
+ case CM_PROB_DUPLICATE_DEVICE:
+ case CM_PROB_FAILED_POST_START:
+ case CM_PROB_HALTED:
+ case CM_PROB_HELD_FOR_EJECT:
+ case CM_PROB_DRIVER_BLOCKED:
+ case CM_PROB_REGISTRY_TOO_LARGE:
default:
{
/* FIXME - troubleshoot the device */
_____
Modified: trunk/reactos/lib/devmgr/misc.c
--- trunk/reactos/lib/devmgr/misc.c 2005-12-07 13:09:01 UTC (rev
19946)
+++ trunk/reactos/lib/devmgr/misc.c 2005-12-07 15:30:00 UTC (rev
19947)
@@ -404,6 +404,7 @@
static const UINT ProblemStringId[NUM_CM_PROB] =
{
IDS_DEV_NO_PROBLEM,
+ IDS_DEV_DEVLOADER_FAILED,
IDS_DEV_NOT_CONFIGURED,
IDS_DEV_OUT_OF_MEMORY,
IDS_DEV_ENTRY_IS_WRONG_TYPE,
@@ -452,7 +453,7 @@
IDS_DEV_HELD_FOR_EJECT,
IDS_DEV_DRIVER_BLOCKED,
IDS_DEV_REGISTRY_TOO_LARGE,
- IDS_DEV_SETPROPERTIES_FAILED,
+ IDS_DEV_SETPROPERTIES_FAILED
};
@@ -486,19 +487,90 @@
}
else
{
- LPWSTR szProblem;
+ LPWSTR szProblem, szInfo = NULL;
+ DWORD dwRet;
+ BOOL AdvFormat = FALSE;
UINT StringIDs[] =
{
MessageId,
IDS_DEVCODE,
};
- if (LoadAndFormatStringsCat(hDllInstance,
- StringIDs,
- sizeof(StringIDs) /
sizeof(StringIDs[0]),
- &szProblem,
- ProblemNumber))
+ switch (ProblemNumber)
{
+ case CM_PROB_DEVLOADER_FAILED:
+ {
+ /* FIXME - if not a root bus devloader then use
IDS_DEV_DEVLOADER_FAILED2 */
+ /* FIXME - get the type string (ie. ISAPNP, PCI
or BIOS for root bus devloaders,
+ or FLOP, ESDI, SCSI, etc for others
*/
+ AdvFormat = (szInfo != NULL);
+ break;
+ }
+
+ case CM_PROB_DEVLOADER_NOT_FOUND:
+ {
+ /* FIXME - 4 cases:
+ 1) if it's a missing system devloader:
+ - get the system devloader name
+ 2) if it's not a system devloader but still
missing:
+ - get the devloader name (file name?)
+ 3) if it's not a system devloader but the
file can be found:
+ - use IDS_DEV_DEVLOADER_NOT_FOUND2
+ 4) if it's a missing or empty software key
+ - use IDS_DEV_DEVLOADER_NOT_FOUND3
+ - AdvFormat = FALSE!
+ */
+ AdvFormat = (szInfo != NULL);
+ break;
+ }
+
+ case CM_PROB_INVALID_DATA:
+ /* FIXME - if the device isn't enumerated by
the BIOS/ACPI use IDS_DEV_INVALID_DATA2 */
+ AdvFormat = FALSE;
+ break;
+
+ case CM_PROB_NORMAL_CONFLICT:
+ /* FIXME - get resource type (IRQ, DMA, Memory
or I/O) */
+ AdvFormat = (szInfo != NULL);
+ break;
+
+ case CM_PROB_UNKNOWN_RESOURCE:
+ /* FIXME - get the .inf file name */
+ AdvFormat = (szInfo != NULL);
+ break;
+
+ case CM_PROB_DISABLED:
+ /* FIXME - if the device was disabled by the
system use IDS_DEV_DISABLED2 */
+ break;
+
+ case CM_PROB_FAILED_ADD:
+ /* FIXME - get the name of the sub-device with
the error */
+ AdvFormat = (szInfo != NULL);
+ break;
+ }
+
+ if (AdvFormat)
+ {
+ StringIDs[1] = IDS_DEVCODE2;
+ dwRet = LoadAndFormatStringsCat(hDllInstance,
+ StringIDs,
+ sizeof(StringIDs) /
sizeof(StringIDs[0]),
+ &szProblem,
+ szInfo,
+ ProblemNumber);
+ LocalFree((HLOCAL)szInfo);
+ }
+ else
+ {
+ dwRet = LoadAndFormatStringsCat(hDllInstance,
+ StringIDs,
+ sizeof(StringIDs) /
sizeof(StringIDs[0]),
+ &szProblem,
+ ProblemNumber);
+ }
+
+ if (dwRet != 0)
+ {
wcsncpy(szBuffer,
szProblem,
BufferSize - 1);
@@ -630,7 +702,7 @@
if (bEnable)
{
- /* try to enable/disable the device on the global profile */
+ /* try to enable the device on the global profile */
pcp.StateChange = DICS_ENABLE;
pcp.Scope = DICS_FLAG_GLOBAL;
_____
Modified: trunk/reactos/lib/devmgr/resource.h
--- trunk/reactos/lib/devmgr/resource.h 2005-12-07 13:09:01 UTC (rev
19946)
+++ trunk/reactos/lib/devmgr/resource.h 2005-12-07 15:30:00 UTC (rev
19947)
@@ -24,7 +24,6 @@
#define IDC_PROPERTIES 0x58A
#define IDC_DEVUSAGELABEL 0x58B
#define IDC_DEVPROBLEM 0x58C
-#define IDS_REINSTALLDRV 0x58D
#define IDS_NAME 0x100
#define IDS_TYPE 0x101
@@ -34,64 +33,76 @@
#define IDS_UNKNOWN 0x105
#define IDS_LOCATIONSTR 0x106
#define IDS_DEVCODE 0x107
-#define IDS_ENABLEDEVICE 0x108
-#define IDS_DISABLEDEVICE 0x109
-#define IDS_UNKNOWNDEVICE 0x10A
-#define IDS_NODRIVERLOADED 0x10B
-#define IDS_DEVONPARENT 0x10C
-#define IDS_TROUBLESHOOTDEV 0x10D
-#define IDS_ENABLEDEV 0x10E
+#define IDS_DEVCODE2 0x108
+#define IDS_ENABLEDEVICE 0x109
+#define IDS_DISABLEDEVICE 0x10A
+#define IDS_UNKNOWNDEVICE 0x10B
+#define IDS_NODRIVERLOADED 0x10C
+#define IDS_DEVONPARENT 0x10D
+#define IDS_TROUBLESHOOTDEV 0x10E
+#define IDS_ENABLEDEV 0x10F
+#define IDS_PROPERTIES 0x110
+#define IDS_UPDATEDRV 0x111
+#define IDS_REINSTALLDRV 0x112
+#define IDS_REBOOT 0x113
#define IDS_DEV_NO_PROBLEM 0x200
#define IDS_DEV_NOT_CONFIGURED 0x201
#define IDS_DEV_DEVLOADER_FAILED 0x202
-#define IDS_DEV_OUT_OF_MEMORY 0x203
-#define IDS_DEV_ENTRY_IS_WRONG_TYPE 0x204
-#define IDS_DEV_LACKED_ARBITRATOR 0x205
-#define IDS_DEV_BOOT_CONFIG_CONFLICT 0x206
-#define IDS_DEV_FAILED_FILTER 0x207
-#define IDS_DEV_DEVLOADER_NOT_FOUND 0x208
-#define IDS_DEV_INVALID_DATA 0x209
-#define IDS_DEV_FAILED_START 0x20A
-#define IDS_DEV_LIAR 0x20B
-#define IDS_DEV_NORMAL_CONFLICT 0x20C
-#define IDS_DEV_NOT_VERIFIED 0x20D
-#define IDS_DEV_NEED_RESTART 0x20E
-#define IDS_DEV_REENUMERATION 0x20F
-#define IDS_DEV_PARTIAL_LOG_CONF 0x210
-#define IDS_DEV_UNKNOWN_RESOURCE 0x211
-#define IDS_DEV_REINSTALL 0x212
-#define IDS_DEV_REGISTRY 0x213
-#define IDS_DEV_WILL_BE_REMOVED 0x214
-#define IDS_DEV_DISABLED 0x215
-#define IDS_DEV_DEVLOADER_NOT_READY 0x216
-#define IDS_DEV_DEVICE_NOT_THERE 0x217
-#define IDS_DEV_MOVED 0x218
-#define IDS_DEV_TOO_EARLY 0x219
-#define IDS_DEV_NO_VALID_LOG_CONF 0x21A
-#define IDS_DEV_FAILED_INSTALL 0x21B
-#define IDS_DEV_HARDWARE_DISABLED 0x21C
-#define IDS_DEV_CANT_SHARE_IRQ 0x21D
-#define IDS_DEV_FAILED_ADD 0x21E
-#define IDS_DEV_DISABLED_SERVICE 0x21F
-#define IDS_DEV_TRANSLATION_FAILED 0x220
-#define IDS_DEV_NO_SOFTCONFIG 0x221
-#define IDS_DEV_BIOS_TABLE 0x222
-#define IDS_DEV_IRQ_TRANSLATION_FAILED 0x223
-#define IDS_DEV_FAILED_DRIVER_ENTRY 0x224
-#define IDS_DEV_DRIVER_FAILED_PRIOR_UNLOAD 0x225
-#define IDS_DEV_DRIVER_FAILED_LOAD 0x226
-#define IDS_DEV_DRIVER_SERVICE_KEY_INVALID 0x227
-#define IDS_DEV_LEGACY_SERVICE_NO_DEVICES 0x228
-#define IDS_DEV_DUPLICATE_DEVICE 0x229
-#define IDS_DEV_FAILED_POST_START 0x22A
-#define IDS_DEV_HALTED 0x22B
-#define IDS_DEV_PHANTOM 0x22C
-#define IDS_DEV_SYSTEM_SHUTDOWN 0x22D
-#define IDS_DEV_HELD_FOR_EJECT 0x22E
-#define IDS_DEV_DRIVER_BLOCKED 0x22F
-#define IDS_DEV_REGISTRY_TOO_LARGE 0x230
-#define IDS_DEV_SETPROPERTIES_FAILED 0x231
+#define IDS_DEV_DEVLOADER_FAILED2 0x203
+#define IDS_DEV_OUT_OF_MEMORY 0x204
+#define IDS_DEV_ENTRY_IS_WRONG_TYPE 0x205
+#define IDS_DEV_LACKED_ARBITRATOR 0x206
+#define IDS_DEV_BOOT_CONFIG_CONFLICT 0x207
+#define IDS_DEV_FAILED_FILTER 0x208
+#define IDS_DEV_DEVLOADER_NOT_FOUND 0x209
+#define IDS_DEV_DEVLOADER_NOT_FOUND2 0x20A
+#define IDS_DEV_DEVLOADER_NOT_FOUND3 0x20B
+#define IDS_DEV_INVALID_DATA 0x20C
+#define IDS_DEV_INVALID_DATA2 0x20D
+#define IDS_DEV_FAILED_START 0x20E
+#define IDS_DEV_LIAR 0x20F
+#define IDS_DEV_NORMAL_CONFLICT 0x210
+#define IDS_DEV_NOT_VERIFIED 0x211
+#define IDS_DEV_NEED_RESTART 0x212
+#define IDS_DEV_REENUMERATION 0x213
+#define IDS_DEV_PARTIAL_LOG_CONF 0x214
+#define IDS_DEV_UNKNOWN_RESOURCE 0x215
+#define IDS_DEV_REINSTALL 0x216
+#define IDS_DEV_REGISTRY 0x217
+#define IDS_DEV_WILL_BE_REMOVED 0x218
+#define IDS_DEV_DISABLED 0x219
+#define IDS_DEV_DISABLED2 0x21A
+#define IDS_DEV_DEVLOADER_NOT_READY 0x21B
+#define IDS_DEV_DEVLOADER_NOT_READY2 0x21C
+#define IDS_DEV_DEVLOADER_NOT_READY3 0x21D
+#define IDS_DEV_DEVICE_NOT_THERE 0x21E
+#define IDS_DEV_MOVED 0x21F
+#define IDS_DEV_TOO_EARLY 0x220
+#define IDS_DEV_NO_VALID_LOG_CONF 0x221
+#define IDS_DEV_FAILED_INSTALL 0x222
+#define IDS_DEV_HARDWARE_DISABLED 0x223
+#define IDS_DEV_CANT_SHARE_IRQ 0x224
+#define IDS_DEV_FAILED_ADD 0x225
+#define IDS_DEV_DISABLED_SERVICE 0x226
+#define IDS_DEV_TRANSLATION_FAILED 0x227
+#define IDS_DEV_NO_SOFTCONFIG 0x228
+#define IDS_DEV_BIOS_TABLE 0x229
+#define IDS_DEV_IRQ_TRANSLATION_FAILED 0x22A
+#define IDS_DEV_FAILED_DRIVER_ENTRY 0x22B
+#define IDS_DEV_DRIVER_FAILED_PRIOR_UNLOAD 0x22C
+#define IDS_DEV_DRIVER_FAILED_LOAD 0x22D
+#define IDS_DEV_DRIVER_SERVICE_KEY_INVALID 0x22E
+#define IDS_DEV_LEGACY_SERVICE_NO_DEVICES 0x22F
+#define IDS_DEV_DUPLICATE_DEVICE 0x230
+#define IDS_DEV_FAILED_POST_START 0x231
+#define IDS_DEV_HALTED 0x232
+#define IDS_DEV_PHANTOM 0x233
+#define IDS_DEV_SYSTEM_SHUTDOWN 0x234
+#define IDS_DEV_HELD_FOR_EJECT 0x235
+#define IDS_DEV_DRIVER_BLOCKED 0x236
+#define IDS_DEV_REGISTRY_TOO_LARGE 0x237
+#define IDS_DEV_SETPROPERTIES_FAILED 0x238
#endif /* __DEVMGR_RESOURCE_H */