reg.c

来自「一个类似windows」· C语言 代码 · 共 2,371 行 · 第 1/5 页

C
2,371
字号
	break;
    }

  RtlFreeUnicodeString (&LocalKeyName);

  return Status;
}


/************************************************************************
 *  RegCreateKeyExA
 *
 * @implemented
 */
LONG STDCALL
RegCreateKeyExA (HKEY hKey,
		 LPCSTR lpSubKey,
		 DWORD Reserved,
		 LPSTR lpClass,
		 DWORD dwOptions,
		 REGSAM samDesired,
		 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
		 PHKEY phkResult,
		 LPDWORD lpdwDisposition)
{
  UNICODE_STRING SubKeyString;
  UNICODE_STRING ClassString;
  OBJECT_ATTRIBUTES Attributes;
  HANDLE ParentKey;
  NTSTATUS Status;

  TRACE("RegCreateKeyExA() called\n");

  /* get the real parent key */
  Status = MapDefaultKey (&ParentKey,
                          hKey);
  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError (Status);
    }
  TRACE("ParentKey %x\n", (ULONG)ParentKey);

  if (lpClass != NULL)
    {
      RtlCreateUnicodeStringFromAsciiz (&ClassString,
					lpClass);
    }

  RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
				   (LPSTR)lpSubKey);
  InitializeObjectAttributes (&Attributes,
			      &SubKeyString,
			      OBJ_CASE_INSENSITIVE,
			      (HANDLE)ParentKey,
			      (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
  Status = CreateNestedKey(phkResult,
			   &Attributes,
			   (lpClass == NULL)? NULL : &ClassString,
			   dwOptions,
			   samDesired,
			   lpdwDisposition);
  RtlFreeUnicodeString (&SubKeyString);
  if (lpClass != NULL)
    {
      RtlFreeUnicodeString (&ClassString);
    }

  ClosePredefKey(ParentKey);

  TRACE("Status %x\n", Status);
  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError (Status);
    }

  return ERROR_SUCCESS;
}


/************************************************************************
 *  RegCreateKeyExW
 *
 * @implemented
 */
LONG STDCALL
RegCreateKeyExW (HKEY hKey,
		 LPCWSTR lpSubKey,
		 DWORD Reserved,
		 LPWSTR lpClass,
		 DWORD dwOptions,
		 REGSAM samDesired,
		 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
		 PHKEY phkResult,
		 LPDWORD lpdwDisposition)
{
  UNICODE_STRING SubKeyString;
  UNICODE_STRING ClassString;
  OBJECT_ATTRIBUTES Attributes;
  HANDLE ParentKey;
  NTSTATUS Status;

  TRACE("RegCreateKeyExW() called\n");

  /* get the real parent key */
  Status = MapDefaultKey (&ParentKey,
                          hKey);
  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError(Status);
    }
  TRACE("ParentKey %x\n", (ULONG)ParentKey);

  RtlInitUnicodeString (&ClassString,
			lpClass);
  RtlInitUnicodeString (&SubKeyString,
			lpSubKey);
  InitializeObjectAttributes (&Attributes,
			      &SubKeyString,
			      OBJ_CASE_INSENSITIVE,
			      (HANDLE)ParentKey,
			      (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
  Status = CreateNestedKey(phkResult,
		           &Attributes,
                           (lpClass == NULL)? NULL : &ClassString,
                           dwOptions,
                           samDesired,
                           lpdwDisposition);

  ClosePredefKey(ParentKey);

  TRACE("Status %x\n", Status);
  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError (Status);
    }

  return ERROR_SUCCESS;
}


/************************************************************************
 *  RegCreateKeyA
 *
 * @implemented
 */
LONG STDCALL
RegCreateKeyA (HKEY hKey,
	       LPCSTR lpSubKey,
	       PHKEY phkResult)
{
  return RegCreateKeyExA (hKey,
			  lpSubKey,
			  0,
			  NULL,
			  0,
			  MAXIMUM_ALLOWED,
			  NULL,
			  phkResult,
			  NULL);
}


/************************************************************************
 *  RegCreateKeyW
 *
 * @implemented
 */
LONG STDCALL
RegCreateKeyW (HKEY hKey,
	       LPCWSTR lpSubKey,
	       PHKEY phkResult)
{
  return RegCreateKeyExW (hKey,
			  lpSubKey,
			  0,
			  NULL,
			  0,
			  MAXIMUM_ALLOWED,
			  NULL,
			  phkResult,
			  NULL);
}


/************************************************************************
 *  RegDeleteKeyA
 *
 * @implemented
 */
LONG STDCALL
RegDeleteKeyA (HKEY hKey,
	       LPCSTR lpSubKey)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  UNICODE_STRING SubKeyName;
  HANDLE ParentKey;
  HANDLE TargetKey;
  NTSTATUS Status;

  Status = MapDefaultKey (&ParentKey,
                          hKey);
  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError (Status);
    }

  RtlCreateUnicodeStringFromAsciiz (&SubKeyName,
				    (LPSTR)lpSubKey);
  InitializeObjectAttributes(&ObjectAttributes,
			     &SubKeyName,
			     OBJ_CASE_INSENSITIVE,
			     ParentKey,
			     NULL);

  Status = NtOpenKey (&TargetKey,
		      DELETE,
		      &ObjectAttributes);
  RtlFreeUnicodeString (&SubKeyName);
  if (!NT_SUCCESS(Status))
    {
      goto Cleanup;
    }

  Status = NtDeleteKey (TargetKey);
  NtClose (TargetKey);
  
Cleanup:
  ClosePredefKey(ParentKey);

  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError(Status);
    }

  return ERROR_SUCCESS;
}


/************************************************************************
 *  RegDeleteKeyW
 *
 * @implemented
 */
LONG STDCALL
RegDeleteKeyW (HKEY hKey,
	       LPCWSTR lpSubKey)
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  UNICODE_STRING SubKeyName;
  HANDLE ParentKey;
  HANDLE TargetKey;
  NTSTATUS Status;

  Status = MapDefaultKey (&ParentKey,
                          hKey);
  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError (Status);
    }

  RtlInitUnicodeString (&SubKeyName,
			(LPWSTR)lpSubKey);
  InitializeObjectAttributes (&ObjectAttributes,
			      &SubKeyName,
			      OBJ_CASE_INSENSITIVE,
			      ParentKey,
			      NULL);
  Status = NtOpenKey (&TargetKey,
		      DELETE,
		      &ObjectAttributes);
  if (!NT_SUCCESS(Status))
    {
      goto Cleanup;
    }

  Status = NtDeleteKey (TargetKey);
  NtClose (TargetKey);
  
Cleanup:
  ClosePredefKey(ParentKey);

  if (!NT_SUCCESS(Status))
    {
      return RtlNtStatusToDosError (Status);
    }

  return ERROR_SUCCESS;
}


/************************************************************************
 *  RegDeleteKeyValueW
 *
 * @implemented
 */
LONG STDCALL
RegDeleteKeyValueW(IN HKEY hKey,
                   IN LPCWSTR lpSubKey  OPTIONAL,
                   IN LPCWSTR lpValueName  OPTIONAL)
{
    UNICODE_STRING ValueName;
    HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
    NTSTATUS Status;

    Status = MapDefaultKey(&KeyHandle,
                           hKey);
    if (!NT_SUCCESS(Status))
    {
        return RtlNtStatusToDosError(Status);
    }

    if (lpSubKey != NULL)
    {
        OBJECT_ATTRIBUTES ObjectAttributes;
        UNICODE_STRING SubKeyName;

        RtlInitUnicodeString(&SubKeyName,
                             (LPWSTR)lpSubKey);

        InitializeObjectAttributes(&ObjectAttributes,
                                   &SubKeyName,
                                   OBJ_CASE_INSENSITIVE,
                                   KeyHandle,
                                   NULL);

        Status = NtOpenKey(&SubKeyHandle,
                           KEY_SET_VALUE,
                           &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            goto Cleanup;
        }
        
        CurKey = SubKeyHandle;
    }
    else
        CurKey = KeyHandle;

    RtlInitUnicodeString(&ValueName,
                         (LPWSTR)lpValueName);

    Status = NtDeleteValueKey(CurKey,
                              &ValueName);

    if (SubKeyHandle != NULL)
    {
        NtClose(SubKeyHandle);
    }
    
Cleanup:
    ClosePredefKey(KeyHandle);

    if (!NT_SUCCESS(Status))
    {
        return RtlNtStatusToDosError(Status);
    }

    return ERROR_SUCCESS;
}


/************************************************************************
 *  RegDeleteKeyValueA
 *
 * @implemented
 */
LONG STDCALL
RegDeleteKeyValueA(IN HKEY hKey,
                   IN LPCSTR lpSubKey  OPTIONAL,
                   IN LPCSTR lpValueName  OPTIONAL)
{
    UNICODE_STRING SubKey = {0}, ValueName = {0};
    LONG Ret;
    
    if (lpSubKey != NULL &&
        !RtlCreateUnicodeStringFromAsciiz(&SubKey,
                                          (LPSTR)lpSubKey))
    {
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    if (lpValueName != NULL &&
        !RtlCreateUnicodeStringFromAsciiz(&ValueName,
                                          (LPSTR)lpValueName))
    {
        RtlFreeUnicodeString(&SubKey);
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    Ret = RegDeleteKeyValueW(hKey,
                             SubKey.Buffer,
                             SubKey.Buffer);

    RtlFreeUnicodeString(&SubKey);
    RtlFreeUnicodeString(&ValueName);
    
    return Ret;
}


static NTSTATUS
RegpDeleteTree(IN HKEY hKey)
{
    typedef struct
    {
        LIST_ENTRY ListEntry;
        HANDLE KeyHandle;
    } REGP_DEL_KEYS, *PREG_DEL_KEYS;

    LIST_ENTRY delQueueHead;
    PREG_DEL_KEYS delKeys, newDelKeys;
    HANDLE ProcessHeap;
    ULONG BufferSize;
    PKEY_BASIC_INFORMATION BasicInfo;
    PREG_DEL_KEYS KeyDelRoot;
    NTSTATUS Status = STATUS_SUCCESS;
    NTSTATUS Status2 = STATUS_SUCCESS;
    
    InitializeListHead(&delQueueHead);
    
    ProcessHeap = RtlGetProcessHeap();
    
    /* NOTE: no need to allocate enough memory for an additional KEY_BASIC_INFORMATION
             structure for the root key, we only do that for subkeys as we need to
             allocate REGP_DEL_KEYS structures anyway! */
    KeyDelRoot = RtlAllocateHeap(ProcessHeap,
                                 0,
                                 sizeof(REGP_DEL_KEYS));
    if (KeyDelRoot != NULL)
    {
        KeyDelRoot->KeyHandle = hKey;
        InsertTailList(&delQueueHead,
                       &KeyDelRoot->ListEntry);

        do
        {
            delKeys = CONTAINING_RECORD(delQueueHead.Flink,
                                        REGP_DEL_KEYS,
                                        ListEntry);

            BufferSize = 0;
            BasicInfo = NULL;
            newDelKeys = NULL;

ReadFirstSubKey:
            /* check if this key contains subkeys and delete them first by queuing
               them at the head of the list */
            Status2 = NtEnumerateKey(delKeys->KeyHandle,
                                     0,
                                     KeyBasicInformation,
                                     BasicInfo,
                                     BufferSize,
                                     &BufferSize);

            if (NT_SUCCESS(Status2))
            {
                OBJECT_ATTRIBUTES ObjectAttributes;
                UNICODE_STRING SubKeyName;
                
                ASSERT(newDelKeys != NULL);
                ASSERT(BasicInfo != NULL);

                /* don't use RtlInitUnicodeString as the string is not NULL-terminated! */
                SubKeyName.Length = BasicInfo->NameLength;
                SubKeyName.MaximumLength = BasicInfo->NameLength;
                SubKeyName.Buffer = BasicInfo->Name;

                InitializeObjectAttributes(&ObjectAttributes,
                                           &SubKeyName,
                                           OBJ_CASE_INSENSITIVE,
                                           delKeys->KeyHandle,
                                           NULL);

                /* open the subkey */
                Status2 = NtOpenKey(&newDelKeys->KeyHandle,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?