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.

412 lines
12 KiB

  1. /** FILE: cyycoins.c ********** Module Header ********************************
  2. *
  3. * Cyclom-Y device co-installer.
  4. *
  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. // Device Class GUID
  17. #include <initguid.h>
  18. #include <devguid.h>
  19. // Application specific
  20. #include "cyyports.h"
  21. #include <msports.h>
  22. #include "cyydel.h"
  23. //==========================================================================
  24. // Globals
  25. //==========================================================================
  26. HANDLE g_hInst = NULL;
  27. TCHAR g_szErrMem[ 200 ]; // Low memory message
  28. TCHAR g_szPortsApplet[ 30 ]; // "Ports Control Panel Applet" title
  29. TCHAR g_szNull[] = TEXT(""); // Null string
  30. TCHAR m_szColon[] = TEXT( ":" );
  31. TCHAR m_szPorts[] = TEXT( "Ports" );
  32. TCHAR m_szCOM[] = TEXT( "COM" );
  33. //
  34. // NT Registry keys to find COM port to Serial Device mapping
  35. //
  36. TCHAR m_szRegSerialMap[] = TEXT( "Hardware\\DeviceMap\\SerialComm" );
  37. //
  38. // Registry Serial Port Advanced I/O settings key and valuenames
  39. //
  40. TCHAR m_szPortName[] = REGSTR_VAL_PORTNAME;
  41. TCHAR m_szDefParams[] = TEXT( "9600,n,8,1" );
  42. //==========================================================================
  43. // Local Function Prototypes
  44. //==========================================================================
  45. LPTSTR GetDIFString(IN DI_FUNCTION Func);
  46. DWORD
  47. CreateFriendlyName(
  48. IN HDEVINFO DeviceInfoSet,
  49. IN PSP_DEVINFO_DATA DeviceInfoData
  50. );
  51. //==========================================================================
  52. // Dll Entry Point
  53. //==========================================================================
  54. BOOL APIENTRY LibMain( HANDLE hDll, DWORD dwReason, LPVOID lpReserved )
  55. {
  56. //#if DBG
  57. // OutputDebugString(TEXT("cyycoins LibMain entry\n"));
  58. //#endif
  59. switch( dwReason )
  60. {
  61. case DLL_PROCESS_ATTACH:
  62. //#if DBG
  63. // OutputDebugString(TEXT("cyycoins DLL_PROCESS_ATTACH\n"));
  64. //#endif
  65. g_hInst = hDll;
  66. DisableThreadLibraryCalls(hDll);
  67. InitStrings();
  68. break;
  69. case DLL_PROCESS_DETACH:
  70. //#if DBG
  71. // OutputDebugString(TEXT("cyycoins DLL_PROCESS_DETACH\n"));
  72. //#endif
  73. break;
  74. default:
  75. //#if DBG
  76. // OutputDebugString(TEXT("cyycoins default\n"));
  77. //#endif
  78. break;
  79. }
  80. //#if DBG
  81. // OutputDebugString(TEXT("cyycoins LibMain exit\n"));
  82. //#endif
  83. return TRUE;
  84. }
  85. void InitStrings(void)
  86. {
  87. DWORD dwClass, dwShare;
  88. TCHAR szClass[ 40 ];
  89. LoadString(g_hInst,
  90. INITS,
  91. g_szErrMem,
  92. CharSizeOf(g_szErrMem));
  93. LoadString(g_hInst,
  94. IDS_CYCLOMY,
  95. g_szPortsApplet,
  96. CharSizeOf(g_szPortsApplet));
  97. }
  98. //==========================================================================
  99. // Functions
  100. //==========================================================================
  101. HRESULT
  102. CyclomyCoInstaller(
  103. IN DI_FUNCTION InstallFunction,
  104. IN HDEVINFO DeviceInfoSet,
  105. IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
  106. IN OUT PCOINSTALLER_CONTEXT_DATA Context
  107. )
  108. /*++
  109. Routine Description:
  110. This routine is a Co-Installer for the Cyclom-Y device.
  111. Arguments:
  112. InstallFunction - Specifies the device installer function code indicating
  113. the action being performed.
  114. DeviceInfoSet - Supplies a handle to the device information set being
  115. acted upon by this install action.
  116. DeviceInfoData - Optionally, supplies the address of a device information
  117. element being acted upon by this install action.
  118. Context - Points to a coinstaller-specific context structure for this
  119. installation request.
  120. Return Value:
  121. If this function successfully completed the requested action, the return
  122. value is NO_ERROR.
  123. If an error occurred while attempting to perform the requested action, a
  124. Win32 error code is returned.
  125. --*/
  126. {
  127. DWORD Status = NO_ERROR;
  128. // #if DBG
  129. // {
  130. // TCHAR buf[500];
  131. // wsprintf(buf, TEXT("CyclomyCoInstaller:InstallFunction(%s) PostProcessing:%d\n"), GetDIFString(InstallFunction), Context->PostProcessing);
  132. // DbgOut(buf);
  133. // }
  134. // #endif
  135. switch(InstallFunction) {
  136. case DIF_INSTALLDEVICE :
  137. //
  138. // We should not copy any INF files until the install has completed
  139. // like the primary INF, all secondary INF's must exist on each disk
  140. // of a multi-disk install.
  141. //
  142. if(!Context->PostProcessing){
  143. DeleteNonPresentDevices();
  144. Status = ERROR_DI_POSTPROCESSING_REQUIRED;
  145. } else {
  146. // post processing
  147. //
  148. // if driver installation failed, we're not interested
  149. // in processing CopyINF entries.
  150. //
  151. if (Context->InstallResult != NO_ERROR) {
  152. DbgOut(TEXT("DIF_INSTALLDEVICE PostProcessing on failure"));
  153. Status = Context->InstallResult;
  154. break;
  155. }
  156. CreateFriendlyName(DeviceInfoSet,DeviceInfoData);
  157. }
  158. break;
  159. case DIF_REMOVE:
  160. GetParentIdAndRemoveChildren(DeviceInfoData);
  161. break;
  162. default :
  163. break;
  164. }
  165. return Status;
  166. }
  167. LPTSTR GetDIFString(IN DI_FUNCTION Func)
  168. /*++
  169. Routine Description:
  170. Given a DI_FUNCTION value, returns a text representation.
  171. Arguments:
  172. Func - DI_FUNCTON value
  173. Return Value:
  174. Text string if value is known. Hex representation if not.
  175. --*/
  176. {
  177. static TCHAR buf[32];
  178. #define MakeCase(d) case d: return TEXT(#d)
  179. switch (Func)
  180. {
  181. MakeCase(DIF_SELECTDEVICE);
  182. MakeCase(DIF_INSTALLDEVICE);
  183. MakeCase(DIF_ASSIGNRESOURCES);
  184. MakeCase(DIF_PROPERTIES);
  185. MakeCase(DIF_REMOVE);
  186. MakeCase(DIF_FIRSTTIMESETUP);
  187. MakeCase(DIF_FOUNDDEVICE);
  188. MakeCase(DIF_SELECTCLASSDRIVERS);
  189. MakeCase(DIF_VALIDATECLASSDRIVERS);
  190. MakeCase(DIF_INSTALLCLASSDRIVERS);
  191. MakeCase(DIF_CALCDISKSPACE);
  192. MakeCase(DIF_DESTROYPRIVATEDATA);
  193. MakeCase(DIF_VALIDATEDRIVER);
  194. MakeCase(DIF_MOVEDEVICE);
  195. MakeCase(DIF_DETECT);
  196. MakeCase(DIF_INSTALLWIZARD);
  197. MakeCase(DIF_DESTROYWIZARDDATA);
  198. MakeCase(DIF_PROPERTYCHANGE);
  199. MakeCase(DIF_ENABLECLASS);
  200. MakeCase(DIF_DETECTVERIFY);
  201. MakeCase(DIF_INSTALLDEVICEFILES);
  202. MakeCase(DIF_UNREMOVE);
  203. MakeCase(DIF_SELECTBESTCOMPATDRV);
  204. MakeCase(DIF_ALLOW_INSTALL);
  205. MakeCase(DIF_REGISTERDEVICE);
  206. MakeCase(DIF_INSTALLINTERFACES);
  207. MakeCase(DIF_DETECTCANCEL);
  208. MakeCase(DIF_REGISTER_COINSTALLERS);
  209. MakeCase(DIF_NEWDEVICEWIZARD_FINISHINSTALL);
  210. MakeCase(DIF_ADDPROPERTYPAGE_ADVANCED);
  211. MakeCase(DIF_TROUBLESHOOTER);
  212. default:
  213. wsprintf(buf, TEXT("%x"), Func);
  214. return buf;
  215. }
  216. }
  217. DWORD
  218. CreateFriendlyName(
  219. IN HDEVINFO DeviceInfoSet,
  220. IN PSP_DEVINFO_DATA DeviceInfoData
  221. )
  222. {
  223. HDEVINFO multportInfoSet;
  224. SP_DEVINFO_DATA multportInfoData;
  225. TCHAR charBuffer[MAX_PATH],
  226. friendlyName[LINE_LEN],
  227. deviceDesc[LINE_LEN],
  228. myDeviceDesc[LINE_LEN];
  229. TCHAR * pBoardNumber;
  230. #define MAX_BOARDS 10
  231. BYTE used[MAX_BOARDS];
  232. DWORD i;
  233. DWORD retStatus = NO_ERROR;
  234. DWORD tmpBoardNumber = 0;
  235. //DbgOut(TEXT("CreateFriendlyName\n"));
  236. for (i=0; i<MAX_BOARDS; i++) {
  237. used[i]=FALSE;
  238. }
  239. if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
  240. DeviceInfoData,
  241. SPDRP_DEVICEDESC,
  242. NULL,
  243. (PBYTE)myDeviceDesc,
  244. sizeof(myDeviceDesc),
  245. NULL)) {
  246. #if DBG
  247. {
  248. TCHAR buf[500];
  249. wsprintf(buf, TEXT("Device Description failed with %x\n"), GetLastError());
  250. DbgOut(buf);
  251. }
  252. #endif
  253. return retStatus;
  254. }
  255. //#if DBG
  256. //{
  257. // TCHAR buf[500];
  258. // wsprintf(buf, TEXT("myDeviceDesc %s\n"), myDeviceDesc);
  259. // DbgOut(buf);
  260. //}
  261. //#endif
  262. multportInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_MULTIPORTSERIAL,NULL,0,0);
  263. if (multportInfoSet == INVALID_HANDLE_VALUE) {
  264. // If failure, we will continue installation without creating Friendly Name.
  265. return retStatus;
  266. }
  267. multportInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  268. for (i=0; SetupDiEnumDeviceInfo(multportInfoSet,i,&multportInfoData);i++) {
  269. if (SetupDiGetDeviceRegistryProperty(multportInfoSet,
  270. &multportInfoData,
  271. SPDRP_DEVICEDESC,
  272. NULL,
  273. (PBYTE)deviceDesc,
  274. sizeof(deviceDesc),
  275. NULL)) {
  276. if ((multportInfoData.DevInst != DeviceInfoData->DevInst) &&
  277. _tcscmp (deviceDesc,myDeviceDesc) == 0){
  278. // Another board with same device description found.
  279. if (SetupDiGetDeviceRegistryProperty(multportInfoSet,
  280. &multportInfoData,
  281. SPDRP_FRIENDLYNAME,
  282. NULL,
  283. (PBYTE)friendlyName,
  284. sizeof(friendlyName),
  285. NULL)) {
  286. pBoardNumber = _tcschr(friendlyName,'#');
  287. if (pBoardNumber == NULL) {
  288. used[0] = TRUE;
  289. continue;
  290. }
  291. if ((pBoardNumber +1) == NULL) {
  292. continue;
  293. }
  294. tmpBoardNumber = MyAtoi(pBoardNumber+1);
  295. if ((tmpBoardNumber > 0) && (tmpBoardNumber < MAX_BOARDS)) {
  296. used[tmpBoardNumber] = TRUE;
  297. }
  298. }
  299. }
  300. }
  301. multportInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  302. }
  303. SetupDiDestroyDeviceInfoList(multportInfoSet);
  304. if (used[0]==TRUE) {
  305. for (i=2; i<MAX_BOARDS; i++) {
  306. if (used[i] == FALSE) {
  307. break;
  308. }
  309. }
  310. if (i<MAX_BOARDS) {
  311. wsprintf(charBuffer, TEXT("%s #%d "), myDeviceDesc, i);
  312. // Write the string friendly name string out
  313. SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
  314. DeviceInfoData,
  315. SPDRP_FRIENDLYNAME,
  316. (PBYTE)charBuffer,
  317. ByteCountOf(lstrlen(charBuffer) + 1)
  318. );
  319. }
  320. } else {
  321. wsprintf(charBuffer, TEXT("%s "), myDeviceDesc);
  322. // Write the string friendly name string out
  323. SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
  324. DeviceInfoData,
  325. SPDRP_FRIENDLYNAME,
  326. (PBYTE)charBuffer,
  327. ByteCountOf(lstrlen(charBuffer) + 1)
  328. );
  329. }
  330. return retStatus;
  331. }