Implement IoRegisterDeviceInterface
Modified: trunk/reactos/include/ddk/defines.h
Modified: trunk/reactos/ntoskrnl/include/ntoskrnl.h
Modified: trunk/reactos/ntoskrnl/io/deviface.c
_____
Modified: trunk/reactos/include/ddk/defines.h
--- trunk/reactos/include/ddk/defines.h 2005-04-20 19:33:48 UTC (rev
14719)
+++ trunk/reactos/include/ddk/defines.h 2005-04-20 19:38:39 UTC (rev
14720)
@@ -28,7 +28,8 @@
OBJ_CASE_INSENSITIVE = 0x40,
OBJ_OPENIF = 0x80,
OBJ_OPENLINK = 0x100,
- OBJ_VALID_ATTRIBUTES = 0x1F2,
+ OBJ_KERNEL_HANDLE = 0x200,
+ OBJ_VALID_ATTRIBUTES = 0x3F2,
};
/*
_____
Modified: trunk/reactos/ntoskrnl/include/ntoskrnl.h
--- trunk/reactos/ntoskrnl/include/ntoskrnl.h 2005-04-20 19:33:48 UTC
(rev 14719)
+++ trunk/reactos/ntoskrnl/include/ntoskrnl.h 2005-04-20 19:38:39 UTC
(rev 14720)
@@ -64,6 +64,15 @@
#include <pseh.h>
+#ifndef RTL_CONSTANT_STRING
+#define RTL_CONSTANT_STRING(__SOURCE_STRING__) \
+{ \
+ sizeof(__SOURCE_STRING__) - sizeof((__SOURCE_STRING__)[0]), \
+ sizeof(__SOURCE_STRING__), \
+ (__SOURCE_STRING__) \
+}
+#endif
+
#ifdef DBG
#ifndef PAGED_CODE
#define PAGED_CODE()
\
_____
Modified: trunk/reactos/ntoskrnl/io/deviface.c
--- trunk/reactos/ntoskrnl/io/deviface.c 2005-04-20 19:33:48 UTC
(rev 14719)
+++ trunk/reactos/ntoskrnl/io/deviface.c 2005-04-20 19:38:39 UTC
(rev 14720)
@@ -16,11 +16,10 @@
#define NDEBUG
#include <internal/debug.h>
-DEFINE_GUID(GUID_SERENUM_BUS_ENUMERATOR,
- 0x4D36E978L, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B,
0xE1, 0x03, 0x18);
-
/* FUNCTIONS
*****************************************************************/
+static PWCHAR BaseKeyString =
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses
\\";
+
/*
* @unimplemented
*/
@@ -93,7 +92,6 @@
IN ULONG Flags,
OUT PWSTR *SymbolicLinkList)
{
- PWCHAR BaseKeyString =
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses
\\";
PWCHAR BaseInterfaceString =
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
UNICODE_STRING GuidString;
UNICODE_STRING BaseKeyName;
@@ -561,7 +559,7 @@
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS STDCALL
@@ -571,16 +569,212 @@
IN PUNICODE_STRING ReferenceString OPTIONAL,
OUT PUNICODE_STRING SymbolicLinkName)
{
- PWCHAR KeyNameString = L"\\Device\\Serenum";
-
- DPRINT("IoRegisterDeviceInterface called (UNIMPLEMENTED)\n");
- if (!memcmp(InterfaceClassGuid,
(LPGUID)&GUID_SERENUM_BUS_ENUMERATOR, sizeof(GUID)))
+ PUNICODE_STRING InstancePath;
+ UNICODE_STRING GuidString;
+ UNICODE_STRING SubKeyName;
+ UNICODE_STRING BaseKeyName;
+ UNICODE_STRING DeviceInstance =
RTL_CONSTANT_STRING(L"DeviceInstance");
+ UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
+ HANDLE InterfaceKey;
+ HANDLE SubKey;
+ ULONG StartIndex;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG i;
+ NTSTATUS Status;
+
+ Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
+ if (!NT_SUCCESS(Status))
{
- RtlInitUnicodeString(SymbolicLinkName, KeyNameString);
- return STATUS_SUCCESS;
+ DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n",
Status);
+ return Status;
}
-
- return STATUS_INVALID_DEVICE_REQUEST;
+
+ /* Create base key name for this interface:
HKLM\SYSTEM\CurrentControlSet\DeviceClasses\{GUID}\##?#ACPI#PNP0501#1#{G
UID} */
+ InstancePath =
&PhysicalDeviceObject->DeviceObjectExtension->DeviceNode->InstancePath;
+ BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
+ BaseKeyName.MaximumLength = BaseKeyName.Length
+ + GuidString.Length
+ + 5 * sizeof(WCHAR) /* 5 = size of \##?# */
+ + InstancePath->Length
+ + sizeof(WCHAR) /* 1 = size of # */
+ + GuidString.Length;
+ BaseKeyName.Buffer = ExAllocatePool(
+ NonPagedPool,
+ BaseKeyName.MaximumLength);
+ if (!BaseKeyName.Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ wcscpy(BaseKeyName.Buffer, BaseKeyString);
+ RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
+ RtlAppendUnicodeToString(&BaseKeyName, L"\\##?#");
+ StartIndex = BaseKeyName.Length / sizeof(WCHAR);
+ RtlAppendUnicodeStringToString(&BaseKeyName, InstancePath);
+ for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
+ {
+ if (BaseKeyName.Buffer[StartIndex + i] == '\\')
+ BaseKeyName.Buffer[StartIndex + i] = '#';
+ }
+ RtlAppendUnicodeToString(&BaseKeyName, L"#");
+ RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
+
+ /* Create BaseKeyName key in registry */
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &BaseKeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
+ NULL, /* RootDirectory */
+ NULL); /* SecurityDescriptor */
+
+ Status = ZwCreateKey(
+ &InterfaceKey,
+ KEY_WRITE,
+ &ObjectAttributes,
+ 0, /* TileIndex */
+ NULL, /* Class */
+ REG_OPTION_VOLATILE,
+ NULL); /* Disposition */
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
+ ExFreePool(BaseKeyName.Buffer);
+ return Status;
+ }
+
+ /* Write DeviceInstance entry. Value is InstancePath */
+ Status = ZwSetValueKey(
+ InterfaceKey,
+ &DeviceInstance,
+ 0, /* TileIndex */
+ REG_SZ,
+ InstancePath->Buffer,
+ InstancePath->Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
+ ZwClose(InterfaceKey);
+ ExFreePool(BaseKeyName.Buffer);
+ return Status;
+ }
+
+ /* Create subkey. Name is #ReferenceString */
+ SubKeyName.Length = 0;
+ SubKeyName.MaximumLength = sizeof(WCHAR);
+ if (ReferenceString && ReferenceString->Length)
+ SubKeyName.MaximumLength += ReferenceString->Length;
+ SubKeyName.Buffer = ExAllocatePool(
+ NonPagedPool,
+ SubKeyName.MaximumLength);
+ if (!SubKeyName.Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ ZwClose(InterfaceKey);
+ ExFreePool(BaseKeyName.Buffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlAppendUnicodeToString(&SubKeyName, L"#");
+ if (ReferenceString && ReferenceString->Length)
+ RtlAppendUnicodeStringToString(&SubKeyName, ReferenceString);
+
+ /* Create SubKeyName key in registry */
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &SubKeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ InterfaceKey, /* RootDirectory */
+ NULL); /* SecurityDescriptor */
+
+ Status = ZwCreateKey(
+ &SubKey,
+ KEY_WRITE,
+ &ObjectAttributes,
+ 0, /* TileIndex */
+ NULL, /* Class */
+ REG_OPTION_VOLATILE,
+ NULL); /* Disposition */
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
+ ZwClose(InterfaceKey);
+ ExFreePool(BaseKeyName.Buffer);
+ return Status;
+ }
+
+ /* Create symbolic link name:
\\?\ACPI#PNP0501#1#{GUID}\ReferenceString */
+ SymbolicLinkName->Length = 0;
+ SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
+ + 4 * sizeof(WCHAR) /* 5 = size of \\??\ */
+ + InstancePath->Length
+ + sizeof(WCHAR) /* 1 = size of # */
+ + GuidString.Length
+ + sizeof(WCHAR); /* final NULL */
+ if (ReferenceString && ReferenceString->Length)
+ SymbolicLinkName->MaximumLength += sizeof(WCHAR) +
ReferenceString->Length;
+ SymbolicLinkName->Buffer = ExAllocatePool(
+ NonPagedPool,
+ SymbolicLinkName->MaximumLength);
+ if (!SymbolicLinkName->Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ ZwClose(InterfaceKey);
+ ZwClose(SubKey);
+ ExFreePool(SubKeyName.Buffer);
+ ExFreePool(BaseKeyName.Buffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlAppendUnicodeToString(SymbolicLinkName, L"\\\\??\\");
+ StartIndex = SymbolicLinkName->Length / sizeof(WCHAR);
+ RtlAppendUnicodeStringToString(SymbolicLinkName, InstancePath);
+ for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
+ {
+ if (SymbolicLinkName->Buffer[StartIndex + i] == '\\')
+ SymbolicLinkName->Buffer[StartIndex + i] = '#';
+ }
+ RtlAppendUnicodeToString(SymbolicLinkName, L"#");
+ RtlAppendUnicodeStringToString(SymbolicLinkName, &GuidString);
+ if (ReferenceString && ReferenceString->Length)
+ {
+ RtlAppendUnicodeToString(SymbolicLinkName, L"\\");
+ RtlAppendUnicodeStringToString(SymbolicLinkName,
ReferenceString);
+ }
+ SymbolicLinkName->Buffer[SymbolicLinkName->Length] = '\0';
+
+ /* Create symbolic link */
+ Status = IoCreateSymbolicLink(SymbolicLinkName, InstancePath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateSymbolicLink() failed with status 0x%08lx\n",
Status);
+ ZwClose(InterfaceKey);
+ ZwClose(SubKey);
+ ExFreePool(SubKeyName.Buffer);
+ ExFreePool(BaseKeyName.Buffer);
+ ExFreePool(SymbolicLinkName->Buffer);
+ return Status;
+ }
+
+ /* Write symbolic link name in registry */
+ Status = ZwSetValueKey(
+ SubKey,
+ &SymbolicLink,
+ 0, /* TileIndex */
+ REG_SZ,
+ SymbolicLinkName->Buffer,
+ SymbolicLinkName->Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
+ ExFreePool(SymbolicLinkName->Buffer);
+ }
+
+ ZwClose(InterfaceKey);
+ ZwClose(SubKey);
+ ExFreePool(SubKeyName.Buffer);
+ ExFreePool(BaseKeyName.Buffer);
+
+ return Status;
}
/*
@@ -592,7 +786,8 @@
IN PUNICODE_STRING SymbolicLinkName,
IN BOOLEAN Enable)
{
- return STATUS_NOT_IMPLEMENTED;
+ DPRINT("IoSetDeviceInterfaceState called (UNIMPLEMENTED)\n");
+ return STATUS_SUCCESS;
}
/* EOF */