+++ /dev/null
-/*\r
-\r
-InstDrv.dll - Installs or Removes Device Drivers\r
-\r
-Copyright © 2003 Jan Kiszka (Jan.Kiszka@web.de)\r
-\r
-This software is provided 'as-is', without any express or implied\r
-warranty. In no event will the authors be held liable for any damages\r
-arising from the use of this software.\r
-\r
-Permission is granted to anyone to use this software for any purpose,\r
-including commercial applications, and to alter it and redistribute\r
-it freely, subject to the following restrictions:\r
-\r
-1. The origin of this software must not be misrepresented; \r
- you must not claim that you wrote the original software.\r
- If you use this software in a product, an acknowledgment in the\r
- product documentation would be appreciated but is not required.\r
-2. Altered versions must be plainly marked as such,\r
- and must not be misrepresented as being the original software.\r
-3. This notice may not be removed or altered from any distribution.\r
-\r
-*/\r
-\r
-\r
-#include <windows.h>\r
-#include <setupapi.h>\r
-#include <newdev.h>\r
-#include "../exdll/exdll.h"\r
-\r
-\r
-char paramBuf[1024];\r
-GUID devClass;\r
-char hwIdBuf[1024];\r
-int initialized = 0;\r
-\r
-\r
-\r
-void* memset(void* dst, int val, unsigned int len)\r
-{\r
- while (len-- > 0)\r
- *((char *)dst)++ = val;\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-\r
-void* memcpy(void* dst, const void* src, unsigned int len)\r
-{\r
- while (len-- > 0)\r
- *((char *)dst)++ = *((char *)src)++;\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-\r
-int HexCharToInt(char c)\r
-{\r
- if ((c >= '0') && (c <= '9'))\r
- return c - '0';\r
- else if ((c >= 'a') && (c <= 'f'))\r
- return c - 'a' + 10;\r
- else if ((c >= 'A') && (c <= 'F'))\r
- return c - 'A' + 10;\r
- else\r
- return -1;\r
-}\r
-\r
-\r
-\r
-BOOLEAN HexStringToUInt(char* str, int width, void* valBuf)\r
-{\r
- int i, val;\r
-\r
-\r
- for (i = width - 4; i >= 0; i -= 4)\r
- {\r
- val = HexCharToInt(*str++);\r
- if (val < 0)\r
- return FALSE;\r
- *(unsigned int *)valBuf += val << i;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-\r
-BOOLEAN StringToGUID(char* guidStr, GUID* pGuid)\r
-{\r
- int i;\r
-\r
-\r
- memset(pGuid, 0, sizeof(GUID));\r
-\r
- if (*guidStr++ != '{')\r
- return FALSE;\r
-\r
- if (!HexStringToUInt(guidStr, 32, &pGuid->Data1))\r
- return FALSE;\r
- guidStr += 8;\r
-\r
- if (*guidStr++ != '-')\r
- return FALSE;\r
-\r
- if (!HexStringToUInt(guidStr, 16, &pGuid->Data2))\r
- return FALSE;\r
- guidStr += 4;\r
-\r
- if (*guidStr++ != '-')\r
- return FALSE;\r
-\r
- if (!HexStringToUInt(guidStr, 16, &pGuid->Data3))\r
- return FALSE;\r
- guidStr += 4;\r
-\r
- if (*guidStr++ != '-')\r
- return FALSE;\r
-\r
- for (i = 0; i < 2; i++)\r
- {\r
- if (!HexStringToUInt(guidStr, 8, &pGuid->Data4[i]))\r
- return FALSE;\r
- guidStr += 2;\r
- }\r
-\r
- if (*guidStr++ != '-')\r
- return FALSE;\r
-\r
- for (i = 2; i < 8; i++)\r
- {\r
- if (!HexStringToUInt(guidStr, 8, &pGuid->Data4[i]))\r
- return FALSE;\r
- guidStr += 2;\r
- }\r
-\r
- if (*guidStr++ != '}')\r
- return FALSE;\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-\r
-DWORD FindNextDevice(HDEVINFO devInfoSet, SP_DEVINFO_DATA* pDevInfoData, DWORD* pIndex)\r
-{\r
- DWORD buffersize = 0;\r
- LPTSTR buffer = NULL;\r
- DWORD dataType;\r
- DWORD result;\r
-\r
-\r
- while (1)\r
- {\r
- if (!SetupDiEnumDeviceInfo(devInfoSet, (*pIndex)++, pDevInfoData))\r
- {\r
- result = GetLastError();\r
- break;\r
- }\r
-\r
- GetDeviceRegistryProperty:\r
- if (!SetupDiGetDeviceRegistryProperty(devInfoSet, pDevInfoData, SPDRP_HARDWAREID,\r
- &dataType, (PBYTE)buffer, buffersize,\r
- &buffersize))\r
- {\r
- result = GetLastError();\r
-\r
- if (result == ERROR_INSUFFICIENT_BUFFER)\r
- {\r
- if (buffer != NULL)\r
- LocalFree(buffer);\r
-\r
- buffer = (LPTSTR)LocalAlloc(LPTR, buffersize);\r
-\r
- if (buffer == NULL)\r
- break;\r
-\r
- goto GetDeviceRegistryProperty;\r
- }\r
- else if (result == ERROR_INVALID_DATA)\r
- continue; // ignore invalid entries\r
- else\r
- break; // break on other errors\r
- }\r
-\r
- if (lstrcmpi(buffer, hwIdBuf) == 0)\r
- {\r
- result = 0;\r
- break;\r
- }\r
- }\r
-\r
- if (buffer != NULL)\r
- LocalFree(buffer);\r
-\r
- return result;\r
-}\r
-\r
-\r
-\r
-DWORD FindFirstDevice(HWND hwndParent, const GUID* pDevClass, const LPTSTR hwId,\r
- HDEVINFO* pDevInfoSet, SP_DEVINFO_DATA* pDevInfoData,\r
- DWORD *pIndex, DWORD flags)\r
-{\r
- DWORD result;\r
-\r
-\r
- *pDevInfoSet = SetupDiGetClassDevs((GUID*)pDevClass, NULL, hwndParent, flags);\r
- if (*pDevInfoSet == INVALID_HANDLE_VALUE)\r
- return GetLastError();\r
-\r
- pDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);\r
- *pIndex = 0;\r
-\r
- result = FindNextDevice(*pDevInfoSet, pDevInfoData, pIndex);\r
-\r
- if (result != 0)\r
- SetupDiDestroyDeviceInfoList(*pDevInfoSet);\r
-\r
- return result;\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::InitDriverSetup devClass drvHWID\r
- *\r
- * devClass - GUID of the driver's device setup class\r
- * drvHWID - Hardware ID of the supported device\r
- *\r
- * Return:\r
- * result - error message, empty on success\r
- */\r
-void __declspec(dllexport) InitDriverSetup(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- EXDLL_INIT();\r
-\r
- /* convert class GUID */\r
- popstring(paramBuf);\r
-\r
- if (!StringToGUID(paramBuf, &devClass))\r
- {\r
- popstring(paramBuf);\r
- pushstring("Invalid GUID!");\r
- return;\r
- }\r
-\r
- /* get hardware ID */\r
- memset(hwIdBuf, 0, sizeof(hwIdBuf));\r
- popstring(hwIdBuf);\r
-\r
- initialized = 1;\r
- pushstring("");\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::CountDevices\r
- *\r
- * Return:\r
- * result - Number of installed devices the driver supports\r
- */\r
-void __declspec(dllexport) CountDevices(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- HDEVINFO devInfoSet;\r
- SP_DEVINFO_DATA devInfoData;\r
- int count = 0;\r
- char countBuf[16];\r
- DWORD index;\r
- DWORD result;\r
-\r
-\r
- EXDLL_INIT();\r
-\r
- if (!initialized)\r
- {\r
- pushstring("Fatal error!");\r
- return;\r
- }\r
-\r
- result = FindFirstDevice(hwndParent, &devClass, hwIdBuf, &devInfoSet, &devInfoData,\r
- &index, DIGCF_PRESENT);\r
- if (result != 0)\r
- {\r
- pushstring("0");\r
- return;\r
- }\r
-\r
- do\r
- {\r
- count++;\r
- } while (FindNextDevice(devInfoSet, &devInfoData, &index) == 0);\r
-\r
- SetupDiDestroyDeviceInfoList(devInfoSet);\r
-\r
- wsprintf(countBuf, "%d", count);\r
- pushstring(countBuf);\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::CreateDevice\r
- *\r
- * Return:\r
- * result - Windows error code\r
- */\r
-void __declspec(dllexport) CreateDevice(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- HDEVINFO devInfoSet;\r
- SP_DEVINFO_DATA devInfoData;\r
- DWORD result = 0;\r
- char resultBuf[16];\r
-\r
-\r
- EXDLL_INIT();\r
-\r
- if (!initialized)\r
- {\r
- pushstring("Fatal error!");\r
- return;\r
- }\r
-\r
- devInfoSet = SetupDiCreateDeviceInfoList(&devClass, hwndParent);\r
- if (devInfoSet == INVALID_HANDLE_VALUE)\r
- {\r
- wsprintf(resultBuf, "%08X", GetLastError());\r
- pushstring(resultBuf);\r
- return;\r
- }\r
-\r
- devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);\r
- if (!SetupDiCreateDeviceInfo(devInfoSet, hwIdBuf, &devClass, NULL,\r
- hwndParent, DICD_GENERATE_ID, &devInfoData))\r
- {\r
- result = GetLastError();\r
- goto InstallCleanup;\r
- }\r
-\r
- if (!SetupDiSetDeviceRegistryProperty(devInfoSet, &devInfoData, SPDRP_HARDWAREID,\r
- hwIdBuf, (lstrlen(hwIdBuf)+2)*sizeof(TCHAR))) \r
- {\r
- result = GetLastError();\r
- goto InstallCleanup;\r
- }\r
-\r
- if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, devInfoSet, &devInfoData))\r
- result = GetLastError();\r
-\r
- InstallCleanup:\r
- SetupDiDestroyDeviceInfoList(devInfoSet);\r
-\r
- wsprintf(resultBuf, "%08X", result);\r
- pushstring(resultBuf);\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::InstallDriver infPath\r
- *\r
- * Return:\r
- * result - Windows error code\r
- * reboot - non-zero if reboot is required\r
- */\r
-void __declspec(dllexport) InstallDriver(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- char resultBuf[16];\r
- BOOL reboot;\r
-\r
-\r
- EXDLL_INIT();\r
- popstring(paramBuf);\r
-\r
- if (!initialized)\r
- {\r
- pushstring("Fatal error!");\r
- return;\r
- }\r
-\r
- if (!UpdateDriverForPlugAndPlayDevices(hwndParent, hwIdBuf, paramBuf,\r
- INSTALLFLAG_FORCE, &reboot))\r
- {\r
- wsprintf(resultBuf, "%08X", GetLastError());\r
- pushstring(resultBuf);\r
- }\r
- else\r
- {\r
- wsprintf(resultBuf, "%d", reboot);\r
- pushstring(resultBuf);\r
- pushstring("00000000");\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::DeleteOemInfFiles\r
- *\r
- * Return:\r
- * result - Windows error code\r
- * oeminf - Path of the deleted devices setup file (oemXX.inf)\r
- * oempnf - Path of the deleted devices setup file (oemXX.pnf)\r
- */\r
-void __declspec(dllexport) DeleteOemInfFiles(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- HDEVINFO devInfo;\r
- SP_DEVINFO_DATA devInfoData;\r
- SP_DRVINFO_DATA drvInfoData;\r
- SP_DRVINFO_DETAIL_DATA drvInfoDetail;\r
- DWORD index;\r
- DWORD result;\r
- char resultBuf[16];\r
-\r
-\r
- if (!initialized)\r
- {\r
- pushstring("Fatal error!");\r
- return;\r
- }\r
-\r
- result = FindFirstDevice(NULL, &devClass, hwIdBuf, &devInfo, &devInfoData, &index, 0);\r
- if (result != 0)\r
- goto Cleanup1;\r
-\r
- if (!SetupDiBuildDriverInfoList(devInfo, &devInfoData, SPDIT_COMPATDRIVER))\r
- {\r
- result = GetLastError();\r
- goto Cleanup2;\r
- }\r
-\r
- drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);\r
- drvInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);\r
-\r
- if (!SetupDiEnumDriverInfo(devInfo, &devInfoData, SPDIT_COMPATDRIVER, 0, &drvInfoData))\r
- {\r
- result = GetLastError();\r
- goto Cleanup3;\r
- }\r
-\r
- if (!SetupDiGetDriverInfoDetail(devInfo, &devInfoData, &drvInfoData,\r
- &drvInfoDetail, sizeof(drvInfoDetail), NULL))\r
- {\r
- result = GetLastError();\r
-\r
- if (result != ERROR_INSUFFICIENT_BUFFER)\r
- goto Cleanup3;\r
-\r
- result = 0;\r
- }\r
-\r
- pushstring(drvInfoDetail.InfFileName);\r
- if (!DeleteFile(drvInfoDetail.InfFileName))\r
- result = GetLastError();\r
- else\r
- {\r
- index = lstrlen(drvInfoDetail.InfFileName);\r
- if (index > 3)\r
- {\r
- lstrcpy(drvInfoDetail.InfFileName+index-3, "pnf");\r
- pushstring(drvInfoDetail.InfFileName);\r
- if (!DeleteFile(drvInfoDetail.InfFileName))\r
- result = GetLastError();\r
- }\r
- }\r
-\r
- Cleanup3:\r
- SetupDiDestroyDriverInfoList(devInfo, &devInfoData, SPDIT_COMPATDRIVER);\r
-\r
- Cleanup2:\r
- SetupDiDestroyDeviceInfoList(devInfo);\r
-\r
- Cleanup1:\r
- wsprintf(resultBuf, "%08X", result);\r
- pushstring(resultBuf);\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::RemoveAllDevices\r
- *\r
- * Return:\r
- * result - Windows error code\r
- * reboot - non-zero if reboot is required\r
- */\r
-void __declspec(dllexport) RemoveAllDevices(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- HDEVINFO devInfo;\r
- SP_DEVINFO_DATA devInfoData;\r
- DWORD index;\r
- DWORD result;\r
- char resultBuf[16];\r
- BOOL reboot = FALSE;\r
- SP_DEVINSTALL_PARAMS instParams;\r
-\r
-\r
- EXDLL_INIT();\r
-\r
- if (!initialized)\r
- {\r
- pushstring("Fatal error!");\r
- return;\r
- }\r
-\r
- result = FindFirstDevice(NULL, &devClass, hwIdBuf, &devInfo, &devInfoData, &index, 0);\r
- if (result != 0)\r
- goto Cleanup1;\r
-\r
- do\r
- {\r
- if (!SetupDiCallClassInstaller(DIF_REMOVE, devInfo, &devInfoData))\r
- {\r
- result = GetLastError();\r
- break;\r
- }\r
-\r
- instParams.cbSize = sizeof(instParams);\r
- if (!reboot &&\r
- SetupDiGetDeviceInstallParams(devInfo, &devInfoData, &instParams) &&\r
- ((instParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT)) != 0))\r
- {\r
- reboot = TRUE;\r
- }\r
-\r
- result = FindNextDevice(devInfo, &devInfoData, &index);\r
- } while (result == 0);\r
-\r
- SetupDiDestroyDeviceInfoList(devInfo);\r
-\r
- Cleanup1:\r
- if ((result == 0) || (result == ERROR_NO_MORE_ITEMS))\r
- {\r
- wsprintf(resultBuf, "%d", reboot);\r
- pushstring(resultBuf);\r
- pushstring("00000000");\r
- }\r
- else\r
- {\r
- wsprintf(resultBuf, "%08X", result);\r
- pushstring(resultBuf);\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::StartSystemService serviceName\r
- *\r
- * Return:\r
- * result - Windows error code\r
- */\r
-void __declspec(dllexport) StartSystemService(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- SC_HANDLE managerHndl;\r
- SC_HANDLE svcHndl;\r
- SERVICE_STATUS svcStatus;\r
- DWORD oldCheckPoint;\r
- DWORD result;\r
- char resultBuf[16];\r
-\r
-\r
- EXDLL_INIT();\r
- popstring(paramBuf);\r
-\r
- managerHndl = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
- if (managerHndl == NULL)\r
- {\r
- result = GetLastError();\r
- goto Cleanup1;\r
- }\r
-\r
- svcHndl = OpenService(managerHndl, paramBuf, SERVICE_START | SERVICE_QUERY_STATUS);\r
- if (svcHndl == NULL)\r
- {\r
- result = GetLastError();\r
- goto Cleanup2;\r
- }\r
-\r
- if (!StartService(svcHndl, 0, NULL) || !QueryServiceStatus(svcHndl, &svcStatus))\r
- {\r
- result = GetLastError();\r
- goto Cleanup3;\r
- }\r
-\r
- while (svcStatus.dwCurrentState == SERVICE_START_PENDING)\r
- {\r
- oldCheckPoint = svcStatus.dwCheckPoint;\r
-\r
- Sleep(svcStatus.dwWaitHint);\r
-\r
- if (!QueryServiceStatus(svcHndl, &svcStatus))\r
- {\r
- result = GetLastError();\r
- break;\r
- }\r
-\r
- if (oldCheckPoint >= svcStatus.dwCheckPoint)\r
- {\r
- if ((svcStatus.dwCurrentState == SERVICE_STOPPED) &&\r
- (svcStatus.dwWin32ExitCode != 0))\r
- result = svcStatus.dwWin32ExitCode;\r
- else\r
- result = ERROR_SERVICE_REQUEST_TIMEOUT;\r
- }\r
- }\r
-\r
- if (svcStatus.dwCurrentState == SERVICE_RUNNING)\r
- result = 0;\r
-\r
- Cleanup3:\r
- CloseServiceHandle(svcHndl);\r
-\r
- Cleanup2:\r
- CloseServiceHandle(managerHndl);\r
-\r
- Cleanup1:\r
- wsprintf(resultBuf, "%08X", result);\r
- pushstring(resultBuf);\r
-}\r
-\r
-\r
-\r
-/*\r
- * InstDrv::StopSystemService serviceName\r
- *\r
- * Return:\r
- * result - Windows error code\r
- */\r
-void __declspec(dllexport) StopSystemService(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)\r
-{\r
- SC_HANDLE managerHndl;\r
- SC_HANDLE svcHndl;\r
- SERVICE_STATUS svcStatus;\r
- DWORD oldCheckPoint;\r
- DWORD result;\r
- char resultBuf[16];\r
-\r
-\r
- EXDLL_INIT();\r
- popstring(paramBuf);\r
-\r
- managerHndl = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
- if (managerHndl == NULL)\r
- {\r
- result = GetLastError();\r
- goto Cleanup1;\r
- }\r
-\r
- svcHndl = OpenService(managerHndl, paramBuf, SERVICE_STOP | SERVICE_QUERY_STATUS);\r
- if (svcHndl == NULL)\r
- {\r
- result = GetLastError();\r
- goto Cleanup2;\r
- }\r
-\r
- if (!ControlService(svcHndl, SERVICE_CONTROL_STOP, &svcStatus))\r
- {\r
- result = GetLastError();\r
- goto Cleanup3;\r
- }\r
-\r
- while (svcStatus.dwCurrentState == SERVICE_STOP_PENDING)\r
- {\r
- oldCheckPoint = svcStatus.dwCheckPoint;\r
-\r
- Sleep(svcStatus.dwWaitHint);\r
-\r
- if (!QueryServiceStatus(svcHndl, &svcStatus))\r
- {\r
- result = GetLastError();\r
- break;\r
- }\r
-\r
- if (oldCheckPoint >= svcStatus.dwCheckPoint)\r
- {\r
- result = ERROR_SERVICE_REQUEST_TIMEOUT;\r
- break;\r
- }\r
- }\r
-\r
- if (svcStatus.dwCurrentState == SERVICE_STOPPED)\r
- result = 0;\r
-\r
- Cleanup3:\r
- CloseServiceHandle(svcHndl);\r
-\r
- Cleanup2:\r
- CloseServiceHandle(managerHndl);\r
-\r
- Cleanup1:\r
- wsprintf(resultBuf, "%08X", result);\r
- pushstring(resultBuf);\r
-}\r
-\r
-\r
-\r
-BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)\r
-{\r
- return TRUE;\r
-}\r