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.

502 lines
11 KiB

  1. /*++
  2. Copyright (c) 1989, 1990, 1991 Microsoft Corporation
  3. Module Name:
  4. autodial.c
  5. Abstract:
  6. This module contains code that interacts with the
  7. automatic connection driver (rasacd.sys):
  8. o NbfNoteNewConnection
  9. o NbfAcdBind
  10. o NbfAcdUnbind
  11. Author:
  12. Anthony Discolo (adiscolo) 6 September 1995
  13. Environment:
  14. Kernel mode
  15. Revision History:
  16. --*/
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. #ifdef RASAUTODIAL
  20. #include <acd.h>
  21. #include <acdapi.h>
  22. //
  23. // Global variables.
  24. //
  25. BOOLEAN fAcdLoadedG;
  26. ACD_DRIVER AcdDriverG;
  27. ULONG ulDriverIdG = 'Nbf ';
  28. BOOLEAN
  29. NbfCancelAutoDialRequest(
  30. IN PVOID pArg,
  31. IN ULONG ulFlags,
  32. IN ACD_CONNECT_CALLBACK pProc,
  33. IN USHORT nArgs,
  34. IN PVOID *pArgs
  35. )
  36. {
  37. if (nArgs != 1)
  38. return FALSE;
  39. return (pArgs[0] == pArg);
  40. } // NbfCancelAutoDialRequest
  41. VOID
  42. NbfRetryTdiConnect(
  43. IN BOOLEAN fSuccess,
  44. IN PVOID *pArgs
  45. )
  46. /*++
  47. Routine Description:
  48. This routine is called indirectly by the automatic
  49. connection driver to continue the connection process
  50. after an automatic connection has been made.
  51. Arguments:
  52. fSuccess - TRUE if the connection attempt was successful.
  53. pArgs - a pointer to the argument vector
  54. Return Value:
  55. None.
  56. --*/
  57. {
  58. NTSTATUS status;
  59. PTP_CONNECTION pConnection = pArgs[0];
  60. KIRQL irql;
  61. BOOL fStopping;
  62. //
  63. // Check for a destroyed connection.
  64. //
  65. if (pConnection == NULL)
  66. return;
  67. status = NbfVerifyConnectionObject(pConnection);
  68. if (status != STATUS_SUCCESS) {
  69. DbgPrint(
  70. "NbfRetryTdiConnect: NbfVerifyConnectionObject failed (status=0x%x)\n",
  71. status);
  72. return;
  73. }
  74. #ifdef notdef // DBG
  75. DbgPrint(
  76. "NbfRetryTdiConnect: fSuccess=%d, pConnection=0x%x, STOPPING=%d\n",
  77. fSuccess,
  78. pConnection,
  79. pConnection->Flags2 & CONNECTION_FLAGS2_STOPPING);
  80. #endif
  81. KeRaiseIrql(DISPATCH_LEVEL, &irql);
  82. //
  83. // Check to see if the connection
  84. // is closing.
  85. //
  86. ACQUIRE_DPC_SPIN_LOCK(&pConnection->SpinLock);
  87. fStopping = (pConnection->Flags2 & CONNECTION_FLAGS2_STOPPING);
  88. //
  89. // Clear the automatic connection
  90. // in-progress flag, and set the
  91. // autoconnected flag.
  92. //
  93. pConnection->Flags2 &= ~CONNECTION_FLAGS2_AUTOCONNECTING;
  94. pConnection->Flags2 |= CONNECTION_FLAGS2_AUTOCONNECTED;
  95. RELEASE_DPC_SPIN_LOCK(&pConnection->SpinLock);
  96. if (!fStopping) {
  97. if (fSuccess) {
  98. //
  99. // Restart the name query.
  100. //
  101. pConnection->Retries =
  102. (USHORT)pConnection->Provider->NameQueryRetries;
  103. NbfSendNameQuery (
  104. pConnection,
  105. TRUE);
  106. NbfStartConnectionTimer (
  107. pConnection,
  108. ConnectionEstablishmentTimeout,
  109. pConnection->Provider->NameQueryTimeout);
  110. }
  111. else {
  112. //
  113. // Terminate the connection with an error.
  114. //
  115. NbfStopConnection(pConnection, STATUS_BAD_NETWORK_PATH);
  116. }
  117. }
  118. KeLowerIrql(irql);
  119. NbfDereferenceConnection ("NbfRetryTdiConnect", pConnection, CREF_BY_ID);
  120. } /* NbfRetryTdiConnect */
  121. BOOLEAN
  122. NbfCancelTdiConnect(
  123. IN PDEVICE_OBJECT pDeviceObject,
  124. IN PIRP pIrp
  125. )
  126. /*++
  127. DESCRIPTION
  128. This routine is called by the I/O system to cancel a connection
  129. when we are attempting to restore an automatic connection.
  130. ARGUMENTS
  131. pDeviceObject: a pointer to the device object for this driver
  132. pIrp: a pointer to the irp to be cancelled
  133. RETURN VALUE
  134. TRUE if the request was canceled; FALSE otherwise.
  135. --*/
  136. {
  137. PIO_STACK_LOCATION pIrpSp;
  138. PTP_CONNECTION pConnection;
  139. ACD_ADDR addr;
  140. UNREFERENCED_PARAMETER(pDeviceObject);
  141. //
  142. // Get a pointer to the current stack location in the IRP. This is where
  143. // the function codes and parameters are stored.
  144. //
  145. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  146. pConnection = pIrpSp->FileObject->FsContext;
  147. if (pConnection == NULL)
  148. return FALSE;
  149. #ifdef notdef // DBG
  150. DbgPrint(
  151. "NbfCancelTdiConnect: pIrp=0x%x, pConnection=0x%x\n",
  152. pIrp,
  153. pConnection);
  154. #endif
  155. //
  156. // Get the address of the connection.
  157. //
  158. addr.fType = ACD_ADDR_NB;
  159. RtlCopyMemory(&addr.cNetbios, pConnection->CalledAddress.NetbiosName, 15);
  160. //
  161. // Cancel the autodial request.
  162. //
  163. return (*AcdDriverG.lpfnCancelConnection)(
  164. ulDriverIdG,
  165. &addr,
  166. NbfCancelAutoDialRequest,
  167. pConnection);
  168. } // NbfCancelTdiConnect
  169. BOOLEAN
  170. NbfAttemptAutoDial(
  171. IN PTP_CONNECTION pConnection,
  172. IN ULONG ulFlags,
  173. IN ACD_CONNECT_CALLBACK pProc,
  174. IN PVOID pArg
  175. )
  176. /*++
  177. Routine Description:
  178. Call the automatic connection driver to attempt an
  179. automatic connection.
  180. Arguments:
  181. pConnection - a pointer to the TP_CONNECTION block for this connection
  182. ulFlags - connection flags to pass to the automatic
  183. connection driver
  184. pProc - a callback procedure when the automatic connection completes
  185. pArg - the single parameter to the callback procedure
  186. Return Value:
  187. TRUE if the automatic connection was started successfully,
  188. FALSE otherwise.
  189. --*/
  190. {
  191. ACD_ADDR addr;
  192. PVOID pArgs[1];
  193. BOOLEAN bSuccess;
  194. //
  195. // If we've already attempted an automatic
  196. // connection on this connection, then
  197. // don't try again.
  198. //
  199. if (pConnection->Flags2 & CONNECTION_FLAGS2_AUTOCONNECTED)
  200. return FALSE;
  201. //
  202. // Get the address of the connection.
  203. //
  204. addr.fType = ACD_ADDR_NB;
  205. RtlCopyMemory(&addr.cNetbios, pConnection->CalledAddress.NetbiosName, 15);
  206. #ifdef notdef // DBG
  207. DbgPrint("NbfAttemptAutoDial: szAddr=%15.15s\n", addr.cNetbios);
  208. #endif
  209. //
  210. // Attempt to start the connection.
  211. // NbfRetryTdiConnect() will be called
  212. // when the connection process has completed.
  213. //
  214. pArgs[0] = pArg;
  215. bSuccess = (*AcdDriverG.lpfnStartConnection)(
  216. ulDriverIdG,
  217. &addr,
  218. ulFlags,
  219. pProc,
  220. 1,
  221. pArgs);
  222. if (bSuccess) {
  223. //
  224. // Set the CONNECTION_FLAGS2_AUTOCONNECTING flag on
  225. // the connection. This will prevent it from being
  226. // aborted during the automatic connection process.
  227. //
  228. pConnection->Flags2 |= CONNECTION_FLAGS2_AUTOCONNECTING;
  229. }
  230. return bSuccess;
  231. } // NbfAttemptAutoDial
  232. VOID
  233. NbfNoteNewConnection(
  234. PTP_CONNECTION pConnection,
  235. PDEVICE_CONTEXT DeviceContext
  236. )
  237. /*++
  238. Routine Description:
  239. Inform the automatic connection driver of a successful
  240. new connection.
  241. Arguments:
  242. Connection - a pointer to a connection object
  243. DeviceContext - a pointer to the device context
  244. Return Value:
  245. None.
  246. --*/
  247. {
  248. KIRQL irql;
  249. ACD_ADDR addr;
  250. ACD_ADAPTER adapter;
  251. ULONG ulcChars;
  252. addr.fType = ACD_ADDR_NB;
  253. RtlCopyMemory(&addr.cNetbios, pConnection->CalledAddress.NetbiosName, 15);
  254. #ifdef notdef // DBG
  255. DbgPrint("NbfNoteNewConnection: szAddr=%15.15s\n", addr.cNetbios);
  256. #endif
  257. //
  258. // Eliminate the "/Device/Nbf_" prefix when
  259. // copying the adapter name.
  260. //
  261. adapter.fType = ACD_ADAPTER_NAME;
  262. ulcChars = DeviceContext->DeviceNameLength / sizeof(WCHAR) - 1 - 12;
  263. if (ulcChars >= ACD_ADAPTER_NAME_LEN)
  264. ulcChars = ACD_ADAPTER_NAME_LEN - 1;
  265. RtlCopyMemory(
  266. adapter.szName,
  267. &DeviceContext->DeviceName[12],
  268. ulcChars * sizeof (WCHAR));
  269. adapter.szName[ulcChars] = L'\0';
  270. //
  271. // Simply notify the automatic connection driver
  272. // that a successful connection has been made.
  273. //
  274. (*AcdDriverG.lpfnNewConnection)(
  275. &addr,
  276. &adapter);
  277. } // NbfNoteNewConnection
  278. VOID
  279. NbfAcdBind()
  280. {
  281. NTSTATUS status;
  282. UNICODE_STRING nameString;
  283. IO_STATUS_BLOCK ioStatusBlock;
  284. PIRP pIrp;
  285. PFILE_OBJECT pAcdFileObject;
  286. PDEVICE_OBJECT pAcdDeviceObject;
  287. PACD_DRIVER pDriver = &AcdDriverG;
  288. //
  289. // Initialize the name of the automatic
  290. // connection device.
  291. //
  292. RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME);
  293. //
  294. // Get the file and device objects for the
  295. // device.
  296. //
  297. status = IoGetDeviceObjectPointer(
  298. &nameString,
  299. SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE,
  300. &pAcdFileObject,
  301. &pAcdDeviceObject);
  302. if (status != STATUS_SUCCESS)
  303. return;
  304. //
  305. // Reference the device object.
  306. //
  307. ObReferenceObject(pAcdDeviceObject);
  308. //
  309. // Remove the reference IoGetDeviceObjectPointer()
  310. // put on the file object.
  311. //
  312. ObDereferenceObject(pAcdFileObject);
  313. //
  314. // Initialize our part of the ACD_DRIVER
  315. // structure.
  316. //
  317. KeInitializeSpinLock(&AcdDriverG.SpinLock);
  318. AcdDriverG.ulDriverId = ulDriverIdG;
  319. AcdDriverG.fEnabled = FALSE;
  320. //
  321. // Build a request to get the automatic
  322. // connection driver entry points.
  323. //
  324. pIrp = IoBuildDeviceIoControlRequest(
  325. IOCTL_INTERNAL_ACD_BIND,
  326. pAcdDeviceObject,
  327. (PVOID)&pDriver,
  328. sizeof (pDriver),
  329. NULL,
  330. 0,
  331. TRUE,
  332. NULL,
  333. &ioStatusBlock);
  334. if (pIrp == NULL) {
  335. ObDereferenceObject(pAcdDeviceObject);
  336. return;
  337. }
  338. //
  339. // Submit the request to the
  340. // automatic connection driver.
  341. //
  342. status = IoCallDriver(pAcdDeviceObject, pIrp);
  343. fAcdLoadedG = (status == STATUS_SUCCESS);
  344. //
  345. // Close the device.
  346. //
  347. ObDereferenceObject(pAcdDeviceObject);
  348. } // NbfAcdBind
  349. VOID
  350. NbfAcdUnbind()
  351. {
  352. NTSTATUS status;
  353. UNICODE_STRING nameString;
  354. IO_STATUS_BLOCK ioStatusBlock;
  355. PIRP pIrp;
  356. PFILE_OBJECT pAcdFileObject;
  357. PDEVICE_OBJECT pAcdDeviceObject;
  358. PACD_DRIVER pDriver = &AcdDriverG;
  359. //
  360. // Don't bother to unbind if we
  361. // didn't successfully bind in the
  362. // first place.
  363. //
  364. if (!fAcdLoadedG)
  365. return;
  366. //
  367. // Initialize the name of the automatic
  368. // connection device.
  369. //
  370. RtlInitUnicodeString(&nameString, ACD_DEVICE_NAME);
  371. //
  372. // Get the file and device objects for the
  373. // device.
  374. //
  375. status = IoGetDeviceObjectPointer(
  376. &nameString,
  377. SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE,
  378. &pAcdFileObject,
  379. &pAcdDeviceObject);
  380. if (status != STATUS_SUCCESS)
  381. return;
  382. //
  383. // Reference the device object.
  384. //
  385. ObReferenceObject(pAcdDeviceObject);
  386. //
  387. // Remove the reference IoGetDeviceObjectPointer()
  388. // put on the file object.
  389. //
  390. ObDereferenceObject(pAcdFileObject);
  391. //
  392. // Build a request to unbind from
  393. // the automatic connection driver.
  394. //
  395. pIrp = IoBuildDeviceIoControlRequest(
  396. IOCTL_INTERNAL_ACD_UNBIND,
  397. pAcdDeviceObject,
  398. (PVOID)&pDriver,
  399. sizeof (pDriver),
  400. NULL,
  401. 0,
  402. TRUE,
  403. NULL,
  404. &ioStatusBlock);
  405. if (pIrp == NULL) {
  406. ObDereferenceObject(pAcdDeviceObject);
  407. return;
  408. }
  409. //
  410. // Submit the request to the
  411. // automatic connection driver.
  412. //
  413. status = IoCallDriver(pAcdDeviceObject, pIrp);
  414. //
  415. // Close the device.
  416. //
  417. ObDereferenceObject(pAcdDeviceObject);
  418. } // NbfAcdUnbind
  419. #endif // RASAUTODIAL
  420.