Home | Info | Community | Development | myReactOS | Contact Us
[static]
Definition at line 73 of file move.c.
Referenced by MoveFileWithProgressW().
{ static const WCHAR ValueName[] = {'P','e','n','d','i','n','g', 'F','i','l','e','R','e','n','a','m','e', 'O','p','e','r','a','t','i','o','n','s',0}; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager"); static const int info_size = FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data ); OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING nameW, source_name, dest_name; KEY_VALUE_PARTIAL_INFORMATION *info; BOOL rc = FALSE; HANDLE Reboot = NULL; DWORD len1, len2; DWORD DestLen = 0; DWORD DataSize = 0; BYTE *Buffer = NULL; WCHAR *p; NTSTATUS Status; TRACE("add_boot_rename_entry( %S, %S, %d ) \n", source, dest, flags); if(dest) DestLen = wcslen(dest); if (!RtlDosPathNameToNtPathName_U( source, &source_name, NULL, NULL )) { SetLastError( ERROR_PATH_NOT_FOUND ); return FALSE; } dest_name.Buffer = NULL; if (DestLen && !RtlDosPathNameToNtPathName_U( dest, &dest_name, NULL, NULL )) { RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); SetLastError( ERROR_PATH_NOT_FOUND ); return FALSE; } InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateKey(&Reboot, KEY_QUERY_VALUE | KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); if (Status == STATUS_ACCESS_DENIED) { Status = NtCreateKey( &Reboot, KEY_QUERY_VALUE | KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_BACKUP_RESTORE, NULL); } if (!NT_SUCCESS(Status)) { WARN("NtCreateKey() failed (Status 0x%lx)\n", Status); if (source_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); if (dest_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); return FALSE; } len1 = source_name.Length + sizeof(WCHAR); if (DestLen) { len2 = dest_name.Length + sizeof(WCHAR); if (flags & MOVEFILE_REPLACE_EXISTING) len2 += sizeof(WCHAR); /* Plus 1 because of the leading '!' */ } else { len2 = sizeof(WCHAR); /* minimum is the 0 characters for the empty second string */ } RtlInitUnicodeString( &nameW, ValueName ); /* First we check if the key exists and if so how many bytes it already contains. */ Status = NtQueryValueKey( Reboot, &nameW, KeyValuePartialInformation, NULL, 0, &DataSize ); if ((Status == STATUS_BUFFER_OVERFLOW) || (Status == STATUS_BUFFER_TOO_SMALL)) { if (!(Buffer = HeapAlloc(GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR)))) goto Quit; Status = NtQueryValueKey(Reboot, &nameW, KeyValuePartialInformation, Buffer, DataSize, &DataSize); if(!NT_SUCCESS(Status)) goto Quit; info = (KEY_VALUE_PARTIAL_INFORMATION *)Buffer; if (info->Type != REG_MULTI_SZ) goto Quit; if (DataSize > sizeof(info)) DataSize -= sizeof(WCHAR); /* remove terminating null (will be added back later) */ } else { DataSize = info_size; if (!(Buffer = HeapAlloc( GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR) ))) goto Quit; } memcpy( Buffer + DataSize, source_name.Buffer, len1 ); DataSize += len1; p = (WCHAR *)(Buffer + DataSize); if (DestLen) { if (flags & MOVEFILE_REPLACE_EXISTING) *p++ = '!'; memcpy( p, dest_name.Buffer, len2 ); DataSize += len2; } else { *p = 0; DataSize += sizeof(WCHAR); } /* add final null */ p = (WCHAR *)(Buffer + DataSize); *p = 0; DataSize += sizeof(WCHAR); rc = NT_SUCCESS(NtSetValueKey(Reboot, &nameW, 0, REG_MULTI_SZ, Buffer + info_size, DataSize - info_size)); Quit: RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); if (dest_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); NtClose(Reboot); if(Buffer) HeapFree(GetProcessHeap(), 0, Buffer); return(rc); }