|
|
/*****************************************************************************
* * DIAddHw.c * * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved. * * Abstract: * * Add New Hardware * * Contents: * * AddNewHardware * *****************************************************************************/
#include "dinputpr.h"
#include "dithunk.h"
#pragma BEGIN_CONST_DATA
/*****************************************************************************
* * The sqiffle for this file. * *****************************************************************************/
#define sqfl sqflJoyCfg
#ifdef IDirectInputJoyConfig_QueryInterface
#define case95(n) case n:
#define caseNT(n) case n:
HRESULT INTERNAL hresFromDiErr_NT(DWORD et); HRESULT INTERNAL hresFromDiErr_95(int et);
/*****************************************************************************
* * These are the functions we have to steal from SYSDM... * *****************************************************************************/
LPCSTR rgpszSysdm[] = { "InstallDevice_RunDLL", /* InstallDevice_RunDLL */ };
typedef struct SYSDM { /* sysdm */ FARPROC InstallDevice_RunDLL; } SYSDM, *PSYSDM;
/*****************************************************************************
* * @doc INTERNAL * * @func int | DiDestroyDeviceInfoList | * * Thunk down to SETUPX.DiCallClassInstaller. * *****************************************************************************/
void INLINE InstallDevice_RunDLL(PSYSDM psysdm, HWND hwnd, HINSTANCE hinst, LPCSTR psz, UINT show) { TemplateThunk(psysdm->InstallDevice_RunDLL, "ssps", hwnd, hinst, psz, show); }
/*****************************************************************************
* * @doc INTERNAL * * @struct CLASSMAP | * * Structure that establishes the relationship between * <t GUIDs> for device classes and the name of the class. * * This code needs to hang around because Windows 95 * doesn't have SETUPAPI.DLL, so we need to fake it. * * @parm HWND | hwndOwner | * * Window to act as owner window for UI. * * @parm REFGUID | rguidClass | * * <t GUID> which specifies the class of the hardware device. * *****************************************************************************/
typedef struct CLASSMAP { REFGUID pguidClass; LPCSTR ptszClass; } CLASSMAP, *PCLASSMAP;
const CLASSMAP c_rgcmap[] = { { &GUID_KeyboardClass, ("keyboard"), }, { &GUID_MediaClass, ("media"), }, { &GUID_MouseClass, ("mouse"), }, { &GUID_HIDClass, ("HID"), }, };
/*****************************************************************************
* * @doc INTERNAL * * @func RESULT | AddNewHardware | * * Display the "Add new hardware" dialog. * * @parm HWND | hwndOwner | * * Window to act as owner window for UI. * * @parm REFGUID | rguidClass | * * <t GUID> which specifies the class of the hardware device. * * @comm Win9x and Win2k have completely different versions of this. * *****************************************************************************/ HRESULT EXTERNAL AddNewHardware(HWND hwnd, REFGUID rguid) #ifdef WINNT
{ HRESULT hres; HINSTANCE hInst; BOOL b; FARPROC proc; DWORD le;
EnterProcR(AddNewHardware, (_ "xG", hwnd, rguid));
hres = E_NOTIMPL;
/* Load AddNewHardware proc from newdev.dll part of AddNewHardware wizard.
*/ hInst = LoadLibrary(TEXT("newdev.dll"));
if (hInst) { proc = GetProcAddress(hInst, (LPCSTR)"InstallNewDevice");
if (proc) { le = ERROR_SUCCESS; b = (BOOL)(*proc)(hwnd, rguid, 0); // 0 means newdev decides about reboot
if (!b) { le = GetLastError(); }
hres = hresFromDiErr_NT(le); }
FreeLibrary(hInst); }
ExitOleProc(); return hres; } #else
/*
* We pull a gross hack because Device Manager is completely unmanageable. * We simply call the RunDll entry point and let it do its thing. * Note that this means we have no way of knowing what the result was. */ { SYSDM sysdm; HINSTANCE hinst; HRESULT hres; EnterProcR(AddNewHardware, (_ "xG", hwnd, rguid));
if (Thunk_GetKernelProcAddresses() && (hinst = Thunk_GetProcAddresses((PV)&sysdm, rgpszSysdm, cA(rgpszSysdm), ("SYSDM.CPL")))) { int icmap;
for (icmap = 0; icmap < cA(c_rgcmap); icmap++) { if (IsEqualGUID(rguid, c_rgcmap[icmap].pguidClass)) { goto found; } } RPF("%s: Unknown device class", s_szProc); hres = DIERR_INVALIDCLASSINSTALLER; goto done;
found:;
InstallDevice_RunDLL(&sysdm, hwnd, hinst, c_rgcmap[icmap].ptszClass, SW_NORMAL);
g_kpa.FreeLibrary16(hinst);
hres = S_FALSE;
} else { RPF("%s: Problems thunking to configuration manager", s_szProc); hres = E_FAIL; }
done:; ExitOleProc(); return hres; } #endif
/*****************************************************************************
* * @doc INTERNAL * * @func HRESULT | hresFromDiErr | * * Convert a device installer error code into an HRESULT. * *****************************************************************************/
HRESULT INTERNAL hresFromDiErr_NT(DWORD et) { HRESULT hres;
switch (et) {
case ERROR_SUCCESS: hres = S_OK; break;
/*
* Do the default action for the requested operation. */ caseNT(ERROR_DI_DO_DEFAULT); hres = S_OK; break;
/*
* No need to copy files (in install). */ caseNT(ERROR_DI_NOFILECOPY); hres = S_OK; break;
/*
* Registry entry or DLL for class installer invalid. */ caseNT(ERROR_INVALID_CLASS_INSTALLER); hres = DIERR_INVALIDCLASSINSTALLER; break;
/*
* Insufficient memory. */ caseNT(ERROR_NOT_ENOUGH_MEMORY); caseNT(ERROR_OUTOFMEMORY); hres = E_OUTOFMEMORY; break;
/*
* The user cancelled the operation. */ caseNT(ERROR_CANCELLED); caseNT(ERROR_NO_DRIVER_SELECTED); hres = DIERR_CANCELLED; break;
/*
* Various impossible things. */ caseNT(ERROR_NO_ASSOCIATED_CLASS); caseNT(ERROR_CLASS_MISMATCH); caseNT(ERROR_DUPLICATE_FOUND); caseNT(ERROR_KEY_DOES_NOT_EXIST); caseNT(ERROR_INVALID_DEVINST_NAME); caseNT(ERROR_INVALID_CLASS); caseNT(ERROR_DEVINFO_NOT_REGISTERED); caseNT(ERROR_DEVINST_ALREADY_EXISTS); caseNT(ERROR_INVALID_REG_PROPERTY); caseNT(ERROR_NO_SUCH_DEVINST); caseNT(ERROR_CANT_LOAD_CLASS_ICON); caseNT(ERROR_INVALID_HWPROFILE); caseNT(ERROR_DEVINFO_LIST_LOCKED); caseNT(ERROR_DEVINFO_DATA_LOCKED); caseNT(ERROR_NO_CLASSINSTALL_PARAMS); caseNT(ERROR_FILEQUEUE_LOCKED); caseNT(ERROR_BAD_SERVICE_INSTALLSECT); caseNT(ERROR_NO_CLASS_DRIVER_LIST); caseNT(ERROR_NO_ASSOCIATED_SERVICE); caseNT(ERROR_NO_DEFAULT_DEVICE_INTERFACE); default:; hres = E_FAIL; break;
caseNT(ERROR_DI_BAD_PATH); caseNT(ERROR_NO_INF); hres = DIERR_BADINF; break;
} return hres; }
#ifndef DI_ERROR
#define DI_ERROR (500) // Device Installer
#endif
enum _ERR_DEVICE_INSTALL { ERR_DI_INVALID_DEVICE_ID = DI_ERROR, // Incorrectly formed device IDF
ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST, // Invalid compatible device list
ERR_DI_REG_API, // Error returned by Reg API.
ERR_DI_LOW_MEM, // Insufficient memory to complete
ERR_DI_BAD_DEV_INFO, // Device Info struct invalid
ERR_DI_INVALID_CLASS_INSTALLER, // Registry entry / DLL invalid
ERR_DI_DO_DEFAULT, // Take default action
ERR_DI_USER_CANCEL, // the user cancelled the operation
ERR_DI_NOFILECOPY, // No need to copy files (in install)
ERR_DI_BAD_CLASS_INFO, // Class Info Struct invalid
ERR_DI_BAD_INF, // Bad INF file encountered
ERR_DI_BAD_MOVEDEV_PARAMS, // Bad Move Device Params struct
ERR_DI_NO_INF, // No INF found on OEM disk
ERR_DI_BAD_PROPCHANGE_PARAMS, // Bad property change param struct
ERR_DI_BAD_SELECTDEVICE_PARAMS, // Bad Select Device Parameters
ERR_DI_BAD_REMOVEDEVICE_PARAMS, // Bad Remove Device Parameters
ERR_DI_BAD_ENABLECLASS_PARAMS, // Bad Enable Class Parameters
ERR_DI_FAIL_QUERY, // Fail the Enable Class query
ERR_DI_API_ERROR, // DI API called incorrectly
ERR_DI_BAD_PATH, // An OEM path was specified incorrectly
ERR_DI_BAD_UNREMOVEDEVICE_PARAMS, // Bad Unremove Device Parameters
ERR_DI_NOUPDATE, // No Drivers Were updated
ERR_DI_NODATE, // The driver does not have a Date stamp in the INF
ERR_DI_NOVERSION, // There is not version string in the INF
ERR_DI_DONT_INSTALL, // Don't upgrade the current driver
ERR_DI_NO_DIGITAL_SIGNATURE_CATALOG, // Catalog is not digitally signed
ERR_DI_NO_DIGITAL_SIGNATURE_INF, // Inf is not digitally signed
ERR_DI_NO_DIGITAL_SIGNATURE_FILE, // A file is not digitally signed
};
HRESULT INTERNAL hresFromDiErr_95(int et) { HRESULT hres;
switch (et) { case ERROR_SUCCESS: hres = S_OK; break;
/*
* Do the default action for the requested operation. */ case95(ERR_DI_DO_DEFAULT); hres = S_OK; break;
/*
* No need to copy files (in install). */ case95(ERR_DI_NOFILECOPY); hres = S_OK; break;
/*
* No Drivers Were updated. */ // case95(ERR_DI_NOUPDATE);
// hres = S_OK; break;
/*
* Don't upgrade the current driver. */ // case95(ERR_DI_DONT_UPGRADE);
// hres = S_OK; break;
/*
* No Drivers Were updated. */ case95(ERR_DI_NOUPDATE); hres = S_OK; break;
/*
* Registry entry or DLL for class installer invalid. */ case95(ERR_DI_INVALID_CLASS_INSTALLER); hres = DIERR_INVALIDCLASSINSTALLER; break;
/*
* Insufficient memory. */ case95(ERR_DI_LOW_MEM); hres = E_OUTOFMEMORY; break;
/*
* The user cancelled the operation. */ case95(ERR_DI_USER_CANCEL); hres = DIERR_CANCELLED; break;
/*
* Various impossible things. */ case95(ERR_DI_BAD_DEV_INFO); /* Device Info struct invalid */ case95(ERR_DI_BAD_CLASS_INFO); /* Class Info Struct invalid */ case95(ERR_DI_API_ERROR); /* DI API called incorrectly */ case95(ERR_DI_BAD_PROPCHANGE_PARAMS); /* Bad property chg param struct */ case95(ERR_DI_BAD_SELECTDEVICE_PARAMS); /* Bad Select Device Parameters */ case95(ERR_DI_BAD_REMOVEDEVICE_PARAMS); /* Bad Remove Device Parameters */ case95(ERR_DI_BAD_ENABLECLASS_PARAMS); /* Bad Enable Class Parameters */ case95(ERR_DI_BAD_MOVEDEV_PARAMS); /* Bad Move Device Params struct */ case95(ERR_DI_FAIL_QUERY); /* Fail the Enable Class query */ case95(ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST); /* Invalid compatible device list*/ case95(ERR_DI_BAD_UNREMOVEDEVICE_PARAMS); /* Bad Unremove Device Parameters*/ case95(ERR_DI_INVALID_DEVICE_ID); /* Incorrectly formed device IDF */ case95(ERR_DI_REG_API); /* Error returned by Reg API. */ default:; hres = E_FAIL; break;
case95(ERR_DI_BAD_PATH); /* OEM path specified incorrectly*/ case95(ERR_DI_BAD_INF); /* Bad INF file encountered */ case95(ERR_DI_NO_INF); /* No INF found on OEM disk */ case95(ERR_DI_NOVERSION); /* No version string in the INF */ case95(ERR_DI_NODATE); /* No Date stamp in the INF */ hres = DIERR_BADINF; break;
} return hres; }
#endif /* defined(IDirectInputJoyConfigVtbl) */
|