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.

1097 lines
31 KiB

  1. /*-------------------------------------------------------------------
  2. | initvs.c - main init code for VS1000/2000 NT device driver. Contains
  3. mostly initialization code.
  4. Copyright 1996-98 Comtrol Corporation. All rights reserved.
  5. |--------------------------------------------------------------------*/
  6. #include "precomp.h"
  7. static int CatBindList(IN WCHAR *pwstr);
  8. static void GetBindingNames(void);
  9. static Nic *FindFreeNic(void);
  10. static int BindNameUsed(char *nicname);
  11. static int NicNameUsed(char *nicname);
  12. static void ScanForNewNicCards(void);
  13. static int reg_list_nt50_linkage(void);
  14. static int reg_list_nt40_linkage(void);
  15. /*----------------------------------------------------------------------
  16. CatBindList - Given the multisz Wchar string read out of the registry,
  17. convert it to normal c-string multisz list.
  18. |----------------------------------------------------------------------*/
  19. static int CatBindList(IN WCHAR *pwstr)
  20. {
  21. char *cstr;
  22. int size = 0;
  23. cstr = Driver.BindNames;
  24. MyKdPrint(D_Thread, ("CatBindList\n"))
  25. // cat on to end of existing list, so find end of list
  26. while (cstr[size] != 0)
  27. {
  28. //MyKdPrint(D_Thread, ("ExList:%s\n", &cstr[size]))
  29. while (cstr[size] != 0)
  30. ++size;
  31. ++size; // pass up string null to next string
  32. }
  33. cstr += size;
  34. MyKdPrint(D_Thread, ("CatList Size:%d\n", size))
  35. if (*pwstr == 0)
  36. {
  37. MyKdPrint(D_Thread, ("Null List!\n"))
  38. }
  39. while ((*pwstr != 0) && (size < 7700))
  40. {
  41. // first convert it past the list end and check if its already in the list
  42. WStrToCStr(cstr+4, pwstr, 200);
  43. if (!BindNameUsed(cstr+4))
  44. {
  45. WStrToCStr(cstr, pwstr, 200); // put at end of list
  46. MyKdPrint(D_Thread, ("Bind: %s\n", cstr))
  47. size = (strlen(cstr) + 1);
  48. cstr += size;
  49. *cstr = 0; // double null end of list
  50. *(cstr+1) = 0;
  51. }
  52. //----- Advance to the next string of the MULTI_SZ string
  53. while (*pwstr != 0)
  54. ++pwstr;
  55. ++pwstr;
  56. }
  57. return 0; // ok
  58. }
  59. /*----------------------------------------------------------------------
  60. GetBindingNames - Reads Binding info to find possible nic-card export
  61. names from registry. Reads the list into Driver.BindNames multisz
  62. list.
  63. |----------------------------------------------------------------------*/
  64. static void GetBindingNames(void)
  65. {
  66. if (Driver.BindNames == NULL)
  67. {
  68. Driver.BindNames = ExAllocatePool(PagedPool, 8000 * sizeof(WCHAR));
  69. if (Driver.BindNames == NULL) {
  70. Eprintf("GetBindingNames no memory");
  71. return;
  72. }
  73. }
  74. // clear list
  75. RtlZeroMemory( (PUCHAR)Driver.BindNames, sizeof(WCHAR)*2);
  76. #ifdef NT50
  77. reg_list_nt50_linkage();
  78. #else
  79. reg_list_nt40_linkage();
  80. #endif
  81. }
  82. /*----------------------------------------------------------------------
  83. FindFreeNic - Find an unused Nic structure to try and open.
  84. |----------------------------------------------------------------------*/
  85. static Nic *FindFreeNic(void)
  86. {
  87. int i;
  88. #ifdef BREAK_NIC_STUFF
  89. for (i=VS1000_MAX_NICS-1; i>=0; i--)
  90. #else
  91. for (i=0; i<VS1000_MAX_NICS; i++)
  92. #endif
  93. {
  94. if (Driver.nics[i].NICHandle == NULL)
  95. return &Driver.nics[i];
  96. }
  97. return NULL;
  98. }
  99. /*----------------------------------------------------------------------
  100. BindNameUsed - Return true if Bind Nic name already in bind list.
  101. |----------------------------------------------------------------------*/
  102. static int BindNameUsed(char *nicname)
  103. {
  104. char *szptr;
  105. szptr = Driver.BindNames; // multisz list
  106. while (*szptr != 0) // while list of binding nic-names to try
  107. {
  108. if (my_lstricmp(szptr, nicname) == 0) // a match
  109. {
  110. return 1; // its in use.
  111. }
  112. while (*szptr != 0) // to next bind string to try
  113. ++szptr;
  114. ++szptr;
  115. } // while (szptr (more bind strings to try)
  116. return 0; // its not in use.
  117. }
  118. /*----------------------------------------------------------------------
  119. NicNameUsed - Return true if Nic name is in use.
  120. |----------------------------------------------------------------------*/
  121. static int NicNameUsed(char *nicname)
  122. {
  123. int i;
  124. for (i=0; i<VS1000_MAX_NICS; i++)
  125. {
  126. if (Driver.nics[i].NicName[0] != 0)
  127. {
  128. if (my_lstricmp(Driver.nics[i].NicName, nicname) == 0) // a match
  129. {
  130. return 1; // its in use.
  131. }
  132. }
  133. }
  134. return 0; // its not in use.
  135. }
  136. /*----------------------------------------------------------------------
  137. ScanForNewNicCards - Reads Binding info to find possible nic-card export
  138. names. Scans through all nic cards and attempts to open those that
  139. have not been successfully opened already.
  140. |----------------------------------------------------------------------*/
  141. static void ScanForNewNicCards(void)
  142. {
  143. Nic *nic;
  144. char *szptr;
  145. int stat;
  146. MyKdPrint(D_Thread, ("ScanForNewNicCards\n"))
  147. GetBindingNames();
  148. szptr = Driver.BindNames; // multisz list
  149. if ((szptr == NULL) || (*szptr == 0))
  150. {
  151. MyKdPrint(D_Error, ("No Binding\n"))
  152. return; // err
  153. }
  154. while (*szptr != 0) // while list of binding nic-names to try
  155. {
  156. if (!NicNameUsed(szptr)) // if this name is not in use yet
  157. {
  158. nic = FindFreeNic();
  159. if (nic == NULL)
  160. {
  161. MyKdPrint(D_Error, ("Out of Nics\n"))
  162. break;
  163. }
  164. // try to open NIC card
  165. stat = NicOpen(nic, CToU1(szptr));
  166. if (stat == 0)
  167. {
  168. MyKdPrint(D_Thread, ("Opened nic %s\n", szptr))
  169. }
  170. else
  171. {
  172. MyKdPrint(D_Thread, ("Failed Opened nic %s\n", szptr))
  173. }
  174. }
  175. else
  176. {
  177. MyKdPrint(D_Thread, ("Nic %s already used.\n", szptr))
  178. }
  179. while (*szptr != 0) // to next bind string to try
  180. ++szptr;
  181. ++szptr;
  182. } // while (szptr (more bind strings to try)
  183. MyKdPrint(D_Thread, ("End ScanForNewNicCards\n"))
  184. }
  185. /*----------------------------------------------------------------------
  186. NicThread - Scans through all nic cards and attempts to open those that
  187. have not been successfully opened already. If all nic cards are not opened
  188. successfully timeout for 1 second and try it again. This function operates
  189. as a separate thread spawned by Driver_Entry in init.c. When all the nic
  190. cards have been successfully opened this thread will terminate itself.
  191. |----------------------------------------------------------------------*/
  192. VOID NicThread(IN PVOID Context)
  193. {
  194. int i, stat;
  195. int SearchForNicsFlag;
  196. int ticks = 0;
  197. PSERIAL_DEVICE_EXTENSION ext;
  198. for (;;)
  199. {
  200. // this time of wait is critically matched to a timeout associated
  201. // with killing this task.
  202. time_stall(10); // wait 1 second
  203. Driver.threadCount++;
  204. //----- open up any unopened the nic cards.
  205. if (Driver.threadHandle == NULL) // request to kill ourselves
  206. break;
  207. ++ticks;
  208. if (Driver.Stop_Poll) // flag to stop poll access
  209. ticks = 0; // don't do config stuff now(contention)
  210. if (Driver.AutoMacDevExt)
  211. {
  212. MyKdPrint(D_Test, ("Auto Mac Assign Thread\n"))
  213. port_set_new_mac_addr(Driver.AutoMacDevExt->pm,
  214. Driver.AutoMacDevExt->config->MacAddr);
  215. write_dev_mac(Driver.AutoMacDevExt);
  216. Driver.AutoMacDevExt = NULL;
  217. }
  218. if (ticks > 60) // every 60 seconds
  219. {
  220. // if any boxes are not in the init state of communications,
  221. // then assume that there may be a missing nic-card we need to
  222. // find in the system.
  223. SearchForNicsFlag = FALSE;
  224. ext = Driver.board_ext;
  225. while(ext)
  226. {
  227. if (ext->pm->state == ST_INIT)
  228. {
  229. SearchForNicsFlag = TRUE;
  230. }
  231. ext = ext->board_ext; // next
  232. }
  233. if (SearchForNicsFlag)
  234. {
  235. ticks = 0; // come back around after full 60 second timeout
  236. ScanForNewNicCards();
  237. }
  238. else
  239. ticks -= 30; // come back around in 30 seconds
  240. }
  241. }
  242. Driver.threadHandle = NULL;
  243. // Terminate myself
  244. PsTerminateSystemThread( STATUS_SUCCESS );
  245. }
  246. #ifdef NT50
  247. /*-----------------------------------------------------------------
  248. reg_list_nt50_linkage - Find ethernet nic-card names in the
  249. registry. Official binding tells us what we are bound to
  250. via NT's binding rules. But, this binding process is combersome
  251. and has problems. Another technique is to search the registry
  252. and look for nic-card names to use. Under NT50, this is easier
  253. in that there is a Net class, and we can search it for cards
  254. with "Ethernet" linkage. So we do both, this gives some backward
  255. compatibility if we choose to install and get the proper bindings
  256. and/or if we want to avoid these binding shortcomings by hacking
  257. our own list of nic-cards from the registry.
  258. Installing as a protocol might solve some of the linkage problems,
  259. (and present new problems too.)
  260. NT4.0 and below stores this in "Services\Servicename\Linkage" area.
  261. NT5.0 PnP network card linkage info stored at:
  262. "REGISTRY\Machine\System\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\0000\Linkage"
  263. Id to determine if node is ours(vs):
  264. "REGISTRY\Machine\System\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\0000\ComponentId"=
  265. "vslinka_did"
  266. |------------------------------------------------------------------*/
  267. static int reg_list_nt50_linkage(void)
  268. {
  269. static char *szLowerRange = {"LowerRange"};
  270. static char *szNdiInterfaces = {"Ndi\\Interfaces"};
  271. static char *szComponentId = {"ComponentId"};
  272. static char *szLinkage = {"Linkage"};
  273. static char *szBind = {"Bind"};
  274. static char *szExport = {"Export"};
  275. static char *szRegRMSCCNetGuid =
  276. {"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}"};
  277. static char *szEthernet = {"Ethernet"};
  278. static char tmpstr[200]; // make static, don't put too much on stack..
  279. static char compstr[40];
  280. static char nodestr[20];
  281. WCHAR *wstr_ptr;
  282. char *buffer = NULL;
  283. char *data_ptr;
  284. HANDLE KeyHandle = NULL;
  285. HANDLE KeyHandle2 = NULL;
  286. HANDLE KeyHandle3 = NULL;
  287. int node_num = 0;
  288. int linkage_found = 0;
  289. int stat;
  290. #define OUR_BUF_SIZE (8000*2)
  291. MyKdPrint(D_Thread, ("Start RegFind Linkage\n"))
  292. stat = our_open_key(&KeyHandle, NULL, szRegRMSCCNetGuid, KEY_READ);
  293. if (stat)
  294. {
  295. MyKdPrint(D_Error, ("Failed OpenKey\n"))
  296. return 1;
  297. }
  298. buffer = ExAllocatePool(PagedPool, OUR_BUF_SIZE);
  299. if ( buffer == NULL ) {
  300. Eprintf("RegFindLinkage no memory");
  301. return 1;
  302. }
  303. for(;;)
  304. {
  305. stat = our_enum_key(KeyHandle,
  306. node_num,
  307. buffer,
  308. OUR_BUF_SIZE,
  309. &data_ptr);
  310. ++node_num;
  311. if (stat)
  312. {
  313. MyKdPrint(D_Thread, ("Done\n"))
  314. break;
  315. }
  316. // does this come back as wchar?
  317. WStrToCStr(nodestr, (PWCHAR)data_ptr, 18);
  318. //if (strlen(data_ptr) < 18)
  319. // strcpy(nodestr, data_ptr);
  320. MyKdPrint(D_Thread, ("Got Key Node:%s.\n", nodestr))
  321. // open up the sub-key (0000, 0001, etc..)
  322. stat = our_open_key(&KeyHandle2, KeyHandle, nodestr, KEY_READ);
  323. if (stat)
  324. {
  325. MyKdPrint(D_Error, ("Err 1X\n"))
  326. continue;
  327. }
  328. stat = our_query_value(KeyHandle2,
  329. szComponentId,
  330. buffer,
  331. OUR_BUF_SIZE,
  332. NULL, // pDataType
  333. &data_ptr);
  334. if (stat)
  335. {
  336. // no component id
  337. MyKdPrint(D_Thread, ("No compId\n"))
  338. compstr[0] = 0;
  339. }
  340. else
  341. {
  342. WStrToCStr(compstr, (PWCHAR)data_ptr, 38);
  343. }
  344. //if (strlen(data_ptr) < 38)
  345. // strcpy(compstr, data_ptr);
  346. MyKdPrint(D_Thread, ("Got compid:%s.\n", compstr))
  347. if ((my_lstricmp(compstr, "vslink1_did") == 0) ||
  348. (my_lstricmp(compstr, "vslink2_did") == 0))
  349. {
  350. MyKdPrint(D_Thread, ("Match\n"))
  351. // open up the sub-key "Linkage" and get "Bind" multisz string
  352. stat = our_open_key(&KeyHandle3, KeyHandle2, szLinkage, KEY_READ);
  353. if (stat)
  354. {
  355. MyKdPrint(D_Thread, ("No Linkage\n"))
  356. continue;
  357. }
  358. stat = our_query_value(KeyHandle3,
  359. szBind,
  360. buffer,
  361. OUR_BUF_SIZE,
  362. NULL, // pDataType
  363. &data_ptr);
  364. if (stat)
  365. {
  366. // no component id
  367. MyKdPrint(D_Thread, ("No Bind\n"))
  368. continue;
  369. }
  370. MyKdPrint(D_Thread, ("Got bind!\n"))
  371. wstr_ptr = (PWCHAR)(data_ptr);
  372. #if DBG
  373. //while (*wstr_ptr != 0) // while more multisz strings
  374. //{
  375. // WStrToCStr(tmpstr, wstr_ptr, 100);
  376. // MyKdPrint(D_Thread, ("Got Bind Name:%s.\n", tmpstr))
  377. // while (*wstr_ptr != 0) // pass up this string
  378. // ++wstr_ptr;
  379. // ++wstr_ptr;
  380. //}
  381. //wstr_ptr = (PWCHAR)(data_ptr);
  382. #endif
  383. CatBindList(wstr_ptr);
  384. ++linkage_found;
  385. }
  386. else //------- not a VS node
  387. {
  388. // so check to see if its a ethernet nic-card which we can
  389. // use the exported name to add to our bind list
  390. // open up the sub-key "Ndi\\Interfaces" and get "LowerRange" multisz string
  391. stat = our_open_key(&KeyHandle3, KeyHandle2, szNdiInterfaces, KEY_READ);
  392. if (stat)
  393. {
  394. MyKdPrint(D_Thread, ("Not a e.nic-card\n"))
  395. continue;
  396. }
  397. stat = our_query_value(KeyHandle3,
  398. szLowerRange,
  399. buffer,
  400. OUR_BUF_SIZE,
  401. NULL, // pDataType
  402. &data_ptr);
  403. if (stat)
  404. {
  405. MyKdPrint(D_Thread, ("No LowRange\n"))
  406. continue;
  407. }
  408. WStrToCStr(tmpstr, (PWCHAR)data_ptr, 38);
  409. if (my_lstricmp(tmpstr, szEthernet) != 0)
  410. {
  411. MyKdPrint(D_Thread, ("Not Eth\n"))
  412. continue;
  413. }
  414. MyKdPrint(D_Thread, ("Found a Nic Card!\n"))
  415. // open up the sub-key "Linkage" and get "Export" multisz string
  416. stat = our_open_key(&KeyHandle3, KeyHandle2, szLinkage, KEY_READ);
  417. if (stat)
  418. {
  419. MyKdPrint(D_Thread, ("No Linkage on E card\n"))
  420. continue;
  421. }
  422. stat = our_query_value(KeyHandle3,
  423. szExport,
  424. buffer,
  425. OUR_BUF_SIZE,
  426. NULL, // pDataType
  427. &data_ptr);
  428. if (stat)
  429. {
  430. MyKdPrint(D_Thread, ("No Export on E.nic-card\n"))
  431. continue;
  432. }
  433. MyKdPrint(D_Thread, ("Got e.card export 2!\n"))
  434. wstr_ptr = (PWCHAR) data_ptr;
  435. #if DBG
  436. //while (*wstr_ptr != 0) // while more multisz strings
  437. //{
  438. // WStrToCStr(tmpstr, wstr_ptr, 100);
  439. // MyKdPrint(D_Thread, ("Got E. Card Name:%s.\n", tmpstr))
  440. // while (*wstr_ptr != 0) // pass up this string
  441. // ++wstr_ptr;
  442. // ++wstr_ptr;
  443. //}
  444. //wstr_ptr = (PWCHAR) data_ptr;
  445. #endif
  446. ++linkage_found;
  447. MyKdPrint(D_Thread, ("E card 3!\n"))
  448. CatBindList(wstr_ptr);
  449. }
  450. } // for
  451. if (KeyHandle != NULL)
  452. ZwClose(KeyHandle);
  453. if (KeyHandle2 != NULL)
  454. ZwClose(KeyHandle2);
  455. if (KeyHandle3 != NULL)
  456. ZwClose(KeyHandle3);
  457. if (buffer != NULL)
  458. ExFreePool(buffer);
  459. if (linkage_found == 0)
  460. {
  461. MyKdPrint(D_Thread, ("ERROR, No Ethernet found!\n"))
  462. }
  463. MyKdPrint(D_Thread, ("reg_list done\n"))
  464. return 1; // err, not found
  465. }
  466. #else
  467. /*----------------------------------------------------------------------------
  468. nt40
  469. |----------------------------------------------------------------------------*/
  470. static int reg_list_nt40_linkage(void)
  471. {
  472. //static char *szLowerRange = {"LowerRange"};
  473. //static char *szNdiInterfaces = {"Ndi\\Interfaces"};
  474. //static char *szComponentId = {"ComponentId"};
  475. //static char *szExport = {"Export"};
  476. //static char *szRegRMSCCNetGuid =
  477. // {"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}"};
  478. //static char *szEthernet = {"Ethernet"};
  479. static char *szRegRMSCS =
  480. {"\\Registry\\Machine\\System\\CurrentControlSet\\Services"};
  481. static char *szLinkage = {"Linkage"};
  482. static char *szBind = {"Bind"};
  483. static char tmpstr[200]; // make static, don't put too much on stack..
  484. static char compstr[40];
  485. static char nodestr[20];
  486. WCHAR *wstr_ptr;
  487. char *buffer = NULL;
  488. char *data_ptr;
  489. HANDLE KeyHandle = NULL;
  490. HANDLE KeyHandle2 = NULL;
  491. HANDLE KeyHandle3 = NULL;
  492. int node_num = 0;
  493. int linkage_found = 0;
  494. int stat;
  495. OBJECT_ATTRIBUTES objAttribs;
  496. NTSTATUS status;
  497. #define OUR_BUF_SIZE (8000*2)
  498. MyKdPrint(D_Thread, ("Start RegFind Linkage\n"))
  499. MyKdPrint(D_Thread, ("str:%s\n", UToC1(&Driver.RegPath) ))
  500. buffer = ExAllocatePool(PagedPool, OUR_BUF_SIZE);
  501. if ( buffer == NULL ) {
  502. Eprintf("RegFindLinkage no memory");
  503. return 1;
  504. }
  505. for (;;)
  506. {
  507. //--- open up our service key: controlset\services\vslinka
  508. InitializeObjectAttributes(&objAttribs,
  509. &Driver.RegPath,
  510. OBJ_CASE_INSENSITIVE,
  511. NULL, // root dir relative handle
  512. NULL); // security desc
  513. status = ZwOpenKey(&KeyHandle,
  514. KEY_READ,
  515. &objAttribs);
  516. if (status != STATUS_SUCCESS)
  517. {
  518. MyKdPrint(D_Error, ("Err 4D:%d\n", status))
  519. break;
  520. }
  521. // open up the sub-key "Linkage" and get "Bind" multisz string
  522. stat = our_open_key(&KeyHandle2, KeyHandle, szLinkage, KEY_READ);
  523. if (stat)
  524. {
  525. MyKdPrint(D_Thread, ("No Linkage\n"))
  526. break;
  527. }
  528. stat = our_query_value(KeyHandle2,
  529. szBind,
  530. buffer,
  531. OUR_BUF_SIZE,
  532. NULL, // pDataType
  533. &data_ptr);
  534. if (stat)
  535. {
  536. // no component id
  537. MyKdPrint(D_Thread, ("No Bind\n"))
  538. break;
  539. }
  540. MyKdPrint(D_Thread, ("Got bind!\n"))
  541. wstr_ptr = (PWCHAR)(data_ptr);
  542. #if DBG
  543. while (*wstr_ptr != 0) // while more multisz strings
  544. {
  545. WStrToCStr(tmpstr, wstr_ptr, 100);
  546. MyKdPrint(D_Thread, ("Got Bind Name:%s.\n", tmpstr))
  547. while (*wstr_ptr != 0) // pass up this string
  548. ++wstr_ptr;
  549. ++wstr_ptr;
  550. }
  551. MyKdPrint(D_Thread, ("bind 3!\n"))
  552. wstr_ptr = (PWCHAR)(data_ptr);
  553. #endif
  554. CatBindList(wstr_ptr);
  555. MyKdPrint(D_Thread, ("bind 4!\n"))
  556. ++linkage_found;
  557. break; // all done.
  558. }
  559. // now go nab tcpip's bindings...
  560. for (;;)
  561. {
  562. MyKdPrint(D_Thread, ("Get other Linkage\n"))
  563. stat = our_open_key(&KeyHandle, NULL, szRegRMSCS, KEY_READ);
  564. if (stat)
  565. {
  566. MyKdPrint(D_Thread, ("Failed OpenKey\n"))
  567. break;
  568. }
  569. // open up the sub-key "tcpip\\Linkage" and get "Bind" multisz string
  570. tmpstr[0] = 't';
  571. tmpstr[1] = 'c';
  572. tmpstr[2] = 'p';
  573. tmpstr[3] = 'i';
  574. tmpstr[4] = 'p';
  575. tmpstr[5] = '\\';
  576. tmpstr[6] = 0;
  577. strcat(tmpstr, szLinkage);
  578. stat = our_open_key(&KeyHandle2, KeyHandle, tmpstr, KEY_READ);
  579. if (stat)
  580. {
  581. MyKdPrint(D_Thread, ("No other binding\n"))
  582. break;
  583. }
  584. stat = our_query_value(KeyHandle2,
  585. szBind,
  586. buffer,
  587. OUR_BUF_SIZE,
  588. NULL, // pDataType
  589. &data_ptr);
  590. if (stat)
  591. {
  592. // no component id
  593. MyKdPrint(D_Thread, ("No other Bind\n"))
  594. break;
  595. }
  596. MyKdPrint(D_Thread, ("Got other bind!\n"))
  597. wstr_ptr = (PWCHAR)(data_ptr);
  598. #if DBG
  599. while (*wstr_ptr != 0) // while more multisz strings
  600. {
  601. WStrToCStr(tmpstr, wstr_ptr, 100);
  602. MyKdPrint(D_Thread, ("Got Bind Name:%s.\n", tmpstr))
  603. while (*wstr_ptr != 0) // pass up this string
  604. ++wstr_ptr;
  605. ++wstr_ptr;
  606. }
  607. wstr_ptr = (PWCHAR)(data_ptr);
  608. #endif
  609. CatBindList(wstr_ptr);
  610. ++linkage_found;
  611. break;
  612. }
  613. if (KeyHandle != NULL)
  614. ZwClose(KeyHandle);
  615. if (KeyHandle2 != NULL)
  616. ZwClose(KeyHandle2);
  617. if (KeyHandle3 != NULL)
  618. ZwClose(KeyHandle3);
  619. if (buffer != NULL)
  620. ExFreePool(buffer);
  621. MyKdPrint(D_Thread, ("reg_list done\n"))
  622. if (linkage_found == 0)
  623. {
  624. MyKdPrint(D_Thread, ("ERROR, No Ethernet found!\n"))
  625. return 1;
  626. }
  627. return 0; // ok, linkage found
  628. }
  629. #endif
  630. /*----------------------------------------------------------------------
  631. init_eth_start - start up ethernet work.
  632. |----------------------------------------------------------------------*/
  633. int init_eth_start(void)
  634. {
  635. int stat,i;
  636. for (i=0; i<VS1000_MAX_NICS; i++)
  637. {
  638. // this is only used for debug display
  639. Driver.nics[i].RefIndex = i;
  640. }
  641. stat = ProtocolOpen(); // fills in Driver.ndis_version
  642. if (stat != 0)
  643. {
  644. Eprintf("Protocol fail:%d",stat);
  645. SerialUnload(Driver.GlobalDriverObject);
  646. return STATUS_SERIAL_NO_DEVICE_INITED;
  647. }
  648. // start up our nic handler thread, to periodically find any
  649. // new nic cards in the system
  650. ScanForNewNicCards(); // do initial scan.
  651. // start up our thread
  652. if (Driver.threadHandle == NULL)
  653. {
  654. Driver.threadCount = 0;
  655. stat = PsCreateSystemThread(
  656. &Driver.threadHandle,
  657. THREAD_ALL_ACCESS,
  658. NULL,
  659. NULL,
  660. NULL,
  661. (PKSTART_ROUTINE)NicThread,
  662. NULL); // our context
  663. if (Driver.threadHandle == NULL)
  664. {
  665. Eprintf("Thread Fail\n");
  666. SerialUnload(Driver.GlobalDriverObject);
  667. return STATUS_SERIAL_NO_DEVICE_INITED;
  668. }
  669. } // if threadHandle
  670. return STATUS_SUCCESS;
  671. }
  672. /*-----------------------------------------------------------------------
  673. VSSpecialStartup - after board_ext is created and after port_ext's are
  674. created. This sets up further structs.
  675. |-----------------------------------------------------------------------*/
  676. NTSTATUS VSSpecialStartup(PSERIAL_DEVICE_EXTENSION board_ext)
  677. {
  678. //PSERIAL_DEVICE_EXTENSION ext = NULL;
  679. int stat, port_index;
  680. if (board_ext->config->NumPorts <= 8) // its a RHub device
  681. board_ext->config->IsHubDevice = 1;
  682. // setup default ClkRate if not specified
  683. if (board_ext->config->ClkRate == 0)
  684. {
  685. // use default
  686. if (board_ext->config->IsHubDevice)
  687. board_ext->config->ClkRate = DEF_RHUB_CLOCKRATE;
  688. else
  689. board_ext->config->ClkRate = DEF_VS_CLOCKRATE;
  690. }
  691. // setup default PreScaler if not specified
  692. if (board_ext->config->ClkPrescaler == 0)
  693. {
  694. // use default
  695. if (board_ext->config->IsHubDevice)
  696. board_ext->config->ClkPrescaler = DEF_RHUB_PRESCALER;
  697. else
  698. board_ext->config->ClkPrescaler = DEF_VS_PRESCALER;
  699. }
  700. stat = portman_init(board_ext->hd,
  701. board_ext->pm,
  702. board_ext->config->NumPorts,
  703. board_ext->UniqueId,
  704. board_ext->config->BackupServer,
  705. board_ext->config->BackupTimer,
  706. board_ext->config->MacAddr);
  707. if (stat != 0)
  708. {
  709. MyKdPrint(D_Init, ("Hdlc Failed Open\n"))
  710. return STATUS_SERIAL_NO_DEVICE_INITED;
  711. }
  712. #ifdef NT40
  713. board_ext->config->HardwareStarted = TRUE; // tell ISR its ready to go
  714. board_ext->FdoStarted = 1; // ok to start using
  715. #endif
  716. return STATUS_SUCCESS;
  717. }
  718. /*----------------------------------------------------------------------
  719. init_stop - unload thread, ndis nic cards, etc
  720. |----------------------------------------------------------------------*/
  721. int init_stop(void)
  722. {
  723. int i;
  724. MyKdPrint(D_Init, ("Init Stop\n"))
  725. if (Driver.threadHandle != NULL)
  726. {
  727. ZwClose(Driver.threadHandle);
  728. Driver.threadHandle = NULL; // tell thread to kill itself
  729. time_stall(15); // wait 1.5 second
  730. }
  731. if (Driver.nics != NULL)
  732. {
  733. for (i=0; i<VS1000_MAX_NICS; i++)
  734. {
  735. if (Driver.nics[i].NICHandle != NULL)
  736. NicClose(&Driver.nics[i]);
  737. }
  738. //our_free(Driver.nics, "nics");
  739. }
  740. //Driver.nics = NULL;
  741. if (Driver.NdisProtocolHandle != NULL)
  742. NicProtocolClose();
  743. Driver.NdisProtocolHandle = NULL;
  744. MyKdPrint(D_Init, ("Init Stop End\n"))
  745. return 0;
  746. }
  747. /*----------------------------------------------------------------------
  748. find_all_boxes - Locate all boxes out on the networks. Use broadcasts.
  749. |----------------------------------------------------------------------*/
  750. int find_all_boxes(int pass)
  751. {
  752. int inic, j;
  753. if (pass == 0)
  754. Driver.NumBoxMacs = 0; // clear out mac query-respond list
  755. // do the query on all nic-segments
  756. for (inic=0; inic<VS1000_MAX_NICS; inic++)
  757. {
  758. // broadcast request id
  759. if (Driver.nics[inic].Open) // if nic-card open for use
  760. {
  761. admin_send_query_id(&Driver.nics[inic], broadcast_addr, 0,0);
  762. }
  763. }
  764. // wait for responses which are accumulated in Driver.BoxMacs[] and
  765. // Driver.NumBoxMacs.
  766. time_stall((4*pass)+4); // wait .2 second
  767. if (Driver.NumBoxMacs == 0) // no reply
  768. {
  769. return 1; // return error
  770. }
  771. // sort the replies in ascending order
  772. sort_macs();
  773. #if DBG
  774. if (Driver.VerboseLog && (pass == 0))
  775. {
  776. unsigned char *mac;
  777. for (j=0; j<Driver.NumBoxMacs; j++)
  778. {
  779. mac = &Driver.BoxMacs[j*8];
  780. Tprintf("MacLst:%x %x %x %x %x %x ,N:%d",
  781. mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[7]);
  782. }
  783. }
  784. #endif
  785. return 0; // return ok
  786. }
  787. /*----------------------------------------------------------------------
  788. sort_macs - sort mac addresses returned by query_id requests sent
  789. out to boxes. Mac array is 8 bytes to allow extra room to indicate
  790. nic-segment it was found on.
  791. |----------------------------------------------------------------------*/
  792. void sort_macs(void)
  793. {
  794. int i;
  795. BYTE temp_mac[8];
  796. BYTE *mac1;
  797. BYTE *mac2;
  798. int done;
  799. int num_macs = Driver.NumBoxMacs;
  800. if (num_macs <= 1)
  801. return;
  802. // bubble sort
  803. done = 0;
  804. while (!done)
  805. {
  806. done = 1;
  807. for (i=1; i<num_macs; i++)
  808. {
  809. mac1 = &Driver.BoxMacs[i*8];
  810. mac2 = &Driver.BoxMacs[(i-1)*8];
  811. if (mac_cmp(mac1, mac2) < 0)
  812. {
  813. done = 0;
  814. // swap em
  815. memcpy(temp_mac, mac1, 8);
  816. memcpy(mac1, mac2, 8);
  817. memcpy(mac2, temp_mac, 8);
  818. } // sort op-swap
  819. } // sort loop
  820. } // !done
  821. }
  822. /*-----------------------------------------------------------------------
  823. LoadMicroCode - Load up the micro-code from disk.
  824. |-----------------------------------------------------------------------*/
  825. int LoadMicroCode(char *filename)
  826. {
  827. NTSTATUS ntStatus;
  828. HANDLE NtFileHandle;
  829. OBJECT_ATTRIBUTES ObjectAttributes;
  830. IO_STATUS_BLOCK IoStatus;
  831. USTR_160 uname;
  832. FILE_STANDARD_INFORMATION StandardInfo;
  833. // WCHAR PathPrefix[] = L"\\SystemRoot\\system32\\drivers\\";
  834. ULONG LengthOfFile;
  835. // ULONG FullFileNameLength;
  836. static char *def_filename = {"\\SystemRoot\\system32\\drivers\\vslinka.bin"};
  837. if (filename == NULL)
  838. filename = def_filename;
  839. CToUStr((PUNICODE_STRING)&uname, filename, sizeof(uname));
  840. InitializeObjectAttributes ( &ObjectAttributes,
  841. &uname.ustr,
  842. OBJ_CASE_INSENSITIVE,
  843. NULL,
  844. NULL );
  845. ntStatus = ZwCreateFile( &NtFileHandle,
  846. SYNCHRONIZE | FILE_READ_DATA,
  847. &ObjectAttributes,
  848. &IoStatus,
  849. NULL, // alloc size = none
  850. FILE_ATTRIBUTE_NORMAL,
  851. FILE_SHARE_READ,
  852. FILE_OPEN,
  853. FILE_SYNCHRONOUS_IO_NONALERT,
  854. NULL, // eabuffer
  855. 0); // ealength
  856. if (!NT_SUCCESS(ntStatus))
  857. {
  858. return 1;
  859. }
  860. //
  861. // Query the object to determine its length.
  862. //
  863. ntStatus = ZwQueryInformationFile( NtFileHandle,
  864. &IoStatus,
  865. &StandardInfo,
  866. sizeof(FILE_STANDARD_INFORMATION),
  867. FileStandardInformation );
  868. if (!NT_SUCCESS(ntStatus))
  869. {
  870. ZwClose(NtFileHandle);
  871. return 2;
  872. }
  873. LengthOfFile = StandardInfo.EndOfFile.LowPart;
  874. //ZwCFDump(ZWCFDIAG1, ("File length is %d\n", LengthOfFile));
  875. if (LengthOfFile < 1)
  876. {
  877. ZwClose(NtFileHandle);
  878. return 3;
  879. }
  880. if (Driver.MicroCodeImage != NULL)
  881. {
  882. our_free(Driver.MicroCodeImage, "MCI");
  883. }
  884. // Allocate buffer for this file
  885. Driver.MicroCodeImage = our_locked_alloc( LengthOfFile, "MCI");
  886. if( Driver.MicroCodeImage == NULL )
  887. {
  888. MyKdPrint(D_Init, ("Err 12A\n"))
  889. ZwClose( NtFileHandle );
  890. return 4;
  891. }
  892. // Read the file into our buffer.
  893. ntStatus = ZwReadFile( NtFileHandle,
  894. NULL,
  895. NULL,
  896. NULL,
  897. &IoStatus,
  898. Driver.MicroCodeImage,
  899. LengthOfFile,
  900. NULL,
  901. NULL);
  902. if( (!NT_SUCCESS(ntStatus)) || (IoStatus.Information != LengthOfFile) )
  903. {
  904. MyKdPrint(D_Init, ("Err 12B\n"))
  905. our_free(Driver.MicroCodeImage,"MCI");
  906. return 5;
  907. }
  908. ZwClose( NtFileHandle );
  909. Driver.MicroCodeSize = LengthOfFile;
  910. // no, lets not corrupt the startup code!
  911. ////Driver.MicroCodeImage[50] = 0;
  912. // TraceStr(Driver.MicroCodeImage);
  913. // TraceStr(">>> Done Reading");
  914. return 0;
  915. }
  916. #if 0
  917. /*----------------------------------------------------------------------
  918. is_mac_unused - Used for autoconfig of mac-address.
  919. |----------------------------------------------------------------------*/
  920. int is_mac_used(DRIVER_MAC_STATUS *)
  921. {
  922. PSERIAL_DEVICE_EXTENSION board_ext;
  923. if (mac_entry->flags & FLAG_APPL_RUNNING)
  924. return 1; // its used
  925. board_ext = Driver.board_ext;
  926. while (board_ext != NULL)
  927. {
  928. if ((!board_ext->FdoStarted) || (!board_ext->config->HardwareStarted))
  929. {
  930. board_ext = board_ext->board_ext; // next in chain
  931. return 1; // might be used
  932. }
  933. if (mac_match(ext->config->MacAddr, mac_entry->mac)
  934. return 1; // its used
  935. }
  936. board_ext = board_ext->board_ext;
  937. }
  938. return 0; // its not used
  939. }
  940. #endif