Project

General

Profile

Actions

Emulator Issues #2538

closed

[WIN32]: WIIUSE + WII_IPC_HLE_WIIMOTE/DEVICE_USB Issue - NO "wiiuse_unexpected_disconnect" causing handle leakage!

Added by snzgoo about 14 years ago.

Status:
Fixed
Priority:
Normal
Assignee:
-
% Done:

0%

Operating system:
N/A
Issue type:
Bug
Milestone:
Regression:
No
Relates to usability:
No
Relates to performance:
No
Easy:
No
Relates to maintainability:
No
Regression start:
Fixed in:

Description

PROBLEM:
Pair up a wiimote under win32, take out the batteries and try to pair it up
as long dolphin is still running -->> FAIL.

REASON:
Wiise leaks createfile() handles on wiiuse_unexpected_disconnects.

It's because [WIIUSE] is not taking care of wiiuse_unexpected_disconnects
at all under WIN32, causing to leave the dev_handle created by createfile()
within wiiuse_find() open. The leak happens after timing out on
io_read/write which is not handled atm, disallowing us to re-pair the same
wiimote again as long dolphin is still running.

However fixing the problem with the leaked handles under WIIUSE causes new
a problem but a problem within dolphin. We will need to relink those
re-paired wiimotes with the Update() device_usb routine somehow, 'cause i
presume the core is still using the old HID handle channel or whatever.

A simple DoRefreshReal() for relinking atm only works for us, because
wiiuse fails in cleaning up handles, making a relink of the device_usb
unnecessary but as soon you have a new handle dorefreshreal() is not enough
to relink those (re)paired wiimotes.
The problem lies within the device_usb/hle_Wiimote section, i would
appreciate it if someone with more knowledge of the HID could take a look
at it.

What is needed:
1)Implementing wiiuse_unexpected_disconnect @wiiuse. (code below)
2)Implementing a routine that also relinks/rechannels paired wiimotes with
the device_usb/hle_Wiimote if the HID/dev_handle has changed.

WIIUSE fix:
http://archiv.to/GET/FILE4BBDE376ED48E


Index: io_win.c

--- io_win.c (revision 5289)
+++ io_win.c (working copy)
@@ -112,22 +114,31 @@

		/* try to set the output report to see if the device is actually

connected */
if (!wiiuse_set_report_type(wm[found])) {

  •   		Sleep(10);
      		WIIMOTE_DISABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED);
    
  •   		if (wm[found]->event == WIIUSE_UNEXPECTED_DISCONNECT) {
    
  •   			break;
    
  •   		} 
      		continue;
    
  •   	}
      	/* do the handshake */
      	wiiuse_handshake(wm[found], NULL, 0);
    
      	++found;
      	if (found >= max_wiimotes)
      		break;
      } else {
      	/* not a wiimote */
    
      	CloseHandle(dev);
      }
    
  •   Sleep(10);
    

    }

    if (detail_data)
    @@ -180,22 +193,24 @@

      if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) {
      	/* remote disconnect */
    
  •   	WIIUSE_WARNING("ERROR_DEVICE_NOT_CONNECTED unid:%d error:%d.",
    

wm->unid, b);

  •   	wm->event = WIIUSE_UNEXPECTED_DISCONNECT;
      	wiiuse_disconnected(wm);
      	return 0;
      }
    
      r = WaitForSingleObject(wm->hid_overlap.hEvent, wm->timeout);
      if (r == WAIT_TIMEOUT) {
      	/* timeout - cancel and continue */
    
  •   	/*if (*wm->event_buf)
    
  •   		WIIUSE_WARNING("Packet ignored.  This may indicate a problem (timeout
    

is %i ms).", wm->timeout); */

  •   	if (*wm->event_buf)
    
  •   		WIIUSE_WARNING("Packet ignored.  This may indicate a problem (timeout
    

is %i ms).", wm->timeout);

		CancelIo(wm->dev_handle);
		ResetEvent(wm->hid_overlap.hEvent);
		return 0;
	} else if (r == WAIT_FAILED) {
  •   	WIIUSE_WARNING("A wait error occured on reading from wiimote %i.",
    

wm->unid);

  •   	WIIUSE_WARNING("WAIT_FAILED %i.", wm->unid);
      	return 0;
      }
    

@@ -229,19 +244,37 @@
wm->stack = WIIUSE_STACK_BLUESOLEIL;
return i;
}
+

		if (i = HidD_SetOutputReport(wm->dev_handle, buf + 1, len - 1)) {
			wm->stack = WIIUSE_STACK_MS;
			return i;
		}
  •   	WIIUSE_ERROR("Unable to determine bluetooth stack type.");
    
  •   	//121 = timeout on semaphore/device off/disconnected
    
  •   	if (GetLastError() == 121) {
    
  •   		wm->event = WIIUSE_UNEXPECTED_DISCONNECT;
    
  •   		WIIUSE_INFO("WIIUSE_UNEXPECTED_DISCONNECT");
    
  •   		wiiuse_disconnected(wm);
    
  •   	}
    
  •   	WIIUSE_ERROR("Unable to determine bluetooth stack type || Wiimote timed
    

out.");
return 0;
}

	case WIIUSE_STACK_MS:
  •   	return HidD_SetOutputReport(wm->dev_handle, buf + 1, len - 1);
    
  •   	i = HidD_SetOutputReport(wm->dev_handle, buf + 1, len - 1);
    
  •   	if (GetLastError() == 121) {
    
  •   		wm->event = WIIUSE_UNEXPECTED_DISCONNECT;
    
  •   		WIIUSE_INFO("WIIUSE_UNEXPECTED_DISCONNECT");
    
  •   		wiiuse_disconnected(wm);
    
  •   		return 0;
    
  •   	}
    
  •   	return ((BOOLEAN) i);
    
  •   case WIIUSE_STACK_BLUESOLEIL:
      	return WriteFile(wm->dev_handle, buf + 1, 22, &bytes, &wm->hid_overlap);
    

    }
    Index: wiiuse.c
    ===================================================================
    --- wiiuse.c (revision 5289)
    +++ wiiuse.c (working copy)
    @@ -71,6 +71,7 @@
    WIIUSE_INFO("wiiuse clean up...");

    for (; i < wiimotes; ++i) {

  •   //CloseHandle(wm[i]-&gt;dev_handle);
      wiiuse_disconnect(wm[i]);
      free(wm[i]);
    

    }
    @@ -170,15 +171,10 @@

    /* disable the connected flag /
    WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
    /
    reset a bunch of stuff */

  • #ifndef WIN32
  •   wm-&gt;out_sock = -1;
    
  •   wm-&gt;in_sock = -1;
    
  • #else
  •   wm-&gt;dev_handle = 0;
    
  • #endif
  • wm->leds = 0;
    wm->state = WIIMOTE_INIT_STATES;
    wm->read_req = NULL;
    @@ -187,8 +183,17 @@
    wm->btns_held = 0;
    wm->btns_released = 0;
    memset(wm->event_buf, 0, sizeof(wm->event_buf));
  • if (wm->event == WIIUSE_UNEXPECTED_DISCONNECT) {
  •   CloseHandle(wm-&gt;dev_handle);
    
  • }
  • else
    wm->event = WIIUSE_DISCONNECT;
  • #ifndef WIN32
  •   wm-&gt;out_sock = -1;
    
  •   wm-&gt;in_sock = -1;
    
  • #else
  •   wm-&gt;dev_handle = 0;
    
  • #endif
    }
Actions #1

Updated by snzgoo about 14 years ago

BTW you can simply trace the createfile() wiimote handles by using the windows
resource monitor. Just monitor dolphin.exe, you will find the handles under CPU/
assigned handles. They look like: FILE \Device\00000XXX

Actions #2

Updated by NeoBrainX about 14 years ago

CCing ayuanx on request

Actions #3

Updated by snzgoo about 14 years ago

Actions #4

Updated by snzgoo about 14 years ago

Nvm, i already fixed the issue, it was simpler than i thought.., however, i'll
publish it 2morrow or so. I just didnt look at that place cuz i didnt think somebody
was messing with my that code part...

Actions #6

Updated by Anonymous about 14 years ago

  • Status changed from New to Fixed
Actions

Also available in: Atom PDF