00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00021 #include <windows.h>
00022 #include <stdio.h>
00023
00024 #include "instcbm.h"
00025
00026 #include <setupapi.h>
00027 #include <cfgmgr32.h>
00028
00029 #include <initguid.h>
00030 #include <ntddpar.h>
00031
00033 #define DBG_USERMODE
00034
00036 #define DBG_PROGNAME "INSTCBM.EXE"
00037
00038 #include "debug.h"
00039
00040
00043 static void
00044 output_error(void)
00045 {
00046 DWORD error = GetLastError();
00047
00048 if (error)
00049 {
00050 DBG_ERROR((DBG_PREFIX "error: (0x%x) '%s'", error, FormatErrorMessage(error)));
00051 printf("error: (0x%x) '%s'\n", error, FormatErrorMessage(error));
00052 }
00053 }
00054
00059 typedef CMAPI CONFIGRET (*P_CM_Get_Device_ID_ExA)(
00060 IN DEVINST dnDevInst, OUT PTCHAR Buffer, IN ULONG BufferLen,
00061 IN ULONG ulFlags, IN HMACHINE hMachine);
00062
00067 typedef WINSETUPAPI BOOL (*P_SetupDiGetDeviceInfoListDetailA)(
00068 IN HDEVINFO DeviceInfoSet, OUT PSP_DEVINFO_LIST_DETAIL_DATA DeviceInfoSetDetailData);
00069
00073 typedef
00074 struct {
00075
00077 HMODULE HandleSetupApiDll;
00078
00080 P_CM_Get_Device_ID_ExA CM_Get_Device_ID_ExA_p;
00081
00083 P_SetupDiGetDeviceInfoListDetailA SetupDiGetDeviceInfoListDetailA_p;
00084
00085 } SETUPAPI, *PSETUPAPI;
00087 static VOID
00088 FreeDynamicalAddresses(PSETUPAPI SetupApi)
00089 {
00090 FUNC_ENTER();
00091
00092 DBG_ASSERT(SetupApi->HandleSetupApiDll != NULL);
00093
00094 FreeLibrary(SetupApi->HandleSetupApiDll);
00095
00096 DBGDO(memset(SetupApi, 0, sizeof(*SetupApi));)
00097
00098 FUNC_LEAVE();
00099 }
00100
00102 #define GET_PROC_ADDRESS(_xxx) \
00103 if (SetupApi && SetupApi->HandleSetupApiDll) \
00104 { \
00105 SetupApi->_xxx##_p = (P_##_xxx) GetProcAddress(SetupApi->HandleSetupApiDll, #_xxx); \
00106 \
00107 DBG_SUCCESS((DBG_PREFIX "p_CM_Get_Device_ID_Ex = %p", SetupApi->_xxx##_p)); \
00108 \
00109 if (SetupApi->_xxx##_p == NULL) \
00110 { \
00111 DBG_WARN((DBG_PREFIX "GetProcAddress(\"" #_xxx "\") FAILED!")); \
00112 FreeDynamicalAddresses(SetupApi); \
00113 } \
00114 }
00115
00116 static BOOLEAN
00117 GetDynamicalAddresses(PSETUPAPI SetupApi)
00118 {
00119 FUNC_ENTER();
00120
00121 DBG_ASSERT(SetupApi != NULL);
00122 DBG_ASSERT(SetupApi->HandleSetupApiDll == NULL);
00123 DBG_ASSERT(SetupApi->CM_Get_Device_ID_ExA_p == NULL);
00124
00125 SetupApi->HandleSetupApiDll = LoadLibrary("SETUPAPI.DLL");
00126
00127 DBG_SUCCESS((DBG_PREFIX "SetupApi->HandleSetupApiDll = %p",
00128 SetupApi->HandleSetupApiDll));
00129
00130 GET_PROC_ADDRESS(CM_Get_Device_ID_ExA);
00131 GET_PROC_ADDRESS(SetupDiGetDeviceInfoListDetailA);
00132
00133 FUNC_LEAVE_BOOLEAN(SetupApi->HandleSetupApiDll != NULL ? TRUE : FALSE);
00134 }
00135
00141 VOID
00142 CbmParportRestart(VOID)
00143 {
00144 HDEVINFO hdevInfo;
00145 SETUPAPI setupApi;
00146
00147 FUNC_ENTER();
00148
00149 DBGDO(memset(&setupApi, 0, sizeof(setupApi));)
00150
00151 if (GetDynamicalAddresses(&setupApi))
00152 {
00153 DBG_ASSERT(setupApi.HandleSetupApiDll);
00154 DBG_ASSERT(setupApi.CM_Get_Device_ID_ExA_p);
00155 DBG_ASSERT(setupApi.SetupDiGetDeviceInfoListDetailA_p);
00156
00157
00158
00159 hdevInfo = SetupDiGetClassDevs(&GUID_PARALLEL_DEVICE, NULL, NULL,
00160 DIGCF_DEVICEINTERFACE | DIGCF_PRESENT | DIGCF_PROFILE);
00161
00162 if (hdevInfo != INVALID_HANDLE_VALUE)
00163 {
00164 SP_DEVINFO_DATA sdd;
00165 unsigned i;
00166
00167
00168 for (i=0; ; i++)
00169 {
00170 char deviceId[MAX_DEVICE_ID_LEN];
00171
00172 SP_DEVINFO_LIST_DETAIL_DATA sdld;
00173
00174 sdld.cbSize = sizeof(sdld);
00175
00176 if (!setupApi.SetupDiGetDeviceInfoListDetailA_p(hdevInfo, &sdld))
00177 {
00178 DBG_ERROR((DBG_PREFIX "SetupDiGetDeviceInfoListDetail FAILED!"));
00179 printf("SetupDiGetDeviceInfoListDetail FAILED!\n");
00180 }
00181
00182
00183 sdd.cbSize = sizeof(sdd);
00184
00185 if (SetupDiEnumDeviceInfo(hdevInfo, i, &sdd))
00186 {
00187 SP_DEVINSTALL_PARAMS devParams;
00188 SP_PROPCHANGE_PARAMS spp;
00189 HMACHINE machineHandle = { 0 };
00190
00191 if (setupApi.CM_Get_Device_ID_ExA_p(sdd.DevInst, deviceId, MAX_DEVICE_ID_LEN,
00192 0, machineHandle) != CR_SUCCESS)
00193 {
00194 deviceId[0] = 0;
00195 }
00196 DBG_SUCCESS((DBG_PREFIX "No. %u: Returned deviceId = '%s'", i, deviceId));
00197
00198 spp.ClassInstallHeader.cbSize = sizeof(spp.ClassInstallHeader);
00199 spp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
00200 spp.StateChange = DICS_PROPCHANGE;
00201 spp.Scope = DICS_FLAG_GLOBAL;
00202 spp.HwProfile = 0;
00203
00204 if (SetupDiSetClassInstallParams(hdevInfo, &sdd,
00205 (PSP_CLASSINSTALL_HEADER) &spp, sizeof(spp)))
00206 {
00207 DBG_SUCCESS((DBG_PREFIX "SET CLASS INSTALL PARAMS WAS SUCCESSFULL!"));
00208 }
00209 else
00210 {
00211 DBG_ERROR((DBG_PREFIX "SET CLASS INSTALL PARAMS NOT SUCCESSFULL"));
00212 printf("SET CLASS INSTALL PARAMS NOT SUCCESSFULL!\n");
00213 output_error();
00214 }
00215
00216 if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hdevInfo, &sdd))
00217 {
00218 DBG_SUCCESS((DBG_PREFIX "CALL CLASS INSTALLER WAS SUCCESSFULL!"));
00219 }
00220 else
00221 {
00222 DBG_ERROR((DBG_PREFIX "CALL CLASS INSTALLER NOT SUCCESSFULL"));
00223 printf("CALL CLASS INSTALLER NOT SUCCESSFULL!\n");
00224 output_error();
00225 }
00226
00227 if (SetupDiGetDeviceInstallParams(hdevInfo, &sdd, &devParams))
00228 {
00229 if (devParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT))
00230 {
00231 DBG_ERROR((DBG_PREFIX "NEED REBOOT TO TAKE EFFECT!"));
00232 printf("NEED REBOOT TO TAKE EFFECT!\n");
00233 }
00234 }
00235 }
00236 else
00237 {
00238 if (GetLastError() == ERROR_NO_MORE_ITEMS)
00239 {
00240 break;
00241 }
00242 }
00243 }
00244 }
00245
00246 SetupDiDestroyDeviceInfoList(hdevInfo);
00247
00248 FreeDynamicalAddresses(&setupApi);
00249 }
00250 else
00251 {
00252 DBG_ERROR((DBG_PREFIX "SetupDiGetClassDevs FAILED!"));
00253 printf("SetupDiGetClassDevs FAILED!");
00254 output_error();
00255 }
00256
00257 FUNC_LEAVE();
00258 }