Author: fireball
Date: Sun Jul 9 01:33:25 2006
New Revision: 22948
URL:
http://svn.reactos.org/svn/reactos?rev=22948&view=rev
Log:
[AUDIT] + [FORMATTING]
- Coding style applied (make file's header proper, add headers for every function)
- All functions except one are documented in MSDN
- One undocumented function will undergo further examination and documentation
Modified:
trunk/reactos/ntoskrnl/io/iomgr/deviface.c (contents, props changed)
Modified: trunk/reactos/ntoskrnl/io/iomgr/deviface.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/deviface…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/deviface.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/deviface.c Sun Jul 9 01:33:25 2006
@@ -1,7 +1,7 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/deviface.c
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/io/iomgr/deviface.c
* PURPOSE: Device interface functions
*
* PROGRAMMERS: Filip Navara (xnavara(a)volny.cz)
@@ -20,868 +20,974 @@
static PWCHAR BaseKeyString =
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\";
-/*
+/*++
+ * @name IoOpenDeviceInterfaceRegistryKey
* @unimplemented
- */
-
-NTSTATUS STDCALL
-IoOpenDeviceInterfaceRegistryKey(
- IN PUNICODE_STRING SymbolicLinkName,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE DeviceInterfaceKey)
+ *
+ * Provides a handle to the device's interface instance registry key.
+ * Documented in WDK.
+ *
+ * @param SymbolicLinkName
+ * Pointer to a string which identifies the device interface instance
+ *
+ * @param DesiredAccess
+ * Desired ACCESS_MASK used to access the key (like KEY_READ,
+ * KEY_WRITE, etc)
+ *
+ * @param DeviceInterfaceKey
+ * If a call has been succesfull, a handle to the registry key
+ * will be stored there
+ *
+ * @return Three different NTSTATUS values in case of errors, and STATUS_SUCCESS
+ * otherwise (see WDK for details)
+ *
+ * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a system thread
+ *
+ *--*/
+NTSTATUS
+NTAPI
+IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE DeviceInterfaceKey)
{
- return STATUS_NOT_IMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
-/*
+/*++
+ * @name IoGetDeviceInterfaceAlias
* @unimplemented
- */
-
-NTSTATUS STDCALL
-IoGetDeviceInterfaceAlias(
- IN PUNICODE_STRING SymbolicLinkName,
- IN CONST GUID *AliasInterfaceClassGuid,
- OUT PUNICODE_STRING AliasSymbolicLinkName)
+ *
+ * Returns the alias device interface of the specified device interface
+ * instance, if the alias exists.
+ * Documented in WDK.
+ *
+ * @param SymbolicLinkName
+ * Pointer to a string which identifies the device interface instance
+ *
+ * @param AliasInterfaceClassGuid
+ * See WDK
+ *
+ * @param AliasSymbolicLinkName
+ * See WDK
+ *
+ * @return Three different NTSTATUS values in case of errors, and STATUS_SUCCESS
+ * otherwise (see WDK for details)
+ *
+ * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a system thread
+ *
+ *--*/
+NTSTATUS
+NTAPI
+IoGetDeviceInterfaceAlias(IN PUNICODE_STRING SymbolicLinkName,
+ IN CONST GUID *AliasInterfaceClassGuid,
+ OUT PUNICODE_STRING AliasSymbolicLinkName)
{
- return STATUS_NOT_IMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
+/*++
+ * @name IopOpenInterfaceKey
+ *
+ * Returns the alias device interface of the specified device interface
+ *
+ * @param InterfaceClassGuid
+ * FILLME
+ *
+ * @param DesiredAccess
+ * FILLME
+ *
+ * @param pInterfaceKey
+ * FILLME
+ *
+ * @return Usual NTSTATUS
+ *
+ * @remarks None
+ *
+ *--*/
static NTSTATUS
-IopOpenInterfaceKey(
- IN CONST GUID *InterfaceClassGuid,
- IN ACCESS_MASK DesiredAccess,
- OUT HANDLE *pInterfaceKey)
+IopOpenInterfaceKey(IN CONST GUID *InterfaceClassGuid,
+ IN ACCESS_MASK DesiredAccess,
+ OUT HANDLE *pInterfaceKey)
{
- UNICODE_STRING LocalMachine =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\");
- UNICODE_STRING GuidString;
- UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE InterfaceKey = INVALID_HANDLE_VALUE;
- NTSTATUS Status;
-
- GuidString.Buffer = KeyName.Buffer = NULL;
-
- Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
-
- KeyName.Length = 0;
- KeyName.MaximumLength = LocalMachine.Length + (wcslen(REGSTR_PATH_DEVICE_CLASSES) + 1)
* sizeof(WCHAR) + GuidString.Length;
- KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
- if (!KeyName.Buffer)
- {
- DPRINT("ExAllocatePool() failed\n");
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
- }
-
- Status = RtlAppendUnicodeStringToString(&KeyName, &LocalMachine);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n",
Status);
- goto cleanup;
- }
- Status = RtlAppendUnicodeToString(&KeyName, REGSTR_PATH_DEVICE_CLASSES);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n",
Status);
- goto cleanup;
- }
- Status = RtlAppendUnicodeToString(&KeyName, L"\\");
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n",
Status);
- goto cleanup;
- }
- Status = RtlAppendUnicodeStringToString(&KeyName, &GuidString);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n",
Status);
- goto cleanup;
- }
-
- InitializeObjectAttributes(
- &ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = ZwOpenKey(
- &InterfaceKey,
- DesiredAccess,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
-
- *pInterfaceKey = InterfaceKey;
- Status = STATUS_SUCCESS;
+ UNICODE_STRING LocalMachine =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\");
+ UNICODE_STRING GuidString;
+ UNICODE_STRING KeyName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE InterfaceKey = INVALID_HANDLE_VALUE;
+ NTSTATUS Status;
+
+ GuidString.Buffer = KeyName.Buffer = NULL;
+
+ Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
+ goto cleanup;
+ }
+
+ KeyName.Length = 0;
+ KeyName.MaximumLength = LocalMachine.Length + (wcslen(REGSTR_PATH_DEVICE_CLASSES) +
1) * sizeof(WCHAR) + GuidString.Length;
+ KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
+ if (!KeyName.Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ Status = RtlAppendUnicodeStringToString(&KeyName, &LocalMachine);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+ Status = RtlAppendUnicodeToString(&KeyName, REGSTR_PATH_DEVICE_CLASSES);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+ Status = RtlAppendUnicodeToString(&KeyName, L"\\");
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+ Status = RtlAppendUnicodeStringToString(&KeyName, &GuidString);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwOpenKey(
+ &InterfaceKey,
+ DesiredAccess,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+ goto cleanup;
+ }
+
+ *pInterfaceKey = InterfaceKey;
+ Status = STATUS_SUCCESS;
cleanup:
- if (!NT_SUCCESS(Status))
- {
- if (InterfaceKey != INVALID_HANDLE_VALUE)
- ZwClose(InterfaceKey);
- }
- RtlFreeUnicodeString(&GuidString);
- RtlFreeUnicodeString(&KeyName);
- return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ if (InterfaceKey != INVALID_HANDLE_VALUE)
+ ZwClose(InterfaceKey);
+ }
+ RtlFreeUnicodeString(&GuidString);
+ RtlFreeUnicodeString(&KeyName);
+ return Status;
}
-/*
- * IoGetDeviceInterfaces
+/*++
+ * @name IoGetDeviceInterfaces
+ * @implemented
*
* Returns a list of device interfaces of a particular device interface class.
- *
- * Parameters
- * InterfaceClassGuid
- * Points to a class GUID specifying the device interface class.
- *
- * PhysicalDeviceObject
- * Points to an optional PDO that narrows the search to only the
- * device interfaces of the device represented by the PDO.
- *
- * Flags
- * Specifies flags that modify the search for device interfaces. The
- * DEVICE_INTERFACE_INCLUDE_NONACTIVE flag specifies that the list of
- * returned symbolic links should contain also disabled device
- * interfaces in addition to the enabled ones.
- *
- * SymbolicLinkList
- * Points to a character pointer that is filled in on successful return
- * with a list of unicode strings identifying the device interfaces
- * that match the search criteria. The newly allocated buffer contains
- * a list of symbolic link names. Each unicode string in the list is
- * null-terminated; the end of the whole list is marked by an additional
- * NULL. The caller is responsible for freeing the buffer (ExFreePool)
- * when it is no longer needed.
- * If no device interfaces match the search criteria, this routine
- * returns STATUS_SUCCESS and the string contains a single NULL
- * character.
- *
- * Status
- * @implemented
- *
- */
-
-NTSTATUS STDCALL
-IoGetDeviceInterfaces(
- IN CONST GUID *InterfaceClassGuid,
- IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
- IN ULONG Flags,
- OUT PWSTR *SymbolicLinkList)
+ * Documented in WDK
+ *
+ * @param InterfaceClassGuid
+ * Points to a class GUID specifying the device interface class
+ *
+ * @param PhysicalDeviceObject
+ * Points to an optional PDO that narrows the search to only the
+ * device interfaces of the device represented by the PDO
+ *
+ * @param Flags
+ * Specifies flags that modify the search for device interfaces. The
+ * DEVICE_INTERFACE_INCLUDE_NONACTIVE flag specifies that the list of
+ * returned symbolic links should contain also disabled device
+ * interfaces in addition to the enabled ones.
+ *
+ * @param SymbolicLinkList
+ * Points to a character pointer that is filled in on successful return
+ * with a list of unicode strings identifying the device interfaces
+ * that match the search criteria. The newly allocated buffer contains
+ * a list of symbolic link names. Each unicode string in the list is
+ * null-terminated; the end of the whole list is marked by an additional
+ * NULL. The caller is responsible for freeing the buffer (ExFreePool)
+ * when it is no longer needed.
+ * If no device interfaces match the search criteria, this routine
+ * returns STATUS_SUCCESS and the string contains a single NULL
+ * character.
+ *
+ * @return Usual NTSTATUS
+ *
+ * @remarks None
+ *
+ *--*/
+NTSTATUS
+NTAPI
+IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid,
+ IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
+ IN ULONG Flags,
+ OUT PWSTR *SymbolicLinkList)
{
- UNICODE_STRING Control = RTL_CONSTANT_STRING(L"Control");
- UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
- HANDLE InterfaceKey = INVALID_HANDLE_VALUE;
- HANDLE DeviceKey = INVALID_HANDLE_VALUE;
- HANDLE ReferenceKey = INVALID_HANDLE_VALUE;
- HANDLE ControlKey = INVALID_HANDLE_VALUE;
- PKEY_BASIC_INFORMATION DeviceBi = NULL;
- PKEY_BASIC_INFORMATION ReferenceBi = NULL;
- PKEY_VALUE_PARTIAL_INFORMATION bip = NULL;
- UNICODE_STRING KeyName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- BOOLEAN FoundRightPDO = FALSE;
- ULONG i = 0, j, Size;
- UNICODE_STRING ReturnBuffer = {0,};
- NTSTATUS Status;
-
- PAGED_CODE();
-
- Status = IopOpenInterfaceKey(InterfaceClassGuid, KEY_ENUMERATE_SUB_KEYS,
&InterfaceKey);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IopOpenInterfaceKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
-
- /* Enumerate subkeys (ie the different device objets) */
- while (TRUE)
- {
- Status = ZwEnumerateKey(
- InterfaceKey,
- i,
- KeyBasicInformation,
- NULL,
- 0,
- &Size);
- if (Status == STATUS_NO_MORE_ENTRIES)
- break;
- else if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
-
- DeviceBi = ExAllocatePool(PagedPool, Size);
- if (!DeviceBi)
- {
- DPRINT("ExAllocatePool() failed\n");
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
- }
- Status = ZwEnumerateKey(
- InterfaceKey,
- i++,
- KeyBasicInformation,
- DeviceBi,
- Size,
- &Size);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
-
- /* Open device key */
- KeyName.Length = KeyName.MaximumLength = DeviceBi->NameLength;
- KeyName.Buffer = DeviceBi->Name;
- InitializeObjectAttributes(
- &ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- InterfaceKey,
- NULL);
- Status = ZwOpenKey(
- &DeviceKey,
- KEY_ENUMERATE_SUB_KEYS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
-
- if (PhysicalDeviceObject)
- {
- /* Check if we are on the right physical device object,
- * by reading the DeviceInstance string
- */
- DPRINT1("PhysicalDeviceObject != NULL. Case not implemented.\n");
- //FoundRightPDO = TRUE;
- Status = STATUS_NOT_IMPLEMENTED;
- goto cleanup;
- }
-
- /* Enumerate subkeys (ie the different reference strings) */
- j = 0;
- while (TRUE)
- {
- Status = ZwEnumerateKey(
- DeviceKey,
- j,
+ UNICODE_STRING Control = RTL_CONSTANT_STRING(L"Control");
+ UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
+ HANDLE InterfaceKey = INVALID_HANDLE_VALUE;
+ HANDLE DeviceKey = INVALID_HANDLE_VALUE;
+ HANDLE ReferenceKey = INVALID_HANDLE_VALUE;
+ HANDLE ControlKey = INVALID_HANDLE_VALUE;
+ PKEY_BASIC_INFORMATION DeviceBi = NULL;
+ PKEY_BASIC_INFORMATION ReferenceBi = NULL;
+ PKEY_VALUE_PARTIAL_INFORMATION bip = NULL;
+ UNICODE_STRING KeyName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ BOOLEAN FoundRightPDO = FALSE;
+ ULONG i = 0, j, Size;
+ UNICODE_STRING ReturnBuffer = {0,};
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ Status = IopOpenInterfaceKey(InterfaceClassGuid, KEY_ENUMERATE_SUB_KEYS,
&InterfaceKey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopOpenInterfaceKey() failed with status 0x%08lx\n", Status);
+ goto cleanup;
+ }
+
+ /* Enumerate subkeys (ie the different device objets) */
+ while (TRUE)
+ {
+ Status = ZwEnumerateKey(
+ InterfaceKey,
+ i,
KeyBasicInformation,
NULL,
0,
&Size);
- if (Status == STATUS_NO_MORE_ENTRIES)
+ if (Status == STATUS_NO_MORE_ENTRIES)
+ {
break;
- else if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
- {
+ }
+ else if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+ {
DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
goto cleanup;
- }
-
- ReferenceBi = ExAllocatePool(PagedPool, Size);
- if (!ReferenceBi)
- {
+ }
+
+ DeviceBi = ExAllocatePool(PagedPool, Size);
+ if (!DeviceBi)
+ {
DPRINT("ExAllocatePool() failed\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
- }
- Status = ZwEnumerateKey(
- DeviceKey,
- j++,
+ }
+ Status = ZwEnumerateKey(
+ InterfaceKey,
+ i++,
KeyBasicInformation,
- ReferenceBi,
+ DeviceBi,
Size,
&Size);
- if (!NT_SUCCESS(Status))
- {
+ if (!NT_SUCCESS(Status))
+ {
DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
goto cleanup;
- }
-
- KeyName.Length = KeyName.MaximumLength = ReferenceBi->NameLength;
- KeyName.Buffer = ReferenceBi->Name;
- if (RtlEqualUnicodeString(&KeyName, &Control, TRUE))
- {
- /* Skip Control subkey */
- goto NextReferenceString;
- }
-
- /* Open reference key */
- InitializeObjectAttributes(
+ }
+
+ /* Open device key */
+ KeyName.Length = KeyName.MaximumLength = DeviceBi->NameLength;
+ KeyName.Buffer = DeviceBi->Name;
+ InitializeObjectAttributes(
&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
- DeviceKey,
+ InterfaceKey,
NULL);
- Status = ZwOpenKey(
- &ReferenceKey,
- KEY_QUERY_VALUE,
+ Status = ZwOpenKey(
+ &DeviceKey,
+ KEY_ENUMERATE_SUB_KEYS,
&ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
+ if (!NT_SUCCESS(Status))
+ {
DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
goto cleanup;
- }
-
- if (!(Flags & DEVICE_INTERFACE_INCLUDE_NONACTIVE))
- {
- /* We have to check if the interface is enabled, by
- * reading the Linked value in the Control subkey
- */
+ }
+
+ if (PhysicalDeviceObject)
+ {
+ /* Check if we are on the right physical device object,
+ * by reading the DeviceInstance string
+ */
+ DPRINT1("PhysicalDeviceObject != NULL. Case not implemented.\n");
+ //FoundRightPDO = TRUE;
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto cleanup;
+ }
+
+ /* Enumerate subkeys (ie the different reference strings) */
+ j = 0;
+ while (TRUE)
+ {
+ Status = ZwEnumerateKey(
+ DeviceKey,
+ j,
+ KeyBasicInformation,
+ NULL,
+ 0,
+ &Size);
+ if (Status == STATUS_NO_MORE_ENTRIES)
+ {
+ break;
+ }
+ else if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+
+ ReferenceBi = ExAllocatePool(PagedPool, Size);
+ if (!ReferenceBi)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+ Status = ZwEnumerateKey(
+ DeviceKey,
+ j++,
+ KeyBasicInformation,
+ ReferenceBi,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+
+ KeyName.Length = KeyName.MaximumLength = ReferenceBi->NameLength;
+ KeyName.Buffer = ReferenceBi->Name;
+ if (RtlEqualUnicodeString(&KeyName, &Control, TRUE))
+ {
+ /* Skip Control subkey */
+ goto NextReferenceString;
+ }
+
+ /* Open reference key */
InitializeObjectAttributes(
- &ObjectAttributes,
- &Control,
- OBJ_CASE_INSENSITIVE,
- ReferenceKey,
- NULL);
+ &ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ DeviceKey,
+ NULL);
Status = ZwOpenKey(
- &ControlKey,
- KEY_QUERY_VALUE,
- &ObjectAttributes);
- if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- /* That's OK. The key doesn't exist (yet) because
- * the interface is not activated.
- */
- goto NextReferenceString;
- }
- else if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
- /* FIXME: Read the Linked value
- * If it doesn't exist => ERROR
- * If it is not a REG_DWORD or Size != sizeof(ULONG) => ERROR
- * If its value is 0, go to NextReferenceString
- * At the moment, do as if it is active...
- */
- DPRINT1("Checking if device is enabled is not implemented
yet!\n");
- }
-
- /* Read the SymbolicLink string and add it into SymbolicLinkList */
- Status = ZwQueryValueKey(
- ReferenceKey,
- &SymbolicLink,
- KeyValuePartialInformation,
- NULL,
- 0,
- &Size);
- if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
- bip = ExAllocatePool(PagedPool, Size);
- if (!bip)
- {
+ &ReferenceKey,
+ KEY_QUERY_VALUE,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+ goto cleanup;
+ }
+
+ if (!(Flags & DEVICE_INTERFACE_INCLUDE_NONACTIVE))
+ {
+ /* We have to check if the interface is enabled, by
+ * reading the Linked value in the Control subkey
+ */
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &Control,
+ OBJ_CASE_INSENSITIVE,
+ ReferenceKey,
+ NULL);
+ Status = ZwOpenKey(
+ &ControlKey,
+ KEY_QUERY_VALUE,
+ &ObjectAttributes);
+ if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ /* That's OK. The key doesn't exist (yet) because
+ * the interface is not activated.
+ */
+ goto NextReferenceString;
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwOpenKey() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+ /* FIXME: Read the Linked value
+ * If it doesn't exist => ERROR
+ * If it is not a REG_DWORD or Size != sizeof(ULONG) => ERROR
+ * If its value is 0, go to NextReferenceString
+ * At the moment, do as if it is active...
+ */
+ DPRINT1("Checking if device is enabled is not implemented
yet!\n");
+ }
+
+ /* Read the SymbolicLink string and add it into SymbolicLinkList */
+ Status = ZwQueryValueKey(
+ ReferenceKey,
+ &SymbolicLink,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &Size);
+ if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+ bip = ExAllocatePool(PagedPool, Size);
+ if (!bip)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+ Status = ZwQueryValueKey(
+ ReferenceKey,
+ &SymbolicLink,
+ KeyValuePartialInformation,
+ bip,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n",
Status);
+ goto cleanup;
+ }
+ else if (bip->Type != REG_SZ)
+ {
+ DPRINT("Unexpected registry type 0x%lx (expected 0x%lx)\n",
bip->Type, REG_SZ);
+ Status = STATUS_UNSUCCESSFUL;
+ goto cleanup;
+ }
+ else if (bip->DataLength < 5 * sizeof(WCHAR))
+ {
+ DPRINT("Registry string too short (length %lu, expected %lu at
least)\n", bip->DataLength < 5 * sizeof(WCHAR));
+ Status = STATUS_UNSUCCESSFUL;
+ goto cleanup;
+ }
+ KeyName.Length = KeyName.MaximumLength = bip->DataLength - 4 *
sizeof(WCHAR);
+ KeyName.Buffer = &((PWSTR)bip->Data)[4];
+ if (KeyName.Length && KeyName.Buffer[KeyName.Length / sizeof(WCHAR)]
== UNICODE_NULL)
+ {
+ /* Remove trailing NULL */
+ KeyName.Length -= sizeof(WCHAR);
+ }
+
+ /* Add new symbolic link to symbolic link list */
+ if (ReturnBuffer.Length + KeyName.Length + sizeof(WCHAR) >
ReturnBuffer.MaximumLength)
+ {
+ PWSTR NewBuffer;
+ ReturnBuffer.MaximumLength = max(ReturnBuffer.MaximumLength * 2,
ReturnBuffer.Length + KeyName.Length + 2 * sizeof(WCHAR));
+ NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
+ if (!NewBuffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+ RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
+ ExFreePool(ReturnBuffer.Buffer);
+ ReturnBuffer.Buffer = NewBuffer;
+ }
+ DPRINT("Adding symbolic link %wZ\n", &KeyName);
+ Status = RtlAppendUnicodeStringToString(&ReturnBuffer, &KeyName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlAppendUnicodeStringToString() failed with status
0x%08lx\n", Status);
+ goto cleanup;
+ }
+ /* RtlAppendUnicodeStringToString added a NULL at the end of the
+ * destination string, but didn't increase the Length field.
+ * Do it for it.
+ */
+ ReturnBuffer.Length += sizeof(WCHAR);
+
+NextReferenceString:
+ ExFreePool(ReferenceBi);
+ ReferenceBi = NULL;
+ ExFreePool(bip);
+ bip = NULL;
+ if (ReferenceKey != INVALID_HANDLE_VALUE)
+ {
+ ZwClose(ReferenceKey);
+ ReferenceKey = INVALID_HANDLE_VALUE;
+ }
+ if (ControlKey != INVALID_HANDLE_VALUE)
+ {
+ ZwClose(ControlKey);
+ ControlKey = INVALID_HANDLE_VALUE;
+ }
+ }
+ if (FoundRightPDO)
+ {
+ /* No need to go further, as we already have found what we searched */
+ break;
+ }
+
+ ExFreePool(DeviceBi);
+ DeviceBi = NULL;
+ ZwClose(DeviceKey);
+ DeviceKey = INVALID_HANDLE_VALUE;
+ }
+
+ /* Add final NULL to ReturnBuffer */
+ if (ReturnBuffer.Length >= ReturnBuffer.MaximumLength)
+ {
+ PWSTR NewBuffer;
+ ReturnBuffer.MaximumLength += sizeof(WCHAR);
+ NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
+ if (!NewBuffer)
+ {
DPRINT("ExAllocatePool() failed\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
- }
- Status = ZwQueryValueKey(
- ReferenceKey,
- &SymbolicLink,
- KeyValuePartialInformation,
- bip,
- Size,
- &Size);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
- goto cleanup;
- }
- else if (bip->Type != REG_SZ)
- {
- DPRINT("Unexpected registry type 0x%lx (expected 0x%lx)\n",
bip->Type, REG_SZ);
- Status = STATUS_UNSUCCESSFUL;
- goto cleanup;
- }
- else if (bip->DataLength < 5 * sizeof(WCHAR))
- {
- DPRINT("Registry string too short (length %lu, expected %lu at
least)\n", bip->DataLength < 5 * sizeof(WCHAR));
- Status = STATUS_UNSUCCESSFUL;
- goto cleanup;
- }
- KeyName.Length = KeyName.MaximumLength = bip->DataLength - 4 *
sizeof(WCHAR);
- KeyName.Buffer = &((PWSTR)bip->Data)[4];
- if (KeyName.Length && KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] ==
UNICODE_NULL)
- /* Remove trailing NULL */
- KeyName.Length -= sizeof(WCHAR);
-
- /* Add new symbolic link to symbolic link list */
- if (ReturnBuffer.Length + KeyName.Length + sizeof(WCHAR) >
ReturnBuffer.MaximumLength)
- {
- PWSTR NewBuffer;
- ReturnBuffer.MaximumLength = max(ReturnBuffer.MaximumLength * 2,
ReturnBuffer.Length + KeyName.Length + 2 * sizeof(WCHAR));
- NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
- if (!NewBuffer)
- {
- DPRINT("ExAllocatePool() failed\n");
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
- }
- RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
- ExFreePool(ReturnBuffer.Buffer);
- ReturnBuffer.Buffer = NewBuffer;
- }
- DPRINT("Adding symbolic link %wZ\n", &KeyName);
- Status = RtlAppendUnicodeStringToString(&ReturnBuffer, &KeyName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlAppendUnicodeStringToString() failed with status
0x%08lx\n", Status);
- goto cleanup;
- }
- /* RtlAppendUnicodeStringToString added a NULL at the end of the
- * destination string, but didn't increase the Length field.
- * Do it for it.
- */
- ReturnBuffer.Length += sizeof(WCHAR);
-
-NextReferenceString:
- ExFreePool(ReferenceBi);
- ReferenceBi = NULL;
- ExFreePool(bip);
- bip = NULL;
- if (ReferenceKey != INVALID_HANDLE_VALUE)
- {
- ZwClose(ReferenceKey);
- ReferenceKey = INVALID_HANDLE_VALUE;
- }
- if (ControlKey != INVALID_HANDLE_VALUE)
- {
- ZwClose(ControlKey);
- ControlKey = INVALID_HANDLE_VALUE;
- }
- }
- if (FoundRightPDO)
- {
- /* No need to go further, as we already have found what we searched */
- break;
- }
-
- ExFreePool(DeviceBi);
- DeviceBi = NULL;
- ZwClose(DeviceKey);
- DeviceKey = INVALID_HANDLE_VALUE;
- }
-
- /* Add final NULL to ReturnBuffer */
- if (ReturnBuffer.Length >= ReturnBuffer.MaximumLength)
- {
- PWSTR NewBuffer;
- ReturnBuffer.MaximumLength += sizeof(WCHAR);
- NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
- if (!NewBuffer)
- {
- DPRINT("ExAllocatePool() failed\n");
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
- }
- RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
- ExFreePool(ReturnBuffer.Buffer);
- ReturnBuffer.Buffer = NewBuffer;
- }
- ReturnBuffer.Buffer[ReturnBuffer.Length / sizeof(WCHAR)] = UNICODE_NULL;
- *SymbolicLinkList = ReturnBuffer.Buffer;
- Status = STATUS_SUCCESS;
+ }
+ RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
+ ExFreePool(ReturnBuffer.Buffer);
+ ReturnBuffer.Buffer = NewBuffer;
+ }
+ ReturnBuffer.Buffer[ReturnBuffer.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ *SymbolicLinkList = ReturnBuffer.Buffer;
+ Status = STATUS_SUCCESS;
cleanup:
- if (!NT_SUCCESS(Status))
- ExFreePool(ReturnBuffer.Buffer);
- if (InterfaceKey != INVALID_HANDLE_VALUE)
- ZwClose(InterfaceKey);
- if (DeviceKey != INVALID_HANDLE_VALUE)
- ZwClose(DeviceKey);
- if (ReferenceKey != INVALID_HANDLE_VALUE)
- ZwClose(ReferenceKey);
- if (ControlKey != INVALID_HANDLE_VALUE)
- ZwClose(ControlKey);
- ExFreePool(DeviceBi);
- ExFreePool(ReferenceBi);
- ExFreePool(bip);
- return Status;
+ if (!NT_SUCCESS(Status))
+ ExFreePool(ReturnBuffer.Buffer);
+ if (InterfaceKey != INVALID_HANDLE_VALUE)
+ ZwClose(InterfaceKey);
+ if (DeviceKey != INVALID_HANDLE_VALUE)
+ ZwClose(DeviceKey);
+ if (ReferenceKey != INVALID_HANDLE_VALUE)
+ ZwClose(ReferenceKey);
+ if (ControlKey != INVALID_HANDLE_VALUE)
+ ZwClose(ControlKey);
+ ExFreePool(DeviceBi);
+ ExFreePool(ReferenceBi);
+ ExFreePool(bip);
+ return Status;
}
-/*
+/*++
+ * @name IoRegisterDeviceInterface
* @implemented
- */
-
-NTSTATUS STDCALL
-IoRegisterDeviceInterface(
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN CONST GUID *InterfaceClassGuid,
- IN PUNICODE_STRING ReferenceString OPTIONAL,
- OUT PUNICODE_STRING SymbolicLinkName)
+ *
+ * Registers a device interface class, if it has not been previously registered,
+ * and creates a new instance of the interface class, which a driver can
+ * subsequently enable for use by applications or other system components.
+ * Documented in WDK.
+ *
+ * @param PhysicalDeviceObject
+ * Points to an optional PDO that narrows the search to only the
+ * device interfaces of the device represented by the PDO
+ *
+ * @param InterfaceClassGuid
+ * Points to a class GUID specifying the device interface class
+ *
+ * @param ReferenceString
+ * Optional parameter, pointing to a unicode string. For a full
+ * description of this rather rarely used param (usually drivers
+ * pass NULL here) see WDK
+ *
+ * @param SymbolicLinkName
+ * Pointer to the resulting unicode string
+ *
+ * @return Usual NTSTATUS
+ *
+ * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a
+ * system thread
+ *
+ *--*/
+NTSTATUS
+NTAPI
+IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN CONST GUID *InterfaceClassGuid,
+ IN PUNICODE_STRING ReferenceString OPTIONAL,
+ OUT PUNICODE_STRING SymbolicLinkName)
{
- PUNICODE_STRING InstancePath;
- UNICODE_STRING GuidString;
- UNICODE_STRING SubKeyName;
- UNICODE_STRING InterfaceKeyName;
- UNICODE_STRING BaseKeyName;
- UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))];
- POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer;
- UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance");
- UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
- HANDLE ClassKey;
- HANDLE InterfaceKey;
- HANDLE SubKey;
- ULONG StartIndex;
- OBJECT_ATTRIBUTES ObjectAttributes;
- ULONG i;
- NTSTATUS Status;
-
- ASSERT_IRQL(PASSIVE_LEVEL);
-
- if (!(PhysicalDeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE))
- {
- DPRINT("PhysicalDeviceObject 0x%p is not a valid Pdo\n",
PhysicalDeviceObject);
- return STATUS_INVALID_PARAMETER_1;
- }
-
- Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
- return Status;
- }
-
- /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
- Status = ObQueryNameString(
- PhysicalDeviceObject,
- PdoNameInfo,
- sizeof(PdoNameInfoBuffer),
- &i);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status);
- return Status;
- }
- ASSERT(PdoNameInfo->Name.Length);
-
- /* Create base key name for this interface:
HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
-
ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode);
- InstancePath =
&((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath;
- BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
- BaseKeyName.MaximumLength = BaseKeyName.Length
- + GuidString.Length;
- BaseKeyName.Buffer = ExAllocatePool(
- PagedPool,
- BaseKeyName.MaximumLength);
- if (!BaseKeyName.Buffer)
- {
- DPRINT("ExAllocatePool() failed\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- wcscpy(BaseKeyName.Buffer, BaseKeyString);
- 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(
- &ClassKey,
- 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;
- }
-
- /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */
- InterfaceKeyName.Length = 0;
- InterfaceKeyName.MaximumLength =
- 4 * sizeof(WCHAR) + /* 4 = size of ##?# */
- InstancePath->Length +
- sizeof(WCHAR) + /* 1 = size of # */
- GuidString.Length;
- InterfaceKeyName.Buffer = ExAllocatePool(
- PagedPool,
- InterfaceKeyName.MaximumLength);
- if (!InterfaceKeyName.Buffer)
- {
- DPRINT("ExAllocatePool() failed\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#");
- StartIndex = InterfaceKeyName.Length / sizeof(WCHAR);
- RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath);
- for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
- {
- if (InterfaceKeyName.Buffer[StartIndex + i] == '\\')
- InterfaceKeyName.Buffer[StartIndex + i] = '#';
- }
- RtlAppendUnicodeToString(&InterfaceKeyName, L"#");
- RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString);
-
- /* Create the interface key in registry */
- InitializeObjectAttributes(
- &ObjectAttributes,
- &InterfaceKeyName,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
- ClassKey,
- 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);
- ZwClose(ClassKey);
- 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);
- ZwClose(ClassKey);
- ExFreePool(InterfaceKeyName.Buffer);
- 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(
- PagedPool,
- SubKeyName.MaximumLength);
- if (!SubKeyName.Buffer)
- {
- DPRINT("ExAllocatePool() failed\n");
- ZwClose(InterfaceKey);
- ZwClose(ClassKey);
- ExFreePool(InterfaceKeyName.Buffer);
- 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);
- ZwClose(ClassKey);
- ExFreePool(InterfaceKeyName.Buffer);
- ExFreePool(BaseKeyName.Buffer);
- return Status;
- }
-
- /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
- SymbolicLinkName->Length = 0;
- SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
- + 4 * sizeof(WCHAR) /* 4 = 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(
- PagedPool,
- SymbolicLinkName->MaximumLength);
- if (!SymbolicLinkName->Buffer)
- {
- DPRINT("ExAllocatePool() failed\n");
- ZwClose(SubKey);
- ZwClose(InterfaceKey);
- ZwClose(ClassKey);
- ExFreePool(InterfaceKeyName.Buffer);
- 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/sizeof(WCHAR)] =
L'\0';
-
- /* Create symbolic link */
- DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ ->
%wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
- Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status);
- ZwClose(SubKey);
- ZwClose(InterfaceKey);
- ZwClose(ClassKey);
- ExFreePool(SubKeyName.Buffer);
- ExFreePool(InterfaceKeyName.Buffer);
- ExFreePool(BaseKeyName.Buffer);
- ExFreePool(SymbolicLinkName->Buffer);
- return Status;
- }
-
- /* Write symbolic link name in registry */
- SymbolicLinkName->Buffer[1] = '\\';
- 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);
- }
-
- /* Remove \\?\ at the start of symbolic link name */
- SymbolicLinkName->Length -= 4 * sizeof(WCHAR);
- SymbolicLinkName->MaximumLength -= 4 * sizeof(WCHAR);
- RtlMoveMemory(
- SymbolicLinkName->Buffer,
- &SymbolicLinkName->Buffer[4],
- SymbolicLinkName->Length);
-
- ZwClose(SubKey);
- ZwClose(InterfaceKey);
- ZwClose(ClassKey);
- ExFreePool(SubKeyName.Buffer);
- ExFreePool(InterfaceKeyName.Buffer);
- ExFreePool(BaseKeyName.Buffer);
-
- return Status;
+ PUNICODE_STRING InstancePath;
+ UNICODE_STRING GuidString;
+ UNICODE_STRING SubKeyName;
+ UNICODE_STRING InterfaceKeyName;
+ UNICODE_STRING BaseKeyName;
+ UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))];
+ POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer;
+ UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance");
+ UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
+ HANDLE ClassKey;
+ HANDLE InterfaceKey;
+ HANDLE SubKey;
+ ULONG StartIndex;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG i;
+ NTSTATUS Status;
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ if (!(PhysicalDeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE))
+ {
+ DPRINT("PhysicalDeviceObject 0x%p is not a valid Pdo\n",
PhysicalDeviceObject);
+ return STATUS_INVALID_PARAMETER_1;
+ }
+
+ Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
+ Status = ObQueryNameString(
+ PhysicalDeviceObject,
+ PdoNameInfo,
+ sizeof(PdoNameInfoBuffer),
+ &i);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+ ASSERT(PdoNameInfo->Name.Length);
+
+ /* Create base key name for this interface:
HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
+
ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode);
+ InstancePath =
&((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath;
+ BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
+ BaseKeyName.MaximumLength = BaseKeyName.Length
+ + GuidString.Length;
+ BaseKeyName.Buffer = ExAllocatePool(
+ PagedPool,
+ BaseKeyName.MaximumLength);
+ if (!BaseKeyName.Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ wcscpy(BaseKeyName.Buffer, BaseKeyString);
+ 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(
+ &ClassKey,
+ 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;
+ }
+
+ /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */
+ InterfaceKeyName.Length = 0;
+ InterfaceKeyName.MaximumLength =
+ 4 * sizeof(WCHAR) + /* 4 = size of ##?# */
+ InstancePath->Length +
+ sizeof(WCHAR) + /* 1 = size of # */
+ GuidString.Length;
+ InterfaceKeyName.Buffer = ExAllocatePool(
+ PagedPool,
+ InterfaceKeyName.MaximumLength);
+ if (!InterfaceKeyName.Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#");
+ StartIndex = InterfaceKeyName.Length / sizeof(WCHAR);
+ RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath);
+ for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
+ {
+ if (InterfaceKeyName.Buffer[StartIndex + i] == '\\')
+ InterfaceKeyName.Buffer[StartIndex + i] = '#';
+ }
+ RtlAppendUnicodeToString(&InterfaceKeyName, L"#");
+ RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString);
+
+ /* Create the interface key in registry */
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &InterfaceKeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
+ ClassKey,
+ 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);
+ ZwClose(ClassKey);
+ 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);
+ ZwClose(ClassKey);
+ ExFreePool(InterfaceKeyName.Buffer);
+ 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(
+ PagedPool,
+ SubKeyName.MaximumLength);
+ if (!SubKeyName.Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ ZwClose(InterfaceKey);
+ ZwClose(ClassKey);
+ ExFreePool(InterfaceKeyName.Buffer);
+ 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);
+ ZwClose(ClassKey);
+ ExFreePool(InterfaceKeyName.Buffer);
+ ExFreePool(BaseKeyName.Buffer);
+ return Status;
+ }
+
+ /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
+ SymbolicLinkName->Length = 0;
+ SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
+ + 4 * sizeof(WCHAR) /* 4 = 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(
+ PagedPool,
+ SymbolicLinkName->MaximumLength);
+ if (!SymbolicLinkName->Buffer)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ ZwClose(SubKey);
+ ZwClose(InterfaceKey);
+ ZwClose(ClassKey);
+ ExFreePool(InterfaceKeyName.Buffer);
+ 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/sizeof(WCHAR)] =
L'\0';
+
+ /* Create symbolic link */
+ DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ ->
%wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
+ Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status);
+ ZwClose(SubKey);
+ ZwClose(InterfaceKey);
+ ZwClose(ClassKey);
+ ExFreePool(SubKeyName.Buffer);
+ ExFreePool(InterfaceKeyName.Buffer);
+ ExFreePool(BaseKeyName.Buffer);
+ ExFreePool(SymbolicLinkName->Buffer);
+ return Status;
+ }
+
+ /* Write symbolic link name in registry */
+ SymbolicLinkName->Buffer[1] = '\\';
+ 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);
+ }
+
+ /* Remove \\?\ at the start of symbolic link name */
+ SymbolicLinkName->Length -= 4 * sizeof(WCHAR);
+ SymbolicLinkName->MaximumLength -= 4 * sizeof(WCHAR);
+ RtlMoveMemory(
+ SymbolicLinkName->Buffer,
+ &SymbolicLinkName->Buffer[4],
+ SymbolicLinkName->Length);
+
+ ZwClose(SubKey);
+ ZwClose(InterfaceKey);
+ ZwClose(ClassKey);
+ ExFreePool(SubKeyName.Buffer);
+ ExFreePool(InterfaceKeyName.Buffer);
+ ExFreePool(BaseKeyName.Buffer);
+
+ return Status;
}
-/*
+/*++
+ * @name IoSetDeviceInterfaceState
* @implemented
- */
-
-NTSTATUS STDCALL
-IoSetDeviceInterfaceState(
- IN PUNICODE_STRING SymbolicLinkName,
- IN BOOLEAN Enable)
+ *
+ * Enables or disables an instance of a previously registered device
+ * interface class.
+ * Documented in WDK.
+ *
+ * @param SymbolicLinkName
+ * Pointer to the string identifying instance to enable or disable
+ *
+ * @param Enable
+ * TRUE = enable, FALSE = disable
+ *
+ * @return Usual NTSTATUS
+ *
+ * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a
+ * system thread
+ *
+ *--*/
+NTSTATUS
+NTAPI
+IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName,
+ IN BOOLEAN Enable)
{
- PDEVICE_OBJECT PhysicalDeviceObject;
- PFILE_OBJECT FileObject;
- UNICODE_STRING ObjectName;
- UNICODE_STRING GuidString;
- PWCHAR StartPosition;
- PWCHAR EndPosition;
- NTSTATUS Status;
- LPCGUID EventGuid;
-
- if (SymbolicLinkName == NULL)
- return STATUS_INVALID_PARAMETER_1;
-
- DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName,
Enable);
-
- /* Symbolic link name is ACPI#PNP0501#1#{GUID}\ReferenceString */
- /* Get GUID from SymbolicLinkName */
- StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
- EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
- if (!StartPosition ||!EndPosition || StartPosition > EndPosition)
- return STATUS_INVALID_PARAMETER_1;
- GuidString.Buffer = StartPosition;
- GuidString.MaximumLength = GuidString.Length = (ULONG_PTR)(EndPosition + 1) -
(ULONG_PTR)StartPosition;
-
- /* Create \??\SymbolicLinkName string */
- ObjectName.Length = 0;
- ObjectName.MaximumLength = SymbolicLinkName->Length + 4 * sizeof(WCHAR);
- ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength);
- if (!ObjectName.Buffer)
- return STATUS_INSUFFICIENT_RESOURCES;
- RtlAppendUnicodeToString(&ObjectName, L"\\??\\");
- RtlAppendUnicodeStringToString(&ObjectName, SymbolicLinkName);
-
- /* Get pointer to the PDO */
- Status = IoGetDeviceObjectPointer(&ObjectName,
- 0, /* DesiredAccess */
- &FileObject,
- &PhysicalDeviceObject);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(ObjectName.Buffer);
- return Status;
- }
-
- EventGuid = Enable ? &GUID_DEVICE_INTERFACE_ARRIVAL :
&GUID_DEVICE_INTERFACE_REMOVAL;
- IopNotifyPlugPlayNotification(
- PhysicalDeviceObject,
- EventCategoryDeviceInterfaceChange,
- EventGuid,
- &GuidString,
- (PVOID)SymbolicLinkName);
-
- ObDereferenceObject(FileObject);
- ExFreePool(ObjectName.Buffer);
-
- return STATUS_SUCCESS;
+ PDEVICE_OBJECT PhysicalDeviceObject;
+ PFILE_OBJECT FileObject;
+ UNICODE_STRING ObjectName;
+ UNICODE_STRING GuidString;
+ PWCHAR StartPosition;
+ PWCHAR EndPosition;
+ NTSTATUS Status;
+ LPCGUID EventGuid;
+
+ if (SymbolicLinkName == NULL)
+ return STATUS_INVALID_PARAMETER_1;
+
+ DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName,
Enable);
+
+ /* Symbolic link name is ACPI#PNP0501#1#{GUID}\ReferenceString */
+ /* Get GUID from SymbolicLinkName */
+ StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
+ EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
+ if (!StartPosition ||!EndPosition || StartPosition > EndPosition)
+ return STATUS_INVALID_PARAMETER_1;
+ GuidString.Buffer = StartPosition;
+ GuidString.MaximumLength = GuidString.Length = (ULONG_PTR)(EndPosition + 1) -
(ULONG_PTR)StartPosition;
+
+ /* Create \??\SymbolicLinkName string */
+ ObjectName.Length = 0;
+ ObjectName.MaximumLength = SymbolicLinkName->Length + 4 * sizeof(WCHAR);
+ ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength);
+ if (!ObjectName.Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlAppendUnicodeToString(&ObjectName, L"\\??\\");
+ RtlAppendUnicodeStringToString(&ObjectName, SymbolicLinkName);
+
+ /* Get pointer to the PDO */
+ Status = IoGetDeviceObjectPointer(&ObjectName,
+ 0, /* DesiredAccess */
+ &FileObject,
+ &PhysicalDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ObjectName.Buffer);
+ return Status;
+ }
+
+ EventGuid = Enable ? &GUID_DEVICE_INTERFACE_ARRIVAL :
&GUID_DEVICE_INTERFACE_REMOVAL;
+ IopNotifyPlugPlayNotification(
+ PhysicalDeviceObject,
+ EventCategoryDeviceInterfaceChange,
+ EventGuid,
+ &GuidString,
+ (PVOID)SymbolicLinkName);
+
+ ObDereferenceObject(FileObject);
+ ExFreePool(ObjectName.Buffer);
+
+ return STATUS_SUCCESS;
}
/* EOF */
Propchange: trunk/reactos/ntoskrnl/io/iomgr/deviface.c
------------------------------------------------------------------------------
--- svn:needs-lock (original)
+++ svn:needs-lock (removed)
@@ -1,1 +1,0 @@
-*