ReactOS  0.4.13-dev-249-gcba1a2f
deviface.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for deviface.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define GUID_STRING_CHARS   38
 
#define GUID_STRING_BYTES   (GUID_STRING_CHARS * sizeof(WCHAR))
 

Functions

 C_ASSERT (sizeof(L"{01234567-89ab-cdef-0123-456789abcdef}")==GUID_STRING_BYTES+sizeof(UNICODE_NULL))
 
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance (PUNICODE_STRING DeviceInstance)
 
static NTSTATUS OpenRegistryHandlesFromSymbolicLink (IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, IN OPTIONAL PHANDLE GuidKey, IN OPTIONAL PHANDLE DeviceKey, IN OPTIONAL PHANDLE InstanceKey)
 
NTSTATUS NTAPI IoOpenDeviceInterfaceRegistryKey (IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DeviceInterfaceKey)
 
NTSTATUS NTAPI IoGetDeviceInterfaceAlias (IN PUNICODE_STRING SymbolicLinkName, IN CONST GUID *AliasInterfaceClassGuid, OUT PUNICODE_STRING AliasSymbolicLinkName)
 
static NTSTATUS IopOpenInterfaceKey (IN CONST GUID *InterfaceClassGuid, IN ACCESS_MASK DesiredAccess, OUT HANDLE *pInterfaceKey)
 
NTSTATUS NTAPI IoGetDeviceInterfaces (IN CONST GUID *InterfaceClassGuid, IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN ULONG Flags, OUT PWSTR *SymbolicLinkList)
 
NTSTATUS NTAPI IoRegisterDeviceInterface (IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
 
NTSTATUS NTAPI IoSetDeviceInterfaceState (IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
 

Variables

static PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\"
 

Macro Definition Documentation

◆ GUID_STRING_BYTES

#define GUID_STRING_BYTES   (GUID_STRING_CHARS * sizeof(WCHAR))

Definition at line 21 of file deviface.c.

◆ GUID_STRING_CHARS

#define GUID_STRING_CHARS   38

Definition at line 20 of file deviface.c.

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file deviface.c.

Function Documentation

◆ C_ASSERT()

C_ASSERT ( sizeof(L"{01234567-89ab-cdef-0123-456789abcdef}")  = =GUID_STRING_BYTES+sizeof(UNICODE_NULL))

◆ IoGetDeviceInterfaceAlias()

NTSTATUS NTAPI IoGetDeviceInterfaceAlias ( IN PUNICODE_STRING  SymbolicLinkName,
IN CONST GUID AliasInterfaceClassGuid,
OUT PUNICODE_STRING  AliasSymbolicLinkName 
)

Definition at line 303 of file deviface.c.

306 {
307  return STATUS_NOT_IMPLEMENTED;
308 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225

Referenced by DeviceInterfaceTest_Func().

◆ IoGetDeviceInterfaces()

NTSTATUS NTAPI IoGetDeviceInterfaces ( IN CONST GUID InterfaceClassGuid,
IN PDEVICE_OBJECT PhysicalDeviceObject  OPTIONAL,
IN ULONG  Flags,
OUT PWSTR SymbolicLinkList 
)

Definition at line 454 of file deviface.c.

458 {
461  HANDLE InterfaceKey = NULL;
462  HANDLE DeviceKey = NULL;
463  HANDLE ReferenceKey = NULL;
464  HANDLE ControlKey = NULL;
465  PKEY_BASIC_INFORMATION DeviceBi = NULL;
466  PKEY_BASIC_INFORMATION ReferenceBi = NULL;
468  PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
469  PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;
470  PUNICODE_STRING InstanceDevicePath = NULL;
473  BOOLEAN FoundRightPDO = FALSE;
474  ULONG i = 0, j, Size, NeededLength, ActualLength, LinkedValue;
475  UNICODE_STRING ReturnBuffer = { 0, 0, NULL };
477 
478  PAGED_CODE();
479 
480  if (PhysicalDeviceObject != NULL)
481  {
482  /* Parameters must pass three border of checks */
483  DeviceObjectExtension = (PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension;
484 
485  /* 1st level: Presence of a Device Node */
486  if (DeviceObjectExtension->DeviceNode == NULL)
487  {
488  DPRINT("PhysicalDeviceObject 0x%p doesn't have a DeviceNode\n", PhysicalDeviceObject);
490  }
491 
492  /* 2nd level: Presence of an non-zero length InstancePath */
493  if (DeviceObjectExtension->DeviceNode->InstancePath.Length == 0)
494  {
495  DPRINT("PhysicalDeviceObject 0x%p's DOE has zero-length InstancePath\n", PhysicalDeviceObject);
497  }
498 
499  InstanceDevicePath = &DeviceObjectExtension->DeviceNode->InstancePath;
500  }
501 
502 
504  if (!NT_SUCCESS(Status))
505  {
506  DPRINT("IopOpenInterfaceKey() failed with status 0x%08lx\n", Status);
507  goto cleanup;
508  }
509 
510  /* Enumerate subkeys (i.e. the different device objects) */
511  while (TRUE)
512  {
513  Status = ZwEnumerateKey(
514  InterfaceKey,
515  i,
517  NULL,
518  0,
519  &Size);
521  {
522  break;
523  }
525  {
526  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
527  goto cleanup;
528  }
529 
530  DeviceBi = ExAllocatePool(PagedPool, Size);
531  if (!DeviceBi)
532  {
533  DPRINT("ExAllocatePool() failed\n");
535  goto cleanup;
536  }
537  Status = ZwEnumerateKey(
538  InterfaceKey,
539  i++,
541  DeviceBi,
542  Size,
543  &Size);
544  if (!NT_SUCCESS(Status))
545  {
546  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
547  goto cleanup;
548  }
549 
550  /* Open device key */
551  KeyName.Length = KeyName.MaximumLength = (USHORT)DeviceBi->NameLength;
552  KeyName.Buffer = DeviceBi->Name;
555  &KeyName,
557  InterfaceKey,
558  NULL);
559  Status = ZwOpenKey(
560  &DeviceKey,
563  if (!NT_SUCCESS(Status))
564  {
565  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
566  goto cleanup;
567  }
568 
570  {
571  /* Check if we are on the right physical device object,
572  * by reading the DeviceInstance string
573  */
574  RtlInitUnicodeString(&KeyName, L"DeviceInstance");
575  Status = ZwQueryValueKey(DeviceKey, &KeyName, KeyValuePartialInformation, NULL, 0, &NeededLength);
577  {
578  ActualLength = NeededLength;
579  PartialInfo = ExAllocatePool(NonPagedPool, ActualLength);
580  if (!PartialInfo)
581  {
583  goto cleanup;
584  }
585 
586  Status = ZwQueryValueKey(DeviceKey, &KeyName, KeyValuePartialInformation, PartialInfo, ActualLength, &NeededLength);
587  if (!NT_SUCCESS(Status))
588  {
589  DPRINT1("ZwQueryValueKey #2 failed (%x)\n", Status);
590  ExFreePool(PartialInfo);
591  goto cleanup;
592  }
593  if (PartialInfo->DataLength == InstanceDevicePath->Length)
594  {
595  if (RtlCompareMemory(PartialInfo->Data, InstanceDevicePath->Buffer, InstanceDevicePath->Length) == InstanceDevicePath->Length)
596  {
597  /* found right pdo */
598  FoundRightPDO = TRUE;
599  }
600  }
601  ExFreePool(PartialInfo);
602  PartialInfo = NULL;
603  if (!FoundRightPDO)
604  {
605  /* not yet found */
606  continue;
607  }
608  }
609  else
610  {
611  /* error */
612  break;
613  }
614  }
615 
616  /* Enumerate subkeys (ie the different reference strings) */
617  j = 0;
618  while (TRUE)
619  {
620  Status = ZwEnumerateKey(
621  DeviceKey,
622  j,
624  NULL,
625  0,
626  &Size);
628  {
629  break;
630  }
632  {
633  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
634  goto cleanup;
635  }
636 
637  ReferenceBi = ExAllocatePool(PagedPool, Size);
638  if (!ReferenceBi)
639  {
640  DPRINT("ExAllocatePool() failed\n");
642  goto cleanup;
643  }
644  Status = ZwEnumerateKey(
645  DeviceKey,
646  j++,
648  ReferenceBi,
649  Size,
650  &Size);
651  if (!NT_SUCCESS(Status))
652  {
653  DPRINT("ZwEnumerateKey() failed with status 0x%08lx\n", Status);
654  goto cleanup;
655  }
656 
657  KeyName.Length = KeyName.MaximumLength = (USHORT)ReferenceBi->NameLength;
658  KeyName.Buffer = ReferenceBi->Name;
660  {
661  /* Skip Control subkey */
662  goto NextReferenceString;
663  }
664 
665  /* Open reference key */
668  &KeyName,
670  DeviceKey,
671  NULL);
672  Status = ZwOpenKey(
673  &ReferenceKey,
676  if (!NT_SUCCESS(Status))
677  {
678  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
679  goto cleanup;
680  }
681 
683  {
684  /* We have to check if the interface is enabled, by
685  * reading the Linked value in the Control subkey
686  */
689  &Control,
691  ReferenceKey,
692  NULL);
693  Status = ZwOpenKey(
694  &ControlKey,
698  {
699  /* That's OK. The key doesn't exist (yet) because
700  * the interface is not activated.
701  */
702  goto NextReferenceString;
703  }
704  else if (!NT_SUCCESS(Status))
705  {
706  DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
707  goto cleanup;
708  }
709 
710  RtlInitUnicodeString(&KeyName, L"Linked");
711  Status = ZwQueryValueKey(ControlKey,
712  &KeyName,
714  NULL,
715  0,
716  &NeededLength);
718  {
719  ActualLength = NeededLength;
720  PartialInfo = ExAllocatePool(NonPagedPool, ActualLength);
721  if (!PartialInfo)
722  {
724  goto cleanup;
725  }
726 
727  Status = ZwQueryValueKey(ControlKey,
728  &KeyName,
730  PartialInfo,
731  ActualLength,
732  &NeededLength);
733  if (!NT_SUCCESS(Status))
734  {
735  DPRINT1("ZwQueryValueKey #2 failed (%x)\n", Status);
736  ExFreePool(PartialInfo);
737  goto cleanup;
738  }
739 
740  if (PartialInfo->Type != REG_DWORD || PartialInfo->DataLength != sizeof(ULONG))
741  {
742  DPRINT1("Bad registry read\n");
743  ExFreePool(PartialInfo);
744  goto cleanup;
745  }
746 
747  RtlCopyMemory(&LinkedValue,
748  PartialInfo->Data,
749  PartialInfo->DataLength);
750 
751  ExFreePool(PartialInfo);
752  if (LinkedValue == 0)
753  {
754  /* This interface isn't active */
755  goto NextReferenceString;
756  }
757  }
758  else
759  {
760  DPRINT1("ZwQueryValueKey #1 failed (%x)\n", Status);
761  goto cleanup;
762  }
763  }
764 
765  /* Read the SymbolicLink string and add it into SymbolicLinkList */
766  Status = ZwQueryValueKey(
767  ReferenceKey,
768  &SymbolicLink,
770  NULL,
771  0,
772  &Size);
774  {
775  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
776  goto cleanup;
777  }
778  bip = ExAllocatePool(PagedPool, Size);
779  if (!bip)
780  {
781  DPRINT("ExAllocatePool() failed\n");
783  goto cleanup;
784  }
785  Status = ZwQueryValueKey(
786  ReferenceKey,
787  &SymbolicLink,
789  bip,
790  Size,
791  &Size);
792  if (!NT_SUCCESS(Status))
793  {
794  DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
795  goto cleanup;
796  }
797  else if (bip->Type != REG_SZ)
798  {
799  DPRINT("Unexpected registry type 0x%lx (expected 0x%lx)\n", bip->Type, REG_SZ);
801  goto cleanup;
802  }
803  else if (bip->DataLength < 5 * sizeof(WCHAR))
804  {
805  DPRINT("Registry string too short (length %lu, expected %lu at least)\n", bip->DataLength, 5 * sizeof(WCHAR));
807  goto cleanup;
808  }
809  KeyName.Length = KeyName.MaximumLength = (USHORT)bip->DataLength;
810  KeyName.Buffer = (PWSTR)bip->Data;
811 
812  /* Fixup the prefix (from "\\?\") */
813  RtlCopyMemory(KeyName.Buffer, L"\\??\\", 4 * sizeof(WCHAR));
814 
815  /* Add new symbolic link to symbolic link list */
816  if (ReturnBuffer.Length + KeyName.Length + sizeof(WCHAR) > ReturnBuffer.MaximumLength)
817  {
818  PWSTR NewBuffer;
819  ReturnBuffer.MaximumLength = (USHORT)max(2 * ReturnBuffer.MaximumLength,
820  (USHORT)(ReturnBuffer.Length +
821  KeyName.Length +
822  2 * sizeof(WCHAR)));
823  NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
824  if (!NewBuffer)
825  {
826  DPRINT("ExAllocatePool() failed\n");
828  goto cleanup;
829  }
830  if (ReturnBuffer.Buffer)
831  {
832  RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
833  ExFreePool(ReturnBuffer.Buffer);
834  }
835  ReturnBuffer.Buffer = NewBuffer;
836  }
837  DPRINT("Adding symbolic link %wZ\n", &KeyName);
838  Status = RtlAppendUnicodeStringToString(&ReturnBuffer, &KeyName);
839  if (!NT_SUCCESS(Status))
840  {
841  DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
842  goto cleanup;
843  }
844  /* RtlAppendUnicodeStringToString added a NULL at the end of the
845  * destination string, but didn't increase the Length field.
846  * Do it for it.
847  */
848  ReturnBuffer.Length += sizeof(WCHAR);
849 
850 NextReferenceString:
851  ExFreePool(ReferenceBi);
852  ReferenceBi = NULL;
853  if (bip)
854  ExFreePool(bip);
855  bip = NULL;
856  if (ReferenceKey != NULL)
857  {
858  ZwClose(ReferenceKey);
859  ReferenceKey = NULL;
860  }
861  if (ControlKey != NULL)
862  {
863  ZwClose(ControlKey);
864  ControlKey = NULL;
865  }
866  }
867  if (FoundRightPDO)
868  {
869  /* No need to go further, as we already have found what we searched */
870  break;
871  }
872 
873  ExFreePool(DeviceBi);
874  DeviceBi = NULL;
875  ZwClose(DeviceKey);
876  DeviceKey = NULL;
877  }
878 
879  /* Add final NULL to ReturnBuffer */
880  ASSERT(ReturnBuffer.Length <= ReturnBuffer.MaximumLength);
881  if (ReturnBuffer.Length >= ReturnBuffer.MaximumLength)
882  {
883  PWSTR NewBuffer;
884  ReturnBuffer.MaximumLength += sizeof(WCHAR);
885  NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
886  if (!NewBuffer)
887  {
888  DPRINT("ExAllocatePool() failed\n");
890  goto cleanup;
891  }
892  if (ReturnBuffer.Buffer)
893  {
894  RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
895  ExFreePool(ReturnBuffer.Buffer);
896  }
897  ReturnBuffer.Buffer = NewBuffer;
898  }
899  ReturnBuffer.Buffer[ReturnBuffer.Length / sizeof(WCHAR)] = UNICODE_NULL;
900  *SymbolicLinkList = ReturnBuffer.Buffer;
902 
903 cleanup:
904  if (!NT_SUCCESS(Status) && ReturnBuffer.Buffer)
905  ExFreePool(ReturnBuffer.Buffer);
906  if (InterfaceKey != NULL)
907  ZwClose(InterfaceKey);
908  if (DeviceKey != NULL)
909  ZwClose(DeviceKey);
910  if (ReferenceKey != NULL)
911  ZwClose(ReferenceKey);
912  if (ControlKey != NULL)
913  ZwClose(ControlKey);
914  if (DeviceBi)
915  ExFreePool(DeviceBi);
916  if (ReferenceBi)
917  ExFreePool(ReferenceBi);
918  if (bip)
919  ExFreePool(bip);
920  return Status;
921 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_opt_ PDEVICE_OBJECT _In_ ULONG _Outptr_result_nullonfailure_ _At_ * SymbolicLinkList(return==0, __drv_allocatesMem(Mem))) PZZWSTR *SymbolicLinkList
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define UNICODE_NULL
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct _DEVICE_NODE * DeviceNode
Definition: iotypes.h:919
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DEVICE_INTERFACE_INCLUDE_NONACTIVE
Definition: iofuncs.h:2808
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
static const WCHAR Control[]
Definition: interface.c:27
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
static NTSTATUS IopOpenInterfaceKey(IN CONST GUID *InterfaceClassGuid, IN ACCESS_MASK DesiredAccess, OUT HANDLE *pInterfaceKey)
Definition: deviface.c:330
unsigned short USHORT
Definition: pedump.c:61
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
_In_ CONST GUID * InterfaceClassGuid
Definition: iofuncs.h:1134
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define REG_DWORD
Definition: sdbapi.c:596
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
static const WCHAR SymbolicLink[]
Definition: interface.c:31
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by CompBattGetBatteries(), DeviceInterfaceTest_Func(), get_device_pnp_name_guid(), IopFetchConfigurationInformation(), IopGetInterfaceDeviceList(), IoRegisterPlugPlayNotification(), KsRegisterFilterWithNoKSPins(), and WdmAudOpenSysAudioDevices().

◆ IoOpenDeviceInterfaceRegistryKey()

NTSTATUS NTAPI IoOpenDeviceInterfaceRegistryKey ( IN PUNICODE_STRING  SymbolicLinkName,
IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE  DeviceInterfaceKey 
)

Definition at line 241 of file deviface.c.

244 {
245  HANDLE InstanceKey, DeviceParametersKey;
248  UNICODE_STRING DeviceParametersU = RTL_CONSTANT_STRING(L"Device Parameters");
249 
250  Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName,
252  NULL,
253  NULL,
254  &InstanceKey);
255  if (!NT_SUCCESS(Status))
256  return Status;
257 
259  &DeviceParametersU,
261  InstanceKey,
262  NULL);
263  Status = ZwCreateKey(&DeviceParametersKey,
266  0,
267  NULL,
269  NULL);
270  ZwClose(InstanceKey);
271 
272  if (NT_SUCCESS(Status))
273  *DeviceInterfaceKey = DeviceParametersKey;
274 
275  return Status;
276 }
static NTSTATUS OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, IN OPTIONAL PHANDLE GuidKey, IN OPTIONAL PHANDLE DeviceKey, IN OPTIONAL PHANDLE InstanceKey)
Definition: deviface.c:33
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
_In_ ACCESS_MASK _Out_ PHANDLE DeviceInterfaceKey
Definition: iofuncs.h:1113
#define OBJ_OPENIF
Definition: winternl.h:229
smooth NULL
Definition: ftsmooth.c:416
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by Enum(), KsFilterFactoryUpdateCacheData(), KsRegisterFilterWithNoKSPins(), and PcNewRegistryKey().

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 148 of file plugplay.c.

149 {
150  if (IopRootDeviceNode == NULL)
151  return NULL;
152 
153  if (DeviceInstance == NULL ||
154  DeviceInstance->Length == 0)
155  {
157  {
160  }
161  else
162  return NULL;
163  }
164 
166 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:839
PDEVICE_NODE IopRootDeviceNode
Definition: pnpmgr.c:18
static PDEVICE_OBJECT IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:119
smooth NULL
Definition: ftsmooth.c:416
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by IoSetDeviceInterfaceState().

◆ IopOpenInterfaceKey()

static NTSTATUS IopOpenInterfaceKey ( IN CONST GUID InterfaceClassGuid,
IN ACCESS_MASK  DesiredAccess,
OUT HANDLE pInterfaceKey 
)
static

Definition at line 330 of file deviface.c.

333 {
334  UNICODE_STRING LocalMachine = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\");
338  HANDLE InterfaceKey = NULL;
340 
341  GuidString.Buffer = KeyName.Buffer = NULL;
342 
344  if (!NT_SUCCESS(Status))
345  {
346  DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
347  goto cleanup;
348  }
349 
350  KeyName.Length = 0;
351  KeyName.MaximumLength = LocalMachine.Length + ((USHORT)wcslen(REGSTR_PATH_DEVICE_CLASSES) + 1) * sizeof(WCHAR) + GuidString.Length;
352  KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
353  if (!KeyName.Buffer)
354  {
355  DPRINT("ExAllocatePool() failed\n");
357  goto cleanup;
358  }
359 
360  Status = RtlAppendUnicodeStringToString(&KeyName, &LocalMachine);
361  if (!NT_SUCCESS(Status))
362  {
363  DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
364  goto cleanup;
365  }
367  if (!NT_SUCCESS(Status))
368  {
369  DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
370  goto cleanup;
371  }
373  if (!NT_SUCCESS(Status))
374  {
375  DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
376  goto cleanup;
377  }
379  if (!NT_SUCCESS(Status))
380  {
381  DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
382  goto cleanup;
383  }
384 
387  &KeyName,
389  NULL,
390  NULL);
391  Status = ZwOpenKey(
392  &InterfaceKey,
395  if (!NT_SUCCESS(Status))
396  {
397  DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
398  goto cleanup;
399  }
400 
401  *pInterfaceKey = InterfaceKey;
403 
404 cleanup:
405  if (!NT_SUCCESS(Status))
406  {
407  if (InterfaceKey != NULL)
408  ZwClose(InterfaceKey);
409  }
412  return Status;
413 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
static PWSTR GuidString
Definition: apphelp.c:91
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define REGSTR_PATH_DEVICE_CLASSES
Definition: regstr.h:481
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
Status
Definition: gdiplustypes.h:24
unsigned short USHORT
Definition: pedump.c:61
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
_In_ CONST GUID * InterfaceClassGuid
Definition: iofuncs.h:1134
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IoGetDeviceInterfaces().

◆ IoRegisterDeviceInterface()

NTSTATUS NTAPI IoRegisterDeviceInterface ( IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN CONST GUID InterfaceClassGuid,
IN PUNICODE_STRING ReferenceString  OPTIONAL,
OUT PUNICODE_STRING  SymbolicLinkName 
)

Definition at line 955 of file deviface.c.

959 {
960  PUNICODE_STRING InstancePath;
963  UNICODE_STRING InterfaceKeyName;
964  UNICODE_STRING BaseKeyName;
965  UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))];
966  POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer;
969  HANDLE ClassKey;
970  HANDLE InterfaceKey;
971  HANDLE SubKey;
972  ULONG StartIndex;
974  ULONG i;
975  NTSTATUS Status, SymLinkStatus;
976  PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;
977 
979 
980  DPRINT("IoRegisterDeviceInterface(): PDO %p, RefString: %wZ\n",
982 
983  /* Parameters must pass three border of checks */
984  DeviceObjectExtension = (PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension;
985 
986  /* 1st level: Presence of a Device Node */
987  if (DeviceObjectExtension->DeviceNode == NULL)
988  {
989  DPRINT("PhysicalDeviceObject 0x%p doesn't have a DeviceNode\n", PhysicalDeviceObject);
991  }
992 
993  /* 2nd level: Presence of an non-zero length InstancePath */
994  if (DeviceObjectExtension->DeviceNode->InstancePath.Length == 0)
995  {
996  DPRINT("PhysicalDeviceObject 0x%p's DOE has zero-length InstancePath\n", PhysicalDeviceObject);
998  }
999 
1000  /* 3rd level: Optional, based on WDK documentation */
1001  if (ReferenceString != NULL)
1002  {
1003  /* Reference string must not contain path-separator symbols */
1004  for (i = 0; i < ReferenceString->Length / sizeof(WCHAR); i++)
1005  {
1006  if ((ReferenceString->Buffer[i] == '\\') ||
1007  (ReferenceString->Buffer[i] == '/'))
1009  }
1010  }
1011 
1013  if (!NT_SUCCESS(Status))
1014  {
1015  DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
1016  return Status;
1017  }
1018 
1019  /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
1022  PdoNameInfo,
1023  sizeof(PdoNameInfoBuffer),
1024  &i);
1025  if (!NT_SUCCESS(Status))
1026  {
1027  DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status);
1028  return Status;
1029  }
1030  ASSERT(PdoNameInfo->Name.Length);
1031 
1032  /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
1033  ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode);
1034  InstancePath = &((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath;
1035  BaseKeyName.Length = (USHORT)wcslen(BaseKeyString) * sizeof(WCHAR);
1036  BaseKeyName.MaximumLength = BaseKeyName.Length
1037  + GuidString.Length;
1038  BaseKeyName.Buffer = ExAllocatePool(
1039  PagedPool,
1040  BaseKeyName.MaximumLength);
1041  if (!BaseKeyName.Buffer)
1042  {
1043  DPRINT("ExAllocatePool() failed\n");
1045  }
1046  wcscpy(BaseKeyName.Buffer, BaseKeyString);
1048 
1049  /* Create BaseKeyName key in registry */
1052  &BaseKeyName,
1054  NULL, /* RootDirectory */
1055  NULL); /* SecurityDescriptor */
1056 
1057  Status = ZwCreateKey(
1058  &ClassKey,
1059  KEY_WRITE,
1061  0, /* TileIndex */
1062  NULL, /* Class */
1064  NULL); /* Disposition */
1065 
1066  if (!NT_SUCCESS(Status))
1067  {
1068  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1069  ExFreePool(BaseKeyName.Buffer);
1070  return Status;
1071  }
1072 
1073  /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */
1074  InterfaceKeyName.Length = 0;
1075  InterfaceKeyName.MaximumLength =
1076  4 * sizeof(WCHAR) + /* 4 = size of ##?# */
1077  InstancePath->Length +
1078  sizeof(WCHAR) + /* 1 = size of # */
1079  GuidString.Length;
1080  InterfaceKeyName.Buffer = ExAllocatePool(
1081  PagedPool,
1082  InterfaceKeyName.MaximumLength);
1083  if (!InterfaceKeyName.Buffer)
1084  {
1085  DPRINT("ExAllocatePool() failed\n");
1087  }
1088 
1089  RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#");
1090  StartIndex = InterfaceKeyName.Length / sizeof(WCHAR);
1091  RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath);
1092  for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
1093  {
1094  if (InterfaceKeyName.Buffer[StartIndex + i] == '\\')
1095  InterfaceKeyName.Buffer[StartIndex + i] = '#';
1096  }
1097  RtlAppendUnicodeToString(&InterfaceKeyName, L"#");
1098  RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString);
1099 
1100  /* Create the interface key in registry */
1103  &InterfaceKeyName,
1105  ClassKey,
1106  NULL); /* SecurityDescriptor */
1107 
1108  Status = ZwCreateKey(
1109  &InterfaceKey,
1110  KEY_WRITE,
1112  0, /* TileIndex */
1113  NULL, /* Class */
1115  NULL); /* Disposition */
1116 
1117  if (!NT_SUCCESS(Status))
1118  {
1119  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1120  ZwClose(ClassKey);
1121  ExFreePool(BaseKeyName.Buffer);
1122  return Status;
1123  }
1124 
1125  /* Write DeviceInstance entry. Value is InstancePath */
1126  Status = ZwSetValueKey(
1127  InterfaceKey,
1128  &DeviceInstance,
1129  0, /* TileIndex */
1130  REG_SZ,
1131  InstancePath->Buffer,
1132  InstancePath->Length);
1133  if (!NT_SUCCESS(Status))
1134  {
1135  DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1136  ZwClose(InterfaceKey);
1137  ZwClose(ClassKey);
1138  ExFreePool(InterfaceKeyName.Buffer);
1139  ExFreePool(BaseKeyName.Buffer);
1140  return Status;
1141  }
1142 
1143  /* Create subkey. Name is #ReferenceString */
1144  SubKeyName.Length = 0;
1145  SubKeyName.MaximumLength = sizeof(WCHAR);
1146  if (ReferenceString && ReferenceString->Length)
1147  SubKeyName.MaximumLength += ReferenceString->Length;
1148  SubKeyName.Buffer = ExAllocatePool(
1149  PagedPool,
1150  SubKeyName.MaximumLength);
1151  if (!SubKeyName.Buffer)
1152  {
1153  DPRINT("ExAllocatePool() failed\n");
1154  ZwClose(InterfaceKey);
1155  ZwClose(ClassKey);
1156  ExFreePool(InterfaceKeyName.Buffer);
1157  ExFreePool(BaseKeyName.Buffer);
1159  }
1161  if (ReferenceString && ReferenceString->Length)
1163 
1164  /* Create SubKeyName key in registry */
1167  &SubKeyName,
1169  InterfaceKey, /* RootDirectory */
1170  NULL); /* SecurityDescriptor */
1171 
1172  Status = ZwCreateKey(
1173  &SubKey,
1174  KEY_WRITE,
1176  0, /* TileIndex */
1177  NULL, /* Class */
1179  NULL); /* Disposition */
1180 
1181  if (!NT_SUCCESS(Status))
1182  {
1183  DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
1184  ZwClose(InterfaceKey);
1185  ZwClose(ClassKey);
1186  ExFreePool(InterfaceKeyName.Buffer);
1187  ExFreePool(BaseKeyName.Buffer);
1188  return Status;
1189  }
1190 
1191  /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
1192  SymbolicLinkName->Length = 0;
1193  SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
1194  + 4 * sizeof(WCHAR) /* 4 = size of \??\ */
1195  + InstancePath->Length
1196  + sizeof(WCHAR) /* 1 = size of # */
1197  + GuidString.Length
1198  + sizeof(WCHAR); /* final NULL */
1199  if (ReferenceString && ReferenceString->Length)
1200  SymbolicLinkName->MaximumLength += sizeof(WCHAR) + ReferenceString->Length;
1201  SymbolicLinkName->Buffer = ExAllocatePool(
1202  PagedPool,
1203  SymbolicLinkName->MaximumLength);
1204  if (!SymbolicLinkName->Buffer)
1205  {
1206  DPRINT("ExAllocatePool() failed\n");
1207  ZwClose(SubKey);
1208  ZwClose(InterfaceKey);
1209  ZwClose(ClassKey);
1210  ExFreePool(InterfaceKeyName.Buffer);
1211  ExFreePool(SubKeyName.Buffer);
1212  ExFreePool(BaseKeyName.Buffer);
1214  }
1215  RtlAppendUnicodeToString(SymbolicLinkName, L"\\??\\");
1216  StartIndex = SymbolicLinkName->Length / sizeof(WCHAR);
1217  RtlAppendUnicodeStringToString(SymbolicLinkName, InstancePath);
1218  for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
1219  {
1220  if (SymbolicLinkName->Buffer[StartIndex + i] == '\\')
1221  SymbolicLinkName->Buffer[StartIndex + i] = '#';
1222  }
1223  RtlAppendUnicodeToString(SymbolicLinkName, L"#");
1224  RtlAppendUnicodeStringToString(SymbolicLinkName, &GuidString);
1225  SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';
1226 
1227  /* Create symbolic link */
1228  DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
1229  SymLinkStatus = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
1230 
1231  /* If the symbolic link already exists, return an informational success status */
1232  if (SymLinkStatus == STATUS_OBJECT_NAME_COLLISION)
1233  {
1234  /* HACK: Delete the existing symbolic link and update it to the new PDO name */
1235  IoDeleteSymbolicLink(SymbolicLinkName);
1236  IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
1237  SymLinkStatus = STATUS_OBJECT_NAME_EXISTS;
1238  }
1239 
1240  if (!NT_SUCCESS(SymLinkStatus))
1241  {
1242  DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", SymLinkStatus);
1243  ZwClose(SubKey);
1244  ZwClose(InterfaceKey);
1245  ZwClose(ClassKey);
1246  ExFreePool(SubKeyName.Buffer);
1247  ExFreePool(InterfaceKeyName.Buffer);
1248  ExFreePool(BaseKeyName.Buffer);
1249  ExFreePool(SymbolicLinkName->Buffer);
1250  return SymLinkStatus;
1251  }
1252 
1253  if (ReferenceString && ReferenceString->Length)
1254  {
1255  RtlAppendUnicodeToString(SymbolicLinkName, L"\\");
1257  }
1258  SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';
1259 
1260  /* Write symbolic link name in registry */
1261  SymbolicLinkName->Buffer[1] = '\\';
1262  Status = ZwSetValueKey(
1263  SubKey,
1264  &SymbolicLink,
1265  0, /* TileIndex */
1266  REG_SZ,
1267  SymbolicLinkName->Buffer,
1268  SymbolicLinkName->Length);
1269  if (!NT_SUCCESS(Status))
1270  {
1271  DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status);
1272  ExFreePool(SymbolicLinkName->Buffer);
1273  }
1274  else
1275  {
1276  SymbolicLinkName->Buffer[1] = '?';
1277  }
1278 
1279  ZwClose(SubKey);
1280  ZwClose(InterfaceKey);
1281  ZwClose(ClassKey);
1282  ExFreePool(SubKeyName.Buffer);
1283  ExFreePool(InterfaceKeyName.Buffer);
1284  ExFreePool(BaseKeyName.Buffer);
1285 
1286  return NT_SUCCESS(Status) ? SymLinkStatus : Status;
1287 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static PWSTR GuidString
Definition: apphelp.c:91
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define ASSERT_IRQL_EQUAL(x)
Definition: debug.h:43
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1156
struct _EXTENDED_DEVOBJ_EXTENSION * PEXTENDED_DEVOBJ_EXTENSION
#define OBJ_OPENIF
Definition: winternl.h:229
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ CONST GUID _In_opt_ PUNICODE_STRING ReferenceString
Definition: iofuncs.h:1134
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct _DEVICE_NODE * DeviceNode
Definition: iotypes.h:919
#define KEY_WRITE
Definition: nt_native.h:1031
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static PWCHAR BaseKeyString
Definition: deviface.c:29
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
_In_ CONST GUID * InterfaceClassGuid
Definition: iofuncs.h:1134
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
static const WCHAR SymbolicLink[]
Definition: interface.c:31
struct _OBJECT_NAME_INFORMATION * POBJECT_NAME_INFORMATION
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

Referenced by _Function_class_(), AddDevice(), BatteryClassInitializeDevice(), Bus_PDO_PnP(), CdRomInitDevice(), ClassAddDevice(), ClasspRegisterMountedDeviceInterface(), DiskInitFdo(), DiskInitPdo(), FreeBT_AddDevice(), HidClassPDO_PnP(), i8042PowerWorkItem(), KsCreateBusEnumObject(), KspRegisterDeviceAssociation(), KspRegisterDeviceInterfaces(), NdisIAddDevice(), PcRegisterSubdevice(), RamdiskAddDevice(), RamdiskPnp(), RegisterDeviceInterfaces(), ScsiFlopInitDevice(), SerenumAddDevice(), SerialAddDeviceInternal(), CHubController::SetDeviceInterface(), SysAudioRegisterDeviceInterfaces(), Test_IoRegisterDeviceInterface(), USBH_SymbolicLink(), USBHUB_PdoStartDevice(), USBPORT_RegisterDeviceInterface(), and WdmAudRegisterDeviceInterface().

◆ IoSetDeviceInterfaceState()

NTSTATUS NTAPI IoSetDeviceInterfaceState ( IN PUNICODE_STRING  SymbolicLinkName,
IN BOOLEAN  Enable 
)

Definition at line 1311 of file deviface.c.

1313 {
1316  NTSTATUS Status;
1317  LPCGUID EventGuid;
1318  HANDLE InstanceHandle, ControlHandle;
1321  ULONG LinkedValue, Index;
1322  GUID DeviceGuid;
1323  UNICODE_STRING DosDevicesPrefix1 = RTL_CONSTANT_STRING(L"\\??\\");
1324  UNICODE_STRING DosDevicesPrefix2 = RTL_CONSTANT_STRING(L"\\\\?\\");
1325  UNICODE_STRING LinkNameNoPrefix;
1326  USHORT i;
1327  USHORT ReferenceStringOffset;
1328 
1329  if (SymbolicLinkName == NULL)
1330  {
1331  return STATUS_INVALID_PARAMETER;
1332  }
1333 
1334  DPRINT("IoSetDeviceInterfaceState('%wZ', %u)\n", SymbolicLinkName, Enable);
1335 
1336  /* Symbolic link name is \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
1337  /* Make sure it starts with the expected prefix */
1338  if (!RtlPrefixUnicodeString(&DosDevicesPrefix1, SymbolicLinkName, FALSE) &&
1339  !RtlPrefixUnicodeString(&DosDevicesPrefix2, SymbolicLinkName, FALSE))
1340  {
1341  DPRINT1("IoSetDeviceInterfaceState() invalid link name '%wZ'\n", SymbolicLinkName);
1342  return STATUS_INVALID_PARAMETER;
1343  }
1344 
1345  /* Make a version without the prefix for further processing */
1346  ASSERT(DosDevicesPrefix1.Length == DosDevicesPrefix2.Length);
1347  ASSERT(SymbolicLinkName->Length >= DosDevicesPrefix1.Length);
1348  LinkNameNoPrefix.Buffer = SymbolicLinkName->Buffer + DosDevicesPrefix1.Length / sizeof(WCHAR);
1349  LinkNameNoPrefix.Length = SymbolicLinkName->Length - DosDevicesPrefix1.Length;
1350  LinkNameNoPrefix.MaximumLength = LinkNameNoPrefix.Length;
1351 
1352  /* Find the reference string, if any */
1353  for (i = 0; i < LinkNameNoPrefix.Length / sizeof(WCHAR); i++)
1354  {
1355  if (LinkNameNoPrefix.Buffer[i] == L'\\')
1356  {
1357  break;
1358  }
1359  }
1360  ReferenceStringOffset = i * sizeof(WCHAR);
1361 
1362  /* The GUID is before the reference string or at the end */
1363  ASSERT(LinkNameNoPrefix.Length >= ReferenceStringOffset);
1364  if (ReferenceStringOffset < GUID_STRING_BYTES + sizeof(WCHAR))
1365  {
1366  DPRINT1("IoSetDeviceInterfaceState() invalid link name '%wZ'\n", SymbolicLinkName);
1367  return STATUS_INVALID_PARAMETER;
1368  }
1369 
1370  GuidString.Buffer = LinkNameNoPrefix.Buffer + (ReferenceStringOffset - GUID_STRING_BYTES) / sizeof(WCHAR);
1371  GuidString.Length = GUID_STRING_BYTES;
1372  GuidString.MaximumLength = GuidString.Length;
1373  Status = RtlGUIDFromString(&GuidString, &DeviceGuid);
1374  if (!NT_SUCCESS(Status))
1375  {
1376  DPRINT1("RtlGUIDFromString() invalid GUID '%wZ' in link name '%wZ'\n", &GuidString, SymbolicLinkName);
1377  return Status;
1378  }
1379 
1380  /* Open registry keys */
1381  Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName,
1383  NULL,
1384  NULL,
1385  &InstanceHandle);
1386  if (!NT_SUCCESS(Status))
1387  return Status;
1388 
1389  RtlInitUnicodeString(&KeyName, L"Control");
1391  &KeyName,
1393  InstanceHandle,
1394  NULL);
1395  Status = ZwCreateKey(&ControlHandle,
1396  KEY_SET_VALUE,
1398  0,
1399  NULL,
1401  NULL);
1402  ZwClose(InstanceHandle);
1403  if (!NT_SUCCESS(Status))
1404  {
1405  DPRINT1("Failed to create the Control subkey\n");
1406  return Status;
1407  }
1408 
1409  LinkedValue = (Enable ? 1 : 0);
1410 
1411  RtlInitUnicodeString(&KeyName, L"Linked");
1412  Status = ZwSetValueKey(ControlHandle,
1413  &KeyName,
1414  0,
1415  REG_DWORD,
1416  &LinkedValue,
1417  sizeof(ULONG));
1418  ZwClose(ControlHandle);
1419  if (!NT_SUCCESS(Status))
1420  {
1421  DPRINT1("Failed to write the Linked value\n");
1422  return Status;
1423  }
1424 
1425  ASSERT(GuidString.Buffer >= LinkNameNoPrefix.Buffer + 1);
1426  DeviceInstance.Length = (GuidString.Buffer - LinkNameNoPrefix.Buffer - 1) * sizeof(WCHAR);
1427  if (DeviceInstance.Length == 0)
1428  {
1429  DPRINT1("No device instance in link name '%wZ'\n", SymbolicLinkName);
1431  }
1435  TAG_IO);
1436  if (DeviceInstance.Buffer == NULL)
1437  {
1438  /* no memory */
1440  }
1441 
1443  LinkNameNoPrefix.Buffer,
1445 
1446  for (Index = 0; Index < DeviceInstance.Length / sizeof(WCHAR); Index++)
1447  {
1448  if (DeviceInstance.Buffer[Index] == L'#')
1449  {
1450  DeviceInstance.Buffer[Index] = L'\\';
1451  }
1452  }
1453 
1455 
1456  if (!PhysicalDeviceObject)
1457  {
1458  DPRINT1("IopGetDeviceObjectFromDeviceInstance failed to find device object for %wZ\n", &DeviceInstance);
1461  }
1462 
1464 
1469  EventGuid,
1470  &DeviceGuid,
1471  (PVOID)SymbolicLinkName);
1472 
1474  DPRINT("Status %x\n", Status);
1475  return STATUS_SUCCESS;
1476 }
static NTSTATUS OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, IN OPTIONAL PHANDLE GuidKey, IN OPTIONAL PHANDLE DeviceKey, IN OPTIONAL PHANDLE InstanceKey)
Definition: deviface.c:33
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
static PWSTR GuidString
Definition: apphelp.c:91
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
#define KEY_SET_VALUE
Definition: nt_native.h:1017
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define GUID_STRING_BYTES
Definition: deviface.c:21
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSYSAPI NTSTATUS WINAPI RtlGUIDFromString(PUNICODE_STRING, GUID *)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID IopNotifyPlugPlayNotification(IN PDEVICE_OBJECT DeviceObject, IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN LPCGUID Event, IN PVOID EventCategoryData1, IN PVOID EventCategoryData2)
Definition: pnpnotify.c:36
static const WCHAR L[]
Definition: oid.c:1250
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:148
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define REG_DWORD
Definition: sdbapi.c:596
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by _Function_class_(), add_volume_device(), AddDevice(), BatteryClassInitializeDevice(), BatteryClassUnload(), Bus_PDO_PnP(), CdRomInitDevice(), CdRomRemoveDevice(), ClasspRegisterMountedDeviceInterface(), ClassRemoveDevice(), DiskInitFdo(), DiskInitPdo(), DiskRemoveDevice(), HandleRemoveDevice(), HandleStartDevice(), HandleSurpriseRemoval(), HidClassPDO_PnP(), i8042PowerWorkItem(), KsCreateBusEnumObject(), KspEnableBusDeviceInterface(), KspRegisterDeviceAssociation(), KspRemoveDeviceAssociations(), KspSetDeviceInterfacesState(), NdisIPnPStartDevice(), NdisIPnPStopDevice(), PcRegisterSubdevice(), RamdiskAddDevice(), RamdiskPnp(), RamdiskRemoveBusDevice(), RegisterDeviceInterfaces(), remove_volume_child(), ScsiFlopRemoveDevice(), ScsiFlopStartDevice(), SerenumFdoStartDevice(), SerialPnpStartDevice(), CHubController::SetDeviceInterface(), SysAudioRegisterDeviceInterfaces(), Test_IoSetDeviceInterface(), USBH_SymbolicLink(), USBHUB_PdoStartDevice(), USBPORT_RegisterDeviceInterface(), and WdmAudRegisterDeviceInterface().

◆ OpenRegistryHandlesFromSymbolicLink()

static NTSTATUS OpenRegistryHandlesFromSymbolicLink ( IN PUNICODE_STRING  SymbolicLinkName,
IN ACCESS_MASK  DesiredAccess,
IN OPTIONAL PHANDLE  GuidKey,
IN OPTIONAL PHANDLE  DeviceKey,
IN OPTIONAL PHANDLE  InstanceKey 
)
static

Definition at line 33 of file deviface.c.

38 {
40  UNICODE_STRING BaseKeyU;
42  PWCHAR StartPosition, EndPosition;
43  HANDLE ClassesKey;
44  PHANDLE GuidKeyRealP, DeviceKeyRealP, InstanceKeyRealP;
45  HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal;
47 
48  SubKeyName.Buffer = NULL;
49 
50  if (GuidKey != NULL)
51  GuidKeyRealP = GuidKey;
52  else
53  GuidKeyRealP = &GuidKeyReal;
54 
55  if (DeviceKey != NULL)
56  DeviceKeyRealP = DeviceKey;
57  else
58  DeviceKeyRealP = &DeviceKeyReal;
59 
60  if (InstanceKey != NULL)
61  InstanceKeyRealP = InstanceKey;
62  else
63  InstanceKeyRealP = &InstanceKeyReal;
64 
65  *GuidKeyRealP = NULL;
66  *DeviceKeyRealP = NULL;
67  *InstanceKeyRealP = NULL;
68 
70 
71  /* Open the DeviceClasses key */
73  &BaseKeyU,
75  NULL,
76  NULL);
77  Status = ZwOpenKey(&ClassesKey,
80  if (!NT_SUCCESS(Status))
81  {
82  DPRINT1("Failed to open %wZ\n", &BaseKeyU);
83  goto cleanup;
84  }
85 
86  StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
87  EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
88  if (!StartPosition || !EndPosition || StartPosition > EndPosition)
89  {
90  DPRINT1("Bad symbolic link: %wZ\n", SymbolicLinkName);
92  }
93  GuidString.Buffer = StartPosition;
94  GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition);
95 
97  &GuidString,
99  ClassesKey,
100  NULL);
101  Status = ZwCreateKey(GuidKeyRealP,
104  0,
105  NULL,
107  NULL);
108  ZwClose(ClassesKey);
109  if (!NT_SUCCESS(Status))
110  {
111  DPRINT1("Failed to open %wZ%wZ (%x)\n", &BaseKeyU, &GuidString, Status);
112  goto cleanup;
113  }
114 
115  SubKeyName.MaximumLength = SymbolicLinkName->Length + sizeof(WCHAR);
116  SubKeyName.Length = 0;
117  SubKeyName.Buffer = ExAllocatePool(PagedPool, SubKeyName.MaximumLength);
118  if (!SubKeyName.Buffer)
119  {
121  goto cleanup;
122  }
123 
125  SymbolicLinkName);
126 
127  SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
128 
129  SubKeyName.Buffer[0] = L'#';
130  SubKeyName.Buffer[1] = L'#';
131  SubKeyName.Buffer[2] = L'?';
132  SubKeyName.Buffer[3] = L'#';
133 
134  ReferenceString.Buffer = wcsrchr(SubKeyName.Buffer, '\\');
135  if (ReferenceString.Buffer != NULL)
136  {
137  ReferenceString.Buffer[0] = L'#';
138 
139  SubKeyName.Length = (USHORT)((ULONG_PTR)(ReferenceString.Buffer) - (ULONG_PTR)SubKeyName.Buffer);
140  ReferenceString.Length = SymbolicLinkName->Length - SubKeyName.Length;
141  }
142  else
143  {
145  }
146 
148  &SubKeyName,
150  *GuidKeyRealP,
151  NULL);
152  Status = ZwCreateKey(DeviceKeyRealP,
155  0,
156  NULL,
158  NULL);
159  if (!NT_SUCCESS(Status))
160  {
161  DPRINT1("Failed to open %wZ%wZ\\%wZ Status %x\n", &BaseKeyU, &GuidString, &SubKeyName, Status);
162  goto cleanup;
163  }
164 
168  *DeviceKeyRealP,
169  NULL);
170  Status = ZwCreateKey(InstanceKeyRealP,
173  0,
174  NULL,
176  NULL);
177  if (!NT_SUCCESS(Status))
178  {
179  DPRINT1("Failed to open %wZ%wZ\\%wZ%\\%wZ (%x)\n", &BaseKeyU, &GuidString, &SubKeyName, &ReferenceString, Status);
180  goto cleanup;
181  }
182 
184 
185 cleanup:
186  if (SubKeyName.Buffer != NULL)
187  ExFreePool(SubKeyName.Buffer);
188 
189  if (NT_SUCCESS(Status))
190  {
191  if (!GuidKey)
192  ZwClose(*GuidKeyRealP);
193 
194  if (!DeviceKey)
195  ZwClose(*DeviceKeyRealP);
196 
197  if (!InstanceKey)
198  ZwClose(*InstanceKeyRealP);
199  }
200  else
201  {
202  if (*GuidKeyRealP != NULL)
203  ZwClose(*GuidKeyRealP);
204 
205  if (*DeviceKeyRealP != NULL)
206  ZwClose(*DeviceKeyRealP);
207 
208  if (*InstanceKeyRealP != NULL)
209  ZwClose(*InstanceKeyRealP);
210  }
211 
212  return Status;
213 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static PWSTR GuidString
Definition: apphelp.c:91
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING SubKeyName
Definition: ndis.h:4723
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UNICODE_NULL
_In_ CONST GUID _In_opt_ PUNICODE_STRING ReferenceString
Definition: iofuncs.h:1134
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static PWCHAR BaseKeyString
Definition: deviface.c:29
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
Status
Definition: gdiplustypes.h:24
_In_ ULONG _In_ PVOID StartPosition
Definition: usbdlib.h:145
unsigned short USHORT
Definition: pedump.c:61
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019

Referenced by IoOpenDeviceInterfaceRegistryKey(), and IoSetDeviceInterfaceState().

Variable Documentation

◆ BaseKeyString

PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\"
static

Definition at line 29 of file deviface.c.

Referenced by IoRegisterDeviceInterface(), and OpenRegistryHandlesFromSymbolicLink().