- Partly Implement KsCacheMedium

- Implement KsHandleSizedListQuery
- Remove KsGetChildCreateParameter, it is not exported in NT 5.1 KS

svn path=/trunk/; revision=42303
This commit is contained in:
Johannes Anderwald 2009-07-30 16:51:03 +00:00
parent 974e0eca7e
commit cd03260db2
3 changed files with 127 additions and 25 deletions

View file

@ -9,6 +9,9 @@
#include "priv.h" #include "priv.h"
const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
/* /*
@implemented @implemented
*/ */
@ -1163,7 +1166,7 @@ KsSynchronousIoControlDevice(
} }
/* /*
@implemented @unimplemented
*/ */
KSDDKAPI KSDDKAPI
NTSTATUS NTSTATUS
@ -1179,7 +1182,7 @@ KsUnserializeObjectPropertiesFromRegistry(
/* /*
@unimplemented @implemented
*/ */
KSDDKAPI KSDDKAPI
NTSTATUS NTSTATUS
@ -1189,8 +1192,83 @@ KsCacheMedium(
IN PKSPIN_MEDIUM Medium, IN PKSPIN_MEDIUM Medium,
IN ULONG PinDirection) IN ULONG PinDirection)
{ {
UNIMPLEMENTED; HANDLE hKey;
return STATUS_UNSUCCESSFUL; UNICODE_STRING Path;
UNICODE_STRING BasePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediumCache\\");
UNICODE_STRING GuidString;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
BOOLEAN PathAdjusted = FALSE;
ULONG Value = 0;
/* first check if the medium is standard */
if (IsEqualGUIDAligned(&KSMEDIUMSETID_Standard, &Medium->Set) ||
IsEqualGUIDAligned(&GUID_NULL, &Medium->Set))
{
/* no need to cache that */
return STATUS_SUCCESS;
}
/* convert guid to string */
Status = RtlStringFromGUID(&Medium->Set, &GuidString);
if (!NT_SUCCESS(Status))
return Status;
/* allocate path buffer */
Path.Length = 0;
Path.MaximumLength = BasePath.MaximumLength + GuidString.MaximumLength + 10 * sizeof(WCHAR);
Path.Buffer = AllocateItem(PagedPool, Path.MaximumLength);
if (!Path.Buffer)
{
/* not enough resources */
RtlFreeUnicodeString(&GuidString);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlAppendUnicodeStringToString(&Path, &BasePath);
RtlAppendUnicodeStringToString(&Path, &GuidString);
RtlAppendUnicodeToString(&Path, L"-");
/* FIXME append real instance id */
RtlAppendUnicodeToString(&Path, L"0");
RtlAppendUnicodeToString(&Path, L"-");
/* FIXME append real instance id */
RtlAppendUnicodeToString(&Path, L"0");
/* free guid string */
RtlFreeUnicodeString(&GuidString);
/* initialize object attributes */
InitializeObjectAttributes(&ObjectAttributes, &Path, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
/* create the key */
Status = ZwCreateKey(&hKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
/* free path buffer */
FreeItem(Path.Buffer);
if (NT_SUCCESS(Status))
{
/* store symbolic link */
if (SymbolicLink->Buffer[1] == L'?' && SymbolicLink->Buffer[2] == L'?')
{
/* replace kernel path with user mode path */
SymbolicLink->Buffer[1] = L'\\';
PathAdjusted = TRUE;
}
/* store the key */
Status = ZwSetValueKey(hKey, SymbolicLink, 0, REG_DWORD, &Value, sizeof(ULONG));
if (PathAdjusted)
{
/* restore kernel path */
SymbolicLink->Buffer[1] = L'?';
}
ZwClose(hKey);
}
/* done */
return Status;
} }
/* /*

View file

@ -402,34 +402,42 @@ KsPinDataIntersection(
ULONG Index; ULONG Index;
NTSTATUS Status; NTSTATUS Status;
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
/* calculate minimum data size */
Size = sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATARANGE); Size = sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATARANGE);
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Size) if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Size)
{ {
Irp->IoStatus.Information = 0; /* buffer too small */
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = Size;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
/* is pin id out of bounds */
if (Pin->PinId >= DescriptorsCount) if (Pin->PinId >= DescriptorsCount)
{ {
/* it is */
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/* get start item */
Item = (KSMULTIPLE_ITEM*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; Item = (KSMULTIPLE_ITEM*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
/* get first data range */
DataRange = (KSDATARANGE*)(Item + 1); DataRange = (KSDATARANGE*)(Item + 1);
/* iterate through all data ranges */
for(Index = 0; Index < Item->Count; Index++, DataRange++) for(Index = 0; Index < Item->Count; Index++, DataRange++)
{ {
/* call intersect handler */
Status = IntersectHandler(Irp, Pin, DataRange, Data); Status = IntersectHandler(Irp, Pin, DataRange, Data);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSDATARANGE)) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < DataRange->FormatSize)
{ {
Irp->IoStatus.Information = sizeof(KSDATARANGE); /* buffer is too small */
Irp->IoStatus.Information = DataRange->FormatSize;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
@ -447,7 +455,7 @@ KsPinDataIntersection(
} }
/* /*
@unimplemented @implemented
*/ */
KSDDKAPI KSDDKAPI
@ -459,5 +467,35 @@ KsHandleSizedListQuery(
IN ULONG DataItemSize, IN ULONG DataItemSize,
IN const VOID* DataItems) IN const VOID* DataItems)
{ {
ULONG Size;
PIO_STACK_LOCATION IoStack;
PKSMULTIPLE_ITEM Item;
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
Size = DataItemSize * DataItemsCount + sizeof(KSMULTIPLE_ITEM);
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Size)
{
/* buffer too small */
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = Size;
return STATUS_BUFFER_TOO_SMALL;
}
/* get multiple item */
Item = (PKSMULTIPLE_ITEM)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
Item->Count = DataItemsCount;
Item->Size = DataItemSize;
/* copy items */
RtlMoveMemory((PVOID)(Item + 1), DataItems, DataItemSize * DataItemsCount);
/* store result */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
/* done */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -1140,20 +1140,6 @@ KsCancelRoutine(
} }
} }
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsGetChildCreateParameter(
IN PIRP Irp,
OUT PVOID* CreateParameter)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
NTSTATUS NTSTATUS
FindMatchingCreateItem( FindMatchingCreateItem(
PLIST_ENTRY ListHead, PLIST_ENTRY ListHead,