NTSTATUS TapeGetDriveParameters( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine returns the default fixed-block size, the maximum block size, the minimum block size, the maximum number of partitions, and the device features flag. Arguments: DeviceObject Irp Return Value: NTSTATUS --*/ { PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; PTAPE_GET_DRIVE_PARAMETERS tapeGetDriveParams = Irp->AssociatedIrp.SystemBuffer; PNINE_TRACKSENSE_DATA buffer; PREAD_BLOCK_LIMITS_DATA blockLimits; SCSI_REQUEST_BLOCK srb; PCDB cdb = (PCDB)srb.Cdb; NTSTATUS status; DebugPrint((3,"TapeGetDriveParameters: Get Tape Drive Parameters\n")); // // Zero CDB in SRB on stack. // RtlZeroMemory(cdb, MAXIMUM_CDB_SIZE); srb.CdbLength = CDB6GENERIC_LENGTH; cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE; // // Set timeout value. // srb.TimeOutValue = deviceExtension->TimeOutValue; cdb->MODE_SENSE.AllocationLength = sizeof(NINE_TRACKSENSE_DATA); cdb->MODE_SENSE.PageCode = MODE_SENSE_CURRENT_VALUES; cdb->MODE_SENSE.Pc = 0x0B; buffer = ExAllocatePool(NonPagedPoolCacheAligned, sizeof(NINE_TRACKSENSE_DATA)); if (!buffer) { return STATUS_INSUFFICIENT_RESOURCES; } status = ScsiClassSendSrbSynchronous(DeviceObject, &srb, buffer, sizeof(NINE_TRACKSENSE_DATA), FALSE); if (NT_SUCCESS(status)) { Irp->IoStatus.Information = sizeof(TAPE_GET_DRIVE_PARAMETERS); // // Indicate support of following: // tapeGetDriveParams->ECC = FALSE; tapeGetDriveParams->Compression = FALSE; tapeGetDriveParams->DataPadding = FALSE; tapeGetDriveParams->ReportSetmarks = FALSE; tapeGetDriveParams->FeaturesLow = TAPE_DRIVE_ERASE_SHORT | TAPE_DRIVE_FIXED_BLOCK | TAPE_DRIVE_VARIABLE_BLOCK | TAPE_DRIVE_WRITE_PROTECT | TAPE_DRIVE_GET_ABSOLUTE_BLK | TAPE_DRIVE_GET_LOGICAL_BLK; tapeGetDriveParams->FeaturesHigh = TAPE_DRIVE_LOAD_UNLOAD | TAPE_DRIVE_LOCK_UNLOCK | TAPE_DRIVE_SET_BLOCK_SIZE | TAPE_DRIVE_ABSOLUTE_BLK | TAPE_DRIVE_ABS_BLK_IMMED | TAPE_DRIVE_LOGICAL_BLK | TAPE_DRIVE_END_OF_DATA | TAPE_DRIVE_FILEMARKS | TAPE_DRIVE_SEQUENTIAL_FMKS | TAPE_DRIVE_REVERSE_POSITION | TAPE_DRIVE_WRITE_FILEMARKS; } ExFreePool(buffer); if (!NT_SUCCESS(status)) { return status; } // // Zero CDB in SRB on stack. // RtlZeroMemory(cdb, MAXIMUM_CDB_SIZE); srb.CdbLength = CDB6GENERIC_LENGTH; cdb->CDB6GENERIC.OperationCode = SCSIOP_READ_BLOCK_LIMITS; // // Set timeout value. // srb.TimeOutValue = deviceExtension->TimeOutValue; blockLimits = ExAllocatePool(NonPagedPoolCacheAligned, sizeof(READ_BLOCK_LIMITS_DATA)); if (!blockLimits) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(blockLimits, sizeof(READ_BLOCK_LIMITS_DATA)); status = ScsiClassSendSrbSynchronous(DeviceObject, &srb, blockLimits, sizeof(READ_BLOCK_LIMITS_DATA), FALSE); if (NT_SUCCESS(status)) { tapeGetDriveParams->MaximumBlockSize = blockLimits->BlockMaximumSize[2]; tapeGetDriveParams->MaximumBlockSize += (blockLimits->BlockMaximumSize[1] << 8); tapeGetDriveParams->MaximumBlockSize += (blockLimits->BlockMaximumSize[0] << 16); tapeGetDriveParams->MinimumBlockSize = blockLimits->BlockMinimumSize[1]; tapeGetDriveParams->MinimumBlockSize += (blockLimits->BlockMinimumSize[0] << 8); } ExFreePool(blockLimits); return status; } // end TapeGetDriveParameters()
/* Creates the client side */ NTSTATUS DEFAULTAPI MsfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PMSFS_DEVICE_EXTENSION DeviceExtension; PMSFS_FCB Fcb; PMSFS_CCB Ccb; PMSFS_FCB current = NULL; PLIST_ENTRY current_entry; KIRQL oldIrql; DPRINT("MsfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = IoGetCurrentIrpStackLocation(Irp); DeviceExtension = DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; DPRINT("Mailslot name: %wZ\n", &FileObject->FileName); Ccb = ExAllocatePool(NonPagedPool, sizeof(MSFS_CCB)); if (Ccb == NULL) { Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } KeLockMutex(&DeviceExtension->FcbListLock); current_entry = DeviceExtension->FcbListHead.Flink; while (current_entry != &DeviceExtension->FcbListHead) { current = CONTAINING_RECORD(current_entry, MSFS_FCB, FcbListEntry); if (!RtlCompareUnicodeString(&FileObject->FileName, ¤t->Name, TRUE)) break; current_entry = current_entry->Flink; } if (current_entry == &DeviceExtension->FcbListHead) { ExFreePool(Ccb); KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } Fcb = current; KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry); KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); Fcb->ReferenceCount++; Ccb->Fcb = Fcb; KeUnlockMutex(&DeviceExtension->FcbListLock); FileObject->FsContext = Fcb; FileObject->FsContext2 = Ccb; FileObject->Flags |= FO_MAILSLOT; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
NTSTATUS NTAPI SeLocateProcessImageName(IN PEPROCESS Process, OUT PUNICODE_STRING *ProcessImageName) { POBJECT_NAME_INFORMATION AuditName; PUNICODE_STRING ImageName; PFILE_OBJECT FileObject; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); /* Assume failure */ *ProcessImageName = NULL; /* Check if we have audit info */ AuditName = Process->SeAuditProcessCreationInfo.ImageFileName; if (!AuditName) { /* Get the file object */ Status = PsReferenceProcessFilePointer(Process, &FileObject); if (!NT_SUCCESS(Status)) return Status; /* Initialize the audit structure */ Status = SeInitializeProcessAuditName(FileObject, TRUE, &AuditName); if (NT_SUCCESS(Status)) { /* Set it */ if (InterlockedCompareExchangePointer((PVOID*)&Process-> SeAuditProcessCreationInfo.ImageFileName, AuditName, NULL)) { /* Someone beat us to it, deallocate our copy */ ExFreePool(AuditName); } } /* Dereference the file object */ ObDereferenceObject(FileObject); if (!NT_SUCCESS(Status)) return Status; } /* Get audit info again, now we have it for sure */ AuditName = Process->SeAuditProcessCreationInfo.ImageFileName; /* Allocate the output string */ ImageName = ExAllocatePoolWithTag(NonPagedPool, AuditName->Name.MaximumLength + sizeof(UNICODE_STRING), TAG_SEPA); if (!ImageName) return STATUS_NO_MEMORY; /* Make a copy of it */ RtlCopyMemory(ImageName, &AuditName->Name, AuditName->Name.MaximumLength + sizeof(UNICODE_STRING)); /* Fix up the buffer */ ImageName->Buffer = (PWSTR)(ImageName + 1); /* Return it */ *ProcessImageName = ImageName; /* Return status */ return Status; }
NTSTATUS FsRtlGetTunnelParameterValue ( IN PUNICODE_STRING ValueName, IN OUT PULONG Value ) /*++ Routine Description: Given a unicode value name this routine will go into the registry location for the Tunnel parameter information and get the value. Arguments: ValueName - the unicode name for the registry value located in the double space configuration location of the registry. Value - a pointer to the ULONG for the result. Return Value: NTSTATUS If STATUS_SUCCESSFUL is returned, the location *Value will be updated with the DWORD value from the registry. If any failing status is returned, this value is untouched. --*/ { HANDLE Handle; NTSTATUS Status; ULONG RequestLength; ULONG ResultLength; UCHAR Buffer[KEY_WORK_AREA]; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; KeyName.Buffer = TUNNEL_KEY_NAME; KeyName.Length = sizeof(TUNNEL_KEY_NAME) - sizeof(WCHAR); KeyName.MaximumLength = sizeof(TUNNEL_KEY_NAME); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&Handle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { return Status; } RequestLength = KEY_WORK_AREA; KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer; while (1) { Status = ZwQueryValueKey(Handle, ValueName, KeyValueFullInformation, KeyValueInformation, RequestLength, &ResultLength); ASSERT( Status != STATUS_BUFFER_OVERFLOW ); if (Status == STATUS_BUFFER_OVERFLOW) { // // Try to get a buffer big enough. // if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) { ExFreePool(KeyValueInformation); } RequestLength += 256; KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION) ExAllocatePoolWithTag(PagedPool, RequestLength, 'KnuT'); if (!KeyValueInformation) { return STATUS_NO_MEMORY; } } else { break; } } ZwClose(Handle); if (NT_SUCCESS(Status)) { if (KeyValueInformation->DataLength != 0) { PULONG DataPtr; // // Return contents to the caller. // DataPtr = (PULONG) ((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset); *Value = *DataPtr; } else { // // Treat as if no value was found // Status = STATUS_OBJECT_NAME_NOT_FOUND; } } if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) { ExFreePool(KeyValueInformation); } return Status; }
NTSTATUS DiskDeviceControl(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) { PIO_STACK_LOCATION irpSp; PDokanDCB dcb; PDokanVCB vcb; NTSTATUS status = STATUS_NOT_IMPLEMENTED; ULONG outputLength = 0; ULONG inputLength = 0; DDbgPrint(" => DokanDiskDeviceControl\n"); irpSp = IoGetCurrentIrpStackLocation(Irp); dcb = DeviceObject->DeviceExtension; outputLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; inputLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; if (GetIdentifierType(dcb) != DCB) { PrintIdType(dcb); DDbgPrint(" Device is not dcb so go out here\n"); return STATUS_INVALID_PARAMETER; } if (IsDeletePending(DeviceObject)) { DDbgPrint(" Device object is pending for delete valid anymore\n"); return STATUS_DEVICE_REMOVED; } vcb = dcb->Vcb; if (IsUnmountPendingVcb(vcb)) { DDbgPrint(" Volume is unmounted so ignore dcb requests\n"); return STATUS_NO_SUCH_DEVICE; } DDbgPrint(" DiskDeviceControl Device name %wZ \n", dcb->DiskDeviceName); switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_DISK_GET_DRIVE_GEOMETRY: { PDISK_GEOMETRY diskGeometry; DDbgPrint(" IOCTL_DISK_GET_DRIVE_GEOMETRY\n"); if (outputLength < sizeof(DISK_GEOMETRY)) { Irp->IoStatus.Information = 0; status = STATUS_BUFFER_TOO_SMALL; break; } diskGeometry = (PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer; ASSERT(diskGeometry != NULL); DokanPopulateDiskGeometry(diskGeometry); Irp->IoStatus.Information = sizeof(DISK_GEOMETRY); status = STATUS_SUCCESS; } break; case IOCTL_DISK_GET_LENGTH_INFO: { PGET_LENGTH_INFORMATION getLengthInfo; DDbgPrint(" IOCTL_DISK_GET_LENGTH_INFO\n"); if (outputLength < sizeof(GET_LENGTH_INFORMATION)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; break; } getLengthInfo = (PGET_LENGTH_INFORMATION)Irp->AssociatedIrp.SystemBuffer; ASSERT(getLengthInfo != NULL); getLengthInfo->Length.QuadPart = 1024 * 1024 * 500; status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION); } break; case IOCTL_DISK_GET_DRIVE_LAYOUT: case IOCTL_DISK_GET_DRIVE_LAYOUT_EX: case IOCTL_DISK_GET_PARTITION_INFO: case IOCTL_DISK_GET_PARTITION_INFO_EX: { // Fake drive layout/partition information VOID *outputBuffer = Irp->AssociatedIrp.SystemBuffer; ULONG ioctl = irpSp->Parameters.DeviceIoControl.IoControlCode; switch (ioctl) { case IOCTL_DISK_GET_DRIVE_LAYOUT: DDbgPrint(" IOCTL_DISK_GET_DRIVE_LAYOUT\n"); Irp->IoStatus.Information = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[1]); break; case IOCTL_DISK_GET_DRIVE_LAYOUT_EX: DDbgPrint(" IOCTL_DISK_GET_DRIVE_LAYOUT_EX\n"); Irp->IoStatus.Information = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[1]); break; case IOCTL_DISK_GET_PARTITION_INFO: DDbgPrint(" IOCTL_DISK_GET_PARTITION_INFO\n"); Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION); break; case IOCTL_DISK_GET_PARTITION_INFO_EX: DDbgPrint(" IOCTL_DISK_GET_PARTITION_INFO_EX\n"); Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX); break; } if (outputLength < Irp->IoStatus.Information) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; break; } RtlZeroMemory(outputBuffer, Irp->IoStatus.Information); // if we are getting the drive layout, then we need to start by // adding some of the non-partition stuff that says we have // exactly one partition available. if (ioctl == IOCTL_DISK_GET_DRIVE_LAYOUT) { PDRIVE_LAYOUT_INFORMATION layout; layout = (PDRIVE_LAYOUT_INFORMATION)outputBuffer; layout->PartitionCount = 1; layout->Signature = 1; outputBuffer = (PVOID)(layout->PartitionEntry); ioctl = IOCTL_DISK_GET_PARTITION_INFO; } else if (ioctl == IOCTL_DISK_GET_DRIVE_LAYOUT_EX) { PDRIVE_LAYOUT_INFORMATION_EX layoutEx; layoutEx = (PDRIVE_LAYOUT_INFORMATION_EX)outputBuffer; layoutEx->PartitionStyle = PARTITION_STYLE_MBR; layoutEx->PartitionCount = 1; layoutEx->Mbr.Signature = 1; outputBuffer = (PVOID)(layoutEx->PartitionEntry); ioctl = IOCTL_DISK_GET_PARTITION_INFO_EX; } // NOTE: the local var 'ioctl' is now modified to either EX or // non-EX version. the local var 'systemBuffer' is now pointing // to the partition information structure. if (ioctl == IOCTL_DISK_GET_PARTITION_INFO) { PPARTITION_INFORMATION partitionInfo; partitionInfo = (PPARTITION_INFORMATION)outputBuffer; partitionInfo->RewritePartition = FALSE; partitionInfo->RecognizedPartition = FALSE; partitionInfo->PartitionType = PARTITION_ENTRY_UNUSED; partitionInfo->BootIndicator = FALSE; partitionInfo->HiddenSectors = 0; partitionInfo->StartingOffset.QuadPart = 0; partitionInfo->PartitionLength.QuadPart = DOKAN_DEFAULT_DISK_SIZE; // Partition size equels disk size here partitionInfo->PartitionNumber = 0; } else { PPARTITION_INFORMATION_EX partitionInfo; partitionInfo = (PPARTITION_INFORMATION_EX)outputBuffer; partitionInfo->PartitionStyle = PARTITION_STYLE_MBR; partitionInfo->RewritePartition = FALSE; partitionInfo->Mbr.RecognizedPartition = FALSE; partitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED; partitionInfo->Mbr.BootIndicator = FALSE; partitionInfo->Mbr.HiddenSectors = 0; partitionInfo->StartingOffset.QuadPart = 0; partitionInfo->PartitionLength.QuadPart = DOKAN_DEFAULT_DISK_SIZE; // Partition size equels disk size here partitionInfo->PartitionNumber = 0; } status = STATUS_SUCCESS; } break; case IOCTL_DISK_IS_WRITABLE: DDbgPrint(" IOCTL_DISK_IS_WRITABLE\n"); status = IS_DEVICE_READ_ONLY(DeviceObject) ? STATUS_MEDIA_WRITE_PROTECTED : STATUS_SUCCESS; break; case IOCTL_DISK_MEDIA_REMOVAL: DDbgPrint(" IOCTL_DISK_MEDIA_REMOVAL\n"); status = STATUS_SUCCESS; break; case IOCTL_STORAGE_MEDIA_REMOVAL: DDbgPrint(" IOCTL_STORAGE_MEDIA_REMOVAL\n"); status = STATUS_SUCCESS; break; case IOCTL_DISK_SET_PARTITION_INFO: DDbgPrint(" IOCTL_DISK_SET_PARTITION_INFO\n"); break; case IOCTL_DISK_VERIFY: DDbgPrint(" IOCTL_DISK_VERIFY\n"); break; case IOCTL_STORAGE_GET_HOTPLUG_INFO: { PSTORAGE_HOTPLUG_INFO hotplugInfo; DDbgPrint(" IOCTL_STORAGE_GET_HOTPLUG_INFO\n"); if (outputLength < sizeof(STORAGE_HOTPLUG_INFO)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; break; } hotplugInfo = Irp->AssociatedIrp.SystemBuffer; hotplugInfo->Size = sizeof(STORAGE_HOTPLUG_INFO); hotplugInfo->MediaRemovable = 1; hotplugInfo->MediaHotplug = 1; hotplugInfo->DeviceHotplug = 1; hotplugInfo->WriteCacheEnableOverride = 0; status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO); } break; case IOCTL_VOLUME_GET_GPT_ATTRIBUTES: { DDbgPrint(" IOCTL_VOLUME_GET_GPT_ATTRIBUTES\n"); PVOLUME_GET_GPT_ATTRIBUTES_INFORMATION gptAttrInfo; if (outputLength < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; break; } // Set GPT read-only flag if device is not writable gptAttrInfo = Irp->AssociatedIrp.SystemBuffer; if (IS_DEVICE_READ_ONLY(DeviceObject)) gptAttrInfo->GptAttributes = GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY; Irp->IoStatus.Information = sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION); status = STATUS_SUCCESS; } break; case IOCTL_STORAGE_CHECK_VERIFY: case IOCTL_DISK_CHECK_VERIFY: DDbgPrint(" IOCTL_STORAGE_CHECK_VERIFY\n"); status = STATUS_SUCCESS; break; case IOCTL_STORAGE_CHECK_VERIFY2: DDbgPrint(" IOCTL_STORAGE_CHECK_VERIFY2\n"); status = STATUS_SUCCESS; break; case IOCTL_STORAGE_QUERY_PROPERTY: DDbgPrint(" IOCTL_STORAGE_QUERY_PROPERTY\n"); PSTORAGE_PROPERTY_QUERY query = NULL; query = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer; ASSERT(query != NULL); if (query->QueryType == PropertyExistsQuery) { if (query->PropertyId == StorageDeviceUniqueIdProperty) { PSTORAGE_DEVICE_UNIQUE_IDENTIFIER storage; DDbgPrint(" PropertyExistsQuery StorageDeviceUniqueIdProperty\n"); if (outputLength < sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; break; } storage = Irp->AssociatedIrp.SystemBuffer; status = STATUS_SUCCESS; } else if (query->PropertyId == StorageDeviceWriteCacheProperty) { DDbgPrint(" PropertyExistsQuery StorageDeviceWriteCacheProperty\n"); status = STATUS_NOT_IMPLEMENTED; } else { DDbgPrint(" PropertyExistsQuery Unknown %d\n", query->PropertyId); status = STATUS_NOT_IMPLEMENTED; } } else if (query->QueryType == PropertyStandardQuery) { if (query->PropertyId == StorageDeviceProperty) { PSTORAGE_DEVICE_DESCRIPTOR storage; DDbgPrint(" PropertyStandardQuery StorageDeviceProperty\n"); if (outputLength < sizeof(STORAGE_DEVICE_DESCRIPTOR)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; break; } storage = Irp->AssociatedIrp.SystemBuffer; status = STATUS_SUCCESS; } else if (query->PropertyId == StorageAdapterProperty) { DDbgPrint(" PropertyStandardQuery StorageAdapterProperty\n"); status = STATUS_NOT_IMPLEMENTED; } else { DDbgPrint(" PropertyStandardQuery Unknown %d\n", query->PropertyId); status = STATUS_ACCESS_DENIED; } } else { DDbgPrint(" Unknown query type %d\n", query->QueryType); status = STATUS_ACCESS_DENIED; } break; case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: { PMOUNTDEV_NAME mountdevName; PUNICODE_STRING deviceName = dcb->DiskDeviceName; DDbgPrint(" IOCTL_MOUNTDEV_QUERY_DEVICE_NAME\n"); if (outputLength < sizeof(MOUNTDEV_NAME)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME); break; } mountdevName = (PMOUNTDEV_NAME)Irp->AssociatedIrp.SystemBuffer; ASSERT(mountdevName != NULL); /* NOTE: When Windows API GetVolumeNameForVolumeMountPoint is called, this IO control is called. Even if status = STATUS_SUCCESS, GetVolumeNameForVolumeMountPoint can returns error if it doesn't match cached data from mount manager (looks like). */ RtlZeroMemory(mountdevName, outputLength); mountdevName->NameLength = deviceName->Length; if (sizeof(USHORT) + mountdevName->NameLength < outputLength) { RtlCopyMemory((PCHAR)mountdevName->Name, deviceName->Buffer, mountdevName->NameLength); Irp->IoStatus.Information = sizeof(USHORT) + mountdevName->NameLength; status = STATUS_SUCCESS; DDbgPrint(" DeviceName %wZ\n", deviceName); } else { Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME); status = STATUS_BUFFER_OVERFLOW; } } break; case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: { PMOUNTDEV_UNIQUE_ID uniqueId; DDbgPrint(" IOCTL_MOUNTDEV_QUERY_UNIQUE_ID\n"); if (outputLength < sizeof(MOUNTDEV_UNIQUE_ID)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID); break; } uniqueId = (PMOUNTDEV_UNIQUE_ID)Irp->AssociatedIrp.SystemBuffer; ASSERT(uniqueId != NULL); uniqueId->UniqueIdLength = dcb->DiskDeviceName->Length; if (sizeof(USHORT) + uniqueId->UniqueIdLength < outputLength) { RtlCopyMemory((PCHAR)uniqueId->UniqueId, dcb->DiskDeviceName->Buffer, uniqueId->UniqueIdLength); Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + uniqueId->UniqueIdLength; status = STATUS_SUCCESS; DDbgPrint(" UniqueName %wZ\n", dcb->DiskDeviceName); break; } else { Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID); status = STATUS_BUFFER_OVERFLOW; } } break; case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME: { PMOUNTDEV_SUGGESTED_LINK_NAME linkName; DDbgPrint(" IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n"); if (outputLength < sizeof(MOUNTDEV_SUGGESTED_LINK_NAME)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = sizeof(MOUNTDEV_SUGGESTED_LINK_NAME); break; } linkName = (PMOUNTDEV_SUGGESTED_LINK_NAME)Irp->AssociatedIrp.SystemBuffer; ASSERT(linkName != NULL); if (dcb->MountPoint != NULL && dcb->MountPoint->Length > 0) { if (IsMountPointDriveLetter(dcb->MountPoint) == STATUS_SUCCESS) { linkName->UseOnlyIfThereAreNoOtherLinks = FALSE; linkName->NameLength = dcb->MountPoint->Length; if (sizeof(USHORT) + linkName->NameLength < outputLength) { RtlCopyMemory((PCHAR)linkName->Name, dcb->MountPoint->Buffer, linkName->NameLength); Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME, Name[0]) + linkName->NameLength; status = STATUS_SUCCESS; DDbgPrint(" LinkName %wZ (%d)\n", dcb->MountPoint, dcb->MountPoint->Length); break; } else { Irp->IoStatus.Information = sizeof(MOUNTDEV_SUGGESTED_LINK_NAME); status = STATUS_BUFFER_OVERFLOW; } } else { DDbgPrint(" MountPoint %wZ is not a drive\n", dcb->MountPoint); status = STATUS_NOT_FOUND; } } else { DDbgPrint(" MountPoint is NULL or undefined\n"); status = STATUS_NOT_FOUND; } } break; case IOCTL_MOUNTDEV_LINK_CREATED: { PMOUNTDEV_NAME mountdevName = Irp->AssociatedIrp.SystemBuffer; DDbgPrint(" IOCTL_MOUNTDEV_LINK_CREATED\n"); status = STATUS_SUCCESS; if (!IsUnmountPending(DeviceObject) && mountdevName != NULL && mountdevName->NameLength > 0) { WCHAR *symbolicLinkNameBuf = ExAllocatePool((mountdevName->NameLength + 1) * sizeof(WCHAR)); if (symbolicLinkNameBuf == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlZeroMemory(symbolicLinkNameBuf, (mountdevName->NameLength + 1) * sizeof(WCHAR)); RtlCopyMemory(symbolicLinkNameBuf, mountdevName->Name, mountdevName->NameLength); DDbgPrint(" MountDev Name: %ws\n", symbolicLinkNameBuf); if (wcsncmp(symbolicLinkNameBuf, L"\\DosDevices\\", 12) == 0) { if (dcb->MountPoint != NULL && dcb->MountPoint->Length == 0) { ExFreePool(dcb->MountPoint); dcb->MountPoint = NULL; } if (dcb->MountPoint == NULL) { DDbgPrint(" Not current MountPoint. MountDev set as MountPoint\n"); dcb->MountPoint = DokanAllocateUnicodeString(symbolicLinkNameBuf); if (dcb->DiskDeviceName != NULL) { PMOUNT_ENTRY mountEntry; PDOKAN_CONTROL dokanControl = ExAllocatePool(sizeof(DOKAN_CONTROL)); if (dokanControl == NULL) { ExFreePool(symbolicLinkNameBuf); status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlZeroMemory(dokanControl, sizeof(*dokanControl)); RtlCopyMemory(dokanControl->DeviceName, dcb->DiskDeviceName->Buffer, dcb->DiskDeviceName->Length); if (dcb->UNCName->Buffer != NULL && dcb->UNCName->Length > 0) { RtlCopyMemory(dokanControl->UNCName, dcb->UNCName->Buffer, dcb->UNCName->Length); } mountEntry = FindMountEntry(dcb->Global, dokanControl, TRUE); ExFreePool(dokanControl); if (mountEntry != NULL) { RtlStringCchCopyW(mountEntry->MountControl.MountPoint, MAXIMUM_FILENAME_LENGTH, symbolicLinkNameBuf); } else { DDbgPrint(" Cannot found associated MountEntry.\n"); } } else { DDbgPrint( " DiskDeviceName is null. Is device currently unmounted?\n"); } } else { DDbgPrint(" Mount Point already assigned to the device. New mount " "point ignored.\n"); } } else { DDbgPrint(" Mount Point is not DosDevices, ignored.\n"); } ExFreePool(symbolicLinkNameBuf); } else { DDbgPrint(" MountDev Name is undefined or unmounting in progress.\n"); } } break; case IOCTL_MOUNTDEV_LINK_DELETED: { PMOUNTDEV_NAME mountdevName = Irp->AssociatedIrp.SystemBuffer; DDbgPrint(" IOCTL_MOUNTDEV_LINK_DELETED\n"); status = STATUS_SUCCESS; if (dcb->UseMountManager) { if (mountdevName != NULL && mountdevName->NameLength > 0) { WCHAR *symbolicLinkNameBuf = ExAllocatePool((mountdevName->NameLength + 1) * sizeof(WCHAR)); if (symbolicLinkNameBuf == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlZeroMemory(symbolicLinkNameBuf, (mountdevName->NameLength + 1) * sizeof(WCHAR)); RtlCopyMemory(symbolicLinkNameBuf, mountdevName->Name, mountdevName->NameLength); DDbgPrint(" MountDev Name: %ws\n", symbolicLinkNameBuf); if (dcb->MountPoint != NULL && dcb->MountPoint->Length > 0) { // If deleted mount point match user requested mount point, release // devices if (dcb->MountPoint->Length == mountdevName->NameLength && RtlCompareMemory(mountdevName->Name, dcb->MountPoint->Buffer, mountdevName->NameLength) == mountdevName->NameLength) { status = DokanEventRelease(vcb->DeviceObject, Irp); } else { DDbgPrint(" Deleted Mount Point doesn't match device excepted " "mount point.\n"); } } // Or, if no requested mount point, we assume the first deleted one // release devices else { status = DokanEventRelease(vcb->DeviceObject, Irp); } ExFreePool(symbolicLinkNameBuf); } else { DDbgPrint(" MountDev Name is undefined.\n"); } } else { DDbgPrint(" Mount Manager is not enabled for this device. Ignored.\n"); } } break; // case IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY: // DDbgPrint(" IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY\n"); // break; case IOCTL_MOUNTDEV_QUERY_STABLE_GUID: DDbgPrint(" IOCTL_MOUNTDEV_QUERY_STABLE_GUID\n"); break; case IOCTL_VOLUME_ONLINE: DDbgPrint(" IOCTL_VOLUME_ONLINE\n"); status = STATUS_SUCCESS; break; case IOCTL_VOLUME_OFFLINE: DDbgPrint(" IOCTL_VOLUME_OFFLINE\n"); status = STATUS_SUCCESS; break; case IOCTL_VOLUME_READ_PLEX: DDbgPrint(" IOCTL_VOLUME_READ_PLEX\n"); break; case IOCTL_VOLUME_PHYSICAL_TO_LOGICAL: DDbgPrint(" IOCTL_VOLUME_PHYSICAL_TO_LOGICAL\n"); break; case IOCTL_VOLUME_IS_CLUSTERED: DDbgPrint(" IOCTL_VOLUME_IS_CLUSTERED\n"); break; case IOCTL_VOLUME_PREPARE_FOR_CRITICAL_IO: DDbgPrint(" IOCTL_VOLUME_PREPARE_FOR_CRITICAL_IO\n"); break; case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: { PVOLUME_DISK_EXTENTS volume; ULONG bufferLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; DDbgPrint(" IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS\n"); if (bufferLength < sizeof(VOLUME_DISK_EXTENTS)) { status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } volume = Irp->AssociatedIrp.SystemBuffer; RtlZeroMemory(volume, sizeof(VOLUME_DISK_EXTENTS)); volume->NumberOfDiskExtents = 1; Irp->IoStatus.Information = sizeof(VOLUME_DISK_EXTENTS); status = STATUS_SUCCESS; } break; case IOCTL_STORAGE_EJECT_MEDIA: { DDbgPrint(" IOCTL_STORAGE_EJECT_MEDIA\n"); DokanUnmount(dcb); status = STATUS_SUCCESS; } break; case IOCTL_REDIR_QUERY_PATH_EX: case IOCTL_REDIR_QUERY_PATH: { PQUERY_PATH_RESPONSE pathResp; BOOLEAN prefixOk = FALSE; if (dcb->UNCName != NULL && dcb->UNCName->Length > 0) { if (Irp->RequestorMode != KernelMode) { break; } WCHAR *lpPath = NULL; ULONG ulPath = 0; if (irpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_REDIR_QUERY_PATH) { PQUERY_PATH_REQUEST pathReq; DDbgPrint(" IOCTL_REDIR_QUERY_PATH\n"); if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(QUERY_PATH_REQUEST)) { status = STATUS_BUFFER_OVERFLOW; break; } // Always a METHOD_NEITHER IOCTL pathReq = (PQUERY_PATH_REQUEST) irpSp->Parameters.DeviceIoControl.Type3InputBuffer; DDbgPrint(" PathNameLength = %d\n", pathReq->PathNameLength); DDbgPrint(" SecurityContext = %p\n", pathReq->SecurityContext); DDbgPrint(" FilePathName = %.*ls\n", (unsigned int)(pathReq->PathNameLength / sizeof(WCHAR)), pathReq->FilePathName); lpPath = pathReq->FilePathName; ulPath = pathReq->PathNameLength / sizeof(WCHAR); if (pathReq->PathNameLength >= dcb->UNCName->Length / sizeof(WCHAR)) { prefixOk = (_wcsnicmp(pathReq->FilePathName, dcb->UNCName->Buffer, dcb->UNCName->Length / sizeof(WCHAR)) == 0); } } else { PQUERY_PATH_REQUEST_EX pathReqEx; DDbgPrint(" IOCTL_REDIR_QUERY_PATH_EX\n"); if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(QUERY_PATH_REQUEST_EX)) { status = STATUS_BUFFER_OVERFLOW; break; } // Always a METHOD_NEITHER IOCTL pathReqEx = (PQUERY_PATH_REQUEST_EX) irpSp->Parameters.DeviceIoControl.Type3InputBuffer; DDbgPrint(" pSecurityContext = %p\n", pathReqEx->pSecurityContext); DDbgPrint(" EaLength = %d\n", pathReqEx->EaLength); DDbgPrint(" pEaBuffer = %p\n", pathReqEx->pEaBuffer); DDbgPrint(" PathNameLength = %d\n", pathReqEx->PathName.Length); DDbgPrint(" FilePathName = %*ls\n", (unsigned int)(pathReqEx->PathName.Length / sizeof(WCHAR)), pathReqEx->PathName.Buffer); lpPath = pathReqEx->PathName.Buffer; ulPath = pathReqEx->PathName.Length / sizeof(WCHAR); if (pathReqEx->PathName.Length >= dcb->UNCName->Length) { prefixOk = (_wcsnicmp(pathReqEx->PathName.Buffer, dcb->UNCName->Buffer, dcb->UNCName->Length / sizeof(WCHAR)) == 0); } } unsigned int i = 1; for (; i < ulPath && i * sizeof(WCHAR) < dcb->UNCName->Length && !prefixOk; ++i) { if (_wcsnicmp(&lpPath[i], &dcb->UNCName->Buffer[i], 1) != 0) { break; } if ((i + 1) * sizeof(WCHAR) < dcb->UNCName->Length) { prefixOk = (dcb->UNCName->Buffer[i + 1] == L'\\'); } } if (!prefixOk) { status = STATUS_BAD_NETWORK_PATH; break; } for (; i < ulPath && i * sizeof(WCHAR) < dcb->UNCName->Length && prefixOk; ++i) { if (_wcsnicmp(&lpPath[i], &dcb->UNCName->Buffer[i], 1) != 0) { prefixOk = FALSE; } } if (!prefixOk) { status = STATUS_BAD_NETWORK_NAME; break; } pathResp = (PQUERY_PATH_RESPONSE)Irp->UserBuffer; pathResp->LengthAccepted = dcb->UNCName->Length; status = STATUS_SUCCESS; } } break; case IOCTL_STORAGE_GET_MEDIA_TYPES_EX: { PGET_MEDIA_TYPES mediaTypes = NULL; PDEVICE_MEDIA_INFO mediaInfo = NULL; //&mediaTypes->MediaInfo[0]; // We alway return only one media type DDbgPrint(" IOCTL_STORAGE_GET_MEDIA_TYPES_EX\n"); if (outputLength < sizeof(GET_MEDIA_TYPES)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; break; } mediaTypes = (PGET_MEDIA_TYPES)Irp->AssociatedIrp.SystemBuffer; ASSERT(mediaTypes != NULL); mediaInfo = &mediaTypes->MediaInfo[0]; mediaTypes->DeviceType = FILE_DEVICE_VIRTUAL_DISK; mediaTypes->MediaInfoCount = 1; PDISK_GEOMETRY diskGeometry = ExAllocatePool(sizeof(DISK_GEOMETRY)); if (diskGeometry == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlZeroMemory(diskGeometry, sizeof(*diskGeometry)); DokanPopulateDiskGeometry(diskGeometry); mediaInfo->DeviceSpecific.DiskInfo.MediaType = diskGeometry->MediaType; mediaInfo->DeviceSpecific.DiskInfo.NumberMediaSides = 1; mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_WRITE); mediaInfo->DeviceSpecific.DiskInfo.Cylinders.QuadPart = diskGeometry->Cylinders.QuadPart; mediaInfo->DeviceSpecific.DiskInfo.TracksPerCylinder = diskGeometry->TracksPerCylinder; mediaInfo->DeviceSpecific.DiskInfo.SectorsPerTrack = diskGeometry->SectorsPerTrack; mediaInfo->DeviceSpecific.DiskInfo.BytesPerSector = diskGeometry->BytesPerSector; ExFreePool(diskGeometry); status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(GET_MEDIA_TYPES); } break; case IOCTL_STORAGE_GET_DEVICE_NUMBER: { PSTORAGE_DEVICE_NUMBER deviceNumber; DDbgPrint(" IOCTL_STORAGE_GET_DEVICE_NUMBER\n"); if (outputLength < sizeof(STORAGE_DEVICE_NUMBER)) { status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER); break; } deviceNumber = (PSTORAGE_DEVICE_NUMBER)Irp->AssociatedIrp.SystemBuffer; ASSERT(deviceNumber != NULL); deviceNumber->DeviceType = FILE_DEVICE_VIRTUAL_DISK; if (vcb) { deviceNumber->DeviceType = vcb->DeviceObject->DeviceType; } deviceNumber->DeviceNumber = 0; // Always one volume only per disk device deviceNumber->PartitionNumber = (ULONG)-1; // Not partitionable Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER); status = STATUS_SUCCESS; } break; default: PrintUnknownDeviceIoctlCode( irpSp->Parameters.DeviceIoControl.IoControlCode); status = STATUS_INVALID_DEVICE_REQUEST; break; } DDbgPrint(" <= DokanDiskDeviceControl\n"); return status; }
NTSTATUS KDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status = STATUS_UNSUCCESSFUL; PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp); PPROCESS_EVENT pProcessEvent; PCHAR pOutputBuffer; PPROCESS_INFORMATION pInputBuffer; UINT dwDataWritten = 0; PCAPTURE_PROCESS_MANAGER pProcessManager; /* Get the process manager from the device extension */ pProcessManager = gpDeviceObject->DeviceExtension; switch(irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_CAPTURE_GET_PROCINFO: /* Update the time the user space program last sent an IOCTL */ //UpdateLastContactTime(); /* Return some of the process events that are queued */ if(irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PROCESS_EVENT)) { ULONG left = irpStack->Parameters.DeviceIoControl.OutputBufferLength; ULONG done = 0; pOutputBuffer = Irp->UserBuffer; __try { ProbeForWrite(pOutputBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, __alignof (PROCESS_EVENT)); //ExAcquireFastMutex(&pProcessManager->mProcessWaitingSpinLock); //if(pProcessManager->pCurrentProcessEvent != NULL) //{ // RtlCopyMemory(pOutputBuffer+done, pProcessManager->pCurrentProcessEvent, sizeof(PROCESS_EVENT)); // done += sizeof(PROCESS_EVENT); // ExFreePoolWithTag(pProcessManager->pCurrentProcessEvent, PROCESS_POOL_TAG); // pProcessManager->pCurrentProcessEvent = NULL; //} //ExReleaseFastMutex(&pProcessManager->mProcessWaitingSpinLock); if(!IsListEmpty(&pProcessManager->lQueuedProcessEvents)) { PLIST_ENTRY head; PPROCESS_EVENT_PACKET pProcessEventPacket; head = ExInterlockedRemoveHeadList(&pProcessManager->lQueuedProcessEvents, &pProcessManager->lQueuedProcessEventsSpinLock); pProcessManager->nQueuedProcessEvents--; pProcessEventPacket = CONTAINING_RECORD(head, PROCESS_EVENT_PACKET, Link); RtlCopyMemory(pOutputBuffer, &pProcessEventPacket->processEvent, sizeof(PROCESS_EVENT)); done = sizeof(PROCESS_EVENT); ExFreePool(pProcessEventPacket); // Notify that we still have process events queued if( pProcessManager->nQueuedProcessEvents ) { KeSetEvent(pProcessManager->eNewProcessEvent, 0, FALSE); KeClearEvent(pProcessManager->eNewProcessEvent); } } dwDataWritten = done; status = STATUS_SUCCESS; } __except( EXCEPTION_EXECUTE_HANDLER ) { DbgPrint("CaptureProcessMonitor: EXCEPTION IOCTL_CAPTURE_GET_PROCINFO - %08x\n", GetExceptionCode()); status = GetExceptionCode(); } } break; default: break; }
BOOLEAN LfsReadNextLogRecord ( IN LFS_LOG_HANDLE LogHandle, IN OUT LFS_LOG_CONTEXT Context, OUT PLFS_RECORD_TYPE RecordType, OUT TRANSACTION_ID *TransactionId, OUT PLSN UndoNextLsn, OUT PLSN PreviousLsn, OUT PLSN Lsn, OUT PULONG BufferLength, OUT PVOID *Buffer ) /*++ Routine Description: This routine is called to continue a query operation. The Lfs uses private information stored in the context structure to determine the next log record to return to the caller. Arguments: LogHandle - Pointer to private Lfs structure used to identify this client. Context - Supplies the address to store a pointer to the Lfs created context structure. Lsn - Lsn for this log record. RecordType - Supplies the address to store the record type of this log record. TransactionId - Supplies the address to store the transaction Id of this log record. UndoNextLsn - Supplies the address to store the Undo Next Lsn for this log record. PreviousLsn - Supplies the address to store the Previous Lsn for this log record. BufferLength - This is the length of the log data. Buffer - This is a pointer to the start of the log data. Return Value: None --*/ { volatile NTSTATUS Status = STATUS_SUCCESS; PLCH Lch; PLFCB Lfcb; PLfsLCB Lcb; BOOLEAN FoundNextLsn; BOOLEAN UnwindRememberLcbFields; PBCB UnwindRecordHeaderBcb; PLFS_RECORD_HEADER UnwindRecordHeader; PVOID UnwindCurrentLogRecord; BOOLEAN UnwindAuxilaryBuffer; PAGED_CODE(); LfsDebugTrace( +1, Dbg, "LfsReadNextLogRecord: Entered\n", 0 ); LfsDebugTrace( 0, Dbg, "Log Handle -> %08lx\n", LogHandle ); LfsDebugTrace( 0, Dbg, "Context -> %08lx\n", Context ); FoundNextLsn = FALSE; UnwindRememberLcbFields = FALSE; Lch = (PLCH) LogHandle; Lcb = (PLfsLCB) Context; // // Check that the structure is a valid log handle structure. // LfsValidateLch( Lch ); // // Use a try-except to catch errors. // __try { // // Use a try-finally to facilitate cleanup. // __try { // // Acquire the log file control block for this log file. // LfsAcquireLch( Lch ); Lfcb = Lch->Lfcb; // // If the Log file has been closed then refuse access. // if (Lfcb == NULL) { ExRaiseStatus( STATUS_ACCESS_DENIED ); } // // Check that the client Id is valid. // LfsValidateClientId( Lfcb, Lch ); // // Check that the context structure is valid. // LfsValidateLcb( Lcb, Lch ); // // Remember any context fields to be overwritten. // UnwindRememberLcbFields = TRUE; UnwindRecordHeaderBcb = Lcb->RecordHeaderBcb; Lcb->RecordHeaderBcb = NULL; UnwindRecordHeader = Lcb->RecordHeader; UnwindCurrentLogRecord = Lcb->CurrentLogRecord; UnwindAuxilaryBuffer = Lcb->AuxilaryBuffer; Lcb->AuxilaryBuffer = FALSE; // // Find the next Lsn number based on the current Lsn number in // the context block. // if (LfsFindClientNextLsn( Lfcb, Lcb, Lsn )) { // // We can give up the Lfcb as we know the Lsn is within the file. // LfsReleaseLfcb( Lfcb ); // // Cleanup the context block so we can do the next search. // Lcb->CurrentLogRecord = NULL; Lcb->AuxilaryBuffer = FALSE; // // Perform the work of getting the log record. // LfsFindLogRecord( Lfcb, Lcb, *Lsn, RecordType, TransactionId, UndoNextLsn, PreviousLsn, BufferLength, Buffer ); FoundNextLsn = TRUE; } } __finally { DebugUnwind( LfsReadNextLogRecord ); // // If we exited due to an error, we have to restore the context // block. // if (UnwindRememberLcbFields) { if (AbnormalTermination()) { // // If the record header in the context block is not // the same as we started with. Then we unpin that // data. // if (Lcb->RecordHeaderBcb != NULL) { CcUnpinData( Lcb->RecordHeaderBcb ); } if (Lcb->CurrentLogRecord != NULL && Lcb->AuxilaryBuffer == TRUE) { ExFreePool( Lcb->CurrentLogRecord ); } Lcb->RecordHeaderBcb = UnwindRecordHeaderBcb; Lcb->RecordHeader = UnwindRecordHeader; Lcb->CurrentLogRecord = UnwindCurrentLogRecord; Lcb->AuxilaryBuffer = UnwindAuxilaryBuffer; // // Otherwise, if we have successfully found the next Lsn, // we free up any resources being held from the previous search. // } else if (FoundNextLsn ) { if (UnwindRecordHeaderBcb != NULL) { CcUnpinData( UnwindRecordHeaderBcb ); } if (UnwindCurrentLogRecord != NULL && UnwindAuxilaryBuffer == TRUE) { ExFreePool( UnwindCurrentLogRecord ); } // // Restore the Bcb and auxilary buffer field for the final // cleanup. // } else { if (UnwindRecordHeaderBcb != NULL) { if (Lcb->RecordHeaderBcb != NULL) { CcUnpinData( UnwindRecordHeaderBcb ); } else { Lcb->RecordHeaderBcb = UnwindRecordHeaderBcb; } } if (UnwindAuxilaryBuffer) { if (Lcb->CurrentLogRecord == UnwindCurrentLogRecord) { Lcb->AuxilaryBuffer = TRUE; } else { ExFreePool( UnwindCurrentLogRecord ); } } } } // // Release the log file control block if held. // LfsReleaseLch( Lch ); LfsDebugTrace( 0, Dbg, "Lsn (Low) -> %08lx\n", Lsn->LowPart ); LfsDebugTrace( 0, Dbg, "Lsn (High) -> %08lx\n", Lsn->HighPart ); LfsDebugTrace( 0, Dbg, "Buffer Length -> %08lx\n", *BufferLength ); LfsDebugTrace( 0, Dbg, "Buffer -> %08lx\n", *Buffer ); LfsDebugTrace( -1, Dbg, "LfsReadNextLogRecord: Exit\n", 0 ); } } __except (LfsExceptionFilter( GetExceptionInformation() )) { Status = GetExceptionCode(); } if (Status != STATUS_SUCCESS) { ExRaiseStatus( Status ); } return FoundNextLsn; }
NTSTATUS ReleaseTimeoutPendingIrp( PDEVICE_EXTENSION DeviceExtension ) { KIRQL oldIrql; PLIST_ENTRY thisEntry, nextEntry, listHead; PIRP_ENTRY irpEntry; LARGE_INTEGER tickCount; LIST_ENTRY completeList; PIRP irp; DDbgPrint("==> ReleaseTimeoutPendingIRP\n"); InitializeListHead(&completeList); ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); KeAcquireSpinLock(&DeviceExtension->PendingIrp.ListLock, &oldIrql); // when IRP queue is empty, there is nothing to do if (IsListEmpty(&DeviceExtension->PendingIrp.ListHead)) { KeReleaseSpinLock(&DeviceExtension->PendingIrp.ListLock, oldIrql); DDbgPrint(" IrpQueue is Empty\n"); return STATUS_SUCCESS; } KeQueryTickCount(&tickCount); // search timeout IRP through pending IRP list listHead = &DeviceExtension->PendingIrp.ListHead; for (thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = nextEntry) { nextEntry = thisEntry->Flink; irpEntry = CONTAINING_RECORD(thisEntry, IRP_ENTRY, ListEntry); // this IRP is NOT timeout yet if ( (tickCount.QuadPart - irpEntry->TickCount.QuadPart) * KeQueryTimeIncrement() < DOKAN_IPR_PENDING_TIMEOUT * 10000 * 1000) { break; } RemoveEntryList(thisEntry); DDbgPrint(" timeout Irp #%X\n", irpEntry->SerialNumber); irp = irpEntry->Irp; if (irp == NULL) { // this IRP has already been canceled ASSERT(irpEntry->CancelRoutineFreeMemory == FALSE); ExFreePool(irpEntry); continue; } // this IRP is not canceled yet if (IoSetCancelRoutine(irp, NULL) == NULL) { // Cancel routine will run as soon as we release the lock InitializeListHead(&irpEntry->ListEntry); irpEntry->CancelRoutineFreeMemory = TRUE; continue; } // IrpEntry is saved here for CancelRoutine // Clear it to prevent to be completed by CancelRoutine twice irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_IRP_ENTRY] = NULL; InsertTailList(&completeList, &irpEntry->ListEntry); } if (IsListEmpty(&DeviceExtension->PendingIrp.ListHead)) { KeClearEvent(&DeviceExtension->PendingIrp.NotEmpty); } KeReleaseSpinLock(&DeviceExtension->PendingIrp.ListLock, oldIrql); while (!IsListEmpty(&completeList)) { listHead = RemoveHeadList(&completeList); irpEntry = CONTAINING_RECORD(listHead, IRP_ENTRY, ListEntry); irp = irpEntry->Irp; irp->IoStatus.Information = 0; irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; ExFreePool(irpEntry); IoCompleteRequest(irp, IO_NO_INCREMENT); } DDbgPrint("<== ReleaseTimeoutPendingIRP\n"); return STATUS_SUCCESS; }
NTSTATUS NTAPI NduDispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2; KIRQL OldIrql, OldCancelIrql; NTSTATUS Status; PLIST_ENTRY ListEntry; PNDISUIO_PACKET_ENTRY PacketEntry = NULL; ULONG BytesCopied = 0; ASSERT(DeviceObject == GlobalDeviceObject); if (OpenEntry->WriteOnly) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INVALID_PARAMETER; } /* Make the read cancellable */ IoAcquireCancelSpinLock(&OldCancelIrql); IoSetCancelRoutine(Irp, ReadIrpCancel); if (Irp->Cancel) { IoReleaseCancelSpinLock(OldCancelIrql); /* Indicate a 0 byte read */ Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } IoReleaseCancelSpinLock(OldCancelIrql); while (TRUE) { KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql); /* Check if we have a packet */ if (IsListEmpty(&AdapterContext->PacketList)) { KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql); /* Wait for a packet (in the context of the calling user thread) */ Status = KeWaitForSingleObject(&AdapterContext->PacketReadEvent, UserRequest, UserMode, TRUE, NULL); if (Status != STATUS_SUCCESS) { /* Remove the cancel routine */ IoAcquireCancelSpinLock(&OldCancelIrql); IoSetCancelRoutine(Irp, NULL); IoReleaseCancelSpinLock(OldCancelIrql); break; } } else { /* Remove the cancel routine */ IoAcquireCancelSpinLock(&OldCancelIrql); IoSetCancelRoutine(Irp, NULL); IoReleaseCancelSpinLock(OldCancelIrql); /* Remove the first packet in the list */ ListEntry = RemoveHeadList(&AdapterContext->PacketList); PacketEntry = CONTAINING_RECORD(ListEntry, NDISUIO_PACKET_ENTRY, ListEntry); /* Release the adapter lock */ KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql); /* And we're done with this loop */ Status = STATUS_SUCCESS; break; } } /* Check if we got a packet */ if (PacketEntry != NULL) { /* Find the right amount of bytes to copy */ BytesCopied = PacketEntry->PacketLength; if (BytesCopied > IrpSp->Parameters.Read.Length) BytesCopied = IrpSp->Parameters.Read.Length; /* Copy the packet */ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &PacketEntry->PacketData[0], BytesCopied); /* Free the packet entry */ ExFreePool(PacketEntry); } else { /* Something failed */ BytesCopied = 0; } /* Complete the IRP */ Irp->IoStatus.Status = Status; Irp->IoStatus.Information = BytesCopied; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); return Status; }
EXTERN_C VOID EnumProcessModuleByVM( PEPROCESS pEProcess, PALL_PROCESS_MODULE_INFO pAllModuleInf ) { ULONG dwStartAddr = 0x00000000; HANDLE hProcess; MEMORY_BASIC_INFORMATION mbi; PUNICODE_STRING pSectionNam = NULL; OBJECT_ATTRIBUTES ObjectAttributes; CLIENT_ID ClientId={0}; NTSTATUS status; int i=0; int count = -1; ULONG ulDllSize; //BOOL bInit = FALSE; //WinVer = GetWindowsVersion(); //switch(WinVer) //{ //case WINDOWS_VERSION_XP: // if (!MmIsAddressValidEx(ZwQueryVirtualMemory)){ // ZwQueryVirtualMemory = GetZwQueryVirtualMemoryAddress(); // } // break; //case WINDOWS_VERSION_7_7600_UP: //case WINDOWS_VERSION_7_7000: // ReLoadNtosCALL((PVOID)(&ZwQueryVirtualMemory),L"ZwQueryVirtualMemory",SystemKernelModuleBase,(ULONG)ImageModuleBase); //win7导出了,可以直接用 // break; //case WINDOWS_VERSION_2K3_SP1_SP2: // if (!MmIsAddressValidEx(ZwQueryVirtualMemory)){ // ZwQueryVirtualMemory = GetZwQueryVirtualMemoryAddress(); // } // break; //} //ReLoadNtosCALL((PVOID)(&RObOpenObjectByPointer),L"ObOpenObjectByPointer",SystemKernelModuleBase,(ULONG)ImageModuleBase); //ReLoadNtosCALL((PVOID)(&RExAllocatePool),L"ExAllocatePool",SystemKernelModuleBase,(ULONG)ImageModuleBase); //ReLoadNtosCALL((PVOID)(&RExFreePool),L"ExFreePool",SystemKernelModuleBase,(ULONG)ImageModuleBase); //ReLoadNtosCALL((PVOID)(&RZwClose),L"ZwClose",SystemKernelModuleBase,(ULONG)ImageModuleBase); //if (ZwQueryVirtualMemory && // RObOpenObjectByPointer && // RExAllocatePool && // RExFreePool && // RZwClose) //{ // bInit = TRUE; //} //if (!bInit) // return ; ////进程已经退出鸟 //if (!IsExitProcess((PEPROCESS)EProcess)){ // return ; //} status = ObOpenObjectByPointer( (PVOID)pEProcess, // Object OBJ_KERNEL_HANDLE, // HandleAttributes NULL, // PassedAccessState OPTIONAL (ACCESS_MASK)0, // DesiredAccess *PsProcessType, // ObjectType KernelMode, // AccessMode &hProcess); if (!NT_SUCCESS(status)) { //if (DebugOn) //KdPrint(("ObOpenObjectByPointer failed:%d",RtlNtStatusToDosError(status))); return ; } pSectionNam = (PUNICODE_STRING)ExAllocatePool(NonPagedPool, MAX_PATH * sizeof(WCHAR)); if (!pSectionNam) { ZwClose(hProcess); return; } RtlZeroMemory(pSectionNam->Buffer, MAX_PATH * sizeof(WCHAR)); pSectionNam->MaximumLength = MAX_PATH; __try { for (dwStartAddr = 0; dwStartAddr < 0x7fffffff; dwStartAddr = dwStartAddr + 0x10000) { status = ZwQueryVirtualMemory( hProcess, (PVOID)dwStartAddr, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), 0 ); if (NT_SUCCESS(status) && mbi.Type == MEM_IMAGE) { status = ZwQueryVirtualMemory( hProcess, (PVOID)dwStartAddr, MemorySectionName, pSectionNam, MAX_PATH*sizeof(WCHAR), 0 ); if (NT_SUCCESS(status) && !MmIsAddressValid(pSectionNam->Buffer)) { //如果当前的DLL模块路径 不等于前一个,则说明是开始了下一个DLL的枚举了,首先判断第一个字节是否是'\' if (((PCHAR)pSectionNam->Buffer)[0] == 0x5c) { if (count == -1 ||\ RtlCompareMemory(pAllModuleInf->vModuleInf[count].ImagePathName, pSectionNam->Buffer, pSectionNam->Length)\ != pSectionNam->Length) { RtlCopyMemory(pAllModuleInf->vModuleInf[++count].ImagePathName, pSectionNam->Buffer, pSectionNam->Length); for (ulDllSize = dwStartAddr+mbi.RegionSize; ulDllSize < 0x7fffffff; ulDllSize += mbi.RegionSize) { status = ZwQueryVirtualMemory( hProcess, (PVOID)ulDllSize, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), 0 ); if (NT_SUCCESS(status) && mbi.Type != MEM_IMAGE) { pAllModuleInf->vModuleInf[count].size = ulDllSize - dwStartAddr; } } } } } } } }__except(EXCEPTION_EXECUTE_HANDLER){} _FunctionRet: pAllModuleInf->uCount = count; ExFreePool(pSectionNam); ZwClose(hProcess); }
NTSTATUS CreateSdpRecord( _In_ PBTHDDI_SDP_NODE_INTERFACE SdpNodeInterface, _In_ PBTHDDI_SDP_PARSE_INTERFACE SdpParseInterface, _In_ const GUID * ClassId, _In_ LPWSTR Name, _In_ USHORT Psm, _Out_ PUCHAR * Stream, _Out_ ULONG * Size ) /*++ Description: Create server SDP record Arguments: SdpNodeInterface - Node interface that we obtained from bth stack SdpParseInterface - Parse interface that we obtained from bth stack ClassId - Service Class ID to publish Name - Service name to publish Psm - Server PSM Stream - receives the sdp record stream Size - receives size of sdp record stream Return Value: NTSTATUS Status code. --*/ { NTSTATUS status; PSDP_TREE_ROOT_NODE tree = NULL; PSDP_NODE seqClsIdList, seqProto, seqLang; PSDP_NODE nodeName = NULL, nodeDesc = NULL, nodeProto; UNICODE_STRING unicodeStrName; ANSI_STRING ansiStrName; PUCHAR stream = NULL; ULONG size; ULONG_PTR errorByte = 0; RtlInitUnicodeString(&unicodeStrName, Name); RtlInitAnsiString(&ansiStrName, NULL); status = RtlUnicodeStringToAnsiString(&ansiStrName, &unicodeStrName, TRUE); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Creating ANSI string for service name failed, Status code %!STATUS!\n", status); ansiStrName.Length = 0; goto exit; } tree = SdpNodeInterface->SdpCreateNodeTree( POOLTAG_BTHECHOSAMPLE ); if (NULL == tree) { status = STATUS_INSUFFICIENT_RESOURCES; TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "SdpCreateNodeTree failed, returning Status code %!STATUS!\n", status); goto exit; } // // Add ClassIdList attribute // status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_CLASS_ID_LIST, &seqClsIdList); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUuid128(SdpNodeInterface, seqClsIdList, ClassId); if (!NT_SUCCESS(status)) { goto exit; } // // Add protocols // // // L2CAP // status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST, &seqProto); if (!NT_SUCCESS(status)) { goto exit; } status = AppendSeqNode(SdpNodeInterface, seqProto, &nodeProto); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUuid16(SdpNodeInterface, nodeProto, L2CAP_PROTOCOL_UUID16); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, nodeProto, Psm); if (!NT_SUCCESS(status)) { goto exit; } // // SDP // status = AppendSeqNode(SdpNodeInterface, seqProto, &nodeProto); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUuid16(SdpNodeInterface, nodeProto, SDP_PROTOCOL_UUID16); if (!NT_SUCCESS(status)) { goto exit; } // // Add lang attributes // status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_LANG_BASE_ATTRIB_ID_LIST, &seqLang); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x656e); //TODO: find constants for these if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x006A); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x0100); if (!NT_SUCCESS(status)) { goto exit; } // // Add service name // nodeName = SdpNodeInterface->SdpCreateNodeString( ansiStrName.Buffer, ansiStrName.Length, POOLTAG_BTHECHOSAMPLE ); if(NULL == nodeName) { status = STATUS_INSUFFICIENT_RESOURCES; TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Creating node for service name failed, Status code %!STATUS!\n", status); goto exit; } status = SdpNodeInterface->SdpAddAttributeToTree( tree, LANG_DEFAULT_ID+STRING_NAME_OFFSET, nodeName, POOLTAG_BTHECHOSAMPLE ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "SdpAddAttributeToTree for service name failed, Status code %!STATUS!\n", status); goto exit; } nodeName = NULL; //transferred owenership to tree nodeDesc = SdpNodeInterface->SdpCreateNodeString( ansiStrName.Buffer, ansiStrName.Length, POOLTAG_BTHECHOSAMPLE ); if(NULL == nodeDesc) { status = STATUS_INSUFFICIENT_RESOURCES; TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Creating node for service desc failed, Status code %!STATUS!\n", status); goto exit; } status = SdpNodeInterface->SdpAddAttributeToTree( tree, LANG_DEFAULT_ID+STRING_DESCRIPTION_OFFSET, nodeDesc, POOLTAG_BTHECHOSAMPLE ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "SdpAddAttributeToTree for service desc failed, Status code %!STATUS!\n", status); goto exit; } nodeDesc = NULL; // // Create stream from tree // status = SdpParseInterface->SdpConvertTreeToStream(tree, &stream, &size, POOLTAG_BTHECHOSAMPLE); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Failed to get stream from tree for SDP record, Status code %!STATUS!\n", status); goto exit; } status = SdpParseInterface->SdpValidateStream( stream, size, &errorByte ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Validate stream failed for SDP record, first failure at address %p\n", (PVOID)errorByte); goto exit; } *Stream = stream; *Size = size; exit: if (NULL != tree) { SdpNodeInterface->SdpFreeTree(tree); } if (NULL != nodeName) { // // If we failed to add attribute to tree use ExFreePool to free it // ExFreePool(nodeName); } if (NULL != nodeDesc) { // // If we failed to add attribute to tree use ExFreePool to free it // ExFreePool(nodeDesc); } RtlFreeAnsiString(&ansiStrName); if (!NT_SUCCESS(status)) { if (stream != NULL) { ExFreePoolWithTag(stream, POOLTAG_BTHECHOSAMPLE); } } return status; }
void STDCALL free_cache() { ExFreePool(cache_callbacks); }
NTSTATUS TapeSetMediaParameters( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine sets the fixed-length logical block size or variable-length block mode (if the block size is 0). Arguments: DeviceObject Irp Return Value: NTSTATUS --*/ { PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; PTAPE_SET_MEDIA_PARAMETERS tapeSetMediaParams = Irp->AssociatedIrp.SystemBuffer; PMODE_PARM_READ_WRITE_DATA buffer; SCSI_REQUEST_BLOCK srb; PCDB cdb = (PCDB)srb.Cdb; NTSTATUS status; DebugPrint((3,"TapeIoControl: Set Tape Media Parameters \n")); // // Zero CDB in SRB on stack. // RtlZeroMemory(cdb, MAXIMUM_CDB_SIZE); srb.CdbLength = CDB6GENERIC_LENGTH; cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT; // // Set timeout value. // srb.TimeOutValue = deviceExtension->TimeOutValue; cdb->MODE_SELECT.ParameterListLength = sizeof(MODE_PARM_READ_WRITE_DATA); cdb->MODE_SELECT.Reserved1 = MODE_SELECT_PFBIT; buffer = ExAllocatePool(NonPagedPoolCacheAligned, sizeof(MODE_PARM_READ_WRITE_DATA)); if (!buffer) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(buffer, sizeof(MODE_PARM_READ_WRITE_DATA)); buffer->ParameterListHeader.DeviceSpecificParameter = 0x10; buffer->ParameterListHeader.BlockDescriptorLength = MODE_BLOCK_DESC_LENGTH; buffer->ParameterListBlock.BlockLength[0] = (UCHAR)((tapeSetMediaParams->BlockSize >> 16) & 0xFF); buffer->ParameterListBlock.BlockLength[1] = (UCHAR)((tapeSetMediaParams->BlockSize >> 8) & 0xFF); buffer->ParameterListBlock.BlockLength[2] = (UCHAR)(tapeSetMediaParams->BlockSize & 0xFF); status = ScsiClassSendSrbSynchronous(DeviceObject, &srb, buffer, sizeof( MODE_PARM_READ_WRITE_DATA ), TRUE); ExFreePool(buffer); return status; } // end TapeSetMediaParameters()
NTSTATUS TapeGetMediaParameters( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: The OVERLAND 9-track tape device can return whether media is write-protected. Arguments: DeviceObject Irp Return Value: NTSTATUS --*/ { PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; PTAPE_GET_MEDIA_PARAMETERS tapeGetMediaParams = Irp->AssociatedIrp.SystemBuffer; PNINE_TRACKSENSE_DATA buffer; SCSI_REQUEST_BLOCK srb; PCDB cdb = (PCDB)srb.Cdb; NTSTATUS status; DebugPrint((3,"TapeGetMediaParameters: Get Tape Media Parameters\n")); // // Zero SRB on stack. // RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK)); srb.CdbLength = CDB6GENERIC_LENGTH; cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE; // // Set timeout value. // srb.TimeOutValue = deviceExtension->TimeOutValue; cdb->MODE_SENSE.AllocationLength = sizeof(NINE_TRACKSENSE_DATA); cdb->MODE_SENSE.PageCode = MODE_SENSE_CURRENT_VALUES; cdb->MODE_SENSE.Pc = 0x0B; buffer = ExAllocatePool(NonPagedPoolCacheAligned, sizeof(NINE_TRACKSENSE_DATA)); if (!buffer) { return STATUS_INSUFFICIENT_RESOURCES; } status = ScsiClassSendSrbSynchronous(DeviceObject, &srb, buffer, sizeof(NINE_TRACKSENSE_DATA), FALSE); if (status == STATUS_DATA_OVERRUN) { status = STATUS_SUCCESS; } if (NT_SUCCESS(status)) { Irp->IoStatus.Information = sizeof(TAPE_GET_MEDIA_PARAMETERS); tapeGetMediaParams->BlockSize = buffer->BlockLength[2]; tapeGetMediaParams->BlockSize += buffer->BlockLength[1] << 8; tapeGetMediaParams->BlockSize += buffer->BlockLength[0] << 16; tapeGetMediaParams->WriteProtected = buffer->WriteProtected; tapeGetMediaParams->PartitionCount = 0; } ExFreePool(buffer); return status; return status; } // end TapeGetMediaParameters()
NTSTATUS FatPostStackOverflowRead ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PFCB Fcb ) /*++ Routine Description: This routine posts a read request that could not be processed by the fsp thread because of stack overflow potential. Arguments: Irp - Supplies the request to process. Fcb - Supplies the file. Return Value: STATUS_PENDING. --*/ { PKEVENT Event; PERESOURCE Resource; DebugTrace(0, Dbg, "Getting too close to stack limit pass request to Fsp\n", 0 ); // // Allocate an event and get shared on the resource we will // be later using the common read. // Event = FsRtlAllocatePool( NonPagedPool, sizeof(KEVENT) ); KeInitializeEvent( Event, NotificationEvent, FALSE ); if (FlagOn(Irp->Flags, IRP_PAGING_IO) && (Fcb->Header.PagingIoResource != NULL)) { Resource = Fcb->Header.PagingIoResource; } else { Resource = Fcb->Header.Resource; } ExAcquireResourceShared( Resource, TRUE ); try { // // Make the Irp just like a regular post request and // then send the Irp to the special overflow thread. // After the post we will wait for the stack overflow // read routine to set the event that indicates we can // now release the scb resource and return. // FatPrePostIrp( IrpContext, Irp ); // // If this read is the result of a verify, we have to // tell the overflow read routne to temporarily // hijack the Vcb->VerifyThread field so that reads // can go through. // if (Fcb->Vcb->VerifyThread == KeGetCurrentThread()) { SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_VERIFY_READ); } FsRtlPostStackOverflow( IrpContext, Event, FatStackOverflowRead ); // // And wait for the worker thread to complete the item // (VOID) KeWaitForSingleObject( Event, Executive, KernelMode, FALSE, NULL ); } finally { ExReleaseResource( Resource ); ExFreePool( Event ); } return STATUS_PENDING; }
VOID NTAPI LpcpDestroyPortQueue(IN PLPCP_PORT_OBJECT Port, IN BOOLEAN Destroy) { PLIST_ENTRY ListHead, NextEntry; PETHREAD Thread; PLPCP_MESSAGE Message; PLPCP_PORT_OBJECT ConnectionPort = NULL; PLPCP_CONNECTION_MESSAGE ConnectMessage; PAGED_CODE(); LPCTRACE(LPC_CLOSE_DEBUG, "Port: %p. Flags: %lx\n", Port, Port->Flags); /* Hold the lock */ KeAcquireGuardedMutex(&LpcpLock); /* Check if we have a connected port */ if (((Port->Flags & LPCP_PORT_TYPE_MASK) != LPCP_UNCONNECTED_PORT) && (Port->ConnectedPort)) { /* Disconnect it */ Port->ConnectedPort->ConnectedPort = NULL; ConnectionPort = Port->ConnectedPort->ConnectionPort; if (ConnectionPort) { /* Clear connection port */ Port->ConnectedPort->ConnectionPort = NULL; } } /* Check if this is a connection port */ if ((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_CONNECTION_PORT) { /* Delete the name */ Port->Flags |= LPCP_NAME_DELETED; } /* Walk all the threads waiting and signal them */ ListHead = &Port->LpcReplyChainHead; NextEntry = ListHead->Flink; while ((NextEntry) && (NextEntry != ListHead)) { /* Get the Thread */ Thread = CONTAINING_RECORD(NextEntry, ETHREAD, LpcReplyChain); /* Make sure we're not in exit */ if (Thread->LpcExitThreadCalled) break; /* Move to the next entry */ NextEntry = NextEntry->Flink; /* Remove and reinitialize the List */ RemoveEntryList(&Thread->LpcReplyChain); InitializeListHead(&Thread->LpcReplyChain); /* Check if someone is waiting */ if (!KeReadStateSemaphore(&Thread->LpcReplySemaphore)) { /* Get the message */ Message = LpcpGetMessageFromThread(Thread); if (Message) { /* Check if it's a connection request */ if (Message->Request.u2.s2.Type == LPC_CONNECTION_REQUEST) { /* Get the connection message */ ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1); /* Check if it had a section */ if (ConnectMessage->SectionToMap) { /* Dereference it */ ObDereferenceObject(ConnectMessage->SectionToMap); } } /* Clear the reply message */ Thread->LpcReplyMessage = NULL; /* And remove the message from the port zone */ LpcpFreeToPortZone(Message, 1); NextEntry = Port->LpcReplyChainHead.Flink; } /* Release the semaphore and reset message id count */ Thread->LpcReplyMessageId = 0; KeReleaseSemaphore(&Thread->LpcReplySemaphore, 0, 1, FALSE); } } /* Reinitialize the list head */ InitializeListHead(&Port->LpcReplyChainHead); /* Loop queued messages */ while ((Port->MsgQueue.ReceiveHead.Flink) && !(IsListEmpty(&Port->MsgQueue.ReceiveHead))) { /* Get the message */ Message = CONTAINING_RECORD(Port->MsgQueue.ReceiveHead.Flink, LPCP_MESSAGE, Entry); /* Free and reinitialize it's list head */ RemoveEntryList(&Message->Entry); InitializeListHead(&Message->Entry); /* Remove it from the port zone */ LpcpFreeToPortZone(Message, 1); } /* Release the lock */ KeReleaseGuardedMutex(&LpcpLock); /* Dereference the connection port */ if (ConnectionPort) ObDereferenceObject(ConnectionPort); /* Check if we have to free the port entirely */ if (Destroy) { /* Check if the semaphore exists */ if (Port->MsgQueue.Semaphore) { /* Use the semaphore to find the port queue and free it */ ExFreePool(CONTAINING_RECORD(Port->MsgQueue.Semaphore, LPCP_NONPAGED_PORT_QUEUE, Semaphore)); } } }
NTSTATUS IrpCreateFile( IN PUNICODE_STRING FileName, IN ACCESS_MASK DesiredAccess, __out PIO_STATUS_BLOCK IoStatusBlock, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT RealDevice, OUT PFILE_OBJECT *Object ) { NTSTATUS status; KEVENT event; PIRP irp; PIO_STACK_LOCATION irpSp; IO_SECURITY_CONTEXT securityContext; ACCESS_STATE accessState; OBJECT_ATTRIBUTES objectAttributes; PFILE_OBJECT fileObject; AUX_ACCESS_DATA auxData; PAGED_CODE(); RtlZeroMemory(&auxData, sizeof(AUX_ACCESS_DATA)); InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE| OBJ_KERNEL_HANDLE, 0, NULL); status = ObCreateObject(KernelMode, *IoFileObjectType, &objectAttributes, KernelMode, NULL, sizeof(FILE_OBJECT), 0, 0, (PVOID *)&fileObject); if (!NT_SUCCESS(status)) { return status; } RtlZeroMemory(fileObject, sizeof(FILE_OBJECT)); fileObject->Type = IO_TYPE_FILE; fileObject->Size = sizeof(FILE_OBJECT); fileObject->DeviceObject = RealDevice; // fileObject->RelatedFileObject = NULL; fileObject->Flags = FO_SYNCHRONOUS_IO; fileObject->FileName.MaximumLength = FileName->MaximumLength; fileObject->FileName.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, FileName->MaximumLength, 'File'); //fileObject->FileObjectExtension if (fileObject->FileName.Buffer == NULL) { ObDereferenceObject(fileObject); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&fileObject->FileName, FileName); KeInitializeEvent(&fileObject->Lock, SynchronizationEvent, FALSE); KeInitializeEvent(&fileObject->Event, NotificationEvent, FALSE); irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (irp == NULL) { ObDereferenceObject(fileObject); return STATUS_INSUFFICIENT_RESOURCES; } KeInitializeEvent(&event, SynchronizationEvent, FALSE); irp->MdlAddress = NULL; irp->Flags |= IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API; irp->RequestorMode = KernelMode; irp->UserIosb = IoStatusBlock; ////LCXL:CHANGE irp->UserEvent = &event; //irp->UserEvent = NULL; irp->PendingReturned = FALSE; irp->Cancel = FALSE; irp->CancelRoutine = NULL; irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread(); irp->Tail.Overlay.AuxiliaryBuffer = NULL; irp->Tail.Overlay.OriginalFileObject = fileObject; status = SeCreateAccessState(&accessState, &auxData, DesiredAccess, IoGetFileObjectGenericMapping()); if (!NT_SUCCESS(status)) { IoFreeIrp(irp); ExFreePool(fileObject->FileName.Buffer); ObDereferenceObject(fileObject); return status; } securityContext.SecurityQos = NULL; securityContext.AccessState = &accessState; securityContext.DesiredAccess = DesiredAccess; securityContext.FullCreateOptions = 0; irpSp = IoGetNextIrpStackLocation(irp); irpSp->MajorFunction = IRP_MJ_CREATE; irpSp->DeviceObject = DeviceObject; irpSp->FileObject = fileObject; irpSp->Parameters.Create.SecurityContext = &securityContext; irpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions; irpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes; irpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess; irpSp->Parameters.Create.EaLength = 0; IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE); status = IoCallDriver(DeviceObject, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL); } status = IoStatusBlock->Status; if (!NT_SUCCESS(status)) { ExFreePool(fileObject->FileName.Buffer); fileObject->FileName.Length = 0; fileObject->DeviceObject = NULL; ObDereferenceObject(fileObject); } else { InterlockedIncrement(&fileObject->DeviceObject->ReferenceCount); if (fileObject->Vpb) { InterlockedIncrement((PLONG)&fileObject->Vpb->ReferenceCount); } *Object = fileObject; KdPrint(("IrpCreateFile:Open file success! object = %x\n", fileObject)); } return status; }
NTSTATUS UpdateDeviceInformation( PDEVICE_OBJECT fdo ) { PUSB_STRING_DESCRIPTOR desc; UNICODE_STRING dummy; URB urb; int id; NTSTATUS status; KdPrint((DRIVERNAME " - UpdateDeviceInformation\n")); status = STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; // initialize buffers pdx->manufacturer.Buffer = NULL; pdx->product .Buffer = NULL; pdx->serialNumber.Buffer = NULL; pdx->displayName .Buffer = NULL; desc = NULL; // allocate buffers for all strings pdx->manufacturer.Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); pdx->product .Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); pdx->serialNumber.Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); pdx->displayName .Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); if( (pdx->manufacturer.Buffer == NULL) || (pdx->product .Buffer == NULL) || (pdx->serialNumber.Buffer == NULL) || (pdx->displayName .Buffer == NULL) ) { KdPrint((DRIVERNAME " - Unable to allocate memory for device info\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } pdx->manufacturer.Length = 0; pdx->manufacturer.MaximumLength = StringDescriptorBytes; pdx->product .Length = 0; pdx->product .MaximumLength = StringDescriptorBytes; pdx->serialNumber.Length = 0; pdx->serialNumber.MaximumLength = StringDescriptorBytes; pdx->displayName .Length = 0; pdx->displayName .MaximumLength = StringDescriptorBytes; // allocate buffer for device string descriptor requests desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG ); if(!desc) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } if(0 != pdx->dd.iManufacturer) { // Manufacturer UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, pdx->dd.iManufacturer, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->manufacturer, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->manufacturer, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve manufacturer %08x\n", status )); } } if(0 != pdx->dd.iProduct) { // Product UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, pdx->dd.iProduct, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->product, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->product, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve product %08x\n", status )); } } if(0 != pdx->dd.iSerialNumber) { // Serial Number UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, pdx->dd.iSerialNumber, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->serialNumber, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->serialNumber, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve serial number %08x\n", status )); } } // DisplayName UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, DisplayNameId, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->displayName, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->displayName, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve display name %08x\n", status )); } cleanup: if(desc) ExFreePool( desc ); if(!NT_SUCCESS(status)) { if(pdx->manufacturer.Buffer) ExFreePool( pdx->manufacturer.Buffer ); if(pdx->product .Buffer) ExFreePool( pdx->product .Buffer ); if(pdx->serialNumber.Buffer) ExFreePool( pdx->serialNumber.Buffer ); if(pdx->displayName .Buffer) ExFreePool( pdx->displayName .Buffer ); pdx->manufacturer.Buffer = NULL; pdx->product .Buffer = NULL; pdx->serialNumber.Buffer = NULL; pdx->displayName .Buffer = NULL; } return status; }
NTSTATUS transfer(libusb_device_t *dev, IRP *irp, int direction, int urb_function, int endpoint, int packet_size, MDL *buffer, int size) { IO_STACK_LOCATION *stack_location = NULL; context_t *context; NTSTATUS status = STATUS_SUCCESS; DEBUG_PRINT_NL(); if(urb_function == URB_FUNCTION_ISOCH_TRANSFER) DEBUG_MESSAGE("transfer(): isochronous transfer"); else DEBUG_MESSAGE("transfer(): bulk or interrupt transfer"); if(direction == USBD_TRANSFER_DIRECTION_IN) DEBUG_MESSAGE("transfer(): direction in"); else DEBUG_MESSAGE("transfer(): direction out"); DEBUG_MESSAGE("transfer(): endpoint 0x%02x", endpoint); if(urb_function == URB_FUNCTION_ISOCH_TRANSFER) DEBUG_MESSAGE("transfer(): packet_size 0x%x", packet_size); DEBUG_MESSAGE("transfer(): size %d", size); DEBUG_MESSAGE("transfer(): sequence %d", sequence); DEBUG_PRINT_NL(); if(!dev->config.value) { DEBUG_ERROR("transfer(): invalid configuration 0"); remove_lock_release(dev); return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0); } context = ExAllocatePool(NonPagedPool, sizeof(context_t)); if(!context) { remove_lock_release(dev); return complete_irp(irp, STATUS_NO_MEMORY, 0); } status = create_urb(dev, &context->urb, direction, urb_function, endpoint, packet_size, buffer, size); if(!NT_SUCCESS(status)) { ExFreePool(context); remove_lock_release(dev); return complete_irp(irp, status, 0); } context->sequence = sequence++; stack_location = IoGetNextIrpStackLocation(irp); stack_location->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; stack_location->Parameters.Others.Argument1 = context->urb; stack_location->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(irp, transfer_complete, context, TRUE, TRUE, TRUE); return IoCallDriver(dev->target_device, irp); }
NTSTATUS StartDevice( PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated ) { USB_CONFIGURATION_DESCRIPTOR tcd; PUSB_CONFIGURATION_DESCRIPTOR pcd; PUSB_STRING_DESCRIPTOR desc; HANDLE RecoveryHandle; PURB selurb; URB urb; NTSTATUS status; status = STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; selurb = NULL; pcd = NULL; // Read our device descriptor. The only real purpose to this would be to find out how many // configurations there are so we can read their descriptors. In this simplest of examples, // there's only one configuration. KdPrint((DRIVERNAME " - Start device\n")); UsbBuildGetDescriptorRequest( &urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_DEVICE_DESCRIPTOR_TYPE, 0, LangId, &pdx->dd, NULL, sizeof(pdx->dd), NULL ); status = SendAwaitUrb( fdo, &urb ); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to retrieve device descriptor\n", status)); goto cleanup; } // allocate the buffer for the descriptor; take extra space to null terminate the bString member desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG ); if(!desc) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } pdx->devHash = desc; UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, DeviceId, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to retrieve string descriptor for DeviceId\n", status)); goto cleanup; } // null terminate the buffer; we allocated one more wchar_t for the purpose desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; UpdateDeviceInformation( fdo ); // Read the descriptor of the first configuration. This requires two steps. The first step // reads the fixed-size configuration descriptor alone. The second step reads the // configuration descriptor plus all imbedded interface and endpoint descriptors. UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, LangId, &tcd, NULL, sizeof(tcd), NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status)); goto cleanup; } ULONG size = tcd.wTotalLength; pcd = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size, SPOT_TAG); if(!pcd) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for configuration descriptor\n", size)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, LangId, pcd, NULL, size, NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status)); goto cleanup; } // Locate the descriptor for the one and only interface we expect to find PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pcd, pcd, -1, -1, -1, -1, -1); ASSERT(pid); // Create a URB to use in selecting a configuration. USBD_INTERFACE_LIST_ENTRY interfaces[2] = { {pid, NULL}, {NULL, NULL}, // fence to terminate the array }; selurb = USBD_CreateConfigurationRequestEx(pcd, interfaces); if(!selurb) { KdPrint((DRIVERNAME " - Unable to create configuration request\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } // Verify that the interface describes exactly the endpoints we expect if(pid->bNumEndpoints != 2) { KdPrint((DRIVERNAME " - %d is the wrong number of endpoints\n", pid->bNumEndpoints)); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } PUSB_ENDPOINT_DESCRIPTOR ped = (PUSB_ENDPOINT_DESCRIPTOR) pid; ped = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(pcd, tcd.wTotalLength, ped, USB_ENDPOINT_DESCRIPTOR_TYPE); if(!ped || 0 == (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64) { KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n")); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } ++ped; if(!ped || 0 != (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64) { KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n")); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } ++ped; PUSBD_INTERFACE_INFORMATION pii = interfaces[0].Interface; ASSERT(pii->NumberOfPipes == pid->bNumEndpoints); // Initialize the maximum transfer size for each of the endpoints. The // default would be PAGE_SIZE. The firmware itself only has a 4096-byte // ring buffer, though. We need to restrict the test applet to that many // bytes. In order to exercise the multi-segment aspect of the transfer code, // therefore, reduce the maximum transfer size to 1024 bytes. pii->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; pii->Pipes[1].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; pdx->maxtransfer = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; // Submit the set-configuration request status = SendAwaitUrb(fdo, selurb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to select configuration\n", status)); goto cleanup; } // Save the configuration and pipe handles pdx->hconfig = selurb->UrbSelectConfiguration.ConfigurationHandle; pdx->hinpipe = pii->Pipes[0].PipeHandle; pdx->houtpipe = pii->Pipes[1].PipeHandle; // Transfer ownership of the configuration descriptor to the device extension pdx->pcd = pcd; pcd = NULL; // Enable the interface IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, TRUE); // Enable the interface IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, TRUE); // create recovery thread status = PsCreateSystemThread(&RecoveryHandle, 0, NULL, NULL, NULL, RecoveryThread, (PVOID)pdx); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - PsCreateSystemThread failed with error %08x\n", status)); goto cleanup; } status = ObReferenceObjectByHandle( RecoveryHandle, SYNCHRONIZE, NULL, KernelMode, (PVOID*)&pdx->RecoveryThread, NULL ); ASSERT(NT_SUCCESS(status)); ZwClose(RecoveryHandle); // Start polling status = StartPolling(pdx); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - StartPolling failed 0x%08x\n", status)); if(pdx->RecoveryThread) { // shutdown recovery thread pdx->RecoveryExit = TRUE; KeSetEvent(&pdx->RecoveryEvent, 0, FALSE); // wait for polling thread to exit KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(pdx->RecoveryThread); pdx->RecoveryThread = NULL; } goto cleanup; } cleanup: if(selurb) ExFreePool(selurb); if(pcd ) ExFreePool(pcd ); // get rid of return codes like STATUS_PENDING if(NT_SUCCESS(status)) { return STATUS_SUCCESS; } return status; }
VOID LfsFindLogRecord ( IN PLFCB Lfcb, IN OUT PLfsLCB Lcb, IN LSN Lsn, OUT PLFS_RECORD_TYPE RecordType, OUT TRANSACTION_ID *TransactionId, OUT PLSN UndoNextLsn, OUT PLSN PreviousLsn, OUT PULONG BufferLength, OUT PVOID *Buffer ) /*++ Routine Description: This routine is called recover a log record for a client. Arguments: Lfcb - Log file control block for this file. Lcb - Pointer to the context block to update. Lsn - This is the Lsn for the log record. RecordType - Supplies the address to store the record type of this log record. TransactionId - Supplies the address to store the transaction Id of this log record. UndoNextLsn - Supplies the address to store the Undo Next Lsn for this log record. PreviousLsn - Supplies the address to store the Previous Lsn for this log record. BufferLength - Pointer to address to store the length in bytes of the log record. Buffer - Pointer to store the address where the log record data begins. Return Value: None --*/ { PCHAR NewBuffer; BOOLEAN UsaError; LONGLONG LogRecordLength; ULONG PageOffset; PAGED_CODE(); LfsDebugTrace( +1, Dbg, "LfsFindLogRecord: Entered\n", 0 ); LfsDebugTrace( 0, Dbg, "Lfcb -> %08lx\n", Lfcb ); LfsDebugTrace( 0, Dbg, "Context Block -> %08lx\n", Lcb ); LfsDebugTrace( 0, Dbg, "Lsn (Low) -> %08lx\n", Lsn.LowPart ); NewBuffer = NULL; // // Use a try-finally to facilitate cleanup. // __try { // // Map the record header for this Lsn if we haven't already. // if (Lcb->RecordHeader == NULL) { LfsPinOrMapLogRecordHeader( Lfcb, Lsn, FALSE, FALSE, &UsaError, &Lcb->RecordHeader, &Lcb->RecordHeaderBcb ); } // // We now have the log record desired. If the Lsn in the // log record doesn't match the desired Lsn then the disk is // corrupt. // if ( Lsn.QuadPart != Lcb->RecordHeader->ThisLsn.QuadPart ) { //**** xxNeq( Lsn, Lcb->RecordHeader->ThisLsn ) ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR ); } // // Check that the length field isn't greater than the total available space // in the log file. // LogRecordLength = Lcb->RecordHeader->ClientDataLength + Lfcb->RecordHeaderLength; //**** xxFromUlong( Lcb->RecordHeader->ClientDataLength + Lfcb->RecordHeaderLength ); if ( LogRecordLength >= Lfcb->TotalAvailable ) { //**** xxGeq( LogRecordLength, Lfcb->TotalAvailable ) ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR ); } // // If the entire log record is on this log page, put a pointer to // the log record in the context block. // if (!FlagOn( Lcb->RecordHeader->Flags, LOG_RECORD_MULTI_PAGE )) { // // If client size indicates that we have to go beyond the end of the current // page, we raise an error. // PageOffset = LfsLsnToPageOffset( Lfcb, Lsn ); if ((PageOffset + Lcb->RecordHeader->ClientDataLength + Lfcb->RecordHeaderLength) > (ULONG)Lfcb->LogPageSize) { ExRaiseStatus( STATUS_DISK_CORRUPT_ERROR ); } Lcb->CurrentLogRecord = LfsAdd2Ptr( Lcb->RecordHeader, LFS_RECORD_HEADER_SIZE, PVOID ); Lcb->AuxilaryBuffer = FALSE; // // Else we copy the data and remember that we allocated a buffer. // } else { NewBuffer = FsRtlAllocatePool( PagedPool, Lcb->RecordHeader->ClientDataLength ); LfsCopyReadLogRecord( Lfcb, Lcb->RecordHeader, NewBuffer ); Lcb->CurrentLogRecord = NewBuffer; Lcb->AuxilaryBuffer = TRUE; NewBuffer = NULL; } // // We need to update the caller's parameters and the context block. // *RecordType = Lcb->RecordHeader->RecordType; *TransactionId = Lcb->RecordHeader->TransactionId; *UndoNextLsn = Lcb->RecordHeader->ClientUndoNextLsn; *PreviousLsn = Lcb->RecordHeader->ClientPreviousLsn; *Buffer = Lcb->CurrentLogRecord; *BufferLength = Lcb->RecordHeader->ClientDataLength; } __finally { DebugUnwind( LfsFindLogRecord ); // // If an error occurred we unpin the record header and the log // We also free the buffer if allocated by us. // if (NewBuffer != NULL) { ExFreePool( NewBuffer ); } LfsDebugTrace( 0, Dbg, "Buffer Length -> %08lx\n", *BufferLength ); LfsDebugTrace( 0, Dbg, "Buffer -> %08lx\n", *Buffer ); LfsDebugTrace( -1, Dbg, "LfsFindLogRecord: Exit\n", 0 ); } return; }
NTSTATUS OnWriteComplete(PDEVICE_OBJECT fdo, PIRP Irp, PRWCONTEXT ctx) { PIO_STACK_LOCATION stack; NTSTATUS status; ULONG length; KIRQL OldIrql; ULONG count; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; status = Irp->IoStatus.Status; if(NT_SUCCESS(status) && ctx->remain && !Irp->Cancel) { /* we have more to transfer */ length = ctx->remain; if(length > pdx->maxtransfer) length = pdx->maxtransfer; UsbBuildInterruptOrBulkTransferRequest(&ctx->urb, sizeof(_URB_BULK_OR_INTERRUPT_TRANSFER), pdx->houtpipe, ctx->data, NULL, length, (USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK), NULL); ctx->data += length; ctx->remain -= length; stack = IoGetNextIrpStackLocation(Irp); stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; stack->Parameters.Others.Argument1 = (PVOID)&ctx->urb; stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)OnWriteComplete, (PVOID) ctx, TRUE, TRUE, TRUE); IoCallDriver(pdx->LowerDeviceObject, Irp); return STATUS_MORE_PROCESSING_REQUIRED; } if(NT_SUCCESS(status)) { Irp->IoStatus.Information = ctx->total; } else { KdPrint((DRIVERNAME " - finished with error!\n")); } ExFreePool(ctx); StartNextPacket ( &pdx->dqWrite, fdo ); IoReleaseRemoveLock( &pdx->RemoveLock, Irp ); return STATUS_SUCCESS; }
/* Source: WDK/src_5239/kmdf/1394/isochapi.c, line 679. */ NTSTATUS t1394_IsochFreeResources( PDEVICE_EXTENSION deviceExtension, /* added for SLAyer */ /* IN WDFDEVICE Device, */ /* IN WDFREQUEST Request, */ /* IN */ HANDLE hResource ) { NTSTATUS ntStatus = STATUS_SUCCESS; /* PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); */ PIRB pIrb = NULL; PISOCH_RESOURCE_DATA IsochResourceData = NULL; PLIST_ENTRY listHead; PLIST_ENTRY thisEntry; /* ENTER("t1394_IsochFreeResources"); */ /* TRACE(TL_TRACE, ("hResource = 0x%x\n", hResource)); */ pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_1394); if (!pIrb) { /* TRACE(TL_ERROR, ("Failed to allocate pIrb!\n")); */ ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto Exit_IsochFreeResources; } // if // remove this one from our list... WdfSpinLockAcquire(deviceExtension->IsochResourceSpinLock); listHead = &deviceExtension->IsochResourceData; for(thisEntry = listHead->Flink; thisEntry != listHead; IsochResourceData = NULL, thisEntry = thisEntry->Flink) { IsochResourceData = CONTAINING_RECORD(thisEntry, ISOCH_RESOURCE_DATA, IsochResourceList); if (IsochResourceData->hResource == hResource) { /* TRACE(TL_TRACE, ("Removing hResource = 0x%x\n", hResource)); */ RemoveEntryList(&IsochResourceData->IsochResourceList); ExFreePool(IsochResourceData); break; } } WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock); RtlZeroMemory (pIrb, sizeof (IRB)); /* pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES; */ pIrb->Flags = 0; /* pIrb->u.IsochFreeResources.hResource = hResource; */ /* ntStatus = t1394_SubmitIrpSynch(deviceExtension->StackIoTarget, Request, pIrb); */ if (!NT_SUCCESS(ntStatus)) { /* TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus)); */ } Exit_IsochFreeResources: if (pIrb) { ExFreePool(pIrb); } /* EXIT("t1394_IsochFreeResources", ntStatus); */ return(ntStatus); } // t1394_IsochFreeResources
NTSTATUS LspCleanupLock( PLANSCSI_SESSION LSS, UCHAR LockNo ){ NTSTATUS status; LONG i; LANSCSI_PDUDESC pduDesc; BYTE pduResponse; PLANSCSI_SESSION tempLSS; LONG maxConn; LARGE_INTEGER GenericTimeOut; TA_LSTRANS_ADDRESS BindingAddress, TargetAddress; LSSLOGIN_INFO loginInfo; LSPROTO_TYPE LSProto; ULONG cleaned; // // Parameter check // if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) { return STATUS_NOT_SUPPORTED; } if(LSS->HWVersion >= 1) { maxConn = LANSCSIIDE_MAX_CONNECTION_VER11 - 1; } else { return STATUS_NOT_SUPPORTED; } tempLSS = ExAllocatePoolWithTag( NonPagedPool, maxConn * sizeof(LANSCSI_SESSION), LSS_POOLTAG); RtlZeroMemory(tempLSS, maxConn * sizeof(LANSCSI_SESSION)); // // Init variables // status = STATUS_SUCCESS; RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC)); pduDesc.Param8[3] = (UCHAR)LockNo; LspGetAddresses(LSS, &BindingAddress, &TargetAddress); GenericTimeOut.QuadPart = NANO100_PER_SEC * 5; cleaned = 0; // // Try to make connections to fill up connection pool of the NDAS device. // So, we can clear invalid acquisition of the locks. // KDPrintM(DBG_LURN_ERROR,("Try to clean up lock\n")); for (i=0 ; i < maxConn; i++) { // // Connect and log in with read-only access. // // connect LspSetTimeOut(&tempLSS[i], &GenericTimeOut); status = LspConnect( &tempLSS[i], &BindingAddress, &TargetAddress ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_LURN_ERROR, ("LspConnect(), Can't Connect to the LS node. STATUS:0x%08x\n", status)); break; } } for (i=0; i < maxConn; i++) { if(!LspIsConnected(&tempLSS[i])) { continue; } KDPrintM(DBG_LURN_TRACE, ("Con#%u\n", i)); cleaned++; // extract login information from the existing LSS. LspBuildLoginInfo(LSS, &loginInfo); status = LspLookupProtocol(loginInfo.HWType, loginInfo.HWVersion, &LSProto); if(!NT_SUCCESS(status)) { LspDisconnect(&tempLSS[i]); KDPrintM(DBG_LURN_ERROR, ("Wrong hardware version.\n")); continue; } // Log in with read-only access. if (loginInfo.HWVersion == LANSCSIIDE_VERSION_2_5) { loginInfo.UserID = MAKE_USER_ID(DEFAULT_USER_NUM, USER_PERMISSION_RO); } else { loginInfo.UserID &= 0x0000ffff; } status = LspLogin( &tempLSS[i], &loginInfo, LSProto, FALSE ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_LURN_ERROR, ("LspLogin() failed. STATUS:0x%08x\n", status)); LspDisconnect(&tempLSS[i]); ASSERT(FALSE); continue; } // // Acquire the lock on the NDAS device. // pduDesc.Command = VENDOR_OP_SET_MUTEX; status = LspVendorRequest( &tempLSS[i], &pduDesc, &pduResponse ); if(pduResponse != LANSCSI_RESPONSE_SUCCESS) { KDPrintM(DBG_LURN_ERROR, ("Acquiring lock #%u denied by NDAS device\n", LockNo)); } if(!NT_SUCCESS(status)) { LspDisconnect(&tempLSS[i]); KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status)); continue; } // // Release the lock on the NDAS device. // pduDesc.Command = VENDOR_OP_FREE_MUTEX; status = LspVendorRequest( &tempLSS[i], &pduDesc, &pduResponse ); if(pduResponse != LANSCSI_RESPONSE_SUCCESS) { KDPrintM(DBG_LURN_ERROR, ("Releasing lock #%u denied by NDAS device\n", LockNo)); } if(!NT_SUCCESS(status)) { LspDisconnect(&tempLSS[i]); KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status)); continue; } // // Log out and disconnect. // LspLogout( &tempLSS[i] ); LspDisconnect( &tempLSS[i] ); } KDPrintM(DBG_LURN_INFO, ("Cleaned #%u\n", cleaned)); ExFreePool(tempLSS); return status; }
/* Creates the server side */ NTSTATUS DEFAULTAPI MsfsCreateMailslot(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PEXTENDED_IO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PMSFS_DEVICE_EXTENSION DeviceExtension; PMSFS_FCB Fcb; PMSFS_CCB Ccb; KIRQL oldIrql; PLIST_ENTRY current_entry; PMSFS_FCB current = NULL; PMAILSLOT_CREATE_PARAMETERS Buffer; DPRINT("MsfsCreateMailslot(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp); DeviceExtension = DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; Buffer = IoStack->Parameters.CreateMailslot.Parameters; DPRINT("Mailslot name: %wZ\n", &FileObject->FileName); Fcb = ExAllocatePool(NonPagedPool, sizeof(MSFS_FCB)); if (Fcb == NULL) { Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } Fcb->Name.Length = FileObject->FileName.Length; Fcb->Name.MaximumLength = Fcb->Name.Length + sizeof(UNICODE_NULL); Fcb->Name.Buffer = ExAllocatePool(NonPagedPool, Fcb->Name.MaximumLength); if (Fcb->Name.Buffer == NULL) { ExFreePool(Fcb); Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } RtlCopyUnicodeString(&Fcb->Name, &FileObject->FileName); Ccb = ExAllocatePool(NonPagedPool, sizeof(MSFS_CCB)); if (Ccb == NULL) { ExFreePool(Fcb->Name.Buffer); ExFreePool(Fcb); Irp->IoStatus.Status = STATUS_NO_MEMORY; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NO_MEMORY; } Fcb->ReferenceCount = 0; InitializeListHead(&Fcb->CcbListHead); KeInitializeSpinLock(&Fcb->CcbListLock); Fcb->MaxMessageSize = Buffer->MaximumMessageSize; Fcb->MessageCount = 0; Fcb->TimeOut = Buffer->ReadTimeout; KeInitializeEvent(&Fcb->MessageEvent, NotificationEvent, FALSE); InitializeListHead(&Fcb->MessageListHead); KeInitializeSpinLock(&Fcb->MessageListLock); KeLockMutex(&DeviceExtension->FcbListLock); current_entry = DeviceExtension->FcbListHead.Flink; while (current_entry != &DeviceExtension->FcbListHead) { current = CONTAINING_RECORD(current_entry, MSFS_FCB, FcbListEntry); if (!RtlCompareUnicodeString(&Fcb->Name, ¤t->Name, TRUE)) break; current_entry = current_entry->Flink; } if (current_entry != &DeviceExtension->FcbListHead) { ExFreePool(Fcb->Name.Buffer); ExFreePool(Fcb); ExFreePool(Ccb); KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } else { InsertTailList(&DeviceExtension->FcbListHead, &Fcb->FcbListEntry); } KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); InsertTailList(&Fcb->CcbListHead, &Ccb->CcbListEntry); KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); Fcb->ReferenceCount++; Fcb->ServerCcb = Ccb; Ccb->Fcb = Fcb; KeUnlockMutex(&DeviceExtension->FcbListLock); FileObject->FsContext = Fcb; FileObject->FsContext2 = Ccb; FileObject->Flags |= FO_MAILSLOT; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
NTSTATUS LspConnectEx( IN OUT PLANSCSI_SESSION LSS, OUT PTA_LSTRANS_ADDRESS BoundAddr, IN PTA_LSTRANS_ADDRESS BindAddr, IN PTA_LSTRANS_ADDRESS BindAddr2, IN PTA_LSTRANS_ADDRESS DestAddr, IN BOOLEAN BindAnyAddress ) { NTSTATUS status; PTA_LSTRANS_ADDRESS addrList; ULONG addrListLen; PTA_LSTRANS_ADDRESS addrListPrioritized; ULONG idx_addr; LSTRANS_TYPE transport; ASSERT(LSS); ASSERT(DestAddr); // // Parameter check // if(DestAddr->TAAddressCount != 1) { return STATUS_INVALID_PARAMETER; } if(DestAddr->Address[0].AddressType != TDI_ADDRESS_TYPE_LPX) { return STATUS_NOT_IMPLEMENTED; } if(BindAddr && DestAddr->Address[0].AddressType != BindAddr->Address[0].AddressType) return STATUS_INVALID_PARAMETER; if(BindAddr2 && DestAddr->Address[0].AddressType != BindAddr2->Address[0].AddressType) return STATUS_INVALID_PARAMETER; // // Initialize variables // addrList = NULL; addrListPrioritized = NULL; do { // // Query binding address list // addrList = LstranAllocateAddr( LSTRANS_MAX_BINDADDR, &addrListLen ); if(!addrList) { status = STATUS_INSUFFICIENT_RESOURCES; break; } status = LstransAddrTypeToTransType(DestAddr->Address[0].AddressType, &transport); if(!NT_SUCCESS(status)) { KDPrintM(DBG_PROTO_ERROR, ("Address type not supported. STATUS=%08lx\n", status)); break; } status = LstransQueryBindingDevices(transport, addrListLen, addrList, NULL); if(!NT_SUCCESS(status)) { KDPrintM(DBG_PROTO_ERROR, ("LstransQueryBindingDevices() failed. STATUS=%08lx\n", status)); break; } // // Validate binding address // if(BindAddr) { status = LstransIsInAddressList(addrList, BindAddr, TRUE); if(status == STATUS_OBJECT_NAME_NOT_FOUND) { BindAddr = NULL; } else if(!NT_SUCCESS(status)) { break; } } if(BindAddr2) { status = LstransIsInAddressList(addrList, BindAddr2, TRUE); if(status == STATUS_OBJECT_NAME_NOT_FOUND) { BindAddr2 = NULL; } else if(!NT_SUCCESS(status)) { break; } } // // Try bind addresses in order of BindAddr, BindAddr2, and any addresses available. // addrListPrioritized = LstranAllocateAddr( LSTRANS_MAX_BINDADDR, NULL); if(!addrListPrioritized) { status = STATUS_INSUFFICIENT_RESOURCES; break; } idx_addr = 0; addrListPrioritized->TAAddressCount = 0; if(BindAddr) { RtlCopyMemory(&addrListPrioritized->Address[idx_addr], BindAddr->Address, sizeof(struct _AddrLstrans)); addrListPrioritized->TAAddressCount ++; idx_addr ++; } if(BindAddr2) { RtlCopyMemory(&addrListPrioritized->Address[idx_addr], BindAddr2->Address, sizeof(struct _AddrLstrans)); addrListPrioritized->TAAddressCount ++; idx_addr ++; } if(BindAnyAddress) { ULONG idx_bindaddr; for(idx_bindaddr = 0; idx_bindaddr < (ULONG)addrList->TAAddressCount; idx_bindaddr ++) { // // If an address has a valid length, copy into prioritized address list. // Set zero legnth to the same address as BindAddr and BindAddr2 in LstransIsInAddressList(). // if(addrList->Address[idx_bindaddr].AddressLength) { RtlCopyMemory( &addrListPrioritized->Address[idx_addr], &addrList->Address[idx_bindaddr], sizeof(TA_LSTRANS_ADDRESS)); addrListPrioritized->TAAddressCount ++; idx_addr ++; } } } // // Try connecting with prioritized binding address. // status = LspConnectBindAddrList(LSS, BoundAddr, DestAddr, addrListPrioritized); } while(FALSE); if(addrListPrioritized) ExFreePool(addrListPrioritized); if(addrList) ExFreePool(addrList); return status; }
NTSTATUS DEFAULTAPI MsfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IoStack; PFILE_OBJECT FileObject; PMSFS_DEVICE_EXTENSION DeviceExtension; PMSFS_FCB Fcb; PMSFS_CCB Ccb; PMSFS_MESSAGE Message; KIRQL oldIrql; DPRINT("MsfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp); IoStack = IoGetCurrentIrpStackLocation(Irp); DeviceExtension = DeviceObject->DeviceExtension; FileObject = IoStack->FileObject; KeLockMutex(&DeviceExtension->FcbListLock); if (DeviceExtension->FcbListHead.Flink == &DeviceExtension->FcbListHead) { KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } Fcb = FileObject->FsContext; Ccb = FileObject->FsContext2; DPRINT("Mailslot name: %wZ\n", &Fcb->Name); Fcb->ReferenceCount--; if (Fcb->ServerCcb == Ccb) { /* delete all messages from message-list */ KeAcquireSpinLock(&Fcb->MessageListLock, &oldIrql); while (Fcb->MessageListHead.Flink != &Fcb->MessageListHead) { Message = CONTAINING_RECORD(Fcb->MessageListHead.Flink, MSFS_MESSAGE, MessageListEntry); RemoveEntryList(Fcb->MessageListHead.Flink); ExFreePool(Message); } Fcb->MessageCount = 0; KeReleaseSpinLock(&Fcb->MessageListLock, oldIrql); Fcb->ServerCcb = NULL; } KeAcquireSpinLock(&Fcb->CcbListLock, &oldIrql); RemoveEntryList(&Ccb->CcbListEntry); KeReleaseSpinLock(&Fcb->CcbListLock, oldIrql); ExFreePool(Ccb); FileObject->FsContext2 = NULL; if (Fcb->ReferenceCount == 0) { DPRINT("ReferenceCount == 0: Deleting mailslot data\n"); RemoveEntryList(&Fcb->FcbListEntry); ExFreePool(Fcb->Name.Buffer); ExFreePool(Fcb); } KeUnlockMutex(&DeviceExtension->FcbListLock); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
/** * Internal worker for the RTMpOn* APIs. * * @returns IPRT status code. * @param pfnWorker The callback. * @param pvUser1 User argument 1. * @param pvUser2 User argument 2. * @param enmCpuid What to do / is idCpu valid. * @param idCpu Used if enmCpuid RT_NT_CPUID_SPECIFIC, otherwise ignored. */ static int rtMpCall(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2, RT_NT_CPUID enmCpuid, RTCPUID idCpu) { PRTMPARGS pArgs; KDPC *paExecCpuDpcs; #if 0 /* KeFlushQueuedDpcs must be run at IRQL PASSIVE_LEVEL according to MSDN, but the * driver verifier doesn't complain... */ AssertMsg(KeGetCurrentIrql() == PASSIVE_LEVEL, ("%d != %d (PASSIVE_LEVEL)\n", KeGetCurrentIrql(), PASSIVE_LEVEL)); #endif #ifdef IPRT_TARGET_NT4 KAFFINITY Mask; /* g_pfnrtNt* are not present on NT anyway. */ return VERR_NOT_SUPPORTED; #else KAFFINITY Mask = KeQueryActiveProcessors(); #endif /* KeFlushQueuedDpcs is not present in Windows 2000; import it dynamically so we can just fail this call. */ if (!g_pfnrtNtKeFlushQueuedDpcs) return VERR_NOT_SUPPORTED; pArgs = (PRTMPARGS)ExAllocatePoolWithTag(NonPagedPool, MAXIMUM_PROCESSORS*sizeof(KDPC) + sizeof(RTMPARGS), (ULONG)'RTMp'); if (!pArgs) return VERR_NO_MEMORY; pArgs->pfnWorker = pfnWorker; pArgs->pvUser1 = pvUser1; pArgs->pvUser2 = pvUser2; pArgs->idCpu = NIL_RTCPUID; pArgs->cHits = 0; paExecCpuDpcs = (KDPC *)(pArgs + 1); if (enmCpuid == RT_NT_CPUID_SPECIFIC) { KeInitializeDpc(&paExecCpuDpcs[0], rtmpNtDPCWrapper, pArgs); KeSetImportanceDpc(&paExecCpuDpcs[0], HighImportance); KeSetTargetProcessorDpc(&paExecCpuDpcs[0], (int)idCpu); } else { for (unsigned i = 0; i < MAXIMUM_PROCESSORS; i++) { KeInitializeDpc(&paExecCpuDpcs[i], rtmpNtDPCWrapper, pArgs); KeSetImportanceDpc(&paExecCpuDpcs[i], HighImportance); KeSetTargetProcessorDpc(&paExecCpuDpcs[i], i); } } /* Raise the IRQL to DISPATCH_LEVEL so we can't be rescheduled to another cpu. * KeInsertQueueDpc must also be executed at IRQL >= DISPATCH_LEVEL. */ KIRQL oldIrql; KeRaiseIrql(DISPATCH_LEVEL, &oldIrql); /* * We cannot do other than assume a 1:1 relationship between the * affinity mask and the process despite the warnings in the docs. * If someone knows a better way to get this done, please let bird know. */ if (enmCpuid == RT_NT_CPUID_SPECIFIC) { BOOLEAN ret = KeInsertQueueDpc(&paExecCpuDpcs[0], 0, 0); Assert(ret); } else { unsigned iSelf = KeGetCurrentProcessorNumber(); for (unsigned i = 0; i < MAXIMUM_PROCESSORS; i++) { if ( (i != iSelf) && (Mask & RT_BIT_64(i))) { BOOLEAN ret = KeInsertQueueDpc(&paExecCpuDpcs[i], 0, 0); Assert(ret); } } if (enmCpuid != RT_NT_CPUID_OTHERS) pfnWorker(iSelf, pvUser1, pvUser2); } KeLowerIrql(oldIrql); /* Flush all DPCs and wait for completion. (can take long!) */ /** @todo Consider changing this to an active wait using some atomic inc/dec * stuff (and check for the current cpu above in the specific case). */ g_pfnrtNtKeFlushQueuedDpcs(); ExFreePool(pArgs); return VINF_SUCCESS; }
NTSTATUS NTAPI SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject, IN BOOLEAN DoAudit, OUT POBJECT_NAME_INFORMATION *AuditInfo) { OBJECT_NAME_INFORMATION LocalNameInfo; POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; ULONG ReturnLength = 8; NTSTATUS Status; PAGED_CODE(); ASSERT(AuditInfo); /* Check if we should do auditing */ if (DoAudit) { /* FIXME: TODO */ } /* Now query the name */ Status = ObQueryNameString(FileObject, &LocalNameInfo, sizeof(LocalNameInfo), &ReturnLength); if (((Status == STATUS_BUFFER_OVERFLOW) || (Status == STATUS_BUFFER_TOO_SMALL) || (Status == STATUS_INFO_LENGTH_MISMATCH)) && (ReturnLength != sizeof(LocalNameInfo))) { /* Allocate required size */ ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool, ReturnLength, TAG_SEPA); if (ObjectNameInfo) { /* Query the name again */ Status = ObQueryNameString(FileObject, ObjectNameInfo, ReturnLength, &ReturnLength); } } /* Check if we got here due to failure */ if ((ObjectNameInfo) && (!(NT_SUCCESS(Status)) || (ReturnLength == sizeof(LocalNameInfo)))) { /* First, free any buffer we might've allocated */ ASSERT(FALSE); if (ObjectNameInfo) ExFreePool(ObjectNameInfo); /* Now allocate a temporary one */ ReturnLength = sizeof(OBJECT_NAME_INFORMATION); ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(OBJECT_NAME_INFORMATION), TAG_SEPA); if (ObjectNameInfo) { /* Clear it */ RtlZeroMemory(ObjectNameInfo, ReturnLength); Status = STATUS_SUCCESS; } } /* Check if memory allocation failed */ if (!ObjectNameInfo) Status = STATUS_NO_MEMORY; /* Return the audit name */ *AuditInfo = ObjectNameInfo; /* Return status */ return Status; }
VOID SendDeviceIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP SIrp ) { NTSTATUS ntStatus; POWER_STATE powState; PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; SYSTEM_POWER_STATE systemState; DEVICE_POWER_STATE devState; PPOWER_COMPLETION_CONTEXT powerContext; irpStack = IoGetCurrentIrpStackLocation(SIrp); systemState = irpStack->Parameters.Power.State.SystemState; deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; FreeBT_DbgPrint(3, ("FBTUSB: SendDeviceIrp: Entered\n")); // Read out the D-IRP out of the S->D mapping array captured in QueryCap's. // we can choose deeper sleep states than our mapping but never choose // lighter ones. devState = deviceExtension->DeviceCapabilities.DeviceState[systemState]; powState.DeviceState = devState; powerContext = (PPOWER_COMPLETION_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(POWER_COMPLETION_CONTEXT)); if (!powerContext) { FreeBT_DbgPrint(1, ("FBTUSB: SendDeviceIrp: Failed to alloc memory for powerContext\n")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; } else { powerContext->DeviceObject = DeviceObject; powerContext->SIrp = SIrp; // in win2k PoRequestPowerIrp can take fdo or pdo. ntStatus = PoRequestPowerIrp( deviceExtension->PhysicalDeviceObject, irpStack->MinorFunction, powState, (PREQUEST_POWER_COMPLETE)DevPoCompletionRoutine, powerContext, NULL); } if (!NT_SUCCESS(ntStatus)) { if (powerContext) { ExFreePool(powerContext); } PoStartNextPowerIrp(SIrp); SIrp->IoStatus.Status = ntStatus; SIrp->IoStatus.Information = 0; IoCompleteRequest(SIrp, IO_NO_INCREMENT); FreeBT_DbgPrint(3, ("FBTUSB: SendDeviceIrp::")); FreeBT_IoDecrement(deviceExtension); } FreeBT_DbgPrint(3, ("FBTUSB: SendDeviceIrp: Leaving\n")); }