00001
00010 #include "resetComPort.h"
00011 #include "DetectOS.h"
00012 #if defined(WINDOWS_OS)
00013 #include <windows.h>
00014 #include <setupapi.h>
00015 #include <stdio.h>
00016 #endif
00017
00018
00019 namespace
00020 {
00021 #if defined(WINDOWS_OS)
00022
00023 GUID GUID_DEVINTERFACE_COM_DEVICE = {
00024 0x4D36E978L, 0xE325, 0x11CE,
00025 {
00026 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18
00027 }
00028 };
00029
00030
00031 int deviceId(const char* com_device, HDEVINFO hdi)
00032 {
00033
00034 SP_DEVINFO_DATA sDevInfo;
00035 sDevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
00036 for (DWORD i = 0; SetupDiEnumDeviceInfo(hdi, i, &sDevInfo); ++i){
00037
00038 enum { BufferSize = 128 };
00039 char buffer[BufferSize];
00040 DWORD dwRegType;
00041 DWORD dwSize = 0;
00042
00043
00044 SetupDiGetDeviceRegistryProperty(hdi, &sDevInfo, SPDRP_FRIENDLYNAME,
00045 &dwRegType, (BYTE*)buffer,
00046 BufferSize, &dwSize);
00047 if (dwSize < 7) {
00048 continue;
00049 }
00050 char* p = strstr(&buffer[dwSize - 7], "COM");
00051 if (! p) {
00052 continue;
00053 }
00054
00055 if (! strncmp(com_device, p, strlen(com_device))) {
00056 return i;
00057 }
00058 }
00059
00060 return -1;
00061 }
00062
00063
00064 void setDeviceState(int state, int device_id, HDEVINFO hdi)
00065 {
00066 SP_DEVINFO_DATA sDevInfo;
00067 sDevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
00068 if (! SetupDiEnumDeviceInfo(hdi, device_id, &sDevInfo)) {
00069 return;
00070 }
00071
00072 SP_PROPCHANGE_PARAMS sPropChange;
00073 sPropChange.ClassInstallHeader.cbSize =
00074 sizeof(sPropChange.ClassInstallHeader);
00075
00076 sPropChange.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
00077 sPropChange.Scope = DICS_FLAG_GLOBAL;
00078 sPropChange.StateChange = state;
00079 if (! SetupDiSetClassInstallParams(hdi, &sDevInfo,
00080 &sPropChange.ClassInstallHeader,
00081 sizeof(sPropChange))) {
00082 return;
00083 }
00084 if (! SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hdi, &sDevInfo)) {
00085 return;
00086 }
00087
00088 sPropChange.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
00089 sPropChange.Scope = DICS_FLAG_CONFIGSPECIFIC;
00090 sPropChange.StateChange = state;
00091 if (! SetupDiSetClassInstallParams(hdi, &sDevInfo,
00092 &sPropChange.ClassInstallHeader,
00093 sizeof(sPropChange))) {
00094 return;
00095 }
00096 if (! SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hdi, &sDevInfo)) {
00097 return;
00098 }
00099
00100 return;
00101 }
00102
00103
00104 void disableDevice(int device_id, HDEVINFO hdi)
00105 {
00106 setDeviceState(DICS_DISABLE, device_id, hdi);
00107 }
00108
00109
00110 void enableDevice(int device_id, HDEVINFO hdi)
00111 {
00112 setDeviceState(DICS_ENABLE, device_id, hdi);
00113 }
00114 #endif
00115 }
00116
00117
00118 bool qrk::resetComPort(const char* com_device)
00119 {
00120 #if defined(WINDOWS_OS)
00121 HDEVINFO hdi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COM_DEVICE, 0, 0,
00122 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
00123 if (hdi == INVALID_HANDLE_VALUE) {
00124 return false;
00125 }
00126
00127
00128 int id = deviceId(com_device, hdi);
00129 if (id >= 0) {
00130 disableDevice(id, hdi);
00131 enableDevice(id, hdi);
00132 }
00133
00134 SetupDiDestroyDeviceInfoList(hdi);
00135
00136 return true;
00137 #else
00138
00139 static_cast<void>(com_device);
00140
00141 return false;
00142 #endif
00143 }