NTSTATUS AnajoystReadRegistryParameterDWORD( PUNICODE_STRING RegistryPathName, PWSTR ParameterName, PDWORD ParameterValue ) /*++ Routine Description: This routine reads registry values for the driver configuration Arguments: RegistryPathName - Registry path containing the desired parameters ParameterName - The name of the parameter ParameterValue - Variable to receive the parameter value Return Value: STATUS_SUCCESS -- STATUS_NO_MORE_ENTRIES -- Couldn't find any entries STATUS_INSUFFICIENT_RESOURCES -- Couldn't allocate paged pool STATUS_DEVICE_CONFIGURATION_ERROR -- Returned value wasn't a DWORD or error status from NT itself -- */ { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE ServiceKey; HANDLE DeviceKey; // Key handle of service node UNICODE_STRING DeviceName; // Key to parameter node DWORD KeyIndex; DWORD KeyValueLength; PBYTE KeyData; BOOL ValueWasFound; PKEY_VALUE_FULL_INFORMATION KeyInfo; InitializeObjectAttributes( &ObjectAttributes, RegistryPathName, OBJ_CASE_INSENSITIVE, NULL, (PSECURITY_DESCRIPTOR) NULL); // // Open a key for our services node entry // Status = ZwOpenKey( &ServiceKey, KEY_READ | KEY_WRITE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { return Status; } // // Open the key to our device subkey // RtlInitUnicodeString(&DeviceName, L"Parameters"); InitializeObjectAttributes( &ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, ServiceKey, (PSECURITY_DESCRIPTOR) NULL); Status = ZwOpenKey (&DeviceKey, KEY_READ | KEY_WRITE, &ObjectAttributes); ZwClose(ServiceKey); if (!NT_SUCCESS(Status)) { return Status; } // // Loop reading our key values // // TODO exit loop when value is found? ValueWasFound = FALSE; for (KeyIndex = 0; ; KeyIndex++) { KeyValueLength = 0; // // find out how much data we will get // Status = ZwEnumerateValueKey( DeviceKey, KeyIndex, KeyValueFullInformation, NULL, 0, &KeyValueLength); if (STATUS_NO_MORE_ENTRIES == Status) { break; } if (0 == KeyValueLength) { return Status; } // // Read the data // KeyData = ExAllocatePool (PagedPool, KeyValueLength); if (NULL == KeyData) { return STATUS_INSUFFICIENT_RESOURCES; } Status = ZwEnumerateValueKey( DeviceKey, KeyIndex, KeyValueFullInformation, KeyData, KeyValueLength, &KeyValueLength); if (!NT_SUCCESS(Status)) { ExFreePool(KeyData); return Status; } KeyInfo = (PKEY_VALUE_FULL_INFORMATION) KeyData; if (0 == lstrnicmpW(KeyInfo->Name, ParameterName, KeyInfo->NameLength / sizeof(WCHAR))) { // check its a DWORD if (REG_DWORD != KeyInfo->Type) { ExFreePool(KeyData); return STATUS_DEVICE_CONFIGURATION_ERROR; } ValueWasFound = TRUE; *ParameterValue = *(PDWORD) (KeyData + KeyInfo->DataOffset); } ExFreePool(KeyData); } return (ValueWasFound) ? STATUS_SUCCESS : STATUS_DEVICE_CONFIGURATION_ERROR; }
VOID EnumSubValueTest() { WCHAR MY_KEY_NAME[] = L"\\Registry\\Machine\\Software\\Microsoft\\.NETFramework"; UNICODE_STRING RegUnicodeString; HANDLE hRegister; OBJECT_ATTRIBUTES objectAttributes; ULONG ulSize,i; UNICODE_STRING uniKeyName; PKEY_FULL_INFORMATION pfi; NTSTATUS ntStatus; //初始化UNICODE_STRING字符串 RtlInitUnicodeString( &RegUnicodeString, MY_KEY_NAME); //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE_INSENSITIVE,//对大小写敏感 NULL, NULL ); //打开注册表 ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes); if (NT_SUCCESS(ntStatus)) { DbgPrint("Open register successfully\n"); } //查询VALUE的大小 ZwQueryKey(hRegister,KeyFullInformation,NULL,0,&ulSize); pfi = (PKEY_FULL_INFORMATION) ExAllocatePool(PagedPool,ulSize); ZwQueryKey(hRegister,KeyFullInformation,pfi,ulSize,&ulSize); for (i=0;i<pfi->Values;i++) { PKEY_VALUE_BASIC_INFORMATION pvbi; //查询单个VALUE的大小 ZwEnumerateValueKey(hRegister,i,KeyValueBasicInformation,NULL,0,&ulSize); pvbi = (PKEY_VALUE_BASIC_INFORMATION)ExAllocatePool(PagedPool,ulSize); //查询单个VALUE的详情 ZwEnumerateValueKey(hRegister,i,KeyValueBasicInformation,pvbi,ulSize,&ulSize); uniKeyName.Length = (USHORT)pvbi->NameLength; uniKeyName.MaximumLength = (USHORT)pvbi->NameLength; uniKeyName.Buffer = pvbi->Name; DbgPrint("The %d sub value name:%wZ\n",i,&uniKeyName); if (pvbi->Type==REG_SZ) { DbgPrint("The sub value type:REG_SZ\n"); } else if (pvbi->Type==REG_MULTI_SZ) { DbgPrint("The sub value type:REG_MULTI_SZ\n"); } else if (pvbi->Type==REG_DWORD) { DbgPrint("The sub value type:REG_DWORD\n"); } else if (pvbi->Type==REG_BINARY) { DbgPrint("The sub value type:REG_BINARY\n"); } ExFreePool(pvbi); } ExFreePool(pfi); ZwClose(hRegister); }
NTSTATUS NTAPI IntCopyRegistryKey( _In_ HANDLE SourceKeyHandle, _In_ HANDLE DestKeyHandle) { PVOID InfoBuffer; PKEY_BASIC_INFORMATION KeyInformation; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; OBJECT_ATTRIBUTES ObjectAttributes; ULONG Index, InformationLength, RequiredLength; UNICODE_STRING NameString; NTSTATUS Status; HANDLE SourceSubKeyHandle, DestSubKeyHandle; /* Start with no buffer, set initial size */ InfoBuffer = NULL; InformationLength = 256; /* Start looping with key index 0 */ Index = 0; while (TRUE) { /* Check if we have no buffer */ if (InfoBuffer == NULL) { /* Allocate a new buffer */ InfoBuffer = ExAllocatePoolWithTag(PagedPool, InformationLength, TAG_VIDEO_PORT_BUFFER); if (InfoBuffer == NULL) { ERR_(VIDEOPRT, "Could not allocate buffer for key info\n"); return Status; } } /* Enumerate the next sub-key */ KeyInformation = InfoBuffer; Status = ZwEnumerateKey(SourceKeyHandle, Index, KeyBasicInformation, KeyInformation, InformationLength, &RequiredLength); if ((Status == STATUS_BUFFER_OVERFLOW) || (Status == STATUS_BUFFER_TOO_SMALL)) { /* Free the buffer and remember the required size */ ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER); InfoBuffer = NULL; InformationLength = RequiredLength; /* Try again */ continue; } else if (Status == STATUS_NO_MORE_ENTRIES) { /* We are done with the sub-keys */ break; } else if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ZwEnumerateKey failed, status 0x%lx\n", Status); goto Cleanup; } /* Initialize a unicode string from the key name */ NameString.Buffer = KeyInformation->Name; NameString.Length = (USHORT)KeyInformation->NameLength; NameString.MaximumLength = NameString.Length; /* Initialize object attributes and open the source sub-key */ InitializeObjectAttributes(&ObjectAttributes, &NameString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, SourceKeyHandle, NULL); Status = ZwOpenKey(&SourceSubKeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "failed to open the source key.\n"); goto Cleanup; } /* Initialize object attributes and create the dest sub-key */ InitializeObjectAttributes(&ObjectAttributes, &NameString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, DestKeyHandle, NULL); Status = ZwCreateKey(&DestSubKeyHandle, KEY_WRITE, &ObjectAttributes, 0, NULL, 0, NULL); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "failed to create the destination key.\n"); ObCloseHandle(SourceSubKeyHandle, KernelMode); goto Cleanup; } /* Recursively copy the sub-key */ Status = IntCopyRegistryKey(SourceSubKeyHandle, DestSubKeyHandle); if (!NT_SUCCESS(Status)) { /* Just warn, but continue with the remaining sub-keys */ WARN_(VIDEOPRT, "failed to copy subkey '%wZ'.\n", &NameString); } /* Close the sub-key handles */ ObCloseHandle(SourceSubKeyHandle, KernelMode); ObCloseHandle(DestSubKeyHandle, KernelMode); /* Next sub-key */ Index++; } /* Start looping with value index 0 */ Index = 0; while (TRUE) { /* Check if we have no buffer */ if (InfoBuffer == NULL) { /* Allocate a new buffer */ InfoBuffer = ExAllocatePoolWithTag(PagedPool, InformationLength, TAG_VIDEO_PORT_BUFFER); if (InfoBuffer == NULL) { ERR_(VIDEOPRT, "Could not allocate buffer for key values\n"); return Status; } } /* Enumerate the next value */ KeyValueInformation = InfoBuffer; Status = ZwEnumerateValueKey(SourceKeyHandle, Index, KeyValueFullInformation, KeyValueInformation, InformationLength, &RequiredLength); if ((Status == STATUS_BUFFER_OVERFLOW) || (Status == STATUS_BUFFER_TOO_SMALL)) { /* Free the buffer and remember the required size */ ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER); InfoBuffer = NULL; InformationLength = RequiredLength; /* Try again */ continue; } else if (Status == STATUS_NO_MORE_ENTRIES) { /* We are done with the values */ Status = STATUS_SUCCESS; break; } else if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ZwEnumerateValueKey failed, status 0x%lx\n", Status); goto Cleanup; } /* Initialize a unicode string from the value name */ NameString.Buffer = KeyValueInformation->Name; NameString.Length = (USHORT)KeyValueInformation->NameLength; NameString.MaximumLength = NameString.Length; /* Create the key value in the destination key */ Status = ZwSetValueKey(DestKeyHandle, &NameString, KeyValueInformation->TitleIndex, KeyValueInformation->Type, (PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset, KeyValueInformation->DataLength); if (!NT_SUCCESS(Status)) { /* Just warn, but continue with the remaining sub-keys */ WARN_(VIDEOPRT, "failed to set value '%wZ'.\n", NameString); } /* Next subkey */ Index++; } Cleanup: /* Free the buffer and return the failure code */ if (InfoBuffer != NULL) ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER); return Status; }
NTSTATUS RegistryEnumerateValues( IN HANDLE Key, IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR), IN PVOID Context ) { ULONG Size; NTSTATUS status; PKEY_FULL_INFORMATION Full; PKEY_VALUE_BASIC_INFORMATION Basic; ULONG Index; status = ZwQueryKey(Key, KeyFullInformation, NULL, 0, &Size); if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL) goto fail1; #pragma prefast(suppress:6102) Full = __RegistryAllocate(Size); status = STATUS_NO_MEMORY; if (Full == NULL) goto fail2; status = ZwQueryKey(Key, KeyFullInformation, Full, Size, &Size); if (!NT_SUCCESS(status)) goto fail3; Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + Full->MaxValueNameLen; Basic = __RegistryAllocate(Size); status = STATUS_NO_MEMORY; if (Basic == NULL) goto fail4; for (Index = 0; Index < Full->Values; Index++) { UNICODE_STRING Unicode; ANSI_STRING Ansi; status = ZwEnumerateValueKey(Key, Index, KeyValueBasicInformation, Basic, Size, &Size); if (!NT_SUCCESS(status)) goto fail5; Unicode.MaximumLength = (USHORT)Basic->NameLength; Unicode.Buffer = Basic->Name; Unicode.Length = (USHORT)Basic->NameLength; Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR)); Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength); status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE); ASSERT(NT_SUCCESS(status)); Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR)); status = Callback(Context, Key, Ansi.Buffer); __RegistryFree(Ansi.Buffer); if (!NT_SUCCESS(status)) goto fail6; } __RegistryFree(Basic); __RegistryFree(Full); return STATUS_SUCCESS; fail6: fail5: __RegistryFree(Basic); fail4: fail3: __RegistryFree(Full); fail2: fail1: return status; }
NTSTATUS NTAPI PciBuildHackTable(IN HANDLE KeyHandle) { PKEY_FULL_INFORMATION FullInfo; ULONG i, HackCount; PKEY_VALUE_FULL_INFORMATION ValueInfo; PPCI_HACK_ENTRY Entry; NTSTATUS Status; ULONG NameLength, ResultLength; ULONGLONG HackFlags; /* So we know what to free at the end of the body */ FullInfo = NULL; ValueInfo = NULL; do { /* Query the size required for full key information */ Status = ZwQueryKey(KeyHandle, KeyFullInformation, NULL, 0, &ResultLength); if (Status != STATUS_BUFFER_TOO_SMALL) break; /* Allocate the space required to hold the full key information */ Status = STATUS_INSUFFICIENT_RESOURCES; ASSERT(ResultLength > 0); FullInfo = ExAllocatePoolWithTag(PagedPool, ResultLength, PCI_POOL_TAG); if (!FullInfo) break; /* Go ahead and query the key information */ Status = ZwQueryKey(KeyHandle, KeyFullInformation, FullInfo, ResultLength, &ResultLength); if (!NT_SUCCESS(Status)) break; /* The only piece of information that's needed is the count of values */ HackCount = FullInfo->Values; /* Free the structure now */ ExFreePoolWithTag(FullInfo, 0); FullInfo = NULL; /* Allocate the hack table, now that the number of entries is known */ Status = STATUS_INSUFFICIENT_RESOURCES; ResultLength = sizeof(PCI_HACK_ENTRY) * HackCount; PciHackTable = ExAllocatePoolWithTag(NonPagedPool, ResultLength + sizeof(PCI_HACK_ENTRY), PCI_POOL_TAG); if (!PciHackTable) break; /* Allocate the space needed to hold the full value information */ ValueInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEY_VALUE_FULL_INFORMATION) + PCI_HACK_ENTRY_FULL_SIZE, PCI_POOL_TAG); if (!PciHackTable) break; /* Loop each value in the registry */ Entry = &PciHackTable[0]; for (i = 0; i < HackCount; i++) { /* Get the entry for this value */ Entry = &PciHackTable[i]; /* Query the value in the key */ Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation, ValueInfo, sizeof(KEY_VALUE_FULL_INFORMATION) + PCI_HACK_ENTRY_FULL_SIZE, &ResultLength); if (!NT_SUCCESS(Status)) { /* Check why the call failed */ if ((Status != STATUS_BUFFER_OVERFLOW) && (Status != STATUS_BUFFER_TOO_SMALL)) { /* The call failed due to an unknown error, bail out */ break; } /* The data seems to mismatch, try the next key in the list */ continue; } /* Check if the value data matches what's expected */ if ((ValueInfo->Type != REG_BINARY) || (ValueInfo->DataLength != sizeof(ULONGLONG))) { /* It doesn't, try the next key in the list */ continue; } /* Read the actual hack flags */ HackFlags = *(PULONGLONG)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset); /* Check what kind of errata entry this is, based on the name */ NameLength = ValueInfo->NameLength; if ((NameLength != PCI_HACK_ENTRY_SIZE) && (NameLength != PCI_HACK_ENTRY_REV_SIZE) && (NameLength != PCI_HACK_ENTRY_SUBSYS_SIZE) && (NameLength != PCI_HACK_ENTRY_FULL_SIZE)) { /* It's an invalid entry, skip it */ DPRINT1("Skipping hack entry with invalid length name\n"); continue; } /* Initialize the entry */ RtlZeroMemory(Entry, sizeof(PCI_HACK_ENTRY)); /* Get the vendor and device data */ if (!(PciStringToUSHORT(ValueInfo->Name, &Entry->VendorID)) || !(PciStringToUSHORT(&ValueInfo->Name[4], &Entry->DeviceID))) { /* This failed, try the next entry */ continue; } /* Check if the entry contains subsystem information */ if ((NameLength == PCI_HACK_ENTRY_SUBSYS_SIZE) || (NameLength == PCI_HACK_ENTRY_FULL_SIZE)) { /* Get the data */ if (!(PciStringToUSHORT(&ValueInfo->Name[8], &Entry->SubVendorID)) || !(PciStringToUSHORT(&ValueInfo->Name[12], &Entry->SubSystemID))) { /* This failed, try the next entry */ continue; } /* Save the fact this entry has finer controls */ Entry->Flags |= PCI_HACK_HAS_SUBSYSTEM_INFO; } /* Check if the entry contains revision information */ if ((NameLength == PCI_HACK_ENTRY_REV_SIZE) || (NameLength == PCI_HACK_ENTRY_FULL_SIZE)) { /* Get the data */ if (!PciStringToUSHORT(&ValueInfo->Name[16], &Entry->RevisionID)) { /* This failed, try the next entry */ continue; } /* Save the fact this entry has finer controls */ Entry->Flags |= PCI_HACK_HAS_REVISION_INFO; } /* Only the last entry should have this set */ ASSERT(Entry->VendorID != PCI_INVALID_VENDORID); /* Save the actual hack flags */ Entry->HackFlags = HackFlags; /* Print out for the debugger's sake */ #ifdef HACK_DEBUG DPRINT1("Adding Hack entry for Vendor:0x%04x Device:0x%04x ", Entry->VendorID, Entry->DeviceID); if (Entry->Flags & PCI_HACK_HAS_SUBSYSTEM_INFO) DbgPrint("SybSys:0x%04x SubVendor:0x%04x ", Entry->SubSystemID, Entry->SubVendorID); if (Entry->Flags & PCI_HACK_HAS_REVISION_INFO) DbgPrint("Revision:0x%02x", Entry->RevisionID); DbgPrint(" = 0x%I64x\n", Entry->HackFlags); #endif } /* Bail out in case of failure */ if (!NT_SUCCESS(Status)) break; /* Terminate the table with an invalid entry */ ASSERT(Entry < (PciHackTable + HackCount + 1)); Entry->VendorID = PCI_INVALID_VENDORID; /* Success path, free the temporary registry data */ ExFreePoolWithTag(ValueInfo, 0); return STATUS_SUCCESS; } while (TRUE); /* Failure path, free temporary allocations and return failure code */ ASSERT(!NT_SUCCESS(Status)); if (FullInfo) ExFreePool(FullInfo); if (ValueInfo) ExFreePool(ValueInfo); if (PciHackTable) ExFreePool(PciHackTable); return Status; }
NTSTATUS SampRegEnumerateValue(IN HANDLE KeyHandle, IN ULONG Index, OUT LPWSTR Name, IN OUT PULONG NameLength, OUT PULONG Type OPTIONAL, OUT PVOID Data OPTIONAL, IN OUT PULONG DataLength OPTIONAL) { PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL; ULONG BufferLength = 0; ULONG ReturnedLength; NTSTATUS Status; TRACE("Index: %lu\n", Index); /* Calculate the required buffer length */ BufferLength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name); BufferLength += (MAX_PATH + 1) * sizeof(WCHAR); if (Data != NULL) BufferLength += *DataLength; /* Allocate the value buffer */ ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength); if (ValueInfo == NULL) return STATUS_NO_MEMORY; /* Enumerate the value*/ Status = ZwEnumerateValueKey(KeyHandle, Index, KeyValueFullInformation, ValueInfo, BufferLength, &ReturnedLength); if (NT_SUCCESS(Status)) { if (Name != NULL) { /* Check if the name fits */ if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR))) { /* Copy it */ RtlMoveMemory(Name, ValueInfo->Name, ValueInfo->NameLength); /* Terminate the string */ Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0; } else { /* Otherwise, we ran out of buffer space */ Status = STATUS_BUFFER_OVERFLOW; goto done; } } if (Data != NULL) { /* Check if the data fits */ if (ValueInfo->DataLength <= *DataLength) { /* Copy it */ RtlMoveMemory(Data, (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset), ValueInfo->DataLength); /* if the type is REG_SZ and data is not 0-terminated * and there is enough space in the buffer NT appends a \0 */ if (IsStringType(ValueInfo->Type) && ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)) { WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength); if ((ptr > (WCHAR *)Data) && ptr[-1]) *ptr = 0; } } else { Status = STATUS_BUFFER_OVERFLOW; goto done; } } } done: if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW)) { if (Type != NULL) *Type = ValueInfo->Type; if (NameLength != NULL) *NameLength = ValueInfo->NameLength; if (DataLength != NULL) *DataLength = ValueInfo->DataLength; } /* Free the buffer and return status */ if (ValueInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo); return Status; }
NTSTATUS NTAPI IopDetectResourceConflict( IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; HANDLE ResourceMapKey = INVALID_HANDLE_VALUE, ChildKey2 = INVALID_HANDLE_VALUE, ChildKey3 = INVALID_HANDLE_VALUE; ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength; PKEY_BASIC_INFORMATION KeyInformation; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; PKEY_VALUE_BASIC_INFORMATION KeyNameInformation; ULONG ChildKeyIndex1 = 0, ChildKeyIndex2 = 0, ChildKeyIndex3 = 0; NTSTATUS Status; RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL); Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* The key is missing which means we are the first device */ return STATUS_SUCCESS; } while (TRUE) { Status = ZwEnumerateKey(ResourceMapKey, ChildKeyIndex1, KeyBasicInformation, NULL, 0, &RequiredLength); if (Status == STATUS_NO_MORE_ENTRIES) break; else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { KeyInformationLength = RequiredLength; KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength); if (!KeyInformation) { Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } Status = ZwEnumerateKey(ResourceMapKey, ChildKeyIndex1, KeyBasicInformation, KeyInformation, KeyInformationLength, &RequiredLength); } else goto cleanup; ChildKeyIndex1++; if (!NT_SUCCESS(Status)) goto cleanup; KeyName.Buffer = KeyInformation->Name; KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength; InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, ResourceMapKey, NULL); Status = ZwOpenKey(&ChildKey2, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes); ExFreePool(KeyInformation); if (!NT_SUCCESS(Status)) goto cleanup; while (TRUE) { Status = ZwEnumerateKey(ChildKey2, ChildKeyIndex2, KeyBasicInformation, NULL, 0, &RequiredLength); if (Status == STATUS_NO_MORE_ENTRIES) break; else if (Status == STATUS_BUFFER_TOO_SMALL) { KeyInformationLength = RequiredLength; KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength); if (!KeyInformation) { Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } Status = ZwEnumerateKey(ChildKey2, ChildKeyIndex2, KeyBasicInformation, KeyInformation, KeyInformationLength, &RequiredLength); } else goto cleanup; ChildKeyIndex2++; if (!NT_SUCCESS(Status)) goto cleanup; KeyName.Buffer = KeyInformation->Name; KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength; InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, ChildKey2, NULL); Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes); ExFreePool(KeyInformation); if (!NT_SUCCESS(Status)) goto cleanup; while (TRUE) { Status = ZwEnumerateValueKey(ChildKey3, ChildKeyIndex3, KeyValuePartialInformation, NULL, 0, &RequiredLength); if (Status == STATUS_NO_MORE_ENTRIES) break; else if (Status == STATUS_BUFFER_TOO_SMALL) { KeyValueInformationLength = RequiredLength; KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength); if (!KeyValueInformation) { Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } Status = ZwEnumerateValueKey(ChildKey3, ChildKeyIndex3, KeyValuePartialInformation, KeyValueInformation, KeyValueInformationLength, &RequiredLength); } else goto cleanup; if (!NT_SUCCESS(Status)) goto cleanup; Status = ZwEnumerateValueKey(ChildKey3, ChildKeyIndex3, KeyValueBasicInformation, NULL, 0, &RequiredLength); if (Status == STATUS_BUFFER_TOO_SMALL) { KeyNameInformationLength = RequiredLength; KeyNameInformation = ExAllocatePool(PagedPool, KeyNameInformationLength + sizeof(WCHAR)); if (!KeyNameInformation) { Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } Status = ZwEnumerateValueKey(ChildKey3, ChildKeyIndex3, KeyValueBasicInformation, KeyNameInformation, KeyNameInformationLength, &RequiredLength); } else goto cleanup; ChildKeyIndex3++; if (!NT_SUCCESS(Status)) goto cleanup; KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL; /* Skip translated entries */ if (wcsstr(KeyNameInformation->Name, L".Translated")) { ExFreePool(KeyNameInformation); continue; } ExFreePool(KeyNameInformation); if (IopCheckForResourceConflict(ResourceList, (PCM_RESOURCE_LIST)KeyValueInformation->Data, Silent, ConflictingDescriptor)) { ExFreePool(KeyValueInformation); Status = STATUS_CONFLICTING_ADDRESSES; goto cleanup; } ExFreePool(KeyValueInformation); } } } cleanup: if (ResourceMapKey != INVALID_HANDLE_VALUE) ZwClose(ResourceMapKey); if (ChildKey2 != INVALID_HANDLE_VALUE) ZwClose(ChildKey2); if (ChildKey3 != INVALID_HANDLE_VALUE) ZwClose(ChildKey3); if (Status == STATUS_NO_MORE_ENTRIES) Status = STATUS_SUCCESS; return Status; }
/////////////////////////////////////////////////////////////////////////////////////////////////// // testdrvRegEnumerateValueKeys // Enumerates and print names of sub value keys using a given registry key handle. // // Arguments: // IN RegKeyHandle // Handle to root key // // Return Value: // none // VOID testdrvRegEnumerateValueKeys( IN HANDLE RegKeyHandle ) { NTSTATUS status; ULONG index; PKEY_VALUE_BASIC_INFORMATION regBuffer; PWCHAR nameBuffer; ULONG length; status = STATUS_SUCCESS; index = 0; regBuffer = NULL; nameBuffer = NULL; while (status != STATUS_NO_MORE_ENTRIES) { // Get the buffer size necessary status = ZwEnumerateValueKey( RegKeyHandle, index, KeyValueBasicInformation, NULL, 0, &length ); if ((status != STATUS_BUFFER_TOO_SMALL) && (status != STATUS_BUFFER_OVERFLOW)) { if (status != STATUS_NO_MORE_ENTRIES) { testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey failed %x", status); } else { testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": Enumerated %d value keys", index); } break; } regBuffer = (PKEY_VALUE_BASIC_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, length, TESTDRV_POOL_TAG); if (regBuffer == NULL) { continue; } // Now actually attempt to get subkey info status = ZwEnumerateValueKey( RegKeyHandle, index, KeyValueBasicInformation, regBuffer, length, &length ); if (!NT_SUCCESS(status)) { testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey failed %x", status); // Free our temporary storage ExFreePool(regBuffer); continue; } // Allocate a buffer for the display name nameBuffer = (PWCHAR)ExAllocatePoolWithTag( PagedPool, regBuffer->NameLength + sizeof(WCHAR), TESTDRV_POOL_TAG ); if (nameBuffer == NULL) { // Free our temporary storage ExFreePool(regBuffer); continue; } // NULL terminate the string RtlZeroMemory(nameBuffer, regBuffer->NameLength + sizeof(WCHAR)); // Copy the name over RtlCopyMemory(nameBuffer, regBuffer->Name, regBuffer->NameLength); testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey returned %S", nameBuffer); // Free both buffers ExFreePool(regBuffer); ExFreePool(nameBuffer); // Increment our index ++index; } return; }
NTSTATUS NdasPortFdoRegEnumerateLogicalUnits( __in PNDASPORT_FDO_EXTENSION FdoExtension, __in PNDASPORT_ENUMERATE_LOGICALUNIT_CALLBACK Callback, __in PVOID CallbackContext) { NTSTATUS status, status2; HANDLE keyHandle; PKEY_VALUE_FULL_INFORMATION keyValueInformation; ULONG keyValueInformationLength; ULONG resultLength; ULONG index; PNDAS_LOGICALUNIT_DESCRIPTOR descriptor; PAGED_CODE(); keyHandle = NULL; status = NdasPortFdoOpenRegistryKey( FdoExtension, NDASPORT_FDO_REGKEY_LOGICALUNIT_LIST, KEY_READ, &keyHandle); if (!NT_SUCCESS(status)) { NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR, "IoOpenDeviceRegistryKey failed, status=%X, fdo=%p\n", status, FdoExtension->DeviceObject); return status; } keyValueInformation = NULL; keyValueInformationLength = 0; for (index = 0; ;) { status = ZwEnumerateValueKey( keyHandle, index, KeyValueFullInformation, keyValueInformation, keyValueInformationLength, &resultLength); if (NT_SUCCESS(status)) { // // value prefix must be LU // ASSERT(NULL != keyValueInformation); if (keyValueInformation->NameLength < 4 || !RtlEqualMemory(keyValueInformation->Name, L"LU", 4)) { NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING, "Value is not prefixed with LU, value=%ws\n", keyValueInformation->NameLength ? keyValueInformation->Name : L"(default)"); // ignore the invalid key values ++index; continue; } // // It should contain valid logical unit descriptor // if (keyValueInformation->DataLength < sizeof(NDAS_LOGICALUNIT_DESCRIPTOR)) { NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING, "Data is not a valid descriptor, DataLength=0x%X\n", keyValueInformation->DataLength); // ignore the invalid key values ++index; continue; } descriptor = (PNDAS_LOGICALUNIT_DESCRIPTOR) NdasPortOffsetOf( keyValueInformation, keyValueInformation->DataOffset); // // Descriptor version should be the size of the structure // if (sizeof(NDAS_LOGICALUNIT_DESCRIPTOR) != descriptor->Version) { NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING, "Data is not a valid descriptor, descriptor->Version=0x%X\n", descriptor->Version); // ignore the invalid key values ++index; continue; } // // DataLength should be larger than the size specified in // the descriptor // if (keyValueInformation->DataLength < descriptor->Size) { NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING, "Data is not a valid descriptor, " "DataLength is less than the size in the descriptor " "descriptor->Size=0x%X, dataLength=0x%X\n", descriptor->Size, keyValueInformation->DataLength); // ignore the invalid key values ++index; continue; } // // Now we get the valid logical unit descriptor // Invoke the callback function // (*Callback)(FdoExtension, descriptor, CallbackContext); // // Next entry // ++index; continue; } else if (STATUS_NO_MORE_ENTRIES == status) { // // STATUS_NO_MORE_ENTRIES means success for this function // status = STATUS_SUCCESS; break; } else if (STATUS_BUFFER_OVERFLOW == status || STATUS_BUFFER_TOO_SMALL == status) { if (NULL != keyValueInformation) { ExFreePoolWithTag( keyValueInformation, NDASPORT_TAG_REGISTRY_ENUM); } keyValueInformation = ExAllocatePoolWithTag( PagedPool, resultLength, NDASPORT_TAG_REGISTRY_ENUM); if (NULL == keyValueInformation) { status2 = ZwClose(keyHandle); ASSERT(NT_SUCCESS(status2)); status = STATUS_NO_MEMORY; break; } keyValueInformationLength = resultLength; // // try again with the same index // continue; } else { // // retain the status value and return the status code // break; } } if (NULL != keyValueInformation) { ExFreePoolWithTag( keyValueInformation, NDASPORT_TAG_REGISTRY_ENUM); } status2 = ZwClose(keyHandle); ASSERT(NT_SUCCESS(status2)); if (!NT_SUCCESS(status2)) { NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING, "ZwClose failed, keyHandle=%p, status=%X\n", keyHandle, status2); } return status; }
PPCI_REGISTRY_INFO_INTERNAL NTAPI INIT_FUNCTION HalpQueryPciRegistryInfo(VOID) { #ifndef _MINIHAL_ WCHAR NameBuffer[8]; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName, ConfigName, IdentName; HANDLE KeyHandle, BusKeyHandle, CardListHandle; NTSTATUS Status; UCHAR KeyBuffer[sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + 100]; PKEY_VALUE_FULL_INFORMATION ValueInfo = (PVOID)KeyBuffer; UCHAR PartialKeyBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(PCI_CARD_DESCRIPTOR)]; PKEY_VALUE_PARTIAL_INFORMATION PartialValueInfo = (PVOID)PartialKeyBuffer; KEY_FULL_INFORMATION KeyInformation; ULONG ResultLength; PWSTR Tag; ULONG i, ElementCount; PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor; PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; PPCI_REGISTRY_INFO PciRegInfo; PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo; PPCI_CARD_DESCRIPTOR CardDescriptor; /* Setup the object attributes for the key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Hardware\\Description\\" L"System\\MultiFunctionAdapter"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); /* Open the key */ Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) return NULL; /* Setup the receiving string */ KeyName.Buffer = NameBuffer; KeyName.MaximumLength = sizeof(NameBuffer); /* Setup the configuration and identifier key names */ RtlInitUnicodeString(&ConfigName, L"Configuration Data"); RtlInitUnicodeString(&IdentName, L"Identifier"); /* Keep looping for each ID */ for (i = 0; TRUE; i++) { /* Setup the key name */ RtlIntegerToUnicodeString(i, 10, &KeyName); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, KeyHandle, NULL); /* Open it */ Status = ZwOpenKey(&BusKeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* None left, fail */ ZwClose(KeyHandle); return NULL; } /* Read the registry data */ Status = ZwQueryValueKey(BusKeyHandle, &IdentName, KeyValueFullInformation, ValueInfo, sizeof(KeyBuffer), &ResultLength); if (!NT_SUCCESS(Status)) { /* Failed, try the next one */ ZwClose(BusKeyHandle); continue; } /* Get the PCI Tag and validate it */ Tag = (PWSTR)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset); if ((Tag[0] != L'P') || (Tag[1] != L'C') || (Tag[2] != L'I') || (Tag[3])) { /* Not a valid PCI entry, skip it */ ZwClose(BusKeyHandle); continue; } /* Now read our PCI structure */ Status = ZwQueryValueKey(BusKeyHandle, &ConfigName, KeyValueFullInformation, ValueInfo, sizeof(KeyBuffer), &ResultLength); ZwClose(BusKeyHandle); if (!NT_SUCCESS(Status)) continue; /* We read it OK! Get the actual resource descriptors */ FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) ((ULONG_PTR)ValueInfo + ValueInfo->DataOffset); PartialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((ULONG_PTR)FullDescriptor-> PartialResourceList.PartialDescriptors); /* Check if this is our PCI Registry Information */ if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific) { /* It is, stop searching */ break; } } /* Close the key */ ZwClose(KeyHandle); /* Save the PCI information for later */ PciRegInfo = (PPCI_REGISTRY_INFO)(PartialDescriptor + 1); /* Assume no Card List entries */ ElementCount = 0; /* Set up for checking the PCI Card List key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\" L"Control\\PnP\\PCI\\CardList"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); /* Attempt to open it */ Status = ZwOpenKey(&CardListHandle, KEY_READ, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* It exists, so let's query it */ Status = ZwQueryKey(CardListHandle, KeyFullInformation, &KeyInformation, sizeof(KEY_FULL_INFORMATION), &ResultLength); if (!NT_SUCCESS(Status)) { /* Failed to query, so no info */ PciRegistryInfo = NULL; } else { /* Allocate the full structure */ PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_REGISTRY_INFO_INTERNAL) + (KeyInformation.Values * sizeof(PCI_CARD_DESCRIPTOR)), TAG_HAL); if (PciRegistryInfo) { /* Get the first card descriptor entry */ CardDescriptor = (PPCI_CARD_DESCRIPTOR)(PciRegistryInfo + 1); /* Loop all the values */ for (i = 0; i < KeyInformation.Values; i++) { /* Attempt to get the value */ Status = ZwEnumerateValueKey(CardListHandle, i, KeyValuePartialInformation, PartialValueInfo, sizeof(PartialKeyBuffer), &ResultLength); if (!NT_SUCCESS(Status)) { /* Something went wrong, stop the search */ break; } /* Make sure it is correctly sized */ if (PartialValueInfo->DataLength == sizeof(PCI_CARD_DESCRIPTOR)) { /* Sure is, copy it over */ *CardDescriptor = *(PPCI_CARD_DESCRIPTOR) PartialValueInfo->Data; /* One more Card List entry */ ElementCount++; /* Move to the next descriptor */ CardDescriptor = (CardDescriptor + 1); } } } } /* Close the Card List key */ ZwClose(CardListHandle); } else { /* No key, no Card List */ PciRegistryInfo = NULL; } /* Check if we failed to get the full structure */ if (!PciRegistryInfo) { /* Just allocate the basic structure then */ PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_REGISTRY_INFO_INTERNAL), TAG_HAL); if (!PciRegistryInfo) return NULL; } /* Save the info we got */ PciRegistryInfo->MajorRevision = PciRegInfo->MajorRevision; PciRegistryInfo->MinorRevision = PciRegInfo->MinorRevision; PciRegistryInfo->NoBuses = PciRegInfo->NoBuses; PciRegistryInfo->HardwareMechanism = PciRegInfo->HardwareMechanism; PciRegistryInfo->ElementCount = ElementCount; /* Return it */ return PciRegistryInfo; #else return NULL; #endif }
BOOLEAN QueryServiceRunType( PUNICODE_STRING pSrvName, PSERVICES_INFO pServicesInfo ) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE HandleRegKey = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; ULONG SubItemIndex, SubItemCount, ulSize, ulItemValue; UNICODE_STRING usItemName, usItemValue; PKEY_VALUE_FULL_INFORMATION pKeyFullValueInfo = NULL; PKEY_FULL_INFORMATION pKeyFullInfo = NULL; BOOLEAN bRet = FALSE; /************************************************************************/ /* ServiceType 服务类型:0×10为独立进程服务,0×20为共享进程服务(比如svchost); StartType 启动类型:0 系统引导时加载,1 OS初始化时加载,2 由SCM(服务控制管理器)自动启动,3 手动启动,4 禁用。(注意,0和1只能用于驱动程序) ErrorControl 错误控制:0 忽略,1 继续并警告,2 切换到LastKnownGood的设置,3 蓝屏。 ServiceBinary 服务程序位置:%11%表示system32目录,%10%表示系统目录(WINNT或Windows),%12%为驱动目录system32\drivers。也可以不用变量,直接使用全路径。 服务名MentoHUST后面有两个逗号,因为中间省略了一个不常用的参数flags。 Description、ServiceType、StartType、ErrorControl四项是必须要有的,还有LoadOrderGroup、Dependencies等就不做详述了。 */ /************************************************************************/ __try { InitializeObjectAttributes(&ObjectAttributes, pSrvName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, // handle NULL); status = ZwOpenKey(&HandleRegKey, KEY_READ, &ObjectAttributes); // 第一次调用是为了获取需要的长度 ZwQueryKey(HandleRegKey, KeyFullInformation, NULL, 0, &ulSize); pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize); // 第二次调用是为了获取数据 ZwQueryKey(HandleRegKey, KeyFullInformation, pKeyFullInfo, ulSize, &ulSize); SubItemCount = pKeyFullInfo->Values; //循环遍历各个子项 for (SubItemIndex = 0; SubItemIndex < SubItemCount; SubItemIndex++) { //_asm int 3 ZwEnumerateValueKey(HandleRegKey, SubItemIndex, KeyValueFullInformation, NULL, 0, &ulSize); pKeyFullValueInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize); //获取第I个子项的数据 status = ZwEnumerateValueKey(HandleRegKey, SubItemIndex, KeyValueFullInformation, pKeyFullValueInfo, ulSize, &ulSize); if (status == STATUS_SUCCESS) { usItemName.Length = usItemName.MaximumLength = (USHORT)pKeyFullValueInfo->NameLength; usItemName.Buffer = pKeyFullValueInfo->Name; usItemValue.Length = usItemValue.MaximumLength = (USHORT)pKeyFullValueInfo->DataLength; usItemValue.Buffer = (PWCHAR)((PUCHAR)pKeyFullValueInfo + pKeyFullValueInfo->DataOffset); if (RtlCompareMemory(usItemName.Buffer, L"Type", usItemName.Length)) { ulItemValue = *(PULONG)usItemValue.Buffer; //RtlUnicodeStringToInteger(&usItemValue, 16, &ulItemValue); if (0x10 != ulItemValue && 0x20 != ulItemValue && 0x110 != ulItemValue && 0x120 != ulItemValue) { bRet = FALSE; break; } else { bRet = TRUE; //_asm int 3 } } else if (RtlCompareMemory(usItemName.Buffer, L"DisplayName", usItemName.Length) == usItemName.Length) { RtlCopyMemory(pServicesInfo->lpwzSrvName, usItemValue.Buffer, usItemValue.Length); } else if (RtlCompareMemory(usItemName.Buffer, L"ImagePath", usItemName.Length) == usItemName.Length) { RtlCopyMemory(pServicesInfo->lpwzImageName, usItemValue.Buffer, usItemValue.Length); } else if (RtlCompareMemory(usItemName.Buffer, L"Description", usItemName.Length) == usItemName.Length) { RtlCopyMemory(pServicesInfo->lpwzDescription, usItemValue.Buffer, usItemValue.Length); } else if (RtlCompareMemory(usItemName.Buffer, L"Start", usItemName.Length) == usItemName.Length) { ulItemValue = *(PULONG)usItemValue.Buffer; switch(ulItemValue) { case(SERVICE_AUTO_START): RtlCopyMemory(pServicesInfo->lpwzBootType, L"自动", sizeof(L"自动")); break; case(SERVICE_BOOT_START): RtlCopyMemory(pServicesInfo->lpwzBootType, L"引导", sizeof(L"引导")); break; case(SERVICE_DEMAND_START): RtlCopyMemory(pServicesInfo->lpwzBootType, L"手动", sizeof(L"手动")); break; case(SERVICE_DISABLED): RtlCopyMemory(pServicesInfo->lpwzBootType, L"已禁用", sizeof(L"已禁用")); break; case(SERVICE_SYSTEM_START): RtlCopyMemory(pServicesInfo->lpwzBootType, L"系统", sizeof(L"系统")); break; default: RtlCopyMemory(pServicesInfo->lpwzBootType, L"未知", sizeof(L"未知")); break; } } if (pKeyFullValueInfo->Type == REG_SZ) { KdPrint(("The sub value type:REG_SZ\n")); } else if (pKeyFullValueInfo->Type == REG_EXPAND_SZ) { KdPrint(("The sub value type:REG_EXPAND_SZ\n")); } else if (pKeyFullValueInfo->Type == REG_DWORD) { KdPrint(("The sub value type:REG_DWORD\n")); } else if (pKeyFullValueInfo->Type == REG_BINARY) { KdPrint(("The sub value type:REG_BINARY\n")); } } if (NULL != pKeyFullValueInfo) { ExFreePool(pKeyFullValueInfo); pKeyFullValueInfo = NULL; } } } __except(EXCEPTION_EXECUTE_HANDLER) { bRet = FALSE; } if (NULL != pKeyFullInfo) { ExFreePool(pKeyFullInfo); pKeyFullInfo = NULL; } if (NULL != pKeyFullValueInfo) { ExFreePool(pKeyFullValueInfo); pKeyFullValueInfo = NULL; } return bRet; }