Source code of Windows XP (NT5)
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.

530 lines
12 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. autodial.c
  5. Abstract:
  6. NT specific routines for interfacing with the
  7. RAS AutoDial driver (rasacd.sys).
  8. Author:
  9. Anthony Discolo (adiscolo) Aug 30, 1995
  10. Revision History:
  11. Who When What
  12. -------- -------- ----------------------------------------------
  13. adiscolo 08-30-95 created
  14. Notes:
  15. --*/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #ifdef RASAUTODIAL
  19. #include <acd.h>
  20. #include <acdapi.h>
  21. //
  22. // Global variables
  23. //
  24. BOOLEAN fAcdLoadedG;
  25. ACD_DRIVER AcdDriverG;
  26. ULONG ulDriverIdG = 'Nbi ';
  27. VOID
  28. NbiRetryTdiConnect(
  29. IN BOOLEAN fSuccess,
  30. IN PVOID *pArgs
  31. )
  32. /*++
  33. Routine Description:
  34. This routine is called indirectly by the automatic
  35. connection driver to continue the connection process
  36. after an automatic connection has been made.
  37. Arguments:
  38. fSuccess - TRUE if the connection attempt was successful.
  39. pArgs - a pointer to the argument vector
  40. Return Value:
  41. None.
  42. --*/
  43. {
  44. NTSTATUS status;
  45. PDEVICE pDevice = pArgs[0];
  46. PCONNECTION pConnection = pArgs[1];
  47. PREQUEST pRequest = pArgs[2];
  48. CTELockHandle ConnectionLH, DeviceLH;
  49. CTELockHandle CancelLH;
  50. BOOLEAN bLockFreed = FALSE;
  51. //
  52. // Check that the connection is valid. This references
  53. // the connection.
  54. //
  55. #if notdef // DBG
  56. DbgPrint("NbiRetryTdiConnect: fSuccess=%d, pConnection=0x%x\n", fSuccess, pConnection);
  57. #endif
  58. status = NbiVerifyConnection(pConnection);
  59. if (!NT_SUCCESS(status)) {
  60. DbgPrint(
  61. "NbiRetryTdiConnect: NbiVerifyConnection failed on connection 0x%x (status=0x%x)\n",
  62. pConnection,
  63. status);
  64. return;
  65. }
  66. NB_GET_CANCEL_LOCK( &CancelLH );
  67. NB_GET_LOCK (&pConnection->Lock, &ConnectionLH);
  68. NB_GET_LOCK (&pDevice->Lock, &DeviceLH);
  69. #if notdef // DBG
  70. DbgPrint(
  71. "NbiRetryTdiConnect: AddressFile=0x%x, DisassociatePending=0x%x, ClosePending=0x%x\n",
  72. pConnection->AddressFile,
  73. pConnection->DisassociatePending,
  74. pConnection->ClosePending);
  75. #endif
  76. if ((pConnection->AddressFile != NULL) &&
  77. (pConnection->AddressFile != (PVOID)-1) &&
  78. (pConnection->DisassociatePending == NULL) &&
  79. (pConnection->ClosePending == NULL))
  80. {
  81. NbiReferenceConnectionLock(pConnection, CREF_CONNECT);
  82. //
  83. // Clear the AUTOCONNECTING flag since we
  84. // done with the automatic connection attempt.
  85. // Set the AUTOCONNECTED flag to prevent us
  86. // from attempting an automatic connection
  87. // for this connection again.
  88. //
  89. pConnection->Flags &= ~CONNECTION_FLAGS_AUTOCONNECTING;
  90. pConnection->Flags |= CONNECTION_FLAGS_AUTOCONNECTED;
  91. pConnection->State = CONNECTION_STATE_CONNECTING;
  92. pConnection->Retries = pDevice->ConnectionCount;
  93. status = NbiTdiConnectFindName(
  94. pDevice,
  95. pRequest,
  96. pConnection,
  97. CancelLH,
  98. ConnectionLH,
  99. DeviceLH,
  100. &bLockFreed);
  101. }
  102. else {
  103. DbgPrint("NbiRetryTdiConnect: Connect on invalid connection 0x%x\n", pConnection);
  104. pConnection->SubState = CONNECTION_SUBSTATE_C_DISCONN;
  105. NB_FREE_LOCK (&pDevice->Lock, DeviceLH);
  106. status = STATUS_INVALID_CONNECTION;
  107. }
  108. if (!bLockFreed) {
  109. NB_FREE_LOCK (&pConnection->Lock, ConnectionLH);
  110. NB_FREE_CANCEL_LOCK(CancelLH);
  111. }
  112. //
  113. // Complete the irp if necessary.
  114. //
  115. if (status != STATUS_PENDING) {
  116. REQUEST_INFORMATION(pRequest) = 0;
  117. REQUEST_STATUS(pRequest) = status;
  118. NbiCompleteRequest(pRequest);
  119. NbiFreeRequest(pDevice, pRequest);
  120. }
  121. NbiDereferenceConnection(pConnection, CREF_VERIFY);
  122. } /* NbiRetryTdiConnect */
  123. BOOLEAN
  124. NbiCancelAutoDialRequest(
  125. IN PVOID pArg,
  126. IN ULONG ulFlags,
  127. IN ACD_CONNECT_CALLBACK pProc,
  128. IN USHORT nArgs,
  129. IN PVOID *pArgs
  130. )
  131. {
  132. #if notdef // DBG
  133. DbgPrint("NbiCancelAutodialRequest: pArg=0x%x\n", pArg);
  134. #endif
  135. if (nArgs != 2)
  136. return FALSE;
  137. return (pArgs[1] == pArg);
  138. } // NbiCancelAutoDialRequest
  139. BOOLEAN
  140. NbiCancelTdiConnect(
  141. IN PDEVICE pDevice,
  142. IN PREQUEST pRequest,
  143. IN PCONNECTION pConnection
  144. )
  145. /*++
  146. DESCRIPTION
  147. This routine is called by the I/O system to cancel a connection
  148. when we are attempting to restore an automatic connection.
  149. ARGUMENTS
  150. pDevice: a pointer to the device object for this driver
  151. pRequest: a pointer to the irp to be cancelled
  152. pConnection: a pointer to the connnection to be cancelled
  153. RETURN VALUE
  154. TRUE if the request was canceled; FALSE otherwise.
  155. --*/
  156. {
  157. ACD_ADDR addr;
  158. //
  159. // Get the address of the connection.
  160. //
  161. addr.fType = ACD_ADDR_NB;
  162. RtlCopyMemory(&addr.cNetbios, pConnection->RemoteName, 16);
  163. #ifdef notdef // DBG
  164. DbgPrint(
  165. "NbiCancelTdiConnect: pIrp=0x%x, RemoteName=%-15.15s, pConnection=0x%x\n",
  166. pRequest,
  167. addr.cNetbios,
  168. pConnection);
  169. #endif
  170. //
  171. // Cancel the autodial request.
  172. //
  173. return (*AcdDriverG.lpfnCancelConnection)(
  174. ulDriverIdG,
  175. &addr,
  176. NbiCancelAutoDialRequest,
  177. pConnection);
  178. } // NbiCancelTdiConnect
  179. BOOLEAN
  180. NbiAttemptAutoDial(
  181. IN PDEVICE pDevice,
  182. IN PCONNECTION pConnection,
  183. IN ULONG ulFlags,
  184. IN ACD_CONNECT_CALLBACK pProc,
  185. IN PREQUEST pRequest
  186. )
  187. /*++
  188. Routine Description:
  189. Call the automatic connection driver to attempt an
  190. automatic connection.
  191. Arguments:
  192. pDevice - a pointer to the DEVICE structure for this connection
  193. pConnection - a pointer to the CONNECTION block for this connection
  194. ulFlags - connection flags to pass to the automatic
  195. connection driver
  196. pProc - a callback procedure when the automatic connection completes
  197. pRequest - a pointer to the request irp
  198. Return Value:
  199. TRUE if the automatic connection was started successfully,
  200. FALSE otherwise.
  201. --*/
  202. {
  203. ACD_ADDR addr;
  204. PVOID pArgs[3];
  205. BOOLEAN bSuccess;
  206. //
  207. // If we've already attempted an automatic connection
  208. // on this connection, don't try it again.
  209. //
  210. if (pConnection->Flags & CONNECTION_FLAGS_AUTOCONNECTED)
  211. return FALSE;
  212. //
  213. // Get the address of the connection.
  214. //
  215. addr.fType = ACD_ADDR_NB;
  216. RtlCopyMemory(&addr.cNetbios, pConnection->RemoteName, 16);
  217. #ifdef notdef // DBG
  218. DbgPrint("NbiAttemptAutoDial: szAddr=%15.15s\n", addr.cNetbios);
  219. #endif
  220. //
  221. // Attempt to start the connection.
  222. // NbiRetryTdiConnect() will be called
  223. // when the connection process has completed.
  224. //
  225. pArgs[0] = pDevice;
  226. pArgs[1] = pConnection;
  227. pArgs[2] = pRequest;
  228. bSuccess = (*AcdDriverG.lpfnStartConnection)(
  229. ulDriverIdG,
  230. &addr,
  231. ulFlags,
  232. pProc,
  233. 3,
  234. pArgs);
  235. if (bSuccess) {
  236. //
  237. // Set the AUTOCONNECTING flag so we know
  238. // to also cancel the connection in the
  239. // automatic connection driver if this
  240. // request gets canceled.
  241. //
  242. pConnection->Flags |= CONNECTION_FLAGS_AUTOCONNECTING;
  243. }
  244. return bSuccess;
  245. } // NbiAttemptAutoDial
  246. VOID
  247. NbiNoteNewConnection(
  248. IN PCONNECTION pConnection
  249. )
  250. {
  251. NTSTATUS status;
  252. ACD_ADDR addr;
  253. ACD_ADAPTER adapter;
  254. ULONG i;
  255. TDI_ADDRESS_IPX tdiIpxAddress;
  256. addr.fType = ACD_ADDR_NB;
  257. RtlCopyMemory(&addr.cNetbios, pConnection->RemoteName, 16);
  258. //
  259. // Determine the mac address of the adapter
  260. // over which the connection has been made.
  261. //
  262. status = (pConnection->Device->Bind.QueryHandler)(
  263. IPX_QUERY_IPX_ADDRESS,
  264. #if defined(_PNP_POWER)
  265. &pConnection->LocalTarget.NicHandle,
  266. #else
  267. pConnection->LocalTarget.NicId,
  268. #endif _PNP_POWER
  269. &tdiIpxAddress,
  270. sizeof(TDI_ADDRESS_IPX),
  271. NULL);
  272. if (status != STATUS_SUCCESS) {
  273. #if notdef // DBG
  274. DbgPrint("NbiNoteNewConnection: QueryHandler(IPX_QUERY_IPX_ADDRESS) failed (status=0x%x)\n", status);
  275. return;
  276. #endif
  277. }
  278. //
  279. // Copy the source mac address to identify
  280. // the adapter.
  281. //
  282. adapter.fType = ACD_ADAPTER_MAC;
  283. for (i = 0; i < 6; i++)
  284. adapter.cMac[i] = tdiIpxAddress.NodeAddress[i];
  285. #if notdef // DBG
  286. DbgPrint(
  287. "NbiNoteNewConnection: address=%-15.15s, remote mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
  288. addr.cNetbios,
  289. adapter.cMac[0],
  290. adapter.cMac[1],
  291. adapter.cMac[2],
  292. adapter.cMac[3],
  293. adapter.cMac[4],
  294. adapter.cMac[5]);
  295. #endif
  296. //
  297. // Simply notify the automatic connection driver
  298. // that a successful connection has been made.
  299. //
  300. (*AcdDriverG.lpfnNewConnection)(
  301. &addr,
  302. &adapter);
  303. } // NbiNoteNewConnection
  304. VOID
  305. NbiAcdBind()
  306. {
  307. NTSTATUS status;
  308. UNICODE_STRING nameString;
  309. IO_STATUS_BLOCK ioStatusBlock;
  310. PIRP pIrp;
  311. PFILE_OBJECT pAcdFileObject;
  312. PDEVICE_OBJECT pAcdDeviceObject;
  313. PACD_DRIVER pDriver = &AcdDriverG;
  314. //
  315. // Initialize the name of the automatic
  316. // connection device.
  317. //
  318. RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME);
  319. //
  320. // Get the file and device objects for the
  321. // device.
  322. //
  323. status = IoGetDeviceObjectPointer(
  324. &nameString,
  325. SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE,
  326. &pAcdFileObject,
  327. &pAcdDeviceObject);
  328. if (status != STATUS_SUCCESS)
  329. return;
  330. //
  331. // Reference the device object.
  332. //
  333. ObReferenceObject(pAcdDeviceObject);
  334. //
  335. // Remove the reference IoGetDeviceObjectPointer()
  336. // put on the file object.
  337. //
  338. ObDereferenceObject(pAcdFileObject);
  339. //
  340. // Initialize our part of the ACD_DRIVER
  341. // structure.
  342. //
  343. KeInitializeSpinLock(&AcdDriverG.SpinLock);
  344. AcdDriverG.ulDriverId = ulDriverIdG;
  345. AcdDriverG.fEnabled = FALSE;
  346. //
  347. // Build a request to get the automatic
  348. // connection driver entry points.
  349. //
  350. pIrp = IoBuildDeviceIoControlRequest(
  351. IOCTL_INTERNAL_ACD_BIND,
  352. pAcdDeviceObject,
  353. (PVOID)&pDriver,
  354. sizeof (pDriver),
  355. NULL,
  356. 0,
  357. TRUE,
  358. NULL,
  359. &ioStatusBlock);
  360. if (pIrp == NULL) {
  361. ObDereferenceObject(pAcdDeviceObject);
  362. return;
  363. }
  364. //
  365. // Submit the request to the
  366. // automatic connection driver.
  367. //
  368. status = IoCallDriver(pAcdDeviceObject, pIrp);
  369. fAcdLoadedG = (status == STATUS_SUCCESS);
  370. //
  371. // Close the device.
  372. //
  373. ObDereferenceObject(pAcdDeviceObject);
  374. } // NbiAcdBind
  375. VOID
  376. NbiAcdUnbind()
  377. {
  378. NTSTATUS status;
  379. UNICODE_STRING nameString;
  380. IO_STATUS_BLOCK ioStatusBlock;
  381. PIRP pIrp;
  382. PFILE_OBJECT pAcdFileObject;
  383. PDEVICE_OBJECT pAcdDeviceObject;
  384. PACD_DRIVER pDriver = &AcdDriverG;
  385. //
  386. // Don't bother to unbind if we
  387. // didn't successfully bind in the
  388. // first place.
  389. //
  390. if (!fAcdLoadedG)
  391. return;
  392. //
  393. // Initialize the name of the automatic
  394. // connection device.
  395. //
  396. RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME);
  397. //
  398. // Get the file and device objects for the
  399. // device.
  400. //
  401. status = IoGetDeviceObjectPointer(
  402. &nameString,
  403. SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE,
  404. &pAcdFileObject,
  405. &pAcdDeviceObject);
  406. if (status != STATUS_SUCCESS)
  407. return;
  408. //
  409. // Reference the device object.
  410. //
  411. ObReferenceObject(pAcdDeviceObject);
  412. //
  413. // Remove the reference IoGetDeviceObjectPointer()
  414. // put on the file object.
  415. //
  416. ObDereferenceObject(pAcdFileObject);
  417. //
  418. // Build a request to unbind from
  419. // the automatic connection driver.
  420. //
  421. pIrp = IoBuildDeviceIoControlRequest(
  422. IOCTL_INTERNAL_ACD_UNBIND,
  423. pAcdDeviceObject,
  424. (PVOID)&pDriver,
  425. sizeof (pDriver),
  426. NULL,
  427. 0,
  428. TRUE,
  429. NULL,
  430. &ioStatusBlock);
  431. if (pIrp == NULL) {
  432. ObDereferenceObject(pAcdDeviceObject);
  433. return;
  434. }
  435. //
  436. // Submit the request to the
  437. // automatic connection driver.
  438. //
  439. status = IoCallDriver(pAcdDeviceObject, pIrp);
  440. //
  441. // Close the device.
  442. //
  443. ObDereferenceObject(pAcdDeviceObject);
  444. } // NbiAcdUnbind
  445. #endif // RASAUTODIAL
  446.