NTSTATUS GetConnectRequest( IN PIRP Irp, OUT PKSPIN_CONNECT * Result) { PIO_STACK_LOCATION IoStack; ULONG ObjectLength, ParametersLength; PVOID Buffer; /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* get object class length */ ObjectLength = (wcslen(KSSTRING_Pin) + 1) * sizeof(WCHAR); /* check for minium length requirement */ if (ObjectLength + sizeof(KSPIN_CONNECT) > IoStack->FileObject->FileName.MaximumLength) return STATUS_UNSUCCESSFUL; /* extract parameters length */ ParametersLength = IoStack->FileObject->FileName.MaximumLength - ObjectLength; /* allocate buffer */ Buffer = AllocateItem(NonPagedPool, ParametersLength); if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES; /* copy parameters */ RtlMoveMemory(Buffer, &IoStack->FileObject->FileName.Buffer[ObjectLength / sizeof(WCHAR)], ParametersLength); /* store result */ *Result = (PKSPIN_CONNECT)Buffer; return STATUS_SUCCESS; }
NTSTATUS WdmAudOpenSysAudioDeviceInterfaces( IN PWDMAUD_DEVICE_EXTENSION DeviceExtension, IN LPWSTR SymbolicLinkList) { SYSAUDIO_ENTRY * Entry; ULONG Length; DPRINT1("WdmAudOpenSysAudioDeviceInterfaces called\n"); while(*SymbolicLinkList) { Length = wcslen(SymbolicLinkList) + 1; Entry = (SYSAUDIO_ENTRY*)AllocateItem(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR)); if (!Entry) { return STATUS_INSUFFICIENT_RESOURCES; } Entry->SymbolicLink.Length = Length * sizeof(WCHAR); Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR); Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1); wcscpy(Entry->SymbolicLink.Buffer, SymbolicLinkList); InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry); DeviceExtension->NumSysAudioDevices++; SymbolicLinkList += Length; } return STATUS_SUCCESS; }
NTSTATUS NTAPI KspCreateObjectType( IN HANDLE ParentHandle, IN LPWSTR ObjectType, PVOID CreateParameters, UINT CreateParametersSize, IN ACCESS_MASK DesiredAccess, OUT PHANDLE NodeHandle) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Name; /* calculate request length */ Name.Length = 0; Name.MaximumLength = wcslen(ObjectType) * sizeof(WCHAR) + CreateParametersSize + 1 * sizeof(WCHAR); Name.MaximumLength += sizeof(WCHAR); /* acquire request buffer */ Name.Buffer = AllocateItem(NonPagedPool, Name.MaximumLength); /* check for success */ if (!Name.Buffer) { /* insufficient resources */ return STATUS_INSUFFICIENT_RESOURCES; } /* build a request which looks like {ObjectClass}\CreateParameters * For pins the parent is the reference string used in registration * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams */ RtlAppendUnicodeToString(&Name, ObjectType); RtlAppendUnicodeToString(&Name, L"\\"); /* append create parameters */ RtlMoveMemory(Name.Buffer + (Name.Length / sizeof(WCHAR)), CreateParameters, CreateParametersSize); Name.Length += CreateParametersSize; Name.Buffer[Name.Length / 2] = L'\0'; InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL); /* create the instance */ Status = IoCreateFile(NodeHandle, DesiredAccess, &ObjectAttributes, &IoStatusBlock, NULL, 0, 0, FILE_OPEN, 0, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK); /* free request buffer */ FreeItem(Name.Buffer); return Status; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsAllocateObjectBag( IN PKSDEVICE Device, OUT KSOBJECT_BAG* ObjectBag) { PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_BAG Bag; IKsDevice *KsDevice; /* get real device header */ DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); /* allocate a object bag ctx */ Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); if (!Bag) return STATUS_INSUFFICIENT_RESOURCES; /* get device interface */ KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* initialize object bag */ return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL); }
/* @implemented */ NTSTATUS NTAPI KsAddItemToObjectBag( IN KSOBJECT_BAG ObjectBag, IN PVOID Item, IN PFNKSFREE Free OPTIONAL) { PKSIOBJECT_BAG Bag; PKSIOBJECT_BAG_ENTRY BagEntry; DPRINT("KsAddItemToObjectBag\n"); /* get real object bag */ Bag = (PKSIOBJECT_BAG)ObjectBag; /* acquire bag mutex */ KeWaitForSingleObject(Bag->BagMutex, Executive, KernelMode, FALSE, NULL); /* is the item already present in this object bag */ BagEntry = KspFindObjectBagItem(&Bag->ObjectList, Item); if (BagEntry) { /* is is, update reference count */ InterlockedIncrement((PLONG)&BagEntry->References); /* release mutex */ KeReleaseMutex(Bag->BagMutex, FALSE); /* return result */ return STATUS_SUCCESS; } /* item is new, allocate entry */ BagEntry = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG_ENTRY)); if (!BagEntry) { /* no memory */ KeReleaseMutex(Bag->BagMutex, FALSE); /* return result */ return STATUS_INSUFFICIENT_RESOURCES; } /* initialize bag entry */ BagEntry->References = 1; BagEntry->Item = Item; if (Free) BagEntry->Free = Free; else BagEntry->Free = ExFreePool; /* insert item */ InsertTailList(&Bag->ObjectList, &BagEntry->Entry); /* release mutex */ KeReleaseMutex(Bag->BagMutex, FALSE); /* done */ return STATUS_SUCCESS; }
NTSTATUS NTAPI USBCCGP_GetStringDescriptor( IN PDEVICE_OBJECT DeviceObject, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor) { NTSTATUS Status; PUSB_STRING_DESCRIPTOR StringDescriptor; ULONG Size; PVOID Buffer; // retrieve descriptor Status = USBCCGP_GetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor); if (!NT_SUCCESS(Status)) { // failed return Status; } // get descriptor structure StringDescriptor = (PUSB_STRING_DESCRIPTOR)*OutDescriptor; // sanity check ASSERT(StringDescriptor->bLength < DescriptorLength - 2); if (StringDescriptor->bLength == 2) { // invalid descriptor FreeItem(StringDescriptor); return STATUS_DEVICE_DATA_ERROR; } // calculate size Size = StringDescriptor->bLength + sizeof(WCHAR); // allocate buffer Buffer = AllocateItem(NonPagedPool, Size); if (!Buffer) { // no memory FreeItem(StringDescriptor); return STATUS_INSUFFICIENT_RESOURCES; } // copy result RtlCopyMemory(Buffer, StringDescriptor->bString, Size - FIELD_OFFSET(USB_STRING_DESCRIPTOR, bString)); // free buffer FreeItem(StringDescriptor); // store result *OutDescriptor = (PVOID)Buffer; return STATUS_SUCCESS; }
NTSTATUS USBSTOR_PdoHandleDeviceRelations( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp) { PDEVICE_RELATIONS DeviceRelations; PIO_STACK_LOCATION IoStack; DPRINT("USBSTOR_PdoHandleDeviceRelations\n"); // // get current irp stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); // // check if relation type is BusRelations // if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) { // // PDO handles only target device relation // return Irp->IoStatus.Status; } // // allocate device relations // DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); if (!DeviceRelations) { // // no memory // return STATUS_INSUFFICIENT_RESOURCES; } // // initialize device relations // DeviceRelations->Count = 1; DeviceRelations->Objects[0] = DeviceObject; ObReferenceObject(DeviceObject); // // store result // Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; // // completed successfully // return STATUS_SUCCESS; }
PVOID AllocEventData( IN ULONG ExtraSize) { PKSEVENTDATA Data = (PKSEVENTDATA)AllocateItem(NonPagedPool, sizeof(KSEVENTDATA) + ExtraSize); if (!Data) return NULL; Data->EventObject.Event = AllocateItem(NonPagedPool, sizeof(KEVENT)); if (!Data->EventHandle.Event) { FreeItem(Data); return NULL; } KeInitializeEvent(Data->EventObject.Event, NotificationEvent, FALSE); Data->NotificationType = KSEVENTF_EVENT_HANDLE; return Data; }
NTSTATUS USBCCGP_SelectInterface( IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension, IN ULONG InterfaceIndex) { NTSTATUS Status; PURB Urb; // // allocate urb // Urb = AllocateItem(NonPagedPool, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints)); if (!Urb) { // // no memory // return STATUS_INSUFFICIENT_RESOURCES; } // // now prepare interface urb // UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bInterfaceNumber, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bAlternateSetting); // // now select the interface // Status = USBCCGP_SyncUrbRequest(DeviceExtension->NextDeviceObject, Urb); // // did it succeeed // if (NT_SUCCESS(Status)) { // // update configuration info // ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceList[InterfaceIndex].Interface->Length); RtlCopyMemory(DeviceExtension->InterfaceList[InterfaceIndex].Interface, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length); } // // free urb // FreeItem(Urb); // // done // return Status; }
PIRP_CONTEXT USBSTOR_AllocateIrpContext() { PIRP_CONTEXT Context; // // allocate irp context // Context = (PIRP_CONTEXT)AllocateItem(NonPagedPool, sizeof(IRP_CONTEXT)); if (!Context) { // // no memory // return NULL; } // // allocate cbw block // Context->cbw = (PCBW)AllocateItem(NonPagedPool, 512); if (!Context->cbw) { // // no memory // FreeItem(Context); return NULL; } // // done // return Context; }
NTSTATUS GetSysAudioDevicePnpName( IN PDEVICE_OBJECT DeviceObject, IN ULONG DeviceIndex, OUT LPWSTR * Device) { ULONG BytesReturned; KSP_PIN Pin; NTSTATUS Status; PWDMAUD_DEVICE_EXTENSION DeviceExtension; /* first check if the device index is within bounds */ if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject)) return STATUS_INVALID_PARAMETER; /* setup the query request */ Pin.Property.Set = KSPROPSETID_Sysaudio; Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME; Pin.Property.Flags = KSPROPERTY_TYPE_GET; Pin.PinId = DeviceIndex; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; /* query sysaudio for the device path */ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), NULL, 0, &BytesReturned); /* check if the request failed */ if (Status != STATUS_BUFFER_TOO_SMALL || BytesReturned == 0) return STATUS_UNSUCCESSFUL; /* allocate buffer for the device */ *Device = AllocateItem(NonPagedPool, BytesReturned); if (!Device) return STATUS_INSUFFICIENT_RESOURCES; /* query sysaudio again for the device path */ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)*Device, BytesReturned, &BytesReturned); if (!NT_SUCCESS(Status)) { /* failed */ FreeItem(*Device); return Status; } return Status; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsCreateDefaultClock( IN PIRP Irp, IN PKSDEFAULTCLOCK DefaultClock) { NTSTATUS Status; PKSCLOCK_CREATE ClockCreate; PKSICLOCK Clock; Status = KsValidateClockCreateRequest(Irp, &ClockCreate); if (!NT_SUCCESS(Status)) return Status; /* let's allocate the clock struct */ Clock = AllocateItem(NonPagedPool, sizeof(KSICLOCK)); if (!Clock) { FreeItem(ClockCreate); return STATUS_INSUFFICIENT_RESOURCES; } /* now allocate the object header */ Status = KsAllocateObjectHeader((PVOID*)&Clock->ObjectHeader, 0, NULL, Irp, &DispatchTable); /* did it work */ if (!NT_SUCCESS(Status)) { /* failed */ FreeItem(ClockCreate); FreeItem(Clock); return Status; } /* initialize clock */ /* FIXME IKsClock */ Clock->ObjectHeader->ObjectType = (PVOID)Clock; Clock->ref = 1; Clock->ClockCreate = ClockCreate; Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock; /* increment reference count */ InterlockedIncrement(&Clock->DefaultClock->ReferenceCount); return Status; }
NTSTATUS AllocateInterfaceDescriptorsArray( IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PUSB_INTERFACE_DESCRIPTOR **OutArray) { PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; ULONG Count = 0; PUSB_INTERFACE_DESCRIPTOR *Array; // // allocate array // Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * ConfigurationDescriptor->bNumInterfaces); if (!Array) return STATUS_INSUFFICIENT_RESOURCES; // // enumerate all interfaces // Count = 0; do { // // find next descriptor // InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, Count, 0, -1, -1, -1); if (!InterfaceDescriptor) break; // // store descriptor // Array[Count] = InterfaceDescriptor; Count++; }while(TRUE); // // store result // *OutArray = Array; // // done // return STATUS_SUCCESS; }
VOID CALLBACK EventCallback( IN PVOID MixerEventContext, IN HANDLE hMixer, IN ULONG NotificationType, IN ULONG Value) { PWDMAUD_CLIENT ClientInfo; PEVENT_ENTRY Entry; ULONG Index; /* get client context */ ClientInfo = (PWDMAUD_CLIENT)MixerEventContext; /* now search for the mixer which originated the request */ for(Index = 0; Index < ClientInfo->NumPins; Index++) { if (ClientInfo->hPins[Index].Handle == hMixer && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) { if (ClientInfo->hPins[Index].NotifyEvent) { /* allocate event entry */ Entry = AllocateItem(NonPagedPool, sizeof(EVENT_ENTRY)); if (!Entry) { /* no memory */ break; } /* setup event entry */ Entry->NotificationType = NotificationType; Entry->Value = Value; Entry->hMixer = hMixer; /* insert entry */ InsertTailList(&ClientInfo->MixerEventList, &Entry->Entry); /* now notify the client */ KeSetEvent(ClientInfo->hPins[Index].NotifyEvent, 0, FALSE); } /* done */ break; } } }
NTSTATUS WdmAudOpenSysaudio( IN PDEVICE_OBJECT DeviceObject, IN PWDMAUD_CLIENT *pClient) { PWDMAUD_CLIENT Client; PWDMAUD_DEVICE_EXTENSION DeviceExtension; /* get device extension */ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; if (!DeviceExtension->NumSysAudioDevices) { /* wdmaud failed to open sysaudio */ return STATUS_UNSUCCESSFUL; } /* sanity check */ ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList)); /* allocate client context struct */ Client = AllocateItem(NonPagedPool, sizeof(WDMAUD_CLIENT)); /* check for allocation failure */ if (!Client) { /* not enough memory */ return STATUS_INSUFFICIENT_RESOURCES; } /* zero client context struct */ RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT)); /* initialize mixer event list */ InitializeListHead(&Client->MixerEventList); /* store result */ *pClient = Client; /* insert client into list */ ExInterlockedInsertTailList(&DeviceExtension->WdmAudClientList, &Client->Entry, &DeviceExtension->Lock); /* done */ return STATUS_SUCCESS; }
NTSTATUS NTAPI NewDispatchObject( IN PIRP Irp, IN IIrpTarget * Target, IN ULONG CreateItemCount, IN PKSOBJECT_CREATE_ITEM CreateItem) { NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; PIO_STACK_LOCATION IoStack; PDISPATCH_CONTEXT DispatchContext; // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); DispatchContext = (PDISPATCH_CONTEXT)AllocateItem(NonPagedPool, sizeof(DISPATCH_CONTEXT), TAG_PORTCLASS); if (!DispatchContext) return STATUS_INSUFFICIENT_RESOURCES; // allocate object header Status = KsAllocateObjectHeader(&ObjectHeader, CreateItemCount, CreateItem, Irp, &DispatchTable); if (!NT_SUCCESS(Status)) { // free dispatch context FreeItem(DispatchContext, TAG_PORTCLASS); // done return Status; } // initialize dispatch context DispatchContext->ObjectHeader = ObjectHeader; DispatchContext->Target = Target; DispatchContext->CreateItem = CreateItem; // store dispatch context IoStack->FileObject->FsContext = DispatchContext; DPRINT("KsAllocateObjectHeader result %x Target %p Context %p\n", Status, Target, DispatchContext); return Status; }
NTSTATUS InsertPinHandle( IN PWDMAUD_CLIENT ClientInfo, IN ULONG FilterId, IN ULONG PinId, IN SOUND_DEVICE_TYPE DeviceType, IN HANDLE PinHandle, IN ULONG FreeIndex) { PWDMAUD_HANDLE Handles; if (FreeIndex != MAXULONG) { /* re-use a free index */ ClientInfo->hPins[FreeIndex].Handle = PinHandle; ClientInfo->hPins[FreeIndex].FilterId = FilterId; ClientInfo->hPins[FreeIndex].PinId = PinId; ClientInfo->hPins[FreeIndex].Type = DeviceType; return STATUS_SUCCESS; } Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1)); if (!Handles) return STATUS_INSUFFICIENT_RESOURCES; if (ClientInfo->NumPins) { RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins); FreeItem(ClientInfo->hPins); } ClientInfo->hPins = Handles; ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle; ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceType; ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId; ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId; ClientInfo->NumPins++; return STATUS_SUCCESS; }
PKEY_VALUE_PARTIAL_INFORMATION ReadKeyValue( IN HANDLE hSubKey, IN PUNICODE_STRING KeyName) { NTSTATUS Status; ULONG Length; PKEY_VALUE_PARTIAL_INFORMATION PartialInformation; /* now query MatchingDeviceId key */ Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0, &Length); /* check for success */ if (Status != STATUS_BUFFER_TOO_SMALL) return NULL; /* allocate a buffer for key data */ PartialInformation = AllocateItem(NonPagedPool, Length); if (!PartialInformation) return NULL; /* now query MatchingDeviceId key */ Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length); /* check for success */ if (!NT_SUCCESS(Status)) { FreeItem(PartialInformation); return NULL; } if (PartialInformation->Type != REG_SZ) { /* invalid key type */ FreeItem(PartialInformation); return NULL; } return PartialInformation; }
NTSTATUS USBSTOR_SendCapacity( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG RetryCount) { UFI_CAPACITY_CMD Cmd; PUFI_CAPACITY_RESPONSE Response; PPDO_DEVICE_EXTENSION PDODeviceExtension; // // get PDO device extension // PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // allocate capacity response // Response = (PUFI_CAPACITY_RESPONSE)AllocateItem(NonPagedPool, PAGE_SIZE); if (!Response) { // // no memory // return STATUS_INSUFFICIENT_RESOURCES; } // // initialize capacity cmd // RtlZeroMemory(&Cmd, sizeof(UFI_INQUIRY_CMD)); Cmd.Code = SCSIOP_READ_CAPACITY; Cmd.LUN = (PDODeviceExtension->LUN & MAX_LUN); // // send request, response will be freed in completion routine // return USBSTOR_SendRequest(DeviceObject, Irp, UFI_READ_CAPACITY_CMD_LEN, (PUCHAR)&Cmd, sizeof(UFI_CAPACITY_RESPONSE), (PUCHAR)Response, RetryCount); }
NTSTATUS KspCopyCreateRequest( IN PIRP Irp, IN LPWSTR ObjectClass, IN OUT PULONG Size, OUT PVOID * Result) { PIO_STACK_LOCATION IoStack; ULONG ObjectLength, ParametersLength; PVOID Buffer; /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* get object class length */ ObjectLength = (wcslen(ObjectClass) + 1) * sizeof(WCHAR); /* check for minium length requirement */ if (ObjectLength + *Size > IoStack->FileObject->FileName.MaximumLength) return STATUS_UNSUCCESSFUL; /* extract parameters length */ ParametersLength = IoStack->FileObject->FileName.MaximumLength - ObjectLength; /* allocate buffer */ Buffer = AllocateItem(NonPagedPool, ParametersLength); if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES; /* copy parameters */ RtlMoveMemory(Buffer, &IoStack->FileObject->FileName.Buffer[ObjectLength / sizeof(WCHAR)], ParametersLength); /* store result */ *Result = Buffer; *Size = ParametersLength; return STATUS_SUCCESS; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsRegisterWorker( IN WORK_QUEUE_TYPE WorkQueueType, OUT PKSWORKER* Worker) { PKSIWORKER KsWorker; if (WorkQueueType != CriticalWorkQueue && WorkQueueType != DelayedWorkQueue && WorkQueueType != HyperCriticalWorkQueue) { return STATUS_INVALID_PARAMETER; } /* allocate worker context */ KsWorker = AllocateItem(NonPagedPool, sizeof(KSIWORKER)); if (!KsWorker) return STATUS_INSUFFICIENT_RESOURCES; /* initialze the work ctx */ ExInitializeWorkItem(&KsWorker->WorkItem, WorkItemRoutine, (PVOID)KsWorker); /* setup type */ KsWorker->Type = WorkQueueType; /* Initialize work item queue */ InitializeListHead(&KsWorker->QueuedWorkItems); /* initialize work item lock */ KeInitializeSpinLock(&KsWorker->Lock); /* initialize event */ KeInitializeEvent(&KsWorker->Event, NotificationEvent, FALSE); *Worker = KsWorker; return STATUS_SUCCESS; }
PVOID Alloc(ULONG NumBytes) { return AllocateItem(NonPagedPool, NumBytes); }
NTSTATUS USBSTOR_FdoHandleDeviceRelations( IN PFDO_DEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp) { ULONG DeviceCount = 0; LONG Index; PDEVICE_RELATIONS DeviceRelations; PIO_STACK_LOCATION IoStack; // // get current irp stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); // // check if relation type is BusRelations // if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations) { // // FDO always only handles bus relations // return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); } // // go through array and count device objects // for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++) { if (DeviceExtension->ChildPDO[Index]) { // // child pdo // DeviceCount++; } } // // allocate device relations // DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0)); if (!DeviceRelations) { // // no memory // return STATUS_INSUFFICIENT_RESOURCES; } // // add device objects // for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++) { if (DeviceExtension->ChildPDO[Index]) { // // store child pdo // DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index]; // // add reference // ObReferenceObject(DeviceExtension->ChildPDO[Index]); // // increment count // DeviceRelations->Count++; } } // // store result // Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; // // request completed successfully // return STATUS_SUCCESS; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsCreateDefaultAllocatorEx( IN PIRP Irp, IN PVOID InitializeContext OPTIONAL, IN PFNKSDEFAULTALLOCATE DefaultAllocate OPTIONAL, IN PFNKSDEFAULTFREE DefaultFree OPTIONAL, IN PFNKSINITIALIZEALLOCATOR InitializeAllocator OPTIONAL, IN PFNKSDELETEALLOCATOR DeleteAllocator OPTIONAL) { NTSTATUS Status; PKSALLOCATOR_FRAMING AllocatorFraming; PALLOCATOR Allocator; PVOID Ctx; /* first validate connect request */ Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming); if (!NT_SUCCESS(Status)) return STATUS_INVALID_PARAMETER; /* check the valid file alignment */ if (AllocatorFraming->FileAlignment > (PAGE_SIZE-1)) { FreeItem(AllocatorFraming); return STATUS_INVALID_PARAMETER; } /* allocate allocator struct */ Allocator = AllocateItem(NonPagedPool, sizeof(ALLOCATOR)); if (!Allocator) { FreeItem(AllocatorFraming); return STATUS_INSUFFICIENT_RESOURCES; } /* allocate object header */ Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&Allocator->Header, 0, NULL, Irp, &DispatchTable); if (!NT_SUCCESS(Status)) { FreeItem(AllocatorFraming); FreeItem(Allocator); return Status; } /* set allocator type in object header */ Allocator->lpVtbl = &vt_IKsAllocator; Allocator->Header->Unknown = (PUNKNOWN)&Allocator->lpVtbl; Allocator->ref = 1; if (DefaultAllocate) { /* use external allocator */ Allocator->Type = ALLOCATOR_CUSTOM; Allocator->Allocate.DefaultAllocate = DefaultAllocate; Allocator->Free.DefaultFree = DefaultFree; Allocator->Delete.DefaultDelete = DeleteAllocator; Ctx = InitializeAllocator(InitializeContext, AllocatorFraming, &Allocator->u.CustomList); /* check for success */ if (!Ctx) { KsFreeObjectHeader(Allocator->Header); FreeItem(Allocator); return Status; } } else if (AllocatorFraming->PoolType == NonPagedPool) { /* use non-paged pool allocator */ Allocator->Type = ALLOCATOR_NPAGED_LOOKASIDE; Allocator->Allocate.NPagedPool = ExAllocateFromNPagedLookasideList; Allocator->Free.NPagedPool = ExFreeToNPagedLookasideList; Allocator->Delete.NPagedPool = ExDeleteNPagedLookasideList; ExInitializeNPagedLookasideList(&Allocator->u.NPagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0); } else if (AllocatorFraming->PoolType == PagedPool) { /* use paged pool allocator */ Allocator->Allocate.PagedPool = ExAllocateFromPagedLookasideList; Allocator->Free.PagedPool = ExFreeToPagedLookasideList; Allocator->Delete.PagedPool = ExDeletePagedLookasideList; Allocator->Type = ALLOCATOR_PAGED_LOOKASIDE; ExInitializePagedLookasideList(&Allocator->u.PagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0); } /* backup allocator framing */ RtlMoveMemory(&Allocator->Status.Framing, AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); FreeItem(AllocatorFraming); return Status; }
NTSTATUS NTAPI DispatchCreateSysAudioPin( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IoStack; PKSAUDIO_DEVICE_ENTRY DeviceEntry; PKSPIN_CONNECT Connect; PDISPATCH_CONTEXT DispatchContext; DPRINT("DispatchCreateSysAudioPin entered\n"); /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* sanity checks */ ASSERT(IoStack->FileObject); ASSERT(IoStack->FileObject->RelatedFileObject); ASSERT(IoStack->FileObject->RelatedFileObject->FsContext); /* get current attached virtual device */ DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)IoStack->FileObject->RelatedFileObject->FsContext; /* check for success */ if (!NT_SUCCESS(Status)) { /* failed */ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } /* get connect details */ Status = GetConnectRequest(Irp, &Connect); /* check for success */ if (!NT_SUCCESS(Status)) { /* failed to obtain connect details */ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } /* allocate dispatch context */ DispatchContext = AllocateItem(NonPagedPool, sizeof(DISPATCH_CONTEXT)); if (!DispatchContext) { /* failed */ Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } /* zero dispatch context */ RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT)); /* allocate object header */ Status = KsAllocateObjectHeader(&DispatchContext->ObjectHeader, 0, NULL, Irp, &PinTable); if (!NT_SUCCESS(Status)) { /* failed */ FreeItem(DispatchContext); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } /* now instantiate the pins */ Status = InstantiatePins(DeviceEntry, Connect, DispatchContext, (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension); if (!NT_SUCCESS(Status)) { /* failed */ KsFreeObjectHeader(DispatchContext->ObjectHeader); FreeItem(DispatchContext); } else { /* store dispatch context */ IoStack->FileObject->FsContext = (PVOID)DispatchContext; } /* FIXME create items for clocks / allocators */ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI InstantiatePins( IN PKSAUDIO_DEVICE_ENTRY DeviceEntry, IN PKSPIN_CONNECT Connect, IN PDISPATCH_CONTEXT DispatchContext, IN PSYSAUDIODEVEXT DeviceExtension) { NTSTATUS Status; HANDLE RealPinHandle; PKSDATAFORMAT_WAVEFORMATEX InputFormat; PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL; PKSPIN_CONNECT MixerPinConnect = NULL; KSPIN_CINSTANCES PinInstances; DPRINT("InstantiatePins entered\n"); /* query instance count */ Status = GetPinInstanceCount(DeviceEntry, &PinInstances, Connect); if (!NT_SUCCESS(Status)) { /* failed to query instance count */ return Status; } /* can be the pin be instantiated */ if (PinInstances.PossibleCount == 0) { /* caller wanted to open an instance-less pin */ return STATUS_UNSUCCESSFUL; } /* has the maximum instance count been exceeded */ if (PinInstances.CurrentCount == PinInstances.PossibleCount) { /* FIXME pin already exists * and kmixer infrastructure is not implemented */ return STATUS_UNSUCCESSFUL; } /* Fetch input format */ InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1); /* Let's try to create the audio irp pin */ Status = KsCreatePin(DeviceEntry->Handle, Connect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); if (!NT_SUCCESS(Status)) { /* FIXME disable kmixer */ return STATUS_UNSUCCESSFUL; } #if 0 if (!NT_SUCCESS(Status)) { /* the audio irp pin didnt accept the input format * let's compute a compatible format */ MixerPinConnect = AllocateItem(NonPagedPool, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX)); if (!MixerPinConnect) { /* not enough memory */ return STATUS_INSUFFICIENT_RESOURCES; } /* Zero pin connect */ RtlZeroMemory(MixerPinConnect, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX)); /* Copy initial connect details */ RtlMoveMemory(MixerPinConnect, Connect, sizeof(KSPIN_CONNECT)); OutputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(MixerPinConnect + 1); Status = ComputeCompatibleFormat(DeviceEntry, Connect->PinId, InputFormat, OutputFormat); if (!NT_SUCCESS(Status)) { DPRINT1("ComputeCompatibleFormat failed with %x\n", Status); FreeItem(MixerPinConnect); return Status; } /* Retry with Mixer format */ Status = KsCreatePin(DeviceEntry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); if (!NT_SUCCESS(Status)) { /* This should not fail */ DPRINT1("KsCreatePin failed with %x\n", Status); DPRINT1(" InputFormat: SampleRate %u Bits %u Channels %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, InputFormat->WaveFormatEx.wBitsPerSample, InputFormat->WaveFormatEx.nChannels); DPRINT1("OutputFormat: SampleRate %u Bits %u Channels %u\n", OutputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.nChannels); FreeItem(MixerPinConnect); return Status; } } #endif //DeviceEntry->Pins[Connect->PinId].References = 0; /* initialize dispatch context */ DispatchContext->Handle = RealPinHandle; DispatchContext->PinId = Connect->PinId; DispatchContext->AudioEntry = DeviceEntry; DPRINT("RealPinHandle %p\n", RealPinHandle); /* Do we need to transform the audio stream */ if (OutputFormat != NULL) { /* Now create the mixer pin */ Status = CreateMixerPinAndSetFormat(DeviceExtension->KMixerHandle, MixerPinConnect, (PKSDATAFORMAT)InputFormat, (PKSDATAFORMAT)OutputFormat, &DispatchContext->hMixerPin); /* check for success */ if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create Mixer Pin with %x\n", Status); FreeItem(MixerPinConnect); } } /* done */ return Status; }
NTSTATUS USBSTOR_PdoHandleQueryInstanceId( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp) { PPDO_DEVICE_EXTENSION PDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension; WCHAR Buffer[100]; ULONG Length; LPWSTR InstanceId; // // get PDO device extension // PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // get FDO device extension // FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; // // format instance id // if (FDODeviceExtension->SerialNumber) { // // using serial number from device // swprintf(Buffer, L"%s&%c", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN); } else { // // use instance count and LUN // swprintf(Buffer, L"%04lu&%c", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN); } // // calculate length // Length = wcslen(Buffer) + 1; // // allocate instance id // InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR)); if (!InstanceId) { // // no memory // Irp->IoStatus.Information = 0; return STATUS_INSUFFICIENT_RESOURCES; } // // copy instance id // wcscpy(InstanceId, Buffer); DPRINT("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId); // // store result // Irp->IoStatus.Information = (ULONG_PTR)InstanceId; // // completed successfully // return STATUS_SUCCESS; }
NTSTATUS WdmAudControlOpenMixer( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { HANDLE hMixer; PWDMAUD_HANDLE Handles; //PWDMAUD_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status; PKEVENT EventObject = NULL; DPRINT("WdmAudControlOpenMixer\n"); //DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; if (DeviceInfo->u.hNotifyEvent) { Status = ObReferenceObjectByHandle(DeviceInfo->u.hNotifyEvent, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Invalid notify event passed %p from client %p\n", DeviceInfo->u.hNotifyEvent, ClientInfo); DbgBreakPoint(); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } } if (MMixerOpen(&MixerContext, DeviceInfo->DeviceIndex, ClientInfo, EventCallback, &hMixer) != MM_STATUS_SUCCESS) { ObDereferenceObject(EventObject); DPRINT1("Failed to open mixer\n"); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1)); if (Handles) { if (ClientInfo->NumPins) { RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins); FreeItem(ClientInfo->hPins); } ClientInfo->hPins = Handles; ClientInfo->hPins[ClientInfo->NumPins].Handle = hMixer; ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE; ClientInfo->hPins[ClientInfo->NumPins].NotifyEvent = EventObject; ClientInfo->NumPins++; } else { ObDereferenceObject(EventObject); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); } DeviceInfo->hDevice = hMixer; return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); }
MIXER_STATUS QueryKeyValue( IN HANDLE hKey, IN LPWSTR lpKeyName, OUT PVOID * ResultBuffer, OUT PULONG ResultLength, OUT PULONG KeyType) { NTSTATUS Status; UNICODE_STRING KeyName; ULONG Length; PKEY_VALUE_PARTIAL_INFORMATION PartialInformation; /* initialize key name */ RtlInitUnicodeString(&KeyName, lpKeyName); /* now query MatchingDeviceId key */ Status = ZwQueryValueKey(hKey, &KeyName, KeyValuePartialInformation, NULL, 0, &Length); /* check for success */ if (Status != STATUS_BUFFER_TOO_SMALL) return MM_STATUS_UNSUCCESSFUL; /* allocate a buffer for key data */ PartialInformation = AllocateItem(NonPagedPool, Length); if (!PartialInformation) return MM_STATUS_NO_MEMORY; /* now query MatchingDeviceId key */ Status = ZwQueryValueKey(hKey, &KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length); /* check for success */ if (!NT_SUCCESS(Status)) { FreeItem(PartialInformation); return MM_STATUS_UNSUCCESSFUL; } if (KeyType) { /* return key type */ *KeyType = PartialInformation->Type; } if (ResultLength) { /* return data length */ *ResultLength = PartialInformation->DataLength; } *ResultBuffer = AllocateItem(NonPagedPool, PartialInformation->DataLength); if (!*ResultBuffer) { /* not enough memory */ FreeItem(PartialInformation); return MM_STATUS_NO_MEMORY; } /* copy key value */ RtlMoveMemory(*ResultBuffer, PartialInformation->Data, PartialInformation->DataLength); /* free key info */ FreeItem(PartialInformation); return MM_STATUS_SUCCESS; }
NTSTATUS USBSTOR_PdoHandleQueryCompatibleId( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp) { PPDO_DEVICE_EXTENSION PDODeviceExtension; PFDO_DEVICE_EXTENSION FDODeviceExtension; CHAR Buffer[100]; ULONG Length, Offset; LPWSTR InstanceId; LPCSTR DeviceType; // // get PDO device extension // PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // get FDO device extension // FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; // // sanity check // ASSERT(FDODeviceExtension->DeviceDescriptor); // // get target device type // DeviceType = USBSTOR_GetDeviceType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData, PDODeviceExtension->IsFloppy); // // zero memory // RtlZeroMemory(Buffer, sizeof(Buffer)); // // format instance id // Length = sprintf(Buffer, "USBSTOR\\%s", DeviceType) + 1; Length += sprintf(&Buffer[Length], "USBSTOR\\%s", "RAW") + 2; // // allocate instance id // InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR)); if (!InstanceId) { // // no memory // Irp->IoStatus.Information = 0; return STATUS_INSUFFICIENT_RESOURCES; } USBSTOR_ConvertToUnicodeString(Buffer, Length, 0, InstanceId, &Offset); USBSTOR_ConvertToUnicodeString(&Buffer[Offset], Length, Offset, InstanceId, &Offset); DPRINT("USBSTOR_PdoHandleQueryCompatibleId %S\n", InstanceId); // // store result // Irp->IoStatus.Information = (ULONG_PTR)InstanceId; // // completed successfully // return STATUS_SUCCESS; }