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.

754 lines
19 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. driver.c
  5. Abstract:
  6. ATMEPVC - Driver Entry and associated functions
  7. Author:
  8. Revision History:
  9. Who When What
  10. -------- -------- ----
  11. ADube 03-23-00 created, .
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #pragma NDIS_INIT_FUNCTION(DriverEntry)
  16. //
  17. // temp global variables
  18. //
  19. NDIS_HANDLE ProtHandle, DriverHandle;
  20. //
  21. // global variables
  22. //
  23. NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
  24. NDIS_HANDLE ProtHandle = NULL;
  25. NDIS_HANDLE DriverHandle = NULL;
  26. NDIS_MEDIUM MediumArray[1] =
  27. {
  28. NdisMediumAtm
  29. };
  30. LIST_ENTRY g_ProtocolList;
  31. EPVC_GLOBALS EpvcGlobals;
  32. RM_STATUS
  33. epvcResHandleGlobalProtocolList(
  34. PRM_OBJECT_HEADER pObj,
  35. RM_RESOURCE_OPERATION Op,
  36. PVOID pvUserParams,
  37. PRM_STACK_RECORD psr
  38. );
  39. RM_STATUS
  40. epvcRegisterIMDriver(
  41. PRM_OBJECT_HEADER pObj,
  42. RM_RESOURCE_OPERATION Op,
  43. PVOID pvUserParams,
  44. PRM_STACK_RECORD psr
  45. );
  46. RM_STATUS
  47. epvcUnloadDriver(
  48. PRM_OBJECT_HEADER pObj,
  49. RM_RESOURCE_OPERATION Op,
  50. PVOID pvUserParams,
  51. PRM_STACK_RECORD psr
  52. );
  53. RM_STATUS
  54. epvcDeRegisterIMDriver(
  55. PRM_OBJECT_HEADER pObj,
  56. RM_RESOURCE_OPERATION Op,
  57. PVOID pvUserParams,
  58. PRM_STACK_RECORD psr
  59. );
  60. RM_STATUS
  61. epvcIMDriverRegistration(
  62. PRM_OBJECT_HEADER pObj,
  63. RM_RESOURCE_OPERATION Op,
  64. PVOID pvUserParams,
  65. PRM_STACK_RECORD psr
  66. );
  67. //--------------------------------------------------------------------------------
  68. // //
  69. // Global Root structure definitions //
  70. // //
  71. // //
  72. //--------------------------------------------------------------------------------
  73. // List of fixed resources used by ArpGlobals
  74. //
  75. enum
  76. {
  77. RTYPE_GLOBAL_PROTOCOL_LIST,
  78. RTYPE_GLOBAL_REGISTER_IM
  79. }; // EPVC_GLOBAL_RESOURCES;
  80. //
  81. // Identifies information pertaining to the use of the above resources.
  82. // Following table MUST be in strict increasing order of the RTYPE_GLOBAL
  83. // enum.
  84. //
  85. RM_RESOURCE_TABLE_ENTRY
  86. EpvcGlobals_ResourceTable[] =
  87. {
  88. {RTYPE_GLOBAL_PROTOCOL_LIST, epvcResHandleGlobalProtocolList},
  89. {RTYPE_GLOBAL_REGISTER_IM, epvcIMDriverRegistration}
  90. };
  91. // Static information about ArpGlobals.
  92. //
  93. RM_STATIC_OBJECT_INFO
  94. EpvcGlobals_StaticInfo =
  95. {
  96. 0, // TypeUID
  97. 0, // TypeFlags
  98. "EpvcGlobals", // TypeName
  99. 0, // Timeout
  100. NULL, // pfnCreate
  101. NULL, // pfnDelete
  102. NULL, // pfnVerifyLock
  103. sizeof(EpvcGlobals_ResourceTable)/sizeof(EpvcGlobals_ResourceTable[1]),
  104. EpvcGlobals_ResourceTable
  105. };
  106. //--------------------------------------------------------------------------------
  107. // //
  108. // Underlying Adapters. The Protocol gets called at BindAdapter for //
  109. // each adapter //
  110. // //
  111. // //
  112. //--------------------------------------------------------------------------------
  113. // eovcAdapter_HashInfo contains information required maintain a hashtable
  114. // of EPVC_ADAPTER objects.
  115. //
  116. RM_HASH_INFO
  117. epvcAdapter_HashInfo =
  118. {
  119. NULL, // pfnTableAllocator
  120. NULL, // pfnTableDeallocator
  121. epvcAdapterCompareKey, // fnCompare
  122. // Function to generate a ULONG-sized hash.
  123. //
  124. epvcAdapterHash // pfnHash
  125. };
  126. // EpvcGlobals_AdapterStaticInfo contains static information about
  127. // objects of type EPVC_ADAPTERS.
  128. // It is a group of Adapters that the protocol has bound to
  129. //
  130. RM_STATIC_OBJECT_INFO
  131. EpvcGlobals_AdapterStaticInfo =
  132. {
  133. 0, // TypeUID
  134. 0, // TypeFlags
  135. "Adapter", // TypeName
  136. 0, // Timeout
  137. epvcAdapterCreate, // pfnCreate
  138. epvcAdapterDelete, // pfnDelete
  139. NULL, // pfnVerifyLock
  140. 0, // Size of resource table
  141. NULL, // ResourceTable
  142. &epvcAdapter_HashInfo
  143. };
  144. //--------------------------------------------------------------------------------
  145. // //
  146. // Intermediate miniports - each hangs of a protocol block //
  147. // //
  148. // //
  149. //--------------------------------------------------------------------------------
  150. // arpAdapter_HashInfo contains information required maintain a hashtable
  151. // of EPVC_ADAPTER objects.
  152. //
  153. RM_HASH_INFO
  154. epvc_I_Miniport_HashInfo=
  155. {
  156. NULL, // pfnTableAllocator
  157. NULL, // pfnTableDeallocator
  158. epvcIMiniportCompareKey, // fnCompare
  159. // Function to generate a ULONG-sized hash.
  160. //
  161. epvcIMiniportHash // pfnHash
  162. };
  163. RM_STATIC_OBJECT_INFO
  164. EpvcGlobals_I_MiniportStaticInfo =
  165. {
  166. 0, // TypeUID
  167. 0, // TypeFlags
  168. "IMiniport", // TypeName
  169. 0, // Timeout
  170. epvcIMiniportCreate, // pfnCreate
  171. epvcIMiniportDelete, // pfnDelete
  172. NULL, // pfnVerifyLock
  173. 0, // Size of resource table
  174. NULL, // ResourceTable
  175. &epvc_I_Miniport_HashInfo
  176. };
  177. //
  178. // Variables used in debugging
  179. //
  180. #if DBG
  181. ULONG g_ulTraceLevel= DEFAULTTRACELEVEL;
  182. ULONG g_ulTraceMask = DEFAULTTRACEMASK ;
  183. #endif
  184. NTSTATUS
  185. DriverEntry(
  186. IN PDRIVER_OBJECT DriverObject,
  187. IN PUNICODE_STRING RegistryPath
  188. )
  189. /*++
  190. Routine Description:
  191. Arguments:
  192. Return Value:
  193. --*/
  194. {
  195. NDIS_STATUS Status;
  196. NTSTATUS NtStatus;
  197. BOOLEAN AllocatedGlobals = FALSE;
  198. ENTER("DriverEntry", 0xbfcb7eb1)
  199. RM_DECLARE_STACK_RECORD(SR)
  200. TIMESTAMP("==>DriverEntry");
  201. TRACE ( TL_T, TM_Dr,("==>Atm Epvc DriverEntry\n"));
  202. do
  203. {
  204. //
  205. // Inititalize the global variables
  206. //
  207. // Must be done before any RM apis are used.
  208. //
  209. RmInitializeRm();
  210. RmInitializeLock(
  211. &EpvcGlobals.Lock,
  212. LOCKLEVEL_GLOBAL
  213. );
  214. RmInitializeHeader(
  215. NULL, // pParentObject,
  216. &EpvcGlobals.Hdr,
  217. ATMEPVC_GLOBALS_SIG ,
  218. &EpvcGlobals.Lock,
  219. &EpvcGlobals_StaticInfo,
  220. NULL, // szDescription
  221. &SR
  222. );
  223. AllocatedGlobals = TRUE;
  224. //
  225. // Initialize globals
  226. //
  227. EpvcGlobals.driver.pDriverObject = DriverObject;
  228. EpvcGlobals.driver.pRegistryPath = RegistryPath;
  229. //
  230. // Register the IM Miniport with NDIS.
  231. //
  232. Status = RmLoadGenericResource(
  233. &EpvcGlobals.Hdr,
  234. RTYPE_GLOBAL_PROTOCOL_LIST,
  235. &SR
  236. );
  237. if (FAIL(Status)) break;
  238. //
  239. // Register the protocol with NDIS.
  240. //
  241. Status = RmLoadGenericResource(
  242. &EpvcGlobals.Hdr,
  243. RTYPE_GLOBAL_REGISTER_IM,
  244. &SR
  245. );
  246. if (FAIL(Status)) break;
  247. } while (FALSE);
  248. if (FAIL(Status))
  249. {
  250. if (AllocatedGlobals)
  251. {
  252. RmUnloadAllGenericResources(
  253. &EpvcGlobals.Hdr,
  254. &SR
  255. );
  256. RmDeallocateObject(
  257. &EpvcGlobals.Hdr,
  258. &SR
  259. );
  260. }
  261. // Must be done after any RM apis are used and async activity complete.
  262. //
  263. RmDeinitializeRm();
  264. NtStatus = STATUS_UNSUCCESSFUL;
  265. }
  266. else
  267. {
  268. NtStatus = NDIS_STATUS_SUCCESS;
  269. }
  270. EXIT()
  271. TIMESTAMP("<==DriverEntry");
  272. RM_ASSERT_CLEAR(&SR);
  273. return Status ;
  274. }
  275. VOID
  276. EpvcUnload(
  277. IN PDRIVER_OBJECT pDriverObject
  278. )
  279. /*++
  280. Routine Description:
  281. This routine is called by the system prior to unloading us.
  282. Currently, we just undo everything we did in DriverEntry,
  283. that is, de-register ourselves as an NDIS protocol, and delete
  284. the device object we had created.
  285. Arguments:
  286. pDriverObject - Pointer to the driver object created by the system.
  287. Return Value:
  288. None
  289. --*/
  290. {
  291. NDIS_STATUS NdisStatus;
  292. ENTER("Unload", 0xc8482549)
  293. RM_DECLARE_STACK_RECORD(sr);
  294. TIMESTAMP("==>Unload");
  295. RmUnloadAllGenericResources(&EpvcGlobals.Hdr, &sr);
  296. RmDeallocateObject(&EpvcGlobals.Hdr, &sr);
  297. // Must be done after any RM apis are used and async activity complete.
  298. //
  299. RmDeinitializeRm();
  300. // TODO? Block(250);
  301. RM_ASSERT_CLEAR(&sr)
  302. EXIT()
  303. TIMESTAMP("<==Unload");
  304. return;
  305. }
  306. RM_STATUS
  307. epvcResHandleGlobalProtocolList(
  308. PRM_OBJECT_HEADER pObj,
  309. RM_RESOURCE_OPERATION Op,
  310. PVOID pvUserParams,
  311. PRM_STACK_RECORD pSR
  312. )
  313. {
  314. PEPVC_GLOBALS pGlobals = NULL;
  315. ENTER("GlobalAdapterList", 0xb407e79e)
  316. TRACE (TL_T, TM_Dr, ("==>epvcResHandleGlobalProtocolList pObj %x, Op",
  317. pObj , Op ) );
  318. pGlobals = CONTAINING_RECORD(
  319. pObj,
  320. EPVC_GLOBALS,
  321. Hdr);
  322. //
  323. //
  324. if (Op == RM_RESOURCE_OP_LOAD)
  325. {
  326. //
  327. // Allocate adapter list.
  328. //
  329. TR_WARN(("LOADING"));
  330. RmInitializeGroup(
  331. pObj, // pParentObject
  332. &EpvcGlobals_AdapterStaticInfo, // pStaticInfo
  333. &(pGlobals->adapters.Group), // pGroup
  334. "Adapters Group", // szDescription
  335. pSR // pStackRecord
  336. );
  337. }
  338. else if (Op == RM_RESOURCE_OP_UNLOAD)
  339. {
  340. //
  341. // We're unloading this "resource", i.e., unloading and deallocating the
  342. // global adapter list. We first unload and free all the adapters
  343. // in the list, and then free the list itself.
  344. //
  345. TR_WARN(("UNLOADING"));
  346. //
  347. // We expect there to be no adapter objects at this point.
  348. //
  349. ASSERT(pGlobals->adapters.Group.HashTable.NumItems == 0);
  350. RmDeinitializeGroup(&pGlobals->adapters.Group, pSR);
  351. NdisZeroMemory(&(pGlobals->adapters), sizeof(pGlobals->adapters));
  352. }
  353. else
  354. {
  355. // Unexpected op code.
  356. //
  357. ASSERT(!"Unexpected OpCode epvcResHandleGlobalProtocolList ");
  358. }
  359. TRACE (TL_T, TM_Dr, ("<==epvcResHandleGlobalProtocolList Status %x",
  360. NDIS_STATUS_SUCCESS) );
  361. EXIT()
  362. RM_ASSERT_CLEAR(pSR);
  363. return NDIS_STATUS_SUCCESS;
  364. }
  365. RM_STATUS
  366. epvcIMDriverRegistration(
  367. PRM_OBJECT_HEADER pObj,
  368. RM_RESOURCE_OPERATION Op,
  369. PVOID pvUserParams,
  370. PRM_STACK_RECORD psr
  371. )
  372. {
  373. TRACE (TL_T, TM_Mp, ("epvcIMDriverRegistration Op %x", Op));
  374. if (RM_RESOURCE_OP_LOAD == Op)
  375. {
  376. epvcRegisterIMDriver(pObj,Op,pvUserParams,psr);
  377. }
  378. else
  379. {
  380. epvcDeRegisterIMDriver(pObj,Op,pvUserParams,psr);
  381. }
  382. return NDIS_STATUS_SUCCESS;
  383. }
  384. RM_STATUS
  385. epvcRegisterIMDriver(
  386. PRM_OBJECT_HEADER pObj,
  387. RM_RESOURCE_OPERATION Op,
  388. PVOID pvUserParams,
  389. PRM_STACK_RECORD psr
  390. )
  391. {
  392. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  393. PEPVC_GLOBALS pGlobals = NULL;
  394. NDIS_PROTOCOL_CHARACTERISTICS PChars;
  395. NDIS_MINIPORT_CHARACTERISTICS MChars;
  396. NDIS_STRING Name;
  397. ENTER("epvcRegisterIMDriver", 0x0d0f008a);
  398. pGlobals = CONTAINING_RECORD(
  399. pObj,
  400. EPVC_GLOBALS,
  401. Hdr);
  402. TRACE (TL_T, TM_Dr, ("==>epvcRegisterIMDriver Globals %x",
  403. pObj) );
  404. //
  405. // Register the miniport with NDIS. Note that it is the miniport
  406. // which was started as a driver and not the protocol. Also the miniport
  407. // must be registered prior to the protocol since the protocol's BindAdapter
  408. // handler can be initiated anytime and when it is, it must be ready to
  409. // start driver instances.
  410. //
  411. NdisMInitializeWrapper(&pGlobals->driver.WrapperHandle,
  412. pGlobals->driver.pDriverObject,
  413. pGlobals->driver.pRegistryPath,
  414. NULL);
  415. NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
  416. MChars.MajorNdisVersion = 5;
  417. MChars.MinorNdisVersion = 0;
  418. MChars.InitializeHandler = EpvcInitialize;
  419. MChars.QueryInformationHandler = EpvcMpQueryInformation;
  420. MChars.SetInformationHandler = EpvcMpSetInformation;
  421. MChars.ResetHandler = MPReset;
  422. MChars.TransferDataHandler = MPTransferData;
  423. MChars.HaltHandler = EpvcHalt;
  424. //
  425. // We will disable the check for hang timeout so we do not
  426. // need a check for hang handler!
  427. //
  428. MChars.CheckForHangHandler = NULL;
  429. MChars.SendHandler = NULL;
  430. MChars.ReturnPacketHandler = EpvcReturnPacket;
  431. //
  432. // Either the Send or the SendPackets handler should be specified.
  433. // If SendPackets handler is specified, SendHandler is ignored
  434. //
  435. MChars.SendPacketsHandler = EpvcSendPackets;
  436. Status = NdisIMRegisterLayeredMiniport(pGlobals->driver.WrapperHandle,
  437. &MChars,
  438. sizeof(MChars),
  439. &EpvcGlobals.driver.DriverHandle);
  440. ASSERT (EpvcGlobals.driver.DriverHandle != NULL);
  441. if (Status != NDIS_STATUS_SUCCESS)
  442. {
  443. //
  444. // todo: fix failure case
  445. //
  446. ASSERT (0);
  447. };
  448. //
  449. // Now register the protocol.
  450. //
  451. NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  452. PChars.MajorNdisVersion = 5;
  453. PChars.MinorNdisVersion = 0;
  454. //
  455. // Make sure the protocol-name matches the service-name under which this protocol is installed.
  456. // This is needed to ensure that NDIS can correctly determine the binding and call us to bind
  457. // to miniports below.
  458. //
  459. NdisInitUnicodeString(&Name, L"ATMEPVCP"); // Protocol name
  460. PChars.Name = Name;
  461. PChars.OpenAdapterCompleteHandler = EpvcOpenAdapterComplete;
  462. PChars.CloseAdapterCompleteHandler = EpvcCloseAdapterComplete;
  463. PChars.SendCompleteHandler = NULL;
  464. PChars.TransferDataCompleteHandler = PtTransferDataComplete;
  465. PChars.ResetCompleteHandler = EpvcResetComplete;
  466. PChars.RequestCompleteHandler = EpvcRequestComplete ;
  467. PChars.ReceiveHandler = PtReceive;
  468. PChars.ReceiveCompleteHandler = EpvcPtReceiveComplete;
  469. PChars.StatusHandler = EpvcStatus;
  470. PChars.StatusCompleteHandler = PtStatusComplete;
  471. PChars.BindAdapterHandler = EpvcBindAdapter;
  472. PChars.UnbindAdapterHandler = EpvcUnbindAdapter;
  473. PChars.UnloadHandler = NULL;
  474. PChars.ReceivePacketHandler = PtReceivePacket;
  475. PChars.PnPEventHandler= EpvcPtPNPHandler;
  476. PChars.CoAfRegisterNotifyHandler = EpvcAfRegisterNotify;
  477. PChars.CoSendCompleteHandler = EpvcPtSendComplete;
  478. PChars.CoReceivePacketHandler = EpvcCoReceive;
  479. {
  480. //
  481. // Update client characteristis
  482. //
  483. PNDIS_CLIENT_CHARACTERISTICS pNdisCC = &(pGlobals->ndis.CC);
  484. NdisZeroMemory(pNdisCC, sizeof(*pNdisCC));
  485. pNdisCC->MajorVersion = EPVC_NDIS_MAJOR_VERSION;
  486. pNdisCC->MinorVersion = EPVC_NDIS_MINOR_VERSION;
  487. pNdisCC->ClCreateVcHandler = EpvcClientCreateVc;
  488. pNdisCC->ClDeleteVcHandler = EpvcClientDeleteVc;
  489. pNdisCC->ClRequestHandler = EpvcCoRequest;
  490. pNdisCC->ClRequestCompleteHandler = EpvcCoRequestComplete;
  491. pNdisCC->ClOpenAfCompleteHandler = EpvcCoOpenAfComplete;
  492. pNdisCC->ClCloseAfCompleteHandler = EpvcCoCloseAfComplete;
  493. pNdisCC->ClMakeCallCompleteHandler = EpvcCoMakeCallComplete;
  494. pNdisCC->ClModifyCallQoSCompleteHandler = NULL;
  495. pNdisCC->ClIncomingCloseCallHandler = EpvcCoIncomingClose;
  496. pNdisCC->ClCallConnectedHandler = EpvcCoCallConnected;
  497. pNdisCC->ClCloseCallCompleteHandler = EpvcCoCloseCallComplete;
  498. pNdisCC->ClIncomingCallHandler = EpvcCoIncomingCall;
  499. }
  500. NdisRegisterProtocol(&Status,
  501. &pGlobals->driver.ProtocolHandle,
  502. &PChars,
  503. sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  504. ASSERT(Status == NDIS_STATUS_SUCCESS);
  505. NdisMRegisterUnloadHandler(pGlobals->driver.WrapperHandle,
  506. EpvcUnload);
  507. ASSERT (pGlobals == &EpvcGlobals);
  508. NdisIMAssociateMiniport(EpvcGlobals.driver.DriverHandle, pGlobals->driver.ProtocolHandle);
  509. EXIT()
  510. TRACE (TL_T, TM_Dr, ("<==epvcRegisterIMDriver ") );
  511. return Status;
  512. }
  513. RM_STATUS
  514. epvcDeRegisterIMDriver(
  515. PRM_OBJECT_HEADER pObj,
  516. RM_RESOURCE_OPERATION Op,
  517. PVOID pvUserParams,
  518. PRM_STACK_RECORD psr
  519. )
  520. {
  521. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  522. TRACE (TL_T, TM_Pt, ("== eovcDeRegisterIMDriver"));
  523. while (NdisStatus != NDIS_STATUS_SUCCESS)
  524. {
  525. NdisDeregisterProtocol(&NdisStatus, EpvcGlobals.driver.ProtocolHandle);
  526. NdisMSleep(1000);
  527. }
  528. return NdisStatus;
  529. }
  530. void
  531. DbgMark(UINT Luid)
  532. {
  533. // do nothing useful, but do something specific, so that the compiler doesn't
  534. // alias DbgMark to some other function that happens to do nothing.
  535. //
  536. static int i;
  537. i=Luid;
  538. }