Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
8.5 KiB

  1. /** FILE: cyzdel.c *******************************************************
  2. *
  3. * This module is used by cyzcoins.dll and zinfdelete.exe.
  4. * Please re-generate both files when cyzdel.c is changed.
  5. *
  6. * Copyright (C) 2000 Cyclades Corporation
  7. *
  8. *************************************************************************/
  9. //==========================================================================
  10. // Include files
  11. //==========================================================================
  12. // C Runtime
  13. #include <stddef.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. //#include <stdio.h> Used with .exe
  17. // Device Class GUID
  18. #include <initguid.h>
  19. #include <devguid.h>
  20. // Application specific
  21. #include <windows.h>
  22. #include <tchar.h> // Make all functions UNICODE safe.
  23. #include <cfgmgr32.h>
  24. #include <setupapi.h> // for SetupDiXxx functions.
  25. #include <regstr.h>
  26. #include "cyzdel.h"
  27. //#include "zinfdelete.h" Used with .exe
  28. //==========================================================================
  29. // Macros
  30. //==========================================================================
  31. #define CharSizeOf(x) (sizeof(x) / sizeof(*x))
  32. #define ByteCountOf(x) ((x) * sizeof(TCHAR))
  33. #if DBG
  34. #define DbgOut(Text) OutputDebugString(Text)
  35. #else
  36. #define DbgOut(Text)
  37. #endif
  38. //==========================================================================
  39. // Globals
  40. //==========================================================================
  41. TCHAR z_szCycladzEnumerator[] = TEXT("Cyclades-Z");
  42. TCHAR z_szParentIdPrefix[] = TEXT("ParentIdPrefix");
  43. //==========================================================================
  44. // Local Function Prototypes
  45. //==========================================================================
  46. BOOL
  47. IsItCycladz(
  48. PTCHAR ptrChar
  49. );
  50. DWORD
  51. RemoveMyChildren(
  52. PTCHAR ParentIdPrefix
  53. );
  54. //==========================================================================
  55. // Functions
  56. //==========================================================================
  57. void
  58. DeleteNonPresentDevices(
  59. )
  60. {
  61. HDEVINFO MultiportInfoSet, PresentInfoSet;
  62. SP_DEVINFO_DATA MultiportInfoData, PresentInfoData;
  63. DWORD i,j;
  64. DWORD bufType,bufSize;
  65. DWORD present;
  66. TCHAR bufChar[256];
  67. MultiportInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_MULTIPORTSERIAL,
  68. 0,
  69. 0,
  70. 0 ); // All devices, even non present
  71. if (MultiportInfoSet == INVALID_HANDLE_VALUE) {
  72. return;
  73. }
  74. MultiportInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  75. for (i=0;SetupDiEnumDeviceInfo(MultiportInfoSet,i,&MultiportInfoData);i++){
  76. if (SetupDiGetDeviceRegistryProperty(MultiportInfoSet,
  77. &MultiportInfoData,
  78. SPDRP_HARDWAREID, //SPDRP_SERVICE,
  79. &bufType,
  80. (PBYTE) bufChar,
  81. sizeof(bufChar),
  82. NULL)) {
  83. if (bufType != REG_MULTI_SZ) {
  84. continue;
  85. }
  86. if (!IsItCycladz(bufChar)) {
  87. continue;
  88. }
  89. // Verify if this cyclad-z is present.
  90. PresentInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_MULTIPORTSERIAL,
  91. 0,
  92. 0,
  93. DIGCF_PRESENT );
  94. if (PresentInfoSet == INVALID_HANDLE_VALUE) {
  95. continue;
  96. }
  97. present = FALSE;
  98. PresentInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  99. for (j=0;SetupDiEnumDeviceInfo(PresentInfoSet,j,&PresentInfoData);j++) {
  100. if (MultiportInfoData.DevInst == PresentInfoData.DevInst) {
  101. present = TRUE;
  102. break;
  103. }
  104. }
  105. if (GetLastError() == ERROR_NO_MORE_ITEMS) {
  106. if (!present) {
  107. //#if DBG
  108. //TCHAR myDevInstId[200];
  109. //DWORD err;
  110. //err = CM_Get_Device_ID(MultiportInfoData.DevInst,myDevInstId,
  111. // sizeof(myDevInstId),0);
  112. //if (err==CR_SUCCESS) {
  113. // TCHAR buf[500];
  114. // wsprintf(buf, TEXT("Delete %s\n"), myDevInstId);
  115. // DbgOut(buf);
  116. //}
  117. //#endif
  118. GetParentIdAndRemoveChildren(&MultiportInfoData);
  119. SetupDiCallClassInstaller(DIF_REMOVE,MultiportInfoSet,&MultiportInfoData);
  120. }
  121. }
  122. SetupDiDestroyDeviceInfoList(PresentInfoSet);
  123. }
  124. }
  125. SetupDiDestroyDeviceInfoList(MultiportInfoSet);
  126. }
  127. BOOL
  128. IsItCycladz(
  129. PTCHAR ptrChar
  130. )
  131. {
  132. while (*ptrChar) {
  133. //_tprintf("%s\n", ptrChar);
  134. if (_tcsnicmp(ptrChar,
  135. TEXT("PCI\\VEN_120E&DEV_020"),
  136. _tcslen(TEXT("PCI\\VEN_120E&DEV_020")))
  137. == 0) {
  138. return TRUE;
  139. }
  140. ptrChar = ptrChar + _tcslen(ptrChar) + 1;
  141. }
  142. return FALSE;
  143. }
  144. DWORD
  145. GetParentIdAndRemoveChildren(
  146. IN PSP_DEVINFO_DATA DeviceInfoData
  147. )
  148. {
  149. DWORD dwSize;
  150. TCHAR instanceId[MAX_DEVICE_ID_LEN];
  151. TCHAR parentIdPrefix[50];
  152. HKEY enumKey,instKey;
  153. BOOL gotParentIdPrefix;
  154. DWORD Status = NO_ERROR;
  155. if (CM_Get_Device_ID(DeviceInfoData->DevInst,instanceId,CharSizeOf(instanceId),0) ==
  156. CR_SUCCESS) {
  157. gotParentIdPrefix = FALSE;
  158. // Open Registry and retrieve ParentIdPrefix value
  159. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_SYSTEMENUM,0,KEY_READ,
  160. &enumKey) == ERROR_SUCCESS) {
  161. if (RegOpenKeyEx(enumKey,instanceId,0,KEY_READ,&instKey) == ERROR_SUCCESS) {
  162. dwSize = sizeof(parentIdPrefix);
  163. if (RegQueryValueEx(instKey,z_szParentIdPrefix,NULL,NULL,
  164. (PBYTE)parentIdPrefix,&dwSize) == ERROR_SUCCESS) {
  165. _tcsupr(parentIdPrefix);
  166. gotParentIdPrefix = TRUE;
  167. }
  168. RegCloseKey(instKey);
  169. }
  170. RegCloseKey(enumKey);
  171. }
  172. if (gotParentIdPrefix) {
  173. Status = RemoveMyChildren(parentIdPrefix);
  174. }
  175. }
  176. return Status;
  177. }
  178. DWORD
  179. RemoveMyChildren(
  180. PTCHAR ParentIdPrefix
  181. )
  182. {
  183. HDEVINFO DeviceInfoSet;
  184. SP_DEVINFO_DATA DeviceInfoData;
  185. DWORD i,err;
  186. TCHAR portId[MAX_DEVICE_ID_LEN];
  187. PTCHAR ptrParent;
  188. DeviceInfoSet = SetupDiGetClassDevs( &GUID_DEVCLASS_PORTS,z_szCycladzEnumerator,0,0 );
  189. if (DeviceInfoSet == INVALID_HANDLE_VALUE)
  190. {
  191. return GetLastError();
  192. }
  193. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  194. for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
  195. {
  196. if (CM_Get_Device_ID(DeviceInfoData.DevInst,portId,CharSizeOf(portId),0)
  197. == CR_SUCCESS) {
  198. // BUG? For ParentIdPrefix "3&2b41c2e&1f" (12 characters), _tcscspn
  199. // always returns 0!! Using _tcsstr instead.
  200. //position = _tcscspn(portId,ParentIdPrefix);
  201. ptrParent = _tcsstr(portId,ParentIdPrefix);
  202. if (ptrParent) {
  203. if (_tcsnicmp (ptrParent,ParentIdPrefix,_tcslen(ParentIdPrefix))
  204. == 0){
  205. //
  206. // Worker function to remove device.
  207. //
  208. //#if DBG
  209. //{
  210. // TCHAR buf[500];
  211. // wsprintf(buf, TEXT("Delete %s\n"), portId);
  212. // DbgOut(buf);
  213. //}
  214. //#endif
  215. SetupDiCallClassInstaller(DIF_REMOVE,DeviceInfoSet,&DeviceInfoData);
  216. }
  217. }
  218. }
  219. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  220. }
  221. SetupDiDestroyDeviceInfoList(DeviceInfoSet);
  222. return NO_ERROR;
  223. }