[ros-diffs] [hpoussin] 14720: Implement IoRegisterDeviceInterface

hpoussin at svn.reactos.com hpoussin at svn.reactos.com
Wed Apr 20 21:38:40 CEST 2005


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 */



More information about the Ros-diffs mailing list