diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
index 486bd0f763f1d94935084998faf4bf868bfa23e4..f248228ffd420c23bd40ad2e91f19c02eb1c7f1f 100644
--- a/dlls/dsound/buffer.c
+++ b/dlls/dsound/buffer.c
@@ -235,15 +235,18 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume(
 	ICOM_THIS(IDirectSoundBufferImpl,iface);
 	TRACE("(%p,%p)\n",This,vol);
 
+	if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
+		WARN("control unavailable\n");
+		return DSERR_CONTROLUNAVAIL;
+	}
+
 	if (vol == NULL) {
 		WARN("invalid parameter: vol == NULL\n");
 		return DSERR_INVALIDPARAM;
 	}
 
-	if (This->dsbd.dwFlags & DSBCAPS_CTRL3D)
-		*vol = This->ds3db_lVolume;
-	else
-		*vol = This->volpan.lVolume;
+	*vol = This->volpan.lVolume;
+
 	return DS_OK;
 }
 
@@ -759,6 +762,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetPan(
 	ICOM_THIS(IDirectSoundBufferImpl,iface);
 	TRACE("(%p,%p)\n",This,pan);
 
+	if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
+		WARN("control unavailable\n");
+		return DSERR_CONTROLUNAVAIL;
+	}
+
 	if (pan == NULL) {
 		WARN("invalid parameter: pan = NULL\n");
 		return DSERR_INVALIDPARAM;
diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c
index e13b388c161069d7decd9560e22d4dc1e9b79dbe..43f990dad2e32b5d714479e052a6ff29bdb478fb 100644
--- a/dlls/dsound/capture.c
+++ b/dlls/dsound/capture.c
@@ -197,7 +197,7 @@ DirectSoundCaptureEnumerateA(
 	    		if (err == DS_OK) {
 			    TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
 		    		debugstr_guid(&DSDEVID_DefaultCapture),"Primary Sound Capture Driver",desc.szDrvName,lpContext);
-			    if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, "Primary Sound Capture Driver", desc.szDrvName, lpContext) == FALSE)
+			    if (lpDSEnumCallback(NULL, "Primary Sound Capture Driver", desc.szDrvName, lpContext) == FALSE)
 				return DS_OK;
 			}
 		    }
@@ -270,7 +270,7 @@ DirectSoundCaptureEnumerateW(
 			        wDesc, sizeof(wDesc)/sizeof(WCHAR) );
 			    MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, 
 		    	        wName, sizeof(wName)/sizeof(WCHAR) );
-			    if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, wDesc, wName, lpContext) == FALSE)
+			    if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE)
 				return DS_OK;
 			}
 		    }
@@ -325,10 +325,10 @@ DSOUND_capture_callback(
 		This->read_position = mtime.u.cb;
 		This->state = STATE_CAPTURING;
 	    }
-	    This->index = (This->index + 1) % This->nrofpwaves;
 	    waveInUnprepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR));
 	    if (This->capture_buffer->nrofnotifies)
 		SetEvent(This->capture_buffer->notifies[This->index].hEventNotify);
+	    This->index = (This->index + 1) % This->nrofpwaves;
 	    if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) {
 		TRACE("end of buffer\n");
 		This->state = STATE_STOPPED;
diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c
index 144557259e8a1f0f862f8385b738a1ab6b557597..a312b549c49e2e996bd12b3d8859bbe3dffe773a 100644
--- a/dlls/dsound/dsound_main.c
+++ b/dlls/dsound/dsound_main.c
@@ -336,7 +336,7 @@ HRESULT WINAPI DirectSoundEnumerateA(
 			if (err == DS_OK) {
 			    TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
 				debugstr_guid(&DSDEVID_DefaultPlayback),"Primary Sound Driver",desc.szDrvName,lpContext);
-			    if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback, "Primary Sound Driver", desc.szDrvName, lpContext) == FALSE)
+			    if (lpDSEnumCallback(NULL, "Primary Sound Driver", desc.szDrvName, lpContext) == FALSE)
 				return DS_OK;
 			}
 		    }
@@ -408,7 +408,7 @@ HRESULT WINAPI DirectSoundEnumerateW(
 				wDesc, sizeof(wDesc)/sizeof(WCHAR) );
 				MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
 				wName, sizeof(wName)/sizeof(WCHAR) );
-			    if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback, wDesc, wName, lpContext) == FALSE)
+			    if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE)
 				return DS_OK;
 			}
 		    }
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
index b58615b3ac85d78c122d953af75a9639bc2ebb8d..42b76fb4bc5fd59d4c04d2b2361d367b631afab5 100644
--- a/dlls/dsound/primary.c
+++ b/dlls/dsound/primary.c
@@ -745,11 +745,53 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(
 	LPDIRECTSOUNDBUFFER8 iface,LONG pan
 ) {
 	ICOM_THIS(PrimaryBufferImpl,iface);
+	IDirectSoundImpl* dsound = This->dsound;
+	LONG oldPan;
+
 	TRACE("(%p,%ld)\n",This,pan);
 
-	/* You cannot set the pan of the primary buffer */
-	WARN("control unavailable\n");
-	return DSERR_CONTROLUNAVAIL;
+	if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
+		WARN("control unavailable\n");
+		return DSERR_CONTROLUNAVAIL;
+	}
+
+	if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
+		WARN("invalid parameter: pan = %ld\n", pan);
+		return DSERR_INVALIDPARAM;
+	}
+
+	/* **** */
+	EnterCriticalSection(&(dsound->mixlock));
+
+	oldPan = dsound->volpan.lPan;
+	dsound->volpan.lPan = pan;
+	DSOUND_RecalcVolPan(&dsound->volpan);
+
+	if (pan != oldPan) {
+		if (dsound->hwbuf) {
+			HRESULT hres;
+			hres = IDsDriverBuffer_SetVolumePan(dsound->hwbuf, &(dsound->volpan));
+			if (hres != DS_OK) {
+				LeaveCriticalSection(&(dsound->mixlock));
+				WARN("IDsDriverBuffer_SetVolumePan failed\n");
+				return hres;
+			}
+		}
+		else {
+#if 0 /* should we really do this? */
+			/* the DS volume ranges from 0 (max, 0dB attenuation) to -10000 (min, 100dB attenuation) */
+			/* the MM volume ranges from 0 to 0xffff in an unspecified logarithmic scale */
+			WORD cvol = 0xffff + vol*6 + vol/2;
+			DWORD vol = cvol | ((DWORD)cvol << 16)
+			waveOutSetVolume(dsound->hwo, vol);
+#endif
+		}
+	}
+
+	LeaveCriticalSection(&(dsound->mixlock));
+	/* **** */
+
+	return DS_OK;
 }
 
 static HRESULT WINAPI PrimaryBufferImpl_GetPan(
@@ -758,6 +800,11 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(
 	ICOM_THIS(PrimaryBufferImpl,iface);
 	TRACE("(%p,%p)\n",This,pan);
 
+	if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
+		WARN("control unavailable\n");
+		return DSERR_CONTROLUNAVAIL;
+	}
+
 	if (pan == NULL) {
 		WARN("invalid parameter: pan == NULL\n");
 		return DSERR_INVALIDPARAM;
@@ -774,7 +821,7 @@ static HRESULT WINAPI PrimaryBufferImpl_Unlock(
 	ICOM_THIS(PrimaryBufferImpl,iface);
 	IDirectSoundImpl* dsound = This->dsound;
 
-	TRACE("(%p,%p,%ld,%p,%ld):stub\n", This,p1,x1,p2,x2);
+	TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2);
 
 	if (dsound->priolevel != DSSCL_WRITEPRIMARY) {
 		WARN("failed priority check!\n");
diff --git a/dlls/dsound/propset.c b/dlls/dsound/propset.c
index 6d72cc20f2e52eecdf024c468a46592434f281f7..eeb628ed6fdfe29b704b731490ea3bf61d78f8a7 100644
--- a/dlls/dsound/propset.c
+++ b/dlls/dsound/propset.c
@@ -449,9 +449,123 @@ static HRESULT WINAPI DSPROPERTY_DescriptionA(
     ULONG cbPropData,
     PULONG pcbReturned )
 {
-    FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
+    PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData;
+    HRESULT err;
+    GUID guid, dev_guid;
+    TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
 	debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
-    return E_PROP_ID_UNSUPPORTED;
+
+    TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
+    if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
+	/* default device of type specified by ppd->DataFlow */
+	if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
+	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
+	} else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
+	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
+	} else {
+	    TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
+	}
+	FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
+	    debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
+	return E_PROP_ID_UNSUPPORTED;
+    }
+
+    ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
+    GetDeviceID(&ppd->DeviceId, &dev_guid);
+
+    if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
+	 IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
+	ULONG wod;
+	int wodn;
+	TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
+	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
+	wodn = waveOutGetNumDevs();
+	for (wod = 0; wod < wodn; wod++) {
+	    err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
+	    if (err == DS_OK) {
+		if (IsEqualGUID( &dev_guid, &guid) ) {
+		    DSDRIVERDESC desc;
+		    ppd->WaveDeviceId = wod;
+		    err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
+		    if (err == DS_OK) {
+			PIDSDRIVER drv = NULL;
+			/* FIXME: this is a memory leak */
+			CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
+			CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1);
+			CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
+
+			strcpy(szDescription, desc.szDesc);
+			strcpy(szModule, desc.szDrvName);
+			strcpy(szInterface, "Interface");
+
+			ppd->Description = szDescription;
+			ppd->Module = szModule;
+			ppd->Interface = szInterface;
+			err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
+			if (err == DS_OK && drv)
+			    ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
+			break;
+		    } else {
+			WARN("waveOutMessage failed\n");
+			return E_PROP_ID_UNSUPPORTED;
+		    }
+		}
+	    } else {
+		WARN("waveOutMessage failed\n");
+		return E_PROP_ID_UNSUPPORTED;
+	    }
+	}
+    } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
+	       IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
+	ULONG wid;
+	int widn;
+	TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
+	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
+	widn = waveInGetNumDevs();
+	for (wid = 0; wid < widn; wid++) {
+	    err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
+	    if (err == DS_OK) {
+		if (IsEqualGUID( &dev_guid, &guid) ) {
+		    DSDRIVERDESC desc;
+		    ppd->WaveDeviceId = wid;
+		    err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
+		    if (err == DS_OK) {
+			PIDSCDRIVER drv;
+			/* FIXME: this is a memory leak */
+			CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
+			CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1);
+			CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
+
+			strcpy(szDescription, desc.szDesc);
+			strcpy(szModule, desc.szDrvName);
+			strcpy(szInterface, "Interface");
+
+			ppd->Description = szDescription;
+			ppd->Module = szModule;
+			ppd->Interface = szInterface;
+			err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
+			if (err == DS_OK && drv)
+				ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
+			break;
+		    } else {
+			WARN("waveInMessage failed\n");
+			return E_PROP_ID_UNSUPPORTED;
+		    }
+		    break;
+		}
+	    } else {
+		WARN("waveOutMessage failed\n");
+		return E_PROP_ID_UNSUPPORTED;
+	    }
+	}
+    }
+
+    if (pcbReturned) {
+	*pcbReturned = cbPropData;
+	TRACE("*pcbReturned=%ld\n", *pcbReturned);
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI DSPROPERTY_DescriptionW(
diff --git a/dlls/winmm/wineoss/audio.c b/dlls/winmm/wineoss/audio.c
index fb56fab6a31e2f3b8ce00e13dc14d6f7c59634e5..83cd00db07a9f1ac1a79d503eaa3049dda483614 100644
--- a/dlls/winmm/wineoss/audio.c
+++ b/dlls/winmm/wineoss/audio.c
@@ -2140,7 +2140,8 @@ static HRESULT WINAPI IDsDriverBufferImpl_SetVolumePan(PIDSDRIVERBUFFER iface, P
 {
     /* ICOM_THIS(IDsDriverBufferImpl,iface); */
     FIXME("(%p,%p): stub!\n",iface,pVolPan);
-    return DSERR_UNSUPPORTED;
+    /* FIXME: the dsound software mixer does this for us so don't return an error */
+    return DS_OK;
 }
 
 static HRESULT WINAPI IDsDriverBufferImpl_SetPosition(PIDSDRIVERBUFFER iface, DWORD dwNewPos)