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.

1165 lines
28 KiB

  1. /*++
  2. Copyright (c) 1991 - 2001 Microsoft Corporation
  3. Module Name:
  4. ##### ## ## ##### ##### ##### ###### ### #### ##### #####
  5. ## ## ## ## ## ## ## ## ## ## ## # ## # ## ## ## ##
  6. ## #### ## ## ## ## ## ## ## ### ## ## ## ## ##
  7. ##### ## ## ## ## ## ##### ## ### ## ## ## ## ##
  8. ## #### ##### ## ## #### ## ### ## ##### #####
  9. ## ## ## ## ## ## ## ## ## # ## ## ## # ## ##
  10. ##### ## ## ## ##### ## ## ## ### ## #### ## ##
  11. Abstract:
  12. This module contains the code for all fundtions that
  13. are exported by the Server Appliance port driver for
  14. use by the mini-port drivers.
  15. Author:
  16. Wesley Witt (wesw) 1-Oct-2001
  17. Environment:
  18. Kernel mode only.
  19. Notes:
  20. --*/
  21. #include "internal.h"
  22. #include <ntimage.h>
  23. PVOID
  24. SaPortAllocatePool(
  25. IN PVOID MiniPortDeviceExtension,
  26. IN SIZE_T NumberOfBytes
  27. )
  28. /*++
  29. Routine Description:
  30. This routine is a wrapper for ExAllocatePool, but enforces
  31. pool tagging by using the associated miniport's driver name
  32. for the pool tag.
  33. Arguments:
  34. MiniPortDeviceExtension - Pointer to the miniport's device extension
  35. NumberOfBytes - Number of bytes to allocate
  36. Return Value:
  37. Pointer to the allocated pool or NULL for failure.
  38. --*/
  39. {
  40. PDEVICE_EXTENSION DeviceExtension;
  41. ULONG DeviceType;
  42. ULONG PoolTag;
  43. if (MiniPortDeviceExtension) {
  44. DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  45. DeviceType = DeviceExtension->InitData->DeviceType;
  46. } else {
  47. DeviceType = 0;
  48. }
  49. switch (DeviceType) {
  50. case SA_DEVICE_DISPLAY:
  51. PoolTag = 'sDaS';
  52. break;
  53. case SA_DEVICE_KEYPAD:
  54. PoolTag = 'pKaS';
  55. break;
  56. case SA_DEVICE_NVRAM:
  57. PoolTag = 'vNaS';
  58. break;
  59. case SA_DEVICE_WATCHDOG:
  60. PoolTag = 'dWaS';
  61. break;
  62. default:
  63. PoolTag = 'tPaS';
  64. break;
  65. }
  66. return ExAllocatePoolWithTag( NonPagedPool, NumberOfBytes, PoolTag );
  67. }
  68. VOID
  69. SaPortFreePool(
  70. IN PVOID MiniPortDeviceExtension,
  71. IN PVOID PoolMemory
  72. )
  73. /*++
  74. Routine Description:
  75. This routine is a wrapper for ExFreePool, but enforces
  76. pool tagging by using the associated miniport's driver name
  77. for the pool tag.
  78. Arguments:
  79. MiniPortDeviceExtension - Pointer to the miniport's device extension
  80. PoolMemory - Pointer to the previously allocated pool
  81. Return Value:
  82. None.
  83. --*/
  84. {
  85. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  86. ULONG PoolTag;
  87. switch (DeviceExtension->InitData->DeviceType) {
  88. case SA_DEVICE_DISPLAY:
  89. PoolTag = 'sDaS';
  90. break;
  91. case SA_DEVICE_KEYPAD:
  92. PoolTag = 'pKaS';
  93. break;
  94. case SA_DEVICE_NVRAM:
  95. PoolTag = 'vNaS';
  96. break;
  97. case SA_DEVICE_WATCHDOG:
  98. PoolTag = 'dWaS';
  99. break;
  100. }
  101. ExFreePoolWithTag( PoolMemory, PoolTag );
  102. }
  103. PVOID
  104. SaPortGetVirtualAddress(
  105. IN PVOID MiniPortDeviceExtension,
  106. IN PHYSICAL_ADDRESS PhysicalAddress,
  107. IN ULONG Length
  108. )
  109. /*++
  110. Routine Description:
  111. This routine is a wrapper for MmMapIoSpace and simply provides a
  112. virtual memory address to access a physical resource.
  113. Arguments:
  114. MiniPortDeviceExtension - Pointer to the miniport's device extension
  115. PhysicalAddress - Physical memory address
  116. Length - Length of the memory space
  117. Return Value:
  118. None.
  119. --*/
  120. {
  121. return MmMapIoSpace( PhysicalAddress, Length, MmNonCached );
  122. }
  123. VOID
  124. SaPortRequestDpc(
  125. IN PVOID MiniPortDeviceExtension,
  126. IN PVOID Context
  127. )
  128. /*++
  129. Routine Description:
  130. This routine is a wrapper for IoRequestDpc.
  131. Arguments:
  132. MiniPortDeviceExtension - Pointer to the miniport's device extension
  133. Context - Miniport supplied context pointer
  134. Return Value:
  135. None.
  136. --*/
  137. {
  138. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  139. IoRequestDpc( DeviceExtension->DeviceObject, MiniPortDeviceExtension, Context );
  140. }
  141. VOID
  142. SaPortCompleteRequest(
  143. IN PVOID MiniPortDeviceExtension,
  144. IN PIRP Irp,
  145. IN ULONG Information,
  146. IN NTSTATUS Status,
  147. IN BOOLEAN CompleteAll
  148. )
  149. /*++
  150. Routine Description:
  151. This routine is use by all miniports to complete the currently processed IRP.
  152. The caller can optionally request that all oustanding I/Os be completed. This is
  153. accomplished by removing all IRPs from the device queue and processing the I/O.
  154. Arguments:
  155. MiniPortDeviceExtension - Pointer to the miniport's device extension
  156. Information - Informational, request specific data
  157. Status - NT status value
  158. CompleteAll - TRUE for completion of all outstanding I/O requests, otherwise FALSE
  159. Return Value:
  160. None.
  161. --*/
  162. {
  163. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  164. PKDEVICE_QUEUE_ENTRY Packet;
  165. KIRQL CancelIrql;
  166. PIRP ThisIrp;
  167. if (Irp) {
  168. CompleteRequest( Irp, Status, Information );
  169. return;
  170. }
  171. if (DeviceExtension->DeviceObject->CurrentIrp == NULL) {
  172. return;
  173. }
  174. CompleteRequest( DeviceExtension->DeviceObject->CurrentIrp, Status, Information );
  175. if (CompleteAll) {
  176. while (1) {
  177. IoAcquireCancelSpinLock( &CancelIrql );
  178. Packet = KeRemoveDeviceQueue( &DeviceExtension->DeviceObject->DeviceQueue );
  179. if (Packet == NULL) {
  180. IoReleaseCancelSpinLock( CancelIrql );
  181. break;
  182. }
  183. ThisIrp = CONTAINING_RECORD( Packet, IRP, Tail.Overlay.DeviceQueueEntry );
  184. IoReleaseCancelSpinLock( CancelIrql );
  185. SaPortStartIo( DeviceExtension->DeviceObject, ThisIrp );
  186. }
  187. } else {
  188. IoStartNextPacket( DeviceExtension->DeviceObject, TRUE );
  189. }
  190. IoReleaseRemoveLock( &DeviceExtension->RemoveLock, DeviceExtension->DeviceObject->CurrentIrp );
  191. }
  192. BOOLEAN
  193. SaPortSynchronizeExecution (
  194. IN PVOID MiniPortDeviceExtension,
  195. IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
  196. IN PVOID SynchronizeContext
  197. )
  198. /*++
  199. Routine Description:
  200. This routine is a wrapper for KeSynchronizeExecution.
  201. Arguments:
  202. MiniPortDeviceExtension - Pointer to the miniport's device extension
  203. SynchronizeRoutine - Is the entry point for a caller-supplied SynchCritSection routine whose execution is to be
  204. synchronized with the execution of the ISR associated with the interrupt objects.
  205. SynchronizeContext - Pointer to a caller-supplied context area to be passed to the SynchronizeRoutine when it is called.
  206. Return Value:
  207. None.
  208. --*/
  209. {
  210. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  211. if (DeviceExtension->InterruptObject == NULL) {
  212. return FALSE;
  213. }
  214. return KeSynchronizeExecution(
  215. DeviceExtension->InterruptObject,
  216. SynchronizeRoutine,
  217. SynchronizeContext
  218. );
  219. }
  220. ULONG
  221. SaPortGetOsVersion(
  222. VOID
  223. )
  224. /*++
  225. Routine Description:
  226. This routine provides access to the OS version on which the minport is running.
  227. The OS version value is obtained at DriverEntry time.
  228. Arguments:
  229. None.
  230. Return Value:
  231. OS Version data.
  232. --*/
  233. {
  234. return (ULONG)((OsMajorVersion << 16) | (OsMinorVersion & 0xffff));
  235. }
  236. NTSTATUS
  237. SaPortGetRegistryValueInformation(
  238. IN PVOID MiniPortDeviceExtension,
  239. IN PWSTR ValueName,
  240. IN OUT PULONG RegistryType,
  241. IN OUT PULONG RegistryDataLength
  242. )
  243. {
  244. NTSTATUS status;
  245. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  246. PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
  247. __try {
  248. status = ReadRegistryValue(
  249. DeviceExtension->DriverExtension,
  250. &DeviceExtension->DriverExtension->RegistryPath,
  251. ValueName,
  252. &KeyInformation
  253. );
  254. if (!NT_SUCCESS(status)) {
  255. __leave;
  256. }
  257. *RegistryType = KeyInformation->Type;
  258. *RegistryDataLength = KeyInformation->DataLength;
  259. status = STATUS_SUCCESS;
  260. } __finally {
  261. if (KeyInformation) {
  262. ExFreePool( KeyInformation );
  263. }
  264. }
  265. return status;
  266. }
  267. NTSTATUS
  268. SaPortDeleteRegistryValue(
  269. IN PVOID MiniPortDeviceExtension,
  270. IN PWSTR ValueName
  271. )
  272. {
  273. NTSTATUS status;
  274. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  275. UNICODE_STRING unicodeString;
  276. HANDLE parametersKey = NULL;
  277. __try {
  278. status = OpenParametersRegistryKey(
  279. DeviceExtension->DriverExtension,
  280. &DeviceExtension->DriverExtension->RegistryPath,
  281. KEY_ALL_ACCESS,
  282. &parametersKey
  283. );
  284. if (!NT_SUCCESS(status)) {
  285. ERROR_RETURN( DeviceExtension->DeviceType, "OpenParametersRegistryKey failed", status );
  286. }
  287. RtlInitUnicodeString( &unicodeString, ValueName );
  288. status = ZwDeleteValueKey(
  289. parametersKey,
  290. &unicodeString
  291. );
  292. if (!NT_SUCCESS(status)) {
  293. ERROR_RETURN( DeviceExtension->DeviceType, "ZwDeleteValueKey failed", status );
  294. }
  295. status = STATUS_SUCCESS;
  296. } __finally {
  297. if (parametersKey) {
  298. ZwClose( parametersKey );
  299. }
  300. }
  301. return status;
  302. }
  303. NTSTATUS
  304. SaPortReadNumericRegistryValue(
  305. IN PVOID MiniPortDeviceExtension,
  306. IN PWSTR ValueName,
  307. OUT PULONG RegistryValue
  308. )
  309. /*++
  310. Routine Description:
  311. This routine provides access to the miniport driver's registry parameters.
  312. This function returns a numeric (REG_DWORD) data value.
  313. Arguments:
  314. MiniPortDeviceExtension - Pointer to the miniport's device extension
  315. ValueName - Name of the registry value to read
  316. RegistryValue - Pointer to a ULONG that holds the registry data
  317. Return Value:
  318. NT status code.
  319. --*/
  320. {
  321. NTSTATUS status;
  322. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  323. PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
  324. __try {
  325. status = ReadRegistryValue(
  326. DeviceExtension->DriverExtension,
  327. &DeviceExtension->DriverExtension->RegistryPath,
  328. ValueName,
  329. &KeyInformation
  330. );
  331. if (!NT_SUCCESS(status)) {
  332. __leave;
  333. }
  334. if (KeyInformation->Type != REG_DWORD) {
  335. status = STATUS_OBJECT_TYPE_MISMATCH;
  336. __leave;
  337. }
  338. RtlCopyMemory( RegistryValue, (PUCHAR)KeyInformation + KeyInformation->DataOffset, sizeof(ULONG) );
  339. status = STATUS_SUCCESS;
  340. } __finally {
  341. if (KeyInformation) {
  342. ExFreePool( KeyInformation );
  343. }
  344. }
  345. return status;
  346. }
  347. NTSTATUS
  348. SaPortWriteNumericRegistryValue(
  349. IN PVOID MiniPortDeviceExtension,
  350. IN PWSTR ValueName,
  351. IN ULONG RegistryValue
  352. )
  353. /*++
  354. Routine Description:
  355. This routine provides access to the miniport driver's registry parameters.
  356. This function returns a numeric (REG_DWORD) data value.
  357. Arguments:
  358. MiniPortDeviceExtension - Pointer to the miniport's device extension
  359. ValueName - Name of the registry value to read
  360. RegistryValue - Pointer to a ULONG that holds the registry data
  361. Return Value:
  362. NT status code.
  363. --*/
  364. {
  365. NTSTATUS Status;
  366. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  367. __try {
  368. Status = WriteRegistryValue(
  369. DeviceExtension->DriverExtension,
  370. &DeviceExtension->DriverExtension->RegistryPath,
  371. ValueName,
  372. REG_DWORD,
  373. &RegistryValue,
  374. sizeof(ULONG)
  375. );
  376. if (!NT_SUCCESS(Status)) {
  377. __leave;
  378. }
  379. Status = STATUS_SUCCESS;
  380. } __finally {
  381. }
  382. return Status;
  383. }
  384. NTSTATUS
  385. SaPortReadBinaryRegistryValue(
  386. IN PVOID MiniPortDeviceExtension,
  387. IN PWSTR ValueName,
  388. OUT PVOID RegistryValue,
  389. IN OUT PULONG RegistryValueLength
  390. )
  391. /*++
  392. Routine Description:
  393. This routine provides access to the miniport driver's registry parameters.
  394. This function returns a numeric (REG_DWORD) data value.
  395. Arguments:
  396. MiniPortDeviceExtension - Pointer to the miniport's device extension
  397. ValueName - Name of the registry value to read
  398. RegistryValue - Pointer to a ULONG that holds the registry data
  399. Return Value:
  400. NT status code.
  401. --*/
  402. {
  403. NTSTATUS status;
  404. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  405. PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
  406. __try {
  407. status = ReadRegistryValue(
  408. DeviceExtension->DriverExtension,
  409. &DeviceExtension->DriverExtension->RegistryPath,
  410. ValueName,
  411. &KeyInformation
  412. );
  413. if (!NT_SUCCESS(status)) {
  414. __leave;
  415. }
  416. if (KeyInformation->Type != REG_BINARY) {
  417. status = STATUS_OBJECT_TYPE_MISMATCH;
  418. __leave;
  419. }
  420. if (*RegistryValueLength < KeyInformation->DataLength) {
  421. *RegistryValueLength = KeyInformation->DataLength;
  422. status = STATUS_BUFFER_TOO_SMALL;
  423. __leave;
  424. }
  425. RtlCopyMemory( RegistryValue, (PUCHAR)KeyInformation + KeyInformation->DataOffset, KeyInformation->DataLength );
  426. status = STATUS_SUCCESS;
  427. } __finally {
  428. if (KeyInformation) {
  429. ExFreePool( KeyInformation );
  430. }
  431. }
  432. return status;
  433. }
  434. NTSTATUS
  435. SaPortWriteBinaryRegistryValue(
  436. IN PVOID MiniPortDeviceExtension,
  437. IN PWSTR ValueName,
  438. IN PVOID RegistryValue,
  439. IN ULONG RegistryValueLength
  440. )
  441. /*++
  442. Routine Description:
  443. This routine provides access to the miniport driver's registry parameters.
  444. This function returns a numeric (REG_DWORD) data value.
  445. Arguments:
  446. MiniPortDeviceExtension - Pointer to the miniport's device extension
  447. ValueName - Name of the registry value to read
  448. RegistryValue - Pointer to a ULONG that holds the registry data
  449. Return Value:
  450. NT status code.
  451. --*/
  452. {
  453. NTSTATUS Status;
  454. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  455. __try {
  456. Status = WriteRegistryValue(
  457. DeviceExtension->DriverExtension,
  458. &DeviceExtension->DriverExtension->RegistryPath,
  459. ValueName,
  460. REG_BINARY,
  461. RegistryValue,
  462. RegistryValueLength
  463. );
  464. if (!NT_SUCCESS(Status)) {
  465. __leave;
  466. }
  467. Status = STATUS_SUCCESS;
  468. } __finally {
  469. }
  470. return Status;
  471. }
  472. NTSTATUS
  473. SaPortReadUnicodeStringRegistryValue(
  474. IN PVOID MiniPortDeviceExtension,
  475. IN PWSTR ValueName,
  476. OUT PUNICODE_STRING RegistryValue
  477. )
  478. /*++
  479. Routine Description:
  480. This routine provides access to the miniport driver's registry parameters.
  481. This function returns a UNICODE_STRING representation of REG_SZ registry data.
  482. Arguments:
  483. MiniPortDeviceExtension - Pointer to the miniport's device extension
  484. ValueName - Name of the registry value to read
  485. RegistryValue - Pointer to a UNICODE_STRING that holds the registry data
  486. Return Value:
  487. NT status code.
  488. --*/
  489. {
  490. NTSTATUS status;
  491. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  492. PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
  493. __try {
  494. status = ReadRegistryValue(
  495. DeviceExtension->DriverExtension,
  496. &DeviceExtension->DriverExtension->RegistryPath,
  497. ValueName,
  498. &KeyInformation
  499. );
  500. if (!NT_SUCCESS(status)) {
  501. __leave;
  502. }
  503. if (KeyInformation->Type != REG_SZ) {
  504. status = STATUS_OBJECT_TYPE_MISMATCH;
  505. __leave;
  506. }
  507. RegistryValue->Buffer = (PWSTR) ExAllocatePool( NonPagedPool, KeyInformation->DataLength );
  508. if (RegistryValue->Buffer == NULL) {
  509. status = STATUS_INSUFFICIENT_RESOURCES;
  510. __leave;
  511. }
  512. RtlCopyMemory( RegistryValue->Buffer, (PUCHAR)KeyInformation + KeyInformation->DataOffset, KeyInformation->DataLength );
  513. RegistryValue->Length = (USHORT) KeyInformation->DataLength;
  514. RegistryValue->MaximumLength = RegistryValue->Length;
  515. status = STATUS_SUCCESS;
  516. } __finally {
  517. if (KeyInformation) {
  518. ExFreePool( KeyInformation );
  519. }
  520. if (!NT_SUCCESS(status)) {
  521. if (RegistryValue->Buffer) {
  522. ExFreePool( RegistryValue->Buffer );
  523. }
  524. }
  525. }
  526. return status;
  527. }
  528. NTSTATUS
  529. SaPortWriteUnicodeStringRegistryValue(
  530. IN PVOID MiniPortDeviceExtension,
  531. IN PWSTR ValueName,
  532. IN PUNICODE_STRING RegistryValue
  533. )
  534. /*++
  535. Routine Description:
  536. This routine provides access to the miniport driver's registry parameters.
  537. This function returns a UNICODE_STRING representation of REG_SZ registry data.
  538. Arguments:
  539. MiniPortDeviceExtension - Pointer to the miniport's device extension
  540. ValueName - Name of the registry value to read
  541. RegistryValue - Pointer to a UNICODE_STRING that holds the registry data
  542. Return Value:
  543. NT status code.
  544. --*/
  545. {
  546. NTSTATUS Status;
  547. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  548. __try {
  549. Status = WriteRegistryValue(
  550. DeviceExtension->DriverExtension,
  551. &DeviceExtension->DriverExtension->RegistryPath,
  552. ValueName,
  553. REG_SZ,
  554. RegistryValue->Buffer,
  555. RegistryValue->Length
  556. );
  557. if (!NT_SUCCESS(Status)) {
  558. __leave;
  559. }
  560. Status = STATUS_SUCCESS;
  561. } __finally {
  562. }
  563. return Status;
  564. }
  565. PVOID
  566. SaPortLockPagesForSystem(
  567. IN PVOID MiniPortDeviceExtension,
  568. IN PVOID UserBuffer,
  569. IN ULONG UserBufferLength,
  570. IN OUT PMDL *Mdl
  571. )
  572. /*++
  573. Routine Description:
  574. This routine obtains a virtual address that is locked down
  575. and usable by the miniport driver at all times.
  576. Arguments:
  577. MiniPortDeviceExtension - Pointer to the miniport's device extension
  578. UserBuffer - User buffer that is passed to the miniport
  579. UserBufferLength - Length in bytes of the UserBuffer
  580. Mdl - MDL that is created by this routine
  581. Return Value:
  582. Virtual system address for the UserBuffer
  583. --*/
  584. {
  585. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  586. if (Mdl == NULL) {
  587. return NULL;
  588. }
  589. *Mdl = NULL;
  590. __try {
  591. *Mdl = IoAllocateMdl( UserBuffer, UserBufferLength, FALSE, TRUE, NULL );
  592. } __except(EXCEPTION_EXECUTE_HANDLER) {
  593. *Mdl = NULL;
  594. }
  595. if (*Mdl == NULL) {
  596. return NULL;
  597. }
  598. __try {
  599. MmProbeAndLockPages( *Mdl, KernelMode , IoWriteAccess );
  600. } __except(EXCEPTION_EXECUTE_HANDLER) {
  601. IoFreeMdl( *Mdl );
  602. }
  603. return MmGetSystemAddressForMdlSafe( *Mdl, NormalPagePriority );
  604. }
  605. VOID
  606. SaPortReleaseLockedPagesForSystem(
  607. IN PVOID MiniPortDeviceExtension,
  608. IN PMDL Mdl
  609. )
  610. /*++
  611. Routine Description:
  612. This routine releases the resources with a previously allocated MDL.
  613. Arguments:
  614. MiniPortDeviceExtension - Pointer to the miniport's device extension
  615. Mdl - MDL that is created by SaPortLockPagesForSystem
  616. Return Value:
  617. None.
  618. --*/
  619. {
  620. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  621. MmUnlockPages( Mdl );
  622. IoFreeMdl( Mdl );
  623. }
  624. NTSTATUS
  625. SaPortCopyUnicodeString(
  626. IN PVOID MiniPortDeviceExtension,
  627. IN PUNICODE_STRING DestinationString,
  628. IN OUT PUNICODE_STRING SourceString
  629. )
  630. /*++
  631. Routine Description:
  632. This routine copies a UNICODE_STRING from a source to a
  633. destination, but allocates a new buffer from pool first.
  634. Arguments:
  635. DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
  636. SourceString - Source UNICODE_STRING for the copy
  637. Return Value:
  638. NT status code
  639. --*/
  640. {
  641. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  642. DestinationString->Buffer = (PWSTR) SaPortAllocatePool( MiniPortDeviceExtension, SourceString->MaximumLength );
  643. if (DestinationString->Buffer == NULL) {
  644. REPORT_ERROR( DeviceExtension->DeviceType, "Failed to allocate pool for string", STATUS_INSUFFICIENT_RESOURCES );
  645. return STATUS_INSUFFICIENT_RESOURCES;
  646. }
  647. RtlCopyMemory( DestinationString->Buffer, SourceString->Buffer, SourceString->Length );
  648. DestinationString->Length = SourceString->Length;
  649. DestinationString->MaximumLength = SourceString->MaximumLength;
  650. return STATUS_SUCCESS;
  651. }
  652. NTSTATUS
  653. SaPortCreateUnicodeString(
  654. IN PVOID MiniPortDeviceExtension,
  655. IN PUNICODE_STRING DestinationString,
  656. IN PWSTR SourceString
  657. )
  658. /*++
  659. Routine Description:
  660. This routine creates a new UNICODE_STRING from pool
  661. and initializes it with the source string.
  662. Arguments:
  663. DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
  664. SourceString - Source character string
  665. Return Value:
  666. NT status code
  667. --*/
  668. {
  669. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  670. DestinationString->Length = wcslen(SourceString) * sizeof(WCHAR);
  671. DestinationString->MaximumLength = DestinationString->Length;
  672. DestinationString->Buffer = (PWSTR) SaPortAllocatePool( MiniPortDeviceExtension, DestinationString->Length+2 );
  673. if (DestinationString->Buffer == NULL) {
  674. REPORT_ERROR( DeviceExtension->DeviceType, "Failed to allocate pool for string", STATUS_INSUFFICIENT_RESOURCES );
  675. return STATUS_INSUFFICIENT_RESOURCES;
  676. }
  677. RtlZeroMemory( DestinationString->Buffer, DestinationString->Length+2 );
  678. RtlCopyMemory( DestinationString->Buffer, SourceString, DestinationString->Length );
  679. return STATUS_SUCCESS;
  680. }
  681. NTSTATUS
  682. SaPortCreateUnicodeStringCat(
  683. IN PVOID MiniPortDeviceExtension,
  684. IN PUNICODE_STRING DestinationString,
  685. IN PWSTR SourceString1,
  686. IN PWSTR SourceString2
  687. )
  688. /*++
  689. Routine Description:
  690. This routine creates a new UNICODE_STRING from pool
  691. and initializes it with the two source strings by
  692. concatinating them together.
  693. Arguments:
  694. DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
  695. SourceString1 - Source character string
  696. SourceString2 - Source character string
  697. Return Value:
  698. NT status code
  699. --*/
  700. {
  701. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  702. DestinationString->Length = STRING_SZ(SourceString1) + STRING_SZ(SourceString2);
  703. DestinationString->MaximumLength = DestinationString->Length;
  704. DestinationString->Buffer = (PWSTR) SaPortAllocatePool( MiniPortDeviceExtension, DestinationString->Length+2 );
  705. if (DestinationString->Buffer == NULL) {
  706. REPORT_ERROR( DeviceExtension->DeviceType, "Failed to allocate pool for string", STATUS_INSUFFICIENT_RESOURCES );
  707. return STATUS_INSUFFICIENT_RESOURCES;
  708. }
  709. RtlZeroMemory( DestinationString->Buffer, DestinationString->Length+2 );
  710. RtlCopyMemory( DestinationString->Buffer, SourceString1, STRING_SZ(SourceString1) );
  711. RtlCopyMemory( ((PUCHAR)DestinationString->Buffer)+STRING_SZ(SourceString1), SourceString2, STRING_SZ(SourceString2) );
  712. return STATUS_SUCCESS;
  713. }
  714. VOID
  715. SaPortFreeUnicodeString(
  716. IN PVOID MiniPortDeviceExtension,
  717. IN PUNICODE_STRING SourceString
  718. )
  719. /*++
  720. Routine Description:
  721. This routine creates a new UNICODE_STRING from pool
  722. and initializes it with the two source strings by
  723. concatinating them together.
  724. Arguments:
  725. DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
  726. SourceString1 - Source character string
  727. SourceString2 - Source character string
  728. Return Value:
  729. NT status code
  730. --*/
  731. {
  732. SaPortFreePool( MiniPortDeviceExtension, SourceString->Buffer );
  733. SourceString->Buffer = NULL;
  734. SourceString->MaximumLength = 0;
  735. SourceString->MaximumLength = 0;
  736. }
  737. extern "C" PACL SePublicDefaultDacl;
  738. NTSTATUS
  739. SaPortCreateBasenamedEvent(
  740. IN PVOID MiniPortDeviceExtension,
  741. IN PWSTR EventNameString,
  742. IN OUT PKEVENT *Event,
  743. IN OUT PHANDLE EventHandle
  744. )
  745. {
  746. NTSTATUS Status;
  747. PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
  748. UNICODE_STRING EventName;
  749. PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  750. OBJECT_ATTRIBUTES objectAttributes;
  751. __try {
  752. SecurityDescriptor = (PSECURITY_DESCRIPTOR) SaPortAllocatePool( DeviceExtension, 4096 );
  753. if (SecurityDescriptor == NULL) {
  754. Status = STATUS_INSUFFICIENT_RESOURCES;
  755. ERROR_RETURN( DeviceExtension->DeviceType, "Could not allocate pool for security descriptor", Status );
  756. }
  757. Status = RtlCreateSecurityDescriptor( SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
  758. if (!NT_SUCCESS(Status)) {
  759. ERROR_RETURN( DeviceExtension->DeviceType, "RtlCreateSecurityDescriptor failed", Status );
  760. }
  761. Status = RtlSetDaclSecurityDescriptor( SecurityDescriptor, TRUE, *(PACL*)SePublicDefaultDacl, FALSE );
  762. if (!NT_SUCCESS(Status)) {
  763. ERROR_RETURN( DeviceExtension->DeviceType, "RtlSetDaclSecurityDescriptor failed", Status );
  764. }
  765. Status = SaPortCreateUnicodeStringCat( MiniPortDeviceExtension, &EventName, L"\\BaseNamedObjects\\", EventNameString );
  766. if (!NT_SUCCESS(Status)) {
  767. ERROR_RETURN( DeviceExtension->DeviceType, "SaPortCreateUnicodeStringCat failed", Status );
  768. }
  769. InitializeObjectAttributes( &objectAttributes, &EventName, OBJ_OPENIF, NULL, SecurityDescriptor );
  770. Status = ZwCreateEvent( EventHandle, EVENT_ALL_ACCESS, &objectAttributes, SynchronizationEvent, TRUE );
  771. if (!NT_SUCCESS(Status)) {
  772. ERROR_RETURN( DeviceExtension->DeviceType, "ZwCreateEvent failed", Status );
  773. }
  774. Status = ObReferenceObjectByHandle( *EventHandle, 0, NULL, KernelMode, (PVOID*)Event, NULL );
  775. if (!NT_SUCCESS(Status)) {
  776. ERROR_RETURN( DeviceExtension->DeviceType, "ObReferenceObjectByHandle failed", Status );
  777. }
  778. ObDereferenceObject( *Event );
  779. } __finally {
  780. if (EventName.Buffer) {
  781. SaPortFreeUnicodeString( MiniPortDeviceExtension, &EventName );
  782. }
  783. if (!NT_SUCCESS(Status)) {
  784. if (SecurityDescriptor) {
  785. SaPortFreePool( MiniPortDeviceExtension, SecurityDescriptor );
  786. }
  787. if (EventHandle) {
  788. ZwClose( *EventHandle );
  789. }
  790. }
  791. }
  792. return Status;
  793. }
  794. NTSTATUS
  795. SaPortShutdownSystem(
  796. IN BOOLEAN PowerOff
  797. )
  798. {
  799. return NtShutdownSystem( PowerOff ? ShutdownPowerOff : ShutdownReboot );
  800. }