📄 usbswitch.cpp
字号:
VBR(lineShutdown(hLineApp) == 0);
}
LocalFree(pDevConfig);
EXITTRACE(hr);
return hr;
}
//
// Creates or updates a specified RAS connection for USB Serial
//
HRESULT CreateConnectoid(__in LPCTSTR pszEntry, __in LPCTSTR pszDevice, __in LPCTSTR pszBaud)
{
ENTERTRACE();
Trace(L"Entry=%s, Device=%s, Baud=%s", pszEntry, pszDevice, pszBaud);
HRESULT hr = S_OK;
DWORD cb = 0;
RASENTRY RasEntry = { 0 };
LPVARSTRING pDevConfig = NULL;
DWORD dwErr = 0;
// Get a default RasEntry
RasEntry.dwSize = sizeof(RasEntry);
cb = sizeof(RASENTRY);
dwErr = RasGetEntryProperties(NULL, TEXT(""), &RasEntry, &cb, NULL, NULL);
CBREx(dwErr == 0, HRESULT_FROM_WIN32(dwErr));
Trace(L"CreateConnectoid: '%s' '%s' 0x%x", RasEntry.szDeviceName, RasEntry.szDeviceType, RasEntry.dwfOptions);
hr = StringCbCopy(RasEntry.szDeviceName, sizeof(RasEntry.szDeviceName), pszDevice);
CHR(hr);
for (int i = 0; i < 10; i++)
{
hr = SetBaudRate(&RasEntry, pszBaud, &pDevConfig);
if (pDevConfig)
{
break;
}
else
{
VBR(FAILED(hr));
Sleep(i * 300);
}
}
CHR(hr);
//
// Active Sync uses these for desktop pass-through.
// We need to set the default gateway as the desktop, so the IP packet's
// won't try to go through any WIFI connection.
//
RasEntry.dwfOptions |= RASEO_RemoteDefaultGateway;
if (pDevConfig)
{
dwErr = RasSetEntryProperties(NULL, (LPTSTR) pszEntry, &RasEntry, sizeof(RASENTRY),
((LPBYTE)pDevConfig + pDevConfig->dwStringOffset),
pDevConfig->dwStringSize);
CBREx(dwErr == 0, HRESULT_FROM_WIN32(dwErr));
}
Error:
if (pDevConfig)
{
LocalFree(pDevConfig);
}
EXITTRACE(hr);
return hr;
}
//
// Creates or updates RAS connections corresponding to USB serial
//
HRESULT CreateDefaultConnectoids()
{
ENTERTRACE();
HRESULT hr = S_OK;
HKEY hkey = NULL;
TCHAR szUSBFriendlyName[MAX_PATH];
hr = RegistryGetString(HKEY_LOCAL_MACHINE, _T("\\Drivers\\USB\\FunctionDrivers\\Serial_Class"),
_T("FriendlyName"), szUSBFriendlyName, ARRAYSIZE(szUSBFriendlyName));
CHR(hr);
Trace(L"FriendlyName=%s", szUSBFriendlyName);
hr = CreateConnectoid(c_szUsbRasName, szUSBFriendlyName, _T("115200"));
CHR(hr);
Error:
if (hkey)
{
RegCloseKey(hkey);
}
EXITTRACE(hr);
return hr;
}
//
// Returns a handle to USB bus controller
//
HRESULT GetUfnController(__out HANDLE* phUfn)
{
ENTERTRACE();
HRESULT hr = S_OK;
GUID guidBus;
HANDLE hFind = INVALID_HANDLE_VALUE;
DEVMGR_DEVICE_INFORMATION di = { 0 };
// Parse the GUID
hr = CLSIDFromString(USBBUS_GUID, &guidBus);
CHR(hr);
// Get a handle to the bus driver
di.dwSize = sizeof(di);
hFind = FindFirstDevice(DeviceSearchByGuid, (LPVOID)&guidBus, &di);
CBREx(hFind != INVALID_HANDLE_VALUE, HRESULT_FROM_WIN32(GetLastError()));
Trace(L"LegacyName=%s, DeviceKey=%s, DeviceName=%s, BusName=%s",
di.szLegacyName, di.szDeviceKey, di.szDeviceName, di.szBusName);
VBR(FindClose(hFind));
*phUfn = CreateFile(di.szBusName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
CBREx(*phUfn != INVALID_HANDLE_VALUE, HRESULT_FROM_WIN32(GetLastError()));
Error:
EXITTRACE(hr);
return hr;
}
//
// Load the specified USB driver ("Serial_Class" or "RNDIS")
//
HRESULT LoadFnDriver(LPCTSTR pszNewDriver)
{
ENTERTRACE();
HRESULT hr = E_FAIL;
HANDLE hUfn = INVALID_HANDLE_VALUE;
UFN_CLIENT_NAME ucn = { 0 };
// Get the controller handle
hr = GetUfnController(&hUfn);
CHR(hr);
// Change to the new client driver(function driver)
hr = StringCchCopy(ucn.szName, ARRAYSIZE(ucn.szName), pszNewDriver);
CHR(hr);
BOOL fRes = DeviceIoControl(hUfn, IOCTL_UFN_CHANGE_CURRENT_CLIENT, &ucn, sizeof(ucn), NULL, 0, NULL, NULL);
CBREx(fRes, HRESULT_FROM_WIN32(GetLastError()));
Error:
if (INVALID_HANDLE_VALUE != hUfn)
{
CloseHandle(hUfn);
}
EXITTRACE(hr);
return hr;
}
//
// Flips the USB driver:
// - if the current driver is USB serial, switch to USB RNDIS
// - if the current driver is USB RNDIS, switch to USB serial
//
HRESULT FlipUSBDriver()
{
ENTERTRACE();
HRESULT hr = S_OK;
TCHAR szDriverName[MAX_PATH];
LPCTSTR szNewDriverName = NULL;
BOOL fRndisToSerial = FALSE;
//
// Get current driver from the registry
//
hr = RegistryGetString(HKEY_LOCAL_MACHINE, c_szDriverRegKey, c_szFunctionDriver, szDriverName, ARRAYSIZE(szDriverName));
CHR(hr);
CBR(szDriverName[0] != 0);
Trace(L"Driver Found %s", szDriverName);
if (_tcscmp(szDriverName, c_szRndisFnName) == 0)
{
szNewDriverName = c_szUsbSerialFnName;
fRndisToSerial = TRUE;
MessageBox(NULL, L"Set USB serial!", L"WARNING", MB_OK);
}
else if (_tcscmp(szDriverName, c_szUsbSerialFnName) == 0)
{
szNewDriverName = c_szMassStorageFnName;
fRndisToSerial = FALSE;
MessageBox(NULL, L"Set MassStorage!", L"WARNING", MB_OK);
}
else if (_tcscmp(szDriverName, c_szMassStorageFnName) == 0)
{
szNewDriverName = c_szRndisFnName;
fRndisToSerial = FALSE;
MessageBox(NULL, L"Set Rndis!", L"WARNING", MB_OK);
}
else
{
CBR(FALSE);
MessageBox(NULL, L"Set Error!", L"WARNING", MB_OK);
}
//
// Set a serial driver in the registry
//
hr = RegistrySetString(HKEY_LOCAL_MACHINE, c_szDriverRegKey, c_szFunctionDriver, szNewDriverName);
CHR(hr);
#if 0
//ICS
MessageBox(NULL, L"SYSTEM WILL RESET!", L"WARNING", MB_OK);
SetSystemPowerState(NULL, POWER_STATE_RESET, POWER_FORCE);
return hr;
#endif
//
// Load the driver
//
hr = LoadFnDriver(szNewDriverName);
CHR(hr);
if (fRndisToSerial)
{
//
// Create RAS book
//
HRESULT hr2 = CreateDefaultConnectoids();
if (SUCCEEDED(hr2))
{
//
// Set the default ActiveSync connection to UsbSerial
//
hr = RegistrySetString(HKEY_CURRENT_USER, L"ControlPanel\\Comm", L"Cnct", c_szUsbRasName);
CHR(hr);
}
//
// Suppress CreateDefaultConnectoids errors, corresponding RAS connection may already exist.
// If not user will need to switch back to RNDIS
//
}
VBR(RegFlushKey(HKEY_LOCAL_MACHINE) == ERROR_SUCCESS);
VBR(RegFlushKey(HKEY_CURRENT_USER) == ERROR_SUCCESS);
Trace(L"Switched from %s to %s", szDriverName, szNewDriverName);
const DWORD dwResId = fRndisToSerial ? IDS_RNDIS2SERIAL_CONFIRMATION : IDS_SERIAL2RNDIS_CONFIRMATION;
LPCTSTR szConfirmationMessage = (LPCTSTR) LoadString(g_hInstance, dwResId, NULL, 0);
LPCTSTR szAppTitle = (LPCTSTR) LoadString(g_hInstance, IDS_USBSWITCH_APPTITLE, NULL, 0);
CPR(szConfirmationMessage && szAppTitle);
::MessageBox(::GetForegroundWindow(), szConfirmationMessage, szAppTitle, MB_OK | MB_ICONINFORMATION);
Error:
EXITTRACE(hr);
return hr;
}
//
// The entry point
//
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPTSTR szCmdLine, int nCmdShow)
{
ENTERTRACE();
UNREFERENCED_PARAMETER(hInstPrev);
UNREFERENCED_PARAMETER(szCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
HRESULT hr = S_FALSE;
HANDLE hMutex = CreateMutex(NULL, FALSE, c_szAppMutexName);
if (hMutex == NULL)
{
Trace(L"Failed to create mutex. Exit now.");
}
else if (GetLastError() == ERROR_ALREADY_EXISTS)
{
Trace(L"Previous instance running. Exit now.");
}
else
{
g_hInstance = hInst;
hr = FlipUSBDriver();
VHR(hr);
}
EXITTRACE(hr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -